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

7. 輻輳制御 (Congestion Control)

SCTPは、ネットワーク輻輳を回避し、ネットワークリソースの公平な共有を確保するために、TCPと類似した輻輳制御メカニズムを使用します。

7.1. SCTPとTCP輻輳制御の違い (SCTP Differences from TCP Congestion Control)

SCTPの輻輳制御はTCPのメカニズムに基づいていますが、以下の重要な違いがあります:

7.1.1. マルチホームとマルチパス

SCTPはマルチホームエンドポイントをサポートし、各宛先トランスポートアドレスは独立した輻輳制御パラメータを維持します:

  • 宛先ごとのcwnd: 各パスは独自の輻輳ウィンドウを持つ
  • 宛先ごとのssthresh: 各パスは独自のスロースタート閾値を持つ
  • 宛先ごとのRTO: 各パスは独自の再送信タイムアウトを持つ

これにより、SCTPは異なるパス上で独立して輻輳制御を実行できます。

7.1.2. TSNベースの確認応答

SCTPは、バイトシーケンス番号ではなくTSNを使用して確認応答します。これは次のことを意味します:

  • 輻輳ウィンドウはバイト単位で維持される
  • SACKはTSN範囲を確認する
  • cwnd更新は、TSN数ではなく確認されたバイト数に基づく

7.1.3. マルチストリーム送信

SCTPの複数のストリームは、同じアソシエーションの輻輳制御パラメータを共有します。ストリーム間に個別の輻輳制御はなく、これにより以下が保証されます:

  • すべてのストリームが帯域幅を公平に共有
  • 単一のストリームがリソースを独占することを防ぐ

7.2. SCTPスロースタートと輻輳回避 (SCTP Slow-Start and Congestion Avoidance)

SCTPの輻輳制御アルゴリズムは、TCPのスロースタートと輻輳回避の原則に従います。

7.2.1. 初期化と再起動

アソシエーションが最初に確立されたとき、またはパスがアイドル後に再起動したとき:

cwnd = min(4*MTU, max(2*MTU, 4380バイト))
ssthresh = ピアのa_rwnd

注意: 初期cwndの計算は、少なくとも2つの完全なパケットを送信できることを保証しますが、4つのMTUサイズのパケットを超えません。

7.2.2. スロースタートフェーズ

スロースタート中(cwnd <= ssthresh):

新しいデータのSACKを受信したとき:

cwnd = cwnd + min(確認されたバイト数, MTU)

ルール:

  • cwndは一度に最大1つのMTUずつ増加
  • すべての確認されたデータが現在のcwnd下で送信された場合にのみ増加
  • cwndがssthreshに達するか超えると、輻輳回避フェーズに入る

7.2.3. 輻輳回避フェーズ

cwnd > ssthreshのとき:

適切なバイトカウンティング (Appropriate Byte Counting, ABC) を使用:

RTTごとに:
partial_bytes_acked = partial_bytes_acked + 確認されたバイト数

partial_bytes_acked >= cwnd のとき:
cwnd = cwnd + MTU
partial_bytes_acked = partial_bytes_acked - cwnd

目標: RTTごとにcwndを約1 MTU増加させる。

7.2.4. 輻輳検出と応答

輻輳の信号:

  1. 再送信タイムアウト (RTOの期限切れ)
  2. 高速再送信 (4つの重複SACKを受信)

RTOタイムアウトへの応答:

ssthresh = max(cwnd/2, 4*MTU)
cwnd = 1*MTU
partial_bytes_acked = 0

高速再送信への応答:

ssthresh = max(cwnd/2, 4*MTU)
cwnd = ssthresh
partial_bytes_acked = 0

7.2.5. アイドル期間後の処理

宛先がRTO期間内にデータ送信がない場合(アイドル):

オプション1 (推奨):

cwnd = max(cwnd/2, 4*MTU)

オプション2 (保守的):

cwnd = min(4*MTU, max(2*MTU, 4380バイト))

これにより、長いアイドル期間の後に突然大量のデータを送信することを防ぎます。

7.3. パスMTU発見 (Path MTU Discovery)

SCTPエンドポイントは、パスMTU発見([RFC4821]で定義されたPacketization Layer PMTUD)を使用すべきです (SHOULD):

  • 宛先への最大利用可能MTUを決定
  • IP断片化を回避
  • データ転送効率を最適化

7.3.1. PMTU発見プロセス

  1. 初期MTU: 保守的な初期値を使用(通常、IPv4では576バイト、IPv6では1280バイト)

  2. より大きなMTUを探索:

    • "Don't Fragment"フラグを設定したパケットを送信
    • 成功した場合、より大きなMTUを試す
    • 失敗した場合(ICMP "Packet Too Big"を受信)、より小さいMTUを使用
  3. 定期的な再探索: パスの変化に適応するために、定期的により大きなMTUを試す

7.3.2. MTU更新が輻輳制御に与える影響

PMTUが増加したとき:

cwnd = (cwnd / 旧MTU) * 新MTU
ssthresh = (ssthresh / 旧MTU) * 新MTU

PMTUが減少したとき:

cwnd = (cwnd / 旧MTU) * 新MTU
ssthresh = (ssthresh / 旧MTU) * 新MTU
partial_bytes_acked = min(partial_bytes_acked, cwnd)

これにより、輻輳制御パラメータがMTUサイズと一貫した関係を維持することが保証されます。

7.3.3. 失敗処理

PMTU発見が失敗または利用できない場合:

  • 保守的なMTU値を使用
  • "Don't Fragment"フラグを使用しない
  • IP層による断片化を許可

まとめ

SCTPの輻輳制御設計は、以下の重要な要素を考慮しています:

  1. マルチパスサポート: パスごとの独立した輻輳制御
  2. TCP親和性: TCPとのネットワーク帯域幅の公平な共有
  3. マルチストリーム効率: 輻輳制御を維持しながらヘッドオブラインブロッキングを回避
  4. パス適応: PMTU発見による送信の最適化

これらのメカニズムにより、SCTPはネットワークリソースを効率的に利用しながら、他のトラフィックと公平に共存できます。