On Tue, Mar 10, 2009 at 8:02 PM, Guy Harris <g...@alum.mit.edu> wrote: > > On Mar 10, 2009, at 9:52 AM, Chris Morgan wrote: > >> Does mac osx have epoll? > > No. It has poll(), but that, as noted, doesn't work with character special > files, such as the BPF devices used for traffic capture in OS X. (BPF > devices *do* work with poll() in *BSD.) >
Hmm. Yeah I'll make sure to put in a comment about mac os support. >> You mentioned that Linux doesn't support a timeout, I see that the >> call used by libpcap is a recvmsg() call. Does Windows have a timeout >> on the packet read > > Yes. It's similar to the BPF timeout, in that the timer starts when the > read is done (rather than when the first packet arrives, as is the case on > Solaris). > Cool. That should mean that we don't need to we don't need to do anything special on Windows. >> Because we pass each packet off as we receive it we don't buffer >> internal to SharpPcap. I thought that for performance reasons >> Wireshark would group packets together and upon reaching a high water >> mark or exceeding some interval, that the group of packets would be >> passed somewhere. Maybe I'm not understanding your initial comments >> about buffering but not holding onto packets forever if the buffer >> never fills up. > > For performance reasons, some in-kernel packet capture mechanisms, such as: > > BPF, as used in *BSD and Mac OS X > > the bufmod STREAMS module in Solaris (which is one component of the > mechanism); > > the packetfilter mechanism in Tru64 UNIX; > > the WinPcap kernel code; > > will *NOT* return from a read as soon as the first packet arrives; they > will, instead, try to accumulate multiple packets and hand all of them up in > a single read. > > Obviously, if you get one packet an hour, you don't want to have the > application wait several hours until enough packets have been accumulated, > so those mechanisms also include a timer, so that, after enough time > expires, the read will return even if a bufferful of packets hasn't been > accumulated. > > This isn't done by Wireshark, or, rather, by dumpcap - and it isn't done by > tcpdump, or any other such application, either. > > It's not even done by libpcap; the applications just call pcap_open_live(), > passing it a timeout value, and pcap_open_live() passes that timeout value > to the kernel packet capture mechanism, if it supports a timeout. > > In BPF and WinPcap, and, I think, in packetfilter, the timer starts when the > read starts, and the read will return after the timer expires even if *no* > packets have been accumulated. > > In Solaris, the timer starts - and is reset - whenever a packet arrives, so > the read won't return until at least one packet has been accumulated. > > On those platforms, the buffering will be done regardless of what SharpPcap > does, as it's not something that the caller of libpcap/WinPcap does - it's > done by the kernel-mode code that libpcap and the WinPcap user-mode code > use. > 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. How does it work if there is no timeout and packets get captured but not enough for the callback to occur? >> Is there some reason not to implement pcap_breakloop() such that it >> will send a signal to wake up the pcap_dispatch() thread? > > Well, one reason not to do that might be that there *isn't* necessarily a > separate thread doing pcap_dispatch() or pcap_loop() or.... > >> I suppose >> that opens a huge can of worms since now you are dealing with cross >> platform thread synchronization issues. > > Yes. The code would be significantly different between UN*X and Windows. > > If there were a pcap_breakloop_thread() operation, which would take a pcap_t > * and a thread, the UN*X version could use pthread_kill() to send a signal > to the thread and the Windows version could use QueueUserAPC() to queue an > APC for the thread. > > That would require that WinPcap use a WaitFor...Ex() call; I'd have to see > whether it already uses a WaitFor...() call or not. > Ahh. Considering the delay in adding such a feature and getting a release out etc it seems simpler to just handle the issue at the application level. >> Alternatively why not use poll() or select() inside of pcap_dispatch() >> to avoid performing the read if there is no pending data? > > Because, in many cases, you don't *want* to avoid performing the read if > there's no pending data - you want to wait for data. That's what tcpdump > does, and what the program Wireshark and TShark run to do captures (dumpcap) > does. > Wouldn't using poll if the timeout was set and not if it wasn't solve that problem? >> 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(). 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 was trying to use this functionality to have the read abort and return to the caller. I'll just use poll() under linux to avoid the read if there are no packets available. That will let us avoid using signals and keep cpu usage low by reducing the idle call rate to once a second or something. Chris - This is the tcpdump-workers list. Visit https://cod.sandelman.ca/ to unsubscribe.