【Wireshark】TCP解析(Retransmission/Dup ACK など)

音声で聞く

読む前にこの記事のポイントを音声で確認できます。この音声は本記事をもとにAIツール(NotebookLM)で自動生成したもので、発音や言い回しが不自然な箇所や、内容の誤りが含まれる可能性があります。理解の補助としてご利用ください。

ネットワークの遅延などを調べるために TCP の通信をキャプチャすると、黒い背景に赤い文字で TCP Retransmission や TCP Dup ACK と表示された行を見かけることがあります。

画面イメージについて

この記事の画面は、実際の画面ではなく、検証時の画面から見るポイントを抜き出して描いたイメージです。バージョンによって、項目の並びや表記は変わります。

パケット一覧(Wireshark)画面イメージ
No.TimeInfo
395.5732711[TCP Retransmission] 443 → 58205 [PSH, ACK] Seq=5420 …
435.7773872[TCP Spurious Retransmission] 443 → 58205 [PSH, ACK] …
445.7774593[TCP Dup ACK 40#1] 58205 → 443 [ACK] Seq=1101 Ack=5429 …
535.788523[TCP Spurious Retransmission] 443 → 58205 [PSH, ACK] …
545.788586[TCP Dup ACK 50#1] 58205 → 443 [ACK] Seq=1101 Ack=6056 …
図1 TCP の注意が必要なパケットの表示。Source と Destination の列は省いています(実際の画面ではなく、表示のポイントを示したイメージです)
No.表示意味
1TCP Retransmission再送されたセグメント
2TCP Spurious Retransmissionすでに ACK されたデータの再送
3TCP Dup ACK 40#1フレーム 40 の ACK と同じ内容の重複 ACK の1つ目

これらは、Wireshark が TCP のシーケンス番号を追いかけて、再送など注意が必要なやりとりを見つけたときに付ける表示です。黒地に赤字の色分けは、Wireshark の既定の色付けルール「Bad TCP」によるものです。この記事では、TCP のシーケンス番号の考え方と、Wireshark の代表的な表示の意味を確認していきます。

この記事でわかること
  1. シーケンス番号(SEQ)とセグメント長(LEN)、確認応答番号(ACK)の関係
  2. 再送(TCP Retransmission)と再送タイムアウト(RTO)
  3. 重複 ACK(TCP Dup ACK)と高速再送(TCP Fast Retransmission)
  4. スプリアス再送(TCP Spurious Retransmission)

TCPシーケンスの考え方

TCP は、データを欠けることなく確実に宛先へ届けるために、シーケンス番号(SEQ)と確認応答番号(ACK)を使ってやりとりします。

TCP セグメントは TCP ヘッダとデータでできていて、そのデータ部分の長さを TCP セグメント長(LEN)と呼びます。シーケンス番号にこのセグメント長を足した値が、受信者が返す確認応答番号になります。確認応答番号は「次はこの番号のデータを待っています」という意味です。

シーケンス番号SEQ+TCPセグメント長LEN(データの長さ)=確認応答番号ACKEthernet14 バイトIP ヘッダ20 バイトTCP ヘッダ20 バイトデータX バイトTCPセグメント長(LEN)TCP セグメント(ヘッダ+データ)ヘッダの長さはオプションなしの場合
図2 SEQ と LEN と ACK の関係

送信者はデータを送るときに、そのデータの先頭のシーケンス番号(SEQ)とセグメント長(LEN)を受信者に伝えます。受信者はデータを受け取ると、SEQ に LEN を足した値を確認応答番号(ACK)として返します。

たとえば、送信者が SEQ=0 で 100 バイトのデータを送ると、受信者は ACK=100(0+100)を返します。送信者は次のデータを送るとき、受け取った ACK の値を SEQ にします。ACK=100 を受け取った送信者が、続けて 200 バイトのデータを SEQ=100 で送ると、受信者は ACK=300(100+200)を返します。

送信者受信者Seq=0, Len=100Ack=1000 + 100Seq=100, Len=200Ack の値を次の Seq にAck=300100 + 200
図3 SEQ と ACK のやりとり
補足
  • 実際のシーケンス番号の初期値は、接続を始めるとき(SYN)にそれぞれの端末が決めます。Wireshark は既定で、初期値を 0 とした相対的な番号(relative sequence number)で表示します。
  • SYN と FIN はデータがなくても、シーケンス番号を1つ使います。
  • Wireshark のパケットの詳細では、SEQ+LEN の値が [Next Sequence Number] として表示されます。

TCP のシーケンス番号は、次の記事でも解説しています。

>> 参考記事:【TCP】シーケンス番号とACK番号について解説

TCP再送(TCP Retransmission)

送信者が期待した ACK が返ってこないときに、送信者が同じデータを送り直すのが再送です。たとえば送信者が SEQ=100、LEN=200 のデータを送ると、送信者は受信者から ACK=300 が返ってくるのを待ちます。データが途中で失われるなどして ACK=300 が返ってこないと、送信者は同じセグメントを送り直します。このパケットが TCP Retransmission と表示されます。

送信者は、再送タイムアウト(RTO:Retransmission Timeout)が過ぎても期待した ACK が来ないと再送します。RTO は、パケットを送ってから ACK を受け取るまでの往復時間(RTT:Round Trip Time)を測り、その値から計算します。

送信者受信者SYNSYN/ACKデータACKRTTRTTSeq=100, Len=200RTOAck=300 が返ってこないSeq=100, Len=200TCP RetransmissionRTT から RTO を計算
図4 RTT から RTO を決め、RTO が過ぎたら再送する
RTO の決め方

RFC 6298 では、RTT を平滑化した値(SRTT)とそのばらつき(RTTVAR)から RTO = SRTT + 4 × RTTVAR で計算します。最小値は 1 秒が推奨で、RTO が切れて再送するたびに RTO を2倍にします(バックオフ)。実際の最小値や細かい計算は OS によって違い、1 秒より短い RTO で再送する実装もあります。

Wireshark で再送されたパケットの詳細を開くと、[SEQ/ACK analysis] の中に、元のセグメントを送ってからこの再送までにかかった時間が表示されます。

パケットの詳細(Wireshark)画面イメージ
No.TimeSourceDestinationProtocolLengthInfo
134…164.284411(伏せています)(伏せています)TCP54[TCP Retransmission] 443 → …
    Window: 8    [Calculated window size: 8]    [Window size scaling factor: -1 (unknown)]    Checksum: 0xa1bb [unverified]    [Checksum Status: Unverified]    Urgent Pointer: 0  › [Timestamps]  ▾ [SEQ/ACK analysis]    ▾ [TCP Analysis Flags]1      ▾ [Expert Info (Note/Sequence): This frame is a (suspected) retransmission]          [This frame is a (suspected) retransmission]          [Severity level: Note]          [Group: Sequence]2      [The RTO for this segment was: 0.306271000 seconds]3      [RTO based on delta from frame: 12964]
図5 再送されたパケットの SEQ/ACK analysis(実際の画面ではなく、表示内容のポイントを示したイメージです)
No.表示意味
1This frame is a (suspected) retransmissionWireshark がこのフレームを再送と判断したことを示します。「suspected(疑い)」とあるとおり、キャプチャから推定した結果です
2The RTO for this segment was: 0.306271000 seconds元のセグメントからこの再送までにかかった時間です。キャプチャした場所で見えた間隔なので、送信者が内部で持っている RTO の値そのものではありません
3RTO based on delta from frame: 12964比べた元のセグメントがフレーム 12964 であることを示します。クリックするとそのフレームに移動します

重複ACK(TCP Dup ACK)

受信者が、待っているシーケンス番号より先のデータを受け取ったときに発生します。

たとえば受信者が ACK=300 を返すと、受信者は送信者から SEQ=300 のデータが来るのを待ちます。ここで SEQ=300 のデータが途中で失われ、次の SEQ=500 のデータが先に届いたとします。受信者は SEQ=300 のデータが抜けていると判断して、もう一度 ACK=300 を返します。前と同じ確認応答番号の ACK なので、重複 ACK(TCP Dup ACK)と呼びます。

送信者受信者Seq=100, Len=200Ack=300次は Seq=300 を待つSeq=300, Len=200Seq=500, Len=200Seq=300 が来ていないAck=300TCP Dup ACKもう一度 Ack=300
図6 SEQ=300 が抜けたので、もう一度 ACK=300 を返す

Wireshark の Info 欄の TCP Dup ACK 40#1 は、「フレーム 40 の ACK と同じ重複 ACK の1つ目」という意味です。同じ ACK が続くと #2、#3 と数が増えていきます。

補足

受信側でキャプチャしている場合、抜けたデータの次のセグメント(図6の SEQ=500)には、TCP Previous segment not captured が表示されます。前のセグメントがキャプチャに入っていない(シーケンス番号が飛んでいる)ことを示す表示です。

TCP高速再送(TCP Fast Retransmission)

通常の再送は、RTO が過ぎても期待した ACK が来ないときに行われます。ただし、送信者が重複 ACK を3つ受け取ると、RTO を待たずに抜けているデータを再送します。これが高速再送(TCP Fast Retransmission)です。

重複 ACK は、抜けたデータより後ろのセグメントが受信者に届くたびに1つ返ります。SEQ=300 が失われたあとに SEQ=500、700、900 が届くと、受信者は ACK=300 を3回重ねて返し、送信者は3つ目の重複 ACK で SEQ=300 を再送します。

送信者受信者Ack=300Seq=300, Len=200Seq=500, Len=200Ack=300重複 ACK 1つ目Seq=700, Len=200Ack=300重複 ACK 2つ目Seq=900, Len=200Ack=300重複 ACK 3つ目Seq=300, Len=200TCP Fast RetransmissionRTO を待たずに再送
図7 重複 ACK を3つ受け取ると、RTO を待たずに再送する
補足

重複 ACK 3つで高速再送するのは、RFC 5681 で決められた送信者の動きです。Wireshark は、逆方向の重複 ACK を2つ以上見たあとの再送などを条件に TCP Fast Retransmission と表示するので、Wireshark の表示と重複 ACK の数がぴったり合わないこともあります。

TCPスプリアス再送信(TCP Spurious Retransmission)

受信者がすでに ACK を返したデータを、送信者が再送したパケットには TCP Spurious Retransmission と表示されます。spurious は「不要な」という意味です。

下の例では、受信者は ACK=300 を返していますが、送信者は SEQ=100、LEN=200 のデータを再送しています。受信者からの ACK が送信者に届かなかった、ACK が届く前に送信者の RTO が切れて再送した、などが考えられます。

送信者受信者Seq=100, Len=200Ack=300Ack=300 は返しているSeq=100, Len=200TCP Spurious RetransmissionACK 済みのデータを再送
図8 ACK 済みのデータを再送する

Wireshark は、キャプチャの中ですでに ACK されたデータかどうかで判断します。そのため、受信者の近くでキャプチャすると、受信者は ACK を返しているのに送信者には届いていない、という状況がこの表示で見えてきます。

まとめ

表示何が起きているか見るポイント
TCP Retransmission期待した ACK が RTO までに来ず、送信者が再送したSEQ/ACK analysis の再送までの時間、元のフレーム
TCP Dup ACK受信者が、抜けているデータの番号でもう一度 ACK を返した#1 #2 の数、直前の Previous segment not captured
TCP Fast
Retransmission
重複 ACK を受けて、RTO を待たずに再送した直前の重複 ACK
TCP Spurious
Retransmission
すでに ACK されたデータを再送したACK が送信者に届いているか、キャプチャした場所

再送や重複 ACK は、少し出るだけなら TCP が正しく回復している証拠でもあります。数が多い、特定の通信に偏っている、といった場合に、どこでパケットが失われているかを調べる手がかりにしてください。

コメント