假设情景:
udp分组流到达运行两个程序的机器X,一个正在侦听具有recv()的数据包,另一个正在运行pcap.
udp分组流到达运行两个程序的机器X,一个正在侦听具有recv()的数据包,另一个正在运行pcap.
在这种情况下,根据我的理解,数据包被存储在接口中,直到它被内核轮询,然后将它们移动到内核中的缓冲区中,并将数据包复制到另外两个缓冲区中 – 一个程序缓冲区用recv监听,一个缓冲区用于使用pcap监听程序.在读取数据包时,通过pcap_next()或recv(),下一次进程调度程序运行它们(我认为它们在这种情况下阻塞),从相应的缓冲区中删除.它是否正确?有没有使用4个缓冲区,还是处理其他方式?
我正在寻找一个尽可能详细的描述,关于这种情况下真正涉及到哪些缓冲区,以及数据包从一个到另一个的移动(例如,在到达recv缓冲区之前,数据包被复制到pcaps缓冲区,之后还是未定义?).
我知道这似乎是一个大问题,但我真正关心的是数据包的存储位置,以及它在那里停留多久.子弹点是罚款.理想情况下,我想要一个普遍的答案,但是如果在我对Linux最感兴趣的操作系统之间有所不同.
Linux案例(BSD可能有点类似,使用mbuf而不是skbuffs):
Linux使用skbuffs(套接字缓冲区)来缓冲网络数据. skbuff具有关于某些网络数据的元数据,以及一些指向该数据的指针.
水龙头(pcap用户)创建了skbuffs的克隆.克隆是一个新的skbuff,但它指向相同的数据.当有人需要修改几个skbuff(原始的skbuff及其克隆)共享的数据时,首先需要创建一个新的副本(写时复制).
当有人不需要一个skbuff了,它是kfree_skb()的. kfree_skb()减少一个引用计数,当引用计数达到零时,这个skbuff被释放.解释克隆有点复杂,但这是一般的想法.