【问题标题】:How does libpcap handle buffer size limits and processing time?libpcap 如何处理缓冲区大小限制和处理时间?
【发布时间】:2021-07-27 03:41:48
【问题描述】:

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

  • 既然可以设置缓冲区大小,如果缓冲区大小不是数据包大小的倍数会怎样?假设我有 500 字节的数据包,我的缓冲区是 800 字节,如果有两个数据包到达,缓冲区会变满,但它会丢失 200 字节来存储整个第二个数据包。这只是它应该如何工作(因此您必须选择适当的缓冲区大小)还是有什么可以防止这种情况发生?
  • 现在假设我将缓冲区设置为 1000 字节,而数据包仍然是 500 字节。当两个数据包到达时,我的处理函数被缓冲区调用,但是如果一个新的数据包到达,而我的处理函数仍在处理最后两个数据包,会发生什么?在我的处理函数完成处理最后两个数据包之前,是否还有其他内部内核缓冲区仍会存储它,并且只有在处理完成后,内核/libpcap 才会再次写入我的缓冲区?

谢谢

【问题讨论】:

    标签: libpcap


    【解决方案1】:

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

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

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

    对于 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 字节,通常不是。缓冲区太小,无法即使缓冲区为空,保持最大大小的数据包也会丢弃这些数据包!)

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

    见上文。

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

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

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

    【讨论】:

    • 感谢您的详细解答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-10
    • 2013-08-14
    • 2014-08-29
    • 2019-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多