3.5.2 Eifel 检测算法 [RFC3522]实验性的 Eifel 检测算法利用了 TCP 的 TSOPT 来检测伪重传 。在发生超时重传后,Eifel 算法等待接收下一个 ACK,若为针对第一次传输(即原始传输)的确认,则判定该重传是伪重传 。
与 DSACK 的比较:利用 Eifel 检测算法能比仅采用 DSACK更早检测到伪重传行为,因为它判断伪重传的 ACK 是在启动丢失恢复之前生成的 。相反,DSACK 只有在重复报文段到达接收端后才能发送,并且在 DSACK 返回至发送端后才能有所响应 。及早检测伪重传更为有利,它能使发送端有效避免“回退 N”行为 。
3.5.3 迁移 RTO 恢复算法(F-RTO)前移 RTO 恢复(Forward-RTO Recovery,F-RTO)[RFC5682]是检测伪重传的标准算法 。它不需要任何 TCP 选项,因此只要在发送端实现该方法后,即使针对不支持 TSOPT 的接收端也能有效地工作 。该算法只检测由重传计时器超时引发的伪重传,对之前提到的其他原因引起的伪重传则无法判断 。
F-RTO 的工作原理如下:1. F-RTO 会修改 TCP 的行为,在超时重传后收到第一个 ACK 时,TCP 会发送新(非重传)数据,之后再响应后一个到达的 ACK 。2.如果其中有一个为重复 ACK,则认为此次重传没问题 。3. 如果这两个都不是重复 ACK,则表示该重传是伪重传 。4.重复 ACK 是在接收端收到失序的报文段产生的 。这种方法比较直观 。如果新数据的传输得到了相应的 ACK,就使得接收端窗口前移 。如果新数据的发送导致了重复 ACK,那么接收端至少有一个或更多的空缺 。这两种情况下,接收新数据都不会影响整体数据的传输性能 。
四、拥塞状态机TCP 通过拥塞状态机来决定收到 ACK 时 cwnd 的行为(增长或者降低) 。TCP 拥塞状态机有 Open,Disorder,Recovery,Lost和CWR五种状态 。
文章插图
TCP拥塞控制状态机
4.1 Open当网络中没有发生丢包,也就不需要重传,sender 按照慢启动或者拥塞避免算法处理到来的 ACK 。
4.2 Disorder当 sender 检测到 dupack 或者 SACK,将会转移到 Disorder 状态,当处在这个这个状态中时,cwnd 将维持不变 。每收到一个 dupack 或 SACK,发送方将发送一个新包 。
4.3 CWR当 sender 收到 ACK 包含显示拥塞通知(ECN),这个 ECN 由路由器写在 IP 头中,告诉 TCP sender 网络拥塞,sender 不会立马降低 cwnd,而是根据快速恢复算法进行降窗,直到减为之前的一半 。当 cwnd 正在减小 cwnd,网络中有没有重传包时,这个状态就叫 CWR,CWR 可以被 Recovery 或者 Loss 中断 。
4.4 Recovery当 sender 因为快速重传机制触发丢包时,sender 会重传第一个未被 ACK 的包,并进入 Recovery 状态 。在 Recovery 状态期间,cwnd 的处理同 CWR 大致一样,要么重传标记了 lost 的包,要么根据保守原则发送新包 。直到网络中所有的包都被 ACK,才会退出 Recovery 进入 Open 状态,Recovery 状态可以被 loss 状态打断 。
- 经典 Reno 模式(非 SACK 模式)下,
文章插图
时退出 Recovery 状态 。
文章插图
Reno 模式退出Recovery状态
如上图,数据包 A、B、C 可能没有丢失只是被延迟接收,然而没有 SACK 机制下无法判断是 A、B、C 的重传触发的 3 次重复 ACK 还是新数据 1、2、3 丢失 1(或者 1、2 或者 1、2、3)导致的重复 ACK,两种情况均会马上把拥塞状态机带入到 Recovery 状态,然而前一种是不必要的 。如果在 SND_UNA== SND_HIGH 即转为 Open 态,那么当发生上述 1、2、3 的延迟到达后,紧接着的 Recovery 状态会再次将拥塞窗口减半,最终降低到一个极低值 。
- SACK/FACK 模式下,
文章插图
时退出 Recovery 状态 。因为即使发生经典 Reno 模式下的 A、B、C 失序到达,由于存在 SACK 信息,状态机会将此三个重复 ACK 记为三个重复的 DSACK,在 SACK 模式下,判断是否进入 Recovery 状态的条件是被 SACK 的数据包数量大于 dupthresh,而 DSACK 不被计入到 SACKed 数量中 。FACK 模式下只影响进入 Recovery 状态的时机,其核心仍建立在 SACK 之上,所以不影响退出的时机 。
文章插图
SACK/FACK模式退出Recovery状态
4.5 Loss
当 RTO 后,TCPsender 进入 Loss 状态,所有在网络中的包被标记为 lost,cwnd 重置为 1,通过 slow start 重新增加 cwnd 。Loss 与 Recovery 状态的不同点在于,cwnd 会重置为 1,但是 Recovery 状态不会,Recovery 状态下拥塞控制通过快速恢复算法逐步降低 cwnd 至 sshthresh 。Loss 状态不能被其它任何状态中断,只有当网络中所有的包被成功 ACK 后,才能重新进入 Open 状态 。
推荐阅读
- 如何基于TCP/IP协议进行MFC Socket网络通讯编程
- Treck TCP/IP协议库多个漏洞安全风险通告
- tcp,icmp,http 基于wireshark报文分析快速过滤报文时延
- 服务器海量TCP连接如何高效保活?
- 两万字深度介绍分布式,一文入魂
- TCP 半连接队列和全连接队列满了,怎么破?
- 说起来 TCP 的连接与释放真是个浪漫的故事呢!
- 网络安全常见协议解析:TCP、UDP、HTTP、FTP、SMTP等之间的区别
- 全网最强TCP/IP拥塞控制总结
- 轻松学习http知识让枯燥的内容变得生动有趣:TCP/IP四层模型