]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/alert: add infra for new alert queue
authorJuliana Fajardini <jufajardini@gmail.com>
Mon, 18 Apr 2022 21:14:52 +0000 (18:14 -0300)
committerVictor Julien <vjulien@oisf.net>
Sat, 30 Apr 2022 05:58:39 +0000 (07:58 +0200)
Initial work to bring part of the alert queue processing to
DetectEngineThreadCtx.

Task #4943

src/detect-engine-alert.c
src/detect-engine-alert.h
src/detect-engine.c
src/detect.c
src/detect.h

index 6c2acf5e4ba05a40074145fbbd189733810c4745..9f7db969f1aa0ce71929105ca0f756ac01013700 100644 (file)
@@ -275,6 +275,88 @@ static void PacketApplySignatureActions(Packet *p, const Signature *s, const uin
     }
 }
 
+void AlertQueueInit(DetectEngineThreadCtx *det_ctx)
+{
+    det_ctx->alert_queue_size = 0;
+    det_ctx->alert_queue = SCCalloc(packet_alert_max, sizeof(PacketAlert));
+    if (det_ctx->alert_queue == NULL) {
+        FatalError(SC_ERR_MEM_ALLOC, "failed to allocate %" PRIu64 " bytes for the alert queue",
+                (uint64_t)(packet_alert_max * sizeof(PacketAlert)));
+    }
+    det_ctx->alert_queue_capacity = packet_alert_max;
+    SCLogDebug("alert queue initialized to %u elements (%" PRIu64 " bytes)", packet_alert_max,
+            (uint64_t)(packet_alert_max * sizeof(PacketAlert)));
+}
+
+void AlertQueueFree(DetectEngineThreadCtx *det_ctx)
+{
+    SCFree(det_ctx->alert_queue);
+    det_ctx->alert_queue_capacity = 0;
+}
+
+/** \internal
+ * \retval the new capacity
+ */
+static uint16_t AlertQueueExpand(DetectEngineThreadCtx *det_ctx)
+{
+    uint16_t new_cap = det_ctx->alert_queue_capacity * 2;
+    void *tmp_queue = SCRealloc(det_ctx->alert_queue, (size_t)(sizeof(PacketAlert) * new_cap));
+    if (unlikely(tmp_queue == NULL)) {
+        /* queue capacity didn't change */
+        return det_ctx->alert_queue_capacity;
+    }
+    det_ctx->alert_queue = tmp_queue;
+    det_ctx->alert_queue_capacity = new_cap;
+    SCLogDebug("Alert queue size doubled: %u elements, bytes: %" PRIuMAX "",
+            det_ctx->alert_queue_capacity,
+            (uintmax_t)(sizeof(PacketAlert) * det_ctx->alert_queue_capacity));
+    return new_cap;
+}
+
+/** \internal
+ */
+static inline PacketAlert PacketAlertSet(
+        DetectEngineThreadCtx *det_ctx, const Signature *s, uint64_t tx_id, uint8_t alert_flags)
+{
+    PacketAlert pa;
+    pa.num = s->num;
+    pa.action = s->action;
+    pa.s = (Signature *)s;
+    pa.flags = alert_flags;
+    /* Set tx_id if the frame has it */
+    pa.tx_id = (tx_id == UINT64_MAX) ? 0 : tx_id;
+    pa.frame_id = (alert_flags & PACKET_ALERT_FLAG_FRAME) ? det_ctx->frame_id : 0;
+    return pa;
+}
+
+/**
+ * \brief Append signature to local packet alert queue for later preprocessing
+ */
+void AlertQueueAppend(DetectEngineThreadCtx *det_ctx, const Signature *s, Packet *p, uint64_t tx_id,
+        uint8_t alert_flags)
+{
+    /* first time we see a drop action signature, set that in the packet */
+    /* we do that even before inserting into the queue, so we save it even if appending fails */
+    if (p->alerts.drop.action == 0 && s->action & ACTION_DROP) {
+        p->alerts.drop = PacketAlertSet(det_ctx, s, tx_id, alert_flags);
+        SCLogDebug("Set PacketAlert drop action. s->num %" PRIu32 "", s->num);
+    }
+
+    uint16_t pos = det_ctx->alert_queue_size;
+    if (pos == det_ctx->alert_queue_capacity) {
+        /* we must grow the alert queue */
+        if (pos == AlertQueueExpand(det_ctx)) {
+            /* this means we failed to expand the queue */
+            return;
+        }
+    }
+    det_ctx->alert_queue[pos] = PacketAlertSet(det_ctx, s, tx_id, alert_flags);
+
+    SCLogDebug("Appending sid %" PRIu32 ", s->num %" PRIu32 " to alert queue", s->id, s->num);
+    det_ctx->alert_queue_size++;
+    return;
+}
+
 /**
  * \brief Check the threshold of the sigs that match, set actions, break on pass action
  *        This function iterate the packet alerts array, removing those that didn't match
index dc6687885cc068e2ad52089678b191146a4cf8d7..8ae7fe5130a8549c8efb3d2f0e68b66b1b4a5454 100644 (file)
 #include "decode.h"
 #include "detect.h"
 
+void AlertQueueInit(DetectEngineThreadCtx *det_ctx);
+void AlertQueueFree(DetectEngineThreadCtx *det_ctx);
+void AlertQueueAppend(DetectEngineThreadCtx *det_ctx, const Signature *s, Packet *p, uint64_t tx_id,
+        uint8_t alert_flags);
 void PacketAlertFinalize(DetectEngineCtx *, DetectEngineThreadCtx *, Packet *);
 int PacketAlertAppend(DetectEngineThreadCtx *, const Signature *,
         Packet *, uint64_t tx_id, uint8_t);
index ad4babc04c3edebe20cdb3cf2f859f1534fbdce1..97ebe76a05b6a1c9a8077367b674a9bf37d8716c 100644 (file)
@@ -3066,6 +3066,9 @@ static TmEcode ThreadCtxDoInit (DetectEngineCtx *de_ctx, DetectEngineThreadCtx *
         RuleMatchCandidateTxArrayInit(det_ctx, de_ctx->sig_array_len);
     }
 
+    /* Alert processing queue */
+    AlertQueueInit(det_ctx);
+
     /* byte_extract storage */
     det_ctx->byte_values = SCMalloc(sizeof(*det_ctx->byte_values) *
                                   (de_ctx->byte_extract_max_local_id + 1));
@@ -3297,6 +3300,8 @@ static void DetectEngineThreadCtxFree(DetectEngineThreadCtx *det_ctx)
 
     RuleMatchCandidateTxArrayFree(det_ctx);
 
+    AlertQueueFree(det_ctx);
+
     if (det_ctx->byte_values != NULL)
         SCFree(det_ctx->byte_values);
 
index 7ff2638dc3912ebb0bceeb81c107c57e9387d43d..9d68f9a0198ccea8f2312365a618a19babf75621 100644 (file)
@@ -834,6 +834,9 @@ static DetectRunScratchpad DetectRunSetup(
     det_ctx->raw_stream_progress = 0;
     det_ctx->match_array_cnt = 0;
 
+    det_ctx->alert_queue_size = 0;
+    p->alerts.drop.action = 0;
+
 #ifdef DEBUG
     if (p->flags & PKT_STREAM_ADD) {
         det_ctx->pkt_stream_add_cnt++;
index bb5307c641e6f371fd12da72a42ded20938df138..967e0b63fcea16eb14add8fef668e07fd82033fb 100644 (file)
@@ -1130,6 +1130,10 @@ typedef struct DetectEngineThreadCtx_ {
     int64_t frame_id;
     Packet *p;
 
+    uint16_t alert_queue_size;
+    uint16_t alert_queue_capacity;
+    PacketAlert *alert_queue;
+
     SC_ATOMIC_DECLARE(int, so_far_used_by_detect);
 
     /* holds the current recursion depth on content inspection */
@@ -1558,6 +1562,11 @@ void *DetectThreadCtxGetKeywordThreadCtx(DetectEngineThreadCtx *, int);
 void RuleMatchCandidateTxArrayInit(DetectEngineThreadCtx *det_ctx, uint32_t size);
 void RuleMatchCandidateTxArrayFree(DetectEngineThreadCtx *det_ctx);
 
+void AlertQueueInit(DetectEngineThreadCtx *det_ctx);
+void AlertQueueFree(DetectEngineThreadCtx *det_ctx);
+void AlertQueueAppend(DetectEngineThreadCtx *det_ctx, const Signature *s, Packet *p, uint64_t tx_id,
+        uint8_t alert_flags);
+
 int DetectFlowbitsAnalyze(DetectEngineCtx *de_ctx);
 
 int DetectMetadataHashInit(DetectEngineCtx *de_ctx);