我想实现TCP / UDP流量的网络延迟模型,如Linux libnetfilter_queue delayed packet problem中所述。我已经遵循了Andy的建议,将整个数据包复制到我的程序并将其置于优先级队列中。随着时间的推移,优先级队列中的数据包将被删除并使用RAW套接字进行分派。
我面临的问题是:libnetfilter_queue对数据包的初始捕获是通过匹配端口来完成的(sudo iptables -A OUTPUT -p udp --dport 8000 -j NFQUEUE --queue-num 0)。当这些数据包被RAW套接字重新注入时,它们会被libnetfilter_queue再次拾取(因为端口保持不变),因此会继续循环。
我真的很困惑,想不出办法。请帮帮我。
答案 0 :(得分:2)
使用skb->标记。它是一个仅存在于主机IP堆栈中的标记。它不会影响网络数据包本身的任何内容。
您可以使用'--mark'过滤器使用iptables过滤它。使用它从延迟链返回,以便重新插入的数据包不会再次延迟。
iptables -A DELAY -m mark --mark 0xE -j RETURN
iptables -A DELAY -j DELAY
您可以使用setsockopt(fd, SOL_SOCKET, SO_MARK, ...)
配置原始套接字以应用标记。打开套接字后,您只需执行此操作一次。标记值将自动应用于通过套接字发送的每个数据包。
答案 1 :(得分:-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。