问题描述
情况
我当前正在编写一个内核模块,该模块应该处理基于UDP的自定义网络协议。 我要做的(用伪代码)是,我用
创建了一个UDP套接字sock_create(AF_INET,SOCK_DGRAM,IPPROTO_UDP,&sk);
其中sk
是套接字指针。
因此,我没有主动轮询内核以获取新的UDP数据,而是向
sk->sk_data_ready = myudp_data_ready;
void myudp_data_ready(struct sock *sk) {
struct sk_buff *skb;
int err;
if ((skb = skb_recv_datagram(sk,1,&err)) == NULL) {
goto Bail;
}
// ...
// HERE,MY CUSTOM UDP-BASED PROTOCOL WILL BE IMPLEMENTED
// ...
skb_free_datagram(sk,skb);
return;
Bail:
return;
}
问题
现在的问题是,我得到所有UDP数据包都很好。
skb_recv_datagram
函数正在返回我可以处理的套接字缓冲区。
但是,一段时间后,它将停止工作。
我已经尝试过的东西
在/proc/net/udp
中,我看到rx_queue
一直在增长,直到充满为止,然后数据包被丢弃。
在这里,我的代码中不再有任何数据包了(很明显)。
这似乎很奇怪。
如果我正确理解,内核将在套接字缓冲区中使用引用计数。
如果该计数下降到1,则释放缓冲区并将缓冲区与接收队列断开链接。
我查看了skb->users
字段,该字段应该是引用计数。
它设置为1
,这意味着我的代码是唯一保存对skb
的引用的位置。
但是skb_free_datagram
和kfree_skb
似乎都没有释放缓冲区,因为rx_queue
一直在增长。
而且我不知道为什么。
您有什么建议吗?
我想念什么吗?
更多信息
我正在将Ubuntu 20.04与内核版本5.4.0-52一起使用。 我有一个简单的用户土地应用程序,它将UDP数据包发送到内核模块正在侦听的特定端口。
谢谢您的帮助。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)