diff options
author | Guy Harris <guy@alum.mit.edu> | 2014-04-15 13:20:14 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2014-04-15 13:20:14 -0700 |
commit | 9e35faaac7436d29b607e5664b73c4676ec326a4 (patch) | |
tree | ad632a6e69a2722d376a0af9b054eb2a10a9272d | |
parent | a2ebd87bf9662e4d7a1685493faa3aa8568bdfa6 (diff) |
Handle a timeout value of 0 better with TPACKET_V3.
If the user specified a timeout value of 0, and we don't have any
packets to return from pcap_read_linux_mmap_v3(), go back and wait for
packets. Yes, this means waiting indefinitely, but that's what the
documentation used to say, and what we're making it say again; if this
is a problem, *don't use a timeout value of 0*.
This should fix GitHub libpcap issue #350.
-rw-r--r-- | pcap-linux.c | 12 | ||||
-rw-r--r-- | pcap.3pcap.in | 8 | ||||
-rw-r--r-- | pcap_set_timeout.3pcap | 3 |
3 files changed, 14 insertions, 9 deletions
diff --git a/pcap-linux.c b/pcap-linux.c index 38df97b5..9ff71ee9 100644 --- a/pcap-linux.c +++ b/pcap-linux.c @@ -4474,6 +4474,7 @@ pcap_read_linux_mmap_v3(pcap_t *handle, int max_packets, pcap_handler callback, int pkts = 0; int ret; +again: if (handlep->current_packet == NULL) { /* wait for frames availability.*/ ret = pcap_wait_for_frames_mmap(handle); @@ -4482,8 +4483,13 @@ pcap_read_linux_mmap_v3(pcap_t *handle, int max_packets, pcap_handler callback, } } h.raw = pcap_get_ring_frame(handle, TP_STATUS_USER); - if (!h.raw) + if (!h.raw) { + if (pkts == 0 && handlep->timeout == 0) { + /* Block until we see a packet. */ + goto again; + } return pkts; + } /* non-positive values of max_packets are used to require all * packets currently available in the ring */ @@ -4564,6 +4570,10 @@ pcap_read_linux_mmap_v3(pcap_t *handle, int max_packets, pcap_handler callback, return PCAP_ERROR_BREAK; } } + if (pkts == 0 && handlep->timeout == 0) { + /* Block until we see a packet. */ + goto again; + } return pkts; } #endif /* HAVE_TPACKET3 */ diff --git a/pcap.3pcap.in b/pcap.3pcap.in index 03afb992..d3c01692 100644 --- a/pcap.3pcap.in +++ b/pcap.3pcap.in @@ -172,11 +172,9 @@ arbitrarily long period of time. .IP Not all platforms support a read timeout; on platforms that don't, the read timeout is ignored. A zero value for the timeout, -on platforms that support a read timeout, has platform-dependent -behavior that could cause a read to wait for an unlimited amount -of time until the capture buffer fills up or could cause a read timeout -of 1 millisecond to be used. We recommend that a value of zero not be -used. +on platforms that support a read timeout, +will cause a read to wait forever to allow enough packets to +arrive, with no timeout. .IP .BR NOTE : the read timeout cannot be used to cause calls that read diff --git a/pcap_set_timeout.3pcap b/pcap_set_timeout.3pcap index fa3b167e..1a0641ee 100644 --- a/pcap_set_timeout.3pcap +++ b/pcap_set_timeout.3pcap @@ -36,9 +36,6 @@ sets the read timeout that will be used on a capture handle when the handle is activated to .IR to_ms , which is in units of milliseconds. -.LP -The behavior, if the timeout isn't specified, is undefined. We -recommend always setting the timeout to a non-zero value. .SH RETURN VALUE .B pcap_set_timeout() returns 0 on success or |