我正在使用 netfilter 处理 TCP 数据包,因此我必须重新计算按预期工作的 TCP 和 IP 校验和。
Wireshark 报告校验和在离开服务器时是正确的(这也符合客户端认为它们应该是的),但是当它们到达客户端时,校验和总是替换为 0xAA6A。
在后路由 Hook 中,我按如下方式计算 TCP 校验和...在处理地址/端口之后。
tcp_header->check = 0;
tcp_header->check = tcp_v4_check(tcp_len,
ip_header->saddr,
ip_header->daddr,
csum_partial((char *)tcp_header, tcp_len, 0));
IP校验和可以使用
ip_send_check(ip_header);
服务器没有为 RX 或 TX 启用 TCP 卸载,甚至也不支持它,我在尝试启用或禁用时收到不支持的错误。
Offload parameters for eth0:
rx-checksumming: off
tx-checksumming: off
scatter-gather: off
tcp-segmentation-offload: off
udp-fragmentation-offload: off
generic-segmentation-offload: off
generic-receive-offload: on
large-receive-offload: off
rx-vlan-offload: off
tx-vlan-offload: off
ntuple-filters: off
receive-hashing: off
另一个我不确定的相关点......我还在服务器上的预路由 Hook 中操作数据包/端口,它们被传输层接受并且无论如何肯定会到达我的应用程序我似乎对 TCP 校验和做了处理,我假设如果在更改 IP 地址/和端口后未更新 TCP 校验和,它们将被删除。
这种行为是否有任何明显的原因,或者我是否误解了网络堆栈的一部分?
更新:
将 ip_summed 设置为 CHECKSUM_NONE 会在离开我的代码后停止重新计算校验和。我不确定的是为什么它被重新计算为不正确的固定值?如果我不设置它,它会设置为 CHECKSUM_PARTIAL。
最佳答案
如果另一边的值始终相同,我看到 2 种主要可能性:1) 您稍后在这段代码之后覆盖校验和 2) tcp_len 错误 您还应该检查 NETIF_F_V4_CSUM 是否在 sockbuff dev->features 中设置,因为内核在这种情况下做了一些不同的事情
关于c - TCP 校验和计算更改 - tcp 卸载已禁用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16548576/