summaryrefslogtreecommitdiff
path: root/src/microhttpd/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r--src/microhttpd/daemon.c392
1 files changed, 303 insertions, 89 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index a25fe358..2fb87ed4 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -626,11 +626,15 @@ MHD_get_fdset (struct MHD_Daemon *daemon,
fd_set *except_fd_set,
MHD_socket *max_fd)
{
- return MHD_get_fdset2(daemon, read_fd_set,
- write_fd_set, except_fd_set,
- max_fd, _MHD_SYS_DEFAULT_FD_SETSIZE);
+ return MHD_get_fdset2 (daemon,
+ read_fd_set,
+ write_fd_set,
+ except_fd_set,
+ max_fd,
+ _MHD_SYS_DEFAULT_FD_SETSIZE);
}
+
/**
* Obtain the `select()` sets for this daemon.
* Daemon's FDs will be added to fd_sets. To get only
@@ -729,25 +733,25 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
}
for (urh = daemon->urh_head; NULL != urh; urh = urh->next)
{
- if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->celi_mhd)) &&
- (! MHD_add_to_fd_set_ (urh->mhd_socket,
+ if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
+ (! MHD_add_to_fd_set_ (urh->mhd.socket,
read_fd_set,
max_fd,
fd_setsize)) )
result = MHD_NO;
- if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->celi_mhd)) &&
- (! MHD_add_to_fd_set_ (urh->mhd_socket,
+ if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
+ (! MHD_add_to_fd_set_ (urh->mhd.socket,
write_fd_set,
max_fd,
fd_setsize)) )
result = MHD_NO;
- if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->celi_client)) &&
+ if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) &&
(! MHD_add_to_fd_set_ (urh->connection->socket_fd,
read_fd_set,
max_fd,
fd_setsize)) )
result = MHD_NO;
- if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->celi_client)) &&
+ if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
(! MHD_add_to_fd_set_ (urh->connection->socket_fd,
write_fd_set,
max_fd,
@@ -2175,7 +2179,7 @@ static void
process_urh (struct MHD_UpgradeResponseHandle *urh)
{
/* handle reading from TLS client and writing to application */
- if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->celi_client)) &&
+ if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) &&
(urh->in_buffer_off < urh->in_buffer_size) )
{
ssize_t res;
@@ -2186,25 +2190,25 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
if ( (GNUTLS_E_AGAIN == res) ||
(GNUTLS_E_INTERRUPTED == res) )
{
- urh->celi_client &= ~MHD_EPOLL_STATE_READ_READY;
+ urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
}
else if (res > 0)
{
urh->in_buffer_off += res;
}
}
- if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->celi_mhd)) &&
+ if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
(urh->in_buffer_off > 0) )
{
size_t res;
- res = write (urh->mhd_socket,
+ res = write (urh->mhd.socket,
urh->in_buffer,
urh->in_buffer_off);
if (-1 == res)
{
/* FIXME: differenciate by errno? */
- urh->celi_mhd &= ~MHD_EPOLL_STATE_WRITE_READY;
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
}
else
{
@@ -2223,25 +2227,25 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
}
/* handle reading from application and writing to HTTPS client */
- if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->celi_mhd)) &&
+ if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
(urh->out_buffer_off < urh->out_buffer_size) )
{
size_t res;
- res = read (urh->mhd_socket,
+ res = read (urh->mhd.socket,
&urh->out_buffer[urh->out_buffer_off],
urh->out_buffer_size - urh->out_buffer_off);
if (-1 == res)
{
/* FIXME: differenciate by errno? */
- urh->celi_mhd &= ~MHD_EPOLL_STATE_READ_READY;
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
}
else
{
urh->out_buffer_off += res;
}
}
- if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->celi_client)) &&
+ if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
(urh->out_buffer_off > 0) )
{
ssize_t res;
@@ -2252,7 +2256,7 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
if ( (GNUTLS_E_AGAIN == res) ||
(GNUTLS_E_INTERRUPTED == res) )
{
- urh->celi_client &= ~MHD_EPOLL_STATE_WRITE_READY;
+ urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
}
else if (res > 0)
{
@@ -2359,13 +2363,13 @@ MHD_run_from_select (struct MHD_Daemon *daemon,
{
/* update urh state based on select() output */
if (FD_ISSET (urh->connection->socket_fd, read_fd_set))
- urh->celi_client |= MHD_EPOLL_STATE_READ_READY;
+ urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
if (FD_ISSET (urh->connection->socket_fd, write_fd_set))
- urh->celi_client |= MHD_EPOLL_STATE_WRITE_READY;
- if (FD_ISSET (urh->mhd_socket, read_fd_set))
- urh->celi_mhd |= MHD_EPOLL_STATE_READ_READY;
- if (FD_ISSET (urh->mhd_socket, write_fd_set))
- urh->celi_mhd |= MHD_EPOLL_STATE_WRITE_READY;
+ urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
+ if (FD_ISSET (urh->mhd.socket, read_fd_set))
+ urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
+ if (FD_ISSET (urh->mhd.socket, write_fd_set))
+ urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
/* call generic forwarding function for passing data */
process_urh (urh);
}
@@ -2632,15 +2636,15 @@ MHD_poll_all (struct MHD_Daemon *daemon,
for (urh = daemon->urh_head; NULL != urh; urh = urh->next)
{
p[poll_server+i].fd = urh->connection->socket_fd;
- if (0 == (MHD_EPOLL_STATE_READ_READY & urh->celi_client))
+ if (0 == (MHD_EPOLL_STATE_READ_READY & urh->app.celi))
p[poll_server+i].events |= POLLIN;
- if (0 == (MHD_EPOLL_STATE_WRITE_READY & urh->celi_client))
+ if (0 == (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi))
p[poll_server+i].events |= POLLOUT;
i++;
- p[poll_server+i].fd = urh->mhd_socket;
- if (0 == (MHD_EPOLL_STATE_READ_READY & urh->celi_mhd))
+ p[poll_server+i].fd = urh->mhd.socket;
+ if (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi))
p[poll_server+i].events |= POLLIN;
- if (0 == (MHD_EPOLL_STATE_WRITE_READY & urh->celi_mhd))
+ if (0 == (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi))
p[poll_server+i].events |= POLLOUT;
i++;
}
@@ -2701,11 +2705,11 @@ MHD_poll_all (struct MHD_Daemon *daemon,
if (p[poll_server+i].fd != urh->connection->socket_fd)
continue; /* fd mismatch, something else happened, retry later ... */
if (0 != (p[poll_server+i].revents & POLLIN))
- urh->celi_client |= MHD_EPOLL_STATE_READ_READY;
+ urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
if (0 != (p[poll_server+i].revents & POLLOUT))
- urh->celi_client |= MHD_EPOLL_STATE_WRITE_READY;
+ urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
i++;
- if (p[poll_server+i].fd != urh->mhd_socket)
+ if (p[poll_server+i].fd != urh->mhd.socket)
{
/* fd mismatch, something else happened, retry later ... */
/* may still be able to do something based on updates
@@ -2714,9 +2718,9 @@ MHD_poll_all (struct MHD_Daemon *daemon,
continue;
}
if (0 != (p[poll_server+i].revents & POLLIN))
- urh->celi_mhd |= MHD_EPOLL_STATE_READ_READY;
+ urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
if (0 != (p[poll_server+i].revents & POLLOUT))
- urh->celi_mhd |= MHD_EPOLL_STATE_WRITE_READY;
+ urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
i++;
process_urh (urh);
}
@@ -2832,6 +2836,136 @@ MHD_poll (struct MHD_Daemon *daemon,
#define MAX_EVENTS 128
+#if HTTPS_SUPPORT
+
+/**
+ * Do epoll()-based processing for TLS connections that have been
+ * upgraded. This requires a separate epoll() invocation as we
+ * cannot use the `struct MHD_Connection` data structures for
+ * the `union epoll_data` in this case.
+ */
+static int
+run_epoll_for_upgrade (struct MHD_Daemon *daemon)
+{
+ struct epoll_event events[MAX_EVENTS];
+ int num_events;
+ unsigned int i;
+
+ num_events = MAX_EVENTS;
+ while (MAX_EVENTS == num_events)
+ {
+ /* update event masks */
+ num_events = epoll_wait (daemon->epoll_upgrade_fd,
+ events,
+ MAX_EVENTS,
+ 0);
+ if (-1 == num_events)
+ {
+ const int err = MHD_socket_get_error_ ();
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ return MHD_YES;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ "Call to epoll_wait failed: %s\n",
+ MHD_socket_strerr_ (err));
+#endif
+ return MHD_NO;
+ }
+ for (i=0;i<(unsigned int) num_events;i++)
+ {
+ struct UpgradeEpollHandle *ueh = events[i].data.ptr;
+ struct MHD_UpgradeResponseHandle *urh = ueh->urh;
+ struct epoll_event event;
+ int fd;
+
+ /* Update our state based on what is ready according to epoll() */
+ if (0 != (events[i].events & EPOLLIN))
+ ueh->celi |= MHD_EPOLL_STATE_READ_READY;
+ if (0 != (events[i].events & EPOLLOUT))
+ ueh->celi |= MHD_EPOLL_STATE_WRITE_READY;
+
+ /* shuffle data based on buffers and FD readyness */
+ process_urh (urh);
+
+ /* if we drained the IO buffer, re-add to epoll() to wait for more! */
+ if (0 == (ueh->celi & MHD_EPOLL_STATE_READ_READY))
+ {
+ event.events = EPOLLIN;
+ event.data.ptr = ueh;
+ fd = (ueh == &urh->mhd) ? ueh->socket : urh->connection->socket_fd;
+ if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
+ EPOLL_CTL_ADD,
+ fd,
+ &event))
+ {
+ MHD_socket myfd;
+
+ /* Handle error by closing OUR socket; with some
+ luck, this should tricker the application to fail
+ to read, and then the application should close
+ the connection completely. */
+
+ /* epoll documentation suggests that closing a FD
+ automatically removes it from the epoll set;
+ however, this is not true as if we fail to do
+ manually remove it, we are still seeing an event
+ for this fd in epoll, causing grief
+ (use-after-free...) --- at least on my system. */
+ myfd = urh->mhd.socket;
+ if ( (fd != myfd) &&
+ (0 != epoll_ctl (daemon->epoll_upgrade_fd,
+ EPOLL_CTL_DEL,
+ urh->mhd.socket,
+ NULL)) )
+ MHD_PANIC ("Failed to remove FD from epoll set\n");
+ urh->mhd.socket = MHD_INVALID_SOCKET;
+ MHD_socket_close_ (myfd);
+ continue;
+ }
+ }
+ if (0 == (ueh->celi & MHD_EPOLL_STATE_WRITE_READY))
+ {
+ event.events = EPOLLOUT;
+ event.data.ptr = ueh;
+ fd = (ueh == &ueh->urh->mhd) ? ueh->socket : ueh->urh->connection->socket_fd;
+ if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
+ EPOLL_CTL_ADD,
+ fd,
+ &event))
+ {
+ MHD_socket myfd;
+
+ /* Handle error by closing OUR socket; with some
+ luck, this should tricker the application to fail
+ to read, and then the application should close
+ the connection completely. */
+
+ /* epoll documentation suggests that closing a FD
+ automatically removes it from the epoll set;
+ however, this is not true as if we fail to do
+ manually remove it, we are still seeing an event
+ for this fd in epoll, causing grief
+ (use-after-free...) --- at least on my system. */
+ myfd = urh->mhd.socket;
+ if ( (fd != myfd) &&
+ (0 != epoll_ctl (daemon->epoll_upgrade_fd,
+ EPOLL_CTL_DEL,
+ urh->mhd.socket,
+ NULL)) )
+ MHD_PANIC ("Failed to remove FD from epoll set\n");
+
+ urh->mhd.socket = MHD_INVALID_SOCKET;
+ MHD_socket_close_ (myfd);
+ continue;
+ }
+ }
+ }
+ }
+ return MHD_YES;
+}
+#endif
+
+
/**
* Do epoll()-based processing (this function is allowed to
* block if @a may_block is set to #MHD_YES).
@@ -2844,6 +2978,9 @@ static int
MHD_epoll (struct MHD_Daemon *daemon,
int may_block)
{
+#if HTTPS_SUPPORT
+ static const char *upgrade_marker = "upgrade_ptr";
+#endif
struct MHD_Connection *pos;
struct MHD_Connection *next;
struct epoll_event events[MAX_EVENTS];
@@ -2879,6 +3016,27 @@ MHD_epoll (struct MHD_Daemon *daemon,
}
daemon->listen_socket_in_epoll = MHD_YES;
}
+#if HTTPS_SUPPORT
+ if ( (MHD_NO == daemon->upgrade_fd_in_epoll) &&
+ (MHD_INVALID_SOCKET != daemon->epoll_upgrade_fd) )
+ {
+ event.events = EPOLLIN | EPOLLOUT;
+ event.data.ptr = (void *) upgrade_marker;
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_ADD,
+ daemon->epoll_upgrade_fd,
+ &event))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ "Call to epoll_ctl failed: %s\n",
+ MHD_socket_last_strerr_ ());
+#endif
+ return MHD_NO;
+ }
+ daemon->upgrade_fd_in_epoll = MHD_YES;
+ }
+#endif
if ( ( (MHD_YES == daemon->listen_socket_in_epoll) &&
(daemon->connections == daemon->connection_limit) ) ||
(MHD_YES == daemon->at_limit) )
@@ -2917,7 +3075,9 @@ MHD_epoll (struct MHD_Daemon *daemon,
{
/* update event masks */
num_events = epoll_wait (daemon->epoll_fd,
- events, MAX_EVENTS, timeout_ms);
+ events,
+ MAX_EVENTS,
+ timeout_ms);
if (-1 == num_events)
{
const int err = MHD_socket_get_error_ ();
@@ -2932,8 +3092,25 @@ MHD_epoll (struct MHD_Daemon *daemon,
}
for (i=0;i<(unsigned int) num_events;i++)
{
+ /* First, check for the values of `ptr` that would indicate
+ that this event is not about a normal connection. */
if (NULL == events[i].data.ptr)
continue; /* shutdown signal! */
+#if HTTPS_SUPPORT
+ if (upgrade_marker == events[i].data.ptr)
+ {
+ /* activity on an upgraded connection, we process
+ those in a separate epoll() */
+ daemon->upgrade_fd_in_epoll = MHD_NO;
+ run_epoll_for_upgrade (daemon);
+ continue;
+ }
+#endif
+ /* UGH: we're storing pointers and fds in the same union
+ here; incredibly ugly and somewhat risky, even though a
+ pointer with the same numeric value as the wpipe[0] can
+ be expected to be rare... FIXME (a construction similar
+ to what we did with the `upgrade_marker` should do) */
if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
(daemon->wpipe[0] == events[i].data.fd) )
{
@@ -2942,39 +3119,7 @@ MHD_epoll (struct MHD_Daemon *daemon,
MHD_pipe_drain_ (daemon->wpipe[0]);
continue;
}
- if (daemon != events[i].data.ptr)
- {
- /* this is an event relating to a 'normal' connection,
- remember the event and if appropriate mark the
- connection as 'eready'. */
- pos = events[i].data.ptr;
- if (0 != (events[i].events & EPOLLIN))
- {
- pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
- if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ||
- (pos->read_buffer_size > pos->read_buffer_offset) ) &&
- (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
- {
- EDLL_insert (daemon->eready_head,
- daemon->eready_tail,
- pos);
- pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
- }
- }
- if (0 != (events[i].events & EPOLLOUT))
- {
- pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
- if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
- (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
- {
- EDLL_insert (daemon->eready_head,
- daemon->eready_tail,
- pos);
- pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
- }
- }
- }
- else /* must be listen socket */
+ if (daemon == events[i].data.ptr)
{
/* run 'accept' until it fails or we are not allowed to take
on more connections */
@@ -2984,8 +3129,39 @@ MHD_epoll (struct MHD_Daemon *daemon,
(series_length < 128) &&
(MHD_NO == daemon->at_limit) )
series_length++;
+ continue;
}
- }
+ /* this is an event relating to a 'normal' connection,
+ remember the event and if appropriate mark the
+ connection as 'eready'. */
+ pos = events[i].data.ptr;
+ /* normal processing: update read/write data */
+ if (0 != (events[i].events & EPOLLIN))
+ {
+ pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
+ if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ||
+ (pos->read_buffer_size > pos->read_buffer_offset) ) &&
+ (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
+ {
+ EDLL_insert (daemon->eready_head,
+ daemon->eready_tail,
+ pos);
+ pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ }
+ }
+ if (0 != (events[i].events & EPOLLOUT))
+ {
+ pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
+ if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
+ (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
+ {
+ EDLL_insert (daemon->eready_head,
+ daemon->eready_tail,
+ pos);
+ pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ }
+ }
+ }
}
/* we handle resumes here because we may have ready connections
@@ -3426,8 +3602,8 @@ parse_options_va (struct MHD_Daemon *daemon,
if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
{
#ifdef HAVE_MESSAGES
- MHD_DLOG(daemon,
- "Error initializing DH parameters\n");
+ MHD_DLOG (daemon,
+ "Error initializing DH parameters\n");
#endif
return MHD_NO;
}
@@ -3437,8 +3613,8 @@ parse_options_va (struct MHD_Daemon *daemon,
GNUTLS_X509_FMT_PEM) < 0)
{
#ifdef HAVE_MESSAGES
- MHD_DLOG(daemon,
- "Bad Diffie-Hellman parameters format\n");
+ MHD_DLOG (daemon,
+ "Bad Diffie-Hellman parameters format\n");
#endif
gnutls_dh_params_deinit (daemon->https_mem_dhparams);
return MHD_NO;
@@ -3652,34 +3828,27 @@ parse_options_va (struct MHD_Daemon *daemon,
#ifdef EPOLL_SUPPORT
-/**
- * Setup epoll() FD for the daemon and initialize it to listen
- * on the listen FD.
- *
- * @param daemon daemon to initialize for epoll()
- * @return #MHD_YES on success, #MHD_NO on failure
- */
static int
-setup_epoll_to_listen (struct MHD_Daemon *daemon)
+setup_epoll_fd (struct MHD_Daemon *daemon)
{
- struct epoll_event event;
+ int fd;
#ifdef USE_EPOLL_CREATE1
- daemon->epoll_fd = epoll_create1 (EPOLL_CLOEXEC);
+ fd = epoll_create1 (EPOLL_CLOEXEC);
#else /* ! USE_EPOLL_CREATE1 */
- daemon->epoll_fd = epoll_create (MAX_EVENTS);
+ fd = epoll_create (MAX_EVENTS);
#endif /* ! USE_EPOLL_CREATE1 */
- if (-1 == daemon->epoll_fd)
+ if (MHD_INVALID_SOCKET == fd)
{
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
"Call to epoll_create1 failed: %s\n",
MHD_socket_last_strerr_ ());
#endif
- return MHD_NO;
+ return MHD_INVALID_SOCKET;
}
#if !defined(USE_EPOLL_CREATE1)
- if (!MHD_socket_noninheritable_ (daemon->epoll_fd))
+ if (! MHD_socket_noninheritable_ (fd))
{
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
@@ -3687,6 +3856,33 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
#endif
}
#endif /* ! USE_EPOLL_CREATE1 */
+ return fd;
+}
+
+
+/**
+ * Setup epoll() FD for the daemon and initialize it to listen
+ * on the listen FD.
+ *
+ * @param daemon daemon to initialize for epoll()
+ * @return #MHD_YES on success, #MHD_NO on failure
+ */
+static int
+setup_epoll_to_listen (struct MHD_Daemon *daemon)
+{
+ struct epoll_event event;
+
+ daemon->epoll_fd = setup_epoll_fd (daemon);
+ if (MHD_INVALID_SOCKET == daemon->epoll_fd)
+ return MHD_NO;
+#if HTTPS_SUPPORT
+ if (MHD_USE_TLS_EPOLL_UPGRADE == (MHD_USE_TLS_EPOLL_UPGRADE & daemon->options))
+ {
+ daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
+ if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd)
+ return MHD_NO;
+ }
+#endif
if (MHD_INVALID_SOCKET == daemon->socket_fd)
return MHD_YES; /* non-listening daemon */
event.events = EPOLLIN;
@@ -3788,6 +3984,9 @@ MHD_start_daemon_va (unsigned int flags,
memset (daemon, 0, sizeof (struct MHD_Daemon));
#ifdef EPOLL_SUPPORT
daemon->epoll_fd = -1;
+#if HTTPS_SUPPORT
+ daemon->epoll_upgrade_fd = -1;
+#endif
#endif
/* try to open listen socket */
#if HTTPS_SUPPORT
@@ -3842,7 +4041,7 @@ MHD_start_daemon_va (unsigned int flags,
free (daemon);
return NULL;
}
- if (!MHD_itc_nonblocking_(daemon->wpipe[0]))
+ if (! MHD_itc_nonblocking_(daemon->wpipe[0]))
{
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
@@ -4482,6 +4681,10 @@ thread_failed:
#ifdef EPOLL_SUPPORT
if (-1 != daemon->epoll_fd)
close (daemon->epoll_fd);
+#if HTTPS_SUPPORT
+ if (-1 != daemon->epoll_upgrade_fd)
+ close (daemon->epoll_upgrade_fd);
+#endif
#endif
#ifdef DAUTH_SUPPORT
free (daemon->nnc);
@@ -4710,6 +4913,11 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
if ( (-1 != daemon->worker_pool[i].epoll_fd) &&
(0 != MHD_socket_close_ (daemon->worker_pool[i].epoll_fd)) )
MHD_PANIC ("close failed\n");
+#if HTTPS_SUPPORT
+ if ( (-1 != daemon->worker_pool[i].epoll_upgrade_fd) &&
+ (0 != MHD_socket_close_ (daemon->worker_pool[i].epoll_upgrade_fd)) )
+ MHD_PANIC ("close failed\n");
+#endif
#endif
/* Individual pipes are always used */
if (1)
@@ -4762,6 +4970,12 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
(-1 != daemon->epoll_fd) &&
(0 != MHD_socket_close_ (daemon->epoll_fd)) )
MHD_PANIC ("close failed\n");
+#if HTTPS_SUPPORT
+ if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
+ (-1 != daemon->epoll_upgrade_fd) &&
+ (0 != MHD_socket_close_ (daemon->epoll_upgrade_fd)) )
+ MHD_PANIC ("close failed\n");
+#endif
#endif
#ifdef DAUTH_SUPPORT