libnids中多线程
来源:互联网 发布:淘宝链接短网址转换 编辑:程序博客网 时间:2024/06/05 04:47
可以通过设置全局变量nids_params.multiproc不为0来在libnids中使用多线程捕获数据包。libnids使用的是glib库的gthread-2.0线程函数(该函数库某些函数已经过时,例如线程创建函数;过时的api:https://developer.gnome.org/glib/stable/glib-Deprecated-Thread-APIs.html;新版thread接口:https://developer.gnome.org/glib/stable/glib-Threads.html)。
在libnids1.24源文件libnids.c中nids_run会调用pcap_loop函数进行循环捕获数据包的操作;pcap_loop函数的回调函数nids_pcap_heandler在设置了全局变量multiproc时,会将捕获的数据包片段插入到异步捕获队列中(这里的异步队列是glib的接口,用于在不同线程之间通信,https://developer.gnome.org/glib/stable/glib-Asynchronous-Queues.html)
int nids_run(){ if (!desc) {strcpy(nids_errbuf, "Libnids not initialized");return 0; } START_CAP_QUEUE_PROCESS_THREAD(); /* threading... */ pcap_loop(desc, -1, (pcap_handler) nids_pcap_handler, 0); //循环捕获数据包 /* FIXME: will this code ever be called? Don't think so - mcree */ STOP_CAP_QUEUE_PROCESS_THREAD(); nids_exit(); return 0;}nids_pcap_handler部分代码:
#ifdef HAVE_LIBGTHREAD_2_0 if(nids_params.multiproc) { //如果系统有thread_2_0函数库并设置了使用多线程 /* * Insert received fragment into the async capture queue. * We hope that the overhead of memcpy * will be saturated by the benefits of SMP - mcree */ qitem=malloc(sizeof(struct cap_queue_item)); if (qitem && (qitem->data=malloc(hdr->caplen - nids_linkoffset))) { qitem->caplen=hdr->caplen - nids_linkoffset; memcpy(qitem->data,data_aligned,qitem->caplen); g_async_queue_lock(cap_queue); //为异步队列加锁 /* ensure queue does not overflow,如果队列长度大于全局变量queue_limit的限制就说明overflow了*/ if(g_async_queue_length_unlocked(cap_queue) > nids_params.queue_limit) { /* queue limit reached: drop packet - should we notify user via syslog? */ free(qitem->data); //丢弃数据包数据 free(qitem); //销毁数据包 } else { /* insert packet to queue */ g_async_queue_push_unlocked(cap_queue,qitem); } g_async_queue_unlock(cap_queue); //解锁异步队列} } else { /* user requested simple passthru - no threading */ call_ip_frag_procs(data_aligned,hdr->caplen - nids_linkoffset); } #else call_ip_frag_procs(data_aligned,hdr->caplen - nids_linkoffset); #endif}
可以看出nids_run函数中是通过宏START_CAP_QUEUE_PROCESS_THREAD()来创建新线程的,通过STOP_CAP_QUEUE_PROCESS_THREAD()来销毁线程的。
如下是宏 START_CAP_QUEUE_PROCESS_THREAD()和STOP_CAP_QUEUE_PROCESS_THREAD()的定义:
//g_thread_create_full从version 2.32开始被废弃了 and should not be used in newly-written code.//https://developer.gnome.org/glib/stable/glib-Deprecated-Thread-APIs.html#g-thread-create-full#define START_CAP_QUEUE_PROCESS_THREAD() \ if(nids_params.multiproc) { /* threading... */ \ if(!(g_thread_create_full((GThreadFunc)cap_queue_process_thread,NULL,0,FALSE,TRUE,G_THREAD_PRIORITY_LOW,&gerror))) { \ strcpy(nids_errbuf, "thread: "); \ strncat(nids_errbuf, gerror->message, sizeof(nids_errbuf) - 8); \ return 0; \ }; \ }#define STOP_CAP_QUEUE_PROCESS_THREAD() \ if(nids_params.multiproc) { /* stop the capture process thread */ \ g_async_queue_push(cap_queue,&EOF_item); \ }g_thread_create_full创建新线程,其中第一个参数cap_queue_process_thread是要在新创建的线程里执行的函数,它的定义如下:
/* thread entry point * pops capture queue items and feeds them to * the ip fragment processors - mcree */static void cap_queue_process_thread(){ struct cap_queue_item *qitem; while(1) { /* loop "forever" */ qitem=g_async_queue_pop(cap_queue); if (qitem==&EOF_item) break; /* EOF item received: we should exit */ call_ip_frag_procs(qitem->data,qitem->caplen); free(qitem->data); free(qitem); } g_thread_exit(NULL);}该函数从异步队列中不断取出pcap_loop捕获的数据包,交给call_ip_frag_procs函数进行处理。上面nids_pcap_handler函数的部分代码中可以看出,如果没有设置使用多线程,那么直接在nids_pcap_handler函数中就使用call_ip_frag_procs函数处理数据包了。接下来处理过程参考http://blog.csdn.net/u013074465/article/details/45555837
0 0
- libnids中多线程
- 移植libnids 郁闷中
- libnids
- libnids 中ipfrag重组的实现机制
- libnids 中tcp流重组代码
- Libnids中tcp流处理"tcp.c"
- Libnids中tcp重组的实现
- 基于libnids的TCP数据流的还原(多线程实现)
- 基于libnids的TCP数据流的还原(多线程实现)
- 基于libnids的TCP数据流的还原(多线程实现)
- 基于libnids的TCP数据流的还原(多线程实现)
- libnids-1.21 中 IP 分片重组分析 之代码
- libnids-1.21 中 IP 分片重组分析 之代码
- libnids 中关于监测ddos攻击的设计
- libnids 在VS 2010中使用方法及编译错误解决方法
- libnids中主要数据结构和函数“nids.h”
- libnids study
- libnids使用
- curl登录采集
- html5动效系列二:超级惊艳 10款HTML5动画特效推荐
- 【递归】排列问题,整数划分问题,Hanoi
- windows C++多线程编程高级篇 实现线程同步
- 常用meta整理
- libnids中多线程
- ifconfig: command not found
- 开源代码链接
- 考研——留给多年以后自己看
- curl-post-files
- 什么是M3U8,与HTML5的区别是什么
- 分页类PageBean的代码
- mybatis3中@SelectProvider的使用技巧
- C++Primer再起航