]> git.ipfire.org Git - people/ms/suricata.git/commitdiff
detect: store detect flags in AppLayerTxData
authorVictor Julien <victor@inliniac.net>
Tue, 26 May 2020 12:34:57 +0000 (14:34 +0200)
committerVictor Julien <victor@inliniac.net>
Sat, 11 Jul 2020 06:37:40 +0000 (08:37 +0200)
rust/src/applayer.rs
src/app-layer-parser.c
src/detect-engine-state.h
src/detect.c

index 7e4d3732b5e7b46f88140fd3db455b9343d31919..1ed11b36e1b5e625fcf5544ee713b462566d6a8a 100644 (file)
@@ -57,6 +57,10 @@ pub struct AppLayerTxData {
 
     /// logger flags for tx logging api
     logged: LoggerFlags,
+
+    /// detection engine flags for use by detection engine
+    detect_flags_ts: u64,
+    detect_flags_tc: u64,
 }
 
 impl AppLayerTxData {
@@ -64,6 +68,8 @@ impl AppLayerTxData {
         Self {
             config: AppLayerTxConfig::new(),
             logged: LoggerFlags::new(),
+            detect_flags_ts: 0,
+            detect_flags_tc: 0,
         }
     }
 }
index dae0d2487748c9b1a0db52368adc3c4c00c8e94d..e96c827dab5cf463150c26bd85dbcbe9ff02abe6 100644 (file)
@@ -745,6 +745,42 @@ uint64_t AppLayerParserGetTransactionInspectId(AppLayerParserState *pstate, uint
     SCReturnCT(pstate->inspect_id[direction & STREAM_TOSERVER ? 0 : 1], "uint64_t");
 }
 
+static inline uint64_t GetTxDetectFlags(const uint8_t ipproto, const AppProto alproto, void *tx, const uint8_t dir)
+{
+    uint64_t detect_flags;
+    AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx);
+    if (txd != NULL) {
+        detect_flags = (dir & STREAM_TOSERVER) ? txd->detect_flags_ts : txd->detect_flags_tc;
+    } else {
+        detect_flags = AppLayerParserGetTxDetectFlags(ipproto, alproto, tx, dir);
+    }
+    return detect_flags;
+}
+
+static inline void SetTxDetectFlags(const uint8_t ipproto, const AppProto alproto, void *tx, const uint8_t dir, const uint64_t detect_flags)
+{
+    AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx);
+    if (txd != NULL) {
+        if (dir & STREAM_TOSERVER) {
+            txd->detect_flags_ts = detect_flags;
+        } else {
+            txd->detect_flags_tc = detect_flags;
+        }
+    } else {
+        AppLayerParserSetTxDetectFlags(ipproto, alproto, tx, dir, detect_flags);
+    }
+}
+
+static inline uint32_t GetTxLogged(const Flow *f, void *alstate, void *tx)
+{
+    AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, tx);
+    if (txd) {
+        return txd->logged.flags;
+    } else {
+        return AppLayerParserGetTxLogged(f, alstate, tx);
+    }
+}
+
 void AppLayerParserSetTransactionInspectId(const Flow *f, AppLayerParserState *pstate,
                                            void *alstate, const uint8_t flags,
                                            bool tag_txs_as_inspected)
@@ -780,10 +816,10 @@ void AppLayerParserSetTransactionInspectId(const Flow *f, AppLayerParserState *p
             break;
 
         if (tag_txs_as_inspected) {
-            uint64_t detect_flags = AppLayerParserGetTxDetectFlags(ipproto, alproto, tx, flags);
+            uint64_t detect_flags = GetTxDetectFlags(ipproto, alproto, tx, flags);
             if ((detect_flags & APP_LAYER_TX_INSPECTED_FLAG) == 0) {
                 detect_flags |= APP_LAYER_TX_INSPECTED_FLAG;
-                AppLayerParserSetTxDetectFlags(ipproto, alproto, tx, flags, detect_flags);
+                SetTxDetectFlags(ipproto, alproto, tx, flags, detect_flags);
                 SCLogDebug("%p/%"PRIu64" in-order tx is done for direction %s. Flag %016"PRIx64,
                         tx, idx, flags & STREAM_TOSERVER ? "toserver" : "toclient", detect_flags);
             }
@@ -817,10 +853,10 @@ void AppLayerParserSetTransactionInspectId(const Flow *f, AppLayerParserState *p
             if (state_progress < state_done_progress)
                 break;
 
-            uint64_t detect_flags = AppLayerParserGetTxDetectFlags(ipproto, alproto, tx, flags);
+            uint64_t detect_flags = GetTxDetectFlags(ipproto, alproto, tx, flags);
             if ((detect_flags & APP_LAYER_TX_INSPECTED_FLAG) == 0) {
                 detect_flags |= APP_LAYER_TX_INSPECTED_FLAG;
-                AppLayerParserSetTxDetectFlags(ipproto, alproto, tx, flags, detect_flags);
+                SetTxDetectFlags(ipproto, alproto, tx, flags, detect_flags);
                 SCLogDebug("%p/%"PRIu64" out of order tx is done for direction %s. Flag %016"PRIx64,
                         tx, idx, flags & STREAM_TOSERVER ? "toserver" : "toclient", detect_flags);
 
@@ -895,7 +931,7 @@ void AppLayerParserTransactionsCleanup(Flow *f)
     if (unlikely(p->StateTransactionFree == NULL))
         SCReturn;
 
-    const bool has_tx_detect_flags = (p->GetTxDetectFlags != NULL);
+    const bool has_tx_detect_flags = (p->GetTxDetectFlags != NULL || p->GetTxData != NULL);
     const uint8_t ipproto = f->proto;
     const AppProto alproto = f->alproto;
     void * const alstate = f->alstate;
@@ -942,7 +978,7 @@ void AppLayerParserTransactionsCleanup(Flow *f)
         }
         if (has_tx_detect_flags) {
             if (f->sgh_toserver != NULL) {
-                uint64_t detect_flags_ts = AppLayerParserGetTxDetectFlags(ipproto, alproto, tx, STREAM_TOSERVER);
+                uint64_t detect_flags_ts = GetTxDetectFlags(ipproto, alproto, tx, STREAM_TOSERVER);
                 if (!(detect_flags_ts & APP_LAYER_TX_INSPECTED_FLAG)) {
                     SCLogDebug("%p/%"PRIu64" skipping: TS inspect not done: ts:%"PRIx64,
                             tx, i, detect_flags_ts);
@@ -951,7 +987,7 @@ void AppLayerParserTransactionsCleanup(Flow *f)
                 }
             }
             if (f->sgh_toclient != NULL) {
-                uint64_t detect_flags_tc = AppLayerParserGetTxDetectFlags(ipproto, alproto, tx, STREAM_TOCLIENT);
+                uint64_t detect_flags_tc = GetTxDetectFlags(ipproto, alproto, tx, STREAM_TOCLIENT);
                 if (!(detect_flags_tc & APP_LAYER_TX_INSPECTED_FLAG)) {
                     SCLogDebug("%p/%"PRIu64" skipping: TC inspect not done: tc:%"PRIx64,
                             tx, i, detect_flags_tc);
@@ -961,7 +997,7 @@ void AppLayerParserTransactionsCleanup(Flow *f)
             }
         }
         if (logger_expectation != 0) {
-            LoggerId tx_logged = AppLayerParserGetTxLogged(f, alstate, tx);
+            LoggerId tx_logged = GetTxLogged(f, alstate, tx);
             if (tx_logged != logger_expectation) {
                 SCLogDebug("%p/%"PRIu64" skipping: logging not done: want:%"PRIx32", have:%"PRIx32,
                         tx, i, logger_expectation, tx_logged);
@@ -1147,6 +1183,9 @@ bool AppLayerParserSupportsTxDetectFlags(AppProto alproto)
         if (alp_ctx.ctxs[p][alproto].GetTxDetectFlags != NULL) {
             SCReturnBool(true);
         }
+        if (alp_ctx.ctxs[p][alproto].GetTxData != NULL) {
+            SCReturnBool(true);
+        }
     }
     SCReturnBool(false);
 }
index 154f8bbaf30219f3eeee9bd9ce53164493d3f103..4491105619d6d3a353c42e4e31ae244f07cca61a 100644 (file)
@@ -97,6 +97,7 @@ typedef struct DetectEngineState_ {
 typedef struct DetectTransaction_ {
     void *tx_ptr;
     const uint64_t tx_id;
+    struct AppLayerTxData *tx_data_ptr;
     DetectEngineStateDirection *de_state;
     const uint64_t detect_flags;            /* detect flags get/set from/to applayer */
     uint64_t prefilter_flags;               /* prefilter flags for direction, to be updated by prefilter code */
index 9aa0a279aca17312d830fe36a5e178fdff9f9698..fe0e55406e9b51a54a3cdda465e452eaae6fc511 100644 (file)
@@ -1233,12 +1233,18 @@ static DetectTransaction GetDetectTx(const uint8_t ipproto, const AppProto alpro
         void *alstate, const uint64_t tx_id, void *tx_ptr, const int tx_end_state,
         const uint8_t flow_flags)
 {
-    const uint64_t detect_flags = AppLayerParserGetTxDetectFlags(ipproto, alproto, tx_ptr, flow_flags);
+    uint64_t detect_flags;
+    AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx_ptr);
+    if (txd != NULL) {
+        detect_flags = (flow_flags & STREAM_TOSERVER) ? txd->detect_flags_ts : txd->detect_flags_tc;
+    } else {
+        detect_flags = AppLayerParserGetTxDetectFlags(ipproto, alproto, tx_ptr, flow_flags);
+    }
     if (detect_flags & APP_LAYER_TX_INSPECTED_FLAG) {
         SCLogDebug("%"PRIu64" tx already fully inspected for %s. Flags %016"PRIx64,
                 tx_id, flow_flags & STREAM_TOSERVER ? "toserver" : "toclient",
                 detect_flags);
-        DetectTransaction no_tx = { NULL, 0, NULL, 0, 0, 0, 0, 0, };
+        DetectTransaction no_tx = { NULL, 0, NULL, NULL, 0, 0, 0, 0, 0, };
         return no_tx;
     }
 
@@ -1251,6 +1257,7 @@ static DetectTransaction GetDetectTx(const uint8_t ipproto, const AppProto alpro
     DetectTransaction tx = {
                             .tx_ptr = tx_ptr,
                             .tx_id = tx_id,
+                            .tx_data_ptr = (struct AppLayerTxData *)txd,
                             .de_state = tx_dir_state,
                             .detect_flags = detect_flags,
                             .prefilter_flags = prefilter_flags,
@@ -1261,6 +1268,22 @@ static DetectTransaction GetDetectTx(const uint8_t ipproto, const AppProto alpro
     return tx;
 }
 
+static inline void StoreDetectFlags(DetectTransaction *tx, const uint8_t flow_flags,
+        const uint8_t ipproto, const AppProto alproto, const uint64_t detect_flags)
+{
+    AppLayerTxData *txd = (AppLayerTxData *)tx->tx_data_ptr;
+    if (txd != NULL) {
+        if (flow_flags & STREAM_TOSERVER) {
+            txd->detect_flags_ts = detect_flags;
+        } else {
+            txd->detect_flags_tc = detect_flags;
+        }
+    } else {
+        AppLayerParserSetTxDetectFlags(ipproto, alproto, tx->tx_ptr,
+                flow_flags, detect_flags);
+    }
+}
+
 static void DetectRunTx(ThreadVars *tv,
                     DetectEngineCtx *de_ctx,
                     DetectEngineThreadCtx *det_ctx,
@@ -1501,8 +1524,8 @@ static void DetectRunTx(ThreadVars *tv,
             new_detect_flags |= tx.detect_flags;
             SCLogDebug("%p/%"PRIu64" Storing new flags %016"PRIx64" (was %016"PRIx64")",
                     tx.tx_ptr, tx.tx_id, new_detect_flags, tx.detect_flags);
-            AppLayerParserSetTxDetectFlags(ipproto, alproto, tx.tx_ptr,
-                    flow_flags, new_detect_flags);
+
+            StoreDetectFlags(&tx, flow_flags, ipproto, alproto, new_detect_flags);
         }
 next:
         InspectionBufferClean(det_ctx);