TCP-IP详解:SACK选项(wireshark抓包有SLE和SRE的SACK包)

1. 前言

TCP快速重传和超时重传都会面临到一个重传什么包的问题,因为发送端也不清楚丢失包后面传送的数据是否有成功的送到。主要原因还是对于TCP的确认系统,不是特别的好处理这种不连续确认的状况了,只有低于ACK number的片段都被收到才有进行ACK,out-of-order的片段只能是等待,同时,这个时间窗口是无法向右移动的。

假设服务器给客户端发送了序号为0-1000的数据包,客户端只收到0-800和820-1000的数据,序号为801-819的数据缺失。此时,客户端就会向服务器发送反馈,发送ACK=800并且增加SACK通知服务端收到了SLE=820,SRE=1000的数据包。那么,服务器就知道下次需要从seq=801开始发,并且发801-819这段数据,不需要重复发送820-1000的数据,因为此时已经收到了。
在这个过程中,SACK就能够保证发送端只传输中间丢失的部分数据,不需要重复发送已接收到的数据,提升网络效率。

2. 名词解释

SACK(Selective Acknowledgment)
SACK:selective ACK,即TCP的选项,来允许TCP单独确认非连续的片段,用于告知真正丢失的包,只重传丢失的片段
D-SACK:duplicate selective ACK,即使用SACK来告诉发送方有哪些数据被重复接收了。
SLE: Sequence Left Edge of already acknowledged data when Selective Acknowledgments are used,即已收到tcp数据的左边界。
SRE: Sequence Right Edge of already acknowledged data when Selective Acknowledgments are used, 即已收到tcp数据的右边界。

3. TCP SACK选项

SACK是一个TCP的选项,来允许TCP单独确认非连续的片段,用于告知真正丢失的包,只重传丢失的片段。要使用SACK,2个设备必须同时支持SACK才可以,建立连接的时候需要使用SACK Permitted的option,如果允许,后续的传输过程中TCP segment中的可以携带SACK option,这个option内容包含一系列的非连续的没有确认的数据的seq range,这些SYN包中SACK Permitted 选项,双方都支持才对。
在这里插入图片描述

3.1 SACK option格式

Kind 5 Length 剩下的都是没有确认的segment的range了 比如说segment 501-600 没有被确认,那么Left Edge of 1st Block = 501,Right Edge of 1st Block = 600,TCP的选项不能超过40个字节,所以边界不能超过4组。

3.2 SACK(RFC2018)

SACK通常是由数据接收方产生,如果在connection建立的时候,SYN包中有SACK-Permitted 的选项为true,同时自身也支持SACK,那么可以在接收异常的时候,产生SACK option. 如果要发送,SACK中需要携带接收队列中所有没有被确认的数据段信息。

如果接收方选择发送带有SACK的ACK,需要遵循如下规则:

  1. 第一个block需要指出是哪一个segment触发SACK option ,我认为就是谁乱序了,才会导致SACK

  2. 尽可能多的把所有的block填满

  3. SACK 要报告最近接收的不连续的数据块

接收端的行为:

  1. 数据没有被确认前,都会保持在滑动窗口内

  2. 每一个数据包都有一个SACKed的标志,对于已经标示的segment,重新发送的时候会忽略

  3. 如果SACK丢失,超时重传之后,重置所有数据包SACKed 标志

3.3 D-SACK(RFC2883)

D-SACK主要是使用了SACK来告诉发送方有哪些数据被重复接收了,如果是D-SACK,那么SACK option的第一个block代表被重复发送的序列片段

需要注意的点:

  1. D-SACK仅仅是接收端报告一个重复的连续的片段

  2. 每个重复的连续片段只能在一个block中

  3. 重复片段的序列号,特别注意右端序号应该是重复报文的最后一个seq + 1。(具体见下方)

  4. 第二个block指的是data没有被确认的

3.4 举例说明

  1. Reporting a Duplicate Segment
    如下图: 发送端发送seg1和seg2,但是接收端的ACK都被drop掉了,超时重传seg1,然后接收端就发了一个D-SACK,告诉发送端3000~3499重复接收,需要接收4000的。
    在这里插入图片描述
  2. 报告OUT-OF-ORDER段和重传段

从图中可以看出seg4 out-of-order会触发SACK,说明已经收到4500-5000的数据,中间丢了4001-4499的数据。但是这个ACK报文丢掉了。发送方又重传了seg1,接收方此时会生成D-SACK,block1中存放了dup的segment,block2中存放了收到但没有确认(ACK要等于5000才算是确认过)的segment。


RFC2883中对D-SACK的解释如下:左端是重复报文的第一个seq,右端是跟在重复报文的最后一个seq后面的序号,即重复报文的最后一个seq + 1。
在这里插入图片描述
还有比较多的例子,详细的可以参考 RFC2883

总起来说,D-SACK还是带了诸多的好处,能否让发送方了解是ACK丢了还是发送的数据包丢了,重复发送就说明是ACK丢了呗,同时也能够掌握网络上的一些事情,比如out-of-order,超时重传等,这样了解了网络,才能更好的做流控。

4. wireshark抓包分析

在这里插入图片描述

(1)编号为22440-22442为来自发送端的数据。从接收端应答的22443报文可以看出:当前ACK=1935,已经收到seq为3395(SLE)到4855(SRE)的数据,而seq为1935-3395的数据丢失。
(2)发送端继续发送seq为4855-6314的报文,即22445报文,从接收端的应答22446报文可以看到:接收端已经正确接收到
该段数据。因此,报文22446中的SRE就变成了6315(22444的SRE 4855 +22445的数据长度 1460)。
(3)接着发送端有一段数据(6315-7774)没有到达,导致在22451数据包中多了一组SLE +SRE。
(4)接下来可以看到发送端一直在持续的数据,但接收端的第一组SRE不断增大,其他参数一直不变,表明丢失的包一直没有到达。
(5)在22472中又多了一组SLE+SRE,表明中间又缺失了一段数据,分析同上。

5. 参考文献

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值