Я управляю TCP-пакетами с помощью netfilter, поэтому мне приходится пересчитывать контрольные суммы 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);
На сервере не включена разгрузка TCP для RX или TX, а также она даже не поддерживается, я получаю неподдерживаемую ошибку при попытке включить или отключить.
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, я предполагал, что они будут отброшены, если контрольная сумма TCP не будет обновлена после изменения IP-адреса / и порта.
Есть ли очевидная причина такого поведения или я неправильно понимаю часть сетевого стека?
Обновление:
Установка ip_summed на CHECKSUM_NONE останавливает пересчет контрольной суммы, как только она покидает мой код. В чем я не уверен, так это в том, почему он пересчитывается на неправильное фиксированное значение? Если я не установил его, он будет установлен на CHECKSUM_PARTIAL.