diff --git a/src/counters.c b/src/counters.c index 2b3d0c92d1..8aea93e650 100644 --- a/src/counters.c +++ b/src/counters.c @@ -292,6 +292,8 @@ static char *SCPerfGetLogFilename(void) */ static void SCPerfInitOPCtx(void) { + SCEnter(); + if ( (sc_perf_op_ctx = SCMalloc(sizeof(SCPerfOPIfaceContext))) == NULL) { SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCPerfInitOPCtx. Exiting..."); exit(EXIT_FAILURE); @@ -328,7 +330,7 @@ static void SCPerfInitOPCtx(void) exit(EXIT_FAILURE); } - return; + SCReturn; } /** @@ -958,7 +960,6 @@ static int SCPerfOutputCounterFileIface() if (sc_perf_op_ctx->club_tm == 0) { for (u = 0; u < TVT_MAX; u++) { tv = tv_root[u]; - if (pc_heads == NULL || pc_heads[u] == NULL) continue; @@ -1003,17 +1004,18 @@ static int SCPerfOutputCounterFileIface() pctmi = sc_perf_op_ctx->pctmi; while (pctmi != NULL) { - if ( (pc_heads = SCMalloc(pctmi->size * sizeof(SCPerfCounter *))) == NULL) + if ((pc_heads = SCMalloc(pctmi->size * sizeof(SCPerfCounter *))) == NULL) return 0; - memset(pc_heads, 0, pctmi->size * sizeof(SCPerfCounter **)); + memset(pc_heads, 0, pctmi->size * sizeof(SCPerfCounter *)); for (u = 0; u < pctmi->size; u++) { pc_heads[u] = pctmi->head[u]->head; SCMutexLock(&pctmi->head[u]->m); - while(strcmp(pctmi->tm_name, pc_heads[u]->name->tm_name)) + while(pc_heads[u] != NULL && strcmp(pctmi->tm_name, pc_heads[u]->name->tm_name)) { pc_heads[u] = pc_heads[u]->next; + } } flag = 1; @@ -1364,6 +1366,7 @@ int SCPerfAddToClubbedTMTable(char *tm_name, SCPerfContext *pctx) SCMutexLock(&sc_perf_op_ctx->pctmi_lock); pctmi = sc_perf_op_ctx->pctmi; + SCLogDebug("pctmi %p", pctmi); prev = pctmi; while (pctmi != NULL) { @@ -1381,8 +1384,8 @@ int SCPerfAddToClubbedTMTable(char *tm_name, SCPerfContext *pctx) return 0; memset(temp, 0, sizeof(SCPerfClubTMInst)); - temp->size++; - temp->head = SCRealloc(temp->head, temp->size * sizeof(SCPerfContext **)); + temp->size = 1; + temp->head = SCMalloc(sizeof(SCPerfContext **)); if (temp->head == NULL) return 0; temp->head[0] = pctx; @@ -1397,6 +1400,7 @@ int SCPerfAddToClubbedTMTable(char *tm_name, SCPerfContext *pctx) return 1; } + /* see if the pctx is already part of this pctmi */ hpctx = pctmi->head; for (u = 0; u < pctmi->size; u++) { if (hpctx[u] != pctx) diff --git a/src/runmodes.c b/src/runmodes.c index 3255a0af0d..51e01ec82c 100644 --- a/src/runmodes.c +++ b/src/runmodes.c @@ -2415,6 +2415,167 @@ int RunModeFilePcapAuto(DetectEngineCtx *de_ctx, char *file) { return 0; } +/** + * \brief RunModeFilePcapAuto set up the following thread packet handlers: + * - Receive thread (from pcap file) + * - Decode thread + * - Stream thread + * - Detect: If we have only 1 cpu, it will setup one Detect thread + * If we have more than one, it will setup num_cpus - 1 + * starting from the second cpu available. + * - Outputs thread + * By default the threads will use the first cpu available + * except the Detection threads if we have more than one cpu + * + * \param de_ctx pointer to the Detection Engine + * \param file pointer to the name of the file from which we will fetch + * the packets + * \retval 0 if all goes well. (If any problem is detected the engine will + * exit()) + */ +int RunModeFilePcapAutoFp(DetectEngineCtx *de_ctx, char *file) { + SCEnter(); + char tname[12]; + char qname[12]; + uint16_t cpu = 0; + char queues[2048] = ""; + + RunModeInitialize(); + + /* Available cpus */ + uint16_t ncpus = UtilCpuGetNumProcessorsOnline(); + + /* start with cpu 1 so that if we're creating an odd number of detect + * threads we're not creating the most on CPU0. */ + if (ncpus > 0) + cpu = 1; + + /* always create at least one thread */ + int thread_max = ncpus * threading_detect_ratio; + if (thread_max < 1) + thread_max = 1; + + int thread; + for (thread = 0; thread < thread_max; thread++) { + if (strlen(queues) > 0) + strlcat(queues, ",", sizeof(queues)); + + snprintf(qname, sizeof(qname),"pickup%"PRIu16, thread+1); + strlcat(queues, qname, sizeof(queues)); + } + printf("queues %s\n", queues); + + SCLogDebug("file %s", file); + TimeModeSetOffline(); + + /* create the threads */ + ThreadVars *tv_receivepcap = TmThreadCreatePacketHandler("ReceivePcapFile","packetpool","packetpool",queues,"flow","varslot"); + if (tv_receivepcap == NULL) { + printf("ERROR: TmThreadsCreate failed\n"); + exit(EXIT_FAILURE); + } + TmModule *tm_module = TmModuleGetByName("ReceivePcapFile"); + if (tm_module == NULL) { + printf("ERROR: TmModuleGetByName failed for ReceivePcap\n"); + exit(EXIT_FAILURE); + } + TmVarSlotSetFuncAppend(tv_receivepcap,tm_module,file); + + tm_module = TmModuleGetByName("DecodePcapFile"); + if (tm_module == NULL) { + printf("ERROR: TmModuleGetByName DecodePcap failed\n"); + exit(EXIT_FAILURE); + } + TmVarSlotSetFuncAppend(tv_receivepcap,tm_module,NULL); + + if (threading_set_cpu_affinity) { + TmThreadSetCPUAffinity(tv_receivepcap, 0); + if (ncpus > 1) + TmThreadSetThreadPriority(tv_receivepcap, PRIO_MEDIUM); + } + + if (TmThreadSpawn(tv_receivepcap) != TM_ECODE_OK) { + printf("ERROR: TmThreadSpawn failed\n"); + exit(EXIT_FAILURE); + } + + for (thread = 0; thread < thread_max; thread++) { + snprintf(tname, sizeof(tname),"Detect%"PRIu16, thread+1); + snprintf(qname, sizeof(qname),"pickup%"PRIu16, thread+1); + + printf("tname %s, qname %s\n", tname, qname); + + char *thread_name = SCStrdup(tname); + SCLogDebug("Assigning %s affinity to cpu %u", thread_name, cpu); + + ThreadVars *tv_detect_ncpu = TmThreadCreatePacketHandler(thread_name, qname, "flow","alert-queue1","ringbuffer","varslot"); + if (tv_detect_ncpu == NULL) { + printf("ERROR: TmThreadsCreate failed\n"); + exit(EXIT_FAILURE); + } + tm_module = TmModuleGetByName("StreamTcp"); + if (tm_module == NULL) { + printf("ERROR: TmModuleGetByName StreamTcp failed\n"); + exit(EXIT_FAILURE); + } + TmVarSlotSetFuncAppend(tv_detect_ncpu,tm_module,NULL); + + tm_module = TmModuleGetByName("Detect"); + if (tm_module == NULL) { + printf("ERROR: TmModuleGetByName Detect failed\n"); + exit(EXIT_FAILURE); + } + TmVarSlotSetFuncAppend(tv_detect_ncpu,tm_module,(void *)de_ctx); + + if (threading_set_cpu_affinity) { + TmThreadSetCPUAffinity(tv_detect_ncpu, (int)cpu); + /* If we have more than one core/cpu, the first Detect thread + * (at cpu 0) will have less priority (higher 'nice' value) + * In this case we will set the thread priority to +10 (default is 0) + */ + if (cpu == 0 && ncpus > 1) { + TmThreadSetThreadPriority(tv_detect_ncpu, PRIO_LOW); + } else if (ncpus > 1) { + TmThreadSetThreadPriority(tv_detect_ncpu, PRIO_MEDIUM); + } + } + + char *thread_group_name = SCStrdup("Detect"); + if (thread_group_name == NULL) { + printf("Error allocating memory\n"); + exit(EXIT_FAILURE); + } + tv_detect_ncpu->thread_group_name = thread_group_name; + + if (TmThreadSpawn(tv_detect_ncpu) != TM_ECODE_OK) { + printf("ERROR: TmThreadSpawn failed\n"); + exit(EXIT_FAILURE); + } + + if ((cpu + 1) == ncpus) + cpu = 0; + else + cpu++; + } + + ThreadVars *tv_outputs = TmThreadCreatePacketHandler("Outputs", + "alert-queue1", "ringbuffer", "packetpool", "packetpool", "varslot"); + SetupOutputs(tv_outputs); + + if (threading_set_cpu_affinity) { + TmThreadSetCPUAffinity(tv_outputs, 0); + if (ncpus > 1) + TmThreadSetThreadPriority(tv_outputs, PRIO_MEDIUM); + } + + if (TmThreadSpawn(tv_outputs) != TM_ECODE_OK) { + printf("ERROR: TmThreadSpawn failed\n"); + exit(EXIT_FAILURE); + } + + return 0; +} + int RunModeFilePcapAuto2(DetectEngineCtx *de_ctx, char *file) { SCEnter(); char tname[12]; diff --git a/src/runmodes.h b/src/runmodes.h index 4c20fdae8e..35827122fa 100644 --- a/src/runmodes.h +++ b/src/runmodes.h @@ -52,5 +52,6 @@ int RunModeErfDagAuto(DetectEngineCtx *, char *); void RunModeShutDown(void); +int RunModeFilePcapAutoFp(DetectEngineCtx *de_ctx, char *file); #endif /* __RUNMODES_H__ */ diff --git a/src/suricata.c b/src/suricata.c index 69507032b3..c0678338b4 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -1015,6 +1015,7 @@ int main(int argc, char **argv) //RunModeFilePcap(de_ctx, pcap_file); //RunModeFilePcap2(de_ctx, pcap_file); RunModeFilePcapAuto(de_ctx, pcap_file); + //RunModeFilePcapAutoFp(de_ctx, pcap_file); //RunModeFilePcapAuto2(de_ctx, pcap_file); } else if (run_mode == MODE_PFRING) {