1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-11 18:29:03 +00:00

Do a non-blocking check for events when pcap data is available

For platforms without selectable pcap handles (e.g. Windows), the
arrival of data for a pcap read would previously skip checking for any
triggered non-pcap events in that loop iteration. This is not usually a
problem because the next loop will be triggered immediately, picking up
the non-pcap events before any further pcap data arrives. However,
excessive pcap data on a handle in immediate mode might prevent the
engine loop from checking for non-pcap events for long enough to result
in timeouts. Instead, do a non-blocking check for triggered events in
this case and handle those in the same loop iteration.
This commit is contained in:
dmiller
2024-10-09 17:40:10 +00:00
parent 167fafe65c
commit 532938f49c
5 changed files with 63 additions and 64 deletions

View File

@@ -261,6 +261,17 @@ int kqueue_loop(struct npool *nsp, int msec_timeout) {
* timeout) */
combined_msecs = MIN((unsigned)event_msecs, (unsigned)msec_timeout);
#if HAVE_PCAP
#ifndef PCAP_CAN_DO_SELECT
/* do non-blocking read on pcap devices that doesn't support select()
* If there is anything read, just leave this loop. */
if (pcap_read_on_nonselect(nsp)) {
/* okay, something was read. */
// Make the kevent call non-blocking
combined_msecs = 0;
}
#endif
#endif
/* Set up the timeval pointer we will give to kevent() */
memset(&ts, 0, sizeof(struct timespec));
if (combined_msecs >= 0) {
@@ -271,20 +282,9 @@ int kqueue_loop(struct npool *nsp, int msec_timeout) {
ts_p = NULL;
}
#if HAVE_PCAP
#ifndef PCAP_CAN_DO_SELECT
/* do non-blocking read on pcap devices that doesn't support select()
* If there is anything read, just leave this loop. */
if (pcap_read_on_nonselect(nsp)) {
/* okay, something was read. */
} else
#endif
#endif
{
results_left = kevent(kinfo->kqfd, NULL, 0, kinfo->events, kinfo->evlen, ts_p);
if (results_left == -1)
sock_err = socket_errno();
}
results_left = kevent(kinfo->kqfd, NULL, 0, kinfo->events, kinfo->evlen, ts_p);
if (results_left == -1)
sock_err = socket_errno();
gettimeofday(&nsock_tod, NULL); /* Due to kevent delay */
} while (results_left == -1 && sock_err == EINTR); /* repeat only if signal occurred */