TCP/IP协议
文章平均质量分 90
Blue summer
这个作者很懒,什么都没留下…
展开
-
数据包接收流程
1、数据包到达网卡设备2、收到数据后 网卡通过 DMA 将数据存到内存,也就是网卡的ring buffer中3、产生硬件中断,通知CPU处理数据报文4、CPU执行网络设备注册的中断处理函数,响应硬中断,将该设备添加到CPU轮询设备队列中,关闭网络设备中断响应,并唤醒软中断处理5、NAPI软中断处理例程从CPU的轮询队列中按额度从ring buffer中poll数据报文skb并递交上层协议栈...原创 2019-11-12 20:56:54 · 911 阅读 · 0 评论 -
Linux accept系统调用
注:本文分析基于3.10.0-693.el7内核版本,即CentOS 7.41、函数原型int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 参数说明:sockfd:套接字的文件描述符,socket()系统调用返回的文件描述符fdaddr:指向存放地址信息的结构体的首地址addrlen...原创 2018-06-08 22:46:18 · 11274 阅读 · 0 评论 -
Linux SYNACK报文的接收及ACK报文的发送
注:本文分析基于3.10.0-693.el7内核版本,即CentOS 7.4随着SYNACK报文的发送,连接建立随着第二次握手报文来到客户端。客户端接收到这个SYNACK报文,就认为连接建立了。仍然从TCP层开始分析,依然是由tcp_v4_rcv()入手。int tcp_v4_rcv(struct sk_buff *skb){... //根据报文的源和目的地址在establ...原创 2018-06-03 17:45:51 · 1795 阅读 · 0 评论 -
TCP SYNACK定时器梳理
注:本文分析基于3.10.107内核版本问题:在TCP建链的三次握手中,如果服务端回复的SYN+ACK报文在传输过程中丢失,或者客户端接收到这个SYN+ACK报文,但是第三次握手回复的ACK报文在传输过程中丢失了,服务端以什么样的方式感知,这条链接又如何结束?这便是SYNACK定时器的工作了。激活定时器在介绍listen()函数的backlog参数时,我们知道服务端接收到SYN...原创 2017-11-04 17:33:12 · 952 阅读 · 0 评论 -
Linux socket 数据发送类函数实现(一)
注:本文分析基于3.10.0-693.el7内核版本,即CentOS 7.4三次握手完成了,下面就该发送数据了。发送数据使用的函数有很多,比如send、sendto、sendmsg、sendmmsg,甚至还有write、wirtev等,那这些函数都是怎么将数据发送的呢,下面我们就来探个究竟。send()函数我们看看内核实现,SYSCALL_DEFINE4(send, int, ...原创 2018-08-24 12:09:41 · 3060 阅读 · 0 评论 -
Linux socket 数据发送类函数实现(二)
write()函数函数原型ssize_t write(int fd, const void *buf, size_t count);其中, fd为文件描述符,在socket编程中即为socket或者accept系统调用返回的网络文件描述符; buf是用户数据存储起始地址; count为用户数据长度。内核实现SYSCALL_DEFINE3(write, un...原创 2018-08-24 12:45:02 · 942 阅读 · 0 评论 -
Linux socket 数据发送类函数实现(三)
注:本文分析基于3.10.0-693.el7内核版本,即CentOS 7.4上回我们说到send四兄弟在sock_sendmsg()完成集合,write家族也在__sock_sendmsg()处等待。其实sock_sendmsg()的下一步就是进入__sock_sendmsg(),所以我们就从__sock_sendmsg()开始,带着这些兵马再次出发吧。int sock_sendm...原创 2018-09-09 13:06:39 · 1501 阅读 · 0 评论 -
Linux socket 数据发送类函数实现(四)
注:本文分析基于3.10.0-693.el7内核版本,即CentOS 7.4数据发送类函数流程梳理的也差不多了,用张图大概描述下这个过程,原创 2018-09-19 10:11:35 · 523 阅读 · 0 评论 -
为什么内核中TCP连接在第一次握手后没有进入SYN_RECV状态?
注:本文分析基于3.10.0-693.el7内核版本,即CentOS 7.4背景之前梳理TCP建链的过程时,发现一个问题,百思不得其解。各种文章和书籍里说的都是服务端在接收到客户端的SYN报文后就进入SYN_RECV状态,然而当我看内核源码时,发现却不是这样的。连接在第一次握手后还是保持LISTEN状态,只是请求被放入了半连接状态。等到第三次握手后,服务端才根据半连接队列里的请求重新构造一个s...原创 2018-09-21 17:14:31 · 2024 阅读 · 0 评论 -
Linux TCP连接建立时同时打开
static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, const struct tcphdr *th, unsigned int len){ struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *...原创 2018-09-30 13:52:15 · 855 阅读 · 0 评论 -
Linux 第三次握手ACK的接收和TCP连接建立完成
注:本文分析基于3.10.0-693.el7内核版本,即CentOS 7.4客户端发送第三个握手报文ACK报文后,客户端其实就已经处于连接建立的状态,此时服务端还需要接收到这个ACK报文才算最终完成连接建立。TCP层接收到ACK还是由tcp_v4_rcv()处理,这就是TCP层的对外接口。int tcp_v4_rcv(struct sk_buff *skb){... //根...原创 2018-06-03 22:54:55 · 660 阅读 · 0 评论 -
Linux SYN报文接收及发送SYNACK报文
注:本文分析基于3.10.0-693.el7内核版本,即CentOS 7.4在分析connect()系统调用时,我们已经发送SYN报文,所以服务端就需要作出回应了。我们依然只分析TCP层的操作。SYN报文到达TCP层由tcp_v4_rcv()接管。int tcp_v4_rcv(struct sk_buff *skb){ const struct iphdr *iph; ...原创 2018-06-03 10:43:39 · 2836 阅读 · 0 评论 -
Linux bind系统调用
注:本文分析基于3.10.0-693.el7内核版本,即CentOS 7.41、函数原型int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 参数说明:sockfd:套接字的文件描述符,socket()系统调用返回的fdaddr:指向存放地址信息的结构体的首地址addrlen:存放地...原创 2018-05-14 23:32:08 · 1087 阅读 · 1 评论 -
TCP 的backlog详解及半连接队列和全连接队列
注:本文分析基于3.10.107内核版本问题1:backlog是什么? 问题2:backlog怎么设置? 问题3:backlog怎么影响TCP的建链? 问题4:如何验证backlog的设置?以上就是我的疑问,因此我开始去从代码中了解backlog。man手册首先,要知道这个backlog是listen()函数里的第二个参数。int listen(int sockf...原创 2017-10-27 21:26:36 · 5651 阅读 · 5 评论 -
Linux socket系统调用(一)
注:本文分析基于3.10.107内核版本1、函数原型int socket(int domain, int type, int protocol);参数说明:domain:指定通信协议族。常用的协议族有AF_INET、AF_UNIX等,对于TCP协议,该字段应为AF_INET(ipv4)或AF_INET6(ipv6)。type:指定socket类型。常用的socket类型...原创 2018-02-24 00:11:31 · 6191 阅读 · 0 评论 -
Linux socket系统调用(二)----sock_alloc()
注:本文分析基于3.10.107内核版本当我们在进行网络编程时,socket系统调用是必不可少的一个步骤。socket系统调用返回的是一个fd,即一个文件描述符。其实它就只是一个int类型的数值,我们为什么能像操作文件一样进行读写呢?这就是VFS的功劳了,同时协议栈为了适配VFS虚拟文件系统实现了sockfs,最终使得我们可以像操作文件一样操作文件描述符。而实现socket和文件系统绑定的...原创 2018-02-22 16:08:40 · 1781 阅读 · 0 评论 -
Linux socket系统调用(三)----tcp_sock、sock、socket结构体以及TCP slab缓存建立
在内核协议栈初始化时—-inet_init()函数,注册了内置的几种协议(TCP,UDP,RAW,PING),同时为每种协议申请slab高速缓存。static int __init inet_init(void){... rc = proto_register(&tcp_prot, 1); if (rc) goto out_free_reserv...原创 2018-02-23 00:51:49 · 3796 阅读 · 0 评论 -
TCP FIN_WAIT2定时器
注:本文分析基于3.10.107内核版本之前我们一直考虑的是TCP建链过程中出现问题时,双方用户是如何感知,并处理的。在TCP建链的三次我手中主要是由超时重传定时器以及SYNACK定时器来进行链接状态的维护。下面我们来考虑一下在TCP四次挥手的断链过程中各个socket的状态维护和处理。在具体分析之前,我们来看下这四次挥手时双方socket状态的转换过程。借用下百科上的图,此次我们...原创 2018-02-27 10:46:23 · 1003 阅读 · 0 评论 -
Linux sockfd_lookup_light()----根据文件描述符fd获取socket结构体
注:本文分析基于3.10.0-693.el7内核版本,即CentOS 7.4在网络编程中,我们通过socket()系统调用分配一个fd,后续的操作都通过这个文件描述符fd实现。那内核是怎么通过这个文件描述符fd找到我们需要的socket结构体呢。下面就来看下sockfd_lookup_light()的实现。static struct socket *sockfd_lookup_ligh...原创 2018-03-22 16:03:23 · 3925 阅读 · 0 评论 -
Linux listen系统调用
注:本文分析基于3.10.0-693.el7内核版本,即CentOS 7.41、函数原型int listen(int sockfd, int backlog); 参数说明: sockfd:套接字的文件描述符,即socket()系统调用返回的fd backlog:保存客户端请求的队列长度listen()系统调用是比较简单的,但是涉及了backlog,这个参数是比较复杂的...原创 2018-04-08 17:48:41 · 1028 阅读 · 0 评论 -
Linux connect系统调用
注:本文分析基于3.10.0-693.el7内核版本,即CentOS 7.41、函数原型int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 参数说明:sockfd:套接字的文件描述符,socket()系统调用返回的fdaddr:指向存放地址信息的结构体的首地址addrlen:存放地址信息的结构体的大小,其实原创 2018-04-17 10:47:31 · 5258 阅读 · 0 评论 -
TCP TIME_WAIT定时器
注:本文分析基于3.10.107内核版本其实TIME_WAIT定时器是挺奇怪的,从名字上来看,是在socket进入TIME_WAIT之后工作的,但实际上并不是,或者说不全是,因为在FIN_WAIT2上也会使用TIME_WAIT定时器,正如之前讲述FIN_WAIT2定时器所描述。下面我们就来谈一谈TIME_WAIT定时器。注册其实TIME_WAIT定时器由两个定时器构成,在全局变...原创 2018-03-13 15:22:13 · 779 阅读 · 0 评论 -
TCP超时重传定时器梳理
注:本文分析基于3.10.107内核版本简介超时重传定时器是TCP连接可靠性的重要保证,其工作原理为TCP连接在发送某一个数据报文或者SYN报文后,该连接就会启动一个定时器,在规定时间内如果没有收到对端回复的ACK报文,那么定时器超时处理函数就重新发送数据,直到发送成功或者达到最大重传次数而上报错误为止。定时器类型一个TCP连接有多个定时器来保证TCP连接的可靠性及其传输效...原创 2017-10-14 15:32:32 · 5106 阅读 · 0 评论