On Tue, Mar 10, 2009 at 9:01 PM, Guy Harris <g...@alum.mit.edu> wrote: > > On Mar 10, 2009, at 5:40 PM, Chris Morgan wrote: > >> Hmm. Yeah I'll make sure to put in a comment about mac os support. > > Note that select() *does* work with BPF devices on OS X - modulo the > traditional BPF bug wherein the timer starts when a read is done, *not* when > a select() is done, so you *could* block forever. At this point I think all > the *BSDs have fixed that in their BPF implementations, but OS X hasn't > fixed it yet. >
Yeah, I've heard that OS X has a lot of bugs that are reported but not fixed so it doesn't surprise me. > (If BPF had done Solaris-style timeouts, where the timer is an inter-packet > timer, this wouldn't have been an issue in the first place. It might also > mean that the timer would have done a better job of batching packets if > they're arriving fast and delivering them when there's a pause.) > >> Right. I was thinking that there might be cases where if the timeout >> wasn't supported you would end up with the os buffering packets and >> never returning them to the caller. > > No. If the timeout isn't supported, the OS doesn't buffer any packets - it > delivers them immediately, even if that means that a burst of packets is > delivered one packet at a time, with a trip to the kernel done for each > packet. > Ahh. That makes sense. >> How does it work if there is no timeout and packets get captured but >> not enough for the callback to occur? > > If there's no timeout, that's because there's no in-kernel buffering to > require a timeout, so "enough for the callout to occur" is one packet. > >> Wouldn't using poll if the timeout was set and not if it wasn't solve >> that problem? > > No, because tcpdump and dumpcap *do* want a timeout, because they don't want > to, for example, block for several hours if you only get one packet an hour. > They don't care whether the read blocks forever waiting for the *first* > packet to arrive, they just don't want it to block forever waiting for a > bufferful of packets to arrive. > Right. >> >> >> >> >>>> Wouldn't >>>> that let you implement the timeout functionality >>> >>> To what timeout functionality are you referring? A timeout that prevents >>> reads from blocking forever even if no packets arrive is, as noted, not >>> something that all applications need or want - that's *NOT* what the >>> timeout >>> specified in pcap_open_live() is intended to do, and not what it was ever >>> guaranteed to do - and a timeout that just prevents packets from being >>> buffered indefinitely if they're not arriving fast enough is *already* >>> implemented. >>> - >> >> Right, I'm referring to the to_ms timeout in pcap_open_live(). > > That timeout is, at least on Solaris, "a timeout that just prevents packets > from being buffered indefinitely if they're not arriving fast enough." On > some other OSes, it also happens to prevent reads from blocking forever if > no packets arrive, but applications should not be depending on that unless > they also call uname() and abort if the OS name string is "SunOS", so that > they ensure that they never run on Solaris. > >> I see >> what you mean, the man page certainly disclaims support for the >> timeout on all platforms. The documentation on to_ms does sound like >> exactly what I'm trying to do though, cause the read to timeout. > > I tried as hard as I could to write the documentation *NOT* to sound like > that. The problem is that I didn't mention that until the description of > pcap_dispatch(): > > NOTE: when reading a live capture, pcap_dispatch() will not > necessarily > return when the read times out; on some platforms, the read > timeout > isn't supported, and, on other platforms, the timer doesn't start > until > at least one packet arrives. This means that the read timeout > should > NOT be used in, for example, an interactive application, to allow > the > packet capture loop to ``poll'' for user input periodically, as > there's > no guarantee that pcap_dispatch() will return after the > timeout > expires. > > In libpcap 1.x, the pcap man page discusses the timeout in some detail, and > does explicitly note that it's *NOT* guaranteed to keep reads from blocking > forever: > > read timeout > If, when capturing, packets are delivered as soon as > they > arrive, the application capturing the packets will be woken > up > for each packet as it arrives, and might have to make one > or > more calls to the operating system to fetch each packet. > > If, instead, packets are not delivered as soon as they > arrive, > but are delivered after a short delay (called a "read > timeout"), > more than one packet can be accumulated before the packets > are > delivered, so that a single wakeup would be done for > multiple > packets, and each set of calls made to the operating > system > would supply multiple packets, rather than a single > packet. > This reduces the per-packet CPU overhead if packets are > arriving > at a high rate, increasing the number of packets per second > that > can be captured. > > The read timeout is required so that an application won't > wait > for the operating system's capture buffer to fill up > before > packets are delivered; if packets are arriving slowly, that > wait > could take an arbitrarily long period of time. > > Not all platforms support a read timeout; on platforms > that > don't, the read timeout is ignored. A zero value for the > time- > out, on platforms that support a read timeout, will cause a > read > to wait forever to allow enough packets to arrive, with no > time- > out. > > NOTE: the read timeout cannot be used to cause calls that > read > packets to return within a limited period of time, because, > on > some platforms, the read timeout isn't supported, and, on > other > platforms, the timer doesn't start until at least one > packet > arrives. This means that the read timeout should NOT be > used, > for example, in an interactive application to allow the > packet > capture loop to ``poll'' for user input periodically, as > there's > no guarantee that a call reading packets will return after > the > timeout expires even if no packets have arrived. > > The read timeout is set with pcap_set_timeout(). > > and the man pages for the individual routines just refer to the read timeout > without giving details. The man page might be clearer if the timeout was referred to as a 'buffered packet timeout' to indicate that the timeout refers to the time holding already read packets vs. the read operation. In any case I understood the behavior but was trying to suggest a change that suited my use but that I didn't believe conflicted with the documentation. I appreciate the information and I think I'm all set now. I'll use poll() or epoll() or signals under Linux, and if necessary the Windows equivalent with winpcap. Chris - This is the tcpdump-workers list. Visit https://cod.sandelman.ca/ to unsubscribe.