50 #ifdef MHD_HTTPS_REQUIRE_GRYPT 55 #if defined(_WIN32) && ! defined(__CYGWIN__) 56 #ifndef WIN32_LEAN_AND_MEAN 57 #define WIN32_LEAN_AND_MEAN 1 65 #ifdef MHD_POSIX_SOCKETS 66 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 4) 68 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 2) 74 #define MHD_POOL_SIZE_DEFAULT (32 * 1024) 80 #define DEBUG_CLOSE MHD_NO 86 #define DEBUG_CONNECT MHD_NO 136 _(
"Fatal error in GNU libmicrohttpd %s:%u: %s\n"),
166 #if defined(_WIN32) && ! defined(__CYGWIN__) 170 static int mhd_winsock_inited_ = 0;
173 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED 178 #define MHD_check_global_init_() (void)0 184 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 188 MHD_MUTEX_STATIC_DEFN_INIT_(global_init_mutex_);
197 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 202 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 247 struct in6_addr ipv6;
297 offsetof (
struct MHD_IPCount,
313 struct MHD_IPCount *key)
320 if (
sizeof (
struct sockaddr_in) == addrlen)
322 const struct sockaddr_in *addr4 = (
const struct sockaddr_in*) addr;
324 key->family = AF_INET;
325 memcpy (&key->addr.ipv4,
327 sizeof(addr4->sin_addr));
333 if (
sizeof (
struct sockaddr_in6) == addrlen)
335 const struct sockaddr_in6 *addr6 = (
const struct sockaddr_in6*) addr;
337 key->family = AF_INET6;
338 memcpy (&key->addr.ipv6,
340 sizeof(addr6->sin6_addr));
363 const struct sockaddr *addr,
366 struct MHD_IPCount *key;
376 if (
NULL == (key = malloc (
sizeof(*key))))
397 _(
"Failed to add IP connection count node\n"));
407 key = (
struct MHD_IPCount *) node;
429 const struct sockaddr *addr,
432 struct MHD_IPCount search_key;
433 struct MHD_IPCount *found_key;
455 MHD_PANIC (
_(
"Failed to find previously-added IP address\n"));
457 found_key = (
struct MHD_IPCount *) *nodep;
459 if (0 == found_key->count)
461 MHD_PANIC (
_(
"Previously-added IP address had counter of zero\n"));
464 if (0 == --found_key->count)
484 MHD_init_daemon_certificate (
struct MHD_Daemon *daemon)
490 #if GNUTLS_VERSION_MAJOR >= 3 491 if (
NULL != daemon->cert_callback)
493 gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
494 daemon->cert_callback);
497 if (
NULL != daemon->https_mem_trust)
499 cert.data = (
unsigned char *) daemon->https_mem_trust;
500 cert.size = strlen (daemon->https_mem_trust);
501 if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred,
503 GNUTLS_X509_FMT_PEM) < 0)
507 "Bad trust certificate format\n");
513 if (daemon->have_dhparams)
515 gnutls_certificate_set_dh_params (daemon->x509_cred,
516 daemon->https_mem_dhparams);
519 if ( (
NULL != daemon->https_mem_cert) &&
520 (
NULL != daemon->https_mem_key) )
522 key.data = (
unsigned char *) daemon->https_mem_key;
523 key.size = strlen (daemon->https_mem_key);
524 cert.data = (
unsigned char *) daemon->https_mem_cert;
525 cert.size = strlen (daemon->https_mem_cert);
527 if (
NULL != daemon->https_key_password) {
528 #if GNUTLS_VERSION_NUMBER >= 0x030111 529 ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
533 daemon->https_key_password,
538 _(
"Failed to setup x509 certificate/key: pre 3.X.X version " \
539 "of GnuTLS does not support setting key password"));
545 ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
548 GNUTLS_X509_FMT_PEM);
552 "GnuTLS failed to setup x509 certificate/key: %s\n",
553 gnutls_strerror (ret));
557 #if GNUTLS_VERSION_MAJOR >= 3 558 if (
NULL != daemon->cert_callback)
563 "You need to specify a certificate and key location\n");
578 switch (daemon->cred_type)
580 case GNUTLS_CRD_CERTIFICATE:
582 gnutls_certificate_allocate_credentials (&daemon->x509_cred))
583 return GNUTLS_E_MEMORY_ERROR;
584 return MHD_init_daemon_certificate (daemon);
588 _(
"Error: invalid credentials type %d specified.\n"),
631 fd_set *write_fd_set,
632 fd_set *except_fd_set,
644 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 658 urh_to_fdset (
struct MHD_UpgradeResponseHandle *urh,
663 unsigned int fd_setsize)
665 const MHD_socket conn_sckt = urh->connection->socket_fd;
673 if ( (urh->in_buffer_used < urh->in_buffer_size) &&
679 if ( (0 != urh->out_buffer_used) &&
688 ((0 != urh->in_buffer_size) ||
689 (0 != urh->out_buffer_size) ||
690 (0 != urh->out_buffer_used)))
698 if ( (urh->out_buffer_used < urh->out_buffer_size) &&
704 if ( (0 != urh->in_buffer_used) &&
713 ((0 != urh->out_buffer_size) ||
714 (0 != urh->in_buffer_size) ||
715 (0 != urh->in_buffer_used)))
736 urh_from_fdset (
struct MHD_UpgradeResponseHandle *urh,
741 const MHD_socket conn_sckt = urh->connection->socket_fd;
750 if (FD_ISSET (conn_sckt, rs))
752 if (FD_ISSET (conn_sckt, ws))
754 if (FD_ISSET (conn_sckt, es))
759 if (FD_ISSET (mhd_sckt, rs))
761 if (FD_ISSET (mhd_sckt, ws))
763 if (FD_ISSET (mhd_sckt, es))
779 urh_update_pollfd(
struct MHD_UpgradeResponseHandle *urh,
785 if (urh->in_buffer_used < urh->in_buffer_size)
786 p[0].events |= POLLIN;
787 if (0 != urh->out_buffer_used)
788 p[0].events |= POLLOUT;
793 ((0 != urh->in_buffer_size) ||
794 (0 != urh->out_buffer_size) ||
795 (0 != urh->out_buffer_used)))
796 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
798 if (urh->out_buffer_used < urh->out_buffer_size)
799 p[1].events |= POLLIN;
800 if (0 != urh->in_buffer_used)
801 p[1].events |= POLLOUT;
806 ((0 != urh->out_buffer_size) ||
807 (0 != urh->in_buffer_size) ||
808 (0 != urh->in_buffer_used)))
809 p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
820 urh_to_pollfd(
struct MHD_UpgradeResponseHandle *urh,
823 p[0].fd = urh->connection->socket_fd;
824 p[1].fd = urh->mhd.socket;
825 urh_update_pollfd(urh, p);
835 urh_from_pollfd(
struct MHD_UpgradeResponseHandle *urh,
842 if (0 != (p[0].revents & POLLIN))
844 if (0 != (p[0].revents & POLLOUT))
846 if (0 != (p[0].revents & POLLHUP))
848 if (0 != (p[0].revents & MHD_POLL_REVENTS_ERRROR))
850 if (0 != (p[1].revents & POLLIN))
852 if (0 != (p[1].revents & POLLOUT))
854 if (0 != (p[1].revents & POLLHUP))
856 if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
880 fd_set *write_fd_set,
881 fd_set *except_fd_set,
883 unsigned int fd_setsize)
919 #ifdef MHD_POSIX_SOCKETS 932 #ifdef MHD_POSIX_SOCKETS 940 if ( (
NULL == except_fd_set) ||
952 #ifdef MHD_WINSOCK_SOCKETS 965 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 967 struct MHD_UpgradeResponseHandle *urh;
969 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
986 _(
"Maximum socket in select set: %d\n"),
1028 fd_set *read_fd_set,
1029 fd_set *write_fd_set,
1030 fd_set *except_fd_set,
1032 unsigned int fd_setsize)
1036 if ( (
NULL == daemon) ||
1037 (
NULL == read_fd_set) ||
1038 (
NULL == write_fd_set) ||
1043 if (
NULL == except_fd_set)
1045 #ifdef HAVE_MESSAGES 1047 _(
"MHD_get_fdset2() called with except_fd_set " 1048 "set to NULL. Such behavior is unsupported.\n"));
1051 except_fd_set = &es;
1054 #ifdef EPOLL_SUPPORT 1099 bool states_info_processed =
false;
1103 #ifdef HTTPS_SUPPORT 1104 if (con->tls_read_ready)
1114 states_info_processed =
true;
1123 states_info_processed =
true;
1133 if (!states_info_processed)
1180 #ifdef HTTPS_SUPPORT 1181 else if ( (con->tls_read_ready) &&
1190 #ifdef UPGRADE_SUPPORT 1201 struct MHD_UpgradeResponseHandle *urh = connection->urh;
1205 #ifdef HTTPS_SUPPORT 1209 gnutls_bye (connection->tls_session,
1218 connection->urh =
NULL;
1224 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 1234 process_urh (
struct MHD_UpgradeResponseHandle *urh)
1249 #ifdef HAVE_MESSAGES 1250 if (! urh->was_closed)
1253 _(
"Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
1256 urh->was_closed =
true;
1258 was_closed = urh->was_closed;
1263 if (0 < urh->in_buffer_used)
1265 #ifdef HAVE_MESSAGES 1268 " bytes of data received from remote side: application shut down socket\n"),
1278 if (0 != urh->out_buffer_size)
1281 urh->in_buffer_used = 0;
1285 urh->in_buffer_size = 0;
1287 connection->tls_read_ready =
false;
1307 (connection->tls_read_ready) ) &&
1308 (urh->in_buffer_used < urh->in_buffer_size) )
1313 buf_size = urh->in_buffer_size - urh->in_buffer_used;
1314 if (buf_size > SSIZE_MAX)
1315 buf_size = SSIZE_MAX;
1317 connection->tls_read_ready =
false;
1318 res = gnutls_record_recv (connection->tls_session,
1319 &urh->in_buffer[urh->in_buffer_used],
1323 if (GNUTLS_E_INTERRUPTED != res)
1326 if (GNUTLS_E_AGAIN != res)
1331 urh->in_buffer_size = 0;
1337 urh->in_buffer_used += res;
1338 if (buf_size > (
size_t)res)
1340 else if (0 < gnutls_record_check_pending (connection->tls_session))
1341 connection->tls_read_ready =
true;
1349 urh->in_buffer_size = 0;
1357 (urh->out_buffer_used < urh->out_buffer_size) )
1362 buf_size = urh->out_buffer_size - urh->out_buffer_used;
1367 &urh->out_buffer[urh->out_buffer_used],
1386 urh->out_buffer_size = 0;
1392 urh->out_buffer_used += res;
1393 if (buf_size > (
size_t)res)
1403 urh->out_buffer_size = 0;
1411 (urh->out_buffer_used > 0) )
1416 data_size = urh->out_buffer_used;
1417 if (data_size > SSIZE_MAX)
1418 data_size = SSIZE_MAX;
1420 res = gnutls_record_send (connection->tls_session,
1425 if (GNUTLS_E_INTERRUPTED != res)
1428 if (GNUTLS_E_INTERRUPTED != res)
1432 #ifdef HAVE_MESSAGES 1435 " bytes of data received from application: %s\n"),
1437 gnutls_strerror(res));
1440 urh->out_buffer_used = 0;
1442 urh->out_buffer_size = 0;
1449 const size_t next_out_buffer_used = urh->out_buffer_used - res;
1450 if (0 != next_out_buffer_used)
1452 memmove (urh->out_buffer,
1453 &urh->out_buffer[res],
1454 next_out_buffer_used);
1455 if (data_size > (
size_t)res)
1458 urh->out_buffer_used = next_out_buffer_used;
1460 if ( (0 == urh->out_buffer_used) &&
1468 urh->out_buffer_size = 0;
1477 (urh->in_buffer_used > 0) )
1482 data_size = urh->in_buffer_used;
1500 #ifdef HAVE_MESSAGES 1503 " bytes of data received from remote side: %s\n"),
1508 urh->in_buffer_used = 0;
1510 urh->in_buffer_size = 0;
1512 connection->tls_read_ready =
false;
1518 const size_t next_in_buffer_used = urh->in_buffer_used - res;
1519 if (0 != next_in_buffer_used)
1521 memmove (urh->in_buffer,
1522 &urh->in_buffer[res],
1523 next_in_buffer_used);
1524 if (data_size > (
size_t)res)
1527 urh->in_buffer_used = next_in_buffer_used;
1529 if ( (0 == urh->in_buffer_used) &&
1535 urh->in_buffer_size = 0;
1537 connection->tls_read_ready =
false;
1543 if ( (connection->tls_read_ready) &&
1544 (urh->in_buffer_used < urh->in_buffer_size) &&
1549 ( (0 != urh->out_buffer_size) ||
1550 (0 != urh->out_buffer_used) ) )
1553 #ifdef HAVE_MESSAGES 1554 if (0 < urh->out_buffer_used)
1557 " bytes of data received from application: daemon shut down\n"),
1561 urh->out_buffer_used = 0;
1565 urh->out_buffer_size = 0;
1572 #ifdef UPGRADE_SUPPORT 1584 #ifdef HTTPS_SUPPORT 1585 struct MHD_UpgradeResponseHandle *urh = con->urh;
1594 while ( (0 != urh->in_buffer_size) ||
1595 (0 != urh->out_buffer_size) ||
1596 (0 != urh->in_buffer_used) ||
1597 (0 != urh->out_buffer_used) )
1611 result = urh_to_fdset (urh,
1619 #ifdef HAVE_MESSAGES 1621 _(
"Error preparing select\n"));
1628 struct timeval* tvp;
1630 if ( (con->tls_read_ready) &&
1631 (urh->in_buffer_used < urh->in_buffer_size))
1653 #ifdef HAVE_MESSAGES 1655 _(
"Error during select (%d): `%s'\n"),
1661 urh_from_fdset (urh,
1676 p[0].fd = urh->connection->socket_fd;
1677 p[1].fd = urh->mhd.socket;
1679 while ( (0 != urh->in_buffer_size) ||
1680 (0 != urh->out_buffer_size) ||
1681 (0 != urh->in_buffer_used) ||
1682 (0 != urh->out_buffer_used) )
1686 urh_update_pollfd(urh, p);
1688 if ( (con->tls_read_ready) &&
1689 (urh->in_buffer_used < urh->in_buffer_size))
1694 if (MHD_sys_poll_ (p,
1702 #ifdef HAVE_MESSAGES 1704 _(
"Error during poll: `%s'\n"),
1709 urh_from_pollfd(urh, p);
1732 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
1743 struct timeval *tvp;
1749 #define EXTRA_SLOTS 1 1751 #define EXTRA_SLOTS 0 1760 const bool use_poll = 0;
1762 bool was_suspended =
false;
1763 MHD_thread_init_(&(con->
pid));
1769 #ifdef UPGRADE_SUPPORT 1770 struct MHD_UpgradeResponseHandle *
const urh = con->urh;
1772 static const void *
const urh =
NULL;
1779 was_suspended =
true;
1788 #ifdef HAVE_MESSAGES 1790 _(
"Failed to add FD to fd_set\n"));
1804 #ifdef HAVE_MESSAGES 1806 _(
"Error during select (%d): `%s'\n"),
1816 p[0].events = POLLIN;
1817 p[0].fd = MHD_itc_r_fd_ (daemon->
itc);
1819 if (0 > MHD_sys_poll_ (p,
1825 #ifdef HAVE_MESSAGES 1827 _(
"Error during poll: `%s'\n"),
1834 MHD_itc_clear_ (daemon->
itc);
1843 was_suspended =
false;
1849 #ifdef HTTPS_SUPPORT
1850 || ( (con->tls_read_ready) &&
1861 if ( (
NULL == tvp) &&
1869 const time_t seconds_left = timeout - (now - con->
last_activity);
1870 #if !defined(_WIN32) || defined(__CYGWIN__) 1871 tv.tv_sec = seconds_left;
1885 bool err_state =
false;
1919 if (MHD_ITC_IS_VALID_(daemon->
itc) )
1930 #ifdef HAVE_MESSAGES 1932 _(
"Failed to add FD to fd_set\n"));
1948 #ifdef HAVE_MESSAGES 1950 _(
"Error during select (%d): `%s'\n"),
1959 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
1960 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
1962 MHD_itc_clear_ (daemon->
itc);
1985 p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
1988 p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
1991 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
1999 if (MHD_ITC_IS_VALID_(daemon->
itc))
2001 p[1].events |= POLLIN;
2002 p[1].fd = MHD_itc_r_fd_ (daemon->
itc);
2007 if (MHD_sys_poll_ (p,
2013 (
NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
2017 #ifdef HAVE_MESSAGES 2019 _(
"Error during poll: `%s'\n"),
2027 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2028 (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
2029 MHD_itc_clear_ (daemon->
itc);
2033 0 != (p[0].revents & POLLIN),
2034 0 != (p[0].revents & POLLOUT),
2035 0 != (p[0].revents & (POLLERR | MHD_POLL_REVENTS_ERR_DISC))))
2039 #ifdef UPGRADE_SUPPORT 2040 if (MHD_CONNECTION_UPGRADE == con->
state)
2052 thread_main_connection_upgrade (con);
2056 con->urh->clean_ready =
true;
2064 return (MHD_THRD_RTRN_TYPE_) 0;
2071 #ifdef HAVE_MESSAGES 2073 _(
"Processing thread terminating. Closing connection\n"));
2098 return (MHD_THRD_RTRN_TYPE_) 0;
2112 #if defined(HTTPS_SUPPORT) 2113 #if !defined(MHD_WINSOCK_SOCKETS) && !defined(MHD_socket_nosignal_) && \ 2114 (GNUTLS_VERSION_NUMBER+0 < 0x030402) && defined(MSG_NOSIGNAL) 2120 #define MHD_TLSLIB_NEED_PUSH_FUNC 1 2123 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC 2129 MHD_tls_push_func_(gnutls_transport_ptr_t trnsp,
2133 #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) 2170 const struct sockaddr *addr,
2210 #ifdef HAVE_MESSAGES 2212 _(
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
2213 (
int) client_socket,
2223 #ifdef MHD_socket_nosignal_ 2224 if (! MHD_socket_nosignal_ (client_socket))
2226 #ifdef HAVE_MESSAGES 2228 _(
"Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
2231 #ifndef MSG_NOSIGNAL 2242 #ifdef HAVE_MESSAGES 2245 _(
"Accepted connection on socket %d\n"),
2255 #ifdef HAVE_MESSAGES 2257 _(
"Server reached connection limit. Closing inbound connection.\n"));
2273 #ifdef HAVE_MESSAGES 2275 _(
"Connection rejected by application. Closing connection.\n"));
2291 #ifdef HAVE_MESSAGES 2293 "Error allocating memory: %s\n",
2306 #ifdef HAVE_MESSAGES 2308 _(
"Error allocating memory: %s\n"),
2323 if (
NULL == (connection->
addr = malloc (addrlen)))
2326 #ifdef HAVE_MESSAGES 2328 _(
"Error allocating memory: %s\n"),
2340 memcpy (connection->
addr,
2346 connection->
daemon = daemon;
2356 #ifdef HTTPS_SUPPORT 2359 gnutls_init (&connection->tls_session,
2361 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030402)
2364 #
if GNUTLS_VERSION_MAJOR >= 3
2368 gnutls_priority_set (connection->tls_session,
2369 daemon->priority_cache);
2370 switch (daemon->cred_type)
2373 case GNUTLS_CRD_CERTIFICATE:
2374 gnutls_credentials_set (connection->tls_session,
2375 GNUTLS_CRD_CERTIFICATE,
2379 #ifdef HAVE_MESSAGES 2380 MHD_DLOG (connection->
daemon,
2381 _(
"Failed to setup TLS credentials: unknown credential type %d\n"),
2388 free (connection->
addr);
2396 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030109) && !defined(_WIN64) 2397 gnutls_transport_set_int (connection->tls_session, (
int)(client_socket));
2399 gnutls_transport_set_ptr (connection->tls_session, (gnutls_transport_ptr_t)(intptr_t)(client_socket));
2401 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC 2402 gnutls_transport_set_push_function (connection->tls_session, MHD_tls_push_func_);
2404 if (daemon->https_mem_trust)
2405 gnutls_certificate_server_set_request (connection->tls_session,
2406 GNUTLS_CERT_REQUEST);
2420 #ifdef HAVE_MESSAGES 2422 _(
"Server reached connection limit. Closing inbound connection.\n"));
2457 #ifdef HAVE_MESSAGES 2459 "Failed to create a thread: %s\n",
2466 connection->
pid = daemon->
pid;
2467 #ifdef EPOLL_SUPPORT 2472 struct epoll_event event;
2474 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2475 event.data.ptr = connection;
2476 if (0 != epoll_ctl (daemon->epoll_fd,
2482 #ifdef HAVE_MESSAGES 2484 _(
"Call to epoll_ctl failed: %s\n"),
2496 daemon->eready_tail,
2504 (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2505 (! MHD_itc_activate_ (daemon->
itc,
"n")) )
2507 #ifdef HAVE_MESSAGES 2509 _(
"Failed to signal new connection via inter-thread communication channel."));
2519 #ifdef HTTPS_SUPPORT 2520 if (
NULL != connection->tls_session)
2521 gnutls_deinit (connection->tls_session);
2539 free (connection->
addr);
2590 #ifdef EPOLL_SUPPORT 2596 daemon->eready_tail,
2602 if (0 != epoll_ctl (daemon->epoll_fd,
2606 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
2653 MHD_PANIC (
_(
"Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2654 #ifdef UPGRADE_SUPPORT 2655 if (
NULL != connection->urh)
2657 #ifdef HAVE_MESSAGES 2659 _(
"Error: connection scheduled for \"upgrade\" cannot be suspended"));
2681 daemon = connection->
daemon;
2683 MHD_PANIC (
_(
"Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2688 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2689 (! MHD_itc_activate_ (daemon->
itc,
"r")) )
2691 #ifdef HAVE_MESSAGES 2693 _(
"Failed to signal resume via inter-thread communication channel."));
2731 #ifdef UPGRADE_SUPPORT 2732 struct MHD_UpgradeResponseHandle *
const urh = pos->urh;
2734 static const void *
const urh =
NULL;
2738 #ifdef UPGRADE_SUPPORT
2739 || ( (
NULL != urh) &&
2740 ( (! urh->was_closed) ||
2741 (! urh->clean_ready) ) )
2771 #ifdef EPOLL_SUPPORT 2775 MHD_PANIC (
"Resumed connection was already in EREADY set\n");
2779 daemon->eready_tail,
2787 #ifdef UPGRADE_SUPPORT 2802 if ( (used_thr_p_c) &&
2805 if (! MHD_itc_activate_(daemon->
itc,
2808 #ifdef HAVE_MESSAGES 2810 _(
"Failed to signal resume of connection via inter-thread communication channel."));
2848 const struct sockaddr *addr,
2854 #ifdef HAVE_MESSAGES 2856 _(
"Failed to set nonblocking mode on new client socket: %s\n"),
2867 #ifdef HAVE_MESSAGES 2869 _(
"Failed to set noninheritable mode on new client socket.\n"));
2899 struct sockaddr_in6 addrstorage;
2901 struct sockaddr_in addrstorage;
2903 struct sockaddr *addr = (
struct sockaddr *) &addrstorage;
2909 addrlen =
sizeof (addrstorage);
2912 sizeof (addrstorage));
2939 #ifdef HAVE_MESSAGES 2942 _(
"Error accepting connection: %s\n"),
2954 #ifdef HAVE_MESSAGES 2959 _(
"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"));
2967 #ifdef HAVE_MESSAGES 2969 _(
"Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
2976 #if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK) 2979 #ifdef HAVE_MESSAGES 2981 _(
"Failed to set nonblocking mode on incoming connection socket: %s\n"),
2988 #if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC) 2991 #ifdef HAVE_MESSAGES 2993 _(
"Failed to set noninheritable mode on incoming connection socket.\n"));
2997 #ifdef HAVE_MESSAGES 3000 _(
"Accepted connection on socket %d\n"),
3038 (! MHD_join_thread_ (pos->
pid.handle)) )
3040 #ifdef UPGRADE_SUPPORT 3041 cleanup_upgraded_connection (pos);
3044 #ifdef HTTPS_SUPPORT 3045 if (
NULL != pos->tls_session)
3046 gnutls_deinit (pos->tls_session);
3058 #ifdef EPOLL_SUPPORT 3068 if ( (-1 !=
daemon->epoll_fd) &&
3077 if (0 != epoll_ctl (
daemon->epoll_fd,
3081 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
3129 time_t earliest_deadline;
3136 #ifdef HAVE_MESSAGES 3138 _(
"Illegal call to MHD_get_timeout\n"));
3150 #ifdef EPOLL_SUPPORT 3153 #
if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
3164 have_timeout =
false;
3165 earliest_deadline = 0;
3170 if ( (! have_timeout) ||
3173 have_timeout =
true;
3178 if ( (
NULL != pos) &&
3181 if ( (! have_timeout) ||
3184 have_timeout =
true;
3190 if (earliest_deadline < now)
3194 const time_t second_left = earliest_deadline - now;
3198 *timeout = 1000LL * second_left;
3216 const fd_set *read_fd_set,
3217 const fd_set *write_fd_set,
3218 const fd_set *except_fd_set)
3223 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3224 struct MHD_UpgradeResponseHandle *urh;
3225 struct MHD_UpgradeResponseHandle *urhn;
3234 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
3235 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
3237 MHD_itc_clear_ (daemon->
itc);
3250 while (
NULL != (pos = prev))
3266 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3268 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
3272 urh_from_fdset (urh,
3279 if ( (0 == urh->in_buffer_size) &&
3280 (0 == urh->out_buffer_size) &&
3281 (0 == urh->in_buffer_used) &&
3282 (0 == urh->out_buffer_used) )
3285 urh->clean_ready =
true;
3320 const fd_set *read_fd_set,
3321 const fd_set *write_fd_set,
3322 const fd_set *except_fd_set)
3328 if (
NULL == read_fd_set ||
NULL == write_fd_set)
3330 if (
NULL == except_fd_set)
3332 #ifdef HAVE_MESSAGES 3334 _(
"MHD_run_from_select() called with except_fd_set " 3335 "set to NULL. Such behavior is deprecated.\n"));
3338 except_fd_set = &es;
3342 #ifdef EPOLL_SUPPORT 3344 ret = MHD_epoll (daemon,
MHD_NO);
3357 write_fd_set, except_fd_set);
3378 struct timeval timeout;
3385 timeout.tv_usec = 0;
3409 #ifdef HAVE_MESSAGES 3411 _(
"Could not obtain daemon fdsets"));
3426 #ifdef HAVE_MESSAGES 3428 _(
"Could not add listen socket to fdset"));
3433 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
3439 #if defined(MHD_WINSOCK_SOCKETS) 3454 #ifdef HAVE_MESSAGES 3456 _(
"Could not add control inter-thread communication channel FD to fdset"));
3459 #if defined(MHD_WINSOCK_SOCKETS) 3471 (MHD_ITC_IS_VALID_(daemon->
itc)) &&
3483 timeout.tv_usec = 0;
3491 timeout.tv_usec = (ltimeout % 1000) * 1000;
3510 #ifdef HAVE_MESSAGES 3512 _(
"select failed: %s\n"),
3539 unsigned int num_connections;
3542 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3543 struct MHD_UpgradeResponseHandle *urh;
3544 struct MHD_UpgradeResponseHandle *urhn;
3552 num_connections = 0;
3555 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3556 for (urh = daemon->urh_head;
NULL != urh; urh = urh->next)
3557 num_connections += 2;
3563 unsigned int poll_server;
3569 p =
MHD_calloc_ ((2 + num_connections),
sizeof (
struct pollfd));
3572 #ifdef HAVE_MESSAGES 3574 _(
"Error allocating memory: %s\n"),
3587 p[poll_server].fd = ls;
3588 p[poll_server].events = POLLIN;
3589 p[poll_server].revents = 0;
3590 poll_listen = (int) poll_server;
3594 if (MHD_ITC_IS_VALID_(daemon->
itc))
3596 p[poll_server].fd = MHD_itc_r_fd_ (daemon->
itc);
3597 p[poll_server].events = POLLIN;
3598 p[poll_server].revents = 0;
3599 poll_itc_idx = (int) poll_server;
3609 timeout = (ltimeout > INT_MAX) ? INT_MAX : (
int) ltimeout;
3618 p[poll_server+i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
3621 p[poll_server+i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
3624 p[poll_server+i].events |= MHD_POLL_EVENTS_ERR_DISC;
3632 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3633 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
3635 urh_to_pollfd(urh, &(p[poll_server+i]));
3639 if (0 == poll_server + num_connections)
3644 if (MHD_sys_poll_(p,
3645 poll_server + num_connections,
3654 #ifdef HAVE_MESSAGES 3656 _(
"poll failed: %s\n"),
3669 if ( (-1 != poll_itc_idx) &&
3670 (0 != (p[poll_itc_idx].revents & POLLIN)) )
3671 MHD_itc_clear_ (daemon->
itc);
3681 while (
NULL != (pos = prev))
3685 if (i >= num_connections)
3690 0 != (p[poll_server+i].revents & POLLIN),
3691 0 != (p[poll_server+i].revents & POLLOUT),
3692 0 != (p[poll_server+i].revents & MHD_POLL_REVENTS_ERR_DISC));
3695 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3696 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
3698 if (i >= num_connections)
3705 if ((p[poll_server+i].
fd != urh->connection->socket_fd) ||
3706 (p[poll_server+i+1].fd != urh->mhd.socket))
3708 urh_from_pollfd(urh, &(p[poll_server+i]));
3712 if ( (0 == urh->in_buffer_size) &&
3713 (0 == urh->out_buffer_size) &&
3714 (0 == urh->in_buffer_used) &&
3715 (0 == urh->out_buffer_used) )
3720 urh->clean_ready =
true;
3730 if ( (-1 != poll_listen) &&
3731 (0 != (p[poll_listen].revents & POLLIN)) )
3748 MHD_poll_listen_socket (
struct MHD_Daemon *daemon,
3753 unsigned int poll_count;
3768 p[poll_count].fd = ls;
3769 p[poll_count].events = POLLIN;
3770 p[poll_count].revents = 0;
3771 poll_listen = poll_count;
3774 if (MHD_ITC_IS_VALID_(daemon->
itc))
3776 p[poll_count].fd = MHD_itc_r_fd_ (daemon->
itc);
3777 p[poll_count].events = POLLIN;
3778 p[poll_count].revents = 0;
3779 poll_itc_idx = poll_count;
3790 if (0 == poll_count)
3792 if (MHD_sys_poll_(p,
3800 #ifdef HAVE_MESSAGES 3802 _(
"poll failed: %s\n"),
3807 if ( (-1 != poll_itc_idx) &&
3808 (0 != (p[poll_itc_idx].revents & POLLIN)) )
3809 MHD_itc_clear_ (daemon->
itc);
3814 if ( (-1 != poll_listen) &&
3815 (0 != (p[poll_listen].revents & POLLIN)) )
3837 return MHD_poll_all (daemon,
3839 return MHD_poll_listen_socket (daemon,
3847 #ifdef EPOLL_SUPPORT 3857 #define MAX_EVENTS 128 3860 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3870 is_urh_ready(
struct MHD_UpgradeResponseHandle *
const urh)
3872 const struct MHD_Connection *
const connection = urh->connection;
3874 if ( (0 == urh->in_buffer_size) &&
3875 (0 == urh->out_buffer_size) &&
3876 (0 == urh->in_buffer_used) &&
3877 (0 == urh->out_buffer_used) )
3884 (connection->tls_read_ready) ) &&
3885 (urh->in_buffer_used < urh->in_buffer_size) )
3889 (urh->out_buffer_used < urh->out_buffer_size) )
3893 (urh->out_buffer_used > 0) )
3897 (urh->in_buffer_used > 0) )
3914 struct epoll_event events[MAX_EVENTS];
3916 struct MHD_UpgradeResponseHandle * pos;
3917 struct MHD_UpgradeResponseHandle * prev;
3919 num_events = MAX_EVENTS;
3920 while (MAX_EVENTS == num_events)
3924 num_events = epoll_wait (daemon->epoll_upgrade_fd,
3928 if (-1 == num_events)
3933 #ifdef HAVE_MESSAGES 3935 _(
"Call to epoll_wait failed: %s\n"),
3940 for (i = 0; i < (
unsigned int) num_events; i++)
3942 struct UpgradeEpollHandle *
const ueh = events[i].data.ptr;
3943 struct MHD_UpgradeResponseHandle *
const urh = ueh->urh;
3944 bool new_err_state =
false;
3946 if (urh->clean_ready)
3950 if (0 != (events[i].events & EPOLLIN))
3952 if (0 != (events[i].events & EPOLLOUT))
3954 if (0 != (events[i].events & EPOLLHUP))
3958 (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
3964 new_err_state =
true;
3967 if (! urh->in_eready_list)
3969 if (new_err_state ||
3973 daemon->eready_urh_tail,
3975 urh->in_eready_list =
true;
3980 prev = daemon->eready_urh_tail;
3981 while (
NULL != (pos = prev))
3985 if (! is_urh_ready(pos))
3988 daemon->eready_urh_tail,
3990 pos->in_eready_list =
false;
3993 if ( (0 == pos->in_buffer_size) &&
3994 (0 == pos->out_buffer_size) &&
3995 (0 == pos->in_buffer_used) &&
3996 (0 == pos->out_buffer_used) )
3999 pos->clean_ready =
true;
4015 static const char *
const epoll_itc_marker =
"itc_marker";
4029 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4030 static const char *
const upgrade_marker =
"upgrade_ptr";
4034 struct epoll_event events[MAX_EVENTS];
4035 struct epoll_event event;
4041 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4042 int run_upgraded =
MHD_NO;
4045 if (-1 == daemon->epoll_fd)
4052 (! daemon->listen_socket_in_epoll) &&
4055 event.events = EPOLLIN;
4056 event.data.ptr = daemon;
4057 if (0 != epoll_ctl (daemon->epoll_fd,
4062 #ifdef HAVE_MESSAGES 4064 _(
"Call to epoll_ctl failed: %s\n"),
4069 daemon->listen_socket_in_epoll =
true;
4072 (daemon->listen_socket_in_epoll) )
4074 if (0 != epoll_ctl (daemon->epoll_fd,
4078 MHD_PANIC (
"Failed to remove listen FD from epoll set\n");
4079 daemon->listen_socket_in_epoll =
false;
4082 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4083 if ( (! daemon->upgrade_fd_in_epoll) &&
4084 (-1 != daemon->epoll_upgrade_fd) )
4086 event.events = EPOLLIN | EPOLLOUT;
4087 event.data.ptr = (
void *) upgrade_marker;
4088 if (0 != epoll_ctl (daemon->epoll_fd,
4090 daemon->epoll_upgrade_fd,
4093 #ifdef HAVE_MESSAGES 4095 _(
"Call to epoll_ctl failed: %s\n"),
4100 daemon->upgrade_fd_in_epoll =
true;
4103 if ( (daemon->listen_socket_in_epoll) &&
4110 if (0 != epoll_ctl (daemon->epoll_fd,
4114 MHD_PANIC (
_(
"Failed to remove listen FD from epoll set\n"));
4115 daemon->listen_socket_in_epoll =
false;
4128 timeout_ms = INT_MAX;
4130 timeout_ms = (int) timeout_ll;
4147 num_events = MAX_EVENTS;
4148 while (MAX_EVENTS == num_events)
4151 num_events = epoll_wait (daemon->epoll_fd,
4155 if (-1 == num_events)
4160 #ifdef HAVE_MESSAGES 4162 _(
"Call to epoll_wait failed: %s\n"),
4167 for (i=0;i<(
unsigned int) num_events;i++)
4173 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4174 if (upgrade_marker == events[i].
data.ptr)
4182 if (epoll_itc_marker == events[i].
data.ptr)
4186 MHD_itc_clear_ (daemon->
itc);
4189 if (daemon == events[i].
data.ptr)
4193 if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
4195 unsigned int series_length = 0;
4201 (series_length < 10) &&
4211 pos = events[i].data.ptr;
4213 if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
4219 daemon->eready_tail,
4226 if (0 != (events[i].events & EPOLLIN))
4234 daemon->eready_tail,
4239 if (0 != (events[i].events & EPOLLOUT))
4246 daemon->eready_tail,
4255 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4257 run_epoll_for_upgrade (daemon);
4261 prev = daemon->eready_tail;
4262 while (
NULL != (pos = prev))
4279 daemon->eready_tail,
4295 while (
NULL != (pos = prev))
4305 while (
NULL != (pos = prev))
4348 #ifdef EPOLL_SUPPORT 4351 MHD_epoll (daemon,
MHD_NO);
4415 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
4419 MHD_thread_init_(&(daemon->
pid));
4425 #ifdef EPOLL_SUPPORT 4439 return (MHD_THRD_RTRN_TYPE_)0;
4542 #ifdef HAVE_MESSAGES 4544 "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC\n");
4553 #ifdef EPOLL_SUPPORT 4558 if (0 != epoll_ctl (daemon->
worker_pool[i].epoll_fd,
4562 MHD_PANIC (
_(
"Failed to remove listen FD from epoll set\n"));
4563 daemon->
worker_pool[i].listen_socket_in_epoll =
false;
4570 MHD_PANIC (
_(
"Failed to signal quiesce via inter-thread communication channel"));
4574 #ifdef EPOLL_SUPPORT 4576 (-1 != daemon->epoll_fd) &&
4577 (daemon->listen_socket_in_epoll) )
4579 if (0 != epoll_ctl (daemon->epoll_fd,
4583 MHD_PANIC (
"Failed to remove listen FD from epoll set\n");
4584 daemon->listen_socket_in_epoll =
false;
4587 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
4588 (! MHD_itc_activate_ (daemon->
itc,
"q")) )
4589 MHD_PANIC (
_(
"failed to signal quiesce via inter-thread communication channel"));
4617 const struct sockaddr **servaddr,
4631 const struct sockaddr **servaddr,
4637 va_start (ap, servaddr);
4656 const struct sockaddr **servaddr,
4663 #ifdef HTTPS_SUPPORT 4692 #ifdef HAVE_MESSAGES 4694 _(
"Warning: Too large timeout value, ignored.\n"));
4718 *servaddr = va_arg (ap,
4719 const struct sockaddr *);
4732 #ifdef HAVE_MESSAGES 4734 _(
"Warning: Zero size, specified for thread pool size, is ignored. " 4735 "Thread pool is not used.\n"));
4740 #ifdef HAVE_MESSAGES 4742 _(
"Warning: \"1\", specified for thread pool size, is ignored. " 4743 "Thread pool is not used.\n"));
4752 #ifdef HAVE_MESSAGES 4754 _(
"Specified thread pool size (%u) too big\n"),
4763 #ifdef HAVE_MESSAGES 4765 _(
"MHD_OPTION_THREAD_POOL_SIZE option is specified but " 4766 "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
4772 #ifdef HAVE_MESSAGES 4774 _(
"Both MHD_OPTION_THREAD_POOL_SIZE option and " 4775 "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
4781 #ifdef HTTPS_SUPPORT 4784 daemon->https_mem_key = va_arg (ap,
4786 #ifdef HAVE_MESSAGES 4789 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4795 daemon->https_key_password = va_arg (ap,
4797 #ifdef HAVE_MESSAGES 4800 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4806 daemon->https_mem_cert = va_arg (ap,
4808 #ifdef HAVE_MESSAGES 4811 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4817 daemon->https_mem_trust = va_arg (ap,
4819 #ifdef HAVE_MESSAGES 4822 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4827 daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
4833 const char *arg = va_arg (ap,
4835 gnutls_datum_t dhpar;
4837 if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
4839 #ifdef HAVE_MESSAGES 4841 _(
"Error initializing DH parameters\n"));
4845 dhpar.data = (
unsigned char *) arg;
4846 dhpar.size = strlen (arg);
4847 if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
4849 GNUTLS_X509_FMT_PEM) < 0)
4851 #ifdef HAVE_MESSAGES 4853 _(
"Bad Diffie-Hellman parameters format\n"));
4855 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
4858 daemon->have_dhparams =
true;
4862 #ifdef HAVE_MESSAGES 4864 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4873 gnutls_priority_deinit (daemon->priority_cache);
4874 ret = gnutls_priority_init (&daemon->priority_cache,
4875 pstr = va_arg (ap,
const char*),
4877 if (GNUTLS_E_SUCCESS != ret)
4879 #ifdef HAVE_MESSAGES 4881 _(
"Setting priorities to `%s' failed: %s\n"),
4883 gnutls_strerror (ret));
4885 daemon->priority_cache =
NULL;
4891 #if GNUTLS_VERSION_MAJOR < 3 4892 #ifdef HAVE_MESSAGES 4894 _(
"MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n"));
4899 daemon->cert_callback = va_arg (ap,
4900 gnutls_certificate_retrieve_function2 *);
4904 #ifdef DAUTH_SUPPORT 4906 daemon->digest_auth_rand_size = va_arg (ap,
4908 daemon->digest_auth_random = va_arg (ap,
4912 daemon->nonce_nc_size = va_arg (ap,
4919 #ifdef HAVE_MESSAGES 4921 _(
"MHD_OPTION_LISTEN_SOCKET specified for daemon " 4922 "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
4931 #ifdef HAVE_MESSAGES 4932 daemon->custom_error_log = va_arg (ap,
4934 daemon->custom_error_log_cls = va_arg (ap,
4949 daemon->fastopen_queue_size = va_arg (ap,
4955 unsigned int) ? 1 : -1;
4963 #ifdef HAVE_MESSAGES 4968 _(
"Flag MHD_USE_PEDANTIC_CHECKS is ignored because " 4969 "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n"));
4987 (
size_t) oa[i].
value,
5003 (
unsigned int) oa[i].
value,
5008 #ifdef HTTPS_SUPPORT 5013 (gnutls_credentials_type_t) oa[i].
value,
5062 (
void *) oa[i].
value,
5072 (
size_t) oa[i].
value,
5090 #ifdef HAVE_MESSAGES 5096 _(
"MHD HTTPS option %d passed to MHD compiled without HTTPS support\n"),
5102 _(
"Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n"),
5113 #ifdef EPOLL_SUPPORT 5119 #ifndef HAVE_MESSAGES 5123 #ifdef USE_EPOLL_CREATE1 5124 fd = epoll_create1 (EPOLL_CLOEXEC);
5126 fd = epoll_create (MAX_EVENTS);
5130 #ifdef HAVE_MESSAGES 5132 _(
"Call to epoll_create1 failed: %s\n"),
5137 #if !defined(USE_EPOLL_CREATE1) 5140 #ifdef HAVE_MESSAGES 5142 _(
"Failed to set noninheritable mode on epoll FD.\n"));
5160 setup_epoll_to_listen (
struct MHD_Daemon *daemon)
5162 struct epoll_event event;
5165 daemon->epoll_fd = setup_epoll_fd (daemon);
5166 if (-1 == daemon->epoll_fd)
5168 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5171 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
5179 event.events = EPOLLIN;
5180 event.data.ptr = daemon;
5181 if (0 != epoll_ctl (daemon->epoll_fd,
5186 #ifdef HAVE_MESSAGES 5188 _(
"Call to epoll_ctl failed: %s\n"),
5193 daemon->listen_socket_in_epoll =
true;
5194 if (MHD_ITC_IS_VALID_(daemon->
itc))
5196 event.events = EPOLLIN;
5197 event.data.ptr = (
void *) epoll_itc_marker;
5198 if (0 != epoll_ctl (daemon->epoll_fd,
5200 MHD_itc_r_fd_ (daemon->
itc),
5203 #ifdef HAVE_MESSAGES 5205 _(
"Call to epoll_ctl failed: %s\n"),
5249 struct sockaddr_in servaddr4;
5251 struct sockaddr_in6 servaddr6;
5253 const struct sockaddr *servaddr =
NULL;
5270 #ifndef EPOLL_SUPPORT 5274 #ifndef HTTPS_SUPPORT 5278 #ifndef TCP_FASTOPEN 5284 #ifdef UPGRADE_SUPPORT 5315 #if defined(EPOLL_SUPPORT) 5317 #elif defined(HAVE_POLL) 5326 #if defined(EPOLL_SUPPORT) 5336 #ifdef EPOLL_SUPPORT 5337 daemon->epoll_fd = -1;
5338 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5339 daemon->epoll_upgrade_fd = -1;
5343 #ifdef HTTPS_SUPPORT 5344 daemon->priority_cache =
NULL;
5347 gnutls_priority_init (&daemon->priority_cache,
5357 daemon->
port = port;
5368 MHD_itc_set_invalid_ (daemon->
itc);
5374 #ifdef HAVE_MESSAGES 5376 daemon->custom_error_log_cls = stderr;
5381 #ifdef HAVE_MESSAGES 5383 _(
"Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with " 5384 "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD " 5385 "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"));
5393 #ifdef HAVE_LISTEN_SHUTDOWN 5398 #ifdef DAUTH_SUPPORT 5399 daemon->digest_auth_rand_size = 0;
5400 daemon->digest_auth_random =
NULL;
5401 daemon->nonce_nc_size = 4;
5403 #ifdef HTTPS_SUPPORT 5406 daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
5415 #ifdef HTTPS_SUPPORT 5417 (
NULL != daemon->priority_cache) )
5418 gnutls_priority_deinit (daemon->priority_cache);
5424 #ifdef HAVE_MESSAGES 5425 MHD_DLOG (daemon,
_(
"Using debug build of libmicrohttpd.\n") );
5431 if (! MHD_itc_init_ (daemon->
itc))
5433 #ifdef HAVE_MESSAGES 5435 _(
"Failed to create inter-thread communication channel: %s\n"),
5436 MHD_itc_last_strerror_ ());
5438 #ifdef HTTPS_SUPPORT 5439 if (
NULL != daemon->priority_cache)
5440 gnutls_priority_deinit (daemon->priority_cache);
5449 #ifdef HAVE_MESSAGES 5451 _(
"file descriptor for inter-thread communication channel exceeds maximum value\n"));
5454 #ifdef HTTPS_SUPPORT 5455 if (
NULL != daemon->priority_cache)
5456 gnutls_priority_deinit (daemon->priority_cache);
5463 #ifdef DAUTH_SUPPORT 5464 if (daemon->nonce_nc_size > 0)
5466 if ( ( (
size_t) (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc))) /
5467 sizeof(
struct MHD_NonceNc) != daemon->nonce_nc_size)
5469 #ifdef HAVE_MESSAGES 5471 _(
"Specified value for NC_SIZE too large\n"));
5473 #ifdef HTTPS_SUPPORT 5475 gnutls_priority_deinit (daemon->priority_cache);
5480 daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc));
5481 if (
NULL == daemon->nnc)
5483 #ifdef HAVE_MESSAGES 5485 _(
"Failed to allocate memory for nonce-nc map: %s\n"),
5488 #ifdef HTTPS_SUPPORT 5490 gnutls_priority_deinit (daemon->priority_cache);
5497 if (! MHD_mutex_init_ (&daemon->nnc_lock))
5499 #ifdef HAVE_MESSAGES 5501 _(
"MHD failed to initialize nonce-nc mutex\n"));
5503 #ifdef HTTPS_SUPPORT 5505 gnutls_priority_deinit (daemon->priority_cache);
5517 #ifdef HAVE_MESSAGES 5519 _(
"MHD thread pooling only works with MHD_USE_INTERNAL_POLLING_THREAD\n"));
5531 #ifdef HAVE_MESSAGES 5533 _(
"Failed to create socket for listening: %s\n"),
5542 #ifndef MHD_WINSOCK_SOCKETS 5547 if (0 > setsockopt (listen_fd,
5550 (
void*)&on,
sizeof (on)))
5552 #ifdef HAVE_MESSAGES 5554 _(
"setsockopt failed: %s\n"),
5563 #ifndef MHD_WINSOCK_SOCKETS 5566 if (0 > setsockopt (listen_fd,
5569 (
void*)&on,
sizeof (on)))
5571 #ifdef HAVE_MESSAGES 5573 _(
"setsockopt failed: %s\n"),
5583 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT) 5584 if (0 > setsockopt (listen_fd,
5586 #ifndef MHD_WINSOCK_SOCKETS
5594 #ifdef HAVE_MESSAGES 5596 _(
"setsockopt failed: %s\n"),
5604 #ifdef HAVE_MESSAGES 5606 _(
"Cannot allow listening address reuse: SO_REUSEPORT not defined\n"));
5619 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \ 5620 (defined(__sun) && defined(SO_EXCLBIND)) 5621 if (0 > setsockopt (listen_fd,
5623 #ifdef SO_EXCLUSIVEADDRUSE
5624 SO_EXCLUSIVEADDRUSE,
5631 #ifdef HAVE_MESSAGES 5633 _(
"setsockopt failed: %s\n"),
5638 #elif defined(MHD_WINSOCK_SOCKETS) 5639 #ifdef HAVE_MESSAGES 5641 _(
"Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n"));
5650 addrlen =
sizeof (
struct sockaddr_in6);
5653 addrlen =
sizeof (
struct sockaddr_in);
5654 if (
NULL == servaddr)
5659 #ifdef IN6ADDR_ANY_INIT 5660 static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
5664 sizeof (
struct sockaddr_in6));
5665 servaddr6.sin6_family = AF_INET6;
5666 servaddr6.sin6_port = htons (port);
5667 #ifdef IN6ADDR_ANY_INIT 5668 servaddr6.sin6_addr = static_in6any;
5670 #if HAVE_SOCKADDR_IN_SIN_LEN 5671 servaddr6.sin6_len =
sizeof (
struct sockaddr_in6);
5673 servaddr = (
struct sockaddr *) &servaddr6;
5680 sizeof (
struct sockaddr_in));
5681 servaddr4.sin_family = AF_INET;
5682 servaddr4.sin_port = htons (port);
5683 if (0 != INADDR_ANY)
5684 servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
5685 #if HAVE_SOCKADDR_IN_SIN_LEN 5686 servaddr4.sin_len =
sizeof (
struct sockaddr_in);
5688 servaddr = (
struct sockaddr *) &servaddr4;
5703 if (0 > setsockopt (listen_fd,
5704 IPPROTO_IPV6, IPV6_V6ONLY,
5705 (
const void *) &v6_only,
5708 #ifdef HAVE_MESSAGES 5710 _(
"setsockopt failed: %s\n"),
5717 if (-1 == bind (listen_fd, servaddr, addrlen))
5719 #ifdef HAVE_MESSAGES 5721 _(
"Failed to bind to port %u: %s\n"),
5722 (
unsigned int) port,
5731 if (0 == daemon->fastopen_queue_size)
5732 daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
5733 if (0 != setsockopt (listen_fd,
5736 &daemon->fastopen_queue_size,
5737 sizeof (daemon->fastopen_queue_size)))
5739 #ifdef HAVE_MESSAGES 5741 _(
"setsockopt failed: %s\n"),
5747 if (listen (listen_fd,
5750 #ifdef HAVE_MESSAGES 5752 _(
"Failed to listen for connections: %s\n"),
5764 if ( (0 == daemon->
port) &&
5767 struct sockaddr_storage servaddr;
5771 sizeof (
struct sockaddr_storage));
5772 addrlen =
sizeof (servaddr);
5773 if (0 != getsockname (listen_fd,
5774 (
struct sockaddr *) &servaddr,
5777 #ifdef HAVE_MESSAGES 5779 _(
"Failed to get listen port number: %s\n"),
5783 #ifdef MHD_POSIX_SOCKETS 5784 else if (
sizeof (servaddr) < addrlen)
5787 #ifdef HAVE_MESSAGES 5789 _(
"Failed to get listen port number (`struct sockaddr_storage` too small!?)\n"));
5795 switch (servaddr.ss_family)
5799 struct sockaddr_in *s4 = (
struct sockaddr_in *) &servaddr;
5801 daemon->
port = ntohs (s4->sin_port);
5807 struct sockaddr_in6 *s6 = (
struct sockaddr_in6 *) &servaddr;
5809 daemon->
port = ntohs(s6->sin6_port);
5820 #ifdef HAVE_MESSAGES 5822 _(
"Unknown address family!\n"));
5833 #ifdef HAVE_MESSAGES 5835 _(
"Failed to set nonblocking mode on listening socket: %s\n"),
5853 #ifdef HAVE_MESSAGES 5855 _(
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
5863 #ifdef EPOLL_SUPPORT 5870 #ifdef HAVE_MESSAGES 5872 _(
"Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
5876 if (
MHD_YES != setup_epoll_to_listen (daemon))
5883 #ifdef HAVE_MESSAGES 5885 _(
"MHD failed to initialize IP connection limit mutex\n"));
5896 #ifdef HAVE_MESSAGES 5898 _(
"MHD failed to initialize IP connection limit mutex\n"));
5907 #ifdef HTTPS_SUPPORT 5910 (0 != MHD_TLS_init (daemon)) )
5912 #ifdef HAVE_MESSAGES 5914 _(
"Failed to initialize TLS support\n"));
5931 "MHD-listen" :
"MHD-single",
5936 #ifdef HAVE_MESSAGES 5938 _(
"Failed to create listen thread: %s\n"),
5972 memcpy (d, daemon,
sizeof (
struct MHD_Daemon));
5982 if (! MHD_itc_init_ (d->
itc))
5984 #ifdef HAVE_MESSAGES 5986 _(
"Failed to create worker inter-thread communication channel: %s\n"),
5987 MHD_itc_last_strerror_() );
5995 #ifdef HAVE_MESSAGES 5997 _(
"File descriptor for worker inter-thread communication channel exceeds maximum value\n"));
6004 MHD_itc_set_invalid_ (d->
itc);
6010 if (i < leftover_conns)
6012 #ifdef EPOLL_SUPPORT 6014 (
MHD_YES != setup_epoll_to_listen (d)) )
6020 #ifdef HAVE_MESSAGES 6022 _(
"MHD failed to initialize cleanup connection mutex\n"));
6034 #ifdef HAVE_MESSAGES 6036 _(
"Failed to create pool thread: %s\n"),
6047 #ifdef HTTPS_SUPPORT 6050 daemon->https_key_password =
NULL;
6081 #ifdef EPOLL_SUPPORT 6082 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6083 if (daemon->upgrade_fd_in_epoll)
6085 if (0 != epoll_ctl (daemon->epoll_fd,
6087 daemon->epoll_upgrade_fd,
6089 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
6090 daemon->upgrade_fd_in_epoll =
false;
6093 if (-1 != daemon->epoll_fd)
6094 close (daemon->epoll_fd);
6095 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6096 if (-1 != daemon->epoll_upgrade_fd)
6097 close (daemon->epoll_upgrade_fd);
6100 #ifdef DAUTH_SUPPORT 6104 #ifdef HTTPS_SUPPORT 6106 gnutls_priority_deinit (daemon->priority_cache);
6108 if (MHD_ITC_IS_VALID_(daemon->
itc))
6128 #ifdef UPGRADE_SUPPORT 6131 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6132 struct MHD_UpgradeResponseHandle *urh;
6133 struct MHD_UpgradeResponseHandle *urhn;
6140 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
6147 urh->clean_ready =
true;
6165 #ifdef UPGRADE_SUPPORT 6171 while (
NULL != susp)
6173 if (
NULL == susp->urh)
6174 MHD_PANIC (
_(
"MHD_stop_daemon() called while we have suspended connections.\n"));
6175 #ifdef HTTPS_SUPPORT 6176 else if (used_tls &&
6178 (! susp->urh->clean_ready) )
6179 shutdown (susp->urh->app.socket,
6184 #ifdef HAVE_MESSAGES 6185 if (! susp->urh->was_closed)
6187 _(
"Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
6189 susp->urh->was_closed =
true;
6205 MHD_PANIC (
_(
"MHD_stop_daemon() called while we have suspended connections.\n"));
6210 #if MHD_WINSOCK_SOCKETS 6213 (! MHD_itc_activate_ (
daemon->
itc,
"e")) )
6214 MHD_PANIC (
_(
"Failed to signal shutdown via inter-thread communication channel"));
6227 if (! MHD_join_thread_ (pos->
pid.handle))
6241 #ifdef UPGRADE_SUPPORT 6298 MHD_PANIC (
_(
"Failed to signal shutdown via inter-thread communication channel."));
6303 #ifdef HAVE_LISTEN_SHUTDOWN 6306 (void) shutdown (
fd,
6316 #ifdef EPOLL_SUPPORT 6318 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6336 if (! MHD_itc_activate_ (
daemon->
itc,
"e"))
6337 MHD_PANIC (
_(
"Failed to signal shutdown via inter-thread communication channel"));
6341 #ifdef HAVE_LISTEN_SHUTDOWN 6345 (void) shutdown (
fd,
6353 if (! MHD_join_thread_ (
daemon->
pid.handle))
6368 #ifdef EPOLL_SUPPORT 6370 (-1 !=
daemon->epoll_fd) )
6372 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6374 (-1 !=
daemon->epoll_upgrade_fd) )
6390 #ifdef HTTPS_SUPPORT 6391 if (
daemon->have_dhparams)
6393 gnutls_dh_params_deinit (
daemon->https_mem_dhparams);
6394 daemon->have_dhparams =
false;
6398 gnutls_priority_deinit (
daemon->priority_cache);
6400 gnutls_certificate_free_credentials (
daemon->x509_cred);
6404 #ifdef DAUTH_SUPPORT 6441 #ifdef EPOLL_SUPPORT 6508 #ifdef PACKAGE_VERSION 6509 return PACKAGE_VERSION;
6511 static char ver[12] =
"\0\0\0\0\0\0\0\0\0\0\0";
6514 int res = MHD_snprintf_(ver,
6520 if (0 >= res ||
sizeof(ver) <= res)
6545 #ifdef HAVE_MESSAGES 6551 #ifdef HTTPS_SUPPORT 6557 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3 6569 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) 6581 #ifdef EPOLL_SUPPORT 6587 #ifdef HAVE_LISTEN_SHUTDOWN 6593 #ifdef _MHD_ITC_SOCKETPAIR 6605 #ifdef BAUTH_SUPPORT 6611 #ifdef DAUTH_SUPPORT 6617 #ifdef HAVE_POSTPROCESSOR 6623 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111 6629 #if defined(HAVE_PREAD64) || defined(_WIN32) 6631 #elif defined(HAVE_PREAD) 6632 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
6633 #elif defined(HAVE_LSEEK64) 6636 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
6639 #if defined(MHD_USE_THREAD_NAME_) 6645 #if defined(UPGRADE_SUPPORT) 6651 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32) 6657 #ifdef MHD_USE_GETSOCKNAME 6663 #if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || defined (MSG_NOSIGNAL) 6669 #ifdef _MHD_HAVE_SENDFILE 6680 #ifdef MHD_HTTPS_REQUIRE_GRYPT 6681 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600 6682 #if defined(MHD_USE_POSIX_THREADS) 6683 GCRY_THREAD_OPTION_PTHREAD_IMPL;
6684 #elif defined(MHD_W32_MUTEX_) 6687 gcry_w32_mutex_init (
void **ppmtx)
6689 *ppmtx = malloc (
sizeof (MHD_mutex_));
6693 if (!MHD_mutex_init_ ((MHD_mutex_*)*ppmtx))
6705 gcry_w32_mutex_destroy (
void **ppmtx)
6707 int res = (MHD_mutex_destroy_ ((MHD_mutex_*)*ppmtx)) ? 0 : EINVAL;
6714 gcry_w32_mutex_lock (
void **ppmtx)
6716 return MHD_mutex_lock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
6721 gcry_w32_mutex_unlock (
void **ppmtx)
6723 return MHD_mutex_unlock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
6727 static struct gcry_thread_cbs gcry_threads_w32 = {
6728 (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
6729 NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
6730 gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
6743 #if defined(_WIN32) && ! defined(__CYGWIN__) 6750 #if defined(_WIN32) && ! defined(__CYGWIN__) 6751 if (0 != WSAStartup(MAKEWORD(2, 2), &wsd))
6752 MHD_PANIC (
_(
"Failed to initialize winsock\n"));
6753 mhd_winsock_inited_ = 1;
6754 if (2 != LOBYTE(wsd.wVersion) && 2 != HIBYTE(wsd.wVersion))
6755 MHD_PANIC (
_(
"Winsock version 2.2 is not available\n"));
6757 #ifdef HTTPS_SUPPORT 6758 #ifdef MHD_HTTPS_REQUIRE_GRYPT 6759 #if GCRYPT_VERSION_NUMBER < 0x010600 6760 #if defined(MHD_USE_POSIX_THREADS) 6761 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
6762 &gcry_threads_pthread))
6763 MHD_PANIC (
_(
"Failed to initialise multithreading in libgcrypt\n"));
6764 #elif defined(MHD_W32_MUTEX_) 6765 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
6767 MHD_PANIC (
_(
"Failed to initialise multithreading in libgcrypt\n"));
6769 gcry_check_version (
NULL);
6771 if (
NULL == gcry_check_version (
"1.6.0"))
6772 MHD_PANIC (
_(
"libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n"));
6775 gnutls_global_init ();
6778 #ifdef HAVE_FREEBSD_SENDFILE 6779 MHD_conn_init_static_ ();
6787 #ifdef HTTPS_SUPPORT 6788 gnutls_global_deinit ();
6790 #if defined(_WIN32) && ! defined(__CYGWIN__) 6791 if (mhd_winsock_inited_)
6797 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
unsigned int per_ip_connection_limit
int MHD_socket_nonblocking_(MHD_socket sock)
void * unescape_callback_cls
volatile int global_init_count
#define MHD_send_(s, b, l)
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)
static int parse_options(struct MHD_Daemon *daemon, const struct sockaddr **servaddr,...)
_MHD_EXTERN const char * MHD_get_version(void)
#define DLL_insert(head, tail, element)
bool data_already_pending
size_t(* UnescapeCallback)(void *cls, struct MHD_Connection *conn, char *uri)
enum MHD_CONNECTION_STATE state
static int call_handlers(struct MHD_Connection *con, bool read_ready, bool write_ready, bool force_close)
void MHD_pool_destroy(struct MemoryPool *pool)
#define MHD_SCKT_SEND_MAX_SIZE_
enum MHD_ConnectionEventLoopInfo event_loop_info
void(* VfprintfFunctionPointerType)(void *cls, const char *format, va_list va)
#define MHD_ITC_IS_INVALID_(itc)
MHD_thread_handle_ID_ pid
time_t connection_timeout
Methods for managing connections.
_MHD_EXTERN int MHD_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode termination_code)
_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
#define MHD_socket_get_error_()
struct MHD_Connection * normal_timeout_tail
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ MHD_polling_thread(void *cls)
Header for platform missing functions.
volatile bool was_quiesced
void MHD_connection_mark_closed_(struct MHD_Connection *connection)
#define MHD_MAX_CONNECTIONS_DEFAULT
MHD_thread_handle_ID_ pid
static void mhd_panic_std(void *cls, const char *file, unsigned int line, const char *reason)
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)
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)
_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_mutex_destroy_chk_(pmutex)
#define EDLL_insert(head, tail, element)
#define MHD_SCKT_ERR_IS_(err, code)
static int parse_options_va(struct MHD_Daemon *daemon, const struct sockaddr **servaddr, va_list ap)
#define MHD_strerror_(errnum)
#define MHD_itc_destroy_chk_(itc)
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)
Methods for managing response objects.
_MHD_EXTERN void MHD_set_panic_func(MHD_PanicCallback cb, void *cls)
void MHD_update_last_activity_(struct MHD_Connection *connection)
#define MHD_UNSIGNED_LONG_LONG
void * uri_log_callback_cls
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)
struct MHD_Daemon * daemon
int listening_address_reuse
MHD_mutex_ per_ip_connection_mutex
struct MHD_Connection * manual_timeout_head
MHD_NotifyConnectionCallback notify_connection
struct MHD_Connection * cleanup_head
#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)
#define XDLL_remove(head, tail, element)
#define MHD_mutex_unlock_chk_(pmutex)
#define XDLL_insert(head, tail, element)
MHD_socket MHD_socket_create_listen_(int use_ipv6)
struct MHD_Connection * cleanup_tail
Header for platform-independent inter-thread communication.
struct MHD_Connection * prev
static int MHD_ip_addr_compare(const void *a1, const void *a2)
struct MHD_Daemon * worker_pool
#define MAYBE_SOCK_CLOEXEC
_MHD_EXTERN void MHD_stop_daemon(struct MHD_Daemon *daemon)
#define MHD_socket_close_chk_(fd)
struct MHD_Connection * manual_timeout_tail
static int MHD_ip_addr_to_key(const struct sockaddr *addr, socklen_t addrlen, struct MHD_IPCount *key)
#define MHD_INVALID_SOCKET
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_create_named_thread_(t, n, s, r, a)
int MHD_add_to_fd_set_(MHD_socket fd, fd_set *set, MHD_socket *max_fd, unsigned int fd_setsize)
unsigned int connection_limit
#define MHD_recv_(s, b, l)
unsigned int worker_pool_size
#define MHD_SCKT_ERR_IS_EAGAIN_(err)
_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)
LogCallback uri_log_callback
void MHD_connection_handle_read(struct MHD_Connection *connection)
#define MHD_SYS_select_(n, r, w, e, t)
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
time_t connection_timeout
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ thread_main_handle_connection(void *data)
static int MHD_ip_limit_add(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Methods for managing connections.
struct MHD_Connection * normal_timeout_head
void * tdelete(const void *__restrict vkey, void **__restrict vrootp, int(*compar)(const void *, const void *))
static void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
int MHD_socket_noninheritable_(MHD_socket sock)
void * tfind(const void *vkey, void *const *vrootp, int(*compar)(const void *, const void *))
#define MAYBE_SOCK_NONBLOCK
limits values definitions
Header for platform-independent threads abstraction.
void MHD_monotonic_sec_counter_init(void)
internal shared structures
void * MHD_calloc_(size_t nelem, size_t elsize)
UnescapeCallback unescape_callback
#define MHD_socket_last_strerr_()
void internal_suspend_connection_(struct MHD_Connection *connection)
#define MHD_SCKT_LAST_ERR_IS_(code)
internal monotonic clock functions implementations
unsigned int listen_backlog_size
struct MHD_Connection * connections_head
struct MHD_Daemon * master
#define _SET_INIT_AND_DEINIT_FUNCS(FI, FD)
struct MHD_Connection * next
MHD_AcceptPolicyCallback apc
void *(* LogCallback)(void *cls, const char *uri, struct MHD_Connection *con)
int MHD_connection_handle_idle(struct MHD_Connection *connection)
static int resume_suspended_connections(struct MHD_Daemon *daemon)
#define MHD_socket_strerr_(err)
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)
static int MHD_accept_connection(struct MHD_Daemon *daemon)
_MHD_EXTERN int MHD_get_fdset(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd)
static void MHD_ip_count_unlock(struct MHD_Daemon *daemon)
#define MHD_connection_finish_forward_(conn)
time_t MHD_monotonic_sec_counter(void)
void(* MHD_RequestCompletedCallback)(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
#define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)
void MHD_check_global_init_(void)
MHD_RequestCompletedCallback notify_completed
#define MHD_SCKT_FD_FITS_FDSET_(fd, pset)
struct MHD_Connection * prevX
static void close_connection(struct MHD_Connection *pos)
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
#define DLL_remove(head, tail, element)
void * notify_completed_cls
struct MemoryPool * MHD_pool_create(size_t max)
#define EDLL_remove(head, tail, element)
_MHD_EXTERN int MHD_run(struct MHD_Daemon *daemon)
#define TIMEVAL_TV_SEC_MAX
void * notify_connection_cls
void * tsearch(const void *vkey, void **vrootp, int(*compar)(const void *, const void *))
MHD_PanicCallback mhd_panic
struct MHD_Connection * suspended_connections_tail
#define MHD_UNSIGNED_LONG_LONG_PRINTF
void MHD_resume_connection(struct MHD_Connection *connection)
void * per_ip_connection_count
_MHD_EXTERN int MHD_is_feature_supported(enum MHD_FEATURE feature)
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)
Header for platform-independent locks abstraction.
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)
static void close_all_connections(struct MHD_Daemon *daemon)
struct MHD_Connection * connections_tail
void MHD_monotonic_sec_counter_finish(void)
#define MHD_TEST_ALLOW_SUSPEND_RESUME
MHD_FLAG
Flags for the struct MHD_Daemon.
#define MHD_mutex_lock_chk_(pmutex)
struct MHD_Connection * suspended_connections_head
#define _MHD_SYS_DEFAULT_FD_SETSIZE
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...