]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
app-layer-expectation: clean expectation at flow end
authorEric Leblond <eric@regit.org>
Fri, 7 Feb 2020 23:05:01 +0000 (00:05 +0100)
committerVictor Julien <victor@inliniac.net>
Fri, 3 Apr 2020 08:07:48 +0000 (10:07 +0200)
When a flow timeout, we can have still existing expectations that
are linked to this flow. Given that there is a delay between the
real ending of the flow and its destruction by Suricata, the
expectation should be already honored so we can assume the risk
to clean the expectations that have been triggered by the
to-be-deleted flow.

src/app-layer-expectation.c
src/app-layer-expectation.h
src/flow.c
src/flow.h

index 0c4f23d0c46b1cc916436e0b63658c17163ccabe..91cb067c2a0d7a65e2a942fd49836d911d410945 100644 (file)
@@ -356,6 +356,37 @@ out:
     return alproto;
 }
 
+void AppLayerExpectationClean(Flow *f)
+{
+    IPPair *ipp = NULL;
+    Expectation *exp = NULL;
+    Expectation *pexp = NULL;
+
+    int x = SC_ATOMIC_GET(expectation_count);
+    if (x == 0) {
+        return;
+    }
+
+    /* Call will take reference of the ip pair in 'ipp' */
+    ExpectationList *exp_list = AppLayerExpectationLookup(f, &ipp);
+    if (exp_list == NULL)
+        goto out;
+
+    CIRCLEQ_FOREACH_SAFE(exp, &exp_list->list, entries, pexp) {
+        /* Cleaning remove old entries */
+        if (exp->orig_f == (void *)f) {
+            exp_list = AppLayerExpectationRemove(ipp, exp_list, exp);
+            if (exp_list == NULL)
+                goto out;
+        }
+    }
+
+out:
+    if (ipp)
+        IPPairRelease(ipp);
+    return;
+}
+
 /**
  * @}
  */
index 70f743a03fc4c6ae598bb7a07faac8c3c82d42cb..c45b85f5194c65b050ce0a8d91ba4f2eeabed54f 100644 (file)
@@ -30,6 +30,8 @@ int AppLayerExpectationCreate(Flow *f, int direction, Port src, Port dst,
 AppProto AppLayerExpectationHandle(Flow *f, int direction);
 int AppLayerExpectationGetDataId(void);
 
+void AppLayerExpectationClean(Flow *f);
+
 uint64_t ExpectationGetCounter(void);
 
 #endif /* __APP_LAYER_EXPECTATION__H__ */
index c07bf7c88776e130c9329a9b1e090234984654bc..fce1ae3f31149b522d2cd0f3baf031bc22e9a5af 100644 (file)
@@ -62,6 +62,7 @@
 #include "stream.h"
 
 #include "app-layer-parser.h"
+#include "app-layer-expectation.h"
 
 #define FLOW_DEFAULT_EMERGENCY_RECOVERY 30
 
@@ -1052,6 +1053,9 @@ int FlowClearMemory(Flow* f, uint8_t proto_map)
 
     FlowFreeStorage(f);
 
+    if (f->flags & FLOW_HAS_EXPECTATION)
+        AppLayerExpectationClean(f);
+
     FLOW_RECYCLE(f);
 
     SCReturnInt(1);
index 25365c69e654f3748e65fa07a9decc44de19a564..e362f8d40d6c2eb335b71660bfae93cccb3765c8 100644 (file)
@@ -104,6 +104,8 @@ typedef struct AppLayerParserState_ AppLayerParserState;
 #define FLOW_WRONG_THREAD               BIT_U32(25)
 /** Protocol detection told us flow is picked up in wrong direction (midstream) */
 #define FLOW_DIR_REVERSED               BIT_U32(26)
+/** Indicate that the flow did trigger an expectation creation */
+#define FLOW_HAS_EXPECTATION            BIT_U32(27)
 
 /* File flags */