インターネット上でデータを送受信する際、ネットワークの混雑や障害により、パケットが途中で失われることがあります。このような状況でも確実にデータを届けるために、TCPには再送(Retransmission)という仕組みが備わっています。
再送制御はTCPの信頼性を支える根幹的な機能であり、パケットロスが発生しても通信を継続できる仕組みを提供するでしょう。タイムアウトによる再送や高速再送など、状況に応じた複数のメカニズムが組み合わさって動作しています。
本記事では、TCPの再送の基本的な仕組みから、再送タイムアウト(RTO)の計算方法、高速再送の詳細、そして再送制御の設定と調整方法まで、詳しく解説していきます。
TCPの再送とは何か?基本的な仕組みと必要性
それではまず、TCPの再送制御の基本について解説していきます。
パケットロスと再送の関係
パケットロスとは、送信したデータパケットが宛先に届かずに失われる現象です。ネットワーク機器のバッファ溢れ、回線の物理的な障害、電波干渉など、様々な原因によって発生するでしょう。
IPはベストエフォート型のプロトコルであり、パケットの到達を保証しません。パケットが失われても、IP自身はその事実を送信側に通知しないのです。そのため、上位層のTCPがパケットロスを検出し、失われたデータを再送する仕組みを提供しています。
TCPは確認応答(ACK)の受信有無によってパケットロスを検出します。送信したデータに対してACKが一定時間内に返ってこなければ、パケットが失われたと判断して再送を行う仕組みです。
TCPの再送制御により、パケットロスが発生しても最終的にすべてのデータが確実に届けられます。これがTCPを信頼性の高いプロトコルたらしめる重要な機能です。
再送制御の基本動作
TCPが再送制御を行う際の基本的な流れを理解しておくことは重要でしょう。送信側はデータを送信すると同時に、再送タイマーを起動します。このタイマーが満了するまでにACKが届かない場合、パケットロスと判断して再送を開始するのです。
再送されたパケットは元のパケットと同じシーケンス番号を持ちます。受信側は、シーケンス番号によってすでに受信済みのデータか、新しいデータかを判断できるでしょう。重複して受信したパケットは自動的に破棄されます。
再送後もACKが返ってこない場合は、タイムアウト値を指数関数的に増加させながら複数回の再送を試みます。最大再送回数に達すると、コネクションが異常終了するのです。
【再送制御の基本的な流れ】
1. データ送信 → 再送タイマー起動
2. ACK受信 → タイマーリセット(正常)
3. タイムアウト → パケットロスと判断
4. データ再送 → タイムアウト値を2倍に
5. ACK受信まで繰り返し(最大再送回数まで)
再送の種類
TCPの再送には主に2種類の仕組みがあります。タイムアウト再送と高速再送(Fast Retransmit)です。
タイムアウト再送は、再送タイマーが満了したときに発動する基本的な仕組みでしょう。一方、高速再送は重複ACKを手がかりにタイムアウトを待たずに即座に再送を行う仕組みです。高速再送の方が早く対応できるため、通常はこちらが優先されます。
| 再送種別 | 発動条件 | 速度 | 特徴 |
|---|---|---|---|
| タイムアウト再送 | RTOタイマー満了 | 遅い | 確実だが遅延大きい |
| 高速再送 | 重複ACK 3個受信 | 速い | 早期検出・迅速回復 |
| SACK再送 | SACK情報に基づく | 速い | 必要なセグメントのみ再送 |
再送タイムアウト(RTO)の仕組みと計算方法
続いては、再送制御の核心である再送タイムアウト(RTO)について確認していきます。
RTOとは何か
RTO(Retransmission Timeout)は、送信したデータに対するACKを待つ最大時間です。この時間内にACKが届かない場合、TCPはパケットロスと判断して再送を開始するでしょう。
RTOの設定は非常に重要です。短すぎると、まだ届いていないだけのパケットを不必要に再送してしまいます(偽のロス検出)。長すぎると、実際にパケットが失われた際の回復に時間がかかり、通信効率が大幅に低下するのです。
そのため、TCPはRTTの測定値をもとにRTOを動的に計算します。ネットワークの状況に合わせてRTOを適応的に調整することで、効率的な再送制御が実現されています。
RTTの測定とRTOの計算
RTT(Round Trip Time)とは、データを送信してからACKが返ってくるまでの往復時間です。RTOはこのRTTをもとに計算されるでしょう。
TCPでは、Jacobsonのアルゴリズムを用いて平滑化RTT(SRTT)とRTTの変動値(RTTVAR)を計算し、これらからRTOを算出します。変動が大きいネットワークでは余裕を持った大きなRTOが設定され、安定したネットワークでは小さなRTOになる仕組みです。
【RTOの計算式(RFC 6298)】
初回測定時:
SRTT = RTT
RTTVAR = RTT / 2
RTO = SRTT + 4 × RTTVAR
2回目以降:
RTTVAR = (1 – β) × RTTVAR + β × |SRTT – RTT| (β = 0.25)
SRTT = (1 – α) × SRTT + α × RTT (α = 0.125)
RTO = SRTT + 4 × RTTVAR
※ RTO最小値は1秒、最大値は60秒が一般的
指数バックオフによるRTOの増加
タイムアウトによる再送が発生した後、RTOは指数バックオフ(Exponential Backoff)によって増加します。再送のたびにRTOが2倍になることで、ネットワークへの負荷を抑えながら回復を試みるでしょう。
例えば、初回のRTOが1秒だった場合、1回目の再送後は2秒、2回目の再送後は4秒、3回目は8秒というように指数関数的に増加します。これにより、ネットワークが混雑している場合に過剰な再送でさらに混雑を悪化させることを防ぐのです。
Karn’s Algorithmという重要な補正方法もあります。再送したパケットに対するACKは、RTTの計算に使用しないというルールです。再送パケットへのACKが元のパケットへのものか再送パケットへのものかが区別できないため、RTT計算に誤差が混入するのを防いでいます。
| 再送回数 | 待機時間(例) | 累積経過時間 | 動作 |
|---|---|---|---|
| 初回送信 | RTO = 1秒 | 0秒 | データ送信 |
| 1回目再送 | RTO = 2秒 | 1秒後 | タイムアウト・再送 |
| 2回目再送 | RTO = 4秒 | 3秒後 | 再送 |
| 3回目再送 | RTO = 8秒 | 7秒後 | 再送 |
| 4回目再送 | RTO = 16秒 | 15秒後 | 再送 |
高速再送(Fast Retransmit)の仕組みと動作
続いては、タイムアウトを待たずに迅速なパケット回復を実現する高速再送の仕組みを確認していきます。
高速再送が必要な理由
タイムアウト再送には大きな欠点があります。RTOはRTTよりもはるかに大きな値(通常数百ミリ秒〜数秒)が設定されるため、パケットロス発生から再送完了までに長い待機時間が生じてしまうでしょう。
特に高速ネットワークでは、この待機時間中に大量のデータが転送できたはずです。タイムアウトを待つ間、送信ウィンドウが止まってしまい、スループットが大幅に低下するのです。
高速再送はこの問題を解決するために考案されました。受信側が送信する重複ACK(Duplicate ACK)を手がかりに、タイムアウト前にパケットロスを検出して即座に再送するのです。
重複ACKの仕組み
受信側は、期待するシーケンス番号より大きいデータを受信した場合(順序が乱れた受信)、期待しているシーケンス番号に対する重複ACKを送信します。
例えば、セグメント1・2・3・4・5という順序で送信された場合に、セグメント2が失われてセグメント3が先に届いたとします。受信側はセグメント2を期待しているため、セグメント3を受信してもセグメント1に対するACK(ACK=2を要求)を重複して送り続けるでしょう。
送信側が3つの重複ACKを受信すると、そのシーケンス番号のパケットが失われたと判断し、タイムアウトを待たずに即座に再送します。3つという閾値は、パケットの順序入れ替えによる誤検出を防ぎつつ、迅速な対応を可能にするバランスのとれた値なのです。
高速再送は、タイムアウト再送と比べて大幅に早くパケットロスから回復できるため、TCPのスループット向上に大きく貢献しています。特に高帯域・低遅延ネットワークでその効果が顕著に現れます。
SACKによる選択的再送
SACK(Selective Acknowledgment)は、受信側が受け取ったデータの範囲を詳細に通知するオプション機能です。通常のACKは「ここまで受け取った」という累積確認しか提供しませんが、SACKは「この範囲のデータは受け取ったが、この部分が欠けている」という詳細な情報を提供できます。
SACKを使用することで、複数のパケットロスが発生した場合でも、失われたセグメントのみを選択的に再送できるでしょう。SACKなしの場合、確認されていないセグメントをすべて再送する必要がありましたが、SACKにより不要な再送を大幅に削減できます。
【SACKの動作例】
送信:セグメント1・2・3・4・5
ロス:セグメント2・4
通常のACK:ACK=2(1まで受信確認)
→ 2・3・4・5をすべて再送する必要あり
SACKあり:ACK=2、SACK=3(3は受信済み)、SACK=5(5は受信済み)
→ 2と4だけを再送すればよい
再送制御の設定と調整方法
続いては、実際のシステムにおける再送制御の設定と最適化について確認していきます。
OSレベルの再送設定パラメータ
Linuxシステムでは、TCPの再送制御に関連する様々なカーネルパラメータを調整できます。これらの設定を適切に行うことで、特定のネットワーク環境や用途に最適化した通信性能を得られるでしょう。
最大再送回数を制御するパラメータとして、tcp_retries1とtcp_retries2があります。tcp_retries1はネットワーク層に問題を報告するまでの再送回数(デフォルト3回)、tcp_retries2はコネクションを強制終了するまでの最大再送回数(デフォルト15回)を設定するのです。
【Linuxの主要な再送関連パラメータ】
tcp_retries1:ルート問題報告前の再送回数(デフォルト:3)
tcp_retries2:コネクション切断前の最大再送回数(デフォルト:15)
tcp_syn_retries:SYNパケットの最大再送回数(デフォルト:6)
tcp_synack_retries:SYN-ACKの最大再送回数(デフォルト:5)
確認コマンド:sysctl net.ipv4.tcp_retries2
ネットワーク環境に応じた調整
再送制御の最適な設定は、ネットワーク環境によって異なります。データセンター内の低遅延ネットワークと、広域インターネット上の長距離通信では、適切なパラメータが大きく異なるでしょう。
低遅延環境では、RTOの最小値を小さくすることで迅速な回復が可能になります。一方、高遅延・高帯域の環境では、RTOを適切に大きく設定しないと、遅延による誤検出で不要な再送が発生してしまうのです。
また、パケットロス率が高い無線ネットワーク環境では、再送回数の閾値や輻輳制御アルゴリズムの選択も重要な要素になります。BBRなど最新の輻輳制御アルゴリズムは、このような環境での再送動作も改善しているでしょう。
Wiresharkを使った再送の可視化と分析
Wiresharkなどのパケットキャプチャツールを使うと、実際の再送パケットを可視化して詳細な分析が行えます。TCPの再送問題を調査する際に非常に有効なアプローチでしょう。
Wiresharkでは、TCPの再送パケットが自動的に識別され、色付きで表示されます。「TCP Retransmission」「TCP Fast Retransmission」「TCP Spurious Retransmission(偽の再送)」などのラベルが付与され、どの種類の再送が発生しているかを一目で確認できるのです。
| Wiresharkの表示 | 意味 | 考えられる原因 |
|---|---|---|
| TCP Retransmission | タイムアウト再送 | 重大なパケットロス・高遅延 |
| TCP Fast Retransmission | 高速再送 | 軽微なパケットロス |
| TCP Spurious Retransmission | 不要な再送 | RTO設定が小さすぎる |
| TCP Dup ACK | 重複ACK | パケット順序の乱れ・ロス |
| TCP Out-of-Order | 順序外パケット受信 | マルチパス・パケット並び替え |
まとめ
TCPの再送制御は、パケットロスが発生した際にデータを確実に届けるための重要な仕組みです。再送タイムアウト(RTO)をRTTの測定値から動的に計算し、指数バックオフで段階的に再送間隔を延ばすことで、ネットワークへの過負荷を防ぎながら信頼性を確保しています。
高速再送は、重複ACKを手がかりにタイムアウトを待たずに迅速なパケット回復を実現し、通信スループットの向上に大きく貢献するでしょう。さらにSACKオプションを活用することで、複数のパケットロスが発生した場合でも効率的な回復が可能になります。
再送制御の仕組みを理解しておくことは、ネットワークのトラブルシューティングや性能チューニングにおいて非常に重要なスキルです。Wiresharkなどのツールと組み合わせることで、実際の通信における再送の発生状況を分析し、最適な設定を見つけることができるでしょう。