You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在TUN设备上收到TCP重传而非ACK的问题排查

TCP校验和错误导致SYN-ACK不被响应的排查要点

1. 伪头部构造错误

TCP校验和计算依赖IP伪头部,这是最常见的出错点:

  • 伪头部必须包含源IP(你的TUN设备IP:192.168.20.99)、目的IP(NC客户端的IP)、协议号(固定为6,对应TCP)、TCP报文总长度(头部+数据的字节数,不是IP包总长度)
  • 确认伪头部的字段类型和长度符合要求:IP是32位、协议号是8位、TCP长度是16位,不要出现字段长度或值的错误

2. 字节序不匹配

RFC1071要求所有参与计算的字段必须是网络字节序(大端):

  • 检查TCP头部的序列号、确认号、窗口大小等字段,是否在计算前已经通过htons()/htonl()转换为大端
  • 伪头部中的IP地址、TCP长度必须是大端格式,不能直接使用主机字节序的数值
  • 累加过程中,每个16位块要确保是网络字节序后再加入总和

3. 校验和计算细节遗漏

严格按照RFC1071的步骤检查:

  • 如果TCP报文长度是奇数,必须在末尾补一个0字节(仅用于计算,不发送),否则会漏掉最后一个字节的校验
  • 累加时的溢出处理:每次累加后,要将高16位的值加到低16位,循环直到没有溢出
  • 最终校验和是累加结果的按位取反,不要直接使用累加值或取反错误
  • 若TCP头部包含选项字段,必须将选项部分纳入计算,不能只计算固定头部

4. TUN报文封装问题

TUN设备处理三层IP报文,需确认:

  • 你构造的SYN-ACK是否封装成了完整合法的IP包,IP头部自身的校验和是否正确计算(IP校验和错误会导致报文被丢弃,间接引发TCP重传)
  • 检查TUN设备的MTU设置,避免报文被截断导致校验和计算的原始数据与实际发送数据不一致

5. 计算后报文被修改

  • 校验和计算完成后,是否修改过TCP头部的字段(比如SYN/ACK标志位),但未重新计算校验和
  • 确保发送的二进制报文与计算校验和时的原始数据完全一致,无字节丢失、篡改或顺序错误

参考校验和计算伪代码(对照排查)

uint16_t tcp_checksum(uint8_t *tcp_data, size_t tcp_len, uint32_t src_ip, uint32_t dst_ip) {
    // 构造伪头部并累加
    uint32_t sum = 0;
    sum += (src_ip >> 16) + (src_ip & 0xFFFF);
    sum += (dst_ip >> 16) + (dst_ip & 0xFFFF);
    sum += htons(6);          // TCP协议号
    sum += htons(tcp_len);    // TCP报文总长度

    // 累加TCP报文数据
    while (tcp_len > 1) {
        sum += htons(*(uint16_t*)tcp_data);
        tcp_data += 2;
        tcp_len -= 2;
    }
    // 处理奇数长度的剩余字节
    if (tcp_len > 0) {
        sum += htons(*tcp_data << 8);
    }
    // 处理溢出
    while (sum >> 16) {
        sum = (sum & 0xFFFF) + (sum >> 16);
    }
    // 取反得到最终校验和
    return (uint16_t)~sum;
}

内容的提问来源于stack exchange,提问作者Iman Seyed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 11:57:17