TCP系列18—重传—8、FACK及SACK reneging下的重传
一、介绍
FACK的全称是forward acknowledgement,FACK通过记录SACK块中系列号最大(forward-most)的SACK块来推测丢包信息,在linux中使用fackets_out这个状态变量来记录FACK信息。我们之前介绍SACK重传时候说过在SACK下需要3个dup ACK来触发快速重传(3个为默认值),而SACK下的dup ACK的定义与传统的非SACK下定义又略有不同(详细请参考前面的文章和示例)。当使能FACK的时候,实际上我们可以通过一个SACK块信息来推测丢包情况进而触发快速重传。比如server端依次发出P1(0-9)、P2(10-19)、P3(20-29)、P4(30-39)、P5(40-49),假设client端正常收到了P1包并回复了ACK确认包,P2、P3、P4则由于网络拥塞等原因丢失,client在收到P5时候回复一个Ack=10的确认包,并携带P5有SACK块信息(40-50),这样server在收到P1的确认包和P5的dup ACK时候,就可以根据dup ACK中的SACK信息得知client端收到了P1报文和P5报文,计算出P1和P5两个数据包中间间隔了3个数据包,达到了dup ACK门限(默认为3),进而推测出P2报文丢失。
SACK reneging我们在前面SACK中已经介绍了,下面我们通过示例来一起看一下FACK和SACK reneging下的重传。
二、wireshark示例
1、tcp_early_retrans=0,tcp_retrans_collapse=0,tcp_discard_on_port =9877,tcp_sack=1,tcp_fack=1;场景下的重传如下图所示:
server端依次发送No6-No10五个数据包
client收到No6后回复一个不带有SACK选项的ACK确认包(No11),server端正常接收到这个ACK确认包
接着client模拟No7-No9数据包丢包,在收到No10乱序包的时候,回复一个dup ACK,其中包含SACK信息(33-41),
server端收到这个dup ACK后推测处client端已经收到No6和No10报文,中间间隔的报文个数为3个,达到dup ACK门限,进而触发快速重传。
client继续模拟丢包,接着server端RTO超时,进行指数回退过程。
直到No16重传后,client开始回复不带有SACK选项的ACK(partial ACK),但是因为ack number并没有落在33-40之间,此时linux并不会确认发生了SACK reneging。这个ACK触发快速重传(No18)。受限与拥塞控制,这个时候只能发送一个重传包,发送完这个重传报文后根据收到的ACK更新拥塞窗口,拥塞窗口自增1,因此此时可以发送一个新的数据包,但是因为缓存中没有新的待发送数据因此并没有新数据包传出。
接收client回复No19的ACK确认包(partial ACK),这个ACK报文虽然不带有SACK选项,但是linux同样不会确认发生了SACK reneging,server端根据这个partial ACK触发快速重传,在上一步中拥塞窗口已经自增了1,因此实际上快速重传可以重传两个TCP报文但是因为重传完No20后,只剩下一个报文待重传,而这个报文之前又被SACK过,因此快速重传不会重传这个报文
接着client回复不带有SACK选项的No21确认包,Ack=33,注意之前触发FACK快速重传的时候反馈的SACK块信息是(33-41)告诉server端收到了No10数据包,而这个新回复的No21确认包又告诉server没有收到No10确认包。此时就是发生了SACK reneging。在这个ACK确认包触发快速重传时候,就会检测是否发生了SACK seneging,如果发生SACK reneging,linux会初始化一个RTO定时器,定时器的定时时间为RTT/2。快速重传时候检测到了SACK seneging就会直接退出。
接着上一步的RTO定时器超时,触发了No22的RTO超时重传,client回复对应的ACK确认包,整个传输过程结束。

2、tcp_early_retrans=0,tcp_retrans_collapse=0,tcp_discard_on_port =9877,tcp_sack=1,tcp_fack=0;这里我们关闭FACK功能,其他设置不变重新进行类似上面的测试
可以看到这个示例与上面示例的主要差异就是No12的dup ACK虽然同样反馈了No10的SACK信息,但是并没有触发快速重传。其他内容与上面示例基本一致不再重复介绍。

3、tcp_early_retrans=0,tcp_retrans_collapse=0,tcp_discard_on_port =9877,tcp_sack=1,tcp_fack=1;低于dup ACK门限
这个示例和示例1不同的地方在于No12的dup ACK确认包携带的SACK信息为(25-33),也就是通过SACK确认了No9报文,No9与No6报文之间间隔了2个报文没有达到dup ACK的门限,因此并不会触发快速重传。注意server端在收到No19确认包时候触发了快速重传流程,但是快速重传前检测到SACK seneging,重启了RTO定时器并退出快速重传。

补充说明:
1、SACK seneging的检测和RTO定时器的设置参考linux内核tcp_check_sack_reneging函数
TCP系列18—重传—8、FACK及SACK reneging下的重传的更多相关文章
- TCP系列13—重传—3、协议中RTO计算和RTO定时器维护
从上一篇示例中我们可以看到在TCP中有一个重要的过程就是决定何时进行超时重传,也就是RTO的计算更新.由于网络状况可能会受到路由变化.网络负载等因素的影响,因此RTO也必须跟随网络状况动态更新.如果T ...
- TCP系列45—拥塞控制—8、SACK关闭的拥塞撤销与虚假快速重传
一.概述 这篇文章介绍一下TCP从Recovery状态恢复到Open状态的时候cwnd的更新.我们在tcp重传部分的文章中曾经介绍过虚假重传的概念,Linux在探测到虚假重传的时候就会执行拥塞撤销操作 ...
- TCP系列17—重传—7、SACK下的重传
我们之前介绍SACK选项的时候说过,SACK可以把接收端系列号空间的洞反映给发送端,因此发送端可以更充分的理解接收端的情况,而进行更好的重传恢复过程.这种过程有时候也叫做advanced loss r ...
- TCP系列46—拥塞控制—9、SACK下的快速恢复与Limited transmit
一.概述 1.SACK下的特殊处理过程 SACK下的拥塞控制处理是linux中拥塞控制的实现依据,再次强调一遍RFC6675的重要性,linux中拥塞控制主体框架的实现是与RFC6675一致的,所以如 ...
- TCP系列52—拥塞控制—15、前向重传与RACK重传拥塞控制处理对比
一.概述 这里主要简单分析一个丢包重传并恢复的场景,通过不同的设置让这个相同的场景分别触发RACK重传和前向重传,通过对比说明以下问题: Forward Retransmit可以产生只有重传标记的数据 ...
- TCP系列47—拥塞控制—10、FACK下的快速恢复与PRR
一.概述 FACK下的重传我们在之前的重传部分已经进行了介绍,这里简单介绍一下随着FACK提出的拥塞控制算法的改进及随后的进一步改进. 从我们之前介绍的RFC2582和RFC5681中可以看到,快速恢 ...
- 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超时进行重 ...
随机推荐
- UML类图介绍以及PlantUML使用方法
类的UML表示方法 UML介绍 类图,是UML(统一建模语言)中用于描述"类"以及"类与类"之间的示意图.它形象的描述出了系统的结构,帮助人们理解系统. 类图是 ...
- 大数据学习--day08(hnapp 后台系统开发、面向对象)
hnapp 后台系统开发.面向对象 利用前面所学的知识,写一个控制台登陆注册后台界面 package sy180918.hnapp.array; import java.util.Arrays; im ...
- java对象转map
/** * java对象转map * @param obj * @return * @throws IllegalAccessException * @throws IllegalArgumentEx ...
- POJ-3436:ACM Computer Factory (Dinic最大流)
题目链接:http://poj.org/problem?id=3436 解题心得: 题目真的是超级复杂,但解出来就是一个网络流,建图稍显复杂.其实提炼出来就是一个工厂n个加工机器,每个机器有一个效率w ...
- 我和Python的Py交易》》》》》》函数
一 函数是什么? 是数学中的函数? Python中 函数是指将一组语句的集合通过一个名字(函数名)封装起来的一段代码.(所以这里的函数是subroutine子程序) 那要函数干嘛.不都是代码吗?只不 ...
- 动态代理以及对应Spring中AOP源码分析
AOP(面向切面编程)在Spring中是被广泛应用的(例如日志,事务,权限等),而它的基本原理便是动态代理. 我们知道动态代理有两种:基于JDK的动态代理以及基于CGlib动态代理.以下是两种动态代理 ...
- 使用JAX-WS(JWS)发布WebService(二)
将项目改为maven工程,并发布到Tomcat: WebService常用到的注解以及作用: 发布过程中遇到的问题总结: 一.将项目改为maven工程,并发布到Tomcat: 继续上一篇,将代码完善成 ...
- 将 List<Obj> 集合, 导出至 Excel
主代码在这:http://www.codeproject.com/Articles/120480/Export-to-Excel-Functionality-in-WPF-DataGrid 黑人老外写 ...
- 【BZOJ1564】【NOI2009】二叉查找树(动态规划)
[BZOJ1564][NOI2009]二叉查找树(动态规划) 题面 BZOJ 洛谷 题目描述 已知一棵特殊的二叉查找树.根据定义,该二叉查找树中每个结点的数据值都比它左儿子结点的数据值大,而比它右儿子 ...
- JDBC 工具类模板c3p0
JDBC 工具类模板 package com.itheima.sh.utils; import com.mchange.v2.c3p0.ComboPooledDataSource; import ja ...