在循环中接收UDP数据包会导致Linux内核崩溃

时间:2016-08-11 10:49:10

标签: c loops linux-kernel network-programming udp

我在linux内核中修改了UDP代码,以实现发送和接收缓冲区来处理数据包的无序传递。在新代码中,每当我尝试从接收缓冲区向套接字传递多个数据包时,就会出现内核崩溃。我的代码片段:

while(!skb_queue_empty(&sk->sk_receive_queue)){
    skb = skb_peek(&sk->sk_receive_queue);
    qb = QUIC_SKB_CB(skb);

    //Check if this is the packet to be received
    if(qb->sequence != qp->first_rcv){
        printk("First packet in queue not yet received\nFirst packet seq %u\nExpected packet seq %u\n", qb->sequence, qp->first_rcv);
        //break;
        goto drop;
    }

    skb_unlink(skb, &sk->sk_receive_queue);
    if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf))
        goto drop;


    rc = 0;

    ipv4_pktinfo_prepare(sk, skb);
    bh_lock_sock(sk);
    if (!sock_owned_by_user(sk))
        rc = __udp_queue_rcv_skb(sk, skb);
    else if (sk_add_backlog(sk, skb, sk->sk_rcvbuf)) {
        bh_unlock_sock(sk);
        goto drop;
    }
    bh_unlock_sock(sk);
    printk("Packets left in read buffer = %u\n", skb_queue_len(&sk->sk_receive_queue));
}

return rc;

然而,当我从代码中删除while循环时,代码运行正常,但我只设法从缓冲区发送一个数据包。此外,崩溃发生在bh_lock_sock(sk)之后,即数据包被传递到套接字时。我通过评论锁定和解锁套接字之间的界限来解决这个问题。

循环可能出现什么问题?

感谢。

1 个答案:

答案 0 :(得分:0)

我弄清楚我做错了什么。我使用sk->sk_receive_queue作为接收缓冲区,假设UDP没有真正使用它。因此,当调用函数__udp_queue_rcv_skb时,它将使用列表sk->sk_receive_queue,从而干扰我已经填充的队列。

我刚刚在struct udp_opt中定义了另一个接收缓冲区,我现在正在使用它。