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