Wireshark-dev: Re: [Wireshark-dev] Triggers
From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Thu, 10 Apr 2008 14:47:32 -0700
Gianluca Varenni wrote:

It works (even with AirPcap adapters), with a caveat. The handle doesn't get signalled immediately. It gets signalled when at least mintocopy bytes have been stored in the WinPcap kernel buffer. By default mintocopy is 16k, so if you receive less than 16k packets, the event never gets signalled. You can use WaitForSingleObject/WaitForMultipleObjects, *but* you need to use a timeout to avoid a deadlock if less than mintocopy bytes are received.

Wow, it's BSD-compatible! :-)

(That's the equivalent of the bug that various BSDs have, wherein a select() wakeup doesn't occur until the BPF store buffer fills up, regardless of the timeout. The workaround is similar - add a timeout to the select(), and make sure the BPF device is in non-blocking mode, so that if the timeout expires and there are *no* packets available, you won't block forever.

The fix is to, in the BPF code, catch attempts to select() or poll() on the descriptor, and start a timer when that happens, and when that timer expires, indicate that the descriptor is readable. I don't know whether that can be done in Windows, as I don't know whether a device can have a "call me when somebody does a 'wait for' on a handle for me" routine.

Now, if the way the timeout worked was that it caused a read to finish if more than the specified amount of time elapsed *between packets*, this wouldn't be an issue; the code would do a wakeup if either the buffer fills up or it's been too long since the last packet arrived.

That would also have two other advantages:

1) it arguably does what's *really* wanted here, which is to do batching of packets when they're arriving at a high rate without waiting too long - or forever - if they're arriving at a slow rate; a fairly short timeout might work, as the timer doesn't start until a packet arrives, and it resets on each packet, and a short timeout means you don't have a high latency when packets are arriving slowly.

2) it means that people wouldn't have gotten confused and thought that the libpcap timeout somehow guaranteed that a pcap_dispatch() call would return after a given period of time, even if no packets were processed.

Solaris's timer in bpfmod doesn't start until at least one packet arrives, but it doesn't get reset on each packet.