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