41 static enum MHD_StatusCode
51 #ifndef MHD_WINSOCK_SOCKETS
62 MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED,
63 _ (
"setsockopt failed: %s\n"),
66 return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED;
75 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT)
78 #ifndef MHD_WINSOCK_SOCKETS
88 MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED,
89 _ (
"setsockopt failed: %s\n"),
92 return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED;
100 MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_NOT_SUPPORTED,
102 "Cannot allow listening address reuse: SO_REUSEPORT not defined.\n"));
104 return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_NOT_SUPPORTED;
115 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \
116 (defined(__sun) && defined(SO_EXCLBIND))
119 #ifdef SO_EXCLUSIVEADDRUSE
129 MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_FAILED,
130 _ (
"setsockopt failed: %s\n"),
133 return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_FAILED;
136 #elif defined(MHD_WINSOCK_SOCKETS)
139 MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_NOT_SUPPORTED,
141 "Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined.\n"));
143 return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_NOT_SUPPORTED;
156 static enum MHD_StatusCode
159 enum MHD_StatusCode sc;
161 struct sockaddr_storage ss;
162 const struct sockaddr *sa;
198 return MHD_SC_AF_NOT_SUPPORTED_BY_BUILD;
223 MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD,
224 _ (
"IPv6 not supported by this build.\n"));
226 return MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD;
231 try_open_listen_socket:
239 goto try_open_listen_socket;
245 MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET,
246 _ (
"Failed to create socket for listening: %s\n"),
249 return MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET;
259 #if defined IPPROTO_IPV6 && defined IPV6_V6ONLY
269 (
const void *) &v6_only,
274 MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_FAILED,
275 _ (
"setsockopt failed: %s\n"),
282 MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_NOT_SUPPORTED,
284 "Cannot explicitly setup dual stack behavior on this platform.\n"));
293 sa = (
const struct sockaddr *) &daemon->
listen_sa;
302 #ifdef IN6ADDR_ANY_INIT
303 static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
305 struct sockaddr_in6 *sin6 = (
struct sockaddr_in6 *) &ss;
307 addrlen =
sizeof (
struct sockaddr_in6);
310 sizeof (
struct sockaddr_in6));
311 sin6->sin6_family = AF_INET6;
313 #ifdef IN6ADDR_ANY_INIT
314 sin6->sin6_addr = static_in6any;
316 #if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
317 sin6->sin6_len =
sizeof (
struct sockaddr_in6);
323 struct sockaddr_in *sin4 = (
struct sockaddr_in *) &ss;
325 addrlen =
sizeof (
struct sockaddr_in);
328 sizeof (
struct sockaddr_in));
329 sin4->sin_family = AF_INET;
332 sin4->sin_addr.s_addr = htonl (INADDR_ANY);
333 #if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
334 sin4->sin_len =
sizeof (
struct sockaddr_in);
337 sa = (
const struct sockaddr *) &ss;
346 unsigned int port = 0;
348 switch (sa->sa_family)
351 if (addrlen ==
sizeof (
struct sockaddr_in))
352 port = ntohs (((
const struct sockaddr_in *) sa)->sin_port);
354 port = UINT16_MAX + 1;
357 if (addrlen ==
sizeof (
struct sockaddr_in6))
358 port = ntohs (((
const struct sockaddr_in6 *) sa)->sin6_port);
360 port = UINT16_MAX + 1;
367 MHD_SC_LISTEN_SOCKET_BIND_FAILED,
368 _ (
"Failed to bind to port %u: %s\n"),
372 return MHD_SC_LISTEN_SOCKET_BIND_FAILED;
387 MHD_SC_FAST_OPEN_FAILURE,
388 _ (
"setsockopt failed: %s\n"),
392 return MHD_SC_FAST_OPEN_FAILURE;
403 MHD_SC_LISTEN_FAILURE,
404 _ (
"Failed to listen for connections: %s\n"),
407 return MHD_SC_LISTEN_FAILURE;
424 struct sockaddr_storage servaddr;
433 sizeof (
struct sockaddr_storage));
434 addrlen =
sizeof (servaddr);
436 (
struct sockaddr *) &servaddr,
441 MHD_SC_LISTEN_PORT_INTROSPECTION_FAILURE,
442 _ (
"Failed to get listen port number: %s\n"),
447 #ifdef MHD_POSIX_SOCKETS
448 if (
sizeof (servaddr) < addrlen)
453 MHD_SC_LISTEN_PORT_INTROSPECTION_FAILURE,
455 "Failed to get listen port number (`struct sockaddr_storage` too small!?).\n"));
460 switch (servaddr.ss_family)
464 struct sockaddr_in *s4 = (
struct sockaddr_in *) &servaddr;
472 struct sockaddr_in6 *s6 = (
struct sockaddr_in6 *) &servaddr;
486 MHD_SC_LISTEN_PORT_INTROSPECTION_UNKNOWN_AF,
487 _ (
"Unknown address family!\n"));
507 #ifndef HAVE_MESSAGES
511 #ifdef USE_EPOLL_CREATE1
512 fd = epoll_create1 (EPOLL_CLOEXEC);
514 fd = epoll_create (MAX_EVENTS);
520 MHD_SC_EPOLL_CTL_CREATE_FAILED,
521 _ (
"Call to epoll_create1 failed: %s\n"),
526 #if ! defined(USE_EPOLL_CREATE1)
531 MHD_SC_EPOLL_CTL_CONFIGURE_NOINHERIT_FAILED,
532 _ (
"Failed to set noninheritable mode on epoll FD.\n"));
549 static enum MHD_StatusCode
550 setup_epoll_to_listen (
struct MHD_Daemon *daemon)
552 struct epoll_event event;
556 daemon->epoll_fd = setup_epoll_fd (daemon);
557 if (-1 == daemon->epoll_fd)
558 return MHD_SC_EPOLL_CTL_CREATE_FAILED;
559 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
562 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
564 return MHD_SC_EPOLL_CTL_CREATE_FAILED;
570 event.events = EPOLLIN;
571 event.data.ptr = daemon;
572 if (0 != epoll_ctl (daemon->epoll_fd,
579 MHD_SC_EPOLL_CTL_ADD_FAILED,
580 _ (
"Call to epoll_ctl failed: %s\n"),
583 return MHD_SC_EPOLL_CTL_ADD_FAILED;
585 daemon->listen_socket_in_epoll =
true;
586 if (MHD_ITC_IS_VALID_ (daemon->
itc))
588 event.events = EPOLLIN;
589 event.data.ptr = (
void *) daemon->epoll_itc_marker;
590 if (0 != epoll_ctl (daemon->epoll_fd,
592 MHD_itc_r_fd_ (daemon->
itc),
597 MHD_SC_EPOLL_CTL_ADD_FAILED,
598 _ (
"Call to epoll_ctl failed: %s\n"),
601 return MHD_SC_EPOLL_CTL_ADD_FAILED;
618 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
623 MHD_thread_init_ (&daemon->
pid);
629 MHD_PANIC (
"MHD_ELS_AUTO should have been mapped to preferred style.\n");
640 MHD_PANIC (
"MHD_ELS_POLL not supported, should have failed earlier.\n");
645 MHD_daemon_epoll_ (daemon,
648 MHD_PANIC (
"MHD_ELS_EPOLL not supported, should have failed earlier.\n");
661 return (MHD_THRD_RTRN_TYPE_) 0;
671 static enum MHD_StatusCode
682 enum MHD_StatusCode sc;
688 return MHD_SC_THREAD_POOL_MALLOC_FAILURE;
709 if (((
unsigned int) i) < leftover_conns)
714 if (! MHD_itc_init_ (d->
itc))
718 MHD_SC_ITC_INITIALIZATION_FAILED,
720 "Failed to create worker inter-thread communication channel: %s\n"),
721 MHD_itc_last_strerror_ () );
723 sc = MHD_SC_ITC_INITIALIZATION_FAILED;
732 MHD_SC_ITC_DESCRIPTOR_TOO_LARGE,
734 "File descriptor for inter-thread communication channel exceeds maximum value.\n"));
737 sc = MHD_SC_ITC_DESCRIPTOR_TOO_LARGE;
743 MHD_itc_set_invalid_ (d->
itc);
748 (MHD_SC_OK != (sc = setup_epoll_to_listen (d))) )
757 MHD_SC_THREAD_POOL_CREATE_MUTEX_FAILURE,
758 _ (
"MHD failed to initialize cleanup connection mutex.\n"));
762 sc = MHD_SC_THREAD_POOL_CREATE_MUTEX_FAILURE;
775 MHD_SC_THREAD_POOL_LAUNCH_FAILURE,
776 _ (
"Failed to create pool thread: %s\n"),
784 sc = MHD_SC_THREAD_POOL_LAUNCH_FAILURE;
802 return MHD_SC_THREAD_LAUNCH_FAILURE;
825 enum MHD_StatusCode sc;
852 MHD_SC_SYSCALL_THREAD_COMBINATION_INVALID,
854 "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
856 return MHD_SC_SYSCALL_THREAD_COMBINATION_INVALID;
864 if (! MHD_itc_init_ (daemon->
itc))
868 MHD_SC_ITC_INITIALIZATION_FAILED,
869 _ (
"Failed to create inter-thread communication channel: %s\n"),
870 MHD_itc_last_strerror_ ());
872 return MHD_SC_ITC_INITIALIZATION_FAILED;
880 MHD_SC_ITC_DESCRIPTOR_TOO_LARGE,
882 "File descriptor for inter-thread communication channel exceeds maximum value.\n"));
884 return MHD_SC_ITC_DESCRIPTOR_TOO_LARGE;
899 MHD_SC_LISTEN_SOCKET_TOO_LARGE,
900 _ (
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
904 return MHD_SC_LISTEN_SOCKET_TOO_LARGE;
913 MHD_SC_LISTEN_SOCKET_NONBLOCKING_FAILURE,
914 _ (
"Failed to set nonblocking mode on listening socket: %s\n"),
924 return MHD_SC_LISTEN_SOCKET_NONBLOCKING_FAILURE;
933 (MHD_SC_OK != (sc = setup_epoll_to_listen (daemon))) )
940 if ( ( (MHD_TM_THREAD_PER_CONNECTION == daemon->
threading_mode) ||
944 (MHD_TM_THREAD_PER_CONNECTION ==
954 MHD_SC_THREAD_MAIN_LAUNCH_FAILURE,
955 _ (
"Failed to create listen thread: %s\n"),
958 return MHD_SC_THREAD_MAIN_LAUNCH_FAILURE;
void MHD_connection_cleanup_(struct MHD_Daemon *daemon)
functions to cleanup completed connection
void MHD_daemon_close_all_connections_(struct MHD_Daemon *daemon)
function to close all connections open at a daemon
non-public functions provided by daemon_epoll.c
enum MHD_StatusCode MHD_daemon_poll_(struct MHD_Daemon *daemon, bool may_block)
non-public functions provided by daemon_poll.c
enum MHD_StatusCode MHD_daemon_select_(struct MHD_Daemon *daemon, int may_block)
non-public functions provided by daemon_select.c
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ MHD_polling_thread(void *cls)
static enum MHD_StatusCode configure_listen_reuse(struct MHD_Daemon *daemon)
static enum MHD_StatusCode setup_thread_pool(struct MHD_Daemon *daemon)
static void get_listen_port_number(struct MHD_Daemon *daemon)
static enum MHD_StatusCode open_listen_socket(struct MHD_Daemon *daemon)
enum MHD_StatusCode MHD_daemon_start(struct MHD_Daemon *daemon)
MHD_socket MHD_daemon_quiesce(struct MHD_Daemon *daemon)
void * MHD_calloc_(size_t nelem, size_t elsize)
#define MHD_strerror_(errnum)
#define MHD_itc_destroy_chk_(itc)
#define MHD_mutex_destroy_chk_(pmutex)
int MHD_socket_noninheritable_(MHD_socket sock)
int MHD_socket_nonblocking_(MHD_socket sock)
MHD_socket MHD_socket_create_listen_(int pf)
#define MHD_socket_last_strerr_()
#define MHD_SCKT_FD_FITS_FDSET_(fd, pset)
#define MHD_create_named_thread_(t, n, s, r, a)
internal shared structures
#define MHD_mutex_init_(ignore)
#define MHD_INVALID_SOCKET
bool MHD_resume_suspended_connections_(struct MHD_Daemon *daemon)
implementation of MHD_request_resume()
enum MHD_AddressFamily listen_af
MHD_mutex_ cleanup_connection_mutex
unsigned int worker_pool_size
enum MHD_FastOpenMethod fast_open_method
enum MHD_EventLoopSyscall event_loop_syscall
bool disallow_suspend_resume
struct sockaddr_storage listen_sa
struct MHD_Daemon * worker_pool
MHD_thread_handle_ID_ pid
struct MHD_Daemon * master
enum MHD_ThreadingMode threading_mode
unsigned int global_connection_limit
size_t thread_stack_limit_b
unsigned int fo_queue_length