RFC793 - Transmission Control Protocol

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    --> <SEQ=100><CTL=SYN>               --> SYN-RECEIVED

3.  ESTABLISHED <-- <SEQ=300><ACK=101><CTL=SYN,ACK>  <-- SYN-RECEIVED

4.  ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK>       --> ESTABLISHED

5.  ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK><DATA> --> 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     --> <SEQ=100><CTL=SYN>              ...             

3.  SYN-RECEIVED <-- <SEQ=300><CTL=SYN>              <-- SYN-SENT    

4.               ... <SEQ=100><CTL=SYN>              --> SYN-RECEIVED

5.  SYN-RECEIVED --> <SEQ=100><ACK=301><CTL=SYN,ACK> ...             

6.  ESTABLISHED  <-- <SEQ=300><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED

7.               ... <SEQ=101><ACK=301><CTL=ACK>     --> 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    --> <SEQ=100><CTL=SYN>               ...             

3.  (duplicate) ... <SEQ=90><CTL=SYN>               --> SYN-RECEIVED 

4.  SYN-SENT    <-- <SEQ=300><ACK=91><CTL=SYN,ACK>  <-- SYN-RECEIVED 

5.  SYN-SENT    --> <SEQ=91><CTL=RST>               --> LISTEN       

6.              ... <SEQ=100><CTL=SYN>               --> SYN-RECEIVED

7.  SYN-SENT    <-- <SEQ=400><ACK=101><CTL=SYN,ACK>  <-- SYN-RECEIVED

8.  ESTABLISHED --> <SEQ=101><ACK=401><CTL=ACK>      --> 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 --> <SEQ=400><CTL=SYN>              --> (??)       

4.  (!!)     <-- <SEQ=300><ACK=100><CTL=ACK>     <-- ESTABLISHED

5.  SYN-SENT --> <SEQ=100><CTL=RST>              --> (Abort!!)  

6.  SYN-SENT                                         CLOSED     

7.  SYN-SENT --> <SEQ=400><CTL=SYN>              -->            

図 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.  (??)    <-- <SEQ=300><ACK=100><DATA=10><CTL=ACK> <-- ESTABLISHED

3.          --> <SEQ=100><CTL=RST>                   --> (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.       ... <SEQ=Z><CTL=SYN>                -->  SYN-RECEIVED       

3.  (??) <-- <SEQ=X><ACK=Z+1><CTL=SYN,ACK>   <--  SYN-RECEIVED       

4.       --> <SEQ=Z+1><CTL=RST>              -->  (return to LISTEN!)

5.  LISTEN                                        LISTEN             

図 12 - 古い重複 SYN が 2 つの受動ソケット上でリセットを起動する。

様々な他のケースも起り得る。それらの全ては、RST 生成/処理に関する以下の規則によって説明される。

リセット生成

一般規則として、現在のコネクション上で明らかに意図されていないセグメントが到達した時は、常にリセット (RST) を送信しなければならない。これがそのケースであることが明確でないならば、リセットを送信してはならない。

状態には 3 つのグループがある。

  1. もしコネクションが存在しなければ (CLOSED)、別のリセットを除く全ての入力セグメントに対する応答でリセットが送信される。特に、存在しないコネクションにアドレス付けられた SYN は、この手段によって拒否される。

    もし、入力セグメントが 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 フィールドをシーケンス番号に指定する。

リセット処理

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 する。

ケース 1: ローカルユーザがクローズを起動する。

この場合、FIN セグメントが作成され、出力セグメントキューに置かれる。以降のユーザからの SEND を TCP は受諾せず、FIN-WAIT-1 状態に入る。RECEIVE はこの状態では許される。FIN を含む先行する全てのセグメントは、確認されるまで再送される。相手側 TCP が FIN を確認し、自分自身の FIN を送信した時、起動側 TCP はこの FIN に ACK を送信することができる。FIN を受信した TCP は ACK は送信するが、さらにユーザがコネクションを CLOSE するまで自身の FIN は送信しないだろう。

ケース 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  --> <SEQ=100><ACK=300><CTL=FIN,ACK>  --> CLOSE-WAIT 

  3.  FIN-WAIT-2  <-- <SEQ=300><ACK=101><CTL=ACK>      <-- CLOSE-WAIT 

  4.                                                       (Close)    
      TIME-WAIT   <-- <SEQ=300><ACK=101><CTL=FIN,ACK>  <-- LAST-ACK   

  5.  TIME-WAIT   --> <SEQ=101><ACK=301><CTL=ACK>      --> CLOSED     

  6.  (2 MSL)                                                         
      CLOSED                                                          

図 13. - 通常のクローズシーケンス
      TCP A                                                TCP B      

  1.  ESTABLISHED                                          ESTABLISHED

  2.  (Close)                                              (Close)    
      FIN-WAIT-1  --> <SEQ=100><ACK=300><CTL=FIN,ACK>  ... FIN-WAIT-1 
                  <-- <SEQ=300><ACK=100><CTL=FIN,ACK>  <--            
                  ... <SEQ=100><ACK=300><CTL=FIN,ACK>  -->            

  3.  CLOSING     --> <SEQ=101><ACK=301><CTL=ACK>      ... CLOSING    
                  <-- <SEQ=301><ACK=101><CTL=ACK>      <--            
                  ... <SEQ=101><ACK=301><CTL=ACK>      -->            

  4.  TIME-WAIT                                            TIME-WAIT  
      (2 MSL)                                              (2 MSL)    
      CLOSED                                               CLOSED     

図 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 はコマンドを受諾しなければならないだけでなく、サービスを提供しているプロセスに情報を返却もしなければならない。後者は以下のものから構成される。

  1. コネクションについての一般的な情報 (中断、遠隔クローズ、未指定の相手側ソケットのバインド等)
  2. 指定されたユーザコマンドへの応答で、成功したか失敗した様々なタイプ

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) が選択される。<SEQ=ISS><CTL=SYN> の形式の 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 状態

TCB を削除し、キューイングされている SEND あるいは RECEIVE に対して全て "エラー: クローズ中" が返却される。

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 状態

以下のリセットセグメントを送信する。
    <SEQ=SND.NXT><CTL=RST>

キューイングされている全ての SEND と RECEIVE に対して "エラー: コネクションリセット" を通知するか、送信または再送するためにキューイングされた全てのセグメント (上記で生成された RST は除く) をフラッシュすべきであり、TCB を削除し、CLOSED 状態に遷移して戻る。

CLOSING 状態
LAST-ACK 状態
TIME-WAIT 状態

"OK" で応答し、TCB を削除し、CLOSED 状態に遷移して戻る。

STATUS 呼び出し

CLOSED 状態 (すなわち TCB が存在しない)

もしユーザがそのコネクションへのアクセス権を持っていなければ、"エラー: このプロセスではコネクション不正" を返却する。

さもなくば、"エラー: コネクションが存在しない" を返却する。

LISTEN 状態

"状態=LISTEN" と TCB ポインタを返却する。

SYN-SENT 状態

"状態=SYN-SENT" と 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 が使用される。

    <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>

  もし ACK ビットがオンならば、

    <SEQ=SEG.ACK><CTL=RST>

  リターン

もし状態が LISTEN ならば、

  一番目に RST をチェックする。

    受信した RST は無視する。リターン。

  二番目にACKをチェックする。

    まだ LISTEN 状態のコネクション上に到着したら、いかなる肯定応答
    も不正である。到着した 不正 ACK セグメントに対して、受諾可能な
    リセットセグメントを生成する。その RST の形式は、以下の通り。

      <SEQ=SEG.ACK><CTL=RST>

    リターン

  三番目に SYN をチェックする。

    もし SYN ビットが設定されていたら、セキュリティをチェックする。
    もし受信したセグメントのセキュリティ/コンパートメントが、TCB
    のセキュリティ/コンパートメントと正確に一致しなければ、下記の
    形式のリセットを送信してリターンする。

      <SEQ=SEG.ACK><CTL=RST>

    もし SEG.PRC が TCB.PRC よりも大きいならば、もしユーザやシステ
    ムに許可されていれば TCB.PRC に SEG.PRC を設定し、もし許可され
    ていないならば下記の形式のリセットを送信してリターンする。

      <SEQ=SEG.ACK><CTL=RST>

    もし SEG.PRC が TCB.PRC よりも小さいならば、継続。

    RCV.NXT に SEG.SEQ+1 を、IRS に SEG.SEQ を設定し、後で処理する
    ために他の制御やテキストをキューイングする。ISS を選択して、以
    下の形式の SYN セグメントを送信する。

      <SEQ=ISS><ACK=RCV.NXT><CTL=SYN,ACK>

    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 ビットが設定されて
      いなければ。もし設定されているならばそのセグメントを破棄して
      リターンする)。

        <SEQ=SEG.ACK><CTL=RST>

      そして、そのセグメントを破棄してリターンする。

      もし SND.UNA =< SEG.ACK =< SND.NXT ならば、ACKを受信で
      きる。

  二番目に RST ビットをチェックする。

    もし RST ビットが設定されていたら、

      もし ACK を受信可能ならば、ユーザに "エラー: コネクションリ
      セット" を通知し、セグメントを破棄し、CLOSED 状態に遷移し、
      TCB を削除してリターンする。さもなくば (ACK 不可)、セグメン
      トを破棄してリターンする。

  三番目にセキュリティと優先度をチェックする。

    もしセグメント中のセキュリティ/コンパートメントが、TCB 中のセ
    キュリティ/コンパートメントと正確に一致していなければ、以下の
    リセットを送信する。

      もし ACK が存在するならば、

        <SEQ=SEG.ACK><CTL=RST>

      さもなくば

        <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>

    もし ACK が存在するならば

      セグメント中の優先度は、TCB 中の優先度と一致しなければならな
      い。もし一致しなければ、以下のリセットを送信する。

        <SEQ=SEG.ACK><CTL=RST>

    もし ACK が存在しないならば、

      もしセグメント中の優先度が TCB 中の優先度よりも高く、もしユ
      ーザやシステムによって許可されているならば、TCB 中の優先度を
      セグメント中の優先度に上げる。もし優先度を上げることを許可さ
      れていないならば、以下のリセットを送信する。

        <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>

      もしセグメント中の優先度が 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 を生成して送信する。

      <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>

    送信のためにキューイングされたデータや制御を含んでもよい。もし
    セグメント中に他の制御やテキストが存在するならば、以下の六番目
    のステップの処理を継続して行い、URG ビットをチェックする。さも
    なくばリターン。

    さもなくば SYN-RECEIVED 状態に遷移し、以下の SYN,ACK セグメン
    トを生成して送信する。

      <SEQ=ISS><ACK=RCV.NXT><CTL=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 ビットが設定されていなけれ
      ば。もし設定されているなら、そのセグメントを破棄してリターン
      する)。

        <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>

      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 状
        態に遷移して処理を継続する。

          もし肯定応答のセグメントが受信不可ならば、以下のリセット
          を生成して送信する。

            <SEQ=SEG.ACK><CTL=RST>

      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 を送信する。

        <SEQ=SND.NXT><ACK=RCV.NXT><CTL=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.

最初へ