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

TCP Analysis Flags 之 TCP Window Full

前言

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

TCP 分析展示

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

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

image.png

TCP Window Full 定义

实际在 TCP 分析中,关于 TCP Window Full 的定义非常简单,如下,为本端发送端所发的 TCP 段大小超过对端接收端的接收窗口大小,受到对端接收窗口大小的限制,需注意的是这个标记是在发送端标记,而不是在接收端标记

Set when the segment size is non-zero, we know the window size in the reverse direction, and our segment size exceeds the window size in the reverse direction.

具体的代码如下,总的来说这段代码的作用是检测 TCP 数据流中的“窗口已满”情况,即当前数据段刚好达到接收端宣告的窗口边界,检测到这种情况时,会设置相应的标志以供后续处理使用。

    /* WINDOW FULL* If we know the window scaling* and if this segment contains data and goes all the way to the* edge of the advertised window* then we mark it as WINDOW FULL* SYN/RST/FIN packets are never WINDOW FULL*/if( seglen>0&&  tcpd->rev->win_scale!=-1&&  (seq+seglen)==(tcpd->rev->tcp_analyze_seq_info->lastack+(tcpd->rev->window<<(tcpd->rev->is_first_ack?0:(tcpd->rev->win_scale==-2?0:tcpd->rev->win_scale))))&&  (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_FULL;}
  1. lastack,定义为 Last seen ack for the reverse flow。
  2. 关于 tcpd->rev->is_first_ack,在之后实例中会展开说明。

Packetdrill 示例

在上述 TCP Window Full 定义和代码可知,TCP 分析的逻辑很简单,因此通过 packetdrill 比较容易模拟出相关现象。

# cat tcp_window_full.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, ..., 500) = 500
+0 > P. 1:501(500) ack 1
+0.1 < . 1:1(0) ack 501 win 1000+.1 write(4, ..., 1000) = 1000
+0 > . 501:1001(500) ack 1
+0 > P. 1001:1501(500) ack 1
+0.1 < . 1:1(0) ack 1501 win 1000

通过 tcpdump 捕获数据包后,经 Wireshark 展示如下,可以看到由于客户端 No.5 宣告的 Win 为 1000,所以服务器仅能发送 1000 字节大小的数据分段,也就是分别发送了 No.6 和 No.7 两个 Len 为 500 字节的数据包,这样在 No.7 数据包中会判断为 [TCP Window Full],因为发送字节大小已经达到了对端也就是客户端宣告的 Win 大小。

image.png

BIF 大小 1000,专家信息标识说明为 TCP window specified by the receiver is now completely full接收端窗口满

image.png

实例

关于 TCP Window Full 的实例,正常来说考虑到接收端接收窗口的释放速度,再加上 Window Scale 的存在,TCP 窗口满现象相对来说并不是那么容易出现。而在不同的场景中,也会伴生着出现像是 TCP Window UpdateTCP ZeroWindowTCP ZeroWindowProbeTCP ZeroWindowProbeAck 等信息。

  1. 窗口满

可以看到客户端 No.277 宣告的 Win 为 8712,而服务器 No.278 标识为 [TCP Window Full],是由于在途字节数达到了 8712 字节。

image.png

image.png

而在之后的通讯过程中,由于客户端 Win 降为了 0,在 No.281 也就标识了 [TCP ZeroWindow],之后由于接收窗口释放变化,又发送了 No.282 Win 为 4356 的 ACK,之后服务器再次发送 No.283 数据分段时又一次标识了 [TCP Window Full],同样的原因是由于在途字节数达到了 4356 字节。

image.png

该案例中,客户端并不支持 Window Scale ,也就是在 TCP SYN 中未携带该选项。

  1. 窗口满的特例

当 TCP 通讯速率上不去,疑似某端接收窗口满或有问题时,但又没看到明显的 [TCP Window Full] 标识时,请相信自己的判断,真有可能是发生了 TCP 窗口满问题。

看不到 [TCP Window Full] 标识,仅仅是有可能数据包文件或者说这条 TCP 流不完整,并没有抓到 TCP 三次握手的信息,因此后续的数据通讯过程中是无法得知这条流是否支持 Window Scale 以及它的具体数值,没有这些信息的情况下,是没有办法根据数据包中携带的 Win 字段值计算出实际的窗口值,所以也就没法判断什么时候发生了窗口满事件。

如下,就像只会知道接收窗口 250,在不知道 Window Scale 为 4 的情况下,如何能得出计算后的 Win 大小为 1000 ?

image.png
这种情况下,看到的现象就是一端通告的 Win 只是一个小值,但是另一端发送的在途数据又能超过这个值,此时的情况你就可以判断出是因为缺少了 TCP 三次握手。

注意,仅仅是 Wireshark 因为数据包文件不完整无法判断,真实的数据流如果双方均支持 Window Scale,实际的通讯流均是按照各自的缩放因子来计算且发送数据的。

案例也很好模拟出,在上述 packetdrill 示例中把 No.1-3 TCP 三次握手数据包忽略掉即可,如下,No.7 此时已经不再标识 [TCP Window Full], 虽然对端 No.5 所通告的 Win 为 1000 ,但是 Window size scaling factor: -1(unknown),从 [TCP Window Full] 的代码来说,tcpd->rev->win_scale =-1 已经没有后续判断的依据了,因此 [TCP Window Full] 不再出现。

注意区别 Window size scaling factor: -2 (no window scaling used),-2 代表着说数据包文件完整,也就是捕获到了 TCP 三次握手,但双方不支持 Window Scale。

image.png

如何知道?有条件的话,复现一次 TCP 连接,重新捕获到 TCP 三次握手即可,不管是 -2 不支持,或者其它的值。然而就算知道了,再通过手动指定 Window Scale 值的方式,也无法让 [TCP Window Full] 再出现 。

  1. 再谈窗口满的特例

这里就要提到之前代码中的 tcpd->rev->is_first_ack ,如下,如果 is_frist_ack 为真,对于 Window 的偏移量也就是 Window Scale ,使用值 0,而不是用 TCP 三次握手中的 Window Scale 值。

tcpd->rev->window<<(tcpd->rev->is_first_ack?0:(tcpd->rev->win_scale==-2?0:tcpd->rev->win_scale))

is_first_ack 具体是在 TCP 三次握手阶段即设置为 True,不管是 SYN 或是 SYN/ACK 数据包,均会设置本方向的 is_first_ack 值为 True 。

    if(tcph->th_flags & TH_SYN) {if(tcph->th_flags & TH_ACK) {expert_add_info_format(pinfo, tf_syn, &ei_tcp_connection_synack,"Connection establish acknowledge (SYN+ACK): server port %u", tcph->th_sport);/* Save the server port to help determine dissector used */tcpd->server_port = tcph->th_sport;}else {expert_add_info_format(pinfo, tf_syn, &ei_tcp_connection_syn,"Connection establish request (SYN): server port %u", tcph->th_dport);/* Save the server port to help determine dissector used */tcpd->server_port = tcph->th_dport;tcpd->ts_mru_syn = pinfo->abs_ts;}/* Remember where the next segment will start. */if (tcp_desegment && tcp_reassemble_out_of_order && tcpd && !PINFO_FD_VISITED(pinfo)) {if (tcpd->fwd->maxnextseq == 0) {tcpd->fwd->maxnextseq = tcph->th_seq + 1;}}/* Initiliaze the is_first_ack */tcpd->fwd->is_first_ack = TRUE;

在以下这个案例中,No.79 判定为 [TCP Window Full],光从表面现象来看会感觉很奇怪,因为 TCP 三次握手中明显双方均支持 Window Scale,且双方均为很大的一个值 WS 128,而客户端仅仅从 No.70-79 传了 10 个 MSS 1448 的分段后即出现了窗口满现象。No.79 显示为 BIF 14480 大小,和 SYN/ACK 通告的窗口 Win 14480 相等,但没有使用 Window Scale 来相乘计算,即对于 [TCP Window FUll] 的判断,使用的直接是 0 值,而不是 Window Scale 128。

image.png

image.png
这是因为对于客户端 No.79 来说,tcpd->rev->is_first_ack 实际就是服务器端 is_first_ack 的取值,而此时在 rev 方向仅有 No.68 SYN/ACK 数据包,此时 is_first_ack 的值为 True,因此对于 Window 的偏移量也就是 Window Scale ,使用值 0,所以最终判断为 [TCP Window Full] 。

  1. 继续谈窗口满的特例

再说一个案例,服务器端 No.5 判定为 [TCP Window Full],是因为客户端 No.3 通告的 Win 为 1000,也就是 Win 250 使用了 Window Scale 4 来相乘计算,因此服务器端能发送 No.4 和 No.5 两个 500 字节大小的数据分段,并在 No.5 上标记 [TCP Window Full] 。

image.png

也就是说服务器端在 No.5 数据包分析时,判断 rev 方向 Window Scale 的值是真实值 4 而不是 0 ,这也就意味着此时客户端的 is_first_ack 的值为 False 。而这是在分析客户端 No.3 ACK 数据包时,通过以下代码所实现:

    /** Remember if we have already seen at least one ACK,* then we can neutralize the Window Scale side-effect at the beginning (issue 14690)*/if(tcp_analyze_seq&& (tcph->th_flags & (TH_SYN|TH_ACK)) == TH_ACK) {if(tcpd->fwd->is_first_ack) {tcpd->fwd->is_first_ack = FALSE;}}

总结

总结来说,关于 TCP Window Scale ,有两句话说得很到位:

  1. RFC7323 2.2 The window field in a segment where the SYN bit is set (i.e., a or <SYN,ACK>) MUST NOT be scaled.
  2. The Window Scale option has to be honored and interpreted adequately.

相关文章:

TCP Analysis Flags 之 TCP Window Full

前言 默认情况下&#xff0c;Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态&#xff0c;并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时&#xff0c;会对每个 TCP 数据包进行一次分析&#xff0c;数据包按照它们在数据包列表中出现的顺序进行处理。可…...

相关性检验

文章目录 Pearson相关系数Spearman等级相关系数Cochrans Q检验Kappa一致性系数Kendall相关系数实例分析总结 在数据分析的广阔天地中&#xff0c;相关性检验是探索变量间关系的一把钥匙。本文将带领大家了解几种常用的相关性检验方法&#xff1a;Pearson、Spearman、Cochran’s…...

【python】Django运行报错分析:ImproperlyConfigured 错误解决办法

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…...

AS01/AS11 创建固资和子资产

AS01&#xff1a;创建资产卡片 定义该资产的折旧费用&#xff0c;应该归结到哪个成本中心。 如果一台设备停止使用&#xff0c;可以勾选。停止折旧。 该界面维护折旧码和折旧的时间。 维护完之后点击保存。 系统生成一个资产卡片号。 AS02-修改资产卡片号 更改不同时间段&…...

vue3数字动画插件countup.js

countup.js 是一个轻量级的 JavaScript 库&#xff0c;允许你为网站上显示统计数据或计数器时平滑地动画化数字。CountUp 类被用来创建计数器实例&#xff0c;可以平滑地从一个数值变化到另一个数值。 只是用户视觉更好一些。 1、安装插件 npm i countup.js2、个人是封装了组件…...

aspeed2600 GPIO分析与适配ipmitool power status, ipmitool power on/off

1.说明 本节以x86-power-control/src/power_control.cpp为基础&#xff0c;分析整个GPIO的调用流程&#xff0c;实现简单的ipmitool power on/off,ipmitool power status的管理。 1.资源:x86-power-control:https://github.com/openbmc/x86-power-control2.相关文件: meta-ph…...

在C#中配置ini文件以及封装ini类

在C#中使用 DllImport 属性从 kernel32.dll 导入函数来写入和读取Windows的INI文件&#xff0c;你可以使用 WritePrivateProfileString 来写入数据&#xff0c;使用 GetPrivateProfileString 来读取数据。 以下是如何使用这些函数的示例&#xff1a; 写入INI文件 using Syst…...

使用git上传代码到github

1、设置用户名及邮箱 git config user.name"你的用户名"git config user.email"xxxxx.com" 2、查看配置 git config -l 3、生成秘钥 ssh-keygen -t rsa 根据上图中红框标出的id_rsa.pub地址&#xff0c;找到它&#xff0c;使用txt文件打开&#xff0c;复…...

滚珠花键:新能源汽车传动系统的核心动力传递者

在日常生活中&#xff0c;汽车已经成为了必不可少的交通工具&#xff0c;尤其是新能源汽车。而滚珠花键作为传动系统中的重要组成部分&#xff0c;在传动系统方面的作用不容忽视。 随着科技的不断发展&#xff0c;汽车行业也在不断进步&#xff0c;滚珠花键作为高精度的机械传动…...

LeetCode 149, 347, 31

文章目录 149. 直线上最多的点数题目链接标签思路总体思路如何判断 一个点 在 由两点确定的直线 上 代码 347. 前 K 个高频元素题目链接标签思路代码 31. 下一个排列题目链接标签思路代码 149. 直线上最多的点数 题目链接 149. 直线上最多的点数 标签 几何 数组 哈希表 数学…...

操作系统(信号处理)

一、信号介绍 什么是中断&#xff1a; 当进程接收到消息后中止当前正在执行的任务&#xff0c;转而执行其它任务&#xff0c;等待其它任务执行完毕后再返回继续执行。这种执行模式称为中断&#xff0c;分为硬件中断和软件中断两种 什么是信号&#xff1a; 信号是UNIX、类UNI…...

[MRCTF2020]Ezpop

[MRCTF2020]Ezpop 题目是pop&#xff0c;考的其实就是pop链&#xff0c;可以自己先学学&#xff0c;啥也不会QAQ php反序列化之pop链_pop3.phpwelcome-CSDN博客 POP 面向属性编程(Property-Oriented Programing) 常用于上层语言构造特定调用链的方法&#xff0c;与二进制利用…...

24暑假算法刷题 | Day27 | 贪心算法 I | LeetCode 455. 分发饼干,376. 摆动序列,53. 最大子数组和

目录 455. 分发饼干题目描述题解 376. 摆动序列题目描述题解 53. 最大子数组和题目描述题解 455. 分发饼干 点此跳转题目链接 题目描述 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#x…...

Golang 的空接口有什么用?

空接口在 Go 语言中具有多种重要用途&#xff1a; 实现通用的数据结构 例如&#xff0c;可以创建一个包含空接口类型元素的切片或映射&#xff0c;从而能够存储不同类型的值。这在处理多种未知类型的数据时非常有用。比如&#xff0c;一个日志系统可能会将不同类型的日志消息&a…...

计算机毕业设计选题推荐-课程教学平台-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…...

健身日记之倒立俯卧撑学习——起始日2024.6.4

文章目录 目录 前言上期预期 昔日计划 新目标计划 瓶颈突破尝试 参考视频及文章 前言 两个月过去了&#xff0c;已经有所突破了&#xff0c;但是比较预期还是有较大差距&#xff0c;忘记更新csdn了&#xff0c;平时抖音视频号记录的多一些。 上期预期 2024.6.4开始尝试突…...

pikachu文件包含漏洞

一&#xff1a;漏洞基础 程序在引用文件的时&#xff0c;引用的文件名存在可控的情况&#xff0c;传入的文件名没有经过合理的校验或校验不严&#xff0c;从而操作了预想之外的文件&#xff0c;就有可能导致文件泄漏和恶意的代码注入&#xff1b; 文件包含漏洞概念 在PHP程序…...

09.FreeRTOS时间片调度与任务相关函数

文章目录 09. FreeRTOS时间片调度与任务相关函数1. FreeRTOS时间片调度2. 任务状态查询API函数3. 任务时间统计API函数 09. FreeRTOS时间片调度与任务相关函数 1. FreeRTOS时间片调度 时间片调度简介&#xff1a; 时间片调度实验流程&#xff1a; 核心代码&#xff1a; 开…...

git分支介绍

git branch 查看当前分支情况 可以看见当前只有一个分支叫main&#xff0c;也就是默认分支&#xff0c;可以理解为树的主干&#xff0c;git早期版本中默认分支叫master 命令行创建一个新分支 git branch [分支名]在创建之后&#xff0c;如果需要切换到新分支需要git switc…...

vm虚拟机下安装CentOS7系统

VMware16安装CentOS7 1.启动之前安装的VM 具体VMware安装过程 2.配置Linux&#xff08;centos7&#xff09;的镜像文件 选择安装镜像文件 4.开启虚拟机 开始读秒安装 选择安装过程中使用的语言&#xff0c;这里选择英文、键盘选择美式键盘。点击Continue 首先设置时间…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...