要約

  • TIME-WAITは時間による完全性の境界である。能動的に接続を閉じた側は、RFC 9293に従って2xMSLの間状態を保持し、前の接続のパケットが次の接続へ紛れ込む前に消滅する時間を確保する。
  • RFC 1337が記述した暗殺の連鎖では、受理できない古いセグメントがACKを誘発し、すでに閉じた相手がRSTを返す。そのRSTを受け入れると、TIME-WAITは隔離期間を終える前に削除される。

同RFCは、直後に接続を開き直した場合に三つの障害が起こり得ることを示した。ただし、実験は大量のセグメント複製を発生させるよう調整されたシミュレーションであり、現在の発生頻度を測ったものではない。

アプリケーションが処理を終えても、ネットワークの中身が同時に空になるわけではない。輻輳したリンクの手前でデータセグメントが遅れ、複製されたACKが長い経路を通って後から現れることがある。それらのパケットは、ソケットが閉じたことも、同じアドレスとポートの組み合わせが間もなく別の接続を指す可能性も知らない。

TIME-WAITは二つの履歴を混ぜないために状態を残す。能動的に閉じた側は最後の交換を終えても、直ちに送信制御ブロックを捨てない。RFC 9293は、そのコストを2xMSL、すなわち最大セグメント寿命の2倍と定めている。これは後回しにされた掃除ではない。同じ4タプルが再び意味を持つ前に、古いパケットがネットワークから消えるのを待つ仕組みである。

RFC 1337の発見が厄介なのは、古い通信を処理するための通常のTCP動作そのものが、この隔離を壊し得る点にある。

正しい応答が、誤ったリセットを作る

連鎖は、古いデータまたはACKセグメントが、まだTIME-WAITにいるエンドポイントAへ届くところから始まる。シーケンス番号やタイムスタンプが別の世代に属するため、そのセグメントは受理できない。Aは現在のSND.NXTRCV.NXTを含むACKを返す。

エンドポイントBは、すでにこの接続の状態を捨てている。存在しない接続へのACKを受け取ったBはRSTで応答する。AがそのリセットをTIME-WAITから離れる理由として扱えば、古いパケットより長く残るはずだった状態が消える。古いセグメントがAへ直接「閉じろ」と命じたわけではない。Aに正確な応答を送らせ、その応答が状態を持たないBから破壊的な制御信号を引き出し、最後にその信号が待機を終わらせる。RFC 1337はこの連鎖をTIME-WAIT Assassinationと呼んだ。

暗殺が起きただけでは、新しいアプリケーションへ古いデータが渡ったことにはならない。暗殺は、その事態を防いでいた境界を外す。実害が生じるには、古い複製が消える前に同じ接続識別子が再利用され、前後二世代のシーケンス空間がある程度重なり、さらに古いパケットが新しい状態で有効と判断される範囲へ入らなければならない。

RFC 1337は三つの結果を挙げる。H1では前の接続のデータを誤って受け入れる。H2では両端の状態がずれ、当時の仕様どおりに動くと、送られていない情報を確認し合ってACKループに陥り得る。H3では古いセグメントが接続確立中のリセットを引き起こし、いったん成功したように見えた新しい接続を終了させる。

この追加条件があるため、同RFCはH1、H2、H3を暗殺そのものより起こりにくいものとして扱っている。TIME-WAITの早期削除だけでは足りない。素早い再利用、シーケンス空間の重なり、適切な範囲に入る古い複製がそろう必要がある。文書はSunOS 4.1.1のTCPで現象を再現したが、セグメントを大量に複製し、必要な条件が生じるよう調整したシミュレーションを用いた。これは可能性の存在を示す実験であり、現代のネットワークにおける頻度や、特定の現行製品の挙動を示す証拠ではない。

三つの対策は、同じ範囲を守らない

RFC 1337が第一に挙げる対策は、TIME-WAIT中のRSTを無視することである。同文書が前提とする2分のMSLを守るなら、この方法はH1、H2、H3を防ぐとされる。理由は状態の役割そのものにある。古いセグメントが消えるのを待つ状態なら、認証されていない古い通信に待ち時間を短縮する権限を与えるべきではない。

ただし、勧告には明確な限界がある。RFC 1337はInformational文書であり、RSTを無視する変更に予期しない影響がないか、実運用で長期試験することを求めている。すべての実装がこの処理を採用したとも、どの環境でも無害だとも証明していない。

第二の案はTCPタイムスタンプとPAWSを使う。TIME-WAITが両端の時計が進むまで残れば、新しいSYNのタイムスタンプは古いセグメントより大きくなり、H1の古いデータを排除できる。しかし、H2とH3まで必ず消えるわけではない。古いACKがTIME-WAITに届くと、現在時刻のタイムスタンプを持つ新しいACKを生成し得る。その「新しく作られた古い複製」は、次の接続でPAWSを通過する可能性がある。

第三の案はシーケンス番号を64ビットへ広げることだ。空間を広げれば同じ領域の再利用までを非常に長くできるが、RSTによるTIME-WAITの早期削除は止められない。RFC 1337はこれを単独の修正ではなく、他のパラメータ変更と組み合わせて後続の危険を避け得る大規模なプロトコル変更として論じている。

現行の基礎仕様にも緊張関係は残る

現在のTCP基礎仕様であるRFC 9293も、能動的に閉じた側へ2xMSLのTIME-WAITを要求する。同じ相手からの新しいSYNをTIME-WAITから直接受け入れることはできるが、新しいISNを前の接続で使った最大値より大きくし、そのSYNが古い複製だと分かればTIME-WAITへ戻るという条件が付く。接続確立率の高いサーバー向けには、タイムスタンプを使った改良方式も参照している。

一方、基礎状態機械には問題の出口が残る。受理可能性の検査を通ったRSTをTIME-WAITで処理するとCLOSEDへ移り、制御ブロックを削除する。これに対し、相手のFINが再送された場合はACKを返し、2xMSLタイマーを再起動する。同じ状態へ届く二つの制御セグメントが、別々の分岐を通って境界を終わらせたり延長したりする。

したがって「TIME-WAITを減らす」だけでは設計を説明したことにならない。世代を隔てていた時間の代わりに、どの証拠を使うのかが抜けている。「状態を多く残す」だけでも、その状態を早期に消す信号へ耐えられるかは分からない。問うべきなのは、認証されていない古い通信より長く生きるための隔離を、どの証拠なら安全に終えられるのかである。

本稿の出典は、1992年5月にInformationalとして公開されたRFC 1337と、2022年8月にInternet Standardとして公開されたRFC 9293だけである。両文書は仕組み、成立条件、基礎規則を示すが、現在の発生頻度や特定製品の実装状況は示していない。