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 (
NULL != daemon->https_mem_trust)
552 paramlen = strlen (daemon->https_mem_trust);
557 "Too long trust certificate\n");
561 cert.data = (
unsigned char *) daemon->https_mem_trust;
562 cert.size = (
unsigned int) paramlen;
563 if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred,
565 GNUTLS_X509_FMT_PEM) < 0)
569 "Bad trust certificate format\n");
575 if (daemon->have_dhparams)
577 gnutls_certificate_set_dh_params (daemon->x509_cred,
578 daemon->https_mem_dhparams);
581 if ( (
NULL != daemon->https_mem_cert) &&
582 (
NULL != daemon->https_mem_key) )
587 param1len = strlen (daemon->https_mem_key);
588 param2len = strlen (daemon->https_mem_cert);
594 "Too long key or certificate\n");
598 key.data = (
unsigned char *) daemon->https_mem_key;
599 key.size = (
unsigned int)param1len;
600 cert.data = (
unsigned char *) daemon->https_mem_cert;
601 cert.size = (
unsigned int)param2len;
603 if (
NULL != daemon->https_key_password) {
604 #if GNUTLS_VERSION_NUMBER >= 0x030111 605 ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
609 daemon->https_key_password,
614 _(
"Failed to setup x509 certificate/key: pre 3.X.X version " \
615 "of GnuTLS does not support setting key password"));
621 ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
624 GNUTLS_X509_FMT_PEM);
628 "GnuTLS failed to setup x509 certificate/key: %s\n",
629 gnutls_strerror (ret));
633 #if GNUTLS_VERSION_MAJOR >= 3 634 if (
NULL != daemon->cert_callback)
639 "You need to specify a certificate and key location\n");
653 switch (daemon->cred_type)
655 case GNUTLS_CRD_CERTIFICATE:
657 gnutls_certificate_allocate_credentials (&daemon->x509_cred))
658 return GNUTLS_E_MEMORY_ERROR;
659 return MHD_init_daemon_certificate (daemon);
662 gnutls_psk_allocate_server_credentials (&daemon->psk_cred))
663 return GNUTLS_E_MEMORY_ERROR;
668 _(
"Error: invalid credentials type %d specified.\n"),
711 fd_set *write_fd_set,
712 fd_set *except_fd_set,
724 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 738 urh_to_fdset (
struct MHD_UpgradeResponseHandle *urh,
743 unsigned int fd_setsize)
745 const MHD_socket conn_sckt = urh->connection->socket_fd;
753 if ( (urh->in_buffer_used < urh->in_buffer_size) &&
759 if ( (0 != urh->out_buffer_used) &&
768 ((0 != urh->in_buffer_size) ||
769 (0 != urh->out_buffer_size) ||
770 (0 != urh->out_buffer_used)))
778 if ( (urh->out_buffer_used < urh->out_buffer_size) &&
784 if ( (0 != urh->in_buffer_used) &&
793 ((0 != urh->out_buffer_size) ||
794 (0 != urh->in_buffer_size) ||
795 (0 != urh->in_buffer_used)))
816 urh_from_fdset (
struct MHD_UpgradeResponseHandle *urh,
821 const MHD_socket conn_sckt = urh->connection->socket_fd;
830 if (FD_ISSET (conn_sckt, rs))
832 if (FD_ISSET (conn_sckt, ws))
834 if (FD_ISSET (conn_sckt, es))
839 if (FD_ISSET (mhd_sckt, rs))
841 if (FD_ISSET (mhd_sckt, ws))
843 if (FD_ISSET (mhd_sckt, es))
859 urh_update_pollfd (
struct MHD_UpgradeResponseHandle *urh,
865 if (urh->in_buffer_used < urh->in_buffer_size)
866 p[0].events |= POLLIN;
867 if (0 != urh->out_buffer_used)
868 p[0].events |= POLLOUT;
873 ((0 != urh->in_buffer_size) ||
874 (0 != urh->out_buffer_size) ||
875 (0 != urh->out_buffer_used)))
876 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
878 if (urh->out_buffer_used < urh->out_buffer_size)
879 p[1].events |= POLLIN;
880 if (0 != urh->in_buffer_used)
881 p[1].events |= POLLOUT;
886 ((0 != urh->out_buffer_size) ||
887 (0 != urh->in_buffer_size) ||
888 (0 != urh->in_buffer_used)))
889 p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
900 urh_to_pollfd (
struct MHD_UpgradeResponseHandle *urh,
903 p[0].fd = urh->connection->socket_fd;
904 p[1].fd = urh->mhd.socket;
905 urh_update_pollfd (urh,
916 urh_from_pollfd (
struct MHD_UpgradeResponseHandle *urh,
923 if (0 != (p[0].revents & POLLIN))
925 if (0 != (p[0].revents & POLLOUT))
927 if (0 != (p[0].revents & POLLHUP))
929 if (0 != (p[0].revents & MHD_POLL_REVENTS_ERRROR))
931 if (0 != (p[1].revents & POLLIN))
933 if (0 != (p[1].revents & POLLOUT))
935 if (0 != (p[1].revents & POLLHUP))
937 if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
961 fd_set *write_fd_set,
962 fd_set *except_fd_set,
964 unsigned int fd_setsize)
1000 #ifdef MHD_POSIX_SOCKETS 1013 #ifdef MHD_POSIX_SOCKETS 1021 if ( (
NULL == except_fd_set) ||
1033 #ifdef MHD_WINSOCK_SOCKETS 1046 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 1048 struct MHD_UpgradeResponseHandle *urh;
1050 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
1064 #ifdef HAVE_MESSAGES 1067 _(
"Maximum socket in select set: %d\n"),
1109 fd_set *read_fd_set,
1110 fd_set *write_fd_set,
1111 fd_set *except_fd_set,
1113 unsigned int fd_setsize)
1117 if ( (
NULL == daemon) ||
1118 (
NULL == read_fd_set) ||
1119 (
NULL == write_fd_set) ||
1124 if (
NULL == except_fd_set)
1126 #ifdef HAVE_MESSAGES 1128 _(
"MHD_get_fdset2() called with except_fd_set " 1129 "set to NULL. Such behavior is unsupported.\n"));
1132 except_fd_set = &es;
1135 #ifdef EPOLL_SUPPORT 1180 bool states_info_processed =
false;
1184 #ifdef HTTPS_SUPPORT 1195 states_info_processed =
true;
1204 states_info_processed =
true;
1214 if (!states_info_processed)
1261 #ifdef HTTPS_SUPPORT 1271 #ifdef UPGRADE_SUPPORT 1282 struct MHD_UpgradeResponseHandle *urh = connection->urh;
1286 #ifdef HTTPS_SUPPORT 1290 gnutls_bye (connection->tls_session,
1299 connection->urh =
NULL;
1305 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 1315 process_urh (
struct MHD_UpgradeResponseHandle *urh)
1330 #ifdef HAVE_MESSAGES 1331 if (! urh->was_closed)
1334 _(
"Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
1337 urh->was_closed =
true;
1339 was_closed = urh->was_closed;
1344 if (0 < urh->in_buffer_used)
1346 #ifdef HAVE_MESSAGES 1349 " bytes of data received from remote side: application shut down socket\n"),
1359 if (0 != urh->out_buffer_size)
1362 urh->in_buffer_used = 0;
1366 urh->in_buffer_size = 0;
1389 (urh->in_buffer_used < urh->in_buffer_size) )
1394 buf_size = urh->in_buffer_size - urh->in_buffer_used;
1399 res = gnutls_record_recv (connection->tls_session,
1400 &urh->in_buffer[urh->in_buffer_used],
1404 if (GNUTLS_E_INTERRUPTED != res)
1407 if (GNUTLS_E_AGAIN != res)
1412 urh->in_buffer_size = 0;
1418 urh->in_buffer_used += res;
1419 if (buf_size > (
size_t)res)
1421 else if (0 < gnutls_record_check_pending (connection->tls_session))
1430 urh->in_buffer_size = 0;
1438 (urh->out_buffer_used < urh->out_buffer_size) )
1443 buf_size = urh->out_buffer_size - urh->out_buffer_used;
1448 &urh->out_buffer[urh->out_buffer_used],
1467 urh->out_buffer_size = 0;
1473 urh->out_buffer_used += res;
1474 if (buf_size > (
size_t)res)
1484 urh->out_buffer_size = 0;
1492 (urh->out_buffer_used > 0) )
1497 data_size = urh->out_buffer_used;
1501 res = gnutls_record_send (connection->tls_session,
1506 if (GNUTLS_E_INTERRUPTED != res)
1509 if (GNUTLS_E_AGAIN != res)
1513 #ifdef HAVE_MESSAGES 1516 " bytes of data received from application: %s\n"),
1518 gnutls_strerror(res));
1521 urh->out_buffer_used = 0;
1523 urh->out_buffer_size = 0;
1530 const size_t next_out_buffer_used = urh->out_buffer_used - res;
1531 if (0 != next_out_buffer_used)
1533 memmove (urh->out_buffer,
1534 &urh->out_buffer[res],
1535 next_out_buffer_used);
1536 if (data_size > (
size_t)res)
1539 urh->out_buffer_used = next_out_buffer_used;
1541 if ( (0 == urh->out_buffer_used) &&
1549 urh->out_buffer_size = 0;
1558 (urh->in_buffer_used > 0) )
1563 data_size = urh->in_buffer_used;
1581 #ifdef HAVE_MESSAGES 1584 " bytes of data received from remote side: %s\n"),
1589 urh->in_buffer_used = 0;
1591 urh->in_buffer_size = 0;
1599 const size_t next_in_buffer_used = urh->in_buffer_used - res;
1600 if (0 != next_in_buffer_used)
1602 memmove (urh->in_buffer,
1603 &urh->in_buffer[res],
1604 next_in_buffer_used);
1605 if (data_size > (
size_t)res)
1608 urh->in_buffer_used = next_in_buffer_used;
1610 if ( (0 == urh->in_buffer_used) &&
1616 urh->in_buffer_size = 0;
1625 (urh->in_buffer_used < urh->in_buffer_size) &&
1630 ( (0 != urh->out_buffer_size) ||
1631 (0 != urh->out_buffer_used) ) )
1634 #ifdef HAVE_MESSAGES 1635 if (0 < urh->out_buffer_used)
1638 " bytes of data received from application: daemon shut down\n"),
1642 urh->out_buffer_used = 0;
1646 urh->out_buffer_size = 0;
1652 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 1653 #ifdef UPGRADE_SUPPORT 1665 #ifdef HTTPS_SUPPORT 1666 struct MHD_UpgradeResponseHandle *urh = con->urh;
1675 while ( (0 != urh->in_buffer_size) ||
1676 (0 != urh->out_buffer_size) ||
1677 (0 != urh->in_buffer_used) ||
1678 (0 != urh->out_buffer_used) )
1692 result = urh_to_fdset (urh,
1700 #ifdef HAVE_MESSAGES 1702 _(
"Error preparing select\n"));
1709 struct timeval* tvp;
1712 (urh->in_buffer_used < urh->in_buffer_size))
1734 #ifdef HAVE_MESSAGES 1736 _(
"Error during select (%d): `%s'\n"),
1742 urh_from_fdset (urh,
1757 p[0].fd = urh->connection->socket_fd;
1758 p[1].fd = urh->mhd.socket;
1760 while ( (0 != urh->in_buffer_size) ||
1761 (0 != urh->out_buffer_size) ||
1762 (0 != urh->in_buffer_used) ||
1763 (0 != urh->out_buffer_used) )
1767 urh_update_pollfd(urh, p);
1770 (urh->in_buffer_used < urh->in_buffer_size))
1775 if (MHD_sys_poll_ (p,
1783 #ifdef HAVE_MESSAGES 1785 _(
"Error during poll: `%s'\n"),
1790 urh_from_pollfd (urh,
1814 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
1825 struct timeval *tvp;
1831 #define EXTRA_SLOTS 1 1833 #define EXTRA_SLOTS 0 1842 const bool use_poll = 0;
1844 bool was_suspended =
false;
1845 MHD_thread_init_(&(con->
pid));
1851 #ifdef UPGRADE_SUPPORT 1852 struct MHD_UpgradeResponseHandle *
const urh = con->urh;
1854 static const void *
const urh =
NULL;
1861 was_suspended =
true;
1870 #ifdef HAVE_MESSAGES 1872 _(
"Failed to add FD to fd_set\n"));
1886 #ifdef HAVE_MESSAGES 1888 _(
"Error during select (%d): `%s'\n"),
1898 p[0].events = POLLIN;
1899 p[0].fd = MHD_itc_r_fd_ (daemon->
itc);
1901 if (0 > MHD_sys_poll_ (p,
1907 #ifdef HAVE_MESSAGES 1909 _(
"Error during poll: `%s'\n"),
1916 MHD_itc_clear_ (daemon->
itc);
1925 was_suspended =
false;
1931 #ifdef HTTPS_SUPPORT
1943 if ( (
NULL == tvp) &&
1951 const time_t seconds_left = timeout - (now - con->
last_activity);
1952 #if !defined(_WIN32) || defined(__CYGWIN__) 1953 tv.tv_sec = seconds_left;
1967 bool err_state =
false;
2001 if (MHD_ITC_IS_VALID_(daemon->
itc) )
2012 #ifdef HAVE_MESSAGES 2014 _(
"Failed to add FD to fd_set\n"));
2030 #ifdef HAVE_MESSAGES 2032 _(
"Error during select (%d): `%s'\n"),
2041 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2042 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
2044 MHD_itc_clear_ (daemon->
itc);
2067 p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
2070 p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
2073 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
2081 if (MHD_ITC_IS_VALID_(daemon->
itc))
2083 p[1].events |= POLLIN;
2084 p[1].fd = MHD_itc_r_fd_ (daemon->
itc);
2089 if (MHD_sys_poll_ (p,
2095 (
NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
2099 #ifdef HAVE_MESSAGES 2101 _(
"Error during poll: `%s'\n"),
2109 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2110 (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
2111 MHD_itc_clear_ (daemon->
itc);
2115 0 != (p[0].revents & POLLIN),
2116 0 != (p[0].revents & POLLOUT),
2117 0 != (p[0].revents & (POLLERR | MHD_POLL_REVENTS_ERR_DISC))))
2121 #ifdef UPGRADE_SUPPORT 2122 if (MHD_CONNECTION_UPGRADE == con->
state)
2134 thread_main_connection_upgrade (con);
2138 con->urh->clean_ready =
true;
2146 return (MHD_THRD_RTRN_TYPE_) 0;
2151 #ifdef HAVE_MESSAGES 2153 _(
"Processing thread terminating. Closing connection\n"));
2177 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2178 (! MHD_itc_activate_ (daemon->
itc,
"t")) )
2180 #ifdef HAVE_MESSAGES 2182 _(
"Failed to signal thread termination via inter-thread communication channel."));
2185 return (MHD_THRD_RTRN_TYPE_) 0;
2200 #if defined(HTTPS_SUPPORT) 2201 #if !defined(MHD_WINSOCK_SOCKETS) && !defined(MHD_socket_nosignal_) && \ 2202 (GNUTLS_VERSION_NUMBER+0 < 0x030402) && defined(MSG_NOSIGNAL) 2208 #define MHD_TLSLIB_NEED_PUSH_FUNC 1 2211 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC 2217 MHD_tls_push_func_(gnutls_transport_ptr_t trnsp,
2221 #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) 2239 psk_gnutls_adapter (gnutls_session_t session,
2240 const char *username,
2241 gnutls_datum_t *key)
2246 size_t app_psk_size;
2248 connection = gnutls_session_get_ptr (session);
2249 if (
NULL == connection)
2251 #ifdef HAVE_MESSAGES 2253 MHD_PANIC (
_(
"Internal server error. This should be impossible.\n"));
2257 daemon = connection->
daemon;
2258 #if GNUTLS_VERSION_MAJOR >= 3 2259 if (
NULL == daemon->cred_callback)
2261 #ifdef HAVE_MESSAGES 2263 _(
"PSK not supported by this server.\n"));
2267 if (0 != daemon->cred_callback (daemon->cred_callback_cls,
2273 if (
NULL == (key->data = gnutls_malloc (app_psk_size)))
2275 #ifdef HAVE_MESSAGES 2277 _(
"PSK authentication failed: gnutls_malloc failed to allocate memory\n"));
2284 #ifdef HAVE_MESSAGES 2286 _(
"PSK authentication failed: PSK too long\n"));
2291 key->size = (
unsigned int)app_psk_size;
2298 #ifdef HAVE_MESSAGES 2300 _(
"PSK not supported by this server.\n"));
2336 const struct sockaddr *addr,
2342 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2348 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2380 #ifdef HAVE_MESSAGES 2382 _(
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
2383 (
int) client_socket,
2393 #ifdef MHD_socket_nosignal_ 2394 if (! MHD_socket_nosignal_ (client_socket))
2396 #ifdef HAVE_MESSAGES 2398 _(
"Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
2401 #ifndef MSG_NOSIGNAL 2412 #ifdef HAVE_MESSAGES 2415 _(
"Accepted connection on socket %d\n"),
2425 #ifdef HAVE_MESSAGES 2427 _(
"Server reached connection limit. Closing inbound connection.\n"));
2443 #ifdef HAVE_MESSAGES 2445 _(
"Connection rejected by application. Closing connection.\n"));
2461 #ifdef HAVE_MESSAGES 2463 "Error allocating memory: %s\n",
2476 #ifdef HAVE_MESSAGES 2478 _(
"Error allocating memory: %s\n"),
2493 if (
NULL == (connection->
addr = malloc (addrlen)))
2496 #ifdef HAVE_MESSAGES 2498 _(
"Error allocating memory: %s\n"),
2510 memcpy (connection->
addr,
2516 connection->
daemon = daemon;
2526 #ifdef HTTPS_SUPPORT 2527 gnutls_init_flags_t flags;
2529 flags = GNUTLS_SERVER;
2530 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030402) 2531 flags |= GNUTLS_NO_SIGNAL;
2533 #if GNUTLS_VERSION_MAJOR >= 3 2534 flags |= GNUTLS_NONBLOCK;
2536 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030603) 2538 flags |= GNUTLS_POST_HANDSHAKE_AUTH;
2540 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030605) 2542 flags |= GNUTLS_ENABLE_EARLY_DATA;
2546 gnutls_init (&connection->tls_session,
2548 gnutls_priority_set (connection->tls_session,
2549 daemon->priority_cache);
2550 gnutls_session_set_ptr (connection->tls_session,
2552 switch (daemon->cred_type)
2555 case GNUTLS_CRD_CERTIFICATE:
2556 gnutls_credentials_set (connection->tls_session,
2557 GNUTLS_CRD_CERTIFICATE,
2560 case GNUTLS_CRD_PSK:
2561 gnutls_credentials_set (connection->tls_session,
2564 gnutls_psk_set_server_credentials_function (daemon->psk_cred,
2565 &psk_gnutls_adapter);
2568 #ifdef HAVE_MESSAGES 2569 MHD_DLOG (connection->
daemon,
2570 _(
"Failed to setup TLS credentials: unknown credential type %d\n"),
2577 free (connection->
addr);
2585 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030109) && !defined(_WIN64) 2586 gnutls_transport_set_int (connection->tls_session,
2587 (
int)(client_socket));
2589 gnutls_transport_set_ptr (connection->tls_session,
2590 (gnutls_transport_ptr_t)(intptr_t)(client_socket));
2592 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC 2593 gnutls_transport_set_push_function (connection->tls_session,
2594 MHD_tls_push_func_);
2596 if (daemon->https_mem_trust)
2597 gnutls_certificate_server_set_request (connection->tls_session,
2598 GNUTLS_CERT_REQUEST);
2605 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2611 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2615 #ifdef HAVE_MESSAGES 2617 _(
"Server reached connection limit. Closing inbound connection.\n"));
2634 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2642 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2648 daemon->thread_stack_size,
2653 #ifdef HAVE_MESSAGES 2655 "Failed to create a thread: %s\n",
2662 connection->
pid = daemon->
pid;
2664 #ifdef EPOLL_SUPPORT 2669 struct epoll_event event;
2671 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2672 event.data.ptr = connection;
2673 if (0 != epoll_ctl (daemon->epoll_fd,
2679 #ifdef HAVE_MESSAGES 2681 _(
"Call to epoll_ctl failed: %s\n"),
2693 daemon->eready_tail,
2701 (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2702 (! MHD_itc_activate_ (daemon->
itc,
"n")) )
2704 #ifdef HAVE_MESSAGES 2706 _(
"Failed to signal new connection via inter-thread communication channel."));
2716 #ifdef HTTPS_SUPPORT 2717 if (
NULL != connection->tls_session)
2718 gnutls_deinit (connection->tls_session);
2724 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2736 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2740 free (connection->
addr);
2764 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2771 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2795 #ifdef EPOLL_SUPPORT 2801 daemon->eready_tail,
2807 if (0 != epoll_ctl (daemon->epoll_fd,
2811 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
2817 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2860 MHD_PANIC (
_(
"Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2861 #ifdef UPGRADE_SUPPORT 2862 if (
NULL != connection->urh)
2864 #ifdef HAVE_MESSAGES 2866 _(
"Error: connection scheduled for \"upgrade\" cannot be suspended"));
2889 MHD_PANIC (
_(
"Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2890 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2895 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2898 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2899 (! MHD_itc_activate_ (daemon->
itc,
"r")) )
2901 #ifdef HAVE_MESSAGES 2903 _(
"Failed to signal resume via inter-thread communication channel."));
2925 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2929 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2943 #ifdef UPGRADE_SUPPORT 2944 struct MHD_UpgradeResponseHandle *
const urh = pos->urh;
2946 static const void *
const urh =
NULL;
2950 #ifdef UPGRADE_SUPPORT
2951 || ( (
NULL != urh) &&
2952 ( (! urh->was_closed) ||
2953 (! urh->clean_ready) ) )
2983 #ifdef EPOLL_SUPPORT 2987 MHD_PANIC (
"Resumed connection was already in EREADY set\n");
2991 daemon->eready_tail,
2999 #ifdef UPGRADE_SUPPORT 3024 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3027 if ( (used_thr_p_c) &&
3030 if (! MHD_itc_activate_(daemon->
itc,
3033 #ifdef HAVE_MESSAGES 3035 _(
"Failed to signal resume of connection via inter-thread communication channel."));
3073 const struct sockaddr *addr,
3079 #ifdef HAVE_MESSAGES 3081 _(
"Failed to set nonblocking mode on new client socket: %s\n"),
3092 #ifdef HAVE_MESSAGES 3094 _(
"Failed to set noninheritable mode on new client socket.\n"));
3101 #ifdef HAVE_MESSAGES 3103 _(
"Failed to reset buffering mode on new client socket.\n"));
3133 struct sockaddr_in6 addrstorage;
3135 struct sockaddr_in addrstorage;
3137 struct sockaddr *addr = (
struct sockaddr *) &addrstorage;
3143 addrlen =
sizeof (addrstorage);
3146 sizeof (addrstorage));
3173 #ifdef HAVE_MESSAGES 3176 _(
"Error accepting connection: %s\n"),
3188 #ifdef HAVE_MESSAGES 3193 _(
"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"));
3198 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3202 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3205 #ifdef HAVE_MESSAGES 3207 _(
"Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
3214 #if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK) 3217 #ifdef HAVE_MESSAGES 3219 _(
"Failed to set nonblocking mode on incoming connection socket: %s\n"),
3226 #if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC) 3229 #ifdef HAVE_MESSAGES 3231 _(
"Failed to set noninheritable mode on incoming connection socket.\n"));
3235 #ifdef HAVE_MESSAGES 3238 _(
"Accepted connection on socket %d\n"),
3266 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3274 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3278 (! MHD_join_thread_ (pos->
pid.handle)) )
3281 #ifdef UPGRADE_SUPPORT 3282 cleanup_upgraded_connection (pos);
3285 #ifdef HTTPS_SUPPORT 3286 if (
NULL != pos->tls_session)
3287 gnutls_deinit (pos->tls_session);
3299 #ifdef EPOLL_SUPPORT 3309 if ( (-1 !=
daemon->epoll_fd) &&
3318 if (0 != epoll_ctl (
daemon->epoll_fd,
3322 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
3338 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3344 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3374 time_t earliest_deadline;
3381 #ifdef HAVE_MESSAGES 3383 _(
"Illegal call to MHD_get_timeout\n"));
3395 #ifdef EPOLL_SUPPORT 3398 #
if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
3409 have_timeout =
false;
3410 earliest_deadline = 0;
3415 if ( (! have_timeout) ||
3418 have_timeout =
true;
3423 if ( (
NULL != pos) &&
3426 if ( (! have_timeout) ||
3429 have_timeout =
true;
3435 if (earliest_deadline < now)
3439 const time_t second_left = earliest_deadline - now;
3441 if (((
unsigned long long)second_left) >
ULLONG_MAX / 1000)
3444 *timeout = 1000LLU * (
unsigned long long) second_left;
3462 const fd_set *read_fd_set,
3463 const fd_set *write_fd_set,
3464 const fd_set *except_fd_set)
3469 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3470 struct MHD_UpgradeResponseHandle *urh;
3471 struct MHD_UpgradeResponseHandle *urhn;
3480 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
3481 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
3483 MHD_itc_clear_ (daemon->
itc);
3496 while (
NULL != (pos = prev))
3512 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3514 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
3518 urh_from_fdset (urh,
3525 if ( (0 == urh->in_buffer_size) &&
3526 (0 == urh->out_buffer_size) &&
3527 (0 == urh->in_buffer_used) &&
3528 (0 == urh->out_buffer_used) )
3531 urh->clean_ready =
true;
3566 const fd_set *read_fd_set,
3567 const fd_set *write_fd_set,
3568 const fd_set *except_fd_set)
3574 if (
NULL == read_fd_set ||
NULL == write_fd_set)
3576 if (
NULL == except_fd_set)
3578 #ifdef HAVE_MESSAGES 3580 _(
"MHD_run_from_select() called with except_fd_set " 3581 "set to NULL. Such behavior is deprecated.\n"));
3584 except_fd_set = &es;
3588 #ifdef EPOLL_SUPPORT 3589 int ret = MHD_epoll (daemon,
3627 struct timeval timeout;
3634 timeout.tv_usec = 0;
3658 #ifdef HAVE_MESSAGES 3660 _(
"Could not obtain daemon fdsets"));
3675 #ifdef HAVE_MESSAGES 3677 _(
"Could not add listen socket to fdset"));
3682 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
3688 #if defined(MHD_WINSOCK_SOCKETS) 3703 #ifdef HAVE_MESSAGES 3705 _(
"Could not add control inter-thread communication channel FD to fdset"));
3708 #if defined(MHD_WINSOCK_SOCKETS) 3720 (MHD_ITC_IS_VALID_(daemon->
itc)) &&
3732 timeout.tv_usec = 0;
3740 timeout.tv_usec = (ltimeout % 1000) * 1000;
3759 #ifdef HAVE_MESSAGES 3761 _(
"select failed: %s\n"),
3788 unsigned int num_connections;
3791 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3792 struct MHD_UpgradeResponseHandle *urh;
3793 struct MHD_UpgradeResponseHandle *urhn;
3801 num_connections = 0;
3804 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3805 for (urh = daemon->urh_head;
NULL != urh; urh = urh->next)
3806 num_connections += 2;
3812 unsigned int poll_server;
3819 sizeof (
struct pollfd));
3822 #ifdef HAVE_MESSAGES 3824 _(
"Error allocating memory: %s\n"),
3837 p[poll_server].fd = ls;
3838 p[poll_server].events = POLLIN;
3839 p[poll_server].revents = 0;
3840 poll_listen = (int) poll_server;
3844 if (MHD_ITC_IS_VALID_(daemon->
itc))
3846 p[poll_server].fd = MHD_itc_r_fd_ (daemon->
itc);
3847 p[poll_server].events = POLLIN;
3848 p[poll_server].revents = 0;
3849 poll_itc_idx = (int) poll_server;
3859 timeout = (ltimeout > INT_MAX) ? INT_MAX : (
int) ltimeout;
3868 p[poll_server+i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
3871 p[poll_server+i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
3874 p[poll_server+i].events |= MHD_POLL_EVENTS_ERR_DISC;
3882 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3883 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
3885 urh_to_pollfd(urh, &(p[poll_server+i]));
3889 if (0 == poll_server + num_connections)
3894 if (MHD_sys_poll_(p,
3895 poll_server + num_connections,
3904 #ifdef HAVE_MESSAGES 3906 _(
"poll failed: %s\n"),
3919 if ( (-1 != poll_itc_idx) &&
3920 (0 != (p[poll_itc_idx].revents & POLLIN)) )
3921 MHD_itc_clear_ (daemon->
itc);
3931 while (
NULL != (pos = prev))
3935 if (i >= num_connections)
3940 0 != (p[poll_server+i].revents & POLLIN),
3941 0 != (p[poll_server+i].revents & POLLOUT),
3942 0 != (p[poll_server+i].revents & MHD_POLL_REVENTS_ERR_DISC));
3945 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3946 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
3948 if (i >= num_connections)
3955 if ((p[poll_server+i].
fd != urh->connection->socket_fd) ||
3956 (p[poll_server+i+1].fd != urh->mhd.socket))
3958 urh_from_pollfd (urh,
3963 if ( (0 == urh->in_buffer_size) &&
3964 (0 == urh->out_buffer_size) &&
3965 (0 == urh->in_buffer_used) &&
3966 (0 == urh->out_buffer_used) )
3971 urh->clean_ready =
true;
3981 if ( (-1 != poll_listen) &&
3982 (0 != (p[poll_listen].revents & POLLIN)) )
3999 MHD_poll_listen_socket (
struct MHD_Daemon *daemon,
4004 unsigned int poll_count;
4019 p[poll_count].fd = ls;
4020 p[poll_count].events = POLLIN;
4021 p[poll_count].revents = 0;
4022 poll_listen = poll_count;
4025 if (MHD_ITC_IS_VALID_(daemon->
itc))
4027 p[poll_count].fd = MHD_itc_r_fd_ (daemon->
itc);
4028 p[poll_count].events = POLLIN;
4029 p[poll_count].revents = 0;
4030 poll_itc_idx = poll_count;
4041 if (0 == poll_count)
4043 if (MHD_sys_poll_(p,
4051 #ifdef HAVE_MESSAGES 4053 _(
"poll failed: %s\n"),
4058 if ( (-1 != poll_itc_idx) &&
4059 (0 != (p[poll_itc_idx].revents & POLLIN)) )
4060 MHD_itc_clear_ (daemon->
itc);
4065 if ( (-1 != poll_listen) &&
4066 (0 != (p[poll_listen].revents & POLLIN)) )
4088 return MHD_poll_all (daemon,
4090 return MHD_poll_listen_socket (daemon,
4100 #ifdef EPOLL_SUPPORT 4110 #define MAX_EVENTS 128 4113 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4123 is_urh_ready(
struct MHD_UpgradeResponseHandle *
const urh)
4125 const struct MHD_Connection *
const connection = urh->connection;
4127 if ( (0 == urh->in_buffer_size) &&
4128 (0 == urh->out_buffer_size) &&
4129 (0 == urh->in_buffer_used) &&
4130 (0 == urh->out_buffer_used) )
4136 (urh->in_buffer_used < urh->in_buffer_size) )
4139 (urh->out_buffer_used < urh->out_buffer_size) )
4142 (urh->out_buffer_used > 0) )
4145 (urh->in_buffer_used > 0) )
4162 struct epoll_event events[MAX_EVENTS];
4164 struct MHD_UpgradeResponseHandle * pos;
4165 struct MHD_UpgradeResponseHandle * prev;
4167 num_events = MAX_EVENTS;
4168 while (MAX_EVENTS == num_events)
4172 num_events = epoll_wait (daemon->epoll_upgrade_fd,
4176 if (-1 == num_events)
4181 #ifdef HAVE_MESSAGES 4183 _(
"Call to epoll_wait failed: %s\n"),
4188 for (i = 0; i < (
unsigned int) num_events; i++)
4190 struct UpgradeEpollHandle *
const ueh = events[i].data.ptr;
4191 struct MHD_UpgradeResponseHandle *
const urh = ueh->urh;
4192 bool new_err_state =
false;
4194 if (urh->clean_ready)
4198 if (0 != (events[i].events & EPOLLIN))
4200 if (0 != (events[i].events & EPOLLOUT))
4202 if (0 != (events[i].events & EPOLLHUP))
4206 (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
4212 new_err_state =
true;
4215 if (! urh->in_eready_list)
4217 if (new_err_state ||
4221 daemon->eready_urh_tail,
4223 urh->in_eready_list =
true;
4228 prev = daemon->eready_urh_tail;
4229 while (
NULL != (pos = prev))
4233 if (! is_urh_ready(pos))
4236 daemon->eready_urh_tail,
4238 pos->in_eready_list =
false;
4241 if ( (0 == pos->in_buffer_size) &&
4242 (0 == pos->out_buffer_size) &&
4243 (0 == pos->in_buffer_used) &&
4244 (0 == pos->out_buffer_used) )
4247 pos->clean_ready =
true;
4264 static const char *
const epoll_itc_marker =
"itc_marker";
4279 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4280 static const char *
const upgrade_marker =
"upgrade_ptr";
4284 struct epoll_event events[MAX_EVENTS];
4285 struct epoll_event event;
4291 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4292 int run_upgraded =
MHD_NO;
4295 if (-1 == daemon->epoll_fd)
4302 (! daemon->listen_socket_in_epoll) &&
4305 event.events = EPOLLIN;
4306 event.data.ptr = daemon;
4307 if (0 != epoll_ctl (daemon->epoll_fd,
4312 #ifdef HAVE_MESSAGES 4314 _(
"Call to epoll_ctl failed: %s\n"),
4319 daemon->listen_socket_in_epoll =
true;
4322 (daemon->listen_socket_in_epoll) )
4324 if ( (0 != epoll_ctl (daemon->epoll_fd,
4330 MHD_PANIC (
"Failed to remove listen FD from epoll set\n");
4331 daemon->listen_socket_in_epoll =
false;
4334 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4335 if ( (! daemon->upgrade_fd_in_epoll) &&
4336 (-1 != daemon->epoll_upgrade_fd) )
4338 event.events = EPOLLIN | EPOLLOUT;
4339 event.data.ptr = (
void *) upgrade_marker;
4340 if (0 != epoll_ctl (daemon->epoll_fd,
4342 daemon->epoll_upgrade_fd,
4345 #ifdef HAVE_MESSAGES 4347 _(
"Call to epoll_ctl failed: %s\n"),
4352 daemon->upgrade_fd_in_epoll =
true;
4355 if ( (daemon->listen_socket_in_epoll) &&
4362 if (0 != epoll_ctl (daemon->epoll_fd,
4366 MHD_PANIC (
_(
"Failed to remove listen FD from epoll set\n"));
4367 daemon->listen_socket_in_epoll =
false;
4380 timeout_ms = INT_MAX;
4382 timeout_ms = (int) timeout_ll;
4399 num_events = MAX_EVENTS;
4400 while (MAX_EVENTS == num_events)
4403 num_events = epoll_wait (daemon->epoll_fd,
4407 if (-1 == num_events)
4412 #ifdef HAVE_MESSAGES 4414 _(
"Call to epoll_wait failed: %s\n"),
4419 for (i=0;i<(
unsigned int) num_events;i++)
4425 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4426 if (upgrade_marker == events[i].
data.ptr)
4434 if (epoll_itc_marker == events[i].
data.ptr)
4438 MHD_itc_clear_ (daemon->
itc);
4441 if (daemon == events[i].
data.ptr)
4445 if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
4447 unsigned int series_length = 0;
4453 (series_length < 10) &&
4463 pos = events[i].data.ptr;
4465 if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
4471 daemon->eready_tail,
4478 if (0 != (events[i].events & EPOLLIN))
4486 daemon->eready_tail,
4491 if (0 != (events[i].events & EPOLLOUT))
4498 daemon->eready_tail,
4507 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4509 run_epoll_for_upgrade (daemon);
4513 prev = daemon->eready_tail;
4514 while (
NULL != (pos = prev))
4531 daemon->eready_tail,
4547 while (
NULL != (pos = prev))
4557 while (
NULL != (pos = prev))
4600 #ifdef EPOLL_SUPPORT 4603 MHD_epoll (daemon,
MHD_NO);
4636 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4655 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4661 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4669 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
4674 MHD_thread_init_(&(daemon->
pid));
4679 #ifdef EPOLL_SUPPORT 4695 return (MHD_THRD_RTRN_TYPE_)0;
4791 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4802 #ifdef HAVE_MESSAGES 4804 "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC\n");
4809 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4814 #ifdef EPOLL_SUPPORT 4819 if (0 != epoll_ctl (daemon->
worker_pool[i].epoll_fd,
4823 MHD_PANIC (
_(
"Failed to remove listen FD from epoll set\n"));
4824 daemon->
worker_pool[i].listen_socket_in_epoll =
false;
4831 MHD_PANIC (
_(
"Failed to signal quiesce via inter-thread communication channel"));
4836 #ifdef EPOLL_SUPPORT 4838 (-1 != daemon->epoll_fd) &&
4839 (daemon->listen_socket_in_epoll) )
4841 if ( (0 != epoll_ctl (daemon->epoll_fd,
4847 MHD_PANIC (
"Failed to remove listen FD from epoll set\n");
4848 daemon->listen_socket_in_epoll =
false;
4851 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
4852 (! MHD_itc_activate_ (daemon->
itc,
"q")) )
4853 MHD_PANIC (
_(
"failed to signal quiesce via inter-thread communication channel"));
4881 const struct sockaddr **servaddr,
4895 const struct sockaddr **servaddr,
4901 va_start (ap, servaddr);
4920 const struct sockaddr **servaddr,
4927 #ifdef HTTPS_SUPPORT 4930 #if GNUTLS_VERSION_MAJOR >= 3 4931 gnutls_certificate_retrieve_function2 *pgcrf;
4962 #ifdef HAVE_MESSAGES 4964 _(
"Warning: Too large timeout value, ignored.\n"));
4986 *servaddr = va_arg (ap,
4987 const struct sockaddr *);
4995 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5001 #ifdef HAVE_MESSAGES 5003 _(
"Warning: Zero size, specified for thread pool size, is ignored. " 5004 "Thread pool is not used.\n"));
5009 #ifdef HAVE_MESSAGES 5011 _(
"Warning: \"1\", specified for thread pool size, is ignored. " 5012 "Thread pool is not used.\n"));
5021 #ifdef HAVE_MESSAGES 5023 _(
"Specified thread pool size (%u) too big\n"),
5032 #ifdef HAVE_MESSAGES 5034 _(
"MHD_OPTION_THREAD_POOL_SIZE option is specified but " 5035 "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
5041 #ifdef HAVE_MESSAGES 5043 _(
"Both MHD_OPTION_THREAD_POOL_SIZE option and " 5044 "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
5051 #ifdef HTTPS_SUPPORT 5056 daemon->https_mem_key = pstr;
5057 #ifdef HAVE_MESSAGES 5060 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5068 daemon->https_key_password = pstr;
5069 #ifdef HAVE_MESSAGES 5072 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5080 daemon->https_mem_cert = pstr;
5081 #ifdef HAVE_MESSAGES 5084 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5092 daemon->https_mem_trust = pstr;
5093 #ifdef HAVE_MESSAGES 5096 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5101 daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
5109 gnutls_datum_t dhpar;
5112 if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
5114 #ifdef HAVE_MESSAGES 5116 _(
"Error initializing DH parameters\n"));
5120 dhpar.data = (
unsigned char *) pstr;
5121 pstr_len = strlen (pstr);
5124 #ifdef HAVE_MESSAGES 5126 _(
"Diffie-Hellman parameters string too long\n"));
5130 dhpar.size = (
unsigned int) pstr_len;
5131 if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
5133 GNUTLS_X509_FMT_PEM) < 0)
5135 #ifdef HAVE_MESSAGES 5137 _(
"Bad Diffie-Hellman parameters format\n"));
5139 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
5142 daemon->have_dhparams =
true;
5144 #ifdef HAVE_MESSAGES 5147 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5156 gnutls_priority_deinit (daemon->priority_cache);
5157 ret = gnutls_priority_init (&daemon->priority_cache,
5160 if (GNUTLS_E_SUCCESS != ret)
5162 #ifdef HAVE_MESSAGES 5164 _(
"Setting priorities to `%s' failed: %s\n"),
5166 gnutls_strerror (ret));
5168 daemon->priority_cache =
NULL;
5172 #ifdef HAVE_MESSAGES 5175 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5180 #if GNUTLS_VERSION_MAJOR < 3 5181 #ifdef HAVE_MESSAGES 5183 _(
"MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n"));
5188 gnutls_certificate_retrieve_function2 *);
5190 daemon->cert_callback = pgcrf;
5192 #ifdef HAVE_MESSAGES 5194 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5200 #ifdef DAUTH_SUPPORT 5202 daemon->digest_auth_rand_size = va_arg (ap,
5204 daemon->digest_auth_random = va_arg (ap,
5208 daemon->nonce_nc_size = va_arg (ap,
5215 #ifdef HAVE_MESSAGES 5217 _(
"MHD_OPTION_LISTEN_SOCKET specified for daemon " 5218 "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
5227 #ifdef HAVE_MESSAGES 5228 daemon->custom_error_log = va_arg (ap,
5230 daemon->custom_error_log_cls = va_arg (ap,
5239 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5241 daemon->thread_stack_size = va_arg (ap,
5247 daemon->fastopen_queue_size = va_arg (ap,
5251 #ifdef HAVE_MESSAGES 5253 _(
"TCP fastopen is not supported on this platform\n"));
5259 unsigned int) ? 1 : -1;
5267 #ifdef HAVE_MESSAGES 5272 _(
"Flag MHD_USE_PEDANTIC_CHECKS is ignored because " 5273 "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n"));
5291 (
size_t) oa[i].
value,
5307 (
unsigned int) oa[i].
value,
5312 #ifdef HTTPS_SUPPORT 5317 (gnutls_credentials_type_t) oa[i].
value,
5367 (
void *) oa[i].
value,
5377 (
size_t) oa[i].
value,
5394 #ifdef HTTPS_SUPPORT 5396 #if GNUTLS_VERSION_MAJOR >= 3 5397 daemon->cred_callback = va_arg (ap,
5399 daemon->cred_callback_cls = va_arg (ap,
5404 _(
"MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3\n"),
5410 #ifdef HAVE_MESSAGES 5417 _(
"MHD HTTPS option %d passed to MHD compiled without HTTPS support\n"),
5423 _(
"Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n"),
5434 #ifdef EPOLL_SUPPORT 5440 #ifndef HAVE_MESSAGES 5444 #ifdef USE_EPOLL_CREATE1 5445 fd = epoll_create1 (EPOLL_CLOEXEC);
5447 fd = epoll_create (MAX_EVENTS);
5451 #ifdef HAVE_MESSAGES 5453 _(
"Call to epoll_create1 failed: %s\n"),
5458 #if !defined(USE_EPOLL_CREATE1) 5461 #ifdef HAVE_MESSAGES 5463 _(
"Failed to set noninheritable mode on epoll FD.\n"));
5481 setup_epoll_to_listen (
struct MHD_Daemon *daemon)
5483 struct epoll_event event;
5486 daemon->epoll_fd = setup_epoll_fd (daemon);
5487 if (-1 == daemon->epoll_fd)
5489 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5492 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
5500 event.events = EPOLLIN;
5501 event.data.ptr = daemon;
5502 if (0 != epoll_ctl (daemon->epoll_fd,
5507 #ifdef HAVE_MESSAGES 5509 _(
"Call to epoll_ctl failed: %s\n"),
5514 daemon->listen_socket_in_epoll =
true;
5515 if (MHD_ITC_IS_VALID_(daemon->
itc))
5517 event.events = EPOLLIN;
5518 event.data.ptr = (
void *) epoll_itc_marker;
5519 if (0 != epoll_ctl (daemon->epoll_fd,
5521 MHD_itc_r_fd_ (daemon->
itc),
5524 #ifdef HAVE_MESSAGES 5526 _(
"Call to epoll_ctl failed: %s\n"),
5570 struct sockaddr_in servaddr4;
5572 struct sockaddr_in6 servaddr6;
5574 const struct sockaddr *servaddr =
NULL;
5576 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5593 #ifndef EPOLL_SUPPORT 5597 #ifndef HTTPS_SUPPORT 5601 #ifndef TCP_FASTOPEN 5607 #ifdef UPGRADE_SUPPORT 5638 #if defined(EPOLL_SUPPORT) 5640 #elif defined(HAVE_POLL) 5649 #if defined(EPOLL_SUPPORT) 5659 #ifdef EPOLL_SUPPORT 5660 daemon->epoll_fd = -1;
5661 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5662 daemon->epoll_upgrade_fd = -1;
5666 #ifdef HTTPS_SUPPORT 5667 daemon->priority_cache =
NULL;
5670 gnutls_priority_init (&daemon->priority_cache,
5680 daemon->
port = port;
5691 MHD_itc_set_invalid_ (daemon->
itc);
5697 #ifdef HAVE_MESSAGES 5699 daemon->custom_error_log_cls = stderr;
5704 #ifdef HAVE_MESSAGES 5706 _(
"Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with " 5707 "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD " 5708 "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"));
5716 #ifdef HAVE_LISTEN_SHUTDOWN 5721 #ifdef DAUTH_SUPPORT 5722 daemon->digest_auth_rand_size = 0;
5723 daemon->digest_auth_random =
NULL;
5724 daemon->nonce_nc_size = 4;
5726 #ifdef HTTPS_SUPPORT 5729 daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
5738 #ifdef HTTPS_SUPPORT 5740 (
NULL != daemon->priority_cache) )
5741 gnutls_priority_deinit (daemon->priority_cache);
5752 #ifdef HAVE_MESSAGES 5754 _(
"Using debug build of libmicrohttpd.\n") );
5759 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5764 if (! MHD_itc_init_ (daemon->
itc))
5766 #ifdef HAVE_MESSAGES 5768 _(
"Failed to create inter-thread communication channel: %s\n"),
5769 MHD_itc_last_strerror_ ());
5771 #ifdef HTTPS_SUPPORT 5772 if (
NULL != daemon->priority_cache)
5773 gnutls_priority_deinit (daemon->priority_cache);
5782 #ifdef HAVE_MESSAGES 5784 _(
"file descriptor for inter-thread communication channel exceeds maximum value\n"));
5787 #ifdef HTTPS_SUPPORT 5788 if (
NULL != daemon->priority_cache)
5789 gnutls_priority_deinit (daemon->priority_cache);
5796 #ifdef DAUTH_SUPPORT 5797 if (daemon->nonce_nc_size > 0)
5799 if ( ( (
size_t) (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc))) /
5800 sizeof(
struct MHD_NonceNc) != daemon->nonce_nc_size)
5802 #ifdef HAVE_MESSAGES 5804 _(
"Specified value for NC_SIZE too large\n"));
5806 #ifdef HTTPS_SUPPORT 5808 gnutls_priority_deinit (daemon->priority_cache);
5813 daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc));
5814 if (
NULL == daemon->nnc)
5816 #ifdef HAVE_MESSAGES 5818 _(
"Failed to allocate memory for nonce-nc map: %s\n"),
5821 #ifdef HTTPS_SUPPORT 5823 gnutls_priority_deinit (daemon->priority_cache);
5830 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5831 if (! MHD_mutex_init_ (&daemon->nnc_lock))
5833 #ifdef HAVE_MESSAGES 5835 _(
"MHD failed to initialize nonce-nc mutex\n"));
5837 #ifdef HTTPS_SUPPORT 5839 gnutls_priority_deinit (daemon->priority_cache);
5849 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5853 #ifdef HAVE_MESSAGES 5855 _(
"MHD thread pooling only works with MHD_USE_INTERNAL_POLLING_THREAD\n"));
5867 domain = (*pflags &
MHD_USE_IPv6) ? PF_INET6 : PF_INET;
5877 #ifdef HAVE_MESSAGES 5879 _(
"Failed to create socket for listening: %s\n"),
5888 #ifndef MHD_WINSOCK_SOCKETS 5893 if (0 > setsockopt (listen_fd,
5896 (
void*)&on,
sizeof (on)))
5898 #ifdef HAVE_MESSAGES 5900 _(
"setsockopt failed: %s\n"),
5909 #ifndef MHD_WINSOCK_SOCKETS 5912 if (0 > setsockopt (listen_fd,
5915 (
void*)&on,
sizeof (on)))
5917 #ifdef HAVE_MESSAGES 5919 _(
"setsockopt failed: %s\n"),
5929 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT) 5930 if (0 > setsockopt (listen_fd,
5932 #ifndef MHD_WINSOCK_SOCKETS
5940 #ifdef HAVE_MESSAGES 5942 _(
"setsockopt failed: %s\n"),
5950 #ifdef HAVE_MESSAGES 5952 _(
"Cannot allow listening address reuse: SO_REUSEPORT not defined\n"));
5965 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \ 5966 (defined(__sun) && defined(SO_EXCLBIND)) 5967 if (0 > setsockopt (listen_fd,
5969 #ifdef SO_EXCLUSIVEADDRUSE
5970 SO_EXCLUSIVEADDRUSE,
5977 #ifdef HAVE_MESSAGES 5979 _(
"setsockopt failed: %s\n"),
5984 #elif defined(MHD_WINSOCK_SOCKETS) 5985 #ifdef HAVE_MESSAGES 5987 _(
"Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n"));
5996 addrlen =
sizeof (
struct sockaddr_in6);
5999 addrlen =
sizeof (
struct sockaddr_in);
6000 if (
NULL == servaddr)
6005 #ifdef IN6ADDR_ANY_INIT 6006 static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
6010 sizeof (
struct sockaddr_in6));
6011 servaddr6.sin6_family = AF_INET6;
6012 servaddr6.sin6_port = htons (port);
6013 #ifdef IN6ADDR_ANY_INIT 6014 servaddr6.sin6_addr = static_in6any;
6016 #if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN 6017 servaddr6.sin6_len =
sizeof (
struct sockaddr_in6);
6019 servaddr = (
struct sockaddr *) &servaddr6;
6026 sizeof (
struct sockaddr_in));
6027 servaddr4.sin_family = AF_INET;
6028 servaddr4.sin_port = htons (port);
6029 if (0 != INADDR_ANY)
6030 servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
6031 #if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN 6032 servaddr4.sin_len =
sizeof (
struct sockaddr_in);
6034 servaddr = (
struct sockaddr *) &servaddr4;
6049 if (0 > setsockopt (listen_fd,
6050 IPPROTO_IPV6, IPV6_V6ONLY,
6051 (
const void *) &v6_only,
6054 #ifdef HAVE_MESSAGES 6056 _(
"setsockopt failed: %s\n"),
6063 if (-1 == bind (listen_fd, servaddr, addrlen))
6065 #ifdef HAVE_MESSAGES 6067 _(
"Failed to bind to port %u: %s\n"),
6068 (
unsigned int) port,
6077 if (0 == daemon->fastopen_queue_size)
6078 daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
6079 if (0 != setsockopt (listen_fd,
6082 (
const void*)&daemon->fastopen_queue_size,
6083 sizeof (daemon->fastopen_queue_size)))
6085 #ifdef HAVE_MESSAGES 6087 _(
"setsockopt failed: %s\n"),
6093 if (listen (listen_fd,
6096 #ifdef HAVE_MESSAGES 6098 _(
"Failed to listen for connections: %s\n"),
6110 #ifdef HAVE_GETSOCKNAME 6111 if ( (0 == daemon->
port) &&
6114 struct sockaddr_storage bindaddr;
6118 sizeof (
struct sockaddr_storage));
6119 addrlen =
sizeof (
struct sockaddr_storage);
6120 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 6121 bindaddr.ss_len = addrlen;
6123 if (0 != getsockname (listen_fd,
6124 (
struct sockaddr *) &bindaddr,
6127 #ifdef HAVE_MESSAGES 6129 _(
"Failed to get listen port number: %s\n"),
6133 #ifdef MHD_POSIX_SOCKETS 6134 else if (
sizeof (bindaddr) < addrlen)
6137 #ifdef HAVE_MESSAGES 6139 _(
"Failed to get listen port number (`struct sockaddr_storage` too small!?)\n"));
6143 else if (0 == addrlen)
6153 switch (bindaddr.ss_family)
6157 struct sockaddr_in *s4 = (
struct sockaddr_in *) &bindaddr;
6159 daemon->
port = ntohs (s4->sin_port);
6165 struct sockaddr_in6 *s6 = (
struct sockaddr_in6 *) &bindaddr;
6167 daemon->
port = ntohs(s6->sin6_port);
6178 #ifdef HAVE_MESSAGES 6180 _(
"Unknown address family!\n"));
6192 #ifdef HAVE_MESSAGES 6194 _(
"Failed to set nonblocking mode on listening socket: %s\n"),
6198 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6215 #ifdef HAVE_MESSAGES 6217 _(
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
6225 #ifdef EPOLL_SUPPORT 6227 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6234 #ifdef HAVE_MESSAGES 6236 _(
"Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
6240 if (
MHD_YES != setup_epoll_to_listen (daemon))
6245 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6248 #ifdef HAVE_MESSAGES 6250 _(
"MHD failed to initialize IP connection limit mutex\n"));
6261 #ifdef HAVE_MESSAGES 6263 _(
"MHD failed to initialize IP connection limit mutex\n"));
6265 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6275 #ifdef HTTPS_SUPPORT 6278 (0 != MHD_TLS_init (daemon)) )
6280 #ifdef HAVE_MESSAGES 6282 _(
"Failed to initialize TLS support\n"));
6286 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6294 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6302 "MHD-listen" :
"MHD-single",
6303 daemon->thread_stack_size,
6307 #ifdef HAVE_MESSAGES 6309 _(
"Failed to create listen thread: %s\n"),
6343 memcpy (d, daemon,
sizeof (
struct MHD_Daemon));
6353 if (! MHD_itc_init_ (d->
itc))
6355 #ifdef HAVE_MESSAGES 6357 _(
"Failed to create worker inter-thread communication channel: %s\n"),
6358 MHD_itc_last_strerror_() );
6366 #ifdef HAVE_MESSAGES 6368 _(
"File descriptor for worker inter-thread communication channel exceeds maximum value\n"));
6375 MHD_itc_set_invalid_ (d->
itc);
6381 if (i < leftover_conns)
6383 #ifdef EPOLL_SUPPORT 6385 (
MHD_YES != setup_epoll_to_listen (d)) )
6391 #ifdef HAVE_MESSAGES 6393 _(
"MHD failed to initialize cleanup connection mutex\n"));
6401 daemon->thread_stack_size,
6405 #ifdef HAVE_MESSAGES 6407 _(
"Failed to create pool thread: %s\n"),
6419 #ifdef HTTPS_SUPPORT 6422 daemon->https_key_password =
NULL;
6427 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6455 #ifdef EPOLL_SUPPORT 6456 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6457 if (daemon->upgrade_fd_in_epoll)
6459 if (0 != epoll_ctl (daemon->epoll_fd,
6461 daemon->epoll_upgrade_fd,
6463 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
6464 daemon->upgrade_fd_in_epoll =
false;
6467 if (-1 != daemon->epoll_fd)
6468 close (daemon->epoll_fd);
6469 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6470 if (-1 != daemon->epoll_upgrade_fd)
6471 close (daemon->epoll_upgrade_fd);
6474 #ifdef DAUTH_SUPPORT 6476 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6480 #ifdef HTTPS_SUPPORT 6483 gnutls_priority_deinit (daemon->priority_cache);
6484 if (daemon->x509_cred)
6485 gnutls_certificate_free_credentials (daemon->x509_cred);
6486 if (daemon->psk_cred)
6487 gnutls_psk_free_server_credentials (daemon->psk_cred);
6490 if (MHD_ITC_IS_VALID_(daemon->
itc))
6510 #ifdef UPGRADE_SUPPORT 6513 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6514 struct MHD_UpgradeResponseHandle *urh;
6515 struct MHD_UpgradeResponseHandle *urhn;
6518 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6524 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
6531 urh->clean_ready =
true;
6548 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6551 #ifdef UPGRADE_SUPPORT 6557 while (
NULL != susp)
6559 if (
NULL == susp->urh)
6560 MHD_PANIC (
_(
"MHD_stop_daemon() called while we have suspended connections.\n"));
6561 #ifdef HTTPS_SUPPORT 6562 else if (used_tls &&
6564 (! susp->urh->clean_ready) )
6565 shutdown (susp->urh->app.socket,
6570 #ifdef HAVE_MESSAGES 6571 if (! susp->urh->was_closed)
6573 _(
"Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
6575 susp->urh->was_closed =
true;
6591 MHD_PANIC (
_(
"MHD_stop_daemon() called while we have suspended connections.\n"));
6596 #if MHD_WINSOCK_SOCKETS 6599 (! MHD_itc_activate_ (
daemon->
itc,
"e")) )
6600 MHD_PANIC (
_(
"Failed to signal shutdown via inter-thread communication channel"));
6604 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6614 if (! MHD_join_thread_ (pos->
pid.handle))
6629 #ifdef UPGRADE_SUPPORT 6644 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6665 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6678 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6692 MHD_PANIC (
_(
"Failed to signal shutdown via inter-thread communication channel."));
6697 #ifdef HAVE_LISTEN_SHUTDOWN 6700 (void) shutdown (
fd,
6710 #ifdef EPOLL_SUPPORT 6712 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6720 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6729 MHD_PANIC (
_(
"Failed to signal shutdown via inter-thread communication channel"));
6733 #ifdef HAVE_LISTEN_SHUTDOWN 6737 (void) shutdown (
fd,
6745 if (! MHD_join_thread_ (
daemon->
pid.handle))
6760 #ifdef EPOLL_SUPPORT 6762 (-1 !=
daemon->epoll_fd) )
6764 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6766 (-1 !=
daemon->epoll_upgrade_fd) )
6771 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6784 #ifdef HTTPS_SUPPORT 6785 if (
daemon->have_dhparams)
6787 gnutls_dh_params_deinit (
daemon->https_mem_dhparams);
6788 daemon->have_dhparams =
false;
6792 gnutls_priority_deinit (
daemon->priority_cache);
6794 gnutls_certificate_free_credentials (
daemon->x509_cred);
6796 gnutls_psk_free_server_credentials (
daemon->psk_cred);
6800 #ifdef DAUTH_SUPPORT 6802 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6806 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6840 #ifdef EPOLL_SUPPORT 6851 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6909 #ifdef PACKAGE_VERSION 6910 return PACKAGE_VERSION;
6912 static char ver[12] =
"\0\0\0\0\0\0\0\0\0\0\0";
6915 int res = MHD_snprintf_(ver,
6921 if (0 >= res ||
sizeof(ver) <= res)
6946 #ifdef HAVE_MESSAGES 6952 #ifdef HTTPS_SUPPORT 6958 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3 6970 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) 6982 #ifdef EPOLL_SUPPORT 6988 #ifdef HAVE_LISTEN_SHUTDOWN 6994 #ifdef _MHD_ITC_SOCKETPAIR 7006 #ifdef BAUTH_SUPPORT 7012 #ifdef DAUTH_SUPPORT 7018 #ifdef HAVE_POSTPROCESSOR 7024 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111 7030 #if defined(HAVE_PREAD64) || defined(_WIN32) 7032 #elif defined(HAVE_PREAD) 7033 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
7034 #elif defined(HAVE_LSEEK64) 7037 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
7040 #if defined(MHD_USE_THREAD_NAME_) 7046 #if defined(UPGRADE_SUPPORT) 7052 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32) 7058 #ifdef MHD_USE_GETSOCKNAME 7064 #if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || defined (MSG_NOSIGNAL) 7070 #ifdef _MHD_HAVE_SENDFILE 7076 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 7087 #ifdef MHD_HTTPS_REQUIRE_GRYPT 7088 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600 7089 #if defined(MHD_USE_POSIX_THREADS) 7090 GCRY_THREAD_OPTION_PTHREAD_IMPL;
7091 #elif defined(MHD_W32_MUTEX_) 7094 gcry_w32_mutex_init (
void **ppmtx)
7096 *ppmtx = malloc (
sizeof (MHD_mutex_));
7100 if (!MHD_mutex_init_ ((MHD_mutex_*)*ppmtx))
7112 gcry_w32_mutex_destroy (
void **ppmtx)
7114 int res = (MHD_mutex_destroy_ ((MHD_mutex_*)*ppmtx)) ? 0 : EINVAL;
7121 gcry_w32_mutex_lock (
void **ppmtx)
7123 return MHD_mutex_lock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
7128 gcry_w32_mutex_unlock (
void **ppmtx)
7130 return MHD_mutex_unlock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
7134 static struct gcry_thread_cbs gcry_threads_w32 = {
7135 (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
7136 NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
7137 gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
7150 #if defined(MHD_WINSOCK_SOCKETS) 7157 #if defined(MHD_WINSOCK_SOCKETS) 7158 if (0 != WSAStartup(MAKEWORD(2, 2), &wsd))
7159 MHD_PANIC (
_(
"Failed to initialize winsock\n"));
7160 mhd_winsock_inited_ = 1;
7161 if (2 != LOBYTE(wsd.wVersion) && 2 != HIBYTE(wsd.wVersion))
7162 MHD_PANIC (
_(
"Winsock version 2.2 is not available\n"));
7164 #ifdef HTTPS_SUPPORT 7165 #ifdef MHD_HTTPS_REQUIRE_GRYPT 7166 #if GCRYPT_VERSION_NUMBER < 0x010600 7167 #if defined(MHD_USE_POSIX_THREADS) 7168 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7169 &gcry_threads_pthread))
7170 MHD_PANIC (
_(
"Failed to initialise multithreading in libgcrypt\n"));
7171 #elif defined(MHD_W32_MUTEX_) 7172 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7174 MHD_PANIC (
_(
"Failed to initialise multithreading in libgcrypt\n"));
7176 gcry_check_version (
NULL);
7178 if (
NULL == gcry_check_version (
"1.6.0"))
7179 MHD_PANIC (
_(
"libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n"));
7182 gnutls_global_init ();
7185 #ifdef HAVE_FREEBSD_SENDFILE 7186 MHD_conn_init_static_ ();
7195 #ifdef HTTPS_SUPPORT 7196 gnutls_global_deinit ();
7198 #if defined(MHD_WINSOCK_SOCKETS) 7199 if (mhd_winsock_inited_)
7205 #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