To reload ruleset during engine runtime, send the USR2 signal to the engine, and the ruleset would be reloaded from the same yaml file supplied at engine startup
*/
static void *SCPerfMgmtThread(void *arg)
{
+ /* block usr2. usr2 to be handled by the main thread only */
+ sigset_t x;
+ sigemptyset(&x);
+ sigaddset(&x, SIGUSR2);
+ sigprocmask(SIG_BLOCK, &x, NULL);
+
ThreadVars *tv_local = (ThreadVars *)arg;
uint8_t run = 1;
struct timespec cond_time;
*/
static void *SCPerfWakeupThread(void *arg)
{
+ /* block usr2. usr2 to be handled by the main thread only */
+ sigset_t x;
+ sigemptyset(&x);
+ sigaddset(&x, SIGUSR2);
+ sigprocmask(SIG_BLOCK, &x, NULL);
+
ThreadVars *tv_local = (ThreadVars *)arg;
uint8_t run = 1;
ThreadVars *tv = NULL;
* \retval 1 has state
* \retval 0 has no state
*/
-int DeStateFlowHasState(Flow *f, uint8_t flags, uint16_t alversion) {
+int DeStateFlowHasState(DetectEngineCtx *de_ctx, Flow *f, uint8_t flags, uint16_t alversion) {
SCEnter();
int r = 0;
* the last SigMatch that didn't match */
if (f->de_state == NULL) {
f->de_state = DetectEngineStateAlloc();
+ f->de_state->de_ctx_id = de_ctx->id;
+ } else {
+ if (f->de_state->de_ctx_id != de_ctx->id) {
+ DetectEngineStateReset(f->de_state);
+ f->de_state = DetectEngineStateAlloc();
+ f->de_state->de_ctx_id = de_ctx->id;
+ }
}
+
if (f->de_state != NULL) {
/* \todo shift to an array to transfer these match values*/
DeStateSignatureAppend(f->de_state, s, sm, match_flags);
if (f->de_state == NULL || f->de_state->cnt == 0)
goto end;
+ if (f->de_state->de_ctx_id != de_ctx->id) {
+ DetectEngineStateReset(f->de_state);
+ f->de_state = NULL;
+ SCMutexUnlock(&f->de_state_m);
+ SCReturnInt(0);
+ }
+
DeStateResetFileInspection(f, alproto, alstate);
/* loop through the stores */
* cannot match in to client direction. */
uint16_t toserver_filestore_cnt;/**< number of sigs with filestore that
* cannot match in to server direction. */
+
+ /* the de_ctx id that the state belongs to */
+ uint32_t de_ctx_id;
+
uint16_t flags;
} DetectEngineState;
DetectEngineState *DetectEngineStateAlloc(void);
void DetectEngineStateFree(DetectEngineState *);
-int DeStateFlowHasState(Flow *, uint8_t, uint16_t);
+int DeStateFlowHasState(DetectEngineCtx *, Flow *, uint8_t, uint16_t);
int DeStateDetectStartDetection(ThreadVars *, DetectEngineCtx *,
DetectEngineThreadCtx *, Signature *, Flow *, uint8_t, void *,
*/
#include "suricata-common.h"
+#include "suricata.h"
#include "debug.h"
#include "detect.h"
#include "flow.h"
//#include "util-mpm.h"
#include "util-classification-config.h"
#include "util-reference-config.h"
+#include "util-threshold-config.h"
#include "util-error.h"
#include "util-hash.h"
#include "util-byte.h"
#include "util-debug.h"
#include "util-unittest.h"
+#include "util-action.h"
+#include "util-magic.h"
#include "util-var-name.h"
#define DETECT_ENGINE_DEFAULT_INSPECTION_RECURSION_LIMIT 3000
+static uint32_t detect_engine_ctx_id = 0;
+
+static TmEcode DetectEngineThreadCtxInitForLiveRuleSwap(ThreadVars *, void *, void **);
+
static uint8_t DetectEngineCtxLoadConf(DetectEngineCtx *);
+static void *DetectEngineLiveRuleSwap(void *arg)
+{
+ SCEnter();
+
+ SCLogInfo("===== Starting live rule swap triggered by user signal USR2 =====");
+
+ ThreadVars *tv_local = (ThreadVars *)arg;
+
+ /* block usr2. usr2 to be handled by the main thread only */
+ sigset_t x;
+ sigemptyset(&x);
+ sigaddset(&x, SIGUSR2);
+ sigprocmask(SIG_BLOCK, &x, NULL);
+
+ ConfDeInit();
+ ConfInit();
+
+ /* re-load the yaml file */
+ if (conf_filename != NULL) {
+ if (ConfYamlLoadFile(conf_filename) != 0) {
+ /* Error already displayed. */
+ exit(EXIT_FAILURE);
+ }
+
+ ConfNode *file;
+ ConfNode *includes = ConfGetNode("include");
+ if (includes != NULL) {
+ TAILQ_FOREACH(file, &includes->head, next) {
+ char *ifile = ConfLoadCompleteIncludePath(file->val);
+ SCLogInfo("Live Rule Swap: Including: %s", ifile);
+
+ if (ConfYamlLoadFile(ifile) != 0) {
+ /* Error already displayed. */
+ exit(EXIT_FAILURE);
+ }
+ }
+ }
+ } /* if (conf_filename != NULL) */
+
+#if 0
+ ConfDump();
+#endif
+
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+
+ SCClassConfLoadClassficationConfigFile(de_ctx);
+ SCRConfLoadReferenceConfigFile(de_ctx);
+
+ if (ActionInitConfig() < 0) {
+ exit(EXIT_FAILURE);
+ }
+
+ //if (MagicInit() != 0)
+ // exit(EXIT_FAILURE);
+
+ if (SigLoadSignatures(de_ctx, NULL, FALSE) < 0) {
+ SCLogError(SC_ERR_NO_RULES_LOADED, "Loading signatures failed.");
+ if (de_ctx->failure_fatal)
+ exit(EXIT_FAILURE);
+ }
+
+ SCThresholdConfInitContext(de_ctx, NULL);
+
+
+ /* start the process of swapping detect threads ctxs */
+
+ SCMutexLock(&tv_root_lock);
+
+ int no_of_detect_tvs = 0;
+ ThreadVars *tv = tv_root[TVT_PPT];
+ while (tv) {
+ /* obtain the slots for this TV */
+ TmSlot *slots = tv->tm_slots;
+ while (slots != NULL) {
+ TmModule *tm = TmModuleGetById(slots->tm_id);
+
+ if (suricata_ctl_flags != 0) {
+ TmThreadsSetFlag(tv_local, THV_CLOSED);
+
+ SCLogInfo("===== Live rule swap premature exit, since "
+ "suricta_ctl_flags != 0 =====");
+
+ SignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2EngineShutdown);
+
+ pthread_exit(NULL);
+ }
+
+ if (!(tm->flags & TM_FLAG_DETECT_TM)) {
+ slots = slots->slot_next;
+ continue;
+ }
+
+ no_of_detect_tvs++;
+
+ slots = slots->slot_next;
+ }
+
+ tv = tv->next;
+ }
+
+ DetectEngineThreadCtx *old_det_ctx[no_of_detect_tvs];
+ DetectEngineThreadCtx *new_det_ctx[no_of_detect_tvs];
+
+ /* all receive threads are part of packet processing threads */
+ tv = tv_root[TVT_PPT];
+ int i = 0;
+ while (tv) {
+ /* obtain the slots for this TV */
+ TmSlot *slots = tv->tm_slots;
+ while (slots != NULL) {
+ TmModule *tm = TmModuleGetById(slots->tm_id);
+
+ if (!(tm->flags & TM_FLAG_DETECT_TM)) {
+ slots = slots->slot_next;
+ continue;
+ }
+
+ old_det_ctx[i] = SC_ATOMIC_GET(slots->slot_data);
+
+ DetectEngineThreadCtx *det_ctx = NULL;
+ DetectEngineThreadCtxInitForLiveRuleSwap(tv, (void *)de_ctx,
+ (void **)&det_ctx);
+ SCLogDebug("live rule swap done with new det_ctx - %p and de_ctx "
+ "- %p\n", det_ctx, de_ctx);
+
+ new_det_ctx[i] = det_ctx;
+ i++;
+
+ if (suricata_ctl_flags != 0) {
+ TmThreadsSetFlag(tv_local, THV_CLOSED);
+
+ SCLogInfo("===== Live rule swap premature exit between "
+ "swapping det_ctxs, since "
+ "suricta_ctl_flags != 0 =====");
+
+ SignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2EngineShutdown);
+
+ pthread_exit(NULL);
+ }
+
+
+ SC_ATOMIC_CAS(&slots->slot_data, SC_ATOMIC_GET(slots->slot_data),
+ det_ctx);
+ SCLogDebug("swapping new det_ctx with older one");
+
+ slots = slots->slot_next;
+ }
+
+ tv = tv->next;
+ }
+
+ SCMutexUnlock(&tv_root_lock);
+
+ SCLogInfo("Live rule swap has swapped %d old det_ctx's with new ones, "
+ "along with the new de_ctx", no_of_detect_tvs);
+
+ for (i = 0; i < no_of_detect_tvs; i++) {
+ while (new_det_ctx[i]->so_far_used_by_detect != 1) {
+ SCLogDebug("new_det_ctx - %p used by detect", new_det_ctx[i]);
+ if (suricata_ctl_flags != 0) {
+ TmThreadsSetFlag(tv_local, THV_CLOSED);
+
+ SCLogInfo("===== Live rule swap done, but premature exit at "
+ "de-init phase, since suricta_ctl_flags != 0 =====");
+
+ SignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2EngineShutdown);
+
+ pthread_exit(NULL);
+ }
+
+ usleep(1000);
+ }
+ }
+
+ DetectEngineCtx *old_de_ctx = old_det_ctx[0]->de_ctx;
+ for (i = 0; i < no_of_detect_tvs; i++) {
+ SCLogDebug("Freeing old_det_ctx - %p used by detect",
+ old_det_ctx[i]);
+ if (suricata_ctl_flags != 0) {
+ TmThreadsSetFlag(tv_local, THV_CLOSED);
+
+ SCLogInfo("===== Live rule swap done, but premature exit at "
+ "de-init phase, since suricta_ctl_flags != 0 =====");
+
+ SignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2EngineShutdown);
+
+ pthread_exit(NULL);
+ }
+
+
+ DetectEngineThreadCtxDeinit(NULL, old_det_ctx[i]);
+ }
+ DetectEngineCtxFree(old_de_ctx);
+
+ SignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
+
+ TmThreadsSetFlag(tv_local, THV_CLOSED);
+
+ SCLogInfo("===== Live rule swap DONE =====");
+
+ pthread_exit(NULL);
+}
+
+void DetectEngineSpawnLiveRuleSwapMgmtThread(void)
+{
+ SCEnter();
+
+ SCLogDebug("Spawning mgmt thread for live rule swap");
+
+ ThreadVars *tv = TmThreadCreateMgmtThread("DetectEngineLiveRuleSwap",
+ DetectEngineLiveRuleSwap, 0);
+ if (tv == NULL) {
+ SCLogError(SC_ERR_THREAD_CREATE, "Live rule swap thread spawn failed");
+ exit(EXIT_FAILURE);
+ }
+ if (TmThreadSpawn(tv) != 0) {
+ SCLogError(SC_ERR_THREAD_SPAWN, "TmThreadSpawn failed for "
+ "DetectEngineLiveRuleSwap");
+ exit(EXIT_FAILURE);
+ }
+
+ SCReturn;
+}
+
DetectEngineCtx *DetectEngineCtxInit(void) {
DetectEngineCtx *de_ctx;
goto error;
}
+ de_ctx->id = detect_engine_ctx_id++;
+
return de_ctx;
error:
return NULL;
SCClassConfDeInitContext(de_ctx);
SCRConfDeInitContext(de_ctx);
+ SigGroupCleanup(de_ctx);
+
SCFree(de_ctx);
//DetectAddressGroupPrintMemory();
//DetectSigGroupPrintMemory();
/* this detection engine context belongs to this thread instance */
det_ctx->tv = tv;
- det_ctx->bj_values = SCMalloc(sizeof(*det_ctx->bj_values) * de_ctx->byte_extract_max_local_id);
+ det_ctx->bj_values = SCMalloc(sizeof(*det_ctx->bj_values) *
+ (de_ctx->byte_extract_max_local_id + 1));
+ if (det_ctx->bj_values == NULL) {
+ return TM_ECODE_FAILED;
+ }
+
+ *data = (void *)det_ctx;
+
+ return TM_ECODE_OK;
+}
+
+static TmEcode DetectEngineThreadCtxInitForLiveRuleSwap(ThreadVars *tv, void *initdata, void **data)
+{
+ DetectEngineCtx *de_ctx = (DetectEngineCtx *)initdata;
+ if (de_ctx == NULL)
+ return TM_ECODE_FAILED;
+
+ DetectEngineThreadCtx *det_ctx = SCMalloc(sizeof(DetectEngineThreadCtx));
+ if (det_ctx == NULL)
+ return TM_ECODE_FAILED;
+ memset(det_ctx, 0, sizeof(DetectEngineThreadCtx));
+
+ det_ctx->de_ctx = de_ctx;
+
+ /** \todo we still depend on the global mpm_ctx here
+ *
+ * Initialize the thread pattern match ctx with the max size
+ * of the content and uricontent id's so our match lookup
+ * table is always big enough
+ */
+ PatternMatchThreadPrepare(&det_ctx->mtc, de_ctx->mpm_matcher, DetectContentMaxId(de_ctx));
+ PatternMatchThreadPrepare(&det_ctx->mtcs, de_ctx->mpm_matcher, DetectContentMaxId(de_ctx));
+ PatternMatchThreadPrepare(&det_ctx->mtcu, de_ctx->mpm_matcher, DetectUricontentMaxId(de_ctx));
+
+ //PmqSetup(&det_ctx->pmq, DetectEngineGetMaxSigId(de_ctx), DetectContentMaxId(de_ctx));
+ PmqSetup(&det_ctx->pmq, 0, DetectContentMaxId(de_ctx));
+ int i;
+ for (i = 0; i < 256; i++) {
+ PmqSetup(&det_ctx->smsg_pmq[i], 0, DetectContentMaxId(de_ctx));
+ }
+
+ /* IP-ONLY */
+ DetectEngineIPOnlyThreadInit(de_ctx,&det_ctx->io_ctx);
+
+ /* DeState */
+ if (de_ctx->sig_array_len > 0) {
+ det_ctx->de_state_sig_array_len = de_ctx->sig_array_len;
+ det_ctx->de_state_sig_array = SCMalloc(det_ctx->de_state_sig_array_len * sizeof(uint8_t));
+ if (det_ctx->de_state_sig_array == NULL) {
+ return TM_ECODE_FAILED;
+ }
+ memset(det_ctx->de_state_sig_array, 0,
+ det_ctx->de_state_sig_array_len * sizeof(uint8_t));
+
+ det_ctx->match_array_len = de_ctx->sig_array_len;
+ det_ctx->match_array = SCMalloc(det_ctx->match_array_len * sizeof(Signature *));
+ if (det_ctx->match_array == NULL) {
+ return TM_ECODE_FAILED;
+ }
+ memset(det_ctx->match_array, 0,
+ det_ctx->match_array_len * sizeof(Signature *));
+ }
+
+ /** alert counter setup */
+ det_ctx->counter_alerts = SCPerfTVRegisterCounter("detect.alert", tv,
+ SC_PERF_TYPE_UINT64, "NULL");
+ //tv->sc_perf_pca = SCPerfGetAllCountersArray(&tv->sc_perf_pctx);
+ //SCPerfAddToClubbedTMTable((tv->thread_group_name != NULL) ? tv->thread_group_name : tv->name, &tv->sc_perf_pctx);
+
+ /* this detection engine context belongs to this thread instance */
+ det_ctx->tv = tv;
+
+ det_ctx->bj_values = SCMalloc(sizeof(*det_ctx->bj_values) * (de_ctx->byte_extract_max_local_id + 1));
if (det_ctx->bj_values == NULL) {
return TM_ECODE_FAILED;
}
#include "tm-threads.h"
/* prototypes */
+void DetectEngineSpawnLiveRuleSwapMgmtThread(void);
DetectEngineCtx *DetectEngineCtxInit(void);
void DetectEngineCtxFree(DetectEngineCtx *);
tmm_modules[TMM_DETECT].ThreadDeinit = DetectThreadDeinit;
tmm_modules[TMM_DETECT].RegisterTests = SigRegisterTests;
tmm_modules[TMM_DETECT].cap_flags = 0;
+ tmm_modules[TMM_DETECT].flags = TM_FLAG_DETECT_TM;
PacketAlertTagInit();
}
if (IP_GET_IPPROTO(p) == p->flow->proto) { /* filter out icmp */
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_GETSGH);
if (p->flowflags & FLOW_PKT_TOSERVER && p->flow->flags & FLOW_SGH_TOSERVER) {
- det_ctx->sgh = p->flow->sgh_toserver;
- sms_runflags |= SMS_USE_FLOW_SGH;
+ if (p->flow->sgh_toserver_de_ctx_id != de_ctx->id) {
+ p->flow->flags &= ~FLOW_SGH_TOSERVER;
+ } else {
+ det_ctx->sgh = p->flow->sgh_toserver;
+ sms_runflags |= SMS_USE_FLOW_SGH;
+ }
} else if (p->flowflags & FLOW_PKT_TOCLIENT && p->flow->flags & FLOW_SGH_TOCLIENT) {
- det_ctx->sgh = p->flow->sgh_toclient;
- sms_runflags |= SMS_USE_FLOW_SGH;
+ if (p->flow->sgh_toclient_de_ctx_id != de_ctx->id) {
+ p->flow->flags &= ~FLOW_SGH_TOCLIENT;
+ } else {
+ det_ctx->sgh = p->flow->sgh_toclient;
+ sms_runflags |= SMS_USE_FLOW_SGH;
+ }
}
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_GETSGH);
memset(det_ctx->de_state_sig_array, 0x00, det_ctx->de_state_sig_array_len);
/* if applicable, continue stateful detection */
- int state = DeStateFlowHasState(p->flow, flags, alversion);
+ int state = DeStateFlowHasState(de_ctx, p->flow, flags, alversion);
if (state == 1) {
DeStateDetectContinueDetection(th_v, de_ctx, det_ctx, p->flow,
flags, alstate, alproto, alversion);
if (p->flowflags & FLOW_PKT_TOSERVER && !(p->flow->flags & FLOW_SGH_TOSERVER)) {
/* first time we see this toserver sgh, store it */
p->flow->sgh_toserver = det_ctx->sgh;
+ p->flow->sgh_toserver_de_ctx_id = de_ctx->id;
p->flow->flags |= FLOW_SGH_TOSERVER;
/* see if this sgh requires us to consider file storing */
}
} else if (p->flowflags & FLOW_PKT_TOCLIENT && !(p->flow->flags & FLOW_SGH_TOCLIENT)) {
p->flow->sgh_toclient = det_ctx->sgh;
+ p->flow->sgh_toclient_de_ctx_id = de_ctx->id;
p->flow->flags |= FLOW_SGH_TOCLIENT;
if (p->flow->sgh_toclient == NULL || p->flow->sgh_toclient->filestore_cnt == 0) {
goto error;
}
+ if (det_ctx->so_far_used_by_detect == 0) {
+ det_ctx->so_far_used_by_detect = 1;
+ SCLogDebug("Detect Engine using new det_ctx - %p and de_ctx - %p",
+ det_ctx, de_ctx);
+ }
+
/* see if the packet matches one or more of the sigs */
int r = SigMatchSignatures(tv,de_ctx,det_ctx,p);
if (r >= 0) {
/* the max local id used amongst all sigs */
int32_t byte_extract_max_local_id;
+ /* id used by every detect engine ctx instance */
+ uint32_t id;
+
/** sgh for signatures that match against invalid packets. In those cases
* we can't lookup by proto, address, port as we don't have these */
struct SigGroupHead_ *decoder_event_sgh;
/** ID of the transaction currently being inspected. */
uint16_t tx_id;
+ uint16_t so_far_used_by_detect;
+
/* holds the current recursion depth on content inspection */
int inspection_recursion_counter;
*/
void *FlowManagerThread(void *td)
{
+ /* block usr1. usr1 to be handled by the main thread only */
+ sigset_t x;
+ sigemptyset(&x);
+ sigaddset(&x, SIGUSR2);
+ sigprocmask(SIG_BLOCK, &x, NULL);
+
ThreadVars *th_v = (ThreadVars *)td;
struct timeval ts;
uint32_t established_cnt = 0, new_cnt = 0, closing_cnt = 0;
/** toclient sgh for this flow. Only use when FLOW_SGH_TOCLIENT flow flag
* has been set. */
struct SigGroupHead_ *sgh_toclient;
+ uint32_t sgh_toclient_de_ctx_id;
/** toserver sgh for this flow. Only use when FLOW_SGH_TOSERVER flow flag
* has been set. */
struct SigGroupHead_ *sgh_toserver;
+ uint32_t sgh_toserver_de_ctx_id;
/** List of tags of this flow (from "tag" keyword of type "session") */
void *tag_list;
/** set caps or not */
int sc_set_caps;
+char *conf_filename = NULL;
+
int RunmodeIsUnittests(void) {
if (run_mode == RUNMODE_UNITTEST)
return 1;
sigterm_count = 1;
suricata_ctl_flags |= SURICATA_KILL;
}
+
+void SignalHandlerSigusr2EngineShutdown(int sig)
+{
+ SCLogInfo("Live rule swap no longer possible. Engine in shutdown mode.");
+
+ return;
+}
+
+static void SignalHandlerSigusr2Idle(int sig)
+{
+ if (run_mode == RUNMODE_UNKNOWN || run_mode == RUNMODE_UNITTEST) {
+ SCLogInfo("Ruleset load signal USR2 triggered for wrong runmode");
+ return;
+ }
+
+ SCLogInfo("Hang on buddy! Ruleset load in progress. New ruleset load "
+ "allowed after current is done");
+
+ return;
+}
+
+void SignalHandlerSigusr2(int sig)
+{
+ if (run_mode == RUNMODE_UNKNOWN || run_mode == RUNMODE_UNITTEST) {
+ SCLogInfo("Ruleset load signal USR2 triggered for wrong runmode");
+ return;
+ }
+
+ SignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2Idle);
+
+ DetectEngineSpawnLiveRuleSwapMgmtThread();
+
+ return;
+}
+
#if 0
static void SignalHandlerSighup(/*@unused@*/ int sig) {
sighup_count = 1;
#endif
#endif
-static void
-SignalHandlerSetup(int sig, void (*handler)())
+void SignalHandlerSetup(int sig, void (*handler)())
{
#if defined (OS_WIN32)
signal(sig, handler);
char *sig_file = NULL;
int sig_file_exclusive = FALSE;
int conf_test = 0;
- char *conf_filename = NULL;
char *pid_filename = NULL;
#ifdef UNITTESTS
char *regex_arg = NULL;
AppLayerHtpNeedFileInspection();
+ SignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2Idle);
+
#ifdef UNITTESTS
if (run_mode == RUNMODE_UNITTEST) {
exit(EXIT_SUCCESS);
}
+ /* registering singal handlers we use. We register usr2 here, so that one
+ * can't call it during the first sig load phase */
+ SignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
+
#ifdef PROFILING
SCProfilingInitRuleCounters(de_ctx);
#endif /* PROFILING */
usleep(10* 1000);
}
+ SignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2EngineShutdown);
+
/* Update the engine stage/status flag */
SC_ATOMIC_CAS(&engine_stage, SURICATA_RUNTIME, SURICATA_DEINIT);
}
}
#endif
+ /* updated by AS. Don't clean up de_ctx. Necessiated by live rule swap */
+#if 0
SigGroupCleanup(de_ctx);
+#endif
#ifdef __SC_CUDA_SUPPORT__
if (PatternMatchDefaultMatcher() == MPM_B2G_CUDA) {
/* pop the cuda context we just pushed before the call to SigGroupCleanup() */
AppLayerHtpPrintStats();
+ /* updated by AS. Don't clean up de_ctx. Necessiated by live rule swap */
+#if 0
SigCleanSignatures(de_ctx);
+#endif
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
MpmFactoryDeRegisterAllMpmCtxProfiles(de_ctx);
}
+ /* updated by AS. Don't clean up de_ctx. Necessiated by live rule swap */
+#if 0
DetectEngineCtxFree(de_ctx);
+#endif
AlpProtoDestroy();
TagDestroyCtx();
/* uppercase to lowercase conversion lookup table */
uint8_t g_u8_lowercasetable[256];
+extern char *conf_filename;
+
/* marco to do the actual lookup */
//#define u8_tolower(c) g_u8_lowercasetable[(c)]
// these 2 are slower:
void EngineStop(void);
void EngineKill(void);
+/* live rule swap required this to be made static */
+void SignalHandlerSetup(int, void (*handler)());
+void SignalHandlerSigusr2(int);
+void SignalHandlerSigusr2EngineShutdown(int);
+
int RunmodeIsUnittests(void);
#endif /* __SURICATA_H__ */
/* thread flags */
#define TM_FLAG_RECEIVE_TM 0x01
#define TM_FLAG_DECODE_TM 0x02
+#define TM_FLAG_DETECT_TM 0x04
typedef struct TmModule_ {
char *name;
/* 1 slot functions */
void *TmThreadsSlot1NoIn(void *td)
{
+ /* block usr2. usr2 to be handled by the main thread only */
+ sigset_t x;
+ sigemptyset(&x);
+ sigaddset(&x, SIGUSR2);
+ sigprocmask(SIG_BLOCK, &x, NULL);
+
ThreadVars *tv = (ThreadVars *)td;
TmSlot *s = (TmSlot *)tv->tm_slots;
char run = 1;
void *TmThreadsSlot1NoOut(void *td)
{
+ /* block usr2. usr2 to be handled by the main thread only */
+ sigset_t x;
+ sigemptyset(&x);
+ sigaddset(&x, SIGUSR2);
+ sigprocmask(SIG_BLOCK, &x, NULL);
+
ThreadVars *tv = (ThreadVars *)td;
TmSlot *s = (TmSlot *)tv->tm_slots;
Packet *p = NULL;
void *TmThreadsSlot1NoInOut(void *td)
{
+ /* block usr2. usr2 to be handled by the main thread only */
+ sigset_t x;
+ sigemptyset(&x);
+ sigaddset(&x, SIGUSR2);
+ sigprocmask(SIG_BLOCK, &x, NULL);
+
ThreadVars *tv = (ThreadVars *)td;
TmSlot *s = (TmSlot *)tv->tm_slots;
char run = 1;
void *TmThreadsSlot1(void *td)
{
+ /* block usr2. usr2 to be handled by the main thread only */
+ sigset_t x;
+ sigemptyset(&x);
+ sigaddset(&x, SIGUSR2);
+ sigprocmask(SIG_BLOCK, &x, NULL);
+
ThreadVars *tv = (ThreadVars *)td;
TmSlot *s = (TmSlot *)tv->tm_slots;
Packet *p = NULL;
*/
void *TmThreadsSlotPktAcqLoop(void *td) {
+ /* block usr2. usr2 to be handled by the main thread only */
+ sigset_t x;
+ sigemptyset(&x);
+ sigaddset(&x, SIGUSR2);
+ sigprocmask(SIG_BLOCK, &x, NULL);
+
ThreadVars *tv = (ThreadVars *)td;
TmSlot *s = tv->tm_slots;
char run = 1;
*/
void *TmThreadsSlotVar(void *td)
{
+ /* block usr2. usr2 to be handled by the main thread only */
+ sigset_t x;
+ sigemptyset(&x);
+ sigaddset(&x, SIGUSR2);
+ sigprocmask(SIG_BLOCK, &x, NULL);
+
ThreadVars *tv = (ThreadVars *)td;
TmSlot *s = (TmSlot *)tv->tm_slots;
Packet *p = NULL;