TCP系列10—连接管理—9、syncookie、fastopen与backlog
这部分内容涉及较多linux实现,可以跳过。
一、listen系统调用对backlog的处理
当socket处于LISTEN或者CLOSED状态时,fastopen队列的长度可以通过TCP_FASTOPEN选项进行设置。
-
对于listen的入参backlog,内核会限制backlog=min(backlog,/proc/sys/net/core/somaxconn)
如果当前打开了TFO的server端开关(tcp_fastopen的0x2有效),并且fastopen队列的最大长度还没通过选项设置,此时若tcp_fastopen的0x400有效,则初始化fastopenq.max_qlen=backlog,若tcp_fastopen的0x800有效,则初始化fastopenq.max_qlen=min(backlog,tcp_fastopen>>16)。fastopenq.max_qlen限制了fastopen逻辑队列和fastopen的RST队列的总长度。
更新sk->sk_max_ack_backlog = backlog,sk_max_ack_backlog同时限制了半连接逻辑队列和accept队列的长度。
Accetp队列判断条件是>,半连接逻辑队列和fastopen判断条件是>=
二、对SYN报文的处理
当内核编译打开CONFIG_SYN_COOKIES选项的时候,只要满足下面两个条件中的一个则启用syncookie:
①、tcp_syncookies为2。
②、tcp_syncookies为1,半连接逻辑队列满,SYN报文不是timewait转过来的。
如果半连接队列满,且这个SYN报文不是timewait转过来的,这种场景下,如果tcp_syncookies=0,则会直接丢掉这个SYN报文。
如果全连接队列满,并且半连接逻辑队列中还有未重传的synack报文,那么直接丢掉这个syn报文。
当依据上面判断不需要启用syncookie的时候,则会判断是否使能fastopen,其中当fastopen逻辑队列和fastopen的RST队列总长度超过fastopenq.max_qlen并且fast open的rst队列没有可以释放的节点的时候,则不会启用fastopen。
如果启动了syncookie,那么req使用后会释放,不会添加到半连接逻辑队列也不会添加到accept队列
如果启用了fastopen,那么req将会直接添加到accept队列,如果accept队列满,则启动fastopen队列失败。
如果未启动syncookie也未启用fastopen,那么把req添加到半连接逻辑队列
三、三次握手最后ACK的处理
如果在处理SYN报文的时候,启用了syncookie,此时校验syncookie通过,但是accept队列满的时候,丢弃报文。
fastopen在接收到SYN报文的时候就已经处理了半连接逻辑队列和accept队列。
如果对应的连接即没有启用syncookie,也没有启用fastopen,那么accept队列满的时候按照如下处理
tcp_abort_on_overflow=0场景下,直接丢掉这个报文
tcp_abort_on_overflow=1场景下,回复RST。
补充:
另外reqsk_timer_handler重传函数中,如果(qlen << 1) > max(8U,sk_max_ack_backlog),即半连接队列已经使用了一半以上的时候,则会对重传次数进行回退。
另外还有一个设置参数:tcp_max_syn_backlog,当设置tcp_syncookies=0来关闭syncookie功能的时候,如果半连接请求队列的长度超过了(3/4)*tcp_max_syn_backlog,那么新接收的SYN报文需要在tcp_metric缓存中验证通过后才能接收这个连接,否则直接丢掉SYN报文。
四、wireshark示例
1、默认设置下tcp_syncookies=1、tcp_abort_on_overflow=0,listen入参backlog设置为5,场景如下图所示,当启用syncookie的时候,TSval的低四位表示接收到的window scale,第五位表示SACK,第六位表示ECN。
首先No1、No3、No5、No7、No9五个数据包填满了半连接逻辑队列,因此从下图Timestamp value列可以看到No11、No13、No15、No17启用了syncookie。
接着No19报文把20001端口对应的连接从半连接队列转移到了accept队列。此时半连接逻辑队列空闲出一个位置。
No20这个SYN报文对应的req重新添加到了半连接队列,可以从图中看到并没有启用syncookie。
No22-No25这几个数据包对应的连接之前位于半连接对应,可以被server正常接收处理并建立连接。
No26:这个对应之前启用了syncookie的No11,因为accept队列满的判断标准是大于等于,因此accept队列相比半连接队列可以多接收一个连接,No26正常建立连接。
No27、No28、No29、No32:这几个报文同样因为accept队列满而不能建立连接。但是No32报文对应的连接保存于半连接队列中,而No27-No29是通过syncookie响应的SYN报文。至此总共建立了6个连接,对应client端口号为20001-20006。
接着client尝试发送数据的时候可以看到,对应端口20007-20010的client数据包No43-No46,server端都没有响应,说明连接并没有建立起来。
No47-No51:因为端口20010的连接存在于半连接队列中,因此会触发synack的重传。而端口20007-20009的连接通过syncookie响应SYN连接请求,并不会触发synack重传。
2、设置tcp_syncookies=1、tcp_abort_on_overflow=1,重复上面的测试,唯一的差异就在于端口号为20010的连接。如下图所示,因此该连接处于半连接逻辑队列里面,而server端接收到三次握手的ACK报文的时候全连接队列满,因此直接回复RST,abort这个连接。
TCP系列10—连接管理—9、syncookie、fastopen与backlog的更多相关文章
- TCP系列07—连接管理—6、TCP连接管理的状态机
经过前面对TCP连接管理的介绍,我们本小节通过TCP连接管理的状态机来总结一下看看TCP连接的状态变化 一.TCP状态机整体状态转换图(截取自第二版TCPIP详解) 二.TCP连接建立 ...
- TCP系列05—连接管理—4、TCP连接的ISN、连接建立超时及TCP的长短连接
一.TCP连接的ISN 之前我们说过初始建立TCP连接的时候的系列号(ISN)是随机选择的,那么这个系列号为什么不采用一个固定的值呢?主要有两方面的原因 防止同一个连接的不同实例(di ...
- TCP系列02—连接管理—1、三次握手与四次挥手
一.TCP连接管理概述 正如我们在之前所说TCP是一个面向连接的通信协议,因此在进行数据传输前一般需要先建立连接(TFO除外),因此我们首先来介绍TCP的连接管理. 通常一次完整的TCP数据传输一般包 ...
- TCP系列03—连接管理—2、TCP连接的同时打开和同时关闭
在前面的内容中我们介绍了TCP连接管理中最常见的三次握手方式和四次挥手的方式.但是有可能A和B两端同时执行主动打开并连接对方或者同时执行主动关闭连接(尽管发生这种情况的可能性比较低低),这个时候的流程 ...
- TCP系列04—连接管理—3、TCP连接的半打开和半关闭
在前面部分我们我们分别介绍了三次握手.四次挥手.同时打开和同时关闭,TCP连接还有两种场景分别是半打开(Half-Open)连接和半关闭(Half-Close)连接.TCP是一个全双工(Full-Du ...
- TCP系列06—连接管理—5、TCP fastopen(TFO)
一.TFO背景 当前web和web-like应用中一般都是在三次握手后开始数据传输,相比于UDP,多了一个RTT的时延,即使当前很多应用使用长连接来处理这种情况,但是仍然由一定比例的短连接,这额外多出 ...
- TCP系列08—连接管理—7、TCP 常见选项(option)
一.TCP选项概述 在前面介绍TCP头的时候,我们说过tcp基本头下面可以带有tcp选项,其中有些选项只能在连接过程中随着SYN包发送,有些可以延后.下表汇总了一些tcp选项 其中我标记为红色的部分是 ...
- TCP系列09—连接管理—8、TCP Reset
我们在介绍TCP头的时候,提到过其中有个RST标志位.当一个TCP报文中这个标志位打开的时候,我们叫做reset包(严格的说应该叫做reset段,但是很多时候段包帧并不加以区分)或者简单称呼为rese ...
- TCP的运输连接管理
TCP的运输连接管理 TCP是面向连接的协议,有三个阶段:连接建立.数据传送 和 连接释放.运输连接的管理就是使运输连接的简历和释放都能正常地进行. 在TCP连接建立过程中要解决一下三个问题: 1. ...
随机推荐
- 一台ECS服务器,部署多(两)应用,且应用配置不同域名
场景 产品环境服务器有两台,前后端各分配一台服务器.现在在不增加机器的情况下,需要增加部署一套服务给台北地区服务. 现有的前端部署方案. 产品环境部署方案详解 实现 配置NAT步骤 ECS配置多网卡, ...
- Mac下PHP的环境搭建
* 前段时间手欠 ... 入手了一个二手的Macbook pro ! 配置挺高的 16款13寸的基本顶配了 ... 只差 硬盘不是1T的 ... 可以脑补一下配置了* 话说 不是所有程序猿都说 每个程 ...
- 解决thinkphp query()执行原生SQL语句成功结果报错的问题
1.query方法 query方法用于执行SQL查询操作,如果数据非法或者查询错误则返回false,否则返回查询结果数据集(同select方法). 2.execute方法 execute用于更新和写入 ...
- 基于Python的飞机大战游戏
前几天决定学Python,上网找了教程看了两天,和C比起来面向对象的特性真的都很便捷,有了类开发各种敌机,子弹什么的都很方便. 在此要感谢开发pygame模块的开发人员,真的很好用(逃 效果图↓ 主函 ...
- Vi中进行多行指定内容替换
1.先按Esc进入命令模式,然后在打出‘:’(英文输入模式下) 2.输入格式: 首行数,末行数s/要替换的字符串/替换的字符串/g (不加g只替换每行的一个要替换的字符串,后面的不会替换) e ...
- Python写网络后台脚本
Python写网络后台脚本. 首先安装Python3.6.5,在centos中自带的Python是2.6版本的,现在早就出现了3.6版本了况且2和3 之间的差距还是比较大的,所以我选择更新一下Pyth ...
- HDU3394 点双连通分量
Railway Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- Windows下的SysWow64和System32
64位的Windows并不是简单地把所有东西都编译成64位就万事大吉的.关于64位的CPU应该做成什么样子,Intel和AMD曾有各自的打算.AMD的回答直接了当:新的64位处理器,应该能在提高更高处 ...
- SpringCloud Eureka 服务注册与服务发现
一.Eureka简介 spring Cloud Netflix技术栈中,Eureka作为服务注册中心对整个微服务架构起着最核心的整合作用.有了服务发现与注册,你就不需要整天改服务调用的配置文件了,你只 ...
- WSL跑linux服务程序
前段时间折腾了一次WSL下的Apache,无奈遇到各种奇葩问题,总是解决不了,最终放弃,甚至得出了一个现在看来比较可笑的结论:WSL是不可能跑Linux服务程序的! 当时的思路想歪了,由于Apache ...