]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
datasets: reload static sets
authorShivani Bhardwaj <shivanib134@gmail.com>
Mon, 27 Jul 2020 13:47:10 +0000 (19:17 +0530)
committerVictor Julien <victor@inliniac.net>
Sun, 2 Aug 2020 18:09:21 +0000 (20:09 +0200)
src/datasets.c
src/datasets.h
src/detect-engine.c

index 46f39d1926fac73c216fbaaf7e3aa6b14e037850..9104ef2e99c7990b3c1a90abdf854988fe36f085 100644 (file)
@@ -47,6 +47,7 @@ static inline void DatasetUnlockData(THashData *d)
     (void) THashDecrUsecnt(d);
     THashDataUnlock(d);
 }
+static bool DatasetIsStatic(const char *save, const char *load);
 
 enum DatasetTypes DatasetGetTypeFromString(const char *s)
 {
@@ -72,7 +73,7 @@ static Dataset *DatasetSearchByName(const char *name)
 {
     Dataset *set = sets;
     while (set) {
-        if (strcasecmp(name, set->name) == 0) {
+        if (strcasecmp(name, set->name) == 0 && set->hidden == false) {
             return set;
         }
         set = set->next;
@@ -532,6 +533,66 @@ out_err:
     return NULL;
 }
 
+static bool DatasetIsStatic(const char *save, const char *load)
+{
+    /* A set is static if it does not have any dynamic properties like
+     * save and/or state defined but has load defined.
+     * */
+    if ((load != NULL || strlen(load) > 0) &&
+            (save == NULL || strlen(save) == 0)) {
+        return true;
+    }
+    return false;
+}
+
+void DatasetReload(void)
+{
+    /* In order to reload the datasets, just mark the current sets as hidden
+     * and clean them up later.
+     * New datasets shall be created with the rule reload and do not require
+     * any intervention.
+     * */
+    SCMutexLock(&sets_lock);
+    Dataset *set = sets;
+    while (set) {
+        if (!DatasetIsStatic(set->save, set->load) || set->from_yaml == true) {
+            SCLogDebug("Not a static set, skipping %s", set->name);
+            set = set->next;
+            continue;
+        }
+        set->hidden = true;
+        SCLogDebug("Set %s at %p hidden successfully", set->name, set);
+        set = set->next;
+    }
+    SCMutexUnlock(&sets_lock);
+}
+
+void DatasetPostReloadCleanup(void)
+{
+    SCLogDebug("Post Reload Cleanup starting.. Hidden sets will be removed");
+    SCMutexLock(&sets_lock);
+    Dataset *cur = sets;
+    Dataset *prev = NULL;
+    while (cur) {
+        Dataset *next = cur->next;
+        if (cur->hidden == false) {
+            prev = cur;
+            cur = next;
+            continue;
+        }
+        // Delete the set in case it was hidden
+        if (prev != NULL) {
+            prev->next = next;
+        } else {
+            sets = next;
+        }
+        THashShutdown(cur->hash);
+        SCFree(cur);
+        cur = next;
+    }
+    SCMutexUnlock(&sets_lock);
+}
+
 int DatasetsInit(void)
 {
     SCLogDebug("datasets start");
@@ -585,6 +646,7 @@ int DatasetsInit(void)
                 if (dset == NULL)
                     FatalError(SC_ERR_FATAL, "failed to setup dataset for %s", set_name);
                 SCLogDebug("dataset %s: id %d type %s", set_name, n, set_type->val);
+                dset->from_yaml = true;
                 n++;
 
             } else if (strcmp(set_type->val, "sha256") == 0) {
@@ -592,6 +654,7 @@ int DatasetsInit(void)
                 if (dset == NULL)
                     FatalError(SC_ERR_FATAL, "failed to setup dataset for %s", set_name);
                 SCLogDebug("dataset %s: id %d type %s", set_name, n, set_type->val);
+                dset->from_yaml = true;
                 n++;
 
             } else if (strcmp(set_type->val, "string") == 0) {
@@ -599,6 +662,7 @@ int DatasetsInit(void)
                 if (dset == NULL)
                     FatalError(SC_ERR_FATAL, "failed to setup dataset for %s", set_name);
                 SCLogDebug("dataset %s: id %d type %s", set_name, n, set_type->val);
+                dset->from_yaml = true;
                 n++;
             }
 
index 16ae562684bb4166757291cf1d5b0e5e30bcb0c8..71003b28c216e274ef4fbf131c06887a9b375f2c 100644 (file)
@@ -24,6 +24,8 @@
 int DatasetsInit(void);
 void DatasetsDestroy(void);
 void DatasetsSave(void);
+void DatasetReload(void);
+void DatasetPostReloadCleanup(void);
 
 enum DatasetTypes {
 #define DATASET_TYPE_NOTSET 0
@@ -37,7 +39,8 @@ typedef struct Dataset {
     char name[DATASET_NAME_MAX_LEN + 1];
     enum DatasetTypes type;
     uint32_t id;
-
+    bool from_yaml;                     /* Mark whether the set was retrieved from YAML */
+    bool hidden;                        /* Mark the old sets hidden in case of reload */
     THashTableContext *hash;
 
     char load[PATH_MAX];
index cc767c8f085a59e9f7f361323be0129dac1760a3..ead7de6011d1384a6f1c53cd0010eca6c929d21e 100644 (file)
@@ -31,6 +31,7 @@
 #include "flow-worker.h"
 #include "conf.h"
 #include "conf-yaml-loader.h"
+#include "datasets.h"
 
 #include "app-layer-parser.h"
 #include "app-layer-htp.h"
@@ -4093,6 +4094,7 @@ int DetectEngineReload(const SCInstance *suri)
     if (old_de_ctx == NULL)
         return -1;
     SCLogDebug("get ref to old_de_ctx %p", old_de_ctx);
+    DatasetReload();
 
     /* only reload a regular 'normal' and 'delayed detect stub' detect engines */
     if (!(old_de_ctx->type == DETECT_ENGINE_TYPE_NORMAL ||
@@ -4134,6 +4136,8 @@ int DetectEngineReload(const SCInstance *suri)
     /* walk free list, freeing the old_de_ctx */
     DetectEnginePruneFreeList();
 
+    DatasetPostReloadCleanup();
+
     DetectEngineBumpVersion();
 
     SCLogDebug("old_de_ctx should have been freed");