36 #ifdef UPGRADE_SUPPORT 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);
84 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
101 #define EXTRA_SLOTS 1 103 #define EXTRA_SLOTS 0 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;
504 else if (i > (
size_t) ret)
558 else if (i > (
size_t) ret)
587 static 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)."));
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;
1064 #ifdef HAVE_MESSAGES 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;
1080 #ifdef HAVE_MESSAGES 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;
1090 #ifdef HAVE_MESSAGES 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) 1101 #ifdef HAVE_MESSAGES 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) 1115 #ifdef HAVE_MESSAGES 1117 MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED,
1119 "Failed to set noninheritable mode on incoming connection socket.\n"));
1123 #ifdef HAVE_MESSAGES 1126 MHD_SC_CONNECTION_ACCEPTED,
1127 _ (
"Accepted connection on socket %d\n"),
#define MHD_send_(s, b, l)
struct MHD_Request request
int MHD_ip_limit_add(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
enum MHD_EventLoopSyscall event_loop_syscall
void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
size_t connection_memory_limit_b
#define MHD_SYS_select_(n, r, w, e, t)
struct sockaddr_storage addr
non-public functions provided by daemon_select.c
MHD_thread_handle_ID_ pid
#define MHD_mutex_unlock_chk_(pmutex)
unsigned int global_connection_limit
MHD_AcceptPolicyCallback accept_policy_cb
void * termination_cb_cls
#define MHD_socket_get_error_()
size_t thread_stack_limit_b
void * MHD_calloc_(size_t nelem, size_t elsize)
#define MHD_socket_strerr_(err)
#define EDLL_insert(head, tail, element)
MHD_RequestTerminationCallback termination_cb
MHD_thread_handle_ID_ pid
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)
#define MHD_SCKT_ERR_IS_EAGAIN_(err)
static ssize_t send_param_adapter(struct MHD_Connection *connection, const void *other, size_t i)
#define MHD_SCKT_LAST_ERR_IS_(code)
internal shared structures
#define MHD_ERR_CONNRESET_
static ssize_t recv_param_adapter(struct MHD_Connection *connection, void *other, size_t i)
struct MHD_Daemon * daemon
MHD_NotifyConnectionCallback notify_connection_cb
function to update last activity of a connection
time_t connection_default_timeout
enum MHD_REQUEST_STATE state
#define DLL_insert(head, tail, element)
#define MHD_socket_last_strerr_()
struct MHD_Connection * connections_tail
struct MHD_Daemon * worker_pool
functions to close connection
struct MemoryPool * MHD_pool_create(size_t max)
#define MHD_INVALID_SOCKET
enum MHD_StatusCode MHD_daemon_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen)
#define MHD_SCKT_SEND_MAX_SIZE_
unsigned int worker_pool_size
struct MHD_Connection * connections_head
#define MHD_socket_close_chk_(fd)
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode rtc)
complete upgrade socket forwarding operation in TLS mode
time_t connection_timeout
#define MHD_SCKT_ERR_IS_(err, code)
enum MHD_RequestEventLoopInfo event_loop_info
function to call event handlers based on event mask
enum MHD_StatusCode MHD_accept_connection_(struct MHD_Daemon *daemon)
#define TIMEVAL_TV_SEC_MAX
#define DLL_remove(head, tail, element)
#define MHD_strerror_(errnum)
void * accept_policy_cb_cls
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ thread_main_handle_connection(void *data)
struct MHD_Connection * normal_timeout_head
int MHD_connection_call_handlers_(struct MHD_Connection *con, bool read_ready, bool write_ready, bool force_close)
void MHD_pool_destroy(struct MemoryPool *pool)
void MHD_request_resume(struct MHD_Request *request)
void MHD_connection_finish_forward_(struct MHD_Connection *connection) MHD_NONNULL(1)
#define XDLL_remove(head, tail, element)
#define MHD_create_named_thread_(t, n, s, r, a)
#define MHD_recv_(s, b, l)
struct MHD_Connection * normal_timeout_tail
non-public functions provided by daemon_poll.c
struct MHD_Response * response
#define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)
#define MHD_mutex_lock_chk_(pmutex)
#define MHD_SCKT_FD_FITS_FDSET_(fd, pset)
TransmitCallback send_cls
int MHD_socket_nonblocking_(MHD_socket sock)
#define XDLL_insert(head, tail, element)
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)
#define MHD_SCKT_ECONNRESET_
counting of connections per IP
void * notify_connection_cb_cls
enum MHD_ThreadingMode threading_mode
#define MHD_SCKT_ERR_IS_EINTR_(err)
void MHD_connection_update_last_activity_(struct MHD_Connection *connection)
bool MHD_request_handle_idle_(struct MHD_Request *request)
MHD_mutex_ cleanup_connection_mutex
functions to add connection to our active set
#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)
int MHD_socket_noninheritable_(MHD_socket sock)
#define MAYBE_SOCK_NONBLOCK
void MHD_response_queue_for_destroy(struct MHD_Response *response)
#define MAYBE_SOCK_CLOEXEC