当前位置: 首页 > article >正文

TCP Analysis Flags 之 TCP Window Update

前言

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

TCP 分析展示

在数据包文件中进行 TCP 分析时,关于 “TCP Window Update” 一般是如下显示的,包括:

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

目前版本中关于 TCP 分析标志位,颜色规则中唯一被排除的,[Coloring Rule String: tcp.analysis.flags && !tcp.analysis.window_update],非黑底红字。

TCP Window Update 定义

实际在 TCP 分析中,关于 TCP Window Update 的定义如下,当以下所有条件都为真时设置该标志:

  • TCP 段大小为零
  • 窗口大小非零,不等于之前的窗口大小,并且没有有效的 SACK 数据
  • Seq Num 等于之前下一个期望的 Seq Num
  • ACK Num 等于之前的 LastACK Num,或者等于在响应 ZeroWindowProbe 时的下一个期望的 Seq Num
  • SYN、FIN、RST 均未设置
Set when the all of the following are true:

The segment size is zero.
The window size is non-zero and not equal to the last-seen window size, and there is no valid SACK data.
The sequence number is equal to the next expected sequence number.
The acknowledgment number is equal to the last-seen acknowledgment number,
or to the next expected sequence number when answering to a ZeroWindowProbe.
None of SYN, FIN, or RST are set.
  1. next expected sequence number,为 nextseq,定义为 highest seen nextseq。
  2. 其中第 2 个说明中提及不包括有效的 SACK 数据,但是实际代码中未排除,以下实际案例说明。

具体的代码如下,总的来说这段代码的作用是检测 TCP 窗口更新数据包,它对于 TCP 流量控制非常重要,允许接收端动态调整自己的接收窗口,从而控制发送端的发送速率,实现拥塞控制,通过标记数据包,Wireshark 能更好地分析和显示 TCP 的流量控制过程。这段代码的主要逻辑如下,如果所有下述条件均满足,则认为该数据包是一个窗口更新包。

  • 检查 TCP 数据段长度是否为 0;
  • 检查窗口大小是否不为 0;
  • 检查窗口大小与同方向之前窗口大小是否不同;
  • 检查 Seq Num 是否等于同方向之前下一个期望的 Seq Num;
  • 检查 ACK Num 是否等于同方向之前的 LastACK Num;
  • 检查当前数据包是否不是 SYN/FIN/RST 数据包。
    /* WINDOW UPDATE
     * A window update is a 0 byte segment with the same SEQ/ACK numbers as
     * the previous seen segment and with a new window value
     */
    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 ) {
        if(!tcpd->ta) {
            tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
        }
        tcpd->ta->flags|=TCP_A_WINDOW_UPDATE;
    }
  1. next expected sequence number,为 nextseq,定义为 highest seen nextseq。
  2. lastack,定义为 Last seen ack for the reverse flow。

Packetdrill 示例

在上述 TCP Window Update 的定义和代码可知,TCP 分析的逻辑相对简单,在模拟零窗口的代码之上简单加一行 Win 恢复的 ACK 数据包即可。

# cat tcp_window_upate.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 1000 <mss 1460>
+0  > S. 0:0(0) ack 1 <...>
+0.01 < . 1:1(0) ack 1 win 1000
+0 accept(3, ..., ...) = 4

+.1 write(4, ..., 1000) = 1000
+0 > P. 1:1001(1000) ack 1
+0.1 < . 1:1(0) ack 1001 win 0
+0.01 < . 1:1(0) ack 1001 win 1000
# 

经 Wireshark 展示如下,可以看到 No.7 标识 [TCP Window Update] ,满足各项条件,Win 更新恢复为 1000。

当然和零窗口不相关的场景下,也一样会有 [TCP Window Update] ,模拟测试如下

# cat tcp_window_update_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 10000 <mss 1460>
+0  > S. 0:0(0) ack 1 <...>
+0.01 < . 1:1(0) ack 1 win 10000
+0 accept(3, ..., ...) = 4

+.1 write(4, ..., 5000) = 5000
+0 > P. 1:5001(5000) ack 1
+0.1 < . 1:1(0) ack 5001 win 8000
+0.01 < . 1:1(0) ack 5001 win 10000
# 

经 Wireshark 展示如下,可以看到 No.7 标识 [TCP Window Update] ,满足各项条件,Win 更新恢复为 10000。

实例

关于 TCP Window Update 的实例,实际上来说该现象比较常见,只是一个 TCP 窗口更新的提示,并没有任何问题,仅仅是 Chat 级别,信息为:[Expert Info (Chat/Sequence): TCP window update]

TCP Window Update 一般在零窗口下场景下出现的较多,因此以下前3个案例直接复制 TCP ZeroWindow 篇中的案例。

  1. TCP Window Full + TCP ZeroWindow + TCP Window Update

一种比较常见的零窗口情景,接收端短暂的出现 Win 为 0 的情形,紧接着就会释放窗口,发出窗口更新的消息。

首先服务器端发送数据,发现客户端接收窗口满了,则在 No.278 上标识 [TCP Window Full] ,此时客户端 No.281 因为 Win 为 0 且未设置 SYN、FIN、RST 的情况下,标识为 [TCP ZeroWindow],之后 12ms 紧接着就发送了 [TCP Window Update] 窗口更新消息,Win 恢复成 4536,该交互过程并没有出现 [TCP ZeroWindowProbe] 等数据包。

  1. TCP Window Full + TCP ZeroWindow + TCP ZeroWindowProbe + TCP Window Update

另外一种零窗口情景,接收端出现 Win 为 0 的情形,发送 TCP ZeroWindow 通知,发送端在经过一段时间后发出 TCP ZeroWindowProbe 数据包,但接收端收到探测后,由于已经打开窗口,因此直接回复 TCP Window Update 数据包。

首先服务器端 No.10 Win 为 0 且未设置 SYN、FIN、RST 的情况下,标识为 [TCP ZeroWindow] ,之后 286ms 客户端发送了 No.11 [TCP ZeroWindowProbe] 用于确认服务器端接收窗口是否恢复,服务器紧接着回复确认 No.12,表示窗口已恢复 Win 1420,标识为 [TCP Window Update] 数据包。

  1. TCP Window Full + TCP ZeroWindow + TCP ZeroWindowProbe + TCP ZeroWindowProbeAck + TCP Window Update

大满贯场景,覆盖了 5 种 TCP 分析标志。首先客户端发送数据,发现服务器接收窗口满了,则在 No.4 和 No.6 上标识 [TCP Window Full] ,此时服务器端 No.7 因为 Win 为 0 且未设置 SYN、FIN、RST 的情况下,标识为 [TCP ZeroWindow],之后陷入等待,大概 2 秒+后,客户端发送了 No.8 [TCP ZeroWindowProbe] 用于确认服务器端接收窗口是否恢复,服务器紧接着回复确认 No.9,表示仍处于零窗口未恢复,标识为 [TCP ZeroWindowProbeAck] + [TCP ZeroWindow] ,又再过了 300ms 后,服务器端发送 No.10 Win 此时更新为 14600,表示接收窗口已恢复,标识成 [TCP Window Update] ,至此完成一次完整的零窗口出现、探测及恢复过程。

类似的场景同样如下

  1. 普通场景下的窗口更新

正常情况下,由于某一端接收窗口的释放,同样也会发出 [TCP Window Update] 数据包,表示 Win 窗口发生变化,如下 Win 由 259200 变为 262144。

  1. SACK 下的窗口更新

如上官方文档中的描述:The window size is non-zero and not equal to the last-seen window size, and there is no valid SACK data. 应该是不能包含有效的 SACK 数据,但实际在代码中确没有相关判断条件,也因此在以下实际案例中,就算包含有 SACK 数据,也一样会被标识成 [TCP Window Update] 数据包。

当然这只是一个小问题,也许是关于 TCP 窗口更新的解析代码有过更新,但是文档有遗漏,忘记更新。

总结

总结就是 TCP Window Update 很正常,一切放心,网络没有问题。😂


http://www.kler.cn/a/350492.html

相关文章:

  • Python制作简易PDF查看工具PDFViewerV1.0
  • uniApp开通uniPush1.0个推,SpringBoot集成uniPush1.0个推
  • 口令攻击和钓鱼攻击
  • 抖音a_bogus,mstoken全参数爬虫逆向补环境2024-06-15最新版
  • 如何在不暴露MinIO地址的情况下,用Spring Boot与KKFileView实现文件预览
  • Redis可视化工具--RedisDesktopManager的安装
  • 鸡兔同笼(贪心)
  • 【spring ai】java 实现RAG检索增强,超快速入门
  • Unity URP shader ———魔系符文宝石是如何练成的
  • C# Attribute 介绍
  • 微信小程序后台搭建—node+mysql
  • 农业机器人综述:技术现状、应用场景及未来展望
  • YOLOv8改进 - 注意力篇 - 引入ShuffleAttention注意力机制
  • 小米电机与STM32——CAN通信
  • 2024年第九届数维杯大学生数学建模挑战赛赛题和数维杯国际数学建模 LaTeX 模板
  • Android 未来可能支持 Linux 应用,Linux 终端可能登陆 Android 平台
  • 绕过MIME-Type验证
  • 算法知识点————【DFS】【BFS】【树】【图】
  • 发送URL请求中的问题记录
  • [LeetCode] 844. 比较含退格的字符串
  • ubuntu22.04安装mysql5.7
  • 综合小案例
  • foxy moveit2 小鱼
  • 珠海自闭症寄宿学校:打造温馨家庭般的学习氛围
  • mongodb的相关关键字说明
  • 记录使用datagrip备份数据库信息