文章总结: 本文通过packetdrill脚本和tcpdump抓包,深入分析了Linux内核TCP协议栈处理接收窗口外乱序数据包的机制。当乱序包完全超出接收窗口时,系统会直接丢弃该包并回复重复ACK;若乱序包仅部分超出窗口,系统则会完整接收并缓存该包,同时通过SACK选项告知发送方。当后续数据填补序列空缺后,应用层可成功读取包括超出窗口部分在内的所有数据,这揭示了TCP为应对网络乱序而设计的缓冲策略。 综合评分: 92 文章分类: 网络安全,实战经验,漏洞分析,安全工具,二进制安全
Wireshark TS | 接收窗口外的乱序数据包
原创
7ACE
Echo Reply
2025年12月15日 08:08 江苏
向前奔跑
前言
之前写过两篇关于《接收数据超出接收窗口》和《接收数据超出接收窗口续》的文章,描述的是接收窗口满的特殊案例,现象是接收端在接收窗口为 0 的情况下,依然正常接收了数据,最后也说明了是快速路径和慢速路径处理的原因。
此次继续研究下收到接收窗口之外的乱序数据包,是如何处理的。
问题场景
场景一
首先第一个是乱序数据包完全在接收窗口之外的场景,脚本如下。
# cat tcp_ex_ofo_001.pkt 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0+0 setsockopt(3, SOL_SOCKET, SO_RCVBUF, [3000], 4) = 0+0 bind(3, ..., ...) = 0+0 listen(3, 1) = 0
+0 < S 0:0(0) win 10000 <mss 1460,nop,nop,sackOK>+0 > S. 0:0(0) ack 1 <...>+0.01 < . 1:1(0) ack 1 win 10000+0 accept(3, ..., ...) = 4
+0.01 < P. 1:1001(1000) ack 1 win 10000
+0.01 < P. 3001:4001(1000) ack 1 win 10000
+0 `sleep 1`#
通过 tcpdump 捕获数据包如下,在收到第一个数据包 Seq 1:1001 ,服务器端立马响应了 ACK 数据包 Ack Num 1001,且 Win 为 1920 。之后模拟了第二个乱序数据包,Seq Num 3001:4001,超过了接收窗口 2921,此时服务器端同样立马响应了 ACK 数据包,Ack Num 仍然为 1001 (Dup ACK),说明直接丢弃了此乱序数据包。
# packetdrill tcp_ex_ofo_001.pkt#
# tcpdump -i any -nn port 8080tcpdump: data link type LINUX_SLL2tcpdump: verbose output suppressed, use -v[v]... for full protocol decodelistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes15:37:03.664565 tun0 In IP 192.0.2.1.41093 > 192.168.242.43.8080: Flags [S], seq 0, win 10000, options [mss 1460,nop,nop,sackOK], length 015:37:03.664630 tun0 Out IP 192.168.242.43.8080 > 192.0.2.1.41093: Flags [S.], seq 420249078, ack 1, win 2920, options [mss 1460,nop,nop,sackOK], length 015:37:03.674802 tun0 In IP 192.0.2.1.41093 > 192.168.242.43.8080: Flags [.], ack 1, win 10000, length 015:37:03.684893 tun0 In IP 192.0.2.1.41093 > 192.168.242.43.8080: Flags [P.], seq 1:1001, ack 1, win 10000, length 1000: HTTP15:37:03.684922 tun0 Out IP 192.168.242.43.8080 > 192.0.2.1.41093: Flags [.], ack 1001, win 1920, length 015:37:03.694907 tun0 In IP 192.0.2.1.41093 > 192.168.242.43.8080: Flags [P.], seq 3001:4001, ack 1, win 10000, length 1000: HTTP15:37:03.694928 tun0 Out IP 192.168.242.43.8080 > 192.0.2.1.41093: Flags [.], ack 1001, win 1920, length 015:37:04.698071 tun0 Out IP 192.168.242.43.8080 > 192.0.2.1.41093: Flags [R.], seq 1, ack 1001, win 2000, length 015:37:04.698104 tun0 In IP 192.0.2.1.41093 > 192.168.242.43.8080: Flags [R.], seq 4001, ack 1, win 10000, length 0#
在 tcp_rcv_established() 函数中,由于乱序的原因 TCP_SKB_CB(skb)->seq == tp->rcv_nxt 不成立,进入了 slow_path 慢速路径处理,进行 tcp_validate_incoming() 函数处理,!tcp_sequence(tp, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq) 条件成立,之后 tcp_send_dupack()发送了 Dup ACK 数据包,并且将该数据包直接丢弃,因此应用层所读取的是 Seq 1:1001 中的数据。
/* Does PAWS and seqno based validation of an incoming segment, flags will * play significant role here. */static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, const struct tcphdr *th, int syn_inerr){ struct tcp_sock *tp = tcp_sk(sk); SKB_DR(reason);
...
/* Step 1: check sequence number */ if (!tcp_sequence(tp, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq)) { /* RFC793, page 37: "In all states except SYN-SENT, all reset * (RST) segments are validated by checking their SEQ-fields." * And page 69: "If an incoming segment is not acceptable, * an acknowledgment should be sent in reply (unless the RST * bit is set, if so drop the segment and return)". */ if (!th->rst) { if (th->syn) goto syn_challenge; if (!tcp_oow_rate_limited(sock_net(sk), skb, LINUX_MIB_TCPACKSKIPPEDSEQ, &tp->last_oow_ack_time)) tcp_send_dupack(sk, skb); } else if (tcp_reset_check(sk, skb)) { goto reset; } SKB_DR_SET(reason, TCP_INVALID_SEQUENCE); goto discard; }
...
discard: tcp_drop_reason(sk, skb, reason); return false;
...}
场景二
第二个是乱序数据包部分在接收窗口之外的场景,脚本如下。
# cat tcp_ex_ofo_002.pkt 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0+0 setsockopt(3, SOL_SOCKET, SO_RCVBUF, [3000], 4) = 0+0 bind(3, ..., ...) = 0+0 listen(3, 1) = 0
+0 < S 0:0(0) win 10000 <mss 1460,nop,nop,sackOK>+0 > S. 0:0(0) ack 1 <...>+0.01 < . 1:1(0) ack 1 win 10000+0 accept(3, ..., ...) = 4
+0.01 < P. 1:1001(1000) ack 1 win 10000
+0.01 < P. 2001:3001(1000) ack 1 win 10000
+0 `sleep 1`#
通过 tcpdump 捕获数据包如下,在收到第一个数据包 Seq 1:1001 ,服务器端立马响应了 ACK 数据包 Ack Num 1001,且 Win 为 1920 。之后模拟了第二个乱序数据包 Seq Num 2001:3001,并未完全超过接收窗口 2921,有部分数据仍然在接收窗口之内,此时服务器端同样立马响应了 ACK 数据包,Ack Num 仍然为 1001,但是携带了 SACK 块信息 Seq 2001:3001,说明 TCP 正常完整的接收了这个数据包,包括落在接收窗口之外的数据。
# packetdrill tcp_ex_ofo_002.pkt#
# tcpdump -i any -nn port 8080tcpdump: data link type LINUX_SLL2tcpdump: verbose output suppressed, use -v[v]... for full protocol decodelistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes16:20:41.192515 tun0 In IP 192.0.2.1.43157 > 192.168.193.225.8080: Flags [S], seq 0, win 10000, options [mss 1460,nop,nop,sackOK], length 016:20:41.192576 tun0 Out IP 192.168.193.225.8080 > 192.0.2.1.43157: Flags [S.], seq 291836639, ack 1, win 2920, options [mss 1460,nop,nop,sackOK], length 016:20:41.202654 tun0 In IP 192.0.2.1.43157 > 192.168.193.225.8080: Flags [.], ack 1, win 10000, length 016:20:41.212736 tun0 In IP 192.0.2.1.43157 > 192.168.193.225.8080: Flags [P.], seq 1:1001, ack 1, win 10000, length 1000: HTTP16:20:41.212758 tun0 Out IP 192.168.193.225.8080 > 192.0.2.1.43157: Flags [.], ack 1001, win 1920, length 016:20:41.222742 tun0 In IP 192.0.2.1.43157 > 192.168.193.225.8080: Flags [P.], seq 2001:3001, ack 1, win 10000, length 1000: HTTP16:20:41.222763 tun0 Out IP 192.168.193.225.8080 > 192.0.2.1.43157: Flags [.], ack 1001, win 1920, options [nop,nop,sack 1 {2001:3001}], length 016:20:42.227321 ? Out IP 192.168.193.225.8080 > 192.0.2.1.43157: Flags [R.], seq 1, ack 1001, win 1920, options [nop,nop,sack 1 {2001:3001}], length 016:20:42.227412 ? In IP 192.0.2.1.43157 > 192.168.193.225.8080: Flags [R.], seq 3001, ack 1, win 10000, length 0#
那么此时如果将乱序数据的空洞补齐,之后会是如何处理呢,修改脚本如下。
# cat tcp_ex_ofo_003.pkt 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0+0 setsockopt(3, SOL_SOCKET, SO_RCVBUF, [3000], 4) = 0+0 bind(3, ..., ...) = 0+0 listen(3, 1) = 0
+0 < S 0:0(0) win 10000 <mss 1460,nop,nop,sackOK>+0 > S. 0:0(0) ack 1 <...>+0.01 < . 1:1(0) ack 1 win 10000+0 accept(3, ..., ...) = 4
+0.01 < P. 1:1001(1000) ack 1 win 10000
+0.01 < P. 2001:3001(1000) ack 1 win 10000
+0 < P. 1001:2001(1000) ack 1 win 10000
+0 `sleep 1`#
通过 tcpdump 捕获数据包如下,前两个数据包的处理过程同上,而再之后收到第三个数据包 Seq 1001:2001,服务器端立马响应了 ACK 数据包,Ack Num 为 3001,说明 TCP 正常接收了所有数据包。
# packetdrill tcp_ex_ofo_003.pkt#
# tcpdump -i any -nn port 8080tcpdump: data link type LINUX_SLL2tcpdump: verbose output suppressed, use -v[v]... for full protocol decodelistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes16:22:35.224526 tun0 In IP 192.0.2.1.49661 > 192.168.84.75.8080: Flags [S], seq 0, win 10000, options [mss 1460,nop,nop,sackOK], length 016:22:35.224580 tun0 Out IP 192.168.84.75.8080 > 192.0.2.1.49661: Flags [S.], seq 3519184480, ack 1, win 2920, options [mss 1460,nop,nop,sackOK], length 016:22:35.234820 tun0 In IP 192.0.2.1.49661 > 192.168.84.75.8080: Flags [.], ack 1, win 10000, length 016:22:35.244959 tun0 In IP 192.0.2.1.49661 > 192.168.84.75.8080: Flags [P.], seq 1:1001, ack 1, win 10000, length 1000: HTTP16:22:35.244987 tun0 Out IP 192.168.84.75.8080 > 192.0.2.1.49661: Flags [.], ack 1001, win 1920, length 016:22:35.255564 tun0 In IP 192.0.2.1.49661 > 192.168.84.75.8080: Flags [P.], seq 2001:3001, ack 1, win 10000, length 1000: HTTP16:22:35.255582 tun0 Out IP 192.168.84.75.8080 > 192.0.2.1.49661: Flags [.], ack 1001, win 1920, options [nop,nop,sack 1 {2001:3001}], length 016:22:35.255591 tun0 In IP 192.0.2.1.49661 > 192.168.84.75.8080: Flags [P.], seq 1001:2001, ack 1, win 10000, length 1000: HTTP16:22:35.255595 tun0 Out IP 192.168.84.75.8080 > 192.0.2.1.49661: Flags [.], ack 3001, win 0, length 016:22:36.265211 ? Out IP 192.168.84.75.8080 > 192.0.2.1.49661: Flags [R.], seq 1, ack 3001, win 2000, length 016:22:36.265290 ? In IP 192.0.2.1.49661 > 192.168.84.75.8080: Flags [R.], seq 2001, ack 1, win 10000, length 0#
那么应用层读取数据时,是否可以正常读取到超出接收窗口之外的数据呢,增加 read() 验证读取 3000 字节数据,如下脚本执行正常。
# cat tcp_ex_ofo_004.pkt 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0+0 setsockopt(3, SOL_SOCKET, SO_RCVBUF, [3000], 4) = 0+0 bind(3, ..., ...) = 0+0 listen(3, 1) = 0
+0 < S 0:0(0) win 10000 <mss 1460,nop,nop,sackOK>+0 > S. 0:0(0) ack 1 <...>+0.01 < . 1:1(0) ack 1 win 10000+0 accept(3, ..., ...) = 4
+0.01 < P. 1:1001(1000) ack 1 win 10000
+0.01 < P. 2001:3001(1000) ack 1 win 10000
+0 < P. 1001:2001(1000) ack 1 win 10000
+0.01 read(4,...,3000) = 3000
+0 `sleep 1`#
# packetdrill tcp_ex_ofo_004.pkt#
以下应用层实际读取数据内容的验证,如下设计脚本,服务器接收窗口为 1460 字节大小。第一个数据包 Seq 1:1451 内容为不断循环的 “0123456789”,第二个数据包 Seq 1456:1466 内容为 “0123456789”,即模拟乱序数据包部分数据落在接收窗口之外,第三个数据包 Seq 1451:1456 内容为 “01234”。
# cat tcp_ex_ofo_005.pkt 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0+0 setsockopt(3, SOL_SOCKET, SO_RCVBUF, [2000], 4) = 0+0 bind(3, ..., ...) = 0+0 listen(3, 1) = 0
+0 < S 0:0(0) win 10000 <mss 1460,nop,nop,sackOK>+0 > S. 0:0(0) ack 1 <...>+0.01 < . 1:1(0) ack 1 win 10000+0 accept(3, ..., ...) = 4
+0.01 < P. 1:1451(1450) ack 1 win 10000
+0.01 < P. 1456:1466(10) ack 1 win 10000
+0 < P. 1451:1456(5) ack 1 win 10000
+0.01 read(4,...,1465) = 1465
+0 `sleep 1`#
通过 tcpdump 捕获数据包如下,增加 -x,打印数据,以十六进制显示,No.6 乱序数据包为 3031 3233 3435 3637 3839 。
# packetdrill tcp_ex_ofo_005.pkt#
# tcpdump -i any -nnx port 8080tcpdump: data link type LINUX_SLL2tcpdump: verbose output suppressed, use -v[v]... for full protocol decodelistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes17:02:04.044033 tun0 In IP 192.0.2.1.54429 > 192.168.74.206.8080: Flags [S], seq 0, win 10000, options [mss 1460,nop,nop,sackOK], length 0 0x0000: 4500 0030 0000 0000 ff06 ee4f c000 0201 0x0010: c0a8 4ace d49d 1f90 0000 0000 0000 0000 0x0020: 7002 2710 9a69 0000 0204 05b4 0101 040217:02:04.044087 tun0 Out IP 192.168.74.206.8080 > 192.0.2.1.54429: Flags [S.], seq 2921713249, ack 1, win 1460, options [mss 1460,nop,nop,sackOK], length 0 0x0000: 4500 0030 0000 4000 4006 6d50 c0a8 4ace 0x0010: c000 0201 1f90 d49d ae25 ce61 0000 0001 0x0020: 7012 05b4 cd9a 0000 0204 05b4 0101 040217:02:04.054438 tun0 In IP 192.0.2.1.54429 > 192.168.74.206.8080: Flags [.], ack 1, win 10000, length 0 0x0000: 4500 0028 0000 0000 ff06 ee57 c000 0201 0x0010: c0a8 4ace d49d 1f90 0000 0001 ae25 ce62 0x0020: 5010 2710 4a95 000017:02:04.064531 tun0 In IP 192.0.2.1.54429 > 192.168.74.206.8080: Flags [P.], seq 1:1451, ack 1, win 10000, length 1450: HTTP 0x0000: 4500 05d2 0000 0000 ff06 e8ad c000 0201 0x0010: c0a8 4ace d49d 1f90 0000 0001 ae25 ce62 0x0020: 5018 2710 6a36 0000 3031 3233 3435 3637 0x0030: 3839 3031 3233 3435 3637 3839 3031 3233 0x0040: 3435 3637 3839 3031 3233 3435 3637 3839 0x0050: 3031 3233 3435 3637 3839 3031 3233 3435 0x0060: 3637 3839 3031 3233 3435 3637 3839 3031 0x0070: 3233 3435 3637 3839 3031 3233 3435 3637 0x0080: 3839 3031 3233 3435 3637 3839 3031 3233 0x0090: 3435 3637 3839 3031 3233 3435 3637 3839 0x00a0: 3031 3233 3435 3637 3839 3031 3233 3435 0x00b0: 3637 3839 3031 3233 3435 3637 3839 3031 0x00c0: 3233 3435 3637 3839 3031 3233 3435 3637 0x00d0: 3839 3031 3233 3435 3637 3839 3031 3233 0x00e0: 3435 3637 3839 3031 3233 3435 3637 3839 0x00f0: 3031 3233 3435 3637 3839 3031 3233 3435 0x0100: 3637 3839 3031 3233 3435 3637 3839 3031 0x0110: 3233 3435 3637 3839 3031 3233 3435 3637 0x0120: 3839 3031 3233 3435 3637 3839 3031 3233 0x0130: 3435 3637 3839 3031 3233 3435 3637 3839 0x0140: 3031 3233 3435 3637 3839 3031 3233 3435 0x0150: 3637 3839 3031 3233 3435 3637 3839 3031 0x0160: 3233 3435 3637 3839 3031 3233 3435 3637 0x0170: 3839 3031 3233 3435 3637 3839 3031 3233 0x0180: 3435 3637 3839 3031 3233 3435 3637 3839 0x0190: 3031 3233 3435 3637 3839 3031 3233 3435 0x01a0: 3637 3839 3031 3233 3435 3637 3839 3031 0x01b0: 3233 3435 3637 3839 3031 3233 3435 3637 0x01c0: 3839 3031 3233 3435 3637 3839 3031 3233 0x01d0: 3435 3637 3839 3031 3233 3435 3637 3839 0x01e0: 3031 3233 3435 3637 3839 3031 3233 3435 0x01f0: 3637 3839 3031 3233 3435 3637 3839 3031 0x0200: 3233 3435 3637 3839 3031 3233 3435 3637 0x0210: 3839 3031 3233 3435 3637 3839 3031 3233 0x0220: 3435 3637 3839 3031 3233 3435 3637 3839 0x0230: 3031 3233 3435 3637 3839 3031 3233 3435 0x0240: 3637 3839 3031 3233 3435 3637 3839 3031 0x0250: 3233 3435 3637 3839 3031 3233 3435 3637 0x0260: 3839 3031 3233 3435 3637 3839 3031 3233 0x0270: 3435 3637 3839 3031 3233 3435 3637 3839 0x0280: 3031 3233 3435 3637 3839 3031 3233 3435 0x0290: 3637 3839 3031 3233 3435 3637 3839 3031 0x02a0: 3233 3435 3637 3839 3031 3233 3435 3637 0x02b0: 3839 3031 3233 3435 3637 3839 3031 3233 0x02c0: 3435 3637 3839 3031 3233 3435 3637 3839 0x02d0: 3031 3233 3435 3637 3839 3031 3233 3435 0x02e0: 3637 3839 3031 3233 3435 3637 3839 3031 0x02f0: 3233 3435 3637 3839 3031 3233 3435 3637 0x0300: 3839 3031 3233 3435 3637 3839 3031 3233 0x0310: 3435 3637 3839 3031 3233 3435 3637 3839 0x0320: 3031 3233 3435 3637 3839 3031 3233 3435 0x0330: 3637 3839 3031 3233 3435 3637 3839 3031 0x0340: 3233 3435 3637 3839 3031 3233 3435 3637 0x0350: 3839 3031 3233 3435 3637 3839 3031 3233 0x0360: 3435 3637 3839 3031 3233 3435 3637 3839 0x0370: 3031 3233 3435 3637 3839 3031 3233 3435 0x0380: 3637 3839 3031 3233 3435 3637 3839 3031 0x0390: 3233 3435 3637 3839 3031 3233 3435 3637 0x03a0: 3839 3031 3233 3435 3637 3839 3031 3233 0x03b0: 3435 3637 3839 3031 3233 3435 3637 3839 0x03c0: 3031 3233 3435 3637 3839 3031 3233 3435 0x03d0: 3637 3839 3031 3233 3435 3637 3839 3031 0x03e0: 3233 3435 3637 3839 3031 3233 3435 3637 0x03f0: 3839 3031 3233 3435 3637 3839 3031 3233 0x0400: 3435 3637 3839 3031 3233 3435 3637 3839 0x0410: 3031 3233 3435 3637 3839 3031 3233 3435 0x0420: 3637 3839 3031 3233 3435 3637 3839 3031 0x0430: 3233 3435 3637 3839 3031 3233 3435 3637 0x0440: 3839 3031 3233 3435 3637 3839 3031 3233 0x0450: 3435 3637 3839 3031 3233 3435 3637 3839 0x0460: 3031 3233 3435 3637 3839 3031 3233 3435 0x0470: 3637 3839 3031 3233 3435 3637 3839 3031 0x0480: 3233 3435 3637 3839 3031 3233 3435 3637 0x0490: 3839 3031 3233 3435 3637 3839 3031 3233 0x04a0: 3435 3637 3839 3031 3233 3435 3637 3839 0x04b0: 3031 3233 3435 3637 3839 3031 3233 3435 0x04c0: 3637 3839 3031 3233 3435 3637 3839 3031 0x04d0: 3233 3435 3637 3839 3031 3233 3435 3637 0x04e0: 3839 3031 3233 3435 3637 3839 3031 3233 0x04f0: 3435 3637 3839 3031 3233 3435 3637 3839 0x0500: 3031 3233 3435 3637 3839 3031 3233 3435 0x0510: 3637 3839 3031 3233 3435 3637 3839 3031 0x0520: 3233 3435 3637 3839 3031 3233 3435 3637 0x0530: 3839 3031 3233 3435 3637 3839 3031 3233 0x0540: 3435 3637 3839 3031 3233 3435 3637 3839 0x0550: 3031 3233 3435 3637 3839 3031 3233 3435 0x0560: 3637 3839 3031 3233 3435 3637 3839 3031 0x0570: 3233 3435 3637 3839 3031 3233 3435 3637 0x0580: 3839 3031 3233 3435 3637 3839 3031 3233 0x0590: 3435 3637 3839 3031 3233 3435 3637 3839 0x05a0: 3031 3233 3435 3637 3839 3031 3233 3435 0x05b0: 3637 3839 3031 3233 3435 3637 3839 3031 0x05c0: 3233 3435 3637 3839 3031 3233 3435 3637 0x05d0: 383917:02:04.064584 tun0 Out IP 192.168.74.206.8080 > 192.0.2.1.54429: Flags [.], ack 1451, win 10, length 0 0x0000: 4500 0028 bfb8 4000 4006 ad9f c0a8 4ace 0x0010: c000 0201 1f90 d49d ae25 ce62 0000 05ab 0x0020: 5010 000a cd92 000017:02:04.074527 tun0 In IP 192.0.2.1.54429 > 192.168.74.206.8080: Flags [P.], seq 1456:1466, ack 1, win 10000, length 10: HTTP 0x0000: 4500 0032 0000 0000 ff06 ee4d c000 0201 0x0010: c0a8 4ace d49d 1f90 0000 05b0 ae25 ce62 0x0020: 5018 2710 3fca 0000 3031 3233 3435 3637 0x0030: 383917:02:04.074567 tun0 Out IP 192.168.74.206.8080 > 192.0.2.1.54429: Flags [.], ack 1451, win 10, options [nop,nop,sack 1 {1456:1466}], length 0 0x0000: 4500 0034 bfb9 4000 4006 ad92 c0a8 4ace 0x0010: c000 0201 1f90 d49d ae25 ce62 0000 05ab 0x0020: 8010 000a cd9e 0000 0101 050a 0000 05b0 0x0030: 0000 05ba17:02:04.074571 tun0 In IP 192.0.2.1.54429 > 192.168.74.206.8080: Flags [P.], seq 1451:1456, ack 1, win 10000, length 5: HTTP 0x0000: 4500 002d 0000 0000 ff06 ee52 c000 0201 0x0010: c0a8 4ace d49d 1f90 0000 05ab ae25 ce62 0x0020: 5018 2710 ae79 0000 3031 3233 3417:02:04.074608 tun0 Out IP 192.168.74.206.8080 > 192.0.2.1.54429: Flags [.], ack 1466, win 0, length 0 0x0000: 4500 0028 bfba 4000 4006 ad9d c0a8 4ace 0x0010: c000 0201 1f90 d49d ae25 ce62 0000 05ba 0x0020: 5010 0000 cd92 000017:02:04.084712 tun0 Out IP 192.168.74.206.8080 > 192.0.2.1.54429: Flags [.], ack 1466, win 1450, length 0 0x0000: 4500 0028 bfbb 4000 4006 ad9c c0a8 4ace 0x0010: c000 0201 1f90 d49d ae25 ce62 0000 05ba 0x0020: 5010 05aa cd92 000017:02:05.087497 ? Out IP 192.168.74.206.8080 > 192.0.2.1.54429: Flags [F.], seq 1, ack 1466, win 1450, length 0 0x0000: 4500 0028 bfbc 4000 4006 ad9b c0a8 4ace 0x0010: c000 0201 1f90 d49d ae25 ce62 0000 05ba 0x0020: 5011 05aa cd92 000017:02:05.087702 ? In IP 192.0.2.1.54429 > 192.168.74.206.8080: Flags [R.], seq 1456, ack 1, win 10000, length 0 0x0000: 4500 0028 0000 0000 ff06 ee57 c000 0201 0x0010: c0a8 4ace d49d 1f90 0000 05b0 ae25 ce62 0x0020: 5014 2710 44e2 0000#
而当应用层读取数据时,最终获得的内容如下。
读取第一个数据包 1450 字节:30 31 32 33 34 35 36 37 38 39 ... 0123456789 ...
读取第二个数据包 5 字节:30 31 32 33 34 01234
读取第三个数据包 10 字节:30 31 32 33 34 35 36 37 38 39 0123456789
往期推荐
1. Wireshark 提示和技巧 | 捕获点之 TCP 三次握手
2. Wireshark 提示和技巧 | a == ${a} 显示过滤宏
3. Wireshark TS | 当超时或快速重传遇到零窗口
4. Wireshark TS | 防火墙空闲会话超时问题
5. 网络设备 MTU MSS Jumboframe 全解
后台回复「TT」获取 Wireshark 提示和技巧系列 合集
后台回复「TS」获取 Wireshark Troubleshooting系列 合集
如需交流,可后台直接留言,我会在第一时间回复,谢谢!
查看原文:《Wireshark TS | 接收窗口外的乱序数据包》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论