TCP系列20—重传—10、早期重传(ER)
一、介绍
在前面介绍thin stream时候我们介绍过有两种场景下可能不会产生足够的dup ACK来触发快速重传,一种是游戏类响应交互式tcp传输,另外一种是传输受到拥塞控制的限制,只能发送少量TCP报文.针对这种场景提出了一个快速重传的改进算法即早期重传(early retransmit,简称ER)。按照RFC5827,ER有两种形式一种是基于字节的,一种是基于包的,基于包的ER精度要高于基于字节的ER,linux实现的是基于TCP包的ER,因此我们这里只介绍基于包的ER。
ER是在没有新数据可以发送的场景下降低快速重传dup ACK的门限,dup ACK是由乱序TCP报文触发的,但是发出的总数据包的个数少于4个的时候,就会因为没有足够的dup ACK而不能触发快速重传(假设默认dup ACK门限是3)。发送端在接收到ACK时候如果要触发快速重传必须同时满足下面两个条件
发出去的但是还没有收到ACK确认的TCP报文个数(假设为oseg)小于4
缓存中没有未发送数据或者发送窗口受限不能发送新数据,如果允许发送新数据的话就可以进一步触发dup ACK来达到门限了。
当满足上面两个条件时候,如果这个tcp连接未使能SACK的时候,用来触发ER的dup ACK门限必须降低为
ER_thresh = oseg - 1
当这个TCP连接支持SACK的时候,触发ER的条件则变为,(oseg-1)个TCP包已经被SACK确认。
二、linux实现
在linux实现上ER受到控制/proc/sys/net/ipv4/tcp_early_retrans控制,这个参数的描述如下
tcp_early_retrans - INTEGER
Enable Early Retransmit (ER), per RFC 5827. ER lowers the threshold
for triggering fast retransmit when the amount of outstanding data is
small and when no previously unsent data can be transmitted (such
that limited transmit could be used). Also controls the use of
Tail loss probe (TLP) that converts RTOs occurring due to tail
losses into fast recovery (draft-dukkipati-tcpm-tcp-loss-probe-01).
Possible values:
0 disables ER
1 enables ER
2 enables ER but delays fast recovery and fast retransmit
by a fourth of RTT. This mitigates connection falsely
recovers when network has a small degree of reordering
(less than 3 packets).
3 enables delayed ER and TLP.
4 enables TLP only.
Default: 3
其中TLP的内容我们后续介绍,暂时只关注前这个参数为0、1、2的场景,这个参数为0时候关闭ER,为1的时候使能ER,为2的时候使能ER,但是会延迟ER重传(延迟时间为RTT/4),这样可以在一定程度上减少网络的冗余重传。
从上面的描述中我们看到ER也是为了降低TCP的dup ACK门限,前面内容我们thin stream时候也介绍过一个参数tcp_thin_dupack也是用来降低dup ACK门限的,因此这个参数使能时候会与ER冲突,所以当tcp_thin_dupack使能的时候,不管tcp_early_retrans怎么设置都会关闭ER。linux同时还要求tcp_reordering为3的时候才会使能ER(默认值即为3)。
另外linux实现上还有一个点与协议有差异,上面我们介绍过TCP连接支持SACK的时候,触发ER的条件则变为,(oseg-1)个TCP包已经被SACK确认。协议使用的是MUST来描述这个条件,但是linux实现上只要有任意一个TCP包被SACK就会触发快速重传。linux的这个实现是基于在TLP的协议草案中提出的增强ER。
三、wireshark示例
前4个示例我们使用与之前thin stream类似的流量模型来与之前的示例作对比(注意截图中的RST消息产生的原因是server端缓存的TCP报文数据没有被应用层读取而直接close掉了,不用关注RST消息)
1、tcp_thin_dupack=0 tcp_thin_linear_timeouts=0 tcp_early_retrans=1缓存中没有新数据待发送
这是示例与之前thin stream示例类似,不同之处在于第一次RTO超时发生了指数回退(原因是tcp_thin_linear_timeouts=0),RTO超时后server端写入两个TCP报文(No11和No12),两个报文发出后client模式丢失No11报文,回复一个dup ACK包含17-25的SACK信息。此时缓存中没有待发送的新数据,同时oseg = 2(No11和No12两个报文),SACK了No12报文,满足触发ER的条件。因此触发了No14的快速重传,从这里我们可以看到设置tcp_early_retrans=1,tcp_thin_dupack=0时候和之前单独设置tcp_thin_dupack=1的结果类似都会降低快速重传dup ACK的门限,因此在设置了tcp_thin_dupack=1的时候就不会触发ER重传了。

2、tcp_thin_dupack=0 tcp_thin_linear_timeouts=0 tcp_early_retrans=1缓存中有新数据待发送
在设置tcp_thin_linear_timeouts=0后,从下图中我们看到与第一次RTO超时重传开始进行指数回退了(与之前的thin_stream对比)。接着server端写入三个数据包,但是因为拥塞控制暂时只能发出两个TCP报文(No11和No12),接着client回复了一个dup ACK带有17-25的SACK信息,即模拟No11包丢失。可以看到此时并没有触发ER,原因是上面写入了三个tcp报文只发送了两个TCP报文,缓存中还有新数据可以发送。
3、tcp_thin_dupack=0 tcp_thin_linear_timeouts=0 tcp_early_retrans=2缓存中没有新数据待发送
这个示例与第一个示例类似,不同的是这次设置tcp_early_retrans为2延迟触发ER重传。从server端程序中可以看到此时的RTT为0.44s,从下图可以看到ER重传的No14报文与No13报文之间的时间差大约也是0.11s,正好是RTT/4。其他地方与第一个示例一样了
4、tcp_thin_dupack=0 tcp_thin_linear_timeouts=0 tcp_early_retrans=0缓存中没有新数据待发送
接下来我们来看一下即没有使能ER也没有使能thin stream优化的场景,从下图可以看到在收到No13的dup ACK时候并没有触发快速重传,最终RTO超时重传

5、tcp_thin_dupack=0 tcp_thin_linear_timeouts=0 tcp_early_retrans=1缓存中没有新数据待发送
接下来我们看一下我们之前说的linux实现上对dup ACK门限的判断与协议的差异性。在下图中server端发出No6-No9四个TCP报文后,client端正常回退No6报文的ACK确认包。接着模拟No7报文丢失,对No8乱序报文响应No11确认包,其中包含17-25的SACK信息。可以看到测试oseg为3,按照协议需要SACK确认2个TCP数据包才会触发ER,但是我们看到只需要No11通过SACK确认一个TCP报文(No8报文)就会触发ER。其中No13是client对No9响应的ACK报文,包含17-33的SACK信息。

补充资料:
1、https://www.ietf.org/proceedings/69/slides/tcpm-9.pdf
2、https://datatracker.ietf.org/doc/rfc5827/
TCP系列20—重传—10、早期重传(ER)的更多相关文章
- TCP系列47—拥塞控制—10、FACK下的快速恢复与PRR
一.概述 FACK下的重传我们在之前的重传部分已经进行了介绍,这里简单介绍一下随着FACK提出的拥塞控制算法的改进及随后的进一步改进. 从我们之前介绍的RFC2582和RFC5681中可以看到,快速恢 ...
- TCP系列11—重传—1、TCP重传概述
在最开始介绍TCP的时候,我们就介绍了TCP的三个特点,分别是面向连接.可靠.字节流式.前面内容我们已经介绍过了TCP的连接管理,接下来的这部分内容将会介绍与TCP可靠性强关联的TCP重传. 很多网络 ...
- TCP系列45—拥塞控制—8、SACK关闭的拥塞撤销与虚假快速重传
一.概述 这篇文章介绍一下TCP从Recovery状态恢复到Open状态的时候cwnd的更新.我们在tcp重传部分的文章中曾经介绍过虚假重传的概念,Linux在探测到虚假重传的时候就会执行拥塞撤销操作 ...
- TCP系列18—重传—8、FACK及SACK reneging下的重传
一.介绍 FACK的全称是forward acknowledgement,FACK通过记录SACK块中系列号最大(forward-most)的SACK块来推测丢包信息,在linux中使用fackets ...
- TCP系列52—拥塞控制—15、前向重传与RACK重传拥塞控制处理对比
一.概述 这里主要简单分析一个丢包重传并恢复的场景,通过不同的设置让这个相同的场景分别触发RACK重传和前向重传,通过对比说明以下问题: Forward Retransmit可以产生只有重传标记的数据 ...
- TCP系列24—重传—14、F-RTO虚假重传探测
一.虚假重传 在一些情况下,TCP可能会在没有数据丢失的情况下初始化一个重传,这种重传就叫做虚假重传(Spurious retransmission).发生虚假重传的原因可能是包传输中重排序.传输中发 ...
- TCP系列22—重传—12、Forward Retransmit
一.概述 forward retransmit相关的内容在RFC6675中有描述,可以参考RFC6675 section 4中NextSeg ()的定义.forward retransmit中文名可以 ...
- TCP系列21—重传—11、TLP
一.介绍 Tail Loss Probe (TLP)是同样是一个发送端算法,主要目的是使用快速重传取代RTO超时重传来处理尾包丢失场景.在一些WEB业务中,如果TCP尾包丢失,如果依靠RTO超时进行重 ...
- TCP系列16—重传—6、基础快速重传(Fast Retransmit)
一.快速重传介绍 按照TCP协议,RTO超时重传是一个非常重要的事件,当RTO超时的时候,TCP会同时通过两种方式非常谨慎的降低发送数据包的速率,一种是基于拥塞控制削减发送窗口的大小,另外一个是通过指 ...
随机推荐
- 帝国cms全文搜索 增加自定义字段搜索
帝国cms全站搜索功能只能调出固定的几个字段,如果想搜索其他字段的值,这时我们应该怎么办呢?开拓族网站有这个需求,所以研究了一下帝国的全站搜索,后来发现在/e/sch/index.php中可以直接对数 ...
- 全文检索引擎 sphinx-coreseek中文索引
Sphinx是一个基于SQL的全文检索引擎,可以结合MySQL,PostgreSQL做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索. Sphinx特别为一些 ...
- while 循环,格式化输出和运算编码
今日内容 1.while循环 while Ture: content = input ("请输入你要喷的内容",输入Q退出) if ...
- 第6章 HDFS HA配置
目录 6.1 hdfs-site.xml文件配置 6.2 core-site.xml文件配置 6.3 启动与测试 6.4 结合ZooKeeper进行自动故障转移 在Hadoop 2.0.0之前,一个H ...
- python学习笔记:第17天 面向对象03 类与类之间的关系
一.类与类之间的依赖关系 ⼤千世界, 万物之间皆有规则和规律. 我们的类和对象是对⼤千世界中的所有事物进⾏归类. 那事物之间存在着相对应的关系. 类与类之间也同样如此. 在⾯向对象的世界中. 类与类 ...
- Python2和Python3
1. 字符编码 1.1. Python2默认为ACSII编码 1.2. Python3为Unicode 2. Unicode和UTF8和GBK编码的关系 utf8:中文3字节 ...
- Divisibility题解
From lyh 学长 2018.5.3 信(liang)心(liang)杯T3 一道略弱的数论题. 题目描述 给定 n个数,问是否能从中选出恰好 k个数,使得这些数两两之差可以被 m 整除. 输入输 ...
- 将 List<Obj> 集合, 导出至 Excel
主代码在这:http://www.codeproject.com/Articles/120480/Export-to-Excel-Functionality-in-WPF-DataGrid 黑人老外写 ...
- 北京Uber优步司机奖励政策(1月22日
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 流式断言器AssertJ介绍
本文来自网易云社区 作者:范旭斐 大家在使用testng.junit做自动化测试的过程中,经常会用到testng.junit自带的断言器,有时候对一个字符串.日期.列表进行断言很麻烦,需要借助到jdk ...