TCP 层

什么是 Laminar?

Laminar 是适用于 TCP 拥塞控制的新框架,它将传输调度(精确确定何时发送数据)与纯拥塞控制(确定每次 RTT 期间发送的数据总量)分开。

默认的传输调度算法是 Van Jacobson 的数据包守恒原则 [Jacobson88] 的严格实现。数据到达接收器后会触发 ACK,进而导致发送方将等量的数据发回至网络。主要状态变量隐含在网络中循环的数据量和 ACK 的数量中。您可以通过改进的 tcp_packets_in_flight() Estimator(也称为 total_pipe)观察此状态。total_pipe 基于 RFC 3517 中所述的“pipe”,但还包括当前 ACK 报告的数据量以及已通过拥塞控制但正在等待其他事件(例如 TSO)的待处理传输。

新变量 CCwin 是主要拥塞控制状态变量。拥塞控制算法会调整 CCwin 以调节路径上的整体拥塞程度。虽然 CCwin 与 cwnd 类似,但 cwnd 会过载并被多个算法(例如突发抑制)使用,这些算法的目标不同,有时还会相互冲突。

只要 total_pipe 与 CCwin 不同,传输调度算法就会在响应每个 ACK 时略微调整发送的段数。启动缓慢和按比例降低速率 [PRR](用于替代速率减半)都已嵌入到传输调度算法中。

Laminar 框架的主要优势在于,通过将拥塞控制和传输调度划分到单独的子系统,每个子系统都会受到简单得多的设计限制,从而更轻松地开发许多使用先前的代码组织不可行的新算法。

Laminar 框架改变了 TCP 拥塞控制的基础设计理念,并且除了补丁本身之外,可能还具有广泛的影响。此补丁旨在让人们能够试验代码、添加注释,并帮助发现任何可能被忽视的极端情况。此外,补丁还不完整,因为许多算法仍然缺失,具体来说:除 CUBIC 和 Reno 以外的拥塞控制算法、cwnd 验证、目标指标等。如果人员可以帮助重构一些其他算法,将会非常棒。

在互联网草稿 draft-mathis-tcpm-tcp-laminar 中更详细地介绍了 Laminar 框架及其动机。

请将评论和建议发送至 mattmathis@google.com

Google 致力于通过协议改进提高网页速度,正是这项计划的一部分。

实现说明

Laminar 主要在 3 个函数 (tcp_input.c) 中实现:

Tcp_cong_avoid() 和 tcp_mult_decr() 使用 CCwin 状态变量执行 AIMD 拥塞控制。除了撤消之外,只有这两个函数才会让 CCwin 发生变化。(这两个函数都会调用特定于拥塞模块的处理程序)。

Tcp_laminar_schedule() 确定响应每个 ACK 时要发送的数据量。它实现了 Van Jacobson 数据包保护,稍微上下调整,以使 tcp_packets_in_flight() 收敛到 CCwin。

对 tcp_packets_in_flight() Estimator 进行了重要更改,使其在大多数协议事件中都保持不变。应用停止、tcp_laminar_schedule() 中的调整和实际丢包会改变 tcp_packets_in_flight()。ACK 处理、TSO 和大多数其他事件不会处理。请注意,当丢失时,传输中的实际数据包数量会立即发生变化,但在重新传输机制将其标记为丢失并递增 Lost_out 之前,这些数据包不会反映在 tcp_packets_in_flight() Estimator 中。

获取补丁

补丁针对的是 Dave Miller 的 net-next,并且完全应用于 3.5-rc2。
注意:除 Reno 和 CUBIC 之外的其他拥塞控制模块尚未更新,因此无法编译。如果您的配置构建了其他拥塞控制模块(例如 Vegas、可扩缩模块、高速模块等),则必须先停用这些模块。