BBR 雖擁有精確管道模型,但若無封包持續發送與 ACK 回饋,模型無法更新、引擎將熄火。傳統快速重傳僅重傳一次,重傳再丟失會導致滑動窗口卡死,只能等待 RTO (超時重傳) — 代價極大。Linux 核心引入 RACK (Recent ACK) 機制,專門解決「重傳封包再次丟失」的快速恢復問題,為 BBR 提供源源不斷的可發送封包 (能量源)。
rack.mstamp),設定時間窗口 twin (預設 min_rtt/4)。// 1. 更新 rack.mstamp (處理每個 ACK/SACK 區塊)
void tcp_rack_advance(struct tcp_sock *tp, const struct skb_mstamp *xmit_time, u8 sacked);
// 2. 掃描重傳佇列,標記超過 twin 的封包為 LOST
int tcp_rack_mark_lost(struct sock *sk);
tcp_ack() 呼叫 tcp_rack_advance() 更新 rack.mstamptcp_fastretrans_alert() → 呼叫 tcp_rack_mark_lost()tcp_rack_mark_lost() 掃描重傳佇列:if (rack.mstamp - skb->skb_mstamp > twin) → 標記 LOSTpacing_rate 發送max_bw/min_rtt → BBR 模型持續精進假設發送順序 (含重傳) 為:1 | 2 | 3 | 7 | 8 | 6 | 4 | 5 (序號 4-8 為重傳,實際發送時間亂序)。
收到 ACK 確認 4 → rack.mstamp = 發送時間(4)。
封包 7,8,6 發送時間 早於 4,若 發送時間(4) - 發送時間(7) > twin → 判定 7 丟失,標記重傳。
完全忽略序號順序,只比較發送時間 — 解決重傳亂序導致的傳統邏輯失效。
twin = min_rtt / 4:基於 真實測量的離散 min_rtt (滑動窗口採樣),非平滑後的 SRTTmin_rtt/4 內,超過則極大機率真丟失| 模組 | 職責 | 互動 |
|---|---|---|
| BBR 演算法 | 計算 pacing_rate、cwnd (傳多少、多快) | 消費 RACK 提供的可發送封包 |
| TCP 擁塞狀態機 | 準備新資料、標記 LOST (RACK/傳統)、管理發送窗口 | 灌入 BBR 提供的「食道」 |
| TCP 傳輸邏輯 | 實際發送任意可用封包 (新資料/重傳/DSACK 等) | 產生 ACK 回饋給 BBR/RACK |
三者完全解耦,僅透過即時 ACK/SACK 回饋交互。BBR 不再因「無包可發」而熄火,RACK 確保重傳路徑暢通無阻。
# 核心參數 (4.1+ 預設啟用 RACK)
sysctl net.ipv4.tcp_recovery=1 # 1=啟用 RACK/THIN 等現代恢復邏輯
# 驗證 BBR + RACK 運行
ss -ti | grep -E "bbr|rack"