コンピュータネットワークノート-4(TCPプロトコルの詳細な説明)
TCPヘッダー
TCPヘッダー構造を図に示します。
-
16ビットのポート番号には、送信元ポートと宛先ポートが格納されます。TCP通信の場合、クライアントはシステムによって自動的に選択された一時ポート番号を使用し、サーバーは既知のサービスポート番号を使用します(すべての既知のサービスで使用されるポート番号は/ etc / servicesで定義されます)。
-
32ビットのシーケンス番号(送信方向のバイトストリームの各バイトの番号)。初期シーケンス番号は、システムによって初期化されたランダム値ISN(初期シーケンス番号)です。TCPセグメントにはデータが含まれており、そのシーケンス番号の値は最初のバイトのシーケンス番号の値であることに注意してください。
-
32ビットの確認番号。AとBがTCP通信を行っている場合、Aから送信されたTCPセグメントには、独自のシリアル番号が含まれているだけでなく、Bから送信されたTCPセグメントの確認番号も含まれています。確認応答番号の値は、受信したTCPセグメントのシーケンス番号の値に1を加えたものです。
-
4ビットヘッダーの長さは、TCPヘッダーの4バイト数を示します。最大TCPヘッダーは15 * 4バイトです。
-
6ビットフラグには次の項目が含まれます。
- URGフラグは、緊急ポインタが有効かどうかを示します。
- ACKフラグは、確認番号が有効かどうかを示します。ACKフラグを運ぶTCPセグメントは、確認応答セグメントと呼ばれます。
- PSHフラグは、受信アプリケーションがTCP受信バッファー領域からデータをすぐに読み取って、後続のデータ用のスペースを確保する必要があることを示します(読み取られない場合は、常にTCP受信バッファー領域に留まります)。
- RST記号は、相手方が接続を再確立する必要があることを示します。RSTフラグを保持するTCPセグメントは、リセットセグメントと呼ばれます。
- SYNフラグは、接続が要求されていることを示します。これは同期セグメントと呼ばれます。
- FINフラグは、接続が閉じられることを相手に通知することを示します。これは、エンドセグメントと呼ばれます。
-
16ビットのウィンドウサイズはフロー制御に使用されます。ここでのウィンドウはレシーバーウィンドウ(RWND)です。これは、ローカルエンドの受信バッファ領域に収容できるデータのバイト数を相手に通知するために使用されます。これにより、相手はデータの送信速度を制御できます。
-
16ビットのチェックサムは送信側によって入力され、受信側はCRCアルゴリズムを使用してチェックします(ヘッダーをチェックするだけでなく、データもチェックします)。
-
16ビットの緊急ポインタはオフセットです。セグメントシーケンス番号の値とこのオフセットは、送信者が緊急データを受信者に送信するために使用する緊急データのシーケンス番号を表します。
上記は20バイトを占める固定フィールドであり、次の40バイトはオプションフィールドです。
TCPスリーウェイハンドシェイク
TCPスリーウェイハンドシェイクプロセスを図に示します。
スリーウェイハンドシェイクは、実際には、TCP接続が確立されたときに、クライアントとサーバーが合計3つのパケットを送信する必要があることを意味します。スリーウェイハンドシェイクの主な機能は、両当事者の受信および送信機能が正常であるかどうかを確認し、後続の信頼できる送信に備えるために独自の初期化シーケンス番号を指定することです。指定されたポートの本質は、実際にはサーバーに接続され、TCP接続を確立し、シーケンス番号と確認応答番号の両方を接続して同期し、TCPウィンドウサイズ情報を交換します。
クライアントがクローズ状態にあり、サーバーが最初にリッスン状態にあると仮定すると、スリーウェイハンドシェイクの詳細なプロセスは次のようになります。
-
最初のハンドシェイク:クライアントはSYNメッセージをサーバーに送信し、クライアントの初期シーケンス番号ISNを示します。このとき、クライアントはSYN_SENT状態です。
ヘッダーSYN = 1の同期ビット、初期シーケンス番号seq = x、SYN = 1のセグメントはデータを伝送できませんが、シーケンス番号を消費します。
-
2番目のハンドシェイク:サーバーはクライアントからSYNメッセージを受信した後、独自のSYNメッセージで応答し、独自の初期化シーケンス番号ISNも指定します。同時に、クライアントのISN + 1がACK値として使用され、クライアントのSYNを受信し、サーバーがSYN_RCVD状態にあることを示します。
確認セグメントでは、SYN = 1、ACK = 1、確認番号ack = x + 1、初期シーケンス番号seq = yです。
-
3番目のハンドシェイク:クライアントはSYNメッセージを受信した後、ACKメッセージを送信します。もちろん、サーバーのISN + 1はACK値と同じであり、サーバーのSYNメッセージを受信したことを示します。クライアントESTABLISHED状態です。サーバーがACKメッセージを受信すると、サーバーもESTABLISHED状態になります。この時点で、2者は接続を確立しています。
確認応答セグメントACK = 1、確認応答番号ack = y + 1、シーケンス番号seq = x + 1(最初はseq = xであるため、2番目のセグメントは+1である必要があります)、ACKセグメントはデータを伝送でき、データの伝送は消費しませんシリアル番号。
最初のSYNを送信する側はアクティブオープンを実行し、このSYNを受信して次のSYNに送り返すもう一方の端はパッシブオープンを実行します。
ソケットプログラミングでは、クライアントがconnect()を実行すると、スリーウェイハンドシェイクがトリガーされます。
「スリーウェイ」ハンドシェイクの理由
各ハンドシェイクの目的は次のとおりです。
- 最初のハンドシェイク:クライアントはネットワークパケットを送信し、サーバーはそれを受信します。
このようにして、サーバーは、クライアントの送信能力とサーバーの受信能力が正常であると結論付けることができます。 - 2番目のハンドシェイク:サーバーがパッケージを送信し、クライアントがパッケージを受信します。
このようにして、クライアントは、サーバーの受信および送信機能とクライアントの受信および送信機能が正常であると結論付けることができます。ただし、現時点では、サーバーはクライアントの受信機能が正常かどうかを確認できません。 - 3番目のハンドシェイク:クライアントがパッケージを送信し、サーバーがパッケージを受信します。
このようにして、サーバーは、クライアントの送受信機能が正常であり、サーバー自体の送受信機能も正常であると結論付けることができます。
したがって、両当事者の送受信機能が正常であるかどうかを確認するには、スリーウェイハンドシェイクが必要です。
半接続キュー
サーバーがクライアントからSYNを初めて受信すると、SYN_RCVD状態になります。この時点では、2つのパーティは完全に接続を確立していません。サーバーは、この状態の要求接続をキューに入れます。このキューを半接続キューと呼びます。
もちろん、完全に接続されたキューもあります。つまり、スリーウェイハンドシェイクが完了し、接続を確立したキューは完全に接続されたキューに配置されます。キューがいっぱいになると、パケット損失が発生する可能性があります。
SYN-ACK再送回数について:
サーバがSYN-ACKパケットを送信した後、クライアント確認パケットを受信しなかった場合、サーバは初めて再送し、一定時間待機し、クライアント確認を受信しません。パケットを送信してから、2回目の再送信を実行します。再送信の数がシステムによって指定された再送信の最大数を超える場合、システムは接続情報を半接続キューから削除します。
各再送信の待機時間は必ずしも同じではなく、一般に指数関数的に増加することに注意してください。たとえば、間隔時間は1秒、2秒、4秒、8秒です。
ISN
一方の端がSYNを送信して接続を確立すると、接続の初期シーケンス番号が選択されます。ISNは時間の経過とともに変化するため、接続ごとに異なるISNがあります。ISNは、4ミリ秒ごとに1ずつ増加する32ビットカウンタと見なすことができます。このようにシーケンス番号を選択する目的は、ネットワーク内の遅延パケットが将来送信されないようにすることです。これにより、接続されたパーティが誤って解釈する可能性があります。
スリーウェイハンドシェイクの重要な機能の1つは、クライアントとサーバーがISN(初期シーケンス番号)を交換することです。これにより、相手は次にデータを受信するときにシーケンス番号に従ってデータを組み立てる方法を知ることができます。ISNが修正されている場合、攻撃者は後続の確認番号を簡単に推測できるため、ISNは動的に生成されます。
データを運ぶ
3番目のハンドシェイクはデータを伝送できます。ただし、1回目と2回目のハンドシェイクではデータを伝送できません
最初のハンドシェイクがデータを運ぶことができる場合、誰かが悪意を持ってサーバーを攻撃したい場合、彼は毎回最初のハンドシェイクのSYNメッセージに大量のデータを入れます。攻撃者はサーバーの受信機能と送信機能が正常であるかどうかを単に無視し、SYNメッセージの送信を必死に繰り返すため、サーバーはこれらのメッセージを受信するために多くの時間とメモリスペースを費やします。
SYN攻撃
サーバー側のリソース割り当ては2回目のハンドシェイク中に割り当てられ、クライアント側のリソースは3ウェイハンドシェイクの完了時に割り当てられるため、サーバーはSYNフラッド攻撃に対して脆弱です。
SYN攻撃は、クライアントが存在しない多数のIPアドレスを短時間で偽造し、SYNパケットをサーバーに継続的に送信し、サーバーが確認パケットで応答し、クライアントが確認するのを待つことです。送信元アドレスが存在しない場合、サーバーはタイムアウトが経過するまで再送信する必要があります。これらの偽造されたSYNパケットは、接続されていないキューを長時間占有し、キューがいっぱいであるため通常のSYN要求が破棄され、ネットワークの輻輳やシステムの麻痺が発生します。 。SYN攻撃は、典型的なDoS / DDoS攻撃です。
SYN攻撃を検出すると非常に便利です。サーバー上に多数の半接続状態が見られる場合、特に送信元IPアドレスがランダムである場合、これは基本的にSYN攻撃であると結論付けることができます。Linux / Unixでは、システムに付属のnetstatコマンドを使用してSYN攻撃を検出できます。
netstat -n -p TCP | grep SYN_RECV
SYN攻撃から防御するための一般的な方法は次のとおりです。
- SYNタイムアウト時間を短縮します
- 半接続の最大数を増やす
- フィルタゲートウェイ保護
- SYNクッキーテクノロジー
TCPは4回振った
TCPの4つの
手の波のプロセスを図に示します。接続の確立には3つのハンドシェイクが必要であり、接続の終了には4つの手の波が必要です。これは、TCPハーフクローズ結果(ハーフクローズ)が原因で発生します。実際、いわゆるハーフクローズとは、TCPが、接続の一方の端が送信を終了した後、もう一方の端からデータを受信する機能を提供することです。
クライアントまたはサーバーのいずれかがアクティブにウェーブアクションを開始できます。クライアントが最初にシャットダウン要求を開始した場合、最初は両方のパーティがESTABLISHED状態になっています。4回振るプロセスは次のとおりです。
-
初めてWave:クライアントは、メッセージで指定されたシリアル番号を使用してFINメッセージを送信します。このとき、クライアントはFIN_WAIT1状態です。
つまり、接続解放セグメント(FIN = 1、シーケンス番号seq = u)が送信され、データが再び停止され、TCP接続がアクティブに閉じられ、FIN_WAIT1(終了待機1)状態に入り、待機します。サーバーの確認。
-
第2波:FINを受信した後、サーバーはACKメッセージを送信し、クライアントのシリアル番号値+ 1をACKメッセージのシリアル番号値として使用して、クライアントのメッセージが受信されたことを示します。この時点で、サーバーはCLOSE_WAIT状態。
つまり、サーバーは接続解放セグメントを受信した後、確認応答セグメント(ACK = 1、確認番号ack = u + 1、シーケンス番号seq = v)を送信し、サーバーはCLOSE_WAIT(クローズ待機)状態になります。 、TCPハーフクローズ状態では、クライアントからサーバーへの接続が解放されます。サーバーから確認を受信した後、クライアントはFIN_WAIT2(終了待機2)状態に入り、サーバーから送信された接続解放メッセージセグメントを待機します。
-
3番目のウェーブ:クライアントの最初のウェーブと同様に、サーバーも切断する場合は、FINメッセージを送信してシリアル番号を指定します。このとき、サーバーはLAST_ACKの状態です。
つまり、サーバーにはクライアントに送信するデータがなく、サーバーは接続解放セグメント(FIN = 1、ACK = 1、シーケンス番号seq = w、確認番号ack = u + 1)を送信し、サーバーはLAST_ACKに入ります。 (最終確認))ステータス、クライアントからの確認を待っています。
-
第4波:FINを受信した後、クライアントは応答としてACKメッセージを送信し、サーバーのシリアル番号値+1を自身のACKメッセージのシリアル番号値として使用します。この時点で、クライアントはTIME_WAIT状態にあります。サーバーが独自のACKメッセージを受信した後、確実にCLOSED状態になるまでにはしばらく時間がかかります。サーバーは、ACKメッセージを受信すると、接続を閉じてCLOSED状態になります。
つまり、クライアントはサーバーから接続解放セグメントを受信した後、確認応答セグメント(ACK = 1、seq = u + 1、ack = w + 1)を送信し、クライアントはTIME_WAIT(待機時間)状態に入ります。このとき、TCPは解放されず、待機タイマーで設定された2MSLが経過すると、クライアントはCLOSED状態になります。
FINを受信するということは、この方向にデータフローがないことを意味するだけです。クライアントがアクティブシャットダウンを実行してTIME_WAITに入るのは正常です。サーバーは通常パッシブシャットダウンを実行し、TIME_WAIT状態にはなりません。
ソケットプログラミングでは、任意のパーティがclose()操作を実行してwave操作を生成します。
「4回」手を振る理由
サーバーは、クライアントからSYN接続要求メッセージを受信すると、SYN + ACKメッセージを直接送信できます。ACKメッセージは応答に使用され、SYNメッセージは同期に使用されます。ただし、接続が閉じられたとき、サーバーがFINメッセージを受信しても、すぐにSOCKETを閉じない場合があるため、最初にACKメッセージで応答し、クライアントに「送信したFINメッセージを受信しました」と伝えることしかできません。サーバーのすべてのメッセージが送信された後でないと、FINメッセージを送信できないため、一緒に送信することはできません。したがって、4つの波が必要です。
TIME_WAITステータス
特定の各TCP実装は、メッセージセグメントの最大ライフタイムMSL(Maximum Segment Lifetime)を選択する必要があります。これは、メッセージセグメントが破棄されるまでのネットワーク内の最長時間です。TCPセグメントはIPデータグラムとしてネットワークで送信され、IPデータグラムにはその存続期間を制限するTTLフィールドがあるため、この時間は制限されます。
特定の実装の特定のMSL値の場合、処理の原則は次のとおりです。TCPがアクティブクローズを実行して最後のACKを送り返すとき、接続はMSLの2倍の間TIME_WAIT状態に留まる必要があります。これにより、TCPは最後のACKを再度送信して、このACKが失われるのを防ぐことができます(もう一方の端がタイムアウトして最後のFINを再送信します)。
この2MSL待機の別の結果は、この接続を定義するソケット(クライアントのIPアドレスとポート番号、サーバーのIPアドレスとポート番号)が、このTCP接続の2MSL待機期間中に使用できなくなることです。この接続は、2MSLの終了後にのみ使用できます。
2MSLの意味を待っています
クライアントによって送信された最後のACKセグメントがサーバーに到達できるようにするため。このACKが失われる可能性があるため、LAST-ACK状態のサーバーはFIN-ACK確認メッセージを受信できません。サーバーはタイムアウト後にFIN-ACKを再送信し、クライアントは確認応答を再送信して待機タイマーを再開します。最後に、クライアントとサーバーの両方を正常にシャットダウンできます。クライアントが2MSLを待たずに、ACKを送信した直後にクロージャを解放するとします。ACKが失われると、サーバーは通常、閉じた接続状態に入ることができません。
2つの理由:
-
クライアントによって送信された最後のACKセグメントがサーバーに到達できることを確認します。
このACKセグメントが失われる可能性があるため、LAST-ACK状態のBは送信されたFIN + ACKセグメントの確認を受信できません。サーバーは時間の経過とともにFIN + ACKセグメントを再送信し、クライアントはこの再送信されたFIN + ACKを受信した後に送信できます。 2MSL内のセグメントでは、クライアントは確認応答を再送信し、2MSLタイマーを再起動し、最後にクライアントとサーバーの両方がCLOSED状態になります。クライアントがTIME-WAIT状態の場合、しばらく待たずに接続を解放します。 ACKセグメントを送信した直後は、サーバーから再送されたFIN + ACKセグメントを受信できないため、確認セグメントは再度送信されず、サーバーは正常ではありません。CLOSED状態になります。 -
この接続に「失敗した接続要求メッセージセグメント」が表示されないようにします。
クライアントが最後のACKセグメントの送信を終了した後、2MSLの後、この接続の期間中に生成されたすべてのセグメントがネットワークから消えて、次の新しい接続に表示されない可能性があります。古い接続要求セグメント。
TCP状態転送プロセス
TCPの状態遷移プロセスを図に示します。
太い点線はサーバー側接続の状態遷移を表し、太い実線はクライアント接続の状態遷移を表します。
TCPの信頼性
TCPは、シーケンス番号、確認応答応答、タイムアウト再送信、ウィンドウ制御、輻輳制御などのメカニズムを使用して、信頼性を確保します。
シーケンス番号、確認応答、タイムアウト再送信
データが受信者に到着すると、受信者はデータセグメントが受信されたことを示す確認応答を送信する必要があり、確認シーケンス番号は次に受信する必要のあるデータシーケンス番号を示します。送信者が確認応答を遅れて受信しない場合は、送信データが失われたか、確認応答が失われた可能性があります。このとき、送信者は一定時間待ってから再送信します。
ウィンドウ制御と高速再送制御/高速再送(繰り返し確認応答)
TCPはウィンドウ制御を使用して伝送速度を上げます。つまり、ウィンドウサイズ内では、応答を待って次のデータを送信する必要はありません。ウィンドウサイズは、データを送信し続けることができる最大値です。確認を待たずに。ウィンドウコントロールを使用しない場合は、確認応答を受信していないすべてのデータを再送信する必要があります。
ウィンドウ制御を使用して、データセグメント1001〜2000が失われた場合、後続のデータが送信されるたびに、確認応答はシーケンス番号1001の応答を継続的に送信し、1001からデータを受信することを示します。送信者は同じ応答を3回受信し、すぐに再送信されます。
輻輳制御
ウィンドウを大きく設定し、送信者が継続的に大量のデータを送信すると、ネットワークの輻輳やネットワークの麻痺を引き起こす可能性があります。したがって、TCPはこの状況を防ぐために輻輳制御を実行します。
- スロースタート(スロースタート):輻輳ウィンドウ(cwnd)を定義し、最初にウィンドウサイズを1に設定し(通常、サイズを送信者の最大データセグメントサイズである2〜4 SMSSに設定します)、確認応答を受信します毎回(rtt後)、輻輳ウィンドウサイズ* 2。
- 輻輳回避:スロースタートしきい値(ssthresh)を設定します。通常、最初は65536に設定します(図の16)。輻輳回避とは、輻輳ウィンドウのサイズがこのしきい値に達すると、輻輳ウィンドウの値が指数関数的に増加するのではなく、輻輳を回避するために増分的に増加することを意味します(各確認応答/各rtt、輻輳ウィンドウサイズ+1)。
メッセージセグメントのタイムアウト再送信を輻輳と見なし、タイムアウト再送信が発生したら、最初にしきい値を現在のウィンドウサイズの半分に設定し、ウィンドウサイズを初期値1に設定してから、低速に再入力する必要があります。プロセスを開始します。 - 高速再送:確認応答を3回繰り返した場合(高速再送制御)は、3つのメッセージセグメントを受信したが、前のセグメントが失われ、すぐに再送されることを意味します。高速再送信と高速リカバリのプロセスは次のとおりです
。1。3番目の繰り返し確認セグメントを受信したら、ssthresh、ssthresh = max(FlightSize / 2、2 * SMSS)を変更し、失われたセグメントcwnd = ssthresh +をすぐに再送信します。 3 * SMSS
2.重複する確認メッセージセグメントを受信するたびに、cwnd = cwnd + SMSS。この時点で、送信者は新しいTCPセグメントを送信できます(新しいcwndで許可されている場合)。
3.新しいデータの確認を受け取ったら、cwnd = ssthreshを設定します(ssthreshは、最初のステップで計算された新しいスロースタートしきい値です)。
これは達成できます。TCP通信中、ネットワークスループットは徐々に増加し、輻輳によってスループットが低下し、その後ゆっくりと増加するプロセスに入ると、ネットワークが簡単に麻痺することはありません。
この記事で説明されている輻輳制御アルゴリズムは時代遅れであり、現在はGoogleのBBRアルゴリズムが一般的に使用されています。
BBRアルゴリズム
BBRアルゴリズムには2つの特徴があります。
- フィードバックが不十分です。たとえば、Cubicは、3次方程式の凸凹曲線に基づいて高いウィンドウ拡張メカニズムを実装しましたが、この鋸歯状のドロップは強すぎ、ブロッキングを回避する戦略は保守的すぎます(暴力的保守的) 。
- 輻輳アルゴリズムが引き継がれます
。TCP輻輳制御メカニズムがパケット損失(つまり、RTOまたはN回の繰り返しACKなど)を検出すると、TCPは輻輳制御アルゴリズムを完全に引き継ぎ、輻輳ウィンドウを単独で制御します。ただし、問題は、このいわゆるパケット損失が実際のパケット損失ではない可能性があることです。TCPがパケット損失を考慮するだけです。
一般的に、BBRの前の輻輳制御ロジックは、実行プロセスの2つの段階、つまり正常段階と異常段階に分けられます。正常フェーズでは、TCPモジュラー輻輳制御アルゴリズムがウィンドウの調整を支配します。異常フェーズでは、TCPコア輻輳制御ステートマシンが輻輳制御アルゴリズムからウィンドウの計算を引き継ぎます。ロジックは次のとおりです。
static void tcp_cong_control(struct sock *sk, u32 ack, u32 acked_sacked, int flag)
{
if (tcp_in_cwnd_reduction(sk)) { // 异常模式
/* Reduce cwnd if state mandates */
// 在进入窗口下降逻辑之前,还需要tcp_fastretrans_alert来搜集异常信息并处理异常过程。
tcp_cwnd_reduction(sk, acked_sacked, flag);
} else if (tcp_may_raise_cwnd(sk, flag)) { // 正常模式或者安全的异常模式!
/* Advance cwnd if state allows */
tcp_cong_avoid(sk, ack, acked_sacked);
}
tcp_update_pacing_rate(sk);
}
BBRは、輻輳制御ステートマシンが異常モードで引き継ぐことを許可しなくなりました。
static void tcp_cong_control(struct sock *sk, u32 ack, u32 acked_sacked, int flag, const struct rate_sample *rs)
{
const struct inet_connection_sock *icsk = inet_csk(sk);
// 这里是新逻辑,如果回调中宣称自己有能力解决任何拥塞问题,那么交给它
if (icsk->icsk_ca_ops->cong_control) {
icsk->icsk_ca_ops->cong_control(sk, rs);
// 直接return!TCP核心不再过问。
return;
}
// 这是老的逻辑。
if (tcp_in_cwnd_reduction(sk)) {
/* Reduce cwnd if state mandates */
// 如果不是Open状态...记住,tcp_cwnd_reduction并不受拥塞控制算法控制
tcp_cwnd_reduction(sk, acked_sacked, flag);
} else if (tcp_may_raise_cwnd(sk, flag)) {
/* Advance cwnd if state allows */
tcp_cong_avoid(sk, ack, acked_sacked);
}
tcp_update_pacing_rate(sk);
}
BBRは、接続の時間ウィンドウで最大帯域幅max-bwと最小RTT min-rttを継続的に収集し、これに基づいて伝送速度と輻輳ウィンドウを計算し、フィードバックの実際の帯域幅bwとmaxに従ってゲイン係数を調整します。 -rtt。
BBRアルゴリズムは、不要なエイリアシングを排除します。この種ののこぎり波は、BBR以前のTCPの電源にすぎません。さまざまなアルゴリズムにより、ウィンドウが盲目的に増加します。TCPがパケット損失が発生したと判断すると(実際のパケット損失ではない場合があります。したがって、さまざまな複雑なメカニズムがあります。たとえば、DSACKなど...)、ssthreshを離れた後、すべてのロジックが引き継がれ、ギザギザの歯の先端がここにあります。実際、鋸歯は、輻輳イベントが発生したときに、TCP輻輳ステートマシン制御ロジックとTCP輻輳制御アルゴリズムの間の「ワークハンドオーバー」によって形成されます。BBRアルゴリズムはこの不要なハンドオーバーをキャンセルするため、鋸歯は自然に鈍くなります。平らになりました。
VegasやCUBICなどが輻輳を検出できないわけではありませんが、TCPはそれらにフルパワーを提供しません。これは、実際には、ssthreshの概念など、元のTCP実装での慣行である可能性がありますが、実際には多くのアルゴリズムでは必要ありません。BBRはssthreshを使用しません(ssthreshは、輻輳アルゴリズムとTCP輻輳ステートマシン間の結合を反映します。BBRにはこの結合がないため、ssthreshは必要ありません)。
4つの手を振るドロースリーウェイハンドシェイクエイプバレーの記事