]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect: use hashes for all buffer to id
authorVictor Julien <victor@inliniac.net>
Wed, 22 Sep 2021 17:26:02 +0000 (19:26 +0200)
committerVictor Julien <vjulien@oisf.net>
Fri, 3 Dec 2021 15:28:20 +0000 (16:28 +0100)
Instead of a map that is constantly realloc'd, use 2 hash tables for
DetectBufferType entries: one by name (+transforms), the other by
id. Use these everywhere.

src/detect-engine-analyzer.c
src/detect-engine-mpm.c
src/detect-engine.c
src/detect-engine.h
src/detect.h

index 7ca4bf357350570a88c29788f099a5fc3d70bf60..562f4687b24c163ae19a07753cbd828965df1e36 100644 (file)
@@ -534,9 +534,9 @@ static void EngineAnalysisRulesPrintFP(const DetectEngineCtx *de_ctx, const Sign
     }
 
     fprintf(rule_engine_analysis_FD, "\" ");
-    if (de_ctx->buffer_type_map[list_type] && de_ctx->buffer_type_map[list_type]->transforms.cnt) {
-        fprintf(rule_engine_analysis_FD, "(with %d transform(s)) ",
-                de_ctx->buffer_type_map[list_type]->transforms.cnt);
+    const DetectBufferType *bt = DetectBufferTypeGetById(de_ctx, list_type);
+    if (bt && bt->transforms.cnt) {
+        fprintf(rule_engine_analysis_FD, "(with %d transform(s)) ", bt->transforms.cnt);
     }
     fprintf(rule_engine_analysis_FD, "buffer.\n");
 
@@ -1058,12 +1058,12 @@ error:
 
 void DumpPatterns(DetectEngineCtx *de_ctx)
 {
-    if (de_ctx->buffer_type_map_elements == 0 || de_ctx->pattern_hash_table == NULL)
+    if (de_ctx->pattern_hash_table == NULL)
         return;
 
     JsonBuilder *root_jb = jb_new_object();
-    JsonBuilder *arrays[de_ctx->buffer_type_map_elements];
-    memset(&arrays, 0, sizeof(JsonBuilder *) * de_ctx->buffer_type_map_elements);
+    JsonBuilder *arrays[de_ctx->buffer_type_id];
+    memset(&arrays, 0, sizeof(JsonBuilder *) * de_ctx->buffer_type_id);
 
     jb_open_array(root_jb, "buffers");
 
@@ -1102,7 +1102,7 @@ void DumpPatterns(DetectEngineCtx *de_ctx)
         jb_close(jb);
     }
 
-    for (uint32_t i = 0; i < de_ctx->buffer_type_map_elements; i++) {
+    for (uint32_t i = 0; i < de_ctx->buffer_type_id; i++) {
         JsonBuilder *jb = arrays[i];
         if (jb == NULL)
             continue;
index 03aac1134ac0e8ffd88ca63807b2e71d3b8484d8..5376031d19be2f45c6e1f7d8110f517a1373cc4f 100644 (file)
@@ -1112,10 +1112,10 @@ void MpmStoreReportStats(const DetectEngineCtx *de_ctx)
     HashListTableBucket *htb = NULL;
 
     uint32_t stats[MPMB_MAX] = {0};
-    int app_mpms_cnt = de_ctx->buffer_type_map_elements;
+    int app_mpms_cnt = de_ctx->buffer_type_id;
     uint32_t appstats[app_mpms_cnt + 1];    // +1 to silence scan-build
     memset(&appstats, 0x00, sizeof(appstats));
-    int pkt_mpms_cnt = de_ctx->buffer_type_map_elements;
+    int pkt_mpms_cnt = de_ctx->buffer_type_id;
     uint32_t pktstats[pkt_mpms_cnt + 1];    // +1 to silence scan-build
     memset(&pktstats, 0x00, sizeof(pktstats));
 
index a61d1416958b6d5ee5a87577607e7e66ba5cafad..3828d10de5dbfaecffb98c9914cc7a3820cb2fee 100644 (file)
@@ -690,20 +690,24 @@ int DetectBufferTypeMaxId(void)
     return g_buffer_type_id;
 }
 
-static uint32_t DetectBufferTypeHashFunc(HashListTable *ht, void *data, uint16_t datalen)
+static uint32_t DetectBufferTypeHashNameFunc(HashListTable *ht, void *data, uint16_t datalen)
 {
     const DetectBufferType *map = (DetectBufferType *)data;
-    uint32_t hash = 0;
-
-    hash = hashlittle_safe(map->string, strlen(map->string), 0);
+    uint32_t hash = hashlittle_safe(map->string, strlen(map->string), 0);
     hash += hashlittle_safe((uint8_t *)&map->transforms, sizeof(map->transforms), 0);
     hash %= ht->array_size;
+    return hash;
+}
 
+static uint32_t DetectBufferTypeHashIdFunc(HashListTable *ht, void *data, uint16_t datalen)
+{
+    const DetectBufferType *map = (DetectBufferType *)data;
+    uint32_t hash = map->id;
+    hash %= ht->array_size;
     return hash;
 }
 
-static char DetectBufferTypeCompareFunc(void *data1, uint16_t len1, void *data2,
-                                        uint16_t len2)
+static char DetectBufferTypeCompareNameFunc(void *data1, uint16_t len1, void *data2, uint16_t len2)
 {
     DetectBufferType *map1 = (DetectBufferType *)data1;
     DetectBufferType *map2 = (DetectBufferType *)data2;
@@ -713,6 +717,13 @@ static char DetectBufferTypeCompareFunc(void *data1, uint16_t len1, void *data2,
     return r;
 }
 
+static char DetectBufferTypeCompareIdFunc(void *data1, uint16_t len1, void *data2, uint16_t len2)
+{
+    DetectBufferType *map1 = (DetectBufferType *)data1;
+    DetectBufferType *map2 = (DetectBufferType *)data2;
+    return map1->id == map2->id;
+}
+
 static void DetectBufferTypeFreeFunc(void *data)
 {
     DetectBufferType *map = (DetectBufferType *)data;
@@ -740,10 +751,8 @@ static void DetectBufferTypeFreeFunc(void *data)
 static int DetectBufferTypeInit(void)
 {
     BUG_ON(g_buffer_type_hash);
-    g_buffer_type_hash = HashListTableInit(256,
-            DetectBufferTypeHashFunc,
-            DetectBufferTypeCompareFunc,
-            DetectBufferTypeFreeFunc);
+    g_buffer_type_hash = HashListTableInit(256, DetectBufferTypeHashNameFunc,
+            DetectBufferTypeCompareNameFunc, DetectBufferTypeFreeFunc);
     if (g_buffer_type_hash == NULL)
         return -1;
 
@@ -835,23 +844,20 @@ int DetectBufferTypeGetByName(const char *name)
     return exists->id;
 }
 
-const char *DetectBufferTypeGetNameById(const DetectEngineCtx *de_ctx, const int id)
+const DetectBufferType *DetectBufferTypeGetById(const DetectEngineCtx *de_ctx, const int id)
 {
-    BUG_ON(id < 0 || (uint32_t)id >= de_ctx->buffer_type_map_elements);
-    BUG_ON(de_ctx->buffer_type_map == NULL);
-
-    if (de_ctx->buffer_type_map[id] == NULL)
-        return NULL;
-
-    return de_ctx->buffer_type_map[id]->string;
+    DetectBufferType lookup;
+    memset(&lookup, 0, sizeof(lookup));
+    lookup.id = id;
+    const DetectBufferType *res =
+            HashListTableLookup(de_ctx->buffer_type_hash_id, (void *)&lookup, 0);
+    return res;
 }
 
-static const DetectBufferType *DetectBufferTypeGetById(const DetectEngineCtx *de_ctx, const int id)
+const char *DetectBufferTypeGetNameById(const DetectEngineCtx *de_ctx, const int id)
 {
-    BUG_ON(id < 0 || (uint32_t)id >= de_ctx->buffer_type_map_elements);
-    BUG_ON(de_ctx->buffer_type_map == NULL);
-
-    return de_ctx->buffer_type_map[id];
+    const DetectBufferType *res = DetectBufferTypeGetById(de_ctx, id);
+    return res ? res->string : NULL;
 }
 
 void DetectBufferTypeSetDescriptionByName(const char *name, const char *desc)
@@ -1210,32 +1216,35 @@ static void DetectBufferTypeSetupDetectEngine(DetectEngineCtx *de_ctx)
     const int size = g_buffer_type_id;
     BUG_ON(!(size > 0));
 
-    de_ctx->buffer_type_map = SCCalloc(size, sizeof(DetectBufferType *));
-    BUG_ON(!de_ctx->buffer_type_map);
-    de_ctx->buffer_type_map_elements = size;
-    SCLogDebug("de_ctx->buffer_type_map %p with %u members", de_ctx->buffer_type_map, size);
+    de_ctx->buffer_type_hash_name = HashListTableInit(256, DetectBufferTypeHashNameFunc,
+            DetectBufferTypeCompareNameFunc, DetectBufferTypeFreeFunc);
+    BUG_ON(de_ctx->buffer_type_hash_name == NULL);
+    de_ctx->buffer_type_hash_id =
+            HashListTableInit(256, DetectBufferTypeHashIdFunc, DetectBufferTypeCompareIdFunc,
+                    NULL); // entries owned by buffer_type_hash_name
+    BUG_ON(de_ctx->buffer_type_hash_id == NULL);
+    de_ctx->buffer_type_id = g_buffer_type_id;
 
     SCLogDebug("DETECT_SM_LIST_DYNAMIC_START %u", DETECT_SM_LIST_DYNAMIC_START);
     HashListTableBucket *b = HashListTableGetListHead(g_buffer_type_hash);
     while (b) {
         DetectBufferType *map = HashListTableGetListData(b);
-        de_ctx->buffer_type_map[map->id] = map;
+
+        DetectBufferType *copy = SCCalloc(1, sizeof(*copy));
+        BUG_ON(!copy);
+        memcpy(copy, map, sizeof(*copy));
+        int r = HashListTableAdd(de_ctx->buffer_type_hash_name, (void *)copy, 0);
+        BUG_ON(r != 0);
+        r = HashListTableAdd(de_ctx->buffer_type_hash_id, (void *)copy, 0);
+        BUG_ON(r != 0);
+
         SCLogDebug("name %s id %d mpm %s packet %s -- %s. "
-                "Callbacks: Setup %p Validate %p", map->string, map->id,
-                map->mpm ? "true" : "false", map->packet ? "true" : "false",
+                   "Callbacks: Setup %p Validate %p",
+                map->string, map->id, map->mpm ? "true" : "false", map->packet ? "true" : "false",
                 map->description, map->SetupCallback, map->ValidateCallback);
         b = HashListTableGetListNext(b);
     }
 
-    de_ctx->buffer_type_hash = HashListTableInit(256,
-            DetectBufferTypeHashFunc,
-            DetectBufferTypeCompareFunc,
-            DetectBufferTypeFreeFunc);
-    if (de_ctx->buffer_type_hash == NULL) {
-        BUG_ON(1);
-    }
-    de_ctx->buffer_type_id = g_buffer_type_id;
-
     PrefilterInit(de_ctx);
     DetectMpmInitializeAppMpms(de_ctx);
     DetectAppLayerInspectEngineCopyListToDetectCtx(de_ctx);
@@ -1246,10 +1255,10 @@ static void DetectBufferTypeSetupDetectEngine(DetectEngineCtx *de_ctx)
 static void DetectBufferTypeFreeDetectEngine(DetectEngineCtx *de_ctx)
 {
     if (de_ctx) {
-        if (de_ctx->buffer_type_map)
-            SCFree(de_ctx->buffer_type_map);
-        if (de_ctx->buffer_type_hash)
-            HashListTableFree(de_ctx->buffer_type_hash);
+        if (de_ctx->buffer_type_hash_name)
+            HashListTableFree(de_ctx->buffer_type_hash_name);
+        if (de_ctx->buffer_type_hash_id)
+            HashListTableFree(de_ctx->buffer_type_hash_id);
 
         DetectEngineAppInspectionEngine *ilist = de_ctx->app_inspect_engines;
         while (ilist) {
@@ -1309,7 +1318,7 @@ int DetectBufferTypeGetByIdTransforms(DetectEngineCtx *de_ctx, const int id,
     t.cnt = transform_cnt;
 
     DetectBufferType lookup_map = { (char *)base_map->string, NULL, 0, 0, 0, 0, false, NULL, NULL, t };
-    DetectBufferType *res = HashListTableLookup(de_ctx->buffer_type_hash, &lookup_map, 0);
+    DetectBufferType *res = HashListTableLookup(de_ctx->buffer_type_hash_name, &lookup_map, 0);
 
     SCLogDebug("res %p", res);
     if (res != NULL) {
@@ -1336,24 +1345,15 @@ int DetectBufferTypeGetByIdTransforms(DetectEngineCtx *de_ctx, const int id,
                 map->id, map->parent_id, &map->transforms);
     }
 
-    BUG_ON(HashListTableAdd(de_ctx->buffer_type_hash, (void *)map, 0) != 0);
+    BUG_ON(HashListTableAdd(de_ctx->buffer_type_hash_name, (void *)map, 0) != 0);
+    BUG_ON(HashListTableAdd(de_ctx->buffer_type_hash_id, (void *)map, 0) != 0);
     SCLogDebug("buffer %s registered with id %d, parent %d", map->string, map->id, map->parent_id);
+    de_ctx->buffer_type_id++;
 
-    if (map->id >= 0 && (uint32_t)map->id >= de_ctx->buffer_type_map_elements) {
-        void *ptr = SCRealloc(de_ctx->buffer_type_map, (map->id + 1) * sizeof(DetectBufferType *));
-        BUG_ON(ptr == NULL);
-        SCLogDebug("de_ctx->buffer_type_map resized to %u (was %u)", (map->id + 1), de_ctx->buffer_type_map_elements);
-        de_ctx->buffer_type_map = ptr;
-        de_ctx->buffer_type_map[map->id] = map;
-        de_ctx->buffer_type_map_elements = map->id + 1;
-
-        if (map->packet) {
-            DetectPktInspectEngineCopy(de_ctx, map->parent_id, map->id,
-                    &map->transforms);
-        } else {
-            DetectAppLayerInspectEngineCopy(de_ctx, map->parent_id, map->id,
-                    &map->transforms);
-        }
+    if (map->packet) {
+        DetectPktInspectEngineCopy(de_ctx, map->parent_id, map->id, &map->transforms);
+    } else {
+        DetectAppLayerInspectEngineCopy(de_ctx, map->parent_id, map->id, &map->transforms);
     }
     return map->id;
 }
index f952669ba8e7d782ec5da982ff7932939db50a60..f1227579ca6802000baabcb9fc0139023bd88799 100644 (file)
@@ -58,6 +58,7 @@ void DetectBufferTypeRegisterSetupCallback(const char *name,
         void (*Callback)(const DetectEngineCtx *, Signature *));
 void DetectBufferTypeRegisterValidateCallback(const char *name,
         bool (*ValidateCallback)(const Signature *, const char **sigerror));
+const DetectBufferType *DetectBufferTypeGetById(const DetectEngineCtx *de_ctx, const int id);
 
 int DetectBufferTypeGetByIdTransforms(DetectEngineCtx *de_ctx, const int id,
         TransformData *transforms, int transform_cnt);
index 0a0ac44d1c2f8ed26dddb876d04d476841e4c3af..c39ab27fa2f94c5f40f67a7e07a1eed084b702d9 100644 (file)
@@ -913,13 +913,11 @@ typedef struct DetectEngineCtx_ {
     /** table to store metadata keys and values */
     HashTable *metadata_table;
 
-    DetectBufferType **buffer_type_map;
-    uint32_t buffer_type_map_elements;
-
-    /* hash table with rule-time buffer registration. Start time registration
+    /* hash tables with rule-time buffer registration. Start time registration
      * is in detect-engine.c::g_buffer_type_hash */
-    HashListTable *buffer_type_hash;
-    int buffer_type_id;
+    HashListTable *buffer_type_hash_name;
+    HashListTable *buffer_type_hash_id;
+    uint32_t buffer_type_id;
 
     /* list with app inspect engines. Both the start-time registered ones and
      * the rule-time registered ones. */