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