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,
3137 #ifdef HAVE_MESSAGES 3139 _ (
"Failed to set nonblocking mode on new client socket: %s\n"),
3150 #ifdef HAVE_MESSAGES 3152 _ (
"Failed to set noninheritable mode on new client socket.\n"));
3159 #ifdef HAVE_MESSAGES 3161 _ (
"Failed to reset buffering mode on new client socket.\n"));
3191 struct sockaddr_in6 addrstorage;
3193 struct sockaddr_in addrstorage;
3195 struct sockaddr *addr = (
struct sockaddr *) &addrstorage;
3201 addrlen =
sizeof (addrstorage);
3204 sizeof (addrstorage));
3231 #ifdef HAVE_MESSAGES 3234 _ (
"Error accepting connection: %s\n"),
3246 #ifdef HAVE_MESSAGES 3252 "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"));
3257 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3261 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3264 #ifdef HAVE_MESSAGES 3267 "Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
3274 #if defined(MHD_TCP_CORK_NOPUSH) || defined(HAVE_MSG_MORE) 3279 (EOPNOTSUPP != errno) )
3281 #ifdef HAVE_MESSAGES 3283 _ (
"Failed to disable TCP Nagle on socket: %s\n"),
3288 #if ! defined(USE_ACCEPT4) || ! defined(HAVE_SOCK_NONBLOCK) 3291 #ifdef HAVE_MESSAGES 3294 "Failed to set nonblocking mode on incoming connection socket: %s\n"),
3301 #if ! defined(USE_ACCEPT4) || ! defined(SOCK_CLOEXEC) 3304 #ifdef HAVE_MESSAGES 3307 "Failed to set noninheritable mode on incoming connection socket.\n"));
3311 #ifdef HAVE_MESSAGES 3314 _ (
"Accepted connection on socket %d\n"),
3342 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3350 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3354 (! MHD_join_thread_ (pos->
pid.handle)) )
3357 #ifdef UPGRADE_SUPPORT 3358 cleanup_upgraded_connection (pos);
3361 #ifdef HTTPS_SUPPORT 3362 if (
NULL != pos->tls_session)
3363 gnutls_deinit (pos->tls_session);
3375 #ifdef EPOLL_SUPPORT 3385 if ( (-1 !=
daemon->epoll_fd) &&
3393 if (0 != epoll_ctl (
daemon->epoll_fd,
3397 MHD_PANIC (
_ (
"Failed to remove FD from epoll set\n"));
3413 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3419 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3449 time_t earliest_deadline;
3456 #ifdef HAVE_MESSAGES 3458 _ (
"Illegal call to MHD_get_timeout\n"));
3470 #ifdef EPOLL_SUPPORT 3473 #
if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
3484 have_timeout =
false;
3485 earliest_deadline = 0;
3490 if ( (! have_timeout) ||
3493 have_timeout =
true;
3498 if ( (
NULL != pos) &&
3501 if ( (! have_timeout) ||
3504 have_timeout =
true;
3510 if (earliest_deadline < now)
3514 const time_t second_left = earliest_deadline - now;
3516 if (((
unsigned long long) second_left) >
ULLONG_MAX / 1000)
3519 *timeout = 1000LLU * (
unsigned long long) second_left;
3537 const fd_set *read_fd_set,
3538 const fd_set *write_fd_set,
3539 const fd_set *except_fd_set)
3544 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3545 struct MHD_UpgradeResponseHandle *urh;
3546 struct MHD_UpgradeResponseHandle *urhn;
3555 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
3556 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
3558 MHD_itc_clear_ (daemon->
itc);
3571 while (
NULL != (pos = prev))
3587 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3589 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
3593 urh_from_fdset (urh,
3600 if ( (0 == urh->in_buffer_size) &&
3601 (0 == urh->out_buffer_size) &&
3602 (0 == urh->in_buffer_used) &&
3603 (0 == urh->out_buffer_used) )
3606 urh->clean_ready =
true;
3641 const fd_set *read_fd_set,
3642 const fd_set *write_fd_set,
3643 const fd_set *except_fd_set)
3649 if ((
NULL == read_fd_set) || (
NULL == write_fd_set))
3651 if (
NULL == except_fd_set)
3653 #ifdef HAVE_MESSAGES 3655 _ (
"MHD_run_from_select() called with except_fd_set " 3656 "set to NULL. Such behavior is deprecated.\n"));
3659 except_fd_set = &es;
3663 #ifdef EPOLL_SUPPORT 3664 int ret = MHD_epoll (daemon,
3702 struct timeval timeout;
3709 timeout.tv_usec = 0;
3733 #ifdef HAVE_MESSAGES 3735 _ (
"Could not obtain daemon fdsets"));
3750 #ifdef HAVE_MESSAGES 3752 _ (
"Could not add listen socket to fdset"));
3757 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
3763 #if defined(MHD_WINSOCK_SOCKETS) 3778 #ifdef HAVE_MESSAGES 3781 "Could not add control inter-thread communication channel FD to fdset"));
3784 #if defined(MHD_WINSOCK_SOCKETS) 3798 (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
3810 timeout.tv_usec = 0;
3818 timeout.tv_usec = (ltimeout % 1000) * 1000;
3837 #ifdef HAVE_MESSAGES 3839 _ (
"select failed: %s\n"),
3866 unsigned int num_connections;
3869 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3870 struct MHD_UpgradeResponseHandle *urh;
3871 struct MHD_UpgradeResponseHandle *urhn;
3879 num_connections = 0;
3882 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3883 for (urh = daemon->urh_head;
NULL != urh; urh = urh->next)
3884 num_connections += 2;
3890 unsigned int poll_server;
3897 sizeof (
struct pollfd));
3900 #ifdef HAVE_MESSAGES 3902 _ (
"Error allocating memory: %s\n"),
3915 p[poll_server].fd = ls;
3916 p[poll_server].events = POLLIN;
3917 p[poll_server].revents = 0;
3918 poll_listen = (int) poll_server;
3922 if (MHD_ITC_IS_VALID_ (daemon->
itc))
3924 p[poll_server].fd = MHD_itc_r_fd_ (daemon->
itc);
3925 p[poll_server].events = POLLIN;
3926 p[poll_server].revents = 0;
3927 poll_itc_idx = (int) poll_server;
3937 timeout = (ltimeout > INT_MAX) ? INT_MAX : (
int) ltimeout;
3946 p[poll_server + i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
3949 p[poll_server + i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
3952 p[poll_server + i].events |= MHD_POLL_EVENTS_ERR_DISC;
3960 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3961 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
3963 urh_to_pollfd (urh, &(p[poll_server + i]));
3967 if (0 == poll_server + num_connections)
3972 if (MHD_sys_poll_ (p,
3973 poll_server + num_connections,
3982 #ifdef HAVE_MESSAGES 3984 _ (
"poll failed: %s\n"),
3997 if ( (-1 != poll_itc_idx) &&
3998 (0 != (p[poll_itc_idx].revents & POLLIN)) )
3999 MHD_itc_clear_ (daemon->
itc);
4009 while (
NULL != (pos = prev))
4013 if (i >= num_connections)
4018 0 != (p[poll_server + i].revents & POLLIN),
4019 0 != (p[poll_server + i].revents & POLLOUT),
4020 0 != (p[poll_server + i].revents
4021 & MHD_POLL_REVENTS_ERR_DISC));
4024 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4025 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
4027 if (i >= num_connections)
4034 if ((p[poll_server + i].
fd != urh->connection->socket_fd) ||
4035 (p[poll_server + i + 1].fd != urh->mhd.socket))
4037 urh_from_pollfd (urh,
4038 &p[poll_server + i]);
4042 if ( (0 == urh->in_buffer_size) &&
4043 (0 == urh->out_buffer_size) &&
4044 (0 == urh->in_buffer_used) &&
4045 (0 == urh->out_buffer_used) )
4050 urh->clean_ready =
true;
4060 if ( (-1 != poll_listen) &&
4061 (0 != (p[poll_listen].revents & POLLIN)) )
4078 MHD_poll_listen_socket (
struct MHD_Daemon *daemon,
4083 unsigned int poll_count;
4098 p[poll_count].fd = ls;
4099 p[poll_count].events = POLLIN;
4100 p[poll_count].revents = 0;
4101 poll_listen = poll_count;
4104 if (MHD_ITC_IS_VALID_ (daemon->
itc))
4106 p[poll_count].fd = MHD_itc_r_fd_ (daemon->
itc);
4107 p[poll_count].events = POLLIN;
4108 p[poll_count].revents = 0;
4109 poll_itc_idx = poll_count;
4120 if (0 == poll_count)
4122 if (MHD_sys_poll_ (p,
4130 #ifdef HAVE_MESSAGES 4132 _ (
"poll failed: %s\n"),
4137 if ( (-1 != poll_itc_idx) &&
4138 (0 != (p[poll_itc_idx].revents & POLLIN)) )
4139 MHD_itc_clear_ (daemon->
itc);
4144 if ( (-1 != poll_listen) &&
4145 (0 != (p[poll_listen].revents & POLLIN)) )
4169 return MHD_poll_all (daemon,
4171 return MHD_poll_listen_socket (daemon,
4181 #ifdef EPOLL_SUPPORT 4191 #define MAX_EVENTS 128 4194 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4204 is_urh_ready (
struct MHD_UpgradeResponseHandle *
const urh)
4208 if ( (0 == urh->in_buffer_size) &&
4209 (0 == urh->out_buffer_size) &&
4210 (0 == urh->in_buffer_used) &&
4211 (0 == urh->out_buffer_used) )
4217 (urh->in_buffer_used < urh->in_buffer_size) )
4220 (urh->out_buffer_used < urh->out_buffer_size) )
4223 (urh->out_buffer_used > 0) )
4226 (urh->in_buffer_used > 0) )
4243 struct epoll_event events[MAX_EVENTS];
4245 struct MHD_UpgradeResponseHandle *pos;
4246 struct MHD_UpgradeResponseHandle *prev;
4248 num_events = MAX_EVENTS;
4249 while (0 != num_events)
4253 num_events = epoll_wait (daemon->epoll_upgrade_fd,
4257 if (-1 == num_events)
4263 #ifdef HAVE_MESSAGES 4265 _ (
"Call to epoll_wait failed: %s\n"),
4270 for (i = 0; i < (
unsigned int) num_events; i++)
4272 struct UpgradeEpollHandle *
const ueh = events[i].data.ptr;
4273 struct MHD_UpgradeResponseHandle *
const urh = ueh->urh;
4274 bool new_err_state =
false;
4276 if (urh->clean_ready)
4280 if (0 != (events[i].events & EPOLLIN))
4282 if (0 != (events[i].events & EPOLLOUT))
4284 if (0 != (events[i].events & EPOLLHUP))
4288 (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
4294 new_err_state =
true;
4297 if (! urh->in_eready_list)
4299 if (new_err_state ||
4303 daemon->eready_urh_tail,
4305 urh->in_eready_list =
true;
4310 prev = daemon->eready_urh_tail;
4311 while (
NULL != (pos = prev))
4315 if (! is_urh_ready (pos))
4318 daemon->eready_urh_tail,
4320 pos->in_eready_list =
false;
4323 if ( (0 == pos->in_buffer_size) &&
4324 (0 == pos->out_buffer_size) &&
4325 (0 == pos->in_buffer_used) &&
4326 (0 == pos->out_buffer_used) )
4329 pos->clean_ready =
true;
4348 static const char *
const epoll_itc_marker =
"itc_marker";
4363 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4364 static const char *
const upgrade_marker =
"upgrade_ptr";
4368 struct epoll_event events[MAX_EVENTS];
4369 struct epoll_event event;
4375 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4376 bool run_upgraded =
false;
4379 if (-1 == daemon->epoll_fd)
4386 (! daemon->listen_socket_in_epoll) &&
4389 event.events = EPOLLIN;
4390 event.data.ptr = daemon;
4391 if (0 != epoll_ctl (daemon->epoll_fd,
4396 #ifdef HAVE_MESSAGES 4398 _ (
"Call to epoll_ctl failed: %s\n"),
4403 daemon->listen_socket_in_epoll =
true;
4406 (daemon->listen_socket_in_epoll) )
4408 if ( (0 != epoll_ctl (daemon->epoll_fd,
4414 MHD_PANIC (
"Failed to remove listen FD from epoll set\n");
4415 daemon->listen_socket_in_epoll =
false;
4418 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4419 if ( ( (! daemon->upgrade_fd_in_epoll) &&
4420 (-1 != daemon->epoll_upgrade_fd) ) )
4422 event.events = EPOLLIN | EPOLLOUT;
4423 event.data.ptr = (
void *) upgrade_marker;
4424 if (0 != epoll_ctl (daemon->epoll_fd,
4426 daemon->epoll_upgrade_fd,
4429 #ifdef HAVE_MESSAGES 4431 _ (
"Call to epoll_ctl failed: %s\n"),
4436 daemon->upgrade_fd_in_epoll =
true;
4439 if ( (daemon->listen_socket_in_epoll) &&
4446 if (0 != epoll_ctl (daemon->epoll_fd,
4450 MHD_PANIC (
_ (
"Failed to remove listen FD from epoll set\n"));
4451 daemon->listen_socket_in_epoll =
false;
4464 timeout_ms = INT_MAX;
4466 timeout_ms = (int) timeout_ll;
4483 num_events = MAX_EVENTS;
4484 while (MAX_EVENTS == num_events)
4487 num_events = epoll_wait (daemon->epoll_fd,
4491 if (-1 == num_events)
4496 #ifdef HAVE_MESSAGES 4498 _ (
"Call to epoll_wait failed: %s\n"),
4503 for (i = 0; i<(
unsigned int) num_events; i++)
4509 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4510 if (upgrade_marker == events[i].
data.ptr)
4514 run_upgraded =
true;
4518 if (epoll_itc_marker == events[i].
data.ptr)
4522 MHD_itc_clear_ (daemon->
itc);
4525 if (daemon == events[i].
data.ptr)
4529 if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
4531 unsigned int series_length = 0;
4537 (series_length < 10) &&
4547 pos = events[i].data.ptr;
4549 if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
4555 daemon->eready_tail,
4562 if (0 != (events[i].events & EPOLLIN))
4570 daemon->eready_tail,
4575 if (0 != (events[i].events & EPOLLOUT))
4582 daemon->eready_tail,
4591 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4592 if (run_upgraded || (
NULL != daemon->eready_urh_head))
4593 run_epoll_for_upgrade (daemon);
4597 prev = daemon->eready_tail;
4598 while (
NULL != (pos = prev))
4616 daemon->eready_tail,
4631 while (
NULL != (pos = prev))
4641 while (
NULL != (pos = prev))
4686 #ifdef EPOLL_SUPPORT 4689 MHD_epoll (daemon,
MHD_NO);
4722 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4741 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4747 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4755 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
4760 MHD_thread_init_ (&(daemon->
pid));
4765 #ifdef EPOLL_SUPPORT 4781 return (MHD_THRD_RTRN_TYPE_) 0;
4879 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4890 #ifdef HAVE_MESSAGES 4892 "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC\n");
4897 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4902 #ifdef EPOLL_SUPPORT 4907 if (0 != epoll_ctl (daemon->
worker_pool[i].epoll_fd,
4911 MHD_PANIC (
_ (
"Failed to remove listen FD from epoll set\n"));
4912 daemon->
worker_pool[i].listen_socket_in_epoll =
false;
4920 "Failed to signal quiesce via inter-thread communication channel"));
4925 #ifdef EPOLL_SUPPORT 4927 (-1 != daemon->epoll_fd) &&
4928 (daemon->listen_socket_in_epoll) )
4930 if ( (0 != epoll_ctl (daemon->epoll_fd,
4936 MHD_PANIC (
"Failed to remove listen FD from epoll set\n");
4937 daemon->listen_socket_in_epoll =
false;
4940 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
4941 (! MHD_itc_activate_ (daemon->
itc,
"q")) )
4943 "failed to signal quiesce via inter-thread communication channel"));
4971 const struct sockaddr **servaddr,
4985 const struct sockaddr **servaddr,
4991 va_start (ap, servaddr);
5010 const struct sockaddr **servaddr,
5017 #ifdef HTTPS_SUPPORT 5020 #if GNUTLS_VERSION_MAJOR >= 3 5021 gnutls_certificate_retrieve_function2 *pgcrf;
5023 #if GNUTLS_VERSION_NUMBER >= 0x030603 5024 gnutls_certificate_retrieve_function3 *pgcrf2;
5055 #ifdef HAVE_MESSAGES 5057 _ (
"Warning: Too large timeout value, ignored.\n"));
5079 *servaddr = va_arg (ap,
5080 const struct sockaddr *);
5093 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5099 #ifdef HAVE_MESSAGES 5102 "Warning: Zero size, specified for thread pool size, is ignored. " 5103 "Thread pool is not used.\n"));
5108 #ifdef HAVE_MESSAGES 5111 "Warning: \"1\", specified for thread pool size, is ignored. " 5112 "Thread pool is not used.\n"));
5122 #ifdef HAVE_MESSAGES 5124 _ (
"Specified thread pool size (%u) too big\n"),
5133 #ifdef HAVE_MESSAGES 5135 _ (
"MHD_OPTION_THREAD_POOL_SIZE option is specified but " 5136 "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
5142 #ifdef HAVE_MESSAGES 5144 _ (
"Both MHD_OPTION_THREAD_POOL_SIZE option and " 5145 "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
5152 #ifdef HTTPS_SUPPORT 5157 daemon->https_mem_key = pstr;
5158 #ifdef HAVE_MESSAGES 5162 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5170 daemon->https_key_password = pstr;
5171 #ifdef HAVE_MESSAGES 5175 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5183 daemon->https_mem_cert = pstr;
5184 #ifdef HAVE_MESSAGES 5188 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5196 daemon->https_mem_trust = pstr;
5197 #ifdef HAVE_MESSAGES 5201 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5206 daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
5214 gnutls_datum_t dhpar;
5217 if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
5219 #ifdef HAVE_MESSAGES 5221 _ (
"Error initializing DH parameters\n"));
5225 dhpar.data = (
unsigned char *) pstr;
5226 pstr_len = strlen (pstr);
5229 #ifdef HAVE_MESSAGES 5231 _ (
"Diffie-Hellman parameters string too long\n"));
5235 dhpar.size = (
unsigned int) pstr_len;
5236 if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
5238 GNUTLS_X509_FMT_PEM) < 0)
5240 #ifdef HAVE_MESSAGES 5242 _ (
"Bad Diffie-Hellman parameters format\n"));
5244 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
5247 daemon->have_dhparams =
true;
5249 #ifdef HAVE_MESSAGES 5253 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5262 gnutls_priority_deinit (daemon->priority_cache);
5263 ret = gnutls_priority_init (&daemon->priority_cache,
5266 if (GNUTLS_E_SUCCESS != ret)
5268 #ifdef HAVE_MESSAGES 5270 _ (
"Setting priorities to `%s' failed: %s\n"),
5272 gnutls_strerror (ret));
5274 daemon->priority_cache =
NULL;
5278 #ifdef HAVE_MESSAGES 5282 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5287 #if GNUTLS_VERSION_MAJOR < 3 5288 #ifdef HAVE_MESSAGES 5291 "MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n"));
5296 gnutls_certificate_retrieve_function2 *);
5298 daemon->cert_callback = pgcrf;
5300 #ifdef HAVE_MESSAGES 5303 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5309 #if GNUTLS_VERSION_NUMBER < 0x030603 5310 #ifdef HAVE_MESSAGES 5313 "MHD_OPTION_HTTPS_CERT_CALLBACK2 requires building MHD with GnuTLS >= 3.6.3\n"));
5317 pgcrf2 = va_arg (ap,
5318 gnutls_certificate_retrieve_function3 *);
5320 daemon->cert_callback2 = pgcrf2;
5322 #ifdef HAVE_MESSAGES 5325 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5331 #ifdef DAUTH_SUPPORT 5333 daemon->digest_auth_rand_size = va_arg (ap,
5335 daemon->digest_auth_random = va_arg (ap,
5339 daemon->nonce_nc_size = va_arg (ap,
5346 #ifdef HAVE_MESSAGES 5348 _ (
"MHD_OPTION_LISTEN_SOCKET specified for daemon " 5349 "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
5358 #ifdef HAVE_MESSAGES 5359 daemon->custom_error_log = va_arg (ap,
5361 daemon->custom_error_log_cls = va_arg (ap,
5370 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5372 daemon->thread_stack_size = va_arg (ap,
5378 daemon->fastopen_queue_size = va_arg (ap,
5382 #ifdef HAVE_MESSAGES 5384 _ (
"TCP fastopen is not supported on this platform\n"));
5390 unsigned int) ? 1 : -1;
5398 #ifdef HAVE_MESSAGES 5403 _ (
"Flag MHD_USE_PEDANTIC_CHECKS is ignored because " 5404 "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n"));
5422 (
size_t) oa[i].
value,
5439 (
unsigned int) oa[i].
value,
5444 #ifdef HTTPS_SUPPORT 5449 (gnutls_credentials_type_t) oa[i].
value,
5500 (
void *) oa[i].
value,
5510 (
size_t) oa[i].
value,
5527 #ifdef HTTPS_SUPPORT 5529 #if GNUTLS_VERSION_MAJOR >= 3 5530 daemon->cred_callback = va_arg (ap,
5532 daemon->cred_callback_cls = va_arg (ap,
5538 "MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3\n"),
5544 #ifdef HAVE_MESSAGES 5552 "MHD HTTPS option %d passed to MHD compiled without HTTPS support\n"),
5559 "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n"),
5570 #ifdef EPOLL_SUPPORT 5576 #ifndef HAVE_MESSAGES 5580 #ifdef USE_EPOLL_CREATE1 5581 fd = epoll_create1 (EPOLL_CLOEXEC);
5583 fd = epoll_create (MAX_EVENTS);
5587 #ifdef HAVE_MESSAGES 5589 _ (
"Call to epoll_create1 failed: %s\n"),
5594 #if ! defined(USE_EPOLL_CREATE1) 5597 #ifdef HAVE_MESSAGES 5599 _ (
"Failed to set noninheritable mode on epoll FD.\n"));
5617 setup_epoll_to_listen (
struct MHD_Daemon *daemon)
5619 struct epoll_event event;
5622 daemon->epoll_fd = setup_epoll_fd (daemon);
5623 if (-1 == daemon->epoll_fd)
5625 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5628 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
5636 event.events = EPOLLIN;
5637 event.data.ptr = daemon;
5638 if (0 != epoll_ctl (daemon->epoll_fd,
5643 #ifdef HAVE_MESSAGES 5645 _ (
"Call to epoll_ctl failed: %s\n"),
5650 daemon->listen_socket_in_epoll =
true;
5651 if (MHD_ITC_IS_VALID_ (daemon->
itc))
5653 event.events = EPOLLIN;
5654 event.data.ptr = (
void *) epoll_itc_marker;
5655 if (0 != epoll_ctl (daemon->epoll_fd,
5657 MHD_itc_r_fd_ (daemon->
itc),
5660 #ifdef HAVE_MESSAGES 5662 _ (
"Call to epoll_ctl failed: %s\n"),
5708 struct sockaddr_in servaddr4;
5710 struct sockaddr_in6 servaddr6;
5712 const struct sockaddr *servaddr =
NULL;
5714 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5731 #ifndef EPOLL_SUPPORT 5735 #ifndef HTTPS_SUPPORT 5739 #ifndef TCP_FASTOPEN 5745 #ifdef UPGRADE_SUPPORT 5781 #if defined(EPOLL_SUPPORT) 5783 #elif defined(HAVE_POLL) 5792 #if defined(EPOLL_SUPPORT) 5802 #ifdef EPOLL_SUPPORT 5803 daemon->epoll_fd = -1;
5804 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5805 daemon->epoll_upgrade_fd = -1;
5809 #ifdef HTTPS_SUPPORT 5810 daemon->priority_cache =
NULL;
5813 gnutls_priority_init (&daemon->priority_cache,
5824 daemon->
port = port;
5835 MHD_itc_set_invalid_ (daemon->
itc);
5841 #ifdef HAVE_MESSAGES 5843 daemon->custom_error_log_cls = stderr;
5848 #ifdef HAVE_MESSAGES 5851 "Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with " 5852 "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD " 5853 "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"));
5861 #ifdef HAVE_LISTEN_SHUTDOWN 5866 #ifdef DAUTH_SUPPORT 5867 daemon->digest_auth_rand_size = 0;
5868 daemon->digest_auth_random =
NULL;
5869 daemon->nonce_nc_size = 4;
5871 #ifdef HTTPS_SUPPORT 5874 daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
5883 #ifdef HTTPS_SUPPORT 5885 (
NULL != daemon->priority_cache) )
5886 gnutls_priority_deinit (daemon->priority_cache);
5897 #ifdef HAVE_MESSAGES 5899 _ (
"Using debug build of libmicrohttpd.\n") );
5904 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5909 if (! MHD_itc_init_ (daemon->
itc))
5911 #ifdef HAVE_MESSAGES 5913 _ (
"Failed to create inter-thread communication channel: %s\n"),
5914 MHD_itc_last_strerror_ ());
5916 #ifdef HTTPS_SUPPORT 5917 if (
NULL != daemon->priority_cache)
5918 gnutls_priority_deinit (daemon->priority_cache);
5927 #ifdef HAVE_MESSAGES 5930 "file descriptor for inter-thread communication channel exceeds maximum value\n"));
5933 #ifdef HTTPS_SUPPORT 5934 if (
NULL != daemon->priority_cache)
5935 gnutls_priority_deinit (daemon->priority_cache);
5942 #ifdef DAUTH_SUPPORT 5943 if (daemon->nonce_nc_size > 0)
5945 if ( ( (
size_t) (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc)))
5946 /
sizeof(
struct MHD_NonceNc) != daemon->nonce_nc_size)
5948 #ifdef HAVE_MESSAGES 5950 _ (
"Specified value for NC_SIZE too large\n"));
5952 #ifdef HTTPS_SUPPORT 5954 gnutls_priority_deinit (daemon->priority_cache);
5959 daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc));
5960 if (
NULL == daemon->nnc)
5962 #ifdef HAVE_MESSAGES 5964 _ (
"Failed to allocate memory for nonce-nc map: %s\n"),
5967 #ifdef HTTPS_SUPPORT 5969 gnutls_priority_deinit (daemon->priority_cache);
5976 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5977 if (! MHD_mutex_init_ (&daemon->nnc_lock))
5979 #ifdef HAVE_MESSAGES 5981 _ (
"MHD failed to initialize nonce-nc mutex\n"));
5983 #ifdef HTTPS_SUPPORT 5985 gnutls_priority_deinit (daemon->priority_cache);
5995 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5999 #ifdef HAVE_MESSAGES 6002 "MHD thread pooling only works with MHD_USE_INTERNAL_POLLING_THREAD\n"));
6014 domain = (*pflags &
MHD_USE_IPv6) ? PF_INET6 : PF_INET;
6024 #ifdef HAVE_MESSAGES 6026 _ (
"Failed to create socket for listening: %s\n"),
6035 #ifndef MHD_WINSOCK_SOCKETS 6040 if (0 > setsockopt (listen_fd,
6043 (
void*) &on,
sizeof (on)))
6045 #ifdef HAVE_MESSAGES 6047 _ (
"setsockopt failed: %s\n"),
6056 #ifndef MHD_WINSOCK_SOCKETS 6059 if (0 > setsockopt (listen_fd,
6062 (
void*) &on,
sizeof (on)))
6064 #ifdef HAVE_MESSAGES 6066 _ (
"setsockopt failed: %s\n"),
6076 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT) 6077 if (0 > setsockopt (listen_fd,
6079 #ifndef MHD_WINSOCK_SOCKETS
6087 #ifdef HAVE_MESSAGES 6089 _ (
"setsockopt failed: %s\n"),
6097 #ifdef HAVE_MESSAGES 6100 "Cannot allow listening address reuse: SO_REUSEPORT not defined\n"));
6113 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \ 6114 (defined(__sun) && defined(SO_EXCLBIND)) 6115 if (0 > setsockopt (listen_fd,
6117 #ifdef SO_EXCLUSIVEADDRUSE
6118 SO_EXCLUSIVEADDRUSE,
6125 #ifdef HAVE_MESSAGES 6127 _ (
"setsockopt failed: %s\n"),
6132 #elif defined(MHD_WINSOCK_SOCKETS) 6133 #ifdef HAVE_MESSAGES 6136 "Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n"));
6145 addrlen =
sizeof (
struct sockaddr_in6);
6148 addrlen =
sizeof (
struct sockaddr_in);
6149 if (
NULL == servaddr)
6154 #ifdef IN6ADDR_ANY_INIT 6155 static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
6159 sizeof (
struct sockaddr_in6));
6160 servaddr6.sin6_family = AF_INET6;
6161 servaddr6.sin6_port = htons (port);
6162 #ifdef IN6ADDR_ANY_INIT 6163 servaddr6.sin6_addr = static_in6any;
6165 #if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN 6166 servaddr6.sin6_len =
sizeof (
struct sockaddr_in6);
6168 servaddr = (
struct sockaddr *) &servaddr6;
6175 sizeof (
struct sockaddr_in));
6176 servaddr4.sin_family = AF_INET;
6177 servaddr4.sin_port = htons (port);
6178 if (0 != INADDR_ANY)
6179 servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
6180 #if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN 6181 servaddr4.sin_len =
sizeof (
struct sockaddr_in);
6183 servaddr = (
struct sockaddr *) &servaddr4;
6198 if (0 > setsockopt (listen_fd,
6199 IPPROTO_IPV6, IPV6_V6ONLY,
6200 (
const void *) &v6_only,
6203 #ifdef HAVE_MESSAGES 6205 _ (
"setsockopt failed: %s\n"),
6212 if (-1 == bind (listen_fd, servaddr, addrlen))
6214 #ifdef HAVE_MESSAGES 6216 _ (
"Failed to bind to port %u: %s\n"),
6217 (
unsigned int) port,
6226 if (0 == daemon->fastopen_queue_size)
6227 daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
6228 if (0 != setsockopt (listen_fd,
6231 (
const void*) &daemon->fastopen_queue_size,
6232 sizeof (daemon->fastopen_queue_size)))
6234 #ifdef HAVE_MESSAGES 6236 _ (
"setsockopt failed: %s\n"),
6242 if (listen (listen_fd,
6245 #ifdef HAVE_MESSAGES 6247 _ (
"Failed to listen for connections: %s\n"),
6259 #ifdef HAVE_GETSOCKNAME 6260 if ( (0 == daemon->
port) &&
6263 struct sockaddr_storage bindaddr;
6267 sizeof (
struct sockaddr_storage));
6268 addrlen =
sizeof (
struct sockaddr_storage);
6269 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 6270 bindaddr.ss_len = addrlen;
6272 if (0 != getsockname (listen_fd,
6273 (
struct sockaddr *) &bindaddr,
6276 #ifdef HAVE_MESSAGES 6278 _ (
"Failed to get listen port number: %s\n"),
6282 #ifdef MHD_POSIX_SOCKETS 6283 else if (
sizeof (bindaddr) < addrlen)
6286 #ifdef HAVE_MESSAGES 6289 "Failed to get listen port number (`struct sockaddr_storage` too small!?)\n"));
6293 else if (0 == addrlen)
6303 switch (bindaddr.ss_family)
6307 struct sockaddr_in *s4 = (
struct sockaddr_in *) &bindaddr;
6309 daemon->
port = ntohs (s4->sin_port);
6315 struct sockaddr_in6 *s6 = (
struct sockaddr_in6 *) &bindaddr;
6317 daemon->
port = ntohs (s6->sin6_port);
6328 #ifdef HAVE_MESSAGES 6330 _ (
"Unknown address family!\n"));
6341 #ifdef HAVE_MESSAGES 6343 _ (
"Failed to set nonblocking mode on listening socket: %s\n"),
6347 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6364 #ifdef HAVE_MESSAGES 6366 _ (
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
6374 #ifdef EPOLL_SUPPORT 6376 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6383 #ifdef HAVE_MESSAGES 6386 "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
6390 if (
MHD_YES != setup_epoll_to_listen (daemon))
6395 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6398 #ifdef HAVE_MESSAGES 6400 _ (
"MHD failed to initialize IP connection limit mutex\n"));
6411 #ifdef HAVE_MESSAGES 6413 _ (
"MHD failed to initialize IP connection limit mutex\n"));
6415 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6425 #ifdef HTTPS_SUPPORT 6428 (0 != MHD_TLS_init (daemon)) )
6430 #ifdef HAVE_MESSAGES 6432 _ (
"Failed to initialize TLS support\n"));
6436 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6444 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6453 "MHD-listen" :
"MHD-single",
6454 daemon->thread_stack_size,
6458 #ifdef HAVE_MESSAGES 6460 _ (
"Failed to create listen thread: %s\n"),
6494 memcpy (d, daemon,
sizeof (
struct MHD_Daemon));
6504 if (! MHD_itc_init_ (d->
itc))
6506 #ifdef HAVE_MESSAGES 6509 "Failed to create worker inter-thread communication channel: %s\n"),
6510 MHD_itc_last_strerror_ () );
6518 #ifdef HAVE_MESSAGES 6521 "File descriptor for worker inter-thread communication channel exceeds maximum value\n"));
6528 MHD_itc_set_invalid_ (d->
itc);
6534 if (i < leftover_conns)
6536 #ifdef EPOLL_SUPPORT 6538 (
MHD_YES != setup_epoll_to_listen (d)) )
6544 #ifdef HAVE_MESSAGES 6546 _ (
"MHD failed to initialize cleanup connection mutex\n"));
6554 daemon->thread_stack_size,
6558 #ifdef HAVE_MESSAGES 6560 _ (
"Failed to create pool thread: %s\n"),
6572 #ifdef HTTPS_SUPPORT 6575 daemon->https_key_password =
NULL;
6580 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6608 #ifdef EPOLL_SUPPORT 6609 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6610 if (daemon->upgrade_fd_in_epoll)
6612 if (0 != epoll_ctl (daemon->epoll_fd,
6614 daemon->epoll_upgrade_fd,
6616 MHD_PANIC (
_ (
"Failed to remove FD from epoll set\n"));
6617 daemon->upgrade_fd_in_epoll =
false;
6620 if (-1 != daemon->epoll_fd)
6621 close (daemon->epoll_fd);
6622 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6623 if (-1 != daemon->epoll_upgrade_fd)
6624 close (daemon->epoll_upgrade_fd);
6627 #ifdef DAUTH_SUPPORT 6629 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6633 #ifdef HTTPS_SUPPORT 6636 gnutls_priority_deinit (daemon->priority_cache);
6637 if (daemon->x509_cred)
6638 gnutls_certificate_free_credentials (daemon->x509_cred);
6639 if (daemon->psk_cred)
6640 gnutls_psk_free_server_credentials (daemon->psk_cred);
6643 if (MHD_ITC_IS_VALID_ (daemon->
itc))
6664 #ifdef UPGRADE_SUPPORT 6667 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6668 struct MHD_UpgradeResponseHandle *urh;
6669 struct MHD_UpgradeResponseHandle *urhn;
6672 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6678 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
6685 urh->clean_ready =
true;
6702 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6705 #ifdef UPGRADE_SUPPORT 6711 while (
NULL != susp)
6713 if (
NULL == susp->urh)
6715 "MHD_stop_daemon() called while we have suspended connections.\n"));
6716 #ifdef HTTPS_SUPPORT 6717 else if (used_tls &&
6719 (! susp->urh->clean_ready) )
6720 shutdown (susp->urh->app.socket,
6725 #ifdef HAVE_MESSAGES 6726 if (! susp->urh->was_closed)
6729 "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
6731 susp->urh->was_closed =
true;
6748 "MHD_stop_daemon() called while we have suspended connections.\n"));
6753 #if MHD_WINSOCK_SOCKETS 6756 (! MHD_itc_activate_ (
daemon->
itc,
"e")) )
6758 "Failed to signal shutdown via inter-thread communication channel"));
6762 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6772 if (! MHD_join_thread_ (pos->
pid.handle))
6787 #ifdef UPGRADE_SUPPORT 6802 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6823 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6836 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6851 "Failed to signal shutdown via inter-thread communication channel."));
6856 #ifdef HAVE_LISTEN_SHUTDOWN 6859 (void) shutdown (
fd,
6869 #ifdef EPOLL_SUPPORT 6871 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6879 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6889 "Failed to signal shutdown via inter-thread communication channel"));
6893 #ifdef HAVE_LISTEN_SHUTDOWN 6897 (void) shutdown (
fd,
6905 if (! MHD_join_thread_ (
daemon->
pid.handle))
6920 #ifdef EPOLL_SUPPORT 6922 (-1 !=
daemon->epoll_fd) )
6924 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6926 (-1 !=
daemon->epoll_upgrade_fd) )
6931 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6944 #ifdef HTTPS_SUPPORT 6945 if (
daemon->have_dhparams)
6947 gnutls_dh_params_deinit (
daemon->https_mem_dhparams);
6948 daemon->have_dhparams =
false;
6952 gnutls_priority_deinit (
daemon->priority_cache);
6954 gnutls_certificate_free_credentials (
daemon->x509_cred);
6956 gnutls_psk_free_server_credentials (
daemon->psk_cred);
6960 #ifdef DAUTH_SUPPORT 6962 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6966 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 7000 #ifdef EPOLL_SUPPORT 7011 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 7069 #ifdef PACKAGE_VERSION 7070 return PACKAGE_VERSION;
7072 static char ver[12] =
"\0\0\0\0\0\0\0\0\0\0\0";
7075 int res = MHD_snprintf_ (ver,
7081 if ((0 >= res) || (
sizeof(ver) <= res))
7106 #ifdef HAVE_MESSAGES 7112 #ifdef HTTPS_SUPPORT 7118 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3 7124 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030603 7136 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) 7148 #ifdef EPOLL_SUPPORT 7154 #ifdef HAVE_LISTEN_SHUTDOWN 7160 #ifdef _MHD_ITC_SOCKETPAIR 7172 #ifdef BAUTH_SUPPORT 7178 #ifdef DAUTH_SUPPORT 7184 #ifdef HAVE_POSTPROCESSOR 7190 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111 7196 #if defined(HAVE_PREAD64) || defined(_WIN32) 7198 #elif defined(HAVE_PREAD) 7199 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
7200 #elif defined(HAVE_LSEEK64) 7203 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
7206 #if defined(MHD_USE_THREAD_NAME_) 7212 #if defined(UPGRADE_SUPPORT) 7218 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32) 7224 #ifdef MHD_USE_GETSOCKNAME 7230 #if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || \ 7231 defined (MSG_NOSIGNAL) 7237 #ifdef _MHD_HAVE_SENDFILE 7243 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 7254 #ifdef MHD_HTTPS_REQUIRE_GRYPT 7255 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600 7256 #if defined(MHD_USE_POSIX_THREADS) 7257 GCRY_THREAD_OPTION_PTHREAD_IMPL;
7258 #elif defined(MHD_W32_MUTEX_) 7261 gcry_w32_mutex_init (
void **ppmtx)
7263 *ppmtx = malloc (
sizeof (MHD_mutex_));
7267 if (! MHD_mutex_init_ ((MHD_mutex_*) *ppmtx))
7279 gcry_w32_mutex_destroy (
void **ppmtx)
7281 int res = (MHD_mutex_destroy_ ((MHD_mutex_*) *ppmtx)) ? 0 : EINVAL;
7288 gcry_w32_mutex_lock (
void **ppmtx)
7290 return MHD_mutex_lock_ ((MHD_mutex_*) *ppmtx) ? 0 : EINVAL;
7295 gcry_w32_mutex_unlock (
void **ppmtx)
7297 return MHD_mutex_unlock_ ((MHD_mutex_*) *ppmtx) ? 0 : EINVAL;
7301 static struct gcry_thread_cbs gcry_threads_w32 = {
7302 (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
7303 NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
7304 gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
7318 #if defined(MHD_WINSOCK_SOCKETS) 7325 #if defined(MHD_WINSOCK_SOCKETS) 7326 if (0 != WSAStartup (MAKEWORD (2, 2), &wsd))
7327 MHD_PANIC (
_ (
"Failed to initialize winsock\n"));
7328 mhd_winsock_inited_ = 1;
7329 if ((2 != LOBYTE (wsd.wVersion)) && (2 != HIBYTE (wsd.wVersion)))
7330 MHD_PANIC (
_ (
"Winsock version 2.2 is not available\n"));
7332 #ifdef HTTPS_SUPPORT 7333 #ifdef MHD_HTTPS_REQUIRE_GRYPT 7334 #if GCRYPT_VERSION_NUMBER < 0x010600 7335 #if defined(MHD_USE_POSIX_THREADS) 7336 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7337 &gcry_threads_pthread))
7338 MHD_PANIC (
_ (
"Failed to initialise multithreading in libgcrypt\n"));
7339 #elif defined(MHD_W32_MUTEX_) 7340 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7342 MHD_PANIC (
_ (
"Failed to initialise multithreading in libgcrypt\n"));
7344 gcry_check_version (
NULL);
7346 if (
NULL == gcry_check_version (
"1.6.0"))
7348 "libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n"));
7351 gnutls_global_init ();
7354 #ifdef HAVE_FREEBSD_SENDFILE 7355 MHD_conn_init_static_ ();
7364 #ifdef HTTPS_SUPPORT 7365 gnutls_global_deinit ();
7367 #if defined(MHD_WINSOCK_SOCKETS) 7368 if (mhd_winsock_inited_)
7375 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
#define MHD_send_(s, b, l)
unsigned int per_ip_connection_limit
void * unescape_callback_cls
volatile int global_init_count
void MHD_connection_handle_write(struct MHD_Connection *connection)
_MHD_EXTERN struct MHD_Daemon * MHD_start_daemon_va(unsigned int flags, uint16_t port, MHD_AcceptPolicyCallback apc, void *apc_cls, MHD_AccessHandlerCallback dh, void *dh_cls, va_list ap)
Header for platform missing functions.
static int parse_options(struct MHD_Daemon *daemon, const struct sockaddr **servaddr,...)
_MHD_EXTERN const char * MHD_get_version(void)
bool data_already_pending
void MHD_update_last_activity_(struct MHD_Connection *connection)
int(* MHD_PskServerCredentialsCallback)(void *cls, const struct MHD_Connection *connection, const char *username, void **psk, size_t *psk_size)
#define MHD_SYS_select_(n, r, w, e, t)
struct sockaddr_storage addr
struct MHD_Connection * cleanup_head
enum MHD_CONNECTION_STATE state
static int call_handlers(struct MHD_Connection *con, bool read_ready, bool write_ready, bool force_close)
void MHD_init_mem_pools_(void)
enum MHD_ConnectionEventLoopInfo event_loop_info
void(* VfprintfFunctionPointerType)(void *cls, const char *format, va_list va)
static void MHD_default_logger_(void *cls, const char *fm, va_list ap)
#define MHD_ITC_IS_INVALID_(itc)
struct MHD_Connection * prevX
MHD_thread_handle_ID_ pid
#define MHD_mutex_unlock_chk_(pmutex)
time_t connection_timeout
Methods for managing connections.
_MHD_EXTERN int MHD_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
#define MHD_socket_get_error_()
internal monotonic clock functions implementations
#define MHD_mutex_destroy_chk_(pmutex)
void * MHD_calloc_(size_t nelem, size_t elsize)
#define MHD_socket_strerr_(err)
MHD_socket MHD_socket_create_listen_(int pf)
#define EDLL_insert(head, tail, element)
_MHD_EXTERN int MHD_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen)
struct MHD_Response * response
struct MHD_Connection * manual_timeout_head
void *(* LogCallback)(void *cls, const char *uri, struct MHD_Connection *con)
#define MHD_MAX_CONNECTIONS_DEFAULT
MHD_thread_handle_ID_ pid
void * tdelete(const void *__restrict vkey, void **__restrict vrootp, int(*compar)(const void *, const void *))
time_t MHD_monotonic_sec_counter(void)
int MHD_add_to_fd_set_(MHD_socket fd, fd_set *set, MHD_socket *max_fd, unsigned int fd_setsize)
static void mhd_panic_std(void *cls, const char *file, unsigned int line, const char *reason)
MHD_AccessHandlerCallback default_handler
static void MHD_ip_count_lock(struct MHD_Daemon *daemon)
void MHD_suspend_connection(struct MHD_Connection *connection)
static size_t unescape_wrapper(void *cls, struct MHD_Connection *connection, char *val)
#define MHD_SCKT_ERR_IS_EAGAIN_(err)
_MHD_EXTERN struct MHD_Daemon * MHD_start_daemon(unsigned int flags, uint16_t port, MHD_AcceptPolicyCallback apc, void *apc_cls, MHD_AccessHandlerCallback dh, void *dh_cls,...)
#define MHD_SCKT_LAST_ERR_IS_(code)
static int parse_options_va(struct MHD_Daemon *daemon, const struct sockaddr **servaddr, va_list ap)
Methods for managing response objects.
_MHD_EXTERN void MHD_set_panic_func(MHD_PanicCallback cb, void *cls)
#define MHD_UNSIGNED_LONG_LONG
void * uri_log_callback_cls
struct MHD_Daemon * daemon
static struct MHD_Daemon * MHD_get_master(struct MHD_Daemon *daemon)
void(* MHD_PanicCallback)(void *cls, const char *file, unsigned int line, const char *reason)
#define MHD_TEST_ALLOW_SUSPEND_RESUME
int listening_address_reuse
MHD_mutex_ per_ip_connection_mutex
#define MHD_TYPE_IS_SIGNED_(type)
MHD_NotifyConnectionCallback notify_connection
Header for platform-independent inter-thread communication.
struct MHD_Connection * next
void * tsearch(const void *vkey, void **vrootp, int(*compar)(const void *, const void *))
#define DLL_insert(head, tail, element)
static int MHD_ip_addr_compare(const void *a1, const void *a2)
#define MHD_socket_last_strerr_()
struct MHD_Connection * connections_tail
struct MHD_Daemon * worker_pool
_MHD_EXTERN void MHD_stop_daemon(struct MHD_Daemon *daemon)
static int MHD_ip_addr_to_key(const struct sockaddr *addr, socklen_t addrlen, struct MHD_IPCount *key)
struct MemoryPool * MHD_pool_create(size_t max)
#define MHD_INVALID_SOCKET
internal shared structures
static int MHD_select(struct MHD_Daemon *daemon, int may_block)
#define MHD_POOL_SIZE_DEFAULT
void MHD_set_https_callbacks(struct MHD_Connection *connection)
#define MHD_SCKT_SEND_MAX_SIZE_
unsigned int connection_limit
unsigned int worker_pool_size
struct MHD_Connection * connections_head
_MHD_EXTERN int MHD_run_from_select(struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set)
#define MHD_socket_close_chk_(fd)
LogCallback uri_log_callback
void MHD_connection_handle_read(struct MHD_Connection *connection)
void MHD_connection_mark_closed_(struct MHD_Connection *connection)
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode rtc)
time_t connection_timeout
#define MHD_SCKT_ERR_IS_(err, code)
static int MHD_ip_limit_add(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Methods for managing connections.
struct MHD_Daemon * master
#define EDLL_remove(head, tail, element)
struct MHD_Connection * manual_timeout_tail
static void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
struct MHD_Connection * prev
#define TIMEVAL_TV_SEC_MAX
#define DLL_remove(head, tail, element)
#define MHD_strerror_(errnum)
void * tfind(const void *vkey, void *const *vrootp, int(*compar)(const void *, const void *))
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ thread_main_handle_connection(void *data)
static int internal_get_fdset2(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd, unsigned int fd_setsize)
struct MHD_Connection * normal_timeout_head
#define _MHD_SYS_DEFAULT_FD_SETSIZE
void MHD_pool_destroy(struct MemoryPool *pool)
UnescapeCallback unescape_callback
_MHD_EXTERN void MHD_free(void *ptr)
#define MAYBE_SOCK_NOSIGPIPE
void internal_suspend_connection_(struct MHD_Connection *connection)
void MHD_connection_finish_forward_(struct MHD_Connection *connection) MHD_NONNULL(1)
unsigned int listen_backlog_size
#define XDLL_remove(head, tail, element)
void MHD_monotonic_sec_counter_finish(void)
#define _SET_INIT_AND_DEINIT_FUNCS(FI, FD)
static int internal_run_from_select(struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set)
struct MHD_Connection * suspended_connections_tail
#define MHD_create_named_thread_(t, n, s, r, a)
MHD_AcceptPolicyCallback apc
struct MHD_Connection * cleanup_tail
int MHD_connection_handle_idle(struct MHD_Connection *connection)
static int resume_suspended_connections(struct MHD_Daemon *daemon)
#define MHD_itc_destroy_chk_(itc)
static int internal_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen, bool external_add, bool non_blck)
int(* MHD_AccessHandlerCallback)(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls)
static int MHD_poll(struct MHD_Daemon *daemon, int may_block)
static void MHD_cleanup_connections(struct MHD_Daemon *daemon)
int MHD_socket_set_nodelay_(MHD_socket sock, bool on)
void MHD_monotonic_sec_counter_init(void)
#define MHD_recv_(s, b, l)
static int MHD_accept_connection(struct MHD_Daemon *daemon)
_MHD_EXTERN int MHD_get_fdset(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd)
static void MHD_ip_count_unlock(struct MHD_Daemon *daemon)
void(* MHD_RequestCompletedCallback)(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
struct MHD_Connection * normal_timeout_tail
void MHD_check_global_init_(void)
MHD_RequestCompletedCallback notify_completed
#define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)
#define MHD_mutex_lock_chk_(pmutex)
#define MHD_SCKT_FD_FITS_FDSET_(fd, pset)
static void close_connection(struct MHD_Connection *pos)
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
void * notify_completed_cls
_MHD_EXTERN int MHD_run(struct MHD_Daemon *daemon)
int MHD_socket_nonblocking_(MHD_socket sock)
size_t(* UnescapeCallback)(void *cls, struct MHD_Connection *conn, char *uri)
void * notify_connection_cls
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ MHD_polling_thread(void *cls)
MHD_PanicCallback mhd_panic
#define XDLL_insert(head, tail, element)
#define MHD_UNSIGNED_LONG_LONG_PRINTF
void MHD_resume_connection(struct MHD_Connection *connection)
_MHD_EXTERN int MHD_is_feature_supported(enum MHD_FEATURE feature)
struct MHD_Connection * suspended_connections_head
void * per_ip_connection_count
size_t read_buffer_offset
_MHD_EXTERN int MHD_get_fdset2(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd, unsigned int fd_setsize)
void * default_handler_cls
#define MHD_SCKT_ERR_IS_EINTR_(err)
MHD_mutex_ cleanup_connection_mutex
_MHD_EXTERN MHD_socket MHD_quiesce_daemon(struct MHD_Daemon *daemon)
int(* MHD_AcceptPolicyCallback)(void *cls, const struct sockaddr *addr, socklen_t addrlen)
void(* MHD_NotifyConnectionCallback)(void *cls, struct MHD_Connection *connection, void **socket_context, enum MHD_ConnectionNotificationCode toe)
_MHD_EXTERN const union MHD_DaemonInfo * MHD_get_daemon_info(struct MHD_Daemon *daemon, enum MHD_DaemonInfoType info_type,...)
_MHD_EXTERN size_t MHD_http_unescape(char *val)
#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)
static void close_all_connections(struct MHD_Daemon *daemon)
limits values definitions
int MHD_socket_noninheritable_(MHD_socket sock)
#define MAYBE_SOCK_NONBLOCK
MHD_FLAG
Flags for the struct MHD_Daemon.
int MHD_socket_buffering_reset_(MHD_socket sock)
#define MAYBE_SOCK_CLOEXEC