From e379ceb7df948e09982db6b1e7a9d7b4ffb722ae Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 4 Sep 2016 11:11:43 +0000 Subject: -extend test to cover poll and epoll, epoll-related fixes --- src/microhttpd/daemon.c | 85 +++++---------------------------------- src/microhttpd/test_upgrade_ssl.c | 13 ++++-- 2 files changed, 19 insertions(+), 79 deletions(-) (limited to 'src') diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index 08709c80..487575e0 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c @@ -3173,8 +3173,6 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon) { 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)) @@ -3184,79 +3182,6 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon) /* 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; @@ -3399,7 +3324,6 @@ MHD_epoll (struct MHD_Daemon *daemon, { /* 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; } @@ -4977,6 +4901,15 @@ thread_failed: /* clean up basic memory state in 'daemon' and return NULL to indicate failure */ #ifdef EPOLL_SUPPORT + if (MHD_YES == daemon->upgrade_fd_in_epoll) + { + if (0 != epoll_ctl (daemon->epoll_fd, + EPOLL_CTL_DEL, + daemon->epoll_upgrade_fd, + NULL)) + MHD_PANIC ("Failed to remove FD from epoll set\n"); + daemon->upgrade_fd_in_epoll = MHD_NO; + } if (-1 != daemon->epoll_fd) close (daemon->epoll_fd); #if HTTPS_SUPPORT diff --git a/src/microhttpd/test_upgrade_ssl.c b/src/microhttpd/test_upgrade_ssl.c index fc8d55a6..ad5b40c5 100644 --- a/src/microhttpd/test_upgrade_ssl.c +++ b/src/microhttpd/test_upgrade_ssl.c @@ -393,13 +393,13 @@ ahc_upgrade (void *cls, static int -test_upgrade_internal_select () +test_upgrade_internal (int flags) { struct MHD_Daemon *d; MHD_socket sock; pid_t pid; - d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG | MHD_USE_SUSPEND_RESUME | MHD_USE_TLS, + d = MHD_start_daemon (flags | MHD_USE_DEBUG | MHD_USE_SUSPEND_RESUME | MHD_USE_TLS, 1080, NULL, NULL, &ahc_upgrade, NULL, @@ -440,7 +440,14 @@ main (int argc, if (0 != system ("openssl version 1> /dev/null")) return 77; /* openssl not available, can't run the test */ - errorCount += test_upgrade_internal_select (); + errorCount += test_upgrade_internal (MHD_USE_SELECT_INTERNALLY); +#ifdef HAVE_POLL + errorCount += test_upgrade_internal (MHD_USE_POLL_INTERNALLY); +#endif +#ifdef EPOLL_SUPPORT + errorCount += test_upgrade_internal (MHD_USE_EPOLL_INTERNALLY | + MHD_USE_TLS_EPOLL_UPGRADE); +#endif if (errorCount != 0) fprintf (stderr, "Error (code: %u)\n", -- cgit v1.2.3