Linux协议栈(3)——接收流程及函数

简介:

Linux协议栈(3)——接收流程及函数

本章来看下,数据是如何从网络中接收并最后到达应用程序的。

网络层将数据链路层提供的帧组成数据包,包中封装有网络层包头,其中含有逻辑地址信息。

1.1.1.1  链路层

包到达机器的物理网卡时候触发一个中断,并将通过DMA传送到位于 linux kernel 内存中的rx_ring。

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

然后发出一个软中断(NET_RX_SOFTIRQ,该变量定义在include/linux/interrupt.h  文件中),通知内核接收到新的数据帧。

  进入软中断处理流程,调用 net_rx_action 函数。包从 rx_ring 中被删除,进入 netif _receive_skb 处理流程。

netif_receive_skb根据注册在全局数组 ptype_all 和 ptype_base 里的网络层数据报类型,把数据报递交给不同的网络层协议的接收函数(INET域中主要是ip_rcv和arp_rcv)。

 

1.1.1.2  网络层

网络IP层的入口函数在ip_rcv函数。

ip_rcv函数调用第三层协议的接收函数处理该skb包,进入第三层网络层处理。

该函数首先会做包括checksum在内的各种检查,如果需要的话会做 IP defragment(分片合并),最终到达 ip_rcv_finish 函数。

  ip_rcv_finish 函数会调用ip_router_input函数,进入路由处理环节。会调用 ip_route_input 来更新路由,然后查找 route,决定该会被发到本机还是会被转发还是丢弃:

  如果发到本机的话,调用 ip_local_deliver 函数,可能会做 de-fragment(合并多个包),并调用ip_local_deliver_finish。最后调用下一层接口,包括 tcp_v4_rcv (TCP), udp_rcv (UDP),icmp_rcv (ICMP),igmp_rcv(IGMP)。对于 TCP 来说,函数 tcp_v4_rcv 函数会被调用,从而处理流程进入 TCP 栈。

  如果需要转发,则进入转发流程,调用 dev_queue_xmit,进入链路层处理流程。

       如果不是发送到本机的话就要进行转发,则调用ip_forward转发。

       如果是igmp管理数据包,则调用ip_mr_input函数进行组播路由的查找。

 

1.1.1.3  传输层

传输层 TCP 处理入口在tcp_v4_rcv函数(位于 linux/net/ipv4/tcp_ipv4.c 文件中),首先会做一些完整性检查,发现问题直接将包丢弃。

       如果是tcp,则调用tcp_v4_do_rcv

       然后sk->sk_state == TCP_ESTABLISHED,调用tcp_rcv_established。

       调用tcp_data_queue方法将报文放入队列中。然后用tcp_ofo_queue方法报文插入receive队列的。

 

1.1.1.4  应用层

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

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

  TCP 会调用 tcp_recvmsg。该函数从 socket buffer 中拷贝数据到buffer。

  UDP从用户空间可以调用三个recv()/recvfrom()/recvmsg() 中的任意一个来接收 UDP 包,这些系统调用最终都会调用内核中的 udp_recvmsg 方法。

       如下图:

919451da587b76dcbec78a579fcf2f67462ec0b4

网络子系统非常庞大,而且存在变化,后续会进行不断细化和更新。

目录
相关文章
|
8月前
|
存储 Linux
Linux环境下删除大文件后磁盘空间未释放问题诊断流程。
以上诊断流程涉及Linux底层机制与高级管理技能结合之处,并需要管理员根据实际环境灵活调整诊断策略与解决方案。
615 8
|
11月前
|
Linux 网络安全 iOS开发
SecureCRT & SecureFX 9.6.3 for macOS, Linux, Windows - 跨平台的多协议终端仿真和文件传输
SecureCRT & SecureFX 9.6.3 for macOS, Linux, Windows - 跨平台的多协议终端仿真和文件传输
2380 4
SecureCRT & SecureFX 9.6.3 for macOS, Linux, Windows - 跨平台的多协议终端仿真和文件传输
|
11月前
|
安全 网络协议 Linux
Linux网络应用层协议展示:HTTP与HTTPS
此外,必须注意,从HTTP迁移到HTTPS是一项重要且必要的任务,因为这不仅关乎用户信息的安全,也有利于你的网站评级和粉丝的信心。在网络世界中,信息的安全就是一切,选择HTTPS,让您的网站更加安全,使您的用户满意,也使您感到满意。
337 18
|
存储 Linux
linux中的目录操作函数
本文详细介绍了Linux系统编程中常用的目录操作函数,包括创建目录、删除目录、读取目录内容、遍历目录树以及获取和修改目录属性。这些函数是进行文件系统操作的基础,通过示例代码展示了其具体用法。希望本文能帮助您更好地理解和应用这些目录操作函数,提高系统编程的效率和能力。
449 26
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。
|
Linux
【Linux】System V信号量详解以及semget()、semctl()和semop()函数讲解
System V信号量的概念及其在Linux中的使用,包括 `semget()`、`semctl()`和 `semop()`函数的具体使用方法。通过实际代码示例,演示了如何创建、初始化和使用信号量进行进程间同步。掌握这些知识,可以有效解决多进程编程中的同步问题,提高程序的可靠性和稳定性。
959 19
|
Linux Android开发 开发者
linux m、mm、mmm函数和make的区别
通过理解和合理使用这些命令,可以更高效地进行项目构建和管理,特别是在复杂的 Android 开发环境中。
931 18
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
712 13
|
存储 Oracle 安全
服务器数据恢复—LINUX系统删除/格式化的数据恢复流程
Linux操作系统是世界上流行的操作系统之一,被广泛用于服务器、个人电脑、移动设备和嵌入式系统。Linux系统下数据被误删除或者误格式化的问题非常普遍。下面北亚企安数据恢复工程师简单聊一下基于linux的文件系统(EXT2/EXT3/EXT4/Reiserfs/Xfs) 下删除或者格式化的数据恢复流程和可行性。
|
监控 Java Linux
linux服务器上启动framework应用程序流程
【10月更文挑战第18天】在 Linux 服务器上启动框架应用程序的流程包括:准备工作(确保访问权限、上传部署文件、了解启动要求)、检查依赖项、配置环境变量、切换到应用程序目录、启动应用程序、监控启动过程以及验证应用程序是否正常运行。具体步骤可能因应用程序类型和框架而异。
206 0