一、Karn算法

在RTT采样测量过程中,如果一个数据包初传后,RTO超时重传,接着收到这个数据包的ACK报文,那么这个ACK报文是对应初传TCP报文还是对应重传TCP报文呢?这个问题就是retransmission ambiguity problem。当没有使用TSOPT选项,单纯的ACK报文并不会指示对应初传包还是重传包,因此就会发生这个问题。

Karn算法指出,当RTO超时重传发生时候,我们不能依据这个TCP报文的ACK信息来更新RTT估计值。这是Karn算法的第一部分,如之前所说这个是RFC6298要求的。

但是另一方面,如果我们在更新RTO时候只是简单的忽视重传报文信息,可能会丢失一些关于网络状况的信息。例如当网络由于负载等原因导致时延变大的时候,降低发送速率更有助于改善网络状况,因此当进行RTO超时重传时候需要进行指数回退。TCP在RTO上应用一个backoff factor,在每次重传超时的时候,backoff factor进行倍增,直到收到一个对应未重传报文(只进行了初传没有进行重传)的ACK包的时候,backoff factor回退到1。这个过程就是Karn算法的第二部分。

二、TSOPT的RTTM

我们在之前介绍TSOPT选项的时候就说过,TSOPT选项可以用来进行round-trip time measurement(RTTM)。因为TSval值通过反方向TCP报文中的TSecr字段回显,那么根据当前时钟和TSecr的差异就可以进行RTT测量。

当TSopt选项使用的时候,每个接收到的TCP报文都会包含一个TSecr值,但是并不是每个TSecr值都可以用来进行RTT测量的更新。想想一个简单的场景,A给B发送了一个数据包,B回复ACK后,A暂时没有数据要传输,过了一段时间(如1000s)后,A又有新数据包进行传输,当这个新数据包到达B后,这个数据包中的TSecr和当前时钟的差距因为中间存在没有数据传输的空闲状态而变得很大,因此不能用于进行RTT测量。为了解决这个问题,有个规则:在一个TCP报文中接收到的TSecr值可以用于进行RTT测量的前提条件是这个数据包TCP头中的ack number确认了新的数据(即让TCP发送窗的左边向前滑行了)。

当在一个回显TSval值的TCP报文发送之前收到多个带有TSopt选项的报文的时候,TCP必须选择一个合适的TSval用来回复而忽视其他的值。下面分几种情况来说明

1)、延迟 ACK

许多TCP对于到达时间间隔很短的TCP数据报文,经常会隔一个报文回复一个ACK,这种策略就叫做延迟ACK(delayed ACK),数据报文的发送端必须测量包括延迟ACK导致的额外时间的有效RTT,因此在延迟ACK使用的时候,接收端应该回显最先接收到的而且还没有回复ACK的报文的TSval值。

2)、接收的系列号空间存在洞的时候

当发生数据包的丢失,接收端收到乱序报文的时候,会对乱序报文回复重复ACK以触发快速重传(后面介绍快速重传)。丢失的数据包可能是网络负载过重发生拥塞的一个指示,在这种场景下发送端的重传行为应该更保守一些(即增大RTO,减缓重传发送速率),因此把RTT估计过大一些可能更有助于改善网络传输情况(后面拥塞控制会进一步介绍)。因此对于乱序报文的ACK确认包中的TSecr值应该是最近收到的触发接收滑窗前移的报文的TSval值。这里触发接收滑窗迁移的报文是指收到的数据报文的系列号正好是预期接收的连续系列号。当传输过程中发生数据包乱序的时候也会发生相同的场景。

3)、系列号空间的洞被填充的时候

当接收到的TCP报文填充了系列号空间的洞并推进了接收窗前移的时候,这个报文反映了网络传输最新的状况,在TSecr回显的时候应该使用这个报文中的TSval。

协议中描述了一个可以覆盖以上三种情况的算法,算法如下:

1)、每个TCP endpoint维护两个32-bit的状态变量。TS.Recent保存了一个时间戳,当向外发送数据包的时候,TSecr值就取自TS.Recent。另外还有一个Last.ACK.sent保存着上一个发出的数据包的ack number。一在非延迟ACK场景下,Last.ACK.sent反映了endpoint预期接收的数据包。

2)、如果新接收的数据包SEG同时满足下面两个条件SEG.TSval >= TS.Recent 和 SEG.SEQ <= Last.ACK.sent,那么就设置TS.Recent = SEG.TSval。否则忽略这个TSval值。

3)、当发送的数据包带有TSopt选项的时候,设置TSecr字段为TS.Recent。

另外我们之前说过RFC6298中标准方法计算RTO的时候是假设在一个RTT里面至少进行一个RTT采样,在应用TSopt后,在一个RTT里面可以进行多个RTT采样,如果仍然使用RFC6298中的计算方法就会导致,历史值的影响减弱(尤其是链路传输性质是以几个RTT的时间粒度变化的时候),RTO估计不准而造成无效重传,因此需要对标准方法中的alpha和beta按照如下修正。

ExpectedSamples = ceiling(FlightSize / (SMSS * 2))

alpha' = alpha / ExpectedSamples

beta' = beta / ExpectedSamples

其中FlightSize表示发送端已经发出的但是还没有收到ACK的报文大小,SMSS表示发送端的MSS,其中的系数2用于修正延迟ACK。

TCP系列14—重传—4、Karn算法和TSOPT的RTTM的更多相关文章

  1. TCP系列12—重传—2、Linux超时重传引入示例

    在前面我们概述了TCP的超时重传之后我们简单的看一下tcp超时重传的示例.首先简单的描述一下测试过程 1.设置/proc/sys/net/ipv4/tcp_early_retrans为2,关掉TLP功 ...

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

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

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

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

  4. TCP系列13—重传—3、协议中RTO计算和RTO定时器维护

    从上一篇示例中我们可以看到在TCP中有一个重要的过程就是决定何时进行超时重传,也就是RTO的计算更新.由于网络状况可能会受到路由变化.网络负载等因素的影响,因此RTO也必须跟随网络状况动态更新.如果T ...

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

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

  6. TCP系列25—重传—15、DSACK虚假重传探测

    一.DSACK介绍 RFC2883通过指定使用SACK来指示接收端的重复包(duplicate packet)扩展了RFC2018对SACK选项的定义(SACK选项的介绍和示例参考前面内容).RFC2 ...

  7. TCP系列23—重传—13、RACK重传

    一.RACK概述 RACK(Recent ACKnowledgment)是一种新的基于时间的丢包探测算法,RACK的目的是取代传统的基于dupthresh门限的各种快速重传及其变种.前面介绍的各种基于 ...

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

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

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

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

随机推荐

  1. Apache httpd Server Notes

    1. httpd启动.停止以及重启 启动: apachectl –f $PATH_TO_CONF/httpd.conf 停止及重启 apachectl –k stop/restart/graceful ...

  2. collections.Counter类统计列表元素出现次数

    # 使用collections.Counter类统计列表元素出现次数 from collections import Counter names = ["Stanley", &qu ...

  3. notepad无法对linux中的文件进行修改???

    .问题描述: 用notepad++的sftp服务连接LInux,连接成功 想修改图中的程序,来调试udp客户端,但是修改后保存失败(很早之前是成功的) .. 试着解决: 参考博客:https://bl ...

  4. usb之鼠标作为按键输入

    1. 首先搞清楚,鼠标点左键.右键等能得到什么数据,然后分析这些数据上报事件即可. 第一个基本点:usb_alloc_urb函数,创建一个struct urb结构体,只能使用这个函数来创建,它是urb ...

  5. URL和报文知识总结 ——1

    第一部分:浏览器生成的消息 关键词:URL的解析  HTTP请求的生成  DNS服务器 1.URL(网址)的构成: 对于一个网址的解析: https://i.cnblogs.com/index.htm ...

  6. 理解golang中的channel

    channel是goroutine之间的通信机制.可以类比线程间的通信,线程间的通信有多种方式,比如线程上下文.共享内存.IPC通信.socket实现不同机器间的通信. channel用起来很简单,绑 ...

  7. linux静态链接库

    库 库是写好的现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载 ...

  8. vue中cssModules理解可以用于加密和避免重复使用

    cssModules可以用于加密和避免重复使用,也就是说可以在当前vue文件中写的样式会生成独一无二的名字,在其他vue文件中是无法调用的, 一.可以直接配cssModules 第一步,配置vue-l ...

  9. ssm中需要注意的问题

    1.在controller中需要加注解 @Controller @RequestMapping("url") @Autowired private CardService card ...

  10. 【BZOJ3991】寻宝游戏(动态规划)

    [BZOJ3991]寻宝游戏(动态规划) 题面 BZOJ 题解 很明显,从任意一个有宝藏的点开始,每次走到相邻的\(dfs\)的节点就行了. 证明? 类似把一棵树上的关键点全部标记出来 显然是要走一个 ...