1/* 2 This file is part of libmicrohttpd 3 Copyright (C) 2007-2014 Daniel Pittman and Christian Grothoff 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 19*/ 20 21/** 22 * @file microhttpd/daemon.c 23 * @brief A minimal-HTTP server library 24 * @author Daniel Pittman 25 * @author Christian Grothoff 26 */ 27#if defined(_WIN32) && !defined(__CYGWIN__) 28/* override small default value */ 29#define FD_SETSIZE 1024 30#define MHD_DEFAULT_FD_SETSIZE 64 31#else 32#define MHD_DEFAULT_FD_SETSIZE FD_SETSIZE 33#endif 34#include "platform.h" 35#include "internal.h" 36#include "response.h" 37#include "connection.h" 38#include "memorypool.h" 39#include <limits.h> 40#include "autoinit_funcs.h" 41 42#if HAVE_SEARCH_H 43#include <search.h> 44#else 45#include "tsearch.h" 46#endif 47 48#if HTTPS_SUPPORT 49#include "connection_https.h" 50#include <openssl/ssl.h> 51#endif 52 53#if defined(HAVE_POLL_H) && defined(HAVE_POLL) 54#include <poll.h> 55#endif 56 57#ifdef LINUX 58#include <sys/sendfile.h> 59#endif 60 61#ifdef _WIN32 62#ifndef WIN32_LEAN_AND_MEAN 63#define WIN32_LEAN_AND_MEAN 1 64#endif /* !WIN32_LEAN_AND_MEAN */ 65#include <windows.h> 66#include <process.h> 67#endif 68 69#ifndef HAVE_ACCEPT4 70#define HAVE_ACCEPT4 0 71#endif 72 73/** 74 * Default connection limit. 75 */ 76#ifndef WINDOWS 77#define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE - 4 78#else 79#define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE 80#endif 81 82/** 83 * Default memory allowed per connection. 84 */ 85#define MHD_POOL_SIZE_DEFAULT (32 * 1024) 86 87#ifdef TCP_FASTOPEN 88/** 89 * Default TCP fastopen queue size. 90 */ 91#define MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT 10 92#endif 93 94/** 95 * Print extra messages with reasons for closing 96 * sockets? (only adds non-error messages). 97 */ 98#define DEBUG_CLOSE MHD_NO 99 100/** 101 * Print extra messages when establishing 102 * connections? (only adds non-error messages). 103 */ 104#define DEBUG_CONNECT MHD_NO 105 106#ifndef LINUX 107#ifndef MSG_NOSIGNAL 108#define MSG_NOSIGNAL 0 109#endif 110#endif 111 112#ifndef SOCK_CLOEXEC 113#define SOCK_CLOEXEC 0 114#endif 115 116#ifndef EPOLL_CLOEXEC 117#define EPOLL_CLOEXEC 0 118#endif 119 120 121/** 122 * Default implementation of the panic function, 123 * prints an error message and aborts. 124 * 125 * @param cls unused 126 * @param file name of the file with the problem 127 * @param line line number with the problem 128 * @param reason error message with details 129 */ 130static void 131mhd_panic_std (void *cls, 132 const char *file, 133 unsigned int line, 134 const char *reason) 135{ 136#if HAVE_MESSAGES 137 fprintf (stderr, "Fatal error in GNU libmicrohttpd %s:%u: %s\n", 138 file, line, reason); 139#endif 140 abort (); 141} 142 143 144/** 145 * Handler for fatal errors. 146 */ 147MHD_PanicCallback mhd_panic; 148 149/** 150 * Closure argument for "mhd_panic". 151 */ 152void *mhd_panic_cls; 153 154#ifdef _WIN32 155/** 156 * Track initialization of winsock 157 */ 158static int mhd_winsock_inited_ = 0; 159#endif 160 161/** 162 * Trace up to and return master daemon. If the supplied daemon 163 * is a master, then return the daemon itself. 164 * 165 * @param daemon handle to a daemon 166 * @return master daemon handle 167 */ 168static struct MHD_Daemon* 169MHD_get_master (struct MHD_Daemon *daemon) 170{ 171 while (NULL != daemon->master) 172 daemon = daemon->master; 173 return daemon; 174} 175 176 177/** 178 * Maintain connection count for single address. 179 */ 180struct MHD_IPCount 181{ 182 /** 183 * Address family. AF_INET or AF_INET6 for now. 184 */ 185 int family; 186 187 /** 188 * Actual address. 189 */ 190 union 191 { 192 /** 193 * IPv4 address. 194 */ 195 struct in_addr ipv4; 196#if HAVE_INET6 197 /** 198 * IPv6 address. 199 */ 200 struct in6_addr ipv6; 201#endif 202 } addr; 203 204 /** 205 * Counter. 206 */ 207 unsigned int count; 208}; 209 210 211/** 212 * Lock shared structure for IP connection counts and connection DLLs. 213 * 214 * @param daemon handle to daemon where lock is 215 */ 216static void 217MHD_ip_count_lock (struct MHD_Daemon *daemon) 218{ 219 if (MHD_YES != MHD_mutex_lock_(&daemon->per_ip_connection_mutex)) 220 { 221 MHD_PANIC ("Failed to acquire IP connection limit mutex\n"); 222 } 223} 224 225 226/** 227 * Unlock shared structure for IP connection counts and connection DLLs. 228 * 229 * @param daemon handle to daemon where lock is 230 */ 231static void 232MHD_ip_count_unlock (struct MHD_Daemon *daemon) 233{ 234 if (MHD_YES != MHD_mutex_unlock_(&daemon->per_ip_connection_mutex)) 235 { 236 MHD_PANIC ("Failed to release IP connection limit mutex\n"); 237 } 238} 239 240 241/** 242 * Tree comparison function for IP addresses (supplied to tsearch() family). 243 * We compare everything in the struct up through the beginning of the 244 * 'count' field. 245 * 246 * @param a1 first address to compare 247 * @param a2 second address to compare 248 * @return -1, 0 or 1 depending on result of compare 249 */ 250static int 251MHD_ip_addr_compare (const void *a1, const void *a2) 252{ 253 return memcmp (a1, a2, offsetof (struct MHD_IPCount, count)); 254} 255 256 257/** 258 * Parse address and initialize 'key' using the address. 259 * 260 * @param addr address to parse 261 * @param addrlen number of bytes in addr 262 * @param key where to store the parsed address 263 * @return #MHD_YES on success and #MHD_NO otherwise (e.g., invalid address type) 264 */ 265static int 266MHD_ip_addr_to_key (const struct sockaddr *addr, 267 socklen_t addrlen, 268 struct MHD_IPCount *key) 269{ 270 memset(key, 0, sizeof(*key)); 271 272 /* IPv4 addresses */ 273 if (sizeof (struct sockaddr_in) == addrlen) 274 { 275 const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr; 276 key->family = AF_INET; 277 memcpy (&key->addr.ipv4, &addr4->sin_addr, sizeof(addr4->sin_addr)); 278 return MHD_YES; 279 } 280 281#if HAVE_INET6 282 /* IPv6 addresses */ 283 if (sizeof (struct sockaddr_in6) == addrlen) 284 { 285 const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr; 286 key->family = AF_INET6; 287 memcpy (&key->addr.ipv6, &addr6->sin6_addr, sizeof(addr6->sin6_addr)); 288 return MHD_YES; 289 } 290#endif 291 292 /* Some other address */ 293 return MHD_NO; 294} 295 296 297/** 298 * Check if IP address is over its limit. 299 * 300 * @param daemon handle to daemon where connection counts are tracked 301 * @param addr address to add (or increment counter) 302 * @param addrlen number of bytes in addr 303 * @return Return #MHD_YES if IP below limit, #MHD_NO if IP has surpassed limit. 304 * Also returns #MHD_NO if fails to allocate memory. 305 */ 306static int 307MHD_ip_limit_add (struct MHD_Daemon *daemon, 308 const struct sockaddr *addr, 309 socklen_t addrlen) 310{ 311 struct MHD_IPCount *key; 312 void **nodep; 313 void *node; 314 int result; 315 316 daemon = MHD_get_master (daemon); 317 /* Ignore if no connection limit assigned */ 318 if (0 == daemon->per_ip_connection_limit) 319 return MHD_YES; 320 321 if (NULL == (key = malloc (sizeof(*key)))) 322 return MHD_NO; 323 324 /* Initialize key */ 325 if (MHD_NO == MHD_ip_addr_to_key (addr, addrlen, key)) 326 { 327 /* Allow unhandled address types through */ 328 free (key); 329 return MHD_YES; 330 } 331 MHD_ip_count_lock (daemon); 332 333 /* Search for the IP address */ 334 if (NULL == (nodep = tsearch (key, 335 &daemon->per_ip_connection_count, 336 &MHD_ip_addr_compare))) 337 { 338#if HAVE_MESSAGES 339 MHD_DLOG (daemon, 340 "Failed to add IP connection count node\n"); 341#endif 342 MHD_ip_count_unlock (daemon); 343 free (key); 344 return MHD_NO; 345 } 346 node = *nodep; 347 /* If we got an existing node back, free the one we created */ 348 if (node != key) 349 free(key); 350 key = (struct MHD_IPCount *) node; 351 /* Test if there is room for another connection; if so, 352 * increment count */ 353 result = (key->count < daemon->per_ip_connection_limit); 354 if (MHD_YES == result) 355 ++key->count; 356 357 MHD_ip_count_unlock (daemon); 358 return result; 359} 360 361 362/** 363 * Decrement connection count for IP address, removing from table 364 * count reaches 0. 365 * 366 * @param daemon handle to daemon where connection counts are tracked 367 * @param addr address to remove (or decrement counter) 368 * @param addrlen number of bytes in @a addr 369 */ 370static void 371MHD_ip_limit_del (struct MHD_Daemon *daemon, 372 const struct sockaddr *addr, 373 socklen_t addrlen) 374{ 375 struct MHD_IPCount search_key; 376 struct MHD_IPCount *found_key; 377 void **nodep; 378 379 daemon = MHD_get_master (daemon); 380 /* Ignore if no connection limit assigned */ 381 if (0 == daemon->per_ip_connection_limit) 382 return; 383 /* Initialize search key */ 384 if (MHD_NO == MHD_ip_addr_to_key (addr, addrlen, &search_key)) 385 return; 386 387 MHD_ip_count_lock (daemon); 388 389 /* Search for the IP address */ 390 if (NULL == (nodep = tfind (&search_key, 391 &daemon->per_ip_connection_count, 392 &MHD_ip_addr_compare))) 393 { 394 /* Something's wrong if we couldn't find an IP address 395 * that was previously added */ 396 MHD_PANIC ("Failed to find previously-added IP address\n"); 397 } 398 found_key = (struct MHD_IPCount *) *nodep; 399 /* Validate existing count for IP address */ 400 if (0 == found_key->count) 401 { 402 MHD_PANIC ("Previously-added IP address had 0 count\n"); 403 } 404 /* Remove the node entirely if count reduces to 0 */ 405 if (0 == --found_key->count) 406 { 407 tdelete (found_key, 408 &daemon->per_ip_connection_count, 409 &MHD_ip_addr_compare); 410 free (found_key); 411 } 412 413 MHD_ip_count_unlock (daemon); 414} 415 416 417#if HTTPS_SUPPORT 418 419static ssize_t 420recv_param_adapter (struct MHD_Connection *connection, 421 void *other, 422 size_t i); 423static ssize_t 424send_param_adapter (struct MHD_Connection *connection, 425 const void *other, 426 size_t i); 427 428// Internal functions for implementing OpenSSL BIO. 429static int 430MHD_bio_write (BIO* bio, const char* buf, int size) 431{ 432 struct MHD_Connection* connection = (struct MHD_Connection*)bio->ptr; 433 BIO_clear_retry_flags (bio); 434 ssize_t written = send_param_adapter (connection, buf, size); 435 if (written < size) 436 { 437 BIO_set_retry_write (bio); 438 } 439 return written; 440} 441 442static int 443MHD_bio_read (BIO* bio, char* buf, int size) 444{ 445 struct MHD_Connection* connection = (struct MHD_Connection*)bio->ptr; 446 BIO_clear_retry_flags (bio); 447 ssize_t read = recv_param_adapter (connection, buf, size); 448 if (read < size) 449 { 450 BIO_set_retry_read (bio); 451 } 452 return read; 453} 454 455static long 456MHD_bio_ctrl (BIO* bio, int cmd, long num, void* ptr) 457{ 458 if (cmd == BIO_CTRL_FLUSH) 459 { 460 return 1; 461 } 462 return 0; 463} 464 465static int 466MHD_bio_new (BIO* bio) 467{ 468 bio->shutdown = 0; 469 bio->init = 0; 470 bio->num = -1; // not used. 471 return 1; 472} 473 474static int 475MHD_bio_free (BIO* bio) 476{ 477 if (!bio) 478 return 0; 479 480 if (bio->init) 481 { 482 bio->ptr = NULL; 483 bio->init = 0; 484 } 485 return 1; 486} 487 488// Describes a BIO built on [send|recv]_param_adapter(). 489BIO_METHOD MHD_bio_method = 490{ 491 BIO_TYPE_SOURCE_SINK, 492 "mhd", // name 493 MHD_bio_write, // write function 494 MHD_bio_read, // read function 495 NULL, // puts function, not implemented 496 NULL, // gets function, not implemented 497 MHD_bio_ctrl, // control function 498 MHD_bio_new, // creation 499 MHD_bio_free, // free 500 NULL, // callback function, not used 501}; 502 503 504/** 505 * Callback for receiving data from the socket. 506 * 507 * @param connection the MHD_Connection structure 508 * @param other where to write received data to 509 * @param i maximum size of other (in bytes) 510 * @return number of bytes actually received 511 */ 512static ssize_t 513recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i) 514{ 515 int res; 516 517 if (MHD_YES == connection->tls_read_ready) 518 { 519 connection->daemon->num_tls_read_ready--; 520 connection->tls_read_ready = MHD_NO; 521 } 522 res = SSL_read (connection->tls_session, other, i); 523 if ( res < 0 && SSL_want_read (connection->tls_session) ) 524 { 525 MHD_set_socket_errno_ (EINTR); 526#if EPOLL_SUPPORT 527 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; 528#endif 529 return -1; 530 } 531 if (res < 0) 532 { 533 /* Likely 'GNUTLS_E_INVALID_SESSION' (client communication 534 disrupted); set errno to something caller will interpret 535 correctly as a hard error */ 536 MHD_set_socket_errno_ (ECONNRESET); 537 return res; 538 } 539 if (res == i) 540 { 541 connection->tls_read_ready = MHD_YES; 542 connection->daemon->num_tls_read_ready++; 543 } 544 return res; 545} 546 547 548/** 549 * Callback for writing data to the socket. 550 * 551 * @param connection the MHD connection structure 552 * @param other data to write 553 * @param i number of bytes to write 554 * @return actual number of bytes written 555 */ 556static ssize_t 557send_tls_adapter (struct MHD_Connection *connection, 558 const void *other, size_t i) 559{ 560 int res; 561 562 res = SSL_write (connection->tls_session, other, i); 563 if ( res < 0 && SSL_want_write (connection->tls_session) ) 564 { 565 MHD_set_socket_errno_ (EINTR); 566#if EPOLL_SUPPORT 567 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; 568#endif 569 return -1; 570 } 571 if (res < 0) 572 { 573 /* some other GNUTLS error, should set 'errno'; as we do not 574 really understand the error (not listed in GnuTLS 575 documentation explicitly), we set 'errno' to something that 576 will cause the connection to fail. */ 577 MHD_set_socket_errno_ (ECONNRESET); 578 return -1; 579 } 580 return res; 581} 582 583 584/** 585 * Initialize security aspects of the HTTPS daemon 586 * 587 * @param daemon handle to daemon to initialize 588 * @return 0 on success 589 */ 590static int 591MHD_TLS_init (struct MHD_Daemon *daemon) 592{ 593 int ret; 594 daemon->tls_context = SSL_CTX_new (TLSv1_2_server_method()); 595 if (NULL == daemon->tls_context) 596 return -1; 597 if (NULL != daemon->https_mem_trust) 598 { 599 ret = 0; 600 BIO* mem_bio = BIO_new_mem_buf ((void*)daemon->https_mem_trust, -1); 601 X509* x509 = PEM_read_bio_X509 (mem_bio, NULL, NULL, NULL); 602 BIO_free(mem_bio); 603 if (x509 != NULL) 604 { 605 ret = SSL_CTX_add_client_CA (daemon->tls_context, x509); 606 } 607 if (ret == 0) 608 { 609#if HAVE_MESSAGES 610 MHD_DLOG (daemon, 611 "Bad trust certificate format\n"); 612#endif 613 return -1; 614 } 615 } 616 617 if (NULL != daemon->https_mem_dhparams) 618 { 619 ret = 0; 620 BIO* mem_bio = BIO_new_mem_buf ((void*)daemon->https_mem_dhparams, -1); 621 DH* dh = PEM_read_bio_DHparams (mem_bio, NULL, NULL, NULL); 622 BIO_free (mem_bio); 623 if (dh != NULL) 624 { 625 ret = SSL_CTX_set_tmp_dh (daemon->tls_context, dh); 626 } 627 if (ret == 0) 628 { 629#if HAVE_MESSAGES 630 MHD_DLOG (daemon, 631 "Bad DH parameters format\n"); 632#endif 633 return -1; 634 } 635 } 636 637 /* certificate & key loaded from memory */ 638 if ( (NULL != daemon->https_mem_cert) && 639 (NULL != daemon->https_mem_key) ) 640 { 641 ret = 0; 642 BIO* mem_bio = BIO_new_mem_buf ((void*)daemon->https_mem_key, -1); 643 EVP_PKEY* key = PEM_read_bio_PrivateKey (mem_bio, NULL, NULL, 644 (void*)daemon->https_key_password); 645 BIO_free (mem_bio); 646 if (key != NULL) 647 { 648 ret = SSL_CTX_use_PrivateKey (daemon->tls_context, key); 649 } 650 if (ret == 0) 651 { 652#if HAVE_MESSAGES 653 MHD_DLOG (daemon, 654 "Bad private key format\n"); 655#endif 656 return -1; 657 } 658 ret = 0; 659 mem_bio = BIO_new_mem_buf ((void*)daemon->https_mem_cert, -1); 660 X509* x509 = PEM_read_bio_X509 (mem_bio, NULL, NULL, NULL); 661 BIO_free (mem_bio); 662 if (x509 != NULL) 663 { 664 ret = SSL_CTX_use_certificate (daemon->tls_context, x509); 665 } 666 if (ret == 0) 667 { 668#if HAVE_MESSAGES 669 MHD_DLOG (daemon, 670 "Bad certificate format\n"); 671#endif 672 return -1; 673 } 674 if (1 != SSL_CTX_check_private_key (daemon->tls_context)) 675 { 676#if HAVE_MESSAGES 677 MHD_DLOG (daemon, 678 "Invalid key / certificate combination\n"); 679#endif 680 return -1; 681 } 682 } 683 else 684 { 685#if HAVE_MESSAGES 686 MHD_DLOG (daemon, 687 "You need to specify a certificate and key location\n"); 688#endif 689 return -1; 690 } 691 if (NULL != daemon->https_mem_cipher) 692 { 693 ret = SSL_CTX_set_cipher_list (daemon->tls_context, 694 daemon->https_mem_cipher); 695 if (ret == 0) 696 { 697#if HAVE_MESSAGES 698 MHD_DLOG (daemon, 699 "Bad cipher string format\n"); 700#endif 701 return -1; 702 } 703 } 704 else 705 { 706 ret = SSL_CTX_set_cipher_list (daemon->tls_context, 707 "HIGH!SHA1!DH@STRENGTH"); 708 if (ret == 0) 709 { 710#if HAVE_MESSAGES 711 MHD_DLOG (daemon, 712 "Failed to setup default cipher string\n"); 713#endif 714 return -1; 715 } 716 } 717 return 0; 718} 719 720static void 721MHD_TLS_deinit (struct MHD_Daemon *daemon) 722{ 723 SSL_CTX_free (daemon->tls_context); 724} 725#endif 726 727 728/** 729 * Add @a fd to the @a set. If @a fd is 730 * greater than @a max_fd, set @a max_fd to @a fd. 731 * 732 * @param fd file descriptor to add to the @a set 733 * @param set set to modify 734 * @param max_fd maximum value to potentially update 735 * @param fd_setsize value of FD_SETSIZE 736 * @return #MHD_YES on success, #MHD_NO otherwise 737 */ 738static int 739add_to_fd_set (MHD_socket fd, 740 fd_set *set, 741 MHD_socket *max_fd, 742 unsigned int fd_setsize) 743{ 744 if (NULL == set) 745 return MHD_NO; 746#ifdef MHD_WINSOCK_SOCKETS 747 if (set->fd_count >= fd_setsize) 748 { 749 if (FD_ISSET(fd, set)) 750 return MHD_YES; 751 else 752 return MHD_NO; 753 } 754#else // ! MHD_WINSOCK_SOCKETS 755 if (fd >= fd_setsize) 756 return MHD_NO; 757#endif // ! MHD_WINSOCK_SOCKETS 758 FD_SET (fd, set); 759 if ( (NULL != max_fd) && (MHD_INVALID_SOCKET != fd) && 760 ((fd > *max_fd) || (MHD_INVALID_SOCKET == *max_fd)) ) 761 *max_fd = fd; 762 763 return MHD_YES; 764} 765 766#undef MHD_get_fdset 767 768/** 769 * Obtain the `select()` sets for this daemon. 770 * Daemon's FDs will be added to fd_sets. To get only 771 * daemon FDs in fd_sets, call FD_ZERO for each fd_set 772 * before calling this function. FD_SETSIZE is assumed 773 * to be platform's default. 774 * 775 * @param daemon daemon to get sets from 776 * @param read_fd_set read set 777 * @param write_fd_set write set 778 * @param except_fd_set except set 779 * @param max_fd increased to largest FD added (if larger 780 * than existing value); can be NULL 781 * @return #MHD_YES on success, #MHD_NO if this 782 * daemon was not started with the right 783 * options for this call or any FD didn't 784 * fit fd_set. 785 * @ingroup event 786 */ 787int 788MHD_get_fdset (struct MHD_Daemon *daemon, 789 fd_set *read_fd_set, 790 fd_set *write_fd_set, 791 fd_set *except_fd_set, 792 MHD_socket *max_fd) 793{ 794 return MHD_get_fdset2(daemon, read_fd_set, 795 write_fd_set, except_fd_set, 796 max_fd, MHD_DEFAULT_FD_SETSIZE); 797} 798 799/** 800 * Obtain the `select()` sets for this daemon. 801 * Daemon's FDs will be added to fd_sets. To get only 802 * daemon FDs in fd_sets, call FD_ZERO for each fd_set 803 * before calling this function. Passing custom FD_SETSIZE 804 * as @a fd_setsize allow usage of larger/smaller than 805 * platform's default fd_sets. 806 * 807 * @param daemon daemon to get sets from 808 * @param read_fd_set read set 809 * @param write_fd_set write set 810 * @param except_fd_set except set 811 * @param max_fd increased to largest FD added (if larger 812 * than existing value); can be NULL 813 * @param fd_setsize value of FD_SETSIZE 814 * @return #MHD_YES on success, #MHD_NO if this 815 * daemon was not started with the right 816 * options for this call or any FD didn't 817 * fit fd_set. 818 * @ingroup event 819 */ 820int 821MHD_get_fdset2 (struct MHD_Daemon *daemon, 822 fd_set *read_fd_set, 823 fd_set *write_fd_set, 824 fd_set *except_fd_set, 825 MHD_socket *max_fd, 826 unsigned int fd_setsize) 827{ 828 struct MHD_Connection *pos; 829 830 if ( (NULL == daemon) 831 || (NULL == read_fd_set) 832 || (NULL == write_fd_set) 833 || (MHD_YES == daemon->shutdown) 834 || (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 835 || (0 != (daemon->options & MHD_USE_POLL))) 836 return MHD_NO; 837#if EPOLL_SUPPORT 838 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) 839 { 840 /* we're in epoll mode, use the epoll FD as a stand-in for 841 the entire event set */ 842 843 return add_to_fd_set (daemon->epoll_fd, read_fd_set, max_fd, fd_setsize); 844 } 845#endif 846 if (MHD_INVALID_SOCKET != daemon->socket_fd && 847 MHD_YES != add_to_fd_set (daemon->socket_fd, read_fd_set, max_fd, fd_setsize)) 848 return MHD_NO; 849 850 for (pos = daemon->connections_head; NULL != pos; pos = pos->next) 851 { 852 switch (pos->event_loop_info) 853 { 854 case MHD_EVENT_LOOP_INFO_READ: 855 if (MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd, fd_setsize)) 856 return MHD_NO; 857 break; 858 case MHD_EVENT_LOOP_INFO_WRITE: 859 if (MHD_YES != add_to_fd_set (pos->socket_fd, write_fd_set, max_fd, fd_setsize)) 860 return MHD_NO; 861 if (pos->read_buffer_size > pos->read_buffer_offset && 862 MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd, fd_setsize)) 863 return MHD_NO; 864 break; 865 case MHD_EVENT_LOOP_INFO_BLOCK: 866 if (pos->read_buffer_size > pos->read_buffer_offset && 867 MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd, fd_setsize)) 868 return MHD_NO; 869 break; 870 case MHD_EVENT_LOOP_INFO_CLEANUP: 871 /* this should never happen */ 872 break; 873 } 874 } 875#if DEBUG_CONNECT 876#if HAVE_MESSAGES 877 if (NULL != max_fd) 878 MHD_DLOG (daemon, 879 "Maximum socket in select set: %d\n", 880 *max_fd); 881#endif 882#endif 883 return MHD_YES; 884} 885 886 887/** 888 * Main function of the thread that handles an individual 889 * connection when #MHD_USE_THREAD_PER_CONNECTION is set. 890 * 891 * @param data the `struct MHD_Connection` this thread will handle 892 * @return always 0 893 */ 894static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ 895MHD_handle_connection (void *data) 896{ 897 struct MHD_Connection *con = data; 898 int num_ready; 899 fd_set rs; 900 fd_set ws; 901 MHD_socket max; 902 struct timeval tv; 903 struct timeval *tvp; 904 unsigned int timeout; 905 time_t now; 906#if WINDOWS 907 MHD_pipe spipe = con->daemon->wpipe[0]; 908 char tmp; 909#ifdef HAVE_POLL 910 int extra_slot; 911#endif /* HAVE_POLL */ 912#define EXTRA_SLOTS 1 913#else /* !WINDOWS */ 914#define EXTRA_SLOTS 0 915#endif /* !WINDOWS */ 916#ifdef HAVE_POLL 917 struct pollfd p[1 + EXTRA_SLOTS]; 918#endif 919 920 timeout = con->daemon->connection_timeout; 921 while ( (MHD_YES != con->daemon->shutdown) && 922 (MHD_CONNECTION_CLOSED != con->state) ) 923 { 924 tvp = NULL; 925 if (timeout > 0) 926 { 927 now = MHD_monotonic_time(); 928 if (now - con->last_activity > timeout) 929 tv.tv_sec = 0; 930 else 931 tv.tv_sec = timeout - (now - con->last_activity); 932 tv.tv_usec = 0; 933 tvp = &tv; 934 } 935#if HTTPS_SUPPORT 936 if (MHD_YES == con->tls_read_ready) 937 { 938 /* do not block (more data may be inside of TLS buffers waiting for us) */ 939 tv.tv_sec = 0; 940 tv.tv_usec = 0; 941 tvp = &tv; 942 } 943#endif 944 if (0 == (con->daemon->options & MHD_USE_POLL)) 945 { 946 /* use select */ 947 int err_state = 0; 948 FD_ZERO (&rs); 949 FD_ZERO (&ws); 950 max = 0; 951 switch (con->event_loop_info) 952 { 953 case MHD_EVENT_LOOP_INFO_READ: 954 if (MHD_YES != 955 add_to_fd_set (con->socket_fd, &rs, &max, FD_SETSIZE)) 956 err_state = 1; 957 break; 958 case MHD_EVENT_LOOP_INFO_WRITE: 959 if (MHD_YES != 960 add_to_fd_set (con->socket_fd, &ws, &max, FD_SETSIZE)) 961 err_state = 1; 962 if ( (con->read_buffer_size > con->read_buffer_offset) && 963 (MHD_YES != 964 add_to_fd_set (con->socket_fd, &rs, &max, FD_SETSIZE)) ) 965 err_state = 1; 966 break; 967 case MHD_EVENT_LOOP_INFO_BLOCK: 968 if ( (con->read_buffer_size > con->read_buffer_offset) && 969 (MHD_YES != 970 add_to_fd_set (con->socket_fd, &rs, &max, FD_SETSIZE)) ) 971 err_state = 1; 972 tv.tv_sec = 0; 973 tv.tv_usec = 0; 974 tvp = &tv; 975 break; 976 case MHD_EVENT_LOOP_INFO_CLEANUP: 977 /* how did we get here!? */ 978 goto exit; 979 } 980#if WINDOWS 981 if (MHD_INVALID_PIPE_ != spipe) 982 { 983 if (MHD_YES != 984 add_to_fd_set (spipe, &rs, &max, FD_SETSIZE)) 985 err_state = 1; 986 } 987#endif 988 if (0 != err_state) 989 { 990#if HAVE_MESSAGES 991 MHD_DLOG (con->daemon, 992 "Can't add FD to fd_set\n"); 993#endif 994 goto exit; 995 } 996 997 num_ready = MHD_SYS_select_ (max + 1, &rs, &ws, NULL, tvp); 998 if (num_ready < 0) 999 { 1000 if (EINTR == MHD_socket_errno_) 1001 continue; 1002#if HAVE_MESSAGES 1003 MHD_DLOG (con->daemon, 1004 "Error during select (%d): `%s'\n", 1005 MHD_socket_errno_, 1006 MHD_socket_last_strerr_ ()); 1007#endif 1008 break; 1009 } 1010#if WINDOWS 1011 /* drain signaling pipe */ 1012 if ( (MHD_INVALID_PIPE_ != spipe) && 1013 (FD_ISSET (spipe, &rs)) ) 1014 (void) MHD_pipe_read_ (spipe, &tmp, sizeof (tmp)); 1015#endif 1016 /* call appropriate connection handler if necessary */ 1017 if ( (FD_ISSET (con->socket_fd, &rs)) 1018#if HTTPS_SUPPORT 1019 || (MHD_YES == con->tls_read_ready) 1020#endif 1021 ) 1022 con->read_handler (con); 1023 if (FD_ISSET (con->socket_fd, &ws)) 1024 con->write_handler (con); 1025 if (MHD_NO == con->idle_handler (con)) 1026 goto exit; 1027 } 1028#ifdef HAVE_POLL 1029 else 1030 { 1031 /* use poll */ 1032 memset (&p, 0, sizeof (p)); 1033 p[0].fd = con->socket_fd; 1034 switch (con->event_loop_info) 1035 { 1036 case MHD_EVENT_LOOP_INFO_READ: 1037 p[0].events |= POLLIN; 1038 break; 1039 case MHD_EVENT_LOOP_INFO_WRITE: 1040 p[0].events |= POLLOUT; 1041 if (con->read_buffer_size > con->read_buffer_offset) 1042 p[0].events |= POLLIN; 1043 break; 1044 case MHD_EVENT_LOOP_INFO_BLOCK: 1045 if (con->read_buffer_size > con->read_buffer_offset) 1046 p[0].events |= POLLIN; 1047 tv.tv_sec = 0; 1048 tv.tv_usec = 0; 1049 tvp = &tv; 1050 break; 1051 case MHD_EVENT_LOOP_INFO_CLEANUP: 1052 /* how did we get here!? */ 1053 goto exit; 1054 } 1055#if WINDOWS 1056 extra_slot = 0; 1057 if (MHD_INVALID_PIPE_ != spipe) 1058 { 1059 p[1].events |= POLLIN; 1060 p[1].fd = spipe; 1061 p[1].revents = 0; 1062 extra_slot = 1; 1063 } 1064#endif 1065 if (MHD_sys_poll_ (p, 1066#if WINDOWS 1067 1 + extra_slot, 1068#else 1069 1, 1070#endif 1071 (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0) 1072 { 1073 if (EINTR == MHD_socket_errno_) 1074 continue; 1075#if HAVE_MESSAGES 1076 MHD_DLOG (con->daemon, 1077 "Error during poll: `%s'\n", 1078 MHD_socket_last_strerr_ ()); 1079#endif 1080 break; 1081 } 1082#if WINDOWS 1083 /* drain signaling pipe */ 1084 if ( (MHD_INVALID_PIPE_ != spipe) && 1085 (0 != (p[1].revents & (POLLERR | POLLHUP))) ) 1086 (void) MHD_pipe_read_ (spipe, &tmp, sizeof (tmp)); 1087#endif 1088 if ( (0 != (p[0].revents & POLLIN)) 1089#if HTTPS_SUPPORT 1090 || (MHD_YES == con->tls_read_ready) 1091#endif 1092 ) 1093 con->read_handler (con); 1094 if (0 != (p[0].revents & POLLOUT)) 1095 con->write_handler (con); 1096 if (0 != (p[0].revents & (POLLERR | POLLHUP))) 1097 MHD_connection_close (con, MHD_REQUEST_TERMINATED_WITH_ERROR); 1098 if (MHD_NO == con->idle_handler (con)) 1099 goto exit; 1100 } 1101#endif 1102 } 1103 if (MHD_CONNECTION_IN_CLEANUP != con->state) 1104 { 1105#if DEBUG_CLOSE 1106#if HAVE_MESSAGES 1107 MHD_DLOG (con->daemon, 1108 "Processing thread terminating, closing connection\n"); 1109#endif 1110#endif 1111 if (MHD_CONNECTION_CLOSED != con->state) 1112 MHD_connection_close (con, 1113 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN); 1114 con->idle_handler (con); 1115 } 1116exit: 1117 if (NULL != con->response) 1118 { 1119 MHD_destroy_response (con->response); 1120 con->response = NULL; 1121 } 1122 1123 if (NULL != con->daemon->notify_connection) 1124 con->daemon->notify_connection (con->daemon->notify_connection_cls, 1125 con, 1126 &con->socket_context, 1127 MHD_CONNECTION_NOTIFY_CLOSED); 1128 1129 return (MHD_THRD_RTRN_TYPE_)0; 1130} 1131 1132 1133/** 1134 * Callback for receiving data from the socket. 1135 * 1136 * @param connection the MHD connection structure 1137 * @param other where to write received data to 1138 * @param i maximum size of other (in bytes) 1139 * @return number of bytes actually received 1140 */ 1141static ssize_t 1142recv_param_adapter (struct MHD_Connection *connection, 1143 void *other, 1144 size_t i) 1145{ 1146 ssize_t ret; 1147 1148 if ( (MHD_INVALID_SOCKET == connection->socket_fd) || 1149 (MHD_CONNECTION_CLOSED == connection->state) ) 1150 { 1151 MHD_set_socket_errno_ (ENOTCONN); 1152 return -1; 1153 } 1154 ret = recv (connection->socket_fd, other, i, MSG_NOSIGNAL); 1155#if EPOLL_SUPPORT 1156 if (ret < (ssize_t) i) 1157 { 1158 /* partial read --- no longer read-ready */ 1159 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; 1160 } 1161#endif 1162 return ret; 1163} 1164 1165 1166/** 1167 * Callback for writing data to the socket. 1168 * 1169 * @param connection the MHD connection structure 1170 * @param other data to write 1171 * @param i number of bytes to write 1172 * @return actual number of bytes written 1173 */ 1174static ssize_t 1175send_param_adapter (struct MHD_Connection *connection, 1176 const void *other, 1177 size_t i) 1178{ 1179 ssize_t ret; 1180#if LINUX 1181 MHD_socket fd; 1182 off_t offset; 1183 off_t left; 1184#endif 1185 1186 if ( (MHD_INVALID_SOCKET == connection->socket_fd) || 1187 (MHD_CONNECTION_CLOSED == connection->state) ) 1188 { 1189 MHD_set_socket_errno_ (ENOTCONN); 1190 return -1; 1191 } 1192 if (0 != (connection->daemon->options & MHD_USE_SSL)) 1193 return send (connection->socket_fd, other, i, MSG_NOSIGNAL); 1194#if LINUX 1195 if ( (connection->write_buffer_append_offset == 1196 connection->write_buffer_send_offset) && 1197 (NULL != connection->response) && 1198 (MHD_INVALID_SOCKET != (fd = connection->response->fd)) ) 1199 { 1200 /* can use sendfile */ 1201 offset = (off_t) connection->response_write_position + connection->response->fd_off; 1202 left = connection->response->total_size - connection->response_write_position; 1203 if (left > SSIZE_MAX) 1204 left = SSIZE_MAX; /* cap at return value limit */ 1205 if (-1 != (ret = sendfile (connection->socket_fd, 1206 fd, 1207 &offset, 1208 (size_t) left))) 1209 { 1210#if EPOLL_SUPPORT 1211 if (ret < left) 1212 { 1213 /* partial write --- no longer write-ready */ 1214 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; 1215 } 1216#endif 1217 return ret; 1218 } 1219 const int err = MHD_socket_errno_; 1220 if ( (EINTR == err) || (EAGAIN == err) || (EWOULDBLOCK == err) ) 1221 return 0; 1222 if ( (EINVAL == err) || (EBADF == err) ) 1223 return -1; 1224 /* None of the 'usual' sendfile errors occurred, so we should try 1225 to fall back to 'SEND'; see also this thread for info on 1226 odd libc/Linux behavior with sendfile: 1227 http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */ 1228 } 1229#endif 1230 ret = send (connection->socket_fd, other, i, MSG_NOSIGNAL); 1231#if EPOLL_SUPPORT 1232 if (ret < (ssize_t) i) 1233 { 1234 /* partial write --- no longer write-ready */ 1235 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; 1236 } 1237#endif 1238 /* Handle broken kernel / libc, returning -1 but not setting errno; 1239 kill connection as that should be safe; reported on mailinglist here: 1240 http://lists.gnu.org/archive/html/libmicrohttpd/2014-10/msg00023.html */ 1241 if ( (-1 == ret) && (0 == errno) ) 1242 errno = ECONNRESET; 1243 return ret; 1244} 1245 1246 1247/** 1248 * Signature of main function for a thread. 1249 * 1250 * @param cls closure argument for the function 1251 * @return termination code from the thread 1252 */ 1253typedef MHD_THRD_RTRN_TYPE_ (MHD_THRD_CALL_SPEC_ *ThreadStartRoutine)(void *cls); 1254 1255 1256/** 1257 * Create a thread and set the attributes according to our options. 1258 * 1259 * @param thread handle to initialize 1260 * @param daemon daemon with options 1261 * @param start_routine main function of thread 1262 * @param arg argument for start_routine 1263 * @return 0 on success 1264 */ 1265static int 1266create_thread (MHD_thread_handle_ *thread, 1267 const struct MHD_Daemon *daemon, 1268 ThreadStartRoutine start_routine, 1269 void *arg) 1270{ 1271#if defined(MHD_USE_POSIX_THREADS) 1272 pthread_attr_t attr; 1273 pthread_attr_t *pattr; 1274 int ret; 1275 1276 if (0 != daemon->thread_stack_size) 1277 { 1278 if (0 != (ret = pthread_attr_init (&attr))) 1279 goto ERR; 1280 if (0 != (ret = pthread_attr_setstacksize (&attr, daemon->thread_stack_size))) 1281 { 1282 pthread_attr_destroy (&attr); 1283 goto ERR; 1284 } 1285 pattr = &attr; 1286 } 1287 else 1288 { 1289 pattr = NULL; 1290 } 1291 ret = pthread_create (thread, pattr, 1292 start_routine, arg); 1293#ifdef HAVE_PTHREAD_SETNAME_NP 1294 (void) pthread_setname_np (*thread, "libmicrohttpd"); 1295#endif /* HAVE_PTHREAD_SETNAME_NP */ 1296 if (0 != daemon->thread_stack_size) 1297 pthread_attr_destroy (&attr); 1298 return ret; 1299 ERR: 1300#if HAVE_MESSAGES 1301 MHD_DLOG (daemon, 1302 "Failed to set thread stack size\n"); 1303#endif 1304 errno = EINVAL; 1305 return ret; 1306#elif defined(MHD_USE_W32_THREADS) 1307 unsigned threadID; 1308 *thread = (HANDLE)_beginthreadex(NULL, (unsigned)daemon->thread_stack_size, start_routine, 1309 arg, 0, &threadID); 1310 if (NULL == (*thread)) 1311 return errno; 1312 1313 W32_SetThreadName(threadID, "libmicrohttpd"); 1314 1315 return 0; 1316#endif 1317} 1318 1319 1320/** 1321 * Add another client connection to the set of connections 1322 * managed by MHD. This API is usually not needed (since 1323 * MHD will accept inbound connections on the server socket). 1324 * Use this API in special cases, for example if your HTTP 1325 * server is behind NAT and needs to connect out to the 1326 * HTTP client. 1327 * 1328 * The given client socket will be managed (and closed!) by MHD after 1329 * this call and must no longer be used directly by the application 1330 * afterwards. 1331 * 1332 * Per-IP connection limits are ignored when using this API. 1333 * 1334 * @param daemon daemon that manages the connection 1335 * @param client_socket socket to manage (MHD will expect 1336 * to receive an HTTP request from this socket next). 1337 * @param addr IP address of the client 1338 * @param addrlen number of bytes in @a addr 1339 * @param external_add perform additional operations needed due 1340 * to the application calling us directly 1341 * @return #MHD_YES on success, #MHD_NO if this daemon could 1342 * not handle the connection (i.e. malloc failed, etc). 1343 * The socket will be closed in any case; 'errno' is 1344 * set to indicate further details about the error. 1345 */ 1346static int 1347internal_add_connection (struct MHD_Daemon *daemon, 1348 MHD_socket client_socket, 1349 const struct sockaddr *addr, 1350 socklen_t addrlen, 1351 int external_add) 1352{ 1353 struct MHD_Connection *connection; 1354 int res_thread_create; 1355 unsigned int i; 1356 int eno; 1357 struct MHD_Daemon *worker; 1358#if OSX 1359 static int on = 1; 1360#endif 1361 1362 if (NULL != daemon->worker_pool) 1363 { 1364 /* have a pool, try to find a pool with capacity; we use the 1365 socket as the initial offset into the pool for load 1366 balancing */ 1367 for (i=0;i<daemon->worker_pool_size;i++) 1368 { 1369 worker = &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size]; 1370 if (worker->connections < worker->connection_limit) 1371 return internal_add_connection (worker, 1372 client_socket, 1373 addr, addrlen, 1374 external_add); 1375 } 1376 /* all pools are at their connection limit, must refuse */ 1377 if (0 != MHD_socket_close_ (client_socket)) 1378 MHD_PANIC ("close failed\n"); 1379#if ENFILE 1380 errno = ENFILE; 1381#endif 1382 return MHD_NO; 1383 } 1384 1385#ifndef WINDOWS 1386 if ( (client_socket >= FD_SETSIZE) && 1387 (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY))) ) 1388 { 1389#if HAVE_MESSAGES 1390 MHD_DLOG (daemon, 1391 "Socket descriptor larger than FD_SETSIZE: %d > %d\n", 1392 client_socket, 1393 FD_SETSIZE); 1394#endif 1395 if (0 != MHD_socket_close_ (client_socket)) 1396 MHD_PANIC ("close failed\n"); 1397#if EINVAL 1398 errno = EINVAL; 1399#endif 1400 return MHD_NO; 1401 } 1402#endif 1403 1404 1405#if HAVE_MESSAGES 1406#if DEBUG_CONNECT 1407 MHD_DLOG (daemon, 1408 "Accepted connection on socket %d\n", 1409 client_socket); 1410#endif 1411#endif 1412 if ( (daemon->connections == daemon->connection_limit) || 1413 (MHD_NO == MHD_ip_limit_add (daemon, addr, addrlen)) ) 1414 { 1415 /* above connection limit - reject */ 1416#if HAVE_MESSAGES 1417 MHD_DLOG (daemon, 1418 "Server reached connection limit (closing inbound connection)\n"); 1419#endif 1420 if (0 != MHD_socket_close_ (client_socket)) 1421 MHD_PANIC ("close failed\n"); 1422#if ENFILE 1423 errno = ENFILE; 1424#endif 1425 return MHD_NO; 1426 } 1427 1428 /* apply connection acceptance policy if present */ 1429 if ( (NULL != daemon->apc) && 1430 (MHD_NO == daemon->apc (daemon->apc_cls, 1431 addr, addrlen)) ) 1432 { 1433#if DEBUG_CLOSE 1434#if HAVE_MESSAGES 1435 MHD_DLOG (daemon, 1436 "Connection rejected, closing connection\n"); 1437#endif 1438#endif 1439 if (0 != MHD_socket_close_ (client_socket)) 1440 MHD_PANIC ("close failed\n"); 1441 MHD_ip_limit_del (daemon, addr, addrlen); 1442#if EACCESS 1443 errno = EACCESS; 1444#endif 1445 return MHD_NO; 1446 } 1447 1448#if OSX 1449#ifdef SOL_SOCKET 1450#ifdef SO_NOSIGPIPE 1451 setsockopt (client_socket, 1452 SOL_SOCKET, SO_NOSIGPIPE, 1453 &on, sizeof (on)); 1454#endif 1455#endif 1456#endif 1457 1458 if (NULL == (connection = malloc (sizeof (struct MHD_Connection)))) 1459 { 1460 eno = errno; 1461#if HAVE_MESSAGES 1462 MHD_DLOG (daemon, 1463 "Error allocating memory: %s\n", 1464 MHD_strerror_ (errno)); 1465#endif 1466 if (0 != MHD_socket_close_ (client_socket)) 1467 MHD_PANIC ("close failed\n"); 1468 MHD_ip_limit_del (daemon, addr, addrlen); 1469 errno = eno; 1470 return MHD_NO; 1471 } 1472 memset (connection, 1473 0, 1474 sizeof (struct MHD_Connection)); 1475 connection->pool = MHD_pool_create (daemon->pool_size); 1476 if (NULL == connection->pool) 1477 { 1478#if HAVE_MESSAGES 1479 MHD_DLOG (daemon, 1480 "Error allocating memory: %s\n", 1481 MHD_strerror_ (errno)); 1482#endif 1483 if (0 != MHD_socket_close_ (client_socket)) 1484 MHD_PANIC ("close failed\n"); 1485 MHD_ip_limit_del (daemon, addr, addrlen); 1486 free (connection); 1487#if ENOMEM 1488 errno = ENOMEM; 1489#endif 1490 return MHD_NO; 1491 } 1492 1493 connection->connection_timeout = daemon->connection_timeout; 1494 if (NULL == (connection->addr = malloc (addrlen))) 1495 { 1496 eno = errno; 1497#if HAVE_MESSAGES 1498 MHD_DLOG (daemon, 1499 "Error allocating memory: %s\n", 1500 MHD_strerror_ (errno)); 1501#endif 1502 if (0 != MHD_socket_close_ (client_socket)) 1503 MHD_PANIC ("close failed\n"); 1504 MHD_ip_limit_del (daemon, addr, addrlen); 1505 MHD_pool_destroy (connection->pool); 1506 free (connection); 1507 errno = eno; 1508 return MHD_NO; 1509 } 1510 memcpy (connection->addr, addr, addrlen); 1511 connection->addr_len = addrlen; 1512 connection->socket_fd = client_socket; 1513 connection->daemon = daemon; 1514 connection->last_activity = MHD_monotonic_time(); 1515 1516 /* set default connection handlers */ 1517 MHD_set_http_callbacks_ (connection); 1518 connection->recv_cls = &recv_param_adapter; 1519 connection->send_cls = &send_param_adapter; 1520 1521 if (0 == (connection->daemon->options & MHD_USE_EPOLL_TURBO)) 1522 { 1523 /* non-blocking sockets are required on most systems and for GNUtls; 1524 however, they somehow cause serious problems on CYGWIN (#1824); 1525 in turbo mode, we assume that non-blocking was already set 1526 by 'accept4' or whoever calls 'MHD_add_connection' */ 1527#ifdef CYGWIN 1528 if (0 != (daemon->options & MHD_USE_SSL)) 1529#endif 1530 { 1531 /* make socket non-blocking */ 1532#if !defined(WINDOWS) || defined(CYGWIN) 1533 int flags = fcntl (connection->socket_fd, F_GETFL); 1534 if ( (-1 == flags) || 1535 (0 != fcntl (connection->socket_fd, F_SETFL, flags | O_NONBLOCK)) ) 1536 { 1537#if HAVE_MESSAGES 1538 MHD_DLOG (daemon, 1539 "Failed to make socket non-blocking: %s\n", 1540 MHD_socket_last_strerr_ ()); 1541#endif 1542 } 1543#else 1544 unsigned long flags = 1; 1545 if (0 != ioctlsocket (connection->socket_fd, FIONBIO, &flags)) 1546 { 1547#if HAVE_MESSAGES 1548 MHD_DLOG (daemon, 1549 "Failed to make socket non-blocking: %s\n", 1550 MHD_socket_last_strerr_ ()); 1551#endif 1552 } 1553#endif 1554 } 1555 } 1556 1557#if HTTPS_SUPPORT 1558 if (0 != (daemon->options & MHD_USE_SSL)) 1559 { 1560 connection->recv_cls = &recv_tls_adapter; 1561 connection->send_cls = &send_tls_adapter; 1562 connection->state = MHD_TLS_CONNECTION_INIT; 1563 MHD_set_https_callbacks (connection); 1564 connection->tls_session = SSL_new (daemon->tls_context); 1565 BIO* bio = BIO_new (&MHD_bio_method); 1566 if (bio) 1567 { 1568 bio->ptr = connection; 1569 bio->init = 1; 1570 } 1571 SSL_set_bio (connection->tls_session, bio, bio); 1572 SSL_set_app_data (connection->tls_session, connection); 1573 } 1574#endif 1575 1576 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 1577 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) ) 1578 MHD_PANIC ("Failed to acquire cleanup mutex\n"); 1579 XDLL_insert (daemon->normal_timeout_head, 1580 daemon->normal_timeout_tail, 1581 connection); 1582 DLL_insert (daemon->connections_head, 1583 daemon->connections_tail, 1584 connection); 1585 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 1586 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) ) 1587 MHD_PANIC ("Failed to release cleanup mutex\n"); 1588 1589 if (NULL != daemon->notify_connection) 1590 daemon->notify_connection (daemon->notify_connection_cls, 1591 connection, 1592 &connection->socket_context, 1593 MHD_CONNECTION_NOTIFY_STARTED); 1594 1595 /* attempt to create handler thread */ 1596 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 1597 { 1598 res_thread_create = create_thread (&connection->pid, 1599 daemon, 1600 &MHD_handle_connection, 1601 connection); 1602 if (0 != res_thread_create) 1603 { 1604 eno = errno; 1605#if HAVE_MESSAGES 1606 MHD_DLOG (daemon, 1607 "Failed to create a thread: %s\n", 1608 MHD_strerror_ (res_thread_create)); 1609#endif 1610 goto cleanup; 1611 } 1612 } 1613 else 1614 if ( (MHD_YES == external_add) && 1615 (MHD_INVALID_PIPE_ != daemon->wpipe[1]) && 1616 (1 != MHD_pipe_write_ (daemon->wpipe[1], "n", 1)) ) 1617 { 1618#if HAVE_MESSAGES 1619 MHD_DLOG (daemon, 1620 "failed to signal new connection via pipe"); 1621#endif 1622 } 1623#if EPOLL_SUPPORT 1624 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) 1625 { 1626 if (0 == (daemon->options & MHD_USE_EPOLL_TURBO)) 1627 { 1628 struct epoll_event event; 1629 1630 event.events = EPOLLIN | EPOLLOUT | EPOLLET; 1631 event.data.ptr = connection; 1632 if (0 != epoll_ctl (daemon->epoll_fd, 1633 EPOLL_CTL_ADD, 1634 client_socket, 1635 &event)) 1636 { 1637 eno = errno; 1638#if HAVE_MESSAGES 1639 MHD_DLOG (daemon, 1640 "Call to epoll_ctl failed: %s\n", 1641 MHD_socket_last_strerr_ ()); 1642#endif 1643 goto cleanup; 1644 } 1645 connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET; 1646 } 1647 else 1648 { 1649 connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY 1650 | MHD_EPOLL_STATE_IN_EREADY_EDLL; 1651 EDLL_insert (daemon->eready_head, 1652 daemon->eready_tail, 1653 connection); 1654 } 1655 } 1656#endif 1657 daemon->connections++; 1658 return MHD_YES; 1659 cleanup: 1660 if (NULL != daemon->notify_connection) 1661 daemon->notify_connection (daemon->notify_connection_cls, 1662 connection, 1663 &connection->socket_context, 1664 MHD_CONNECTION_NOTIFY_CLOSED); 1665 if (0 != MHD_socket_close_ (client_socket)) 1666 MHD_PANIC ("close failed\n"); 1667 MHD_ip_limit_del (daemon, addr, addrlen); 1668 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 1669 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) ) 1670 MHD_PANIC ("Failed to acquire cleanup mutex\n"); 1671 DLL_remove (daemon->connections_head, 1672 daemon->connections_tail, 1673 connection); 1674 XDLL_remove (daemon->normal_timeout_head, 1675 daemon->normal_timeout_tail, 1676 connection); 1677 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 1678 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) ) 1679 MHD_PANIC ("Failed to release cleanup mutex\n"); 1680 MHD_pool_destroy (connection->pool); 1681 free (connection->addr); 1682 free (connection); 1683#if EINVAL 1684 errno = eno; 1685#endif 1686 return MHD_NO; 1687} 1688 1689 1690/** 1691 * Suspend handling of network data for a given connection. This can 1692 * be used to dequeue a connection from MHD's event loop (external 1693 * select, internal select or thread pool; not applicable to 1694 * thread-per-connection!) for a while. 1695 * 1696 * If you use this API in conjunction with a internal select or a 1697 * thread pool, you must set the option #MHD_USE_PIPE_FOR_SHUTDOWN to 1698 * ensure that a resumed connection is immediately processed by MHD. 1699 * 1700 * Suspended connections continue to count against the total number of 1701 * connections allowed (per daemon, as well as per IP, if such limits 1702 * are set). Suspended connections will NOT time out; timeouts will 1703 * restart when the connection handling is resumed. While a 1704 * connection is suspended, MHD will not detect disconnects by the 1705 * client. 1706 * 1707 * The only safe time to suspend a connection is from the 1708 * #MHD_AccessHandlerCallback. 1709 * 1710 * Finally, it is an API violation to call #MHD_stop_daemon while 1711 * having suspended connections (this will at least create memory and 1712 * socket leaks or lead to undefined behavior). You must explicitly 1713 * resume all connections before stopping the daemon. 1714 * 1715 * @param connection the connection to suspend 1716 */ 1717void 1718MHD_suspend_connection (struct MHD_Connection *connection) 1719{ 1720 struct MHD_Daemon *daemon; 1721 1722 daemon = connection->daemon; 1723 if (MHD_USE_SUSPEND_RESUME != (daemon->options & MHD_USE_SUSPEND_RESUME)) 1724 MHD_PANIC ("Cannot suspend connections without enabling MHD_USE_SUSPEND_RESUME!\n"); 1725 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 1726 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) ) 1727 MHD_PANIC ("Failed to acquire cleanup mutex\n"); 1728 DLL_remove (daemon->connections_head, 1729 daemon->connections_tail, 1730 connection); 1731 DLL_insert (daemon->suspended_connections_head, 1732 daemon->suspended_connections_tail, 1733 connection); 1734 if (connection->connection_timeout == daemon->connection_timeout) 1735 XDLL_remove (daemon->normal_timeout_head, 1736 daemon->normal_timeout_tail, 1737 connection); 1738 else 1739 XDLL_remove (daemon->manual_timeout_head, 1740 daemon->manual_timeout_tail, 1741 connection); 1742#if EPOLL_SUPPORT 1743 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) 1744 { 1745 if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) 1746 { 1747 EDLL_remove (daemon->eready_head, 1748 daemon->eready_tail, 1749 connection); 1750 connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; 1751 } 1752 if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) 1753 { 1754 if (0 != epoll_ctl (daemon->epoll_fd, 1755 EPOLL_CTL_DEL, 1756 connection->socket_fd, 1757 NULL)) 1758 MHD_PANIC ("Failed to remove FD from epoll set\n"); 1759 connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; 1760 } 1761 connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED; 1762 } 1763#endif 1764 connection->suspended = MHD_YES; 1765 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 1766 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) ) 1767 MHD_PANIC ("Failed to release cleanup mutex\n"); 1768} 1769 1770 1771/** 1772 * Resume handling of network data for suspended connection. It is 1773 * safe to resume a suspended connection at any time. Calling this function 1774 * on a connection that was not previously suspended will result 1775 * in undefined behavior. 1776 * 1777 * @param connection the connection to resume 1778 */ 1779void 1780MHD_resume_connection (struct MHD_Connection *connection) 1781{ 1782 struct MHD_Daemon *daemon; 1783 1784 daemon = connection->daemon; 1785 if (MHD_USE_SUSPEND_RESUME != (daemon->options & MHD_USE_SUSPEND_RESUME)) 1786 MHD_PANIC ("Cannot resume connections without enabling MHD_USE_SUSPEND_RESUME!\n"); 1787 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 1788 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) ) 1789 MHD_PANIC ("Failed to acquire cleanup mutex\n"); 1790 connection->resuming = MHD_YES; 1791 daemon->resuming = MHD_YES; 1792 if ( (MHD_INVALID_PIPE_ != daemon->wpipe[1]) && 1793 (1 != MHD_pipe_write_ (daemon->wpipe[1], "r", 1)) ) 1794 { 1795#if HAVE_MESSAGES 1796 MHD_DLOG (daemon, 1797 "failed to signal resume via pipe"); 1798#endif 1799 } 1800 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 1801 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) ) 1802 MHD_PANIC ("Failed to release cleanup mutex\n"); 1803} 1804 1805 1806/** 1807 * Run through the suspended connections and move any that are no 1808 * longer suspended back to the active state. 1809 * 1810 * @param daemon daemon context 1811 * @return #MHD_YES if a connection was actually resumed 1812 */ 1813static int 1814resume_suspended_connections (struct MHD_Daemon *daemon) 1815{ 1816 struct MHD_Connection *pos; 1817 struct MHD_Connection *next = NULL; 1818 int ret; 1819 1820 ret = MHD_NO; 1821 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 1822 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) ) 1823 MHD_PANIC ("Failed to acquire cleanup mutex\n"); 1824 if (MHD_YES == daemon->resuming) 1825 next = daemon->suspended_connections_head; 1826 1827 while (NULL != (pos = next)) 1828 { 1829 next = pos->next; 1830 if (MHD_NO == pos->resuming) 1831 continue; 1832 ret = MHD_YES; 1833 DLL_remove (daemon->suspended_connections_head, 1834 daemon->suspended_connections_tail, 1835 pos); 1836 DLL_insert (daemon->connections_head, 1837 daemon->connections_tail, 1838 pos); 1839 if (pos->connection_timeout == daemon->connection_timeout) 1840 XDLL_insert (daemon->normal_timeout_head, 1841 daemon->normal_timeout_tail, 1842 pos); 1843 else 1844 XDLL_insert (daemon->manual_timeout_head, 1845 daemon->manual_timeout_tail, 1846 pos); 1847#if EPOLL_SUPPORT 1848 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) 1849 { 1850 if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) 1851 MHD_PANIC ("Resumed connection was already in EREADY set\n"); 1852 /* we always mark resumed connections as ready, as we 1853 might have missed the edge poll event during suspension */ 1854 EDLL_insert (daemon->eready_head, 1855 daemon->eready_tail, 1856 pos); 1857 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; 1858 pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED; 1859 } 1860#endif 1861 pos->suspended = MHD_NO; 1862 pos->resuming = MHD_NO; 1863 } 1864 daemon->resuming = MHD_NO; 1865 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 1866 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) ) 1867 MHD_PANIC ("Failed to release cleanup mutex\n"); 1868 return ret; 1869} 1870 1871 1872/** 1873 * Change socket options to be non-blocking, non-inheritable. 1874 * 1875 * @param daemon daemon context 1876 * @param sock socket to manipulate 1877 */ 1878static void 1879make_nonblocking_noninheritable (struct MHD_Daemon *daemon, 1880 MHD_socket sock) 1881{ 1882#ifdef WINDOWS 1883 DWORD dwFlags; 1884 unsigned long flags = 1; 1885 1886 if (0 != ioctlsocket (sock, FIONBIO, &flags)) 1887 { 1888#if HAVE_MESSAGES 1889 MHD_DLOG (daemon, 1890 "Failed to make socket non-blocking: %s\n", 1891 MHD_socket_last_strerr_ ()); 1892#endif 1893 } 1894 if (!GetHandleInformation ((HANDLE) sock, &dwFlags) || 1895 ((dwFlags != (dwFlags & ~HANDLE_FLAG_INHERIT)) && 1896 !SetHandleInformation ((HANDLE) sock, HANDLE_FLAG_INHERIT, 0))) 1897 { 1898#if HAVE_MESSAGES 1899 MHD_DLOG (daemon, 1900 "Failed to make socket non-inheritable: %u\n", 1901 (unsigned int) GetLastError ()); 1902#endif 1903 } 1904#else 1905 int flags; 1906 int nonblock; 1907 1908 nonblock = O_NONBLOCK; 1909#ifdef CYGWIN 1910 if (0 == (daemon->options & MHD_USE_SSL)) 1911 nonblock = 0; 1912#endif 1913 flags = fcntl (sock, F_GETFD); 1914 if ( ( (-1 == flags) || 1915 ( (flags != (flags | FD_CLOEXEC)) && 1916 (0 != fcntl (sock, F_SETFD, flags | nonblock | FD_CLOEXEC)) ) ) ) 1917 { 1918#if HAVE_MESSAGES 1919 MHD_DLOG (daemon, 1920 "Failed to make socket non-inheritable: %s\n", 1921 MHD_socket_last_strerr_ ()); 1922#endif 1923 } 1924#endif 1925} 1926 1927 1928/** 1929 * Add another client connection to the set of connections managed by 1930 * MHD. This API is usually not needed (since MHD will accept inbound 1931 * connections on the server socket). Use this API in special cases, 1932 * for example if your HTTP server is behind NAT and needs to connect 1933 * out to the HTTP client, or if you are building a proxy. 1934 * 1935 * If you use this API in conjunction with a internal select or a 1936 * thread pool, you must set the option 1937 * #MHD_USE_PIPE_FOR_SHUTDOWN to ensure that the freshly added 1938 * connection is immediately processed by MHD. 1939 * 1940 * The given client socket will be managed (and closed!) by MHD after 1941 * this call and must no longer be used directly by the application 1942 * afterwards. 1943 * 1944 * Per-IP connection limits are ignored when using this API. 1945 * 1946 * @param daemon daemon that manages the connection 1947 * @param client_socket socket to manage (MHD will expect 1948 * to receive an HTTP request from this socket next). 1949 * @param addr IP address of the client 1950 * @param addrlen number of bytes in @a addr 1951 * @return #MHD_YES on success, #MHD_NO if this daemon could 1952 * not handle the connection (i.e. malloc() failed, etc). 1953 * The socket will be closed in any case; `errno` is 1954 * set to indicate further details about the error. 1955 * @ingroup specialized 1956 */ 1957int 1958MHD_add_connection (struct MHD_Daemon *daemon, 1959 MHD_socket client_socket, 1960 const struct sockaddr *addr, 1961 socklen_t addrlen) 1962{ 1963 make_nonblocking_noninheritable (daemon, 1964 client_socket); 1965 return internal_add_connection (daemon, 1966 client_socket, 1967 addr, addrlen, 1968 MHD_YES); 1969} 1970 1971 1972/** 1973 * Accept an incoming connection and create the MHD_Connection object for 1974 * it. This function also enforces policy by way of checking with the 1975 * accept policy callback. 1976 * 1977 * @param daemon handle with the listen socket 1978 * @return #MHD_YES on success (connections denied by policy or due 1979 * to 'out of memory' and similar errors) are still considered 1980 * successful as far as #MHD_accept_connection() is concerned); 1981 * a return code of #MHD_NO only refers to the actual 1982 * accept() system call. 1983 */ 1984static int 1985MHD_accept_connection (struct MHD_Daemon *daemon) 1986{ 1987#if HAVE_INET6 1988 struct sockaddr_in6 addrstorage; 1989#else 1990 struct sockaddr_in addrstorage; 1991#endif 1992 struct sockaddr *addr = (struct sockaddr *) &addrstorage; 1993 socklen_t addrlen; 1994 MHD_socket s; 1995 MHD_socket fd; 1996 int nonblock; 1997 1998 addrlen = sizeof (addrstorage); 1999 memset (addr, 0, sizeof (addrstorage)); 2000 if (MHD_INVALID_SOCKET == (fd = daemon->socket_fd)) 2001 return MHD_NO; 2002#ifdef HAVE_SOCK_NONBLOCK 2003 nonblock = SOCK_NONBLOCK; 2004#else 2005 nonblock = 0; 2006#endif 2007#ifdef CYGWIN 2008 if (0 == (daemon->options & MHD_USE_SSL)) 2009 nonblock = 0; 2010#endif 2011#if HAVE_ACCEPT4 2012 s = accept4 (fd, addr, &addrlen, SOCK_CLOEXEC | nonblock); 2013#else 2014 s = accept (fd, addr, &addrlen); 2015#endif 2016 if ((MHD_INVALID_SOCKET == s) || (addrlen <= 0)) 2017 { 2018#if HAVE_MESSAGES 2019 const int err = MHD_socket_errno_; 2020 /* This could be a common occurance with multiple worker threads */ 2021 if ( (EINVAL == err) && 2022 (MHD_INVALID_SOCKET == daemon->socket_fd) ) 2023 return MHD_NO; /* can happen during shutdown */ 2024 if ((EAGAIN != err) && (EWOULDBLOCK != err)) 2025 MHD_DLOG (daemon, 2026 "Error accepting connection: %s\n", 2027 MHD_socket_last_strerr_ ()); 2028#endif 2029 if (MHD_INVALID_SOCKET != s) 2030 { 2031 if (0 != MHD_socket_close_ (s)) 2032 MHD_PANIC ("close failed\n"); 2033 /* just in case */ 2034 } 2035 return MHD_NO; 2036 } 2037#if !defined(HAVE_ACCEPT4) || HAVE_ACCEPT4+0 == 0 || !defined(HAVE_SOCK_NONBLOCK) || SOCK_CLOEXEC+0 == 0 2038 make_nonblocking_noninheritable (daemon, s); 2039#endif 2040#if HAVE_MESSAGES 2041#if DEBUG_CONNECT 2042 MHD_DLOG (daemon, 2043 "Accepted connection on socket %d\n", 2044 s); 2045#endif 2046#endif 2047 (void) internal_add_connection (daemon, s, 2048 addr, addrlen, 2049 MHD_NO); 2050 return MHD_YES; 2051} 2052 2053 2054/** 2055 * Free resources associated with all closed connections. 2056 * (destroy responses, free buffers, etc.). All closed 2057 * connections are kept in the "cleanup" doubly-linked list. 2058 * 2059 * @param daemon daemon to clean up 2060 */ 2061static void 2062MHD_cleanup_connections (struct MHD_Daemon *daemon) 2063{ 2064 struct MHD_Connection *pos; 2065 2066 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 2067 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) ) 2068 MHD_PANIC ("Failed to acquire cleanup mutex\n"); 2069 while (NULL != (pos = daemon->cleanup_head)) 2070 { 2071 DLL_remove (daemon->cleanup_head, 2072 daemon->cleanup_tail, 2073 pos); 2074 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 2075 (MHD_NO == pos->thread_joined) ) 2076 { 2077 if (0 != MHD_join_thread_ (pos->pid)) 2078 { 2079 MHD_PANIC ("Failed to join a thread\n"); 2080 } 2081 } 2082 MHD_pool_destroy (pos->pool); 2083#if HTTPS_SUPPORT 2084 if (NULL != pos->tls_session) 2085 SSL_free (pos->tls_session); 2086#endif 2087 if (NULL != daemon->notify_connection) 2088 daemon->notify_connection (daemon->notify_connection_cls, 2089 pos, 2090 &pos->socket_context, 2091 MHD_CONNECTION_NOTIFY_CLOSED); 2092 MHD_ip_limit_del (daemon, pos->addr, pos->addr_len); 2093#if EPOLL_SUPPORT 2094 if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) 2095 { 2096 EDLL_remove (daemon->eready_head, 2097 daemon->eready_tail, 2098 pos); 2099 pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; 2100 } 2101 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && 2102 (MHD_INVALID_SOCKET != daemon->epoll_fd) && 2103 (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) ) 2104 { 2105 /* epoll documentation suggests that closing a FD 2106 automatically removes it from the epoll set; however, 2107 this is not true as if we fail to do manually remove it, 2108 we are still seeing an event for this fd in epoll, 2109 causing grief (use-after-free...) --- at least on my 2110 system. */ 2111 if (0 != epoll_ctl (daemon->epoll_fd, 2112 EPOLL_CTL_DEL, 2113 pos->socket_fd, 2114 NULL)) 2115 MHD_PANIC ("Failed to remove FD from epoll set\n"); 2116 pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; 2117 } 2118#endif 2119 if (NULL != pos->response) 2120 { 2121 MHD_destroy_response (pos->response); 2122 pos->response = NULL; 2123 } 2124 if (MHD_INVALID_SOCKET != pos->socket_fd) 2125 { 2126#ifdef WINDOWS 2127 shutdown (pos->socket_fd, SHUT_WR); 2128#endif 2129 if (0 != MHD_socket_close_ (pos->socket_fd)) 2130 MHD_PANIC ("close failed\n"); 2131 } 2132 if (NULL != pos->addr) 2133 free (pos->addr); 2134 free (pos); 2135 daemon->connections--; 2136 } 2137 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 2138 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) ) 2139 MHD_PANIC ("Failed to release cleanup mutex\n"); 2140} 2141 2142 2143/** 2144 * Obtain timeout value for `select()` for this daemon (only needed if 2145 * connection timeout is used). The returned value is how long 2146 * `select()` or `poll()` should at most block, not the timeout value set 2147 * for connections. This function MUST NOT be called if MHD is 2148 * running with #MHD_USE_THREAD_PER_CONNECTION. 2149 * 2150 * @param daemon daemon to query for timeout 2151 * @param timeout set to the timeout (in milliseconds) 2152 * @return #MHD_YES on success, #MHD_NO if timeouts are 2153 * not used (or no connections exist that would 2154 * necessiate the use of a timeout right now). 2155 * @ingroup event 2156 */ 2157int 2158MHD_get_timeout (struct MHD_Daemon *daemon, 2159 MHD_UNSIGNED_LONG_LONG *timeout) 2160{ 2161 time_t earliest_deadline; 2162 time_t now; 2163 struct MHD_Connection *pos; 2164 int have_timeout; 2165 2166 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 2167 { 2168#if HAVE_MESSAGES 2169 MHD_DLOG (daemon, 2170 "Illegal call to MHD_get_timeout\n"); 2171#endif 2172 return MHD_NO; 2173 } 2174 2175#if HTTPS_SUPPORT 2176 if (0 != daemon->num_tls_read_ready) 2177 { 2178 /* if there is any TLS connection with data ready for 2179 reading, we must not block in the event loop */ 2180 *timeout = 0; 2181 return MHD_YES; 2182 } 2183#endif 2184 2185 have_timeout = MHD_NO; 2186 earliest_deadline = 0; /* avoid compiler warnings */ 2187 for (pos = daemon->manual_timeout_head; NULL != pos; pos = pos->nextX) 2188 { 2189 if (0 != pos->connection_timeout) 2190 { 2191 if ( (! have_timeout) || 2192 (earliest_deadline > pos->last_activity + pos->connection_timeout) ) 2193 earliest_deadline = pos->last_activity + pos->connection_timeout; 2194#if HTTPS_SUPPORT 2195 if ( (0 != (daemon->options & MHD_USE_SSL)) && 2196 (0 != SSL_pending (pos->tls_session)) ) 2197 earliest_deadline = 0; 2198#endif 2199 have_timeout = MHD_YES; 2200 } 2201 } 2202 /* normal timeouts are sorted, so we only need to look at the 'head' */ 2203 pos = daemon->normal_timeout_head; 2204 if ( (NULL != pos) && 2205 (0 != pos->connection_timeout) ) 2206 { 2207 if ( (! have_timeout) || 2208 (earliest_deadline > pos->last_activity + pos->connection_timeout) ) 2209 earliest_deadline = pos->last_activity + pos->connection_timeout; 2210#if HTTPS_SUPPORT 2211 if ( (0 != (daemon->options & MHD_USE_SSL)) && 2212 (0 != SSL_pending (pos->tls_session)) ) 2213 earliest_deadline = 0; 2214#endif 2215 have_timeout = MHD_YES; 2216 } 2217 2218 if (MHD_NO == have_timeout) 2219 return MHD_NO; 2220 now = MHD_monotonic_time(); 2221 if (earliest_deadline < now) 2222 *timeout = 0; 2223 else 2224 *timeout = 1000 * (1 + earliest_deadline - now); 2225 return MHD_YES; 2226} 2227 2228 2229/** 2230 * Run webserver operations. This method should be called by clients 2231 * in combination with #MHD_get_fdset if the client-controlled select 2232 * method is used. 2233 * 2234 * You can use this function instead of #MHD_run if you called 2235 * `select()` on the result from #MHD_get_fdset. File descriptors in 2236 * the sets that are not controlled by MHD will be ignored. Calling 2237 * this function instead of #MHD_run is more efficient as MHD will 2238 * not have to call `select()` again to determine which operations are 2239 * ready. 2240 * 2241 * @param daemon daemon to run select loop for 2242 * @param read_fd_set read set 2243 * @param write_fd_set write set 2244 * @param except_fd_set except set (not used, can be NULL) 2245 * @return #MHD_NO on serious errors, #MHD_YES on success 2246 * @ingroup event 2247 */ 2248int 2249MHD_run_from_select (struct MHD_Daemon *daemon, 2250 const fd_set *read_fd_set, 2251 const fd_set *write_fd_set, 2252 const fd_set *except_fd_set) 2253{ 2254 MHD_socket ds; 2255 char tmp; 2256 struct MHD_Connection *pos; 2257 struct MHD_Connection *next; 2258 2259#if EPOLL_SUPPORT 2260 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) 2261 { 2262 /* we're in epoll mode, the epoll FD stands for 2263 the entire event set! */ 2264 if (daemon->epoll_fd >= FD_SETSIZE) 2265 return MHD_NO; /* poll fd too big, fail hard */ 2266 if (FD_ISSET (daemon->epoll_fd, read_fd_set)) 2267 return MHD_run (daemon); 2268 return MHD_YES; 2269 } 2270#endif 2271 2272 /* select connection thread handling type */ 2273 if ( (MHD_INVALID_SOCKET != (ds = daemon->socket_fd)) && 2274 (FD_ISSET (ds, (fd_set*)read_fd_set)) ) 2275 (void) MHD_accept_connection (daemon); 2276 /* drain signaling pipe to avoid spinning select */ 2277 if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) && 2278 (FD_ISSET (daemon->wpipe[0], (fd_set*)read_fd_set)) ) 2279 (void) MHD_pipe_read_ (daemon->wpipe[0], &tmp, sizeof (tmp)); 2280 2281 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 2282 { 2283 /* do not have a thread per connection, process all connections now */ 2284 next = daemon->connections_head; 2285 while (NULL != (pos = next)) 2286 { 2287 next = pos->next; 2288 ds = pos->socket_fd; 2289 if (MHD_INVALID_SOCKET == ds) 2290 continue; 2291 switch (pos->event_loop_info) 2292 { 2293 case MHD_EVENT_LOOP_INFO_READ: 2294 if ( (FD_ISSET (ds, (fd_set*)read_fd_set)) 2295#if HTTPS_SUPPORT 2296 || (MHD_YES == pos->tls_read_ready) 2297#endif 2298 ) 2299 pos->read_handler (pos); 2300 break; 2301 case MHD_EVENT_LOOP_INFO_WRITE: 2302 if ( (FD_ISSET (ds, (fd_set*)read_fd_set)) && 2303 (pos->read_buffer_size > pos->read_buffer_offset) ) 2304 pos->read_handler (pos); 2305 if (FD_ISSET (ds, (fd_set*)write_fd_set)) 2306 pos->write_handler (pos); 2307 break; 2308 case MHD_EVENT_LOOP_INFO_BLOCK: 2309 if ( (FD_ISSET (ds, (fd_set*)read_fd_set)) && 2310 (pos->read_buffer_size > pos->read_buffer_offset) ) 2311 pos->read_handler (pos); 2312 break; 2313 case MHD_EVENT_LOOP_INFO_CLEANUP: 2314 /* should never happen */ 2315 break; 2316 } 2317 pos->idle_handler (pos); 2318 } 2319 } 2320 MHD_cleanup_connections (daemon); 2321 return MHD_YES; 2322} 2323 2324 2325/** 2326 * Main internal select() call. Will compute select sets, call select() 2327 * and then #MHD_run_from_select with the result. 2328 * 2329 * @param daemon daemon to run select() loop for 2330 * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking 2331 * @return #MHD_NO on serious errors, #MHD_YES on success 2332 */ 2333static int 2334MHD_select (struct MHD_Daemon *daemon, 2335 int may_block) 2336{ 2337 int num_ready; 2338 fd_set rs; 2339 fd_set ws; 2340 fd_set es; 2341 MHD_socket max; 2342 struct timeval timeout; 2343 struct timeval *tv; 2344 MHD_UNSIGNED_LONG_LONG ltimeout; 2345 2346 timeout.tv_sec = 0; 2347 timeout.tv_usec = 0; 2348 if (MHD_YES == daemon->shutdown) 2349 return MHD_NO; 2350 FD_ZERO (&rs); 2351 FD_ZERO (&ws); 2352 FD_ZERO (&es); 2353 max = MHD_INVALID_SOCKET; 2354 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 2355 { 2356 if ( (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) && 2357 (MHD_YES == resume_suspended_connections (daemon)) ) 2358 may_block = MHD_NO; 2359 2360 /* single-threaded, go over everything */ 2361 if (MHD_NO == MHD_get_fdset2 (daemon, &rs, &ws, &es, &max, FD_SETSIZE)) 2362 return MHD_NO; 2363 2364 /* If we're at the connection limit, no need to 2365 accept new connections; however, make sure 2366 we do not miss the shutdown, so only do this 2367 optimization if we have a shutdown signaling 2368 pipe. */ 2369 if ( (MHD_INVALID_SOCKET != daemon->socket_fd) && 2370 (daemon->connections == daemon->connection_limit) && 2371 (0 != (daemon->options & MHD_USE_PIPE_FOR_SHUTDOWN)) ) 2372 FD_CLR (daemon->socket_fd, &rs); 2373 } 2374 else 2375 { 2376 /* accept only, have one thread per connection */ 2377 if ( (MHD_INVALID_SOCKET != daemon->socket_fd) && 2378 (MHD_YES != add_to_fd_set (daemon->socket_fd, 2379 &rs, 2380 &max, 2381 FD_SETSIZE)) ) 2382 return MHD_NO; 2383 } 2384 if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) && 2385 (MHD_YES != add_to_fd_set (daemon->wpipe[0], 2386 &rs, 2387 &max, 2388 FD_SETSIZE)) ) 2389 return MHD_NO; 2390 2391 tv = NULL; 2392 if (MHD_NO == may_block) 2393 { 2394 timeout.tv_usec = 0; 2395 timeout.tv_sec = 0; 2396 tv = &timeout; 2397 } 2398 else if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 2399 (MHD_YES == MHD_get_timeout (daemon, <imeout)) ) 2400 { 2401 /* ltimeout is in ms */ 2402 timeout.tv_usec = (ltimeout % 1000) * 1000; 2403 timeout.tv_sec = ltimeout / 1000; 2404 tv = &timeout; 2405 } 2406 if (MHD_INVALID_SOCKET == max) 2407 return MHD_YES; 2408 num_ready = MHD_SYS_select_ (max + 1, &rs, &ws, &es, tv); 2409 if (MHD_YES == daemon->shutdown) 2410 return MHD_NO; 2411 if (num_ready < 0) 2412 { 2413 if (EINTR == MHD_socket_errno_) 2414 return MHD_YES; 2415#if HAVE_MESSAGES 2416 MHD_DLOG (daemon, 2417 "select failed: %s\n", 2418 MHD_socket_last_strerr_ ()); 2419#endif 2420 return MHD_NO; 2421 } 2422 return MHD_run_from_select (daemon, &rs, &ws, &es); 2423} 2424 2425 2426#ifdef HAVE_POLL 2427/** 2428 * Process all of our connections and possibly the server 2429 * socket using poll(). 2430 * 2431 * @param daemon daemon to run poll loop for 2432 * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking 2433 * @return #MHD_NO on serious errors, #MHD_YES on success 2434 */ 2435static int 2436MHD_poll_all (struct MHD_Daemon *daemon, 2437 int may_block) 2438{ 2439 unsigned int num_connections; 2440 struct MHD_Connection *pos; 2441 struct MHD_Connection *next; 2442 2443 if ( (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) && 2444 (MHD_YES == resume_suspended_connections (daemon)) ) 2445 may_block = MHD_NO; 2446 2447 /* count number of connections and thus determine poll set size */ 2448 num_connections = 0; 2449 for (pos = daemon->connections_head; NULL != pos; pos = pos->next) 2450 num_connections++; 2451 { 2452 MHD_UNSIGNED_LONG_LONG ltimeout; 2453 unsigned int i; 2454 int timeout; 2455 unsigned int poll_server; 2456 int poll_listen; 2457 int poll_pipe; 2458 char tmp; 2459 struct pollfd *p; 2460 2461 p = malloc(sizeof (struct pollfd) * (2 + num_connections)); 2462 if (NULL == p) 2463 { 2464#if HAVE_MESSAGES 2465 MHD_DLOG(daemon, 2466 "Error allocating memory: %s\n", 2467 MHD_strerror_(errno)); 2468#endif 2469 return MHD_NO; 2470 } 2471 memset (p, 0, sizeof (struct pollfd) * (2 + num_connections)); 2472 poll_server = 0; 2473 poll_listen = -1; 2474 if ( (MHD_INVALID_SOCKET != daemon->socket_fd) && 2475 (daemon->connections < daemon->connection_limit) ) 2476 { 2477 /* only listen if we are not at the connection limit */ 2478 p[poll_server].fd = daemon->socket_fd; 2479 p[poll_server].events = POLLIN; 2480 p[poll_server].revents = 0; 2481 poll_listen = (int) poll_server; 2482 poll_server++; 2483 } 2484 poll_pipe = -1; 2485 if (MHD_INVALID_PIPE_ != daemon->wpipe[0]) 2486 { 2487 p[poll_server].fd = daemon->wpipe[0]; 2488 p[poll_server].events = POLLIN; 2489 p[poll_server].revents = 0; 2490 poll_pipe = (int) poll_server; 2491 poll_server++; 2492 } 2493 if (may_block == MHD_NO) 2494 timeout = 0; 2495 else if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || 2496 (MHD_YES != MHD_get_timeout (daemon, <imeout)) ) 2497 timeout = -1; 2498 else 2499 timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout; 2500 2501 i = 0; 2502 for (pos = daemon->connections_head; NULL != pos; pos = pos->next) 2503 { 2504 p[poll_server+i].fd = pos->socket_fd; 2505 switch (pos->event_loop_info) 2506 { 2507 case MHD_EVENT_LOOP_INFO_READ: 2508 p[poll_server+i].events |= POLLIN; 2509 break; 2510 case MHD_EVENT_LOOP_INFO_WRITE: 2511 p[poll_server+i].events |= POLLOUT; 2512 if (pos->read_buffer_size > pos->read_buffer_offset) 2513 p[poll_server+i].events |= POLLIN; 2514 break; 2515 case MHD_EVENT_LOOP_INFO_BLOCK: 2516 if (pos->read_buffer_size > pos->read_buffer_offset) 2517 p[poll_server+i].events |= POLLIN; 2518 break; 2519 case MHD_EVENT_LOOP_INFO_CLEANUP: 2520 timeout = 0; /* clean up "pos" immediately */ 2521 break; 2522 } 2523 i++; 2524 } 2525 if (0 == poll_server + num_connections) 2526 { 2527 free(p); 2528 return MHD_YES; 2529 } 2530 if (MHD_sys_poll_(p, poll_server + num_connections, timeout) < 0) 2531 { 2532 if (EINTR == MHD_socket_errno_) 2533 { 2534 free(p); 2535 return MHD_YES; 2536 } 2537#if HAVE_MESSAGES 2538 MHD_DLOG (daemon, 2539 "poll failed: %s\n", 2540 MHD_socket_last_strerr_ ()); 2541#endif 2542 free(p); 2543 return MHD_NO; 2544 } 2545 /* handle shutdown */ 2546 if (MHD_YES == daemon->shutdown) 2547 { 2548 free(p); 2549 return MHD_NO; 2550 } 2551 i = 0; 2552 next = daemon->connections_head; 2553 while (NULL != (pos = next)) 2554 { 2555 next = pos->next; 2556 switch (pos->event_loop_info) 2557 { 2558 case MHD_EVENT_LOOP_INFO_READ: 2559 /* first, sanity checks */ 2560 if (i >= num_connections) 2561 break; /* connection list changed somehow, retry later ... */ 2562 if (p[poll_server+i].fd != pos->socket_fd) 2563 break; /* fd mismatch, something else happened, retry later ... */ 2564 /* normal handling */ 2565 if (0 != (p[poll_server+i].revents & POLLIN)) 2566 pos->read_handler (pos); 2567 pos->idle_handler (pos); 2568 i++; 2569 break; 2570 case MHD_EVENT_LOOP_INFO_WRITE: 2571 /* first, sanity checks */ 2572 if (i >= num_connections) 2573 break; /* connection list changed somehow, retry later ... */ 2574 if (p[poll_server+i].fd != pos->socket_fd) 2575 break; /* fd mismatch, something else happened, retry later ... */ 2576 /* normal handling */ 2577 if (0 != (p[poll_server+i].revents & POLLIN)) 2578 pos->read_handler (pos); 2579 if (0 != (p[poll_server+i].revents & POLLOUT)) 2580 pos->write_handler (pos); 2581 pos->idle_handler (pos); 2582 i++; 2583 break; 2584 case MHD_EVENT_LOOP_INFO_BLOCK: 2585 if (0 != (p[poll_server+i].revents & POLLIN)) 2586 pos->read_handler (pos); 2587 pos->idle_handler (pos); 2588 break; 2589 case MHD_EVENT_LOOP_INFO_CLEANUP: 2590 pos->idle_handler (pos); 2591 break; 2592 } 2593 } 2594 /* handle 'listen' FD */ 2595 if ( (-1 != poll_listen) && 2596 (0 != (p[poll_listen].revents & POLLIN)) ) 2597 (void) MHD_accept_connection (daemon); 2598 2599 /* handle pipe FD */ 2600 if ( (-1 != poll_pipe) && 2601 (0 != (p[poll_pipe].revents & POLLIN)) ) 2602 (void) MHD_pipe_read_ (daemon->wpipe[0], &tmp, sizeof (tmp)); 2603 2604 free(p); 2605 } 2606 return MHD_YES; 2607} 2608 2609 2610/** 2611 * Process only the listen socket using poll(). 2612 * 2613 * @param daemon daemon to run poll loop for 2614 * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking 2615 * @return #MHD_NO on serious errors, #MHD_YES on success 2616 */ 2617static int 2618MHD_poll_listen_socket (struct MHD_Daemon *daemon, 2619 int may_block) 2620{ 2621 struct pollfd p[2]; 2622 int timeout; 2623 unsigned int poll_count; 2624 int poll_listen; 2625 2626 memset (&p, 0, sizeof (p)); 2627 poll_count = 0; 2628 poll_listen = -1; 2629 if (MHD_INVALID_SOCKET != daemon->socket_fd) 2630 { 2631 p[poll_count].fd = daemon->socket_fd; 2632 p[poll_count].events = POLLIN; 2633 p[poll_count].revents = 0; 2634 poll_listen = poll_count; 2635 poll_count++; 2636 } 2637 if (MHD_INVALID_PIPE_ != daemon->wpipe[0]) 2638 { 2639 p[poll_count].fd = daemon->wpipe[0]; 2640 p[poll_count].events = POLLIN; 2641 p[poll_count].revents = 0; 2642 poll_count++; 2643 } 2644 if (MHD_NO == may_block) 2645 timeout = 0; 2646 else 2647 timeout = -1; 2648 if (0 == poll_count) 2649 return MHD_YES; 2650 if (MHD_sys_poll_(p, poll_count, timeout) < 0) 2651 { 2652 if (EINTR == MHD_socket_errno_) 2653 return MHD_YES; 2654#if HAVE_MESSAGES 2655 MHD_DLOG (daemon, 2656 "poll failed: %s\n", 2657 MHD_socket_last_strerr_ ()); 2658#endif 2659 return MHD_NO; 2660 } 2661 /* handle shutdown */ 2662 if (MHD_YES == daemon->shutdown) 2663 return MHD_NO; 2664 if ( (-1 != poll_listen) && 2665 (0 != (p[poll_listen].revents & POLLIN)) ) 2666 (void) MHD_accept_connection (daemon); 2667 return MHD_YES; 2668} 2669#endif 2670 2671 2672/** 2673 * Do poll()-based processing. 2674 * 2675 * @param daemon daemon to run poll()-loop for 2676 * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking 2677 * @return #MHD_NO on serious errors, #MHD_YES on success 2678 */ 2679static int 2680MHD_poll (struct MHD_Daemon *daemon, 2681 int may_block) 2682{ 2683#ifdef HAVE_POLL 2684 if (MHD_YES == daemon->shutdown) 2685 return MHD_NO; 2686 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 2687 return MHD_poll_all (daemon, may_block); 2688 else 2689 return MHD_poll_listen_socket (daemon, may_block); 2690#else 2691 return MHD_NO; 2692#endif 2693} 2694 2695 2696#if EPOLL_SUPPORT 2697 2698/** 2699 * How many events to we process at most per epoll() call? Trade-off 2700 * between required stack-size and number of system calls we have to 2701 * make; 128 should be way enough to avoid more than one system call 2702 * for most scenarios, and still be moderate in stack size 2703 * consumption. Embedded systems might want to choose a smaller value 2704 * --- but why use epoll() on such a system in the first place? 2705 */ 2706#define MAX_EVENTS 128 2707 2708 2709/** 2710 * Do epoll()-based processing (this function is allowed to 2711 * block if @a may_block is set to #MHD_YES). 2712 * 2713 * @param daemon daemon to run poll loop for 2714 * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking 2715 * @return #MHD_NO on serious errors, #MHD_YES on success 2716 */ 2717static int 2718MHD_epoll (struct MHD_Daemon *daemon, 2719 int may_block) 2720{ 2721 struct MHD_Connection *pos; 2722 struct MHD_Connection *next; 2723 struct epoll_event events[MAX_EVENTS]; 2724 struct epoll_event event; 2725 int timeout_ms; 2726 MHD_UNSIGNED_LONG_LONG timeout_ll; 2727 int num_events; 2728 unsigned int i; 2729 unsigned int series_length; 2730 char tmp; 2731 2732 if (-1 == daemon->epoll_fd) 2733 return MHD_NO; /* we're down! */ 2734 if (MHD_YES == daemon->shutdown) 2735 return MHD_NO; 2736 if ( (MHD_INVALID_SOCKET != daemon->socket_fd) && 2737 (daemon->connections < daemon->connection_limit) && 2738 (MHD_NO == daemon->listen_socket_in_epoll) ) 2739 { 2740 event.events = EPOLLIN; 2741 event.data.ptr = daemon; 2742 if (0 != epoll_ctl (daemon->epoll_fd, 2743 EPOLL_CTL_ADD, 2744 daemon->socket_fd, 2745 &event)) 2746 { 2747#if HAVE_MESSAGES 2748 MHD_DLOG (daemon, 2749 "Call to epoll_ctl failed: %s\n", 2750 MHD_socket_last_strerr_ ()); 2751#endif 2752 return MHD_NO; 2753 } 2754 daemon->listen_socket_in_epoll = MHD_YES; 2755 } 2756 if ( (MHD_YES == daemon->listen_socket_in_epoll) && 2757 (daemon->connections == daemon->connection_limit) ) 2758 { 2759 /* we're at the connection limit, disable listen socket 2760 for event loop for now */ 2761 if (0 != epoll_ctl (daemon->epoll_fd, 2762 EPOLL_CTL_DEL, 2763 daemon->socket_fd, 2764 NULL)) 2765 MHD_PANIC ("Failed to remove listen FD from epoll set\n"); 2766 daemon->listen_socket_in_epoll = MHD_NO; 2767 } 2768 if (MHD_YES == may_block) 2769 { 2770 if (MHD_YES == MHD_get_timeout (daemon, 2771 &timeout_ll)) 2772 { 2773 if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX) 2774 timeout_ms = INT_MAX; 2775 else 2776 timeout_ms = (int) timeout_ll; 2777 } 2778 else 2779 timeout_ms = -1; 2780 } 2781 else 2782 timeout_ms = 0; 2783 2784 /* drain 'epoll' event queue; need to iterate as we get at most 2785 MAX_EVENTS in one system call here; in practice this should 2786 pretty much mean only one round, but better an extra loop here 2787 than unfair behavior... */ 2788 num_events = MAX_EVENTS; 2789 while (MAX_EVENTS == num_events) 2790 { 2791 /* update event masks */ 2792 num_events = epoll_wait (daemon->epoll_fd, 2793 events, MAX_EVENTS, timeout_ms); 2794 if (-1 == num_events) 2795 { 2796 if (EINTR == MHD_socket_errno_) 2797 return MHD_YES; 2798#if HAVE_MESSAGES 2799 MHD_DLOG (daemon, 2800 "Call to epoll_wait failed: %s\n", 2801 MHD_socket_last_strerr_ ()); 2802#endif 2803 return MHD_NO; 2804 } 2805 for (i=0;i<(unsigned int) num_events;i++) 2806 { 2807 if (NULL == events[i].data.ptr) 2808 continue; /* shutdown signal! */ 2809 if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) && 2810 (daemon->wpipe[0] == events[i].data.fd) ) 2811 { 2812 (void) MHD_pipe_read_ (daemon->wpipe[0], &tmp, sizeof (tmp)); 2813 continue; 2814 } 2815 if (daemon != events[i].data.ptr) 2816 { 2817 /* this is an event relating to a 'normal' connection, 2818 remember the event and if appropriate mark the 2819 connection as 'eready'. */ 2820 pos = events[i].data.ptr; 2821 if (0 != (events[i].events & EPOLLIN)) 2822 { 2823 pos->epoll_state |= MHD_EPOLL_STATE_READ_READY; 2824 if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) || 2825 (pos->read_buffer_size > pos->read_buffer_offset) ) && 2826 (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) 2827 { 2828 EDLL_insert (daemon->eready_head, 2829 daemon->eready_tail, 2830 pos); 2831 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; 2832 } 2833 } 2834 if (0 != (events[i].events & EPOLLOUT)) 2835 { 2836 pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY; 2837 if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) && 2838 (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) 2839 { 2840 EDLL_insert (daemon->eready_head, 2841 daemon->eready_tail, 2842 pos); 2843 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; 2844 } 2845 } 2846 } 2847 else /* must be listen socket */ 2848 { 2849 /* run 'accept' until it fails or we are not allowed to take 2850 on more connections */ 2851 series_length = 0; 2852 while ( (MHD_YES == MHD_accept_connection (daemon)) && 2853 (daemon->connections < daemon->connection_limit) && 2854 (series_length < 128) ) 2855 series_length++; 2856 } 2857 } 2858 } 2859 2860 /* we handle resumes here because we may have ready connections 2861 that will not be placed into the epoll list immediately. */ 2862 if ( (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) && 2863 (MHD_YES == resume_suspended_connections (daemon)) ) 2864 may_block = MHD_NO; 2865 2866 /* process events for connections */ 2867 while (NULL != (pos = daemon->eready_tail)) 2868 { 2869 EDLL_remove (daemon->eready_head, 2870 daemon->eready_tail, 2871 pos); 2872 pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; 2873 if (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) 2874 pos->read_handler (pos); 2875 if (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) 2876 pos->write_handler (pos); 2877 pos->idle_handler (pos); 2878 } 2879 2880 /* Finally, handle timed-out connections; we need to do this here 2881 as the epoll mechanism won't call the 'idle_handler' on everything, 2882 as the other event loops do. As timeouts do not get an explicit 2883 event, we need to find those connections that might have timed out 2884 here. 2885 2886 Connections with custom timeouts must all be looked at, as we 2887 do not bother to sort that (presumably very short) list. */ 2888 next = daemon->manual_timeout_head; 2889 while (NULL != (pos = next)) 2890 { 2891 next = pos->nextX; 2892 pos->idle_handler (pos); 2893 } 2894 /* Connections with the default timeout are sorted by prepending 2895 them to the head of the list whenever we touch the connection; 2896 thus it sufficies to iterate from the tail until the first 2897 connection is NOT timed out */ 2898 next = daemon->normal_timeout_tail; 2899 while (NULL != (pos = next)) 2900 { 2901 next = pos->prevX; 2902 pos->idle_handler (pos); 2903 if (MHD_CONNECTION_CLOSED != pos->state) 2904 break; /* sorted by timeout, no need to visit the rest! */ 2905 } 2906 return MHD_YES; 2907} 2908#endif 2909 2910 2911/** 2912 * Run webserver operations (without blocking unless in client 2913 * callbacks). This method should be called by clients in combination 2914 * with #MHD_get_fdset if the client-controlled select method is used. 2915 * 2916 * This function is a convenience method, which is useful if the 2917 * fd_sets from #MHD_get_fdset were not directly passed to `select()`; 2918 * with this function, MHD will internally do the appropriate `select()` 2919 * call itself again. While it is always safe to call #MHD_run (in 2920 * external select mode), you should call #MHD_run_from_select if 2921 * performance is important (as it saves an expensive call to 2922 * `select()`). 2923 * 2924 * @param daemon daemon to run 2925 * @return #MHD_YES on success, #MHD_NO if this 2926 * daemon was not started with the right 2927 * options for this call. 2928 * @ingroup event 2929 */ 2930int 2931MHD_run (struct MHD_Daemon *daemon) 2932{ 2933 if ( (MHD_YES == daemon->shutdown) || 2934 (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || 2935 (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) ) 2936 return MHD_NO; 2937 if (0 != (daemon->options & MHD_USE_POLL)) 2938 { 2939 MHD_poll (daemon, MHD_NO); 2940 MHD_cleanup_connections (daemon); 2941 } 2942#if EPOLL_SUPPORT 2943 else if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) 2944 { 2945 MHD_epoll (daemon, MHD_NO); 2946 MHD_cleanup_connections (daemon); 2947 } 2948#endif 2949 else 2950 { 2951 MHD_select (daemon, MHD_NO); 2952 /* MHD_select does MHD_cleanup_connections already */ 2953 } 2954 return MHD_YES; 2955} 2956 2957 2958/** 2959 * Thread that runs the select loop until the daemon 2960 * is explicitly shut down. 2961 * 2962 * @param cls 'struct MHD_Deamon' to run select loop in a thread for 2963 * @return always 0 (on shutdown) 2964 */ 2965static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ 2966MHD_select_thread (void *cls) 2967{ 2968 struct MHD_Daemon *daemon = cls; 2969 2970 while (MHD_YES != daemon->shutdown) 2971 { 2972 if (0 != (daemon->options & MHD_USE_POLL)) 2973 MHD_poll (daemon, MHD_YES); 2974#if EPOLL_SUPPORT 2975 else if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) 2976 MHD_epoll (daemon, MHD_YES); 2977#endif 2978 else 2979 MHD_select (daemon, MHD_YES); 2980 MHD_cleanup_connections (daemon); 2981 } 2982 return (MHD_THRD_RTRN_TYPE_)0; 2983} 2984 2985 2986/** 2987 * Process escape sequences ('%HH') Updates val in place; the 2988 * result should be UTF-8 encoded and cannot be larger than the input. 2989 * The result must also still be 0-terminated. 2990 * 2991 * @param cls closure (use NULL) 2992 * @param connection handle to connection, not used 2993 * @param val value to unescape (modified in the process) 2994 * @return length of the resulting val (strlen(val) maybe 2995 * shorter afterwards due to elimination of escape sequences) 2996 */ 2997static size_t 2998unescape_wrapper (void *cls, 2999 struct MHD_Connection *connection, 3000 char *val) 3001{ 3002 return MHD_http_unescape (val); 3003} 3004 3005 3006/** 3007 * Start a webserver on the given port. Variadic version of 3008 * #MHD_start_daemon_va. 3009 * 3010 * @param flags combination of `enum MHD_FLAG` values 3011 * @param port port to bind to 3012 * @param apc callback to call to check which clients 3013 * will be allowed to connect; you can pass NULL 3014 * in which case connections from any IP will be 3015 * accepted 3016 * @param apc_cls extra argument to @a apc 3017 * @param dh handler called for all requests (repeatedly) 3018 * @param dh_cls extra argument to @a dh 3019 * @return NULL on error, handle to daemon on success 3020 * @ingroup event 3021 */ 3022struct MHD_Daemon * 3023MHD_start_daemon (unsigned int flags, 3024 uint16_t port, 3025 MHD_AcceptPolicyCallback apc, 3026 void *apc_cls, 3027 MHD_AccessHandlerCallback dh, void *dh_cls, ...) 3028{ 3029 struct MHD_Daemon *daemon; 3030 va_list ap; 3031 3032 va_start (ap, dh_cls); 3033 daemon = MHD_start_daemon_va (flags, port, apc, apc_cls, dh, dh_cls, ap); 3034 va_end (ap); 3035 return daemon; 3036} 3037 3038 3039/** 3040 * Stop accepting connections from the listening socket. Allows 3041 * clients to continue processing, but stops accepting new 3042 * connections. Note that the caller is responsible for closing the 3043 * returned socket; however, if MHD is run using threads (anything but 3044 * external select mode), it must not be closed until AFTER 3045 * #MHD_stop_daemon has been called (as it is theoretically possible 3046 * that an existing thread is still using it). 3047 * 3048 * Note that some thread modes require the caller to have passed 3049 * #MHD_USE_PIPE_FOR_SHUTDOWN when using this API. If this daemon is 3050 * in one of those modes and this option was not given to 3051 * #MHD_start_daemon, this function will return #MHD_INVALID_SOCKET. 3052 * 3053 * @param daemon daemon to stop accepting new connections for 3054 * @return old listen socket on success, #MHD_INVALID_SOCKET if 3055 * the daemon was already not listening anymore 3056 * @ingroup specialized 3057 */ 3058MHD_socket 3059MHD_quiesce_daemon (struct MHD_Daemon *daemon) 3060{ 3061 unsigned int i; 3062 MHD_socket ret; 3063 3064 ret = daemon->socket_fd; 3065 if (MHD_INVALID_SOCKET == ret) 3066 return MHD_INVALID_SOCKET; 3067 if ( (MHD_INVALID_PIPE_ == daemon->wpipe[1]) && 3068 (0 != (daemon->options & (MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION))) ) 3069 { 3070#if HAVE_MESSAGES 3071 MHD_DLOG (daemon, 3072 "Using MHD_quiesce_daemon in this mode requires MHD_USE_PIPE_FOR_SHUTDOWN\n"); 3073#endif 3074 return MHD_INVALID_SOCKET; 3075 } 3076 3077 if (NULL != daemon->worker_pool) 3078 for (i = 0; i < daemon->worker_pool_size; i++) 3079 { 3080 daemon->worker_pool[i].socket_fd = MHD_INVALID_SOCKET; 3081#if EPOLL_SUPPORT 3082 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && 3083 (-1 != daemon->worker_pool[i].epoll_fd) && 3084 (MHD_YES == daemon->worker_pool[i].listen_socket_in_epoll) ) 3085 { 3086 if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd, 3087 EPOLL_CTL_DEL, 3088 ret, 3089 NULL)) 3090 MHD_PANIC ("Failed to remove listen FD from epoll set\n"); 3091 daemon->worker_pool[i].listen_socket_in_epoll = MHD_NO; 3092 } 3093#endif 3094 } 3095 daemon->socket_fd = MHD_INVALID_SOCKET; 3096#if EPOLL_SUPPORT 3097 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && 3098 (-1 != daemon->epoll_fd) && 3099 (MHD_YES == daemon->listen_socket_in_epoll) ) 3100 { 3101 if (0 != epoll_ctl (daemon->epoll_fd, 3102 EPOLL_CTL_DEL, 3103 ret, 3104 NULL)) 3105 MHD_PANIC ("Failed to remove listen FD from epoll set\n"); 3106 daemon->listen_socket_in_epoll = MHD_NO; 3107 } 3108#endif 3109 return ret; 3110} 3111 3112 3113/** 3114 * Signature of the MHD custom logger function. 3115 * 3116 * @param cls closure 3117 * @param format format string 3118 * @param va arguments to the format string (fprintf-style) 3119 */ 3120typedef void (*VfprintfFunctionPointerType)(void *cls, 3121 const char *format, 3122 va_list va); 3123 3124 3125/** 3126 * Parse a list of options given as varargs. 3127 * 3128 * @param daemon the daemon to initialize 3129 * @param servaddr where to store the server's listen address 3130 * @param ap the options 3131 * @return #MHD_YES on success, #MHD_NO on error 3132 */ 3133static int 3134parse_options_va (struct MHD_Daemon *daemon, 3135 const struct sockaddr **servaddr, 3136 va_list ap); 3137 3138 3139/** 3140 * Parse a list of options given as varargs. 3141 * 3142 * @param daemon the daemon to initialize 3143 * @param servaddr where to store the server's listen address 3144 * @param ... the options 3145 * @return #MHD_YES on success, #MHD_NO on error 3146 */ 3147static int 3148parse_options (struct MHD_Daemon *daemon, 3149 const struct sockaddr **servaddr, 3150 ...) 3151{ 3152 va_list ap; 3153 int ret; 3154 3155 va_start (ap, servaddr); 3156 ret = parse_options_va (daemon, servaddr, ap); 3157 va_end (ap); 3158 return ret; 3159} 3160 3161 3162/** 3163 * Parse a list of options given as varargs. 3164 * 3165 * @param daemon the daemon to initialize 3166 * @param servaddr where to store the server's listen address 3167 * @param ap the options 3168 * @return #MHD_YES on success, #MHD_NO on error 3169 */ 3170static int 3171parse_options_va (struct MHD_Daemon *daemon, 3172 const struct sockaddr **servaddr, 3173 va_list ap) 3174{ 3175 enum MHD_OPTION opt; 3176 struct MHD_OptionItem *oa; 3177 unsigned int i; 3178#if HTTPS_SUPPORT 3179 int ret; 3180 const char *pstr; 3181#endif 3182 3183 while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int))) 3184 { 3185 switch (opt) 3186 { 3187 case MHD_OPTION_CONNECTION_MEMORY_LIMIT: 3188 daemon->pool_size = va_arg (ap, size_t); 3189 break; 3190 case MHD_OPTION_CONNECTION_MEMORY_INCREMENT: 3191 daemon->pool_increment= va_arg (ap, size_t); 3192 break; 3193 case MHD_OPTION_CONNECTION_LIMIT: 3194 daemon->connection_limit = va_arg (ap, unsigned int); 3195 break; 3196 case MHD_OPTION_CONNECTION_TIMEOUT: 3197 daemon->connection_timeout = va_arg (ap, unsigned int); 3198 break; 3199 case MHD_OPTION_NOTIFY_COMPLETED: 3200 daemon->notify_completed = 3201 va_arg (ap, MHD_RequestCompletedCallback); 3202 daemon->notify_completed_cls = va_arg (ap, void *); 3203 break; 3204 case MHD_OPTION_NOTIFY_CONNECTION: 3205 daemon->notify_connection = 3206 va_arg (ap, MHD_NotifyConnectionCallback); 3207 daemon->notify_connection_cls = va_arg (ap, void *); 3208 break; 3209 case MHD_OPTION_PER_IP_CONNECTION_LIMIT: 3210 daemon->per_ip_connection_limit = va_arg (ap, unsigned int); 3211 break; 3212 case MHD_OPTION_SOCK_ADDR: 3213 *servaddr = va_arg (ap, const struct sockaddr *); 3214 break; 3215 case MHD_OPTION_URI_LOG_CALLBACK: 3216 daemon->uri_log_callback = 3217 va_arg (ap, LogCallback); 3218 daemon->uri_log_callback_cls = va_arg (ap, void *); 3219 break; 3220 case MHD_OPTION_THREAD_POOL_SIZE: 3221 daemon->worker_pool_size = va_arg (ap, unsigned int); 3222 if (daemon->worker_pool_size >= (SIZE_MAX / sizeof (struct MHD_Daemon))) 3223 { 3224#if HAVE_MESSAGES 3225 MHD_DLOG (daemon, 3226 "Specified thread pool size (%u) too big\n", 3227 daemon->worker_pool_size); 3228#endif 3229 return MHD_NO; 3230 } 3231 break; 3232#if HTTPS_SUPPORT 3233 case MHD_OPTION_HTTPS_MEM_KEY: 3234 if (0 != (daemon->options & MHD_USE_SSL)) 3235 { 3236 daemon->https_mem_key = va_arg (ap, const char *); 3237 } 3238 else 3239 { 3240#if HAVE_MESSAGES 3241 MHD_DLOG (daemon, 3242 "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n", 3243 opt); 3244#endif 3245 } 3246 break; 3247 case MHD_OPTION_HTTPS_KEY_PASSWORD: 3248 if (0 != (daemon->options & MHD_USE_SSL)) 3249 { 3250 daemon->https_key_password = va_arg (ap, const char *); 3251 } 3252 else 3253 { 3254#if HAVE_MESSAGES 3255 MHD_DLOG (daemon, 3256 "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n", 3257 opt); 3258#endif 3259 } 3260 break; 3261 case MHD_OPTION_HTTPS_MEM_CERT: 3262 if (0 != (daemon->options & MHD_USE_SSL)) 3263 { 3264 daemon->https_mem_cert = va_arg (ap, const char *); 3265 } 3266 else 3267 { 3268#if HAVE_MESSAGES 3269 MHD_DLOG (daemon, 3270 "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n", 3271 opt); 3272#endif 3273 } 3274 break; 3275 case MHD_OPTION_HTTPS_MEM_TRUST: 3276 if (0 != (daemon->options & MHD_USE_SSL)) 3277 { 3278 daemon->https_mem_trust = va_arg (ap, const char *); 3279 } 3280 else 3281 { 3282#if HAVE_MESSAGES 3283 MHD_DLOG (daemon, 3284 "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n", 3285 opt); 3286#endif 3287 } 3288 break; 3289 case MHD_OPTION_HTTPS_CRED_TYPE: 3290 break; 3291 case MHD_OPTION_HTTPS_MEM_DHPARAMS: 3292 if (0 != (daemon->options & MHD_USE_SSL)) 3293 { 3294 daemon->https_mem_dhparams = va_arg (ap, const char *); 3295 } 3296 else 3297 { 3298#if HAVE_MESSAGES 3299 MHD_DLOG (daemon, 3300 "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n", 3301 opt); 3302#endif 3303 } 3304 break; 3305 case MHD_OPTION_HTTPS_PRIORITIES: 3306 if (0 != (daemon->options & MHD_USE_SSL)) 3307 { 3308 daemon->https_mem_cipher = va_arg (ap, const char *); 3309 } 3310 else 3311 { 3312#if HAVE_MESSAGES 3313 MHD_DLOG (daemon, 3314 "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n", 3315 opt); 3316#endif 3317 } 3318 break; 3319 case MHD_OPTION_HTTPS_CERT_CALLBACK: 3320 break; 3321#endif 3322#ifdef DAUTH_SUPPORT 3323 case MHD_OPTION_DIGEST_AUTH_RANDOM: 3324 daemon->digest_auth_rand_size = va_arg (ap, size_t); 3325 daemon->digest_auth_random = va_arg (ap, const char *); 3326 break; 3327 case MHD_OPTION_NONCE_NC_SIZE: 3328 daemon->nonce_nc_size = va_arg (ap, unsigned int); 3329 break; 3330#endif 3331 case MHD_OPTION_LISTEN_SOCKET: 3332 daemon->socket_fd = va_arg (ap, MHD_socket); 3333 break; 3334 case MHD_OPTION_EXTERNAL_LOGGER: 3335#if HAVE_MESSAGES 3336 daemon->custom_error_log = 3337 va_arg (ap, VfprintfFunctionPointerType); 3338 daemon->custom_error_log_cls = va_arg (ap, void *); 3339#else 3340 va_arg (ap, VfprintfFunctionPointerType); 3341 va_arg (ap, void *); 3342#endif 3343 break; 3344 case MHD_OPTION_THREAD_STACK_SIZE: 3345 daemon->thread_stack_size = va_arg (ap, size_t); 3346 break; 3347#ifdef TCP_FASTOPEN 3348 case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE: 3349 daemon->fastopen_queue_size = va_arg (ap, unsigned int); 3350 break; 3351#endif 3352 case MHD_OPTION_LISTENING_ADDRESS_REUSE: 3353 daemon->listening_address_reuse = va_arg (ap, unsigned int) ? 1 : -1; 3354 break; 3355 case MHD_OPTION_ARRAY: 3356 oa = va_arg (ap, struct MHD_OptionItem*); 3357 i = 0; 3358 while (MHD_OPTION_END != (opt = oa[i].option)) 3359 { 3360 switch (opt) 3361 { 3362 /* all options taking 'size_t' */ 3363 case MHD_OPTION_CONNECTION_MEMORY_LIMIT: 3364 case MHD_OPTION_CONNECTION_MEMORY_INCREMENT: 3365 case MHD_OPTION_THREAD_STACK_SIZE: 3366 if (MHD_YES != parse_options (daemon, 3367 servaddr, 3368 opt, 3369 (size_t) oa[i].value, 3370 MHD_OPTION_END)) 3371 return MHD_NO; 3372 break; 3373 /* all options taking 'unsigned int' */ 3374 case MHD_OPTION_NONCE_NC_SIZE: 3375 case MHD_OPTION_CONNECTION_LIMIT: 3376 case MHD_OPTION_CONNECTION_TIMEOUT: 3377 case MHD_OPTION_PER_IP_CONNECTION_LIMIT: 3378 case MHD_OPTION_THREAD_POOL_SIZE: 3379 case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE: 3380 case MHD_OPTION_LISTENING_ADDRESS_REUSE: 3381 if (MHD_YES != parse_options (daemon, 3382 servaddr, 3383 opt, 3384 (unsigned int) oa[i].value, 3385 MHD_OPTION_END)) 3386 return MHD_NO; 3387 break; 3388 /* all options taking 'enum' */ 3389 case MHD_OPTION_HTTPS_CRED_TYPE: 3390 if (MHD_YES != parse_options (daemon, 3391 servaddr, 3392 opt, 3393 (int) oa[i].value, 3394 MHD_OPTION_END)) 3395 return MHD_NO; 3396 break; 3397 /* all options taking 'MHD_socket' */ 3398 case MHD_OPTION_LISTEN_SOCKET: 3399 if (MHD_YES != parse_options (daemon, 3400 servaddr, 3401 opt, 3402 (MHD_socket) oa[i].value, 3403 MHD_OPTION_END)) 3404 return MHD_NO; 3405 break; 3406 /* all options taking one pointer */ 3407 case MHD_OPTION_SOCK_ADDR: 3408 case MHD_OPTION_HTTPS_MEM_KEY: 3409 case MHD_OPTION_HTTPS_KEY_PASSWORD: 3410 case MHD_OPTION_HTTPS_MEM_CERT: 3411 case MHD_OPTION_HTTPS_MEM_TRUST: 3412 case MHD_OPTION_HTTPS_MEM_DHPARAMS: 3413 case MHD_OPTION_HTTPS_PRIORITIES: 3414 case MHD_OPTION_ARRAY: 3415 case MHD_OPTION_HTTPS_CERT_CALLBACK: 3416 if (MHD_YES != parse_options (daemon, 3417 servaddr, 3418 opt, 3419 oa[i].ptr_value, 3420 MHD_OPTION_END)) 3421 return MHD_NO; 3422 break; 3423 /* all options taking two pointers */ 3424 case MHD_OPTION_NOTIFY_COMPLETED: 3425 case MHD_OPTION_NOTIFY_CONNECTION: 3426 case MHD_OPTION_URI_LOG_CALLBACK: 3427 case MHD_OPTION_EXTERNAL_LOGGER: 3428 case MHD_OPTION_UNESCAPE_CALLBACK: 3429 if (MHD_YES != parse_options (daemon, 3430 servaddr, 3431 opt, 3432 (void *) oa[i].value, 3433 oa[i].ptr_value, 3434 MHD_OPTION_END)) 3435 return MHD_NO; 3436 break; 3437 /* options taking size_t-number followed by pointer */ 3438 case MHD_OPTION_DIGEST_AUTH_RANDOM: 3439 if (MHD_YES != parse_options (daemon, 3440 servaddr, 3441 opt, 3442 (size_t) oa[i].value, 3443 oa[i].ptr_value, 3444 MHD_OPTION_END)) 3445 return MHD_NO; 3446 break; 3447 default: 3448 return MHD_NO; 3449 } 3450 i++; 3451 } 3452 break; 3453 case MHD_OPTION_UNESCAPE_CALLBACK: 3454 daemon->unescape_callback = 3455 va_arg (ap, UnescapeCallback); 3456 daemon->unescape_callback_cls = va_arg (ap, void *); 3457 break; 3458 default: 3459#if HAVE_MESSAGES 3460 if (((opt >= MHD_OPTION_HTTPS_MEM_KEY) && 3461 (opt <= MHD_OPTION_HTTPS_PRIORITIES)) || (opt == MHD_OPTION_HTTPS_MEM_TRUST)) 3462 { 3463 MHD_DLOG (daemon, 3464 "MHD HTTPS option %d passed to MHD compiled without HTTPS support\n", 3465 opt); 3466 } 3467 else 3468 { 3469 MHD_DLOG (daemon, 3470 "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n", 3471 opt); 3472 } 3473#endif 3474 return MHD_NO; 3475 } 3476 } 3477 return MHD_YES; 3478} 3479 3480 3481/** 3482 * Create a listen socket, if possible with SOCK_CLOEXEC flag set. 3483 * 3484 * @param daemon daemon for which we create the socket 3485 * @param domain socket domain (i.e. PF_INET) 3486 * @param type socket type (usually SOCK_STREAM) 3487 * @param protocol desired protocol, 0 for default 3488 */ 3489static MHD_socket 3490create_socket (struct MHD_Daemon *daemon, 3491 int domain, int type, int protocol) 3492{ 3493 int ctype = type | SOCK_CLOEXEC; 3494 MHD_socket fd; 3495 3496 /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo 3497 * implementations do not set ai_socktype, e.g. RHL6.2. */ 3498 fd = socket (domain, ctype, protocol); 3499 if ( (MHD_INVALID_SOCKET == fd) && (EINVAL == MHD_socket_errno_) && (0 != SOCK_CLOEXEC) ) 3500 { 3501 ctype = type; 3502 fd = socket(domain, type, protocol); 3503 } 3504 if (MHD_INVALID_SOCKET == fd) 3505 return MHD_INVALID_SOCKET; 3506 if (type == ctype) 3507 make_nonblocking_noninheritable (daemon, fd); 3508 return fd; 3509} 3510 3511 3512#if EPOLL_SUPPORT 3513/** 3514 * Setup epoll() FD for the daemon and initialize it to listen 3515 * on the listen FD. 3516 * 3517 * @param daemon daemon to initialize for epoll() 3518 * @return #MHD_YES on success, #MHD_NO on failure 3519 */ 3520static int 3521setup_epoll_to_listen (struct MHD_Daemon *daemon) 3522{ 3523 struct epoll_event event; 3524 3525#ifdef HAVE_EPOLL_CREATE1 3526 daemon->epoll_fd = epoll_create1 (EPOLL_CLOEXEC); 3527#else /* !HAVE_EPOLL_CREATE1 */ 3528 daemon->epoll_fd = epoll_create (MAX_EVENTS); 3529#endif /* !HAVE_EPOLL_CREATE1 */ 3530 if (-1 == daemon->epoll_fd) 3531 { 3532#if HAVE_MESSAGES 3533 MHD_DLOG (daemon, 3534 "Call to epoll_create1 failed: %s\n", 3535 MHD_socket_last_strerr_ ()); 3536#endif 3537 return MHD_NO; 3538 } 3539#ifndef HAVE_EPOLL_CREATE1 3540 else 3541 { 3542 int fdflags = fcntl (daemon->epoll_fd, F_GETFD); 3543 if (0 > fdflags || 0 > fcntl (daemon->epoll_fd, F_SETFD, fdflags | FD_CLOEXEC)) 3544 { 3545#if HAVE_MESSAGES 3546 MHD_DLOG (daemon, 3547 "Failed to change flags on epoll fd: %s\n", 3548 MHD_socket_last_strerr_ ()); 3549#endif /* HAVE_MESSAGES */ 3550 } 3551 } 3552#endif /* !HAVE_EPOLL_CREATE1 */ 3553 if (0 == EPOLL_CLOEXEC) 3554 make_nonblocking_noninheritable (daemon, 3555 daemon->epoll_fd); 3556 if (MHD_INVALID_SOCKET == daemon->socket_fd) 3557 return MHD_YES; /* non-listening daemon */ 3558 event.events = EPOLLIN; 3559 event.data.ptr = daemon; 3560 if (0 != epoll_ctl (daemon->epoll_fd, 3561 EPOLL_CTL_ADD, 3562 daemon->socket_fd, 3563 &event)) 3564 { 3565#if HAVE_MESSAGES 3566 MHD_DLOG (daemon, 3567 "Call to epoll_ctl failed: %s\n", 3568 MHD_socket_last_strerr_ ()); 3569#endif 3570 return MHD_NO; 3571 } 3572 if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) && 3573 (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) ) 3574 { 3575 event.events = EPOLLIN | EPOLLET; 3576 event.data.ptr = NULL; 3577 event.data.fd = daemon->wpipe[0]; 3578 if (0 != epoll_ctl (daemon->epoll_fd, 3579 EPOLL_CTL_ADD, 3580 daemon->wpipe[0], 3581 &event)) 3582 { 3583#if HAVE_MESSAGES 3584 MHD_DLOG (daemon, 3585 "Call to epoll_ctl failed: %s\n", 3586 MHD_socket_last_strerr_ ()); 3587#endif 3588 return MHD_NO; 3589 } 3590 } 3591 daemon->listen_socket_in_epoll = MHD_YES; 3592 return MHD_YES; 3593} 3594#endif 3595 3596 3597/** 3598 * Start a webserver on the given port. 3599 * 3600 * @param flags combination of `enum MHD_FLAG` values 3601 * @param port port to bind to (in host byte order) 3602 * @param apc callback to call to check which clients 3603 * will be allowed to connect; you can pass NULL 3604 * in which case connections from any IP will be 3605 * accepted 3606 * @param apc_cls extra argument to @a apc 3607 * @param dh handler called for all requests (repeatedly) 3608 * @param dh_cls extra argument to @a dh 3609 * @param ap list of options (type-value pairs, 3610 * terminated with #MHD_OPTION_END). 3611 * @return NULL on error, handle to daemon on success 3612 * @ingroup event 3613 */ 3614struct MHD_Daemon * 3615MHD_start_daemon_va (unsigned int flags, 3616 uint16_t port, 3617 MHD_AcceptPolicyCallback apc, 3618 void *apc_cls, 3619 MHD_AccessHandlerCallback dh, void *dh_cls, 3620 va_list ap) 3621{ 3622 const int on = 1; 3623 struct MHD_Daemon *daemon; 3624 MHD_socket socket_fd; 3625 struct sockaddr_in servaddr4; 3626#if HAVE_INET6 3627 struct sockaddr_in6 servaddr6; 3628#endif 3629 const struct sockaddr *servaddr = NULL; 3630 socklen_t addrlen; 3631 unsigned int i; 3632 int res_thread_create; 3633 int use_pipe; 3634 3635#ifndef HAVE_INET6 3636 if (0 != (flags & MHD_USE_IPv6)) 3637 return NULL; 3638#endif 3639#ifndef HAVE_POLL 3640 if (0 != (flags & MHD_USE_POLL)) 3641 return NULL; 3642#endif 3643#if ! HTTPS_SUPPORT 3644 if (0 != (flags & MHD_USE_SSL)) 3645 return NULL; 3646#endif 3647#ifndef TCP_FASTOPEN 3648 if (0 != (flags & MHD_USE_TCP_FASTOPEN)) 3649 return NULL; 3650#endif 3651 if (NULL == dh) 3652 return NULL; 3653 if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon)))) 3654 return NULL; 3655 memset (daemon, 0, sizeof (struct MHD_Daemon)); 3656#if EPOLL_SUPPORT 3657 daemon->epoll_fd = -1; 3658#endif 3659 /* try to open listen socket */ 3660 daemon->socket_fd = MHD_INVALID_SOCKET; 3661 daemon->listening_address_reuse = 0; 3662 daemon->options = flags; 3663#if WINDOWS 3664 /* Winsock is broken with respect to 'shutdown'; 3665 this disables us calling 'shutdown' on W32. */ 3666 daemon->options |= MHD_USE_EPOLL_TURBO; 3667#endif 3668 daemon->port = port; 3669 daemon->apc = apc; 3670 daemon->apc_cls = apc_cls; 3671 daemon->default_handler = dh; 3672 daemon->default_handler_cls = dh_cls; 3673 daemon->connections = 0; 3674 daemon->connection_limit = MHD_MAX_CONNECTIONS_DEFAULT; 3675 daemon->pool_size = MHD_POOL_SIZE_DEFAULT; 3676 daemon->pool_increment = MHD_BUF_INC_SIZE; 3677 daemon->unescape_callback = &unescape_wrapper; 3678 daemon->connection_timeout = 0; /* no timeout */ 3679 daemon->wpipe[0] = MHD_INVALID_PIPE_; 3680 daemon->wpipe[1] = MHD_INVALID_PIPE_; 3681#if HAVE_MESSAGES 3682 daemon->custom_error_log = (MHD_LogCallback) &vfprintf; 3683 daemon->custom_error_log_cls = stderr; 3684#endif 3685#ifdef HAVE_LISTEN_SHUTDOWN 3686 use_pipe = (0 != (daemon->options & (MHD_USE_NO_LISTEN_SOCKET | MHD_USE_PIPE_FOR_SHUTDOWN))); 3687#else 3688 use_pipe = 1; /* yes, must use pipe to signal shutdown */ 3689#endif 3690 if (0 == (flags & (MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION))) 3691 use_pipe = 0; /* useless if we are using 'external' select */ 3692 if ( (use_pipe) && (0 != MHD_pipe_ (daemon->wpipe)) ) 3693 { 3694#if HAVE_MESSAGES 3695 MHD_DLOG (daemon, 3696 "Failed to create control pipe: %s\n", 3697 MHD_strerror_ (errno)); 3698#endif 3699 free (daemon); 3700 return NULL; 3701 } 3702#ifndef WINDOWS 3703 if ( (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY))) && 3704 (1 == use_pipe) && 3705 (daemon->wpipe[0] >= FD_SETSIZE) ) 3706 { 3707#if HAVE_MESSAGES 3708 MHD_DLOG (daemon, 3709 "file descriptor for control pipe exceeds maximum value\n"); 3710#endif 3711 if (0 != MHD_pipe_close_ (daemon->wpipe[0])) 3712 MHD_PANIC ("close failed\n"); 3713 if (0 != MHD_pipe_close_ (daemon->wpipe[1])) 3714 MHD_PANIC ("close failed\n"); 3715 free (daemon); 3716 return NULL; 3717 } 3718#endif 3719#ifdef DAUTH_SUPPORT 3720 daemon->digest_auth_rand_size = 0; 3721 daemon->digest_auth_random = NULL; 3722 daemon->nonce_nc_size = 4; /* tiny */ 3723#endif 3724 3725 3726 if (MHD_YES != parse_options_va (daemon, &servaddr, ap)) 3727 { 3728 free (daemon); 3729 return NULL; 3730 } 3731#ifdef DAUTH_SUPPORT 3732 if (daemon->nonce_nc_size > 0) 3733 { 3734 if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc))) / 3735 sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size) 3736 { 3737#if HAVE_MESSAGES 3738 MHD_DLOG (daemon, 3739 "Specified value for NC_SIZE too large\n"); 3740#endif 3741 free (daemon); 3742 return NULL; 3743 } 3744 daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc)); 3745 if (NULL == daemon->nnc) 3746 { 3747#if HAVE_MESSAGES 3748 MHD_DLOG (daemon, 3749 "Failed to allocate memory for nonce-nc map: %s\n", 3750 MHD_strerror_ (errno)); 3751#endif 3752 free (daemon); 3753 return NULL; 3754 } 3755 } 3756 3757 if (MHD_YES != MHD_mutex_create_ (&daemon->nnc_lock)) 3758 { 3759#if HAVE_MESSAGES 3760 MHD_DLOG (daemon, 3761 "MHD failed to initialize nonce-nc mutex\n"); 3762#endif 3763 free (daemon->nnc); 3764 free (daemon); 3765 return NULL; 3766 } 3767#endif 3768 3769 /* Thread pooling currently works only with internal select thread model */ 3770 if ( (0 == (flags & MHD_USE_SELECT_INTERNALLY)) && 3771 (daemon->worker_pool_size > 0) ) 3772 { 3773#if HAVE_MESSAGES 3774 MHD_DLOG (daemon, 3775 "MHD thread pooling only works with MHD_USE_SELECT_INTERNALLY\n"); 3776#endif 3777 goto free_and_fail; 3778 } 3779 3780 if ( (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) && 3781 (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) ) 3782 { 3783#if HAVE_MESSAGES 3784 MHD_DLOG (daemon, 3785 "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_SUSPEND_RESUME is not supported.\n"); 3786#endif 3787 goto free_and_fail; 3788 } 3789 3790#ifdef __SYMBIAN32__ 3791 if (0 != (flags & (MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION))) 3792 { 3793#if HAVE_MESSAGES 3794 MHD_DLOG (daemon, 3795 "Threaded operations are not supported on Symbian.\n"); 3796#endif 3797 goto free_and_fail; 3798 } 3799#endif 3800 if ( (MHD_INVALID_SOCKET == daemon->socket_fd) && 3801 (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) ) 3802 { 3803 /* try to open listen socket */ 3804 if (0 != (flags & MHD_USE_IPv6)) 3805 socket_fd = create_socket (daemon, 3806 PF_INET6, SOCK_STREAM, 0); 3807 else 3808 socket_fd = create_socket (daemon, 3809 PF_INET, SOCK_STREAM, 0); 3810 if (MHD_INVALID_SOCKET == socket_fd) 3811 { 3812#if HAVE_MESSAGES 3813 MHD_DLOG (daemon, 3814 "Call to socket failed: %s\n", 3815 MHD_socket_last_strerr_ ()); 3816#endif 3817 goto free_and_fail; 3818 } 3819 3820 /* Apply the socket options according to listening_address_reuse. */ 3821 if (0 == daemon->listening_address_reuse) 3822 { 3823 /* No user requirement, use "traditional" default SO_REUSEADDR, 3824 and do not fail if it doesn't work */ 3825 if (0 > setsockopt (socket_fd, 3826 SOL_SOCKET, 3827 SO_REUSEADDR, 3828 (void*)&on, sizeof (on))) 3829 { 3830#if HAVE_MESSAGES 3831 MHD_DLOG (daemon, 3832 "setsockopt failed: %s\n", 3833 MHD_socket_last_strerr_ ()); 3834#endif 3835 } 3836 } 3837 else if (daemon->listening_address_reuse > 0) 3838 { 3839 /* User requested to allow reusing listening address:port. 3840 * Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms. 3841 * Fail if SO_REUSEPORT does not exist or setsockopt fails. 3842 */ 3843#ifdef _WIN32 3844 /* SO_REUSEADDR on W32 has the same semantics 3845 as SO_REUSEPORT on BSD/Linux */ 3846 if (0 > setsockopt (socket_fd, 3847 SOL_SOCKET, 3848 SO_REUSEADDR, 3849 (void*)&on, sizeof (on))) 3850 { 3851#if HAVE_MESSAGES 3852 MHD_DLOG (daemon, 3853 "setsockopt failed: %s\n", 3854 MHD_socket_last_strerr_ ()); 3855#endif 3856 goto free_and_fail; 3857 } 3858#else 3859#ifndef SO_REUSEPORT 3860#ifdef LINUX 3861/* Supported since Linux 3.9, but often not present (or commented out) 3862 in the headers at this time; but 15 is reserved for this and 3863 thus should be safe to use. */ 3864#define SO_REUSEPORT 15 3865#endif 3866#endif 3867#ifdef SO_REUSEPORT 3868 if (0 > setsockopt (socket_fd, 3869 SOL_SOCKET, 3870 SO_REUSEPORT, 3871 (void*)&on, sizeof (on))) 3872 { 3873#if HAVE_MESSAGES 3874 MHD_DLOG (daemon, 3875 "setsockopt failed: %s\n", 3876 MHD_socket_last_strerr_ ()); 3877#endif 3878 goto free_and_fail; 3879 } 3880#else 3881 /* we're supposed to allow address:port re-use, but 3882 on this platform we cannot; fail hard */ 3883#if HAVE_MESSAGES 3884 MHD_DLOG (daemon, 3885 "Cannot allow listening address reuse: SO_REUSEPORT not defined\n"); 3886#endif 3887 goto free_and_fail; 3888#endif 3889#endif 3890 } 3891 else /* if (daemon->listening_address_reuse < 0) */ 3892 { 3893 /* User requested to disallow reusing listening address:port. 3894 * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE 3895 * is used. Fail if it does not exist or setsockopt fails. 3896 */ 3897#ifdef _WIN32 3898#ifdef SO_EXCLUSIVEADDRUSE 3899 if (0 > setsockopt (socket_fd, 3900 SOL_SOCKET, 3901 SO_EXCLUSIVEADDRUSE, 3902 (void*)&on, sizeof (on))) 3903 { 3904#if HAVE_MESSAGES 3905 MHD_DLOG (daemon, 3906 "setsockopt failed: %s\n", 3907 MHD_socket_last_strerr_ ()); 3908#endif 3909 goto free_and_fail; 3910 } 3911#else /* SO_EXCLUSIVEADDRUSE not defined on W32? */ 3912#if HAVE_MESSAGES 3913 MHD_DLOG (daemon, 3914 "Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n"); 3915#endif 3916 goto free_and_fail; 3917#endif 3918#endif /* _WIN32 */ 3919 } 3920 3921 /* check for user supplied sockaddr */ 3922#if HAVE_INET6 3923 if (0 != (flags & MHD_USE_IPv6)) 3924 addrlen = sizeof (struct sockaddr_in6); 3925 else 3926#endif 3927 addrlen = sizeof (struct sockaddr_in); 3928 if (NULL == servaddr) 3929 { 3930#if HAVE_INET6 3931 if (0 != (flags & MHD_USE_IPv6)) 3932 { 3933 memset (&servaddr6, 0, sizeof (struct sockaddr_in6)); 3934 servaddr6.sin6_family = AF_INET6; 3935 servaddr6.sin6_port = htons (port); 3936#if HAVE_SOCKADDR_IN_SIN_LEN 3937 servaddr6.sin6_len = sizeof (struct sockaddr_in6); 3938#endif 3939 servaddr = (struct sockaddr *) &servaddr6; 3940 } 3941 else 3942#endif 3943 { 3944 memset (&servaddr4, 0, sizeof (struct sockaddr_in)); 3945 servaddr4.sin_family = AF_INET; 3946 servaddr4.sin_port = htons (port); 3947#if HAVE_SOCKADDR_IN_SIN_LEN 3948 servaddr4.sin_len = sizeof (struct sockaddr_in); 3949#endif 3950 servaddr = (struct sockaddr *) &servaddr4; 3951 } 3952 } 3953 daemon->socket_fd = socket_fd; 3954 3955 if (0 != (flags & MHD_USE_IPv6)) 3956 { 3957#ifdef IPPROTO_IPV6 3958#ifdef IPV6_V6ONLY 3959 /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options" 3960 (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx); 3961 and may also be missing on older POSIX systems; good luck if you have any of those, 3962 your IPv6 socket may then also bind against IPv4 anyway... */ 3963#ifndef WINDOWS 3964 const int 3965#else 3966 const char 3967#endif 3968 on = (MHD_USE_DUAL_STACK != (flags & MHD_USE_DUAL_STACK)); 3969 if (0 > setsockopt (socket_fd, 3970 IPPROTO_IPV6, IPV6_V6ONLY, 3971 &on, sizeof (on))) 3972 { 3973#if HAVE_MESSAGES 3974 MHD_DLOG (daemon, 3975 "setsockopt failed: %s\n", 3976 MHD_socket_last_strerr_ ()); 3977#endif 3978 } 3979#endif 3980#endif 3981 } 3982 if (-1 == bind (socket_fd, servaddr, addrlen)) 3983 { 3984#if HAVE_MESSAGES 3985 MHD_DLOG (daemon, 3986 "Failed to bind to port %u: %s\n", 3987 (unsigned int) port, 3988 MHD_socket_last_strerr_ ()); 3989#endif 3990 if (0 != MHD_socket_close_ (socket_fd)) 3991 MHD_PANIC ("close failed\n"); 3992 goto free_and_fail; 3993 } 3994#ifdef TCP_FASTOPEN 3995 if (0 != (flags & MHD_USE_TCP_FASTOPEN)) 3996 { 3997 if (0 == daemon->fastopen_queue_size) 3998 daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT; 3999 if (0 != setsockopt (socket_fd, 4000 IPPROTO_TCP, TCP_FASTOPEN, 4001 &daemon->fastopen_queue_size, 4002 sizeof (daemon->fastopen_queue_size))) 4003 { 4004#if HAVE_MESSAGES 4005 MHD_DLOG (daemon, 4006 "setsockopt failed: %s\n", 4007 MHD_socket_last_strerr_ ()); 4008#endif 4009 } 4010 } 4011#endif 4012#if EPOLL_SUPPORT 4013 if (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY)) 4014 { 4015 int sk_flags = fcntl (socket_fd, F_GETFL); 4016 if (0 != fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK)) 4017 { 4018#if HAVE_MESSAGES 4019 MHD_DLOG (daemon, 4020 "Failed to make listen socket non-blocking: %s\n", 4021 MHD_socket_last_strerr_ ()); 4022#endif 4023 if (0 != MHD_socket_close_ (socket_fd)) 4024 MHD_PANIC ("close failed\n"); 4025 goto free_and_fail; 4026 } 4027 } 4028#endif 4029 if (listen (socket_fd, 32) < 0) 4030 { 4031#if HAVE_MESSAGES 4032 MHD_DLOG (daemon, 4033 "Failed to listen for connections: %s\n", 4034 MHD_socket_last_strerr_ ()); 4035#endif 4036 if (0 != MHD_socket_close_ (socket_fd)) 4037 MHD_PANIC ("close failed\n"); 4038 goto free_and_fail; 4039 } 4040 } 4041 else 4042 { 4043 socket_fd = daemon->socket_fd; 4044 } 4045#ifndef WINDOWS 4046 if ( (socket_fd >= FD_SETSIZE) && 4047 (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY)) ) ) 4048 { 4049#if HAVE_MESSAGES 4050 MHD_DLOG (daemon, 4051 "Socket descriptor larger than FD_SETSIZE: %d > %d\n", 4052 socket_fd, 4053 FD_SETSIZE); 4054#endif 4055 if (0 != MHD_socket_close_ (socket_fd)) 4056 MHD_PANIC ("close failed\n"); 4057 goto free_and_fail; 4058 } 4059#endif 4060 4061#if EPOLL_SUPPORT 4062 if ( (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY)) && 4063 (0 == daemon->worker_pool_size) && 4064 (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) ) 4065 { 4066 if (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) 4067 { 4068#if HAVE_MESSAGES 4069 MHD_DLOG (daemon, 4070 "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL_LINUX_ONLY is not supported.\n"); 4071#endif 4072 goto free_and_fail; 4073 } 4074 if (MHD_YES != setup_epoll_to_listen (daemon)) 4075 goto free_and_fail; 4076 } 4077#else 4078 if (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY)) 4079 { 4080#if HAVE_MESSAGES 4081 MHD_DLOG (daemon, 4082 "epoll is not supported on this platform by this build.\n"); 4083#endif 4084 goto free_and_fail; 4085 } 4086#endif 4087 4088 if (MHD_YES != MHD_mutex_create_ (&daemon->per_ip_connection_mutex)) 4089 { 4090#if HAVE_MESSAGES 4091 MHD_DLOG (daemon, 4092 "MHD failed to initialize IP connection limit mutex\n"); 4093#endif 4094 if ( (MHD_INVALID_SOCKET != socket_fd) && 4095 (0 != MHD_socket_close_ (socket_fd)) ) 4096 MHD_PANIC ("close failed\n"); 4097 goto free_and_fail; 4098 } 4099 if (MHD_YES != MHD_mutex_create_ (&daemon->cleanup_connection_mutex)) 4100 { 4101#if HAVE_MESSAGES 4102 MHD_DLOG (daemon, 4103 "MHD failed to initialize IP connection limit mutex\n"); 4104#endif 4105 (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex); 4106 if ( (MHD_INVALID_SOCKET != socket_fd) && 4107 (0 != MHD_socket_close_ (socket_fd)) ) 4108 MHD_PANIC ("close failed\n"); 4109 goto free_and_fail; 4110 } 4111 4112#if HTTPS_SUPPORT 4113 /* initialize HTTPS daemon certificate aspects & send / recv functions */ 4114 if ((0 != (flags & MHD_USE_SSL)) && (0 != MHD_TLS_init (daemon))) 4115 { 4116#if HAVE_MESSAGES 4117 MHD_DLOG (daemon, 4118 "Failed to initialize TLS support\n"); 4119#endif 4120 if ( (MHD_INVALID_SOCKET != socket_fd) && 4121 (0 != MHD_socket_close_ (socket_fd)) ) 4122 MHD_PANIC ("close failed\n"); 4123 (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex); 4124 (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex); 4125 goto free_and_fail; 4126 } 4127#endif 4128 if ( ( (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) || 4129 ( (0 != (flags & MHD_USE_SELECT_INTERNALLY)) && 4130 (0 == daemon->worker_pool_size)) ) && 4131 (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) && 4132 (0 != (res_thread_create = 4133 create_thread (&daemon->pid, daemon, &MHD_select_thread, daemon)))) 4134 { 4135#if HAVE_MESSAGES 4136 MHD_DLOG (daemon, 4137 "Failed to create listen thread: %s\n", 4138 MHD_strerror_ (res_thread_create)); 4139#endif 4140 (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex); 4141 (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex); 4142 if ( (MHD_INVALID_SOCKET != socket_fd) && 4143 (0 != MHD_socket_close_ (socket_fd)) ) 4144 MHD_PANIC ("close failed\n"); 4145 goto free_and_fail; 4146 } 4147 if ( (daemon->worker_pool_size > 0) && 4148 (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) ) 4149 { 4150#if !defined(WINDOWS) || defined(CYGWIN) 4151 int sk_flags; 4152#else 4153 unsigned long sk_flags; 4154#endif 4155 4156 /* Coarse-grained count of connections per thread (note error 4157 * due to integer division). Also keep track of how many 4158 * connections are leftover after an equal split. */ 4159 unsigned int conns_per_thread = daemon->connection_limit 4160 / daemon->worker_pool_size; 4161 unsigned int leftover_conns = daemon->connection_limit 4162 % daemon->worker_pool_size; 4163 4164 i = 0; /* we need this in case fcntl or malloc fails */ 4165 4166 /* Accept must be non-blocking. Multiple children may wake up 4167 * to handle a new connection, but only one will win the race. 4168 * The others must immediately return. */ 4169#if !defined(WINDOWS) || defined(CYGWIN) 4170 sk_flags = fcntl (socket_fd, F_GETFL); 4171 if (sk_flags < 0) 4172 goto thread_failed; 4173 if (0 != fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK)) 4174 goto thread_failed; 4175#else 4176 sk_flags = 1; 4177 if (SOCKET_ERROR == ioctlsocket (socket_fd, FIONBIO, &sk_flags)) 4178 goto thread_failed; 4179#endif /* WINDOWS && !CYGWIN */ 4180 4181 /* Allocate memory for pooled objects */ 4182 daemon->worker_pool = malloc (sizeof (struct MHD_Daemon) 4183 * daemon->worker_pool_size); 4184 if (NULL == daemon->worker_pool) 4185 goto thread_failed; 4186 4187 /* Start the workers in the pool */ 4188 for (i = 0; i < daemon->worker_pool_size; ++i) 4189 { 4190 /* Create copy of the Daemon object for each worker */ 4191 struct MHD_Daemon *d = &daemon->worker_pool[i]; 4192 4193 memcpy (d, daemon, sizeof (struct MHD_Daemon)); 4194 /* Adjust pooling params for worker daemons; note that memcpy() 4195 has already copied MHD_USE_SELECT_INTERNALLY thread model into 4196 the worker threads. */ 4197 d->master = daemon; 4198 d->worker_pool_size = 0; 4199 d->worker_pool = NULL; 4200 4201 if ( (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) && 4202 (0 != MHD_pipe_ (d->wpipe)) ) 4203 { 4204#if HAVE_MESSAGES 4205 MHD_DLOG (daemon, 4206 "Failed to create worker control pipe: %s\n", 4207 MHD_pipe_last_strerror_() ); 4208#endif 4209 goto thread_failed; 4210 } 4211#ifndef WINDOWS 4212 if ( (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY))) && 4213 (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) && 4214 (d->wpipe[0] >= FD_SETSIZE) ) 4215 { 4216#if HAVE_MESSAGES 4217 MHD_DLOG (daemon, 4218 "file descriptor for worker control pipe exceeds maximum value\n"); 4219#endif 4220 if (0 != MHD_pipe_close_ (d->wpipe[0])) 4221 MHD_PANIC ("close failed\n"); 4222 if (0 != MHD_pipe_close_ (d->wpipe[1])) 4223 MHD_PANIC ("close failed\n"); 4224 goto thread_failed; 4225 } 4226#endif 4227 4228 /* Divide available connections evenly amongst the threads. 4229 * Thread indexes in [0, leftover_conns) each get one of the 4230 * leftover connections. */ 4231 d->connection_limit = conns_per_thread; 4232 if (i < leftover_conns) 4233 ++d->connection_limit; 4234#if EPOLL_SUPPORT 4235 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && 4236 (MHD_YES != setup_epoll_to_listen (d)) ) 4237 goto thread_failed; 4238#endif 4239 /* Must init cleanup connection mutex for each worker */ 4240 if (MHD_YES != MHD_mutex_create_ (&d->cleanup_connection_mutex)) 4241 { 4242#if HAVE_MESSAGES 4243 MHD_DLOG (daemon, 4244 "MHD failed to initialize cleanup connection mutex for thread worker %d\n", i); 4245#endif 4246 goto thread_failed; 4247 } 4248 4249 /* Spawn the worker thread */ 4250 if (0 != (res_thread_create = 4251 create_thread (&d->pid, daemon, &MHD_select_thread, d))) 4252 { 4253#if HAVE_MESSAGES 4254 MHD_DLOG (daemon, 4255 "Failed to create pool thread: %s\n", 4256 MHD_strerror_ (res_thread_create)); 4257#endif 4258 /* Free memory for this worker; cleanup below handles 4259 * all previously-created workers. */ 4260 (void) MHD_mutex_destroy_ (&d->cleanup_connection_mutex); 4261 goto thread_failed; 4262 } 4263 } 4264 } 4265#if HTTPS_SUPPORT 4266 /* API promises to never use the password after initialization, 4267 so we additionally NULL it here to not deref a dangling pointer. */ 4268 daemon->https_key_password = NULL; 4269#endif /* HTTPS_SUPPORT */ 4270 4271 return daemon; 4272 4273thread_failed: 4274 /* If no worker threads created, then shut down normally. Calling 4275 MHD_stop_daemon (as we do below) doesn't work here since it 4276 assumes a 0-sized thread pool means we had been in the default 4277 MHD_USE_SELECT_INTERNALLY mode. */ 4278 if (0 == i) 4279 { 4280 if ( (MHD_INVALID_SOCKET != socket_fd) && 4281 (0 != MHD_socket_close_ (socket_fd)) ) 4282 MHD_PANIC ("close failed\n"); 4283 (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex); 4284 (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex); 4285 if (NULL != daemon->worker_pool) 4286 free (daemon->worker_pool); 4287 goto free_and_fail; 4288 } 4289 4290 /* Shutdown worker threads we've already created. Pretend 4291 as though we had fully initialized our daemon, but 4292 with a smaller number of threads than had been 4293 requested. */ 4294 daemon->worker_pool_size = i; 4295 MHD_stop_daemon (daemon); 4296 return NULL; 4297 4298 free_and_fail: 4299 /* clean up basic memory state in 'daemon' and return NULL to 4300 indicate failure */ 4301#if EPOLL_SUPPORT 4302 if (-1 != daemon->epoll_fd) 4303 close (daemon->epoll_fd); 4304#endif 4305#ifdef DAUTH_SUPPORT 4306 free (daemon->nnc); 4307 (void) MHD_mutex_destroy_ (&daemon->nnc_lock); 4308#endif 4309 free (daemon); 4310 return NULL; 4311} 4312 4313 4314/** 4315 * Close the given connection, remove it from all of its 4316 * DLLs and move it into the cleanup queue. 4317 * 4318 * @param pos connection to move to cleanup 4319 */ 4320static void 4321close_connection (struct MHD_Connection *pos) 4322{ 4323 struct MHD_Daemon *daemon = pos->daemon; 4324 4325 MHD_connection_close (pos, 4326 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN); 4327 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 4328 return; /* must let thread to the rest */ 4329 if (pos->connection_timeout == pos->daemon->connection_timeout) 4330 XDLL_remove (daemon->normal_timeout_head, 4331 daemon->normal_timeout_tail, 4332 pos); 4333 else 4334 XDLL_remove (daemon->manual_timeout_head, 4335 daemon->manual_timeout_tail, 4336 pos); 4337 DLL_remove (daemon->connections_head, 4338 daemon->connections_tail, 4339 pos); 4340 pos->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP; 4341 DLL_insert (daemon->cleanup_head, 4342 daemon->cleanup_tail, 4343 pos); 4344} 4345 4346 4347/** 4348 * Close all connections for the daemon; must only be called after 4349 * all of the threads have been joined and there is no more concurrent 4350 * activity on the connection lists. 4351 * 4352 * @param daemon daemon to close down 4353 */ 4354static void 4355close_all_connections (struct MHD_Daemon *daemon) 4356{ 4357 struct MHD_Connection *pos; 4358 4359 /* first, make sure all threads are aware of shutdown; need to 4360 traverse DLLs in peace... */ 4361 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 4362 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) ) 4363 MHD_PANIC ("Failed to acquire cleanup mutex\n"); 4364 for (pos = daemon->connections_head; NULL != pos; pos = pos->next) 4365 { 4366 shutdown (pos->socket_fd, 4367 (pos->read_closed == MHD_YES) ? SHUT_WR : SHUT_RDWR); 4368#if WINDOWS 4369 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 4370 (MHD_INVALID_PIPE_ != daemon->wpipe[1]) && 4371 (1 != MHD_pipe_write_ (daemon->wpipe[1], "e", 1)) ) 4372 MHD_PANIC ("failed to signal shutdown via pipe"); 4373#endif 4374 } 4375 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 4376 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) ) 4377 MHD_PANIC ("Failed to release cleanup mutex\n"); 4378 4379 /* now, collect threads from thread pool */ 4380 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 4381 { 4382 for (pos = daemon->connections_head; NULL != pos; pos = pos->next) 4383 { 4384 if (0 != MHD_join_thread_ (pos->pid)) 4385 MHD_PANIC ("Failed to join a thread\n"); 4386 pos->thread_joined = MHD_YES; 4387 } 4388 } 4389 4390 /* now that we're alone, move everyone to cleanup */ 4391 while (NULL != (pos = daemon->connections_head)) 4392 close_connection (pos); 4393 MHD_cleanup_connections (daemon); 4394} 4395 4396 4397#if EPOLL_SUPPORT 4398/** 4399 * Shutdown epoll()-event loop by adding 'wpipe' to its event set. 4400 * 4401 * @param daemon daemon of which the epoll() instance must be signalled 4402 */ 4403static void 4404epoll_shutdown (struct MHD_Daemon *daemon) 4405{ 4406 struct epoll_event event; 4407 4408 if (MHD_INVALID_PIPE_ == daemon->wpipe[1]) 4409 { 4410 /* wpipe was required in this mode, how could this happen? */ 4411 MHD_PANIC ("Internal error\n"); 4412 } 4413 event.events = EPOLLOUT; 4414 event.data.ptr = NULL; 4415 if (0 != epoll_ctl (daemon->epoll_fd, 4416 EPOLL_CTL_ADD, 4417 daemon->wpipe[1], 4418 &event)) 4419 MHD_PANIC ("Failed to add wpipe to epoll set to signal termination\n"); 4420} 4421#endif 4422 4423 4424/** 4425 * Shutdown an HTTP daemon. 4426 * 4427 * @param daemon daemon to stop 4428 * @ingroup event 4429 */ 4430void 4431MHD_stop_daemon (struct MHD_Daemon *daemon) 4432{ 4433 MHD_socket fd; 4434 unsigned int i; 4435 4436 if (NULL == daemon) 4437 return; 4438 daemon->shutdown = MHD_YES; 4439 fd = daemon->socket_fd; 4440 daemon->socket_fd = MHD_INVALID_SOCKET; 4441 /* Prepare workers for shutdown */ 4442 if (NULL != daemon->worker_pool) 4443 { 4444 /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */ 4445 for (i = 0; i < daemon->worker_pool_size; ++i) 4446 { 4447 daemon->worker_pool[i].shutdown = MHD_YES; 4448 daemon->worker_pool[i].socket_fd = MHD_INVALID_SOCKET; 4449#if EPOLL_SUPPORT 4450 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && 4451 (-1 != daemon->worker_pool[i].epoll_fd) && 4452 (MHD_INVALID_SOCKET == fd) ) 4453 epoll_shutdown (&daemon->worker_pool[i]); 4454#endif 4455 } 4456 } 4457 if (MHD_INVALID_PIPE_ != daemon->wpipe[1]) 4458 { 4459 if (1 != MHD_pipe_write_ (daemon->wpipe[1], "e", 1)) 4460 MHD_PANIC ("failed to signal shutdown via pipe"); 4461 } 4462#ifdef HAVE_LISTEN_SHUTDOWN 4463 else 4464 { 4465 /* fd might be MHD_INVALID_SOCKET here due to 'MHD_quiesce_daemon' */ 4466 if (MHD_INVALID_SOCKET != fd) 4467 (void) shutdown (fd, SHUT_RDWR); 4468 } 4469#endif 4470#if EPOLL_SUPPORT 4471 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && 4472 (-1 != daemon->epoll_fd) && 4473 (MHD_INVALID_SOCKET == fd) ) 4474 epoll_shutdown (daemon); 4475#endif 4476 4477#if DEBUG_CLOSE 4478#if HAVE_MESSAGES 4479 MHD_DLOG (daemon, 4480 "MHD listen socket shutdown\n"); 4481#endif 4482#endif 4483 4484 4485 /* Signal workers to stop and clean them up */ 4486 if (NULL != daemon->worker_pool) 4487 { 4488 /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */ 4489 for (i = 0; i < daemon->worker_pool_size; ++i) 4490 { 4491 if (MHD_INVALID_PIPE_ != daemon->worker_pool[i].wpipe[1]) 4492 { 4493 if (1 != MHD_pipe_write_ (daemon->worker_pool[i].wpipe[1], "e", 1)) 4494 MHD_PANIC ("failed to signal shutdown via pipe"); 4495 } 4496 if (0 != MHD_join_thread_ (daemon->worker_pool[i].pid)) 4497 MHD_PANIC ("Failed to join a thread\n"); 4498 close_all_connections (&daemon->worker_pool[i]); 4499 (void) MHD_mutex_destroy_ (&daemon->worker_pool[i].cleanup_connection_mutex); 4500#if EPOLL_SUPPORT 4501 if ( (-1 != daemon->worker_pool[i].epoll_fd) && 4502 (0 != MHD_socket_close_ (daemon->worker_pool[i].epoll_fd)) ) 4503 MHD_PANIC ("close failed\n"); 4504#endif 4505 if ( (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) ) 4506 { 4507 if (MHD_INVALID_PIPE_ != daemon->worker_pool[i].wpipe[1]) 4508 { 4509 if (0 != MHD_pipe_close_ (daemon->worker_pool[i].wpipe[0])) 4510 MHD_PANIC ("close failed\n"); 4511 if (0 != MHD_pipe_close_ (daemon->worker_pool[i].wpipe[1])) 4512 MHD_PANIC ("close failed\n"); 4513 } 4514 } 4515 } 4516 free (daemon->worker_pool); 4517 } 4518 else 4519 { 4520 /* clean up master threads */ 4521 if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || 4522 ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) 4523 && (0 == daemon->worker_pool_size))) 4524 { 4525 if (0 != MHD_join_thread_ (daemon->pid)) 4526 { 4527 MHD_PANIC ("Failed to join a thread\n"); 4528 } 4529 } 4530 } 4531 close_all_connections (daemon); 4532 if ( (MHD_INVALID_SOCKET != fd) && 4533 (0 != MHD_socket_close_ (fd)) ) 4534 MHD_PANIC ("close failed\n"); 4535 4536 /* TLS clean up */ 4537#if HTTPS_SUPPORT 4538 if (0 != (daemon->options & MHD_USE_SSL)) 4539 { 4540 MHD_TLS_deinit (daemon); 4541 } 4542#endif 4543#if EPOLL_SUPPORT 4544 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && 4545 (-1 != daemon->epoll_fd) && 4546 (0 != MHD_socket_close_ (daemon->epoll_fd)) ) 4547 MHD_PANIC ("close failed\n"); 4548#endif 4549 4550#ifdef DAUTH_SUPPORT 4551 free (daemon->nnc); 4552 (void) MHD_mutex_destroy_ (&daemon->nnc_lock); 4553#endif 4554 (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex); 4555 (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex); 4556 4557 if (MHD_INVALID_PIPE_ != daemon->wpipe[1]) 4558 { 4559 if (0 != MHD_pipe_close_ (daemon->wpipe[0])) 4560 MHD_PANIC ("close failed\n"); 4561 if (0 != MHD_pipe_close_ (daemon->wpipe[1])) 4562 MHD_PANIC ("close failed\n"); 4563 } 4564 free (daemon); 4565} 4566 4567 4568/** 4569 * Obtain information about the given daemon 4570 * (not fully implemented!). 4571 * 4572 * @param daemon what daemon to get information about 4573 * @param info_type what information is desired? 4574 * @param ... depends on @a info_type 4575 * @return NULL if this information is not available 4576 * (or if the @a info_type is unknown) 4577 * @ingroup specialized 4578 */ 4579const union MHD_DaemonInfo * 4580MHD_get_daemon_info (struct MHD_Daemon *daemon, 4581 enum MHD_DaemonInfoType info_type, 4582 ...) 4583{ 4584 switch (info_type) 4585 { 4586 case MHD_DAEMON_INFO_KEY_SIZE: 4587 return NULL; /* no longer supported */ 4588 case MHD_DAEMON_INFO_MAC_KEY_SIZE: 4589 return NULL; /* no longer supported */ 4590 case MHD_DAEMON_INFO_LISTEN_FD: 4591 return (const union MHD_DaemonInfo *) &daemon->socket_fd; 4592#if EPOLL_SUPPORT 4593 case MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY: 4594 return (const union MHD_DaemonInfo *) &daemon->epoll_fd; 4595#endif 4596 case MHD_DAEMON_INFO_CURRENT_CONNECTIONS: 4597 MHD_cleanup_connections (daemon); 4598 if (daemon->worker_pool) 4599 { 4600 /* Collect the connection information stored in the workers. */ 4601 unsigned int i; 4602 4603 daemon->connections = 0; 4604 for (i=0;i<daemon->worker_pool_size;i++) 4605 { 4606 MHD_cleanup_connections (&daemon->worker_pool[i]); 4607 daemon->connections += daemon->worker_pool[i].connections; 4608 } 4609 } 4610 return (const union MHD_DaemonInfo *) &daemon->connections; 4611 default: 4612 return NULL; 4613 }; 4614} 4615 4616 4617/** 4618 * Sets the global error handler to a different implementation. @a cb 4619 * will only be called in the case of typically fatal, serious 4620 * internal consistency issues. These issues should only arise in the 4621 * case of serious memory corruption or similar problems with the 4622 * architecture. While @a cb is allowed to return and MHD will then 4623 * try to continue, this is never safe. 4624 * 4625 * The default implementation that is used if no panic function is set 4626 * simply prints an error message and calls `abort()`. Alternative 4627 * implementations might call `exit()` or other similar functions. 4628 * 4629 * @param cb new error handler 4630 * @param cls passed to @a cb 4631 * @ingroup logging 4632 */ 4633void 4634MHD_set_panic_func (MHD_PanicCallback cb, void *cls) 4635{ 4636 mhd_panic = cb; 4637 mhd_panic_cls = cls; 4638} 4639 4640 4641/** 4642 * Obtain the version of this library 4643 * 4644 * @return static version string, e.g. "0.9.9" 4645 * @ingroup specialized 4646 */ 4647const char * 4648MHD_get_version (void) 4649{ 4650#ifdef PACKAGE_VERSION 4651 return PACKAGE_VERSION; 4652#else /* !PACKAGE_VERSION */ 4653 static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0"; 4654 if (0 == ver[0]) 4655 { 4656 int res = MHD_snprintf_(ver, sizeof(ver), "%x.%x.%x", 4657 (((int)MHD_VERSION >> 24) & 0xFF), 4658 (((int)MHD_VERSION >> 16) & 0xFF), 4659 (((int)MHD_VERSION >> 8) & 0xFF)); 4660 if (0 >= res || sizeof(ver) <= res) 4661 return "0.0.0"; /* Can't return real version*/ 4662 } 4663 return ver; 4664#endif /* !PACKAGE_VERSION */ 4665} 4666 4667 4668/** 4669 * Get information about supported MHD features. 4670 * Indicate that MHD was compiled with or without support for 4671 * particular feature. Some features require additional support 4672 * by kernel. Kernel support is not checked by this function. 4673 * 4674 * @param feature type of requested information 4675 * @return #MHD_YES if feature is supported by MHD, #MHD_NO if 4676 * feature is not supported or feature is unknown. 4677 * @ingroup specialized 4678 */ 4679_MHD_EXTERN int 4680MHD_is_feature_supported(enum MHD_FEATURE feature) 4681{ 4682 switch(feature) 4683 { 4684 case MHD_FEATURE_MESSGES: 4685#if HAVE_MESSAGES 4686 return MHD_YES; 4687#else 4688 return MHD_NO; 4689#endif 4690 case MHD_FEATURE_SSL: 4691#if HTTPS_SUPPORT 4692 return MHD_YES; 4693#else 4694 return MHD_NO; 4695#endif 4696 case MHD_FEATURE_HTTPS_CERT_CALLBACK: 4697 return MHD_NO; 4698 case MHD_FEATURE_IPv6: 4699#ifdef HAVE_INET6 4700 return MHD_YES; 4701#else 4702 return MHD_NO; 4703#endif 4704 case MHD_FEATURE_IPv6_ONLY: 4705#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) 4706 return MHD_YES; 4707#else 4708 return MHD_NO; 4709#endif 4710 case MHD_FEATURE_POLL: 4711#ifdef HAVE_POLL 4712 return MHD_YES; 4713#else 4714 return MHD_NO; 4715#endif 4716 case MHD_FEATURE_EPOLL: 4717#if EPOLL_SUPPORT 4718 return MHD_YES; 4719#else 4720 return MHD_NO; 4721#endif 4722 case MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET: 4723#ifdef HAVE_LISTEN_SHUTDOWN 4724 return MHD_YES; 4725#else 4726 return MHD_NO; 4727#endif 4728 case MHD_FEATURE_SOCKETPAIR: 4729#ifdef MHD_DONT_USE_PIPES 4730 return MHD_YES; 4731#else 4732 return MHD_NO; 4733#endif 4734 case MHD_FEATURE_TCP_FASTOPEN: 4735#ifdef TCP_FASTOPEN 4736 return MHD_YES; 4737#else 4738 return MHD_NO; 4739#endif 4740 case MHD_FEATURE_BASIC_AUTH: 4741#if BAUTH_SUPPORT 4742 return MHD_YES; 4743#else 4744 return MHD_NO; 4745#endif 4746 case MHD_FEATURE_DIGEST_AUTH: 4747#if DAUTH_SUPPORT 4748 return MHD_YES; 4749#else 4750 return MHD_NO; 4751#endif 4752 case MHD_FEATURE_POSTPROCESSOR: 4753#if HAVE_POSTPROCESSOR 4754 return MHD_YES; 4755#else 4756 return MHD_NO; 4757#endif 4758 case MHD_FEATURE_HTTPS_KEY_PASSWORD: 4759#if HTTPS_SUPPORT 4760 return MHD_YES; 4761#else 4762 return MHD_NO; 4763#endif 4764 } 4765 return MHD_NO; 4766} 4767 4768 4769/** 4770 * Initialize do setup work. 4771 */ 4772void MHD_init(void) 4773{ 4774 mhd_panic = &mhd_panic_std; 4775 mhd_panic_cls = NULL; 4776 4777#ifdef _WIN32 4778 WSADATA wsd; 4779 if (0 != WSAStartup(MAKEWORD(2, 2), &wsd)) 4780 MHD_PANIC ("Failed to initialize winsock\n"); 4781 mhd_winsock_inited_ = 1; 4782 if (2 != LOBYTE(wsd.wVersion) && 2 != HIBYTE(wsd.wVersion)) 4783 MHD_PANIC ("Winsock version 2.2 is not available\n"); 4784#endif 4785#if HTTPS_SUPPORT 4786 SSL_library_init(); 4787#endif 4788} 4789 4790 4791void MHD_fini(void) 4792{ 4793#ifdef _WIN32 4794 if (mhd_winsock_inited_) 4795 WSACleanup(); 4796#endif 4797} 4798 4799_SET_INIT_AND_DEINIT_FUNCS(MHD_init, MHD_fini); 4800 4801/* end of daemon.c */ 4802