daemon.c (333174B)
1 /* 2 This file is part of libmicrohttpd 3 Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff 4 Copyright (C) 2015-2024 Evgeny Grin (Karlson2k) 5 6 This library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License as published by the Free Software Foundation; either 9 version 2.1 of the License, or (at your option) any later version. 10 11 This library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with this library; if not, write to the Free Software 18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 20 */ 21 22 /** 23 * @file microhttpd/daemon.c 24 * @brief A minimal-HTTP server library 25 * @author Daniel Pittman 26 * @author Christian Grothoff 27 * @author Karlson2k (Evgeny Grin) 28 */ 29 #include "platform.h" 30 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 31 #include "mhd_threads.h" 32 #endif 33 #include "internal.h" 34 #include "response.h" 35 #include "connection.h" 36 #include "memorypool.h" 37 #include "mhd_limits.h" 38 #include "autoinit_funcs.h" 39 #include "mhd_mono_clock.h" 40 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 41 #include "mhd_locks.h" 42 #endif 43 #include "mhd_sockets.h" 44 #include "mhd_itc.h" 45 #include "mhd_compat.h" 46 #include "mhd_send.h" 47 #include "mhd_align.h" 48 #include "mhd_str.h" 49 50 #ifdef MHD_USE_SYS_TSEARCH 51 #include <search.h> 52 #else /* ! MHD_USE_SYS_TSEARCH */ 53 #include "tsearch.h" 54 #endif /* ! MHD_USE_SYS_TSEARCH */ 55 56 #ifdef HTTPS_SUPPORT 57 #include "connection_https.h" 58 #ifdef MHD_HTTPS_REQUIRE_GCRYPT 59 #include <gcrypt.h> 60 #endif /* MHD_HTTPS_REQUIRE_GCRYPT */ 61 #endif /* HTTPS_SUPPORT */ 62 63 #if defined(_WIN32) && ! defined(__CYGWIN__) 64 #ifndef WIN32_LEAN_AND_MEAN 65 #define WIN32_LEAN_AND_MEAN 1 66 #endif /* !WIN32_LEAN_AND_MEAN */ 67 #include <windows.h> 68 #endif 69 70 #ifdef MHD_USE_POSIX_THREADS 71 #ifdef HAVE_SIGNAL_H 72 #include <signal.h> 73 #endif /* HAVE_SIGNAL_H */ 74 #endif /* MHD_USE_POSIX_THREADS */ 75 76 /** 77 * Default connection limit. 78 */ 79 #ifdef MHD_POSIX_SOCKETS 80 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 3 - 1 - MHD_ITC_NUM_FDS_) 81 #else 82 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 2) 83 #endif 84 85 /** 86 * Default memory allowed per connection. 87 */ 88 #define MHD_POOL_SIZE_DEFAULT (32 * 1024) 89 90 91 /* Forward declarations. */ 92 93 94 /** 95 * Global initialisation function. 96 */ 97 void 98 MHD_init (void); 99 100 /** 101 * Global deinitialisation function. 102 */ 103 void 104 MHD_fini (void); 105 106 /** 107 * Close all connections for the daemon. 108 * Must only be called when MHD_Daemon::shutdown was set to true. 109 * @remark To be called only from thread that process 110 * daemon's select()/poll()/etc. 111 * 112 * @param daemon daemon to close down 113 */ 114 static void 115 close_all_connections (struct MHD_Daemon *daemon); 116 117 #ifdef EPOLL_SUPPORT 118 119 /** 120 * Do epoll()-based processing. 121 * 122 * @param daemon daemon to run poll loop for 123 * @param millisec the maximum time in milliseconds to wait for events, 124 * set to '0' for non-blocking processing, 125 * set to '-1' to wait indefinitely. 126 * @return #MHD_NO on serious errors, #MHD_YES on success 127 */ 128 static enum MHD_Result 129 MHD_epoll (struct MHD_Daemon *daemon, 130 int32_t millisec); 131 132 #endif /* EPOLL_SUPPORT */ 133 134 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED 135 /** 136 * Do nothing - global initialisation is 137 * performed by library constructor. 138 */ 139 #define MHD_check_global_init_() (void) 0 140 #else /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */ 141 /** 142 * Track global initialisation 143 */ 144 volatile int global_init_count = 0; 145 146 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 147 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 148 /** 149 * Global initialisation mutex 150 */ 151 MHD_MUTEX_STATIC_DEFN_INIT_ (global_init_mutex_); 152 #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ 153 #endif 154 155 156 /** 157 * Check whether global initialisation was performed 158 * and call initialiser if necessary. 159 */ 160 void 161 MHD_check_global_init_ (void) 162 { 163 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 164 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 165 MHD_mutex_lock_chk_ (&global_init_mutex_); 166 #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ 167 #endif 168 if (0 == global_init_count++) 169 MHD_init (); 170 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 171 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 172 MHD_mutex_unlock_chk_ (&global_init_mutex_); 173 #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ 174 #endif 175 } 176 177 178 #endif /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */ 179 180 #ifdef HAVE_MESSAGES 181 /** 182 * Default logger function 183 */ 184 static void 185 MHD_default_logger_ (void *cls, 186 const char *fm, 187 va_list ap) 188 { 189 vfprintf ((FILE *) cls, fm, ap); 190 #ifdef _DEBUG 191 fflush ((FILE *) cls); 192 #endif /* _DEBUG */ 193 } 194 195 196 #endif /* HAVE_MESSAGES */ 197 198 199 /** 200 * Free the memory allocated by MHD. 201 * 202 * If any MHD function explicitly mentions that returned pointer must be 203 * freed by this function, then no other method must be used to free 204 * the memory. 205 * 206 * @param ptr the pointer to free. 207 * @sa #MHD_digest_auth_get_username(), #MHD_basic_auth_get_username_password3() 208 * @sa #MHD_basic_auth_get_username_password() 209 * @note Available since #MHD_VERSION 0x00095600 210 * @ingroup specialized 211 */ 212 _MHD_EXTERN void 213 MHD_free (void *ptr) 214 { 215 free (ptr); 216 } 217 218 219 /** 220 * Maintain connection count for single address. 221 */ 222 struct MHD_IPCount 223 { 224 /** 225 * Address family. AF_INET or AF_INET6 for now. 226 */ 227 int family; 228 229 /** 230 * Actual address. 231 */ 232 union 233 { 234 /** 235 * IPv4 address. 236 */ 237 struct in_addr ipv4; 238 #ifdef HAVE_INET6 239 /** 240 * IPv6 address. 241 */ 242 struct in6_addr ipv6; 243 #endif 244 } addr; 245 246 /** 247 * Counter. 248 */ 249 unsigned int count; 250 }; 251 252 253 /** 254 * Lock shared structure for IP connection counts and connection DLLs. 255 * 256 * @param daemon handle to daemon where lock is 257 */ 258 static void 259 MHD_ip_count_lock (struct MHD_Daemon *daemon) 260 { 261 mhd_assert (NULL == daemon->master); 262 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 263 MHD_mutex_lock_chk_ (&daemon->per_ip_connection_mutex); 264 #else 265 (void) daemon; 266 #endif 267 } 268 269 270 /** 271 * Unlock shared structure for IP connection counts and connection DLLs. 272 * 273 * @param daemon handle to daemon where lock is 274 */ 275 static void 276 MHD_ip_count_unlock (struct MHD_Daemon *daemon) 277 { 278 mhd_assert (NULL == daemon->master); 279 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 280 MHD_mutex_unlock_chk_ (&daemon->per_ip_connection_mutex); 281 #else 282 (void) daemon; 283 #endif 284 } 285 286 287 /** 288 * Tree comparison function for IP addresses (supplied to tsearch() family). 289 * We compare everything in the struct up through the beginning of the 290 * 'count' field. 291 * 292 * @param a1 first address to compare 293 * @param a2 second address to compare 294 * @return -1, 0 or 1 depending on result of compare 295 */ 296 static int 297 MHD_ip_addr_compare (const void *a1, 298 const void *a2) 299 { 300 return memcmp (a1, 301 a2, 302 offsetof (struct MHD_IPCount, 303 count)); 304 } 305 306 307 /** 308 * Parse address and initialize @a key using the address. 309 * 310 * @param addr address to parse 311 * @param addrlen number of bytes in @a addr 312 * @param key where to store the parsed address 313 * @return #MHD_YES on success and #MHD_NO otherwise (e.g., invalid address type) 314 */ 315 static enum MHD_Result 316 MHD_ip_addr_to_key (const struct sockaddr_storage *addr, 317 socklen_t addrlen, 318 struct MHD_IPCount *key) 319 { 320 memset (key, 321 0, 322 sizeof(*key)); 323 324 /* IPv4 addresses */ 325 if (sizeof (struct sockaddr_in) <= (size_t) addrlen) 326 { 327 if (AF_INET == addr->ss_family) 328 { 329 key->family = AF_INET; 330 memcpy (&key->addr.ipv4, 331 &((const struct sockaddr_in *) addr)->sin_addr, 332 sizeof(((const struct sockaddr_in *) NULL)->sin_addr)); 333 return MHD_YES; 334 } 335 } 336 337 #ifdef HAVE_INET6 338 if (sizeof (struct sockaddr_in6) <= (size_t) addrlen) 339 { 340 /* IPv6 addresses */ 341 if (AF_INET6 == addr->ss_family) 342 { 343 key->family = AF_INET6; 344 memcpy (&key->addr.ipv6, 345 &((const struct sockaddr_in6 *) addr)->sin6_addr, 346 sizeof(((const struct sockaddr_in6 *) NULL)->sin6_addr)); 347 return MHD_YES; 348 } 349 } 350 #endif 351 352 /* Some other address */ 353 return MHD_NO; 354 } 355 356 357 /** 358 * Check if IP address is over its limit in terms of the number 359 * of allowed concurrent connections. If the IP is still allowed, 360 * increments the connection counter. 361 * 362 * @param daemon handle to daemon where connection counts are tracked 363 * @param addr address to add (or increment counter) 364 * @param addrlen number of bytes in @a addr 365 * @return Return #MHD_YES if IP below limit, #MHD_NO if IP has surpassed limit. 366 * Also returns #MHD_NO if fails to allocate memory. 367 */ 368 static enum MHD_Result 369 MHD_ip_limit_add (struct MHD_Daemon *daemon, 370 const struct sockaddr_storage *addr, 371 socklen_t addrlen) 372 { 373 struct MHD_IPCount *newkeyp; 374 struct MHD_IPCount *keyp; 375 struct MHD_IPCount **nodep; 376 enum MHD_Result result; 377 378 daemon = MHD_get_master (daemon); 379 /* Ignore if no connection limit assigned */ 380 if (0 == daemon->per_ip_connection_limit) 381 return MHD_YES; 382 383 newkeyp = (struct MHD_IPCount *) malloc (sizeof(struct MHD_IPCount)); 384 if (NULL == newkeyp) 385 return MHD_NO; 386 387 /* Initialize key */ 388 if (MHD_NO == MHD_ip_addr_to_key (addr, 389 addrlen, 390 newkeyp)) 391 { 392 free (newkeyp); 393 return MHD_YES; /* Allow unhandled address types through */ 394 } 395 396 MHD_ip_count_lock (daemon); 397 398 /* Search for the IP address */ 399 nodep = (struct MHD_IPCount **) tsearch (newkeyp, 400 &daemon->per_ip_connection_count, 401 &MHD_ip_addr_compare); 402 if (NULL == nodep) 403 { 404 MHD_ip_count_unlock (daemon); 405 free (newkeyp); 406 #ifdef HAVE_MESSAGES 407 MHD_DLOG (daemon, 408 _ ("Failed to add IP connection count node.\n")); 409 #endif 410 return MHD_NO; 411 } 412 keyp = *nodep; 413 /* Test if there is room for another connection; if so, 414 * increment count */ 415 result = (keyp->count < daemon->per_ip_connection_limit) ? MHD_YES : MHD_NO; 416 if (MHD_NO != result) 417 ++keyp->count; 418 MHD_ip_count_unlock (daemon); 419 420 /* If we got an existing node back, free the one we created */ 421 if (keyp != newkeyp) 422 free (newkeyp); 423 424 return result; 425 } 426 427 428 /** 429 * Decrement connection count for IP address, removing from table 430 * count reaches 0. 431 * 432 * @param daemon handle to daemon where connection counts are tracked 433 * @param addr address to remove (or decrement counter) 434 * @param addrlen number of bytes in @a addr 435 */ 436 static void 437 MHD_ip_limit_del (struct MHD_Daemon *daemon, 438 const struct sockaddr_storage *addr, 439 socklen_t addrlen) 440 { 441 struct MHD_IPCount search_key; 442 struct MHD_IPCount *found_key; 443 void **nodep; 444 445 daemon = MHD_get_master (daemon); 446 /* Ignore if no connection limit assigned */ 447 if (0 == daemon->per_ip_connection_limit) 448 return; 449 /* Initialize search key */ 450 if (MHD_NO == MHD_ip_addr_to_key (addr, 451 addrlen, 452 &search_key)) 453 return; 454 455 MHD_ip_count_lock (daemon); 456 457 /* Search for the IP address */ 458 if (NULL == (nodep = tfind (&search_key, 459 &daemon->per_ip_connection_count, 460 &MHD_ip_addr_compare))) 461 { 462 /* Something's wrong if we couldn't find an IP address 463 * that was previously added */ 464 MHD_PANIC (_ ("Failed to find previously-added IP address.\n")); 465 } 466 found_key = (struct MHD_IPCount *) *nodep; 467 /* Validate existing count for IP address */ 468 if (0 == found_key->count) 469 { 470 MHD_PANIC (_ ("Previously-added IP address had counter of zero.\n")); 471 } 472 /* Remove the node entirely if count reduces to 0 */ 473 if (0 == --found_key->count) 474 { 475 tdelete (found_key, 476 &daemon->per_ip_connection_count, 477 &MHD_ip_addr_compare); 478 MHD_ip_count_unlock (daemon); 479 free (found_key); 480 } 481 else 482 MHD_ip_count_unlock (daemon); 483 } 484 485 486 #ifdef HTTPS_SUPPORT 487 /** 488 * Read and setup our certificate and key. 489 * 490 * @param daemon handle to daemon to initialize 491 * @return 0 on success 492 */ 493 static int 494 MHD_init_daemon_certificate (struct MHD_Daemon *daemon) 495 { 496 gnutls_datum_t key; 497 gnutls_datum_t cert; 498 int ret; 499 500 #if GNUTLS_VERSION_MAJOR >= 3 501 if (NULL != daemon->cert_callback) 502 { 503 gnutls_certificate_set_retrieve_function2 (daemon->x509_cred, 504 daemon->cert_callback); 505 } 506 #endif 507 #if GNUTLS_VERSION_NUMBER >= 0x030603 508 else if (NULL != daemon->cert_callback2) 509 { 510 gnutls_certificate_set_retrieve_function3 (daemon->x509_cred, 511 daemon->cert_callback2); 512 } 513 #endif 514 515 if (NULL != daemon->https_mem_trust) 516 { 517 size_t paramlen; 518 paramlen = strlen (daemon->https_mem_trust); 519 if (UINT_MAX < paramlen) 520 { 521 #ifdef HAVE_MESSAGES 522 MHD_DLOG (daemon, 523 _ ("Too long trust certificate.\n")); 524 #endif 525 return -1; 526 } 527 cert.data = (unsigned char *) _MHD_DROP_CONST (daemon->https_mem_trust); 528 cert.size = (unsigned int) paramlen; 529 if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred, 530 &cert, 531 GNUTLS_X509_FMT_PEM) < 0) 532 { 533 #ifdef HAVE_MESSAGES 534 MHD_DLOG (daemon, 535 _ ("Bad trust certificate format.\n")); 536 #endif 537 return -1; 538 } 539 } 540 541 if (daemon->have_dhparams) 542 { 543 gnutls_certificate_set_dh_params (daemon->x509_cred, 544 daemon->https_mem_dhparams); 545 } 546 /* certificate & key loaded from memory */ 547 if ( (NULL != daemon->https_mem_cert) && 548 (NULL != daemon->https_mem_key) ) 549 { 550 size_t param1len; 551 size_t param2len; 552 553 param1len = strlen (daemon->https_mem_key); 554 param2len = strlen (daemon->https_mem_cert); 555 if ( (UINT_MAX < param1len) || 556 (UINT_MAX < param2len) ) 557 { 558 #ifdef HAVE_MESSAGES 559 MHD_DLOG (daemon, 560 _ ("Too long key or certificate.\n")); 561 #endif 562 return -1; 563 } 564 key.data = (unsigned char *) _MHD_DROP_CONST (daemon->https_mem_key); 565 key.size = (unsigned int) param1len; 566 cert.data = (unsigned char *) _MHD_DROP_CONST (daemon->https_mem_cert); 567 cert.size = (unsigned int) param2len; 568 569 if (NULL != daemon->https_key_password) 570 { 571 #if GNUTLS_VERSION_NUMBER >= 0x030111 572 ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred, 573 &cert, 574 &key, 575 GNUTLS_X509_FMT_PEM, 576 daemon->https_key_password, 577 0); 578 #else 579 #ifdef HAVE_MESSAGES 580 MHD_DLOG (daemon, 581 _ ("Failed to setup x509 certificate/key: pre 3.X.X version " \ 582 "of GnuTLS does not support setting key password.\n")); 583 #endif 584 return -1; 585 #endif 586 } 587 else 588 ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred, 589 &cert, 590 &key, 591 GNUTLS_X509_FMT_PEM); 592 #ifdef HAVE_MESSAGES 593 if (0 != ret) 594 MHD_DLOG (daemon, 595 _ ("GnuTLS failed to setup x509 certificate/key: %s\n"), 596 gnutls_strerror (ret)); 597 #endif 598 return ret; 599 } 600 #if GNUTLS_VERSION_MAJOR >= 3 601 if (NULL != daemon->cert_callback) 602 return 0; 603 #endif 604 #if GNUTLS_VERSION_NUMBER >= 0x030603 605 else if (NULL != daemon->cert_callback2) 606 return 0; 607 #endif 608 #ifdef HAVE_MESSAGES 609 MHD_DLOG (daemon, 610 _ ("You need to specify a certificate and key location.\n")); 611 #endif 612 return -1; 613 } 614 615 616 /** 617 * Initialize security aspects of the HTTPS daemon 618 * 619 * @param daemon handle to daemon to initialize 620 * @return 0 on success 621 */ 622 static int 623 MHD_TLS_init (struct MHD_Daemon *daemon) 624 { 625 switch (daemon->cred_type) 626 { 627 case GNUTLS_CRD_CERTIFICATE: 628 if (0 != 629 gnutls_certificate_allocate_credentials (&daemon->x509_cred)) 630 return GNUTLS_E_MEMORY_ERROR; 631 return MHD_init_daemon_certificate (daemon); 632 case GNUTLS_CRD_PSK: 633 if (0 != 634 gnutls_psk_allocate_server_credentials (&daemon->psk_cred)) 635 return GNUTLS_E_MEMORY_ERROR; 636 return 0; 637 case GNUTLS_CRD_ANON: 638 case GNUTLS_CRD_SRP: 639 case GNUTLS_CRD_IA: 640 default: 641 #ifdef HAVE_MESSAGES 642 MHD_DLOG (daemon, 643 _ ("Error: invalid credentials type %d specified.\n"), 644 daemon->cred_type); 645 #endif 646 return -1; 647 } 648 } 649 650 651 /** 652 * Release the TLS resources that #MHD_start_daemon_va() may already have 653 * allocated when it decides to fail. 654 * 655 * The daemon object is not usable at that point, so #MHD_stop_daemon() 656 * (which is what frees these on the success path) cannot be called; each 657 * failure exit therefore has to do it, and every one of them used to 658 * forget the Diffie-Hellman parameters. Those are created by MHD itself 659 * from the PEM blob of #MHD_OPTION_HTTPS_MEM_DHPARAMS, so the 660 * application has no handle to free either. 661 * 662 * @param[in,out] daemon the half-initialised daemon 663 */ 664 static void 665 tls_cleanup_failed_start (struct MHD_Daemon *daemon) 666 { 667 if (daemon->have_dhparams) 668 { 669 gnutls_dh_params_deinit (daemon->https_mem_dhparams); 670 daemon->have_dhparams = false; 671 } 672 if (NULL != daemon->priority_cache) 673 { 674 gnutls_priority_deinit (daemon->priority_cache); 675 daemon->priority_cache = NULL; 676 } 677 if (NULL != daemon->x509_cred) 678 { 679 gnutls_certificate_free_credentials (daemon->x509_cred); 680 daemon->x509_cred = NULL; 681 } 682 if (NULL != daemon->psk_cred) 683 { 684 gnutls_psk_free_server_credentials (daemon->psk_cred); 685 daemon->psk_cred = NULL; 686 } 687 } 688 689 690 #endif /* HTTPS_SUPPORT */ 691 692 693 #undef MHD_get_fdset 694 695 /** 696 * Obtain the `select()` sets for this daemon. 697 * Daemon's FDs will be added to fd_sets. To get only 698 * daemon FDs in fd_sets, call FD_ZERO for each fd_set 699 * before calling this function. FD_SETSIZE is assumed 700 * to be platform's default. 701 * 702 * This function should be called only when MHD is configured to 703 * use "external" sockets polling with 'select()' or with 'epoll'. 704 * In the latter case, it will only add the single 'epoll' file 705 * descriptor used by MHD to the sets. 706 * It's necessary to use #MHD_get_timeout() to get maximum timeout 707 * value for `select()`. Usage of `select()` with indefinite timeout 708 * (or timeout larger than returned by #MHD_get_timeout()) will 709 * violate MHD API and may results in pending unprocessed data. 710 * 711 * This function must be called only for daemon started 712 * without #MHD_USE_INTERNAL_POLLING_THREAD flag. 713 * 714 * @param daemon daemon to get sets from 715 * @param read_fd_set read set 716 * @param write_fd_set write set 717 * @param except_fd_set except set 718 * @param max_fd increased to largest FD added (if larger 719 * than existing value); can be NULL 720 * @return #MHD_YES on success, #MHD_NO if this 721 * daemon was not started with the right 722 * options for this call or any FD didn't 723 * fit fd_set. 724 * @ingroup event 725 */ 726 _MHD_EXTERN enum MHD_Result 727 MHD_get_fdset (struct MHD_Daemon *daemon, 728 fd_set *read_fd_set, 729 fd_set *write_fd_set, 730 fd_set *except_fd_set, 731 MHD_socket *max_fd) 732 { 733 return MHD_get_fdset2 (daemon, 734 read_fd_set, 735 write_fd_set, 736 except_fd_set, 737 max_fd, 738 #ifdef HAS_FD_SETSIZE_OVERRIDABLE 739 daemon->fdset_size_set_by_app ? 740 ((unsigned int) daemon->fdset_size) : 741 ((unsigned int) _MHD_SYS_DEFAULT_FD_SETSIZE) 742 #else /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 743 ((unsigned int) _MHD_SYS_DEFAULT_FD_SETSIZE) 744 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 745 ); 746 } 747 748 749 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 750 /** 751 * Obtain the select() file descriptor sets for the 752 * given @a urh. 753 * 754 * @param urh upgrade handle to wait for 755 * @param[out] rs read set to initialize 756 * @param[out] ws write set to initialize 757 * @param[out] es except set to initialize 758 * @param[out] max_fd maximum FD to update 759 * @param fd_setsize value of FD_SETSIZE 760 * @return true on success, false on error 761 */ 762 static bool 763 urh_to_fdset (struct MHD_UpgradeResponseHandle *urh, 764 fd_set *rs, 765 fd_set *ws, 766 fd_set *es, 767 MHD_socket *max_fd, 768 int fd_setsize) 769 { 770 const MHD_socket conn_sckt = urh->connection->socket_fd; 771 const MHD_socket mhd_sckt = urh->mhd.socket; 772 bool res = true; 773 774 #ifndef HAS_FD_SETSIZE_OVERRIDABLE 775 (void) fd_setsize; /* Mute compiler warning */ 776 fd_setsize = (int) FD_SETSIZE; /* Help compiler to optimise */ 777 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 778 779 /* Do not add to 'es' only if socket is closed 780 * or not used anymore. */ 781 if (MHD_INVALID_SOCKET != conn_sckt) 782 { 783 if ( (urh->in_buffer_used < urh->in_buffer_size) && 784 (! MHD_add_to_fd_set_ (conn_sckt, 785 rs, 786 max_fd, 787 fd_setsize)) ) 788 res = false; 789 if ( (0 != urh->out_buffer_used) && 790 (! MHD_add_to_fd_set_ (conn_sckt, 791 ws, 792 max_fd, 793 fd_setsize)) ) 794 res = false; 795 /* Do not monitor again for errors if error was detected before as 796 * error state is remembered. */ 797 if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) && 798 ((0 != urh->in_buffer_size) || 799 (0 != urh->out_buffer_size) || 800 (0 != urh->out_buffer_used)) 801 && (NULL != es)) 802 (void) MHD_add_to_fd_set_ (conn_sckt, 803 es, 804 max_fd, 805 fd_setsize); 806 } 807 if (MHD_INVALID_SOCKET != mhd_sckt) 808 { 809 if ( (urh->out_buffer_used < urh->out_buffer_size) && 810 (! MHD_add_to_fd_set_ (mhd_sckt, 811 rs, 812 max_fd, 813 fd_setsize)) ) 814 res = false; 815 if ( (0 != urh->in_buffer_used) && 816 (! MHD_add_to_fd_set_ (mhd_sckt, 817 ws, 818 max_fd, 819 fd_setsize)) ) 820 res = false; 821 /* Do not monitor again for errors if error was detected before as 822 * error state is remembered. */ 823 if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) && 824 ((0 != urh->out_buffer_size) || 825 (0 != urh->in_buffer_size) || 826 (0 != urh->in_buffer_used)) 827 && (NULL != es)) 828 MHD_add_to_fd_set_ (mhd_sckt, 829 es, 830 max_fd, 831 fd_setsize); 832 } 833 834 return res; 835 } 836 837 838 /** 839 * Update the @a urh based on the ready FDs in 840 * the @a rs, @a ws, and @a es. 841 * 842 * @param urh upgrade handle to update 843 * @param rs read result from select() 844 * @param ws write result from select() 845 * @param es except result from select() 846 * @param fd_setsize value of FD_SETSIZE used when fd_sets were created 847 */ 848 static void 849 urh_from_fdset (struct MHD_UpgradeResponseHandle *urh, 850 const fd_set *rs, 851 const fd_set *ws, 852 const fd_set *es, 853 int fd_setsize) 854 { 855 const MHD_socket conn_sckt = urh->connection->socket_fd; 856 const MHD_socket mhd_sckt = urh->mhd.socket; 857 858 /* Reset read/write ready, preserve error state. */ 859 urh->app.celi &= (~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY) 860 & ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY)); 861 urh->mhd.celi &= (~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY) 862 & ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY)); 863 864 mhd_assert (urh->connection->sk_nonblck); 865 866 #ifndef HAS_FD_SETSIZE_OVERRIDABLE 867 (void) fd_setsize; /* Mute compiler warning */ 868 mhd_assert (((int) FD_SETSIZE) <= fd_setsize); 869 fd_setsize = FD_SETSIZE; /* Help compiler to optimise */ 870 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 871 872 if (MHD_INVALID_SOCKET != conn_sckt) 873 { 874 if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (conn_sckt, NULL, fd_setsize)) 875 { 876 if (FD_ISSET (conn_sckt, (fd_set *) _MHD_DROP_CONST (rs))) 877 urh->app.celi |= MHD_EPOLL_STATE_READ_READY; 878 if (FD_ISSET (conn_sckt, (fd_set *) _MHD_DROP_CONST (ws))) 879 urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; 880 if ((NULL != es) && 881 FD_ISSET (conn_sckt, (fd_set *) _MHD_DROP_CONST (es))) 882 urh->app.celi |= MHD_EPOLL_STATE_ERROR; 883 } 884 else 885 { /* Cannot check readiness. Force ready state is safe as socket is non-blocking */ 886 urh->app.celi |= MHD_EPOLL_STATE_READ_READY; 887 urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; 888 } 889 } 890 if ((MHD_INVALID_SOCKET != mhd_sckt)) 891 { 892 if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (mhd_sckt, NULL, fd_setsize)) 893 { 894 if (FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (rs))) 895 urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; 896 if (FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (ws))) 897 urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; 898 if ((NULL != es) && 899 FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (es))) 900 urh->mhd.celi |= MHD_EPOLL_STATE_ERROR; 901 } 902 else 903 { /* Cannot check readiness. Force ready state is safe as socket is non-blocking */ 904 urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; 905 urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; 906 } 907 } 908 } 909 910 911 #ifdef HAVE_POLL 912 913 /** 914 * Set required 'event' members in 'pollfd' elements, 915 * assuming that @a p[0].fd is MHD side of socketpair 916 * and @a p[1].fd is TLS connected socket. 917 * 918 * @param urh upgrade handle to watch for 919 * @param p pollfd array to update 920 */ 921 static void 922 urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh, 923 struct pollfd p[2]) 924 { 925 p[0].events = 0; 926 p[1].events = 0; 927 928 if (urh->in_buffer_used < urh->in_buffer_size) 929 p[0].events |= POLLIN; 930 if (0 != urh->out_buffer_used) 931 p[0].events |= POLLOUT; 932 933 /* Do not monitor again for errors if error was detected before as 934 * error state is remembered. */ 935 if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) && 936 ((0 != urh->in_buffer_size) || 937 (0 != urh->out_buffer_size) || 938 (0 != urh->out_buffer_used))) 939 p[0].events |= MHD_POLL_EVENTS_ERR_DISC; 940 941 if (urh->out_buffer_used < urh->out_buffer_size) 942 p[1].events |= POLLIN; 943 if (0 != urh->in_buffer_used) 944 p[1].events |= POLLOUT; 945 946 /* Do not monitor again for errors if error was detected before as 947 * error state is remembered. */ 948 if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) && 949 ((0 != urh->out_buffer_size) || 950 (0 != urh->in_buffer_size) || 951 (0 != urh->in_buffer_used))) 952 p[1].events |= MHD_POLL_EVENTS_ERR_DISC; 953 } 954 955 956 /** 957 * Set @a p to watch for @a urh. 958 * 959 * @param urh upgrade handle to watch for 960 * @param p pollfd array to set 961 */ 962 static void 963 urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh, 964 struct pollfd p[2]) 965 { 966 p[0].fd = urh->connection->socket_fd; 967 p[1].fd = urh->mhd.socket; 968 urh_update_pollfd (urh, 969 p); 970 } 971 972 973 /** 974 * Update ready state in @a urh based on pollfd. 975 * @param urh upgrade handle to update 976 * @param p 'poll()' processed pollfd. 977 */ 978 static void 979 urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh, 980 struct pollfd p[2]) 981 { 982 /* Reset read/write ready, preserve error state. */ 983 urh->app.celi &= (~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY) 984 & ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY)); 985 urh->mhd.celi &= (~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY) 986 & ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY)); 987 988 if (0 != (p[0].revents & POLLIN)) 989 urh->app.celi |= MHD_EPOLL_STATE_READ_READY; 990 if (0 != (p[0].revents & POLLOUT)) 991 urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; 992 if (0 != (p[0].revents & POLLHUP)) 993 urh->app.celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY; 994 if (0 != (p[0].revents & MHD_POLL_REVENTS_ERRROR)) 995 urh->app.celi |= MHD_EPOLL_STATE_ERROR; 996 if (0 != (p[1].revents & POLLIN)) 997 urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; 998 if (0 != (p[1].revents & POLLOUT)) 999 urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; 1000 if (0 != (p[1].revents & POLLHUP)) 1001 urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY; 1002 if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR)) 1003 urh->mhd.celi |= MHD_EPOLL_STATE_ERROR; 1004 } 1005 1006 1007 #endif /* HAVE_POLL */ 1008 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 1009 1010 1011 /** 1012 * Internal version of #MHD_get_fdset2(). 1013 * 1014 * @param daemon daemon to get sets from 1015 * @param read_fd_set read set 1016 * @param write_fd_set write set 1017 * @param except_fd_set except set 1018 * @param max_fd increased to largest FD added (if larger 1019 * than existing value); can be NULL 1020 * @param fd_setsize value of FD_SETSIZE 1021 * @return #MHD_YES on success, #MHD_NO if any FD didn't 1022 * fit fd_set. 1023 * @ingroup event 1024 */ 1025 static enum MHD_Result 1026 internal_get_fdset2 (struct MHD_Daemon *daemon, 1027 fd_set *read_fd_set, 1028 fd_set *write_fd_set, 1029 fd_set *except_fd_set, 1030 MHD_socket *max_fd, 1031 int fd_setsize) 1032 { 1033 struct MHD_Connection *pos; 1034 struct MHD_Connection *posn; 1035 enum MHD_Result result = MHD_YES; 1036 MHD_socket ls; 1037 bool itc_added; 1038 1039 #ifndef HAS_FD_SETSIZE_OVERRIDABLE 1040 (void) fd_setsize; /* Mute compiler warning */ 1041 fd_setsize = (int) FD_SETSIZE; /* Help compiler to optimise */ 1042 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 1043 1044 if (daemon->shutdown) 1045 return MHD_YES; 1046 1047 /* The order of FDs added is important for W32 sockets as W32 fd_set has 1048 limits for number of added FDs instead of the limit for the higher 1049 FD value. */ 1050 1051 /* Add ITC FD first. The daemon must be able to respond on application 1052 commands issued in other threads. */ 1053 itc_added = false; 1054 if (MHD_ITC_IS_VALID_ (daemon->itc)) 1055 { 1056 itc_added = MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), 1057 read_fd_set, 1058 max_fd, 1059 fd_setsize); 1060 if (! itc_added) 1061 result = MHD_NO; 1062 } 1063 1064 ls = daemon->was_quiesced ? MHD_INVALID_SOCKET : daemon->listen_fd; 1065 if (! itc_added && 1066 (MHD_INVALID_SOCKET != ls)) 1067 { 1068 /* Add listen FD if ITC was not added. Listen FD could be used to signal 1069 the daemon shutdown. */ 1070 if (MHD_add_to_fd_set_ (ls, 1071 read_fd_set, 1072 max_fd, 1073 fd_setsize)) 1074 ls = MHD_INVALID_SOCKET; /* Already added */ 1075 else 1076 result = MHD_NO; 1077 } 1078 1079 /* Add all sockets to 'except_fd_set' as well to watch for 1080 * out-of-band data. However, ignore errors if INFO_READ 1081 * or INFO_WRITE sockets will not fit 'except_fd_set'. */ 1082 /* Start from oldest connections. Make sense for W32 FDSETs. */ 1083 for (pos = daemon->connections_tail; NULL != pos; pos = posn) 1084 { 1085 posn = pos->prev; 1086 1087 switch (pos->event_loop_info) 1088 { 1089 case MHD_EVENT_LOOP_INFO_READ: 1090 case MHD_EVENT_LOOP_INFO_PROCESS_READ: 1091 if (! MHD_add_to_fd_set_ (pos->socket_fd, 1092 read_fd_set, 1093 max_fd, 1094 fd_setsize)) 1095 result = MHD_NO; 1096 #ifdef MHD_POSIX_SOCKETS 1097 if (NULL != except_fd_set) 1098 (void) MHD_add_to_fd_set_ (pos->socket_fd, 1099 except_fd_set, 1100 max_fd, 1101 fd_setsize); 1102 #endif /* MHD_POSIX_SOCKETS */ 1103 break; 1104 case MHD_EVENT_LOOP_INFO_WRITE: 1105 if (! MHD_add_to_fd_set_ (pos->socket_fd, 1106 write_fd_set, 1107 max_fd, 1108 fd_setsize)) 1109 result = MHD_NO; 1110 #ifdef MHD_POSIX_SOCKETS 1111 if (NULL != except_fd_set) 1112 (void) MHD_add_to_fd_set_ (pos->socket_fd, 1113 except_fd_set, 1114 max_fd, 1115 fd_setsize); 1116 #endif /* MHD_POSIX_SOCKETS */ 1117 break; 1118 case MHD_EVENT_LOOP_INFO_PROCESS: 1119 if ( (NULL == except_fd_set) || 1120 ! MHD_add_to_fd_set_ (pos->socket_fd, 1121 except_fd_set, 1122 max_fd, 1123 fd_setsize)) 1124 result = MHD_NO; 1125 break; 1126 case MHD_EVENT_LOOP_INFO_CLEANUP: 1127 /* this should never happen */ 1128 break; 1129 } 1130 } 1131 #ifdef MHD_WINSOCK_SOCKETS 1132 /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets 1133 * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will 1134 * not be pushed out. */ 1135 if (NULL != except_fd_set) 1136 { 1137 for (pos = daemon->connections_tail; NULL != pos; pos = posn) 1138 { 1139 posn = pos->prev; 1140 MHD_add_to_fd_set_ (pos->socket_fd, 1141 except_fd_set, 1142 max_fd, 1143 fd_setsize); 1144 } 1145 } 1146 #endif /* MHD_WINSOCK_SOCKETS */ 1147 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 1148 if (1) 1149 { 1150 struct MHD_UpgradeResponseHandle *urh; 1151 1152 for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev) 1153 { 1154 if (MHD_NO == 1155 urh_to_fdset (urh, 1156 read_fd_set, 1157 write_fd_set, 1158 except_fd_set, 1159 max_fd, 1160 fd_setsize)) 1161 result = MHD_NO; 1162 } 1163 } 1164 #endif 1165 1166 if (MHD_INVALID_SOCKET != ls) 1167 { 1168 /* The listen socket is present and hasn't been added */ 1169 if ((daemon->connections < daemon->connection_limit) && 1170 ! daemon->at_limit) 1171 { 1172 if (! MHD_add_to_fd_set_ (ls, 1173 read_fd_set, 1174 max_fd, 1175 fd_setsize)) 1176 result = MHD_NO; 1177 } 1178 } 1179 1180 #if _MHD_DEBUG_CONNECT 1181 #ifdef HAVE_MESSAGES 1182 if (NULL != max_fd) 1183 MHD_DLOG (daemon, 1184 _ ("Maximum socket in select set: %d\n"), 1185 *max_fd); 1186 #endif 1187 #endif 1188 return result; 1189 } 1190 1191 1192 /** 1193 * Obtain the `select()` sets for this daemon. 1194 * Daemon's FDs will be added to fd_sets. To get only 1195 * daemon FDs in fd_sets, call FD_ZERO for each fd_set 1196 * before calling this function. 1197 * 1198 * Passing custom FD_SETSIZE as @a fd_setsize allow usage of 1199 * larger/smaller than platform's default fd_sets. 1200 * 1201 * This function should be called only when MHD is configured to 1202 * use "external" sockets polling with 'select()' or with 'epoll'. 1203 * In the latter case, it will only add the single 'epoll' file 1204 * descriptor used by MHD to the sets. 1205 * It's necessary to use #MHD_get_timeout() to get maximum timeout 1206 * value for `select()`. Usage of `select()` with indefinite timeout 1207 * (or timeout larger than returned by #MHD_get_timeout()) will 1208 * violate MHD API and may results in pending unprocessed data. 1209 * 1210 * This function must be called only for daemon started 1211 * without #MHD_USE_INTERNAL_POLLING_THREAD flag. 1212 * 1213 * @param daemon daemon to get sets from 1214 * @param read_fd_set read set 1215 * @param write_fd_set write set 1216 * @param except_fd_set except set 1217 * @param max_fd increased to largest FD added (if larger 1218 * than existing value); can be NULL 1219 * @param fd_setsize value of FD_SETSIZE 1220 * @return #MHD_YES on success, #MHD_NO if this 1221 * daemon was not started with the right 1222 * options for this call or any FD didn't 1223 * fit fd_set. 1224 * @ingroup event 1225 */ 1226 _MHD_EXTERN enum MHD_Result 1227 MHD_get_fdset2 (struct MHD_Daemon *daemon, 1228 fd_set *read_fd_set, 1229 fd_set *write_fd_set, 1230 fd_set *except_fd_set, 1231 MHD_socket *max_fd, 1232 unsigned int fd_setsize) 1233 { 1234 if ( (NULL == daemon) || 1235 (NULL == read_fd_set) || 1236 (NULL == write_fd_set) || 1237 MHD_D_IS_USING_THREADS_ (daemon) || 1238 MHD_D_IS_USING_POLL_ (daemon)) 1239 return MHD_NO; 1240 1241 #ifdef HAVE_MESSAGES 1242 if (NULL == except_fd_set) 1243 { 1244 MHD_DLOG (daemon, 1245 _ ("MHD_get_fdset2() called with except_fd_set " 1246 "set to NULL. Such behavior is unsupported.\n")); 1247 } 1248 #endif 1249 1250 #ifdef HAS_FD_SETSIZE_OVERRIDABLE 1251 if (0 == fd_setsize) 1252 return MHD_NO; 1253 else if (((unsigned int) INT_MAX) < fd_setsize) 1254 fd_setsize = (unsigned int) INT_MAX; 1255 #ifdef HAVE_MESSAGES 1256 else if (daemon->fdset_size > ((int) fd_setsize)) 1257 { 1258 if (daemon->fdset_size_set_by_app) 1259 { 1260 MHD_DLOG (daemon, 1261 _ ("%s() called with fd_setsize (%u) " \ 1262 "less than value set by MHD_OPTION_APP_FD_SETSIZE (%d). " \ 1263 "Some socket FDs may be not processed. " \ 1264 "Use MHD_OPTION_APP_FD_SETSIZE with the correct value.\n"), 1265 "MHD_get_fdset2", fd_setsize, daemon->fdset_size); 1266 } 1267 else 1268 { 1269 MHD_DLOG (daemon, 1270 _ ("%s() called with fd_setsize (%u) " \ 1271 "less than FD_SETSIZE used by MHD (%d). " \ 1272 "Some socket FDs may be not processed. " \ 1273 "Consider using MHD_OPTION_APP_FD_SETSIZE option.\n"), 1274 "MHD_get_fdset2", fd_setsize, daemon->fdset_size); 1275 } 1276 } 1277 #endif /* HAVE_MESSAGES */ 1278 #else /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 1279 if (((unsigned int) FD_SETSIZE) > fd_setsize) 1280 { 1281 #ifdef HAVE_MESSAGES 1282 MHD_DLOG (daemon, 1283 _ ("%s() called with fd_setsize (%u) " \ 1284 "less than fixed FD_SETSIZE value (%d) used on the " \ 1285 "platform.\n"), 1286 "MHD_get_fdset2", fd_setsize, (int) FD_SETSIZE); 1287 #endif /* HAVE_MESSAGES */ 1288 return MHD_NO; 1289 } 1290 fd_setsize = (int) FD_SETSIZE; /* Help compiler to optimise */ 1291 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 1292 1293 #ifdef EPOLL_SUPPORT 1294 if (MHD_D_IS_USING_EPOLL_ (daemon)) 1295 { 1296 if (daemon->shutdown) 1297 return MHD_YES; 1298 1299 /* we're in epoll mode, use the epoll FD as a stand-in for 1300 the entire event set */ 1301 1302 return MHD_add_to_fd_set_ (daemon->epoll_fd, 1303 read_fd_set, 1304 max_fd, 1305 (int) fd_setsize) ? MHD_YES : MHD_NO; 1306 } 1307 #endif 1308 1309 return internal_get_fdset2 (daemon, 1310 read_fd_set, 1311 write_fd_set, 1312 except_fd_set, 1313 max_fd, 1314 (int) fd_setsize); 1315 } 1316 1317 1318 /** 1319 * Call the handlers for a connection in the appropriate order based 1320 * on the readiness as detected by the event loop. 1321 * 1322 * @param con connection to handle 1323 * @param read_ready set if the socket is ready for reading 1324 * @param write_ready set if the socket is ready for writing 1325 * @param force_close set if a hard error was detected on the socket; 1326 * if this information is not available, simply pass #MHD_NO 1327 * @return #MHD_YES to continue normally, 1328 * #MHD_NO if a serious error was encountered and the 1329 * connection is to be closed. 1330 */ 1331 static enum MHD_Result 1332 call_handlers (struct MHD_Connection *con, 1333 bool read_ready, 1334 bool write_ready, 1335 bool force_close) 1336 { 1337 enum MHD_Result ret; 1338 bool states_info_processed = false; 1339 /* Fast track flag */ 1340 bool on_fasttrack = (con->state == MHD_CONNECTION_INIT); 1341 ret = MHD_YES; 1342 1343 mhd_assert ((0 == (con->daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 1344 (MHD_thread_handle_ID_is_valid_ID_ (con->tid))); 1345 mhd_assert ((0 != (con->daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 1346 (! MHD_thread_handle_ID_is_valid_ID_ (con->tid))); 1347 mhd_assert ((0 == (con->daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 1348 (MHD_thread_handle_ID_is_current_thread_ (con->tid))); 1349 1350 #ifdef HTTPS_SUPPORT 1351 if (con->tls_read_ready) 1352 read_ready = true; 1353 #endif /* HTTPS_SUPPORT */ 1354 if (con->resumed) 1355 { 1356 /* The connection was resumed since its states were last updated, 1357 so 'con->event_loop_info' still describes the state the 1358 connection was in before it was suspended -- see the field's 1359 description. Dispatching on it would, for instance, call 1360 MHD_connection_handle_write() on a connection whose content 1361 reader has just reported that it has no data yet, which is not a 1362 state the write handler has an action for. */ 1363 con->resumed = false; 1364 ret = MHD_connection_handle_idle (con); 1365 if (MHD_NO == ret) 1366 return ret; /* Connection died and was cleaned up. */ 1367 states_info_processed = true; 1368 } 1369 if ( (0 != (MHD_EVENT_LOOP_INFO_READ & con->event_loop_info)) && 1370 (read_ready || (force_close && con->sk_nonblck)) ) 1371 { 1372 MHD_connection_handle_read (con, force_close); 1373 /* MHD_connection_handle_read() closes the connection when 1374 @a force_close is set, but only once it gets far enough to try. 1375 It returns early, leaving 'con->state' untouched, in three cases, 1376 and all three are reachable from here: 1377 - the connection is suspended, 1378 - a TLS handshake is still in progress, 1379 - the read buffer has no free space at all. */ 1380 #ifdef HTTPS_SUPPORT 1381 mhd_assert ((! force_close) || \ 1382 (MHD_CONNECTION_CLOSED == con->state) || \ 1383 (con->suspended) || \ 1384 ( (MHD_TLS_CONN_NO_TLS != con->tls_state) && \ 1385 (MHD_TLS_CONN_CONNECTED > con->tls_state) ) || \ 1386 (con->read_buffer_size == con->read_buffer_offset)); 1387 #else /* ! HTTPS_SUPPORT */ 1388 mhd_assert ((! force_close) || \ 1389 (MHD_CONNECTION_CLOSED == con->state) || \ 1390 (con->suspended) || \ 1391 (con->read_buffer_size == con->read_buffer_offset)); 1392 #endif /* ! HTTPS_SUPPORT */ 1393 ret = MHD_connection_handle_idle (con); 1394 if (force_close) 1395 return ret; 1396 states_info_processed = true; 1397 } 1398 if (! force_close) 1399 { 1400 /* No need to check value of 'ret' here as closed connection 1401 * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */ 1402 if ( (MHD_EVENT_LOOP_INFO_WRITE == con->event_loop_info) && 1403 write_ready) 1404 { 1405 MHD_connection_handle_write (con); 1406 ret = MHD_connection_handle_idle (con); 1407 states_info_processed = true; 1408 } 1409 } 1410 else 1411 { 1412 MHD_connection_close_ (con, 1413 MHD_REQUEST_TERMINATED_WITH_ERROR); 1414 return MHD_connection_handle_idle (con); 1415 } 1416 1417 if (! states_info_processed) 1418 { /* Connection is not read or write ready, but external conditions 1419 * may be changed and need to be processed. */ 1420 ret = MHD_connection_handle_idle (con); 1421 } 1422 /* Fast track for fast connections. */ 1423 /* If full request was read by single read_handler() invocation 1424 and headers were completely prepared by single MHD_connection_handle_idle() 1425 then try not to wait for next sockets polling and send response 1426 immediately. 1427 As writeability of socket was not checked and it may have 1428 some data pending in system buffers, use this optimization 1429 only for non-blocking sockets. */ 1430 /* No need to check 'ret' as connection is always in 1431 * MHD_CONNECTION_CLOSED state if 'ret' is equal 'MHD_NO'. */ 1432 else if (on_fasttrack && con->sk_nonblck) 1433 { 1434 if (MHD_CONNECTION_HEADERS_SENDING == con->state) 1435 { 1436 MHD_connection_handle_write (con); 1437 /* Always call 'MHD_connection_handle_idle()' after each read/write. */ 1438 ret = MHD_connection_handle_idle (con); 1439 } 1440 /* If all headers were sent by single write_handler() and 1441 * response body is prepared by single MHD_connection_handle_idle() 1442 * call - continue. */ 1443 if ((MHD_CONNECTION_NORMAL_BODY_READY == con->state) || 1444 (MHD_CONNECTION_CHUNKED_BODY_READY == con->state)) 1445 { 1446 MHD_connection_handle_write (con); 1447 ret = MHD_connection_handle_idle (con); 1448 } 1449 } 1450 1451 /* All connection's data and states are processed for this turn. 1452 * If connection already has more data to be processed - use 1453 * zero timeout for next select()/poll(). */ 1454 /* Thread-per-connection do not need global zero timeout as 1455 * connections are processed individually. */ 1456 /* Note: no need to check for read buffer availability for 1457 * TLS read-ready connection in 'read info' state as connection 1458 * without space in read buffer will be marked as 'info block'. */ 1459 if ( (! con->daemon->data_already_pending) && 1460 (! MHD_D_IS_USING_THREAD_PER_CONN_ (con->daemon)) ) 1461 { 1462 if (0 != (MHD_EVENT_LOOP_INFO_PROCESS & con->event_loop_info)) 1463 con->daemon->data_already_pending = true; 1464 #ifdef HTTPS_SUPPORT 1465 else if ( (con->tls_read_ready) && 1466 (0 != (MHD_EVENT_LOOP_INFO_READ & con->event_loop_info)) ) 1467 con->daemon->data_already_pending = true; 1468 #endif /* HTTPS_SUPPORT */ 1469 } 1470 return ret; 1471 } 1472 1473 1474 #ifdef UPGRADE_SUPPORT 1475 /** 1476 * Finally cleanup upgrade-related resources. It should 1477 * be called when TLS buffers have been drained and 1478 * application signaled MHD by #MHD_UPGRADE_ACTION_CLOSE. 1479 * 1480 * @param connection handle to the upgraded connection to clean 1481 */ 1482 static void 1483 cleanup_upgraded_connection (struct MHD_Connection *connection) 1484 { 1485 struct MHD_UpgradeResponseHandle *urh = connection->urh; 1486 1487 if (NULL == urh) 1488 return; 1489 #ifdef HTTPS_SUPPORT 1490 /* Signal remote client the end of TLS connection by 1491 * gracefully closing TLS session. */ 1492 if (0 != (connection->daemon->options & MHD_USE_TLS)) 1493 gnutls_bye (connection->tls_session, 1494 GNUTLS_SHUT_WR); 1495 1496 if (MHD_INVALID_SOCKET != urh->mhd.socket) 1497 MHD_socket_close_chk_ (urh->mhd.socket); 1498 1499 if (MHD_INVALID_SOCKET != urh->app.socket) 1500 MHD_socket_close_chk_ (urh->app.socket); 1501 #endif /* HTTPS_SUPPORT */ 1502 connection->urh = NULL; 1503 free (urh); 1504 } 1505 1506 1507 #endif /* UPGRADE_SUPPORT */ 1508 1509 1510 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 1511 /** 1512 * Performs bi-directional forwarding on upgraded HTTPS connections 1513 * based on the readiness state stored in the @a urh handle. 1514 * @remark To be called only from thread that processes 1515 * connection's recv(), send() and response. 1516 * 1517 * @param urh handle to process 1518 */ 1519 static void 1520 process_urh (struct MHD_UpgradeResponseHandle *urh) 1521 { 1522 /* Help compiler to optimize: 1523 * pointers to 'connection' and 'daemon' are not changed 1524 * during this processing, so no need to chain dereference 1525 * each time. */ 1526 struct MHD_Connection *const connection = urh->connection; 1527 struct MHD_Daemon *const daemon = connection->daemon; 1528 /* Prevent data races: use same value of 'was_closed' throughout 1529 * this function. If 'was_closed' changed externally in the middle 1530 * of processing - it will be processed on next iteration. */ 1531 bool was_closed; 1532 1533 #ifdef MHD_USE_THREADS 1534 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 1535 MHD_thread_handle_ID_is_current_thread_ (connection->tid) ); 1536 #endif /* MHD_USE_THREADS */ 1537 1538 mhd_assert (0 != (daemon->options & MHD_USE_TLS)); 1539 1540 if (daemon->shutdown) 1541 { 1542 /* Daemon shutting down, application will not receive any more data. */ 1543 #ifdef HAVE_MESSAGES 1544 if (! urh->was_closed) 1545 { 1546 MHD_DLOG (daemon, 1547 _ ("Initiated daemon shutdown while \"upgraded\" " \ 1548 "connection was not closed.\n")); 1549 } 1550 #endif 1551 urh->was_closed = true; 1552 } 1553 was_closed = urh->was_closed; 1554 if (was_closed) 1555 { 1556 /* Application was closed connections: no more data 1557 * can be forwarded to application socket. */ 1558 if (0 < urh->in_buffer_used) 1559 { 1560 #ifdef HAVE_MESSAGES 1561 MHD_DLOG (daemon, 1562 _ ("Failed to forward to application %" PRIu64 \ 1563 " bytes of data received from remote side: " \ 1564 "application closed data forwarding.\n"), 1565 (uint64_t) urh->in_buffer_used); 1566 #endif 1567 1568 } 1569 /* Discard any data received form remote. */ 1570 urh->in_buffer_used = 0; 1571 /* Do not try to push data to application. */ 1572 urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY); 1573 /* Reading from remote client is not required anymore. */ 1574 urh->in_buffer_size = 0; 1575 urh->app.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY); 1576 connection->tls_read_ready = false; 1577 } 1578 1579 /* On some platforms (W32, possibly Darwin) failed send() (send() will 1580 * always fail after remote disconnect was detected) may discard data in 1581 * system buffers received by system but not yet read by recv(). So, before 1582 * trying send() on any socket, recv() must be performed at first otherwise 1583 * last part of incoming data may be lost. If disconnect or error was 1584 * detected - try to read from socket to dry data possibly pending is system 1585 * buffers. */ 1586 1587 /* 1588 * handle reading from remote TLS client 1589 */ 1590 if (((0 != ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) 1591 & urh->app.celi)) || 1592 (connection->tls_read_ready)) && 1593 (urh->in_buffer_used < urh->in_buffer_size)) 1594 { 1595 ssize_t res; 1596 size_t buf_size; 1597 1598 buf_size = urh->in_buffer_size - urh->in_buffer_used; 1599 if (buf_size > SSIZE_MAX) 1600 buf_size = SSIZE_MAX; 1601 1602 res = gnutls_record_recv (connection->tls_session, 1603 &urh->in_buffer[urh->in_buffer_used], 1604 buf_size); 1605 if (0 >= res) 1606 { 1607 connection->tls_read_ready = false; 1608 if (GNUTLS_E_INTERRUPTED != res) 1609 { 1610 urh->app.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY); 1611 if ((GNUTLS_E_AGAIN != res) || 1612 (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi))) 1613 { 1614 /* TLS unrecoverable error has been detected, 1615 socket error was detected and all data has been read, 1616 or socket was disconnected/shut down. */ 1617 /* Stop trying to read from this TLS socket. */ 1618 urh->in_buffer_size = 0; 1619 } 1620 } 1621 } 1622 else /* 0 < res */ 1623 { 1624 urh->in_buffer_used += (size_t) res; 1625 connection->tls_read_ready = 1626 (0 < gnutls_record_check_pending (connection->tls_session)); 1627 } 1628 } 1629 1630 /* 1631 * handle reading from application 1632 */ 1633 /* If application signalled MHD about socket closure then 1634 * check for any pending data even if socket is not marked 1635 * as 'ready' (signal may arrive after poll()/select()). 1636 * Socketpair for forwarding is always in non-blocking mode 1637 * so no risk that recv() will block the thread. */ 1638 if (((0 != ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) 1639 & urh->mhd.celi)) 1640 || was_closed) /* Force last reading from app if app has closed the connection */ 1641 && (urh->out_buffer_used < urh->out_buffer_size)) 1642 { 1643 ssize_t res; 1644 size_t buf_size; 1645 1646 buf_size = urh->out_buffer_size - urh->out_buffer_used; 1647 if (buf_size > MHD_SCKT_SEND_MAX_SIZE_) 1648 buf_size = MHD_SCKT_SEND_MAX_SIZE_; 1649 1650 res = MHD_recv_ (urh->mhd.socket, 1651 &urh->out_buffer[urh->out_buffer_used], 1652 buf_size); 1653 if (0 >= res) 1654 { 1655 const int err = MHD_socket_get_error_ (); 1656 if ((0 == res) || 1657 ((! MHD_SCKT_ERR_IS_EINTR_ (err)) && 1658 (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err)))) 1659 { 1660 urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY); 1661 if ((0 == res) || 1662 (was_closed) || 1663 (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) || 1664 (! MHD_SCKT_ERR_IS_EAGAIN_ (err))) 1665 { 1666 /* Socket disconnect/shutdown was detected; 1667 * Application signalled about closure of 'upgraded' socket and 1668 * all data has been read from application; 1669 * or persistent / unrecoverable error. */ 1670 /* Do not try to pull more data from application. */ 1671 urh->out_buffer_size = 0; 1672 } 1673 } 1674 } 1675 else /* 0 < res */ 1676 { 1677 urh->out_buffer_used += (size_t) res; 1678 if (buf_size > (size_t) res) 1679 urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY); 1680 } 1681 } 1682 1683 /* 1684 * handle writing to remote HTTPS client 1685 */ 1686 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) && 1687 (urh->out_buffer_used > 0) ) 1688 { 1689 ssize_t res; 1690 size_t data_size; 1691 1692 data_size = urh->out_buffer_used; 1693 if (data_size > SSIZE_MAX) 1694 data_size = SSIZE_MAX; 1695 1696 res = gnutls_record_send (connection->tls_session, 1697 urh->out_buffer, 1698 data_size); 1699 if (0 >= res) 1700 { 1701 if (GNUTLS_E_INTERRUPTED != res) 1702 { 1703 urh->app.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY); 1704 if (GNUTLS_E_AGAIN != res) 1705 { 1706 /* TLS connection shut down or 1707 * persistent / unrecoverable error. */ 1708 #ifdef HAVE_MESSAGES 1709 MHD_DLOG (daemon, 1710 _ ("Failed to forward to remote client %" PRIu64 \ 1711 " bytes of data received from application: %s\n"), 1712 (uint64_t) urh->out_buffer_used, 1713 gnutls_strerror ((int) res)); 1714 #endif 1715 /* Discard any data unsent to remote. */ 1716 urh->out_buffer_used = 0; 1717 /* Do not try to pull more data from application. */ 1718 urh->out_buffer_size = 0; 1719 urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY); 1720 } 1721 } 1722 } 1723 else /* 0 < res */ 1724 { 1725 const size_t next_out_buffer_used = urh->out_buffer_used - (size_t) res; 1726 if (0 != next_out_buffer_used) 1727 { 1728 memmove (urh->out_buffer, 1729 &urh->out_buffer[res], 1730 next_out_buffer_used); 1731 } 1732 urh->out_buffer_used = next_out_buffer_used; 1733 } 1734 if ( (0 == urh->out_buffer_used) && 1735 (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) ) 1736 { 1737 /* Unrecoverable error on socket was detected and all 1738 * pending data was sent to remote. */ 1739 /* Do not try to send to remote anymore. */ 1740 urh->app.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY); 1741 /* Do not try to pull more data from application. */ 1742 urh->out_buffer_size = 0; 1743 urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY); 1744 } 1745 } 1746 1747 /* 1748 * handle writing to application 1749 */ 1750 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && 1751 (urh->in_buffer_used > 0) ) 1752 { 1753 ssize_t res; 1754 size_t data_size; 1755 1756 data_size = urh->in_buffer_used; 1757 if (data_size > MHD_SCKT_SEND_MAX_SIZE_) 1758 data_size = MHD_SCKT_SEND_MAX_SIZE_; 1759 1760 res = MHD_send_ (urh->mhd.socket, 1761 urh->in_buffer, 1762 data_size); 1763 if (0 >= res) 1764 { 1765 const int err = MHD_socket_get_error_ (); 1766 if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) && 1767 (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err)) ) 1768 { 1769 urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY); 1770 if (! MHD_SCKT_ERR_IS_EAGAIN_ (err)) 1771 { 1772 /* Socketpair connection shut down or 1773 * persistent / unrecoverable error. */ 1774 #ifdef HAVE_MESSAGES 1775 MHD_DLOG (daemon, 1776 _ ("Failed to forward to application %" PRIu64 \ 1777 " bytes of data received from remote side: %s\n"), 1778 (uint64_t) urh->in_buffer_used, 1779 MHD_socket_strerr_ (err)); 1780 #endif 1781 /* Discard any data received from remote. */ 1782 urh->in_buffer_used = 0; 1783 /* Reading from remote client is not required anymore. */ 1784 urh->in_buffer_size = 0; 1785 urh->app.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY); 1786 connection->tls_read_ready = false; 1787 } 1788 } 1789 } 1790 else /* 0 < res */ 1791 { 1792 const size_t next_in_buffer_used = urh->in_buffer_used - (size_t) res; 1793 if (0 != next_in_buffer_used) 1794 { 1795 memmove (urh->in_buffer, 1796 &urh->in_buffer[res], 1797 next_in_buffer_used); 1798 if (data_size > (size_t) res) 1799 urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY); 1800 } 1801 urh->in_buffer_used = next_in_buffer_used; 1802 } 1803 if ( (0 == urh->in_buffer_used) && 1804 (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ) 1805 { 1806 /* Do not try to push data to application. */ 1807 urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY); 1808 /* Reading from remote client is not required anymore. */ 1809 urh->in_buffer_size = 0; 1810 urh->app.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY); 1811 connection->tls_read_ready = false; 1812 } 1813 } 1814 1815 /* Check whether data is present in TLS buffers 1816 * and incoming forward buffer have some space. */ 1817 if ( (connection->tls_read_ready) && 1818 (urh->in_buffer_used < urh->in_buffer_size) && 1819 (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) ) 1820 daemon->data_already_pending = true; 1821 1822 if ( (daemon->shutdown) && 1823 ( (0 != urh->out_buffer_size) || 1824 (0 != urh->out_buffer_used) ) ) 1825 { 1826 /* Daemon shutting down, discard any remaining forward data. */ 1827 #ifdef HAVE_MESSAGES 1828 if (0 < urh->out_buffer_used) 1829 MHD_DLOG (daemon, 1830 _ ("Failed to forward to remote client %" PRIu64 \ 1831 " bytes of data received from application: daemon shut down.\n"), 1832 (uint64_t) urh->out_buffer_used); 1833 #endif 1834 /* Discard any data unsent to remote. */ 1835 urh->out_buffer_used = 0; 1836 /* Do not try to sent to remote anymore. */ 1837 urh->app.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY); 1838 /* Do not try to pull more data from application. */ 1839 urh->out_buffer_size = 0; 1840 urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY); 1841 } 1842 1843 if (! was_closed && urh->was_closed) 1844 daemon->data_already_pending = true; /* Force processing again */ 1845 } 1846 1847 1848 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 1849 1850 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 1851 #ifdef UPGRADE_SUPPORT 1852 /** 1853 * Main function of the thread that handles an individual connection 1854 * after it was "upgraded" when #MHD_USE_THREAD_PER_CONNECTION is set. 1855 * @remark To be called only from thread that process 1856 * connection's recv(), send() and response. 1857 * 1858 * @param con the connection this thread will handle 1859 */ 1860 static void 1861 thread_main_connection_upgrade (struct MHD_Connection *con) 1862 { 1863 #ifdef HTTPS_SUPPORT 1864 struct MHD_UpgradeResponseHandle *urh = con->urh; 1865 struct MHD_Daemon *daemon = con->daemon; 1866 1867 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 1868 MHD_thread_handle_ID_is_current_thread_ (con->tid) ); 1869 /* Here, we need to bi-directionally forward 1870 until the application tells us that it is done 1871 with the socket; */ 1872 if ( (0 != (daemon->options & MHD_USE_TLS)) && 1873 MHD_D_IS_USING_SELECT_ (daemon)) 1874 { 1875 while ( (0 != urh->in_buffer_size) || 1876 (0 != urh->out_buffer_size) || 1877 (0 != urh->in_buffer_used) || 1878 (0 != urh->out_buffer_used) ) 1879 { 1880 /* use select */ 1881 fd_set rs; 1882 fd_set ws; 1883 fd_set es; 1884 MHD_socket max_fd; 1885 int num_ready; 1886 bool result; 1887 1888 FD_ZERO (&rs); 1889 FD_ZERO (&ws); 1890 FD_ZERO (&es); 1891 max_fd = MHD_INVALID_SOCKET; 1892 result = urh_to_fdset (urh, 1893 &rs, 1894 &ws, 1895 &es, 1896 &max_fd, 1897 FD_SETSIZE); 1898 if (! result) 1899 { 1900 #ifdef HAVE_MESSAGES 1901 MHD_DLOG (con->daemon, 1902 _ ("Error preparing select.\n")); 1903 #endif 1904 break; 1905 } 1906 /* FIXME: does this check really needed? */ 1907 if (MHD_INVALID_SOCKET != max_fd) 1908 { 1909 struct timeval *tvp; 1910 struct timeval tv; 1911 if (((con->tls_read_ready) && 1912 (urh->in_buffer_used < urh->in_buffer_size)) || 1913 (daemon->shutdown)) 1914 { /* No need to wait if incoming data is already pending in TLS buffers. */ 1915 tv.tv_sec = 0; 1916 tv.tv_usec = 0; 1917 tvp = &tv; 1918 } 1919 else 1920 tvp = NULL; 1921 num_ready = MHD_SYS_select_ (max_fd + 1, 1922 &rs, 1923 &ws, 1924 &es, 1925 tvp); 1926 } 1927 else 1928 num_ready = 0; 1929 if (num_ready < 0) 1930 { 1931 const int err = MHD_socket_get_error_ (); 1932 1933 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 1934 continue; 1935 #ifdef HAVE_MESSAGES 1936 MHD_DLOG (con->daemon, 1937 _ ("Error during select (%d): `%s'\n"), 1938 err, 1939 MHD_socket_strerr_ (err)); 1940 #endif 1941 break; 1942 } 1943 urh_from_fdset (urh, 1944 &rs, 1945 &ws, 1946 &es, 1947 (int) FD_SETSIZE); 1948 process_urh (urh); 1949 } 1950 } 1951 #ifdef HAVE_POLL 1952 else if (0 != (daemon->options & MHD_USE_TLS)) 1953 { 1954 /* use poll() */ 1955 struct pollfd p[2]; 1956 memset (p, 1957 0, 1958 sizeof (p)); 1959 p[0].fd = urh->connection->socket_fd; 1960 p[1].fd = urh->mhd.socket; 1961 1962 while ( (0 != urh->in_buffer_size) || 1963 (0 != urh->out_buffer_size) || 1964 (0 != urh->in_buffer_used) || 1965 (0 != urh->out_buffer_used) ) 1966 { 1967 int timeout; 1968 1969 urh_update_pollfd (urh, p); 1970 1971 if (((con->tls_read_ready) && 1972 (urh->in_buffer_used < urh->in_buffer_size)) || 1973 (daemon->shutdown)) 1974 timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */ 1975 else 1976 timeout = -1; 1977 1978 if (MHD_sys_poll_ (p, 1979 2, 1980 timeout) < 0) 1981 { 1982 const int err = MHD_socket_get_error_ (); 1983 1984 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 1985 continue; 1986 #ifdef HAVE_MESSAGES 1987 MHD_DLOG (con->daemon, 1988 _ ("Error during poll: `%s'\n"), 1989 MHD_socket_strerr_ (err)); 1990 #endif 1991 break; 1992 } 1993 urh_from_pollfd (urh, 1994 p); 1995 process_urh (urh); 1996 } 1997 } 1998 /* end POLL */ 1999 #endif 2000 /* end HTTPS */ 2001 #endif /* HTTPS_SUPPORT */ 2002 /* TLS forwarding was finished. Cleanup socketpair. */ 2003 MHD_connection_finish_forward_ (con); 2004 /* Do not set 'urh->clean_ready' yet as 'urh' will be used 2005 * in connection thread for a little while. */ 2006 } 2007 2008 2009 #endif /* UPGRADE_SUPPORT */ 2010 2011 2012 /** 2013 * Get maximum wait period for the connection (the amount of time left before 2014 * connection time out) 2015 * @param c the connection to check 2016 * @return the maximum number of millisecond before the connection must be 2017 * processed again. 2018 */ 2019 static uint64_t 2020 connection_get_wait (struct MHD_Connection *c) 2021 { 2022 const uint64_t now = MHD_monotonic_msec_counter (); 2023 const uint64_t since_actv = now - c->last_activity; 2024 const uint64_t timeout = c->connection_timeout_ms; 2025 uint64_t mseconds_left; 2026 2027 mhd_assert (0 != timeout); 2028 /* Keep the next lines in sync with #connection_check_timedout() to avoid 2029 * undesired side-effects like busy-waiting. */ 2030 if (timeout < since_actv) 2031 { 2032 if (UINT64_MAX / 2 < since_actv) 2033 { 2034 const uint64_t jump_back = c->last_activity - now; 2035 /* Very unlikely that it is more than quarter-million years pause. 2036 * More likely that system clock jumps back. */ 2037 if (5000 >= jump_back) 2038 { /* Jump back is less than 5 seconds, try to recover. */ 2039 return 100; /* Set wait time to 0.1 seconds */ 2040 } 2041 /* Too large jump back */ 2042 } 2043 return 0; /* Connection has timed out */ 2044 } 2045 else if (since_actv == timeout) 2046 { 2047 /* Exact match for timeout and time from last activity. 2048 * Maybe this is just a precise match or this happens because the timer 2049 * resolution is too low. 2050 * Set wait time to 0.1 seconds to avoid busy-waiting with low 2051 * timer resolution as connection is not timed-out yet. */ 2052 return 100; 2053 } 2054 mseconds_left = timeout - since_actv; 2055 2056 return mseconds_left; 2057 } 2058 2059 2060 /** 2061 * Complete the resume of a connection that has its own thread. 2062 * 2063 * This is the thread-per-connection counterpart of 2064 * resume_suspended_connections(): the connection's own thread does the 2065 * bookkeeping for itself instead of waiting for the daemon's thread to 2066 * do it. That is what makes the wake-up reliable -- the notification 2067 * is sent to the connection's own ITC and is acted upon by the only 2068 * thread that reads it, so it can neither be consumed by the daemon's 2069 * thread nor be missed between the check of @e resuming and the wait. 2070 * 2071 * @param connection the suspended connection that is to be resumed, 2072 * must have @e resuming set 2073 */ 2074 static void 2075 resume_connection_own_thread_ (struct MHD_Connection *connection) 2076 { 2077 struct MHD_Daemon *const daemon = connection->daemon; 2078 2079 mhd_assert (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)); 2080 mhd_assert (! MHD_D_IS_USING_EPOLL_ (daemon)); 2081 #ifdef UPGRADE_SUPPORT 2082 mhd_assert (NULL == connection->urh); 2083 #endif /* UPGRADE_SUPPORT */ 2084 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2085 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 2086 #endif 2087 mhd_assert (connection->suspended); 2088 mhd_assert (connection->resuming); 2089 DLL_remove (daemon->suspended_connections_head, 2090 daemon->suspended_connections_tail, 2091 connection); 2092 connection->suspended = false; 2093 DLL_insert (daemon->connections_head, 2094 daemon->connections_tail, 2095 connection); 2096 connection->resuming = false; 2097 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2098 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 2099 #endif 2100 /* Drop the notification that led here, as well as any notification 2101 left over from a resume that was undone by a suspend before this 2102 thread got to see it. */ 2103 MHD_itc_clear_ (connection->resume_itc); 2104 } 2105 2106 2107 /** 2108 * Main function of the thread that handles an individual 2109 * connection when #MHD_USE_THREAD_PER_CONNECTION is set. 2110 * 2111 * @param data the `struct MHD_Connection` this thread will handle 2112 * @return always 0 2113 */ 2114 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ 2115 thread_main_handle_connection (void *data) 2116 { 2117 struct MHD_Connection *con = data; 2118 struct MHD_Daemon *daemon = con->daemon; 2119 int num_ready; 2120 fd_set rs; 2121 fd_set ws; 2122 fd_set es; 2123 MHD_socket maxsock; 2124 #ifdef WINDOWS 2125 #ifdef HAVE_POLL 2126 unsigned int extra_slot; 2127 #endif /* HAVE_POLL */ 2128 #define EXTRA_SLOTS 1 2129 #else /* !WINDOWS */ 2130 #define EXTRA_SLOTS 0 2131 #endif /* !WINDOWS */ 2132 #ifdef HAVE_POLL 2133 struct pollfd p[1 + EXTRA_SLOTS]; 2134 #endif 2135 #undef EXTRA_SLOTS 2136 #ifdef HAVE_POLL 2137 const bool use_poll = MHD_D_IS_USING_POLL_ (daemon); 2138 #else /* ! HAVE_POLL */ 2139 const bool use_poll = 0; 2140 #endif /* ! HAVE_POLL */ 2141 bool was_suspended = false; 2142 MHD_thread_handle_ID_set_current_thread_ID_ (&(con->tid)); 2143 2144 while ( (! daemon->shutdown) && 2145 (MHD_CONNECTION_CLOSED != con->state) ) 2146 { 2147 bool use_zero_timeout; 2148 #ifdef UPGRADE_SUPPORT 2149 struct MHD_UpgradeResponseHandle *const urh = con->urh; 2150 #else /* ! UPGRADE_SUPPORT */ 2151 static const void *const urh = NULL; 2152 #endif /* ! UPGRADE_SUPPORT */ 2153 2154 if ( (con->suspended) && 2155 (NULL == urh) ) 2156 { 2157 /* Connection was suspended, wait for resume. */ 2158 was_suspended = true; 2159 if (con->resuming) 2160 { 2161 /* The application resumed this connection. Complete the resume 2162 right here: this thread is the only one that handles this 2163 connection, and doing it here is what keeps the wake-up below 2164 free of lost-notification races. */ 2165 resume_connection_own_thread_ (con); 2166 continue; 2167 } 2168 mhd_assert (MHD_ITC_IS_VALID_ (con->resume_itc)); 2169 if (! use_poll) 2170 { 2171 FD_ZERO (&rs); 2172 if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (con->resume_itc), 2173 &rs, 2174 NULL, 2175 FD_SETSIZE)) 2176 { 2177 #ifdef HAVE_MESSAGES 2178 MHD_DLOG (con->daemon, 2179 _ ("Failed to add FD to fd_set.\n")); 2180 #endif 2181 goto exit; 2182 } 2183 if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (con->resume_itc) + 1, 2184 &rs, 2185 NULL, 2186 NULL, 2187 NULL)) 2188 { 2189 const int err = MHD_socket_get_error_ (); 2190 2191 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 2192 continue; 2193 #ifdef HAVE_MESSAGES 2194 MHD_DLOG (con->daemon, 2195 _ ("Error during select (%d): `%s'\n"), 2196 err, 2197 MHD_socket_strerr_ (err)); 2198 #endif 2199 break; 2200 } 2201 } 2202 #ifdef HAVE_POLL 2203 else /* use_poll */ 2204 { 2205 p[0].events = POLLIN; 2206 p[0].fd = MHD_itc_r_fd_ (con->resume_itc); 2207 p[0].revents = 0; 2208 if (0 > MHD_sys_poll_ (p, 2209 1, 2210 -1)) 2211 { 2212 if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_)) 2213 continue; 2214 #ifdef HAVE_MESSAGES 2215 MHD_DLOG (con->daemon, 2216 _ ("Error during poll: `%s'\n"), 2217 MHD_socket_last_strerr_ ()); 2218 #endif 2219 break; 2220 } 2221 } 2222 #endif /* HAVE_POLL */ 2223 MHD_itc_clear_ (con->resume_itc); 2224 continue; /* Check again for resume. */ 2225 } /* End of "suspended" branch. */ 2226 2227 if (was_suspended) 2228 { 2229 MHD_update_last_activity_ (con); /* Reset timeout timer. */ 2230 /* Process response queued during suspend and update states. */ 2231 MHD_connection_handle_idle (con); 2232 was_suspended = false; 2233 } 2234 2235 use_zero_timeout = 2236 (0 != (MHD_EVENT_LOOP_INFO_PROCESS & con->event_loop_info) 2237 #ifdef HTTPS_SUPPORT 2238 || ( (con->tls_read_ready) && 2239 (0 != (MHD_EVENT_LOOP_INFO_READ & con->event_loop_info)) ) 2240 #endif /* HTTPS_SUPPORT */ 2241 ); 2242 if (! use_poll) 2243 { 2244 /* use select */ 2245 bool err_state = false; 2246 struct timeval tv; 2247 struct timeval *tvp; 2248 if (use_zero_timeout) 2249 { 2250 tv.tv_sec = 0; 2251 tv.tv_usec = 0; 2252 tvp = &tv; 2253 } 2254 else if (con->connection_timeout_ms > 0) 2255 { 2256 const uint64_t mseconds_left = connection_get_wait (con); 2257 #if (SIZEOF_UINT64_T - 2) >= SIZEOF_STRUCT_TIMEVAL_TV_SEC 2258 if (mseconds_left / 1000 > TIMEVAL_TV_SEC_MAX) 2259 tv.tv_sec = TIMEVAL_TV_SEC_MAX; 2260 else 2261 #endif /* (SIZEOF_UINT64_T - 2) >= SIZEOF_STRUCT_TIMEVAL_TV_SEC */ 2262 tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) mseconds_left / 1000; 2263 2264 tv.tv_usec = ((uint16_t) (mseconds_left % 1000)) * ((int32_t) 1000); 2265 tvp = &tv; 2266 } 2267 else 2268 tvp = NULL; 2269 2270 FD_ZERO (&rs); 2271 FD_ZERO (&ws); 2272 FD_ZERO (&es); 2273 maxsock = MHD_INVALID_SOCKET; 2274 switch (con->event_loop_info) 2275 { 2276 case MHD_EVENT_LOOP_INFO_READ: 2277 case MHD_EVENT_LOOP_INFO_PROCESS_READ: 2278 if (! MHD_add_to_fd_set_ (con->socket_fd, 2279 &rs, 2280 &maxsock, 2281 FD_SETSIZE)) 2282 err_state = true; 2283 break; 2284 case MHD_EVENT_LOOP_INFO_WRITE: 2285 if (! MHD_add_to_fd_set_ (con->socket_fd, 2286 &ws, 2287 &maxsock, 2288 FD_SETSIZE)) 2289 err_state = true; 2290 break; 2291 case MHD_EVENT_LOOP_INFO_PROCESS: 2292 if (! MHD_add_to_fd_set_ (con->socket_fd, 2293 &es, 2294 &maxsock, 2295 FD_SETSIZE)) 2296 err_state = true; 2297 break; 2298 case MHD_EVENT_LOOP_INFO_CLEANUP: 2299 /* how did we get here!? */ 2300 goto exit; 2301 } 2302 #ifdef WINDOWS 2303 if (MHD_ITC_IS_VALID_ (daemon->itc) ) 2304 { 2305 if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), 2306 &rs, 2307 &maxsock, 2308 FD_SETSIZE)) 2309 err_state = 1; 2310 } 2311 #endif 2312 if (err_state) 2313 { 2314 #ifdef HAVE_MESSAGES 2315 MHD_DLOG (con->daemon, 2316 _ ("Failed to add FD to fd_set.\n")); 2317 #endif 2318 goto exit; 2319 } 2320 2321 num_ready = MHD_SYS_select_ (maxsock + 1, 2322 &rs, 2323 &ws, 2324 &es, 2325 tvp); 2326 if (num_ready < 0) 2327 { 2328 const int err = MHD_socket_get_error_ (); 2329 2330 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 2331 continue; 2332 #ifdef HAVE_MESSAGES 2333 MHD_DLOG (con->daemon, 2334 _ ("Error during select (%d): `%s'\n"), 2335 err, 2336 MHD_socket_strerr_ (err)); 2337 #endif 2338 break; 2339 } 2340 #ifdef WINDOWS 2341 /* Clear ITC before other processing so additional 2342 * signals will trigger select() again */ 2343 if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && 2344 (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), 2345 &rs)) ) 2346 MHD_itc_clear_ (daemon->itc); 2347 #endif 2348 if (MHD_NO == 2349 call_handlers (con, 2350 FD_ISSET (con->socket_fd, 2351 &rs), 2352 FD_ISSET (con->socket_fd, 2353 &ws), 2354 FD_ISSET (con->socket_fd, 2355 &es)) ) 2356 goto exit; 2357 } 2358 #ifdef HAVE_POLL 2359 else 2360 { 2361 int timeout_val; 2362 /* use poll */ 2363 if (use_zero_timeout) 2364 timeout_val = 0; 2365 else if (con->connection_timeout_ms > 0) 2366 { 2367 const uint64_t mseconds_left = connection_get_wait (con); 2368 #if SIZEOF_UINT64_T >= SIZEOF_INT 2369 if (mseconds_left >= INT_MAX) 2370 timeout_val = INT_MAX; 2371 else 2372 #endif /* SIZEOF_UINT64_T >= SIZEOF_INT */ 2373 timeout_val = (int) mseconds_left; 2374 } 2375 else 2376 timeout_val = -1; 2377 memset (&p, 2378 0, 2379 sizeof (p)); 2380 p[0].fd = con->socket_fd; 2381 switch (con->event_loop_info) 2382 { 2383 case MHD_EVENT_LOOP_INFO_READ: 2384 case MHD_EVENT_LOOP_INFO_PROCESS_READ: 2385 p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; 2386 break; 2387 case MHD_EVENT_LOOP_INFO_WRITE: 2388 p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; 2389 break; 2390 case MHD_EVENT_LOOP_INFO_PROCESS: 2391 p[0].events |= MHD_POLL_EVENTS_ERR_DISC; 2392 break; 2393 case MHD_EVENT_LOOP_INFO_CLEANUP: 2394 /* how did we get here!? */ 2395 goto exit; 2396 } 2397 #ifdef WINDOWS 2398 extra_slot = 0; 2399 if (MHD_ITC_IS_VALID_ (daemon->itc)) 2400 { 2401 p[1].events |= POLLIN; 2402 p[1].fd = MHD_itc_r_fd_ (daemon->itc); 2403 p[1].revents = 0; 2404 extra_slot = 1; 2405 } 2406 #endif 2407 if (MHD_sys_poll_ (p, 2408 #ifdef WINDOWS 2409 1 + extra_slot, 2410 #else 2411 1, 2412 #endif 2413 timeout_val) < 0) 2414 { 2415 if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_)) 2416 continue; 2417 #ifdef HAVE_MESSAGES 2418 MHD_DLOG (con->daemon, 2419 _ ("Error during poll: `%s'\n"), 2420 MHD_socket_last_strerr_ ()); 2421 #endif 2422 break; 2423 } 2424 #ifdef WINDOWS 2425 /* Clear ITC before other processing so additional 2426 * signals will trigger poll() again */ 2427 if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && 2428 (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) ) 2429 MHD_itc_clear_ (daemon->itc); 2430 #endif 2431 if (MHD_NO == 2432 call_handlers (con, 2433 (0 != (p[0].revents & POLLIN)), 2434 (0 != (p[0].revents & POLLOUT)), 2435 (0 != (p[0].revents & MHD_POLL_REVENTS_ERR_DISC)) )) 2436 goto exit; 2437 } 2438 #endif 2439 #ifdef UPGRADE_SUPPORT 2440 if (MHD_CONNECTION_UPGRADE == con->state) 2441 { 2442 /* Normal HTTP processing is finished, 2443 * notify application. */ 2444 if ( (NULL != daemon->notify_completed) && 2445 (con->rq.client_aware) ) 2446 daemon->notify_completed (daemon->notify_completed_cls, 2447 con, 2448 &con->rq.client_context, 2449 MHD_REQUEST_TERMINATED_COMPLETED_OK); 2450 con->rq.client_aware = false; 2451 2452 thread_main_connection_upgrade (con); 2453 /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */ 2454 2455 /* "Upgraded" data will not be used in this thread from this point. */ 2456 con->urh->clean_ready = true; 2457 /* If 'urh->was_closed' set to true, connection will be 2458 * moved immediately to cleanup list. Otherwise connection 2459 * will stay in suspended list until 'urh' will be marked 2460 * with 'was_closed' by application. */ 2461 MHD_resume_connection (con); 2462 2463 /* skip usual clean up */ 2464 return (MHD_THRD_RTRN_TYPE_) 0; 2465 } 2466 #endif /* UPGRADE_SUPPORT */ 2467 } 2468 #if _MHD_DEBUG_CLOSE 2469 #ifdef HAVE_MESSAGES 2470 MHD_DLOG (con->daemon, 2471 _ ("Processing thread terminating. Closing connection.\n")); 2472 #endif 2473 #endif 2474 if (MHD_CONNECTION_CLOSED != con->state) 2475 MHD_connection_close_ (con, 2476 (daemon->shutdown) ? 2477 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN : 2478 MHD_REQUEST_TERMINATED_WITH_ERROR); 2479 MHD_connection_handle_idle (con); 2480 exit: 2481 if (NULL != con->rp.response) 2482 { 2483 MHD_destroy_response (con->rp.response); 2484 con->rp.response = NULL; 2485 } 2486 2487 if (MHD_INVALID_SOCKET != con->socket_fd) 2488 { 2489 shutdown (con->socket_fd, 2490 SHUT_WR); 2491 /* 'socket_fd' can be used in other thread to signal shutdown. 2492 * To avoid data races, do not close socket here. Daemon will 2493 * use more connections only after cleanup anyway. */ 2494 } 2495 if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && 2496 (! MHD_itc_activate_ (daemon->itc, "t")) ) 2497 { 2498 #ifdef HAVE_MESSAGES 2499 MHD_DLOG (daemon, 2500 _ ("Failed to signal thread termination via inter-thread " \ 2501 "communication channel.\n")); 2502 #endif 2503 } 2504 return (MHD_THRD_RTRN_TYPE_) 0; 2505 } 2506 2507 2508 #endif 2509 2510 2511 /** 2512 * Free resources associated with all closed connections. 2513 * (destroy responses, free buffers, etc.). All closed 2514 * connections are kept in the "cleanup" doubly-linked list. 2515 * 2516 * @param daemon daemon to clean up 2517 */ 2518 static void 2519 MHD_cleanup_connections (struct MHD_Daemon *daemon); 2520 2521 #if defined(HTTPS_SUPPORT) 2522 #if defined(MHD_SEND_SPIPE_SUPPRESS_NEEDED) && \ 2523 defined(MHD_SEND_SPIPE_SUPPRESS_POSSIBLE) && \ 2524 ! defined(MHD_socket_nosignal_) && \ 2525 (GNUTLS_VERSION_NUMBER + 0 < 0x030402) && defined(MSG_NOSIGNAL) 2526 /** 2527 * Older version of GnuTLS do not support suppressing of SIGPIPE signal. 2528 * Use push function replacement with suppressing SIGPIPE signal where necessary 2529 * and if possible. 2530 */ 2531 #define MHD_TLSLIB_NEED_PUSH_FUNC 1 2532 #endif /* MHD_SEND_SPIPE_SUPPRESS_NEEDED && 2533 MHD_SEND_SPIPE_SUPPRESS_POSSIBLE && 2534 ! MHD_socket_nosignal_ && (GNUTLS_VERSION_NUMBER+0 < 0x030402) && 2535 MSG_NOSIGNAL */ 2536 2537 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC 2538 /** 2539 * Data push function replacement with suppressing SIGPIPE signal 2540 * for TLS library. 2541 */ 2542 static ssize_t 2543 MHD_tls_push_func_ (gnutls_transport_ptr_t trnsp, 2544 const void *data, 2545 size_t data_size) 2546 { 2547 #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) 2548 if (data_size > MHD_SCKT_SEND_MAX_SIZE_) 2549 data_size = MHD_SCKT_SEND_MAX_SIZE_; 2550 #endif /* (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) */ 2551 return MHD_send_ ((MHD_socket) (intptr_t) (trnsp), data, data_size); 2552 } 2553 2554 2555 #endif /* MHD_TLSLIB_DONT_SUPPRESS_SIGPIPE */ 2556 2557 2558 /** 2559 * The shortest pre-shared key #MHD_OPTION_GNUTLS_PSK_CRED_HANDLER may 2560 * hand back, in bytes. RFC 4279 section 7.1 requires at least 16 bytes 2561 * of entropy in a PSK and recommends the length of the hash of the 2562 * negotiated cipher suite; anything shorter is brute-forceable offline 2563 * from a single recorded handshake, so MHD refuses it rather than let 2564 * the application weaken the connection by accident. 2565 */ 2566 #define MHD_PSK_MIN_SIZE 16 2567 2568 /** 2569 * Function called by GNUtls to obtain the PSK for a given session. 2570 * 2571 * @param session the session to lookup PSK for 2572 * @param username username to lookup PSK for 2573 * @param[out] key where to write PSK 2574 * @return 0 on success, -1 on error 2575 */ 2576 static int 2577 psk_gnutls_adapter (gnutls_session_t session, 2578 const char *username, 2579 gnutls_datum_t *key) 2580 { 2581 struct MHD_Connection *connection; 2582 struct MHD_Daemon *daemon; 2583 #if GNUTLS_VERSION_MAJOR >= 3 2584 void *app_psk; 2585 size_t app_psk_size; 2586 #endif /* GNUTLS_VERSION_MAJOR >= 3 */ 2587 2588 connection = gnutls_session_get_ptr (session); 2589 if (NULL == connection) 2590 { 2591 #ifdef HAVE_MESSAGES 2592 /* Cannot use our logger, we don't even have "daemon" */ 2593 MHD_PANIC (_ ("Internal server error. This should be impossible.\n")); 2594 #endif 2595 return -1; 2596 } 2597 daemon = connection->daemon; 2598 #if GNUTLS_VERSION_MAJOR >= 3 2599 if (NULL == daemon->cred_callback) 2600 { 2601 #ifdef HAVE_MESSAGES 2602 MHD_DLOG (daemon, 2603 _ ("PSK not supported by this server.\n")); 2604 #endif 2605 return -1; 2606 } 2607 if (0 != daemon->cred_callback (daemon->cred_callback_cls, 2608 connection, 2609 username, 2610 &app_psk, 2611 &app_psk_size)) 2612 return -1; 2613 if (MHD_PSK_MIN_SIZE > app_psk_size) 2614 { 2615 #ifdef HAVE_MESSAGES 2616 MHD_DLOG (daemon, 2617 _ ("PSK authentication failed: PSK too short.\n")); 2618 #endif 2619 free (app_psk); 2620 return -1; 2621 } 2622 if (UINT_MAX < app_psk_size) 2623 { 2624 #ifdef HAVE_MESSAGES 2625 MHD_DLOG (daemon, 2626 _ ("PSK authentication failed: PSK too long.\n")); 2627 #endif 2628 free (app_psk); 2629 return -1; 2630 } 2631 /* @a app_psk_size is at least MHD_PSK_MIN_SIZE here, so this is never 2632 gnutls_malloc(0) -- whose result is implementation defined and would 2633 be reported below as an allocation failure. */ 2634 if (NULL == (key->data = gnutls_malloc (app_psk_size))) 2635 { 2636 #ifdef HAVE_MESSAGES 2637 MHD_DLOG (daemon, 2638 _ ("PSK authentication failed: gnutls_malloc failed to " \ 2639 "allocate memory.\n")); 2640 #endif 2641 free (app_psk); 2642 return -1; 2643 } 2644 key->size = (unsigned int) app_psk_size; 2645 memcpy (key->data, 2646 app_psk, 2647 app_psk_size); 2648 free (app_psk); 2649 return 0; 2650 #else 2651 (void) username; (void) key; /* Mute compiler warning */ 2652 #ifdef HAVE_MESSAGES 2653 MHD_DLOG (daemon, 2654 _ ("PSK not supported by this server.\n")); 2655 #endif 2656 return -1; 2657 #endif 2658 } 2659 2660 2661 #endif /* HTTPS_SUPPORT */ 2662 2663 2664 /** 2665 * Do basic preparation work on the new incoming connection. 2666 * 2667 * This function do all preparation that is possible outside main daemon 2668 * thread. 2669 * @remark Could be called from any thread. 2670 * 2671 * @param daemon daemon that manages the connection 2672 * @param client_socket socket to manage (MHD will expect 2673 * to receive an HTTP request from this socket next). 2674 * @param addr IP address of the client 2675 * @param addrlen number of bytes in @a addr 2676 * @param external_add indicate that socket has been added externally 2677 * @param non_blck indicate that socket in non-blocking mode 2678 * @param sk_spipe_supprs indicate that the @a client_socket has 2679 * set SIGPIPE suppression 2680 * @param sk_is_nonip _MHD_YES if this is not a TCP/IP socket 2681 * @return pointer to the connection on success, NULL if this daemon could 2682 * not handle the connection (i.e. malloc failed, etc). 2683 * The socket will be closed in case of error; 'errno' is 2684 * set to indicate further details about the error. 2685 */ 2686 static struct MHD_Connection * 2687 new_connection_prepare_ (struct MHD_Daemon *daemon, 2688 MHD_socket client_socket, 2689 const struct sockaddr_storage *addr, 2690 socklen_t addrlen, 2691 bool external_add, 2692 bool non_blck, 2693 bool sk_spipe_supprs, 2694 enum MHD_tristate sk_is_nonip) 2695 { 2696 struct MHD_Connection *connection; 2697 int eno = 0; 2698 2699 #ifdef HAVE_MESSAGES 2700 #if _MHD_DEBUG_CONNECT 2701 MHD_DLOG (daemon, 2702 _ ("Accepted connection on socket %d.\n"), 2703 client_socket); 2704 #endif 2705 #endif 2706 if ( (daemon->connections == daemon->connection_limit) || 2707 (MHD_NO == MHD_ip_limit_add (daemon, 2708 addr, 2709 addrlen)) ) 2710 { 2711 /* above connection limit - reject */ 2712 #ifdef HAVE_MESSAGES 2713 MHD_DLOG (daemon, 2714 _ ("Server reached connection limit. " \ 2715 "Closing inbound connection.\n")); 2716 #endif 2717 MHD_socket_close_chk_ (client_socket); 2718 #if defined(ENFILE) && (ENFILE + 0 != 0) 2719 errno = ENFILE; 2720 #endif 2721 return NULL; 2722 } 2723 2724 /* apply connection acceptance policy if present */ 2725 if ( (NULL != daemon->apc) && 2726 (MHD_NO == daemon->apc (daemon->apc_cls, 2727 (const struct sockaddr *) addr, 2728 addrlen)) ) 2729 { 2730 #if _MHD_DEBUG_CLOSE 2731 #ifdef HAVE_MESSAGES 2732 MHD_DLOG (daemon, 2733 _ ("Connection rejected by application. Closing connection.\n")); 2734 #endif 2735 #endif 2736 MHD_socket_close_chk_ (client_socket); 2737 MHD_ip_limit_del (daemon, 2738 addr, 2739 addrlen); 2740 #if defined(EACCESS) && (EACCESS + 0 != 0) 2741 errno = EACCESS; 2742 #endif 2743 return NULL; 2744 } 2745 2746 if (NULL == (connection = MHD_calloc_ (1, sizeof (struct MHD_Connection)))) 2747 { 2748 eno = errno; 2749 #ifdef HAVE_MESSAGES 2750 MHD_DLOG (daemon, 2751 _ ("Error allocating memory: %s\n"), 2752 MHD_strerror_ (errno)); 2753 #endif 2754 MHD_socket_close_chk_ (client_socket); 2755 MHD_ip_limit_del (daemon, 2756 addr, 2757 addrlen); 2758 errno = eno; 2759 return NULL; 2760 } 2761 2762 if (! external_add) 2763 { 2764 connection->sk_corked = _MHD_OFF; 2765 connection->sk_nodelay = _MHD_OFF; 2766 } 2767 else 2768 { 2769 connection->sk_corked = _MHD_UNKNOWN; 2770 connection->sk_nodelay = _MHD_UNKNOWN; 2771 } 2772 2773 if (0 < addrlen) 2774 { 2775 if (NULL == (connection->addr = malloc ((size_t) addrlen))) 2776 { 2777 eno = errno; 2778 #ifdef HAVE_MESSAGES 2779 MHD_DLOG (daemon, 2780 _ ("Error allocating memory: %s\n"), 2781 MHD_strerror_ (errno)); 2782 #endif 2783 MHD_socket_close_chk_ (client_socket); 2784 MHD_ip_limit_del (daemon, 2785 addr, 2786 addrlen); 2787 free (connection); 2788 errno = eno; 2789 return NULL; 2790 } 2791 memcpy (connection->addr, 2792 addr, 2793 (size_t) addrlen); 2794 } 2795 else 2796 connection->addr = NULL; 2797 connection->addr_len = addrlen; 2798 connection->socket_fd = client_socket; 2799 connection->sk_nonblck = non_blck; 2800 connection->is_nonip = sk_is_nonip; 2801 connection->sk_spipe_suppress = sk_spipe_supprs; 2802 #ifdef MHD_USE_THREADS 2803 MHD_thread_handle_ID_set_invalid_ (&connection->tid); 2804 #endif /* MHD_USE_THREADS */ 2805 connection->daemon = daemon; 2806 connection->connection_timeout_ms = daemon->connection_timeout_ms; 2807 connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ; 2808 if (0 != connection->connection_timeout_ms) 2809 connection->last_activity = MHD_monotonic_msec_counter (); 2810 2811 MHD_itc_set_invalid_ (connection->resume_itc); 2812 if ( (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) && 2813 (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) && 2814 (! MHD_itc_init_ (connection->resume_itc)) ) 2815 { 2816 eno = errno; 2817 #ifdef HAVE_MESSAGES 2818 MHD_DLOG (daemon, 2819 _ ("Failed to create inter-thread communication channel " \ 2820 "for the connection: %s\n"), 2821 MHD_itc_last_strerror_ ()); 2822 #endif 2823 MHD_socket_close_chk_ (client_socket); 2824 MHD_ip_limit_del (daemon, 2825 addr, 2826 addrlen); 2827 if (NULL != connection->addr) 2828 free (connection->addr); 2829 free (connection); 2830 errno = eno; 2831 return NULL; 2832 } 2833 2834 if (0 == (daemon->options & MHD_USE_TLS)) 2835 { 2836 /* set default connection handlers */ 2837 MHD_set_http_callbacks_ (connection); 2838 } 2839 else 2840 { 2841 #ifdef HTTPS_SUPPORT 2842 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030500) 2843 gnutls_init_flags_t 2844 #else 2845 unsigned int 2846 #endif 2847 flags; 2848 2849 flags = GNUTLS_SERVER; 2850 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030402) 2851 flags |= GNUTLS_NO_SIGNAL; 2852 #endif /* GNUTLS_VERSION_NUMBER >= 0x030402 */ 2853 #if GNUTLS_VERSION_MAJOR >= 3 2854 flags |= GNUTLS_NONBLOCK; 2855 #endif /* GNUTLS_VERSION_MAJOR >= 3*/ 2856 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030603) 2857 if (0 != (daemon->options & MHD_USE_POST_HANDSHAKE_AUTH_SUPPORT)) 2858 flags |= GNUTLS_POST_HANDSHAKE_AUTH; 2859 #endif 2860 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030605) 2861 if (0 != (daemon->options & MHD_USE_INSECURE_TLS_EARLY_DATA)) 2862 flags |= GNUTLS_ENABLE_EARLY_DATA; 2863 #endif 2864 connection->tls_state = MHD_TLS_CONN_INIT; 2865 MHD_set_https_callbacks (connection); 2866 if ((GNUTLS_E_SUCCESS != gnutls_init (&connection->tls_session, flags)) || 2867 (GNUTLS_E_SUCCESS != gnutls_priority_set (connection->tls_session, 2868 daemon->priority_cache))) 2869 { 2870 if (NULL != connection->tls_session) 2871 gnutls_deinit (connection->tls_session); 2872 MHD_socket_close_chk_ (client_socket); 2873 MHD_ip_limit_del (daemon, 2874 addr, 2875 addrlen); 2876 if (NULL != connection->addr) 2877 free (connection->addr); 2878 free (connection); 2879 #ifdef HAVE_MESSAGES 2880 MHD_DLOG (daemon, 2881 _ ("Failed to initialise TLS session.\n")); 2882 #endif 2883 #if defined(EPROTO) && (EPROTO + 0 != 0) 2884 errno = EPROTO; 2885 #endif 2886 return NULL; 2887 } 2888 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030200) 2889 if (! daemon->disable_alpn) 2890 { 2891 static const char prt1[] = "http/1.1"; /* Registered code for HTTP/1.1 */ 2892 static const char prt2[] = "http/1.0"; /* Registered code for HTTP/1.0 */ 2893 static const gnutls_datum_t prts[2] = 2894 { {_MHD_DROP_CONST (prt1), MHD_STATICSTR_LEN_ (prt1)}, 2895 {_MHD_DROP_CONST (prt2), MHD_STATICSTR_LEN_ (prt2)} }; 2896 2897 if (GNUTLS_E_SUCCESS != 2898 gnutls_alpn_set_protocols (connection->tls_session, 2899 prts, 2900 sizeof(prts) / sizeof(prts[0]), 2901 0 /* | GNUTLS_ALPN_SERVER_PRECEDENCE */)) 2902 { 2903 #ifdef HAVE_MESSAGES 2904 MHD_DLOG (daemon, 2905 _ ("Failed to set ALPN protocols.\n")); 2906 #else /* ! HAVE_MESSAGES */ 2907 (void) 0; /* Mute compiler warning */ 2908 #endif /* ! HAVE_MESSAGES */ 2909 } 2910 } 2911 #endif /* GNUTLS_VERSION_NUMBER >= 0x030200 */ 2912 gnutls_session_set_ptr (connection->tls_session, 2913 connection); 2914 switch (daemon->cred_type) 2915 { 2916 /* set needed credentials for certificate authentication. */ 2917 case GNUTLS_CRD_CERTIFICATE: 2918 gnutls_credentials_set (connection->tls_session, 2919 GNUTLS_CRD_CERTIFICATE, 2920 daemon->x509_cred); 2921 break; 2922 case GNUTLS_CRD_PSK: 2923 gnutls_credentials_set (connection->tls_session, 2924 GNUTLS_CRD_PSK, 2925 daemon->psk_cred); 2926 gnutls_psk_set_server_credentials_function (daemon->psk_cred, 2927 &psk_gnutls_adapter); 2928 break; 2929 case GNUTLS_CRD_ANON: 2930 case GNUTLS_CRD_SRP: 2931 case GNUTLS_CRD_IA: 2932 default: 2933 #ifdef HAVE_MESSAGES 2934 MHD_DLOG (daemon, 2935 _ ("Failed to setup TLS credentials: " \ 2936 "unknown credential type %d.\n"), 2937 daemon->cred_type); 2938 #endif 2939 gnutls_deinit (connection->tls_session); 2940 MHD_socket_close_chk_ (client_socket); 2941 MHD_ip_limit_del (daemon, 2942 addr, 2943 addrlen); 2944 if (NULL != connection->addr) 2945 free (connection->addr); 2946 free (connection); 2947 MHD_PANIC (_ ("Unknown credential type.\n")); 2948 #if defined(EINVAL) && (EINVAL + 0 != 0) 2949 errno = EINVAL; 2950 #endif 2951 return NULL; 2952 } 2953 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030109) && ! defined(_WIN64) 2954 gnutls_transport_set_int (connection->tls_session, 2955 (int) (client_socket)); 2956 #else /* GnuTLS before 3.1.9 or Win x64 */ 2957 gnutls_transport_set_ptr (connection->tls_session, 2958 (gnutls_transport_ptr_t) \ 2959 (intptr_t) client_socket); 2960 #endif /* GnuTLS before 3.1.9 or Win x64 */ 2961 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC 2962 gnutls_transport_set_push_function (connection->tls_session, 2963 MHD_tls_push_func_); 2964 #endif /* MHD_TLSLIB_NEED_PUSH_FUNC */ 2965 if (daemon->https_mem_trust) 2966 gnutls_certificate_server_set_request (connection->tls_session, 2967 GNUTLS_CERT_REQUEST); 2968 #else /* ! HTTPS_SUPPORT */ 2969 MHD_socket_close_chk_ (client_socket); 2970 MHD_ip_limit_del (daemon, 2971 addr, 2972 addrlen); 2973 free (connection->addr); 2974 free (connection); 2975 MHD_PANIC (_ ("TLS connection on non-TLS daemon.\n")); 2976 #if 0 2977 /* Unreachable code */ 2978 eno = EINVAL; 2979 return NULL; 2980 #endif 2981 #endif /* ! HTTPS_SUPPORT */ 2982 } 2983 2984 return connection; 2985 } 2986 2987 2988 #ifdef MHD_USE_THREADS 2989 /** 2990 * Close prepared, but not yet processed connection. 2991 * @param daemon the daemon 2992 * @param connection the connection to close 2993 */ 2994 static void 2995 new_connection_close_ (struct MHD_Daemon *daemon, 2996 struct MHD_Connection *connection) 2997 { 2998 mhd_assert (connection->daemon == daemon); 2999 mhd_assert (! connection->in_cleanup); 3000 mhd_assert (NULL == connection->next); 3001 mhd_assert (NULL == connection->nextX); 3002 #ifdef EPOLL_SUPPORT 3003 mhd_assert (NULL == connection->nextE); 3004 #endif /* EPOLL_SUPPORT */ 3005 3006 #ifdef HTTPS_SUPPORT 3007 if (NULL != connection->tls_session) 3008 { 3009 mhd_assert (0 != (daemon->options & MHD_USE_TLS)); 3010 gnutls_deinit (connection->tls_session); 3011 } 3012 #endif /* HTTPS_SUPPORT */ 3013 MHD_socket_close_chk_ (connection->socket_fd); 3014 if (MHD_ITC_IS_VALID_ (connection->resume_itc)) 3015 MHD_itc_destroy_chk_ (connection->resume_itc); 3016 MHD_ip_limit_del (daemon, 3017 connection->addr, 3018 connection->addr_len); 3019 if (NULL != connection->addr) 3020 free (connection->addr); 3021 free (connection); 3022 } 3023 3024 3025 #endif /* MHD_USE_THREADS */ 3026 3027 3028 /** 3029 * Finally insert the new connection to the list of connections 3030 * served by the daemon and start processing. 3031 * @remark To be called only from thread that process 3032 * daemon's select()/poll()/etc. 3033 * 3034 * @param daemon daemon that manages the connection 3035 * @param connection the newly created connection 3036 * @return #MHD_YES on success, #MHD_NO on error 3037 */ 3038 static enum MHD_Result 3039 new_connection_process_ (struct MHD_Daemon *daemon, 3040 struct MHD_Connection *connection) 3041 { 3042 int eno = 0; 3043 3044 mhd_assert (connection->daemon == daemon); 3045 3046 #ifdef MHD_USE_THREADS 3047 /* Function manipulate connection and timeout DL-lists, 3048 * must be called only within daemon thread. */ 3049 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 3050 MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); 3051 mhd_assert (NULL == daemon->worker_pool); 3052 #endif /* MHD_USE_THREADS */ 3053 3054 /* Allocate memory pool in the processing thread so 3055 * intensively used memory area is allocated in "good" 3056 * (for the thread) memory region. It is important with 3057 * NUMA and/or complex cache hierarchy. */ 3058 connection->pool = MHD_pool_create (daemon->pool_size); 3059 if (NULL == connection->pool) 3060 { /* 'pool' creation failed */ 3061 #ifdef HAVE_MESSAGES 3062 MHD_DLOG (daemon, 3063 _ ("Error allocating memory: %s\n"), 3064 MHD_strerror_ (errno)); 3065 #endif 3066 #if defined(ENOMEM) && (ENOMEM + 0 != 0) 3067 eno = ENOMEM; 3068 #endif 3069 (void) 0; /* Mute possible compiler warning */ 3070 } 3071 else 3072 { /* 'pool' creation succeed */ 3073 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 3074 /* Firm check under lock. */ 3075 if (daemon->connections >= daemon->connection_limit) 3076 { /* Connections limit */ 3077 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 3078 #ifdef HAVE_MESSAGES 3079 MHD_DLOG (daemon, 3080 _ ("Server reached connection limit. " 3081 "Closing inbound connection.\n")); 3082 #endif 3083 #if defined(ENFILE) && (ENFILE + 0 != 0) 3084 eno = ENFILE; 3085 #endif 3086 (void) 0; /* Mute possible compiler warning */ 3087 } 3088 else 3089 { /* Have space for new connection */ 3090 daemon->connections++; 3091 DLL_insert (daemon->connections_head, 3092 daemon->connections_tail, 3093 connection); 3094 if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) 3095 { 3096 XDLL_insert (daemon->normal_timeout_head, 3097 daemon->normal_timeout_tail, 3098 connection); 3099 } 3100 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 3101 3102 MHD_connection_set_initial_state_ (connection); 3103 3104 if (NULL != daemon->notify_connection) 3105 daemon->notify_connection (daemon->notify_connection_cls, 3106 connection, 3107 &connection->socket_context, 3108 MHD_CONNECTION_NOTIFY_STARTED); 3109 #ifdef MHD_USE_THREADS 3110 if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) 3111 { 3112 mhd_assert (! MHD_D_IS_USING_EPOLL_ (daemon)); 3113 if (! MHD_create_named_thread_ (&connection->tid, 3114 "MHD-connection", 3115 daemon->thread_stack_size, 3116 &thread_main_handle_connection, 3117 connection)) 3118 { 3119 eno = errno; 3120 #ifdef HAVE_MESSAGES 3121 #ifdef EAGAIN 3122 if (EAGAIN == eno) 3123 MHD_DLOG (daemon, 3124 _ ("Failed to create a new thread because it would " 3125 "have exceeded the system limit on the number of " 3126 "threads or no system resources available.\n")); 3127 else 3128 #endif /* EAGAIN */ 3129 MHD_DLOG (daemon, 3130 _ ("Failed to create a thread: %s\n"), 3131 MHD_strerror_ (eno)); 3132 #endif /* HAVE_MESSAGES */ 3133 } 3134 else /* New thread has been created successfully */ 3135 return MHD_YES; /* *** Function success exit point *** */ 3136 } 3137 else 3138 #else /* ! MHD_USE_THREADS */ 3139 if (1) 3140 #endif /* ! MHD_USE_THREADS */ 3141 { /* No 'thread-per-connection' */ 3142 #ifdef MHD_USE_THREADS 3143 connection->tid = daemon->tid; 3144 #endif /* MHD_USE_THREADS */ 3145 #ifdef EPOLL_SUPPORT 3146 if (MHD_D_IS_USING_EPOLL_ (daemon)) 3147 { 3148 if (0 == (daemon->options & MHD_USE_TURBO)) 3149 { 3150 struct epoll_event event; 3151 3152 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET | EPOLLRDHUP; 3153 event.data.ptr = connection; 3154 if (0 != epoll_ctl (daemon->epoll_fd, 3155 EPOLL_CTL_ADD, 3156 connection->socket_fd, 3157 &event)) 3158 { 3159 eno = errno; 3160 #ifdef HAVE_MESSAGES 3161 MHD_DLOG (daemon, 3162 _ ("Call to epoll_ctl failed: %s\n"), 3163 MHD_socket_last_strerr_ ()); 3164 #endif 3165 } 3166 else 3167 { /* 'socket_fd' has been added to 'epool' */ 3168 connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET; 3169 3170 return MHD_YES; /* *** Function success exit point *** */ 3171 } 3172 } 3173 else 3174 { 3175 connection->epoll_state |= MHD_EPOLL_STATE_READ_READY 3176 | MHD_EPOLL_STATE_WRITE_READY 3177 | MHD_EPOLL_STATE_IN_EREADY_EDLL; 3178 EDLL_insert (daemon->eready_head, 3179 daemon->eready_tail, 3180 connection); 3181 3182 return MHD_YES; /* *** Function success exit point *** */ 3183 } 3184 } 3185 else /* No 'epoll' */ 3186 #endif /* EPOLL_SUPPORT */ 3187 return MHD_YES; /* *** Function success exit point *** */ 3188 } 3189 3190 /* ** Below is a cleanup path ** */ 3191 if (NULL != daemon->notify_connection) 3192 daemon->notify_connection (daemon->notify_connection_cls, 3193 connection, 3194 &connection->socket_context, 3195 MHD_CONNECTION_NOTIFY_CLOSED); 3196 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 3197 if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) 3198 { 3199 XDLL_remove (daemon->normal_timeout_head, 3200 daemon->normal_timeout_tail, 3201 connection); 3202 } 3203 DLL_remove (daemon->connections_head, 3204 daemon->connections_tail, 3205 connection); 3206 daemon->connections--; 3207 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 3208 } 3209 MHD_pool_destroy (connection->pool); 3210 } 3211 /* Free resources allocated before the call of this functions */ 3212 #ifdef HTTPS_SUPPORT 3213 if (NULL != connection->tls_session) 3214 gnutls_deinit (connection->tls_session); 3215 #endif /* HTTPS_SUPPORT */ 3216 MHD_ip_limit_del (daemon, 3217 connection->addr, 3218 connection->addr_len); 3219 if (NULL != connection->addr) 3220 free (connection->addr); 3221 MHD_socket_close_chk_ (connection->socket_fd); 3222 free (connection); 3223 if (0 != eno) 3224 errno = eno; 3225 #ifdef EINVAL 3226 else 3227 errno = EINVAL; 3228 #endif /* EINVAL */ 3229 return MHD_NO; /* *** Function failure exit point *** */ 3230 } 3231 3232 3233 /** 3234 * Add another client connection to the set of connections 3235 * managed by MHD. This API is usually not needed (since 3236 * MHD will accept inbound connections on the server socket). 3237 * Use this API in special cases, for example if your HTTP 3238 * server is behind NAT and needs to connect out to the 3239 * HTTP client. 3240 * 3241 * The given client socket will be managed (and closed!) by MHD after 3242 * this call and must no longer be used directly by the application 3243 * afterwards. 3244 * 3245 * @param daemon daemon that manages the connection 3246 * @param client_socket socket to manage (MHD will expect 3247 * to receive an HTTP request from this socket next). 3248 * @param addr IP address of the client 3249 * @param addrlen number of bytes in @a addr 3250 * @param external_add perform additional operations needed due 3251 * to the application calling us directly 3252 * @param non_blck indicate that socket in non-blocking mode 3253 * @param sk_spipe_supprs indicate that the @a client_socket has 3254 * set SIGPIPE suppression 3255 * @param sk_is_nonip _MHD_YES if this is not a TCP/IP socket 3256 * @return #MHD_YES on success, #MHD_NO if this daemon could 3257 * not handle the connection (i.e. malloc failed, etc). 3258 * The socket will be closed in any case; 'errno' is 3259 * set to indicate further details about the error. 3260 */ 3261 static enum MHD_Result 3262 internal_add_connection (struct MHD_Daemon *daemon, 3263 MHD_socket client_socket, 3264 const struct sockaddr_storage *addr, 3265 socklen_t addrlen, 3266 bool external_add, 3267 bool non_blck, 3268 bool sk_spipe_supprs, 3269 enum MHD_tristate sk_is_nonip) 3270 { 3271 struct MHD_Connection *connection; 3272 3273 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3274 /* Direct add to master daemon could never happen. */ 3275 mhd_assert (NULL == daemon->worker_pool); 3276 #endif 3277 3278 if (MHD_D_IS_USING_SELECT_ (daemon) && 3279 (! MHD_D_DOES_SCKT_FIT_FDSET_ (client_socket, daemon)) ) 3280 { 3281 #ifdef HAVE_MESSAGES 3282 MHD_DLOG (daemon, 3283 _ ("New connection socket descriptor (%d) is not less " \ 3284 "than FD_SETSIZE (%d).\n"), 3285 (int) client_socket, 3286 (int) MHD_D_GET_FD_SETSIZE_ (daemon)); 3287 #endif 3288 MHD_socket_close_chk_ (client_socket); 3289 #if defined(ENFILE) && (ENFILE + 0 != 0) 3290 errno = ENFILE; 3291 #endif 3292 return MHD_NO; 3293 } 3294 3295 if (MHD_D_IS_USING_EPOLL_ (daemon) && 3296 (! non_blck) ) 3297 { 3298 #ifdef HAVE_MESSAGES 3299 MHD_DLOG (daemon, 3300 _ ("Epoll mode supports only non-blocking sockets\n")); 3301 #endif 3302 MHD_socket_close_chk_ (client_socket); 3303 #if defined(EINVAL) && (EINVAL + 0 != 0) 3304 errno = EINVAL; 3305 #endif 3306 return MHD_NO; 3307 } 3308 3309 connection = new_connection_prepare_ (daemon, 3310 client_socket, 3311 addr, addrlen, 3312 external_add, 3313 non_blck, 3314 sk_spipe_supprs, 3315 sk_is_nonip); 3316 if (NULL == connection) 3317 return MHD_NO; 3318 3319 if ((external_add) && 3320 MHD_D_IS_THREAD_SAFE_ (daemon)) 3321 { 3322 /* Connection is added externally and MHD is thread safe mode. */ 3323 MHD_mutex_lock_chk_ (&daemon->new_connections_mutex); 3324 DLL_insert (daemon->new_connections_head, 3325 daemon->new_connections_tail, 3326 connection); 3327 daemon->have_new = true; 3328 MHD_mutex_unlock_chk_ (&daemon->new_connections_mutex); 3329 3330 /* The rest of connection processing must be handled in 3331 * the daemon thread. */ 3332 if ((MHD_ITC_IS_VALID_ (daemon->itc)) && 3333 (! MHD_itc_activate_ (daemon->itc, "n"))) 3334 { 3335 #ifdef HAVE_MESSAGES 3336 MHD_DLOG (daemon, 3337 _ ("Failed to signal new connection via inter-thread " \ 3338 "communication channel.\n")); 3339 #endif 3340 } 3341 return MHD_YES; 3342 } 3343 3344 return new_connection_process_ (daemon, connection); 3345 } 3346 3347 3348 static void 3349 new_connections_list_process_ (struct MHD_Daemon *daemon) 3350 { 3351 struct MHD_Connection *local_head; 3352 struct MHD_Connection *local_tail; 3353 mhd_assert (daemon->have_new); 3354 mhd_assert (MHD_D_IS_THREAD_SAFE_ (daemon)); 3355 3356 /* Detach DL-list of new connections from the daemon for 3357 * following local processing. */ 3358 MHD_mutex_lock_chk_ (&daemon->new_connections_mutex); 3359 mhd_assert (NULL != daemon->new_connections_head); 3360 local_head = daemon->new_connections_head; 3361 local_tail = daemon->new_connections_tail; 3362 daemon->new_connections_head = NULL; 3363 daemon->new_connections_tail = NULL; 3364 daemon->have_new = false; 3365 MHD_mutex_unlock_chk_ (&daemon->new_connections_mutex); 3366 (void) local_head; /* Mute compiler warning */ 3367 3368 /* Process new connections in FIFO order. */ 3369 do 3370 { 3371 struct MHD_Connection *c; /**< Currently processed connection */ 3372 3373 c = local_tail; 3374 DLL_remove (local_head, 3375 local_tail, 3376 c); 3377 mhd_assert (daemon == c->daemon); 3378 if (MHD_NO == new_connection_process_ (daemon, c)) 3379 { 3380 #ifdef HAVE_MESSAGES 3381 MHD_DLOG (daemon, 3382 _ ("Failed to start serving new connection.\n")); 3383 #endif 3384 (void) 0; 3385 } 3386 } while (NULL != local_tail); 3387 3388 } 3389 3390 3391 /** 3392 * Internal version of ::MHD_suspend_connection(). 3393 * 3394 * @remark In thread-per-connection mode: can be called from any thread, 3395 * in any other mode: to be called only from thread that process 3396 * daemon's select()/poll()/etc. 3397 * 3398 * @param connection the connection to suspend 3399 */ 3400 void 3401 internal_suspend_connection_ (struct MHD_Connection *connection) 3402 { 3403 struct MHD_Daemon *daemon = connection->daemon; 3404 mhd_assert (NULL == daemon->worker_pool); 3405 3406 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3407 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 3408 MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) || \ 3409 MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); 3410 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 3411 #endif 3412 if (connection->resuming) 3413 { 3414 /* suspending again while we didn't even complete resuming yet */ 3415 connection->resuming = false; 3416 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3417 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 3418 #endif 3419 return; 3420 } 3421 if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) 3422 { 3423 if (connection->connection_timeout_ms == daemon->connection_timeout_ms) 3424 XDLL_remove (daemon->normal_timeout_head, 3425 daemon->normal_timeout_tail, 3426 connection); 3427 else 3428 XDLL_remove (daemon->manual_timeout_head, 3429 daemon->manual_timeout_tail, 3430 connection); 3431 } 3432 DLL_remove (daemon->connections_head, 3433 daemon->connections_tail, 3434 connection); 3435 mhd_assert (! connection->suspended); 3436 DLL_insert (daemon->suspended_connections_head, 3437 daemon->suspended_connections_tail, 3438 connection); 3439 connection->suspended = true; 3440 #ifdef EPOLL_SUPPORT 3441 if (MHD_D_IS_USING_EPOLL_ (daemon)) 3442 { 3443 if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) 3444 { 3445 EDLL_remove (daemon->eready_head, 3446 daemon->eready_tail, 3447 connection); 3448 connection->epoll_state &= 3449 ~((enum MHD_EpollState) MHD_EPOLL_STATE_IN_EREADY_EDLL); 3450 } 3451 if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) 3452 { 3453 if (0 != epoll_ctl (daemon->epoll_fd, 3454 EPOLL_CTL_DEL, 3455 connection->socket_fd, 3456 NULL)) 3457 MHD_PANIC (_ ("Failed to remove FD from epoll set.\n")); 3458 connection->epoll_state &= 3459 ~((enum MHD_EpollState) MHD_EPOLL_STATE_IN_EPOLL_SET); 3460 } 3461 connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED; 3462 } 3463 #endif 3464 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3465 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 3466 #endif 3467 } 3468 3469 3470 /** 3471 * Suspend handling of network data for a given connection. 3472 * This can be used to dequeue a connection from MHD's event loop 3473 * (not applicable to thread-per-connection!) for a while. 3474 * 3475 * If you use this API in conjunction with an "internal" socket polling, 3476 * you must set the option #MHD_USE_ITC to ensure that a resumed 3477 * connection is immediately processed by MHD. 3478 * 3479 * Suspended connections continue to count against the total number of 3480 * connections allowed (per daemon, as well as per IP, if such limits 3481 * are set). Suspended connections will NOT time out; timeouts will 3482 * restart when the connection handling is resumed. While a 3483 * connection is suspended, MHD will not detect disconnects by the 3484 * client. 3485 * 3486 * The only safe way to call this function is to call it from the 3487 * #MHD_AccessHandlerCallback or #MHD_ContentReaderCallback. 3488 * 3489 * Finally, it is an API violation to call #MHD_stop_daemon while 3490 * having suspended connections (this will at least create memory and 3491 * socket leaks or lead to undefined behavior). You must explicitly 3492 * resume all connections before stopping the daemon. 3493 * 3494 * @param connection the connection to suspend 3495 * 3496 * @sa #MHD_AccessHandlerCallback 3497 */ 3498 _MHD_EXTERN void 3499 MHD_suspend_connection (struct MHD_Connection *connection) 3500 { 3501 struct MHD_Daemon *const daemon = connection->daemon; 3502 3503 #ifdef MHD_USE_THREADS 3504 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 3505 MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) || \ 3506 MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); 3507 #endif /* MHD_USE_THREADS */ 3508 3509 if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) 3510 MHD_PANIC (_ ("Cannot suspend connections without " \ 3511 "enabling MHD_ALLOW_SUSPEND_RESUME!\n")); 3512 #ifdef UPGRADE_SUPPORT 3513 if (NULL != connection->urh) 3514 { 3515 #ifdef HAVE_MESSAGES 3516 MHD_DLOG (daemon, 3517 _ ("Error: connection scheduled for \"upgrade\" cannot " \ 3518 "be suspended.\n")); 3519 #endif /* HAVE_MESSAGES */ 3520 return; 3521 } 3522 #endif /* UPGRADE_SUPPORT */ 3523 internal_suspend_connection_ (connection); 3524 } 3525 3526 3527 /** 3528 * Resume handling of network data for suspended connection. It is 3529 * safe to resume a suspended connection at any time. Calling this 3530 * function on a connection that was not previously suspended will 3531 * result in undefined behavior. 3532 * 3533 * If you are using this function in "external" sockets polling mode, you must 3534 * make sure to run #MHD_run() and #MHD_get_timeout() afterwards (before 3535 * again calling #MHD_get_fdset()), as otherwise the change may not be 3536 * reflected in the set returned by #MHD_get_fdset() and you may end up 3537 * with a connection that is stuck until the next network activity. 3538 * 3539 * @param connection the connection to resume 3540 */ 3541 _MHD_EXTERN void 3542 MHD_resume_connection (struct MHD_Connection *connection) 3543 { 3544 struct MHD_Daemon *daemon = connection->daemon; 3545 bool own_thread; /**< The connection's own thread completes the resume */ 3546 #if defined(MHD_USE_THREADS) 3547 mhd_assert (NULL == daemon->worker_pool); 3548 #endif /* MHD_USE_THREADS */ 3549 3550 if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) 3551 MHD_PANIC (_ ("Cannot resume connections without enabling " \ 3552 "MHD_ALLOW_SUSPEND_RESUME!\n")); 3553 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3554 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 3555 #endif 3556 connection->resuming = true; 3557 /* An "upgraded" connection is resumed only to be moved to the cleanup 3558 list, which is the daemon thread's job even with a thread per 3559 connection. */ 3560 own_thread = MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) 3561 #ifdef UPGRADE_SUPPORT 3562 && (NULL == connection->urh) 3563 #endif /* UPGRADE_SUPPORT */ 3564 ; 3565 if (! own_thread) 3566 daemon->resuming = true; 3567 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3568 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 3569 #endif 3570 if (own_thread) 3571 { 3572 /* Wake the connection's own thread. See the description of 3573 @e resume_itc for why the daemon-wide ITC will not do. */ 3574 mhd_assert (MHD_ITC_IS_VALID_ (connection->resume_itc)); 3575 if (! MHD_itc_activate_ (connection->resume_itc, "r")) 3576 { 3577 #ifdef HAVE_MESSAGES 3578 MHD_DLOG (daemon, 3579 _ ("Failed to signal resume via the connection's " \ 3580 "inter-thread communication channel.\n")); 3581 #endif 3582 } 3583 } 3584 else if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && 3585 (! MHD_itc_activate_ (daemon->itc, "r")) ) 3586 { 3587 #ifdef HAVE_MESSAGES 3588 MHD_DLOG (daemon, 3589 _ ("Failed to signal resume via inter-thread " \ 3590 "communication channel.\n")); 3591 #endif 3592 } 3593 } 3594 3595 3596 #ifdef UPGRADE_SUPPORT 3597 /** 3598 * Mark upgraded connection as closed by application. 3599 * 3600 * The @a connection pointer must not be used after call of this function 3601 * as it may be freed in other thread immediately. 3602 * @param connection the upgraded connection to mark as closed by application 3603 */ 3604 void 3605 MHD_upgraded_connection_mark_app_closed_ (struct MHD_Connection *connection) 3606 { 3607 /* Cache 'daemon' here to avoid data races */ 3608 struct MHD_Daemon *const daemon = connection->daemon; 3609 #if defined(MHD_USE_THREADS) 3610 mhd_assert (NULL == daemon->worker_pool); 3611 #endif /* MHD_USE_THREADS */ 3612 mhd_assert (NULL != connection->urh); 3613 mhd_assert (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)); 3614 3615 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 3616 connection->urh->was_closed = true; 3617 connection->resuming = true; 3618 daemon->resuming = true; 3619 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 3620 if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && 3621 (! MHD_itc_activate_ (daemon->itc, "r")) ) 3622 { 3623 #ifdef HAVE_MESSAGES 3624 MHD_DLOG (daemon, 3625 _ ("Failed to signal resume via " \ 3626 "inter-thread communication channel.\n")); 3627 #endif 3628 } 3629 } 3630 3631 3632 #endif /* UPGRADE_SUPPORT */ 3633 3634 /** 3635 * Run through the suspended connections and move any that are no 3636 * longer suspended back to the active state. 3637 * @remark To be called only from thread that process 3638 * daemon's select()/poll()/etc. 3639 * 3640 * @param daemon daemon context 3641 * @return #MHD_YES if a connection was actually resumed 3642 */ 3643 static enum MHD_Result 3644 resume_suspended_connections (struct MHD_Daemon *daemon) 3645 { 3646 struct MHD_Connection *pos; 3647 struct MHD_Connection *prev = NULL; 3648 enum MHD_Result ret; 3649 const bool used_thr_p_c = (0 != (daemon->options 3650 & MHD_USE_THREAD_PER_CONNECTION)); 3651 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3652 mhd_assert (NULL == daemon->worker_pool); 3653 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 3654 MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); 3655 #endif 3656 3657 ret = MHD_NO; 3658 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3659 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 3660 #endif 3661 3662 if (daemon->resuming) 3663 { 3664 prev = daemon->suspended_connections_tail; 3665 /* During shutdown check for resuming is forced. */ 3666 mhd_assert ((NULL != prev) || (daemon->shutdown) || \ 3667 (0 != (daemon->options & MHD_ALLOW_UPGRADE))); 3668 } 3669 3670 daemon->resuming = false; 3671 3672 while (NULL != (pos = prev)) 3673 { 3674 #ifdef UPGRADE_SUPPORT 3675 struct MHD_UpgradeResponseHandle *const urh = pos->urh; 3676 #else /* ! UPGRADE_SUPPORT */ 3677 static const void *const urh = NULL; 3678 #endif /* ! UPGRADE_SUPPORT */ 3679 prev = pos->prev; 3680 if ( (! pos->resuming) 3681 #ifdef UPGRADE_SUPPORT 3682 || ( (NULL != urh) && 3683 ( (! urh->was_closed) || 3684 (! urh->clean_ready) ) ) 3685 #endif /* UPGRADE_SUPPORT */ 3686 ) 3687 continue; 3688 ret = MHD_YES; 3689 mhd_assert (pos->suspended); 3690 DLL_remove (daemon->suspended_connections_head, 3691 daemon->suspended_connections_tail, 3692 pos); 3693 pos->suspended = false; 3694 if (NULL == urh) 3695 { 3696 DLL_insert (daemon->connections_head, 3697 daemon->connections_tail, 3698 pos); 3699 if (! used_thr_p_c) 3700 { 3701 /* The states of a suspended connection are not updated, so they 3702 are stale now that it is running again. Updating them here 3703 would mean running the state machine under the cleanup mutex, 3704 which is what 0ecf4f26e4c1a4c03d66e1d04bf4cae62bd236a0 backed 3705 out of; flag the connection instead and let call_handlers() 3706 update it before it acts on @e event_loop_info. Thread-per- 3707 connection does the same for itself, in 3708 thread_main_handle_connection(). */ 3709 pos->resumed = true; 3710 3711 /* Reset timeout timer on resume. */ 3712 if (0 != pos->connection_timeout_ms) 3713 pos->last_activity = MHD_monotonic_msec_counter (); 3714 3715 if (pos->connection_timeout_ms == daemon->connection_timeout_ms) 3716 XDLL_insert (daemon->normal_timeout_head, 3717 daemon->normal_timeout_tail, 3718 pos); 3719 else 3720 XDLL_insert (daemon->manual_timeout_head, 3721 daemon->manual_timeout_tail, 3722 pos); 3723 } 3724 #ifdef EPOLL_SUPPORT 3725 if (MHD_D_IS_USING_EPOLL_ (daemon)) 3726 { 3727 if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) 3728 MHD_PANIC ("Resumed connection was already in EREADY set.\n"); 3729 /* we always mark resumed connections as ready, as we 3730 might have missed the edge poll event during suspension */ 3731 EDLL_insert (daemon->eready_head, 3732 daemon->eready_tail, 3733 pos); 3734 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL \ 3735 | MHD_EPOLL_STATE_READ_READY 3736 | MHD_EPOLL_STATE_WRITE_READY; 3737 pos->epoll_state &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_SUSPENDED); 3738 } 3739 #endif 3740 } 3741 #ifdef UPGRADE_SUPPORT 3742 else 3743 { 3744 /* Data forwarding was finished (for TLS connections) AND 3745 * application was closed upgraded connection. 3746 * Insert connection into cleanup list. */ 3747 if ( (NULL != daemon->notify_completed) && 3748 (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) && 3749 (pos->rq.client_aware) ) 3750 { 3751 daemon->notify_completed (daemon->notify_completed_cls, 3752 pos, 3753 &pos->rq.client_context, 3754 MHD_REQUEST_TERMINATED_COMPLETED_OK); 3755 pos->rq.client_aware = false; 3756 } 3757 DLL_insert (daemon->cleanup_head, 3758 daemon->cleanup_tail, 3759 pos); 3760 daemon->data_already_pending = true; 3761 } 3762 #endif /* UPGRADE_SUPPORT */ 3763 pos->resuming = false; 3764 } 3765 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3766 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 3767 #endif 3768 if ( (used_thr_p_c) && 3769 (MHD_NO != ret) ) 3770 { /* Wake up suspended connections. */ 3771 if (! MHD_itc_activate_ (daemon->itc, 3772 "w")) 3773 { 3774 #ifdef HAVE_MESSAGES 3775 MHD_DLOG (daemon, 3776 _ ("Failed to signal resume of connection via " \ 3777 "inter-thread communication channel.\n")); 3778 #endif 3779 } 3780 } 3781 return ret; 3782 } 3783 3784 3785 /** 3786 * Add another client connection to the set of connections managed by 3787 * MHD. This API is usually not needed (since MHD will accept inbound 3788 * connections on the server socket). Use this API in special cases, 3789 * for example if your HTTP server is behind NAT and needs to connect 3790 * out to the HTTP client, or if you are building a proxy. 3791 * 3792 * If you use this API in conjunction with a internal select or a 3793 * thread pool, you must set the option 3794 * #MHD_USE_ITC to ensure that the freshly added 3795 * connection is immediately processed by MHD. 3796 * 3797 * The given client socket will be managed (and closed!) by MHD after 3798 * this call and must no longer be used directly by the application 3799 * afterwards. 3800 * 3801 * @param daemon daemon that manages the connection 3802 * @param client_socket socket to manage (MHD will expect 3803 * to receive an HTTP request from this socket next). 3804 * @param addr IP address of the client 3805 * @param addrlen number of bytes in @a addr 3806 * @return #MHD_YES on success, #MHD_NO if this daemon could 3807 * not handle the connection (i.e. malloc() failed, etc). 3808 * The socket will be closed in any case; `errno` is 3809 * set to indicate further details about the error. 3810 * @ingroup specialized 3811 */ 3812 _MHD_EXTERN enum MHD_Result 3813 MHD_add_connection (struct MHD_Daemon *daemon, 3814 MHD_socket client_socket, 3815 const struct sockaddr *addr, 3816 socklen_t addrlen) 3817 { 3818 bool sk_nonbl; 3819 bool sk_spipe_supprs; 3820 struct sockaddr_storage addrstorage; 3821 3822 /* TODO: fix atomic value reading */ 3823 if ((! MHD_D_IS_THREAD_SAFE_ (daemon)) && 3824 (daemon->connection_limit <= daemon->connections)) 3825 MHD_cleanup_connections (daemon); 3826 3827 #ifdef HAVE_MESSAGES 3828 if (MHD_D_IS_USING_THREADS_ (daemon) && 3829 (0 == (daemon->options & MHD_USE_ITC))) 3830 { 3831 MHD_DLOG (daemon, 3832 _ ("MHD_add_connection() has been called for daemon started" 3833 " without MHD_USE_ITC flag.\nDaemon will not process newly" 3834 " added connection until any activity occurs in already" 3835 " added sockets.\n")); 3836 } 3837 #endif /* HAVE_MESSAGES */ 3838 if (0 != addrlen) 3839 { 3840 if (AF_INET == addr->sa_family) 3841 { 3842 if (sizeof(struct sockaddr_in) > (size_t) addrlen) 3843 { 3844 #ifdef HAVE_MESSAGES 3845 MHD_DLOG (daemon, 3846 _ ("MHD_add_connection() has been called with " 3847 "incorrect 'addrlen' value.\n")); 3848 #endif /* HAVE_MESSAGES */ 3849 return MHD_NO; 3850 } 3851 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 3852 if ((0 != addr->sa_len) && 3853 (sizeof(struct sockaddr_in) > (size_t) addr->sa_len) ) 3854 { 3855 #ifdef HAVE_MESSAGES 3856 MHD_DLOG (daemon, 3857 _ ("MHD_add_connection() has been called with " \ 3858 "non-zero value of 'sa_len' member of " \ 3859 "'struct sockaddr' which does not match 'sa_family'.\n")); 3860 #endif /* HAVE_MESSAGES */ 3861 return MHD_NO; 3862 } 3863 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ 3864 } 3865 #ifdef HAVE_INET6 3866 if (AF_INET6 == addr->sa_family) 3867 { 3868 if (sizeof(struct sockaddr_in6) > (size_t) addrlen) 3869 { 3870 #ifdef HAVE_MESSAGES 3871 MHD_DLOG (daemon, 3872 _ ("MHD_add_connection() has been called with " 3873 "incorrect 'addrlen' value.\n")); 3874 #endif /* HAVE_MESSAGES */ 3875 return MHD_NO; 3876 } 3877 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 3878 if ((0 != addr->sa_len) && 3879 (sizeof(struct sockaddr_in6) > (size_t) addr->sa_len) ) 3880 { 3881 #ifdef HAVE_MESSAGES 3882 MHD_DLOG (daemon, 3883 _ ("MHD_add_connection() has been called with " \ 3884 "non-zero value of 'sa_len' member of " \ 3885 "'struct sockaddr' which does not match 'sa_family'.\n")); 3886 #endif /* HAVE_MESSAGES */ 3887 return MHD_NO; 3888 } 3889 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ 3890 } 3891 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 3892 if ((0 != addr->sa_len) && 3893 (addrlen > addr->sa_len)) 3894 addrlen = (socklen_t) addr->sa_len; /* Use safest value */ 3895 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ 3896 #endif /* HAVE_INET6 */ 3897 } 3898 3899 if (! MHD_socket_nonblocking_ (client_socket)) 3900 { 3901 #ifdef HAVE_MESSAGES 3902 MHD_DLOG (daemon, 3903 _ ("Failed to set nonblocking mode on new client socket: %s\n"), 3904 MHD_socket_last_strerr_ ()); 3905 #endif 3906 sk_nonbl = false; 3907 } 3908 else 3909 sk_nonbl = true; 3910 3911 #ifndef MHD_WINSOCK_SOCKETS 3912 sk_spipe_supprs = false; 3913 #else /* MHD_WINSOCK_SOCKETS */ 3914 sk_spipe_supprs = true; /* Nothing to suppress on W32 */ 3915 #endif /* MHD_WINSOCK_SOCKETS */ 3916 #if defined(MHD_socket_nosignal_) 3917 if (! sk_spipe_supprs) 3918 sk_spipe_supprs = MHD_socket_nosignal_ (client_socket); 3919 if (! sk_spipe_supprs) 3920 { 3921 #ifdef HAVE_MESSAGES 3922 MHD_DLOG (daemon, 3923 _ ("Failed to suppress SIGPIPE on new client socket: %s\n"), 3924 MHD_socket_last_strerr_ ()); 3925 #else /* ! HAVE_MESSAGES */ 3926 (void) 0; /* Mute compiler warning */ 3927 #endif /* ! HAVE_MESSAGES */ 3928 #ifndef MSG_NOSIGNAL 3929 /* Application expects that SIGPIPE will be suppressed, 3930 * but suppression failed and SIGPIPE cannot be suppressed with send(). */ 3931 if (! daemon->sigpipe_blocked) 3932 { 3933 int err = MHD_socket_get_error_ (); 3934 MHD_socket_close_ (client_socket); 3935 MHD_socket_fset_error_ (err); 3936 return MHD_NO; 3937 } 3938 #endif /* MSG_NOSIGNAL */ 3939 } 3940 #endif /* MHD_socket_nosignal_ */ 3941 3942 if ( (0 != (daemon->options & MHD_USE_TURBO)) && 3943 (! MHD_socket_noninheritable_ (client_socket)) ) 3944 { 3945 #ifdef HAVE_MESSAGES 3946 MHD_DLOG (daemon, 3947 _ ("Failed to set noninheritable mode on new client socket.\n")); 3948 #endif 3949 } 3950 3951 /* Copy to sockaddr_storage structure to avoid alignment problems */ 3952 if (0 < addrlen) 3953 memcpy (&addrstorage, addr, (size_t) addrlen); 3954 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 3955 addrstorage.ss_len = addrlen; /* Force set the right length */ 3956 #endif /* HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN */ 3957 3958 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3959 if (NULL != daemon->worker_pool) 3960 { 3961 unsigned int i; 3962 /* have a pool, try to find a pool with capacity; we use the 3963 socket as the initial offset into the pool for load 3964 balancing */ 3965 for (i = 0; i < daemon->worker_pool_size; ++i) 3966 { 3967 struct MHD_Daemon *const worker = 3968 &daemon->worker_pool[(i + (unsigned int) client_socket) 3969 % daemon->worker_pool_size]; 3970 if (worker->connections < worker->connection_limit) 3971 return internal_add_connection (worker, 3972 client_socket, 3973 &addrstorage, 3974 addrlen, 3975 true, 3976 sk_nonbl, 3977 sk_spipe_supprs, 3978 _MHD_UNKNOWN); 3979 } 3980 /* all pools are at their connection limit, must refuse */ 3981 MHD_socket_close_chk_ (client_socket); 3982 #if defined(ENFILE) && (ENFILE + 0 != 0) 3983 errno = ENFILE; 3984 #endif 3985 return MHD_NO; 3986 } 3987 #endif /* MHD_USE_POSIX_THREADS || MHD_USE_W32_THREADS */ 3988 3989 return internal_add_connection (daemon, 3990 client_socket, 3991 &addrstorage, 3992 addrlen, 3993 true, 3994 sk_nonbl, 3995 sk_spipe_supprs, 3996 _MHD_UNKNOWN); 3997 } 3998 3999 4000 /** 4001 * Accept an incoming connection and create the MHD_Connection object for 4002 * it. This function also enforces policy by way of checking with the 4003 * accept policy callback. 4004 * @remark To be called only from thread that process 4005 * daemon's select()/poll()/etc. 4006 * 4007 * @param daemon handle with the listen socket 4008 * @return #MHD_YES on success (connections denied by policy or due 4009 * to 'out of memory' and similar errors) are still considered 4010 * successful as far as #MHD_accept_connection() is concerned); 4011 * a return code of #MHD_NO only refers to the actual 4012 * accept() system call. 4013 */ 4014 static enum MHD_Result 4015 MHD_accept_connection (struct MHD_Daemon *daemon) 4016 { 4017 struct sockaddr_storage addrstorage; 4018 socklen_t addrlen; 4019 MHD_socket s; 4020 MHD_socket fd; 4021 bool sk_nonbl; 4022 bool sk_spipe_supprs; 4023 bool sk_cloexec; 4024 enum MHD_tristate sk_non_ip; 4025 #if defined(_DEBUG) && defined (USE_ACCEPT4) 4026 const bool use_accept4 = ! daemon->avoid_accept4; 4027 #elif defined (USE_ACCEPT4) 4028 static const bool use_accept4 = true; 4029 #else /* ! USE_ACCEPT4 && ! _DEBUG */ 4030 static const bool use_accept4 = false; 4031 #endif /* ! USE_ACCEPT4 && ! _DEBUG */ 4032 4033 #ifdef MHD_USE_THREADS 4034 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 4035 MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); 4036 mhd_assert (NULL == daemon->worker_pool); 4037 #endif /* MHD_USE_THREADS */ 4038 4039 if ( (MHD_INVALID_SOCKET == (fd = daemon->listen_fd)) || 4040 (daemon->was_quiesced) ) 4041 return MHD_NO; 4042 4043 addrlen = (socklen_t) sizeof (addrstorage); 4044 memset (&addrstorage, 4045 0, 4046 (size_t) addrlen); 4047 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 4048 addrstorage.ss_len = addrlen; 4049 #endif /* HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN */ 4050 4051 /* Initialise with default values to avoid compiler warnings */ 4052 sk_nonbl = false; 4053 sk_spipe_supprs = false; 4054 sk_cloexec = false; 4055 s = MHD_INVALID_SOCKET; 4056 4057 #ifdef USE_ACCEPT4 4058 if (use_accept4 && 4059 (MHD_INVALID_SOCKET != 4060 (s = accept4 (fd, 4061 (struct sockaddr *) &addrstorage, 4062 &addrlen, 4063 SOCK_CLOEXEC_OR_ZERO | SOCK_NONBLOCK_OR_ZERO 4064 | SOCK_NOSIGPIPE_OR_ZERO)))) 4065 { 4066 sk_nonbl = (SOCK_NONBLOCK_OR_ZERO != 0); 4067 #ifndef MHD_WINSOCK_SOCKETS 4068 sk_spipe_supprs = (SOCK_NOSIGPIPE_OR_ZERO != 0); 4069 #else /* MHD_WINSOCK_SOCKETS */ 4070 sk_spipe_supprs = true; /* Nothing to suppress on W32 */ 4071 #endif /* MHD_WINSOCK_SOCKETS */ 4072 sk_cloexec = (SOCK_CLOEXEC_OR_ZERO != 0); 4073 } 4074 #endif /* USE_ACCEPT4 */ 4075 #if defined(_DEBUG) || ! defined(USE_ACCEPT4) 4076 if (! use_accept4 && 4077 (MHD_INVALID_SOCKET != 4078 (s = accept (fd, 4079 (struct sockaddr *) &addrstorage, 4080 &addrlen)))) 4081 { 4082 #ifdef MHD_ACCEPT_INHERIT_NONBLOCK 4083 sk_nonbl = daemon->listen_nonblk; 4084 #else /* ! MHD_ACCEPT_INHERIT_NONBLOCK */ 4085 sk_nonbl = false; 4086 #endif /* ! MHD_ACCEPT_INHERIT_NONBLOCK */ 4087 #ifndef MHD_WINSOCK_SOCKETS 4088 sk_spipe_supprs = false; 4089 #else /* MHD_WINSOCK_SOCKETS */ 4090 sk_spipe_supprs = true; /* Nothing to suppress on W32 */ 4091 #endif /* MHD_WINSOCK_SOCKETS */ 4092 sk_cloexec = false; 4093 } 4094 #endif /* _DEBUG || !USE_ACCEPT4 */ 4095 4096 if (MHD_INVALID_SOCKET == s) 4097 { 4098 const int err = MHD_socket_get_error_ (); 4099 4100 /* This could be a common occurrence with multiple worker threads */ 4101 if (MHD_SCKT_ERR_IS_ (err, 4102 MHD_SCKT_EINVAL_)) 4103 return MHD_NO; /* can happen during shutdown */ 4104 if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_ (err)) 4105 return MHD_NO; /* do not print error if client just disconnected early */ 4106 #ifdef HAVE_MESSAGES 4107 if (! MHD_SCKT_ERR_IS_EAGAIN_ (err) ) 4108 MHD_DLOG (daemon, 4109 _ ("Error accepting connection: %s\n"), 4110 MHD_socket_strerr_ (err)); 4111 #endif 4112 if (MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) ) 4113 { 4114 /* system/process out of resources */ 4115 if (0 == daemon->connections) 4116 { 4117 #ifdef HAVE_MESSAGES 4118 /* Not setting 'at_limit' flag, as there is no way it 4119 would ever be cleared. Instead trying to produce 4120 bit fat ugly warning. */ 4121 MHD_DLOG (daemon, 4122 _ ("Hit process or system resource limit at FIRST " \ 4123 "connection. This is really bad as there is no sane " \ 4124 "way to proceed. Will try busy waiting for system " \ 4125 "resources to become magically available.\n")); 4126 #endif 4127 } 4128 else 4129 { 4130 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4131 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 4132 #endif 4133 daemon->at_limit = true; 4134 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4135 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 4136 #endif 4137 #ifdef HAVE_MESSAGES 4138 MHD_DLOG (daemon, 4139 _ ("Hit process or system resource limit at %u " \ 4140 "connections, temporarily suspending accept(). " \ 4141 "Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"), 4142 (unsigned int) daemon->connections); 4143 #endif 4144 } 4145 } 4146 return MHD_NO; 4147 } 4148 4149 sk_non_ip = daemon->listen_is_unix; 4150 if (0 >= addrlen) 4151 { 4152 #ifdef HAVE_MESSAGES 4153 if (_MHD_NO != daemon->listen_is_unix) 4154 MHD_DLOG (daemon, 4155 _ ("Accepted socket has zero-length address. " 4156 "Processing the new socket as a socket with " \ 4157 "unknown type.\n")); 4158 #endif 4159 addrlen = 0; 4160 sk_non_ip = _MHD_YES; /* IP-type addresses have non-zero length */ 4161 } 4162 if (((socklen_t) sizeof (addrstorage)) < addrlen) 4163 { 4164 /* Should not happen as 'sockaddr_storage' must be large enough to 4165 * store any address supported by the system. */ 4166 #ifdef HAVE_MESSAGES 4167 MHD_DLOG (daemon, 4168 _ ("Accepted socket address is larger than expected by " \ 4169 "system headers. Processing the new socket as a socket with " \ 4170 "unknown type.\n")); 4171 #endif 4172 addrlen = 0; 4173 sk_non_ip = _MHD_YES; /* IP-type addresses must fit */ 4174 } 4175 4176 if (! sk_nonbl && ! MHD_socket_nonblocking_ (s)) 4177 { 4178 #ifdef HAVE_MESSAGES 4179 MHD_DLOG (daemon, 4180 _ ("Failed to set nonblocking mode on incoming connection " \ 4181 "socket: %s\n"), 4182 MHD_socket_last_strerr_ ()); 4183 #else /* ! HAVE_MESSAGES */ 4184 (void) 0; /* Mute compiler warning */ 4185 #endif /* ! HAVE_MESSAGES */ 4186 } 4187 else 4188 sk_nonbl = true; 4189 4190 if (! sk_cloexec && ! MHD_socket_noninheritable_ (s)) 4191 { 4192 #ifdef HAVE_MESSAGES 4193 MHD_DLOG (daemon, 4194 _ ("Failed to set noninheritable mode on incoming connection " \ 4195 "socket.\n")); 4196 #else /* ! HAVE_MESSAGES */ 4197 (void) 0; /* Mute compiler warning */ 4198 #endif /* ! HAVE_MESSAGES */ 4199 } 4200 4201 #if defined(MHD_socket_nosignal_) 4202 if (! sk_spipe_supprs && ! MHD_socket_nosignal_ (s)) 4203 { 4204 #ifdef HAVE_MESSAGES 4205 MHD_DLOG (daemon, 4206 _ ("Failed to suppress SIGPIPE on incoming connection " \ 4207 "socket: %s\n"), 4208 MHD_socket_last_strerr_ ()); 4209 #else /* ! HAVE_MESSAGES */ 4210 (void) 0; /* Mute compiler warning */ 4211 #endif /* ! HAVE_MESSAGES */ 4212 #ifndef MSG_NOSIGNAL 4213 /* Application expects that SIGPIPE will be suppressed, 4214 * but suppression failed and SIGPIPE cannot be suppressed with send(). */ 4215 if (! daemon->sigpipe_blocked) 4216 { 4217 (void) MHD_socket_close_ (s); 4218 return MHD_NO; 4219 } 4220 #endif /* MSG_NOSIGNAL */ 4221 } 4222 else 4223 sk_spipe_supprs = true; 4224 #endif /* MHD_socket_nosignal_ */ 4225 #ifdef HAVE_MESSAGES 4226 #if _MHD_DEBUG_CONNECT 4227 MHD_DLOG (daemon, 4228 _ ("Accepted connection on socket %d\n"), 4229 s); 4230 #endif 4231 #endif 4232 (void) internal_add_connection (daemon, 4233 s, 4234 &addrstorage, 4235 addrlen, 4236 false, 4237 sk_nonbl, 4238 sk_spipe_supprs, 4239 sk_non_ip); 4240 return MHD_YES; 4241 } 4242 4243 4244 /** 4245 * Free resources associated with all closed connections. 4246 * (destroy responses, free buffers, etc.). All closed 4247 * connections are kept in the "cleanup" doubly-linked list. 4248 * @remark To be called only from thread that 4249 * process daemon's select()/poll()/etc. 4250 * 4251 * @param daemon daemon to clean up 4252 */ 4253 static void 4254 MHD_cleanup_connections (struct MHD_Daemon *daemon) 4255 { 4256 struct MHD_Connection *pos; 4257 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4258 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 4259 MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); 4260 mhd_assert (NULL == daemon->worker_pool); 4261 4262 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 4263 #endif 4264 while (NULL != (pos = daemon->cleanup_tail)) 4265 { 4266 DLL_remove (daemon->cleanup_head, 4267 daemon->cleanup_tail, 4268 pos); 4269 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4270 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 4271 if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) && 4272 (! pos->thread_joined) && 4273 (! MHD_thread_handle_ID_join_thread_ (pos->tid)) ) 4274 MHD_PANIC (_ ("Failed to join a thread.\n")); 4275 #endif 4276 #ifdef UPGRADE_SUPPORT 4277 cleanup_upgraded_connection (pos); 4278 #endif /* UPGRADE_SUPPORT */ 4279 MHD_pool_destroy (pos->pool); 4280 #ifdef HTTPS_SUPPORT 4281 if (NULL != pos->tls_session) 4282 gnutls_deinit (pos->tls_session); 4283 #endif /* HTTPS_SUPPORT */ 4284 4285 /* clean up the connection */ 4286 if (NULL != daemon->notify_connection) 4287 daemon->notify_connection (daemon->notify_connection_cls, 4288 pos, 4289 &pos->socket_context, 4290 MHD_CONNECTION_NOTIFY_CLOSED); 4291 MHD_ip_limit_del (daemon, 4292 pos->addr, 4293 pos->addr_len); 4294 #ifdef EPOLL_SUPPORT 4295 if (MHD_D_IS_USING_EPOLL_ (daemon)) 4296 { 4297 if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) 4298 { 4299 EDLL_remove (daemon->eready_head, 4300 daemon->eready_tail, 4301 pos); 4302 pos->epoll_state &= 4303 ~((enum MHD_EpollState) MHD_EPOLL_STATE_IN_EREADY_EDLL); 4304 } 4305 if ( (-1 != daemon->epoll_fd) && 4306 (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) ) 4307 { 4308 /* epoll documentation suggests that closing a FD 4309 automatically removes it from the epoll set; however, 4310 this is not true as if we fail to do manually remove it, 4311 we are still seeing an event for this fd in epoll, 4312 causing grief (use-after-free...) --- at least on my 4313 system. */ 4314 if (0 != epoll_ctl (daemon->epoll_fd, 4315 EPOLL_CTL_DEL, 4316 pos->socket_fd, 4317 NULL)) 4318 MHD_PANIC (_ ("Failed to remove FD from epoll set.\n")); 4319 pos->epoll_state &= 4320 ~((enum MHD_EpollState) 4321 MHD_EPOLL_STATE_IN_EPOLL_SET); 4322 } 4323 } 4324 #endif 4325 if (NULL != pos->rp.response) 4326 { 4327 MHD_destroy_response (pos->rp.response); 4328 pos->rp.response = NULL; 4329 } 4330 if (MHD_INVALID_SOCKET != pos->socket_fd) 4331 MHD_socket_close_chk_ (pos->socket_fd); 4332 if (MHD_ITC_IS_VALID_ (pos->resume_itc)) 4333 MHD_itc_destroy_chk_ (pos->resume_itc); 4334 if (NULL != pos->addr) 4335 free (pos->addr); 4336 free (pos); 4337 4338 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4339 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 4340 #endif 4341 daemon->connections--; 4342 daemon->at_limit = false; 4343 } 4344 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4345 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 4346 #endif 4347 } 4348 4349 4350 /** 4351 * Obtain timeout value for polling function for this daemon. 4352 * 4353 * This function set value to the amount of milliseconds for which polling 4354 * function (`select()`, `poll()` or epoll) should at most block, not the 4355 * timeout value set for connections. 4356 * 4357 * Any "external" sockets polling function must be called with the timeout 4358 * value provided by this function. Smaller timeout values can be used for 4359 * polling function if it is required for any reason, but using larger 4360 * timeout value or no timeout (indefinite timeout) when this function 4361 * return #MHD_YES will break MHD processing logic and result in "hung" 4362 * connections with data pending in network buffers and other problems. 4363 * 4364 * It is important to always use this function (or #MHD_get_timeout64(), 4365 * #MHD_get_timeout64s(), #MHD_get_timeout_i() functions) when "external" 4366 * polling is used. 4367 * If this function returns #MHD_YES then #MHD_run() (or #MHD_run_from_select()) 4368 * must be called right after return from polling function, regardless of 4369 * the states of MHD FDs. 4370 * 4371 * In practice, if #MHD_YES is returned then #MHD_run() (or 4372 * #MHD_run_from_select()) must be called not later than @a timeout 4373 * millisecond even if no activity is detected on sockets by sockets 4374 * polling function. 4375 * @remark To be called only from thread that process 4376 * daemon's select()/poll()/etc. 4377 * 4378 * @param daemon daemon to query for timeout 4379 * @param[out] timeout set to the timeout (in milliseconds) 4380 * @return #MHD_YES on success, #MHD_NO if timeouts are 4381 * not used and no data processing is pending. 4382 * @ingroup event 4383 */ 4384 _MHD_EXTERN enum MHD_Result 4385 MHD_get_timeout (struct MHD_Daemon *daemon, 4386 MHD_UNSIGNED_LONG_LONG *timeout) 4387 { 4388 uint64_t t64; 4389 if (MHD_NO == MHD_get_timeout64 (daemon, &t64)) 4390 return MHD_NO; 4391 4392 #if SIZEOF_UINT64_T > SIZEOF_UNSIGNED_LONG_LONG 4393 if (ULLONG_MAX <= t64) 4394 *timeout = ULLONG_MAX; 4395 else 4396 #endif /* SIZEOF_UINT64_T > SIZEOF_UNSIGNED_LONG_LONG */ 4397 *timeout = (MHD_UNSIGNED_LONG_LONG) t64; 4398 return MHD_YES; 4399 } 4400 4401 4402 /** 4403 * Obtain timeout value for external polling function for this daemon. 4404 * 4405 * This function set value to the amount of milliseconds for which polling 4406 * function (`select()`, `poll()` or epoll) should at most block, not the 4407 * timeout value set for connections. 4408 * 4409 * Any "external" sockets polling function must be called with the timeout 4410 * value provided by this function. Smaller timeout values can be used for 4411 * polling function if it is required for any reason, but using larger 4412 * timeout value or no timeout (indefinite timeout) when this function 4413 * return #MHD_YES will break MHD processing logic and result in "hung" 4414 * connections with data pending in network buffers and other problems. 4415 * 4416 * It is important to always use this function (or #MHD_get_timeout(), 4417 * #MHD_get_timeout64s(), #MHD_get_timeout_i() functions) when "external" 4418 * polling is used. 4419 * If this function returns #MHD_YES then #MHD_run() (or #MHD_run_from_select()) 4420 * must be called right after return from polling function, regardless of 4421 * the states of MHD FDs. 4422 * 4423 * In practice, if #MHD_YES is returned then #MHD_run() (or 4424 * #MHD_run_from_select()) must be called not later than @a timeout 4425 * millisecond even if no activity is detected on sockets by sockets 4426 * polling function. 4427 * @remark To be called only from thread that process 4428 * daemon's select()/poll()/etc. 4429 * 4430 * @param daemon daemon to query for timeout 4431 * @param[out] timeout64 the pointer to the variable to be set to the 4432 * timeout (in milliseconds) 4433 * @return #MHD_YES if timeout value has been set, 4434 * #MHD_NO if timeouts are not used and no data processing is pending. 4435 * @note Available since #MHD_VERSION 0x00097701 4436 * @ingroup event 4437 */ 4438 _MHD_EXTERN enum MHD_Result 4439 MHD_get_timeout64 (struct MHD_Daemon *daemon, 4440 uint64_t *timeout64) 4441 { 4442 uint64_t earliest_deadline; 4443 struct MHD_Connection *pos; 4444 struct MHD_Connection *earliest_tmot_conn; /**< the connection with earliest timeout */ 4445 bool resuming; /**< the copy of @a daemon->resuming, read under the lock */ 4446 4447 #ifdef MHD_USE_THREADS 4448 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 4449 MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); 4450 #endif /* MHD_USE_THREADS */ 4451 4452 if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) 4453 { 4454 #ifdef HAVE_MESSAGES 4455 MHD_DLOG (daemon, 4456 _ ("Illegal call to MHD_get_timeout.\n")); 4457 #endif 4458 return MHD_NO; 4459 } 4460 /* Unlike the other flags checked below, which are touched only by the 4461 thread that processes this daemon's polling, 'resuming' is set by 4462 #MHD_resume_connection(), which the application may legally call from 4463 any thread. It is guarded by 'cleanup_connection_mutex' everywhere. */ 4464 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4465 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 4466 #endif 4467 resuming = daemon->resuming; 4468 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4469 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 4470 #endif 4471 if (daemon->data_already_pending 4472 || (NULL != daemon->cleanup_head) 4473 || resuming 4474 || daemon->have_new 4475 || daemon->shutdown) 4476 { 4477 /* Some data or connection statuses already waiting to be processed. */ 4478 *timeout64 = 0; 4479 return MHD_YES; 4480 } 4481 #ifdef EPOLL_SUPPORT 4482 if (MHD_D_IS_USING_EPOLL_ (daemon) && 4483 ((NULL != daemon->eready_head) 4484 #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT) 4485 || (NULL != daemon->eready_urh_head) 4486 #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */ 4487 ) ) 4488 { 4489 /* Some connection(s) already have some data pending. */ 4490 *timeout64 = 0; 4491 return MHD_YES; 4492 } 4493 #endif /* EPOLL_SUPPORT */ 4494 4495 earliest_tmot_conn = NULL; 4496 earliest_deadline = 0; /* mute compiler warning */ 4497 /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */ 4498 pos = daemon->normal_timeout_tail; 4499 if ( (NULL != pos) && 4500 (0 != pos->connection_timeout_ms) ) 4501 { 4502 earliest_tmot_conn = pos; 4503 earliest_deadline = pos->last_activity + pos->connection_timeout_ms; 4504 } 4505 4506 for (pos = daemon->manual_timeout_tail; 4507 NULL != pos; 4508 pos = pos->prevX) 4509 { 4510 if (0 != pos->connection_timeout_ms) 4511 { 4512 if ( (NULL == earliest_tmot_conn) || 4513 (earliest_deadline > 4514 pos->last_activity + pos->connection_timeout_ms) ) 4515 { 4516 earliest_tmot_conn = pos; 4517 earliest_deadline = pos->last_activity + pos->connection_timeout_ms; 4518 } 4519 } 4520 } 4521 4522 if (NULL != earliest_tmot_conn) 4523 { 4524 *timeout64 = connection_get_wait (earliest_tmot_conn); 4525 return MHD_YES; 4526 } 4527 return MHD_NO; 4528 } 4529 4530 4531 #if defined(HAVE_POLL) || defined(EPOLL_SUPPORT) 4532 /** 4533 * Obtain timeout value for external polling function for this daemon. 4534 * 4535 * This function set value to the amount of milliseconds for which polling 4536 * function (`select()`, `poll()` or epoll) should at most block, not the 4537 * timeout value set for connections. 4538 * 4539 * Any "external" sockets polling function must be called with the timeout 4540 * value provided by this function (if returned value is non-negative). 4541 * Smaller timeout values can be used for polling function if it is required 4542 * for any reason, but using larger timeout value or no timeout (indefinite 4543 * timeout) when this function returns non-negative value will break MHD 4544 * processing logic and result in "hung" connections with data pending in 4545 * network buffers and other problems. 4546 * 4547 * It is important to always use this function (or #MHD_get_timeout(), 4548 * #MHD_get_timeout64(), #MHD_get_timeout_i() functions) when "external" 4549 * polling is used. 4550 * If this function returns non-negative value then #MHD_run() (or 4551 * #MHD_run_from_select()) must be called right after return from polling 4552 * function, regardless of the states of MHD FDs. 4553 * 4554 * In practice, if zero or positive value is returned then #MHD_run() (or 4555 * #MHD_run_from_select()) must be called not later than returned amount of 4556 * millisecond even if no activity is detected on sockets by sockets 4557 * polling function. 4558 * @remark To be called only from thread that process 4559 * daemon's select()/poll()/etc. 4560 * 4561 * @param daemon the daemon to query for timeout 4562 * @return -1 if connections' timeouts are not set and no data processing 4563 * is pending, so external polling function may wait for sockets 4564 * activity for indefinite amount of time, 4565 * otherwise returned value is the the maximum amount of millisecond 4566 * that external polling function must wait for the activity of FDs. 4567 * @note Available since #MHD_VERSION 0x00097701 4568 * @ingroup event 4569 */ 4570 _MHD_EXTERN int64_t 4571 MHD_get_timeout64s (struct MHD_Daemon *daemon) 4572 { 4573 uint64_t utimeout; 4574 if (MHD_NO == MHD_get_timeout64 (daemon, &utimeout)) 4575 return -1; 4576 if (INT64_MAX < utimeout) 4577 return INT64_MAX; 4578 4579 return (int64_t) utimeout; 4580 } 4581 4582 4583 /** 4584 * Obtain timeout value for external polling function for this daemon. 4585 * 4586 * This function set value to the amount of milliseconds for which polling 4587 * function (`select()`, `poll()` or epoll) should at most block, not the 4588 * timeout value set for connections. 4589 * 4590 * Any "external" sockets polling function must be called with the timeout 4591 * value provided by this function (if returned value is non-negative). 4592 * Smaller timeout values can be used for polling function if it is required 4593 * for any reason, but using larger timeout value or no timeout (indefinite 4594 * timeout) when this function returns non-negative value will break MHD 4595 * processing logic and result in "hung" connections with data pending in 4596 * network buffers and other problems. 4597 * 4598 * It is important to always use this function (or #MHD_get_timeout(), 4599 * #MHD_get_timeout64(), #MHD_get_timeout64s() functions) when "external" 4600 * polling is used. 4601 * If this function returns non-negative value then #MHD_run() (or 4602 * #MHD_run_from_select()) must be called right after return from polling 4603 * function, regardless of the states of MHD FDs. 4604 * 4605 * In practice, if zero or positive value is returned then #MHD_run() (or 4606 * #MHD_run_from_select()) must be called not later than returned amount of 4607 * millisecond even if no activity is detected on sockets by sockets 4608 * polling function. 4609 * @remark To be called only from thread that process 4610 * daemon's select()/poll()/etc. 4611 * 4612 * @param daemon the daemon to query for timeout 4613 * @return -1 if connections' timeouts are not set and no data processing 4614 * is pending, so external polling function may wait for sockets 4615 * activity for indefinite amount of time, 4616 * otherwise returned value is the the maximum amount of millisecond 4617 * (capped at INT_MAX) that external polling function must wait 4618 * for the activity of FDs. 4619 * @note Available since #MHD_VERSION 0x00097701 4620 * @ingroup event 4621 */ 4622 _MHD_EXTERN int 4623 MHD_get_timeout_i (struct MHD_Daemon *daemon) 4624 { 4625 #if SIZEOF_INT >= SIZEOF_INT64_T 4626 return MHD_get_timeout64s (daemon); 4627 #else /* SIZEOF_INT < SIZEOF_INT64_T */ 4628 const int64_t to64 = MHD_get_timeout64s (daemon); 4629 if (INT_MAX >= to64) 4630 return (int) to64; 4631 return INT_MAX; 4632 #endif /* SIZEOF_INT < SIZEOF_INT64_T */ 4633 } 4634 4635 4636 /** 4637 * Obtain timeout value for polling function for this daemon. 4638 * @remark To be called only from the thread that processes 4639 * daemon's select()/poll()/etc. 4640 * 4641 * @param daemon the daemon to query for timeout 4642 * @param max_timeout the maximum return value (in milliseconds), 4643 * ignored if set to '-1' 4644 * @return timeout value in milliseconds or -1 if no timeout is expected. 4645 */ 4646 static int64_t 4647 get_timeout_millisec_ (struct MHD_Daemon *daemon, 4648 int32_t max_timeout) 4649 { 4650 uint64_t d_timeout; 4651 mhd_assert (0 <= max_timeout || -1 == max_timeout); 4652 if (0 == max_timeout) 4653 return 0; 4654 4655 if (MHD_NO == MHD_get_timeout64 (daemon, &d_timeout)) 4656 return max_timeout; 4657 4658 if ((0 < max_timeout) && ((uint64_t) max_timeout < d_timeout)) 4659 return max_timeout; 4660 4661 if (INT64_MAX <= d_timeout) 4662 return INT64_MAX; 4663 4664 return (int64_t) d_timeout; 4665 } 4666 4667 4668 /** 4669 * Obtain timeout value for polling function for this daemon. 4670 * @remark To be called only from the thread that processes 4671 * daemon's select()/poll()/etc. 4672 * 4673 * @param daemon the daemon to query for timeout 4674 * @param max_timeout the maximum return value (in milliseconds), 4675 * ignored if set to '-1' 4676 * @return timeout value in milliseconds, capped to INT_MAX, or 4677 * -1 if no timeout is expected. 4678 */ 4679 static int 4680 get_timeout_millisec_int (struct MHD_Daemon *daemon, 4681 int32_t max_timeout) 4682 { 4683 int64_t res; 4684 4685 res = get_timeout_millisec_ (daemon, max_timeout); 4686 #if SIZEOF_INT < SIZEOF_INT64_T 4687 if (INT_MAX <= res) 4688 return INT_MAX; 4689 #endif /* SIZEOF_INT < SIZEOF_INT64_T */ 4690 return (int) res; 4691 } 4692 4693 4694 #endif /* HAVE_POLL || EPOLL_SUPPORT */ 4695 4696 /** 4697 * Internal version of #MHD_run_from_select(). 4698 * 4699 * @param daemon daemon to run select loop for 4700 * @param read_fd_set read set 4701 * @param write_fd_set write set 4702 * @param except_fd_set except set 4703 * @param fd_setsize value of FD_SETSIZE used when fd_sets were created 4704 * @return #MHD_NO on serious errors, #MHD_YES on success 4705 * @ingroup event 4706 */ 4707 static enum MHD_Result 4708 internal_run_from_select (struct MHD_Daemon *daemon, 4709 const fd_set *read_fd_set, 4710 const fd_set *write_fd_set, 4711 const fd_set *except_fd_set, 4712 int fd_setsize) 4713 { 4714 MHD_socket ds; 4715 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4716 struct MHD_UpgradeResponseHandle *urh; 4717 struct MHD_UpgradeResponseHandle *urhn; 4718 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 4719 4720 mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 4721 (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid))); 4722 mhd_assert ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 4723 (! MHD_thread_handle_ID_is_valid_ID_ (daemon->tid))); 4724 mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 4725 (MHD_thread_handle_ID_is_current_thread_ (daemon->tid))); 4726 4727 mhd_assert (0 < fd_setsize); 4728 (void) fd_setsize; /* Mute compiler warning */ 4729 #ifndef HAS_FD_SETSIZE_OVERRIDABLE 4730 (void) fd_setsize; /* Mute compiler warning */ 4731 mhd_assert (((int) FD_SETSIZE) <= fd_setsize); 4732 fd_setsize = FD_SETSIZE; /* Help compiler to optimise */ 4733 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 4734 4735 /* Clear ITC to avoid spinning select */ 4736 /* Do it before any other processing so new signals 4737 will trigger select again and will be processed */ 4738 if (MHD_ITC_IS_VALID_ (daemon->itc)) 4739 { /* Have ITC */ 4740 bool need_to_clear_itc = true; /* ITC is always non-blocking, it is safe to clear even if ITC not activated */ 4741 if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (MHD_itc_r_fd_ (daemon->itc), 4742 NULL, fd_setsize)) 4743 need_to_clear_itc = FD_ISSET (MHD_itc_r_fd_ (daemon->itc), \ 4744 (fd_set *) _MHD_DROP_CONST (read_fd_set)); /* Skip clearing, if not needed */ 4745 if (need_to_clear_itc) 4746 MHD_itc_clear_ (daemon->itc); 4747 } 4748 4749 /* Reset. New value will be set when connections are processed. */ 4750 /* Note: no-op for thread-per-connection as it is always false in that mode. */ 4751 daemon->data_already_pending = false; 4752 4753 /* Process externally added connection if any */ 4754 if (daemon->have_new) 4755 new_connections_list_process_ (daemon); 4756 4757 /* select connection thread handling type */ 4758 ds = daemon->listen_fd; 4759 if ( (MHD_INVALID_SOCKET != ds) && 4760 (! daemon->was_quiesced) ) 4761 { 4762 bool need_to_accept; 4763 if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (ds, NULL, fd_setsize)) 4764 need_to_accept = FD_ISSET (ds, 4765 (fd_set *) _MHD_DROP_CONST (read_fd_set)); 4766 else /* Cannot check whether new connection are pending */ 4767 need_to_accept = daemon->listen_nonblk; /* Try to accept if non-blocking */ 4768 4769 if (need_to_accept) 4770 (void) MHD_accept_connection (daemon); 4771 } 4772 4773 if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) 4774 { 4775 /* do not have a thread per connection, process all connections now */ 4776 struct MHD_Connection *pos; 4777 struct MHD_Connection *prev; 4778 4779 for (pos = daemon->connections_tail; NULL != pos; pos = prev) 4780 { 4781 MHD_socket cs; 4782 bool r_ready; 4783 bool w_ready; 4784 bool has_err; 4785 4786 prev = pos->prev; 4787 cs = pos->socket_fd; 4788 if (MHD_INVALID_SOCKET == cs) 4789 continue; 4790 4791 if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (cs, NULL, fd_setsize)) 4792 { 4793 r_ready = FD_ISSET (cs, 4794 (fd_set *) _MHD_DROP_CONST (read_fd_set)); 4795 w_ready = FD_ISSET (cs, 4796 (fd_set *) _MHD_DROP_CONST (write_fd_set)); 4797 has_err = (NULL != except_fd_set) && 4798 FD_ISSET (cs, 4799 (fd_set *) _MHD_DROP_CONST (except_fd_set)); 4800 } 4801 else 4802 { /* Cannot check the real readiness */ 4803 r_ready = pos->sk_nonblck; 4804 w_ready = r_ready; 4805 has_err = false; 4806 } 4807 call_handlers (pos, 4808 r_ready, 4809 w_ready, 4810 has_err); 4811 } 4812 } 4813 4814 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4815 /* handle upgraded HTTPS connections */ 4816 for (urh = daemon->urh_tail; NULL != urh; urh = urhn) 4817 { 4818 urhn = urh->prev; 4819 /* update urh state based on select() output */ 4820 urh_from_fdset (urh, 4821 read_fd_set, 4822 write_fd_set, 4823 except_fd_set, 4824 fd_setsize); 4825 /* call generic forwarding function for passing data */ 4826 process_urh (urh); 4827 /* Finished forwarding? */ 4828 if ( (0 == urh->in_buffer_size) && 4829 (0 == urh->out_buffer_size) && 4830 (0 == urh->in_buffer_used) && 4831 (0 == urh->out_buffer_used) ) 4832 { 4833 MHD_connection_finish_forward_ (urh->connection); 4834 urh->clean_ready = true; 4835 /* Resuming will move connection to cleanup list. */ 4836 MHD_resume_connection (urh->connection); 4837 } 4838 } 4839 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 4840 MHD_cleanup_connections (daemon); 4841 return MHD_YES; 4842 } 4843 4844 4845 #undef MHD_run_from_select 4846 4847 /** 4848 * Run webserver operations. This method should be called by clients 4849 * in combination with #MHD_get_fdset and #MHD_get_timeout() if the 4850 * client-controlled select method is used. 4851 * This function specifies FD_SETSIZE used when provided fd_sets were 4852 * created. It is important on platforms where FD_SETSIZE can be 4853 * overridden. 4854 * 4855 * You can use this function instead of #MHD_run if you called 4856 * 'select()' on the result from #MHD_get_fdset2(). File descriptors in 4857 * the sets that are not controlled by MHD will be ignored. Calling 4858 * this function instead of #MHD_run() is more efficient as MHD will 4859 * not have to call 'select()' again to determine which operations are 4860 * ready. 4861 * 4862 * If #MHD_get_timeout() returned #MHD_YES, than this function must be 4863 * called right after 'select()' returns regardless of detected activity 4864 * on the daemon's FDs. 4865 * 4866 * This function cannot be used with daemon started with 4867 * #MHD_USE_INTERNAL_POLLING_THREAD flag. 4868 * 4869 * @param daemon the daemon to run select loop for 4870 * @param read_fd_set the read set 4871 * @param write_fd_set the write set 4872 * @param except_fd_set the except set 4873 * @param fd_setsize the value of FD_SETSIZE 4874 * @return #MHD_NO on serious errors, #MHD_YES on success 4875 * @sa #MHD_get_fdset2(), #MHD_OPTION_APP_FD_SETSIZE 4876 * @ingroup event 4877 */ 4878 _MHD_EXTERN enum MHD_Result 4879 MHD_run_from_select2 (struct MHD_Daemon *daemon, 4880 const fd_set *read_fd_set, 4881 const fd_set *write_fd_set, 4882 const fd_set *except_fd_set, 4883 unsigned int fd_setsize) 4884 { 4885 if (MHD_D_IS_USING_POLL_ (daemon) || 4886 MHD_D_IS_USING_THREADS_ (daemon)) 4887 return MHD_NO; 4888 if ((NULL == read_fd_set) || (NULL == write_fd_set)) 4889 return MHD_NO; 4890 #ifdef HAVE_MESSAGES 4891 if (NULL == except_fd_set) 4892 { 4893 MHD_DLOG (daemon, 4894 _ ("MHD_run_from_select() called with except_fd_set " 4895 "set to NULL. Such behavior is deprecated.\n")); 4896 } 4897 #endif /* HAVE_MESSAGES */ 4898 4899 #ifdef HAS_FD_SETSIZE_OVERRIDABLE 4900 if (0 == fd_setsize) 4901 return MHD_NO; 4902 else if (((unsigned int) INT_MAX) < fd_setsize) 4903 fd_setsize = (unsigned int) INT_MAX; 4904 #ifdef HAVE_MESSAGES 4905 else if (daemon->fdset_size > ((int) fd_setsize)) 4906 { 4907 if (daemon->fdset_size_set_by_app) 4908 { 4909 MHD_DLOG (daemon, 4910 _ ("%s() called with fd_setsize (%u) " \ 4911 "less than value set by MHD_OPTION_APP_FD_SETSIZE (%d). " \ 4912 "Some socket FDs may be not processed. " \ 4913 "Use MHD_OPTION_APP_FD_SETSIZE with the correct value.\n"), 4914 "MHD_run_from_select2", fd_setsize, daemon->fdset_size); 4915 } 4916 else 4917 { 4918 MHD_DLOG (daemon, 4919 _ ("%s() called with fd_setsize (%u) " \ 4920 "less than FD_SETSIZE used by MHD (%d). " \ 4921 "Some socket FDs may be not processed. " \ 4922 "Consider using MHD_OPTION_APP_FD_SETSIZE option.\n"), 4923 "MHD_run_from_select2", fd_setsize, daemon->fdset_size); 4924 } 4925 } 4926 #endif /* HAVE_MESSAGES */ 4927 #else /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 4928 if (((unsigned int) FD_SETSIZE) > fd_setsize) 4929 { 4930 #ifdef HAVE_MESSAGES 4931 MHD_DLOG (daemon, 4932 _ ("%s() called with fd_setsize (%u) " \ 4933 "less than fixed FD_SETSIZE value (%d) used on the " \ 4934 "platform.\n"), 4935 "MHD_run_from_select2", fd_setsize, (int) FD_SETSIZE); 4936 #endif /* HAVE_MESSAGES */ 4937 return MHD_NO; 4938 } 4939 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 4940 4941 if (MHD_D_IS_USING_EPOLL_ (daemon)) 4942 { 4943 #ifdef EPOLL_SUPPORT 4944 enum MHD_Result ret = MHD_epoll (daemon, 4945 0); 4946 4947 MHD_cleanup_connections (daemon); 4948 return ret; 4949 #else /* ! EPOLL_SUPPORT */ 4950 return MHD_NO; 4951 #endif /* ! EPOLL_SUPPORT */ 4952 } 4953 4954 /* Resuming external connections when using an extern mainloop */ 4955 if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) 4956 resume_suspended_connections (daemon); 4957 4958 return internal_run_from_select (daemon, 4959 read_fd_set, 4960 write_fd_set, 4961 except_fd_set, 4962 (int) fd_setsize); 4963 } 4964 4965 4966 /** 4967 * Run webserver operations. This method should be called by clients 4968 * in combination with #MHD_get_fdset and #MHD_get_timeout() if the 4969 * client-controlled select method is used. 4970 * 4971 * You can use this function instead of #MHD_run if you called 4972 * `select()` on the result from #MHD_get_fdset. File descriptors in 4973 * the sets that are not controlled by MHD will be ignored. Calling 4974 * this function instead of #MHD_run is more efficient as MHD will 4975 * not have to call `select()` again to determine which operations are 4976 * ready. 4977 * 4978 * If #MHD_get_timeout() returned #MHD_YES, than this function must be 4979 * called right after `select()` returns regardless of detected activity 4980 * on the daemon's FDs. 4981 * 4982 * This function cannot be used with daemon started with 4983 * #MHD_USE_INTERNAL_POLLING_THREAD flag. 4984 * 4985 * @param daemon daemon to run select loop for 4986 * @param read_fd_set read set 4987 * @param write_fd_set write set 4988 * @param except_fd_set except set 4989 * @return #MHD_NO on serious errors, #MHD_YES on success 4990 * @ingroup event 4991 */ 4992 _MHD_EXTERN enum MHD_Result 4993 MHD_run_from_select (struct MHD_Daemon *daemon, 4994 const fd_set *read_fd_set, 4995 const fd_set *write_fd_set, 4996 const fd_set *except_fd_set) 4997 { 4998 return MHD_run_from_select2 (daemon, 4999 read_fd_set, 5000 write_fd_set, 5001 except_fd_set, 5002 #ifdef HAS_FD_SETSIZE_OVERRIDABLE 5003 daemon->fdset_size_set_by_app ? 5004 ((unsigned int) daemon->fdset_size) : 5005 ((unsigned int) _MHD_SYS_DEFAULT_FD_SETSIZE) 5006 #else /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 5007 ((unsigned int) _MHD_SYS_DEFAULT_FD_SETSIZE) 5008 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 5009 ); 5010 } 5011 5012 5013 /** 5014 * Main internal select() call. Will compute select sets, call select() 5015 * and then #internal_run_from_select with the result. 5016 * 5017 * @param daemon daemon to run select() loop for 5018 * @param millisec the maximum time in milliseconds to wait for events, 5019 * set to '0' for non-blocking processing, 5020 * set to '-1' to wait indefinitely. 5021 * @return #MHD_NO on serious errors, #MHD_YES on success 5022 */ 5023 static enum MHD_Result 5024 MHD_select (struct MHD_Daemon *daemon, 5025 int32_t millisec) 5026 { 5027 int num_ready; 5028 fd_set rs; 5029 fd_set ws; 5030 fd_set es; 5031 MHD_socket maxsock; 5032 struct timeval timeout; 5033 struct timeval *tv; 5034 int err_state; 5035 MHD_socket ls; 5036 5037 timeout.tv_sec = 0; 5038 timeout.tv_usec = 0; 5039 if (daemon->shutdown) 5040 return MHD_NO; 5041 FD_ZERO (&rs); 5042 FD_ZERO (&ws); 5043 FD_ZERO (&es); 5044 maxsock = MHD_INVALID_SOCKET; 5045 err_state = MHD_NO; 5046 if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) && 5047 (MHD_NO != resume_suspended_connections (daemon)) && 5048 (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) ) 5049 millisec = 0; 5050 5051 if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) 5052 { 5053 /* single-threaded, go over everything */ 5054 if (MHD_NO == 5055 internal_get_fdset2 (daemon, 5056 &rs, 5057 &ws, 5058 &es, 5059 &maxsock, 5060 (int) FD_SETSIZE)) 5061 { 5062 #ifdef HAVE_MESSAGES 5063 MHD_DLOG (daemon, 5064 _ ("Could not obtain daemon fdsets.\n")); 5065 #endif 5066 err_state = MHD_YES; 5067 } 5068 } 5069 else 5070 { 5071 bool itc_added; 5072 /* accept only, have one thread per connection */ 5073 itc_added = false; 5074 if (MHD_ITC_IS_VALID_ (daemon->itc)) 5075 { 5076 itc_added = MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), 5077 &rs, 5078 &maxsock, 5079 (int) FD_SETSIZE); 5080 if (! itc_added) 5081 { 5082 #ifdef HAVE_MESSAGES 5083 MHD_DLOG (daemon, _ ("Could not add control inter-thread " \ 5084 "communication channel FD to fdset.\n")); 5085 #endif 5086 err_state = MHD_YES; 5087 } 5088 } 5089 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && 5090 (! daemon->was_quiesced) ) 5091 { 5092 /* Stop listening if we are at the configured connection limit */ 5093 /* If we're at the connection limit, no point in really 5094 accepting new connections; however, make sure we do not miss 5095 the shutdown OR the termination of an existing connection; so 5096 only do this optimisation if we have a signaling ITC in 5097 place. */ 5098 if (! itc_added || 5099 ((daemon->connections < daemon->connection_limit) && 5100 ! daemon->at_limit)) 5101 { 5102 if (! MHD_add_to_fd_set_ (ls, 5103 &rs, 5104 &maxsock, 5105 (int) FD_SETSIZE)) 5106 { 5107 #ifdef HAVE_MESSAGES 5108 MHD_DLOG (daemon, 5109 _ ("Could not add listen socket to fdset.\n")); 5110 #endif 5111 err_state = MHD_YES; 5112 } 5113 } 5114 } 5115 } 5116 5117 if (MHD_NO != err_state) 5118 millisec = 0; 5119 if (0 == millisec) 5120 { 5121 timeout.tv_usec = 0; 5122 timeout.tv_sec = 0; 5123 tv = &timeout; 5124 } 5125 else 5126 { 5127 uint64_t mhd_tmo; 5128 uint64_t select_tmo; 5129 5130 if ( (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) && 5131 (MHD_NO != MHD_get_timeout64 (daemon, &mhd_tmo)) ) 5132 { 5133 if ( (0 < millisec) && 5134 (mhd_tmo > (uint64_t) millisec) ) 5135 select_tmo = (uint64_t) millisec; 5136 else 5137 select_tmo = mhd_tmo; 5138 tv = &timeout; /* have timeout value */ 5139 } 5140 else if (0 < millisec) 5141 { 5142 select_tmo = (uint64_t) millisec; 5143 tv = &timeout; /* have timeout value */ 5144 } 5145 else 5146 { 5147 select_tmo = 0; /* Not actually used, silent compiler warning */ 5148 tv = NULL; 5149 } 5150 5151 if (NULL != tv) 5152 { /* have timeout value */ 5153 #if (SIZEOF_UINT64_T - 2) >= SIZEOF_STRUCT_TIMEVAL_TV_SEC 5154 if (select_tmo / 1000 > TIMEVAL_TV_SEC_MAX) 5155 timeout.tv_sec = TIMEVAL_TV_SEC_MAX; 5156 else 5157 #endif /* (SIZEOF_UINT64_T - 2) >= SIZEOF_STRUCT_TIMEVAL_TV_SEC */ 5158 timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) (select_tmo / 1000); 5159 5160 timeout.tv_usec = ((uint16_t) (select_tmo % 1000)) * ((int32_t) 1000); 5161 } 5162 } 5163 num_ready = MHD_SYS_select_ (maxsock + 1, 5164 &rs, 5165 &ws, 5166 &es, 5167 tv); 5168 if (daemon->shutdown) 5169 return MHD_NO; 5170 if (num_ready < 0) 5171 { 5172 const int err = MHD_socket_get_error_ (); 5173 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 5174 return (MHD_NO == err_state) ? MHD_YES : MHD_NO; 5175 #ifdef HAVE_MESSAGES 5176 MHD_DLOG (daemon, 5177 _ ("select failed: %s\n"), 5178 MHD_socket_strerr_ (err)); 5179 #endif 5180 return MHD_NO; 5181 } 5182 if (MHD_NO != internal_run_from_select (daemon, 5183 &rs, 5184 &ws, 5185 &es, 5186 (int) FD_SETSIZE)) 5187 return (MHD_NO == err_state) ? MHD_YES : MHD_NO; 5188 return MHD_NO; 5189 } 5190 5191 5192 #ifdef HAVE_POLL 5193 /** 5194 * Process all of our connections and possibly the server 5195 * socket using poll(). 5196 * 5197 * @param daemon daemon to run poll loop for 5198 * @param millisec the maximum time in milliseconds to wait for events, 5199 * set to '0' for non-blocking processing, 5200 * set to '-1' to wait indefinitely. 5201 * @return #MHD_NO on serious errors, #MHD_YES on success 5202 */ 5203 static enum MHD_Result 5204 MHD_poll_all (struct MHD_Daemon *daemon, 5205 int32_t millisec) 5206 { 5207 unsigned int num_connections; 5208 struct MHD_Connection *pos; 5209 struct MHD_Connection *prev; 5210 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5211 struct MHD_UpgradeResponseHandle *urh; 5212 struct MHD_UpgradeResponseHandle *urhn; 5213 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 5214 5215 mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 5216 (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid))); 5217 mhd_assert ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 5218 (! MHD_thread_handle_ID_is_valid_ID_ (daemon->tid))); 5219 mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 5220 (MHD_thread_handle_ID_is_current_thread_ (daemon->tid))); 5221 5222 if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) && 5223 (MHD_NO != resume_suspended_connections (daemon)) ) 5224 millisec = 0; 5225 5226 /* count number of connections and thus determine poll set size */ 5227 num_connections = 0; 5228 for (pos = daemon->connections_head; NULL != pos; pos = pos->next) 5229 num_connections++; 5230 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5231 for (urh = daemon->urh_head; NULL != urh; urh = urh->next) 5232 num_connections += 2; 5233 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 5234 { 5235 unsigned int i; 5236 int timeout; 5237 unsigned int poll_server; 5238 int poll_listen; 5239 int poll_itc_idx; 5240 struct pollfd *p; 5241 MHD_socket ls; 5242 5243 p = MHD_calloc_ ((2 + (size_t) num_connections), 5244 sizeof (struct pollfd)); 5245 if (NULL == p) 5246 { 5247 #ifdef HAVE_MESSAGES 5248 MHD_DLOG (daemon, 5249 _ ("Error allocating memory: %s\n"), 5250 MHD_strerror_ (errno)); 5251 #endif 5252 return MHD_NO; 5253 } 5254 poll_server = 0; 5255 poll_listen = -1; 5256 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && 5257 (! daemon->was_quiesced) && 5258 (daemon->connections < daemon->connection_limit) && 5259 (! daemon->at_limit) ) 5260 { 5261 /* only listen if we are not at the connection limit */ 5262 p[poll_server].fd = ls; 5263 p[poll_server].events = POLLIN; 5264 p[poll_server].revents = 0; 5265 poll_listen = (int) poll_server; 5266 poll_server++; 5267 } 5268 poll_itc_idx = -1; 5269 if (MHD_ITC_IS_VALID_ (daemon->itc)) 5270 { 5271 p[poll_server].fd = MHD_itc_r_fd_ (daemon->itc); 5272 p[poll_server].events = POLLIN; 5273 p[poll_server].revents = 0; 5274 poll_itc_idx = (int) poll_server; 5275 poll_server++; 5276 } 5277 5278 timeout = get_timeout_millisec_int (daemon, millisec); 5279 5280 i = 0; 5281 for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev) 5282 { 5283 p[poll_server + i].fd = pos->socket_fd; 5284 switch (pos->event_loop_info) 5285 { 5286 case MHD_EVENT_LOOP_INFO_READ: 5287 case MHD_EVENT_LOOP_INFO_PROCESS_READ: 5288 p[poll_server + i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; 5289 break; 5290 case MHD_EVENT_LOOP_INFO_WRITE: 5291 p[poll_server + i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; 5292 break; 5293 case MHD_EVENT_LOOP_INFO_PROCESS: 5294 p[poll_server + i].events |= MHD_POLL_EVENTS_ERR_DISC; 5295 break; 5296 case MHD_EVENT_LOOP_INFO_CLEANUP: 5297 timeout = 0; /* clean up "pos" immediately */ 5298 break; 5299 } 5300 i++; 5301 } 5302 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5303 for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev) 5304 { 5305 urh_to_pollfd (urh, &(p[poll_server + i])); 5306 i += 2; 5307 } 5308 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 5309 if (0 == poll_server + num_connections) 5310 { 5311 free (p); 5312 return MHD_YES; 5313 } 5314 if (MHD_sys_poll_ (p, 5315 poll_server + num_connections, 5316 timeout) < 0) 5317 { 5318 const int err = MHD_socket_get_error_ (); 5319 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 5320 { 5321 free (p); 5322 return MHD_YES; 5323 } 5324 #ifdef HAVE_MESSAGES 5325 MHD_DLOG (daemon, 5326 _ ("poll failed: %s\n"), 5327 MHD_socket_strerr_ (err)); 5328 #endif 5329 free (p); 5330 return MHD_NO; 5331 } 5332 5333 /* handle ITC FD */ 5334 /* do it before any other processing so 5335 new signals will be processed in next loop */ 5336 if ( (-1 != poll_itc_idx) && 5337 (0 != (p[poll_itc_idx].revents & POLLIN)) ) 5338 MHD_itc_clear_ (daemon->itc); 5339 5340 /* handle shutdown */ 5341 if (daemon->shutdown) 5342 { 5343 free (p); 5344 return MHD_NO; 5345 } 5346 5347 /* Process externally added connection if any */ 5348 if (daemon->have_new) 5349 new_connections_list_process_ (daemon); 5350 5351 /* handle 'listen' FD */ 5352 if ( (-1 != poll_listen) && 5353 (0 != (p[poll_listen].revents & POLLIN)) ) 5354 (void) MHD_accept_connection (daemon); 5355 5356 /* Reset. New value will be set when connections are processed. */ 5357 daemon->data_already_pending = false; 5358 5359 i = 0; 5360 prev = daemon->connections_tail; 5361 while (NULL != (pos = prev)) 5362 { 5363 prev = pos->prev; 5364 /* first, sanity checks */ 5365 if (i >= num_connections) 5366 break; /* connection list changed somehow, retry later ... */ 5367 if (p[poll_server + i].fd != pos->socket_fd) 5368 continue; /* fd mismatch, something else happened, retry later ... */ 5369 call_handlers (pos, 5370 0 != (p[poll_server + i].revents & POLLIN), 5371 0 != (p[poll_server + i].revents & POLLOUT), 5372 0 != (p[poll_server + i].revents 5373 & MHD_POLL_REVENTS_ERR_DISC)); 5374 i++; 5375 } 5376 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5377 for (urh = daemon->urh_tail; NULL != urh; urh = urhn) 5378 { 5379 if (i >= num_connections) 5380 break; /* connection list changed somehow, retry later ... */ 5381 5382 /* Get next connection here as connection can be removed 5383 * from 'daemon->urh_head' list. */ 5384 urhn = urh->prev; 5385 /* Check for fd mismatch. FIXME: required for safety? */ 5386 if ((p[poll_server + i].fd != urh->connection->socket_fd) || 5387 (p[poll_server + i + 1].fd != urh->mhd.socket)) 5388 break; 5389 urh_from_pollfd (urh, 5390 &p[poll_server + i]); 5391 i += 2; 5392 process_urh (urh); 5393 /* Finished forwarding? */ 5394 if ( (0 == urh->in_buffer_size) && 5395 (0 == urh->out_buffer_size) && 5396 (0 == urh->in_buffer_used) && 5397 (0 == urh->out_buffer_used) ) 5398 { 5399 /* MHD_connection_finish_forward_() will remove connection from 5400 * 'daemon->urh_head' list. */ 5401 MHD_connection_finish_forward_ (urh->connection); 5402 urh->clean_ready = true; 5403 /* If 'urh->was_closed' already was set to true, connection will be 5404 * moved immediately to cleanup list. Otherwise connection 5405 * will stay in suspended list until 'urh' will be marked 5406 * with 'was_closed' by application. */ 5407 MHD_resume_connection (urh->connection); 5408 } 5409 } 5410 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 5411 5412 free (p); 5413 } 5414 return MHD_YES; 5415 } 5416 5417 5418 /** 5419 * Process only the listen socket using poll(). 5420 * 5421 * @param daemon daemon to run poll loop for 5422 * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking 5423 * @return #MHD_NO on serious errors, #MHD_YES on success 5424 */ 5425 static enum MHD_Result 5426 MHD_poll_listen_socket (struct MHD_Daemon *daemon, 5427 int may_block) 5428 { 5429 struct pollfd p[2]; 5430 int timeout; 5431 unsigned int poll_count; 5432 int poll_listen; 5433 int poll_itc_idx; 5434 MHD_socket ls; 5435 5436 mhd_assert (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid)); 5437 mhd_assert (MHD_thread_handle_ID_is_current_thread_ (daemon->tid)); 5438 5439 memset (&p, 5440 0, 5441 sizeof (p)); 5442 poll_count = 0; 5443 poll_listen = -1; 5444 poll_itc_idx = -1; 5445 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && 5446 (! daemon->was_quiesced) ) 5447 5448 { 5449 p[poll_count].fd = ls; 5450 p[poll_count].events = POLLIN; 5451 p[poll_count].revents = 0; 5452 poll_listen = (int) poll_count; 5453 poll_count++; 5454 } 5455 if (MHD_ITC_IS_VALID_ (daemon->itc)) 5456 { 5457 p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc); 5458 p[poll_count].events = POLLIN; 5459 p[poll_count].revents = 0; 5460 poll_itc_idx = (int) poll_count; 5461 poll_count++; 5462 } 5463 5464 if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) 5465 (void) resume_suspended_connections (daemon); 5466 5467 if (MHD_NO == may_block) 5468 timeout = 0; 5469 else 5470 timeout = -1; 5471 if (0 == poll_count) 5472 return MHD_YES; 5473 if (MHD_sys_poll_ (p, 5474 poll_count, 5475 timeout) < 0) 5476 { 5477 const int err = MHD_socket_get_error_ (); 5478 5479 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 5480 return MHD_YES; 5481 #ifdef HAVE_MESSAGES 5482 MHD_DLOG (daemon, 5483 _ ("poll failed: %s\n"), 5484 MHD_socket_strerr_ (err)); 5485 #endif 5486 return MHD_NO; 5487 } 5488 if ( (0 <= poll_itc_idx) && 5489 (0 != (p[poll_itc_idx].revents & POLLIN)) ) 5490 MHD_itc_clear_ (daemon->itc); 5491 5492 /* handle shutdown */ 5493 if (daemon->shutdown) 5494 return MHD_NO; 5495 5496 /* Process externally added connection if any */ 5497 if (daemon->have_new) 5498 new_connections_list_process_ (daemon); 5499 5500 if ( (0 <= poll_listen) && 5501 (0 != (p[poll_listen].revents & POLLIN)) ) 5502 (void) MHD_accept_connection (daemon); 5503 return MHD_YES; 5504 } 5505 5506 5507 #endif 5508 5509 #ifdef HAVE_POLL 5510 5511 /** 5512 * Do poll()-based processing. 5513 * 5514 * @param daemon daemon to run poll()-loop for 5515 * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking 5516 * @return #MHD_NO on serious errors, #MHD_YES on success 5517 */ 5518 static enum MHD_Result 5519 MHD_poll (struct MHD_Daemon *daemon, 5520 int may_block) 5521 { 5522 if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) 5523 return MHD_poll_all (daemon, 5524 may_block ? -1 : 0); 5525 return MHD_poll_listen_socket (daemon, 5526 may_block); 5527 } 5528 5529 5530 #endif /* HAVE_POLL */ 5531 5532 5533 #ifdef EPOLL_SUPPORT 5534 5535 /** 5536 * How many events to we process at most per epoll() call? Trade-off 5537 * between required stack-size and number of system calls we have to 5538 * make; 128 should be way enough to avoid more than one system call 5539 * for most scenarios, and still be moderate in stack size 5540 * consumption. Embedded systems might want to choose a smaller value 5541 * --- but why use epoll() on such a system in the first place? 5542 */ 5543 #define MAX_EVENTS 128 5544 5545 5546 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5547 5548 /** 5549 * Checks whether @a urh has some data to process. 5550 * 5551 * @param urh upgrade handler to analyse 5552 * @return 'true' if @a urh has some data to process, 5553 * 'false' otherwise 5554 */ 5555 static bool 5556 is_urh_ready (struct MHD_UpgradeResponseHandle *const urh) 5557 { 5558 const struct MHD_Connection *const connection = urh->connection; 5559 5560 if ( (0 == urh->in_buffer_size) && 5561 (0 == urh->out_buffer_size) && 5562 (0 == urh->in_buffer_used) && 5563 (0 == urh->out_buffer_used) ) 5564 return false; 5565 if (connection->daemon->shutdown) 5566 return true; 5567 if ( ( (0 != ((MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_ERROR) 5568 & urh->app.celi)) || 5569 (connection->tls_read_ready) ) && 5570 (urh->in_buffer_used < urh->in_buffer_size) ) 5571 return true; 5572 if ( ( (0 != ((MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_ERROR) 5573 & urh->mhd.celi)) || 5574 urh->was_closed) && 5575 (urh->out_buffer_used < urh->out_buffer_size) ) 5576 return true; 5577 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) && 5578 (urh->out_buffer_used > 0) ) 5579 return true; 5580 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && 5581 (urh->in_buffer_used > 0) ) 5582 return true; 5583 return false; 5584 } 5585 5586 5587 /** 5588 * Do epoll()-based processing for TLS connections that have been 5589 * upgraded. This requires a separate epoll() invocation as we 5590 * cannot use the `struct MHD_Connection` data structures for 5591 * the `union epoll_data` in this case. 5592 * @remark To be called only from thread that process 5593 * daemon's select()/poll()/etc. 5594 */ 5595 static enum MHD_Result 5596 run_epoll_for_upgrade (struct MHD_Daemon *daemon) 5597 { 5598 struct epoll_event events[MAX_EVENTS]; 5599 int num_events; 5600 struct MHD_UpgradeResponseHandle *pos; 5601 struct MHD_UpgradeResponseHandle *prev; 5602 5603 #ifdef MHD_USE_THREADS 5604 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 5605 MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); 5606 #endif /* MHD_USE_THREADS */ 5607 5608 num_events = MAX_EVENTS; 5609 while (0 != num_events) 5610 { 5611 unsigned int i; 5612 /* update event masks */ 5613 num_events = epoll_wait (daemon->epoll_upgrade_fd, 5614 events, 5615 MAX_EVENTS, 5616 0); 5617 if (-1 == num_events) 5618 { 5619 const int err = MHD_socket_get_error_ (); 5620 5621 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 5622 return MHD_YES; 5623 #ifdef HAVE_MESSAGES 5624 MHD_DLOG (daemon, 5625 _ ("Call to epoll_wait failed: %s\n"), 5626 MHD_socket_strerr_ (err)); 5627 #endif 5628 return MHD_NO; 5629 } 5630 for (i = 0; i < (unsigned int) num_events; i++) 5631 { 5632 struct UpgradeEpollHandle *const ueh = events[i].data.ptr; 5633 struct MHD_UpgradeResponseHandle *const urh = ueh->urh; 5634 bool new_err_state = false; 5635 5636 if (urh->clean_ready) 5637 continue; 5638 5639 /* Update ueh state based on what is ready according to epoll() */ 5640 if (0 != (events[i].events & EPOLLIN)) 5641 { 5642 ueh->celi |= MHD_EPOLL_STATE_READ_READY; 5643 } 5644 if (0 != (events[i].events & EPOLLOUT)) 5645 { 5646 ueh->celi |= MHD_EPOLL_STATE_WRITE_READY; 5647 } 5648 if (0 != (events[i].events & EPOLLHUP)) 5649 { 5650 ueh->celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY; 5651 } 5652 5653 if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) && 5654 (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) ) 5655 { 5656 /* Process new error state only one time and avoid continuously 5657 * marking this connection as 'ready'. */ 5658 ueh->celi |= MHD_EPOLL_STATE_ERROR; 5659 new_err_state = true; 5660 } 5661 if (! urh->in_eready_list) 5662 { 5663 if (new_err_state || 5664 is_urh_ready (urh)) 5665 { 5666 EDLL_insert (daemon->eready_urh_head, 5667 daemon->eready_urh_tail, 5668 urh); 5669 urh->in_eready_list = true; 5670 } 5671 } 5672 } 5673 } 5674 prev = daemon->eready_urh_tail; 5675 while (NULL != (pos = prev)) 5676 { 5677 prev = pos->prevE; 5678 process_urh (pos); 5679 if (! is_urh_ready (pos)) 5680 { 5681 EDLL_remove (daemon->eready_urh_head, 5682 daemon->eready_urh_tail, 5683 pos); 5684 pos->in_eready_list = false; 5685 } 5686 /* Finished forwarding? */ 5687 if ( (0 == pos->in_buffer_size) && 5688 (0 == pos->out_buffer_size) && 5689 (0 == pos->in_buffer_used) && 5690 (0 == pos->out_buffer_used) ) 5691 { 5692 MHD_connection_finish_forward_ (pos->connection); 5693 pos->clean_ready = true; 5694 /* If 'pos->was_closed' already was set to true, connection 5695 * will be moved immediately to cleanup list. Otherwise 5696 * connection will stay in suspended list until 'pos' will 5697 * be marked with 'was_closed' by application. */ 5698 MHD_resume_connection (pos->connection); 5699 } 5700 } 5701 5702 return MHD_YES; 5703 } 5704 5705 5706 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 5707 5708 5709 /** 5710 * Pointer-marker to distinguish ITC slot in epoll sets. 5711 */ 5712 static const char *const epoll_itc_marker = "itc_marker"; 5713 5714 5715 /** 5716 * Do epoll()-based processing. 5717 * 5718 * @param daemon daemon to run poll loop for 5719 * @param millisec the maximum time in milliseconds to wait for events, 5720 * set to '0' for non-blocking processing, 5721 * set to '-1' to wait indefinitely. 5722 * @return #MHD_NO on serious errors, #MHD_YES on success 5723 */ 5724 static enum MHD_Result 5725 MHD_epoll (struct MHD_Daemon *daemon, 5726 int32_t millisec) 5727 { 5728 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5729 static const char *const upgrade_marker = "upgrade_ptr"; 5730 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 5731 struct MHD_Connection *pos; 5732 struct MHD_Connection *prev; 5733 struct epoll_event events[MAX_EVENTS]; 5734 struct epoll_event event; 5735 int timeout_ms; 5736 int num_events; 5737 unsigned int i; 5738 MHD_socket ls; 5739 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5740 bool run_upgraded = false; 5741 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 5742 bool need_to_accept; 5743 5744 mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 5745 (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid))); 5746 mhd_assert ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 5747 (! MHD_thread_handle_ID_is_valid_ID_ (daemon->tid))); 5748 mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 5749 (MHD_thread_handle_ID_is_current_thread_ (daemon->tid))); 5750 5751 if (-1 == daemon->epoll_fd) 5752 return MHD_NO; /* we're down! */ 5753 if (daemon->shutdown) 5754 return MHD_NO; 5755 /* 'listen_socket_in_epoll', 'was_quiesced' and the epoll set itself 5756 are shared with MHD_quiesce_daemon(), which runs on the 5757 application's thread. Testing them and acting on the result has to 5758 be one atomic step. */ 5759 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5760 MHD_mutex_lock_chk_ (&daemon->epoll_listen_mutex); 5761 #endif 5762 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && 5763 (! daemon->was_quiesced) && 5764 (daemon->connections < daemon->connection_limit) && 5765 (! daemon->listen_socket_in_epoll) && 5766 (! daemon->at_limit) ) 5767 { 5768 event.events = EPOLLIN | EPOLLRDHUP; 5769 event.data.ptr = daemon; 5770 if (0 != epoll_ctl (daemon->epoll_fd, 5771 EPOLL_CTL_ADD, 5772 ls, 5773 &event)) 5774 { 5775 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5776 MHD_mutex_unlock_chk_ (&daemon->epoll_listen_mutex); 5777 #endif 5778 #ifdef HAVE_MESSAGES 5779 MHD_DLOG (daemon, 5780 _ ("Call to epoll_ctl failed: %s\n"), 5781 MHD_socket_last_strerr_ ()); 5782 #endif 5783 return MHD_NO; 5784 } 5785 daemon->listen_socket_in_epoll = true; 5786 } 5787 if ( (daemon->was_quiesced) && 5788 (daemon->listen_socket_in_epoll) ) 5789 { 5790 if (0 != epoll_ctl (daemon->epoll_fd, 5791 EPOLL_CTL_DEL, 5792 ls, 5793 NULL)) 5794 MHD_PANIC ("Failed to remove listen FD from epoll set.\n"); 5795 daemon->listen_socket_in_epoll = false; 5796 } 5797 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5798 MHD_mutex_unlock_chk_ (&daemon->epoll_listen_mutex); 5799 #endif 5800 5801 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5802 if ( ( (! daemon->upgrade_fd_in_epoll) && 5803 (-1 != daemon->epoll_upgrade_fd) ) ) 5804 { 5805 event.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP; 5806 event.data.ptr = _MHD_DROP_CONST (upgrade_marker); 5807 if (0 != epoll_ctl (daemon->epoll_fd, 5808 EPOLL_CTL_ADD, 5809 daemon->epoll_upgrade_fd, 5810 &event)) 5811 { 5812 #ifdef HAVE_MESSAGES 5813 MHD_DLOG (daemon, 5814 _ ("Call to epoll_ctl failed: %s\n"), 5815 MHD_socket_last_strerr_ ()); 5816 #endif 5817 return MHD_NO; 5818 } 5819 daemon->upgrade_fd_in_epoll = true; 5820 } 5821 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 5822 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5823 MHD_mutex_lock_chk_ (&daemon->epoll_listen_mutex); 5824 #endif 5825 if ( (daemon->listen_socket_in_epoll) && 5826 ( (daemon->connections == daemon->connection_limit) || 5827 (daemon->at_limit) || 5828 (daemon->was_quiesced) ) ) 5829 { 5830 /* we're at the connection limit, disable listen socket 5831 for event loop for now */ 5832 if (0 != epoll_ctl (daemon->epoll_fd, 5833 EPOLL_CTL_DEL, 5834 ls, 5835 NULL)) 5836 MHD_PANIC (_ ("Failed to remove listen FD from epoll set.\n")); 5837 daemon->listen_socket_in_epoll = false; 5838 } 5839 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5840 MHD_mutex_unlock_chk_ (&daemon->epoll_listen_mutex); 5841 #endif 5842 5843 if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) && 5844 (MHD_NO != resume_suspended_connections (daemon)) ) 5845 millisec = 0; 5846 5847 timeout_ms = get_timeout_millisec_int (daemon, 5848 millisec); 5849 5850 /* Reset. New value will be set when connections are processed. */ 5851 /* Note: Used mostly for uniformity here as same situation is 5852 * signaled in epoll mode by non-empty eready DLL. */ 5853 daemon->data_already_pending = false; 5854 5855 need_to_accept = false; 5856 /* drain 'epoll' event queue; need to iterate as we get at most 5857 MAX_EVENTS in one system call here; in practice this should 5858 pretty much mean only one round, but better an extra loop here 5859 than unfair behavior... */ 5860 num_events = MAX_EVENTS; 5861 while (MAX_EVENTS == num_events) 5862 { 5863 /* update event masks */ 5864 num_events = epoll_wait (daemon->epoll_fd, 5865 events, 5866 MAX_EVENTS, 5867 timeout_ms); 5868 if (-1 == num_events) 5869 { 5870 const int err = MHD_socket_get_error_ (); 5871 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 5872 return MHD_YES; 5873 #ifdef HAVE_MESSAGES 5874 MHD_DLOG (daemon, 5875 _ ("Call to epoll_wait failed: %s\n"), 5876 MHD_socket_strerr_ (err)); 5877 #endif 5878 return MHD_NO; 5879 } 5880 for (i = 0; i < (unsigned int) num_events; i++) 5881 { 5882 /* First, check for the values of `ptr` that would indicate 5883 that this event is not about a normal connection. */ 5884 if (NULL == events[i].data.ptr) 5885 continue; /* shutdown signal! */ 5886 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5887 if (upgrade_marker == events[i].data.ptr) 5888 { 5889 /* activity on an upgraded connection, we process 5890 those in a separate epoll() */ 5891 run_upgraded = true; 5892 continue; 5893 } 5894 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 5895 if (epoll_itc_marker == events[i].data.ptr) 5896 { 5897 /* It's OK to clear ITC here as all external 5898 conditions will be processed later. */ 5899 MHD_itc_clear_ (daemon->itc); 5900 continue; 5901 } 5902 if (daemon == events[i].data.ptr) 5903 { 5904 /* Check for error conditions on listen socket. */ 5905 /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */ 5906 if (0 == (events[i].events & (EPOLLERR | EPOLLHUP))) 5907 need_to_accept = true; 5908 continue; 5909 } 5910 /* this is an event relating to a 'normal' connection, 5911 remember the event and if appropriate mark the 5912 connection as 'eready'. */ 5913 pos = events[i].data.ptr; 5914 /* normal processing: update read/write data */ 5915 if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP))) 5916 { 5917 pos->epoll_state |= MHD_EPOLL_STATE_ERROR; 5918 if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) 5919 { 5920 EDLL_insert (daemon->eready_head, 5921 daemon->eready_tail, 5922 pos); 5923 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; 5924 } 5925 } 5926 else 5927 { 5928 if (0 != (events[i].events & EPOLLIN)) 5929 { 5930 pos->epoll_state |= MHD_EPOLL_STATE_READ_READY; 5931 if ( ( (0 != (MHD_EVENT_LOOP_INFO_READ & pos->event_loop_info)) || 5932 (pos->read_buffer_size > pos->read_buffer_offset) ) && 5933 (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) 5934 { 5935 EDLL_insert (daemon->eready_head, 5936 daemon->eready_tail, 5937 pos); 5938 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; 5939 } 5940 } 5941 if (0 != (events[i].events & EPOLLOUT)) 5942 { 5943 pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY; 5944 if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) && 5945 (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) 5946 { 5947 EDLL_insert (daemon->eready_head, 5948 daemon->eready_tail, 5949 pos); 5950 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; 5951 } 5952 } 5953 } 5954 } 5955 } 5956 5957 /* Process externally added connection if any */ 5958 if (daemon->have_new) 5959 new_connections_list_process_ (daemon); 5960 5961 if (need_to_accept) 5962 { 5963 unsigned int series_length = 0; 5964 5965 /* Run 'accept' until it fails or daemon at limit of connections. 5966 * Do not accept more then 10 connections at once. The rest will 5967 * be accepted on next turn (level trigger is used for listen 5968 * socket). */ 5969 while ( (MHD_NO != MHD_accept_connection (daemon)) && 5970 (series_length < 10) && 5971 (daemon->connections < daemon->connection_limit) && 5972 (! daemon->at_limit) ) 5973 series_length++; 5974 } 5975 5976 /* Handle timed-out connections; we need to do this here 5977 as the epoll mechanism won't call the 'MHD_connection_handle_idle()' on everything, 5978 as the other event loops do. As timeouts do not get an explicit 5979 event, we need to find those connections that might have timed out 5980 here. 5981 5982 Connections with custom timeouts must all be looked at, as we 5983 do not bother to sort that (presumably very short) list. */ 5984 prev = daemon->manual_timeout_tail; 5985 while (NULL != (pos = prev)) 5986 { 5987 prev = pos->prevX; 5988 MHD_connection_handle_idle (pos); 5989 } 5990 /* Connections with the default timeout are sorted by prepending 5991 them to the head of the list whenever we touch the connection; 5992 thus it suffices to iterate from the tail until the first 5993 connection is NOT timed out */ 5994 prev = daemon->normal_timeout_tail; 5995 while (NULL != (pos = prev)) 5996 { 5997 prev = pos->prevX; 5998 MHD_connection_handle_idle (pos); 5999 if (MHD_CONNECTION_CLOSED != pos->state) 6000 break; /* sorted by timeout, no need to visit the rest! */ 6001 } 6002 6003 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6004 if (run_upgraded || (NULL != daemon->eready_urh_head)) 6005 run_epoll_for_upgrade (daemon); 6006 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 6007 6008 /* process events for connections */ 6009 prev = daemon->eready_tail; 6010 while (NULL != (pos = prev)) 6011 { 6012 prev = pos->prevE; 6013 call_handlers (pos, 6014 0 != (pos->epoll_state & MHD_EPOLL_STATE_READ_READY), 6015 0 != (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY), 6016 0 != (pos->epoll_state & MHD_EPOLL_STATE_ERROR)); 6017 if (MHD_EPOLL_STATE_IN_EREADY_EDLL == 6018 (pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED 6019 | MHD_EPOLL_STATE_IN_EREADY_EDLL))) 6020 { 6021 if ( ((MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) && 6022 (0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) || 6023 ((MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) && 6024 (0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) ) || 6025 (MHD_EVENT_LOOP_INFO_CLEANUP == pos->event_loop_info) ) 6026 { 6027 EDLL_remove (daemon->eready_head, 6028 daemon->eready_tail, 6029 pos); 6030 pos->epoll_state &= 6031 ~((enum MHD_EpollState) MHD_EPOLL_STATE_IN_EREADY_EDLL); 6032 } 6033 } 6034 } 6035 6036 return MHD_YES; 6037 } 6038 6039 6040 #endif 6041 6042 6043 /** 6044 * Run webserver operations (without blocking unless in client callbacks). 6045 * 6046 * This method should be called by clients in combination with 6047 * #MHD_get_fdset() (or #MHD_get_daemon_info() with MHD_DAEMON_INFO_EPOLL_FD 6048 * if epoll is used) and #MHD_get_timeout() if the client-controlled 6049 * connection polling method is used (i.e. daemon was started without 6050 * #MHD_USE_INTERNAL_POLLING_THREAD flag). 6051 * 6052 * This function is a convenience method, which is useful if the 6053 * fd_sets from #MHD_get_fdset were not directly passed to `select()`; 6054 * with this function, MHD will internally do the appropriate `select()` 6055 * call itself again. While it is acceptable to call #MHD_run (if 6056 * #MHD_USE_INTERNAL_POLLING_THREAD is not set) at any moment, you should 6057 * call #MHD_run_from_select() if performance is important (as it saves an 6058 * expensive call to `select()`). 6059 * 6060 * If #MHD_get_timeout() returned #MHD_YES, than this function must be called 6061 * right after polling function returns regardless of detected activity on 6062 * the daemon's FDs. 6063 * 6064 * @param daemon daemon to run 6065 * @return #MHD_YES on success, #MHD_NO if this 6066 * daemon was not started with the right 6067 * options for this call. 6068 * @ingroup event 6069 */ 6070 _MHD_EXTERN enum MHD_Result 6071 MHD_run (struct MHD_Daemon *daemon) 6072 { 6073 if ( (daemon->shutdown) || 6074 MHD_D_IS_USING_THREADS_ (daemon) ) 6075 return MHD_NO; 6076 6077 (void) MHD_run_wait (daemon, 0); 6078 return MHD_YES; 6079 } 6080 6081 6082 /** 6083 * Run webserver operation with possible blocking. 6084 * 6085 * This function does the following: waits for any network event not more than 6086 * specified number of milliseconds, processes all incoming and outgoing data, 6087 * processes new connections, processes any timed-out connection, and does 6088 * other things required to run webserver. 6089 * Once all connections are processed, function returns. 6090 * 6091 * This function is useful for quick and simple (lazy) webserver implementation 6092 * if application needs to run a single thread only and does not have any other 6093 * network activity. 6094 * 6095 * This function calls MHD_get_timeout() internally and use returned value as 6096 * maximum wait time if it less than value of @a millisec parameter. 6097 * 6098 * It is expected that the "external" socket polling function is not used in 6099 * conjunction with this function unless the @a millisec is set to zero. 6100 * 6101 * @param daemon the daemon to run 6102 * @param millisec the maximum time in milliseconds to wait for network and 6103 * other events. Note: there is no guarantee that function 6104 * blocks for the specified amount of time. The real processing 6105 * time can be shorter (if some data or connection timeout 6106 * comes earlier) or longer (if data processing requires more 6107 * time, especially in user callbacks). 6108 * If set to '0' then function does not block and processes 6109 * only already available data (if any). 6110 * If set to '-1' then function waits for events 6111 * indefinitely (blocks until next network activity or 6112 * connection timeout). 6113 * @return #MHD_YES on success, #MHD_NO if this 6114 * daemon was not started with the right 6115 * options for this call or some serious 6116 * unrecoverable error occurs. 6117 * @note Available since #MHD_VERSION 0x00097206 6118 * @ingroup event 6119 */ 6120 _MHD_EXTERN enum MHD_Result 6121 MHD_run_wait (struct MHD_Daemon *daemon, 6122 int32_t millisec) 6123 { 6124 enum MHD_Result res; 6125 if ( (daemon->shutdown) || 6126 MHD_D_IS_USING_THREADS_ (daemon) ) 6127 return MHD_NO; 6128 6129 mhd_assert (! MHD_thread_handle_ID_is_valid_handle_ (daemon->tid)); 6130 6131 if (0 > millisec) 6132 millisec = -1; 6133 #ifdef HAVE_POLL 6134 if (MHD_D_IS_USING_POLL_ (daemon)) 6135 { 6136 res = MHD_poll_all (daemon, millisec); 6137 MHD_cleanup_connections (daemon); 6138 } 6139 else 6140 #endif /* HAVE_POLL */ 6141 #ifdef EPOLL_SUPPORT 6142 if (MHD_D_IS_USING_EPOLL_ (daemon)) 6143 { 6144 res = MHD_epoll (daemon, millisec); 6145 MHD_cleanup_connections (daemon); 6146 } 6147 else 6148 #endif 6149 if (1) 6150 { 6151 mhd_assert (MHD_D_IS_USING_SELECT_ (daemon)); 6152 #ifdef HAS_FD_SETSIZE_OVERRIDABLE 6153 #ifdef HAVE_MESSAGES 6154 if (daemon->fdset_size_set_by_app 6155 && (((int) FD_SETSIZE) < daemon->fdset_size)) 6156 { 6157 MHD_DLOG (daemon, 6158 _ ("MHD_run()/MHD_run_wait() called for daemon started with " \ 6159 "MHD_OPTION_APP_FD_SETSIZE option (%d). " \ 6160 "The library was compiled with smaller FD_SETSIZE (%d). " \ 6161 "Some socket FDs may be not processed. " \ 6162 "Use MHD_run_from_select2() instead of MHD_run() or " \ 6163 "do not use MHD_OPTION_APP_FD_SETSIZE option.\n"), 6164 daemon->fdset_size, (int) FD_SETSIZE); 6165 } 6166 #endif /* HAVE_MESSAGES */ 6167 #endif /* HAS_FD_SETSIZE_OVERRIDABLE */ 6168 6169 res = MHD_select (daemon, millisec); 6170 /* MHD_select does MHD_cleanup_connections already */ 6171 } 6172 return res; 6173 } 6174 6175 6176 /** 6177 * Close the given connection, remove it from all of its 6178 * DLLs and move it into the cleanup queue. 6179 * @remark To be called only from thread that 6180 * process daemon's select()/poll()/etc. 6181 * 6182 * @param pos connection to move to cleanup 6183 */ 6184 static void 6185 close_connection (struct MHD_Connection *pos) 6186 { 6187 struct MHD_Daemon *daemon = pos->daemon; 6188 6189 #ifdef MHD_USE_THREADS 6190 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 6191 MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); 6192 mhd_assert (NULL == daemon->worker_pool); 6193 #endif /* MHD_USE_THREADS */ 6194 6195 if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) 6196 { 6197 MHD_connection_mark_closed_ (pos); 6198 return; /* must let thread to do the rest */ 6199 } 6200 MHD_connection_close_ (pos, 6201 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN); 6202 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6203 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 6204 #endif 6205 mhd_assert (! pos->suspended); 6206 mhd_assert (! pos->resuming); 6207 if (pos->connection_timeout_ms == daemon->connection_timeout_ms) 6208 XDLL_remove (daemon->normal_timeout_head, 6209 daemon->normal_timeout_tail, 6210 pos); 6211 else 6212 XDLL_remove (daemon->manual_timeout_head, 6213 daemon->manual_timeout_tail, 6214 pos); 6215 DLL_remove (daemon->connections_head, 6216 daemon->connections_tail, 6217 pos); 6218 DLL_insert (daemon->cleanup_head, 6219 daemon->cleanup_tail, 6220 pos); 6221 daemon->data_already_pending = true; 6222 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6223 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 6224 #endif 6225 } 6226 6227 6228 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6229 /** 6230 * Thread that runs the polling loop until the daemon 6231 * is explicitly shut down. 6232 * 6233 * @param cls `struct MHD_Deamon` to run select loop in a thread for 6234 * @return always 0 (on shutdown) 6235 */ 6236 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ 6237 MHD_polling_thread (void *cls) 6238 { 6239 struct MHD_Daemon *daemon = cls; 6240 #ifdef HAVE_PTHREAD_SIGMASK 6241 sigset_t s_mask; 6242 int err; 6243 #endif /* HAVE_PTHREAD_SIGMASK */ 6244 6245 MHD_thread_handle_ID_set_current_thread_ID_ (&(daemon->tid)); 6246 #ifdef HAVE_PTHREAD_SIGMASK 6247 if ((0 == sigemptyset (&s_mask)) && 6248 (0 == sigaddset (&s_mask, SIGPIPE))) 6249 { 6250 err = pthread_sigmask (SIG_BLOCK, &s_mask, NULL); 6251 } 6252 else 6253 err = errno; 6254 if (0 == err) 6255 daemon->sigpipe_blocked = true; 6256 #ifdef HAVE_MESSAGES 6257 else 6258 MHD_DLOG (daemon, 6259 _ ("Failed to block SIGPIPE on daemon thread: %s\n"), 6260 MHD_strerror_ (errno)); 6261 #endif /* HAVE_MESSAGES */ 6262 #endif /* HAVE_PTHREAD_SIGMASK */ 6263 while (! daemon->shutdown) 6264 { 6265 #ifdef HAVE_POLL 6266 if (MHD_D_IS_USING_POLL_ (daemon)) 6267 MHD_poll (daemon, MHD_YES); 6268 else 6269 #endif /* HAVE_POLL */ 6270 #ifdef EPOLL_SUPPORT 6271 if (MHD_D_IS_USING_EPOLL_ (daemon)) 6272 MHD_epoll (daemon, -1); 6273 else 6274 #endif 6275 MHD_select (daemon, -1); 6276 MHD_cleanup_connections (daemon); 6277 } 6278 6279 /* Resume any pending for resume connections, join 6280 * all connection's threads (if any) and finally cleanup 6281 * everything. */ 6282 if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options)) 6283 resume_suspended_connections (daemon); 6284 close_all_connections (daemon); 6285 6286 return (MHD_THRD_RTRN_TYPE_) 0; 6287 } 6288 6289 6290 #endif 6291 6292 6293 /** 6294 * Process escape sequences ('%HH') Updates val in place; the 6295 * result cannot be larger than the input. 6296 * The result must also still be 0-terminated. 6297 * 6298 * @param cls closure (use NULL) 6299 * @param connection handle to connection, not used 6300 * @param val value to unescape (modified in the process) 6301 * @return length of the resulting val (strlen(val) maybe 6302 * shorter afterwards due to elimination of escape sequences) 6303 */ 6304 static size_t 6305 unescape_wrapper (void *cls, 6306 struct MHD_Connection *connection, 6307 char *val) 6308 { 6309 bool broken; 6310 size_t res; 6311 (void) cls; /* Mute compiler warning. */ 6312 6313 /* TODO: add individual parameter */ 6314 if (0 <= connection->daemon->client_discipline) 6315 return MHD_str_pct_decode_in_place_strict_ (val); 6316 6317 res = MHD_str_pct_decode_in_place_lenient_ (val, &broken); 6318 #ifdef HAVE_MESSAGES 6319 if (broken) 6320 { 6321 MHD_DLOG (connection->daemon, 6322 _ ("The URL encoding is broken.\n")); 6323 } 6324 #endif /* HAVE_MESSAGES */ 6325 return res; 6326 } 6327 6328 6329 /** 6330 * Start a webserver on the given port. Variadic version of 6331 * #MHD_start_daemon_va. 6332 * 6333 * @param flags combination of `enum MHD_FLAG` values 6334 * @param port port to bind to (in host byte order), 6335 * use '0' to bind to random free port, 6336 * ignored if #MHD_OPTION_SOCK_ADDR or 6337 * #MHD_OPTION_LISTEN_SOCKET is provided 6338 * or #MHD_USE_NO_LISTEN_SOCKET is specified 6339 * @param apc callback to call to check which clients 6340 * will be allowed to connect; you can pass NULL 6341 * in which case connections from any IP will be 6342 * accepted 6343 * @param apc_cls extra argument to @a apc 6344 * @param dh handler called for all requests (repeatedly) 6345 * @param dh_cls extra argument to @a dh 6346 * @return NULL on error, handle to daemon on success 6347 * @ingroup event 6348 */ 6349 _MHD_EXTERN struct MHD_Daemon * 6350 MHD_start_daemon (unsigned int flags, 6351 uint16_t port, 6352 MHD_AcceptPolicyCallback apc, 6353 void *apc_cls, 6354 MHD_AccessHandlerCallback dh, 6355 void *dh_cls, 6356 ...) 6357 { 6358 struct MHD_Daemon *daemon; 6359 va_list ap; 6360 6361 va_start (ap, 6362 dh_cls); 6363 daemon = MHD_start_daemon_va (flags, 6364 port, 6365 apc, 6366 apc_cls, 6367 dh, 6368 dh_cls, 6369 ap); 6370 va_end (ap); 6371 return daemon; 6372 } 6373 6374 6375 /** 6376 * Stop accepting connections from the listening socket. Allows 6377 * clients to continue processing, but stops accepting new 6378 * connections. Note that the caller is responsible for closing the 6379 * returned socket; however, if MHD is run using threads (anything but 6380 * external select mode), socket will be removed from existing threads 6381 * with some delay and it must not be closed while it's in use. To make 6382 * sure that the socket is not used anymore, call #MHD_stop_daemon. 6383 * 6384 * Note that some thread modes require the caller to have passed 6385 * #MHD_USE_ITC when using this API. If this daemon is 6386 * in one of those modes and this option was not given to 6387 * #MHD_start_daemon, this function will return #MHD_INVALID_SOCKET. 6388 * 6389 * @param daemon daemon to stop accepting new connections for 6390 * @return old listen socket on success, #MHD_INVALID_SOCKET if 6391 * the daemon was already not listening anymore 6392 * @ingroup specialized 6393 */ 6394 _MHD_EXTERN MHD_socket 6395 MHD_quiesce_daemon (struct MHD_Daemon *daemon) 6396 { 6397 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6398 unsigned int i; 6399 #endif 6400 MHD_socket ret; 6401 6402 ret = daemon->listen_fd; 6403 if ((MHD_INVALID_SOCKET == ret) 6404 || daemon->was_quiesced) 6405 return MHD_INVALID_SOCKET; 6406 if ( (0 == (daemon->options & (MHD_USE_ITC))) && 6407 MHD_D_IS_USING_THREADS_ (daemon) ) 6408 { 6409 #ifdef HAVE_MESSAGES 6410 MHD_DLOG (daemon, 6411 _ ("Using MHD_quiesce_daemon in this mode " \ 6412 "requires MHD_USE_ITC.\n")); 6413 #endif 6414 return MHD_INVALID_SOCKET; 6415 } 6416 6417 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6418 if (NULL != daemon->worker_pool) 6419 for (i = 0; i < daemon->worker_pool_size; i++) 6420 { 6421 /* Each worker is an independent daemon with its own epoll set and 6422 its own lock; they are taken one at a time and never nested, so 6423 there is no ordering to get wrong. Holding the worker's lock 6424 is what stops it removing the same descriptor concurrently from 6425 its own MHD_epoll(). */ 6426 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6427 MHD_mutex_lock_chk_ (&daemon->worker_pool[i].epoll_listen_mutex); 6428 #endif 6429 daemon->worker_pool[i].was_quiesced = true; 6430 #ifdef EPOLL_SUPPORT 6431 if (MHD_D_IS_USING_EPOLL_ (daemon) && 6432 (-1 != daemon->worker_pool[i].epoll_fd) && 6433 (daemon->worker_pool[i].listen_socket_in_epoll) ) 6434 { 6435 if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd, 6436 EPOLL_CTL_DEL, 6437 ret, 6438 NULL)) 6439 MHD_PANIC (_ ("Failed to remove listen FD from epoll set.\n")); 6440 daemon->worker_pool[i].listen_socket_in_epoll = false; 6441 } 6442 else 6443 #endif 6444 if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc)) 6445 { 6446 if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "q")) 6447 MHD_PANIC (_ ("Failed to signal quiesce via inter-thread " \ 6448 "communication channel.\n")); 6449 } 6450 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6451 MHD_mutex_unlock_chk_ (&daemon->worker_pool[i].epoll_listen_mutex); 6452 #endif 6453 } 6454 #endif 6455 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6456 MHD_mutex_lock_chk_ (&daemon->epoll_listen_mutex); 6457 #endif 6458 daemon->was_quiesced = true; 6459 #ifdef EPOLL_SUPPORT 6460 if (MHD_D_IS_USING_EPOLL_ (daemon) && 6461 (-1 != daemon->epoll_fd) && 6462 (daemon->listen_socket_in_epoll) ) 6463 { 6464 if (0 != epoll_ctl (daemon->epoll_fd, 6465 EPOLL_CTL_DEL, 6466 ret, 6467 NULL)) 6468 MHD_PANIC ("Failed to remove listen FD from epoll set.\n"); 6469 daemon->listen_socket_in_epoll = false; 6470 } 6471 #endif 6472 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6473 MHD_mutex_unlock_chk_ (&daemon->epoll_listen_mutex); 6474 #endif 6475 if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && 6476 (! MHD_itc_activate_ (daemon->itc, "q")) ) 6477 MHD_PANIC (_ ("failed to signal quiesce via inter-thread " \ 6478 "communication channel.\n")); 6479 return ret; 6480 } 6481 6482 6483 /** 6484 * Temporal location of the application-provided parameters/options. 6485 * Used when options are decoded from #MHD_start_deamon() parameters, but 6486 * not yet processed/applied. 6487 */ 6488 struct MHD_InterimParams_ 6489 { 6490 /** 6491 * The total number of all user options used. 6492 * 6493 * Contains number only of meaningful options, i.e. #MHD_OPTION_END and 6494 * #MHD_OPTION_ARRAY themselves are not counted, while options inside 6495 * #MHD_OPTION_ARRAY are counted. 6496 */ 6497 size_t num_opts; 6498 /** 6499 * Set to 'true' if @a fdset_size is set by application. 6500 */ 6501 bool fdset_size_set; 6502 /** 6503 * The value for #MHD_OPTION_APP_FD_SETSIZE set by application. 6504 */ 6505 int fdset_size; 6506 /** 6507 * Set to 'true' if @a listen_fd is set by application. 6508 */ 6509 bool listen_fd_set; 6510 /** 6511 * Application-provided listen socket. 6512 */ 6513 MHD_socket listen_fd; 6514 /** 6515 * Set to 'true' if @a server_addr is set by application. 6516 */ 6517 bool pserver_addr_set; 6518 /** 6519 * Application-provided struct sockaddr to bind server to. 6520 */ 6521 const struct sockaddr *pserver_addr; 6522 /** 6523 * Set to 'true' if @a server_addr_len is set by application. 6524 */ 6525 bool server_addr_len_set; 6526 /** 6527 * Applicaiton-provided the size of the memory pointed by @a server_addr. 6528 */ 6529 socklen_t server_addr_len; 6530 }; 6531 6532 /** 6533 * Signature of the MHD custom logger function. 6534 * 6535 * @param cls closure 6536 * @param format format string 6537 * @param va arguments to the format string (fprintf-style) 6538 */ 6539 typedef void 6540 (*VfprintfFunctionPointerType)(void *cls, 6541 const char *format, 6542 va_list va); 6543 6544 6545 /** 6546 * Parse a list of options given as varargs. 6547 * 6548 * @param daemon the daemon to initialize 6549 * @param servaddr where to store the server's listen address 6550 * @param params the interim parameters to be assigned to 6551 * @param ap the options 6552 * @return #MHD_YES on success, #MHD_NO on error 6553 */ 6554 static enum MHD_Result 6555 parse_options_va (struct MHD_Daemon *daemon, 6556 struct MHD_InterimParams_ *params, 6557 va_list ap); 6558 6559 6560 /** 6561 * Parse a list of options given as varargs. 6562 * 6563 * @param daemon the daemon to initialize 6564 * @param servaddr where to store the server's listen address 6565 * @param params the interim parameters to be assigned to 6566 * @param ... the options 6567 * @return #MHD_YES on success, #MHD_NO on error 6568 */ 6569 static enum MHD_Result 6570 parse_options (struct MHD_Daemon *daemon, 6571 struct MHD_InterimParams_ *params, 6572 ...) 6573 { 6574 va_list ap; 6575 enum MHD_Result ret; 6576 6577 va_start (ap, params); 6578 ret = parse_options_va (daemon, 6579 params, 6580 ap); 6581 va_end (ap); 6582 return ret; 6583 } 6584 6585 6586 #ifdef HTTPS_SUPPORT 6587 /** 6588 * Type of GnuTLS priorities base string 6589 */ 6590 enum MHD_TlsPrioritiesBaseType 6591 { 6592 MHD_TLS_PRIO_BASE_LIBMHD = 0, /**< @c "@LIBMICROHTTPD" */ 6593 MHD_TLS_PRIO_BASE_SYSTEM = 1, /**< @c "@SYSTEM" */ 6594 #if GNUTLS_VERSION_NUMBER >= 0x030300 6595 MHD_TLS_PRIO_BASE_DEFAULT, /**< Default priorities string */ 6596 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */ 6597 MHD_TLS_PRIO_BASE_NORMAL /**< @c "NORMAL */ 6598 }; 6599 6600 static const struct _MHD_cstr_w_len MHD_TlsBasePriotities[] = { 6601 _MHD_S_STR_W_LEN ("@LIBMICROHTTPD"), 6602 _MHD_S_STR_W_LEN ("@SYSTEM"), 6603 #if GNUTLS_VERSION_NUMBER >= 0x030300 6604 {NULL, 0}, 6605 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */ 6606 _MHD_S_STR_W_LEN ("NORMAL") 6607 }; 6608 6609 /** 6610 * Initialise TLS priorities with default settings 6611 * @param daemon the daemon to initialise TLS priorities 6612 * @return true on success, false on error 6613 */ 6614 static bool 6615 daemon_tls_priorities_init_default (struct MHD_Daemon *daemon) 6616 { 6617 unsigned int p; 6618 int res; 6619 6620 mhd_assert (0 != (((unsigned int) daemon->options) & MHD_USE_TLS)); 6621 mhd_assert (NULL == daemon->priority_cache); 6622 mhd_assert (MHD_TLS_PRIO_BASE_NORMAL + 1 == \ 6623 sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0])); 6624 6625 res = GNUTLS_E_SUCCESS; /* Mute compiler warning */ 6626 6627 for (p = 0; 6628 p < sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0]); 6629 ++p) 6630 { 6631 res = gnutls_priority_init (&daemon->priority_cache, 6632 MHD_TlsBasePriotities[p].str, NULL); 6633 if (GNUTLS_E_SUCCESS == res) 6634 { 6635 #ifdef _DEBUG 6636 #ifdef HAVE_MESSAGES 6637 switch ((enum MHD_TlsPrioritiesBaseType) p) 6638 { 6639 case MHD_TLS_PRIO_BASE_LIBMHD: 6640 MHD_DLOG (daemon, 6641 _ ("GnuTLS priorities have been initialised with " \ 6642 "@LIBMICROHTTPD application-specific system-wide " \ 6643 "configuration.\n") ); 6644 break; 6645 case MHD_TLS_PRIO_BASE_SYSTEM: 6646 MHD_DLOG (daemon, 6647 _ ("GnuTLS priorities have been initialised with " \ 6648 "@SYSTEM system-wide configuration.\n") ); 6649 break; 6650 #if GNUTLS_VERSION_NUMBER >= 0x030300 6651 case MHD_TLS_PRIO_BASE_DEFAULT: 6652 MHD_DLOG (daemon, 6653 _ ("GnuTLS priorities have been initialised with " \ 6654 "GnuTLS default configuration.\n") ); 6655 break; 6656 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */ 6657 case MHD_TLS_PRIO_BASE_NORMAL: 6658 MHD_DLOG (daemon, 6659 _ ("GnuTLS priorities have been initialised with " \ 6660 "NORMAL configuration.\n") ); 6661 break; 6662 default: 6663 mhd_assert (0); 6664 } 6665 #endif /* HAVE_MESSAGES */ 6666 #endif /* _DEBUG */ 6667 return true; 6668 } 6669 } 6670 #ifdef HAVE_MESSAGES 6671 MHD_DLOG (daemon, 6672 _ ("Failed to set GnuTLS priorities. Last error: %s\n"), 6673 gnutls_strerror (res)); 6674 #endif /* HAVE_MESSAGES */ 6675 return false; 6676 } 6677 6678 6679 /** 6680 * The inner helper function for #daemon_tls_priorities_init_app(). 6681 * @param daemon the daemon to use 6682 * @param prio the appication-specified appendix for default priorities 6683 * @param prio_len the length of @a prio 6684 * @param buf the temporal buffer for string manipulations 6685 * @param buf_size the size of the @a buf 6686 * @return true on success, false on error 6687 */ 6688 static bool 6689 daemon_tls_priorities_init_append_inner_ (struct MHD_Daemon *daemon, 6690 const char *prio, 6691 size_t prio_len, 6692 char *buf, 6693 const size_t buf_size) 6694 { 6695 unsigned int p; 6696 int res; 6697 const char *err_pos; 6698 6699 (void) buf_size; /* Mute compiler warning for non-Debug builds */ 6700 mhd_assert (0 != (((unsigned int) daemon->options) & MHD_USE_TLS)); 6701 mhd_assert (NULL == daemon->priority_cache); 6702 mhd_assert (MHD_TLS_PRIO_BASE_NORMAL + 1 == \ 6703 sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0])); 6704 6705 res = GNUTLS_E_SUCCESS; /* Mute compiler warning */ 6706 6707 for (p = 0; 6708 p < sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0]); 6709 ++p) 6710 { 6711 6712 #if GNUTLS_VERSION_NUMBER >= 0x030300 6713 #if GNUTLS_VERSION_NUMBER >= 0x030603 6714 if (NULL == MHD_TlsBasePriotities[p].str) 6715 res = gnutls_priority_init2 (&daemon->priority_cache, prio, &err_pos, 6716 GNUTLS_PRIORITY_INIT_DEF_APPEND); 6717 else 6718 #else /* 0x030300 <= GNUTLS_VERSION_NUMBER 6719 && GNUTLS_VERSION_NUMBER < 0x030603 */ 6720 if (NULL == MHD_TlsBasePriotities[p].str) 6721 continue; /* Skip the value, no way to append priorities to the default string */ 6722 else 6723 #endif /* GNUTLS_VERSION_NUMBER < 0x030603 */ 6724 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */ 6725 if (1) 6726 { 6727 size_t buf_pos; 6728 6729 mhd_assert (NULL != MHD_TlsBasePriotities[p].str); 6730 buf_pos = 0; 6731 memcpy (buf + buf_pos, MHD_TlsBasePriotities[p].str, 6732 MHD_TlsBasePriotities[p].len); 6733 buf_pos += MHD_TlsBasePriotities[p].len; 6734 buf[buf_pos++] = ':'; 6735 memcpy (buf + buf_pos, prio, prio_len + 1); 6736 #ifdef _DEBUG 6737 buf_pos += prio_len + 1; 6738 mhd_assert (buf_size >= buf_pos); 6739 #endif /* _DEBUG */ 6740 res = gnutls_priority_init (&daemon->priority_cache, buf, &err_pos); 6741 } 6742 if (GNUTLS_E_SUCCESS == res) 6743 { 6744 #ifdef _DEBUG 6745 #ifdef HAVE_MESSAGES 6746 switch ((enum MHD_TlsPrioritiesBaseType) p) 6747 { 6748 case MHD_TLS_PRIO_BASE_LIBMHD: 6749 MHD_DLOG (daemon, 6750 _ ("GnuTLS priorities have been initialised with " \ 6751 "priorities specified by application appended to " \ 6752 "@LIBMICROHTTPD application-specific system-wide " \ 6753 "configuration.\n") ); 6754 break; 6755 case MHD_TLS_PRIO_BASE_SYSTEM: 6756 MHD_DLOG (daemon, 6757 _ ("GnuTLS priorities have been initialised with " \ 6758 "priorities specified by application appended to " \ 6759 "@SYSTEM system-wide configuration.\n") ); 6760 break; 6761 #if GNUTLS_VERSION_NUMBER >= 0x030300 6762 case MHD_TLS_PRIO_BASE_DEFAULT: 6763 MHD_DLOG (daemon, 6764 _ ("GnuTLS priorities have been initialised with " \ 6765 "priorities specified by application appended to " \ 6766 "GnuTLS default configuration.\n") ); 6767 break; 6768 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */ 6769 case MHD_TLS_PRIO_BASE_NORMAL: 6770 MHD_DLOG (daemon, 6771 _ ("GnuTLS priorities have been initialised with " \ 6772 "priorities specified by application appended to " \ 6773 "NORMAL configuration.\n") ); 6774 break; 6775 default: 6776 mhd_assert (0); 6777 } 6778 #endif /* HAVE_MESSAGES */ 6779 #endif /* _DEBUG */ 6780 return true; 6781 } 6782 } 6783 #ifdef HAVE_MESSAGES 6784 MHD_DLOG (daemon, 6785 _ ("Failed to set GnuTLS priorities. Last error: %s. " \ 6786 "The problematic part starts at: %s\n"), 6787 gnutls_strerror (res), err_pos); 6788 #endif /* HAVE_MESSAGES */ 6789 return false; 6790 } 6791 6792 6793 #define LOCAL_BUFF_SIZE 128 6794 6795 /** 6796 * Initialise TLS priorities with default settings with application-specified 6797 * appended string. 6798 * @param daemon the daemon to initialise TLS priorities 6799 * @param prio the application specified priorities to be appended to 6800 * the GnuTLS standard priorities string 6801 * @return true on success, false on error 6802 */ 6803 static bool 6804 daemon_tls_priorities_init_append (struct MHD_Daemon *daemon, const char *prio) 6805 { 6806 static const size_t longest_base_prio = MHD_STATICSTR_LEN_ ("@LIBMICROHTTPD"); 6807 bool ret; 6808 size_t prio_len; 6809 size_t buf_size_needed; 6810 6811 if (NULL == prio) 6812 return daemon_tls_priorities_init_default (daemon); 6813 6814 if (':' == prio[0]) 6815 ++prio; 6816 6817 prio_len = strlen (prio); 6818 6819 buf_size_needed = longest_base_prio + 1 + prio_len + 1; 6820 6821 if (LOCAL_BUFF_SIZE >= buf_size_needed) 6822 { 6823 char local_buffer[LOCAL_BUFF_SIZE]; 6824 ret = daemon_tls_priorities_init_append_inner_ (daemon, prio, prio_len, 6825 local_buffer, 6826 LOCAL_BUFF_SIZE); 6827 } 6828 else 6829 { 6830 char *allocated_buffer; 6831 allocated_buffer = (char *) malloc (buf_size_needed); 6832 if (NULL == allocated_buffer) 6833 { 6834 #ifdef HAVE_MESSAGES 6835 MHD_DLOG (daemon, 6836 _ ("Error allocating memory: %s\n"), 6837 MHD_strerror_ (errno)); 6838 #endif 6839 return false; 6840 } 6841 ret = daemon_tls_priorities_init_append_inner_ (daemon, prio, prio_len, 6842 allocated_buffer, 6843 buf_size_needed); 6844 free (allocated_buffer); 6845 } 6846 return ret; 6847 } 6848 6849 6850 #endif /* HTTPS_SUPPORT */ 6851 6852 6853 /** 6854 * Parse a list of options given as varargs. 6855 * 6856 * @param[in,out] daemon the daemon to initialize 6857 * @param[out] params the interim parameters to be assigned to 6858 * @param ap the options 6859 * @return #MHD_YES on success, #MHD_NO on error 6860 */ 6861 static enum MHD_Result 6862 parse_options_va (struct MHD_Daemon *daemon, 6863 struct MHD_InterimParams_ *params, 6864 va_list ap) 6865 { 6866 enum MHD_OPTION opt; 6867 struct MHD_OptionItem *oa; 6868 unsigned int i; 6869 unsigned int uv; 6870 #ifdef HTTPS_SUPPORT 6871 const char *pstr; 6872 #if GNUTLS_VERSION_MAJOR >= 3 6873 gnutls_certificate_retrieve_function2 * pgcrf; 6874 #endif 6875 #if GNUTLS_VERSION_NUMBER >= 0x030603 6876 gnutls_certificate_retrieve_function3 * pgcrf2; 6877 #endif 6878 #endif /* HTTPS_SUPPORT */ 6879 6880 while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int))) 6881 { 6882 /* Increase counter at start, so resulting value is number of 6883 * processed options, including any failed ones. */ 6884 params->num_opts++; 6885 switch (opt) 6886 { 6887 case MHD_OPTION_CONNECTION_MEMORY_LIMIT: 6888 if (1) 6889 { 6890 size_t val; 6891 6892 val = va_arg (ap, 6893 size_t); 6894 if (0 != val) 6895 { 6896 daemon->pool_size = val; 6897 if (64 > daemon->pool_size) 6898 { 6899 #ifdef HAVE_MESSAGES 6900 MHD_DLOG (daemon, 6901 _ ("Warning: specified " \ 6902 "MHD_OPTION_CONNECTION_MEMORY_LIMIT " \ 6903 "value is too small and rounded up to 64.\n")); 6904 #endif /* HAVE_MESSAGES */ 6905 daemon->pool_size = 64; 6906 } 6907 if (daemon->pool_size / 4 < daemon->pool_increment) 6908 daemon->pool_increment = daemon->pool_size / 4; 6909 } 6910 } 6911 break; 6912 case MHD_OPTION_CONNECTION_MEMORY_INCREMENT: 6913 if (1) 6914 { 6915 size_t val; 6916 6917 val = va_arg (ap, 6918 size_t); 6919 6920 if (0 != val) 6921 { 6922 daemon->pool_increment = val; 6923 if (daemon->pool_size / 4 < daemon->pool_increment) 6924 { 6925 #ifdef HAVE_MESSAGES 6926 MHD_DLOG (daemon, 6927 _ ("Warning: specified " \ 6928 "MHD_OPTION_CONNECTION_MEMORY_INCREMENT value is " \ 6929 "too large and rounded down to 1/4 of " \ 6930 "MHD_OPTION_CONNECTION_MEMORY_LIMIT.\n")); 6931 #endif /* HAVE_MESSAGES */ 6932 daemon->pool_increment = daemon->pool_size / 4; 6933 } 6934 } 6935 } 6936 break; 6937 case MHD_OPTION_CONNECTION_LIMIT: 6938 daemon->connection_limit = va_arg (ap, 6939 unsigned int); 6940 break; 6941 case MHD_OPTION_CONNECTION_TIMEOUT: 6942 uv = va_arg (ap, 6943 unsigned int); 6944 #if (SIZEOF_UINT64_T - 2) <= SIZEOF_UNSIGNED_INT 6945 if ((UINT64_MAX / 4000 - 1) < uv) 6946 { 6947 #ifdef HAVE_MESSAGES 6948 MHD_DLOG (daemon, 6949 _ ("The specified connection timeout (%u) is too large. " \ 6950 "Maximum allowed value (%" PRIu64 ") will be used " \ 6951 "instead.\n"), 6952 uv, 6953 (UINT64_MAX / 4000 - 1)); 6954 #endif 6955 uv = UINT64_MAX / 4000 - 1; 6956 } 6957 #endif /* (SIZEOF_UINT64_T - 2) <= SIZEOF_UNSIGNED_INT */ 6958 daemon->connection_timeout_ms = ((uint64_t) uv) * 1000; 6959 break; 6960 case MHD_OPTION_NOTIFY_COMPLETED: 6961 daemon->notify_completed = va_arg (ap, 6962 MHD_RequestCompletedCallback); 6963 daemon->notify_completed_cls = va_arg (ap, 6964 void *); 6965 break; 6966 case MHD_OPTION_NOTIFY_CONNECTION: 6967 daemon->notify_connection = va_arg (ap, 6968 MHD_NotifyConnectionCallback); 6969 daemon->notify_connection_cls = va_arg (ap, 6970 void *); 6971 break; 6972 case MHD_OPTION_PER_IP_CONNECTION_LIMIT: 6973 daemon->per_ip_connection_limit = va_arg (ap, 6974 unsigned int); 6975 break; 6976 case MHD_OPTION_SOCK_ADDR_LEN: 6977 params->server_addr_len = va_arg (ap, 6978 socklen_t); 6979 params->server_addr_len_set = true; 6980 params->pserver_addr = va_arg (ap, 6981 const struct sockaddr *); 6982 params->pserver_addr_set = true; 6983 break; 6984 case MHD_OPTION_SOCK_ADDR: 6985 params->server_addr_len_set = false; 6986 params->pserver_addr = va_arg (ap, 6987 const struct sockaddr *); 6988 params->pserver_addr_set = true; 6989 break; 6990 case MHD_OPTION_URI_LOG_CALLBACK: 6991 daemon->uri_log_callback = va_arg (ap, 6992 LogCallback); 6993 daemon->uri_log_callback_cls = va_arg (ap, 6994 void *); 6995 break; 6996 case MHD_OPTION_SERVER_INSANITY: 6997 daemon->insanity_level = (enum MHD_DisableSanityCheck) 6998 va_arg (ap, 6999 unsigned int); 7000 break; 7001 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 7002 case MHD_OPTION_THREAD_POOL_SIZE: 7003 daemon->worker_pool_size = va_arg (ap, 7004 unsigned int); 7005 if (0 == daemon->worker_pool_size) 7006 { 7007 (void) 0; /* MHD_OPTION_THREAD_POOL_SIZE ignored, do nothing */ 7008 } 7009 else if (1 == daemon->worker_pool_size) 7010 { 7011 #ifdef HAVE_MESSAGES 7012 MHD_DLOG (daemon, 7013 _ ("Warning: value \"1\", specified as the thread pool " \ 7014 "size, is ignored. Thread pool is not used.\n")); 7015 #endif 7016 daemon->worker_pool_size = 0; 7017 } 7018 #if SIZEOF_UNSIGNED_INT >= (SIZEOF_SIZE_T - 2) 7019 /* Next comparison could be always false on some platforms and whole branch will 7020 * be optimized out on these platforms. On others it will be compiled into real 7021 * check. */ 7022 else if (daemon->worker_pool_size >= 7023 (SIZE_MAX / sizeof (struct MHD_Daemon))) /* Compiler may warn on some platforms, ignore warning. */ 7024 { 7025 #ifdef HAVE_MESSAGES 7026 MHD_DLOG (daemon, 7027 _ ("Specified thread pool size (%u) too big.\n"), 7028 daemon->worker_pool_size); 7029 #endif 7030 return MHD_NO; 7031 } 7032 #endif /* SIZEOF_UNSIGNED_INT >= (SIZEOF_SIZE_T - 2) */ 7033 else 7034 { 7035 if (! MHD_D_IS_USING_THREADS_ (daemon)) 7036 { 7037 #ifdef HAVE_MESSAGES 7038 MHD_DLOG (daemon, 7039 _ ("MHD_OPTION_THREAD_POOL_SIZE option is specified but " 7040 "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n")); 7041 #endif 7042 return MHD_NO; 7043 } 7044 if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) 7045 { 7046 #ifdef HAVE_MESSAGES 7047 MHD_DLOG (daemon, 7048 _ ("Both MHD_OPTION_THREAD_POOL_SIZE option and " 7049 "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n")); 7050 #endif 7051 return MHD_NO; 7052 } 7053 } 7054 break; 7055 #endif 7056 #ifdef HTTPS_SUPPORT 7057 case MHD_OPTION_HTTPS_MEM_KEY: 7058 pstr = va_arg (ap, 7059 const char *); 7060 if (0 != (daemon->options & MHD_USE_TLS)) 7061 daemon->https_mem_key = pstr; 7062 #ifdef HAVE_MESSAGES 7063 else 7064 MHD_DLOG (daemon, 7065 _ ("MHD HTTPS option %d passed to MHD but " \ 7066 "MHD_USE_TLS not set.\n"), 7067 opt); 7068 #endif 7069 break; 7070 case MHD_OPTION_HTTPS_KEY_PASSWORD: 7071 pstr = va_arg (ap, 7072 const char *); 7073 if (0 != (daemon->options & MHD_USE_TLS)) 7074 daemon->https_key_password = pstr; 7075 #ifdef HAVE_MESSAGES 7076 else 7077 MHD_DLOG (daemon, 7078 _ ("MHD HTTPS option %d passed to MHD but " \ 7079 "MHD_USE_TLS not set.\n"), 7080 opt); 7081 #endif 7082 break; 7083 case MHD_OPTION_HTTPS_MEM_CERT: 7084 pstr = va_arg (ap, 7085 const char *); 7086 if (0 != (daemon->options & MHD_USE_TLS)) 7087 daemon->https_mem_cert = pstr; 7088 #ifdef HAVE_MESSAGES 7089 else 7090 MHD_DLOG (daemon, 7091 _ ("MHD HTTPS option %d passed to MHD but " \ 7092 "MHD_USE_TLS not set.\n"), 7093 opt); 7094 #endif 7095 break; 7096 case MHD_OPTION_HTTPS_MEM_TRUST: 7097 pstr = va_arg (ap, 7098 const char *); 7099 if (0 != (daemon->options & MHD_USE_TLS)) 7100 daemon->https_mem_trust = pstr; 7101 #ifdef HAVE_MESSAGES 7102 else 7103 MHD_DLOG (daemon, 7104 _ ("MHD HTTPS option %d passed to MHD but " \ 7105 "MHD_USE_TLS not set.\n"), 7106 opt); 7107 #endif 7108 break; 7109 case MHD_OPTION_HTTPS_CRED_TYPE: 7110 daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap, 7111 int); 7112 break; 7113 case MHD_OPTION_HTTPS_MEM_DHPARAMS: 7114 pstr = va_arg (ap, 7115 const char *); 7116 if (0 != (daemon->options & MHD_USE_TLS)) 7117 { 7118 gnutls_datum_t dhpar; 7119 size_t pstr_len; 7120 7121 if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0) 7122 { 7123 #ifdef HAVE_MESSAGES 7124 MHD_DLOG (daemon, 7125 _ ("Error initializing DH parameters.\n")); 7126 #endif 7127 return MHD_NO; 7128 } 7129 dhpar.data = (unsigned char *) _MHD_DROP_CONST (pstr); 7130 pstr_len = strlen (pstr); 7131 if (UINT_MAX < pstr_len) 7132 { 7133 #ifdef HAVE_MESSAGES 7134 MHD_DLOG (daemon, 7135 _ ("Diffie-Hellman parameters string too long.\n")); 7136 #endif 7137 return MHD_NO; 7138 } 7139 dhpar.size = (unsigned int) pstr_len; 7140 if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams, 7141 &dhpar, 7142 GNUTLS_X509_FMT_PEM) < 0) 7143 { 7144 #ifdef HAVE_MESSAGES 7145 MHD_DLOG (daemon, 7146 _ ("Bad Diffie-Hellman parameters format.\n")); 7147 #endif 7148 gnutls_dh_params_deinit (daemon->https_mem_dhparams); 7149 return MHD_NO; 7150 } 7151 daemon->have_dhparams = true; 7152 } 7153 #ifdef HAVE_MESSAGES 7154 else 7155 MHD_DLOG (daemon, 7156 _ ("MHD HTTPS option %d passed to MHD but " \ 7157 "MHD_USE_TLS not set.\n"), 7158 opt); 7159 #endif 7160 break; 7161 case MHD_OPTION_HTTPS_PRIORITIES: 7162 case MHD_OPTION_HTTPS_PRIORITIES_APPEND: 7163 pstr = va_arg (ap, 7164 const char *); 7165 if (0 != (daemon->options & MHD_USE_TLS)) 7166 { 7167 if (NULL != daemon->priority_cache) 7168 gnutls_priority_deinit (daemon->priority_cache); 7169 7170 if (MHD_OPTION_HTTPS_PRIORITIES == opt) 7171 { 7172 int init_res; 7173 const char *err_pos; 7174 init_res = gnutls_priority_init (&daemon->priority_cache, 7175 pstr, 7176 &err_pos); 7177 if (GNUTLS_E_SUCCESS != init_res) 7178 { 7179 #ifdef HAVE_MESSAGES 7180 MHD_DLOG (daemon, 7181 _ ("Setting priorities to '%s' failed: %s " \ 7182 "The problematic part starts at: %s\n"), 7183 pstr, 7184 gnutls_strerror (init_res), 7185 err_pos); 7186 #endif 7187 daemon->priority_cache = NULL; 7188 return MHD_NO; 7189 } 7190 } 7191 else 7192 { 7193 /* The cache has been deinited */ 7194 daemon->priority_cache = NULL; 7195 if (! daemon_tls_priorities_init_append (daemon, pstr)) 7196 return MHD_NO; 7197 } 7198 } 7199 #ifdef HAVE_MESSAGES 7200 else 7201 MHD_DLOG (daemon, 7202 _ ("MHD HTTPS option %d passed to MHD but " \ 7203 "MHD_USE_TLS not set.\n"), 7204 opt); 7205 #endif 7206 break; 7207 case MHD_OPTION_HTTPS_CERT_CALLBACK: 7208 #if GNUTLS_VERSION_MAJOR < 3 7209 #ifdef HAVE_MESSAGES 7210 MHD_DLOG (daemon, 7211 _ ("MHD_OPTION_HTTPS_CERT_CALLBACK requires building " \ 7212 "MHD with GnuTLS >= 3.0.\n")); 7213 #endif 7214 return MHD_NO; 7215 #else 7216 pgcrf = va_arg (ap, 7217 gnutls_certificate_retrieve_function2 *); 7218 if (0 != (daemon->options & MHD_USE_TLS)) 7219 daemon->cert_callback = pgcrf; 7220 #ifdef HAVE_MESSAGES 7221 else 7222 MHD_DLOG (daemon, 7223 _ ("MHD HTTPS option %d passed to MHD but " \ 7224 "MHD_USE_TLS not set.\n"), 7225 opt); 7226 #endif /* HAVE_MESSAGES */ 7227 break; 7228 #endif 7229 case MHD_OPTION_HTTPS_CERT_CALLBACK2: 7230 #if GNUTLS_VERSION_NUMBER < 0x030603 7231 #ifdef HAVE_MESSAGES 7232 MHD_DLOG (daemon, 7233 _ ("MHD_OPTION_HTTPS_CERT_CALLBACK2 requires building " \ 7234 "MHD with GnuTLS >= 3.6.3.\n")); 7235 #endif 7236 return MHD_NO; 7237 #else 7238 pgcrf2 = va_arg (ap, 7239 gnutls_certificate_retrieve_function3 *); 7240 if (0 != (daemon->options & MHD_USE_TLS)) 7241 daemon->cert_callback2 = pgcrf2; 7242 #ifdef HAVE_MESSAGES 7243 else 7244 MHD_DLOG (daemon, 7245 _ ("MHD HTTPS option %d passed to MHD but " \ 7246 "MHD_USE_TLS not set.\n"), 7247 opt); 7248 #endif /* HAVE_MESSAGES */ 7249 break; 7250 #endif 7251 #endif /* HTTPS_SUPPORT */ 7252 #ifdef DAUTH_SUPPORT 7253 case MHD_OPTION_DIGEST_AUTH_RANDOM: 7254 case MHD_OPTION_DIGEST_AUTH_RANDOM_COPY: 7255 daemon->digest_auth_rand_size = va_arg (ap, 7256 size_t); 7257 daemon->digest_auth_random = va_arg (ap, 7258 const char *); 7259 if (MHD_OPTION_DIGEST_AUTH_RANDOM_COPY == opt) 7260 /* Set to some non-NULL value just to indicate that copy is required. */ 7261 daemon->digest_auth_random_copy = daemon; 7262 else 7263 daemon->digest_auth_random_copy = NULL; 7264 break; 7265 case MHD_OPTION_NONCE_NC_SIZE: 7266 daemon->nonce_nc_size = va_arg (ap, 7267 unsigned int); 7268 break; 7269 case MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE: 7270 daemon->dauth_bind_type = va_arg (ap, 7271 unsigned int); 7272 if (0 != (daemon->dauth_bind_type & MHD_DAUTH_BIND_NONCE_URI_PARAMS)) 7273 daemon->dauth_bind_type |= MHD_DAUTH_BIND_NONCE_URI; 7274 break; 7275 case MHD_OPTION_DIGEST_AUTH_DEFAULT_NONCE_TIMEOUT: 7276 if (1) 7277 { 7278 unsigned int val; 7279 val = va_arg (ap, 7280 unsigned int); 7281 if (0 != val) 7282 daemon->dauth_def_nonce_timeout = val; 7283 } 7284 break; 7285 case MHD_OPTION_DIGEST_AUTH_DEFAULT_MAX_NC: 7286 if (1) 7287 { 7288 uint32_t val; 7289 val = va_arg (ap, 7290 uint32_t); 7291 if (0 != val) 7292 daemon->dauth_def_max_nc = val; 7293 } 7294 break; 7295 #else /* ! DAUTH_SUPPORT */ 7296 case MHD_OPTION_DIGEST_AUTH_RANDOM: 7297 case MHD_OPTION_DIGEST_AUTH_RANDOM_COPY: 7298 case MHD_OPTION_NONCE_NC_SIZE: 7299 case MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE: 7300 case MHD_OPTION_DIGEST_AUTH_DEFAULT_NONCE_TIMEOUT: 7301 case MHD_OPTION_DIGEST_AUTH_DEFAULT_MAX_NC: 7302 #ifdef HAVE_MESSAGES 7303 MHD_DLOG (daemon, 7304 _ ("Digest Auth is disabled for this build " \ 7305 "of GNU libmicrohttpd.\n")); 7306 #endif /* HAVE_MESSAGES */ 7307 return MHD_NO; 7308 #endif /* ! DAUTH_SUPPORT */ 7309 case MHD_OPTION_LISTEN_SOCKET: 7310 params->listen_fd = va_arg (ap, 7311 MHD_socket); 7312 params->listen_fd_set = true; 7313 break; 7314 case MHD_OPTION_EXTERNAL_LOGGER: 7315 #ifdef HAVE_MESSAGES 7316 daemon->custom_error_log = va_arg (ap, 7317 VfprintfFunctionPointerType); 7318 daemon->custom_error_log_cls = va_arg (ap, 7319 void *); 7320 if (1 != params->num_opts) 7321 MHD_DLOG (daemon, 7322 _ ("MHD_OPTION_EXTERNAL_LOGGER is not the first option " 7323 "specified for the daemon. Some messages may be " 7324 "printed by the standard MHD logger.\n")); 7325 7326 #else 7327 (void) va_arg (ap, 7328 VfprintfFunctionPointerType); 7329 (void) va_arg (ap, 7330 void *); 7331 #endif 7332 break; 7333 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 7334 case MHD_OPTION_THREAD_STACK_SIZE: 7335 daemon->thread_stack_size = va_arg (ap, 7336 size_t); 7337 break; 7338 #endif 7339 case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE: 7340 #ifdef TCP_FASTOPEN 7341 daemon->fastopen_queue_size = va_arg (ap, 7342 unsigned int); 7343 break; 7344 #else /* ! TCP_FASTOPEN */ 7345 #ifdef HAVE_MESSAGES 7346 MHD_DLOG (daemon, 7347 _ ("TCP fastopen is not supported on this platform.\n")); 7348 #endif /* HAVE_MESSAGES */ 7349 return MHD_NO; 7350 #endif /* ! TCP_FASTOPEN */ 7351 case MHD_OPTION_LISTENING_ADDRESS_REUSE: 7352 daemon->listening_address_reuse = va_arg (ap, 7353 unsigned int) ? 1 : -1; 7354 break; 7355 case MHD_OPTION_LISTEN_BACKLOG_SIZE: 7356 daemon->listen_backlog_size = va_arg (ap, 7357 unsigned int); 7358 break; 7359 case MHD_OPTION_STRICT_FOR_CLIENT: 7360 daemon->client_discipline = va_arg (ap, int); /* Temporal assignment */ 7361 /* Map to correct value */ 7362 if (-1 >= daemon->client_discipline) 7363 daemon->client_discipline = -3; 7364 else if (1 <= daemon->client_discipline) 7365 daemon->client_discipline = 1; 7366 #ifdef HAVE_MESSAGES 7367 if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) && 7368 (1 != daemon->client_discipline) ) 7369 { 7370 MHD_DLOG (daemon, 7371 _ ("Flag MHD_USE_PEDANTIC_CHECKS is ignored because " 7372 "another behaviour is specified by " 7373 "MHD_OPTION_STRICT_CLIENT.\n")); 7374 } 7375 #endif /* HAVE_MESSAGES */ 7376 break; 7377 case MHD_OPTION_CLIENT_DISCIPLINE_LVL: 7378 daemon->client_discipline = va_arg (ap, int); 7379 #ifdef HAVE_MESSAGES 7380 if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) && 7381 (1 != daemon->client_discipline) ) 7382 { 7383 MHD_DLOG (daemon, 7384 _ ("Flag MHD_USE_PEDANTIC_CHECKS is ignored because " 7385 "another behaviour is specified by " 7386 "MHD_OPTION_CLIENT_DISCIPLINE_LVL.\n")); 7387 } 7388 #endif /* HAVE_MESSAGES */ 7389 break; 7390 case MHD_OPTION_ALLOW_BIN_ZERO_IN_URI_PATH: 7391 daemon->allow_bzero_in_url = va_arg (ap, int); 7392 if ((0 > daemon->allow_bzero_in_url) || 7393 (2 < daemon->allow_bzero_in_url)) 7394 daemon->allow_bzero_in_url = 1; 7395 break; 7396 case MHD_OPTION_ARRAY: 7397 params->num_opts--; /* Do not count MHD_OPTION_ARRAY */ 7398 oa = va_arg (ap, struct MHD_OptionItem *); 7399 i = 0; 7400 while (MHD_OPTION_END != (opt = oa[i].option)) 7401 { 7402 switch (opt) 7403 { 7404 /* all options taking 'size_t' */ 7405 case MHD_OPTION_CONNECTION_MEMORY_LIMIT: 7406 case MHD_OPTION_CONNECTION_MEMORY_INCREMENT: 7407 case MHD_OPTION_THREAD_STACK_SIZE: 7408 if (MHD_NO == parse_options (daemon, 7409 params, 7410 opt, 7411 (size_t) oa[i].value, 7412 MHD_OPTION_END)) 7413 return MHD_NO; 7414 break; 7415 /* all options taking 'unsigned int' */ 7416 case MHD_OPTION_NONCE_NC_SIZE: 7417 case MHD_OPTION_CONNECTION_LIMIT: 7418 case MHD_OPTION_CONNECTION_TIMEOUT: 7419 case MHD_OPTION_PER_IP_CONNECTION_LIMIT: 7420 case MHD_OPTION_THREAD_POOL_SIZE: 7421 case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE: 7422 case MHD_OPTION_LISTENING_ADDRESS_REUSE: 7423 case MHD_OPTION_LISTEN_BACKLOG_SIZE: 7424 case MHD_OPTION_SERVER_INSANITY: 7425 case MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE: 7426 case MHD_OPTION_DIGEST_AUTH_DEFAULT_NONCE_TIMEOUT: 7427 if (MHD_NO == parse_options (daemon, 7428 params, 7429 opt, 7430 (unsigned int) oa[i].value, 7431 MHD_OPTION_END)) 7432 return MHD_NO; 7433 break; 7434 /* all options taking 'enum' */ 7435 case MHD_OPTION_HTTPS_CRED_TYPE: 7436 #ifdef HTTPS_SUPPORT 7437 if (MHD_NO == parse_options (daemon, 7438 params, 7439 opt, 7440 (gnutls_credentials_type_t) oa[i].value, 7441 MHD_OPTION_END)) 7442 #endif /* HTTPS_SUPPORT */ 7443 return MHD_NO; 7444 break; 7445 /* all options taking 'MHD_socket' */ 7446 case MHD_OPTION_LISTEN_SOCKET: 7447 if (MHD_NO == parse_options (daemon, 7448 params, 7449 opt, 7450 (MHD_socket) oa[i].value, 7451 MHD_OPTION_END)) 7452 return MHD_NO; 7453 break; 7454 /* all options taking 'int' */ 7455 case MHD_OPTION_STRICT_FOR_CLIENT: 7456 case MHD_OPTION_CLIENT_DISCIPLINE_LVL: 7457 case MHD_OPTION_SIGPIPE_HANDLED_BY_APP: 7458 case MHD_OPTION_TLS_NO_ALPN: 7459 case MHD_OPTION_APP_FD_SETSIZE: 7460 case MHD_OPTION_ALLOW_BIN_ZERO_IN_URI_PATH: 7461 if (MHD_NO == parse_options (daemon, 7462 params, 7463 opt, 7464 (int) oa[i].value, 7465 MHD_OPTION_END)) 7466 return MHD_NO; 7467 break; 7468 /* all options taking 'uint32_t' */ 7469 case MHD_OPTION_DIGEST_AUTH_DEFAULT_MAX_NC: 7470 if (MHD_NO == parse_options (daemon, 7471 params, 7472 opt, 7473 (uint32_t) oa[i].value, 7474 MHD_OPTION_END)) 7475 return MHD_NO; 7476 break; 7477 /* all options taking one pointer */ 7478 case MHD_OPTION_SOCK_ADDR: 7479 case MHD_OPTION_HTTPS_MEM_KEY: 7480 case MHD_OPTION_HTTPS_KEY_PASSWORD: 7481 case MHD_OPTION_HTTPS_MEM_CERT: 7482 case MHD_OPTION_HTTPS_MEM_TRUST: 7483 case MHD_OPTION_HTTPS_MEM_DHPARAMS: 7484 case MHD_OPTION_HTTPS_PRIORITIES: 7485 case MHD_OPTION_HTTPS_PRIORITIES_APPEND: 7486 case MHD_OPTION_ARRAY: 7487 case MHD_OPTION_HTTPS_CERT_CALLBACK: 7488 case MHD_OPTION_HTTPS_CERT_CALLBACK2: 7489 if (MHD_NO == parse_options (daemon, 7490 params, 7491 opt, 7492 oa[i].ptr_value, 7493 MHD_OPTION_END)) 7494 return MHD_NO; 7495 break; 7496 /* all options taking two pointers */ 7497 case MHD_OPTION_NOTIFY_COMPLETED: 7498 case MHD_OPTION_NOTIFY_CONNECTION: 7499 case MHD_OPTION_URI_LOG_CALLBACK: 7500 case MHD_OPTION_EXTERNAL_LOGGER: 7501 case MHD_OPTION_UNESCAPE_CALLBACK: 7502 case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER: 7503 if (MHD_NO == parse_options (daemon, 7504 params, 7505 opt, 7506 (void *) oa[i].value, 7507 oa[i].ptr_value, 7508 MHD_OPTION_END)) 7509 return MHD_NO; 7510 break; 7511 /* options taking size_t-number followed by pointer */ 7512 case MHD_OPTION_DIGEST_AUTH_RANDOM: 7513 case MHD_OPTION_DIGEST_AUTH_RANDOM_COPY: 7514 if (MHD_NO == parse_options (daemon, 7515 params, 7516 opt, 7517 (size_t) oa[i].value, 7518 oa[i].ptr_value, 7519 MHD_OPTION_END)) 7520 return MHD_NO; 7521 break; 7522 /* options taking socklen_t-number followed by pointer */ 7523 case MHD_OPTION_SOCK_ADDR_LEN: 7524 if (MHD_NO == parse_options (daemon, 7525 params, 7526 opt, 7527 (socklen_t) oa[i].value, 7528 oa[i].ptr_value, 7529 MHD_OPTION_END)) 7530 return MHD_NO; 7531 break; 7532 case MHD_OPTION_END: /* Not possible */ 7533 default: 7534 return MHD_NO; 7535 } 7536 i++; 7537 } 7538 break; 7539 case MHD_OPTION_UNESCAPE_CALLBACK: 7540 daemon->unescape_callback = va_arg (ap, 7541 UnescapeCallback); 7542 daemon->unescape_callback_cls = va_arg (ap, 7543 void *); 7544 break; 7545 #ifdef HTTPS_SUPPORT 7546 case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER: 7547 #if GNUTLS_VERSION_MAJOR >= 3 7548 daemon->cred_callback = va_arg (ap, 7549 MHD_PskServerCredentialsCallback); 7550 daemon->cred_callback_cls = va_arg (ap, 7551 void *); 7552 break; 7553 #else 7554 MHD_DLOG (daemon, 7555 _ ("MHD HTTPS option %d passed to MHD compiled " \ 7556 "without GNUtls >= 3.\n"), 7557 opt); 7558 return MHD_NO; 7559 #endif 7560 #endif /* HTTPS_SUPPORT */ 7561 case MHD_OPTION_SIGPIPE_HANDLED_BY_APP: 7562 if (! MHD_D_IS_USING_THREADS_ (daemon)) 7563 daemon->sigpipe_blocked = ( (va_arg (ap, 7564 int)) != 0); 7565 else 7566 { 7567 (void) va_arg (ap, 7568 int); 7569 } 7570 break; 7571 case MHD_OPTION_TLS_NO_ALPN: 7572 #ifdef HTTPS_SUPPORT 7573 daemon->disable_alpn = (va_arg (ap, 7574 int) != 0); 7575 #else /* ! HTTPS_SUPPORT */ 7576 (void) va_arg (ap, int); 7577 #endif /* ! HTTPS_SUPPORT */ 7578 #ifdef HAVE_MESSAGES 7579 if (0 == (daemon->options & MHD_USE_TLS)) 7580 MHD_DLOG (daemon, 7581 _ ("MHD HTTPS option %d passed to MHD " \ 7582 "but MHD_USE_TLS not set.\n"), 7583 (int) opt); 7584 #endif /* HAVE_MESSAGES */ 7585 break; 7586 case MHD_OPTION_APP_FD_SETSIZE: 7587 params->fdset_size_set = true; 7588 params->fdset_size = va_arg (ap, 7589 int); 7590 break; 7591 #ifndef HTTPS_SUPPORT 7592 case MHD_OPTION_HTTPS_MEM_KEY: 7593 case MHD_OPTION_HTTPS_MEM_CERT: 7594 case MHD_OPTION_HTTPS_CRED_TYPE: 7595 case MHD_OPTION_HTTPS_PRIORITIES: 7596 case MHD_OPTION_HTTPS_PRIORITIES_APPEND: 7597 case MHD_OPTION_HTTPS_MEM_TRUST: 7598 case MHD_OPTION_HTTPS_CERT_CALLBACK: 7599 case MHD_OPTION_HTTPS_MEM_DHPARAMS: 7600 case MHD_OPTION_HTTPS_KEY_PASSWORD: 7601 case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER: 7602 case MHD_OPTION_HTTPS_CERT_CALLBACK2: 7603 #ifdef HAVE_MESSAGES 7604 MHD_DLOG (daemon, 7605 _ ("MHD HTTPS option %d passed to MHD " 7606 "compiled without HTTPS support.\n"), 7607 opt); 7608 #endif 7609 return MHD_NO; 7610 #endif /* HTTPS_SUPPORT */ 7611 case MHD_OPTION_END: /* Not possible */ 7612 default: 7613 #ifdef HAVE_MESSAGES 7614 MHD_DLOG (daemon, 7615 _ ("Invalid option %d! (Did you terminate " 7616 "the list with MHD_OPTION_END?).\n"), 7617 opt); 7618 #endif 7619 return MHD_NO; 7620 } 7621 } 7622 return MHD_YES; 7623 } 7624 7625 7626 #ifdef EPOLL_SUPPORT 7627 static int 7628 setup_epoll_fd (struct MHD_Daemon *daemon) 7629 { 7630 int fd; 7631 7632 #ifndef HAVE_MESSAGES 7633 (void) daemon; /* Mute compiler warning. */ 7634 #endif /* ! HAVE_MESSAGES */ 7635 7636 #ifdef USE_EPOLL_CREATE1 7637 fd = epoll_create1 (EPOLL_CLOEXEC); 7638 #else /* ! USE_EPOLL_CREATE1 */ 7639 fd = epoll_create (MAX_EVENTS); 7640 #endif /* ! USE_EPOLL_CREATE1 */ 7641 if (MHD_INVALID_SOCKET == fd) 7642 { 7643 #ifdef HAVE_MESSAGES 7644 MHD_DLOG (daemon, 7645 _ ("Call to epoll_create1 failed: %s\n"), 7646 MHD_socket_last_strerr_ ()); 7647 #endif 7648 return MHD_INVALID_SOCKET; 7649 } 7650 #if ! defined(USE_EPOLL_CREATE1) 7651 if (! MHD_socket_noninheritable_ (fd)) 7652 { 7653 #ifdef HAVE_MESSAGES 7654 MHD_DLOG (daemon, 7655 _ ("Failed to set noninheritable mode on epoll FD.\n")); 7656 #endif 7657 } 7658 #endif /* ! USE_EPOLL_CREATE1 */ 7659 return fd; 7660 } 7661 7662 7663 /** 7664 * Setup epoll() FD for the daemon and initialize it to listen 7665 * on the listen FD. 7666 * @remark To be called only from MHD_start_daemon_va() 7667 * 7668 * @param daemon daemon to initialize for epoll() 7669 * @return #MHD_YES on success, #MHD_NO on failure 7670 */ 7671 static enum MHD_Result 7672 setup_epoll_to_listen (struct MHD_Daemon *daemon) 7673 { 7674 struct epoll_event event; 7675 MHD_socket ls; 7676 7677 mhd_assert (MHD_D_IS_USING_EPOLL_ (daemon)); 7678 mhd_assert (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)); 7679 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 7680 (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) || \ 7681 MHD_ITC_IS_VALID_ (daemon->itc) ); 7682 daemon->epoll_fd = setup_epoll_fd (daemon); 7683 if (! MHD_D_IS_USING_THREADS_ (daemon) 7684 && (0 != (daemon->options & MHD_USE_AUTO))) 7685 { 7686 /* Application requested "MHD_USE_AUTO", probably MHD_get_fdset() will be 7687 used. 7688 Make sure that epoll FD is suitable for fd_set. 7689 Actually, MHD_get_fdset() is allowed for MHD_USE_EPOLL direct, 7690 but most probably direct requirement for MHD_USE_EPOLL means that 7691 epoll FD will be used directly. This logic is fuzzy, but better 7692 than nothing with current MHD API. */ 7693 if (! MHD_D_DOES_SCKT_FIT_FDSET_ (daemon->epoll_fd, daemon)) 7694 { 7695 #ifdef HAVE_MESSAGES 7696 MHD_DLOG (daemon, 7697 _ ("The epoll FD is too large to be used with fd_set.\n")); 7698 #endif /* HAVE_MESSAGES */ 7699 return MHD_NO; 7700 } 7701 } 7702 if (-1 == daemon->epoll_fd) 7703 return MHD_NO; 7704 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 7705 if (0 != (MHD_ALLOW_UPGRADE & daemon->options)) 7706 { 7707 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon); 7708 if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd) 7709 return MHD_NO; 7710 } 7711 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 7712 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && 7713 (! daemon->was_quiesced) ) 7714 { 7715 event.events = EPOLLIN | EPOLLRDHUP; 7716 event.data.ptr = daemon; 7717 if (0 != epoll_ctl (daemon->epoll_fd, 7718 EPOLL_CTL_ADD, 7719 ls, 7720 &event)) 7721 { 7722 #ifdef HAVE_MESSAGES 7723 MHD_DLOG (daemon, 7724 _ ("Call to epoll_ctl failed: %s\n"), 7725 MHD_socket_last_strerr_ ()); 7726 #endif 7727 return MHD_NO; 7728 } 7729 daemon->listen_socket_in_epoll = true; 7730 } 7731 7732 if (MHD_ITC_IS_VALID_ (daemon->itc)) 7733 { 7734 event.events = EPOLLIN | EPOLLRDHUP; 7735 event.data.ptr = _MHD_DROP_CONST (epoll_itc_marker); 7736 if (0 != epoll_ctl (daemon->epoll_fd, 7737 EPOLL_CTL_ADD, 7738 MHD_itc_r_fd_ (daemon->itc), 7739 &event)) 7740 { 7741 #ifdef HAVE_MESSAGES 7742 MHD_DLOG (daemon, 7743 _ ("Call to epoll_ctl failed: %s\n"), 7744 MHD_socket_last_strerr_ ()); 7745 #endif 7746 return MHD_NO; 7747 } 7748 } 7749 return MHD_YES; 7750 } 7751 7752 7753 #endif 7754 7755 7756 /** 7757 * Apply interim parameters 7758 * @param[in,out] d the daemon to use 7759 * @param[out] ppsockaddr the pointer to store the pointer to 'struct sockaddr' 7760 * if provided by application 7761 * @param[out] psockaddr_len the size memory area pointed by 'struct sockaddr' 7762 * if provided by application 7763 * @param[in,out] params the interim parameters to process 7764 * @return true in case of success, 7765 * false in case of critical error (the daemon must be closed). 7766 */ 7767 static bool 7768 process_interim_params (struct MHD_Daemon *d, 7769 const struct sockaddr **ppsockaddr, 7770 socklen_t *psockaddr_len, 7771 struct MHD_InterimParams_ *params) 7772 { 7773 if (params->fdset_size_set) 7774 { 7775 if (0 >= params->fdset_size) 7776 { 7777 #ifdef HAVE_MESSAGES 7778 MHD_DLOG (d, 7779 _ ("MHD_OPTION_APP_FD_SETSIZE value (%d) is not positive.\n"), 7780 params->fdset_size); 7781 #endif /* HAVE_MESSAGES */ 7782 return false; 7783 } 7784 if (MHD_D_IS_USING_THREADS_ (d)) 7785 { 7786 #ifdef HAVE_MESSAGES 7787 MHD_DLOG (d, 7788 _ ("MHD_OPTION_APP_FD_SETSIZE is ignored for daemon started " \ 7789 "with MHD_USE_INTERNAL_POLLING_THREAD.\n")); 7790 #endif /* HAVE_MESSAGES */ 7791 (void) 0; 7792 } 7793 else if (MHD_D_IS_USING_POLL_ (d)) 7794 { 7795 #ifdef HAVE_MESSAGES 7796 MHD_DLOG (d, 7797 _ ("MHD_OPTION_APP_FD_SETSIZE is ignored for daemon started " \ 7798 "with MHD_USE_POLL.\n")); 7799 #endif /* HAVE_MESSAGES */ 7800 (void) 0; 7801 } 7802 else 7803 { /* The daemon without internal threads, external sockets polling */ 7804 #ifndef HAS_FD_SETSIZE_OVERRIDABLE 7805 if (((int) FD_SETSIZE) != params->fdset_size) 7806 { 7807 #ifdef HAVE_MESSAGES 7808 MHD_DLOG (d, 7809 _ ("MHD_OPTION_APP_FD_SETSIZE value (%d) does not match " \ 7810 "the platform FD_SETSIZE value (%d) and this platform " \ 7811 "does not support overriding of FD_SETSIZE.\n"), 7812 params->fdset_size, (int) FD_SETSIZE); 7813 #endif /* HAVE_MESSAGES */ 7814 return false; 7815 } 7816 #else /* HAS_FD_SETSIZE_OVERRIDABLE */ 7817 d->fdset_size = params->fdset_size; 7818 d->fdset_size_set_by_app = true; 7819 #endif /* HAS_FD_SETSIZE_OVERRIDABLE */ 7820 } 7821 } 7822 7823 if (params->listen_fd_set) 7824 { 7825 if (MHD_INVALID_SOCKET == params->listen_fd) 7826 { 7827 (void) 0; /* Use MHD-created socket */ 7828 } 7829 #ifdef HAS_SIGNED_SOCKET 7830 else if (0 > params->listen_fd) 7831 { 7832 #ifdef HAVE_MESSAGES 7833 MHD_DLOG (d, 7834 _ ("The value provided for MHD_OPTION_LISTEN_SOCKET " \ 7835 "is invalid.\n")); 7836 #endif /* HAVE_MESSAGES */ 7837 return false; 7838 } 7839 #endif /* HAS_SIGNED_SOCKET */ 7840 else if (0 != (d->options & MHD_USE_NO_LISTEN_SOCKET)) 7841 { 7842 #ifdef HAVE_MESSAGES 7843 MHD_DLOG (d, 7844 _ ("MHD_OPTION_LISTEN_SOCKET specified for daemon " 7845 "with MHD_USE_NO_LISTEN_SOCKET flag set.\n")); 7846 #endif /* HAVE_MESSAGES */ 7847 (void) MHD_socket_close_ (params->listen_fd); 7848 return false; 7849 } 7850 else 7851 { 7852 d->listen_fd = params->listen_fd; 7853 d->listen_is_unix = _MHD_UNKNOWN; 7854 #ifdef MHD_USE_GETSOCKNAME 7855 d->port = 0; /* Force use of autodetection */ 7856 #endif /* MHD_USE_GETSOCKNAME */ 7857 } 7858 } 7859 7860 mhd_assert (! params->server_addr_len_set || params->pserver_addr_set); 7861 if (params->pserver_addr_set) 7862 { 7863 if (NULL == params->pserver_addr) 7864 { 7865 /* The size must be zero if set */ 7866 if (params->server_addr_len_set && (0 != params->server_addr_len)) 7867 return false; 7868 /* Ignore parameter if it is NULL */ 7869 } 7870 else if (MHD_INVALID_SOCKET != d->listen_fd) 7871 { 7872 #ifdef HAVE_MESSAGES 7873 MHD_DLOG (d, 7874 _ ("MHD_OPTION_LISTEN_SOCKET cannot be used together with " \ 7875 "MHD_OPTION_SOCK_ADDR_LEN or MHD_OPTION_SOCK_ADDR.\n")); 7876 #endif /* HAVE_MESSAGES */ 7877 return false; 7878 } 7879 else if (0 != (d->options & MHD_USE_NO_LISTEN_SOCKET)) 7880 { 7881 #ifdef HAVE_MESSAGES 7882 MHD_DLOG (d, 7883 _ ("MHD_OPTION_SOCK_ADDR_LEN or MHD_OPTION_SOCK_ADDR " \ 7884 "specified for daemon with MHD_USE_NO_LISTEN_SOCKET " \ 7885 "flag set.\n")); 7886 #endif /* HAVE_MESSAGES */ 7887 if (MHD_INVALID_SOCKET != d->listen_fd) 7888 { 7889 (void) MHD_socket_close_ (params->listen_fd); 7890 params->listen_fd = MHD_INVALID_SOCKET; 7891 } 7892 return false; 7893 } 7894 else 7895 { 7896 *ppsockaddr = params->pserver_addr; 7897 if (params->server_addr_len_set) 7898 { 7899 /* The size must be non-zero if set */ 7900 if (0 == params->server_addr_len) 7901 return false; 7902 *psockaddr_len = params->server_addr_len; 7903 } 7904 else 7905 *psockaddr_len = 0; 7906 } 7907 } 7908 return true; 7909 } 7910 7911 7912 /** 7913 * Start a webserver on the given port. 7914 * 7915 * @param flags combination of `enum MHD_FLAG` values 7916 * @param port port to bind to (in host byte order), 7917 * use '0' to bind to random free port, 7918 * ignored if #MHD_OPTION_SOCK_ADDR or 7919 * #MHD_OPTION_LISTEN_SOCKET is provided 7920 * or #MHD_USE_NO_LISTEN_SOCKET is specified 7921 * @param apc callback to call to check which clients 7922 * will be allowed to connect; you can pass NULL 7923 * in which case connections from any IP will be 7924 * accepted 7925 * @param apc_cls extra argument to @a apc 7926 * @param dh handler called for all requests (repeatedly) 7927 * @param dh_cls extra argument to @a dh 7928 * @param ap list of options (type-value pairs, 7929 * terminated with #MHD_OPTION_END). 7930 * @return NULL on error, handle to daemon on success 7931 * @ingroup event 7932 */ 7933 _MHD_EXTERN struct MHD_Daemon * 7934 MHD_start_daemon_va (unsigned int flags, 7935 uint16_t port, 7936 MHD_AcceptPolicyCallback apc, 7937 void *apc_cls, 7938 MHD_AccessHandlerCallback dh, 7939 void *dh_cls, 7940 va_list ap) 7941 { 7942 const MHD_SCKT_OPT_BOOL_ on = 1; 7943 struct MHD_Daemon *daemon; 7944 const struct sockaddr *pservaddr = NULL; 7945 socklen_t addrlen; 7946 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 7947 unsigned int i; 7948 #endif 7949 enum MHD_FLAG eflags; /* same type as in MHD_Daemon */ 7950 enum MHD_FLAG *pflags; 7951 struct MHD_InterimParams_ *interim_params; 7952 7953 MHD_check_global_init_ (); 7954 eflags = (enum MHD_FLAG) flags; 7955 pflags = &eflags; 7956 7957 if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) 7958 *pflags |= MHD_USE_INTERNAL_POLLING_THREAD; /* Force enable, log warning later if needed */ 7959 7960 #ifndef HAVE_INET6 7961 if (0 != (*pflags & MHD_USE_IPv6)) 7962 return NULL; 7963 #endif 7964 #ifndef HAVE_POLL 7965 if (0 != (*pflags & MHD_USE_POLL)) 7966 return NULL; 7967 #endif 7968 #ifndef EPOLL_SUPPORT 7969 if (0 != (*pflags & MHD_USE_EPOLL)) 7970 return NULL; 7971 #endif /* ! EPOLL_SUPPORT */ 7972 #ifndef HTTPS_SUPPORT 7973 if (0 != (*pflags & MHD_USE_TLS)) 7974 return NULL; 7975 #endif /* ! HTTPS_SUPPORT */ 7976 #ifndef TCP_FASTOPEN 7977 if (0 != (*pflags & MHD_USE_TCP_FASTOPEN)) 7978 return NULL; 7979 #endif 7980 if (0 != (*pflags & MHD_ALLOW_UPGRADE)) 7981 { 7982 #ifdef UPGRADE_SUPPORT 7983 *pflags |= MHD_ALLOW_SUSPEND_RESUME; 7984 #else /* ! UPGRADE_SUPPORT */ 7985 return NULL; 7986 #endif /* ! UPGRADE_SUPPORT */ 7987 } 7988 #ifdef MHD_USE_THREADS 7989 if ((MHD_USE_NO_THREAD_SAFETY | MHD_USE_INTERNAL_POLLING_THREAD) == 7990 ((MHD_USE_NO_THREAD_SAFETY | MHD_USE_INTERNAL_POLLING_THREAD) 7991 & *pflags)) 7992 return NULL; /* Cannot be thread-unsafe with multiple threads */ 7993 #else /* ! MHD_USE_THREADS */ 7994 if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) 7995 return NULL; 7996 #endif /* ! MHD_USE_THREADS */ 7997 7998 if (NULL == dh) 7999 return NULL; 8000 8001 /* Check for invalid combinations of flags. */ 8002 if ((0 != (*pflags & MHD_USE_POLL)) && (0 != (*pflags & MHD_USE_EPOLL))) 8003 return NULL; 8004 if ((0 != (*pflags & MHD_USE_EPOLL)) && 8005 (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))) 8006 return NULL; 8007 if ((0 != (*pflags & MHD_USE_POLL)) && 8008 (0 == (*pflags & (MHD_USE_INTERNAL_POLLING_THREAD 8009 | MHD_USE_THREAD_PER_CONNECTION)))) 8010 return NULL; 8011 if ((0 != (*pflags & MHD_USE_AUTO)) && 8012 (0 != (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL)))) 8013 return NULL; 8014 8015 if (0 != (*pflags & MHD_USE_AUTO)) 8016 { 8017 #if defined(EPOLL_SUPPORT) && defined(HAVE_POLL) 8018 if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) 8019 *pflags |= MHD_USE_POLL; 8020 else 8021 *pflags |= MHD_USE_EPOLL; /* Including "external select" mode */ 8022 #elif defined(HAVE_POLL) 8023 if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) 8024 *pflags |= MHD_USE_POLL; /* Including thread-per-connection */ 8025 #elif defined(EPOLL_SUPPORT) 8026 if (0 == (*pflags & MHD_USE_THREAD_PER_CONNECTION)) 8027 *pflags |= MHD_USE_EPOLL; /* Including "external select" mode */ 8028 #else 8029 /* No choice: use select() for any mode - do not modify flags */ 8030 #endif 8031 } 8032 8033 if (0 != (*pflags & MHD_USE_NO_THREAD_SAFETY)) 8034 *pflags = (*pflags & ~((enum MHD_FLAG) MHD_USE_ITC)); /* useless in single-threaded environment */ 8035 else if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) 8036 { 8037 #ifdef HAVE_LISTEN_SHUTDOWN 8038 if (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET)) 8039 #endif 8040 *pflags |= MHD_USE_ITC; /* yes, must use ITC to signal thread */ 8041 } 8042 8043 if (NULL == (daemon = MHD_calloc_ (1, sizeof (struct MHD_Daemon)))) 8044 return NULL; 8045 interim_params = (struct MHD_InterimParams_ *) \ 8046 MHD_calloc_ (1, sizeof (struct MHD_InterimParams_)); 8047 if (NULL == interim_params) 8048 { 8049 int err_num = errno; 8050 free (daemon); 8051 errno = err_num; 8052 return NULL; 8053 } 8054 #ifdef EPOLL_SUPPORT 8055 daemon->epoll_fd = -1; 8056 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 8057 daemon->epoll_upgrade_fd = -1; 8058 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 8059 #endif 8060 /* try to open listen socket */ 8061 #ifdef HTTPS_SUPPORT 8062 daemon->priority_cache = NULL; 8063 #endif /* HTTPS_SUPPORT */ 8064 daemon->listen_fd = MHD_INVALID_SOCKET; 8065 daemon->listen_is_unix = _MHD_NO; 8066 daemon->listening_address_reuse = 0; 8067 daemon->options = *pflags; 8068 pflags = &daemon->options; 8069 daemon->client_discipline = (0 != (*pflags & MHD_USE_PEDANTIC_CHECKS)) ? 8070 1 : 0; 8071 daemon->port = port; 8072 daemon->apc = apc; 8073 daemon->apc_cls = apc_cls; 8074 daemon->default_handler = dh; 8075 daemon->default_handler_cls = dh_cls; 8076 daemon->connections = 0; 8077 daemon->connection_limit = MHD_MAX_CONNECTIONS_DEFAULT; 8078 daemon->pool_size = MHD_POOL_SIZE_DEFAULT; 8079 daemon->pool_increment = MHD_BUF_INC_SIZE; 8080 daemon->unescape_callback = &unescape_wrapper; 8081 daemon->connection_timeout_ms = 0; /* no timeout */ 8082 MHD_itc_set_invalid_ (daemon->itc); 8083 #ifdef MHD_USE_THREADS 8084 MHD_thread_handle_ID_set_invalid_ (&daemon->tid); 8085 #endif /* MHD_USE_THREADS */ 8086 #ifdef SOMAXCONN 8087 daemon->listen_backlog_size = SOMAXCONN; 8088 #else /* !SOMAXCONN */ 8089 daemon->listen_backlog_size = 511; /* should be safe value */ 8090 #endif /* !SOMAXCONN */ 8091 #ifdef HAVE_MESSAGES 8092 daemon->custom_error_log = &MHD_default_logger_; 8093 daemon->custom_error_log_cls = stderr; 8094 #endif 8095 #ifndef MHD_WINSOCK_SOCKETS 8096 daemon->sigpipe_blocked = false; 8097 #else /* MHD_WINSOCK_SOCKETS */ 8098 /* There is no SIGPIPE on W32, nothing to block. */ 8099 daemon->sigpipe_blocked = true; 8100 #endif /* _WIN32 && ! __CYGWIN__ */ 8101 #if defined(_DEBUG) && defined(HAVE_ACCEPT4) 8102 daemon->avoid_accept4 = false; 8103 #endif /* _DEBUG */ 8104 #ifdef HAS_FD_SETSIZE_OVERRIDABLE 8105 daemon->fdset_size = (int) FD_SETSIZE; 8106 daemon->fdset_size_set_by_app = false; 8107 #endif /* HAS_FD_SETSIZE_OVERRIDABLE */ 8108 8109 #ifdef DAUTH_SUPPORT 8110 daemon->digest_auth_rand_size = 0; 8111 daemon->digest_auth_random = NULL; 8112 daemon->nonce_nc_size = 4; /* tiny */ 8113 daemon->dauth_def_nonce_timeout = MHD_DAUTH_DEF_TIMEOUT_; 8114 daemon->dauth_def_max_nc = MHD_DAUTH_DEF_MAX_NC_; 8115 #endif 8116 #ifdef HTTPS_SUPPORT 8117 if (0 != (*pflags & MHD_USE_TLS)) 8118 { 8119 daemon->cred_type = GNUTLS_CRD_CERTIFICATE; 8120 } 8121 #endif /* HTTPS_SUPPORT */ 8122 8123 interim_params->num_opts = 0; 8124 interim_params->fdset_size_set = false; 8125 interim_params->fdset_size = 0; 8126 interim_params->listen_fd_set = false; 8127 interim_params->listen_fd = MHD_INVALID_SOCKET; 8128 interim_params->pserver_addr_set = false; 8129 interim_params->pserver_addr = NULL; 8130 interim_params->server_addr_len_set = false; 8131 interim_params->server_addr_len = 0; 8132 8133 if (MHD_NO == parse_options_va (daemon, 8134 interim_params, 8135 ap)) 8136 { 8137 #ifdef HTTPS_SUPPORT 8138 tls_cleanup_failed_start (daemon); 8139 #endif /* HTTPS_SUPPORT */ 8140 free (interim_params); 8141 free (daemon); 8142 return NULL; 8143 } 8144 if (! process_interim_params (daemon, 8145 &pservaddr, 8146 &addrlen, 8147 interim_params)) 8148 { 8149 #ifdef HTTPS_SUPPORT 8150 tls_cleanup_failed_start (daemon); 8151 #endif /* HTTPS_SUPPORT */ 8152 free (interim_params); 8153 free (daemon); 8154 return NULL; 8155 } 8156 free (interim_params); 8157 interim_params = NULL; 8158 #ifdef HTTPS_SUPPORT 8159 if ((0 != (*pflags & MHD_USE_TLS)) 8160 && (NULL == daemon->priority_cache) 8161 && ! daemon_tls_priorities_init_default (daemon)) 8162 { 8163 #ifdef HAVE_MESSAGES 8164 MHD_DLOG (daemon, 8165 _ ("Failed to initialise GnuTLS priorities.\n")); 8166 #endif /* HAVE_MESSAGES */ 8167 tls_cleanup_failed_start (daemon); 8168 free (daemon); 8169 return NULL; 8170 } 8171 #endif /* HTTPS_SUPPORT */ 8172 8173 #ifdef HAVE_MESSAGES 8174 if ( (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) && 8175 (0 == (flags & MHD_USE_INTERNAL_POLLING_THREAD)) ) 8176 { 8177 MHD_DLOG (daemon, 8178 _ ("Warning: MHD_USE_THREAD_PER_CONNECTION must be used " \ 8179 "only with MHD_USE_INTERNAL_POLLING_THREAD. " \ 8180 "Flag MHD_USE_INTERNAL_POLLING_THREAD was added. " \ 8181 "Consider setting MHD_USE_INTERNAL_POLLING_THREAD " \ 8182 "explicitly.\n")); 8183 } 8184 #endif 8185 8186 if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) 8187 && ((NULL != daemon->notify_completed) 8188 || (NULL != daemon->notify_connection)) ) 8189 *pflags |= MHD_USE_ITC; /* requires ITC */ 8190 8191 #ifdef _DEBUG 8192 #ifdef HAVE_MESSAGES 8193 MHD_DLOG (daemon, 8194 _ ("Using debug build of libmicrohttpd.\n") ); 8195 #endif /* HAVE_MESSAGES */ 8196 #endif /* _DEBUG */ 8197 8198 if ( (0 != (*pflags & MHD_USE_ITC)) 8199 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 8200 && (0 == daemon->worker_pool_size) 8201 #endif 8202 ) 8203 { 8204 if (! MHD_itc_init_ (daemon->itc)) 8205 { 8206 #ifdef HAVE_MESSAGES 8207 MHD_DLOG (daemon, 8208 _ ("Failed to create inter-thread communication channel: %s\n"), 8209 MHD_itc_last_strerror_ ()); 8210 #endif 8211 #ifdef HTTPS_SUPPORT 8212 if (NULL != daemon->priority_cache) 8213 gnutls_priority_deinit (daemon->priority_cache); 8214 #endif /* HTTPS_SUPPORT */ 8215 free (daemon); 8216 return NULL; 8217 } 8218 if (MHD_D_IS_USING_SELECT_ (daemon) && 8219 (! MHD_D_DOES_SCKT_FIT_FDSET_ (MHD_itc_r_fd_ (daemon->itc), daemon)) ) 8220 { 8221 #ifdef HAVE_MESSAGES 8222 MHD_DLOG (daemon, 8223 _ ("file descriptor for inter-thread communication " \ 8224 "channel exceeds maximum value.\n")); 8225 #endif 8226 MHD_itc_destroy_chk_ (daemon->itc); 8227 #ifdef HTTPS_SUPPORT 8228 if (NULL != daemon->priority_cache) 8229 gnutls_priority_deinit (daemon->priority_cache); 8230 #endif /* HTTPS_SUPPORT */ 8231 free (daemon); 8232 return NULL; 8233 } 8234 } 8235 8236 #ifdef DAUTH_SUPPORT 8237 if (NULL != daemon->digest_auth_random_copy) 8238 { 8239 mhd_assert (daemon == daemon->digest_auth_random_copy); 8240 daemon->digest_auth_random_copy = malloc (daemon->digest_auth_rand_size); 8241 if (NULL == daemon->digest_auth_random_copy) 8242 { 8243 #ifdef HTTPS_SUPPORT 8244 if (0 != (*pflags & MHD_USE_TLS)) 8245 gnutls_priority_deinit (daemon->priority_cache); 8246 #endif /* HTTPS_SUPPORT */ 8247 free (daemon); 8248 return NULL; 8249 } 8250 memcpy (daemon->digest_auth_random_copy, 8251 daemon->digest_auth_random, 8252 daemon->digest_auth_rand_size); 8253 daemon->digest_auth_random = daemon->digest_auth_random_copy; 8254 } 8255 if (daemon->nonce_nc_size > 0) 8256 { 8257 if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc))) 8258 / sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size) 8259 { 8260 #ifdef HAVE_MESSAGES 8261 MHD_DLOG (daemon, 8262 _ ("Specified value for NC_SIZE too large.\n")); 8263 #endif 8264 #ifdef HTTPS_SUPPORT 8265 if (0 != (*pflags & MHD_USE_TLS)) 8266 gnutls_priority_deinit (daemon->priority_cache); 8267 #endif /* HTTPS_SUPPORT */ 8268 free (daemon->digest_auth_random_copy); 8269 free (daemon); 8270 return NULL; 8271 } 8272 daemon->nnc = MHD_calloc_ (daemon->nonce_nc_size, 8273 sizeof (struct MHD_NonceNc)); 8274 if (NULL == daemon->nnc) 8275 { 8276 #ifdef HAVE_MESSAGES 8277 MHD_DLOG (daemon, 8278 _ ("Failed to allocate memory for nonce-nc map: %s\n"), 8279 MHD_strerror_ (errno)); 8280 #endif 8281 #ifdef HTTPS_SUPPORT 8282 if (0 != (*pflags & MHD_USE_TLS)) 8283 gnutls_priority_deinit (daemon->priority_cache); 8284 #endif /* HTTPS_SUPPORT */ 8285 free (daemon->digest_auth_random_copy); 8286 free (daemon); 8287 return NULL; 8288 } 8289 } 8290 8291 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 8292 if (! MHD_mutex_init_ (&daemon->nnc_lock)) 8293 { 8294 #ifdef HAVE_MESSAGES 8295 MHD_DLOG (daemon, 8296 _ ("MHD failed to initialize nonce-nc mutex.\n")); 8297 #endif 8298 #ifdef HTTPS_SUPPORT 8299 if (0 != (*pflags & MHD_USE_TLS)) 8300 gnutls_priority_deinit (daemon->priority_cache); 8301 #endif /* HTTPS_SUPPORT */ 8302 free (daemon->digest_auth_random_copy); 8303 free (daemon->nnc); 8304 free (daemon); 8305 return NULL; 8306 } 8307 #endif 8308 #endif 8309 8310 /* Thread polling currently works only with internal select thread mode */ 8311 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 8312 if ( (! MHD_D_IS_USING_THREADS_ (daemon)) && 8313 (daemon->worker_pool_size > 0) ) 8314 { 8315 #ifdef HAVE_MESSAGES 8316 MHD_DLOG (daemon, 8317 _ ("MHD thread polling only works with " \ 8318 "MHD_USE_INTERNAL_POLLING_THREAD.\n")); 8319 #endif 8320 goto free_and_fail; 8321 } 8322 #endif 8323 8324 if ( (MHD_INVALID_SOCKET == daemon->listen_fd) && 8325 (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) ) 8326 { 8327 /* try to open listen socket */ 8328 struct sockaddr_in servaddr4; 8329 #ifdef HAVE_INET6 8330 struct sockaddr_in6 servaddr6; 8331 const bool use_ipv6 = (0 != (*pflags & MHD_USE_IPv6)); 8332 #else /* ! HAVE_INET6 */ 8333 const bool use_ipv6 = false; 8334 #endif /* ! HAVE_INET6 */ 8335 int domain; 8336 8337 if (NULL != pservaddr) 8338 { 8339 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 8340 const socklen_t sa_len = pservaddr->sa_len; 8341 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ 8342 #ifdef HAVE_INET6 8343 if (use_ipv6 && (AF_INET6 != pservaddr->sa_family)) 8344 { 8345 #ifdef HAVE_MESSAGES 8346 MHD_DLOG (daemon, 8347 _ ("MHD_USE_IPv6 is enabled, but 'struct sockaddr *' " \ 8348 "specified for MHD_OPTION_SOCK_ADDR_LEN or " \ 8349 "MHD_OPTION_SOCK_ADDR is not IPv6 address.\n")); 8350 #endif /* HAVE_MESSAGES */ 8351 goto free_and_fail; 8352 } 8353 #endif /* HAVE_INET6 */ 8354 switch (pservaddr->sa_family) 8355 { 8356 case AF_INET: 8357 if (1) 8358 { 8359 struct sockaddr_in sa4; 8360 uint16_t sa4_port; 8361 if ((0 != addrlen) 8362 && (((socklen_t) sizeof(sa4)) > addrlen)) 8363 { 8364 #ifdef HAVE_MESSAGES 8365 MHD_DLOG (daemon, 8366 _ ("The size specified for MHD_OPTION_SOCK_ADDR_LEN " \ 8367 "option is wrong.\n")); 8368 #endif /* HAVE_MESSAGES */ 8369 goto free_and_fail; 8370 } 8371 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 8372 if (0 != sa_len) 8373 { 8374 if (((socklen_t) sizeof(sa4)) > sa_len) 8375 { 8376 #ifdef HAVE_MESSAGES 8377 MHD_DLOG (daemon, 8378 _ ("The value of 'struct sockaddr.sa_len' provided " \ 8379 "via MHD_OPTION_SOCK_ADDR_LEN option is not zero " \ 8380 "and does not match 'sa_family' value of the " \ 8381 "same structure.\n")); 8382 #endif /* HAVE_MESSAGES */ 8383 goto free_and_fail; 8384 } 8385 if ((0 == addrlen) || (sa_len < addrlen)) 8386 addrlen = sa_len; /* Use smaller value for safety */ 8387 } 8388 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ 8389 if (0 == addrlen) 8390 addrlen = sizeof(sa4); 8391 memcpy (&sa4, pservaddr, sizeof(sa4)); /* Required due to stronger alignment */ 8392 sa4_port = (uint16_t) ntohs (sa4.sin_port); 8393 #ifndef MHD_USE_GETSOCKNAME 8394 if (0 != sa4_port) 8395 #endif /* ! MHD_USE_GETSOCKNAME */ 8396 daemon->port = sa4_port; 8397 domain = PF_INET; 8398 } 8399 break; 8400 #ifdef HAVE_INET6 8401 case AF_INET6: 8402 if (1) 8403 { 8404 struct sockaddr_in6 sa6; 8405 uint16_t sa6_port; 8406 if ((0 != addrlen) 8407 && (((socklen_t) sizeof(sa6)) > addrlen)) 8408 { 8409 #ifdef HAVE_MESSAGES 8410 MHD_DLOG (daemon, 8411 _ ("The size specified for MHD_OPTION_SOCK_ADDR_LEN " \ 8412 "option is wrong.\n")); 8413 #endif /* HAVE_MESSAGES */ 8414 goto free_and_fail; 8415 } 8416 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 8417 if (0 != sa_len) 8418 { 8419 if (((socklen_t) sizeof(sa6)) > sa_len) 8420 { 8421 #ifdef HAVE_MESSAGES 8422 MHD_DLOG (daemon, 8423 _ ("The value of 'struct sockaddr.sa_len' provided " \ 8424 "via MHD_OPTION_SOCK_ADDR_LEN option is not zero " \ 8425 "and does not match 'sa_family' value of the " \ 8426 "same structure.\n")); 8427 #endif /* HAVE_MESSAGES */ 8428 goto free_and_fail; 8429 } 8430 if ((0 == addrlen) || (sa_len < addrlen)) 8431 addrlen = sa_len; /* Use smaller value for safety */ 8432 } 8433 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ 8434 if (0 == addrlen) 8435 addrlen = sizeof(sa6); 8436 memcpy (&sa6, pservaddr, sizeof(sa6)); /* Required due to stronger alignment */ 8437 sa6_port = (uint16_t) ntohs (sa6.sin6_port); 8438 #ifndef MHD_USE_GETSOCKNAME 8439 if (0 != sa6_port) 8440 #endif /* ! MHD_USE_GETSOCKNAME */ 8441 daemon->port = sa6_port; 8442 domain = PF_INET6; 8443 *pflags |= ((enum MHD_FLAG) MHD_USE_IPv6); 8444 } 8445 break; 8446 #endif /* HAVE_INET6 */ 8447 #ifdef AF_UNIX 8448 case AF_UNIX: 8449 #endif /* AF_UNIX */ 8450 default: 8451 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 8452 if (0 == addrlen) 8453 addrlen = sa_len; 8454 else if ((0 != sa_len) && (sa_len < addrlen)) 8455 addrlen = sa_len; /* Use smaller value for safety */ 8456 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ 8457 if (0 >= addrlen) 8458 { 8459 #ifdef HAVE_MESSAGES 8460 MHD_DLOG (daemon, 8461 _ ("The 'sa_family' of the 'struct sockaddr' provided " \ 8462 "via MHD_OPTION_SOCK_ADDR option is not supported.\n")); 8463 #endif /* HAVE_MESSAGES */ 8464 goto free_and_fail; 8465 } 8466 #ifdef AF_UNIX 8467 if (AF_UNIX == pservaddr->sa_family) 8468 { 8469 daemon->port = 0; /* special value for UNIX domain sockets */ 8470 daemon->listen_is_unix = _MHD_YES; 8471 #ifdef PF_UNIX 8472 domain = PF_UNIX; 8473 #else /* ! PF_UNIX */ 8474 domain = AF_UNIX; 8475 #endif /* ! PF_UNIX */ 8476 } 8477 else /* combined with the next 'if' */ 8478 #endif /* AF_UNIX */ 8479 if (1) 8480 { 8481 daemon->port = 0; /* ugh */ 8482 daemon->listen_is_unix = _MHD_UNKNOWN; 8483 /* Assumed the same values for AF_* and PF_* */ 8484 domain = pservaddr->sa_family; 8485 } 8486 break; 8487 } 8488 } 8489 else 8490 { 8491 if (! use_ipv6) 8492 { 8493 memset (&servaddr4, 8494 0, 8495 sizeof (struct sockaddr_in)); 8496 servaddr4.sin_family = AF_INET; 8497 servaddr4.sin_port = htons (port); 8498 if (0 != INADDR_ANY) 8499 servaddr4.sin_addr.s_addr = htonl (INADDR_ANY); 8500 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN 8501 servaddr4.sin_len = sizeof (struct sockaddr_in); 8502 #endif 8503 pservaddr = (struct sockaddr *) &servaddr4; 8504 addrlen = (socklen_t) sizeof(servaddr4); 8505 daemon->listen_is_unix = _MHD_NO; 8506 domain = PF_INET; 8507 } 8508 #ifdef HAVE_INET6 8509 else 8510 { 8511 #ifdef IN6ADDR_ANY_INIT 8512 static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT; 8513 #endif 8514 memset (&servaddr6, 8515 0, 8516 sizeof (struct sockaddr_in6)); 8517 servaddr6.sin6_family = AF_INET6; 8518 servaddr6.sin6_port = htons (port); 8519 #ifdef IN6ADDR_ANY_INIT 8520 servaddr6.sin6_addr = static_in6any; 8521 #endif 8522 #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN 8523 servaddr6.sin6_len = sizeof (struct sockaddr_in6); 8524 #endif 8525 pservaddr = (struct sockaddr *) &servaddr6; 8526 addrlen = (socklen_t) sizeof (servaddr6); 8527 daemon->listen_is_unix = _MHD_NO; 8528 domain = PF_INET6; 8529 } 8530 #endif /* HAVE_INET6 */ 8531 } 8532 8533 daemon->listen_fd = MHD_socket_create_listen_ (domain); 8534 if (MHD_INVALID_SOCKET == daemon->listen_fd) 8535 { 8536 #ifdef HAVE_MESSAGES 8537 MHD_DLOG (daemon, 8538 _ ("Failed to create socket for listening: %s\n"), 8539 MHD_socket_last_strerr_ ()); 8540 #endif 8541 goto free_and_fail; 8542 } 8543 if (MHD_D_IS_USING_SELECT_ (daemon) && 8544 (! MHD_D_DOES_SCKT_FIT_FDSET_ (daemon->listen_fd, 8545 daemon)) ) 8546 { 8547 #ifdef HAVE_MESSAGES 8548 MHD_DLOG (daemon, 8549 _ ("Listen socket descriptor (%d) is not " \ 8550 "less than daemon FD_SETSIZE value (%d).\n"), 8551 (int) daemon->listen_fd, 8552 (int) MHD_D_GET_FD_SETSIZE_ (daemon)); 8553 #endif 8554 goto free_and_fail; 8555 } 8556 8557 /* Apply the socket options according to listening_address_reuse. */ 8558 if (0 == daemon->listening_address_reuse) 8559 { 8560 #ifndef MHD_WINSOCK_SOCKETS 8561 /* No user requirement, use "traditional" default SO_REUSEADDR 8562 * on non-W32 platforms, and do not fail if it doesn't work. 8563 * Don't use it on W32, because on W32 it will allow multiple 8564 * bind to the same address:port, like SO_REUSEPORT on others. */ 8565 if (0 > setsockopt (daemon->listen_fd, 8566 SOL_SOCKET, 8567 SO_REUSEADDR, 8568 (const void *) &on, sizeof (on))) 8569 { 8570 #ifdef HAVE_MESSAGES 8571 MHD_DLOG (daemon, 8572 _ ("setsockopt failed: %s\n"), 8573 MHD_socket_last_strerr_ ()); 8574 #endif 8575 } 8576 #endif /* ! MHD_WINSOCK_SOCKETS */ 8577 } 8578 else if (daemon->listening_address_reuse > 0) 8579 { 8580 /* User requested to allow reusing listening address:port. */ 8581 #ifndef MHD_WINSOCK_SOCKETS 8582 /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if 8583 * it doesn't work. */ 8584 if (0 > setsockopt (daemon->listen_fd, 8585 SOL_SOCKET, 8586 SO_REUSEADDR, 8587 (const void *) &on, sizeof (on))) 8588 { 8589 #ifdef HAVE_MESSAGES 8590 MHD_DLOG (daemon, 8591 _ ("setsockopt failed: %s\n"), 8592 MHD_socket_last_strerr_ ()); 8593 #endif 8594 } 8595 #endif /* ! MHD_WINSOCK_SOCKETS */ 8596 /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms. 8597 * Fail if SO_REUSEPORT is not defined or setsockopt fails. 8598 */ 8599 /* SO_REUSEADDR on W32 has the same semantics 8600 as SO_REUSEPORT on BSD/Linux */ 8601 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT) 8602 if (0 > setsockopt (daemon->listen_fd, 8603 SOL_SOCKET, 8604 #ifndef MHD_WINSOCK_SOCKETS 8605 SO_REUSEPORT, 8606 #else /* MHD_WINSOCK_SOCKETS */ 8607 SO_REUSEADDR, 8608 #endif /* MHD_WINSOCK_SOCKETS */ 8609 (const void *) &on, 8610 sizeof (on))) 8611 { 8612 #ifdef HAVE_MESSAGES 8613 MHD_DLOG (daemon, 8614 _ ("setsockopt failed: %s\n"), 8615 MHD_socket_last_strerr_ ()); 8616 #endif 8617 goto free_and_fail; 8618 } 8619 #else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */ 8620 /* we're supposed to allow address:port re-use, but 8621 on this platform we cannot; fail hard */ 8622 #ifdef HAVE_MESSAGES 8623 MHD_DLOG (daemon, 8624 _ ("Cannot allow listening address reuse: " \ 8625 "SO_REUSEPORT not defined.\n")); 8626 #endif 8627 goto free_and_fail; 8628 #endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */ 8629 } 8630 else /* if (daemon->listening_address_reuse < 0) */ 8631 { 8632 /* User requested to disallow reusing listening address:port. 8633 * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE 8634 * is used and Solaris with SO_EXCLBIND. 8635 * Fail if MHD was compiled for W32 without SO_EXCLUSIVEADDRUSE 8636 * or setsockopt fails. 8637 */ 8638 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \ 8639 (defined(__sun) && defined(SO_EXCLBIND)) 8640 if (0 > setsockopt (daemon->listen_fd, 8641 SOL_SOCKET, 8642 #ifdef SO_EXCLUSIVEADDRUSE 8643 SO_EXCLUSIVEADDRUSE, 8644 #else /* SO_EXCLBIND */ 8645 SO_EXCLBIND, 8646 #endif /* SO_EXCLBIND */ 8647 (const void *) &on, 8648 sizeof (on))) 8649 { 8650 #ifdef HAVE_MESSAGES 8651 MHD_DLOG (daemon, 8652 _ ("setsockopt failed: %s\n"), 8653 MHD_socket_last_strerr_ ()); 8654 #endif 8655 goto free_and_fail; 8656 } 8657 #elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */ 8658 #ifdef HAVE_MESSAGES 8659 MHD_DLOG (daemon, 8660 _ ("Cannot disallow listening address reuse: " \ 8661 "SO_EXCLUSIVEADDRUSE not defined.\n")); 8662 #endif 8663 goto free_and_fail; 8664 #endif /* MHD_WINSOCK_SOCKETS */ 8665 } 8666 8667 /* check for user supplied sockaddr */ 8668 if (0 != (*pflags & MHD_USE_IPv6)) 8669 { 8670 #ifdef IPPROTO_IPV6 8671 #ifdef IPV6_V6ONLY 8672 /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options" 8673 (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx); 8674 and may also be missing on older POSIX systems; good luck if you have any of those, 8675 your IPv6 socket may then also bind against IPv4 anyway... */ 8676 const MHD_SCKT_OPT_BOOL_ v6_only = 8677 (MHD_USE_DUAL_STACK != (*pflags & MHD_USE_DUAL_STACK)); 8678 if (0 > setsockopt (daemon->listen_fd, 8679 IPPROTO_IPV6, IPV6_V6ONLY, 8680 (const void *) &v6_only, 8681 sizeof (v6_only))) 8682 { 8683 #ifdef HAVE_MESSAGES 8684 MHD_DLOG (daemon, 8685 _ ("setsockopt failed: %s\n"), 8686 MHD_socket_last_strerr_ ()); 8687 #endif 8688 } 8689 #endif 8690 #endif 8691 } 8692 if (0 != bind (daemon->listen_fd, 8693 pservaddr, 8694 addrlen)) 8695 { 8696 #ifdef HAVE_MESSAGES 8697 MHD_DLOG (daemon, 8698 _ ("Failed to bind to port %u: %s\n"), 8699 (unsigned int) port, 8700 MHD_socket_last_strerr_ ()); 8701 #endif 8702 goto free_and_fail; 8703 } 8704 #ifdef TCP_FASTOPEN 8705 if (0 != (*pflags & MHD_USE_TCP_FASTOPEN)) 8706 { 8707 if (0 == daemon->fastopen_queue_size) 8708 daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT; 8709 if (0 != setsockopt (daemon->listen_fd, 8710 IPPROTO_TCP, 8711 TCP_FASTOPEN, 8712 (const void *) &daemon->fastopen_queue_size, 8713 sizeof (daemon->fastopen_queue_size))) 8714 { 8715 #ifdef HAVE_MESSAGES 8716 MHD_DLOG (daemon, 8717 _ ("setsockopt failed: %s\n"), 8718 MHD_socket_last_strerr_ ()); 8719 #endif 8720 } 8721 } 8722 #endif 8723 if (0 != listen (daemon->listen_fd, 8724 (int) daemon->listen_backlog_size)) 8725 { 8726 #ifdef HAVE_MESSAGES 8727 MHD_DLOG (daemon, 8728 _ ("Failed to listen for connections: %s\n"), 8729 MHD_socket_last_strerr_ ()); 8730 #endif 8731 goto free_and_fail; 8732 } 8733 } 8734 else 8735 { 8736 if (MHD_D_IS_USING_SELECT_ (daemon) && 8737 (! MHD_D_DOES_SCKT_FIT_FDSET_ (daemon->listen_fd, 8738 daemon)) ) 8739 { 8740 #ifdef HAVE_MESSAGES 8741 MHD_DLOG (daemon, 8742 _ ("Listen socket descriptor (%d) is not " \ 8743 "less than daemon FD_SETSIZE value (%d).\n"), 8744 (int) daemon->listen_fd, 8745 (int) MHD_D_GET_FD_SETSIZE_ (daemon)); 8746 #endif 8747 goto free_and_fail; 8748 } 8749 else 8750 { 8751 #if defined(SOL_SOCKET) && (defined(SO_DOMAIN) || defined(SO_PROTOCOL_INFOW)) 8752 int af; 8753 int opt_name; 8754 void *poptval; 8755 socklen_t optval_size; 8756 #ifdef SO_DOMAIN 8757 opt_name = SO_DOMAIN; 8758 poptval = ⁡ 8759 optval_size = (socklen_t) sizeof (af); 8760 #else /* SO_PROTOCOL_INFOW */ 8761 WSAPROTOCOL_INFOW prot_info; 8762 opt_name = SO_PROTOCOL_INFOW; 8763 poptval = &prot_info; 8764 optval_size = (socklen_t) sizeof (prot_info); 8765 #endif /* SO_PROTOCOL_INFOW */ 8766 8767 if (0 == getsockopt (daemon->listen_fd, 8768 SOL_SOCKET, 8769 opt_name, 8770 poptval, 8771 &optval_size)) 8772 { 8773 #ifndef SO_DOMAIN 8774 af = prot_info.iAddressFamily; 8775 #endif /* SO_DOMAIN */ 8776 switch (af) 8777 { 8778 case AF_INET: 8779 daemon->listen_is_unix = _MHD_NO; 8780 break; 8781 #ifdef HAVE_INET6 8782 case AF_INET6: 8783 *pflags |= MHD_USE_IPv6; 8784 daemon->listen_is_unix = _MHD_NO; 8785 break; 8786 #endif /* HAVE_INET6 */ 8787 #ifdef AF_UNIX 8788 case AF_UNIX: 8789 daemon->port = 0; /* special value for UNIX domain sockets */ 8790 daemon->listen_is_unix = _MHD_YES; 8791 break; 8792 #endif /* AF_UNIX */ 8793 default: 8794 daemon->port = 0; /* ugh */ 8795 daemon->listen_is_unix = _MHD_UNKNOWN; 8796 break; 8797 } 8798 } 8799 else 8800 #endif /* SOL_SOCKET && (SO_DOMAIN || SO_PROTOCOL_INFOW)) */ 8801 daemon->listen_is_unix = _MHD_UNKNOWN; 8802 } 8803 8804 #ifdef MHD_USE_GETSOCKNAME 8805 daemon->port = 0; /* Force use of autodetection */ 8806 #endif /* MHD_USE_GETSOCKNAME */ 8807 } 8808 8809 #ifdef MHD_USE_GETSOCKNAME 8810 if ( (0 == daemon->port) && 8811 (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) && 8812 (_MHD_YES != daemon->listen_is_unix) ) 8813 { /* Get port number. */ 8814 struct sockaddr_storage bindaddr; 8815 8816 memset (&bindaddr, 8817 0, 8818 sizeof (struct sockaddr_storage)); 8819 addrlen = sizeof (struct sockaddr_storage); 8820 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 8821 bindaddr.ss_len = (socklen_t) addrlen; 8822 #endif 8823 if (0 != getsockname (daemon->listen_fd, 8824 (struct sockaddr *) &bindaddr, 8825 &addrlen)) 8826 { 8827 #ifdef HAVE_MESSAGES 8828 MHD_DLOG (daemon, 8829 _ ("Failed to get listen port number: %s\n"), 8830 MHD_socket_last_strerr_ ()); 8831 #endif /* HAVE_MESSAGES */ 8832 } 8833 #ifdef MHD_POSIX_SOCKETS 8834 else if (sizeof (bindaddr) < addrlen) 8835 { 8836 /* should be impossible with `struct sockaddr_storage` */ 8837 #ifdef HAVE_MESSAGES 8838 MHD_DLOG (daemon, 8839 _ ("Failed to get listen port number " \ 8840 "(`struct sockaddr_storage` too small!?).\n")); 8841 #endif /* HAVE_MESSAGES */ 8842 } 8843 #ifndef __linux__ 8844 else if (0 == addrlen) 8845 { 8846 /* Many non-Linux-based platforms return zero addrlen 8847 * for AF_UNIX sockets */ 8848 daemon->port = 0; /* special value for UNIX domain sockets */ 8849 if (_MHD_UNKNOWN == daemon->listen_is_unix) 8850 daemon->listen_is_unix = _MHD_YES; 8851 } 8852 #endif /* __linux__ */ 8853 #endif /* MHD_POSIX_SOCKETS */ 8854 else 8855 { 8856 switch (bindaddr.ss_family) 8857 { 8858 case AF_INET: 8859 { 8860 struct sockaddr_in *s4 = (struct sockaddr_in *) &bindaddr; 8861 8862 daemon->port = ntohs (s4->sin_port); 8863 daemon->listen_is_unix = _MHD_NO; 8864 break; 8865 } 8866 #ifdef HAVE_INET6 8867 case AF_INET6: 8868 { 8869 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &bindaddr; 8870 8871 daemon->port = ntohs (s6->sin6_port); 8872 daemon->listen_is_unix = _MHD_NO; 8873 mhd_assert (0 != (*pflags & MHD_USE_IPv6)); 8874 break; 8875 } 8876 #endif /* HAVE_INET6 */ 8877 #ifdef AF_UNIX 8878 case AF_UNIX: 8879 daemon->port = 0; /* special value for UNIX domain sockets */ 8880 daemon->listen_is_unix = _MHD_YES; 8881 break; 8882 #endif 8883 default: 8884 #ifdef HAVE_MESSAGES 8885 MHD_DLOG (daemon, 8886 _ ("Listen socket has unknown address family!\n")); 8887 #endif 8888 daemon->port = 0; /* ugh */ 8889 daemon->listen_is_unix = _MHD_UNKNOWN; 8890 break; 8891 } 8892 } 8893 } 8894 #endif /* MHD_USE_GETSOCKNAME */ 8895 8896 if (MHD_INVALID_SOCKET != daemon->listen_fd) 8897 { 8898 mhd_assert (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)); 8899 if (! MHD_socket_nonblocking_ (daemon->listen_fd)) 8900 { 8901 #ifdef HAVE_MESSAGES 8902 MHD_DLOG (daemon, 8903 _ ("Failed to set nonblocking mode on listening socket: %s\n"), 8904 MHD_socket_last_strerr_ ()); 8905 #endif 8906 if (MHD_D_IS_USING_EPOLL_ (daemon) 8907 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 8908 || (daemon->worker_pool_size > 0) 8909 #endif 8910 ) 8911 { 8912 /* Accept must be non-blocking. Multiple children may wake up 8913 * to handle a new connection, but only one will win the race. 8914 * The others must immediately return. */ 8915 goto free_and_fail; 8916 } 8917 daemon->listen_nonblk = false; 8918 } 8919 else 8920 daemon->listen_nonblk = true; 8921 } 8922 else 8923 { 8924 mhd_assert (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET)); 8925 daemon->listen_nonblk = false; /* Actually listen socket does not exist */ 8926 } 8927 8928 #ifdef EPOLL_SUPPORT 8929 if (MHD_D_IS_USING_EPOLL_ (daemon) 8930 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 8931 && (0 == daemon->worker_pool_size) 8932 #endif 8933 ) 8934 { 8935 if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) 8936 { 8937 #ifdef HAVE_MESSAGES 8938 MHD_DLOG (daemon, 8939 _ ("Combining MHD_USE_THREAD_PER_CONNECTION and " \ 8940 "MHD_USE_EPOLL is not supported.\n")); 8941 #endif 8942 goto free_and_fail; 8943 } 8944 if (MHD_NO == setup_epoll_to_listen (daemon)) 8945 goto free_and_fail; 8946 } 8947 #endif /* EPOLL_SUPPORT */ 8948 8949 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 8950 if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex)) 8951 { 8952 #ifdef HAVE_MESSAGES 8953 MHD_DLOG (daemon, 8954 _ ("MHD failed to initialize IP connection limit mutex.\n")); 8955 #endif 8956 goto free_and_fail; 8957 } 8958 #endif 8959 8960 #ifdef HTTPS_SUPPORT 8961 /* initialize HTTPS daemon certificate aspects & send / recv functions */ 8962 if ( (0 != (*pflags & MHD_USE_TLS)) && 8963 (0 != MHD_TLS_init (daemon)) ) 8964 { 8965 #ifdef HAVE_MESSAGES 8966 MHD_DLOG (daemon, 8967 _ ("Failed to initialize TLS support.\n")); 8968 #endif 8969 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 8970 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 8971 #endif 8972 goto free_and_fail; 8973 } 8974 #endif /* HTTPS_SUPPORT */ 8975 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 8976 /* Start threads if requested by parameters */ 8977 if (MHD_D_IS_USING_THREADS_ (daemon)) 8978 { 8979 /* Internal thread (or threads) is used. 8980 * Make sure that MHD will be able to communicate with threads. */ 8981 /* If using a thread pool ITC will be initialised later 8982 * for each individual worker thread. */ 8983 #ifdef HAVE_LISTEN_SHUTDOWN 8984 mhd_assert ((1 < daemon->worker_pool_size) || \ 8985 (MHD_ITC_IS_VALID_ (daemon->itc)) || \ 8986 (MHD_INVALID_SOCKET != daemon->listen_fd)); 8987 #else /* ! HAVE_LISTEN_SHUTDOWN */ 8988 mhd_assert ((1 < daemon->worker_pool_size) || \ 8989 (MHD_ITC_IS_VALID_ (daemon->itc))); 8990 #endif /* ! HAVE_LISTEN_SHUTDOWN */ 8991 if (0 == daemon->worker_pool_size) 8992 { 8993 if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex)) 8994 { 8995 #ifdef HAVE_MESSAGES 8996 MHD_DLOG (daemon, 8997 _ ("Failed to initialise internal lists mutex.\n")); 8998 #endif 8999 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 9000 goto free_and_fail; 9001 } 9002 if (! MHD_mutex_init_ (&daemon->new_connections_mutex)) 9003 { 9004 #ifdef HAVE_MESSAGES 9005 MHD_DLOG (daemon, 9006 _ ("Failed to initialise mutex.\n")); 9007 #endif 9008 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 9009 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); 9010 goto free_and_fail; 9011 } 9012 if (! MHD_mutex_init_ (&daemon->epoll_listen_mutex)) 9013 { 9014 #ifdef HAVE_MESSAGES 9015 MHD_DLOG (daemon, 9016 _ ("Failed to initialise mutex.\n")); 9017 #endif 9018 MHD_mutex_destroy_chk_ (&daemon->new_connections_mutex); 9019 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); 9020 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 9021 goto free_and_fail; 9022 } 9023 if (! MHD_create_named_thread_ (&daemon->tid, 9024 MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) ? 9025 "MHD-listen" : "MHD-single", 9026 daemon->thread_stack_size, 9027 &MHD_polling_thread, 9028 daemon) ) 9029 { 9030 #ifdef HAVE_MESSAGES 9031 #ifdef EAGAIN 9032 if (EAGAIN == errno) 9033 MHD_DLOG (daemon, 9034 _ ("Failed to create a new thread because it would have " \ 9035 "exceeded the system limit on the number of threads or " \ 9036 "no system resources available.\n")); 9037 else 9038 #endif /* EAGAIN */ 9039 MHD_DLOG (daemon, 9040 _ ("Failed to create listen thread: %s\n"), 9041 MHD_strerror_ (errno)); 9042 #endif /* HAVE_MESSAGES */ 9043 MHD_mutex_destroy_chk_ (&daemon->epoll_listen_mutex); 9044 MHD_mutex_destroy_chk_ (&daemon->new_connections_mutex); 9045 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 9046 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); 9047 goto free_and_fail; 9048 } 9049 } 9050 else /* 0 < daemon->worker_pool_size */ 9051 { 9052 /* Coarse-grained count of connections per thread (note error 9053 * due to integer division). Also keep track of how many 9054 * connections are leftover after an equal split. */ 9055 unsigned int conns_per_thread = daemon->connection_limit 9056 / daemon->worker_pool_size; 9057 unsigned int leftover_conns = daemon->connection_limit 9058 % daemon->worker_pool_size; 9059 9060 mhd_assert (2 <= daemon->worker_pool_size); 9061 i = 0; /* we need this in case fcntl or malloc fails */ 9062 9063 /* Allocate memory for pooled objects */ 9064 daemon->worker_pool = malloc (sizeof (struct MHD_Daemon) 9065 * daemon->worker_pool_size); 9066 if (NULL == daemon->worker_pool) 9067 goto thread_failed; 9068 9069 /* Start the workers in the pool */ 9070 for (i = 0; i < daemon->worker_pool_size; ++i) 9071 { 9072 /* Create copy of the Daemon object for each worker */ 9073 struct MHD_Daemon *d = &daemon->worker_pool[i]; 9074 9075 memcpy (d, daemon, sizeof (struct MHD_Daemon)); 9076 /* Adjust polling params for worker daemons; note that memcpy() 9077 has already copied MHD_USE_INTERNAL_POLLING_THREAD thread mode into 9078 the worker threads. */ 9079 d->master = daemon; 9080 d->worker_pool_size = 0; 9081 d->worker_pool = NULL; 9082 if (! MHD_mutex_init_ (&d->cleanup_connection_mutex)) 9083 { 9084 #ifdef HAVE_MESSAGES 9085 MHD_DLOG (daemon, 9086 _ ("Failed to initialise internal lists mutex.\n")); 9087 #endif 9088 goto thread_failed; 9089 } 9090 if (! MHD_mutex_init_ (&d->new_connections_mutex)) 9091 { 9092 #ifdef HAVE_MESSAGES 9093 MHD_DLOG (daemon, 9094 _ ("Failed to initialise mutex.\n")); 9095 #endif 9096 MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex); 9097 goto thread_failed; 9098 } 9099 if (! MHD_mutex_init_ (&d->epoll_listen_mutex)) 9100 { 9101 #ifdef HAVE_MESSAGES 9102 MHD_DLOG (daemon, 9103 _ ("Failed to initialise mutex.\n")); 9104 #endif 9105 MHD_mutex_destroy_chk_ (&d->new_connections_mutex); 9106 MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex); 9107 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 9108 goto free_and_fail; 9109 } 9110 if (0 != (*pflags & MHD_USE_ITC)) 9111 { 9112 if (! MHD_itc_init_ (d->itc)) 9113 { 9114 #ifdef HAVE_MESSAGES 9115 MHD_DLOG (daemon, 9116 _ ("Failed to create worker inter-thread " \ 9117 "communication channel: %s\n"), 9118 MHD_itc_last_strerror_ () ); 9119 #endif 9120 MHD_mutex_destroy_chk_ (&d->epoll_listen_mutex); 9121 MHD_mutex_destroy_chk_ (&d->new_connections_mutex); 9122 MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex); 9123 goto thread_failed; 9124 } 9125 if (MHD_D_IS_USING_SELECT_ (d) && 9126 (! MHD_D_DOES_SCKT_FIT_FDSET_ (MHD_itc_r_fd_ (d->itc), daemon)) ) 9127 { 9128 #ifdef HAVE_MESSAGES 9129 MHD_DLOG (daemon, 9130 _ ("File descriptor for worker inter-thread " \ 9131 "communication channel exceeds maximum value.\n")); 9132 #endif 9133 MHD_itc_destroy_chk_ (d->itc); 9134 MHD_mutex_destroy_chk_ (&d->epoll_listen_mutex); 9135 MHD_mutex_destroy_chk_ (&d->new_connections_mutex); 9136 MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex); 9137 goto thread_failed; 9138 } 9139 } 9140 else 9141 MHD_itc_set_invalid_ (d->itc); 9142 9143 #ifdef HAVE_LISTEN_SHUTDOWN 9144 mhd_assert ((MHD_ITC_IS_VALID_ (d->itc)) || \ 9145 (MHD_INVALID_SOCKET != d->listen_fd)); 9146 #else /* ! HAVE_LISTEN_SHUTDOWN */ 9147 mhd_assert (MHD_ITC_IS_VALID_ (d->itc)); 9148 #endif /* ! HAVE_LISTEN_SHUTDOWN */ 9149 9150 /* Divide available connections evenly amongst the threads. 9151 * Thread indexes in [0, leftover_conns) each get one of the 9152 * leftover connections. */ 9153 d->connection_limit = conns_per_thread; 9154 if (i < leftover_conns) 9155 ++d->connection_limit; 9156 #ifdef EPOLL_SUPPORT 9157 if (MHD_D_IS_USING_EPOLL_ (d) && 9158 (MHD_NO == setup_epoll_to_listen (d)) ) 9159 { 9160 if (MHD_ITC_IS_VALID_ (d->itc)) 9161 MHD_itc_destroy_chk_ (d->itc); 9162 MHD_mutex_destroy_chk_ (&d->epoll_listen_mutex); 9163 MHD_mutex_destroy_chk_ (&d->new_connections_mutex); 9164 MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex); 9165 goto thread_failed; 9166 } 9167 #endif 9168 /* Some members must be used only in master daemon */ 9169 #if defined(MHD_USE_THREADS) 9170 memset (&d->per_ip_connection_mutex, 0x7F, 9171 sizeof(d->per_ip_connection_mutex)); 9172 #endif /* MHD_USE_THREADS */ 9173 #ifdef DAUTH_SUPPORT 9174 d->nnc = NULL; 9175 d->nonce_nc_size = 0; 9176 d->digest_auth_random_copy = NULL; 9177 #if defined(MHD_USE_THREADS) 9178 memset (&d->nnc_lock, 0x7F, sizeof(d->nnc_lock)); 9179 #endif /* MHD_USE_THREADS */ 9180 #endif /* DAUTH_SUPPORT */ 9181 9182 /* Spawn the worker thread */ 9183 if (! MHD_create_named_thread_ (&d->tid, 9184 "MHD-worker", 9185 daemon->thread_stack_size, 9186 &MHD_polling_thread, 9187 d)) 9188 { 9189 #ifdef HAVE_MESSAGES 9190 #ifdef EAGAIN 9191 if (EAGAIN == errno) 9192 MHD_DLOG (daemon, 9193 _ ("Failed to create a new pool thread because it would " \ 9194 "have exceeded the system limit on the number of " \ 9195 "threads or no system resources available.\n")); 9196 else 9197 #endif /* EAGAIN */ 9198 MHD_DLOG (daemon, 9199 _ ("Failed to create pool thread: %s\n"), 9200 MHD_strerror_ (errno)); 9201 #endif 9202 /* Free memory for this worker; cleanup below handles 9203 * all previously-created workers. */ 9204 if (MHD_ITC_IS_VALID_ (d->itc)) 9205 MHD_itc_destroy_chk_ (d->itc); 9206 MHD_mutex_destroy_chk_ (&d->epoll_listen_mutex); 9207 MHD_mutex_destroy_chk_ (&d->new_connections_mutex); 9208 MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex); 9209 goto thread_failed; 9210 } 9211 } 9212 } 9213 } 9214 else 9215 { /* Daemon without internal threads */ 9216 if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex)) 9217 { 9218 #ifdef HAVE_MESSAGES 9219 MHD_DLOG (daemon, 9220 _ ("Failed to initialise internal lists mutex.\n")); 9221 #endif 9222 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 9223 goto free_and_fail; 9224 } 9225 if (! MHD_mutex_init_ (&daemon->new_connections_mutex)) 9226 { 9227 #ifdef HAVE_MESSAGES 9228 MHD_DLOG (daemon, 9229 _ ("Failed to initialise mutex.\n")); 9230 #endif 9231 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); 9232 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 9233 goto free_and_fail; 9234 } 9235 if (! MHD_mutex_init_ (&daemon->epoll_listen_mutex)) 9236 { 9237 #ifdef HAVE_MESSAGES 9238 MHD_DLOG (daemon, 9239 _ ("Failed to initialise mutex.\n")); 9240 #endif 9241 MHD_mutex_destroy_chk_ (&daemon->new_connections_mutex); 9242 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); 9243 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 9244 goto free_and_fail; 9245 } 9246 } 9247 #endif 9248 #ifdef HTTPS_SUPPORT 9249 /* API promises to never use the password after initialization, 9250 so we additionally NULL it here to not deref a dangling pointer. */ 9251 daemon->https_key_password = NULL; 9252 #endif /* HTTPS_SUPPORT */ 9253 9254 return daemon; 9255 9256 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9257 thread_failed: 9258 /* If no worker threads created, then shut down normally. Calling 9259 MHD_stop_daemon (as we do below) doesn't work here since it 9260 assumes a 0-sized thread pool means we had been in the default 9261 MHD_USE_INTERNAL_POLLING_THREAD mode. */ 9262 if (0 == i) 9263 { 9264 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 9265 if (NULL != daemon->worker_pool) 9266 free (daemon->worker_pool); 9267 goto free_and_fail; 9268 } 9269 9270 /* Shutdown worker threads we've already created. Pretend 9271 as though we had fully initialized our daemon, but 9272 with a smaller number of threads than had been 9273 requested. */ 9274 daemon->worker_pool_size = i; 9275 MHD_stop_daemon (daemon); 9276 return NULL; 9277 #endif 9278 9279 free_and_fail: 9280 /* clean up basic memory state in 'daemon' and return NULL to 9281 indicate failure */ 9282 #ifdef EPOLL_SUPPORT 9283 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 9284 if (daemon->upgrade_fd_in_epoll) 9285 { 9286 if (0 != epoll_ctl (daemon->epoll_fd, 9287 EPOLL_CTL_DEL, 9288 daemon->epoll_upgrade_fd, 9289 NULL)) 9290 MHD_PANIC (_ ("Failed to remove FD from epoll set.\n")); 9291 daemon->upgrade_fd_in_epoll = false; 9292 } 9293 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 9294 if (-1 != daemon->epoll_fd) 9295 close (daemon->epoll_fd); 9296 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 9297 if (-1 != daemon->epoll_upgrade_fd) 9298 close (daemon->epoll_upgrade_fd); 9299 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 9300 #endif /* EPOLL_SUPPORT */ 9301 #ifdef DAUTH_SUPPORT 9302 free (daemon->digest_auth_random_copy); 9303 free (daemon->nnc); 9304 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9305 MHD_mutex_destroy_chk_ (&daemon->nnc_lock); 9306 #endif 9307 #endif 9308 #ifdef HTTPS_SUPPORT 9309 tls_cleanup_failed_start (daemon); 9310 #endif /* HTTPS_SUPPORT */ 9311 if (MHD_ITC_IS_VALID_ (daemon->itc)) 9312 MHD_itc_destroy_chk_ (daemon->itc); 9313 if (MHD_INVALID_SOCKET != daemon->listen_fd) 9314 (void) MHD_socket_close_ (daemon->listen_fd); 9315 free (daemon); 9316 return NULL; 9317 } 9318 9319 9320 /** 9321 * Close all connections for the daemon. 9322 * Must only be called when MHD_Daemon::shutdown was set to true. 9323 * @remark To be called only from thread that process 9324 * daemon's select()/poll()/etc. 9325 * 9326 * @param daemon daemon to close down 9327 */ 9328 static void 9329 close_all_connections (struct MHD_Daemon *daemon) 9330 { 9331 struct MHD_Connection *pos; 9332 const bool used_thr_p_c = MHD_D_IS_USING_THREAD_PER_CONN_ (daemon); 9333 #ifdef UPGRADE_SUPPORT 9334 const bool upg_allowed = (0 != (daemon->options & MHD_ALLOW_UPGRADE)); 9335 #endif /* UPGRADE_SUPPORT */ 9336 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 9337 struct MHD_UpgradeResponseHandle *urh; 9338 struct MHD_UpgradeResponseHandle *urhn; 9339 const bool used_tls = (0 != (daemon->options & MHD_USE_TLS)); 9340 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 9341 9342 #ifdef MHD_USE_THREADS 9343 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 9344 MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) || \ 9345 MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); 9346 mhd_assert (NULL == daemon->worker_pool); 9347 #endif /* MHD_USE_THREADS */ 9348 mhd_assert (daemon->shutdown); 9349 9350 #ifdef MHD_USE_THREADS 9351 /* Remove new connections that MHD_add_connection() queued and that were 9352 * never processed. This is not limited to daemons with an internal 9353 * polling thread: internal_add_connection() queues whenever the daemon 9354 * is thread-safe, which is every daemon that was not started with 9355 * MHD_USE_NO_THREAD_SAFETY, and new_connections_list_process_() 9356 * asserts the same condition. An application driving an external 9357 * event loop can therefore call MHD_add_connection() and then 9358 * MHD_stop_daemon() before the next MHD_run(), and this list is what 9359 * holds the connection at that point. */ 9360 MHD_mutex_lock_chk_ (&daemon->new_connections_mutex); 9361 while (NULL != (pos = daemon->new_connections_tail)) 9362 { 9363 mhd_assert (MHD_D_IS_THREAD_SAFE_ (daemon)); 9364 DLL_remove (daemon->new_connections_head, 9365 daemon->new_connections_tail, 9366 pos); 9367 new_connection_close_ (daemon, pos); 9368 } 9369 MHD_mutex_unlock_chk_ (&daemon->new_connections_mutex); 9370 #endif /* MHD_USE_THREADS */ 9371 9372 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 9373 /* give upgraded HTTPS connections a chance to finish */ 9374 /* 'daemon->urh_head' is not used in thread-per-connection mode. */ 9375 for (urh = daemon->urh_tail; NULL != urh; urh = urhn) 9376 { 9377 mhd_assert (! used_thr_p_c); 9378 urhn = urh->prev; 9379 /* call generic forwarding function for passing data 9380 with chance to detect that application is done. */ 9381 process_urh (urh); 9382 MHD_connection_finish_forward_ (urh->connection); 9383 urh->clean_ready = true; 9384 /* Resuming will move connection to cleanup list. */ 9385 MHD_resume_connection (urh->connection); 9386 } 9387 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 9388 9389 /* Give suspended connections a chance to resume to avoid 9390 running into the check for there not being any suspended 9391 connections left in case of a tight race with a recently 9392 resumed connection. */ 9393 if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options)) 9394 { 9395 daemon->resuming = true; /* Force check for pending resume. */ 9396 resume_suspended_connections (daemon); 9397 } 9398 /* first, make sure all threads are aware of shutdown; need to 9399 traverse DLLs in peace... */ 9400 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9401 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 9402 #endif 9403 #ifdef UPGRADE_SUPPORT 9404 if (upg_allowed) 9405 { 9406 struct MHD_Connection *susp; 9407 9408 susp = daemon->suspended_connections_tail; 9409 while (NULL != susp) 9410 { 9411 if (NULL == susp->urh) /* "Upgraded" connection? */ 9412 MHD_PANIC (_ ("MHD_stop_daemon() called while we have " \ 9413 "suspended connections.\n")); 9414 #ifdef HTTPS_SUPPORT 9415 else if (used_tls && 9416 used_thr_p_c && 9417 (! susp->urh->clean_ready) ) 9418 shutdown (susp->urh->app.socket, 9419 SHUT_RDWR); /* Wake thread by shutdown of app socket. */ 9420 #endif /* HTTPS_SUPPORT */ 9421 else 9422 { 9423 #ifdef HAVE_MESSAGES 9424 if (! susp->urh->was_closed) 9425 MHD_DLOG (daemon, 9426 _ ("Initiated daemon shutdown while \"upgraded\" " \ 9427 "connection was not closed.\n")); 9428 #endif 9429 susp->urh->was_closed = true; 9430 /* If thread-per-connection is used, connection's thread 9431 * may still processing "upgrade" (exiting). */ 9432 if (! used_thr_p_c) 9433 MHD_connection_finish_forward_ (susp); 9434 /* Do not use MHD_resume_connection() as mutex is 9435 * already locked. */ 9436 susp->resuming = true; 9437 daemon->resuming = true; 9438 } 9439 susp = susp->prev; 9440 } 9441 } 9442 else /* This 'else' is combined with next 'if' */ 9443 #endif /* UPGRADE_SUPPORT */ 9444 if (NULL != daemon->suspended_connections_head) 9445 MHD_PANIC (_ ("MHD_stop_daemon() called while we have " \ 9446 "suspended connections.\n")); 9447 #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT) 9448 #ifdef MHD_USE_THREADS 9449 if (upg_allowed && used_tls && used_thr_p_c) 9450 { 9451 /* "Upgraded" threads may be running in parallel. Connection will not be 9452 * moved to the "cleanup list" until connection's thread finishes. 9453 * We must ensure that all "upgraded" connections are finished otherwise 9454 * connection may stay in "suspended" list and will not be cleaned. */ 9455 for (pos = daemon->suspended_connections_tail; NULL != pos; pos = pos->prev) 9456 { 9457 /* Any connection found here is "upgraded" connection, normal suspended 9458 * connections are already removed from this list. */ 9459 mhd_assert (NULL != pos->urh); 9460 if (! pos->thread_joined) 9461 { 9462 /* While "cleanup" list is not manipulated by "upgraded" 9463 * connection, "cleanup" mutex is required for call of 9464 * MHD_resume_connection() during finishing of "upgraded" 9465 * thread. */ 9466 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 9467 if (! MHD_thread_handle_ID_join_thread_ (pos->tid)) 9468 MHD_PANIC (_ ("Failed to join a thread.\n")); 9469 pos->thread_joined = true; 9470 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 9471 } 9472 } 9473 } 9474 #endif /* MHD_USE_THREADS */ 9475 #endif 9476 for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev) 9477 { 9478 shutdown (pos->socket_fd, 9479 SHUT_RDWR); 9480 #ifdef MHD_WINSOCK_SOCKETS 9481 if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) && 9482 (MHD_ITC_IS_VALID_ (daemon->itc)) && 9483 (! MHD_itc_activate_ (daemon->itc, "e")) ) 9484 MHD_PANIC (_ ("Failed to signal shutdown via inter-thread " \ 9485 "communication channel.\n")); 9486 #endif 9487 } 9488 9489 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9490 /* now, collect per-connection threads */ 9491 if (used_thr_p_c) 9492 { 9493 pos = daemon->connections_tail; 9494 while (NULL != pos) 9495 { 9496 if (! pos->thread_joined) 9497 { 9498 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 9499 if (! MHD_thread_handle_ID_join_thread_ (pos->tid)) 9500 MHD_PANIC (_ ("Failed to join a thread.\n")); 9501 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 9502 pos->thread_joined = true; 9503 /* The thread may have concurrently modified the DLL, 9504 need to restart from the beginning */ 9505 pos = daemon->connections_tail; 9506 continue; 9507 } 9508 pos = pos->prev; 9509 } 9510 } 9511 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 9512 #endif 9513 9514 #ifdef UPGRADE_SUPPORT 9515 /* Finished threads with "upgraded" connections need to be moved 9516 * to cleanup list by resume_suspended_connections(). */ 9517 /* "Upgraded" connections that were not closed explicitly by 9518 * application should be moved to cleanup list too. */ 9519 if (upg_allowed) 9520 { 9521 daemon->resuming = true; /* Force check for pending resume. */ 9522 resume_suspended_connections (daemon); 9523 } 9524 #endif /* UPGRADE_SUPPORT */ 9525 9526 mhd_assert (NULL == daemon->suspended_connections_head); 9527 /* now that we're alone, move everyone to cleanup */ 9528 while (NULL != (pos = daemon->connections_tail)) 9529 { 9530 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9531 if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) && 9532 (! pos->thread_joined) ) 9533 MHD_PANIC (_ ("Failed to join a thread.\n")); 9534 #endif 9535 close_connection (pos); 9536 } 9537 MHD_cleanup_connections (daemon); 9538 } 9539 9540 9541 /** 9542 * Shutdown an HTTP daemon. 9543 * 9544 * @param daemon daemon to stop 9545 * @ingroup event 9546 */ 9547 _MHD_EXTERN void 9548 MHD_stop_daemon (struct MHD_Daemon *daemon) 9549 { 9550 MHD_socket fd; 9551 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9552 unsigned int i; 9553 #endif 9554 9555 if (NULL == daemon) 9556 return; 9557 if ( (daemon->shutdown) && (NULL == daemon->master) ) 9558 MHD_PANIC (_ ("MHD_stop_daemon() was called twice.")); 9559 9560 mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 9561 (NULL != daemon->worker_pool) || \ 9562 (MHD_thread_handle_ID_is_valid_handle_ (daemon->tid))); 9563 mhd_assert (((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) && 9564 (NULL == daemon->worker_pool)) || \ 9565 (! MHD_thread_handle_ID_is_valid_handle_ (daemon->tid))); 9566 9567 /* Slave daemons must be stopped by master daemon. */ 9568 mhd_assert ( (NULL == daemon->master) || (daemon->shutdown) ); 9569 9570 daemon->shutdown = true; 9571 if (daemon->was_quiesced) 9572 fd = MHD_INVALID_SOCKET; /* Do not use FD if daemon was quiesced */ 9573 else 9574 fd = daemon->listen_fd; 9575 9576 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9577 if (NULL != daemon->worker_pool) 9578 { /* Master daemon with worker pool. */ 9579 mhd_assert (1 < daemon->worker_pool_size); 9580 mhd_assert (MHD_D_IS_USING_THREADS_ (daemon)); 9581 9582 /* Let workers shutdown in parallel. */ 9583 for (i = 0; i < daemon->worker_pool_size; ++i) 9584 { 9585 daemon->worker_pool[i].shutdown = true; 9586 if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc)) 9587 { 9588 if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, 9589 "e")) 9590 MHD_PANIC (_ ("Failed to signal shutdown via inter-thread " \ 9591 "communication channel.\n")); 9592 } 9593 else 9594 mhd_assert (MHD_INVALID_SOCKET != fd); 9595 } 9596 #ifdef HAVE_LISTEN_SHUTDOWN 9597 if (MHD_INVALID_SOCKET != fd) 9598 { 9599 (void) shutdown (fd, 9600 SHUT_RDWR); 9601 } 9602 #endif /* HAVE_LISTEN_SHUTDOWN */ 9603 for (i = 0; i < daemon->worker_pool_size; ++i) 9604 { 9605 MHD_stop_daemon (&daemon->worker_pool[i]); 9606 } 9607 free (daemon->worker_pool); 9608 mhd_assert (MHD_ITC_IS_INVALID_ (daemon->itc)); 9609 #ifdef EPOLL_SUPPORT 9610 mhd_assert (-1 == daemon->epoll_fd); 9611 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 9612 mhd_assert (-1 == daemon->epoll_upgrade_fd); 9613 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 9614 #endif /* EPOLL_SUPPORT */ 9615 } 9616 else 9617 #endif 9618 { /* Worker daemon or single daemon. */ 9619 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9620 if (MHD_D_IS_USING_THREADS_ (daemon)) 9621 { /* Worker daemon or single daemon with internal thread(s). */ 9622 mhd_assert (0 == daemon->worker_pool_size); 9623 /* Separate thread(s) is used for polling sockets. */ 9624 if (MHD_ITC_IS_VALID_ (daemon->itc)) 9625 { 9626 if (! MHD_itc_activate_ (daemon->itc, 9627 "e")) 9628 MHD_PANIC (_ ("Failed to signal shutdown via inter-thread " \ 9629 "communication channel.\n")); 9630 } 9631 else 9632 { 9633 #ifdef HAVE_LISTEN_SHUTDOWN 9634 if (MHD_INVALID_SOCKET != fd) 9635 { 9636 if (NULL == daemon->master) 9637 (void) shutdown (fd, 9638 SHUT_RDWR); 9639 } 9640 else 9641 #endif /* HAVE_LISTEN_SHUTDOWN */ 9642 mhd_assert (false); /* Should never happen */ 9643 } 9644 9645 if (! MHD_thread_handle_ID_join_thread_ (daemon->tid)) 9646 { 9647 MHD_PANIC (_ ("Failed to join a thread.\n")); 9648 } 9649 /* close_all_connections() was called in daemon thread. */ 9650 } 9651 else 9652 #endif 9653 { 9654 /* No internal threads are used for polling sockets. */ 9655 close_all_connections (daemon); 9656 } 9657 mhd_assert (NULL == daemon->connections_head); 9658 mhd_assert (NULL == daemon->cleanup_head); 9659 mhd_assert (NULL == daemon->suspended_connections_head); 9660 mhd_assert (NULL == daemon->new_connections_head); 9661 #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT) 9662 mhd_assert (NULL == daemon->urh_head); 9663 #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */ 9664 9665 if (MHD_ITC_IS_VALID_ (daemon->itc)) 9666 MHD_itc_destroy_chk_ (daemon->itc); 9667 9668 #ifdef EPOLL_SUPPORT 9669 if (MHD_D_IS_USING_EPOLL_ (daemon) && 9670 (-1 != daemon->epoll_fd) ) 9671 MHD_socket_close_chk_ (daemon->epoll_fd); 9672 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 9673 if (MHD_D_IS_USING_EPOLL_ (daemon) && 9674 (-1 != daemon->epoll_upgrade_fd) ) 9675 MHD_socket_close_chk_ (daemon->epoll_upgrade_fd); 9676 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 9677 #endif /* EPOLL_SUPPORT */ 9678 9679 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9680 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); 9681 MHD_mutex_destroy_chk_ (&daemon->epoll_listen_mutex); 9682 MHD_mutex_destroy_chk_ (&daemon->new_connections_mutex); 9683 #endif 9684 } 9685 9686 if (NULL == daemon->master) 9687 { /* Cleanup that should be done only one time in master/single daemon. 9688 * Do not perform this cleanup in worker daemons. */ 9689 9690 if (MHD_INVALID_SOCKET != fd) 9691 MHD_socket_close_chk_ (fd); 9692 9693 /* TLS clean up */ 9694 #ifdef HTTPS_SUPPORT 9695 if (daemon->have_dhparams) 9696 { 9697 gnutls_dh_params_deinit (daemon->https_mem_dhparams); 9698 daemon->have_dhparams = false; 9699 } 9700 if (0 != (daemon->options & MHD_USE_TLS)) 9701 { 9702 gnutls_priority_deinit (daemon->priority_cache); 9703 if (daemon->x509_cred) 9704 gnutls_certificate_free_credentials (daemon->x509_cred); 9705 if (daemon->psk_cred) 9706 gnutls_psk_free_server_credentials (daemon->psk_cred); 9707 } 9708 #endif /* HTTPS_SUPPORT */ 9709 9710 #ifdef DAUTH_SUPPORT 9711 free (daemon->digest_auth_random_copy); 9712 free (daemon->nnc); 9713 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9714 MHD_mutex_destroy_chk_ (&daemon->nnc_lock); 9715 #endif 9716 #endif 9717 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9718 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 9719 #endif 9720 free (daemon); 9721 } 9722 } 9723 9724 9725 /** 9726 * Obtain information about the given daemon. 9727 * The returned pointer is invalidated with the next call of this function or 9728 * when the daemon is stopped. 9729 * 9730 * @param daemon what daemon to get information about 9731 * @param info_type what information is desired? 9732 * @param ... depends on @a info_type 9733 * @return NULL if this information is not available 9734 * (or if the @a info_type is unknown) 9735 * @ingroup specialized 9736 */ 9737 _MHD_EXTERN const union MHD_DaemonInfo * 9738 MHD_get_daemon_info (struct MHD_Daemon *daemon, 9739 enum MHD_DaemonInfoType info_type, 9740 ...) 9741 { 9742 if (NULL == daemon) 9743 return NULL; 9744 9745 mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 9746 (NULL != daemon->worker_pool) || \ 9747 (MHD_thread_handle_ID_is_valid_handle_ (daemon->tid))); 9748 mhd_assert (((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) && 9749 (NULL == daemon->worker_pool)) || \ 9750 (! MHD_thread_handle_ID_is_valid_handle_ (daemon->tid))); 9751 9752 switch (info_type) 9753 { 9754 case MHD_DAEMON_INFO_KEY_SIZE: 9755 return NULL; /* no longer supported */ 9756 case MHD_DAEMON_INFO_MAC_KEY_SIZE: 9757 return NULL; /* no longer supported */ 9758 case MHD_DAEMON_INFO_LISTEN_FD: 9759 daemon->daemon_info_dummy_listen_fd.listen_fd = daemon->listen_fd; 9760 return &daemon->daemon_info_dummy_listen_fd; 9761 case MHD_DAEMON_INFO_EPOLL_FD: 9762 #ifdef EPOLL_SUPPORT 9763 daemon->daemon_info_dummy_epoll_fd.epoll_fd = daemon->epoll_fd; 9764 return &daemon->daemon_info_dummy_epoll_fd; 9765 #else /* ! EPOLL_SUPPORT */ 9766 return NULL; 9767 #endif /* ! EPOLL_SUPPORT */ 9768 case MHD_DAEMON_INFO_CURRENT_CONNECTIONS: 9769 if (! MHD_D_IS_THREAD_SAFE_ (daemon)) 9770 MHD_cleanup_connections (daemon); 9771 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9772 else if (daemon->worker_pool) 9773 { 9774 unsigned int i; 9775 /* Collect the connection information stored in the workers. */ 9776 daemon->connections = 0; 9777 for (i = 0; i < daemon->worker_pool_size; i++) 9778 { 9779 /* FIXME: next line is thread-safe only if read is atomic. */ 9780 daemon->connections += daemon->worker_pool[i].connections; 9781 } 9782 } 9783 #endif 9784 daemon->daemon_info_dummy_num_connections.num_connections 9785 = daemon->connections; 9786 return &daemon->daemon_info_dummy_num_connections; 9787 case MHD_DAEMON_INFO_FLAGS: 9788 daemon->daemon_info_dummy_flags.flags = daemon->options; 9789 return &daemon->daemon_info_dummy_flags; 9790 case MHD_DAEMON_INFO_BIND_PORT: 9791 daemon->daemon_info_dummy_port.port = daemon->port; 9792 return &daemon->daemon_info_dummy_port; 9793 default: 9794 return NULL; 9795 } 9796 } 9797 9798 9799 /** 9800 * Obtain the version of this library 9801 * 9802 * @return static version string, e.g. "0.9.9" 9803 * @ingroup specialized 9804 */ 9805 _MHD_EXTERN const char * 9806 MHD_get_version (void) 9807 { 9808 #ifdef PACKAGE_VERSION 9809 return PACKAGE_VERSION; 9810 #else /* !PACKAGE_VERSION */ 9811 static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0"; 9812 if (0 == ver[0]) 9813 { 9814 int res = MHD_snprintf_ (ver, 9815 sizeof(ver), 9816 "%x.%x.%x", 9817 (int) (((uint32_t) MHD_VERSION >> 24) & 0xFF), 9818 (int) (((uint32_t) MHD_VERSION >> 16) & 0xFF), 9819 (int) (((uint32_t) MHD_VERSION >> 8) & 0xFF)); 9820 if ((0 >= res) || (sizeof(ver) <= res)) 9821 return "0.0.0"; /* Can't return real version */ 9822 } 9823 return ver; 9824 #endif /* !PACKAGE_VERSION */ 9825 } 9826 9827 9828 /** 9829 * Obtain the version of this library as a binary value. 9830 * 9831 * @return version binary value, e.g. "0x00090900" (#MHD_VERSION of 9832 * compiled MHD binary) 9833 * @note Available since #MHD_VERSION 0x00097601 9834 * @ingroup specialized 9835 */ 9836 _MHD_EXTERN uint32_t 9837 MHD_get_version_bin (void) 9838 { 9839 return (uint32_t) MHD_VERSION; 9840 } 9841 9842 9843 /** 9844 * Get information about supported MHD features. 9845 * Indicate that MHD was compiled with or without support for 9846 * particular feature. Some features require additional support 9847 * by kernel. Kernel support is not checked by this function. 9848 * 9849 * @param feature type of requested information 9850 * @return #MHD_YES if feature is supported by MHD, #MHD_NO if 9851 * feature is not supported or feature is unknown. 9852 * @ingroup specialized 9853 */ 9854 _MHD_EXTERN enum MHD_Result 9855 MHD_is_feature_supported (enum MHD_FEATURE feature) 9856 { 9857 switch (feature) 9858 { 9859 case MHD_FEATURE_MESSAGES: 9860 #ifdef HAVE_MESSAGES 9861 return MHD_YES; 9862 #else 9863 return MHD_NO; 9864 #endif 9865 case MHD_FEATURE_TLS: 9866 #ifdef HTTPS_SUPPORT 9867 return MHD_YES; 9868 #else /* ! HTTPS_SUPPORT */ 9869 return MHD_NO; 9870 #endif /* ! HTTPS_SUPPORT */ 9871 case MHD_FEATURE_HTTPS_CERT_CALLBACK: 9872 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3 9873 return MHD_YES; 9874 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */ 9875 return MHD_NO; 9876 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */ 9877 case MHD_FEATURE_HTTPS_CERT_CALLBACK2: 9878 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030603 9879 return MHD_YES; 9880 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */ 9881 return MHD_NO; 9882 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */ 9883 case MHD_FEATURE_IPv6: 9884 #ifdef HAVE_INET6 9885 return MHD_YES; 9886 #else 9887 return MHD_NO; 9888 #endif 9889 case MHD_FEATURE_IPv6_ONLY: 9890 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) 9891 return MHD_YES; 9892 #else 9893 return MHD_NO; 9894 #endif 9895 case MHD_FEATURE_POLL: 9896 #ifdef HAVE_POLL 9897 return MHD_YES; 9898 #else 9899 return MHD_NO; 9900 #endif 9901 case MHD_FEATURE_EPOLL: 9902 #ifdef EPOLL_SUPPORT 9903 return MHD_YES; 9904 #else 9905 return MHD_NO; 9906 #endif 9907 case MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET: 9908 #ifdef HAVE_LISTEN_SHUTDOWN 9909 return MHD_YES; 9910 #else 9911 return MHD_NO; 9912 #endif 9913 case MHD_FEATURE_SOCKETPAIR: 9914 #ifdef _MHD_ITC_SOCKETPAIR 9915 return MHD_YES; 9916 #else 9917 return MHD_NO; 9918 #endif 9919 case MHD_FEATURE_TCP_FASTOPEN: 9920 #ifdef TCP_FASTOPEN 9921 return MHD_YES; 9922 #else 9923 return MHD_NO; 9924 #endif 9925 case MHD_FEATURE_BASIC_AUTH: 9926 #ifdef BAUTH_SUPPORT 9927 return MHD_YES; 9928 #else 9929 return MHD_NO; 9930 #endif 9931 case MHD_FEATURE_DIGEST_AUTH: 9932 #ifdef DAUTH_SUPPORT 9933 return MHD_YES; 9934 #else 9935 return MHD_NO; 9936 #endif 9937 case MHD_FEATURE_POSTPROCESSOR: 9938 #ifdef HAVE_POSTPROCESSOR 9939 return MHD_YES; 9940 #else 9941 return MHD_NO; 9942 #endif 9943 case MHD_FEATURE_HTTPS_KEY_PASSWORD: 9944 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111 9945 return MHD_YES; 9946 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */ 9947 return MHD_NO; 9948 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */ 9949 case MHD_FEATURE_LARGE_FILE: 9950 #if defined(HAVE_PREAD64) || defined(_WIN32) 9951 return MHD_YES; 9952 #elif defined(HAVE_PREAD) 9953 return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES; 9954 #elif defined(HAVE_LSEEK64) 9955 return MHD_YES; 9956 #else 9957 return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES; 9958 #endif 9959 case MHD_FEATURE_THREAD_NAMES: 9960 #if defined(MHD_USE_THREAD_NAME_) 9961 return MHD_YES; 9962 #else 9963 return MHD_NO; 9964 #endif 9965 case MHD_FEATURE_UPGRADE: 9966 #if defined(UPGRADE_SUPPORT) 9967 return MHD_YES; 9968 #else 9969 return MHD_NO; 9970 #endif 9971 case MHD_FEATURE_RESPONSES_SHARED_FD: 9972 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32) 9973 return MHD_YES; 9974 #else 9975 return MHD_NO; 9976 #endif 9977 case MHD_FEATURE_AUTODETECT_BIND_PORT: 9978 #ifdef MHD_USE_GETSOCKNAME 9979 return MHD_YES; 9980 #else 9981 return MHD_NO; 9982 #endif 9983 case MHD_FEATURE_AUTOSUPPRESS_SIGPIPE: 9984 #if defined(MHD_SEND_SPIPE_SUPPRESS_POSSIBLE) || \ 9985 ! defined(MHD_SEND_SPIPE_SUPPRESS_NEEDED) 9986 return MHD_YES; 9987 #else 9988 return MHD_NO; 9989 #endif 9990 case MHD_FEATURE_SENDFILE: 9991 #ifdef _MHD_HAVE_SENDFILE 9992 return MHD_YES; 9993 #else 9994 return MHD_NO; 9995 #endif 9996 case MHD_FEATURE_THREADS: 9997 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9998 return MHD_YES; 9999 #else 10000 return MHD_NO; 10001 #endif 10002 case MHD_FEATURE_COOKIE_PARSING: 10003 #if defined(COOKIE_SUPPORT) 10004 return MHD_YES; 10005 #else 10006 return MHD_NO; 10007 #endif 10008 case MHD_FEATURE_DIGEST_AUTH_RFC2069: 10009 #ifdef DAUTH_SUPPORT 10010 return MHD_YES; 10011 #else 10012 return MHD_NO; 10013 #endif 10014 case MHD_FEATURE_DIGEST_AUTH_MD5: 10015 #if defined(DAUTH_SUPPORT) && defined(MHD_MD5_SUPPORT) 10016 return MHD_YES; 10017 #else 10018 return MHD_NO; 10019 #endif 10020 case MHD_FEATURE_DIGEST_AUTH_SHA256: 10021 #if defined(DAUTH_SUPPORT) && defined(MHD_SHA256_SUPPORT) 10022 return MHD_YES; 10023 #else 10024 return MHD_NO; 10025 #endif 10026 case MHD_FEATURE_DIGEST_AUTH_SHA512_256: 10027 #if defined(DAUTH_SUPPORT) && defined(MHD_SHA512_256_SUPPORT) 10028 return MHD_YES; 10029 #else 10030 return MHD_NO; 10031 #endif 10032 case MHD_FEATURE_DIGEST_AUTH_AUTH_INT: 10033 #ifdef DAUTH_SUPPORT 10034 return MHD_NO; 10035 #else 10036 return MHD_NO; 10037 #endif 10038 case MHD_FEATURE_DIGEST_AUTH_ALGO_SESSION: 10039 #ifdef DAUTH_SUPPORT 10040 return MHD_NO; 10041 #else 10042 return MHD_NO; 10043 #endif 10044 case MHD_FEATURE_DIGEST_AUTH_USERHASH: 10045 #ifdef DAUTH_SUPPORT 10046 return MHD_YES; 10047 #else 10048 return MHD_NO; 10049 #endif 10050 case MHD_FEATURE_EXTERN_HASH: 10051 #if defined(MHD_MD5_TLSLIB) || defined(MHD_SHA256_TLSLIB) 10052 return MHD_YES; 10053 #else 10054 return MHD_NO; 10055 #endif 10056 case MHD_FEATURE_DEBUG_BUILD: 10057 #ifdef _DEBUG 10058 return MHD_YES; 10059 #else 10060 return MHD_NO; 10061 #endif 10062 case MHD_FEATURE_FLEXIBLE_FD_SETSIZE: 10063 #ifdef HAS_FD_SETSIZE_OVERRIDABLE 10064 return MHD_YES; 10065 #else /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 10066 return MHD_NO; 10067 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 10068 10069 default: 10070 break; 10071 } 10072 return MHD_NO; 10073 } 10074 10075 10076 #ifdef MHD_HTTPS_REQUIRE_GCRYPT 10077 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600 10078 #if defined(MHD_USE_POSIX_THREADS) 10079 GCRY_THREAD_OPTION_PTHREAD_IMPL; 10080 #elif defined(MHD_W32_MUTEX_) 10081 10082 static int 10083 gcry_w32_mutex_init (void **ppmtx) 10084 { 10085 *ppmtx = malloc (sizeof (MHD_mutex_)); 10086 10087 if (NULL == *ppmtx) 10088 return ENOMEM; 10089 if (! MHD_mutex_init_ ((MHD_mutex_ *) *ppmtx)) 10090 { 10091 free (*ppmtx); 10092 *ppmtx = NULL; 10093 return EPERM; 10094 } 10095 10096 return 0; 10097 } 10098 10099 10100 static int 10101 gcry_w32_mutex_destroy (void **ppmtx) 10102 { 10103 int res = (MHD_mutex_destroy_ ((MHD_mutex_ *) *ppmtx)) ? 0 : EINVAL; 10104 free (*ppmtx); 10105 return res; 10106 } 10107 10108 10109 static int 10110 gcry_w32_mutex_lock (void **ppmtx) 10111 { 10112 return MHD_mutex_lock_ ((MHD_mutex_ *) *ppmtx) ? 0 : EINVAL; 10113 } 10114 10115 10116 static int 10117 gcry_w32_mutex_unlock (void **ppmtx) 10118 { 10119 return MHD_mutex_unlock_ ((MHD_mutex_ *) *ppmtx) ? 0 : EINVAL; 10120 } 10121 10122 10123 static struct gcry_thread_cbs gcry_threads_w32 = { 10124 (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)), 10125 NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy, 10126 gcry_w32_mutex_lock, gcry_w32_mutex_unlock, 10127 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL 10128 }; 10129 10130 #endif /* defined(MHD_W32_MUTEX_) */ 10131 #endif /* HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600 */ 10132 #endif /* MHD_HTTPS_REQUIRE_GCRYPT */ 10133 10134 /** 10135 * Initialize do setup work. 10136 */ 10137 void 10138 MHD_init (void) 10139 { 10140 #if defined(MHD_WINSOCK_SOCKETS) 10141 WSADATA wsd; 10142 #endif /* MHD_WINSOCK_SOCKETS */ 10143 10144 MHD_set_panic_func (NULL, NULL); 10145 10146 #if defined(MHD_WINSOCK_SOCKETS) 10147 if (0 != WSAStartup (MAKEWORD (2, 2), &wsd)) 10148 MHD_PANIC (_ ("Failed to initialize winsock.\n")); 10149 if ((2 != LOBYTE (wsd.wVersion)) && (2 != HIBYTE (wsd.wVersion))) 10150 MHD_PANIC (_ ("Winsock version 2.2 is not available.\n")); 10151 #endif /* MHD_WINSOCK_SOCKETS */ 10152 #ifdef HTTPS_SUPPORT 10153 #ifdef MHD_HTTPS_REQUIRE_GCRYPT 10154 #if GCRYPT_VERSION_NUMBER < 0x010600 10155 #if GNUTLS_VERSION_NUMBER <= 0x020b00 10156 #if defined(MHD_USE_POSIX_THREADS) 10157 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS, 10158 &gcry_threads_pthread)) 10159 MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt.\n")); 10160 #elif defined(MHD_W32_MUTEX_) 10161 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS, 10162 &gcry_threads_w32)) 10163 MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt.\n")); 10164 #endif /* defined(MHD_W32_MUTEX_) */ 10165 #endif /* GNUTLS_VERSION_NUMBER <= 0x020b00 */ 10166 gcry_check_version (NULL); 10167 #else 10168 if (NULL == gcry_check_version ("1.6.0")) 10169 MHD_PANIC (_ ("libgcrypt is too old. MHD was compiled for " \ 10170 "libgcrypt 1.6.0 or newer.\n")); 10171 #endif 10172 #endif /* MHD_HTTPS_REQUIRE_GCRYPT */ 10173 gnutls_global_init (); 10174 #endif /* HTTPS_SUPPORT */ 10175 MHD_monotonic_sec_counter_init (); 10176 MHD_send_init_static_vars_ (); 10177 MHD_init_mem_pools_ (); 10178 /* Check whether sizes were correctly detected by configure */ 10179 #ifdef _DEBUG 10180 if (1) 10181 { 10182 struct timeval tv; 10183 mhd_assert (sizeof(tv.tv_sec) == SIZEOF_STRUCT_TIMEVAL_TV_SEC); 10184 } 10185 #endif /* _DEBUG */ 10186 mhd_assert (sizeof(uint64_t) == SIZEOF_UINT64_T); 10187 } 10188 10189 10190 void 10191 MHD_fini (void) 10192 { 10193 #ifdef HTTPS_SUPPORT 10194 gnutls_global_deinit (); 10195 #endif /* HTTPS_SUPPORT */ 10196 #if defined(MHD_WINSOCK_SOCKETS) 10197 WSACleanup (); 10198 #endif /* MHD_WINSOCK_SOCKETS */ 10199 MHD_monotonic_sec_counter_finish (); 10200 } 10201 10202 10203 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED 10204 _SET_INIT_AND_DEINIT_FUNCS (MHD_init, MHD_fini); 10205 #endif /* _AUTOINIT_FUNCS_ARE_SUPPORTED */ 10206 10207 /* end of daemon.c */