深入理解Linux网络(二):UDP接收内核探究

news2024/9/22 5:28:54

深入理解Linux网络(二):UDP接收内核探究

  • 一、UDP 协议处理
  • 二、recvfrom 系统调⽤实现

一、UDP 协议处理

udp 协议的处理函数是 udp_rcv。

//file: net/ipv4/udp.c
int udp_rcv(struct sk_buff *skb)
{
 return __udp4_lib_rcv(skb, &udp_table, IPPROTO_UDP);
}

int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, int proto)
{
 sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
 if (sk != NULL) {
   int ret = udp_queue_rcv_skb(sk, skb);
 }
 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
}

__udp4_lib_lookup_skb 是根据 skb 来寻找对应的socket,当找到以后将数据包放到
socket 的缓存队列⾥。如果没有找到,则发送⼀个⽬标不可达的 icmp 包。

//file: net/ipv4/udp.c
int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{ 
 ......
 if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf))
   goto drop;
 rc = 0;
 ipv4_pktinfo_prepare(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);
 return rc;
}

sock_owned_by_user 判断的是⽤户是不是正在这个 socket 上进⾏系统调⽤( socket 被占⽤)。
如果没有,那就可以直接放到 socket 的接收队列中。
如果有,那就通过 sk_add_backlog 把数据包添加到 backlog 队列。 当⽤户释放的 socket 的时候,内核会检查 backlog 队列,如果有数据再移动到接收队列中。
sk_rcvqueues_full 接收队列如果满了的话,将直接把包丢弃。接收队列⼤⼩受内核参数
net.core.rmem_max 和 net.core.rmem_default 影响。

二、recvfrom 系统调⽤实现

代码⾥调⽤的 recvfrom 是⼀个 glibc 的库函数,该函数在执⾏后会将⽤户进⾏陷⼊到内核态,进⼊到 Linux 实现的系统调⽤ sys_recvfrom 。
在这里插入图片描述
socket 数据结构中的 const struct proto_ops 对应的是协议的⽅法集合。每个协议都会实现不同的⽅法集,对于IPv4 Internet 协议族来说,每种协议都有对应的处理⽅法,如下:
对于 udp 来说,是通过 inet_dgram_ops 来定义的,其中注册了 inet_recvmsg ⽅法。

//file: net/ipv4/af_inet.c
const struct proto_ops inet_stream_ops = {
 ......
 .recvmsg = inet_recvmsg,
 .mmap = sock_no_mmap,
 ......
}
const struct proto_ops inet_dgram_ops = {
 ......
 .sendmsg = inet_sendmsg,
 .recvmsg = inet_recvmsg,
 ......
}

socket 数据结构中的另⼀个数据结构 struct sock *sk 是⼀个⾮常⼤,⾮常重要的⼦结构体。其中的 sk_prot ⼜定义了⼆级处理函数。对于udp协议来说,会被设置成 udp 协议实现的⽅法集 udp_prot 。

//file: net/ipv4/udp.c
struct proto udp_prot = {
 .name = "UDP",
 .owner = THIS_MODULE,
 .close = udp_lib_close,
 .connect = ip4_datagram_connect,
 ......
 .sendmsg = udp_sendmsg,
 .recvmsg = udp_recvmsg,
 .sendpage = udp_sendpage,
 ......
}

看完了 socket 变量之后,我们再来看 sys_recvfrom 的实现过程。
在这里插入图片描述
在 inet_recvmsg 调⽤了 sk->sk_prot->recvmsg 。

//file: net/ipv4/af_inet.c
int inet_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg,
 size_t size, int flags)
{ 
 ......
 err = sk->sk_prot->recvmsg(iocb, sk, msg, size, flags &
MSG_DONTWAIT,
 flags & ~MSG_DONTWAIT, &addr_len);
 if (err >= 0)
 msg->msg_namelen = addr_len;
 return err;
}

//file: net/core/datagram.c:EXPORT_SYMBOL(__skb_recv_datagram);
struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned
  int flags, int *peeked, int *off, int *err)
{
 ......
 do {
   struct sk_buff_head *queue = &sk->sk_receive_queue;
   skb_queue_walk(queue, skb) {
   ......
 }
 /* User doesn't want to wait */
 error = -EAGAIN;
 if (!timeo)
   goto no_packet;
 } while (!wait_for_more_packets(sk, err, &timeo, last));
}

上⾯所谓的读取过程,就是访问 sk->sk_receive_queue 。
如果没有数据,且⽤户也允许等待,则将调⽤ wait_for_more_packets() 执⾏等待操作,它加⼊会让⽤户进程进⼊睡眠状态。
具体是怎么进⼊睡眠状态的,和 TCP 的实现一样,属于进程的基本知识了。

再次推荐飞哥的 《深入理解Linux网络》。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1938834.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IntelliJ IDEA 直接在软件中更新为最新版

当我们的 IDEA 工具许久没有更新,已经拖了好几个版本,想跨大版本更新,比如从2020.2.1 -> 2023.x.x 此时,我们菜单栏点击 Help -> Check for Updates… ,右下角会有提示更新,如下图: 点…

【深大计算机系统(2)】实验一 实验环境配置与使用 附常用指令

目录 一、 实验目标: 二、实验环境与工件: 三、实验内容与步骤 1. 学习并熟悉Linux基本操作,按照要求创建用户。(30分) 2.新建用户主目录下创建子目录:gdbdebug,并进入gdbdebug子目录。将过程和…

亲测--linux下安装ffmpeg最新版本---详细教程

下载地址 Download FFmpeg 下载最新的https://ffmpeg.org/releases/ffmpeg-7.0.1.tar.xz 上传到服务器 解压 tar xvf ffmpeg-7.0.1.tar.xz 编译 cd ffmpeg-7.0.1 ./configure --prefix=/usr/local/ffmpeg make && make install 报错: 解决:在后面加 跳过检测…

粉尘传感器助力面粉厂安全生产

在面粉加工行业中,粉尘问题一直是一个不容忽视的难题。从原料的破碎、研磨到成品的包装,整个生产流程中都会伴随着大量的粉尘产生。这些粉尘不仅影响生产环境,更对工作人员的健康、设备的安全运行以及环境保护构成严重威胁。因此,…

【Unity实战100例】Unity声音可视化多种显示效果

目录 一、技术背景 二、界面搭建 三、 实现 UIAudioVisualizer 基类 四、实现 AudioSampler 类 五、实现 IAudioSample 接口 六、实现MusicAudioVisualizer 七、实现 MicrophoneAudioManager 类 八、实现 MicrophoneAudioVisualizer 类 九、源码下载 Unity声音可视化四…

云计算数据中心(三)

目录 四、自动化管理(一)自动化管理的特征(二)自动化管理实现阶段(三)Facebook自动化管理 五、容灾备份(一)容灾系统的等级标准(二)容灾备份的关键技术&#…

基于图片中的表格检测与识别

1、项目介绍 本文将会使用Microsoft开源的表格检测模型table-transformer-detection来实现表格检测与入门。 以下将分三部分进行介绍: 表格检测:检测图片或PDF文件中的表格所在的区域表格结构识别:对于检测后的表格区域,再详细识…

Langchain[3]:Langchain架构演进与功能扩展:流式事件处理、事件过滤机制、回调传播策略及装饰器应用

Langchain[3]:Langchain架构演进与功能扩展:流式事件处理、事件过滤机制、回调传播策略及装饰器应用 1. Langchain的演变 v0.1: 初始版本,包含基本功能。 从0.1~0.2完成的特性: 通过事件流 API 提供更好的流式支持。标准化工具调用支持Tool…

全国区块链职业技能大赛国赛考题前端功能开发

任务3-1:区块链应用前端功能开发 1.请基于前端系统的开发模板,在登录组件login.js、组件管理文件components.js中添加对应的逻辑代码,实现对前端的角色选择功能,并测试功能完整性,示例页面如下: 具体要求如下: (1)有明确的提示,提示用户选择角色; (2)用户可看…

Java中静态代理和动态代理介绍和使用

前言 在Java中,代理模式是一种常用的设计模式,用于为其他对象提供一种代理以控制对这个对象的访问。代理模式主要有两种实现方式:静态代理和动态代理。 一、静态代理 静态代理是由程序员手动创建或指定代理类,代理类在程序运行…

【C语言】详解结构体(下)(位段)

文章目录 前言1. 位段的含义2. 位段的声明3. 位段的内存分配(重点)3.1 存储方向的问题3.2 剩余空间利用的问题 4. 位段的跨平台问题5. 位段的应用6. 总结 前言 相信大部分的读者在学校或者在自学时结构体的知识时,可能很少会听到甚至就根本没…

sip代理服务器、SIP用户代理服务器、sip服务器的区别和联系

一.SIP代理服务器(SIP Proxy Server)和SIP用户代理服务器(SIP User Agent Server,简称SIP UAS)的区别和联系。 1. 区别 1)功能定位 SIP代理服务器:主要负责将SIP请求消息从发起方…

VBA技术资料MF175:利用文本框和列表框实现多列数据录入

我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套,分为初级、中级、高级三大部分,教程是对VBA的系统讲解&#…

学习周报:文献阅读+水动力学方程推导

目录 摘要 Abstract 文献阅读:物理信息神经网络学习自由表面流 文献摘要 讨论|结论 预备知识 浅水方程SWE(Shallow Water Equations) 质量守恒方程: 动量守恒方程: Godunov通量法: 基本原理&…

分布式会话拦截器

1.分布式会话拦截器-构建拦截器 背景:对于不同的用户进行权限拦截(基于token的判断) 实现过程:在api下构建包以及相关的文件,创建UserTokenInterceptor,实现implements handlerInterceptor.重写三种主要方法。 preHandle postHandle afterCo…

MongoDB文档整理

过往mongodb文档: https://blog.csdn.net/qq_46921028/article/details/123361633https://blog.csdn.net/qq_46921028/article/details/131136935https://blog.csdn.net/qq_46921028/article/details/139247847 1. MongoDB前瞻 1、MongoDB概述: MongoDB是…

【Rust日报】在 Linux 文件系统中使用 Rust 的讨论

SIMD 加速的迭代器 单指令流多数据流(Single Instruction Multiple Data,缩写:SIMD)是一种采用一个控制器来控制多个处理器,同时对一组数据(又称"数据向量")中的每一个分别执行相同的…

PDF压缩软件电脑版 电脑pdf压缩怎么压缩文件

在数字化时代,pdf文件因其良好的兼容性和稳定性,已成为工作与生活中不可或缺的文件格式。然而,随着内容的增多,pdf文件的体积也随之增大,给文件的传输和存储带来了一定的困扰。本文将为你详细介绍如何在电脑上压缩pdf文…

【手撕数据结构】拿捏单链表

目录 单链表介绍链表的初始化打印链表增加节点尾插头插再给定位置之后插入在给定位置之前插入 删除节点尾删头删删除给定位置的节点删除给定位置之后的节点 查找节点 单链表介绍 单链表也叫做无头单向非循环链表,链表也是一种线性结构。他在逻辑结构上一定连续&…

昇思25天学习打卡营第10天 | FCN图像语义分割

学习心得:全卷积网络(FCN)在图像语义分割中的应用 图像语义分割作为计算机视觉领域的一个重要分支,对于理解图像内容提供了非常关键的技术支持。通过学习并实践全卷积网络(FCN)在图像语义分割的应用&#…