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

XDP/eBPF环境下TCP校验和计算异常排查求助

TCP校验和计算代码问题排查

以下是针对你提供的TCP校验和计算代码的问题分析及修复方案:

核心问题点

1. 奇数字节访问越界

当处理奇数长度的TCP段(比如你的测试场景:TCP头+125字节payload,假设TCP头为20字节,总长度145字节,为奇数)时,sum16函数中对最后一个单字节的访问索引错误:

  • 原代码中((const __u8*)data)[i*2+1],当2*i+1 == size时,i*2+1等于总长度,而数组索引从0开始,最后一个有效字节的索引是size-1,这会导致访问超出数据范围的内存,直接导致计算结果错误。

2. 数据边界检查逻辑错误

  • 原代码中if (data + 2*i +1 +1 > data_end)的检查冗余且错误,正确的双字节边界检查应该是确认data + 2*i +1 < data_end(因为data_end是数据末尾的下一个地址,有效数据到data_end-1),否则会误触发返回0的错误逻辑。
  • 处理奇数字节时的边界检查if (data + (i*2+2) > data_end)完全错误,该检查判断的是超出当前段长度的地址,必然成立,导致直接返回0而非处理最后一个字节。

3. TCP伪头部长度字段未转网络字节序

TCP伪头部中的长度字段需要以**网络字节序(大端)**参与计算,但原代码直接将主机字节序的长度值加入校验和,这会导致字节序不匹配,计算结果错误。

修复后的代码

修正后的sum16函数

#define MAX_CSUM_WORDS 750

static __always_inline __u32 sum16(const void* data, __u32 size, const void* data_end) {
    __u32 s = 0;
    #pragma unroll
    for (__u32 i = 0; i < MAX_CSUM_WORDS; i++) {
        // 所有字节处理完成,正常退出
        if (2*i >= size) {
            return s;
        }

        // 检查当前双字节是否在有效范围内
        if (data + 2*i + 1 >= data_end) {
            return 0; // 越界,返回错误
        }

        // 累加双字节
        s += ((const __u16*)data)[i];

        // 处理奇数长度的最后一个单字节
        if (2*i + 2 == size) {
            // 检查最后一个单字节是否在有效范围内
            if (data + size - 1 >= data_end) {
                return 0;
            }
            // 将单字节作为高字节为0的16位值累加(TCP校验和要求奇数字节补0)
            s += ((const __u8*)data)[size - 1] << 8;
            return s;
        }
    }
    return s;
}

修正后的主逻辑中长度字段处理

// 原代码中的长度累加行替换为:
tcp_csum += htons((tcph->doff * 4) + payload_len);

其他函数保持不变

sum16_32和carry函数逻辑正确,无需修改:

static __always_inline __u32 sum16_32(__u32 v) {
    return (v >> 16) + (v & 0xffff);
}
static __always_inline __u16 carry(__u32 csum) {
    csum = (csum & 0xffff) + (csum >> 16);
    csum = (csum & 0xffff) + (csum >> 16); // 确保进位完全处理
    return ~csum;
}

关键说明

  • 奇数字节处理时,TCP校验和要求将最后一个单字节视为高字节补0的16位值(即单字节0xAB视为0x00AB),修复代码中使用<<8操作实现这一点,而非直接累加单字节值。
  • 边界检查逻辑修正为基于size-1判断最后一个字节的有效性,避免越界误判。
  • 伪头部长度字段必须转换为网络字节序,确保与TCP协议要求一致。

内容的提问来源于stack exchange,提问作者Yousef Ashraf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 21:13:14