メインコンテンツまでスキップ

2. TCP Window Scale Option (TCP ウィンドウスケールオプション)

2. TCP Window Scale Option (TCP ウィンドウスケールオプション)

2.1 Introduction (序論)

ウィンドウスケール拡張は、TCPウィンドウの定義を32ビットに拡張し、スケール係数を使用して、この32ビット値をTCPヘッダーの16ビットWindowフィールド (RFC-793のSEG.WND) で伝送します。スケール係数は新しいTCPオプションWindow Scaleで伝送されます。このオプションはSYNセグメント (SYNビットがオンのセグメント) でのみ送信されるため、接続が開かれたときに各方向のウィンドウスケールが固定されます。(別の設計選択は、すべてのTCPセグメントでウィンドウスケールを指定することです。スケール係数が変更されたときにのみウィンドウスケールオプションを送信するのは誤りです。なぜなら、確認応答セグメント内のTCPオプションは確実に配信されないためです (ACKが反対方向のデータにピギーバックされる場合を除く)。接続が開かれたときにスケールを固定することの利点は、オーバーヘッドが低いことですが、欠点は、接続中にスケール係数を変更できないことです。)

最大受信ウィンドウ、したがってスケール係数は、最大受信バッファスペースによって決定されます。典型的な最新の実装では、この最大バッファスペースはデフォルトで設定されますが、TCP接続が開かれる前にユーザープログラムによってオーバーライドできます。これによりスケール係数が決定されるため、ウィンドウスケーリングのための新しいユーザーインターフェースは必要ありません。

2.2 Window Scale Option (ウィンドウスケールオプション)

3バイトのWindow ScaleオプションはTCPによってSYNセグメントで送信される場合があります。これには2つの目的があります: (1) TCPが送信と受信の両方のウィンドウスケーリングを実行する準備ができていることを示す、および (2) その受信ウィンドウに適用するスケール係数を通信する。したがって、ウィンドウをスケールする準備ができているTCPは、自身のスケール係数が1であっても、このオプションを送信する必要があります。スケール係数は2の累乗に制限され、対数的にエンコードされるため、バイナリシフト操作で実装できます。

TCP Window Scale Option (WSopt):

Kind: 3 Length: 3 bytes

+---------+---------+---------+
| Kind=3 |Length=3 |shift.cnt|
+---------+---------+---------+

このオプションは約束ではなく提案です; 両側はSYNセグメントでWindow Scaleオプションを送信して、どちらの方向でもウィンドウスケーリングを有効にする必要があります。ウィンドウスケーリングが有効になっている場合、このオプションを送信したTCPは、SEG.WNDでの送信のために、その真の受信ウィンドウ値を'shift.cnt'ビット右シフトします。値'shift.cnt'はゼロでもかまいません (スケールを提供しながら、受信ウィンドウにスケール係数1を適用する)。

このオプションは、初期`<SYN>`セグメント (つまり、SYNビットがオンでACKビットがオフのセグメント) で送信できます。`<SYN,ACK>`セグメントでも送信できますが、初期`<SYN>`セグメントでWindow Scaleオプションが受信された場合のみです。SYNビットのないセグメント内のWindow Scaleオプションは無視する必要があります。

SYN (つまり、`<SYN>`または`<SYN,ACK>`) セグメント自体のWindowフィールドはスケールされません。

2.3 Using the Window Scale Option (ウィンドウスケールオプションの使用)

ウィンドウスケーリングのモデル実装は、RFC-793 [Postel81] の表記法を使用して、次のとおりです:

  • すべてのウィンドウは、接続制御ブロックでの格納およびローカル計算のために32ビット量として扱われます。これには、送信ウィンドウ (SND.WND) および受信ウィンドウ (RCV.WND) の値、および輻輳ウィンドウが含まれます。

  • 接続状態は、着信および発信ウィンドウフィールドにそれぞれ適用される2つのウィンドウシフトカウント、Snd.Wind.ScaleおよびRcv.Wind.Scaleによって拡張されます。

  • TCPがWindow Scaleオプションを含む`<SYN>`セグメントを受信すると、`<SYN,ACK>`セグメントで独自のWindow Scaleオプションを送信します。

  • Window Scaleオプションはshift.cnt = Rで送信されます。ここで、Rは、TCPが受信ウィンドウに使用したい値です。

  • shift.cnt = Sを含むWindow ScaleオプションでSYNセグメントを受信すると、TCPはSnd.Wind.ScaleをSに設定し、Rcv.Wind.ScaleをRに設定します。そうでない場合は、Snd.Wind.ScaleとRcv.Wind.Scaleの両方をゼロに設定します。

  • SYNセグメントを除くすべての着信セグメントのヘッダーのウィンドウフィールド (SEG.WND) は、SND.WNDを更新する前に、Snd.Wind.Scaleビット左シフトされます:

    SND.WND = SEG.WND &lt;&lt; Snd.Wind.Scale

    (RFC793の他の条件が満たされていると仮定し、左シフトには"C"の表記"<<"を使用)。

  • SYNセグメントを除くすべての発信セグメントのウィンドウフィールド (SEG.WND) は、Rcv.Wind.Scaleビット右シフトされます:

    SEG.WND = RCV.WND >> Rcv.Wind.Scale.

TCPは、そのシーケンス番号がウィンドウの左端から231バイト以内にあるかどうかをテストすることにより、データセグメントが"古い"か"新しい"かを判断し、そうでない場合は、データを"古い"として破棄します。新しいデータが誤って古いと見なされないように、またその逆を確実にするために、送信者のウィンドウの左端は、受信者のウィンドウの右端から最大231離れている必要があります。送信者の右端と受信者の左端についても同様です。送信者または受信者のウィンドウの右端と左端はウィンドウサイズだけ異なり、送信者と受信者のウィンドウは最大でウィンドウサイズだけ位相がずれる可能性があるため、上記の制約は、2 * 最大ウィンドウサイズが2**31未満でなければならないことを意味します。または

max window &lt; 2**30

最大ウィンドウは2S (ここでSはスケーリングシフトカウント) に最大216 - 1 (最大未スケールウィンドウ) を掛けたものであるため、S &lt;= 14の場合、最大ウィンドウは&lt; 230であることが保証されます。したがって、シフトカウントは14に制限する必要があります (これにより230 = 1 Gbyteのウィンドウが可能になります)。shift.cnt値が14を超えるWindow Scaleオプションを受信した場合、TCPはエラーをログに記録しますが、指定された値の代わりに14を使用する必要があります。

スケール係数は、TCPヘッダーで送信されるWindowフィールドにのみ適用されます; 拡張ウィンドウを使用する各TCPは、ウィンドウ値をローカルで32ビット数として維持します。たとえば、スロースタートおよび輻輳回避によって計算される"輻輳ウィンドウ"は、スケール係数の影響を受けないため、ウィンドウスケーリングは輻輳ウィンドウに量子化を導入しません。