RFC: 793
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 TITLE="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
転送制御プロトコル (TCP: Transmission Control Protocol) は、パケット交換コンピュータ通信ネットワーク内で、そしてその様なネットワークの相互接続システムにおいて、ホスト間の高く信頼できる host-to-host プロトコルとして使用することを意図している。
このドキュメントは、Transmission Control Protocol によって実行される機能、それを実装するプログラム、そのサービスを要求するプログラムか利用者へのインタフェースについて記述している。
コンピュータ通信システムは軍事、政治、市民環境において増しつつある重要な役割を担っている。このドキュメントは基本的に、軍事コンピュータ通信の要求、特に信頼の無い通信における信頼性の強化、混雑時の効率化に的を絞っている。これらの問題はの多くは、市民や政治の場面でも見られる。
戦略的、戦術的コンピュータ通信ネットワークが開発され導入されるにつれて、それらを相互接続する手段や、広範囲なアプリケーションをサポートできる標準的な相互処理通信プロトコルを提供することが不可欠になっている。その様な標準の必要性を見越して、国防次官調査技術委員会 (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 セグメントの優先度、セキュリティ分類、区分に関する情報も運ぶ。よってこの情報は、複数のネットワークに渡ってエンドツーエンドに伝達することができる。
+---------------------+ | higher-level | +---------------------+ | TCP | +---------------------+ | internet protocol | +---------------------+ |communication network| +---------------------+ Figure 1
そのドキュメントの大半は、ホストコンピュータ内の上位レベルプロトコルと同居している TCP 実装のコンテキストで記述されている。あるコンピュータシステムは、ネットワーク特定ソフトウェアだけでなく、TCP と Internet Protocol が実装されている front-end コンピュータを経由してネットワークに接続されるかもしれない。TCP 規約は、適切な host-to-front-end プロトコルが実装されている限り、front-end の場合さえも実装できるような上位レベルプロトコルへのインタフェースを規定している。
TCP は、マルチネットワーク内での、信頼できる process-to-process 通信サービスを提供することを意図している。TCP は、複数のネットワークで共通で使用される host-to-host のプロトコルであることを意図している。
このドキュメントは、上位レベルプロトコルとの相互動作と、他の TCP との相互動作の両面に関する全ての TCP の実装に要求された振る舞いの規定を表している。この節の残りは、プロトコルインタフェースと処理の非常に簡潔な観点を提供している。第 2 節は、TCP 設計の根本的思想を要約している。第 3 節は、様々なイベント (新たなセグメントの到達、利用者のコール、エラー等) が発生した時に TCP に要求された動作の詳細な規定と TCP セグメントのフォーマットの詳細の両方を提供している。
TCP は、一方では利用者かアプリケーションのプロセスへの、もう一方では例えば Internet Protocol の様な下位レベルプロトコルへの橋渡しをする。
アプリケーションプロセスと TCP 間のインタフェースは、効率的に詳しく図示されている。このインタフェースは、ファイルを扱うためにオペレーティングシステムがアプリケーションプロセスに提供しているコールに、非常によく似たコールのセットから構成される。例えば、確立されたコネクション上でデータを送受信するために、コネクションをオープン/クローズするコールがある。又 TCP は、非同期でアプリケーションプログラムと通信できることを期待されている。ある特定のオペレーティングシステム環境に適したインタフェースを設計するために、かなりの自由度が TCP の実装者に許されているが、全ての正しい実装の TCP/user インタフェースにおいて、最小限の機能性は求められる。
TCP と下位レベルプロトコル間のインタフェースは、2 つのレベルがお互いに非同期に情報を渡し合うメカニズムが存在するという想定を除き、本質的に規定しない。一般的に、下位レベルのプロトコルでこのインターフェースを規定することが期待される。TCP は、相互接続された非常に一般的な環境で動作するために設計されている。このドキュメントを通して想定される下位レベルのプロトコルは、Internet Protocol [2] である。
上記で示されている様に、TCP の主要目的は、一組のプロセス間で信頼できて保証できる論理回線サービス、あるいはコネクションサービスを提供することである。信頼性の薄いインターネット通信システムの最上位でこのサービスを提供するために、以下の分野における設備が必要である。
基本データ転送 (Basic Data Transfer)
信頼性 (Reliability)
フロー制御 (Flow Control)
多重化 (Multiplexing)
コネクション (Connections)
優先度とセキュリティ (Precedence and Security)
これらの分野の各々における TCP の基本処理は、以下のパラグラフに記述されている。
TCP は、数個のオクテットをインターネットシステムを通じて転送するためのセグメントにパッケージングすることによって、オクテットの連続的ストリームを利用者間の各々の方向に転送することができる。通常 TCP は、いつデータをブロックしたり転送するかを自身の便宜で決定する。
時々利用者は、TCP に渡したデータの全てが転送されたことを確かめる必要がある。この目的のために push 機能が定義されている。TCP に渡されたデータが実際に転送されたことを確かめるために、送信側利用者は TCP に、受信側利用者に push せよと指示する。push は、TCP にそのポイントまでのデータを受信側に即座に送信/配送させる。正確な push ポイントは受信側利用者には見えないかもしれない。また push 機能は、レコード境界のマーカを供給しない。
TCP は、インターネット通信システムによって破損を受けたり、欠損したり、重複したり、順番通りに配送されていないデータを回復させなければならない。これは、転送する各々のオクテットにシーケンス番号を割り当て、受信側 TCP からの肯定応答 (ACK: positive acknowledgment) を要求することによって実現される。もし タイムアウト間隔以内に ACK を受信しなければ、そのデータは再送される。受信側では、順番通りに受信していないかもしれないセグメントを正しく順序付けたり、重複を取り除くためにシーケンス番号を使用する。破損は、転送するセグメントの各々にチェックサムを付加し、受信側でそれをチェックして、破損があるセグメントは破棄することによって処理される。
TCP が適切に機能し続け、インターネットシステムが完全に分離されない限り、転送エラーが正常なデータの配送に影響することはないだろう。TCP は、インターネット通信システムの異常から回復させる。
TCP は、受信者が送信者によって送信されるデータ量を抑制する手段を提供する。これは、正常に受信した最終セグメント以降の受諾できるシーケンス番号の範囲を示す全ての ACK で、"ウィンドウ" を返すことによって実現される。ウィンドウは、送信者が次の許可を受ける前に転送してもよいオクテット数を示す。
単一のホスト内で多くのプロセスが TCP 通信設備を同時に使用可能にするために、TCP は各ホスト内でアドレスかポートのセットを提供する。インターネット通信層からのネットワークとホストのアドレスを連結して、ソケットを形成する。ソケットのペアは各々のコネクションをユニークに識別する。すなわち、ソケットは複数のコネクションで同時に使用してもよい。
ポートのプロセスへの結び付け (binding) は、各々のホストによって独立して処理される。しかし、しばしば使用されるプロセス (例えば "logger" や時分割サービス) を、公に知られている固定のソケットに割り当てることは、便利であることが判明している。これらのサービスは、既知のアドレスを通じてアクセスすることができる。他のプロセスのポートアドレスを設けたり知ることは、より動的なメカニズムを伴うかもしれない。
上記に示されている信頼性とフロー制御メカニズムは、TCP が各々のデータストリームに対するあるステータス情報を初期化して維持することを必要とする。ソケットやシーケンス番号、ウィンドウサイズを含むこれらの情報のコンビネーションは、コネクションと呼ばれる。各々のコネクションは、両者を識別する一対のソケットによってユニークに指定される。
2 つのプロセスが通信することを望む時、それらの TCP はまず始めにコネクションを確立しなければならない (各々の側でステータス情報を初期化する)。それらの通信が完了した時、コネクションを終了又はクローズして、他で使用するために資源を解放する。
コネクションは、信頼できないホスト間で、信頼できないインターネット通信システム上で確立しなければならないので、クロックに基づくシーケンス番号を持ったハンドシェークメカニズムが、コネクションの初期化異常を避けるために利用される。
TCP の利用者は、その通信のセキュリティと優先度を指示してもよい。これらの特徴が必要でない時に使用されるデフォルト値が設けられている。
相互ネットワーク環境は、ゲートウェイを経由して相互接続されるネットワークに接続されたホストで構成される。ネットワークはローカルネットワーク (例えば Ethernet) か大規模ネットワーク (例えば ARPANET) のどちらかであることが想定されるが、いずれのケースもパケット交換技術に基づいている。メッセージを生成し消費する活性エージェントは、プロセスである。ネットワーク中のプロトコルやゲートウェイやホストの様々なレベルは、プロセスポート間の論理接続上で 2 方向データフローを提供する相互処理通信システムをサポートする。
パケットという言葉は、ホストとネットワーク間の 1 トランザクションのデータを意味するために、総称的にここでは使用される。ネットワーク内で交換されるデータブロックのフォーマットは、通常我々には関係ない。
ホストは、ネットワークと結びついたコンピュータであり、通信ネットワークの観点から見るとパケットの送信元と宛先である。プロセスは、ホストコンピュータ中では活性化した要素として見られる (実行プログラムとしてのプロセスの公正な共通定義に従って)。端末やファイル又は他の I/O デバイスでさえ、プロセスの使用を通じて互いに通信している様に見られる。よって、全ての通信は相互プロセス通信として見られる。
プロセスは、自分自身と他のプロセスとの間の幾つかの通信ストリームの中で区別する必要があるので、各々のプロセスは数多くのポートを持ち、それらを通じて他のプロセスのポートと通信するだろう。
プロセスは、TCP を呼び出し、アーギュメントとしてデータのバッファを渡すことによってデータを転送する。TCP は、これらのバッファからデータをセグメントに包み込む。受信側 TCP は、データをセグメントから受信側ユーザのバッファに置き、受信側ユーザに通知する。TCP は、信頼できる順序のデータ転送を保証するために使用する制御情報を、セグメント中に含む。
インターネット通信のモデルは、ローカルネットワークへのインタフェースを提供する各 TCP に結び付いた Internet Protocol モジュールが存在することである。このインターネットモジュールは、TCP セグメントをインターネットデータグラムの内部にパケット化し、これらのデータグラムを宛先インターネットモジュールか、あるいは中間のゲートウェイに振り分ける。ローカルネットワークを通じてデータグラムを転送するために、それはローカルネットワークパケットに埋め込まれる。
パケット交換は、ローカルパケットの宛先インターネットモジュールへの配送を達成するために、更なるパケット化、セグメント化、あるいは他の処理を実行するかもしれない。
ネットワーク間のゲートウェイにおいては、インターネットデータグラムはローカルパケットから "包みが開けられ (unwrapped)"、どのネットワークを通じてインターネットデータグラムを次に送るかを決定しようと試みる。その後、インターネットデータグラムは、次のネットワークに適したローカルパケットに "包まれ (wrapped)"、次のゲートウェイか又は最終宛先に振分けられる。
ゲートウェイは、もし次のネットワークを通じての転送に必要であれば、インターネットデータグラムを、より小さいインターネットデータグラムのフラグメントに分割してもよい。これを行うために、ゲートウェイは 1 セットのインターネットデータグラムを生成し、各々 1 つのフラグメントを運ぶ。そのフラグメントは、次のゲートウェイで、より小さいフラグメントに更に分割されるかもしれない。インターネットデータグラムのフラグメント形式は、宛先インターネットモジュールがフラグメントをインターネットデータグラムに再組み立てできるように設計されている。
宛先インターネットモジュールは、(必要があれば再組み立てを行った後) データグラムからセグメントを解き、宛先 TCP に渡す。
この単純な処理モデルは、多くの詳細を取り繕う。一つの重要な特徴はサービスタイプである。これは、ゲートウェイ (又はインターネットモジュール) に、次のゲートウェイに配送するのに使用されるサービスパラメタを選択する際の指標となる情報を提供する。サービス情報のタイプに含まれるものは、データグラムの優先度である。データグラムは、複数レベルのセキュリティ環境で運用されるホストやゲートウェイが、セキュリティを考慮して適切にデータグラムを差別化することを可能にするために、セキュリティ情報も運ぶかもしれない。
TCP は、オペレーティングシステム中のモジュールであると想定される。利用者は、ファイルシステムにアクセスするのとほとんど同じ様に TCP にアクセスする。TCP は、例えばデータ構造を管理するために、他のオペレーティングシステムの機能を呼んでもよい。ネットワークへの実際のインタフェースは、デバイスドライバモジュールによって制御されると想定される。TCP は、ネットワークデバイスドライバを直接呼ばず、代わりにデバイスドライバを呼ぶであろうインターネットデータグラムプロトコルモジュールを呼ぶ。
TCP のメカニズムは、front-end プロセッサにおける TCP の実装を除外していない。TCP のメカニズムは、front-end プロセッサにおける TCP の実装を除外していない。しかしそうした実装では、host-to-front-end プロトコルは、このドキュメントで規定されている TCP ユーザインタフェースのタイプをサポートする機能を提供しなければならない。
TCP/ユーザインタフェースは、TCP 上で利用者がコネクションを OPEN か CLOSE したり、データを SEND か RECEIVE したり、コネクションについての STATUS を取得するための呼び出しを提供する。これらの呼び出しは、例えばファイルの open, read, close のような、オペレーティングシステム上のユーザプログラムからの他の呼び出しと似たものである。
TCP/internet インタフェースは、インターネットシステム内のあらゆるホストの中にある TCP モジュールにアドレス付けられたデータグラムを送受信する呼び出しを提供する。これらの呼び出しは、アドレスやサービスタイプ、優先度、セキュリティ、他の制御情報等を渡すパラメタを持つ。
以下の図は、プロトコル階層内での 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 のような、上位レベルプロトコルへのインタフェースを持つことは簡単なはずである。
TCP コネクション上で送信されるデータのストリームは、信頼性があり、順番通りに宛先に配送される。
シーケンス番号と肯定応答を利用することによって、信頼できる転送が行われる。概念上では、データの各オクテットにシーケンス番号が割り当てられる。データの一番目のオクテットのセグメント中のシーケンス番号は、そのセグメントと共に転送され、セグメントシーケンス番号と呼ばれる。セグメントは、次に期待される逆方向転送のデータオクテットのシーケンス番号である確認番号も運ぶ。TCP がデータを含んでいるセグメントを転送する時、再送キューにコピーを置き、タイマーを開始する。そのデータに対する肯定応答を受信した時、そのセグメントがキューから削除される。もしタイマが完了するまでに肯定応答を受信しなければ、そのセグメントは再送される。
TCP による肯定応答は、データがエンドユーザに届いたことは保証しておらず、受信側 TCP がデータをエンドユーザに届ける責任があることを保証しているだけである。
TCP 間のデータの流れを統治するために、フロー制御メカニズムが導入される。受信側 TCP は、送信側 TCP に "ウィンドウ" を通知する。このウィンドウは、受信側 TCP に現在受信する準備がされているオクテットの数 (確認番号から始まる) を示している。
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 が外部のソケットを指定しないままとするケースである。この場合、自側のソケットが一致すればあらゆる外部ソケットが受諾できる。
TCB と (その様な TCB が存在するならば) 一致するであろう。 もし、同一の自側ソケットで幾つかのペンディングになっている消極的 OPEN (TCB に記録されている) が存在するならば、外部の積極的 OPEN は、未指定の外部ソケットの TCB を選択する前に、外部の積極的 OPEN で指定された外部ソケットの TCB と一致するだろう (その様な TCB が存在するならば)。
コネクションを確立するための手続きは同期 (SYN: synchronize) 制御フラグを利用し、3 つのメッセージ交換を行う。この交換は 3 方向ハンドシェーク [3] と名付けられている。
コネクションは、SYN を含むセグメントの到着と、ユーザ OPEN コマンドによって各々生成された TCB エントリの待ちとの待ち合わせによって起動される。自側と外部のソケットの照合は、いつコネクションが起動されたかを決定する。そのコネクションは、シーケンス番号が両方向で同期がとられた時に "確立済 (established)" になる。
コネクションのクリアもセグメントの交換を行う。この場合 FIN 制御フラグを運ぶ。
コネクション上に流れるデータは、オクテットのストリームと考えられる。送信側ユーザは各々の SEND コールで、そのコール (とあらゆる先行コール) 中のデータを即座に受信側ユーザに押し出すべきか否かを、PUSH フラグを設定することによって指示する。
送信側 TCP は、push 機能が通達されるまで、送信側ユーザからのデータを集め、セグメント中のデータを都合の良い時に送信することができる。push 機能が通達されると全ての未送信データを送信しなければならない。受信側の TCP が PUSH フラグを検出したら、受信側のプロセスにそのデータを渡す前に送信側 TCP からデータを更に待ってはならない。
push 機能とセグメント境界の間は、必ずしも関係はない。ある特定のセグメント中のデータは、その全てあるいは一部分が 1 つの SEND コールの結果かもしれないし、複数の SEND コールの結果かもしれない。
push 機能や PUSH フラグの目的は、送信側ユーザから受信側ユーザにデータを押し出すことである。記録サービスは提供しない。
push 機能と TCP/ユーザインタフェースを渡るデータのバッファの使用は連結される。受信側ユーザのバッファに入れられるデータに PUSH フラグが付いているたびに、そのバッファはたとえ一杯になっていなくても、処理するためにユーザに返される。もし、PUSH を検出する前にユーザバッファを一杯にするデータが到達したら、そのデータはバッファサイズの単位でユーザに渡される。
TCP は、受信側が現在読み込んでいるデータストリームの更に先のポイントに緊急のデータが存在することを、データの受信側に通知する手段も提供する。TCP は緊急データのペンディングを通知する際に、ユーザが明示的に何を行うかを定義することは試みていない。しかし、受信側プロセスが緊急のデータをすぐに処理する動作を実行するだろうといことは通常考えられる。
TCP は、1 コネクション毎に TCP ユーザに優先度とセキュリティを提供するために、Internet Protocol サービスタイプフィールドとセキュリティオプションを使用する。全ての TCP モジュールが複数レベルのセキュリティ環境の機能を必要とするわけではない。あるものは分類しない使用のみに限定するかもしれないし、またあるものは 1 つのセキュリティレベルやコンパートメントでのみ処理するかもしれない。よって、TCP の実装とユーザへのサービスは、複数レベルのセキュリティケースのサブセットに限定されるかもしれない。
複数レベルのセキュリティ環境で処理する TCP モジュールは、セキュリティ、コンパートメント、優先度を持つ出力セグメントを適切にマークしなければならない。そうした TCP モジュールはユーザや、Telent や THP 等の上位レベルのプロトコルに、望ましいコネクションのセキュリティレベル、コンパートメント、優先度の指定を可能にするためのインタフェースを提供しなければならない。
TCP の実装は、頑強さの一般原則: 自ら行うことには慎重に、他から受け入れるものには寛大に、に従う。
TCP セグメントはインターネットデータグラムとして送信される。Internet Protocol ヘッダは、送信元と宛先ホストアドレス [2] を含む幾つかの情報フィールドを運ぶ。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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 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 (左から右へ):
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
| -
| End of option list |
1
| -
| No-Operation. |
2
| 4
| Maximum Segment Size. |
特定のオプション定義
オプションリストの最終
+--------+ |00000000| +--------+ 種別 = 0
このオプションコードは、オプションリストの最終を示す。これは、データオフセットフィールドに従った TCP ヘッダの最終とは一致しないかもしれない。これは、各オプションの最後で使用されるのではなく、全オプションの最後で使用される。オプションの最後が TCP ヘッダの最後と一致しない場合にのみ使用する必要がある。
操作なし
+--------+ |00000001| +--------+ 種別 = 1
このオプションコードは、例えば後続するオプションの開始をワード境界に調整するために、オプションの間で使用してもよい。送信者がこのオプションを使用する保証はない。よって受信側は、たとえワード境界で始まっていなくてもオプションを処理できるよう、準備していなければならない。
最大セグメントサイズ
+--------+--------+---------+--------+ |00000010|00000100| max seg size | +--------+--------+---------+--------+ 種別 = 2, 長さ = 4
最大セグメントサイズのオプションデータ: 16 bits
もし、このオプションが提供されたら、このセグメントを送信する
TCP で、最大受信セグメントサイズを通信する。このフィールドは、初期コネクション要求でのみ送信できる
(すなわち、SYN 制御ビットが設定されたセグメント)。もしこのオフションが使用されなければ、いかなるセグメントサイズも許される。
パディング: 可変
TCP ヘッダパディングは、TCP ヘッダの最終とデータ部の開始が
32 ビット境界にあることを保証するために使用される。パディングは、0
から成る。
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 - まだ使用できない将来のシーケンス番号
Figure 4. - Send Sequence Space
送信ウィンドウは、図 4 のシーケンス空間のラベル 3 の所である。
受信シーケンス空間
1 2 3 ----------|----------|---------- RCV.NXT RCV.NXT +RCV.WND
1 - 確認済の古いシーケンス番号
2 - 新たに受信できるシーケンス番号
3 - まだ使用できない将来のシーケンス番号
Figure 5. - Receive Sequence Space
受信ウィンドウは、図 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.
設計における基本的な考え方は、TCP コネクション上で送信されるデータの全てのオクテットはシーケンス番号を持つということである。全てのオクテットは順番通りに並べられるので、それらの各々に対して確認することができる。提供される確認メカニズムは累積されるものなので、シーケンス番号の X の確認は、X を含まない X までの全てのオクテットを受信したことを示す。セグメント内のオクテットの番号付けにおいては、ベッダの直後に続く一番目のデータオクテットに最も小さい番号が付けられ、それに続くオクテットは連番になる。
実際のシーケンス番号空間は非常に大きいが、有限であることを覚えておくことは重要である。この空間は、0 から 2 の 32 乗 - 1 の範囲である。空間が有限なので、シーケンス番号を扱う全ての計算は、2 の 32 乗のモジュロを実行しなければならない。この符号無しの計算は、2 の 32 乗 - 1 から 0 に再び環してシーケンス番号の関係を保つ。モジュロ計算を算出する巧妙な方法が幾つかあるので、大半はその値の比較プログラミングに注意を向けるべきである。"=<" の記号は、"以下" を意味する (モジュロ 2 の 32 乗)。
TCP が実行しなければならない典型的な種類のシーケンス番号の比較は、以下を含む。
送信データに対する応答で、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 Length | Receive Window | Test |
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 秒経過するまで "ビジー" か "使用中" となる。そしてクラッシュした時、時空間のブロックは最後に発行されたセグメントのオクテットに占有される。もし新しいコネクションが非常に早く開始され、前のコネクションの化身の最終セグメントの時空間の足跡中のシーケンス番号を使用したら、受信側が混乱するかもしれない潜在的なシーケンス番号の重複する領域が存在する。