libpcap 如何处理缓冲区大小限制和处理时间?

How does libpcap handle buffer size limits and processing time?

Pcap 文档指出,pcap_dispatch 等函数读取大量数据。对此我有很多不明白的地方。

谢谢

Since you can set the buffer size, what happens if the buffer size isn't a multiple of the packet size?

一般来说,没有所谓的“数据包大小”。

因此,真正的问题是“如果到达的数据包不适合缓冲区中剩余的 space,会发生什么情况?”

对于 UN*Xes 上最常见的捕获机制(*BSD/macOS/AIX/Solaris 和 PF_PACKET 套接字中的 BPF 捕获机制),答案是“缓冲区已标记为已满并可用到用户区(即线程 运行 libpcap 循环唤醒,以便它可以读取缓冲区),并且,如果有任何其他缓冲区可用,则将数据包放在下一个缓冲区的开头 - 如果有没有可用的缓冲区,数据包被丢弃。

即,对于那些数据包捕获机制,没有单个缓冲区,有两个或更多缓冲区(两个缓冲区带有 BPF,多个缓冲区带有 PF_PACKET 套接字)。

使用 WinPcap/Npcap 在 Windows 上使用的数据包捕获机制,有一个循环缓冲区,以及“当这么多数据包数据可用时唤醒用户空间代码”的数量。如果缓冲区中的可用 space 小于数据包的大小,则丢弃该数据包。

“唤醒用户空间代码”的数量小于缓冲区大小,因此,如果数据到达的速度没有快于用户空间处理它的速度,则用户空间应该足够快地清空缓冲区以确保足够的空间。

Say I have 500 bytes packets and my buffer is 800 bytes

...那么您可能会丢弃 lot 的数据包。缓冲区应该比那个大。很久以前,BPF 的默认缓冲区大小是 32K 字节;它现在是 256K 字节(这通常是 OS 支持的最大大小;实际上是它的两倍,因为有两个缓冲区)。 PF_PACKET 套接字的默认缓冲区大小为 2M 字节。

所以不要那样做。事实上,除非您看到大量数据包丢失,或者在 非常 内存受限的机器上,否则根本不要设置缓冲区大小 , 让 libpcap 帮你挑选。

(800 字节缓冲区大小不佳的另一个原因 - 如果 CRC 不是捕获的数据包的一部分,则以太网上的最大数据包大小为 1514 字节,而通常情况下不是。缓冲区太大即使缓冲区为空,容纳最大数据包的小数据包也会丢弃这些数据包!)

Now let's say I set my buffer to 1000 bytes, and the packets are still 500 bytes. When two packets arrive my handler function is called with the buffer, but what happens if a new packet arrives while my handler function is still processing the two last packets?

见上文。

Is there some other internal kernel buffer that will still store it before my handler function has finished processing the last two packets,

如前所述,大多数 UN*Xes 上没有单个缓冲区,因此使用了另一个缓冲区——另一个 BPF 缓冲区,或下一个 PF_PACKET 缓冲区。在 Windows 上,默认的“唤醒用户区”量是这样的,即有足够的空间容纳其他数据包 - 只要缓冲区足够大,这是可能的。

请注意,原始 libpcap 甚至没有设置缓冲区大小的例程 - 您只是获得了默认大小。