diff options
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r-- | src/microhttpd/daemon.c | 85 |
1 files changed, 9 insertions, 76 deletions
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) | |||
3173 | { | 3173 | { |
3174 | struct UpgradeEpollHandle *ueh = events[i].data.ptr; | 3174 | struct UpgradeEpollHandle *ueh = events[i].data.ptr; |
3175 | struct MHD_UpgradeResponseHandle *urh = ueh->urh; | 3175 | struct MHD_UpgradeResponseHandle *urh = ueh->urh; |
3176 | struct epoll_event event; | ||
3177 | int fd; | ||
3178 | 3176 | ||
3179 | /* Update our state based on what is ready according to epoll() */ | 3177 | /* Update our state based on what is ready according to epoll() */ |
3180 | if (0 != (events[i].events & EPOLLIN)) | 3178 | if (0 != (events[i].events & EPOLLIN)) |
@@ -3184,79 +3182,6 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon) | |||
3184 | 3182 | ||
3185 | /* shuffle data based on buffers and FD readyness */ | 3183 | /* shuffle data based on buffers and FD readyness */ |
3186 | process_urh (urh); | 3184 | process_urh (urh); |
3187 | |||
3188 | /* if we drained the IO buffer, re-add to epoll() to wait for more! */ | ||
3189 | if (0 == (ueh->celi & MHD_EPOLL_STATE_READ_READY)) | ||
3190 | { | ||
3191 | event.events = EPOLLIN; | ||
3192 | event.data.ptr = ueh; | ||
3193 | fd = (ueh == &urh->mhd) ? ueh->socket : urh->connection->socket_fd; | ||
3194 | if (0 != epoll_ctl (daemon->epoll_upgrade_fd, | ||
3195 | EPOLL_CTL_ADD, | ||
3196 | fd, | ||
3197 | &event)) | ||
3198 | { | ||
3199 | MHD_socket myfd; | ||
3200 | |||
3201 | /* Handle error by closing OUR socket; with some | ||
3202 | luck, this should tricker the application to fail | ||
3203 | to read, and then the application should close | ||
3204 | the connection completely. */ | ||
3205 | |||
3206 | /* epoll documentation suggests that closing a FD | ||
3207 | automatically removes it from the epoll set; | ||
3208 | however, this is not true as if we fail to do | ||
3209 | manually remove it, we are still seeing an event | ||
3210 | for this fd in epoll, causing grief | ||
3211 | (use-after-free...) --- at least on my system. */ | ||
3212 | myfd = urh->mhd.socket; | ||
3213 | if ( (fd != myfd) && | ||
3214 | (0 != epoll_ctl (daemon->epoll_upgrade_fd, | ||
3215 | EPOLL_CTL_DEL, | ||
3216 | urh->mhd.socket, | ||
3217 | NULL)) ) | ||
3218 | MHD_PANIC ("Failed to remove FD from epoll set\n"); | ||
3219 | urh->mhd.socket = MHD_INVALID_SOCKET; | ||
3220 | MHD_socket_close_ (myfd); | ||
3221 | continue; | ||
3222 | } | ||
3223 | } | ||
3224 | if (0 == (ueh->celi & MHD_EPOLL_STATE_WRITE_READY)) | ||
3225 | { | ||
3226 | event.events = EPOLLOUT; | ||
3227 | event.data.ptr = ueh; | ||
3228 | fd = (ueh == &ueh->urh->mhd) ? ueh->socket : ueh->urh->connection->socket_fd; | ||
3229 | if (0 != epoll_ctl (daemon->epoll_upgrade_fd, | ||
3230 | EPOLL_CTL_ADD, | ||
3231 | fd, | ||
3232 | &event)) | ||
3233 | { | ||
3234 | MHD_socket myfd; | ||
3235 | |||
3236 | /* Handle error by closing OUR socket; with some | ||
3237 | luck, this should tricker the application to fail | ||
3238 | to read, and then the application should close | ||
3239 | the connection completely. */ | ||
3240 | |||
3241 | /* epoll documentation suggests that closing a FD | ||
3242 | automatically removes it from the epoll set; | ||
3243 | however, this is not true as if we fail to do | ||
3244 | manually remove it, we are still seeing an event | ||
3245 | for this fd in epoll, causing grief | ||
3246 | (use-after-free...) --- at least on my system. */ | ||
3247 | myfd = urh->mhd.socket; | ||
3248 | if ( (fd != myfd) && | ||
3249 | (0 != epoll_ctl (daemon->epoll_upgrade_fd, | ||
3250 | EPOLL_CTL_DEL, | ||
3251 | urh->mhd.socket, | ||
3252 | NULL)) ) | ||
3253 | MHD_PANIC ("Failed to remove FD from epoll set\n"); | ||
3254 | |||
3255 | urh->mhd.socket = MHD_INVALID_SOCKET; | ||
3256 | MHD_socket_close_ (myfd); | ||
3257 | continue; | ||
3258 | } | ||
3259 | } | ||
3260 | } | 3185 | } |
3261 | } | 3186 | } |
3262 | return MHD_YES; | 3187 | return MHD_YES; |
@@ -3399,7 +3324,6 @@ MHD_epoll (struct MHD_Daemon *daemon, | |||
3399 | { | 3324 | { |
3400 | /* activity on an upgraded connection, we process | 3325 | /* activity on an upgraded connection, we process |
3401 | those in a separate epoll() */ | 3326 | those in a separate epoll() */ |
3402 | daemon->upgrade_fd_in_epoll = MHD_NO; | ||
3403 | run_epoll_for_upgrade (daemon); | 3327 | run_epoll_for_upgrade (daemon); |
3404 | continue; | 3328 | continue; |
3405 | } | 3329 | } |
@@ -4977,6 +4901,15 @@ thread_failed: | |||
4977 | /* clean up basic memory state in 'daemon' and return NULL to | 4901 | /* clean up basic memory state in 'daemon' and return NULL to |
4978 | indicate failure */ | 4902 | indicate failure */ |
4979 | #ifdef EPOLL_SUPPORT | 4903 | #ifdef EPOLL_SUPPORT |
4904 | if (MHD_YES == daemon->upgrade_fd_in_epoll) | ||
4905 | { | ||
4906 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
4907 | EPOLL_CTL_DEL, | ||
4908 | daemon->epoll_upgrade_fd, | ||
4909 | NULL)) | ||
4910 | MHD_PANIC ("Failed to remove FD from epoll set\n"); | ||
4911 | daemon->upgrade_fd_in_epoll = MHD_NO; | ||
4912 | } | ||
4980 | if (-1 != daemon->epoll_fd) | 4913 | if (-1 != daemon->epoll_fd) |
4981 | close (daemon->epoll_fd); | 4914 | close (daemon->epoll_fd); |
4982 | #if HTTPS_SUPPORT | 4915 | #if HTTPS_SUPPORT |