【问题标题】:Does pcap_breakloop() flushes packets in the packet buffer before pcap_loop() returns?pcap_breakloop() 是否会在 pcap_loop() 返回之前刷新数据包缓冲区中的数据包?
【发布时间】:2022-11-18 14:55:39
【问题描述】:

我有一个使用 libpcap 捕获数据包的库。我在专用线程中使用 pcap_loop() 进行捕获,使用 pcap_breakloop() 停止捕获。
数据包缓冲区超时设置为 500 毫秒。

在极少数情况下,我会遗漏我的应用程序在调用 pcap_breakloop() 之前发送的最后一个数据包。

阅读 libpcap 文档我最后想知道丢包是否与数据包缓冲区超时.文件说:

数据包不会在到达时立即交付,而是在短暂的延迟(称为“数据包缓冲区超时”)后交付

如果在此延迟期间调用 pcap_breakloop() 会发生什么情况?缓冲区中的数据包是传递给回调还是在pcap_loop()返回之前被丢弃?
我无法在文档中找到答案。

【问题讨论】:

    标签: libpcap


    【解决方案1】:

    缓冲区中的数据包是否传递给回调

    不。

    或者它们在 pcap_loop() 返回之前被丢弃了?

    是的。在内核代码中缓冲数据包并仅在缓冲区填满或超时到期时才传送它们的捕获机制中,pcap_breakloop() 不会强制传送数据包。

    为了一些那里的捕获机制可能是一种强制超时实际上过期的方法,但我不知道记录在案使用 Linux PF_PACKET 套接字、BPF 或 WinPcap/Npcap NPF 来做到这一点的方法。

    更新,提供更多细节:

    在 Linux 和 Windows 上,pcap_breakloop() 尝试唤醒任何被阻止等待相同pcap_t 上的数据包的东西。

    在 Linux 上,这是通过在用于捕获的 PF_PACKET 套接字和“事件”描述符上的 libpcap 块中调用 poll() 来实现的; pcap_breakloop() 导致“事件”描述符提供一个事件,这样 poll() 就会被唤醒,即使还没有数据包可以从套接字中提取。那确实不是强制将缓冲区中的当前块(内核和用户态代码之间共享的内存)分配给用户态,因此它们不会提供给 libpcap 的调用者。

    在 Windows 上,对于 Npcap,驱动程序和 Packet32 库(Npcap 的 libpcap 部分调用 Packet32 库中的例程)使用“事件对象”来允许库阻止等待数据包,并且驱动程序在时唤醒库数据包可用。 pcap_breakloop()对该对象的句柄进行SetEvent()调用,这会强制等待数据包唤醒的用户态代码;然后它会尝试从设备中读取。我将不得不花更多的时间查看驱动程序代码,看看如果此时有缓冲但未交付的数据包,它们是否会被交付。

    在所有其他平台上,pcap_breakloop() 确实不是提供唤醒,因为捕获机制要么不进行缓冲,要么不提供强制唤醒的机制,因此:

    • 如果没有进行缓冲,则没有要刷新的数据包缓冲区;
    • 如果有超时,读取阻塞的代码将在超时到期时被唤醒,并且该缓冲区将被传送到用户空间;
    • 如果没有超时,读取时阻塞的代码可能会无限期阻塞。

    理想的情况是,如果捕获机制在所有进行缓冲的平台上提供了一种用户态代码强制交付当前缓冲区的方式,从而引起唤醒。这将需要更改 Npcap 中的 NPF 驱动程序和 Packet32 库,并且需要更改 Linux、*BSD、macOS、Solaris 和 AIX 中的内核。

    更新 2:

    另请注意,“中断循环”意味着立即跳出循环,因此即使完成了上述所有操作,当退出循环时,libpcap 的用户空间缓冲区中可能仍有数据包。如果你想要那些数据包——即使通过调用pcap_breakloop(),你告诉 libpcap“停止给我数据包”——你将把pcap_t 置于非阻塞模式并调用pcap_dispatch() 来耗尽用户空间缓冲区。 (这不会耗尽内核缓冲区。)

    【讨论】:

    • 感谢您的回复,您对这种行为有任何参考吗?或者我可以参考的文档?
    • “你有关于这种行为的任何参考资料吗?或者我可以参考的文档?”不,我没有更新手册页来提及这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-21
    • 2013-04-01
    • 2020-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多