我正在使用 netfilter 操作 TCP 数据包,因此我必须重新计算按预期工作的 TCP 和 IP 校验和。
Wireshark 报告校验和在离开服务器时是正确的(这也与客户端认为的正确),但是当它们到达客户端时,校验和总是被替换为 0xAA6A。
在后路由挂钩中,我正在计算 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
另一个我不确定的相关点......我还在服务器上的预路由挂钩中操作数据包/端口,它们被传输层接受,并且无论我看起来如何,它们肯定会到达我的应用程序对 TCP 校验和进行处理,我假设如果在更改 IP 地址/和端口后未更新 TCP 校验和,它们将被丢弃。
这种行为有什么明显的原因,还是我误解了网络堆栈的一部分?
更新:
将 ip_summed 设置为 CHECKSUM_NONE 会在校验和离开我的代码后停止重新计算。我不确定的是为什么它被重新计算为不正确的固定值?如果我不设置它,它被设置为 CHECKSUM_PARTIAL。