要約

  • RFC 938 では、確認ウィンドウ内にある DATA パケットの宛先ポートが未知なら、IRTP は現在の rcv_nxt を入れた PORT NAK を返し、データを破棄する。
  • その返答が確認するのはシーケンス上の累積受信であり、否定するのはポート番号である。アプリケーションの受信、認可、保存、処理完了を示すものではない。

「配達済み」という語は便利だが、何が起きたかをあまりに多く覆い隠す。RFC 938 の Internet Reliable Transaction Protocol は、その一語に逃げなかった。PORT NAK について、否定されるのはパケット番号ではなくポート番号だと明記した。ホスト間の受信状態は前に進み得る。しかしローカルに、そのデータを受け持つプロセスがいるとは限らない。この二つを一つの成功や失敗にしないことが、この小さな仕様の歴史的な強さである。

RFC 938 の情報ページ は、文書を 1985 年 2 月の experimental/proposed としている。従って、この資料から導けるのは設計された振る舞いであって、広範な導入、実運用の性能、現在のトラフィックではない。ここで読むべきなのは、どの主張をワイヤ上の事実として許し、どの主張をローカルな判断として残したかである。

IRTP は IP の上位に置かれた。RFC 791 は IP の Protocol フィールドが次の層のプロトコルを識別すると説明し、IANA の protocol-numbers registry は現在、番号 28 を IRTP として RFC 938 に結び付けている。これは番号の調整記録であり、実装や現用を数える記録ではない。

八オクテットに同居する別々の問い

IRTP のヘッダは八オクテットで、パケット型、ポート番号、シーケンス番号、長さ、チェックサムを持つ。型は SYNCH、SYNCH ACK、DATA、DATA ACK、PORT NAK の五つである。シーケンス番号が答えるのはホスト間の信頼性の問いであり、ポート番号が答えるのは、上位プロトコルまたはローカルプロセスをどこに振り分けるかという問いである。

一つのプロセスは複数のポートを claim できるが、一つのポート番号を claim できるプロセスは一つだけだった。また IRTP の connection は host と port の組ごとではなく、リモート Internet address ごとのホスト間関係だった。connection table には snd_nxt、rcv_nxt、snd_una などが置かれ、SYNCH と SYNCH ACK はその関係の状態を確立または再同期する。

ここでポートは、信頼性関係の名前ではない。すでに存在するホスト間の状態で、データがローカルな引受先を探す場面の問いである。シーケンスが進んだという事実と、ポートが引き受けられたという事実を同じラベルにする理由はない。

まずウィンドウ、次にポート

RFC 938 の受信手順はその順番を固定している。DATA を受けると、module はまずシーケンス番号が acknowledgement window にあるかを見る。該当するパケットでは rcv_nxt を再計算し、それからポートが known かどうかを調べる。

ポートが known なら、DATA ACK を返した後にデータを user process 用に queue できる。unknown なら PORT NAK を返し、データを捨てる。どちらの場合も応答のシーケンス欄には現在の rcv_nxt が入る。従って一つの交換には、累積受信の境界と、ローカルな振り分けの拒否という、両立する二つの事実が含まれる。

RFC はさらに、PORT NAK が sequence field にある番号までのすべてのパケット番号の reception を acknowledge し、NAK するのは port number であって packet number ではないと書く。これは再送要求ではない。存在しない受け手への入場許可でもない。負荷はその境界で破棄される。

受信、振り分け、結果を同じ証拠にしない

PORT NAK を含む記録から言えるのは限定される。IRTP module が受信 DATA を関係する範囲内として扱い、ある rcv_nxt までの累積状態を報告したこと。そしてその瞬間、指定されたポートを claim した process を知らなかったこと。この二つである。

そこから、application が bytes を読んだ、構文を受理した、送信者を認証した、操作を許可した、記録を永続化した、業務が終わった、とは言えない。サービスが永遠に不在だったとも言えない。port claim はローカルで時間とともに変わり得る。NAK は一つの時点の状態を記録するだけである。

証拠を三つに分けるべきである。sequence evidence は両 host module の関係について語る。port-claim evidence は受信側の local mapping について語る。application evidence があるなら、それは parse、identity、authorization、transaction、persistence という別の control surface に属する。下位二層の証拠が上位の決定を代弁することはできない。

この限定は Heng Lu Note 64 の考え方とも響く。共有する規則は最小で決定的、かつローカルに検証可能であり得る。しかし、その規則が後続のローカルな選択を命じることにはならない。ワイヤ上の確認はワイヤ自身の状態を語れるが、ポートを claim しなかった process や、データの意味を決める組織の権限を引き受けられない。

reliable は万能な運用方針ではない

RFC 938 は checksum、同期、acknowledgement、再送の枠組みを定めた。実装は再送を起動する仕組みを持ち、snd_una を再送しなければならない。しかし timer と retransmission strategy を一つに定めなかった。共有ヘッダは運用方針の所有者を指定しない。

リモート address が known になったときの二分間 quiet time についても、RFC 938 は RFC 793 を参照する。これは設計上の比較に限られる。IRTP を TCP と同一視する根拠にも、同じ semantics や導入履歴の根拠にもならない。

したがって reliable は期待する application endpoint が待っていることを意味せず、transaction は人や組織の処理完了を意味しない。仕様が提供したのは、限られた sequence handling と port dispatch の結果である。その間の責任の空白を消さなかった点に意味がある。

後から答えられる記録

PORT NAK を調べるなら、remote address、port、受信 sequence、返した rcv_nxt、window、connection epoch、checksum、packet type、同期の有無、当時の port claim を残す。RFC 938 が未規定にした timer と retransmission policy も別に保存する。

そうして初めて、port が claim されなかったケースと、port lookup の前に checksum または window で落ちたケースを分けられる。再同期と application failure、peer の再送反応とデータ受理も分けられる。「delivery failed」という一つのカウンタは、異なる control surface を一度に消してしまう。

出典と限界

パケット構造と受信手順は RFC 938、その experimental/proposed の地位は情報ページ、IP Protocol の役割は RFC 791、quiet time の比較は RFC 793、番号 28 は IANA による。これらはいずれも導入率、トラフィック、性能、現在の使用を示さない。

また PORT NAK は security や事業結果の証明ではない。一つの層で正しい acknowledgement が、次の層の受け手を発明しないこと。それがこの仕様の慎重さである。