要約

  • 遠方の障害はゲートウェイ群が経路を組み直す。ホスト固有の仕事は、通知を返せなくなった直近ゲートウェイの死を見つけ、別の隣接ゲートウェイを試すことだった。
  • 収束中に届く単発のICMPエラーは、接続を終わらせる判決ではない。再送とユーザータイムアウトは深刻さを、エラー通知は推定原因を示した。
  • TCPのACKはアプリケーション処理の完了を証明しない。SMTPの最終応答と、無通信時のTelnet生存確認は、上位層が自ら管理する必要があった。

無通信では故障を観測する仕事も生まれない

RFC 816が挙げたサーバーTelnetの例は、タイムアウトへの素朴な期待を崩す。利用者が入力せずにいる時間に通信経路が失われることがある。次にキーを押した利用者は切断に気づく。しかしサーバー側に送信すべきデータがなければ、未確認セグメントも再送も発生せず、TCPは異常を知らせる材料を持たない。

アプリケーションから時折問い合わせれば生存確認はできる。ただし大規模システムの全アイドル利用者へ高頻度に送れば、ネットワークとホストに新たな負荷を作る。RFC 816は、無活動が長いなど「怪しい理由」が生じたときに確認する考え方を示した。

沈黙は、正常な待機、戻り経路の断絶、相手プロセスの停止を区別しない。どの沈黙をいつ調べるかは、会話の意味と古い状態を残す費用を知るアプリケーションの判断になる。

返事を出せない第一ホップ

IP側にも似た沈黙があった。RFC 816のゲートウェイは、隣接するネットワークとゲートウェイの状態について最新の見解を交換する。障害直後には見解が食い違っても、やがて別経路を含む整合したトポロジーへ落ち着く。遠方の故障なら、その近くのゲートウェイが迂回を担当できる。

ところがホストが直接使う第一ゲートウェイ自身が停止すると、RedirectもDestination Unreachableも返せない。ほかのゲートウェイが正しく収束していても、パケットはそこまで届かず消える。

そこでホストが担う障害分離は一点に絞られた。現在パケットを渡しているゲートウェイの死を検知し、直接到達できる別のゲートウェイを選ぶ。ホストにインターネット全体の経路計算を移すのではない。故障した当事者からは得られない局所情報だけを、最も近い観測者が処理する。

この証拠が許すのは第一ホップの交換までである。遠方のホストやサービス、利用者の処理が失敗したとはまだ言えない。

収束の途中で届いたエラー

RFC 816はICMP RedirectとDestination Unreachableを助言として説明した。Redirectはより良い直近ゲートウェイを示す。Unreachableは、その通知を作った時点の経路観測では到達できなかったことを示す。

障害直後、ゲートウェイは同時には更新されない。一つのパケットが古い見解を持つ地点を通り、単発のUnreachableを受けた直後に、新しい経路が成立することもある。その一通だけで確立済みTCP接続を破棄すれば、端点を変えずに内部を再構成できるインターネットの利点を失う。

だからといってICMPを捨てるのでもない。新規接続の開始時なら誤ったアドレスを示す可能性が高い。TCPが時間切れになった後なら原因を具体化できる。Parameter Problemなら実装上の欠陥も疑える。種類、コード、送信者、接続状態、時刻、ほかの信号との一致を残して初めて、情報の重みを判断できる。

一層の観測が上へ伝わることと、その観測が上位処理を終了させる権限を持つことは別だった。

確定診断の前に戻せる行動を取る

RFC 816は第一ホップ検知の候補を比較した。接続網が死活を直接知らせる場合もある。ICMP Echoで常時ポーリングすれば早く見つけられるが、必要な頻度ではホスト、回線、ゲートウェイに過大な負荷がかかる。個別分析で許容性を示さない限り、この方式は禁止された。

トリガー型ポーリングでは、TCPの反復再送など上位層の苦情が出てからIPが調べる。負荷は減るが、確認前にTCPの待ち時間が尽きるかもしれない。

トリガー型の再選択は、確認より先に次のゲートウェイを試す。元のゲートウェイが死んでいれば回復を早める。元が正常なら、代替ゲートウェイが転送し、Redirectによってより良い元の選択へ戻せる。

これは無根拠な切替ではなく、誤りを修正できる小さな実験だった。局所的な疑いに局所的な可逆行動で応じ、永久的な権威へ膨らませない。

RFC 1122は後に、経路キャッシュの次ホップ故障を検出し代替を選ぶことをIPの必須要件にした。同時に完全に満足できる万能アルゴリズムがないことを認め、第一ホップへの常時pingを禁じ、TCP、リンク、ARP、ACK、Redirectからの助言を優先した。

TCPの時間切れは原因名ではない

TCPは未確認セグメントを再送し、ACKか待ち時間の終端を待つ。再送の増加はIPに負の助言を与えられる。逆方向には、IPや接続網からICMPなどの情報が上がる。

再送は進捗がない事実を示す。ユーザータイムアウトはTCPの利用者が待つことをやめる境界を示す。ネットワークエラーは原因候補を示す。それぞれを一つの「障害」に潰すと、何を根拠に何を決めたかが消える。

RFC 1122は、規定されたソフトエラーで確立済み接続を中断してはならず、その情報をアプリケーションに渡すべきだとした。RFC 5461は、過渡障害からの復旧を待てる利点と、永久到達不能な第一アドレスが次の試行を遅らせる欠点を整理した。接続開始時の実装上の近道を記録しても、標準動作を変更してはいない。

RFC 9293でも、再送タイムアウトはキュー先頭のセグメントを送り直し、ユーザータイムアウトはキューを捨て、異常終了を通知して接続状態を削除する。同じ「時間切れ」でも、継続と終了という別の判断である。

ACKの後にも失敗は残った

早期のメール受信プログラムには、本文をすべて受け取った後、SMTPレベルの確認を返す直前に停止するものがあった。TCP上では全テキストが確認済みで、再送タイマーを起こす未確認データがない。送信プログラムはアプリケーション応答を永遠に待ち得た。

SMTP側のタイマーが必要だったが、短すぎれば遅いホストへの大きなメールを誤って失敗にし、長すぎれば本当の停止を遅く発見する。当時はメッセージ量に応じて時間を変える実装もあった。重要なのは特定の秒数ではなく、完了応答と作業量を知る層が期限を決めたことだ。

TCP ACKが証明するのは、該当するシーケンス空間が相手のトランスポートへ届いたことまでである。受信プロセスの存続、永続化、メール受付、業務完了までは証明しない。

助言にとどめたから組み合わせられた

RFC 816の設計は単一の万能検知器ではない。遠方の経路はゲートウェイ群が直し、沈黙した第一ホップはホストが交換し、TCPは停滞と待機終了を報告し、アプリケーションは自らの完了を確認する。

ICMPは無意味ではなく、絶対判決でもない。タイムアウトは深刻さを示すが原因を決めない。ACKは本物でも業務受領証ではない。部分的な事実を部分的なまま結び付けることで、過渡的矛盾を越えて回復できる。

エラー通知の力は、権限を限定したところにあった。原因を知らせ、局所行動を促しながら、最後の約束をした層から最終判断を奪わなかった。

出典