daemon.c (320944B)
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 if ( (NULL != daemon->notify_completed) && 3537 (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) && 3538 (pos->rq.client_aware) ) 3539 { 3540 daemon->notify_completed (daemon->notify_completed_cls, 3541 pos, 3542 &pos->rq.client_context, 3543 MHD_REQUEST_TERMINATED_COMPLETED_OK); 3544 pos->rq.client_aware = false; 3545 } 3546 DLL_insert (daemon->cleanup_head, 3547 daemon->cleanup_tail, 3548 pos); 3549 daemon->data_already_pending = true; 3550 } 3551 #endif /* UPGRADE_SUPPORT */ 3552 pos->resuming = false; 3553 } 3554 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3555 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 3556 #endif 3557 if ( (used_thr_p_c) && 3558 (MHD_NO != ret) ) 3559 { /* Wake up suspended connections. */ 3560 if (! MHD_itc_activate_ (daemon->itc, 3561 "w")) 3562 { 3563 #ifdef HAVE_MESSAGES 3564 MHD_DLOG (daemon, 3565 _ ("Failed to signal resume of connection via " \ 3566 "inter-thread communication channel.\n")); 3567 #endif 3568 } 3569 } 3570 return ret; 3571 } 3572 3573 3574 /** 3575 * Add another client connection to the set of connections managed by 3576 * MHD. This API is usually not needed (since MHD will accept inbound 3577 * connections on the server socket). Use this API in special cases, 3578 * for example if your HTTP server is behind NAT and needs to connect 3579 * out to the HTTP client, or if you are building a proxy. 3580 * 3581 * If you use this API in conjunction with a internal select or a 3582 * thread pool, you must set the option 3583 * #MHD_USE_ITC to ensure that the freshly added 3584 * connection is immediately processed by MHD. 3585 * 3586 * The given client socket will be managed (and closed!) by MHD after 3587 * this call and must no longer be used directly by the application 3588 * afterwards. 3589 * 3590 * @param daemon daemon that manages the connection 3591 * @param client_socket socket to manage (MHD will expect 3592 * to receive an HTTP request from this socket next). 3593 * @param addr IP address of the client 3594 * @param addrlen number of bytes in @a addr 3595 * @return #MHD_YES on success, #MHD_NO if this daemon could 3596 * not handle the connection (i.e. malloc() failed, etc). 3597 * The socket will be closed in any case; `errno` is 3598 * set to indicate further details about the error. 3599 * @ingroup specialized 3600 */ 3601 _MHD_EXTERN enum MHD_Result 3602 MHD_add_connection (struct MHD_Daemon *daemon, 3603 MHD_socket client_socket, 3604 const struct sockaddr *addr, 3605 socklen_t addrlen) 3606 { 3607 bool sk_nonbl; 3608 bool sk_spipe_supprs; 3609 struct sockaddr_storage addrstorage; 3610 3611 /* TODO: fix atomic value reading */ 3612 if ((! MHD_D_IS_THREAD_SAFE_ (daemon)) && 3613 (daemon->connection_limit <= daemon->connections)) 3614 MHD_cleanup_connections (daemon); 3615 3616 #ifdef HAVE_MESSAGES 3617 if (MHD_D_IS_USING_THREADS_ (daemon) && 3618 (0 == (daemon->options & MHD_USE_ITC))) 3619 { 3620 MHD_DLOG (daemon, 3621 _ ("MHD_add_connection() has been called for daemon started" 3622 " without MHD_USE_ITC flag.\nDaemon will not process newly" 3623 " added connection until any activity occurs in already" 3624 " added sockets.\n")); 3625 } 3626 #endif /* HAVE_MESSAGES */ 3627 if (0 != addrlen) 3628 { 3629 if (AF_INET == addr->sa_family) 3630 { 3631 if (sizeof(struct sockaddr_in) > (size_t) addrlen) 3632 { 3633 #ifdef HAVE_MESSAGES 3634 MHD_DLOG (daemon, 3635 _ ("MHD_add_connection() has been called with " 3636 "incorrect 'addrlen' value.\n")); 3637 #endif /* HAVE_MESSAGES */ 3638 return MHD_NO; 3639 } 3640 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 3641 if ((0 != addr->sa_len) && 3642 (sizeof(struct sockaddr_in) > (size_t) addr->sa_len) ) 3643 { 3644 #ifdef HAVE_MESSAGES 3645 MHD_DLOG (daemon, 3646 _ ("MHD_add_connection() has been called with " \ 3647 "non-zero value of 'sa_len' member of " \ 3648 "'struct sockaddr' which does not match 'sa_family'.\n")); 3649 #endif /* HAVE_MESSAGES */ 3650 return MHD_NO; 3651 } 3652 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ 3653 } 3654 #ifdef HAVE_INET6 3655 if (AF_INET6 == addr->sa_family) 3656 { 3657 if (sizeof(struct sockaddr_in6) > (size_t) addrlen) 3658 { 3659 #ifdef HAVE_MESSAGES 3660 MHD_DLOG (daemon, 3661 _ ("MHD_add_connection() has been called with " 3662 "incorrect 'addrlen' value.\n")); 3663 #endif /* HAVE_MESSAGES */ 3664 return MHD_NO; 3665 } 3666 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 3667 if ((0 != addr->sa_len) && 3668 (sizeof(struct sockaddr_in6) > (size_t) addr->sa_len) ) 3669 { 3670 #ifdef HAVE_MESSAGES 3671 MHD_DLOG (daemon, 3672 _ ("MHD_add_connection() has been called with " \ 3673 "non-zero value of 'sa_len' member of " \ 3674 "'struct sockaddr' which does not match 'sa_family'.\n")); 3675 #endif /* HAVE_MESSAGES */ 3676 return MHD_NO; 3677 } 3678 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ 3679 } 3680 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 3681 if ((0 != addr->sa_len) && 3682 (addrlen > addr->sa_len)) 3683 addrlen = (socklen_t) addr->sa_len; /* Use safest value */ 3684 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ 3685 #endif /* HAVE_INET6 */ 3686 } 3687 3688 if (! MHD_socket_nonblocking_ (client_socket)) 3689 { 3690 #ifdef HAVE_MESSAGES 3691 MHD_DLOG (daemon, 3692 _ ("Failed to set nonblocking mode on new client socket: %s\n"), 3693 MHD_socket_last_strerr_ ()); 3694 #endif 3695 sk_nonbl = false; 3696 } 3697 else 3698 sk_nonbl = true; 3699 3700 #ifndef MHD_WINSOCK_SOCKETS 3701 sk_spipe_supprs = false; 3702 #else /* MHD_WINSOCK_SOCKETS */ 3703 sk_spipe_supprs = true; /* Nothing to suppress on W32 */ 3704 #endif /* MHD_WINSOCK_SOCKETS */ 3705 #if defined(MHD_socket_nosignal_) 3706 if (! sk_spipe_supprs) 3707 sk_spipe_supprs = MHD_socket_nosignal_ (client_socket); 3708 if (! sk_spipe_supprs) 3709 { 3710 #ifdef HAVE_MESSAGES 3711 MHD_DLOG (daemon, 3712 _ ("Failed to suppress SIGPIPE on new client socket: %s\n"), 3713 MHD_socket_last_strerr_ ()); 3714 #else /* ! HAVE_MESSAGES */ 3715 (void) 0; /* Mute compiler warning */ 3716 #endif /* ! HAVE_MESSAGES */ 3717 #ifndef MSG_NOSIGNAL 3718 /* Application expects that SIGPIPE will be suppressed, 3719 * but suppression failed and SIGPIPE cannot be suppressed with send(). */ 3720 if (! daemon->sigpipe_blocked) 3721 { 3722 int err = MHD_socket_get_error_ (); 3723 MHD_socket_close_ (client_socket); 3724 MHD_socket_fset_error_ (err); 3725 return MHD_NO; 3726 } 3727 #endif /* MSG_NOSIGNAL */ 3728 } 3729 #endif /* MHD_socket_nosignal_ */ 3730 3731 if ( (0 != (daemon->options & MHD_USE_TURBO)) && 3732 (! MHD_socket_noninheritable_ (client_socket)) ) 3733 { 3734 #ifdef HAVE_MESSAGES 3735 MHD_DLOG (daemon, 3736 _ ("Failed to set noninheritable mode on new client socket.\n")); 3737 #endif 3738 } 3739 3740 /* Copy to sockaddr_storage structure to avoid alignment problems */ 3741 if (0 < addrlen) 3742 memcpy (&addrstorage, addr, (size_t) addrlen); 3743 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 3744 addrstorage.ss_len = addrlen; /* Force set the right length */ 3745 #endif /* HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN */ 3746 3747 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3748 if (NULL != daemon->worker_pool) 3749 { 3750 unsigned int i; 3751 /* have a pool, try to find a pool with capacity; we use the 3752 socket as the initial offset into the pool for load 3753 balancing */ 3754 for (i = 0; i < daemon->worker_pool_size; ++i) 3755 { 3756 struct MHD_Daemon *const worker = 3757 &daemon->worker_pool[(i + (unsigned int) client_socket) 3758 % daemon->worker_pool_size]; 3759 if (worker->connections < worker->connection_limit) 3760 return internal_add_connection (worker, 3761 client_socket, 3762 &addrstorage, 3763 addrlen, 3764 true, 3765 sk_nonbl, 3766 sk_spipe_supprs, 3767 _MHD_UNKNOWN); 3768 } 3769 /* all pools are at their connection limit, must refuse */ 3770 MHD_socket_close_chk_ (client_socket); 3771 #if defined(ENFILE) && (ENFILE + 0 != 0) 3772 errno = ENFILE; 3773 #endif 3774 return MHD_NO; 3775 } 3776 #endif /* MHD_USE_POSIX_THREADS || MHD_USE_W32_THREADS */ 3777 3778 return internal_add_connection (daemon, 3779 client_socket, 3780 &addrstorage, 3781 addrlen, 3782 true, 3783 sk_nonbl, 3784 sk_spipe_supprs, 3785 _MHD_UNKNOWN); 3786 } 3787 3788 3789 /** 3790 * Accept an incoming connection and create the MHD_Connection object for 3791 * it. This function also enforces policy by way of checking with the 3792 * accept policy callback. 3793 * @remark To be called only from thread that process 3794 * daemon's select()/poll()/etc. 3795 * 3796 * @param daemon handle with the listen socket 3797 * @return #MHD_YES on success (connections denied by policy or due 3798 * to 'out of memory' and similar errors) are still considered 3799 * successful as far as #MHD_accept_connection() is concerned); 3800 * a return code of #MHD_NO only refers to the actual 3801 * accept() system call. 3802 */ 3803 static enum MHD_Result 3804 MHD_accept_connection (struct MHD_Daemon *daemon) 3805 { 3806 struct sockaddr_storage addrstorage; 3807 socklen_t addrlen; 3808 MHD_socket s; 3809 MHD_socket fd; 3810 bool sk_nonbl; 3811 bool sk_spipe_supprs; 3812 bool sk_cloexec; 3813 enum MHD_tristate sk_non_ip; 3814 #if defined(_DEBUG) && defined (USE_ACCEPT4) 3815 const bool use_accept4 = ! daemon->avoid_accept4; 3816 #elif defined (USE_ACCEPT4) 3817 static const bool use_accept4 = true; 3818 #else /* ! USE_ACCEPT4 && ! _DEBUG */ 3819 static const bool use_accept4 = false; 3820 #endif /* ! USE_ACCEPT4 && ! _DEBUG */ 3821 3822 #ifdef MHD_USE_THREADS 3823 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 3824 MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); 3825 mhd_assert (NULL == daemon->worker_pool); 3826 #endif /* MHD_USE_THREADS */ 3827 3828 if ( (MHD_INVALID_SOCKET == (fd = daemon->listen_fd)) || 3829 (daemon->was_quiesced) ) 3830 return MHD_NO; 3831 3832 addrlen = (socklen_t) sizeof (addrstorage); 3833 memset (&addrstorage, 3834 0, 3835 (size_t) addrlen); 3836 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 3837 addrstorage.ss_len = addrlen; 3838 #endif /* HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN */ 3839 3840 /* Initialise with default values to avoid compiler warnings */ 3841 sk_nonbl = false; 3842 sk_spipe_supprs = false; 3843 sk_cloexec = false; 3844 s = MHD_INVALID_SOCKET; 3845 3846 #ifdef USE_ACCEPT4 3847 if (use_accept4 && 3848 (MHD_INVALID_SOCKET != 3849 (s = accept4 (fd, 3850 (struct sockaddr *) &addrstorage, 3851 &addrlen, 3852 SOCK_CLOEXEC_OR_ZERO | SOCK_NONBLOCK_OR_ZERO 3853 | SOCK_NOSIGPIPE_OR_ZERO)))) 3854 { 3855 sk_nonbl = (SOCK_NONBLOCK_OR_ZERO != 0); 3856 #ifndef MHD_WINSOCK_SOCKETS 3857 sk_spipe_supprs = (SOCK_NOSIGPIPE_OR_ZERO != 0); 3858 #else /* MHD_WINSOCK_SOCKETS */ 3859 sk_spipe_supprs = true; /* Nothing to suppress on W32 */ 3860 #endif /* MHD_WINSOCK_SOCKETS */ 3861 sk_cloexec = (SOCK_CLOEXEC_OR_ZERO != 0); 3862 } 3863 #endif /* USE_ACCEPT4 */ 3864 #if defined(_DEBUG) || ! defined(USE_ACCEPT4) 3865 if (! use_accept4 && 3866 (MHD_INVALID_SOCKET != 3867 (s = accept (fd, 3868 (struct sockaddr *) &addrstorage, 3869 &addrlen)))) 3870 { 3871 #ifdef MHD_ACCEPT_INHERIT_NONBLOCK 3872 sk_nonbl = daemon->listen_nonblk; 3873 #else /* ! MHD_ACCEPT_INHERIT_NONBLOCK */ 3874 sk_nonbl = false; 3875 #endif /* ! MHD_ACCEPT_INHERIT_NONBLOCK */ 3876 #ifndef MHD_WINSOCK_SOCKETS 3877 sk_spipe_supprs = false; 3878 #else /* MHD_WINSOCK_SOCKETS */ 3879 sk_spipe_supprs = true; /* Nothing to suppress on W32 */ 3880 #endif /* MHD_WINSOCK_SOCKETS */ 3881 sk_cloexec = false; 3882 } 3883 #endif /* _DEBUG || !USE_ACCEPT4 */ 3884 3885 if (MHD_INVALID_SOCKET == s) 3886 { 3887 const int err = MHD_socket_get_error_ (); 3888 3889 /* This could be a common occurrence with multiple worker threads */ 3890 if (MHD_SCKT_ERR_IS_ (err, 3891 MHD_SCKT_EINVAL_)) 3892 return MHD_NO; /* can happen during shutdown */ 3893 if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_ (err)) 3894 return MHD_NO; /* do not print error if client just disconnected early */ 3895 #ifdef HAVE_MESSAGES 3896 if (! MHD_SCKT_ERR_IS_EAGAIN_ (err) ) 3897 MHD_DLOG (daemon, 3898 _ ("Error accepting connection: %s\n"), 3899 MHD_socket_strerr_ (err)); 3900 #endif 3901 if (MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) ) 3902 { 3903 /* system/process out of resources */ 3904 if (0 == daemon->connections) 3905 { 3906 #ifdef HAVE_MESSAGES 3907 /* Not setting 'at_limit' flag, as there is no way it 3908 would ever be cleared. Instead trying to produce 3909 bit fat ugly warning. */ 3910 MHD_DLOG (daemon, 3911 _ ("Hit process or system resource limit at FIRST " \ 3912 "connection. This is really bad as there is no sane " \ 3913 "way to proceed. Will try busy waiting for system " \ 3914 "resources to become magically available.\n")); 3915 #endif 3916 } 3917 else 3918 { 3919 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3920 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 3921 #endif 3922 daemon->at_limit = true; 3923 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3924 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 3925 #endif 3926 #ifdef HAVE_MESSAGES 3927 MHD_DLOG (daemon, 3928 _ ("Hit process or system resource limit at %u " \ 3929 "connections, temporarily suspending accept(). " \ 3930 "Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"), 3931 (unsigned int) daemon->connections); 3932 #endif 3933 } 3934 } 3935 return MHD_NO; 3936 } 3937 3938 sk_non_ip = daemon->listen_is_unix; 3939 if (0 >= addrlen) 3940 { 3941 #ifdef HAVE_MESSAGES 3942 if (_MHD_NO != daemon->listen_is_unix) 3943 MHD_DLOG (daemon, 3944 _ ("Accepted socket has zero-length address. " 3945 "Processing the new socket as a socket with " \ 3946 "unknown type.\n")); 3947 #endif 3948 addrlen = 0; 3949 sk_non_ip = _MHD_YES; /* IP-type addresses have non-zero length */ 3950 } 3951 if (((socklen_t) sizeof (addrstorage)) < addrlen) 3952 { 3953 /* Should not happen as 'sockaddr_storage' must be large enough to 3954 * store any address supported by the system. */ 3955 #ifdef HAVE_MESSAGES 3956 MHD_DLOG (daemon, 3957 _ ("Accepted socket address is larger than expected by " \ 3958 "system headers. Processing the new socket as a socket with " \ 3959 "unknown type.\n")); 3960 #endif 3961 addrlen = 0; 3962 sk_non_ip = _MHD_YES; /* IP-type addresses must fit */ 3963 } 3964 3965 if (! sk_nonbl && ! MHD_socket_nonblocking_ (s)) 3966 { 3967 #ifdef HAVE_MESSAGES 3968 MHD_DLOG (daemon, 3969 _ ("Failed to set nonblocking mode on incoming connection " \ 3970 "socket: %s\n"), 3971 MHD_socket_last_strerr_ ()); 3972 #else /* ! HAVE_MESSAGES */ 3973 (void) 0; /* Mute compiler warning */ 3974 #endif /* ! HAVE_MESSAGES */ 3975 } 3976 else 3977 sk_nonbl = true; 3978 3979 if (! sk_cloexec && ! MHD_socket_noninheritable_ (s)) 3980 { 3981 #ifdef HAVE_MESSAGES 3982 MHD_DLOG (daemon, 3983 _ ("Failed to set noninheritable mode on incoming connection " \ 3984 "socket.\n")); 3985 #else /* ! HAVE_MESSAGES */ 3986 (void) 0; /* Mute compiler warning */ 3987 #endif /* ! HAVE_MESSAGES */ 3988 } 3989 3990 #if defined(MHD_socket_nosignal_) 3991 if (! sk_spipe_supprs && ! MHD_socket_nosignal_ (s)) 3992 { 3993 #ifdef HAVE_MESSAGES 3994 MHD_DLOG (daemon, 3995 _ ("Failed to suppress SIGPIPE on incoming connection " \ 3996 "socket: %s\n"), 3997 MHD_socket_last_strerr_ ()); 3998 #else /* ! HAVE_MESSAGES */ 3999 (void) 0; /* Mute compiler warning */ 4000 #endif /* ! HAVE_MESSAGES */ 4001 #ifndef MSG_NOSIGNAL 4002 /* Application expects that SIGPIPE will be suppressed, 4003 * but suppression failed and SIGPIPE cannot be suppressed with send(). */ 4004 if (! daemon->sigpipe_blocked) 4005 { 4006 (void) MHD_socket_close_ (s); 4007 return MHD_NO; 4008 } 4009 #endif /* MSG_NOSIGNAL */ 4010 } 4011 else 4012 sk_spipe_supprs = true; 4013 #endif /* MHD_socket_nosignal_ */ 4014 #ifdef HAVE_MESSAGES 4015 #if _MHD_DEBUG_CONNECT 4016 MHD_DLOG (daemon, 4017 _ ("Accepted connection on socket %d\n"), 4018 s); 4019 #endif 4020 #endif 4021 (void) internal_add_connection (daemon, 4022 s, 4023 &addrstorage, 4024 addrlen, 4025 false, 4026 sk_nonbl, 4027 sk_spipe_supprs, 4028 sk_non_ip); 4029 return MHD_YES; 4030 } 4031 4032 4033 /** 4034 * Free resources associated with all closed connections. 4035 * (destroy responses, free buffers, etc.). All closed 4036 * connections are kept in the "cleanup" doubly-linked list. 4037 * @remark To be called only from thread that 4038 * process daemon's select()/poll()/etc. 4039 * 4040 * @param daemon daemon to clean up 4041 */ 4042 static void 4043 MHD_cleanup_connections (struct MHD_Daemon *daemon) 4044 { 4045 struct MHD_Connection *pos; 4046 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4047 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 4048 MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); 4049 mhd_assert (NULL == daemon->worker_pool); 4050 4051 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 4052 #endif 4053 while (NULL != (pos = daemon->cleanup_tail)) 4054 { 4055 DLL_remove (daemon->cleanup_head, 4056 daemon->cleanup_tail, 4057 pos); 4058 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4059 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 4060 if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) && 4061 (! pos->thread_joined) && 4062 (! MHD_thread_handle_ID_join_thread_ (pos->tid)) ) 4063 MHD_PANIC (_ ("Failed to join a thread.\n")); 4064 #endif 4065 #ifdef UPGRADE_SUPPORT 4066 cleanup_upgraded_connection (pos); 4067 #endif /* UPGRADE_SUPPORT */ 4068 MHD_pool_destroy (pos->pool); 4069 #ifdef HTTPS_SUPPORT 4070 if (NULL != pos->tls_session) 4071 gnutls_deinit (pos->tls_session); 4072 #endif /* HTTPS_SUPPORT */ 4073 4074 /* clean up the connection */ 4075 if (NULL != daemon->notify_connection) 4076 daemon->notify_connection (daemon->notify_connection_cls, 4077 pos, 4078 &pos->socket_context, 4079 MHD_CONNECTION_NOTIFY_CLOSED); 4080 MHD_ip_limit_del (daemon, 4081 pos->addr, 4082 pos->addr_len); 4083 #ifdef EPOLL_SUPPORT 4084 if (MHD_D_IS_USING_EPOLL_ (daemon)) 4085 { 4086 if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) 4087 { 4088 EDLL_remove (daemon->eready_head, 4089 daemon->eready_tail, 4090 pos); 4091 pos->epoll_state &= 4092 ~((enum MHD_EpollState) MHD_EPOLL_STATE_IN_EREADY_EDLL); 4093 } 4094 if ( (-1 != daemon->epoll_fd) && 4095 (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) ) 4096 { 4097 /* epoll documentation suggests that closing a FD 4098 automatically removes it from the epoll set; however, 4099 this is not true as if we fail to do manually remove it, 4100 we are still seeing an event for this fd in epoll, 4101 causing grief (use-after-free...) --- at least on my 4102 system. */ 4103 if (0 != epoll_ctl (daemon->epoll_fd, 4104 EPOLL_CTL_DEL, 4105 pos->socket_fd, 4106 NULL)) 4107 MHD_PANIC (_ ("Failed to remove FD from epoll set.\n")); 4108 pos->epoll_state &= 4109 ~((enum MHD_EpollState) 4110 MHD_EPOLL_STATE_IN_EPOLL_SET); 4111 } 4112 } 4113 #endif 4114 if (NULL != pos->rp.response) 4115 { 4116 MHD_destroy_response (pos->rp.response); 4117 pos->rp.response = NULL; 4118 } 4119 if (MHD_INVALID_SOCKET != pos->socket_fd) 4120 MHD_socket_close_chk_ (pos->socket_fd); 4121 if (NULL != pos->addr) 4122 free (pos->addr); 4123 free (pos); 4124 4125 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4126 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 4127 #endif 4128 daemon->connections--; 4129 daemon->at_limit = false; 4130 } 4131 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4132 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 4133 #endif 4134 } 4135 4136 4137 /** 4138 * Obtain timeout value for polling function for this daemon. 4139 * 4140 * This function set value to the amount of milliseconds for which polling 4141 * function (`select()`, `poll()` or epoll) should at most block, not the 4142 * timeout value set for connections. 4143 * 4144 * Any "external" sockets polling function must be called with the timeout 4145 * value provided by this function. Smaller timeout values can be used for 4146 * polling function if it is required for any reason, but using larger 4147 * timeout value or no timeout (indefinite timeout) when this function 4148 * return #MHD_YES will break MHD processing logic and result in "hung" 4149 * connections with data pending in network buffers and other problems. 4150 * 4151 * It is important to always use this function (or #MHD_get_timeout64(), 4152 * #MHD_get_timeout64s(), #MHD_get_timeout_i() functions) when "external" 4153 * polling is used. 4154 * If this function returns #MHD_YES then #MHD_run() (or #MHD_run_from_select()) 4155 * must be called right after return from polling function, regardless of 4156 * the states of MHD FDs. 4157 * 4158 * In practice, if #MHD_YES is returned then #MHD_run() (or 4159 * #MHD_run_from_select()) must be called not later than @a timeout 4160 * millisecond even if no activity is detected on sockets by sockets 4161 * polling function. 4162 * @remark To be called only from thread that process 4163 * daemon's select()/poll()/etc. 4164 * 4165 * @param daemon daemon to query for timeout 4166 * @param[out] timeout set to the timeout (in milliseconds) 4167 * @return #MHD_YES on success, #MHD_NO if timeouts are 4168 * not used and no data processing is pending. 4169 * @ingroup event 4170 */ 4171 _MHD_EXTERN enum MHD_Result 4172 MHD_get_timeout (struct MHD_Daemon *daemon, 4173 MHD_UNSIGNED_LONG_LONG *timeout) 4174 { 4175 uint64_t t64; 4176 if (MHD_NO == MHD_get_timeout64 (daemon, &t64)) 4177 return MHD_NO; 4178 4179 #if SIZEOF_UINT64_T > SIZEOF_UNSIGNED_LONG_LONG 4180 if (ULLONG_MAX <= t64) 4181 *timeout = ULLONG_MAX; 4182 else 4183 #endif /* SIZEOF_UINT64_T > SIZEOF_UNSIGNED_LONG_LONG */ 4184 *timeout = (MHD_UNSIGNED_LONG_LONG) t64; 4185 return MHD_YES; 4186 } 4187 4188 4189 /** 4190 * Obtain timeout value for external polling function for this daemon. 4191 * 4192 * This function set value to the amount of milliseconds for which polling 4193 * function (`select()`, `poll()` or epoll) should at most block, not the 4194 * timeout value set for connections. 4195 * 4196 * Any "external" sockets polling function must be called with the timeout 4197 * value provided by this function. Smaller timeout values can be used for 4198 * polling function if it is required for any reason, but using larger 4199 * timeout value or no timeout (indefinite timeout) when this function 4200 * return #MHD_YES will break MHD processing logic and result in "hung" 4201 * connections with data pending in network buffers and other problems. 4202 * 4203 * It is important to always use this function (or #MHD_get_timeout(), 4204 * #MHD_get_timeout64s(), #MHD_get_timeout_i() functions) when "external" 4205 * polling is used. 4206 * If this function returns #MHD_YES then #MHD_run() (or #MHD_run_from_select()) 4207 * must be called right after return from polling function, regardless of 4208 * the states of MHD FDs. 4209 * 4210 * In practice, if #MHD_YES is returned then #MHD_run() (or 4211 * #MHD_run_from_select()) must be called not later than @a timeout 4212 * millisecond even if no activity is detected on sockets by sockets 4213 * polling function. 4214 * @remark To be called only from thread that process 4215 * daemon's select()/poll()/etc. 4216 * 4217 * @param daemon daemon to query for timeout 4218 * @param[out] timeout64 the pointer to the variable to be set to the 4219 * timeout (in milliseconds) 4220 * @return #MHD_YES if timeout value has been set, 4221 * #MHD_NO if timeouts are not used and no data processing is pending. 4222 * @note Available since #MHD_VERSION 0x00097701 4223 * @ingroup event 4224 */ 4225 _MHD_EXTERN enum MHD_Result 4226 MHD_get_timeout64 (struct MHD_Daemon *daemon, 4227 uint64_t *timeout64) 4228 { 4229 uint64_t earliest_deadline; 4230 struct MHD_Connection *pos; 4231 struct MHD_Connection *earliest_tmot_conn; /**< the connection with earliest timeout */ 4232 4233 #ifdef MHD_USE_THREADS 4234 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 4235 MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); 4236 #endif /* MHD_USE_THREADS */ 4237 4238 if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) 4239 { 4240 #ifdef HAVE_MESSAGES 4241 MHD_DLOG (daemon, 4242 _ ("Illegal call to MHD_get_timeout.\n")); 4243 #endif 4244 return MHD_NO; 4245 } 4246 if (daemon->data_already_pending 4247 || (NULL != daemon->cleanup_head) 4248 || daemon->resuming 4249 || daemon->have_new 4250 || daemon->shutdown) 4251 { 4252 /* Some data or connection statuses already waiting to be processed. */ 4253 *timeout64 = 0; 4254 return MHD_YES; 4255 } 4256 #ifdef EPOLL_SUPPORT 4257 if (MHD_D_IS_USING_EPOLL_ (daemon) && 4258 ((NULL != daemon->eready_head) 4259 #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT) 4260 || (NULL != daemon->eready_urh_head) 4261 #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */ 4262 ) ) 4263 { 4264 /* Some connection(s) already have some data pending. */ 4265 *timeout64 = 0; 4266 return MHD_YES; 4267 } 4268 #endif /* EPOLL_SUPPORT */ 4269 4270 earliest_tmot_conn = NULL; 4271 earliest_deadline = 0; /* mute compiler warning */ 4272 /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */ 4273 pos = daemon->normal_timeout_tail; 4274 if ( (NULL != pos) && 4275 (0 != pos->connection_timeout_ms) ) 4276 { 4277 earliest_tmot_conn = pos; 4278 earliest_deadline = pos->last_activity + pos->connection_timeout_ms; 4279 } 4280 4281 for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX) 4282 { 4283 if (0 != pos->connection_timeout_ms) 4284 { 4285 if ( (NULL == earliest_tmot_conn) || 4286 (earliest_deadline - pos->last_activity > 4287 pos->connection_timeout_ms) ) 4288 { 4289 earliest_tmot_conn = pos; 4290 earliest_deadline = pos->last_activity + pos->connection_timeout_ms; 4291 } 4292 } 4293 } 4294 4295 if (NULL != earliest_tmot_conn) 4296 { 4297 *timeout64 = connection_get_wait (earliest_tmot_conn); 4298 return MHD_YES; 4299 } 4300 return MHD_NO; 4301 } 4302 4303 4304 #if defined(HAVE_POLL) || defined(EPOLL_SUPPORT) 4305 /** 4306 * Obtain timeout value for external polling function for this daemon. 4307 * 4308 * This function set value to the amount of milliseconds for which polling 4309 * function (`select()`, `poll()` or epoll) should at most block, not the 4310 * timeout value set for connections. 4311 * 4312 * Any "external" sockets polling function must be called with the timeout 4313 * value provided by this function (if returned value is non-negative). 4314 * Smaller timeout values can be used for polling function if it is required 4315 * for any reason, but using larger timeout value or no timeout (indefinite 4316 * timeout) when this function returns non-negative value will break MHD 4317 * processing logic and result in "hung" connections with data pending in 4318 * network buffers and other problems. 4319 * 4320 * It is important to always use this function (or #MHD_get_timeout(), 4321 * #MHD_get_timeout64(), #MHD_get_timeout_i() functions) when "external" 4322 * polling is used. 4323 * If this function returns non-negative value then #MHD_run() (or 4324 * #MHD_run_from_select()) must be called right after return from polling 4325 * function, regardless of the states of MHD FDs. 4326 * 4327 * In practice, if zero or positive value is returned then #MHD_run() (or 4328 * #MHD_run_from_select()) must be called not later than returned amount of 4329 * millisecond even if no activity is detected on sockets by sockets 4330 * polling function. 4331 * @remark To be called only from thread that process 4332 * daemon's select()/poll()/etc. 4333 * 4334 * @param daemon the daemon to query for timeout 4335 * @return -1 if connections' timeouts are not set and no data processing 4336 * is pending, so external polling function may wait for sockets 4337 * activity for indefinite amount of time, 4338 * otherwise returned value is the the maximum amount of millisecond 4339 * that external polling function must wait for the activity of FDs. 4340 * @note Available since #MHD_VERSION 0x00097701 4341 * @ingroup event 4342 */ 4343 _MHD_EXTERN int64_t 4344 MHD_get_timeout64s (struct MHD_Daemon *daemon) 4345 { 4346 uint64_t utimeout; 4347 if (MHD_NO == MHD_get_timeout64 (daemon, &utimeout)) 4348 return -1; 4349 if (INT64_MAX < utimeout) 4350 return INT64_MAX; 4351 4352 return (int64_t) utimeout; 4353 } 4354 4355 4356 /** 4357 * Obtain timeout value for external polling function for this daemon. 4358 * 4359 * This function set value to the amount of milliseconds for which polling 4360 * function (`select()`, `poll()` or epoll) should at most block, not the 4361 * timeout value set for connections. 4362 * 4363 * Any "external" sockets polling function must be called with the timeout 4364 * value provided by this function (if returned value is non-negative). 4365 * Smaller timeout values can be used for polling function if it is required 4366 * for any reason, but using larger timeout value or no timeout (indefinite 4367 * timeout) when this function returns non-negative value will break MHD 4368 * processing logic and result in "hung" connections with data pending in 4369 * network buffers and other problems. 4370 * 4371 * It is important to always use this function (or #MHD_get_timeout(), 4372 * #MHD_get_timeout64(), #MHD_get_timeout64s() functions) when "external" 4373 * polling is used. 4374 * If this function returns non-negative value then #MHD_run() (or 4375 * #MHD_run_from_select()) must be called right after return from polling 4376 * function, regardless of the states of MHD FDs. 4377 * 4378 * In practice, if zero or positive value is returned then #MHD_run() (or 4379 * #MHD_run_from_select()) must be called not later than returned amount of 4380 * millisecond even if no activity is detected on sockets by sockets 4381 * polling function. 4382 * @remark To be called only from thread that process 4383 * daemon's select()/poll()/etc. 4384 * 4385 * @param daemon the daemon to query for timeout 4386 * @return -1 if connections' timeouts are not set and no data processing 4387 * is pending, so external polling function may wait for sockets 4388 * activity for indefinite amount of time, 4389 * otherwise returned value is the the maximum amount of millisecond 4390 * (capped at INT_MAX) that external polling function must wait 4391 * for the activity of FDs. 4392 * @note Available since #MHD_VERSION 0x00097701 4393 * @ingroup event 4394 */ 4395 _MHD_EXTERN int 4396 MHD_get_timeout_i (struct MHD_Daemon *daemon) 4397 { 4398 #if SIZEOF_INT >= SIZEOF_INT64_T 4399 return MHD_get_timeout64s (daemon); 4400 #else /* SIZEOF_INT < SIZEOF_INT64_T */ 4401 const int64_t to64 = MHD_get_timeout64s (daemon); 4402 if (INT_MAX >= to64) 4403 return (int) to64; 4404 return INT_MAX; 4405 #endif /* SIZEOF_INT < SIZEOF_INT64_T */ 4406 } 4407 4408 4409 /** 4410 * Obtain timeout value for polling function for this daemon. 4411 * @remark To be called only from the thread that processes 4412 * daemon's select()/poll()/etc. 4413 * 4414 * @param daemon the daemon to query for timeout 4415 * @param max_timeout the maximum return value (in milliseconds), 4416 * ignored if set to '-1' 4417 * @return timeout value in milliseconds or -1 if no timeout is expected. 4418 */ 4419 static int64_t 4420 get_timeout_millisec_ (struct MHD_Daemon *daemon, 4421 int32_t max_timeout) 4422 { 4423 uint64_t d_timeout; 4424 mhd_assert (0 <= max_timeout || -1 == max_timeout); 4425 if (0 == max_timeout) 4426 return 0; 4427 4428 if (MHD_NO == MHD_get_timeout64 (daemon, &d_timeout)) 4429 return max_timeout; 4430 4431 if ((0 < max_timeout) && ((uint64_t) max_timeout < d_timeout)) 4432 return max_timeout; 4433 4434 if (INT64_MAX <= d_timeout) 4435 return INT64_MAX; 4436 4437 return (int64_t) d_timeout; 4438 } 4439 4440 4441 /** 4442 * Obtain timeout value for polling function for this daemon. 4443 * @remark To be called only from the thread that processes 4444 * daemon's select()/poll()/etc. 4445 * 4446 * @param daemon the daemon to query for timeout 4447 * @param max_timeout the maximum return value (in milliseconds), 4448 * ignored if set to '-1' 4449 * @return timeout value in milliseconds, capped to INT_MAX, or 4450 * -1 if no timeout is expected. 4451 */ 4452 static int 4453 get_timeout_millisec_int (struct MHD_Daemon *daemon, 4454 int32_t max_timeout) 4455 { 4456 int64_t res; 4457 4458 res = get_timeout_millisec_ (daemon, max_timeout); 4459 #if SIZEOF_INT < SIZEOF_INT64_T 4460 if (INT_MAX <= res) 4461 return INT_MAX; 4462 #endif /* SIZEOF_INT < SIZEOF_INT64_T */ 4463 return (int) res; 4464 } 4465 4466 4467 #endif /* HAVE_POLL || EPOLL_SUPPORT */ 4468 4469 /** 4470 * Internal version of #MHD_run_from_select(). 4471 * 4472 * @param daemon daemon to run select loop for 4473 * @param read_fd_set read set 4474 * @param write_fd_set write set 4475 * @param except_fd_set except set 4476 * @param fd_setsize value of FD_SETSIZE used when fd_sets were created 4477 * @return #MHD_NO on serious errors, #MHD_YES on success 4478 * @ingroup event 4479 */ 4480 static enum MHD_Result 4481 internal_run_from_select (struct MHD_Daemon *daemon, 4482 const fd_set *read_fd_set, 4483 const fd_set *write_fd_set, 4484 const fd_set *except_fd_set, 4485 int fd_setsize) 4486 { 4487 MHD_socket ds; 4488 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4489 struct MHD_UpgradeResponseHandle *urh; 4490 struct MHD_UpgradeResponseHandle *urhn; 4491 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 4492 4493 mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 4494 (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid))); 4495 mhd_assert ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 4496 (! MHD_thread_handle_ID_is_valid_ID_ (daemon->tid))); 4497 mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 4498 (MHD_thread_handle_ID_is_current_thread_ (daemon->tid))); 4499 4500 mhd_assert (0 < fd_setsize); 4501 (void) fd_setsize; /* Mute compiler warning */ 4502 #ifndef HAS_FD_SETSIZE_OVERRIDABLE 4503 (void) fd_setsize; /* Mute compiler warning */ 4504 mhd_assert (((int) FD_SETSIZE) <= fd_setsize); 4505 fd_setsize = FD_SETSIZE; /* Help compiler to optimise */ 4506 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 4507 4508 /* Clear ITC to avoid spinning select */ 4509 /* Do it before any other processing so new signals 4510 will trigger select again and will be processed */ 4511 if (MHD_ITC_IS_VALID_ (daemon->itc)) 4512 { /* Have ITC */ 4513 bool need_to_clear_itc = true; /* ITC is always non-blocking, it is safe to clear even if ITC not activated */ 4514 if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (MHD_itc_r_fd_ (daemon->itc), 4515 NULL, fd_setsize)) 4516 need_to_clear_itc = FD_ISSET (MHD_itc_r_fd_ (daemon->itc), \ 4517 (fd_set *) _MHD_DROP_CONST (read_fd_set)); /* Skip clearing, if not needed */ 4518 if (need_to_clear_itc) 4519 MHD_itc_clear_ (daemon->itc); 4520 } 4521 4522 /* Reset. New value will be set when connections are processed. */ 4523 /* Note: no-op for thread-per-connection as it is always false in that mode. */ 4524 daemon->data_already_pending = false; 4525 4526 /* Process externally added connection if any */ 4527 if (daemon->have_new) 4528 new_connections_list_process_ (daemon); 4529 4530 /* select connection thread handling type */ 4531 ds = daemon->listen_fd; 4532 if ( (MHD_INVALID_SOCKET != ds) && 4533 (! daemon->was_quiesced) ) 4534 { 4535 bool need_to_accept; 4536 if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (ds, NULL, fd_setsize)) 4537 need_to_accept = FD_ISSET (ds, 4538 (fd_set *) _MHD_DROP_CONST (read_fd_set)); 4539 else /* Cannot check whether new connection are pending */ 4540 need_to_accept = daemon->listen_nonblk; /* Try to accept if non-blocking */ 4541 4542 if (need_to_accept) 4543 (void) MHD_accept_connection (daemon); 4544 } 4545 4546 if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) 4547 { 4548 /* do not have a thread per connection, process all connections now */ 4549 struct MHD_Connection *pos; 4550 struct MHD_Connection *prev; 4551 4552 for (pos = daemon->connections_tail; NULL != pos; pos = prev) 4553 { 4554 MHD_socket cs; 4555 bool r_ready; 4556 bool w_ready; 4557 bool has_err; 4558 4559 prev = pos->prev; 4560 cs = pos->socket_fd; 4561 if (MHD_INVALID_SOCKET == cs) 4562 continue; 4563 4564 if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (cs, NULL, fd_setsize)) 4565 { 4566 r_ready = FD_ISSET (cs, 4567 (fd_set *) _MHD_DROP_CONST (read_fd_set)); 4568 w_ready = FD_ISSET (cs, 4569 (fd_set *) _MHD_DROP_CONST (write_fd_set)); 4570 has_err = (NULL != except_fd_set) && 4571 FD_ISSET (cs, 4572 (fd_set *) _MHD_DROP_CONST (except_fd_set)); 4573 } 4574 else 4575 { /* Cannot check the real readiness */ 4576 r_ready = pos->sk_nonblck; 4577 w_ready = r_ready; 4578 has_err = false; 4579 } 4580 call_handlers (pos, 4581 r_ready, 4582 w_ready, 4583 has_err); 4584 } 4585 } 4586 4587 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4588 /* handle upgraded HTTPS connections */ 4589 for (urh = daemon->urh_tail; NULL != urh; urh = urhn) 4590 { 4591 urhn = urh->prev; 4592 /* update urh state based on select() output */ 4593 urh_from_fdset (urh, 4594 read_fd_set, 4595 write_fd_set, 4596 except_fd_set, 4597 fd_setsize); 4598 /* call generic forwarding function for passing data */ 4599 process_urh (urh); 4600 /* Finished forwarding? */ 4601 if ( (0 == urh->in_buffer_size) && 4602 (0 == urh->out_buffer_size) && 4603 (0 == urh->in_buffer_used) && 4604 (0 == urh->out_buffer_used) ) 4605 { 4606 MHD_connection_finish_forward_ (urh->connection); 4607 urh->clean_ready = true; 4608 /* Resuming will move connection to cleanup list. */ 4609 MHD_resume_connection (urh->connection); 4610 } 4611 } 4612 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 4613 MHD_cleanup_connections (daemon); 4614 return MHD_YES; 4615 } 4616 4617 4618 #undef MHD_run_from_select 4619 4620 /** 4621 * Run webserver operations. This method should be called by clients 4622 * in combination with #MHD_get_fdset and #MHD_get_timeout() if the 4623 * client-controlled select method is used. 4624 * This function specifies FD_SETSIZE used when provided fd_sets were 4625 * created. It is important on platforms where FD_SETSIZE can be 4626 * overridden. 4627 * 4628 * You can use this function instead of #MHD_run if you called 4629 * 'select()' on the result from #MHD_get_fdset2(). File descriptors in 4630 * the sets that are not controlled by MHD will be ignored. Calling 4631 * this function instead of #MHD_run() is more efficient as MHD will 4632 * not have to call 'select()' again to determine which operations are 4633 * ready. 4634 * 4635 * If #MHD_get_timeout() returned #MHD_YES, than this function must be 4636 * called right after 'select()' returns regardless of detected activity 4637 * on the daemon's FDs. 4638 * 4639 * This function cannot be used with daemon started with 4640 * #MHD_USE_INTERNAL_POLLING_THREAD flag. 4641 * 4642 * @param daemon the daemon to run select loop for 4643 * @param read_fd_set the read set 4644 * @param write_fd_set the write set 4645 * @param except_fd_set the except set 4646 * @param fd_setsize the value of FD_SETSIZE 4647 * @return #MHD_NO on serious errors, #MHD_YES on success 4648 * @sa #MHD_get_fdset2(), #MHD_OPTION_APP_FD_SETSIZE 4649 * @ingroup event 4650 */ 4651 _MHD_EXTERN enum MHD_Result 4652 MHD_run_from_select2 (struct MHD_Daemon *daemon, 4653 const fd_set *read_fd_set, 4654 const fd_set *write_fd_set, 4655 const fd_set *except_fd_set, 4656 unsigned int fd_setsize) 4657 { 4658 if (MHD_D_IS_USING_POLL_ (daemon) || 4659 MHD_D_IS_USING_THREADS_ (daemon)) 4660 return MHD_NO; 4661 if ((NULL == read_fd_set) || (NULL == write_fd_set)) 4662 return MHD_NO; 4663 #ifdef HAVE_MESSAGES 4664 if (NULL == except_fd_set) 4665 { 4666 MHD_DLOG (daemon, 4667 _ ("MHD_run_from_select() called with except_fd_set " 4668 "set to NULL. Such behavior is deprecated.\n")); 4669 } 4670 #endif /* HAVE_MESSAGES */ 4671 4672 #ifdef HAS_FD_SETSIZE_OVERRIDABLE 4673 if (0 == fd_setsize) 4674 return MHD_NO; 4675 else if (((unsigned int) INT_MAX) < fd_setsize) 4676 fd_setsize = (unsigned int) INT_MAX; 4677 #ifdef HAVE_MESSAGES 4678 else if (daemon->fdset_size > ((int) fd_setsize)) 4679 { 4680 if (daemon->fdset_size_set_by_app) 4681 { 4682 MHD_DLOG (daemon, 4683 _ ("%s() called with fd_setsize (%u) " \ 4684 "less than value set by MHD_OPTION_APP_FD_SETSIZE (%d). " \ 4685 "Some socket FDs may be not processed. " \ 4686 "Use MHD_OPTION_APP_FD_SETSIZE with the correct value.\n"), 4687 "MHD_run_from_select2", fd_setsize, daemon->fdset_size); 4688 } 4689 else 4690 { 4691 MHD_DLOG (daemon, 4692 _ ("%s() called with fd_setsize (%u) " \ 4693 "less than FD_SETSIZE used by MHD (%d). " \ 4694 "Some socket FDs may be not processed. " \ 4695 "Consider using MHD_OPTION_APP_FD_SETSIZE option.\n"), 4696 "MHD_run_from_select2", fd_setsize, daemon->fdset_size); 4697 } 4698 } 4699 #endif /* HAVE_MESSAGES */ 4700 #else /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 4701 if (((unsigned int) FD_SETSIZE) > fd_setsize) 4702 { 4703 #ifdef HAVE_MESSAGES 4704 MHD_DLOG (daemon, 4705 _ ("%s() called with fd_setsize (%u) " \ 4706 "less than fixed FD_SETSIZE value (%d) used on the " \ 4707 "platform.\n"), 4708 "MHD_run_from_select2", fd_setsize, (int) FD_SETSIZE); 4709 #endif /* HAVE_MESSAGES */ 4710 return MHD_NO; 4711 } 4712 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 4713 4714 if (MHD_D_IS_USING_EPOLL_ (daemon)) 4715 { 4716 #ifdef EPOLL_SUPPORT 4717 enum MHD_Result ret = MHD_epoll (daemon, 4718 0); 4719 4720 MHD_cleanup_connections (daemon); 4721 return ret; 4722 #else /* ! EPOLL_SUPPORT */ 4723 return MHD_NO; 4724 #endif /* ! EPOLL_SUPPORT */ 4725 } 4726 4727 /* Resuming external connections when using an extern mainloop */ 4728 if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) 4729 resume_suspended_connections (daemon); 4730 4731 return internal_run_from_select (daemon, 4732 read_fd_set, 4733 write_fd_set, 4734 except_fd_set, 4735 (int) fd_setsize); 4736 } 4737 4738 4739 /** 4740 * Run webserver operations. This method should be called by clients 4741 * in combination with #MHD_get_fdset and #MHD_get_timeout() if the 4742 * client-controlled select method is used. 4743 * 4744 * You can use this function instead of #MHD_run if you called 4745 * `select()` on the result from #MHD_get_fdset. File descriptors in 4746 * the sets that are not controlled by MHD will be ignored. Calling 4747 * this function instead of #MHD_run is more efficient as MHD will 4748 * not have to call `select()` again to determine which operations are 4749 * ready. 4750 * 4751 * If #MHD_get_timeout() returned #MHD_YES, than this function must be 4752 * called right after `select()` returns regardless of detected activity 4753 * on the daemon's FDs. 4754 * 4755 * This function cannot be used with daemon started with 4756 * #MHD_USE_INTERNAL_POLLING_THREAD flag. 4757 * 4758 * @param daemon daemon to run select loop for 4759 * @param read_fd_set read set 4760 * @param write_fd_set write set 4761 * @param except_fd_set except set 4762 * @return #MHD_NO on serious errors, #MHD_YES on success 4763 * @ingroup event 4764 */ 4765 _MHD_EXTERN enum MHD_Result 4766 MHD_run_from_select (struct MHD_Daemon *daemon, 4767 const fd_set *read_fd_set, 4768 const fd_set *write_fd_set, 4769 const fd_set *except_fd_set) 4770 { 4771 return MHD_run_from_select2 (daemon, 4772 read_fd_set, 4773 write_fd_set, 4774 except_fd_set, 4775 #ifdef HAS_FD_SETSIZE_OVERRIDABLE 4776 daemon->fdset_size_set_by_app ? 4777 ((unsigned int) daemon->fdset_size) : 4778 ((unsigned int) _MHD_SYS_DEFAULT_FD_SETSIZE) 4779 #else /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 4780 ((unsigned int) _MHD_SYS_DEFAULT_FD_SETSIZE) 4781 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 4782 ); 4783 } 4784 4785 4786 /** 4787 * Main internal select() call. Will compute select sets, call select() 4788 * and then #internal_run_from_select with the result. 4789 * 4790 * @param daemon daemon to run select() loop for 4791 * @param millisec the maximum time in milliseconds to wait for events, 4792 * set to '0' for non-blocking processing, 4793 * set to '-1' to wait indefinitely. 4794 * @return #MHD_NO on serious errors, #MHD_YES on success 4795 */ 4796 static enum MHD_Result 4797 MHD_select (struct MHD_Daemon *daemon, 4798 int32_t millisec) 4799 { 4800 int num_ready; 4801 fd_set rs; 4802 fd_set ws; 4803 fd_set es; 4804 MHD_socket maxsock; 4805 struct timeval timeout; 4806 struct timeval *tv; 4807 int err_state; 4808 MHD_socket ls; 4809 4810 timeout.tv_sec = 0; 4811 timeout.tv_usec = 0; 4812 if (daemon->shutdown) 4813 return MHD_NO; 4814 FD_ZERO (&rs); 4815 FD_ZERO (&ws); 4816 FD_ZERO (&es); 4817 maxsock = MHD_INVALID_SOCKET; 4818 err_state = MHD_NO; 4819 if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) && 4820 (MHD_NO != resume_suspended_connections (daemon)) && 4821 (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) ) 4822 millisec = 0; 4823 4824 if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) 4825 { 4826 /* single-threaded, go over everything */ 4827 if (MHD_NO == 4828 internal_get_fdset2 (daemon, 4829 &rs, 4830 &ws, 4831 &es, 4832 &maxsock, 4833 (int) FD_SETSIZE)) 4834 { 4835 #ifdef HAVE_MESSAGES 4836 MHD_DLOG (daemon, 4837 _ ("Could not obtain daemon fdsets.\n")); 4838 #endif 4839 err_state = MHD_YES; 4840 } 4841 } 4842 else 4843 { 4844 bool itc_added; 4845 /* accept only, have one thread per connection */ 4846 itc_added = false; 4847 if (MHD_ITC_IS_VALID_ (daemon->itc)) 4848 { 4849 itc_added = MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), 4850 &rs, 4851 &maxsock, 4852 (int) FD_SETSIZE); 4853 if (! itc_added) 4854 { 4855 #ifdef HAVE_MESSAGES 4856 MHD_DLOG (daemon, _ ("Could not add control inter-thread " \ 4857 "communication channel FD to fdset.\n")); 4858 #endif 4859 err_state = MHD_YES; 4860 } 4861 } 4862 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && 4863 (! daemon->was_quiesced) ) 4864 { 4865 /* Stop listening if we are at the configured connection limit */ 4866 /* If we're at the connection limit, no point in really 4867 accepting new connections; however, make sure we do not miss 4868 the shutdown OR the termination of an existing connection; so 4869 only do this optimisation if we have a signaling ITC in 4870 place. */ 4871 if (! itc_added || 4872 ((daemon->connections < daemon->connection_limit) && 4873 ! daemon->at_limit)) 4874 { 4875 if (! MHD_add_to_fd_set_ (ls, 4876 &rs, 4877 &maxsock, 4878 (int) FD_SETSIZE)) 4879 { 4880 #ifdef HAVE_MESSAGES 4881 MHD_DLOG (daemon, 4882 _ ("Could not add listen socket to fdset.\n")); 4883 #endif 4884 err_state = MHD_YES; 4885 } 4886 } 4887 } 4888 } 4889 4890 if (MHD_NO != err_state) 4891 millisec = 0; 4892 if (0 == millisec) 4893 { 4894 timeout.tv_usec = 0; 4895 timeout.tv_sec = 0; 4896 tv = &timeout; 4897 } 4898 else 4899 { 4900 uint64_t mhd_tmo; 4901 uint64_t select_tmo; 4902 4903 if ( (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) && 4904 (MHD_NO != MHD_get_timeout64 (daemon, &mhd_tmo)) ) 4905 { 4906 if ( (0 < millisec) && 4907 (mhd_tmo > (uint64_t) millisec) ) 4908 select_tmo = (uint64_t) millisec; 4909 else 4910 select_tmo = mhd_tmo; 4911 tv = &timeout; /* have timeout value */ 4912 } 4913 else if (0 < millisec) 4914 { 4915 select_tmo = (uint64_t) millisec; 4916 tv = &timeout; /* have timeout value */ 4917 } 4918 else 4919 { 4920 select_tmo = 0; /* Not actually used, silent compiler warning */ 4921 tv = NULL; 4922 } 4923 4924 if (NULL != tv) 4925 { /* have timeout value */ 4926 #if (SIZEOF_UINT64_T - 2) >= SIZEOF_STRUCT_TIMEVAL_TV_SEC 4927 if (select_tmo / 1000 > TIMEVAL_TV_SEC_MAX) 4928 timeout.tv_sec = TIMEVAL_TV_SEC_MAX; 4929 else 4930 #endif /* (SIZEOF_UINT64_T - 2) >= SIZEOF_STRUCT_TIMEVAL_TV_SEC */ 4931 timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) (select_tmo / 1000); 4932 4933 timeout.tv_usec = ((uint16_t) (select_tmo % 1000)) * ((int32_t) 1000); 4934 } 4935 } 4936 num_ready = MHD_SYS_select_ (maxsock + 1, 4937 &rs, 4938 &ws, 4939 &es, 4940 tv); 4941 if (daemon->shutdown) 4942 return MHD_NO; 4943 if (num_ready < 0) 4944 { 4945 const int err = MHD_socket_get_error_ (); 4946 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 4947 return (MHD_NO == err_state) ? MHD_YES : MHD_NO; 4948 #ifdef HAVE_MESSAGES 4949 MHD_DLOG (daemon, 4950 _ ("select failed: %s\n"), 4951 MHD_socket_strerr_ (err)); 4952 #endif 4953 return MHD_NO; 4954 } 4955 if (MHD_NO != internal_run_from_select (daemon, 4956 &rs, 4957 &ws, 4958 &es, 4959 (int) FD_SETSIZE)) 4960 return (MHD_NO == err_state) ? MHD_YES : MHD_NO; 4961 return MHD_NO; 4962 } 4963 4964 4965 #ifdef HAVE_POLL 4966 /** 4967 * Process all of our connections and possibly the server 4968 * socket using poll(). 4969 * 4970 * @param daemon daemon to run poll loop for 4971 * @param millisec the maximum time in milliseconds to wait for events, 4972 * set to '0' for non-blocking processing, 4973 * set to '-1' to wait indefinitely. 4974 * @return #MHD_NO on serious errors, #MHD_YES on success 4975 */ 4976 static enum MHD_Result 4977 MHD_poll_all (struct MHD_Daemon *daemon, 4978 int32_t millisec) 4979 { 4980 unsigned int num_connections; 4981 struct MHD_Connection *pos; 4982 struct MHD_Connection *prev; 4983 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4984 struct MHD_UpgradeResponseHandle *urh; 4985 struct MHD_UpgradeResponseHandle *urhn; 4986 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 4987 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_valid_ID_ (daemon->tid))); 4992 mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 4993 (MHD_thread_handle_ID_is_current_thread_ (daemon->tid))); 4994 4995 if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) && 4996 (MHD_NO != resume_suspended_connections (daemon)) ) 4997 millisec = 0; 4998 4999 /* count number of connections and thus determine poll set size */ 5000 num_connections = 0; 5001 for (pos = daemon->connections_head; NULL != pos; pos = pos->next) 5002 num_connections++; 5003 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5004 for (urh = daemon->urh_head; NULL != urh; urh = urh->next) 5005 num_connections += 2; 5006 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 5007 { 5008 unsigned int i; 5009 int timeout; 5010 unsigned int poll_server; 5011 int poll_listen; 5012 int poll_itc_idx; 5013 struct pollfd *p; 5014 MHD_socket ls; 5015 5016 p = MHD_calloc_ ((2 + (size_t) num_connections), 5017 sizeof (struct pollfd)); 5018 if (NULL == p) 5019 { 5020 #ifdef HAVE_MESSAGES 5021 MHD_DLOG (daemon, 5022 _ ("Error allocating memory: %s\n"), 5023 MHD_strerror_ (errno)); 5024 #endif 5025 return MHD_NO; 5026 } 5027 poll_server = 0; 5028 poll_listen = -1; 5029 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && 5030 (! daemon->was_quiesced) && 5031 (daemon->connections < daemon->connection_limit) && 5032 (! daemon->at_limit) ) 5033 { 5034 /* only listen if we are not at the connection limit */ 5035 p[poll_server].fd = ls; 5036 p[poll_server].events = POLLIN; 5037 p[poll_server].revents = 0; 5038 poll_listen = (int) poll_server; 5039 poll_server++; 5040 } 5041 poll_itc_idx = -1; 5042 if (MHD_ITC_IS_VALID_ (daemon->itc)) 5043 { 5044 p[poll_server].fd = MHD_itc_r_fd_ (daemon->itc); 5045 p[poll_server].events = POLLIN; 5046 p[poll_server].revents = 0; 5047 poll_itc_idx = (int) poll_server; 5048 poll_server++; 5049 } 5050 5051 timeout = get_timeout_millisec_int (daemon, millisec); 5052 5053 i = 0; 5054 for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev) 5055 { 5056 p[poll_server + i].fd = pos->socket_fd; 5057 switch (pos->event_loop_info) 5058 { 5059 case MHD_EVENT_LOOP_INFO_READ: 5060 case MHD_EVENT_LOOP_INFO_PROCESS_READ: 5061 p[poll_server + i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; 5062 break; 5063 case MHD_EVENT_LOOP_INFO_WRITE: 5064 p[poll_server + i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; 5065 break; 5066 case MHD_EVENT_LOOP_INFO_PROCESS: 5067 p[poll_server + i].events |= MHD_POLL_EVENTS_ERR_DISC; 5068 break; 5069 case MHD_EVENT_LOOP_INFO_CLEANUP: 5070 timeout = 0; /* clean up "pos" immediately */ 5071 break; 5072 } 5073 i++; 5074 } 5075 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5076 for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev) 5077 { 5078 urh_to_pollfd (urh, &(p[poll_server + i])); 5079 i += 2; 5080 } 5081 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 5082 if (0 == poll_server + num_connections) 5083 { 5084 free (p); 5085 return MHD_YES; 5086 } 5087 if (MHD_sys_poll_ (p, 5088 poll_server + num_connections, 5089 timeout) < 0) 5090 { 5091 const int err = MHD_socket_get_error_ (); 5092 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 5093 { 5094 free (p); 5095 return MHD_YES; 5096 } 5097 #ifdef HAVE_MESSAGES 5098 MHD_DLOG (daemon, 5099 _ ("poll failed: %s\n"), 5100 MHD_socket_strerr_ (err)); 5101 #endif 5102 free (p); 5103 return MHD_NO; 5104 } 5105 5106 /* handle ITC FD */ 5107 /* do it before any other processing so 5108 new signals will be processed in next loop */ 5109 if ( (-1 != poll_itc_idx) && 5110 (0 != (p[poll_itc_idx].revents & POLLIN)) ) 5111 MHD_itc_clear_ (daemon->itc); 5112 5113 /* handle shutdown */ 5114 if (daemon->shutdown) 5115 { 5116 free (p); 5117 return MHD_NO; 5118 } 5119 5120 /* Process externally added connection if any */ 5121 if (daemon->have_new) 5122 new_connections_list_process_ (daemon); 5123 5124 /* handle 'listen' FD */ 5125 if ( (-1 != poll_listen) && 5126 (0 != (p[poll_listen].revents & POLLIN)) ) 5127 (void) MHD_accept_connection (daemon); 5128 5129 /* Reset. New value will be set when connections are processed. */ 5130 daemon->data_already_pending = false; 5131 5132 i = 0; 5133 prev = daemon->connections_tail; 5134 while (NULL != (pos = prev)) 5135 { 5136 prev = pos->prev; 5137 /* first, sanity checks */ 5138 if (i >= num_connections) 5139 break; /* connection list changed somehow, retry later ... */ 5140 if (p[poll_server + i].fd != pos->socket_fd) 5141 continue; /* fd mismatch, something else happened, retry later ... */ 5142 call_handlers (pos, 5143 0 != (p[poll_server + i].revents & POLLIN), 5144 0 != (p[poll_server + i].revents & POLLOUT), 5145 0 != (p[poll_server + i].revents 5146 & MHD_POLL_REVENTS_ERR_DISC)); 5147 i++; 5148 } 5149 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5150 for (urh = daemon->urh_tail; NULL != urh; urh = urhn) 5151 { 5152 if (i >= num_connections) 5153 break; /* connection list changed somehow, retry later ... */ 5154 5155 /* Get next connection here as connection can be removed 5156 * from 'daemon->urh_head' list. */ 5157 urhn = urh->prev; 5158 /* Check for fd mismatch. FIXME: required for safety? */ 5159 if ((p[poll_server + i].fd != urh->connection->socket_fd) || 5160 (p[poll_server + i + 1].fd != urh->mhd.socket)) 5161 break; 5162 urh_from_pollfd (urh, 5163 &p[poll_server + i]); 5164 i += 2; 5165 process_urh (urh); 5166 /* Finished forwarding? */ 5167 if ( (0 == urh->in_buffer_size) && 5168 (0 == urh->out_buffer_size) && 5169 (0 == urh->in_buffer_used) && 5170 (0 == urh->out_buffer_used) ) 5171 { 5172 /* MHD_connection_finish_forward_() will remove connection from 5173 * 'daemon->urh_head' list. */ 5174 MHD_connection_finish_forward_ (urh->connection); 5175 urh->clean_ready = true; 5176 /* If 'urh->was_closed' already was set to true, connection will be 5177 * moved immediately to cleanup list. Otherwise connection 5178 * will stay in suspended list until 'urh' will be marked 5179 * with 'was_closed' by application. */ 5180 MHD_resume_connection (urh->connection); 5181 } 5182 } 5183 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 5184 5185 free (p); 5186 } 5187 return MHD_YES; 5188 } 5189 5190 5191 /** 5192 * Process only the listen socket using poll(). 5193 * 5194 * @param daemon daemon to run poll loop for 5195 * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking 5196 * @return #MHD_NO on serious errors, #MHD_YES on success 5197 */ 5198 static enum MHD_Result 5199 MHD_poll_listen_socket (struct MHD_Daemon *daemon, 5200 int may_block) 5201 { 5202 struct pollfd p[2]; 5203 int timeout; 5204 unsigned int poll_count; 5205 int poll_listen; 5206 int poll_itc_idx; 5207 MHD_socket ls; 5208 5209 mhd_assert (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid)); 5210 mhd_assert (MHD_thread_handle_ID_is_current_thread_ (daemon->tid)); 5211 5212 memset (&p, 5213 0, 5214 sizeof (p)); 5215 poll_count = 0; 5216 poll_listen = -1; 5217 poll_itc_idx = -1; 5218 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && 5219 (! daemon->was_quiesced) ) 5220 5221 { 5222 p[poll_count].fd = ls; 5223 p[poll_count].events = POLLIN; 5224 p[poll_count].revents = 0; 5225 poll_listen = (int) poll_count; 5226 poll_count++; 5227 } 5228 if (MHD_ITC_IS_VALID_ (daemon->itc)) 5229 { 5230 p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc); 5231 p[poll_count].events = POLLIN; 5232 p[poll_count].revents = 0; 5233 poll_itc_idx = (int) poll_count; 5234 poll_count++; 5235 } 5236 5237 if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) 5238 (void) resume_suspended_connections (daemon); 5239 5240 if (MHD_NO == may_block) 5241 timeout = 0; 5242 else 5243 timeout = -1; 5244 if (0 == poll_count) 5245 return MHD_YES; 5246 if (MHD_sys_poll_ (p, 5247 poll_count, 5248 timeout) < 0) 5249 { 5250 const int err = MHD_socket_get_error_ (); 5251 5252 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 5253 return MHD_YES; 5254 #ifdef HAVE_MESSAGES 5255 MHD_DLOG (daemon, 5256 _ ("poll failed: %s\n"), 5257 MHD_socket_strerr_ (err)); 5258 #endif 5259 return MHD_NO; 5260 } 5261 if ( (0 <= poll_itc_idx) && 5262 (0 != (p[poll_itc_idx].revents & POLLIN)) ) 5263 MHD_itc_clear_ (daemon->itc); 5264 5265 /* handle shutdown */ 5266 if (daemon->shutdown) 5267 return MHD_NO; 5268 5269 /* Process externally added connection if any */ 5270 if (daemon->have_new) 5271 new_connections_list_process_ (daemon); 5272 5273 if ( (0 <= poll_listen) && 5274 (0 != (p[poll_listen].revents & POLLIN)) ) 5275 (void) MHD_accept_connection (daemon); 5276 return MHD_YES; 5277 } 5278 5279 5280 #endif 5281 5282 #ifdef HAVE_POLL 5283 5284 /** 5285 * Do poll()-based processing. 5286 * 5287 * @param daemon daemon to run poll()-loop for 5288 * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking 5289 * @return #MHD_NO on serious errors, #MHD_YES on success 5290 */ 5291 static enum MHD_Result 5292 MHD_poll (struct MHD_Daemon *daemon, 5293 int may_block) 5294 { 5295 if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) 5296 return MHD_poll_all (daemon, 5297 may_block ? -1 : 0); 5298 return MHD_poll_listen_socket (daemon, 5299 may_block); 5300 } 5301 5302 5303 #endif /* HAVE_POLL */ 5304 5305 5306 #ifdef EPOLL_SUPPORT 5307 5308 /** 5309 * How many events to we process at most per epoll() call? Trade-off 5310 * between required stack-size and number of system calls we have to 5311 * make; 128 should be way enough to avoid more than one system call 5312 * for most scenarios, and still be moderate in stack size 5313 * consumption. Embedded systems might want to choose a smaller value 5314 * --- but why use epoll() on such a system in the first place? 5315 */ 5316 #define MAX_EVENTS 128 5317 5318 5319 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5320 5321 /** 5322 * Checks whether @a urh has some data to process. 5323 * 5324 * @param urh upgrade handler to analyse 5325 * @return 'true' if @a urh has some data to process, 5326 * 'false' otherwise 5327 */ 5328 static bool 5329 is_urh_ready (struct MHD_UpgradeResponseHandle *const urh) 5330 { 5331 const struct MHD_Connection *const connection = urh->connection; 5332 5333 if ( (0 == urh->in_buffer_size) && 5334 (0 == urh->out_buffer_size) && 5335 (0 == urh->in_buffer_used) && 5336 (0 == urh->out_buffer_used) ) 5337 return false; 5338 if (connection->daemon->shutdown) 5339 return true; 5340 if ( ( (0 != ((MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_ERROR) 5341 & urh->app.celi)) || 5342 (connection->tls_read_ready) ) && 5343 (urh->in_buffer_used < urh->in_buffer_size) ) 5344 return true; 5345 if ( ( (0 != ((MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_ERROR) 5346 & urh->mhd.celi)) || 5347 urh->was_closed) && 5348 (urh->out_buffer_used < urh->out_buffer_size) ) 5349 return true; 5350 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) && 5351 (urh->out_buffer_used > 0) ) 5352 return true; 5353 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && 5354 (urh->in_buffer_used > 0) ) 5355 return true; 5356 return false; 5357 } 5358 5359 5360 /** 5361 * Do epoll()-based processing for TLS connections that have been 5362 * upgraded. This requires a separate epoll() invocation as we 5363 * cannot use the `struct MHD_Connection` data structures for 5364 * the `union epoll_data` in this case. 5365 * @remark To be called only from thread that process 5366 * daemon's select()/poll()/etc. 5367 */ 5368 static enum MHD_Result 5369 run_epoll_for_upgrade (struct MHD_Daemon *daemon) 5370 { 5371 struct epoll_event events[MAX_EVENTS]; 5372 int num_events; 5373 struct MHD_UpgradeResponseHandle *pos; 5374 struct MHD_UpgradeResponseHandle *prev; 5375 5376 #ifdef MHD_USE_THREADS 5377 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 5378 MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); 5379 #endif /* MHD_USE_THREADS */ 5380 5381 num_events = MAX_EVENTS; 5382 while (0 != num_events) 5383 { 5384 unsigned int i; 5385 /* update event masks */ 5386 num_events = epoll_wait (daemon->epoll_upgrade_fd, 5387 events, 5388 MAX_EVENTS, 5389 0); 5390 if (-1 == num_events) 5391 { 5392 const int err = MHD_socket_get_error_ (); 5393 5394 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 5395 return MHD_YES; 5396 #ifdef HAVE_MESSAGES 5397 MHD_DLOG (daemon, 5398 _ ("Call to epoll_wait failed: %s\n"), 5399 MHD_socket_strerr_ (err)); 5400 #endif 5401 return MHD_NO; 5402 } 5403 for (i = 0; i < (unsigned int) num_events; i++) 5404 { 5405 struct UpgradeEpollHandle *const ueh = events[i].data.ptr; 5406 struct MHD_UpgradeResponseHandle *const urh = ueh->urh; 5407 bool new_err_state = false; 5408 5409 if (urh->clean_ready) 5410 continue; 5411 5412 /* Update ueh state based on what is ready according to epoll() */ 5413 if (0 != (events[i].events & EPOLLIN)) 5414 { 5415 ueh->celi |= MHD_EPOLL_STATE_READ_READY; 5416 } 5417 if (0 != (events[i].events & EPOLLOUT)) 5418 { 5419 ueh->celi |= MHD_EPOLL_STATE_WRITE_READY; 5420 } 5421 if (0 != (events[i].events & EPOLLHUP)) 5422 { 5423 ueh->celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY; 5424 } 5425 5426 if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) && 5427 (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) ) 5428 { 5429 /* Process new error state only one time and avoid continuously 5430 * marking this connection as 'ready'. */ 5431 ueh->celi |= MHD_EPOLL_STATE_ERROR; 5432 new_err_state = true; 5433 } 5434 if (! urh->in_eready_list) 5435 { 5436 if (new_err_state || 5437 is_urh_ready (urh)) 5438 { 5439 EDLL_insert (daemon->eready_urh_head, 5440 daemon->eready_urh_tail, 5441 urh); 5442 urh->in_eready_list = true; 5443 } 5444 } 5445 } 5446 } 5447 prev = daemon->eready_urh_tail; 5448 while (NULL != (pos = prev)) 5449 { 5450 prev = pos->prevE; 5451 process_urh (pos); 5452 if (! is_urh_ready (pos)) 5453 { 5454 EDLL_remove (daemon->eready_urh_head, 5455 daemon->eready_urh_tail, 5456 pos); 5457 pos->in_eready_list = false; 5458 } 5459 /* Finished forwarding? */ 5460 if ( (0 == pos->in_buffer_size) && 5461 (0 == pos->out_buffer_size) && 5462 (0 == pos->in_buffer_used) && 5463 (0 == pos->out_buffer_used) ) 5464 { 5465 MHD_connection_finish_forward_ (pos->connection); 5466 pos->clean_ready = true; 5467 /* If 'pos->was_closed' already was set to true, connection 5468 * will be moved immediately to cleanup list. Otherwise 5469 * connection will stay in suspended list until 'pos' will 5470 * be marked with 'was_closed' by application. */ 5471 MHD_resume_connection (pos->connection); 5472 } 5473 } 5474 5475 return MHD_YES; 5476 } 5477 5478 5479 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 5480 5481 5482 /** 5483 * Pointer-marker to distinguish ITC slot in epoll sets. 5484 */ 5485 static const char *const epoll_itc_marker = "itc_marker"; 5486 5487 5488 /** 5489 * Do epoll()-based processing. 5490 * 5491 * @param daemon daemon to run poll loop for 5492 * @param millisec the maximum time in milliseconds to wait for events, 5493 * set to '0' for non-blocking processing, 5494 * set to '-1' to wait indefinitely. 5495 * @return #MHD_NO on serious errors, #MHD_YES on success 5496 */ 5497 static enum MHD_Result 5498 MHD_epoll (struct MHD_Daemon *daemon, 5499 int32_t millisec) 5500 { 5501 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5502 static const char *const upgrade_marker = "upgrade_ptr"; 5503 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 5504 struct MHD_Connection *pos; 5505 struct MHD_Connection *prev; 5506 struct epoll_event events[MAX_EVENTS]; 5507 struct epoll_event event; 5508 int timeout_ms; 5509 int num_events; 5510 unsigned int i; 5511 MHD_socket ls; 5512 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5513 bool run_upgraded = false; 5514 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 5515 bool need_to_accept; 5516 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_valid_ID_ (daemon->tid))); 5521 mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 5522 (MHD_thread_handle_ID_is_current_thread_ (daemon->tid))); 5523 5524 if (-1 == daemon->epoll_fd) 5525 return MHD_NO; /* we're down! */ 5526 if (daemon->shutdown) 5527 return MHD_NO; 5528 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && 5529 (! daemon->was_quiesced) && 5530 (daemon->connections < daemon->connection_limit) && 5531 (! daemon->listen_socket_in_epoll) && 5532 (! daemon->at_limit) ) 5533 { 5534 event.events = EPOLLIN | EPOLLRDHUP; 5535 event.data.ptr = daemon; 5536 if (0 != epoll_ctl (daemon->epoll_fd, 5537 EPOLL_CTL_ADD, 5538 ls, 5539 &event)) 5540 { 5541 #ifdef HAVE_MESSAGES 5542 MHD_DLOG (daemon, 5543 _ ("Call to epoll_ctl failed: %s\n"), 5544 MHD_socket_last_strerr_ ()); 5545 #endif 5546 return MHD_NO; 5547 } 5548 daemon->listen_socket_in_epoll = true; 5549 } 5550 if ( (daemon->was_quiesced) && 5551 (daemon->listen_socket_in_epoll) ) 5552 { 5553 if ( (0 != epoll_ctl (daemon->epoll_fd, 5554 EPOLL_CTL_DEL, 5555 ls, 5556 NULL)) && 5557 (ENOENT != errno) ) /* ENOENT can happen due to race with 5558 #MHD_quiesce_daemon() */ 5559 MHD_PANIC ("Failed to remove listen FD from epoll set.\n"); 5560 daemon->listen_socket_in_epoll = false; 5561 } 5562 5563 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5564 if ( ( (! daemon->upgrade_fd_in_epoll) && 5565 (-1 != daemon->epoll_upgrade_fd) ) ) 5566 { 5567 event.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP; 5568 event.data.ptr = _MHD_DROP_CONST (upgrade_marker); 5569 if (0 != epoll_ctl (daemon->epoll_fd, 5570 EPOLL_CTL_ADD, 5571 daemon->epoll_upgrade_fd, 5572 &event)) 5573 { 5574 #ifdef HAVE_MESSAGES 5575 MHD_DLOG (daemon, 5576 _ ("Call to epoll_ctl failed: %s\n"), 5577 MHD_socket_last_strerr_ ()); 5578 #endif 5579 return MHD_NO; 5580 } 5581 daemon->upgrade_fd_in_epoll = true; 5582 } 5583 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 5584 if ( (daemon->listen_socket_in_epoll) && 5585 ( (daemon->connections == daemon->connection_limit) || 5586 (daemon->at_limit) || 5587 (daemon->was_quiesced) ) ) 5588 { 5589 /* we're at the connection limit, disable listen socket 5590 for event loop for now */ 5591 if (0 != epoll_ctl (daemon->epoll_fd, 5592 EPOLL_CTL_DEL, 5593 ls, 5594 NULL)) 5595 MHD_PANIC (_ ("Failed to remove listen FD from epoll set.\n")); 5596 daemon->listen_socket_in_epoll = false; 5597 } 5598 5599 if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) && 5600 (MHD_NO != resume_suspended_connections (daemon)) ) 5601 millisec = 0; 5602 5603 timeout_ms = get_timeout_millisec_int (daemon, 5604 millisec); 5605 5606 /* Reset. New value will be set when connections are processed. */ 5607 /* Note: Used mostly for uniformity here as same situation is 5608 * signaled in epoll mode by non-empty eready DLL. */ 5609 daemon->data_already_pending = false; 5610 5611 need_to_accept = false; 5612 /* drain 'epoll' event queue; need to iterate as we get at most 5613 MAX_EVENTS in one system call here; in practice this should 5614 pretty much mean only one round, but better an extra loop here 5615 than unfair behavior... */ 5616 num_events = MAX_EVENTS; 5617 while (MAX_EVENTS == num_events) 5618 { 5619 /* update event masks */ 5620 num_events = epoll_wait (daemon->epoll_fd, 5621 events, 5622 MAX_EVENTS, 5623 timeout_ms); 5624 if (-1 == num_events) 5625 { 5626 const int err = MHD_socket_get_error_ (); 5627 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 5628 return MHD_YES; 5629 #ifdef HAVE_MESSAGES 5630 MHD_DLOG (daemon, 5631 _ ("Call to epoll_wait failed: %s\n"), 5632 MHD_socket_strerr_ (err)); 5633 #endif 5634 return MHD_NO; 5635 } 5636 for (i = 0; i < (unsigned int) num_events; i++) 5637 { 5638 /* First, check for the values of `ptr` that would indicate 5639 that this event is not about a normal connection. */ 5640 if (NULL == events[i].data.ptr) 5641 continue; /* shutdown signal! */ 5642 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5643 if (upgrade_marker == events[i].data.ptr) 5644 { 5645 /* activity on an upgraded connection, we process 5646 those in a separate epoll() */ 5647 run_upgraded = true; 5648 continue; 5649 } 5650 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 5651 if (epoll_itc_marker == events[i].data.ptr) 5652 { 5653 /* It's OK to clear ITC here as all external 5654 conditions will be processed later. */ 5655 MHD_itc_clear_ (daemon->itc); 5656 continue; 5657 } 5658 if (daemon == events[i].data.ptr) 5659 { 5660 /* Check for error conditions on listen socket. */ 5661 /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */ 5662 if (0 == (events[i].events & (EPOLLERR | EPOLLHUP))) 5663 need_to_accept = true; 5664 continue; 5665 } 5666 /* this is an event relating to a 'normal' connection, 5667 remember the event and if appropriate mark the 5668 connection as 'eready'. */ 5669 pos = events[i].data.ptr; 5670 /* normal processing: update read/write data */ 5671 if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP))) 5672 { 5673 pos->epoll_state |= MHD_EPOLL_STATE_ERROR; 5674 if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) 5675 { 5676 EDLL_insert (daemon->eready_head, 5677 daemon->eready_tail, 5678 pos); 5679 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; 5680 } 5681 } 5682 else 5683 { 5684 if (0 != (events[i].events & EPOLLIN)) 5685 { 5686 pos->epoll_state |= MHD_EPOLL_STATE_READ_READY; 5687 if ( ( (0 != (MHD_EVENT_LOOP_INFO_READ & pos->event_loop_info)) || 5688 (pos->read_buffer_size > pos->read_buffer_offset) ) && 5689 (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) 5690 { 5691 EDLL_insert (daemon->eready_head, 5692 daemon->eready_tail, 5693 pos); 5694 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; 5695 } 5696 } 5697 if (0 != (events[i].events & EPOLLOUT)) 5698 { 5699 pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY; 5700 if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) && 5701 (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) 5702 { 5703 EDLL_insert (daemon->eready_head, 5704 daemon->eready_tail, 5705 pos); 5706 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; 5707 } 5708 } 5709 } 5710 } 5711 } 5712 5713 /* Process externally added connection if any */ 5714 if (daemon->have_new) 5715 new_connections_list_process_ (daemon); 5716 5717 if (need_to_accept) 5718 { 5719 unsigned int series_length = 0; 5720 5721 /* Run 'accept' until it fails or daemon at limit of connections. 5722 * Do not accept more then 10 connections at once. The rest will 5723 * be accepted on next turn (level trigger is used for listen 5724 * socket). */ 5725 while ( (MHD_NO != MHD_accept_connection (daemon)) && 5726 (series_length < 10) && 5727 (daemon->connections < daemon->connection_limit) && 5728 (! daemon->at_limit) ) 5729 series_length++; 5730 } 5731 5732 /* Handle timed-out connections; we need to do this here 5733 as the epoll mechanism won't call the 'MHD_connection_handle_idle()' on everything, 5734 as the other event loops do. As timeouts do not get an explicit 5735 event, we need to find those connections that might have timed out 5736 here. 5737 5738 Connections with custom timeouts must all be looked at, as we 5739 do not bother to sort that (presumably very short) list. */ 5740 prev = daemon->manual_timeout_tail; 5741 while (NULL != (pos = prev)) 5742 { 5743 prev = pos->prevX; 5744 MHD_connection_handle_idle (pos); 5745 } 5746 /* Connections with the default timeout are sorted by prepending 5747 them to the head of the list whenever we touch the connection; 5748 thus it suffices to iterate from the tail until the first 5749 connection is NOT timed out */ 5750 prev = daemon->normal_timeout_tail; 5751 while (NULL != (pos = prev)) 5752 { 5753 prev = pos->prevX; 5754 MHD_connection_handle_idle (pos); 5755 if (MHD_CONNECTION_CLOSED != pos->state) 5756 break; /* sorted by timeout, no need to visit the rest! */ 5757 } 5758 5759 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5760 if (run_upgraded || (NULL != daemon->eready_urh_head)) 5761 run_epoll_for_upgrade (daemon); 5762 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 5763 5764 /* process events for connections */ 5765 prev = daemon->eready_tail; 5766 while (NULL != (pos = prev)) 5767 { 5768 prev = pos->prevE; 5769 call_handlers (pos, 5770 0 != (pos->epoll_state & MHD_EPOLL_STATE_READ_READY), 5771 0 != (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY), 5772 0 != (pos->epoll_state & MHD_EPOLL_STATE_ERROR)); 5773 if (MHD_EPOLL_STATE_IN_EREADY_EDLL == 5774 (pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED 5775 | MHD_EPOLL_STATE_IN_EREADY_EDLL))) 5776 { 5777 if ( ((MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) && 5778 (0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) || 5779 ((MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) && 5780 (0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) ) || 5781 (MHD_EVENT_LOOP_INFO_CLEANUP == pos->event_loop_info) ) 5782 { 5783 EDLL_remove (daemon->eready_head, 5784 daemon->eready_tail, 5785 pos); 5786 pos->epoll_state &= 5787 ~((enum MHD_EpollState) MHD_EPOLL_STATE_IN_EREADY_EDLL); 5788 } 5789 } 5790 } 5791 5792 return MHD_YES; 5793 } 5794 5795 5796 #endif 5797 5798 5799 /** 5800 * Run webserver operations (without blocking unless in client callbacks). 5801 * 5802 * This method should be called by clients in combination with 5803 * #MHD_get_fdset() (or #MHD_get_daemon_info() with MHD_DAEMON_INFO_EPOLL_FD 5804 * if epoll is used) and #MHD_get_timeout() if the client-controlled 5805 * connection polling method is used (i.e. daemon was started without 5806 * #MHD_USE_INTERNAL_POLLING_THREAD flag). 5807 * 5808 * This function is a convenience method, which is useful if the 5809 * fd_sets from #MHD_get_fdset were not directly passed to `select()`; 5810 * with this function, MHD will internally do the appropriate `select()` 5811 * call itself again. While it is acceptable to call #MHD_run (if 5812 * #MHD_USE_INTERNAL_POLLING_THREAD is not set) at any moment, you should 5813 * call #MHD_run_from_select() if performance is important (as it saves an 5814 * expensive call to `select()`). 5815 * 5816 * If #MHD_get_timeout() returned #MHD_YES, than this function must be called 5817 * right after polling function returns regardless of detected activity on 5818 * the daemon's FDs. 5819 * 5820 * @param daemon daemon to run 5821 * @return #MHD_YES on success, #MHD_NO if this 5822 * daemon was not started with the right 5823 * options for this call. 5824 * @ingroup event 5825 */ 5826 _MHD_EXTERN enum MHD_Result 5827 MHD_run (struct MHD_Daemon *daemon) 5828 { 5829 if ( (daemon->shutdown) || 5830 MHD_D_IS_USING_THREADS_ (daemon) ) 5831 return MHD_NO; 5832 5833 (void) MHD_run_wait (daemon, 0); 5834 return MHD_YES; 5835 } 5836 5837 5838 /** 5839 * Run webserver operation with possible blocking. 5840 * 5841 * This function does the following: waits for any network event not more than 5842 * specified number of milliseconds, processes all incoming and outgoing data, 5843 * processes new connections, processes any timed-out connection, and does 5844 * other things required to run webserver. 5845 * Once all connections are processed, function returns. 5846 * 5847 * This function is useful for quick and simple (lazy) webserver implementation 5848 * if application needs to run a single thread only and does not have any other 5849 * network activity. 5850 * 5851 * This function calls MHD_get_timeout() internally and use returned value as 5852 * maximum wait time if it less than value of @a millisec parameter. 5853 * 5854 * It is expected that the "external" socket polling function is not used in 5855 * conjunction with this function unless the @a millisec is set to zero. 5856 * 5857 * @param daemon the daemon to run 5858 * @param millisec the maximum time in milliseconds to wait for network and 5859 * other events. Note: there is no guarantee that function 5860 * blocks for the specified amount of time. The real processing 5861 * time can be shorter (if some data or connection timeout 5862 * comes earlier) or longer (if data processing requires more 5863 * time, especially in user callbacks). 5864 * If set to '0' then function does not block and processes 5865 * only already available data (if any). 5866 * If set to '-1' then function waits for events 5867 * indefinitely (blocks until next network activity or 5868 * connection timeout). 5869 * @return #MHD_YES on success, #MHD_NO if this 5870 * daemon was not started with the right 5871 * options for this call or some serious 5872 * unrecoverable error occurs. 5873 * @note Available since #MHD_VERSION 0x00097206 5874 * @ingroup event 5875 */ 5876 _MHD_EXTERN enum MHD_Result 5877 MHD_run_wait (struct MHD_Daemon *daemon, 5878 int32_t millisec) 5879 { 5880 enum MHD_Result res; 5881 if ( (daemon->shutdown) || 5882 MHD_D_IS_USING_THREADS_ (daemon) ) 5883 return MHD_NO; 5884 5885 mhd_assert (! MHD_thread_handle_ID_is_valid_handle_ (daemon->tid)); 5886 5887 if (0 > millisec) 5888 millisec = -1; 5889 #ifdef HAVE_POLL 5890 if (MHD_D_IS_USING_POLL_ (daemon)) 5891 { 5892 res = MHD_poll_all (daemon, millisec); 5893 MHD_cleanup_connections (daemon); 5894 } 5895 else 5896 #endif /* HAVE_POLL */ 5897 #ifdef EPOLL_SUPPORT 5898 if (MHD_D_IS_USING_EPOLL_ (daemon)) 5899 { 5900 res = MHD_epoll (daemon, millisec); 5901 MHD_cleanup_connections (daemon); 5902 } 5903 else 5904 #endif 5905 if (1) 5906 { 5907 mhd_assert (MHD_D_IS_USING_SELECT_ (daemon)); 5908 #ifdef HAS_FD_SETSIZE_OVERRIDABLE 5909 #ifdef HAVE_MESSAGES 5910 if (daemon->fdset_size_set_by_app 5911 && (((int) FD_SETSIZE) < daemon->fdset_size)) 5912 { 5913 MHD_DLOG (daemon, 5914 _ ("MHD_run()/MHD_run_wait() called for daemon started with " \ 5915 "MHD_OPTION_APP_FD_SETSIZE option (%d). " \ 5916 "The library was compiled with smaller FD_SETSIZE (%d). " \ 5917 "Some socket FDs may be not processed. " \ 5918 "Use MHD_run_from_select2() instead of MHD_run() or " \ 5919 "do not use MHD_OPTION_APP_FD_SETSIZE option.\n"), 5920 daemon->fdset_size, (int) FD_SETSIZE); 5921 } 5922 #endif /* HAVE_MESSAGES */ 5923 #endif /* HAS_FD_SETSIZE_OVERRIDABLE */ 5924 5925 res = MHD_select (daemon, millisec); 5926 /* MHD_select does MHD_cleanup_connections already */ 5927 } 5928 return res; 5929 } 5930 5931 5932 /** 5933 * Close the given connection, remove it from all of its 5934 * DLLs and move it into the cleanup queue. 5935 * @remark To be called only from thread that 5936 * process daemon's select()/poll()/etc. 5937 * 5938 * @param pos connection to move to cleanup 5939 */ 5940 static void 5941 close_connection (struct MHD_Connection *pos) 5942 { 5943 struct MHD_Daemon *daemon = pos->daemon; 5944 5945 #ifdef MHD_USE_THREADS 5946 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 5947 MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); 5948 mhd_assert (NULL == daemon->worker_pool); 5949 #endif /* MHD_USE_THREADS */ 5950 5951 if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) 5952 { 5953 MHD_connection_mark_closed_ (pos); 5954 return; /* must let thread to do the rest */ 5955 } 5956 MHD_connection_close_ (pos, 5957 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN); 5958 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5959 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 5960 #endif 5961 mhd_assert (! pos->suspended); 5962 mhd_assert (! pos->resuming); 5963 if (pos->connection_timeout_ms == daemon->connection_timeout_ms) 5964 XDLL_remove (daemon->normal_timeout_head, 5965 daemon->normal_timeout_tail, 5966 pos); 5967 else 5968 XDLL_remove (daemon->manual_timeout_head, 5969 daemon->manual_timeout_tail, 5970 pos); 5971 DLL_remove (daemon->connections_head, 5972 daemon->connections_tail, 5973 pos); 5974 DLL_insert (daemon->cleanup_head, 5975 daemon->cleanup_tail, 5976 pos); 5977 daemon->data_already_pending = true; 5978 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5979 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 5980 #endif 5981 } 5982 5983 5984 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5985 /** 5986 * Thread that runs the polling loop until the daemon 5987 * is explicitly shut down. 5988 * 5989 * @param cls `struct MHD_Deamon` to run select loop in a thread for 5990 * @return always 0 (on shutdown) 5991 */ 5992 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ 5993 MHD_polling_thread (void *cls) 5994 { 5995 struct MHD_Daemon *daemon = cls; 5996 #ifdef HAVE_PTHREAD_SIGMASK 5997 sigset_t s_mask; 5998 int err; 5999 #endif /* HAVE_PTHREAD_SIGMASK */ 6000 6001 MHD_thread_handle_ID_set_current_thread_ID_ (&(daemon->tid)); 6002 #ifdef HAVE_PTHREAD_SIGMASK 6003 if ((0 == sigemptyset (&s_mask)) && 6004 (0 == sigaddset (&s_mask, SIGPIPE))) 6005 { 6006 err = pthread_sigmask (SIG_BLOCK, &s_mask, NULL); 6007 } 6008 else 6009 err = errno; 6010 if (0 == err) 6011 daemon->sigpipe_blocked = true; 6012 #ifdef HAVE_MESSAGES 6013 else 6014 MHD_DLOG (daemon, 6015 _ ("Failed to block SIGPIPE on daemon thread: %s\n"), 6016 MHD_strerror_ (errno)); 6017 #endif /* HAVE_MESSAGES */ 6018 #endif /* HAVE_PTHREAD_SIGMASK */ 6019 while (! daemon->shutdown) 6020 { 6021 #ifdef HAVE_POLL 6022 if (MHD_D_IS_USING_POLL_ (daemon)) 6023 MHD_poll (daemon, MHD_YES); 6024 else 6025 #endif /* HAVE_POLL */ 6026 #ifdef EPOLL_SUPPORT 6027 if (MHD_D_IS_USING_EPOLL_ (daemon)) 6028 MHD_epoll (daemon, -1); 6029 else 6030 #endif 6031 MHD_select (daemon, -1); 6032 MHD_cleanup_connections (daemon); 6033 } 6034 6035 /* Resume any pending for resume connections, join 6036 * all connection's threads (if any) and finally cleanup 6037 * everything. */ 6038 if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options)) 6039 resume_suspended_connections (daemon); 6040 close_all_connections (daemon); 6041 6042 return (MHD_THRD_RTRN_TYPE_) 0; 6043 } 6044 6045 6046 #endif 6047 6048 6049 /** 6050 * Process escape sequences ('%HH') Updates val in place; the 6051 * result cannot be larger than the input. 6052 * The result must also still be 0-terminated. 6053 * 6054 * @param cls closure (use NULL) 6055 * @param connection handle to connection, not used 6056 * @param val value to unescape (modified in the process) 6057 * @return length of the resulting val (strlen(val) maybe 6058 * shorter afterwards due to elimination of escape sequences) 6059 */ 6060 static size_t 6061 unescape_wrapper (void *cls, 6062 struct MHD_Connection *connection, 6063 char *val) 6064 { 6065 bool broken; 6066 size_t res; 6067 (void) cls; /* Mute compiler warning. */ 6068 6069 /* TODO: add individual parameter */ 6070 if (0 <= connection->daemon->client_discipline) 6071 return MHD_str_pct_decode_in_place_strict_ (val); 6072 6073 res = MHD_str_pct_decode_in_place_lenient_ (val, &broken); 6074 #ifdef HAVE_MESSAGES 6075 if (broken) 6076 { 6077 MHD_DLOG (connection->daemon, 6078 _ ("The URL encoding is broken.\n")); 6079 } 6080 #endif /* HAVE_MESSAGES */ 6081 return res; 6082 } 6083 6084 6085 /** 6086 * Start a webserver on the given port. Variadic version of 6087 * #MHD_start_daemon_va. 6088 * 6089 * @param flags combination of `enum MHD_FLAG` values 6090 * @param port port to bind to (in host byte order), 6091 * use '0' to bind to random free port, 6092 * ignored if #MHD_OPTION_SOCK_ADDR or 6093 * #MHD_OPTION_LISTEN_SOCKET is provided 6094 * or #MHD_USE_NO_LISTEN_SOCKET is specified 6095 * @param apc callback to call to check which clients 6096 * will be allowed to connect; you can pass NULL 6097 * in which case connections from any IP will be 6098 * accepted 6099 * @param apc_cls extra argument to @a apc 6100 * @param dh handler called for all requests (repeatedly) 6101 * @param dh_cls extra argument to @a dh 6102 * @return NULL on error, handle to daemon on success 6103 * @ingroup event 6104 */ 6105 _MHD_EXTERN struct MHD_Daemon * 6106 MHD_start_daemon (unsigned int flags, 6107 uint16_t port, 6108 MHD_AcceptPolicyCallback apc, 6109 void *apc_cls, 6110 MHD_AccessHandlerCallback dh, 6111 void *dh_cls, 6112 ...) 6113 { 6114 struct MHD_Daemon *daemon; 6115 va_list ap; 6116 6117 va_start (ap, 6118 dh_cls); 6119 daemon = MHD_start_daemon_va (flags, 6120 port, 6121 apc, 6122 apc_cls, 6123 dh, 6124 dh_cls, 6125 ap); 6126 va_end (ap); 6127 return daemon; 6128 } 6129 6130 6131 /** 6132 * Stop accepting connections from the listening socket. Allows 6133 * clients to continue processing, but stops accepting new 6134 * connections. Note that the caller is responsible for closing the 6135 * returned socket; however, if MHD is run using threads (anything but 6136 * external select mode), socket will be removed from existing threads 6137 * with some delay and it must not be closed while it's in use. To make 6138 * sure that the socket is not used anymore, call #MHD_stop_daemon. 6139 * 6140 * Note that some thread modes require the caller to have passed 6141 * #MHD_USE_ITC when using this API. If this daemon is 6142 * in one of those modes and this option was not given to 6143 * #MHD_start_daemon, this function will return #MHD_INVALID_SOCKET. 6144 * 6145 * @param daemon daemon to stop accepting new connections for 6146 * @return old listen socket on success, #MHD_INVALID_SOCKET if 6147 * the daemon was already not listening anymore 6148 * @ingroup specialized 6149 */ 6150 _MHD_EXTERN MHD_socket 6151 MHD_quiesce_daemon (struct MHD_Daemon *daemon) 6152 { 6153 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6154 unsigned int i; 6155 #endif 6156 MHD_socket ret; 6157 6158 ret = daemon->listen_fd; 6159 if ((MHD_INVALID_SOCKET == ret) 6160 || daemon->was_quiesced) 6161 return MHD_INVALID_SOCKET; 6162 if ( (0 == (daemon->options & (MHD_USE_ITC))) && 6163 MHD_D_IS_USING_THREADS_ (daemon) ) 6164 { 6165 #ifdef HAVE_MESSAGES 6166 MHD_DLOG (daemon, 6167 _ ("Using MHD_quiesce_daemon in this mode " \ 6168 "requires MHD_USE_ITC.\n")); 6169 #endif 6170 return MHD_INVALID_SOCKET; 6171 } 6172 6173 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6174 if (NULL != daemon->worker_pool) 6175 for (i = 0; i < daemon->worker_pool_size; i++) 6176 { 6177 daemon->worker_pool[i].was_quiesced = true; 6178 #ifdef EPOLL_SUPPORT 6179 if (MHD_D_IS_USING_EPOLL_ (daemon) && 6180 (-1 != daemon->worker_pool[i].epoll_fd) && 6181 (daemon->worker_pool[i].listen_socket_in_epoll) ) 6182 { 6183 if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd, 6184 EPOLL_CTL_DEL, 6185 ret, 6186 NULL)) 6187 MHD_PANIC (_ ("Failed to remove listen FD from epoll set.\n")); 6188 daemon->worker_pool[i].listen_socket_in_epoll = false; 6189 } 6190 else 6191 #endif 6192 if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc)) 6193 { 6194 if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "q")) 6195 MHD_PANIC (_ ("Failed to signal quiesce via inter-thread " \ 6196 "communication channel.\n")); 6197 } 6198 } 6199 #endif 6200 daemon->was_quiesced = true; 6201 #ifdef EPOLL_SUPPORT 6202 if (MHD_D_IS_USING_EPOLL_ (daemon) && 6203 (-1 != daemon->epoll_fd) && 6204 (daemon->listen_socket_in_epoll) ) 6205 { 6206 if ( (0 != epoll_ctl (daemon->epoll_fd, 6207 EPOLL_CTL_DEL, 6208 ret, 6209 NULL)) && 6210 (ENOENT != errno) ) /* ENOENT can happen due to race with 6211 #MHD_epoll() */ 6212 MHD_PANIC ("Failed to remove listen FD from epoll set.\n"); 6213 daemon->listen_socket_in_epoll = false; 6214 } 6215 #endif 6216 if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && 6217 (! MHD_itc_activate_ (daemon->itc, "q")) ) 6218 MHD_PANIC (_ ("failed to signal quiesce via inter-thread " \ 6219 "communication channel.\n")); 6220 return ret; 6221 } 6222 6223 6224 /** 6225 * Temporal location of the application-provided parameters/options. 6226 * Used when options are decoded from #MHD_start_deamon() parameters, but 6227 * not yet processed/applied. 6228 */ 6229 struct MHD_InterimParams_ 6230 { 6231 /** 6232 * The total number of all user options used. 6233 * 6234 * Contains number only of meaningful options, i.e. #MHD_OPTION_END and 6235 * #MHD_OPTION_ARRAY themselves are not counted, while options inside 6236 * #MHD_OPTION_ARRAY are counted. 6237 */ 6238 size_t num_opts; 6239 /** 6240 * Set to 'true' if @a fdset_size is set by application. 6241 */ 6242 bool fdset_size_set; 6243 /** 6244 * The value for #MHD_OPTION_APP_FD_SETSIZE set by application. 6245 */ 6246 int fdset_size; 6247 /** 6248 * Set to 'true' if @a listen_fd is set by application. 6249 */ 6250 bool listen_fd_set; 6251 /** 6252 * Application-provided listen socket. 6253 */ 6254 MHD_socket listen_fd; 6255 /** 6256 * Set to 'true' if @a server_addr is set by application. 6257 */ 6258 bool pserver_addr_set; 6259 /** 6260 * Application-provided struct sockaddr to bind server to. 6261 */ 6262 const struct sockaddr *pserver_addr; 6263 /** 6264 * Set to 'true' if @a server_addr_len is set by application. 6265 */ 6266 bool server_addr_len_set; 6267 /** 6268 * Applicaiton-provided the size of the memory pointed by @a server_addr. 6269 */ 6270 socklen_t server_addr_len; 6271 }; 6272 6273 /** 6274 * Signature of the MHD custom logger function. 6275 * 6276 * @param cls closure 6277 * @param format format string 6278 * @param va arguments to the format string (fprintf-style) 6279 */ 6280 typedef void 6281 (*VfprintfFunctionPointerType)(void *cls, 6282 const char *format, 6283 va_list va); 6284 6285 6286 /** 6287 * Parse a list of options given as varargs. 6288 * 6289 * @param daemon the daemon to initialize 6290 * @param servaddr where to store the server's listen address 6291 * @param params the interim parameters to be assigned to 6292 * @param ap the options 6293 * @return #MHD_YES on success, #MHD_NO on error 6294 */ 6295 static enum MHD_Result 6296 parse_options_va (struct MHD_Daemon *daemon, 6297 struct MHD_InterimParams_ *params, 6298 va_list ap); 6299 6300 6301 /** 6302 * Parse a list of options given as varargs. 6303 * 6304 * @param daemon the daemon to initialize 6305 * @param servaddr where to store the server's listen address 6306 * @param params the interim parameters to be assigned to 6307 * @param ... the options 6308 * @return #MHD_YES on success, #MHD_NO on error 6309 */ 6310 static enum MHD_Result 6311 parse_options (struct MHD_Daemon *daemon, 6312 struct MHD_InterimParams_ *params, 6313 ...) 6314 { 6315 va_list ap; 6316 enum MHD_Result ret; 6317 6318 va_start (ap, params); 6319 ret = parse_options_va (daemon, 6320 params, 6321 ap); 6322 va_end (ap); 6323 return ret; 6324 } 6325 6326 6327 #ifdef HTTPS_SUPPORT 6328 /** 6329 * Type of GnuTLS priorities base string 6330 */ 6331 enum MHD_TlsPrioritiesBaseType 6332 { 6333 MHD_TLS_PRIO_BASE_LIBMHD = 0, /**< @c "@LIBMICROHTTPD" */ 6334 MHD_TLS_PRIO_BASE_SYSTEM = 1, /**< @c "@SYSTEM" */ 6335 #if GNUTLS_VERSION_NUMBER >= 0x030300 6336 MHD_TLS_PRIO_BASE_DEFAULT, /**< Default priorities string */ 6337 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */ 6338 MHD_TLS_PRIO_BASE_NORMAL /**< @c "NORMAL */ 6339 }; 6340 6341 static const struct _MHD_cstr_w_len MHD_TlsBasePriotities[] = { 6342 _MHD_S_STR_W_LEN ("@LIBMICROHTTPD"), 6343 _MHD_S_STR_W_LEN ("@SYSTEM"), 6344 #if GNUTLS_VERSION_NUMBER >= 0x030300 6345 {NULL, 0}, 6346 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */ 6347 _MHD_S_STR_W_LEN ("NORMAL") 6348 }; 6349 6350 /** 6351 * Initialise TLS priorities with default settings 6352 * @param daemon the daemon to initialise TLS priorities 6353 * @return true on success, false on error 6354 */ 6355 static bool 6356 daemon_tls_priorities_init_default (struct MHD_Daemon *daemon) 6357 { 6358 unsigned int p; 6359 int res; 6360 6361 mhd_assert (0 != (((unsigned int) daemon->options) & MHD_USE_TLS)); 6362 mhd_assert (NULL == daemon->priority_cache); 6363 mhd_assert (MHD_TLS_PRIO_BASE_NORMAL + 1 == \ 6364 sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0])); 6365 6366 res = GNUTLS_E_SUCCESS; /* Mute compiler warning */ 6367 6368 for (p = 0; 6369 p < sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0]); 6370 ++p) 6371 { 6372 res = gnutls_priority_init (&daemon->priority_cache, 6373 MHD_TlsBasePriotities[p].str, NULL); 6374 if (GNUTLS_E_SUCCESS == res) 6375 { 6376 #ifdef _DEBUG 6377 #ifdef HAVE_MESSAGES 6378 switch ((enum MHD_TlsPrioritiesBaseType) p) 6379 { 6380 case MHD_TLS_PRIO_BASE_LIBMHD: 6381 MHD_DLOG (daemon, 6382 _ ("GnuTLS priorities have been initialised with " \ 6383 "@LIBMICROHTTPD application-specific system-wide " \ 6384 "configuration.\n") ); 6385 break; 6386 case MHD_TLS_PRIO_BASE_SYSTEM: 6387 MHD_DLOG (daemon, 6388 _ ("GnuTLS priorities have been initialised with " \ 6389 "@SYSTEM system-wide configuration.\n") ); 6390 break; 6391 #if GNUTLS_VERSION_NUMBER >= 0x030300 6392 case MHD_TLS_PRIO_BASE_DEFAULT: 6393 MHD_DLOG (daemon, 6394 _ ("GnuTLS priorities have been initialised with " \ 6395 "GnuTLS default configuration.\n") ); 6396 break; 6397 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */ 6398 case MHD_TLS_PRIO_BASE_NORMAL: 6399 MHD_DLOG (daemon, 6400 _ ("GnuTLS priorities have been initialised with " \ 6401 "NORMAL configuration.\n") ); 6402 break; 6403 default: 6404 mhd_assert (0); 6405 } 6406 #endif /* HAVE_MESSAGES */ 6407 #endif /* _DEBUG */ 6408 return true; 6409 } 6410 } 6411 #ifdef HAVE_MESSAGES 6412 MHD_DLOG (daemon, 6413 _ ("Failed to set GnuTLS priorities. Last error: %s\n"), 6414 gnutls_strerror (res)); 6415 #endif /* HAVE_MESSAGES */ 6416 return false; 6417 } 6418 6419 6420 /** 6421 * The inner helper function for #daemon_tls_priorities_init_app(). 6422 * @param daemon the daemon to use 6423 * @param prio the appication-specified appendix for default priorities 6424 * @param prio_len the length of @a prio 6425 * @param buf the temporal buffer for string manipulations 6426 * @param buf_size the size of the @a buf 6427 * @return true on success, false on error 6428 */ 6429 static bool 6430 daemon_tls_priorities_init_append_inner_ (struct MHD_Daemon *daemon, 6431 const char *prio, 6432 size_t prio_len, 6433 char *buf, 6434 const size_t buf_size) 6435 { 6436 unsigned int p; 6437 int res; 6438 const char *err_pos; 6439 6440 (void) buf_size; /* Mute compiler warning for non-Debug builds */ 6441 mhd_assert (0 != (((unsigned int) daemon->options) & MHD_USE_TLS)); 6442 mhd_assert (NULL == daemon->priority_cache); 6443 mhd_assert (MHD_TLS_PRIO_BASE_NORMAL + 1 == \ 6444 sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0])); 6445 6446 res = GNUTLS_E_SUCCESS; /* Mute compiler warning */ 6447 6448 for (p = 0; 6449 p < sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0]); 6450 ++p) 6451 { 6452 6453 #if GNUTLS_VERSION_NUMBER >= 0x030300 6454 #if GNUTLS_VERSION_NUMBER >= 0x030603 6455 if (NULL == MHD_TlsBasePriotities[p].str) 6456 res = gnutls_priority_init2 (&daemon->priority_cache, prio, &err_pos, 6457 GNUTLS_PRIORITY_INIT_DEF_APPEND); 6458 else 6459 #else /* 0x030300 <= GNUTLS_VERSION_NUMBER 6460 && GNUTLS_VERSION_NUMBER < 0x030603 */ 6461 if (NULL == MHD_TlsBasePriotities[p].str) 6462 continue; /* Skip the value, no way to append priorities to the default string */ 6463 else 6464 #endif /* GNUTLS_VERSION_NUMBER < 0x030603 */ 6465 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */ 6466 if (1) 6467 { 6468 size_t buf_pos; 6469 6470 mhd_assert (NULL != MHD_TlsBasePriotities[p].str); 6471 buf_pos = 0; 6472 memcpy (buf + buf_pos, MHD_TlsBasePriotities[p].str, 6473 MHD_TlsBasePriotities[p].len); 6474 buf_pos += MHD_TlsBasePriotities[p].len; 6475 buf[buf_pos++] = ':'; 6476 memcpy (buf + buf_pos, prio, prio_len + 1); 6477 #ifdef _DEBUG 6478 buf_pos += prio_len + 1; 6479 mhd_assert (buf_size >= buf_pos); 6480 #endif /* _DEBUG */ 6481 res = gnutls_priority_init (&daemon->priority_cache, buf, &err_pos); 6482 } 6483 if (GNUTLS_E_SUCCESS == res) 6484 { 6485 #ifdef _DEBUG 6486 #ifdef HAVE_MESSAGES 6487 switch ((enum MHD_TlsPrioritiesBaseType) p) 6488 { 6489 case MHD_TLS_PRIO_BASE_LIBMHD: 6490 MHD_DLOG (daemon, 6491 _ ("GnuTLS priorities have been initialised with " \ 6492 "priorities specified by application appended to " \ 6493 "@LIBMICROHTTPD application-specific system-wide " \ 6494 "configuration.\n") ); 6495 break; 6496 case MHD_TLS_PRIO_BASE_SYSTEM: 6497 MHD_DLOG (daemon, 6498 _ ("GnuTLS priorities have been initialised with " \ 6499 "priorities specified by application appended to " \ 6500 "@SYSTEM system-wide configuration.\n") ); 6501 break; 6502 #if GNUTLS_VERSION_NUMBER >= 0x030300 6503 case MHD_TLS_PRIO_BASE_DEFAULT: 6504 MHD_DLOG (daemon, 6505 _ ("GnuTLS priorities have been initialised with " \ 6506 "priorities specified by application appended to " \ 6507 "GnuTLS default configuration.\n") ); 6508 break; 6509 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */ 6510 case MHD_TLS_PRIO_BASE_NORMAL: 6511 MHD_DLOG (daemon, 6512 _ ("GnuTLS priorities have been initialised with " \ 6513 "priorities specified by application appended to " \ 6514 "NORMAL configuration.\n") ); 6515 break; 6516 default: 6517 mhd_assert (0); 6518 } 6519 #endif /* HAVE_MESSAGES */ 6520 #endif /* _DEBUG */ 6521 return true; 6522 } 6523 } 6524 #ifdef HAVE_MESSAGES 6525 MHD_DLOG (daemon, 6526 _ ("Failed to set GnuTLS priorities. Last error: %s. " \ 6527 "The problematic part starts at: %s\n"), 6528 gnutls_strerror (res), err_pos); 6529 #endif /* HAVE_MESSAGES */ 6530 return false; 6531 } 6532 6533 6534 #define LOCAL_BUFF_SIZE 128 6535 6536 /** 6537 * Initialise TLS priorities with default settings with application-specified 6538 * appended string. 6539 * @param daemon the daemon to initialise TLS priorities 6540 * @param prio the application specified priorities to be appended to 6541 * the GnuTLS standard priorities string 6542 * @return true on success, false on error 6543 */ 6544 static bool 6545 daemon_tls_priorities_init_append (struct MHD_Daemon *daemon, const char *prio) 6546 { 6547 static const size_t longest_base_prio = MHD_STATICSTR_LEN_ ("@LIBMICROHTTPD"); 6548 bool ret; 6549 size_t prio_len; 6550 size_t buf_size_needed; 6551 6552 if (NULL == prio) 6553 return daemon_tls_priorities_init_default (daemon); 6554 6555 if (':' == prio[0]) 6556 ++prio; 6557 6558 prio_len = strlen (prio); 6559 6560 buf_size_needed = longest_base_prio + 1 + prio_len + 1; 6561 6562 if (LOCAL_BUFF_SIZE >= buf_size_needed) 6563 { 6564 char local_buffer[LOCAL_BUFF_SIZE]; 6565 ret = daemon_tls_priorities_init_append_inner_ (daemon, prio, prio_len, 6566 local_buffer, 6567 LOCAL_BUFF_SIZE); 6568 } 6569 else 6570 { 6571 char *allocated_buffer; 6572 allocated_buffer = (char *) malloc (buf_size_needed); 6573 if (NULL == allocated_buffer) 6574 { 6575 #ifdef HAVE_MESSAGES 6576 MHD_DLOG (daemon, 6577 _ ("Error allocating memory: %s\n"), 6578 MHD_strerror_ (errno)); 6579 #endif 6580 return false; 6581 } 6582 ret = daemon_tls_priorities_init_append_inner_ (daemon, prio, prio_len, 6583 allocated_buffer, 6584 buf_size_needed); 6585 free (allocated_buffer); 6586 } 6587 return ret; 6588 } 6589 6590 6591 #endif /* HTTPS_SUPPORT */ 6592 6593 6594 /** 6595 * Parse a list of options given as varargs. 6596 * 6597 * @param[in,out] daemon the daemon to initialize 6598 * @param[out] params the interim parameters to be assigned to 6599 * @param ap the options 6600 * @return #MHD_YES on success, #MHD_NO on error 6601 */ 6602 static enum MHD_Result 6603 parse_options_va (struct MHD_Daemon *daemon, 6604 struct MHD_InterimParams_ *params, 6605 va_list ap) 6606 { 6607 enum MHD_OPTION opt; 6608 struct MHD_OptionItem *oa; 6609 unsigned int i; 6610 unsigned int uv; 6611 #ifdef HTTPS_SUPPORT 6612 const char *pstr; 6613 #if GNUTLS_VERSION_MAJOR >= 3 6614 gnutls_certificate_retrieve_function2 * pgcrf; 6615 #endif 6616 #if GNUTLS_VERSION_NUMBER >= 0x030603 6617 gnutls_certificate_retrieve_function3 * pgcrf2; 6618 #endif 6619 #endif /* HTTPS_SUPPORT */ 6620 6621 while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int))) 6622 { 6623 /* Increase counter at start, so resulting value is number of 6624 * processed options, including any failed ones. */ 6625 params->num_opts++; 6626 switch (opt) 6627 { 6628 case MHD_OPTION_CONNECTION_MEMORY_LIMIT: 6629 if (1) 6630 { 6631 size_t val; 6632 6633 val = va_arg (ap, 6634 size_t); 6635 if (0 != val) 6636 { 6637 daemon->pool_size = val; 6638 if (64 > daemon->pool_size) 6639 { 6640 #ifdef HAVE_MESSAGES 6641 MHD_DLOG (daemon, 6642 _ ("Warning: specified " \ 6643 "MHD_OPTION_CONNECTION_MEMORY_LIMIT " \ 6644 "value is too small and rounded up to 64.\n")); 6645 #endif /* HAVE_MESSAGES */ 6646 daemon->pool_size = 64; 6647 } 6648 if (daemon->pool_size / 4 < daemon->pool_increment) 6649 daemon->pool_increment = daemon->pool_size / 4; 6650 } 6651 } 6652 break; 6653 case MHD_OPTION_CONNECTION_MEMORY_INCREMENT: 6654 if (1) 6655 { 6656 size_t val; 6657 6658 val = va_arg (ap, 6659 size_t); 6660 6661 if (0 != val) 6662 { 6663 daemon->pool_increment = val; 6664 if (daemon->pool_size / 4 < daemon->pool_increment) 6665 { 6666 #ifdef HAVE_MESSAGES 6667 MHD_DLOG (daemon, 6668 _ ("Warning: specified " \ 6669 "MHD_OPTION_CONNECTION_MEMORY_INCREMENT value is " \ 6670 "too large and rounded down to 1/4 of " \ 6671 "MHD_OPTION_CONNECTION_MEMORY_LIMIT.\n")); 6672 #endif /* HAVE_MESSAGES */ 6673 daemon->pool_increment = daemon->pool_size / 4; 6674 } 6675 } 6676 } 6677 break; 6678 case MHD_OPTION_CONNECTION_LIMIT: 6679 daemon->connection_limit = va_arg (ap, 6680 unsigned int); 6681 break; 6682 case MHD_OPTION_CONNECTION_TIMEOUT: 6683 uv = va_arg (ap, 6684 unsigned int); 6685 #if (SIZEOF_UINT64_T - 2) <= SIZEOF_UNSIGNED_INT 6686 if ((UINT64_MAX / 4000 - 1) < uv) 6687 { 6688 #ifdef HAVE_MESSAGES 6689 MHD_DLOG (daemon, 6690 _ ("The specified connection timeout (%u) is too large. " \ 6691 "Maximum allowed value (%" PRIu64 ") will be used " \ 6692 "instead.\n"), 6693 uv, 6694 (UINT64_MAX / 4000 - 1)); 6695 #endif 6696 uv = UINT64_MAX / 4000 - 1; 6697 } 6698 #endif /* (SIZEOF_UINT64_T - 2) <= SIZEOF_UNSIGNED_INT */ 6699 daemon->connection_timeout_ms = ((uint64_t) uv) * 1000; 6700 break; 6701 case MHD_OPTION_NOTIFY_COMPLETED: 6702 daemon->notify_completed = va_arg (ap, 6703 MHD_RequestCompletedCallback); 6704 daemon->notify_completed_cls = va_arg (ap, 6705 void *); 6706 break; 6707 case MHD_OPTION_NOTIFY_CONNECTION: 6708 daemon->notify_connection = va_arg (ap, 6709 MHD_NotifyConnectionCallback); 6710 daemon->notify_connection_cls = va_arg (ap, 6711 void *); 6712 break; 6713 case MHD_OPTION_PER_IP_CONNECTION_LIMIT: 6714 daemon->per_ip_connection_limit = va_arg (ap, 6715 unsigned int); 6716 break; 6717 case MHD_OPTION_SOCK_ADDR_LEN: 6718 params->server_addr_len = va_arg (ap, 6719 socklen_t); 6720 params->server_addr_len_set = true; 6721 params->pserver_addr = va_arg (ap, 6722 const struct sockaddr *); 6723 params->pserver_addr_set = true; 6724 break; 6725 case MHD_OPTION_SOCK_ADDR: 6726 params->server_addr_len_set = false; 6727 params->pserver_addr = va_arg (ap, 6728 const struct sockaddr *); 6729 params->pserver_addr_set = true; 6730 break; 6731 case MHD_OPTION_URI_LOG_CALLBACK: 6732 daemon->uri_log_callback = va_arg (ap, 6733 LogCallback); 6734 daemon->uri_log_callback_cls = va_arg (ap, 6735 void *); 6736 break; 6737 case MHD_OPTION_SERVER_INSANITY: 6738 daemon->insanity_level = (enum MHD_DisableSanityCheck) 6739 va_arg (ap, 6740 unsigned int); 6741 break; 6742 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6743 case MHD_OPTION_THREAD_POOL_SIZE: 6744 daemon->worker_pool_size = va_arg (ap, 6745 unsigned int); 6746 if (0 == daemon->worker_pool_size) 6747 { 6748 (void) 0; /* MHD_OPTION_THREAD_POOL_SIZE ignored, do nothing */ 6749 } 6750 else if (1 == daemon->worker_pool_size) 6751 { 6752 #ifdef HAVE_MESSAGES 6753 MHD_DLOG (daemon, 6754 _ ("Warning: value \"1\", specified as the thread pool " \ 6755 "size, is ignored. Thread pool is not used.\n")); 6756 #endif 6757 daemon->worker_pool_size = 0; 6758 } 6759 #if SIZEOF_UNSIGNED_INT >= (SIZEOF_SIZE_T - 2) 6760 /* Next comparison could be always false on some platforms and whole branch will 6761 * be optimized out on these platforms. On others it will be compiled into real 6762 * check. */ 6763 else if (daemon->worker_pool_size >= 6764 (SIZE_MAX / sizeof (struct MHD_Daemon))) /* Compiler may warn on some platforms, ignore warning. */ 6765 { 6766 #ifdef HAVE_MESSAGES 6767 MHD_DLOG (daemon, 6768 _ ("Specified thread pool size (%u) too big.\n"), 6769 daemon->worker_pool_size); 6770 #endif 6771 return MHD_NO; 6772 } 6773 #endif /* SIZEOF_UNSIGNED_INT >= (SIZEOF_SIZE_T - 2) */ 6774 else 6775 { 6776 if (! MHD_D_IS_USING_THREADS_ (daemon)) 6777 { 6778 #ifdef HAVE_MESSAGES 6779 MHD_DLOG (daemon, 6780 _ ("MHD_OPTION_THREAD_POOL_SIZE option is specified but " 6781 "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n")); 6782 #endif 6783 return MHD_NO; 6784 } 6785 if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) 6786 { 6787 #ifdef HAVE_MESSAGES 6788 MHD_DLOG (daemon, 6789 _ ("Both MHD_OPTION_THREAD_POOL_SIZE option and " 6790 "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n")); 6791 #endif 6792 return MHD_NO; 6793 } 6794 } 6795 break; 6796 #endif 6797 #ifdef HTTPS_SUPPORT 6798 case MHD_OPTION_HTTPS_MEM_KEY: 6799 pstr = va_arg (ap, 6800 const char *); 6801 if (0 != (daemon->options & MHD_USE_TLS)) 6802 daemon->https_mem_key = pstr; 6803 #ifdef HAVE_MESSAGES 6804 else 6805 MHD_DLOG (daemon, 6806 _ ("MHD HTTPS option %d passed to MHD but " \ 6807 "MHD_USE_TLS not set.\n"), 6808 opt); 6809 #endif 6810 break; 6811 case MHD_OPTION_HTTPS_KEY_PASSWORD: 6812 pstr = va_arg (ap, 6813 const char *); 6814 if (0 != (daemon->options & MHD_USE_TLS)) 6815 daemon->https_key_password = pstr; 6816 #ifdef HAVE_MESSAGES 6817 else 6818 MHD_DLOG (daemon, 6819 _ ("MHD HTTPS option %d passed to MHD but " \ 6820 "MHD_USE_TLS not set.\n"), 6821 opt); 6822 #endif 6823 break; 6824 case MHD_OPTION_HTTPS_MEM_CERT: 6825 pstr = va_arg (ap, 6826 const char *); 6827 if (0 != (daemon->options & MHD_USE_TLS)) 6828 daemon->https_mem_cert = pstr; 6829 #ifdef HAVE_MESSAGES 6830 else 6831 MHD_DLOG (daemon, 6832 _ ("MHD HTTPS option %d passed to MHD but " \ 6833 "MHD_USE_TLS not set.\n"), 6834 opt); 6835 #endif 6836 break; 6837 case MHD_OPTION_HTTPS_MEM_TRUST: 6838 pstr = va_arg (ap, 6839 const char *); 6840 if (0 != (daemon->options & MHD_USE_TLS)) 6841 daemon->https_mem_trust = pstr; 6842 #ifdef HAVE_MESSAGES 6843 else 6844 MHD_DLOG (daemon, 6845 _ ("MHD HTTPS option %d passed to MHD but " \ 6846 "MHD_USE_TLS not set.\n"), 6847 opt); 6848 #endif 6849 break; 6850 case MHD_OPTION_HTTPS_CRED_TYPE: 6851 daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap, 6852 int); 6853 break; 6854 case MHD_OPTION_HTTPS_MEM_DHPARAMS: 6855 pstr = va_arg (ap, 6856 const char *); 6857 if (0 != (daemon->options & MHD_USE_TLS)) 6858 { 6859 gnutls_datum_t dhpar; 6860 size_t pstr_len; 6861 6862 if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0) 6863 { 6864 #ifdef HAVE_MESSAGES 6865 MHD_DLOG (daemon, 6866 _ ("Error initializing DH parameters.\n")); 6867 #endif 6868 return MHD_NO; 6869 } 6870 dhpar.data = (unsigned char *) _MHD_DROP_CONST (pstr); 6871 pstr_len = strlen (pstr); 6872 if (UINT_MAX < pstr_len) 6873 { 6874 #ifdef HAVE_MESSAGES 6875 MHD_DLOG (daemon, 6876 _ ("Diffie-Hellman parameters string too long.\n")); 6877 #endif 6878 return MHD_NO; 6879 } 6880 dhpar.size = (unsigned int) pstr_len; 6881 if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams, 6882 &dhpar, 6883 GNUTLS_X509_FMT_PEM) < 0) 6884 { 6885 #ifdef HAVE_MESSAGES 6886 MHD_DLOG (daemon, 6887 _ ("Bad Diffie-Hellman parameters format.\n")); 6888 #endif 6889 gnutls_dh_params_deinit (daemon->https_mem_dhparams); 6890 return MHD_NO; 6891 } 6892 daemon->have_dhparams = true; 6893 } 6894 #ifdef HAVE_MESSAGES 6895 else 6896 MHD_DLOG (daemon, 6897 _ ("MHD HTTPS option %d passed to MHD but " \ 6898 "MHD_USE_TLS not set.\n"), 6899 opt); 6900 #endif 6901 break; 6902 case MHD_OPTION_HTTPS_PRIORITIES: 6903 case MHD_OPTION_HTTPS_PRIORITIES_APPEND: 6904 pstr = va_arg (ap, 6905 const char *); 6906 if (0 != (daemon->options & MHD_USE_TLS)) 6907 { 6908 if (NULL != daemon->priority_cache) 6909 gnutls_priority_deinit (daemon->priority_cache); 6910 6911 if (MHD_OPTION_HTTPS_PRIORITIES == opt) 6912 { 6913 int init_res; 6914 const char *err_pos; 6915 init_res = gnutls_priority_init (&daemon->priority_cache, 6916 pstr, 6917 &err_pos); 6918 if (GNUTLS_E_SUCCESS != init_res) 6919 { 6920 #ifdef HAVE_MESSAGES 6921 MHD_DLOG (daemon, 6922 _ ("Setting priorities to '%s' failed: %s " \ 6923 "The problematic part starts at: %s\n"), 6924 pstr, 6925 gnutls_strerror (init_res), 6926 err_pos); 6927 #endif 6928 daemon->priority_cache = NULL; 6929 return MHD_NO; 6930 } 6931 } 6932 else 6933 { 6934 /* The cache has been deinited */ 6935 daemon->priority_cache = NULL; 6936 if (! daemon_tls_priorities_init_append (daemon, pstr)) 6937 return MHD_NO; 6938 } 6939 } 6940 #ifdef HAVE_MESSAGES 6941 else 6942 MHD_DLOG (daemon, 6943 _ ("MHD HTTPS option %d passed to MHD but " \ 6944 "MHD_USE_TLS not set.\n"), 6945 opt); 6946 #endif 6947 break; 6948 case MHD_OPTION_HTTPS_CERT_CALLBACK: 6949 #if GNUTLS_VERSION_MAJOR < 3 6950 #ifdef HAVE_MESSAGES 6951 MHD_DLOG (daemon, 6952 _ ("MHD_OPTION_HTTPS_CERT_CALLBACK requires building " \ 6953 "MHD with GnuTLS >= 3.0.\n")); 6954 #endif 6955 return MHD_NO; 6956 #else 6957 pgcrf = va_arg (ap, 6958 gnutls_certificate_retrieve_function2 *); 6959 if (0 != (daemon->options & MHD_USE_TLS)) 6960 daemon->cert_callback = pgcrf; 6961 #ifdef HAVE_MESSAGES 6962 else 6963 MHD_DLOG (daemon, 6964 _ ("MHD HTTPS option %d passed to MHD but " \ 6965 "MHD_USE_TLS not set.\n"), 6966 opt); 6967 #endif /* HAVE_MESSAGES */ 6968 break; 6969 #endif 6970 case MHD_OPTION_HTTPS_CERT_CALLBACK2: 6971 #if GNUTLS_VERSION_NUMBER < 0x030603 6972 #ifdef HAVE_MESSAGES 6973 MHD_DLOG (daemon, 6974 _ ("MHD_OPTION_HTTPS_CERT_CALLBACK2 requires building " \ 6975 "MHD with GnuTLS >= 3.6.3.\n")); 6976 #endif 6977 return MHD_NO; 6978 #else 6979 pgcrf2 = va_arg (ap, 6980 gnutls_certificate_retrieve_function3 *); 6981 if (0 != (daemon->options & MHD_USE_TLS)) 6982 daemon->cert_callback2 = pgcrf2; 6983 #ifdef HAVE_MESSAGES 6984 else 6985 MHD_DLOG (daemon, 6986 _ ("MHD HTTPS option %d passed to MHD but " \ 6987 "MHD_USE_TLS not set.\n"), 6988 opt); 6989 #endif /* HAVE_MESSAGES */ 6990 break; 6991 #endif 6992 #endif /* HTTPS_SUPPORT */ 6993 #ifdef DAUTH_SUPPORT 6994 case MHD_OPTION_DIGEST_AUTH_RANDOM: 6995 case MHD_OPTION_DIGEST_AUTH_RANDOM_COPY: 6996 daemon->digest_auth_rand_size = va_arg (ap, 6997 size_t); 6998 daemon->digest_auth_random = va_arg (ap, 6999 const char *); 7000 if (MHD_OPTION_DIGEST_AUTH_RANDOM_COPY == opt) 7001 /* Set to some non-NULL value just to indicate that copy is required. */ 7002 daemon->digest_auth_random_copy = daemon; 7003 else 7004 daemon->digest_auth_random_copy = NULL; 7005 break; 7006 case MHD_OPTION_NONCE_NC_SIZE: 7007 daemon->nonce_nc_size = va_arg (ap, 7008 unsigned int); 7009 break; 7010 case MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE: 7011 daemon->dauth_bind_type = va_arg (ap, 7012 unsigned int); 7013 if (0 != (daemon->dauth_bind_type & MHD_DAUTH_BIND_NONCE_URI_PARAMS)) 7014 daemon->dauth_bind_type |= MHD_DAUTH_BIND_NONCE_URI; 7015 break; 7016 case MHD_OPTION_DIGEST_AUTH_DEFAULT_NONCE_TIMEOUT: 7017 if (1) 7018 { 7019 unsigned int val; 7020 val = va_arg (ap, 7021 unsigned int); 7022 if (0 != val) 7023 daemon->dauth_def_nonce_timeout = val; 7024 } 7025 break; 7026 case MHD_OPTION_DIGEST_AUTH_DEFAULT_MAX_NC: 7027 if (1) 7028 { 7029 uint32_t val; 7030 val = va_arg (ap, 7031 uint32_t); 7032 if (0 != val) 7033 daemon->dauth_def_max_nc = val; 7034 } 7035 break; 7036 #else /* ! DAUTH_SUPPORT */ 7037 case MHD_OPTION_DIGEST_AUTH_RANDOM: 7038 case MHD_OPTION_DIGEST_AUTH_RANDOM_COPY: 7039 case MHD_OPTION_NONCE_NC_SIZE: 7040 case MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE: 7041 case MHD_OPTION_DIGEST_AUTH_DEFAULT_NONCE_TIMEOUT: 7042 case MHD_OPTION_DIGEST_AUTH_DEFAULT_MAX_NC: 7043 #ifdef HAVE_MESSAGES 7044 MHD_DLOG (daemon, 7045 _ ("Digest Auth is disabled for this build " \ 7046 "of GNU libmicrohttpd.\n")); 7047 #endif /* HAVE_MESSAGES */ 7048 return MHD_NO; 7049 #endif /* ! DAUTH_SUPPORT */ 7050 case MHD_OPTION_LISTEN_SOCKET: 7051 params->listen_fd = va_arg (ap, 7052 MHD_socket); 7053 params->listen_fd_set = true; 7054 break; 7055 case MHD_OPTION_EXTERNAL_LOGGER: 7056 #ifdef HAVE_MESSAGES 7057 daemon->custom_error_log = va_arg (ap, 7058 VfprintfFunctionPointerType); 7059 daemon->custom_error_log_cls = va_arg (ap, 7060 void *); 7061 if (1 != params->num_opts) 7062 MHD_DLOG (daemon, 7063 _ ("MHD_OPTION_EXTERNAL_LOGGER is not the first option " 7064 "specified for the daemon. Some messages may be " 7065 "printed by the standard MHD logger.\n")); 7066 7067 #else 7068 (void) va_arg (ap, 7069 VfprintfFunctionPointerType); 7070 (void) va_arg (ap, 7071 void *); 7072 #endif 7073 break; 7074 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 7075 case MHD_OPTION_THREAD_STACK_SIZE: 7076 daemon->thread_stack_size = va_arg (ap, 7077 size_t); 7078 break; 7079 #endif 7080 case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE: 7081 #ifdef TCP_FASTOPEN 7082 daemon->fastopen_queue_size = va_arg (ap, 7083 unsigned int); 7084 break; 7085 #else /* ! TCP_FASTOPEN */ 7086 #ifdef HAVE_MESSAGES 7087 MHD_DLOG (daemon, 7088 _ ("TCP fastopen is not supported on this platform.\n")); 7089 #endif /* HAVE_MESSAGES */ 7090 return MHD_NO; 7091 #endif /* ! TCP_FASTOPEN */ 7092 case MHD_OPTION_LISTENING_ADDRESS_REUSE: 7093 daemon->listening_address_reuse = va_arg (ap, 7094 unsigned int) ? 1 : -1; 7095 break; 7096 case MHD_OPTION_LISTEN_BACKLOG_SIZE: 7097 daemon->listen_backlog_size = va_arg (ap, 7098 unsigned int); 7099 break; 7100 case MHD_OPTION_STRICT_FOR_CLIENT: 7101 daemon->client_discipline = va_arg (ap, int); /* Temporal assignment */ 7102 /* Map to correct value */ 7103 if (-1 >= daemon->client_discipline) 7104 daemon->client_discipline = -3; 7105 else if (1 <= daemon->client_discipline) 7106 daemon->client_discipline = 1; 7107 #ifdef HAVE_MESSAGES 7108 if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) && 7109 (1 != daemon->client_discipline) ) 7110 { 7111 MHD_DLOG (daemon, 7112 _ ("Flag MHD_USE_PEDANTIC_CHECKS is ignored because " 7113 "another behaviour is specified by " 7114 "MHD_OPTION_STRICT_CLIENT.\n")); 7115 } 7116 #endif /* HAVE_MESSAGES */ 7117 break; 7118 case MHD_OPTION_CLIENT_DISCIPLINE_LVL: 7119 daemon->client_discipline = va_arg (ap, int); 7120 #ifdef HAVE_MESSAGES 7121 if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) && 7122 (1 != daemon->client_discipline) ) 7123 { 7124 MHD_DLOG (daemon, 7125 _ ("Flag MHD_USE_PEDANTIC_CHECKS is ignored because " 7126 "another behaviour is specified by " 7127 "MHD_OPTION_CLIENT_DISCIPLINE_LVL.\n")); 7128 } 7129 #endif /* HAVE_MESSAGES */ 7130 break; 7131 case MHD_OPTION_ALLOW_BIN_ZERO_IN_URI_PATH: 7132 daemon->allow_bzero_in_url = va_arg (ap, int); 7133 if ((0 > daemon->allow_bzero_in_url) || 7134 (2 < daemon->allow_bzero_in_url)) 7135 daemon->allow_bzero_in_url = 1; 7136 break; 7137 case MHD_OPTION_ARRAY: 7138 params->num_opts--; /* Do not count MHD_OPTION_ARRAY */ 7139 oa = va_arg (ap, struct MHD_OptionItem *); 7140 i = 0; 7141 while (MHD_OPTION_END != (opt = oa[i].option)) 7142 { 7143 switch (opt) 7144 { 7145 /* all options taking 'size_t' */ 7146 case MHD_OPTION_CONNECTION_MEMORY_LIMIT: 7147 case MHD_OPTION_CONNECTION_MEMORY_INCREMENT: 7148 case MHD_OPTION_THREAD_STACK_SIZE: 7149 if (MHD_NO == parse_options (daemon, 7150 params, 7151 opt, 7152 (size_t) oa[i].value, 7153 MHD_OPTION_END)) 7154 return MHD_NO; 7155 break; 7156 /* all options taking 'unsigned int' */ 7157 case MHD_OPTION_NONCE_NC_SIZE: 7158 case MHD_OPTION_CONNECTION_LIMIT: 7159 case MHD_OPTION_CONNECTION_TIMEOUT: 7160 case MHD_OPTION_PER_IP_CONNECTION_LIMIT: 7161 case MHD_OPTION_THREAD_POOL_SIZE: 7162 case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE: 7163 case MHD_OPTION_LISTENING_ADDRESS_REUSE: 7164 case MHD_OPTION_LISTEN_BACKLOG_SIZE: 7165 case MHD_OPTION_SERVER_INSANITY: 7166 case MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE: 7167 case MHD_OPTION_DIGEST_AUTH_DEFAULT_NONCE_TIMEOUT: 7168 if (MHD_NO == parse_options (daemon, 7169 params, 7170 opt, 7171 (unsigned int) oa[i].value, 7172 MHD_OPTION_END)) 7173 return MHD_NO; 7174 break; 7175 /* all options taking 'enum' */ 7176 case MHD_OPTION_HTTPS_CRED_TYPE: 7177 #ifdef HTTPS_SUPPORT 7178 if (MHD_NO == parse_options (daemon, 7179 params, 7180 opt, 7181 (gnutls_credentials_type_t) oa[i].value, 7182 MHD_OPTION_END)) 7183 #endif /* HTTPS_SUPPORT */ 7184 return MHD_NO; 7185 break; 7186 /* all options taking 'MHD_socket' */ 7187 case MHD_OPTION_LISTEN_SOCKET: 7188 if (MHD_NO == parse_options (daemon, 7189 params, 7190 opt, 7191 (MHD_socket) oa[i].value, 7192 MHD_OPTION_END)) 7193 return MHD_NO; 7194 break; 7195 /* all options taking 'int' */ 7196 case MHD_OPTION_STRICT_FOR_CLIENT: 7197 case MHD_OPTION_CLIENT_DISCIPLINE_LVL: 7198 case MHD_OPTION_SIGPIPE_HANDLED_BY_APP: 7199 case MHD_OPTION_TLS_NO_ALPN: 7200 case MHD_OPTION_APP_FD_SETSIZE: 7201 case MHD_OPTION_ALLOW_BIN_ZERO_IN_URI_PATH: 7202 if (MHD_NO == parse_options (daemon, 7203 params, 7204 opt, 7205 (int) oa[i].value, 7206 MHD_OPTION_END)) 7207 return MHD_NO; 7208 break; 7209 /* all options taking 'uint32_t' */ 7210 case MHD_OPTION_DIGEST_AUTH_DEFAULT_MAX_NC: 7211 if (MHD_NO == parse_options (daemon, 7212 params, 7213 opt, 7214 (uint32_t) oa[i].value, 7215 MHD_OPTION_END)) 7216 return MHD_NO; 7217 break; 7218 /* all options taking one pointer */ 7219 case MHD_OPTION_SOCK_ADDR: 7220 case MHD_OPTION_HTTPS_MEM_KEY: 7221 case MHD_OPTION_HTTPS_KEY_PASSWORD: 7222 case MHD_OPTION_HTTPS_MEM_CERT: 7223 case MHD_OPTION_HTTPS_MEM_TRUST: 7224 case MHD_OPTION_HTTPS_MEM_DHPARAMS: 7225 case MHD_OPTION_HTTPS_PRIORITIES: 7226 case MHD_OPTION_HTTPS_PRIORITIES_APPEND: 7227 case MHD_OPTION_ARRAY: 7228 case MHD_OPTION_HTTPS_CERT_CALLBACK: 7229 case MHD_OPTION_HTTPS_CERT_CALLBACK2: 7230 if (MHD_NO == parse_options (daemon, 7231 params, 7232 opt, 7233 oa[i].ptr_value, 7234 MHD_OPTION_END)) 7235 return MHD_NO; 7236 break; 7237 /* all options taking two pointers */ 7238 case MHD_OPTION_NOTIFY_COMPLETED: 7239 case MHD_OPTION_NOTIFY_CONNECTION: 7240 case MHD_OPTION_URI_LOG_CALLBACK: 7241 case MHD_OPTION_EXTERNAL_LOGGER: 7242 case MHD_OPTION_UNESCAPE_CALLBACK: 7243 case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER: 7244 if (MHD_NO == parse_options (daemon, 7245 params, 7246 opt, 7247 (void *) oa[i].value, 7248 oa[i].ptr_value, 7249 MHD_OPTION_END)) 7250 return MHD_NO; 7251 break; 7252 /* options taking size_t-number followed by pointer */ 7253 case MHD_OPTION_DIGEST_AUTH_RANDOM: 7254 case MHD_OPTION_DIGEST_AUTH_RANDOM_COPY: 7255 if (MHD_NO == parse_options (daemon, 7256 params, 7257 opt, 7258 (size_t) oa[i].value, 7259 oa[i].ptr_value, 7260 MHD_OPTION_END)) 7261 return MHD_NO; 7262 break; 7263 /* options taking socklen_t-number followed by pointer */ 7264 case MHD_OPTION_SOCK_ADDR_LEN: 7265 if (MHD_NO == parse_options (daemon, 7266 params, 7267 opt, 7268 (socklen_t) oa[i].value, 7269 oa[i].ptr_value, 7270 MHD_OPTION_END)) 7271 return MHD_NO; 7272 break; 7273 case MHD_OPTION_END: /* Not possible */ 7274 default: 7275 return MHD_NO; 7276 } 7277 i++; 7278 } 7279 break; 7280 case MHD_OPTION_UNESCAPE_CALLBACK: 7281 daemon->unescape_callback = va_arg (ap, 7282 UnescapeCallback); 7283 daemon->unescape_callback_cls = va_arg (ap, 7284 void *); 7285 break; 7286 #ifdef HTTPS_SUPPORT 7287 case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER: 7288 #if GNUTLS_VERSION_MAJOR >= 3 7289 daemon->cred_callback = va_arg (ap, 7290 MHD_PskServerCredentialsCallback); 7291 daemon->cred_callback_cls = va_arg (ap, 7292 void *); 7293 break; 7294 #else 7295 MHD_DLOG (daemon, 7296 _ ("MHD HTTPS option %d passed to MHD compiled " \ 7297 "without GNUtls >= 3.\n"), 7298 opt); 7299 return MHD_NO; 7300 #endif 7301 #endif /* HTTPS_SUPPORT */ 7302 case MHD_OPTION_SIGPIPE_HANDLED_BY_APP: 7303 if (! MHD_D_IS_USING_THREADS_ (daemon)) 7304 daemon->sigpipe_blocked = ( (va_arg (ap, 7305 int)) != 0); 7306 else 7307 { 7308 (void) va_arg (ap, 7309 int); 7310 } 7311 break; 7312 case MHD_OPTION_TLS_NO_ALPN: 7313 #ifdef HTTPS_SUPPORT 7314 daemon->disable_alpn = (va_arg (ap, 7315 int) != 0); 7316 #else /* ! HTTPS_SUPPORT */ 7317 (void) va_arg (ap, int); 7318 #endif /* ! HTTPS_SUPPORT */ 7319 #ifdef HAVE_MESSAGES 7320 if (0 == (daemon->options & MHD_USE_TLS)) 7321 MHD_DLOG (daemon, 7322 _ ("MHD HTTPS option %d passed to MHD " \ 7323 "but MHD_USE_TLS not set.\n"), 7324 (int) opt); 7325 #endif /* HAVE_MESSAGES */ 7326 break; 7327 case MHD_OPTION_APP_FD_SETSIZE: 7328 params->fdset_size_set = true; 7329 params->fdset_size = va_arg (ap, 7330 int); 7331 break; 7332 #ifndef HTTPS_SUPPORT 7333 case MHD_OPTION_HTTPS_MEM_KEY: 7334 case MHD_OPTION_HTTPS_MEM_CERT: 7335 case MHD_OPTION_HTTPS_CRED_TYPE: 7336 case MHD_OPTION_HTTPS_PRIORITIES: 7337 case MHD_OPTION_HTTPS_PRIORITIES_APPEND: 7338 case MHD_OPTION_HTTPS_MEM_TRUST: 7339 case MHD_OPTION_HTTPS_CERT_CALLBACK: 7340 case MHD_OPTION_HTTPS_MEM_DHPARAMS: 7341 case MHD_OPTION_HTTPS_KEY_PASSWORD: 7342 case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER: 7343 case MHD_OPTION_HTTPS_CERT_CALLBACK2: 7344 #ifdef HAVE_MESSAGES 7345 MHD_DLOG (daemon, 7346 _ ("MHD HTTPS option %d passed to MHD " 7347 "compiled without HTTPS support.\n"), 7348 opt); 7349 #endif 7350 return MHD_NO; 7351 #endif /* HTTPS_SUPPORT */ 7352 case MHD_OPTION_END: /* Not possible */ 7353 default: 7354 #ifdef HAVE_MESSAGES 7355 MHD_DLOG (daemon, 7356 _ ("Invalid option %d! (Did you terminate " 7357 "the list with MHD_OPTION_END?).\n"), 7358 opt); 7359 #endif 7360 return MHD_NO; 7361 } 7362 } 7363 return MHD_YES; 7364 } 7365 7366 7367 #ifdef EPOLL_SUPPORT 7368 static int 7369 setup_epoll_fd (struct MHD_Daemon *daemon) 7370 { 7371 int fd; 7372 7373 #ifndef HAVE_MESSAGES 7374 (void) daemon; /* Mute compiler warning. */ 7375 #endif /* ! HAVE_MESSAGES */ 7376 7377 #ifdef USE_EPOLL_CREATE1 7378 fd = epoll_create1 (EPOLL_CLOEXEC); 7379 #else /* ! USE_EPOLL_CREATE1 */ 7380 fd = epoll_create (MAX_EVENTS); 7381 #endif /* ! USE_EPOLL_CREATE1 */ 7382 if (MHD_INVALID_SOCKET == fd) 7383 { 7384 #ifdef HAVE_MESSAGES 7385 MHD_DLOG (daemon, 7386 _ ("Call to epoll_create1 failed: %s\n"), 7387 MHD_socket_last_strerr_ ()); 7388 #endif 7389 return MHD_INVALID_SOCKET; 7390 } 7391 #if ! defined(USE_EPOLL_CREATE1) 7392 if (! MHD_socket_noninheritable_ (fd)) 7393 { 7394 #ifdef HAVE_MESSAGES 7395 MHD_DLOG (daemon, 7396 _ ("Failed to set noninheritable mode on epoll FD.\n")); 7397 #endif 7398 } 7399 #endif /* ! USE_EPOLL_CREATE1 */ 7400 return fd; 7401 } 7402 7403 7404 /** 7405 * Setup epoll() FD for the daemon and initialize it to listen 7406 * on the listen FD. 7407 * @remark To be called only from MHD_start_daemon_va() 7408 * 7409 * @param daemon daemon to initialize for epoll() 7410 * @return #MHD_YES on success, #MHD_NO on failure 7411 */ 7412 static enum MHD_Result 7413 setup_epoll_to_listen (struct MHD_Daemon *daemon) 7414 { 7415 struct epoll_event event; 7416 MHD_socket ls; 7417 7418 mhd_assert (MHD_D_IS_USING_EPOLL_ (daemon)); 7419 mhd_assert (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)); 7420 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 7421 (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) || \ 7422 MHD_ITC_IS_VALID_ (daemon->itc) ); 7423 daemon->epoll_fd = setup_epoll_fd (daemon); 7424 if (! MHD_D_IS_USING_THREADS_ (daemon) 7425 && (0 != (daemon->options & MHD_USE_AUTO))) 7426 { 7427 /* Application requested "MHD_USE_AUTO", probably MHD_get_fdset() will be 7428 used. 7429 Make sure that epoll FD is suitable for fd_set. 7430 Actually, MHD_get_fdset() is allowed for MHD_USE_EPOLL direct, 7431 but most probably direct requirement for MHD_USE_EPOLL means that 7432 epoll FD will be used directly. This logic is fuzzy, but better 7433 than nothing with current MHD API. */ 7434 if (! MHD_D_DOES_SCKT_FIT_FDSET_ (daemon->epoll_fd, daemon)) 7435 { 7436 #ifdef HAVE_MESSAGES 7437 MHD_DLOG (daemon, 7438 _ ("The epoll FD is too large to be used with fd_set.\n")); 7439 #endif /* HAVE_MESSAGES */ 7440 return MHD_NO; 7441 } 7442 } 7443 if (-1 == daemon->epoll_fd) 7444 return MHD_NO; 7445 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 7446 if (0 != (MHD_ALLOW_UPGRADE & daemon->options)) 7447 { 7448 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon); 7449 if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd) 7450 return MHD_NO; 7451 } 7452 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 7453 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && 7454 (! daemon->was_quiesced) ) 7455 { 7456 event.events = EPOLLIN | EPOLLRDHUP; 7457 event.data.ptr = daemon; 7458 if (0 != epoll_ctl (daemon->epoll_fd, 7459 EPOLL_CTL_ADD, 7460 ls, 7461 &event)) 7462 { 7463 #ifdef HAVE_MESSAGES 7464 MHD_DLOG (daemon, 7465 _ ("Call to epoll_ctl failed: %s\n"), 7466 MHD_socket_last_strerr_ ()); 7467 #endif 7468 return MHD_NO; 7469 } 7470 daemon->listen_socket_in_epoll = true; 7471 } 7472 7473 if (MHD_ITC_IS_VALID_ (daemon->itc)) 7474 { 7475 event.events = EPOLLIN | EPOLLRDHUP; 7476 event.data.ptr = _MHD_DROP_CONST (epoll_itc_marker); 7477 if (0 != epoll_ctl (daemon->epoll_fd, 7478 EPOLL_CTL_ADD, 7479 MHD_itc_r_fd_ (daemon->itc), 7480 &event)) 7481 { 7482 #ifdef HAVE_MESSAGES 7483 MHD_DLOG (daemon, 7484 _ ("Call to epoll_ctl failed: %s\n"), 7485 MHD_socket_last_strerr_ ()); 7486 #endif 7487 return MHD_NO; 7488 } 7489 } 7490 return MHD_YES; 7491 } 7492 7493 7494 #endif 7495 7496 7497 /** 7498 * Apply interim parameters 7499 * @param[in,out] d the daemon to use 7500 * @param[out] ppsockaddr the pointer to store the pointer to 'struct sockaddr' 7501 * if provided by application 7502 * @param[out] psockaddr_len the size memory area pointed by 'struct sockaddr' 7503 * if provided by application 7504 * @param[in,out] params the interim parameters to process 7505 * @return true in case of success, 7506 * false in case of critical error (the daemon must be closed). 7507 */ 7508 static bool 7509 process_interim_params (struct MHD_Daemon *d, 7510 const struct sockaddr **ppsockaddr, 7511 socklen_t *psockaddr_len, 7512 struct MHD_InterimParams_ *params) 7513 { 7514 if (params->fdset_size_set) 7515 { 7516 if (0 >= params->fdset_size) 7517 { 7518 #ifdef HAVE_MESSAGES 7519 MHD_DLOG (d, 7520 _ ("MHD_OPTION_APP_FD_SETSIZE value (%d) is not positive.\n"), 7521 params->fdset_size); 7522 #endif /* HAVE_MESSAGES */ 7523 return false; 7524 } 7525 if (MHD_D_IS_USING_THREADS_ (d)) 7526 { 7527 #ifdef HAVE_MESSAGES 7528 MHD_DLOG (d, 7529 _ ("MHD_OPTION_APP_FD_SETSIZE is ignored for daemon started " \ 7530 "with MHD_USE_INTERNAL_POLLING_THREAD.\n")); 7531 #endif /* HAVE_MESSAGES */ 7532 (void) 0; 7533 } 7534 else if (MHD_D_IS_USING_POLL_ (d)) 7535 { 7536 #ifdef HAVE_MESSAGES 7537 MHD_DLOG (d, 7538 _ ("MHD_OPTION_APP_FD_SETSIZE is ignored for daemon started " \ 7539 "with MHD_USE_POLL.\n")); 7540 #endif /* HAVE_MESSAGES */ 7541 (void) 0; 7542 } 7543 else 7544 { /* The daemon without internal threads, external sockets polling */ 7545 #ifndef HAS_FD_SETSIZE_OVERRIDABLE 7546 if (((int) FD_SETSIZE) != params->fdset_size) 7547 { 7548 #ifdef HAVE_MESSAGES 7549 MHD_DLOG (d, 7550 _ ("MHD_OPTION_APP_FD_SETSIZE value (%d) does not match " \ 7551 "the platform FD_SETSIZE value (%d) and this platform " \ 7552 "does not support overriding of FD_SETSIZE.\n"), 7553 params->fdset_size, (int) FD_SETSIZE); 7554 #endif /* HAVE_MESSAGES */ 7555 return false; 7556 } 7557 #else /* HAS_FD_SETSIZE_OVERRIDABLE */ 7558 d->fdset_size = params->fdset_size; 7559 d->fdset_size_set_by_app = true; 7560 #endif /* HAS_FD_SETSIZE_OVERRIDABLE */ 7561 } 7562 } 7563 7564 if (params->listen_fd_set) 7565 { 7566 if (MHD_INVALID_SOCKET == params->listen_fd) 7567 { 7568 (void) 0; /* Use MHD-created socket */ 7569 } 7570 #ifdef HAS_SIGNED_SOCKET 7571 else if (0 > params->listen_fd) 7572 { 7573 #ifdef HAVE_MESSAGES 7574 MHD_DLOG (d, 7575 _ ("The value provided for MHD_OPTION_LISTEN_SOCKET " \ 7576 "is invalid.\n")); 7577 #endif /* HAVE_MESSAGES */ 7578 return false; 7579 } 7580 #endif /* HAS_SIGNED_SOCKET */ 7581 else if (0 != (d->options & MHD_USE_NO_LISTEN_SOCKET)) 7582 { 7583 #ifdef HAVE_MESSAGES 7584 MHD_DLOG (d, 7585 _ ("MHD_OPTION_LISTEN_SOCKET specified for daemon " 7586 "with MHD_USE_NO_LISTEN_SOCKET flag set.\n")); 7587 #endif /* HAVE_MESSAGES */ 7588 (void) MHD_socket_close_ (params->listen_fd); 7589 return false; 7590 } 7591 else 7592 { 7593 d->listen_fd = params->listen_fd; 7594 d->listen_is_unix = _MHD_UNKNOWN; 7595 #ifdef MHD_USE_GETSOCKNAME 7596 d->port = 0; /* Force use of autodetection */ 7597 #endif /* MHD_USE_GETSOCKNAME */ 7598 } 7599 } 7600 7601 mhd_assert (! params->server_addr_len_set || params->pserver_addr_set); 7602 if (params->pserver_addr_set) 7603 { 7604 if (NULL == params->pserver_addr) 7605 { 7606 /* The size must be zero if set */ 7607 if (params->server_addr_len_set && (0 != params->server_addr_len)) 7608 return false; 7609 /* Ignore parameter if it is NULL */ 7610 } 7611 else if (MHD_INVALID_SOCKET != d->listen_fd) 7612 { 7613 #ifdef HAVE_MESSAGES 7614 MHD_DLOG (d, 7615 _ ("MHD_OPTION_LISTEN_SOCKET cannot be used together with " \ 7616 "MHD_OPTION_SOCK_ADDR_LEN or MHD_OPTION_SOCK_ADDR.\n")); 7617 #endif /* HAVE_MESSAGES */ 7618 return false; 7619 } 7620 else if (0 != (d->options & MHD_USE_NO_LISTEN_SOCKET)) 7621 { 7622 #ifdef HAVE_MESSAGES 7623 MHD_DLOG (d, 7624 _ ("MHD_OPTION_SOCK_ADDR_LEN or MHD_OPTION_SOCK_ADDR " \ 7625 "specified for daemon with MHD_USE_NO_LISTEN_SOCKET " \ 7626 "flag set.\n")); 7627 #endif /* HAVE_MESSAGES */ 7628 if (MHD_INVALID_SOCKET != d->listen_fd) 7629 { 7630 (void) MHD_socket_close_ (params->listen_fd); 7631 params->listen_fd = MHD_INVALID_SOCKET; 7632 } 7633 return false; 7634 } 7635 else 7636 { 7637 *ppsockaddr = params->pserver_addr; 7638 if (params->server_addr_len_set) 7639 { 7640 /* The size must be non-zero if set */ 7641 if (0 == params->server_addr_len) 7642 return false; 7643 *psockaddr_len = params->server_addr_len; 7644 } 7645 else 7646 *psockaddr_len = 0; 7647 } 7648 } 7649 return true; 7650 } 7651 7652 7653 /** 7654 * Start a webserver on the given port. 7655 * 7656 * @param flags combination of `enum MHD_FLAG` values 7657 * @param port port to bind to (in host byte order), 7658 * use '0' to bind to random free port, 7659 * ignored if #MHD_OPTION_SOCK_ADDR or 7660 * #MHD_OPTION_LISTEN_SOCKET is provided 7661 * or #MHD_USE_NO_LISTEN_SOCKET is specified 7662 * @param apc callback to call to check which clients 7663 * will be allowed to connect; you can pass NULL 7664 * in which case connections from any IP will be 7665 * accepted 7666 * @param apc_cls extra argument to @a apc 7667 * @param dh handler called for all requests (repeatedly) 7668 * @param dh_cls extra argument to @a dh 7669 * @param ap list of options (type-value pairs, 7670 * terminated with #MHD_OPTION_END). 7671 * @return NULL on error, handle to daemon on success 7672 * @ingroup event 7673 */ 7674 _MHD_EXTERN struct MHD_Daemon * 7675 MHD_start_daemon_va (unsigned int flags, 7676 uint16_t port, 7677 MHD_AcceptPolicyCallback apc, 7678 void *apc_cls, 7679 MHD_AccessHandlerCallback dh, 7680 void *dh_cls, 7681 va_list ap) 7682 { 7683 const MHD_SCKT_OPT_BOOL_ on = 1; 7684 struct MHD_Daemon *daemon; 7685 const struct sockaddr *pservaddr = NULL; 7686 socklen_t addrlen; 7687 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 7688 unsigned int i; 7689 #endif 7690 enum MHD_FLAG eflags; /* same type as in MHD_Daemon */ 7691 enum MHD_FLAG *pflags; 7692 struct MHD_InterimParams_ *interim_params; 7693 7694 MHD_check_global_init_ (); 7695 eflags = (enum MHD_FLAG) flags; 7696 pflags = &eflags; 7697 7698 if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) 7699 *pflags |= MHD_USE_INTERNAL_POLLING_THREAD; /* Force enable, log warning later if needed */ 7700 7701 #ifndef HAVE_INET6 7702 if (0 != (*pflags & MHD_USE_IPv6)) 7703 return NULL; 7704 #endif 7705 #ifndef HAVE_POLL 7706 if (0 != (*pflags & MHD_USE_POLL)) 7707 return NULL; 7708 #endif 7709 #ifndef EPOLL_SUPPORT 7710 if (0 != (*pflags & MHD_USE_EPOLL)) 7711 return NULL; 7712 #endif /* ! EPOLL_SUPPORT */ 7713 #ifndef HTTPS_SUPPORT 7714 if (0 != (*pflags & MHD_USE_TLS)) 7715 return NULL; 7716 #endif /* ! HTTPS_SUPPORT */ 7717 #ifndef TCP_FASTOPEN 7718 if (0 != (*pflags & MHD_USE_TCP_FASTOPEN)) 7719 return NULL; 7720 #endif 7721 if (0 != (*pflags & MHD_ALLOW_UPGRADE)) 7722 { 7723 #ifdef UPGRADE_SUPPORT 7724 *pflags |= MHD_ALLOW_SUSPEND_RESUME; 7725 #else /* ! UPGRADE_SUPPORT */ 7726 return NULL; 7727 #endif /* ! UPGRADE_SUPPORT */ 7728 } 7729 #ifdef MHD_USE_THREADS 7730 if ((MHD_USE_NO_THREAD_SAFETY | MHD_USE_INTERNAL_POLLING_THREAD) == 7731 ((MHD_USE_NO_THREAD_SAFETY | MHD_USE_INTERNAL_POLLING_THREAD) 7732 & *pflags)) 7733 return NULL; /* Cannot be thread-unsafe with multiple threads */ 7734 #else /* ! MHD_USE_THREADS */ 7735 if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) 7736 return NULL; 7737 #endif /* ! MHD_USE_THREADS */ 7738 7739 if (NULL == dh) 7740 return NULL; 7741 7742 /* Check for invalid combinations of flags. */ 7743 if ((0 != (*pflags & MHD_USE_POLL)) && (0 != (*pflags & MHD_USE_EPOLL))) 7744 return NULL; 7745 if ((0 != (*pflags & MHD_USE_EPOLL)) && 7746 (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))) 7747 return NULL; 7748 if ((0 != (*pflags & MHD_USE_POLL)) && 7749 (0 == (*pflags & (MHD_USE_INTERNAL_POLLING_THREAD 7750 | MHD_USE_THREAD_PER_CONNECTION)))) 7751 return NULL; 7752 if ((0 != (*pflags & MHD_USE_AUTO)) && 7753 (0 != (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL)))) 7754 return NULL; 7755 7756 if (0 != (*pflags & MHD_USE_AUTO)) 7757 { 7758 #if defined(EPOLL_SUPPORT) && defined(HAVE_POLL) 7759 if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) 7760 *pflags |= MHD_USE_POLL; 7761 else 7762 *pflags |= MHD_USE_EPOLL; /* Including "external select" mode */ 7763 #elif defined(HAVE_POLL) 7764 if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) 7765 *pflags |= MHD_USE_POLL; /* Including thread-per-connection */ 7766 #elif defined(EPOLL_SUPPORT) 7767 if (0 == (*pflags & MHD_USE_THREAD_PER_CONNECTION)) 7768 *pflags |= MHD_USE_EPOLL; /* Including "external select" mode */ 7769 #else 7770 /* No choice: use select() for any mode - do not modify flags */ 7771 #endif 7772 } 7773 7774 if (0 != (*pflags & MHD_USE_NO_THREAD_SAFETY)) 7775 *pflags = (*pflags & ~((enum MHD_FLAG) MHD_USE_ITC)); /* useless in single-threaded environment */ 7776 else if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) 7777 { 7778 #ifdef HAVE_LISTEN_SHUTDOWN 7779 if (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET)) 7780 #endif 7781 *pflags |= MHD_USE_ITC; /* yes, must use ITC to signal thread */ 7782 } 7783 7784 if (NULL == (daemon = MHD_calloc_ (1, sizeof (struct MHD_Daemon)))) 7785 return NULL; 7786 interim_params = (struct MHD_InterimParams_ *) \ 7787 MHD_calloc_ (1, sizeof (struct MHD_InterimParams_)); 7788 if (NULL == interim_params) 7789 { 7790 int err_num = errno; 7791 free (daemon); 7792 errno = err_num; 7793 return NULL; 7794 } 7795 #ifdef EPOLL_SUPPORT 7796 daemon->epoll_fd = -1; 7797 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 7798 daemon->epoll_upgrade_fd = -1; 7799 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 7800 #endif 7801 /* try to open listen socket */ 7802 #ifdef HTTPS_SUPPORT 7803 daemon->priority_cache = NULL; 7804 #endif /* HTTPS_SUPPORT */ 7805 daemon->listen_fd = MHD_INVALID_SOCKET; 7806 daemon->listen_is_unix = _MHD_NO; 7807 daemon->listening_address_reuse = 0; 7808 daemon->options = *pflags; 7809 pflags = &daemon->options; 7810 daemon->client_discipline = (0 != (*pflags & MHD_USE_PEDANTIC_CHECKS)) ? 7811 1 : 0; 7812 daemon->port = port; 7813 daemon->apc = apc; 7814 daemon->apc_cls = apc_cls; 7815 daemon->default_handler = dh; 7816 daemon->default_handler_cls = dh_cls; 7817 daemon->connections = 0; 7818 daemon->connection_limit = MHD_MAX_CONNECTIONS_DEFAULT; 7819 daemon->pool_size = MHD_POOL_SIZE_DEFAULT; 7820 daemon->pool_increment = MHD_BUF_INC_SIZE; 7821 daemon->unescape_callback = &unescape_wrapper; 7822 daemon->connection_timeout_ms = 0; /* no timeout */ 7823 MHD_itc_set_invalid_ (daemon->itc); 7824 #ifdef MHD_USE_THREADS 7825 MHD_thread_handle_ID_set_invalid_ (&daemon->tid); 7826 #endif /* MHD_USE_THREADS */ 7827 #ifdef SOMAXCONN 7828 daemon->listen_backlog_size = SOMAXCONN; 7829 #else /* !SOMAXCONN */ 7830 daemon->listen_backlog_size = 511; /* should be safe value */ 7831 #endif /* !SOMAXCONN */ 7832 #ifdef HAVE_MESSAGES 7833 daemon->custom_error_log = &MHD_default_logger_; 7834 daemon->custom_error_log_cls = stderr; 7835 #endif 7836 #ifndef MHD_WINSOCK_SOCKETS 7837 daemon->sigpipe_blocked = false; 7838 #else /* MHD_WINSOCK_SOCKETS */ 7839 /* There is no SIGPIPE on W32, nothing to block. */ 7840 daemon->sigpipe_blocked = true; 7841 #endif /* _WIN32 && ! __CYGWIN__ */ 7842 #if defined(_DEBUG) && defined(HAVE_ACCEPT4) 7843 daemon->avoid_accept4 = false; 7844 #endif /* _DEBUG */ 7845 #ifdef HAS_FD_SETSIZE_OVERRIDABLE 7846 daemon->fdset_size = (int) FD_SETSIZE; 7847 daemon->fdset_size_set_by_app = false; 7848 #endif /* HAS_FD_SETSIZE_OVERRIDABLE */ 7849 7850 #ifdef DAUTH_SUPPORT 7851 daemon->digest_auth_rand_size = 0; 7852 daemon->digest_auth_random = NULL; 7853 daemon->nonce_nc_size = 4; /* tiny */ 7854 daemon->dauth_def_nonce_timeout = MHD_DAUTH_DEF_TIMEOUT_; 7855 daemon->dauth_def_max_nc = MHD_DAUTH_DEF_MAX_NC_; 7856 #endif 7857 #ifdef HTTPS_SUPPORT 7858 if (0 != (*pflags & MHD_USE_TLS)) 7859 { 7860 daemon->cred_type = GNUTLS_CRD_CERTIFICATE; 7861 } 7862 #endif /* HTTPS_SUPPORT */ 7863 7864 interim_params->num_opts = 0; 7865 interim_params->fdset_size_set = false; 7866 interim_params->fdset_size = 0; 7867 interim_params->listen_fd_set = false; 7868 interim_params->listen_fd = MHD_INVALID_SOCKET; 7869 interim_params->pserver_addr_set = false; 7870 interim_params->pserver_addr = NULL; 7871 interim_params->server_addr_len_set = false; 7872 interim_params->server_addr_len = 0; 7873 7874 if (MHD_NO == parse_options_va (daemon, 7875 interim_params, 7876 ap)) 7877 { 7878 #ifdef HTTPS_SUPPORT 7879 if ( (0 != (*pflags & MHD_USE_TLS)) && 7880 (NULL != daemon->priority_cache) ) 7881 gnutls_priority_deinit (daemon->priority_cache); 7882 #endif /* HTTPS_SUPPORT */ 7883 free (interim_params); 7884 free (daemon); 7885 return NULL; 7886 } 7887 if (! process_interim_params (daemon, 7888 &pservaddr, 7889 &addrlen, 7890 interim_params)) 7891 { 7892 free (interim_params); 7893 free (daemon); 7894 return NULL; 7895 } 7896 free (interim_params); 7897 interim_params = NULL; 7898 #ifdef HTTPS_SUPPORT 7899 if ((0 != (*pflags & MHD_USE_TLS)) 7900 && (NULL == daemon->priority_cache) 7901 && ! daemon_tls_priorities_init_default (daemon)) 7902 { 7903 #ifdef HAVE_MESSAGES 7904 MHD_DLOG (daemon, 7905 _ ("Failed to initialise GnuTLS priorities.\n")); 7906 #endif /* HAVE_MESSAGES */ 7907 free (daemon); 7908 return NULL; 7909 } 7910 #endif /* HTTPS_SUPPORT */ 7911 7912 #ifdef HAVE_MESSAGES 7913 if ( (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) && 7914 (0 == (flags & MHD_USE_INTERNAL_POLLING_THREAD)) ) 7915 { 7916 MHD_DLOG (daemon, 7917 _ ("Warning: MHD_USE_THREAD_PER_CONNECTION must be used " \ 7918 "only with MHD_USE_INTERNAL_POLLING_THREAD. " \ 7919 "Flag MHD_USE_INTERNAL_POLLING_THREAD was added. " \ 7920 "Consider setting MHD_USE_INTERNAL_POLLING_THREAD " \ 7921 "explicitly.\n")); 7922 } 7923 #endif 7924 7925 if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) 7926 && ((NULL != daemon->notify_completed) 7927 || (NULL != daemon->notify_connection)) ) 7928 *pflags |= MHD_USE_ITC; /* requires ITC */ 7929 7930 #ifdef _DEBUG 7931 #ifdef HAVE_MESSAGES 7932 MHD_DLOG (daemon, 7933 _ ("Using debug build of libmicrohttpd.\n") ); 7934 #endif /* HAVE_MESSAGES */ 7935 #endif /* _DEBUG */ 7936 7937 if ( (0 != (*pflags & MHD_USE_ITC)) 7938 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 7939 && (0 == daemon->worker_pool_size) 7940 #endif 7941 ) 7942 { 7943 if (! MHD_itc_init_ (daemon->itc)) 7944 { 7945 #ifdef HAVE_MESSAGES 7946 MHD_DLOG (daemon, 7947 _ ("Failed to create inter-thread communication channel: %s\n"), 7948 MHD_itc_last_strerror_ ()); 7949 #endif 7950 #ifdef HTTPS_SUPPORT 7951 if (NULL != daemon->priority_cache) 7952 gnutls_priority_deinit (daemon->priority_cache); 7953 #endif /* HTTPS_SUPPORT */ 7954 free (daemon); 7955 return NULL; 7956 } 7957 if (MHD_D_IS_USING_SELECT_ (daemon) && 7958 (! MHD_D_DOES_SCKT_FIT_FDSET_ (MHD_itc_r_fd_ (daemon->itc), daemon)) ) 7959 { 7960 #ifdef HAVE_MESSAGES 7961 MHD_DLOG (daemon, 7962 _ ("file descriptor for inter-thread communication " \ 7963 "channel exceeds maximum value.\n")); 7964 #endif 7965 MHD_itc_destroy_chk_ (daemon->itc); 7966 #ifdef HTTPS_SUPPORT 7967 if (NULL != daemon->priority_cache) 7968 gnutls_priority_deinit (daemon->priority_cache); 7969 #endif /* HTTPS_SUPPORT */ 7970 free (daemon); 7971 return NULL; 7972 } 7973 } 7974 7975 #ifdef DAUTH_SUPPORT 7976 if (NULL != daemon->digest_auth_random_copy) 7977 { 7978 mhd_assert (daemon == daemon->digest_auth_random_copy); 7979 daemon->digest_auth_random_copy = malloc (daemon->digest_auth_rand_size); 7980 if (NULL == daemon->digest_auth_random_copy) 7981 { 7982 #ifdef HTTPS_SUPPORT 7983 if (0 != (*pflags & MHD_USE_TLS)) 7984 gnutls_priority_deinit (daemon->priority_cache); 7985 #endif /* HTTPS_SUPPORT */ 7986 free (daemon); 7987 return NULL; 7988 } 7989 memcpy (daemon->digest_auth_random_copy, 7990 daemon->digest_auth_random, 7991 daemon->digest_auth_rand_size); 7992 daemon->digest_auth_random = daemon->digest_auth_random_copy; 7993 } 7994 if (daemon->nonce_nc_size > 0) 7995 { 7996 if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc))) 7997 / sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size) 7998 { 7999 #ifdef HAVE_MESSAGES 8000 MHD_DLOG (daemon, 8001 _ ("Specified value for NC_SIZE too large.\n")); 8002 #endif 8003 #ifdef HTTPS_SUPPORT 8004 if (0 != (*pflags & MHD_USE_TLS)) 8005 gnutls_priority_deinit (daemon->priority_cache); 8006 #endif /* HTTPS_SUPPORT */ 8007 free (daemon->digest_auth_random_copy); 8008 free (daemon); 8009 return NULL; 8010 } 8011 daemon->nnc = MHD_calloc_ (daemon->nonce_nc_size, 8012 sizeof (struct MHD_NonceNc)); 8013 if (NULL == daemon->nnc) 8014 { 8015 #ifdef HAVE_MESSAGES 8016 MHD_DLOG (daemon, 8017 _ ("Failed to allocate memory for nonce-nc map: %s\n"), 8018 MHD_strerror_ (errno)); 8019 #endif 8020 #ifdef HTTPS_SUPPORT 8021 if (0 != (*pflags & MHD_USE_TLS)) 8022 gnutls_priority_deinit (daemon->priority_cache); 8023 #endif /* HTTPS_SUPPORT */ 8024 free (daemon->digest_auth_random_copy); 8025 free (daemon); 8026 return NULL; 8027 } 8028 } 8029 8030 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 8031 if (! MHD_mutex_init_ (&daemon->nnc_lock)) 8032 { 8033 #ifdef HAVE_MESSAGES 8034 MHD_DLOG (daemon, 8035 _ ("MHD failed to initialize nonce-nc mutex.\n")); 8036 #endif 8037 #ifdef HTTPS_SUPPORT 8038 if (0 != (*pflags & MHD_USE_TLS)) 8039 gnutls_priority_deinit (daemon->priority_cache); 8040 #endif /* HTTPS_SUPPORT */ 8041 free (daemon->digest_auth_random_copy); 8042 free (daemon->nnc); 8043 free (daemon); 8044 return NULL; 8045 } 8046 #endif 8047 #endif 8048 8049 /* Thread polling currently works only with internal select thread mode */ 8050 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 8051 if ( (! MHD_D_IS_USING_THREADS_ (daemon)) && 8052 (daemon->worker_pool_size > 0) ) 8053 { 8054 #ifdef HAVE_MESSAGES 8055 MHD_DLOG (daemon, 8056 _ ("MHD thread polling only works with " \ 8057 "MHD_USE_INTERNAL_POLLING_THREAD.\n")); 8058 #endif 8059 goto free_and_fail; 8060 } 8061 #endif 8062 8063 if ( (MHD_INVALID_SOCKET == daemon->listen_fd) && 8064 (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) ) 8065 { 8066 /* try to open listen socket */ 8067 struct sockaddr_in servaddr4; 8068 #ifdef HAVE_INET6 8069 struct sockaddr_in6 servaddr6; 8070 const bool use_ipv6 = (0 != (*pflags & MHD_USE_IPv6)); 8071 #else /* ! HAVE_INET6 */ 8072 const bool use_ipv6 = false; 8073 #endif /* ! HAVE_INET6 */ 8074 int domain; 8075 8076 if (NULL != pservaddr) 8077 { 8078 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 8079 const socklen_t sa_len = pservaddr->sa_len; 8080 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ 8081 #ifdef HAVE_INET6 8082 if (use_ipv6 && (AF_INET6 != pservaddr->sa_family)) 8083 { 8084 #ifdef HAVE_MESSAGES 8085 MHD_DLOG (daemon, 8086 _ ("MHD_USE_IPv6 is enabled, but 'struct sockaddr *' " \ 8087 "specified for MHD_OPTION_SOCK_ADDR_LEN or " \ 8088 "MHD_OPTION_SOCK_ADDR is not IPv6 address.\n")); 8089 #endif /* HAVE_MESSAGES */ 8090 goto free_and_fail; 8091 } 8092 #endif /* HAVE_INET6 */ 8093 switch (pservaddr->sa_family) 8094 { 8095 case AF_INET: 8096 if (1) 8097 { 8098 struct sockaddr_in sa4; 8099 uint16_t sa4_port; 8100 if ((0 != addrlen) 8101 && (((socklen_t) sizeof(sa4)) > addrlen)) 8102 { 8103 #ifdef HAVE_MESSAGES 8104 MHD_DLOG (daemon, 8105 _ ("The size specified for MHD_OPTION_SOCK_ADDR_LEN " \ 8106 "option is wrong.\n")); 8107 #endif /* HAVE_MESSAGES */ 8108 goto free_and_fail; 8109 } 8110 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 8111 if (0 != sa_len) 8112 { 8113 if (((socklen_t) sizeof(sa4)) > sa_len) 8114 { 8115 #ifdef HAVE_MESSAGES 8116 MHD_DLOG (daemon, 8117 _ ("The value of 'struct sockaddr.sa_len' provided " \ 8118 "via MHD_OPTION_SOCK_ADDR_LEN option is not zero " \ 8119 "and does not match 'sa_family' value of the " \ 8120 "same structure.\n")); 8121 #endif /* HAVE_MESSAGES */ 8122 goto free_and_fail; 8123 } 8124 if ((0 == addrlen) || (sa_len < addrlen)) 8125 addrlen = sa_len; /* Use smaller value for safety */ 8126 } 8127 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ 8128 if (0 == addrlen) 8129 addrlen = sizeof(sa4); 8130 memcpy (&sa4, pservaddr, sizeof(sa4)); /* Required due to stronger alignment */ 8131 sa4_port = (uint16_t) ntohs (sa4.sin_port); 8132 #ifndef MHD_USE_GETSOCKNAME 8133 if (0 != sa4_port) 8134 #endif /* ! MHD_USE_GETSOCKNAME */ 8135 daemon->port = sa4_port; 8136 domain = PF_INET; 8137 } 8138 break; 8139 #ifdef HAVE_INET6 8140 case AF_INET6: 8141 if (1) 8142 { 8143 struct sockaddr_in6 sa6; 8144 uint16_t sa6_port; 8145 if ((0 != addrlen) 8146 && (((socklen_t) sizeof(sa6)) > addrlen)) 8147 { 8148 #ifdef HAVE_MESSAGES 8149 MHD_DLOG (daemon, 8150 _ ("The size specified for MHD_OPTION_SOCK_ADDR_LEN " \ 8151 "option is wrong.\n")); 8152 #endif /* HAVE_MESSAGES */ 8153 goto free_and_fail; 8154 } 8155 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 8156 if (0 != sa_len) 8157 { 8158 if (((socklen_t) sizeof(sa6)) > sa_len) 8159 { 8160 #ifdef HAVE_MESSAGES 8161 MHD_DLOG (daemon, 8162 _ ("The value of 'struct sockaddr.sa_len' provided " \ 8163 "via MHD_OPTION_SOCK_ADDR_LEN option is not zero " \ 8164 "and does not match 'sa_family' value of the " \ 8165 "same structure.\n")); 8166 #endif /* HAVE_MESSAGES */ 8167 goto free_and_fail; 8168 } 8169 if ((0 == addrlen) || (sa_len < addrlen)) 8170 addrlen = sa_len; /* Use smaller value for safety */ 8171 } 8172 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ 8173 if (0 == addrlen) 8174 addrlen = sizeof(sa6); 8175 memcpy (&sa6, pservaddr, sizeof(sa6)); /* Required due to stronger alignment */ 8176 sa6_port = (uint16_t) ntohs (sa6.sin6_port); 8177 #ifndef MHD_USE_GETSOCKNAME 8178 if (0 != sa6_port) 8179 #endif /* ! MHD_USE_GETSOCKNAME */ 8180 daemon->port = sa6_port; 8181 domain = PF_INET6; 8182 *pflags |= ((enum MHD_FLAG) MHD_USE_IPv6); 8183 } 8184 break; 8185 #endif /* HAVE_INET6 */ 8186 #ifdef AF_UNIX 8187 case AF_UNIX: 8188 #endif /* AF_UNIX */ 8189 default: 8190 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 8191 if (0 == addrlen) 8192 addrlen = sa_len; 8193 else if ((0 != sa_len) && (sa_len < addrlen)) 8194 addrlen = sa_len; /* Use smaller value for safety */ 8195 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ 8196 if (0 >= addrlen) 8197 { 8198 #ifdef HAVE_MESSAGES 8199 MHD_DLOG (daemon, 8200 _ ("The 'sa_family' of the 'struct sockaddr' provided " \ 8201 "via MHD_OPTION_SOCK_ADDR option is not supported.\n")); 8202 #endif /* HAVE_MESSAGES */ 8203 goto free_and_fail; 8204 } 8205 #ifdef AF_UNIX 8206 if (AF_UNIX == pservaddr->sa_family) 8207 { 8208 daemon->port = 0; /* special value for UNIX domain sockets */ 8209 daemon->listen_is_unix = _MHD_YES; 8210 #ifdef PF_UNIX 8211 domain = PF_UNIX; 8212 #else /* ! PF_UNIX */ 8213 domain = AF_UNIX; 8214 #endif /* ! PF_UNIX */ 8215 } 8216 else /* combined with the next 'if' */ 8217 #endif /* AF_UNIX */ 8218 if (1) 8219 { 8220 daemon->port = 0; /* ugh */ 8221 daemon->listen_is_unix = _MHD_UNKNOWN; 8222 /* Assumed the same values for AF_* and PF_* */ 8223 domain = pservaddr->sa_family; 8224 } 8225 break; 8226 } 8227 } 8228 else 8229 { 8230 if (! use_ipv6) 8231 { 8232 memset (&servaddr4, 8233 0, 8234 sizeof (struct sockaddr_in)); 8235 servaddr4.sin_family = AF_INET; 8236 servaddr4.sin_port = htons (port); 8237 if (0 != INADDR_ANY) 8238 servaddr4.sin_addr.s_addr = htonl (INADDR_ANY); 8239 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN 8240 servaddr4.sin_len = sizeof (struct sockaddr_in); 8241 #endif 8242 pservaddr = (struct sockaddr *) &servaddr4; 8243 addrlen = (socklen_t) sizeof(servaddr4); 8244 daemon->listen_is_unix = _MHD_NO; 8245 domain = PF_INET; 8246 } 8247 #ifdef HAVE_INET6 8248 else 8249 { 8250 #ifdef IN6ADDR_ANY_INIT 8251 static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT; 8252 #endif 8253 memset (&servaddr6, 8254 0, 8255 sizeof (struct sockaddr_in6)); 8256 servaddr6.sin6_family = AF_INET6; 8257 servaddr6.sin6_port = htons (port); 8258 #ifdef IN6ADDR_ANY_INIT 8259 servaddr6.sin6_addr = static_in6any; 8260 #endif 8261 #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN 8262 servaddr6.sin6_len = sizeof (struct sockaddr_in6); 8263 #endif 8264 pservaddr = (struct sockaddr *) &servaddr6; 8265 addrlen = (socklen_t) sizeof (servaddr6); 8266 daemon->listen_is_unix = _MHD_NO; 8267 domain = PF_INET6; 8268 } 8269 #endif /* HAVE_INET6 */ 8270 } 8271 8272 daemon->listen_fd = MHD_socket_create_listen_ (domain); 8273 if (MHD_INVALID_SOCKET == daemon->listen_fd) 8274 { 8275 #ifdef HAVE_MESSAGES 8276 MHD_DLOG (daemon, 8277 _ ("Failed to create socket for listening: %s\n"), 8278 MHD_socket_last_strerr_ ()); 8279 #endif 8280 goto free_and_fail; 8281 } 8282 if (MHD_D_IS_USING_SELECT_ (daemon) && 8283 (! MHD_D_DOES_SCKT_FIT_FDSET_ (daemon->listen_fd, 8284 daemon)) ) 8285 { 8286 #ifdef HAVE_MESSAGES 8287 MHD_DLOG (daemon, 8288 _ ("Listen socket descriptor (%d) is not " \ 8289 "less than daemon FD_SETSIZE value (%d).\n"), 8290 (int) daemon->listen_fd, 8291 (int) MHD_D_GET_FD_SETSIZE_ (daemon)); 8292 #endif 8293 goto free_and_fail; 8294 } 8295 8296 /* Apply the socket options according to listening_address_reuse. */ 8297 if (0 == daemon->listening_address_reuse) 8298 { 8299 #ifndef MHD_WINSOCK_SOCKETS 8300 /* No user requirement, use "traditional" default SO_REUSEADDR 8301 * on non-W32 platforms, and do not fail if it doesn't work. 8302 * Don't use it on W32, because on W32 it will allow multiple 8303 * bind to the same address:port, like SO_REUSEPORT on others. */ 8304 if (0 > setsockopt (daemon->listen_fd, 8305 SOL_SOCKET, 8306 SO_REUSEADDR, 8307 (const void *) &on, sizeof (on))) 8308 { 8309 #ifdef HAVE_MESSAGES 8310 MHD_DLOG (daemon, 8311 _ ("setsockopt failed: %s\n"), 8312 MHD_socket_last_strerr_ ()); 8313 #endif 8314 } 8315 #endif /* ! MHD_WINSOCK_SOCKETS */ 8316 } 8317 else if (daemon->listening_address_reuse > 0) 8318 { 8319 /* User requested to allow reusing listening address:port. */ 8320 #ifndef MHD_WINSOCK_SOCKETS 8321 /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if 8322 * it doesn't work. */ 8323 if (0 > setsockopt (daemon->listen_fd, 8324 SOL_SOCKET, 8325 SO_REUSEADDR, 8326 (const void *) &on, sizeof (on))) 8327 { 8328 #ifdef HAVE_MESSAGES 8329 MHD_DLOG (daemon, 8330 _ ("setsockopt failed: %s\n"), 8331 MHD_socket_last_strerr_ ()); 8332 #endif 8333 } 8334 #endif /* ! MHD_WINSOCK_SOCKETS */ 8335 /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms. 8336 * Fail if SO_REUSEPORT is not defined or setsockopt fails. 8337 */ 8338 /* SO_REUSEADDR on W32 has the same semantics 8339 as SO_REUSEPORT on BSD/Linux */ 8340 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT) 8341 if (0 > setsockopt (daemon->listen_fd, 8342 SOL_SOCKET, 8343 #ifndef MHD_WINSOCK_SOCKETS 8344 SO_REUSEPORT, 8345 #else /* MHD_WINSOCK_SOCKETS */ 8346 SO_REUSEADDR, 8347 #endif /* MHD_WINSOCK_SOCKETS */ 8348 (const void *) &on, 8349 sizeof (on))) 8350 { 8351 #ifdef HAVE_MESSAGES 8352 MHD_DLOG (daemon, 8353 _ ("setsockopt failed: %s\n"), 8354 MHD_socket_last_strerr_ ()); 8355 #endif 8356 goto free_and_fail; 8357 } 8358 #else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */ 8359 /* we're supposed to allow address:port re-use, but 8360 on this platform we cannot; fail hard */ 8361 #ifdef HAVE_MESSAGES 8362 MHD_DLOG (daemon, 8363 _ ("Cannot allow listening address reuse: " \ 8364 "SO_REUSEPORT not defined.\n")); 8365 #endif 8366 goto free_and_fail; 8367 #endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */ 8368 } 8369 else /* if (daemon->listening_address_reuse < 0) */ 8370 { 8371 /* User requested to disallow reusing listening address:port. 8372 * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE 8373 * is used and Solaris with SO_EXCLBIND. 8374 * Fail if MHD was compiled for W32 without SO_EXCLUSIVEADDRUSE 8375 * or setsockopt fails. 8376 */ 8377 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \ 8378 (defined(__sun) && defined(SO_EXCLBIND)) 8379 if (0 > setsockopt (daemon->listen_fd, 8380 SOL_SOCKET, 8381 #ifdef SO_EXCLUSIVEADDRUSE 8382 SO_EXCLUSIVEADDRUSE, 8383 #else /* SO_EXCLBIND */ 8384 SO_EXCLBIND, 8385 #endif /* SO_EXCLBIND */ 8386 (const void *) &on, 8387 sizeof (on))) 8388 { 8389 #ifdef HAVE_MESSAGES 8390 MHD_DLOG (daemon, 8391 _ ("setsockopt failed: %s\n"), 8392 MHD_socket_last_strerr_ ()); 8393 #endif 8394 goto free_and_fail; 8395 } 8396 #elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */ 8397 #ifdef HAVE_MESSAGES 8398 MHD_DLOG (daemon, 8399 _ ("Cannot disallow listening address reuse: " \ 8400 "SO_EXCLUSIVEADDRUSE not defined.\n")); 8401 #endif 8402 goto free_and_fail; 8403 #endif /* MHD_WINSOCK_SOCKETS */ 8404 } 8405 8406 /* check for user supplied sockaddr */ 8407 if (0 != (*pflags & MHD_USE_IPv6)) 8408 { 8409 #ifdef IPPROTO_IPV6 8410 #ifdef IPV6_V6ONLY 8411 /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options" 8412 (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx); 8413 and may also be missing on older POSIX systems; good luck if you have any of those, 8414 your IPv6 socket may then also bind against IPv4 anyway... */ 8415 const MHD_SCKT_OPT_BOOL_ v6_only = 8416 (MHD_USE_DUAL_STACK != (*pflags & MHD_USE_DUAL_STACK)); 8417 if (0 > setsockopt (daemon->listen_fd, 8418 IPPROTO_IPV6, IPV6_V6ONLY, 8419 (const void *) &v6_only, 8420 sizeof (v6_only))) 8421 { 8422 #ifdef HAVE_MESSAGES 8423 MHD_DLOG (daemon, 8424 _ ("setsockopt failed: %s\n"), 8425 MHD_socket_last_strerr_ ()); 8426 #endif 8427 } 8428 #endif 8429 #endif 8430 } 8431 if (0 != bind (daemon->listen_fd, 8432 pservaddr, 8433 addrlen)) 8434 { 8435 #ifdef HAVE_MESSAGES 8436 MHD_DLOG (daemon, 8437 _ ("Failed to bind to port %u: %s\n"), 8438 (unsigned int) port, 8439 MHD_socket_last_strerr_ ()); 8440 #endif 8441 goto free_and_fail; 8442 } 8443 #ifdef TCP_FASTOPEN 8444 if (0 != (*pflags & MHD_USE_TCP_FASTOPEN)) 8445 { 8446 if (0 == daemon->fastopen_queue_size) 8447 daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT; 8448 if (0 != setsockopt (daemon->listen_fd, 8449 IPPROTO_TCP, 8450 TCP_FASTOPEN, 8451 (const void *) &daemon->fastopen_queue_size, 8452 sizeof (daemon->fastopen_queue_size))) 8453 { 8454 #ifdef HAVE_MESSAGES 8455 MHD_DLOG (daemon, 8456 _ ("setsockopt failed: %s\n"), 8457 MHD_socket_last_strerr_ ()); 8458 #endif 8459 } 8460 } 8461 #endif 8462 if (0 != listen (daemon->listen_fd, 8463 (int) daemon->listen_backlog_size)) 8464 { 8465 #ifdef HAVE_MESSAGES 8466 MHD_DLOG (daemon, 8467 _ ("Failed to listen for connections: %s\n"), 8468 MHD_socket_last_strerr_ ()); 8469 #endif 8470 goto free_and_fail; 8471 } 8472 } 8473 else 8474 { 8475 if (MHD_D_IS_USING_SELECT_ (daemon) && 8476 (! MHD_D_DOES_SCKT_FIT_FDSET_ (daemon->listen_fd, 8477 daemon)) ) 8478 { 8479 #ifdef HAVE_MESSAGES 8480 MHD_DLOG (daemon, 8481 _ ("Listen socket descriptor (%d) is not " \ 8482 "less than daemon FD_SETSIZE value (%d).\n"), 8483 (int) daemon->listen_fd, 8484 (int) MHD_D_GET_FD_SETSIZE_ (daemon)); 8485 #endif 8486 goto free_and_fail; 8487 } 8488 else 8489 { 8490 #if defined(SOL_SOCKET) && (defined(SO_DOMAIN) || defined(SO_PROTOCOL_INFOW)) 8491 int af; 8492 int opt_name; 8493 void *poptval; 8494 socklen_t optval_size; 8495 #ifdef SO_DOMAIN 8496 opt_name = SO_DOMAIN; 8497 poptval = ⁡ 8498 optval_size = (socklen_t) sizeof (af); 8499 #else /* SO_PROTOCOL_INFOW */ 8500 WSAPROTOCOL_INFOW prot_info; 8501 opt_name = SO_PROTOCOL_INFOW; 8502 poptval = &prot_info; 8503 optval_size = (socklen_t) sizeof (prot_info); 8504 #endif /* SO_PROTOCOL_INFOW */ 8505 8506 if (0 == getsockopt (daemon->listen_fd, 8507 SOL_SOCKET, 8508 opt_name, 8509 poptval, 8510 &optval_size)) 8511 { 8512 #ifndef SO_DOMAIN 8513 af = prot_info.iAddressFamily; 8514 #endif /* SO_DOMAIN */ 8515 switch (af) 8516 { 8517 case AF_INET: 8518 daemon->listen_is_unix = _MHD_NO; 8519 break; 8520 #ifdef HAVE_INET6 8521 case AF_INET6: 8522 *pflags |= MHD_USE_IPv6; 8523 daemon->listen_is_unix = _MHD_NO; 8524 break; 8525 #endif /* HAVE_INET6 */ 8526 #ifdef AF_UNIX 8527 case AF_UNIX: 8528 daemon->port = 0; /* special value for UNIX domain sockets */ 8529 daemon->listen_is_unix = _MHD_YES; 8530 break; 8531 #endif /* AF_UNIX */ 8532 default: 8533 daemon->port = 0; /* ugh */ 8534 daemon->listen_is_unix = _MHD_UNKNOWN; 8535 break; 8536 } 8537 } 8538 else 8539 #endif /* SOL_SOCKET && (SO_DOMAIN || SO_PROTOCOL_INFOW)) */ 8540 daemon->listen_is_unix = _MHD_UNKNOWN; 8541 } 8542 8543 #ifdef MHD_USE_GETSOCKNAME 8544 daemon->port = 0; /* Force use of autodetection */ 8545 #endif /* MHD_USE_GETSOCKNAME */ 8546 } 8547 8548 #ifdef MHD_USE_GETSOCKNAME 8549 if ( (0 == daemon->port) && 8550 (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) && 8551 (_MHD_YES != daemon->listen_is_unix) ) 8552 { /* Get port number. */ 8553 struct sockaddr_storage bindaddr; 8554 8555 memset (&bindaddr, 8556 0, 8557 sizeof (struct sockaddr_storage)); 8558 addrlen = sizeof (struct sockaddr_storage); 8559 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 8560 bindaddr.ss_len = (socklen_t) addrlen; 8561 #endif 8562 if (0 != getsockname (daemon->listen_fd, 8563 (struct sockaddr *) &bindaddr, 8564 &addrlen)) 8565 { 8566 #ifdef HAVE_MESSAGES 8567 MHD_DLOG (daemon, 8568 _ ("Failed to get listen port number: %s\n"), 8569 MHD_socket_last_strerr_ ()); 8570 #endif /* HAVE_MESSAGES */ 8571 } 8572 #ifdef MHD_POSIX_SOCKETS 8573 else if (sizeof (bindaddr) < addrlen) 8574 { 8575 /* should be impossible with `struct sockaddr_storage` */ 8576 #ifdef HAVE_MESSAGES 8577 MHD_DLOG (daemon, 8578 _ ("Failed to get listen port number " \ 8579 "(`struct sockaddr_storage` too small!?).\n")); 8580 #endif /* HAVE_MESSAGES */ 8581 } 8582 #ifndef __linux__ 8583 else if (0 == addrlen) 8584 { 8585 /* Many non-Linux-based platforms return zero addrlen 8586 * for AF_UNIX sockets */ 8587 daemon->port = 0; /* special value for UNIX domain sockets */ 8588 if (_MHD_UNKNOWN == daemon->listen_is_unix) 8589 daemon->listen_is_unix = _MHD_YES; 8590 } 8591 #endif /* __linux__ */ 8592 #endif /* MHD_POSIX_SOCKETS */ 8593 else 8594 { 8595 switch (bindaddr.ss_family) 8596 { 8597 case AF_INET: 8598 { 8599 struct sockaddr_in *s4 = (struct sockaddr_in *) &bindaddr; 8600 8601 daemon->port = ntohs (s4->sin_port); 8602 daemon->listen_is_unix = _MHD_NO; 8603 break; 8604 } 8605 #ifdef HAVE_INET6 8606 case AF_INET6: 8607 { 8608 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &bindaddr; 8609 8610 daemon->port = ntohs (s6->sin6_port); 8611 daemon->listen_is_unix = _MHD_NO; 8612 mhd_assert (0 != (*pflags & MHD_USE_IPv6)); 8613 break; 8614 } 8615 #endif /* HAVE_INET6 */ 8616 #ifdef AF_UNIX 8617 case AF_UNIX: 8618 daemon->port = 0; /* special value for UNIX domain sockets */ 8619 daemon->listen_is_unix = _MHD_YES; 8620 break; 8621 #endif 8622 default: 8623 #ifdef HAVE_MESSAGES 8624 MHD_DLOG (daemon, 8625 _ ("Listen socket has unknown address family!\n")); 8626 #endif 8627 daemon->port = 0; /* ugh */ 8628 daemon->listen_is_unix = _MHD_UNKNOWN; 8629 break; 8630 } 8631 } 8632 } 8633 #endif /* MHD_USE_GETSOCKNAME */ 8634 8635 if (MHD_INVALID_SOCKET != daemon->listen_fd) 8636 { 8637 mhd_assert (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)); 8638 if (! MHD_socket_nonblocking_ (daemon->listen_fd)) 8639 { 8640 #ifdef HAVE_MESSAGES 8641 MHD_DLOG (daemon, 8642 _ ("Failed to set nonblocking mode on listening socket: %s\n"), 8643 MHD_socket_last_strerr_ ()); 8644 #endif 8645 if (MHD_D_IS_USING_EPOLL_ (daemon) 8646 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 8647 || (daemon->worker_pool_size > 0) 8648 #endif 8649 ) 8650 { 8651 /* Accept must be non-blocking. Multiple children may wake up 8652 * to handle a new connection, but only one will win the race. 8653 * The others must immediately return. */ 8654 goto free_and_fail; 8655 } 8656 daemon->listen_nonblk = false; 8657 } 8658 else 8659 daemon->listen_nonblk = true; 8660 } 8661 else 8662 { 8663 mhd_assert (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET)); 8664 daemon->listen_nonblk = false; /* Actually listen socket does not exist */ 8665 } 8666 8667 #ifdef EPOLL_SUPPORT 8668 if (MHD_D_IS_USING_EPOLL_ (daemon) 8669 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 8670 && (0 == daemon->worker_pool_size) 8671 #endif 8672 ) 8673 { 8674 if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) 8675 { 8676 #ifdef HAVE_MESSAGES 8677 MHD_DLOG (daemon, 8678 _ ("Combining MHD_USE_THREAD_PER_CONNECTION and " \ 8679 "MHD_USE_EPOLL is not supported.\n")); 8680 #endif 8681 goto free_and_fail; 8682 } 8683 if (MHD_NO == setup_epoll_to_listen (daemon)) 8684 goto free_and_fail; 8685 } 8686 #endif /* EPOLL_SUPPORT */ 8687 8688 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 8689 if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex)) 8690 { 8691 #ifdef HAVE_MESSAGES 8692 MHD_DLOG (daemon, 8693 _ ("MHD failed to initialize IP connection limit mutex.\n")); 8694 #endif 8695 goto free_and_fail; 8696 } 8697 #endif 8698 8699 #ifdef HTTPS_SUPPORT 8700 /* initialize HTTPS daemon certificate aspects & send / recv functions */ 8701 if ( (0 != (*pflags & MHD_USE_TLS)) && 8702 (0 != MHD_TLS_init (daemon)) ) 8703 { 8704 #ifdef HAVE_MESSAGES 8705 MHD_DLOG (daemon, 8706 _ ("Failed to initialize TLS support.\n")); 8707 #endif 8708 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 8709 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 8710 #endif 8711 goto free_and_fail; 8712 } 8713 #endif /* HTTPS_SUPPORT */ 8714 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 8715 /* Start threads if requested by parameters */ 8716 if (MHD_D_IS_USING_THREADS_ (daemon)) 8717 { 8718 /* Internal thread (or threads) is used. 8719 * Make sure that MHD will be able to communicate with threads. */ 8720 /* If using a thread pool ITC will be initialised later 8721 * for each individual worker thread. */ 8722 #ifdef HAVE_LISTEN_SHUTDOWN 8723 mhd_assert ((1 < daemon->worker_pool_size) || \ 8724 (MHD_ITC_IS_VALID_ (daemon->itc)) || \ 8725 (MHD_INVALID_SOCKET != daemon->listen_fd)); 8726 #else /* ! HAVE_LISTEN_SHUTDOWN */ 8727 mhd_assert ((1 < daemon->worker_pool_size) || \ 8728 (MHD_ITC_IS_VALID_ (daemon->itc))); 8729 #endif /* ! HAVE_LISTEN_SHUTDOWN */ 8730 if (0 == daemon->worker_pool_size) 8731 { 8732 if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex)) 8733 { 8734 #ifdef HAVE_MESSAGES 8735 MHD_DLOG (daemon, 8736 _ ("Failed to initialise internal lists mutex.\n")); 8737 #endif 8738 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 8739 goto free_and_fail; 8740 } 8741 if (! MHD_mutex_init_ (&daemon->new_connections_mutex)) 8742 { 8743 #ifdef HAVE_MESSAGES 8744 MHD_DLOG (daemon, 8745 _ ("Failed to initialise mutex.\n")); 8746 #endif 8747 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 8748 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); 8749 goto free_and_fail; 8750 } 8751 if (! MHD_create_named_thread_ (&daemon->tid, 8752 MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) ? 8753 "MHD-listen" : "MHD-single", 8754 daemon->thread_stack_size, 8755 &MHD_polling_thread, 8756 daemon) ) 8757 { 8758 #ifdef HAVE_MESSAGES 8759 #ifdef EAGAIN 8760 if (EAGAIN == errno) 8761 MHD_DLOG (daemon, 8762 _ ("Failed to create a new thread because it would have " \ 8763 "exceeded the system limit on the number of threads or " \ 8764 "no system resources available.\n")); 8765 else 8766 #endif /* EAGAIN */ 8767 MHD_DLOG (daemon, 8768 _ ("Failed to create listen thread: %s\n"), 8769 MHD_strerror_ (errno)); 8770 #endif /* HAVE_MESSAGES */ 8771 MHD_mutex_destroy_chk_ (&daemon->new_connections_mutex); 8772 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 8773 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); 8774 goto free_and_fail; 8775 } 8776 } 8777 else /* 0 < daemon->worker_pool_size */ 8778 { 8779 /* Coarse-grained count of connections per thread (note error 8780 * due to integer division). Also keep track of how many 8781 * connections are leftover after an equal split. */ 8782 unsigned int conns_per_thread = daemon->connection_limit 8783 / daemon->worker_pool_size; 8784 unsigned int leftover_conns = daemon->connection_limit 8785 % daemon->worker_pool_size; 8786 8787 mhd_assert (2 <= daemon->worker_pool_size); 8788 i = 0; /* we need this in case fcntl or malloc fails */ 8789 8790 /* Allocate memory for pooled objects */ 8791 daemon->worker_pool = malloc (sizeof (struct MHD_Daemon) 8792 * daemon->worker_pool_size); 8793 if (NULL == daemon->worker_pool) 8794 goto thread_failed; 8795 8796 /* Start the workers in the pool */ 8797 for (i = 0; i < daemon->worker_pool_size; ++i) 8798 { 8799 /* Create copy of the Daemon object for each worker */ 8800 struct MHD_Daemon *d = &daemon->worker_pool[i]; 8801 8802 memcpy (d, daemon, sizeof (struct MHD_Daemon)); 8803 /* Adjust polling params for worker daemons; note that memcpy() 8804 has already copied MHD_USE_INTERNAL_POLLING_THREAD thread mode into 8805 the worker threads. */ 8806 d->master = daemon; 8807 d->worker_pool_size = 0; 8808 d->worker_pool = NULL; 8809 if (! MHD_mutex_init_ (&d->cleanup_connection_mutex)) 8810 { 8811 #ifdef HAVE_MESSAGES 8812 MHD_DLOG (daemon, 8813 _ ("Failed to initialise internal lists mutex.\n")); 8814 #endif 8815 goto thread_failed; 8816 } 8817 if (! MHD_mutex_init_ (&d->new_connections_mutex)) 8818 { 8819 #ifdef HAVE_MESSAGES 8820 MHD_DLOG (daemon, 8821 _ ("Failed to initialise mutex.\n")); 8822 #endif 8823 MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex); 8824 goto thread_failed; 8825 } 8826 if (0 != (*pflags & MHD_USE_ITC)) 8827 { 8828 if (! MHD_itc_init_ (d->itc)) 8829 { 8830 #ifdef HAVE_MESSAGES 8831 MHD_DLOG (daemon, 8832 _ ("Failed to create worker inter-thread " \ 8833 "communication channel: %s\n"), 8834 MHD_itc_last_strerror_ () ); 8835 #endif 8836 MHD_mutex_destroy_chk_ (&d->new_connections_mutex); 8837 MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex); 8838 goto thread_failed; 8839 } 8840 if (MHD_D_IS_USING_SELECT_ (d) && 8841 (! MHD_D_DOES_SCKT_FIT_FDSET_ (MHD_itc_r_fd_ (d->itc), daemon)) ) 8842 { 8843 #ifdef HAVE_MESSAGES 8844 MHD_DLOG (daemon, 8845 _ ("File descriptor for worker inter-thread " \ 8846 "communication channel exceeds maximum value.\n")); 8847 #endif 8848 MHD_itc_destroy_chk_ (d->itc); 8849 MHD_mutex_destroy_chk_ (&d->new_connections_mutex); 8850 MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex); 8851 goto thread_failed; 8852 } 8853 } 8854 else 8855 MHD_itc_set_invalid_ (d->itc); 8856 8857 #ifdef HAVE_LISTEN_SHUTDOWN 8858 mhd_assert ((MHD_ITC_IS_VALID_ (d->itc)) || \ 8859 (MHD_INVALID_SOCKET != d->listen_fd)); 8860 #else /* ! HAVE_LISTEN_SHUTDOWN */ 8861 mhd_assert (MHD_ITC_IS_VALID_ (d->itc)); 8862 #endif /* ! HAVE_LISTEN_SHUTDOWN */ 8863 8864 /* Divide available connections evenly amongst the threads. 8865 * Thread indexes in [0, leftover_conns) each get one of the 8866 * leftover connections. */ 8867 d->connection_limit = conns_per_thread; 8868 if (i < leftover_conns) 8869 ++d->connection_limit; 8870 #ifdef EPOLL_SUPPORT 8871 if (MHD_D_IS_USING_EPOLL_ (d) && 8872 (MHD_NO == setup_epoll_to_listen (d)) ) 8873 { 8874 if (MHD_ITC_IS_VALID_ (d->itc)) 8875 MHD_itc_destroy_chk_ (d->itc); 8876 MHD_mutex_destroy_chk_ (&d->new_connections_mutex); 8877 MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex); 8878 goto thread_failed; 8879 } 8880 #endif 8881 /* Some members must be used only in master daemon */ 8882 #if defined(MHD_USE_THREADS) 8883 memset (&d->per_ip_connection_mutex, 0x7F, 8884 sizeof(d->per_ip_connection_mutex)); 8885 #endif /* MHD_USE_THREADS */ 8886 #ifdef DAUTH_SUPPORT 8887 d->nnc = NULL; 8888 d->nonce_nc_size = 0; 8889 d->digest_auth_random_copy = NULL; 8890 #if defined(MHD_USE_THREADS) 8891 memset (&d->nnc_lock, 0x7F, sizeof(d->nnc_lock)); 8892 #endif /* MHD_USE_THREADS */ 8893 #endif /* DAUTH_SUPPORT */ 8894 8895 /* Spawn the worker thread */ 8896 if (! MHD_create_named_thread_ (&d->tid, 8897 "MHD-worker", 8898 daemon->thread_stack_size, 8899 &MHD_polling_thread, 8900 d)) 8901 { 8902 #ifdef HAVE_MESSAGES 8903 #ifdef EAGAIN 8904 if (EAGAIN == errno) 8905 MHD_DLOG (daemon, 8906 _ ("Failed to create a new pool thread because it would " \ 8907 "have exceeded the system limit on the number of " \ 8908 "threads or no system resources available.\n")); 8909 else 8910 #endif /* EAGAIN */ 8911 MHD_DLOG (daemon, 8912 _ ("Failed to create pool thread: %s\n"), 8913 MHD_strerror_ (errno)); 8914 #endif 8915 /* Free memory for this worker; cleanup below handles 8916 * all previously-created workers. */ 8917 MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex); 8918 if (MHD_ITC_IS_VALID_ (d->itc)) 8919 MHD_itc_destroy_chk_ (d->itc); 8920 MHD_mutex_destroy_chk_ (&d->new_connections_mutex); 8921 MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex); 8922 goto thread_failed; 8923 } 8924 } 8925 } 8926 } 8927 else 8928 { /* Daemon without internal threads */ 8929 if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex)) 8930 { 8931 #ifdef HAVE_MESSAGES 8932 MHD_DLOG (daemon, 8933 _ ("Failed to initialise internal lists mutex.\n")); 8934 #endif 8935 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 8936 goto free_and_fail; 8937 } 8938 if (! MHD_mutex_init_ (&daemon->new_connections_mutex)) 8939 { 8940 #ifdef HAVE_MESSAGES 8941 MHD_DLOG (daemon, 8942 _ ("Failed to initialise mutex.\n")); 8943 #endif 8944 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); 8945 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 8946 goto free_and_fail; 8947 } 8948 } 8949 #endif 8950 #ifdef HTTPS_SUPPORT 8951 /* API promises to never use the password after initialization, 8952 so we additionally NULL it here to not deref a dangling pointer. */ 8953 daemon->https_key_password = NULL; 8954 #endif /* HTTPS_SUPPORT */ 8955 8956 return daemon; 8957 8958 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 8959 thread_failed: 8960 /* If no worker threads created, then shut down normally. Calling 8961 MHD_stop_daemon (as we do below) doesn't work here since it 8962 assumes a 0-sized thread pool means we had been in the default 8963 MHD_USE_INTERNAL_POLLING_THREAD mode. */ 8964 if (0 == i) 8965 { 8966 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 8967 if (NULL != daemon->worker_pool) 8968 free (daemon->worker_pool); 8969 goto free_and_fail; 8970 } 8971 8972 /* Shutdown worker threads we've already created. Pretend 8973 as though we had fully initialized our daemon, but 8974 with a smaller number of threads than had been 8975 requested. */ 8976 daemon->worker_pool_size = i; 8977 MHD_stop_daemon (daemon); 8978 return NULL; 8979 #endif 8980 8981 free_and_fail: 8982 /* clean up basic memory state in 'daemon' and return NULL to 8983 indicate failure */ 8984 #ifdef EPOLL_SUPPORT 8985 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 8986 if (daemon->upgrade_fd_in_epoll) 8987 { 8988 if (0 != epoll_ctl (daemon->epoll_fd, 8989 EPOLL_CTL_DEL, 8990 daemon->epoll_upgrade_fd, 8991 NULL)) 8992 MHD_PANIC (_ ("Failed to remove FD from epoll set.\n")); 8993 daemon->upgrade_fd_in_epoll = false; 8994 } 8995 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 8996 if (-1 != daemon->epoll_fd) 8997 close (daemon->epoll_fd); 8998 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 8999 if (-1 != daemon->epoll_upgrade_fd) 9000 close (daemon->epoll_upgrade_fd); 9001 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 9002 #endif /* EPOLL_SUPPORT */ 9003 #ifdef DAUTH_SUPPORT 9004 free (daemon->digest_auth_random_copy); 9005 free (daemon->nnc); 9006 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9007 MHD_mutex_destroy_chk_ (&daemon->nnc_lock); 9008 #endif 9009 #endif 9010 #ifdef HTTPS_SUPPORT 9011 if (0 != (*pflags & MHD_USE_TLS)) 9012 { 9013 gnutls_priority_deinit (daemon->priority_cache); 9014 if (daemon->x509_cred) 9015 gnutls_certificate_free_credentials (daemon->x509_cred); 9016 if (daemon->psk_cred) 9017 gnutls_psk_free_server_credentials (daemon->psk_cred); 9018 } 9019 #endif /* HTTPS_SUPPORT */ 9020 if (MHD_ITC_IS_VALID_ (daemon->itc)) 9021 MHD_itc_destroy_chk_ (daemon->itc); 9022 if (MHD_INVALID_SOCKET != daemon->listen_fd) 9023 (void) MHD_socket_close_ (daemon->listen_fd); 9024 free (daemon); 9025 return NULL; 9026 } 9027 9028 9029 /** 9030 * Close all connections for the daemon. 9031 * Must only be called when MHD_Daemon::shutdown was set to true. 9032 * @remark To be called only from thread that process 9033 * daemon's select()/poll()/etc. 9034 * 9035 * @param daemon daemon to close down 9036 */ 9037 static void 9038 close_all_connections (struct MHD_Daemon *daemon) 9039 { 9040 struct MHD_Connection *pos; 9041 const bool used_thr_p_c = MHD_D_IS_USING_THREAD_PER_CONN_ (daemon); 9042 #ifdef UPGRADE_SUPPORT 9043 const bool upg_allowed = (0 != (daemon->options & MHD_ALLOW_UPGRADE)); 9044 #endif /* UPGRADE_SUPPORT */ 9045 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 9046 struct MHD_UpgradeResponseHandle *urh; 9047 struct MHD_UpgradeResponseHandle *urhn; 9048 const bool used_tls = (0 != (daemon->options & MHD_USE_TLS)); 9049 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 9050 9051 #ifdef MHD_USE_THREADS 9052 mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \ 9053 MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) || \ 9054 MHD_thread_handle_ID_is_current_thread_ (daemon->tid) ); 9055 mhd_assert (NULL == daemon->worker_pool); 9056 #endif /* MHD_USE_THREADS */ 9057 mhd_assert (daemon->shutdown); 9058 9059 #ifdef MHD_USE_THREADS 9060 /* Remove externally added new connections that are 9061 * not processed by the daemon thread. */ 9062 MHD_mutex_lock_chk_ (&daemon->new_connections_mutex); 9063 while (NULL != (pos = daemon->new_connections_tail)) 9064 { 9065 mhd_assert (MHD_D_IS_USING_THREADS_ (daemon)); 9066 DLL_remove (daemon->new_connections_head, 9067 daemon->new_connections_tail, 9068 pos); 9069 new_connection_close_ (daemon, pos); 9070 } 9071 MHD_mutex_unlock_chk_ (&daemon->new_connections_mutex); 9072 #endif /* MHD_USE_THREADS */ 9073 9074 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 9075 /* give upgraded HTTPS connections a chance to finish */ 9076 /* 'daemon->urh_head' is not used in thread-per-connection mode. */ 9077 for (urh = daemon->urh_tail; NULL != urh; urh = urhn) 9078 { 9079 mhd_assert (! used_thr_p_c); 9080 urhn = urh->prev; 9081 /* call generic forwarding function for passing data 9082 with chance to detect that application is done. */ 9083 process_urh (urh); 9084 MHD_connection_finish_forward_ (urh->connection); 9085 urh->clean_ready = true; 9086 /* Resuming will move connection to cleanup list. */ 9087 MHD_resume_connection (urh->connection); 9088 } 9089 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 9090 9091 /* Give suspended connections a chance to resume to avoid 9092 running into the check for there not being any suspended 9093 connections left in case of a tight race with a recently 9094 resumed connection. */ 9095 if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options)) 9096 { 9097 daemon->resuming = true; /* Force check for pending resume. */ 9098 resume_suspended_connections (daemon); 9099 } 9100 /* first, make sure all threads are aware of shutdown; need to 9101 traverse DLLs in peace... */ 9102 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9103 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 9104 #endif 9105 #ifdef UPGRADE_SUPPORT 9106 if (upg_allowed) 9107 { 9108 struct MHD_Connection *susp; 9109 9110 susp = daemon->suspended_connections_tail; 9111 while (NULL != susp) 9112 { 9113 if (NULL == susp->urh) /* "Upgraded" connection? */ 9114 MHD_PANIC (_ ("MHD_stop_daemon() called while we have " \ 9115 "suspended connections.\n")); 9116 #ifdef HTTPS_SUPPORT 9117 else if (used_tls && 9118 used_thr_p_c && 9119 (! susp->urh->clean_ready) ) 9120 shutdown (susp->urh->app.socket, 9121 SHUT_RDWR); /* Wake thread by shutdown of app socket. */ 9122 #endif /* HTTPS_SUPPORT */ 9123 else 9124 { 9125 #ifdef HAVE_MESSAGES 9126 if (! susp->urh->was_closed) 9127 MHD_DLOG (daemon, 9128 _ ("Initiated daemon shutdown while \"upgraded\" " \ 9129 "connection was not closed.\n")); 9130 #endif 9131 susp->urh->was_closed = true; 9132 /* If thread-per-connection is used, connection's thread 9133 * may still processing "upgrade" (exiting). */ 9134 if (! used_thr_p_c) 9135 MHD_connection_finish_forward_ (susp); 9136 /* Do not use MHD_resume_connection() as mutex is 9137 * already locked. */ 9138 susp->resuming = true; 9139 daemon->resuming = true; 9140 } 9141 susp = susp->prev; 9142 } 9143 } 9144 else /* This 'else' is combined with next 'if' */ 9145 #endif /* UPGRADE_SUPPORT */ 9146 if (NULL != daemon->suspended_connections_head) 9147 MHD_PANIC (_ ("MHD_stop_daemon() called while we have " \ 9148 "suspended connections.\n")); 9149 #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT) 9150 #ifdef MHD_USE_THREADS 9151 if (upg_allowed && used_tls && used_thr_p_c) 9152 { 9153 /* "Upgraded" threads may be running in parallel. Connection will not be 9154 * moved to the "cleanup list" until connection's thread finishes. 9155 * We must ensure that all "upgraded" connections are finished otherwise 9156 * connection may stay in "suspended" list and will not be cleaned. */ 9157 for (pos = daemon->suspended_connections_tail; NULL != pos; pos = pos->prev) 9158 { 9159 /* Any connection found here is "upgraded" connection, normal suspended 9160 * connections are already removed from this list. */ 9161 mhd_assert (NULL != pos->urh); 9162 if (! pos->thread_joined) 9163 { 9164 /* While "cleanup" list is not manipulated by "upgraded" 9165 * connection, "cleanup" mutex is required for call of 9166 * MHD_resume_connection() during finishing of "upgraded" 9167 * thread. */ 9168 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 9169 if (! MHD_thread_handle_ID_join_thread_ (pos->tid)) 9170 MHD_PANIC (_ ("Failed to join a thread.\n")); 9171 pos->thread_joined = true; 9172 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 9173 } 9174 } 9175 } 9176 #endif /* MHD_USE_THREADS */ 9177 #endif 9178 for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev) 9179 { 9180 shutdown (pos->socket_fd, 9181 SHUT_RDWR); 9182 #ifdef MHD_WINSOCK_SOCKETS 9183 if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) && 9184 (MHD_ITC_IS_VALID_ (daemon->itc)) && 9185 (! MHD_itc_activate_ (daemon->itc, "e")) ) 9186 MHD_PANIC (_ ("Failed to signal shutdown via inter-thread " \ 9187 "communication channel.\n")); 9188 #endif 9189 } 9190 9191 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9192 /* now, collect per-connection threads */ 9193 if (used_thr_p_c) 9194 { 9195 pos = daemon->connections_tail; 9196 while (NULL != pos) 9197 { 9198 if (! pos->thread_joined) 9199 { 9200 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 9201 if (! MHD_thread_handle_ID_join_thread_ (pos->tid)) 9202 MHD_PANIC (_ ("Failed to join a thread.\n")); 9203 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 9204 pos->thread_joined = true; 9205 /* The thread may have concurrently modified the DLL, 9206 need to restart from the beginning */ 9207 pos = daemon->connections_tail; 9208 continue; 9209 } 9210 pos = pos->prev; 9211 } 9212 } 9213 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 9214 #endif 9215 9216 #ifdef UPGRADE_SUPPORT 9217 /* Finished threads with "upgraded" connections need to be moved 9218 * to cleanup list by resume_suspended_connections(). */ 9219 /* "Upgraded" connections that were not closed explicitly by 9220 * application should be moved to cleanup list too. */ 9221 if (upg_allowed) 9222 { 9223 daemon->resuming = true; /* Force check for pending resume. */ 9224 resume_suspended_connections (daemon); 9225 } 9226 #endif /* UPGRADE_SUPPORT */ 9227 9228 mhd_assert (NULL == daemon->suspended_connections_head); 9229 /* now that we're alone, move everyone to cleanup */ 9230 while (NULL != (pos = daemon->connections_tail)) 9231 { 9232 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9233 if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) && 9234 (! pos->thread_joined) ) 9235 MHD_PANIC (_ ("Failed to join a thread.\n")); 9236 #endif 9237 close_connection (pos); 9238 } 9239 MHD_cleanup_connections (daemon); 9240 } 9241 9242 9243 /** 9244 * Shutdown an HTTP daemon. 9245 * 9246 * @param daemon daemon to stop 9247 * @ingroup event 9248 */ 9249 _MHD_EXTERN void 9250 MHD_stop_daemon (struct MHD_Daemon *daemon) 9251 { 9252 MHD_socket fd; 9253 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9254 unsigned int i; 9255 #endif 9256 9257 if (NULL == daemon) 9258 return; 9259 if ( (daemon->shutdown) && (NULL == daemon->master) ) 9260 MHD_PANIC (_ ("MHD_stop_daemon() was called twice.")); 9261 9262 mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 9263 (NULL != daemon->worker_pool) || \ 9264 (MHD_thread_handle_ID_is_valid_handle_ (daemon->tid))); 9265 mhd_assert (((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) && 9266 (NULL == daemon->worker_pool)) || \ 9267 (! MHD_thread_handle_ID_is_valid_handle_ (daemon->tid))); 9268 9269 /* Slave daemons must be stopped by master daemon. */ 9270 mhd_assert ( (NULL == daemon->master) || (daemon->shutdown) ); 9271 9272 daemon->shutdown = true; 9273 if (daemon->was_quiesced) 9274 fd = MHD_INVALID_SOCKET; /* Do not use FD if daemon was quiesced */ 9275 else 9276 fd = daemon->listen_fd; 9277 9278 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9279 if (NULL != daemon->worker_pool) 9280 { /* Master daemon with worker pool. */ 9281 mhd_assert (1 < daemon->worker_pool_size); 9282 mhd_assert (MHD_D_IS_USING_THREADS_ (daemon)); 9283 9284 /* Let workers shutdown in parallel. */ 9285 for (i = 0; i < daemon->worker_pool_size; ++i) 9286 { 9287 daemon->worker_pool[i].shutdown = true; 9288 if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc)) 9289 { 9290 if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, 9291 "e")) 9292 MHD_PANIC (_ ("Failed to signal shutdown via inter-thread " \ 9293 "communication channel.\n")); 9294 } 9295 else 9296 mhd_assert (MHD_INVALID_SOCKET != fd); 9297 } 9298 #ifdef HAVE_LISTEN_SHUTDOWN 9299 if (MHD_INVALID_SOCKET != fd) 9300 { 9301 (void) shutdown (fd, 9302 SHUT_RDWR); 9303 } 9304 #endif /* HAVE_LISTEN_SHUTDOWN */ 9305 for (i = 0; i < daemon->worker_pool_size; ++i) 9306 { 9307 MHD_stop_daemon (&daemon->worker_pool[i]); 9308 } 9309 free (daemon->worker_pool); 9310 mhd_assert (MHD_ITC_IS_INVALID_ (daemon->itc)); 9311 #ifdef EPOLL_SUPPORT 9312 mhd_assert (-1 == daemon->epoll_fd); 9313 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 9314 mhd_assert (-1 == daemon->epoll_upgrade_fd); 9315 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 9316 #endif /* EPOLL_SUPPORT */ 9317 } 9318 else 9319 #endif 9320 { /* Worker daemon or single daemon. */ 9321 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9322 if (MHD_D_IS_USING_THREADS_ (daemon)) 9323 { /* Worker daemon or single daemon with internal thread(s). */ 9324 mhd_assert (0 == daemon->worker_pool_size); 9325 /* Separate thread(s) is used for polling sockets. */ 9326 if (MHD_ITC_IS_VALID_ (daemon->itc)) 9327 { 9328 if (! MHD_itc_activate_ (daemon->itc, 9329 "e")) 9330 MHD_PANIC (_ ("Failed to signal shutdown via inter-thread " \ 9331 "communication channel.\n")); 9332 } 9333 else 9334 { 9335 #ifdef HAVE_LISTEN_SHUTDOWN 9336 if (MHD_INVALID_SOCKET != fd) 9337 { 9338 if (NULL == daemon->master) 9339 (void) shutdown (fd, 9340 SHUT_RDWR); 9341 } 9342 else 9343 #endif /* HAVE_LISTEN_SHUTDOWN */ 9344 mhd_assert (false); /* Should never happen */ 9345 } 9346 9347 if (! MHD_thread_handle_ID_join_thread_ (daemon->tid)) 9348 { 9349 MHD_PANIC (_ ("Failed to join a thread.\n")); 9350 } 9351 /* close_all_connections() was called in daemon thread. */ 9352 } 9353 else 9354 #endif 9355 { 9356 /* No internal threads are used for polling sockets. */ 9357 close_all_connections (daemon); 9358 } 9359 mhd_assert (NULL == daemon->connections_head); 9360 mhd_assert (NULL == daemon->cleanup_head); 9361 mhd_assert (NULL == daemon->suspended_connections_head); 9362 mhd_assert (NULL == daemon->new_connections_head); 9363 #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT) 9364 mhd_assert (NULL == daemon->urh_head); 9365 #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */ 9366 9367 if (MHD_ITC_IS_VALID_ (daemon->itc)) 9368 MHD_itc_destroy_chk_ (daemon->itc); 9369 9370 #ifdef EPOLL_SUPPORT 9371 if (MHD_D_IS_USING_EPOLL_ (daemon) && 9372 (-1 != daemon->epoll_fd) ) 9373 MHD_socket_close_chk_ (daemon->epoll_fd); 9374 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 9375 if (MHD_D_IS_USING_EPOLL_ (daemon) && 9376 (-1 != daemon->epoll_upgrade_fd) ) 9377 MHD_socket_close_chk_ (daemon->epoll_upgrade_fd); 9378 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 9379 #endif /* EPOLL_SUPPORT */ 9380 9381 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9382 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); 9383 MHD_mutex_destroy_chk_ (&daemon->new_connections_mutex); 9384 #endif 9385 } 9386 9387 if (NULL == daemon->master) 9388 { /* Cleanup that should be done only one time in master/single daemon. 9389 * Do not perform this cleanup in worker daemons. */ 9390 9391 if (MHD_INVALID_SOCKET != fd) 9392 MHD_socket_close_chk_ (fd); 9393 9394 /* TLS clean up */ 9395 #ifdef HTTPS_SUPPORT 9396 if (daemon->have_dhparams) 9397 { 9398 gnutls_dh_params_deinit (daemon->https_mem_dhparams); 9399 daemon->have_dhparams = false; 9400 } 9401 if (0 != (daemon->options & MHD_USE_TLS)) 9402 { 9403 gnutls_priority_deinit (daemon->priority_cache); 9404 if (daemon->x509_cred) 9405 gnutls_certificate_free_credentials (daemon->x509_cred); 9406 if (daemon->psk_cred) 9407 gnutls_psk_free_server_credentials (daemon->psk_cred); 9408 } 9409 #endif /* HTTPS_SUPPORT */ 9410 9411 #ifdef DAUTH_SUPPORT 9412 free (daemon->digest_auth_random_copy); 9413 free (daemon->nnc); 9414 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9415 MHD_mutex_destroy_chk_ (&daemon->nnc_lock); 9416 #endif 9417 #endif 9418 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9419 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 9420 #endif 9421 free (daemon); 9422 } 9423 } 9424 9425 9426 /** 9427 * Obtain information about the given daemon. 9428 * The returned pointer is invalidated with the next call of this function or 9429 * when the daemon is stopped. 9430 * 9431 * @param daemon what daemon to get information about 9432 * @param info_type what information is desired? 9433 * @param ... depends on @a info_type 9434 * @return NULL if this information is not available 9435 * (or if the @a info_type is unknown) 9436 * @ingroup specialized 9437 */ 9438 _MHD_EXTERN const union MHD_DaemonInfo * 9439 MHD_get_daemon_info (struct MHD_Daemon *daemon, 9440 enum MHD_DaemonInfoType info_type, 9441 ...) 9442 { 9443 if (NULL == daemon) 9444 return NULL; 9445 9446 mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ 9447 (NULL != daemon->worker_pool) || \ 9448 (MHD_thread_handle_ID_is_valid_handle_ (daemon->tid))); 9449 mhd_assert (((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) && 9450 (NULL == daemon->worker_pool)) || \ 9451 (! MHD_thread_handle_ID_is_valid_handle_ (daemon->tid))); 9452 9453 switch (info_type) 9454 { 9455 case MHD_DAEMON_INFO_KEY_SIZE: 9456 return NULL; /* no longer supported */ 9457 case MHD_DAEMON_INFO_MAC_KEY_SIZE: 9458 return NULL; /* no longer supported */ 9459 case MHD_DAEMON_INFO_LISTEN_FD: 9460 daemon->daemon_info_dummy_listen_fd.listen_fd = daemon->listen_fd; 9461 return &daemon->daemon_info_dummy_listen_fd; 9462 case MHD_DAEMON_INFO_EPOLL_FD: 9463 #ifdef EPOLL_SUPPORT 9464 daemon->daemon_info_dummy_epoll_fd.epoll_fd = daemon->epoll_fd; 9465 return &daemon->daemon_info_dummy_epoll_fd; 9466 #else /* ! EPOLL_SUPPORT */ 9467 return NULL; 9468 #endif /* ! EPOLL_SUPPORT */ 9469 case MHD_DAEMON_INFO_CURRENT_CONNECTIONS: 9470 if (! MHD_D_IS_THREAD_SAFE_ (daemon)) 9471 MHD_cleanup_connections (daemon); 9472 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9473 else if (daemon->worker_pool) 9474 { 9475 unsigned int i; 9476 /* Collect the connection information stored in the workers. */ 9477 daemon->connections = 0; 9478 for (i = 0; i < daemon->worker_pool_size; i++) 9479 { 9480 /* FIXME: next line is thread-safe only if read is atomic. */ 9481 daemon->connections += daemon->worker_pool[i].connections; 9482 } 9483 } 9484 #endif 9485 daemon->daemon_info_dummy_num_connections.num_connections 9486 = daemon->connections; 9487 return &daemon->daemon_info_dummy_num_connections; 9488 case MHD_DAEMON_INFO_FLAGS: 9489 daemon->daemon_info_dummy_flags.flags = daemon->options; 9490 return &daemon->daemon_info_dummy_flags; 9491 case MHD_DAEMON_INFO_BIND_PORT: 9492 daemon->daemon_info_dummy_port.port = daemon->port; 9493 return &daemon->daemon_info_dummy_port; 9494 default: 9495 return NULL; 9496 } 9497 } 9498 9499 9500 /** 9501 * Obtain the version of this library 9502 * 9503 * @return static version string, e.g. "0.9.9" 9504 * @ingroup specialized 9505 */ 9506 _MHD_EXTERN const char * 9507 MHD_get_version (void) 9508 { 9509 #ifdef PACKAGE_VERSION 9510 return PACKAGE_VERSION; 9511 #else /* !PACKAGE_VERSION */ 9512 static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0"; 9513 if (0 == ver[0]) 9514 { 9515 int res = MHD_snprintf_ (ver, 9516 sizeof(ver), 9517 "%x.%x.%x", 9518 (int) (((uint32_t) MHD_VERSION >> 24) & 0xFF), 9519 (int) (((uint32_t) MHD_VERSION >> 16) & 0xFF), 9520 (int) (((uint32_t) MHD_VERSION >> 8) & 0xFF)); 9521 if ((0 >= res) || (sizeof(ver) <= res)) 9522 return "0.0.0"; /* Can't return real version */ 9523 } 9524 return ver; 9525 #endif /* !PACKAGE_VERSION */ 9526 } 9527 9528 9529 /** 9530 * Obtain the version of this library as a binary value. 9531 * 9532 * @return version binary value, e.g. "0x00090900" (#MHD_VERSION of 9533 * compiled MHD binary) 9534 * @note Available since #MHD_VERSION 0x00097601 9535 * @ingroup specialized 9536 */ 9537 _MHD_EXTERN uint32_t 9538 MHD_get_version_bin (void) 9539 { 9540 return (uint32_t) MHD_VERSION; 9541 } 9542 9543 9544 /** 9545 * Get information about supported MHD features. 9546 * Indicate that MHD was compiled with or without support for 9547 * particular feature. Some features require additional support 9548 * by kernel. Kernel support is not checked by this function. 9549 * 9550 * @param feature type of requested information 9551 * @return #MHD_YES if feature is supported by MHD, #MHD_NO if 9552 * feature is not supported or feature is unknown. 9553 * @ingroup specialized 9554 */ 9555 _MHD_EXTERN enum MHD_Result 9556 MHD_is_feature_supported (enum MHD_FEATURE feature) 9557 { 9558 switch (feature) 9559 { 9560 case MHD_FEATURE_MESSAGES: 9561 #ifdef HAVE_MESSAGES 9562 return MHD_YES; 9563 #else 9564 return MHD_NO; 9565 #endif 9566 case MHD_FEATURE_TLS: 9567 #ifdef HTTPS_SUPPORT 9568 return MHD_YES; 9569 #else /* ! HTTPS_SUPPORT */ 9570 return MHD_NO; 9571 #endif /* ! HTTPS_SUPPORT */ 9572 case MHD_FEATURE_HTTPS_CERT_CALLBACK: 9573 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3 9574 return MHD_YES; 9575 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */ 9576 return MHD_NO; 9577 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */ 9578 case MHD_FEATURE_HTTPS_CERT_CALLBACK2: 9579 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030603 9580 return MHD_YES; 9581 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */ 9582 return MHD_NO; 9583 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */ 9584 case MHD_FEATURE_IPv6: 9585 #ifdef HAVE_INET6 9586 return MHD_YES; 9587 #else 9588 return MHD_NO; 9589 #endif 9590 case MHD_FEATURE_IPv6_ONLY: 9591 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) 9592 return MHD_YES; 9593 #else 9594 return MHD_NO; 9595 #endif 9596 case MHD_FEATURE_POLL: 9597 #ifdef HAVE_POLL 9598 return MHD_YES; 9599 #else 9600 return MHD_NO; 9601 #endif 9602 case MHD_FEATURE_EPOLL: 9603 #ifdef EPOLL_SUPPORT 9604 return MHD_YES; 9605 #else 9606 return MHD_NO; 9607 #endif 9608 case MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET: 9609 #ifdef HAVE_LISTEN_SHUTDOWN 9610 return MHD_YES; 9611 #else 9612 return MHD_NO; 9613 #endif 9614 case MHD_FEATURE_SOCKETPAIR: 9615 #ifdef _MHD_ITC_SOCKETPAIR 9616 return MHD_YES; 9617 #else 9618 return MHD_NO; 9619 #endif 9620 case MHD_FEATURE_TCP_FASTOPEN: 9621 #ifdef TCP_FASTOPEN 9622 return MHD_YES; 9623 #else 9624 return MHD_NO; 9625 #endif 9626 case MHD_FEATURE_BASIC_AUTH: 9627 #ifdef BAUTH_SUPPORT 9628 return MHD_YES; 9629 #else 9630 return MHD_NO; 9631 #endif 9632 case MHD_FEATURE_DIGEST_AUTH: 9633 #ifdef DAUTH_SUPPORT 9634 return MHD_YES; 9635 #else 9636 return MHD_NO; 9637 #endif 9638 case MHD_FEATURE_POSTPROCESSOR: 9639 #ifdef HAVE_POSTPROCESSOR 9640 return MHD_YES; 9641 #else 9642 return MHD_NO; 9643 #endif 9644 case MHD_FEATURE_HTTPS_KEY_PASSWORD: 9645 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111 9646 return MHD_YES; 9647 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */ 9648 return MHD_NO; 9649 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */ 9650 case MHD_FEATURE_LARGE_FILE: 9651 #if defined(HAVE_PREAD64) || defined(_WIN32) 9652 return MHD_YES; 9653 #elif defined(HAVE_PREAD) 9654 return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES; 9655 #elif defined(HAVE_LSEEK64) 9656 return MHD_YES; 9657 #else 9658 return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES; 9659 #endif 9660 case MHD_FEATURE_THREAD_NAMES: 9661 #if defined(MHD_USE_THREAD_NAME_) 9662 return MHD_YES; 9663 #else 9664 return MHD_NO; 9665 #endif 9666 case MHD_FEATURE_UPGRADE: 9667 #if defined(UPGRADE_SUPPORT) 9668 return MHD_YES; 9669 #else 9670 return MHD_NO; 9671 #endif 9672 case MHD_FEATURE_RESPONSES_SHARED_FD: 9673 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32) 9674 return MHD_YES; 9675 #else 9676 return MHD_NO; 9677 #endif 9678 case MHD_FEATURE_AUTODETECT_BIND_PORT: 9679 #ifdef MHD_USE_GETSOCKNAME 9680 return MHD_YES; 9681 #else 9682 return MHD_NO; 9683 #endif 9684 case MHD_FEATURE_AUTOSUPPRESS_SIGPIPE: 9685 #if defined(MHD_SEND_SPIPE_SUPPRESS_POSSIBLE) || \ 9686 ! defined(MHD_SEND_SPIPE_SUPPRESS_NEEDED) 9687 return MHD_YES; 9688 #else 9689 return MHD_NO; 9690 #endif 9691 case MHD_FEATURE_SENDFILE: 9692 #ifdef _MHD_HAVE_SENDFILE 9693 return MHD_YES; 9694 #else 9695 return MHD_NO; 9696 #endif 9697 case MHD_FEATURE_THREADS: 9698 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 9699 return MHD_YES; 9700 #else 9701 return MHD_NO; 9702 #endif 9703 case MHD_FEATURE_COOKIE_PARSING: 9704 #if defined(COOKIE_SUPPORT) 9705 return MHD_YES; 9706 #else 9707 return MHD_NO; 9708 #endif 9709 case MHD_FEATURE_DIGEST_AUTH_RFC2069: 9710 #ifdef DAUTH_SUPPORT 9711 return MHD_YES; 9712 #else 9713 return MHD_NO; 9714 #endif 9715 case MHD_FEATURE_DIGEST_AUTH_MD5: 9716 #if defined(DAUTH_SUPPORT) && defined(MHD_MD5_SUPPORT) 9717 return MHD_YES; 9718 #else 9719 return MHD_NO; 9720 #endif 9721 case MHD_FEATURE_DIGEST_AUTH_SHA256: 9722 #if defined(DAUTH_SUPPORT) && defined(MHD_SHA256_SUPPORT) 9723 return MHD_YES; 9724 #else 9725 return MHD_NO; 9726 #endif 9727 case MHD_FEATURE_DIGEST_AUTH_SHA512_256: 9728 #if defined(DAUTH_SUPPORT) && defined(MHD_SHA512_256_SUPPORT) 9729 return MHD_YES; 9730 #else 9731 return MHD_NO; 9732 #endif 9733 case MHD_FEATURE_DIGEST_AUTH_AUTH_INT: 9734 #ifdef DAUTH_SUPPORT 9735 return MHD_NO; 9736 #else 9737 return MHD_NO; 9738 #endif 9739 case MHD_FEATURE_DIGEST_AUTH_ALGO_SESSION: 9740 #ifdef DAUTH_SUPPORT 9741 return MHD_NO; 9742 #else 9743 return MHD_NO; 9744 #endif 9745 case MHD_FEATURE_DIGEST_AUTH_USERHASH: 9746 #ifdef DAUTH_SUPPORT 9747 return MHD_YES; 9748 #else 9749 return MHD_NO; 9750 #endif 9751 case MHD_FEATURE_EXTERN_HASH: 9752 #if defined(MHD_MD5_TLSLIB) || defined(MHD_SHA256_TLSLIB) 9753 return MHD_YES; 9754 #else 9755 return MHD_NO; 9756 #endif 9757 case MHD_FEATURE_DEBUG_BUILD: 9758 #ifdef _DEBUG 9759 return MHD_YES; 9760 #else 9761 return MHD_NO; 9762 #endif 9763 case MHD_FEATURE_FLEXIBLE_FD_SETSIZE: 9764 #ifdef HAS_FD_SETSIZE_OVERRIDABLE 9765 return MHD_YES; 9766 #else /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 9767 return MHD_NO; 9768 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */ 9769 9770 default: 9771 break; 9772 } 9773 return MHD_NO; 9774 } 9775 9776 9777 #ifdef MHD_HTTPS_REQUIRE_GCRYPT 9778 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600 9779 #if defined(MHD_USE_POSIX_THREADS) 9780 GCRY_THREAD_OPTION_PTHREAD_IMPL; 9781 #elif defined(MHD_W32_MUTEX_) 9782 9783 static int 9784 gcry_w32_mutex_init (void **ppmtx) 9785 { 9786 *ppmtx = malloc (sizeof (MHD_mutex_)); 9787 9788 if (NULL == *ppmtx) 9789 return ENOMEM; 9790 if (! MHD_mutex_init_ ((MHD_mutex_ *) *ppmtx)) 9791 { 9792 free (*ppmtx); 9793 *ppmtx = NULL; 9794 return EPERM; 9795 } 9796 9797 return 0; 9798 } 9799 9800 9801 static int 9802 gcry_w32_mutex_destroy (void **ppmtx) 9803 { 9804 int res = (MHD_mutex_destroy_ ((MHD_mutex_ *) *ppmtx)) ? 0 : EINVAL; 9805 free (*ppmtx); 9806 return res; 9807 } 9808 9809 9810 static int 9811 gcry_w32_mutex_lock (void **ppmtx) 9812 { 9813 return MHD_mutex_lock_ ((MHD_mutex_ *) *ppmtx) ? 0 : EINVAL; 9814 } 9815 9816 9817 static int 9818 gcry_w32_mutex_unlock (void **ppmtx) 9819 { 9820 return MHD_mutex_unlock_ ((MHD_mutex_ *) *ppmtx) ? 0 : EINVAL; 9821 } 9822 9823 9824 static struct gcry_thread_cbs gcry_threads_w32 = { 9825 (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)), 9826 NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy, 9827 gcry_w32_mutex_lock, gcry_w32_mutex_unlock, 9828 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL 9829 }; 9830 9831 #endif /* defined(MHD_W32_MUTEX_) */ 9832 #endif /* HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600 */ 9833 #endif /* MHD_HTTPS_REQUIRE_GCRYPT */ 9834 9835 /** 9836 * Initialize do setup work. 9837 */ 9838 void 9839 MHD_init (void) 9840 { 9841 #if defined(MHD_WINSOCK_SOCKETS) 9842 WSADATA wsd; 9843 #endif /* MHD_WINSOCK_SOCKETS */ 9844 9845 MHD_set_panic_func (NULL, NULL); 9846 9847 #if defined(MHD_WINSOCK_SOCKETS) 9848 if (0 != WSAStartup (MAKEWORD (2, 2), &wsd)) 9849 MHD_PANIC (_ ("Failed to initialize winsock.\n")); 9850 if ((2 != LOBYTE (wsd.wVersion)) && (2 != HIBYTE (wsd.wVersion))) 9851 MHD_PANIC (_ ("Winsock version 2.2 is not available.\n")); 9852 #endif /* MHD_WINSOCK_SOCKETS */ 9853 #ifdef HTTPS_SUPPORT 9854 #ifdef MHD_HTTPS_REQUIRE_GCRYPT 9855 #if GCRYPT_VERSION_NUMBER < 0x010600 9856 #if GNUTLS_VERSION_NUMBER <= 0x020b00 9857 #if defined(MHD_USE_POSIX_THREADS) 9858 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS, 9859 &gcry_threads_pthread)) 9860 MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt.\n")); 9861 #elif defined(MHD_W32_MUTEX_) 9862 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS, 9863 &gcry_threads_w32)) 9864 MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt.\n")); 9865 #endif /* defined(MHD_W32_MUTEX_) */ 9866 #endif /* GNUTLS_VERSION_NUMBER <= 0x020b00 */ 9867 gcry_check_version (NULL); 9868 #else 9869 if (NULL == gcry_check_version ("1.6.0")) 9870 MHD_PANIC (_ ("libgcrypt is too old. MHD was compiled for " \ 9871 "libgcrypt 1.6.0 or newer.\n")); 9872 #endif 9873 #endif /* MHD_HTTPS_REQUIRE_GCRYPT */ 9874 gnutls_global_init (); 9875 #endif /* HTTPS_SUPPORT */ 9876 MHD_monotonic_sec_counter_init (); 9877 MHD_send_init_static_vars_ (); 9878 MHD_init_mem_pools_ (); 9879 /* Check whether sizes were correctly detected by configure */ 9880 #ifdef _DEBUG 9881 if (1) 9882 { 9883 struct timeval tv; 9884 mhd_assert (sizeof(tv.tv_sec) == SIZEOF_STRUCT_TIMEVAL_TV_SEC); 9885 } 9886 #endif /* _DEBUG */ 9887 mhd_assert (sizeof(uint64_t) == SIZEOF_UINT64_T); 9888 } 9889 9890 9891 void 9892 MHD_fini (void) 9893 { 9894 #ifdef HTTPS_SUPPORT 9895 gnutls_global_deinit (); 9896 #endif /* HTTPS_SUPPORT */ 9897 #if defined(MHD_WINSOCK_SOCKETS) 9898 WSACleanup (); 9899 #endif /* MHD_WINSOCK_SOCKETS */ 9900 MHD_monotonic_sec_counter_finish (); 9901 } 9902 9903 9904 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED 9905 _SET_INIT_AND_DEINIT_FUNCS (MHD_init, MHD_fini); 9906 #endif /* _AUTOINIT_FUNCS_ARE_SUPPORTED */ 9907 9908 /* end of daemon.c */