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_
232 vfprintf ((FILE*) cls, fm, ap);
234 fflush ((FILE*) cls);
293 struct in6_addr ipv6;
312 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
328 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
351 offsetof (
struct MHD_IPCount,
367 struct MHD_IPCount *key)
374 if (
sizeof (
struct sockaddr_in) == addrlen)
376 const struct sockaddr_in *addr4 = (
const struct sockaddr_in*) addr;
378 key->family = AF_INET;
379 memcpy (&key->addr.ipv4,
381 sizeof(addr4->sin_addr));
387 if (
sizeof (
struct sockaddr_in6) == addrlen)
389 const struct sockaddr_in6 *addr6 = (
const struct sockaddr_in6*) addr;
391 key->family = AF_INET6;
392 memcpy (&key->addr.ipv6,
394 sizeof(addr6->sin6_addr));
417 const struct sockaddr *addr,
420 struct MHD_IPCount *key;
430 if (
NULL == (key = malloc (
sizeof(*key))))
451 _ (
"Failed to add IP connection count node\n"));
461 key = (
struct MHD_IPCount *) node;
483 const struct sockaddr *addr,
486 struct MHD_IPCount search_key;
487 struct MHD_IPCount *found_key;
509 MHD_PANIC (
_ (
"Failed to find previously-added IP address\n"));
511 found_key = (
struct MHD_IPCount *) *nodep;
513 if (0 == found_key->count)
515 MHD_PANIC (
_ (
"Previously-added IP address had counter of zero\n"));
518 if (0 == --found_key->count)
538 MHD_init_daemon_certificate (
struct MHD_Daemon *daemon)
544 #if GNUTLS_VERSION_MAJOR >= 3
545 if (
NULL != daemon->cert_callback)
547 gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
548 daemon->cert_callback);
551 #if GNUTLS_VERSION_NUMBER >= 0x030603
552 else if (
NULL != daemon->cert_callback2)
554 gnutls_certificate_set_retrieve_function3 (daemon->x509_cred,
555 daemon->cert_callback2);
559 if (
NULL != daemon->https_mem_trust)
562 paramlen = strlen (daemon->https_mem_trust);
567 "Too long trust certificate\n");
571 cert.data = (
unsigned char *) daemon->https_mem_trust;
572 cert.size = (
unsigned int) paramlen;
573 if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred,
575 GNUTLS_X509_FMT_PEM) < 0)
579 "Bad trust certificate format\n");
585 if (daemon->have_dhparams)
587 gnutls_certificate_set_dh_params (daemon->x509_cred,
588 daemon->https_mem_dhparams);
591 if ( (
NULL != daemon->https_mem_cert) &&
592 (
NULL != daemon->https_mem_key) )
597 param1len = strlen (daemon->https_mem_key);
598 param2len = strlen (daemon->https_mem_cert);
604 "Too long key or certificate\n");
608 key.data = (
unsigned char *) daemon->https_mem_key;
609 key.size = (
unsigned int) param1len;
610 cert.data = (
unsigned char *) daemon->https_mem_cert;
611 cert.size = (
unsigned int) param2len;
613 if (
NULL != daemon->https_key_password)
615 #if GNUTLS_VERSION_NUMBER >= 0x030111
616 ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
620 daemon->https_key_password,
625 _ (
"Failed to setup x509 certificate/key: pre 3.X.X version " \
626 "of GnuTLS does not support setting key password"));
632 ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
635 GNUTLS_X509_FMT_PEM);
639 "GnuTLS failed to setup x509 certificate/key: %s\n",
640 gnutls_strerror (ret));
644 #if GNUTLS_VERSION_MAJOR >= 3
645 if (
NULL != daemon->cert_callback)
648 #if GNUTLS_VERSION_NUMBER >= 0x030603
649 else if (
NULL != daemon->cert_callback2)
654 "You need to specify a certificate and key location\n");
669 switch (daemon->cred_type)
671 case GNUTLS_CRD_CERTIFICATE:
673 gnutls_certificate_allocate_credentials (&daemon->x509_cred))
674 return GNUTLS_E_MEMORY_ERROR;
675 return MHD_init_daemon_certificate (daemon);
678 gnutls_psk_allocate_server_credentials (&daemon->psk_cred))
679 return GNUTLS_E_MEMORY_ERROR;
684 _ (
"Error: invalid credentials type %d specified.\n"),
729 fd_set *write_fd_set,
730 fd_set *except_fd_set,
742 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
756 urh_to_fdset (
struct MHD_UpgradeResponseHandle *urh,
761 unsigned int fd_setsize)
763 const MHD_socket conn_sckt = urh->connection->socket_fd;
771 if ( (urh->in_buffer_used < urh->in_buffer_size) &&
777 if ( (0 != urh->out_buffer_used) &&
786 ((0 != urh->in_buffer_size) ||
787 (0 != urh->out_buffer_size) ||
788 (0 != urh->out_buffer_used)))
796 if ( (urh->out_buffer_used < urh->out_buffer_size) &&
802 if ( (0 != urh->in_buffer_used) &&
811 ((0 != urh->out_buffer_size) ||
812 (0 != urh->in_buffer_size) ||
813 (0 != urh->in_buffer_used)))
834 urh_from_fdset (
struct MHD_UpgradeResponseHandle *urh,
839 const MHD_socket conn_sckt = urh->connection->socket_fd;
848 if (FD_ISSET (conn_sckt, rs))
850 if (FD_ISSET (conn_sckt, ws))
852 if (FD_ISSET (conn_sckt, es))
857 if (FD_ISSET (mhd_sckt, rs))
859 if (FD_ISSET (mhd_sckt, ws))
861 if (FD_ISSET (mhd_sckt, es))
878 urh_update_pollfd (
struct MHD_UpgradeResponseHandle *urh,
884 if (urh->in_buffer_used < urh->in_buffer_size)
885 p[0].events |= POLLIN;
886 if (0 != urh->out_buffer_used)
887 p[0].events |= POLLOUT;
892 ((0 != urh->in_buffer_size) ||
893 (0 != urh->out_buffer_size) ||
894 (0 != urh->out_buffer_used)))
895 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
897 if (urh->out_buffer_used < urh->out_buffer_size)
898 p[1].events |= POLLIN;
899 if (0 != urh->in_buffer_used)
900 p[1].events |= POLLOUT;
905 ((0 != urh->out_buffer_size) ||
906 (0 != urh->in_buffer_size) ||
907 (0 != urh->in_buffer_used)))
908 p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
919 urh_to_pollfd (
struct MHD_UpgradeResponseHandle *urh,
922 p[0].fd = urh->connection->socket_fd;
923 p[1].fd = urh->mhd.socket;
924 urh_update_pollfd (urh,
935 urh_from_pollfd (
struct MHD_UpgradeResponseHandle *urh,
942 if (0 != (p[0].revents & POLLIN))
944 if (0 != (p[0].revents & POLLOUT))
946 if (0 != (p[0].revents & POLLHUP))
948 if (0 != (p[0].revents & MHD_POLL_REVENTS_ERRROR))
950 if (0 != (p[1].revents & POLLIN))
952 if (0 != (p[1].revents & POLLOUT))
954 if (0 != (p[1].revents & POLLHUP))
956 if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
982 fd_set *write_fd_set,
983 fd_set *except_fd_set,
985 unsigned int fd_setsize)
1021 #ifdef MHD_POSIX_SOCKETS
1034 #ifdef MHD_POSIX_SOCKETS
1042 if ( (
NULL == except_fd_set) ||
1054 #ifdef MHD_WINSOCK_SOCKETS
1067 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
1069 struct MHD_UpgradeResponseHandle *urh;
1071 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
1085 #ifdef HAVE_MESSAGES
1088 _ (
"Maximum socket in select set: %d\n"),
1130 fd_set *read_fd_set,
1131 fd_set *write_fd_set,
1132 fd_set *except_fd_set,
1134 unsigned int fd_setsize)
1138 if ( (
NULL == daemon) ||
1139 (
NULL == read_fd_set) ||
1140 (
NULL == write_fd_set) ||
1145 if (
NULL == except_fd_set)
1147 #ifdef HAVE_MESSAGES
1149 _ (
"MHD_get_fdset2() called with except_fd_set "
1150 "set to NULL. Such behavior is unsupported.\n"));
1153 except_fd_set = &es;
1156 #ifdef EPOLL_SUPPORT
1201 bool states_info_processed =
false;
1205 #ifdef HTTPS_SUPPORT
1216 states_info_processed =
true;
1225 states_info_processed =
true;
1235 if (! states_info_processed)
1280 #ifdef HTTPS_SUPPORT
1290 #ifdef UPGRADE_SUPPORT
1301 struct MHD_UpgradeResponseHandle *urh = connection->urh;
1305 #ifdef HTTPS_SUPPORT
1309 gnutls_bye (connection->tls_session,
1318 connection->urh =
NULL;
1326 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
1336 process_urh (
struct MHD_UpgradeResponseHandle *urh)
1351 #ifdef HAVE_MESSAGES
1352 if (! urh->was_closed)
1356 "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
1359 urh->was_closed =
true;
1361 was_closed = urh->was_closed;
1366 if (0 < urh->in_buffer_used)
1368 #ifdef HAVE_MESSAGES
1371 "Failed to forward to application "
1373 " bytes of data received from remote side: application shut down socket\n"),
1382 if (0 != urh->out_buffer_size)
1385 urh->in_buffer_used = 0;
1389 urh->in_buffer_size = 0;
1409 (urh->in_buffer_used < urh->in_buffer_size) )
1414 buf_size = urh->in_buffer_size - urh->in_buffer_used;
1419 res = gnutls_record_recv (connection->tls_session,
1420 &urh->in_buffer[urh->in_buffer_used],
1424 if (GNUTLS_E_INTERRUPTED != res)
1427 if (GNUTLS_E_AGAIN != res)
1432 urh->in_buffer_size = 0;
1438 urh->in_buffer_used += res;
1439 if (buf_size > (
size_t) res)
1441 else if (0 < gnutls_record_check_pending (connection->tls_session))
1450 urh->in_buffer_size = 0;
1458 (urh->out_buffer_used < urh->out_buffer_size) )
1463 buf_size = urh->out_buffer_size - urh->out_buffer_used;
1468 &urh->out_buffer[urh->out_buffer_used],
1487 urh->out_buffer_size = 0;
1493 urh->out_buffer_used += res;
1494 if (buf_size > (
size_t) res)
1504 urh->out_buffer_size = 0;
1512 (urh->out_buffer_used > 0) )
1517 data_size = urh->out_buffer_used;
1521 res = gnutls_record_send (connection->tls_session,
1526 if (GNUTLS_E_INTERRUPTED != res)
1529 if (GNUTLS_E_AGAIN != res)
1533 #ifdef HAVE_MESSAGES
1536 "Failed to forward to remote client "
1538 " bytes of data received from application: %s\n"),
1540 gnutls_strerror (res));
1543 urh->out_buffer_used = 0;
1545 urh->out_buffer_size = 0;
1552 const size_t next_out_buffer_used = urh->out_buffer_used - res;
1553 if (0 != next_out_buffer_used)
1555 memmove (urh->out_buffer,
1556 &urh->out_buffer[res],
1557 next_out_buffer_used);
1558 if (data_size > (
size_t) res)
1561 urh->out_buffer_used = next_out_buffer_used;
1563 if ( (0 == urh->out_buffer_used) &&
1571 urh->out_buffer_size = 0;
1580 (urh->in_buffer_used > 0) )
1585 data_size = urh->in_buffer_used;
1603 #ifdef HAVE_MESSAGES
1606 "Failed to forward to application "
1608 " bytes of data received from remote side: %s\n"),
1613 urh->in_buffer_used = 0;
1615 urh->in_buffer_size = 0;
1623 const size_t next_in_buffer_used = urh->in_buffer_used - res;
1624 if (0 != next_in_buffer_used)
1626 memmove (urh->in_buffer,
1627 &urh->in_buffer[res],
1628 next_in_buffer_used);
1629 if (data_size > (
size_t) res)
1632 urh->in_buffer_used = next_in_buffer_used;
1634 if ( (0 == urh->in_buffer_used) &&
1640 urh->in_buffer_size = 0;
1649 (urh->in_buffer_used < urh->in_buffer_size) &&
1654 ( (0 != urh->out_buffer_size) ||
1655 (0 != urh->out_buffer_used) ) )
1658 #ifdef HAVE_MESSAGES
1659 if (0 < urh->out_buffer_used)
1662 "Failed to forward to remote client "
1664 " bytes of data received from application: daemon shut down\n"),
1668 urh->out_buffer_used = 0;
1672 urh->out_buffer_size = 0;
1680 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1681 #ifdef UPGRADE_SUPPORT
1693 #ifdef HTTPS_SUPPORT
1694 struct MHD_UpgradeResponseHandle *urh = con->urh;
1703 while ( (0 != urh->in_buffer_size) ||
1704 (0 != urh->out_buffer_size) ||
1705 (0 != urh->in_buffer_used) ||
1706 (0 != urh->out_buffer_used) )
1720 result = urh_to_fdset (urh,
1728 #ifdef HAVE_MESSAGES
1730 _ (
"Error preparing select\n"));
1740 (urh->in_buffer_used < urh->in_buffer_size))
1762 #ifdef HAVE_MESSAGES
1764 _ (
"Error during select (%d): `%s'\n"),
1770 urh_from_fdset (urh,
1785 p[0].fd = urh->connection->socket_fd;
1786 p[1].fd = urh->mhd.socket;
1788 while ( (0 != urh->in_buffer_size) ||
1789 (0 != urh->out_buffer_size) ||
1790 (0 != urh->in_buffer_used) ||
1791 (0 != urh->out_buffer_used) )
1795 urh_update_pollfd (urh, p);
1798 (urh->in_buffer_used < urh->in_buffer_size))
1803 if (MHD_sys_poll_ (p,
1811 #ifdef HAVE_MESSAGES
1813 _ (
"Error during poll: `%s'\n"),
1818 urh_from_pollfd (urh,
1844 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
1855 struct timeval *tvp;
1861 #define EXTRA_SLOTS 1
1863 #define EXTRA_SLOTS 0
1872 const bool use_poll = 0;
1874 bool was_suspended =
false;
1875 MHD_thread_init_ (&(con->
pid));
1881 #ifdef UPGRADE_SUPPORT
1882 struct MHD_UpgradeResponseHandle *
const urh = con->urh;
1884 static const void *
const urh =
NULL;
1891 was_suspended =
true;
1900 #ifdef HAVE_MESSAGES
1902 _ (
"Failed to add FD to fd_set\n"));
1916 #ifdef HAVE_MESSAGES
1918 _ (
"Error during select (%d): `%s'\n"),
1928 p[0].events = POLLIN;
1929 p[0].fd = MHD_itc_r_fd_ (daemon->
itc);
1931 if (0 > MHD_sys_poll_ (p,
1937 #ifdef HAVE_MESSAGES
1939 _ (
"Error during poll: `%s'\n"),
1946 MHD_itc_clear_ (daemon->
itc);
1955 was_suspended =
false;
1961 #ifdef HTTPS_SUPPORT
1973 if ( (
NULL == tvp) &&
1981 const time_t seconds_left = timeout - (now - con->
last_activity);
1982 #if ! defined(_WIN32) || defined(__CYGWIN__)
1983 tv.tv_sec = seconds_left;
1997 bool err_state =
false;
2031 if (MHD_ITC_IS_VALID_ (daemon->
itc) )
2042 #ifdef HAVE_MESSAGES
2044 _ (
"Failed to add FD to fd_set\n"));
2060 #ifdef HAVE_MESSAGES
2062 _ (
"Error during select (%d): `%s'\n"),
2071 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
2072 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
2074 MHD_itc_clear_ (daemon->
itc);
2097 p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
2100 p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
2103 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
2111 if (MHD_ITC_IS_VALID_ (daemon->
itc))
2113 p[1].events |= POLLIN;
2114 p[1].fd = MHD_itc_r_fd_ (daemon->
itc);
2119 if (MHD_sys_poll_ (p,
2125 (
NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
2129 #ifdef HAVE_MESSAGES
2131 _ (
"Error during poll: `%s'\n"),
2139 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
2140 (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
2141 MHD_itc_clear_ (daemon->
itc);
2145 (0 != (p[0].revents & POLLIN)),
2146 (0 != (p[0].revents & POLLOUT)),
2147 (0 != (p[0].revents & (POLLERR
2148 | MHD_POLL_REVENTS_ERR_DISC))) ))
2152 #ifdef UPGRADE_SUPPORT
2153 if (MHD_CONNECTION_UPGRADE == con->
state)
2165 thread_main_connection_upgrade (con);
2169 con->urh->clean_ready =
true;
2177 return (MHD_THRD_RTRN_TYPE_) 0;
2182 #ifdef HAVE_MESSAGES
2184 _ (
"Processing thread terminating. Closing connection\n"));
2208 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
2209 (! MHD_itc_activate_ (daemon->
itc,
"t")) )
2211 #ifdef HAVE_MESSAGES
2214 "Failed to signal thread termination via inter-thread communication channel."));
2217 return (MHD_THRD_RTRN_TYPE_) 0;
2234 #if defined(HTTPS_SUPPORT)
2235 #if ! defined(MHD_WINSOCK_SOCKETS) && ! defined(MHD_socket_nosignal_) && \
2236 (GNUTLS_VERSION_NUMBER + 0 < 0x030402) && defined(MSG_NOSIGNAL)
2242 #define MHD_TLSLIB_NEED_PUSH_FUNC 1
2245 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2251 MHD_tls_push_func_ (gnutls_transport_ptr_t trnsp,
2255 #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX)
2275 psk_gnutls_adapter (gnutls_session_t session,
2276 const char *username,
2277 gnutls_datum_t *key)
2282 size_t app_psk_size;
2284 connection = gnutls_session_get_ptr (session);
2285 if (
NULL == connection)
2287 #ifdef HAVE_MESSAGES
2289 MHD_PANIC (
_ (
"Internal server error. This should be impossible.\n"));
2293 daemon = connection->
daemon;
2294 #if GNUTLS_VERSION_MAJOR >= 3
2295 if (
NULL == daemon->cred_callback)
2297 #ifdef HAVE_MESSAGES
2299 _ (
"PSK not supported by this server.\n"));
2303 if (0 != daemon->cred_callback (daemon->cred_callback_cls,
2309 if (
NULL == (key->data = gnutls_malloc (app_psk_size)))
2311 #ifdef HAVE_MESSAGES
2314 "PSK authentication failed: gnutls_malloc failed to allocate memory\n"));
2321 #ifdef HAVE_MESSAGES
2323 _ (
"PSK authentication failed: PSK too long\n"));
2328 key->size = (
unsigned int) app_psk_size;
2335 #ifdef HAVE_MESSAGES
2337 _ (
"PSK not supported by this server.\n"));
2375 const struct sockaddr *addr,
2381 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2387 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2419 #ifdef HAVE_MESSAGES
2421 _ (
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
2422 (
int) client_socket,
2432 #ifdef MHD_socket_nosignal_
2433 if (! MHD_socket_nosignal_ (client_socket))
2435 #ifdef HAVE_MESSAGES
2437 _ (
"Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
2440 #ifndef MSG_NOSIGNAL
2451 #ifdef HAVE_MESSAGES
2454 _ (
"Accepted connection on socket %d\n"),
2464 #ifdef HAVE_MESSAGES
2467 "Server reached connection limit. Closing inbound connection.\n"));
2483 #ifdef HAVE_MESSAGES
2485 _ (
"Connection rejected by application. Closing connection.\n"));
2501 #ifdef HAVE_MESSAGES
2503 "Error allocating memory: %s\n",
2516 #ifdef HAVE_MESSAGES
2518 _ (
"Error allocating memory: %s\n"),
2533 if (
NULL == (connection->
addr = malloc (addrlen)))
2536 #ifdef HAVE_MESSAGES
2538 _ (
"Error allocating memory: %s\n"),
2550 memcpy (connection->
addr,
2556 connection->
daemon = daemon;
2566 #ifdef HTTPS_SUPPORT
2567 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030500)
2574 flags = GNUTLS_SERVER;
2575 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030402)
2576 flags |= GNUTLS_NO_SIGNAL;
2578 #if GNUTLS_VERSION_MAJOR >= 3
2579 flags |= GNUTLS_NONBLOCK;
2581 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030603)
2583 flags |= GNUTLS_POST_HANDSHAKE_AUTH;
2585 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030605)
2587 flags |= GNUTLS_ENABLE_EARLY_DATA;
2591 gnutls_init (&connection->tls_session,
2593 gnutls_priority_set (connection->tls_session,
2594 daemon->priority_cache);
2595 gnutls_session_set_ptr (connection->tls_session,
2597 switch (daemon->cred_type)
2600 case GNUTLS_CRD_CERTIFICATE:
2601 gnutls_credentials_set (connection->tls_session,
2602 GNUTLS_CRD_CERTIFICATE,
2605 case GNUTLS_CRD_PSK:
2606 gnutls_credentials_set (connection->tls_session,
2609 gnutls_psk_set_server_credentials_function (daemon->psk_cred,
2610 &psk_gnutls_adapter);
2613 #ifdef HAVE_MESSAGES
2614 MHD_DLOG (connection->
daemon,
2616 "Failed to setup TLS credentials: unknown credential type %d\n"),
2623 free (connection->
addr);
2631 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030109) && ! defined(_WIN64)
2632 gnutls_transport_set_int (connection->tls_session,
2633 (
int) (client_socket));
2635 gnutls_transport_set_ptr (connection->tls_session,
2636 (gnutls_transport_ptr_t) (intptr_t) (client_socket));
2638 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2639 gnutls_transport_set_push_function (connection->tls_session,
2640 MHD_tls_push_func_);
2642 if (daemon->https_mem_trust)
2643 gnutls_certificate_server_set_request (connection->tls_session,
2644 GNUTLS_CERT_REQUEST);
2651 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2657 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2661 #ifdef HAVE_MESSAGES
2664 "Server reached connection limit. Closing inbound connection.\n"));
2681 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2689 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2695 daemon->thread_stack_size,
2700 #ifdef HAVE_MESSAGES
2702 "Failed to create a thread: %s\n",
2709 connection->
pid = daemon->
pid;
2711 #ifdef EPOLL_SUPPORT
2716 struct epoll_event event;
2718 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2719 event.data.ptr = connection;
2720 if (0 != epoll_ctl (daemon->epoll_fd,
2726 #ifdef HAVE_MESSAGES
2728 _ (
"Call to epoll_ctl failed: %s\n"),
2741 daemon->eready_tail,
2749 (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
2750 (! MHD_itc_activate_ (daemon->
itc,
"n")) )
2752 #ifdef HAVE_MESSAGES
2755 "Failed to signal new connection via inter-thread communication channel."));
2765 #ifdef HTTPS_SUPPORT
2766 if (
NULL != connection->tls_session)
2767 gnutls_deinit (connection->tls_session);
2773 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2785 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2789 free (connection->
addr);
2813 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2820 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2844 #ifdef EPOLL_SUPPORT
2850 daemon->eready_tail,
2856 if (0 != epoll_ctl (daemon->epoll_fd,
2860 MHD_PANIC (
_ (
"Failed to remove FD from epoll set\n"));
2866 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2910 "Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2911 #ifdef UPGRADE_SUPPORT
2912 if (
NULL != connection->urh)
2914 #ifdef HAVE_MESSAGES
2917 "Error: connection scheduled for \"upgrade\" cannot be suspended"));
2941 "Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2942 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2947 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2950 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
2951 (! MHD_itc_activate_ (daemon->
itc,
"r")) )
2953 #ifdef HAVE_MESSAGES
2956 "Failed to signal resume via inter-thread communication channel."));
2979 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2983 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2997 #ifdef UPGRADE_SUPPORT
2998 struct MHD_UpgradeResponseHandle *
const urh = pos->urh;
3000 static const void *
const urh =
NULL;
3004 #ifdef UPGRADE_SUPPORT
3005 || ( (
NULL != urh) &&
3006 ( (! urh->was_closed) ||
3007 (! urh->clean_ready) ) )
3037 #ifdef EPOLL_SUPPORT
3041 MHD_PANIC (
"Resumed connection was already in EREADY set\n");
3045 daemon->eready_tail,
3054 #ifdef UPGRADE_SUPPORT
3079 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3082 if ( (used_thr_p_c) &&
3085 if (! MHD_itc_activate_ (daemon->
itc,
3088 #ifdef HAVE_MESSAGES
3091 "Failed to signal resume of connection via inter-thread communication channel."));
3129 const struct sockaddr *addr,
3136 #ifdef HAVE_MESSAGES
3138 _ (
"Failed to set nonblocking mode on new client socket: %s\n"),
3149 #ifdef HAVE_MESSAGES
3151 _ (
"Failed to set noninheritable mode on new client socket.\n"));
3158 #ifdef HAVE_MESSAGES
3160 _ (
"Failed to reset buffering mode on new client socket.\n"));
3190 struct sockaddr_in6 addrstorage;
3192 struct sockaddr_in addrstorage;
3194 struct sockaddr *addr = (
struct sockaddr *) &addrstorage;
3200 addrlen =
sizeof (addrstorage);
3203 sizeof (addrstorage));
3230 #ifdef HAVE_MESSAGES
3233 _ (
"Error accepting connection: %s\n"),
3245 #ifdef HAVE_MESSAGES
3251 "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"));
3256 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3260 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3263 #ifdef HAVE_MESSAGES
3266 "Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
3273 #if defined(MHD_TCP_CORK_NOPUSH) || defined(HAVE_MSG_MORE)
3278 (EOPNOTSUPP != errno) )
3280 #ifdef HAVE_MESSAGES
3282 _ (
"Failed to disable TCP Nagle on socket: %s\n"),
3287 #if ! defined(USE_ACCEPT4) || ! defined(HAVE_SOCK_NONBLOCK)
3290 #ifdef HAVE_MESSAGES
3293 "Failed to set nonblocking mode on incoming connection socket: %s\n"),
3300 #if ! defined(USE_ACCEPT4) || ! defined(SOCK_CLOEXEC)
3303 #ifdef HAVE_MESSAGES
3306 "Failed to set noninheritable mode on incoming connection socket.\n"));
3310 #ifdef HAVE_MESSAGES
3313 _ (
"Accepted connection on socket %d\n"),
3341 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3349 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3353 (! MHD_join_thread_ (pos->
pid.handle)) )
3356 #ifdef UPGRADE_SUPPORT
3357 cleanup_upgraded_connection (pos);
3360 #ifdef HTTPS_SUPPORT
3361 if (
NULL != pos->tls_session)
3362 gnutls_deinit (pos->tls_session);
3374 #ifdef EPOLL_SUPPORT
3384 if ( (-1 !=
daemon->epoll_fd) &&
3392 if (0 != epoll_ctl (
daemon->epoll_fd,
3396 MHD_PANIC (
_ (
"Failed to remove FD from epoll set\n"));
3412 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3418 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3448 time_t earliest_deadline;
3455 #ifdef HAVE_MESSAGES
3457 _ (
"Illegal call to MHD_get_timeout\n"));
3469 #ifdef EPOLL_SUPPORT
3472 #
if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
3483 have_timeout =
false;
3484 earliest_deadline = 0;
3489 if ( (! have_timeout) ||
3492 have_timeout =
true;
3497 if ( (
NULL != pos) &&
3500 if ( (! have_timeout) ||
3503 have_timeout =
true;
3509 if (earliest_deadline < now)
3513 const time_t second_left = earliest_deadline - now;
3515 if (((
unsigned long long) second_left) >
ULLONG_MAX / 1000)
3518 *timeout = 1000LLU * (
unsigned long long) second_left;
3536 const fd_set *read_fd_set,
3537 const fd_set *write_fd_set,
3538 const fd_set *except_fd_set)
3543 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3544 struct MHD_UpgradeResponseHandle *urh;
3545 struct MHD_UpgradeResponseHandle *urhn;
3554 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
3555 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
3557 MHD_itc_clear_ (daemon->
itc);
3570 while (
NULL != (pos = prev))
3586 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3588 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
3592 urh_from_fdset (urh,
3599 if ( (0 == urh->in_buffer_size) &&
3600 (0 == urh->out_buffer_size) &&
3601 (0 == urh->in_buffer_used) &&
3602 (0 == urh->out_buffer_used) )
3605 urh->clean_ready =
true;
3640 const fd_set *read_fd_set,
3641 const fd_set *write_fd_set,
3642 const fd_set *except_fd_set)
3648 if ((
NULL == read_fd_set) || (
NULL == write_fd_set))
3650 if (
NULL == except_fd_set)
3652 #ifdef HAVE_MESSAGES
3654 _ (
"MHD_run_from_select() called with except_fd_set "
3655 "set to NULL. Such behavior is deprecated.\n"));
3658 except_fd_set = &es;
3662 #ifdef EPOLL_SUPPORT
3663 int ret = MHD_epoll (daemon,
3701 struct timeval timeout;
3708 timeout.tv_usec = 0;
3732 #ifdef HAVE_MESSAGES
3734 _ (
"Could not obtain daemon fdsets"));
3749 #ifdef HAVE_MESSAGES
3751 _ (
"Could not add listen socket to fdset"));
3756 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
3762 #if defined(MHD_WINSOCK_SOCKETS)
3777 #ifdef HAVE_MESSAGES
3780 "Could not add control inter-thread communication channel FD to fdset"));
3783 #if defined(MHD_WINSOCK_SOCKETS)
3797 (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
3809 timeout.tv_usec = 0;
3817 timeout.tv_usec = (ltimeout % 1000) * 1000;
3836 #ifdef HAVE_MESSAGES
3838 _ (
"select failed: %s\n"),
3865 unsigned int num_connections;
3868 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3869 struct MHD_UpgradeResponseHandle *urh;
3870 struct MHD_UpgradeResponseHandle *urhn;
3878 num_connections = 0;
3881 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3882 for (urh = daemon->urh_head;
NULL != urh; urh = urh->next)
3883 num_connections += 2;
3889 unsigned int poll_server;
3896 sizeof (
struct pollfd));
3899 #ifdef HAVE_MESSAGES
3901 _ (
"Error allocating memory: %s\n"),
3914 p[poll_server].fd = ls;
3915 p[poll_server].events = POLLIN;
3916 p[poll_server].revents = 0;
3917 poll_listen = (int) poll_server;
3921 if (MHD_ITC_IS_VALID_ (daemon->
itc))
3923 p[poll_server].fd = MHD_itc_r_fd_ (daemon->
itc);
3924 p[poll_server].events = POLLIN;
3925 p[poll_server].revents = 0;
3926 poll_itc_idx = (int) poll_server;
3936 timeout = (ltimeout > INT_MAX) ? INT_MAX : (
int) ltimeout;
3945 p[poll_server + i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
3948 p[poll_server + i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
3951 p[poll_server + i].events |= MHD_POLL_EVENTS_ERR_DISC;
3959 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3960 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
3962 urh_to_pollfd (urh, &(p[poll_server + i]));
3966 if (0 == poll_server + num_connections)
3971 if (MHD_sys_poll_ (p,
3972 poll_server + num_connections,
3981 #ifdef HAVE_MESSAGES
3983 _ (
"poll failed: %s\n"),
3996 if ( (-1 != poll_itc_idx) &&
3997 (0 != (p[poll_itc_idx].revents & POLLIN)) )
3998 MHD_itc_clear_ (daemon->
itc);
4008 while (
NULL != (pos = prev))
4012 if (i >= num_connections)
4017 0 != (p[poll_server + i].revents & POLLIN),
4018 0 != (p[poll_server + i].revents & POLLOUT),
4019 0 != (p[poll_server + i].revents
4020 & MHD_POLL_REVENTS_ERR_DISC));
4023 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4024 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
4026 if (i >= num_connections)
4033 if ((p[poll_server + i].
fd != urh->connection->socket_fd) ||
4034 (p[poll_server + i + 1].fd != urh->mhd.socket))
4036 urh_from_pollfd (urh,
4037 &p[poll_server + i]);
4041 if ( (0 == urh->in_buffer_size) &&
4042 (0 == urh->out_buffer_size) &&
4043 (0 == urh->in_buffer_used) &&
4044 (0 == urh->out_buffer_used) )
4049 urh->clean_ready =
true;
4059 if ( (-1 != poll_listen) &&
4060 (0 != (p[poll_listen].revents & POLLIN)) )
4077 MHD_poll_listen_socket (
struct MHD_Daemon *daemon,
4082 unsigned int poll_count;
4097 p[poll_count].fd = ls;
4098 p[poll_count].events = POLLIN;
4099 p[poll_count].revents = 0;
4100 poll_listen = poll_count;
4103 if (MHD_ITC_IS_VALID_ (daemon->
itc))
4105 p[poll_count].fd = MHD_itc_r_fd_ (daemon->
itc);
4106 p[poll_count].events = POLLIN;
4107 p[poll_count].revents = 0;
4108 poll_itc_idx = poll_count;
4119 if (0 == poll_count)
4121 if (MHD_sys_poll_ (p,
4129 #ifdef HAVE_MESSAGES
4131 _ (
"poll failed: %s\n"),
4136 if ( (-1 != poll_itc_idx) &&
4137 (0 != (p[poll_itc_idx].revents & POLLIN)) )
4138 MHD_itc_clear_ (daemon->
itc);
4143 if ( (-1 != poll_listen) &&
4144 (0 != (p[poll_listen].revents & POLLIN)) )
4168 return MHD_poll_all (daemon,
4170 return MHD_poll_listen_socket (daemon,
4180 #ifdef EPOLL_SUPPORT
4190 #define MAX_EVENTS 128
4193 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4203 is_urh_ready (
struct MHD_UpgradeResponseHandle *
const urh)
4207 if ( (0 == urh->in_buffer_size) &&
4208 (0 == urh->out_buffer_size) &&
4209 (0 == urh->in_buffer_used) &&
4210 (0 == urh->out_buffer_used) )
4216 (urh->in_buffer_used < urh->in_buffer_size) )
4219 (urh->out_buffer_used < urh->out_buffer_size) )
4222 (urh->out_buffer_used > 0) )
4225 (urh->in_buffer_used > 0) )
4242 struct epoll_event events[MAX_EVENTS];
4244 struct MHD_UpgradeResponseHandle *pos;
4245 struct MHD_UpgradeResponseHandle *prev;
4247 num_events = MAX_EVENTS;
4248 while (0 != num_events)
4252 num_events = epoll_wait (daemon->epoll_upgrade_fd,
4256 if (-1 == num_events)
4262 #ifdef HAVE_MESSAGES
4264 _ (
"Call to epoll_wait failed: %s\n"),
4269 for (i = 0; i < (
unsigned int) num_events; i++)
4271 struct UpgradeEpollHandle *
const ueh = events[i].data.ptr;
4272 struct MHD_UpgradeResponseHandle *
const urh = ueh->urh;
4273 bool new_err_state =
false;
4275 if (urh->clean_ready)
4279 if (0 != (events[i].events & EPOLLIN))
4281 if (0 != (events[i].events & EPOLLOUT))
4283 if (0 != (events[i].events & EPOLLHUP))
4287 (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
4293 new_err_state =
true;
4296 if (! urh->in_eready_list)
4298 if (new_err_state ||
4302 daemon->eready_urh_tail,
4304 urh->in_eready_list =
true;
4309 prev = daemon->eready_urh_tail;
4310 while (
NULL != (pos = prev))
4314 if (! is_urh_ready (pos))
4317 daemon->eready_urh_tail,
4319 pos->in_eready_list =
false;
4322 if ( (0 == pos->in_buffer_size) &&
4323 (0 == pos->out_buffer_size) &&
4324 (0 == pos->in_buffer_used) &&
4325 (0 == pos->out_buffer_used) )
4328 pos->clean_ready =
true;
4347 static const char *
const epoll_itc_marker =
"itc_marker";
4362 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4363 static const char *
const upgrade_marker =
"upgrade_ptr";
4367 struct epoll_event events[MAX_EVENTS];
4368 struct epoll_event event;
4374 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4375 bool run_upgraded =
false;
4378 if (-1 == daemon->epoll_fd)
4385 (! daemon->listen_socket_in_epoll) &&
4388 event.events = EPOLLIN;
4389 event.data.ptr = daemon;
4390 if (0 != epoll_ctl (daemon->epoll_fd,
4395 #ifdef HAVE_MESSAGES
4397 _ (
"Call to epoll_ctl failed: %s\n"),
4402 daemon->listen_socket_in_epoll =
true;
4405 (daemon->listen_socket_in_epoll) )
4407 if ( (0 != epoll_ctl (daemon->epoll_fd,
4413 MHD_PANIC (
"Failed to remove listen FD from epoll set\n");
4414 daemon->listen_socket_in_epoll =
false;
4417 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4418 if ( ( (! daemon->upgrade_fd_in_epoll) &&
4419 (-1 != daemon->epoll_upgrade_fd) ) )
4421 event.events = EPOLLIN | EPOLLOUT;
4422 event.data.ptr = (
void *) upgrade_marker;
4423 if (0 != epoll_ctl (daemon->epoll_fd,
4425 daemon->epoll_upgrade_fd,
4428 #ifdef HAVE_MESSAGES
4430 _ (
"Call to epoll_ctl failed: %s\n"),
4435 daemon->upgrade_fd_in_epoll =
true;
4438 if ( (daemon->listen_socket_in_epoll) &&
4445 if (0 != epoll_ctl (daemon->epoll_fd,
4449 MHD_PANIC (
_ (
"Failed to remove listen FD from epoll set\n"));
4450 daemon->listen_socket_in_epoll =
false;
4463 timeout_ms = INT_MAX;
4465 timeout_ms = (int) timeout_ll;
4482 num_events = MAX_EVENTS;
4483 while (MAX_EVENTS == num_events)
4486 num_events = epoll_wait (daemon->epoll_fd,
4490 if (-1 == num_events)
4495 #ifdef HAVE_MESSAGES
4497 _ (
"Call to epoll_wait failed: %s\n"),
4502 for (i = 0; i<(
unsigned int) num_events; i++)
4508 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4509 if (upgrade_marker == events[i].
data.ptr)
4513 run_upgraded =
true;
4517 if (epoll_itc_marker == events[i].
data.ptr)
4521 MHD_itc_clear_ (daemon->
itc);
4524 if (daemon == events[i].
data.ptr)
4528 if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
4530 unsigned int series_length = 0;
4536 (series_length < 10) &&
4546 pos = events[i].data.ptr;
4548 if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
4554 daemon->eready_tail,
4561 if (0 != (events[i].events & EPOLLIN))
4569 daemon->eready_tail,
4574 if (0 != (events[i].events & EPOLLOUT))
4581 daemon->eready_tail,
4590 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4591 if (run_upgraded || (
NULL != daemon->eready_urh_head))
4592 run_epoll_for_upgrade (daemon);
4596 prev = daemon->eready_tail;
4597 while (
NULL != (pos = prev))
4615 daemon->eready_tail,
4630 while (
NULL != (pos = prev))
4640 while (
NULL != (pos = prev))
4685 #ifdef EPOLL_SUPPORT
4688 MHD_epoll (daemon,
MHD_NO);
4721 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4740 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4746 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4754 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
4759 MHD_thread_init_ (&(daemon->
pid));
4764 #ifdef EPOLL_SUPPORT
4780 return (MHD_THRD_RTRN_TYPE_) 0;
4878 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4889 #ifdef HAVE_MESSAGES
4891 "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC\n");
4896 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4901 #ifdef EPOLL_SUPPORT
4906 if (0 != epoll_ctl (daemon->
worker_pool[i].epoll_fd,
4910 MHD_PANIC (
_ (
"Failed to remove listen FD from epoll set\n"));
4911 daemon->
worker_pool[i].listen_socket_in_epoll =
false;
4919 "Failed to signal quiesce via inter-thread communication channel"));
4924 #ifdef EPOLL_SUPPORT
4926 (-1 != daemon->epoll_fd) &&
4927 (daemon->listen_socket_in_epoll) )
4929 if ( (0 != epoll_ctl (daemon->epoll_fd,
4935 MHD_PANIC (
"Failed to remove listen FD from epoll set\n");
4936 daemon->listen_socket_in_epoll =
false;
4939 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
4940 (! MHD_itc_activate_ (daemon->
itc,
"q")) )
4942 "failed to signal quiesce via inter-thread communication channel"));
4970 const struct sockaddr **servaddr,
4984 const struct sockaddr **servaddr,
4990 va_start (ap, servaddr);
5009 const struct sockaddr **servaddr,
5016 #ifdef HTTPS_SUPPORT
5019 #if GNUTLS_VERSION_MAJOR >= 3
5020 gnutls_certificate_retrieve_function2 *pgcrf;
5022 #if GNUTLS_VERSION_NUMBER >= 0x030603
5023 gnutls_certificate_retrieve_function3 *pgcrf2;
5054 #ifdef HAVE_MESSAGES
5056 _ (
"Warning: Too large timeout value, ignored.\n"));
5078 *servaddr = va_arg (ap,
5079 const struct sockaddr *);
5092 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5098 #ifdef HAVE_MESSAGES
5101 "Warning: Zero size, specified for thread pool size, is ignored. "
5102 "Thread pool is not used.\n"));
5107 #ifdef HAVE_MESSAGES
5110 "Warning: \"1\", specified for thread pool size, is ignored. "
5111 "Thread pool is not used.\n"));
5121 #ifdef HAVE_MESSAGES
5123 _ (
"Specified thread pool size (%u) too big\n"),
5132 #ifdef HAVE_MESSAGES
5134 _ (
"MHD_OPTION_THREAD_POOL_SIZE option is specified but "
5135 "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
5141 #ifdef HAVE_MESSAGES
5143 _ (
"Both MHD_OPTION_THREAD_POOL_SIZE option and "
5144 "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
5151 #ifdef HTTPS_SUPPORT
5156 daemon->https_mem_key = pstr;
5157 #ifdef HAVE_MESSAGES
5161 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5169 daemon->https_key_password = pstr;
5170 #ifdef HAVE_MESSAGES
5174 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5182 daemon->https_mem_cert = pstr;
5183 #ifdef HAVE_MESSAGES
5187 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5195 daemon->https_mem_trust = pstr;
5196 #ifdef HAVE_MESSAGES
5200 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5205 daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
5213 gnutls_datum_t dhpar;
5216 if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
5218 #ifdef HAVE_MESSAGES
5220 _ (
"Error initializing DH parameters\n"));
5224 dhpar.data = (
unsigned char *) pstr;
5225 pstr_len = strlen (pstr);
5228 #ifdef HAVE_MESSAGES
5230 _ (
"Diffie-Hellman parameters string too long\n"));
5234 dhpar.size = (
unsigned int) pstr_len;
5235 if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
5237 GNUTLS_X509_FMT_PEM) < 0)
5239 #ifdef HAVE_MESSAGES
5241 _ (
"Bad Diffie-Hellman parameters format\n"));
5243 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
5246 daemon->have_dhparams =
true;
5248 #ifdef HAVE_MESSAGES
5252 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5261 gnutls_priority_deinit (daemon->priority_cache);
5262 ret = gnutls_priority_init (&daemon->priority_cache,
5265 if (GNUTLS_E_SUCCESS != ret)
5267 #ifdef HAVE_MESSAGES
5269 _ (
"Setting priorities to `%s' failed: %s\n"),
5271 gnutls_strerror (ret));
5273 daemon->priority_cache =
NULL;
5277 #ifdef HAVE_MESSAGES
5281 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5286 #if GNUTLS_VERSION_MAJOR < 3
5287 #ifdef HAVE_MESSAGES
5290 "MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n"));
5295 gnutls_certificate_retrieve_function2 *);
5297 daemon->cert_callback = pgcrf;
5299 #ifdef HAVE_MESSAGES
5302 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5308 #if GNUTLS_VERSION_NUMBER < 0x030603
5309 #ifdef HAVE_MESSAGES
5312 "MHD_OPTION_HTTPS_CERT_CALLBACK2 requires building MHD with GnuTLS >= 3.6.3\n"));
5316 pgcrf2 = va_arg (ap,
5317 gnutls_certificate_retrieve_function3 *);
5319 daemon->cert_callback2 = pgcrf2;
5321 #ifdef HAVE_MESSAGES
5324 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5330 #ifdef DAUTH_SUPPORT
5332 daemon->digest_auth_rand_size = va_arg (ap,
5334 daemon->digest_auth_random = va_arg (ap,
5338 daemon->nonce_nc_size = va_arg (ap,
5345 #ifdef HAVE_MESSAGES
5347 _ (
"MHD_OPTION_LISTEN_SOCKET specified for daemon "
5348 "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
5357 #ifdef HAVE_MESSAGES
5358 daemon->custom_error_log = va_arg (ap,
5360 daemon->custom_error_log_cls = va_arg (ap,
5369 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5371 daemon->thread_stack_size = va_arg (ap,
5377 daemon->fastopen_queue_size = va_arg (ap,
5381 #ifdef HAVE_MESSAGES
5383 _ (
"TCP fastopen is not supported on this platform\n"));
5389 unsigned int) ? 1 : -1;
5397 #ifdef HAVE_MESSAGES
5402 _ (
"Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
5403 "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n"));
5421 (
size_t) oa[i].
value,
5438 (
unsigned int) oa[i].
value,
5443 #ifdef HTTPS_SUPPORT
5448 (gnutls_credentials_type_t) oa[i].
value,
5499 (
void *) oa[i].
value,
5509 (
size_t) oa[i].
value,
5526 #ifdef HTTPS_SUPPORT
5528 #if GNUTLS_VERSION_MAJOR >= 3
5529 daemon->cred_callback = va_arg (ap,
5531 daemon->cred_callback_cls = va_arg (ap,
5537 "MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3\n"),
5543 #ifdef HAVE_MESSAGES
5551 "MHD HTTPS option %d passed to MHD compiled without HTTPS support\n"),
5558 "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n"),
5569 #ifdef EPOLL_SUPPORT
5575 #ifndef HAVE_MESSAGES
5579 #ifdef USE_EPOLL_CREATE1
5580 fd = epoll_create1 (EPOLL_CLOEXEC);
5582 fd = epoll_create (MAX_EVENTS);
5586 #ifdef HAVE_MESSAGES
5588 _ (
"Call to epoll_create1 failed: %s\n"),
5593 #if ! defined(USE_EPOLL_CREATE1)
5596 #ifdef HAVE_MESSAGES
5598 _ (
"Failed to set noninheritable mode on epoll FD.\n"));
5616 setup_epoll_to_listen (
struct MHD_Daemon *daemon)
5618 struct epoll_event event;
5621 daemon->epoll_fd = setup_epoll_fd (daemon);
5622 if (-1 == daemon->epoll_fd)
5624 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
5627 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
5635 event.events = EPOLLIN;
5636 event.data.ptr = daemon;
5637 if (0 != epoll_ctl (daemon->epoll_fd,
5642 #ifdef HAVE_MESSAGES
5644 _ (
"Call to epoll_ctl failed: %s\n"),
5649 daemon->listen_socket_in_epoll =
true;
5650 if (MHD_ITC_IS_VALID_ (daemon->
itc))
5652 event.events = EPOLLIN;
5653 event.data.ptr = (
void *) epoll_itc_marker;
5654 if (0 != epoll_ctl (daemon->epoll_fd,
5656 MHD_itc_r_fd_ (daemon->
itc),
5659 #ifdef HAVE_MESSAGES
5661 _ (
"Call to epoll_ctl failed: %s\n"),
5707 struct sockaddr_in servaddr4;
5709 struct sockaddr_in6 servaddr6;
5711 const struct sockaddr *servaddr =
NULL;
5713 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5730 #ifndef EPOLL_SUPPORT
5734 #ifndef HTTPS_SUPPORT
5738 #ifndef TCP_FASTOPEN
5744 #ifdef UPGRADE_SUPPORT
5780 #if defined(EPOLL_SUPPORT)
5782 #elif defined(HAVE_POLL)
5791 #if defined(EPOLL_SUPPORT)
5801 #ifdef EPOLL_SUPPORT
5802 daemon->epoll_fd = -1;
5803 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
5804 daemon->epoll_upgrade_fd = -1;
5808 #ifdef HTTPS_SUPPORT
5809 daemon->priority_cache =
NULL;
5812 gnutls_priority_init (&daemon->priority_cache,
5823 daemon->
port = port;
5834 MHD_itc_set_invalid_ (daemon->
itc);
5840 #ifdef HAVE_MESSAGES
5842 daemon->custom_error_log_cls = stderr;
5847 #ifdef HAVE_MESSAGES
5850 "Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with "
5851 "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD "
5852 "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"));
5860 #ifdef HAVE_LISTEN_SHUTDOWN
5865 #ifdef DAUTH_SUPPORT
5866 daemon->digest_auth_rand_size = 0;
5867 daemon->digest_auth_random =
NULL;
5868 daemon->nonce_nc_size = 4;
5870 #ifdef HTTPS_SUPPORT
5873 daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
5882 #ifdef HTTPS_SUPPORT
5884 (
NULL != daemon->priority_cache) )
5885 gnutls_priority_deinit (daemon->priority_cache);
5896 #ifdef HAVE_MESSAGES
5898 _ (
"Using debug build of libmicrohttpd.\n") );
5903 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5908 if (! MHD_itc_init_ (daemon->
itc))
5910 #ifdef HAVE_MESSAGES
5912 _ (
"Failed to create inter-thread communication channel: %s\n"),
5913 MHD_itc_last_strerror_ ());
5915 #ifdef HTTPS_SUPPORT
5916 if (
NULL != daemon->priority_cache)
5917 gnutls_priority_deinit (daemon->priority_cache);
5926 #ifdef HAVE_MESSAGES
5929 "file descriptor for inter-thread communication channel exceeds maximum value\n"));
5932 #ifdef HTTPS_SUPPORT
5933 if (
NULL != daemon->priority_cache)
5934 gnutls_priority_deinit (daemon->priority_cache);
5941 #ifdef DAUTH_SUPPORT
5942 if (daemon->nonce_nc_size > 0)
5944 if ( ( (
size_t) (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc)))
5945 /
sizeof(
struct MHD_NonceNc) != daemon->nonce_nc_size)
5947 #ifdef HAVE_MESSAGES
5949 _ (
"Specified value for NC_SIZE too large\n"));
5951 #ifdef HTTPS_SUPPORT
5953 gnutls_priority_deinit (daemon->priority_cache);
5958 daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc));
5959 if (
NULL == daemon->nnc)
5961 #ifdef HAVE_MESSAGES
5963 _ (
"Failed to allocate memory for nonce-nc map: %s\n"),
5966 #ifdef HTTPS_SUPPORT
5968 gnutls_priority_deinit (daemon->priority_cache);
5975 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5976 if (! MHD_mutex_init_ (&daemon->nnc_lock))
5978 #ifdef HAVE_MESSAGES
5980 _ (
"MHD failed to initialize nonce-nc mutex\n"));
5982 #ifdef HTTPS_SUPPORT
5984 gnutls_priority_deinit (daemon->priority_cache);
5994 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5998 #ifdef HAVE_MESSAGES
6001 "MHD thread pooling only works with MHD_USE_INTERNAL_POLLING_THREAD\n"));
6013 domain = (*pflags &
MHD_USE_IPv6) ? PF_INET6 : PF_INET;
6023 #ifdef HAVE_MESSAGES
6025 _ (
"Failed to create socket for listening: %s\n"),
6034 #ifndef MHD_WINSOCK_SOCKETS
6039 if (0 > setsockopt (listen_fd,
6042 (
void*) &on,
sizeof (on)))
6044 #ifdef HAVE_MESSAGES
6046 _ (
"setsockopt failed: %s\n"),
6055 #ifndef MHD_WINSOCK_SOCKETS
6058 if (0 > setsockopt (listen_fd,
6061 (
void*) &on,
sizeof (on)))
6063 #ifdef HAVE_MESSAGES
6065 _ (
"setsockopt failed: %s\n"),
6075 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT)
6076 if (0 > setsockopt (listen_fd,
6078 #ifndef MHD_WINSOCK_SOCKETS
6086 #ifdef HAVE_MESSAGES
6088 _ (
"setsockopt failed: %s\n"),
6096 #ifdef HAVE_MESSAGES
6099 "Cannot allow listening address reuse: SO_REUSEPORT not defined\n"));
6112 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \
6113 (defined(__sun) && defined(SO_EXCLBIND))
6114 if (0 > setsockopt (listen_fd,
6116 #ifdef SO_EXCLUSIVEADDRUSE
6117 SO_EXCLUSIVEADDRUSE,
6124 #ifdef HAVE_MESSAGES
6126 _ (
"setsockopt failed: %s\n"),
6131 #elif defined(MHD_WINSOCK_SOCKETS)
6132 #ifdef HAVE_MESSAGES
6135 "Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n"));
6144 addrlen =
sizeof (
struct sockaddr_in6);
6147 addrlen =
sizeof (
struct sockaddr_in);
6148 if (
NULL == servaddr)
6153 #ifdef IN6ADDR_ANY_INIT
6154 static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
6158 sizeof (
struct sockaddr_in6));
6159 servaddr6.sin6_family = AF_INET6;
6160 servaddr6.sin6_port = htons (port);
6161 #ifdef IN6ADDR_ANY_INIT
6162 servaddr6.sin6_addr = static_in6any;
6164 #if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
6165 servaddr6.sin6_len =
sizeof (
struct sockaddr_in6);
6167 servaddr = (
struct sockaddr *) &servaddr6;
6174 sizeof (
struct sockaddr_in));
6175 servaddr4.sin_family = AF_INET;
6176 servaddr4.sin_port = htons (port);
6177 if (0 != INADDR_ANY)
6178 servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
6179 #if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
6180 servaddr4.sin_len =
sizeof (
struct sockaddr_in);
6182 servaddr = (
struct sockaddr *) &servaddr4;
6197 if (0 > setsockopt (listen_fd,
6198 IPPROTO_IPV6, IPV6_V6ONLY,
6199 (
const void *) &v6_only,
6202 #ifdef HAVE_MESSAGES
6204 _ (
"setsockopt failed: %s\n"),
6211 if (-1 == bind (listen_fd, servaddr, addrlen))
6213 #ifdef HAVE_MESSAGES
6215 _ (
"Failed to bind to port %u: %s\n"),
6216 (
unsigned int) port,
6225 if (0 == daemon->fastopen_queue_size)
6226 daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
6227 if (0 != setsockopt (listen_fd,
6230 (
const void*) &daemon->fastopen_queue_size,
6231 sizeof (daemon->fastopen_queue_size)))
6233 #ifdef HAVE_MESSAGES
6235 _ (
"setsockopt failed: %s\n"),
6241 if (listen (listen_fd,
6244 #ifdef HAVE_MESSAGES
6246 _ (
"Failed to listen for connections: %s\n"),
6258 #ifdef HAVE_GETSOCKNAME
6259 if ( (0 == daemon->
port) &&
6262 struct sockaddr_storage bindaddr;
6266 sizeof (
struct sockaddr_storage));
6267 addrlen =
sizeof (
struct sockaddr_storage);
6268 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
6269 bindaddr.ss_len = addrlen;
6271 if (0 != getsockname (listen_fd,
6272 (
struct sockaddr *) &bindaddr,
6275 #ifdef HAVE_MESSAGES
6277 _ (
"Failed to get listen port number: %s\n"),
6281 #ifdef MHD_POSIX_SOCKETS
6282 else if (
sizeof (bindaddr) < addrlen)
6285 #ifdef HAVE_MESSAGES
6288 "Failed to get listen port number (`struct sockaddr_storage` too small!?)\n"));
6292 else if (0 == addrlen)
6302 switch (bindaddr.ss_family)
6306 struct sockaddr_in *s4 = (
struct sockaddr_in *) &bindaddr;
6308 daemon->
port = ntohs (s4->sin_port);
6314 struct sockaddr_in6 *s6 = (
struct sockaddr_in6 *) &bindaddr;
6316 daemon->
port = ntohs (s6->sin6_port);
6327 #ifdef HAVE_MESSAGES
6329 _ (
"Unknown address family!\n"));
6340 #ifdef HAVE_MESSAGES
6342 _ (
"Failed to set nonblocking mode on listening socket: %s\n"),
6346 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6363 #ifdef HAVE_MESSAGES
6365 _ (
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
6373 #ifdef EPOLL_SUPPORT
6375 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6382 #ifdef HAVE_MESSAGES
6385 "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
6389 if (
MHD_YES != setup_epoll_to_listen (daemon))
6394 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6397 #ifdef HAVE_MESSAGES
6399 _ (
"MHD failed to initialize IP connection limit mutex\n"));
6410 #ifdef HAVE_MESSAGES
6412 _ (
"MHD failed to initialize IP connection limit mutex\n"));
6414 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6424 #ifdef HTTPS_SUPPORT
6427 (0 != MHD_TLS_init (daemon)) )
6429 #ifdef HAVE_MESSAGES
6431 _ (
"Failed to initialize TLS support\n"));
6435 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6443 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6452 "MHD-listen" :
"MHD-single",
6453 daemon->thread_stack_size,
6457 #ifdef HAVE_MESSAGES
6459 _ (
"Failed to create listen thread: %s\n"),
6493 memcpy (d, daemon,
sizeof (
struct MHD_Daemon));
6503 if (! MHD_itc_init_ (d->
itc))
6505 #ifdef HAVE_MESSAGES
6508 "Failed to create worker inter-thread communication channel: %s\n"),
6509 MHD_itc_last_strerror_ () );
6517 #ifdef HAVE_MESSAGES
6520 "File descriptor for worker inter-thread communication channel exceeds maximum value\n"));
6527 MHD_itc_set_invalid_ (d->
itc);
6533 if (i < leftover_conns)
6535 #ifdef EPOLL_SUPPORT
6537 (
MHD_YES != setup_epoll_to_listen (d)) )
6543 #ifdef HAVE_MESSAGES
6545 _ (
"MHD failed to initialize cleanup connection mutex\n"));
6553 daemon->thread_stack_size,
6557 #ifdef HAVE_MESSAGES
6559 _ (
"Failed to create pool thread: %s\n"),
6571 #ifdef HTTPS_SUPPORT
6574 daemon->https_key_password =
NULL;
6579 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6607 #ifdef EPOLL_SUPPORT
6608 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6609 if (daemon->upgrade_fd_in_epoll)
6611 if (0 != epoll_ctl (daemon->epoll_fd,
6613 daemon->epoll_upgrade_fd,
6615 MHD_PANIC (
_ (
"Failed to remove FD from epoll set\n"));
6616 daemon->upgrade_fd_in_epoll =
false;
6619 if (-1 != daemon->epoll_fd)
6620 close (daemon->epoll_fd);
6621 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6622 if (-1 != daemon->epoll_upgrade_fd)
6623 close (daemon->epoll_upgrade_fd);
6626 #ifdef DAUTH_SUPPORT
6628 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6632 #ifdef HTTPS_SUPPORT
6635 gnutls_priority_deinit (daemon->priority_cache);
6636 if (daemon->x509_cred)
6637 gnutls_certificate_free_credentials (daemon->x509_cred);
6638 if (daemon->psk_cred)
6639 gnutls_psk_free_server_credentials (daemon->psk_cred);
6642 if (MHD_ITC_IS_VALID_ (daemon->
itc))
6663 #ifdef UPGRADE_SUPPORT
6666 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6667 struct MHD_UpgradeResponseHandle *urh;
6668 struct MHD_UpgradeResponseHandle *urhn;
6671 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6677 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
6684 urh->clean_ready =
true;
6701 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6704 #ifdef UPGRADE_SUPPORT
6710 while (
NULL != susp)
6712 if (
NULL == susp->urh)
6714 "MHD_stop_daemon() called while we have suspended connections.\n"));
6715 #ifdef HTTPS_SUPPORT
6716 else if (used_tls &&
6718 (! susp->urh->clean_ready) )
6719 shutdown (susp->urh->app.socket,
6724 #ifdef HAVE_MESSAGES
6725 if (! susp->urh->was_closed)
6728 "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
6730 susp->urh->was_closed =
true;
6747 "MHD_stop_daemon() called while we have suspended connections.\n"));
6752 #if MHD_WINSOCK_SOCKETS
6755 (! MHD_itc_activate_ (
daemon->
itc,
"e")) )
6757 "Failed to signal shutdown via inter-thread communication channel"));
6761 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6771 if (! MHD_join_thread_ (pos->
pid.handle))
6786 #ifdef UPGRADE_SUPPORT
6801 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6822 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6835 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6850 "Failed to signal shutdown via inter-thread communication channel."));
6855 #ifdef HAVE_LISTEN_SHUTDOWN
6858 (void) shutdown (
fd,
6868 #ifdef EPOLL_SUPPORT
6870 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6878 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6888 "Failed to signal shutdown via inter-thread communication channel"));
6892 #ifdef HAVE_LISTEN_SHUTDOWN
6896 (void) shutdown (
fd,
6904 if (! MHD_join_thread_ (
daemon->
pid.handle))
6919 #ifdef EPOLL_SUPPORT
6921 (-1 !=
daemon->epoll_fd) )
6923 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6925 (-1 !=
daemon->epoll_upgrade_fd) )
6930 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6943 #ifdef HTTPS_SUPPORT
6944 if (
daemon->have_dhparams)
6946 gnutls_dh_params_deinit (
daemon->https_mem_dhparams);
6947 daemon->have_dhparams =
false;
6951 gnutls_priority_deinit (
daemon->priority_cache);
6953 gnutls_certificate_free_credentials (
daemon->x509_cred);
6955 gnutls_psk_free_server_credentials (
daemon->psk_cred);
6959 #ifdef DAUTH_SUPPORT
6961 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6965 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6999 #ifdef EPOLL_SUPPORT
7010 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7068 #ifdef PACKAGE_VERSION
7069 return PACKAGE_VERSION;
7071 static char ver[12] =
"\0\0\0\0\0\0\0\0\0\0\0";
7074 int res = MHD_snprintf_ (ver,
7080 if ((0 >= res) || (
sizeof(ver) <= res))
7105 #ifdef HAVE_MESSAGES
7111 #ifdef HTTPS_SUPPORT
7117 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3
7123 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030603
7135 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
7147 #ifdef EPOLL_SUPPORT
7153 #ifdef HAVE_LISTEN_SHUTDOWN
7159 #ifdef _MHD_ITC_SOCKETPAIR
7171 #ifdef BAUTH_SUPPORT
7177 #ifdef DAUTH_SUPPORT
7183 #ifdef HAVE_POSTPROCESSOR
7189 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111
7195 #if defined(HAVE_PREAD64) || defined(_WIN32)
7197 #elif defined(HAVE_PREAD)
7198 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
7199 #elif defined(HAVE_LSEEK64)
7202 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
7205 #if defined(MHD_USE_THREAD_NAME_)
7211 #if defined(UPGRADE_SUPPORT)
7217 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32)
7223 #ifdef MHD_USE_GETSOCKNAME
7229 #if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || \
7230 defined (MSG_NOSIGNAL)
7236 #ifdef _MHD_HAVE_SENDFILE
7242 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7253 #ifdef MHD_HTTPS_REQUIRE_GRYPT
7254 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600
7255 #if defined(MHD_USE_POSIX_THREADS)
7256 GCRY_THREAD_OPTION_PTHREAD_IMPL;
7257 #elif defined(MHD_W32_MUTEX_)
7260 gcry_w32_mutex_init (
void **ppmtx)
7262 *ppmtx = malloc (
sizeof (MHD_mutex_));
7266 if (! MHD_mutex_init_ ((MHD_mutex_*) *ppmtx))
7278 gcry_w32_mutex_destroy (
void **ppmtx)
7280 int res = (MHD_mutex_destroy_ ((MHD_mutex_*) *ppmtx)) ? 0 : EINVAL;
7287 gcry_w32_mutex_lock (
void **ppmtx)
7289 return MHD_mutex_lock_ ((MHD_mutex_*) *ppmtx) ? 0 : EINVAL;
7294 gcry_w32_mutex_unlock (
void **ppmtx)
7296 return MHD_mutex_unlock_ ((MHD_mutex_*) *ppmtx) ? 0 : EINVAL;
7300 static struct gcry_thread_cbs gcry_threads_w32 = {
7301 (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
7302 NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
7303 gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
7317 #if defined(MHD_WINSOCK_SOCKETS)
7324 #if defined(MHD_WINSOCK_SOCKETS)
7325 if (0 != WSAStartup (MAKEWORD (2, 2), &wsd))
7326 MHD_PANIC (
_ (
"Failed to initialize winsock\n"));
7327 mhd_winsock_inited_ = 1;
7328 if ((2 != LOBYTE (wsd.wVersion)) && (2 != HIBYTE (wsd.wVersion)))
7329 MHD_PANIC (
_ (
"Winsock version 2.2 is not available\n"));
7331 #ifdef HTTPS_SUPPORT
7332 #ifdef MHD_HTTPS_REQUIRE_GRYPT
7333 #if GCRYPT_VERSION_NUMBER < 0x010600
7334 #if defined(MHD_USE_POSIX_THREADS)
7335 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7336 &gcry_threads_pthread))
7337 MHD_PANIC (
_ (
"Failed to initialise multithreading in libgcrypt\n"));
7338 #elif defined(MHD_W32_MUTEX_)
7339 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7341 MHD_PANIC (
_ (
"Failed to initialise multithreading in libgcrypt\n"));
7343 gcry_check_version (
NULL);
7345 if (
NULL == gcry_check_version (
"1.6.0"))
7347 "libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n"));
7350 gnutls_global_init ();
7353 #ifdef HAVE_FREEBSD_SENDFILE
7354 MHD_conn_init_static_ ();
7363 #ifdef HTTPS_SUPPORT
7364 gnutls_global_deinit ();
7366 #if defined(MHD_WINSOCK_SOCKETS)
7367 if (mhd_winsock_inited_)
7374 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED