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"
55 #ifdef MHD_HTTPS_REQUIRE_GRYPT
60 #if defined(_WIN32) && ! defined(__CYGWIN__)
61 #ifndef WIN32_LEAN_AND_MEAN
62 #define WIN32_LEAN_AND_MEAN 1
67 #ifdef MHD_USE_POSIX_THREADS
76 #ifdef MHD_POSIX_SOCKETS
77 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 4)
79 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 2)
85 #define MHD_POOL_SIZE_DEFAULT (32 * 1024)
135 _ (
"Fatal error in GNU libmicrohttpd %s:%u: %s\n"),
165 #if defined(MHD_WINSOCK_SOCKETS)
169 static int mhd_winsock_inited_ = 0;
172 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
177 #define MHD_check_global_init_() (void) 0
184 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
185 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_
189 MHD_MUTEX_STATIC_DEFN_INIT_ (global_init_mutex_);
201 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
202 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_
208 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
209 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_
223 MHD_default_logger_ (
void *cls,
227 vfprintf ((FILE*) cls, fm, ap);
229 fflush ((FILE*) cls);
291 struct in6_addr ipv6;
310 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
326 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
349 offsetof (
struct MHD_IPCount,
365 struct MHD_IPCount *key)
372 if (
sizeof (
struct sockaddr_in) == addrlen)
374 const struct sockaddr_in *addr4 = (
const struct sockaddr_in*) addr;
376 key->family = AF_INET;
377 memcpy (&key->addr.ipv4,
379 sizeof(addr4->sin_addr));
385 if (
sizeof (
struct sockaddr_in6) == addrlen)
387 const struct sockaddr_in6 *addr6 = (
const struct sockaddr_in6*) addr;
389 key->family = AF_INET6;
390 memcpy (&key->addr.ipv6,
392 sizeof(addr6->sin6_addr));
415 const struct sockaddr *addr,
418 struct MHD_IPCount *key;
428 if (
NULL == (key = malloc (
sizeof(*key))))
449 _ (
"Failed to add IP connection count node.\n"));
459 key = (
struct MHD_IPCount *) node;
481 const struct sockaddr *addr,
484 struct MHD_IPCount search_key;
485 struct MHD_IPCount *found_key;
507 MHD_PANIC (
_ (
"Failed to find previously-added IP address.\n"));
509 found_key = (
struct MHD_IPCount *) *nodep;
511 if (0 == found_key->count)
513 MHD_PANIC (
_ (
"Previously-added IP address had counter of zero.\n"));
516 if (0 == --found_key->count)
536 MHD_init_daemon_certificate (
struct MHD_Daemon *daemon)
542 #if GNUTLS_VERSION_MAJOR >= 3
543 if (
NULL != daemon->cert_callback)
545 gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
546 daemon->cert_callback);
549 #if GNUTLS_VERSION_NUMBER >= 0x030603
550 else if (
NULL != daemon->cert_callback2)
552 gnutls_certificate_set_retrieve_function3 (daemon->x509_cred,
553 daemon->cert_callback2);
557 if (
NULL != daemon->https_mem_trust)
560 paramlen = strlen (daemon->https_mem_trust);
565 "Too long trust certificate.\n");
569 cert.data = (
unsigned char *) daemon->https_mem_trust;
570 cert.size = (
unsigned int) paramlen;
571 if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred,
573 GNUTLS_X509_FMT_PEM) < 0)
577 "Bad trust certificate format.\n");
583 if (daemon->have_dhparams)
585 gnutls_certificate_set_dh_params (daemon->x509_cred,
586 daemon->https_mem_dhparams);
589 if ( (
NULL != daemon->https_mem_cert) &&
590 (
NULL != daemon->https_mem_key) )
595 param1len = strlen (daemon->https_mem_key);
596 param2len = strlen (daemon->https_mem_cert);
602 "Too long key or certificate.\n");
606 key.data = (
unsigned char *) daemon->https_mem_key;
607 key.size = (
unsigned int) param1len;
608 cert.data = (
unsigned char *) daemon->https_mem_cert;
609 cert.size = (
unsigned int) param2len;
611 if (
NULL != daemon->https_key_password)
613 #if GNUTLS_VERSION_NUMBER >= 0x030111
614 ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
618 daemon->https_key_password,
623 _ (
"Failed to setup x509 certificate/key: pre 3.X.X version " \
624 "of GnuTLS does not support setting key password.\n"));
630 ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
633 GNUTLS_X509_FMT_PEM);
637 "GnuTLS failed to setup x509 certificate/key: %s\n",
638 gnutls_strerror (ret));
642 #if GNUTLS_VERSION_MAJOR >= 3
643 if (
NULL != daemon->cert_callback)
646 #if GNUTLS_VERSION_NUMBER >= 0x030603
647 else if (
NULL != daemon->cert_callback2)
652 "You need to specify a certificate and key location.\n");
667 switch (daemon->cred_type)
669 case GNUTLS_CRD_CERTIFICATE:
671 gnutls_certificate_allocate_credentials (&daemon->x509_cred))
672 return GNUTLS_E_MEMORY_ERROR;
673 return MHD_init_daemon_certificate (daemon);
676 gnutls_psk_allocate_server_credentials (&daemon->psk_cred))
677 return GNUTLS_E_MEMORY_ERROR;
682 _ (
"Error: invalid credentials type %d specified.\n"),
727 fd_set *write_fd_set,
728 fd_set *except_fd_set,
740 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
754 urh_to_fdset (
struct MHD_UpgradeResponseHandle *urh,
759 unsigned int fd_setsize)
761 const MHD_socket conn_sckt = urh->connection->socket_fd;
769 if ( (urh->in_buffer_used < urh->in_buffer_size) &&
775 if ( (0 != urh->out_buffer_used) &&
784 ((0 != urh->in_buffer_size) ||
785 (0 != urh->out_buffer_size) ||
786 (0 != urh->out_buffer_used)))
794 if ( (urh->out_buffer_used < urh->out_buffer_size) &&
800 if ( (0 != urh->in_buffer_used) &&
809 ((0 != urh->out_buffer_size) ||
810 (0 != urh->in_buffer_size) ||
811 (0 != urh->in_buffer_used)))
832 urh_from_fdset (
struct MHD_UpgradeResponseHandle *urh,
837 const MHD_socket conn_sckt = urh->connection->socket_fd;
846 if (FD_ISSET (conn_sckt, rs))
848 if (FD_ISSET (conn_sckt, ws))
850 if (FD_ISSET (conn_sckt, es))
855 if (FD_ISSET (mhd_sckt, rs))
857 if (FD_ISSET (mhd_sckt, ws))
859 if (FD_ISSET (mhd_sckt, es))
876 urh_update_pollfd (
struct MHD_UpgradeResponseHandle *urh,
882 if (urh->in_buffer_used < urh->in_buffer_size)
883 p[0].events |= POLLIN;
884 if (0 != urh->out_buffer_used)
885 p[0].events |= POLLOUT;
890 ((0 != urh->in_buffer_size) ||
891 (0 != urh->out_buffer_size) ||
892 (0 != urh->out_buffer_used)))
893 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
895 if (urh->out_buffer_used < urh->out_buffer_size)
896 p[1].events |= POLLIN;
897 if (0 != urh->in_buffer_used)
898 p[1].events |= POLLOUT;
903 ((0 != urh->out_buffer_size) ||
904 (0 != urh->in_buffer_size) ||
905 (0 != urh->in_buffer_used)))
906 p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
917 urh_to_pollfd (
struct MHD_UpgradeResponseHandle *urh,
920 p[0].fd = urh->connection->socket_fd;
921 p[1].fd = urh->mhd.socket;
922 urh_update_pollfd (urh,
933 urh_from_pollfd (
struct MHD_UpgradeResponseHandle *urh,
940 if (0 != (p[0].revents & POLLIN))
942 if (0 != (p[0].revents & POLLOUT))
944 if (0 != (p[0].revents & POLLHUP))
946 if (0 != (p[0].revents & MHD_POLL_REVENTS_ERRROR))
948 if (0 != (p[1].revents & POLLIN))
950 if (0 != (p[1].revents & POLLOUT))
952 if (0 != (p[1].revents & POLLHUP))
954 if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
980 fd_set *write_fd_set,
981 fd_set *except_fd_set,
983 unsigned int fd_setsize)
1019 #ifdef MHD_POSIX_SOCKETS
1032 #ifdef MHD_POSIX_SOCKETS
1040 if ( (
NULL == except_fd_set) ||
1052 #ifdef MHD_WINSOCK_SOCKETS
1065 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
1067 struct MHD_UpgradeResponseHandle *urh;
1069 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
1082 #if _MHD_DEBUG_CONNECT
1083 #ifdef HAVE_MESSAGES
1086 _ (
"Maximum socket in select set: %d\n"),
1128 fd_set *read_fd_set,
1129 fd_set *write_fd_set,
1130 fd_set *except_fd_set,
1132 unsigned int fd_setsize)
1136 if ( (
NULL == daemon) ||
1137 (
NULL == read_fd_set) ||
1138 (
NULL == write_fd_set) ||
1143 if (
NULL == except_fd_set)
1145 #ifdef HAVE_MESSAGES
1147 _ (
"MHD_get_fdset2() called with except_fd_set "
1148 "set to NULL. Such behavior is unsupported.\n"));
1151 except_fd_set = &es;
1154 #ifdef EPOLL_SUPPORT
1199 bool states_info_processed =
false;
1203 #ifdef HTTPS_SUPPORT
1214 states_info_processed =
true;
1223 states_info_processed =
true;
1233 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)
1349 #ifdef MHD_USE_THREADS
1351 MHD_thread_ID_match_current_ (connection->
pid) );
1356 #ifdef HAVE_MESSAGES
1357 if (! urh->was_closed)
1361 "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
1364 urh->was_closed =
true;
1366 was_closed = urh->was_closed;
1371 if (0 < urh->in_buffer_used)
1373 #ifdef HAVE_MESSAGES
1375 _ (
"Failed to forward to application "
1377 " bytes of data received from remote side: application shut down socket.\n"),
1387 if (0 != urh->out_buffer_size)
1390 urh->in_buffer_used = 0;
1394 urh->in_buffer_size = 0;
1416 (urh->in_buffer_used < urh->in_buffer_size) )
1421 buf_size = urh->in_buffer_size - urh->in_buffer_used;
1426 res = gnutls_record_recv (connection->tls_session,
1427 &urh->in_buffer[urh->in_buffer_used],
1431 if (GNUTLS_E_INTERRUPTED != res)
1434 if (GNUTLS_E_AGAIN != res)
1439 urh->in_buffer_size = 0;
1445 urh->in_buffer_used += res;
1446 if (0 < gnutls_record_check_pending (connection->tls_session))
1457 urh->in_buffer_size = 0;
1465 (urh->out_buffer_used < urh->out_buffer_size) )
1470 buf_size = urh->out_buffer_size - urh->out_buffer_used;
1475 &urh->out_buffer[urh->out_buffer_used],
1494 urh->out_buffer_size = 0;
1500 urh->out_buffer_used += res;
1501 if (buf_size > (
size_t) res)
1511 urh->out_buffer_size = 0;
1519 (urh->out_buffer_used > 0) )
1524 data_size = urh->out_buffer_used;
1528 res = gnutls_record_send (connection->tls_session,
1533 if (GNUTLS_E_INTERRUPTED != res)
1536 if (GNUTLS_E_AGAIN != res)
1540 #ifdef HAVE_MESSAGES
1543 "Failed to forward to remote client "
1545 " bytes of data received from application: %s\n"),
1547 gnutls_strerror (res));
1550 urh->out_buffer_used = 0;
1552 urh->out_buffer_size = 0;
1559 const size_t next_out_buffer_used = urh->out_buffer_used - res;
1560 if (0 != next_out_buffer_used)
1562 memmove (urh->out_buffer,
1563 &urh->out_buffer[res],
1564 next_out_buffer_used);
1565 if (data_size > (
size_t) res)
1568 urh->out_buffer_used = next_out_buffer_used;
1570 if ( (0 == urh->out_buffer_used) &&
1578 urh->out_buffer_size = 0;
1587 (urh->in_buffer_used > 0) )
1592 data_size = urh->in_buffer_used;
1610 #ifdef HAVE_MESSAGES
1613 "Failed to forward to application "
1615 " bytes of data received from remote side: %s\n"),
1620 urh->in_buffer_used = 0;
1622 urh->in_buffer_size = 0;
1630 const size_t next_in_buffer_used = urh->in_buffer_used - res;
1631 if (0 != next_in_buffer_used)
1633 memmove (urh->in_buffer,
1634 &urh->in_buffer[res],
1635 next_in_buffer_used);
1636 if (data_size > (
size_t) res)
1639 urh->in_buffer_used = next_in_buffer_used;
1641 if ( (0 == urh->in_buffer_used) &&
1647 urh->in_buffer_size = 0;
1656 (urh->in_buffer_used < urh->in_buffer_size) &&
1661 ( (0 != urh->out_buffer_size) ||
1662 (0 != urh->out_buffer_used) ) )
1665 #ifdef HAVE_MESSAGES
1666 if (0 < urh->out_buffer_used)
1669 "Failed to forward to remote client "
1671 " bytes of data received from application: daemon shut down.\n"),
1675 urh->out_buffer_used = 0;
1679 urh->out_buffer_size = 0;
1687 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1688 #ifdef UPGRADE_SUPPORT
1700 #ifdef HTTPS_SUPPORT
1701 struct MHD_UpgradeResponseHandle *urh = con->urh;
1705 MHD_thread_ID_match_current_ (con->
pid) );
1712 while ( (0 != urh->in_buffer_size) ||
1713 (0 != urh->out_buffer_size) ||
1714 (0 != urh->in_buffer_used) ||
1715 (0 != urh->out_buffer_used) )
1729 result = urh_to_fdset (urh,
1737 #ifdef HAVE_MESSAGES
1739 _ (
"Error preparing select.\n"));
1749 (urh->in_buffer_used < urh->in_buffer_size)) ||
1772 #ifdef HAVE_MESSAGES
1774 _ (
"Error during select (%d): `%s'\n"),
1780 urh_from_fdset (urh,
1795 p[0].fd = urh->connection->socket_fd;
1796 p[1].fd = urh->mhd.socket;
1798 while ( (0 != urh->in_buffer_size) ||
1799 (0 != urh->out_buffer_size) ||
1800 (0 != urh->in_buffer_used) ||
1801 (0 != urh->out_buffer_used) )
1805 urh_update_pollfd (urh, p);
1808 (urh->in_buffer_used < urh->in_buffer_size)) ||
1814 if (MHD_sys_poll_ (p,
1822 #ifdef HAVE_MESSAGES
1824 _ (
"Error during poll: `%s'\n"),
1829 urh_from_pollfd (urh,
1855 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
1866 struct timeval *tvp;
1872 #define EXTRA_SLOTS 1
1874 #define EXTRA_SLOTS 0
1883 const bool use_poll = 0;
1885 bool was_suspended =
false;
1886 MHD_thread_init_ (&(con->
pid));
1892 #ifdef UPGRADE_SUPPORT
1893 struct MHD_UpgradeResponseHandle *
const urh = con->urh;
1895 static const void *
const urh =
NULL;
1902 was_suspended =
true;
1911 #ifdef HAVE_MESSAGES
1913 _ (
"Failed to add FD to fd_set.\n"));
1927 #ifdef HAVE_MESSAGES
1929 _ (
"Error during select (%d): `%s'\n"),
1939 p[0].events = POLLIN;
1940 p[0].fd = MHD_itc_r_fd_ (daemon->
itc);
1942 if (0 > MHD_sys_poll_ (p,
1948 #ifdef HAVE_MESSAGES
1950 _ (
"Error during poll: `%s'\n"),
1957 MHD_itc_clear_ (daemon->
itc);
1966 was_suspended =
false;
1972 #ifdef HTTPS_SUPPORT
1984 if ( (
NULL == tvp) &&
1992 const time_t seconds_left = timeout - (now - con->
last_activity);
1993 #if ! defined(_WIN32) || defined(__CYGWIN__)
1994 tv.tv_sec = seconds_left;
2008 bool err_state =
false;
2042 if (MHD_ITC_IS_VALID_ (daemon->
itc) )
2053 #ifdef HAVE_MESSAGES
2055 _ (
"Failed to add FD to fd_set.\n"));
2071 #ifdef HAVE_MESSAGES
2073 _ (
"Error during select (%d): `%s'\n"),
2082 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
2083 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
2085 MHD_itc_clear_ (daemon->
itc);
2108 p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
2111 p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
2114 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
2122 if (MHD_ITC_IS_VALID_ (daemon->
itc))
2124 p[1].events |= POLLIN;
2125 p[1].fd = MHD_itc_r_fd_ (daemon->
itc);
2130 if (MHD_sys_poll_ (p,
2136 (
NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
2140 #ifdef HAVE_MESSAGES
2142 _ (
"Error during poll: `%s'\n"),
2150 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
2151 (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
2152 MHD_itc_clear_ (daemon->
itc);
2156 (0 != (p[0].revents & POLLIN)),
2157 (0 != (p[0].revents & POLLOUT)),
2158 (0 != (p[0].revents & (POLLERR
2159 | MHD_POLL_REVENTS_ERR_DISC))) ))
2163 #ifdef UPGRADE_SUPPORT
2164 if (MHD_CONNECTION_UPGRADE == con->
state)
2176 thread_main_connection_upgrade (con);
2180 con->urh->clean_ready =
true;
2188 return (MHD_THRD_RTRN_TYPE_) 0;
2192 #if _MHD_DEBUG_CLOSE
2193 #ifdef HAVE_MESSAGES
2195 _ (
"Processing thread terminating. Closing connection.\n"));
2219 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
2220 (! MHD_itc_activate_ (daemon->
itc,
"t")) )
2222 #ifdef HAVE_MESSAGES
2225 "Failed to signal thread termination via inter-thread communication channel.\n"));
2228 return (MHD_THRD_RTRN_TYPE_) 0;
2245 #if defined(HTTPS_SUPPORT)
2246 #if ! defined(MHD_WINSOCK_SOCKETS) && ! defined(MHD_socket_nosignal_) && \
2247 (GNUTLS_VERSION_NUMBER + 0 < 0x030402) && defined(MSG_NOSIGNAL)
2253 #define MHD_TLSLIB_NEED_PUSH_FUNC 1
2257 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2263 MHD_tls_push_func_ (gnutls_transport_ptr_t trnsp,
2267 #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX)
2287 psk_gnutls_adapter (gnutls_session_t session,
2288 const char *username,
2289 gnutls_datum_t *key)
2294 size_t app_psk_size;
2296 connection = gnutls_session_get_ptr (session);
2297 if (
NULL == connection)
2299 #ifdef HAVE_MESSAGES
2301 MHD_PANIC (
_ (
"Internal server error. This should be impossible.\n"));
2305 daemon = connection->
daemon;
2306 #if GNUTLS_VERSION_MAJOR >= 3
2307 if (
NULL == daemon->cred_callback)
2309 #ifdef HAVE_MESSAGES
2311 _ (
"PSK not supported by this server.\n"));
2315 if (0 != daemon->cred_callback (daemon->cred_callback_cls,
2321 if (
NULL == (key->data = gnutls_malloc (app_psk_size)))
2323 #ifdef HAVE_MESSAGES
2326 "PSK authentication failed: gnutls_malloc failed to allocate memory.\n"));
2333 #ifdef HAVE_MESSAGES
2335 _ (
"PSK authentication failed: PSK too long.\n"));
2340 key->size = (
unsigned int) app_psk_size;
2347 #ifdef HAVE_MESSAGES
2349 _ (
"PSK not supported by this server.\n"));
2383 const struct sockaddr *
addr,
2387 bool sk_spipe_supprs)
2392 #ifdef HAVE_MESSAGES
2393 #if _MHD_DEBUG_CONNECT
2395 _ (
"Accepted connection on socket %d.\n"),
2405 #ifdef HAVE_MESSAGES
2408 "Server reached connection limit. Closing inbound connection.\n"));
2423 #if _MHD_DEBUG_CLOSE
2424 #ifdef HAVE_MESSAGES
2426 _ (
"Connection rejected by application. Closing connection.\n"));
2442 #ifdef HAVE_MESSAGES
2444 "Error allocating memory: %s\n",
2467 if (
NULL == (connection->
addr = malloc (addrlen)))
2470 #ifdef HAVE_MESSAGES
2472 _ (
"Error allocating memory: %s\n"),
2483 memcpy (connection->
addr,
2500 #ifdef HTTPS_SUPPORT
2501 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030500)
2508 flags = GNUTLS_SERVER;
2509 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030402)
2510 flags |= GNUTLS_NO_SIGNAL;
2512 #if GNUTLS_VERSION_MAJOR >= 3
2513 flags |= GNUTLS_NONBLOCK;
2515 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030603)
2517 flags |= GNUTLS_POST_HANDSHAKE_AUTH;
2519 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030605)
2521 flags |= GNUTLS_ENABLE_EARLY_DATA;
2525 if ((GNUTLS_E_SUCCESS != gnutls_init (&connection->tls_session, flags)) ||
2526 (GNUTLS_E_SUCCESS != gnutls_priority_set (connection->tls_session,
2527 daemon->priority_cache)))
2529 if (
NULL != connection->tls_session)
2530 gnutls_deinit (connection->tls_session);
2535 free (connection->
addr);
2537 #ifdef HAVE_MESSAGES
2539 _ (
"Failed to initialise TLS session.\n"));
2546 gnutls_session_set_ptr (connection->tls_session,
2548 switch (
daemon->cred_type)
2551 case GNUTLS_CRD_CERTIFICATE:
2552 gnutls_credentials_set (connection->tls_session,
2553 GNUTLS_CRD_CERTIFICATE,
2556 case GNUTLS_CRD_PSK:
2557 gnutls_credentials_set (connection->tls_session,
2560 gnutls_psk_set_server_credentials_function (
daemon->psk_cred,
2561 &psk_gnutls_adapter);
2564 #ifdef HAVE_MESSAGES
2567 "Failed to setup TLS credentials: unknown credential type %d.\n"),
2570 gnutls_deinit (connection->tls_session);
2575 free (connection->
addr);
2577 MHD_PANIC (
_ (
"Unknown credential type.\n"));
2583 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030109) && ! defined(_WIN64)
2584 gnutls_transport_set_int (connection->tls_session,
2585 (
int) (client_socket));
2587 gnutls_transport_set_ptr (connection->tls_session,
2588 (gnutls_transport_ptr_t) (intptr_t) (client_socket));
2590 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2591 gnutls_transport_set_push_function (connection->tls_session,
2592 MHD_tls_push_func_);
2594 if (
daemon->https_mem_trust)
2595 gnutls_certificate_server_set_request (connection->tls_session,
2596 GNUTLS_CERT_REQUEST);
2602 free (connection->
addr);
2604 MHD_PANIC (
_ (
"TLS connection on non-TLS daemon.\n"));
2614 #ifdef MHD_USE_THREADS
2628 #ifdef EPOLL_SUPPORT
2632 #ifdef HTTPS_SUPPORT
2633 if (
NULL != connection->tls_session)
2636 gnutls_deinit (connection->tls_session);
2643 free (connection->
addr);
2669 #ifdef MHD_USE_THREADS
2673 MHD_thread_ID_match_current_ (
daemon->
pid) );
2683 #ifdef HAVE_MESSAGES
2685 _ (
"Error allocating memory: %s\n"),
2699 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2705 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2709 #ifdef HAVE_MESSAGES
2712 "Server reached connection limit. Closing inbound connection.\n"));
2729 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2737 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2743 daemon->thread_stack_size,
2748 #ifdef HAVE_MESSAGES
2750 "Failed to create a thread: %s\n",
2759 #ifdef EPOLL_SUPPORT
2764 struct epoll_event event;
2766 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2767 event.data.ptr = connection;
2768 if (0 != epoll_ctl (daemon->epoll_fd,
2774 #ifdef HAVE_MESSAGES
2776 _ (
"Call to epoll_ctl failed: %s\n"),
2789 daemon->eready_tail,
2803 #ifdef HTTPS_SUPPORT
2804 if (
NULL != connection->tls_session)
2805 gnutls_deinit (connection->tls_session);
2811 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2823 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2827 free (connection->
addr);
2867 const struct sockaddr *addr,
2871 bool sk_spipe_supprs)
2875 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2883 #ifdef HAVE_MESSAGES
2885 _ (
"New connection socket descriptor (%d) is not less " \
2886 "than FD_SETSIZE (%d).\n"),
2887 (
int) client_socket,
2900 #ifdef HAVE_MESSAGES
2902 _ (
"Epoll mode supports only non-blocking sockets\n"));
2912 external_add, non_blck,
2914 if (
NULL == connection)
2917 if ((external_add) &&
2930 if ((MHD_ITC_IS_VALID_ (
daemon->
itc)) &&
2931 (! MHD_itc_activate_ (
daemon->
itc,
"n")))
2933 #ifdef HAVE_MESSAGES
2935 _ (
"Failed to signal new connection via inter-thread " \
2936 "communication channel.\n"));
2978 #ifdef HAVE_MESSAGES
2980 _ (
"Failed to start serving new connection.\n"));
2984 }
while (
NULL != local_tail);
3003 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3006 MHD_thread_ID_match_current_ (daemon->
pid) );
3013 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3037 #ifdef EPOLL_SUPPORT
3043 daemon->eready_tail,
3049 if (0 != epoll_ctl (daemon->epoll_fd,
3053 MHD_PANIC (
_ (
"Failed to remove FD from epoll set.\n"));
3059 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3101 #ifdef MHD_USE_THREADS
3104 MHD_thread_ID_match_current_ (daemon->
pid) );
3109 "Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
3110 #ifdef UPGRADE_SUPPORT
3111 if (
NULL != connection->urh)
3113 #ifdef HAVE_MESSAGES
3116 "Error: connection scheduled for \"upgrade\" cannot be suspended.\n"));
3140 "Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
3141 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3146 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3149 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
3150 (! MHD_itc_activate_ (daemon->
itc,
"r")) )
3152 #ifdef HAVE_MESSAGES
3155 "Failed to signal resume via inter-thread communication channel.\n"));
3178 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3181 MHD_thread_ID_match_current_ (
daemon->
pid) );
3185 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3201 #ifdef UPGRADE_SUPPORT
3202 struct MHD_UpgradeResponseHandle *
const urh = pos->urh;
3204 static const void *
const urh =
NULL;
3208 #ifdef UPGRADE_SUPPORT
3209 || ( (
NULL != urh) &&
3210 ( (! urh->was_closed) ||
3211 (! urh->clean_ready) ) )
3241 #ifdef EPOLL_SUPPORT
3245 MHD_PANIC (
"Resumed connection was already in EREADY set.\n");
3249 daemon->eready_tail,
3258 #ifdef UPGRADE_SUPPORT
3283 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3286 if ( (used_thr_p_c) &&
3289 if (! MHD_itc_activate_ (daemon->
itc,
3292 #ifdef HAVE_MESSAGES
3295 "Failed to signal resume of connection via inter-thread communication channel.\n"));
3333 const struct sockaddr *addr,
3337 bool sk_spipe_supprs;
3344 #ifdef HAVE_MESSAGES
3349 _ (
"MHD_add_connection() has been called for daemon started"
3350 " without MHD_USE_ITC flag.\nDaemon will not process newly"
3351 " added connection until any activity occurs in already"
3352 " added sockets.\n"));
3358 #ifdef HAVE_MESSAGES
3360 _ (
"Failed to set nonblocking mode on new client socket: %s\n"),
3368 #ifndef MHD_WINSOCK_SOCKETS
3369 sk_spipe_supprs =
false;
3371 sk_spipe_supprs =
true;
3373 #if defined(MHD_socket_nosignal_)
3374 if (! sk_spipe_supprs && ! MHD_socket_nosignal_ (client_socket))
3376 #ifdef HAVE_MESSAGES
3379 "Failed to suppress SIGPIPE on new client socket: %s\n"),
3384 #ifndef MSG_NOSIGNAL
3397 sk_spipe_supprs =
true;
3403 #ifdef HAVE_MESSAGES
3405 _ (
"Failed to set noninheritable mode on new client socket.\n"));
3409 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3466 struct sockaddr_in6 addrstorage;
3468 struct sockaddr_in addrstorage;
3470 struct sockaddr *addr = (
struct sockaddr *) &addrstorage;
3475 bool sk_spipe_supprs;
3477 #ifdef MHD_USE_THREADS
3479 MHD_thread_ID_match_current_ (daemon->
pid) );
3482 addrlen =
sizeof (addrstorage);
3485 sizeof (addrstorage));
3496 #ifndef MHD_WINSOCK_SOCKETS
3499 sk_spipe_supprs =
true;
3506 #ifndef MHD_WINSOCK_SOCKETS
3507 sk_spipe_supprs =
false;
3509 sk_spipe_supprs =
true;
3523 #ifdef HAVE_MESSAGES
3526 _ (
"Error accepting connection: %s\n"),
3538 #ifdef HAVE_MESSAGES
3544 "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"));
3549 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3553 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3556 #ifdef HAVE_MESSAGES
3559 "Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
3566 #if ! defined(USE_ACCEPT4) || ! defined(HAVE_SOCK_NONBLOCK)
3569 #ifdef HAVE_MESSAGES
3572 "Failed to set nonblocking mode on incoming connection socket: %s\n"),
3579 #if ! defined(USE_ACCEPT4) || ! defined(SOCK_CLOEXEC)
3582 #ifdef HAVE_MESSAGES
3585 "Failed to set noninheritable mode on incoming connection socket.\n"));
3589 #if defined(MHD_socket_nosignal_)
3590 if (! sk_spipe_supprs && ! MHD_socket_nosignal_ (s))
3592 #ifdef HAVE_MESSAGES
3595 "Failed to suppress SIGPIPE on incoming connection socket: %s\n"),
3600 #ifndef MSG_NOSIGNAL
3611 sk_spipe_supprs =
true;
3613 #ifdef HAVE_MESSAGES
3614 #if _MHD_DEBUG_CONNECT
3616 _ (
"Accepted connection on socket %d\n"),
3644 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3646 MHD_thread_ID_match_current_ (
daemon->
pid) );
3655 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3659 (! MHD_join_thread_ (pos->
pid.handle)) )
3660 MHD_PANIC (
_ (
"Failed to join a thread.\n"));
3662 #ifdef UPGRADE_SUPPORT
3663 cleanup_upgraded_connection (pos);
3666 #ifdef HTTPS_SUPPORT
3667 if (
NULL != pos->tls_session)
3668 gnutls_deinit (pos->tls_session);
3680 #ifdef EPOLL_SUPPORT
3690 if ( (-1 !=
daemon->epoll_fd) &&
3699 if (0 != epoll_ctl (
daemon->epoll_fd,
3703 MHD_PANIC (
_ (
"Failed to remove FD from epoll set.\n"));
3719 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3725 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3755 time_t earliest_deadline;
3760 #ifdef MHD_USE_THREADS
3762 MHD_thread_ID_match_current_ (
daemon->
pid) );
3767 #ifdef HAVE_MESSAGES
3769 _ (
"Illegal call to MHD_get_timeout.\n"));
3781 #ifdef EPOLL_SUPPORT
3784 #
if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
3795 have_timeout =
false;
3796 earliest_deadline = 0;
3801 if ( (! have_timeout) ||
3804 have_timeout =
true;
3809 if ( (
NULL != pos) &&
3812 if ( (! have_timeout) ||
3815 have_timeout =
true;
3821 if (earliest_deadline < now)
3825 const time_t second_left = earliest_deadline - now;
3827 if (((
unsigned long long) second_left) >
ULLONG_MAX / 1000)
3830 *timeout = 1000LLU * (
unsigned long long) second_left;
3848 const fd_set *read_fd_set,
3849 const fd_set *write_fd_set,
3850 const fd_set *except_fd_set)
3855 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3856 struct MHD_UpgradeResponseHandle *urh;
3857 struct MHD_UpgradeResponseHandle *urhn;
3866 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
3867 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
3869 MHD_itc_clear_ (daemon->
itc);
3886 while (
NULL != (pos = prev))
3902 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3904 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
3908 urh_from_fdset (urh,
3915 if ( (0 == urh->in_buffer_size) &&
3916 (0 == urh->out_buffer_size) &&
3917 (0 == urh->in_buffer_used) &&
3918 (0 == urh->out_buffer_used) )
3921 urh->clean_ready =
true;
3956 const fd_set *read_fd_set,
3957 const fd_set *write_fd_set,
3958 const fd_set *except_fd_set)
3964 if ((
NULL == read_fd_set) || (
NULL == write_fd_set))
3966 if (
NULL == except_fd_set)
3968 #ifdef HAVE_MESSAGES
3970 _ (
"MHD_run_from_select() called with except_fd_set "
3971 "set to NULL. Such behavior is deprecated.\n"));
3974 except_fd_set = &es;
3978 #ifdef EPOLL_SUPPORT
4017 struct timeval timeout;
4024 timeout.tv_usec = 0;
4048 #ifdef HAVE_MESSAGES
4050 _ (
"Could not obtain daemon fdsets.\n"));
4065 #ifdef HAVE_MESSAGES
4067 _ (
"Could not add listen socket to fdset.\n"));
4072 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
4078 #if defined(MHD_WINSOCK_SOCKETS)
4093 #ifdef HAVE_MESSAGES
4096 "Could not add control inter-thread communication channel FD to fdset.\n"));
4099 #if defined(MHD_WINSOCK_SOCKETS)
4113 (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
4125 timeout.tv_usec = 0;
4133 timeout.tv_usec = (ltimeout % 1000) * 1000;
4152 #ifdef HAVE_MESSAGES
4154 _ (
"select failed: %s\n"),
4181 unsigned int num_connections;
4184 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4185 struct MHD_UpgradeResponseHandle *urh;
4186 struct MHD_UpgradeResponseHandle *urhn;
4194 num_connections = 0;
4197 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4198 for (urh = daemon->urh_head;
NULL != urh; urh = urh->next)
4199 num_connections += 2;
4205 unsigned int poll_server;
4212 sizeof (
struct pollfd));
4215 #ifdef HAVE_MESSAGES
4217 _ (
"Error allocating memory: %s\n"),
4230 p[poll_server].fd = ls;
4231 p[poll_server].events = POLLIN;
4232 p[poll_server].revents = 0;
4233 poll_listen = (int) poll_server;
4237 if (MHD_ITC_IS_VALID_ (daemon->
itc))
4239 p[poll_server].fd = MHD_itc_r_fd_ (daemon->
itc);
4240 p[poll_server].events = POLLIN;
4241 p[poll_server].revents = 0;
4242 poll_itc_idx = (int) poll_server;
4252 timeout = (ltimeout > INT_MAX) ? INT_MAX : (
int) ltimeout;
4261 p[poll_server + i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
4264 p[poll_server + i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
4267 p[poll_server + i].events |= MHD_POLL_EVENTS_ERR_DISC;
4275 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4276 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
4278 urh_to_pollfd (urh, &(p[poll_server + i]));
4282 if (0 == poll_server + num_connections)
4287 if (MHD_sys_poll_ (p,
4288 poll_server + num_connections,
4297 #ifdef HAVE_MESSAGES
4299 _ (
"poll failed: %s\n"),
4309 if ( (-1 != poll_itc_idx) &&
4310 (0 != (p[poll_itc_idx].revents & POLLIN)) )
4311 MHD_itc_clear_ (daemon->
itc);
4325 if ( (-1 != poll_listen) &&
4326 (0 != (p[poll_listen].revents & POLLIN)) )
4334 while (
NULL != (pos = prev))
4338 if (i >= num_connections)
4343 0 != (p[poll_server + i].revents & POLLIN),
4344 0 != (p[poll_server + i].revents & POLLOUT),
4345 0 != (p[poll_server + i].revents
4346 & MHD_POLL_REVENTS_ERR_DISC));
4349 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4350 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
4352 if (i >= num_connections)
4359 if ((p[poll_server + i].
fd != urh->connection->socket_fd) ||
4360 (p[poll_server + i + 1].fd != urh->mhd.socket))
4362 urh_from_pollfd (urh,
4363 &p[poll_server + i]);
4367 if ( (0 == urh->in_buffer_size) &&
4368 (0 == urh->out_buffer_size) &&
4369 (0 == urh->in_buffer_used) &&
4370 (0 == urh->out_buffer_used) )
4375 urh->clean_ready =
true;
4399 MHD_poll_listen_socket (
struct MHD_Daemon *daemon,
4404 unsigned int poll_count;
4419 p[poll_count].fd = ls;
4420 p[poll_count].events = POLLIN;
4421 p[poll_count].revents = 0;
4422 poll_listen = poll_count;
4425 if (MHD_ITC_IS_VALID_ (daemon->
itc))
4427 p[poll_count].fd = MHD_itc_r_fd_ (daemon->
itc);
4428 p[poll_count].events = POLLIN;
4429 p[poll_count].revents = 0;
4430 poll_itc_idx = poll_count;
4441 if (0 == poll_count)
4443 if (MHD_sys_poll_ (p,
4451 #ifdef HAVE_MESSAGES
4453 _ (
"poll failed: %s\n"),
4458 if ( (-1 != poll_itc_idx) &&
4459 (0 != (p[poll_itc_idx].revents & POLLIN)) )
4460 MHD_itc_clear_ (daemon->
itc);
4470 if ( (-1 != poll_listen) &&
4471 (0 != (p[poll_listen].revents & POLLIN)) )
4495 return MHD_poll_all (daemon,
4497 return MHD_poll_listen_socket (daemon,
4507 #ifdef EPOLL_SUPPORT
4517 #define MAX_EVENTS 128
4520 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4530 is_urh_ready (
struct MHD_UpgradeResponseHandle *
const urh)
4534 if ( (0 == urh->in_buffer_size) &&
4535 (0 == urh->out_buffer_size) &&
4536 (0 == urh->in_buffer_used) &&
4537 (0 == urh->out_buffer_used) )
4543 (urh->in_buffer_used < urh->in_buffer_size) )
4546 (urh->out_buffer_used < urh->out_buffer_size) )
4549 (urh->out_buffer_used > 0) )
4552 (urh->in_buffer_used > 0) )
4569 struct epoll_event events[MAX_EVENTS];
4571 struct MHD_UpgradeResponseHandle *pos;
4572 struct MHD_UpgradeResponseHandle *prev;
4574 #ifdef MHD_USE_THREADS
4576 MHD_thread_ID_match_current_ (daemon->
pid) );
4579 num_events = MAX_EVENTS;
4580 while (0 != num_events)
4584 num_events = epoll_wait (daemon->epoll_upgrade_fd,
4588 if (-1 == num_events)
4594 #ifdef HAVE_MESSAGES
4596 _ (
"Call to epoll_wait failed: %s\n"),
4601 for (i = 0; i < (
unsigned int) num_events; i++)
4603 struct UpgradeEpollHandle *
const ueh = events[i].data.ptr;
4604 struct MHD_UpgradeResponseHandle *
const urh = ueh->urh;
4605 bool new_err_state =
false;
4607 if (urh->clean_ready)
4611 if (0 != (events[i].events & EPOLLIN))
4615 if (0 != (events[i].events & EPOLLOUT))
4619 if (0 != (events[i].events & EPOLLHUP))
4625 (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
4630 new_err_state =
true;
4632 if (! urh->in_eready_list)
4634 if (new_err_state ||
4638 daemon->eready_urh_tail,
4640 urh->in_eready_list =
true;
4645 prev = daemon->eready_urh_tail;
4646 while (
NULL != (pos = prev))
4650 if (! is_urh_ready (pos))
4653 daemon->eready_urh_tail,
4655 pos->in_eready_list =
false;
4658 if ( (0 == pos->in_buffer_size) &&
4659 (0 == pos->out_buffer_size) &&
4660 (0 == pos->in_buffer_used) &&
4661 (0 == pos->out_buffer_used) )
4664 pos->clean_ready =
true;
4683 static const char *
const epoll_itc_marker =
"itc_marker";
4698 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4699 static const char *
const upgrade_marker =
"upgrade_ptr";
4703 struct epoll_event events[MAX_EVENTS];
4704 struct epoll_event event;
4710 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4711 bool run_upgraded =
false;
4713 bool need_to_accept;
4715 if (-1 == daemon->epoll_fd)
4722 (! daemon->listen_socket_in_epoll) &&
4725 event.events = EPOLLIN;
4726 event.data.ptr = daemon;
4727 if (0 != epoll_ctl (daemon->epoll_fd,
4732 #ifdef HAVE_MESSAGES
4734 _ (
"Call to epoll_ctl failed: %s\n"),
4739 daemon->listen_socket_in_epoll =
true;
4742 (daemon->listen_socket_in_epoll) )
4744 if ( (0 != epoll_ctl (daemon->epoll_fd,
4750 MHD_PANIC (
"Failed to remove listen FD from epoll set.\n");
4751 daemon->listen_socket_in_epoll =
false;
4754 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4755 if ( ( (! daemon->upgrade_fd_in_epoll) &&
4756 (-1 != daemon->epoll_upgrade_fd) ) )
4758 event.events = EPOLLIN | EPOLLOUT;
4759 event.data.ptr = (
void *) upgrade_marker;
4760 if (0 != epoll_ctl (daemon->epoll_fd,
4762 daemon->epoll_upgrade_fd,
4765 #ifdef HAVE_MESSAGES
4767 _ (
"Call to epoll_ctl failed: %s\n"),
4772 daemon->upgrade_fd_in_epoll =
true;
4775 if ( (daemon->listen_socket_in_epoll) &&
4782 if (0 != epoll_ctl (daemon->epoll_fd,
4786 MHD_PANIC (
_ (
"Failed to remove listen FD from epoll set.\n"));
4787 daemon->listen_socket_in_epoll =
false;
4800 timeout_ms = INT_MAX;
4802 timeout_ms = (int) timeout_ll;
4815 need_to_accept =
false;
4820 num_events = MAX_EVENTS;
4821 while (MAX_EVENTS == num_events)
4824 num_events = epoll_wait (daemon->epoll_fd,
4828 if (-1 == num_events)
4833 #ifdef HAVE_MESSAGES
4835 _ (
"Call to epoll_wait failed: %s\n"),
4840 for (i = 0; i<(
unsigned int) num_events; i++)
4846 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4847 if (upgrade_marker == events[i].
data.ptr)
4851 run_upgraded =
true;
4855 if (epoll_itc_marker == events[i].
data.ptr)
4859 MHD_itc_clear_ (daemon->
itc);
4862 if (daemon == events[i].
data.ptr)
4866 if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
4867 need_to_accept =
true;
4873 pos = events[i].data.ptr;
4875 if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
4881 daemon->eready_tail,
4888 if (0 != (events[i].events & EPOLLIN))
4896 daemon->eready_tail,
4901 if (0 != (events[i].events & EPOLLOUT))
4908 daemon->eready_tail,
4923 unsigned int series_length = 0;
4930 (series_length < 10) &&
4945 while (
NULL != (pos = prev))
4955 while (
NULL != (pos = prev))
4963 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4964 if (run_upgraded || (
NULL != daemon->eready_urh_head))
4965 run_epoll_for_upgrade (daemon);
4969 prev = daemon->eready_tail;
4970 while (
NULL != (pos = prev))
4988 daemon->eready_tail,
5033 #ifdef EPOLL_SUPPORT
5036 MHD_epoll (daemon,
MHD_NO);
5062 #ifdef MHD_USE_THREADS
5064 MHD_thread_ID_match_current_ (daemon->
pid) );
5074 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5093 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5099 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5107 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
5111 #ifdef HAVE_PTHREAD_SIGMASK
5116 MHD_thread_init_ (&(daemon->
pid));
5117 #ifdef HAVE_PTHREAD_SIGMASK
5118 if ((0 == sigemptyset (&s_mask)) &&
5119 (0 == sigaddset (&s_mask, SIGPIPE)))
5121 err = pthread_sigmask (SIG_BLOCK, &s_mask,
NULL);
5127 #ifdef HAVE_MESSAGES
5130 _ (
"Failed to block SIGPIPE on daemon thread: %s\n"),
5138 #ifdef EPOLL_SUPPORT
5154 return (MHD_THRD_RTRN_TYPE_) 0;
5252 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5263 #ifdef HAVE_MESSAGES
5265 "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC.\n");
5270 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5275 #ifdef EPOLL_SUPPORT
5280 if (0 != epoll_ctl (daemon->
worker_pool[i].epoll_fd,
5284 MHD_PANIC (
_ (
"Failed to remove listen FD from epoll set.\n"));
5285 daemon->
worker_pool[i].listen_socket_in_epoll =
false;
5293 "Failed to signal quiesce via inter-thread communication channel.\n"));
5298 #ifdef EPOLL_SUPPORT
5300 (-1 != daemon->epoll_fd) &&
5301 (daemon->listen_socket_in_epoll) )
5303 if ( (0 != epoll_ctl (daemon->epoll_fd,
5309 MHD_PANIC (
"Failed to remove listen FD from epoll set.\n");
5310 daemon->listen_socket_in_epoll =
false;
5313 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
5314 (! MHD_itc_activate_ (daemon->
itc,
"q")) )
5316 "failed to signal quiesce via inter-thread communication channel.\n"));
5344 const struct sockaddr **servaddr,
5358 const struct sockaddr **servaddr,
5364 va_start (ap, servaddr);
5383 const struct sockaddr **servaddr,
5390 #ifdef HTTPS_SUPPORT
5393 #if GNUTLS_VERSION_MAJOR >= 3
5394 gnutls_certificate_retrieve_function2 *pgcrf;
5396 #if GNUTLS_VERSION_NUMBER >= 0x030603
5397 gnutls_certificate_retrieve_function3 *pgcrf2;
5428 #ifdef HAVE_MESSAGES
5430 _ (
"Warning: Too large timeout value, ignored.\n"));
5452 *servaddr = va_arg (ap,
5453 const struct sockaddr *);
5466 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5472 #ifdef HAVE_MESSAGES
5475 "Warning: Zero size, specified for thread pool size, is ignored. "
5476 "Thread pool is not used.\n"));
5481 #ifdef HAVE_MESSAGES
5484 "Warning: \"1\", specified for thread pool size, is ignored. "
5485 "Thread pool is not used.\n"));
5489 #if (0 == (UINT_MAX + 0)) || (UINT_MAX >= (SIZE_MAX / (64 * 1024)))
5496 #ifdef HAVE_MESSAGES
5498 _ (
"Specified thread pool size (%u) too big.\n"),
5508 #ifdef HAVE_MESSAGES
5510 _ (
"MHD_OPTION_THREAD_POOL_SIZE option is specified but "
5511 "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
5517 #ifdef HAVE_MESSAGES
5519 _ (
"Both MHD_OPTION_THREAD_POOL_SIZE option and "
5520 "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
5527 #ifdef HTTPS_SUPPORT
5532 daemon->https_mem_key = pstr;
5533 #ifdef HAVE_MESSAGES
5537 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5545 daemon->https_key_password = pstr;
5546 #ifdef HAVE_MESSAGES
5550 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5558 daemon->https_mem_cert = pstr;
5559 #ifdef HAVE_MESSAGES
5563 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5571 daemon->https_mem_trust = pstr;
5572 #ifdef HAVE_MESSAGES
5576 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5581 daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
5589 gnutls_datum_t dhpar;
5592 if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
5594 #ifdef HAVE_MESSAGES
5596 _ (
"Error initializing DH parameters.\n"));
5600 dhpar.data = (
unsigned char *) pstr;
5601 pstr_len = strlen (pstr);
5604 #ifdef HAVE_MESSAGES
5606 _ (
"Diffie-Hellman parameters string too long.\n"));
5610 dhpar.size = (
unsigned int) pstr_len;
5611 if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
5613 GNUTLS_X509_FMT_PEM) < 0)
5615 #ifdef HAVE_MESSAGES
5617 _ (
"Bad Diffie-Hellman parameters format.\n"));
5619 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
5622 daemon->have_dhparams =
true;
5624 #ifdef HAVE_MESSAGES
5628 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5637 gnutls_priority_deinit (daemon->priority_cache);
5638 ret = gnutls_priority_init (&daemon->priority_cache,
5641 if (GNUTLS_E_SUCCESS != ret)
5643 #ifdef HAVE_MESSAGES
5645 _ (
"Setting priorities to `%s' failed: %s\n"),
5647 gnutls_strerror (ret));
5649 daemon->priority_cache =
NULL;
5653 #ifdef HAVE_MESSAGES
5657 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5662 #if GNUTLS_VERSION_MAJOR < 3
5663 #ifdef HAVE_MESSAGES
5666 "MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0.\n"));
5671 gnutls_certificate_retrieve_function2 *);
5673 daemon->cert_callback = pgcrf;
5674 #ifdef HAVE_MESSAGES
5678 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5684 #if GNUTLS_VERSION_NUMBER < 0x030603
5685 #ifdef HAVE_MESSAGES
5688 "MHD_OPTION_HTTPS_CERT_CALLBACK2 requires building MHD with GnuTLS >= 3.6.3.\n"));
5692 pgcrf2 = va_arg (ap,
5693 gnutls_certificate_retrieve_function3 *);
5695 daemon->cert_callback2 = pgcrf2;
5696 #ifdef HAVE_MESSAGES
5700 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5706 #ifdef DAUTH_SUPPORT
5708 daemon->digest_auth_rand_size = va_arg (ap,
5710 daemon->digest_auth_random = va_arg (ap,
5714 daemon->nonce_nc_size = va_arg (ap,
5721 #ifdef HAVE_MESSAGES
5723 _ (
"MHD_OPTION_LISTEN_SOCKET specified for daemon "
5724 "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
5733 #ifdef HAVE_MESSAGES
5734 daemon->custom_error_log = va_arg (ap,
5736 daemon->custom_error_log_cls = va_arg (ap,
5745 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5747 daemon->thread_stack_size = va_arg (ap,
5753 daemon->fastopen_queue_size = va_arg (ap,
5757 #ifdef HAVE_MESSAGES
5759 _ (
"TCP fastopen is not supported on this platform.\n"));
5765 unsigned int) ? 1 : -1;
5773 #ifdef HAVE_MESSAGES
5778 _ (
"Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
5779 "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n"));
5797 (
size_t) oa[i].
value,
5814 (
unsigned int) oa[i].
value,
5819 #ifdef HTTPS_SUPPORT
5824 (gnutls_credentials_type_t) oa[i].
value,
5875 (
void *) oa[i].
value,
5885 (
size_t) oa[i].
value,
5902 #ifdef HTTPS_SUPPORT
5904 #if GNUTLS_VERSION_MAJOR >= 3
5905 daemon->cred_callback = va_arg (ap,
5907 daemon->cred_callback_cls = va_arg (ap,
5913 "MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3.\n"),
5919 #ifdef HAVE_MESSAGES
5927 "MHD HTTPS option %d passed to MHD compiled without HTTPS support.\n"),
5934 "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?).\n"),
5945 #ifdef EPOLL_SUPPORT
5951 #ifndef HAVE_MESSAGES
5955 #ifdef USE_EPOLL_CREATE1
5956 fd = epoll_create1 (EPOLL_CLOEXEC);
5958 fd = epoll_create (MAX_EVENTS);
5962 #ifdef HAVE_MESSAGES
5964 _ (
"Call to epoll_create1 failed: %s\n"),
5969 #if ! defined(USE_EPOLL_CREATE1)
5972 #ifdef HAVE_MESSAGES
5974 _ (
"Failed to set noninheritable mode on epoll FD.\n"));
5991 setup_epoll_to_listen (
struct MHD_Daemon *daemon)
5993 struct epoll_event event;
6000 MHD_ITC_IS_VALID_ (daemon->
itc) );
6001 daemon->epoll_fd = setup_epoll_fd (daemon);
6002 if (-1 == daemon->epoll_fd)
6004 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6007 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
6015 event.events = EPOLLIN;
6016 event.data.ptr = daemon;
6017 if (0 != epoll_ctl (daemon->epoll_fd,
6022 #ifdef HAVE_MESSAGES
6024 _ (
"Call to epoll_ctl failed: %s\n"),
6029 daemon->listen_socket_in_epoll =
true;
6032 if (MHD_ITC_IS_VALID_ (daemon->
itc))
6034 event.events = EPOLLIN;
6035 event.data.ptr = (
void *) epoll_itc_marker;
6036 if (0 != epoll_ctl (daemon->epoll_fd,
6038 MHD_itc_r_fd_ (daemon->
itc),
6041 #ifdef HAVE_MESSAGES
6043 _ (
"Call to epoll_ctl failed: %s\n"),
6089 struct sockaddr_in servaddr4;
6091 struct sockaddr_in6 servaddr6;
6093 const struct sockaddr *servaddr =
NULL;
6095 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6112 #ifndef EPOLL_SUPPORT
6116 #ifndef HTTPS_SUPPORT
6120 #ifndef TCP_FASTOPEN
6126 #ifdef UPGRADE_SUPPORT
6162 #if defined(EPOLL_SUPPORT)
6164 #elif defined(HAVE_POLL)
6173 #if defined(EPOLL_SUPPORT)
6183 #ifdef EPOLL_SUPPORT
6184 daemon->epoll_fd = -1;
6185 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6186 daemon->epoll_upgrade_fd = -1;
6190 #ifdef HTTPS_SUPPORT
6191 daemon->priority_cache =
NULL;
6194 gnutls_priority_init (&daemon->priority_cache,
6205 daemon->
port = port;
6216 MHD_itc_set_invalid_ (daemon->
itc);
6222 #ifdef HAVE_MESSAGES
6223 daemon->custom_error_log = &MHD_default_logger_;
6224 daemon->custom_error_log_cls = stderr;
6226 #ifndef MHD_WINSOCK_SOCKETS
6236 #ifdef HAVE_MESSAGES
6239 "Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with "
6240 "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD "
6241 "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"));
6249 #ifdef HAVE_LISTEN_SHUTDOWN
6254 #ifdef DAUTH_SUPPORT
6255 daemon->digest_auth_rand_size = 0;
6256 daemon->digest_auth_random =
NULL;
6257 daemon->nonce_nc_size = 4;
6259 #ifdef HTTPS_SUPPORT
6262 daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
6271 #ifdef HTTPS_SUPPORT
6273 (
NULL != daemon->priority_cache) )
6274 gnutls_priority_deinit (daemon->priority_cache);
6285 #ifdef HAVE_MESSAGES
6287 _ (
"Using debug build of libmicrohttpd.\n") );
6292 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6297 if (! MHD_itc_init_ (daemon->
itc))
6299 #ifdef HAVE_MESSAGES
6301 _ (
"Failed to create inter-thread communication channel: %s\n"),
6302 MHD_itc_last_strerror_ ());
6304 #ifdef HTTPS_SUPPORT
6305 if (
NULL != daemon->priority_cache)
6306 gnutls_priority_deinit (daemon->priority_cache);
6315 #ifdef HAVE_MESSAGES
6318 "file descriptor for inter-thread communication channel exceeds maximum value.\n"));
6321 #ifdef HTTPS_SUPPORT
6322 if (
NULL != daemon->priority_cache)
6323 gnutls_priority_deinit (daemon->priority_cache);
6330 #ifdef DAUTH_SUPPORT
6331 if (daemon->nonce_nc_size > 0)
6333 if ( ( (
size_t) (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc)))
6334 /
sizeof(
struct MHD_NonceNc) != daemon->nonce_nc_size)
6336 #ifdef HAVE_MESSAGES
6338 _ (
"Specified value for NC_SIZE too large.\n"));
6340 #ifdef HTTPS_SUPPORT
6342 gnutls_priority_deinit (daemon->priority_cache);
6347 daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc));
6348 if (
NULL == daemon->nnc)
6350 #ifdef HAVE_MESSAGES
6352 _ (
"Failed to allocate memory for nonce-nc map: %s\n"),
6355 #ifdef HTTPS_SUPPORT
6357 gnutls_priority_deinit (daemon->priority_cache);
6364 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6367 #ifdef HAVE_MESSAGES
6369 _ (
"MHD failed to initialize nonce-nc mutex.\n"));
6371 #ifdef HTTPS_SUPPORT
6373 gnutls_priority_deinit (daemon->priority_cache);
6383 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6387 #ifdef HAVE_MESSAGES
6390 "MHD thread polling only works with MHD_USE_INTERNAL_POLLING_THREAD.\n"));
6402 domain = (*pflags &
MHD_USE_IPv6) ? PF_INET6 : PF_INET;
6412 #ifdef HAVE_MESSAGES
6414 _ (
"Failed to create socket for listening: %s\n"),
6423 #ifndef MHD_WINSOCK_SOCKETS
6428 if (0 > setsockopt (listen_fd,
6431 (
void*) &on,
sizeof (on)))
6433 #ifdef HAVE_MESSAGES
6435 _ (
"setsockopt failed: %s\n"),
6444 #ifndef MHD_WINSOCK_SOCKETS
6447 if (0 > setsockopt (listen_fd,
6450 (
void*) &on,
sizeof (on)))
6452 #ifdef HAVE_MESSAGES
6454 _ (
"setsockopt failed: %s\n"),
6464 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT)
6465 if (0 > setsockopt (listen_fd,
6467 #ifndef MHD_WINSOCK_SOCKETS
6475 #ifdef HAVE_MESSAGES
6477 _ (
"setsockopt failed: %s\n"),
6485 #ifdef HAVE_MESSAGES
6488 "Cannot allow listening address reuse: SO_REUSEPORT not defined.\n"));
6501 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \
6502 (defined(__sun) && defined(SO_EXCLBIND))
6503 if (0 > setsockopt (listen_fd,
6505 #ifdef SO_EXCLUSIVEADDRUSE
6506 SO_EXCLUSIVEADDRUSE,
6513 #ifdef HAVE_MESSAGES
6515 _ (
"setsockopt failed: %s\n"),
6520 #elif defined(MHD_WINSOCK_SOCKETS)
6521 #ifdef HAVE_MESSAGES
6524 "Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined.\n"));
6533 addrlen =
sizeof (
struct sockaddr_in6);
6536 addrlen =
sizeof (
struct sockaddr_in);
6537 if (
NULL == servaddr)
6542 #ifdef IN6ADDR_ANY_INIT
6543 static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
6547 sizeof (
struct sockaddr_in6));
6548 servaddr6.sin6_family = AF_INET6;
6549 servaddr6.sin6_port = htons (port);
6550 #ifdef IN6ADDR_ANY_INIT
6551 servaddr6.sin6_addr = static_in6any;
6553 #if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
6554 servaddr6.sin6_len =
sizeof (
struct sockaddr_in6);
6556 servaddr = (
struct sockaddr *) &servaddr6;
6563 sizeof (
struct sockaddr_in));
6564 servaddr4.sin_family = AF_INET;
6565 servaddr4.sin_port = htons (port);
6566 if (0 != INADDR_ANY)
6567 servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
6568 #if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
6569 servaddr4.sin_len =
sizeof (
struct sockaddr_in);
6571 servaddr = (
struct sockaddr *) &servaddr4;
6586 if (0 > setsockopt (listen_fd,
6587 IPPROTO_IPV6, IPV6_V6ONLY,
6588 (
const void *) &v6_only,
6591 #ifdef HAVE_MESSAGES
6593 _ (
"setsockopt failed: %s\n"),
6600 if (-1 == bind (listen_fd, servaddr, addrlen))
6602 #ifdef HAVE_MESSAGES
6604 _ (
"Failed to bind to port %u: %s\n"),
6605 (
unsigned int) port,
6614 if (0 == daemon->fastopen_queue_size)
6615 daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
6616 if (0 != setsockopt (listen_fd,
6619 (
const void*) &daemon->fastopen_queue_size,
6620 sizeof (daemon->fastopen_queue_size)))
6622 #ifdef HAVE_MESSAGES
6624 _ (
"setsockopt failed: %s\n"),
6630 if (listen (listen_fd,
6633 #ifdef HAVE_MESSAGES
6635 _ (
"Failed to listen for connections: %s\n"),
6647 #ifdef HAVE_GETSOCKNAME
6648 if ( (0 == daemon->
port) &&
6651 struct sockaddr_storage bindaddr;
6655 sizeof (
struct sockaddr_storage));
6656 addrlen =
sizeof (
struct sockaddr_storage);
6657 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
6658 bindaddr.ss_len = addrlen;
6660 if (0 != getsockname (listen_fd,
6661 (
struct sockaddr *) &bindaddr,
6664 #ifdef HAVE_MESSAGES
6666 _ (
"Failed to get listen port number: %s\n"),
6670 #ifdef MHD_POSIX_SOCKETS
6671 else if (
sizeof (bindaddr) < addrlen)
6674 #ifdef HAVE_MESSAGES
6677 "Failed to get listen port number (`struct sockaddr_storage` too small!?).\n"));
6681 else if (0 == addrlen)
6691 switch (bindaddr.ss_family)
6695 struct sockaddr_in *s4 = (
struct sockaddr_in *) &bindaddr;
6697 daemon->
port = ntohs (s4->sin_port);
6703 struct sockaddr_in6 *s6 = (
struct sockaddr_in6 *) &bindaddr;
6705 daemon->
port = ntohs (s6->sin6_port);
6716 #ifdef HAVE_MESSAGES
6718 _ (
"Unknown address family!\n"));
6729 #ifdef HAVE_MESSAGES
6731 _ (
"Failed to set nonblocking mode on listening socket: %s\n"),
6735 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6752 #ifdef HAVE_MESSAGES
6754 _ (
"Listen socket descriptor (%d) is not " \
6755 "less than FD_SETSIZE (%d).\n"),
6763 #ifdef EPOLL_SUPPORT
6765 #
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6772 #ifdef HAVE_MESSAGES
6775 "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
6779 if (
MHD_NO == setup_epoll_to_listen (daemon))
6784 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6787 #ifdef HAVE_MESSAGES
6789 _ (
"MHD failed to initialize IP connection limit mutex.\n"));
6797 #ifdef HAVE_MESSAGES
6799 _ (
"MHD failed to initialize IP connection limit mutex.\n"));
6801 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6810 #ifdef HTTPS_SUPPORT
6813 (0 != MHD_TLS_init (daemon)) )
6815 #ifdef HAVE_MESSAGES
6817 _ (
"Failed to initialize TLS support.\n"));
6821 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6828 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6836 #ifdef HAVE_LISTEN_SHUTDOWN
6838 (MHD_ITC_IS_VALID_ (daemon->
itc)) || \
6842 (MHD_ITC_IS_VALID_ (daemon->
itc)));
6848 #ifdef HAVE_MESSAGES
6850 _ (
"Failed to initialise mutex.\n"));
6861 "MHD-listen" :
"MHD-single",
6862 daemon->thread_stack_size,
6866 #ifdef HAVE_MESSAGES
6868 _ (
"Failed to create listen thread: %s\n"),
6904 memcpy (d, daemon,
sizeof (
struct MHD_Daemon));
6913 #ifdef HAVE_MESSAGES
6915 _ (
"Failed to initialise mutex.\n"));
6921 if (! MHD_itc_init_ (d->
itc))
6923 #ifdef HAVE_MESSAGES
6926 "Failed to create worker inter-thread communication channel: %s\n"),
6927 MHD_itc_last_strerror_ () );
6936 #ifdef HAVE_MESSAGES
6939 "File descriptor for worker inter-thread communication channel exceeds maximum value.\n"));
6947 MHD_itc_set_invalid_ (d->
itc);
6949 #ifdef HAVE_LISTEN_SHUTDOWN
6960 if (i < leftover_conns)
6962 #ifdef EPOLL_SUPPORT
6964 (
MHD_NO == setup_epoll_to_listen (d)) )
6966 if (MHD_ITC_IS_VALID_ (d->
itc))
6975 #ifdef HAVE_MESSAGES
6977 _ (
"MHD failed to initialize cleanup connection mutex.\n"));
6979 if (MHD_ITC_IS_VALID_ (d->
itc))
6988 daemon->thread_stack_size,
6992 #ifdef HAVE_MESSAGES
6994 _ (
"Failed to create pool thread: %s\n"),
7000 if (MHD_ITC_IS_VALID_ (d->
itc))
7012 #ifdef HAVE_MESSAGES
7014 _ (
"Failed to initialise mutex.\n"));
7020 #ifdef HTTPS_SUPPORT
7023 daemon->https_key_password =
NULL;
7028 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7056 #ifdef EPOLL_SUPPORT
7057 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
7058 if (daemon->upgrade_fd_in_epoll)
7060 if (0 != epoll_ctl (daemon->epoll_fd,
7062 daemon->epoll_upgrade_fd,
7064 MHD_PANIC (
_ (
"Failed to remove FD from epoll set.\n"));
7065 daemon->upgrade_fd_in_epoll =
false;
7068 if (-1 != daemon->epoll_fd)
7069 close (daemon->epoll_fd);
7070 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
7071 if (-1 != daemon->epoll_upgrade_fd)
7072 close (daemon->epoll_upgrade_fd);
7075 #ifdef DAUTH_SUPPORT
7077 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7081 #ifdef HTTPS_SUPPORT
7084 gnutls_priority_deinit (daemon->priority_cache);
7085 if (daemon->x509_cred)
7086 gnutls_certificate_free_credentials (daemon->x509_cred);
7087 if (daemon->psk_cred)
7088 gnutls_psk_free_server_credentials (daemon->psk_cred);
7091 if (MHD_ITC_IS_VALID_ (daemon->
itc))
7112 #ifdef UPGRADE_SUPPORT
7115 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
7116 struct MHD_UpgradeResponseHandle *urh;
7117 struct MHD_UpgradeResponseHandle *urhn;
7121 #ifdef MHD_USE_THREADS
7124 MHD_thread_ID_match_current_ (daemon->
pid) );
7129 #ifdef MHD_USE_THREADS
7138 new_connection_close_ (daemon, pos);
7142 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
7145 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
7153 urh->clean_ready =
true;
7170 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7173 #ifdef UPGRADE_SUPPORT
7179 while (
NULL != susp)
7181 if (
NULL == susp->urh)
7183 "MHD_stop_daemon() called while we have suspended connections.\n"));
7184 #ifdef HTTPS_SUPPORT
7185 else if (used_tls &&
7187 (! susp->urh->clean_ready) )
7188 shutdown (susp->urh->app.socket,
7193 #ifdef HAVE_MESSAGES
7194 if (! susp->urh->was_closed)
7197 "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
7199 susp->urh->was_closed =
true;
7216 "MHD_stop_daemon() called while we have suspended connections.\n"));
7217 #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
7218 #ifdef MHD_USE_THREADS
7219 if (upg_allowed && used_tls && used_thr_p_c)
7237 if (! MHD_join_thread_ (pos->
pid.handle))
7238 MHD_PANIC (
_ (
"Failed to join a thread.\n"));
7250 #if MHD_WINSOCK_SOCKETS
7253 (! MHD_itc_activate_ (
daemon->
itc,
"e")) )
7255 "Failed to signal shutdown via inter-thread communication channel.\n"));
7259 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7269 if (! MHD_join_thread_ (pos->
pid.handle))
7270 MHD_PANIC (
_ (
"Failed to join a thread.\n"));
7284 #ifdef UPGRADE_SUPPORT
7300 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7303 MHD_PANIC (
_ (
"Failed to join a thread.\n"));
7321 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7328 MHD_PANIC (
_ (
"MHD_stop_daemon() was called twice."));
7338 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7353 "Failed to signal shutdown via inter-thread communication channel.\n"));
7358 #ifdef HAVE_LISTEN_SHUTDOWN
7361 (void) shutdown (
fd,
7371 #ifdef EPOLL_SUPPORT
7373 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
7381 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7391 "Failed to signal shutdown via inter-thread communication channel.\n"));
7395 #ifdef HAVE_LISTEN_SHUTDOWN
7399 (void) shutdown (
fd,
7407 if (! MHD_join_thread_ (
daemon->
pid.handle))
7409 MHD_PANIC (
_ (
"Failed to join a thread.\n"));
7419 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7427 #if defined(UPGRADE_SUPPORT) && defined (HTTPS_SUPPORT)
7434 #ifdef EPOLL_SUPPORT
7436 (-1 !=
daemon->epoll_fd) )
7438 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
7440 (-1 !=
daemon->epoll_upgrade_fd) )
7445 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7458 #ifdef HTTPS_SUPPORT
7459 if (
daemon->have_dhparams)
7461 gnutls_dh_params_deinit (
daemon->https_mem_dhparams);
7462 daemon->have_dhparams =
false;
7466 gnutls_priority_deinit (
daemon->priority_cache);
7468 gnutls_certificate_free_credentials (
daemon->x509_cred);
7470 gnutls_psk_free_server_credentials (
daemon->psk_cred);
7474 #ifdef DAUTH_SUPPORT
7476 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7480 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7514 #ifdef EPOLL_SUPPORT
7525 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7583 #ifdef PACKAGE_VERSION
7584 return PACKAGE_VERSION;
7586 static char ver[12] =
"\0\0\0\0\0\0\0\0\0\0\0";
7589 int res = MHD_snprintf_ (ver,
7595 if ((0 >= res) || (
sizeof(ver) <= res))
7620 #ifdef HAVE_MESSAGES
7626 #ifdef HTTPS_SUPPORT
7632 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3
7638 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030603
7650 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
7662 #ifdef EPOLL_SUPPORT
7668 #ifdef HAVE_LISTEN_SHUTDOWN
7674 #ifdef _MHD_ITC_SOCKETPAIR
7686 #ifdef BAUTH_SUPPORT
7692 #ifdef DAUTH_SUPPORT
7698 #ifdef HAVE_POSTPROCESSOR
7704 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111
7710 #if defined(HAVE_PREAD64) || defined(_WIN32)
7712 #elif defined(HAVE_PREAD)
7713 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
7714 #elif defined(HAVE_LSEEK64)
7717 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
7720 #if defined(MHD_USE_THREAD_NAME_)
7726 #if defined(UPGRADE_SUPPORT)
7732 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32)
7738 #ifdef MHD_USE_GETSOCKNAME
7744 #if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || \
7745 defined (MSG_NOSIGNAL)
7751 #ifdef _MHD_HAVE_SENDFILE
7757 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7768 #ifdef MHD_HTTPS_REQUIRE_GRYPT
7769 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600
7770 #if defined(MHD_USE_POSIX_THREADS)
7771 GCRY_THREAD_OPTION_PTHREAD_IMPL;
7772 #elif defined(MHD_W32_MUTEX_)
7775 gcry_w32_mutex_init (
void **ppmtx)
7777 *ppmtx = malloc (
sizeof (MHD_mutex_));
7793 gcry_w32_mutex_destroy (
void **ppmtx)
7802 gcry_w32_mutex_lock (
void **ppmtx)
7809 gcry_w32_mutex_unlock (
void **ppmtx)
7815 static struct gcry_thread_cbs gcry_threads_w32 = {
7816 (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
7817 NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
7818 gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
7832 #if defined(MHD_WINSOCK_SOCKETS)
7839 #if defined(MHD_WINSOCK_SOCKETS)
7840 if (0 != WSAStartup (MAKEWORD (2, 2), &wsd))
7841 MHD_PANIC (
_ (
"Failed to initialize winsock.\n"));
7842 mhd_winsock_inited_ = 1;
7843 if ((2 != LOBYTE (wsd.wVersion)) && (2 != HIBYTE (wsd.wVersion)))
7844 MHD_PANIC (
_ (
"Winsock version 2.2 is not available.\n"));
7846 #ifdef HTTPS_SUPPORT
7847 #ifdef MHD_HTTPS_REQUIRE_GRYPT
7848 #if GCRYPT_VERSION_NUMBER < 0x010600
7849 #if defined(MHD_USE_POSIX_THREADS)
7850 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7851 &gcry_threads_pthread))
7852 MHD_PANIC (
_ (
"Failed to initialise multithreading in libgcrypt.\n"));
7853 #elif defined(MHD_W32_MUTEX_)
7854 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7856 MHD_PANIC (
_ (
"Failed to initialise multithreading in libgcrypt.\n"));
7858 gcry_check_version (
NULL);
7860 if (
NULL == gcry_check_version (
"1.6.0"))
7862 "libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer.\n"));
7865 gnutls_global_init ();
7868 #ifdef HAVE_FREEBSD_SENDFILE
7869 MHD_send_init_static_vars_ ();
7878 #ifdef HTTPS_SUPPORT
7879 gnutls_global_deinit ();
7881 #if defined(MHD_WINSOCK_SOCKETS)
7882 if (mhd_winsock_inited_)
7889 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
#define _SET_INIT_AND_DEINIT_FUNCS(FI, FD)
void MHD_connection_handle_read(struct MHD_Connection *connection)
void MHD_connection_handle_write(struct MHD_Connection *connection)
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
enum MHD_Result MHD_connection_handle_idle(struct MHD_Connection *connection)
Methods for managing connections.
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ thread_main_handle_connection(void *data)
void MHD_connection_mark_closed_(struct MHD_Connection *connection)
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode rtc)
void MHD_connection_finish_forward_(struct MHD_Connection *connection) MHD_NONNULL(1)
void MHD_set_https_callbacks(struct MHD_Connection *connection)
Methods for managing connections.
void MHD_update_last_activity_(struct MHD_Connection *connection)
void MHD_suspend_connection(struct MHD_Connection *connection)
static void close_all_connections(struct MHD_Daemon *daemon)
static struct MHD_Daemon * MHD_get_master(struct MHD_Daemon *daemon)
static enum MHD_Result MHD_select(struct MHD_Daemon *daemon, int may_block)
MHD_PanicCallback mhd_panic
static enum MHD_Result MHD_ip_limit_add(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
void MHD_resume_connection(struct MHD_Connection *connection)
void internal_suspend_connection_(struct MHD_Connection *connection)
static enum MHD_Result parse_options_va(struct MHD_Daemon *daemon, const struct sockaddr **servaddr, va_list ap)
static enum MHD_Result call_handlers(struct MHD_Connection *con, bool read_ready, bool write_ready, bool force_close)
static void MHD_ip_count_unlock(struct MHD_Daemon *daemon)
volatile int global_init_count
static enum MHD_Result MHD_poll(struct MHD_Daemon *daemon, int may_block)
void MHD_check_global_init_(void)
static void close_connection(struct MHD_Connection *pos)
static struct MHD_Connection * new_connection_prepare_(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen, bool external_add, bool non_blck, bool sk_spipe_supprs)
static int MHD_ip_addr_compare(const void *a1, const void *a2)
static void new_connections_list_process_(struct MHD_Daemon *daemon)
static void MHD_cleanup_connections(struct MHD_Daemon *daemon)
void(* VfprintfFunctionPointerType)(void *cls, const char *format, va_list va)
static enum MHD_Result MHD_accept_connection(struct MHD_Daemon *daemon)
static void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
#define MHD_MAX_CONNECTIONS_DEFAULT
static size_t unescape_wrapper(void *cls, struct MHD_Connection *connection, char *val)
static enum MHD_Result new_connection_process_(struct MHD_Daemon *daemon, struct MHD_Connection *connection)
static void MHD_ip_count_lock(struct MHD_Daemon *daemon)
static enum MHD_Result MHD_ip_addr_to_key(const struct sockaddr *addr, socklen_t addrlen, struct MHD_IPCount *key)
static enum MHD_Result parse_options(struct MHD_Daemon *daemon, const struct sockaddr **servaddr,...)
static enum MHD_Result internal_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen, bool external_add, bool non_blck, bool sk_spipe_supprs)
static enum MHD_Result resume_suspended_connections(struct MHD_Daemon *daemon)
#define MHD_POOL_SIZE_DEFAULT
static void mhd_panic_std(void *cls, const char *file, unsigned int line, const char *reason)
_MHD_EXTERN void MHD_free(void *ptr)
static enum MHD_Result 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)
static enum MHD_Result 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)
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ MHD_polling_thread(void *cls)
_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,...)
_MHD_EXTERN enum MHD_Result 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)
_MHD_EXTERN void MHD_stop_daemon(struct MHD_Daemon *daemon)
_MHD_EXTERN enum MHD_Result 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)
_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)
_MHD_EXTERN enum MHD_Result MHD_run(struct MHD_Daemon *daemon)
_MHD_EXTERN enum MHD_Result MHD_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
_MHD_EXTERN enum MHD_Result 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(* MHD_PanicCallback)(void *cls, const char *file, unsigned int line, const char *reason)
_MHD_EXTERN void MHD_set_panic_func(MHD_PanicCallback cb, void *cls)
void(* MHD_NotifyConnectionCallback)(void *cls, struct MHD_Connection *connection, void **socket_context, enum MHD_ConnectionNotificationCode toe)
void(* MHD_RequestCompletedCallback)(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
@ MHD_CONNECTION_NOTIFY_STARTED
@ MHD_CONNECTION_NOTIFY_CLOSED
@ MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN
@ MHD_REQUEST_TERMINATED_COMPLETED_OK
@ MHD_REQUEST_TERMINATED_WITH_ERROR
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
_MHD_EXTERN const union MHD_DaemonInfo * MHD_get_daemon_info(struct MHD_Daemon *daemon, enum MHD_DaemonInfoType info_type,...)
_MHD_EXTERN MHD_socket MHD_quiesce_daemon(struct MHD_Daemon *daemon)
_MHD_EXTERN enum MHD_Result MHD_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen)
_MHD_EXTERN enum MHD_Result MHD_is_feature_supported(enum MHD_FEATURE feature)
_MHD_EXTERN const char * MHD_get_version(void)
#define XDLL_insert(head, tail, element)
@ MHD_EPOLL_STATE_SUSPENDED
@ MHD_EPOLL_STATE_IN_EREADY_EDLL
@ MHD_EPOLL_STATE_READ_READY
@ MHD_EPOLL_STATE_IN_EPOLL_SET
@ MHD_EPOLL_STATE_WRITE_READY
#define DLL_insert(head, tail, element)
#define EDLL_insert(head, tail, element)
#define EDLL_remove(head, tail, element)
#define XDLL_remove(head, tail, element)
#define DLL_remove(head, tail, element)
void MHD_pool_destroy(struct MemoryPool *pool)
struct MemoryPool * MHD_pool_create(size_t max)
void * MHD_calloc_(size_t nelem, size_t elsize)
#define MHD_strerror_(errnum)
#define MHD_ITC_IS_INVALID_(itc)
#define MHD_itc_destroy_chk_(itc)
#define MHD_TYPE_IS_SIGNED_(type)
#define TIMEVAL_TV_SEC_MAX
#define MHD_mutex_unlock_chk_(pmutex)
#define MHD_mutex_destroy_chk_(pmutex)
#define MHD_mutex_lock_chk_(pmutex)
void MHD_monotonic_sec_counter_finish(void)
time_t MHD_monotonic_sec_counter(void)
void MHD_monotonic_sec_counter_init(void)
int MHD_add_to_fd_set_(MHD_socket fd, fd_set *set, MHD_socket *max_fd, unsigned int fd_setsize)
int MHD_socket_noninheritable_(MHD_socket sock)
int MHD_socket_nonblocking_(MHD_socket sock)
MHD_socket MHD_socket_create_listen_(int pf)
#define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)
#define MHD_SCKT_ERR_IS_(err, code)
#define MHD_socket_close_(fd)
#define MHD_SCKT_ERR_IS_EAGAIN_(err)
#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)
#define _MHD_SYS_DEFAULT_FD_SETSIZE
#define MHD_socket_strerr_(err)
#define MHD_socket_last_strerr_()
#define MHD_socket_get_error_()
#define MHD_socket_close_chk_(fd)
#define MHD_SCKT_ERR_IS_EINTR_(err)
#define MHD_socket_fset_error_(err)
#define MHD_SCKT_SEND_MAX_SIZE_
#define MHD_recv_(s, b, l)
#define MHD_send_(s, b, l)
#define MHD_SCKT_LAST_ERR_IS_(code)
#define MHD_SYS_select_(n, r, w, e, t)
#define MHD_SCKT_FD_FITS_FDSET_(fd, pset)
#define MHD_create_named_thread_(t, n, s, r, a)
void * tsearch(const void *vkey, void **vrootp, int(*compar)(const void *, const void *))
void * tfind(const void *vkey, void *const *vrootp, int(*compar)(const void *, const void *))
void * tdelete(const void *__restrict vkey, void **__restrict vrootp, int(*compar)(const void *, const void *))
Declarations of send() wrappers.
internal shared structures
@ MHD_CONNECTION_HEADERS_SENDING
@ MHD_CONNECTION_NORMAL_BODY_READY
@ MHD_CONNECTION_CHUNKED_BODY_READY
@ MHD_EVENT_LOOP_INFO_READ
@ MHD_EVENT_LOOP_INFO_WRITE
@ MHD_EVENT_LOOP_INFO_CLEANUP
@ MHD_EVENT_LOOP_INFO_BLOCK
void *(* LogCallback)(void *cls, const char *uri, struct MHD_Connection *con)
#define MHD_TEST_ALLOW_SUSPEND_RESUME
size_t(* UnescapeCallback)(void *cls, struct MHD_Connection *conn, char *uri)
void MHD_init_mem_pools_(void)
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...
Header for platform missing functions.
Header for platform-independent inter-thread communication.
limits values definitions
#define MHD_mutex_destroy_(ignore)
#define MHD_mutex_unlock_(ignore)
#define MHD_mutex_lock_(ignore)
#define MHD_mutex_init_(ignore)
internal monotonic clock functions implementations
#define SOCK_NONBLOCK_OR_ZERO
#define SOCK_NOSIGPIPE_OR_ZERO
#define SOCK_CLOEXEC_OR_ZERO
@ MHD_FEATURE_POSTPROCESSOR
@ MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET
@ MHD_FEATURE_AUTODETECT_BIND_PORT
@ MHD_FEATURE_HTTPS_CERT_CALLBACK
@ MHD_FEATURE_DIGEST_AUTH
@ MHD_FEATURE_THREAD_NAMES
@ MHD_FEATURE_HTTPS_KEY_PASSWORD
@ MHD_FEATURE_AUTOSUPPRESS_SIGPIPE
@ MHD_FEATURE_RESPONSES_SHARED_FD
@ MHD_FEATURE_TCP_FASTOPEN
@ MHD_FEATURE_HTTPS_CERT_CALLBACK2
@ MHD_OPTION_CONNECTION_MEMORY_INCREMENT
@ MHD_OPTION_HTTPS_CRED_TYPE
@ MHD_OPTION_URI_LOG_CALLBACK
@ MHD_OPTION_HTTPS_CERT_CALLBACK2
@ MHD_OPTION_UNESCAPE_CALLBACK
@ MHD_OPTION_EXTERNAL_LOGGER
@ MHD_OPTION_LISTEN_BACKLOG_SIZE
@ MHD_OPTION_HTTPS_PRIORITIES
@ MHD_OPTION_HTTPS_MEM_DHPARAMS
@ MHD_OPTION_NOTIFY_CONNECTION
@ MHD_OPTION_LISTENING_ADDRESS_REUSE
@ MHD_OPTION_THREAD_POOL_SIZE
@ MHD_OPTION_CONNECTION_LIMIT
@ MHD_OPTION_PER_IP_CONNECTION_LIMIT
@ MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE
@ MHD_OPTION_HTTPS_MEM_CERT
@ MHD_OPTION_SERVER_INSANITY
@ MHD_OPTION_LISTEN_SOCKET
@ MHD_OPTION_HTTPS_MEM_KEY
@ MHD_OPTION_DIGEST_AUTH_RANDOM
@ MHD_OPTION_HTTPS_KEY_PASSWORD
@ MHD_OPTION_NONCE_NC_SIZE
@ MHD_OPTION_CONNECTION_MEMORY_LIMIT
@ MHD_OPTION_THREAD_STACK_SIZE
@ MHD_OPTION_STRICT_FOR_CLIENT
@ MHD_OPTION_CONNECTION_TIMEOUT
@ MHD_OPTION_GNUTLS_PSK_CRED_HANDLER
@ MHD_OPTION_HTTPS_MEM_TRUST
@ MHD_OPTION_HTTPS_CERT_CALLBACK
@ MHD_OPTION_NOTIFY_COMPLETED
enum MHD_Result(* MHD_AcceptPolicyCallback)(void *cls, const struct sockaddr *addr, socklen_t addrlen)
#define MHD_UNSIGNED_LONG_LONG
#define MHD_UNSIGNED_LONG_LONG_PRINTF
_MHD_EXTERN size_t MHD_http_unescape(char *val)
#define MHD_INVALID_SOCKET
enum MHD_Result(* 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)
int(* MHD_PskServerCredentialsCallback)(void *cls, const struct MHD_Connection *connection, const char *username, void **psk, size_t *psk_size)
@ MHD_DAEMON_INFO_MAC_KEY_SIZE
@ MHD_DAEMON_INFO_BIND_PORT
@ MHD_DAEMON_INFO_EPOLL_FD
@ MHD_DAEMON_INFO_KEY_SIZE
@ MHD_DAEMON_INFO_CURRENT_CONNECTIONS
@ MHD_DAEMON_INFO_LISTEN_FD
MHD_FLAG
Flags for the struct MHD_Daemon.
@ MHD_ALLOW_SUSPEND_RESUME
@ MHD_USE_THREAD_PER_CONNECTION
@ MHD_USE_POST_HANDSHAKE_AUTH_SUPPORT
@ MHD_USE_INSECURE_TLS_EARLY_DATA
@ MHD_USE_NO_LISTEN_SOCKET
@ MHD_USE_PEDANTIC_CHECKS
@ MHD_USE_INTERNAL_POLLING_THREAD
Methods for managing response objects.
enum MHD_tristate sk_nodelay
struct MHD_Connection * prevX
enum MHD_ConnectionEventLoopInfo event_loop_info
struct MHD_Response * response
struct MHD_Connection * next
time_t connection_timeout
struct sockaddr_storage addr
size_t read_buffer_offset
struct MHD_Connection * prev
MHD_thread_handle_ID_ pid
struct MHD_Connection * nextX
enum MHD_CONNECTION_STATE state
struct MHD_Daemon * daemon
enum MHD_tristate sk_corked
MHD_NotifyConnectionCallback notify_connection
MHD_AccessHandlerCallback default_handler
LogCallback uri_log_callback
bool data_already_pending
MHD_mutex_ per_ip_connection_mutex
void * per_ip_connection_count
struct MHD_Connection * new_connections_tail
unsigned int connection_limit
void * unescape_callback_cls
MHD_mutex_ cleanup_connection_mutex
enum MHD_DisableSanityCheck insanity_level
struct MHD_Connection * connections_head
unsigned int listen_backlog_size
MHD_RequestCompletedCallback notify_completed
unsigned int worker_pool_size
int listening_address_reuse
unsigned int per_ip_connection_limit
struct MHD_Connection * manual_timeout_tail
void * notify_connection_cls
UnescapeCallback unescape_callback
void * notify_completed_cls
struct MHD_Connection * cleanup_tail
struct MHD_Daemon * worker_pool
struct MHD_Connection * new_connections_head
MHD_thread_handle_ID_ pid
struct MHD_Connection * manual_timeout_head
void * default_handler_cls
struct MHD_Connection * suspended_connections_tail
time_t connection_timeout
MHD_AcceptPolicyCallback apc
struct MHD_Connection * cleanup_head
struct MHD_Daemon * master
struct MHD_Connection * normal_timeout_head
struct MHD_Connection * normal_timeout_tail
void * uri_log_callback_cls
struct MHD_Connection * suspended_connections_head
struct MHD_Connection * connections_tail