TCP Analysis Flags 之 TCP Dup ACK

前言

默认情况下,Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态,并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时,会对每个 TCP 数据包进行一次分析,数据包按照它们在数据包列表中出现的顺序进行处理。可以通过 "Analyze TCP sequence numbers" TCP 解析首选项启用或禁用此功能。

TCP 分析展示

在数据包文件中进行 TCP 分析时,关于 "TCP Dup ACK" 一般是如下显示的,包括:

  1. Packet List 窗口中的 Info 信息列,以 [TCP Dup ACK #] 黑底红字进行标注;
  2. Packet Details 窗口中的 TCP 协议树下,在 [SEQ/ACK analysis] -> [TCP Analysis Flags] 中定义该 TCP 数据包的分析说明。

TCP Dup ACK 定义

实际在 TCP 分析中,关于 TCP Dup ACK 的定义也相对来说简单,包括如下:

  • TCP 段大小为 0
  • 窗口大小非零且没有改变,或者有有效的 SACK 数据
  • 下一个期望的 Seq Num 和 LastACK Num 是非 0 的(即连接已经建立)
  • 没有设置 SYN、FIN、RST
plain 复制代码
Set when all of the following are true:

The segment size is zero.
The window size is non-zero and hasn't changed, or there is valid SACK data.
The next expected sequence number and last-seen acknowledgment number are non-zero (i.e., the connection has been established).
SYN, FIN, and RST are not set.

具体的代码如下,总的来说这段代码的用于准确检测 TCP 重复 ACK 的情况,并记录相关信息以支持后续的重传机制分析,是 TCP 可靠传输的重要组成部分。这段代码的主要逻辑如下,如果所有下述条件均满足,则认为该数据包是一个重复确认包。

  • 检查 TCP 段大小是否为 0;
  • 检查窗口大小是否不为 0;
  • 检查窗口大小与同方向之前窗口大小是否相同;
  • 检查 Seq Num 是否等于同方向之前下一个期望的 Seq Num;
  • 检查 ACK Num 是否等于同方向之前的LastACK Num;
  • 检查当前数据包是否不是 SYN/FIN/RST 数据包。
plain 复制代码
    /* DUPLICATE ACK
     * It is a duplicate ack if window/seq/ack is the same as the previous
     * segment and if the segment length is 0
     */
    if( seglen==0
    &&  window
    &&  window==tcpd->fwd->window
    &&  seq==tcpd->fwd->tcp_analyze_seq_info->nextseq
    &&  ack==tcpd->fwd->tcp_analyze_seq_info->lastack
    &&  (flags&(TH_SYN|TH_FIN|TH_RST))==0 ) {

        /* MPTCP tolerates duplicate acks in some circumstances, see RFC 8684 4. */
        if(tcpd->mptcp_analysis && (tcpd->mptcp_analysis->mp_operations!=tcpd->fwd->mp_operations)) {
            /* just ignore this DUPLICATE ACK */
        } else {
            tcpd->fwd->tcp_analyze_seq_info->dupacknum++;

            if(!tcpd->ta) {
                tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
            }
            tcpd->ta->flags|=TCP_A_DUPLICATE_ACK;
            tcpd->ta->dupack_num=tcpd->fwd->tcp_analyze_seq_info->dupacknum;
            tcpd->ta->dupack_frame=tcpd->fwd->tcp_analyze_seq_info->lastnondupack;
       }
    }
  1. next expected sequence number,为 nextseq,定义为 highest seen nextseq。
  2. lastack,定义为 Last seen ack for the reverse flow。

Packetdrill 示例

根据上述 TCP Dup ACK 定义和代码说明,通过 packetdrill 模拟丢包现象即可,因缺失中间一段数据,在收到后一段数据后,就会触发产生 TCP Dup ACK 数据包。

plain 复制代码
# cat tcp_dup_ack.pkt 
0   socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0  setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0  bind(3, ..., ...) = 0
+0  listen(3, 1) = 0

+0 < S 0:0(0) win 16000 <mss 1460>
+0 > S. 0:0(0) ack 1 <...>
+0.01 < . 1:1(0) ack 1 win 16000

+0 accept(3, ..., ...) = 4
+0 < P. 1:21(20) ack 1 win 15000
+0 < P. 41:61(20) ack 1 win 15000
# 

经 Wireshark 展示如下,可以看到满足判断条件后,No.7 标识 [TCP Dup ACK 5#1] ,意味着 No.7 与 No.5 重复,发生一次。

如果想触发多次重复的 Dup ACK,可增加几次后续数据段即可,如下

plain 复制代码
# cat tcp_dup_ack_02.pkt 
0   socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0  setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0  bind(3, ..., ...) = 0
+0  listen(3, 1) = 0

+0 < S 0:0(0) win 16000 <mss 1460>
+0 > S. 0:0(0) ack 1 <...>
+0.01 < . 1:1(0) ack 1 win 16000

+0 accept(3, ..., ...) = 4
+0 < P. 1:21(20) ack 1 win 15000
+0 < P. 41:61(20) ack 1 win 15000
+0 < P. 61:81(20) ack 1 win 15000
+0 < P. 81:101(20) ack 1 win 15000
# 

经 Wireshark 展示如下,No.7 标识 [TCP Dup ACK 5#1] ,No.9 标识 [TCP Dup ACK 5#2] ,No.11 标识 [TCP Dup ACK 5#3] ,共重复三次。

实例

关于 TCP Dup ACK 的实例,实际日常抓包中经常会看到,是比较常见的一种 TCP 分析信息,多数情况会发生在乱序或丢包场景中。在不同的场景中,也会伴生着出现像是 TCP Previous segment not caputredTCP Fast RetransmissionTCP Spurious Retransmission 等信息,当然有时也会单独出现。

  1. TCP Dup ACK + TCP Fast Retransmission

很常见的数据段丢包场景,No.1969 Seq Num 为 1431,提示 TCP 之前的数据分段未被捕获到,也即丢失了一个长度为 1430 字节的数据分段(Seq Num 1、Next Seq Num 1431),因此在收到 No.1969-1971 三个数据分段后,客户端会依次响应 No.1972-1974 三个 ACK 数据包,包含 SACK 信息,并标识为 [TCP Dup ACK],重复三次#1-#3,这样服务器端触发产生了之前丢失分段的快速重传,即 No.1975 数据包。

  1. TCP Dup ACK + TCP Retransmission

一个看起来实际像是丢包,实际为乱序的场景。该数据包为客户端所抓取,No.33 和 No.34 为客户端所发送的数据分段,但在收到服务器端所返回的 No.36 Ack Num 11217 以及 SACK SLE=12168 SRE=12239 说明未收到 No.33,而收到了 No.34 数据包段,因此在客户端由 RACK 触发了重传了 No.33 数据包,也就是 No.37 Seq Num 11217,而在之后才收到了服务器端的 No.38 和 No.39 两个 Ack,其中 No.39 标识 [TCP Dup ACK] ,No.38 Ack Num 为 12239 , 而 No.39 Ack Num 也为 12239 + SACK SLE=11217 SRE=12168,说明在服务器端收到了两个同样的分段 Seq 11217 + Len 951 的数据段,也就是说 No.38 ACK 确认的是 No.33 原始数据段,而 No.39 ACK 确认的是 No.37 重传数据段。

  1. TCP Dup ACK + TCP Spurious Retransmission

一个 RTO 超时重传的场景,该数据包为客户端所抓取,对于服务器端所发送的 No.6 数据段,客户端由于延迟确认等原因,间隔 209ms 才发出 No.7 Ack 确认了该数据段,但同时此时在服务器端又因为 RTO 超时重传,对 No.6 进行了重传,也就是 No.8 数据包,标识 [TCP Spurious Retransmission],继而触发客户端发送了 No.9 ACK 数据包,标识 [TCP Dup ACK]

  1. TCP Dup ACK + TCP Out-Of-Order

一种数据包乱序的场景,该抓包点在客户端本地,服务器端所发送的数据分段在到达时即已发生了乱序,No.5 标识为 [TCP Previous segment not captured],之前应该还有两个 Len=1460 的分段,No.6 为其中一个乱序数据段,标识为 [TCP Out-Of-Order] ,之后客户端 No.7 Ack 确认了 No.5,标识为 [TCP Dup ACK],同时 SACK SLE=2921 SRE=4201,No.8 Ack Num 1461 + SACK SLE=2921 SRE=4201 确认了 No.6,之后才收到另外一个乱序数据段 No.9,最后回复 No.10 Ack Num 4201 。

  1. 看不到 TCP Out-Of-Order 的乱序

同样一种数据包乱序的场景,但是看不到乱序标识,这是正常的,只是抓包点的问题。该数据包为客户端所抓取,因为看到的客户端 No.3414 Len 1573 实际会大于 MTU 1380,但是在出本地网卡后,会变成两个数据包,一个 Len 1380,另一个 Len 193,再加 No.3415 Len 213,一共三个数据包到达了服务器,此时可能在中间网络传输中发生了乱序,数据分段顺序变成了 Len 193、Len 213、Len 1380,这样前两个数据包会触发服务器产生 No.3416-3417 ACK 数据包,标识为 [TCP Dup ACK],其中 No.3416 SLE=17956 SRE=18149 表明收到了 Len 193 的数据分段,No.3417 SLE=17956 SRE=18362 表明又收到了 Len 213 的数据分段,而在之后的 No.3420 ACK Num 18362 才表示收到了 Seq Num 18362 之前所有的数据分段。

总结

考虑到数据包会出现乱序、丢包、重传等各类不同的场景,产生 TCP Dup ACK 的情形自然也是五花八门,具体问题具体分析。

相关推荐
ZachOn1y26 分钟前
计算机网络:运输层 —— TCP 的 “三次握手” 与 “四次挥手”
网络·tcp/ip·计算机网络·tcp·三次握手·四次挥手
yyycqupt31 分钟前
多路转接之poll
服务器·c++·后端·网络协议
雾间云34 分钟前
【计算机网络】TCP协议特点1
网络·tcp/ip·计算机网络
NMBG2236 分钟前
[JAVAEE] 网络编程
java·服务器·网络·tcp/ip·udp·java-ee
RememberLey4 小时前
【eNSP】路由基础与路由来源——静态路由实验
网络·tcp/ip·华为·智能路由器·ensp·静态路由·huawei
qyhua5 小时前
免费申请 Let‘s Encrypt SSL 证书
网络·网络协议·ssl
清酒伴风(面试准备中......)6 小时前
计算机网络HTTP——针对实习面试
java·笔记·网络协议·计算机网络·http·面试·实习
前端李易安6 小时前
HTTP常见的状态码有哪些,都代表什么意思
网络·网络协议·http
软件技术员6 小时前
ZeroSSL HTTPS SSL证书ACMESSL申请3个月证书
网络协议·http·https