再从main()函数看起 --- 模式、模块、线程和槽

转载 2014年05月19日 09:52:12
经过上面几篇Blog的学习步骤,到今天再回过头去看了下main函数的执行过程,把重点几个步骤重新整理了下,方便更深入的理解架构。

1. 注册各种运行模式
   RunModeRegisterRunModes()函数
   
   RunModeIdsPcapRegister();      // IDS+pcap
   RunModeFilePcapRegister();     // File+pcap
   RunModeIdsPfringRegister();    // IDS+pfring
   RunModeIpsIPFWRegister();      // IPS+ipfw
   RunModeIpsNFQRegister();       // IPS+nfq
   RunModeErfFileRegister();      // erf+file
   RunModeErfDagRegister();       // erf+dag
   RunModeNapatechRegister();     // napatech
   RunModeIdsAFPRegister();       // IDS+AFP
   RunModeUnixSocketRegister();   // UnixSocket
   其中每一种运行模式调用RunModeRegisterNewRunMode注册各自的Custom mode(暂且翻译为“自定义模式”)
   
   RunModeRegisterNewRunMode设置各种运行模式的执行函数
   例如:RunModeRegisterNewRunMode(RUNMODE_PCAP_DEV, "single",
                              "Single threaded pcap live mode",
                              RunModeIdsPcapSingle);
   将执行函数添加到runmodes全局数组中。
   全局Runmodes类型数组runmodes保存运行模式,存储结构如下图:
   

2. 注册模块
   注册suricata所支持的所有线程模块
   
   TmModuleReceiveNFQRegister();
   TmModuleVerdictNFQRegister();
   TmModuleDecodeNFQRegister();
   
   TmModuleReceiveIPFWRegister();
   TmModuleVerdictIPFWRegister();
   TmModuleDecodeIPFWRegister();
   
   TmModuleReceivePcapRegister();
   TmModuleDecodePcapRegister();
   
   TmModuleReceivePcapFileRegister();
   TmModuleDecodePcapFileRegister();
   ……
   ……
   函数内部实现:
   void TmModuleReceivePcapRegister (void) 
   {
    tmm_modules[TMM_RECEIVEPCAP].name = "ReceivePcap";
    tmm_modules[TMM_RECEIVEPCAP].ThreadInit = ReceivePcapThreadInit;
    tmm_modules[TMM_RECEIVEPCAP].Func = NULL;
    tmm_modules[TMM_RECEIVEPCAP].PktAcqLoop = ReceivePcapLoop;
    tmm_modules[TMM_RECEIVEPCAP].ThreadExitPrintStats = ReceivePcapThreadExitStats;
    tmm_modules[TMM_RECEIVEPCAP].ThreadDeinit = NULL;
    tmm_modules[TMM_RECEIVEPCAP].RegisterTests = NULL;
    tmm_modules[TMM_RECEIVEPCAP].cap_flags = SC_CAP_NET_RAW;
    tmm_modules[TMM_RECEIVEPCAP].flags = TM_FLAG_RECEIVE_TM;
   }
   保存在全局TmModule tmm_modules[TMM_SIZE]数组中。
   typedef struct TmModule_ 
   {
      char *name;
      TmEcode (*ThreadInit)(ThreadVars *, void *, void **); // 线程初始化函数
      void (*ThreadExitPrintStats)(ThreadVars *, void *); // 线程退出打印函数
      TmEcode (*ThreadDeinit)(ThreadVars *, void *); // 线程关闭函数
      TmEcode (*Func)(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *);
      TmEcode (*PktAcqLoop)(ThreadVars *, void *, void *);
      TmEcode (*Init)(void);// 全局初始化模块函数
      TmEcode (*DeInit)(void);// 全局关闭模块函数
      void (*RegisterTests)(void);
      uint8_t cap_flags;  
      uint8_t flags;
    } TmModule;
  
  存储结构如下图所示:
   
3. 模块初始化
   TmModuleRunInit()函数
   调用tmm_modules[TMM_SIZE]数组中模块各个模块初始化函数。
    for (i = 0; i < TMM_SIZE; i++)
    {
        t = &tmm_modules[i];
        t->Init(); // 注意这里执行的是模块全局初始化函数
    }

4. 运行模式调度
   RunModeDispatch()函数
  • 从配置中读取运行模式。
  • 获得该运行模式中默认的Custom mode(如:single、auto等)。
  • 执行Custom mode中设置的执行函数,如上图中所示的“执行函数”。

5. 运行模式执行函数
   例如:RunModeFilePcapSingle()
  • 通用模块初始化RunModeInitialize
  • 创建tv实例TmThreadCreatePacketHandler
  • 从tmm_modules中获得模块TmModuleGetByName
  • 插入槽slot
  • TmThreadSpawn真正创建线程函数


整理下执行顺序:
  • 运行模式注册,设置执行函数
  • 所有模块注册,设置模块相关函数
  • 所有模块初始化
  • 从配置获取运行模式类型,执行函数
  • 创建线程
  • 根据模块名称从全局数组tmm_modules中得到模块指针
  • 插入线程槽slot

线程、槽和模块之间的关系

suricata中tv、slot和tm的关系必须要搞清楚,汇总如下: tv:ThreadVars类型,线程。 slot:TmSlot类型,槽。 tm:TmModule类型,模块。 ...
  • wsk004321
  • wsk004321
  • 2014年05月15日 17:57
  • 1150

Python中'__main__'模块的作用

Python不同于C/C++,程序执行并不需要主程序,如main(),而是文件自上而下的执行。 但很多Python程序中都有 if __name__ == '__main__': statem...
  • rena521
  • rena521
  • 2015年07月15日 16:53
  • 1972

js模块化编程一:模块化函数的介绍

js模块化一:模块化函数的介绍
  • fengchao2016
  • fengchao2016
  • 2017年01月15日 17:45
  • 414

线程、槽和模块之间的关系

suricata中tv、slot和tm的关系必须要搞清楚,汇总如下: tv:ThreadVars类型,线程。 slot:TmSlot类型,槽。 tm:TmModule类型,模块。 ...
  • wsk004321
  • wsk004321
  • 2014年05月15日 17:57
  • 1150

c#学习笔记之十五 目前多线程执行函数的思路

1.如果不用传递和返回结果,仅仅是执行代码体,则直接在新建线程的时候传递函数的名词。 2.如果需要传递参数或(和)返回结果,那么就使用函数代表的BeginInvoke()和EndInvoke()方法,...
  • CGGUANG
  • CGGUANG
  • 2016年12月11日 18:20
  • 523

Python模块及函数的使用

一. 1.模块是包含函数和其他语句的脚本文件,以".py"为后缀名,在Python中可以通过导入模块来使用模块中的函数或数据. 创建一个文件fun.py内容如下: [python] def f...
  • a6225301
  • a6225301
  • 2015年03月23日 17:28
  • 1561

Python 学习笔记二 函数、模块和对象

Python 学习笔记二 函数、模块和对象定义函数def printme( str ): "打印传入的字符串到标准显示设备上" print str return调用:printme(...
  • xundh
  • xundh
  • 2016年07月22日 09:57
  • 796

模块(加载函数和卸载函数)

Linux模块是一些代码的集成,可以在启动系统后动态链接到内核的一部分,一旦载入之后就和内核没有什么区别,可以使内核崩溃。当不需要这些模块时,又可以断开链接将其删除。Linux的模块可以用C语言来编写...
  • LDan508
  • LDan508
  • 2016年01月18日 10:56
  • 1042

main函数之前--真正的函数执行入口或开始

现在最重要的是要跟得上潮流,所以套用比较时髦的话,谁动了我的奶酪。谁调用了我的 main?不过作为计算机工作者,我劝大家还是不要赶时髦,今天Java热,明天 .net 流行,什么时髦就学什么。我的意思...
  • a511244213
  • a511244213
  • 2015年04月11日 13:38
  • 2120

模块与进程的关系

模块分为进程内和进程外两种类型 前者共享进程空间,比如许多在进程中加载的dll 后者与进程一样,独立运行,通常供其它进程调用(由引用计数之类的管理)...
  • u012564690
  • u012564690
  • 2014年05月18日 23:15
  • 1494
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:再从main()函数看起 --- 模式、模块、线程和槽
举报原因:
原因补充:

(最多只允许输入30个字)