跳到主要内容

3.2. Fast Retransmit/Fast Recovery

Receiver 行为​

当 out-of-order segment 到达时, TCP receiver 应该立即发送 duplicate ACK. 此 ACK 的目的是告知 sender 收到了乱序 segment, 以及期望的 sequence number.

Duplicate ACK 的成因​

从 sender 的角度看, duplicate ACKs 可能由多种网络问题造成:

  1. Dropped segments: dropped segment 之后的所有 segments 都会触发 duplicate ACKs, 直到丢失被修复
  2. 网络对 data segments 进行 re-ordering (在某些网络路径上并不罕见 [Pax97])
  3. 网络对 ACK 或 data segments 进行 replication

用于填补间隙的 ACK​

此外, 当 incoming segment 填补 sequence space 中的全部或部分 gap 时, TCP receiver 应该立即发送 ACK. 这会为通过 retransmission timeout, fast retransmit 或高级 loss recovery 算法从丢失中恢复的 sender 生成更及时的信息, 如 section 4.3 所概述.

Fast Retransmit 算法​

TCP sender 应该基于 incoming duplicate ACKs 使用 "fast retransmit" 算法检测并修复丢失.

fast retransmit 算法将 3 个 duplicate ACKs 的到达 (按 section 2 定义, 中间没有任何推进 SND.UNA 的 ACK) 作为 segment 已丢失的指示. 收到 3 个 duplicate ACKs 后, TCP 会重传看似缺失的 segment, 而不等待 retransmission timer 过期.

Fast Recovery 算法​

fast retransmit 算法发送看似缺失的 segment 后, "fast recovery" 算法控制新数据传输, 直到 non-duplicate ACK 到达.

理由​

不执行 slow start 的原因是, 收到 duplicate ACKs 不仅表示某个 segment 已丢失, 还表示 segments 很可能正在离开网络 (尽管网络中的大量 segment duplication 可能使这一结论失效).

换言之, 由于 receiver 只能在某个 segment 已到达时生成 duplicate ACK, 该 segment 已离开网络并位于 receiver 的缓冲区中, 因此我们知道它不再消耗网络资源. 此外, 由于 ACK "clock" [Jac88] 得以保留, TCP sender 可以继续传输新 segments (尽管传输必须继续使用降低后的 cwnd, 因为丢失是拥塞的指示).

Fast Retransmit 和 Fast Recovery 实现​

fast retransmit 和 fast recovery 算法按如下方式一起实现:

1. 第一个和第二个 Duplicate ACK​

sender 收到第一个和第二个 duplicate ACKs 时, 如果满足以下条件, TCP 应该按 [RFC3042] 发送一个此前未发送数据的 segment:

  • receiver 的 advertised window 允许
  • 总 FlightSize 将保持小于或等于 cwnd 加 2*SMSS
  • 有新数据可供传输

此外, TCP sender 不得改变 cwnd 以反映这两个 segments [RFC3042].

Note: 使用 SACK [RFC2018] 的 sender 不得发送新数据, 除非 incoming duplicate acknowledgment 包含新的 SACK 信息.

2. 第三个 Duplicate ACK​

收到第三个 duplicate ACK 时, TCP 必须将 ssthresh 设置为不超过 equation (4) 给出的值. 使用 [RFC3042] 时, limited transmit 中发送的额外数据不得纳入此计算.

3. 重传并膨胀 Window​

从 SND.UNA 开始的 lost segment 必须被重传, 且 cwnd 设置为 ssthresh 加 3*SMSS. 这会按已经离开网络并由 receiver 缓冲的 segments 数量 (三个) 人为 "inflates" congestion window.

4. 额外 Duplicate ACKs​

对于收到的每个额外 duplicate ACK (第三个之后), cwnd 必须增加 SMSS. 这会人为膨胀 congestion window, 以反映已经离开网络的额外 segment.

关于伪造 Duplicate ACKs 的说明​

Note: [SCWA99] 讨论了一种基于 receiver 的攻击, 即向 data sender 发送许多 bogus duplicate ACKs, 以人为膨胀 cwnd 并导致使用高于适当水平的发送速率. 因此, TCP 可以将 loss recovery 期间 cwnd 被人为膨胀的次数限制为 outstanding segments 的数量 (或其近似值).

关于 FlightSize 膨胀的说明​

Note: 未使用高级 loss recovery 机制 (如 section 4.3 所概述) 时, FlightSize 的这种增加可能导致 equation (4) 轻微膨胀 cwnd 和 ssthresh, 因为 SND.UNA 与 SND.NXT 之间的一些 segments 被假定已离开网络, 但仍反映在 FlightSize 中.

5. 发送此前未发送的数据​

当此前未发送的数据可用, 且 cwnd 新值和 receiver 的 advertised window 允许时, TCP 应该发送 1*SMSS 字节的此前未发送数据.

6. 收缩 Window​

当下一个确认此前未确认数据的 ACK 到达时, TCP 必须将 cwnd 设置为 ssthresh (step 2 中设置的值). 这称为 "deflating" window.

此 ACK 应是 step 3 中重传所引发的 acknowledgment, 在重传一个 RTT 后到达 (不过在 receiver 处存在显著 data segments 乱序交付时, 它可能更早到达).

此外, 如果 lost segment 与收到第三个 duplicate ACK 之间发送的所有中间 segments 均未丢失, 此 ACK 应确认所有这些中间 segments.

限制​

Note: 已知该算法通常无法从单个 flight of packets 中的多次丢失高效恢复 [FF96]. 下文 section 4.3 处理这类情况.