]> git.ipfire.org Git - people/ms/suricata.git/commitdiff
detect/threshold: Function to deep-copy thresh obj
authorJeff Lucovsky <jeff@lucovsky.org>
Mon, 29 Mar 2021 12:28:50 +0000 (08:28 -0400)
committerVictor Julien <victor@inliniac.net>
Thu, 8 Apr 2021 09:08:32 +0000 (11:08 +0200)
This commit adds a function to make a deep copy of a DetectThresholdData
object.

The function is used when parsing threshold.config items to make a
one-time object and then add copies as needed.

src/detect-threshold.c
src/detect-threshold.h

index 612fb56e45d909c82f45808089447fa6766da69f..3abe8d263cef4e15c2593704697de14571bcd2a5 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2020 Open Information Security Foundation
+/* Copyright (C) 2007-2021 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
@@ -286,6 +286,53 @@ static void DetectThresholdFree(DetectEngineCtx *de_ctx, void *de_ptr)
     }
 }
 
+/**
+ * \brief Make a deep-copy of an extant DetectTHresholdData object.
+ *
+ * \param de pointer to DetectThresholdData
+ */
+DetectThresholdData *DetectThresholdDataCopy(DetectThresholdData *de)
+{
+    DetectThresholdData *new_de = SCCalloc(1, sizeof(DetectThresholdData));
+    if (unlikely(new_de == NULL))
+        return NULL;
+
+    *new_de = *de;
+    new_de->addrs.ipv4_head = NULL;
+    new_de->addrs.ipv6_head = NULL;
+
+    for (DetectAddress *last = NULL, *tmp_ad = de->addrs.ipv4_head; tmp_ad; tmp_ad = tmp_ad->next) {
+        DetectAddress *n_addr = DetectAddressCopy(tmp_ad);
+        if (n_addr == NULL)
+            goto error;
+        if (last == NULL) {
+            new_de->addrs.ipv4_head = n_addr;
+        } else {
+            last->next = n_addr;
+            n_addr->prev = last;
+        }
+        last = n_addr;
+    }
+    for (DetectAddress *last = NULL, *tmp_ad = de->addrs.ipv6_head; tmp_ad; tmp_ad = tmp_ad->next) {
+        DetectAddress *n_addr = DetectAddressCopy(tmp_ad);
+        if (n_addr == NULL)
+            goto error;
+        if (last == NULL) {
+            new_de->addrs.ipv6_head = n_addr;
+        } else {
+            last->next = n_addr;
+            n_addr->prev = last;
+        }
+        last = n_addr;
+    }
+
+    return new_de;
+
+error:
+    DetectThresholdFree(NULL, new_de);
+    return NULL;
+}
+
 /*
  * ONLY TESTS BELOW THIS COMMENT
  */
index 616e48ab2c76e783ad19f043f4db2a71273f39e2..4accda399c95ac62b664c97feaff6cac3af73d8c 100644 (file)
@@ -85,5 +85,6 @@ typedef struct DetectThresholdEntry_ {
  */
 
 void DetectThresholdRegister(void);
+DetectThresholdData *DetectThresholdDataCopy(DetectThresholdData *);
 
 #endif /*__DETECT_THRESHOLD_H__ */