要約

  • RFC 3517 は累積 ACK と SACK ブロックを送信側のスコアボードへ集め、SetPipe() でなお転送中と扱うオクテット数を推定した。
  • 未損失判定のまま再送したデータは二重に数えられ得た。cwnd - pipe は次の送信を許す局所条件であり、経路上の実数や配送完了ではない。

一つのウィンドウで複数のセグメントが失われると、累積 ACK だけでは連続した左端しか示せない。受信側は穴の先に届いた島を持っていても、その状態を単一の累積値に畳めない。RFC 2018 の SACK は、その不連続な範囲を通知できるようにした。

しかし通知は保管保証ではない。受信側は一度 SACK したデータを捨てることがあり、送信側は累積 ACK が進むまで再送バッファを解放できない。SACK は観測の粒度を上げたが、証拠を不可逆にはしなかった。

RFC 3517 はこの情報から実行可能な回復状態を作った。HighACK、HighData、HighRxt、RecoveryPoint が範囲を定め、Update() がスコアボードを更新する。IsLost() は上位に十分な不連続 SACK や十分なバイト数が現れたとき、対象を損失と判定した。

その判定は閾値に基づく推論である。どのルータ、どのキュー、どの原因で落ちたかを観測したわけではない。送信側が次の操作に必要な局所判断と、経路全体の事実は別のままだった。

SetPipe() は HighACK から HighData までを走査する。SACK されず損失とも判定されないデータは、まだネットワークにあると仮定して pipe に加える。HighRxt 以下の再送オクテットも加える。標準自身がこの結果を推定値と呼んだ。

特に重要なのが二重計上である。元の送信を損失と確定する前に再送すると、元コピーと再送コピーの両方を数える場合がある。送信側には一方だけが経路を離れたのか、両方なのか分からない。両方が消えたと決めつければ pipe を過小評価し、さらに多くを注入しかねない。

二重計上は粗雑さではなく、未知を抑制側へ割り当てる設計だった。単一フローの回復を少し遅くする可能性と、共有された混雑へ余分なトラフィックを入れる危険を比較し、後者を避けたのである。

回復開始時には RecoveryPoint を HighData に置き、輻輳ウィンドウを縮小し、最初の推定損失を再送して SetPipe() を実行する。その後の ACK ごとに状態を更新し、cwnd - pipe に一 SMSS 以上の余地があるときだけ NextSeg() が次を選ぶ。

この差はセンサー出力ではない。送信後に pipe を増やしても、特定キューへの投入、経路上での残留、受信、アプリケーション消費は証明されない。累積 ACK が RecoveryPoint を越えれば回復フェーズは終わるが、それも利用者の結果とは別である。

RFC 3042 の Limited Transmit は最初の重複 ACK を利用した。RFC 2883 の D-SACK は重複到着を報告し、不要な再送や並べ替えの兆候を与えた。RFC 5681 は輻輳制御の枠組みを、RFC 6582 は NewReno の部分 ACK 回復を記した。判断材料は増えても、経路内の直接計数にはならない。

RTO は最後の境界として残った。タイムアウト後は受信側の reneging を考え、以前の SACK を永続事実として扱えない。精密に見えるスコアボードも、期限と前提を持つ証拠だった。

RFC 6675 は 2012 年に RFC 3517 を置き換え、損失閾値、回復への入り方、救済再送を整えた。それでも pipe は推定値であり続けた。RFC 6937 の PRR は配送量に基づく別のペース調整を示した。回復勘定が制御方針であることを、この変遷が証明する。

現在の TCP 基本仕様は RFC 9293 であり、IANA は SACK-Permitted と SACK の番号を登録する。番号の権威は接続上の利用や配送を保証しない。RFC 3517 の歴史的価値は、見えない現実を見えたふりせず、それでも安全に動く変数を作った点にある。

情報源