Suricata-7.0 源码分析之流表建立FlowWorker

一、什么是Flow?
二、Flow是怎么建立的?
三、Flow建立的具体过程是什么?

一、什么是Flow?
  在Suricata 7.0中,流Flow是指所有相同五元组(协议,源IP,目的IP,源端口,目的端口)的数据包Packet分组,它们都属于同一流Flow,属于流Flow的数据包Packet在内部连接到它。
  流Flow建立是在FlowWorker()函数中,在解码Decode模块中调用函数FlowSetupPacket(),基于五元组(协议,源IP,目的IP,源端口,目的端口)生成流Flow的hash值(p->flow_hash),并且设置标志位PKT_WANTS_FLOW,表示这个Packet数据包是由网络收包经过解码Decode模块而来的Packet数据包。

/*
*这段代码是一个函数,用于在处理网络数据包时设置相关的流处理标记和流哈希值。1. `p->flags |= PKT_WANTS_FLOW;`:将数据包的标志中加入了 `PKT_WANTS_FLOW` 标记。这个标记通常用于表示当前数据包需要进行流处理,即需要为该数据包创建或更新对应的流对象。2. `p->flow_hash = FlowGetHash(p);`:调用 `FlowGetHash` 函数来计算当前数据包的流哈希值,并将结果赋给数据包的 `flow_hash` 属性。流哈希值通常用于在流表中快速查找或定位对应的流对象。总的来说,这段代码的作用是在处理网络数据包时,标记该数据包需要进行流处理,并计算并保存该数据包对应的流哈希值,以便后续创建或更新对应的流对象。
*/
void FlowSetupPacket(Packet *p)
{p->flags |= PKT_WANTS_FLOW;p->flow_hash = FlowGetHash(p);
}
Flow结构体如下:
/***  \brief Flow data structure.**  The flow is a global data structure that is created for new packets of a*  flow and then looked up for the following packets of a flow.**  Locking**  The flow is updated/used by multiple packets at the same time. This is why*  there is a flow-mutex. It's a mutex and not a spinlock because some*  operations on the flow can be quite expensive, thus spinning would be*  too expensive.**  The flow "header" (addresses, ports, proto, recursion level) are static*  after the initialization and remain read-only throughout the entire live*  of a flow. This is why we can access those without protection of the lock.* Flow的结构体,用于表示流数据的结构。这个结构体的各个成员的含义:这个结构体定义了用于表示网络数据流的各种属性和状态信息,包括地址、端口、协议类型、超时信息、线程信息、锁信息、协议特定数据指针等。*/typedef struct Flow_
{/* flow "header", used for hashing and flow lookup. Static after init,* so safe to look at without lock */FlowAddress src, dst; /*表示流的源地址和目的地址。*//* sp,dp:表示源端口和目的端口。*/union {Port sp;        /**< tcp/udp source port */struct {uint8_t type;   /**< icmp type */uint8_t code;   /**< icmp code */} icmp_s;struct {uint32_t spi; /**< esp spi */} esp;};union {Port dp;        /**< tcp/udp destination port */struct {uint8_t type;   /**< icmp type */uint8_t code;   /**< icmp code */} icmp_d;};uint8_t proto; /*表示协议类型。*/uint8_t recursion_level;/*表示递归级别。 */uint16_t vlan_id[VLAN_MAX_LAYERS]; /* 表示 VLAN ID 和 VLAN 索引。*/uint8_t vlan_idx;/* track toserver/toclient flow timeout needs ffr_ts、ffr_tc、ffr
用于跟踪流的超时需求。
*/union {struct {uint8_t ffr_ts:4;uint8_t ffr_tc:4;};uint8_t ffr;};/** timestamp in seconds of the moment this flow will timeout*  according to the timeout policy. Does *not* take emergency*  mode into account.
timeout_at:表示流的超时时间戳。*/uint32_t timeout_at; /** Thread ID for the stream/detect portion of this flow
thread_id:用于存储流的线程 ID。
*/FlowThreadId thread_id[2];struct Flow_ *next; /* (hash) list next 指向下一个流的指针。 *//** Incoming interface 
livedev:表示流的输入接口。
*/struct LiveDevice_ *livedev;/** flow hash - the flow hash before hash table size mod.
flow_hash:表示流的哈希值。*/uint32_t flow_hash;/** timeout policy value in seconds to add to the lastts.tv_sec*  when a packet has been received.
timeout_policy:表示超时策略的数值。
*/uint32_t timeout_policy;/* time stamp of last update (last packet). Set/updated under the* flow and flow hash row locks, safe to read under either the* flow lock or flow hash row lock. 
lastts:表示流的最后更新时间戳。
*/SCTime_t lastts;/* flow_state:表示流的状态类型。*/FlowStateType flow_state;/** flow tenant id, used to setup flow timeout and stream pseudo*  packets with the correct tenant id set 
tenant_id:表示租户 ID。
*/uint32_t tenant_id;/*probing_parser_toserver_alproto_masks、probing_parser_toclient_alproto_masks:用于探测解析器的掩码。*/uint32_t probing_parser_toserver_alproto_masks;uint32_t probing_parser_toclient_alproto_masks;uint32_t flags;         /**< generic flags flags:表示流的通用标志。*/uint16_t file_flags;    /**< file tracking/extraction flags file_flags:表示文件跟踪/提取标志。*//** destination port to be used in protocol detection. This is meant*  for use with STARTTLS and HTTP CONNECT detection 
protodetect_dp:用于协议检测的目的端口。*/uint16_t protodetect_dp; /**< 0 if not used *//* Parent flow id for protocol like ftp parent_id:表示协议的父流 ID。*/int64_t parent_id;/*
r、m:用于流锁的读写锁或互斥锁。
*/
#ifdef FLOWLOCK_RWLOCKSCRWLock r;
#elif defined FLOWLOCK_MUTEXSCMutex m;
#else#error Enable FLOWLOCK_RWLOCK or FLOWLOCK_MUTEX
#endif/** protocol specific data pointer, e.g. for TcpSession protoctx:指向协议特定数据的指针。*/void *protoctx;/** mapping to Flow's protocol specific protocols for timeoutsand state and free functions. protomap:用于超时和状态函数的协议映射。*/uint8_t protomap;/* flow_end_flags:流结束标志。*/uint8_t flow_end_flags;/* coccinelle: Flow:flow_end_flags:FLOW_END_FLAG_ *//*alproto、alproto_ts、alproto_tc、alproto_orig、alproto_expect:表示应用层协议类型。*/AppProto alproto; /**< \brief application level protocol */AppProto alproto_ts;AppProto alproto_tc;/** original application level protocol. Used to indicate the previousprotocol when changing to another protocol , e.g. with STARTTLS. alproto_orig:这是一个枚举类型的变量,用于表示原始的应用层协议。当协议发生更改时,例如通过使用STARTTLS进行加密通信,该变量用于指示之前使用的协议。alproto_expect:这是一个枚举类型的变量,用于表示预期的应用层协议。它在处理协议更改或升级的情况下很有用,例如在使用STARTTLS进行加密通信后,它可以指定在更改或升级后预期使用的协议。*/AppProto alproto_orig;/** expected app protocol: used in protocol change/upgrade like in*  STARTTLS. */AppProto alproto_expect;/** detection engine ctx version used to inspect this flow. Set at initial*  inspection. If it doesn't match the currently in use de_ctx, the*  stored sgh ptrs are reset.de_ctx_version:表示检测引擎上下文的版本。*/uint32_t de_ctx_version;/** ttl tracking min_ttl_toserver、max_ttl_toserver、min_ttl_toclient、		 max_ttl_toclient:用于跟踪 TTL(生存时间)。*/uint8_t min_ttl_toserver;uint8_t max_ttl_toserver;uint8_t min_ttl_toclient;uint8_t max_ttl_toclient;/** application level storage ptrs.*alparser、alstate:用于应用层解析器的内部状态和应用层状态的指针。*/AppLayerParserState *alparser;     /**< parser internal state */void *alstate;      /**< application layer state *//** toclient sgh for this flow. Only use when FLOW_SGH_TOCLIENT flow flag*  has been set. sgh_toclient、sgh_toserver:指向流的客户端和服务器端的 SigGroupHead 结构的指针。*/const struct SigGroupHead_ *sgh_toclient;/** toserver sgh for this flow. Only use when FLOW_SGH_TOSERVER flow flag*  has been set. */const struct SigGroupHead_ *sgh_toserver;/* pointer to the var list flowvar:指向变量列表的指针。*/GenericVar *flowvar;/* fb:指向流桶的指针。*/struct FlowBucket_ *fb;/* startts:表示流的开始时间戳。*/SCTime_t startts;/*todstpktcnt、tosrcpktcnt、todstbytecnt、tosrcbytecnt:用于跟踪数据包和字节计数。*/uint32_t todstpktcnt;uint32_t tosrcpktcnt;uint64_t todstbytecnt;uint64_t tosrcbytecnt;
} Flow;

二、Flow是怎么建立的?
  主要流程,如下所示:
  FlowWorker
    -->FlowHandlePacket
      -->FlowGetFlowFromHash
        -->FlowGetNew(新建流)
          -->FlowQueuePrivateGetFromTop(从flow_spare_pool中申请流)
          -->FlowAlloc(flow_spare_pool不够,直接alloc申请)
         -->MoveToWorkQueue(已有流超时的,从哈希桶中删除,并放入work_queue或者evicted链表)

        -->FlowWorkerProcessInjectedFlows(取出flow_queue中的flow放入到work_queue)
        -->FlowWorkerProcessLocalFlows
          -->CheckWorkQueue
            -->FlowClearMemory(清除流信息)
            -->FlowSparePoolReturnFlow(将流归还到flow_spare_pool中)

  Flow建立详细过程,如下图所示:
FlowerWorker-1
FlowerWorker-2

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

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

相关文章

makefile里面的变量使用,系统变量

文章目录 makefile里面的变量使用 makefile里面的变量使用 calc:add.o sub.o multi.ogcc add.o sub.o multi.o calc.cpp -o calcadd.o:add.cppgcc -c add.cpp -o add.osub.o:sub.cppgcc -c sub.cpp -o sub.omulti.o:multi.cppgcc -c multi.cpp -o multi.oclean:rm -rf *.o cal…

Linux第32步_编译ST公司的TF-A源码

正点原子STM32MP157开发板使用的CPU型号是STM32MP157DAA1&#xff0c;而开发板硬件参考了ST公司的STM32MP157 EVK开发板&#xff0c;因此我们在移植的时候需要关注“stm32mp157d-ev1”。 一、了解SDK 包 ST公司会从ARM官方下载TF-A软件包&#xff0c;然后将STM32MP1 芯片添加…

算法总结——单调栈

纵有疾风起&#xff0c;人生不言弃。本文篇幅较长&#xff0c;如有错误请不吝赐教&#xff0c;感谢支持。 文章目录 一、单调栈的定义二、单调栈的应用&#xff1a;寻找左边第一个比它小的数单调栈的思想&#xff08;重点&#xff09;&#xff1a;寻找左边第一个比它小的数的下…

Unity常用的优化技巧集锦

Unity性能优化是面试的时候经常被问道的一些内容&#xff0c;今天给大家分享一些常用的Unity的优化技巧和思路&#xff0c;方便大家遇到问题时候参考与学习。 对啦&#xff01;这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白&#xff0c;也有一些正在从事游…

(C语言)编译和链接

前言͟͟͞͞&#x1f48c;&#xff1a;对于现在的各种编译器而言许多都是好多个功能的集成&#xff0c;那么我们的代码到底是如何去实现的呢&#xff1f;难道我们的计算机可以直接读懂我们所写的代码&#xff0c;并运行吗&#xff1f;对于很多细心的小伙伴们可能会想这样的问题…

Spring Security 优化鉴权注解:自定义鉴权注解的崭新征程

文章目录 1. 引言2. Spring Security基础2.1 Spring Security概述2.2 PreAuthorize注解 3. 自定义鉴权注解的优势3.1 业务语义更明确3.2 参数化鉴权更灵活3.3 可维护性更好 4. 实现自定义鉴权注解4.1 创建自定义注解4.2 实现鉴权逻辑4.3 注册自定义注解和逻辑4.4 使用自定义注解…

Divisibility Problem-codefordes

题目链接&#xff1a;Problem - A - Codeforces 解题思路&#xff1a; 如果 a 能被 b整除&#xff0c;就不需要进行改变&#xff0c;直接输出0&#xff0c;否则输出((a / b) 1) * b - a&#xff0c;找到最小的能被b整除的数。 下面是c代码&#xff1a; #include<iostrea…

探索JAVA神秘运行机制:揭秘JVM内存区域

目录 1. 前文回顾 2.内存区域的划分 2.1 存放类的方法区 2.2 程序计数器 2.3 Java虚拟机栈 2.4 Java堆内存 2.5 其他内存区域 3. 核心内存区域运行流程 4. 总结 1. 前文回顾 上一篇我们一起探索了Java的整体运行流程&#xff0c;类加载器以及类的加载机制&#xff0…

去了字节跳动,才知道年薪 30w 的测试工程师有这么多?

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

会体言一心文-码代-4202

简明版本 最近感悟就是在“常规赛”中&#xff0c;大部分奇技淫巧远不如官方教程。 我使用大模型工具快一年的时间所积累的经验远不如认真看看官方教程。 官方教程 里面有一点就可以秒99%的工具人&#xff0c;“文心一言7*24小时在线&#xff0c;伴你左右。 ” 结合文心一言…

中仕教育:考上选调生之后能不去吗?选调生和公务员哪个比较好?

选调生&#xff0c;是指经过选拔、培训、考核等一系列程序&#xff0c;选拔出的人才。选调生通常需要在基层锻炼一段时间&#xff0c;然后根据工作表现和能力得到提拔。 考上选调生之后能否不去&#xff0c;有以下两种情况。 1.如果通过选调笔试&#xff0c;但是并未参加后续…

2788.按分隔符拆分字符串

前言 力扣还挺上道&#xff08;bushi&#xff09;&#xff0c;今天第一次写每日一题&#xff0c;给了个简单等级的数组题&#xff0c;我只能说&#xff0c;首战告捷&#xff08;小白的呐喊&#xff09;&#xff0c;看看这每日一题我能坚持一天写出来&#xff0c; ok&#xff…

Javaweb之SpringBootWeb案例员工管理之新增员工的详细解析

SpringBootWeb案例 前面我们已经实现了员工信息的条件分页查询以及删除操作。 关于员工管理的功能&#xff0c;还有两个需要实现&#xff1a; 新增员工 修改员工 首先我们先完成"新增员工"的功能开发&#xff0c;再完成"修改员工"的功能开发。而在&q…

Self-RAG:通过自我反思学习检索、生成和批判

论文地址&#xff1a;https://arxiv.org/abs/2310.11511 项目主页&#xff1a;https://selfrag.github.io/ Self-RAG学习检索、生成和批评&#xff0c;以提高 LM 的输出质量和真实性&#xff0c;在六项任务上优于 ChatGPT 和检索增强的 LLama2 Chat。 问题&#xff1a;万能L…

10分钟完成权限系统全流程开发

背景 首先问下chatgpt,权限系统的模型有哪些&#xff1f; 基于上述的结论&#xff0c;我们选择基于角色的访问控制(RBAC)&#xff0c;请从数据库设计、接口文档、代码实现、单元测试四个方面分别详细描述每个部份需要实现的内容。 数据库实现 针对上述的数据库设计部份&#…

格局打开!前端未死,只是要求变高了

本文笔者会从以下几个方面分享&#xff0c;希望能够帮助正在迷茫的前端小伙伴提供一点思路&#xff01; 逛技术博客 不局限框架 全栈工程师兴起 关注前沿 写技术文章 录制前端视频 总结 2024年了&#xff0c;没工作的找到工作了吗&#xff1f;有工作的加薪了吗&#xff1f;加薪…

【高等数学之极限】

一、引言 我们先思考一下&#xff0c;上面三个表达式&#xff0c;是否可以将极限值直接代入求值&#xff0c;我们在计算之前需要先分析一下&#xff0c;如果将极限值代入&#xff0c;那么表达式将会变成什么形式? 经过上面的分析&#xff0c;我们发现第一个式子可以直接带入&a…

浪花 - 主页开发

一、简易版主页 1. 主页展示用户列表 <template><!--推荐用户列表--><van-cardv-for"user in userList":desc"user.profile":title"${user.username}(${user.planetCode})":thumb"user.avatarUrl"><template #…

VUE表单中多个el-upload上传组件共享回调函数解决方案

产品需求界面&#xff1a; 在产品配置页面表单中需要上传多个图片&#xff0c;项目中上传组件采用Element Plus 中的 el-upload&#xff0c;目前问题是每个上传组件都需要实现自己的回调&#xff0c;比如:on-change&#xff0c;采用官方推荐标准代码如下&#xff1a; <el-fo…

java中的时间API

Created: January 19, 2024 2:31 PM 1、旧版时间API的缺点 在java1.0中使用java.utol.Date类表示时间&#xff0c;该类存在很多问题&#xff0c;例如时间零点是1900年1月0日&#xff0c;例如想到表示2024年1月19日就需要如下定义&#xff0c;此外Date也无法表示时间、包含默认…