1

我想为 TCP/UDP 流量实现网络延迟模型,如Linux libnetfilter_queue 延迟数据包问题中所述。我已经按照安迪那里的建议,将整个数据包复制到我的程序中并将其放置在优先级队列中。随着时间的推移,优先队列中的数据包将被删除并使用 RAW 套接字进行分派。

我面临的问题是:libnetfilter_queue 对数据包的初始捕获是通过匹配端口来完成的(sudo iptables -A OUTPUT -p udp --dport 8000 -j NFQUEUE --queue-num 0)。当这些数据包被 RAW 套接字重新注入时,它们会再次被 libnetfilter_queue 拾取(因为端口保持不变),因此会一直循环下去。

我真的很迷茫,想不出出路。请帮我。

4

2 回答 2

2

使用 skb-> 标记。这是一个仅存在于您主机的 IP 堆栈中的标记。它不会影响网络数据包本身的任何内容。

您可以使用 iptables 使用“--mark”过滤器对其进行过滤。使用它从您的延迟链返回,以便您重新插入的数据包不会再次延迟。

iptables -A DELAY -m mark --mark 0xE -j RETURN
iptables -A DELAY -j DELAY

您可以配置原始套接字以应用标记,使用setsockopt(fd, SOL_SOCKET, SO_MARK, ...). 您只需在打开套接字后执行一次。标记值将自动应用于您通过套接字发送的每个数据包。

于 2012-05-06T19:07:16.720 回答
-1

这可能不是最好的方法,但这是一种可能的解决方案。您可以使用 IP 标头中的 DSCP 字段来区分新数据包和您重新注入的数据包。将您的 iptables 规则更改为仅将 DSCP 为 0 的数据包排入队列(请参阅http://www.frozentux.net/iptables-tutorial/iptables-tutorial.html#DSCPMATCH)。这假设当您的操作系统发送数据包时,它将 DSCP 设置为 0。现在操作系统生成的所有新数据包都将发送到您的程序,因为它们仍然匹配 iptables 规则。当您在程序中使用 RAW 套接字创建新数据包时,请将 DSCP 值设置为非零值。当您的新数据包被重新注入时,它将不再符合 iptables 规则,并将通过网络发送出去。

如果您不希望数据包在设置了 DSCP 值的情况下通过网络发送出去,您可以添加另一个 iptables 规则以将 dscp 值重新写入 0。

于 2012-05-06T18:48:16.953 回答