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(_WIN32) && ! defined(__CYGWIN__)
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_
260 struct in6_addr ipv6;
279 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
295 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
318 offsetof (
struct MHD_IPCount,
334 struct MHD_IPCount *key)
341 if (
sizeof (
struct sockaddr_in) == addrlen)
343 const struct sockaddr_in *addr4 = (
const struct sockaddr_in*) addr;
345 key->family = AF_INET;
346 memcpy (&key->addr.ipv4,
348 sizeof(addr4->sin_addr));
354 if (
sizeof (
struct sockaddr_in6) == addrlen)
356 const struct sockaddr_in6 *addr6 = (
const struct sockaddr_in6*) addr;
358 key->family = AF_INET6;
359 memcpy (&key->addr.ipv6,
361 sizeof(addr6->sin6_addr));
384 const struct sockaddr *addr,
387 struct MHD_IPCount *key;
397 if (
NULL == (key = malloc (
sizeof(*key))))
418 _(
"Failed to add IP connection count node\n"));
428 key = (
struct MHD_IPCount *) node;
450 const struct sockaddr *addr,
453 struct MHD_IPCount search_key;
454 struct MHD_IPCount *found_key;
476 MHD_PANIC (
_(
"Failed to find previously-added IP address\n"));
478 found_key = (
struct MHD_IPCount *) *nodep;
480 if (0 == found_key->count)
482 MHD_PANIC (
_(
"Previously-added IP address had counter of zero\n"));
485 if (0 == --found_key->count)
511 #if GNUTLS_VERSION_MAJOR >= 3
512 if (
NULL != daemon->cert_callback)
514 gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
515 daemon->cert_callback);
518 if (
NULL != daemon->https_mem_trust)
520 cert.data = (
unsigned char *) daemon->https_mem_trust;
521 cert.size = strlen (daemon->https_mem_trust);
522 if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred,
524 GNUTLS_X509_FMT_PEM) < 0)
528 "Bad trust certificate format\n");
534 if (daemon->have_dhparams)
536 gnutls_certificate_set_dh_params (daemon->x509_cred,
537 daemon->https_mem_dhparams);
540 if ( (
NULL != daemon->https_mem_cert) &&
541 (
NULL != daemon->https_mem_key) )
543 key.data = (
unsigned char *) daemon->https_mem_key;
544 key.size = strlen (daemon->https_mem_key);
545 cert.data = (
unsigned char *) daemon->https_mem_cert;
546 cert.size = strlen (daemon->https_mem_cert);
548 if (
NULL != daemon->https_key_password) {
549 #if GNUTLS_VERSION_NUMBER >= 0x030111
550 ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
554 daemon->https_key_password,
559 _(
"Failed to setup x509 certificate/key: pre 3.X.X version " \
560 "of GnuTLS does not support setting key password"));
566 ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
569 GNUTLS_X509_FMT_PEM);
573 "GnuTLS failed to setup x509 certificate/key: %s\n",
574 gnutls_strerror (ret));
578 #if GNUTLS_VERSION_MAJOR >= 3
579 if (
NULL != daemon->cert_callback)
584 "You need to specify a certificate and key location\n");
598 switch (daemon->cred_type)
600 case GNUTLS_CRD_CERTIFICATE:
602 gnutls_certificate_allocate_credentials (&daemon->x509_cred))
603 return GNUTLS_E_MEMORY_ERROR;
604 return MHD_init_daemon_certificate (daemon);
607 gnutls_psk_allocate_server_credentials (&daemon->psk_cred))
608 return GNUTLS_E_MEMORY_ERROR;
613 _(
"Error: invalid credentials type %d specified.\n"),
656 fd_set *write_fd_set,
657 fd_set *except_fd_set,
669 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
683 urh_to_fdset (
struct MHD_UpgradeResponseHandle *urh,
688 unsigned int fd_setsize)
690 const MHD_socket conn_sckt = urh->connection->socket_fd;
698 if ( (urh->in_buffer_used < urh->in_buffer_size) &&
704 if ( (0 != urh->out_buffer_used) &&
713 ((0 != urh->in_buffer_size) ||
714 (0 != urh->out_buffer_size) ||
715 (0 != urh->out_buffer_used)))
723 if ( (urh->out_buffer_used < urh->out_buffer_size) &&
729 if ( (0 != urh->in_buffer_used) &&
738 ((0 != urh->out_buffer_size) ||
739 (0 != urh->in_buffer_size) ||
740 (0 != urh->in_buffer_used)))
761 urh_from_fdset (
struct MHD_UpgradeResponseHandle *urh,
766 const MHD_socket conn_sckt = urh->connection->socket_fd;
775 if (FD_ISSET (conn_sckt, rs))
777 if (FD_ISSET (conn_sckt, ws))
779 if (FD_ISSET (conn_sckt, es))
784 if (FD_ISSET (mhd_sckt, rs))
786 if (FD_ISSET (mhd_sckt, ws))
788 if (FD_ISSET (mhd_sckt, es))
804 urh_update_pollfd (
struct MHD_UpgradeResponseHandle *urh,
810 if (urh->in_buffer_used < urh->in_buffer_size)
811 p[0].events |= POLLIN;
812 if (0 != urh->out_buffer_used)
813 p[0].events |= POLLOUT;
818 ((0 != urh->in_buffer_size) ||
819 (0 != urh->out_buffer_size) ||
820 (0 != urh->out_buffer_used)))
821 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
823 if (urh->out_buffer_used < urh->out_buffer_size)
824 p[1].events |= POLLIN;
825 if (0 != urh->in_buffer_used)
826 p[1].events |= POLLOUT;
831 ((0 != urh->out_buffer_size) ||
832 (0 != urh->in_buffer_size) ||
833 (0 != urh->in_buffer_used)))
834 p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
845 urh_to_pollfd (
struct MHD_UpgradeResponseHandle *urh,
848 p[0].fd = urh->connection->socket_fd;
849 p[1].fd = urh->mhd.socket;
850 urh_update_pollfd (urh,
861 urh_from_pollfd (
struct MHD_UpgradeResponseHandle *urh,
868 if (0 != (p[0].revents & POLLIN))
870 if (0 != (p[0].revents & POLLOUT))
872 if (0 != (p[0].revents & POLLHUP))
874 if (0 != (p[0].revents & MHD_POLL_REVENTS_ERRROR))
876 if (0 != (p[1].revents & POLLIN))
878 if (0 != (p[1].revents & POLLOUT))
880 if (0 != (p[1].revents & POLLHUP))
882 if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
906 fd_set *write_fd_set,
907 fd_set *except_fd_set,
909 unsigned int fd_setsize)
945 #ifdef MHD_POSIX_SOCKETS
958 #ifdef MHD_POSIX_SOCKETS
966 if ( (
NULL == except_fd_set) ||
978 #ifdef MHD_WINSOCK_SOCKETS
991 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
993 struct MHD_UpgradeResponseHandle *urh;
995 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
1009 #ifdef HAVE_MESSAGES
1012 _(
"Maximum socket in select set: %d\n"),
1054 fd_set *read_fd_set,
1055 fd_set *write_fd_set,
1056 fd_set *except_fd_set,
1058 unsigned int fd_setsize)
1062 if ( (
NULL == daemon) ||
1063 (
NULL == read_fd_set) ||
1064 (
NULL == write_fd_set) ||
1069 if (
NULL == except_fd_set)
1071 #ifdef HAVE_MESSAGES
1073 _(
"MHD_get_fdset2() called with except_fd_set "
1074 "set to NULL. Such behavior is unsupported.\n"));
1077 except_fd_set = &es;
1080 #ifdef EPOLL_SUPPORT
1125 bool states_info_processed =
false;
1129 #ifdef HTTPS_SUPPORT
1140 states_info_processed =
true;
1149 states_info_processed =
true;
1159 if (!states_info_processed)
1206 #ifdef HTTPS_SUPPORT
1216 #ifdef UPGRADE_SUPPORT
1227 struct MHD_UpgradeResponseHandle *urh = connection->urh;
1231 #ifdef HTTPS_SUPPORT
1235 gnutls_bye (connection->tls_session,
1244 connection->urh =
NULL;
1250 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
1260 process_urh (
struct MHD_UpgradeResponseHandle *urh)
1275 #ifdef HAVE_MESSAGES
1276 if (! urh->was_closed)
1279 _(
"Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
1282 urh->was_closed =
true;
1284 was_closed = urh->was_closed;
1289 if (0 < urh->in_buffer_used)
1291 #ifdef HAVE_MESSAGES
1294 " bytes of data received from remote side: application shut down socket\n"),
1304 if (0 != urh->out_buffer_size)
1307 urh->in_buffer_used = 0;
1311 urh->in_buffer_size = 0;
1334 (urh->in_buffer_used < urh->in_buffer_size) )
1339 buf_size = urh->in_buffer_size - urh->in_buffer_used;
1340 if (buf_size > SSIZE_MAX)
1341 buf_size = SSIZE_MAX;
1344 res = gnutls_record_recv (connection->tls_session,
1345 &urh->in_buffer[urh->in_buffer_used],
1349 if (GNUTLS_E_INTERRUPTED != res)
1352 if (GNUTLS_E_AGAIN != res)
1357 urh->in_buffer_size = 0;
1363 urh->in_buffer_used += res;
1364 if (buf_size > (
size_t)res)
1366 else if (0 < gnutls_record_check_pending (connection->tls_session))
1375 urh->in_buffer_size = 0;
1383 (urh->out_buffer_used < urh->out_buffer_size) )
1388 buf_size = urh->out_buffer_size - urh->out_buffer_used;
1393 &urh->out_buffer[urh->out_buffer_used],
1412 urh->out_buffer_size = 0;
1418 urh->out_buffer_used += res;
1419 if (buf_size > (
size_t)res)
1429 urh->out_buffer_size = 0;
1437 (urh->out_buffer_used > 0) )
1442 data_size = urh->out_buffer_used;
1443 if (data_size > SSIZE_MAX)
1444 data_size = SSIZE_MAX;
1446 res = gnutls_record_send (connection->tls_session,
1451 if (GNUTLS_E_INTERRUPTED != res)
1454 if (GNUTLS_E_INTERRUPTED != res)
1458 #ifdef HAVE_MESSAGES
1461 " bytes of data received from application: %s\n"),
1463 gnutls_strerror(res));
1466 urh->out_buffer_used = 0;
1468 urh->out_buffer_size = 0;
1475 const size_t next_out_buffer_used = urh->out_buffer_used - res;
1476 if (0 != next_out_buffer_used)
1478 memmove (urh->out_buffer,
1479 &urh->out_buffer[res],
1480 next_out_buffer_used);
1481 if (data_size > (
size_t)res)
1484 urh->out_buffer_used = next_out_buffer_used;
1486 if ( (0 == urh->out_buffer_used) &&
1494 urh->out_buffer_size = 0;
1503 (urh->in_buffer_used > 0) )
1508 data_size = urh->in_buffer_used;
1526 #ifdef HAVE_MESSAGES
1529 " bytes of data received from remote side: %s\n"),
1534 urh->in_buffer_used = 0;
1536 urh->in_buffer_size = 0;
1544 const size_t next_in_buffer_used = urh->in_buffer_used - res;
1545 if (0 != next_in_buffer_used)
1547 memmove (urh->in_buffer,
1548 &urh->in_buffer[res],
1549 next_in_buffer_used);
1550 if (data_size > (
size_t)res)
1553 urh->in_buffer_used = next_in_buffer_used;
1555 if ( (0 == urh->in_buffer_used) &&
1561 urh->in_buffer_size = 0;
1570 (urh->in_buffer_used < urh->in_buffer_size) &&
1575 ( (0 != urh->out_buffer_size) ||
1576 (0 != urh->out_buffer_used) ) )
1579 #ifdef HAVE_MESSAGES
1580 if (0 < urh->out_buffer_used)
1583 " bytes of data received from application: daemon shut down\n"),
1587 urh->out_buffer_used = 0;
1591 urh->out_buffer_size = 0;
1597 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1598 #ifdef UPGRADE_SUPPORT
1610 #ifdef HTTPS_SUPPORT
1611 struct MHD_UpgradeResponseHandle *urh = con->urh;
1620 while ( (0 != urh->in_buffer_size) ||
1621 (0 != urh->out_buffer_size) ||
1622 (0 != urh->in_buffer_used) ||
1623 (0 != urh->out_buffer_used) )
1637 result = urh_to_fdset (urh,
1645 #ifdef HAVE_MESSAGES
1647 _(
"Error preparing select\n"));
1654 struct timeval* tvp;
1657 (urh->in_buffer_used < urh->in_buffer_size))
1679 #ifdef HAVE_MESSAGES
1681 _(
"Error during select (%d): `%s'\n"),
1687 urh_from_fdset (urh,
1702 p[0].fd = urh->connection->socket_fd;
1703 p[1].fd = urh->mhd.socket;
1705 while ( (0 != urh->in_buffer_size) ||
1706 (0 != urh->out_buffer_size) ||
1707 (0 != urh->in_buffer_used) ||
1708 (0 != urh->out_buffer_used) )
1712 urh_update_pollfd(urh, p);
1715 (urh->in_buffer_used < urh->in_buffer_size))
1720 if (MHD_sys_poll_ (p,
1728 #ifdef HAVE_MESSAGES
1730 _(
"Error during poll: `%s'\n"),
1735 urh_from_pollfd (urh,
1759 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
1770 struct timeval *tvp;
1776 #define EXTRA_SLOTS 1
1778 #define EXTRA_SLOTS 0
1787 const bool use_poll = 0;
1789 bool was_suspended =
false;
1790 MHD_thread_init_(&(con->
pid));
1796 #ifdef UPGRADE_SUPPORT
1797 struct MHD_UpgradeResponseHandle *
const urh = con->urh;
1799 static const void *
const urh =
NULL;
1806 was_suspended =
true;
1815 #ifdef HAVE_MESSAGES
1817 _(
"Failed to add FD to fd_set\n"));
1831 #ifdef HAVE_MESSAGES
1833 _(
"Error during select (%d): `%s'\n"),
1843 p[0].events = POLLIN;
1844 p[0].fd = MHD_itc_r_fd_ (daemon->
itc);
1846 if (0 > MHD_sys_poll_ (p,
1852 #ifdef HAVE_MESSAGES
1854 _(
"Error during poll: `%s'\n"),
1861 MHD_itc_clear_ (daemon->
itc);
1870 was_suspended =
false;
1876 #ifdef HTTPS_SUPPORT
1888 if ( (
NULL == tvp) &&
1896 const time_t seconds_left = timeout - (now - con->
last_activity);
1897 #if !defined(_WIN32) || defined(__CYGWIN__)
1898 tv.tv_sec = seconds_left;
1912 bool err_state =
false;
1946 if (MHD_ITC_IS_VALID_(daemon->
itc) )
1957 #ifdef HAVE_MESSAGES
1959 _(
"Failed to add FD to fd_set\n"));
1975 #ifdef HAVE_MESSAGES
1977 _(
"Error during select (%d): `%s'\n"),
1986 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
1987 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
1989 MHD_itc_clear_ (daemon->
itc);
2012 p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
2015 p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
2018 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
2026 if (MHD_ITC_IS_VALID_(daemon->
itc))
2028 p[1].events |= POLLIN;
2029 p[1].fd = MHD_itc_r_fd_ (daemon->
itc);
2034 if (MHD_sys_poll_ (p,
2040 (
NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
2044 #ifdef HAVE_MESSAGES
2046 _(
"Error during poll: `%s'\n"),
2054 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2055 (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
2056 MHD_itc_clear_ (daemon->
itc);
2060 0 != (p[0].revents & POLLIN),
2061 0 != (p[0].revents & POLLOUT),
2062 0 != (p[0].revents & (POLLERR | MHD_POLL_REVENTS_ERR_DISC))))
2066 #ifdef UPGRADE_SUPPORT
2067 if (MHD_CONNECTION_UPGRADE == con->
state)
2079 thread_main_connection_upgrade (con);
2083 con->urh->clean_ready =
true;
2091 return (MHD_THRD_RTRN_TYPE_) 0;
2096 #ifdef HAVE_MESSAGES
2098 _(
"Processing thread terminating. Closing connection\n"));
2122 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2123 (! MHD_itc_activate_ (daemon->
itc,
"t")) )
2125 #ifdef HAVE_MESSAGES
2127 _(
"Failed to signal thread termination via inter-thread communication channel."));
2130 return (MHD_THRD_RTRN_TYPE_) 0;
2145 #if defined(HTTPS_SUPPORT)
2146 #if !defined(MHD_WINSOCK_SOCKETS) && !defined(MHD_socket_nosignal_) && \
2147 (GNUTLS_VERSION_NUMBER+0 < 0x030402) && defined(MSG_NOSIGNAL)
2153 #define MHD_TLSLIB_NEED_PUSH_FUNC 1
2156 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2162 MHD_tls_push_func_(gnutls_transport_ptr_t trnsp,
2166 #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX)
2184 psk_gnutls_adapter (gnutls_session_t session,
2185 const char *username,
2186 gnutls_datum_t *key)
2191 size_t app_psk_size;
2193 connection = gnutls_session_get_ptr (session);
2194 if (
NULL == connection)
2196 #ifdef HAVE_MESSAGES
2198 MHD_PANIC (
_(
"Internal server error. This should be impossible.\n"));
2202 daemon = connection->
daemon;
2203 #if GNUTLS_VERSION_MAJOR >= 3
2204 if (
NULL == daemon->cred_callback)
2206 #ifdef HAVE_MESSAGES
2208 _(
"PSK not supported by this server.\n"));
2212 if (0 != daemon->cred_callback (daemon->cred_callback_cls,
2218 if (
NULL == (key->data = gnutls_malloc (app_psk_size)))
2220 #ifdef HAVE_MESSAGES
2222 _(
"PSK authentication failed: gnutls_malloc failed to allocate memory\n"));
2227 key->size = app_psk_size;
2234 #ifdef HAVE_MESSAGES
2236 _(
"PSK not supported by this server.\n"));
2272 const struct sockaddr *addr,
2278 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2284 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2316 #ifdef HAVE_MESSAGES
2318 _(
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
2319 (
int) client_socket,
2329 #ifdef MHD_socket_nosignal_
2330 if (! MHD_socket_nosignal_ (client_socket))
2332 #ifdef HAVE_MESSAGES
2334 _(
"Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
2337 #ifndef MSG_NOSIGNAL
2348 #ifdef HAVE_MESSAGES
2351 _(
"Accepted connection on socket %d\n"),
2361 #ifdef HAVE_MESSAGES
2363 _(
"Server reached connection limit. Closing inbound connection.\n"));
2379 #ifdef HAVE_MESSAGES
2381 _(
"Connection rejected by application. Closing connection.\n"));
2397 #ifdef HAVE_MESSAGES
2399 "Error allocating memory: %s\n",
2412 #ifdef HAVE_MESSAGES
2414 _(
"Error allocating memory: %s\n"),
2429 if (
NULL == (connection->
addr = malloc (addrlen)))
2432 #ifdef HAVE_MESSAGES
2434 _(
"Error allocating memory: %s\n"),
2446 memcpy (connection->
addr,
2462 #ifdef HTTPS_SUPPORT
2465 gnutls_init (&connection->tls_session,
2467 #
if (GNUTLS_VERSION_NUMBER+0 >= 0x030402)
2470 #
if GNUTLS_VERSION_MAJOR >= 3
2474 gnutls_priority_set (connection->tls_session,
2475 daemon->priority_cache);
2476 gnutls_session_set_ptr (connection->tls_session,
2478 switch (daemon->cred_type)
2481 case GNUTLS_CRD_CERTIFICATE:
2482 gnutls_credentials_set (connection->tls_session,
2483 GNUTLS_CRD_CERTIFICATE,
2486 case GNUTLS_CRD_PSK:
2487 gnutls_credentials_set (connection->tls_session,
2490 gnutls_psk_set_server_credentials_function (daemon->psk_cred,
2491 &psk_gnutls_adapter);
2494 #ifdef HAVE_MESSAGES
2495 MHD_DLOG (connection->
daemon,
2496 _(
"Failed to setup TLS credentials: unknown credential type %d\n"),
2503 free (connection->
addr);
2511 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030109) && !defined(_WIN64)
2512 gnutls_transport_set_int (connection->tls_session,
2513 (
int)(client_socket));
2515 gnutls_transport_set_ptr (connection->tls_session,
2516 (gnutls_transport_ptr_t)(intptr_t)(client_socket));
2518 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2519 gnutls_transport_set_push_function (connection->tls_session,
2520 MHD_tls_push_func_);
2522 if (daemon->https_mem_trust)
2523 gnutls_certificate_server_set_request (connection->tls_session,
2524 GNUTLS_CERT_REQUEST);
2531 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2537 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2541 #ifdef HAVE_MESSAGES
2543 _(
"Server reached connection limit. Closing inbound connection.\n"));
2560 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2568 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2574 daemon->thread_stack_size,
2579 #ifdef HAVE_MESSAGES
2581 "Failed to create a thread: %s\n",
2588 connection->
pid = daemon->
pid;
2590 #ifdef EPOLL_SUPPORT
2595 struct epoll_event event;
2597 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2598 event.data.ptr = connection;
2599 if (0 != epoll_ctl (daemon->epoll_fd,
2605 #ifdef HAVE_MESSAGES
2607 _(
"Call to epoll_ctl failed: %s\n"),
2619 daemon->eready_tail,
2627 (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2628 (! MHD_itc_activate_ (daemon->
itc,
"n")) )
2630 #ifdef HAVE_MESSAGES
2632 _(
"Failed to signal new connection via inter-thread communication channel."));
2642 #ifdef HTTPS_SUPPORT
2643 if (
NULL != connection->tls_session)
2644 gnutls_deinit (connection->tls_session);
2650 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2662 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2666 free (connection->
addr);
2690 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2697 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2721 #ifdef EPOLL_SUPPORT
2727 daemon->eready_tail,
2733 if (0 != epoll_ctl (daemon->epoll_fd,
2737 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
2743 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2786 MHD_PANIC (
_(
"Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2787 #ifdef UPGRADE_SUPPORT
2788 if (
NULL != connection->urh)
2790 #ifdef HAVE_MESSAGES
2792 _(
"Error: connection scheduled for \"upgrade\" cannot be suspended"));
2815 MHD_PANIC (
_(
"Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2816 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2821 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2824 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2825 (! MHD_itc_activate_ (daemon->
itc,
"r")) )
2827 #ifdef HAVE_MESSAGES
2829 _(
"Failed to signal resume via inter-thread communication channel."));
2851 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2855 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2867 while (
NULL != (pos = prev))
2869 #ifdef UPGRADE_SUPPORT
2870 struct MHD_UpgradeResponseHandle *
const urh = pos->urh;
2872 static const void *
const urh =
NULL;
2876 #ifdef UPGRADE_SUPPORT
2877 || ( (
NULL != urh) &&
2878 ( (! urh->was_closed) ||
2879 (! urh->clean_ready) ) )
2909 #ifdef EPOLL_SUPPORT
2913 MHD_PANIC (
"Resumed connection was already in EREADY set\n");
2917 daemon->eready_tail,
2925 #ifdef UPGRADE_SUPPORT
2950 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2953 if ( (used_thr_p_c) &&
2956 if (! MHD_itc_activate_(daemon->
itc,
2959 #ifdef HAVE_MESSAGES
2961 _(
"Failed to signal resume of connection via inter-thread communication channel."));
2999 const struct sockaddr *addr,
3005 #ifdef HAVE_MESSAGES
3007 _(
"Failed to set nonblocking mode on new client socket: %s\n"),
3018 #ifdef HAVE_MESSAGES
3020 _(
"Failed to set noninheritable mode on new client socket.\n"));
3050 struct sockaddr_in6 addrstorage;
3052 struct sockaddr_in addrstorage;
3054 struct sockaddr *addr = (
struct sockaddr *) &addrstorage;
3060 addrlen =
sizeof (addrstorage);
3063 sizeof (addrstorage));
3090 #ifdef HAVE_MESSAGES
3093 _(
"Error accepting connection: %s\n"),
3105 #ifdef HAVE_MESSAGES
3110 _(
"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"));
3115 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3119 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3122 #ifdef HAVE_MESSAGES
3124 _(
"Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
3131 #if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK)
3134 #ifdef HAVE_MESSAGES
3136 _(
"Failed to set nonblocking mode on incoming connection socket: %s\n"),
3143 #if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC)
3146 #ifdef HAVE_MESSAGES
3148 _(
"Failed to set noninheritable mode on incoming connection socket.\n"));
3152 #ifdef HAVE_MESSAGES
3155 _(
"Accepted connection on socket %d\n"),
3183 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3191 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3195 (! MHD_join_thread_ (pos->
pid.handle)) )
3198 #ifdef UPGRADE_SUPPORT
3199 cleanup_upgraded_connection (pos);
3202 #ifdef HTTPS_SUPPORT
3203 if (
NULL != pos->tls_session)
3204 gnutls_deinit (pos->tls_session);
3216 #ifdef EPOLL_SUPPORT
3222 daemon->eready_tail,
3226 if ( (-1 != daemon->epoll_fd) &&
3235 if (0 != epoll_ctl (daemon->epoll_fd,
3239 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
3255 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3261 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3291 time_t earliest_deadline;
3298 #ifdef HAVE_MESSAGES
3300 _(
"Illegal call to MHD_get_timeout\n"));
3312 #ifdef EPOLL_SUPPORT
3314 ((
NULL != daemon->eready_head)
3315 #
if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
3316 || (
NULL != daemon->eready_urh_head)
3326 have_timeout =
false;
3327 earliest_deadline = 0;
3332 if ( (! have_timeout) ||
3335 have_timeout =
true;
3340 if ( (
NULL != pos) &&
3343 if ( (! have_timeout) ||
3346 have_timeout =
true;
3352 if (earliest_deadline < now)
3356 const time_t second_left = earliest_deadline - now;
3358 if (((
unsigned long long)second_left) >
ULLONG_MAX / 1000)
3361 *timeout = 1000LLU * (
unsigned long long) second_left;
3379 const fd_set *read_fd_set,
3380 const fd_set *write_fd_set,
3381 const fd_set *except_fd_set)
3386 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3387 struct MHD_UpgradeResponseHandle *urh;
3388 struct MHD_UpgradeResponseHandle *urhn;
3397 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
3398 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
3400 MHD_itc_clear_ (daemon->
itc);
3413 while (
NULL != (pos = prev))
3429 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3431 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
3435 urh_from_fdset (urh,
3442 if ( (0 == urh->in_buffer_size) &&
3443 (0 == urh->out_buffer_size) &&
3444 (0 == urh->in_buffer_used) &&
3445 (0 == urh->out_buffer_used) )
3448 urh->clean_ready =
true;
3483 const fd_set *read_fd_set,
3484 const fd_set *write_fd_set,
3485 const fd_set *except_fd_set)
3491 if (
NULL == read_fd_set ||
NULL == write_fd_set)
3493 if (
NULL == except_fd_set)
3495 #ifdef HAVE_MESSAGES
3497 _(
"MHD_run_from_select() called with except_fd_set "
3498 "set to NULL. Such behavior is deprecated.\n"));
3501 except_fd_set = &es;
3505 #ifdef EPOLL_SUPPORT
3506 int ret = MHD_epoll (daemon,
3544 struct timeval timeout;
3551 timeout.tv_usec = 0;
3575 #ifdef HAVE_MESSAGES
3577 _(
"Could not obtain daemon fdsets"));
3592 #ifdef HAVE_MESSAGES
3594 _(
"Could not add listen socket to fdset"));
3599 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
3605 #if defined(MHD_WINSOCK_SOCKETS)
3620 #ifdef HAVE_MESSAGES
3622 _(
"Could not add control inter-thread communication channel FD to fdset"));
3625 #if defined(MHD_WINSOCK_SOCKETS)
3637 (MHD_ITC_IS_VALID_(daemon->
itc)) &&
3649 timeout.tv_usec = 0;
3657 timeout.tv_usec = (ltimeout % 1000) * 1000;
3676 #ifdef HAVE_MESSAGES
3678 _(
"select failed: %s\n"),
3705 unsigned int num_connections;
3708 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3709 struct MHD_UpgradeResponseHandle *urh;
3710 struct MHD_UpgradeResponseHandle *urhn;
3718 num_connections = 0;
3721 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3722 for (urh = daemon->urh_head;
NULL != urh; urh = urh->next)
3723 num_connections += 2;
3729 unsigned int poll_server;
3736 sizeof (
struct pollfd));
3739 #ifdef HAVE_MESSAGES
3741 _(
"Error allocating memory: %s\n"),
3754 p[poll_server].fd = ls;
3755 p[poll_server].events = POLLIN;
3756 p[poll_server].revents = 0;
3757 poll_listen = (int) poll_server;
3761 if (MHD_ITC_IS_VALID_(daemon->
itc))
3763 p[poll_server].fd = MHD_itc_r_fd_ (daemon->
itc);
3764 p[poll_server].events = POLLIN;
3765 p[poll_server].revents = 0;
3766 poll_itc_idx = (int) poll_server;
3776 timeout = (ltimeout > INT_MAX) ? INT_MAX : (
int) ltimeout;
3785 p[poll_server+i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
3788 p[poll_server+i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
3791 p[poll_server+i].events |= MHD_POLL_EVENTS_ERR_DISC;
3799 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3800 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
3802 urh_to_pollfd(urh, &(p[poll_server+i]));
3806 if (0 == poll_server + num_connections)
3811 if (MHD_sys_poll_(p,
3812 poll_server + num_connections,
3821 #ifdef HAVE_MESSAGES
3823 _(
"poll failed: %s\n"),
3836 if ( (-1 != poll_itc_idx) &&
3837 (0 != (p[poll_itc_idx].revents & POLLIN)) )
3838 MHD_itc_clear_ (daemon->
itc);
3848 while (
NULL != (pos = prev))
3852 if (i >= num_connections)
3857 0 != (p[poll_server+i].revents & POLLIN),
3858 0 != (p[poll_server+i].revents & POLLOUT),
3859 0 != (p[poll_server+i].revents & MHD_POLL_REVENTS_ERR_DISC));
3862 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3863 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
3865 if (i >= num_connections)
3872 if ((p[poll_server+i].
fd != urh->connection->socket_fd) ||
3873 (p[poll_server+i+1].fd != urh->mhd.socket))
3875 urh_from_pollfd (urh,
3880 if ( (0 == urh->in_buffer_size) &&
3881 (0 == urh->out_buffer_size) &&
3882 (0 == urh->in_buffer_used) &&
3883 (0 == urh->out_buffer_used) )
3888 urh->clean_ready =
true;
3898 if ( (-1 != poll_listen) &&
3899 (0 != (p[poll_listen].revents & POLLIN)) )
3916 MHD_poll_listen_socket (
struct MHD_Daemon *daemon,
3921 unsigned int poll_count;
3936 p[poll_count].fd = ls;
3937 p[poll_count].events = POLLIN;
3938 p[poll_count].revents = 0;
3939 poll_listen = poll_count;
3942 if (MHD_ITC_IS_VALID_(daemon->
itc))
3944 p[poll_count].fd = MHD_itc_r_fd_ (daemon->
itc);
3945 p[poll_count].events = POLLIN;
3946 p[poll_count].revents = 0;
3947 poll_itc_idx = poll_count;
3958 if (0 == poll_count)
3960 if (MHD_sys_poll_(p,
3968 #ifdef HAVE_MESSAGES
3970 _(
"poll failed: %s\n"),
3975 if ( (-1 != poll_itc_idx) &&
3976 (0 != (p[poll_itc_idx].revents & POLLIN)) )
3977 MHD_itc_clear_ (daemon->
itc);
3982 if ( (-1 != poll_listen) &&
3983 (0 != (p[poll_listen].revents & POLLIN)) )
4005 return MHD_poll_all (daemon,
4007 return MHD_poll_listen_socket (daemon,
4017 #ifdef EPOLL_SUPPORT
4027 #define MAX_EVENTS 128
4030 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4040 is_urh_ready(
struct MHD_UpgradeResponseHandle *
const urh)
4042 const struct MHD_Connection *
const connection = urh->connection;
4044 if ( (0 == urh->in_buffer_size) &&
4045 (0 == urh->out_buffer_size) &&
4046 (0 == urh->in_buffer_used) &&
4047 (0 == urh->out_buffer_used) )
4053 (urh->in_buffer_used < urh->in_buffer_size) )
4056 (urh->out_buffer_used < urh->out_buffer_size) )
4059 (urh->out_buffer_used > 0) )
4062 (urh->in_buffer_used > 0) )
4077 run_epoll_for_upgrade (
struct MHD_Daemon *daemon)
4079 struct epoll_event events[MAX_EVENTS];
4081 struct MHD_UpgradeResponseHandle * pos;
4082 struct MHD_UpgradeResponseHandle *
prev;
4084 num_events = MAX_EVENTS;
4085 while (MAX_EVENTS == num_events)
4089 num_events = epoll_wait (daemon->epoll_upgrade_fd,
4093 if (-1 == num_events)
4098 #ifdef HAVE_MESSAGES
4100 _(
"Call to epoll_wait failed: %s\n"),
4105 for (i = 0; i < (
unsigned int) num_events; i++)
4107 struct UpgradeEpollHandle *
const ueh = events[i].data.ptr;
4108 struct MHD_UpgradeResponseHandle *
const urh = ueh->urh;
4109 bool new_err_state =
false;
4111 if (urh->clean_ready)
4115 if (0 != (events[i].events & EPOLLIN))
4117 if (0 != (events[i].events & EPOLLOUT))
4119 if (0 != (events[i].events & EPOLLHUP))
4123 (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
4129 new_err_state =
true;
4132 if (! urh->in_eready_list)
4134 if (new_err_state ||
4138 daemon->eready_urh_tail,
4140 urh->in_eready_list =
true;
4145 prev = daemon->eready_urh_tail;
4146 while (
NULL != (pos = prev))
4150 if (! is_urh_ready(pos))
4153 daemon->eready_urh_tail,
4155 pos->in_eready_list =
false;
4158 if ( (0 == pos->in_buffer_size) &&
4159 (0 == pos->out_buffer_size) &&
4160 (0 == pos->in_buffer_used) &&
4161 (0 == pos->out_buffer_used) )
4164 pos->clean_ready =
true;
4181 static const char *
const epoll_itc_marker =
"itc_marker";
4196 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4197 static const char *
const upgrade_marker =
"upgrade_ptr";
4201 struct epoll_event events[MAX_EVENTS];
4202 struct epoll_event event;
4208 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4209 int run_upgraded =
MHD_NO;
4212 if (-1 == daemon->epoll_fd)
4219 (! daemon->listen_socket_in_epoll) &&
4222 event.events = EPOLLIN;
4224 if (0 != epoll_ctl (daemon->epoll_fd,
4229 #ifdef HAVE_MESSAGES
4231 _(
"Call to epoll_ctl failed: %s\n"),
4236 daemon->listen_socket_in_epoll =
true;
4239 (daemon->listen_socket_in_epoll) )
4241 if ( (0 != epoll_ctl (daemon->epoll_fd,
4247 MHD_PANIC (
"Failed to remove listen FD from epoll set\n");
4248 daemon->listen_socket_in_epoll =
false;
4251 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4252 if ( (! daemon->upgrade_fd_in_epoll) &&
4253 (-1 != daemon->epoll_upgrade_fd) )
4255 event.events = EPOLLIN | EPOLLOUT;
4256 event.data.ptr = (
void *) upgrade_marker;
4257 if (0 != epoll_ctl (daemon->epoll_fd,
4259 daemon->epoll_upgrade_fd,
4262 #ifdef HAVE_MESSAGES
4264 _(
"Call to epoll_ctl failed: %s\n"),
4269 daemon->upgrade_fd_in_epoll =
true;
4272 if ( (daemon->listen_socket_in_epoll) &&
4279 if (0 != epoll_ctl (daemon->epoll_fd,
4283 MHD_PANIC (
_(
"Failed to remove listen FD from epoll set\n"));
4284 daemon->listen_socket_in_epoll =
false;
4297 timeout_ms = INT_MAX;
4299 timeout_ms = (int) timeout_ll;
4316 num_events = MAX_EVENTS;
4317 while (MAX_EVENTS == num_events)
4320 num_events = epoll_wait (daemon->epoll_fd,
4324 if (-1 == num_events)
4329 #ifdef HAVE_MESSAGES
4331 _(
"Call to epoll_wait failed: %s\n"),
4336 for (i=0;i<(
unsigned int) num_events;i++)
4340 if (
NULL == events[i].data.ptr)
4342 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4343 if (upgrade_marker == events[i].data.ptr)
4351 if (epoll_itc_marker == events[i].data.ptr)
4355 MHD_itc_clear_ (daemon->
itc);
4358 if (daemon == events[i].data.ptr)
4362 if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
4364 unsigned int series_length = 0;
4370 (series_length < 10) &&
4380 pos = events[i].data.ptr;
4382 if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
4388 daemon->eready_tail,
4395 if (0 != (events[i].events & EPOLLIN))
4403 daemon->eready_tail,
4408 if (0 != (events[i].events & EPOLLOUT))
4415 daemon->eready_tail,
4424 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4426 run_epoll_for_upgrade (daemon);
4430 prev = daemon->eready_tail;
4431 while (
NULL != (pos = prev))
4448 daemon->eready_tail,
4464 while (
NULL != (pos = prev))
4474 while (
NULL != (pos = prev))
4517 #ifdef EPOLL_SUPPORT
4520 MHD_epoll (daemon,
MHD_NO);
4553 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4572 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4578 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4586 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
4591 MHD_thread_init_(&(daemon->
pid));
4596 #ifdef EPOLL_SUPPORT
4612 return (MHD_THRD_RTRN_TYPE_)0;
4708 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4719 #ifdef HAVE_MESSAGES
4721 "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC\n");
4726 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4731 #ifdef EPOLL_SUPPORT
4736 if (0 != epoll_ctl (daemon->
worker_pool[i].epoll_fd,
4740 MHD_PANIC (
_(
"Failed to remove listen FD from epoll set\n"));
4741 daemon->
worker_pool[i].listen_socket_in_epoll =
false;
4748 MHD_PANIC (
_(
"Failed to signal quiesce via inter-thread communication channel"));
4753 #ifdef EPOLL_SUPPORT
4755 (-1 != daemon->epoll_fd) &&
4756 (daemon->listen_socket_in_epoll) )
4758 if ( (0 != epoll_ctl (daemon->epoll_fd,
4764 MHD_PANIC (
"Failed to remove listen FD from epoll set\n");
4765 daemon->listen_socket_in_epoll =
false;
4768 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
4769 (! MHD_itc_activate_ (daemon->
itc,
"q")) )
4770 MHD_PANIC (
_(
"failed to signal quiesce via inter-thread communication channel"));
4798 const struct sockaddr **servaddr,
4812 const struct sockaddr **servaddr,
4818 va_start (ap, servaddr);
4837 const struct sockaddr **servaddr,
4844 #ifdef HTTPS_SUPPORT
4847 #if GNUTLS_VERSION_MAJOR >= 3
4848 gnutls_certificate_retrieve_function2 *pgcrf;
4876 #ifdef HAVE_MESSAGES
4878 _(
"Warning: Too large timeout value, ignored.\n"));
4902 *servaddr = va_arg (ap,
4903 const struct sockaddr *);
4911 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4917 #ifdef HAVE_MESSAGES
4919 _(
"Warning: Zero size, specified for thread pool size, is ignored. "
4920 "Thread pool is not used.\n"));
4925 #ifdef HAVE_MESSAGES
4927 _(
"Warning: \"1\", specified for thread pool size, is ignored. "
4928 "Thread pool is not used.\n"));
4937 #ifdef HAVE_MESSAGES
4939 _(
"Specified thread pool size (%u) too big\n"),
4948 #ifdef HAVE_MESSAGES
4950 _(
"MHD_OPTION_THREAD_POOL_SIZE option is specified but "
4951 "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
4957 #ifdef HAVE_MESSAGES
4959 _(
"Both MHD_OPTION_THREAD_POOL_SIZE option and "
4960 "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
4967 #ifdef HTTPS_SUPPORT
4972 daemon->https_mem_key = pstr;
4973 #ifdef HAVE_MESSAGES
4976 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4984 daemon->https_key_password = pstr;
4985 #ifdef HAVE_MESSAGES
4988 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4996 daemon->https_mem_cert = pstr;
4997 #ifdef HAVE_MESSAGES
5000 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5008 daemon->https_mem_trust = pstr;
5009 #ifdef HAVE_MESSAGES
5012 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5017 daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
5025 gnutls_datum_t dhpar;
5027 if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
5029 #ifdef HAVE_MESSAGES
5031 _(
"Error initializing DH parameters\n"));
5035 dhpar.data = (
unsigned char *) pstr;
5036 dhpar.size = strlen (pstr);
5037 if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
5039 GNUTLS_X509_FMT_PEM) < 0)
5041 #ifdef HAVE_MESSAGES
5043 _(
"Bad Diffie-Hellman parameters format\n"));
5045 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
5048 daemon->have_dhparams =
true;
5050 #ifdef HAVE_MESSAGES
5053 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5062 gnutls_priority_deinit (daemon->priority_cache);
5063 ret = gnutls_priority_init (&daemon->priority_cache,
5066 if (GNUTLS_E_SUCCESS != ret)
5068 #ifdef HAVE_MESSAGES
5070 _(
"Setting priorities to `%s' failed: %s\n"),
5072 gnutls_strerror (ret));
5074 daemon->priority_cache =
NULL;
5078 #ifdef HAVE_MESSAGES
5081 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5086 #if GNUTLS_VERSION_MAJOR < 3
5087 #ifdef HAVE_MESSAGES
5089 _(
"MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n"));
5094 gnutls_certificate_retrieve_function2 *);
5096 daemon->cert_callback = pgcrf;
5098 #ifdef HAVE_MESSAGES
5100 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5106 #ifdef DAUTH_SUPPORT
5108 daemon->digest_auth_rand_size = va_arg (ap,
5110 daemon->digest_auth_random = va_arg (ap,
5114 daemon->nonce_nc_size = va_arg (ap,
5121 #ifdef HAVE_MESSAGES
5123 _(
"MHD_OPTION_LISTEN_SOCKET specified for daemon "
5124 "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
5133 #ifdef HAVE_MESSAGES
5134 daemon->custom_error_log = va_arg (ap,
5136 daemon->custom_error_log_cls = va_arg (ap,
5145 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5147 daemon->thread_stack_size = va_arg (ap,
5153 daemon->fastopen_queue_size = va_arg (ap,
5159 unsigned int) ? 1 : -1;
5167 #ifdef HAVE_MESSAGES
5172 _(
"Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
5173 "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n"));
5191 (
size_t) oa[i].
value,
5207 (
unsigned int) oa[i].value,
5212 #ifdef HTTPS_SUPPORT
5217 (gnutls_credentials_type_t) oa[i].value,
5267 (
void *) oa[i].value,
5277 (
size_t) oa[i].value,
5294 #ifdef HTTPS_SUPPORT
5296 #if GNUTLS_VERSION_MAJOR >= 3
5297 daemon->cred_callback = va_arg (ap,
5299 daemon->cred_callback_cls = va_arg (ap,
5304 _(
"MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3\n"),
5310 #ifdef HAVE_MESSAGES
5317 _(
"MHD HTTPS option %d passed to MHD compiled without HTTPS support\n"),
5323 _(
"Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n"),
5334 #ifdef EPOLL_SUPPORT
5340 #ifndef HAVE_MESSAGES
5344 #ifdef USE_EPOLL_CREATE1
5345 fd = epoll_create1 (EPOLL_CLOEXEC);
5347 fd = epoll_create (MAX_EVENTS);
5351 #ifdef HAVE_MESSAGES
5353 _(
"Call to epoll_create1 failed: %s\n"),
5358 #if !defined(USE_EPOLL_CREATE1)
5361 #ifdef HAVE_MESSAGES
5363 _(
"Failed to set noninheritable mode on epoll FD.\n"));
5381 setup_epoll_to_listen (
struct MHD_Daemon *daemon)
5383 struct epoll_event event;
5386 daemon->epoll_fd = setup_epoll_fd (daemon);
5387 if (-1 == daemon->epoll_fd)
5389 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
5392 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
5400 event.events = EPOLLIN;
5402 if (0 != epoll_ctl (daemon->epoll_fd,
5407 #ifdef HAVE_MESSAGES
5409 _(
"Call to epoll_ctl failed: %s\n"),
5414 daemon->listen_socket_in_epoll =
true;
5415 if (MHD_ITC_IS_VALID_(daemon->
itc))
5417 event.events = EPOLLIN;
5418 event.data.ptr = (
void *) epoll_itc_marker;
5419 if (0 != epoll_ctl (daemon->epoll_fd,
5421 MHD_itc_r_fd_ (daemon->
itc),
5424 #ifdef HAVE_MESSAGES
5426 _(
"Call to epoll_ctl failed: %s\n"),
5470 struct sockaddr_in servaddr4;
5472 struct sockaddr_in6 servaddr6;
5474 const struct sockaddr *servaddr =
NULL;
5476 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5493 #ifndef EPOLL_SUPPORT
5497 #ifndef HTTPS_SUPPORT
5501 #ifndef TCP_FASTOPEN
5507 #ifdef UPGRADE_SUPPORT
5517 if ( ((0 != (*pflags & MHD_USE_POLL)) && (0 != (*pflags & MHD_USE_EPOLL))) ||
5519 ((0 != (*pflags & MHD_USE_POLL)) &&
5521 ((0 != (*pflags &
MHD_USE_AUTO)) && (0 != (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL)))) )
5524 if (0 != (*pflags & MHD_USE_AUTO))
5538 #if defined(EPOLL_SUPPORT)
5540 #elif defined(HAVE_POLL)
5549 #if defined(EPOLL_SUPPORT)
5559 #ifdef EPOLL_SUPPORT
5560 daemon->epoll_fd = -1;
5561 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
5562 daemon->epoll_upgrade_fd = -1;
5566 #ifdef HTTPS_SUPPORT
5567 daemon->priority_cache =
NULL;
5568 if (0 != (*pflags & MHD_USE_TLS))
5570 gnutls_priority_init (&daemon->priority_cache,
5580 daemon->
port = port;
5591 MHD_itc_set_invalid_ (daemon->
itc);
5597 #ifdef HAVE_MESSAGES
5599 daemon->custom_error_log_cls = stderr;
5604 #ifdef HAVE_MESSAGES
5606 _(
"Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with "
5607 "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD "
5608 "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"));
5616 #ifdef HAVE_LISTEN_SHUTDOWN
5621 #ifdef DAUTH_SUPPORT
5622 daemon->digest_auth_rand_size = 0;
5623 daemon->digest_auth_random =
NULL;
5624 daemon->nonce_nc_size = 4;
5626 #ifdef HTTPS_SUPPORT
5627 if (0 != (*pflags & MHD_USE_TLS))
5629 daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
5638 #ifdef HTTPS_SUPPORT
5639 if ( (0 != (*pflags & MHD_USE_TLS)) &&
5640 (
NULL != daemon->priority_cache) )
5641 gnutls_priority_deinit (daemon->priority_cache);
5648 (0 != (daemon->
options & MHD_USE_THREAD_PER_CONNECTION)) )
5652 #ifdef HAVE_MESSAGES
5654 _(
"Using debug build of libmicrohttpd.\n") );
5659 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5664 if (! MHD_itc_init_ (daemon->
itc))
5666 #ifdef HAVE_MESSAGES
5668 _(
"Failed to create inter-thread communication channel: %s\n"),
5669 MHD_itc_last_strerror_ ());
5671 #ifdef HTTPS_SUPPORT
5672 if (
NULL != daemon->priority_cache)
5673 gnutls_priority_deinit (daemon->priority_cache);
5678 if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) &&
5682 #ifdef HAVE_MESSAGES
5684 _(
"file descriptor for inter-thread communication channel exceeds maximum value\n"));
5687 #ifdef HTTPS_SUPPORT
5688 if (
NULL != daemon->priority_cache)
5689 gnutls_priority_deinit (daemon->priority_cache);
5696 #ifdef DAUTH_SUPPORT
5697 if (daemon->nonce_nc_size > 0)
5699 if ( ( (
size_t) (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc))) /
5700 sizeof(
struct MHD_NonceNc) != daemon->nonce_nc_size)
5702 #ifdef HAVE_MESSAGES
5704 _(
"Specified value for NC_SIZE too large\n"));
5706 #ifdef HTTPS_SUPPORT
5707 if (0 != (*pflags & MHD_USE_TLS))
5708 gnutls_priority_deinit (daemon->priority_cache);
5713 daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc));
5714 if (
NULL == daemon->nnc)
5716 #ifdef HAVE_MESSAGES
5718 _(
"Failed to allocate memory for nonce-nc map: %s\n"),
5721 #ifdef HTTPS_SUPPORT
5722 if (0 != (*pflags & MHD_USE_TLS))
5723 gnutls_priority_deinit (daemon->priority_cache);
5730 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5731 if (! MHD_mutex_init_ (&daemon->nnc_lock))
5733 #ifdef HAVE_MESSAGES
5735 _(
"MHD failed to initialize nonce-nc mutex\n"));
5737 #ifdef HTTPS_SUPPORT
5738 if (0 != (*pflags & MHD_USE_TLS))
5739 gnutls_priority_deinit (daemon->priority_cache);
5749 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5750 if ( (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) &&
5753 #ifdef HAVE_MESSAGES
5755 _(
"MHD thread pooling only works with MHD_USE_INTERNAL_POLLING_THREAD\n"));
5767 domain = (*pflags &
MHD_USE_IPv6) ? PF_INET6 : PF_INET;
5769 if (*pflags & MHD_USE_IPv6)
5777 #ifdef HAVE_MESSAGES
5779 _(
"Failed to create socket for listening: %s\n"),
5788 #ifndef MHD_WINSOCK_SOCKETS
5793 if (0 > setsockopt (listen_fd,
5796 (
void*)&on,
sizeof (on)))
5798 #ifdef HAVE_MESSAGES
5800 _(
"setsockopt failed: %s\n"),
5809 #ifndef MHD_WINSOCK_SOCKETS
5812 if (0 > setsockopt (listen_fd,
5815 (
void*)&on,
sizeof (on)))
5817 #ifdef HAVE_MESSAGES
5819 _(
"setsockopt failed: %s\n"),
5829 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT)
5830 if (0 > setsockopt (listen_fd,
5832 #ifndef MHD_WINSOCK_SOCKETS
5840 #ifdef HAVE_MESSAGES
5842 _(
"setsockopt failed: %s\n"),
5850 #ifdef HAVE_MESSAGES
5852 _(
"Cannot allow listening address reuse: SO_REUSEPORT not defined\n"));
5865 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \
5866 (defined(__sun) && defined(SO_EXCLBIND))
5867 if (0 > setsockopt (listen_fd,
5869 #ifdef SO_EXCLUSIVEADDRUSE
5870 SO_EXCLUSIVEADDRUSE,
5877 #ifdef HAVE_MESSAGES
5879 _(
"setsockopt failed: %s\n"),
5884 #elif defined(MHD_WINSOCK_SOCKETS)
5885 #ifdef HAVE_MESSAGES
5887 _(
"Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n"));
5895 if (0 != (*pflags & MHD_USE_IPv6))
5896 addrlen =
sizeof (
struct sockaddr_in6);
5899 addrlen =
sizeof (
struct sockaddr_in);
5900 if (
NULL == servaddr)
5903 if (0 != (*pflags & MHD_USE_IPv6))
5905 #ifdef IN6ADDR_ANY_INIT
5906 static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
5910 sizeof (
struct sockaddr_in6));
5911 servaddr6.sin6_family = AF_INET6;
5912 servaddr6.sin6_port = htons (port);
5913 #ifdef IN6ADDR_ANY_INIT
5914 servaddr6.sin6_addr = static_in6any;
5916 #if HAVE_SOCKADDR_IN_SIN_LEN
5917 servaddr6.sin6_len =
sizeof (
struct sockaddr_in6);
5919 servaddr = (
struct sockaddr *) &servaddr6;
5926 sizeof (
struct sockaddr_in));
5927 servaddr4.sin_family = AF_INET;
5928 servaddr4.sin_port = htons (port);
5929 if (0 != INADDR_ANY)
5930 servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
5931 #if HAVE_SOCKADDR_IN_SIN_LEN
5932 servaddr4.sin_len =
sizeof (
struct sockaddr_in);
5934 servaddr = (
struct sockaddr *) &servaddr4;
5939 if (0 != (*pflags & MHD_USE_IPv6))
5949 if (0 > setsockopt (listen_fd,
5950 IPPROTO_IPV6, IPV6_V6ONLY,
5951 (
const void *) &v6_only,
5954 #ifdef HAVE_MESSAGES
5956 _(
"setsockopt failed: %s\n"),
5963 if (-1 == bind (listen_fd, servaddr, addrlen))
5965 #ifdef HAVE_MESSAGES
5967 _(
"Failed to bind to port %u: %s\n"),
5968 (
unsigned int) port,
5975 if (0 != (*pflags & MHD_USE_TCP_FASTOPEN))
5977 if (0 == daemon->fastopen_queue_size)
5978 daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
5979 if (0 != setsockopt (listen_fd,
5982 (
const void*)&daemon->fastopen_queue_size,
5983 sizeof (daemon->fastopen_queue_size)))
5985 #ifdef HAVE_MESSAGES
5987 _(
"setsockopt failed: %s\n"),
5993 if (listen (listen_fd,
5996 #ifdef HAVE_MESSAGES
5998 _(
"Failed to listen for connections: %s\n"),
6010 if ( (0 == daemon->
port) &&
6011 (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
6013 struct sockaddr_storage servaddr;
6017 sizeof (
struct sockaddr_storage));
6018 addrlen =
sizeof (servaddr);
6019 if (0 != getsockname (listen_fd,
6020 (
struct sockaddr *) &servaddr,
6023 #ifdef HAVE_MESSAGES
6025 _(
"Failed to get listen port number: %s\n"),
6029 #ifdef MHD_POSIX_SOCKETS
6030 else if (
sizeof (servaddr) < addrlen)
6033 #ifdef HAVE_MESSAGES
6035 _(
"Failed to get listen port number (`struct sockaddr_storage` too small!?)\n"));
6041 switch (servaddr.ss_family)
6045 struct sockaddr_in *s4 = (
struct sockaddr_in *) &servaddr;
6047 daemon->
port = ntohs (s4->sin_port);
6053 struct sockaddr_in6 *s6 = (
struct sockaddr_in6 *) &servaddr;
6055 daemon->
port = ntohs(s6->sin6_port);
6066 #ifdef HAVE_MESSAGES
6068 _(
"Unknown address family!\n"));
6079 #ifdef HAVE_MESSAGES
6081 _(
"Failed to set nonblocking mode on listening socket: %s\n"),
6084 if (0 != (*pflags & MHD_USE_EPOLL)
6085 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6100 (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL)) ) )
6102 #ifdef HAVE_MESSAGES
6104 _(
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
6112 #ifdef EPOLL_SUPPORT
6113 if ( (0 != (*pflags & MHD_USE_EPOLL))
6114 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6119 if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
6121 #ifdef HAVE_MESSAGES
6123 _(
"Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
6127 if (
MHD_YES != setup_epoll_to_listen (daemon))
6132 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6135 #ifdef HAVE_MESSAGES
6137 _(
"MHD failed to initialize IP connection limit mutex\n"));
6148 #ifdef HAVE_MESSAGES
6150 _(
"MHD failed to initialize IP connection limit mutex\n"));
6152 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6162 #ifdef HTTPS_SUPPORT
6164 if ( (0 != (*pflags & MHD_USE_TLS)) &&
6165 (0 != MHD_TLS_init (daemon)) )
6167 #ifdef HAVE_MESSAGES
6169 _(
"Failed to initialize TLS support\n"));
6173 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6181 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6182 if ( (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) &&
6183 (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
6188 (*pflags & MHD_USE_THREAD_PER_CONNECTION) ?
6189 "MHD-listen" :
"MHD-single",
6190 daemon->thread_stack_size,
6194 #ifdef HAVE_MESSAGES
6196 _(
"Failed to create listen thread: %s\n"),
6230 memcpy (d, daemon,
sizeof (
struct MHD_Daemon));
6238 if (0 != (*pflags & MHD_USE_ITC))
6240 if (! MHD_itc_init_ (d->
itc))
6242 #ifdef HAVE_MESSAGES
6244 _(
"Failed to create worker inter-thread communication channel: %s\n"),
6245 MHD_itc_last_strerror_() );
6249 if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) &&
6253 #ifdef HAVE_MESSAGES
6255 _(
"File descriptor for worker inter-thread communication channel exceeds maximum value\n"));
6262 MHD_itc_set_invalid_ (d->
itc);
6268 if (i < leftover_conns)
6270 #ifdef EPOLL_SUPPORT
6271 if ( (0 != (*pflags & MHD_USE_EPOLL)) &&
6272 (
MHD_YES != setup_epoll_to_listen (d)) )
6278 #ifdef HAVE_MESSAGES
6280 _(
"MHD failed to initialize cleanup connection mutex\n"));
6288 daemon->thread_stack_size,
6292 #ifdef HAVE_MESSAGES
6294 _(
"Failed to create pool thread: %s\n"),
6306 #ifdef HTTPS_SUPPORT
6309 daemon->https_key_password =
NULL;
6314 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6342 #ifdef EPOLL_SUPPORT
6343 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6344 if (daemon->upgrade_fd_in_epoll)
6346 if (0 != epoll_ctl (daemon->epoll_fd,
6348 daemon->epoll_upgrade_fd,
6350 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
6351 daemon->upgrade_fd_in_epoll =
false;
6354 if (-1 != daemon->epoll_fd)
6355 close (daemon->epoll_fd);
6356 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6357 if (-1 != daemon->epoll_upgrade_fd)
6358 close (daemon->epoll_upgrade_fd);
6361 #ifdef DAUTH_SUPPORT
6363 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6367 #ifdef HTTPS_SUPPORT
6368 if (0 != (*pflags & MHD_USE_TLS))
6369 gnutls_priority_deinit (daemon->priority_cache);
6371 if (MHD_ITC_IS_VALID_(daemon->
itc))
6391 #ifdef UPGRADE_SUPPORT
6394 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6395 struct MHD_UpgradeResponseHandle *urh;
6396 struct MHD_UpgradeResponseHandle *urhn;
6399 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6405 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
6412 urh->clean_ready =
true;
6429 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6432 #ifdef UPGRADE_SUPPORT
6438 while (
NULL != susp)
6440 if (
NULL == susp->urh)
6441 MHD_PANIC (
_(
"MHD_stop_daemon() called while we have suspended connections.\n"));
6442 #ifdef HTTPS_SUPPORT
6443 else if (used_tls &&
6445 (! susp->urh->clean_ready) )
6446 shutdown (susp->urh->app.socket,
6451 #ifdef HAVE_MESSAGES
6452 if (! susp->urh->was_closed)
6454 _(
"Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
6456 susp->urh->was_closed =
true;
6472 MHD_PANIC (
_(
"MHD_stop_daemon() called while we have suspended connections.\n"));
6477 #if MHD_WINSOCK_SOCKETS
6479 (MHD_ITC_IS_VALID_(daemon->
itc)) &&
6480 (! MHD_itc_activate_ (daemon->
itc,
"e")) )
6481 MHD_PANIC (
_(
"Failed to signal shutdown via inter-thread communication channel"));
6485 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6495 if (! MHD_join_thread_ (pos->
pid.handle))
6510 #ifdef UPGRADE_SUPPORT
6525 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6546 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6559 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6573 MHD_PANIC (
_(
"Failed to signal shutdown via inter-thread communication channel."));
6578 #ifdef HAVE_LISTEN_SHUTDOWN
6581 (void) shutdown (fd,
6591 #ifdef EPOLL_SUPPORT
6593 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6601 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6606 if (MHD_ITC_IS_VALID_ (daemon->
itc))
6608 if (! MHD_itc_activate_ (daemon->
itc,
6610 MHD_PANIC (
_(
"Failed to signal shutdown via inter-thread communication channel"));
6614 #ifdef HAVE_LISTEN_SHUTDOWN
6618 (void) shutdown (fd,
6626 if (! MHD_join_thread_ (daemon->
pid.handle))
6638 if (MHD_ITC_IS_VALID_ (daemon->
itc))
6641 #ifdef EPOLL_SUPPORT
6643 (-1 != daemon->epoll_fd) )
6645 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6647 (-1 != daemon->epoll_upgrade_fd) )
6652 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6665 #ifdef HTTPS_SUPPORT
6666 if (daemon->have_dhparams)
6668 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
6669 daemon->have_dhparams =
false;
6673 gnutls_priority_deinit (daemon->priority_cache);
6674 if (daemon->x509_cred)
6675 gnutls_certificate_free_credentials (daemon->x509_cred);
6676 if (daemon->psk_cred)
6677 gnutls_psk_free_server_credentials (daemon->psk_cred);
6681 #ifdef DAUTH_SUPPORT
6683 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6687 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6721 #ifdef EPOLL_SUPPORT
6732 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6790 #ifdef PACKAGE_VERSION
6791 return PACKAGE_VERSION;
6793 static char ver[12] =
"\0\0\0\0\0\0\0\0\0\0\0";
6796 int res = MHD_snprintf_(ver,
6802 if (0 >= res ||
sizeof(ver) <= res)
6827 #ifdef HAVE_MESSAGES
6833 #ifdef HTTPS_SUPPORT
6839 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3
6851 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
6863 #ifdef EPOLL_SUPPORT
6869 #ifdef HAVE_LISTEN_SHUTDOWN
6875 #ifdef _MHD_ITC_SOCKETPAIR
6887 #ifdef BAUTH_SUPPORT
6893 #ifdef DAUTH_SUPPORT
6899 #ifdef HAVE_POSTPROCESSOR
6905 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111
6911 #if defined(HAVE_PREAD64) || defined(_WIN32)
6913 #elif defined(HAVE_PREAD)
6914 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
6915 #elif defined(HAVE_LSEEK64)
6918 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
6921 #if defined(MHD_USE_THREAD_NAME_)
6927 #if defined(UPGRADE_SUPPORT)
6933 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32)
6939 #ifdef MHD_USE_GETSOCKNAME
6945 #if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || defined (MSG_NOSIGNAL)
6951 #ifdef _MHD_HAVE_SENDFILE
6957 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6968 #ifdef MHD_HTTPS_REQUIRE_GRYPT
6969 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600
6970 #if defined(MHD_USE_POSIX_THREADS)
6971 GCRY_THREAD_OPTION_PTHREAD_IMPL;
6972 #elif defined(MHD_W32_MUTEX_)
6975 gcry_w32_mutex_init (
void **ppmtx)
6977 *ppmtx = malloc (
sizeof (MHD_mutex_));
6981 if (!MHD_mutex_init_ ((MHD_mutex_*)*ppmtx))
6993 gcry_w32_mutex_destroy (
void **ppmtx)
6995 int res = (MHD_mutex_destroy_ ((MHD_mutex_*)*ppmtx)) ? 0 : EINVAL;
7002 gcry_w32_mutex_lock (
void **ppmtx)
7004 return MHD_mutex_lock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
7009 gcry_w32_mutex_unlock (
void **ppmtx)
7011 return MHD_mutex_unlock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
7015 static struct gcry_thread_cbs gcry_threads_w32 = {
7016 (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
7017 NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
7018 gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
7031 #if defined(_WIN32) && ! defined(__CYGWIN__)
7038 #if defined(_WIN32) && ! defined(__CYGWIN__)
7039 if (0 != WSAStartup(MAKEWORD(2, 2), &wsd))
7040 MHD_PANIC (
_(
"Failed to initialize winsock\n"));
7041 mhd_winsock_inited_ = 1;
7042 if (2 != LOBYTE(wsd.wVersion) && 2 != HIBYTE(wsd.wVersion))
7043 MHD_PANIC (
_(
"Winsock version 2.2 is not available\n"));
7045 #ifdef HTTPS_SUPPORT
7046 #ifdef MHD_HTTPS_REQUIRE_GRYPT
7047 #if GCRYPT_VERSION_NUMBER < 0x010600
7048 #if defined(MHD_USE_POSIX_THREADS)
7049 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7050 &gcry_threads_pthread))
7051 MHD_PANIC (
_(
"Failed to initialise multithreading in libgcrypt\n"));
7052 #elif defined(MHD_W32_MUTEX_)
7053 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7055 MHD_PANIC (
_(
"Failed to initialise multithreading in libgcrypt\n"));
7057 gcry_check_version (
NULL);
7059 if (
NULL == gcry_check_version (
"1.6.0"))
7060 MHD_PANIC (
_(
"libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n"));
7063 gnutls_global_init ();
7066 #ifdef HAVE_FREEBSD_SENDFILE
7067 MHD_conn_init_static_ ();
7075 #ifdef HTTPS_SUPPORT
7076 gnutls_global_deinit ();
7078 #if defined(_WIN32) && ! defined(__CYGWIN__)
7079 if (mhd_winsock_inited_)
7085 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
#define MHD_send_(s, b, l)
unsigned int per_ip_connection_limit
void * unescape_callback_cls
int MHD_ip_limit_add(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
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
DLL_remove(daemon->suspended_connections_head, daemon->suspended_connections_tail, pos)
_MHD_EXTERN union MHD_DaemonInfo * MHD_get_daemon_info(struct MHD_Daemon *daemon, enum MHD_DaemonInfoType info_type,...)
void MHD_update_last_activity_(struct MHD_Connection *connection)
#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)
MHD_mutex_lock_chk_ & daemon
enum MHD_ConnectionEventLoopInfo event_loop_info
#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_PanicCallback mhd_panic
_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)
void MHD_check_global_init_(void)
_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
void(* MHD_RequestCompletedCallback)(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
void *(* LogCallback)(void *cls, const char *uri, struct MHD_Connection *con)
struct MHD_Connection * prev
struct MHD_Connection * manual_timeout_head
#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)
void(* MHD_NotifyConnectionCallback)(void *cls, struct MHD_Connection *connection, void **socket_context, enum MHD_ConnectionNotificationCode toe)
MHD_AccessHandlerCallback default_handler
static void MHD_ip_count_lock(struct MHD_Daemon *daemon)
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)
#define MHD_TEST_ALLOW_SUSPEND_RESUME
int listening_address_reuse
MHD_mutex_ per_ip_connection_mutex
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)
int(* MHD_PskServerCredentialsCallback)(void *cls, const struct MHD_Connection *connection, const char *username, void **psk, size_t *psk_size)
#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)
_MHD_EXTERN void MHD_suspend_connection(struct MHD_Connection *connection)
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode rtc)
time_t connection_timeout
int(* MHD_AcceptPolicyCallback)(void *cls, const struct sockaddr *addr, socklen_t addrlen)
volatile unsigned int global_init_count
#define MHD_SCKT_ERR_IS_(err, code)
Methods for managing connections.
size_t(* UnescapeCallback)(void *cls, struct MHD_Connection *conn, char *uri)
struct MHD_Daemon * master
#define EDLL_remove(head, tail, element)
struct MHD_Connection * manual_timeout_tail
struct MHD_Connection * prev
#define TIMEVAL_TV_SEC_MAX
#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
void internal_suspend_connection_(struct MHD_Connection *connection)
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)
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)
#define MHD_connection_finish_forward_(conn)
struct MHD_Connection * normal_timeout_tail
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)
void * notify_connection_cls
void(* VfprintfFunctionPointerType)(void *cls, const char *format, va_list va)
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ MHD_polling_thread(void *cls)
#define XDLL_insert(head, tail, element)
#define MHD_UNSIGNED_LONG_LONG_PRINTF
_MHD_EXTERN int MHD_is_feature_supported(enum MHD_FEATURE feature)
struct MHD_Connection * suspended_connections_head
void * per_ip_connection_count
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)
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)
_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.
void(* MHD_LogCallback)(void *cls, const char *fm, va_list ap)
_MHD_EXTERN void MHD_resume_connection(struct MHD_Connection *connection)
void(* MHD_PanicCallback)(void *cls, const char *file, unsigned int line, const char *reason)
#define MAYBE_SOCK_CLOEXEC