Go to the documentation of this file.
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).\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;
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"),
struct MHD_Daemon * worker_pool
unsigned int worker_pool_size
enum MHD_StatusCode MHD_accept_connection_(struct MHD_Daemon *daemon)
int MHD_socket_nonblocking_(MHD_socket sock)
#define MHD_socket_close_chk_(fd)
@ MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN
#define EDLL_insert(head, tail, element)
#define MHD_mutex_unlock_chk_(pmutex)
@ MHD_EPOLL_STATE_WRITE_READY
void MHD_connection_finish_forward_(struct MHD_Connection *connection) MHD_NONNULL(1)
void MHD_connection_update_last_activity_(struct MHD_Connection *connection)
time_t MHD_monotonic_sec_counter(void)
@ MHD_EVENT_LOOP_INFO_BLOCK
#define MAYBE_SOCK_NONBLOCK
struct MHD_Connection * normal_timeout_tail
void * accept_policy_cb_cls
void * MHD_calloc_(size_t nelem, size_t elsize)
struct MHD_Connection * normal_timeout_head
@ MHD_REQUEST_TERMINATED_COMPLETED_OK
#define MHD_recv_(s, b, l)
functions to add connection to our active set
non-public functions provided by daemon_poll.c
functions to close connection
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ thread_main_handle_connection(void *data)
#define MHD_INVALID_SOCKET
struct MemoryPool * MHD_pool_create(size_t max)
internal shared structures
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode rtc)
non-public functions provided by daemon_select.c
TransmitCallback send_cls
int MHD_add_to_fd_set_(MHD_socket fd, fd_set *set, MHD_socket *max_fd, unsigned int fd_setsize)
static ssize_t recv_param_adapter(struct MHD_Connection *connection, void *other, size_t i)
enum MHD_RequestEventLoopInfo event_loop_info
#define MHD_socket_get_error_()
#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)
enum MHD_EventLoopSyscall event_loop_syscall
#define MHD_SCKT_ERR_IS_(err, code)
@ MHD_EPOLL_STATE_IN_EPOLL_SET
@ MHD_EVENT_LOOP_INFO_READ
#define MHD_ERR_CONNRESET_
int MHD_socket_noninheritable_(MHD_socket sock)
void * notify_connection_cb_cls
struct MHD_Request request
#define DLL_insert(head, tail, element)
#define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)
enum MHD_StatusCode MHD_daemon_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen)
MHD_thread_handle_ID_ pid
struct sockaddr_storage addr
#define DLL_remove(head, tail, element)
enum MHD_ThreadingMode threading_mode
size_t thread_stack_limit_b
void MHD_pool_destroy(struct MemoryPool *pool)
#define MHD_socket_last_strerr_()
MHD_mutex_ cleanup_connection_mutex
enum MHD_REQUEST_STATE state
unsigned int global_connection_limit
#define MHD_create_named_thread_(t, n, s, r, a)
MHD_AcceptPolicyCallback accept_policy_cb
static ssize_t send_param_adapter(struct MHD_Connection *connection, const void *other, size_t i)
@ MHD_CONNECTION_NOTIFY_STARTED
#define MHD_SYS_select_(n, r, w, e, t)
size_t connection_memory_limit_b
MHD_RequestTerminationCallback termination_cb
void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
function to update last activity of a connection
int MHD_ip_limit_add(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
@ MHD_EVENT_LOOP_INFO_CLEANUP
void * termination_cb_cls
@ MHD_EPOLL_STATE_READ_READY
#define MHD_mutex_lock_chk_(pmutex)
#define MHD_strerror_(errnum)
#define MHD_SCKT_ERR_IS_EAGAIN_(err)
#define XDLL_remove(head, tail, element)
struct MHD_Daemon * daemon
time_t connection_default_timeout
MHD_thread_handle_ID_ pid
struct MHD_Connection * connections_tail
#define XDLL_insert(head, tail, element)
#define MHD_SCKT_FD_FITS_FDSET_(fd, pset)
complete upgrade socket forwarding operation in TLS mode
@ MHD_REQUEST_TERMINATED_WITH_ERROR
void MHD_request_resume(struct MHD_Request *request)
struct MHD_Connection * connections_head
#define MAYBE_SOCK_CLOEXEC
#define MHD_SCKT_LAST_ERR_IS_(code)
function to call event handlers based on event mask
#define MHD_SCKT_ECONNRESET_
#define MHD_send_(s, b, l)
#define MHD_socket_strerr_(err)
struct MHD_Response * response
#define TIMEVAL_TV_SEC_MAX
MHD_NotifyConnectionCallback notify_connection_cb
bool MHD_request_handle_idle_(struct MHD_Request *request)
#define MHD_SCKT_ERR_IS_EINTR_(err)
void MHD_response_queue_for_destroy(struct MHD_Response *response)
@ MHD_EPOLL_STATE_IN_EREADY_EDLL
time_t connection_timeout
counting of connections per IP
@ MHD_CONNECTION_NOTIFY_CLOSED
#define MHD_SCKT_SEND_MAX_SIZE_
int MHD_connection_call_handlers_(struct MHD_Connection *con, bool read_ready, bool write_ready, bool force_close)
@ MHD_EVENT_LOOP_INFO_WRITE
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)