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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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--;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user