]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
Simplify flow resetting on de_ctx update. Detect ctx id starts at 1. So in a flow...
authorVictor Julien <victor@inliniac.net>
Wed, 14 Mar 2012 10:18:43 +0000 (11:18 +0100)
committerVictor Julien <victor@inliniac.net>
Tue, 26 Jun 2012 07:36:11 +0000 (09:36 +0200)
src/detect-engine-state.c
src/detect-engine-state.h
src/detect-engine.c
src/detect.c
src/flow-util.h
src/flow.h

index 3e714d720b26d2b1030c62cc299b96f57dec6cfc..3cdf0d744403a5f0b0d58f125a3c20592acaa13e 100644 (file)
@@ -366,7 +366,7 @@ void DeStateStoreFileNoMatch(DetectEngineState *de_state, uint8_t direction,
  *  \retval 1 has state
  *  \retval 0 has no state
  */
-int DeStateFlowHasState(DetectEngineCtx *de_ctx, Flow *f, uint8_t flags, uint16_t alversion) {
+int DeStateFlowHasState(Flow *f, uint8_t flags, uint16_t alversion) {
     SCEnter();
 
     int r = 0;
@@ -679,15 +679,7 @@ 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);
@@ -735,13 +727,6 @@ 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 */
index 1602dc1ad19aca9ea996b5ec6d693d03c9179040..ad717be3eefeefb1938403454a3affb4125fe047 100644 (file)
@@ -125,10 +125,6 @@ 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;
 
@@ -141,7 +137,7 @@ void DetectEngineStateReset(DetectEngineState *state);
 DetectEngineState *DetectEngineStateAlloc(void);
 void DetectEngineStateFree(DetectEngineState *);
 
-int DeStateFlowHasState(DetectEngineCtx *, Flow *, uint8_t, uint16_t);
+int DeStateFlowHasState(Flow *, uint8_t, uint16_t);
 
 int DeStateDetectStartDetection(ThreadVars *, DetectEngineCtx *,
         DetectEngineThreadCtx *, Signature *, Flow *, uint8_t, void *,
index 3099b17b7e272d6b289dead786d5c5ccfee10a8f..815343b5c415179cc38f938d6e43b44810fbdad7 100644 (file)
@@ -67,7 +67,7 @@
 
 #define DETECT_ENGINE_DEFAULT_INSPECTION_RECURSION_LIMIT 3000
 
-static uint32_t detect_engine_ctx_id = 0;
+static uint32_t detect_engine_ctx_id = 1;
 
 static TmEcode DetectEngineThreadCtxInitForLiveRuleSwap(ThreadVars *, void *, void **);
 
index e50e2b0cb3cc5e2829e7a44033e65194d029cec3..f9a53ac3b55f03d53b35ee653b567c6441a7eaf0 100644 (file)
@@ -1304,6 +1304,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
     Signature *s = NULL;
     SigMatch *sm = NULL;
     uint16_t alversion = 0;
+    int reset_de_state = 0;
 
     SCEnter();
 
@@ -1328,6 +1329,21 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
 
         FLOWLOCK_WRLOCK(p->flow);
         {
+            /* live ruleswap check for flow updates */
+            if (p->flow->de_ctx_id == 0) {
+                /* first time this flow is inspected, set id */
+                p->flow->de_ctx_id = de_ctx->id;
+            } else if (p->flow->de_ctx_id != de_ctx->id) {
+                /* first time we inspect flow with this de_ctx, reset */
+                p->flow->flags &= ~FLOW_SGH_TOSERVER;
+                p->flow->flags &= ~FLOW_SGH_TOCLIENT;
+                p->flow->sgh_toserver = NULL;
+                p->flow->sgh_toclient = NULL;
+                reset_de_state = 1;
+
+                p->flow->de_ctx_id = de_ctx->id;
+            }
+
             /* set the iponly stuff */
             if (p->flow->flags & FLOW_TOCLIENT_IPONLY_SET)
                 p->flowflags |= FLOW_PKT_TOCLIENT_IPONLY_SET;
@@ -1339,19 +1355,11 @@ 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) {
-                    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;
-                    }
+                    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) {
-                    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;
-                    }
+                    det_ctx->sgh = p->flow->sgh_toclient;
+                    sms_runflags |= SMS_USE_FLOW_SGH;
                 }
                 PACKET_PROFILING_DETECT_END(p, PROF_DETECT_GETSGH);
 
@@ -1392,8 +1400,13 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
         }
         SCLogDebug("p->flowflags 0x%02x", p->flowflags);
 
+        /* reset because of ruleswap */
+        if (reset_de_state) {
+            SCMutexLock(&p->flow->de_state_m);
+            DetectEngineStateReset(p->flow->de_state);
+            SCMutexUnlock(&p->flow->de_state_m);
         /* see if we need to increment the inspect_id and reset the de_state */
-        if (alstate != NULL && alproto == ALPROTO_HTTP) {
+        } else if (alstate != NULL && alproto == ALPROTO_HTTP) {
             PACKET_PROFILING_DETECT_START(p, PROF_DETECT_STATEFUL);
             SCLogDebug("getting de_state_status");
             int de_state_status = DeStateUpdateInspectTransactionId(p->flow,
@@ -1488,7 +1501,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(de_ctx, p->flow, flags, alversion);
+        int state = DeStateFlowHasState(p->flow, flags, alversion);
         if (state == 1) {
             DeStateDetectContinueDetection(th_v, de_ctx, det_ctx, p->flow,
                     flags, alstate, alproto, alversion);
@@ -1776,7 +1789,6 @@ 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 */
@@ -1793,7 +1805,6 @@ 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) {
index c327c34700e5ceec08d6ba2c40a1243903a08eeb..e5c46a254db31c03f752e10eed048209ca347d3d 100644 (file)
         (f)->sp = 0; \
         (f)->dp = 0; \
         SC_ATOMIC_INIT((f)->use_cnt); \
+        (f)->probing_parser_toserver_al_proto_masks = 0; \
+        (f)->probing_parser_toclient_al_proto_masks = 0; \
         (f)->flags = 0; \
         (f)->lastts_sec = 0; \
         FLOWLOCK_INIT((f)); \
         (f)->protoctx = NULL; \
         (f)->alproto = 0; \
-        (f)->probing_parser_toserver_al_proto_masks = 0; \
-        (f)->probing_parser_toclient_al_proto_masks = 0; \
+        (f)->de_ctx_id = 0; \
         (f)->alparser = NULL; \
         (f)->alstate = NULL; \
         (f)->de_state = NULL; \
@@ -76,6 +77,8 @@
         (f)->sp = 0; \
         (f)->dp = 0; \
         SC_ATOMIC_RESET((f)->use_cnt); \
+        (f)->probing_parser_toserver_al_proto_masks = 0; \
+        (f)->probing_parser_toclient_al_proto_masks = 0; \
         (f)->flags = 0; \
         (f)->lastts_sec = 0; \
         (f)->protoctx = NULL; \
@@ -83,8 +86,7 @@
         (f)->alparser = NULL; \
         (f)->alstate = NULL; \
         (f)->alproto = 0; \
-        (f)->probing_parser_toserver_al_proto_masks = 0; \
-        (f)->probing_parser_toclient_al_proto_masks = 0; \
+        (f)->de_ctx_id = 0; \
         if ((f)->de_state != NULL) { \
             DetectEngineStateReset((f)->de_state); \
         } \
index 46b4c8101dcf2750dac0925f26bd606434402f0a..ab34da4124476e203c1aed36251d1ae432be358d 100644 (file)
@@ -315,6 +315,11 @@ typedef struct Flow_
 
     uint16_t alproto; /**< \brief application level protocol */
 
+    /** detection engine ctx id used to inspect this flow. Set at initial
+     *  inspection. If it doesn't match the currently in use de_ctx, the
+     *  de_state and stored sgh ptrs are reset. */
+    uint32_t de_ctx_id;
+
     /** application level storage ptrs.
      *
      */
@@ -327,11 +332,9 @@ 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;