要約

  • 受信側が要求された文字集合をすでに使っていても、RFC 2066ではACCEPTEDが必須だった。沈黙は成功状態ではない。
  • クライアントとサーバーが同時にCHARSET REQUESTを送ったとき、サーバーはクライアント側の要求を拒否し、クライアントはサーバー側の要求に答えることで衝突を終わらせる。
  • ACCEPTEDが証明するのは特定要求の受領と後続テキスト用の文字集合選択である。後続バイト、変換、アプリ処理、認証、通信の安全までは証明しない。

あるTelnet端点が二つの文字集合を提案し、その後何も受け取らなかったとする。相手はすでに片方を使っているので黙ったのかもしれない。要求が失われたのかもしれない。実装がサブネゴシエーションを理解していないのかもしれない。要求側から見える記録は、どれも同じ沈黙である。

1997年1月にExperimentalとして公開されたRFC 2066は、この曖昧さを共有状態にしなかった。Telnetオプション42のCHARSETを定義し、クライアントとサーバーがテキストの符号化を名指しし、必要なら変換表を交換できるようにした。歴史的に重要なのは文字集合の種類よりも、変更を受領証で閉じる設計である。

基本交渉の防ループ規則は、そのままでは足りなかった

RFC 854のTelnetオプション交渉は、DO、DON'T、WILL、WON'Tを使う対称的な仕組みだった。双方が同時に同じオプションを求めれば、互いの要求を自分への肯定応答として扱える。一方、その対称性は無限の確認ループを生み得るため、すでに有効なモードへの要求には答えず、状態変更の要求には結果が変わらなくても答えるという規則が置かれた。

RFC 855は、パラメーターの話し合いをオプション利用の合意後に分離した。まずDO/WILLで「話し合う」ことに同意し、次にIAC SBからIAC SEまでのサブネゴシエーションで値を渡す。DO CHARSETとWILL CHARSETは交渉資格を作るだけで、次のテキストバイトの符号化を決めない。

そこでRFC 2066は、現在状態への要求を無視するという読み方を文字集合要求には適用しなかった。受信側が提示された集合の一つですでに送受信している場合でも、ACCEPTEDを返し、要求を無視してはならない。文書が掲げた理由は決定可能性だった。要求側にタイムアウトから返答を推測させない。そして肯定応答には応答しないため、明示化しても新たなループは始まらない。

リストは命令ではなく、順序付きの提案だった

CHARSET REQUESTを送れるのは、DO CHARSETを受信し、かつWILL CHARSETを送信した側だけである。順番は問わない。要求には一つ以上の文字集合名を優先順に並べる。私用のX-で始まらない名前はIANA登録が必要だが、受信側は自らの能力と選好に従って候補を選べる。

応答経路は四つに閉じていた。現在の集合を肯定する、別の対応可能な候補を選ぶ、要求側が許した場合に変換表を送る、どれも扱えなければREJECTEDを返す。肯定応答は要求リスト中の名前を指定する。否定応答も要求を受け取ったことは確認するが、この回の候補をすべて拒む。

ACCEPTEDもREJECTEDも現在のサブネゴシエーションを終える。前者は後続テキストに指定符号化を課し、後者は提案した符号化を有効にしない。どちらも一般的な成功・障害表示ではなく、実装能力の理由も将来の提案も決めない。

同時要求では片方を先に閉じる必要があった

資格を持つ両端が、相手のメッセージを見る前にCHARSET REQUESTを送ると、対称性が停止要因になる。新しい要求は既存要求への正しい応答ではない。追加規則がなければ、双方が相手の要求を保持しながら自分への終端応答を待つ。

RFC 2066は役割で対称性を破った。サーバーはクライアントの要求へ否定応答を返し、クライアントはサーバーの要求に答えなければならない。一方の提案が閉じ、もう一方がACCEPTED、REJECTED、または変換表経路へ進む。サーバーの好みを上位に置く道徳判断ではない。安定した役割から双方が同じ次状態を計算するためのタイブレークである。

拒否の後に新しい提案を出すことはできた。サーバーがアプリケーション側の集合を優先したいなら、クライアントの提案を拒否して自分から要求する。それも拒否されたなら、クライアントが当初扱えた集合に戻って提案できる。ただし各ラウンドは別々に完了しなければならない。選好は変わっても、受領境界は省略できない。

受領証はバイト列の境界でもあった

ACCEPTEDの後、双方は後続テキストを指定集合で符号化しなければならない。サブネゴシエーション中のデータはキューに置き、終了後に正しい集合で送ることが推奨された。応答は、古い理解に属するバイトと新しい理解に属するバイトを分ける順序点でもある。

適用範囲は限られる。変換対象はテキストであってTelnetコマンドではなく、BINARYモード時だけである。BINARYでなければNVT ASCIIが前提となる。ブロック端末ではEnd of Recordオプションの併用が推奨された。文字集合の合意だけで周囲のプロトコル条件は消えない。

変換表にもTTABLE-ACK、TTABLE-NAK、TTABLE-REJECTEDという別の終了経路があった。失敗後の再送は認めても、何度も失敗するなら否定応答で閉じ、無制限の再送にしない。RFCはここでも、疲労による停止より観測可能な終端状態を選んだ。

小さな主張だから受領証は強い

ACCEPTEDの記録から言えるのは、相手が特定の要求を受け取り、一覧中の名前を後続テキスト用に選んだということだ。その後のバイトが正しいこと、表変換が正確なこと、アプリが読めたこと、利用者の仕事が終わったことは分からない。REJECTEDも、この回の受領と拒否を示すだけで永久的な非対応を示さない。

安全性も別問題である。RFC 2066のSecurity Considerationsは、セキュリティー問題を論じないとだけ記した。符号化交渉は端点認証、利用許可、暗号化、完全性保護ではない。状態機械が正しく終わっても、通信路は安全とは限らない。

現在のIANA登録に42番CHARSETが残り、RFCがExperimentalとして存在することも、実装数や相互運用を証明しない。Lu Hengの後年の「最小初期仕様」から見れば、要求資格、終端返答、バイト境界、衝突規則だけを共有する薄い層と読めるが、これは編集上の比較であって著者の制度的意図ではない。歴史から確実に言えるのは、沈黙が複数の意味を持つなら、欠けている受領証をプロトコル化する必要があるということだ。

情報源