当前位置: 首页 > news >正文

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

深入理解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, unsignedint 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网络》。

相关文章:

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

深入理解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_…...

linux内核中list的基本用法

内核链表 1 list_head 结构 为了使用链表机制&#xff0c;驱动程序需要包含<linux/types.h>头文件&#xff0c;该文件定义了如下结构体实现双向链&#xff1a; struct list_head {struct list_head *next, *prev; };2 链表的初始化 2.1 链表宏定义和初始化 可使用以…...

项目中无关痛痒的词句背后深层含义

项目中听上去无关痛痒的词句背后&#xff0c;深层含义有的时候并不友善。 他们说的&#xff1a;进度表有些激进 真正的意思&#xff1a;我们有麻烦了 他们说的&#xff1a;我们将在接下来的几个迭代里面弥补延误 真正的意思&#xff1a;我们还是有麻烦 他们说的&#xff1…...

DLMS协议中的高级安全(HLS)身份验证

1.四步身份验证协议 在IEC 62056-53中已说明&#xff0c;ACSE提供部分高级身份安全&#xff08;HLS&#xff09;验证服务。高级身份安全验证适用于通信通道不能提供内部安全&#xff0c;应采取防范措施以防止偷听和信息&#xff08;密码&#xff09;重现的情况。这时&#xff…...

2024“钉耙编程”杭电多校1006 序列立方(思维+前缀和优化dp)

来源 题目 Problem Description 给定长度为 N 的序列 a。 一个序列有很多个子序列&#xff0c;每个子序列在序列中出现了若干次。 小马想请你输出序列 a 每个非空子序列出现次数的立方值的和&#xff0c;答案对 998244353 取模。 你可以通过样例解释来辅助理解题意。 Input 第…...

钡铼分布式I/O系统边缘计算Modbus,MQTT,OPC UA耦合器BL206

BL206系列耦合器是一个数据采集和控制系统&#xff0c;基于强大的32 位微处理器设计&#xff0c;采用Linux操作系统&#xff0c;支持Modbus&#xff0c;MQTT&#xff0c;OPC UA协议&#xff0c;可以快速接入现场PLC、DCS、PAS、MES、Ignition和SCADA以及ERP系统&#xff0c;同时…...

防火墙--双机热备

目录 双击热备作用 防火墙和路由器备份不同之处 如何连线 双机 热备 冷备 VRRP VGMP&#xff08;华为私有协议&#xff09; 场景解释 VGMP作用过程 主备的形成场景 接口故障的切换场景 整机故障 原主设备故障恢复的场景 如果没有开启抢占 如果开启了抢占 负载分…...

机器学习 -逻辑回归的似然函数

公式解释 公式如下&#xff1a; L ( θ ) ∏ i 1 m P ( y i ∣ x i ; θ ) ∏ i 1 m ( h θ ( x i ) ) y i ( 1 − h θ ( x i ) ) 1 − y i L(\theta) \prod_{i1}^m P(y_i | x_i; \theta) \prod_{i1}^m (h_\theta(x_i))^{y_i} (1 - h_\theta(x_i))^{1 - y_i} L(θ)i1∏…...

go 实现websocket以及详细设计流程过程,确保通俗易懂

websocket简介&#xff1a; WebSocket 是一种网络传输协议&#xff0c;可在单个 TCP 连接上进行全双工通信&#xff0c;位于 OSI 模型的应用层。WebSocket 协议在 2011 年由 IETF 标准化为 RFC 6455&#xff0c;后由 RFC 7936 补充规范。 WebSocket 使得客户端和服务器之间的数…...

记录工作中遇到的关于更新丢失商品超开的一个坑

场景&#xff1a; 工作中使用MybatisPlus以及Oracle进行数据库操作&#xff0c;收到RocketMQ消息开始并发分摊不同清货单的商品的批次&#xff0c;并对商品更新冻结数量。 上线后频繁出现商品超库存开票问题。&#xff08;还好是内部业务&#xff0c;人工替换批次记账即可&…...

形状之美:WebKit中CSS形状的实现与创新

形状之美&#xff1a;WebKit中CSS形状的实现与创新 在网页设计的世界里&#xff0c;CSS形状&#xff08;Shapes&#xff09;是一种革命性的特性&#xff0c;它允许开发者使用几何形状来创建复杂的布局结构。WebKit&#xff0c;作为现代浏览器的核心引擎之一&#xff0c;对CSS形…...

项目管理进阶之RACI矩阵

前言 项目管理进阶系列续新篇。 RACI&#xff1f;这个是什么矩阵&#xff0c;有什么用途&#xff1f; 在项目管理过程中&#xff0c;如Team规模超5以上时&#xff0c;则有必要采用科学的管理方式&#xff0c;满足工作需要。否则可能事倍功半。 Q&#xff1a;什么是RACI矩阵 …...

docker: No space left on device处理与迁移目录

简介&#xff1a;工作中当遇到Docker容器内部的磁盘空间已满。可能的原因包括日志文件过大、临时文件过多或者是Docker容器的存储卷已满&#xff0c;需要我们及时清理相关文件&#xff0c;并对docker的路径进行迁移。 历史攻略&#xff1a; centos&#xff1a;清理磁盘空间 …...

设计模式使用场景实现示例及优缺点(结构型模式——外观模式)

在一个繁忙而复杂的城市中&#xff0c;有一座名为“技术森林”的巨大图书馆。这座图书馆里藏着各种各样的知识宝典&#xff0c;从古老的卷轴到现的电子书籍&#xff0c;无所不包。但是&#xff0c;图书馆之所以得名“技术森林”&#xff0c;是因为它的结构异常复杂&#xff0c;…...

Artix7系列FPGA实现SDI视频编解码+UDP以太网传输,基于GTP高速接口,提供工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本博已有的以太网方案本博已有的FPGA图像缩放方案本方案的缩放应用本方案在Xilinx--Kintex系列FPGA上的应用本方案在Xilinx--Zynq系列FPGA上的应用 3、详细设计方案设计原理框图SDI 输入设备Gv8601a 均衡…...

加拿大上市药品查询-加拿大药品数据库

在加拿大&#xff0c;药品的安全性、有效性和质量是受到严格监管的。根据《食品药品法案》的规定&#xff0c;所有药品制造商必须提供充分的科学证据&#xff0c;证明其产品的安全性和有效性。为此&#xff0c;加拿大卫生部建立了一个全面的药品数据库 &#xff08;DPD) &#…...

qt自定义控件(QLabel)

先创建自定义控件类painter_label 1.自定义类必须给基类传入父窗口指针 2.重写控件中的方法 3.在UI中创建一个QLabel,右键“提升为”&#xff0c;输入类名...

阿里云国际站:海外视频安全的DRM加密

随着科技的进步&#xff0c;视频以直播或录播的形式陆续开展海外市场&#xff0c;从而也衍生出内容安全的问题&#xff0c;阿里云在这方面提供了完善的内容安全保护机制&#xff0c;适用于不同的场景&#xff0c;如在视频安全提供DRM加密。 由图可以了解到阿里云保护直播安全的…...

【Apache Doris】周FAQ集锦:第 15 期

【Apache Doris】周FAQ集锦&#xff1a;第 15 期 SQL问题数据操作问题运维常见问题其它问题关于社区 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目&#xff01; 在这个栏目中&#xff0c;每周将筛选社区反馈的热门问题和话题&#xff0c;重点回答并进行深入探讨。旨在为广大用户…...

verilog实现ram16*8 (vivado)

module ram_16x2 (input clk, // 时钟信号input we, // 写使能input en, // 使能信号input [3:0] addr, // 地址线input [1:0] datain, // 输入数据线output reg [1:0] dataout // 输出数据线 );// 定义存储器数组reg [1:0] mem [15:0];always (posedge…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...