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.

Reply via email to