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);
82 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
101 #define EXTRA_SLOTS 0 110 const bool use_poll =
false;
112 bool was_suspended =
false;
114 MHD_thread_init_ (&con->
pid);
120 #ifdef UPGRADE_SUPPORT 121 struct MHD_UpgradeResponseHandle *
const urh = con->
request.urh;
123 static const void *
const urh =
NULL;
130 was_suspended =
true;
141 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
142 _ (
"Failed to add FD to fd_set\n"));
158 MHD_SC_UNEXPECTED_SELECT_ERROR,
159 _ (
"Error during select (%d): `%s'\n"),
169 p[0].events = POLLIN;
170 p[0].fd = MHD_itc_r_fd_ (daemon->
itc);
172 if (0 > MHD_sys_poll_ (p,
180 MHD_SC_UNEXPECTED_POLL_ERROR,
181 _ (
"Error during poll: `%s'\n"),
188 MHD_itc_clear_ (daemon->
itc);
197 was_suspended =
false;
215 if ( (
NULL == tvp) &&
223 const time_t seconds_left = timeout - (now - con->
last_activity);
224 #if ! defined(_WIN32) || defined(__CYGWIN__) 225 tv.tv_sec = seconds_left;
239 bool err_state =
false;
273 if (MHD_ITC_IS_VALID_ (daemon->
itc) )
286 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
287 _ (
"Failed to add FD to fd_set\n"));
305 MHD_SC_UNEXPECTED_SELECT_ERROR,
306 _ (
"Error during select (%d): `%s'\n"),
315 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
316 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
318 MHD_itc_clear_ (daemon->
itc);
341 p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
344 p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
347 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
355 if (MHD_ITC_IS_VALID_ (daemon->
itc))
357 p[1].events |= POLLIN;
358 p[1].fd = MHD_itc_r_fd_ (daemon->
itc);
363 if (MHD_sys_poll_ (p,
369 (
NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
375 MHD_SC_UNEXPECTED_POLL_ERROR,
376 _ (
"Error during poll: `%s'\n"),
384 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
385 (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
386 MHD_itc_clear_ (daemon->
itc);
390 (0 != (p[0].revents & POLLIN)),
391 (0 != (p[0].revents & POLLOUT)),
392 (0 != (p[0].revents & (POLLERR
394 MHD_POLL_REVENTS_ERR_DISC))) ))
398 #ifdef UPGRADE_SUPPORT 408 thread_main_connection_upgrade (con);
412 con->
request.urh->clean_ready =
true;
420 return (MHD_THRD_RTRN_TYPE_) 0;
427 MHD_SC_THREAD_TERMINATING,
428 _ (
"Processing thread terminating. Closing connection\n"));
452 return (MHD_THRD_RTRN_TYPE_) 0;
502 else if (i > (
size_t) ret)
556 else if (i > (
size_t) ret)
585 static enum MHD_StatusCode
588 const struct sockaddr *addr,
593 enum MHD_StatusCode sc;
600 if ( (external_add) &&
625 return MHD_SC_LIMIT_CONNECTIONS_REACHED;
634 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
635 _ (
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
643 return MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
646 #ifdef MHD_socket_nosignal_ 647 if (! MHD_socket_nosignal_ (client_socket))
651 MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED,
652 _ (
"Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
660 return MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED;
669 MHD_SC_CONNECTION_ACCEPTED,
670 _ (
"Accepted connection on socket %d\n"),
682 MHD_SC_LIMIT_CONNECTIONS_REACHED,
684 "Server reached connection limit. Closing inbound connection.\n"));
690 return MHD_SC_LIMIT_CONNECTIONS_REACHED;
703 MHD_SC_ACCEPT_POLICY_REJECTED,
704 _ (
"Connection rejected by application. Closing connection.\n"));
714 return MHD_SC_ACCEPT_POLICY_REJECTED;
724 MHD_SC_CONNECTION_MALLOC_FAILURE,
725 "Error allocating memory: %s\n",
733 return MHD_SC_CONNECTION_MALLOC_FAILURE;
741 MHD_SC_POOL_MALLOC_FAILURE,
742 _ (
"Error allocating memory: %s\n"),
753 return MHD_SC_POOL_MALLOC_FAILURE;
757 memcpy (&connection->
addr,
763 connection->
daemon = daemon;
767 if (
NULL != daemon->tls_api)
770 = daemon->tls_api->setup_connection (daemon->tls_api->cls,
772 if (
NULL == connection->tls_cs)
794 MHD_SC_LIMIT_CONNECTIONS_REACHED,
796 "Server reached connection limit. Closing inbound connection.\n"));
801 sc = MHD_SC_LIMIT_CONNECTIONS_REACHED;
833 MHD_SC_THREAD_LAUNCH_FAILURE,
834 "Failed to create a thread: %s\n",
837 sc = MHD_SC_THREAD_LAUNCH_FAILURE;
843 connection->
pid = daemon->
pid;
851 struct epoll_event event;
853 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
854 event.data.ptr = connection;
855 if (0 != epoll_ctl (daemon->epoll_fd,
863 MHD_SC_EPOLL_CTL_ADD_FAILED,
864 _ (
"Call to epoll_ctl failed: %s\n"),
867 sc = MHD_SC_EPOLL_CTL_ADD_FAILED;
886 (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
887 (! MHD_itc_activate_ (daemon->
itc,
892 MHD_SC_ITC_USE_FAILED,
894 "Failed to signal new connection via inter-thread communication channel (not necessarily fatal, continuing anyway)."));
905 if ( (
NULL != daemon->tls_api) &&
906 (
NULL != connection->tls_cs) )
907 daemon->tls_api->teardown_connection (daemon->tls_api->cls,
964 const struct sockaddr *addr,
973 MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED,
974 _ (
"Failed to set nonblocking mode on new client socket: %s\n"),
989 MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED,
990 _ (
"Failed to set noninheritable mode on new client socket.\n"));
1014 struct sockaddr_storage addrstorage;
1015 struct sockaddr *addr = (
struct sockaddr *) &addrstorage;
1021 addrlen =
sizeof (addrstorage);
1024 sizeof (addrstorage));
1027 return MHD_SC_DAEMON_ALREADY_QUIESCED;
1048 return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
1050 return MHD_SC_ACCEPT_FAST_DISCONNECT;
1052 return MHD_SC_ACCEPT_FAILED_EAGAIN;
1062 #ifdef HAVE_MESSAGES 1067 MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY,
1069 "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"));
1071 return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY;
1078 #ifdef HAVE_MESSAGES 1080 MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED,
1082 "Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
1085 return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED;
1088 #ifdef HAVE_MESSAGES 1090 MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY,
1091 _ (
"Error accepting connection: %s\n"),
1094 return MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY;
1096 #if ! defined(USE_ACCEPT4) || ! defined(HAVE_SOCK_NONBLOCK) 1099 #ifdef HAVE_MESSAGES 1101 MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED,
1103 "Failed to set nonblocking mode on incoming connection socket: %s\n"),
1110 #if ! defined(USE_ACCEPT4) || ! defined(SOCK_CLOEXEC) 1113 #ifdef HAVE_MESSAGES 1115 MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED,
1117 "Failed to set noninheritable mode on incoming connection socket.\n"));
1121 #ifdef HAVE_MESSAGES 1124 MHD_SC_CONNECTION_ACCEPTED,
1125 _ (
"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