Linux协议栈(8)——传输层实现

简介: Linux协议栈(8)——传输层实现 ip_local_deliver负责分发IP分组传输的数据内容。基于IP的主要传输协议分别是UDP和TCP。处理函数分别是udp_rcv和tcp_rcv。

Linux协议栈(8)——传输层实现

ip_local_deliver负责分发IP分组传输的数据内容。基于IP的主要传输协议分别是UDP和TCP。处理函数分别是udp_rcv和tcp_rcv。

1.1.1.1  接收

1.1.1.1.1          tcp接收

函数tcp_v4_rcv()定义在net/ipv4/tcp_ipv4.c中负责接收来自网络层的TCP数据包。相比UDP,TCP在内核中实现要困难得多,其状态转换如下图,珍藏多年的一张好图,高清图可以从网上下载。

0d62ad21bd0365c51b5165b09b6ae64f8ead0da2

  tcp报头定义在include/uapi/linux/tcp.h

struct tcphdr {         

        __be16  source; 

        __be16  dest;   

        __be32  seq;    

        __be32  ack_seq;

#if defined(__LITTLE_ENDIAN_BITFIELD)

        __u16   res1:4

                doff:4

                fin:1,  

                syn:1,

                rst:1,

                psh:1,  

                ack:1,

                urg:1,  

                ece:1,

                cwr:1;  

#elif defined(__BIG_ENDIAN_BITFIELD)

        __u16   doff:4,

                res1:4

                cwr:1,  

                ece:1,  

                urg:1,  

                ack:1,  

                psh:1,  

                rst:1,  

                syn:1,

                fin:1;  

#else 

#error  "Adjust your <asm/byteorder.h> defines"

#endif                  

        __be16  window; 

        __sum16 check;  

        __be16  urg_ptr;

};

tcp协议对象,位于net/ipv4/af_inet.c文件中

static struct net_protocol tcp_protocol = {

        .early_demux    =       tcp_v4_early_demux,

        .early_demux_handler =  tcp_v4_early_demux,

        .handler        =       tcp_v4_rcv,

        .err_handler    =       tcp_v4_err,

        .no_policy      =       1,  

        .netns_ok       =       1,  

        .icmp_strict_tag_validation = 1,

};

 在inet_init(net/ipv4/af_inet.c)函数中调用inet_add_protocol(net/ipv4/protocol.c)函数来添加协议。

  tcp定时器定义在net/ipv4/tcp_timer.c中,有四个定时器:重传定时器、延迟确认定时器、存活定时器、零窗口探测定时器。

TCP的接收入口是tcp_v4_rcv, 调用__inet_lookup_skb函数,该函数会调用__inet_lookup,调用

__inet_lookup_established函数,检测套接字,没有套接字就调用__inet_lookup_listener.

  根据链接的状态,如果sk->sk_state == TCP_LISTEN,调用tcp_v4_do_rcv,进入TCP状态自动机。

  代码流程图如下:

1a0a4cfe17067763a6885f11a905cc8483b3edab

 


1.1.1.1.2          udp接收

  udp_rcv是处理UDP数据包的函数,定义在net/ipv4/udp.c,该函数是__udp4_lib_rcv函数的包装函数。入参包含套接字缓冲区。会调用__udp4_lib_lookup_skb函数在udptable中找套接字,找到则调用udp_queue_rcv_skb函数。

            udp包头文件定义在:include/uapi/linux/udp.h 文件中。

struct udphdr {

        __be16  source;

        __be16  dest;

        __be16  len;

        __sum16 check;  

};


 f9ce1c7e4faf3f8bb48f33263184e2ed351e1477

1.1.1.2  发送

1.1.1.2.1          tcp发送分组

  tcp分组的发送从tcp_sendmsg函数调用开始。tcp_sendmsg(net/ipv4/tcp.c)函数会首先检查已经建立的 TCP connection 的状态,然后获取该连接的MSS,开始发送流程。

  构造 TCP 段的 playload:它在内核空间中创建该 packet 的 sk_buffer 数据结构的实例 skb,从 用户空间的 buffer 中拷贝 packet 的数据到 skb 的 buffer。构造 TCP header。

  计算 TCP 校验和(checksum)和 顺序号 (sequence number)。TCP的校验和是必需的。然后发到 IP 层处理:调用 IP handler 句柄 ip_queue_xmit,将 skb 传入 IP 处理流程。

  SOCK_STREAM类socket的TCP层操作函数集实例为tcp_prot定义在net/ipv4/tcp_ipv4.c文件中。之后调用tcp_write_xmit()来把sock发送队列中的skb尽量地发送出去。

传输层协议inet_sendmsg的proto指向的操作也不一样,而对于TCP协议,inet_sendmsg指向tcp_sendmsg函数,

 

1.1.1.2.2          udp发送分组
对于 UDP socket 来说, sendto 调用,真正去做工作的是 udp_sendmsg 这个函数 , 定义在 net/ipv4/udp.c文件中
目录
打赏
0
0
0
0
78
分享
相关文章
【Linux开发实战指南】基于UDP协议的即时聊天室:快速构建登陆、聊天与退出功能
UDP 是一种无连接的、不可靠的传输层协议,位于IP协议之上。它提供了最基本的数据传输服务,不保证数据包的顺序、可靠到达或无重复。与TCP(传输控制协议)相比,UDP具有较低的传输延迟,因为省去了建立连接和确认接收等过程,适用于对实时性要求较高、但能容忍一定数据丢失的场景,如在线视频、语音通话、DNS查询等。 链表 链表是一种动态数据结构,用于存储一系列元素(节点),每个节点包含数据字段和指向下一个节点的引用(指针)。链表分为单向链表、双向链表和循环链表等类型。与数组相比,链表在插入和删除操作上更为高效,因为它不需要移动元素,只需修改节点间的指针即可。但访问链表中的元素不如数组直接,通常需要从
382 2
【在Linux世界中追寻伟大的One Piece】HTTPS协议原理
【在Linux世界中追寻伟大的One Piece】HTTPS协议原理
82 2
扩展Linux网络栈
扩展Linux网络栈
144 3
【Azure 存储服务】如何把开启NFS 3.0协议的Azure Blob挂载在Linux VM中呢?(NFS: Network File System 网络文件系统)
【Azure 存储服务】如何把开启NFS 3.0协议的Azure Blob挂载在Linux VM中呢?(NFS: Network File System 网络文件系统)
111 0
在Linux中,我们都知道FTP协议有两种工作模式,它们的大概的⼀个工作流程是怎样的?
在Linux中,我们都知道FTP协议有两种工作模式,它们的大概的⼀个工作流程是怎样的?
在Linux中,我们都知道,dns采用了tcp协议,又采用了udp协议,什么时候采用tcp协议?什么 时候采用udp协议?为什么要这么设计?
在Linux中,我们都知道,dns采用了tcp协议,又采用了udp协议,什么时候采用tcp协议?什么 时候采用udp协议?为什么要这么设计?
在Linux中,TCP/IP协议栈的工作原理是什么?
在Linux中,TCP/IP协议栈的工作原理是什么?
【Linux】DNS系统,ICMP协议,NAPT技术详解
NAPT(Network Address Port Translation),也被称为端口地址转换,是一种NAT(网络地址转换)的形式。NAPT允许多个设备在内部网络上使用私有IP地址,并通过单个公共IP地址与外部网络进行通信。NAPT通过改变传输层的端口号来实现这一点,从而允许多个内部设备共享同一个公共IP地址。
113 0