天天看点

【Linux】UDP广播报文接收速率问题

项目采用的是3.10.108的kernel,在测试时使用发包功率高速发送DHCP Request报文,发现busybox中的udhcpd 进程状态为D,抓包看,没有offer包,而且样机ping不通。

分析发现是在kernel中的函数udp_queue_rcv_skb中:

if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf))

{

//printk("%s %d goto drop; \r\n", FUNCTION, LINE);

goto drop;

}

丢包;

打印调试代码后发现:

[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack

[16:52:24] : sock_queue_rcv_skb 483 call sk->sk_data_ready

[16:52:24] :

[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack

[16:52:24] : udp_queue_rcv_skb 1538 goto drop;

[16:52:24] :

[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack

[16:52:24] : udp_queue_rcv_skb 1538 goto drop;

[16:52:24] :

[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack

[16:52:24] : sock_queue_rcv_skb 483 call sk->sk_data_ready

[16:52:24] :

[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack

[16:52:24] : udp_queue_rcv_skb 1538 goto drop;

[16:52:24] :

[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack

[16:52:24] : udp_queue_rcv_skb 1538 goto drop;

[16:52:24] :

[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack

[16:52:24] : sock_queue_rcv_skb 483 call sk->sk_data_ready

[16:52:24] :

[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack

[16:52:24] : udp_queue_rcv_skb 1538 goto drop;

[16:52:24] :

[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack

[16:52:24] : udp_queue_rcv_skb 1538 goto drop;

[16:52:24] :

[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack

[16:52:24] : sock_queue_rcv_skb 483 call sk->sk_data_ready

[16:52:24] :

[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack

[16:52:24] : udp_queue_rcv_skb 1538 goto drop;

[16:52:24] :

[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack

[16:52:24] : sock_queue_rcv_skb 483 call sk->sk_data_ready

[16:52:24] :

[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack

[16:52:24] : udp_queue_rcv_skb 1538 goto drop;

[16:52:24] :

[16:52:24] : __udp4_lib_mcast_deliver 1641 do flush_stack

[16:52:24] : udp_queue_rcv_skb 1538 goto drop;

[16:52:29] : udhcpd_main 501 : select retval = 1

udp协议栈中多次接收到包,并且把包放入sk->sk_receive_queue队列,但是上层的应用程序select却检测到一次socket可读并收包,这样导致队列满而数据包被丢弃。

问题原因找到,在busybox中汇报调用了

fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));导致进程处于D状态。包没有发出去,导致IP地址续约失败。