要約

  • TCPMUXではTCPポート1への接続後にサービス名を送り、肯定応答を受けてから同じ接続上で目的の通信を始める。複数のアプリケーションのデータを同時に混ぜる方式ではない。
  • 私的なサービスは独自の正式なポート割り当てを得ずに利用できる一方、予約名の意味と既存サービスの専用ポートは維持する必要があった。
  • inetdがプログラムに代わって肯定応答を送る構成もある。選択の承諾、プログラムの稼働、利用者の認証、仕事の完了は別々に確認しなければならない。

接続先が決まってから、相手を選ぶ

TCPの接続ができた時点で、目的のプログラムと話しているとは限らない。ポート1のTCPMUXは、まずサービス名を待つ。利用者が求める名前を受け付け、続けてよいと返答したところで、ようやくそのサービスの通信が始まる。

通常のポート番号が担っていた選択を、接続後の短い会話に一部移した仕組みである。1988年11月の RFC 1078 に、M. LottorがTCP Port Service Multiplexerとしてまとめた。仕様は短いが、どの段階で何が決まるのかがよく見える。

クライアントは大文字と小文字を区別しないサービス名を送り、末尾を復帰と改行で区切る。サーバーの応答はプラスまたはマイナスの符号から始まり、必要なら説明を付け、同じく復帰と改行で終える。肯定なら選んだプロトコルに進み、否定なら接続を閉じる。

重要なのは、その後も同じTCP接続を使うことだ。別のポート番号を教えてもらってつなぎ直すのではない。また、一つの接続の中に複数の通信路を設けて、異なるアプリケーションのデータを交互に流す規則でもない。共通の入口に複数の選択肢があり、一つの接続では一つを選ぶ。この意味での多重化だった。

共通番号と私的な実験の距離

知らない相手のホストに既知のサービスを求めるには、共通の接続先番号が便利である。各実装が同じ番号を同じ意味で使えば、クライアントはホストごとに私的な取り決めを結ばなくてよい。番号の共有は、小さな管理作業で大きな互換性を支えていた。

TCPMUXが参照した RFC 1010 は、1987年5月のAssigned Numbersである。各種番号の割り当てを記録し、新たな番号が必要な開発者に連絡先を示している。これは、あるホストでプログラムが動いているという記録ではない。独立した実装が番号の意味をそろえるための記録だった。

RFC 1078は当時のよく知られたポートの範囲を0から255と説明する。この数字をTCP全体で使える値の数と取り違えてはいけない。共通のサービス用として扱われた範囲と、TCPのポート欄が表せる範囲は別であり、現在の分類も当時とは異なる。

新しい私的なプロトコルにまで専用の正式番号が必要とは限らない。すでに相手とサービス名を共有できるなら、入口だけ共通にして、その先の対応表をホスト内に置ける。TCPMUXはこの可能性を利用した。新しい名前にどの実行プログラムを結び付けるかは、そのホストの運用者が決める。

だからといって、番号管理も運用上の許可もなくなったわけではない。ポート1という合流点と選択の書式は共通の約束である。プログラムを実行する権限、接続を通すネットワーク設定、利用者に許す操作は、それぞれ別に必要だ。少なくなったのは共通に決める項目であって、現実の運用条件ではない。

古い入口は残さなければならなかった

RFC 1078には、すでに専用の割り当てポートを持つサービスはそのポートで引き続き提供する、という制約がある。TCPMUXからの利用は追加の選択肢にすぎない。新しい入口を作ったからといって、古いクライアントの接続先を消してよいわけではなかった。

この制約には通信上の理由がある。従来のクライアントは、接続するとサーバーが先に挨拶を送ると期待しているかもしれない。TCPMUX側は先に名前を受け取るつもりで待っている。接続先番号だけを変えても、双方が待ち続ける関係は解消しない。新方式の採用には、新しい前置きを理解する実装が両端に必要になる。

名前にも継続性が求められた。Assigned Numbersに記載済みの名前は、そこで定義された意味を保つ。私的な名前は衝突しにくいものを選び、組織名を前に付けるなどの工夫が勧められた。版を区別するための末尾の表記も考えられていた。

ただし、組織名らしい文字列は身分証明にならない。名前の付け方が分かりやすいことと、その名前を使う者が本当に組織を代表していることは違う。版の表記も、相手のプログラムが意味を理解していなければ互換性を生まない。文字列の工夫が保証する範囲を広げすぎてはいけない。

HELPという予約名は、対応するサービスを一行に一つずつ返して接続を閉じるために使われる。この一覧は、そのホストで選べるものを知る手掛かりになる。しかし全世界のサービスを探す台帳でも、個々のプログラムが健康であるという証明でもない。項目が載っていることと、その利用者が実行を許されていることも分けて読む必要がある。

プラス記号を送るのは誰か

仕様上の境界は、実装の説明でさらに具体的になる。NetBSDのinetdマニュアル は、要求された名前を /etc/inetd.conf のサービス表で検索すると説明している。tcpmux/ 形式では呼び出されたサーバーが肯定応答を返す。tcpmux/+ 形式では、inetd側が代わりに返す。

後者なら、標準入力と標準出力を使う古いプログラムにTCPMUX専用の応答処理を加えずに済む。接続を渡す側が前置きを処理し、プログラムは自分の仕事から始められる。便利な適合方法だが、通信記録の読み方には注意を要する。

プラス記号を見ても、目的のプログラムが自ら準備完了を宣言したと即断できない。選択を受け付けた側が送っただけかもしれない。プログラムが利用者を認証したか、後続のデータを読んだか、要求された操作を終えたかは、その後の観測で確かめる。

責任の分担を誤ると、両方が肯定応答を送ったり、両方とも相手が送ると思って待ったりする可能性がある。余分な行がアプリケーションの入力に混ざる場合と、必要な行が来ない場合では原因が異なる。これは仕組みから導かれる診断上の注意であり、特定の過去の障害が起きたと主張するものではない。

FreeBSDのinetdマニュアルのソース には、個別サービスとは別に、入口となる多重化機能自体も有効にする必要があると明記されている。プログラム名を書いた設定があるだけでは、共通入口が受け付けているとは限らない。接続はプログラムの入出力用の記述子へ渡される。

こうした文書は、実装と設定の経路を確認する材料になる。何台が有効にしているかという普及調査ではない。また、どのプログラムをどの利用者権限で動かすかはホスト側の設定で決まる。公共の番号登録が、その決定を代行してくれるわけではない。

残った番号から普及の物語を作らない

2011年の RFC 6335 では、システムポートは0–1023、ユーザーポートは1024–49151、動的ポートは49152–65535と整理されている。サービス名だけを登録し、固定ポートを伴わせない方法もある。名前を共有することと番号を固定することは、必ずしも一体ではない。

2015年の RFC 7605 は、ポートをむやみに増やさず、プロトコル内の情報で版や通信の種類を区別する選択肢を扱う。TCPMUXと共通する設計上の問いは見えるが、それだけで直接の影響関係を断定することはできない。

現在の IANAのサービス名・ポート番号登録簿 にも、ポート1のtcpmuxが残っている。TCPとUDPの行が並んでいる点は慎重に扱うべきだ。RFC 1078が定義したのはTCPの会話であり、登録簿のUDP行から未記載の交換手順を作り出してはいけない。

番号が残ること、マニュアルが存在すること、設定が有効であること、実際に通信が観測されることは、それぞれ異なる証拠である。ここで確認できる資料は設計と実装を説明するが、大規模な採用や特定の衰退原因までは示さない。

TCPMUXの歴史的な意味は、勝者だったかどうかだけでは測れない。互通に必要な入口と言葉を共通にし、その先の選択を実際にプログラムを動かす側へ残した。同時に、旧来の接続先を奪わず、選択の承諾を仕事の完了と混同しないことも求めた。共通部分を小さくする設計には、境界を正確に守る仕事が伴っていた。