tcpdump mailing list archives
Re: pcap_read_linux_mmap is always blocking
From: Dragos Ilie <dragos.ilie () gmail com>
Date: Mon, 06 Jul 2009 20:08:31 +0200
Guy Harris wrote:
On Jul 6, 2009, at 9:39 AM, Dragos Ilie wrote:I traced the issue to pcap-linux.c:pcap_read_linux_mmap(), which is the read handler selected when HAVE_PACKET_RING is defined. The handler calls poll() with a negative value, which means an infinite timeout. This occurs when the libpcap variable md.timeout is equal to zero (default value). If the caller specifies a positive md.timeout then pcap_setnonblock_mmap() re-computes the timeout as shown below: p->md.timeout = p->md.timeout*-1 - 1; When the user-specified timeout is negative the expression above becomes: p->md.timeout = (p->md.timeout+1)*-1;The user-specified timeout isn't supposed to be negative; the behavior when that is done has never been specified. If your application is setting the timeout to a negative value, it should stop doing so. Internally, libpcap uses a negative timeout value in the pcap_t data structure to indicate non-blocking mode; if it's negative, poll() isn't called. If, when pcap_setnonblock() is called, the p->md.timeout is: zero, p->md.timeout becomes -1; 1 through INT_MAX, p->md.timeout becomes -2 through -INT_MAX-1; and that should be negative in all cases, so poll() shouldn't be called. - This is the tcpdump-workers list. Visit https://cod.sandelman.ca/ to unsubscribe.
My application is not setting the timeout. This corresponds to the case where p->md.timeout == 0. The function pcap_setnonblock_mmap first checks the nonblock flag and if it is set *and* if p->md.timeout > 0 it maps the value to p->md.timeout*-1 - 1 ... static int pcap_setnonblock_mmap(pcap_t *p, int nonblock, char *errbuf) { /* map each value to the corresponding 2's complement, to * preserve the timeout value provided with pcap_set_timeout */ if (nonblock) { if (p->md.timeout > 0) p->md.timeout = p->md.timeout*-1 - 1; } else ... pcap_read_linux_mmap calls poll() unconditionally: ret = poll(&pollinfo, 1, (handle->md.timeout > 0)? handle->md.timeout: -1); If md.timeout==0 (which is my case) the result is that the poll-timeout is set to -1 (infinite). Am I missing something? On a related note, if HAVE_PACKET_RING is not defined I get non-blocking behavior, without any changes to my application. - This is the tcpdump-workers list. Visit https://cod.sandelman.ca/ to unsubscribe.
Current thread:
- pcap_read_linux_mmap is always blocking Dragos Ilie (Jul 06)
- Re: pcap_read_linux_mmap is always blocking Guy Harris (Jul 06)
- Re: pcap_read_linux_mmap is always blocking Dragos Ilie (Jul 06)
- Re: pcap_read_linux_mmap is always blocking Guy Harris (Jul 06)
- Re: pcap_read_linux_mmap is always blocking Dragos Ilie (Jul 06)
- Re: pcap_read_linux_mmap is always blocking Guy Harris (Jul 06)