diff options
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r-- | src/microhttpd/daemon.c | 392 |
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 |