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);
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) {
612 #if GNUTLS_VERSION_NUMBER >= 0x030111 613 ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
617 daemon->https_key_password,
622 _(
"Failed to setup x509 certificate/key: pre 3.X.X version " \
623 "of GnuTLS does not support setting key password"));
629 ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
632 GNUTLS_X509_FMT_PEM);
636 "GnuTLS failed to setup x509 certificate/key: %s\n",
637 gnutls_strerror (ret));
641 #if GNUTLS_VERSION_MAJOR >= 3 642 if (
NULL != daemon->cert_callback)
645 #if GNUTLS_VERSION_NUMBER >= 0x030603 646 else if (
NULL != daemon->cert_callback2)
651 "You need to specify a certificate and key location\n");
665 switch (daemon->cred_type)
667 case GNUTLS_CRD_CERTIFICATE:
669 gnutls_certificate_allocate_credentials (&daemon->x509_cred))
670 return GNUTLS_E_MEMORY_ERROR;
671 return MHD_init_daemon_certificate (daemon);
674 gnutls_psk_allocate_server_credentials (&daemon->psk_cred))
675 return GNUTLS_E_MEMORY_ERROR;
680 _(
"Error: invalid credentials type %d specified.\n"),
723 fd_set *write_fd_set,
724 fd_set *except_fd_set,
736 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 750 urh_to_fdset (
struct MHD_UpgradeResponseHandle *urh,
755 unsigned int fd_setsize)
757 const MHD_socket conn_sckt = urh->connection->socket_fd;
765 if ( (urh->in_buffer_used < urh->in_buffer_size) &&
771 if ( (0 != urh->out_buffer_used) &&
780 ((0 != urh->in_buffer_size) ||
781 (0 != urh->out_buffer_size) ||
782 (0 != urh->out_buffer_used)))
790 if ( (urh->out_buffer_used < urh->out_buffer_size) &&
796 if ( (0 != urh->in_buffer_used) &&
805 ((0 != urh->out_buffer_size) ||
806 (0 != urh->in_buffer_size) ||
807 (0 != urh->in_buffer_used)))
828 urh_from_fdset (
struct MHD_UpgradeResponseHandle *urh,
833 const MHD_socket conn_sckt = urh->connection->socket_fd;
842 if (FD_ISSET (conn_sckt, rs))
844 if (FD_ISSET (conn_sckt, ws))
846 if (FD_ISSET (conn_sckt, es))
851 if (FD_ISSET (mhd_sckt, rs))
853 if (FD_ISSET (mhd_sckt, ws))
855 if (FD_ISSET (mhd_sckt, es))
871 urh_update_pollfd (
struct MHD_UpgradeResponseHandle *urh,
877 if (urh->in_buffer_used < urh->in_buffer_size)
878 p[0].events |= POLLIN;
879 if (0 != urh->out_buffer_used)
880 p[0].events |= POLLOUT;
885 ((0 != urh->in_buffer_size) ||
886 (0 != urh->out_buffer_size) ||
887 (0 != urh->out_buffer_used)))
888 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
890 if (urh->out_buffer_used < urh->out_buffer_size)
891 p[1].events |= POLLIN;
892 if (0 != urh->in_buffer_used)
893 p[1].events |= POLLOUT;
898 ((0 != urh->out_buffer_size) ||
899 (0 != urh->in_buffer_size) ||
900 (0 != urh->in_buffer_used)))
901 p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
912 urh_to_pollfd (
struct MHD_UpgradeResponseHandle *urh,
915 p[0].fd = urh->connection->socket_fd;
916 p[1].fd = urh->mhd.socket;
917 urh_update_pollfd (urh,
928 urh_from_pollfd (
struct MHD_UpgradeResponseHandle *urh,
935 if (0 != (p[0].revents & POLLIN))
937 if (0 != (p[0].revents & POLLOUT))
939 if (0 != (p[0].revents & POLLHUP))
941 if (0 != (p[0].revents & MHD_POLL_REVENTS_ERRROR))
943 if (0 != (p[1].revents & POLLIN))
945 if (0 != (p[1].revents & POLLOUT))
947 if (0 != (p[1].revents & POLLHUP))
949 if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
973 fd_set *write_fd_set,
974 fd_set *except_fd_set,
976 unsigned int fd_setsize)
1012 #ifdef MHD_POSIX_SOCKETS 1025 #ifdef MHD_POSIX_SOCKETS 1033 if ( (
NULL == except_fd_set) ||
1045 #ifdef MHD_WINSOCK_SOCKETS 1058 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 1060 struct MHD_UpgradeResponseHandle *urh;
1062 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
1076 #ifdef HAVE_MESSAGES 1079 _(
"Maximum socket in select set: %d\n"),
1121 fd_set *read_fd_set,
1122 fd_set *write_fd_set,
1123 fd_set *except_fd_set,
1125 unsigned int fd_setsize)
1129 if ( (
NULL == daemon) ||
1130 (
NULL == read_fd_set) ||
1131 (
NULL == write_fd_set) ||
1136 if (
NULL == except_fd_set)
1138 #ifdef HAVE_MESSAGES 1140 _(
"MHD_get_fdset2() called with except_fd_set " 1141 "set to NULL. Such behavior is unsupported.\n"));
1144 except_fd_set = &es;
1147 #ifdef EPOLL_SUPPORT 1192 bool states_info_processed =
false;
1196 #ifdef HTTPS_SUPPORT 1207 states_info_processed =
true;
1216 states_info_processed =
true;
1226 if (!states_info_processed)
1273 #ifdef HTTPS_SUPPORT 1283 #ifdef UPGRADE_SUPPORT 1294 struct MHD_UpgradeResponseHandle *urh = connection->urh;
1298 #ifdef HTTPS_SUPPORT 1302 gnutls_bye (connection->tls_session,
1311 connection->urh =
NULL;
1317 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 1327 process_urh (
struct MHD_UpgradeResponseHandle *urh)
1342 #ifdef HAVE_MESSAGES 1343 if (! urh->was_closed)
1346 _(
"Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
1349 urh->was_closed =
true;
1351 was_closed = urh->was_closed;
1356 if (0 < urh->in_buffer_used)
1358 #ifdef HAVE_MESSAGES 1361 " bytes of data received from remote side: application shut down socket\n"),
1371 if (0 != urh->out_buffer_size)
1374 urh->in_buffer_used = 0;
1378 urh->in_buffer_size = 0;
1401 (urh->in_buffer_used < urh->in_buffer_size) )
1406 buf_size = urh->in_buffer_size - urh->in_buffer_used;
1411 res = gnutls_record_recv (connection->tls_session,
1412 &urh->in_buffer[urh->in_buffer_used],
1416 if (GNUTLS_E_INTERRUPTED != res)
1419 if (GNUTLS_E_AGAIN != res)
1424 urh->in_buffer_size = 0;
1430 urh->in_buffer_used += res;
1431 if (buf_size > (
size_t)res)
1433 else if (0 < gnutls_record_check_pending (connection->tls_session))
1442 urh->in_buffer_size = 0;
1450 (urh->out_buffer_used < urh->out_buffer_size) )
1455 buf_size = urh->out_buffer_size - urh->out_buffer_used;
1460 &urh->out_buffer[urh->out_buffer_used],
1479 urh->out_buffer_size = 0;
1485 urh->out_buffer_used += res;
1486 if (buf_size > (
size_t)res)
1496 urh->out_buffer_size = 0;
1504 (urh->out_buffer_used > 0) )
1509 data_size = urh->out_buffer_used;
1513 res = gnutls_record_send (connection->tls_session,
1518 if (GNUTLS_E_INTERRUPTED != res)
1521 if (GNUTLS_E_AGAIN != res)
1525 #ifdef HAVE_MESSAGES 1528 " bytes of data received from application: %s\n"),
1530 gnutls_strerror(res));
1533 urh->out_buffer_used = 0;
1535 urh->out_buffer_size = 0;
1542 const size_t next_out_buffer_used = urh->out_buffer_used - res;
1543 if (0 != next_out_buffer_used)
1545 memmove (urh->out_buffer,
1546 &urh->out_buffer[res],
1547 next_out_buffer_used);
1548 if (data_size > (
size_t)res)
1551 urh->out_buffer_used = next_out_buffer_used;
1553 if ( (0 == urh->out_buffer_used) &&
1561 urh->out_buffer_size = 0;
1570 (urh->in_buffer_used > 0) )
1575 data_size = urh->in_buffer_used;
1593 #ifdef HAVE_MESSAGES 1596 " bytes of data received from remote side: %s\n"),
1601 urh->in_buffer_used = 0;
1603 urh->in_buffer_size = 0;
1611 const size_t next_in_buffer_used = urh->in_buffer_used - res;
1612 if (0 != next_in_buffer_used)
1614 memmove (urh->in_buffer,
1615 &urh->in_buffer[res],
1616 next_in_buffer_used);
1617 if (data_size > (
size_t)res)
1620 urh->in_buffer_used = next_in_buffer_used;
1622 if ( (0 == urh->in_buffer_used) &&
1628 urh->in_buffer_size = 0;
1637 (urh->in_buffer_used < urh->in_buffer_size) &&
1642 ( (0 != urh->out_buffer_size) ||
1643 (0 != urh->out_buffer_used) ) )
1646 #ifdef HAVE_MESSAGES 1647 if (0 < urh->out_buffer_used)
1650 " bytes of data received from application: daemon shut down\n"),
1654 urh->out_buffer_used = 0;
1658 urh->out_buffer_size = 0;
1664 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 1665 #ifdef UPGRADE_SUPPORT 1677 #ifdef HTTPS_SUPPORT 1678 struct MHD_UpgradeResponseHandle *urh = con->urh;
1687 while ( (0 != urh->in_buffer_size) ||
1688 (0 != urh->out_buffer_size) ||
1689 (0 != urh->in_buffer_used) ||
1690 (0 != urh->out_buffer_used) )
1704 result = urh_to_fdset (urh,
1712 #ifdef HAVE_MESSAGES 1714 _(
"Error preparing select\n"));
1721 struct timeval* tvp;
1724 (urh->in_buffer_used < urh->in_buffer_size))
1746 #ifdef HAVE_MESSAGES 1748 _(
"Error during select (%d): `%s'\n"),
1754 urh_from_fdset (urh,
1769 p[0].fd = urh->connection->socket_fd;
1770 p[1].fd = urh->mhd.socket;
1772 while ( (0 != urh->in_buffer_size) ||
1773 (0 != urh->out_buffer_size) ||
1774 (0 != urh->in_buffer_used) ||
1775 (0 != urh->out_buffer_used) )
1779 urh_update_pollfd(urh, p);
1782 (urh->in_buffer_used < urh->in_buffer_size))
1787 if (MHD_sys_poll_ (p,
1795 #ifdef HAVE_MESSAGES 1797 _(
"Error during poll: `%s'\n"),
1802 urh_from_pollfd (urh,
1826 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
1837 struct timeval *tvp;
1843 #define EXTRA_SLOTS 1 1845 #define EXTRA_SLOTS 0 1854 const bool use_poll = 0;
1856 bool was_suspended =
false;
1857 MHD_thread_init_(&(con->
pid));
1863 #ifdef UPGRADE_SUPPORT 1864 struct MHD_UpgradeResponseHandle *
const urh = con->urh;
1866 static const void *
const urh =
NULL;
1873 was_suspended =
true;
1882 #ifdef HAVE_MESSAGES 1884 _(
"Failed to add FD to fd_set\n"));
1898 #ifdef HAVE_MESSAGES 1900 _(
"Error during select (%d): `%s'\n"),
1910 p[0].events = POLLIN;
1911 p[0].fd = MHD_itc_r_fd_ (daemon->
itc);
1913 if (0 > MHD_sys_poll_ (p,
1919 #ifdef HAVE_MESSAGES 1921 _(
"Error during poll: `%s'\n"),
1928 MHD_itc_clear_ (daemon->
itc);
1937 was_suspended =
false;
1943 #ifdef HTTPS_SUPPORT
1955 if ( (
NULL == tvp) &&
1963 const time_t seconds_left = timeout - (now - con->
last_activity);
1964 #if !defined(_WIN32) || defined(__CYGWIN__) 1965 tv.tv_sec = seconds_left;
1979 bool err_state =
false;
2013 if (MHD_ITC_IS_VALID_(daemon->
itc) )
2024 #ifdef HAVE_MESSAGES 2026 _(
"Failed to add FD to fd_set\n"));
2042 #ifdef HAVE_MESSAGES 2044 _(
"Error during select (%d): `%s'\n"),
2053 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2054 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
2056 MHD_itc_clear_ (daemon->
itc);
2079 p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
2082 p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
2085 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
2093 if (MHD_ITC_IS_VALID_(daemon->
itc))
2095 p[1].events |= POLLIN;
2096 p[1].fd = MHD_itc_r_fd_ (daemon->
itc);
2101 if (MHD_sys_poll_ (p,
2107 (
NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
2111 #ifdef HAVE_MESSAGES 2113 _(
"Error during poll: `%s'\n"),
2121 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2122 (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
2123 MHD_itc_clear_ (daemon->
itc);
2127 0 != (p[0].revents & POLLIN),
2128 0 != (p[0].revents & POLLOUT),
2129 0 != (p[0].revents & (POLLERR | MHD_POLL_REVENTS_ERR_DISC))))
2133 #ifdef UPGRADE_SUPPORT 2134 if (MHD_CONNECTION_UPGRADE == con->
state)
2146 thread_main_connection_upgrade (con);
2150 con->urh->clean_ready =
true;
2158 return (MHD_THRD_RTRN_TYPE_) 0;
2163 #ifdef HAVE_MESSAGES 2165 _(
"Processing thread terminating. Closing connection\n"));
2189 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2190 (! MHD_itc_activate_ (daemon->
itc,
"t")) )
2192 #ifdef HAVE_MESSAGES 2194 _(
"Failed to signal thread termination via inter-thread communication channel."));
2197 return (MHD_THRD_RTRN_TYPE_) 0;
2212 #if defined(HTTPS_SUPPORT) 2213 #if !defined(MHD_WINSOCK_SOCKETS) && !defined(MHD_socket_nosignal_) && \ 2214 (GNUTLS_VERSION_NUMBER+0 < 0x030402) && defined(MSG_NOSIGNAL) 2220 #define MHD_TLSLIB_NEED_PUSH_FUNC 1 2223 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC 2229 MHD_tls_push_func_(gnutls_transport_ptr_t trnsp,
2233 #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) 2251 psk_gnutls_adapter (gnutls_session_t session,
2252 const char *username,
2253 gnutls_datum_t *key)
2258 size_t app_psk_size;
2260 connection = gnutls_session_get_ptr (session);
2261 if (
NULL == connection)
2263 #ifdef HAVE_MESSAGES 2265 MHD_PANIC (
_(
"Internal server error. This should be impossible.\n"));
2269 daemon = connection->
daemon;
2270 #if GNUTLS_VERSION_MAJOR >= 3 2271 if (
NULL == daemon->cred_callback)
2273 #ifdef HAVE_MESSAGES 2275 _(
"PSK not supported by this server.\n"));
2279 if (0 != daemon->cred_callback (daemon->cred_callback_cls,
2285 if (
NULL == (key->data = gnutls_malloc (app_psk_size)))
2287 #ifdef HAVE_MESSAGES 2289 _(
"PSK authentication failed: gnutls_malloc failed to allocate memory\n"));
2296 #ifdef HAVE_MESSAGES 2298 _(
"PSK authentication failed: PSK too long\n"));
2303 key->size = (
unsigned int)app_psk_size;
2310 #ifdef HAVE_MESSAGES 2312 _(
"PSK not supported by this server.\n"));
2348 const struct sockaddr *addr,
2354 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2360 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2392 #ifdef HAVE_MESSAGES 2394 _(
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
2395 (
int) client_socket,
2405 #ifdef MHD_socket_nosignal_ 2406 if (! MHD_socket_nosignal_ (client_socket))
2408 #ifdef HAVE_MESSAGES 2410 _(
"Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
2413 #ifndef MSG_NOSIGNAL 2424 #ifdef HAVE_MESSAGES 2427 _(
"Accepted connection on socket %d\n"),
2437 #ifdef HAVE_MESSAGES 2439 _(
"Server reached connection limit. Closing inbound connection.\n"));
2455 #ifdef HAVE_MESSAGES 2457 _(
"Connection rejected by application. Closing connection.\n"));
2473 #ifdef HAVE_MESSAGES 2475 "Error allocating memory: %s\n",
2488 #ifdef HAVE_MESSAGES 2490 _(
"Error allocating memory: %s\n"),
2505 if (
NULL == (connection->
addr = malloc (addrlen)))
2508 #ifdef HAVE_MESSAGES 2510 _(
"Error allocating memory: %s\n"),
2522 memcpy (connection->
addr,
2528 connection->
daemon = daemon;
2538 #ifdef HTTPS_SUPPORT 2539 gnutls_init_flags_t flags;
2541 flags = GNUTLS_SERVER;
2542 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030402) 2543 flags |= GNUTLS_NO_SIGNAL;
2545 #if GNUTLS_VERSION_MAJOR >= 3 2546 flags |= GNUTLS_NONBLOCK;
2548 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030603) 2550 flags |= GNUTLS_POST_HANDSHAKE_AUTH;
2552 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030605) 2554 flags |= GNUTLS_ENABLE_EARLY_DATA;
2558 gnutls_init (&connection->tls_session,
2560 gnutls_priority_set (connection->tls_session,
2561 daemon->priority_cache);
2562 gnutls_session_set_ptr (connection->tls_session,
2564 switch (daemon->cred_type)
2567 case GNUTLS_CRD_CERTIFICATE:
2568 gnutls_credentials_set (connection->tls_session,
2569 GNUTLS_CRD_CERTIFICATE,
2572 case GNUTLS_CRD_PSK:
2573 gnutls_credentials_set (connection->tls_session,
2576 gnutls_psk_set_server_credentials_function (daemon->psk_cred,
2577 &psk_gnutls_adapter);
2580 #ifdef HAVE_MESSAGES 2581 MHD_DLOG (connection->
daemon,
2582 _(
"Failed to setup TLS credentials: unknown credential type %d\n"),
2589 free (connection->
addr);
2597 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030109) && !defined(_WIN64) 2598 gnutls_transport_set_int (connection->tls_session,
2599 (
int)(client_socket));
2601 gnutls_transport_set_ptr (connection->tls_session,
2602 (gnutls_transport_ptr_t)(intptr_t)(client_socket));
2604 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC 2605 gnutls_transport_set_push_function (connection->tls_session,
2606 MHD_tls_push_func_);
2608 if (daemon->https_mem_trust)
2609 gnutls_certificate_server_set_request (connection->tls_session,
2610 GNUTLS_CERT_REQUEST);
2617 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2623 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2627 #ifdef HAVE_MESSAGES 2629 _(
"Server reached connection limit. Closing inbound connection.\n"));
2646 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2654 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2660 daemon->thread_stack_size,
2665 #ifdef HAVE_MESSAGES 2667 "Failed to create a thread: %s\n",
2674 connection->
pid = daemon->
pid;
2676 #ifdef EPOLL_SUPPORT 2681 struct epoll_event event;
2683 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2684 event.data.ptr = connection;
2685 if (0 != epoll_ctl (daemon->epoll_fd,
2691 #ifdef HAVE_MESSAGES 2693 _(
"Call to epoll_ctl failed: %s\n"),
2705 daemon->eready_tail,
2713 (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2714 (! MHD_itc_activate_ (daemon->
itc,
"n")) )
2716 #ifdef HAVE_MESSAGES 2718 _(
"Failed to signal new connection via inter-thread communication channel."));
2728 #ifdef HTTPS_SUPPORT 2729 if (
NULL != connection->tls_session)
2730 gnutls_deinit (connection->tls_session);
2736 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2748 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2752 free (connection->
addr);
2776 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2783 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2807 #ifdef EPOLL_SUPPORT 2813 daemon->eready_tail,
2819 if (0 != epoll_ctl (daemon->epoll_fd,
2823 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
2829 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2872 MHD_PANIC (
_(
"Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2873 #ifdef UPGRADE_SUPPORT 2874 if (
NULL != connection->urh)
2876 #ifdef HAVE_MESSAGES 2878 _(
"Error: connection scheduled for \"upgrade\" cannot be suspended"));
2901 MHD_PANIC (
_(
"Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2902 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2907 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2910 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2911 (! MHD_itc_activate_ (daemon->
itc,
"r")) )
2913 #ifdef HAVE_MESSAGES 2915 _(
"Failed to signal resume via inter-thread communication channel."));
2937 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2941 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2955 #ifdef UPGRADE_SUPPORT 2956 struct MHD_UpgradeResponseHandle *
const urh = pos->urh;
2958 static const void *
const urh =
NULL;
2962 #ifdef UPGRADE_SUPPORT
2963 || ( (
NULL != urh) &&
2964 ( (! urh->was_closed) ||
2965 (! urh->clean_ready) ) )
2995 #ifdef EPOLL_SUPPORT 2999 MHD_PANIC (
"Resumed connection was already in EREADY set\n");
3003 daemon->eready_tail,
3011 #ifdef UPGRADE_SUPPORT 3036 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3039 if ( (used_thr_p_c) &&
3042 if (! MHD_itc_activate_(daemon->
itc,
3045 #ifdef HAVE_MESSAGES 3047 _(
"Failed to signal resume of connection via inter-thread communication channel."));
3085 const struct sockaddr *addr,
3092 #ifdef HAVE_MESSAGES 3094 _(
"Failed to set nonblocking mode on new client socket: %s\n"),
3105 #ifdef HAVE_MESSAGES 3107 _(
"Failed to set noninheritable mode on new client socket.\n"));
3114 #ifdef HAVE_MESSAGES 3116 _(
"Failed to reset buffering mode on new client socket.\n"));
3146 struct sockaddr_in6 addrstorage;
3148 struct sockaddr_in addrstorage;
3150 struct sockaddr *addr = (
struct sockaddr *) &addrstorage;
3156 addrlen =
sizeof (addrstorage);
3159 sizeof (addrstorage));
3186 #ifdef HAVE_MESSAGES 3189 _(
"Error accepting connection: %s\n"),
3201 #ifdef HAVE_MESSAGES 3206 _(
"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"));
3211 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3215 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3218 #ifdef HAVE_MESSAGES 3220 _(
"Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
3227 #if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK) 3230 #ifdef HAVE_MESSAGES 3232 _(
"Failed to set nonblocking mode on incoming connection socket: %s\n"),
3239 #if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC) 3242 #ifdef HAVE_MESSAGES 3244 _(
"Failed to set noninheritable mode on incoming connection socket.\n"));
3248 #ifdef HAVE_MESSAGES 3251 _(
"Accepted connection on socket %d\n"),
3279 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3287 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3291 (! MHD_join_thread_ (pos->
pid.handle)) )
3294 #ifdef UPGRADE_SUPPORT 3295 cleanup_upgraded_connection (pos);
3298 #ifdef HTTPS_SUPPORT 3299 if (
NULL != pos->tls_session)
3300 gnutls_deinit (pos->tls_session);
3312 #ifdef EPOLL_SUPPORT 3322 if ( (-1 !=
daemon->epoll_fd) &&
3331 if (0 != epoll_ctl (
daemon->epoll_fd,
3335 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
3351 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3357 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3387 time_t earliest_deadline;
3394 #ifdef HAVE_MESSAGES 3396 _(
"Illegal call to MHD_get_timeout\n"));
3408 #ifdef EPOLL_SUPPORT 3411 #
if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
3422 have_timeout =
false;
3423 earliest_deadline = 0;
3428 if ( (! have_timeout) ||
3431 have_timeout =
true;
3436 if ( (
NULL != pos) &&
3439 if ( (! have_timeout) ||
3442 have_timeout =
true;
3448 if (earliest_deadline < now)
3452 const time_t second_left = earliest_deadline - now;
3454 if (((
unsigned long long)second_left) >
ULLONG_MAX / 1000)
3457 *timeout = 1000LLU * (
unsigned long long) second_left;
3475 const fd_set *read_fd_set,
3476 const fd_set *write_fd_set,
3477 const fd_set *except_fd_set)
3482 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3483 struct MHD_UpgradeResponseHandle *urh;
3484 struct MHD_UpgradeResponseHandle *urhn;
3493 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
3494 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
3496 MHD_itc_clear_ (daemon->
itc);
3509 while (
NULL != (pos = prev))
3525 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3527 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
3531 urh_from_fdset (urh,
3538 if ( (0 == urh->in_buffer_size) &&
3539 (0 == urh->out_buffer_size) &&
3540 (0 == urh->in_buffer_used) &&
3541 (0 == urh->out_buffer_used) )
3544 urh->clean_ready =
true;
3579 const fd_set *read_fd_set,
3580 const fd_set *write_fd_set,
3581 const fd_set *except_fd_set)
3587 if (
NULL == read_fd_set ||
NULL == write_fd_set)
3589 if (
NULL == except_fd_set)
3591 #ifdef HAVE_MESSAGES 3593 _(
"MHD_run_from_select() called with except_fd_set " 3594 "set to NULL. Such behavior is deprecated.\n"));
3597 except_fd_set = &es;
3601 #ifdef EPOLL_SUPPORT 3602 int ret = MHD_epoll (daemon,
3640 struct timeval timeout;
3647 timeout.tv_usec = 0;
3671 #ifdef HAVE_MESSAGES 3673 _(
"Could not obtain daemon fdsets"));
3688 #ifdef HAVE_MESSAGES 3690 _(
"Could not add listen socket to fdset"));
3695 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
3701 #if defined(MHD_WINSOCK_SOCKETS) 3716 #ifdef HAVE_MESSAGES 3718 _(
"Could not add control inter-thread communication channel FD to fdset"));
3721 #if defined(MHD_WINSOCK_SOCKETS) 3733 (MHD_ITC_IS_VALID_(daemon->
itc)) &&
3745 timeout.tv_usec = 0;
3753 timeout.tv_usec = (ltimeout % 1000) * 1000;
3772 #ifdef HAVE_MESSAGES 3774 _(
"select failed: %s\n"),
3801 unsigned int num_connections;
3804 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3805 struct MHD_UpgradeResponseHandle *urh;
3806 struct MHD_UpgradeResponseHandle *urhn;
3814 num_connections = 0;
3817 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3818 for (urh = daemon->urh_head;
NULL != urh; urh = urh->next)
3819 num_connections += 2;
3825 unsigned int poll_server;
3832 sizeof (
struct pollfd));
3835 #ifdef HAVE_MESSAGES 3837 _(
"Error allocating memory: %s\n"),
3850 p[poll_server].fd = ls;
3851 p[poll_server].events = POLLIN;
3852 p[poll_server].revents = 0;
3853 poll_listen = (int) poll_server;
3857 if (MHD_ITC_IS_VALID_(daemon->
itc))
3859 p[poll_server].fd = MHD_itc_r_fd_ (daemon->
itc);
3860 p[poll_server].events = POLLIN;
3861 p[poll_server].revents = 0;
3862 poll_itc_idx = (int) poll_server;
3872 timeout = (ltimeout > INT_MAX) ? INT_MAX : (
int) ltimeout;
3881 p[poll_server+i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
3884 p[poll_server+i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
3887 p[poll_server+i].events |= MHD_POLL_EVENTS_ERR_DISC;
3895 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3896 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
3898 urh_to_pollfd(urh, &(p[poll_server+i]));
3902 if (0 == poll_server + num_connections)
3907 if (MHD_sys_poll_(p,
3908 poll_server + num_connections,
3917 #ifdef HAVE_MESSAGES 3919 _(
"poll failed: %s\n"),
3932 if ( (-1 != poll_itc_idx) &&
3933 (0 != (p[poll_itc_idx].revents & POLLIN)) )
3934 MHD_itc_clear_ (daemon->
itc);
3944 while (
NULL != (pos = prev))
3948 if (i >= num_connections)
3953 0 != (p[poll_server+i].revents & POLLIN),
3954 0 != (p[poll_server+i].revents & POLLOUT),
3955 0 != (p[poll_server+i].revents & MHD_POLL_REVENTS_ERR_DISC));
3958 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3959 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
3961 if (i >= num_connections)
3968 if ((p[poll_server+i].
fd != urh->connection->socket_fd) ||
3969 (p[poll_server+i+1].fd != urh->mhd.socket))
3971 urh_from_pollfd (urh,
3976 if ( (0 == urh->in_buffer_size) &&
3977 (0 == urh->out_buffer_size) &&
3978 (0 == urh->in_buffer_used) &&
3979 (0 == urh->out_buffer_used) )
3984 urh->clean_ready =
true;
3994 if ( (-1 != poll_listen) &&
3995 (0 != (p[poll_listen].revents & POLLIN)) )
4012 MHD_poll_listen_socket (
struct MHD_Daemon *daemon,
4017 unsigned int poll_count;
4032 p[poll_count].fd = ls;
4033 p[poll_count].events = POLLIN;
4034 p[poll_count].revents = 0;
4035 poll_listen = poll_count;
4038 if (MHD_ITC_IS_VALID_(daemon->
itc))
4040 p[poll_count].fd = MHD_itc_r_fd_ (daemon->
itc);
4041 p[poll_count].events = POLLIN;
4042 p[poll_count].revents = 0;
4043 poll_itc_idx = poll_count;
4054 if (0 == poll_count)
4056 if (MHD_sys_poll_(p,
4064 #ifdef HAVE_MESSAGES 4066 _(
"poll failed: %s\n"),
4071 if ( (-1 != poll_itc_idx) &&
4072 (0 != (p[poll_itc_idx].revents & POLLIN)) )
4073 MHD_itc_clear_ (daemon->
itc);
4078 if ( (-1 != poll_listen) &&
4079 (0 != (p[poll_listen].revents & POLLIN)) )
4101 return MHD_poll_all (daemon,
4103 return MHD_poll_listen_socket (daemon,
4113 #ifdef EPOLL_SUPPORT 4123 #define MAX_EVENTS 128 4126 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4136 is_urh_ready(
struct MHD_UpgradeResponseHandle *
const urh)
4138 const struct MHD_Connection *
const connection = urh->connection;
4140 if ( (0 == urh->in_buffer_size) &&
4141 (0 == urh->out_buffer_size) &&
4142 (0 == urh->in_buffer_used) &&
4143 (0 == urh->out_buffer_used) )
4149 (urh->in_buffer_used < urh->in_buffer_size) )
4152 (urh->out_buffer_used < urh->out_buffer_size) )
4155 (urh->out_buffer_used > 0) )
4158 (urh->in_buffer_used > 0) )
4175 struct epoll_event events[MAX_EVENTS];
4177 struct MHD_UpgradeResponseHandle * pos;
4178 struct MHD_UpgradeResponseHandle * prev;
4180 num_events = MAX_EVENTS;
4181 while (0 != num_events)
4185 num_events = epoll_wait (daemon->epoll_upgrade_fd,
4189 if (-1 == num_events)
4195 #ifdef HAVE_MESSAGES 4197 _(
"Call to epoll_wait failed: %s\n"),
4202 for (i = 0; i < (
unsigned int) num_events; i++)
4204 struct UpgradeEpollHandle *
const ueh = events[i].data.ptr;
4205 struct MHD_UpgradeResponseHandle *
const urh = ueh->urh;
4206 bool new_err_state =
false;
4208 if (urh->clean_ready)
4212 if (0 != (events[i].events & EPOLLIN))
4214 if (0 != (events[i].events & EPOLLOUT))
4216 if (0 != (events[i].events & EPOLLHUP))
4220 (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
4226 new_err_state =
true;
4229 if (! urh->in_eready_list)
4231 if (new_err_state ||
4235 daemon->eready_urh_tail,
4237 urh->in_eready_list =
true;
4242 prev = daemon->eready_urh_tail;
4243 while (
NULL != (pos = prev))
4247 if (! is_urh_ready(pos))
4250 daemon->eready_urh_tail,
4252 pos->in_eready_list =
false;
4255 if ( (0 == pos->in_buffer_size) &&
4256 (0 == pos->out_buffer_size) &&
4257 (0 == pos->in_buffer_used) &&
4258 (0 == pos->out_buffer_used) )
4261 pos->clean_ready =
true;
4278 static const char *
const epoll_itc_marker =
"itc_marker";
4293 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4294 static const char *
const upgrade_marker =
"upgrade_ptr";
4298 struct epoll_event events[MAX_EVENTS];
4299 struct epoll_event event;
4305 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4306 bool run_upgraded =
false;
4309 if (-1 == daemon->epoll_fd)
4316 (! daemon->listen_socket_in_epoll) &&
4319 event.events = EPOLLIN;
4320 event.data.ptr = daemon;
4321 if (0 != epoll_ctl (daemon->epoll_fd,
4326 #ifdef HAVE_MESSAGES 4328 _(
"Call to epoll_ctl failed: %s\n"),
4333 daemon->listen_socket_in_epoll =
true;
4336 (daemon->listen_socket_in_epoll) )
4338 if ( (0 != epoll_ctl (daemon->epoll_fd,
4344 MHD_PANIC (
"Failed to remove listen FD from epoll set\n");
4345 daemon->listen_socket_in_epoll =
false;
4348 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4349 if ( ( (! daemon->upgrade_fd_in_epoll) &&
4350 (-1 != daemon->epoll_upgrade_fd) ) )
4352 event.events = EPOLLIN | EPOLLOUT;
4353 event.data.ptr = (
void *) upgrade_marker;
4354 if (0 != epoll_ctl (daemon->epoll_fd,
4356 daemon->epoll_upgrade_fd,
4359 #ifdef HAVE_MESSAGES 4361 _(
"Call to epoll_ctl failed: %s\n"),
4366 daemon->upgrade_fd_in_epoll =
true;
4369 if ( (daemon->listen_socket_in_epoll) &&
4376 if (0 != epoll_ctl (daemon->epoll_fd,
4380 MHD_PANIC (
_(
"Failed to remove listen FD from epoll set\n"));
4381 daemon->listen_socket_in_epoll =
false;
4394 timeout_ms = INT_MAX;
4396 timeout_ms = (int) timeout_ll;
4413 num_events = MAX_EVENTS;
4414 while (MAX_EVENTS == num_events)
4417 num_events = epoll_wait (daemon->epoll_fd,
4421 if (-1 == num_events)
4426 #ifdef HAVE_MESSAGES 4428 _(
"Call to epoll_wait failed: %s\n"),
4433 for (i=0;i<(
unsigned int) num_events;i++)
4439 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4440 if (upgrade_marker == events[i].
data.ptr)
4444 run_upgraded =
true;
4448 if (epoll_itc_marker == events[i].
data.ptr)
4452 MHD_itc_clear_ (daemon->
itc);
4455 if (daemon == events[i].
data.ptr)
4459 if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
4461 unsigned int series_length = 0;
4467 (series_length < 10) &&
4477 pos = events[i].data.ptr;
4479 if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
4485 daemon->eready_tail,
4492 if (0 != (events[i].events & EPOLLIN))
4500 daemon->eready_tail,
4505 if (0 != (events[i].events & EPOLLOUT))
4512 daemon->eready_tail,
4521 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4522 if (run_upgraded || (
NULL != daemon->eready_urh_head))
4523 run_epoll_for_upgrade (daemon);
4527 prev = daemon->eready_tail;
4528 while (
NULL != (pos = prev))
4545 daemon->eready_tail,
4561 while (
NULL != (pos = prev))
4571 while (
NULL != (pos = prev))
4614 #ifdef EPOLL_SUPPORT 4617 MHD_epoll (daemon,
MHD_NO);
4650 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4669 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4675 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4683 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
4688 MHD_thread_init_(&(daemon->
pid));
4693 #ifdef EPOLL_SUPPORT 4709 return (MHD_THRD_RTRN_TYPE_)0;
4805 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4816 #ifdef HAVE_MESSAGES 4818 "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC\n");
4823 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4828 #ifdef EPOLL_SUPPORT 4833 if (0 != epoll_ctl (daemon->
worker_pool[i].epoll_fd,
4837 MHD_PANIC (
_(
"Failed to remove listen FD from epoll set\n"));
4838 daemon->
worker_pool[i].listen_socket_in_epoll =
false;
4845 MHD_PANIC (
_(
"Failed to signal quiesce via inter-thread communication channel"));
4850 #ifdef EPOLL_SUPPORT 4852 (-1 != daemon->epoll_fd) &&
4853 (daemon->listen_socket_in_epoll) )
4855 if ( (0 != epoll_ctl (daemon->epoll_fd,
4861 MHD_PANIC (
"Failed to remove listen FD from epoll set\n");
4862 daemon->listen_socket_in_epoll =
false;
4865 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
4866 (! MHD_itc_activate_ (daemon->
itc,
"q")) )
4867 MHD_PANIC (
_(
"failed to signal quiesce via inter-thread communication channel"));
4895 const struct sockaddr **servaddr,
4909 const struct sockaddr **servaddr,
4915 va_start (ap, servaddr);
4934 const struct sockaddr **servaddr,
4941 #ifdef HTTPS_SUPPORT 4944 #if GNUTLS_VERSION_MAJOR >= 3 4945 gnutls_certificate_retrieve_function2 *pgcrf;
4947 #if GNUTLS_VERSION_NUMBER >= 0x030603 4948 gnutls_certificate_retrieve_function3 *pgcrf2;
4979 #ifdef HAVE_MESSAGES 4981 _(
"Warning: Too large timeout value, ignored.\n"));
5003 *servaddr = va_arg (ap,
5004 const struct sockaddr *);
5012 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5018 #ifdef HAVE_MESSAGES 5020 _(
"Warning: Zero size, specified for thread pool size, is ignored. " 5021 "Thread pool is not used.\n"));
5026 #ifdef HAVE_MESSAGES 5028 _(
"Warning: \"1\", specified for thread pool size, is ignored. " 5029 "Thread pool is not used.\n"));
5038 #ifdef HAVE_MESSAGES 5040 _(
"Specified thread pool size (%u) too big\n"),
5049 #ifdef HAVE_MESSAGES 5051 _(
"MHD_OPTION_THREAD_POOL_SIZE option is specified but " 5052 "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
5058 #ifdef HAVE_MESSAGES 5060 _(
"Both MHD_OPTION_THREAD_POOL_SIZE option and " 5061 "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
5068 #ifdef HTTPS_SUPPORT 5073 daemon->https_mem_key = pstr;
5074 #ifdef HAVE_MESSAGES 5077 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5085 daemon->https_key_password = pstr;
5086 #ifdef HAVE_MESSAGES 5089 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5097 daemon->https_mem_cert = pstr;
5098 #ifdef HAVE_MESSAGES 5101 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5109 daemon->https_mem_trust = pstr;
5110 #ifdef HAVE_MESSAGES 5113 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5118 daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
5126 gnutls_datum_t dhpar;
5129 if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
5131 #ifdef HAVE_MESSAGES 5133 _(
"Error initializing DH parameters\n"));
5137 dhpar.data = (
unsigned char *) pstr;
5138 pstr_len = strlen (pstr);
5141 #ifdef HAVE_MESSAGES 5143 _(
"Diffie-Hellman parameters string too long\n"));
5147 dhpar.size = (
unsigned int) pstr_len;
5148 if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
5150 GNUTLS_X509_FMT_PEM) < 0)
5152 #ifdef HAVE_MESSAGES 5154 _(
"Bad Diffie-Hellman parameters format\n"));
5156 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
5159 daemon->have_dhparams =
true;
5161 #ifdef HAVE_MESSAGES 5164 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5173 gnutls_priority_deinit (daemon->priority_cache);
5174 ret = gnutls_priority_init (&daemon->priority_cache,
5177 if (GNUTLS_E_SUCCESS != ret)
5179 #ifdef HAVE_MESSAGES 5181 _(
"Setting priorities to `%s' failed: %s\n"),
5183 gnutls_strerror (ret));
5185 daemon->priority_cache =
NULL;
5189 #ifdef HAVE_MESSAGES 5192 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5197 #if GNUTLS_VERSION_MAJOR < 3 5198 #ifdef HAVE_MESSAGES 5200 _(
"MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n"));
5205 gnutls_certificate_retrieve_function2 *);
5207 daemon->cert_callback = pgcrf;
5209 #ifdef HAVE_MESSAGES 5211 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5217 #if GNUTLS_VERSION_NUMBER < 0x030603 5218 #ifdef HAVE_MESSAGES 5220 _(
"MHD_OPTION_HTTPS_CERT_CALLBACK2 requires building MHD with GnuTLS >= 3.6.3\n"));
5224 pgcrf2 = va_arg (ap,
5225 gnutls_certificate_retrieve_function3 *);
5227 daemon->cert_callback2 = pgcrf2;
5229 #ifdef HAVE_MESSAGES 5231 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5237 #ifdef DAUTH_SUPPORT 5239 daemon->digest_auth_rand_size = va_arg (ap,
5241 daemon->digest_auth_random = va_arg (ap,
5245 daemon->nonce_nc_size = va_arg (ap,
5252 #ifdef HAVE_MESSAGES 5254 _(
"MHD_OPTION_LISTEN_SOCKET specified for daemon " 5255 "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
5264 #ifdef HAVE_MESSAGES 5265 daemon->custom_error_log = va_arg (ap,
5267 daemon->custom_error_log_cls = va_arg (ap,
5276 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5278 daemon->thread_stack_size = va_arg (ap,
5284 daemon->fastopen_queue_size = va_arg (ap,
5288 #ifdef HAVE_MESSAGES 5290 _(
"TCP fastopen is not supported on this platform\n"));
5296 unsigned int) ? 1 : -1;
5304 #ifdef HAVE_MESSAGES 5309 _(
"Flag MHD_USE_PEDANTIC_CHECKS is ignored because " 5310 "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n"));
5328 (
size_t) oa[i].
value,
5344 (
unsigned int) oa[i].
value,
5349 #ifdef HTTPS_SUPPORT 5354 (gnutls_credentials_type_t) oa[i].
value,
5405 (
void *) oa[i].
value,
5415 (
size_t) oa[i].
value,
5432 #ifdef HTTPS_SUPPORT 5434 #if GNUTLS_VERSION_MAJOR >= 3 5435 daemon->cred_callback = va_arg (ap,
5437 daemon->cred_callback_cls = va_arg (ap,
5442 _(
"MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3\n"),
5448 #ifdef HAVE_MESSAGES 5455 _(
"MHD HTTPS option %d passed to MHD compiled without HTTPS support\n"),
5461 _(
"Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n"),
5472 #ifdef EPOLL_SUPPORT 5478 #ifndef HAVE_MESSAGES 5482 #ifdef USE_EPOLL_CREATE1 5483 fd = epoll_create1 (EPOLL_CLOEXEC);
5485 fd = epoll_create (MAX_EVENTS);
5489 #ifdef HAVE_MESSAGES 5491 _(
"Call to epoll_create1 failed: %s\n"),
5496 #if !defined(USE_EPOLL_CREATE1) 5499 #ifdef HAVE_MESSAGES 5501 _(
"Failed to set noninheritable mode on epoll FD.\n"));
5519 setup_epoll_to_listen (
struct MHD_Daemon *daemon)
5521 struct epoll_event event;
5524 daemon->epoll_fd = setup_epoll_fd (daemon);
5525 if (-1 == daemon->epoll_fd)
5527 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5530 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
5538 event.events = EPOLLIN;
5539 event.data.ptr = daemon;
5540 if (0 != epoll_ctl (daemon->epoll_fd,
5545 #ifdef HAVE_MESSAGES 5547 _(
"Call to epoll_ctl failed: %s\n"),
5552 daemon->listen_socket_in_epoll =
true;
5553 if (MHD_ITC_IS_VALID_(daemon->
itc))
5555 event.events = EPOLLIN;
5556 event.data.ptr = (
void *) epoll_itc_marker;
5557 if (0 != epoll_ctl (daemon->epoll_fd,
5559 MHD_itc_r_fd_ (daemon->
itc),
5562 #ifdef HAVE_MESSAGES 5564 _(
"Call to epoll_ctl failed: %s\n"),
5608 struct sockaddr_in servaddr4;
5610 struct sockaddr_in6 servaddr6;
5612 const struct sockaddr *servaddr =
NULL;
5614 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5631 #ifndef EPOLL_SUPPORT 5635 #ifndef HTTPS_SUPPORT 5639 #ifndef TCP_FASTOPEN 5645 #ifdef UPGRADE_SUPPORT 5676 #if defined(EPOLL_SUPPORT) 5678 #elif defined(HAVE_POLL) 5687 #if defined(EPOLL_SUPPORT) 5697 #ifdef EPOLL_SUPPORT 5698 daemon->epoll_fd = -1;
5699 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5700 daemon->epoll_upgrade_fd = -1;
5704 #ifdef HTTPS_SUPPORT 5705 daemon->priority_cache =
NULL;
5708 gnutls_priority_init (&daemon->priority_cache,
5718 daemon->
port = port;
5729 MHD_itc_set_invalid_ (daemon->
itc);
5735 #ifdef HAVE_MESSAGES 5737 daemon->custom_error_log_cls = stderr;
5742 #ifdef HAVE_MESSAGES 5744 _(
"Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with " 5745 "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD " 5746 "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"));
5754 #ifdef HAVE_LISTEN_SHUTDOWN 5759 #ifdef DAUTH_SUPPORT 5760 daemon->digest_auth_rand_size = 0;
5761 daemon->digest_auth_random =
NULL;
5762 daemon->nonce_nc_size = 4;
5764 #ifdef HTTPS_SUPPORT 5767 daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
5776 #ifdef HTTPS_SUPPORT 5778 (
NULL != daemon->priority_cache) )
5779 gnutls_priority_deinit (daemon->priority_cache);
5790 #ifdef HAVE_MESSAGES 5792 _(
"Using debug build of libmicrohttpd.\n") );
5797 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5802 if (! MHD_itc_init_ (daemon->
itc))
5804 #ifdef HAVE_MESSAGES 5806 _(
"Failed to create inter-thread communication channel: %s\n"),
5807 MHD_itc_last_strerror_ ());
5809 #ifdef HTTPS_SUPPORT 5810 if (
NULL != daemon->priority_cache)
5811 gnutls_priority_deinit (daemon->priority_cache);
5820 #ifdef HAVE_MESSAGES 5822 _(
"file descriptor for inter-thread communication channel exceeds maximum value\n"));
5825 #ifdef HTTPS_SUPPORT 5826 if (
NULL != daemon->priority_cache)
5827 gnutls_priority_deinit (daemon->priority_cache);
5834 #ifdef DAUTH_SUPPORT 5835 if (daemon->nonce_nc_size > 0)
5837 if ( ( (
size_t) (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc))) /
5838 sizeof(
struct MHD_NonceNc) != daemon->nonce_nc_size)
5840 #ifdef HAVE_MESSAGES 5842 _(
"Specified value for NC_SIZE too large\n"));
5844 #ifdef HTTPS_SUPPORT 5846 gnutls_priority_deinit (daemon->priority_cache);
5851 daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc));
5852 if (
NULL == daemon->nnc)
5854 #ifdef HAVE_MESSAGES 5856 _(
"Failed to allocate memory for nonce-nc map: %s\n"),
5859 #ifdef HTTPS_SUPPORT 5861 gnutls_priority_deinit (daemon->priority_cache);
5868 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5869 if (! MHD_mutex_init_ (&daemon->nnc_lock))
5871 #ifdef HAVE_MESSAGES 5873 _(
"MHD failed to initialize nonce-nc mutex\n"));
5875 #ifdef HTTPS_SUPPORT 5877 gnutls_priority_deinit (daemon->priority_cache);
5887 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5891 #ifdef HAVE_MESSAGES 5893 _(
"MHD thread pooling only works with MHD_USE_INTERNAL_POLLING_THREAD\n"));
5905 domain = (*pflags &
MHD_USE_IPv6) ? PF_INET6 : PF_INET;
5915 #ifdef HAVE_MESSAGES 5917 _(
"Failed to create socket for listening: %s\n"),
5926 #ifndef MHD_WINSOCK_SOCKETS 5931 if (0 > setsockopt (listen_fd,
5934 (
void*)&on,
sizeof (on)))
5936 #ifdef HAVE_MESSAGES 5938 _(
"setsockopt failed: %s\n"),
5947 #ifndef MHD_WINSOCK_SOCKETS 5950 if (0 > setsockopt (listen_fd,
5953 (
void*)&on,
sizeof (on)))
5955 #ifdef HAVE_MESSAGES 5957 _(
"setsockopt failed: %s\n"),
5967 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT) 5968 if (0 > setsockopt (listen_fd,
5970 #ifndef MHD_WINSOCK_SOCKETS
5978 #ifdef HAVE_MESSAGES 5980 _(
"setsockopt failed: %s\n"),
5988 #ifdef HAVE_MESSAGES 5990 _(
"Cannot allow listening address reuse: SO_REUSEPORT not defined\n"));
6003 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \ 6004 (defined(__sun) && defined(SO_EXCLBIND)) 6005 if (0 > setsockopt (listen_fd,
6007 #ifdef SO_EXCLUSIVEADDRUSE
6008 SO_EXCLUSIVEADDRUSE,
6015 #ifdef HAVE_MESSAGES 6017 _(
"setsockopt failed: %s\n"),
6022 #elif defined(MHD_WINSOCK_SOCKETS) 6023 #ifdef HAVE_MESSAGES 6025 _(
"Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n"));
6034 addrlen =
sizeof (
struct sockaddr_in6);
6037 addrlen =
sizeof (
struct sockaddr_in);
6038 if (
NULL == servaddr)
6043 #ifdef IN6ADDR_ANY_INIT 6044 static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
6048 sizeof (
struct sockaddr_in6));
6049 servaddr6.sin6_family = AF_INET6;
6050 servaddr6.sin6_port = htons (port);
6051 #ifdef IN6ADDR_ANY_INIT 6052 servaddr6.sin6_addr = static_in6any;
6054 #if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN 6055 servaddr6.sin6_len =
sizeof (
struct sockaddr_in6);
6057 servaddr = (
struct sockaddr *) &servaddr6;
6064 sizeof (
struct sockaddr_in));
6065 servaddr4.sin_family = AF_INET;
6066 servaddr4.sin_port = htons (port);
6067 if (0 != INADDR_ANY)
6068 servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
6069 #if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN 6070 servaddr4.sin_len =
sizeof (
struct sockaddr_in);
6072 servaddr = (
struct sockaddr *) &servaddr4;
6087 if (0 > setsockopt (listen_fd,
6088 IPPROTO_IPV6, IPV6_V6ONLY,
6089 (
const void *) &v6_only,
6092 #ifdef HAVE_MESSAGES 6094 _(
"setsockopt failed: %s\n"),
6101 if (-1 == bind (listen_fd, servaddr, addrlen))
6103 #ifdef HAVE_MESSAGES 6105 _(
"Failed to bind to port %u: %s\n"),
6106 (
unsigned int) port,
6115 if (0 == daemon->fastopen_queue_size)
6116 daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
6117 if (0 != setsockopt (listen_fd,
6120 (
const void*)&daemon->fastopen_queue_size,
6121 sizeof (daemon->fastopen_queue_size)))
6123 #ifdef HAVE_MESSAGES 6125 _(
"setsockopt failed: %s\n"),
6131 if (listen (listen_fd,
6134 #ifdef HAVE_MESSAGES 6136 _(
"Failed to listen for connections: %s\n"),
6148 #ifdef HAVE_GETSOCKNAME 6149 if ( (0 == daemon->
port) &&
6152 struct sockaddr_storage bindaddr;
6156 sizeof (
struct sockaddr_storage));
6157 addrlen =
sizeof (
struct sockaddr_storage);
6158 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 6159 bindaddr.ss_len = addrlen;
6161 if (0 != getsockname (listen_fd,
6162 (
struct sockaddr *) &bindaddr,
6165 #ifdef HAVE_MESSAGES 6167 _(
"Failed to get listen port number: %s\n"),
6171 #ifdef MHD_POSIX_SOCKETS 6172 else if (
sizeof (bindaddr) < addrlen)
6175 #ifdef HAVE_MESSAGES 6177 _(
"Failed to get listen port number (`struct sockaddr_storage` too small!?)\n"));
6181 else if (0 == addrlen)
6191 switch (bindaddr.ss_family)
6195 struct sockaddr_in *s4 = (
struct sockaddr_in *) &bindaddr;
6197 daemon->
port = ntohs (s4->sin_port);
6203 struct sockaddr_in6 *s6 = (
struct sockaddr_in6 *) &bindaddr;
6205 daemon->
port = ntohs(s6->sin6_port);
6216 #ifdef HAVE_MESSAGES 6218 _(
"Unknown address family!\n"));
6230 #ifdef HAVE_MESSAGES 6232 _(
"Failed to set nonblocking mode on listening socket: %s\n"),
6236 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6253 #ifdef HAVE_MESSAGES 6255 _(
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
6263 #ifdef EPOLL_SUPPORT 6265 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6272 #ifdef HAVE_MESSAGES 6274 _(
"Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
6278 if (
MHD_YES != setup_epoll_to_listen (daemon))
6283 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6286 #ifdef HAVE_MESSAGES 6288 _(
"MHD failed to initialize IP connection limit mutex\n"));
6299 #ifdef HAVE_MESSAGES 6301 _(
"MHD failed to initialize IP connection limit mutex\n"));
6303 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6313 #ifdef HTTPS_SUPPORT 6316 (0 != MHD_TLS_init (daemon)) )
6318 #ifdef HAVE_MESSAGES 6320 _(
"Failed to initialize TLS support\n"));
6324 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6332 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6340 "MHD-listen" :
"MHD-single",
6341 daemon->thread_stack_size,
6345 #ifdef HAVE_MESSAGES 6347 _(
"Failed to create listen thread: %s\n"),
6381 memcpy (d, daemon,
sizeof (
struct MHD_Daemon));
6391 if (! MHD_itc_init_ (d->
itc))
6393 #ifdef HAVE_MESSAGES 6395 _(
"Failed to create worker inter-thread communication channel: %s\n"),
6396 MHD_itc_last_strerror_() );
6404 #ifdef HAVE_MESSAGES 6406 _(
"File descriptor for worker inter-thread communication channel exceeds maximum value\n"));
6413 MHD_itc_set_invalid_ (d->
itc);
6419 if (i < leftover_conns)
6421 #ifdef EPOLL_SUPPORT 6423 (
MHD_YES != setup_epoll_to_listen (d)) )
6429 #ifdef HAVE_MESSAGES 6431 _(
"MHD failed to initialize cleanup connection mutex\n"));
6439 daemon->thread_stack_size,
6443 #ifdef HAVE_MESSAGES 6445 _(
"Failed to create pool thread: %s\n"),
6457 #ifdef HTTPS_SUPPORT 6460 daemon->https_key_password =
NULL;
6465 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6493 #ifdef EPOLL_SUPPORT 6494 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6495 if (daemon->upgrade_fd_in_epoll)
6497 if (0 != epoll_ctl (daemon->epoll_fd,
6499 daemon->epoll_upgrade_fd,
6501 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
6502 daemon->upgrade_fd_in_epoll =
false;
6505 if (-1 != daemon->epoll_fd)
6506 close (daemon->epoll_fd);
6507 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6508 if (-1 != daemon->epoll_upgrade_fd)
6509 close (daemon->epoll_upgrade_fd);
6512 #ifdef DAUTH_SUPPORT 6514 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6518 #ifdef HTTPS_SUPPORT 6521 gnutls_priority_deinit (daemon->priority_cache);
6522 if (daemon->x509_cred)
6523 gnutls_certificate_free_credentials (daemon->x509_cred);
6524 if (daemon->psk_cred)
6525 gnutls_psk_free_server_credentials (daemon->psk_cred);
6528 if (MHD_ITC_IS_VALID_(daemon->
itc))
6548 #ifdef UPGRADE_SUPPORT 6551 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6552 struct MHD_UpgradeResponseHandle *urh;
6553 struct MHD_UpgradeResponseHandle *urhn;
6556 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6562 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
6569 urh->clean_ready =
true;
6586 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6589 #ifdef UPGRADE_SUPPORT 6595 while (
NULL != susp)
6597 if (
NULL == susp->urh)
6598 MHD_PANIC (
_(
"MHD_stop_daemon() called while we have suspended connections.\n"));
6599 #ifdef HTTPS_SUPPORT 6600 else if (used_tls &&
6602 (! susp->urh->clean_ready) )
6603 shutdown (susp->urh->app.socket,
6608 #ifdef HAVE_MESSAGES 6609 if (! susp->urh->was_closed)
6611 _(
"Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
6613 susp->urh->was_closed =
true;
6629 MHD_PANIC (
_(
"MHD_stop_daemon() called while we have suspended connections.\n"));
6634 #if MHD_WINSOCK_SOCKETS 6637 (! MHD_itc_activate_ (
daemon->
itc,
"e")) )
6638 MHD_PANIC (
_(
"Failed to signal shutdown via inter-thread communication channel"));
6642 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6652 if (! MHD_join_thread_ (pos->
pid.handle))
6667 #ifdef UPGRADE_SUPPORT 6682 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6703 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6716 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6730 MHD_PANIC (
_(
"Failed to signal shutdown via inter-thread communication channel."));
6735 #ifdef HAVE_LISTEN_SHUTDOWN 6738 (void) shutdown (
fd,
6748 #ifdef EPOLL_SUPPORT 6750 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6758 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6767 MHD_PANIC (
_(
"Failed to signal shutdown via inter-thread communication channel"));
6771 #ifdef HAVE_LISTEN_SHUTDOWN 6775 (void) shutdown (
fd,
6783 if (! MHD_join_thread_ (
daemon->
pid.handle))
6798 #ifdef EPOLL_SUPPORT 6800 (-1 !=
daemon->epoll_fd) )
6802 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6804 (-1 !=
daemon->epoll_upgrade_fd) )
6809 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6822 #ifdef HTTPS_SUPPORT 6823 if (
daemon->have_dhparams)
6825 gnutls_dh_params_deinit (
daemon->https_mem_dhparams);
6826 daemon->have_dhparams =
false;
6830 gnutls_priority_deinit (
daemon->priority_cache);
6832 gnutls_certificate_free_credentials (
daemon->x509_cred);
6834 gnutls_psk_free_server_credentials (
daemon->psk_cred);
6838 #ifdef DAUTH_SUPPORT 6840 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6844 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6878 #ifdef EPOLL_SUPPORT 6889 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6947 #ifdef PACKAGE_VERSION 6948 return PACKAGE_VERSION;
6950 static char ver[12] =
"\0\0\0\0\0\0\0\0\0\0\0";
6953 int res = MHD_snprintf_(ver,
6959 if (0 >= res ||
sizeof(ver) <= res)
6984 #ifdef HAVE_MESSAGES 6990 #ifdef HTTPS_SUPPORT 6996 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3 7002 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030603 7014 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) 7026 #ifdef EPOLL_SUPPORT 7032 #ifdef HAVE_LISTEN_SHUTDOWN 7038 #ifdef _MHD_ITC_SOCKETPAIR 7050 #ifdef BAUTH_SUPPORT 7056 #ifdef DAUTH_SUPPORT 7062 #ifdef HAVE_POSTPROCESSOR 7068 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111 7074 #if defined(HAVE_PREAD64) || defined(_WIN32) 7076 #elif defined(HAVE_PREAD) 7077 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
7078 #elif defined(HAVE_LSEEK64) 7081 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
7084 #if defined(MHD_USE_THREAD_NAME_) 7090 #if defined(UPGRADE_SUPPORT) 7096 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32) 7102 #ifdef MHD_USE_GETSOCKNAME 7108 #if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || defined (MSG_NOSIGNAL) 7114 #ifdef _MHD_HAVE_SENDFILE 7120 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 7131 #ifdef MHD_HTTPS_REQUIRE_GRYPT 7132 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600 7133 #if defined(MHD_USE_POSIX_THREADS) 7134 GCRY_THREAD_OPTION_PTHREAD_IMPL;
7135 #elif defined(MHD_W32_MUTEX_) 7138 gcry_w32_mutex_init (
void **ppmtx)
7140 *ppmtx = malloc (
sizeof (MHD_mutex_));
7144 if (!MHD_mutex_init_ ((MHD_mutex_*)*ppmtx))
7156 gcry_w32_mutex_destroy (
void **ppmtx)
7158 int res = (MHD_mutex_destroy_ ((MHD_mutex_*)*ppmtx)) ? 0 : EINVAL;
7165 gcry_w32_mutex_lock (
void **ppmtx)
7167 return MHD_mutex_lock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
7172 gcry_w32_mutex_unlock (
void **ppmtx)
7174 return MHD_mutex_unlock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
7178 static struct gcry_thread_cbs gcry_threads_w32 = {
7179 (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
7180 NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
7181 gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
7194 #if defined(MHD_WINSOCK_SOCKETS) 7201 #if defined(MHD_WINSOCK_SOCKETS) 7202 if (0 != WSAStartup(MAKEWORD(2, 2), &wsd))
7203 MHD_PANIC (
_(
"Failed to initialize winsock\n"));
7204 mhd_winsock_inited_ = 1;
7205 if (2 != LOBYTE(wsd.wVersion) && 2 != HIBYTE(wsd.wVersion))
7206 MHD_PANIC (
_(
"Winsock version 2.2 is not available\n"));
7208 #ifdef HTTPS_SUPPORT 7209 #ifdef MHD_HTTPS_REQUIRE_GRYPT 7210 #if GCRYPT_VERSION_NUMBER < 0x010600 7211 #if defined(MHD_USE_POSIX_THREADS) 7212 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7213 &gcry_threads_pthread))
7214 MHD_PANIC (
_(
"Failed to initialise multithreading in libgcrypt\n"));
7215 #elif defined(MHD_W32_MUTEX_) 7216 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7218 MHD_PANIC (
_(
"Failed to initialise multithreading in libgcrypt\n"));
7220 gcry_check_version (
NULL);
7222 if (
NULL == gcry_check_version (
"1.6.0"))
7223 MHD_PANIC (
_(
"libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n"));
7226 gnutls_global_init ();
7229 #ifdef HAVE_FREEBSD_SENDFILE 7230 MHD_conn_init_static_ ();
7239 #ifdef HTTPS_SUPPORT 7240 gnutls_global_deinit ();
7242 #if defined(MHD_WINSOCK_SOCKETS) 7243 if (mhd_winsock_inited_)
7249 #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)
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