From: Eric Leblond Date: Fri, 7 Feb 2020 23:05:01 +0000 (+0100) Subject: app-layer-expectation: clean expectation at flow end X-Git-Tag: suricata-6.0.0-beta1~570 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1ddd77fae06d7b41b7d7752c70ebfce3d335983e;p=thirdparty%2Fsuricata.git app-layer-expectation: clean expectation at flow end 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. --- diff --git a/src/app-layer-expectation.c b/src/app-layer-expectation.c index 0c4f23d0c4..91cb067c2a 100644 --- a/src/app-layer-expectation.c +++ b/src/app-layer-expectation.c @@ -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; +} + /** * @} */ diff --git a/src/app-layer-expectation.h b/src/app-layer-expectation.h index 70f743a03f..c45b85f519 100644 --- a/src/app-layer-expectation.h +++ b/src/app-layer-expectation.h @@ -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__ */ diff --git a/src/flow.c b/src/flow.c index c07bf7c887..fce1ae3f31 100644 --- a/src/flow.c +++ b/src/flow.c @@ -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); diff --git a/src/flow.h b/src/flow.h index 25365c69e6..e362f8d40d 100644 --- a/src/flow.h +++ b/src/flow.h @@ -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 */