示例#1
0
static TmEcode FlowWorkerThreadInit(ThreadVars *tv, const void *initdata, void **data)
{
    FlowWorkerThreadData *fw = SCCalloc(1, sizeof(*fw));
    if (fw == NULL)
        return TM_ECODE_FAILED;

    SC_ATOMIC_INIT(fw->detect_thread);
    SC_ATOMIC_SET(fw->detect_thread, NULL);

    fw->dtv = DecodeThreadVarsAlloc(tv);
    if (fw->dtv == NULL) {
        FlowWorkerThreadDeinit(tv, fw);
        return TM_ECODE_FAILED;
    }

    /* setup TCP */
    if (StreamTcpThreadInit(tv, NULL, &fw->stream_thread_ptr) != TM_ECODE_OK) {
        FlowWorkerThreadDeinit(tv, fw);
        return TM_ECODE_FAILED;
    }

    if (DetectEngineEnabled()) {
        /* setup DETECT */
        void *detect_thread = NULL;
        if (DetectEngineThreadCtxInit(tv, NULL, &detect_thread) != TM_ECODE_OK) {
            FlowWorkerThreadDeinit(tv, fw);
            return TM_ECODE_FAILED;
        }
        SC_ATOMIC_SET(fw->detect_thread, detect_thread);
    }

    /* Setup outputs for this thread. */
    if (OutputLoggerThreadInit(tv, initdata, &fw->output_thread) != TM_ECODE_OK) {
        FlowWorkerThreadDeinit(tv, fw);
        return TM_ECODE_FAILED;
    }

    DecodeRegisterPerfCounters(fw->dtv, tv);
    AppLayerRegisterThreadCounters(tv);

    /* setup pq for stream end pkts */
    memset(&fw->pq, 0, sizeof(PacketQueue));
    SCMutexInit(&fw->pq.mutex_q, NULL);

    *data = fw;
    return TM_ECODE_OK;
}
示例#2
0
int RunModeSetIPSWorker(ConfigIPSParserFunc ConfigParser,
        char *recv_mod_name,
        char *verdict_mod_name,
        char *decode_mod_name)
{
    char tname[TM_THREAD_NAME_MAX];
    ThreadVars *tv = NULL;
    TmModule *tm_module = NULL;
    char *cur_queue = NULL;

    int nqueue = LiveGetDeviceCount();

    for (int i = 0; i < nqueue; i++) {
        /* create the threads */
        cur_queue = LiveGetDeviceName(i);
        if (cur_queue == NULL) {
            SCLogError(SC_ERR_RUNMODE, "invalid queue number");
            exit(EXIT_FAILURE);
        }
        memset(tname, 0, sizeof(tname));
        snprintf(tname, sizeof(tname), "Worker-Q%s", cur_queue);

        tv = TmThreadCreatePacketHandler(tname,
                "packetpool", "packetpool",
                "packetpool", "packetpool",
                "pktacqloop");
        if (tv == NULL) {
            SCLogError(SC_ERR_THREAD_CREATE, "TmThreadsCreate failed");
            exit(EXIT_FAILURE);
        }

        tm_module = TmModuleGetByName(recv_mod_name);
        if (tm_module == NULL) {
            SCLogError(SC_ERR_INVALID_VALUE, "TmModuleGetByName failed for %s", recv_mod_name);
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv, tm_module, (void *) ConfigParser(i));

        tm_module = TmModuleGetByName(decode_mod_name);
        if (tm_module == NULL) {
            SCLogError(SC_ERR_INVALID_VALUE, "TmModuleGetByName %s failed", decode_mod_name);
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv, tm_module, NULL);

        tm_module = TmModuleGetByName("StreamTcp");
        if (tm_module == NULL) {
            SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName StreamTcp failed");
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv, tm_module, NULL);

        if (DetectEngineEnabled()) {
            tm_module = TmModuleGetByName("Detect");
            if (tm_module == NULL) {
                SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName Detect failed");
                exit(EXIT_FAILURE);
            }
            TmSlotSetFuncAppend(tv, tm_module, NULL);
        }

        tm_module = TmModuleGetByName(verdict_mod_name);
        if (tm_module == NULL) {
            SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName %s failed", verdict_mod_name);
            exit(EXIT_FAILURE);
        }

        TmSlotSetFuncAppend(tv, tm_module, NULL);

        tm_module = TmModuleGetByName("RespondReject");
        if (tm_module == NULL) {
            SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName for RespondReject failed");
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv, tm_module, NULL);

        SetupOutputs(tv);

        TmThreadSetCPU(tv, DETECT_CPU_SET);

        if (TmThreadSpawn(tv) != TM_ECODE_OK) {
            SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed");
            exit(EXIT_FAILURE);
        }
    }

    return 0;
}
示例#3
0
/**
 * \brief RunModeTileMpipeWorkers set up to process all modules in each thread.
 *
 * \param iface pointer to the name of the interface from which we will
 *              fetch the packets
 * \retval 0 if all goes well. (If any problem is detected the engine will
 *           exit())
 */
int RunModeTileMpipeWorkers(void)
{
    SCEnter();
    char tname[TM_THREAD_NAME_MAX];
    char *thread_name;
    TmModule *tm_module;
    int pipe;

    RunModeInitialize();

    /* Available cpus */
    uint16_t ncpus = UtilCpuGetNumProcessorsOnline();

    TimeModeSetLive();

    unsigned int pipe_max = 1;
    if (ncpus > 1)
        pipe_max = ncpus - 1;

    intmax_t threads;

    if (ConfGetInt("mpipe.threads", &threads) == 1) {
        tile_num_pipelines = threads;
    } else {
        tile_num_pipelines = pipe_max;
    }
    SCLogInfo("%d Tilera worker threads", tile_num_pipelines);

    ReceiveMpipeInit();

    char *mpipe_dev = NULL;
    int nlive = LiveGetDeviceCount();
    if (nlive > 0) {
        SCLogInfo("Using %d live device(s).", nlive);
        /*mpipe_dev = LiveGetDevice(0);*/
    } else {
        /*
         * Attempt to get interface from config file
         * overrides -i from command line.
         */
        if (ConfGet("mpipe.interface", &mpipe_dev) == 0) {
            if (ConfGet("mpipe.single_mpipe_dev", &mpipe_dev) == 0) {
                SCLogError(SC_ERR_RUNMODE, "Failed retrieving "
                           "mpipe.single_mpipe_dev from Conf");
                exit(EXIT_FAILURE);
            }
        }
    }

    /* Get affinity for worker */
    cpu_set_t cpus;
    //int result = tmc_cpus_get_my_affinity(&cpus);
    int result = tmc_cpus_get_dataplane_cpus(&cpus);
    if (result < 0) {
        SCLogError(SC_ERR_INVALID_ARGUMENT,
                   "tmc_cpus_get_my_affinity() returned=%d", result);
        SCReturnInt(TM_ECODE_FAILED);
    }

    for (pipe = 0; pipe < tile_num_pipelines; pipe++) {
        char *mpipe_devc;

        if (nlive > 0) {
            mpipe_devc = SCStrdup("multi");
        } else {
            mpipe_devc = SCStrdup(mpipe_dev);
        }
        if (unlikely(mpipe_devc == NULL)) {
            printf("ERROR: SCStrdup failed for ReceiveMpipe\n");
            exit(EXIT_FAILURE);
        }

        snprintf(tname, sizeof(tname), "%s#%02d", thread_name_workers, pipe+1);

        /* create the threads */
        ThreadVars *tv_worker =
             TmThreadCreatePacketHandler(tname,
                                         "packetpool", "packetpool",
                                         "packetpool", "packetpool", 
                                         "pktacqloop");
        if (tv_worker == NULL) {
            printf("ERROR: TmThreadsCreate failed\n");
            exit(EXIT_FAILURE);
        }
        tm_module = TmModuleGetByName("ReceiveMpipe");
        if (tm_module == NULL) {
            printf("ERROR: TmModuleGetByName failed for ReceiveMpipe\n");
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv_worker, tm_module, (void *)mpipe_devc);

	/* Bind to a single cpu. */
	int pipe_cpu = tmc_cpus_find_nth_cpu(&cpus, pipe);
	tv_worker->rank = pipe;

        TmThreadSetCPUAffinity(tv_worker, pipe_cpu);

        tm_module = TmModuleGetByName("DecodeMpipe");
        if (tm_module == NULL) {
            printf("ERROR: TmModuleGetByName DecodeMpipe failed\n");
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv_worker, tm_module, NULL);

        tm_module = TmModuleGetByName("StreamTcp");
        if (tm_module == NULL) {
            printf("ERROR: TmModuleGetByName StreamTcp failed\n");
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv_worker, tm_module, NULL);

        if (DetectEngineEnabled()) {
            tm_module = TmModuleGetByName("Detect");
            if (tm_module == NULL) {
                printf("ERROR: TmModuleGetByName Detect failed\n");
                exit(EXIT_FAILURE);
            }
            TmSlotSetFuncAppend(tv_worker, tm_module, NULL);
        }

        tm_module = TmModuleGetByName("RespondReject");
        if (tm_module == NULL) {
            printf("ERROR: TmModuleGetByName for RespondReject failed\n");
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv_worker, tm_module, NULL);

        SetupOutputs(tv_worker);

        if (TmThreadSpawn(tv_worker) != TM_ECODE_OK) {
            printf("ERROR: TmThreadSpawn failed\n");
            exit(EXIT_FAILURE);
        }
    }

    return 0;
}
示例#4
0
int RunModeSetIPSAutoFp(ConfigIPSParserFunc ConfigParser,
                        char *recv_mod_name,
                        char *verdict_mod_name,
                        char *decode_mod_name)
{
    SCEnter();
    char tname[TM_THREAD_NAME_MAX];
    char qname[TM_QUEUE_NAME_MAX];
    TmModule *tm_module ;
    char *cur_queue = NULL;
    char *queues = NULL;
    int thread;

    /* Available cpus */
    uint16_t ncpus = UtilCpuGetNumProcessorsOnline();
    int nqueue = LiveGetDeviceCount();

    int thread_max = TmThreadGetNbThreads(DETECT_CPU_SET);
    /* always create at least one thread */
    if (thread_max == 0)
        thread_max = ncpus * threading_detect_ratio;
    if (thread_max < 1)
        thread_max = 1;

    RunmodeSetFlowStreamAsync();

    queues = RunmodeAutoFpCreatePickupQueuesString(thread_max);
    if (queues == NULL) {
        SCLogError(SC_ERR_RUNMODE, "RunmodeAutoFpCreatePickupQueuesString failed");
        exit(EXIT_FAILURE);
    }

    for (int i = 0; i < nqueue; i++) {
    /* create the threads */
        cur_queue = LiveGetDeviceName(i);
        if (cur_queue == NULL) {
            SCLogError(SC_ERR_RUNMODE, "invalid queue number");
            exit(EXIT_FAILURE);
        }
        memset(tname, 0, sizeof(tname));
        snprintf(tname, sizeof(tname), "Recv-Q%s", cur_queue);

        ThreadVars *tv_receive =
            TmThreadCreatePacketHandler(tname,
                    "packetpool", "packetpool",
                    queues, "flow", "pktacqloop");
        if (tv_receive == NULL) {
            SCLogError(SC_ERR_RUNMODE, "TmThreadsCreate failed");
            exit(EXIT_FAILURE);
        }
        TmModule *tm_module = TmModuleGetByName(recv_mod_name);
        if (tm_module == NULL) {
            SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName failed for %s", recv_mod_name);
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv_receive, tm_module, (void *) ConfigParser(i));

        tm_module = TmModuleGetByName(decode_mod_name);
        if (tm_module == NULL) {
            SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName %s failed", decode_mod_name);
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv_receive, tm_module, NULL);

        TmThreadSetCPU(tv_receive, RECEIVE_CPU_SET);

        if (TmThreadSpawn(tv_receive) != TM_ECODE_OK) {
            SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed");
            exit(EXIT_FAILURE);
        }

    }
    for (thread = 0; thread < thread_max; thread++) {
        snprintf(tname, sizeof(tname), "Detect%d", thread+1);
        snprintf(qname, sizeof(qname), "pickup%d", thread+1);

        SCLogDebug("tname %s, qname %s", tname, qname);

        ThreadVars *tv_detect_ncpu =
            TmThreadCreatePacketHandler(tname,
                                        qname, "flow",
                                        "verdict-queue", "simple",
                                        "varslot");
        if (tv_detect_ncpu == NULL) {
            SCLogError(SC_ERR_RUNMODE, "TmThreadsCreate failed");
            exit(EXIT_FAILURE);
        }
        TmModule *tm_module = TmModuleGetByName("StreamTcp");
        if (tm_module == NULL) {
            SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName StreamTcp failed");
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL);

        if (DetectEngineEnabled()) {
            tm_module = TmModuleGetByName("Detect");
            if (tm_module == NULL) {
                SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName Detect failed");
                exit(EXIT_FAILURE);
            }
            TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL);
        }

        TmThreadSetCPU(tv_detect_ncpu, DETECT_CPU_SET);

        SetupOutputs(tv_detect_ncpu);

        TmThreadSetGroupName(tv_detect_ncpu, "Detect");

        if (TmThreadSpawn(tv_detect_ncpu) != TM_ECODE_OK) {
            SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed");
            exit(EXIT_FAILURE);
        }
    }

    /* create the threads */
    for (int i = 0; i < nqueue; i++) {
        memset(tname, 0, sizeof(tname));
        snprintf(tname, sizeof(tname), "Verdict%d", i);

        ThreadVars *tv_verdict =
            TmThreadCreatePacketHandler(tname,
                                        "verdict-queue", "simple",
                                        "packetpool", "packetpool",
                                        "varslot");
        if (tv_verdict == NULL) {
            SCLogError(SC_ERR_RUNMODE, "TmThreadsCreate failed");
            exit(EXIT_FAILURE);
        }
        tm_module = TmModuleGetByName(verdict_mod_name);
        if (tm_module == NULL) {
            SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName %s failed", verdict_mod_name);
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv_verdict, tm_module, (void *)ConfigParser(i));

        tm_module = TmModuleGetByName("RespondReject");
        if (tm_module == NULL) {
            SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName for RespondReject failed");
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv_verdict, tm_module, NULL);

        TmThreadSetCPU(tv_verdict, VERDICT_CPU_SET);

        if (TmThreadSpawn(tv_verdict) != TM_ECODE_OK) {
            SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed");
            exit(EXIT_FAILURE);
        }
    }

    SCFree(queues);
    return 0;
}
示例#5
0
static int RunModeSetLiveCaptureWorkersForDevice(ConfigIfaceThreadsCountFunc ModThreadsCount,
                              char *recv_mod_name,
                              char *decode_mod_name, char *thread_name,
                              const char *live_dev, void *aconf,
                              unsigned char single_mode)
{
    int thread;
    int threads_count;

    if (single_mode) {
        threads_count = 1;
    } else {
        threads_count = ModThreadsCount(aconf);
        SCLogInfo("Going to use %" PRId32 " thread(s)", threads_count);
    }

    /* create the threads */
    for (thread = 0; thread < threads_count; thread++) {
        char tname[TM_THREAD_NAME_MAX];
        ThreadVars *tv = NULL;
        TmModule *tm_module = NULL;

        if (single_mode) {
            snprintf(tname, sizeof(tname), "%s", thread_name);
        } else {
            snprintf(tname, sizeof(tname), "%s%s%d",
                     thread_name, live_dev, thread+1);
        }
        tv = TmThreadCreatePacketHandler(tname,
                "packetpool", "packetpool",
                "packetpool", "packetpool",
                "pktacqloop");
        if (tv == NULL) {
            SCLogError(SC_ERR_THREAD_CREATE, "TmThreadsCreate failed");
            exit(EXIT_FAILURE);
        }

        tm_module = TmModuleGetByName(recv_mod_name);
        if (tm_module == NULL) {
            SCLogError(SC_ERR_INVALID_VALUE, "TmModuleGetByName failed for %s", recv_mod_name);
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv, tm_module, aconf);

        tm_module = TmModuleGetByName(decode_mod_name);
        if (tm_module == NULL) {
            SCLogError(SC_ERR_INVALID_VALUE, "TmModuleGetByName %s failed", decode_mod_name);
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv, tm_module, NULL);

        tm_module = TmModuleGetByName("StreamTcp");
        if (tm_module == NULL) {
            SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName StreamTcp failed");
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv, tm_module, NULL);

        if (DetectEngineEnabled()) {
            tm_module = TmModuleGetByName("Detect");
            if (tm_module == NULL) {
                SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName Detect failed");
                exit(EXIT_FAILURE);
            }
            TmSlotSetFuncAppend(tv, tm_module, NULL);
        }

        tm_module = TmModuleGetByName("RespondReject");
        if (tm_module == NULL) {
            SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName RespondReject failed");
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv, tm_module, NULL);

        SetupOutputs(tv);

        TmThreadSetCPU(tv, DETECT_CPU_SET);

        if (TmThreadSpawn(tv) != TM_ECODE_OK) {
            SCLogError(SC_ERR_THREAD_SPAWN, "TmThreadSpawn failed");
            exit(EXIT_FAILURE);
        }
    }

    return 0;
}
示例#6
0
int RunModeSetLiveCaptureAutoFp(ConfigIfaceParserFunc ConfigParser,
                              ConfigIfaceThreadsCountFunc ModThreadsCount,
                              char *recv_mod_name,
                              char *decode_mod_name, char *thread_name,
                              const char *live_dev)
{
    char tname[TM_THREAD_NAME_MAX];
    char qname[TM_QUEUE_NAME_MAX];
    char *queues = NULL;
    int thread = 0;
    /* Available cpus */
    uint16_t ncpus = UtilCpuGetNumProcessorsOnline();
    int nlive = LiveGetDeviceCount();
    int thread_max = TmThreadGetNbThreads(DETECT_CPU_SET);
    /* always create at least one thread */
    if (thread_max == 0)
        thread_max = ncpus * threading_detect_ratio;
    if (thread_max < 1)
        thread_max = 1;

    RunmodeSetFlowStreamAsync();

    queues = RunmodeAutoFpCreatePickupQueuesString(thread_max);
    if (queues == NULL) {
        SCLogError(SC_ERR_RUNMODE, "RunmodeAutoFpCreatePickupQueuesString failed");
         exit(EXIT_FAILURE);
    }

    if ((nlive <= 1) && (live_dev != NULL)) {
        void *aconf;
        int threads_count;

        SCLogDebug("live_dev %s", live_dev);

        aconf = ConfigParser(live_dev);
        if (aconf == NULL) {
            SCLogError(SC_ERR_RUNMODE, "Failed to allocate config for %s (%d)",
                   live_dev, thread);
            exit(EXIT_FAILURE);
        }

        threads_count = ModThreadsCount(aconf);
        SCLogInfo("Going to use %" PRId32 " %s receive thread(s)",
                  threads_count, recv_mod_name);

        /* create the threads */
        for (thread = 0; thread < threads_count; thread++) {
            snprintf(tname, sizeof(tname), "%s%d", thread_name, thread+1);
            ThreadVars *tv_receive =
                TmThreadCreatePacketHandler(tname,
                        "packetpool", "packetpool",
                        queues, "flow", "pktacqloop");
            if (tv_receive == NULL) {
                SCLogError(SC_ERR_RUNMODE, "TmThreadsCreate failed");
                exit(EXIT_FAILURE);
            }
            TmModule *tm_module = TmModuleGetByName(recv_mod_name);
            if (tm_module == NULL) {
                SCLogError(SC_ERR_RUNMODE,
                    "TmModuleGetByName failed for %s",
                    recv_mod_name);
                exit(EXIT_FAILURE);
            }
            TmSlotSetFuncAppend(tv_receive, tm_module, aconf);

            tm_module = TmModuleGetByName(decode_mod_name);
            if (tm_module == NULL) {
                SCLogError(SC_ERR_RUNMODE,
                        "TmModuleGetByName %s failed", decode_mod_name);
                exit(EXIT_FAILURE);
            }
            TmSlotSetFuncAppend(tv_receive, tm_module, NULL);

            TmThreadSetCPU(tv_receive, RECEIVE_CPU_SET);

            if (TmThreadSpawn(tv_receive) != TM_ECODE_OK) {
                SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed");
                exit(EXIT_FAILURE);
            }
        }
    } else { /* Multiple input device */
        SCLogInfo("Using %d live device(s).", nlive);
        int lthread;

        for (lthread = 0; lthread < nlive; lthread++) {
            char *live_dev = LiveGetDeviceName(lthread);
            void *aconf;
            int threads_count;

            if (live_dev == NULL) {
                SCLogError(SC_ERR_RUNMODE, "Failed to lookup live dev %d", lthread);
                exit(EXIT_FAILURE);
            }
            SCLogDebug("live_dev %s", live_dev);

            aconf = ConfigParser(live_dev);
            if (aconf == NULL) {
                SCLogError(SC_ERR_RUNMODE, "Multidev: Failed to allocate config for %s (%d)",
                       live_dev, lthread);
                exit(EXIT_FAILURE);
            }

            threads_count = ModThreadsCount(aconf);
            for (thread = 0; thread < threads_count; thread++) {
                snprintf(tname, sizeof(tname), "%s%s%d", thread_name,
                         live_dev, thread+1);
                ThreadVars *tv_receive =
                    TmThreadCreatePacketHandler(tname,
                            "packetpool", "packetpool",
                            queues, "flow", "pktacqloop");
                if (tv_receive == NULL) {
                    SCLogError(SC_ERR_RUNMODE, "TmThreadsCreate failed");
                    exit(EXIT_FAILURE);
                }
                TmModule *tm_module = TmModuleGetByName(recv_mod_name);
                if (tm_module == NULL) {
                    SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName failed for %s", recv_mod_name);
                    exit(EXIT_FAILURE);
                }
                TmSlotSetFuncAppend(tv_receive, tm_module, aconf);

                tm_module = TmModuleGetByName(decode_mod_name);
                if (tm_module == NULL) {
                    SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName %s failed", decode_mod_name);
                    exit(EXIT_FAILURE);
                }
                TmSlotSetFuncAppend(tv_receive, tm_module, NULL);

                TmThreadSetCPU(tv_receive, RECEIVE_CPU_SET);

                if (TmThreadSpawn(tv_receive) != TM_ECODE_OK) {
                    SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed");
                    exit(EXIT_FAILURE);
                }
            }
        }
    }

    for (thread = 0; thread < thread_max; thread++) {
        snprintf(tname, sizeof(tname), "Detect%d", thread+1);
        snprintf(qname, sizeof(qname), "pickup%d", thread+1);

        SCLogDebug("tname %s, qname %s", tname, qname);

        ThreadVars *tv_detect_ncpu =
            TmThreadCreatePacketHandler(tname,
                                        qname, "flow",
                                        "packetpool", "packetpool",
                                        "varslot");
        if (tv_detect_ncpu == NULL) {
            SCLogError(SC_ERR_RUNMODE, "TmThreadsCreate failed");
            exit(EXIT_FAILURE);
        }
        TmModule *tm_module = TmModuleGetByName("StreamTcp");
        if (tm_module == NULL) {
            SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName StreamTcp failed");
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL);

        if (DetectEngineEnabled()) {
            tm_module = TmModuleGetByName("Detect");
            if (tm_module == NULL) {
                SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName Detect failed");
                exit(EXIT_FAILURE);
            }
            TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL);
        }

        TmThreadSetCPU(tv_detect_ncpu, DETECT_CPU_SET);

        TmThreadSetGroupName(tv_detect_ncpu, "Detect");

        tm_module = TmModuleGetByName("RespondReject");
        if (tm_module == NULL) {
            SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName RespondReject failed");
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL);

        /* add outputs as well */
        SetupOutputs(tv_detect_ncpu);

        if (TmThreadSpawn(tv_detect_ncpu) != TM_ECODE_OK) {
            SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed");
            exit(EXIT_FAILURE);
        }
    }

    SCFree(queues);
    return 0;
}
int RunModeErfFileSingle(void)
{
    char *file;

    SCEnter();

    if (ConfGet("erf-file.file", &file) == 0) {
        SCLogError(SC_ERR_RUNMODE, "Failed to get erf-file.file from config.");
        exit(EXIT_FAILURE);
    }

    RunModeInitialize();

    TimeModeSetOffline();

    /* Basically the same setup as PCAP files. */

    ThreadVars *tv = TmThreadCreatePacketHandler(thread_name_single,
        "packetpool", "packetpool",
        "packetpool", "packetpool",
        "pktacqloop");
    if (tv == NULL) {
        printf("ERROR: TmThreadsCreate failed\n");
        exit(EXIT_FAILURE);
    }

    TmModule *tm_module = TmModuleGetByName("ReceiveErfFile");
    if (tm_module == NULL) {
        printf("ERROR: TmModuleGetByName failed for ReceiveErfFile\n");
        exit(EXIT_FAILURE);
    }
    TmSlotSetFuncAppend(tv, tm_module, file);

    tm_module = TmModuleGetByName("DecodeErfFile");
    if (tm_module == NULL) {
        printf("ERROR: TmModuleGetByName DecodeErfFile failed\n");
        exit(EXIT_FAILURE);
    }
    TmSlotSetFuncAppend(tv, tm_module, NULL);

    tm_module = TmModuleGetByName("StreamTcp");
    if (tm_module == NULL) {
        printf("ERROR: TmModuleGetByName StreamTcp failed\n");
        exit(EXIT_FAILURE);
    }
    TmSlotSetFuncAppend(tv, tm_module, NULL);

    if (DetectEngineEnabled()) {
        tm_module = TmModuleGetByName("Detect");
        if (tm_module == NULL) {
            printf("ERROR: TmModuleGetByName Detect failed\n");
            exit(EXIT_FAILURE);
        }
        TmSlotSetFuncAppend(tv, tm_module, NULL);
    }

    SetupOutputs(tv);

    if (TmThreadSpawn(tv) != TM_ECODE_OK) {
        printf("ERROR: TmThreadSpawn failed\n");
        exit(EXIT_FAILURE);
    }

    SCLogInfo("RunModeErfFileSingle initialised");

    SCReturnInt(0);
}
int RunModeErfFileAutoFp(void)
{
    SCEnter();
    char tname[TM_THREAD_NAME_MAX];
    char qname[TM_QUEUE_NAME_MAX];
    uint16_t cpu = 0;
    char *queues = NULL;
    int thread;

    RunModeInitialize();
    RunmodeSetFlowStreamAsync();

    char *file = NULL;
    if (ConfGet("erf-file.file", &file) == 0) {
        SCLogError(SC_ERR_RUNMODE,
            "Failed retrieving erf-file.file from config");
        exit(EXIT_FAILURE);
    }

    TimeModeSetOffline();

    /* 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 = TmThreadGetNbThreads(DETECT_CPU_SET);
    if (thread_max == 0)
        thread_max = ncpus * threading_detect_ratio;
    if (thread_max < 1)
        thread_max = 1;

    queues = RunmodeAutoFpCreatePickupQueuesString(thread_max);
    if (queues == NULL) {
        SCLogError(SC_ERR_RUNMODE, "RunmodeAutoFpCreatePickupQueuesString failed");
        exit(EXIT_FAILURE);
    }

    /* create the threads */
    ThreadVars *tv =
        TmThreadCreatePacketHandler(thread_name_autofp,
                                    "packetpool", "packetpool",
                                    queues, "flow",
                                    "pktacqloop");
    SCFree(queues);

    if (tv == NULL) {
        printf("ERROR: TmThreadsCreate failed\n");
        exit(EXIT_FAILURE);
    }
    TmModule *tm_module = TmModuleGetByName("ReceiveErfFile");
    if (tm_module == NULL) {
        printf("ERROR: TmModuleGetByName failed for ReceiveErfFile\n");
        exit(EXIT_FAILURE);
    }
    TmSlotSetFuncAppend(tv, tm_module, file);

    tm_module = TmModuleGetByName("DecodeErfFile");
    if (tm_module == NULL) {
        printf("ERROR: TmModuleGetByName DecodeErfFile failed\n");
        exit(EXIT_FAILURE);
    }
    TmSlotSetFuncAppend(tv, tm_module, NULL);

    if (threading_set_cpu_affinity) {
        TmThreadSetCPUAffinity(tv, 0);
        if (ncpus > 1)
            TmThreadSetThreadPriority(tv, PRIO_MEDIUM);
    }

    if (TmThreadSpawn(tv) != TM_ECODE_OK) {
        printf("ERROR: TmThreadSpawn failed\n");
        exit(EXIT_FAILURE);
    }

    for (thread = 0; thread < thread_max; thread++) {
        snprintf(tname, sizeof(tname), "%s#%02d", thread_name_workers, thread+1);
        snprintf(qname, sizeof(qname), "pickup%d", thread+1);

        SCLogDebug("tname %s, qname %s", tname, qname);

        SCLogDebug("Assigning %s affinity to cpu %u", tname, cpu);

        ThreadVars *tv_detect_ncpu =
            TmThreadCreatePacketHandler(tname,
                                        qname, "flow",
                                        "packetpool", "packetpool",
                                        "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);
        }
        TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL);

        if (DetectEngineEnabled()) {
            tm_module = TmModuleGetByName("Detect");
            if (tm_module == NULL) {
                printf("ERROR: TmModuleGetByName Detect failed\n");
                exit(EXIT_FAILURE);
            }
            TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL);
        }

        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);
            }
        }

        TmThreadSetGroupName(tv_detect_ncpu, "Detect");

        /* add outputs as well */
        SetupOutputs(tv_detect_ncpu);

        if (TmThreadSpawn(tv_detect_ncpu) != TM_ECODE_OK) {
            printf("ERROR: TmThreadSpawn failed\n");
            exit(EXIT_FAILURE);
        }

        if ((cpu + 1) == ncpus)
            cpu = 0;
        else
            cpu++;
    }

    SCLogInfo("RunModeErfFileAutoFp initialised");

    SCReturnInt(0);
}