RFC793 日本語訳
0793 Transmission Control Protocol. J. Postel. September 1981. (Format: TXT=172710 bytes) (Updated by RFC1122, RFC3168) (Also STD0007) (Status: STANDARD)
RFC一覧
英語原文
RFC: 793 転送制御プロトコル DARPAインターネットプロトコル プロトコル仕様書 1981年9月 提出先 Defense Advanced Research Projects Agency Information Processing Techniques Office 1400 Wilson Boulevard Arlington, Virginia 22209 作成 Information Sciences Institute University of Southern California 4676 Admiralty Way Marina del Rey, California 90291 1981年9月 転送制御プロトコル 目次 前書き ......................................................... iii 1. 序説 ............................................................. 1 1.1 動機 .......................................................... 1 1.2 スコープ ...................................................... 2 1.3 このドキュメントについて ...................................... 2 1.4 インタフェース ................................................ 2 1.5 動作 .......................................................... 3 2. 考え方 ........................................................... 7 2.1 インターネットワークシステムの構成要素 ........................ 7 2.2 動作のモデル .................................................. 7 2.3 ホスト環境 .................................................... 8 2.4 インタフェース ................................................ 9 2.5 他のプロトコルとの関係 ........................................ 9 2.6 高信頼通信 .................................................... 9 2.7 コネクションの確立とクリア ................................... 10 2.8 データ通信 ................................................... 12 2.9 優先度とセキュリティ ......................................... 12 2.10 堅牢性の原理 ................................................. 13 3. 機能仕様 ........................................................ 15 3.1 ヘッダフォーマット ........................................... 15 3.2 用語解説 ..................................................... 19 3.3 シーケンス番号 ............................................... 24 3.4 コネクションの確立 ........................................... 30 3.5 コネクションのクローズ ....................................... 37 3.6 優先度とセキュリティ ......................................... 39 3.7 データ通信 ................................................... 40 3.8 インタフェース ............................................... 43 3.9 イベント処理 ................................................. 50 GLOSSARY ............................................................ 79 REFERENCES .......................................................... 85 [Page i] 1981年9月 転送制御プロトコル [Page ii] 1981年9月 転送制御プロトコル 前書き このドキュメントは、DoD標準の転送制御プロトコル(TCP)の説明である。この 標準が基にしているARPA TCP仕様書には以前の版が9つの存在し、現在の文章の 多くはこれらの版から集められたものである。多くの方が、コンセプトの面と文 章の面でこの作業に貢献してくれた。この版では、いくつかの細かい部分の明確 化、文字終端バッファサイズ調整の削除、プッシュ機能というレターメカニズム の記述の改訂を行った。 Jon Postel 編者 [Page iii] RFC: 793 置換: RFC 761 IEN 129、124、112、81、 55、44、40、27、21、5 転送制御プロトコル DARPAインターネットプログラム プロトコル仕様書 1. 序説 転送制御プロトコル(TCP)は、高信頼ホスト間プロトコルとしてパケット交換 型コンピュータ通信ネットワークや、それらネットワークを相互接続したシステ ムで使用することを想定している。 このドキュメントは、転送制御プロトコルによって実行される機能、このプロト コルを実装するプログラム、このサービスを要求するプログラムやユーザに対す るインタフェースについて説明している。 1.1. 動機 コンピュータ通信システムは、軍や政府、民間の環境でますます重要な役割を 果たすようになってきた。このドキュメントでは、特に通信の非信頼性に対す る堅牢さ、輻輳に対する可用性といった軍事コンピュータ通信の要求について 注目しているが、これらの問題の多くは民間や政府の分野でも同様に見受けら れる。 戦略・戦術コンピュータ通信ネットワークが発達・展開するにつれ、それらの 相互接続方法の提供、および広範囲なアプリケーションをサポートできる標準 的なプロセル間通信プロトコルの提供はきわめて重要なものとなってきた。こ のような標準が必要となることを見越して、国防研究技術次官代理は、この文 書で述べられている転送制御プロトコル(TCP)がDoD全域で使われるプロセス 間通信プロトコル標準の基礎となると表明している。 TCPは、コネクション型でエンド・エンド間の高信頼プロトコルであり、マル チネットワークアプリケーションをサポートするプロトコルのレイヤ階層構造 に合致するよう設計されている。TCPは、相互接続された2つのコンピュータ通 信ネットワークにそれぞれ接続されたホストコンピュータのプロセス間に高信 頼プロセス間通信を提供する。TCP層の下位にある通信プロトコルの信頼性に 関しては、ほとんどあてにしていない。TCPは、単純で低信頼なデータグラム サービスしか下位プロトコルからは得られないと仮定している。原則として、 TCPは、配線で接続されたものからパケット交換ネットワークや回線交換ネッ トワークまでにわたる幅広い通信システムの上で動作する必要がある。 TCPは[1]でCerfとKahnが最初に述べた概念を基にしている。TCPは、階層化 プロトコルアーキテクチャの中の基本的なインターネットプロトコル[2]の すぐ上に当てはまっており、インターネットプロトコルはTCPに対して、可変 長の情報セグメントをインターネットデータグラムの「封筒」に包んで送受信 する方法を提供している。インターネットデータグラムは、異なるネットワー クにある送信元TCPと宛先TCPのアドレスを指定する方法を提供する。また、イ [Page 1] 1981年9月 転送制御プロトコル 序説 ンターネットプロトコルは、複数のネットワークや相互接続ゲートウェイをま たぐような転送・配送を行なうのに必要なTCPセグメントのフラグメンテーシ ョンやリアセンブリも扱う。さらに、インターネットプロトコルはTCPセグメ ントの優先度やセキュリティ分類・コンパートメントの情報も運び、その結果、 この情報を複数のネットワークをまたいだエンド・エンド間で伝達可能である。 プロトコル階層 +------------------------+ | 上位 | +------------------------+ | TCP | +------------------------+ |インターネットプロトコル| +------------------------+ | 通信ネットワーク | +------------------------+ 図1 このドキュメントで書かれている状況のほとんどは、TCP実装と上位プロトコ ルがホストコンピュータ内で同居している状況を想定している。しかし、フロ ントエンドコンピュータ経由でネットワークに接続されているコンピュータシ ステムもある。ここで、フロントエンドコンピュータとは、TCP層とインター ネットプロトコル層の機能を持ち、さらにネットワーク固有のソフトウェアを 持っているものである。TCP仕様書では、適切なホスト・フロントエンド間の プロトコルが実装されていれば、フロントエンドでも実装可能と考えられるよ うな上位プロトコルへのインタフェースを記述している。 1.2. スコープ TCPは、複合ネットワーク環境において高信頼なプロセス間通信サービスを提 供できるよう考えられている。そして、複合ネットワークで一般的に使用され るホスト・ホスト間プロトコルになるように考えられている。 1.3. このドキュメントについて このドキュメントは、上位プロトコルとのやりとり、および他のTCPとのやり とりにおいてTCP実装にに求められる動作の仕様を述べたものである。この節 の残りの部分で、プロトコルのインタフェースと動作のごく簡単な概要を述べ ていく。第2節では、TCP設計に対する考え方の基本部分をまとめる。第3節で は、様々なイベント(新しいセグメントの到着、 ユーザ呼び出し、 エラーな ど)が発生した際、TCPに求められる動作の詳細な説明、およびTCPセグメント フォーマットの詳細を示す。 1.4. インタフェース TCPは、一方でユーザやアプリケーションプロセスとのインタフェースを持ち、 [Page 2] 1981年9月 転送制御プロトコル 序説 もう一方でインターネットプロトコルのような下位プロトコルとのインタフェ ースを持つ。 アプリケーションプロセスとTCPの間のインタフェースについては、かなり詳 しく説明している。このインタフェースは、ファイル操作のためにオペレーテ ィングシステムがアプリケーションプロセスに提供するコールとよく似た一連 のコールで構成されている。例えば、コネクションのオープンとクローズのコ ール、確立されたコネクション上でのデータの送信と受信のコールがある。ま た、TCPはアプリケーションプログラムとの非同期通信が可能であることも要 求される。TCP実装者が特定のオペレーティングシステム環境に合わせたイン タフェースを設計する際、非常に多くの自由度が許されているが、正しい実装 のためにTCPユーザ間インタフェースで要求される最低限の機能というものが ある。 TCPと下位プロトコルの間のインタフェースは、2つのレベルが非同期で情報を 渡し合うようなメカニズムがあることを仮定していること以外、基本的に決め られていない。通常は、下位プロトコルがこのインタフェースの仕様を決めて いる。TCPは、非常に一般的な相互接続ネットワーク環境で動作するよう設計 されている。この文書の中で仮定している下位プロトコルはインターネットプ ロトコルである[2]。 1.5. 動作 上記のように、TCPの主たる目的は、2つのプロセス間で高信頼で高セキュリテ ィの論理回線あるいは接続サービスを提供することである。信頼性の低いイン ターネット通信システムの上でこのようなサービスを提供するには、以下の分 野における機能を必要とする。 基本データ転送 高信頼性 フロー制御 多重化 コネクション 優先度とセキュリティ これら各分野におけるTCPの基本動作について以降の項で述べていく。 基本データ転送 TCPは、インターネットシステムの中で転送を行うためのセグメントに何オ クテットかをパッケージングして、ユーザ間の各方向でオクテットの連続的 なストリームを運ぶことができる。一般的にTCPは、いつデータを遮断し、 いつデータを転送するかを各自の都合で決定する。 ユーザは、TCPに投げたデータ全てが確実に転送されるようにしたい場合が ある。この目的のためにプッシュ機能が定義されている。TCPに投げたデー タが実際に転送されることを保証するために、送信ユーザは受信ユーザにこ のデータがプッシュスルー(完遂)されるべきだと指示する。プッシュする [Page 3] 1981年9月 転送制御プロトコル 序説 ことで、TCPは受信側に向けて、そのポイントまでのデータの転送および配 達を即座に行う。正しいプッシュポイントが受信ユーザ側で判らない場合も あるし、またプッシュ機能はレコード境界のマーカーを提供していない。 高信頼性 TCPは、インターネット通信システムによって破損、消失、重複してしまっ たデータや、順序がバラバラになったデータを回復しなければならない。こ れは転送される各オクテットにシーケンス番号を割当て、受信側のTCPから 肯定の確認応答(ACK)を求めることで達成される。ACKがタイムアウトの期 間内に受信できない場合、データが再送される。受信側ではシーケンス番号 を使って、バラバラに受信されたセグメントを正しい順序に並べたり、重複 を削除したりする。破損については転送される各セグメントにチェックサム を加えて、受信側で確認し、破損セグメントを廃棄することで処理される。 TCPが正しく動作し続けており、かつインターネットシステムが完全に分断 されてしまわない限り、転送エラーがデータの正しい配達に影響を及ぼすよ うなことは無いだろう。TCPはインターネット通信システムのエラーを回復 する。 フロー制御 TCPは、送信側が送るデータ量を受信側が管理する方法を提供する。これは、 正常に受信された最後のセグメントから更に受信可能なシーケンス番号の範 囲を示す「ウィンドウ」をACKと共に返すことによって達成される。ウィン ドウは、送信者が許可無しで転送できるオクテットの許容数を示している。 多重化 1つのホスト内で多数のプロセスが同時に TCP 通信機能を使用できるよう、 TCPはそれぞれのホスト内でのアドレスあるいはポートを提供する。インタ ーネット通信層のネットワークおよびホストアドレスと連結することによっ て、これはソケットを構成する。それぞれのコネクションはソケットのペア によって一意に識別される。言い換えると、1つのソケットが複数のコネク ションで同時に使われることもあるということだ。 ポートとプロセスのバインディングは各ホストで独立した扱いとなる。しか し、しばしば使われるプロセス(例えば "logger" や時分割サービス)を公 表されている固定ソケットに結び付ける方が便利であることが判る。こうし ておけば、アドレスが判るとこれらのサービスにアクセスできるようになる。 他のプロセスが持つポートアドレスの確認と学習には、より動的なメカニズ ムが必要となる。 コネクション 上記の高信頼性とフロー制御のメカニズムでは、各データストリームに対し てTCPがあるステータス情報を初期化し維持することが必要となる。この情 報の組合せにはソケット、シーケンス番号、ウィンドウサイズが含まれ、こ [Page 4] 1981年9月 転送制御プロトコル 序説 の組合せはコネクションと呼ばれる。各コネクションは、その両側を識別す るソケットのペアによって一意に特定される。 2つのプロセスが通信を行おうとするとき、お互いのTCPは最初にコネクショ ンを確立しなければならない(両側でステータス情報の初期化をしなければ ならない)。通信が完了した場合、コネクションを終了またはクローズし、 他のプロセスのためにリソースを開放する。 コネクションは信頼性の低いホスト間で、かつ信頼性の低いインターネット 通信システム上で確立しなければならないため、クロックベースのシーケン ス番号を持つハンドシェイクメカニズムを使用して、コネクションの初期化 誤りを起こらないようにしている。 優先度とセキュリティ TCPのユーザは、自分の通信のセキュリティの優先度を示すことができる。 この機能が必要無いときは、デフォルト値が提供される。 [Page 5] 1981年9月 転送制御プロトコル [Page 6] 1981年9月 転送制御プロトコル 2. 考え方 2.1. インターネットワークシステムの構成要素 インターネットワーク環境は、ゲートウェイ経由で次々に相互接続されたネッ トワークに接続されたホスト群で構成される。 ここで、 ネットワークはロー カルネットワーク (例えばイーサネット) か大規模ネットワーク (例えば ARPANET)のどちらかであるが、どちらの場合もパケットスイッチング技術を ベースにしている。メッセージを生成したり消費したりするアクティブなエー ジェントがプロセスである。ネットワーク、ゲートウェイ、ホストにおけるプ ロトコルの各種レベルでプロセス間通信システムがサポートされ、これによっ てプロセスポート間の論理コネクションにおける双方向データフローが提供さ れる。 ここでは一般的に、パケットという用語を、ホストとそのネットワークの間に おける1トランザクションのデータを表すのに使用する。ネットワークで交換 されるデータブロックのフォーマットは一般的に我々が感知しないところであ る。 ホストとはネットワークに接続されたコンピュータのことで、通信ネットワー クの観点から見るとパケットの送信元と宛先である。プロセスはホストコンピ ュータで動作しているアクティブな要素とみなされる(実行中のプログラムと いう非常に一般的なプロセスの定義に従う)。それぞれの端末とファイルや他 の入出力装置とはお互いにプロセスを使用して通信を行っていると見なされる。 したがって、全ての通信はプロセス間通信と見なされる。 プロセスは、自身と他のプロセス(またはプロセス群)との間の複数の通信ス トリームを識別しなければならないため、各プロセスは、他のプロセスのポー トと通信を行うポートを多数持てると仮定する。 2.2. 動作のモデル プロセスはTCPを呼び出し、引数にデータのバッファを渡して、データを転送 する。TCPはこのバッファに入っているデータをセグメントにパッケージング し、宛先TCPに各セグメントを転送するようにインターネットモジュールを呼 び出す。受信側TCPは、データをセグメントから受信側ユーザのバッファに入 れ、受信側ユーザに通知する。TCPは制御情報をセグメントに含めて、高信頼 で順序通りの転送を保証するのに使用する。 インターネット通信のモデルは、TCPと結び付けられているインターネットプ ロトコルモジュールが、ローカルネットワークへのインタフェースを提供して いるというものである。このインターネットモジュールは、TCPセグメントを インターネットデータグラムにパッケージングして、そのデータグラムを宛先 のインターネットモジュールまたは中間ゲートウェイにルーティングする。デ ータグラムは、ローカルネットワークで転送するため。ローカルネットワーク パケットに埋め込まれる。 パケットスイッチは、宛先のインターネットモジュールまでローカルパケット を配達するため、さらなるパッケージング、フラグメンテーションなどの操作 [Page 7] 1981年9月 転送制御プロトコル 考え方 を行うこともある。 ネットワーク間のゲートウェイでは、インターネットデータグラムがローカル パケットから「包装を解かれ」て、次にどのネットワークをインターネットデ ータグラムが通るべきかの決定を行われる。そして、インターネットデータグ ラムは次のネットワークに向かうのに適したローカルパケットに「包装され」、 次のゲートウェイ、もしくは最終的な宛先に向けて送られる。 次のネットワークでの転送に必要ならば、ゲートウェイはインターネットデー タグラムをより小さいインターネットデータグラムフラグメントに分割するこ とも許される。これを行うために、ゲートウェイはインターネットデータグラ ムの集合を作り出す。そして、そのデータグラムがそれぞれ1つのフラグメン トを運ぶ。フラグメントは、続くゲートウェイでより小さいフラグメントに再 分割されることもある。インターネットデータグラムフラグメントのフォーマ ットは、宛先インターネットモジュールがフラグメントをインターネットデー タグラムにリアセンブリできるよう設計されている。 宛先インターネットモジュールは(必要ならデータグラムをリアセンブリした 後)データグラムからセグメントを取り出し、宛先TCPに渡す。 この単純な動作モデルでは、細かい部分を多くごまかしている。1つの重要な 機能として、サービスタイプがある。これはゲートウェイ(あるいはインター ネットモジュール)に情報を提供し、次のネットワークに送る際に使用するサ ービスパラメータを選択する指針となる。サービスタイプ情報に含まれるもの には、データグラムの優先度がある。また、データグラムはセキュリティ情報 も運ぶこともでき、これによって、マルチレベルのセキュア環境で動作するホ ストやゲートウェイはセキュリティ要件に従って正しくデータグラムを分離す ることができる。 2.3. ホスト環境 TCPはオペレーティングシステムのモジュールであると想定している。ユーザ は、まるでファイルシステムにアクセスするかのようにTCPにアクセスする。 TCPは、例えばデータ構造管理などのために、他のオペレーティングシステム 機能を呼び出すこともある。実際のネットワークへのインタフェースは、デバ イスドライバモジュールで制御されていると想定している。TCPはネットワー クデバイスドライバを直接呼び出すのではなく、正しくは、代わりにデバイス ドライバを呼び出すインターネットデータグラムプロトコルモジュールを呼び 出すのである。 このTCPのメカニズムでは、フロントエンドプロセッサでのTCPの実装は適用外 である。しかし、このような実装におけるホスト・フロントエンド間プロトコ ルは、この文書で述べているTCPユーザインタフェースのタイプをサポートす るための機能を提供しなければならない。 [Page 8] 1981年9月 転送制御プロトコル 考え方 2.4. インタフェース TCP/ユーザのインタフェースは、コネクションのOPENやCLOSE、データのSEND やRECEIVE、コネクションSTATUS取得を行うために、TCP上のユーザが利用する コールを用意している。これらのコールは、例えば、ファイルのオープン、読 み込み、クローズのためのコールといった、オペレーティングシステム上のユ ーザプログラムからの他のコールと類似している。 TCP/インターネットのインタフェースは、インターネットシステムのどこか にあるホストのTCPモジュール宛てデータグラムを送受信するためのコールを 用意している。これらのコールは、アドレス、サービスタイプ、優先度、セキ ュリティなどを含む制御情報の受け渡しのためにパラメータを持っている。 2.5. 他のプロトコルとの関係 以下の図は、プロトコル階層構造におけるTCPの位置付けを示している。 +------+ +-----+ +-----+ +-----+ |Telnet| | FTP | |音声 | ... | | アプリケーションレベル +------+ +-----+ +-----+ +-----+ | | | | +-----+ +-----+ +-----+ | TCP | | RTP | ... | | ホストレベル +-----+ +-----+ +-----+ | | | +-------------------------------+ |インターネットプロトコル & ICMP| ゲートウェイレベル +-------------------------------+ | +-------------------------------+ |ローカルネットワークプロトコル | ネットワークレベル +-------------------------------+ プロトコル関係図 図2 TCP は 上位プロトコルを能率的にサポートできることが期待されている。 ARPANET TelnetやAUTODIN II THPのような上位プロトコルをTCPと接続するこ とは容易にできるべきである。 2.6. 高信頼通信 TCPコネクションで送信されるデータのストリームは、宛先において高信頼か つ順序通りに配達される。 転送はシーケンス番号と確認応答を使うことで信頼性が高められている。理論 [Page 9] 1981年9月 転送制御プロトコル 考え方 的にはデータの各オクテットにシーケンス番号が振られることになる。セグメ ント内データの先頭のオクテットのシーケンス番号は、そのセグメントととも に転送され、セグメントシーケンス番号と呼ばれる。また、セグメントは確認 応答番号も運び、これは逆方向の送信で次に期待されるデータオクテットのシ ーケンス番号である。TCPがデータを含むセグメントを送信するとき、再送キ ューにコピーを置き、タイマーを開始する。そのデータの確認応答を受信する と、そのセグメントはキューから削除される。もしタイマーが時間切れになる までに確認応答が受信されなかった場合、そのセグメントは再送される。 TCPによる確認応答はデータがエンドユーザに配達されることを保証するもの ではなく、受信側TCPがその責任を負ったということだけを保証している。 TCP間のデータのフローを管理するために、フロー制御メカニズムが用いられ ている。受信側TCPは送信側TCPに「ウィンドウ」を通知する。このウィンドウ はオクテット数を指定しており、その時点で受信側TCPが受信の準備をしてい る確認応答番号からのオクテット数である。 2.7. コネクションの確立とクリア TCPが処理できる個々のデータストリームを識別するために、TCPはポート識別 子を提供している。ポート識別子はそれぞれのTCPで独立して選ばれるので、 一意ではなくて構わない。各TCPの中で一意なアドレスを用意するために、TCP を識別するインターネットアドレスとポート識別子を連結させてソケットを作 る。これは、一緒に接続されている全ネットワークで一意になっている。 コネクションはエンドにおいてソケットのペアで完全に特定される。1つのロ ーカルソケットは様々な外部ソケットへの多数のコネクションに加わることが できる。コネクションは双方向にデータを運ぶのに使用できる。すなわち「全 二重」である。 TCPはポートとプロセスの関連付けを好きなように選ぶことができる。しかし、 いくつかの基本概念については全ての実装に必須である。TCPが何らかの方法 で「適当な」プロセスにだけ関連付けている既知(well-known)ソケットは必 須である。プロセスはポートを「所有」することができ、プロセスは所有する ポートでのみコネクションを開始することができると考えている(ポートをど うやって所有するかはローカルな問題であるが、Request Portユーザコマンド や、例えば、ポート名の上位ビットと特定のプロセスを関連付けるなど特定の プロセスにポート群を一意に割当てる方法を考えている)。 コネクションはローカルポート引数と外部ソケット引数によるOPENコールで指 定される。戻りとして、TCPはローカルコネクション名を提供し、この名前を 使ってユーザは以降のコールでコネクションを表す。コネクションについて覚 えていなければならない事柄がいくつかある。この情報を保存するために、転 送制御ブロック(TCB)と呼ばれるデータ構造がある。ローカルコネクション 名をこのコネクションに対するTCBへのポインタにするのも1つの実装である。 また、OPENコールは、コネクションの確立を能動的に追跡するか、受動的に待 ち受けるかというのも指定する。 [Page 10] 1981年9月 転送制御プロトコル 考え方 受動的OPEN要求は、プロセスがコネクションを開始しようとするのではなく、 コネクション要求がやって来るのを受け入れようとすることである。多くの場 合、受動的OPENを要求するプロセスは任意のコール元からのコネクション要求 を受け入れる。この場合、全て0の外部ソケットを使用して未指定ソケットを 示す。未指定外部ソケットは受動的OPENでのみ許される。 未知の他プロセスにサービスを提供するサービスプロセスは、未指定外部ソケ ットの受動的OPEN要求を出す。そして、このローカルソケットへのコネクショ ンを要求しているプロセスならどれでも、コネクションを張ることができる。 もしローカルソケットとこのサービスと関連付けが既知のものであるとしたら、 このことは助けになるだろう。 既知ソケットは、標準サービスとソケットアドレスを予め関連付けるための便 利なメカニズムである。例えば、「Telnetサーバ」プロセスは特定のソケット に恒久的に割当てられており、それ以外にもソケットはファイル転送、リモー トジョブエントリー、テキスト生成、エコー、シンクのプロセス(最後の3つ は試験目的)のために予約されている。ソケットアドレスは「ルックアップ」 サービスへのアクセスのために予約されている場合もある。このサービスは新 たに作成されたサービスを提供している特定ソケットを返す。既知ソケットの 概念はTCP仕様の一部であるが、ソケットのサービスへの割当てはこの仕様の 範疇ではない([4]を参照)。 プロセスは、受動的OPENを発して他のプロセスからの合致する能動的OPENを待 ち受け、コネクションが確立されたときにTCPから通知を受けることができる。 2つのプロセスが同時にお互いに対して能動的OPENを発した場合、正しく接続 されるだろう。この柔軟性は、構成要素がお互いについて非同期にふるまうよ うな分散コンピューティングのサポートのために重要である。 ローカルな受動的OPENと外部の能動的OPENのソケットが合致するのは、主に2 つの場合がある。1つ目は、ローカルな受動的OPENが外部ソケットを完全に指 定している場合である。この場合、正確に合致するはずだ。2つ目は、ローカ ルな受動的OPENが外部ソケットを指定していない場合である。この場合、どん な外部ソケットでもローカルソケットが一致する限り受け入れられる。その他 の可能性に含まれるものとして、部分的に制限された合致がある。 同じローカルソケットを持つ(TCBに記録されている)保留状態の受動的OPEN が複数ある場合、外部の能動的OPENは未指定外部ソケットを持つTCBを選択す る前に、その外部の能動的OPENの外部ソケットが指定されているようなTCBが 存在すれば、それと合致するだろう。 コネクションを確立するための手順は、同期(SYN)制御フラグを利用し、3つ のメッセージの交換を必要とする。この交換は3方向ハンドシェイクと呼ばれ ている[3]。 コネクションは、SYNを持つセグメントの到着と、それぞれユーザのOPENコマ ンドで作成された待ち受けTCBエントリーとが出会うことで開始される。ロー カルと外部のソケットが合致することで、いつコネクションが開始されたかが 判る。コネクションはシーケンス番号が双方向で同期されたとき「確立」とな [Page 11] 1981年9月 転送制御プロトコル 考え方 る。 コネクションのクリアはセグメントの交換も必要である。この場合、セグメン トはFIN制御フラグを持っている。 2.8. データ通信 コネクション上を流れるデータは、オクテットのストリームとして考えてよい。 送信側ユーザは各SENDコールの中で、そのコール(およびそれ以前のコール) のデータが即座にプッシュスルー(完遂)されるべきかどうか、PUSHフラグを 設定して受信側ユーザに通知する。 送信側TCPは、プッシュ機能が指示されるまで、送信側ユーザからのデータを 溜め込んで、自身の都合が良いときにセグメントに入れてそのデータを送信す ることができ、指示があったら全ての未送信データを全て送信しなければなら ない。受信側TCPは、PUSHフラグを見たら、送信側TCPからのデータをそれ以上 待たずにデータを受信側プロセスに渡さなければならない。 プッシュ機能とセグメント境界とに関連が無くても構わない。個々のセグメン ト内のデータは、全部または一部が1回のSENDコールの結果かもしれないし、 複数のSENDコールの結果かもしれない。 プッシュ機能とPUSHフラグの目的は、送信側ユーザから受信側ユーザにデータ をプッシュスルーすることである。これは記録サービスを提供するものではな い。 プッシュ機能とTCP/ユーザインタフェースを通るデータのバッファ使用は結 びついている。PUSHフラグと受信側ユーザのバッファ上のデータとが関連付け られるたびに、バッファが埋まっていなくても、処理するためバッファをユー ザに返す。PUSHが現れる前にデータが到着してユーザのバッファが埋まった場 合、データはバッファサイズ単位でユーザへ渡される。 また、TCPは、データストリームにおいて受信側が現在見ているポイント以降 に緊急データが存在することをデータの受信側に通知する手段を提供する。緊 急データが待ち状態にあると通知された際にユーザが具体的に何をするのかを、 TCPは定義することは考えていないが、受信プロセスが緊急データを迅速に処 理すべく動作に入ることは一般的な考え方である。 2.9. 優先度とセキュリティ TCPはインターネットプロトコルのサービスタイプフィールドとセキュリティ オプションを利用して、コネクション単位で優先度とセキュリティをTCPユー ザに提供する。必ずしも全てのTCPモジュールがマルチレベルのセキュア環境 で機能しなくてもよい。非機密の使用だけに限られるものもあるし、1つのセ キュリティレベルとコンパートメントだけで動作するものもある。したがって、 TCPの実装およびユーザへのサービスによっては、マルチレベルセキュアケー スの一部機能に限定してもかまわない。 [Page 12] 1981年9月 転送制御プロトコル 考え方 マルチレベルのセキュア環境をで動作するTCPモジュールは、出力セグメント にセキュリティ、コンパートメント、優先度を適切に書き込まなければならな い。また、このようなTCPモジュールはユーザあるいはTelnetやTHPなどの上位 プロトコルにインタフェースを提供して、望まれるコネクションのセキュリテ ィレベル、コンパートメント、優先度を指定できるようにしなければならない。 2.10. 堅牢性の原理 TCP実装は一般的な堅牢性の原理に従う。すなわち、行うことには堅実に、他 者から受けるときは寛容にである。 [Page 13] 1981年9月 転送制御プロトコル [Page 14] 1981年9月 転送制御プロトコル 3. 機能仕様 3.1. ヘッダフォーマット TCPセグメントはインターネットデータグラムとして送信される。インターネ ットプロトコルのヘッダは複数の情報フィールドを持っており、それには送信 元ホストアドレスや宛先ホストアドレスが含まれる[2]。TCPヘッダはインタ ーネットヘッダの後ろに置かれ、TCPプロトコル固有の情報を与える。このよ うに分離されているのは、TCP以外のホストレベルプロトコルの存在を考慮し てのことである。 TCPヘッダフォーマット 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 送信元ポート | 宛先ポート | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | シーケンス番号 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 確認応答番号 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | データ| |U|A|P|R|S|F| | | オフ | 予約 |R|C|S|S|Y|I| ウィンドウ | | セット| |G|K|H|T|N|N| | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | チェックサム | 緊急ポインタ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | オプション | パディング | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | データ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ TCPヘッダフォーマット 注:目盛りはそれぞれ1ビットの位置を示している。 図3 送信元ポート: 16ビット 送信元ポート番号である。 宛先ポート: 16ビット 宛先ポート番号である。 [Page 15] 1981年9月 転送制御プロトコル 機能仕様 シーケンス番号: 32ビット このセグメントの先頭のデータオクテットのシーケンス番号である(SYNが 立っているときを除く)。SYNが立っているときは、シーケンス番号は初期 シーケンス番号(ISN)となり、先頭のデータオクテットはISN+1となる。 確認応答番号: 32ビット ACK制御ビットがセットされている場合、そのセグメントの送信側が次に受 信することを想定しているシーケンス番号の値がこのフィールドに入る。コ ネクションが確立されれば、これは常に送信される。 データオフセット: 4ビット TCPヘッダ中の32ビットワード数である。これはデータの始まりがどこかを 示している。TCPヘッダは(オプションを含んでいるものでも)32ビット長 の整数倍である。 予約: 6ビット 将来使用するために予約されている。必ず0にする。 制御ビット: 6ビット(以下、左から右の順で) URG: 緊急ポインタフィールドが有効 ACK: 確認応答フィールドが有効 PSH: プッシュ機能 RST: コネクションのリセット SYN: シーケンス番号の同期 FIN: 送信側からの後続データ無し ウィンドウ: 16ビット 確認応答フィールドで示しているオクテットを始点として、このセグメント の送信側が受け入れ可能なデータオクテットの数。 チェックサム: 16ビット チェックサムフィールドは、ヘッダとテキストに含まれる全ての16ビットワ ードの1の補数の合計について、16ビットの1の補数を取ったものである。セ グメントに含まれるチェックサム対象のヘッダとテキストのオクテット数が 奇数だった場合、最後のオクテットは、チェックサムで16ビットワードとな るように、右側に0をパディングする。このパディングはセグメントの一部 として送信されない。チェックサムを計算する際、チェックサムフィールド 自身は0に置き換えられる。 また、チェックサムは概念的にTCPヘッダの前に付けられる96ビットの擬似 ヘッダも対象にする。擬似ヘッダは送信元アドレス、宛先アドレス、プロト [Page 16] 1981年9月 転送制御プロトコル 機能仕様 コル、TCP長を含んでいる。これは間違った経路で送られたセグメントに対 する防御である。この情報はインターネットプロトコルで運ばれ、TCP/ネ ットワークインタフェースを通してIP上のTCPによるコールの引数または結 果の中で受け渡しされる。 +--------+--------+--------+--------+ | 送信元アドレス | +--------+--------+--------+--------+ | 宛先アドレス | +--------+--------+--------+--------+ | 0 | PTCL | TCP長 | +--------+--------+--------+--------+ TCP長は、オクテット単位でTCPヘッダ長にデータ長を加えたもので(これ は明示的に転送される量ではなく、計算によるものである)、擬似ヘッダ の12オクテットは数えない。 緊急ポインタ: 16ビット このフィールドは、そのセグメントのシーケンス番号からの正のオフセット として現在の緊急ポインタの値を伝える。この緊急ポインタは緊急データの 直後のオクテットのシーケンス番号を指している。このフィールドはURG制 御ビットがセットされているセグメントでのみ解釈される。 オプション: 可変長 オプションは、TCPヘッダの後ろの部分を使うことができ、長さが8ビットの 倍数となる。全てのオプションはチェックサムに含まれる。オプションは任 意のオクテット境界で開始できる。オプションのフォーマットは2つのケー スがある。 ケース1: オプション種別単独オクテット。 ケース2:オプション種別オクテットとオプション長オクテット、実際の オプションデータオクテット群。 オプション長オクテットは、オプション種別オクテットとオプション長オク テット、およびオプションデータオクテット群をカウントしている。 オプションリストはデータオフセットフィールドが示すものよりも短い場合 があることに注意する。オプション終了のオプションから後のヘッダの内容 はヘッダパディング(すなわち0)でなければならない。 TCPは全てのオプションを実装していなければならない。 [Page 17] 1981年9月 転送制御プロトコル 機能仕様 現在の定義済みオプションは以下のものが含まれる(種別は8進数で表され ている)。 種別 長さ 意味 ---- ---- ---- 0 - オプションリストの終了 1 - ノーオペレーション 2 4 最大セグメントサイズ 指定オプション定義 オプションリスト終了 +--------+ |00000000| +--------+ 種別=0 このオプションコードはオプションリストの終了を示している。これは、 データオフセットフィールドによるTCPヘッダの終了と一致しない場合 もある。このオプションはそれぞれのオプションの終了ではなく、全て のオプションの終了を示すとき使用するものであり、オプションの終了 がTCPヘッダの終了と一致せずに異なっている場合だけ必要である。 ノーオペレーション +--------+ |00000001| +--------+ 種別=1 このオプションコードは、例えば、連続するオプションの開始をワード 境界に揃えるためなどで、オプションとオプションの間に使用する。送 信側がこのオプションを使用する保証はないので、受信者は、ワード境 界で始まらなくてもオプションを処理できるようにしていなければなら ない。 最大セグメントサイズ +--------+--------+----------+---------+ |00000010|00000100|最大セグメントサイズ| +--------+--------+----------+---------+ 種別=2 長さ=4 最大セグメントサイズオプションデータ: 16ビット このオプションがあるときは、このセグメントを送信したTCP側での [Page 18] 1981年9月 転送制御プロトコル 機能仕様 最大受信セグメントサイズを通知している。このフィールドが送信で きるのは、最初のコネクション要求(すなわち、SYN制御ビットが立 っているセグメント)のときだけである。このオプションが使われな かった場合、任意のセグメントサイズが許される。 パディング: 可変長 32ビット境界でTCPヘッダが終了してデータが始まるようにTCPヘッダのパデ ィングが使われる。このパディングは0の集まりである。 3.2. 用語解説 TCPの動作について深く議論する前に、詳しい専門用語をいくつか紹介する必 要がある。TCPコネクションの維持するためには、いくつかの変数を記憶して おく必要がある。この変数が、転送制御ブロックあるいはTCBと呼ばれるコネ クションレコードに格納される場合を考えてみる。TCBに格納されている変数 には、ローカルソケット番号とリモートソケット番号、コネクションのセキュ リティと優先度、ユーザの送信バッファおよび受信バッファへのポインタ、再 送キューへのポインタ、現在のセグメントへのポインタがある。さらに、送信 および受信シーケンス番号に関するいくつかの変数がTCBに格納されている。 送信シーケンス変数 SND.UNA - 未確認の送信 SND.NXT - 次の送信 SND.WND - 送信ウィンドウ SND.UP - 送信緊急ポインタ SND.WL1 - 最後のウィンドウ更新で使われたセグメントシーケンス番号 SND.WL2 - 最後のウィンドウ更新で使われたセグメントの確認応答番号 ISS - 初期送信シーケンス番号 受信シーケンス変数 RCV.NXT - 次の受信 RCV.WND - 受信ウィンドウ RCV.UP - 受信緊急ポインタ IRS - 初期受信シーケンス番号 [Page 19] 1981年9月 転送制御プロトコル 機能仕様 以下の図は、これらの変数のいくつかをシーケンス空間に結び付ける助けにな るものである。 送信シーケンス空間 1 2 3 4 ----------|----------|----------|---------- SND.UNA SND.NXT SND.UNA +SND.WND 1 - すでに確認応答済みの古いシーケンス番号 2 - 未確認のデータのシーケンス番号 3 - 新規にデータ転送許可を受けたシーケンス番号 4 - 未許可である使用予定のシーケンス番号 送信シーケンス空間 図4 送信ウィンドウは図4で3と書かれたシーケンス空間の部分である。 受信シーケンス空間 1 2 3 ----------|----------|---------- RCV.NXT RCV.NXT +RCV.WND 1 - すでに確認応答済みの古いシーケンス番号 2 - 新規に受信許可を受けたシーケンス番号 3 - 未許可である使用予定のシーケンス番号 受信シーケンス空間 図5 送信ウィンドウは図5で2と書かれたシーケンス空間の部分である。 この他にこの議論でしばしば使用される変数がいくつかある。これらの値は処 理中のセグメントのフィールドから取られる。 [Page 20] 1981年9月 転送制御プロトコル 機能仕様 カレントセグメント変数 SEG.SEQ - セグメントのシーケンス番号 SEG.ACK - セグメントの確認応答番号 SEG.LEN - セグメント長 SEG.WND - セグメントのウィンドウ SEG.UP - セグメントの緊急ポインタ SEG.PRC - セグメントの優先度値 コネクションは、その寿命の中で一連の状態を進行していく。 状態とは、 LISTEN、SYN-SENT、SYN-RECEIVED、ESTABLISHED、FIN-WAIT-1、FIN-WAIT-2、 CLOSE-WAIT、 CLOSING、LAST-ACK、TIME-WAIT、そして実在しない状態CLOSED である。CLOSEDは、TCBが無く、それゆえにコネクションが無いときの状態を 表現するので、これは実在しない。簡単に示すと、これら状態の意味は以下の 通りとなる。 LISTEN - 任意のリモートTCPおよびリモートポートからのコネクション要求 を待っていることを表している。 SYN-SENT - コネクション要求送信した後、それに対応するコネクション要 求を待っていることを表している。 SYN-RECEIVED - コネクション要求の受信と送信の両方を行った後、コネク ション要求の確認応答による承認を待っていることを表している。 ESTABLISHED - オープンコネクションを表しており、受信したデータはユー ザに渡せる。コネクションのデータ転送フェーズにおける通常の状態である。 FIN-WAIT-1 - リモートTCPからのコネクション終了要求、あるいは以前に送 信したコネクション終了要求の確認応答を待っていることを表している。 FIN-WAIT-2 - リモートTCPからのコネクション終了要求を待っていることを 表している。 CLOSE-WAIT - ローカルユーザからのコネクション終了要求を待っているこ とを表している。 CLOSING - リモートTCPからのコネクション終了要求の確認応答を待ってい ることを表している。 LAST-ACK - すでにリモートTCPへ送信したコネクション終了要求の確認応答 を待っていることを表している(これはリモートTCPのコネクション終了要 求の確認応答を含む)。 TIME-WAIT - リモートTCPがコネクション終了要求の確認応答を受信してい ると確信できるだけの時間を待っていることを表している。 CLOSED - 全くコネクションがない状態を表している。 [Page 21] 1981年9月 転送制御プロトコル 機能仕様 TCPコネクションはイベントを受けてある状態から別の状態へ進む。このイベ ントには、ユーザコール、OPEN、SEND、RECEIVE、CLOSE、ABORT、STATUS、さ らに入力セグメント、特にSYN、ACK、RST、FINフラグを持つもの、そしてタイ ムアウトがある。 図6の状態図は状態変化のみを、きっかけとなるイベントと結果の動作と一緒 に示しているが、エラー条件や状態変化に結びつかない動作は扱っていない。 後の節で、イベントに対するTCPの反応についてより詳しい説明を与える。 注意:この図は概要だけであり、仕様の全てと考えてはいけない。 [Page 22] 1981年9月 転送制御プロトコル 機能仕様 +---------+ ---------\ 能動OPEN | CLOSED | \ -------- +---------+<---------\ \ TCB作成 | ^ \ \ SYN送信 受動OPEN | | CLOSE \ \ -------- | | ------- \ \ TCB作成 | | TCB削除 \ \ V | \ \ +---------+ CLOSE | \ | LISTEN | ------- | | +---------+ TCB削除 | | SYN受信 | | SEND | | ------------ | | ------- | V +---------+ SYN、ACK送信 / \ SYN送信 +---------+ | |<----------------- ------------------>| | | SYN | SYN受信 | SYN | | RCVD |<-----------------------------------------------| SENT | | | ACK送信 | | | |------------------ -------------------| | +---------+ SYNのACK受信 \ / SYN、ACK受信 +---------+ | ------------ | | ------------ | x | | ACK送信 | V V | CLOSE +---------+ | ------- | ESTAB | | FIN送信 +---------+ | CLOSE | | FIN受信 V ------- | | ------- +---------+ FIN送信 / \ ACK送信 +---------+ | FIN |<----------------- ------------------>| CLOSE | | WAIT-1 |------------------ | WAIT | +---------+ FIN受信 \ +---------+ | FINのACK受信 ------- | CLOSE | | ------------ ACK送信 | ------- | V x V FIN送信 V +---------+ +---------+ +---------+ |FINWAIT-2| | CLOSING | | LAST-ACK| +---------+ +---------+ +---------+ | FINのACK受信 | FINのACK受信 | | FIN受信 ------------ | タイムアウト=2MSL ------------ | | ------- x V ----------------- x V \ ACK送信 +---------+ TCB削除 +---------+ ------------------------>|TIME WAIT|------------------>| CLOSED | +---------+ +---------+ TCPコネクション状態図 図6 [Page 23] 1981年9月 転送制御プロトコル 機能仕様 3.3. シーケンス番号 設計における基本的な概念は、TCPコネクション上で送られるデータの全ての オクテットがシーケンス番号を持つということである。全てのオクテットが順 序付けられているため、それぞれのオクテットに確認応答応答を行うことがで きる。採用された確認応答メカニズムは累積型で、シーケンス番号Xの確認応 答は、Xを除くX以前の全オクテットが受信されたことを示している。このメカ ニズムによって、再送する際、複製検知を単純にすることができる。セグメン ト内のオクテットの番号付けは、ヘッダの直後にある最初のデータが最も小さ い番号になり、続くオクテットは連続する番号となる。 実際のシーケンス番号空間は非常に大きいものだが有限であることを、覚えて おくのは大切なことである。この空間の範囲は0から2**32 - 1までである。こ の空間が有限であるため、シーケンス番号を使う全ての算術処理は、2**32の モジュロで実行されなければならない。この符号無し算術は、2**32 - 1から 0に再び循環することでシーケンス番号の関係を保っている。コンピュータの モジュロ演算には微妙なものがあり、そのためこのような値の比較のプログラ ミングには十分な注意が必要である。 記号“=<”は (2**32のモジュロで) 「〜より小さいか等しい」を意味する。 TCPが実行する典型的なシーケンス番号の比較には以下のものが含まれる。 (a) 確認応答が送信済みかつ未確認のシーケンス番号を指しているかの判 断。 (b) (例えば再送キューからセグメントを削除するために)あるセグメン トが使用している全てのシーケンス番号が確認応答済みかの判断。 (c) 入力セグメントが期待通りのシーケンス番号を含んでいる(すなわち、 そのセグメントが受信ウィンドウと「オーバーラップ」している)か の判断。 [Page 24] 1981年9月 転送制御プロトコル 機能仕様 送信データに対してTCPは確認応答を受け取る。以下の比較は確認応答の処理 のために必要なものである。 SND.UNA = 最も古い未確認のシーケンス番号 SND.NXT = 送信されるべき次のシーケンス番号 SEG.ACK = 受信側TCPからの確認応答(受信側TCPが期待する次のシーケンス 番号) SEG.SEQ = セグメントの先頭シーケンス番号 SEG.LEN = セグメント内でデータが使用するオクテット数(SYNとFINを勘定 に入れる) SEG.SEQ+SEG.LEN-1 = セグメントの最終シーケンス番号 新しい確認応答番号(「許容ack」と呼ぶ)は、以下の不等式を保つものであ る。 SND.UNA < SEG.ACK =< SND.NXT 再送キュー上のセグメントは、そのシーケンス番号と長さの和が入力セグメン トの確認応答番号値以下であるとき、完全に確認されたとする。 データを受信したときは以下の比較が必要である。 RCV.NXT = 入力セグメントの上で期待される次のシーケンス番号、および受 信ウィンドウの左端または下限 RCV.NXT+RCV.WND-1 = 入力セグメントに期待される最終シーケンス番号、お よび受信ウィンドウの右端または上限 SEG.SEQ = 入力セグメントが持っている先頭シーケンス番号 SEG.SEQ+SEG.LEN-1 = 入力セグメントが持っている最終シーケンス番号 セグメントは、 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND または RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND であるとき、有効な受信シーケンス空間の一部を占めていると判断される。 この判定の第1の部分は、セグメントの先頭がウィンドウ内に入るかどうかを [Page 25] 1981年9月 転送制御プロトコル 機能仕様 見るための確認であり、判定の第2の部分はセグメントの最後がウィンドウ内 に入るかどうかを見るための確認である。セグメントが判定のどちらかの部分 を満たしているなら、それはウィンドウ内のデータを持っている。 実際はこれよりも少々複雑である。ウィンドウ0や長さ0のセグメントがあるた め、入力セグメントの許容判定には4つのケースがある。 セグメ 受信ウィ 判定 ント長 ンドウ ------- -------- ------------------------------------------- 0 0 SEG.SEQ = RCV.NXT 0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND >0 0 許容されない >0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND または RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND 受信ウィンドウが0のとき、ACKセグメント以外のセグメントは受信可能ではな いことに注意してほしい。したがって、データ送信およびACK受信の間、TCPは 受信ウィンドウを0にしておくことが可能である。しかし、受信ウィンドウが 0のときでも、TCPは全ての入力セグメントのRSTフィールドおよびURGフィール ドを処理しなければならない。 また、特定の制御情報を保護するという目的にもこの番号方式を利用している。 これは制御フラグをシーケンス空間に暗に含めることで達成され、その結果こ の制御フラグを再送しても混乱せず確認することができる(すなわち、重複す る制御の1つだけに従うだろう)。制御情報はセグメントのデータ領域で物理 的に運ばれない。したがって、制御のためのシーケンス番号を暗黙に割り当て るためのルールを決めなければならない。この保護を必要とする制御はSYNと FINだけで、これらの制御はコネクションの開始と終了でしか使われない。シ ーケンス番号の目的から、SYNは自分を含むセグメントの最初の実データオク テットの前に現れると考えられ、FINは自分を含むセグメントの最後の実デー タオクテットの後に現れると見なされる。セグメント長(SEG.LEN)はデータ と、制御に付くシーケンス空間の両方を含んでいる。SYNがあるときSEG.SEQは SYNのシーケンス番号である。 初期シーケンス番号の選択 あるコネクションを何度も繰り返し使用することについて、プロトコルでは何 ら制限しない。コネクションはソケットのペアで定義される。コネクションの 新たなインスタンスをコネクションのインカーネーション(具体化)と呼ぶ。 このことから生じる問題は――「そのコネクションの以前のインカーネーショ ンからの重複セグメントなのかを、TCPがどのように判断するか?」――であ る。この問題は、コネクションのオープンとクローズを立て続けにした場合や、 コネクションがメモリ障害で壊れて、その後に再確立された場合に生じる。 [Page 26] 1981年9月 転送制御プロトコル 機能仕様 混乱を避けるため、以前のインカーネーションからの同一シーケンス番号がネ ットワーク内に存在している可能性がある間は、コネクションのインカーネー ションでその番号のセグメントを使用しないようにする必要がある。これは、 たとえTCPがクラッシュして、使用していたシーケンス番号の情報を全て失く したとしても、保証する必要がある。新しいコネクションが作成されるとき、 初期シーケンス番号(ISN)ジェネレータを使用して、新しい32ビットのISNを 選択する。このジェネレータは(おそらく仮想の)32ビットクロックで、下位 ビットが大体4マイクロ秒ごとに増加するようなものに限定される。したがっ て、ISNのサイクルはおよそ4.55時間ごとに一巡する。セグメントがネットワ ークに残り続けるのはたかが最大セグメント存続時間(MSL)分であり、MSLは 4.55時間よりも小さいと仮定すれば、ISNが一意であるという仮定は理にかな っている。 それぞれのコネクションには送信シーケンス番号と受信シーケンス番号がある。 初期送信シーケンス番号(ISS)はデータ送信側TCPによって選ばれ、初期受信 シーケンス番号(IRS)はコネクション確立の手続きの中で学習される。 確立あるいは初期化されたコネクションに対して、2つのTCPはお互いの初期シ ーケンス番号の同期を取らなければならない。これは“SYN”(同期を表す) と呼ばれる制御ビットと初期シーケンス番号を持つコネクション確立セグメン トの交換で行われる。略記としてSYNビットを持つセグメントを“SYN”とする こともある。したがって、このソリューションでは、初期シーケンス番号を選 ぶための適当なメカニズムと、ISNを交換するための多少複雑なハンドシェイ クが要求される。 同期を行うためには、双方が自身の初期シーケンス番号を送信し、その承認を 相手からの確認応答で受信することが必要である。また、双方が相手の初期シ ーケンス番号を受信し、承認する確認応答を送信することも必要である。 1) A --> B SYN 私のシーケンス番号はX 2) A <-- B ACK あなたのシーケンス番号はX 3) A <-- B SYN 私のシーケンス番号はY 4) A --> B ACK あなたのシーケンス番号はY ステップ2および3は1つのメッセージにまとめることができるので、これは3方 向(または3メッセージ)ハンドシェイクと呼ばれる。 3方向ハンドシェイクが必要なのは、シーケンス番号がネットワーク内のグロ ーバルなクロックに縛られておらず、TCPがISNを選ぶための様々なメカニズム を持てるからである。最初のSYNを受信した側は、そのコネクションで使用し た最終シーケンス番号を覚えていなければ(これはいつも可能であるとは限ら ない)、そのセグメントが以前の遅れてきたセグメントかどうかを知り得ない ため、送信側にこのSYNを確認するよう依頼しなければならない。この3方向ハ ンドシェイクとクロックドリブンのやり方は[3]で説明されている。 沈黙を継続する期間を知る ネットワークに残留する古いセグメントと重複する可能性があるシーケンス番 [Page 27] 1981年9月 転送制御プロトコル 機能仕様 号を持つセグメントを、TCPが作成しないようにするために、起動時に、ある いは使用していたシーケンス番号の記憶が消えてしまうようなクラッシュから の回復時に、TCPは最大セグメント存続時間(MSL)の間沈黙してから任意のシ ーケンス番号を割り当てなければならない。この仕様ではMSLを2分間にしてい る。これは工学的な選択であり、実験によって変更する方が良いと示されれば 変更しても構わない。TCPが何かの意図で再初期化されても使用中のシーケン ス番号の記憶が残っているなら、待つ必要など全く無いことに注意してほしい。 また、最近使ったものより大きいシーケンス番号を使うようにすることだけは しなければならない。 TCP沈黙時間の概念 この仕様書では、アクティブな(すなわちクローズしていない)各コネクシ ョンで転送された最終シーケンス番号の記憶を失うような「クラッシュ」を したホストは、少なくともホストが属するインターネットシステムで合意し た最大セグメント寿命(MSL)の間、TCPセグメントの送出を遅らせるべきだ と規定している。以降の段落では、この仕様の説明である。TCPの実装者は 「沈黙時間」制限に違反してもよいが、そうすることによって引き起こされ る、インターネットシステムの受信側で古いデータが新しいデータとして受 容されてしまう、あるいは新しいデータが古い重複データと見なされて拒絶 されてしまうといった危険は覚悟しておくことだ。 TCPは、セグメントが作られ送信元ホストのネットワーク出力キューに入れ られるたびにシーケンス番号空間を消費する。TCPプロトコルにおいて重複 検出および順序付けアルゴリズムは、セグメントデータからシーケンス空間 への対応が一意であることを前提としている。この前提は、シーケンス番号 に対応付けられたセグメントデータが配達され、受信側で確認応答が行われ、 そのセグメントの全ての重複コピーがインターネットから「消滅」する前に、 シーケンス番号が2**32の全ての値を一巡してしまわない限り成り立つ。こ のような仮定がなければ、場合によって2つの異なるTCPセグメントに全く同 じまたは部分的に重なるシーケンス番号が割り当てられることがあり、受信 側でどのデータが新しくどのデータが古いのか分からなくなる可能性がある。 各セグメントには、セグメント内のデータのオクテット数と同数の連続した シーケンス番号が対応付けられていることを覚えていてほしい。 通常の条件では、TCPは次に送出すべきシーケンス番号と一番古い確認応答 待ちの情報を保持して、先に使用したシーケンス番号が確認応答される前に 誤ってもう一度使わないようにしている。しかしこれだけでは古い重複デー タがネットから消滅していることを保証できないので、シーケンス空間を非 常に大きく取ることで、漂流している重複セグメントが到着してトラブルを 引き起こす可能性を減らしている。2メガビット/秒で、2**32オクテットの シーケンス空間を使い切るには4.5時間かかる。ネットにおける最大セグメ ント存続時間が数十秒を超えることはないので、たとえデータの速度が何十 メガビット/秒にまで増えたとしても、予測可能なネットに対してこれは十 分な保護と考えられる。100メガビット/秒では、一巡する時間は5.4分で多 少小さいかもしれないが、まだ適当な値である。 しかし、TCPの基本的な重複検出および順序付けアルゴリズムは、送信元TCP [Page 28] 1981年9月 転送制御プロトコル 機能仕様 が既存のコネクションで最後に使われたシーケンス番号の記憶を失ってしま ったとき崩壊する。例えば、TCPが全てのコネクションをシーケンス番号0か ら始めるとしたら、クラッシュや再起動の際、TCPは(ハーフオープンコネ クションを解決した後、可能な限り)以前のコネクションを再構成するが、 このとき同一コネクションの以前のインカーネーションの送出したパケット がネットワークに残っていて、それとシーケンス番号が一致するか一部重な るパケットを送出してしまう可能性がある。コネクションで使われたシーケ ンス番号の情報が無い場合、そのコネクションの以前のインカーネーション によるセグメントがシステムから消滅する時間を考慮に入れて、 送信元は MSL秒だけ待ってからそのコネクションのセグメントを送出するようTCPの仕 様は推奨する。 時刻を記憶でき、その時刻を使って初期シーケンス番号の値を選択するよう なホストであってもこの問題は付きまとう(すなわち、各コネクションの新 たなインカーネーションの初期シーケンス番号を時刻を用いて選択したとし てもである)。 例えば、コネクションを開くときシーケンス番号Sから始めたとする。この コネクションはそれほど使われておらず、初期シーケンス番号関数(ISN(t)) の値が、コネクション上でこのTCPが最後に送信したセグメントのシーケン ス番号S1と等しくなったと仮定する。この時点で、ホストがクラッシュした 後に復旧し、このコネクションの新しいインカーネーションが確立されたと 仮定する。選ばれた初期シーケンス番号は S1 = ISN(t) である――これは、 コネクションの古いインカーネーションで最後に使われたシーケンス番号に 他ならない! 回復があまりに早かった場合、ネットに残っていたS1付近の シーケンス番号を持つ古い重複パケットが到着し、これが受信側でコネクシ ョンの新しいインカーネーションの新しいパケットとして処理される可能性 がある。 この問題は、復旧するホストがどのくらいクラッシュしたか知ることができ ず、さらに以前のコネクションのインカーネーションによる古い重複パケッ トがシステム内に残留しているかどうか判らないことに起因する。 この問題を解決する1つの方法は、クラッシュから復旧した後は1 MSLだけセ グメントを送り出すのを故意に遅らせることである――これが「沈黙時間」 の仕様である。待ち時間を避けることを選び、宛先で新旧パケットの混乱が 起こる危険について構わないホストは、「沈黙時間」を待たないという選択 も可能である。実装する者はTCPユーザにコネクション単位でクラッシュ後 に待つかどうか選択する機能を提供してもよいし、簡単に全てのコネクショ ンに対して「沈黙時間」を実装してもよい。ユーザが「待つ」ことを選んだ 場合でも、ホストがMSL秒以上の間「アップ」した後なら待つ必要がないの は明白である。 まとめると次のようになる。送信された全てのセグメントはシーケンス空間 の1つ以上のシーケンス番号を使用する。セグメントに使われた番号はMSL秒 経過するまで「ビジー」あるいは「使用中」となる。クラッシュすると、最 後に送出したセグメントのオクテットによって空間・時間の1ブロックが占 有状態となる。もし新しいコネクションの開始が早すぎて、以前のコネクシ [Page 29] 1981年9月 転送制御プロトコル 機能仕様 ョンのインカーネーションの最終セグメントによる空間・時間の占有部分に 含まれるシーケンス番号を使った場合、シーケンス番号重複領域ができて、 これによって受信側が混乱する可能性がある。 3.4. コネクションの確立 「3方向ハンドシェイク」はコネクションを確立するために使われる手順であ る。この手順は通常、一方のTCPが開始し、もう一方のTCPが応答する。また、 2つのTCPが同時に手順を開始しても、この手順は動作する。同時の試みたとき、 それぞれのTCPは“SYN”を送信した後、確認応答を持たない“SYN”セグメン トを受信する。もちろん、古い重複“SYN”セグメントの到着によって、同時 コネクション開始が進行中であることが受信側で明らかになる可能性もある。 「リセット」セグメントを適切に使用することで、これらのケースの曖昧さを 無くすことができる。 コネクション開始の例をいくつか以降で紹介する。これら例ではコネクション の同期化を示すのにデータを運ぶセグメントを使っていないが、データが有効 なことが明らかになるまで受信側TCPがユーザにデータを配達しない(すなわ ち、コネクションがESTABLISHED状態になるまでデータは受信側でバッファさ れなければならない)のであれば、これは完全に正しい動作である。この3方 向ハンドシェイクはコネクション失敗の可能性を減らすことができる。これは、 この確認のための情報を提供するメッセージとメモリとのトレードオフの実装 である。 最も単純な3方向ハンドシェイクを以下の図7で示す。この図は以下のとおり解 釈をすべきである。それぞれの行には参照の目的で番号が振ってある。右向き の矢印(-->)は、TCP AからTCP Bに向けてTCPセグメントが出発したこと、あ るいはセグメントがAからBに到着したことを表している。左向きの矢印(<--) はその逆を表している。省略記号(...)は、ネットワークに残っている(遅 れている)セグメントを表している。“XXX”は、消失あるいは拒否されたセ グメントを表している。コメントは括弧の中に入れている。TCP状態はセグメ ント(その内容は各行の中央に示されている)の出発または到着の後の状態を 表現している。セグメントの内容はシーケンス番号、制御フラグ、ACKフィー ルドの省略形で示されている。それ以外のウィンドウやアドレス、長さ、テキ ストといったフィールドは明快にするために省略している。 [Page 30] 1981年9月 転送制御プロトコル 機能仕様 TCP A TCP B 1. CLOSED LISTEN 2. SYN-SENT -->--> SYN-RECEIVED 3. ESTABLISHED <-- <-- SYN-RECEIVED 4. ESTABLISHED --> --> ESTABLISHED 5. ESTABLISHED --> --> ESTABLISHED コネクション同期化のための基本的な3方向ハンドシェイク 図7 図7の2行目で、TCP Aはシーケンス番号100から開始するシーケンス番号を使う ことを示すSYNセグメントを送信することから始めている。3行目で、TCP Bは SYNを送信し、TCP Aから受信したSYNに対する確認応答を返している。確認応 答フィールドは、TCP Bがシーケンス100を使ったSYNを受け入れ、現在シーケ ンス101を待っていることを表しているのに注意する。 4行目で、TCP AはTCP BのSYNに対してACKの付いた空のセグメントを返してい る。そして5行目で、TCP Aはデータを送信している。5行目のセグメントのシ ーケンス番号が4行目と同じであることに注意する。これは、ACKはシーケンス 番号空間を使用しないからである(もし使用するとすると、ACKにACKを返す羽 目になるのだ!)。 同時開始は図8に示すように少しだけ複雑になる。それぞれのTCPはCLOSEDから SYN-SENT、SYN-RECEIVED、ESTABLISHEDへと循環する。 [Page 31] 1981年9月 転送制御プロトコル 機能仕様 TCP A TCP B 1. CLOSED CLOSED 2. SYN-SENT --> ... 3. SYN-RECEIVED <-- <-- SYN-SENT 4. ... --> SYN-RECEIVED 5. SYN-RECEIVED --> ... 6. ESTABLISHED <-- <-- SYN-RECEIVED 7. ... --> ESTABLISHED 同時コネクション同期化 図8 3方向ハンドシェイクの主たる理由は、古い重複したコネクション開始が混乱 を引き起こさないようにするためである。これを処理するために、特別な制御 メッセージ、リセットが導入されている。受信側TCPが非同期状態(すなわち、 SYN-SENT、SYN-RECEIVED)ならば、受容可能なリセットを受信するとLISTENに 戻る。TCPが同期状態(ESTABLISHED、FIN-WAIT-1、FIN-WAIT-2、CLOSE-WAIT、 CLOSING、LAST-ACK、TIME-WAIT)の1つであるならば、コネクションを中断し てユーザに通知する。この後で、「ハーフオープン」コネクションでこの後者 のケースについて議論する。 [Page 32] 1981年9月 転送制御プロトコル 機能仕様 TCP A TCP B 1. CLOSED LISTEN 2. SYN-SENT --> ... 3. (重複) ... --> SYN-RECEIVED 4. SYN-SENT <-- <-- SYN-RECEIVED 5. SYN-SENT --> --> LISTEN 6. ... --> SYN-RECEIVED 7. SYN-SENT <-- <-- SYN-RECEIVED 8. ESTABLISHED --> --> ESTABLISHED 古い重複SYNからの復旧 図9 古い重複からの復旧の簡単な例として、図9を考えてみよう。3行目で、古い重 複SYNがTCP Bに到着する。TCP Bはこれが古い重複であると判断できず、その ために通常通り応答する(4行目)。TCP AはACKフィールドが正しくないこと を検知し、セグメントを信用させるために選択されたSEQフィールドを付けて RST(リセット)を返す。TCP BはRSTを受け取るとLISTEN状態に戻る。オリジ ナルSYN(原罪の洒落である)が6行目でようやく到着し、同期化が通常どおり 進行する。6行目のSYNがRSTよりも先に到着した場合は、RSTが両方の方向で送 信されるような更に複雑な交換が発生する。 ハーフオープンコネクションとその他の異常 TCPの一方がコネクションを最後にクローズまたは中断したのに、もう一方が それを知らない場合、あるいは2つのコネクション終了がメモリロスによるク ラッシュが原因で非同期化した場合、確立されたコネクションは「ハーフオー プン」であると言われる。このようなコネクションは、どちらかの方向でデー タを送信しようとすると、自動的にリセットとなる。しかし、ハーフオープン コネクションは異常であると考えられ、緩やかな復旧手続きが必要となる。 サイトAでコネクションが無くなった場合、サイトBのユーザがそのコネクショ ンでデータを送信しようとするとサイトBのTCPはリセットの制御メッセージを 受信することになる。このメッセージはサイトBのTCPに対して何かが不正であ ることを通知し、コネクションを中断することを求めている。 [Page 33] 1981年9月 転送制御プロトコル 機能仕様 2つのユーザプロセスAとBはお互いに通信しているときに、クラッシュが発生 してAのTCPのメモリが失われたと仮定する。AのTCPを提供するオペレーティン グシステムによっては、エラー復旧メカニズムが存在することもあるだろう。 TCPが再び立ち上がったとき、Aが最初または復旧ポイントから再び起動するこ ともあるだろう。結果として、Aはたぶんコネクションを再びOPENを行おうと するか、オープンであると思ってコネクション上でSENDを行おうとするだろう。 後者の場合、ローカルな(Aの)TCPからエラーメッセージ「コネクションがオ ープンしていない」を受け取るだろう。コネクションを確立しようとする場合、 AのTCPはSYNを持ったセグメントを送信するだろう。このシナリオは図10で示 す例のようになる。TCP Aがクラッシュした後、ユーザはコネクションを再オ ープンしようとする。TCP Bはその間、コネクションが開いていると考える。 TCP A TCP B 1. (クラッシュ) (300送信、100受信) 2. CLOSED ESTABLISHED 3. SYN-SENT --> --> (??) 4. (!!) <-- <-- ESTABLISHED 5. SYN-SENT --> --> (中断!!) 6. SYN-SENT CLOSED 7. SYN-SENT --> --> ハーフオープンコネクションからの復旧 図10 3行目でSYNが到着したとき、TCP Bは同期状態であり、受信セグメントがウィ ンドウ外であるため、次に待っているシーケンスを示す確認応答(ACK 100) を返す。TCP Aはこのセグメントが送信したものの確認応答でなく、同期化さ れていないと考え、ハーフオープンコネクションが検知されたとしてリセット (RST)を送信する。5行目でTCP Bは中断している。そして、TCP Aはコネクシ ョンの確立しようと続ける。ここでこの問題は図7の基本的な3方向ハンドシェ イクに帰着する。 TCP Aがクラッシュし、TCP Bが同期されたコネクションと思っているコネクシ ョン上でデータを送信しようとするとき、別の興味深いケースが発生する。こ れを図11で示している。このケースでは、TCP BからTCP Aに到着した(2行目) データは、そのようなコネクションが存在しないために受け入れられず、TCP AはRSTを送信する。RSTは受け入れられ、TCP BはRSTを処理してコネクション を中断する。 [Page 34] 1981年9月 転送制御プロトコル 機能仕様 TCP A TCP B 1. (クラッシュ) (300送信、100受信) 2. (??) <-- <-- ESTABLISHED 3. --> --> (中断!!) アクティブ側が要因のハーフオープンコネクション検知\\ 図11 図12では、2つのTCP AとBがSYN待ちの受動的コネクションを持っていることが 判る。古い重複がTCP Bに到着し(2行目)、Bに動作を起こさせる。SYN-ACKが 返され(3行目)、これによってTCP AはRSTを送信する(3行目のACKは受け入 れられない)。TCP Bはリセットを受信して受動的なLISTEN状態に戻る。 TCP A TCP B 1. LISTEN LISTEN 2. ... --> SYN-RECEIVED 3. (??)<-- <-- SYN-RECEIVED 4. --> --> (LISTENに戻る!) 5. LISTEN LISTEN 古い重複SYNによって開始する2つの受動的ソケット上でのリセット 図12 これ以外にも様々なケースがあり得て、その全てが以下のRST生成および処理 に関するルールで説明される。 リセット生成 一般的なルールとして、現在のコネクションにそぐわないことが明白なセグメ ントが到着したときは、リセット(RST)を必ず送信しなければならない。今 がそのケースであると明らかでない場合はリセットを送信してはならない。 状態は3つに分けられる。 [Page 35] 1981年9月 転送制御プロトコル 機能仕様 1. コネクションが存在しない場合(CLOSED)、他者からのリセット以外の 全ての受信セグメントに対してリセットを送信する。特に、存在しないコネ クションに対するSYNは、この方法で拒否する。 受信セグメントにACKフィールドがある場合、リセットのシーケンス番号は 受信セグメントのACKフィールドを採用するか、そうでない場合はリセット はシーケンス番号0を使い、ACKフィールドをシーケンス番号と受信セグメン トのセグメント長とを足した値にする。コネクションはCLOSED状態のままと なる。 2. コネクションが同期化されていない状態(LISTEN、SYN-SENT、SYN- RECEIVED)で、受信セグメントが未送信のものに対する応答である場合、あ るいは受信セグメントが持つセキュリティレベルやコンパートメントが、コ ネクションが要求するレベルとコンパートメントに完全一致しない場合、リ セットが送信される。 こちらのSYNに対する応答が無く、受信セグメントの優先度が要求される優 先度よりも高い場合、(ユーザとシステムによって許可されるなら)ローカ ルの優先度を上げてしまうか、リセットを送信する。あるいは受信セグメン トの優先度が要求される優先度よりも低い場合、あたかも優先度が完全に一 致したかのように続ける(リモートTCPが優先度を上げて、こちらに合わせ ることができない場合、これは次に送信されるセグメントにて検知され、そ の後にコネクションが終了させられる)。こちらのSYNに対して(場合によ っては今来た受信セグメントで)応答があった場合、受信セグメントの優先 度はローカルの優先度と完全に一致しなければならず、そうしない場合はリ セットを送らなければならない。 受信セグメントにACKフィールドがある場合、リセットのシーケンス番号は 受信セグメントのACKフィールドを採用するか、そうでない場合はリセット はシーケンス番号0を使い、ACKフィールドをシーケンス番号と受信セグメン トのセグメント長とを足した値にする。コネクションは同じ状態のままとな る。 3. コネクションが同期化状態(ESTABLISHED、FIN-WAIT-1、FIN-WAIT-2、 CLOSE-WAIT、CLOSING、LAST-ACK、TIME-WAIT)の場合、受け入れられないセ グメント(ウィンドウ外のシーケンス番号や受け入れられない確認応答番号) によって、現在の送信シーケンス番号と次に受信したいシーケンス番号を示 す確認応答を含んだ空の確認応答セグメントだけが生み出され、コネクショ ンは同じ状態のままである。 受信セグメントが持つセキュリティレベルやコンパートメント、優先度が、 コネクションが要求するレベル、コンパートメント、優先度に完全一致しな い場合、リセットが送信され、コネクションはCLOSED状態になる。リセット は自身のシーケンス番号を受信セグメントのACKフィールドから取る。 リセット処理 SYN-SENTを除く全ての状態で、リセット(RST)セグメントは全てSEQフィール [Page 36] 1981年9月 転送制御プロトコル 機能仕様 ドのチェックによって確認される。シーケンス番号がウィンドウ内にあればリ セットは有効である。SYN-SENT状態(最初のSYNに対してRSTが受信された)場 合、ACKフィールドがSYNの応答であればリセットが受け入れられる。 RSTの受信側は最初にRSTを確認し、その後で状態を変える。受信側がLISTEN状 態であった場合、RSTは無視される。受信側がSYN-RECEIVED状態で、その前は LISTEN状態であった場合、受信側はLISTENに戻るか、そうでなければ受信側は コネクションを中断してCLOSED状態になる。受信側が他の状態の場合、コネク ションを中断してユーザに通知し、CLOSED状態になる。 3.5. コネクションのクローズ CLOSEは「これ以上送信するデータが無い」ことを意味する操作である。全二 重コネクションのクローズは、コネクションの受信側の処理方法が明白でない 場合があるため、当然ながらその意向が曖昧に解釈されがちである。我々は単 純な方法でCLOSEを処理することを選んだ。 CLOSEを行うユーザは、 相手も CLOSEしたと通知されるまでRECEIVEを続けることができる。したがって、プロ グラムはいくつかのSENDを開始した後にCLOSEを行い、それから相手がCLOSEし たためにRECEIVEが失敗したと通知されるまでRECEIVEを続けることができる。 我々は、TCPは未解決のRECEIVEが無くても相手のCLOSEをユーザに通知するの で、ユーザは自分の側で行儀良く終わらせることができると我々は考えている。 TCPはコネクションがCLOSEされる前にSENDされた全てのバッファを確実に伝送 するので、ユーザが戻りのデータを期待しないなら、必要なのは自分のデータ が全て宛先TCPで受信されたかを知るためにコネクションCLOSE成功の知らせを 待つだけである。ユーザは、TCPにこれ以上データが無いという言われるまで、 送信のためにクローズしたコネクションを読み込み続けなければならない。 基本的に3つのケースが存在する。 1) ユーザがTCPにコネクションをCLOSEするよう指示して開始 2) リモートTCPがFIN制御シグナルを送信して開始 3) 両方のユーザが同時にCLOSE ケース1: ローカルユーザがクローズを開始 このケースでは、FINセグメントを作って出力セグメントキュー上に入れる ことができる。TCPはユーザからのSENDをこれ以上TCPが受け入れず、FIN- WAIT-1状態に入る。この状態ではRECEIVEは可能である。FIN自身を含むFIN 以前の全てのセグメントは、確認応答されるまで再送される。相手のTCPが FINの確認応答と自身のFINの送信を行ったときは、先に行ったTCPはこのFIN にACKを出すことができる。FINを受信したTCPはACKを出すことができるが、 ユーザがコネクションをCLOSEするまでは自身のFINを送信することはできな い。 [Page 37] 1981年9月 転送制御プロトコル 機能仕様 ケース2: TCPがネットワークからFINを受信 こちらから要求せずにFINがネットワークから到着した場合、受信したTCPは それにACKを出して、ユーザにコネクションがクローズされたことを教える ことができる。ユーザはCLOSEで対応し、TCPはこれに基づいて残りのデータ を送信した後、FINを相手のTCPに送信することができる。そして、TCPは自 身のFINが確認応答されるまで待ち、確認応答が来るとすぐにコネクション を削除する。ACKがくる気配が無い場合、ユーザはタイムアウトした後、コ ネクションは中断され、ユーザに通知する。 ケース3: 両方のユーザが同時にクローズ コネクションの両端のユーザによる同時CLOSEは、FINセグメントが交換され ることになる。FIN以前の全てのセグメントが処理されて確認応答されると、 それぞれのTCPは自分が受信したFINにACKを出す。どちらのTCPもACKを受信 するとコネクションを削除する。 TCP A TCP B 1. ESTABLISHED ESTABLISHED 2. (クローズ) FIN-WAIT-1 --> --> CLOSE-WAIT 3. FIN-WAIT-2 <-- <-- CLOSE-WAIT 4. (クローズ) TIME-WAIT <-- <-- LAST-ACK 5. TIME-WAIT --> --> CLOSED 6. (2 MSL) CLOSED 通常クローズの流れ 図13 [Page 38] 1981年9月 転送制御プロトコル 機能仕様 TCP A TCP B 1. ESTABLISHED ESTABLISHED 2. (クローズ) (クローズ) FIN-WAIT-1 --> ... FIN-WAIT-1 <-- <-- ... --> 3. CLOSING --> ... CLOSING <-- <-- ... --> 4. TIME-WAIT TIME-WAIT (2 MSL) (2 MSL) CLOSED CLOSED 同時クローズの流れ 図14 3.6. 優先度とセキュリティ コネクションは、全く同じセキュリティ値、コンパートメント値を持って動作 しているポート間で、かつその2つのポートが要求する優先度のうち高い方の 優先度であるものだけが許されるというのが、この仕様の意図である。 TCPで使用される優先度とセキュリティのパラメータは、正確にはインターネ ットプロトコル(IP)[2]で定義されているものである。このTCP仕様書を通 じて、「セキュリティ/コンパートメント」という用語は、セキュリティ、コ ンパートメント、ユーザグループ、ハンドリング制限を含むIPで使われるセキ ュリティパラメータを表しているつもりである。 セキュリティ/コンパートメント値が異なっている、あるいは低い優先度値の コネクションを試みた場合、リセットが送信されて拒否されなければならない。 優先度が低すぎることによるコネクションの拒否は、SYNの確認応答が受信さ れた後にだけ行われる。 デフォルト値の優先度でしか動作しないTCPモジュールでも、受信セグメント の優先度を調べて、そのコネクションで使用する優先度を可能な限り上げなけ ればならないことに注意してほしい。 セキュアでない環境であってもセキュリティパラメータを使用する場合がある ので(値は非機密データを示しているだろう)、セキュアでない環境のホスト は、セキュリティパラメータを送信しなくてもよいが受信の準備をしていなけ ればならない。 [Page 39] 1981年9月 転送制御プロトコル 機能仕様 3.7. データ通信 コネクションが確立してしまえば、データはセグメントの交換によって伝達さ れる。セグメントがエラー(チェックサム試験失敗)やネットワークの輻輳に よって消失する可能性もあるので、TCPは(タイムアウトの後)再送を使って、 全てのセグメントの伝達を確実に行う。ネットワークやTCPの再送が原因で、 重複セグメントが到着することもある。シーケンス番号の節で議論したように、 TCPはセグメントのシーケンス番号と確認応答番号の確認試験を行って、受け 入れ可能かどうか確かめる。 データの送信側で次に使用するシーケンス番号の情報は変数SND.NXTに保持さ れる。データの受信側で次に期待されるシーケンス番号は変数RCV.NXTに保持 される。データの送信側で最も古い未確認のシーケンス番号はSND.UNAに保持 される。データフローがしばらくアイドル状態で、送信されたデータが全て確 認応答された場合、3つの変数は等しくなる。 送信側がセグメントを作って送信したとき、送信側はSND.NXTを進める。受信 側がセグメントを受け入れたとき、RCV.NXTを進め、確認応答を送信する。デ ータの送信側が確認応答を受信したとき、SND.UNAを進める。これらの変数が 異なっている程度が通信における遅延を示す指標になる。変数を進める量はセ グメントのデータ長である。ESTABLISHED状態になってしまえば、全てのセグ メントが現在の確認応答の情報を運ばなければならないことに注意する。 CLOSEユーザコールはプッシュ機能を含んでおり、これは受信セグメントのFIN 制御フラグも同様である。 再送タイムアウト インターネットワークシステムを構成するネットワークの変化のしやすさと、 TCPコネクションの広範囲利用のために、再送タイムアウトを動的に決定しな ければならない。再送タイムアウトを決定する1つの手順を、ここで例として 挙げる。 再送タイムアウト手順の例 あるシーケンス番号を持つデータオクテットの送信と、そのシーケンス番 号を処理したという確認応答(送信セグメントが受信セグメントと対応が 取れている必要は無い)の受信との間の経過時間を測る。この測定された 経過時間が往復遅延(RTT)である。 次に以下のように平準化往復遅延 (SRTT)を計算する。 SRTT = ( ALPHA * SRTT ) + ((1-ALPHA) * RTT) そして、これを基に以下のように再送タイムアウト(RTO)を計算する。 RTO = min[UBOUND,max[LBOUND,(BETA*SRTT)]] ここで、UBOUNDはタイムアウトの上限(例えば1分)、LBOUNDはタイムア [Page 40] 1981年9月 転送制御プロトコル 機能仕様 ウトの下限(例えば1秒)、ALPHAは平準化因子(例えば0.8〜0.9)、BETA は遅延変動因子(例えば1.3〜2.0)である。 緊急情報の通信 TCPの緊急処理メカニズムの目的は、送信側ユーザが受信側ユーザを促して緊 急データを受信させられるようにすること、そして現在既知の緊急データが全 てユーザによって受信されたときに受信側TCPが受信側ユーザへ通知できるよ うにすることである。 このメカニズムでは、データストリームのあるポイントを緊急情報の終了ポイ ントとして指定することができる。このポイントが受信側TCPで受信シーケン ス番号(RCV.NXT)よりも先にあるときは、そのTCPがユーザに「緊急モード」 に入るよう指示しなければならない。また、受信シーケンス番号が緊急ポイン タに追いついた場合、TCPはユーザに「通常モード」に入るよう指示しなけれ ばならない。ユーザが「緊急モード」であるときに緊急ポインタが更新されて も、その更新はユーザに見えない。 この手法は転送される全てのセグメントに含まれる緊急フィールドを使用する。 URG制御フラグは、緊急フィールドが意味を持っていて、このフィールドをセ グメントのシーケンス番号に加えて緊急ポインタを生成する必要があることを 表している。このフラグが立っていない場合は、未解決の緊急データが無いこ とを表している。 また、緊急指示を送信するには、ユーザが最低1データオクテットは送信しな ければならない。送信側ユーザもプッシュを指示している場合、宛先のプロセ スへの緊急情報のタイムリーな配送が促進される。 ウィンドウの管理 各セグメントで送信されるウィンドウは、そのウィンドウを送信した側(デー タを受信する側)が現在受け取る用意ができているシーケンス番号の範囲を表 している。このウィンドウはコネクションで使用できる現在利用可能なデータ バッファ空間と関係していると仮定されている。 大きなウィンドウを指定すれば送信は促進される。受信可能な量以上のデータ が到着した場合、そのデータは廃棄される。このことは過度な再送を招き、ネ ットワークとTCPに対して無用な負荷を加えることになる。小さなウィンドウ を指定すれば、新たに送信される各セグメントの間に往復遅延を挿入したよう になるまでデータ送信に制限をかけることができる。 規定されているメカニズムでは、TCPが大きなウィンドウを通知していて、後 でそれほど多くデータを受け取らずにとても小さいウィンドウを通知してしま う可能性がある。これは「ウィンドウ縮小」と呼ばれ、強く非推奨とされてい る。堅牢性の原理によると、TCPは自分のウィンドウを縮小せず、他のTCPのこ のような振舞いに対応できるようにしておくことが要求される。 送信TCPは、たとえ送信ウィンドウが0の場合でも、最低1オクテットの新規デ [Page 41] 1981年9月 転送制御プロトコル 機能仕様 ータをユーザから受け取って送信する準備がなければならない。送信TCPは、 ウィンドウが0の場合でも受信TCPに正しく再送しなければならない。ウィンド ウが0のときの再送間隔は2分が推奨されている。この再送は、どちらかのTCP が0ウィンドウであるときウィンドウの再開を相手方へ確実に通知する保証の ために不可欠である。 受信TCPが0ウィンドウでセグメントが到着したときは、依然として確認応答を 送信して次に期待するシーケンス番号と現在のウィンドウ(0)を示さなけれ ばならない。 送信TCPは再送するデータを現在のウィンドウに適したセグメントにパッケー ジングして、その後で再送キュー上でセグメントを再パッケージングすること ができる。このような再パッケージングは必要ないが便利なときもある。 単方向のデータフローのコネクションでは、ウィンドウ情報はシーケンス番号 が全て同じである確認応答セグメントで運ばれるので、もしそれらがバラバラ の順序で到着しても並べ替えは全く行われない。これは深刻な問題ではないが、 ウィンドウ情報が一時的にデータの受信側からの古い報告に基づいてしまうこ とが時折あるかもしれない。この問題を避けるための改善策は、最も高い確認 応答番号を持つセグメント(これは確認応答番号がそれまで受信した最も高い ものと等しいか、それより大きいセグメントである)からのウィンドウ情報に 従うことである。 ウィンドウ管理のやり方は通信性能に重要な影響を及ぼす。以下のコメントは 実装者への提案である。 ウィンドウ管理の提案 とても小さなウィンドウを割り当てることは、多数の小さなセグメントに よるデータ送信を引き起こす。このとき少数の大きなセグメントを使えば 性能が良くなる。 小さなウィンドウを避ける1つの提案は、追加の割り当てがそのコネクシ ョンで可能な最大割り当て量のXパーセント以上になるまで、受信側がウ ィンドウの更新を延期することである (ここでXは20から40で良いだろ う)。 もう1つの提案は、データを送信する前にウィンドウが十分大きくなるま で送信側が待って小さなセグメントを送信しないことである。ユーザがプ ッシュ機能を指示した場合は、小さなセグメントであってもデータを送信 しなければならない。 確認応答は遅滞させるべきではなく、さもなくば不要な再送を招くことに 注意する。1つの対策は、小さなセグメントが到着したとき確認応答を送 信して(ウィンドウ情報の更新はしない)、ウィンドウが大きくなったと き新しいウィンドウ情報を持つ別の確認応答を送信することだろう。 ウィンドウが0であるかを調べるために送信したセグメントによって、送 [Page 42] 1981年9月 転送制御プロトコル 機能仕様 信データの分割が始まり、次第に小さなセグメントになっていく場合があ る。ウィンドウが0であるかを調べるために送信された1データオクテット を持つセグメントが受信されると、利用可能なウィンドウの1オクテット を消費する。ウィンドウが0でないとき単純に可能な限り多く送信するよ うな送信TCPの場合、送信データは分割されて大きいセグメントと小さい セグメントが交互に現れるようになるだろう。その内に、ウィンドウの割 り当てが可能な受信側で一時停止がときどき起こることで、結果としてこ の大きいセグメントが小さいものとさほど大きくないもののペアに分割さ れるだろう。そして、しばらくするとデータ送信がほとんど小さなセグメ ントで行われることになるだろう。 最も単純に考えた実装ではウィンドウを管理するメカニズムによって多数 の小さなウィンドウになりがちであるので、TCP実装は小さなウィンドウ 割り当てを積極的に集めてより大きなウィンドウにする試みが必要だとい うことがここでの提案である。 3.8. インタフェース 関係するインタフェースは当然2つある。すなわち、ユーザ/TCPインタフェー スとTCP/下位インタフェースである。ユーザ/TCPインタフェースは極めて詳 細なモデルにしたが、下位プロトコルとのインタフェースはここでは規定しな いでおいた。下位プロトコルの仕様書で詳しく規定されるからである。下位が IPである場合については、TCPが使用する一部のパラメータ値について述べる。 ユーザ/TCPインタフェース オペレーティングシステムはそれぞれ異なる機能を持つため、以下のTCPに 対するユーザコマンドの機能説明は、いくら頑張ってもフィクションである。 したがって、TCPの実装が異なれば、異なるユーザインタフェースを持つ可 能性があるのだと、我々は読者に警告しなければならない。しかし、TCP実 装が同一のプロトコル階層をサポートできるようにするため、全てのTCPは 一定の最小サービス群を提供しなければならない。この節では、全てのTCP 実装に求められる機能インタフェースを規定する。 TCPユーザコマンド 以下の節では、ユーザ/TCPインタフェースの機能的な特徴を明らかにす る。使用する記法は上位言語における大部分のプロシージャやファンクシ ョンコールと同じものであるが、この用法によってトラップタイプのサー ビスコール(例えば、SVC、UUO、EMTなど)を除外するわけではない。 以下で述べられるユーザコマンドは、TCPがプロセス間通信をサポートす るために実行しなければならない基本的な機能を規定している。個々の実 装はそれぞれ独自の厳密な形式で定義されるはずで、1回のコールで基本 的な機能の組み合わせまたはサブセットを提供するかもしれない。特に、 あるコネクションに対してユーザが発した最初のSENDやRECEIVEで自動的 にコネクションをOPENしようとする実装もあるだろう。 [Page 43] 1981年9月 転送制御プロトコル 機能仕様 プロセス間通信の機能を提供するにあたり、TCPはコマンドを受けるだけ でなく、サービスしているプロセスに情報を返すことも行わなければなら ない。後者は以下から成り立っている。 (a) 一般的なコネクションに関する情報(例えば、割り込み、リモート によるクローズ、未指定の外部ソケットのバインディング) (b) 個々のユーザコマンドに対する成功を示す応答、または様々な失敗 のタイプを示す応答 Open 書式: OPEN (ローカルポート, 外部ソケット, 能動/受動 [, タイムアウト] [, 優先度] [, セキュリティ/コンパートメント] [, オプション]) -> ローカルコネクション名 ローカルTCPはサービスしているプロセスのIDを知っており、指定され たコネクションを使うプロセスの権限をチェックすると仮定している。 TCPの実装に依存するが、ローカルネットワークと送信元アドレスに対 するTCPの識別子は、TCPあるいは下位プロトコル(例えばIP)が与える ことになる。TCPが別のTCPに成りすますなどといったことが不可能であ る限り、これらの考慮はセキュリティに対する配慮の結果である。同様 に、TCPとの結託がなければプロセスが別のプロセスに成りすますこと は不可能である。 能動/受動フラグが受動にセットされているときは、これはやって来る コネクションを待つLISTENのコールである。受動オープンは、外部ソケ ットを完全に指定して特定のコネクションを待っても、外部ソケットを 指定せず任意のコールを待ってもよい。完全に指定した場合の受動コー ルは、その後SENDを実行することによって能動にすることができる。 転送制御ブロック(TCB)は、作成されてOPENコマンドのパラメータに よるデータで部分的に埋められる。 能動OPENコマンドでは、TCPはすぐにコネクションの同期を取る(すな わち確立する)ための手続きを始める。 タイムアウトを引数に入れれば、TCPに渡す全データにタイムアウト時 間をコール元が設定できる。データがタイムアウト時間内に宛先までう まく届かなかったとき、TCPはコネクションのを中断する。現在のグロ ーバルなデフォルトは5分である。 TCPまたはオペレーティングシステムの一部のコンポーネントは、ユー ザ権限を確認して、特定の優先度またはセキュリティ/コンパートメン トを持つコネクションをオープンするだろう。OPENコールで優先度また はセキュリティ/コンパートメント指定が無い場合は、デフォルト値を 使わなければならないことを示している。 [Page 44] 1981年9月 転送制御プロトコル 機能仕様 TCPは、セキュリティ/コンパートメント情報が完全に一致し、優先度 がOPENコールの優先度要求以上であるときだけ、受信リクエストを合致 したとして受け入れる。 コネクションに対する優先度はOPENコールで要求された値および受信リ クエストで要求された値よりも高くなり、コネクションの最初から最後 までその値で固定されている。この優先度ネゴシエーションの制御をユ ーザに与えたいと思う実装者もいるだろう。例えば、優先度が完全に一 致しなくてはならない、あるいは優先度を上げることをユーザに確認し なくてはならないことをユーザが指定できるというのもあるだろう。 ローカルコネクション名は、TCPによってユーザに返されるだろう。以 降、ローカルコネクション名は、<ローカルソケット, 外部ソケット>の ペアで定義されるコネクションの短縮形として使うことができる。 Send 書式: SEND (ローカルコネクション名, バッファアドレス, バイト数, PUSHフラグ, URGENTフラグ [,タイムアウト]) このコールは、指定されたユーザバッファに含まれるデータが指定コネ クション上で送信されるようにする。コネクションがオープンされてい なかった場合、このSENDはエラーであると見なされる。ユーザが最初か らSEND可能な実装もあるだろう。この場合、自動的なOPENが行われる。 コールを行うプロセスがこのコネクションを使用する権限を持っていな い場合、エラーが返される。 PUSHフラグがセットされている場合、データを即座に受信側に転送しな ければならず、PUSHビットはバッファから生成された最後のTCPセグメ ントにセットする。PUSHフラグがセットされていない場合は、転送効率 のために、データをその後のSENDからのデータと結合することもある。 URGENTフラグがセットされている場合、宛先TCPに送信されるセグメン トには緊急ポインタがセットされている。緊急ポインタ以前のデータが 受信プロセスによって処理されていないことが緊急ポインタによって判 る場合、受信側TCPは緊急状態を受信プロセスに通知する。緊急の目的 は、受信側に緊急データの処理を促し、また現在既知の緊急データが全 て受信された場合に受信側に通知することである。送信ユーザのTCPが 緊急を通知する回数と、受信ユーザが緊急データの存在の通知を受ける 回数とが必ずしも等しいとは限らない。 OPENの際に外部ソケットを指定せず、(例えば、コネクションのLISTEN がローカルソケットに到着した外部セグメントによって確定したためな どで)コネクションが確立した場合、指定されたバッファは暗黙の外部 ソケットに送信される。外部ソケット未指定でOPENを使用するユーザは 外部ソケットアドレスを明示的に知らなくてもSENDを使用することがで きる。 [Page 45] 1981年9月 転送制御プロトコル 機能仕様 しかし、外部ソケットが確定する前にSENDしようとすると、エラーが返 される。ユーザはSTATUSコールを使ってコネクションのステータスを確 認することができる。未指定ソケットが結び付けられたときTCPがユー ザに通知する実装もあるだろう。 タイムアウトが指定されたとき、このコネクションの現在のユーザタイ ムアウトは新しいものに変更される。 転送が完了するかタイムアウト時間を過ぎるまでSENDが送信プロセスに 制御を返さないのが最も簡単な実装である。しかし、この簡単なやり方 は、デッドロック(例えば、コネクションの両側でRECEIVEを行う前に SENDを試みるかもしれない)と提供するパフォーマンスの低下の両方の 影響を受けるので、推奨されない。より洗練された実装は即座に戻って、 プロセスがネットワークI/Oと同時に実行でき、さらに複数のSENDが同 時実行できる。複数のSENDは先着順に処理されるので、TCPは即座に処 理できないものを待ち行列に入れるだろう。 SENDの後、処理中のTCPからある種のSIGNALや擬似割り込みが発生する ような非同期ユーザインタフェースを暗黙に仮定してきた。それ以外に 即座に応答を返すというのもある。例えば、送信されたセグメントに対 して遠くのTCPから確認応答が来ていないにもかかわらず、SENDが即座 にローカルの確認応答を返すというものである。結果的に成功すること を楽観的に仮定することもできるだろう。問題があるなら、コネクショ ンはタイムアウトによってクローズするだろう。この種の実装(同期) では、一部の非同期シグナルは残っているが、これらはコネクション自 身を処理するのであって具体的なセグメントやバッファは処理しない。 異なるSENDに対するエラーや成功の表示をプロセスが見分けるために、 SEND要求に対する応答の符号化とともにバッファアドレスを返すのが良 いだろう。 以降では、コール元プロセスに返すべき情報を示しながら TCP・ユーザ間のシグナリングを議論する。 Receive 書式: RECEIVE (ローカルコネクション名, バッファアドレス, バイト数) -> バイト数, URGENTフラグ, PUSHフラグ このコマンドは指定のコネクションに関する受信バッファを割り当てる。 このコマンド以前にOPENがなかったり、コール元プロセスがこのコネク ションを使用する権限を持っていなかったりした場合、エラーが返され る。 バッファが埋まるか何かエラーが発生するまでコール元プログラムに制 御を返さないのが最も簡単な実装であるが、このやり方ではデッドロッ クとなる可能性が高い。より洗練された実装では、未解決のRECEIVEが 複数同時に存在できる。これらはセグメントが到着すると埋められる。 この方法は、スループットを増加させることができるが、PUSHが検知さ れたことやバッファが埋まったことをコール元プログラムに通知するよ [Page 46] 1981年9月 転送制御プロトコル 機能仕様 り精巧な手段(非同期かもしれない)が犠牲になってしまう。 PUSHを検知する前にバッファを埋めるだけのデータが到着した場合、 RECEIVEに応答でPUSHフラグがセットされないだろう。そしてバッファ は格納できる量と同じだけのデータで埋められる。バッファが埋まる前 にPUSHを検知した場合、バッファは部分的に埋められた状態で返され、 PUSHが指定される。 緊急データがある場合、到着したらすぐにTCP・ユーザ間シグナルを使 ってユーザに通知される。したがって、受信ユーザは「緊急モード」に 入るべきである。URGENTフラグがオンの場合、残りの緊急データがまだ 存在する。URGENTフラグがオフの場合、このRECEIVEへのコールで全て の緊急データが返されており、ユーザはこの時点で「緊急モード」から 抜けることができる。緊急ポインタより後ろのデータ(非緊急データ) は、境界をユーザが明確に示していないとき以外は前の緊急データと同 じバッファでユーザに渡すことはできない。 複数の未解決RECEIVEを区別し、バッファが全て埋まっていないケース を扱うために、リターンコードにはバッファのポインタと受信したデー タの実際の長さを示すバイト数が付く。 別のRECEIVEの実装では、TCPにバッファ記憶領域を割り当てさせる、あ るいはTCPがユーザとリングバッファを共有するというのもあるだろう。 Close 書式: CLOSE (ローカルコネクション名) このコマンドは指定されたコネクションがクローズされるようにする。 コネクションがオープンされていない、あるいはコール元プロセスにこ のコネクションを使用する権限がない場合、エラーが返される。コネク ションのクローズは、全て処理し終わるまで、未解決のSENDを転送(お よび再送)し、フロー制御が許されるという点で行儀の良い動作を目指 している。したがって、複数のSENDコールを行い、その後でCLOSEする ことが許され、全てのデータが宛先に送信されることが期待できるはず である。また、相手側はデータの最後を送信しようとしているかもしれ ないため、ユーザはコネクションをCLOSEしている際もRECEIVEを続ける べきなのは明らかである。したがって、CLOSEは「これ以上送信するも のが無い」という意味ではあるが、「これ以上受信しない」という意味 ではない。(ユーザレベルのプロトコルがよく考えられていないと)ク ローズ側が全てのデータを取り除くことはできず、タイムアウトしてし まうことが起こり得る。この事態に陥ると、CLOSEはABORTになり、クロ ーズ中のTCPは断念してしまう。 ユーザは、自ら主導で、あるいはTCPからの様々な働きかけ(例えば、 リモートでのクローズ実行、送信タイムアウト時間超過、宛先に到達不 能)に反応して、いつでもコネクションをCLOSEすることができる。 [Page 47] 1981年9月 転送制御プロトコル 機能仕様 コネクションのクローズには外部のTCPとの通信が必要なので、コネク ションはしばらくクローズ中状態のままである場合がある。TCPがCLOSE に応答する前にコネクションを再オープンしようとした場合、エラー応 答となる。 また、クローズはプッシュ機能を含んでいる。 Status 書式: STATUS (ローカルコネクション名) -> 状態データ これは実装依存のユーザコマンドで、除外しても何の問題も無い。返さ れる情報は、通常コネクションに関連付けられたTCBに基づいたもので ある。 このコマンドは以下の情報を含むデータブロックを返す。 ローカルソケット 外部ソケット ローカルコネクション名 受信ウィンドウ 送信ウィンドウ コネクション状態 確認応答待ちのバッファ数 受信途中のバッファ数 緊急状態 優先度 セキュリティ/コンパートメント 送信タイムアウト時間 コネクションの状態によっては、あるいは実装によってはこの情報の一 部が得られない、あるいは意味を成さない場合もある。コール元プロセ スがこのコネクションを使用する権限を持っていない場合、エラーが返 される。これは権限の無いプロセスがコネクションについての情報を得 られないようにしている。 Abort 書式: ABORT (ローカルコネクション名) このコマンドは処理途中のSENDおよびRECEIVEを全て中断し、TCBを削除 し、特別なRESETメッセージをコネクションの相手側のTCPに送信する。 実装に依存するが、ユーザは未解決のSENDまたはRECEIVEのそれぞれに 対して中断指示を受け取るかもしれないし、あるいは単純にABORT確認 応答を1つ受信するかもしれない。 [Page 48] 1981年9月 転送制御プロトコル 機能仕様 TCP・ユーザ間メッセージ TCPがユーザプログラムに非同期に通知する手段は、オペレーティングシ ステム環境が提供すると仮定している。TCPがユーザプログラムに通知し たとき、ある情報がユーザに渡される。仕様の中では、多くの場合この情 報はエラーメッセージである。他のケースではSENDやRECEIVEなどのユー ザコールの処理完了に関係する情報もある。 以下の情報が提供される。 ローカルコネクション名 常時 応答文字列 常時 バッファアドレス SEND & RECEIVE バイト数(受信したバイト数をカウント) RECEIVE プッシュフラグ RECEIVE 緊急フラグ RECEIVE TCP/下位インタフェース TCPは下位プロトコルモジュールを呼び出し、実際にネットワーク上での情 報の送受信を行う。ARPAインターネットワークシステムもその1つのケース で、下位モジュールがインターネットプロトコル(IP)[2]である。 下位プロトコルがIPの場合、サービスタイプと生存時間のための引数を提供 する。TCPはこれらのパラメータに以下の設定を使用する。 サービスタイプ = 優先度:通常、遅延:通常、スループット:通常、 信頼性:通常 あるいは 00000000 生存時間 = 1分 あるいは 00111100 最大セグメント寿命が2分と仮定していることに注意する。ここで、1分 以内にインターネットシステムによって配達できなかった場合、セグメ ントが破壊されたかどうか明示的に訊ねる。 下位がIP(もしくはこの機能を提供する他のプロトコル)であり、ソースル ーティングが使用された場合、インタフェースは経路情報が伝達できるよう にしなければならない。これは、TCPチェックサムで使用される送信元アド レスと宛先アドレスが最初の送信元と最終的な宛先であるために特に重要で ある。また、コネクション要求の応答のために戻り経路を保存することも重 要である。 IPの機能と同等な機能を提供し、TCPチェックサムに使用するためには、ど の下位プロトコルも送信元アドレス、宛先アドレス、プロトコルフィールド と、「TCP長」を決める何らかの手段を提供しなければならないだろう。 [Page 49] 1981年9月 転送制御プロトコル 機能仕様 3.9. イベント処理 この節で書かれている処理は実装の1つの可能性の例である。他の実装は処理 の順序が多少異なるかもしれないが、この節のものと異なるのは細かいところ だけであって、実質的には変わらないはずである。 TCPの動作はイベントに対する応答で特徴付けることができる。発生するイベ ントは3つのカテゴリに分けることができる。すなわち、ユーザコール、セグ メントの到着、タイムアウトである。この節ではTCPが各イベントに対して行 う処理を説明する。多くの場合、必要な処理はコネクションの状態に依存する。 発生するイベント: ユーザコール OPEN SEND RECEIVE CLOSE ABORT STATUS セグメントの到着 セグメント到着 タイムアウト ユーザタイムアウト 再送タイムアウト TIME-WAITタイムアウト このTCP/ユーザインタフェースのモデルでは、ユーザコマンドは即時復帰と、 場合によってはイベントまたは擬似割り込みで遅延応答を受信する。以下の説 明で、「シグナル」という用語は遅延応答を起こすという意味である。 エラー応答は文字列として与えられる。例えば、存在しないコネクションを参 照するユーザコマンドは“error: connection not open”(エラー:コネクシ ョンが未オープン)を受信する。 以下、シーケンス番号、確認応答番号、ウィンドウなどの算術は全てシーケン ス番号空間の大きさ2**32のモジュロであることに注意していただきたい。ま た、“=<”は(2**32のモジュロで)「〜より小さいか等しい」を意味する。 受信セグメントの処理について考える場合、最初にシーケンス番号の正当性( すなわち、セグメントの内容がシーケンス番号空間内の期待される「受信ウィ ンドウ」の範囲に収まっていること)について試験し、それから一般的にキュ ーに入れられ、シーケンス番号の順に処理されることをイメージするのが自然 [Page 50] 1981年9月 転送制御プロトコル 機能仕様 である。 セグメントがすでに受信した他のセグメントと重なっているとき、セグメント を再構成して新しいデータを含むようにし、ヘッダのフィールドに矛盾が無い ようにする。 状態変化について触れられていない場合、TCPは同じ状態のままである。 [Page 51] 1981年9月 転送制御プロトコル 機能仕様 OPENコール OPENコール CLOSE状態(すなわちTCBが存在しない) 新たな転送制御ブロック(TCB)を作成し、コネクション状態情報を保持 する。ローカルソケット識別子、外部ソケット、優先度、セキュリティ/ コンパートメント、ユーザタイムアウト情報に書き込む。一部の外部ソケ ットは受動OPENでは指定されず、受信SYNセグメントのパラメータによっ て埋められることになる。要求されたセキュリティおよび優先度がそのと きのユーザに対して許可されたものであることを確認し、そうでない場合 は“error: precedence not allowed”(エラー:優先度が許可されてい ない)または“error: security/compartment not allowed”(エラー: セキュリティ/コンパートメントが許可されていない)を返す。受動の場 合はLISTEN状態に入って戻る。能動で外部ソケットが指定されていない場 合は“error: foreign socket unspecified”(エラー:外部ソケットが 指定されていない)を返す。一方、能動で外部ソケットが指定されている 場合はSYNセグメントを送出する。初期送信シーケンス番号(ISS)が選択 される。 形式のSYNセグメントが送信される。SND.UNA にはISSをセットし、SND.NXTにはISS+1をセットし、SYN-SENT状態に入っ て戻る。 コール元が指定されたローカルソケットへのアクセスを持っていない場合、 “error: connection illegal for this process”(エラー:このプロセ スにとって不正なコネクション)を返す。新しいコネクションを作成する 余地が無い場合、“error: insufficient resources”(エラー:リソー ス不足)を返す。 LISTEN状態 能動で外部ソケットが指定されている場合は、コネクションを受動から能 動に変化させ、ISSを選択する。SYNセグメントを送信して、SND.UNAには ISSを、SND.NXTにはISS+1をセットする。SYN-SENT状態に入る。SENDに関 連付けられたデータはSYNセグメントとともに送信されるか、ESTABLISHED 状態に入った後に送信するためのキューに入れられる。緊急ビットは、コ マンドで要求されると、このコマンドの結果として送信されるデータセグ メントと共に送信しなければならない。要求をキューに入れる余地が無い 場合、“error: insufficient resources”(エラー:リソース不足)で 応答する。 外部ソケットが指定されていない場合は “error: foreign socket unspecified”(エラー:外部ソケットが指定されていない)を返 す。 [Page 52] 1981年9月 転送制御プロトコル 機能仕様 OPENコール SYN-SENT状態 SYN-RECEIVED状態 ESTABLISHED状態 FIN-WAIT-1状態 FIN-WAIT-2状態 CLOSE-WAIT状態 CLOSING状態 LAST-ACK状態 TIME-WAIT状態 “error: connection already exists”(エラー:コネクションはすでに 存在する)を返す。 [Page 53] 1981年9月 転送制御プロトコル 機能仕様 SENDコール SENDコール CLOSE状態(すなわちTCBが存在しない) ユーザがこのようなコネクションへのアクセスを持っていない場合、 “error: connection illegal for this process”(エラー:このプロセ スにとって不正なコネクション)を返す。 それ以外の場合は“error: connection does not exist”(エラー:コネ クションが存在しない)を返す。 LISTEN状態 外部ソケットが指定されている場合、コネクションを受動から能動に変化 させ、ISSを選択する。SYNセグメントを送信して、SND.UNAにはISSを、 SND.NXTにはISS+1をセットする。SYN-SENT状態に入る。SENDに関連付けら れたデータはSYNセグメントとともに送信されるか、ESTABLISHED状態に入 った後に送信するためのキューに入れられる。緊急ビットは、コマンドで 要求されると、このコマンドの結果として送信されるデータセグメントと 共に送信しなければならない。要求をキューに入れる余地が無い場合、 “error: insufficient resources”(エラー:リソース不足)で応答す る。外部ソケットが指定されていない場合は“error: foreign socket unspecified”(エラー:外部ソケットが指定されていない)を返す。 SYN-SENT状態 SYN-RECEIVED状態 ESTABLISHED状態に入った後に送信するために、データをキューに入れる。 キューに余地が無い場合、“error: insufficient resources”(エラー :リソース不足)で応答する。 ESTABLISHED状態 CLOSE-WAIT状態 バッファをセグメント化して、いっしょに格納した確認応答(確認応答値 = RCV.NXT)とともにそれを送信する。このバッファを記憶する容量が不 足している場合、単純に“error: insufficient resources”(エラー: リソース不足)を返す。 緊急フラグがセットされている場合、SND.UP <- SND.NXT-1とし、緊急ポ インタを送信セグメントにセットする。 [Page 54] 1981年9月 転送制御プロトコル 機能仕様 SENDコール FIN-WAIT-1状態 FIN-WAIT-2状態 CLOSING状態 LAST-ACK状態 TIME-WAIT状態 “error: connection closing”(エラー:コネクションクローズ中)を 返し、要求を処理してはいけない。 [Page 55] 1981年9月 転送制御プロトコル 機能仕様 RECEIVEコール RECEIVEコール CLOSE状態(すなわちTCBが存在しない) ユーザがこのようなコネクションへのアクセスを持っていない場合、 “error: connection illegal for this process”(エラー:このプロセ スにとって不正なコネクション)を返す。 それ以外の場合は“error: connection does not exist”(エラー:コネ クションが存在しない)を返す。 LISTEN状態 SYN-SENT状態 SYN-RECEIVED状態 ESTABLISHED状態に入った後に送信するために、データをキューに入れる。 キューに余地が無い場合、“error: insufficient resources”(エラー :リソース不足)で応答する。 ESTABLISHED状態 FIN-WAIT-1状態 FIN-WAIT-2状態 この要求を満たすために不完全な受信セグメントをキューに入れる場合、 この要求をキューに入れる。RECEIVEを記憶するキュー空間が無い場合、 “error: insufficient resources”(エラー:リソース不足)で応答す る。 キューに入れられた受信セグメントをリアセンブルして受信バッファに入 れ、ユーザに戻す。プッシュ発見の場合は「プッシュ発見」(PUSH)をマ ークする。 RCV.UPが現在ユーザに渡している最中のデータより先に位置する場合、緊 急データの存在をユーザに通知する。 TCPがデータをユーザに渡す責任を持つとき、この事実を確認応答で送信 側に通知しなければならない。この確認応答の構成は、以下の受信セグメ ントの処理の議論の中で述べられている。 [Page 56] 1981年9月 転送制御プロトコル 機能仕様 RECEIVEコール CLOSE-WAIT状態 リモート側がすでにFINを送信済みであるため、RECEIVEはすでに受け取ら れていてユーザに配達されていないテキストによって満たされなければな らない。配達待ちのテキストが無い場合、RECEIVEは“error: connection closing”(エラー:コネクションクローズ中)という応答を受けるだろ う。そうでなければ残りのテキストを使ってRECEIVEを満たすことができ る。 CLOSING状態 LAST-ACK状態 TIME-WAIT状態 “error: connection closing”(エラー:コネクションクローズ中)を 返す。 [Page 57] 1981年9月 転送制御プロトコル 機能仕様 CLOSEコール CLOSEコール CLOSED状態(すなわちTCBが存在しない) ユーザがこのようなコネクションへのアクセスを持っていない場合、 “error: connection illegal for this process”(エラー:このプロセ スにとって不正なコネクション)を返す。 それ以外の場合は“error: connection does not exist”(エラー:コネ クションが存在しない)を返す。 LISTEN状態 未解決のRECEIVEは“error: closing”(エラー:クローズ中)という応 答とともに返される。TCBを削除し、CLOSED状態に入り、制御を返す。 SYN-SENT状態 TCBを削除し“error: closing”(エラー:クローズ中)という応答をキ ューにあるSENDまたはRECEIVEに対して返す。 SYN-RECEIVED状態 SENDが送出されておらず、かつ送信されるべき未処理データがない場合、 FINセグメントを作って送信し、FIN-WAIT-1状態に入る。それ以外の場合 は、ESTABLISHED状態に入った後に処理するためにキューに入れる。 ESTABLISHED状態 先行するSENDが全てセグメント化されるまでこのコールをキューに入れ、 その後FINセグメントを作って送信する。いずれにせよ、FIN-WAIT-1状態 に入る。 FIN-WAIT-1状態 FIN-WAIT-2状態 厳密に言うと、これはエラーであり、“error: connection closing” (エラー:コネクションクローズ中)という応答を受信すべきである。さ らに、2つ目のFINが出されない限り(もっとも、1つ目のFINを再送するこ とは可能である)、“ok”という応答も受け入れられる。 [Page 58] 1981年9月 転送制御プロトコル 機能仕様 CLOSEコール CLOSE-WAIT状態 先行するSENDが全てセツメント化されるまでこのコールをキューに入れ、 その後FINセグメントを送信してCLOSING状態に入る。 CLOSING状態 LAST-ACK状態 TIME-WAIT状態 “error: connection closing”(エラー:コネクションクローズ中)を 返す。 [Page 59] 1981年9月 転送制御プロトコル 機能仕様 ABORTコール ABORTコール CLOSED状態(すなわちTCBが存在しない) ユーザがこのようなコネクションへのアクセスを持っていない場合、 “error: connection illegal for this process”(エラー:このプロセ スにとって不正なコネクション)を返す。 それ以外の場合は“error: connection does not exist”(エラー:コネ クションが存在しない)を返す。 LISTEN状態 未解決のRECEIVEは“error: closing”(エラー:クローズ中)という応 答とともに返されるべきである。TCBを削除し、CLOSED状態に入り、制御 を返す。 SYN-SENT状態 キューに入れられた全てのSENDおよびRECEIVEに、“connection reset” (コネクションリセット)という通知が与えられるべきで、TCBを削除し、 CLOSED状態に入り、制御を返す。 SYN-RECEIVED状態 ESTABLISHED状態 FIN-WAIT-1状態 FIN-WAIT-2状態 CLOSE-WAIT状態 次のリセットセグメントを送信する。 キューに入れられた全てのSENDおよびRECEIVEに、“connection reset” (コネクションリセット)という通知が与えられるべきである。送信また は再送のためのキューに入れられた全てのセグメント(上記の状況で作ら れたRSTは除く)は、一掃されるべきで、TCBを削除し、CLOSED状態に入り、 制御を返す。 CLOSING状態 LAST-ACK状態 TIME-WAIT状態 “ok”で応答し、TCBを削除し、CLOSE状態に入り、制御を返す。 [Page 60] 1981年9月 転送制御プロトコル 機能仕様 STATUSコール STATUSコール CLOSED状態(すなわちTCBが存在しない) ユーザがこのようなコネクションへのアクセスを持っていない場合、 “error: connection illegal for this process”(エラー:このプロセ スにとって不正なコネクション)を返す。 それ以外の場合は“error: connection does not exist”(エラー:コネ クションが存在しない)を返す。 LISTEN状態 “state = LISTEN”とTCBポインタを返す。 SYN-SENT状態 “state = SYN-SENT”とTCBポインタを返す。 SYN-RECEIVED状態 “state = SYN-RECEIVED”とTCBポインタを返す。 ESTABLISHED状態 “state = ESTABLISHED”とTCBポインタを返す。 FIN-WAIT-1状態 “state = FIN-WAIT-1”とTCBポインタを返す。 FIN-WAIT-2状態 “state = FIN-WAIT-2”とTCBポインタを返す。 CLOSE-WAIT状態 “state = CLOSE-WAIT”とTCBポインタを返す。 CLOSING状態 “state = CLOSING”とTCBポインタを返す。 LAST-ACK状態 “state = LAST-ACK”とTCBポインタを返す。 [Page 61] 1981年9月 転送制御プロトコル 機能仕様 STATUSコール TIME-WAIT状態 “state = TIME-WAIT”とTCBポインタを返す。 [Page 62] 1981年9月 転送制御プロトコル 機能仕様 セグメント到着 セグメント到着 状態がCLOSEDの(すなわちTCBが存在しない)場合 受信セグメントの全データが廃棄される。RSTを含む受信セグメントは廃 棄される。RSTを含まない受信セグメントは、応答でRSTが送信されるよう にする。その確認応答フィールド値とシーケンスフィールド値の選択は、 そのリセットシーケンスが違反セグメントの送信元TCPに受け入れ可能と なるように行われる。 ACKビットがオフの場合、シーケンス番号0が使われ次のようになる。 ACKビットがオンの場合は次のようになる。 そして、制御が返される。 状態がLISTENの場合 1:RSTチェック 受信したRSTは無視すべきである。そして制御を返す。 2:ACKチェック まだLISTEN状態であるコネクションに到着した確認応答は全て不正であ る。到着したACKを運ぶセグメントに対して、受け入れ可能なリセット セグメントを作るべきである。RSTは以下のようなフォーマットにすべ きである。 そして、制御を返す。 3:SYNチェック SYNビットがセットされている場合、セキュリティをチェックする。受 信セグメントのセキュリティ/コンパートメントがTCBにあるセキュリ ティ/コンパートメントと完全一致しない場合はリセットを送信して制 御を返す。 SEG.PRCがTCB.PRCよりも大きい場合、ユーザとシステムが許すなら [Page 63] 1981年9月 転送制御プロトコル 機能仕様 セグメント到着 TCB.PRC<-SEG.PRCとセットし、許さないならリセットを送信して制御 を返す。 SEG.PRCがTCB.PRCよりも小さい場合はそのまま続ける。 RCV.NXTにSEG.SEQ+1をセットし、IRSにSEG.SEQをセットし、他の制御お よびテキストは後で処理するためのキューに入れるべきである。ISSを 選択してSYNセグメントを次の形式で送信すべきである。 SND.NXTにはISS+1をセットし、SND.UNAにはISSをセットする。コネクシ ョン状態はSYN-RECEIVEDに変わるべきである。(SYNと共に)受信した 他の制御およびデータはSYN-RECEIVED状態で処理されることになるが、 SYNとACKの処理は繰り返すべきでない。完全指定されなかったリッスン の場合(すなわち、外部ソケットが完全に指定されなかった場合)、未 指定フィールドはこのときに埋められるべきである。 4:その他のテキストおよび制御 他の制御やテキストを運ぶ(SYNを含まない)セグメントはACKを持たな ければならず、ゆえにACK処理によって廃棄されることになる。また、 このコネクションのインカーネーションが送信したものに対してRSTセ グメントが送信されることはないはずなので、受信したRSTセグメント が正しいことはない。したがって、ここに到達することはありそうにな いが、もし到達してしまったら、セグメントを廃棄して制御を返す。 状態がSYN-SENTの場合 1:ACKビットチェック ACKビットがセットされている場合 SEG.ACK =< ISS または SETG.ACK > SND.NXT の場合、次のようなリ セットを送信し(RSTビットがセットされていない場合。RSTビットが セットされている場合はセグメントを破棄して制御を返す) セグメントを廃棄する。そして制御を返す。 SND.UNA =< SEG.ACK =< SND.NXT の場合、ACKを受け入れる。 2:RSTビットチェック [Page 64] 1981年9月 転送制御プロトコル 機能仕様 セグメント到着 RSTビットがセットされている場合 ACKが受け入れ可能だったなら、ユーザに“error: connection reset”(エラー:コネクションリセット)を通知し、セグメントを 廃棄してCLOSED状態に入り、TCBを削除し、制御を返す。さもなくば (ACKなし)、セグメントを廃棄して制御を返す。 3:セキュリティおよび優先度チェック セグメントのセキュリティ/コンパートメントがTCBのセキュリティ/ コンパートメントと完全一致しない場合、次の通りリセットを送信する。 ACKがあるなら さもなくば ACKがある場合 セグメントの優先度がTCBの優先度と一致しなければならない。一致 しない場合はリセットを送信する。 ACKが無い場合 セグメントの優先度がTCBの優先度よりも高いときは、ユーザとシス テムが許可すればシステムがTCBの優先度をセグメントの優先度まで 上げ、優先度を上げることを許可しないならばリセットを送信する。 セグメントの優先度がTCBの優先度よりも低いときは続ける。 リセットが送信された場合、セグメントを廃棄して制御を返す。 4:SYNビットチェック このステップには、ACKが大丈夫である場合、あるいはACKが無くセグメ ントがRSTを含んでいなかった場合だけ到着するはずである。 SYNビットがオンで、セキュリティ/コンパートメントおよび優先度が 受け入れ可能であれば、RCV.NXTにSEG.SEQ+1をセットし、IRSにSEG.SEQ をセットする。SND.UNAは(ACKがあるなら)SEG.ACKと等しくなるまで [Page 65] 1981年9月 転送制御プロトコル 機能仕様 セグメント到着 進められ、その結果として確認された再送キュー上のセグメントは削除 されるべきである。 SND.UNA > ISS(こちらからのSYNにはACK済み)の場合、コネクション 状態がESTABLISHEDに変わり、ACKセグメント を作って送信する。送信用キューに入れられたデータや制御を含めるこ とは可能である。それ以外の制御やテキストがセグメントにある場合は、 以下の6番目のステップのURGビットをチェックする処理に進む。 さもなくば、SYN-RECEIVEDに入り、SYN,ACKセグメント を作って送信する。それ以外の制御やテキストがセグメントにある場合 は、ESTABLISHED状態になった後で処理をするためにキューに入れられ、 制御を返す。 5:SYNビットまたはRSTビットがどちらもセットされていない場合、セグ メントを廃棄して制御を返す。 [Page 66] 1981年9月 転送制御プロトコル 機能仕様 セグメント到着 その他の場合 1:シーケンス番号チェック SYN-RECEIVED状態 ESTABLISHED状態 FIN-WAIT-1状態 FIN-WAIT-2状態 CLOSE-WAIT状態 CLOSING状態 LAST-ACK状態 TIME-WAIT状態 セグメントは順番に処理される。到着し次第、初期の判定を使って古い 重複を廃棄するが、以降の処理はSEG.SEQに従って行なわれる。セグメ ントの中身が新旧の境界に跨がっている場合、新しい部分だけを処理す べきである。 受信セグメントに対する受け入れ可否判定には次の4つのケースがある。 セグメ 受信ウィ 判定 ント長 ンドウ ------- ------- ------------------------------------------- 0 0 SEG.SEQ = RCV.NXT 0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND >0 0 許容されない >0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND または RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND RCV.WNDが0の場合、セグメントは受け入れられないが、正当なACK、URG、 RSTを受け入れるために特別な抜け道を作るべきである。 受信セグメントが受け入れ不可能な場合、次のような応答で確認応答を 送るべきである(これはRSTビットがセットされていない場合である。 もしセットされているならセグメントを廃棄して制御を返す)。 この確認応答を送信した後、受け入れられないセグメントを廃棄し制御 を返す。 以降では、セグメントはRCV.NXTで始まり、ウィンドウを超えない理想 的なセグメントであると仮定している。(SYNとFINを含めて)ウィンド [Page 67] 1981年9月 転送制御プロトコル 機能仕様 セグメント到着 ウの範囲外にある部分を切り捨てて、セグメントの開始がRCV.NXTにな るように処理を進めるだけで、実際のセグメントを仮定に沿うように合 わせることも可能だろう。大きいシーケンス番号を持つセグメントは後 で処理するために保持できる。 2:RSTビットチェック SYN-RECEIVED状態 RSTビットがセットされている場合 このコネクションが受動OPENで始められている場合(すなわち、 LISTEN状態からの場合)、このコネクションはLISTEN状態に戻り制御 を返す。ユーザは通知を必要としない。このコネクションが能動OPEN で始められている場合(すなわちSYN-SENT状態からの場合)、コネク ションは拒否され、ユーザに“connection refused”(コネクション 拒否)を通知する。どちらの場合も、再送キューにある全セグメント が削除されるべきである。能動OPENの場合、CLOSED状態に入り、TCB を削除し、制御を返す。 ESTABLISHED状態 FIN-WAIT-1状態 FIN-WAIT-2状態 CLOSE-WAIT状態 RSTビットがセットされている場合、未解決のRECEIVEおよびSENDは “reset”という応答を受信すべきである。全てのセグメントキューは 一掃されるべきである。またユーザは、一方的で包括的な“connection reset”(コネクションリセット)シグナルを受信すべきでもある。そ してCLOSED状態に入り、TCBを削除して、制御を返す。 CLOSING状態 LAST-ACK状態 TIME-WAIT状態 RSTビットがセットされている場合、CLOSED状態に入り、TCBを削除し、 制御を返す。 3:セキュリティおよび優先度チェック SYN-RECEIVED状態 セグメントのセキュリティ/コンパートメントおよび優先度がTCBのセ キュリティ/コンパートメントおよび優先度と完全一致しない場合、リ セットを送信して制御を返す。 [Page 68] 1981年9月 転送制御プロトコル 機能仕様 セグメント到着 ESTABLISHED状態 セグメントのセキュリティ/コンパートメントおよび優先度がTCBのセ キュリティ/コンパートメントおよび優先度と完全一致しない場合、リ セットを送信し、未解決のRECEIVEおよびSENDは“reset”という応答を 受信すべきである。全てのセグメントキューは一掃されるべきである。 またユーザは、一方的で包括的な“connection reset”(コネクション リセット)シグナルを受信すべきでもある。そしてCLOSED状態に入り、 TCBを削除して、制御を返す。 注意:このチェックはシーケンスチェックの後になっている。これは、問 題とするポート間で異なるセキュリティまたは異なる優先度を持つ古いコ ネクションからのセグメントによって、現在のコネクションの中断が起き ないようにするためである。 4:SYNビットチェック SYN-RECEIVED状態 ESTABLISHED状態 FIN-WAIT-1状態 FIN-WAIT-2状態 CLOSE-WAIT状態 CLOSING状態 LAST-ACK状態 TIME-WAIT状態 SYNがウィンドウ範囲内ならば、エラーであり、リセットを送信し、未 解決のRECEIVEおよびSENDは“reset”という応答を受信すべきである。 全てのセグメントキューは一掃され、またユーザは一方的で包括的な “connection reset”(コネクションリセット)シグナルを受信すべき でもある。そしてCLOSED状態に入り、TCBを削除して、制御を返す。 SYNがウィンドウ範囲外であれば、このステップには到達せず、1番目の ステップ(シーケンス番号チェック)でACKが送信されるだろう。 5:ACKフィールドチェック ACKビットがオフの場合、セグメントを廃棄して制御を返す ACKビットがオンの場合 SYN-RECEIVED状態 SND.UNA =< SEG.ACK =< SND.NXT ならば、ESTABLISHED状態に入って 処理を継続する。 セグメントの確認応答が受け入れられないときは、リセットセグメ [Page 69] 1981年9月 転送制御プロトコル 機能仕様 セグメント到着 ント を作って送信する。 ESTABLISHED状態 SND.UNA < SEG.ACK =< SND.NXT ならば、SND.UNA <- SEG.ACK とセッ トする。再送キューのセグメントで、それに関して全体が確認応答さ れるものは削除される。ユーザは、SENDされて完全な確認応答を受け たバッファに対して肯定の確認応答を受けるべきである(すなわち SENDバッファは“ok”応答で返されるべきである)。ACKが重複であ る場合(SEG.ACK < SND.UNA)は無視することができる。ACKが未送信 のものに確認応答している場合(SEG.ACK > SND.NXT)はACKを送信し、 セグメントを廃棄して制御を返す。 SND.UNA < SEG.ACK =< SND.NXT の場合、送信ウィンドウは更新され るべきである。(SND.WL1 < SEG.SEQ または(SND.WL1 = SEG.SEQ か つ SND.WL2 =< SEG.ACK))の場合、SND.WND <- SEG.WND、 SND.WL1 <- SEG.SEQ、SND.WL2 <- SEG.ACK とセットする。 SND.WNDがSND.UNAからのオフセットであること、さらにSND.WL1は SND.WNDを更新する際に使用した最終セグメントのシーケンス番号を 記録していること、SND.WL2がSND.WNDを更新する際に使用した最終セ グメントの確認応答番号を記録していることに注意する。ここでのチ ェックによって、ウィンドウの更新に古いセグメントを使用しないよ うにしている。 FIN-WAIT-1状態 ESTABLISHED状態での処理に加えて、こちらからのFINに対してその時 点で確認応答されたなら、FIN-WAIT-2に入り、その状態での処理を続 ける。 FIN-WAIT-2状態 ESTABLISHED状態での処理に加えて、再送キューが空なら、ユーザのC LOSEに確認応答(“ok”)を出すことができるが、TCBを削除しては いけない。 CLOSE-WAIT状態 ESTABLISHED状態と同様の処理を行なう。 [Page 70] 1981年9月 転送制御プロトコル 機能仕様 セグメント到着 CLOSING状態 ESTABLISHED状態での処理に加えて、こちらからのFINにACKによって 確認応答されたならTIME-WAIT状態に入り、それ以外の場合はセグメ ントを無視する。 LAST-ACK状態 この状態で到着可能なものは、こちらからのFINに対する確認応答だ けである。こちらからのFINがこのときに確認応答された場合、TCBを 削除して、CLOSED状態に入り、制御を返す。 TIME-WAIT状態 この状態で到着可能なものは、リモート側のFINの再送だけである。 これに対して確認応答を送り、2 MSLのタイムアウト時間を再び開始 する。 6:URGビットチェック ESTABLISHED状態 FIN-WAIT-1状態 FIN-WAIT-2状態 URGビットがセットされている場合、RCV.UP <- max(RCV.UP, SEG.UP) とし、緊急ポインタ(RCV.UP)が処理済データよりも先にあるならユー ザにリモート側が緊急データを持っていることを通知する。この連続的 な緊急データのシーケンスに対して、ユーザにすでに通知している(あ るいはユーザが「緊急モード」のままである)場合、再度ユーザに通知 してはいけない。 CLOSE-WAIT状態 CLOSING状態 LAST-ACK状態 TIME-WAIT状態 FINをリモート側から受信しているのため、これは起こるはずが無い。 URGは無視する。 7:セグメントテキスト処理 ESTABLISHED状態 FIN-WAIT-1状態 FIN-WAIT-2状態 一度ESTABLISHED状態になれば、セグメントテキストをユーザのRECEIVE バッファに配達することが可能である。テキストはセグメントから、バ [Page 71] 1981年9月 転送制御プロトコル 機能仕様 セグメント到着 ッファが一杯になるか、セグメントが空になるまでバッファに移動させ ることができる。セグメントが空になってPUSHフラグを運んでいるなら、 バッファが返されるときPUSHが受信されたことをユーザに通知する。 TCPがデータをユーザに届ける責任を負うとき、データの受領の確認応 答もしなければならない。 TCPがデータの責任を持つと、RCV.NXTを受け入れたデータの次に進め、 RCV.WNDを利用可能な現在のバッファに合わせて調整する。RCV.NXTと RCV.WNDの合計は減らすべきではない。 第3.7項のウィンドウ管理の提案について注意していただきたい。 次の形式の確認応答を送信する。 この確認応答は、過度の遅延を被らずに可能であれば転送されるセグメ ントに相乗りさせるべきである。 CLOSE-WAIT状態 CLOSING状態 LAST-ACK状態 TIME-WAIT状態 FINをリモート側から受信しているのため、これは起こるはずが無い。 セグメントテキストは無視する。 8:FINビットチェック 状態がCLOSED、LISTEN、SYN-SENTである場合FINを処理してはいけない。 なぜなら、SEG.SEQが有効ではないはずだからである。セグメントを廃棄 して制御を返す。 FINビットがセットされている場合、ユーザに“connection closing” (コネクションクローズ中)を通知し、未処理のRECEIVE全てに同じメッ セージを返し、RCV.NXTをFINの次に進め、FINに対する確認応答を送信す る。ユーザに未配達のセグメントについてFINはPUSHを含んでいることに 注意すること。 SYN-RECEIVED状態 ESTABLISHED状態 CLOSE-WAIT状態に入る。 [Page 72] 1981年9月 転送制御プロトコル 機能仕様 セグメント到着 FIN-WAIT-1状態 こちらからのFINに(おそらくこのセグメントで)ACKが返ってきてい る場合、TIME-WAITに入り、待ち時間タイマを開始して、他のタイマ を止める。それ以外の場合はCLOSING状態に入る。 FIN-WAIT-2状態 TIME-WAIT状態に入る。待ち時間タイマを開始して、他のタイマを止 める。 CLOSE-WAIT状態 CLOSE-WAIT状態を維持。 CLOSING状態 CLOSING状態を維持。 LAST-ACK状態 LAST-ACK状態を維持。 TIME-WAIT状態 TIME-WAIT状態を維持。2MSLのタイムアウト待ち時間を再び開始する。 そして、制御を返す。 [Page 73] 1981年9月 転送制御プロトコル 機能仕様 ユーザタイムアウト ユーザタイムアウト 任意の状態で、ユーザタイムアウトを過ぎた場合、包括的にかつ全ての未処 理コールに対して“error: connection aborted due to user timeout” (エラー:コネクションはユーザタイムアウトによって中断)を通知し、 TCBの削除を行い、CLOSED状態に入り、制御を返す。 再送タイムアウト 任意の状態で、再送キューにあるセグメントについて再送タイムアウトを過 ぎた場合、再送キューの先頭にあるセグメントを再び送信し、再送タイマを 再初期化して制御を返す。 TIME-WAITタイムアウト コネクションについてTIME-WAITタイムアウトを過ぎた場合、TCBを削除して CLOSED状態に入り、制御を返す。 [Page 74] 1981年9月 転送制御プロトコル 用語 1822 BBN Report 1822、『The Specification of the Interconnection of a Host and an IMP』。ホスト・ARPANET間インターフェースの仕様。 ACK シーケンス番号を使用しない制御ビット(確認応答)。そのセグメン トの確認応答フィールドが送信側で次に受信を期待しているシーケン ス番号を指定しており、それ以前のシーケンス番号は全て受信確認し ていることを示している。 ARPANETメッセージ ARPANETにおいてホストとIMPの間での転送単位。最大サイズは約1012 オクテット(8096ビット)である。 ARPANETパケット IMP間のARPANETで内部的に使用される転送単位。最大サイズは約126 オクテット(1008ビット)である。 コネクション 一対のソケットで識別される論理的な通信パス。 データグラム パケット交換型コンピュータ通信ネットワークで送信されるメッセー ジ。 宛先アドレス 送信先のアドレス。通常はネットワークおよびホストの識別子。 FIN シーケンス番号を1つ使用する制御ビット(終了)。シーケンス空間 を使用するデータや制御をこれ以上送信側が送らないことを示してい る。 フラグメント 論理単位のデータの一部。特にインターネットフラグメントはインタ ーネットデータグラムの一部である。 FTP ファイル転送プロトコル。 ヘッダ メッセージやセグメント、フラグメント、パケット、データのブロッ クなどの先頭にある制御情報。 [Page 75] 1981年9月 転送制御プロトコル 用語 ホスト コンピュータ。特に通信ネットワークの観点ではメッセージの送信元 または宛先。 識別子 インターネットプロトコルのフィールド。この値は送信側によって割 り当てられ、データグラムのフラグメントの組み立てを助ける。 IMP インターフェースメッセージプロセッサ。ARPANETのパケットスイッ チ。 インターネットアドレス ホストレベルに特化した送信元または宛先のアドレス。 インターネットデータグラム インターネットヘッダとともにインターネットモジュールと上位プロ トコルの間で交換されるデータの単位。 インターネットフラグメント インターネットデータグラムのデータの一部にインターネットヘッダ を付けたもの。 IP インターネットプロトコル。 IRS 初期受信シーケンス番号。コネクションの送信側が使う最初のシーケ ンス番号。 ISN 初期シーケンス番号。コネクションで使われる最初のシーケンス番号 (ISSまたはIRSのどちらか)。クロックに基づく手続きで選択される。 ISS 初期送信シーケンス番号。コネクションの送信側が使う最初のシーケ ンス番号。 リーダ メッセージあるいはデータのブロックの先頭にある制御情報。とくに ARPANETでは、ホスト・IMPインタフェースでのARPANETメッセージ上 の制御情報。 残りシーケンス これは、データ受信側TCPが確認応答すべき次のシーケンス番号(あ るいはその時点で確認応答されていない最も小さいシーケンス番号) で、送信ウィンドウの残りエッジと呼ばれることもある。 [Page 76] 1981年9月 転送制御プロトコル 用語 ローカルパケット ローカルネットワーク内での転送単位。 モジュール プロトコルやその他のプロシージャの実装で、普通はソフトウェアで ある。 MSL 最大セグメント寿命。TCPセグメントがインターネットワークシステ ムで存在できる時間。 オクテット 8ビットバイト。 オプション オプションフィールドは複数のオプションを持つことができ、各オプ ションは長さが数オクテットとなる。オプションは主に試験の場面、 例えばタイムスタンプを付加する際などで使用される。インターネッ トプロトコルもTCPもオプションフィールドを提供している。 パケット ヘッダを持つデータの塊で、論理的に完全であってもなくても構わな い。大抵は論理的なデータのパッケージ化よりも物理的なパッケージ 化のことである。 ポート 当該データに関連しているプロセスの論理入力チャネルまたは論理出 力チャネルを指定するソケットの一部。 プロセス 実行中のプログラム。TCPやその他のホスト間プロトコルの観点で見 るとデータの送信元または宛先である。 PUSH シーケンス空間を使用しない制御ビット。受信側ユーザにプッシュス ルーしなければならないデータをこのセグメントが含んでいることを 示している。 RCV.NXT 次の受信シーケンス番号 RCV.UP 受信緊急ポインタ RCV.WND 受信ウィンドウ [Page 77] 1981年9月 転送制御プロトコル 用語 次の受信シーケンス番号 これはローカルTCPが受信を期待している次のシーケンス番号である。 受信ウィンドウ ローカル(受信側)TCPが受信を認めているシーケンス番号を表して いる。ゆえに、ローカルTCPは、RCV.NXTからRCV.NXT + RCV.WND - 1 の範囲に重なるセグメントは受け入れられるデータまたは制御を運ん でいると見なす。この範囲から完全に外れているシーケンス番号を持 つセグメントは、重複と見なされ廃棄される。 RST シーケンス番号を使用しない制御ビット(リセット)。受信側はこれ 以上対話せずにコネクションを削除するべきだということを表してい る。リセットコマンドを有効とするか無視するかを、受信側は受信セ グメントのシーケンス番号フィールドと確認応答フィールドに基づい て決定する。いかなる場合も、RSTを含むセグメントの受信によって RSTの応答を引き起こすことはない。 RTP リアルタイムプロトコル、すなわち時間重視の情報を通信するための ホスト間プロトコル。 SEG.ACK セグメント確認応答 SEG.LEN セグメント長 SEG.PRC セグメント優先度値 SEG.SEQ セグメントシーケンス SEG.UP セグメント緊急ポインタフィールド SEG.WND セグメントウィンドウフィールド セグメント 論理的なデータ単位。特にTCPセグメントは、TCPモジュール間で転送 されるデータ単位である。 セグメント確認応答 到着セグメントの確認応答フィールドにあるシーケンス番号。 [Page 78] 1981年9月 転送制御プロトコル 用語 セグメント長 セグメントが使用するシーケンス番号空間の大きさで、シーケンス空 間を使用する任意の制御も含まれる。 セグメントシーケンス 到着セグメントのシーケンスフィールドにあるシーケンス番号。 送信シーケンス これはローカル(送信側)TCPがコネクションで使用する次のシーケ ンス番号である。まず初期シーケンス番号曲線(ISN)より選ばれ、 転送されるデータの各オクテットの分だけ、あるいは順番に扱われる 制御の分だけ値が増加する。 送信ウィンドウ これはリモート(受信側)TCPが受信して構わないとするシーケンス 番号を表している。これはリモート(データ受信側)TCPからのセグ メントで指定されているウィンドウフィールドの値である。TCPが出 せる新たなシーケンス番号の範囲はSND.NXTとSND.UNA + SND.WND - 1 の間になるようにしなければならない(もちろん、SND.UNAとSND.NXT の間のシーケンス番号の再送はあり得ることである)。 SND.NXT 送信シーケンス SND.UNA 残りシーケンス SND.UP 送信緊急ポインタ SND.WL1 最新のウィンドウ更新におけるセグメントシーケンス番号 SND.WL2 最新のウィンドウ更新におけるセグメント確認応答番号 SND.WND 送信ウィンドウ ソケット ポート識別子を明確に含むアドレス、すなわちインターネットアドレ スとTCPポートの組合わせである。 送信元アドレス 送信元のアドレス。通常はネットワークおよびホストの識別子。 [Page 79] 1981年9月 転送制御プロトコル 用語 SYN シーケンス番号を1つ使用する受信セグメントの制御ビット。コネク ションの開始で、シーケンス番号を降り始めたことを表すために使わ れる。 TCB 転送制御ブロック。コネクションの状態を記録するデータ構造。 TCB.PRC コネクションの優先度 TCP 転送制御プロトコル。インターネットワーク環境において信頼性のあ る通信を行うためのホスト間プロトコル。 TOS サービスタイプ。インターネットプロトコルフィールド。 サービスタイプ そのインターネットフラグメントに対するサービスのタイプを示すイ ンターネットプロトコルフィールド。 URG シーケンス番号を1つ使用する制御ビット(緊急)。緊急ポインタで 示される値よりも小さいシーケンス番号を持っている処理すべきデー タが存在する限り、受信側ユーザは緊急処理を行うべきであることを 示すために使われる。 緊急ポインタ URGビットがオンであるときだけ意味を持つ制御フィールド。このフ ィールドは緊急ポインタの値を通知し、緊急ポインタは送信側ユーザ の緊急コールと関連するデータオクテットを示している。 [Page 80] 1981年9月 転送制御プロトコル 参考文献 [1] Cerf, V., and R. Kahn, "A Protocol for Packet Network Intercommunication", IEEE Transactions on Communications, Vol. COM-22, No. 5, pp 637-648, May 1974. [2] Postel, J. (ed.), "Internet Protocol - DARPA Internet Program Protocol Specification", RFC 791, USC/Information Sciences Institute, September 1981. [3] Dalal, Y. and C. Sunshine, "Connection Management in Transport Protocols", Computer Networks, Vol. 2, No. 6, pp. 454-473, December 1978. [4] Postel, J., "Assigned Numbers", RFC 790, USC/Information Sciences Institute, September 1981. [Page 81]
一覧
スポンサーリンク