一、概述

FRTO虚假超时重传检测我们之前重传章节的文章已经介绍过了,这里不再重复介绍,针对后面的示例在说明两点

1、FRTO只能用于虚假超时重传的探测,不能用于虚假快速重传的探测。

2、延迟ER重传触发的进入Recovery状态时候,并不会立即更新cwnd。

本篇在演示FRTO的同时,还会涉及到ER超时重传、TLP探测、SACK关闭场景下的拥塞撤销,后面或者前面都会有针对这些场景的专门介绍文章。

一、wireshark示例

1、FRTO与ER

我们通过一个示例看一下关闭SACK时候,tcp_sack=0,FRTO虚假超时探测和拥塞撤销的处理,同时我们需要设置关闭TSopt选项,否则Eifel探测会先于FRTO探测到虚假超时,tcp_timestamps=0,后面我们会介绍到Eifel探测。如下设置相关参数

  1. ******@Inspiron:~$sudo ip route add local 127.0.0.2 dev lo congctl reno initcwnd 3  ssthresh lock 15   #参考本系列destination metric文章
  2. ******@Inspiron:~$ sudo ethtool -K lo tso off gso off  #关闭tso gso以方便观察cwnd变化

业务场景:server端在与client端建立连接后休眠1s,然后写入50bytes数据,接着休眠46ms,然后以3ms为间隔连续写入6次,每次写入50bytes。client在收到第一个数据包并回复ACK确认包后,server与client之间的RTT突然变大(RTT大约从50ms突变为300ms,例如移动终端切换场景),然后server端触发虚假RTO超时。最终TCP流交互如下图所示。

No1-No9:server端慢启动过程,不再解释,注意因为关闭了SACK功能,因此TLP功能也不会使能,因此server端在收到No7数据包的时候会重新启动RTO定时器,后面也不会被改写为TLP定时器。发出No9后ssthresh=15, cwnd=4, packets_out=4, sacked_out=0,  lost_out=0, retrans_out=0。

No10:RTO超时后,server端从Open状态切换为Loss状态,更新prior_ssthresh=max(ssthresh, cwnd*3/4)=15, ssthresh=max(cwnd/2, 2)=2, cwnd=1,并把No5、No6、No8、No9四个数据包标记为lost,lost_out=4,接着重传No5数据包,retrans_out=1。并且当前满足使能FRTO的条件。

No11-No13:No11报文为client对No5的确认包,server端收到No11报文后,更新packets_out=3, lost_out=3,retrans_out=0,发现当前使能了FRTO功能,并且No11这个报文的ack number确认了新的数据包,因此server端FRTO尝试发出新的未发送数据包,此时cwnd=1,in_flight=3-(3+0)+0=0,因此发出一个数据包即No12,FRTO对这个ACK报文的处理结束。接着reno的慢启动更新cwnd=2,又发出一个新数据包即No13。最终packets_out=5。

No14:server端收到No14报文后,更新packets_out=4,lost_out=2,发现No14这个确认包相比No11又确认了新的数据包,而且新确认的数据包是未曾重传过的No6数据包,因此server端FRTO认定之前的No10重传为虚假超时重传,接着进行拥塞撤销,更新cwnd=max(cwnd,2*ssthresh)=4,ssthresh = max(ssthresh,prior_ssthresh)=15,并取消No8、No9数据包的lost标记,更新lost=0,server端从Loss状态切换为Open状态。接着reno的慢启动更新cwnd=5。

No15-No16:同样是延迟到达的ACK报文,最终ssthresh=15, cwnd=7, packets_out=2, sacked_out=0,  lost_out=0, retrans_out=0。

No17:No17是No10的确认包,是一个dup ACK,server端收到No17后更新sacked_out=1,并从Open状态切换为Disorder状态,此时满足

sacked_out>0, packets_out >= (sacked_out + 1) , packets_out < 4这几个条件且没有待发送的新数据,因此触发延迟ER,设置ER定时器为RTT/4(大约为35ms)。处理完No17后ssthresh=15, cwnd=7, packets_out=2, sacked_out=1,  lost_out=0, retrans_out=0。

No18:ER定时器超时后,server端从Disorder状态切换到Recovery状态,更新high_seq=351, prior_ssthresh=max(ssthresh, cwnd*3/4)=15, ssthresh=max(cwnd/2, 2)=3,并把No12数据包标记为lost,更新lost_out=1,接着重传这个数据包,即发出No18,并更新retrans_out=1, prr_out=1。最终ssthresh=3, cwnd=7, packets_out=2, sacked_out=1,  lost_out=1, retrans_out=1。注意ER定时器超时重传的时候并没有直接削减cwnd。

No19-No20:No19是一个partial ACK,更新packets_out=1, sacked_out=0,  lost_out=0, retrans_out=0,SACK关闭场景下收到partial ACK,会立即把partial ACK的ack number对应的数据包(即No13)标记为lost,因而又更新lost_out=1,接着进入更新cwnd的流程,注意这里newly_acked_sacked=0, 因此并不会更新cwnd ,接着重传标记为lost的数据包即No20,更新retrans_out=1,prr_out=2。

No21:No21是No13数据包的确认包,server端收到No21的时候,更新packets_out=0,lost_out=0,retrans_out=0,Ack=351=high_seq,即正好到达Recovery point,但是因为此时SACK处于关闭状态,因此server端并不会从Recovery状态切换到Open状态,更新cwnd=min(cwnd, in_flight+dupthresh)=3, 最终处理完No21后,ssthresh=3, cwnd=3, packets_out=0, sacked_out=0,  lost_out=0, retrans_out=0, prr_delivered=0, prr_out=2。(No21数据包的处理请参考介绍SACK关闭场景拥塞撤销处理的文章)。

No22-No23:server端收到虚假重传的dup ACK的确认包,最终处理完No23后,server端处于Recovery状态,ssthresh=3, cwnd=3, packets_out=0, sacked_out=0,  lost_out=0, retrans_out=0, prr_delivered=0, prr_out=2。

2、FRTO与TLP

我们会在DSACK拥塞撤销的文章中用示例演示了server与client协商好TSopt后,如果收到不带有TSopt选项的数据包,虽然协议建议静默丢弃这种报文,但是linux仍然正常接收处理。这个示例我们先来看一下client如果与server协商好SACK选项后,而client侧代码bug或者其他原因导致收到乱序包后回复的dup ACK没有携带SACK信息时候,server端会如何处理。同样在执行示例前如下设置相关TCP参数:

  1. ******@Inspiron:~$sudo ip route add local 127.0.0.2 dev lo congctl reno initcwnd 5  ssthresh lock 4   #参考本系列destination metric文章
  2. ******@Inspiron:~$ sudo ethtool -K lo tso off gso off  #关闭tso gso以方便观察cwnd变化

业务场景:server端在与client端建立连接后休眠1000ms,接着以3ms为间隔,连续发送10个数据包,每个数据包的大小为50bytes,其中高亮标出的No7数据包在传输中丢失。client对于收到的乱序的报文回复的dup ACK确认包并不带有SACK选项。最终如下图所示:

No1-No12:连接建立后的拥塞避免过程,最终发出No23后, ssthresh=4, cwnd=4,cwnd_cnt=1, packets_out=5, sacked_out=0,  lost_out=0, retrans_out=0, fackets_out=0,server端处于Open状态,并设置了TLP定时器,PTO=2*RTT,大约为100ms。

No13:这个dup ACK是对No8报文的回复,但是可以看到里面并没有SACK选项,但是在三次握手的时候client和server端是协商了SACK的,因此server端在收到这种不带有SACK选项的dup ACK的时候,并不会更新sacked_out,因此server端也并不会进入Disorder状态。但是server端在收到这个dup ACK的时候,会先取消PTO定时器并设置成RTO定时器,然后检查收到报文的ack number是否能取消RTO定时器,因为收到的报文ack number并没有完整确认数据,因此仍然保留有RTO定时器的设置,接着server端在检查如果当前有设置RTO定时器,就会尝试取消RTO定时器设置为PTO定时器。因此收到No13后,server端最终又会重新设置PTO定时器为2*RTT,大约为100ms。

No14-No16:这几个报文的处理与No13类似,最终收到No16后,重设PTO定时器为100ms。

No17:PTO定时器超时,触发loss probe过程,此时缓存中有待发送的新数据,因此发出No17数据包,更新packets_out=6,并取消PTO定时器设置成RTO定时器。

No18:server端收到No18后又会把RTO定时器重设为PTO定时器,定时时间大约为100ms。

No19-No24:这几个数据包的处理与No17、No18类似。收到No24后,重设PTO定时器,定时时间为100ms。此时 ssthresh=5, cwnd=4,cwnd_cnt=1, packets_out=9, sacked_out=0,  lost_out=0, retrans_out=0, fackets_out=0,server端处于Open状态,注意此时cwnd=4,in_flight=9,可以看到loss probe报文并不会受到拥塞控制cwnd的限制。

No25:当PTO定时器再次超时的时候,此时server端的缓存中已经没有待发送的新数据包,因此重传最后发送的数据包(即No23),注意虽然No25发生了数据包的重传,但是TLP重传后,server端TCP仍然会停留在Open状态,而且并不会更新lost_out等字段,因此重传完No25后, ssthresh=4, cwnd=4,cwnd_cnt=1, packets_out=9, sacked_out=0,  lost_out=0, retrans_out=0, fackets_out=0,server端TCP处于Open状态,并且当前设置有RTO定时器。

No26:server端在收到No26这个dup ACK后的处理与No13类似,最终会把RTO定时器重设为PTO定时器,定时时间大约为100ms。

No27:No26设置的PTO定时器超时后发现当前已经有了一个TLP超时重传(即No25),因此不会在进行TLP尾包重传,而是设置RTO定时器,定时时间大约为250ms,最终RTO超时触发No27重传,此时server端由Open状态切换为Loss状态,发出No27后以指数回退重设RTO定时器,相关状态变量如下,prior_ssthresh=4, ssthresh=2, cwnd=1,cwnd_cnt=1, packets_out=9, sacked_out=0,  lost_out=9, retrans_out=1, fackets_out=0。

No28:No28的ack number确认了未重传的数据包,因此触发FRTO拥塞撤销,更新cwnd=max(cwnd,2*ssthresh)=4,ssthresh = max(ssthresh,prior_ssthresh)=4,同时server端从Loss状态切换为Open状态,然后在Open状态下进入reno的拥塞避免过程,No28的ack number新确认了9个数据包,9/cwnd=2,因此更新cwnd=cwnd+2=6,cwnd_cnt=9-2*4=1,最终ssthresh=4, cwnd=6,cwnd_cnt=1, packets_out=0, sacked_out=0,  lost_out=9, retrans_out=0, fackets_out=0

TCP系列48—拥塞控制—11、FRTO拥塞撤销的更多相关文章

  1. TCP系列39—拥塞控制—2、拥塞相关算法及基础知识

    一.拥塞控制的相关算法 早期的TCP协议只有基于窗口的流控(flow control)机制而没有拥塞控制机制,因而易导致网络拥塞.1988年Jacobson针对TCP在网络拥塞控制方面的不足,提出了& ...

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

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

  3. TCP系列50—拥塞控制—13、Eifel探测下的拥塞撤销

    一.概述 我们之前在SACK关闭场景下的拥塞撤销那篇文章中提到过Eifel探测算法(Eifel Detection Algorithm),最早在介绍DSACK和FRTO的时候我们就有提到过Eifel探 ...

  4. TCP系列49—拥塞控制—12、DSACK下的拥塞撤销

    一.概述 DSACK下的虚假重传的检测我们之前重传部分的文章已经介绍过了,这里简单说一下拥塞控制部分的实现. linux内部会维护一个undo_retrans状态变量,其值为已经重传的次数减掉被DSA ...

  5. TCP系列55—拥塞控制—18、其他拥塞控制算法及相关内容概述

    前面我们演示分析了100+个wireshark TCP实例,拥塞控制部分也介绍常见的拥塞处理场景以及4种拥塞撤销机制,但是我们一直使用的都是reno拥塞控制算法.实际上拥塞控制发展到今天已经有了各种各 ...

  6. TCP系列46—拥塞控制—9、SACK下的快速恢复与Limited transmit

    一.概述 1.SACK下的特殊处理过程 SACK下的拥塞控制处理是linux中拥塞控制的实现依据,再次强调一遍RFC6675的重要性,linux中拥塞控制主体框架的实现是与RFC6675一致的,所以如 ...

  7. TCP系列41—拥塞控制—4、Linux中的慢启动和拥塞避免(一)

    一.Linux中的慢启动和拥塞避免 Linux中采用了Google论文的建议把IW初始化成了10了.在linux中一般有三种场景会触发慢启动过程 1.连接初始建立发送数据的时候,此时cwnd初始化为1 ...

  8. TCP系列42—拥塞控制—5、Linux中的慢启动和拥塞避免(二)

    在本篇中我们继续上一篇文章wireshark的示例讲解,上一篇介绍了一个综合示例后,本篇介绍一些简单的示例,在读本篇前建议先把上一篇读完,为了节省篇幅,本篇只针对一些特殊的场景点报文进行讲解,不会像上 ...

  9. TCP系列40—拥塞控制—3、慢启动和拥塞避免概述

    本篇中先介绍一下慢启动和拥塞避免的大概过程,下一篇中将会给出多个linux下reno拥塞控制算法的wireshark示例,并详细解释慢启动和拥塞避免的过程. 一.慢启动(slow start) 一个T ...

随机推荐

  1. 【Keil】Keil5-改变字的大小和颜色

    点击 Edit / Configuration 出现弹窗,选择Colors & Fonts 底下可以选择要改哪个部分,例如普通代码.数字.关键字.注释...等等,当然也可以改变背景颜色的,英文 ...

  2. 使用树莓派拍摄延时动画,制作GIF图

    本期教大家将编写一个小脚本用树莓派来捕获多个图像,然后可以将这些图像组合成动画GIF,使用延时摄影功能,可以在几秒钟内查看非常慢的事情. 我们需要用到ImageMagick,这是一个用于图像处理的命令 ...

  3. PTA(BasicLevel)-1012 数字分类

    一 题目描述    给定一系列正整数,请按要求对数字进行分类,并输出以下 5 个数字: ​​ = 能被 5 整除的数字中所有偶数的和: ​​ = 将被 5 除后余 1 的数字按给出顺序进行交错求和,即 ...

  4. Mac使用bootcamp安装win系统花屏解决方法

    15年11'乞丐版air装win屏幕花屏,很郁闷,先后找了网上很多方法,最终总结出了一个比较折中的方法,不玩游戏不使用大型3D的可以参考. 1 花屏现象 2 解决方法 2.1 禁用驱动 2.2 使用M ...

  5. 【LG4609】[FJOI2016]建筑师

    [LG4609][FJOI2016]建筑师 题面 洛谷 题解 (图片来源于网络) 我们将每个柱子和他右边的省略号看作一个集合 则图中共有\(a+b-2\)个集合 而原来的元素中有\(n-1\)个(除去 ...

  6. CF 1025 D. Recovering BST

    D. Recovering BST http://codeforces.com/contest/1025/problem/D 题意: 给出一个连续上升的序列a,两个点之间有边满足gcd(ai ,aj) ...

  7. 无旋treap的简单思想以及模板

    因为学了treap,不想弃坑去学splay,终于理解了无旋treap... 好像普通treap没卵用...(再次大雾) 简单说一下思想免得以后忘记.普通treap因为带旋转操作似乎没卵用,而无旋tre ...

  8. javaweb(二十四)——jsp传统标签开发

    一.标签技术的API 1.1.标签技术的API类继承关系 二.标签API简单介绍 2.1.JspTag接口 JspTag接口是所有自定义标签的父接口,它是JSP2.0中新定义的一个标记接口,没有任何属 ...

  9. javaweb(十六)——JSP指令

    一.JSP指令简介 JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分. 在JSP 2.0规范中共定义了三个指令: pa ...

  10. Openstack 10 云环境安装

    概述 资源规划 Undercloud Installation Overcloud Installation Trouble Shooting 附录 本指南介绍了如何使用 Red Hat OpenSt ...