• suricata 流管理


    flow相关文件及作用

    1. flow.h flow.c:
    2. flow-worker.h flow-worker.c:
    3. flow-hash.h flow-hash.c:
    4. flow-manager.h flow-manager.c:
    5. flow-timeout.h flow-timeout.c:
    6. flow-queue.h flow-queue.c
    7. flow-private.h
    8. tmqh-flow.c tmqh-flow.h
    9. flow-storage.h flow-storage.c
    10. flow-util.h flow-util.c
    11. output-json-flow.c output-json-flow.h
    12. detect-flow.h detect-flow.c
    13. detect-flowbits.h detect-flowbits.c
    14. detect-flowint.h detect-flowint.c
    15. detect-flowvar.h detect-flowvar.c
    16. flow-bit.h flow-bit.c
    17. flow-bypass.h flow-bypass.c
    18. flow-spare-pool.h flow-spare-pool.c
    19. output-flow.h output-flow.c
    20. flow-var.c flow-var.h
    1. flow-var:
    2. 定义flow变量,有两种类型,分别是FLOWVAR_TYPE_STR和FLOWVAR_TYPE_INT。
    3. ①FlowVarTypeStr结构体:FLOWVAR_TYPE_STR类型,包含内容和长度。
    4. ②FlowVarTypeInt结构体:FLOWVAR_TYPE_INT类型, 包含内容。
    5. ③FlowVar结构体:Flowvar的带索引的单向链表。
    6. ④FlowVarAddIdValue函数:通过idx从flow中拿flowvar,没拿到就新建一个,然后把value(STR)放进去,追加到flow的flowvar链表之后。
    7. ⑤FlowVarAddKeyValue函数:新建一个flowvar,value放进去,追加到flow的flowvar链表之后。
    8. ⑥FlowVarAddIntNoLock函数:通过idx从flow中拿flowvar,没拿到就新建一个,然后把value(int)放进去,追加到flow的flowvar链表之后。
    9. ⑦FlowVarAddInt函数:调用FlowVarAddIntNoLock。
    10. ⑧FlowVarGet函数:通过idx 获取flow中的flowvar
    11. ⑨FlowVarGetByKey函数:当idx为0,获取与key值相同的flow-》flowvar。
    12. ⑩FlowVarFree函数
    13. 11.FlowVarPrint函数

    flow-manager:

    ①FlowTimeoutsInit函数:从flow_timeouts_normal中拿超时时间flow_timeouts

    ②FlowTimeoutsEmergency函数:从flow_timeouts_emerg中拿超时时间flow_timeouts

    ③FlowManagerThreadSpawn函数

    ④FlowDisableFlowManagerThread函数

    ⑤FlowRecyclerThreadSpawn函数

    ⑥FlowDisableFlowRecyclerThread函数

    ⑦TmModuleFlowManagerRegister函数

    ⑧TmModuleFlowRecyclerRegister函数

    ⑨FlowTimeoutCounters结构

    flow-private:

    ①FlowGetFlowTimeoutDirect函数:判断NEW、ESTABLISHED、CLOSED、OFFLOAD、LOCAL_BYPASSED超时(只要有一个超时即超时)

    ①FlowGetFlowTimeout函数

    ①FlowGetTimeoutPolicy函数

    ①FlowGetFlowTimeoutDirect函数

    一、Flow

    所有相同元组(协议,源IP,目的IP,源端口,目的端口)的包分组属于同一流。使用flow管理一个会话。

    通常我们也指从一端到另一端的一次网络数据传输过程。其包含连接的建立,数据的传输。一条流往往指的是一次完成的数据传输,其包含了该过程中所有的数据包。但是一个连接可以有多个流,即在连接建立之后,可以有多次的数据传输。

    二、Flow的管理

    suricata实现了流管理机制来回收与重复利用Flow。suricata使用三个线程维护这三个队列(Flow哈希表,Flow备用队列,Flow回收队列)。

    其中:

    2.1 线程

            ①FlowManager线程:从流表中摘除超时的流放入回收队列,检查空闲队列长度是否为预设值,若过长则释放一部分,若过短则申请一部分。

    1. // 根据配置创建flow_managers线程个数
    2. void FlowManagerThreadSpawn()
    3. {
    4. intmax_t setting = 1;
    5. (void)ConfGetInt("flow.managers", &setting);
    6. if (setting < 1 || setting > 1024) {
    7. FatalError(SC_ERR_INVALID_ARGUMENTS,
    8. "invalid flow.managers setting %"PRIdMAX, setting);
    9. }
    10. flowmgr_number = (uint32_t)setting;
    11. SCLogConfig("using %u flow manager threads", flowmgr_number);
    12. StatsRegisterGlobalCounter("flow.memuse", FlowGetMemuse);// 注册一个全局的原子的flow计数器flow_memuse
    13. for (uint32_t u = 0; u < flowmgr_number; u++) {
    14. char name[TM_THREAD_NAME_MAX];
    15. snprintf(name, sizeof(name), "%s#%02u", thread_name_flow_mgr, u+1);
    16. ThreadVars *tv_flowmgr = TmThreadCreateMgmtThreadByName(name,
    17. "FlowManager", 0);// 创建线程变量结构体
    18. BUG_ON(tv_flowmgr == NULL);
    19. if (tv_flowmgr == NULL) {
    20. FatalError(SC_ERR_FATAL, "flow manager thread creation failed");
    21. }
    22. if (TmThreadSpawn(tv_flowmgr) != TM_ECODE_OK) { // 根据生成的线程名创建线程
    23. FatalError(SC_ERR_FATAL, "flow manager thread spawn failed");
    24. }
    25. }
    26. return;
    27. }

            ②FlowRecyler线程:从回收队列中摘除Flow,调用注册流输出模块的回掉,清空Flow信息,插入回收队列。

            ③FlowWorker线程

    • 对于新到达的包,在流表中查找其对应Flow结构,若存在则直接引用
    • 若流表中不存在对应此包的Flow结构,则按如下优先级获取一个新的Flow结构
      1. 从空闲队列中取出一个Flow结构
      2. 重新申请一个Flow结构
      3. 从流表中去除一个当前未被引用的Flow结构,清空其内容并重新插入流表

    2.2 三种队列

    Flow哈希表: 这个是FlowBucket *flow_hash 数组,数据大小为配置中的 flow_config 的 hash_size,其在数组中的每一个FlowBucket元素中都挂了一串之前数据包对应的Flow链队列。

    Flow备用队列: static FlowSparePool *flow_spare_pool 备用池链队列,其每一个链pool中都挂载一个备用Flow队列。

    Flow回收队列: FlowQueue flow_recycle_q 回收队列,挂载一个备用Flow队列。

    2.3 Flow管理流程

    ①当一个数据包来到时,计算数据包对应的hash值

    ②在后续的模块中将使用这个hash 在Flow哈希表中找到 FlowBucket ,不同会话的hash值可能相同,所以不是比较hash相同来定位Flow,而是在篮子里顺序查找具有相同五元组和vlan的Flow,找到则利用此Flow

    ③若Flow哈希表中没有,则在Flow备用队列取出一个Flow, 或是新建一个Flow使用,同时把这个Flow插入到Flow哈希表


     

  • 相关阅读:
    前端获取图片宽高的几种方法
    自然语言处理(一):基于统计的方法表示单词
    微信最新更新隐私策略(2023-08-15)
    SpringBoot框架学习(三)——热部署,整合Redis
    day17 正则表达式+今日作业
    万字摸透Redis、MySQL和ZooKeeper分布式锁,还不会的出来!
    Kubernetes PV与PVC 持久卷应用
    强网杯2022 pwn 赛题解析——yakacmp
    科普达人丨漫画图解什么是eRDMA?
    使用表单登录方法模拟登录通信人家园,要求发送登录请求后打印出来的用户名下的用户组类别
  • 原文地址:https://blog.csdn.net/clygo9/article/details/127431072