TCP源码—连接建立
一、SYN报文处理:
公共部分:tcp_v4_rcv->tcp_v4_do_rcv->tcp_v4_cookie_check(无处理动作)->tcp_rcv_state_process->tcp_v4_conn_request[conn_request]->tcp_conn_request(传入两个参数tcp_request_sock_ops和tcp_request_sock_ipv4_ops,该函数内解析SYN报文的option,req初始化工作)
syncookie连接:inet_reqsk_alloc(创建request_sock)->[tcp_conn_request]tcp_v4_send_synack [send_synack](发送SYNACK)->tcp_make_synack->[tcp_conn_request]reqsk_free(syncookie下不保存request_sock,因此需要在这里进行释放)
TFO连接:inet_reqsk_alloc(创建request_sock)->[tcp_conn_request]tcp_try_fastopen(当不需要syncookie的时候尝试fastopen)->tcp_fastopen_create_child(设置TFO的重传定时器,接收随着SYN报文的数据)->tcp_v4_syn_recv_sock[syn_recv_sock]->tcp_create_openreq_child(创建SYN_RCVD状态的newsk,sock_copy复制listen状态的成员值)->[tcp_v4_syn_recv_sock]inet_ehash_nolisten(把newsk插入到ehash散列表)->[tcp_conn_request]tcp_v4_send_synack [send_synack](发送SYNACK)->tcp_make_synack->[tcp_conn_request]inet_csk_reqsk_queue_add(把req插入到accept队列)
普通连接:inet_reqsk_alloc(创建request_sock)->[tcp_conn_request]inet_csk_reqsk_queue_hash_add->reqsk_queue_hash_req(把req插入ehash散列表中并设置普通连接SYNACK的重传定时器)->inet_ehash_insert->[inet_csk_reqsk_queue_hash_add]inet_csk_reqsk_queue_added(更新半连接逻辑队列qlen的长度)->[tcp_conn_request]tcp_v4_send_synack [send_synack](发送SYNACK)->tcp_make_synack
tcp_conn_request:
1、判断是否使能syncookie,首先需要内核编译启用CONFIG_SYN_COOKIES选项,下面两种场景下会启用syncookie
tcp_syncookies=2
tcp_syncookies=1,半连接逻辑队列满、当前状态不是timewait转换过来的
2、accept队列满,且当前半连接队列有未重传的SYNACK请求,则直接丢弃SYN连接请求报文
3、非timwait切换非syncookie场景下,如果tcp_tw_recycle参数有效,则执行更严格的PAWS校验,如果tcp_tw_recycle无效且参数tcp_syncookies=0,则在半连接队列中预留1/4的空间给TCP metric中已经proved的destination。
二、SYNACK的处理
tcp_v4_rcv->tcp_v4_do_rcv->tcp_rcv_state_process->tcp_rcv_synsent_state_process
tcp_rcv_synsent_state_process:
ACK标志位有效的正常流程:
1、检测收到数据包的ack number、TSopt、RST、SYN等的有效性
2、初始化mtup、fack、mss等
3、调用tcp_finish_connect完成连接
4、如果是TFO,需要进入tcp_rcv_fastopen_synack处理TFO相关内容,如重传未被ACK的数据并重启重传定时器
5、如果写操作被挂起、或者TCP_QUICKACK选项设置为0、或者TCP_DEFER_ACCEPT设置为1,那么设置延迟ACK,正确节省一个ACK报文的消耗。
ACK标志位无效的时候
1、检测RST是否有效
2、进行paws检查
3、如果SYN标志位有效,则切换到TCP_SYN_RECV状态,发送SYNACK进行TCP同开的处理。
tcp_finish_connect:更新状态为TCP_ESTABLISHED
1、初始化metrics
2、触发拥塞控制模块init接口来进行拥塞控制模块的初始化
3、初始化rcvbuf和sndbuf
4、初始化keepalive
5、判断是否启动数据包处理的快速路径
6、通过sock_def_wakeup[sk->sk_state_change]唤醒等待的连接
sock_def_wakeup[sk->sk_state_change]
当sk被添加到prequeue或者backlog的时候最终会被tcp_v4_do_rcv处理,请参考release_sock
三、最后的ACK处理:
syncookie连接:tcp_v4_rcv->tcp_v4_do_rcv->tcp_v4_cookie_check->cookie_v4_check->inet_reqsk_alloc(创建request_sock)->[cookie_v4_check]tcp_get_cookie_sock->tcp_v4_syn_recv_sock[syn_recv_sock]->tcp_create_openreq_child(创建SYN_RCVD状态的newsk,sock_copy复制listen状态的成员值)->[tcp_v4_syn_recv_sock]inet_ehash_nolisten(把newsk插入到ehash队列)->[tcp_v4_do_rcv] tcp_child_process->tcp_rcv_state_process(把newsk从SYN_RCVD切换到ESTABLISHED)->sock_def_readable[parent->sk_data_ready](唤醒sk->sk_wq中的等待进程)
TFO连接:tcp_v4_rcv->tcp_v4_do_rcv(tcp_v4_rcv还可能切换到其他函数)->tcp_rcv_state_process[把TFO的sock从SYN_RCVD切换到ESTABLISHED]->tcp_check_req(仅做报文有效性检查会提前return,不处理defer_accept处理,也不调用tcp_v4_syn_recv_sock)->reqsk_fastopen_remove(从fastopen逻辑队列移除这个TFO连接)
普通连接:tcp_v4_rcv(查找之前创建并插入到ehash的request_sock,状态为NEW_SYN_RCVD)->tcp_check_req(报文有效性检测,如PAWS、系列号是否窗口内、纯SYN包的SYNACK重传处理、defer_accept处理等等)->tcp_v4_syn_recv_sock[syn_recv_sock]->tcp_create_openreq_child(创建SYN_RCVD状态的newsk,sock_copy复制listen状态的成员值)->[tcp_v4_syn_recv_sock]inet_ehash_nolisten(把newsk插入到ehash散列表,并替换出之前插入的req)->[tcp_check_req]inet_csk_complete_hashdance(更新半连接队列的长度qlen=qlen-1,并把req插入到accept队列)->[tcp_v4_rcv]tcp_child_process->tcp_rcv_state_process(把newsk从SYN_RCVD切换到ESTABLISHED)
tcp_v4_syn_recv_sock:
Accept队列满或者不能新建立newsk的时候返回Null,静默丢弃三次握手最后的ACK确认报文。
__inet_inherit_port[tcp_v4_syn_recv_sock]:
listen后建立的新连接不一定和listen的socket端口一致,tproxy场景可能不一致。
tcp_check_req:
接收到PAWS校验失败且系列号不相符的SYN报文时候,普通连接回复RST报文并从半连接队列删除req,TFO会把sock加入TFO RST逻辑队列
收到RST报文的时候,普通连接直接从半连接队列删除req并不回复RST,TFO会把sock加入TFO RST逻辑队列
四个队列:
Accept队列:表示等待用户层accept的连接,队列为icsk_accept_queue sk->sk_ack_backlog
半连接逻辑队列: 表示非TFO、非syncookie下的TCP普通连接,已经接收到SYN报文但是还没接收到SYNACK报文的SOCK数量,实际保存在ehash散列表中,队列长度(&inet_csk(sk)->icsk_accept_queue)->qlen
fastopen逻辑队列:表示接收到SYN报文但是还没有进入ESTABLISHED状态的TFO sock数量,TFO sock存在ehash散列表里面,队列长度(&inet_csk(sk)->icsk_accept_queue)->fastopenq.qlen tcp_fastopen_create_child中增加队列长度 当TFO连接进入ESTABLISHED或者直接进入FIN_WAIT1状态时候在reqsk_fastopen_remove函数中削减队列
fastopen rst队列:&inet_csk(sk)->icsk_accept_queue->fastopenq->{rskq_rst_head,rskq_rst_tail} RST处理的差异需要额外注意一下 存活60s。关于这个RST队列描述如下:
To protect the server, it is important to limit the maximum number of
total pending TFO connection requests, i.e., PendingFastOpenRequests
(Section 4.2). When the limit is exceeded, the server temporarily
disables TFO entirely as described in "Server Cookie Handling"
(Section 4.1.2). Then, subsequent TFO requests will be downgraded to
regular connection requests, i.e., with the data dropped and only
SYNs acknowledged. This allows regular SYN flood defense techniques
[RFC4987] like SYN cookies to kick in and prevent further service
disruption.
The main impact of SYN floods against the standard TCP stack is not
directly from the floods themselves costing TCP processing overhead
or host memory, but rather from the spoofed SYN packets filling up
the often small listener's queue.
On the other hand, TFO SYN floods can cause damage directly if
admitted without limit into the stack. The reset (RST) packets from
the spoofed host will fuel rather than defeat the SYN floods as
compared to the non-TFO case, because the attacker can flood more
SYNs with data and incur more cost in terms of data processing
resources. For this reason, a TFO server needs to monitor the
connections in SYN-RCVD being reset in addition to imposing a
reasonable max queue length. Implementations may combine the two,
e.g., by continuing to account for those connection requests that
have just been reset against the listener's PendingFastOpenRequests
until a timeout period has passed.
TCP源码—连接建立的更多相关文章
- TCP源码—epoll源码及测试
一.epoll_create & epoll_create1 SYSCALL_DEFINE1(epoll_create, int, size) sys_epoll_create->sys ...
- TCP源码—系统调用
1.socket SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) sys_socket->sock_create-& ...
- Linux进阶之Linux破解密码、yum源配置、防火墙设置及源码包安装
一.老师语录: 所有要求笔试的公司都是垃圾公司 笔试(是考所有的涉及到的点) 要有自己的卖点.专长(给自己个标签)(至少一个) 生产环境中,尽量使用mv(mv到一个没用的目录下),少使用rm 二.防火 ...
- Redis源码阅读---连接建立
对于并发请求很高的生产环境,单个Redis满足不了性能要求,通常都会配置Redis集群来提高服务性能.3.0之后的Redis支持了集群模式. Redis官方提供的集群功能是无中心的,命令请求可以发送到 ...
- TCP三次握手Linux源码解析
TCP是面向连接的协议.面向连接的传输层协议在原点和重点之间建立了一条虚拟路径,同属于一个报文的所有报文段都沿着这条虚拟路径发送,为整个报文使用一条虚拟路径能够更容易地实施确认过程以及对损伤或者丢失报 ...
- 我为 Netty 贡献源码 | 且看 Netty 如何应对 TCP 连接的正常关闭,异常关闭,半关闭场景
欢迎关注公众号:bin的技术小屋,本文图片加载不出来的话可查看公众号原文 本系列Netty源码解析文章基于 4.1.56.Final版本 写在前面..... 本文是笔者肉眼盯 Bug 系列的第三弹,前 ...
- TCP/UDP简易通信框架源码,支持轻松管理多个TCP服务端(客户端)、UDP客户端
目录 说明 TCP/UDP通信主要结构 管理多个Socket的解决方案 框架中TCP部分的使用 框架中UDP部分的使用 框架源码结构 补充说明 源码地址 说明 之前有好几篇博客在讲TCP/UDP通信方 ...
- 清晰易懂TCP通信原理解析(附demo、简易TCP通信库源码、解决沾包问题等)C#版
目录 说明 TCP与UDP通信的特点 TCP中的沾包现象 自定义应用层协议 TCPLibrary通信库介绍 Demo演示 未完成功能 源码下载 说明 我前面博客中有多篇文章讲到了.NET中的网络编程, ...
- tcprstat源码分析之tcp数据包分析
tcprstat是percona用来监测mysql响应时间的.不过对于任何运行在TCP协议上的响应时间,都可以用.本文主要做源码分析,如何使用tcprstat请大家查看博文<tcprstat分析 ...
随机推荐
- thinkphp5 toArray()报错
//DB操作返回是数组.模型直接操作返回是对象 //对象类型转换数组 //打开 database.php 增加或修改参数 'resultset_type' => '\think\Collecti ...
- tp js结合时间戳
$(document).ready(function(){ $.extend({ show:function(){ } }); setInterval("show()",1000) ...
- Window10 Electron 开发环境搭建及打包exe程序
1.安装 Electron 首先要安装Node.js (安装方法:https://www.cnblogs.com/inkwhite/p/9685520.html) 我这里已经安装好了. 2:安 ...
- 前端css之float浮动
浮动的准则,先找前一个块标签,在确认有否清除浮动的条件或者是距离的情况下,如果这一行能摆得下,就继续紧贴前一个标签 如果摆不下,就会另起一行 浮动只有左边和右边 如果是块标签,设置浮动,先把displ ...
- Node.js Express+Mongodb 项目实战
Node.js Express+Mongodb 项目实战 这是一个简单的商品管理系统的小项目,包含的功能还算挺全的,项目涵盖了登录.注册,图片上传以及对商品进行增.删.查.改等操作,对于新手来说是个很 ...
- 模仿淘宝首页写的高仿页面,脚本全用的原生JS,菜鸟一枚高手看了勿喷哈
自己仿照淘宝首页写的页面,仿真度自己感觉可以.JS脚本全是用原生JavaScript写得,没用框架.高手看了勿喷,请多多指正哈!先上网页截图看看效果,然后上源码: 上源码,先JavaScript : ...
- 成都Uber优步司机奖励政策(1月22日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- java 多维数组转化为字符串
int[][] a = {{1,2,3},{4,5,7}}; System.out.println(Arrays.deepToString(a)); Arrays.deepToString()此方法是 ...
- 汽车VIN码识别/汽车车架号OCR识别,移动端VIN码识别,OCR扫描工具
本文推荐了一项汽车VIN码自动识别技术,用户通过手机“扫一扫”的简单操作,就可以快速识别VIN码,查询到车辆的详细信息,为汽修汽配.二手车交易.车辆监管.查勘理赔提高工作效率. VIN是英文Vehic ...
- 前端开发工程师 - 03.DOM编程艺术 - 第1章.基础篇(上)
第1章.基础篇(上) Abstract:文档树.节点操作.属性操作.样式操作.事件 DOM (Document Object Model) - 文档对象模型 以对象的方式来表示对应的html,它有一系 ...