diff --git a/CHANGELOG b/CHANGELOG index d0b1d8f95..7567305c4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -22,7 +22,8 @@ o [NSE] Added tls-nextprotoneg script which enumerates a TLS server's supported o [NSOCK] Fixed an epoll-engine-specific bug. The engine didn't recognized FDs that were internally closed and replaced by other ones. This happened during - reconnect attempts. [Henri Doreau] + reconnect attempts. Also, the IOD flags were not properly cleared. + [Henri Doreau, Daniel Miller] o Added support for log type bitmasks in log_vwrite(). Also replaced a fatal() statement by an assert(0) to get rid of a possible infinite call loop when diff --git a/nsock/src/engine_epoll.c b/nsock/src/engine_epoll.c index d8b2f3bdf..eb62d19f9 100644 --- a/nsock/src/engine_epoll.c +++ b/nsock/src/engine_epoll.c @@ -207,6 +207,7 @@ int epoll_iod_modify(mspool *nsp, msiod *iod, int ev_set, int ev_clr) { struct epoll_engine_info *einfo = (struct epoll_engine_info *)nsp->engine_data; assert((ev_set & ev_clr) == 0); + assert(IOD_PROPGET(iod, IOD_REGISTERED)); memset(&epev, 0x00, sizeof(struct epoll_event)); epev.events = EPOLLET; @@ -230,16 +231,10 @@ int epoll_iod_modify(mspool *nsp, msiod *iod, int ev_set, int ev_clr) { epev.events |= EPOLL_X_FLAGS; sd = nsi_getsd(iod); - if (epoll_ctl(einfo->epfd, EPOLL_CTL_MOD, sd, &epev) < 0) { - if (errno == ENOENT) { - /* This IOD is registered but its associated fd is not in the epoll set. - * It was probably closed and another one was open (e.g.: reconnect operation). - * We therefore want to add the new one. */ - epoll_ctl(einfo->epfd, EPOLL_CTL_ADD, sd, &epev); - } else { - fatal("Unable to update events for IOD #%lu: %s", iod->id, strerror(errno)); - } - } + + if (epoll_ctl(einfo->epfd, EPOLL_CTL_MOD, sd, &epev) < 0) + fatal("Unable to update events for IOD #%lu: %s", iod->id, strerror(errno)); + return 1; } diff --git a/nsock/src/engine_select.c b/nsock/src/engine_select.c index c222a7ad8..a11f471aa 100644 --- a/nsock/src/engine_select.c +++ b/nsock/src/engine_select.c @@ -208,8 +208,10 @@ int select_iod_unregister(mspool *nsp, msiod *iod) { { CHECKED_FD_CLR(iod->sd, &sinfo->fds_master_r); CHECKED_FD_CLR(iod->sd, &sinfo->fds_master_w); + CHECKED_FD_CLR(iod->sd, &sinfo->fds_master_x); CHECKED_FD_CLR(iod->sd, &sinfo->fds_results_r); CHECKED_FD_CLR(iod->sd, &sinfo->fds_results_w); + CHECKED_FD_CLR(iod->sd, &sinfo->fds_results_x); } if (sinfo->max_sd == iod->sd) diff --git a/nsock/src/nsock_core.c b/nsock/src/nsock_core.c index 1ca1c8450..97b913b34 100644 --- a/nsock/src/nsock_core.c +++ b/nsock/src/nsock_core.c @@ -462,6 +462,8 @@ void handle_connect_result(mspool *ms, msevent *nse, enum nse_status status) { socket_count_write_inc(iod); update_events(iod, ms, EV_WRITE, EV_NONE); } else if (!(options & SSL_OP_NO_SSLv2)) { + int saved_ev; + /* SSLv3-only and TLSv1-only servers can't be connected to when the * SSL_OP_NO_SSLv2 option is not set, which is the case when the pool * was initialized with nsp_ssl_init_max_speed. Try reconnecting with @@ -469,8 +471,13 @@ void handle_connect_result(mspool *ms, msevent *nse, enum nse_status status) { * might use SSLv2. */ if (ms->tracelevel > 0) nsock_trace(ms, "EID %li reconnecting with SSL_OP_NO_SSLv2", nse->id); + + saved_ev = iod->watched_events; + ms->engine->iod_unregister(ms, iod); close(iod->sd); nsock_connect_internal(ms, nse, iod->lastproto, &iod->peer, iod->peerlen, nsi_peerport(iod)); + ms->engine->iod_register(ms, iod, saved_ev); + SSL_clear(iod->ssl); if(!SSL_clear(iod->ssl)) fatal("SSL_clear failed: %s", ERR_error_string(ERR_get_error(), NULL)); diff --git a/nsock/src/nsock_iod.c b/nsock/src/nsock_iod.c index 6b9f3b5b7..d8e34ace6 100644 --- a/nsock/src/nsock_iod.c +++ b/nsock/src/nsock_iod.c @@ -121,6 +121,8 @@ nsock_iod nsi_new2(nsock_pool nsockp, int sd, void *userdata) { nsi->userdata = userdata; nsi->nsp = (mspool *)nsockp; + nsi->_flags = 0; + nsi->read_count = 0; nsi->write_count = 0;