【问题标题】:Packets looping forever in libnetfilter_queue包在 libnetfilter_queue 中永远循环
【发布时间】:2012-05-06 18:31:46
【问题描述】:

我想为 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 拾取(因为端口保持不变),因此会一直循环下去。

我真的很困惑,想不出出路。请帮帮我。

【问题讨论】:

    标签: c++ c linux networking netfilter


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 对不起,我对skb一无所知。我们如何配置原始套接字来应用这个标记?然后通过 iptables 规则检测它?如果可能的话,那就太好了。
    【解决方案2】:

    这可能不是最好的方法,但这是一种可能的解决方案。您可以使用 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。

    【讨论】:

    • "这假定当您的操作系统发送数据包时,它将 DSCP 设置为 0。"如果不是这种情况怎么办?我如何确定这一点?
    • 打开wireshark看一下。您可以展开 IP 标头,它会显示 DSCP 的设置。除非您以其他方式配置操作系统,否则我认为它应该将 DSCP 设置为 0。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-30
    • 2017-10-12
    • 2021-11-18
    • 2018-05-30
    • 1970-01-01
    相关资源
    最近更新 更多