深入理解网络栈

网络路径

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.hqwc.cn/news/27995.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux的权限管理精细总结

(该图由AI绘制 关注我 学习AI画图) 目录 一、权限概述 1、权限的基本概念 2、为什么要设置权限 3、Linux用户身份类别 4、user文件拥有者 5、group文件所属组内用户 6、other其他用户 7、特殊用户root 二、普通权限管理 1、ls -l命令查看文件…

项目名称:无源在线词典项目

一,概述 基于C语言的网络电子词典项目,使用到了tcp协议的并发服务器设计、网络编程、文件I/O、数据库等多方面的知识。可以满足多用户同时登陆,用户登陆后可以查询单词及历史记录,具有查找快速,保密性好等优点。 开…

详细介绍MATLAB中的图论算法

MATLAB是一种功能强大的编程语言和环境,提供了许多用于图论算法的工具和函数。图论是研究图及其属性和关系的数学分支,广泛应用于计算机科学、网络分析、社交网络分析等领域。在MATLAB中,我们可以使用图论算法来解决各种问题,如最短路径问题、最小生成树问题、最大流问题等…

HDFS与MapResource笔记

客户端向NN请求上传文件 NN回应可以上传 请求上传块,返回DN 所以后面就比较慢 找最近的服务器进行 64K发到1节点,1节点立刻发给2节点,同时1节点自动开始落盘,这里,3个节点是同时落盘的. 因为缓存是在内存中,而持久化是将数据存到磁盘上. 副本节点选择: 1.安全:放不同机架 2.速…

Apache Knox Gateway

简介: Knox是一个提供认证和访问集群中hadoop服务的单个端点服务。目标是为用户和操作者简化hadoop安全。knox运行为一个服务或者集群服务,并提供集中访问一个或者多个hadoop集群。通常网关的目标如下: 1、为hadoop rest api 提供外层的安全…

深入篇【C++】谈vector中的深浅拷贝与迭代器失效问题

深入篇【C】谈vector中的深浅拷贝与迭代器失效问题 Ⅰ.深浅拷贝问题1.内置类型深拷贝2.自定义类型深拷贝 Ⅱ.迭代器失效问题1.内部迭代器失效2.外部迭代器失效 Ⅰ.深浅拷贝问题 1.内置类型深拷贝 浅拷贝是什么意思?就是单纯的值拷贝。 浅拷贝的坏处: ①…

力扣 860. 柠檬水找零

题目来源:https://leetcode.cn/problems/lemonade-change/description/ C题解:由于收到的钱币只有5,10,20三种,对于5元直接收,对于10元找零1张5元,对于20元找零15元,可以找零105或者…

echarts 横向柱状图 刻度标签

echarts 横向柱状图 刻度标签 怎么调试都不左对齐 将width去掉固定宽度 echarts会自适应

自来水收费系统适合应用于哪些场景?

自来水收费系统是一种用于自来水公司或供水管理部门的软件系统,旨在帮助自动化自来水的收费和管理过程。该系统可以帮助自来水公司更好地管理水资源,提高供水质量和效率,同时也可以为用户提供更加便捷和安全的用水服务。下面将从多个方面来介…

mysal数据库的日志恢复

目录 一 物理冷备份 二 mysqldump 备份与恢复(温备份) 三 mgsql中的增量备份需要借助mysql日志的二进制来恢复 小结 一 物理冷备份 systemctl stop mysqld yum -y install xz 压缩备份 tar Jcvf /opt/mysql_all_$(date %F).tar.xz /usr/local/mysql/…

Acwing.908 最大不相交区间数量(贪心)

题目 给定N个闭区间[ai,bi],请你在数轴上选择若干区间,使得选中的区间之间互不相交(包括端点)。输出可选取区间的最大数量。 输入格式 第一行包含整数N,表示区间数。 接下来N行,每行包含两个整数ai , bi&#xff0c…

Appium 全新 2.0 全新跨平台生态,版本特性抢鲜体验!

关于Appium V2 Appium V2 beta版本在2021年发布,从2022年1月1号开始,Appium核心团队不会再维护Appium 1.x版本了,所有近期官方发布的平台驱动(如Android平台的UIAutomator,IOS平台的XCUITest)不再兼容Appi…