本篇文章将分析一下suricata中的流表管理,包括流表初始化,流的新建以及流的老化。

对于任何的网络分析工具和产品来说,流管理都是非常重要的一个方面。所谓的流就是由源目的IP,源目的端口以及传输层的协议构成的通信双方的虚拟链接,有了这条虚拟链接之后,数据包就可以在网络上中有目的的传输。通常来说网络分析工具和产品,通过五元组建立起流表之后,每处理一个报文,这个报文通常就会归属一个流,相当于对于报文进行了一次分类。同一条流上的报文就可以进行TCP的重组等一些重要的操作。

对于suricata来说流管理主要涉及到如下几个方面:

  • 1,流表的初始化。
  • 2,每一条流上下文的申请和建立。
  • 3,每一条流上下文的老化,释放等等。

流表的初始化

流表初始化对应的函数为FlowInitConfig,该函数在suricata初始化阶段被调用,具体调用函数为PreRunInit。该函数的主要目的是初始化流的一些参数,包括流表占用的内存大小,流哈希表的长度,预分配的流表个数。当然初始化这些参数有两种方式,一种使用系统默认的方式,另外一种通过读取suricata.yaml配置文件中的配置。

流表占用内存指的是suricata给流表设置的内存大小,但是其实更常用的做法是设置流表的长度,也就是流表支持多少条流的存储。当然这个地方也是可以转换的,每一条流占用的内存空间在FlowAlloc有所体现,为size_t size = sizeof(Flow) + FlowStorageSize();,用总内存除以每条流的内存即可以得到流表的大小。系统默认的流内存大小为32M。

由于流表是使用哈希表这样的数据结构来组织的,流哈希表的长度即哈希表的长度,默认的值为65535。哈希的计算函数为FlowGetHash,由于哈希存在冲突,因此每一项下面可能会下挂多个流,用哈希桶进行存储。

预分配流表个数指的是在初始化的时候预先申请流个数,当系统运行起来,动态的申请内存对于系统的处理性能有一定的影响,因此会预先申请一定数量的流内存,默认值为10000。这里就是配置的流个数。而不像前面配置的是内存。如下代码是FlowInitConfig函数中预先申请流内存的代码片段:

/* pre allocate flows */for (i = 0; i < flow_config.prealloc; i++) {if (!(FLOW_CHECK_MEMCAP(sizeof(Flow) + FlowStorageSize()))) {SCLogError(SC_ERR_FLOW_INIT, "preallocating flows failed: ""max flow memcap reached. Memcap %"PRIu64", ""Memuse %"PRIu64".", SC_ATOMIC_GET(flow_config.memcap),((uint64_t)SC_ATOMIC_GET(flow_memuse) + (uint64_t)sizeof(Flow)));exit(EXIT_FAILURE);}Flow *f = FlowAlloc();if (f == NULL) {SCLogError(SC_ERR_FLOW_INIT, "preallocating flow failed: %s", strerror(errno));exit(EXIT_FAILURE);}FlowEnqueue(&flow_spare_q,f);}

可以看到对于申请的流表内存,都会放入flow_spare_q这样一个全局队列进行管理。在系统运行起来之后,流建立的时候都会从flow_spare_q队列中欧取一条流的内存空间进行使用。

除了上述三个参数的初始化,在FlowInitFlowProto函数中对于流老化时长也有进行初始化。suricata对于不同协议的流以及流的不同阶段都定义了不同的老化时长。可以明显的看到对于TCP流的初建阶段的老化时长默认值为FLOW_IPPROTO_TCP_NEW_TIMEOUT 30秒,而对于TCP握手完成之后的流老化时长默认为FLOW_IPPROTO_TCP_EST_TIMEOUT 300秒。

其实除此之外还有更为复杂的机制就是当流内存不够用的时候,会启用一个紧急状态机制,这个时候不同协议以及不同流状态的老化时间会大大的缩短,加速流表老化。以腾出更多的内存空间为新流所用,例如紧急状态下TCP流的初建阶段的老化时长默认值为FLOW_IPPROTO_TCP_EMERG_NEW_TIMEOUT 10秒,而对于TCP握手完成之后的流老化时长默认为FLOW_IPPROTO_TCP_EMERG_EST_TIMEOUT 100秒。

流的新建

suricata中有几个比较重要的模块,例如收包,解码以及检测处理,分别对应像,TmModuleReceivePcapFileRegisterTmModuleDecodePcapFileRegisterTmModuleFlowWorkerRegister这样几个注册模块中的功能。像流建立的处理就在TmModuleFlowWorkerRegister模块中 的FlowWorker函数中。

suricata的策略是当流的第一个包到来的时候就回去申请这条流的内存空间,虽然有PKT_WANTS_FLOW这样一个标志位的判断,但是对于像TCP,UDP,STCP,ICMP等需要建流的协议来说,每一个包都会在FlowSetupPacket函数中打上这个标志,因此基本上这列协议的包都会进入FlowHandlePacket->FlowGetFlowFromHash去寻找流表,根据五元组等值通过FlowGetHash计算的哈希值,直接去flow_hash表中索引对应的项。然后再去判断该项下面的哪一个哈希桶是目的流。

  • 1,如果找到目的流,则首先将该流的哈希桶放到,该索引下链表的头部,因为这是最新的活动流,下一个报文还有可能是该流的报文,主要是降低哈希桶匹配的查询次数。其次为了线程安全,防止其他线程对于该条流的读写,需要将该流加上读写锁,FLOWLOCK_WRLOCK(f);。也就是说在该报文的处理期间,本线程享有对于该流的读写操作,禁止其他线程的操作。什么时候去锁,就是在对该报文处理结束的时候去锁。可以发现在FlowWorker函数中return的地方,会有对于流的去锁操作FLOWLOCK_UNLOCK(p->flow);
  • 2,当然如果遍历该项所有的哈希桶没有找到目的流,这个时候就会调用FlowGetNew函数进行去新建流。创建新流最主要的动作就是申请流的内存空间。由于在流表初始化阶段,在flow_spare_q变量中提前申请了一定的流内存空间。因此首先去flow_spare_q对联中看看有没有内存空间使用,如果有,直接返回该流即可。如果没有,第一步先检查给流表分配的空间有没有被使用完,没有则调用FlowAlloc函数申请内存并返回即可。如果内存空间被使用完毕,这个时候就需要老化一部分流,也就是将存在时间较长的一部分流的内存回收供新流使用。共分为三个步奏:1,FlowTimeoutsEmergency启动紧急模式,缩短老化时长。2,FlowWakeupFlowManagerThread启动老化线程。3,当然在第二步的时候可能会由于老化时长没到,没有流老化释放出来,这个时候就会调用FlowGetUsedFlow函数。在该函数中,会遍历整个哈希表,找到某个索引项下面存在时长最长的那个流,复用其内存。当然哪些被上锁的索引项是不能够被回收的。如果遍历完整个哈希表,仍然没有可用的,则只能返回NULL。

流表的老化

在上述也提到了流表的老化,就是函数FlowManager的功能之一。FlowManager首先会调用FlowUpdateSpareFlows,该函数的目的就是更新备用流内存,也就是flow_spare_q队列的内容。前面提到在suricata初始化阶段,会设置预分配的流个数,并申请对应的内存交由flow_spare_q进行管理。FlowUpdateSpareFlows的目的就是检查当备用流个数小于预设值的时候,进行流内存申请,入队;当大于预设值的时候,进行流内存的释放,出队。实现流老化功能的函数为FlowTimeoutHash->FlowManagerHashRowTimeout

FlowManagerHashRowTimeout函数中:

  • 1,FlowManagerFlowTimeout判断该条流的老化时长有没有到;
  • 2,FlowManagerFlowTimedOut函数确定是都能够老化该流,因为虽然有的流老化时长到了,但是需要进行TCP重组,这个时候就不能够老化该流。
  • 3,将老化的流方式flow_recycle_q全局队列中。函数FlowRecycler会由一个单独的线程处理这种别老化的流,在改函数中,会FlowClearMemory清空该流的内存,清空之后通过FlowMoveToSpare函数方式备用流flow_spare_q中,当然flow_spare_q的管理就是刚刚提到的。总的原则就是流内存的申请是一个比较耗时的动作,并不会轻易的将其释放,最好用于重用。

FlowManager函数之中除了FlowTimeoutHash用于老化流,还有DefragTimeoutHash,HostTimeoutHash,IPPairTimeoutHash这三个老化的函数,那么这些函数的作用是什么?同时在FlowAlloc函数中,可以看到申请的内存空间为size_t size = sizeof(Flow) + FlowStorageSize();,即流结构体的大小加上flow storage的大小,这个flow storage又是什么呢?这些方面的内容将在下一篇进行介绍。

本文为CSDN村中少年原创文章,转载记得加上原创出处,博主链接这里。

suricata源码之-流表管理相关推荐

  1. Redis如何实现分布式锁延时队列以及限流应用丨Redis源码原理|跳表|B+树|分布式锁|中间件|主从同步|存储原理

    Redis如何实现分布式锁延时队列以及限流应用 视频讲解如下,点击观看: Redis如何实现分布式锁延时队列以及限流应用丨Redis源码原理|跳表|B+树|分布式锁|中间件|主从同步|存储原理|数据模 ...

  2. suricata源码之tag

    tag是suricata提供的一个规则关键字,但是在suricata的说明文档,这里并没有给出关键字的解释,因为他是为了兼容snort规则而支持的一个关键字. tag的字面含义就是标签的意思.通常来说 ...

  3. RocketMQ4.0源码分析之-路由管理

    RocketMQ4.0源码分析之-路由管理 一 前言 路由管理功能是RocketMQ的核心功能之一,涵盖了订阅管理,连接管理,负载均衡管理等一系列功能,代码布在NameServer,Broker,Pr ...

  4. 美容院SPA会员管理系统源码 美容行业会员管理收银系统源码

    美容院SPA会员管理系统源码 美容行业会员管理收银源码 开发语言:PHP 数据库:MySQL 开发工具:phpstrom 源码类型:全开源免费分享 该套会员管理系统是一套通用性强.功能强大的会员管理系 ...

  5. caffe源码分析--SyncedMemory 内存管理机制

    caffe源码分析–SyncedMemory 内存管理机制 ​ SyncedMemory 是caffe中用来管理内存分配和CPU.GPU数据及同步的类,只服务于Blob类.SyncedMemory 对 ...

  6. 修改gh-ost源码实现两表在线高速复制

    修改gh-ost源码实现两表在线高速复制 一.问题起源 笔者所在的公司的需要对核心业务表tb_doc 进行表分区,目前该表的记录数为190,522,155. 由于该表没有分区,新增分区需要创建影子表, ...

  7. Mybatis源码分析--关联表查询及延迟加载原理(二)

    在上一篇博客Mybatis源码分析--关联表查询及延迟加载(一)中我们简单介绍了Mybatis的延迟加载的编程,接下来我们通过分析源码来分析一下Mybatis延迟加载的实现原理. 其实简单来说Myba ...

  8. Linux内核源码分析《进程管理》

    Linux内核源码分析<进程管理> 前言 1. Linux 内核源码分析架构 2. 进程原理分析 2.1 进程基础知识 2.2 Linux进程四要素 2.3 进程描述符 task_stru ...

  9. C#源码 +sqlserver包含库存管理、销售管理

    C#源码 +sqlserver包含库存管理.销售管理.采购管理.委外加工管理.生产管理.财务管理.基础数据管理.系统管理.文件管理.设备管理.权限管理等模块,完全开源,支持二次开发. 编号:85765 ...

最新文章

  1. bash的常见命令及文章查看命令
  2. 快捷启动_start for mac(快捷启动应用)
  3. 听得我都激动了……喝死奥巴马,你怎么看?
  4. 【算法】算法测试题4:最长公共连续子串
  5. 通过ClassLoader加载硬盘上的图片到内存及ImageIO的使用
  6. Spring.NET学习笔记——前言
  7. flink实时机器学习-alink在线机器学习remote模式贝叶斯建模实验记录
  8. 哈夫曼编码和带权路径计算
  9. php foreach结果如何保存_每天一个PHP语法四引用使用及实现
  10. java特殊字符转义html_java转义html特殊字符
  11. 惠普企业(HPE)是否免不了最终被关停的命?
  12. Delphi中Chrome Chromium、Cef3学习笔记(三)
  13. # 20145205 《Java程序设计》第1周学习总结
  14. Abaqus 子结构分析 实例
  15. X度网盘大文件使用浏览器或迅雷下载的方法之一
  16. Python3.8场景式编程学习与训练- 第1章 入门基础 Python学习方法论与学习资源
  17. 【2022-12-10 修订】如何将 BD(蓝光光盘)备份到硬盘 · 播放 BD 和 UHD BD
  18. 【服务器数据恢复】nas存储服务器的数据恢复案例
  19. csgo服务器搭建文件,CSGO服务器架设.doc
  20. JAVA回文数的判断

热门文章

  1. Hadoop (海量数据存储及计算) 基本概念
  2. 数据中台实战(三):用户分析(产品设计篇)
  3. ios 图像坐标系_Mac,iOS界面中的三维坐标系
  4. 剧版《三体》曝光清华“飞刃”成果:现实里长这样,太空电梯和碳基芯片都能用...
  5. 来自上海市的匿名人士对新闻:360:要起诉金山的评论
  6. 我的2019年度代码报告
  7. 三国塔防游戏android源码
  8. 大数据分析案例:每日各时段的PV和UV分析。使用框架:hadoop,Hvie,Sqoop
  9. STM32单片机修改串口波特率
  10. android toolbar 自定义,自定义Toolbar,解决你所有的适配苦恼!