RFC: 793 TRANSMISSION CONTROL PROTOCOL DARPA INTERNET PROGRAM PROTOCOL SPECIFICATION September 1981 prepared for Defense Advanced Research Projects Agency Information Processing Techniques Office 1400 Wilson Boulevard Arlington, Virginia 22209 by Information Sciences Institute University of Southern California 4676 Admiralty Way Marina del Rey, California 90291 TABLE OF CONTENTS 序章 1. 導入 1.1 動機 1.2 概要 1.3 このドキュメントについて 1.4 インタフェース 1.5 オペレーション 2. 原理 2.1 相互動作システムの要素 2.2 オペレーションのモデル 2.3 ホスト環境 2.4 インタフェース 2.5 他のプロトコルとの関係 2.6 信頼できる通信 2.7 コネクションの確立と解放 2.8 データ通信 2.9 優先度とセキュリティ 2.10 頑強さの指針 3. 機能規定 3.1 ヘッダ形式 3.2 用語 3.3 シーケンス番号 3.4 コネクション確立 3.5 コネクション解放 3.6 優先度とセキュリティ 3.7 データ通信 3.8 インタフェース 3.9 イベント処理 用語 参照 序章 このドキュメントは、DoD 標準 Transmission Control Protocol (TCP)を規定 している。この標準が基づいている 前の ARPA TCP 規約は、9 つの版があっ た。そして現在のテキストは、それらをかなり取り入れている。概念やテキス トの両方に関して、この作業に多くの寄書があった。この編集は、幾つかの詳 細を分類している。そして、終端文字のバッファサイズの調整 (end-of- letter buffer-size adjustments) を削除し、文字メカニズムを push 機能と して再規定している。 Jon Postel Editor 1. 導入 転送制御プロトコル (TCP: Transmission Control Protocol) は、パケット交 換コンピュータ通信ネットワーク内で、そしてその様なネットワークの相互接 続システムにおいて、ホスト間の高く信頼できる host-to-hostプロトコルと して使用することを意図している。 このドキュメントは、Transmission Control Protocol によって実行される機 能、それを実装するプログラム、そのサービスを要求するプログラムか利用者 へのインタフェースについて記述している。 1.1. 動機 コンピュータ通信システムは軍事、政治、市民環境において増しつつある重 要な役割を担っている。このドキュメントは基本的に、軍事コンピュータ通 信の要求、特に信頼の無い通信における信頼性の強化、混雑時の効率化に的 を絞っている。これらの問題はの多くは、市民や政治の場面でも見られる。 戦略的、戦術的コンピュータ通信ネットワークが開発され導入されるにつれ て、それらを相互接続する手段や、広範囲なアプリケーションをサポートで きる標準的な相互処理通信プロトコルを提供することが不可欠になっている。 その様な標準の必要性を見越して、国防次官調査技術委員会 (Deputy Undersecretary of Defense for Research and Engineering) は、ここで規 定されている Transmission Control Protocol (TCP) が、DoD-wide な相互 処理通信プロトコル標準の基礎であることを宣言した。 TCP は、コネクション型でエンドツーエンドの信頼できるプロトコルであり、 マルチネットワークアプリケーションをサポートするプロトコルの層に分か れた階層に合わせるために設計された。TCP は、別々だが相互に接続された コンピュータ通信ネットワークに接続されたホストコンピュータで、一組の プロセス間の信頼できる相互処理通信を提供する。TCP 層以下の通信プロト コルの信頼性については、ほとんど想定していない。TCP は、下位レベルの プロトコルから、単純で潜在的に信頼できないデータグラムサービスを受け られることを想定している。原則的に、TCP はハード組み込み接続からパケ ット交換、又は回線交換ネットワークまでの、広範囲な通信システムのスペ クトル上で扱えるべきである。 TCP は、[1] で Cerf and Kahn によって最初に規定された概念に基づいて いる。TCP は基本的な Internet Protocol [2] の直上に、層で分けられた プロトコル体系に適合しており、Internet Protocol は TCPがインターネッ トデータグラムの "封筒" に同封された、可変長の情報のセグメントを送受 信する方法を提供する。インターネットデータグラムは、異なるネットワー ク内にある送信元と宛先の TCP をアドレス付けする手段を提供する。 Internet Protocol は又、複数のネットワークや相互接続ゲートウェイを通 じて転送と配送を実現するために要求された TCP セグメントのセグメント 化と再組み立てを扱っている。さらにInternet Protocol は、TCP セグメン トの優先度、セキュリティ分類、区分に関する情報も運ぶ。よってこの情報 は、複数のネットワークに渡ってエンドツーエンドに伝達することができる。 Protocol Layering +---------------------+ | higher-level | +---------------------+ | TCP | +---------------------+ | internet protocol | +---------------------+ |communication network| +---------------------+ Figure 1 そのドキュメントの大半は、ホストコンピュータ内の上位レベルプロトコル と同居している TCP 実装のコンテキストで記述されている。あるコンピュ ータシステムは、ネットワーク特定ソフトウェアだけでなく、TCP と Internet Protocol が実装されている front-end コンピュータを経由して ネットワークに接続されるかもしれない。TCP 規約は、適切な host-to- front-end プロトコルが実装されている限り、front-endの場合さえも実装 できるような上位レベルプロトコルへのインタフェースを規定している。 1.2. 概要 TCP は、マルチネットワーク内での、信頼できる process-to-process 通信 サービスを提供することを意図している。TCP は、複数のネットワークで共 通で使用される host-to-host のプロトコルであることを意図している。 1.3. このドキュメントについて このドキュメントは、上位レベルプロトコルとの相互動作と、他の TCPとの 相互動作の両面に関する全ての TCP の実装に要求された振る舞いの規定を 表している。この節の残りは、プロトコルインタフェースと処理の非常に簡 潔な観点を提供している。第 2 節は、TCP 設計の根本的思想を要約してい る。第 3 節は、様々なイベント (新たなセグメントの到達、利用者のコー ル、エラー等) が発生した時に TCP に要求された動作の詳細な規定と TCP セグメントのフォーマットの詳細の両方を提供している。 1.4. インタフェース TCP は、一方では利用者かアプリケーションのプロセスへの、もう一方では 例えば Internet Protocol の様な下位レベルプロトコルへの橋渡しをする。 アプリケーションプロセスと TCP 間のインタフェースは、効率的に詳しく 図示されている。このインタフェースは、ファイルを扱うためにオペレーティ ングシステムがアプリケーションプロセスに提供しているコールに、非常に よく似たコールのセットから構成される。例えば、確立されたコネクション 上でデータを送受信するために、コネクションをオープン/クローズするコ ールがある。又 TCP は、非同期でアプリケーションプログラムと通信でき ることを期待されている。ある特定のオペレーティングシステム環境に適し たインタフェースを設計するために、かなりの自由度が TCP の実装者に許 されているが、全ての正しい実装の TCP/user インタフェースにおいて、最 小限の機能性は求められる。 TCP と下位レベルプロトコル間のインタフェースは、2 つのレベルがお互い に非同期に情報を渡し合うメカニズムが存在するという想定を除き、本質的 に規定しない。一般的に、下位レベルのプロトコルでこのインターフェース を規定することが期待される。TCP は、相互接続された非常に一般的な環境 で動作するために設計されている。このドキュメントを通して想定される下 位レベルのプロトコルは、Internet Protocol [2]である。 1.5. オペレーション 上記で示されている様に、TCP の主要目的は、一組のプロセス間で信頼でき て保証できる論理回線サービス、あるいはコネクションサービスを提供する ことである。信頼性の薄いインターネット通信システムの最上位でこのサー ビスを提供するために、以下の分野における設備が必要である。 基本データ転送 (Basic Data Transfer) 信頼性 (Reliability) フロー制御 (Flow Control) 多重化 (Multiplexing) コネクション (Connections) 優先度とセキュリティ (Precedence and Security) これらの分野の各々における TCP の基本処理は、以下のパラグラフに記述 されている。 基本データ転送 (Basic Data Transfer) TCP は、数個のオクテットをインターネットシステムを通じて転送するた めのセグメントにパッケージングすることによって、オクテットの連続的 ストリームを利用者間の各々の方向に転送することができる。通常 TCP は、いつデータをブロックしたり転送するかを自身の便宜で決定する。 時々利用者は、TCP に渡したデータの全てが転送されたことを確かめる必 要がある。この目的のために push 機能が定義されている。TCPに渡され たデータが実際に転送されたことを確かめるために、送信側利用者は TCP に、受信側利用者に push せよと指示する。push は、TCP にそのポイン トまでのデータを受信側に即座に送信/配送させる。正確な push ポイン トは受信側利用者には見えないかもしれない。また push 機能は、レコー ド境界のマーカを供給しない。 信頼性 (Reliability) TCP は、インターネット通信システムによって破損を受けたり、欠損した り、重複したり、順番通りに配送されていないデータを回復させなければ ならない。これは、転送する各々のオクテットにシーケンス番号を割り当 て、受信側 TCP からの肯定応答 (ACK: positive acknowledgment) を要 求することによって実現される。もし タイムアウト間隔以内に ACK を受 信しなければ、そのデータは再送される。受信側では、順番通りに受信し ていないかもしれないセグメントを正しく順序付けたり、重複を取り除く ためにシーケンス番号を使用する。破損は、転送するセグメントの各々に チェックサムを付加し、受信側でそれをチェックして、破損があるセグメ ントは破棄することによって処理される。 TCP が適切に機能し続け、インターネットシステムが完全に分離されない 限り、転送エラーが正常なデータの配送に影響することはないだろう。 TCP は、インターネット通信システムの異常から回復させる。 フロー制御 (Flow Control) TCP は、受信者が送信者によって送信されるデータ量を抑制する手段を提 供する。これは、正常に受信した最終セグメント以降の受諾できるシーケ ンス番号の範囲を示す全ての ACK で、"ウィンドウ" を返すことによって 実現される。ウィンドウは、送信者が次の許可を受ける前に転送してもよ いオクテット数を示す。 多重化 (Multiplexing) 単一のホスト内で多くのプロセスが TCP 通信設備を同時に使用可能にす るために、TCP は各ホスト内でアドレスかポートのセットを提供する。イ ンターネット通信層からのネットワークとホストのアドレスを連結して、 ソケットを形成する。ソケットのペアは各々のコネクションをユニークに 識別する。すなわち、ソケットは複数のコネクションで同時に使用しても よい。 ポートのプロセスへの結び付け (binding) は、各々のホストによって独 立して処理される。しかし、しばしば使用されるプロセス (例えば " logger" や時分割サービス) を、公に知られている固定のソケットに割り 当てることは、便利であることが判明している。これらのサービスは、既 知のアドレスを通じてアクセスすることができる。他のプロセスのポート アドレスを設けたり知ることは、より動的なメカニズムを伴うかもしれな い。 コネクション (Connections) 上記に示されている信頼性とフロー制御メカニズムは、TCP が各々のデー タストリームに対するあるステータス情報を初期化して維持することを必 要とする。ソケットやシーケンス番号、ウィンドウサイズを含むこれらの 情報のコンビネーションは、コネクションと呼ばれる。各々のコネクショ ンは、両者を識別する一対のソケットによってユニークに指定される。 2 つのプロセスが通信することを望む時、それらの TCP はまず始めにコ ネクションを確立しなければならない (各々の側でステータス情報を初期 化する)。それらの通信が完了した時、コネクションを終了又はクローズ して、他で使用するために資源を解放する。 コネクションは、信頼できないホスト間で、信頼できないインターネット 通信システム上で確立しなければならないので、クロックに基づくシーケ ンス番号を持ったハンドシェークメカニズムが、コネクションの初期化異 常を避けるために利用される。 優先度とセキュリティ (Precedence and Security) TCP の利用者は、その通信のセキュリティと優先度を指示してもよい。こ れらの特徴が必要でない時に使用されるデフォルト値が設けられている。 2. 原理 2.1. 相互動作システムの要素 相互ネットワーク環境は、ゲートウェイを経由して相互接続されるネットワ ークに接続されたホストで構成される。ネットワークはローカルネットワー ク (例えば Ethernet) か大規模ネットワーク (例えばARPANET) のどちらか であることが想定されるが、いずれのケースもパケット交換技術に基づいて いる。メッセージを生成し消費する活性エージェントは、プロセスである。 ネットワーク中のプロトコルやゲートウェイやホストの様々なレベルは、プ ロセスポート間の論理接続上で 2 方向データフローを提供する相互処理通 信システムをサポートする。 パケットという言葉は、ホストとネットワーク間の 1 トランザクションの データを意味するために、総称的にここでは使用される。ネットワーク内で 交換されるデータブロックのフォーマットは、通常我々には関係ない。 ホストは、ネットワークと結びついたコンピュータであり、通信ネットワー クの観点から見るとパケットの送信元と宛先である。プロセスは、ホストコ ンピュータ中では活性化した要素として見られる (実行プログラムとしての プロセスの公正な共通定義に従って)。端末やファイル又は他の I/O デバイ スでさえ、プロセスの使用を通じて互いに通信している様に見られる。よっ て、全ての通信は相互プロセス通信として見られる。 プロセスは、自分自身と他のプロセスとの間の幾つかの通信ストリームの中 で区別する必要があるので、各々のプロセスは数多くのポートを持ち、それ らを通じて他のプロセスのポートと通信するだろう。 2.2. オペレーションのモデル プロセスは、TCP を呼び出し、アーギュメントとしてデータのバッファを渡 すことによってデータを転送する。TCP は、これらのバッファからデータを セグメントに包み込む。受信側 TCP は、データをセグメントから受信側ユ ーザのバッファに置き、受信側ユーザに通知する。TCP は、信頼できる順序 のデータ転送を保証するために使用する制御情報を、セグメント中に含む。 インターネット通信のモデルは、ローカルネットワークへのインタフェース を提供する各 TCP に結び付いた Internet Protocol モジュールが存在する ことである。このインターネットモジュールは、TCP セグメントをインター ネットデータグラムの内部にパケット化し、これらのデータグラムを宛先イ ンターネットモジュールか、あるいは中間のゲートウェイに振り分ける。ロ ーカルネットワークを通じてデータグラムを転送するために、それはローカ ルネットワークパケットに埋め込まれる。 パケット交換は、ローカルパケットの宛先インターネットモジュールへの配 送を達成するために、更なるパケット化、セグメント化、あるいは他の処理 を実行するかもしれない。 ネットワーク間のゲートウェイにおいては、インターネットデータグラムは ローカルパケットから "包みが開けられ (unwrapped)"、どのネットワーク を通じてインターネットデータグラムを次に送るかを決定しようと試みる。 その後、インターネットデータグラムは、次のネットワークに適したローカ ルパケットに "包まれ (wrapped)"、次のゲートウェイか又は最終宛先に振 り分けられる。 ゲートウェイは、もし次のネットワークを通じての転送に必要であれば、イ ンターネットデータグラムを、より小さいインターネットデータグラムのフ ラグメントに分割してもよい。これを行うために、ゲートウェイは 1 セッ トのインターネットデータグラムを生成し、各々 1 つのフラグメントを運 ぶ。そのフラグメントは、次のゲートウェイで、より小さいフラグメントに 更に分割されるかもしれない。インターネットデータグラムのフラグメント 形式は、宛先インターネットモジュールがフラグメントをインターネットデ ータグラムに再組み立てできる様に設計されている。 宛先インターネットモジュールは、(必要があれば再組み立てを行った後)デ ータグラムからセグメントを解き、宛先 TCP に渡す。 この単純な処理モデルは、多くの詳細を取り繕う。一つの重要な特徴はサー ビスタイプである。これは、ゲートウェイ (又はインターネットモジュー ル) に、次のゲートウェイに配送するのに使用されるサービスパラメタを選 択する際の指標となる情報を提供する。サービス情報のタイプに含まれるも のは、データグラムの優先度である。データグラムは、複数レベルのセキュ リティ環境で運用されるホストやゲートウェイが、セキュリティを考慮して 適切にデータグラムを差別化することを可能にするために、セキュリティ情 報も運ぶかもしれない。 2.3. ホスト環境 TCP は、オペレーティングシステム中のモジュールであると想定される。利 用者は、ファイルシステムにアクセスするのとほとんど同じ様に TCPにアク セスする。TCP は、例えばデータ構造を管理するために、他のオペレーティ ングシステムの機能を呼んでもよい。ネットワークへの実際のインタフェー スは、デバイスドライバモジュールによって制御されると想定される。TCP は、ネットワークデバイスドライバを直接呼ばず、代わりにデバイスドライ バを呼ぶであろうインターネットデータグラムプロトコルモジュールを呼ぶ。 TCP のメカニズムは、front-end プロセッサにおける TCP の実装を除外し ていない。しかしそうした実装では、host-to-front-end プロトコルは、こ のドキュメントで規定されている TCP ユーザインタフェースのタイプをサ ポートする機能を提供しなければならない。 2.4. インタフェース TCP/ユーザインタフェースは、TCP 上で利用者がコネクションを OPENか CLOSE したり、データを SEND か RECEIVE したり、コネクションについて の STATUS を取得するための呼び出しを提供する。これらの呼び出しは、例 えばファイルの open, read, close のような、オペレーティングシステム 上のユーザプログラムからの他の呼び出しと似たものである。 TCP/internet インタフェースは、インターネットシステム内のあらゆるホ ストの中にある TCP モジュールにアドレス付けられたデータグラムを送受 信する呼び出しを提供する。これらの呼び出しは、アドレスやサービスタイ プ、優先度、セキュリティ、他の制御情報等を渡すパラメタを持つ。 2.5. 他のプロトコルとの関係 以下の図は、プロトコル階層内での TCP の場所を示している。 +------+ +-----+ +-----+ +-----+ |Telnet| | FTP | |Voice| ... | | Application Level +------+ +-----+ +-----+ +-----+ | | | | +-----+ +-----+ +-----+ | TCP | | RTP | ... | | Host Level +-----+ +-----+ +-----+ | | | +-------------------------------+ | Internet Protocol & ICMP | Gateway Level +-------------------------------+ | +---------------------------+ | Local Network Protocol | Network Level +---------------------------+ Protocol Relationships Figure 2. TCP が上位レベルのプロトコルを効率的にサポートできることが期待される。 ARPANET Telnet や TCP への AUTODIN II THP のような、上位レベルプロト コルへのインタフェースを持つことは簡単なはずである。 2.6. 信頼できる通信 TCP コネクション上で送信されるデータのストリームは、信頼性があり、順 番通りに宛先に配送される。 シーケンス番号と肯定応答を利用することによって、信頼できる転送が行わ れる。概念上では、データの各オクテットにシーケンス番号が割り当てられ る。データの一番目のオクテットのセグメント中のシーケンス番号は、その セグメントと共に転送され、セグメントシーケンス番号と呼ばれる。セグメ ントは、次に期待される逆方向転送のデータオクテットのシーケンス番号で ある確認番号も運ぶ。TCP がデータを含んでいるセグメントを転送する時、 再送キューにコピーを置き、タイマーを開始する。そのデータに対する肯定 応答を受信した時、そのセグメントがキューから削除される。もしタイマが 完了するまでに肯定応答を受信しなければ、そのセグメントは再送される。 TCP による肯定応答は、データがエンドユーザに届いたことは保証しておら ず、受信側 TCP がデータをエンドユーザに届ける責任があることを保証し ているだけである。 TCP 間のデータの流れを統治するために、フロー制御メカニズムが導入され る。受信側 TCP は、送信側 TCP に "ウィンドウ" を通知する。このウィン ドウは、受信側 TCP に現在受信する準備がされているオクテットの数 (確 認番号から始まる) を示している。 2.7. コネクションの確立と解放 TCP が扱うかもしれない別々のデータストリームを識別するために、TCP は ポート識別子を提供する。ポート識別子は各々の TCP によって独自に選択 されるので、それらはユニークでなくともよい。各 TCP 内でユニークなア ドレスを提供するために、我々は TCP を識別するインターネットアドレス をポート識別子と連結して、互いに接続された全てのネットワークを通して ユニークであるソケットを生成する。 コネクションは、最終的にはソケットのペアによって完全に指定される。ロ ーカルソケットは、別々の外部のソケットへの数多くのコネクションに参加 してもよい。コネクションは両方向にデータを運ぶのに使用できる。すなわ ち "全二重" である。 TCP はどのように選択するんであれ、自由にポートをプロセスに割り当てる ことができる。しかし、幾つかの基本的な概念が、あらゆる実装に必要であ る。TCP がある手段によって "適切な" プロセスのみに割り当てる、よく知 られた (well-known) ソケットが存在しなければならない。プロセスはポー トを "所有" し、プロセスは自ら所有しているポート上にのみコネクション を起動できると想定する。(所有権を実装する手段はローカルな問題である。 しかし、ポート要求 (Request Port) のユーザコマンドや、指定されたプロ セスへのポートのグループをユニークに割り当てる方法、例えばポート名の 高次ビットを指定されたプロセスに割り当てる等、が想定される)。 コネクションは、ローカルポートと外のソケットアーギュメントによるOPEN コールで指定される。お返しに TCP は、ユーザが以降の呼び出しでコネク ションを参照する (短い) ローカルコネクション名を提供する。コネクショ ンに関して覚えておかなければならないものが幾つかある。この情報を蓄積 するために、我々は転送制御ブロック (TCB: Transmission Control Block) と呼ばれるデータ構造があると想像する。一つの実装戦略は、このコネクショ ンに対する TCB へのポインタであるローカルなコネクション名を持つこと である。OPEN コールは、コネクション確立を能動的に遂行するか、受動的 に待つかを指定する。 受動的 OPEN 要求とは、プロセスがコネクションの起動を試みるのではなく、 入力コネクション要求の受信を望んでいることを意味する。受動的 OPEN を 要求しているプロセスは、大抵あらゆる発呼者からのコネクション要求を受 諾する。この場合、未指定のソケットであることを示すために、全て 0 の 外部のソケットが使用される。未指定の外部ソケットは受動的 OPEN のみに 使用できる。 未知の他プロセスに対するサービスを提供したいプロセスは、外部ソケット を指定せずに受動的 OPEN 要求を発行するだろう。そうすれば、このローカ ルソケットにコネクションを要求したいかなるプロセスとでも、コネクショ ンを確立することができる。もし、このローカルソケットがこのサービスに 割り当てられていることが知られていれば、役立つであろう。 よく知られたソケットは、ソケットアドレスを標準的なサービスに優先的に 割り当てるのに便利なメカニズムである。例えば、"Telnet サービス" プロ セスは、永久的にある特定のソケットに割り当てられており、他のソケット は File Transfer や Remote Job Entry, Text Generator, Echoer, Sink プロセスとして予約されている。(最後の 3つはテストのためのものであ る。) ソケットアドレスは、新たに作成されたサービスが提供されるであろ う、ある特定のソケットを返す " Look-Up" サービスへのアクセスとして予 約されるかもしれない。 プロセスは受動的 OPEN を発行し、他のプロセスから能動的 OPEN を受ける のを待つことができる。そして、コネクションが確立された時、TCP によっ て通知される。互いに同時に能動的 OPEN を発行した 2 つのプロセスは、 正しく接続されるであろう。この融通性は、コンポーネントが互いに非同期 で動作する分散コンピューティングのサポートにとって重要である。 自側の受動的 OPEN や外部の能動的 OPEN でのソケットを照合するために、 2 つの原則的なケースがある。一つ目は、自側の受動的 OPEN が完全に外部 のソケットを指定するケースである。この場合、正確に一致しなければなら ない。二つ目は、自側の受動的 OPEN が外部のソケットを指定しないままと するケースである。この場合、自側のソケットが一致すればあらゆる外部ソ ケットが受諾できる。 もし、同一の自側ソケットで幾つかのペンディングになっている受動的OPEN (TCB に記録されている) が存在するならば、外部の能動的 OPENは、未指定 の外部ソケットの TCB を選択する前に、外部の能動的 OPENで指定された外 部ソケットの TCB と一致するだろう (その様な TCB が存在するならば)。 コネクションを確立するための手続きは同期 (SYN: synchronize) 制御フラ グを利用し、3 つのメッセージ交換を行う。この交換は 3 方向ハンドシェ ーク [3] と名付けられている。 コネクションは、SYN を含むセグメントの到着と、ユーザ OPEN コマンドに よって各々生成された TCB エントリの待ちとの待ち合わせによって起動さ れる。自側と外部のソケットの照合は、いつコネクションが起動されたかを 決定する。そのコネクションは、シーケンス番号が両方向で同期がとられた 時に "確立済 (established)" になる。 コネクションのクリアもセグメントの交換を行う。この場合 FIN 制御フラ グを運ぶ。 2.8. データ通信 コネクション上に流れるデータは、オクテットのストリームと考えられる。 送信側ユーザは各々の SEND コールで、そのコール (とあらゆる先行コー ル) 中のデータを即座に受信側ユーザに押し出すべきか否かを、PUSH フラ グを設定することによって指示する。 送信側 TCP は、push 機能が通達されるまで、送信側ユーザからのデータを 集め、セグメント中のデータを都合の良い時に送信することができる。push 機能が通達されると全ての未送信データを送信しなければならない。受信側 の TCP が PUSH フラグを検出したら、受信側のプロセスにそのデータを渡 す前に送信側 TCP からデータを更に待ってはならない。 push 機能とセグメント境界の間は、必ずしも関係はない。ある特定のセグ メント中のデータは、その全てあるいは一部分が 1 つの SEND コールの結 果かもしれないし、複数の SEND コールの結果かもしれない。 push 機能や PUSH フラグの目的は、送信側ユーザから受信側ユーザにデー タを押し出すことである。記録サービスは提供しない。 push 機能と TCP/ユーザインタフェースを渡るデータのバッファの使用は連 結される。受信側ユーザのバッファに入れられるデータに PUSH フラグが付 いているたびに、そのバッファはたとえ一杯になっていなくても、処理する ためにユーザに返される。もし、PUSHを検出する前にユーザバッファを一杯 にするデータが到達したら、そのデータはバッファサイズの単位でユーザに 渡される。 TCP は、受信側が現在読み込んでいるデータストリームの更に先のポイント に緊急のデータが存在することを、データの受信側に通知する手段も提供す る。TCP は緊急データのペンディングを通知する際に、ユーザが明示的に何 を行うかを定義することは試みていない。しかし、受信側プロセスが緊急の データをすぐに処理する動作を実行するだろうといことは通常考えられる。 2.9. 優先度とセキュリティ TCP は、1 コネクション毎に TCP ユーザに優先度とセキュリティを提供す るために、Internet Protocol サービスタイプフィールドとセキュリティオ プションを使用する。全ての TCP モジュールが複数レベルのセキュリティ 環境の機能を必要とするわけではない。あるものは分類しない使用のみに限 定するかもしれないし、またあるものは 1 つのセキュリティレベルやコン パートメントでのみ処理するかもしれない。よって、TCP の実装とユーザへ のサービスは、複数レベルのセキュリティケースのサブセットに限定される かもしれない。 複数レベルのセキュリティ環境で処理する TCP モジュールは、セキュリ ティ、コンパートメント、優先度を持つ出力セグメントを適切にマークしな ければならない。そうした TCP モジュールはユーザや、Telentや THP 等の 上位レベルのプロトコルに、望ましいコネクションのセキュリティレベル、 コンパートメント、優先度の指定を可能にするためのインタフェースを提供 しなければならない。 2.10. 頑強さの指針 TCP の実装は、頑丈さの一般原則: 自ら行うことには慎重であれ、他から受 け入れるものには寛大であれ、に従う。 3. 機能規定 3.1. ヘッダ形式 TCP セグメントはインターネットデータグラムとして送信される。Internet Protocol ヘッダは、送信元と宛先ホストアドレス [2] を含む幾つかの情報 フィールドを運ぶ。TCP ヘッダはインターネットヘッダの次に続き、TCP プ ロトコルに特有の情報を提供する。この区分けにより、TCP 以外のホストレ ベルのプロトコルが存在できる。 TCP Header Format 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Port | Destination Port | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Sequence Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Acknowledgment Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data | |U|A|P|R|S|F| | | Offset| Reserved |R|C|S|S|Y|I| Window | | | |G|K|H|T|N|N| | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Checksum | Urgent Pointer | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Options | Padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | data | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Figure 3. TCP Header Format 注記: 区切りマークは 1 ビットを示す。 Source Port: 16 bits 送信元ポート番号 Destination Port: 16 bits 宛先ポート番号 Sequence Number: 32 bits このセグメント中の一番目のデータオクテットのシーケンス番号 (SYN が 提供されている時を除く)。もし SYN が提供されていれば、シーケンス番 号は初期シーケンス番号 (ISN) で、一番目のデータオクテットは ISN+1 である。 Acknowledgment Number: 32 bits もし、ACK 制御ビットが設定されていれば、このフィールドはセグメント の送信者が受信を期待している次のシーケンス番号の値を含む。一旦コネ クションが確立されると、これは常に設定される。 Data Offset: 4 bits TCP ヘッダの 32 ビット単位の個数。これはデータの始まる場所を示す。 TCP ヘッダは、(オプションを含んでいるものでさえ) 32 ビット長の整数 の数である。 Reserved: 6 bits 将来の使用のために予約。0 でなければならない。 Control Bits: 6 bits (from left to right): URG: 緊急ポインタフィールド識別 ACK: 確認フィールド識別 PSH: Push 機能 RST: コネクションのリセット SYN: 同期シーケンス番号 FIN: 送信側からのデータは無い Window: 16 bits 肯定応答フィールドで示される番号から開始して、このセグメントの送信 側が受信可能なデータオクテットの数。 Checksum: 16 bits チェックサムフィールドは、ヘッダとテキストの全ての 16 ビット単位の 1 の補数の合計の 16 ビットの 1 の補数である。もし、セグメントがチェ ックされるヘッダとテキストのオクテット数が奇数個を含むならば、最後 のオクテットは、チェックサムを行う目的で 16 ビット単位を形成するた めに、右側を 0 でパディングされる。パディングは、セグメントの一部 として送信されない。チェックサムを算出する際、チェックサムフィール ド自身は、0 で置き換えられる。 チェックサムは、TCP ヘッダの前に概念的に付加された 96 ビットの疑似 ヘッダもカバーする。この疑似ヘッダは、送信元アドレス、宛先アドレス、 プロトコル、TCP 長を含む。これにより、振分けに失敗したセグメントに 対する TCP での防御が可能になる。この情報はInternet Protocol で運 ばれ、TCP/Network インタフェースを通して、TCP の IP へのコールのア ーギュメントか結果で送信される。 +--------+--------+--------+--------+ | Source Address | +--------+--------+--------+--------+ | Destination Address | +--------+--------+--------+--------+ | zero | PTCL | TCP Length | +--------+--------+--------+--------+ TCP 長は、TCP ヘッダ長にデータのオクテット長を加えたもの (これは 明示的に転送される量ではなく、計算によるもの) で、疑似ヘッダの 12 オクテットは数えない。 Urgent Pointer: 16 bits このフィールドは緊急ポインタの現在の値を、このセグメントのシーケン ス番号からの正のオフセットとして通知する。緊急ポインタは、緊急デー タの後に続くオクテットのシーケンス番号を指す。このフィールドは、 URG 制御ビットが設定されたセグメントでのみ解釈される。 Options: 可変 オプションは TCP ヘッダの最後の部分を占め、長さは 8 ビットの倍数で ある。全てのオプションは、いかなるオクテット境界で始まってもよい。 オプションの形式には二つのケースがある。 Case 1: オプション種別の単一オクテット Case 2: オプション種別の 1 オクテット、オプションの長さを示す 1 オクテット、実際のオプションデータのオクテット。 オプション長は、オプションデータオクテットだけでなく、オプション種 別とオプション長の二つのオクテットも数える。 オプションのリストは、データオフセットフィールドが示している長さよ り短くてもよい。オプション最終オプションを超えたヘッダの中身は、ヘ ッダパディング (つまり 0) でなければならない。 TCP は全てのオプションを実装しなければならない。 現在定義されているオプションは、以下を含む (種別は 8 進)。 種別 長さ 意味 ---- ------ ------- 0 - オプションリストの最終 1 - 操作なし 2 4 最大セグメントサイズ 特定のオプション定義 オプションリストの最終 +--------+ |00000000| +--------+ 種別 = 0 このオプションコードは、オプションリストの最終を示す。これは、 データオフセットフィールドに従った TCP ヘッダの最終とは一致し ないかもしれない。これは、各オプションの最後で使用されるのでは なく、全オプションの最後で使用される。オプションの最後が TCP ヘッダの最後と一致しない場合にのみ使用する必要がある。 操作なし +--------+ |00000001| +--------+ 種別 = 1 このオプションコードは、例えば後続するオプションの開始をワード 境界に調整するために、オプションの間で使用してもよい。送信者が このオプションを使用する保証はない。よって受信側は、たとえワー ド境界で始まっていなくてもオプションを処理できるよう、準備して いなければならない。 最大セグメントサイズ +--------+--------+---------+--------+ |00000010|00000100| max seg size | +--------+--------+---------+--------+ 種別 = 2 長さ = 4 最大セグメントサイズのオプションデータ: 16 bits もし、このオプションが提供されたら、このセグメントを送信する TCP で、最大受信セグメントサイズを通信する。このフィールドは、 初期コネクション要求でのみ送信できる (すなわち、SYN 制御ビッ トが設定されたセグメント)。もしこのオフションが使用されなけ れば、いかなるセグメントサイズも許される。 パディング: 可変 TCP ヘッダパディングは、TCP ヘッダの最終とデータ部の開始が 32ビッ ト境界にあることを保証するために使用される。パディングは、0 から成 る。 3.2. 用語 TCP の扱いについて、かなり多くのことを論じるために、幾つかの用語を詳 細に紹介する必要がある。TCP コネクションを保守するために、幾つかの変 数を覚えておく必要がある。これらの変数は、転送制御ブロック (TCB: Transmission Control Block) と呼ばれるコネクションレコードの中に格納 されるものと想定する。TCB に格納される変数の中には、自側と相手側のソ ケット番号やセキュリティ、コネクションの優先度、ユーザが送受信したバ ッファへのポインタ、再送キューや現セグメントへのポインタがある。加え て、送受信シーケンス番号に相当する幾つかの変数が TCB に格納される。 送信シーケンス変数 SND.UNA - 確認未の送信 SND.NXT - 次の送信 SND.WND - ウィンドウの送信 SND.UP - 緊急ポインタの送信 SND.WL1 - 最後のウィンドウの更新に使用されるセグメントシーケンス 番号 SND.WL2 - 最後のウィンドウの更新に使用されるセグメント確認番号 ISS - 初期送信シーケンス番号 受信シーケンス変数 RCV.NXT - 次の受信 RCV.WND - ウィンドウの受信 RCV.UP - 緊急ポインタの受信 IRS - 初期受信シーケンス番号 以下の図は、これらの変数の幾つかをシーケンス空間に関連させるのに助け になるだろう。 送信シーケンス空間 1 2 3 4 ----------|----------|----------|---------- SND.UNA SND.NXT SND.UNA +SND.WND 1 - 確認済の古いシーケンス番号 2 - 確認未のシーケンス番号 3 - 新しいデータの転送で使用できるシーケンス番号 4 - まだ使用できない将来のシーケンス番号 Send Sequence Space Figure 4. 送信ウィンドウは、図 4 のシーケンス空間のラベル 3 の所である。 受信シーケンス空間 1 2 3 ----------|----------|---------- RCV.NXT RCV.NXT +RCV.WND 1 - 確認済の古いシーケンス番号 2 - 新たに受信できるシーケンス番号 3 - まだ使用できない将来のシーケンス番号 Receive Sequence Space Figure 5. 受信ウィンドウは、図 5 のシーケンス空間のラベル 2 の所である。 また、現セグメントのフィールドの値を取り上げて論じる際に、しばしば使 用されるいくつかの変数がある。 現セグメント変数 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 は擬似である。というのは、CLOSED 状態とは TCB が無い、 つまりコネクションが無い状態を表すからである。状態の具体的な意味は以 下の通り。 LISTEN - あらゆるリモート TCP やポートからのコネクション要求を待っ ていることを表す。 SYN-SENT - コネクション要求を送信した後、それに一致するコネクショ ン要求を待っていることを表す。 SYN-RECEIVED - コネクション要求を送受信した後、そのコネクション要 求確認 (ACK) の肯定応答を待っていることを表す。 ESTABLISHED - コネクションのオープンを表し、受信したデータをユーザ に配送することができる。コネクションのデータ転送フェーズにとっての 通常の状態である。 FIN-WAIT-1 - リモート TCP からのコネクション終了要求か、前に送信し たコネクション終了要求の肯定応答を待っていることを表す。 FIN-WAIT-2 - リモート TCP からのコネクション終了要求を待っているこ とを表す。 CLOSE-WAIT - 自側 TCP からのコネクション終了要求を待っていることを 表す。 CLOSING - リモート TCP からのコネクション終了要求の肯定応答を待っ ていることを表す。 LAST-ACK - リモート TCP に前に送信したコネクション終了要求の肯定応 答を待っていることを表す (それは、コネクション終了要求の肯定応答を 含む)。 TIME-WAIT - リモート TCP がコネクション終了要求の肯定応答を受信し たことを保証するのに十分な時間待っていることを表す。 CLOSED - コネクションの状態が全く無いことを表す。 TCP コネクションは、イベントに応じてある状態から別の状態に進行する。 イベントとは、OPEN, SEND, RECEIVE, CLOSE, ABORT, STATUS のユーザコー ルや、入力セグメント (本来 SYN, ACK, RST, FIN フラグを含んでいる) や タイムアウトである。 図 6 の状態図は、原因となるイベントや結果として行うアクションと共に、 状態遷移を示している。しかし、状態遷移に結びつかないエラーの条件やア クションは示していない。イベントに対する TCP のリアクションに関する 詳細は、後のセクションで示されている。 注記:この図は要約に過ぎず、規定全体として扱ってはならない。 +---------+ ---------\ active OPEN | CLOSED | \ ----------- +---------+<---------\ \ create TCB | ^ \ \ snd SYN passive OPEN | | CLOSE \ \ ------------ | | ---------- \ \ create TCB | | delete TCB \ \ V | \ \ +---------+ CLOSE | \ | LISTEN | ---------- | | +---------+ delete TCB | | rcv SYN | | SEND | | ----------- | | ------- | V +---------+ snd SYN,ACK / \ snd SYN +---------+ | |<----------------- ------------------>| | | SYN | rcv SYN | SYN | | RCVD |<-----------------------------------------------| SENT | | | snd ACK | | | |------------------ -------------------| | +---------+ rcv ACK of SYN \ / rcv SYN,ACK +---------+ | -------------- | | ----------- | x | | snd ACK | V V | CLOSE +---------+ | ------- | ESTAB | | snd FIN +---------+ | CLOSE | | rcv FIN V ------- | | ------- +---------+ snd FIN / \ snd ACK +---------+ | FIN |<----------------- ------------------>| CLOSE | | WAIT-1 |------------------ | WAIT | +---------+ rcv FIN \ +---------+ | rcv ACK of FIN ------- | CLOSE | | -------------- snd ACK | ------- | V x V snd FIN V +---------+ +---------+ +---------+ |FINWAIT-2| | CLOSING | | LAST-ACK| +---------+ +---------+ +---------+ | rcv ACK of FIN | rcv ACK of FIN | | rcv FIN -------------- | Timeout=2MSL -------------- | | ------- x V ------------ x V \ snd ACK +---------+delete TCB +---------+ ------------------------>|TIME WAIT|------------------>| CLOSED | +---------+ +---------+ TCP Connection State Diagram Figure 6. 3.3. シーケンス番号 設計における基本的な考え方は、TCP コネクション上で送信されるデータの 全てのオクテットはシーケンス番号を持つということである。全てのオクテ ットは順番通りに並べられるので、それらの各々に対して確認することがで きる。提供される確認メカニズムは累積されるものなので、シーケンス番号 の X の確認は、X を含まない X までの全てのオクテットを受信したことを 示す。セグメント内のオクテットの番号付けにおいては、ベッダの直後に続 く一番目のデータオクテットに最も小さい番号が付けられ、それに続くオク テットは連番になる。 実際のシーケンス番号空間は非常に大きいが、有限であることを覚えておく ことは重要である。この空間は、0 から 2 の 32 乗 - 1 の範囲である。空 間が有限なので、シーケンス番号を扱う全ての計算は、2 の 32 乗のモジュ ロを実行しなければならない。この符号無しの計算は、2 の 32 乗 - 1 か ら 0 に再び環してシーケンス番号の関係を保つ。モジュロ計算を算出する 巧妙な方法が幾つかあるので、大半はその値の比較プログラミングに注意を 向けるべきである。"=<" の記号は、"以下" を意味する (モジュロ 2 の 32 乗)。 TCP が実行しなければならない典型的な種類のシーケンス番号の比較は、以 下を含む。 (a) 肯定応答が、送信されたがまだ確認されていない幾つかのシーケンス 番号を指しているか決める。 (b) セグメントによって占められた全てのシーケンス番号が確認されか決 める (例えば、再送キューからセグメントを削除するために)。 (c) 入力セグメントが期待したシーケンス番号を含んでいるか決定する (つまり、セグメントが受信ウィンドウに収まっているか)。 送信データに対する応答で、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 一番目のテストは、セグメントの開始がウィンドウの範囲内にあるか否かを チェックする。二番目のテストは、セグメントの最終がウィンドウの範囲内 にあるか否かをチェックする。セグメントがそのどちらかのテストにパスす れば、そのセグメントはウィンドウの範囲内のデータを含んでいる。 実際は、これよりも若干複雑である。0 ウィンドウと 0 長のセグメントの 場合、受信可能な入力セグメントは、以下の 4 つのケースである。 Segment Receive Test Length Window ------- ------- ------------------------------------------- 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 or RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND 注記: 受信ウィンドウが 0 である時、ACK セグメントを除くどのセグメン トも受諾できない。よって、データを送信して ACK を受信する間、TCP が 受信ウィンドウ 0 を維持することはあり得る。しかし、たとえ受信ウィン ドウが 0 であっても、TCP は全ての入力セグメントの RST と URG フィー ルドを処理しなければならない。 ある制御情報を保護するためにも、番号付スキームの利点を得ている。これ は、ある制御フラグをシーケンス空間に暗黙的に含めることによって達成さ れる。よって、それらは混乱することなく再送し確認することができる (例 えば、制御のコピーが一つだけ実行されるだろう)。制御情報は、物理的に はセグメントのデータ空間で運ばれない。従って、我々は制御にシーケンス 番号を暗黙的に割り当てるための規則を適用しなければならない。SYN と FIN が、この保護を必要とする唯一の制御であり、これらの制御はコネクショ ンをオープン又はクローズする時にのみ使用される。シーケンス番号の処理 に際し、SYN はそれが表れるセグメントの一番最初の実データオクテットの 前に表れると見なされる。一方、FIN はそれが表れるセグメントの一番最後 の実データオクテットの後に表れると見なされる。セグメント長 (SEG.LEN) は、制御を占めているデータとシーケンス空間の両方を含む。SYN が提供さ れる時、SEG.SEQ は SYN のシーケンス番号である Initial Sequence Number Selection プロトコルは、特定のコネクションを繰り返し使用することに何の制限も設 けない。コネクションは一組のソケットによって定義される。コネクション の新しいインスタンスは、コネクションの化身 (incarnation) として参照 される。これにより起きる問題は、"TCP はどのようにして、コネクション の前の化身からの重複セグメントを区別するか ?" である。この問題は、も しコネクションがオープンされ、続いて即座にクローズされたら、あるいは、 もしコネクションがメモリ不足で壊れ、再度確立されたら浮き彫りあがる。 混乱を避けるために、前のセグメントがまだネットワーク中に存在している かもしれない間、コネクションの 1 化身からのセグメントに前の化身のセ グメントと同じシーケンス番号が使用されることを防がなければならない。 たとえ TCP がクラッシュして、使用していたシーケンス番号の全ての知識 を失っても、これは保証したい。新しいコネクションが生成される時、初期 シーケンス番号 (ISN: initial sequence number) 生成機が用いられ、新し い 32 ビット ISN を選択する。生成機は、その下位ビットがおおよそ 4 マ イクロ秒ごとに加算される (おそらく疑似的な) 32 ビットクロックに結び 付けられる。よって、ISN はおよそ 4.55 時間毎に一回りする。セグメント はせいぜい最大セグメント生存期間 (MSL: Maximum Segment Lifetime) ま でしかネットワーク中に残存せず、MSL は 4.55 時間以下であると想定して いるので、ISN がユニークになるだろうと効率的に想定することができる。 各々のコネクションに対して、送信シーケンス番号と受信シーケンス番号が 存在する。初期送信シーケンス番号 (ISS) は、データを送信する TCP によ って選択される。そして、初期受信シーケンス番号 (IRS) は、コネクショ ン確立の手続きの間に知らされる。 確立または初期化されるコネクションに対して、二つの TCP はお互いの初 期シーケンス番号を同期させなければならない。これは、"SYN" (同期) と 呼ばれる制御ビットと初期シーケンス番号が設定されたコネクション確立の セグメントの交換で行われる。簡略化すると、SYN ビットを設定したセグメ ントは "SYNs" とも呼ばれる。よって解決方法としては、初期シーケンス番 号を選択し、ISN を交換する若干複雑なハンドシェークのための適切なメカ ニズムが必要である。 同期は、各々が自分の初期シーケンス番号を送信し、相手からその肯定応答 を受信する必要がある。各々が相手の初期シーケンス番号を受信し、それを 確認する肯定応答を送信しなければならない。 1) A → B SYN 私のシーケンス番号は X 2) A ← B ACK あなたのシーケンス番号は X 3) A ← B SYN 私のシーケンス番号は Y 4) A → B ACK あなたのシーケンス番号は Y ステップ 2 と 3 は一つのメッセージで結合できるので、これは 3 方向 (3 メッセージ) ハンドシェークと呼ばれる。 シーケンス番号がネットワークでグローバルなクロックに結びつかず、TCP は ISN を選択するための異なるメカニズムを持つかもしれないので、3 方 向ハンドシェークは必要である。一番最初の SYN の受信側は、そのコネク ションで使用された最後のシーケンス番号を覚えておかなければ (常に可能 ではない)、セグメントが古く遅れたものか否かを知る方法がない。よって、 送信側にこの SYN が正当であるか尋ねなければならない。3 方向ハンドシェ ークとクロック仕掛けのスキームの利点は、[3] で論じられる。 Knowing When to Keep Quiet TCP が、ネットワーク中に残っている古いセグメントと重複するかもしれな いシーケンス番号を運ぶセグメントを生成しないことを保証するために、 TCP は開始時か、使用するシーケンス番号のメモリが消去されるようなクラ ッシュからの回復時に、最大セグメント生存時間 (MSL: maximum segment lifetime) の間、何らかのシーケンス番号を割り当てる前に黙っていなけれ ばならない。この規約では、MSLは 2 分である。これは技術者による選択で あり、もし経験上望ましいのであれば変更してもよい。もし TCP がある理 由で再起動され、まだ使用するシーケンス番号のメモリが残っていたら、 TCP は全く待つ必要はなく、最も最近使用した番号よりも大きいシーケンス 番号を使用することのみ保証する。 The TCP Quiet Time Concept この規約では、各活性 (すなわち閉塞ではない) コネクション上で送信し た最後のシーケンス番号の知識を保持せずに "クラッシュ" したホストは、 少なくともホストが参加しているインターネットシステムで同意されてい る最大セグメント生存時間の間、TCP セグメントの発行を遅らせなければ ならない。以下の段落では、この規約の説明を行っている。TCP 実装者は "黙っている時間" の制限を冒してもよいが、インターネットシステム内 の受信側で古いデータが新しいデータとして受諾される、あるいは古いデ ータと重複したために新しいデータが拒否される危険性はある。 TCP は、セグメントが生成され、送信元ホスト側でネットワーク出力キュ ーに入力されるたびにシーケンス番号空間を消費する。TCP プロトコルに おける重複検出とシーケンス付けアルゴリズムは、これらのシーケンス番 号に割り当てられたセグメントデータが送信され、それが受信者によって 確認され、セグメントの重複した複製全てがインターネットから "排出" される前に、シーケンス番号は全ての 2**32 値を通して一回りしない範 囲で、セグメント空間にセグメントデータをユニークに割当てることに頼 る。この仮定がなければ、2 つの別個の TCP セグメントは恐らく同じか 重複したシーケンス番号を割り当てられ、どのデータが新しくてどのデー タが古いかについて受信側の混乱を引き起こすことになるだろう。各々の セグメントは、セグメントのデータオクテットが存在する限り、連続した シーケンス番号が割り当てられることを覚えておくこと。 通常の条件において、一番目に使用した番号が確認される前にシーケンス 番号が誤って使用されることを避けるために、TCP は発行する次のシーケ ンス番号と最も古い肯定応答待ちを記録しておく。これだけでは、古い重 複データがネットワークから排出されることを保証していない。従って、 さまよう重複データが到着したことによるトラブルの可能性を減らすため に、シーケンス空間がとても大きくなる。2 メガビット/秒の場合、シー ケンス空間の 2**32 オクテットを使用するのに 4.5 時間かかる。ネット ワーク中の最大セグメント生存時間は、2,30 数秒を超えることはないの で、たとえデータレートが 10 メガビット/秒に拡大されても、予測可能 なネットワークでは十分な防御であると考えられる。100 メガビット/秒 では、サイクル時間は 5.4 分で少し小さいが、依然として理由の範囲内 である。 しかし、もし送信元 TCP が与えられたコネクション上で最後に使用され たシーケンス番号を記憶していなければ、TCP の基本的な重複検出とシー ケンスアルゴリズムは駄目になる。例えば、もし TCP が全てのコネクショ ンをシーケンス番号 0 で開始し、クラッシュ/再起動が発生したら、TCP は前のコネクションを再生成し (恐らく半オープンコネクションの解決 後)、同一のシーケンス番号を持つか、同一コネクションの前の化身上に 発行されたネットワーク中のパケットと重複するパケットを発行する。特 定のコネクション上で使用されたシーケンス番号についての知識が無い場 合、TCP 規約は、前のコネクションの化身からのセグメントがシステムか ら排出されることを可能にするために、送信元がセグメントをコネクショ ン上に発行する前に MSL 秒間遅らせてることを推奨する。 時間を記憶できていて、それを初期シーケンス番号の値を選択するのに使 用しているホストであっても、この問題から免れるわけではない (たとえ 各々の新しいコネクションの化身に対して初期シーケンス番号を選択する のに時間を使用していても)。 例えば、コネクションがシーケンス番号 S で開始してオープンされると 仮定する。そして、このコネクションはあまり使用されず、結局初期シー ケンス番号関数の ISN(t) が、この TCP によって送信された最後のセグ メントと等しいシーケンス番号 (つまり S1) を取ると仮定する。さらに、 この瞬間ホストがクラッシュし、復旧し、そして新しいコネクションの化 身を確立するとする。選択される初期シーケンス番号は S1 = ISN(t)、古 いコネクション上の化身で最後に使用されたシーケンス番号である。もし 回復が十分すばやく発生すれば、S1 に近いシーケンス番号を運んでいる ネットワーク中で古い重複が到達し、新しいコネクションの化身の受信側 によって新しいパケットとして扱われる。 この問題は、回復したホストがどのくらいの間クラッシュしていたか、そ して前のコネクションの化身からシステム中にまだ古い重複データが残っ ているか否かが分からないということである。 この問題に対処する一つの方法は、クラッシュから回復した後、1 MSL の 間セグメントの発行を故意に遅らせることである。これが "黙っている時 間" の規約である。待つことを避けたいホストは、指定された受信側で新 旧のパケットが混在するかもしれない危険性を厭わず、"黙っている時間" の間待たないことを選択してもよい。実装者は TCP 利用者に、クラッシュ した後に待つか否かをコネクション毎に選択する能力を提供してもよいし、 全てのコネクションに対して非公式に "黙っている時間" を実装してもよ い。明らかに利用者が "待つ" ことを選択した場合であっても、少なくと も MSL 秒かかってホストが "立ち上がった" 後はこれは必要ない。 要約: 発行された全てのセグメントは、シーケンス空間における一つ以上 のシーケンス番号を占有し、セグメントによって占有された番号は MSL 秒経過するまで "ビジー" か "使用中"" となる。そしてクラッシュした 時、時空間のブロックは最後に発行されたセグメントのオクテットに占有 される。もし新しいコネクションが非常に早く開始され、前のコネクショ ンの化身の最終セグメントの時空間の足跡中のシーケンス番号を使用した ら、受信側が混乱するかもしれない潜在的なシーケンス番号の重複する領 域が存在する。 3.4. コネクション確立 "三方向ハンドシェーク" が、コネクションの確立で使用される手続きであ る。この手続きは通常、一方の TCP によって起動され、別の TCP によって 応答される。この手続きは、もし二つの TCP が同時に手続きを起動した場 合でも動作する。同時に手続きが発生した場合は、各々の TCP は "SYN" を 送信した後、肯定応答を乗せていない "SYN" セグメントを受信する。もち ろん古い重複した "SYN" セグメントの到達により、受信側に、同時のコネ クション起動が進行中であることが潜在的に表れるかもしれない。"リセッ ト" セグメントを適切に使用することによって、これらのケースの曖昧さを 無くすことができる。 コネクション起動の幾つかの例を以下に示す。これらの例は、データを運ぶ セグメントを使用したコネクション同期を示していないが、データの正当性 が明確になるまで受信側 TCP がデータを利用者に渡さない限り、これは完 全に合法的である。(すなわち、コネクションが ESTABLISHED 状態に到達す るまで、データは受信者側でバッファリングされる)。三方向ハンドシェー クは、誤ったコネクションの可能性を減らす。それは、このチェックの情報 を提供するためのメモリとメッセージのトレードオフの実装である。 最も簡単な三方向ハンドシェークは、以下の図 7 に示されている。図は次 のように解釈される。各行は、参照する目的で番号が付けられている。右矢 印 (-->)は、TCP A から TCP B への TCP セグメントの発行、あるいは B における A からのセグメント到着を示している。左矢印(<--)は、その逆を 示している。省略記号 (...) は、まだネットワークにある (遅れた) セグ メントを示している。"XXX" は、損失されたか拒否されたセグメントを示す。 コメントは括弧の中に示される。TCP 状態は、セグメントが発行/到達した 後の状態を表している (各行の中央に示される)。セグメントは略号形式と シーケンス番号、制御フラグ、ACK フィールドで示される。ウィンドウ、ア ドレス、長さ、テキスト等のフィールドは、明示する必要性に応じて示され る。 TCP A TCP B 1. CLOSED LISTEN 2. SYN-SENT --> --> SYN-RECEIVED 3. ESTABLISHED <-- <-- SYN-RECEIVED 4. ESTABLISHED --> --> ESTABLISHED 5. ESTABLISHED --> --> ESTABLISHED 図 7 -- 基本的なコネクション同期の三方向ハンドシェーク 図 7 の 2 行目では、シーケンス番号 100 で始まるシーケンス番号を使用 することを示す SYN セグメントを、TCP A が送信することによって開始し ている。3 行目では、TCP B が SYN と TCP A から受信した SYN の肯定応 答を送信している。肯定応答フィールドは、TCP B が現在、シーケンス 101 の受信を期待していて、シーケンス 100 を占有した SYN に肯定応答してい ることを示す。 5 行目では、TCP A はあるデータを送信している。5 行目のセグメントのシ ーケンス番号は、4 行目の番号と同じである。なぜなら、ACK はシーケンス 番号空間を占有しないからである (もし占有したら ACK の ACK で舞い上が ってしまう)。 図 8 では、若干複雑な同時起動が図示されている。各 TCP は、状態が CLOSED から SYN-SENT、SYN-RECEIVED、ESTABLISHED の順で循環する。 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 - 同時コネクション同期 三方向ハンドシェークを行う根本的な理由は、古い重複コネクション起動が 混乱を引き起こすことを防ぐことである。これを取り扱うために、特別な制 御メッセージ、リセットが考え出された。もし受信側 TCP が非同期状態 (SYN-SENT, SYN-RECEIVED) にいたら、受諾可能なリセットを受信すると、 LISTEN 状態に戻る。もし TCP が同期状態 (ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT) のどれかにいた ら、TCP はコネクションの異常切断を利用者に通知する。この後者のケース を、以下の "半オープン" コネクションのケースで論じる。 TCP A TCP B 1. CLOSED LISTEN 2. SYN-SENT --> ... 3. (duplicate) ... --> SYN-RECEIVED 4. SYN-SENT <-- <-- SYN-RECEIVED 5. SYN-SENT --> --> LISTEN 6. ... --> SYN-RECEIVED 7. SYN-SENT <-- <-- SYN-RECEIVED 8. ESTABLISHED --> --> ESTABLISHED 図 9 - 古い重複 SYN からの回復 古い重複 SYN からの回復の簡単な例として、図 9 を検証する。3 行目で、 古い重複 SYN が TCP B に到達する。TCP B はこれが古い重複したものであ ることは分からないので、通常通りに応答する。TCP A は ACK フィールド が不正であることを検出し、そのセグメントを信用させるために選択された SEQ フィールドを持つ RST (リセット) を返却する。TCP B は RST を受信 して、LISTEN 状態に戻る。6 行目で、元の SYN が最終的に到達し、同期処 理が通常通りに実行される。もし 6 行目の SYN が RST の前に到達したら、 両方向に RST が送信され、より複雑な交換が発生する。 半コネクションとその他の変則 もし 一方の終端の TCP が他方の状態を知らずにコネクションをクローズ/ アボートしたか、メモリ不足が原因で破棄されてしまったために二つのコネ クションの終端間で同期がとれていない場合、その確立中のコネクションは "半オープン" と呼ばれる。そのようなコネクションは、どちらかの方向に データが送信されたら自動的にリセットされる。しかし、半オープンコネク ションは、通常ではないと見なされ、回復手続きが緩やかに行われる。 もしサイト A でコネクションがもはや存在しなければ、サイト B のユーザ によるデータ送信の試みは、サイト B の TCP でリセットの制御メッセージ を受信する結果を招くだろう。そのようなメッセージは、何かが異常である ことをサイト B TCP に示し、コネクションをアボートすることが期待され る。 二つのユーザプロセス 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. (CRASH) (send 300,receive 100) 2. CLOSED ESTABLISHED 3. SYN-SENT --> --> (??) 4. (!!) <-- <-- ESTABLISHED 5. SYN-SENT --> --> (Abort!!) 6. SYN-SENT CLOSED 7. SYN-SENT --> --> 図 10 - 半オープンコネクション検出 3 行目で SYN が到達した時、TCP B は同期状態にいて、ウィンドウ外の受 信セグメントに対して、次に期待するのは何のシーケンスか (ACK 100) を 示す肯定応答で応答する。TCP A は、このセグメントが自分が送信たしもの を何も確認しておらず同期していないことが分かり、半オープンコネクショ ンを検出したことから、リセット (RST) を送信する。TCP B は、5 行目で アボートする。TCP A は、コネクションの確立を続けて試みるだろう。そし て、図 7 の基本的な 3 方向ハンドシェークにより、その問題は減少する。 興味深い別のケースは、TCP A がクラッシュし、TCP B が同期がとれている と思っているコネクション上でデータ送信を試みる時発生する。このケース は、図 11で図示されている。この場合、TCP B から TCP A 到達したデータ (2 行目) は、もはやそのコネクションは存在しないので制御不可である。 よって、TCP A は RST を送信する。その RST は受信できるので、TCP B は それを処理しコネクションをアボートする。 TCP A TCP B 1. (CRASH) (send 300,receive 100) 2. (??) <-- <-- ESTABLISHED 3. --> --> (ABORT!!) 図 11 - 活性側による半オープンコネクションの回復 図 12 では、SYN を待っている受動的コネクションでの 2 つの TCP A と B について見る。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. --> --> (return to LISTEN!) 5. LISTEN LISTEN 図 12 - 古い重複 SYN が 2 つの受動ソケット上でリセットを起動する。 様々な他のケースも起り得る。それらの全ては、RST 生成/処理に関する以 下の規則によって説明される。 Reset Generation 一般規則として、現在のコネクション上で明らかに意図されていないセグメ ントが到達した時は、常にリセット (RST) を送信しなければならない。こ れがそのケースであることが明確でないならば、リセットを送信してはなら ない。 その状態には 3 つのグループがある。 1. もしコネクションが存在しなければ (CLOSED)、別のリセットを除く全 ての入力セグメントに対する応答でリセットが送信される。特に、存在し ないコネクションにアドレス付けられた SYN は、この手段によって拒否 される。 もし、入力セグメントが ACK フィールドを持っていたら、リセットはそ のセグメン もし、入力セグメントが ACK フィールドを持っていたら、 リセットはそのセグメントの ACK フィールドをシーケンス番号に指定す る。入力セグメントが ACK フィールドを持っていなければ、リセットは シーケンス番号 0 を指定し、受信したセグメントのシーケンス番号とセ グメント長の合計をリセットの ACK フィールドに設定する。コネクショ ンは CLOSED 状態のままである。 2. もしコネクションが非同期状態 (LISTEN, SYN-SENT, SYN-RECEIVED) であり、入力セグメントが、まだ送信していないものを確認していたら (セグメントが受諾できない ACK を運んだ)、あるいは入力セグメントが、 そのコネクションで要求されたセキュリティレベルやコンパートメントと 正確に一致しないセキュリティレベルやコンパートメントを持っていたら、 リセットが送信される。 もしまだ SYN が確認されておらず、入力セグメントの優先度レベルが要 求された優先度レベルよりも高いならば、自側の優先度レベル (利用者と システムで可能なら) を上げるか、リセットを送信するかのいずれかを行 う。また、入力セグメントの優先度レベルが要求された優先度レベルより も低いならば、正確に一致する優先度であるものとして継続する (もし、 リモートの TCP が一致する優先度レベルに上げることができないなら、 次のセグメントでこれが検出され、そのコネクションは終了するだろう)。 もし SYN が確認されたら (おそらくこの入力セグメントで)、入力セグメ ントの優先度レベルは自側の優先度レベルと正確に一致しなければならな い。さもなくば、リセットを送信しなければならない。 もし、入力セグメントが ACK フィールドを持っていたら、リセットはそ のセグメントの ACK フィールドをシーケンス番号に指定する。入力セグ メントが ACK フィールドを持っていなければ、リセットはシーケンス番 号 0 を指定し、受信したセグメントのシーケンス番号とセグメント長の 合計をリセットの ACK フィールドに設定する。コネクションは同じ状態 のままである。 3. もしコネクションが同期状態 (ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT) ならば、受諾できないセグ メント (ウィンドウ外のシーケンス番号か受諾できない確認番号) は、現 在の送信シーケンス番号と、次に受信を期待するシーケンス番号を示す肯 定応答を含んでいる空の肯定応答セグメントしか出してはならないそして、 コネクションは同じ状態のままである。 もし入力セグメントが、コネクションで要求されたレベルやコンパートメ ントや優先度と正確に一致しないセキュリティレベルやコンパートメント や優先度を持っていたら、リセットが送信され、コネクションは CLOSED 状態に遷移する。そのリセットは、入力セグメントの ACK フィールドを シーケンス番号に指定する。 Reset Processing SYN-SENT を除く全ての状態で、全てのリセット (RST) セグメントはそのシ ーケンスフィールドによって評価される。リセットは、もしそのシーケンス 番号がウィンドウ内であれば正しい。SYN-SENT 状態 (最初の SYN の応答で 受信した RST) では、RST は、ACK フィールドが SYN を確認していれば受 諾できる。 RST の受信側は最初にこれを評価し、そして状態を遷移させる。もし受信側 が LISTEN 状態ならば、これを無視する。もし受信側が SYN-RECEIVED 状態 で、その前が LISTEN 状態だったならば、受信側は LISTEN 状態に戻る。さ もなくば、受信側はコネクションをアボートし、CLOSED 状態に遷移する。 受信側がその他の状態ならば、そのコネクションをアボートして利用者に通 達し、CLOSED 状態に遷移する。 3.5. コネクション解放 CLOSE の処理上の意味は、"私はもう送信するデータがありません" である。 全二重コネクションをクローズする考えは、コネクションの受信側の扱い方 がもちろん明確でないため、曖昧な解釈に陥りやすい。我々は単純なやり方 を選択した。CLOSE したユーザは、相手側も CLOSED したということが通知 されるまで RECEIVE し続けてよい。つまり、プログラムは幾つかの SEND に続いて CLOSE を発行でき、そして相手側が CLOSE したことにより RECEIVE が失敗したと通知されるまで、RECEIVE を継続できる。たとえ未処 理の RECEIVE が存在しなくても、相手側がクローズしたことを TCP はユー ザに通知すると仮定する。それによって、ユーザは自側をすんなり終了でき る。コネクションが CLOSED される前に、TCP は SEND された全てのバッファ を確実に配送するので、返却されるデータが無いことを期待するユーザは、 自側の全てのデータが宛先の TCP で受信されたことを知るために、コネク ションが正常に CLOSED されるのを待つだけでよい。ユーザは、TCP がもう データが無いと言うまで、送信をクローズしたコネクションを読み込み続け なければならない。 基本的に三つのケースが存在する。 1) ユーザが、TCP にコネクションの CLOSE を告げることによって起動す る。 2) リモートの TCP が、FIN 制御シグナルを送信することによって起動す る。 3) 両方のユーザが同時に CLOSE する。 Case 1: ローカルユーザがクローズを起動する。 この場合、FIN セグメントが作成され、出力セグメントキューに置かれる。 以降のユーザからの SEND を TCP は受諾せず、FIN-WAIT-1 状態に入る。 RECEIVE はこの状態では許される。FIN を含む先行する全てのセグメント は、確認されるまで再送される。相手側 TCP が FIN を確認し、自分自身 の FIN を送信した時、起動側 TCP はこの FIN に ACK を送信することが できる。FIN を受信した TCP は ACK は送信するが、さらにユーザがコネ クションを CLOSE するまで自身の FIN は送信しないだろう。 Case 2: TCP がネットワークから FIN を受信する。 もし求められていない FIN がネットワークから到着したら、受信側 TCP はその ACK を送信し、ユーザにコネクションがクローズされていること を通知できる。ユーザは CLOSE で応えるだろう。そして TCP は残りの全 てのデータを送信した後で、相手側 TCP に FIN を送信することができる。 その後 TCP は自分の FIN が確認されるまで待ち、確認されたらコネクショ ンを削除する。もし ACK が来なければ、ユーザタイムアウト後にそのコ ネクションがアボートされ、ユーザに通知される。 Case 3: 両方のユーザが同時にクローズする。 コネクションの両端のユーザによる同時 CLOSE は、FIN セグメントの交 換を引き起こす。FIN より前に送信された全てのセグメントが処理され確 認された時、各々の TCP は受信した FIN に対して ACK を送信すること ができる。両側の TCP はこれらの ACK を受信後、コネクションを削除す る。 TCP A TCP B 1. ESTABLISHED ESTABLISHED 2. (Close) FIN-WAIT-1 --> --> CLOSE-WAIT 3. FIN-WAIT-2 <-- <-- CLOSE-WAIT 4. (Close) TIME-WAIT <-- <-- LAST-ACK 5. TIME-WAIT --> --> CLOSED 6. (2 MSL) CLOSED Normal Close Sequence Figure 13. TCP A TCP B 1. ESTABLISHED ESTABLISHED 2. (Close) (Close) FIN-WAIT-1 --> ... FIN-WAIT-1 <-- <-- ... --> 3. CLOSING --> ... CLOSING <-- <-- ... --> 4. TIME-WAIT TIME-WAIT (2 MSL) (2 MSL) CLOSED CLOSED Simultaneous Close Sequence Figure 14. 3.6. 優先度とセキュリティ 意図は、全く同じセキュリティとコンパートメント値か、二つのポートによ って要求された優先度レベルより上位で処理するポート間しかコネクション を許可しないということである。 TCP で使用される優先度とセキュリティパラメタは、インターネットプロト コル (IP)[2] で定義されたものと全く同じである。この TCP の規定を通し て、"セキュリティ/コンパートメント" は IP で使用されるセキュリティパ ラメタを示すことを意図しており、セキュリティ、コンパートメント、ユー ザグループ、制限操作を含む、 一致しないセキュリティ/コンパートメント値か、より低い優先度の値で試 みられたコネクションは、リセットを送信することによって拒否しなければ ならない。優先度が低いためにコネクションが拒否されるケースは、SYN の 肯定応答を受信した後にのみ発生する。 注記: 優先度の値としてデフォルト値のみを扱う TCP モジュールも、入力 セグメントの優先度をチェックして、場合によってはそのコネクションで使 用する優先度レベルを上げなければならない。 セキュリティパラメタは、非セキュリティ環境であっても使用してよい (そ の値は機密扱いを受けないデータを示すだろう)。従って、非セキュリティ 環境にあるホストは、送信する必要が無くともセキュリティパラメタを受信 する準備ができていなければならない。 3.7. データ通信 一旦コネクションが確立されたら、セグメントの交換によってデータが通信 される。セグメントはエラー (チェックサムテストの失敗) やネットワーク 輻輳によって損失するかもしれないので、TCP は全てのセグメントの配送を 保証するために再送 (タイムアウトした後) を使用する。シーケンス番号の セクションで論じたように、TCP は受諾可能かを確かめるために、セグメン ト中のシーケンスと確認番号のチェックを実行する。 データの送信側は、使用する次のシーケンス番号を変数 SND.NXT に保持す る。データの受信側は、期待している次のシーケンス番号を変数 RCV.NXT に保持する。データの送信側は、最も古い未確認のシーケンス番号を変数 SND.UNA に保持する。もしデータフローが少しの間アイドルで、送信した全 てのデータが確認されていたら、これら三つの変数は等しい値であるだろう。 送信側がセグメントを生成し送信する時、送信側は SND.NXT を加算する。 受信側はセグメントを受信した時、RCN.NXT を加算して肯定応答を送信する。 データの送信側が肯定応答を受信した時、SND.UNA を加算する。これらの変 数の値が異なる範囲は、通信の遅延の大きさである。変数が加算される量は セグメントのデータ長さである。一旦 ESTABLISHED 状態になったら、全て のセグメントで現在の確認情報を運ばなければならない。 CLOSE のユーザ呼び出しは入力セグメントに FIN 制御フラグを立てるので、 プッシュ機能を暗黙的に意味している。 再送タイムアウト 相互接続システムを構成するネットワークの多様性や、TCP コネクションは 広範囲に渡って使用されるため、再送タイムアウトは動的に決定しなければ ならない。再送タイムアウトを決定するための一つの手続きを以下に例示す る。 再送タイムアウト手続きの例 特定のシーケンス番号を持つオクテットの送信と、そのシーケンス番号 をカバーする肯定応答の受信 (送信されたセグメントが受信されたセグ メントと一致する必要はない) の間に経過した時間を計測する。この計 測された経過時間は、ラウンドトリップタイム (RTT: Round Trip Time) である。次に、スムーズドラウンドトリップ (SRTT: Smoothed Round Trip Time) を以下のように計算する。 SRTT = ( ALPHA * SRTT ) + ((1-ALPHA) * RTT) これに基づいて、再送タイムアウト (RTO: retransmission timeout) を以下のように計算する。 RTO = min[UBOUND,max[LBOUND,(BETA*SRTT)]] UBOUND はタイムアウトの上位境界 (例えば 1 分) で、LBOUND はタイ ムアウトの下位境界 (例えば 1 秒) で、ALPHA はスムージング要素 (例えば .8 〜 .9 )で、BETA は遅延の可変要素 (例えば 1.3 〜 2.0) である。 緊急情報の通信 TCP 緊急メカニズムの目的は、送信側ユーザが受信側ユーザに緊急データの 受信を促すことを可能にし、受信側 TCP が、現在認識されている全ての緊 急データがユーザによっていつ受信されたかを、受信側ユーザに示すことを 許すことである。 このメカニズムは、データストリーム中の点を緊急情報の最後として示すこ とを可能にする。この点が、受信側 TCP において受信シーケンス番号 (RCV.NXT) の前にある場合は常に、その TCP はユーザに "緊急モード" に 入ることを通知しなければならない。受信シーケンス番号が緊急ポインタよ り先へ行った場合、TCP はユーザに "通常モード" に入ることを通知しなけ ればならない。ユーザが "緊急モード" にある間に緊急ポインタが更新され ても、その更新はユーザには見えないだろう。 この方法は、送信される全てのセグメント内で運ばれる緊急フィールドを用 いる。URG 制御フラグは、緊急フィールドに意味があり、緊急ポインタを生 成するためにセグメントシーケンス番号を追加しなければならないことを示 す。このフラグが無いことは、未処理の緊急データが存在しないことを示す。 また、緊急指示を送信するために、ユーザは少なくとも 1 オクテットは送 信しなければならない。もし、送信側ユーザがさらに push を指示したら、 宛先プロセスへの緊急情報の適時の配送は増やされる。 ウィンドウ管理 各々のセグメントで送信されるウィンドウは、ウィンドウの送信側 (データ の受信側) が現在受信できるシーケンス番号の範囲を示す。これは、このコ ネクションで現在利用可能なデータバッファ空間に関連するものと想定され る。 大きなウィンドウを示すことは、転送を励行する。もし、受信できる以上の データが到達したら、それらは破棄されるだろう。結果として過度の再送が 発生し、ネットワークと TCP に不要な負荷が増える。小さいウィンドウを 示すことは、送信される各々の新たなセグメント間のラウンドトリップ遅延 を導入しているポイントに、データの送信を制限するかもしれない。 提供されるメカニズムにより、TCP は大きいウィンドウを通知し、続いてそ の多くのデータを受信せずに、ずっとより小さいウィンドウを通知すること が可能である。このいわゆる "ウィンドウ縮小" は、使用しないことが強く 推奨される。頑強さの原理は、TCP がウィンドウ自体を縮小せず、他の TCP の部分でそのような動作を準備するよう命じている。 送信側 TCP は、ユーザからの受信を準備し、たとえ送信ウィンドウが 0 で あっても新たなデータのうち少なくとも 1 オクテットは送信できなければ ならない。送信側 TCP はウィンドウが 0 である時も、受信側 TCP に定期 的に再送しなければならない。ウィンドウが 0 である時の再送間隔は 2 分 とすることが推奨される。この再送は、どちらかの TCP が 0 ウィンドウに なった時、ウィンドウの再開が確実に相手側に通知されることを保証するた めに重要である。 受信側 TCP が 0 ウィンドウになってセグメントが到着した場合でも、次の 期待するシーケンス番号と現在のウィンドウ (0) を示す肯定応答を送信し なければならない。 送信側 TCP は、送信データを現在のウィンドウに収まるセグメントに詰め 込み、再送キュー上のセグメントを再度詰め込んでもよい。そうした再詰め 込みは必須ではないが、効果的かもしれない。 一方向のデータコネクションフローでは、ウィンドウ情報は肯定応答セグメ ントで運ばれるだろう。全て同じシーケンス番号を持つので、もしそれらが 順番通りに到着しなかったら、再順序付けする方法はない。これは重大な問 題ではないが、ウィンドウ情報が稀に一時的にデータの受信側からの古い通 知に基づくことがあり得る。この問題を避けるための改善事項は、最も大き い確認番号 (それは、以前に受信した最も大きい番号と等しいか、より大き い確認番号を持ったセグメントである) を運ぶセグメントから得られるウィ ンドウ情報を扱うことである。 ウィンドウ管理手続きは、通信パフォーマンスに対し重要な影響を持つ。以 下のコメントは、実装者に向けての提案である。 ウィンドウ管理の提案 非常に小さいウィンドウを割り当てることによって、より良いパフォー マンスは数少ない大きなセグメントを使用して達成される時に、小さい セグメントが数多く送信されることになる 小さいウィンドウを避けるための提案は、追加割当てがそのコネクショ ンで可能な最大割当ての少なくとも X パーセント (X は 20〜40 位) になるまで、受信側がウィンドウの更新を遅らせることである。 別の提案は、送信側がデータを送信する前にウィンドウが十分大きくな るのを待つことによって、小さいセグメントの送信を避けることである。 もしユーザが push 機能を通知したら、たとえ小さいセグメントであっ てもそのデータを送信しなければならない。 肯定応答は遅延すべきでないことに注意されたい。さもないと不必要な 再送が結果として起きるだろう。一つの戦略は、小さいセグメントが到 着した時に肯定応答を送信し (ウィンドウ情報を更新しない)、その後 でウィンドウが大きくなった時に、新しいウィンドウ情報を持った別の 肯定応答を送信することである。 0 ウィンドウを調べるために送信されるセグメントも、送信データを次 第に小さいセグメントに分割し始めるかもしれない。もし 0 ウィンド ウを調べるために送信された 1 データオクテットを含むセグメントを 受信したら、現在使用可能なウィンドウのうち 1 オクテットを消費す る。もし送信側 TCP が、ウィンドウが 0 でない時は常に送信可能な大 きさで単に送信するだけならば、送信されるデータは大きいセグメント と小さいセグメントに交互に分割されるだろう。時間が経過するにつれ て、受信側がウィンドウ割当てを可能にするために時々停止することに よって、大きなセグメントは小さいセグメントとさほど大きくないセグ メントのペアに分割されるだろう。しばらくすると、データ転送はほと んど小さいセグメントになるだろう。 ここでの提案は、TCP 実装が小さいウィンドウ割当てをより大きなウィ ンドウに結合することを積極的に試みる必要があるということである。 なぜなら、ウィンドウ管理のメカニズムは、最も単純な考えによる実装 では数多くの小さいウィンドウを招く傾向にあるからである。 3.8. インタフェース もちろん、考慮すべきインタフェースは二つある。それは、ユーザ/TCP イ ンタフェースと TCP/下位レベルインタフェースである。我々は、ユーザ/ TCP インタフェースのモデルを公正に作成したが、下位レベルプロトコルモ ジュールとのインタフェースは、下位層プロトコルの規定によって詳細に規 定されるので、ここでは未規定のままである。下位レベルが IP である場合、 TCP が使用してもよいパラメタ値の幾つかを注記する。 ユーザ/TCP インタフェース あらゆるオペレーティングシステムは異なる機能を持つだろうから、以下 の TCP へのユーザコマンドの機能的な説明はせいぜい虚構である。つま り、異なる TCP 実装は異なるユーザインタフェースを持つかもしれない ことを、読者は注意しなければならない。しかしあらゆる TCP は、あら ゆる TCP 実装が同じプロトコル階層をサポートできることを保証するた めに、ある最小限のサービスのセットを提供しなければならない。 TCP ユーザコマンド 以下のセクションは、ユーザ/TCP インタフェースを機能的に特徴付け る。使用される記法は高級言語の大半の手続きや関数コールと同様であ るが、この使用方法はトラップタイプのサービスコール (例えば SVC, UUO, EMT 等) を無視することは意図していない。 以下で説明されるユーザコマンドは、TCP が相互プロセス通信をサポー トするために実現しなければならない基本的な機能を規定する。個々の 実装では、自身の正確な形式を定義しなければならず、基本的な機能の 結合、あるいはサブセットを単一のコールで提供してもよい。特にある 実装は、付与されたコネクション上にユーザによって発行された一番最 初の SEND か RECEIVE で、自動的にコネクションを OPEN したいと望 むかもしれない。 相互プロセス通信機能を提供する際、TCP はコマンドを受諾しなければ ならないだけでなく、サービスを提供しているプロセスに情報を返却も しなければならない。後者は以下のものから構成される。 (a) コネクションについての一般的な情報 (中断、遠隔クローズ、未 指定の相手側ソケットのバインド等) (b) 指定されたユーザコマンドへの応答で、成功したか失敗した様々 なタイプ Open Format: OPEN (自側ポート, 相手側ソケット, 送信用/受信用 [, タイムアウト] [, 優先度] [, セキュリティ/コンパートメント] [, オプション]) -> 自側コネクション名 自側 TCP はサービスを提供するプロセスの身元を知っていて、指定 されたコネクションを使用するプロセスの権限をチェックするものと 仮定する。TCP の実装に依存して、自側ネットワークと送信元アドレ スの TCP 識別子が、TCP か下位レベルプロトコル (例えば IP) のど ちらかによって供給される。これらの考慮は、TCP が別のものに見せ かけることができない等の範囲でセキュリティを配慮した結果である。 同様にプロセスも、TCP と共謀することなく別のプロセスとして見せ かけることはできない。 もし、能動/受動フラグが受動に設定されたら、これは入力コネクショ ンに対する LISTEN のコールである。受動オープンは相手側ソケット を完全に指定して特定のコネクションを待ってもよいし、相手側ソケ ットを指定せずにあらゆるコールを待ってもよい。完全に指定した受 動呼び出しは、後で SEND を実行することによって能動にすることが できる。 転送制御ブロック (TCB: transmission control block) が生成され、 OPEN コマンドパラメタからのデータで部分的に満たされる。 能動的 OPEN コマンドでは、TCP はすぐにコネクションを同期するた めの手続き (すなわち確立) を開始するだろう。 タイムアウトは、もし提供されていれば、TCP に渡される全てのデー タに対するタイムアウトを、呼び出し元が設定できる。もしデータが タイムアウト期間内に正常に宛先に送信されなければ、TCP はコネク ションをアボートするだろう。当面の一般的なデフォルト値は 5 分 である。 オペレーティングシステムの TCP かコンポーネントは、指定された 優先度やセキュリティ/コンパートメントによって、コネクションを オープンするためのユーザの権限を確かめるだろう。OPEN コールに 優先度やセキュリティ/コンパートメントの指定が省略されていたら、 デフォルト値を使用しなければならない。 TCP は、OPEN コールで要求されたセキュリティ/コンパートメント情 報と全く同一である場合に限り、そして優先度が等しいか高い場合に 限り、入力要求を一致したものとして受諾するだろう。 コネクションの優先度は OPEN コールで要求された値と入力要求から 受信した値のうち、より高い値をとり、コネクションが生存中はその 値で固定される。実装者は、この優先度折衝のユーザによる制御を提 供したいかもしれない。例えば、優先度は正確に一致しなければなら ないことや、優先度を上げる如何なる試みもユーザによって確認され ることを、ユーザによって指定可能にしてもよい。 ローカルコネクション名は、TCP によってユーザに返却されるだろう。 そして、ローカルコネクション名は <自側ソケット、相手側ソケット> のペアによって定義されたコネクションを、短かい用語として使用す ることができる。 Send Format: SEND (ローカルコネクション名, バッファアドレス、 バイト数, PUSHフラグ, URGENTフラグ [,タイムアウト]) このコールは、指定されたユーザバッファに含まれるデータを、指定 されたコネクション上に送信する。もしコネクションがオープンされ ていなければ、SEND はエラーと見なされる。ある実装はユーザが最 初に SEND することを許すかもしれない。その場合、自動的に OPEN が実行される。もし呼び出し元プロセスがこのコネクションを使用す る権限がないならば、エラーが返却される。 もし PUSH フラグが設定されたならば、データは受信側に即座に送信 しなければならず、バッファから生成される TCP セグメントの最後 に PUSH ビットが設定される。もし PUSH フラグが設定されなければ、 データは転送効率を踏まえて後続する SEND からのデータと結合して もよい。 もし URGENT フラグが設定されたならば、宛先 TCP に送信されたセ グメントは緊急ポインタが設定される。もし、緊急ポインタより前の データが受信側プロセスによって受け尽くされていないことを緊急ポ インタが示しているならば、受信側 TCP は緊急状態を受信側プロセ スに通知する。緊急の目的は緊急データの処理を受信側に促し、現在 認識している全ての緊急データがいつ受信されたのかを受信側に示す ことである。送信側ユーザの TCP が緊急を通知する回数は、受信側 ユーザが緊急データの存在を通知される回数と必ずしも等しいとは限 らない。 もし、OPEN で相手側のソケットが指定されず、コネクションが確立 されたならば (LISTEN 中のコネクションは、相手側のセグメントが ローカルソケットに到着して特定される)、明示的に指定されたバッ ファが暗黙的な相手側ソケットに送信される。相手側ソケットを指定 せずに OPEN を使用したユーザは、相手側のソケットアドレスが明確 に分からなくても SEND を使用できる。 しかし、もし相手側ソケットが特定される前に SEND が試みられたら も、エラーが返却されるだろう。ユーザは、コネクションの状態を決 定するために STATUS コールを使用することができる。ある実装では、 未指定のソケットがバインドされたときに、TCP がユーザに通知する かもしれない。 もし、タイムアウトが指定されたら、そのコネクションでの現在のユ ーザタイムアウトは新しい値に変更される。 最も単純な実装では、SEND は送信が完了するかタイムアウトが満了 するまで、送信プロセスに制御が戻らないだろう。しかしこの簡単な 方法では、両者がデッドロックを招きやすく (例えばコネクションの 両側が RECEIVE を実行する前に SEND を試みるといった場合)、パフォ ーマンスが貧弱となる。よって、それは推奨されない。より洗練され た実装では、ネットワーク I/O と同時に動作することを可能にし、 さらに複数の SEND の処理を可能にするために、即座に戻るかもしれ ない。複数の SEND は最初に来たものを最初に扱うので、TCP は即座 には処理できないものをキューイングするだろう。 SEND が TCP からある種のシグナルや擬似割り込みを後で誘発するよ うな、非同期のユーザインタフェースを暗黙的に想定している。代替 手段は応答を即座に返却することである。例えば、送信されたセグメ ントが相手側の TCP によって確認されていなくても、SEND は即座に ローカルな肯定応答を返却してもよい。最終的には成功するものと楽 観的に仮定する。もし間違っていたら、とにかくコネクションをタイ ムアウトによってクローズさせる。この種の (同期の) 実装では、依 然として非同期のシグナルが存在するかもしれないが、これらはコネ クション自身を取り扱い、特定のセグメントやバッファは扱わないだ ろう。 異なる SEND に対して、エラーの指示か成功の指示かをプロセスが区 別するために、SEND 要求に対する応答コードと共にバッファアドレ スを返却することは適切である。TCP からユーザへのシグナルは後述 するが、そこで呼び出し元のプロセスに返却すべき情報について記述 している。 Receive Format: RECEIVE (ローカルコネクション名, バッファアドレス、 バイト数) -> バイト数, 緊急フラグ, pushフラグ このコマンドは、指定されたコネクションに結びついた受信バッファ を割り当てる。もしOPEN がこのコマンドの前に実行されていないか、 呼び出し元プロセスがこのコネクションを使用する権限を持っていな いならば、エラーが返却される。 最も単純な実装では、バッファが埋まるかエラーが発生するまで、呼 び出し元プロセスに制御が戻らないだろう。しかし、この方法ではデ ッドロックを招く可能性が極めて高い。より洗練された実装では、複 数の RECEIVE を同時に未処理にすることが可能であるかもしれない。 これらはセグメントが到着したときに埋められる。この戦略により、 PUSH が検出されたかあるいはバッファが埋まったことを呼び出し元 のプログラムに通知するために、より精巧なスキーム (恐らく非同 期) を提供することによって、スループットの増加を可能にする。 もし、PUSH を検出する前にバッファが十分埋まる程のデータが到着 したら、RECEIVE の応答で PUSH フラグは設定されない。バッファは 保持できるだけのデータで埋められるだろう。もしバッファが一杯に なる前に PUSH フラグを検出したら、一部埋まったバッファが返却さ れ、PUSH が指示されるだろう。 もし緊急データが存在すれば、ユーザはデータが到着するとすぐに、 TCP からユーザへのシグナルによって通知されるだろう。その場合受 信側ユーザは "緊急モード" に入らなければならない。もし URGENT フラグが設定されていれば、追加の緊急データが残っている。もし URGENT フラグが設定されていなければ、この RECEIVE 呼び出しは全 ての緊急データの返却が完了しており、ユーザは "緊急モード" から 抜ける。もしユーザに境界が明示されないならば、緊急ポインタに続 くデータ (非緊急データ) は、前にある緊急データと同じバッファで はユーザに渡すことができないことに注意されたい。 複数の未処理の RECEIVE を区別し、バッファが完全に埋まらないケ ースに注意するために、戻り値はバッファポインタと受信したデータ の実際の長さを示すバイト数の両方を併うべきである。 RECEIVE の代替の実装は、TCP に格納バッファを割り当てるさせるか、 TCP がリングバッファをユーザと共有することである。 Close Format: CLOSE (ローカルコネクション名) このコマンドは、指定されたコネクションをクローズする。もしコネ クションがオープンされていないか、呼び出し元プロセスがこのコネ クションを使用する権限を持っていないならば、エラーが返却される。 コネクションのクローズは、フロー制御が許すように、全てのデータ がサービスされるまで未処理の SEND は送信される (再送される) と いう意味で、上品な操作であることを意図している。従って、CLOSE の前の複数の SEND 呼び出しは受諾可能であるべきであり、全てのデ ータが相手に送信されることが期待される。また、相手がデータの最 後を送信しようとしているかもしれないので、ユーザが CLOSING の コネクション上で RECEIVE を継続すべきであることは明白である。 つまり、CLOSE は "私はもう送信するものが無い" ことを意味するが、 "私はもう受信しません" という意味ではない。クローズ中の側がタ イムアウト前に全てのデータを取り除くことができないことは有り得 る (もしユーザレベルのプロトコルがうまく考慮していなければ)。 この場合、CLOSE は ABORT に変化し、クローズ中の TCPは諦める。 ユーザは、いかなる時にも自分が先導してコネクションを CLOSE し てよい。あるいは、TCP からの様々な促し (例えば、相手側でクロー ズ実行、送信タイムアウトの満了、宛先がアクセス不能) に対する応 答で CLOSE してよい。 コネクションのクローズは相手 TCP との通信を必要とするので、コ ネクションは短い間クローズ中状態に留まる。TCP が CLOSE コマン ドに返答する前にコネクションを再度オープンする試みは、エラー応 答が結果として返るだろう。 クローズは、プッシュ機能も暗黙的に意味する。 Status Format: STATUS (ローカルコネクション名) -> 状態データ これはユーザコマンドに依存する実装であり、逆効果なく除外できる。 返却される情報は通常、コネクションに結びついた TCB から得られ る。 このコマンドは、以下の情報を含むデータブロックを返却する。 自側ソケット 相手側ソケット 自側コネクション名 受信ウィンドウ 送信ウィンドウ コネクション状態 肯定応答を待っているバッファ数 受信をペンディングしているバッファ数 緊急状態 優先度 セキュリティ/コンパートメント 送信タイムアウト コネクションの状態によって、あるいは実装自身によって、この情報 の幾つかは利用できないか意味を持たないかもしれない。呼び出し元 プロセスがこのコネクションを使用する権限を持っていないならば、 エラーが返却される。これは、権限を持たないプロセスがコネクショ ンに関する情報を取得することを防ぐ。 Abort Format: ABORT (local connection name) このコマンドは、全てのペンディング中の SEND と RECEIVE をアボ ートさせ、TCB を消去し、特殊な RESET メッセージをコネクション の相手側の TCP に向けて送信させる。実装によっては、ユーザは各 々の未処理の SEND や RECEIVE に対してアボート指示を受信するか もしれないし、あるいは単にアボート確認を受信するかもしれない。 TCP ユーザメッセージ TCP がユーザプログラムに非同期にシグナルを送る手段は、オペレーティ ングシステム環境が提供するものと想定する。TCP がユーザプログラム にシグナルを送る時、ある情報がユーザに渡される。この規約でしばし ば出てきているが、その情報とはエラーメッセージである。その他のケ ースとしては、SEND や RECEIVE や他のユーザ呼び出しの処理が完了し たことに関連する情報だろう。 以下の情報が提供される。 ローカルコネクション名 常に 応答文字列 常に バッファアドレス Send と Receive バッファ数 (受信したバイト数) Receive プッシュフラグ Receive 緊急フラグ Receive TCP/下位レベルインタフェース TCP は、ネットワーク上の情報を実際に送受信するために、下位レベルの プロトコルモジュールを呼ぶ。一つのケースは、下位レベルのモジュール がインターネットプロトコル (IP)[2]である、ARPA 相互接続システムの ものである。 もし下位レベルプロトコルが IP ならば、TCP はサービスタイプと生存時 間のアーギュメントを提供する。TCP は、これらのパラメタのために以下 の設定を使用する。 サービスタイプ = 優先度: 通常. 遅延: 通常, 信頼性: 通常、または 00000000 生存時間 = 1 分、または 00111100 想定される最大セグメント生存時間は 2 分であることに注意された い。上記は、もしインターネットシステムによって 1 分以内に配送 されなければ、セグメントが破棄されることを明示的に依頼している。 もし下位レベルが IP (またはこの機能を提供する他のプロトコル) で、 送信元ルーティングが使用されるならば、そのインタフェースは経路情報 の伝達を可能にしなければならない。TCP チェックサムで使用される送信 元と宛先のアドレスは、起動した送信元と最終的な宛先なので、これは特 に重要である。コネクション要求に応えるための返却経路を維持するため にも重要である。 如何なる下位レベルのプロトコルも、IP と機能的に同等なサービスを提 供することと、TCP チェックサムで使用することの両方のために、送信元 アドレス、宛先アドレス、プロトコルフィールド、"TCP 長" を決定する ための方法を提供しなければならない。 3.9. イベント処理 このセクションで述べられた処理は、一つの有り得る実装の例である。他の 実装は、若干異なる処理シーケンスを持つかもしれないが、それらはこのセ クションの要旨ではなく、細かな点についてのみ異なるべきである。 TCP の動作は、イベントに対する応答として特徴づけることができる。発生 するイベントは、三つのカテゴリに分類できる。それは、ユーザ呼び出し、 セグメント到着、タイムアウトである。このセクションは、各々のイベント に対する応答で TCP が実行する処理について記述している。多くの場合、 必要な処理はコネクションの状態に依存する。 発生イベント: ユーザ呼び出し OPEN SEND RECEIVE CLOSE ABORT STATUS セグメント到着 SEGMENT ARRIVES タイムアウト USER TIMEOUT RETRANSMISSION TIMEOUT TIME-WAIT TIMEOUT TCP/ユーザインタフェースのモデルは、ユーザコマンドが即座の返却を受け たり、イベントか擬似割り込みを経て遅れて応答を受けることである。以下 の説明では、"シグナル" という言葉は遅れた応答の起因を意味する。 エラー応答は文字列として与えられる。例えば、存在しないコネクションを 参照しようとしたユーザコマンドは、"エラー: コネクションがオープンさ れていない" を受信する。 以下のシーケンス番号や確認番号、ウィンドウ等の全ての数値演算は、モジュ ロ 2**32 のシーケンス番号空間のサイズであることに注意されたい。また、 "=<"は、(モジュロ2**32) より小さいか等しいことを意味する。 セグメント受信の処理について考える際の自然な方法は、適切なシーケンス 番号であるか(つまり、その内容がシーケンス番号空間において期待した "受信ウィンドウ" の範囲内にあるか) が最初にテストされ、そして通常は それらがキューイングされて、シーケンス番号の順番で処理されると想像す ることである。 セグメントが既に受信した他のセグメントと重複する時、単に新しいデータ を含めるためにセグメントを再構築し、一貫させるためにヘッダフィールド を調整する。 もし、状態変更について言及していなければ、TCP は同じ状態に留まる。 OPEN 呼び出し CLOSED 状態 (すなわち TCB が存在しない) コネクション状態情報を保持するために新しい転送制御ブロック (TCB) を作成する。自側ソケット識別子、相手ソケット、優先度、セキュリティ /コンパートメント、ユーザタイムアウト情報を埋め込む。相手ソケッ トのある部分は受動的 OPEN で指定されず、入力 SYN セグメントのパ ラメタによって埋められるかもしれない。もし "エラー: 優先度が許可 されていない" あるいは "エラー: セキュリティ/コンパートメントが 許可されていない" が返却されなければ、要求されたセキュリティと優 先度がユーザに対して許可されていることが実証される。もし受動的な らば、LISTEN 状態に遷移して戻る。もし能動的で相手ソケットが指定 されていないならば、"エラー: 相手ソケット未指定" を返却する。も し能動的で相手ソケットが指定されているならば、SYN セグメントを発 行する。初期シーケンス番号は (ISS) が選択される。 の形式の SYN セグメントが送信される。SND.UNA に ISS を設定 し、SND.NXT に ISS+1 を設定し、SYN-SENT 状態に遷移して戻る。 もし呼び出し元が指定された自側ソケットへのアクセス権を持っていな ければ、"エラー: このプロセスではコネクション不正" を返却する。 もし新しいコネクションを生成する余地がないならば、"エラー: 資源 不足" を返却する。 LISTEN 状態 もし能動的で相手ソケットが指定されているならば、そのコネクション を受動的から能動的に変更し、ISS を選択する。SYN セグメントを送信 し、SND.UNA に ISS を設定し、SND.NXT に ISS+1 を設定する。 SYN-SENT 状態に遷移する。SEND に割り付けられたデータを SYN セグ メントと共に送信してもよいし、ESTABLISHED 状態に遷移した後に送信 するためにキューイングしてもよい。もしコマンドで要求されたら、こ のコマンドの結果としてデータセグメントに緊急ビットを付加して送信 しなければならない。もし要求をキューイングする余地が無いならば、 "エラー: 資源不足" を返却する。もし相手ソケットが指定されていな ければ、"エラー: 相手ソケット未指定" を返却する。 SYN-SENT 状態 SYN-RECEIVED 状態 ESTABLISHED 状態 FIN-WAIT-1 状態 FIN-WAIT-2 状態 CLOSE-WAIT 状態 CLOSING 状態 LAST-ACK 状態 TIME-WAIT 状態 "エラー: コネクションは既に存在" を返却する。 SEND 呼び出し CLOSED 状態 (すなわち TCB が存在しない) もしユーザがそのコネクションへのアクセス権を持っていなければ、 "エラー: このプロセスではコネクション不正" を返却する。 さもなくば、"エラー: コネクションが存在しない" を返却する。 LISTEN 状態 もし相手ソケットが指定されたならば、そのコネクションを受動的から 能動的に変更し、ISS を選択する。SYN セグメントを送信し、SND.UNA に ISS を設定し、SND.NXT に ISS+1 を設定する。SYN-SENT 状態に遷 移する。SEND に割り付けられたデータを SYN セグメントと共に送信し てもよいし、ESTABLISHED 状態に遷移した後に送信するためにキューイ ングしてもよい。もしコマンドで要求されたら、このコマンドの結果と してデータセグメントに緊急ビットを付加して送信しなければならない。 もし要求をキューイングする余地が無いならば、"エラー: 資源不足" を返却する。もし相手ソケットが指定されていなければ、"エラー: 相 手ソケット未指定" を返却する。 SYN-SENT 状態 SYN-RECEIVED 状態 ESTABLISHED 状態に遷移した後に送信するためにデータをキューイング する。もしキューイングする余地が無いならば、"エラー: 資源不足" を返却する。 ESTABLISHED 状態 CLOSE-WAIT 状態 バッファをセグメント化し、肯定応答 (確認値=RCV.NXT) を相乗りさせ て送信する。もしこのバッファを記憶する余地が無いならば、"エラー: 資源不足" を返却する。 もし緊急フラグが設定されたならば、SEND.UP に SND.NXT-1 を設定し、 出力セグメントの緊急ポインタを設定する。 FIN-WAIT-1 状態 FIN-WAIT-2 状態 CLOSING 状態 LAST-ACK 状態 TIME-WAIT 状態 "エラー: コネクションクローズ中" を返却し、要求は処理しない。 RECEIVE 呼び出し CLOSED 状態 (すなわち TCB が存在しない) もしユーザがそのコネクションへのアクセス権を持っていなければ、 "エラー: このプロセスではコネクション不正" を返却する。 さもなくば、"エラー: コネクションが存在しない" を返却する。 LISTEN 状態 SYN-SENT 状態 SYN-RECEIVED 状態 ESTABLISHED 状態に遷移した後に処理するためにキューイングする。も しこの要求をキューイングする余地が無いならば、"エラー: 資源不足" を返却する。 ESTABLISHED 状態 FIN-WAIT-1 状態 FIN-WAIT-2 状態 もし要求を満たすには不十分な入力セグメントがキューイングされてい たら、その要求をキューイングする。もし RECEIVE を記憶するための キュー空間が無いならば、"エラー: 資源不足" を返却する。 キューイングされた入力セグメントをバッファに再度集め、ユーザに返 却する。もし PUSH を検出したら、"PUSH 検出" を記入する。 もし RCV.UP が現在ユーザに渡そうとしているデータよりも前ならば、 そのユーザに緊急データの存在を通知する。 TCP がデータをユーザに配送する責任を担う場合、その事実を肯定応答 によって送信側に知らせなければならない。その様な肯定応答の形式は、 以下の入力セグメントの処理の議論で説明される。 CLOSE-WAIT 状態 相手側は既に FIN を送信済みなので、手元にあるがユーザにはまだ配 送していないテキストで RECEIVE を満たさなければならない。もし配 送を待つテキストが無いならば、RECEIVE は "エラー: コネクションク ローズ中" の応答を受け取るだろう。さもなくば、全ての残りのテキス トが RECEIVE を満たすために使用される。 CLOSING 状態 LAST-ACK 状態 TIME-WAIT 状態 "エラー: コネクションクローズ中" を返却する。 CLOSE 呼び出し CLOSED 状態 (すなわち TCB が存在しない) もしユーザがそのコネクションへのアクセス権を持っていなければ、 "エラー: このプロセスではコネクション不正" を返却する。 さもなくば、"エラー: コネクションが存在しない" を返却する。 LISTEN 状態 未処理の RECEIVE は全て "エラー: クローズ中" で返却される。TCB を削除し、CLOSED 状態に遷移して戻る。 SYN-SENT 状態 TCB を削除し、キューイングされている SEND あるいは RECEIVE に対 して全て "エラー: クローズ中" が返却される。 SYN-RECEIVED 状態 もし SEND が発行されておらず、ペンディング中の送信データが存在し なければ、FIN セグメントを生成して送信し、FIN-WAIT-1 状態に遷移 する。さもなくば、ESTABLISHED 状態に遷移した後に処理するためにキュ ーイングする。 ESTABLISHED 状態 先行する SEND が全てセグメント化されるまで、これをキューイングす る。セグメント化されたら FIN を生成して送信する。いずれの場合も FIN-WAIT-1 状態に遷移する。 FIN-WAIT-1 状態 FIN-WAIT-2 状態 厳密に言うとこれはエラーであり、"エラー: コネクションクローズ中" を返却すべきである。二個目の FIN が発行されない限り (ただし一個 目の FIN は再送してもよい)、"OK" 応答でもよい。 CLOSE-WAIT 状態 先行する SEND が全てセグメント化されるまで、これをキューイングす る。セグメント化されたら FIN セグメントを送信し、CLOSING 状態に 遷移する。 CLOSING 状態 LAST-ACK 状態 TIME-WAIT 状態 "エラー: コネクションクローズ中" を返却する。 ABORT 呼び出し CLOSED 状態 (すなわち TCB が存在しない) もしユーザがそのコネクションへのアクセス権を持っていなければ、 "エラー: このプロセスではコネクション不正" を返却する。 さもなくば、"エラー: コネクションが存在しない" を返却する。 LISTEN 状態 未処理の全ての RECEIVE に対して "エラー:コネクションリセット" の 応答を返却すべきである。TCB を削除し、CLOSED 状態に遷移して戻る。 SYN-SENT 状態 キューイングされている全ての SEND と RECEIVE に対して "エラー: コネクションリセット" が通知され、TCB を削除し、CLOSED 状態に遷 移して戻る。 SYN-RECEIVED 状態 ESTABLISHED 状態 FIN-WAIT-1 状態 FIN-WAIT-2 状態 CLOSE-WAIT 状態 以下のリセットセグメントを送信する。 キューイングされている全ての SEND と RECEIVE に対して "エラー: コネクションリセット" を通知するか、送信または再送するためにキュ ーイングされた全てのセグメント (上記で生成された RST は除く) を フラッシュすべきであり、TCB を削除し、CLOSED 状態に遷移して戻る。 CLOSING 状態 LAST-ACK 状態 TIME-WAIT 状態 "OK" で応答し、TCB を削除し、CLOSED 状態に遷移して戻る。 STATUS 呼び出し CLOSED 状態 (すなわち TCB が存在しない) もしユーザがそのコネクションへのアクセス権を持っていなければ、" エラー: このプロセスではコネクション不正" を返却する。 さもなくば、"エラー: コネクションが存在しない" を返却する。 LISTEN 状態 "状態=LISTEN" と TCB ポインタを返却する。 SYN-SENT 状態 "状態=SYN-SENTN" と TCB ポインタを返却する。 SYN-RECEIVED 状態 "状態=SYN-RECEIVED" と TCB ポインタを返却する。 ESTABLISHED 状態 "状態=ESTABLISHED" と TCB ポインタを返却する。 FIN-WAIT-1 状態 "状態=FIN-WAIT-1" と TCB ポインタを返却する。 FIN-WAIT-2 状態 "状態=FIN-WAIT-2" と TCB ポインタを返却する。 CLOSE-WAIT 状態 "状態=CLOSE-WAIT" と TCB ポインタを返却する。 CLOSING 状態 "状態=CLOSING" と TCB ポインタを返却する。 LAST-ACK 状態 "状態=LAST-ACK" と TCB ポインタを返却する。 TIME-WAIT 状態 "状態=TIME-WAIT" と TCB ポインタを返却する。 セグメント到着 もし状態が CLOSED (すなわち TCB が存在しない) ならば、 入力セグメント中の全てのデータを破棄する。RST を含む入力セグメン トは破棄する。RST を含まない入力セグメントは、その応答として RST を送信する。その確認番号とシーケンスフィールド値は、不快なセグメ ントを送信した TCP が受諾できるリセットシーケンスを作成するため に選択される。 もし ACK ビットがオフならば、シーケンス番号 0 が使用される。 もし ACK ビットがオンならば、 リターン もし状態が LISTEN ならば、 一番目に RST をチェックする。 受信した RST は無視する。リターン。 二番目に ACK をチェックする。 まだ LISTEN 状態のコネクション上に到着したら、いかなる肯定応答 も不正である。到着した 不正 ACK セグメントに対して、受諾可能な リセットセグメントを生成する。その RST の形式は、以下の通り。 リターン 三番目に SYN をチェックする。 もし SYN ビットが設定されていたら、セキュリティをチェックする。 もし受信したセグメントのセキュリティ/コンパートメントが、TCB のセキュリティ/コンパートメントと正確に一致しなければ、下記の 形式のリセットを送信してリターンする。 もし SEG.PRC が TCB.PRC よりも大きいならば、もしユーザやシステ ムに許可されていれば TCB.PRC に SEG.PRC を設定し、もし許可され ていないならば下記の形式のリセットを送信してリターンする。 もし SEG.PRC が TCB.PRC よりも小さいならば、継続。 RCV.NXT に SEG.SEQ+1 を、IRS に SEG.SEQ を設定し、後で処理する ために他の制御やテキストをキューイングする。ISS を選択して、以 下の形式の SYN セグメントを送信する。 SND.NXT に ISS+1 を設定し、SND.USA に ISS を設定する。コネクショ ン状態を SYN-RECEIVED に変更する。他の全ての受信した (SYN と結 合した) 制御やデータは SYN-RECEIVED 状態で処理されるが、SYN と ACK の処理は繰り返してはならないことに注意されたい。もしリッス ンが完全に指定されていなければ (相手側のソケットが完全に指定さ れていない)、未指定のフィールドが今埋められる。 四番目に他のテキストか制御をチェックする。 他のいかなる制御や不正なテキストセグメント (SYN を含まない) も ACK を持っているはずであり、従って ACK の処理によって破棄され るだろう。受信した RST セグメントは正しいことは有り得ない。な ぜなら、このコネクションの前のコネクションによって送信されたも のに対する応答で送信されることはないからである。従って、ここに 至ることはなさそうであるが、もし至ったらセグメントを破棄してリ ターンする。 もし状態が SYN-SENT ならば、 一番目に ACK ビットをチェックする。 もし ACK ビットが設定されていたら、 もし SEG.ACK =< ISS または SEG.ACK > SND.NXT ならば、以下の 形式のリセットを送信する (もし RST ビットが設定されていなけ れば。もし設定されているならばそのセグメントを破棄してリター ンする)。 そして、そのセグメントを破棄してリターンする。 もし SND.UNA =< SEG.ACK =< SND.NXT ならば、ACK を受信できる。 二番目に RST ビットをチェックする。 もし RST ビットが設定されていたら、 もし ACK を受信可能ならば、ユーザに "エラー: コネクションリ セット" を通知し、セグメントを破棄し、CLOSED 状態に遷移し、 TCB を削除してリターンする。さもなくば (ACK 不可)、セグメン トを破棄してリターンする。 三番目にセキュリティと優先度をチェックする。 もしセグメント中のセキュリティ/コンパートメントが、TCB 中のセ キュリティ/コンパートメントと正確に一致していなければ、以下の リセットを送信する。 もし ACK が存在するならば、 さもなくば もし ACK が存在するならば セグメント中の優先度は、TCB 中の優先度と一致しなければならな い。もし一致しなければ、以下のリセットを送信する。 もし ACK が存在しないならば、 もしセグメント中の優先度が TCB 中の優先度よりも高く、もしユ ーザやシステムによって許可されているならば、TCB 中の優先度を セグメント中の優先度に上げる。もし優先度を上げることを許可さ れていないならば、以下のリセットを送信する。 もしセグメント中の優先度が TCB 中の優先度よりも低いならば、 継続。 もしリセットが送信されたら、そのセグメントを破棄してリターンす る。 四番目に SYN ビットをチェックする。 このステップは、ACK が ok か ACK が存在せず、そのセグメントが RST を含まない場合にしか到達しないはずである。 もし SYN ビットが設定され、セキュリティ/コンパートメントや優先 度が受諾可能ならば、RCV.NXT に SEG.SEQ+1 が設定され、IRS に SEG.SEQ が設定される。SND.UNA は SEQ.ACK と等しい値に進められ (もし ACK が存在するならば)、それによって確認された再送キュー 上の全てのセグメントが除去される。 もし SND.UNA > ISS ならば (SYN は既に ACK 済み)、ESTABLISHD 状 態に遷移し、以下の ACK を生成して送信する。 送信のためにキューイングされたデータや制御を含んでもよい。もし セグメント中に他の制御やテキストが存在するならば、以下の六番目 のステップの処理を継続して行い、URG ビットをチェックする。さも なくばリターン。 さもなくば SYN-RECEIVED 状態に遷移し、以下の SYN,ACK セグメン トを生成して送信する。 もしセグメント中に他の制御やテキストが存在するならば、 ESTABLISHED 状態に遷移した後で処理するためにキューイングしてリ ターンする。 五番目に、もし SYN と RST のいずれのビットも設定されていなければ、 そのセグメントを破棄してリターンする。 さもなくば、(その他の状態ならば) 最初にシーケンス番号をチェックする。 SYN-RECEIVED 状態 ESTABLISHED 状態 FIN-WAIT-1 状態 FIN-WAIT-2 状態 CLOSE-WAIT 状態 CLOSING 状態 LAST-ACK 状態 TIME-WAIT 状態 セグメントを順序通り処理する。古い重複を破棄するために到着時に 初期チェックを行うが、以降は SEG.SEQ の順序で処理する。もしセ グメントの内容が新旧の境界をまたがるならば、新しい部分だけを処 理しなければならない。 入力セグメントに対する受信可能チェックは、以下の四つのケースが ある。 セグメント 受信 長 ウィンドウ テスト ------- ------- ------------------------------------------- 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 は特別に受信可能とすべきである。 もし入力セグメントが受信可能でないならば、以下の ACK をその応 答で送信すべきである (もし RST ビットが設定されていなければ。 もし設定されているなら、そのセグメントを破棄してリターンする)。 ACK を送信した後、受信不可のセグメントを破棄してリターンする。 次に来るものは、セグメントが RCV.NXT から始まりウィンドを超え ない理想的なセグメントであると想定される。あるものは、この想定 に合わせるために、ウィンドウの外に位置する部分 (SYN と FIN を 含め) を切り取り、結果的にセグメントが RCV.NXN から始まるなら ば、以降の処理を行うことによって、実際のセグメントを仕立てるこ とができるだろう。より高い開始シーケンス番号を持つセグメントは、 後で処理するために保持する。 二番目に RST ビットをチェックする。 SYN-RECEIVED 状態 もし RST ビットが設定されていたら、 もしこのコネクションが受動的 OPEN で起動されていたら (つまり LISTEN 状態から遷移した)、このコネクションを LISTEN 状態に戻 してリターンする。ユーザには通知する必要はない。もしこのコネ クションが能動的 OPEN で起動されていたら (つまりSYN-SENT 状 態から遷移した)、そのコネクションは拒否されており、ユーザに "コネクション拒否" を通知する。いずれのケースも、再送キュー 上の全てのセグメントを除去すべきである。そして能動的 OPEN の ケースでは、CLOSED 状態に遷移し、TCB を削除してリターンする。 ESTABLISHED 状態 FIN-WAIT-1 状態 FIN-WAIT-2 状態 CLOSE-WAIT 状態 もし RST ビットが設定されていたら、全ての未処理の RECEIVE と SEND は "リセット" 応答を受信すべきである。全てのセ グメントキューをフラッシュすべきである。ユーザはさらに、望まれ ない通常の "コネクションリセット" 通知を受信すべきで ある。CLOSED 状態に遷移し、TCB を削除してリターンする。 CLOSING STATE 状態 LAST-ACK STATE 状態 TIME-WAIT 状態 もし RST ビットが設定されていたら、CLOSED 状態に遷移し、TCB を削除してリターンする。 三番目にセキュリティと優先度をチェックする。 SYN-RECEIVED 状態 もしセグメント中のセキュリティ/コンパートメントと優先度が、TCB 中のセキュリティ/コンパートメントと優先度に正確に一致しなけれ ば、リセットを送信してリターンする。 ESTABLISHED 状態 もしセグメント中のセキュリティ/コンパートメントと優先度が、TCB 中のセキュリティ/コンパートメントと優先度に正確に一致しなけれ ば、リセットを送信し、全ての未処理の RECEIVE と SEND は "リセ ット" 応答を受信すべきである。全てのセグメントキューをフラッシュ すべきである。ユーザはさらに、望まれない通常の "コネクションリ セット" 通知を受信すべきである。CLOSED 状態に遷移し、TCB を削 除してリターンする。 このチェックは、現コネクションのアボート原因となった異なるセキュ リティか優先度を持つこれらのポート間の古いコネクションからのセグ メントを避けるために、シーケンスチェックの後に行われることに注意 されたい。 四番目に SYN ビットをチェックする。 SYN-RECEIVED 状態 ESTABLISHED STATE 状態 FIN-WAIT STATE-1 状態 FIN-WAIT STATE-2 状態 CLOSE-WAIT STATE 状態 CLOSING STATE 状態 LAST-ACK STATE 状態 TIME-WAIT STATE 状態 もし SYN がウィンドウ内であれば、それはエラーであり、リセット を送信し、全ての未処理の RECEIVE と SEND は "リセット" 応答を 受信すべきである。全てのセグメントキューをフラッシュすべきであ る。ユーザはさらに、望まれない通常の "コネクションリセット" 通 知を受信すべきである。CLOSED 状態に遷移し、TCB を削除してリタ ーンする。 もし SYN がウィンドウ内でなければ、このステップには到達せず、 最初のステップ (シーケンスチェック) で ACK が送信されるだろう。 五番目に ACK フィールドをチェックする。 もし ACK ビットがオフならば、そのセグメントを破棄してリターンす る。 もし ACK ビットがオンならば、 SYN-RECEIVED 状態 もし SND.UNA =< SEG.ACK =< SND.NXT ならば、ESTABLISHED 状態 に遷移して処理を継続する。 もし肯定応答のセグメントが受信不可ならば、以下のリセットを 生成して送信する。 ESTABLISHED 状態 もし SND.UNA < SEG.ACK =< SND.NXT ならば、もし SND.UNA に SEG.ACK を設定する。これによって全体が確認された再送キュー上 の全てのセグメントは削除される。ユーザは、送信され完全に確認 されたバッファに対する明確な肯定応答を受信すべきである (SEND バッファは "ok" 応答でリターンすべきである)。もし ACK が重複 していたら (SEG.ACK < SND.UNA)、それを無視できる。もし ACK がまだ送信していないものに対する確認ならば、ACK を送信し、そ のセグメントを破棄してリターンする。 もし SND.UNA < SEG.ACK =< SND.NXT ならば、送信ウィンドウを更 新すべきである。もし (SND.WL1 < SEG.SEQ または (SND.WL1 = SEG.SEQ and 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 状態での処理に加えて、もし再送キューが空ならば、 ユーザの CLOSE に肯定応答することができる ("ok") が、TCB は 削除しない。 CLOSE-WAIT 状態 ESTABLISHED 状態での処理の同じ処理を行う。 CLOSING 状態 ESTABLISHED 状態での処理に加えて、もし ACK が自側の FIN を確 認したら TIME-WAIT 状態に遷移し、さもなくばそのセグメントを 無視する。 LAST-ACK 状態 この状態で受信できるのは自側の FIN に対する肯定応答だけであ る。もし自側の FIN が確認されたら、TCB を削除し、CLOSED 状態 に遷移してリターンする。 TIME-WAIT 状態 この状態で受信できる唯一のものは、相手側 FIN の再送である。 それを肯定して 2 MSL タイムアウトを再開する。 六番目に 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 を無視する。 七番目にセグメントのテキストを処理する。 ESTABLISHED 状態 FIN-WAIT-1 状態 FIN-WAIT-2 状態 一旦 ESTABLISHED 状態に遷移したら、ユーザの RECEIVE バッファに セグメントのテキストを配送することが可能である。セグメントから のテキストは、バッファが一杯になるかセグメントが空になるまでバ ッファに移動することができる。もしセグメントが空で PUSH フラグ を運んでいるならば、バッファを返却する時に PUSH を受信したこと をユーザに通知する。 TCP がユーザにデータを配送する責任を担う時、データの受信側への 肯定応答の送信も行わなければならない。 一旦 TCP がデータの責任を担うと、RCV.NXT を受信したデータまで 進め、利用可能な現バッファに適するように RCV.WND を調整する。 RCV.NXT と RCV.WND の総計は減少してはならない。 セクション3.7のウィンドウ管理の提案に注意されたい。 以下の形式の ACK を送信する。 もし過度の遅延を受けず可能であれば、この肯定応答は送信しようと しているセグメント上に乗せて運ぶべきである。 CLOSE-WAIT 状態 CLOSING 状態 LAST-ACK 状態 TIME-WAIT 状態 相手側から既に FIN を受信済みなので、これは発生しないはずであ る。セグメントのテキストを無視する。 八番目に FIN ビットをチェックする。 もし状態が CLOSED,LISTEN,SYN-SENT ならば、SEG.SEQ を評価できない ので、FIN を処理せずセグメントを破棄してリターンする。 もし FIN ビットが設定されていたら、ユーザに "コネクションクロー ズ中" を通知し、ペンディング中の全ての RECEIVE に対して同じメッ セージで返し、RCV.NXT を FIN まで進め、FIN に対する肯定応答を送 信する。FIN は、ユーザにまだ配送されていないセグメントテキストの PUSH を暗黙的に意味することに注意されたい。 SYN-RECEIVED 状態 ESTABLISHED 状態 CLOSE-WAIT 状態に遷移する。 FIN-WAIT-1 状態 もし自側の FIN が確認されたら (おそらくこのセグメントで)、 TIME-WAIT 状態に遷移し、タイムウェイトタイマを開始し、他のタ イマを停止する。さもなくば、CLOSING 状態に遷移する。 FIN-WAIT-2 状態 TIME-WAIT 状態に遷移し、タイムウェイトタイマを開始し、他のタ イマを停止する。 CLOSE-WAIT 状態 CLOSE-WAIT 状態に留まる。 CLOSING 状態 CLOSING 状態に留まる。 LAST-ACK 状態 LAST-ACK 状態に留まる。 TIME-WAIT 状態 TIME-WAIT 状態に留まる。2 MSL タイムウェイトタイムアウトを再 開する。 そして、リターンする。 ユーザタイムアウト 如何なる状態においても、もしユーザタイムアウトが満了したら、全ての キューをフラッシュし、未処理の呼び出しに対して一般的にユーザに "エ ラー: ユーザタイムアウトによるコネクションアボート" を通知し、TCB を削除し、CLOSED 状態に遷移してリターンする。 再送タイムアウト 如何なる状態においても、もし再送キュー中のセグメントに対する再送タ イムアウトが満了したら、再送キューの一番前にあるセグメントを再度送 信し、再送タイマを再起動してリターンする。 タイムウェイトタイムアウト もしコネクションに対するタイムウェイトタイムアウトが満了したら、 TCB を削除し、CLOSED 状態に遷移してリターンする。 用語 1822 BBN レポート 1822、"ホストと IMP の相互接続規約"。ホストと ARPANET 間のインタフェースの規約。 ACK 制御ビット (確認) はシーケンス空間を消費せず、このセグメント の確認フィールドは、このセグメントの送信側が受信で期待してい る次のシーケンス番号を示す。つまり、この前の全てのシーケンス 番号の受信を確認する。 ARPANET メッセージ ARPANET 内のホストと IMP 間の送信単位。最大長は約 1012 オク テット (8096 ビット) である。 ARPANET パケット ARPANET 内の IMP 間で内部的に使用される送信単位。最大長は約 126 オクテット (1008 ビット)である。 コネクション ソケットのペアによって識別される論理的な通信パス。 データグラム パケット交換コンピュータ通信ネットワークで送信されるメッセー ジ。 宛先アドレス 宛先のアドレスで、通常はネットワークとホストの識別子である、 FIN 1 シーケンス番号を消費する制御ビット (終了) で、送信側がシー ケンス空間を消費するデータか制御をもう送信しないことを示す。 フラグメント データの論理的な単位の一部、特にインターネットフラグメントは インターネットデータグラムの一部分である。 FTP ファイル転送プロトコル。 ヘッダ メッセージ、セグメント、フラグメント、パケット、データブロッ クの開始にある制御情報。 ホスト コンピュータ。特に通信ネットワークの観点では、メッセージの送 信元か宛先。 識別子 インターネットプロトコルフィールド。送信側によって割り当てら れたこの識別値は、データグラムのフラグメントを組み立てる際の 助けとなる。 IMP インタフェースメッセージプロセッサ (Interface Message Processor)、ARPANET のパケット交換。 インターネットアドレス ホストレベルに特定な送信元か宛先のアドレス。 インターネットデータグラム インターネットヘッダと共に、インターネットモジュールと上位レ ベルプロトコル間で交換されるデータの単位。 インターネットフラグメント インターネットヘッダを持つインターネットデータグラムのデータ の一部分。 IP インターネットプロトコル。 IRS 初期受信シーケンス番号。コネクション上の送信側によって使用さ れる最初のシーケンス番号。 ISN 初期シーケンス番号。コネクション上で使用される最初のシーケン ス番号 (ISS か IRS のいずれか)。クロックに基づく手続きで選択 される。 ISS 初期送信シーケンス番号。コネクション上の送信側によって使用さ れる最初のシーケンス番号。 リーダ メッセージかデータブロックの開始の制御情報。特に ARPANET で は、host-IMP インタフェースにおける ARPANET メッセージ上の制 御情報。 残シーケンス これは、データ受信側の TCP によって確認された番号の次のシー ケンス番号 (または、現在未確認の最も小さいシーケンス番号) で あり、時々送信ウィンドウの残縁とも呼ばれる。 ローカルパケット ローカルネットワーク内の送信単位。 モジュール プロトコルや他の手続きの実装体、通常ソフトウェア。 MSL 最大セグメント生存時間、TCP セグメントが相互接続システム内で 存在できる時間。任意に 2 分と定義されている。 オクテット 8 ビットバイト。 オプション オプションフィールドは幾つかのオプションを含んでよく、各々の オプションは複数のオクテット長であってもよい。オプションは、 例えばタイムスタンプを運ぶといった、基本的に状況のテストに使 用される。インターネットプロトコルと TCP の両方ともオプショ ンフィールドを提供する。 パケット 論理的に完了していてもいなくてもよいヘッダを持つデータのパッ ケージ。大抵は、データを論理的に包装するよりも物理的に包装す る。 ポート プロセスのどの論理的な入出力チャネルがデータに割り当てられる かを示すソケットの一部。 プロセス 実行中のプログラム。特に TCP や他のホストツーホストプロトコ ルの観点では、データの送信元か宛先。 PUSH シーケンス空間を消費しない制御ビットで、このセグメントは受信 側ユーザに押し通さなければならないデータを含むことを示す。 RCV.NXT 受信する次のシーケンス番号 RCV.UP 受信する緊急ポインタ RCV.WND 受信ウィンドウ 受信する次のシーケンス番号 これは、自側 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 モジュ ール間のデータ転送の単位である。 セグメント確認 到着したセグメントの確認フィールドのシーケンス番号。 セグメント長 セグメントによって消費されるシーケンス番号空間の量で、シーケ ンス空間を消費する全ての制御も含む、 セグメントシーケンス 到着したセグメントのシーケンスフィールドの番号。 送信シーケンス これは、自側 (送信側) 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 ポートの連結。 送信元アドレス 送信元アドレス、通常、ネットワークとホスト識別子。 SYN 入力セグメント中の制御ビットで、一つのシーケンス空間を占め、 コネクションの起動に使用され、どのシーケンス番号から開始する かを示す。 TCB 転送制御ブロック、コネクションの状態を記録するデータ構造。 TCB.PRC コネクションの優先度。 TCP 転送制御プロトコル。相互ネットワーク環境で信頼できる通信を行 うためのホストツーホストプロトコル。 TOS サービスタイプ、インターネットプロトコルフィールド。 サービスタイプ このインターネットフラグメントに対するサービスタイプを示すイ ンターネットプロトコルフィールド。 URG シーケンス番号空間を占めない制御ビット (緊急)。緊急ポインタ で示された値よりも小さいシーケンス番号を消費するデータが存在 する限り、緊急に処理することを受信側ユーザに通知すべきである ことを示すために使用される。 緊急ポインタ URG ビットがオンの時に限り意味を持つ制御フィールド。このフィ ールドは、送信側ユーザの緊急呼び出しに関連したデータオクテッ トを示す緊急ポインタの値を伝達する。 参照 [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.