static int NFQCallBack(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *data) { NFQThreadVars *ntv = (NFQThreadVars *)data; ThreadVars *tv = ntv->tv; int ret; /* grab a packet */ Packet *p = PacketGetFromQueueOrAlloc(); if (p == NULL) { return -1; } PKT_SET_SRC(p, PKT_SRC_WIRE); p->nfq_v.nfq_index = ntv->nfq_index; /* if bypass mask is set then we may want to bypass so set pointer */ if (nfq_config.bypass_mask) { p->BypassPacketsFlow = NFQBypassCallback; } ret = NFQSetupPkt(p, qh, (void *)nfa); if (ret == -1) { #ifdef COUNTERS NFQQueueVars *q = NFQGetQueue(ntv->nfq_index); q->errs++; q->pkts++; q->bytes += GET_PKT_LEN(p); #endif /* COUNTERS */ (void) SC_ATOMIC_ADD(ntv->livedev->pkts, 1); /* NFQSetupPkt is issuing a verdict so we only recycle Packet and leave */ TmqhOutputPacketpool(tv, p); return 0; } p->ReleasePacket = NFQReleasePacket; #ifdef COUNTERS NFQQueueVars *q = NFQGetQueue(ntv->nfq_index); q->pkts++; q->bytes += GET_PKT_LEN(p); #endif /* COUNTERS */ (void) SC_ATOMIC_ADD(ntv->livedev->pkts, 1); if (ntv->slot) { if (TmThreadsSlotProcessPkt(tv, ntv->slot, p) != TM_ECODE_OK) { TmqhOutputPacketpool(ntv->tv, p); return -1; } } else { /* pass on... */ tv->tmqh_out(tv, p); } return 0; }
static int NFQCallBack(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *data) { NFQThreadVars *ntv = (NFQThreadVars *)data; ThreadVars *tv = ntv->tv; int ret; /* grab a packet */ Packet *p = PacketGetFromQueueOrAlloc(); if (p == NULL) { return -1; } PKT_SET_SRC(p, PKT_SRC_WIRE); p->nfq_v.nfq_index = ntv->nfq_index; ret = NFQSetupPkt(p, qh, (void *)nfa); if (ret == -1) { #ifdef COUNTERS NFQQueueVars *nfq_q = NFQGetQueue(ntv->nfq_index); nfq_q->errs++; nfq_q->pkts++; nfq_q->bytes += GET_PKT_LEN(p); #endif /* COUNTERS */ /* recycle Packet and leave */ TmqhOutputPacketpool(tv, p); return 0; } #ifdef COUNTERS NFQQueueVars *nfq_q = NFQGetQueue(ntv->nfq_index); nfq_q->pkts++; nfq_q->bytes += GET_PKT_LEN(p); #endif /* COUNTERS */ if (ntv->slot) { if (TmThreadsSlotProcessPkt(tv, ntv->slot, p) != TM_ECODE_OK) { TmqhOutputPacketpool(ntv->tv, p); return -1; } } else { /* pass on... */ tv->tmqh_out(tv, p); } return 0; }
/** * \brief Single thread version of the Pcap file processing. */ int RunModeFilePcapSingle(void) { const char *file = NULL; char tname[TM_THREAD_NAME_MAX]; if (ConfGet("pcap-file.file", &file) == 0) { SCLogError(SC_ERR_RUNMODE, "Failed retrieving pcap-file from Conf"); exit(EXIT_FAILURE); } RunModeInitialize(); TimeModeSetOffline(); PcapFileGlobalInit(); snprintf(tname, sizeof(tname), "%s#01", thread_name_single); /* create the threads */ ThreadVars *tv = TmThreadCreatePacketHandler(tname, "packetpool", "packetpool", "packetpool", "packetpool", "pktacqloop"); if (tv == NULL) { SCLogError(SC_ERR_RUNMODE, "threading setup failed"); exit(EXIT_FAILURE); } TmModule *tm_module = TmModuleGetByName("ReceivePcapFile"); if (tm_module == NULL) { SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName failed for ReceivePcap"); exit(EXIT_FAILURE); } TmSlotSetFuncAppend(tv, tm_module, file); tm_module = TmModuleGetByName("DecodePcapFile"); if (tm_module == NULL) { SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName DecodePcap failed"); exit(EXIT_FAILURE); } TmSlotSetFuncAppend(tv, tm_module, NULL); tm_module = TmModuleGetByName("FlowWorker"); if (tm_module == NULL) { SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName for FlowWorker failed"); exit(EXIT_FAILURE); } TmSlotSetFuncAppend(tv, tm_module, NULL); TmThreadSetCPU(tv, WORKER_CPU_SET); #ifndef AFLFUZZ_PCAP_RUNMODE if (TmThreadSpawn(tv) != TM_ECODE_OK) { SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed"); exit(EXIT_FAILURE); } #else /* in afl mode we don't spawn a new thread, but run the pipeline * in the main thread */ tv->tm_func(tv); int afl_runmode_exit_immediately = 0; (void)ConfGetBool("afl.exit_after_pcap", &afl_runmode_exit_immediately); if (afl_runmode_exit_immediately) { SCLogNotice("exit because of afl-runmode-exit-after-pcap commandline option"); exit(EXIT_SUCCESS); } #endif return 0; }
/** * \todo only the first "slot" currently makes the "post_pq" available * to the thread module. */ void *TmThreadsSlotVar(void *td) { ThreadVars *tv = (ThreadVars *)td; TmVarSlot *s = (TmVarSlot *)tv->tm_slots; Packet *p = NULL; char run = 1; TmEcode r = TM_ECODE_OK; TmSlot *slot = NULL; /* Set the thread name */ SCSetThreadName(tv->name); /* Drop the capabilities for this thread */ SCDropCaps(tv); if (tv->thread_setup_flags != 0) TmThreadSetupOptions(tv); /* check if we are setup properly */ if (s == NULL || s->s == NULL || tv->tmqh_in == NULL || tv->tmqh_out == NULL) { EngineKill(); TmThreadsSetFlag(tv, THV_CLOSED); pthread_exit((void *) -1); } for (slot = s->s; slot != NULL; slot = slot->slot_next) { if (slot->SlotThreadInit != NULL) { r = slot->SlotThreadInit(tv, slot->slot_initdata, &slot->slot_data); if (r != TM_ECODE_OK) { EngineKill(); TmThreadsSetFlag(tv, THV_CLOSED); pthread_exit((void *) -1); } } memset(&slot->slot_pre_pq, 0, sizeof(PacketQueue)); memset(&slot->slot_post_pq, 0, sizeof(PacketQueue)); } TmThreadsSetFlag(tv, THV_INIT_DONE); while(run) { TmThreadTestThreadUnPaused(tv); /* input a packet */ p = tv->tmqh_in(tv); if (p != NULL) { /* run the thread module(s) */ r = TmThreadsSlotVarRun(tv, p, s->s); if (r == TM_ECODE_FAILED) { TmqhOutputPacketpool(tv, p); TmThreadsSetFlag(tv, THV_FAILED); break; } /* output the packet */ tv->tmqh_out(tv, p); /* now handle the post_pq packets */ while (s->s->slot_post_pq.top != NULL) { Packet *extra_p = PacketDequeue(&s->s->slot_post_pq); if (extra_p == NULL) continue; if (s->s->slot_next != NULL) { r = TmThreadsSlotVarRun(tv, extra_p, s->s->slot_next); if (r == TM_ECODE_FAILED) { TmqhOutputPacketpool(tv, extra_p); TmThreadsSetFlag(tv, THV_FAILED); break; } } /* output the packet */ tv->tmqh_out(tv, extra_p); } } if (TmThreadsCheckFlag(tv, THV_KILL)) { run = 0; } } SCPerfUpdateCounterArray(tv->sc_perf_pca, &tv->sc_perf_pctx, 0); for (slot = s->s; slot != NULL; slot = slot->slot_next) { if (slot->SlotThreadExitPrintStats != NULL) { slot->SlotThreadExitPrintStats(tv, slot->slot_data); } if (slot->SlotThreadDeinit != NULL) { r = slot->SlotThreadDeinit(tv, slot->slot_data); if (r != TM_ECODE_OK) { TmThreadsSetFlag(tv, THV_CLOSED); pthread_exit((void *) -1); } } } SCLogDebug("%s ending", tv->name); TmThreadsSetFlag(tv, THV_CLOSED); pthread_exit((void *) 0); }
void *TmThreadsSlot1(void *td) { ThreadVars *tv = (ThreadVars *)td; Tm1Slot *s = (Tm1Slot *)tv->tm_slots; Packet *p = NULL; char run = 1; TmEcode r = TM_ECODE_OK; /* Set the thread name */ SCSetThreadName(tv->name); /* Drop the capabilities for this thread */ SCDropCaps(tv); if (tv->thread_setup_flags != 0) TmThreadSetupOptions(tv); SCLogDebug("%s starting", tv->name); if (s->s.SlotThreadInit != NULL) { r = s->s.SlotThreadInit(tv, s->s.slot_initdata, &s->s.slot_data); if (r != TM_ECODE_OK) { EngineKill(); TmThreadsSetFlag(tv, THV_CLOSED); pthread_exit((void *) -1); } } memset(&s->s.slot_pre_pq, 0, sizeof(PacketQueue)); memset(&s->s.slot_post_pq, 0, sizeof(PacketQueue)); TmThreadsSetFlag(tv, THV_INIT_DONE); while(run) { TmThreadTestThreadUnPaused(tv); /* input a packet */ p = tv->tmqh_in(tv); if (p == NULL) { //printf("%s: TmThreadsSlot1: p == NULL\n", tv->name); } else { r = s->s.SlotFunc(tv, p, s->s.slot_data, &s->s.slot_pre_pq, &s->s.slot_post_pq); /* handle error */ if (r == TM_ECODE_FAILED) { TmqhReleasePacketsToPacketPool(&s->s.slot_pre_pq); TmqhReleasePacketsToPacketPool(&s->s.slot_post_pq); TmqhOutputPacketpool(tv, p); TmThreadsSetFlag(tv, THV_FAILED); break; } while (s->s.slot_pre_pq.top != NULL) { /* handle new packets from this func */ Packet *extra_p = PacketDequeue(&s->s.slot_pre_pq); if (extra_p != NULL) { tv->tmqh_out(tv, extra_p); } } /* output the packet */ tv->tmqh_out(tv, p); while (s->s.slot_post_pq.top != NULL) { /* handle new packets from this func */ Packet *extra_p = PacketDequeue(&s->s.slot_post_pq); if (extra_p != NULL) { tv->tmqh_out(tv, extra_p); } } } if (TmThreadsCheckFlag(tv, THV_KILL)) { //printf("%s: TmThreadsSlot1: KILL is set\n", tv->name); SCPerfUpdateCounterArray(tv->sc_perf_pca, &tv->sc_perf_pctx, 0); run = 0; } } if (s->s.SlotThreadExitPrintStats != NULL) { s->s.SlotThreadExitPrintStats(tv, s->s.slot_data); } if (s->s.SlotThreadDeinit != NULL) { r = s->s.SlotThreadDeinit(tv, s->s.slot_data); if (r != TM_ECODE_OK) { TmThreadsSetFlag(tv, THV_CLOSED); pthread_exit((void *) -1); } } SCLogDebug("%s ending", tv->name); TmThreadsSetFlag(tv, THV_CLOSED); pthread_exit((void *) 0); }
void *TmThreadsSlot1NoOut(void *td) { ThreadVars *tv = (ThreadVars *)td; Tm1Slot *s = (Tm1Slot *)tv->tm_slots; Packet *p = NULL; char run = 1; TmEcode r = TM_ECODE_OK; /* Set the thread name */ SCSetThreadName(tv->name); /* Drop the capabilities for this thread */ SCDropCaps(tv); if (tv->thread_setup_flags != 0) TmThreadSetupOptions(tv); if (s->s.SlotThreadInit != NULL) { r = s->s.SlotThreadInit(tv, s->s.slot_initdata, &s->s.slot_data); if (r != TM_ECODE_OK) { EngineKill(); TmThreadsSetFlag(tv, THV_CLOSED); pthread_exit((void *) -1); } } memset(&s->s.slot_pre_pq, 0, sizeof(PacketQueue)); memset(&s->s.slot_post_pq, 0, sizeof(PacketQueue)); TmThreadsSetFlag(tv, THV_INIT_DONE); while(run) { TmThreadTestThreadUnPaused(tv); p = tv->tmqh_in(tv); r = s->s.SlotFunc(tv, p, s->s.slot_data, /* no outqh no pq */NULL, /* no outqh no pq */NULL); /* handle error */ if (r == TM_ECODE_FAILED) { TmqhOutputPacketpool(tv, p); TmThreadsSetFlag(tv, THV_FAILED); break; } if (TmThreadsCheckFlag(tv, THV_KILL)) { SCPerfUpdateCounterArray(tv->sc_perf_pca, &tv->sc_perf_pctx, 0); run = 0; } } if (s->s.SlotThreadExitPrintStats != NULL) { s->s.SlotThreadExitPrintStats(tv, s->s.slot_data); } if (s->s.SlotThreadDeinit != NULL) { r = s->s.SlotThreadDeinit(tv, s->s.slot_data); if (r != TM_ECODE_OK) { TmThreadsSetFlag(tv, THV_CLOSED); pthread_exit((void *) -1); } } TmThreadsSetFlag(tv, THV_CLOSED); pthread_exit((void *) 0); }
void TmThreadKillThreads(void) { ThreadVars *tv = NULL; int i = 0; for (i = 0; i < TVT_MAX; i++) { tv = tv_root[i]; while (tv) { TmThreadsSetFlag(tv, THV_KILL); SCLogDebug("told thread %s to stop", tv->name); if (tv->inq != NULL) { int i; //printf("TmThreadKillThreads: (t->inq->reader_cnt + t->inq->writer_cnt) %" PRIu32 "\n", (t->inq->reader_cnt + t->inq->writer_cnt)); /* make sure our packet pending counter doesn't block */ //SCCondSignal(&cond_pending); /* signal the queue for the number of users */ if (tv->InShutdownHandler != NULL) { tv->InShutdownHandler(tv); } for (i = 0; i < (tv->inq->reader_cnt + tv->inq->writer_cnt); i++) { if (tv->inq->q_type == 0) SCCondSignal(&trans_q[tv->inq->id].cond_q); else SCCondSignal(&data_queues[tv->inq->id].cond_q); } /* to be sure, signal more */ int cnt = 0; while (1) { if (TmThreadsCheckFlag(tv, THV_CLOSED)) { SCLogDebug("signalled the thread %" PRId32 " times", cnt); break; } cnt++; if (tv->InShutdownHandler != NULL) { tv->InShutdownHandler(tv); } for (i = 0; i < (tv->inq->reader_cnt + tv->inq->writer_cnt); i++) { if (tv->inq->q_type == 0) SCCondSignal(&trans_q[tv->inq->id].cond_q); else SCCondSignal(&data_queues[tv->inq->id].cond_q); } usleep(100); } SCLogDebug("signalled tv->inq->id %" PRIu32 "", tv->inq->id); } if (tv->cond != NULL ) { int cnt = 0; while (1) { if (TmThreadsCheckFlag(tv, THV_CLOSED)) { SCLogDebug("signalled the thread %" PRId32 " times", cnt); break; } cnt++; pthread_cond_broadcast(tv->cond); usleep(100); } } /* join it */ pthread_join(tv->t, NULL); SCLogDebug("thread %s stopped", tv->name); tv = tv->next; } } }