TCP系列17—重传—7、SACK下的重传

原文https://www.cnblogs.com/lshs/p/6038555.html

我们之前介绍SACK选项的时候说过,SACK可以把接收端系列号空间的洞反映给发送端,因此发送端可以更充分的理解接收端的情况,而进行更好的重传恢复过程。这种过程有时候也叫做advanced loss recovery。

一、数据接收端SACK行为

我们通过一个wireshark示例来说明接收端的SACK行为:

如上图,为了方便在info列中查看SACK信息,我把info列中TSopt的信息隐藏了,同时把源地址列和目的地址列一起隐藏了。client依次发送P1(1-6)、P2(25-30)、P3(13-18)、P4(37-42)、P5(49-54)、P6(7-12)、P7(31-36)、P8(19-24)、P9(43-48)其中括号中的数字为相对系列号,接收端SACK行为简述如下(详细的可以参考原始的wireshark文件)

  1. 接收端在接收到P1后回复的No5确认包中不包含SACK信息

  2. 在接收到P2后回复的No7确认包中包含的SACK块为(25-31)

  3. 接收端在接收到P3后回复No9确认包,包含的SACK块为(13-19),(25-31)

  4. 接收端在接收到P4后回复No11确认包,包含的SACK信息为(37-43),(13-19),(25-31)

  5. 接收端在接收到P5后回复No13确认包,包含的SACK信息为(49-55),(37-43),(13-19),上图截图中对应的SACK信息就是这个确认包的信息

  6. 接收端在接收到P6后回复No15确认包,包含的SACK信息为(49-55),(37-43),(25-31)

  7. 接收端在接收到P7后回复No17确认包,包含的SACK信息为(25-43),(49-55)

  8. 接收端在接收到P8后回复No19确认包,包含的SACK信息为(49-55)

  9. 接收端在接收到P9后回复No21确认包,接收端系列号空间中不再存在洞,因为这个确认包中不再包含SACK信息。

上面的每个ACK确认包都会包含一个TSopt的选项,从上面第5点可以看到,在ACK确认包包含有TSopt选项的时候,最后只能包含3个SACK块,此时TCP头长已经到达60bytes的最大值不能在容纳更多的SACK块了。

另外注意就是SACK块是按照最新形成的洞信息倒序排列的。每个ACK报文中可以携带多个SACK块的原因是因为ACK确认包有可能会丢包,但是ACK报文不消耗系列号因此不会进行重传,因此接收端通过多个ACK报文中冗余的SACK块信息来提高SACK信息传输的可靠性。

二、数据发送端SACK行为

TCP连接要利用SACK信息还需要发送端根据接收到的SACK信息执行选择性重传(selective retransmisson或者叫做selective repeat)。首先根据SACK信息来填充洞,然后在传递新数据(RFC6675),但是具体实现上可能会有一些差异。另外按照RFC2018,当TCP初始化一个RTO超时重传的时候需要清空SACK信息,但是RFC6675认为RTO超时保留SACK信息也是有一定必要性的。RFC2018还要求发送端只有收到TCP头中的累计ack number的时候才能释放对应的发送缓存,而不能根据SACK信息释放,原因是接收端有可能先发送一个SACK块,然后后面又不在反馈这个SACK块(SACK reneging)。(实际上按照协议发送端接收到的SACK块可能是接收端已经丢弃的TCP报文,虽然这个报文丢弃了但是特定情况下接收端仍然可以在SACK块中携带这个报文信息,而在实现上如果linux内存不足,那么有可能会丢掉已经收到的乱序TCP报文)。SACK reneging的示例我们后面会在FACK介绍中进行简单介绍。

另外一个需要注意的就是在快速重传的时候dup ACK的定义,RFC6675中对于SACK下dup ACK的定义如下

  For the purposes of this specification, we define a "duplicate   acknowledgment" as a segment that arrives carrying a SACK block that   identifies previously unacknowledged and un-SACKed octets between   HighACK and HighData.  Note that an ACK which carries new SACK data   is counted as a duplicate acknowledgment under this definition even if it carries new data, changes the advertised window, or moves the   cumulative acknowledgment point, which is different from the   definition of duplicate acknowledgment in [RFC5681].

其中

     "HighACK" is the sequence number of the highest byte of data that has been cumulatively ACKed at a given point.      "HighData" is the highest sequence number transmitted at a given point.

下面我们还是重点关注一下Linux实现上的处理吧。

三、SACK下的重传示例

1、SACK打开但是不携带SACK选项的场景

前面我们介绍快速重传示例的时候,都是把tcp_sack开关设置为0。其中有一个示例如下

 其中No12-No14三个数据包是不带有SACK选项的ACK确认包。可以看到server在接收到三个dup ack后触发了快速重传,我们设置tcp_sack为1后重新运行测试程序,抓包如下,可以看到server在接收到三个不带有SACK选项的dup ack后并没有触发快速重传,由此可以看到SACK下对于dup ACK理解上的差异。

2、带有SACK选项的快速重传

下面我们看一个带有SACK的快速重传,下面的测试程序与上面类似,同样打开tcp_sack功能,不同的时候这次在No12确认包中包含17-25的SACK块信息,在No13确认包中包含17-33的SACK块信息,在No14确认包中包含17-41的SACK块信息。No12-No14确认包的ack number都是9,在收到No14确认包后累计收到三个dup ACK,因此触发了快速重传。注意这里对dup ACK的认定并不是因为ack number相同,而是因为SACK块中累计反馈了三个发送出去的数据包。

3、SACK下ack number不同的dup ACK

上面我们说过SACK下对于dup ACK的认定并不是因为ack number不同。我们在来看一个例子,从下图可以看到wireshark显示两个dup ack后就触发了快速重传,实际上是因为wireshark对于dup ack的认定只关注ack number导致的。在No11中带有17-25的SACK块信息,No12中带有17-33的SACK块信息,No13中带有17-41的SACK块信息。按照上面SACK下对于dup ACK的定义,server实际上已经接收到了3个dup ACK,因此触发了快速重传。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值