QUIC协议本身(RFC 9002)并没有强制规定必须使用哪一种拥塞控制。它只定义了拥塞控制器与QUIC协议栈交互的接口和信号

QUIC最流行的两种拥塞控制算法是CUBICBBR

RFC 中没有以特定编程语言的 API 形式来定义接口,但它描述了一套逻辑上的接口。可以其分为以下两类 conceptual API:

输入接口 (协议栈 -> 拥塞控制器)

这些是协议栈向拥塞控制器提供数据和事件的接口:

  • OnPacketSent(packet):
    • 何时调用: 每当一个数据包被发送时。
    • 传递信息: 数据包大小 (bytes_sent)、包号、是否需要确认 (is_ack_eliciting) 等。
    • 作用: 让控制器更新在途数据量 (bytes_in_flight)。
  • OnAckReceived(acked_packets):
    • 何时调用: 当收到一个 ACK 帧时。
    • 传递信息: 一个列表,包含了所有被确认的数据包的详细信息(包号、发送时间、数据包大小等),以及最新的 RTT 测量值。
    • 作用: 这是最主要的良性反馈信号,用于增加拥塞窗口,更新 RTT 估计。
  • OnPacketsLost(lost_packets):
    • 何时调用: 当丢包检测器宣告有数据包丢失时。
    • 传递信息: 丢失的数据包列表。
    • 作用: 这是最主要的拥塞信号,用于触发拥塞窗口减小等拥塞响应。
  • OnCongestionEvent(ecn_counts):
    • 何时调用: 当收到带有 ECN (显式拥塞通知) 标记的 ACK 时。
    • 作用: 提供了一个在丢包发生前的早期拥塞信号。

输出接口 (拥塞控制器 -> 协议栈)

这些是协议栈向拥塞控制器获取决策的接口:

  • GetCongestionWindow() -> bytes:
    • 作用: 协议栈通过此接口查询当前拥塞窗口 (cwnd) 的大小。这是决定能否发送新数据的核心依据。
  • GetPacingRate() -> bytes_per_second (可选但推荐):
    • 作用: 对于 BBR 等基于速率的算法,控制器可以直接提供一个建议的发送速率。协议栈应以此速率平滑地发送数据(Pacing),而不是瞬间把 cwnd 用完,以避免在网络中产生流量尖峰。
  • GetProbeTimeout() -> duration:
    • 作用: 查询 PTO (探测超时) 的时长,用于设置丢包检测计时器。