mirror of
https://github.com/nmap/nmap.git
synced 2025-12-19 22:19:02 +00:00
Don't try to do FD_ISSET on a nonselectable pcap descriptor.
The Nsock select engine stores readiness information in a mask instead of doing an FD_ISSET against the descriptor every time. This is a good idea, but it removed a special case in the pre-engines code: in case PCAP_CAN_DO_SELECT is not defined, we can't do FD_ISSET on the descriptor because it is -1. Here we check for that occurrence and set EV_READ in the mask so that a non-blocking pcap read can happen every iteration.
This commit is contained in:
@@ -349,25 +349,22 @@ int select_loop(mspool *nsp, int msec_timeout) {
|
|||||||
|
|
||||||
/* ---- INTERNAL FUNCTIONS ---- */
|
/* ---- INTERNAL FUNCTIONS ---- */
|
||||||
|
|
||||||
/* Iterate through all the event lists (such as connect_events, read_events,
|
static int get_evmask(const mspool *nsp, const msiod *nsi) {
|
||||||
* timer_events, etc) and take action for those that have completed (due to
|
|
||||||
* timeout, i/o, etc) */
|
|
||||||
void iterate_through_event_lists(mspool *nsp) {
|
|
||||||
gh_list_elem *current, *next, *last, *timer_last;
|
|
||||||
struct select_engine_info *sinfo = (struct select_engine_info *)nsp->engine_data;
|
struct select_engine_info *sinfo = (struct select_engine_info *)nsp->engine_data;
|
||||||
|
int sd, evmask;
|
||||||
|
|
||||||
/* Clear it -- We will find the next event as we go through the list */
|
evmask = EV_NONE;
|
||||||
nsp->next_ev.tv_sec = 0;
|
|
||||||
|
|
||||||
last = GH_LIST_LAST_ELEM(&nsp->active_iods);
|
#if HAVE_PCAP
|
||||||
timer_last = GH_LIST_LAST_ELEM(&nsp->timer_events);
|
#ifndef PCAP_CAN_DO_SELECT
|
||||||
|
if (nsi->pcap) {
|
||||||
for (current = GH_LIST_FIRST_ELEM(&nsp->active_iods);
|
/* Always assume readable for a non-blocking read. We can't check FD_ISSET
|
||||||
current != NULL && GH_LIST_ELEM_PREV(current) != last; current = next) {
|
because we don't have a pcap_desc. */
|
||||||
msiod *nsi = (msiod *)GH_LIST_ELEM_DATA(current);
|
evmask |= EV_READ;
|
||||||
|
return evmask;
|
||||||
if (nsi->state != NSIOD_STATE_DELETED && nsi->events_pending) {
|
}
|
||||||
int sd, evmask = EV_NONE;
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if HAVE_PCAP
|
#if HAVE_PCAP
|
||||||
if (nsi->pcap)
|
if (nsi->pcap)
|
||||||
@@ -385,9 +382,28 @@ void iterate_through_event_lists(mspool *nsp) {
|
|||||||
if (FD_ISSET(sd, &sinfo->fds_results_x))
|
if (FD_ISSET(sd, &sinfo->fds_results_x))
|
||||||
evmask |= EV_EXCEPT;
|
evmask |= EV_EXCEPT;
|
||||||
|
|
||||||
process_iod_events(nsp, nsi, evmask);
|
return evmask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Iterate through all the event lists (such as connect_events, read_events,
|
||||||
|
* timer_events, etc) and take action for those that have completed (due to
|
||||||
|
* timeout, i/o, etc) */
|
||||||
|
void iterate_through_event_lists(mspool *nsp) {
|
||||||
|
gh_list_elem *current, *next, *last, *timer_last;
|
||||||
|
|
||||||
|
/* Clear it -- We will find the next event as we go through the list */
|
||||||
|
nsp->next_ev.tv_sec = 0;
|
||||||
|
|
||||||
|
last = GH_LIST_LAST_ELEM(&nsp->active_iods);
|
||||||
|
timer_last = GH_LIST_LAST_ELEM(&nsp->timer_events);
|
||||||
|
|
||||||
|
for (current = GH_LIST_FIRST_ELEM(&nsp->active_iods);
|
||||||
|
current != NULL && GH_LIST_ELEM_PREV(current) != last; current = next) {
|
||||||
|
msiod *nsi = (msiod *)GH_LIST_ELEM_DATA(current);
|
||||||
|
|
||||||
|
if (nsi->state != NSIOD_STATE_DELETED && nsi->events_pending)
|
||||||
|
process_iod_events(nsp, nsi, get_evmask(nsp, nsi));
|
||||||
|
|
||||||
next = GH_LIST_ELEM_NEXT(current);
|
next = GH_LIST_ELEM_NEXT(current);
|
||||||
if (nsi->state == NSIOD_STATE_DELETED) {
|
if (nsi->state == NSIOD_STATE_DELETED) {
|
||||||
gh_list_remove_elem(&nsp->active_iods, current);
|
gh_list_remove_elem(&nsp->active_iods, current);
|
||||||
|
|||||||
@@ -982,10 +982,7 @@ void process_event(mspool *nsp, gh_list *evlist, msevent *nse, int ev) {
|
|||||||
if (nsp->tracelevel > 5)
|
if (nsp->tracelevel > 5)
|
||||||
nsock_trace(nsp, "PCAP iterating %lu", nse->id);
|
nsock_trace(nsp, "PCAP iterating %lu", nse->id);
|
||||||
|
|
||||||
#if PCAP_CAN_DO_SELECT
|
if (ev & EV_READ) {
|
||||||
if (ev & EV_READ)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
/* buffer empty? check it! */
|
/* buffer empty? check it! */
|
||||||
if (FILESPACE_LENGTH(&(nse->iobuf)) == 0)
|
if (FILESPACE_LENGTH(&(nse->iobuf)) == 0)
|
||||||
do_actual_pcap_read(nse);
|
do_actual_pcap_read(nse);
|
||||||
|
|||||||
Reference in New Issue
Block a user