一、介绍

在前面介绍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)的更多相关文章

  1. TCP系列47—拥塞控制—10、FACK下的快速恢复与PRR

    一.概述 FACK下的重传我们在之前的重传部分已经进行了介绍,这里简单介绍一下随着FACK提出的拥塞控制算法的改进及随后的进一步改进. 从我们之前介绍的RFC2582和RFC5681中可以看到,快速恢 ...

  2. TCP系列11—重传—1、TCP重传概述

    在最开始介绍TCP的时候,我们就介绍了TCP的三个特点,分别是面向连接.可靠.字节流式.前面内容我们已经介绍过了TCP的连接管理,接下来的这部分内容将会介绍与TCP可靠性强关联的TCP重传. 很多网络 ...

  3. TCP系列45—拥塞控制—8、SACK关闭的拥塞撤销与虚假快速重传

    一.概述 这篇文章介绍一下TCP从Recovery状态恢复到Open状态的时候cwnd的更新.我们在tcp重传部分的文章中曾经介绍过虚假重传的概念,Linux在探测到虚假重传的时候就会执行拥塞撤销操作 ...

  4. TCP系列18—重传—8、FACK及SACK reneging下的重传

    一.介绍 FACK的全称是forward acknowledgement,FACK通过记录SACK块中系列号最大(forward-most)的SACK块来推测丢包信息,在linux中使用fackets ...

  5. TCP系列52—拥塞控制—15、前向重传与RACK重传拥塞控制处理对比

    一.概述 这里主要简单分析一个丢包重传并恢复的场景,通过不同的设置让这个相同的场景分别触发RACK重传和前向重传,通过对比说明以下问题: Forward Retransmit可以产生只有重传标记的数据 ...

  6. TCP系列24—重传—14、F-RTO虚假重传探测

    一.虚假重传 在一些情况下,TCP可能会在没有数据丢失的情况下初始化一个重传,这种重传就叫做虚假重传(Spurious retransmission).发生虚假重传的原因可能是包传输中重排序.传输中发 ...

  7. TCP系列22—重传—12、Forward Retransmit

    一.概述 forward retransmit相关的内容在RFC6675中有描述,可以参考RFC6675 section 4中NextSeg ()的定义.forward retransmit中文名可以 ...

  8. TCP系列21—重传—11、TLP

    一.介绍 Tail Loss Probe (TLP)是同样是一个发送端算法,主要目的是使用快速重传取代RTO超时重传来处理尾包丢失场景.在一些WEB业务中,如果TCP尾包丢失,如果依靠RTO超时进行重 ...

  9. TCP系列16—重传—6、基础快速重传(Fast Retransmit)

    一.快速重传介绍 按照TCP协议,RTO超时重传是一个非常重要的事件,当RTO超时的时候,TCP会同时通过两种方式非常谨慎的降低发送数据包的速率,一种是基于拥塞控制削减发送窗口的大小,另外一个是通过指 ...

随机推荐

  1. C# 发送Http协议 模拟 Post Get请求

    1.参数 paramsValue的格式 要和 Reques.ContentType一致, 如果 contentype  "application/x-www-form-urlencoded& ...

  2. Bigdata--hadoop系列安装

    Date:20180827 Monday 目前市场hadoop主流版本是2.7.x系列,下面我们就以hadoop-2.7.3为例进行安装 安装前准备: 1.操作系统:cetos(6和7) 2.java ...

  3. zkfc的znode不存在的问题

    cd /soft/hadoop/logs/hadoop-centos-zkfc-s101.log发现: 2018-09-29 12:42:03,616 FATAL org.apache.hadoop. ...

  4. 最新版的stm32f1xx.h文件中取消了u8, u16, u32的类型定义

    使用芯片stm32f103zet6和stm32l151c8t6,在移植程序时发现,编译器提示u8未定义: 在Keil MDK 开发环境里,st定义无符号32位整形数据有很多种表示方法: 1 unsig ...

  5. ZYNQ的Linux Linaro系统镜像制作SD卡启动

    ZYNQ的Linux Linaro系统镜像制作SD卡启动 0. 概述 ZYNQ生成uboot的时候和正常的ARM设备不太一样,ZYNQ属于二次辅助启动uboot然后由uboot启动内核,大概意思就是 ...

  6. 『Python题库 - 填空题』151道Python笔试填空题

    『Python题库 - 填空题』Python笔试填空题 part 1. Python语言概述和Python开发环境配置 part 2. Python语言基本语法元素(变量,基本数据类型, 基础运算) ...

  7. Python学习笔记一:第一个Python程序,变量,字符编码与二进制,用户交互程序

    第一个python程序 Windows:设置环境变量,X:\pthonxxx,xxx是版本号 在命令提示符下 输入python,进入解释器 >>>print(“Hello World ...

  8. JZ2440开发板:UART(串口)使用(学习笔记)

    查看UART在硬件上的信息,阅读JZ2440原理图可以看到: JZ2440开发板的UART0是可以跟USB相接的,用于打印调试,UART1,UART2两个串口用来外接模块.所以本文仅对UART0进行操 ...

  9. Java基础之进制转换

    1.十进制与二进制之间的转换 (1)十进制转二进制的方法:使用十进制的数据不断除以2,直到商为0为止,从下往上取余就是对应的二进制. (2)二进制转十进制:使用二进制的每一位乘以2的n次方,n从0开始 ...

  10. 博科Brocade 300光纤交换机配置zone教程

    光纤交换机作为SAN网络的重要组成部分,在日常应用中非常普遍,本次将以常用的博科交换机介绍基本的配置方法. 博科300实物图: 环境描述: 如上图,四台服务器通过各自的双HBA卡连接至两台博科300光 ...