gpt4 book ai didi

libpcap - pcap_dispatch-回调处理问题

转载 作者:行者123 更新时间:2023-12-04 05:20:51 30 4
gpt4 key购买 nike

我正在编写相当简单的pcap“实时”捕获引擎,但是pcap_dispatch的数据包处理回调实现应花费相对较长的时间进行处理。
pcap是否在单独的线程中运行每个“pcap_handler”回调?如果是,“pcap_handler”是否是线程安全的,还是应该使用关键部分来保护它?
另外,pcap_dispatch回调是否可以串行方式工作?例如。仅在完成数据包1的“pcap_handler”之后才调用数据包2的“pcap_handler”吗?如果是这样,是否有一种避免累积延迟的方法?
谢谢,
-V

最佳答案

Pcap基本上是这样工作的:有一个内核模式驱动程序,用于捕获数据包并将它们放置在大小为B的缓冲区中。用户模式应用程序可以随时使用pcap_looppcap_dispatchpcap_next(后者基本上是带有一个数据包的pcap_dispatch)。

因此,当您使用pcap_dispatch请求一些数据包时,libpcap进入内核并请求缓冲区中的下一个数据包(如果没有一个超时代码,则填充内容,但这与本讨论无关),进行传输将其放入用户区,然后将其从缓冲区中删除。之后,pcap_dispatch调用您的处理程序,减少它的待办事项计数器,并从头开始。结果,pcap_dispatch仅在请求的数据包数量已处理,发生错误或发生超时时返回。

如您所见,与大多数C API一样,libpcap完全是非线程的。但是,内核模式驱动程序显然很乐意将数据包传递到多个线程(否则您将无法从多个进程中捕获),并且完全是线程安全的(每个用户模式都有一个单独的缓冲区)处理)。

这意味着您必须自己实现所有并行性。您想做这样的事情:

pcap_dispatch(P, count, handler, data);
.
.
.
struct pcap_work_item {
struct pcap_pkthdr header;
u_char data[];
};

void handler(u_char *user, struct pcap_pkthdr *header, u_char *data)
{
struct pcap_work_item *item = malloc(sizeof(pcap_pkthdr) + header->caplen);
item->header = *header;
memcpy(item->data, data, header->caplen);
queue_work_item(item);
}

请注意,我们必须将数据包复制到堆中,因为回调返回后, headerdata指针无效。

函数 queue_work_item应该找到一个工作线程,并为其分配处理数据包的任务。由于您说回调需要“相对较长的时间”,因此您可能需要大量的工作线程。找合适数量的 worker 需要精打细算。

在本文的开头,我说过内核模式驱动程序具有缓冲区来收集等待处理的传入数据包。此缓冲区的大小由实现定义。 snaplenpcap_open_live参数仅控制捕获一个数据包的多少字节,但是,不能以可移植的方式控制数据包的 数字。它可能是固定大小的。随着越来越多的数据包到达,它可能会变得更大。但是,如果溢出,则所有其他数据包都将被丢弃,直到有足够的空间可容纳下一个数据包为止。如果要在高流量环境中使用应用程序,则要确保* pcap_dispatch *回调快速完成。我的示例回调仅将数据包分配给工作人员,因此即使在交通繁忙的环境中也能正常工作。

我希望这能回答您的所有问题。

关于libpcap - pcap_dispatch-回调处理问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7771963/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com