TCP/IP卷一:76---TCP超时与重传之(伪超时与重传(重复SACK(DSACK)、Eifel检测算法、迁移RTO恢复算法(F-RTO)、Eifel响应算法))
发布日期:2021-06-29 22:33:33 浏览次数:3 分类:技术文章

本文共 3961 字,大约阅读时间需要 13 分钟。

一、伪超时与重传概述

  • 在很多情况下,即使没有出现数据丢失也可能引发重传。这种不必要的重传称为伪重传其主要造成原因是伪超时,即过早判定超时其他因素如包失序、包重复,或ACK丢失也可能导致该现象。在实际RTT显著增长,超过当前RTO时,可能出现伪超时。在下层协议性能变化较大的环境中(如无线环境),这种情况出现得比较多,[KP87]中也提到
  • 这里我们仅关注由伪超时导致的伪重传。失序与重复的影响在下面的章节中再讨论
  • 为处理伪超时问题提出了许多方法。这些方法通常包含检测算法与响应算法。检测算法用于判断某个超时或基于计时器的重传是否真实,一旦认定出现伪超时则执行响应算法,用于撤销或减轻该超时带来的影响。本章中我们只讨论报文段重传行为。典型的响应算法也涉及拥塞控制变化,会在后面“TCP拥塞控制”介绍

图示(回退“N”行为)

  • 下图描述了一个简化的TCP交换过程
  • 在报文段8发送完成后ACK链路上出现了延迟高峰导致了一次伪重传。在报文段5超时重传后,原始传输的报文段5 - 8的ACK仍然处于在传状态
  • 本图中为简便起见,序列号和ACK号都基于包而非字节来表示,并且ACK号表示已接收到的包,而非期望接收的下一个包。当这些ACK到达时,发送端继续重传早已接收的其他报文段,从已确认的报文段之后开始。这导致TCP出现了“回退N”的行为模式,并产生了更多的“重复ACK”返回发送端,这时就可能会触发快速重传。 针对这一问题,提出了一些方法来减轻不良影响。下面我们讨论其中比较常用的几种方法

二、重复SACK(DSACK)扩展

  • 在非SACK的TCP中,ACK只能向发送端告知最大的有序报文段。采用SACK则可告知其他的(失序)报文段基本的SACK机制对接收端收到重复数据段时怎样运作没有规定。 这些重复数据可能是伪重传、网络中的重复或其他原因造成的

DSACK发送端

  • 在SACK接收端采用DSACK(或称作D-SACK),即重复SACK[RFC2883],并结合通常的SACK发送端,可在第一个SACK块中告知接收端收到的重复报文段序列号
  • DSACK的主要目的是判断何时的重传是不必要的,并了解网络中的其他事项。因此发送端至少可以推断是否发生了包失序、 ACK丢失、包重复或伪重传
  • DSACK相比于传统SACK并不需要额外的协商过程。为使其正常工作,接收端返回的SACK的内容会有所改变,对应的发送端的响应也会随之变化。如果一个非DSACK与DSACK的TCP共用一个连接,它们会交互操作,但非DSACK不能使用DSACK的功能

DSACK接收端

  • SACK接收端的变化在于,允许包含序列号小于(或等于)累积ACK号字段的SACK块。这并非SACK的本意,但这样做能很好地配合该目的。 (在DSACK信息高于累积ACK号字段的情况下,即出现重复的失序报文段时,它也能很好地工作)DSACK信息只包含在单个ACK中,该ACK称为DSACK
  • 与通常的SACK信息不同,DSACK信息不会在多个SACK中重复。因此,DSACK较通常的SACK鲁棒性低
  • [RFC2883]没有具体规定发送端对DSACK怎样处理。 [RFC3708]给出了一种实验算法,利用DSACK来检测伪重传,但它并没有提供响应算法。它提到可采用Eifel响应算法,我们下面讨论,在此之前我们先介绍一些其他的检测算在法

三、Eifel检测算法

  • 概念:
    • 在前面,我们讨论了重传二义性问题。实验性的Eifel检测算法[RFC3522]利用了TCP的TSOPT来检测伪重传
    • 在发生超时重传后,Eifel算法等待接收下一个ACK,若为针对第一次传输(即原始传输)的确认,则判定该重传是伪重传
  • 与DSACK的比较:
    • 利用Eifel检测算法能比仅采用DSACK更早检测到伪重传行为,因为它判断伪重传的ACK是在启动丢失恢复之前生成的
    • 相反,DSACK只有在重复报文段到达接收端后才能发送,并且在DSACK返回至发送端后才能有所响应
    • 及早检测伪重传更为有利,它能使发送端有效避免前面提到的“回退N”行为

Eifel检测算法原理

  • Eifel检测算法的机制很简单。它需要使用TCP的TSOPT
  • 发送端:当发送一个重传(不论是基于计时器的重传还是快速重传)后,保存其TSV值
  • 接收端:当接收到相应分组的ACK后,检查该ACK的TSER部分若TSER值小于之前存储的TSV值,则可判定该ACK对应的是原始传输分组,即该重传是伪重传
  • 这种方法针对ACK丢失也有很好的鲁棒性。如果一个ACK丢失,后续ACK的TSER值仍比存储的重传分组的TSV小。该窗口内的任一ACK的到达都能判断是否出现伪重传,因此单个ACK的丢失不会造成太大问题
  • Eifel检测算法可与DSACK结合使用,这样可以解决整个窗口的ACK信息均丢失,但原始传输和重传分组都成功到达接收端的情况。在这种特殊情况下,重传分组的到达会生成一个DSACK。Eifel算法会理所当然地认定出现了伪重传。然而,在出现了如此之多的ACK 丢失的情况下,使得TCP相信该重传不是伪重传是有用的(例如,使其减慢发送速率——采用拥塞控制的后果)。因此,DSACK的到达会使得Eifel算法认定相应的重传不是伪重传

四、迁移RTO恢复算法(F-RTO)

  • 前移RTO恢复(Forward-RTO Recovery,F-RTO)[RFC5682]是检测伪重传的标准算法。它不需要任何TCP选项,因此只要在发送端实现该方法后,即使针对不支持TSOPT的接收端也能有效地工作。该算法只检测由重传计时器超时引发的伪重传;对之前提到的其他原因引起的伪重传则无法判断
  • 在一次基于计时器的重传之后,F-RTO会对TCP的常用行为做出一定修改。由于这类重传针对的是没有收到ACK信息的最小序列号,通常情况下,TCP会继续按序发送相邻的分组,这就是前面描述的“回退N”行为

工作原理

  • F-RTO会修改TCP的行为,在超时重传后收到第一个ACK时,TCP会发送新(非重传)数据,之后再响应后一个到达的ACK
  • 如果其中有一个为重复ACK,则认为此次重传没问题
  • 如果这两个都不是重复ACK,则表示该重传是伪重传
  • 重复ACK是在接收端收到失序的报文段产生的。这种方法比较直观。如果新数据的传输得到了相应的ACK,就使得接收端窗口前移。如果新数据的发送导致了重复ACK,那么接收端至少有一个或更多的空缺。这两种情况下,接收新数据都不会影响整体数据的传输性能(假设接收端有足够的存储空间)

五、Eifel响应算法

  • 一旦判断出现伪重传,则会引发一套标准操作,即Eifel响应算法[RFC4015]。由于响应算法逻辑上与Eifel检测算法分离,所以它可与我们前面讨论的任一种检测方法结合使用。原则上超时重传和快速重传都可使用Eifel响应算法,但目前只针对超时重传做了相关规定
  • 尽管Eifel响应算法可结合其他检测算法使用,但根据是否能尽早(如Eifel检测算法或F-RTO)或较迟(如DSACK)检测出伪超时的不同而有所区别。前者称为伪超时,通过检查ACK或原始传输来实现。后者称为迟伪超时,基于由(伪)超时而引 发的重传所返回的ACK来判定
  • 响应算法只针对第一种重传事件。若在恢复阶段完成之前再次发生超时,则不会执行响应算法。在重传计时器超时后,它会查看srtt和rttvar的值,并按如下方式记录新的变量sett_prev和rttvar_prev:

  • 在任何一次计时器超时后,都会指定这两个变量,但只有在判定出现伪超时才会使用它们,用于设定新的RTO。在上式中,G代表TCP时钟粒度。srtt_prev设为srtt加上两倍的时钟粒度是由于:srtt的值过小,可能会出现伪超时。如果srtt稍大,就可能不会发生超时。srtt加上2G得到srtt_prev,之后都使用srtt_prev来设置RTO
  • 完成srtt_prev和rttvar_prev的存储后,就要触发某种检测算法。运行检测算法后可得到一个特殊的值,称为伪恢复。如果检测到一次伪超时,则将伪恢复置为SPUR_TO。如果检测到迟伪超时,则将其置为LATE_SPUILTO。否则,该次超时为正常超时,TCP继续执行正常的响应行为
  • 若伪恢复为SPUR_TO,TCP可在恢复阶段完成之前进行操作。通过将下一个要发送报文段(称为SND.NXT)的序列号修改为最新的未发送过的报文段(称为SND.MAX)。这就可在首次重传后避免不必要的“回退N”行为。如果检测到一次迟伪超时,此时已生成对首次重传的ACK,则SND.NXT不改变。在以上两种情况中,都要重新设置拥塞控制状态。并且一旦接收到重传计时器超时后发送的报文段的ACK,就要接如下方式更新srtt、 rttvar和RTO的值:

  • 这里,m是一个RTT样本值,它是基于超时后首个发送数据收到的ACK而计算得到的。进行这些变量更新的目的在于,实际的RTT值可能发生了很大变化,RTT的当前估计值已经不适合用于设置RTO。若路径上的实际RTT突然增大(例如由于无线切换至一个新的基 站),当前的srtt和rttvar就显得过小,应重新设置。而另一方面,RTT的增大可能只是暂时的,这时重设srtt和rttvar的值就不那么明智了,因为它们原先的值可能更为精确
  • 在新RTT样本值较大的情况下,上述等式尽力获得上述两种情况的平衡。这样做可以有效地抛弃之前的RTT历史值(和RTT的历史变化情况)。只有在响应算法中srtt和rttvar的值才会增大。若RTT不会增大,则维持估计值不变,这本质上是忽略超时情况的发生。 两种情况中,RTO还是按正常方式进行更新,并针对此次超时设置新的重传计时器值

转载地址:https://dongshao.blog.csdn.net/article/details/104106014 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:TCP/IP卷一:77---TCP超时与重传之(包失序与包重复)
下一篇:Linux(内核剖析):33---内核同步之(完成变量(completion)、大内核锁(BLK)、顺序所(seqlock)、禁止抢占、顺序和屏障(barriers))

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月19日 23时32分54秒