TCP Analysis Flags 之 TCP Window Full

news2024/9/21 14:50:44

前言

默认情况下,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.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1977335.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

详解C/C++输入输出

前言 C/C输入输出很多&#xff0c;在不同的情况会用不同的输入输出&#xff0c;有的题目在输入时可能换一种输入输出就能不会TLE&#xff0c;有的输入可能要循环输入&#xff0c;但是可以换一种输入直接就能把所有数据输入进去。C/C有哪些常用的输入输出&#xff0c;在什么时候…

总线学习1--I2C

很久以前就听说总线这个词了&#xff0c;一直不懂&#xff0c;所以觉得很牛叉。。。这次有机会学习&#xff0c;就干脆一起看看吧。 1 环境介绍 说实话&#xff0c;计算机的学习最好还是有个环境&#xff0c;裸学真的要难一些。硬件学习其实难就难在搭环境&#xff0c;之前很多…

生物计算与纳米技术:交汇前沿的科学领域

在当今科技迅猛发展的时代&#xff0c;生物计算和纳米技术作为前沿科技领域的两个重要方向&#xff0c;正在逐渐融合并带来深远的影响。生物计算涉及使用生物系统进行计算和数据存储&#xff0c;而纳米技术则关注制造极小尺度的电子器件和材料科学。本文将深入探讨这两个领域的…

2.2 (1) 处理机调度

文章目录 处理机调度概念处理机调度层次高级调度&#xff08;作业调度&#xff09;中级调度&#xff08;内存调度&#xff09;低级调度&#xff08;进程调度/处理机调度&#xff09;三层调度的联系对比 进程调度的时机需要进行进程调度与切换的情况不能进行进程调度与切换的情况…

【Linux学习】文件系统 - 第一篇

&#x1f351;个人主页&#xff1a;Jupiter. &#x1f680; 所属专栏&#xff1a;Linux从入门到进阶 欢迎大家点赞收藏评论&#x1f60a; &#x1f4d5;文章目录 &#x1f4da;基础知识铺垫&#x1f351;重新使用C语言文件接口---对比重定向&#x1f388;fopen函数&#x1f30f…

[云原生]三、Kubernetes(1.18)

主要内容: 1、kubernetes 简介 2、kubernetes 集群搭建  方式搭建  二进制方式搭建 3、 kubeadm kubernetes 核心技术  YAML 文件详解  kubectl 命令工具  Pod  Label  Controller 控制器 …

node.js使用NodeMachineID 生成唯一UUID和注意事项

node-machine-id用于获取或生成唯一的机器ID 如何使用 const { machineId, machineIdSync } require(node-machine-id) JSON.stringify(machineIdSync({original: true})) ;方法&#xff1a; machineIdSync 此函数同步获取操作系统本机UUID/GUID&#xff0c;默认情况下进行哈…

深入理解 ReLU 激活函数及其在深度学习中的应用【激活函数、Sigmoid、Tanh】

ReLU&#xff08;Rectified Linear Unit&#xff09;激活函数 ReLU&#xff08;Rectified Linear Unit&#xff09;激活函数是一种广泛应用于神经网络中的非线性激活函数。其公式如下&#xff1a; ReLU ( x ) max ⁡ ( 0 , x ) \text{ReLU}(x) \max(0, x) ReLU(x)max(0,x) 在…

嵌入式Linux系统中pinictrl框架基本实现

1. 回顾Pinctrl的三大作用 记住pinctrl的三大作用,有助于理解所涉及的数据结构: * 引脚枚举与命名(Enumerating and naming) * 单个引脚 * 各组引脚 * 引脚复用(Multiplexing):比如用作GPIO、I2C或其他功能 * 引脚配置(Configuration):比如上拉、下拉、open drain、驱…

Java中的五种线程池类型

Java中的五种线程池类型 1. CachedThreadPool &#xff08;有缓冲的线程池&#xff09;2. FixedThreadPool &#xff08;固定大小的线程池&#xff09;3. ScheduledThreadPool&#xff08;计划线程池&#xff09;4. SingleThreadExecutor &#xff08;单线程线程池&#xff09…

CTFHUB-SSRF-DNS重绑定 Bypass

开启题目&#xff0c;页面空白&#xff0c;访问附件 附件是一个知乎的文章&#xff0c;翻到下面点击文中这个链接 跳转之后&#xff0c;进行设置 把得到的链接拼接到题目的后面进行访问&#xff0c;然后得到了本题的 flag

Leetcode3226. 使两个整数相等的位更改次数

Every day a Leetcode 题目来源&#xff1a;3226. 使两个整数相等的位更改次数 解法1&#xff1a;位运算 从集合的角度理解&#xff0c;k 必须是 n 的子集。如果不是&#xff0c;返回 −1。怎么用位运算判断&#xff0c;见上面的文章链接。 如果 k 是 n 的子集&#xff0c;…

Windows Batch Linux Shell

windows上使用unix&#xff0c;Linux的unix工具对应的windows的可执行exe程序&#xff0c;对于本来的windows用户也可以使用这些工具提高工作效率&#xff0c;特别地在windows的批处理中使用这些命令很方便 二 工具列表 agrep.exe ansi2knr.exe basename.exe bc.exe bison.exe…

图像生成技术的颠覆性进展——从GAN到Aura SR V2

欢迎来到我们的科技专栏&#xff01;最近&#xff0c;文本到图像合成技术的成功引起了全球的轰动&#xff0c;激发了公众的无限想象力。从技术角度看&#xff0c;这也标志着在设计生成图像模型的架构上发生了巨大的变化。曾经&#xff0c;生成对抗网络&#xff08;GANs&#xf…

【Material-UI】详解安装指南

文章目录 一、默认安装1.1 Peer Dependencies 二、使用styled-components三、Roboto字体3.1 使用Fontsource3.2 使用Google Web Fonts 四、图标4.1 使用Google Web Fonts 五、CDN安装六、总结 Material-UI是全球最受欢迎的React UI框架之一。它提供了丰富的组件和高度可定制的主…

CSDN 的 Markdown 编辑器图片居中对齐和设置图片大小的方法

图片对齐方式 加在文件格式后面 #pic_center #pic_left #pic_right例如&#xff1a; 居中对齐 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/eb16b0a5bc414b9888ab73f3c74a8acb.png#pic_center)左对齐 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direc…

AI答题应用平台相关面试题

目录 1、请介绍整个系统后端的架构设计&#xff0c;有哪些模块以及各模块之间的关系&#xff1f; 2、你在项目中是如何设计库表的&#xff1f;可以从字段、索引、关联等方面回答。 3、为什么使用策略模式来封装不同的应用评分算法&#xff1f;它有哪些好处&#xff1f;具体如…

Elasticsearch 的DSL查询,聚合查询与多维度数据统计

文章目录 搜索聚合高阶概念 搜索 即从一个索引下按照特定的字段或关键词搜索出符合用户预期的一个或者一堆cocument&#xff0c;然后根据文档的相关度得分&#xff0c;在返回的结果集里并根据得分对这些文档进行一定的排序。 聚合 根据业务需求&#xff0c;对文档中的某个或…

【源码+文档+调试讲解】营业厅宽带系统设计与实现

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本营业厅宽带系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&…

Action部署在线上写文章

原文&#xff1a;https://blog.c12th.cn/archives/32.html 前言 之前分别出了 Hexo 和 Hugo 的 Action搭建教程&#xff0c;相当于伪动态&#xff0c;可以在线上写文章了&#xff1b;不过对于喜欢魔改的同学就不太友好了qwq 教程 github.dev 确保在配置过程中能访问Github &…