29 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 30 #include "mhd_threads.h" 39 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 40 #include "mhd_locks.h" 54 #ifdef MHD_HTTPS_REQUIRE_GRYPT 59 #if defined(_WIN32) && ! defined(__CYGWIN__) 60 #ifndef WIN32_LEAN_AND_MEAN 61 #define WIN32_LEAN_AND_MEAN 1 69 #ifdef MHD_POSIX_SOCKETS 70 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 4) 72 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 2) 78 #define MHD_POOL_SIZE_DEFAULT (32 * 1024) 84 #define DEBUG_CLOSE MHD_NO 90 #define DEBUG_CONNECT MHD_NO 140 _(
"Fatal error in GNU libmicrohttpd %s:%u: %s\n"),
170 #if defined(_WIN32) && ! defined(__CYGWIN__) 174 static int mhd_winsock_inited_ = 0;
177 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED 182 #define MHD_check_global_init_() (void)0 189 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 190 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 194 MHD_MUTEX_STATIC_DEFN_INIT_(global_init_mutex_);
206 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 207 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 213 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 214 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 260 struct in6_addr ipv6;
279 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 295 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 318 offsetof (
struct MHD_IPCount,
334 struct MHD_IPCount *key)
341 if (
sizeof (
struct sockaddr_in) == addrlen)
343 const struct sockaddr_in *addr4 = (
const struct sockaddr_in*) addr;
345 key->family = AF_INET;
346 memcpy (&key->addr.ipv4,
348 sizeof(addr4->sin_addr));
354 if (
sizeof (
struct sockaddr_in6) == addrlen)
356 const struct sockaddr_in6 *addr6 = (
const struct sockaddr_in6*) addr;
358 key->family = AF_INET6;
359 memcpy (&key->addr.ipv6,
361 sizeof(addr6->sin6_addr));
384 const struct sockaddr *addr,
387 struct MHD_IPCount *key;
397 if (
NULL == (key = malloc (
sizeof(*key))))
418 _(
"Failed to add IP connection count node\n"));
428 key = (
struct MHD_IPCount *) node;
450 const struct sockaddr *addr,
453 struct MHD_IPCount search_key;
454 struct MHD_IPCount *found_key;
476 MHD_PANIC (
_(
"Failed to find previously-added IP address\n"));
478 found_key = (
struct MHD_IPCount *) *nodep;
480 if (0 == found_key->count)
482 MHD_PANIC (
_(
"Previously-added IP address had counter of zero\n"));
485 if (0 == --found_key->count)
505 MHD_init_daemon_certificate (
struct MHD_Daemon *daemon)
511 #if GNUTLS_VERSION_MAJOR >= 3 512 if (
NULL != daemon->cert_callback)
514 gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
515 daemon->cert_callback);
518 if (
NULL != daemon->https_mem_trust)
520 cert.data = (
unsigned char *) daemon->https_mem_trust;
521 cert.size = strlen (daemon->https_mem_trust);
522 if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred,
524 GNUTLS_X509_FMT_PEM) < 0)
528 "Bad trust certificate format\n");
534 if (daemon->have_dhparams)
536 gnutls_certificate_set_dh_params (daemon->x509_cred,
537 daemon->https_mem_dhparams);
540 if ( (
NULL != daemon->https_mem_cert) &&
541 (
NULL != daemon->https_mem_key) )
543 key.data = (
unsigned char *) daemon->https_mem_key;
544 key.size = strlen (daemon->https_mem_key);
545 cert.data = (
unsigned char *) daemon->https_mem_cert;
546 cert.size = strlen (daemon->https_mem_cert);
548 if (
NULL != daemon->https_key_password) {
549 #if GNUTLS_VERSION_NUMBER >= 0x030111 550 ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
554 daemon->https_key_password,
559 _(
"Failed to setup x509 certificate/key: pre 3.X.X version " \
560 "of GnuTLS does not support setting key password"));
566 ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
569 GNUTLS_X509_FMT_PEM);
573 "GnuTLS failed to setup x509 certificate/key: %s\n",
574 gnutls_strerror (ret));
578 #if GNUTLS_VERSION_MAJOR >= 3 579 if (
NULL != daemon->cert_callback)
584 "You need to specify a certificate and key location\n");
598 switch (daemon->cred_type)
600 case GNUTLS_CRD_CERTIFICATE:
602 gnutls_certificate_allocate_credentials (&daemon->x509_cred))
603 return GNUTLS_E_MEMORY_ERROR;
604 return MHD_init_daemon_certificate (daemon);
607 gnutls_psk_allocate_server_credentials (&daemon->psk_cred))
608 return GNUTLS_E_MEMORY_ERROR;
613 _(
"Error: invalid credentials type %d specified.\n"),
656 fd_set *write_fd_set,
657 fd_set *except_fd_set,
669 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 683 urh_to_fdset (
struct MHD_UpgradeResponseHandle *urh,
688 unsigned int fd_setsize)
690 const MHD_socket conn_sckt = urh->connection->socket_fd;
698 if ( (urh->in_buffer_used < urh->in_buffer_size) &&
704 if ( (0 != urh->out_buffer_used) &&
713 ((0 != urh->in_buffer_size) ||
714 (0 != urh->out_buffer_size) ||
715 (0 != urh->out_buffer_used)))
723 if ( (urh->out_buffer_used < urh->out_buffer_size) &&
729 if ( (0 != urh->in_buffer_used) &&
738 ((0 != urh->out_buffer_size) ||
739 (0 != urh->in_buffer_size) ||
740 (0 != urh->in_buffer_used)))
761 urh_from_fdset (
struct MHD_UpgradeResponseHandle *urh,
766 const MHD_socket conn_sckt = urh->connection->socket_fd;
775 if (FD_ISSET (conn_sckt, rs))
777 if (FD_ISSET (conn_sckt, ws))
779 if (FD_ISSET (conn_sckt, es))
784 if (FD_ISSET (mhd_sckt, rs))
786 if (FD_ISSET (mhd_sckt, ws))
788 if (FD_ISSET (mhd_sckt, es))
804 urh_update_pollfd (
struct MHD_UpgradeResponseHandle *urh,
810 if (urh->in_buffer_used < urh->in_buffer_size)
811 p[0].events |= POLLIN;
812 if (0 != urh->out_buffer_used)
813 p[0].events |= POLLOUT;
818 ((0 != urh->in_buffer_size) ||
819 (0 != urh->out_buffer_size) ||
820 (0 != urh->out_buffer_used)))
821 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
823 if (urh->out_buffer_used < urh->out_buffer_size)
824 p[1].events |= POLLIN;
825 if (0 != urh->in_buffer_used)
826 p[1].events |= POLLOUT;
831 ((0 != urh->out_buffer_size) ||
832 (0 != urh->in_buffer_size) ||
833 (0 != urh->in_buffer_used)))
834 p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
845 urh_to_pollfd (
struct MHD_UpgradeResponseHandle *urh,
848 p[0].fd = urh->connection->socket_fd;
849 p[1].fd = urh->mhd.socket;
850 urh_update_pollfd (urh,
861 urh_from_pollfd (
struct MHD_UpgradeResponseHandle *urh,
868 if (0 != (p[0].revents & POLLIN))
870 if (0 != (p[0].revents & POLLOUT))
872 if (0 != (p[0].revents & POLLHUP))
874 if (0 != (p[0].revents & MHD_POLL_REVENTS_ERRROR))
876 if (0 != (p[1].revents & POLLIN))
878 if (0 != (p[1].revents & POLLOUT))
880 if (0 != (p[1].revents & POLLHUP))
882 if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
906 fd_set *write_fd_set,
907 fd_set *except_fd_set,
909 unsigned int fd_setsize)
945 #ifdef MHD_POSIX_SOCKETS 958 #ifdef MHD_POSIX_SOCKETS 966 if ( (
NULL == except_fd_set) ||
978 #ifdef MHD_WINSOCK_SOCKETS 991 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 993 struct MHD_UpgradeResponseHandle *urh;
995 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
1009 #ifdef HAVE_MESSAGES 1012 _(
"Maximum socket in select set: %d\n"),
1054 fd_set *read_fd_set,
1055 fd_set *write_fd_set,
1056 fd_set *except_fd_set,
1058 unsigned int fd_setsize)
1062 if ( (
NULL == daemon) ||
1063 (
NULL == read_fd_set) ||
1064 (
NULL == write_fd_set) ||
1069 if (
NULL == except_fd_set)
1071 #ifdef HAVE_MESSAGES 1073 _(
"MHD_get_fdset2() called with except_fd_set " 1074 "set to NULL. Such behavior is unsupported.\n"));
1077 except_fd_set = &es;
1080 #ifdef EPOLL_SUPPORT 1125 bool states_info_processed =
false;
1129 #ifdef HTTPS_SUPPORT 1140 states_info_processed =
true;
1149 states_info_processed =
true;
1159 if (!states_info_processed)
1206 #ifdef HTTPS_SUPPORT 1216 #ifdef UPGRADE_SUPPORT 1227 struct MHD_UpgradeResponseHandle *urh = connection->urh;
1231 #ifdef HTTPS_SUPPORT 1235 gnutls_bye (connection->tls_session,
1244 connection->urh =
NULL;
1250 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 1260 process_urh (
struct MHD_UpgradeResponseHandle *urh)
1275 #ifdef HAVE_MESSAGES 1276 if (! urh->was_closed)
1279 _(
"Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
1282 urh->was_closed =
true;
1284 was_closed = urh->was_closed;
1289 if (0 < urh->in_buffer_used)
1291 #ifdef HAVE_MESSAGES 1294 " bytes of data received from remote side: application shut down socket\n"),
1304 if (0 != urh->out_buffer_size)
1307 urh->in_buffer_used = 0;
1311 urh->in_buffer_size = 0;
1334 (urh->in_buffer_used < urh->in_buffer_size) )
1339 buf_size = urh->in_buffer_size - urh->in_buffer_used;
1340 if (buf_size > SSIZE_MAX)
1341 buf_size = SSIZE_MAX;
1344 res = gnutls_record_recv (connection->tls_session,
1345 &urh->in_buffer[urh->in_buffer_used],
1349 if (GNUTLS_E_INTERRUPTED != res)
1352 if (GNUTLS_E_AGAIN != res)
1357 urh->in_buffer_size = 0;
1363 urh->in_buffer_used += res;
1364 if (buf_size > (
size_t)res)
1366 else if (0 < gnutls_record_check_pending (connection->tls_session))
1375 urh->in_buffer_size = 0;
1383 (urh->out_buffer_used < urh->out_buffer_size) )
1388 buf_size = urh->out_buffer_size - urh->out_buffer_used;
1393 &urh->out_buffer[urh->out_buffer_used],
1412 urh->out_buffer_size = 0;
1418 urh->out_buffer_used += res;
1419 if (buf_size > (
size_t)res)
1429 urh->out_buffer_size = 0;
1437 (urh->out_buffer_used > 0) )
1442 data_size = urh->out_buffer_used;
1443 if (data_size > SSIZE_MAX)
1444 data_size = SSIZE_MAX;
1446 res = gnutls_record_send (connection->tls_session,
1451 if (GNUTLS_E_INTERRUPTED != res)
1454 if (GNUTLS_E_AGAIN != res)
1458 #ifdef HAVE_MESSAGES 1461 " bytes of data received from application: %s\n"),
1463 gnutls_strerror(res));
1466 urh->out_buffer_used = 0;
1468 urh->out_buffer_size = 0;
1475 const size_t next_out_buffer_used = urh->out_buffer_used - res;
1476 if (0 != next_out_buffer_used)
1478 memmove (urh->out_buffer,
1479 &urh->out_buffer[res],
1480 next_out_buffer_used);
1481 if (data_size > (
size_t)res)
1484 urh->out_buffer_used = next_out_buffer_used;
1486 if ( (0 == urh->out_buffer_used) &&
1494 urh->out_buffer_size = 0;
1503 (urh->in_buffer_used > 0) )
1508 data_size = urh->in_buffer_used;
1526 #ifdef HAVE_MESSAGES 1529 " bytes of data received from remote side: %s\n"),
1534 urh->in_buffer_used = 0;
1536 urh->in_buffer_size = 0;
1544 const size_t next_in_buffer_used = urh->in_buffer_used - res;
1545 if (0 != next_in_buffer_used)
1547 memmove (urh->in_buffer,
1548 &urh->in_buffer[res],
1549 next_in_buffer_used);
1550 if (data_size > (
size_t)res)
1553 urh->in_buffer_used = next_in_buffer_used;
1555 if ( (0 == urh->in_buffer_used) &&
1561 urh->in_buffer_size = 0;
1570 (urh->in_buffer_used < urh->in_buffer_size) &&
1575 ( (0 != urh->out_buffer_size) ||
1576 (0 != urh->out_buffer_used) ) )
1579 #ifdef HAVE_MESSAGES 1580 if (0 < urh->out_buffer_used)
1583 " bytes of data received from application: daemon shut down\n"),
1587 urh->out_buffer_used = 0;
1591 urh->out_buffer_size = 0;
1597 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 1598 #ifdef UPGRADE_SUPPORT 1610 #ifdef HTTPS_SUPPORT 1611 struct MHD_UpgradeResponseHandle *urh = con->urh;
1620 while ( (0 != urh->in_buffer_size) ||
1621 (0 != urh->out_buffer_size) ||
1622 (0 != urh->in_buffer_used) ||
1623 (0 != urh->out_buffer_used) )
1637 result = urh_to_fdset (urh,
1645 #ifdef HAVE_MESSAGES 1647 _(
"Error preparing select\n"));
1654 struct timeval* tvp;
1657 (urh->in_buffer_used < urh->in_buffer_size))
1679 #ifdef HAVE_MESSAGES 1681 _(
"Error during select (%d): `%s'\n"),
1687 urh_from_fdset (urh,
1702 p[0].fd = urh->connection->socket_fd;
1703 p[1].fd = urh->mhd.socket;
1705 while ( (0 != urh->in_buffer_size) ||
1706 (0 != urh->out_buffer_size) ||
1707 (0 != urh->in_buffer_used) ||
1708 (0 != urh->out_buffer_used) )
1712 urh_update_pollfd(urh, p);
1715 (urh->in_buffer_used < urh->in_buffer_size))
1720 if (MHD_sys_poll_ (p,
1728 #ifdef HAVE_MESSAGES 1730 _(
"Error during poll: `%s'\n"),
1735 urh_from_pollfd (urh,
1759 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
1770 struct timeval *tvp;
1776 #define EXTRA_SLOTS 1 1778 #define EXTRA_SLOTS 0 1787 const bool use_poll = 0;
1789 bool was_suspended =
false;
1790 MHD_thread_init_(&(con->
pid));
1796 #ifdef UPGRADE_SUPPORT 1797 struct MHD_UpgradeResponseHandle *
const urh = con->urh;
1799 static const void *
const urh =
NULL;
1806 was_suspended =
true;
1815 #ifdef HAVE_MESSAGES 1817 _(
"Failed to add FD to fd_set\n"));
1831 #ifdef HAVE_MESSAGES 1833 _(
"Error during select (%d): `%s'\n"),
1843 p[0].events = POLLIN;
1844 p[0].fd = MHD_itc_r_fd_ (daemon->
itc);
1846 if (0 > MHD_sys_poll_ (p,
1852 #ifdef HAVE_MESSAGES 1854 _(
"Error during poll: `%s'\n"),
1861 MHD_itc_clear_ (daemon->
itc);
1870 was_suspended =
false;
1876 #ifdef HTTPS_SUPPORT
1888 if ( (
NULL == tvp) &&
1896 const time_t seconds_left = timeout - (now - con->
last_activity);
1897 #if !defined(_WIN32) || defined(__CYGWIN__) 1898 tv.tv_sec = seconds_left;
1912 bool err_state =
false;
1946 if (MHD_ITC_IS_VALID_(daemon->
itc) )
1957 #ifdef HAVE_MESSAGES 1959 _(
"Failed to add FD to fd_set\n"));
1975 #ifdef HAVE_MESSAGES 1977 _(
"Error during select (%d): `%s'\n"),
1986 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
1987 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
1989 MHD_itc_clear_ (daemon->
itc);
2012 p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
2015 p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
2018 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
2026 if (MHD_ITC_IS_VALID_(daemon->
itc))
2028 p[1].events |= POLLIN;
2029 p[1].fd = MHD_itc_r_fd_ (daemon->
itc);
2034 if (MHD_sys_poll_ (p,
2040 (
NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
2044 #ifdef HAVE_MESSAGES 2046 _(
"Error during poll: `%s'\n"),
2054 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2055 (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
2056 MHD_itc_clear_ (daemon->
itc);
2060 0 != (p[0].revents & POLLIN),
2061 0 != (p[0].revents & POLLOUT),
2062 0 != (p[0].revents & (POLLERR | MHD_POLL_REVENTS_ERR_DISC))))
2066 #ifdef UPGRADE_SUPPORT 2067 if (MHD_CONNECTION_UPGRADE == con->
state)
2079 thread_main_connection_upgrade (con);
2083 con->urh->clean_ready =
true;
2091 return (MHD_THRD_RTRN_TYPE_) 0;
2096 #ifdef HAVE_MESSAGES 2098 _(
"Processing thread terminating. Closing connection\n"));
2122 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2123 (! MHD_itc_activate_ (daemon->
itc,
"t")) )
2125 #ifdef HAVE_MESSAGES 2127 _(
"Failed to signal thread termination via inter-thread communication channel."));
2130 return (MHD_THRD_RTRN_TYPE_) 0;
2145 #if defined(HTTPS_SUPPORT) 2146 #if !defined(MHD_WINSOCK_SOCKETS) && !defined(MHD_socket_nosignal_) && \ 2147 (GNUTLS_VERSION_NUMBER+0 < 0x030402) && defined(MSG_NOSIGNAL) 2153 #define MHD_TLSLIB_NEED_PUSH_FUNC 1 2156 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC 2162 MHD_tls_push_func_(gnutls_transport_ptr_t trnsp,
2166 #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) 2184 psk_gnutls_adapter (gnutls_session_t session,
2185 const char *username,
2186 gnutls_datum_t *key)
2191 size_t app_psk_size;
2193 connection = gnutls_session_get_ptr (session);
2194 if (
NULL == connection)
2196 #ifdef HAVE_MESSAGES 2198 MHD_PANIC (
_(
"Internal server error. This should be impossible.\n"));
2202 daemon = connection->
daemon;
2203 #if GNUTLS_VERSION_MAJOR >= 3 2204 if (
NULL == daemon->cred_callback)
2206 #ifdef HAVE_MESSAGES 2208 _(
"PSK not supported by this server.\n"));
2212 if (0 != daemon->cred_callback (daemon->cred_callback_cls,
2218 if (
NULL == (key->data = gnutls_malloc (app_psk_size)))
2220 #ifdef HAVE_MESSAGES 2222 _(
"PSK authentication failed: gnutls_malloc failed to allocate memory\n"));
2227 key->size = app_psk_size;
2234 #ifdef HAVE_MESSAGES 2236 _(
"PSK not supported by this server.\n"));
2272 const struct sockaddr *addr,
2278 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2284 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2316 #ifdef HAVE_MESSAGES 2318 _(
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
2319 (
int) client_socket,
2329 #ifdef MHD_socket_nosignal_ 2330 if (! MHD_socket_nosignal_ (client_socket))
2332 #ifdef HAVE_MESSAGES 2334 _(
"Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
2337 #ifndef MSG_NOSIGNAL 2348 #ifdef HAVE_MESSAGES 2351 _(
"Accepted connection on socket %d\n"),
2361 #ifdef HAVE_MESSAGES 2363 _(
"Server reached connection limit. Closing inbound connection.\n"));
2379 #ifdef HAVE_MESSAGES 2381 _(
"Connection rejected by application. Closing connection.\n"));
2397 #ifdef HAVE_MESSAGES 2399 "Error allocating memory: %s\n",
2412 #ifdef HAVE_MESSAGES 2414 _(
"Error allocating memory: %s\n"),
2429 if (
NULL == (connection->
addr = malloc (addrlen)))
2432 #ifdef HAVE_MESSAGES 2434 _(
"Error allocating memory: %s\n"),
2446 memcpy (connection->
addr,
2452 connection->
daemon = daemon;
2462 #ifdef HTTPS_SUPPORT 2465 gnutls_init (&connection->tls_session,
2467 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030402)
2470 #
if GNUTLS_VERSION_MAJOR >= 3
2474 gnutls_priority_set (connection->tls_session,
2475 daemon->priority_cache);
2476 gnutls_session_set_ptr (connection->tls_session,
2478 switch (daemon->cred_type)
2481 case GNUTLS_CRD_CERTIFICATE:
2482 gnutls_credentials_set (connection->tls_session,
2483 GNUTLS_CRD_CERTIFICATE,
2486 case GNUTLS_CRD_PSK:
2487 gnutls_credentials_set (connection->tls_session,
2490 gnutls_psk_set_server_credentials_function (daemon->psk_cred,
2491 &psk_gnutls_adapter);
2494 #ifdef HAVE_MESSAGES 2495 MHD_DLOG (connection->
daemon,
2496 _(
"Failed to setup TLS credentials: unknown credential type %d\n"),
2503 free (connection->
addr);
2511 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030109) && !defined(_WIN64) 2512 gnutls_transport_set_int (connection->tls_session,
2513 (
int)(client_socket));
2515 gnutls_transport_set_ptr (connection->tls_session,
2516 (gnutls_transport_ptr_t)(intptr_t)(client_socket));
2518 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC 2519 gnutls_transport_set_push_function (connection->tls_session,
2520 MHD_tls_push_func_);
2522 if (daemon->https_mem_trust)
2523 gnutls_certificate_server_set_request (connection->tls_session,
2524 GNUTLS_CERT_REQUEST);
2531 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2537 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2541 #ifdef HAVE_MESSAGES 2543 _(
"Server reached connection limit. Closing inbound connection.\n"));
2560 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2568 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2574 daemon->thread_stack_size,
2579 #ifdef HAVE_MESSAGES 2581 "Failed to create a thread: %s\n",
2588 connection->
pid = daemon->
pid;
2590 #ifdef EPOLL_SUPPORT 2595 struct epoll_event event;
2597 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2598 event.data.ptr = connection;
2599 if (0 != epoll_ctl (daemon->epoll_fd,
2605 #ifdef HAVE_MESSAGES 2607 _(
"Call to epoll_ctl failed: %s\n"),
2619 daemon->eready_tail,
2627 (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2628 (! MHD_itc_activate_ (daemon->
itc,
"n")) )
2630 #ifdef HAVE_MESSAGES 2632 _(
"Failed to signal new connection via inter-thread communication channel."));
2642 #ifdef HTTPS_SUPPORT 2643 if (
NULL != connection->tls_session)
2644 gnutls_deinit (connection->tls_session);
2650 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2662 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2666 free (connection->
addr);
2690 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2697 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2721 #ifdef EPOLL_SUPPORT 2727 daemon->eready_tail,
2733 if (0 != epoll_ctl (daemon->epoll_fd,
2737 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
2743 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2786 MHD_PANIC (
_(
"Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2787 #ifdef UPGRADE_SUPPORT 2788 if (
NULL != connection->urh)
2790 #ifdef HAVE_MESSAGES 2792 _(
"Error: connection scheduled for \"upgrade\" cannot be suspended"));
2815 MHD_PANIC (
_(
"Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2816 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2821 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2824 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2825 (! MHD_itc_activate_ (daemon->
itc,
"r")) )
2827 #ifdef HAVE_MESSAGES 2829 _(
"Failed to signal resume via inter-thread communication channel."));
2851 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2855 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2869 #ifdef UPGRADE_SUPPORT 2870 struct MHD_UpgradeResponseHandle *
const urh = pos->urh;
2872 static const void *
const urh =
NULL;
2876 #ifdef UPGRADE_SUPPORT
2877 || ( (
NULL != urh) &&
2878 ( (! urh->was_closed) ||
2879 (! urh->clean_ready) ) )
2909 #ifdef EPOLL_SUPPORT 2913 MHD_PANIC (
"Resumed connection was already in EREADY set\n");
2917 daemon->eready_tail,
2925 #ifdef UPGRADE_SUPPORT 2950 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 2953 if ( (used_thr_p_c) &&
2956 if (! MHD_itc_activate_(daemon->
itc,
2959 #ifdef HAVE_MESSAGES 2961 _(
"Failed to signal resume of connection via inter-thread communication channel."));
2999 const struct sockaddr *addr,
3005 #ifdef HAVE_MESSAGES 3007 _(
"Failed to set nonblocking mode on new client socket: %s\n"),
3018 #ifdef HAVE_MESSAGES 3020 _(
"Failed to set noninheritable mode on new client socket.\n"));
3027 #ifdef HAVE_MESSAGES 3029 _(
"Failed to reset buffering mode on new client socket.\n"));
3059 struct sockaddr_in6 addrstorage;
3061 struct sockaddr_in addrstorage;
3063 struct sockaddr *addr = (
struct sockaddr *) &addrstorage;
3069 addrlen =
sizeof (addrstorage);
3072 sizeof (addrstorage));
3099 #ifdef HAVE_MESSAGES 3102 _(
"Error accepting connection: %s\n"),
3114 #ifdef HAVE_MESSAGES 3119 _(
"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"));
3124 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3128 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3131 #ifdef HAVE_MESSAGES 3133 _(
"Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
3140 #if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK) 3143 #ifdef HAVE_MESSAGES 3145 _(
"Failed to set nonblocking mode on incoming connection socket: %s\n"),
3152 #if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC) 3155 #ifdef HAVE_MESSAGES 3157 _(
"Failed to set noninheritable mode on incoming connection socket.\n"));
3161 #ifdef HAVE_MESSAGES 3164 _(
"Accepted connection on socket %d\n"),
3192 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3200 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3204 (! MHD_join_thread_ (pos->
pid.handle)) )
3207 #ifdef UPGRADE_SUPPORT 3208 cleanup_upgraded_connection (pos);
3211 #ifdef HTTPS_SUPPORT 3212 if (
NULL != pos->tls_session)
3213 gnutls_deinit (pos->tls_session);
3225 #ifdef EPOLL_SUPPORT 3235 if ( (-1 !=
daemon->epoll_fd) &&
3244 if (0 != epoll_ctl (
daemon->epoll_fd,
3248 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
3264 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3270 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3300 time_t earliest_deadline;
3307 #ifdef HAVE_MESSAGES 3309 _(
"Illegal call to MHD_get_timeout\n"));
3321 #ifdef EPOLL_SUPPORT 3324 #
if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
3335 have_timeout =
false;
3336 earliest_deadline = 0;
3341 if ( (! have_timeout) ||
3344 have_timeout =
true;
3349 if ( (
NULL != pos) &&
3352 if ( (! have_timeout) ||
3355 have_timeout =
true;
3361 if (earliest_deadline < now)
3365 const time_t second_left = earliest_deadline - now;
3367 if (((
unsigned long long)second_left) >
ULLONG_MAX / 1000)
3370 *timeout = 1000LLU * (
unsigned long long) second_left;
3388 const fd_set *read_fd_set,
3389 const fd_set *write_fd_set,
3390 const fd_set *except_fd_set)
3395 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3396 struct MHD_UpgradeResponseHandle *urh;
3397 struct MHD_UpgradeResponseHandle *urhn;
3406 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
3407 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
3409 MHD_itc_clear_ (daemon->
itc);
3422 while (
NULL != (pos = prev))
3438 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3440 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
3444 urh_from_fdset (urh,
3451 if ( (0 == urh->in_buffer_size) &&
3452 (0 == urh->out_buffer_size) &&
3453 (0 == urh->in_buffer_used) &&
3454 (0 == urh->out_buffer_used) )
3457 urh->clean_ready =
true;
3492 const fd_set *read_fd_set,
3493 const fd_set *write_fd_set,
3494 const fd_set *except_fd_set)
3500 if (
NULL == read_fd_set ||
NULL == write_fd_set)
3502 if (
NULL == except_fd_set)
3504 #ifdef HAVE_MESSAGES 3506 _(
"MHD_run_from_select() called with except_fd_set " 3507 "set to NULL. Such behavior is deprecated.\n"));
3510 except_fd_set = &es;
3514 #ifdef EPOLL_SUPPORT 3515 int ret = MHD_epoll (daemon,
3553 struct timeval timeout;
3560 timeout.tv_usec = 0;
3584 #ifdef HAVE_MESSAGES 3586 _(
"Could not obtain daemon fdsets"));
3601 #ifdef HAVE_MESSAGES 3603 _(
"Could not add listen socket to fdset"));
3608 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
3614 #if defined(MHD_WINSOCK_SOCKETS) 3629 #ifdef HAVE_MESSAGES 3631 _(
"Could not add control inter-thread communication channel FD to fdset"));
3634 #if defined(MHD_WINSOCK_SOCKETS) 3646 (MHD_ITC_IS_VALID_(daemon->
itc)) &&
3658 timeout.tv_usec = 0;
3666 timeout.tv_usec = (ltimeout % 1000) * 1000;
3685 #ifdef HAVE_MESSAGES 3687 _(
"select failed: %s\n"),
3714 unsigned int num_connections;
3717 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3718 struct MHD_UpgradeResponseHandle *urh;
3719 struct MHD_UpgradeResponseHandle *urhn;
3727 num_connections = 0;
3730 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3731 for (urh = daemon->urh_head;
NULL != urh; urh = urh->next)
3732 num_connections += 2;
3738 unsigned int poll_server;
3745 sizeof (
struct pollfd));
3748 #ifdef HAVE_MESSAGES 3750 _(
"Error allocating memory: %s\n"),
3763 p[poll_server].fd = ls;
3764 p[poll_server].events = POLLIN;
3765 p[poll_server].revents = 0;
3766 poll_listen = (int) poll_server;
3770 if (MHD_ITC_IS_VALID_(daemon->
itc))
3772 p[poll_server].fd = MHD_itc_r_fd_ (daemon->
itc);
3773 p[poll_server].events = POLLIN;
3774 p[poll_server].revents = 0;
3775 poll_itc_idx = (int) poll_server;
3785 timeout = (ltimeout > INT_MAX) ? INT_MAX : (
int) ltimeout;
3794 p[poll_server+i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
3797 p[poll_server+i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
3800 p[poll_server+i].events |= MHD_POLL_EVENTS_ERR_DISC;
3808 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3809 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
3811 urh_to_pollfd(urh, &(p[poll_server+i]));
3815 if (0 == poll_server + num_connections)
3820 if (MHD_sys_poll_(p,
3821 poll_server + num_connections,
3830 #ifdef HAVE_MESSAGES 3832 _(
"poll failed: %s\n"),
3845 if ( (-1 != poll_itc_idx) &&
3846 (0 != (p[poll_itc_idx].revents & POLLIN)) )
3847 MHD_itc_clear_ (daemon->
itc);
3857 while (
NULL != (pos = prev))
3861 if (i >= num_connections)
3866 0 != (p[poll_server+i].revents & POLLIN),
3867 0 != (p[poll_server+i].revents & POLLOUT),
3868 0 != (p[poll_server+i].revents & MHD_POLL_REVENTS_ERR_DISC));
3871 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3872 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
3874 if (i >= num_connections)
3881 if ((p[poll_server+i].
fd != urh->connection->socket_fd) ||
3882 (p[poll_server+i+1].fd != urh->mhd.socket))
3884 urh_from_pollfd (urh,
3889 if ( (0 == urh->in_buffer_size) &&
3890 (0 == urh->out_buffer_size) &&
3891 (0 == urh->in_buffer_used) &&
3892 (0 == urh->out_buffer_used) )
3897 urh->clean_ready =
true;
3907 if ( (-1 != poll_listen) &&
3908 (0 != (p[poll_listen].revents & POLLIN)) )
3925 MHD_poll_listen_socket (
struct MHD_Daemon *daemon,
3930 unsigned int poll_count;
3945 p[poll_count].fd = ls;
3946 p[poll_count].events = POLLIN;
3947 p[poll_count].revents = 0;
3948 poll_listen = poll_count;
3951 if (MHD_ITC_IS_VALID_(daemon->
itc))
3953 p[poll_count].fd = MHD_itc_r_fd_ (daemon->
itc);
3954 p[poll_count].events = POLLIN;
3955 p[poll_count].revents = 0;
3956 poll_itc_idx = poll_count;
3967 if (0 == poll_count)
3969 if (MHD_sys_poll_(p,
3977 #ifdef HAVE_MESSAGES 3979 _(
"poll failed: %s\n"),
3984 if ( (-1 != poll_itc_idx) &&
3985 (0 != (p[poll_itc_idx].revents & POLLIN)) )
3986 MHD_itc_clear_ (daemon->
itc);
3991 if ( (-1 != poll_listen) &&
3992 (0 != (p[poll_listen].revents & POLLIN)) )
4014 return MHD_poll_all (daemon,
4016 return MHD_poll_listen_socket (daemon,
4026 #ifdef EPOLL_SUPPORT 4036 #define MAX_EVENTS 128 4039 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4049 is_urh_ready(
struct MHD_UpgradeResponseHandle *
const urh)
4051 const struct MHD_Connection *
const connection = urh->connection;
4053 if ( (0 == urh->in_buffer_size) &&
4054 (0 == urh->out_buffer_size) &&
4055 (0 == urh->in_buffer_used) &&
4056 (0 == urh->out_buffer_used) )
4062 (urh->in_buffer_used < urh->in_buffer_size) )
4065 (urh->out_buffer_used < urh->out_buffer_size) )
4068 (urh->out_buffer_used > 0) )
4071 (urh->in_buffer_used > 0) )
4088 struct epoll_event events[MAX_EVENTS];
4090 struct MHD_UpgradeResponseHandle * pos;
4091 struct MHD_UpgradeResponseHandle * prev;
4093 num_events = MAX_EVENTS;
4094 while (MAX_EVENTS == num_events)
4098 num_events = epoll_wait (daemon->epoll_upgrade_fd,
4102 if (-1 == num_events)
4107 #ifdef HAVE_MESSAGES 4109 _(
"Call to epoll_wait failed: %s\n"),
4114 for (i = 0; i < (
unsigned int) num_events; i++)
4116 struct UpgradeEpollHandle *
const ueh = events[i].data.ptr;
4117 struct MHD_UpgradeResponseHandle *
const urh = ueh->urh;
4118 bool new_err_state =
false;
4120 if (urh->clean_ready)
4124 if (0 != (events[i].events & EPOLLIN))
4126 if (0 != (events[i].events & EPOLLOUT))
4128 if (0 != (events[i].events & EPOLLHUP))
4132 (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
4138 new_err_state =
true;
4141 if (! urh->in_eready_list)
4143 if (new_err_state ||
4147 daemon->eready_urh_tail,
4149 urh->in_eready_list =
true;
4154 prev = daemon->eready_urh_tail;
4155 while (
NULL != (pos = prev))
4159 if (! is_urh_ready(pos))
4162 daemon->eready_urh_tail,
4164 pos->in_eready_list =
false;
4167 if ( (0 == pos->in_buffer_size) &&
4168 (0 == pos->out_buffer_size) &&
4169 (0 == pos->in_buffer_used) &&
4170 (0 == pos->out_buffer_used) )
4173 pos->clean_ready =
true;
4190 static const char *
const epoll_itc_marker =
"itc_marker";
4205 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4206 static const char *
const upgrade_marker =
"upgrade_ptr";
4210 struct epoll_event events[MAX_EVENTS];
4211 struct epoll_event event;
4217 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4218 int run_upgraded =
MHD_NO;
4221 if (-1 == daemon->epoll_fd)
4228 (! daemon->listen_socket_in_epoll) &&
4231 event.events = EPOLLIN;
4232 event.data.ptr = daemon;
4233 if (0 != epoll_ctl (daemon->epoll_fd,
4238 #ifdef HAVE_MESSAGES 4240 _(
"Call to epoll_ctl failed: %s\n"),
4245 daemon->listen_socket_in_epoll =
true;
4248 (daemon->listen_socket_in_epoll) )
4250 if ( (0 != epoll_ctl (daemon->epoll_fd,
4256 MHD_PANIC (
"Failed to remove listen FD from epoll set\n");
4257 daemon->listen_socket_in_epoll =
false;
4260 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4261 if ( (! daemon->upgrade_fd_in_epoll) &&
4262 (-1 != daemon->epoll_upgrade_fd) )
4264 event.events = EPOLLIN | EPOLLOUT;
4265 event.data.ptr = (
void *) upgrade_marker;
4266 if (0 != epoll_ctl (daemon->epoll_fd,
4268 daemon->epoll_upgrade_fd,
4271 #ifdef HAVE_MESSAGES 4273 _(
"Call to epoll_ctl failed: %s\n"),
4278 daemon->upgrade_fd_in_epoll =
true;
4281 if ( (daemon->listen_socket_in_epoll) &&
4288 if (0 != epoll_ctl (daemon->epoll_fd,
4292 MHD_PANIC (
_(
"Failed to remove listen FD from epoll set\n"));
4293 daemon->listen_socket_in_epoll =
false;
4306 timeout_ms = INT_MAX;
4308 timeout_ms = (int) timeout_ll;
4325 num_events = MAX_EVENTS;
4326 while (MAX_EVENTS == num_events)
4329 num_events = epoll_wait (daemon->epoll_fd,
4333 if (-1 == num_events)
4338 #ifdef HAVE_MESSAGES 4340 _(
"Call to epoll_wait failed: %s\n"),
4345 for (i=0;i<(
unsigned int) num_events;i++)
4351 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4352 if (upgrade_marker == events[i].
data.ptr)
4360 if (epoll_itc_marker == events[i].
data.ptr)
4364 MHD_itc_clear_ (daemon->
itc);
4367 if (daemon == events[i].
data.ptr)
4371 if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
4373 unsigned int series_length = 0;
4379 (series_length < 10) &&
4389 pos = events[i].data.ptr;
4391 if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
4397 daemon->eready_tail,
4404 if (0 != (events[i].events & EPOLLIN))
4412 daemon->eready_tail,
4417 if (0 != (events[i].events & EPOLLOUT))
4424 daemon->eready_tail,
4433 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4435 run_epoll_for_upgrade (daemon);
4439 prev = daemon->eready_tail;
4440 while (
NULL != (pos = prev))
4457 daemon->eready_tail,
4473 while (
NULL != (pos = prev))
4483 while (
NULL != (pos = prev))
4526 #ifdef EPOLL_SUPPORT 4529 MHD_epoll (daemon,
MHD_NO);
4562 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4581 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4587 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4595 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
4600 MHD_thread_init_(&(daemon->
pid));
4605 #ifdef EPOLL_SUPPORT 4621 return (MHD_THRD_RTRN_TYPE_)0;
4717 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4728 #ifdef HAVE_MESSAGES 4730 "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC\n");
4735 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4740 #ifdef EPOLL_SUPPORT 4745 if (0 != epoll_ctl (daemon->
worker_pool[i].epoll_fd,
4749 MHD_PANIC (
_(
"Failed to remove listen FD from epoll set\n"));
4750 daemon->
worker_pool[i].listen_socket_in_epoll =
false;
4757 MHD_PANIC (
_(
"Failed to signal quiesce via inter-thread communication channel"));
4762 #ifdef EPOLL_SUPPORT 4764 (-1 != daemon->epoll_fd) &&
4765 (daemon->listen_socket_in_epoll) )
4767 if ( (0 != epoll_ctl (daemon->epoll_fd,
4773 MHD_PANIC (
"Failed to remove listen FD from epoll set\n");
4774 daemon->listen_socket_in_epoll =
false;
4777 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
4778 (! MHD_itc_activate_ (daemon->
itc,
"q")) )
4779 MHD_PANIC (
_(
"failed to signal quiesce via inter-thread communication channel"));
4807 const struct sockaddr **servaddr,
4821 const struct sockaddr **servaddr,
4827 va_start (ap, servaddr);
4846 const struct sockaddr **servaddr,
4853 #ifdef HTTPS_SUPPORT 4856 #if GNUTLS_VERSION_MAJOR >= 3 4857 gnutls_certificate_retrieve_function2 *pgcrf;
4885 #ifdef HAVE_MESSAGES 4887 _(
"Warning: Too large timeout value, ignored.\n"));
4911 *servaddr = va_arg (ap,
4912 const struct sockaddr *);
4920 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4926 #ifdef HAVE_MESSAGES 4928 _(
"Warning: Zero size, specified for thread pool size, is ignored. " 4929 "Thread pool is not used.\n"));
4934 #ifdef HAVE_MESSAGES 4936 _(
"Warning: \"1\", specified for thread pool size, is ignored. " 4937 "Thread pool is not used.\n"));
4946 #ifdef HAVE_MESSAGES 4948 _(
"Specified thread pool size (%u) too big\n"),
4957 #ifdef HAVE_MESSAGES 4959 _(
"MHD_OPTION_THREAD_POOL_SIZE option is specified but " 4960 "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
4966 #ifdef HAVE_MESSAGES 4968 _(
"Both MHD_OPTION_THREAD_POOL_SIZE option and " 4969 "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
4976 #ifdef HTTPS_SUPPORT 4981 daemon->https_mem_key = pstr;
4982 #ifdef HAVE_MESSAGES 4985 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4993 daemon->https_key_password = pstr;
4994 #ifdef HAVE_MESSAGES 4997 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5005 daemon->https_mem_cert = pstr;
5006 #ifdef HAVE_MESSAGES 5009 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5017 daemon->https_mem_trust = pstr;
5018 #ifdef HAVE_MESSAGES 5021 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5026 daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
5034 gnutls_datum_t dhpar;
5036 if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
5038 #ifdef HAVE_MESSAGES 5040 _(
"Error initializing DH parameters\n"));
5044 dhpar.data = (
unsigned char *) pstr;
5045 dhpar.size = strlen (pstr);
5046 if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
5048 GNUTLS_X509_FMT_PEM) < 0)
5050 #ifdef HAVE_MESSAGES 5052 _(
"Bad Diffie-Hellman parameters format\n"));
5054 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
5057 daemon->have_dhparams =
true;
5059 #ifdef HAVE_MESSAGES 5062 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5071 gnutls_priority_deinit (daemon->priority_cache);
5072 ret = gnutls_priority_init (&daemon->priority_cache,
5075 if (GNUTLS_E_SUCCESS != ret)
5077 #ifdef HAVE_MESSAGES 5079 _(
"Setting priorities to `%s' failed: %s\n"),
5081 gnutls_strerror (ret));
5083 daemon->priority_cache =
NULL;
5087 #ifdef HAVE_MESSAGES 5090 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5095 #if GNUTLS_VERSION_MAJOR < 3 5096 #ifdef HAVE_MESSAGES 5098 _(
"MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n"));
5103 gnutls_certificate_retrieve_function2 *);
5105 daemon->cert_callback = pgcrf;
5107 #ifdef HAVE_MESSAGES 5109 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5115 #ifdef DAUTH_SUPPORT 5117 daemon->digest_auth_rand_size = va_arg (ap,
5119 daemon->digest_auth_random = va_arg (ap,
5123 daemon->nonce_nc_size = va_arg (ap,
5130 #ifdef HAVE_MESSAGES 5132 _(
"MHD_OPTION_LISTEN_SOCKET specified for daemon " 5133 "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
5142 #ifdef HAVE_MESSAGES 5143 daemon->custom_error_log = va_arg (ap,
5145 daemon->custom_error_log_cls = va_arg (ap,
5154 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5156 daemon->thread_stack_size = va_arg (ap,
5162 daemon->fastopen_queue_size = va_arg (ap,
5168 unsigned int) ? 1 : -1;
5176 #ifdef HAVE_MESSAGES 5181 _(
"Flag MHD_USE_PEDANTIC_CHECKS is ignored because " 5182 "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n"));
5200 (
size_t) oa[i].
value,
5216 (
unsigned int) oa[i].
value,
5221 #ifdef HTTPS_SUPPORT 5226 (gnutls_credentials_type_t) oa[i].
value,
5276 (
void *) oa[i].
value,
5286 (
size_t) oa[i].
value,
5303 #ifdef HTTPS_SUPPORT 5305 #if GNUTLS_VERSION_MAJOR >= 3 5306 daemon->cred_callback = va_arg (ap,
5308 daemon->cred_callback_cls = va_arg (ap,
5313 _(
"MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3\n"),
5319 #ifdef HAVE_MESSAGES 5326 _(
"MHD HTTPS option %d passed to MHD compiled without HTTPS support\n"),
5332 _(
"Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n"),
5343 #ifdef EPOLL_SUPPORT 5349 #ifndef HAVE_MESSAGES 5353 #ifdef USE_EPOLL_CREATE1 5354 fd = epoll_create1 (EPOLL_CLOEXEC);
5356 fd = epoll_create (MAX_EVENTS);
5360 #ifdef HAVE_MESSAGES 5362 _(
"Call to epoll_create1 failed: %s\n"),
5367 #if !defined(USE_EPOLL_CREATE1) 5370 #ifdef HAVE_MESSAGES 5372 _(
"Failed to set noninheritable mode on epoll FD.\n"));
5390 setup_epoll_to_listen (
struct MHD_Daemon *daemon)
5392 struct epoll_event event;
5395 daemon->epoll_fd = setup_epoll_fd (daemon);
5396 if (-1 == daemon->epoll_fd)
5398 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5401 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
5409 event.events = EPOLLIN;
5410 event.data.ptr = daemon;
5411 if (0 != epoll_ctl (daemon->epoll_fd,
5416 #ifdef HAVE_MESSAGES 5418 _(
"Call to epoll_ctl failed: %s\n"),
5423 daemon->listen_socket_in_epoll =
true;
5424 if (MHD_ITC_IS_VALID_(daemon->
itc))
5426 event.events = EPOLLIN;
5427 event.data.ptr = (
void *) epoll_itc_marker;
5428 if (0 != epoll_ctl (daemon->epoll_fd,
5430 MHD_itc_r_fd_ (daemon->
itc),
5433 #ifdef HAVE_MESSAGES 5435 _(
"Call to epoll_ctl failed: %s\n"),
5479 struct sockaddr_in servaddr4;
5481 struct sockaddr_in6 servaddr6;
5483 const struct sockaddr *servaddr =
NULL;
5485 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5502 #ifndef EPOLL_SUPPORT 5506 #ifndef HTTPS_SUPPORT 5510 #ifndef TCP_FASTOPEN 5516 #ifdef UPGRADE_SUPPORT 5547 #if defined(EPOLL_SUPPORT) 5549 #elif defined(HAVE_POLL) 5558 #if defined(EPOLL_SUPPORT) 5568 #ifdef EPOLL_SUPPORT 5569 daemon->epoll_fd = -1;
5570 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5571 daemon->epoll_upgrade_fd = -1;
5575 #ifdef HTTPS_SUPPORT 5576 daemon->priority_cache =
NULL;
5579 gnutls_priority_init (&daemon->priority_cache,
5589 daemon->
port = port;
5600 MHD_itc_set_invalid_ (daemon->
itc);
5606 #ifdef HAVE_MESSAGES 5608 daemon->custom_error_log_cls = stderr;
5613 #ifdef HAVE_MESSAGES 5615 _(
"Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with " 5616 "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD " 5617 "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"));
5625 #ifdef HAVE_LISTEN_SHUTDOWN 5630 #ifdef DAUTH_SUPPORT 5631 daemon->digest_auth_rand_size = 0;
5632 daemon->digest_auth_random =
NULL;
5633 daemon->nonce_nc_size = 4;
5635 #ifdef HTTPS_SUPPORT 5638 daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
5647 #ifdef HTTPS_SUPPORT 5649 (
NULL != daemon->priority_cache) )
5650 gnutls_priority_deinit (daemon->priority_cache);
5661 #ifdef HAVE_MESSAGES 5663 _(
"Using debug build of libmicrohttpd.\n") );
5668 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5673 if (! MHD_itc_init_ (daemon->
itc))
5675 #ifdef HAVE_MESSAGES 5677 _(
"Failed to create inter-thread communication channel: %s\n"),
5678 MHD_itc_last_strerror_ ());
5680 #ifdef HTTPS_SUPPORT 5681 if (
NULL != daemon->priority_cache)
5682 gnutls_priority_deinit (daemon->priority_cache);
5691 #ifdef HAVE_MESSAGES 5693 _(
"file descriptor for inter-thread communication channel exceeds maximum value\n"));
5696 #ifdef HTTPS_SUPPORT 5697 if (
NULL != daemon->priority_cache)
5698 gnutls_priority_deinit (daemon->priority_cache);
5705 #ifdef DAUTH_SUPPORT 5706 if (daemon->nonce_nc_size > 0)
5708 if ( ( (
size_t) (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc))) /
5709 sizeof(
struct MHD_NonceNc) != daemon->nonce_nc_size)
5711 #ifdef HAVE_MESSAGES 5713 _(
"Specified value for NC_SIZE too large\n"));
5715 #ifdef HTTPS_SUPPORT 5717 gnutls_priority_deinit (daemon->priority_cache);
5722 daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc));
5723 if (
NULL == daemon->nnc)
5725 #ifdef HAVE_MESSAGES 5727 _(
"Failed to allocate memory for nonce-nc map: %s\n"),
5730 #ifdef HTTPS_SUPPORT 5732 gnutls_priority_deinit (daemon->priority_cache);
5739 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5740 if (! MHD_mutex_init_ (&daemon->nnc_lock))
5742 #ifdef HAVE_MESSAGES 5744 _(
"MHD failed to initialize nonce-nc mutex\n"));
5746 #ifdef HTTPS_SUPPORT 5748 gnutls_priority_deinit (daemon->priority_cache);
5758 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5762 #ifdef HAVE_MESSAGES 5764 _(
"MHD thread pooling only works with MHD_USE_INTERNAL_POLLING_THREAD\n"));
5776 domain = (*pflags &
MHD_USE_IPv6) ? PF_INET6 : PF_INET;
5786 #ifdef HAVE_MESSAGES 5788 _(
"Failed to create socket for listening: %s\n"),
5797 #ifndef MHD_WINSOCK_SOCKETS 5802 if (0 > setsockopt (listen_fd,
5805 (
void*)&on,
sizeof (on)))
5807 #ifdef HAVE_MESSAGES 5809 _(
"setsockopt failed: %s\n"),
5818 #ifndef MHD_WINSOCK_SOCKETS 5821 if (0 > setsockopt (listen_fd,
5824 (
void*)&on,
sizeof (on)))
5826 #ifdef HAVE_MESSAGES 5828 _(
"setsockopt failed: %s\n"),
5838 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT) 5839 if (0 > setsockopt (listen_fd,
5841 #ifndef MHD_WINSOCK_SOCKETS
5849 #ifdef HAVE_MESSAGES 5851 _(
"setsockopt failed: %s\n"),
5859 #ifdef HAVE_MESSAGES 5861 _(
"Cannot allow listening address reuse: SO_REUSEPORT not defined\n"));
5874 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \ 5875 (defined(__sun) && defined(SO_EXCLBIND)) 5876 if (0 > setsockopt (listen_fd,
5878 #ifdef SO_EXCLUSIVEADDRUSE
5879 SO_EXCLUSIVEADDRUSE,
5886 #ifdef HAVE_MESSAGES 5888 _(
"setsockopt failed: %s\n"),
5893 #elif defined(MHD_WINSOCK_SOCKETS) 5894 #ifdef HAVE_MESSAGES 5896 _(
"Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n"));
5905 addrlen =
sizeof (
struct sockaddr_in6);
5908 addrlen =
sizeof (
struct sockaddr_in);
5909 if (
NULL == servaddr)
5914 #ifdef IN6ADDR_ANY_INIT 5915 static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
5919 sizeof (
struct sockaddr_in6));
5920 servaddr6.sin6_family = AF_INET6;
5921 servaddr6.sin6_port = htons (port);
5922 #ifdef IN6ADDR_ANY_INIT 5923 servaddr6.sin6_addr = static_in6any;
5925 #if HAVE_SOCKADDR_IN_SIN_LEN 5926 servaddr6.sin6_len =
sizeof (
struct sockaddr_in6);
5928 servaddr = (
struct sockaddr *) &servaddr6;
5935 sizeof (
struct sockaddr_in));
5936 servaddr4.sin_family = AF_INET;
5937 servaddr4.sin_port = htons (port);
5938 if (0 != INADDR_ANY)
5939 servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
5940 #if HAVE_SOCKADDR_IN_SIN_LEN 5941 servaddr4.sin_len =
sizeof (
struct sockaddr_in);
5943 servaddr = (
struct sockaddr *) &servaddr4;
5958 if (0 > setsockopt (listen_fd,
5959 IPPROTO_IPV6, IPV6_V6ONLY,
5960 (
const void *) &v6_only,
5963 #ifdef HAVE_MESSAGES 5965 _(
"setsockopt failed: %s\n"),
5972 if (-1 == bind (listen_fd, servaddr, addrlen))
5974 #ifdef HAVE_MESSAGES 5976 _(
"Failed to bind to port %u: %s\n"),
5977 (
unsigned int) port,
5986 if (0 == daemon->fastopen_queue_size)
5987 daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
5988 if (0 != setsockopt (listen_fd,
5991 (
const void*)&daemon->fastopen_queue_size,
5992 sizeof (daemon->fastopen_queue_size)))
5994 #ifdef HAVE_MESSAGES 5996 _(
"setsockopt failed: %s\n"),
6002 if (listen (listen_fd,
6005 #ifdef HAVE_MESSAGES 6007 _(
"Failed to listen for connections: %s\n"),
6019 if ( (0 == daemon->
port) &&
6022 struct sockaddr_storage servaddr;
6026 sizeof (
struct sockaddr_storage));
6027 addrlen =
sizeof (servaddr);
6028 if (0 != getsockname (listen_fd,
6029 (
struct sockaddr *) &servaddr,
6032 #ifdef HAVE_MESSAGES 6034 _(
"Failed to get listen port number: %s\n"),
6038 #ifdef MHD_POSIX_SOCKETS 6039 else if (
sizeof (servaddr) < addrlen)
6042 #ifdef HAVE_MESSAGES 6044 _(
"Failed to get listen port number (`struct sockaddr_storage` too small!?)\n"));
6050 switch (servaddr.ss_family)
6054 struct sockaddr_in *s4 = (
struct sockaddr_in *) &servaddr;
6056 daemon->
port = ntohs (s4->sin_port);
6062 struct sockaddr_in6 *s6 = (
struct sockaddr_in6 *) &servaddr;
6064 daemon->
port = ntohs(s6->sin6_port);
6075 #ifdef HAVE_MESSAGES 6077 _(
"Unknown address family!\n"));
6088 #ifdef HAVE_MESSAGES 6090 _(
"Failed to set nonblocking mode on listening socket: %s\n"),
6094 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6111 #ifdef HAVE_MESSAGES 6113 _(
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
6121 #ifdef EPOLL_SUPPORT 6123 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6130 #ifdef HAVE_MESSAGES 6132 _(
"Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
6136 if (
MHD_YES != setup_epoll_to_listen (daemon))
6141 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6144 #ifdef HAVE_MESSAGES 6146 _(
"MHD failed to initialize IP connection limit mutex\n"));
6157 #ifdef HAVE_MESSAGES 6159 _(
"MHD failed to initialize IP connection limit mutex\n"));
6161 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6171 #ifdef HTTPS_SUPPORT 6174 (0 != MHD_TLS_init (daemon)) )
6176 #ifdef HAVE_MESSAGES 6178 _(
"Failed to initialize TLS support\n"));
6182 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6190 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6198 "MHD-listen" :
"MHD-single",
6199 daemon->thread_stack_size,
6203 #ifdef HAVE_MESSAGES 6205 _(
"Failed to create listen thread: %s\n"),
6239 memcpy (d, daemon,
sizeof (
struct MHD_Daemon));
6249 if (! MHD_itc_init_ (d->
itc))
6251 #ifdef HAVE_MESSAGES 6253 _(
"Failed to create worker inter-thread communication channel: %s\n"),
6254 MHD_itc_last_strerror_() );
6262 #ifdef HAVE_MESSAGES 6264 _(
"File descriptor for worker inter-thread communication channel exceeds maximum value\n"));
6271 MHD_itc_set_invalid_ (d->
itc);
6277 if (i < leftover_conns)
6279 #ifdef EPOLL_SUPPORT 6281 (
MHD_YES != setup_epoll_to_listen (d)) )
6287 #ifdef HAVE_MESSAGES 6289 _(
"MHD failed to initialize cleanup connection mutex\n"));
6297 daemon->thread_stack_size,
6301 #ifdef HAVE_MESSAGES 6303 _(
"Failed to create pool thread: %s\n"),
6315 #ifdef HTTPS_SUPPORT 6318 daemon->https_key_password =
NULL;
6323 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6351 #ifdef EPOLL_SUPPORT 6352 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6353 if (daemon->upgrade_fd_in_epoll)
6355 if (0 != epoll_ctl (daemon->epoll_fd,
6357 daemon->epoll_upgrade_fd,
6359 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
6360 daemon->upgrade_fd_in_epoll =
false;
6363 if (-1 != daemon->epoll_fd)
6364 close (daemon->epoll_fd);
6365 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6366 if (-1 != daemon->epoll_upgrade_fd)
6367 close (daemon->epoll_upgrade_fd);
6370 #ifdef DAUTH_SUPPORT 6372 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6376 #ifdef HTTPS_SUPPORT 6379 gnutls_priority_deinit (daemon->priority_cache);
6380 if (daemon->x509_cred)
6381 gnutls_certificate_free_credentials (daemon->x509_cred);
6382 if (daemon->psk_cred)
6383 gnutls_psk_free_server_credentials (daemon->psk_cred);
6386 if (MHD_ITC_IS_VALID_(daemon->
itc))
6406 #ifdef UPGRADE_SUPPORT 6409 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6410 struct MHD_UpgradeResponseHandle *urh;
6411 struct MHD_UpgradeResponseHandle *urhn;
6414 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6420 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
6427 urh->clean_ready =
true;
6444 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6447 #ifdef UPGRADE_SUPPORT 6453 while (
NULL != susp)
6455 if (
NULL == susp->urh)
6456 MHD_PANIC (
_(
"MHD_stop_daemon() called while we have suspended connections.\n"));
6457 #ifdef HTTPS_SUPPORT 6458 else if (used_tls &&
6460 (! susp->urh->clean_ready) )
6461 shutdown (susp->urh->app.socket,
6466 #ifdef HAVE_MESSAGES 6467 if (! susp->urh->was_closed)
6469 _(
"Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
6471 susp->urh->was_closed =
true;
6487 MHD_PANIC (
_(
"MHD_stop_daemon() called while we have suspended connections.\n"));
6492 #if MHD_WINSOCK_SOCKETS 6495 (! MHD_itc_activate_ (
daemon->
itc,
"e")) )
6496 MHD_PANIC (
_(
"Failed to signal shutdown via inter-thread communication channel"));
6500 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6510 if (! MHD_join_thread_ (pos->
pid.handle))
6525 #ifdef UPGRADE_SUPPORT 6540 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6561 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6574 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6588 MHD_PANIC (
_(
"Failed to signal shutdown via inter-thread communication channel."));
6593 #ifdef HAVE_LISTEN_SHUTDOWN 6596 (void) shutdown (
fd,
6606 #ifdef EPOLL_SUPPORT 6608 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6616 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6625 MHD_PANIC (
_(
"Failed to signal shutdown via inter-thread communication channel"));
6629 #ifdef HAVE_LISTEN_SHUTDOWN 6633 (void) shutdown (
fd,
6641 if (! MHD_join_thread_ (
daemon->
pid.handle))
6656 #ifdef EPOLL_SUPPORT 6658 (-1 !=
daemon->epoll_fd) )
6660 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6662 (-1 !=
daemon->epoll_upgrade_fd) )
6667 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6680 #ifdef HTTPS_SUPPORT 6681 if (
daemon->have_dhparams)
6683 gnutls_dh_params_deinit (
daemon->https_mem_dhparams);
6684 daemon->have_dhparams =
false;
6688 gnutls_priority_deinit (
daemon->priority_cache);
6690 gnutls_certificate_free_credentials (
daemon->x509_cred);
6692 gnutls_psk_free_server_credentials (
daemon->psk_cred);
6696 #ifdef DAUTH_SUPPORT 6698 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6702 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6736 #ifdef EPOLL_SUPPORT 6747 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6805 #ifdef PACKAGE_VERSION 6806 return PACKAGE_VERSION;
6808 static char ver[12] =
"\0\0\0\0\0\0\0\0\0\0\0";
6811 int res = MHD_snprintf_(ver,
6817 if (0 >= res ||
sizeof(ver) <= res)
6842 #ifdef HAVE_MESSAGES 6848 #ifdef HTTPS_SUPPORT 6854 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3 6866 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) 6878 #ifdef EPOLL_SUPPORT 6884 #ifdef HAVE_LISTEN_SHUTDOWN 6890 #ifdef _MHD_ITC_SOCKETPAIR 6902 #ifdef BAUTH_SUPPORT 6908 #ifdef DAUTH_SUPPORT 6914 #ifdef HAVE_POSTPROCESSOR 6920 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111 6926 #if defined(HAVE_PREAD64) || defined(_WIN32) 6928 #elif defined(HAVE_PREAD) 6929 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
6930 #elif defined(HAVE_LSEEK64) 6933 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
6936 #if defined(MHD_USE_THREAD_NAME_) 6942 #if defined(UPGRADE_SUPPORT) 6948 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32) 6954 #ifdef MHD_USE_GETSOCKNAME 6960 #if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || defined (MSG_NOSIGNAL) 6966 #ifdef _MHD_HAVE_SENDFILE 6972 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6983 #ifdef MHD_HTTPS_REQUIRE_GRYPT 6984 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600 6985 #if defined(MHD_USE_POSIX_THREADS) 6986 GCRY_THREAD_OPTION_PTHREAD_IMPL;
6987 #elif defined(MHD_W32_MUTEX_) 6990 gcry_w32_mutex_init (
void **ppmtx)
6992 *ppmtx = malloc (
sizeof (MHD_mutex_));
6996 if (!MHD_mutex_init_ ((MHD_mutex_*)*ppmtx))
7008 gcry_w32_mutex_destroy (
void **ppmtx)
7010 int res = (MHD_mutex_destroy_ ((MHD_mutex_*)*ppmtx)) ? 0 : EINVAL;
7017 gcry_w32_mutex_lock (
void **ppmtx)
7019 return MHD_mutex_lock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
7024 gcry_w32_mutex_unlock (
void **ppmtx)
7026 return MHD_mutex_unlock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
7030 static struct gcry_thread_cbs gcry_threads_w32 = {
7031 (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
7032 NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
7033 gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
7046 #if defined(_WIN32) && ! defined(__CYGWIN__) 7053 #if defined(_WIN32) && ! defined(__CYGWIN__) 7054 if (0 != WSAStartup(MAKEWORD(2, 2), &wsd))
7055 MHD_PANIC (
_(
"Failed to initialize winsock\n"));
7056 mhd_winsock_inited_ = 1;
7057 if (2 != LOBYTE(wsd.wVersion) && 2 != HIBYTE(wsd.wVersion))
7058 MHD_PANIC (
_(
"Winsock version 2.2 is not available\n"));
7060 #ifdef HTTPS_SUPPORT 7061 #ifdef MHD_HTTPS_REQUIRE_GRYPT 7062 #if GCRYPT_VERSION_NUMBER < 0x010600 7063 #if defined(MHD_USE_POSIX_THREADS) 7064 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7065 &gcry_threads_pthread))
7066 MHD_PANIC (
_(
"Failed to initialise multithreading in libgcrypt\n"));
7067 #elif defined(MHD_W32_MUTEX_) 7068 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7070 MHD_PANIC (
_(
"Failed to initialise multithreading in libgcrypt\n"));
7072 gcry_check_version (
NULL);
7074 if (
NULL == gcry_check_version (
"1.6.0"))
7075 MHD_PANIC (
_(
"libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n"));
7078 gnutls_global_init ();
7081 #ifdef HAVE_FREEBSD_SENDFILE 7082 MHD_conn_init_static_ ();
7090 #ifdef HTTPS_SUPPORT 7091 gnutls_global_deinit ();
7093 #if defined(_WIN32) && ! defined(__CYGWIN__) 7094 if (mhd_winsock_inited_)
7100 #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)
enum MHD_ConnectionEventLoopInfo event_loop_info
void(* VfprintfFunctionPointerType)(void *cls, const char *format, va_list va)
#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)
void(* MHD_LogCallback)(void *cls, const char *fm, va_list ap)
#define MHD_TEST_ALLOW_SUSPEND_RESUME
int listening_address_reuse
MHD_mutex_ per_ip_connection_mutex
MHD_NotifyConnectionCallback notify_connection
Header for platform-independent inter-thread communication.
struct MHD_Connection * next
void * tsearch(const void *vkey, void **vrootp, int(*compar)(const void *, const void *))
#define DLL_insert(head, tail, element)
static int MHD_ip_addr_compare(const void *a1, const void *a2)
#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
void internal_suspend_connection_(struct MHD_Connection *connection)
void MHD_connection_finish_forward_(struct MHD_Connection *connection) MHD_NONNULL(1)
unsigned int listen_backlog_size
#define XDLL_remove(head, tail, element)
void MHD_monotonic_sec_counter_finish(void)
#define _SET_INIT_AND_DEINIT_FUNCS(FI, FD)
static int internal_run_from_select(struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set)
struct MHD_Connection * suspended_connections_tail
#define MHD_create_named_thread_(t, n, s, r, a)
MHD_AcceptPolicyCallback apc
struct MHD_Connection * cleanup_tail
int MHD_connection_handle_idle(struct MHD_Connection *connection)
static int resume_suspended_connections(struct MHD_Daemon *daemon)
#define MHD_itc_destroy_chk_(itc)
static int internal_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen, bool external_add, bool non_blck)
int(* MHD_AccessHandlerCallback)(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls)
static int MHD_poll(struct MHD_Daemon *daemon, int may_block)
static void MHD_cleanup_connections(struct MHD_Daemon *daemon)
void MHD_monotonic_sec_counter_init(void)
#define MHD_recv_(s, b, l)
static int MHD_accept_connection(struct MHD_Daemon *daemon)
_MHD_EXTERN int MHD_get_fdset(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd)
static void MHD_ip_count_unlock(struct MHD_Daemon *daemon)
void(* MHD_RequestCompletedCallback)(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
struct MHD_Connection * normal_timeout_tail
void MHD_check_global_init_(void)
MHD_RequestCompletedCallback notify_completed
#define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)
#define MHD_mutex_lock_chk_(pmutex)
#define MHD_SCKT_FD_FITS_FDSET_(fd, pset)
static void close_connection(struct MHD_Connection *pos)
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
void * notify_completed_cls
_MHD_EXTERN int MHD_run(struct MHD_Daemon *daemon)
int MHD_socket_nonblocking_(MHD_socket sock)
size_t(* UnescapeCallback)(void *cls, struct MHD_Connection *conn, char *uri)
void * notify_connection_cls
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ MHD_polling_thread(void *cls)
MHD_PanicCallback mhd_panic
#define XDLL_insert(head, tail, element)
#define MHD_UNSIGNED_LONG_LONG_PRINTF
void MHD_resume_connection(struct MHD_Connection *connection)
_MHD_EXTERN int MHD_is_feature_supported(enum MHD_FEATURE feature)
struct MHD_Connection * suspended_connections_head
void * per_ip_connection_count
size_t read_buffer_offset
_MHD_EXTERN int MHD_get_fdset2(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd, unsigned int fd_setsize)
void * default_handler_cls
#define MHD_SCKT_ERR_IS_EINTR_(err)
MHD_mutex_ cleanup_connection_mutex
_MHD_EXTERN MHD_socket MHD_quiesce_daemon(struct MHD_Daemon *daemon)
int(* MHD_AcceptPolicyCallback)(void *cls, const struct sockaddr *addr, socklen_t addrlen)
void(* MHD_NotifyConnectionCallback)(void *cls, struct MHD_Connection *connection, void **socket_context, enum MHD_ConnectionNotificationCode toe)
_MHD_EXTERN const union MHD_DaemonInfo * MHD_get_daemon_info(struct MHD_Daemon *daemon, enum MHD_DaemonInfoType info_type,...)
_MHD_EXTERN size_t MHD_http_unescape(char *val)
#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)
static void close_all_connections(struct MHD_Daemon *daemon)
limits values definitions
int MHD_socket_noninheritable_(MHD_socket sock)
#define MAYBE_SOCK_NONBLOCK
MHD_FLAG
Flags for the struct MHD_Daemon.
int MHD_socket_buffering_reset_(MHD_socket sock)
#define MAYBE_SOCK_CLOEXEC