要約
- Network Virtual Terminalは端末差を消すのではなく、
CR LFを改行、CR NULを復帰だけとする最小の共通動作を定めた。 - CR直後の一文字が二つの意味を分ける証拠になり、送信側は意図を共通形式にし、受信側は自分のOSや端末へ写像できた。
- RFC 1123はEnterキーの曖昧さを整理し、Binaryは行末変換を止め、Net-UnicodeはCRLFを残しながらCR NULを避ける方向へ進んだ。
CRはまだ完結していない
NVTのprinterでは、Carriage Returnは印字位置を同じ行の左端へ戻す。Line Feedは横位置を保ったまま次の行へ移す。二つが続くと、次行の左端という「new line」になる。
初期の端末やhostは、この二動作を同じようには扱わなかった。別々に制御できる装置もあれば、一方が他方を伴う装置もあった。行をCRで区切るOS、LFで区切るOS、長さ付きrecordを使うOSもある。受信側がCRを即時実行すると、後続LFとの組合せを一動作として扱えない。反対に、ずっと待てば本当にCRだけを送った場合に終点がない。
RFC 318は1972年、CRを一時保持し、次の文字で決める案を示した。LFならnew line。CR単独の意図なら、送信側はCR NULを送る。NULはprinterを動かさないが、判断を完了させる。
「何もしない」という効果と「情報がない」は同じではない。この位置のNULは、LFが続かないことを明示していた。
仮想端末は中央の翻訳所ではなかった
RFC 854はTelnet接続の初期状態をNetwork Virtual Terminalとした。相手のterminal typeとOS規則を網羅的に交換するのではなく、各hostが自分の環境をNVTへ変換し、受け取ったNVTを自分の環境へ戻す。
共通層は小さい。NULはno operation、LFは縦方向の移動、CRは左端への復帰を表す。画面幅、page長、buffer、local character変換までは共有決定にしない。
その一方で、曖昧さに関わる規則は厳格だった。default NVT ASCIIで複合改行を求めるならCR LFを一つのnew-line characterとして扱う。復帰だけならCR NULを使い、他の文脈でCRを置かない。両方向に同じ規則が適用される。
受信時にはCRの後のNULを取り除いてからlocal mappingを行う。つまりNULはこの層の判別子であり、必ずapplicationへ渡すpayloadではない。ただし、別のmodeでも同じだと思い込む権利はない。
Enterはwire上の名前ではない
人間が押すReturnやEnterを何へ写すかは別問題だった。RFC 854はprinter出力の意味を詳しくしたが、User Telnetがend-of-line keyを受けた時の送信形を十分に一意化しなかった。
RFC 1123は、CR LFを送るclientとCR NULを送るclientが混在し、相互運用上の長期的な障害になったと記録する。ASCII serverはterminal inputとして両方をlocalの行終了keyと同じ効果にしなければならない。しかし非ASCII hostでは、CR NULを行終了と解釈するとbare CRを入力できなくなる場合がある。
修正はcontextを分けた。User TelnetはCR LF、CR NUL、LFのすべてを送れる必要がある。ASCII clientではCR LFとCR NULを選ぶmodeを設け、通常のend-of-line keyにはCR LFをdefaultとすることが推奨された。server outputやTelnet内の別application protocolのようにterminal-to-computer入力でないtextは、CR LFで行を終える。
server側もraw modeとformatted modeを区別する。前者ならapplicationへCRを渡せる。後者ならlocalの行規則を適用する。規格が合わせたのは境界での効果であり、内部byte列の永久的な同一性ではない。
Binaryでは行末を読まない
RFC 856のBinary optionは方向ごとに合意する。一方が要求し、他方が承認した方向だけが8-bit binary dataとして解釈される。逆方向は自動的には変わらない。
BinaryでもTelnet commandは消えない。IACはcommandの入口であり、dataとして255を送る時はIACを二重化する。しかしCRの行末処理は消える。RFC 1123は、Binary中にCRをCR NULやCR LFへ置換してはならないと明記した。
これはNVTの文字幅を増やすだけのoptionではない。どのparserがbyteを所有するかを変える。Binary streamから「CRの後だから」とNULを除けばdata corruptionであり、親切にNULを加えても同じ結果になる。
packet captureだけでなく、方向とnegotiation stateを保存しなければ、同じ三つのbyteを正しく評価できない。
Linemodeは編集場所だけを動かした
RFC 1184は長い遅延のあるnetworkで、keyごとのremote echoを待つ負担を減らした。EDIT modeならclientがlocalで一行を完成させ、通常のline terminatorをCR LFとして送る。
EDITを外すとcarriage returnはCR NUL、line feedはLF、ASCII一文字へ写せない「行を完了するkey」はCR LFになる。server outputはmodeにかかわらずserverが処理し、new lineはCR LF、復帰だけはCR NUL、linefeedだけはLFとする。
editingをuserの近くへ置いても、remote outputの意味をclientへ移す必要はなかった。性能上の配置と意味の所有は別々に変更できる。
Unicodeは古い例外を狭めた
RFC 5198はNet-Unicodeの歴史的背景としてNVT ASCIIを位置付けた。UTF-8 textのline endingにCRLFを採用し、CRの直後はLFまたはNULでなければならないという構造も残した。
ただしCR NULは避けるべきだとした。overstrikeやprinter layoutの需要は小さくなり、NULをstring terminatorに使うprogramming環境では危険になる。かつて必要だった復帰単独の表現より、installed baseを持つCRLFの継続が重くなった。
古い設計の否定ではない。共有abstractionがprinter motionからnetwork textへ変わり、必要な互換部分と退役できる例外が分かれたのである。
IANA Telnet Options registryにはBinary、Linemode、carriage-return dispositionなどが残る。登録はoption番号の根拠であり、現在の利用率や実装適合を証明しない。
一文字先を失えば、意図は復元できない
NVTの統制は薄かった。送信側が共通actionを選び、受信側は隣接するbyteだけで検証し、local mappingを自分で行う。mode変更にはpeerの同意が要る。
壊れるのは、この順序をshortcutした時だ。gatewayがstateを見る前に改行を正規化し、libraryがNULで文字列を切り、loggerがrender後のtextだけを残す。後から人間の意図を議論しても、protocolが用意した証拠は戻らない。
情報源と証拠の限界
- https://www.rfc-editor.org/rfc/rfc318.html
- https://www.rfc-editor.org/rfc/rfc854.html
- https://www.rfc-editor.org/rfc/rfc856.html
- https://www.rfc-editor.org/rfc/rfc1123.html
- https://www.rfc-editor.org/rfc/rfc1184.html
- https://www.rfc-editor.org/rfc/rfc5198.html
- https://www.iana.org/assignments/telnet-options/telnet-options.xhtml
これらは規則、後年の修正、option境界と登録語彙を示す。現在の普及率、個別製品のdefault、歴史上すべての実装の一致までは示さない。CR NULの意味は、明示されたdirectionとmodeの内部に限定する。
会員向け解説
プロフィールの詳細
適切な会員レベルでログインすると、解説全文と出典メモをご覧いただけます。
Strategic Circle 限定
Strategic Circle
すべての読者に公開されています。参加してログインすると プロフィール解説 を閲覧できます。
Strategic Circle に参加Leadership Alliance 会員限定
Leadership Alliance
対象となる IP 資産の所有者・管理者向けです。ログインすると Leadership Alliance の解説を閲覧できます。
Leadership Alliance に参加
