live rule support added

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
remotes/origin/master
Anoop Saldanha 14 years ago committed by Victor Julien
parent 83a8f6e03a
commit ecad4a24fa

@ -433,6 +433,12 @@ static void SCPerfReleaseOPCtx()
*/
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;
@ -487,6 +493,12 @@ static void *SCPerfMgmtThread(void *arg)
*/
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;

@ -366,7 +366,7 @@ void DeStateStoreFileNoMatch(DetectEngineState *de_state, uint8_t direction,
* \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;
@ -679,7 +679,15 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
* 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);
@ -727,6 +735,13 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
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 */

@ -125,6 +125,10 @@ typedef struct DetectEngineState_ {
* 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;
@ -137,7 +141,7 @@ void DetectEngineStateReset(DetectEngineState *state);
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 *,

@ -22,6 +22,7 @@
*/
#include "suricata-common.h"
#include "suricata.h"
#include "debug.h"
#include "detect.h"
#include "flow.h"
@ -49,11 +50,14 @@
//#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"
@ -61,8 +65,236 @@
#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;
@ -133,6 +365,8 @@ DetectEngineCtx *DetectEngineCtxInit(void) {
goto error;
}
de_ctx->id = detect_engine_ctx_id++;
return de_ctx;
error:
return NULL;
@ -168,6 +402,8 @@ void DetectEngineCtxFree(DetectEngineCtx *de_ctx) {
SCClassConfDeInitContext(de_ctx);
SCRConfDeInitContext(de_ctx);
SigGroupCleanup(de_ctx);
SCFree(de_ctx);
//DetectAddressGroupPrintMemory();
//DetectSigGroupPrintMemory();
@ -453,7 +689,79 @@ TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data) {
/* 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;
}

@ -28,6 +28,7 @@
#include "tm-threads.h"
/* prototypes */
void DetectEngineSpawnLiveRuleSwapMgmtThread(void);
DetectEngineCtx *DetectEngineCtxInit(void);
void DetectEngineCtxFree(DetectEngineCtx *);

@ -208,6 +208,7 @@ void TmModuleDetectRegister (void) {
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();
}
@ -1338,11 +1339,19 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
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);
@ -1479,7 +1488,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
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);
@ -1767,6 +1776,7 @@ end:
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 */
@ -1783,6 +1793,7 @@ end:
}
} 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) {
@ -1842,6 +1853,12 @@ TmEcode Detect(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQue
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) {

@ -659,6 +659,9 @@ typedef struct DetectEngineCtx_ {
/* 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;
@ -733,6 +736,8 @@ typedef struct DetectionEngineThreadCtx_ {
/** 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;

@ -371,6 +371,12 @@ next:
*/
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;

@ -327,9 +327,11 @@ typedef struct Flow_
/** 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;

@ -222,6 +222,8 @@ intmax_t max_pending_packets;
/** set caps or not */
int sc_set_caps;
char *conf_filename = NULL;
int RunmodeIsUnittests(void) {
if (run_mode == RUNMODE_UNITTEST)
return 1;
@ -237,6 +239,41 @@ static void SignalHandlerSigterm(/*@unused@*/ int sig) {
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;
@ -258,8 +295,7 @@ uint8_t print_mem_flag = 1;
#endif
#endif
static void
SignalHandlerSetup(int sig, void (*handler)())
void SignalHandlerSetup(int sig, void (*handler)())
{
#if defined (OS_WIN32)
signal(sig, handler);
@ -630,7 +666,6 @@ int main(int argc, char **argv)
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;
@ -1435,6 +1470,8 @@ int main(int argc, char **argv)
AppLayerHtpNeedFileInspection();
SignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2Idle);
#ifdef UNITTESTS
if (run_mode == RUNMODE_UNITTEST) {
@ -1671,6 +1708,10 @@ int main(int argc, char **argv)
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 */
@ -1838,6 +1879,8 @@ int main(int argc, char **argv)
usleep(10* 1000);
}
SignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2EngineShutdown);
/* Update the engine stage/status flag */
SC_ATOMIC_CAS(&engine_stage, SURICATA_RUNTIME, SURICATA_DEINIT);
@ -1887,7 +1930,10 @@ int main(int argc, char **argv)
}
}
#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() */
@ -1902,11 +1948,17 @@ int main(int argc, char **argv)
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();

@ -125,6 +125,8 @@ extern uint8_t suricata_ctl_flags;
/* 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:
@ -138,6 +140,11 @@ uint8_t g_u8_lowercasetable[256];
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__ */

@ -30,6 +30,7 @@
/* 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;

@ -121,6 +121,12 @@ void TmThreadsUnsetFlag(ThreadVars *tv, uint8_t flag)
/* 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;
@ -213,6 +219,12 @@ void *TmThreadsSlot1NoIn(void *td)
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;
@ -288,6 +300,12 @@ void *TmThreadsSlot1NoOut(void *td)
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;
@ -358,6 +376,12 @@ void *TmThreadsSlot1NoInOut(void *td)
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;
@ -558,6 +582,12 @@ TmEcode TmThreadsSlotVarRun(ThreadVars *tv, Packet *p,
*/
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;
@ -645,6 +675,12 @@ void *TmThreadsSlotPktAcqLoop(void *td) {
*/
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;

Loading…
Cancel
Save