linux网络
文章平均质量分 72
fanxiaoyu321
天道酬勤
展开
-
linux网络校验和计算API
文章目录校验和算法IP首部校验和计算APIip_compute_csum()ip_fast_csum()ip_send_check()ip_decrease_ttl()通用校验和计算APIskb_checksum()csum_fold()csum_partial系列csum_block_add/sub()csum_add/sub()skb_checksum_help()csum_tcpudp_magic()校验和算法发送方先把校验和字段置为0,然后对参与校验的数据每16bit进行二进制反码求和,然后将结原创 2021-12-18 14:06:37 · 1786 阅读 · 0 评论 -
套接字缓存区sk_buff
文章目录数据结构缓存区: sk_buffskb指针: sk_buff_data_t协议头指针缓存区队列: sk_buff_headskb共享信息: skb_shared_info片段: skb_frag_t数据组织格式关于数据长度skb的分配alloc_skb()dev_alloc_skb()skb的释放skb_release_all()skb_release_head_state()skb_release_data()数据预留和对齐skb_reserve()skb_push()skb_put()skb_p原创 2021-12-15 02:03:50 · 2192 阅读 · 0 评论 -
TCP选项之SACK选项的接收(二)
这篇笔记记录了TCP在收到SACK选项后,对发送队列中skb的记分牌的更新细节。tcp_sacktag_skip()辅助函数tcp_sacktag_skip()遍历发送队列,直到某个skb的末尾序号(假设序号范围为[seq1, end1))end1大于等于目标值,并且将遍历过程中所有不满足条件的skb的非线性区间的段数累加到参数中。@skb:从该skb开始向后遍历,skb必须指向发送队列中的...原创 2019-03-15 23:59:17 · 780 阅读 · 0 评论 -
TCP选项之SACK选项的接收(一)
这篇笔记开始记录SACK选项的接收部分处理逻辑,这部分内容较多,会分成几篇来介绍。接收方对SACK信息的处理收到ACK段后,首先会用tcp_paser_options()解析输入段携带的选项信息,在该函数中,如果包含了SACK信息,那么skb的控制块的sacked字段就记录了SACK信息距TCP首部的偏移量,如果skb中没有SACK信息,则sacked字段为0.之后,在tcp_ack()的慢...原创 2019-03-15 01:07:46 · 4392 阅读 · 1 评论 -
TCP选项之SACK选项的接收(三)
标准的TCP确认机制中,如果发送方发送了0-1000序号之间的数据,接收方收到了0-100、300-1000,那么接收方只能向发送方确认101,这时发送方会重传所有101-1000之间的数据,实际上这是不必要的。为了优化这种情况,必须让发送方知道更多的接收信息,所以发展出了SACK选项,这篇笔记就来记录SACK相关内容,关于SACK的标准见RFC 2018。接收方对SACK信息的处理收到ACK...原创 2019-03-24 10:08:50 · 648 阅读 · 0 评论 -
TCP定时器之超时重传定时器
每条TCP连接都会维护一个超时重传定时器,该定时器是TCP保证可靠性的一个非常重要的手段,一旦该定时器超时,那么就会重传还未收到ACK的报文。这篇笔记就来看看该定时器相关的代码实现。1. 相关数据结构struct inet_connection_sock {... //icsk_retransmit_timer的超时时刻,jiffies超过该值时定时器超时 unsigned long ...原创 2019-03-09 12:26:24 · 5090 阅读 · 0 评论 -
TCP数据接收之清除发送队列
在ACK的确认过程中,需要做的非常重要的一件事就是将已经确认的数据从发送队列(以及重传队列)中删除,这是通过tcp_clean_rtx_queue()完成的。此外由于TCP在实现过程中,发送队列和重传队列都是sk_write_queue,所以这两个队列是一并处理的。这篇笔记就来看看发送队列的清除操作是如何实现的。1. tcp_clean_rtx_queue()/* Remove acknowl...原创 2019-03-02 13:54:29 · 2328 阅读 · 0 评论 -
TCP选项之SACK选项的发送
当接收方收到乱序报文时,如果在TCP握手过程中,双方都表示支持SACK选项,那么就会生成SACK选项信息,并且在下一次报文发送过程中将这些选项发送给发送方,这篇笔记记录了SACK选项的生成过程以及SACK选项的发送过程。1. 相关数据结构1.1 struct tcp_sockTCB结构中有如下字段和SACK选项的发送过程有关:struct tcp_sock {... //用户保存生成的...原创 2019-02-24 02:06:06 · 1025 阅读 · 0 评论 -
TCP之系统调用connect()之二
这篇笔记记录connect()系统调用的后半部分,即客户端收到SYN+ACK响应,然后回复ACK的部分。1. 客户端收到SYN+ACK报文发送SYN请求报文后,TCB的状态由TCP_CLOSE迁移到TCP_SYN_SENT,所以在收到接收响应后,将由tcp_rcv_state_process()处理。1.1 tcp_rcv_state_process()/* * This functio...原创 2018-12-23 12:06:16 · 1859 阅读 · 0 评论 -
TCP之系统调用connect()之一
客户端通过调用connect()系统调用建立与服务器的连接,对应到TCP协议层次,核心操作就是TCP的三次握手(从客户端角度),由于整个过程涉及内容较多,分两部分来看connect()的实现,这篇笔记是第一部分,包括系统调用入口以及SYN报文发送过程。1. 内核入口/* * Connect to a remote host. There is regrettably still a litt...原创 2018-12-22 23:00:37 · 7487 阅读 · 0 评论 -
TCP选项之MSS
1. 概述MSS(Maximum Segment Size,最大报文段大小)的概念是指TCP层所能够接收的最大段大小,该值只包括TCP段的数据部分,不包括选项部分。另外,在TCP首部有一个MSS选项,在三次握手过程中,TCP发送端使用该选项告诉对方自己所能接受的最大段大小。MSS选项虽然作为一个选项存在,原则上讲是可有可无的,但是目前绝大多数的TCP通信过程中都会携带该选项,所以可以说它是T...原创 2018-12-28 00:03:45 · 32016 阅读 · 1 评论 -
TCP之服务器端发送SYN+ACK报文
从《TCP之服务器端接收SYN请求段》中可以看到,当服务器端收到SYN包后,将会调用tcp_v4_send_synack()向客户端发送SYN+ACK报文,这篇笔记就来分析下这个过程。1. tcp_v4_send_synack()/* * Send a SYN-ACK after having received a SYN. * This still operates on a reque...原创 2018-12-16 20:00:03 · 6681 阅读 · 9 评论 -
TCP之服务器端接收SYN请求段
这篇笔记要说明的是TCP服务器端在收到客户端第一个SYN请求段时的处理过程,由于SYN请求段的处理过程属于TCP数据接收流程中的一部分,而接收流程非常的复杂,所以下面的代码流程只列出与本主题相关的内容。1. 接收SYN请求段TCP层的数据包输入接口为tcp_v4_rcv(),我们从这里看起:int tcp_v4_rcv(struct sk_buff *skb){ struct tcphd...原创 2018-12-16 19:14:33 · 2804 阅读 · 1 评论 -
TCP之系统调用listen()
这篇笔记记录了TCP协议对listen()系统调用的实现。1. 概述服务器端程序需要调用listen()系统调用将socket状态由TCP_CLOSE迁移到TCP_LISTEN,这样该套接字才能处理来自客户端的SYN请求。2. 监听套接字的管理为了查询方便,TCP协议将所有的监听套接字用全局的哈希表管理起来,哈希表信息如下:path: net/ipv4/tcp_ipv4.cstruct...原创 2018-12-16 13:35:26 · 2660 阅读 · 0 评论 -
TCP之连接请求队列
1. 概述TCP服务器端程序首先创建一个监听套接字,一旦有客户端连接该监听套接字,那么会创建一个新的通信套接字用来和客户端通信,而监听套接字继续等待其它客户端的连接请求。这期间就是三次握手过程,这个过程可能会失败,所以为了管理这期间的套接字,TCP协议特意定义了一组数据结构。这篇笔记的目的就是把这几个核心数据结构之间的关系理清楚,先来一张整体结构图,对着结构图看下面的数据结构定义会更容易理解。...原创 2018-12-16 12:23:29 · 1880 阅读 · 0 评论 -
TCP之系统调用bind()
这篇笔记记录了TCP协议对bind()系统调用的实现。1. 概述应用程序可以通过bind()系统调用将套接字和本地地址绑定,这里的地址包括L3的IP地址和L4的端口,应用程序可以只指定其中一个,另外一个由内核自动选择。这里我们不关注IP地址的绑定过程,因为这没什么好看的,就是校验地址合法性,然后保存到内核相关数据结构中即可;这里重点看L4端口的绑定过程。2. 端口信息的管理一般来讲,一个...原创 2018-12-15 22:47:47 · 6081 阅读 · 0 评论 -
TCP之系统调用accept()
这篇笔记来看看TCP对accept()系统调用的实现。在看这篇笔记之前,建议先看下《系统调用之listen.md》以及《TCP请求连接队列的管理》。1. 内核入口//从注释中也可以看出accept()系统调用要做的事情://1.建立一个新的套接字供服务器端和客户端通信//2.创建一个新的fd供应用程序后续读写该套接字/* * For accept, we attempt to crea...原创 2018-12-21 00:02:00 · 10758 阅读 · 0 评论 -
TCP之服务器端收到ACK包
这篇笔记记录的是服务器端收到TCP第三次握手的ACK包后的行为。1. 数据包入口在《TCP之服务器端接收SYN请求段》中,就有提到TCP对ACK包的处理是由tcp_v4_do_rcv()完成的,这里再次列出相关的核心代码:int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb){ struct sock *rsk; if (sk-...原创 2018-12-19 22:49:11 · 4915 阅读 · 0 评论 -
TCP数据发送之tcp_sendmsg()
这篇笔记记录的TCP协议对发送数据相关系统调用内核实现,虽然发送相关的系统调用接口由很多,但是到了TCP协议,都统一由tcp_sendmsg()处理。1. tcp_sendmsg()该函数要完成的工作就是将应用程序要发送的数据组织成skb,然后尽可能的发出去。@msg:要发送的数据;@size:本次要发送的数据量int tcp_sendmsg(struct kiocb *iocb, st...原创 2018-12-24 00:17:14 · 5115 阅读 · 1 评论 -
TCP数据发送之发送新数
在上一篇笔记TCP之数据发送(一)中介绍了TCP发送相关系统调用的内核核心处理函数tcp_sendmsg(),并且可以看出该函数做的核心工作就是将待发送的数据组织成一个个的skb,并且将这些skb按照先后顺序放入到TCB的发送队列sk_write_queue中。并且该函数也会尝试调用tcp_push()(以及其它两个接口)进行一次数据发送,这篇笔记就是要谈谈这部分数据发送相关的流程。tcp_se...原创 2019-01-05 10:23:42 · 3232 阅读 · 3 评论 -
TCP选项之SACK选项概述
标准的TCP确认机制中,如果发送方发送了0-1000序号之间的数据,接收方收到了0-100、300-1000,那么接收方只能向发送方确认101,这时发送方会重传所有101-1000之间的数据,实际上这是不必要的。为了优化这种情况,必须让发送方知道更多的接收信息,所以发展出了SACK选项,关于SACK的标准见RFC 2018。SACK在实际使用中是比较普遍的一个选项,而且相关的内容也较多,准备用三...原创 2019-02-21 23:53:40 · 21976 阅读 · 2 评论 -
TCP拥塞控制之理论基础
TCP的拥塞控制算法在不停的演进,这篇笔记按照演进顺序只介绍最基本的三个版本:Tahoe、Reno、New Reno。1. Tahoe这是TCP拥塞控制算法的第一个正式版本,其只有慢启动、拥塞避免、快速重传三个算法,没有快速恢复算法。对于慢启动和拥塞避免算法,大家耳熟能详,这里不再赘述,下面只说明快速重传算法和遇到拥塞后的具体表现。这个版本中将两种情况视为发生了拥塞:重传定时器超时;连...原创 2019-01-27 15:18:06 · 897 阅读 · 0 评论 -
TCP数据接收之慢速路径处理
由TCP数据接收之入口中看到,无论是哪个队列,最终都是调用tcp_v4_do_rcv()处理输入数据包,对于连接态,是由tcp_rcv_established()函数完成处理,这篇笔记就来看看该函数的实现。1. 慢速路径执行int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, struct tcphdr *th, u...原创 2019-03-01 00:20:45 · 952 阅读 · 0 评论 -
TCP数据接收之快速路径处理
1. 基本原理TCP的接收过程为什么要分为快速路径和慢速路径处理,如下面这段话所述:就是要高效,如果满足快速路径,那么在接收过程中就可以使用更少的检查条件。1.1 首部预测标记那么什么样的数据包是当前最期望收到的数据包呢?共有两种情况:如果才发送了数据,那么这时最期望收到的就是对刚发送数据的确认;如果只是接收场景,那么最期望收到的一定是以rcv_nxt为起始序号的数据包。如何来...原创 2019-02-24 00:48:51 · 1527 阅读 · 0 评论 -
TCP数据接收之入口
IP层组合出一包数据后,如果数据包首部的协议字段表明上层协议为TCP,则调用TCP的tcp_v4_rcv()函数将数据传递给传输层继续处理,传输层的整体处理过程是非常复杂的,这篇笔记就先来看看传输层的入口处是如何处理的。1. 三个队列TCP对输入数据包的整体处理流程可以简单的用下图表达:从上图中可以看到TCP的接收过程会涉及到三个队列:prequeue队列、receive队列以及backl...原创 2019-02-22 22:29:35 · 2693 阅读 · 1 评论 -
TCP拥塞控制之多算法支持
Linux内核是支持多种拥塞控制算法并存的,而且支持为不同的流使用不同的拥塞控制算法。这篇笔记就来介绍下内核是如何支持这种特性的。1. 数据结构每一种拥塞控制算法必须提供一个struct tcp_congestion_ops结构,然后向系统注册,系统将所有注册的拥塞控制算法组织成一个单链表。/* * Interface for adding new TCP congestion contr...原创 2019-01-31 22:58:36 · 1254 阅读 · 0 评论 -
TCP数据接收之ACK的处理
在TCP输入数据段的处理过程中,如果最终看到输入段携带了ACK信息,则会调用tcp_ack()进行相关处理,实际上,ACK总是会携带的,因为携带ACK不需要任何的附加开销,所以对于输入的每一个段(输了RST等特殊段),这个过程总是要执行的,这篇笔记就来看看这个处理过程。1. tcp_ack()/* This routine deals with incoming acks, but not o...原创 2019-01-30 00:22:11 · 9342 阅读 · 0 评论 -
TCP数据发送之发送窗口
TCP的发送过程由滑动窗口控制,而滑动窗口的大小受限于发送窗口和拥塞窗口,拥塞窗口由拥塞控制算法的代表,而发送窗口是流量控制算法的代表,这篇笔记记录了发送窗口相关的内容,包括发送窗口的初始化、更新、以及它是如何影响数据发送过程的。1. 概述TCP的发送窗口可以用下图表示:如图所示,TCB中有三个成员和发送窗口强相关。struct tcp_sock {... //下一个要发送的序号,即...原创 2019-02-26 00:07:12 · 9292 阅读 · 0 评论 -
TCP数据发送之TSO/GSO
TSO相关的内容充斥着TCP的整个发送过程,弄明白其机制对理解TCP的发送过程至关重要,这篇笔记就来看看TSO相关内容。1. 基本概念我们知道,网络设备一次能够传输的最大数据量是MTU,即IP传递给网络设备的每一个数据包不能超过MTU个字节,所以IP层分段和重组功能,这两个功能就是为了适配网络设备的MUT而存在的。从理论上来讲,TCP可以不关心MTU的限定,只需要按照自己的意愿随意的将数据包丢...原创 2019-02-26 00:07:25 · 7868 阅读 · 3 评论 -
套接口层之socket系统调用实现
这篇笔记记录了AF_INET协议族在套接口层对scoket()系统调用的实现,注意这里只介绍了套接口层的实现,相比于完整的socket()系统调用实现,这里缺少两部分内容:文件系统相关的部分,比如文件描述符的分配等;传输层的实现,套接字的创建肯定是要传输层参与的,但是不同的传输层处理方式又不同,这种协议差异会单独在相关笔记中介绍。socket()系统调用涉及的核心函数调用关系如下图:...原创 2018-10-20 13:25:52 · 635 阅读 · 0 评论