TCP Analysis Flags 之 TCP ACKed unseen segment

news2024/9/20 20:40:02

前言

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

TCP 分析展示

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

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

image.png

TCP ACKed unseen segment 定义

实际在 TCP 分析中,关于 TCP ACKed unseen segment 的定义非常简单,当为反方向设置了期望的下一个确认号并且它小于当前确认号时设置。

Set when the expected next acknowledgment number is set for the reverse direction and it’s less than the current acknowledgment number.

具体的代码如下,涉及到 TCP 分析逻辑还是稍复杂,毕竟涉及到不同方向的 Seq 和 Ack Num 计算,其中还涉及零窗口恢复时候的的一个特殊场景。总之,代码通过识别和处理 TCP 数据流中的 “被 ACK 的丢失数据包” 情况,并调整 maxseqtobeacked变量来反映被 ACK 的最大序列号,从而准确跟踪分析 TCP 连接的状态。

    /* ACKED LOST PACKET
     * If this segment acks beyond the 'max seq to be acked' in the other direction
     * then that means we have missed packets going in the
     * other direction.
     * It might also indicate we are resuming from a Zero Window,
     * where a Probe is just followed by an ACK opening again the window.
     * See issue 8404.
     *
     * We only check this if we have actually seen some seq numbers
     * in the other direction.
     */
    if( tcpd->rev->tcp_analyze_seq_info->maxseqtobeacked
    &&  GT_SEQ(ack, tcpd->rev->tcp_analyze_seq_info->maxseqtobeacked)
    &&  (flags&(TH_ACK))!=0 ) {
        if(!tcpd->ta) {
            tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
        }

        /* resuming from a Zero Window Probe which re-opens the window,
         * mark it as a Window Update
         */
        if(EQ_SEQ(ack,tcpd->fwd->tcp_analyze_seq_info->lastack+1)
        && (seq==tcpd->fwd->tcp_analyze_seq_info->nextseq)
        && (tcpd->rev->lastsegmentflags&TCP_A_ZERO_WINDOW_PROBE) ) {
            tcpd->rev->tcp_analyze_seq_info->nextseq=ack;
            tcpd->rev->tcp_analyze_seq_info->maxseqtobeacked=ack;
            tcpd->ta->flags|=TCP_A_WINDOW_UPDATE;
        }
        /* real ACKED LOST PACKET */
        else {
            /* We ensure there is no matching packet waiting in the unacked list,
             * and take this opportunity to push the tail further than this single packet
             */

            guint32 tail_le = 0, tail_re = 0;
            for(ual=tcpd->rev->tcp_analyze_seq_info->segments; ual; ual=ual->next) {

                if(tail_le == tail_re) { /* init edge values */
                    tail_le = ual->seq;
                    tail_re = ual->nextseq;
                }

                /* Only look at what happens above the current ACK value,
                 * as what happened before is definetely ACKed here and can be
                 * safely ignored. */
                if(GE_SEQ(ual->seq,ack)) {

                    /* if the left edge is contiguous, move the tail leftward */
                    if(EQ_SEQ(ual->nextseq,tail_le)) {
                        tail_le = ual->seq;
                    }

                    /* otherwise, we have isolated segments above what is being ACKed here,
                     * and we reinit the tails with the current values */
                    else {
                        tail_le = ual->seq;
                        tail_re = ual->nextseq; // move the end tail
                    }
                }
            }

            /* a tail was found and we can push the maxseqtobeacked further */
            if(EQ_SEQ(ack,tail_le) && GT_SEQ(tail_re, ack)) {
                tcpd->rev->tcp_analyze_seq_info->maxseqtobeacked=tail_re;
            }

            /* otherwise, just take into account the value being ACKed now */
            else {
                tcpd->rev->tcp_analyze_seq_info->maxseqtobeacked=ack;
            }

            tcpd->ta->flags|=TCP_A_ACK_LOST_PACKET;
        }
    }
  1. next expected sequence number,为 nextseq,定义为 highest seen nextseq。
  2. lastack,定义为 Last seen ack for the reverse flow。
  3. maxseqtobeacked,定义为 highest seen continuous seq number (without hole in the stream) from the fwd party, this is the maximum seq number that can be acked by the rev party in normal case.If the rev party sends an ACK beyond this seq number it indicates TCP_A_ACK_LOST_PACKET condition。

Packetdrill 示例

根据上述 TCP ACKed unseen segment 定义和代码说明,对于通过 packetdrill 模拟 TCP 连接通讯,仔细琢磨了下,发现不好直接模拟出来,因为 TCP ACKed unseen segment 的现象较为普遍的场景是没有捕获到被 ACK 的数据分段,重点是没有捕获到,而实际端到端 TCP 通讯是正常收到数据分段并确认的。

因此首先第一步简单通过 packetdrill 模拟出一个完整的数据通讯即可,并通过 tcpdump 捕获数据包后,经 Wireshark 展示如下。

# cat tcp_acked_unseen_segment.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. 21:41(20) ack 1 win 15000
+0 < P. 41:61(20) ack 1 win 15000
+0.1 read(4, ..., 60) = 60 
# 

image.png

第二步通过 Wireshark 忽略掉 No.6 数据包即可,也就是说这个 TCP 流中没有捕获到该分段,这样在 No.7 数据包中会判断为 [TCP ACKed unseen segment],因为在反方向最大的可确认的 Seq Num 是 No.4 中的 21 ,小于 No.7 的 ACK Num 41 。

image.png

实例

关于 TCP ACKed unseen segment 的实例,实际日常抓包中经常会看到,是比较常见的一种 TCP 分析信息,多数情况下可认为就是没有捕获到相应的数据分段。当然不同的场景,也会伴生着出现像是 TCP Previous segment not caputredTCP Spurious Retransmission 等信息。

  1. 未捕获到数据分段

最常见的未捕获到一个或多个数据分段时的情景,在这个 TCP 流中没有捕获到反方向从 Seq 1 NextSeq 2401 的分段,这样在 No.120 数据包中会判断为 [TCP ACKed unseen segment],因为在反方向最大的可确认的 Seq Num 是 No.119 中的 1 ,小于 No.120 的 ACK Num 2401 。

image.png

  1. 零窗口的特例

关于从零窗口探测 (Zero Window Probe) 状态恢复的情况,代码判断如果满足以下三个条件:

  1. ACK 值正好是上次 ACK 值加 1。
  2. 当前序列号等于期望的下一个序列号。
  3. 之前的数据段是一个零窗口探测包。

那么就将当前包标记为窗口更新 (Window Update),并更新一些序列号相关的变量。这种情况下不认为是 “被ACK的丢失数据包” 。

以上是关于零窗口探测状态恢复的代码部分解读,结合以下这个实际案例来看,实际是没有出现未捕获数据包的情形的,也因此一开始我对 No.12 标识成 [TCP Window Update] 会感觉疑惑,因为首先需要满足 GT_SEQ(ack, tcpd->rev->tcp_analyze_seq_info->maxseqtobeacked),也就是 ack num 15622 要大于 maxseqtobeacked,而 maxseqtobeacked 不就应该是 No.11 中的 NextSeq Num 15622 嘛??? 既然相等,也就没有后面代码执行的逻辑,也就不会判断标识成 [TCP Window Update] 了。。。

image.png

但为什么实际会出现 [TCP Window Update] 呢?各方寻求帮助,再加上不断找寻案例,最后在代码中找到了相关说明,确实是零窗口的特例,简单来说就是 [TCP ZeroWindowProbe] 的 NextSeqNum 会被排除,不会更新 maxseqtobeacked,因此对于上面的案例,maxseqtobeacked 的值仍是 No.5 的 NextSeqNum 15621,所以 GT_SEQ 成立。

    /* Store the highest continuous seq number seen so far for 'max seq to be acked',
     * so we can detect TCP_A_ACK_LOST_PACKET condition.
     * If this ever happens, this boundary value can "jump" further in order to
     * avoid duplicating multiple messages for the very same lost packet. See later
     * how ACKED LOST PACKET are handled.
     * Zero Window Probes are logically left out at this moment, but if their data
     * really were to be ack'ed, then it will be done later when analyzing their
     * Probe ACK (be it a real Probe ACK, or an ordinary ACK moving the RCV Window).
     */
    if(EQ_SEQ(seq, tcpd->fwd->tcp_analyze_seq_info->maxseqtobeacked) || !tcpd->fwd->tcp_analyze_seq_info->maxseqtobeacked) {
        if( !tcpd->ta || !(tcpd->ta->flags&TCP_A_ZERO_WINDOW_PROBE) ) {
            tcpd->fwd->tcp_analyze_seq_info->maxseqtobeacked=tcpd->fwd->tcp_analyze_seq_info->nextseq;
        }
    }
  1. TCP Keep-Alive 的特例

实际并没有未捕获到数据分段,但仍判断为 [TCP ACKed unseen segment] 的特殊场景。
判断为 [TCP ACKed unseen segment] ,是因为在反方向最大的可确认的 Seq Num 是 No.1 中的 1 ,小于 No.2 的 ACK Num 2 ,但如一开始所述,它仅仅是符合了 [TCP ACKed unseen segment] 的代码逻辑,但真实情况并非这样。

image.png

细看下边的数据包,可以发现 No.1 和 No.2 实际是一对 [TCP Keep-Alive][TCP Keep-Alive ACK] ,通过 ip.id 辅助查看,也可以发现 No.1 和 No.3 是连续的数据包,中间并没有多余的数据包,也就是说并不存在数据分段未被捕获到的情形。

image.png

该案例的详细情况,可见《Wireshark TS | 丢包?不要轻易下结论续》。

  1. 消失的 TCP ACKed unseen segment

对于这一种案例,从目前的代码上来说,对于 No.6 确实不会标识成 [TCP ACKed unseen segment] ,因为满足不了 GT_SEQ 的判断。但如下图示,可以很容易看到未捕获到 No.4 和 No.5 之间理应存在的两个分段 Seq 2401 NextSeq 4801,但是在 No.6 ACK 却确认了 6001 以前的所有数据,这不就是一种很明显的 ACKed unseen segment 的情形嘛。

image.png

目前我无法确认是否还有一些特殊的情况考虑在内,在之后的某一天也许可以就这样的案例发起一个 TCP 解析器增强功能的请求。

总结

总的来说,[TCP ACKed unseen segment] 实质上没有任何真实的业务影响,你是否明白了其中的真正原理呢。

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

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

相关文章

Java---面向对象

一.面向对象 1.概念 1.1面向过程 C 吃饭&#xff1a;动作为核心 起身--》开门--》大量的逻辑判断 1.2面向对象 C/Java/Python/Go 目标&#xff1a;吃饭 人&#xff08;忽略&#xff09;吃饭 站在人类的角度思考问题 2.什么是对象&#xff1f; Object-->东西(万事万物皆…

【数据结构2】哈希表、哈希表的应用(集合与字典、md5算法和文件的哈希值)

1 哈希表 哈希表一个通过哈希函数来计算数据存 储位置的数据结构&#xff0c;通常支持如下操作: 插入(键&#xff0c;值):插入键值对(键&#xff0c;值) Get(key):如果存在键为键的键值对则返回其值&#xff0c;否则返回空值 删除(键):删除键为键的键值对哈希表(Hash Table&am…

开发者学习类网站

目录 **1、CodeProject****2、simplilearn****3、VisuAlgo****4、Google AI****5、CodeWars****6、SourceForge****7、GeeksforGeeks****8、StackOverflow** 1、CodeProject 网址&#xff1a;https://www.codeproject.com/ CodeProject是一个免费公开自己写的代码与程序的优秀…

稀土阻燃协效剂在木质地板中的应用

木质地板作为一种天然材料&#xff0c;非常容易燃烧&#xff0c;因此需要采取措施来增强其阻燃性能。稀土阻燃协效剂基于稀土4f电子层结构带来的特有属性&#xff0c;在聚合物材料燃烧时可催化酯化成炭,迅速在高分子表面形成致密连续的碳层,隔绝聚合物材料内部的可燃性气体与氧…

vue项目png图片加载不出来的问题

前提&#xff1a;因为命名的时候 配合后端&#xff0c;所以把图片的名称设置成中文的例如&#xff1a;新增圆、新增方块等命名&#xff1b;提交到线上环境后&#xff0c;发现有些图片不能完全显示&#xff1b;鼠标移入查看地址&#xff0c;发现其他展示的图片已经转为base64的形…

SALib | 灵敏度分析Python工具箱

灵敏度分析Python工具箱 Sensitivity Analysis LibrarySupported MethodsInstallationRequirementsHow to cite SALibReference Sensitivity Analysis Library SALib是常用灵敏度分析方法的Python实现&#xff0c;包括 Sobol、Morris 和 FAST 方法。在系统建模中很有用&#x…

解决Element-plus中Carousel(走马灯)图片无法正常加载的bug

前言&#xff1a; 最近帮助朋友解决了一个使用Element-plus中Carousel&#xff08;走马灯&#xff09;图片无法正常加载的bug&#xff0c;经过笔者的不断努力终于实现了&#xff0c;现在跟大家分享一下&#xff1a; 朋友原来的代码是这样的&#xff1a; <template><…

代码随想录Day 23|回溯Part02,39.组合总和、40.组合总和Ⅱ、131.分割回文串

提示&#xff1a;DDU&#xff0c;供自己复习使用。欢迎大家前来讨论~ 文章目录 第七章 回溯算法part03一、题目题目一&#xff1a; 39. 组合总和解题思路&#xff1a;回溯三部曲剪枝优化小结&#xff1a; 题目二&#xff1a;40.组合总和Ⅱ解题思路&#xff1a;回溯三部曲 题目…

LabVIEW中CANopen Read SDO.vi 和 CANopen Read Write CAN Frame.vi区别

CANopen Read SDO.vi 和 CANopen Read Write CAN Frame.vi 都是 NI-Industrial Communications for CANopen 库中的示例 VI&#xff0c;用于与 CANopen 网络进行通信&#xff0c;但它们的功能和使用场景有所不同。以下是它们的主要区别&#xff1a; 1. 功能层次 CANopen Read W…

图像分割论文阅读:BCU-Net: Bridging ConvNeXt and U-Net for medical image segmentation

本文提出了一种集合ConvNeXt和U-Net优势的网络模型来分割医学图像。 当然&#xff0c;模型整体结构就是并列双分支&#xff0c;如果只是这些内容&#xff0c;不值得拿出来讲。 主要有意思的部分是其融合两分支的多标签召回模块&#xff08;multilabel recall loss module&…

Tutorial:Deep Learning for Remote Sensing Data

文章目录 0. Intro1. ADVANTAGES OF REMOTE SENSING METHODS2. THE GENERAL FRAMEWORK3. BASIC ALGORITHMS IN DEEP LEARNING3.1 CONVOLUTIONAL NEURAL NETWORKS3.1.1 CONVOLUTIONAL LAYER3.1.2 NONLINEARITY LAYER3.1.3 POOLING LAYER 3.2 AUTOENCODERS3.3 RESTRICTED BOLTZMA…

SEO古诗网,可做站群,可二开成泛——码山侠

数据量大&#xff0c;古诗&#xff0c;名句等一共有数十万数据&#xff0c;基本上所有的古诗词已经入库完。 模板SEO强大&#xff0c;做好了基本的优化配置&#xff0c;结合帝国强大的sinfo插件&#xff0c;百度推送插件&#xff0c;以及itag管理插件很容易形成词库。 帝国CM…

数据结构(邓俊辉)学习笔记】串 01——ADT

1. 定义 特点 我们讨论的主题是串&#xff0c;无论从抽象数据类型&#xff0c;还是从具体实现的角度来看&#xff0c;串&#xff0c;相当于此前所介绍的数据结构来说都更为简单。因此&#xff0c;会将更多的时间用于讨论串的相关算法&#xff0c;尤其是串匹配的算法。 在接下…

探寻孩子不会说话与自闭症的关联及成因

在孩子的成长过程中&#xff0c;语言的发展是一个至关重要的阶段。然而&#xff0c;有些孩子却迟迟不会说话&#xff0c;这让家长们忧心忡忡。而当孩子不会说话的同时还伴有一些异常行为时&#xff0c;自闭症的担忧便会涌上心头。那么&#xff0c;孩子不会说话且患有自闭症究竟…

最近再写一个仿微信的项目遇到的一些bug(一)

目录&#xff1a; bug &#xff08;一&#xff09;Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are requiredProperty报错解决方法 bug &#xff08;二&#xff09;Cannot invoke “javax.script.ScriptEngine.eval(String)“ because “engine“ is null报错原…

likeshop采集商品图片无法保存解决方案

封面图 一个修复单&#xff0c;客户的likeshop采集tb商品后&#xff0c;保存到商品库的时候 主图无法显示 报错&#xff1a; "/www/wwwroot/test.0ev.cn/server/public/uploads/l7pu2aqt/admin/images/d61d40dab9e6245f90b62ede72b51639.jpg" string(6226) "…

除毛大作战,选择你的清理工具——希喂、美的宠物空气净化器PK

随着气温的升高&#xff0c;又到了宠物的换毛季。猫咪在家里疯狂掉毛&#xff0c;而铲屎官也陷入清理难题。幸好&#xff0c;有宠物空气净化器可以帮助铲屎官减轻打扫负担。那么宠物空气净化器又该如何挑选呢&#xff1f;哪款宠物空气净化器效果更佳&#xff1f;我也很想知道答…

【JVM】剖析字符串与数组的底层实现(一)

剖析字符串与数组的底层实现 字符数组的存储方式 JVM有三种模型: 1.Oop模型:Java对象对应的C对象2.Klass模型:Java类在JVM对应的C对象3.handle模型 字符串常量池 即String Pool&#xff0c;但是JVM中对应的类是StringTable&#xff0c;底层实现是一个hashtable,如代码所示 …

老师怎样分班更便捷?

随着新学期的钟声敲响&#xff0c;老师们又迎来了一年中最繁忙的时刻。开学之初&#xff0c;除了要处理日常的教学事务&#xff0c;老师们还肩负着一项重要任务——给新生进行分班。 其实老师们完全可以不必那么劳累。在这个科技日新月异的时代&#xff0c;有许多工具可以帮助老…

计算机毕业设计选题推荐-高中素质评价档案系统-Java/Python项目实战

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