深入理解网络栈

news2024/11/25 16:44:55

网络路径

img

发送端

应用层

1、socket

各种网络应用程序基本上都是通过 Linux Socket 编程接口来和内核空间的网络协议栈通信的

socket 是网络编程的入口,它提供了大量的系统调用,构成了网络程序的主体

udp

UDP 是面向无连接的协议,不需要与服务端建立连接

img

tcp

对于 TCP socket 来说,应用调用 connect() API ,使得客户端和服务器端通过该 socket 建立一个虚拟连接。在此过程中,TCP 协议栈通过三次握手会建立 TCP 连接。默认地,该 API 会等到 TCP 握手完成连接建立后才返回

img

2、应用层处理流程

1、创建socket

每一个 userspace 网络应用创建的 socket,在内核中都有一个对应的 struct socket和 struct sock。

其中,struct sock 有三个队列(queue),分别是 rx , tx 和 err;

在 sock 结构被初始化的时候,这些缓冲队列也被初始化完成;

在收据收发过程中,每个 queue 中保存要发送或者接受的每个 packet 对应的 Linux 网络栈 sk_buffer 数据结构的实例 skb

2、sock_sendmsg 被调用,它使用 socket descriptor 获取 sock struct,创建 message header 和 socket control message

3、_sock_sendmsg 调用

(1)对于 TCP ,调用 tcp_sendmsg 函数。

(2)对于 UDP 来说,userspace 应用可以调send()/sendto()/sendmsg() 三个 system call 中的任意一个来发送 UDP message,它们最终都会调用内核中的 udp_sendmsg() 函数

传输层

目的

提供高效的、可靠的和成本有效的数据传输服务

功能

(1)构造 TCP segment

(2)计算 checksum

(3)发送回复(ACK)包

(4)滑动窗口(sliding windown)

tcp栈大概流程

img

1、tcp_sendmsg 函数会首先检查已经建立的 TCP connection 的状态,然后获取该连接的 MSS,开始 segement 发送流程。

2、构造 TCP 段的 playload:

它在内核空间中创建该 packet 的 sk_buffer 数据结构的实例 skb,从 userspace buffer 中拷贝 packet 的数据到 skb 的 buffer。

3、构造 TCP header。

4、计算 TCP 校验和(checksum)和 顺序号 (sequence number)。

(1)TCP 校验和是一个端到端的校验和,由发送端计算,然后由接收端验证。其目的是为了发现TCP首部和数据在发送端到接收端之间发生的任何改动。

如果接收方检测到校验和有差错,则TCP段会被直接丢弃。

TCP校验和覆盖 TCP 首部和 TCP 数据。

(2)TCP的校验和是必需的

(3)发到 IP 层处理:调用 IP handler 句柄 ip_queue_xmit,将 skb 传入 IP 处理流程。

UDP 栈简要过程

1、UDP 将 message 封装成 UDP 数据报

2、调用 ip_append_data() 方法将 packet 送到 IP 层进行处理。

网络层

目的

1、选择合适的网间路由和交换结点, 确保数据及时传送;

2、网络层将数据链路层提供的帧组成数据包,包中封装有网络层包头,其中含有逻辑地址信息- -源站点和目的站点地址的网络地址

功能

(1)路由处理,即选择下一跳

(2)添加 IP header

(3)计算 IP header checksum,用于检测 IP 报文头部在传播过程中是否出错

(4)可能的话,进行 IP 分片

(5)处理完毕,获取下一跳的 MAC 地址,设置链路层报文头,然后转入链路层处理。

ip头

img

IP 栈简要过程

img

1、首先,ip_queue_xmit(skb)会检查skb->dst路由信息。如果没有,比如套接字的第一个包,就使用ip_route_output()选择一个路由。

2、接着,填充IP包的各个字段,比如版本、包头长度、TOS等。

3、ip分片基本思想:当报文的长度大于mtu,gso的长度不为0就会调用 ip_fragment 进行分片,否则就会调用ip_finish_output2把数据发送出去

ip_fragment 函数中,会检查 IP_DF 标志位,如果待分片IP数据包禁止分片,则调用 icmp_send()向发送方发送一个原因为需要分片而设置了不分片标志的目的不可达ICMP报文,并丢弃报文,即设置IP状态为分片失败,释放skb,返回消息过长错误码。

4、接下来就用 ip_finish_ouput2 设置链路层报文头了。如果,链路层包头缓存有(即hh不为空),那就拷贝到skb里。如果没,那么就调用neigh_resolve_output,使用 ARP 获取。

数据链路层

目的

在物理层提供比特流服务的基础上,建立相邻结点之间的数据链路,通过差错控制提供数据帧(Frame)在信道上无差错的传输

功能

物理地址寻址、数据的成帧、流量控制、数据的检错、重发

网络设备抽象层

具体的物理网络设备在设备驱动中(driver.c)需要实现其中的虚函数

img

物理层

功能

1、物理层在收到发送请求之后,通过 DMA 将该主存中的数据拷贝至内部RAM(buffer)之中。在数据拷贝中,同时加入符合以太网协议的相关header,IFG、前导符和CRC。

对于以太网网络,物理层发送采用CSMA/CD,即在发送过程中侦听链路冲突。

2、一旦网卡完成报文发送,将产生中断通知CPU,然后驱动层中的中断处理程序就可以删除保存的 skb 了。

接受端

物理层和数据链路层

1、一个 package 到达机器的物理网络适配器,当它接收到数据帧时,就会触发一个中断,并将通过 DMA 传送到位于 linux kernel 内存中的 rx_ring

2、网卡发出中断,通知 CPU 有个 package 需要它处理。

中断处理程序主要进行以下一些操作:

分配 skb_buff 数据结构,并将接收到的数据帧从网络适配器I/O端口拷贝到skb_buff 缓冲区中;从数据帧中提取出一些信息,并设置 skb_buff 相应的参数,这些参数将被上层的网络协议使用,例如skb->protocol;

3、中断处理程序经过简单处理后,发出一个软中断(NET_RX_SOFTIRQ),通知内核接收到新的数据帧。

4、驱动有两种方式通知内核:

(1) 通过以前的函数netif_rx;

(2)通过NAPI机制。该中断处理程序调用 Network device的 netif_rx_schedule 函数,进入软中断处理流程,再调用 net_rx_action 函数。

5、net_rx_action函数关中断,获取每个 Network device 的 rx_ring 中的所有 package,最终 package 从 rx_ring 中被删除,进入 netif _receive_skb 处理流程。

6、netif_receive_skb 是链路层接收数据报的最后一站。它根据注册在全局数组 ptype_all 和 ptype_base 里的网络层数据报类型,把数据包递交给不同的网络层协议的接收函数(INET域中主要是ip_rcv和arp_rcv)。该函数主要就是调用第三层协议的接收函数处理该skb包,进入第三层网络层处理。

网络层

1、IP 层的入口函数在 ip_rcv 函数。

(1)包括 package checksum 在内的各种检查;

(2)如果需要的话会做 IP defragment(将多个分片合并);

(3)调用已经注册的 Pre-routing netfilter hook ,完成后最终到达 ip_rcv_finish 函数。

2、ip_rcv_finish 函数会调用 ip_router_input 函数,进入路由处理环节。

(1)会调用 ip_route_input 来更新路由;

(2)查找 route,决定该 package 将会被发到本机还是会被转发还是丢弃

A、如果是发到本机的话:

调用 ip_local_deliver 函数,可能会做 de-fragment(合并多个 IP packet);

然后调用 ip_local_deliver 函数。该函数根据 package 的下一个处理层的 protocal number,调用下一层接口,包括 tcp_v4_rcv (TCP), udp_rcv (UDP),icmp_rcv (ICMP),igmp_rcv(IGMP)。对于 TCP 来说,函数 tcp_v4_rcv 函数会被调用,从而处理流程进入 TCP 栈。

B、如果需要转发 (forward),则进入转发流程

该流程需要处理 TTL,再调用 dst_input 函数

该函数会 (1)处理 Netfilter Hook (2)执行 IP fragmentation (3)调用 dev_queue_xmit,进入链路层处理流程。

传输层

1、传输层 TCP 处理入口在 tcp_v4_rcv 函数(位于 linux/net/ipv4/tcp ipv4.c 文件中),它会做 TCP header 检查等处理。

2、调用 _tcp_v4_lookup,查找该 package 的 open socket。如果找不到,该 package 会被丢弃。接下来检查 socket 和 connection 的状态。

3、如果socket 和 connection 一切正常

(1)调用 tcp_prequeue 使 package 从内核进入 user space,放进 socket 的 receive queue(2)然后 socket 会被唤醒,调用 system call

 

 

(3)最终调用 tcp_recvmsg 函数去从 socket recieve queue 中获取 segment

应用层

1、每当用户应用调用 read 或者 recvfrom 时,该调用会被映射为/net/socket.c 中的 sys_recv 系统调用,并被转化为 sys_recvfrom 调用,然后调用 sock_recgmsg 函数。

2、对于 INET 类型的 socket,net/ipv4/af inet.c 中的 inet_recvmsg 方法会被调用,它会调用相关协议的数据接收方法。

3、对 TCP 来说,调用 tcp_recvmsg。该函数从 socket buffer 中拷贝数据到 user buffer。

4、对 UDP 来说,从 user space 中可以调用三个 system call recv()/recvfrom()/recvmsg() 中的任意一个来接收 UDP package,这些系统调用最终都会调用内核中的 udp_recvmsg 方法

参考链接

1、理解 Linux 网络栈(1):Linux 网络协议栈简单总结 - SammyLiu - 博客园 (cnblogs.com)

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

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

相关文章

CycleGAN论文的阅读与翻译,无监督风格迁移、对抗损失

CycleGAN论文的阅读与翻译,无监督风格迁移 CycleGAN 论文原文 arXiv CycleGAN junyanz,作者自己用 lua 在 GitHub 上的实现 CycleGAN tensorflow PyTorch by LynnHo,一个简单的 TensorFlow 实现 0. 摘要: 图像到图像的翻译 (Ima…

黑马大数据学习笔记2-HDFS基本操作

目录 进程启停管理一键启停脚本单进程启停 文件系统操作命令HDFS文件系统基本信息介绍创建文件夹查看指定目录下内容上传文件到HDFS指定目录查看HDFS文件内容下载HDFS文件拷贝HDFS文件追加数据到HDFS文件HDFS数据移动HDFS数据删除其他命令HDFS WEB浏览 HDFS权限修改权限 https:…

如何设计一个注册中心?(2)实现注册接口

1. 创建SpringBoot工程 创建父工程及三个子模块&#xff0c;其中一个模块作为注册中心&#xff0c;另外两个作为服务提供者。 pom <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns…

OpenCV for Python 入坑第三天 :图片处理(2)

上一篇博客我们了解了图像在OpenCV中的保存方式。并且我们自己上手创建了一张灰度图像和一张彩色图像。除此之外&#xff0c;我们还了解到了彩色图像通道在OpenCV中和我们日常所了解的不一样&#xff0c;是通过BGR的顺序进行编码的。咱们一定要记清楚哦~ 那么今天&#xff0c;我…

tinymce编辑器导入docx、doc格式Word文档完整版

看此文章之前需要注意一点 在前端使用导入Word文档并自动解析成html再插入到tinymce编辑器中&#xff0c;在这里我使用的是mammoth.js识别Word内容&#xff0c;并set到编辑器中&#xff0c;使用mammoth只可解析.docx格式的Word&#xff0c;目前的mammoth不支持.doc格式&#x…

Ghost Buster Pro for mac(快速清理卸载的应用残存文件)

Ghost Buster Pro for mac可从您已卸载的应用程序中查找并删除文件。该应用程序速度快如闪电&#xff0c;可立即释放内存。 许多应用程序都安装在计算机上&#xff0c;但它们通常只会在您的计算机上停留很短的时间。每个应用程序都会创建文件&#xff0c;但删除应用程序不会删…

01 - 如何制定性能调优标准?

1、为什么要做性能调优&#xff1f; 一款线上产品如果没有经过性能测试&#xff0c;那它就好比是一颗定时炸弹&#xff0c;你不知道它什么时候会出现问题&#xff0c;你也不清楚它能承受的极限在哪儿。 有些性能问题是时间累积慢慢产生的&#xff0c;到了一定时间自然就爆炸了…

使用dhtmlx-gantt甘特图插件定制预约表【实战】

示例传送门 定制预约表展示 一、安装 npm i dhtmlx-gantt二、配置解释与汇总 //自定义表头列 gantt.config.columns = [{name: "

服务器部署 Python 项目总结

title: 服务器部署 Python 项目总结 date: 2023-07-05 16:33:49 tags: 服务器Python categories:服务器 cover: https://cover.png feature: false 1. 准备 Python 项目需要 Python 的环境&#xff0c;假如服务器操作系统为 CentOS 7 的话&#xff0c;默认安装了 Python2 与 …

安达发|APS高级排程系统界的天花板!

APS 系统不仅为生产部门提供制造依据&#xff0c;而且涉及到采购计划、安全库存、订单交付等方面。这是非常复杂的管理。一个易于使用的 APS 系统不仅能够充分整合生产相关业务流程&#xff0c;保证生产计划的顺利进行&#xff0c;而且能够大大提高生产效率&#xff0c;降低管理…

导出python环境的所有安装包

导出操作 pip freeze > requests.txt批量导入操作 pip install -r requests.txt

redis数据类型基本操作(list,string,hash,keys相关操作),mongodb(增删改查)

1、 string类型数据的命令操作&#xff1a; &#xff08;1&#xff09; 设置键值&#xff1a; &#xff08;2&#xff09; 读取键值&#xff1a; &#xff08;3&#xff09; 数值类型自增1&#xff1a; &#xff08;4&#xff09; 数值类型自减1&#xff1a; &#xff08;5…

Java面试突击

Java面向对象有哪些特征&#xff0c;如何应用 ​ 面向对象编程是利用类和对象编程的一种思想。万物可归类&#xff0c;类是对于世界事物的高度抽象 &#xff0c;不同的事物之间有不同的关系 &#xff0c;一个类自身与外界的封装关系&#xff0c;一个父类和子类的继承关系&…

三菱PLC 控制灯一秒钟交替闪烁

三菱PLC中常用的特殊继电器&#xff1a; M8000 上电一直ON标志 M8002 上电导通一次 M8004 PLC出错 M8005 PLC备用电池电量低标志 M8011 10ms时钟脉冲 M8012 100ms时钟脉冲 M8013 1s时钟脉冲 M8014 1min时钟脉冲 M8034…

【论文笔记】图像修复MPRNet:Multi-Stage Progressive Image Restoration 含代码解析

目录 一、介绍 二、使用方法 1.推理 2.训练 三、MPRNet结构 1.整体结构 2.CAB(Channel Attention Block) 3.Stage1 Encoder 4.Stage2 Encoder 5.Decoder 6.SAM(Supervised Attention Module) 7.ORSNet(Original Resolution Subnetwork) 四、损失函数 1.Charbonni…

[LINUX]之grep文本过滤

linux通过使用grep -v操作来实现文本过滤 新创建文本如下 执行过滤命令如下&#xff0c;已经过滤了test3 cat test.txt |grep -v "test3"

Dockerd的迁移与备份

1、容器保存为镜像 &#xff08;1&#xff09; 通过以下命令将容器保存为镜像 # 保存nginx容器为镜像 docker commit 容器名称 镜像名称 例如&#xff1a;docker commit mynginx mynginx_i&#xff08;2&#xff09;用 docker ps -a 查看所有的容器 &#xff08;3&#xf…

15-C++基本算法-贪心法

&#x1f4da; 理论基础 贪心法&#xff08;Greedy Algorithm&#xff09;是一种常见的算法思想&#xff0c;它在每一步选择中都采取当前状态下最优的选择&#xff0c;以期望获得全局最优解。贪心法通常适用于问题具有最优子结构和贪心选择性质的情况。 适用场景 贪心法适用…

react 实现浮动可吸附悬浮窗,悬浮球,悬浮按钮,支持拖动拖拽功能(suspend-button)

前言&#xff1a; 最近在做移动端&#xff0c;有个需求是 实现一个浮动球可拖拽&#xff0c;能吸附&#xff08;吸附到 左右两则&#xff0c;距离哪进就吸附到哪边&#xff09;。 实现过程&#xff1a; 使用 suspend-button &#xff08;但是此组件不支持 ts 和pc端&#x…

VMWare安装统信UOS虚拟机

单击 创建新的虚拟机 按钮&#xff0c;然后选择 自定义&#xff0c; 然后 下一步 硬件兼容性 选择 Workstation16.x &#xff0c;然后 下一步 选择“稍后安装操作系统”&#xff0c; 然后 下一步 选择 Linux &#xff0c; 再选 版本 CentOS 8 64位/ Ubuntu 均可&#xff0c;然…