54 if ( (
NULL != daemon->tls_api) &&
57 MHD_daemon_upgrade_connection_with_select_ (con);
60 else if (
NULL != daemon->tls_api)
62 MHD_daemon_upgrade_connection_with_poll_ (con);
84static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
112 const bool use_poll =
false;
114 bool was_suspended =
false;
116 MHD_thread_init_ (&con->
pid);
122#ifdef UPGRADE_SUPPORT
123 struct MHD_UpgradeResponseHandle *
const urh = con->
request.urh;
125 static const void *
const urh =
NULL;
132 was_suspended =
true;
143 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
144 _ (
"Failed to add FD to fd_set.\n"));
160 MHD_SC_UNEXPECTED_SELECT_ERROR,
161 _ (
"Error during select (%d): `%s'\n"),
171 p[0].events = POLLIN;
172 p[0].fd = MHD_itc_r_fd_ (daemon->
itc);
174 if (0 > MHD_sys_poll_ (p,
182 MHD_SC_UNEXPECTED_POLL_ERROR,
183 _ (
"Error during poll: `%s'\n"),
190 MHD_itc_clear_ (daemon->
itc);
199 was_suspended =
false;
217 if ( (
NULL == tvp) &&
225 const time_t seconds_left = timeout - (now - con->
last_activity);
226#if ! defined(_WIN32) || defined(__CYGWIN__)
227 tv.tv_sec = seconds_left;
241 bool err_state =
false;
275 if (MHD_ITC_IS_VALID_ (daemon->
itc) )
288 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
289 _ (
"Failed to add FD to fd_set.\n"));
307 MHD_SC_UNEXPECTED_SELECT_ERROR,
308 _ (
"Error during select (%d): `%s'\n"),
317 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
318 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
320 MHD_itc_clear_ (daemon->
itc);
343 p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
346 p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
349 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
357 if (MHD_ITC_IS_VALID_ (daemon->
itc))
359 p[1].events |= POLLIN;
360 p[1].fd = MHD_itc_r_fd_ (daemon->
itc);
365 if (MHD_sys_poll_ (p,
371 (
NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
377 MHD_SC_UNEXPECTED_POLL_ERROR,
378 _ (
"Error during poll: `%s'\n"),
386 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
387 (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
388 MHD_itc_clear_ (daemon->
itc);
392 (0 != (p[0].revents & POLLIN)),
393 (0 != (p[0].revents & POLLOUT)),
394 (0 != (p[0].revents & (POLLERR
396 MHD_POLL_REVENTS_ERR_DISC))) ))
400#ifdef UPGRADE_SUPPORT
410 thread_main_connection_upgrade (con);
414 con->
request.urh->clean_ready =
true;
422 return (MHD_THRD_RTRN_TYPE_) 0;
429 MHD_SC_THREAD_TERMINATING,
430 _ (
"Processing thread terminating. Closing connection.\n"));
454 return (MHD_THRD_RTRN_TYPE_) 0;
492 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
504 else if (i > (
size_t) ret)
505 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
546 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
558 else if (i > (
size_t) ret)
559 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
587static enum MHD_StatusCode
590 const struct sockaddr *addr,
595 enum MHD_StatusCode sc;
602 if ( (external_add) &&
627 return MHD_SC_LIMIT_CONNECTIONS_REACHED;
636 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
637 _ (
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
645 return MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
648#ifdef MHD_socket_nosignal_
649 if (! MHD_socket_nosignal_ (client_socket))
653 MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED,
654 _ (
"Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
662 return MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED;
671 MHD_SC_CONNECTION_ACCEPTED,
672 _ (
"Accepted connection on socket %d.\n"),
684 MHD_SC_LIMIT_CONNECTIONS_REACHED,
686 "Server reached connection limit. Closing inbound connection.\n"));
692 return MHD_SC_LIMIT_CONNECTIONS_REACHED;
705 MHD_SC_ACCEPT_POLICY_REJECTED,
706 _ (
"Connection rejected by application. Closing connection.\n"));
716 return MHD_SC_ACCEPT_POLICY_REJECTED;
726 MHD_SC_CONNECTION_MALLOC_FAILURE,
727 "Error allocating memory: %s\n",
735 return MHD_SC_CONNECTION_MALLOC_FAILURE;
743 MHD_SC_POOL_MALLOC_FAILURE,
744 _ (
"Error allocating memory: %s\n"),
755 return MHD_SC_POOL_MALLOC_FAILURE;
759 memcpy (&connection->
addr,
765 connection->
daemon = daemon;
769 if (
NULL != daemon->tls_api)
772 = daemon->tls_api->setup_connection (daemon->tls_api->cls,
774 if (
NULL == connection->tls_cs)
796 MHD_SC_LIMIT_CONNECTIONS_REACHED,
798 "Server reached connection limit. Closing inbound connection.\n"));
803 sc = MHD_SC_LIMIT_CONNECTIONS_REACHED;
835 MHD_SC_THREAD_LAUNCH_FAILURE,
836 "Failed to create a thread: %s\n",
839 sc = MHD_SC_THREAD_LAUNCH_FAILURE;
845 connection->
pid = daemon->
pid;
853 struct epoll_event event;
855 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
856 event.data.ptr = connection;
857 if (0 != epoll_ctl (daemon->epoll_fd,
865 MHD_SC_EPOLL_CTL_ADD_FAILED,
866 _ (
"Call to epoll_ctl failed: %s\n"),
869 sc = MHD_SC_EPOLL_CTL_ADD_FAILED;
888 (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
889 (! MHD_itc_activate_ (daemon->
itc,
894 MHD_SC_ITC_USE_FAILED,
896 "Failed to signal new connection via inter-thread communication channel (not necessarily fatal, continuing anyway).\n"));
907 if ( (
NULL != daemon->tls_api) &&
908 (
NULL != connection->tls_cs) )
909 daemon->tls_api->teardown_connection (daemon->tls_api->cls,
966 const struct sockaddr *addr,
975 MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED,
976 _ (
"Failed to set nonblocking mode on new client socket: %s\n"),
991 MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED,
992 _ (
"Failed to set noninheritable mode on new client socket.\n"));
1016 struct sockaddr_storage addrstorage;
1017 struct sockaddr *addr = (
struct sockaddr *) &addrstorage;
1023 addrlen =
sizeof (addrstorage);
1026 sizeof (addrstorage));
1029 return MHD_SC_DAEMON_ALREADY_QUIESCED;
1050 return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
1052 return MHD_SC_ACCEPT_FAST_DISCONNECT;
1054 return MHD_SC_ACCEPT_FAILED_EAGAIN;
1069 MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY,
1071 "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"));
1073 return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY;
1082 MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED,
1084 "Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
1087 return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED;
1092 MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY,
1093 _ (
"Error accepting connection: %s\n"),
1096 return MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY;
1098#if ! defined(USE_ACCEPT4) || ! defined(HAVE_SOCK_NONBLOCK)
1103 MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED,
1105 "Failed to set nonblocking mode on incoming connection socket: %s\n"),
1112#if ! defined(USE_ACCEPT4) || ! defined(SOCK_CLOEXEC)
1117 MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED,
1119 "Failed to set noninheritable mode on incoming connection socket.\n"));
1126 MHD_SC_CONNECTION_ACCEPTED,
1127 _ (
"Accepted connection on socket %d.\n"),
#define MHD_connection_finish_forward_(conn)
static ssize_t recv_param_adapter(struct MHD_Connection *connection, void *other, size_t i)
static ssize_t send_param_adapter(struct MHD_Connection *connection, const void *other, size_t i)
static enum MHD_StatusCode internal_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen, bool external_add, bool non_blck)
enum MHD_StatusCode MHD_accept_connection_(struct MHD_Daemon *daemon)
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ thread_main_handle_connection(void *data)
functions to add connection to our active set
int MHD_connection_call_handlers_(struct MHD_Connection *con, bool read_ready, bool write_ready, bool force_close)
bool MHD_request_handle_idle_(struct MHD_Request *request)
function to call event handlers based on event mask
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode rtc)
functions to close connection
complete upgrade socket forwarding operation in TLS mode
void MHD_connection_update_last_activity_(struct MHD_Connection *connection)
function to update last activity of a connection
int MHD_ip_limit_add(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
counting of connections per IP
non-public functions provided by daemon_poll.c
non-public functions provided by daemon_select.c
@ MHD_CONNECTION_NOTIFY_STARTED
@ MHD_CONNECTION_NOTIFY_CLOSED
@ MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN
@ MHD_REQUEST_TERMINATED_COMPLETED_OK
@ MHD_REQUEST_TERMINATED_WITH_ERROR
void MHD_response_queue_for_destroy(struct MHD_Response *response)
enum MHD_StatusCode MHD_daemon_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen)
#define MHD_ERR_CONNRESET_
#define XDLL_insert(head, tail, element)
@ 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 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 TIMEVAL_TV_SEC_MAX
#define MHD_mutex_unlock_chk_(pmutex)
#define MHD_mutex_lock_chk_(pmutex)
time_t MHD_monotonic_sec_counter(void)
int MHD_add_to_fd_set_(MHD_socket fd, fd_set *set, MHD_socket *max_fd, unsigned int fd_setsize)
int MHD_socket_noninheritable_(MHD_socket sock)
int MHD_socket_nonblocking_(MHD_socket sock)
#define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)
#define MHD_SCKT_ERR_IS_(err, code)
#define MHD_SCKT_ERR_IS_EAGAIN_(err)
#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)
#define MHD_socket_strerr_(err)
#define MHD_socket_last_strerr_()
#define MHD_socket_get_error_()
#define MAYBE_SOCK_NONBLOCK
#define MHD_socket_close_chk_(fd)
#define MHD_SCKT_ERR_IS_EINTR_(err)
#define MHD_SCKT_SEND_MAX_SIZE_
#define MAYBE_SOCK_CLOEXEC
#define MHD_recv_(s, b, l)
#define MHD_send_(s, b, l)
#define MHD_SCKT_ECONNRESET_
#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)
MHD internal shared structures.
@ MHD_EVENT_LOOP_INFO_READ
@ MHD_EVENT_LOOP_INFO_WRITE
@ MHD_EVENT_LOOP_INFO_CLEANUP
@ MHD_EVENT_LOOP_INFO_BLOCK
#define MHD_INVALID_SOCKET
void MHD_request_resume(struct MHD_Request *request)
struct MHD_Request request
time_t connection_timeout
struct sockaddr_storage addr
TransmitCallback send_cls
MHD_thread_handle_ID_ pid
struct MHD_Daemon * daemon
MHD_mutex_ cleanup_connection_mutex
MHD_AcceptPolicyCallback accept_policy_cb
struct MHD_Connection * connections_head
MHD_NotifyConnectionCallback notify_connection_cb
void * notify_connection_cb_cls
unsigned int worker_pool_size
enum MHD_EventLoopSyscall event_loop_syscall
struct MHD_Daemon * worker_pool
MHD_thread_handle_ID_ pid
time_t connection_default_timeout
struct MHD_Connection * normal_timeout_head
size_t connection_memory_limit_b
struct MHD_Connection * normal_timeout_tail
enum MHD_ThreadingMode threading_mode
unsigned int global_connection_limit
void * accept_policy_cb_cls
size_t thread_stack_limit_b
struct MHD_Connection * connections_tail
struct MHD_Response * response
enum MHD_RequestEventLoopInfo event_loop_info
enum MHD_REQUEST_STATE state
void * termination_cb_cls
MHD_RequestTerminationCallback termination_cb