skb校验和计算功能可能导致系统挂起

问题描述 投票:0回答:1

在Linux论坛上的asking about the same problem和一些错误测试后,我有以下与我的问题相关的信息:

我正在构建一个应用程序,将内核网络挂钩的传入数据包转移到用户空间中的代理,该应用程序从tcp套接字读取数据,然后将其发送到其原始目标。当数据包进入时,我将skb目标地址更改为我的代理tcp服务器的地址,当它离开时我更改源地址,以便通信将透明地进行。

我遇到了以下问题:

当大量数据进入时,它们可以毫无问题地到达代理。

但是,当将数据发送到其原始目标时,如果我发送足够大量的数据,系统将挂起。穴居人的调试表明,当skb离开代理时它只是非线性的,并且在不调用skb_linearize的情况下,校验和不能成功计算。

当数据退出时我自己在内核中没有分配任何数据,并且在我自己的代码中似乎没有内存错误,所以我得出结论,问题很大就是我使用skb_linearize函数,或者我如何计算校验和一般:

void fixChecksum(struct sk_buff *skb)
{
    if(skb_is_nonlinear(skb))
    {
        skb_linearize(skb);
    }
    struct iphdr *ip_header = ip_hdr(skb);
    struct tcphdr *tcp_header = (struct tcphdr*)(skb_network_header(skb) + ip_hdrlen(skb));
    int tcplen = (skb->len - ((ip_header->ihl )<< 2));
    tcp_header->check=0;
    tcp_header->check = tcp_v4_check(tcplen, ip_header->saddr, ip_header->daddr,csum_partial((char*)tcp_header, tcplen,0));
    skb->ip_summed = CHECKSUM_NONE; //stop offloading
    ip_header->check = 0;
    ip_header->check = ip_fast_csum((u8 *)ip_header, ip_header->ihl);
}

我怀疑我传输的数据会以某种方式保留在内核中,并且在内核耗尽并且系统挂起之后。但是我不明白这里可能有什么问题。我也尝试将skb_linearize更改为skb_linearize_cow,但没有帮助。

在我处理它们之后,我在LOCAL_OUT钩子上处理的skbs是否有可能不被释放?

我的内核版本是3.2

c networking tcp linux-kernel kernel-module
1个回答
0
投票

因此,在我的程序运行之后,经过一些调试并检查内核内存使用情况后,结果发现每个数据包都没有增长。在我添加的一个函数中删除了自旋锁后,它停止了锁定,因为我希望在系统调用之间保持模块函数线程安全。显然我不知道我在做什么,重负荷可能导致死锁或其他什么,这很奇怪,因为我只有一个锁。谢谢,如果有人试图帮助和抱歉浪费你的时间。

© www.soinside.com 2019 - 2024. All rights reserved.