要約
- TCP同時オープンでは、同じソケット対に向けて双方が能動OPENを行う。ACKのないSYNが交差し、双方が
SYN-RECEIVEDへ移り、交差するSYN-ACKから一つの接続が成立する。 - 必要なのはクライアント役の選挙ではない。各端点が相手の現在の初期シーケンス番号を受け取り、自分の番号も確認されたと局所的に証明できればよい。
- NATはしばしば「送信SYNの次は受信SYN-ACK」という頻出形をTCP全体とみなした。RFC 5382は、許可済み接続なら受信SYNという正規の遷移も扱うよう求めた。
三本の矢印が役割を固定してしまった
教科書の図は明快だ。左のクライアントがSYN、右のサーバーがSYN-ACK、左がACKを返す。だがRFC 793は、能動OPENと受動OPENを定義すると同時に、二つのプロセスが互いに同時の能動OPENをしても正しく接続されると記した。非同期に動く分散計算には、この柔軟性が重要だった。
つまり、クライアントとサーバーはアプリケーション上の有用な役割ではあっても、TCP接続が成立するための身分ではない。通常の図は状態機械の一経路を示すにすぎず、誰が先に話す権利を持つかを定めてはいなかった。
同時オープンは珍しい事故への後付け対処でもない。最初の仕様に組み込まれた、接続同期の正規経路だった。
二つのSYNから一つの状態が生まれた
Aが初期番号100、Bが300を選ぶ。AはSYNを送りSYN-SENTへ進み、Bも同じことをする。二つのSYNは網内ですれ違う。
AはBの裸のSYNを受けても、自分の試行と衝突したとは判断しない。Bの開始番号を記録し、SYN-RECEIVEDに移り、301を確認するSYN-ACKを送る。Bも101を確認する。SYN-ACKが互いに届けば、双方は相手の開始点を知り、自分の開始点が届いたことも知る。
現行の統合仕様RFC 9293でも、両端の状態はCLOSED → SYN-SENT → SYN-RECEIVED → ESTABLISHEDとなる。パケット図は通常の三方向の並びと違っても、論理は同じだ。二つの開始番号を交換し、両方を確認する。
「プラス1」は受領証だった
SYNはシーケンス空間を一つ消費する。300のSYNに対するACKが301なのは、受信側がその制御点を越えたことを示すためだ。空のACK自身は空間を消費しない。そうでなければACKへのACKが無限に必要になる。
双方が発信しても、送信シーケンスは混ざらない。AとBは独立した起点を持つ。RFC 6528は後に、四つ組と秘密に結び付く擬似乱数関数を初期番号生成へ加え、推測攻撃への耐性を強めた。対称なのは開始の自由であり、番号の共有ではない。
接続を成立させる権威は肩書ではなく、各端点が検証できる証拠にある。ソケット対、現在の番号、相互の確認だけで十分だった。
二回のconnectは二接続を意味しない
両アプリケーションが能動的に呼び出したなら二つの接続だ、と実装者が考えるのは自然である。RFC 1122はその驚きを明示的に処理した。同時の接続試行から生まれるのは一つであり、これは意図的な設計なので「修正」してはならない。
Aから見たローカル/リモートの組は、Bからは逆向きに見える。しかし同じ四つ組である。二重化すれば情報が増えるのではなく、どちらにデータを流すかという不要な競合が増える。
ローカル手続きの数と共有されるネットワーク事実の数は違う。二つの要求があっても、同期された関連は一つである。
同じ状態名にも来歴が必要だった
SYN-RECEIVEDは、受動待受から入る場合と、能動OPEN後に相手のSYNを受けて入る場合がある。RFC 1122とRFC 9293は、その来歴を記憶するよう求める。RSTを受けた後に待受へ戻るかなど、回復動作が異なるからだ。
さらにRFC 793は、古い重複SYNが同時開始に見える可能性を指摘した。正しい解決は交差SYNを禁止することではない。現在期待するシーケンス、ACK、RST検証を使い、現行の接続と過去の残骸を分ける。
状態名だけでは状態機械は完成しない。どの経路でそこへ来たかという因果情報が、安全な次の判断を支える。
NATは人気のある筋書きだけを覚えた
典型的なNATでは、外向きSYNが対応表を作り、内向きSYN-ACKが続く。同時オープンでは、内向きに来るのはSYNである。RFC 5382は、それを未承諾トラフィックとして遮断するNATや、その後の外向きSYN-ACKを誤変換するNATを記録した。
端点はTCPに従い、NATも外向きSYNを見て接続状態を作っている。それでも中間装置が一つの頻出順序をプロトコル全体とみなせば、正規の会合は失敗する。
フィルターポリシーが接続を拒否することはあり得る。しかし許可した接続について、正しい遷移を「不正なTCP」と扱うのは別問題だ。RFC 5382は、許可された接続の全ての有効なTCP列を処理し、同時オープンも支えるようNATに要求した。
六秒は未来を知らないことの価格だった
遠隔SYNが、ローカルSYNによるマッピング作成より先にNATへ着く場合がある。その瞬間だけ見れば未承諾に見える。直ちにRSTやICMPを返せば誤りの通知は速いが、少し遅れてローカルSYNが来る正当な会合も終了させてしまう。
RFC 5382は最低六秒待つという妥協を置いた。その間に対応する外向きSYNが現れれば、早着SYNは黙って捨て、再送を完成済みマッピングへ通せる。現れなければ、セキュリティ方針に従ってエラーを返す。
六秒は自然法則ではない。不完全な観測のもとで、速い確定と可逆性をどう交換するかを可視化した値である。経路上の装置は未来を知らない以上、その無知を即時の不可逆判定に変えてはならない。
P2Pは古い対称性を再利用した
双方がNATの内側にいると、どちらも単純な受信側になれないことがある。だが両方が外向き状態を準備し、事前に共有したアドレスとポートへ向けてSYNを出せば、直接経路が成立する可能性が生まれる。
RFC 6544はICE TCPに能動、受動、同時オープン(S-O)の候補を定義した。ただし複数候補とリレーも推奨する。OS、NAT、ファイアウォール、移動先のネットワークが同じ能力を持つとは限らないからだ。
TCP仕様上の正当性と、あらゆる経路での到達性は別の主張である。同時オープンは端点の選択肢を作ったが、その選択肢を利用可能に保つ責任は周辺システムにも広がった。
持続したのは証拠に基づく対称性だった
共通層が定めたものは小さい。ソケット対を一致させ、二つの新しい起点を交換し、相互に確認し、回復に必要な履歴を保持する。その上で、アプリケーションは能動、受動、同時試行、リレーを選べる。
NAT時代の失敗は、端点が自由すぎたことではない。中間装置が多数派の形を規則へ昇格させたことだった。RFC 5382は、許可を決める権限と、許可したTCPを忠実に読む義務を分け直した。
両端が同時に電話をかけたとき、TCPは勝者を選ばなかった。互いの送受信を証明させた。一つの接続は役割の宣言からではなく、検証可能な共有状態から生まれた。
情報源と限界
根拠は RFC 793、RFC 1122、RFC 5382、RFC 6528、RFC 6544、RFC 9293 である。現在の利用率、全OSのAPI、全NATの適合性までは示さない。損失や再送で観測順序が変わる点にも注意が必要だ。
会員向け解説
プロフィールの詳細
適切な会員レベルでログインすると、解説全文と出典メモをご覧いただけます。
Strategic Circle 限定
Strategic Circle
すべての読者に公開されています。参加してログインすると プロフィール解説 を閲覧できます。
Strategic Circle に参加Leadership Alliance 会員限定
Leadership Alliance
対象となる IP 資産の所有者・管理者向けです。ログインすると Leadership Alliance の解説を閲覧できます。
Leadership Alliance に参加
