29 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 30 #include "mhd_threads.h" 39 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 40 #include "mhd_locks.h" 54 #ifdef MHD_HTTPS_REQUIRE_GRYPT 59 #if defined(_WIN32) && ! defined(__CYGWIN__) 60 #ifndef WIN32_LEAN_AND_MEAN 61 #define WIN32_LEAN_AND_MEAN 1 69 #ifdef MHD_POSIX_SOCKETS 70 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 4) 72 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 2) 78 #define MHD_POOL_SIZE_DEFAULT (32 * 1024) 84 #define DEBUG_CLOSE MHD_NO 90 #define DEBUG_CONNECT MHD_NO 140 _ (
"Fatal error in GNU libmicrohttpd %s:%u: %s\n"),
170 #if defined(MHD_WINSOCK_SOCKETS) 174 static int mhd_winsock_inited_ = 0;
177 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED 182 #define MHD_check_global_init_() (void) 0 189 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 190 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 194 MHD_MUTEX_STATIC_DEFN_INIT_ (global_init_mutex_);
206 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 207 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 213 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 214 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 230 vfprintf ((FILE*) cls, fm, ap);
232 fflush ((FILE*) cls);
291 struct in6_addr ipv6;
310 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 326 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 349 offsetof (
struct MHD_IPCount,
365 struct MHD_IPCount *key)
372 if (
sizeof (
struct sockaddr_in) == addrlen)
374 const struct sockaddr_in *addr4 = (
const struct sockaddr_in*) addr;
376 key->family = AF_INET;
377 memcpy (&key->addr.ipv4,
379 sizeof(addr4->sin_addr));
385 if (
sizeof (
struct sockaddr_in6) == addrlen)
387 const struct sockaddr_in6 *addr6 = (
const struct sockaddr_in6*) addr;
389 key->family = AF_INET6;
390 memcpy (&key->addr.ipv6,
392 sizeof(addr6->sin6_addr));
415 const struct sockaddr *addr,
418 struct MHD_IPCount *key;
428 if (
NULL == (key = malloc (
sizeof(*key))))
449 _ (
"Failed to add IP connection count node\n"));
459 key = (
struct MHD_IPCount *) node;
481 const struct sockaddr *addr,
484 struct MHD_IPCount search_key;
485 struct MHD_IPCount *found_key;
507 MHD_PANIC (
_ (
"Failed to find previously-added IP address\n"));
509 found_key = (
struct MHD_IPCount *) *nodep;
511 if (0 == found_key->count)
513 MHD_PANIC (
_ (
"Previously-added IP address had counter of zero\n"));
516 if (0 == --found_key->count)
536 MHD_init_daemon_certificate (
struct MHD_Daemon *daemon)
542 #if GNUTLS_VERSION_MAJOR >= 3 543 if (
NULL != daemon->cert_callback)
545 gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
546 daemon->cert_callback);
549 #if GNUTLS_VERSION_NUMBER >= 0x030603 550 else if (
NULL != daemon->cert_callback2)
552 gnutls_certificate_set_retrieve_function3 (daemon->x509_cred,
553 daemon->cert_callback2);
557 if (
NULL != daemon->https_mem_trust)
560 paramlen = strlen (daemon->https_mem_trust);
565 "Too long trust certificate\n");
569 cert.data = (
unsigned char *) daemon->https_mem_trust;
570 cert.size = (
unsigned int) paramlen;
571 if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred,
573 GNUTLS_X509_FMT_PEM) < 0)
577 "Bad trust certificate format\n");
583 if (daemon->have_dhparams)
585 gnutls_certificate_set_dh_params (daemon->x509_cred,
586 daemon->https_mem_dhparams);
589 if ( (
NULL != daemon->https_mem_cert) &&
590 (
NULL != daemon->https_mem_key) )
595 param1len = strlen (daemon->https_mem_key);
596 param2len = strlen (daemon->https_mem_cert);
602 "Too long key or certificate\n");
606 key.data = (
unsigned char *) daemon->https_mem_key;
607 key.size = (
unsigned int) param1len;
608 cert.data = (
unsigned char *) daemon->https_mem_cert;
609 cert.size = (
unsigned int) param2len;
611 if (
NULL != daemon->https_key_password)
613 #if GNUTLS_VERSION_NUMBER >= 0x030111 614 ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
618 daemon->https_key_password,
623 _ (
"Failed to setup x509 certificate/key: pre 3.X.X version " \
624 "of GnuTLS does not support setting key password"));
630 ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
633 GNUTLS_X509_FMT_PEM);
637 "GnuTLS failed to setup x509 certificate/key: %s\n",
638 gnutls_strerror (ret));
642 #if GNUTLS_VERSION_MAJOR >= 3 643 if (
NULL != daemon->cert_callback)
646 #if GNUTLS_VERSION_NUMBER >= 0x030603 647 else if (
NULL != daemon->cert_callback2)
652 "You need to specify a certificate and key location\n");
666 switch (daemon->cred_type)
668 case GNUTLS_CRD_CERTIFICATE:
670 gnutls_certificate_allocate_credentials (&daemon->x509_cred))
671 return GNUTLS_E_MEMORY_ERROR;
672 return MHD_init_daemon_certificate (daemon);
675 gnutls_psk_allocate_server_credentials (&daemon->psk_cred))
676 return GNUTLS_E_MEMORY_ERROR;
681 _ (
"Error: invalid credentials type %d specified.\n"),
724 fd_set *write_fd_set,
725 fd_set *except_fd_set,
737 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 751 urh_to_fdset (
struct MHD_UpgradeResponseHandle *urh,
756 unsigned int fd_setsize)
758 const MHD_socket conn_sckt = urh->connection->socket_fd;
766 if ( (urh->in_buffer_used < urh->in_buffer_size) &&
772 if ( (0 != urh->out_buffer_used) &&
781 ((0 != urh->in_buffer_size) ||
782 (0 != urh->out_buffer_size) ||
783 (0 != urh->out_buffer_used)))
791 if ( (urh->out_buffer_used < urh->out_buffer_size) &&
797 if ( (0 != urh->in_buffer_used) &&
806 ((0 != urh->out_buffer_size) ||
807 (0 != urh->in_buffer_size) ||
808 (0 != urh->in_buffer_used)))
829 urh_from_fdset (
struct MHD_UpgradeResponseHandle *urh,
834 const MHD_socket conn_sckt = urh->connection->socket_fd;
843 if (FD_ISSET (conn_sckt, rs))
845 if (FD_ISSET (conn_sckt, ws))
847 if (FD_ISSET (conn_sckt, es))
852 if (FD_ISSET (mhd_sckt, rs))
854 if (FD_ISSET (mhd_sckt, ws))
856 if (FD_ISSET (mhd_sckt, es))
872 urh_update_pollfd (
struct MHD_UpgradeResponseHandle *urh,
878 if (urh->in_buffer_used < urh->in_buffer_size)
879 p[0].events |= POLLIN;
880 if (0 != urh->out_buffer_used)
881 p[0].events |= POLLOUT;
886 ((0 != urh->in_buffer_size) ||
887 (0 != urh->out_buffer_size) ||
888 (0 != urh->out_buffer_used)))
889 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
891 if (urh->out_buffer_used < urh->out_buffer_size)
892 p[1].events |= POLLIN;
893 if (0 != urh->in_buffer_used)
894 p[1].events |= POLLOUT;
899 ((0 != urh->out_buffer_size) ||
900 (0 != urh->in_buffer_size) ||
901 (0 != urh->in_buffer_used)))
902 p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
913 urh_to_pollfd (
struct MHD_UpgradeResponseHandle *urh,
916 p[0].fd = urh->connection->socket_fd;
917 p[1].fd = urh->mhd.socket;
918 urh_update_pollfd (urh,
929 urh_from_pollfd (
struct MHD_UpgradeResponseHandle *urh,
936 if (0 != (p[0].revents & POLLIN))
938 if (0 != (p[0].revents & POLLOUT))
940 if (0 != (p[0].revents & POLLHUP))
942 if (0 != (p[0].revents & MHD_POLL_REVENTS_ERRROR))
944 if (0 != (p[1].revents & POLLIN))
946 if (0 != (p[1].revents & POLLOUT))
948 if (0 != (p[1].revents & POLLHUP))
950 if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
974 fd_set *write_fd_set,
975 fd_set *except_fd_set,
977 unsigned int fd_setsize)
1013 #ifdef MHD_POSIX_SOCKETS 1026 #ifdef MHD_POSIX_SOCKETS 1034 if ( (
NULL == except_fd_set) ||
1046 #ifdef MHD_WINSOCK_SOCKETS 1059 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 1061 struct MHD_UpgradeResponseHandle *urh;
1063 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
1077 #ifdef HAVE_MESSAGES 1080 _ (
"Maximum socket in select set: %d\n"),
1122 fd_set *read_fd_set,
1123 fd_set *write_fd_set,
1124 fd_set *except_fd_set,
1126 unsigned int fd_setsize)
1130 if ( (
NULL == daemon) ||
1131 (
NULL == read_fd_set) ||
1132 (
NULL == write_fd_set) ||
1137 if (
NULL == except_fd_set)
1139 #ifdef HAVE_MESSAGES 1141 _ (
"MHD_get_fdset2() called with except_fd_set " 1142 "set to NULL. Such behavior is unsupported.\n"));
1145 except_fd_set = &es;
1148 #ifdef EPOLL_SUPPORT 1193 bool states_info_processed =
false;
1197 #ifdef HTTPS_SUPPORT 1208 states_info_processed =
true;
1217 states_info_processed =
true;
1227 if (! states_info_processed)
1274 #ifdef HTTPS_SUPPORT 1284 #ifdef UPGRADE_SUPPORT 1295 struct MHD_UpgradeResponseHandle *urh = connection->urh;
1299 #ifdef HTTPS_SUPPORT 1303 gnutls_bye (connection->tls_session,
1312 connection->urh =
NULL;
1318 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 1328 process_urh (
struct MHD_UpgradeResponseHandle *urh)
1343 #ifdef HAVE_MESSAGES 1344 if (! urh->was_closed)
1348 "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
1351 urh->was_closed =
true;
1353 was_closed = urh->was_closed;
1358 if (0 < urh->in_buffer_used)
1360 #ifdef HAVE_MESSAGES 1363 "Failed to forward to application " 1365 " bytes of data received from remote side: application shut down socket\n"),
1375 if (0 != urh->out_buffer_size)
1378 urh->in_buffer_used = 0;
1382 urh->in_buffer_size = 0;
1405 (urh->in_buffer_used < urh->in_buffer_size) )
1410 buf_size = urh->in_buffer_size - urh->in_buffer_used;
1415 res = gnutls_record_recv (connection->tls_session,
1416 &urh->in_buffer[urh->in_buffer_used],
1420 if (GNUTLS_E_INTERRUPTED != res)
1423 if (GNUTLS_E_AGAIN != res)
1428 urh->in_buffer_size = 0;
1434 urh->in_buffer_used += res;
1435 if (buf_size > (
size_t) res)
1437 else if (0 < gnutls_record_check_pending (connection->tls_session))
1446 urh->in_buffer_size = 0;
1454 (urh->out_buffer_used < urh->out_buffer_size) )
1459 buf_size = urh->out_buffer_size - urh->out_buffer_used;
1464 &urh->out_buffer[urh->out_buffer_used],
1483 urh->out_buffer_size = 0;
1489 urh->out_buffer_used += res;
1490 if (buf_size > (
size_t) res)
1500 urh->out_buffer_size = 0;
1508 (urh->out_buffer_used > 0) )
1513 data_size = urh->out_buffer_used;
1517 res = gnutls_record_send (connection->tls_session,
1522 if (GNUTLS_E_INTERRUPTED != res)
1525 if (GNUTLS_E_AGAIN != res)
1529 #ifdef HAVE_MESSAGES 1532 "Failed to forward to remote client " 1534 " bytes of data received from application: %s\n"),
1536 gnutls_strerror (res));
1539 urh->out_buffer_used = 0;
1541 urh->out_buffer_size = 0;
1548 const size_t next_out_buffer_used = urh->out_buffer_used - res;
1549 if (0 != next_out_buffer_used)
1551 memmove (urh->out_buffer,
1552 &urh->out_buffer[res],
1553 next_out_buffer_used);
1554 if (data_size > (
size_t) res)
1557 urh->out_buffer_used = next_out_buffer_used;
1559 if ( (0 == urh->out_buffer_used) &&
1567 urh->out_buffer_size = 0;
1576 (urh->in_buffer_used > 0) )
1581 data_size = urh->in_buffer_used;
1599 #ifdef HAVE_MESSAGES 1602 "Failed to forward to application " 1604 " bytes of data received from remote side: %s\n"),
1609 urh->in_buffer_used = 0;
1611 urh->in_buffer_size = 0;
1619 const size_t next_in_buffer_used = urh->in_buffer_used - res;
1620 if (0 != next_in_buffer_used)
1622 memmove (urh->in_buffer,
1623 &urh->in_buffer[res],
1624 next_in_buffer_used);
1625 if (data_size > (
size_t) res)
1628 urh->in_buffer_used = next_in_buffer_used;
1630 if ( (0 == urh->in_buffer_used) &&
1636 urh->in_buffer_size = 0;
1645 (urh->in_buffer_used < urh->in_buffer_size) &&
1650 ( (0 != urh->out_buffer_size) ||
1651 (0 != urh->out_buffer_used) ) )
1654 #ifdef HAVE_MESSAGES 1655 if (0 < urh->out_buffer_used)
1658 "Failed to forward to remote client " 1660 " bytes of data received from application: daemon shut down\n"),
1664 urh->out_buffer_used = 0;
1668 urh->out_buffer_size = 0;
1674 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 1675 #ifdef UPGRADE_SUPPORT 1687 #ifdef HTTPS_SUPPORT 1688 struct MHD_UpgradeResponseHandle *urh = con->urh;
1697 while ( (0 != urh->in_buffer_size) ||
1698 (0 != urh->out_buffer_size) ||
1699 (0 != urh->in_buffer_used) ||
1700 (0 != urh->out_buffer_used) )
1714 result = urh_to_fdset (urh,
1722 #ifdef HAVE_MESSAGES 1724 _ (
"Error preparing select\n"));
1734 (urh->in_buffer_used < urh->in_buffer_size))
1756 #ifdef HAVE_MESSAGES 1758 _ (
"Error during select (%d): `%s'\n"),
1764 urh_from_fdset (urh,
1779 p[0].fd = urh->connection->socket_fd;
1780 p[1].fd = urh->mhd.socket;
1782 while ( (0 != urh->in_buffer_size) ||
1783 (0 != urh->out_buffer_size) ||
1784 (0 != urh->in_buffer_used) ||
1785 (0 != urh->out_buffer_used) )
1789 urh_update_pollfd (urh, p);
1792 (urh->in_buffer_used < urh->in_buffer_size))
1797 if (MHD_sys_poll_ (p,
1805 #ifdef HAVE_MESSAGES 1807 _ (
"Error during poll: `%s'\n"),
1812 urh_from_pollfd (urh,
1836 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
1847 struct timeval *tvp;
1853 #define EXTRA_SLOTS 1 1855 #define EXTRA_SLOTS 0 1864 const bool use_poll = 0;
1866 bool was_suspended =
false;
1867 MHD_thread_init_ (&(con->
pid));
1873 #ifdef UPGRADE_SUPPORT 1874 struct MHD_UpgradeResponseHandle *
const urh = con->urh;
1876 static const void *
const urh =
NULL;
1883 was_suspended =
true;
1892 #ifdef HAVE_MESSAGES 1894 _ (
"Failed to add FD to fd_set\n"));
1908 #ifdef HAVE_MESSAGES 1910 _ (
"Error during select (%d): `%s'\n"),
1920 p[0].events = POLLIN;
1921 p[0].fd = MHD_itc_r_fd_ (daemon->
itc);
1923 if (0 > MHD_sys_poll_ (p,
1929 #ifdef HAVE_MESSAGES 1931 _ (
"Error during poll: `%s'\n"),
1938 MHD_itc_clear_ (daemon->
itc);
1947 was_suspended =
false;
1953 #ifdef HTTPS_SUPPORT
1965 if ( (
NULL == tvp) &&
1973 const time_t seconds_left = timeout - (now - con->
last_activity);
1974 #if ! defined(_WIN32) || defined(__CYGWIN__) 1975 tv.tv_sec = seconds_left;
1989 bool err_state =
false;
2023 if (MHD_ITC_IS_VALID_ (daemon->
itc) )
2034 #ifdef HAVE_MESSAGES 2036 _ (
"Failed to add FD to fd_set\n"));
2052 #ifdef HAVE_MESSAGES 2054 _ (
"Error during select (%d): `%s'\n"),
2063 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
2064 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
2066 MHD_itc_clear_ (daemon->
itc);
2089 p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
2092 p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
2095 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
2103 if (MHD_ITC_IS_VALID_ (daemon->
itc))
2105 p[1].events |= POLLIN;
2106 p[1].fd = MHD_itc_r_fd_ (daemon->
itc);
2111 if (MHD_sys_poll_ (p,
2117 (
NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
2121 #ifdef HAVE_MESSAGES 2123 _ (
"Error during poll: `%s'\n"),
2131 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
2132 (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
2133 MHD_itc_clear_ (daemon->
itc);
2137 (0 != (p[0].revents & POLLIN)),
2138 (0 != (p[0].revents & POLLOUT)),
2139 (0 != (p[0].revents & (POLLERR
2140 | MHD_POLL_REVENTS_ERR_DISC))) ))
2144 #ifdef UPGRADE_SUPPORT 2145 if (MHD_CONNECTION_UPGRADE == con->
state)
2157 thread_main_connection_upgrade (con);
2161 con->urh->clean_ready =
true;
2169 return (MHD_THRD_RTRN_TYPE_) 0;
2174 #ifdef HAVE_MESSAGES 2176 _ (
"Processing thread terminating. Closing connection\n"));
2200 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
2201 (! MHD_itc_activate_ (daemon->
itc,
"t")) )
2203 #ifdef HAVE_MESSAGES 2206 "Failed to signal thread termination via inter-thread communication channel."));
2209 return (MHD_THRD_RTRN_TYPE_) 0;
2224 #if defined(HTTPS_SUPPORT) 2225 #if ! defined(MHD_WINSOCK_SOCKETS) && ! defined(MHD_socket_nosignal_) && \ 2226 (GNUTLS_VERSION_NUMBER + 0 < 0x030402) && defined(MSG_NOSIGNAL) 2232 #define MHD_TLSLIB_NEED_PUSH_FUNC 1 2235 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC 2241 MHD_tls_push_func_ (gnutls_transport_ptr_t trnsp,
2245 #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) 2263 psk_gnutls_adapter (gnutls_session_t session,
2264 const char *username,
2265 gnutls_datum_t *key)
2270 size_t app_psk_size;
2272 connection = gnutls_session_get_ptr (session);
2273 if (
NULL == connection)
2275 #ifdef HAVE_MESSAGES 2277 MHD_PANIC (
_ (
"Internal server error. This should be impossible.\n"));
2281 daemon = connection->
daemon;
2282 #if GNUTLS_VERSION_MAJOR >= 3 2283 if (
NULL == daemon->cred_callback)
2285 #ifdef HAVE_MESSAGES 2287 _ (
"PSK not supported by this server.\n"));
2291 if (0 != daemon->cred_callback (daemon->cred_callback_cls,
2297 if (
NULL == (key->data = gnutls_malloc (app_psk_size)))
2299 #ifdef HAVE_MESSAGES 2302 "PSK authentication failed: gnutls_malloc failed to allocate memory\n"));
2309 #ifdef HAVE_MESSAGES 2311 _ (
"PSK authentication failed: PSK too long\n"));
2316 key->size = (
unsigned int) app_psk_size;
2323 #ifdef HAVE_MESSAGES 2325 _ (
"PSK not supported by this server.\n"));
2361 const struct sockaddr *addr,
2367 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2373 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2405 #ifdef HAVE_MESSAGES 2407 _ (
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
2408 (
int) client_socket,
2418 #ifdef MHD_socket_nosignal_ 2419 if (! MHD_socket_nosignal_ (client_socket))
2421 #ifdef HAVE_MESSAGES 2423 _ (
"Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
2426 #ifndef MSG_NOSIGNAL 2437 #ifdef HAVE_MESSAGES 2440 _ (
"Accepted connection on socket %d\n"),
2450 #ifdef HAVE_MESSAGES 2453 "Server reached connection limit. Closing inbound connection.\n"));
2469 #ifdef HAVE_MESSAGES 2471 _ (
"Connection rejected by application. Closing connection.\n"));
2487 #ifdef HAVE_MESSAGES 2489 "Error allocating memory: %s\n",
2502 #ifdef HAVE_MESSAGES 2504 _ (
"Error allocating memory: %s\n"),
2519 if (
NULL == (connection->
addr = malloc (addrlen)))
2522 #ifdef HAVE_MESSAGES 2524 _ (
"Error allocating memory: %s\n"),
2536 memcpy (connection->
addr,
2542 connection->
daemon = daemon;
2552 #ifdef HTTPS_SUPPORT 2553 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030500) 2560 flags = GNUTLS_SERVER;
2561 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030402) 2562 flags |= GNUTLS_NO_SIGNAL;
2564 #if GNUTLS_VERSION_MAJOR >= 3 2565 flags |= GNUTLS_NONBLOCK;
2567 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030603) 2569 flags |= GNUTLS_POST_HANDSHAKE_AUTH;
2571 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030605) 2573 flags |= GNUTLS_ENABLE_EARLY_DATA;
2577 gnutls_init (&connection->tls_session,
2579 gnutls_priority_set (connection->tls_session,
2580 daemon->priority_cache);
2581 gnutls_session_set_ptr (connection->tls_session,
2583 switch (daemon->cred_type)
2586 case GNUTLS_CRD_CERTIFICATE:
2587 gnutls_credentials_set (connection->tls_session,
2588 GNUTLS_CRD_CERTIFICATE,
2591 case GNUTLS_CRD_PSK:
2592 gnutls_credentials_set (connection->tls_session,
2595 gnutls_psk_set_server_credentials_function (daemon->psk_cred,
2596 &psk_gnutls_adapter);
2599 #ifdef HAVE_MESSAGES 2600 MHD_DLOG (connection->
daemon,
2602 "Failed to setup TLS credentials: unknown credential type %d\n"),
2609 free (connection->
addr);
2617 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030109) && ! defined(_WIN64) 2618 gnutls_transport_set_int (connection->tls_session,
2619 (
int) (client_socket));
2621 gnutls_transport_set_ptr (connection->tls_session,
2622 (gnutls_transport_ptr_t) (intptr_t) (client_socket));
2624 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC 2625 gnutls_transport_set_push_function (connection->tls_session,
2626 MHD_tls_push_func_);
2628 if (daemon->https_mem_trust)
2629 gnutls_certificate_server_set_request (connection->tls_session,
2630 GNUTLS_CERT_REQUEST);
2637 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2643 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2647 #ifdef HAVE_MESSAGES 2650 "Server reached connection limit. Closing inbound connection.\n"));
2667 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2675 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2681 daemon->thread_stack_size,
2686 #ifdef HAVE_MESSAGES 2688 "Failed to create a thread: %s\n",
2695 connection->
pid = daemon->
pid;
2697 #ifdef EPOLL_SUPPORT 2702 struct epoll_event event;
2704 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2705 event.data.ptr = connection;
2706 if (0 != epoll_ctl (daemon->epoll_fd,
2712 #ifdef HAVE_MESSAGES 2714 _ (
"Call to epoll_ctl failed: %s\n"),
2727 daemon->eready_tail,
2735 (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
2736 (! MHD_itc_activate_ (daemon->
itc,
"n")) )
2738 #ifdef HAVE_MESSAGES 2741 "Failed to signal new connection via inter-thread communication channel."));
2751 #ifdef HTTPS_SUPPORT 2752 if (
NULL != connection->tls_session)
2753 gnutls_deinit (connection->tls_session);
2759 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2771 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2775 free (connection->
addr);
2799 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2806 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2830 #ifdef EPOLL_SUPPORT 2836 daemon->eready_tail,
2842 if (0 != epoll_ctl (daemon->epoll_fd,
2846 MHD_PANIC (
_ (
"Failed to remove FD from epoll set\n"));
2852 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2896 "Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2897 #ifdef UPGRADE_SUPPORT 2898 if (
NULL != connection->urh)
2900 #ifdef HAVE_MESSAGES 2903 "Error: connection scheduled for \"upgrade\" cannot be suspended"));
2927 "Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2928 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2933 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2936 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
2937 (! MHD_itc_activate_ (daemon->
itc,
"r")) )
2939 #ifdef HAVE_MESSAGES 2942 "Failed to signal resume via inter-thread communication channel."));
2965 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2969 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2983 #ifdef UPGRADE_SUPPORT 2984 struct MHD_UpgradeResponseHandle *
const urh = pos->urh;
2986 static const void *
const urh =
NULL;
2990 #ifdef UPGRADE_SUPPORT
2991 || ( (
NULL != urh) &&
2992 ( (! urh->was_closed) ||
2993 (! urh->clean_ready) ) )
3023 #ifdef EPOLL_SUPPORT 3027 MHD_PANIC (
"Resumed connection was already in EREADY set\n");
3031 daemon->eready_tail,
3040 #ifdef UPGRADE_SUPPORT 3065 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3068 if ( (used_thr_p_c) &&
3071 if (! MHD_itc_activate_ (daemon->
itc,
3074 #ifdef HAVE_MESSAGES 3077 "Failed to signal resume of connection via inter-thread communication channel."));
3115 const struct sockaddr *addr,
3122 #ifdef HAVE_MESSAGES 3124 _ (
"Failed to set nonblocking mode on new client socket: %s\n"),
3135 #ifdef HAVE_MESSAGES 3137 _ (
"Failed to set noninheritable mode on new client socket.\n"));
3144 #ifdef HAVE_MESSAGES 3146 _ (
"Failed to reset buffering mode on new client socket.\n"));
3176 struct sockaddr_in6 addrstorage;
3178 struct sockaddr_in addrstorage;
3180 struct sockaddr *addr = (
struct sockaddr *) &addrstorage;
3186 addrlen =
sizeof (addrstorage);
3189 sizeof (addrstorage));
3216 #ifdef HAVE_MESSAGES 3219 _ (
"Error accepting connection: %s\n"),
3231 #ifdef HAVE_MESSAGES 3237 "Hit process or system resource limit at FIRST connection. This is really bad as there is no sane way to proceed. Will try busy waiting for system resources to become magically available.\n"));
3242 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3246 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3249 #ifdef HAVE_MESSAGES 3252 "Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
3259 #if defined(MHD_TCP_CORK_NOPUSH) || defined(HAVE_MSG_MORE) 3264 (EOPNOTSUPP != errno) )
3266 #ifdef HAVE_MESSAGES 3268 _ (
"Failed to disable TCP Nagle on socket: %s\n"),
3273 #if ! defined(USE_ACCEPT4) || ! defined(HAVE_SOCK_NONBLOCK) 3276 #ifdef HAVE_MESSAGES 3279 "Failed to set nonblocking mode on incoming connection socket: %s\n"),
3286 #if ! defined(USE_ACCEPT4) || ! defined(SOCK_CLOEXEC) 3289 #ifdef HAVE_MESSAGES 3292 "Failed to set noninheritable mode on incoming connection socket.\n"));
3296 #ifdef HAVE_MESSAGES 3299 _ (
"Accepted connection on socket %d\n"),
3327 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3335 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3339 (! MHD_join_thread_ (pos->
pid.handle)) )
3342 #ifdef UPGRADE_SUPPORT 3343 cleanup_upgraded_connection (pos);
3346 #ifdef HTTPS_SUPPORT 3347 if (
NULL != pos->tls_session)
3348 gnutls_deinit (pos->tls_session);
3360 #ifdef EPOLL_SUPPORT 3370 if ( (-1 !=
daemon->epoll_fd) &&
3379 if (0 != epoll_ctl (
daemon->epoll_fd,
3383 MHD_PANIC (
_ (
"Failed to remove FD from epoll set\n"));
3399 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3405 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3435 time_t earliest_deadline;
3442 #ifdef HAVE_MESSAGES 3444 _ (
"Illegal call to MHD_get_timeout\n"));
3456 #ifdef EPOLL_SUPPORT 3459 #
if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
3470 have_timeout =
false;
3471 earliest_deadline = 0;
3476 if ( (! have_timeout) ||
3479 have_timeout =
true;
3484 if ( (
NULL != pos) &&
3487 if ( (! have_timeout) ||
3490 have_timeout =
true;
3496 if (earliest_deadline < now)
3500 const time_t second_left = earliest_deadline - now;
3502 if (((
unsigned long long) second_left) >
ULLONG_MAX / 1000)
3505 *timeout = 1000LLU * (
unsigned long long) second_left;
3523 const fd_set *read_fd_set,
3524 const fd_set *write_fd_set,
3525 const fd_set *except_fd_set)
3530 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3531 struct MHD_UpgradeResponseHandle *urh;
3532 struct MHD_UpgradeResponseHandle *urhn;
3541 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
3542 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
3544 MHD_itc_clear_ (daemon->
itc);
3557 while (
NULL != (pos = prev))
3573 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3575 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
3579 urh_from_fdset (urh,
3586 if ( (0 == urh->in_buffer_size) &&
3587 (0 == urh->out_buffer_size) &&
3588 (0 == urh->in_buffer_used) &&
3589 (0 == urh->out_buffer_used) )
3592 urh->clean_ready =
true;
3627 const fd_set *read_fd_set,
3628 const fd_set *write_fd_set,
3629 const fd_set *except_fd_set)
3635 if ((
NULL == read_fd_set)||(
NULL == write_fd_set))
3637 if (
NULL == except_fd_set)
3639 #ifdef HAVE_MESSAGES 3641 _ (
"MHD_run_from_select() called with except_fd_set " 3642 "set to NULL. Such behavior is deprecated.\n"));
3645 except_fd_set = &es;
3649 #ifdef EPOLL_SUPPORT 3650 int ret = MHD_epoll (daemon,
3688 struct timeval timeout;
3695 timeout.tv_usec = 0;
3719 #ifdef HAVE_MESSAGES 3721 _ (
"Could not obtain daemon fdsets"));
3736 #ifdef HAVE_MESSAGES 3738 _ (
"Could not add listen socket to fdset"));
3743 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
3749 #if defined(MHD_WINSOCK_SOCKETS) 3764 #ifdef HAVE_MESSAGES 3767 "Could not add control inter-thread communication channel FD to fdset"));
3770 #if defined(MHD_WINSOCK_SOCKETS) 3782 (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
3794 timeout.tv_usec = 0;
3802 timeout.tv_usec = (ltimeout % 1000) * 1000;
3821 #ifdef HAVE_MESSAGES 3823 _ (
"select failed: %s\n"),
3850 unsigned int num_connections;
3853 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3854 struct MHD_UpgradeResponseHandle *urh;
3855 struct MHD_UpgradeResponseHandle *urhn;
3863 num_connections = 0;
3866 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3867 for (urh = daemon->urh_head;
NULL != urh; urh = urh->next)
3868 num_connections += 2;
3874 unsigned int poll_server;
3881 sizeof (
struct pollfd));
3884 #ifdef HAVE_MESSAGES 3886 _ (
"Error allocating memory: %s\n"),
3899 p[poll_server].fd = ls;
3900 p[poll_server].events = POLLIN;
3901 p[poll_server].revents = 0;
3902 poll_listen = (int) poll_server;
3906 if (MHD_ITC_IS_VALID_ (daemon->
itc))
3908 p[poll_server].fd = MHD_itc_r_fd_ (daemon->
itc);
3909 p[poll_server].events = POLLIN;
3910 p[poll_server].revents = 0;
3911 poll_itc_idx = (int) poll_server;
3921 timeout = (ltimeout > INT_MAX) ? INT_MAX : (
int) ltimeout;
3930 p[poll_server + i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
3933 p[poll_server + i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
3936 p[poll_server + i].events |= MHD_POLL_EVENTS_ERR_DISC;
3944 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3945 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
3947 urh_to_pollfd (urh, &(p[poll_server + i]));
3951 if (0 == poll_server + num_connections)
3956 if (MHD_sys_poll_ (p,
3957 poll_server + num_connections,
3966 #ifdef HAVE_MESSAGES 3968 _ (
"poll failed: %s\n"),
3981 if ( (-1 != poll_itc_idx) &&
3982 (0 != (p[poll_itc_idx].revents & POLLIN)) )
3983 MHD_itc_clear_ (daemon->
itc);
3993 while (
NULL != (pos = prev))
3997 if (i >= num_connections)
4002 0 != (p[poll_server + i].revents & POLLIN),
4003 0 != (p[poll_server + i].revents & POLLOUT),
4004 0 != (p[poll_server + i].revents
4005 & MHD_POLL_REVENTS_ERR_DISC));
4008 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4009 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
4011 if (i >= num_connections)
4018 if ((p[poll_server + i].
fd != urh->connection->socket_fd) ||
4019 (p[poll_server + i + 1].fd != urh->mhd.socket))
4021 urh_from_pollfd (urh,
4022 &p[poll_server + i]);
4026 if ( (0 == urh->in_buffer_size) &&
4027 (0 == urh->out_buffer_size) &&
4028 (0 == urh->in_buffer_used) &&
4029 (0 == urh->out_buffer_used) )
4034 urh->clean_ready =
true;
4044 if ( (-1 != poll_listen) &&
4045 (0 != (p[poll_listen].revents & POLLIN)) )
4062 MHD_poll_listen_socket (
struct MHD_Daemon *daemon,
4067 unsigned int poll_count;
4082 p[poll_count].fd = ls;
4083 p[poll_count].events = POLLIN;
4084 p[poll_count].revents = 0;
4085 poll_listen = poll_count;
4088 if (MHD_ITC_IS_VALID_ (daemon->
itc))
4090 p[poll_count].fd = MHD_itc_r_fd_ (daemon->
itc);
4091 p[poll_count].events = POLLIN;
4092 p[poll_count].revents = 0;
4093 poll_itc_idx = poll_count;
4104 if (0 == poll_count)
4106 if (MHD_sys_poll_ (p,
4114 #ifdef HAVE_MESSAGES 4116 _ (
"poll failed: %s\n"),
4121 if ( (-1 != poll_itc_idx) &&
4122 (0 != (p[poll_itc_idx].revents & POLLIN)) )
4123 MHD_itc_clear_ (daemon->
itc);
4128 if ( (-1 != poll_listen) &&
4129 (0 != (p[poll_listen].revents & POLLIN)) )
4151 return MHD_poll_all (daemon,
4153 return MHD_poll_listen_socket (daemon,
4163 #ifdef EPOLL_SUPPORT 4173 #define MAX_EVENTS 128 4176 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4186 is_urh_ready (
struct MHD_UpgradeResponseHandle *
const urh)
4190 if ( (0 == urh->in_buffer_size) &&
4191 (0 == urh->out_buffer_size) &&
4192 (0 == urh->in_buffer_used) &&
4193 (0 == urh->out_buffer_used) )
4199 (urh->in_buffer_used < urh->in_buffer_size) )
4202 (urh->out_buffer_used < urh->out_buffer_size) )
4205 (urh->out_buffer_used > 0) )
4208 (urh->in_buffer_used > 0) )
4225 struct epoll_event events[MAX_EVENTS];
4227 struct MHD_UpgradeResponseHandle *pos;
4228 struct MHD_UpgradeResponseHandle *prev;
4230 num_events = MAX_EVENTS;
4231 while (0 != num_events)
4235 num_events = epoll_wait (daemon->epoll_upgrade_fd,
4239 if (-1 == num_events)
4245 #ifdef HAVE_MESSAGES 4247 _ (
"Call to epoll_wait failed: %s\n"),
4252 for (i = 0; i < (
unsigned int) num_events; i++)
4254 struct UpgradeEpollHandle *
const ueh = events[i].data.ptr;
4255 struct MHD_UpgradeResponseHandle *
const urh = ueh->urh;
4256 bool new_err_state =
false;
4258 if (urh->clean_ready)
4262 if (0 != (events[i].events & EPOLLIN))
4264 if (0 != (events[i].events & EPOLLOUT))
4266 if (0 != (events[i].events & EPOLLHUP))
4270 (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
4276 new_err_state =
true;
4279 if (! urh->in_eready_list)
4281 if (new_err_state ||
4285 daemon->eready_urh_tail,
4287 urh->in_eready_list =
true;
4292 prev = daemon->eready_urh_tail;
4293 while (
NULL != (pos = prev))
4297 if (! is_urh_ready (pos))
4300 daemon->eready_urh_tail,
4302 pos->in_eready_list =
false;
4305 if ( (0 == pos->in_buffer_size) &&
4306 (0 == pos->out_buffer_size) &&
4307 (0 == pos->in_buffer_used) &&
4308 (0 == pos->out_buffer_used) )
4311 pos->clean_ready =
true;
4328 static const char *
const epoll_itc_marker =
"itc_marker";
4343 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4344 static const char *
const upgrade_marker =
"upgrade_ptr";
4348 struct epoll_event events[MAX_EVENTS];
4349 struct epoll_event event;
4355 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4356 bool run_upgraded =
false;
4359 if (-1 == daemon->epoll_fd)
4366 (! daemon->listen_socket_in_epoll) &&
4369 event.events = EPOLLIN;
4370 event.data.ptr = daemon;
4371 if (0 != epoll_ctl (daemon->epoll_fd,
4376 #ifdef HAVE_MESSAGES 4378 _ (
"Call to epoll_ctl failed: %s\n"),
4383 daemon->listen_socket_in_epoll =
true;
4386 (daemon->listen_socket_in_epoll) )
4388 if ( (0 != epoll_ctl (daemon->epoll_fd,
4394 MHD_PANIC (
"Failed to remove listen FD from epoll set\n");
4395 daemon->listen_socket_in_epoll =
false;
4398 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4399 if ( ( (! daemon->upgrade_fd_in_epoll) &&
4400 (-1 != daemon->epoll_upgrade_fd) ) )
4402 event.events = EPOLLIN | EPOLLOUT;
4403 event.data.ptr = (
void *) upgrade_marker;
4404 if (0 != epoll_ctl (daemon->epoll_fd,
4406 daemon->epoll_upgrade_fd,
4409 #ifdef HAVE_MESSAGES 4411 _ (
"Call to epoll_ctl failed: %s\n"),
4416 daemon->upgrade_fd_in_epoll =
true;
4419 if ( (daemon->listen_socket_in_epoll) &&
4426 if (0 != epoll_ctl (daemon->epoll_fd,
4430 MHD_PANIC (
_ (
"Failed to remove listen FD from epoll set\n"));
4431 daemon->listen_socket_in_epoll =
false;
4444 timeout_ms = INT_MAX;
4446 timeout_ms = (int) timeout_ll;
4463 num_events = MAX_EVENTS;
4464 while (MAX_EVENTS == num_events)
4467 num_events = epoll_wait (daemon->epoll_fd,
4471 if (-1 == num_events)
4476 #ifdef HAVE_MESSAGES 4478 _ (
"Call to epoll_wait failed: %s\n"),
4483 for (i = 0; i<(
unsigned int) num_events; i++)
4489 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4490 if (upgrade_marker == events[i].
data.ptr)
4494 run_upgraded =
true;
4498 if (epoll_itc_marker == events[i].
data.ptr)
4502 MHD_itc_clear_ (daemon->
itc);
4505 if (daemon == events[i].
data.ptr)
4509 if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
4511 unsigned int series_length = 0;
4517 (series_length < 10) &&
4527 pos = events[i].data.ptr;
4529 if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
4535 daemon->eready_tail,
4542 if (0 != (events[i].events & EPOLLIN))
4550 daemon->eready_tail,
4555 if (0 != (events[i].events & EPOLLOUT))
4562 daemon->eready_tail,
4571 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4572 if (run_upgraded || (
NULL != daemon->eready_urh_head))
4573 run_epoll_for_upgrade (daemon);
4577 prev = daemon->eready_tail;
4578 while (
NULL != (pos = prev))
4596 daemon->eready_tail,
4612 while (
NULL != (pos = prev))
4622 while (
NULL != (pos = prev))
4665 #ifdef EPOLL_SUPPORT 4668 MHD_epoll (daemon,
MHD_NO);
4701 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4720 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4726 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4734 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
4739 MHD_thread_init_ (&(daemon->
pid));
4744 #ifdef EPOLL_SUPPORT 4760 return (MHD_THRD_RTRN_TYPE_) 0;
4856 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4867 #ifdef HAVE_MESSAGES 4869 "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC\n");
4874 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4879 #ifdef EPOLL_SUPPORT 4884 if (0 != epoll_ctl (daemon->
worker_pool[i].epoll_fd,
4888 MHD_PANIC (
_ (
"Failed to remove listen FD from epoll set\n"));
4889 daemon->
worker_pool[i].listen_socket_in_epoll =
false;
4897 "Failed to signal quiesce via inter-thread communication channel"));
4902 #ifdef EPOLL_SUPPORT 4904 (-1 != daemon->epoll_fd) &&
4905 (daemon->listen_socket_in_epoll) )
4907 if ( (0 != epoll_ctl (daemon->epoll_fd,
4913 MHD_PANIC (
"Failed to remove listen FD from epoll set\n");
4914 daemon->listen_socket_in_epoll =
false;
4917 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
4918 (! MHD_itc_activate_ (daemon->
itc,
"q")) )
4920 "failed to signal quiesce via inter-thread communication channel"));
4948 const struct sockaddr **servaddr,
4962 const struct sockaddr **servaddr,
4968 va_start (ap, servaddr);
4987 const struct sockaddr **servaddr,
4994 #ifdef HTTPS_SUPPORT 4997 #if GNUTLS_VERSION_MAJOR >= 3 4998 gnutls_certificate_retrieve_function2 *pgcrf;
5000 #if GNUTLS_VERSION_NUMBER >= 0x030603 5001 gnutls_certificate_retrieve_function3 *pgcrf2;
5032 #ifdef HAVE_MESSAGES 5034 _ (
"Warning: Too large timeout value, ignored.\n"));
5056 *servaddr = va_arg (ap,
5057 const struct sockaddr *);
5070 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5076 #ifdef HAVE_MESSAGES 5079 "Warning: Zero size, specified for thread pool size, is ignored. " 5080 "Thread pool is not used.\n"));
5085 #ifdef HAVE_MESSAGES 5088 "Warning: \"1\", specified for thread pool size, is ignored. " 5089 "Thread pool is not used.\n"));
5099 #ifdef HAVE_MESSAGES 5101 _ (
"Specified thread pool size (%u) too big\n"),
5110 #ifdef HAVE_MESSAGES 5112 _ (
"MHD_OPTION_THREAD_POOL_SIZE option is specified but " 5113 "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
5119 #ifdef HAVE_MESSAGES 5121 _ (
"Both MHD_OPTION_THREAD_POOL_SIZE option and " 5122 "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
5129 #ifdef HTTPS_SUPPORT 5134 daemon->https_mem_key = pstr;
5135 #ifdef HAVE_MESSAGES 5139 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5147 daemon->https_key_password = pstr;
5148 #ifdef HAVE_MESSAGES 5152 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5160 daemon->https_mem_cert = pstr;
5161 #ifdef HAVE_MESSAGES 5165 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5173 daemon->https_mem_trust = pstr;
5174 #ifdef HAVE_MESSAGES 5178 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5183 daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
5191 gnutls_datum_t dhpar;
5194 if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
5196 #ifdef HAVE_MESSAGES 5198 _ (
"Error initializing DH parameters\n"));
5202 dhpar.data = (
unsigned char *) pstr;
5203 pstr_len = strlen (pstr);
5206 #ifdef HAVE_MESSAGES 5208 _ (
"Diffie-Hellman parameters string too long\n"));
5212 dhpar.size = (
unsigned int) pstr_len;
5213 if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
5215 GNUTLS_X509_FMT_PEM) < 0)
5217 #ifdef HAVE_MESSAGES 5219 _ (
"Bad Diffie-Hellman parameters format\n"));
5221 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
5224 daemon->have_dhparams =
true;
5226 #ifdef HAVE_MESSAGES 5230 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5239 gnutls_priority_deinit (daemon->priority_cache);
5240 ret = gnutls_priority_init (&daemon->priority_cache,
5243 if (GNUTLS_E_SUCCESS != ret)
5245 #ifdef HAVE_MESSAGES 5247 _ (
"Setting priorities to `%s' failed: %s\n"),
5249 gnutls_strerror (ret));
5251 daemon->priority_cache =
NULL;
5255 #ifdef HAVE_MESSAGES 5259 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5264 #if GNUTLS_VERSION_MAJOR < 3 5265 #ifdef HAVE_MESSAGES 5268 "MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n"));
5273 gnutls_certificate_retrieve_function2 *);
5275 daemon->cert_callback = pgcrf;
5277 #ifdef HAVE_MESSAGES 5280 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5286 #if GNUTLS_VERSION_NUMBER < 0x030603 5287 #ifdef HAVE_MESSAGES 5290 "MHD_OPTION_HTTPS_CERT_CALLBACK2 requires building MHD with GnuTLS >= 3.6.3\n"));
5294 pgcrf2 = va_arg (ap,
5295 gnutls_certificate_retrieve_function3 *);
5297 daemon->cert_callback2 = pgcrf2;
5299 #ifdef HAVE_MESSAGES 5302 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5308 #ifdef DAUTH_SUPPORT 5310 daemon->digest_auth_rand_size = va_arg (ap,
5312 daemon->digest_auth_random = va_arg (ap,
5316 daemon->nonce_nc_size = va_arg (ap,
5323 #ifdef HAVE_MESSAGES 5325 _ (
"MHD_OPTION_LISTEN_SOCKET specified for daemon " 5326 "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
5335 #ifdef HAVE_MESSAGES 5336 daemon->custom_error_log = va_arg (ap,
5338 daemon->custom_error_log_cls = va_arg (ap,
5347 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5349 daemon->thread_stack_size = va_arg (ap,
5355 daemon->fastopen_queue_size = va_arg (ap,
5359 #ifdef HAVE_MESSAGES 5361 _ (
"TCP fastopen is not supported on this platform\n"));
5367 unsigned int) ? 1 : -1;
5375 #ifdef HAVE_MESSAGES 5380 _ (
"Flag MHD_USE_PEDANTIC_CHECKS is ignored because " 5381 "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n"));
5399 (
size_t) oa[i].
value,
5416 (
unsigned int) oa[i].
value,
5421 #ifdef HTTPS_SUPPORT 5426 (gnutls_credentials_type_t) oa[i].
value,
5477 (
void *) oa[i].
value,
5487 (
size_t) oa[i].
value,
5504 #ifdef HTTPS_SUPPORT 5506 #if GNUTLS_VERSION_MAJOR >= 3 5507 daemon->cred_callback = va_arg (ap,
5509 daemon->cred_callback_cls = va_arg (ap,
5515 "MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3\n"),
5521 #ifdef HAVE_MESSAGES 5529 "MHD HTTPS option %d passed to MHD compiled without HTTPS support\n"),
5536 "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n"),
5547 #ifdef EPOLL_SUPPORT 5553 #ifndef HAVE_MESSAGES 5557 #ifdef USE_EPOLL_CREATE1 5558 fd = epoll_create1 (EPOLL_CLOEXEC);
5560 fd = epoll_create (MAX_EVENTS);
5564 #ifdef HAVE_MESSAGES 5566 _ (
"Call to epoll_create1 failed: %s\n"),
5571 #if ! defined(USE_EPOLL_CREATE1) 5574 #ifdef HAVE_MESSAGES 5576 _ (
"Failed to set noninheritable mode on epoll FD.\n"));
5594 setup_epoll_to_listen (
struct MHD_Daemon *daemon)
5596 struct epoll_event event;
5599 daemon->epoll_fd = setup_epoll_fd (daemon);
5600 if (-1 == daemon->epoll_fd)
5602 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5605 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
5613 event.events = EPOLLIN;
5614 event.data.ptr = daemon;
5615 if (0 != epoll_ctl (daemon->epoll_fd,
5620 #ifdef HAVE_MESSAGES 5622 _ (
"Call to epoll_ctl failed: %s\n"),
5627 daemon->listen_socket_in_epoll =
true;
5628 if (MHD_ITC_IS_VALID_ (daemon->
itc))
5630 event.events = EPOLLIN;
5631 event.data.ptr = (
void *) epoll_itc_marker;
5632 if (0 != epoll_ctl (daemon->epoll_fd,
5634 MHD_itc_r_fd_ (daemon->
itc),
5637 #ifdef HAVE_MESSAGES 5639 _ (
"Call to epoll_ctl failed: %s\n"),
5683 struct sockaddr_in servaddr4;
5685 struct sockaddr_in6 servaddr6;
5687 const struct sockaddr *servaddr =
NULL;
5689 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5706 #ifndef EPOLL_SUPPORT 5710 #ifndef HTTPS_SUPPORT 5714 #ifndef TCP_FASTOPEN 5720 #ifdef UPGRADE_SUPPORT 5756 #if defined(EPOLL_SUPPORT) 5758 #elif defined(HAVE_POLL) 5767 #if defined(EPOLL_SUPPORT) 5777 #ifdef EPOLL_SUPPORT 5778 daemon->epoll_fd = -1;
5779 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5780 daemon->epoll_upgrade_fd = -1;
5784 #ifdef HTTPS_SUPPORT 5785 daemon->priority_cache =
NULL;
5788 gnutls_priority_init (&daemon->priority_cache,
5799 daemon->
port = port;
5810 MHD_itc_set_invalid_ (daemon->
itc);
5816 #ifdef HAVE_MESSAGES 5818 daemon->custom_error_log_cls = stderr;
5823 #ifdef HAVE_MESSAGES 5826 "Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with " 5827 "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD " 5828 "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"));
5836 #ifdef HAVE_LISTEN_SHUTDOWN 5841 #ifdef DAUTH_SUPPORT 5842 daemon->digest_auth_rand_size = 0;
5843 daemon->digest_auth_random =
NULL;
5844 daemon->nonce_nc_size = 4;
5846 #ifdef HTTPS_SUPPORT 5849 daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
5858 #ifdef HTTPS_SUPPORT 5860 (
NULL != daemon->priority_cache) )
5861 gnutls_priority_deinit (daemon->priority_cache);
5872 #ifdef HAVE_MESSAGES 5874 _ (
"Using debug build of libmicrohttpd.\n") );
5879 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5884 if (! MHD_itc_init_ (daemon->
itc))
5886 #ifdef HAVE_MESSAGES 5888 _ (
"Failed to create inter-thread communication channel: %s\n"),
5889 MHD_itc_last_strerror_ ());
5891 #ifdef HTTPS_SUPPORT 5892 if (
NULL != daemon->priority_cache)
5893 gnutls_priority_deinit (daemon->priority_cache);
5902 #ifdef HAVE_MESSAGES 5905 "file descriptor for inter-thread communication channel exceeds maximum value\n"));
5908 #ifdef HTTPS_SUPPORT 5909 if (
NULL != daemon->priority_cache)
5910 gnutls_priority_deinit (daemon->priority_cache);
5917 #ifdef DAUTH_SUPPORT 5918 if (daemon->nonce_nc_size > 0)
5920 if ( ( (
size_t) (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc)))
5921 /
sizeof(
struct MHD_NonceNc) != daemon->nonce_nc_size)
5923 #ifdef HAVE_MESSAGES 5925 _ (
"Specified value for NC_SIZE too large\n"));
5927 #ifdef HTTPS_SUPPORT 5929 gnutls_priority_deinit (daemon->priority_cache);
5934 daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc));
5935 if (
NULL == daemon->nnc)
5937 #ifdef HAVE_MESSAGES 5939 _ (
"Failed to allocate memory for nonce-nc map: %s\n"),
5942 #ifdef HTTPS_SUPPORT 5944 gnutls_priority_deinit (daemon->priority_cache);
5951 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5952 if (! MHD_mutex_init_ (&daemon->nnc_lock))
5954 #ifdef HAVE_MESSAGES 5956 _ (
"MHD failed to initialize nonce-nc mutex\n"));
5958 #ifdef HTTPS_SUPPORT 5960 gnutls_priority_deinit (daemon->priority_cache);
5970 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5974 #ifdef HAVE_MESSAGES 5977 "MHD thread pooling only works with MHD_USE_INTERNAL_POLLING_THREAD\n"));
5989 domain = (*pflags &
MHD_USE_IPv6) ? PF_INET6 : PF_INET;
5999 #ifdef HAVE_MESSAGES 6001 _ (
"Failed to create socket for listening: %s\n"),
6010 #ifndef MHD_WINSOCK_SOCKETS 6015 if (0 > setsockopt (listen_fd,
6018 (
void*) &on,
sizeof (on)))
6020 #ifdef HAVE_MESSAGES 6022 _ (
"setsockopt failed: %s\n"),
6031 #ifndef MHD_WINSOCK_SOCKETS 6034 if (0 > setsockopt (listen_fd,
6037 (
void*) &on,
sizeof (on)))
6039 #ifdef HAVE_MESSAGES 6041 _ (
"setsockopt failed: %s\n"),
6051 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT) 6052 if (0 > setsockopt (listen_fd,
6054 #ifndef MHD_WINSOCK_SOCKETS
6062 #ifdef HAVE_MESSAGES 6064 _ (
"setsockopt failed: %s\n"),
6072 #ifdef HAVE_MESSAGES 6075 "Cannot allow listening address reuse: SO_REUSEPORT not defined\n"));
6088 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \ 6089 (defined(__sun) && defined(SO_EXCLBIND)) 6090 if (0 > setsockopt (listen_fd,
6092 #ifdef SO_EXCLUSIVEADDRUSE
6093 SO_EXCLUSIVEADDRUSE,
6100 #ifdef HAVE_MESSAGES 6102 _ (
"setsockopt failed: %s\n"),
6107 #elif defined(MHD_WINSOCK_SOCKETS) 6108 #ifdef HAVE_MESSAGES 6111 "Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n"));
6120 addrlen =
sizeof (
struct sockaddr_in6);
6123 addrlen =
sizeof (
struct sockaddr_in);
6124 if (
NULL == servaddr)
6129 #ifdef IN6ADDR_ANY_INIT 6130 static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
6134 sizeof (
struct sockaddr_in6));
6135 servaddr6.sin6_family = AF_INET6;
6136 servaddr6.sin6_port = htons (port);
6137 #ifdef IN6ADDR_ANY_INIT 6138 servaddr6.sin6_addr = static_in6any;
6140 #if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN 6141 servaddr6.sin6_len =
sizeof (
struct sockaddr_in6);
6143 servaddr = (
struct sockaddr *) &servaddr6;
6150 sizeof (
struct sockaddr_in));
6151 servaddr4.sin_family = AF_INET;
6152 servaddr4.sin_port = htons (port);
6153 if (0 != INADDR_ANY)
6154 servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
6155 #if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN 6156 servaddr4.sin_len =
sizeof (
struct sockaddr_in);
6158 servaddr = (
struct sockaddr *) &servaddr4;
6173 if (0 > setsockopt (listen_fd,
6174 IPPROTO_IPV6, IPV6_V6ONLY,
6175 (
const void *) &v6_only,
6178 #ifdef HAVE_MESSAGES 6180 _ (
"setsockopt failed: %s\n"),
6187 if (-1 == bind (listen_fd, servaddr, addrlen))
6189 #ifdef HAVE_MESSAGES 6191 _ (
"Failed to bind to port %u: %s\n"),
6192 (
unsigned int) port,
6201 if (0 == daemon->fastopen_queue_size)
6202 daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
6203 if (0 != setsockopt (listen_fd,
6206 (
const void*) &daemon->fastopen_queue_size,
6207 sizeof (daemon->fastopen_queue_size)))
6209 #ifdef HAVE_MESSAGES 6211 _ (
"setsockopt failed: %s\n"),
6217 if (listen (listen_fd,
6220 #ifdef HAVE_MESSAGES 6222 _ (
"Failed to listen for connections: %s\n"),
6234 #ifdef HAVE_GETSOCKNAME 6235 if ( (0 == daemon->
port) &&
6238 struct sockaddr_storage bindaddr;
6242 sizeof (
struct sockaddr_storage));
6243 addrlen =
sizeof (
struct sockaddr_storage);
6244 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 6245 bindaddr.ss_len = addrlen;
6247 if (0 != getsockname (listen_fd,
6248 (
struct sockaddr *) &bindaddr,
6251 #ifdef HAVE_MESSAGES 6253 _ (
"Failed to get listen port number: %s\n"),
6257 #ifdef MHD_POSIX_SOCKETS 6258 else if (
sizeof (bindaddr) < addrlen)
6261 #ifdef HAVE_MESSAGES 6264 "Failed to get listen port number (`struct sockaddr_storage` too small!?)\n"));
6268 else if (0 == addrlen)
6278 switch (bindaddr.ss_family)
6282 struct sockaddr_in *s4 = (
struct sockaddr_in *) &bindaddr;
6284 daemon->
port = ntohs (s4->sin_port);
6290 struct sockaddr_in6 *s6 = (
struct sockaddr_in6 *) &bindaddr;
6292 daemon->
port = ntohs (s6->sin6_port);
6303 #ifdef HAVE_MESSAGES 6305 _ (
"Unknown address family!\n"));
6316 #ifdef HAVE_MESSAGES 6318 _ (
"Failed to set nonblocking mode on listening socket: %s\n"),
6322 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6339 #ifdef HAVE_MESSAGES 6341 _ (
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
6349 #ifdef EPOLL_SUPPORT 6351 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6358 #ifdef HAVE_MESSAGES 6361 "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
6365 if (
MHD_YES != setup_epoll_to_listen (daemon))
6370 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6373 #ifdef HAVE_MESSAGES 6375 _ (
"MHD failed to initialize IP connection limit mutex\n"));
6386 #ifdef HAVE_MESSAGES 6388 _ (
"MHD failed to initialize IP connection limit mutex\n"));
6390 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6400 #ifdef HTTPS_SUPPORT 6403 (0 != MHD_TLS_init (daemon)) )
6405 #ifdef HAVE_MESSAGES 6407 _ (
"Failed to initialize TLS support\n"));
6411 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6419 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6428 "MHD-listen" :
"MHD-single",
6429 daemon->thread_stack_size,
6433 #ifdef HAVE_MESSAGES 6435 _ (
"Failed to create listen thread: %s\n"),
6469 memcpy (d, daemon,
sizeof (
struct MHD_Daemon));
6479 if (! MHD_itc_init_ (d->
itc))
6481 #ifdef HAVE_MESSAGES 6484 "Failed to create worker inter-thread communication channel: %s\n"),
6485 MHD_itc_last_strerror_ () );
6493 #ifdef HAVE_MESSAGES 6496 "File descriptor for worker inter-thread communication channel exceeds maximum value\n"));
6503 MHD_itc_set_invalid_ (d->
itc);
6509 if (i < leftover_conns)
6511 #ifdef EPOLL_SUPPORT 6513 (
MHD_YES != setup_epoll_to_listen (d)) )
6519 #ifdef HAVE_MESSAGES 6521 _ (
"MHD failed to initialize cleanup connection mutex\n"));
6529 daemon->thread_stack_size,
6533 #ifdef HAVE_MESSAGES 6535 _ (
"Failed to create pool thread: %s\n"),
6547 #ifdef HTTPS_SUPPORT 6550 daemon->https_key_password =
NULL;
6555 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6583 #ifdef EPOLL_SUPPORT 6584 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6585 if (daemon->upgrade_fd_in_epoll)
6587 if (0 != epoll_ctl (daemon->epoll_fd,
6589 daemon->epoll_upgrade_fd,
6591 MHD_PANIC (
_ (
"Failed to remove FD from epoll set\n"));
6592 daemon->upgrade_fd_in_epoll =
false;
6595 if (-1 != daemon->epoll_fd)
6596 close (daemon->epoll_fd);
6597 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6598 if (-1 != daemon->epoll_upgrade_fd)
6599 close (daemon->epoll_upgrade_fd);
6602 #ifdef DAUTH_SUPPORT 6604 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6608 #ifdef HTTPS_SUPPORT 6611 gnutls_priority_deinit (daemon->priority_cache);
6612 if (daemon->x509_cred)
6613 gnutls_certificate_free_credentials (daemon->x509_cred);
6614 if (daemon->psk_cred)
6615 gnutls_psk_free_server_credentials (daemon->psk_cred);
6618 if (MHD_ITC_IS_VALID_ (daemon->
itc))
6639 #ifdef UPGRADE_SUPPORT 6642 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6643 struct MHD_UpgradeResponseHandle *urh;
6644 struct MHD_UpgradeResponseHandle *urhn;
6647 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6653 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
6660 urh->clean_ready =
true;
6677 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6680 #ifdef UPGRADE_SUPPORT 6686 while (
NULL != susp)
6688 if (
NULL == susp->urh)
6690 "MHD_stop_daemon() called while we have suspended connections.\n"));
6691 #ifdef HTTPS_SUPPORT 6692 else if (used_tls &&
6694 (! susp->urh->clean_ready) )
6695 shutdown (susp->urh->app.socket,
6700 #ifdef HAVE_MESSAGES 6701 if (! susp->urh->was_closed)
6704 "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
6706 susp->urh->was_closed =
true;
6723 "MHD_stop_daemon() called while we have suspended connections.\n"));
6728 #if MHD_WINSOCK_SOCKETS 6731 (! MHD_itc_activate_ (
daemon->
itc,
"e")) )
6733 "Failed to signal shutdown via inter-thread communication channel"));
6737 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6747 if (! MHD_join_thread_ (pos->
pid.handle))
6762 #ifdef UPGRADE_SUPPORT 6777 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6798 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6811 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6826 "Failed to signal shutdown via inter-thread communication channel."));
6831 #ifdef HAVE_LISTEN_SHUTDOWN 6834 (void) shutdown (
fd,
6844 #ifdef EPOLL_SUPPORT 6846 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6854 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6864 "Failed to signal shutdown via inter-thread communication channel"));
6868 #ifdef HAVE_LISTEN_SHUTDOWN 6872 (void) shutdown (
fd,
6880 if (! MHD_join_thread_ (
daemon->
pid.handle))
6895 #ifdef EPOLL_SUPPORT 6897 (-1 !=
daemon->epoll_fd) )
6899 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6901 (-1 !=
daemon->epoll_upgrade_fd) )
6906 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6919 #ifdef HTTPS_SUPPORT 6920 if (
daemon->have_dhparams)
6922 gnutls_dh_params_deinit (
daemon->https_mem_dhparams);
6923 daemon->have_dhparams =
false;
6927 gnutls_priority_deinit (
daemon->priority_cache);
6929 gnutls_certificate_free_credentials (
daemon->x509_cred);
6931 gnutls_psk_free_server_credentials (
daemon->psk_cred);
6935 #ifdef DAUTH_SUPPORT 6937 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6941 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6975 #ifdef EPOLL_SUPPORT 6986 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 7044 #ifdef PACKAGE_VERSION 7045 return PACKAGE_VERSION;
7047 static char ver[12] =
"\0\0\0\0\0\0\0\0\0\0\0";
7050 int res = MHD_snprintf_ (ver,
7056 if ((0 >= res)||(
sizeof(ver) <= res))
7081 #ifdef HAVE_MESSAGES 7087 #ifdef HTTPS_SUPPORT 7093 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3 7099 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030603 7111 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) 7123 #ifdef EPOLL_SUPPORT 7129 #ifdef HAVE_LISTEN_SHUTDOWN 7135 #ifdef _MHD_ITC_SOCKETPAIR 7147 #ifdef BAUTH_SUPPORT 7153 #ifdef DAUTH_SUPPORT 7159 #ifdef HAVE_POSTPROCESSOR 7165 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111 7171 #if defined(HAVE_PREAD64) || defined(_WIN32) 7173 #elif defined(HAVE_PREAD) 7174 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
7175 #elif defined(HAVE_LSEEK64) 7178 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
7181 #if defined(MHD_USE_THREAD_NAME_) 7187 #if defined(UPGRADE_SUPPORT) 7193 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32) 7199 #ifdef MHD_USE_GETSOCKNAME 7205 #if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || \ 7206 defined (MSG_NOSIGNAL) 7212 #ifdef _MHD_HAVE_SENDFILE 7218 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 7229 #ifdef MHD_HTTPS_REQUIRE_GRYPT 7230 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600 7231 #if defined(MHD_USE_POSIX_THREADS) 7232 GCRY_THREAD_OPTION_PTHREAD_IMPL;
7233 #elif defined(MHD_W32_MUTEX_) 7236 gcry_w32_mutex_init (
void **ppmtx)
7238 *ppmtx = malloc (
sizeof (MHD_mutex_));
7242 if (! MHD_mutex_init_ ((MHD_mutex_*) *ppmtx))
7254 gcry_w32_mutex_destroy (
void **ppmtx)
7256 int res = (MHD_mutex_destroy_ ((MHD_mutex_*) *ppmtx)) ? 0 : EINVAL;
7263 gcry_w32_mutex_lock (
void **ppmtx)
7265 return MHD_mutex_lock_ ((MHD_mutex_*) *ppmtx) ? 0 : EINVAL;
7270 gcry_w32_mutex_unlock (
void **ppmtx)
7272 return MHD_mutex_unlock_ ((MHD_mutex_*) *ppmtx) ? 0 : EINVAL;
7276 static struct gcry_thread_cbs gcry_threads_w32 = {
7277 (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
7278 NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
7279 gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
7293 #if defined(MHD_WINSOCK_SOCKETS) 7300 #if defined(MHD_WINSOCK_SOCKETS) 7301 if (0 != WSAStartup (MAKEWORD (2, 2), &wsd))
7302 MHD_PANIC (
_ (
"Failed to initialize winsock\n"));
7303 mhd_winsock_inited_ = 1;
7304 if ((2 != LOBYTE (wsd.wVersion))&&(2 != HIBYTE (wsd.wVersion)))
7305 MHD_PANIC (
_ (
"Winsock version 2.2 is not available\n"));
7307 #ifdef HTTPS_SUPPORT 7308 #ifdef MHD_HTTPS_REQUIRE_GRYPT 7309 #if GCRYPT_VERSION_NUMBER < 0x010600 7310 #if defined(MHD_USE_POSIX_THREADS) 7311 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7312 &gcry_threads_pthread))
7313 MHD_PANIC (
_ (
"Failed to initialise multithreading in libgcrypt\n"));
7314 #elif defined(MHD_W32_MUTEX_) 7315 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7317 MHD_PANIC (
_ (
"Failed to initialise multithreading in libgcrypt\n"));
7319 gcry_check_version (
NULL);
7321 if (
NULL == gcry_check_version (
"1.6.0"))
7323 "libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n"));
7326 gnutls_global_init ();
7329 #ifdef HAVE_FREEBSD_SENDFILE 7330 MHD_conn_init_static_ ();
7339 #ifdef HTTPS_SUPPORT 7340 gnutls_global_deinit ();
7342 #if defined(MHD_WINSOCK_SOCKETS) 7343 if (mhd_winsock_inited_)
7349 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
#define MHD_send_(s, b, l)
unsigned int per_ip_connection_limit
void * unescape_callback_cls
volatile int global_init_count
void MHD_connection_handle_write(struct MHD_Connection *connection)
_MHD_EXTERN struct MHD_Daemon * MHD_start_daemon_va(unsigned int flags, uint16_t port, MHD_AcceptPolicyCallback apc, void *apc_cls, MHD_AccessHandlerCallback dh, void *dh_cls, va_list ap)
Header for platform missing functions.
static int parse_options(struct MHD_Daemon *daemon, const struct sockaddr **servaddr,...)
_MHD_EXTERN const char * MHD_get_version(void)
bool data_already_pending
void MHD_update_last_activity_(struct MHD_Connection *connection)
int(* MHD_PskServerCredentialsCallback)(void *cls, const struct MHD_Connection *connection, const char *username, void **psk, size_t *psk_size)
#define MHD_SYS_select_(n, r, w, e, t)
struct sockaddr_storage addr
struct MHD_Connection * cleanup_head
enum MHD_CONNECTION_STATE state
static int call_handlers(struct MHD_Connection *con, bool read_ready, bool write_ready, bool force_close)
void MHD_init_mem_pools_(void)
enum MHD_ConnectionEventLoopInfo event_loop_info
void(* VfprintfFunctionPointerType)(void *cls, const char *format, va_list va)
static void MHD_default_logger_(void *cls, const char *fm, va_list ap)
#define MHD_ITC_IS_INVALID_(itc)
struct MHD_Connection * prevX
MHD_thread_handle_ID_ pid
#define MHD_mutex_unlock_chk_(pmutex)
time_t connection_timeout
Methods for managing connections.
_MHD_EXTERN int MHD_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
#define MHD_socket_get_error_()
internal monotonic clock functions implementations
#define MHD_mutex_destroy_chk_(pmutex)
void * MHD_calloc_(size_t nelem, size_t elsize)
#define MHD_socket_strerr_(err)
MHD_socket MHD_socket_create_listen_(int pf)
#define EDLL_insert(head, tail, element)
_MHD_EXTERN int MHD_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen)
struct MHD_Response * response
struct MHD_Connection * manual_timeout_head
void *(* LogCallback)(void *cls, const char *uri, struct MHD_Connection *con)
#define MHD_MAX_CONNECTIONS_DEFAULT
MHD_thread_handle_ID_ pid
void * tdelete(const void *__restrict vkey, void **__restrict vrootp, int(*compar)(const void *, const void *))
time_t MHD_monotonic_sec_counter(void)
int MHD_add_to_fd_set_(MHD_socket fd, fd_set *set, MHD_socket *max_fd, unsigned int fd_setsize)
static void mhd_panic_std(void *cls, const char *file, unsigned int line, const char *reason)
MHD_AccessHandlerCallback default_handler
static void MHD_ip_count_lock(struct MHD_Daemon *daemon)
void MHD_suspend_connection(struct MHD_Connection *connection)
static size_t unescape_wrapper(void *cls, struct MHD_Connection *connection, char *val)
#define MHD_SCKT_ERR_IS_EAGAIN_(err)
_MHD_EXTERN struct MHD_Daemon * MHD_start_daemon(unsigned int flags, uint16_t port, MHD_AcceptPolicyCallback apc, void *apc_cls, MHD_AccessHandlerCallback dh, void *dh_cls,...)
#define MHD_SCKT_LAST_ERR_IS_(code)
static int parse_options_va(struct MHD_Daemon *daemon, const struct sockaddr **servaddr, va_list ap)
Methods for managing response objects.
_MHD_EXTERN void MHD_set_panic_func(MHD_PanicCallback cb, void *cls)
#define MHD_UNSIGNED_LONG_LONG
void * uri_log_callback_cls
struct MHD_Daemon * daemon
static struct MHD_Daemon * MHD_get_master(struct MHD_Daemon *daemon)
void(* MHD_PanicCallback)(void *cls, const char *file, unsigned int line, const char *reason)
#define MHD_TEST_ALLOW_SUSPEND_RESUME
int listening_address_reuse
MHD_mutex_ per_ip_connection_mutex
#define MHD_TYPE_IS_SIGNED_(type)
MHD_NotifyConnectionCallback notify_connection
Header for platform-independent inter-thread communication.
struct MHD_Connection * next
void * tsearch(const void *vkey, void **vrootp, int(*compar)(const void *, const void *))
#define DLL_insert(head, tail, element)
static int MHD_ip_addr_compare(const void *a1, const void *a2)
#define MHD_socket_last_strerr_()
struct MHD_Connection * connections_tail
struct MHD_Daemon * worker_pool
_MHD_EXTERN void MHD_stop_daemon(struct MHD_Daemon *daemon)
static int MHD_ip_addr_to_key(const struct sockaddr *addr, socklen_t addrlen, struct MHD_IPCount *key)
struct MemoryPool * MHD_pool_create(size_t max)
#define MHD_INVALID_SOCKET
internal shared structures
static int MHD_select(struct MHD_Daemon *daemon, int may_block)
#define MHD_POOL_SIZE_DEFAULT
void MHD_set_https_callbacks(struct MHD_Connection *connection)
#define MHD_SCKT_SEND_MAX_SIZE_
unsigned int connection_limit
unsigned int worker_pool_size
struct MHD_Connection * connections_head
_MHD_EXTERN int MHD_run_from_select(struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set)
#define MHD_socket_close_chk_(fd)
LogCallback uri_log_callback
void MHD_connection_handle_read(struct MHD_Connection *connection)
void MHD_connection_mark_closed_(struct MHD_Connection *connection)
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode rtc)
time_t connection_timeout
#define MHD_SCKT_ERR_IS_(err, code)
static int MHD_ip_limit_add(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Methods for managing connections.
struct MHD_Daemon * master
#define EDLL_remove(head, tail, element)
struct MHD_Connection * manual_timeout_tail
static void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
struct MHD_Connection * prev
#define TIMEVAL_TV_SEC_MAX
#define DLL_remove(head, tail, element)
#define MHD_strerror_(errnum)
void * tfind(const void *vkey, void *const *vrootp, int(*compar)(const void *, const void *))
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ thread_main_handle_connection(void *data)
static int internal_get_fdset2(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd, unsigned int fd_setsize)
struct MHD_Connection * normal_timeout_head
#define _MHD_SYS_DEFAULT_FD_SETSIZE
void MHD_pool_destroy(struct MemoryPool *pool)
UnescapeCallback unescape_callback
_MHD_EXTERN void MHD_free(void *ptr)
#define MAYBE_SOCK_NOSIGPIPE
void internal_suspend_connection_(struct MHD_Connection *connection)
void MHD_connection_finish_forward_(struct MHD_Connection *connection) MHD_NONNULL(1)
unsigned int listen_backlog_size
#define XDLL_remove(head, tail, element)
void MHD_monotonic_sec_counter_finish(void)
#define _SET_INIT_AND_DEINIT_FUNCS(FI, FD)
static int internal_run_from_select(struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set)
struct MHD_Connection * suspended_connections_tail
#define MHD_create_named_thread_(t, n, s, r, a)
MHD_AcceptPolicyCallback apc
struct MHD_Connection * cleanup_tail
int MHD_connection_handle_idle(struct MHD_Connection *connection)
static int resume_suspended_connections(struct MHD_Daemon *daemon)
#define MHD_itc_destroy_chk_(itc)
static int internal_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen, bool external_add, bool non_blck)
int(* MHD_AccessHandlerCallback)(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls)
static int MHD_poll(struct MHD_Daemon *daemon, int may_block)
static void MHD_cleanup_connections(struct MHD_Daemon *daemon)
int MHD_socket_set_nodelay_(MHD_socket sock, bool on)
void MHD_monotonic_sec_counter_init(void)
#define MHD_recv_(s, b, l)
static int MHD_accept_connection(struct MHD_Daemon *daemon)
_MHD_EXTERN int MHD_get_fdset(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd)
static void MHD_ip_count_unlock(struct MHD_Daemon *daemon)
void(* MHD_RequestCompletedCallback)(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
struct MHD_Connection * normal_timeout_tail
void MHD_check_global_init_(void)
MHD_RequestCompletedCallback notify_completed
#define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)
#define MHD_mutex_lock_chk_(pmutex)
#define MHD_SCKT_FD_FITS_FDSET_(fd, pset)
static void close_connection(struct MHD_Connection *pos)
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
void * notify_completed_cls
_MHD_EXTERN int MHD_run(struct MHD_Daemon *daemon)
int MHD_socket_nonblocking_(MHD_socket sock)
size_t(* UnescapeCallback)(void *cls, struct MHD_Connection *conn, char *uri)
void * notify_connection_cls
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ MHD_polling_thread(void *cls)
MHD_PanicCallback mhd_panic
#define XDLL_insert(head, tail, element)
#define MHD_UNSIGNED_LONG_LONG_PRINTF
void MHD_resume_connection(struct MHD_Connection *connection)
_MHD_EXTERN int MHD_is_feature_supported(enum MHD_FEATURE feature)
struct MHD_Connection * suspended_connections_head
void * per_ip_connection_count
size_t read_buffer_offset
_MHD_EXTERN int MHD_get_fdset2(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd, unsigned int fd_setsize)
void * default_handler_cls
#define MHD_SCKT_ERR_IS_EINTR_(err)
MHD_mutex_ cleanup_connection_mutex
_MHD_EXTERN MHD_socket MHD_quiesce_daemon(struct MHD_Daemon *daemon)
int(* MHD_AcceptPolicyCallback)(void *cls, const struct sockaddr *addr, socklen_t addrlen)
void(* MHD_NotifyConnectionCallback)(void *cls, struct MHD_Connection *connection, void **socket_context, enum MHD_ConnectionNotificationCode toe)
_MHD_EXTERN const union MHD_DaemonInfo * MHD_get_daemon_info(struct MHD_Daemon *daemon, enum MHD_DaemonInfoType info_type,...)
_MHD_EXTERN size_t MHD_http_unescape(char *val)
#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)
static void close_all_connections(struct MHD_Daemon *daemon)
limits values definitions
int MHD_socket_noninheritable_(MHD_socket sock)
#define MAYBE_SOCK_NONBLOCK
MHD_FLAG
Flags for the struct MHD_Daemon.
int MHD_socket_buffering_reset_(MHD_socket sock)
#define MAYBE_SOCK_CLOEXEC