Usually when you’re using libpcap to capture network traffic, your chief worry will be whether or not your application will keep up with the flow of traffic.
Today, though, I’ve stubbed my toe on a problem with traffic that’s too slow. It happens with both Ubuntu Trusty and Debian Jessie. If there’s a gap between packets of more than about 50 milliseconds, the first packet to arrive after the gap will be dropped and you’ll never see it. I was capturing DNS queries and responses, and found that with a query rate of under 20 queries per second you start dropping queries. By the time you’re down to 15 queries per second, nearly every query is dropped.
After spotting that tcpdump
doesn’t have this problem, and much experimentation later, it’s not quite as simple as that. Whether or not you drop packets depends on the libpcap API you are using. If you’re using pcap_loop()
to capture packets, you can stop worrying. This works properly. I guess that tcpdump
is using pcap_loop()
to capture packets and that’s why it works.
If, on the other hand, you’re using pcap_dispatch()
or pcap_next_ex()
, as the documentation urges you to do, than you’re doomed. This is regardless of whether you are using blocking or non-blocking mode.
So, what can you do? Your choices are limited.
- Switch your application to using
pcap_loop()
. If you were using non-blocking mode with eitherpcap_dispatch()
orpcap_next_ex()
, this will be non-trivial, aspcap_loop()
doesn’t observe non-blocking, but always blocks. It won’t be straightforward either if you’re usingpcap_next_ex()
in your own loop. - Upgrade. The problem is fixed if you upgrade Ubuntu to Xenial. I also found the problem apparently fixed by updating Jessie to the 4.7.0 kernel in Debian Backports.