1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-21 23:19:03 +00:00

Change EV_EXCEPT handling.

Original patch by Henri Doreau: http://seclists.org/nmap-dev/2017/q1/252
This commit is contained in:
dmiller
2017-06-19 22:58:23 +00:00
parent cb17b788b3
commit 2065d752bb
4 changed files with 38 additions and 33 deletions

View File

@@ -74,12 +74,12 @@
#define EPOLL_R_FLAGS (EPOLLIN | EPOLLPRI)
#define EPOLL_W_FLAGS EPOLLOUT
#ifdef EPOLLRDHUP
#define EPOLL_X_FLAGS (EPOLLERR | EPOLLRDHUP| EPOLLHUP)
#else
/* EPOLLRDHUP was introduced later and might be unavailable on older systems. */
#define EPOLL_X_FLAGS (EPOLLERR | EPOLLHUP)
#endif /* EPOLLRDHUP */
/* EPOLLRDHUP was introduced later and might be unavailable on older systems. */
#ifndef EPOLLRDHUP
#define EPOLLRDHUP 0
#endif
#define EPOLL_X_FLAGS (EPOLLERR | EPOLLRDHUP| EPOLLHUP)
/* --- ENGINE INTERFACE PROTOTYPES --- */
@@ -178,8 +178,6 @@ int epoll_iod_register(struct npool *nsp, struct niod *iod, struct nevent *nse,
epev.events |= EPOLL_R_FLAGS;
if (ev & EV_WRITE)
epev.events |= EPOLL_W_FLAGS;
if (ev & EV_EXCEPT)
epev.events |= EPOLL_X_FLAGS;
sd = nsock_iod_get_sd(iod);
if (epoll_ctl(einfo->epfd, EPOLL_CTL_ADD, sd, &epev) < 0)
@@ -233,8 +231,6 @@ int epoll_iod_modify(struct npool *nsp, struct niod *iod, struct nevent *nse, in
epev.events |= EPOLL_R_FLAGS;
if (iod->watched_events & EV_WRITE)
epev.events |= EPOLL_W_FLAGS;
if (iod->watched_events & EV_EXCEPT)
epev.events |= EPOLL_X_FLAGS;
sd = nsock_iod_get_sd(iod);
@@ -328,7 +324,7 @@ static inline int get_evmask(struct epoll_engine_info *einfo, int n) {
if (einfo->events[n].events & EPOLL_W_FLAGS)
evmask |= EV_WRITE;
if (einfo->events[n].events & EPOLL_X_FLAGS)
evmask |= (EV_READ | EV_WRITE | EV_EXCEPT);
evmask |= EV_EXCEPT;
return evmask;
}

View File

@@ -294,10 +294,6 @@ int poll_iod_modify(struct npool *nsp, struct niod *iod, struct nevent *nse, int
pinfo->events[sd].events |= POLL_R_FLAGS;
if (iod->watched_events & EV_WRITE)
pinfo->events[sd].events |= POLL_W_FLAGS;
#ifndef WIN32
if (iod->watched_events & EV_EXCEPT)
pinfo->events[sd].events |= POLL_X_FLAGS;
#endif
return 1;
}
@@ -403,7 +399,7 @@ static inline int get_evmask(struct npool *nsp, struct niod *nsi) {
if (pev->revents & POLL_W_FLAGS)
evmask |= EV_WRITE;
if (pev->events && (pev->revents & POLL_X_FLAGS))
evmask |= (EV_READ | EV_WRITE | EV_EXCEPT);
evmask |= EV_EXCEPT;
}
return evmask;
}

View File

@@ -208,6 +208,9 @@ int select_iod_modify(struct npool *nsp, struct niod *iod, struct nevent *nse, i
iod->watched_events |= ev_set;
iod->watched_events &= ~ev_clr;
ev_set |= EV_EXCEPT;
ev_clr &= ~EV_EXCEPT;
sd = nsock_iod_get_sd(iod);
/* -- set events -- */
@@ -233,7 +236,7 @@ int select_iod_modify(struct npool *nsp, struct niod *iod, struct nevent *nse, i
/* -- update max_sd -- */
if (ev_set != EV_NONE)
sinfo->max_sd = MAX(sinfo->max_sd,sd);
sinfo->max_sd = MAX(sinfo->max_sd, sd);
else if (ev_clr != EV_NONE && iod->events_pending == 1 && (sinfo->max_sd == sd))
sinfo->max_sd--;

View File

@@ -168,6 +168,18 @@ static int socket_count_dec_ssl_desire(struct nevent *nse) {
}
#endif
static int should_clear_ev_read(const struct niod *iod, int ev_set) {
return (ev_set & EV_READ) &&
#if HAVE_PCAP
!iod->readpcapsd_count &&
#endif
!iod->readsd_count;
}
static int should_clear_ev_write(const struct niod *iod, int ev_set) {
return (ev_set & EV_WRITE) && !iod->writesd_count;
}
/* Update the events that the IO engine should watch for a given IOD.
*
* ev_inc is a set of events for which the event counters should be increased.
@@ -188,18 +200,18 @@ static void update_events(struct niod * iod, struct npool *ms, struct nevent *ns
setmask = ev_inc;
clrmask = EV_NONE;
if ((ev_dec & EV_READ) &&
#if HAVE_PCAP
!iod->readpcapsd_count &&
#endif
!iod->readsd_count)
if (should_clear_ev_read(iod, ev_dec))
clrmask |= EV_READ;
if ((ev_dec & EV_WRITE) && !iod->writesd_count)
if (should_clear_ev_write(iod, ev_dec))
clrmask |= EV_WRITE;
/* EV_EXCEPT is systematically set and cannot be removed */
if (ev_inc & EV_EXCEPT)
nsock_log_info("Invalid event set, no need to specify EV_EXCEPT");
if (ev_dec & EV_EXCEPT)
clrmask |= EV_EXCEPT;
nsock_log_info("Invalid event set, refusing to clear EV_EXCEPT");
if (!IOD_PROPGET(iod, IOD_REGISTERED)) {
assert(clrmask == EV_NONE);
@@ -399,7 +411,6 @@ void handle_connect_result(struct npool *ms, struct nevent *nse, enum nse_status
ev |= socket_count_read_dec(iod);
ev |= socket_count_write_dec(iod);
ev |= EV_EXCEPT;
update_events(iod, ms, nse, EV_NONE, ev);
}
@@ -924,7 +935,9 @@ enum nsock_loopstatus nsock_loop(nsock_pool nsp, int msec_timeout) {
}
void process_event(struct npool *nsp, gh_list_t *evlist, struct nevent *nse, int ev) {
int match_r = 0, match_w = 0;
int match_r = ev & EV_READ;
int match_w = ev & EV_WRITE;
int match_x = ev & EV_EXCEPT;
#if HAVE_OPENSSL
int desire_r = 0, desire_w = 0;
#endif
@@ -945,8 +958,6 @@ void process_event(struct npool *nsp, gh_list_t *evlist, struct nevent *nse, int
break;
case NSE_TYPE_READ:
match_r = ev & EV_READ;
match_w = ev & EV_WRITE;
#if HAVE_OPENSSL
desire_r = nse->sslinfo.ssl_desire == SSL_ERROR_WANT_READ;
desire_w = nse->sslinfo.ssl_desire == SSL_ERROR_WANT_WRITE;
@@ -954,16 +965,15 @@ void process_event(struct npool *nsp, gh_list_t *evlist, struct nevent *nse, int
handle_read_result(nsp, nse, NSE_STATUS_SUCCESS);
else
#endif
if (!nse->iod->ssl && match_r)
if ((!nse->iod->ssl && match_r) || match_x)
handle_read_result(nsp, nse, NSE_STATUS_SUCCESS);
if (event_timedout(nse))
handle_read_result(nsp, nse, NSE_STATUS_TIMEOUT);
break;
case NSE_TYPE_WRITE:
match_r = ev & EV_READ;
match_w = ev & EV_WRITE;
#if HAVE_OPENSSL
desire_r = nse->sslinfo.ssl_desire == SSL_ERROR_WANT_READ;
desire_w = nse->sslinfo.ssl_desire == SSL_ERROR_WANT_WRITE;
@@ -971,7 +981,7 @@ void process_event(struct npool *nsp, gh_list_t *evlist, struct nevent *nse, int
handle_write_result(nsp, nse, NSE_STATUS_SUCCESS);
else
#endif
if (!nse->iod->ssl && match_w)
if ((!nse->iod->ssl && match_w) || match_x)
handle_write_result(nsp, nse, NSE_STATUS_SUCCESS);
if (event_timedout(nse))
@@ -1236,7 +1246,7 @@ void nsock_pool_add_event(struct npool *nsp, struct nevent *nse) {
assert(nse->iod->sd >= 0);
socket_count_read_inc(nse->iod);
socket_count_write_inc(nse->iod);
update_events(nse->iod, nsp, nse, EV_READ|EV_WRITE|EV_EXCEPT, EV_NONE);
update_events(nse->iod, nsp, nse, EV_READ|EV_WRITE, EV_NONE);
}
iod_add_event(nse->iod, nse);
break;