TCP快速重传触发条件的一个细节
倒数第二个工作日,拒绝午饭!撰文以记之。
浙江温州皮鞋湿,下雨进水不会胖!
前几日和前同事聊天聊到一个Linux内核协议栈实现中关于TCP快速重传触发条件的一个细节,觉得比较有意思。
这个细节是这样的。
且看tcp_ack中,如果我们发现该ACK所携带的信息是 可疑的, 那么逻辑就会进入到进一步的筛选判断中,以最终抉择 是不是要让该TCP连接的拥塞状态机从Open切换到Disorder或者Recovery状态。
我们看一卡这个 可疑的 其判断标准是什么。
#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED)
#define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE)
...
static inline bool tcp_ack_is_dubious(const struct sock *sk, const int flag)
{return !(flag & FLAG_NOT_DUP) || (flag & FLAG_CA_ALERT) ||inet_csk(sk)->icsk_ca_state != TCP_CA_Open;
}
FLAG_CA_ALERT这个倒是很明确,只要携带了SACK,或者显式的拥塞标志,那肯定是可疑的,需要进一步判断。
这里比较有意思的是:
为什么只要携带FLAG_DATA标志可以代表NOT_DUP?
比较明显的疑点就是,在关闭SACK支持的情况下,如果一个双向传输的TCP连接,对端每次都发送点数据过来,那么本端岂不是永远都不会被触发快速重传吗?
简单点说是这样的,确实是只要对端发送数据过来,就不会进入tcp_ack_is_dubious分支,进而不会触发快速重传。
编写下面的packetdrill脚本以验证事实:
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0+0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7>
+0 > S. 0:0(0) ack 1 <...>+0 < . 1:1(0) ack 1 win 257
+0 accept(3, ..., ...) = 4// Send 1 data segment and get an ACK, so cwnd is now 4.
+0 write(4, ..., 1000) = 1000
+0 > P. 1:1001(1000) ack 1+0 < . 1:1(0) ack 1001 win 257// Write 4 data segments.
+0 write(4, ..., 4000) = 4000
+0 > P. 1001:5001(4000) ack 1// Get 3 SACKs.
//
+0 < . 1:11(10) ack 1001 win 257 <sack 2001:3001,nop,nop>
+0 < . 11:21(10) ack 1001 win 257 <sack 2001:4001,nop,nop>
+0 < . 21:31(10) ack 1001 win 257 <sack 2001:5001,nop,nop>
// net.ipv4.tcp_sack=0时,这里没有快速重传,这里超时
// net.ipv4.tcp_sack=1时,这里触发了快速重传,因为FLAG_CA_ALERT置位。// Receiver ACKs all data.
+10 < . 1:1(0) ack 6001 win 257
这是一个问题吗?如果是问题为什么多年以来Linux的TCP实现一直这么写。
仔细思考了一下这个问题,最后发现其实这不是问题。
TCP是全双工通信协议,它原本应该全双工两个方向独立进行传输/确认,为了提高资源利用率,实施了 捎带确认 的逻辑,也就是说,捎带确认只是一个优化,而不是与生俱来的。
在开启SACK支持时,捎带确认中埋藏SACK告诉反方向的一端说可能有拥塞丢包,那这只是一种友情协助,并不是人家的义务。而关闭SACK支持时,无论如何捎带确认也无法明确告知反方向数据包可能丢包或者乱序了…
换句话说, 只有3次重复ACK明确是由本端发送的数据包所触发的时候,才会去进一步判断是否要快速重传,否则在可疑判断时将会直接放行!
显然,携带数据的包是对端主动发送的,而其携带的ACK属于捎带确认,不属于本端触发的确认,因此不会被认为是重复ACK。
如果我们不区分 捎带确认 和 数据接收触发的确认 会怎样呢?下图示之:
为了在 可疑异常 情况下可以尽快让 数据接收触发的确认 反馈到发送端,RFC规定, 可疑异常情况下的数据接收触发的确认,不允许捎带!必须立刻发送!
从小没咋放过鞭炮,也没咋吃过一家人一起的除夕团圆饭,所以不知年味儿,虽然如此,我还是祝福每一个人,每一个家庭都能团团圆圆,幸运美满,明年获得更多的幸福收获!
浙江温州皮鞋湿,下雨进水不会胖!
TCP快速重传触发条件的一个细节相关推荐
- 关于TCP快速重传的细节-重传优先级与重传触发条件
这篇文章写的有点过于细节,因此考虑到可读性和日后的可查阅性,我以两个问题作为引子.作为TCP相关项目的招聘,也可以作为面试题,不过,我敢肯定,大多数人都不能回答第一个问题,第二个问题可能会模棱两可. ...
- 通过packetdrill构造的包序列理解TCP快速重传机制
TCP的逻辑是极其复杂的,其学习曲线虽然很平缓但其每一步都是异常艰难,好在这些都是体力活,只要肯花时间也就不在话下了.想彻底理解一个TCP的机制,有个四部曲: 1.读与其相关的RFC: 2.看Linu ...
- TCP快速重传为什么是三次冗余ack,这个三次是怎么定下来的?
先理解ACK的基本工作原理,当发送端发送第N-1个包后,接收端答复的ACK序列号实际上跟发送端发送下一个包,也就是第N个包的序列号一致. 假设有个主机ISN是5000,发送500字节报文至接收方.一旦 ...
- TCP快速重传为什么是三次冗余ack
先理解ACK的基本工作原理,当发送端发送第N-1个包后,接收端答复的ACK序列号实际上跟发送端发送下一个包,也就是第N个包的序列号一致. 重复ACK是指在接收方收到乱序报文时,所发出的一类TCP报文. ...
- TCP 是一个可靠传输的协议,那我们来重点介绍 TCP 的重传机制、滑动窗口、流量控制、拥塞控制。
TCP 巨复杂,它为了保证可靠性,用了巨多的机制来保证,真是个「伟大」的协议,写着写着发现这水太深了... 本文的全部图片都是小林绘画的,非常的辛苦且累,不废话了,直接进入正文,Go! 相信大家都知道 ...
- TCP的拥塞避免、超时重传、快速重传、快速恢复
转自:http://blog.csdn.net/itmacar/article/details/12278769 感谢博主的辛勤成果! 为了防止网络的拥塞现象,TCP提出了一系列的拥塞控制机制.最初由 ...
- 【计算机网络】传输层 : TCP 可靠传输 ( 可靠传输机制 | 快速重传机制 )
文章目录 一.TCP 可靠传输 二.TCP 可靠传输机制 三.TCP 快速重传 机制 一.TCP 可靠传输 可靠性 : 保证 接收方进程 从 TCP 缓冲区 中读取的数据 与 发送方进程 发送的数据 ...
- 图解TCP 的重传、滑动窗口、流量控制和拥塞控制机制
每日一句英语学习,每天进步一点点: 前言 前一篇「硬不硬你说了算!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题」得到了很多读者的认可,在此特别感谢你们的认可,大家都暖暖的. 来了,今 ...
- TCP-F(orward)ACK:植入快速重传灵魂的强制快速重传
纸上学来终学浅,绝知此事要躬行. 今日和友人争辩快速重传,只拿着书本上的东西和人对飙近20分钟,还自认为略有取胜,真是汗颜加羞愧. 中文版计算机网络,书上还写着接收到3次重复ACK启用快速重传.TCP ...
- 网络基础2-3(TCP协议,三次握手,四次挥手,TIME_WAIT状态的作用,TCP如何保证可靠传输,TCP连接中状态转化,滑动窗口,流量控制,快速重传,拥塞窗口,延迟应答,捎带应答,粘包问题)
TCP协议 TCP协议概念 TCP全称为 "传输控制协议(Transmission Control Protocol"). 人如其名, 要对数据的传输进行一个详细的控制 TCP协议 ...
最新文章
- AI创作神器GAN的演变全过程
- android sd卡列目录文件_Android加载SD卡目录,文件夹遍历,图片设置,设置文件对应打开方式等...
- 欢迎使用CSDN-markdown编辑器12213123
- HDU1394(权值线段树)
- 前端学习(2379):调整初始目录结构
- What means the error-message 'java.lang.OutOfMemoryError: GC overhead limit exceeded' in Java?
- 细数MQ那些不得不说的8大好处
- 计算广告(computational advertising)
- 腾讯java笔试题_腾讯java笔试题
- 单场淘汰制场次计算方法_怎样用单循环制进行的比赛计算场数
- TrendForce:2018年上半年电视面板出货年增11%
- 关于fat32分区32g限制的问题
- Java8 Lambda表达式学习笔记——一文学懂笔记系列(一)
- Educoder---Java继承与接口、文件
- QAP,社会网络分析假设检验之一
- IE8 各种版本链接
- python表达式3or5的值为_表达式 3 or 5 的值为
- 图论、建图--bzoj1539: [POI2005]Dwu-Double-row
- 最新notion enhancer安装教程(macOS Intel适用)
- 《地理信息系统导论》chapter10 数据探查习作
热门文章
- 实验吧 天网管理系统
- 村上春树《挪威的森林》读书笔记
- filp/whoops初体验
- diy无感无刷电机霍尔安装_永磁无刷直流电机霍尔位置传感器的安装
- 蒙牛发言人香港发言措辞欠妥
- 读书笔记——《柯维的智慧》格言
- gazebo plugins
- The specified target project directory 项目名\src\main\resources does not exist 问题解决
- 问题:控制台报错style-helper.mjs?d002:125 Uncaught (in promise) TypeError: Cannot read properties
- STP的安全特性详解与环路保护机制