From ea571add738d73e1e8bbe6c4206c7d24813ad237 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Thu, 16 Jul 2015 16:43:19 +0200 Subject: [PATCH] app-layer: disruption flags Stream GAPs and stream reassembly depth are tracked per direction. In many cases they will happen in one direction, but not in the other. Example: HTTP requests a generally smaller than responses. So on the response side we may hit the depth limit, but not on the request side. The asynchronious 'disruption' has a side effect in the transaction engine. The 'progress' tracking would never mark such transactions as complete, and thus some inspection and logging wouldn't happen until the very last moment: when EOF's are passed around. Especially in proxy environments with _very_ many transactions in a single TCP connection, this could lead to serious resource issues. The EOF handling would suddenly have to handle thousands or more transactions. These transactions would have been stored for a long time. This patch introduces the concept of disruption flags. Flags passed to the tx progress logic that are and indication of disruptions in the traffic or the traffic handling. The idea is that the progress is marked as complete on disruption, even if a tx is not complete. This allows the detection and logging engines to process the tx after which it can be cleaned up. --- src/app-layer-parser.c | 19 ++++++++++++++++--- src/detect-engine-hcbd.c | 4 ++-- src/detect-engine-hcd.c | 4 ++-- src/detect-engine-hhd.c | 8 ++++---- src/detect-engine-hhhd.c | 2 +- src/detect-engine-hmd.c | 2 +- src/detect-engine-hrhd.c | 12 ++++++------ src/detect-engine-hrhhd.c | 2 +- src/detect-engine-hrl.c | 2 +- src/detect-engine-hrud.c | 2 +- src/detect-engine-hsbd.c | 6 +++--- src/detect-engine-hscd.c | 2 +- src/detect-engine-hsmd.c | 2 +- src/detect-engine-hua.c | 2 +- src/detect-engine-uri.c | 2 +- src/detect.c | 2 ++ src/flow.c | 31 +++++++++++++++++++++++++++++++ src/flow.h | 1 + 18 files changed, 76 insertions(+), 29 deletions(-) diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index c79e6142bb..c97929f700 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -725,13 +725,26 @@ static void AppLayerParserTransactionsCleanup(Flow *f) } } +#define IS_DISRUPTED(flags) \ + ((flags) & (STREAM_DEPTH|STREAM_GAP)) + +/** + * \brief get the progress value for a tx/protocol + * + * If the stream is disrupted, we return the 'completion' value. + */ int AppLayerParserGetStateProgress(uint8_t ipproto, AppProto alproto, - void *alstate, uint8_t direction) + void *alstate, uint8_t flags) { SCEnter(); int r = 0; - r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - StateGetProgress(alstate, direction); + if (unlikely(IS_DISRUPTED(flags))) { + r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. + StateGetProgressCompletionStatus(flags); + } else { + r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. + StateGetProgress(alstate, flags); + } SCReturnInt(r); } diff --git a/src/detect-engine-hcbd.c b/src/detect-engine-hcbd.c index aed137985e..a1e47e6be4 100644 --- a/src/detect-engine-hcbd.c +++ b/src/detect-engine-hcbd.c @@ -160,7 +160,7 @@ static uint8_t *DetectEngineHCBDGetBufferForTX(htp_tx_t *tx, uint64_t tx_id, if ((htp_state->cfg->request_body_limit == 0 || htud->request_body.content_len_so_far < htp_state->cfg->request_body_limit) && htud->request_body.content_len_so_far < htp_state->cfg->request_inspect_min_size && - !(AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOSERVER) > HTP_REQUEST_BODY) && + !(AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_BODY) && !(flags & STREAM_EOF)) { SCLogDebug("we still haven't seen the entire request body. " "Let's defer body inspection till we see the " @@ -274,7 +274,7 @@ int DetectEngineInspectHttpClientBody(ThreadVars *tv, end: - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOSERVER) > HTP_REQUEST_BODY) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_BODY) return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; else return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; diff --git a/src/detect-engine-hcd.c b/src/detect-engine-hcd.c index 513507e4e1..5fcfa51fd3 100644 --- a/src/detect-engine-hcd.c +++ b/src/detect-engine-hcd.c @@ -142,10 +142,10 @@ int DetectEngineInspectHttpCookie(ThreadVars *tv, end: if (flags & STREAM_TOSERVER) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOSERVER) > HTP_REQUEST_HEADERS) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_HEADERS) return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; } else { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOCLIENT) > HTP_RESPONSE_HEADERS) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_RESPONSE_HEADERS) return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; } return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; diff --git a/src/detect-engine-hhd.c b/src/detect-engine-hhd.c index 82c5b9ce35..baf5cf6672 100644 --- a/src/detect-engine-hhd.c +++ b/src/detect-engine-hhd.c @@ -143,11 +143,11 @@ static uint8_t *DetectEngineHHDGetBufferForTX(htp_tx_t *tx, uint64_t tx_id, htp_table_t *headers; if (flags & STREAM_TOSERVER) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOSERVER) <= HTP_REQUEST_HEADERS) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) <= HTP_REQUEST_HEADERS) goto end; headers = tx->request_headers; } else { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOCLIENT) <= HTP_RESPONSE_HEADERS) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) <= HTP_RESPONSE_HEADERS) goto end; headers = tx->response_headers; } @@ -263,10 +263,10 @@ int DetectEngineInspectHttpHeader(ThreadVars *tv, end: if (flags & STREAM_TOSERVER) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOSERVER) > HTP_REQUEST_HEADERS) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_HEADERS) return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; } else { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOCLIENT) > HTP_RESPONSE_HEADERS) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_RESPONSE_HEADERS) return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; } return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; diff --git a/src/detect-engine-hhhd.c b/src/detect-engine-hhhd.c index 77a9791d83..65aebd070a 100644 --- a/src/detect-engine-hhhd.c +++ b/src/detect-engine-hhhd.c @@ -118,7 +118,7 @@ int DetectEngineInspectHttpHH(ThreadVars *tv, return DETECT_ENGINE_INSPECT_SIG_MATCH; end: - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOSERVER) > HTP_REQUEST_HEADERS) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_HEADERS) return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; else return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; diff --git a/src/detect-engine-hmd.c b/src/detect-engine-hmd.c index c33cfd967d..5a4b7d8ad1 100644 --- a/src/detect-engine-hmd.c +++ b/src/detect-engine-hmd.c @@ -96,7 +96,7 @@ int DetectEngineInspectHttpMethod(ThreadVars *tv, { htp_tx_t *tx = (htp_tx_t *)txv; if (tx->request_method == NULL) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOSERVER) > HTP_REQUEST_LINE) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_LINE) return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; else return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; diff --git a/src/detect-engine-hrhd.c b/src/detect-engine-hrhd.c index b6b86a3772..90cf1d5e90 100644 --- a/src/detect-engine-hrhd.c +++ b/src/detect-engine-hrhd.c @@ -71,7 +71,7 @@ int DetectEngineRunHttpRawHeaderMpm(DetectEngineThreadCtx *det_ctx, Flow *f, SCReturnInt(cnt); if (flags & STREAM_TOSERVER) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, STREAM_TOSERVER) <= HTP_REQUEST_HEADERS) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) <= HTP_REQUEST_HEADERS) SCReturnInt(cnt); if (tx_ud->request_headers_raw != NULL) { @@ -81,7 +81,7 @@ int DetectEngineRunHttpRawHeaderMpm(DetectEngineThreadCtx *det_ctx, Flow *f, flags); } } else { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, STREAM_TOCLIENT) <= HTP_RESPONSE_HEADERS) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) <= HTP_RESPONSE_HEADERS) SCReturnInt(cnt); if (tx_ud->response_headers_raw != NULL) { @@ -120,10 +120,10 @@ int DetectEngineInspectHttpRawHeader(ThreadVars *tv, uint32_t headers_raw_len = 0; if (flags & STREAM_TOSERVER) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, STREAM_TOSERVER) <= HTP_REQUEST_HEADERS) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) <= HTP_REQUEST_HEADERS) return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; } else { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, STREAM_TOCLIENT) <= HTP_RESPONSE_HEADERS) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) <= HTP_RESPONSE_HEADERS) return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; } @@ -154,10 +154,10 @@ int DetectEngineInspectHttpRawHeader(ThreadVars *tv, end: if (flags & STREAM_TOSERVER) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, STREAM_TOSERVER) > HTP_REQUEST_HEADERS) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) > HTP_REQUEST_HEADERS) return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; } else { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, STREAM_TOCLIENT) > HTP_RESPONSE_HEADERS) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) > HTP_RESPONSE_HEADERS) return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; } return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; diff --git a/src/detect-engine-hrhhd.c b/src/detect-engine-hrhhd.c index 273c8b6d6a..f1acf10018 100644 --- a/src/detect-engine-hrhhd.c +++ b/src/detect-engine-hrhhd.c @@ -145,7 +145,7 @@ int DetectEngineInspectHttpHRH(ThreadVars *tv, return DETECT_ENGINE_INSPECT_SIG_MATCH; end: - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOSERVER) > HTP_REQUEST_HEADERS) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_HEADERS) return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; else return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; diff --git a/src/detect-engine-hrl.c b/src/detect-engine-hrl.c index af1b93f316..5e5c0cb621 100644 --- a/src/detect-engine-hrl.c +++ b/src/detect-engine-hrl.c @@ -72,7 +72,7 @@ int DetectEngineInspectHttpRequestLine(ThreadVars *tv, htp_tx_t *tx = (htp_tx_t *)txv; if (tx->request_line == NULL) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, STREAM_TOSERVER) > HTP_REQUEST_LINE) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) > HTP_REQUEST_LINE) return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; else return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; diff --git a/src/detect-engine-hrud.c b/src/detect-engine-hrud.c index 343054b9ad..c715c02926 100644 --- a/src/detect-engine-hrud.c +++ b/src/detect-engine-hrud.c @@ -102,7 +102,7 @@ int DetectEngineInspectHttpRawUri(ThreadVars *tv, { htp_tx_t *tx = (htp_tx_t *)txv; if (tx->request_uri == NULL) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOSERVER) > HTP_REQUEST_LINE) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_LINE) return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; else return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; diff --git a/src/detect-engine-hsbd.c b/src/detect-engine-hsbd.c index 9fad1a3af1..a6319db67f 100644 --- a/src/detect-engine-hsbd.c +++ b/src/detect-engine-hsbd.c @@ -286,7 +286,7 @@ static uint8_t *DetectEngineHSBDGetBufferForTX(htp_tx_t *tx, uint64_t tx_id, htud->response_body.content_len_so_far, htp_state->cfg->response_inspect_min_size, flags & STREAM_EOF ? "true" : "false", - (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOCLIENT) > HTP_RESPONSE_BODY) ? "true" : "false"); + (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_RESPONSE_BODY) ? "true" : "false"); if (!htp_state->cfg->http_body_inline) { /* inspect the body if the transfer is complete or we have hit @@ -294,7 +294,7 @@ static uint8_t *DetectEngineHSBDGetBufferForTX(htp_tx_t *tx, uint64_t tx_id, if ((htp_state->cfg->response_body_limit == 0 || htud->response_body.content_len_so_far < htp_state->cfg->response_body_limit) && htud->response_body.content_len_so_far < htp_state->cfg->response_inspect_min_size && - !(AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOCLIENT) > HTP_RESPONSE_BODY) && + !(AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_RESPONSE_BODY) && !(flags & STREAM_EOF)) { SCLogDebug("we still haven't seen the entire response body. " "Let's defer body inspection till we see the " @@ -368,7 +368,7 @@ int DetectEngineInspectHttpServerBody(ThreadVars *tv, return DETECT_ENGINE_INSPECT_SIG_MATCH; end: - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOCLIENT) > HTP_RESPONSE_BODY) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_RESPONSE_BODY) return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; else return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; diff --git a/src/detect-engine-hscd.c b/src/detect-engine-hscd.c index aa9f6f7dcc..a38562b193 100644 --- a/src/detect-engine-hscd.c +++ b/src/detect-engine-hscd.c @@ -100,7 +100,7 @@ int DetectEngineInspectHttpStatCode(ThreadVars *tv, { htp_tx_t *tx = (htp_tx_t *)txv; if (tx->response_status == NULL) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOCLIENT) > HTP_RESPONSE_LINE) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_RESPONSE_LINE) return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; else return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; diff --git a/src/detect-engine-hsmd.c b/src/detect-engine-hsmd.c index 2c5176022a..61c8e2e9b5 100644 --- a/src/detect-engine-hsmd.c +++ b/src/detect-engine-hsmd.c @@ -100,7 +100,7 @@ int DetectEngineInspectHttpStatMsg(ThreadVars *tv, { htp_tx_t *tx = (htp_tx_t *)txv; if (tx->response_message == NULL) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOCLIENT) > HTP_RESPONSE_LINE) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_RESPONSE_LINE) return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; else return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; diff --git a/src/detect-engine-hua.c b/src/detect-engine-hua.c index d1bd0c2ff1..8cafa423af 100644 --- a/src/detect-engine-hua.c +++ b/src/detect-engine-hua.c @@ -122,7 +122,7 @@ int DetectEngineInspectHttpUA(ThreadVars *tv, return DETECT_ENGINE_INSPECT_SIG_MATCH; end: - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOSERVER) > HTP_REQUEST_HEADERS) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_HEADERS) return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; else return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; diff --git a/src/detect-engine-uri.c b/src/detect-engine-uri.c index e0df1e0b9e..cd73715784 100644 --- a/src/detect-engine-uri.c +++ b/src/detect-engine-uri.c @@ -73,7 +73,7 @@ int DetectEngineInspectPacketUris(ThreadVars *tv, HtpTxUserData *tx_ud = htp_tx_get_user_data(txv); if (tx_ud == NULL || tx_ud->request_uri_normalized == NULL) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, STREAM_TOSERVER) > HTP_REQUEST_LINE) + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) > HTP_REQUEST_LINE) return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; else return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; diff --git a/src/detect.c b/src/detect.c index 77de1714ad..868e3ed736 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1335,6 +1335,8 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh (p->proto == IPPROTO_UDP) || (p->proto == IPPROTO_SCTP && (p->flowflags & FLOW_PKT_ESTABLISHED))) { + /* update flow flags with knowledge on disruptions */ + flow_flags = FlowGetDisruptionFlags(pflow, flow_flags); has_state = (FlowGetAppState(pflow) != NULL); alproto = FlowGetAppProtocol(pflow); alversion = AppLayerParserGetStateVersion(pflow->alparser); diff --git a/src/flow.c b/src/flow.c index 4e9b684806..42099c3ad5 100644 --- a/src/flow.c +++ b/src/flow.c @@ -870,6 +870,37 @@ void *FlowGetAppState(const Flow *f) return f->alstate; } +/** + * \brief get 'disruption' flags: GAP/DEPTH/PASS + * \param f locked flow + * \param flags existing flags to be ammended + * \retval flags original flags + disrupt flags (if any) + * \TODO handle UDP + */ +uint8_t FlowGetDisruptionFlags(const Flow *f, uint8_t flags) +{ + if (f->proto != IPPROTO_TCP) { + return flags; + } + if (f->protoctx == NULL) { + return flags; + } + + uint8_t newflags = flags; + TcpSession *ssn = f->protoctx; + TcpStream *stream = flags & STREAM_TOSERVER ? &ssn->client : &ssn->server; + + if (stream->flags & STREAMTCP_STREAM_FLAG_DEPTH_REACHED) { + newflags |= STREAM_DEPTH; + } + if (stream->flags & STREAMTCP_STREAM_FLAG_GAP) { + newflags |= STREAM_GAP; + } + /* todo: handle pass case (also for UDP!) */ + + return newflags; +} + /************************************Unittests*******************************/ #ifdef UNITTESTS diff --git a/src/flow.h b/src/flow.h index bc1f65ac88..caa34c6fc8 100644 --- a/src/flow.h +++ b/src/flow.h @@ -568,6 +568,7 @@ int FlowClearMemory(Flow *,uint8_t ); AppProto FlowGetAppProtocol(const Flow *f); void *FlowGetAppState(const Flow *f); +uint8_t FlowGetDisruptionFlags(const Flow *f, uint8_t flags); void FlowHandlePacketUpdateRemove(Flow *f, Packet *p); void FlowHandlePacketUpdate(Flow *f, Packet *p); -- 2.47.2