首页 > 解决方案 > libpcap 如何处理缓冲区大小限制和处理时间?

问题描述

Pcap 文档指出诸如pcap_dispatch读取数据缓冲区之类的功能。对此我有很多不明白的地方。

谢谢

标签: libpcap

解决方案


由于您可以设置缓冲区大小,如果缓冲区大小不是数据包大小的倍数会怎样?

一般来说,没有“数据包大小”这样的东西。

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

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

即,使用这些数据包捕获机制,没有单个缓冲区,有两个或多个缓冲区(两个带 BPF 的缓冲区,多个带 PF_PACKET 套接字的缓冲区)。

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

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

假设我有 500 字节的数据包,我的缓冲区是 800 字节

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

所以不要那样做。事实上,除非你看到很多丢包,或者在一台内存非常有限的机器上,否则根本不要设置缓冲区大小,让 libpcap 为你挑选。

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

现在假设我将缓冲区设置为 1000 字节,而数据包仍然是 500 字节。当两个数据包到达时,我的处理函数被缓冲区调用,但是如果一个新的数据包到达,而我的处理函数仍在处理最后两个数据包,会发生什么?

看上面。

在我的处理函数完成处理最后两个数据包之前,是否还有其他内部内核缓冲区仍会存储它,

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

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


推荐阅读