]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1965 in SNORT/snort3 from ~DAVMCPHE/snort3:reload_fatal_attractio...
authorDavis McPherson (davmcphe) <davmcphe@cisco.com>
Thu, 13 Feb 2020 14:26:17 +0000 (14:26 +0000)
committerDavis McPherson (davmcphe) <davmcphe@cisco.com>
Thu, 13 Feb 2020 14:26:17 +0000 (14:26 +0000)
Squashed commit of the following:

commit 24b57441e129bcfdd47bfaf62d55957a0ccc6c38
Author: davis mcpherson <davmcphe@cisco.com>
Date:   Fri Nov 22 13:27:03 2019 -0500

    reload: eliminate FatalError calls that can't happen because snort_calloc always returns valid memory

    ghash: refactor ghash implementation to convert it to an actual c++ class.

    xhash: refactor xhash to be a real c++ class

    xhash/zhash: refactor to move common definitions into hash_defs.h

    hashfcn: refactor key compare function prototype and functions to return boolean

72 files changed:
src/detection/detection_options.cc
src/detection/detection_options.h
src/detection/fp_create.cc
src/detection/fp_detect.cc
src/detection/fp_detect.h
src/detection/pcrm.cc
src/detection/rules.h
src/detection/service_map.cc
src/detection/service_map.h
src/detection/signature.cc
src/detection/signature.h
src/detection/tag.cc
src/detection/treenodes.h
src/file_api/file_cache.cc
src/file_api/file_cache.h
src/file_api/file_identifier.cc
src/filters/detection_filter.cc
src/filters/rate_filter.cc
src/filters/sfrf.cc
src/filters/sfrf.h
src/filters/sfthd.cc
src/filters/sfthd.h
src/filters/sfthd_test.cc
src/flow/expect_cache.cc
src/flow/flow_cache.cc
src/flow/flow_key.cc
src/flow/flow_key.h
src/flow/ha.cc
src/flow/test/ha_test.cc
src/hash/CMakeLists.txt
src/hash/dev_notes.txt
src/hash/ghash.cc
src/hash/ghash.h
src/hash/hash_defs.h [new file with mode: 0644]
src/hash/hashfcn.cc
src/hash/hashfcn.h
src/hash/test/ghash_test.cc
src/hash/test/xhash_test.cc
src/hash/xhash.cc
src/hash/xhash.h
src/hash/zhash.cc
src/hash/zhash.h
src/ips_options/ips_flowbits.cc
src/ips_options/ips_session.cc
src/loggers/alert_sf_socket.cc
src/main/policy.h
src/main/snort_config.cc
src/main/snort_config.h
src/managers/inspector_manager.cc
src/mime/file_mime_process.cc
src/network_inspectors/appid/service_state.cc
src/network_inspectors/appid/service_state.h
src/network_inspectors/perf_monitor/flow_ip_tracker.cc
src/network_inspectors/perf_monitor/perf_module.cc
src/network_inspectors/perf_monitor/perf_monitor.cc
src/network_inspectors/port_scan/ps_detect.cc
src/parser/parse_ports.cc
src/parser/parse_rule.cc
src/parser/parser.cc
src/parser/vars.cc
src/ports/port_item.cc
src/ports/port_object.cc
src/ports/port_object2.cc
src/ports/port_object2.h
src/ports/port_table.cc
src/ports/port_utils.cc
src/ports/port_var_table.cc
src/ports/rule_port_tables.cc
src/profiler/rule_profiler.cc
src/service_inspectors/sip/sip_config.cc
src/stream/udp/udp_session.cc
src/utils/sflsq.cc

index af2cbb6fd1936b6d773faf990937dc6270f6be05..a64f0944e8753bec507d7a3ec045e9cd3f5d2188 100644 (file)
@@ -69,9 +69,6 @@ using namespace snort;
 #define HASH_RULE_OPTIONS 16384
 #define HASH_RULE_TREE     8192
 
-#define HASH_EQUAL        0
-#define HASH_NOT_EQUAL    1
-
 struct detection_option_key_t
 {
     option_type_t option_type;
@@ -94,16 +91,15 @@ static uint32_t detection_option_hash_func(HashFnc*, const unsigned char* k, int
     return 0;
 }
 
-static int detection_option_key_compare_func(const void* k1, const void* k2, size_t)
+static bool detection_option_key_compare_func(const void* k1, const void* k2, size_t)
 {
     const detection_option_key_t* key1 = (const detection_option_key_t*)k1;
     const detection_option_key_t* key2 = (const detection_option_key_t*)k2;
 
-    if ( !key1 || !key2 )
-        return HASH_NOT_EQUAL;
+    assert(key1 && key2);
 
     if ( key1->option_type != key2->option_type )
-        return HASH_NOT_EQUAL;
+        return false;
 
     if ( key1->option_type != RULE_OPTION_TYPE_LEAF_NODE )
     {
@@ -111,9 +107,9 @@ static int detection_option_key_compare_func(const void* k1, const void* k2, siz
         IpsOption* opt2 = (IpsOption*)key2->option_data;
 
         if ( *opt1 == *opt2 )
-            return HASH_EQUAL;
+            return true;
     }
-    return HASH_NOT_EQUAL;
+    return false;
 }
 
 static int detection_hash_free_func(void* option_key, void*)
@@ -130,27 +126,17 @@ static int detection_hash_free_func(void* option_key, void*)
 
 static XHash* DetectionHashTableNew()
 {
-    XHash* doht = xhash_new(HASH_RULE_OPTIONS,
-        sizeof(detection_option_key_t),
-        0,                              /* Data size == 0, just store the ptr */
-        0,                              /* Memcap */
-        0,                              /* Auto node recovery */
-        nullptr,                           /* Auto free function */
-        detection_hash_free_func,                           /* User free function */
-        1);                             /* Recycle nodes */
-
-    if (doht == nullptr)
-        FatalError("Failed to create rule detection option hash table");
+    XHash* doht = new XHash(HASH_RULE_OPTIONS, sizeof(detection_option_key_t),
+        0, 0, false,  nullptr, detection_hash_free_func, true);
 
-    xhash_set_keyops(doht, detection_option_hash_func, detection_option_key_compare_func);
+    doht->set_key_opcodes(detection_option_hash_func, detection_option_key_compare_func);
 
     return doht;
 }
 
 void DetectionHashTableFree(XHash* doht)
 {
-    if (doht != nullptr)
-        xhash_delete(doht);
+    delete doht;
 }
 
 void* add_detection_option(SnortConfig* sc, option_type_t type, void* option_data)
@@ -162,10 +148,10 @@ void* add_detection_option(SnortConfig* sc, option_type_t type, void* option_dat
     key.option_type = type;
     key.option_data = option_data;
 
-    if ( void* p = xhash_find(sc->detection_option_hash_table, &key) )
+    if ( void* p = sc->detection_option_hash_table->get_user_data(&key) )
         return p;
 
-    xhash_add(sc->detection_option_hash_table, &key, option_data);
+    sc->detection_option_hash_table->insert(&key, option_data);
     return nullptr;
 }
 
@@ -228,37 +214,31 @@ static uint32_t detection_option_tree_hash_func(HashFnc*, const unsigned char* k
 static bool detection_option_tree_compare(
     const detection_option_tree_node_t* r, const detection_option_tree_node_t* l)
 {
-    if ( !r and !l )
-        return HASH_EQUAL;
-
-    if ( !r or !l )
-        return HASH_NOT_EQUAL;
+    assert(r and l);
 
     if ( r->option_data != l->option_data )
-        return HASH_NOT_EQUAL;
+        return false;
 
     if ( r->num_children != l->num_children )
-        return HASH_NOT_EQUAL;
+        return false;
 
-    for ( int i=0; i<r->num_children; i++ )
+    for ( int i = 0; i < r->num_children; i++ )
     {
         /* Recurse & check the children for equality */
-        int ret = detection_option_tree_compare(r->children[i], l->children[i]);
-
-        if ( ret != HASH_EQUAL )
-            return ret;
+        if ( !detection_option_tree_compare(r->children[i], l->children[i]) )
+            return false;
     }
 
-    return HASH_EQUAL;
+    return true;
 }
 
-static int detection_option_tree_compare_func(const void* k1, const void* k2, size_t)
+static bool detection_option_tree_compare_func(const void* k1, const void* k2, size_t)
 {
     const detection_option_key_t* key_r = (const detection_option_key_t*)k1;
     const detection_option_key_t* key_l = (const detection_option_key_t*)k2;
 
     if ( !key_r or !key_l )
-        return HASH_NOT_EQUAL;
+        return false;
 
     const detection_option_tree_node_t* r = (const detection_option_tree_node_t*)key_r->option_data;
     const detection_option_tree_node_t* l = (const detection_option_tree_node_t*)key_l->option_data;
@@ -275,26 +255,15 @@ static int detection_option_tree_free_func(void*, void* data)
 
 void DetectionTreeHashTableFree(XHash* dtht)
 {
-    if (dtht != nullptr)
-        xhash_delete(dtht);
+    delete dtht;
 }
 
 static XHash* DetectionTreeHashTableNew()
 {
-    XHash* dtht = xhash_new(
-        HASH_RULE_TREE,
-        sizeof(detection_option_key_t),
-        0,      /* Data size == 0, just store the ptr */
-        0,      /* Memcap */
-        0,      /* Auto node recovery */
-        nullptr,   /* Auto free function */
-        detection_option_tree_free_func,   /* User free function */
-        1);     /* Recycle nodes */
-
-    if (dtht == nullptr)
-        FatalError("Failed to create rule detection option hash table");
+    XHash* dtht = new XHash(HASH_RULE_TREE, sizeof(detection_option_key_t),
+        0, 0, false, nullptr, detection_option_tree_free_func, true);
 
-    xhash_set_keyops(dtht, detection_option_tree_hash_func, detection_option_tree_compare_func);
+    dtht->set_key_opcodes(detection_option_tree_hash_func, detection_option_tree_compare_func);
 
     return dtht;
 }
@@ -338,10 +307,10 @@ void* add_detection_option_tree(SnortConfig* sc, detection_option_tree_node_t* o
     key.option_data = (void*)option_tree;
     key.option_type = RULE_OPTION_TYPE_LEAF_NODE;
 
-    if ( void* p = xhash_find(sc->detection_option_tree_hash_table, &key) )
+    if ( void* p = sc->detection_option_tree_hash_table->get_user_data(&key) )
         return p;
 
-    xhash_add(sc->detection_option_tree_hash_table, &key, option_tree);
+    sc->detection_option_tree_hash_table->insert(&key, option_tree);
     return nullptr;
 }
 
@@ -800,7 +769,7 @@ void detection_option_tree_update_otn_stats(XHash* doth)
     if ( !doth )
         return;
 
-    for ( auto hnode = xhash_findfirst(doth); hnode; hnode = xhash_findnext(doth) )
+    for ( auto hnode = doth->find_first_node(); hnode; hnode = doth->find_next_node() )
     {
         auto* node = (detection_option_tree_node_t*)hnode->data;
         assert(node);
index 14a0c66ef1bffca36ea6fe8fe2063a84db0f331e..6f6fdf4a98e4b4256a19a9e3b4b82262149924fb 100644 (file)
@@ -43,7 +43,7 @@ namespace snort
 {
 struct Packet;
 struct SnortConfig;
-struct XHash;
+class XHash;
 }
 struct RuleLatencyState;
 
index d9fc9b6e1d3b38be6f79a75474d1518fc0d85739..9f9fde9f0cb52352b7d153c7faf693547e46c39b 100644 (file)
@@ -413,8 +413,7 @@ static int fpFinishPortGroupRule(
     return 0;
 }
 
-static int fpFinishPortGroup(
-    SnortConfig* sc, PortGroup* pg, FastPatternConfig* fp)
+static int fpFinishPortGroup(SnortConfig* sc, PortGroup* pg, FastPatternConfig* fp)
 {
     int i;
     int rules = 0;
@@ -774,7 +773,7 @@ struct PortIteratorData
     PortGroup* group;
 };
 
-static int fpCreateInitRuleMap(
+static void fpCreateInitRuleMap(
     PORT_RULE_MAP* prm, PortTable* src, PortTable* dst, PortObject* any)
 {
     /* setup the any-port content port group */
@@ -792,9 +791,9 @@ static int fpCreateInitRuleMap(
     /* Process src PORT groups */
     if ( src )
     {
-        for ( GHashNode* node = ghash_findfirst(src->pt_mpxo_hash);
-            node;
-            node=ghash_findnext(src->pt_mpxo_hash) )
+        for (GHashNode* node = src->pt_mpxo_hash->find_first();
+             node;
+             node = src->pt_mpxo_hash->find_next())
         {
             PortObject2* po = (PortObject2*)node->data;
 
@@ -802,7 +801,7 @@ static int fpCreateInitRuleMap(
                 continue;
 
             /* Add up the total src rules */
-            prm->prmNumSrcRules  += po->rule_hash->count;
+            prm->prmNumSrcRules  += po->rule_hash->get_count();
 
             /* Increment the port group count */
             prm->prmNumSrcGroups++;
@@ -816,9 +815,9 @@ static int fpCreateInitRuleMap(
     /* process destination port groups */
     if ( dst )
     {
-        for ( GHashNode* node=ghash_findfirst(dst->pt_mpxo_hash);
-            node;
-            node=ghash_findnext(dst->pt_mpxo_hash) )
+        for (GHashNode* node = dst->pt_mpxo_hash->find_first();
+             node;
+             node = dst->pt_mpxo_hash->find_next())
         {
             PortObject2* po = (PortObject2*)node->data;
 
@@ -826,7 +825,7 @@ static int fpCreateInitRuleMap(
                 continue;
 
             /* Add up the total src rules */
-            prm->prmNumDstRules  += po->rule_hash->count;
+            prm->prmNumDstRules  += po->rule_hash->get_count();
 
             /* Increment the port group count */
             prm->prmNumDstGroups++;
@@ -836,33 +835,22 @@ static int fpCreateInitRuleMap(
             PortObject2Iterate(po, PortIteratorData::set, &pit_data);
         }
     }
-
-    return 0;
 }
 
 /*
  * Create and initialize the rule maps
  */
-static int fpCreateRuleMaps(SnortConfig* sc, RulePortTables* p)
+static void fpCreateRuleMaps(SnortConfig* sc, RulePortTables* p)
 {
     sc->prmIpRTNX = prmNewMap();
     sc->prmIcmpRTNX = prmNewMap();
     sc->prmTcpRTNX = prmNewMap();
     sc->prmUdpRTNX = prmNewMap();
 
-    if (fpCreateInitRuleMap(sc->prmIpRTNX, p->ip.src, p->ip.dst, p->ip.any))
-        return -1;
-
-    if (fpCreateInitRuleMap(sc->prmIcmpRTNX, p->icmp.src, p->icmp.dst, p->icmp.any))
-        return -1;
-
-    if (fpCreateInitRuleMap(sc->prmTcpRTNX, p->tcp.src, p->tcp.dst, p->tcp.any))
-        return -1;
-
-    if (fpCreateInitRuleMap(sc->prmUdpRTNX, p->udp.src, p->udp.dst, p->udp.any))
-        return -1;
-
-    return 0;
+    fpCreateInitRuleMap(sc->prmIpRTNX, p->ip.src, p->ip.dst, p->ip.any);
+    fpCreateInitRuleMap(sc->prmIcmpRTNX, p->icmp.src, p->icmp.dst, p->icmp.any);
+    fpCreateInitRuleMap(sc->prmTcpRTNX, p->tcp.src, p->tcp.dst, p->tcp.any);
+    fpCreateInitRuleMap(sc->prmUdpRTNX, p->udp.src, p->udp.dst, p->udp.any);
 }
 
 static void fpFreeRuleMaps(SnortConfig* sc)
@@ -1018,31 +1006,21 @@ static void fpDeletePMX(void* pv)
  *  content and uricontent based on the rules in the PortObjects
  *  hash table.
  */
-static int fpCreatePortObject2PortGroup(
-    SnortConfig* sc, PortObject2* po, PortObject2* poaa)
+static void fpCreatePortObject2PortGroup(SnortConfig* sc, PortObject2* po, PortObject2* poaa)
 {
-    GHashNode* node;
-    unsigned sid, gid;
-    OptTreeNode* otn;
-    PortGroup* pg;
-    PortObject2* pox;
-    FastPatternConfig* fp = sc->fast_pattern_config;
-
-    /* verify we have a port object */
-    if (po == nullptr)
-        return 0;
+    assert( po );
 
     po->group = nullptr;
-
-    if (fp->get_debug_print_rule_group_build_details())
+    FastPatternConfig* fp = sc->fast_pattern_config;
+    if ( fp->get_debug_print_rule_group_build_details() )
         PortObject2PrintPorts(po);
 
     /* Check if we have any rules */
-    if (po->rule_hash == nullptr)
-        return 0;
+    if ( !po->rule_hash )
+        return;
 
     /* create a port_group */
-    pg = PortGroup::alloc();
+    PortGroup* pg = PortGroup::alloc();
     s_group = "port";
 
     /*
@@ -1060,14 +1038,14 @@ static int fpCreatePortObject2PortGroup(
      * (src/dst or any-any ports)
      *
      */
-    pox = po;
-
-    while (pox != nullptr)
+    PortObject2* pox = po;
+    while ( pox )
     {
-        for (node = ghash_findfirst(pox->rule_hash);
-            node;
-            node = ghash_findnext(pox->rule_hash))
+        for (GHashNode* node = pox->rule_hash->find_first();
+             node;
+             node = pox->rule_hash->find_next())
         {
+            unsigned sid, gid;
             int* prindex = (int*)node->data;
 
             /* be safe - no rule index, ignore it */
@@ -1078,7 +1056,7 @@ static int fpCreatePortObject2PortGroup(
             parser_get_rule_ids(*prindex, gid, sid);
 
             /* look up otn */
-            otn = OtnLookup(sc->otn_map, gid, sid);
+            OptTreeNode* otn = OtnLookup(sc->otn_map, gid, sid);
             assert(otn);
 
             if ( is_network_protocol(otn->snort_protocol_id) )
@@ -1094,53 +1072,42 @@ static int fpCreatePortObject2PortGroup(
         pox = poaa;
     }
 
-    /* This might happen if there was ip proto only rules
-     * Don't return failure */
+    // This might happen if there was ip proto only rules...Don't return failure
     if (fpFinishPortGroup(sc, pg, fp) != 0)
-        return 0;
+        return;
 
     po->group = pg;
-    return 0;
+    return;
 }
 
 /*
  *  Create the port groups for this port table
  */
-static int fpCreatePortTablePortGroups(
-    SnortConfig* sc, PortTable* p, PortObject2* poaa)
+static void fpCreatePortTablePortGroups(SnortConfig* sc, PortTable* p, PortObject2* poaa)
 {
-    GHashNode* node;
-    int cnt=1;
+    int cnt = 1;
     FastPatternConfig* fp = sc->fast_pattern_config;
+    if ( fp->get_debug_print_rule_group_build_details() )
+        LogMessage("%d Port Groups in Port Table\n",p->pt_mpo_hash->get_count());
 
-    if (fp->get_debug_print_rule_group_build_details())
-        LogMessage("%d Port Groups in Port Table\n",p->pt_mpo_hash->count);
-
-    for (node=ghash_findfirst(p->pt_mpo_hash);
-        node;
-        node=ghash_findnext(p->pt_mpo_hash) )
+    for (GHashNode* node = p->pt_mpo_hash->find_first();
+         node;
+         node = p->pt_mpo_hash->find_next())
     {
         PortObject2* po = (PortObject2*)node->data;
-
         if ( !po )
             continue;
 
         if (fp->get_debug_print_rule_group_build_details())
-            LogMessage("Creating Port Group Object %d of %d\n",cnt++,p->pt_mpo_hash->count);
+            LogMessage("Creating Port Group Object %d of %d\n", cnt++, p->pt_mpo_hash->get_count());
 
         /* if the object is not referenced, don't add it to the PortGroups
          * as it may overwrite other objects that are more inclusive. */
-        if (!po->port_cnt)
+        if ( !po->port_cnt )
             continue;
 
-        if (fpCreatePortObject2PortGroup(sc, po, poaa))
-        {
-            LogMessage("fpCreatePortObject2PortGroup() failed\n");
-            return -1;
-        }
+        fpCreatePortObject2PortGroup(sc, po, poaa);
     }
-
-    return 0;
 }
 
 /*
@@ -1151,172 +1118,106 @@ static int fpCreatePortTablePortGroups(
  */
 static int fpCreatePortGroups(SnortConfig* sc, RulePortTables* p)
 {
-    PortObject2* po2, * add_any_any;
-    FastPatternConfig* fp = sc->fast_pattern_config;
-
     if (!get_rule_count())
         return 0;
 
-    /* IP */
-    if ( !(po2 = PortObject2Dup(p->ip.any)) )
-        FatalError("Could not create a PortObject2 for ip-any rules\n");
+    FastPatternConfig* fp = sc->fast_pattern_config;
+    bool log_rule_group_details = fp->get_debug_print_rule_group_build_details();
 
-    add_any_any = fp->get_split_any_any() ? nullptr : po2;
+    /* IP */
+    PortObject2* po2 = PortObject2Dup(*p->ip.any);
+    PortObject2* add_any_any = fp->get_split_any_any() ? nullptr : po2;
 
-    if (fp->get_debug_print_rule_group_build_details())
+    if ( log_rule_group_details )
         LogMessage("\nIP-SRC ");
 
-    if (fpCreatePortTablePortGroups(sc, p->ip.src, add_any_any))
-    {
-        LogMessage("fpCreatePorTablePortGroups failed-ip.src\n");
-        return -1;
-    }
+    fpCreatePortTablePortGroups(sc, p->ip.src, add_any_any);
 
-    if (fp->get_debug_print_rule_group_build_details())
+    if ( log_rule_group_details )
         LogMessage("\nIP-DST ");
 
-    if (fpCreatePortTablePortGroups(sc, p->ip.dst, add_any_any))
-    {
-        LogMessage("fpCreatePorTablePortGroups failed-ip.dst\n");
-        return -1;
-    }
+    fpCreatePortTablePortGroups(sc, p->ip.dst, add_any_any);
 
-    if (fp->get_debug_print_rule_group_build_details())
+    if ( log_rule_group_details )
         LogMessage("\nIP-ANY ");
 
-    if (fpCreatePortObject2PortGroup(sc, po2, nullptr))
-    {
-        LogMessage("fpCreatePorTablePortGroups failed-ip any\n");
-        return -1;
-    }
-
+    fpCreatePortObject2PortGroup(sc, po2, nullptr);
     p->ip.any->group = po2->group;
     po2->group = nullptr;
     PortObject2Free(po2);
 
     /* ICMP */
-    if ( !(po2 = PortObject2Dup(p->icmp.any)) )
-        FatalError("Could not create a PortObject2 for icmp-any rules\n");
-
+    po2 = PortObject2Dup(*p->icmp.any);
     add_any_any = fp->get_split_any_any() ? nullptr : po2;
 
-    if (fp->get_debug_print_rule_group_build_details())
+    if ( log_rule_group_details )
         LogMessage("\nICMP-SRC ");
 
-    if (fpCreatePortTablePortGroups(sc, p->icmp.src, add_any_any))
-    {
-        LogMessage("fpCreatePorTablePortGroups failed-icmp.src\n");
-        return -1;
-    }
+    fpCreatePortTablePortGroups(sc, p->icmp.src, add_any_any);
 
-    if (fp->get_debug_print_rule_group_build_details())
+    if ( log_rule_group_details )
         LogMessage("\nICMP-DST ");
 
-    if (fpCreatePortTablePortGroups(sc, p->icmp.dst, add_any_any))
-    {
-        LogMessage("fpCreatePorTablePortGroups failed-icmp.src\n");
-        return -1;
-    }
+    fpCreatePortTablePortGroups(sc, p->icmp.dst, add_any_any);
 
-    if (fp->get_debug_print_rule_group_build_details())
+    if ( log_rule_group_details )
         LogMessage("\nICMP-ANY ");
 
-    if (fpCreatePortObject2PortGroup(sc, po2, nullptr))
-    {
-        LogMessage("fpCreatePorTablePortGroups failed-icmp any\n");
-        return -1;
-    }
-
+    fpCreatePortObject2PortGroup(sc, po2, nullptr);
     p->icmp.any->group = po2->group;
     po2->group = nullptr;
     PortObject2Free(po2);
 
-    if ( !(po2 = PortObject2Dup(p->tcp.any)) )
-        FatalError("Could not create a PortObject2 for tcp-any rules\n");
-
+    po2 = PortObject2Dup(*p->tcp.any);
     add_any_any = fp->get_split_any_any() ? nullptr : po2;
 
-    if (fp->get_debug_print_rule_group_build_details())
+    if ( log_rule_group_details )
         LogMessage("\nTCP-SRC ");
 
-    if (fpCreatePortTablePortGroups(sc, p->tcp.src, add_any_any))
-    {
-        LogMessage("fpCreatePorTablePortGroups failed-tcp.src\n");
-        return -1;
-    }
+    fpCreatePortTablePortGroups(sc, p->tcp.src, add_any_any);
 
-    if (fp->get_debug_print_rule_group_build_details())
+    if ( log_rule_group_details )
         LogMessage("\nTCP-DST ");
 
-    if (fpCreatePortTablePortGroups(sc, p->tcp.dst, add_any_any))
-    {
-        LogMessage("fpCreatePorTablePortGroups failed-tcp.dst\n");
-        return -1;
-    }
+    fpCreatePortTablePortGroups(sc, p->tcp.dst, add_any_any);
 
-    if (fp->get_debug_print_rule_group_build_details())
+    if ( log_rule_group_details )
         LogMessage("\nTCP-ANY ");
 
-    if (fpCreatePortObject2PortGroup(sc, po2, nullptr))
-    {
-        LogMessage("fpCreatePorTablePortGroups failed-tcp any\n");
-        return -1;
-    }
-
+    fpCreatePortObject2PortGroup(sc, po2, nullptr);
     p->tcp.any->group = po2->group;
     po2->group = nullptr;
     PortObject2Free(po2);
 
     /* UDP */
-    if ( !(po2 = PortObject2Dup(p->udp.any)) )
-        FatalError("Could not create a PortObject2 for udp-any rules\n");
-
+    po2 = PortObject2Dup(*p->udp.any);
     add_any_any = fp->get_split_any_any() ? nullptr : po2;
 
-    if (fp->get_debug_print_rule_group_build_details())
+    if ( log_rule_group_details )
         LogMessage("\nUDP-SRC ");
 
-    if (fpCreatePortTablePortGroups(sc, p->udp.src, add_any_any))
-    {
-        LogMessage("fpCreatePorTablePortGroups failed-udp.src\n");
-        return -1;
-    }
+    fpCreatePortTablePortGroups(sc, p->udp.src, add_any_any);
 
-    if (fp->get_debug_print_rule_group_build_details())
+    if ( log_rule_group_details )
         LogMessage("\nUDP-DST ");
 
-    if (fpCreatePortTablePortGroups(sc, p->udp.dst, add_any_any))
-    {
-        LogMessage("fpCreatePorTablePortGroups failed-udp.dst\n");
-        return -1;
-    }
+    fpCreatePortTablePortGroups(sc, p->udp.dst, add_any_any);
 
-    if (fp->get_debug_print_rule_group_build_details())
+    if ( log_rule_group_details )
         LogMessage("\nUDP-ANY ");
 
-    if (fpCreatePortObject2PortGroup(sc, po2, nullptr))
-    {
-        LogMessage("fpCreatePorTablePortGroups failed-udp.any\n");
-        return -1;
-    }
-
+    fpCreatePortObject2PortGroup(sc, po2, nullptr);
     p->udp.any->group = po2->group;
     po2->group = nullptr;
     PortObject2Free(po2);
 
     /* SVC */
-    if ( !(po2 = PortObject2Dup(p->svc_any)) )
-        FatalError("Could not create a PortObject2 for svc-any rules\n");
+    po2 = PortObject2Dup(*p->svc_any);
 
-    if (fp->get_debug_print_rule_group_build_details())
+    if ( log_rule_group_details )
         LogMessage("\nSVC-ANY ");
 
-    if (fpCreatePortObject2PortGroup(sc, po2, nullptr))
-    {
-        LogMessage("fpCreatePorTablePortGroups failed-svc_any\n");
-        return -1;
-    }
-
+    fpCreatePortObject2PortGroup(sc, po2, nullptr);
     p->svc_any->group = po2->group;
     po2->group = nullptr;
     PortObject2Free(po2);
@@ -1345,9 +1246,9 @@ static void fpBuildServicePortGroupByServiceOtnList(
      */
     SF_LNODE* cursor;
 
-    for ( OptTreeNode* otn = (OptTreeNode*)sflist_first(list, &cursor);
-        otn;
-        otn = (OptTreeNode*)sflist_next(&cursor) )
+    for (OptTreeNode* otn = (OptTreeNode*)sflist_first(list, &cursor);
+         otn;
+         otn = (OptTreeNode*)sflist_next(&cursor) )
     {
         fpAddPortGroupRule(sc, pg, otn, fp, true);
     }
@@ -1356,7 +1257,7 @@ static void fpBuildServicePortGroupByServiceOtnList(
         return;
 
     /* Add the port_group using it's service name */
-    ghash_add(p, srvc, pg);
+    p->insert(srvc, pg);
 }
 
 /*
@@ -1375,9 +1276,7 @@ static void fpBuildServicePortGroupByServiceOtnList(
 static void fpBuildServicePortGroups(
     SnortConfig* sc, GHash* spg, PortGroupVector& sopg, GHash* srm, FastPatternConfig* fp)
 {
-    for ( GHashNode* n = ghash_findfirst(srm);
-        n;
-        n=ghash_findnext(srm) )
+    for (GHashNode* n = srm->find_first(); n; n = srm->find_next())
     {
         SF_LIST* list = (SF_LIST*)n->data;
         const char* srvc = (const char*)n->key;
@@ -1387,7 +1286,7 @@ static void fpBuildServicePortGroups(
         fpBuildServicePortGroupByServiceOtnList(sc, spg, srvc, list, fp);
 
         /* Add this PortGroup to the protocol-ordinal -> port_group table */
-        PortGroup* pg = (PortGroup*)ghash_find(spg, srvc);
+        PortGroup* pg = (PortGroup*)spg->find(srvc);
         if ( !pg )
         {
             ParseError("*** failed to create and find a port group for '%s'",srvc);
@@ -1441,16 +1340,14 @@ static void fpPrintServiceRuleMapTable(GHash* p, const char* dir)
 {
     GHashNode* n;
 
-    if ( !p || !p->count )
+    if ( !p || !p->get_count() )
         return;
 
     std::string label = "service rule counts - ";
     label += dir;
     LogLabel(label.c_str());
 
-    for ( n = ghash_findfirst(p);
-        n;
-        n = ghash_findnext(p) )
+    for (n = p->find_first(); n; n = p->find_next())
     {
         SF_LIST* list;
 
@@ -1475,7 +1372,7 @@ static void fpPrintServiceRuleMaps(SnortConfig* sc)
 
 static void fp_print_service_rules(SnortConfig* sc, GHash* cli, GHash* srv)
 {
-    if ( !cli->count and !srv->count )
+    if ( !cli->get_count() and !srv->get_count() )
         return;
 
     LogLabel("service rule counts          to-srv  to-cli");
@@ -1485,8 +1382,8 @@ static void fp_print_service_rules(SnortConfig* sc, GHash* cli, GHash* srv)
 
     while ( const char* svc = sc->proto_ref->get_name_sorted(idx++) )
     {
-        SF_LIST* clist = (SF_LIST*)ghash_find(cli, svc);
-        SF_LIST* slist = (SF_LIST*)ghash_find(srv, svc);
+        SF_LIST* clist = (SF_LIST*)cli->find(svc);
+        SF_LIST* slist = (SF_LIST*)srv->find(svc);
 
         if ( !clist and !slist )
             continue;
@@ -1521,8 +1418,9 @@ static void fp_sum_port_groups(PortGroup* pg, unsigned c[PM_TYPE_MAX])
 
 static void fp_sum_service_groups(GHash* h, unsigned c[PM_TYPE_MAX])
 {
-    for ( GHashNode* node=ghash_findfirst(h);
-        node; node=ghash_findnext(h) )
+    for (GHashNode* node = h->find_first();
+         node;
+         node = h->find_next())
     {
         PortGroup* pg = (PortGroup*)node->data;
         fp_sum_port_groups(pg, c);
@@ -1555,8 +1453,9 @@ static void fp_print_service_groups(srmm_table_t* srmm)
 
 static void fp_sum_port_groups(PortTable* tab, unsigned c[PM_TYPE_MAX])
 {
-    for ( GHashNode* node=ghash_findfirst(tab->pt_mpxo_hash);
-        node; node=ghash_findnext(tab->pt_mpxo_hash) )
+    for (GHashNode* node = tab->pt_mpxo_hash->find_first();
+         node;
+         node = tab->pt_mpxo_hash->find_next())
     {
         PortObject2* po = (PortObject2*)node->data;
         fp_sum_port_groups(po->group, c);
@@ -1619,15 +1518,13 @@ static void fp_print_port_groups(RulePortTables* port_tables)
  *  Build Service based PortGroups using the rules
  *  metadata option service parameter.
  */
-static int fpCreateServicePortGroups(SnortConfig* sc)
+static void fpCreateServicePortGroups(SnortConfig* sc)
 {
     FastPatternConfig* fp = sc->fast_pattern_config;
 
     sc->srmmTable = ServiceMapNew();
 
-    if (fpCreateServiceMaps(sc))
-        return -1;
-
+    fpCreateServiceMaps(sc);
     fp_print_service_rules_by_proto(sc);
 
     if ( fp->get_debug_print_rule_group_build_details() )
@@ -1640,7 +1537,6 @@ static int fpCreateServicePortGroups(SnortConfig* sc)
 
     ServiceMapFree(sc->srmmTable);
     sc->srmmTable = nullptr;
-    return 0;
 }
 
 static unsigned can_build_mt(FastPatternConfig* fp)
@@ -1676,6 +1572,7 @@ int fpCreateFastPacketDetection(SnortConfig* sc)
 
     RulePortTables* port_tables = sc->port_tables;
     FastPatternConfig* fp = sc->fast_pattern_config;
+    bool log_rule_group_details = fp->get_debug_print_rule_group_build_details();
 
     assert(port_tables);
     assert(fp);
@@ -1692,37 +1589,34 @@ int fpCreateFastPacketDetection(SnortConfig* sc)
     MpseManager::start_search_engine(fp->get_search_api());
 
     /* Use PortObjects to create PortGroups */
-    if (fp->get_debug_print_rule_group_build_details())
+    if ( log_rule_group_details )
         LogMessage("Creating Port Groups....\n");
 
-    if (fpCreatePortGroups(sc, port_tables))
-        FatalError("Could not create PortGroup objects for PortObjects\n");
+    fpCreatePortGroups(sc, port_tables);
 
-    if (fp->get_debug_print_rule_group_build_details())
+    if ( log_rule_group_details )
+    {
         LogMessage("Port Groups Done....\n");
-
-    /* Create rule_maps */
-    if (fp->get_debug_print_rule_group_build_details())
         LogMessage("Creating Rule Maps....\n");
+    }
 
-    if (fpCreateRuleMaps(sc, port_tables))
-        FatalError("Could not create rule maps\n");
+    /* Create rule_maps */
+    fpCreateRuleMaps(sc, port_tables);
 
-    if (fp->get_debug_print_rule_group_build_details())
+    if ( log_rule_group_details )
+    {
         LogMessage("Rule Maps Done....\n");
-
-    if (fp->get_debug_print_rule_group_build_details())
         LogMessage("Creating Service Based Rule Maps....\n");
+    }
 
     /* Build Service based port groups - rules require service metdata
      * i.e. 'metatdata: service [=] service-name, ... ;'
      *
      * Also requires a service attribute for lookup ...
      */
-    if (fpCreateServicePortGroups(sc))
-        FatalError("Could not create service based port groups\n");
+    fpCreateServicePortGroups(sc);
 
-    if (fp->get_debug_print_rule_group_build_details())
+    if ( log_rule_group_details )
         LogMessage("Service Based Rule Maps Done....\n");
 
     if ( !sc->test_mode() or sc->mem_check() )
@@ -1742,6 +1636,7 @@ int fpCreateFastPacketDetection(SnortConfig* sc)
         LogLabel("search engine");
         MpseManager::print_mpse_summary(fp->get_search_api());
     }
+
     if ( offload_mpse_count and (fp->get_offload_search_api()))
     {
         LogLabel("offload search engine");
index 30cf8cba558e8aab36194ff477fbce771b36d782..05cd9bf62e7bcaa6fcfb1953ab0464a71aee2b54 100644 (file)
@@ -95,7 +95,7 @@ static void fp_immediate(MpseGroup*, Packet*, const uint8_t*, unsigned);
 
 static inline void init_match_info(OtnxMatchData* omd)
 {
-    for ( int i = 0; i < SnortConfig::get_conf()->num_rule_types; i++ )
+    for ( unsigned i = 0; i < SnortConfig::get_conf()->num_rule_types; i++ )
         omd->matchInfo[i].iMatchCount = 0;
 
     omd->have_match = false;
@@ -212,7 +212,7 @@ int fpLogEvent(const RuleTreeNode* rtn, const OptTreeNode* otn, Packet* p)
      * If its order is lower than 'pass', it should have been passed.
      * This is consistent with other detection rules */
     if ( (p->packet_flags & PKT_PASS_RULE)
-        &&(SnortConfig::get_eval_index(rtn->action) > SnortConfig::get_eval_index(Actions::PASS)))
+        && (SnortConfig::get_eval_index(rtn->action) > SnortConfig::get_eval_index(Actions::PASS)) )
     {
         fpLogOther(p, rtn, otn, rtn->action);
         return 1;
@@ -252,7 +252,7 @@ int fpLogEvent(const RuleTreeNode* rtn, const OptTreeNode* otn, Packet* p)
 int fpAddMatch(OtnxMatchData* omd, const OptTreeNode* otn)
 {
     RuleTreeNode* rtn = getRuntimeRtnFromOtn(otn);
-    int evalIndex = rtn->listhead->ruleListNode->evalIndex;
+    unsigned evalIndex = rtn->listhead->ruleListNode->evalIndex;
 
     /* bounds check index */
     if ( evalIndex >= SnortConfig::get_conf()->num_rule_types )
@@ -266,7 +266,7 @@ int fpAddMatch(OtnxMatchData* omd, const OptTreeNode* otn)
     **  If we hit the max number of unique events for any rule type alert,
     **  log or pass, then we don't add it to the list.
     */
-    if ( pmi->iMatchCount >= (int)SnortConfig::get_conf()->fast_pattern_config->get_max_queue_events() ||
+    if ( pmi->iMatchCount >= SnortConfig::get_conf()->fast_pattern_config->get_max_queue_events() ||
         pmi->iMatchCount >= MAX_EVENT_MATCH)
     {
         pc.match_limit++;
@@ -274,15 +274,14 @@ int fpAddMatch(OtnxMatchData* omd, const OptTreeNode* otn)
     }
 
     // don't store the same otn again
-    for ( int i=0; i< pmi->iMatchCount; i++ )
+    for ( unsigned i = 0; i < pmi->iMatchCount; i++ )
     {
-        if ( pmi->MatchArray[ i  ] == otn )
+        if ( pmi->MatchArray[i] == otn )
             return 0;
     }
 
     //  add the event to the appropriate list
     pmi->MatchArray[ pmi->iMatchCount ] = otn;
-
     pmi->iMatchCount++;
     omd->have_match = true;
     return 0;
@@ -617,22 +616,20 @@ static inline int fpFinalSelectEvent(OtnxMatchData* omd, Packet* p)
     if ( !omd->have_match )
         return 0;
 
-    int i;
-    int j;
-    int k;
-    const OptTreeNode* otn;
     unsigned tcnt = 0;
     EventQueueConfig* eq = SnortConfig::get_conf()->event_queue_config;
-    RuleTreeNode* rtn;
+    int (*compar)(const void *, const void *);
+    compar = ( eq->order == SNORT_EVENTQ_PRIORITY )
+        ? &sortOrderByPriority : sortOrderByContentLength;
 
-    for ( i = 0; i < SnortConfig::get_conf()->num_rule_types; i++ )
+    for ( unsigned i = 0; i < SnortConfig::get_conf()->num_rule_types; i++ )
     {
         /* bail if were not dumping events in all the action groups,
          * and we've already got some events */
         if (!SnortConfig::process_all_events() && (tcnt > 0))
             return 1;
 
-        if (omd->matchInfo[i].iMatchCount)
+        if ( omd->matchInfo[i].iMatchCount )
         {
             /*
              * We must always sort so if we que 8 and log 3 and they are
@@ -646,28 +643,16 @@ static inline int fpFinalSelectEvent(OtnxMatchData* omd, Packet* p)
              * part of the natural ordering....Jan '06..
              */
             /* Sort the rules in this action group */
-            if (eq->order == SNORT_EVENTQ_PRIORITY)
-            {
-                qsort(omd->matchInfo[i].MatchArray, omd->matchInfo[i].iMatchCount,
-                    sizeof(void*), sortOrderByPriority);
-            }
-            else if (eq->order == SNORT_EVENTQ_CONTENT_LEN)
-            {
-                qsort(omd->matchInfo[i].MatchArray, omd->matchInfo[i].iMatchCount,
-                    sizeof(void*), sortOrderByContentLength);
-            }
-            else
-            {
-                FatalError("fpdetect: Order function for event queue is invalid.\n");
-            }
+            qsort(omd->matchInfo[i].MatchArray, omd->matchInfo[i].iMatchCount,
+                sizeof(void*), compar);
 
             /* Process each event in the action (alert,drop,log,...) groups */
-            for (j=0; j < omd->matchInfo[i].iMatchCount; j++)
+            for (unsigned j = 0; j < omd->matchInfo[i].iMatchCount; j++)
             {
-                otn = omd->matchInfo[i].MatchArray[j];
-                rtn = getRtnFromOtn(otn);
+                const OptTreeNode* otn = omd->matchInfo[i].MatchArray[j];
+                RuleTreeNode* rtn = getRtnFromOtn(otn);
 
-                if (otn && rtn && Actions::is_pass(rtn->action))
+                if ( otn && rtn && Actions::is_pass(rtn->action) )
                 {
                     /* Already acted on rules, so just don't act on anymore */
                     if ( tcnt > 0 )
@@ -675,9 +660,9 @@ static inline int fpFinalSelectEvent(OtnxMatchData* omd, Packet* p)
                 }
 
                 //  Loop here so we don't log the same event multiple times.
-                for (k = 0; k < j; k++)
+                for (unsigned k = 0; k < j; k++)
                 {
-                    if (omd->matchInfo[i].MatchArray[k] == otn)
+                    if ( omd->matchInfo[i].MatchArray[k] == otn )
                     {
                         otn = nullptr;
                         break;
@@ -695,20 +680,20 @@ static inline int fpFinalSelectEvent(OtnxMatchData* omd, Packet* p)
                     pc.alert_limit++;
 
                 /* Only count it if we're going to log it */
-                if (tcnt <= eq->log_events)
+                if ( tcnt <= eq->log_events )
                 {
                     if ( p->flow )
                         fpAddSessionAlert(p, otn);
                 }
 
-                if (tcnt >= eq->max_events)
+                if ( tcnt >= eq->max_events )
                 {
                     pc.queue_limit++;
                     return 1;
                 }
 
                 /* only log/count one pass */
-                if ( otn && rtn && Actions::is_pass(rtn->action))
+                if ( otn && rtn && Actions::is_pass(rtn->action) )
                 {
                     p->packet_flags |= PKT_PASS_RULE;
                     return 1;
@@ -733,10 +718,8 @@ class MpseStash
 {
 public:
     MpseStash(unsigned limit)
-    {
-        enable = false;
-        max = limit;
-    }
+        : max(limit)
+    { }
 
     void init()
     {
@@ -757,8 +740,8 @@ public:
     { enable = true; }
 
 private:
-    bool enable;
-    unsigned count;
+    bool enable = false;
+    unsigned count = 0;
     unsigned max;
     std::vector<Node> queue;
 
index e567465a3b95748952d352db2c469045ababbb60..4efde0dc3f531cd1a9498f13b6b3d962d2691db6 100644 (file)
@@ -70,9 +70,9 @@ int fp_eval_option(void*, Cursor&, snort::Packet*);
 struct MatchInfo
 {
     const OptTreeNode* MatchArray[MAX_EVENT_MATCH];
-    int iMatchCount;
-    int iMatchIndex;
-    int iMatchMaxLen;
+    unsigned iMatchCount;
+    unsigned iMatchIndex;
+    unsigned iMatchMaxLen;
 };
 
 /*
index 37998b2316395443f6fac4a7a8609c0c6af586f0..4d2088b68de0d75cb28a3f6f1251e61153324cd9 100644 (file)
@@ -46,8 +46,7 @@ using namespace snort;
 
 PORT_RULE_MAP* prmNewMap()
 {
-    PORT_RULE_MAP* p = (PORT_RULE_MAP*)snort_calloc(sizeof(PORT_RULE_MAP));
-    return p;
+    return (PORT_RULE_MAP*)snort_calloc(sizeof(PORT_RULE_MAP));
 }
 
 /*
index 7b97b7684119cea855d44cecc7bcae2704f9b240..c6659567a0f8a0fc62a6066962eb717a6afbb749 100644 (file)
@@ -65,7 +65,7 @@ struct RuleListNode
 {
     ListHead* RuleList;   /* The rule list associated with this node */
     snort::Actions::Type mode;        /* the rule mode */
-    int evalIndex;        /* eval index for this rule set */
+    unsigned evalIndex;        /* eval index for this rule set */
     char* name;           /* name of this rule list */
     RuleListNode* next;   /* the next RuleListNode */
 };
index ce2eec53db97ef3f97196f9c4385fe61de0e144e..65eedc998aa3f5c5e49aae3b123676835b9c8c05 100644 (file)
@@ -57,14 +57,13 @@ using namespace snort;
 static GHash* alloc_srvmap()
 {
     // nodes are lists,free them in ghash_delete
-    GHash* p = ghash_new(1000, 0, 0, (void (*)(void*))sflist_free);
-    return p;
+    return new GHash(1000, 0, 0, (void (*)(void*))sflist_free);
 }
 
 static void free_srvmap(GHash* table)
 {
     if ( table )
-        ghash_delete(table);
+        delete table;
 }
 
 srmm_table_t* ServiceMapNew()
@@ -98,8 +97,7 @@ static void delete_pg(void* pv)
 static GHash* alloc_spgmm()
 {
     // 1000 rows, ascii key
-    GHash* p = ghash_new(1000, 0, 0, delete_pg);
-    return p;
+    return new GHash(1000, 0, 0, delete_pg);
 }
 
 static void free_spgmm(GHash* table)
@@ -107,7 +105,7 @@ static void free_spgmm(GHash* table)
     if ( !table )
         return;
 
-    ghash_delete(table);
+    delete table;
 }
 
 srmm_table_t* ServicePortGroupMapNew()
@@ -145,12 +143,12 @@ void ServicePortGroupMapFree(srmm_table_t* table)
  */
 static void ServiceMapAddOtnRaw(GHash* table, const char* servicename, OptTreeNode* otn)
 {
-    SF_LIST* list = (SF_LIST*)ghash_find(table, servicename);
+    SF_LIST* list = (SF_LIST*)table->find(servicename);
 
     if ( !list )
     {
         list = sflist_new();
-        ghash_add(table, servicename, list);
+        table->insert(servicename, list);
     }
 
     sflist_add_tail(list, otn);
@@ -161,7 +159,7 @@ static void ServiceMapAddOtnRaw(GHash* table, const char* servicename, OptTreeNo
  *  each service map maintains a list of otn's for each service it maps to a
  *  service name.
  */
-static int ServiceMapAddOtn(
+static void ServiceMapAddOtn(
     srmm_table_t* srmm, SnortProtocolId, const char* servicename, OptTreeNode* otn)
 {
     assert(servicename and otn);
@@ -171,8 +169,6 @@ static int ServiceMapAddOtn(
 
     if ( !OtnFlowFromServer(otn) )
         ServiceMapAddOtnRaw(srmm->to_srv, servicename, otn);
-
-    return 0;
 }
 
 void fpPrintServicePortGroupSummary(SnortConfig* sc)
@@ -181,10 +177,10 @@ void fpPrintServicePortGroupSummary(SnortConfig* sc)
     LogMessage("| Service-PortGroup Table Summary \n");
     LogMessage("---------------------------------\n");
 
-    if ( unsigned n = sc->spgmmTable->to_srv->count )
+    if ( unsigned n = sc->spgmmTable->to_srv->get_count() )
         LogMessage("| server   : %d services\n", n);
 
-    if ( unsigned n = sc->spgmmTable->to_cli->count )
+    if ( unsigned n = sc->spgmmTable->to_cli->get_count() )
         LogMessage("| client   : %d services\n", n);
 
     LogMessage("---------------------------------\n");
@@ -194,24 +190,18 @@ void fpPrintServicePortGroupSummary(SnortConfig* sc)
  *  Scan the master otn lists and load the Service maps
  *  for service based rule grouping.
  */
-int fpCreateServiceMaps(SnortConfig* sc)
+void fpCreateServiceMaps(SnortConfig* sc)
 {
-    RuleTreeNode* rtn;
-    GHashNode* hashNode;
-    OptTreeNode* otn  = nullptr;
-    unsigned int svc_idx;
-
-    for (hashNode = ghash_findfirst(sc->otn_map);
-        hashNode;
-        hashNode = ghash_findnext(sc->otn_map))
+    for (GHashNode* hashNode = sc->otn_map->find_first();
+         hashNode;
+         hashNode = sc->otn_map->find_next())
     {
-        otn = (OptTreeNode*)hashNode->data;
-        for ( PolicyId policyId = 0;
-            policyId < otn->proto_node_num;
-            policyId++ )
+        OptTreeNode* otn = (OptTreeNode*)hashNode->data;
+        for (PolicyId policyId = 0;
+             policyId < otn->proto_node_num;
+             policyId++ )
         {
-            rtn = getRtnFromOtn(otn, policyId);
-
+            RuleTreeNode* rtn = getRtnFromOtn(otn, policyId);
             if ( rtn )
             {
                 // skip builtin rules
@@ -222,18 +212,14 @@ int fpCreateServiceMaps(SnortConfig* sc)
                 if ( !rtn->enabled() )
                     continue;
 
-                for (svc_idx = 0; svc_idx < otn->sigInfo.num_services; svc_idx++)
+                for (unsigned svc_idx = 0; svc_idx < otn->sigInfo.num_services; svc_idx++)
                 {
                     const char* svc = otn->sigInfo.services[svc_idx].service;
-
-                    if ( ServiceMapAddOtn(sc->srmmTable, rtn->snort_protocol_id, svc, otn) )
-                        return -1;
+                    ServiceMapAddOtn(sc->srmmTable, rtn->snort_protocol_id, svc, otn);
                 }
             }
         }
     }
-
-    return 0;
 }
 
 //-------------------------------------------------------------------------
index 92f9d6a4f347a102b0ebe6d68d706f23b95d1095..e1f1da18f3ad604a9e7083f1d74fc023506ab9a1 100644 (file)
@@ -35,7 +35,7 @@
 namespace snort
 {
 struct SnortConfig;
-struct GHash;
+class GHash;
 }
 struct PortGroup;
 
@@ -53,7 +53,7 @@ srmm_table_t* ServicePortGroupMapNew();
 void ServicePortGroupMapFree(srmm_table_t*);
 
 void fpPrintServicePortGroupSummary(snort::SnortConfig*);
-int fpCreateServiceMaps(snort::SnortConfig*);
+void fpCreateServiceMaps(snort::SnortConfig*);
 
 //  Service/Protocol Ordinal To PortGroup table
 typedef std::vector<PortGroup*> PortGroupVector;
index 90b40b4733e747d24603bcef929fff0c3b441c59..bed991f8a9cf5632656e409504e6ddbde1119d26 100644 (file)
@@ -162,7 +162,7 @@ void OtnRemove(GHash* otn_map, OptTreeNode* otn)
     key.gid = otn->sigInfo.gid;
     key.sid = otn->sigInfo.sid;
 
-    ghash_remove(otn_map, &key);
+    otn_map->remove(&key);
 }
 
 void OtnFree(void* data)
@@ -220,7 +220,7 @@ void OtnFree(void* data)
 
 GHash* OtnLookupNew()
 {
-    return ghash_new(10000, sizeof(OtnKey), 0, OtnFree);
+    return new GHash(10000, sizeof(OtnKey), 0, OtnFree);
 }
 
 void OtnLookupAdd(GHash* otn_map, OptTreeNode* otn)
@@ -231,8 +231,7 @@ void OtnLookupAdd(GHash* otn_map, OptTreeNode* otn)
     key.gid = otn->sigInfo.gid;
     key.sid = otn->sigInfo.sid;
 
-    int status = ghash_add(otn_map, &key, otn);
-
+    int status = otn_map->insert(&key, otn);
     if ( status == GHASH_OK )
         return;
 
@@ -248,7 +247,7 @@ OptTreeNode* OtnLookup(GHash* otn_map, uint32_t gid, uint32_t sid)
     key.gid = gid;
     key.sid = sid;
 
-    OptTreeNode* otn = (OptTreeNode*)ghash_find(otn_map, &key);
+    OptTreeNode* otn = (OptTreeNode*)otn_map->find(&key);
 
     return otn;
 }
@@ -273,6 +272,6 @@ OptTreeNode* GetOTN(uint32_t gid, uint32_t sid)
 void OtnLookupFree(GHash* otn_map)
 {
     if ( otn_map )
-        ghash_delete(otn_map);
+        delete otn_map;
 }
 
index 1949ab90307579063fb3d8986592c293fc173c6a..d27f93ad43d9d9a4d846bff59fa12641224374ed 100644 (file)
@@ -31,7 +31,7 @@
 
 namespace snort
 {
-struct GHash;
+class GHash;
 struct SnortConfig;
 }
 
index 1dcbd4cdc27f6243030a1286c3c3fd6a64179351..afa2c3b0d80e3cca011cad4502572ce844746cd0 100644 (file)
@@ -132,25 +132,19 @@ static void AddTagNode(Packet*, TagData*, int, uint32_t, uint16_t, void*);
 static inline void SwapTag(TagNode*);
 
 /**Calculated memory needed per node insertion into respective cache. Its includes
- * memory needed for allocating TagNode, XHashNode, and key size.
+ * memory needed for allocating TagNode, HashNode and key size.
  *
  * @param hash - pointer to XHash that should point to either ssn_tag_cache_ptr
  * or host_tag_cache_ptr.
  *
  * @returns number of bytes needed
  */
-static inline unsigned int memory_per_node(
-    XHash* hash
-    )
+static inline unsigned int memory_per_node(XHash* hash)
 {
-    if (hash == ssn_tag_cache_ptr)
-    {
-        return sizeof(tTagFlowKey)+sizeof(XHashNode)+sizeof(TagNode);
-    }
-    else if (hash == host_tag_cache_ptr)
-    {
-        return sizeof(SfIp)+sizeof(XHashNode)+sizeof(TagNode);
-    }
+    if ( hash == ssn_tag_cache_ptr )
+        return sizeof(tTagFlowKey) + sizeof(HashNode) + sizeof(TagNode);
+    else if ( hash == host_tag_cache_ptr )
+        return sizeof(SfIp) + sizeof(HashNode) + sizeof(TagNode);
 
     return 0;
 }
@@ -269,38 +263,17 @@ void InitTag()
 {
     unsigned int hashTableSize = TAG_MEMCAP/sizeof(TagNode);
 
-    ssn_tag_cache_ptr = xhash_new(
-        hashTableSize,                      /* number of hash buckets */
-        sizeof(tTagFlowKey),             /* size of the key we're going to use */
-        0,                                  /* size of the storage node */
-        0,                                  /* disable memcap*/
-        0,                                  /* use auto node recovery */
-        nullptr,                               /* anr free function */
-        TagFreeSessionNodeFunc,             /* user free function */
-        0);                                 /* recycle node flag */
-
-    host_tag_cache_ptr = xhash_new(
-        hashTableSize,               /* number of hash buckets */
-        sizeof(SfIp),            /* size of the key we're going to use */
-        0,                           /* size of the storage node */
-        0,                           /* disable memcap*/
-        0,                           /* use auto node recovery */
-        nullptr,                        /* anr free function */
-        TagFreeHostNodeFunc,         /* user free function */
-        0);                          /* recycle node flag */
+    ssn_tag_cache_ptr = new XHash(hashTableSize, sizeof(tTagFlowKey), 0, 0,
+        false, nullptr, TagFreeSessionNodeFunc, false);
+
+    host_tag_cache_ptr = new XHash(hashTableSize, sizeof(SfIp), 0, 0, false,
+        nullptr, TagFreeHostNodeFunc, false);
 }
 
 void CleanupTag()
 {
-    if (ssn_tag_cache_ptr)
-    {
-        xhash_delete(ssn_tag_cache_ptr);
-    }
-
-    if (host_tag_cache_ptr)
-    {
-        xhash_delete(host_tag_cache_ptr);
-    }
+    delete ssn_tag_cache_ptr;
+    delete host_tag_cache_ptr;
 }
 
 static void TagSession(Packet* p, TagData* tag, uint32_t time, uint16_t event_id, void* log_list)
@@ -399,12 +372,12 @@ static void AddTagNode(Packet* p, TagData* tag, int mode, uint32_t now,
     }
 
     /* check for duplicates */
-    returned = (TagNode*)xhash_find(tag_cache_ptr, idx);
+    returned = (TagNode*)tag_cache_ptr->get_user_data(idx);
 
     if (returned == nullptr)
     {
         SwapTag(idx);
-        returned = (TagNode*)xhash_find(tag_cache_ptr, idx);
+        returned = (TagNode*)tag_cache_ptr->get_user_data(idx);
         SwapTag(idx);
     }
 
@@ -417,7 +390,7 @@ static void AddTagNode(Packet* p, TagData* tag, int mode, uint32_t now,
             SwapTag(idx);
         }
 
-        if (xhash_add(tag_cache_ptr, idx, idx) != XHASH_OK)
+        if (tag_cache_ptr->insert(idx, idx) != HASH_OK)
         {
             TagFree(tag_cache_ptr, idx);
             return;
@@ -443,7 +416,7 @@ int CheckTagList(Packet* p, Event& event, void** log_list)
     char create_event = 1;
 
     /* check for active tags */
-    if (!xhash_count(host_tag_cache_ptr) && !xhash_count(ssn_tag_cache_ptr))
+    if (!host_tag_cache_ptr->get_node_count() && !ssn_tag_cache_ptr->get_node_count())
     {
         return 0;
     }
@@ -459,7 +432,7 @@ int CheckTagList(Packet* p, Event& event, void** log_list)
     idx.key.dp = p->ptrs.dp;
 
     /* check for session tags... */
-    returned = (TagNode*)xhash_find(ssn_tag_cache_ptr, &idx);
+    returned = (TagNode*)ssn_tag_cache_ptr->get_user_data(&idx);
 
     if (returned == nullptr)
     {
@@ -468,11 +441,11 @@ int CheckTagList(Packet* p, Event& event, void** log_list)
         idx.key.dp = p->ptrs.sp;
         idx.key.sp = p->ptrs.dp;
 
-        returned = (TagNode*)xhash_find(ssn_tag_cache_ptr, &idx);
+        returned = (TagNode*)ssn_tag_cache_ptr->get_user_data(&idx);
 
         if (returned == nullptr)
         {
-            returned = (TagNode*)xhash_find(host_tag_cache_ptr, &idx);
+            returned = (TagNode*)host_tag_cache_ptr->get_user_data(&idx);
 
             if (returned == nullptr)
             {
@@ -482,7 +455,7 @@ int CheckTagList(Packet* p, Event& event, void** log_list)
                 */
                 idx.key.sip = *p->ptrs.ip_api.get_src();
 
-                returned = (TagNode*)xhash_find(host_tag_cache_ptr, &idx);
+                returned = (TagNode*)host_tag_cache_ptr->get_user_data(&idx);
             }
 
             if (returned != nullptr)
@@ -560,7 +533,7 @@ int CheckTagList(Packet* p, Event& event, void** log_list)
 
         if ( !returned->metric )
         {
-            if (xhash_remove(taglist, returned) != XHASH_OK)
+            if (taglist->release_node(returned) != HASH_OK)
             {
                 LogMessage("WARNING: failed to remove tagNode from hash.\n");
             }
@@ -585,34 +558,30 @@ static int PruneTagCache(uint32_t thetime, int mustdie)
 
     if (mustdie == 0)
     {
-        if (xhash_count(ssn_tag_cache_ptr) != 0)
-        {
+        if (ssn_tag_cache_ptr->get_node_count() != 0)
             pruned = PruneTime(ssn_tag_cache_ptr, thetime);
-        }
 
-        if (xhash_count(host_tag_cache_ptr) != 0)
-        {
+        if (host_tag_cache_ptr->get_node_count() != 0)
             pruned += PruneTime(host_tag_cache_ptr, thetime);
-        }
     }
     else
     {
         while (pruned < mustdie &&
-            (xhash_count(ssn_tag_cache_ptr) > 0 || xhash_count(host_tag_cache_ptr) > 0))
+            (ssn_tag_cache_ptr->get_node_count() > 0 || host_tag_cache_ptr->get_node_count() > 0))
         {
             TagNode* lru_node;
 
-            if ((lru_node = (TagNode*)xhash_lru(ssn_tag_cache_ptr)) != nullptr)
+            if ((lru_node = (TagNode*)ssn_tag_cache_ptr->get_lru_user_data()) != nullptr)
             {
-                if (xhash_remove(ssn_tag_cache_ptr, lru_node) != XHASH_OK)
+                if (ssn_tag_cache_ptr->release_node(lru_node) != HASH_OK)
                 {
                     LogMessage("WARNING: failed to remove tagNode from hash.\n");
                 }
                 pruned++;
             }
-            if ((lru_node = (TagNode*)xhash_lru(host_tag_cache_ptr)) != nullptr)
+            if ((lru_node = (TagNode*)host_tag_cache_ptr->get_lru_user_data()) != nullptr)
             {
-                if (xhash_remove(host_tag_cache_ptr, lru_node) != XHASH_OK)
+                if (host_tag_cache_ptr->release_node(lru_node) != HASH_OK)
                 {
                     LogMessage("WARNING: failed to remove tagNode from hash.\n");
                 }
@@ -629,11 +598,11 @@ static int PruneTime(XHash* tree, uint32_t thetime)
     int pruned = 0;
     TagNode* lru_node = nullptr;
 
-    while ((lru_node = (TagNode*)xhash_lru(tree)) != nullptr)
+    while ((lru_node = (TagNode*)tree->get_lru_user_data()) != nullptr)
     {
         if ((lru_node->last_access + TAG_PRUNE_QUANTUM) < thetime)
         {
-            if (xhash_remove(tree, lru_node) != XHASH_OK)
+            if (tree->release_node(lru_node) != HASH_OK)
             {
                 LogMessage("WARNING: failed to remove tagNode from hash.\n");
             }
index 6affa8f0d3f1dc3cd8730eaa5f4e4923346a22be..9e7f19580bd936f08e318de36def7a20152cb53c 100644 (file)
@@ -167,23 +167,15 @@ struct OptTreeNode
 
     // ptr to list of RTNs (head part); indexed by policyId
     RuleTreeNode** proto_nodes = nullptr;
-
     OtnState* state = nullptr;
-
     int chain_node_number = 0;
-    int evalIndex = 0;       /* where this rule sits in the evaluation sets */
-
+    unsigned evalIndex = 0;       /* where this rule sits in the evaluation sets */
     unsigned ruleIndex = 0; // unique index
-
     uint32_t num_detection_opts = 0;
     uint32_t plugins = 0;
-
-    // Added for integrity checks during rule parsing.
-    SnortProtocolId snort_protocol_id = 0;
-
+    SnortProtocolId snort_protocol_id = 0;    // Added for integrity checks during rule parsing.
     unsigned short proto_node_num = 0;
     uint16_t longestPatternLen = 0;
-
     IpsPolicy::Enable enable;
     Flag flags = 0;
 
index b8cb4c4ef7c8788729020b0a5b97991992f79899..48019fde5658bd4eac52740d234e0572558bd7a3 100644 (file)
@@ -79,19 +79,14 @@ static int64_t time_elapsed_ms(struct timeval* now, struct timeval* expire_time,
 FileCache::FileCache(int64_t max_files_cached)
 {
     max_files = max_files_cached;
-    fileHash = xhash_new(max_files, sizeof(FileHashKey), sizeof(FileNode),
-        0, 1, file_cache_anr_free_func, file_cache_free_func, 1);
-    if (!fileHash)
-        FatalError("Failed to create the expected channel hash table.\n");
-    xhash_set_max_nodes(fileHash, max_files);
+    fileHash = new XHash(max_files, sizeof(FileHashKey), sizeof(FileNode),
+        0, true, file_cache_anr_free_func, file_cache_free_func, true);
+    fileHash->set_max_nodes(max_files);
 }
 
 FileCache::~FileCache()
 {
-    if (fileHash)
-    {
-        xhash_delete(fileHash);
-    }
+    delete fileHash;
 }
 
 void FileCache::set_block_timeout(int64_t timeout)
@@ -119,7 +114,7 @@ void FileCache::set_max_files(int64_t max)
     }
     else
         max_files = max;
-    xhash_set_max_nodes(fileHash, max_files);
+    fileHash->set_max_nodes(max_files);
 }
 
 FileContext* FileCache::add(const FileHashKey& hashKey, int64_t timeout)
@@ -141,7 +136,7 @@ FileContext* FileCache::add(const FileHashKey& hashKey, int64_t timeout)
 
     std::lock_guard<std::mutex> lock(cache_mutex);
 
-    if (xhash_add(fileHash, (void*)&hashKey, &new_node) != XHASH_OK)
+    if (fileHash->insert((void*)&hashKey, &new_node) != HASH_OK)
     {
         /* Uh, shouldn't get here...
          * There is already a node or couldn't alloc space
@@ -160,12 +155,12 @@ FileContext* FileCache::find(const FileHashKey& hashKey, int64_t timeout)
 {
     std::lock_guard<std::mutex> lock(cache_mutex);
 
-    if (!xhash_count(fileHash))
+    if (!fileHash->get_node_count())
     {
         return nullptr;
     }
 
-    XHashNode* hash_node = xhash_find_node(fileHash, &hashKey);
+    HashNode* hash_node = fileHash->find_node(&hashKey);
 
     if (!hash_node)
         return nullptr;
@@ -173,7 +168,7 @@ FileContext* FileCache::find(const FileHashKey& hashKey, int64_t timeout)
     FileNode* node = (FileNode*)hash_node->data;
     if (!node)
     {
-        xhash_free_node(fileHash, hash_node);
+        fileHash->release_node(hash_node);
         return nullptr;
     }
 
@@ -182,7 +177,7 @@ FileContext* FileCache::find(const FileHashKey& hashKey, int64_t timeout)
 
     if (timercmp(&node->cache_expire_time, &now, <))
     {
-        xhash_free_node(fileHash, hash_node);
+        fileHash->release_node(hash_node);
         return nullptr;
     }
 
index 5394000982938d76b96c484f27aec51a6e8f0e32..1ee25d89dc4705292d99d00b54a52f8a0d2b84d4 100644 (file)
@@ -30,8 +30,7 @@
 
 namespace snort
 {
-struct XHash;
-struct XHashNode;
+class XHash;
 }
 
 class FileCache
index 2d78616622e15568b582a32f1c566d725d1add0c..2e7143ff51f2020baa84b39d133a7dc5cf32d4bf 100644 (file)
@@ -68,22 +68,17 @@ void FileMagicRule::clear()
 
 void FileIdentifier::init_merge_hash()
 {
-    identifier_merge_hash = ghash_new(1000, sizeof(MergeNode), 0, nullptr);
-    assert(identifier_merge_hash);
+    identifier_merge_hash = new GHash(1000, sizeof(MergeNode), 0, nullptr);
 }
 
 FileIdentifier::~FileIdentifier()
 {
     /*Release memory used for identifiers*/
     for (auto mem_block:id_memory_blocks)
-    {
         snort_free(mem_block);
-    }
 
     if (identifier_merge_hash != nullptr)
-    {
-        ghash_delete(identifier_merge_hash);
-    }
+        delete identifier_merge_hash;
 }
 
 void* FileIdentifier::calloc_mem(size_t size)
@@ -176,7 +171,7 @@ IdentifierNode* FileIdentifier::create_trie_from_magic(FileMagicRule& rule, uint
 
 /*This function examines whether to update the trie based on shared state*/
 
-bool FileIdentifier::update_next(IdentifierNode* start,IdentifierNode** next_ptr,
+bool FileIdentifier::update_next(IdentifierNode* start, IdentifierNode** next_ptr,
     IdentifierNode* append)
 {
     IdentifierNode* next = (*next_ptr);
@@ -195,7 +190,7 @@ bool FileIdentifier::update_next(IdentifierNode* start,IdentifierNode** next_ptr
         set_node_state_shared(append);
         return false;
     }
-    else if ((result = (IdentifierNode*)ghash_find(identifier_merge_hash, &merge_node)))
+    else if ((result = (IdentifierNode*)identifier_merge_hash->find(&merge_node)))
     {
         /*the same pointer has been processed, reuse it*/
         *next_ptr = result;
@@ -220,7 +215,7 @@ bool FileIdentifier::update_next(IdentifierNode* start,IdentifierNode** next_ptr
 
             set_node_state_shared(next);
             next = node;
-            ghash_add(identifier_merge_hash, &merge_node, next);
+            identifier_merge_hash->insert(&merge_node, next);
         }
         else if (next->state == ID_NODE_SHARED)
         {
@@ -230,7 +225,7 @@ bool FileIdentifier::update_next(IdentifierNode* start,IdentifierNode** next_ptr
             merge_node.append_node = append;
             next = clone_node(current_next);
             set_node_state_shared(next);
-            ghash_add(identifier_merge_hash, &merge_node, next);
+            identifier_merge_hash->insert(&merge_node, next);
         }
 
         *next_ptr = next;
index ae926b00697cff3fb304d147fb8e6d45ea36f75a..5d30a7818678f81d30046f5044a226ac522e8157 100644 (file)
@@ -82,12 +82,7 @@ void detection_filter_init(DetectionFilterConfig* df_config)
         return;
 
     if ( !detection_filter_hash )
-    {
         detection_filter_hash = sfthd_local_new(df_config->memcap);
-
-        if ( !detection_filter_hash )
-            FatalError("can't allocate detection filter cache\n");
-    }
 }
 
 void detection_filter_term()
@@ -95,7 +90,7 @@ void detection_filter_term()
     if ( !detection_filter_hash )
         return;
 
-    xhash_delete(detection_filter_hash);
+    delete detection_filter_hash;
     detection_filter_hash = nullptr;
 }
 
index bf9d9c7a92c39b7adb2836d472bb8bcc748d7112..3c8c392c991296f1f9ba4a615ad4e80eae2c78a7 100644 (file)
@@ -53,8 +53,8 @@ void RateFilter_ConfigFree(RateFilterConfig* config)
 
     for (i = 0; i < SFRF_MAX_GENID; i++)
     {
-        if (config->genHash[i] != nullptr)
-            ghash_delete(config->genHash[i]);
+        if ( config->genHash[i] )
+            delete config->genHash[i];
     }
 
     snort_free(config);
index ff6e8e15e48fd36bab883925718651f33dc598e9..a985f6caeec3322b1bfd4afbf7a9aad50e9f73d6 100644 (file)
@@ -152,15 +152,8 @@ static void SFRF_New(unsigned nbytes)
     nrows = nbytes / (SFRF_BYTES);
 
     /* Create global hash table for all of the IP Nodes */
-    rf_hash = xhash_new(
-        nrows,  /* try one node per row - for speed */
-        sizeof(tSFRFTrackingNodeKey), /* keys size */
-        sizeof(tSFRFTrackingNode),     /* data size */
-        nbytes,                  /* memcap **/
-        1,         /* ANR flag - true ?- Automatic Node Recovery=ANR */
-        nullptr,         /* ANR callback - none */
-        nullptr,         /* user freemem callback - none */
-        1);       /* Recycle nodes ?*/
+    rf_hash = new XHash(nrows, sizeof(tSFRFTrackingNodeKey),
+        sizeof(tSFRFTrackingNode), nbytes, true, nullptr, nullptr, true);
 }
 
 void SFRF_Delete()
@@ -168,14 +161,14 @@ void SFRF_Delete()
     if ( !rf_hash )
         return;
 
-    xhash_delete(rf_hash);
+    delete rf_hash;
     rf_hash = nullptr;
 }
 
 void SFRF_Flush()
 {
     if ( rf_hash )
-        xhash_make_empty(rf_hash);
+        rf_hash->clear();
 }
 
 static void SFRF_ConfigNodeFree(void* item)
@@ -279,10 +272,7 @@ int SFRF_ConfigAdd(SnortConfig*, RateFilterConfig* rf_config, tSFRFConfigNode* c
         }
 
         /* Create the hash table for this gid */
-        genHash = ghash_new(nrows, sizeof(tSFRFGenHashKey), 0, SFRF_SidNodeFree);
-        if ( !genHash )
-            return -2;
-
+        genHash = new GHash(nrows, sizeof(tSFRFGenHashKey), false, SFRF_SidNodeFree);
         rf_config->genHash[cfgNode->gid] = genHash;
     }
 
@@ -290,7 +280,7 @@ int SFRF_ConfigAdd(SnortConfig*, RateFilterConfig* rf_config, tSFRFConfigNode* c
     key.policyId = policy_id;
 
     /* Check if sid is already in the table - if not allocate and add it */
-    pSidNode = (tSFRFSidNode*)ghash_find(genHash, (void*)&key);
+    pSidNode = (tSFRFSidNode*)genHash->find((void*)&key);
     if ( !pSidNode )
     {
         /* Create the pSidNode hash node data */
@@ -307,7 +297,7 @@ int SFRF_ConfigAdd(SnortConfig*, RateFilterConfig* rf_config, tSFRFConfigNode* c
         }
 
         /* Add the pSidNode to the hash table */
-        if ( ghash_add(genHash, (void*)&key, pSidNode) )
+        if ( genHash->insert((void*)&key, pSidNode) )
         {
             sflist_free(pSidNode->configNodeList);
             snort_free(pSidNode);
@@ -498,7 +488,7 @@ int SFRF_TestThreshold(
     key.sid = sid;
     key.policyId = policy_id;
 
-    pSidNode = (tSFRFSidNode*)ghash_find(genHash, (void*)&key);
+    pSidNode = (tSFRFSidNode*)genHash->find((void*)&key);
     if ( !pSidNode )
     {
 #ifdef SFRF_DEBUG
@@ -586,7 +576,7 @@ void SFRF_ShowObjects(RateFilterConfig* config)
     unsigned int gid;
     GHashNode* sidHashNode;
 
-    for ( gid=0; gid < SFRF_MAX_GENID; gid++ )
+    for ( gid = 0; gid < SFRF_MAX_GENID; gid++ )
     {
         GHash* genHash = config->genHash [ gid ];
 
@@ -595,9 +585,9 @@ void SFRF_ShowObjects(RateFilterConfig* config)
 
         printf("...GEN_ID = %u\n",gid);
 
-        for ( sidHashNode  = ghash_findfirst(genHash);
-            sidHashNode != nullptr;
-            sidHashNode  = ghash_findnext(genHash) )
+        for (sidHashNode = genHash->find_first();
+             sidHashNode != nullptr;
+             sidHashNode = genHash->find_next() )
         {
             /* Check for any Permanent sid objects for this gid */
             pSidnode = (tSFRFSidNode*)sidHashNode->data;
@@ -610,9 +600,9 @@ void SFRF_ShowObjects(RateFilterConfig* config)
                each object has it's own unique thd_id */
             SF_LNODE* cursor;
 
-            for ( cfgNode  = (tSFRFConfigNode*)sflist_first(pSidnode->configNodeList, &cursor);
-                cfgNode != nullptr;
-                cfgNode = (tSFRFConfigNode*)sflist_next(&cursor) )
+            for (cfgNode  = (tSFRFConfigNode*)sflist_first(pSidnode->configNodeList, &cursor);
+                 cfgNode != nullptr;
+                 cfgNode = (tSFRFConfigNode*)sflist_next(&cursor) )
             {
                 printf(".........SFRF_ID  =%d\n",cfgNode->tid);
                 printf(".........tracking =%d\n",cfgNode->tracking);
@@ -795,7 +785,7 @@ static tSFRFTrackingNode* _getSFRFTrackingNode(const SfIp* ip, unsigned tid, tim
     /*
      * Check for any Permanent sid objects for this gid or add this one ...
      */
-    XHashNode* hnode = xhash_get_node(rf_hash, (void*)&key);
+    HashNode* hnode = rf_hash->get_node((void*)&key);
     if ( !hnode )
     {
         // xhash_get_node fails to insert only if rf_hash is full.
index f29d486b1e57bc852c35e67e359da6486fad0dc4..e58aa33b0f18728c7cbc8f12437476e1e4a5796d 100644 (file)
@@ -32,6 +32,7 @@
 
 namespace snort
 {
+class GHash;
 struct SfIp;
 struct SnortConfig;
 }
@@ -138,7 +139,7 @@ struct RateFilterConfig
     /* Array of hash, indexed by gid. Each array element is a hash, which
      * is keyed on sid/policyId and data is a tSFRFSidNode node.
      */
-    struct snort::GHash* genHash [SFRF_MAX_GENID];
+    snort::GHash* genHash [SFRF_MAX_GENID];
 
     unsigned memcap;
     unsigned noRevertCount;
index fbdbe95243ff1da67e68a096b349c6914076a649..b83ba0fa5920855a1bc5fb170d4be4fb5d542e56 100644 (file)
@@ -57,20 +57,10 @@ XHash* sfthd_new_hash(unsigned nbytes, size_t key, size_t data)
 
     /* Calc max ip nodes for this memory */
     if ( nbytes < size )
-    {
         nbytes = size;
-    }
-    nrows = nbytes / (size);
-
-    return xhash_new(
-        nrows,  /* try one node per row - for speed */
-        key,    /* keys size */
-        data,   /* data size */
-        nbytes, /* memcap **/
-        1,      /* ANR flag - true ?- Automatic Node Recovery=ANR */
-        nullptr,      /* ANR callback - none */
-        nullptr,      /* user freemem callback - none */
-        1);     /* Recycle nodes ?*/
+    nrows = nbytes / size;
+
+    return new XHash(nrows, key, data, nbytes, true, nullptr, nullptr, true);
 }
 
 /*!
@@ -142,7 +132,7 @@ THD_STRUCT* sfthd_new(unsigned lbytes, unsigned gbytes)
 #ifdef THD_DEBUG
         printf("Could not allocate the sfxhash table\n");
 #endif
-        xhash_delete(thd->ip_nodes);
+        delete thd->ip_nodes;
         snort_free(thd);
         return nullptr;
     }
@@ -179,24 +169,24 @@ void sfthd_objs_free(ThresholdObjects* thd_objs)
 
     for (i = 0; i < THD_MAX_GENID; i++)
     {
-        if (thd_objs->sfthd_array[i])
-            ghash_delete(thd_objs->sfthd_array[i]);
+        if ( thd_objs->sfthd_array[i] )
+            delete thd_objs->sfthd_array[i];
     }
 
     for (policyId = 0; policyId < thd_objs->numPoliciesAllocated; policyId++)
     {
-        if (thd_objs->sfthd_garray[policyId] == nullptr)
+        if ( !thd_objs->sfthd_garray[policyId] )
             continue;
 
-        if (thd_objs->sfthd_garray[policyId][0] != nullptr)
+        if ( thd_objs->sfthd_garray[policyId][0] )
         {
             sfthd_node_free(thd_objs->sfthd_garray[policyId][0]);
 
             /* Free any individuals */
             for (i = 0; i < THD_MAX_GENID; i++)
             {
-                if (thd_objs->sfthd_garray[policyId][i] !=
-                    thd_objs->sfthd_garray[policyId][0])
+                if ( thd_objs->sfthd_garray[policyId][i] !=
+                    thd_objs->sfthd_garray[policyId][0] )
                 {
                     sfthd_node_free(thd_objs->sfthd_garray[policyId][i]);
                 }
@@ -207,17 +197,15 @@ void sfthd_objs_free(ThresholdObjects* thd_objs)
             /* Anything other GID will be allocated individually */
             for (i = 1; i < THD_MAX_GENID; i++)
             {
-                if (thd_objs->sfthd_garray[policyId][i])
-                {
+                if ( thd_objs->sfthd_garray[policyId][i] )
                     sfthd_node_free(thd_objs->sfthd_garray[policyId][i]);
-                }
             }
         }
 
         snort_free(thd_objs->sfthd_garray[policyId]);
     }
 
-    if (thd_objs->sfthd_garray != nullptr)
+    if ( thd_objs->sfthd_garray )
         snort_free(thd_objs->sfthd_garray);
 
     snort_free(thd_objs);
@@ -235,11 +223,11 @@ void sfthd_free(THD_STRUCT* thd)
     if (thd == nullptr)
         return;
 
-    if (thd->ip_nodes != nullptr)
-        xhash_delete(thd->ip_nodes);
+    if ( thd->ip_nodes )
+        delete thd->ip_nodes;
 
-    if (thd->ip_gnodes != nullptr)
-        xhash_delete(thd->ip_gnodes);
+    if ( thd->ip_gnodes )
+        delete thd->ip_gnodes;
 
     snort_free(thd);
 }
@@ -319,12 +307,7 @@ static int sfthd_create_threshold_local(
         }
 
         /* Create the hash table for this gen_id */
-        sfthd_hash = ghash_new(nrows, sizeof(tThdItemKey), 0, sfthd_item_free);
-        if ( !sfthd_hash )
-        {
-            return -2;
-        }
-
+        sfthd_hash = new GHash(nrows, sizeof(tThdItemKey), false, sfthd_item_free);
         thd_objs->sfthd_array[config->gen_id] = sfthd_hash;
     }
     else
@@ -340,7 +323,7 @@ static int sfthd_create_threshold_local(
     key.policyId = policy_id;
 
     /* Check if sig_id is already in the table - if not allocate and add it */
-    sfthd_item = (THD_ITEM*)ghash_find(sfthd_hash, (void*)&key);
+    sfthd_item = (THD_ITEM*)sfthd_hash->find((void*)&key);
     if ( !sfthd_item )
     {
         /* Create the sfthd_item hash node data */
@@ -358,7 +341,7 @@ static int sfthd_create_threshold_local(
         }
 
         /* Add the sfthd_item to the hash table */
-        if ( ghash_add(sfthd_hash, (void*)&key, sfthd_item) )
+        if ( sfthd_hash->insert((void*)&key, sfthd_item) )
         {
             sflist_free(sfthd_item->sfthd_node_list);
             snort_free(sfthd_item);
@@ -904,21 +887,21 @@ int sfthd_test_local(
     /*
      * Check for any Permanent sig_id objects for this gen_id  or add this one ...
      */
-    int status = xhash_add(local_hash, (void*)&key, &data);
-    if (status == XHASH_INTABLE)
+    int status = local_hash->insert((void*)&key, &data);
+    if (status == HASH_INTABLE)
     {
         /* Already in the table */
-        sfthd_ip_node = (THD_IP_NODE*)local_hash->cnode->data;
+        sfthd_ip_node = (THD_IP_NODE*)local_hash->get_cnode()->data;
 
         /* Increment the event count */
         sfthd_ip_node->count++;
     }
-    else if (status == XHASH_NOMEM)
+    else if (status == HASH_NOMEM)
     {
         event_filter_stats.xhash_nomem_peg_local++;
         return 1;
     }
-    else if (status != XHASH_OK)
+    else if (status != HASH_OK)
     {
         /* hash error */
         return 1; /*  check the next threshold object */
@@ -1002,21 +985,21 @@ static inline int sfthd_test_global(
     data.tstart = data.tlast = curtime; /* Event time */
 
     /* Check for any Permanent sig_id objects for this gen_id  or add this one ...  */
-    int status = xhash_add(global_hash, (void*)&key, &data);
-    if (status == XHASH_INTABLE)
+    int status = global_hash->insert((void*)&key, &data);
+    if (status == HASH_INTABLE)
     {
         /* Already in the table */
-        sfthd_ip_node = (THD_IP_NODE*)global_hash->cnode->data;
+        sfthd_ip_node = (THD_IP_NODE*)global_hash->get_cnode()->data;
 
         /* Increment the event count */
         sfthd_ip_node->count++;
     }
-    else if (status == XHASH_NOMEM)
+    else if (status == HASH_NOMEM)
     {
         event_filter_stats.xhash_nomem_peg_global++;
         return 1;
     }
-    else if (status != XHASH_OK)
+    else if (status != HASH_OK)
     {
         /* hash error */
         return 1; /*  check the next threshold object */
@@ -1103,7 +1086,7 @@ int sfthd_test_threshold(
     /*
      * Check for any Permanent sig_id objects for this gen_id
      */
-    sfthd_item = (THD_ITEM*)ghash_find(sfthd_hash, (void*)&key);
+    sfthd_item = (THD_ITEM*)sfthd_hash->find((void*)&key);
     if (sfthd_item == nullptr)
     {
 #ifdef THD_DEBUG
@@ -1235,9 +1218,9 @@ int sfthd_show_objects(ThresholdObjects* thd_objs)
 
         printf("...GEN_ID = %u\n",gen_id);
 
-        for (item_hash_node  = ghash_findfirst(sfthd_hash);
-            item_hash_node != 0;
-            item_hash_node  = ghash_findnext(sfthd_hash) )
+        for (item_hash_node  = sfthd_hash->ghash_findfirst();
+             item_hash_node != 0;
+             item_hash_node  = sfthd_hash->ghash_findnext() )
         {
             /* Check for any Permanent sig_id objects for this gen_id */
             sfthd_item = (THD_ITEM*)item_hash_node->data;
index 938109ce13f7e22b9596f65000150fb2ec367daf..4b240acc115f1623d8feea161a1c973c32a1b848 100644 (file)
@@ -30,8 +30,8 @@
 
 namespace snort
 {
-struct GHash;
-struct XHash;
+class GHash;
+class XHash;
 struct SnortConfig;
 }
 
index 15c426d72444f31296c377be75116275f9c9d33f..5058d4a089b52f012417ced097a5819fd4bb8009 100644 (file)
@@ -808,7 +808,8 @@ static void Term()
             p->rule = nullptr;
         }
     }
-    xhash_delete(dThd);
+
+    delete dThd;
 }
 
 static int SetupCheck(int i)
index 528541ddbd4969caf4d020b3ea4ecb67b3c10d91..69873cc46976d928b7f258df6a638197f36c20dd 100644 (file)
@@ -270,7 +270,7 @@ ExpectCache::ExpectCache(uint32_t max)
 {
     // -size forces use of abs(size) ie w/o bumping up
     hash_table = new ZHash(-MAX_HASH, sizeof(FlowKey));
-    hash_table->set_keyops(FlowKey::hash, FlowKey::compare);
+    hash_table->set_key_opcodes(FlowKey::hash, FlowKey::is_equal);
 
     nodes = new ExpectNode[max];
     for (unsigned i = 0; i < max; ++i)
index 32d3317bfaeeffba17bd32d187268f861799e1f1..b7ef59dc913ca76faa20f93f45922bee64d4c0da 100644 (file)
@@ -53,7 +53,7 @@ static const unsigned ALL_FLOWS = 3;
 FlowCache::FlowCache(const FlowCacheConfig& cfg) : config(cfg)
 {
     hash_table = new ZHash(config.max_flows, sizeof(FlowKey));
-    hash_table->set_keyops(FlowKey::hash, FlowKey::compare);
+    hash_table->set_key_opcodes(FlowKey::hash, FlowKey::is_equal);
 
     uni_flows = new FlowUniList;
     uni_ip_flows = new FlowUniList;
@@ -365,7 +365,7 @@ unsigned FlowCache::delete_active_flows(unsigned mode, unsigned num_to_delete, u
         if ( (mode == ALLOWED_FLOWS_ONLY and (flow->was_blocked() || flow->is_suspended()))
             or (mode == OFFLOADED_FLOWS_TOO and flow->was_blocked()) )
         {
-            if (!hash_table->touch())
+            if ( !hash_table->touch() )
                 break;
 
             continue;
index 1438d2d85cb4b552fdb975addfe9de5442a21ad4..72575eb1d6edba0f30bc14d314debb81effcd96a 100644 (file)
@@ -331,42 +331,42 @@ uint32_t FlowKey::hash(HashFnc* hf, const unsigned char* p, int)
     return c;
 }
 
-int FlowKey::compare(const void* s1, const void* s2, size_t)
+bool FlowKey::is_equal(const void* s1, const void* s2, size_t)
 {
     const uint64_t* a,* b;
 
     a = (const uint64_t*)s1;
     b = (const uint64_t*)s2;
     if (*a - *b)
-        return 1;               /* Compares IPv4 lo/hi
+        return false;               /* Compares IPv4 lo/hi
                                    Compares IPv6 low[0,1] */
 
     a++;
     b++;
     if (*a - *b)
-        return 1;               /* Compares port lo/hi, vlan, protocol, version
+        return false;               /* Compares port lo/hi, vlan, protocol, version
                                    Compares IPv6 low[2,3] */
 
     a++;
     b++;
     if (*a - *b)
-        return 1;               /* Compares IPv6 hi[0,1] */
+        return false;               /* Compares IPv6 hi[0,1] */
 
     a++;
     b++;
     if (*a - *b)
-        return 1;               /* Compares IPv6 hi[2,3] */
+        return false;               /* Compares IPv6 hi[2,3] */
 
     a++;
     b++;
     if (*a - *b)
-        return 1;               /* Compares MPLS label, port lo/hi */
+        return false;               /* Compares MPLS label, port lo/hi */
 
     a++;
     b++;
     if (*a - *b)
-        return 1;               /* Compares vlan,AddressSpace ID,ip_proto,type,version,8 bit pad */
+        return false;               /* Compares vlan,AddressSpace ID,ip_proto,type,version,8 bit pad */
 
-    return 0;
+    return true;
 }
 
index ddc7d11cf7c2e315c456ecd4d7498c5e41cfe110..4d9fb4ad88855018cd9335c9a1455845f0fa5366 100644 (file)
@@ -71,7 +71,7 @@ struct SO_PUBLIC FlowKey
 
     // If this data structure changes size, compare must be updated!
     static uint32_t hash(HashFnc*, const unsigned char* d, int);
-    static int compare(const void* s1, const void* s2, size_t);
+    static bool is_equal(const void* s1, const void* s2, size_t);
 
 private:
     bool init4(
index f7abe0dfda130c67274e5eb1f307df38035f743f..edf8aebdd1a6256625cb48f6cd50c16e395ed18c 100644 (file)
@@ -658,7 +658,7 @@ Flow* HighAvailability::process_daq_import(Packet& p, FlowKey& key)
             // Validate that the imported flow matches up with the given flow key.
             if (flow)
             {
-                if (FlowKey::compare(&key, flow->key, 0) == 0)
+                if (FlowKey::is_equal(&key, flow->key, 0))
                 {
                     if (flow->flow_state == Flow::FlowState::BLOCK)
                     {
index d64c110c1654c1420e89fcc301bc1fdb72581941..63a3544079d274de9f50bce882762407d593591e 100644 (file)
@@ -207,7 +207,7 @@ void ErrorMessage(const char*,...) { }
 void LogMessage(const char*,...) { }
 }
 
-int FlowKey::compare(const void*, const void*, size_t) { return 0; }
+bool FlowKey::is_equal(const void*, const void*, size_t) { return false; }
 
 int SFDAQInstance::ioctl(DAQ_IoctlCmd, void*, size_t) { return DAQ_SUCCESS; }
 
index f21b36c5b6e4f62059e17bf7f76078560992574b..8cbdd87e27278ab6aac1d447da639af7296aa5ed 100644 (file)
@@ -1,6 +1,7 @@
 
 set (HASH_INCLUDES
     hashes.h
+    hash_defs.h
     ghash.h 
     xhash.h 
     hashfcn.h
index 3e8b3d4b91182346f024182ff2d6b2d17fcb11a4..7765b6c6b1734df0ae236c69ac8befd90fb049b0 100644 (file)
@@ -4,9 +4,9 @@ Message digests and hash maps/table implementations:
 
 * sha2:  open source implementation by Aaron Gifford.
 
-* sfghash: Generic hash table
+* ghash: Generic hash table
 
-* sfxhash: Hash table with supports memcap and automatic memory recovery
+* xhash: Hash table with supports memcap and automatic memory recovery
   when out of memory.
 
 * zhash: zero runtime allocations/preallocated hash table.
index cf742fe61d720ffe474548fa9027c2ac33f3efc7..80e264bb4a0c885bb0d6e465a57dbd0c3bdd056f 100644 (file)
 
 #include "utils/util.h"
 
-#include "hashfcn.h"
 #include "primetable.h"
 
 namespace snort
 {
-/*
-*
-*    Create a new hash table
-*
-*    nrows    : number of rows in hash table, primes are best.
-*               > 0  => we use the nearest prime internally
-*               < 0  => we use the magnitude as nrows.
-*    keysize  : > 0 => bytes in each key, keys are binary bytes,
-*               all keys are the same size.
-*               ==0 => keys are strings and are null terminated,
-*               allowing random key lengths.
-*    userkeys : > 0 => indicates user owns the key data
-*               and we should not allocate or free space for it,
-*               nor should we attempt to free the user key. We just
-*               save the pointer to the key.
-*               ==0 => we should copy the keys and manage them internally
-*    userfree : routine to free users data, null if we should not
-*               free user data in ghash_delete(). The routine
-*               should be of the form 'void userfree(void * userdata)',
-*               'free' works for simple allocations.
-*/
-GHash* ghash_new(int nrows, int keysize, int userkeys, gHashFree userfree)
-{
-    if ( nrows > 0 ) /* make sure we have a prime number */
-    {
-        nrows = nearest_prime(nrows);
-    }
-    else  /* use the magnitude or nrows as is */
-    {
-        nrows = -nrows;
-    }
-
-    GHash* h = (GHash*)snort_calloc(sizeof(GHash));
 
-    h->hashfcn = hashfcn_new(nrows);
-    h->table = (GHashNode**)snort_calloc(nrows, sizeof(GHashNode*));
+GHash::GHash(int nrows_, unsigned keysize, bool userkey, gHashFree userfree)
+    : keysize(keysize), userkey(userkey), userfree(userfree)
+{
+    if ( nrows_ > 0 )
+        nrows = nearest_prime(nrows_);
+    else
+        nrows = -nrows_;
 
+    hashfcn = hashfcn_new(nrows);
+    table = (GHashNode**)snort_calloc(nrows, sizeof(GHashNode*));
     for ( int i = 0; i < nrows; i++ )
-    {
-        h->table[i] = nullptr;
-    }
-
-    h->userkey = userkeys;
-    h->keysize = keysize;
-    h->nrows = nrows;
-    h->count = 0;
-    h->userfree = userfree;
-
-    h->crow = 0; // findfirst/next current row
-    h->cnode = nullptr; // findfirst/next current node ptr
+        table[i] = nullptr;
 
-    return h;
+    count = 0;
+    crow = 0;
+    cnode = nullptr;
 }
 
-/*
-*  Delete the hash Table
-*
-*  free key's, free node's, and free the users data, if they
-*  supply a free function
-*/
-void ghash_delete(GHash* h)
+GHash::~GHash()
 {
-    if ( !h )
-        return;
+    hashfcn_free(hashfcn);
 
-    hashfcn_free(h->hashfcn);
-
-    if ( h->table )
-    {
-        for (int i=0; i<h->nrows; i++)
+    for (int i = 0; i < nrows; i++)
+        for ( GHashNode* node = table[i]; node; )
         {
-            for ( GHashNode* node=h->table[i]; node; )
-            {
-                GHashNode* onode = node;
-                node  = node->next;
+            GHashNode* onode = node;
+            node  = node->next;
 
-                if ( !h->userkey && onode->key )
-                    snort_free(const_cast<void*>(onode->key));
+            if ( !userkey && onode->key )
+                snort_free(const_cast<void*>(onode->key));
 
-                if ( h->userfree && onode->data )
-                    h->userfree(onode->data); /* free users data, with users function */
+            if ( userfree && onode->data )
+                userfree(onode->data);
 
-                snort_free(onode);
-            }
+            snort_free(onode);
         }
-        snort_free(h->table);
-        h->table = nullptr;
-    }
 
-    snort_free(h);
+    snort_free(table);
 }
 
-/*
-*  Add a key + data pair
-*  ---------------------
-*
-*  key + data should both be non-zero, although data can be zero
-*
-*  t    - hash table
-*  key  - users key data (should be unique in this table)
-*         may be ascii strings or fixed size binary keys
-*  data - users data pointer
-*
-*  returns  SF_HASH_NOMEM: alloc error
-*           SF_HASH_INTABLE : key already in table (t->cnode points to the node)
-*           SF_OK: added a node for this key + data pair
-*
-*  Notes:
-*  If the key node already exists, then t->cnode points to it on return,
-*  this allows you to do something with the node - like add the data to a
-*  linked list of data items held by the node, or track a counter, or whatever.
-*
-*/
-int ghash_add(GHash* t, const void* const key, void* const data)
+// set key length, hashkey, and index parameters required to find/add/remove a node
+// the parameters set are valid until for the life of the initial method called
+void GHash::set_node_parameters(const void* const key)
 {
-    unsigned hashkey;
-    int klen;
-    int index;
-    GHashNode* hnode;
-
-    if (t == nullptr || key == nullptr)
-        return GHASH_ERR;
-
-    /*
-    *   Get proper Key Size
-    */
-    if ( t->keysize > 0  )
-    {
-        klen = t->keysize;
-    }
-    else
-    {
-        /* need the null byte for strcmp() in ghash_find() */
-        klen = strlen( (const char*)key) + 1;
-    }
-
-    hashkey = t->hashfcn->hash_fcn(t->hashfcn, (const unsigned char*)key, klen);
+    klen = ( keysize > 0  ) ? keysize : strlen((const char*)key) + 1;
+    hashkey = hashfcn->hash_fcn(hashfcn, (const unsigned char*)key, klen);
+    index = hashkey % nrows;
+}
 
-    index = hashkey % t->nrows;
+GHashNode* GHash::find_node(const void* const key)
+{
+    assert(key);
 
-    /*
-    *  Uniqueness:
-    *  Check 1st to see if the key is already in the table
-    *  Just bail if it is.
-    */
-    for ( hnode=t->table[index]; hnode; hnode=hnode->next )
+    set_node_parameters(key);
+    for ( GHashNode* hnode = table[index]; hnode; hnode = hnode->next )
     {
-        if ( t->keysize > 0 )
+        if ( keysize == 0 )
         {
-            if ( !t->hashfcn->keycmp_fcn(hnode->key,key,klen) )
-            {
-                t->cnode = hnode; /* save pointer to the node */
-                return GHASH_INTABLE; /* found it */
-            }
+            if ( !strcmp((const char*)hnode->key, (const char*)key) )
+                return hnode;
         }
         else
         {
-            if ( !strcmp((const char*)hnode->key,(const char*)key) )
-            {
-                t->cnode = hnode; /* save pointer to the node */
-                return GHASH_INTABLE; /* found it */
-            }
+            if ( hashfcn->keycmp_fcn(hnode->key, key, keysize) )
+                return hnode;
         }
     }
 
-    /*
-    *  Create new node
-    */
-    hnode = (GHashNode*)snort_calloc(sizeof(GHashNode));
+    return nullptr;
+}
+
+int GHash::insert(const void* const key, void* const data)
+{
+    assert(key && data);
+
+    if ( GHashNode* hnode = find_node(key) )
+    {
+        cnode = hnode;
+        return GHASH_INTABLE;
+    }
 
-    /* Add the Key */
-    if ( t->userkey )
+    GHashNode* hnode = (GHashNode*)snort_calloc(sizeof(GHashNode));
+    if ( userkey )
     {
-        /* Use the Users key */
         hnode->key = key;
     }
     else
     {
-        /* Create new key */
         hnode->key = snort_alloc(klen);
-
-        /* Copy key  */
-        memcpy(const_cast<void*>(hnode->key),key,klen);
+        memcpy(const_cast<void*>(hnode->key), key, klen);
     }
 
-    /* Add The Node */
-    if ( t->table[index] ) /* add the node to the existing list */
-    {
-        hnode->prev = nullptr;  // insert node as head node
-        hnode->next=t->table[index];
-        hnode->data=data;
-        t->table[index]->prev = hnode;
-        t->table[index] = hnode;
-    }
-    else /* 1st node in this list */
+    if ( table[index] )
     {
-        hnode->prev=nullptr;
-        hnode->next=nullptr;
-        hnode->data=data;
-        t->table[index] = hnode;
-    }
-
-    t->count++;
-
-    return GHASH_OK;
-}
-
-/*
-*  Find a Node based on the key, return users data.
-*/
-static GHashNode* ghash_find_node(GHash* t, const void* const key)
-{
-    unsigned hashkey;
-    int index, klen;
-    GHashNode* hnode;
-
-    assert(t);
-
-    if ( t->keysize  )
-    {
-        klen = t->keysize;
+        hnode->prev = nullptr;
+        hnode->next = table[index];
+        hnode->data = data;
+        table[index]->prev = hnode;
+        table[index] = hnode;
     }
     else
     {
-        klen = strlen( (const char*)key) + 1;
+        hnode->prev = nullptr;
+        hnode->next = nullptr;
+        hnode->data = data;
+        table[index] = hnode;
     }
 
-    hashkey = t->hashfcn->hash_fcn(t->hashfcn, (const unsigned char*)key, klen);
-
-    index = hashkey % t->nrows;
+    count++;
 
-    for ( hnode=t->table[index]; hnode; hnode=hnode->next )
-    {
-        if ( t->keysize == 0 )
-        {
-            if ( !strcmp((const char*)hnode->key,(const char*)key) )
-            {
-                return hnode;
-            }
-        }
-        else
-        {
-            if ( !t->hashfcn->keycmp_fcn(hnode->key,key,t->keysize) )
-            {
-                return hnode;
-            }
-        }
-    }
-
-    return nullptr;
+    return GHASH_OK;
 }
 
-/*
-*  Find a Node based on the key, return users data.
-*/
-void* ghash_find(GHash* t, const void* const key)
+void* GHash::find(const void* const key)
 {
-    GHashNode* hnode;
-
-    assert(t);
-
-    hnode = ghash_find_node(t, key);
+    assert(key);
 
+    GHashNode* hnode = find_node(key);
     if ( hnode )
         return hnode->data;
 
     return nullptr;
 }
 
-/*
-*  Unlink and free the node
-*/
-static int ghash_free_node(GHash* t, unsigned index, GHashNode* hnode)
+int GHash::free_node(unsigned index, GHashNode* hnode)
 {
-    assert(t);
+    assert(hnode);
 
-    if ( !t->userkey && hnode->key )
+    if ( !userkey && hnode->key )
         snort_free(const_cast<void*>(hnode->key));
 
     hnode->key = nullptr;
 
-    if ( t->userfree)
-        t->userfree(hnode->data);  /* free users data, with users function */
+    if ( userfree)
+        userfree(hnode->data);
 
-    if ( hnode->prev )  // not the 1st node
+    if ( hnode->prev )
     {
         hnode->prev->next = hnode->next;
         if ( hnode->next )
             hnode->next->prev = hnode->prev;
     }
-    else if ( t->table[index] )  // 1st node
+    else if ( table[index] )
     {
-        t->table[index] = t->table[index]->next;
-        if ( t->table[index] )
-            t->table[index]->prev = nullptr;
+        table[index] = table[index]->next;
+        if ( table[index] )
+            table[index]->prev = nullptr;
     }
 
     snort_free(hnode);
-
-    t->count--;
+    count--;
 
     return GHASH_OK;
 }
 
-/*
-*  Remove a Key/Data Pair from the table - find it, unlink it, and free the memory for it.
-*
-*  returns : 0 - OK
-*           -1 - node not found
-*/
-int ghash_remove(GHash* t, const void* const key)
+int GHash::remove(const void* const key)
 {
-    GHashNode* hnode;
-    int klen;
-    unsigned hashkey, index;
-
-    assert(t);
+    assert(key);
 
-    if ( t->keysize > 0 )
-    {
-        klen = t->keysize;
-    }
+    if ( GHashNode* hnode = find_node(key) )
+        return free_node(index, hnode);
     else
-    {
-        klen = strlen((const char*)key) + 1;
-    }
-
-    hashkey = t->hashfcn->hash_fcn(t->hashfcn, (const unsigned char*)key, klen);
-
-    index = hashkey % t->nrows;
-
-    for ( hnode=t->table[index]; hnode; hnode=hnode->next )
-    {
-        if ( t->keysize > 0 )
-        {
-            if ( !t->hashfcn->keycmp_fcn(hnode->key,key,klen) )
-            {
-                return ghash_free_node(t, index, hnode);
-            }
-        }
-        else
-        {
-            if ( !strcmp((const char*)hnode->key,(const char*)key) )
-            {
-                return ghash_free_node(t, index, hnode);
-            }
-        }
-    }
-
-    return GHASH_ERR;
+        return GHASH_NOT_FOUND;
 }
 
-/* Internal use only */
-static void ghash_next(GHash* t)
+void GHash::next()
 {
-    assert(t and t->cnode);
+    assert(cnode);
 
-    /* Next node in current node list */
-    t->cnode = t->cnode->next;
-    if ( t->cnode )
-    {
+    cnode = cnode->next;
+    if ( cnode )
         return;
-    }
 
-    /* Next row
-       Get 1st node in next non-empty row/node list */
-    for ( t->crow++; t->crow < t->nrows; t->crow++ )
+    for ( crow++; crow < nrows; crow++ )
     {
-        t->cnode = t->table[ t->crow ];
-        if ( t->cnode )
-        {
+        cnode = table[crow];
+        if ( cnode )
             return;
-        }
     }
 }
 
-/*
-*   Get First Hash Table Node
-*/
-GHashNode* ghash_findfirst(GHash* t)
+GHashNode* GHash::find_first()
 {
-    GHashNode* n;
-
-    assert(t);
-    /* Start with 1st row */
-    for ( t->crow=0; t->crow < t->nrows; t->crow++ )
+    for ( crow = 0; crow < nrows; crow++ )
     {
-        /* Get 1st Non-Null node in row list */
-        t->cnode = t->table[ t->crow ];
-
-        if ( t->cnode )
+        cnode = table[crow];
+        if ( cnode )
         {
-            n = t->cnode;
-
-            ghash_next(t); // load t->cnode with the next entry
-
+            GHashNode* n = cnode;
+            next();
             return n;
         }
     }
     return nullptr;
 }
 
-/*
-*   Get Next Hash Table Node
-*/
-GHashNode* ghash_findnext(GHash* t)
+GHashNode* GHash::find_next()
 {
-    GHashNode* n;
-
-    assert(t);
-
-    n = t->cnode;
-
-    if ( !n ) /* Done, no more entries */
-    {
-        return nullptr;
-    }
-
-    /*
-       Preload next node into current node
-    */
-    ghash_next(t);
+    GHashNode* n = cnode;
+    if ( n )
+        next();
 
     return n;
 }
 
-/**
- * Make hashfcn use a separate set of opcodes for the backend.
- *
- * @param h hashfcn ptr
- * @param hash_fcn user specified hash function
- * @param keycmp_fcn user specified key comparison function
- */
-int ghash_set_keyops(GHash* h,
-    unsigned (* hash_fcn)(HashFnc* p, const unsigned char* d, int n),
-    int (* keycmp_fcn)(const void* s1, const void* s2, size_t n))
+void GHash::set_key_opcodes(hash_func hash_fcn, keycmp_func keycmp_fcn)
 {
-    assert(h && hash_fcn && keycmp_fcn);
-
-    return hashfcn_set_keyops(h->hashfcn, hash_fcn, keycmp_fcn);
+    hashfcn_set_keyops(hashfcn, hash_fcn, keycmp_fcn);
 }
+
 }
index ec60793446852b623ed896ca3f6b3fe9d867a313..17b874e74ed444d12377c63961e73316f032982c 100644 (file)
 
 #include "main/snort_types.h"
 
-struct HashFnc;
+#include "hashfcn.h"
 
 namespace snort
 {
-
-#define GHASH_NOMEM    (-2)
-#define GHASH_ERR      (-1)
+#define GHASH_NOT_FOUND      (-1)
 #define GHASH_OK        0
 #define GHASH_INTABLE   1
 
-// Flags for ghash_new: userkeys
-#define GH_COPYKEYS 0
-#define GH_USERKEYS 1
-
 struct GHashNode
 {
-    struct GHashNode* next, * prev;
-
+    struct GHashNode* next;
+    struct GHashNode* prev;
     const void* key;  /* Copy of, or Pointer to, the Users key */
     void* data;       /* The users data, this is never copied! */
 };
 
 typedef void (* gHashFree)(void*);
 
-struct GHash
+class SO_PUBLIC GHash
 {
-    HashFnc* hashfcn;
-    int keysize;          /* bytes in key, if < 0 -> keys are strings */
-    int userkey;          /* user owns the key */
-
-    GHashNode** table; /* array of node ptr's */
-    int nrows;            /* # rows int the hash table use a prime number 211, 9871 */
-
-    unsigned count;       /* total # nodes in table */
-
+public:
+    GHash(int nrows, unsigned keysize, bool userkey, gHashFree);
+    ~GHash();
+
+    int insert(const void* const key, void* const data);
+    int remove(const void* const key);
+    void* find(const void* const key);
+    GHashNode* find_first();
+    GHashNode* find_next();
+    void set_key_opcodes(hash_func, keycmp_func);
+
+    unsigned get_count() const
+    { return count; }
+
+private:
+    void set_node_parameters(const void* const key);
+    GHashNode* find_node(const void* const key);
+    int free_node(unsigned index, GHashNode*);
+    void next();
+
+    unsigned keysize;     // bytes in key, if < 0 -> keys are strings
+    bool userkey;          // user owns the key */
     gHashFree userfree;
-
-    int crow;             /* findfirst/next row in table */
-    GHashNode* cnode;  /* findfirst/next node ptr */
+    int nrows;            // # rows int the hash table use a prime number 211, 9871
+    HashFnc* hashfcn;
+    GHashNode** table;    // array of node ptr's
+    unsigned count;       // total # nodes in table
+    int crow;             // findfirst/next row in table
+    GHashNode* cnode;     // findfirst/next node ptr
+
+    // node parameters for search/add/remove
+    unsigned klen = 0;
+    unsigned hashkey = 0;
+    int index = 0;
 };
 
-SO_PUBLIC GHash* ghash_new(int nrows, int keysize, int userkeys, gHashFree);
-SO_PUBLIC void ghash_delete(GHash*);
-SO_PUBLIC int ghash_add(GHash*, const void* const key, void* const data);
-SO_PUBLIC int ghash_remove(GHash*, const void* const key);
-SO_PUBLIC void* ghash_find(GHash*, const void* const key);
-SO_PUBLIC GHashNode* ghash_findfirst(GHash*);
-SO_PUBLIC GHashNode* ghash_findnext(GHash*);
-SO_PUBLIC int ghash_set_keyops(GHash*,
-unsigned (* hash_fcn)(HashFnc* p, const unsigned char* d, int n),
-int (* keycmp_fcn)(const void* s1, const void* s2, size_t n));
+
 }
 #endif
 
diff --git a/src/hash/hash_defs.h b/src/hash/hash_defs.h
new file mode 100644 (file)
index 0000000..f66f164
--- /dev/null
@@ -0,0 +1,49 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2019-2020 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+// hash_defs.h author davis mcpherson davmcphe@cisco.com>
+
+#ifndef HASH_DEFS_H
+#define HASH_DEFS_H
+
+#include "main/snort_types.h"
+#include "utils/sfmemcap.h"
+
+#include "hashfcn.h"
+
+namespace snort
+{
+#define HASH_NOMEM    (-2)
+#define HASH_ERR      (-1)
+#define HASH_OK        0
+#define HASH_INTABLE   1
+#define HASH_PENDING   2
+
+struct HashNode
+{
+    struct HashNode* gnext; // global node list - used for aging nodes
+    struct HashNode* gprev;
+    struct HashNode* next;  // row node list
+    struct HashNode* prev;
+    int rindex;     // row index of table this node belongs to.
+    void* key;      // Pointer to the key.
+    void* data;     // Pointer to the users data, this is not copied !
+};
+
+typedef int (* Hash_FREE_FCN)(void* key, void* data);
+}
+#endif
index 44990dfeac03d9c0145c18ca2b47b1be49888d8a..12b73a49569ae7967cb17b5b68ba753edb8728e4 100644 (file)
@@ -20,9 +20,8 @@
 /*
      hashfcn.c
 
-     Each hash table must allocate it's own GHash struct, this is because
-     ghash_new uses the number of rows in the hash table to modulo the random
-     values.
+     Each hash table allocates it's own GHash struct, using the number of
+     rows in the hash table to modulo the random values.
 
      Updates:
 
@@ -35,6 +34,8 @@
 
 #include "hashfcn.h"
 
+#include <cassert>
+
 #include "main/snort_config.h"
 #include "utils/util.h"
 
 
 using namespace snort;
 
+static bool hashfcn_key_compare(const void* k1, const void* k2, size_t len)
+{
+    if ( memcmp(k1, k2, len ) == 0 )
+        return true;
+    else
+        return false;
+}
+
 HashFnc* hashfcn_new(int m)
 {
     HashFnc* p;
-    static int one=1;
+    static int one = 1;
 
     if ( one ) /* one time init */
     {
@@ -63,13 +72,13 @@ HashFnc* hashfcn_new(int m)
     }
     else
     {
-        p->seed     = nearest_prime( (rand()%m)+3191);
-        p->scale    = nearest_prime( (rand()%m)+709);
+        p->seed = nearest_prime( (rand() % m) + 3191);
+        p->scale = nearest_prime( (rand() % m) + 709);
         p->hardener = ((unsigned) rand() * rand()) + 133824503;
     }
 
-    p->hash_fcn   = &hashfcn_hash;
-    p->keycmp_fcn = &memcmp;
+    p->hash_fcn = &hashfcn_hash;
+    p->keycmp_fcn = &hashfcn_key_compare;
 
     return p;
 }
@@ -99,26 +108,17 @@ unsigned hashfcn_hash(HashFnc* p, const unsigned char* d, int n)
  * @param hash_fcn user specified hash function
  * @param keycmp_fcn user specified key comparison function
  */
-int hashfcn_set_keyops(HashFnc* h,
-    unsigned (* hash_fcn)(HashFnc* p, const unsigned char* d, int n),
-    int (* keycmp_fcn)(const void* s1, const void* s2, size_t n))
+void hashfcn_set_keyops(HashFnc* h, hash_func hash_fcn, keycmp_func keycmp_fcn)
 {
-    if (h && hash_fcn && keycmp_fcn)
-    {
-        h->hash_fcn   = hash_fcn;
-        h->keycmp_fcn = keycmp_fcn;
+    assert(h && hash_fcn && keycmp_fcn);
 
-        return 0;
-    }
-
-    return -1;
+    h->hash_fcn = hash_fcn;
+    h->keycmp_fcn = keycmp_fcn;
 }
 
 namespace snort
 {
-void mix_str(
-    uint32_t& a, uint32_t& b, uint32_t& c,
-    const char* s, unsigned n)
+void mix_str(uint32_t& a, uint32_t& b, uint32_t& c, const char* s, unsigned n)
 {
     unsigned i, j;
 
@@ -134,9 +134,7 @@ void mix_str(
             k=4;
 
         for (unsigned l=0; l<k; l++)
-        {
             tmp |= (unsigned char) s[i + l] << l*8;
-        }
 
         switch (j)
         {
@@ -160,9 +158,7 @@ void mix_str(
     }
 
     if (j != 0)
-    {
         mix(a,b,c);
-    }
 }
 
 uint32_t str_to_hash(const uint8_t *str, size_t length)
index 388d3b1569916d2ac4666c11ca3968e3254bae28..ad56634049eac6deacc3ee269a38c9354ee68f4d 100644 (file)
@@ -54,28 +54,37 @@ SO_PUBLIC void mix_str(
     const char* s, unsigned n = 0);
 
 SO_PUBLIC uint32_t str_to_hash(const uint8_t *str, size_t length);
+
+static inline int hash_nearest_power_of_2(int nrows)
+{
+    nrows -= 1;
+    for (unsigned i = 1; i < sizeof(nrows) * 8; i <<= 1)
+        nrows = nrows | (nrows >> i);
+    nrows += 1;
+
+    return nrows;
+}
+
 }
 
+struct HashFnc;
+
+typedef uint32_t (* hash_func)(HashFnc*, const unsigned char* d, int n);
+typedef bool (* keycmp_func)(const void* s1, const void* s2, size_t n);
+
 struct HashFnc
 {
     unsigned seed;
     unsigned scale;
     unsigned hardener;
-    // FIXIT-H use types for these callbacks
-    unsigned (* hash_fcn)(HashFnc*, const unsigned char* d, int n);
-    int (* keycmp_fcn)(const void* s1, const void* s2, size_t n);
+    hash_func hash_fcn;
+    keycmp_func keycmp_fcn;
 };
 
 HashFnc* hashfcn_new(int nrows);
 void hashfcn_free(HashFnc*);
-
 unsigned hashfcn_hash(HashFnc*, const unsigned char* d, int n);
-
-int hashfcn_set_keyops(
-    HashFnc*,
-    // FIXIT-H use types for these callbacks
-    unsigned (* hash_fcn)(HashFnc* p, const unsigned char* d, int n),
-    int (* keycmp_fcn)(const void* s1, const void* s2, size_t n));
+void hashfcn_set_keyops(HashFnc*, hash_func, keycmp_func);
 
 #endif
 
index fc1dd044f94464a98038307dded53ea2bc9a7115..c1175a9cc98fa9ac337b063be4e2d7d6b3c068d9 100644 (file)
@@ -63,14 +63,14 @@ TEST(ghash, create_find_delete_test)
     int num=100;
 
     // Create a Hash Table
-    GHash* t = ghash_new(1000, 0, GH_COPYKEYS, nullptr);
+    GHash* t = new GHash(1000, 0, false, nullptr);
 
     // Add Nodes to the Hash Table
     for (i=0; i<num; i++)
     {
         snprintf(str, sizeof(str), "KeyWord%d",i+1);
         str[sizeof(str) - 1] = '\0';
-        ghash_add(t, str, (void *)(str + (i+1)));
+        t->insert(str, (void *)(str + (i+1)));
     }
 
     // find those nodes
@@ -79,20 +79,20 @@ TEST(ghash, create_find_delete_test)
         snprintf(str, sizeof(str), "KeyWord%d",i+1);
         str[sizeof(str) - 1] = '\0';
 
-        char* p = (char*)ghash_find(t, str);
+        char* p = (char*)t->find(str);
 
         CHECK(p != nullptr);
         CHECK(p == (void *)(str + (i+1)));
     }
 
-    for (GHashNode* n = ghash_findfirst(t); n; n = ghash_findnext(t) )
+    for (GHashNode* n = t->find_first(); n; n = t->find_next() )
     {
-        i = ghash_remove(t,n->key);
+        i = t->remove(n->key);
 
         CHECK(i==0);
     }
 
-    ghash_delete(t);
+    delete t;
 }
 
 // test to generate collisions and increase test code coverage
@@ -103,7 +103,7 @@ TEST(ghash, collision_test)
     int num=100;
 
     // Create a Hash Table with smaller entries
-    GHash* t = ghash_new(-10, 0, GH_COPYKEYS, nullptr);
+    GHash* t = new GHash(-10, 0, false, nullptr);
 
     CHECK(t != nullptr);
 
@@ -112,13 +112,13 @@ TEST(ghash, collision_test)
     {
         snprintf(str, sizeof(str), "KeyWord%d",i+1);
         str[sizeof(str) - 1] = '\0';
-        ghash_add(t, str, (void *)(str + (i+1)));
+        t->insert(str, (void *)(str + (i+1)));
     }
 
     // try to add an existed entry
     snprintf(str, sizeof(str), "KeyWord%d",1);
     str[sizeof(str) - 1] = '\0';
-    i = ghash_add(t, str, (void *)(str + (1)));
+    i = t->insert(str, (void *)(str + (1)));
     CHECK(i == GHASH_INTABLE);
 
     // find those nodes
@@ -127,31 +127,31 @@ TEST(ghash, collision_test)
         snprintf(str, sizeof(str), "KeyWord%d",i+1);
         str[sizeof(str) - 1] = '\0';
 
-        char* p = (char*)ghash_find(t, str);
+        char* p = (char*)t->find(str);
 
         CHECK(p != nullptr);
         CHECK(p == (void *)(str + (i+1)));
     }
 
     // remove one node
-    GHashNode* n = ghash_findfirst(t);
+    GHashNode* n = t->find_first();
     if (n)
     {
-        n = ghash_findnext(t);
-        i = ghash_remove(t,n->key);
+        n = t->find_next();
+        i = t->remove(n->key);
 
         CHECK(i==0);
     }
 
     // remove rest of nodes
-    for ( n = ghash_findfirst(t); n; n = ghash_findnext(t) )
+    for ( n = t->find_first(); n; n = t->find_next() )
     {
-        i = ghash_remove(t,n->key);
+        i = t->remove(n->key);
 
         CHECK(i==0);
     }
 
-    ghash_delete(t);
+    delete t;
 }
 
 TEST(ghash, userfree_test)
@@ -160,7 +160,7 @@ TEST(ghash, userfree_test)
     int i;
 
     // Create a small Hash Table with user free
-    GHash* t = ghash_new(-5, 0, GH_COPYKEYS, myfree);
+    GHash* t = new GHash(-5, 0, false, myfree);
     // add 5 nodes
     for (i=0; i<5; i++)
     {
@@ -169,7 +169,7 @@ TEST(ghash, userfree_test)
         char* p = (char*)snort_alloc(32);
         p[0] = (char)(i+1);
         p[1] = '\0';
-        ghash_add(t, str, (void *)p);
+        t->insert(str, (void *)p);
     }
 
     // find those nodes
@@ -178,7 +178,7 @@ TEST(ghash, userfree_test)
         snprintf(str, sizeof(str), "KeyWord%d",i+1);
         str[sizeof(str) - 1] = '\0';
 
-        char *p = (char*)ghash_find(t, str);
+        char *p = (char*)t->find(str);
 
         CHECK(p != nullptr);
         CHECK(p[0] == (i+1));
@@ -189,26 +189,20 @@ TEST(ghash, userfree_test)
     str[sizeof(str) - 1] = '\0';
 
     // it should not be found
-    CHECK(ghash_find(t, str) == nullptr);
-
+    CHECK(t->find(str) == nullptr);
+    
     // try to remove a node that is not in the table
-    CHECK(ghash_remove(t, str) == GHASH_ERR);
+    CHECK(t->remove( str) == GHASH_NOT_FOUND);
 
-    for ( GHashNode* n = ghash_findfirst(t); n; n = ghash_findnext(t) )
+    for ( GHashNode* n = t->find_first(); n; n = t->find_next() )
     {
         // user free should be called here, no memory leak should be detected
-        i = ghash_remove(t,n->key);
+        i = t->remove(n->key);
 
         CHECK(i==0);
     }
 
-    ghash_delete(t);
-}
-
-TEST(ghash, nullptr_test)
-{
-    CHECK(GHASH_ERR == ghash_add(nullptr, nullptr, nullptr));
-    ghash_delete(nullptr);
+    delete t;
 }
 
 int main(int argc, char** argv)
index f83edbd7e086dcadaacd9674727d4a54815abacd..a52a4d92d8ec7efab3eb5b504d1775af805fd313 100644 (file)
@@ -56,175 +56,86 @@ TEST_GROUP(xhash)
 //  Test create a hash table, add nodes, find and delete.
 TEST(xhash, create_xhash_test)
 {
-    XHash* test_table = xhash_new(4, sizeof(struct xhash_test_key),
-                                  0, 0, 0, nullptr, nullptr, 0);
-    CHECK(test_table->keysize == sizeof(struct xhash_test_key));
-    xhash_delete(test_table);
-}
+    XHash* test_table = new XHash(4, sizeof(struct xhash_test_key),
+                                  0, 0, false, nullptr, nullptr, false);
+    CHECK(test_table->get_keysize() == sizeof(struct xhash_test_key));
 
-// Test verifies if free_anr_lru_function() throws error on invalid table
-TEST(xhash, free_anr_lru_invalid_test)
-{
-    int ret = xhash_free_anr_lru(nullptr);
-    CHECK(ret == XHASH_ERR);
+    void* data = test_table->get_mru_user_data();
+    CHECK(data == nullptr);
+
+    for (unsigned i = 1; i <= 4; i++)
+    {
+        xhash_test_key xtk;
+        xtk.key = 10 * i;
+        int ret = test_table->insert(&xtk, nullptr);
+        CHECK(ret == HASH_OK);
+    }
+
+    xhash_test_key xtk;
+    xtk.key = 10;
+    HashNode* xnode = test_table->find_node(&xtk);
+    CHECK(xnode != nullptr);
+    int ret = test_table->release_node(xnode);
+    CHECK(ret == HASH_OK);
+
+    delete test_table;
 }
 
 // Create a free node in xhash and verifies if xhash_free_anr_lru() deletes it
 TEST(xhash, free_anr_lru_delete_free_node_test)
 {
-    XHash* test_table = xhash_new(3, sizeof(struct xhash_test_key),
-                                  1, 1040, 0, nullptr, nullptr, 1);
+    XHash* test_table = new XHash(3, sizeof(struct xhash_test_key),
+                                  1, 1040, false, nullptr, nullptr, true);
     xhash_test_key xtk;
     xtk.key = 10;
-    int ret = xhash_add(test_table, &xtk, nullptr);
-    CHECK(ret == XHASH_OK);
+    int ret = test_table->insert(&xtk, nullptr);
+    CHECK(ret == HASH_OK);
 
-    XHashNode *xnode = xhash_get_node(test_table, &xtk);
+     HashNode* xnode = test_table->get_node(&xtk);
     CHECK(xnode != nullptr);
 
-    ret = xhash_free_node(test_table, xnode);
-    CHECK(ret == XHASH_OK);
+    ret = test_table->release_node(xnode);
+    CHECK(ret == HASH_OK);
 
-    ret = xhash_free_anr_lru(test_table);
-    CHECK(ret == XHASH_OK);
+    ret = test_table->delete_anr_or_lru_node();
+    CHECK(ret == HASH_OK);
 
-    XHashNode* xhnode = xhash_find_node(test_table, &xtk);
+    HashNode* xhnode = test_table->find_node(&xtk);
     CHECK(xhnode == nullptr);
-    xhash_delete(test_table);
+
+    delete test_table;
 }
 
 // No free node is available, verifies if xhash_free_anr_lru() deletes the last node
 TEST(xhash, free_anr_lru_delete_tail_node_test)
 {
-    XHash* test_table = xhash_new(3, sizeof(struct xhash_test_key),
-                                  1, 1040, 0, nullptr, nullptr, 1);
+    XHash* test_table = new XHash(3, sizeof(struct xhash_test_key),
+                                  1, 1040, false, nullptr, nullptr, true);
     xhash_test_key xtk;
-    int ret = xhash_add(test_table, &xtk, nullptr);
-    CHECK(ret == XHASH_OK);
+    int ret = test_table->insert(&xtk, nullptr);
+    CHECK(ret == HASH_OK);
 
-    XHashNode* orig_gtail = test_table->gtail;
-    ret = xhash_free_anr_lru(test_table);
-    CHECK(ret == XHASH_OK);
-    CHECK(orig_gtail != test_table->gtail);
+    ret = test_table->delete_anr_or_lru_node();
+    CHECK(ret == HASH_OK);
 
-    xhash_delete(test_table);
+    HashNode* xhnode = test_table->find_node(&xtk);
+    CHECK(xhnode == nullptr);
+
+    delete test_table;
 }
 
 // No free node is available [recycle is not enabled], verifies if last node is deleted
 TEST(xhash, free_anr_lru_usr_free_delete_tail_node_test)
 {
-    XHash* test_table = xhash_new(3, sizeof(struct xhash_test_key),
-                                  1, 1040, 0, nullptr, nullptr, 0);
-    xhash_test_key xtk;
-    int ret = xhash_add(test_table, &xtk, nullptr);
-    CHECK(ret == XHASH_OK);
-
-    XHashNode* orig_gtail = test_table->gtail;
-    ret = xhash_free_anr_lru(test_table);
-    CHECK(ret == XHASH_OK);
-    CHECK(orig_gtail != test_table->gtail);
-    xhash_delete(test_table);
-}
-
-// if new memcap is same as old memcap, do nothing
-TEST(xhash, change_memcap_same_memcap_test)
-{
-    XHash* test_table = xhash_new(5, sizeof(struct xhash_test_key),
-                                  0, 80, 0, nullptr, nullptr, 1);
-    unsigned max_work = 0;
-    int ret = xhash_change_memcap(test_table, 80, &max_work);
-    CHECK(ret == XHASH_OK);
-    CHECK(test_table->mc.memcap == 80);
-    xhash_delete(test_table);
-}
-
-// if new memcap is more than old memcap, only change the memcap
-TEST(xhash, change_memcap_more_memcap_test)
-{
-    XHash* test_table = xhash_new(5, sizeof(struct xhash_test_key),
-                                  0, 80, 0, nullptr, nullptr, 1);
-
-    unsigned max_work = 0;
-    int ret = xhash_change_memcap(test_table, 100, &max_work);
-    CHECK(ret == XHASH_OK);
-    CHECK(test_table->mc.memcap == 100);
-    xhash_delete(test_table);
-}
-
-// IF new memcap is is less than overhead bytes, throw an error
-TEST(xhash, change_memcap_less_than_overhead_memcap_test)
-{
-    XHash* test_table = xhash_new(5, sizeof(struct xhash_test_key),
-                                  0, 80, 0, nullptr, nullptr, 1);
-
-    unsigned max_work = 0;
-    int ret = xhash_change_memcap(test_table, test_table->overhead_bytes-1, &max_work);
-    CHECK(ret == XHASH_ERR);
-    CHECK(test_table->mc.memcap == 80);
-    xhash_delete(test_table);
-}
-
-//if new memcap is less than used memcap, do the pruning
-TEST(xhash, xhash_change_memcap_less_than_used_test)
-{
-    XHash* test_table = xhash_new(3, sizeof(struct xhash_test_key),
-                                  1, 1040, 0, nullptr, nullptr, 1);
-    xhash_test_key xtk[2];
-    int ret = xhash_add(test_table, &xtk[0], nullptr);
-    CHECK(ret == XHASH_OK);
-
-    xtk[1].key = 100;
-    ret = xhash_add(test_table, &xtk[1], nullptr);
-    CHECK(ret == XHASH_OK);
-
-    unsigned max_work = 0;
-    unsigned new_memcap = test_table->mc.memused-1;
-    ret = xhash_change_memcap(test_table, new_memcap, &max_work);
-    CHECK(ret == XHASH_OK);
-    CHECK(test_table->mc.memcap == new_memcap);
-    xhash_delete(test_table);
-}
-
-// new memcap is less than old memcap and cannot prune
-TEST(xhash, xhash_change_memcap_nofree_nodes_test)
-{
-    XHash* test_table = xhash_new(3, sizeof(struct xhash_test_key),
-                                  1, 1040, 0, nullptr, nullptr, 0);
+    XHash* test_table = new XHash(3, sizeof(struct xhash_test_key),
+                                  1, 1040, false, nullptr, nullptr, false);
     xhash_test_key xtk;
+    int ret = test_table->insert(&xtk, nullptr);
+    CHECK(ret == HASH_OK);
 
-    int ret = xhash_add(test_table, &xtk, nullptr);
-    CHECK(ret == XHASH_OK);
-    unsigned new_memcap = test_table->mc.memused-1;
-
-
-    unsigned max_work = 0;
-    test_table->gtail = nullptr;
-    ret = xhash_change_memcap(test_table, new_memcap, &max_work);
-    CHECK(ret == XHASH_NOMEM);
-    xhash_delete(test_table);
-}
-
-// new memcap is less than old memcap and max_work is than needed
-TEST(xhash, xhash_change_memcap_less_max_work_test)
-{
-    XHash* test_table = xhash_new(3, sizeof(struct xhash_test_key),
-                                  142, 1040, 0, nullptr, nullptr, 0);
-    xhash_test_key xtk;
-
-    int ret = xhash_add(test_table, &xtk, nullptr);
-    CHECK(ret == XHASH_OK);
-    unsigned new_memcap = test_table->mc.memused-1;
-
-    xhash_test_key xtk1;
-    xtk1.key = 100;
-    ret = xhash_add(test_table, &xtk1, nullptr);
-    CHECK(ret == XHASH_OK);
-
-    unsigned max_work = 1;
-    ret = xhash_change_memcap(test_table, new_memcap, &max_work);
-    CHECK(ret == XHASH_PENDING);
-    CHECK(max_work == 0);
-    xhash_delete(test_table);
+    ret = test_table->delete_anr_or_lru_node();
+    CHECK(ret == HASH_OK);
+    delete test_table;
 }
 
 int main(int argc, char** argv)
index 98ea27ae3b1fb6e3ae137483f96fbc3fe8830bf3..bcca7c412cba7fe7e670d4f8f753a88b4e8ea114 100644 (file)
@@ -16,8 +16,7 @@
 // with this program; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
-
-/* sfxhash.c
+/* xhash.cc
  *
  *  A Customized hash table library for storing and accessing key + data pairs.
  *
@@ -53,7 +52,7 @@
  *
  *  Per Node Memory Usage:
  *  ----------------------
- *     XHashNode bytes
+ *     HashNode bytes
  *     KEYSIZE bytes
  *     [DATASIZE bytes] if datasize > 0 during call to xhash_new.
  *
 
 #include <cassert>
 #include "utils/util.h"
-#include "hashfcn.h"
 
 using namespace snort;
 
-/*
- * Implements XHash as specialized hash container
- */
-
-/*
-* Private Malloc - abstract the memory system
-*/
-static inline void* s_alloc(XHash* t, int n)
-{
-    return sfmemcap_alloc(&t->mc, n);
-}
-
-static inline void s_free(XHash* t, void* p)
-{
-    sfmemcap_free(&t->mc, p);
-}
-
-static int xhash_nearest_powerof2(int nrows)
-{
-    nrows -= 1;
-    for (unsigned i=1; i<sizeof(nrows) * 8; i <<= 1)
-        nrows = nrows | (nrows >> i);
-    nrows += 1;
-
-    return nrows;
-}
-
 namespace snort
 {
-/*
- * Create a new hash table
- *
- * By default, this will "splay" nodes to the top of a free list.
- *
- * nrows    number of rows in hash table
- * keysize  key size in bytes, same for all keys
- * datasize datasize in bytes, zero indicates user manages data
- * maxmem   maximum memory to use in bytes
- * anr_flag Automatic Node Recovery boolean flag
- * anrfree  users Automatic Node Recovery memory release function
- * usrfree  users standard memory release function
- *
- * return XHash*
- * retval  0 out of memory
- * retval !0 Valid XHash pointer
- */
-/*
-  Notes:
-  if nrows < 0 don't cal the nearest powerof2.
-  datasize must be the same for all entries, unless datasize is zero.
-  maxmem of 0 indicates no memory limits.
-
-*/
-XHash* xhash_new(int nrows, int keysize, int datasize, unsigned long maxmem,
-    int anr_flag,
-    XHash_FREE_FCN anrfree,
-    XHash_FREE_FCN usrfree,
-    int recycle_flag)
-{
-    if ( nrows > 0 ) /* make sure we have a prime number */
-    {
-        /* If nrows is not a power of two, need to find the
-         * next highest power of two */
-        nrows = xhash_nearest_powerof2(nrows);
-    }
-    else   /* use the magnitude of nrows as is */
-    {
-        nrows = -nrows;
-    }
-
-    /* Allocate the table structure from general memory */
-    XHash* h = (XHash*)snort_calloc(sizeof(XHash));
-
-    /* this has a default hashing function */
-    h->hashfcn = hashfcn_new(nrows);
-    sfmemcap_init(&h->mc, maxmem);
-
-    /* Allocate the array of node ptrs */
-    h->table = (XHashNode**)s_alloc(h, sizeof(XHashNode*) * nrows);
 
-    if ( !h->table )
-    {
-        snort_free(h->hashfcn);
-        snort_free(h);
-        return nullptr;
-    }
-
-    for ( int i = 0; i < nrows; i++ )
-        h->table[i] = nullptr;
-
-    h->anrfree  = anrfree;
-    h->usrfree  = usrfree;
-    h->keysize  = keysize;
-
-    h->pad = 0;
-    h->datasize = datasize;
-    h->nrows    = nrows;
-    h->max_nodes = 0;
-    h->crow     = 0;
-    h->cnode    = nullptr;
-    h->count    = 0;
-    h->ghead    = nullptr;
-    h->gtail    = nullptr;
-    h->anr_count= 0;
-    h->anr_tries= 0;
-    h->anr_flag = anr_flag;
-    h->splay    = 1;
-    h->recycle_nodes = recycle_flag;
-
-    h->find_success = 0;
-    h->find_fail    = 0;
-
-    /* save off how much we've already allocated from our memcap */
-    h->overhead_bytes = h->mc.memused;
-    h->overhead_blocks = h->mc.nblocks;
-
-    return h;
-}
-
-/*
- *  Set the maximum nodes used in this hash table.
- *  Specifying 0 is unlimited (or otherwise limited by memcap).
- *
- * h XHash table pointer
- * max_nodes maximum nodes to allow.
- *
- */
-void xhash_set_max_nodes(XHash* h, int max_nodes)
-{
-    if (h)
-    {
-        h->max_nodes = max_nodes;
-    }
-}
-
-/*!
- *  Free all nodes in the free list
- *
- *  Removes and frees all of the nodes in the free list
- *  No need to call the user free, since that should've been
- *  done when those nodes were put back in the free list.
- *
- * h XHash table pointer
- */
-static void xhash_delete_free_list(XHash* t)
+XHash::XHash(int nrows_, int keysize_, int datasize_, unsigned long maxmem,
+    bool anr_enabled, Hash_FREE_FCN anr_free, Hash_FREE_FCN usr_free,
+    bool recycle_nodes)
+    : keysize(keysize_), datasize(datasize_), recycle_nodes(recycle_nodes),
+      anr_enabled(anr_enabled), anr_free(anr_free), usr_free(usr_free)
 {
-    if (t == nullptr || t->fhead == nullptr)
-        return;
-
-    XHashNode* cur = t->fhead;
-    while (cur != nullptr)
-    {
-        XHashNode* next = cur->gnext;
-        s_free(t, (void*)cur);
-        cur = next;
-    }
-
-    t->fhead = nullptr;
-    t->ftail = nullptr;
-}
-
-/*!
- *  Try to change the memcap
- *  Behavior is undefined when t->usrfree is set
- *
- * t             SFXHASH table pointer
- * new_memcap    the new desired memcap
- * max_work      the maximum amount of work for the function to do (0 = do all available work)
- *
- * returns
- * XHASH_OK           when memcap is successfully decreased
- * XHASH_PENDING      when more work needs to be done
- * XHASH_NOMEM        when there isn't enough memory in the hash table
- * XHASH_ERR          when an error has occurred
- */
-int xhash_change_memcap(XHash *t, unsigned long new_memcap, unsigned *max_work)
-{
-    if (t == nullptr or new_memcap < t->overhead_bytes)
-        return XHASH_ERR;
-
-    if (new_memcap == t->mc.memcap)
-        return XHASH_OK;
-
-    if (new_memcap > t->mc.memcap)
-    {
-        t->mc.memcap = new_memcap;
-        return XHASH_OK;
-    }
-
-    unsigned work = 0;
-    while (new_memcap < t->mc.memused
-            and (work < *max_work or *max_work == 0)
-            and (xhash_free_anr_lru(t) == XHASH_OK))
-        work++;
+    // adjust rows to be power of 2
+    if ( nrows_ > 0 )
+        nrows = hash_nearest_power_of_2(nrows_);
+    else
+        nrows = -nrows_;       // if negative use as is
 
-    if (*max_work != 0 and (work == *max_work and new_memcap < t->mc.memused))
-    {
-        *max_work -= work;
-        return XHASH_PENDING;
-    }
+    table = (HashNode**)snort_calloc(sizeof(HashNode*) * nrows);
+    hashfcn = hashfcn_new(nrows);
+    sfmemcap_init(&mc, maxmem);
 
-    //we ran out of nodes to free and there still isn't enough memory
-    //or (we have undefined behavior: t->usrfree is set and xhash_free_anr_lru is returning XHASH_ERR)
-    if (new_memcap < t->mc.memused)
-        return XHASH_NOMEM;
+    for ( unsigned i = 0; i < nrows; i++ )
+        table[i] = nullptr;
 
-    t->mc.memcap = new_memcap;
-    return XHASH_OK;
+    mem_allocated_per_entry = sizeof(HashNode) + keysize + datasize + sizeof(long);
 }
 
-/*!
- *  Delete the hash Table
- *
- *  free keys, free nodes, and free the users data.
- *
- * h XHash table pointer
- *
- */
-void xhash_delete(XHash* h)
+XHash::~XHash()
 {
-    if ( !h )
-        return;
-
-    if ( h->hashfcn )
-        hashfcn_free(h->hashfcn);
+    if ( hashfcn )
+        hashfcn_free(hashfcn);
 
-    if ( h->table )
+    for (unsigned i = 0; i < nrows; i++)
     {
-        for (unsigned i = 0; i < h->nrows; i++)
+        for ( HashNode* node = table[i]; node; )
         {
-            for ( XHashNode* node = h->table[i]; node; )
-            {
-                XHashNode* onode = node;
-                node  = node->next;
+            HashNode* onode = node;
+            node  = node->next;
 
-                /* Notify user that we are about to free this node function */
-                if ( h->usrfree )
-                    h->usrfree(onode->key, onode->data);
+            if ( usr_free )
+                usr_free(onode->key, onode->data);
 
-                s_free(h, onode);
-            }
+            sfmemcap_free(&mc, onode);
         }
-        s_free(h, h->table);
-        h->table = nullptr;
     }
-
-    xhash_delete_free_list(h);
-
-    snort_free(h);   /* free the table from general memory */
+    snort_free(table);
+    purge_free_list();
 }
 
-/*!
- *  Empty out the hash table
- *
- * h XHash table pointer
- *
- * return -1 on error
- */
-int xhash_make_empty(XHash* h)
+void XHash::clear()
 {
-    XHashNode* tmp = nullptr;
-
-    if (h == nullptr)
-        return -1;
-
-    for (unsigned i = 0; i < h->nrows; i++)
+    for (unsigned i = 0; i < nrows; i++)
     {
-        for (XHashNode* n = h->table[i]; n != nullptr; n = tmp)
+        HashNode* n = table[i];
+        while ( n )
         {
-            tmp = n->next;
-            if (xhash_free_node(h, n) != XHASH_OK)
-            {
-                return -1;
-            }
+            HashNode* tmp;
+            tmp = n;
+            n = n->next;
+            release_node(tmp);
         }
     }
 
-    h->max_nodes = 0;
-    h->crow = 0;
-    h->cnode = nullptr;
-    h->count = 0;
-    h->ghead = nullptr;
-    h->gtail = nullptr;
-    h->anr_count = 0;
-    h->anr_tries = 0;
-    h->find_success = 0;
-    h->find_fail = 0;
-
-    return 0;
+    max_nodes = 0;
+    crow = 0;
+    cnode = nullptr;
+    count = 0;
+    ghead = nullptr;
+    gtail = nullptr;
+    anr_count = 0;
+    anr_tries = 0;
+    find_success = 0;
+    find_fail = 0;
 }
 
-/** Save the freed node for later use (recylcing).
- *  Free List - uses the NODE gnext/gprev fields
- */
-static void xhash_save_free_node(XHash* t, XHashNode* hnode)
+void XHash::save_free_node(HashNode* hnode)
 {
-    /* Add A Node to the Free Node List */
-    if ( t->fhead ) /* add the node to head of the the existing list */
+    if ( fhead )
     {
         hnode->gprev    = nullptr;
-        hnode->gnext    = t->fhead;
-        t->fhead->gprev = hnode;
-        t->fhead        = hnode;
-        /* tail is not affected */
+        hnode->gnext    = fhead;
+        fhead->gprev = hnode;
+        fhead        = hnode;
     }
-    else /* 1st node in this list */
+    else
     {
         hnode->gprev = nullptr;
         hnode->gnext = nullptr;
-        t->fhead    = hnode;
-        t->ftail    = hnode;
+        fhead    = hnode;
+        ftail    = hnode;
     }
 }
 
-/**Get a previously freed node for reuse.
- */
-static XHashNode* xhash_get_free_node(XHash* t)
+HashNode* XHash::get_free_node()
 {
-    XHashNode* node = t->fhead;
+    HashNode* node = fhead;
 
-    /* Remove A Node from the Free Node List - remove the head node */
-    if ( t->fhead  )
+    if ( fhead )
     {
-        t->fhead = t->fhead->gnext;
-        if ( t->fhead )
-            t->fhead->gprev = nullptr;
+        fhead = fhead->gnext;
+        if ( fhead )
+            fhead->gprev = nullptr;
 
-        if ( t->ftail  == node ) /* no more nodes - clear the tail */
-            t->ftail  =  nullptr;
+        if ( ftail == node )
+            ftail = nullptr;
     }
 
     return node;
 }
 
-static void xhash_glink_node(XHash* t, XHashNode* hnode)
+void XHash::purge_free_list()
 {
-    /* Add The Node */
-    if ( t->ghead ) /* add the node to head of the the existing list */
+    HashNode* cur = fhead;
+    while ( cur )
     {
-        hnode->gprev    = nullptr;
-        hnode->gnext    = t->ghead;
-        t->ghead->gprev = hnode;
-        t->ghead        = hnode;
-        /* tail is not affected */
+        HashNode* next = cur->gnext;
+        sfmemcap_free(&mc, (void*)cur);
+        cur = next;
     }
-    else /* 1st node in this list */
+
+    fhead = nullptr;
+    ftail = nullptr;
+}
+
+void XHash::glink_node(HashNode* hnode)
+{
+    if ( ghead )
+    {
+        hnode->gprev = nullptr;
+        hnode->gnext = ghead;
+        ghead->gprev = hnode;
+        ghead = hnode;
+    }
+    else
     {
         hnode->gprev = nullptr;
         hnode->gnext = nullptr;
-        t->ghead    = hnode;
-        t->gtail    = hnode;
+        ghead = hnode;
+        gtail = hnode;
     }
 }
 
-static void xhash_gunlink_node(XHash* t, XHashNode* hnode)
+void XHash::gunlink_node(HashNode* hnode)
 {
-    if ( t->gnode == hnode ) /* if this was the global next node */
-    {
-        t->gnode = hnode->gnext;
-    }
+    if ( gnode == hnode )
+        gnode = hnode->gnext;
 
-    /* Remove the Head Node */
-    if ( t->ghead == hnode ) /* add the node to head of the the existing list */
+    if ( ghead == hnode )
     {
-        t->ghead = t->ghead->gnext;
-        if ( t->ghead )
-            t->ghead->gprev = nullptr;
+        ghead = ghead->gnext;
+        if ( ghead )
+            ghead->gprev = nullptr;
     }
 
     if ( hnode->gprev )
@@ -473,77 +254,96 @@ static void xhash_gunlink_node(XHash* t, XHashNode* hnode)
     if ( hnode->gnext )
         hnode->gnext->gprev = hnode->gprev;
 
-    if ( t->gtail  == hnode )
-        t->gtail  =  hnode->gprev;
+    if ( gtail == hnode )
+        gtail = hnode->gprev;
 }
 
-/**Move node to the front of global list. Node movement is application specific.
- */
-void xhash_gmovetofront(XHash* t, XHashNode* hnode)
+void XHash::gmove_to_front(HashNode* hnode)
 {
-    if ( hnode != t->ghead )
+    if ( hnode != ghead )
     {
-        xhash_gunlink_node(t, hnode);
-        xhash_glink_node(t, hnode);
+        gunlink_node(hnode);
+        glink_node(hnode);
     }
 }
 
-/*
- *
- */
-static void xhash_link_node(XHash* t, XHashNode* hnode)
+HashNode* XHash::gfind_next()
+{
+    HashNode* n = gnode;
+    if ( n )
+        gnode = n->gnext;
+    return n;
+}
+
+HashNode* XHash::gfind_first()
+{
+    if ( ghead )
+        gnode = ghead->gnext;
+    else
+        gnode = nullptr;
+    return ghead;
+}
+
+void* XHash::get_mru_user_data()
+{
+    if ( ghead )
+        return ghead->data;
+    else
+        return nullptr;
+}
+
+void* XHash::get_lru_user_data()
+{
+    if ( gtail )
+        return gtail->data;
+    else
+        return nullptr;
+}
+
+void XHash::link_node(HashNode* hnode)
 {
-    /* Add The Node to the Hash Table Row List */
-    if ( t->table[hnode->rindex] ) /* add the node to the existing list */
+    if ( table[hnode->rindex] )
     {
-        hnode->prev = nullptr;  // insert node as head node
-        hnode->next=t->table[hnode->rindex];
-        t->table[hnode->rindex]->prev = hnode;
-        t->table[hnode->rindex] = hnode;
+        hnode->prev = nullptr;
+        hnode->next = table[hnode->rindex];
+        table[hnode->rindex]->prev = hnode;
+        table[hnode->rindex] = hnode;
     }
-    else /* 1st node in this list */
+    else
     {
-        hnode->prev=nullptr;
-        hnode->next=nullptr;
-        t->table[hnode->rindex] = hnode;
+        hnode->prev = nullptr;
+        hnode->next = nullptr;
+        table[hnode->rindex] = hnode;
     }
 }
 
-static void xhash_unlink_node(XHash* t, XHashNode* hnode)
+void XHash::unlink_node(HashNode* hnode)
 {
-    if ( hnode->prev )  // definitely not the 1st node in the list
+    if ( hnode->prev )
     {
         hnode->prev->next = hnode->next;
         if ( hnode->next )
             hnode->next->prev = hnode->prev;
     }
-    else if ( t->table[hnode->rindex] )  // must be the 1st node in the list
+    else if ( table[hnode->rindex] )
     {
-        t->table[hnode->rindex] = t->table[hnode->rindex]->next;
-        if ( t->table[hnode->rindex] )
-            t->table[hnode->rindex]->prev = nullptr;
+        table[hnode->rindex] = table[hnode->rindex]->next;
+        if ( table[hnode->rindex] )
+            table[hnode->rindex]->prev = nullptr;
     }
 }
 
-/*
- *  move a node to the front of the row list at row = 'index'
- */
-static void movetofront(XHash* t, XHashNode* n)
+void XHash::move_to_front(HashNode* n)
 {
-    /* Modify Hash Node Row List */
-    if ( t->table[n->rindex] != n ) // if not at front of list already...
+    if ( table[n->rindex] != n )
     {
-        /* Unlink the node */
-        xhash_unlink_node(t, n);
-
-        /* Link at front of list */
-        xhash_link_node(t, n);
+        unlink_node(n);
+        link_node(n);
     }
 
-    /* Move node in the global hash node list to the front */
-    if (n == t->gnode)
-        t->gnode = n->gnext;
-    xhash_gmovetofront(t, n);
+    if (n == gnode)
+        gnode = n->gnext;
+    gmove_to_front(n);
 }
 
 /*
@@ -556,594 +356,283 @@ static void movetofront(XHash* t, XHashNode* n)
  * to the front of the list. The oldest node is just the tail node.
  *
  */
-static XHashNode* xhash_newnode(XHash* t)
+HashNode* XHash::allocate_node()
 {
-    /* Recycle Old Nodes - if any */
-    XHashNode* hnode = xhash_get_free_node(t);
-
-    /* Allocate memory for a node */
+    // use previously allocated node if there is a free one...
+    HashNode* hnode = get_free_node();
     if ( !hnode )
     {
-        if ((t->max_nodes == 0) || (t->count < t->max_nodes))
-        {
-            hnode = (XHashNode*)s_alloc(t, sizeof(XHashNode) + t->pad +
-                t->keysize + t->datasize);
-        }
-    }
+        if ( (max_nodes == 0) || (count < max_nodes) )
+            hnode = (HashNode*)sfmemcap_alloc(&mc,
+                sizeof(HashNode) + keysize + datasize);
 
-    /*  If we still haven't found hnode, we're at our memory limit.
-     *
-     *  Uses Automatic Node Recovery, to recycle the oldest node-based on access
-     *  (Unlink and reuse the tail node)
-     */
-    if ( !hnode && t->anr_flag && t->gtail )
-    {
-        /* Find the oldest node the users willing to let go. */
-        for (hnode = t->gtail; hnode; hnode = hnode->gprev )
+        if ( !hnode && anr_enabled && gtail )
         {
-            if ( t->anrfree ) /* User has provided a permission+release callback function */
+            /* Find the oldest node the users willing to let go. */
+            for (hnode = gtail; hnode; hnode = hnode->gprev )
             {
-                t->anr_tries++; /* Count # ANR requests */
-
-                /* Ask the user for permission to release this node, but let them say no! */
-                if ( t->anrfree(hnode->key, hnode->data) )
+                if ( anr_free )
                 {
-                    /* NO, don't recycle this node, user's not ready to let it go. */
-                    continue;
+                    anr_tries++;
+                    if ( anr_free(hnode->key, hnode->data) )
+                        continue;   // don't recycle this one...
                 }
 
-                /* YES, user said we can recycle this node */
+                gunlink_node(hnode);
+                unlink_node(hnode);
+                count--;
+                anr_count++;
+                break;
             }
-
-            xhash_gunlink_node(t, hnode);   /* unlink from the global list */
-            xhash_unlink_node(t, hnode);   /* unlink from the row list */
-            t->count--;
-            t->anr_count++; /* count # of ANR operations */
-            break;
         }
     }
 
-    /* either we are returning a node or we're all full and the user
-     * won't let us allocate anymore and we return nullptr */
     return hnode;
 }
 
-/*
- *
- *  Find a Node based on the key, return the node and the index.
- *  The index is valid even if the return value is nullptr, in which
- *  case the index is the correct row in which the node should be
- *  created.
- *
- */
-
-#define hashsize(n) ((uint32_t)1<<(n))
-#define hashmask(n) (hashsize(n)-1)
-
-static XHashNode* xhash_find_node_row(XHash* t, const void* key, int* rindex)
+HashNode* XHash::find_node_row(const void* key, int* rindex)
 {
-    unsigned hashkey = t->hashfcn->hash_fcn(t->hashfcn, (const unsigned char*)key, t->keysize);
+    unsigned hashkey = hashfcn->hash_fcn(hashfcn, (const unsigned char*)key, keysize);
 
-/*     printf("hashkey: %u t->keysize: %d\n", hashkey, t->keysize);
-       flowkey_fprint(stdout, key);
-       printf("****\n"); */
-
-//     index   = hashkey % t->nrows;
-    /* Modulus is slow. Switched to a table size that is a power of 2. */
-    int index  = hashkey & (t->nrows - 1);
+    // Modulus is slow. masking since table size is a power of 2.
+    int index  = hashkey & (nrows - 1);
     *rindex = index;
 
-    for (XHashNode* hnode = t->table[index]; hnode; hnode = hnode->next )
+    for (HashNode* hnode = table[index]; hnode; hnode = hnode->next )
     {
-        if ( !t->hashfcn->keycmp_fcn(hnode->key, key, t->keysize) )
+        if ( hashfcn->keycmp_fcn(hnode->key, key, keysize) )
         {
-            if ( t->splay > 0 )
-                movetofront(t, hnode);
+            if ( splay > 0 )
+                move_to_front(hnode);
 
-            t->find_success++;
+            find_success++;
             return hnode;
         }
     }
 
-    t->find_fail++;
+    find_fail++;
     return nullptr;
 }
 
-/*!
- * Add a key + data pair to the hash table
- *
- * 2003-06-06:
- *  - unique_tracker.c assumes that this splays
- *    nodes to the top when they are added.
- *
- *    This is done because of the successful find.
- *
- * t XHash table pointer
- * key  users key pointer
- * data  users data pointer
- *
- * return integer
- * retval XHASH_OK      success
- * retval XHASH_INTABLE already in the table, t->cnode points to the node
- * retval XHASH_NOMEM   not enough memory
- */
-static int xhash_add_ex(XHash* t, const void* key, void* data, void** data_ptr)
+int XHash::insert(const void* key, void* data)
 {
+    assert(key);
+
     int index = 0;
 
     /* Enforce uniqueness: Check for the key in the table */
-    XHashNode* hnode = xhash_find_node_row(t, key, &index);
+    HashNode* hnode = find_node_row(key, &index);
     if ( hnode )
     {
-        t->cnode = hnode;
-        if (data_ptr)
-            *data_ptr = hnode->data;
-        return XHASH_INTABLE; /* found it - return it. */
+        cnode = hnode;
+        return HASH_INTABLE;
     }
 
-    /*
-     *  Alloc new hash node - allocate key space and data space at the same time.
-     */
-    hnode = xhash_newnode(t);
+    hnode = allocate_node();
     if ( !hnode )
-    {
-        return XHASH_NOMEM;
-    }
-
-    /* Set up the new key pointer */
-    hnode->key = (char*)hnode + sizeof(XHashNode);
-
-    /* Copy the key */
-    memcpy(hnode->key,key,t->keysize);
+        return HASH_NOMEM;
 
-    /* Save our table row index */
+    hnode->key = (char*)hnode + sizeof(HashNode);
+    memcpy(hnode->key, key, keysize);
     hnode->rindex = index;
 
-    /* Copy the users data - or if datasize is zero set ptr to users data */
-    if ( t->datasize )
+    if ( datasize )
     {
-        /* Set up the new data pointer */
-        hnode->data= (char*)hnode + sizeof(XHashNode) + t->pad + t->keysize;
-
-        if (data)
-        {
-            memcpy(hnode->data,data,t->datasize);
-        }
-        if (data_ptr)
-            *data_ptr = hnode->data;
+        hnode->data = (char*)hnode + sizeof(HashNode) + keysize;
+        if ( data )
+            memcpy(hnode->data, data, datasize);
     }
     else
-    {
         hnode->data = data;
-    }
 
-    /* Link the node into the table row list */
-    xhash_link_node (t, hnode);
+    link_node (hnode);
+    glink_node(hnode);
+    count++;
 
-    /* Link at the front of the global node list */
-    xhash_glink_node(t, hnode);
-
-    /* Track # active nodes */
-    t->count++;
-
-    return XHASH_OK;
+    return HASH_OK;
 }
 
-int xhash_add(XHash* t, void* key, void* data)
+HashNode* XHash::get_node(const void* key)
 {
-    return xhash_add_ex(t, key, data, nullptr);
-}
+    assert(key);
 
-/*!
- * Add a key to the hash table, return the hash node
- *
- * 2003-06-06:
- *  - unique_tracker.c assumes that this splays
- *    nodes to the top when they are added.
- *
- *    This is done because of the successful find.
- *
- * t XHash table pointer
- * key  users key pointer
- *
- * return XHashNode*
- * retval nullptr      failed to add node
- */
-XHashNode* xhash_get_node(XHash* t, const void* key)
-{
     int index = 0;
 
-    /* Enforce uniqueness: Check for the key in the table */
-    XHashNode* hnode = xhash_find_node_row(t, key, &index);
+    // Enforce uniqueness: Check for the key in the table
+    HashNode* hnode = find_node_row( key, &index);
     if ( hnode )
     {
-        t->cnode = hnode;
-
-        return hnode; /* found it - return it. */
+        cnode = hnode;
+        return hnode;
     }
 
-    /*
-     *  Alloc new hash node - allocate key space and data space at the same time.
-     */
-    hnode = xhash_newnode(t);
+    hnode = allocate_node();
     if ( !hnode )
-    {
         return nullptr;
-    }
-
-    /* Set up the new key pointer */
-    hnode->key = (char*)hnode + sizeof(XHashNode);
 
-    /* Copy the key */
-    memcpy(hnode->key,key,t->keysize);
-
-    /* Save our table row index */
+    hnode->key = (char*)hnode + sizeof(HashNode);
+    memcpy(hnode->key, key, keysize);
     hnode->rindex = index;
 
-    /* Copy the users data - or if datasize is zero set ptr to users data */
-    if ( t->datasize )
-    {
-        /* Set up the new data pointer */
-        hnode->data = (char*)hnode + sizeof(XHashNode) + t->pad + t->keysize;
-    }
+    if ( datasize )
+        hnode->data = (char*)hnode + sizeof(HashNode) + keysize;
     else
-    {
         hnode->data = nullptr;
-    }
 
-    /* Link the node into the table row list */
-    xhash_link_node (t, hnode);
-
-    /* Link at the front of the global node list */
-    xhash_glink_node(t, hnode);
-
-    /* Track # active nodes */
-    t->count++;
+    link_node(hnode);
+    glink_node(hnode);
+    count++;
 
     return hnode;
 }
 
-/*!
- * Add a key to the hash table, return the hash node
- * If space is not available, it will remove a single
- * node (the LRU) and replace it with a new node.
- *
- * This function handles the scenario that we don't
- * have enough room to allocate a new node - if this is the
- * case, additional pruning should be done
- *
- * t XHash table pointer
- * key  users key pointer
- * prune_performed  bool pointer, 1 = successful prune, 0 = no/failed prune
- *
- * return XHashNode*
- * retval XhashNode*    successfully allocated
- * retval nullptr       failed to allocate
- */
-XHashNode* xhash_get_node_with_prune(XHash* t, const void* key, bool* prune_performed)
+HashNode* XHash::get_node_with_prune(const void* key, bool* prune_performed)
 {
-    size_t mem_after_alloc = t->mc.memused + xhash_required_mem(t);
-    bool over_capacity = (t->mc.memcap < mem_after_alloc);
-    XHashNode* hnode = nullptr;
+    assert(key);
+
+    size_t mem_after_alloc = mc.memused + mem_allocated_per_entry;
+    bool over_capacity = (mc.memcap < mem_after_alloc);
 
-    if (over_capacity)
-        *prune_performed = (xhash_free_anr_lru(t) == XHASH_OK);
+    if ( over_capacity )
+        *prune_performed = (delete_anr_or_lru_node() == HASH_OK);
 
-    if (*prune_performed or !over_capacity)
-        hnode = xhash_get_node(t, key);
+    HashNode* hnode = nullptr;
+    if ( *prune_performed or !over_capacity )
+        hnode = get_node(key);
 
     return hnode;
 }
 
-/*!
- * Find a Node based on the key
- *
- * t XHash table pointer
- * key  users key pointer
- *
- * return XHashNode*   valid pointer to the hash node
- * retval 0               node not found
- *
- */
-XHashNode* xhash_find_node(XHash* t, const void* key)
+HashNode* XHash::find_node(const void* key)
 {
-    int rindex = 0;
-
-    return xhash_find_node_row(t, key, &rindex);
-}
+    assert(key);
 
-/*!
- * Find the users data based associated with the key
- *
- * t XHash table pointer
- * key  users key pointer
- *
- * return void*   valid pointer to the users data
- * retval 0       node not found
- *
- */
-void* xhash_find(XHash* t, void* key)
-{
     int rindex = 0;
-    XHashNode* hnode = xhash_find_node_row(t, key, &rindex);
-    if ( hnode )
-        return hnode->data;
-
-    return nullptr;
+    return find_node_row(key, &rindex);
 }
 
-/**
- * Get the HEAD of the in use list
- *
- * t table pointer
- *
- * return the head of the list or nullptr
- */
-XHashNode* xhash_ghead(XHash* t)
+void* XHash::get_user_data(void* key)
 {
-    if (t)
-    {
-        return t->ghead;
-    }
+    assert(key);
 
-    return nullptr;
-}
-
-/**
- * Walk the global list
- *
- * n current node
- *
- * return the next node in the list or nullptr when at the end
- */
-XHashNode* xhash_gfindnext(XHash* t)
-{
-    XHashNode* n = t->gnode;
-    if (n)
-        t->gnode = n->gnext;
-    return n;
-}
-
-/**
- * Get the HEAD of the in use list
- *
- * t table pointer
- *
- * return the head of the list or nullptr
- */
-XHashNode* xhash_gfindfirst(XHash* t)
-{
-    if (t)
-    {
-        if (t->ghead)
-            t->gnode = t->ghead->gnext;
-        else
-            t->gnode = nullptr;
-        return t->ghead;
-    }
-    return nullptr;
-}
-
-/*!
- * Return the most recently used data from the global list
- *
- * t XHash table pointer
- *
- * return void*   valid pointer to the users data
- * retval 0       node not found
- *
- */
-void* xhash_mru(XHash* t)
-{
-    XHashNode* hnode = xhash_ghead(t);
-    if ( hnode )
-        return hnode->data;
-
-    return nullptr;
-}
-
-/*!
- * Return the least recently used data from the global list
- *
- * t XHash table pointer
- *
- * return void*   valid pointer to the users data
- * retval 0       node not found
- *
- */
-void* xhash_lru(XHash* t)
-{
-    XHashNode* hnode = t->gtail;
+    int rindex = 0;
+    HashNode* hnode = find_node_row(key, &rindex);
     if ( hnode )
         return hnode->data;
 
     return nullptr;
 }
 
-/*
- *  Unlink and free the node
- */
-int xhash_free_node(XHash* t, XHashNode* hnode)
+int XHash::release_node(HashNode* hnode)
 {
-    xhash_unlink_node(t, hnode);   /* unlink from the hash table row list */
+    assert(hnode);
 
-    xhash_gunlink_node(t, hnode);   /* unlink from global-hash-node list */
+    unlink_node(hnode);
+    gunlink_node(hnode);
+    count--;
 
-    t->count--;
+    if ( usr_free )
+        usr_free(hnode->key, hnode->data);
 
-    if ( t->usrfree )
-    {
-        t->usrfree(hnode->key, hnode->data);
-    }
-
-    if ( t->recycle_nodes )
-    {
-        xhash_save_free_node(t, hnode);
-    }
+    if ( recycle_nodes )
+        save_free_node(hnode);
     else
-    {
-        s_free(t, hnode);
-    }
+        sfmemcap_free(&mc, hnode);
 
-    return XHASH_OK;
+    return HASH_OK;
 }
 
-/*!
- * Remove a Key + Data Pair from the table.
- *
- * t XHash table pointer
- * key  users key pointer
- *
- * return 0   success
- * retval !0  failed
- *
- */
-int xhash_remove(XHash* t, void* key)
+int XHash::release_node(void* key)
 {
-    unsigned hashkey = t->hashfcn->hash_fcn(t->hashfcn, (unsigned char*)key, t->keysize);
-
-//    index = hashkey % t->nrows;
-    /* Modulus is slow */
-    unsigned index   = hashkey & (t->nrows - 1);
-
-    for ( XHashNode* hnode = t->table[index]; hnode; hnode = hnode->next )
-    {
-        if ( !t->hashfcn->keycmp_fcn(hnode->key, key, t->keysize) )
-        {
-            return xhash_free_node(t, hnode);
-        }
-    }
+    assert(key);
 
-    return XHASH_ERR;
-}
-
-/*
-   Internal use only
-*/
-static void xhash_next(XHash* t)
-{
-    if ( !t->cnode )
-        return;
+    unsigned hashkey = hashfcn->hash_fcn(hashfcn, (unsigned char*)key, keysize);
 
-    /* Next node in current node list */
-    t->cnode = t->cnode->next;
-    if ( t->cnode )
+    unsigned index = hashkey & (nrows - 1);
+    for ( HashNode* hnode = table[index]; hnode; hnode = hnode->next )
     {
-        return;
+        if ( hashfcn->keycmp_fcn(hnode->key, key, keysize) )
+            return release_node(hnode);
     }
 
-    /* Next row
-       Get 1st node in next non-empty row/node list */
-    for ( t->crow++; t->crow < t->nrows; t->crow++ )
-    {
-        t->cnode = t->table[ t->crow ];
-        if ( t->cnode )
-        {
-            return;
-        }
-    }
+    return HASH_ERR;
 }
 
-static inline int xhash_delete_free_node(XHash *t)
+int XHash::delete_free_node()
 {
-    XHashNode* fn = xhash_get_free_node(t);
+    HashNode* fn = get_free_node();
     if (fn)
     {
-        s_free(t, fn);
-        return XHASH_OK;
+        sfmemcap_free(&mc, fn);
+        return HASH_OK;
     }
-    return XHASH_ERR;
+    return HASH_ERR;
 }
 
-/*!
- * Unlink and free an ANR node or the oldest node, if ANR is empty
- * behavior is undefined if either t->anrfree or t->usrfree is set
- *
- * t XHash table pointer
- *
- * returns
- * XHASH_ERR if error occurs
- * XHASH_OK  if node is freed
- */
-int xhash_free_anr_lru(XHash *t)
+int XHash::delete_anr_or_lru_node()
 {
-    if (t == nullptr)
-        return XHASH_ERR;
-
-    if (t->fhead)
+    if ( fhead )
     {
-        if (xhash_delete_free_node(t) == XHASH_OK)
-            return XHASH_OK;
+        if (delete_free_node() == HASH_OK)
+            return HASH_OK;
     }
 
-    if (t->gtail)
+    if ( gtail )
     {
-        if (xhash_free_node(t, t->gtail) == XHASH_OK)
+        if ( release_node(gtail) == HASH_OK )
         {
-            if (t->fhead)
+            if ( fhead )
             {
-                if (xhash_delete_free_node(t) == XHASH_OK)
-                    return XHASH_OK;
-            }
-            else if (!t->recycle_nodes)
-            {
-                return XHASH_OK;
+                if ( delete_free_node() == HASH_OK )
+                    return HASH_OK;
             }
+            else if ( !recycle_nodes )
+                return HASH_OK;
         }
     }
-    return XHASH_ERR;
+    return HASH_ERR;
 }
 
-/*!
- * Unlink and free nodes if the xhash is exceeding the
- * specified memcap
- *
- * t            XHash table pointer
- * num_freed    set to the number of nodes freed
- * work_limit   the max amount of work to do
- *
- * returns
- * XHASH_ERR if error occurs
- * XHASH_OK  if node(s) freed and memused is within memcap
- * XHASH_PENDING if additional pending is required
- */
-int xhash_free_overallocations(XHash* t, unsigned work_limit, unsigned* num_freed)
+int XHash::free_over_allocations(unsigned work_limit, unsigned* num_freed)
 {
 
-    while (t->mc.memcap < t->mc.memused and work_limit--)
+    while (mc.memcap < mc.memused and work_limit--)
     {
-        if (xhash_free_anr_lru(t) != XHASH_OK)
-            return XHASH_ERR;
+        if (delete_anr_or_lru_node() != HASH_OK)
+            return HASH_ERR;
 
         ++*num_freed;
     }
 
-    return (t->mc.memcap >= t->mc.memused) ? XHASH_OK : XHASH_PENDING;
+    return (mc.memcap >= mc.memused) ? HASH_OK : HASH_PENDING;
 }
 
-/*!
- * Find and return the first hash table node
- *
- * t XHash table pointer
- *
- * return 0   failed
- * retval !0  valid XHashNode *
- *
- */
-XHashNode* xhash_findfirst(XHash* t)
+void XHash::update_cnode()
 {
-    if (!t)
-        return nullptr;
+    if ( !cnode )
+        return;
+
+    cnode = cnode->next;
+    if ( cnode )
+        return;
+
+    for ( crow++; crow < nrows; crow++ )
+    {
+        cnode = table[crow];
+        if ( cnode )
+            return;
+    }
+}
 
-    /* Start with 1st row */
-    for ( t->crow = 0; t->crow < t->nrows; t->crow++ )
+HashNode* XHash::find_first_node()
+{
+    for ( crow = 0; crow < nrows; crow++ )
     {
-        /* Get 1st Non-Null node in row list */
-        t->cnode = t->table[ t->crow ];
-        if ( t->cnode )
+        cnode = table[crow];
+        if ( cnode )
         {
-            XHashNode* n = t->cnode;
-            xhash_next(t);   // load t->cnode with the next entry
+            HashNode* n = cnode;
+            update_cnode();
             return n;
         }
     }
@@ -1151,36 +640,20 @@ XHashNode* xhash_findfirst(XHash* t)
     return nullptr;
 }
 
-/*!
- * Find and return the next hash table node
- *
- * t XHash table pointer
- *
- * return 0   failed
- * retval !0  valid XHashNode *
- *
- */
-XHashNode* xhash_findnext(XHash* t)
+HashNode* XHash::find_next_node()
 {
-    XHashNode* n = t->cnode;
-    if ( !n ) /* Done, no more entries */
-    {
+    HashNode* n = cnode;
+    if ( !n )
         return nullptr;
-    }
 
-    /*
-      Preload next node into current node
-    */
-    xhash_next(t);
+    update_cnode();
 
     return n;
 }
 
-// Make hashfcn use a separate set of opcodes for the backend.
-
-void xhash_set_keyops(XHash* h, hash_func hash_fcn, keycmp_func keycmp_fcn)
+void XHash::set_key_opcodes(hash_func hash_fcn, keycmp_func keycmp_fcn)
 {
-    assert(h and hash_fcn and keycmp_fcn);
-    hashfcn_set_keyops(h->hashfcn, hash_fcn, keycmp_fcn);
+    hashfcn_set_keyops(hashfcn, hash_fcn, keycmp_fcn);
 }
+
 } // namespace snort
index cf27b79fdc4bdc1e75773afd0f159e162ed73252..d9ea5f7dfb1fa6c64a7f8a5162a7399eb5b774e5 100644 (file)
 #include "utils/sfmemcap.h"
 #include "main/snort_types.h"
 
-struct HashFnc;
+#include "hash_defs.h"
+#include "hashfcn.h"
 
 namespace snort
 {
-#define XHASH_NOMEM    (-2)
-#define XHASH_ERR      (-1)
-#define XHASH_OK        0
-#define XHASH_INTABLE   1
-#define XHASH_PENDING   2
-
-struct XHashNode
-{
-    struct XHashNode* gnext; // global node list - used for aging nodes
-    struct XHashNode* gprev;
-    struct XHashNode* next;  // row node list
-    struct XHashNode* prev;
-
-    int rindex;  // row index of table this node belongs to.
-
-    void* key;  // Pointer to the key.
-    void* data; // Pointer to the users data, this is not copied !
-};
-
-typedef int (* XHash_FREE_FCN)(void* key, void* data);
-
-struct XHash
+class SO_PUBLIC XHash
 {
-    HashFnc* hashfcn;    // hash function
-    int keysize;             // bytes in key, if <= 0 -> keys are strings
-    int datasize;            // bytes in key, if == 0 -> user data
-    XHashNode** table;    // array of node ptr's */
-    unsigned nrows;          // # rows int the hash table use a prime number 211, 9871
-    unsigned count;          // total # nodes in table
-
-    unsigned crow;           // findfirst/next row in table
-    unsigned pad;
-    XHashNode* cnode;     // findfirst/next node ptr
-    int splay;               // whether to splay nodes with same hash bucket
-
-    unsigned max_nodes;      // maximum # of nodes within a hash
+public:
+    XHash(int nrows_, int keysize_, int datasize_, unsigned long memcap,
+        bool anr_enabled, Hash_FREE_FCN, Hash_FREE_FCN, bool recycle_nodes);
+    ~XHash();
+
+    int free_over_allocations(unsigned work_limit, unsigned* num_freed);
+    void clear();
+
+    int insert(const void* key, void* data);
+    HashNode* get_node(const void* key);
+    HashNode* get_node_with_prune(const void* key, bool* prune_performed);
+    int release_node(void* key);
+    int release_node(HashNode* node);
+    int delete_anr_or_lru_node();
+    HashNode* find_node(const void* key);
+    HashNode* find_first_node();
+    HashNode* find_next_node();
+    void* get_user_data(void* key);
+    void* get_mru_user_data();
+    void* get_lru_user_data();
+    void set_key_opcodes(hash_func, keycmp_func);
+
+    // Set the maximum nodes used in this hash table.
+    //  Specifying 0 is unlimited (or otherwise limited by memcap).
+    void set_max_nodes(int max)
+    { max_nodes = max; }
+
+    unsigned get_node_count()
+    { return count; }
+
+    unsigned get_anr_count()
+    { return anr_count; }
+
+    unsigned get_total_finds()
+    { return find_success + find_fail; }
+
+    unsigned get_find_fails()
+    { return find_fail; }
+
+    unsigned get_find_successes()
+    { return find_success; }
+
+    void set_memcap(unsigned long new_memcap)
+    { mc.memcap = new_memcap; }
+
+    unsigned long get_memcap()
+    { return mc.memcap; }
+
+    unsigned long get_mem_used()
+    { return mc.memused; }
+
+    const HashNode* get_cnode () const
+    { return cnode; }
+
+    int get_keysize () const
+    { return keysize; }
+
+private:
+    void purge_free_list();
+    void save_free_node(HashNode* hnode);
+    HashNode* get_free_node();
+    void glink_node(HashNode* hnode);
+    void gunlink_node(HashNode* hnode);
+    void gmove_to_front(HashNode* hnode);
+    HashNode* gfind_first();
+    HashNode* gfind_next();
+    void link_node(HashNode* hnode);
+    void unlink_node(HashNode* hnode);
+    void move_to_front(HashNode* n);
+    HashNode* allocate_node();
+    HashNode* find_node_row(const void* key, int* rindex);
+    void update_cnode();
+    int delete_free_node();
+
+    HashFnc* hashfcn = nullptr;     // hash function
+    int keysize = 0;                // bytes in key, if <= 0 -> keys are strings - FIXIT-H does negative keysize work?
+    int datasize = 0;               // bytes in key, if == 0 -> user data
+    unsigned mem_allocated_per_entry = 0;
+    HashNode** table = nullptr;        // array of node ptr's */
+    unsigned nrows = 0;             // # rows int the hash table use a prime number 211, 9871
+    unsigned count = 0;             // total # nodes in table
+    unsigned crow = 0;              // findfirst/next row in table
+    HashNode* cnode = nullptr;     // find_[first|next] node ptr
+    int splay = 1;                  // whether to splay nodes with same hash bucket
+    unsigned max_nodes = 0;         // maximum # of nodes within a hash
     MEMCAP mc;
-    unsigned overhead_bytes;  // # of bytes that will be unavailable for nodes inside the
-                              // table
-    unsigned overhead_blocks; // # of blocks consumed by the table
-    unsigned find_fail;
-    unsigned find_success;
-
-    XHashNode* ghead, * gtail;  // global - root of all nodes allocated in table
-    XHashNode* fhead, * ftail;  // list of free nodes, which are recycled
-    XHashNode* gnode;           // gfirst/gnext node ptr */
-    int recycle_nodes;             // recycle nodes. Nodes are not freed, but are used for
-                                   // subsequent new nodes
-
-    /* Automatic Node Recover (ANR): When number of nodes in hash is equal
-     * to max_nodes, remove the least recently used nodes and use it for
-     * the new node. anr_tries indicates # of ANR tries.*/
-
-    unsigned anr_tries;
-    unsigned anr_count;      // # ANR ops performed
-    int anr_flag;            // 0=off, !0=on
-
-    XHash_FREE_FCN anrfree;
-    XHash_FREE_FCN usrfree;
+    unsigned find_fail = 0;
+    unsigned find_success = 0;
+
+    HashNode* ghead = nullptr;     // global - root of all nodes allocated in table
+    HashNode* gtail = nullptr;
+    HashNode* gnode = nullptr;     // gfirst/gnext node ptr */
+    HashNode* fhead = nullptr;     // list of free nodes, which are recycled
+    HashNode* ftail = nullptr;
+    bool recycle_nodes = false;     // recycle nodes...
+
+    // Automatic Node Recover (ANR): When number of nodes in hash is equal
+    // to max_nodes, remove the least recently used nodes and use it for
+    // the new node. anr_tries indicates # of ANR tries.*/
+    unsigned anr_tries = 0;
+    unsigned anr_count = 0;      // # ANR ops performed
+    bool anr_enabled = false;    // false = anr disable, true = anr enabled
+
+    Hash_FREE_FCN anr_free = nullptr;
+    Hash_FREE_FCN usr_free = nullptr;
 };
 
-SO_PUBLIC XHash* xhash_new(int nrows, int keysize, int datasize, unsigned long memcap,
-    int anr_flag,
-    XHash_FREE_FCN anrfunc,
-    XHash_FREE_FCN usrfunc,
-    int recycle_flag);
-
-SO_PUBLIC void xhash_set_max_nodes(XHash* h, int max_nodes);
-SO_PUBLIC int xhash_change_memcap(XHash *t, unsigned long new_memcap, unsigned *max_work);
-SO_PUBLIC int xhash_free_overallocations(XHash* t, unsigned work_limit, unsigned* num_freed);
-SO_PUBLIC void xhash_delete(XHash* h);
-SO_PUBLIC int xhash_make_empty(XHash*);
-
-SO_PUBLIC int xhash_add(XHash* h, void* key, void* data);
-SO_PUBLIC XHashNode* xhash_get_node(XHash* t, const void* key);
-SO_PUBLIC XHashNode* xhash_get_node_with_prune(XHash* t, const void* key, bool* prune_performed);
-SO_PUBLIC int xhash_remove(XHash* h, void* key);
-
-//  Get the # of Nodes in HASH the table
-inline unsigned xhash_count(XHash* t)
-{ return t->count; }
-
-//  Get the # auto recovery
-inline unsigned xhash_anr_count(XHash* t)
-{ return t->anr_count; }
-
-//  Get the # finds
-inline unsigned xhash_find_total(XHash* t)
-{ return t->find_success + t->find_fail; }
-
-//  Get the # unsuccessful finds
-inline unsigned xhash_find_fail(XHash* t)
-{ return t->find_fail; }
-
-//  Get the # successful finds
-inline unsigned xhash_find_success(XHash* t)
-{ return t->find_success; }
-
-//  Get the # of overhead bytes
-inline unsigned xhash_overhead_bytes(XHash* t)
-{ return t->overhead_bytes; }
-
-// Get the # of overhead blocks
-inline unsigned xhash_overhead_blocks(XHash* t)
-{ return t->overhead_blocks; }
-
-// Get the amount of space required to allocate a new node in the xhash t.
-constexpr size_t xhash_required_mem(XHash *t)
-{ return sizeof(XHashNode) + t->pad + t->keysize + t->datasize + sizeof(long); }
-
-SO_PUBLIC int xhash_free_anr_lru(XHash* t);
-SO_PUBLIC void* xhash_mru(XHash* t);
-SO_PUBLIC void* xhash_lru(XHash* t);
-SO_PUBLIC void* xhash_find(XHash* h, void* key);
-SO_PUBLIC XHashNode* xhash_find_node(XHash* t, const void* key);
-
-SO_PUBLIC XHashNode* xhash_findfirst(XHash* h);
-SO_PUBLIC XHashNode* xhash_findnext(XHash* h);
-
-SO_PUBLIC XHashNode* xhash_ghead(XHash* h);
-SO_PUBLIC void xhash_gmovetofront(XHash* t, XHashNode* hnode);
-
-SO_PUBLIC int xhash_free_node(XHash* t, XHashNode* node);
-
-typedef uint32_t (* hash_func)(HashFnc*, const unsigned char* d, int n);
-
-
-// return 0 for ==, 1 for != ; FIXIT-L convert to bool
-typedef int (* keycmp_func)(const void* s1, const void* s2, size_t n);
-
-SO_PUBLIC void xhash_set_keyops(XHash* h, hash_func, keycmp_func);
-
-SO_PUBLIC XHashNode* xhash_gfindfirst(XHash* t);
-SO_PUBLIC XHashNode* xhash_gfindnext(XHash* t);
 } // namespace snort
 #endif
 
index 7c70cda7d7d4c0fc33bfa44243f215cca1702d26..f2b87d3ac78337faa7a433594abfdd42b2382d3a 100644 (file)
 
 #include "zhash.h"
 
+#include <cassert>
 #include <cstring>
 
-#include "hashfcn.h"
+#include "hash_defs.h"
+
+using namespace snort;
 
 //-------------------------------------------------------------------------
 // private stuff
 //-------------------------------------------------------------------------
 
-struct ZHashNode
-{
-    ZHashNode* gnext = nullptr; // global list
-    ZHashNode* gprev = nullptr; // global list
-
-    ZHashNode* next = nullptr;  // row list
-    ZHashNode* prev = nullptr;  // row list
-
-    int rindex = 0;
-
-    void* key = nullptr;
-    void* data = nullptr;
-};
-
-static inline ZHashNode* s_node_alloc(int keysize)
+static inline HashNode* s_node_alloc(int keysize)
 {
-    auto node = static_cast<ZHashNode*>(
-        ::operator new(sizeof(ZHashNode) + keysize));
+    auto node = static_cast<HashNode*>(
+        ::operator new(sizeof(HashNode) + keysize));
 
     *node = {};
     return node;
 }
 
-static inline void s_node_free(ZHashNode* node)
+static inline void s_node_free(HashNode* node)
 { ::operator delete(node); }
 
 void ZHash::delete_free_list()
@@ -64,7 +53,7 @@ void ZHash::delete_free_list()
     if ( !fhead )
         return;
 
-    ZHashNode* cur = fhead;
+    HashNode* cur = fhead;
 
     while ( cur )
     {
@@ -74,7 +63,7 @@ void ZHash::delete_free_list()
     }
 }
 
-void ZHash::save_free_node(ZHashNode* node)
+void ZHash::save_free_node(HashNode* node)
 {
     if ( fhead )
     {
@@ -91,9 +80,9 @@ void ZHash::save_free_node(ZHashNode* node)
     }
 }
 
-ZHashNode* ZHash::get_free_node()
+HashNode* ZHash::get_free_node()
 {
-    ZHashNode* node = fhead;
+    HashNode* node = fhead;
 
     if ( fhead )
     {
@@ -106,7 +95,7 @@ ZHashNode* ZHash::get_free_node()
     return node;
 }
 
-void ZHash::glink_node(ZHashNode* node)
+void ZHash::glink_node(HashNode* node)
 {
     if ( ghead )
     {
@@ -124,7 +113,7 @@ void ZHash::glink_node(ZHashNode* node)
     }
 }
 
-void ZHash::gunlink_node(ZHashNode* node)
+void ZHash::gunlink_node(HashNode* node)
 {
     if ( cursor == node )
         cursor = node->gprev;
@@ -146,7 +135,7 @@ void ZHash::gunlink_node(ZHashNode* node)
         gtail = node->gprev;
 }
 
-void ZHash::link_node(ZHashNode* node)
+void ZHash::link_node(HashNode* node)
 {
     if ( table[node->rindex] )  // UNINITUSE
     {
@@ -163,7 +152,7 @@ void ZHash::link_node(ZHashNode* node)
     }
 }
 
-void ZHash::unlink_node(ZHashNode* node)
+void ZHash::unlink_node(HashNode* node)
 {
     if ( node->prev )
     {
@@ -180,7 +169,7 @@ void ZHash::unlink_node(ZHashNode* node)
     }
 }
 
-void ZHash::move_to_front(ZHashNode* node)
+void ZHash::move_to_front(HashNode* node)
 {
     // move to front of row list
     if ( table[node->rindex] != node )
@@ -197,7 +186,7 @@ void ZHash::move_to_front(ZHashNode* node)
     }
 }
 
-ZHashNode* ZHash::find_node_row(const void* key, int& row)
+HashNode* ZHash::find_node_row(const void* key, int& row)
 {
     unsigned hashkey = hashfcn->hash_fcn(
         hashfcn, (const unsigned char*)key, keysize);
@@ -206,9 +195,9 @@ ZHashNode* ZHash::find_node_row(const void* key, int& row)
     int index = hashkey & (nrows - 1);
     row = index;
 
-    for ( ZHashNode* node=table[index]; node; node=node->next )  // UNINITUSE
+    for ( HashNode* node = table[index]; node; node = node->next )  // UNINITUSE
     {
-        if ( !hashfcn->keycmp_fcn(node->key,key,keysize) )
+        if ( hashfcn->keycmp_fcn(node->key, key, keysize) )
         {
             move_to_front(node);
             find_success++;
@@ -220,45 +209,21 @@ ZHashNode* ZHash::find_node_row(const void* key, int& row)
     return nullptr;
 }
 
-int ZHash::nearest_powerof2(int rows)
-{
-    rows -= 1;
-
-    for ( unsigned i=1; i<sizeof(rows) * 8; i <<= 1 )
-        rows = rows | (rows >> i);
-
-    rows += 1;
-    return rows;
-}
-
 //-------------------------------------------------------------------------
 // public stuff
 //-------------------------------------------------------------------------
 
 ZHash::ZHash(int rows, int keysz)
+    : keysize(keysz)
 {
+    // adjust rows to be power of 2
     if ( rows > 0 )
-    {
-        // make sure we have a prime number
-        // rows = nearest_prime(rows);
-
-        /* If rows is not a power of two, need to find the
-         * next highest power of two */
-        rows = nearest_powerof2(rows);
-    }
-    else   /* use the magnitude of rows as is */
-    {
-        rows = -rows;
-    }
-
-    /* this has a default hashing function */
-    hashfcn = hashfcn_new(rows);
-
-    /* Allocate the array of node ptrs */
-    table = new ZHashNode*[rows]();
+        nrows = hash_nearest_power_of_2(rows);
+    else
+        nrows = -rows;   // if negative use as is
 
-    keysize = keysz;
-    nrows = rows;
+    table = new HashNode*[nrows]();
+    hashfcn = hashfcn_new(nrows);
 
     fhead = cursor = nullptr;
     ghead = gtail = nullptr;
@@ -267,22 +232,19 @@ ZHash::ZHash(int rows, int keysz)
 
 ZHash::~ZHash()
 {
-    if ( hashfcn )
-        hashfcn_free(hashfcn);
+    hashfcn_free(hashfcn);
 
-    if ( table )
+    for ( unsigned i = 0; i < nrows; ++i )
     {
-        for ( unsigned i = 0; i < nrows; ++i )
+        for ( HashNode* node = table[i]; node; )
         {
-            for ( ZHashNode* node = table[i]; node; )
-            {
-                ZHashNode* onode = node;
-                node = node->next;
-                s_node_free(onode);
-            }
+            HashNode* onode = node;
+            node = node->next;
+            s_node_free(onode);
         }
-        delete[] table;
     }
+
+    delete[] table;
     delete_free_list();
 }
 
@@ -290,7 +252,7 @@ void* ZHash::push(void* p)
 {
     auto node = s_node_alloc(keysize);
 
-    node->key = (char*)node + sizeof(ZHashNode);
+    node->key = (char*)node + sizeof(HashNode);
     node->data = p;
 
     save_free_node(node);
@@ -299,7 +261,7 @@ void* ZHash::push(void* p)
 
 void* ZHash::pop()
 {
-    ZHashNode* node = get_free_node();
+    HashNode* node = get_free_node();
 
     if ( !node )
         return nullptr;
@@ -313,7 +275,7 @@ void* ZHash::pop()
 void* ZHash::get(const void* key, bool *new_node)
 {
     int row;
-    ZHashNode* node = find_node_row(key, row);
+    HashNode* node = find_node_row(key, row);
 
     if ( node )
         return node->data;
@@ -340,7 +302,7 @@ void* ZHash::get(const void* key, bool *new_node)
 void* ZHash::find(const void* key)
 {
     int row;
-    ZHashNode* node = find_node_row(key, row);
+    HashNode* node = find_node_row(key, row);
 
     if ( node )
         return node->data;
@@ -370,7 +332,7 @@ void* ZHash::current()
 
 bool ZHash::touch()
 {
-    ZHashNode* node = cursor;
+    HashNode* node = cursor;
 
     if ( !node )
         return false;
@@ -386,7 +348,7 @@ bool ZHash::touch()
     return false;
 }
 
-bool ZHash::move_to_free_list(ZHashNode* node)
+bool ZHash::move_to_free_list(HashNode* node)
 {
     if ( !node )
         return false;
@@ -401,7 +363,7 @@ bool ZHash::move_to_free_list(ZHashNode* node)
 
 bool ZHash::release()
 {
-    ZHashNode* node = cursor;
+    HashNode* node = cursor;
     cursor = nullptr;
     return move_to_free_list(node);
 }
@@ -409,7 +371,7 @@ bool ZHash::release()
 bool ZHash::release(const void* key)
 {
     int row;
-    ZHashNode* node = find_node_row(key, row);
+    HashNode* node = find_node_row(key, row);
     return move_to_free_list(node);
 }
 
@@ -417,7 +379,7 @@ void* ZHash::remove(const void* key)
 {
     void* pv = nullptr;
     int row;
-    ZHashNode* node = find_node_row(key, row);
+    HashNode* node = find_node_row(key, row);
     if ( node )
     {
         unlink_node(node);
@@ -430,12 +392,7 @@ void* ZHash::remove(const void* key)
     return pv;
 }
 
-int ZHash::set_keyops(
-    unsigned (* hash_fcn)(HashFnc* p, const unsigned char* d, int n),
-    int (* keycmp_fcn)(const void* s1, const void* s2, size_t n))
+void ZHash::set_key_opcodes(hash_func hash_fcn, keycmp_func keycmp_fcn)
 {
-    if ( hash_fcn && keycmp_fcn )
-        return hashfcn_set_keyops(hashfcn, hash_fcn, keycmp_fcn);
-
-    return -1;
+    hashfcn_set_keyops(hashfcn, hash_fcn, keycmp_fcn);
 }
index 334245b49914ec99e01a29f4bde837d927ce572c..27584532bde3dc1573689345dfde9044bd74f037 100644 (file)
 
 #include <cstddef>
 
-struct HashFnc;
-struct ZHashNode;
+#include "hashfcn.h"
+
+namespace snort
+{
+struct HashNode;
+}
 
 class ZHash
 {
@@ -47,28 +51,26 @@ public:
     bool release(const void* key);
     bool release();
     void* remove(const void* key);
+    void set_key_opcodes(hash_func, keycmp_func);
 
-    inline unsigned get_count() { return count; }
-    int set_keyops(
-        unsigned (* hash_fcn)(HashFnc* p, const unsigned char* d, int n),
-        int (* keycmp_fcn)(const void* s1, const void* s2, size_t n));
+    inline unsigned get_count()
+    { return count; }
 
 private:
-    ZHashNode* get_free_node();
-    ZHashNode* find_node_row(const void*, int&);
+    snort::HashNode* get_free_node();
+    snort::HashNode* find_node_row(const void*, int&);
 
-    void glink_node(ZHashNode*);
-    void gunlink_node(ZHashNode*);
+    void glink_node(snort::HashNode*);
+    void gunlink_node(snort::HashNode*);
 
-    void link_node(ZHashNode*);
-    void unlink_node(ZHashNode*);
+    void link_node(snort::HashNode*);
+    void unlink_node(snort::HashNode*);
 
     void delete_free_list();
-    void save_free_node(ZHashNode*);
+    void save_free_node(snort::HashNode*);
 
-    bool move_to_free_list(ZHashNode*);
-    void move_to_front(ZHashNode*);
-    int nearest_powerof2(int nrows);
+    bool move_to_free_list(snort::HashNode*);
+    void move_to_front(snort::HashNode*);
 
 private:
     HashFnc* hashfcn;
@@ -79,11 +81,11 @@ private:
     unsigned find_fail;
     unsigned find_success;
 
-    ZHashNode** table;
-    ZHashNode* ghead;
-    ZHashNode* gtail;
-    ZHashNode* fhead;
-    ZHashNode* cursor;
+    snort::HashNode** table;
+    snort::HashNode* ghead;
+    snort::HashNode* gtail;
+    snort::HashNode* fhead;
+    snort::HashNode* cursor;
 };
 
 #endif
index f5dc826a6dee8dfa49e560c90515a6527ef2b047..4205b3264d08ece27c7c3e58eaf4b478cba76822 100644 (file)
@@ -293,7 +293,7 @@ static inline int clear_group_bit(BitOp* bitop, char* group, FlowBitState* flowb
     // FIXIT-M why is the hash lookup done at runtime for flowbits groups?
     // a pointer to flowbis_grp should be in flowbits config data
     // this *should* be safe but iff splay mode is disabled
-    auto flowbits_grp = (FLOWBITS_GRP*)ghash_find(flowbit_state->flowbits_grp_hash, group);
+    auto flowbits_grp = (FLOWBITS_GRP*)flowbit_state->flowbits_grp_hash->find(group);
 
     if ( !flowbits_grp )
         return 0;
@@ -317,7 +317,7 @@ static inline int toggle_group_bit(BitOp* bitop, char* group, FlowBitState* flow
     if ( !group  )
         return 0;
 
-    auto flowbits_grp = (FLOWBITS_GRP*)ghash_find(flowbit_state->flowbits_grp_hash, group);
+    auto flowbits_grp = (FLOWBITS_GRP*)flowbit_state->flowbits_grp_hash->find(group);
 
     if ( !flowbits_grp )
         return 0;
@@ -374,7 +374,7 @@ static inline int is_set_flowbits(
         return 0;
 
     case FLOWBITS_ALL:
-        flowbits_grp = (FLOWBITS_GRP*)ghash_find(flowbit_state->flowbits_grp_hash, group);
+        flowbits_grp = (FLOWBITS_GRP*)flowbit_state->flowbits_grp_hash->find(group);
         if ( flowbits_grp == nullptr )
             return 0;
         for ( i = 0; i <= (unsigned int)(flowbits_grp->max_id >>3); i++ )
@@ -387,7 +387,7 @@ static inline int is_set_flowbits(
         return 1;
 
     case FLOWBITS_ANY:
-        flowbits_grp = (FLOWBITS_GRP*)ghash_find(flowbit_state->flowbits_grp_hash, group);
+        flowbits_grp = (FLOWBITS_GRP*)flowbit_state->flowbits_grp_hash->find(group);
         if ( flowbits_grp == nullptr )
             return 0;
         for ( i = 0; i <= (unsigned int)(flowbits_grp->max_id >>3); i++ )
@@ -525,22 +525,12 @@ static IpsOption::EvalStatus check_flowbits(
 void flowbits_ginit(SnortConfig* sc)
 {
     sc->flowbit_state = new FlowBitState;
-    sc->flowbit_state->flowbits_hash = ghash_new(10000, 0, 0, FlowItemFree);
-
-    if ( !sc->flowbit_state->flowbits_hash )
-        FatalError("Could not create flowbits hash.\n");
+    sc->flowbit_state->flowbits_hash = new GHash(10000, 0, 0, FlowItemFree);
 
     // this is used during parse time and runtime so do NOT
     // enable splay mode (which is NOT useful here anyway)
-    sc->flowbit_state->flowbits_grp_hash = ghash_new(10000, 0, 0, FlowBitsGrpFree);
-
-    if ( !sc->flowbit_state->flowbits_grp_hash )
-        FatalError("could not create flowbits group hash.\n");
-
+    sc->flowbit_state->flowbits_grp_hash = new GHash(10000, 0, 0, FlowBitsGrpFree);
     sc->flowbit_state->flowbits_bit_queue = sfqueue_new();
-
-    if ( !sc->flowbit_state->flowbits_bit_queue )
-        FatalError("could not create flowbits bit queue.\n");
 }
 
 void flowbits_gterm(SnortConfig* sc)
@@ -550,10 +540,10 @@ void flowbits_gterm(SnortConfig* sc)
         return;
 
     if ( flowbit_state->flowbits_hash )
-        ghash_delete(flowbit_state->flowbits_hash);
+        delete flowbit_state->flowbits_hash;
 
     if ( flowbit_state->flowbits_grp_hash )
-        ghash_delete(flowbit_state->flowbits_grp_hash);
+        delete flowbit_state->flowbits_grp_hash;
 
     if ( flowbit_state->flowbits_bit_queue )
         sfqueue_free_all(flowbit_state->flowbits_bit_queue, nullptr);
@@ -604,7 +594,7 @@ static FLOWBITS_OBJECT* getFlowBitItem(char* flowbitName, FLOWBITS_OP* flowbits,
             s_name, ALLOWED_SPECIAL_CHARS);
     }
 
-    flowbits_item = (FLOWBITS_OBJECT*)ghash_find(flowbit_state->flowbits_hash, flowbitName);
+    flowbits_item = (FLOWBITS_OBJECT*)flowbit_state->flowbits_hash->find(flowbitName);
 
     if (flowbits_item == nullptr)
     {
@@ -627,8 +617,7 @@ static FLOWBITS_OBJECT* getFlowBitItem(char* flowbitName, FLOWBITS_OP* flowbits,
             }
         }
 
-        int hstatus = ghash_add(flowbit_state->flowbits_hash, flowbitName, flowbits_item);
-
+        int hstatus = flowbit_state->flowbits_hash->insert(flowbitName, flowbits_item);
         if (hstatus != GHASH_OK)
             ParseError("Could not add flowbits key (%s) to hash.",flowbitName);
     }
@@ -815,14 +804,13 @@ static FLOWBITS_GRP* getFlowBitGroup(char* groupName, FlowBitState* flowbit_stat
             s_name, ALLOWED_SPECIAL_CHARS);
     }
 
-    flowbits_grp = (FLOWBITS_GRP*)ghash_find(flowbit_state->flowbits_grp_hash, groupName);
+    flowbits_grp = (FLOWBITS_GRP*)flowbit_state->flowbits_grp_hash->find(groupName);
 
     if ( !flowbits_grp )
     {
         // new group defined, add (bitop set later once we know size)
         flowbits_grp = (FLOWBITS_GRP*)snort_calloc(sizeof(*flowbits_grp));
-        int hstatus = ghash_add(flowbit_state->flowbits_grp_hash, groupName, flowbits_grp);
-
+        int hstatus = flowbit_state->flowbits_grp_hash->insert(groupName, flowbits_grp);
         if (hstatus != GHASH_OK)
             ParseAbort("Could not add flowbits group (%s) to hash.\n",groupName);
 
@@ -979,9 +967,9 @@ static void init_groups(FlowBitState* flowbit_state)
     if ( !flowbit_state->flowbits_hash or !flowbit_state->flowbits_grp_hash )
         return;
 
-    for ( GHashNode* n = ghash_findfirst(flowbit_state->flowbits_grp_hash);
-        n != nullptr;
-        n= ghash_findnext(flowbit_state->flowbits_grp_hash) )
+    for (GHashNode* n = flowbit_state->flowbits_grp_hash->find_first();
+         n != nullptr;
+         n= flowbit_state->flowbits_grp_hash->find_next())
     {
         FLOWBITS_GRP* fbg = (FLOWBITS_GRP*)n->data;
         fbg->GrpBitOp = new BitOp(flowbit_state->flowbits_count);
@@ -991,8 +979,8 @@ static void init_groups(FlowBitState* flowbit_state)
     while ( !flowbit_state->op_list.empty() )
     {
         const FLOWBITS_OP* fbop = flowbit_state->op_list.front();
-        FLOWBITS_GRP* fbg = (FLOWBITS_GRP*)ghash_find(flowbit_state->flowbits_grp_hash,
-            fbop->group);
+        FLOWBITS_GRP* fbg =
+            (FLOWBITS_GRP*)flowbit_state->flowbits_grp_hash->find(fbop->group);
         assert(fbg);
 
         for ( int i = 0; i < fbop->num_ids; ++i )
@@ -1011,16 +999,16 @@ static void FlowBitsVerify(FlowBitState* flowbit_state)
     if (flowbit_state->flowbits_hash == nullptr)
         return;
 
-    for (n = ghash_findfirst(flowbit_state->flowbits_hash);
-        n != nullptr;
-        n= ghash_findnext(flowbit_state->flowbits_hash))
+    for (n = flowbit_state->flowbits_hash->find_first();
+         n != nullptr;
+         n = flowbit_state->flowbits_hash->find_next())
     {
         FLOWBITS_OBJECT* fb = (FLOWBITS_OBJECT*)n->data;
 
         if (fb->toggle != flowbit_state->flowbits_toggle)
         {
             sfqueue_add(flowbit_state->flowbits_bit_queue, (NODE_DATA)(uintptr_t)fb->id);
-            ghash_remove(flowbit_state->flowbits_hash, n->key);
+            flowbit_state->flowbits_hash->remove(n->key);
             continue;
         }
 
index 1ac48701923ebaa6a1b5eba1dcb7ce353d1d37cd..c86362ab4bda2a916ccb2723c0bb7239ba945403 100644 (file)
@@ -221,14 +221,12 @@ static FILE* OpenSessionFile(Packet* p)
         if (errno != EEXIST)
         {
             FatalError("Problem creating directory %s: %s\n",
-                log_path,get_error(errno));
+                log_path, get_error(errno));
         }
     }
 
     if (p->ptrs.sp >= p->ptrs.dp)
         SnortSnprintf(session_file, STD_BUF, "%s/SESSION:%d-%d", log_path, p->ptrs.sp, p->ptrs.dp);
-
-
     else
         SnortSnprintf(session_file, STD_BUF, "%s/SESSION:%d-%d", log_path, p->ptrs.dp, p->ptrs.sp);
 
index 075aa2732223cc1158e7ab842c9858ec3b391c6a..ea4f8d2a2d99895d48dabf412a2062ff21a231c2 100644 (file)
@@ -248,9 +248,9 @@ static OptTreeNode* OptTreeNode_Search(uint32_t, uint32_t sid)
     if (sid == 0)
         return nullptr;
 
-    for (hashNode = ghash_findfirst(SnortConfig::get_conf()->otn_map);
+    for (hashNode = SnortConfig::get_conf()->otn_map->find_first();
         hashNode;
-        hashNode = ghash_findnext(SnortConfig::get_conf()->otn_map))
+        hashNode = SnortConfig::get_conf()->otn_map->find_next())
     {
         OptTreeNode* otn = (OptTreeNode*)hashNode->data;
         RuleTreeNode* rtn = getRuntimeRtnFromOtn(otn);
index 242eb8da7fb845111c53b3ebb8983b94f6d453f3..de51b437c251d882b233a6ad5b4e7f3b8958640c 100644 (file)
@@ -39,7 +39,7 @@ typedef unsigned char uuid_t[16];
 
 namespace snort
 {
-struct GHash;
+class GHash;
 struct SnortConfig;
 }
 
@@ -48,7 +48,7 @@ struct vartable_t;
 struct sfip_var_t;
 
 typedef unsigned int PolicyId;
-typedef struct snort::GHash PortVarTable;
+typedef snort::GHash PortVarTable;
 
 enum PolicyMode
 {
index 0ff9981af470aa480007ea1eef0a6f961fd24b13..8666ca5d8fcd31dfd87b2550ddb335dd65d2ad45 100644 (file)
@@ -270,8 +270,7 @@ SnortConfig::~SnortConfig()
     fpDeleteFastPacketDetection(this);
     OtnLookupFree(otn_map);
 
-    if (rtn_hash_table)
-        xhash_delete(rtn_hash_table);
+    delete rtn_hash_table;
 
     if (eth_dst )
         snort_free(eth_dst);
index c2d69ee9c0fab282ef5f80bdac3465e2876aee18..4c099518cd0dd6f7e1cdb47d106522092abc7422 100644 (file)
@@ -150,9 +150,9 @@ struct VarNode;
 namespace snort
 {
 class ProtocolReference;
+class GHash;
+class XHash;
 struct ProfilerConfig;
-struct GHash;
-struct XHash;
 struct SnortConfig;
 
 class ReloadResourceTuner
@@ -350,7 +350,7 @@ public:
 
     ProtocolReference* proto_ref = nullptr;
 
-    int num_rule_types = 0;
+    unsigned num_rule_types = 0;
     RuleListNode* rule_lists = nullptr;
     int evalOrder[Actions::MAX + 1];
 
index afad7ad208910aa5ca03714ac0f135a570567d9b..2ebb73c18d89b642dedfff066b2d317899d9915f 100644 (file)
@@ -908,7 +908,6 @@ Inspector* InspectorManager::acquire(const char* key, bool dflt_only)
 
     if ( !pi )
         FatalError("unconfigured inspector: '%s'.\n", key);
-
     else
         pi->add_ref();
 
index 44889bdc0ed8a5661289ce2c9f31178bafd8c4d4..7c962b6192c7c461703032b51205990f18de95b9 100644 (file)
@@ -781,20 +781,13 @@ int MimeSession::extract_file_name(const char*& start, int length, bool* disp_co
  */
 void MimeSession::init()
 {
-    const MimeToken* tmp;
-
     MimeDecode::init();
 
     mime_hdr_search_mpse = new SearchTool;
-
-    if (mime_hdr_search_mpse == nullptr)
-        FatalError("Could not instantiate search engine.\n");
-
-    for (tmp = &mime_hdrs[0]; tmp->name != nullptr; tmp++)
+    for (const MimeToken* tmp = &mime_hdrs[0]; tmp->name != nullptr; tmp++)
     {
         mime_hdr_search[tmp->search_id].name = tmp->name;
         mime_hdr_search[tmp->search_id].name_len = tmp->name_len;
-
         mime_hdr_search_mpse->add(tmp->name, tmp->name_len, tmp->search_id);
     }
 
index b21617574c827ffa4b4bb85d2bbc8cc559ebaac9..6c3ff2980ca28e8b041ba5aaf604a524f2edc266 100644 (file)
@@ -256,26 +256,6 @@ void AppIdServiceState::check_reset(AppIdSession& asd, const SfIp* ip, uint16_t
     }
 }
 
-void AppIdServiceState::dump_stats()
-{
-    // FIXIT-L - do we need to keep ipv4 and ipv6 separate?  CRC: No.
-#if 0
-    LogMessage("Service State:\n");
-    if (serviceStateCache4)
-    {
-        LogMessage("           IPv4 Count: %u\n", xhash_count(serviceStateCache4));
-        LogMessage("    IPv4 Memory Limit: %lu\n", serviceStateCache4->mc.memcap);
-        LogMessage("     IPv4 Memory Used: %lu\n", serviceStateCache4->mc.memused);
-    }
-    if (serviceStateCache6)
-    {
-        LogMessage("           IPv6 Count: %u\n", xhash_count(serviceStateCache6));
-        LogMessage("    IPv6 Memory Limit: %lu\n", serviceStateCache6->mc.memcap);
-        LogMessage("     IPv6 Memory Used: %lu\n", serviceStateCache6->mc.memused);
-    }
-#endif
-}
-
 bool AppIdServiceState::prune(size_t max_memory, size_t num_items)
 {
     if ( service_state_cache )
index bbc0a06efc0e7e9fccb866ef096e86729da95b6b..715263b657ea6b79ebbf1a4572696f989990d373 100644 (file)
@@ -156,9 +156,6 @@ public:
     static ServiceDiscoveryState* get(const snort::SfIp*, IpProtocol, uint16_t port, bool decrypted, bool do_touch = false);
     static void remove(const snort::SfIp*, IpProtocol, uint16_t port, bool decrypted);
     static void check_reset(AppIdSession& asd, const snort::SfIp* ip, uint16_t port);
-
-    static void dump_stats();
-
     static bool prune(size_t max_memory = 0, size_t num_items = -1u);
 };
 
index 9943c51ca68c47755a827061bcafedc323a3bebd..85c5eb02c6338fd058216918b34e789feb57590d 100644 (file)
@@ -61,15 +61,13 @@ FlowStateValue* FlowIPTracker::find_stats(const SfIp* src_addr, const SfIp* dst_
         *swapped = 1;
     }
 
-    value = (FlowStateValue*)xhash_find(ip_map, &key);
+    value = (FlowStateValue*)ip_map->get_user_data(&key);
     if (!value)
     {
-        XHashNode* node = xhash_get_node_with_prune(ip_map, &key, &prune_required);
+        HashNode* node = ip_map->get_node_with_prune(&key, &prune_required);
 
         if (!node)
-        {
             return nullptr;
-        }
 
         if (prune_required)
         {
@@ -88,16 +86,16 @@ bool FlowIPTracker::initialize(size_t new_memcap)
 {
     bool need_pruning = false;
 
-    if (!ip_map)
+    if ( !ip_map )
     {
-        ip_map = xhash_new(DEFAULT_XHASH_NROWS, sizeof(FlowStateKey), sizeof(FlowStateValue),
-            new_memcap, 1, nullptr, nullptr, 1);
+        ip_map = new XHash(DEFAULT_XHASH_NROWS, sizeof(FlowStateKey), sizeof(FlowStateValue),
+            new_memcap, true, nullptr, nullptr, true);
     }
     else
     {
         need_pruning = (new_memcap < memcap);
         memcap = new_memcap;
-        ip_map->mc.memcap = memcap;
+        ip_map->set_memcap(new_memcap);
     }
 
     return need_pruning;
@@ -142,23 +140,18 @@ FlowIPTracker::FlowIPTracker(PerfConfig* perf) : PerfTracker(perf, TRACKER_NAME)
     formatter->finalize_fields();
 
     memcap = perf->flowip_memcap;
-
-    ip_map = xhash_new(DEFAULT_XHASH_NROWS, sizeof(FlowStateKey), sizeof(FlowStateValue),
-        memcap, 1, nullptr, nullptr, 1);
-
-    if (!ip_map)
-        FatalError("Unable to allocate memory for FlowIP stats\n");
+    ip_map = new XHash(DEFAULT_XHASH_NROWS, sizeof(FlowStateKey), sizeof(FlowStateValue),
+        memcap, true, nullptr, nullptr, true);
 }
 
 FlowIPTracker::~FlowIPTracker()
 {
-    if ( ip_map )
-        xhash_delete(ip_map);
+    delete ip_map;
 }
 
 void FlowIPTracker::reset()
 {
-    xhash_make_empty(ip_map);
+    ip_map->clear();
 }
 
 void FlowIPTracker::update(Packet* p)
@@ -200,7 +193,7 @@ void FlowIPTracker::update(Packet* p)
 
 void FlowIPTracker::process(bool)
 {
-    for (auto node = xhash_findfirst(ip_map); node; node = xhash_findnext(ip_map))
+    for (auto node = ip_map->find_first_node(); node; node = ip_map->find_next_node())
     {
         FlowStateKey* key = (FlowStateKey*)node->key;
         FlowStateValue* cur_stats = (FlowStateValue*)node->data;
index 189df9867344ab23199ad9a3e0d30b78d53e8256..4b215808c46ab375575f3ceb2466dfd00b3ba720 100644 (file)
@@ -74,7 +74,7 @@ static const Parameter s_params[] =
     { "seconds", Parameter::PT_INT, "1:max32", "60",
       "report interval" },
 
-    { "flow_ip_memcap", Parameter::PT_INT, "8200:maxSZ", "52428800",
+    { "flow_ip_memcap", Parameter::PT_INT, "236:maxSZ", "52428800",
       "maximum memory in bytes for flow tracking" },
 
     { "max_file_size", Parameter::PT_INT, "4096:max53", "1073741824",
index 4658859e65fe830ea198bec023ca0f182003eb10..9df381e3b46b5a4b52b3aaeda6e3ad9105479bfc 100644 (file)
@@ -270,10 +270,10 @@ bool PerfMonReloadTuner::tune_resources(unsigned work_limit)
     if (flow_ip_tracker)
     {
         unsigned num_freed = 0;
-        int result = xhash_free_overallocations(flow_ip_tracker->get_ip_map(), work_limit, &num_freed);
+        int result = flow_ip_tracker->get_ip_map()->free_over_allocations(work_limit, &num_freed);
         pmstats.total_frees += num_freed;
         pmstats.reload_frees += num_freed;
-        return (result == XHASH_OK);
+        return (result == HASH_OK);
     }
     else
         return true;
index d04dd71bb59a7abb9224254954892a4eec14aecf..4ee4800b3c0111f9ce6a177188297dce2afa1b22 100644 (file)
@@ -114,7 +114,7 @@ void ps_cleanup()
 {
     if ( portscan_hash )
     {
-        xhash_delete(portscan_hash);
+        delete portscan_hash;
         portscan_hash = nullptr;
     }
 }
@@ -126,18 +126,14 @@ bool ps_init_hash(unsigned long memcap)
 {
     if ( portscan_hash )
     {
-        bool need_pruning = (memcap < portscan_hash->mc.memused);
-        portscan_hash->mc.memcap = memcap;
+        bool need_pruning = (memcap < portscan_hash->get_mem_used());
+        portscan_hash->set_memcap(memcap);
         return need_pruning;
     }
 
     int rows = memcap / ps_node_size();
-
-    portscan_hash = xhash_new(rows, sizeof(PS_HASH_KEY), sizeof(PS_TRACKER),
-        memcap, 1, ps_tracker_free, nullptr, 1);
-
-    if ( !portscan_hash )
-        FatalError("Failed to initialize portscan hash table.\n");
+    portscan_hash = new XHash(rows, sizeof(PS_HASH_KEY), sizeof(PS_TRACKER),
+        memcap, true, ps_tracker_free, nullptr, true);
 
     return false;
 }
@@ -148,15 +144,15 @@ bool ps_prune_hash(unsigned work_limit)
         return true;
 
     unsigned num_pruned = 0;
-    int result = xhash_free_overallocations(portscan_hash, work_limit, &num_pruned);
+    int result = portscan_hash->free_over_allocations(work_limit, &num_pruned);
     spstats.reload_prunes += num_pruned;
-    return result != XHASH_PENDING;
+    return result != HASH_PENDING;
 }
 
 void ps_reset()
 {
     if ( portscan_hash )
-        xhash_make_empty(portscan_hash);
+        portscan_hash->clear();
 }
 
 //  Check scanner and scanned ips to see if we can filter them out.
@@ -296,20 +292,20 @@ bool PortScan::ps_filter_ignore(PS_PKT* ps_pkt)
 */
 static PS_TRACKER* ps_tracker_get(PS_HASH_KEY* key)
 {
-    PS_TRACKER* ht = (PS_TRACKER*)xhash_find(portscan_hash, (void*)key);
+    PS_TRACKER* ht = (PS_TRACKER*)portscan_hash->get_user_data((void*)key);
 
     if ( ht )
         return ht;
 
-    auto prev_count = portscan_hash->count;
-    if ( xhash_add(portscan_hash, (void*)key, nullptr) != XHASH_OK )
+    auto prev_count = portscan_hash->get_node_count();
+    if ( portscan_hash->insert((void*)key, nullptr) != HASH_OK )
         return nullptr;
 
     ++spstats.trackers;
-    if ( prev_count == portscan_hash->count )
+    if ( prev_count == portscan_hash->get_node_count() )
         ++spstats.alloc_prunes;
 
-    ht = (PS_TRACKER*)xhash_mru(portscan_hash);
+    ht = (PS_TRACKER*)portscan_hash->get_mru_user_data();
 
     if ( ht )
         memset(ht, 0x00, sizeof(PS_TRACKER));
index f26aee626d5970d53a30ad89090251b17a05f8c1..8ed5686c07a28b63522d4f84b4de424bfc99050f 100644 (file)
@@ -221,11 +221,7 @@ static uint16_t POParserGetShort(POParser* pop)
 
 static PortObject* _POParseVar(POParser* pop)
 {
-    PortObject* pox;
-    char* name;
-
-    name  = POParserName(pop);
-
+    char* name  = POParserName(pop);
     if (!name)
     {
         pop->pos++;
@@ -233,7 +229,7 @@ static PortObject* _POParseVar(POParser* pop)
         return nullptr;
     }
 
-    pox = PortVarTableFind(pop->pvTable, name);
+    PortObject* pox = PortVarTableFind(pop->pvTable, name);
     snort_free(name);
 
     if (!pox)
@@ -243,13 +239,6 @@ static PortObject* _POParseVar(POParser* pop)
     }
 
     pox = PortObjectDup(pox);
-
-    if (!pox)
-    {
-        pop->errflag = POPERR_MALLOC_FAILED;
-        return nullptr;
-    }
-
     return pox;
 }
 
@@ -257,12 +246,6 @@ static PortObject* _POParsePort(POParser* pop)
 {
     PortObject* po = PortObjectNew();
 
-    if (!po)
-    {
-        pop->errflag = POPERR_MALLOC_FAILED;
-        return nullptr;
-    }
-
     pop->token[0] = 0;
 
     /* The string in pop should only be of the form <port> or <port>:<port> */
@@ -329,20 +312,12 @@ static PortObject* _POParsePort(POParser* pop)
 
 static PortObject* _POParseString(POParser* pop)
 {
-    PortObject* po;
     PortObject* potmp = nullptr;
     int local_neg = 0;
     char c;
     int list_count = 0;
 
-    po = PortObjectNew();
-
-    if (!po)
-    {
-        pop->errflag = POPERR_MALLOC_FAILED;
-        return nullptr;
-    }
-
+    PortObject* po = PortObjectNew();
     while ( (c = POPGetChar2(pop)) != 0 )
     {
         if (c == '!')
@@ -475,16 +450,8 @@ static PortObject* _POParseString(POParser* pop)
 PortObject* PortObjectParseString(PortVarTable* pvTable, POParser* pop,
     const char* name, const char* s, int nameflag)
 {
-    PortObject* po, * potmp;
-
     POParserInit(pop, s, pvTable);
-
-    po = PortObjectNew();
-    if ( !po )
-    {
-        pop->errflag = POPERR_MALLOC_FAILED;
-        return nullptr;
-    }
+    PortObject* po = PortObjectNew();
 
     if ( nameflag ) /* parse a name */
     {
@@ -506,8 +473,7 @@ PortObject* PortObjectParseString(PortVarTable* pvTable, POParser* pop,
 
     // LogMessage("PortObjectParseString: po->name=%s\n",po->name);
 
-    potmp = _POParseString(pop);
-
+    PortObject* potmp = _POParseString(pop);
     if ( !potmp )
     {
         PortObjectFree(po);
index 684ba679b1d3a530de2102b099eedfa629362480..4cba6699e4e632df95ec323059e2b0a26a212b0c 100644 (file)
@@ -223,15 +223,8 @@ static int FinishPortListRule(
         PortObject* pox = PortTableFindInputPortObjectPorts(dstTable, rtn->dst_portobject);
         if ( !pox )
         {
-            /* Create a permanent port object */
-            pox = PortObjectDupPorts(rtn->dst_portobject);
-            if ( !pox )
-            {
-                ParseError("could not dup a port object - out of memory.");
-                return -1;
-            }
-
             /* Add the port object to the table, and add the rule to the port object */
+            pox = PortObjectDupPorts(rtn->dst_portobject);
             PortTableAddObject(dstTable, pox);
         }
 
@@ -244,12 +237,6 @@ static int FinishPortListRule(
             if ( !pox )
             {
                 pox = PortObjectDupPorts(rtn->dst_portobject);
-                if ( !pox )
-                {
-                    ParseError("could not dup a bidir-port object - out of memory.");
-                    return -1;
-                }
-
                 PortTableAddObject(srcTable, pox);
             }
 
@@ -262,15 +249,9 @@ static int FinishPortListRule(
     {
         prc->src++;
         PortObject* pox = PortTableFindInputPortObjectPorts(srcTable, rtn->src_portobject);
-
         if ( !pox )
         {
             pox = PortObjectDupPorts(rtn->src_portobject);
-            if ( !pox )
-            {
-                ParseError("could not dup a port object - out of memory.");
-                return -1;
-            }
             PortTableAddObject(srcTable, pox);
         }
 
@@ -283,12 +264,6 @@ static int FinishPortListRule(
             if ( !pox )
             {
                 pox = PortObjectDupPorts(rtn->src_portobject);
-                if ( !pox )
-                {
-                    ParseError("could not dup a bidir-port object - out of memory.");
-                    return -1;
-                }
-
                 PortTableAddObject(dstTable, pox);
             }
             PortObjectAddRule(pox, otn->ruleIndex);
@@ -625,7 +600,7 @@ static RuleTreeNode* findHeadNode(
     if ( sc->rtn_hash_table )
     {
         RuleTreeNodeKey key { testNode, policyId };
-        return (RuleTreeNode*)xhash_find(sc->rtn_hash_table, &key);
+        return (RuleTreeNode*)sc->rtn_hash_table->get_user_data(&key);
     }
 
     return nullptr;
index a845117d7d7ac242a67cc11df71a8f4ac71954b9..fe5860b6197a4b24017d64e15370852ce0a08743 100644 (file)
@@ -73,9 +73,9 @@ static void FreeRuleTreeNodes(SnortConfig* sc)
     if ( !sc->otn_map )
         return;
 
-    for ( GHashNode* hashNode = ghash_findfirst(sc->otn_map);
-        hashNode;
-        hashNode = ghash_findnext(sc->otn_map) )
+    for (GHashNode* hashNode = sc->otn_map->find_first();
+         hashNode;
+         hashNode = sc->otn_map->find_next())
     {
         OptTreeNode* otn = (OptTreeNode*)hashNode->data;
 
@@ -188,16 +188,12 @@ static void OtnInit(SnortConfig* sc)
 
     /* Init sid-gid -> otn map */
     sc->otn_map = OtnLookupNew();
-    if (sc->otn_map == nullptr)
-        ParseAbort("otn_map ghash_new failed.");
 }
 
-static RuleListNode* addNodeToOrderedList(RuleListNode* ordered_list,
-    RuleListNode* node, int evalIndex)
+static RuleListNode* addNodeToOrderedList
+    (RuleListNode* ordered_list, RuleListNode* node, unsigned evalIndex)
 {
-    RuleListNode* prev;
-
-    prev = ordered_list;
+    RuleListNode* prev = ordered_list;
 
     /* set the eval order for this rule set */
     node->evalIndex = evalIndex;
@@ -417,7 +413,7 @@ void ParseRules(SnortConfig* sc)
 ListHead* CreateRuleType(SnortConfig* sc, const char* name, Actions::Type mode)
 {
     RuleListNode* node;
-    int evalIndex = 0;
+    unsigned evalIndex = 0;
 
     if (sc == nullptr)
         return nullptr;
@@ -556,7 +552,7 @@ RuleTreeNode* deleteRtnFromOtn(OptTreeNode* otn, PolicyId policyId, SnortConfig*
             {
                 assert(sc and sc->rtn_hash_table);
                 RuleTreeNodeKey key { rtn, policyId };
-                xhash_remove(sc->rtn_hash_table, &key);
+                sc->rtn_hash_table->release_node(&key);
             }
         }
         return rtn;
@@ -590,21 +586,21 @@ static uint32_t rtn_hash_func(HashFnc*, const unsigned char* k, int)
     return c;
 }
 
-static int rtn_compare_func(const void* k1, const void* k2, size_t)
+static bool rtn_compare_func(const void* k1, const void* k2, size_t)
 {
     const RuleTreeNodeKey* rtnk1 = (const RuleTreeNodeKey*)k1;
     const RuleTreeNodeKey* rtnk2 = (const RuleTreeNodeKey*)k2;
 
     if (!rtnk1 || !rtnk2)
-        return 1;
+        return false;
 
     if (rtnk1->policyId != rtnk2->policyId)
-        return 1;
+        return false;
 
     if (same_headers(rtnk1->rtn, rtnk2->rtn))
-        return 0;
+        return true;
 
-    return 1;
+    return false;
 }
 
 int addRtnToOtn(SnortConfig* sc, OptTreeNode* otn, RuleTreeNode* rtn, PolicyId policyId)
@@ -642,20 +638,16 @@ int addRtnToOtn(SnortConfig* sc, OptTreeNode* otn, RuleTreeNode* rtn, PolicyId p
 
     if (!sc->rtn_hash_table)
     {
-        sc->rtn_hash_table = xhash_new(
-            10000, sizeof(RuleTreeNodeKey), 0, 0, 0, nullptr, nullptr, 1);
-
-        if (sc->rtn_hash_table == nullptr)
-            FatalError("Failed to create rule tree node hash table\n");
-
-        xhash_set_keyops(sc->rtn_hash_table, rtn_hash_func, rtn_compare_func);
+        sc->rtn_hash_table = new XHash(
+            10000, sizeof(RuleTreeNodeKey), 0, 0, false, nullptr, nullptr, true);
+        sc->rtn_hash_table->set_key_opcodes(rtn_hash_func, rtn_compare_func);
     }
 
     RuleTreeNodeKey key;
     memset(&key, 0, sizeof(key));
     key.rtn = rtn;
     key.policyId = policyId;
-    xhash_add(sc->rtn_hash_table, &key, rtn);
+    sc->rtn_hash_table->insert(&key, rtn);
 
     return 0;
 }
index f58c734f9b95bf3a832c3067adf62ffc5d8b9fc0..5e7f67b6a1f15164300fdc045068b79c94d640d2 100644 (file)
@@ -139,10 +139,6 @@ int PortVarDefine(SnortConfig* sc, const char* name, const char* s)
         }
 
         po = PortObjectNew();
-        if ( !po )
-        {
-            ParseAbort("PortVarTable missing an 'any' variable.");
-        }
         PortObjectSetName(po, name);
         PortObjectAddPortAny(po);
     }
@@ -382,9 +378,8 @@ void DisallowCrossTableDuplicateVars(
     switch (var_type)
     {
     case VAR_TYPE__DEFAULT:
-        if (PortVarTableFind(portVarTable, name)
-            || sfvt_lookup_var(ip_vartable, name)
-            )
+        if ( PortVarTableFind(portVarTable, name)
+            || sfvt_lookup_var(ip_vartable, name) )
         {
             ParseError("can not redefine variable name %s to be of type "
                 "'var'. Use a different name.", name);
@@ -392,11 +387,11 @@ void DisallowCrossTableDuplicateVars(
         break;
 
     case VAR_TYPE__PORTVAR:
-        if (var_table != nullptr)
+        if ( var_table )
         {
             do
             {
-                if (strcasecmp(p->name, name) == 0)
+                if ( strcasecmp(p->name, name) == 0 )
                 {
                     ParseError("can not redefine variable name %s to be of "
                         "type 'portvar'. Use a different name.", name);
@@ -406,7 +401,7 @@ void DisallowCrossTableDuplicateVars(
             while (p != var_table);
         }
 
-        if (sfvt_lookup_var(ip_vartable, name))
+        if ( sfvt_lookup_var(ip_vartable, name) )
         {
             ParseError("can not redefine variable name %s to be of type "
                 "'portvar'. Use a different name.", name);
@@ -415,11 +410,11 @@ void DisallowCrossTableDuplicateVars(
         break;
 
     case VAR_TYPE__IPVAR:
-        if (var_table != nullptr)
+        if ( var_table )
         {
             do
             {
-                if (strcasecmp(p->name, name) == 0)
+                if ( strcasecmp(p->name, name) == 0 )
                 {
                     ParseError("can not redefine variable name %s to be of "
                         "type 'ipvar'. Use a different name.", name);
@@ -430,11 +425,12 @@ void DisallowCrossTableDuplicateVars(
             while (p != var_table);
         }
 
-        if (PortVarTableFind(portVarTable, name))
+        if ( PortVarTableFind(portVarTable, name) )
         {
             ParseError("can not redefine variable name %s to be of type "
                 "'ipvar'. Use a different name.", name);
         }
+        break;
 
     default:
         /* Invalid function usage */
index 07e837b2c9da0551872fbcc4055543ed74a16f2e..5b87aaf1a5fdc89b98b863b15d563de909e69828 100644 (file)
@@ -53,17 +53,8 @@ void PortObjectItemFree(PortObjectItem* poi)
 */
 PortObjectItem* PortObjectItemDup(PortObjectItem* poi)
 {
-    PortObjectItem* poinew;
-
-    if ( !poi )
-        return nullptr;
-
-    poinew = PortObjectItemNew();
-    if ( !poinew )
-        return nullptr;
-
-    memcpy(poinew,poi,sizeof(PortObjectItem));
-
+    PortObjectItem* poinew = PortObjectItemNew();
+    memcpy(poinew,poi, sizeof(PortObjectItem));
     return poinew;
 }
 
index 71bab6aeb5c25c0fa3b461af6578229785314942..5e6114e3da723be52abfd433b7af367beafdccb6 100644 (file)
@@ -112,9 +112,9 @@ int PortObjectAddItem(PortObject* po, PortObjectItem* poi, int* errflag)
         *errflag = 0;
 
     /* Make sure this is not a duplicate */
-    for (p=(PortObjectItem*)sflist_first(po->item_list,&pos);
+    for (p = (PortObjectItem*)sflist_first(po->item_list,&pos);
         p != nullptr;
-        p=(PortObjectItem*)sflist_next(&pos) )
+        p = (PortObjectItem*)sflist_next(&pos))
     {
         if ((p->lport == poi->lport) && (p->hport == poi->hport))
             ParseWarning(WARN_RULES, "duplicate ports in list");
@@ -159,10 +159,6 @@ int PortObjectAddPort(PortObject* po, int port)
 int PortObjectAddRange(PortObject* po, int lport, int hport)
 {
     PortObjectItem* poi = PortObjectItemNew();
-
-    if ( !poi )
-        return -1;
-
     poi->lport = (unsigned short)lport;
     poi->hport = (unsigned short)hport;
 
@@ -205,9 +201,6 @@ PortObject* PortObjectDup(PortObject* po)
     SF_LNODE* lpos = nullptr;
     PortObject* ponew = PortObjectNew();
 
-    if ( !ponew )
-        return nullptr;
-
     /* Dup the Name */
     if ( po->name )
         ponew->name = snort_strdup(po->name);
@@ -217,18 +210,11 @@ PortObject* PortObjectDup(PortObject* po)
     /* Dup the Item List */
     if ( po->item_list )
     {
-        for (PortObjectItem* poi =(PortObjectItem*)sflist_first(po->item_list,&lpos);
+        for (PortObjectItem* poi = (PortObjectItem*)sflist_first(po->item_list, &lpos);
             poi != nullptr;
-            poi =(PortObjectItem*)sflist_next(&lpos) )
+            poi = (PortObjectItem*)sflist_next(&lpos) )
         {
             PortObjectItem* poinew = PortObjectItemDup(poi);
-
-            if (!poinew)
-            {
-                PortObjectFree(ponew);
-                return nullptr;
-            }
-
             PortObjectAddItem(ponew, poinew, nullptr);
         }
     }
@@ -236,13 +222,13 @@ PortObject* PortObjectDup(PortObject* po)
     /* Dup the input rule list */
     if ( po->rule_list )
     {
-        for (int* prid  = (int*)sflist_first(po->rule_list,&lpos);
+        for (int* prid  = (int*)sflist_first(po->rule_list, &lpos);
             prid != nullptr;
             prid  = (int*)sflist_next(&lpos) )
         {
             int* prule = (int*)snort_calloc(sizeof(int));
             *prule = *prid;
-            sflist_add_tail(ponew->rule_list,prule);
+            sflist_add_tail(ponew->rule_list, prule);
         }
     }
 
@@ -257,9 +243,6 @@ PortObject* PortObjectDupPorts(PortObject* po)
     SF_LNODE* lpos = nullptr;
     PortObject* ponew = PortObjectNew();
 
-    if ( !ponew )
-        return nullptr;
-
     /* Dup the Name */
     if ( po->name )
         ponew->name = snort_strdup(po->name);
@@ -269,17 +252,11 @@ PortObject* PortObjectDupPorts(PortObject* po)
     /* Dup the Item List */
     if ( po->item_list )
     {
-        for (PortObjectItem* poi =(PortObjectItem*)sflist_first(po->item_list,&lpos);
+        for (PortObjectItem* poi = (PortObjectItem*)sflist_first(po->item_list, &lpos);
             poi != nullptr;
-            poi =(PortObjectItem*)sflist_next(&lpos) )
+            poi = (PortObjectItem*)sflist_next(&lpos))
         {
             PortObjectItem* poinew = PortObjectItemDup(poi);
-
-            if (!poinew)
-            {
-                PortObjectFree(ponew);
-                return nullptr;
-            }
             PortObjectAddItem(ponew, poinew, nullptr);
         }
     }
@@ -503,9 +480,9 @@ PortObject* PortObjectAppend(PortObject* poa, PortObject* pob)
 {
     SF_LNODE* cursor;
 
-    for ( PortObjectItem* poib = (PortObjectItem*)sflist_first(pob->item_list, &cursor);
-        poib!= nullptr;
-        poib = (PortObjectItem*)sflist_next(&cursor) )
+    for (PortObjectItem* poib = (PortObjectItem*)sflist_first(pob->item_list, &cursor);
+         poib!= nullptr;
+         poib = (PortObjectItem*)sflist_next(&cursor) )
     {
         PortObjectItem* poia = PortObjectItemNew();
 
@@ -589,13 +566,11 @@ void PortObjectPrintEx(PortObject* po, po_print_f print_index_map)
     SnortSnprintfAppend(print_buf, bufsize, " PortObject ");
 
     if ( po->name )
-    {
         SnortSnprintfAppend(print_buf, bufsize, "%s ", po->name);
-    }
 
     SnortSnprintfAppend(print_buf, bufsize,
         " Id:%d  Ports:%u Rules:%u\n {\n",
-        po->id, po->item_list->count,po->rule_list->count);
+        po->id, po->item_list->count, po->rule_list->count);
 
     SnortSnprintfAppend(print_buf, bufsize, "  Ports [\n  ");
 
@@ -605,9 +580,9 @@ void PortObjectPrintEx(PortObject* po, po_print_f print_index_map)
     }
     else
     {
-        for (poi=(PortObjectItem*)sflist_first(po->item_list,&pos);
+        for (poi = (PortObjectItem*)sflist_first(po->item_list,&pos);
             poi != nullptr;
-            poi=(PortObjectItem*)sflist_next(&pos) )
+            poi = (PortObjectItem*)sflist_next(&pos) )
         {
             PortObjectItemPrint(poi, print_buf, bufsize);
         }
@@ -621,16 +596,13 @@ void PortObjectPrintEx(PortObject* po, po_print_f print_index_map)
     }
 
     SnortSnprintfAppend(print_buf, bufsize, "  Rules [ \n ");
-    for (i=0; i<po->rule_list->count; i++)
+    for (i = 0; i < po->rule_list->count; i++)
     {
         if ( print_index_map )
-        {
             print_index_map(rlist[i], print_buf, bufsize);
-        }
         else
-        {
             SnortSnprintfAppend(print_buf, bufsize, " %d",rlist[i]);
-        }
+
         k++;
         if ( k == 25 )
         {
index 72ce99a424f007abc1e62598612d4e814beccbdd..090dd74303859c8161b1f3694f8b2ebece70fecd 100644 (file)
@@ -73,25 +73,33 @@ static unsigned po_rule_hash_func(HashFnc* p, const unsigned char* k, int n)
 
 static int* RuleHashToSortedArray(GHash* rh)
 {
-    if ( !rh or !rh->count )
+    if ( !rh or !rh->get_count() )
         return nullptr;
 
-    int* ra = (int*)snort_calloc(rh->count, sizeof(int));
+    int* ra = (int*)snort_calloc(rh->get_count(), sizeof(int));
     int k = 0;
 
-    for ( GHashNode* node = ghash_findfirst(rh);
-        node != nullptr && k < (int)rh->count;
-        node = ghash_findnext(rh) )
+    for (GHashNode* node = rh->find_first();
+         node != nullptr && k < (int)rh->get_count();
+         node = rh->find_next() )
     {
         if ( int* prid = (int*)node->data )
             ra[k++] = *prid;
     }
 
-    qsort(ra,rh->count,sizeof(int),integer_compare);
+    qsort(ra, rh->get_count(), sizeof(int), integer_compare);
 
     return ra;
 }
 
+static bool port_object_key_compare_func(const void* k1, const void* k2, size_t len)
+{
+    if ( memcmp(k1, k2, len ) )
+        return false;
+    else
+        return true;
+}
+
 //-------------------------------------------------------------------------
 // PortObject2 - public
 //-------------------------------------------------------------------------
@@ -99,25 +107,11 @@ static int* RuleHashToSortedArray(GHash* rh)
 PortObject2* PortObject2New(int nrules)
 {
     PortObject2* po = (PortObject2*)snort_calloc(sizeof(PortObject2));
-    po->item_list =(SF_LIST*)sflist_new();
-
-    if ( !po->item_list )
-    {
-        snort_free(po);
-        return nullptr;
-    }
-
-    po->rule_hash =(GHash*)ghash_new(nrules,sizeof(int), 0,
-        snort_free /* frees data - should be rule id ptrs == (int*) */);
-    if ( !po->rule_hash )
-    {
-        sflist_free_all(po->item_list, snort_free);
-        snort_free(po);
-        return nullptr;
-    }
+    po->item_list = sflist_new();
+    po->rule_hash = new GHash(nrules, sizeof(int), 0, snort_free);
 
     /* Use hash function defined above for hashing the key as an int. */
-    ghash_set_keyops(po->rule_hash, po_rule_hash_func, memcmp);
+    po->rule_hash->set_key_opcodes(po_rule_hash_func, port_object_key_compare_func);
 
     return po;
 }
@@ -134,7 +128,7 @@ void PortObject2Free(PortObject2* po)
         sflist_free_all(po->item_list, snort_free);
 
     if ( po->rule_hash)
-        ghash_delete(po->rule_hash);
+        delete po->rule_hash;
 
     if (po->port_list)
         delete po->port_list;
@@ -150,71 +144,53 @@ void PortObject2Finalize(PortObject2* po)
     sflist_free_all(po->item_list, snort_free);
     po->item_list = nullptr;
 
-    ghash_delete(po->rule_hash);
+    delete po->rule_hash;
     po->rule_hash = nullptr;
 }
 
 /*
  * Dup the PortObjects Item List, Name, and RuleList->RuleHash
  */
-PortObject2* PortObject2Dup(PortObject* po)
+PortObject2* PortObject2Dup(PortObject& po)
 {
-    PortObject2* ponew = nullptr;
-    PortObjectItem* poi = nullptr;
-    PortObjectItem* poinew = nullptr;
-    SF_LNODE* lpos = nullptr;
-    int* prid = nullptr;
-    int* prule = nullptr;
+    assert( po.rule_list );
 
-    if ( !po )
-        return nullptr;
+    PortObject2* ponew = PortObject2New(po.rule_list->count + PO_EXTRA_RULE_CNT);
 
-    if ( !po->rule_list )
-        return nullptr;
-
-    ponew = PortObject2New(po->rule_list->count + PO_EXTRA_RULE_CNT);
-    if ( !ponew )
-        return nullptr;
-
-    /* Dup the Name */
-    if ( po->name )
-        ponew->name = snort_strdup(po->name);
+    if ( po.name )
+        ponew->name = snort_strdup(po.name);
     else
         ponew->name = snort_strdup("dup");
 
     /* Dup the Item List */
-    if ( po->item_list )
+    if ( po.item_list )
     {
-        for (poi =(PortObjectItem*)sflist_first(po->item_list,&lpos);
-            poi != nullptr;
-            poi =(PortObjectItem*)sflist_next(&lpos) )
-        {
-            poinew = PortObjectItemDup(poi);
-
-            if (!poinew)
-            {
-                PortObject2Free(ponew);
-                return nullptr;
-            }
+        PortObjectItem* poi = nullptr;
+        SF_LNODE* lpos = nullptr;
 
+        for (poi = (PortObjectItem*)sflist_first(po.item_list, &lpos);
+             poi != nullptr;
+             poi = (PortObjectItem*)sflist_next(&lpos) )
+        {
+            PortObjectItem* poinew = PortObjectItemDup(poi);
             PortObjectAddItem( (PortObject*)ponew, poinew, nullptr);
         }
     }
 
     /* Dup the input rule list */
-    if ( po->rule_list )
+    if ( po.rule_list )
     {
-        for (prid  = (int*)sflist_first(po->rule_list,&lpos);
-            prid != nullptr;
-            prid  = (int*)sflist_next(&lpos) )
+        SF_LNODE* lpos = nullptr;
+
+        for (int* prid  = (int*)sflist_first(po.rule_list, &lpos);
+             prid != nullptr;
+             prid  = (int*)sflist_next(&lpos) )
         {
-            prule = (int*)snort_calloc(sizeof(int));
+            int* prule = (int*)snort_calloc(sizeof(int));
             *prule = *prid;
 
-            if ( ghash_add(ponew->rule_hash, prule, prule) != GHASH_OK )
-            {
+            if ( ponew->rule_hash->insert(prule, prule) != GHASH_OK )
                 snort_free(prule);
-            }
         }
     }
 
@@ -243,14 +219,14 @@ PortObject2* PortObject2AppendPortObject(PortObject2* poa, PortObject* pob)
 {
     SF_LNODE* lpos;
 
-    for ( int* prid = (int*)sflist_first(pob->rule_list,&lpos);
-        prid!= nullptr;
-        prid = (int*)sflist_next(&lpos) )
+    for (int* prid = (int*)sflist_first(pob->rule_list, &lpos);
+         prid!= nullptr;
+         prid = (int*)sflist_next(&lpos) )
     {
         int* prid2 = (int*)snort_calloc(sizeof(int));
         *prid2 = *prid;
 
-        if ( ghash_add(poa->rule_hash,prid2,prid2) != GHASH_OK )
+        if ( poa->rule_hash->insert(prid2, prid2) != GHASH_OK )
             snort_free(prid2);
     }
     return poa;
@@ -259,9 +235,9 @@ PortObject2* PortObject2AppendPortObject(PortObject2* poa, PortObject* pob)
 /* Dup and append rule list numbers from pob to poa */
 PortObject2* PortObject2AppendPortObject2(PortObject2* poa, PortObject2* pob)
 {
-    for (GHashNode* node = ghash_findfirst(pob->rule_hash);
-        node!= nullptr;
-        node = ghash_findnext(pob->rule_hash) )
+    for (GHashNode* node = pob->rule_hash->find_first();
+         node!= nullptr;
+         node = pob->rule_hash->find_next() )
     {
         int* prid = (int*)node->data;
 
@@ -271,7 +247,7 @@ PortObject2* PortObject2AppendPortObject2(PortObject2* poa, PortObject2* pob)
         int* prid2 = (int*)snort_calloc(sizeof(int));
         *prid2 = *prid;
 
-        if ( ghash_add(poa->rule_hash,prid2,prid2) != GHASH_OK )
+        if ( poa->rule_hash->insert(prid2, prid2) != GHASH_OK )
             snort_free(prid2);
     }
     return poa;
@@ -295,22 +271,18 @@ PortObject2* PortObjectAppendEx2(PortObject2* poa, PortObject* pob)
 
 void PortObject2PrintPorts(PortObject2* po)
 {
-    PortObjectItem* poi = nullptr;
     SF_LNODE* pos = nullptr;
     int bufsize = sizeof(po_print_buf);
 
     po_print_buf[0] = '\0';
-
     SnortSnprintfAppend(po_print_buf, bufsize, " PortObject ");
 
     if ( po->name )
-    {
         SnortSnprintfAppend(po_print_buf, bufsize, "%s ", po->name);
-    }
 
     SnortSnprintfAppend(po_print_buf, bufsize,
         " Id:%d  Ports:%u Rules:%u\n {\n Ports [",
-        po->id, po->item_list->count, po->rule_hash->count);
+        po->id, po->item_list->count, po->rule_hash->get_count());
 
     if ( PortObjectHasAny( (PortObject*)po) )
     {
@@ -318,9 +290,9 @@ void PortObject2PrintPorts(PortObject2* po)
     }
     else
     {
-        for (poi=(PortObjectItem*)sflist_first(po->item_list,&pos);
-            poi != nullptr;
-            poi=(PortObjectItem*)sflist_next(&pos) )
+        for (PortObjectItem* poi = (PortObjectItem*)sflist_first(po->item_list, &pos);
+             poi != nullptr;
+             poi = (PortObjectItem*)sflist_next(&pos) )
         {
             PortObjectItemPrint(poi, po_print_buf, bufsize);
         }
@@ -348,7 +320,7 @@ void PortObject2PrintEx(PortObject2* po,
         SnortSnprintfAppend(po_print_buf, bufsize, "%s ",po->name);
 
     SnortSnprintfAppend(po_print_buf, bufsize, " Id:%d  Ports:%u Rules:%u PortUsageCnt=%d\n {\n",
-        po->id, po->item_list->count, po->rule_hash->count, po->port_cnt);
+        po->id, po->item_list->count, po->rule_hash->get_count(), po->port_cnt);
 
     SnortSnprintfAppend(po_print_buf, bufsize, "  Ports [\n  ");
 
@@ -373,7 +345,7 @@ void PortObject2PrintEx(PortObject2* po,
         return;
 
     SnortSnprintfAppend(po_print_buf, bufsize, "  Rules [ \n ");
-    for (i=0; i<po->rule_hash->count; i++)
+    for (i = 0; i < po->rule_hash->get_count(); i++)
     {
         if ( print_index_map )
         {
index 0c7136acf5b04c9a018fba2ab3a91982a2e011fa..e95cccf2251ac27fb1097ba5ca68c4fc5d7756ce 100644 (file)
@@ -52,7 +52,7 @@ struct PortObject2
 PortObject2* PortObject2New(int nrules /*guess at this */);
 void PortObject2Free(PortObject2*);
 void PortObject2Finalize(PortObject2*);
-PortObject2* PortObject2Dup(PortObject*);
+PortObject2* PortObject2Dup(PortObject&);
 
 typedef void (*PortObjectIterator)(int port, void*);
 void PortObject2Iterate(PortObject2*, PortObjectIterator, void*);
index 25db02f8db1e329a57441732a99bc0d085308e86..71e30bf0e35a527eda1fb84d2ff34c2f35f58e03 100644 (file)
@@ -52,8 +52,7 @@ struct plx_t
 
 static plx_t* plx_new(void* pv_array[], int n)
 {
-    if (!pv_array || n < 0)
-        return nullptr;
+    assert( pv_array && n > 0);
 
     plx_t* p = (plx_t*)snort_calloc(sizeof(plx_t));
     p->p = (void**)snort_calloc(n, sizeof(void*));
@@ -117,24 +116,24 @@ static inline int p_keycmp(const void* a, const void* b)
    -1, and +1 are not strictly needed, they could both return
    a non zero value for the purposes of hashing and searching.
 */
-static int plx_keycmp(const void* a, const void* b, size_t)
+static bool plx_keycmp(const void* a, const void* b, size_t)
 {
     const plx_t* pla = *(plx_t* const*)a;
     const plx_t* plb = *(plx_t* const*)b;
 
     if ( pla->n < plb->n )
-        return -1;
+        return false;
 
     if ( pla->n > plb->n )
-        return 1;
+        return false;
 
     for ( int i = 0; i < pla->n; i++ )
     {
-        if ( int cmp = p_keycmp(&pla->p[i], &plb->p[i]) )
-            return cmp;
+        if ( p_keycmp(&pla->p[i], &plb->p[i]) )
+            return false;
     }
 
-    return 0; /* they are equal */
+    return true; /* they are equal */
 }
 
 //-------------------------------------------------------------------------
@@ -146,9 +145,9 @@ static int plx_keycmp(const void* a, const void* b, size_t)
 
    return values memcmp style
 */
-static int PortObject_keycmp(const void* a, const void* b, size_t)
+static bool PortObject_keycmp(const void* a, const void* b, size_t)
 {
-    return !PortObjectEqual(*(PortObject* const*)a, *(PortObject* const*)b);
+    return PortObjectEqual(*(PortObject* const*)a, *(PortObject* const*)b);
 }
 
 /*
@@ -167,9 +166,9 @@ static unsigned PortObject_hash(HashFnc* p, const unsigned char* d, int)
     SF_LNODE* pos;
 
     /* hash up each item */
-    for ( PortObjectItem* poi = (PortObjectItem*)sflist_first(po->item_list, &pos);
-        poi != nullptr;
-        poi = (PortObjectItem*)sflist_next(&pos) )
+    for (PortObjectItem* poi = (PortObjectItem*)sflist_first(po->item_list, &pos);
+         poi != nullptr;
+         poi = (PortObjectItem*)sflist_next(&pos) )
     {
         if ( poi->any() )
             continue;
@@ -225,112 +224,48 @@ static unsigned PortObject_hash(HashFnc* p, const unsigned char* d, int)
  * lookup.
  */
 static PortObject2* _merge_N_pol(
-    GHash* mhash, GHash* mhashx,
-    SF_LIST* plx_list, void** pol,
-    int pol_cnt, plx_t* plx)
+    GHash* mhash, GHash* mhashx, SF_LIST* plx_list,
+    void** pol, int pol_cnt, plx_t* plx)
 {
-    PortObject2* ponew;
-    PortObject2* pox;
-    plx_t* plx_tmp;
-    int stat;
-
-    /*
-    * Check for the merged port object in the plx table
-    */
-    ponew = (PortObject2*)ghash_find(mhashx, &plx);
-
+    // Check for the merged port object in the plx table
+    PortObject2* ponew = (PortObject2*)mhashx->find(&plx);
     if ( ponew )
-    {
         return ponew;
-    }
-
-    /*
-    *  Merge the port objects together - ports and rules
-    */
 
-    /* Dup the 1st port objects rules and ports */
-    ponew = PortObject2Dup( (PortObject*)pol[0]);
-    if ( !ponew )
-    {
-        FatalError("Could not Dup2\n");
-    }
+    // Merge the port objects together - ports and rules
+    // Dup the 1st port objects rules and ports
+    ponew = PortObject2Dup(*((PortObject*)pol[0]));
 
-    /* Merge in all the other port object rules and ports */
+    // Merge in all the other port object rules and ports
     if ( pol_cnt > 1 )
     {
         for ( int i = 1; i < pol_cnt; i++ )
-        {
             PortObjectAppendEx2(ponew, (PortObject*)pol[i]);
-        }
-        PortObjectNormalize( (PortObject*)ponew);
-    }
-
-    // PortObjectPrint2(ponew);
-
-    /*
-    * Add the Merged PortObject2 to the PortObject2 hash table
-    * keyed by ports.
-    */
-    stat =ghash_add(mhash, &ponew, ponew);
-    if ( stat != GHASH_OK )
-    {
-        /* This is possible since PLX hash on a different key */
-        if ( stat == GHASH_INTABLE )
-        {
-            pox = (PortObject2*)ghash_find(mhash, &ponew);
-            if ( pox )
-            {
-                PortObject2AppendPortObject2(pox, ponew);
-                PortObject2Free(ponew);
-                ponew = pox;
-            }
-            else
-            {
-                FatalError("mhash add/find error n=%d\n", pol_cnt);
-            }
-        }
-        else
-        {
-            FatalError("Could not add ponew to hash table- error\n");
-        }
-    }
-
 
-    /*
-    * Create a plx node and add it to plx table
-    * as the key with the merged port object as the data
-    */
-    plx_tmp = plx_new(pol, pol_cnt);
-    if (!plx_tmp)
-    {
-        FatalError("plx_new: memory alloc error\n");
+        PortObjectNormalize((PortObject*)ponew);
     }
-    sflist_add_head(plx_list, (void*)plx_tmp);
 
-    /*
-     * Add the plx node to the PLX hash table
-     */
-    stat = ghash_add(mhashx, &plx_tmp, ponew);
-    if ( stat != GHASH_OK )
+    // Add the Merged PortObject2 to the PortObject2 hash table keyed by ports.
+    int stat = mhash->insert(&ponew, ponew);
+    // This is possible since PLX hash on a different key
+    if ( stat == GHASH_INTABLE )
     {
-        if ( stat == GHASH_INTABLE )
-        {
-            FatalError("Could not add merged plx to PLX HASH table-INTABLE\n");
-        }
-        else
-        {
-            FatalError("Could not add merged plx to PLX HASH table\n");
-        }
+        PortObject2* pox = (PortObject2*)mhash->find(&ponew);
+        assert( pox );
+        PortObject2AppendPortObject2(pox, ponew);
+        PortObject2Free(ponew);
+        ponew = pox;
     }
 
+    // Create a plx node and add it to plx table as the key with the
+    // merged port object as the data
+    plx_t* plx_tmp = plx_new(pol, pol_cnt);
+    sflist_add_head(plx_list, (void*)plx_tmp);
 
-    /*
-    *  Validate hash table entry
-    */
-    if ( ghash_find(mhashx, &plx_tmp) != ponew )
-    {
-        FatalError("Find after add failed on PLX HASH table key\n");
-    }
+    // Add the plx node to the PLX hash table
+    stat = mhashx->insert(&plx_tmp, ponew);
+    if ( stat == GHASH_INTABLE )
+        FatalError("Could not add merged plx to PLX HASH table-INTABLE\n");
 
     return ponew;
 }
@@ -410,17 +345,13 @@ static PortObject2* PortTableCompileMergePortObjectList2(
     * Merge Large PortObjects
     */
     if ( nlarge )
-    {
-        ponew =  _merge_N_pol(mhash, mhashx, plx_list, polarge, nlarge, &plx_large);
-    }
+        ponew = _merge_N_pol(mhash, mhashx, plx_list, polarge, nlarge, &plx_large);
 
     /*
     * Merge Small PortObjects
     */
     if ( nsmall )
-    {
         posnew =  _merge_N_pol(mhash, mhashx, plx_list, posmall, nsmall, &plx_small);
-    }
     /*
     * Merge Large and Small (rule groups) PortObject2's together
     * append small port object rule sets to the large port objects,
@@ -522,35 +453,27 @@ static inline void delete_port_lists(SF_LIST** parray)
 }
 
 
-static int PortTableCompileMergePortObjects(PortTable* p)
+static void PortTableCompileMergePortObjects(PortTable* p)
 {
     std::unique_ptr<PortObject*[]> upA(new PortObject*[SFPO_MAX_LPORTS]);
     PortObject** pol = upA.get();
 
     // Create a Merged Port Object Table - hash by ports, no user keys, don't free data
-    GHash* mhash = ghash_new(PO_HASH_TBL_ROWS, sizeof(PortObject*), 0, nullptr);
-
-    /* Setup hashing function and key comparison function */
-    hashfcn_set_keyops(mhash->hashfcn, PortObject_hash, PortObject_keycmp);
+    GHash* mhash = new GHash(PO_HASH_TBL_ROWS, sizeof(PortObject*), 0, nullptr);
 
+    mhash->set_key_opcodes(PortObject_hash, PortObject_keycmp);
     p->pt_mpo_hash = mhash;
 
     // Create a Merged Port Object Table - hash by pointers, no user keys, don't free data
-    GHash* mhashx = ghash_new(PO_HASH_TBL_ROWS, sizeof(plx_t*), 0, nullptr);
-
-    /* Setup hashing function and key comparison function */
-    hashfcn_set_keyops(mhashx->hashfcn, plx_hash, plx_keycmp);
+    GHash* mhashx = new GHash(PO_HASH_TBL_ROWS, sizeof(plx_t*), 0, nullptr);
+    mhashx->set_key_opcodes(plx_hash, plx_keycmp);
 
     p->pt_mpxo_hash = mhashx;
-
     SF_LIST* plx_list = sflist_new();
-
     SF_LIST** optimized_pl = create_port_lists(p);
 
-    /*
-     *  For each port, merge rules from all port objects that touch the port
-     *  into an optimal object, that may be shared with other ports.
-     */
+    // For each port, merge rules from all port objects that touch the port
+    // into an optimal object, that may be shared with other ports.
     int id = PO_INIT_ID;
 
     for ( int i = 0; i < SFPO_MAX_PORTS; i++ )
@@ -561,35 +484,23 @@ static int PortTableCompileMergePortObjects(PortTable* p)
         SF_LNODE* lpos;
 
         for (po = (PortObject*)sflist_first(optimized_pl[i], &lpos);
-            po;
-            po = (PortObject*)sflist_next(&lpos) )
+             po;
+             po = (PortObject*)sflist_next(&lpos) )
         {
             if (pol_cnt < SFPO_MAX_LPORTS )
-            {
                 pol[ pol_cnt++ ] = po;
-            }
         }
         p->pt_port_object[i] = nullptr;
 
         if ( !pol_cnt )
-        {
-            //port not contained in any PortObject
-            continue;
-        }
+            continue;            //port not contained in any PortObject
 
         /* merge the rules into an optimal port object */
         p->pt_port_object[i] =
             PortTableCompileMergePortObjectList2(
                 mhash, mhashx, plx_list, pol, pol_cnt, p->pt_lrc);
-
-        if ( !p->pt_port_object[i] )
-        {
-            FatalError(" Could not merge PorObjectList on port %d\n", i);
-        }
-
-        /* give the new compiled port object an id of its own */
-        p->pt_port_object[i]->id = id++;
-
+        assert( p->pt_port_object[i] );
+        p->pt_port_object[i]->id = id++;  // set the port object id
     }
 
     delete_port_lists(optimized_pl);
@@ -601,62 +512,45 @@ static int PortTableCompileMergePortObjects(PortTable* p)
      */
 
     /* 1st- Setup bitmasks for collecting ports */
-    for (GHashNode* node=ghash_findfirst(mhashx);
-        node;
-        node=ghash_findnext(mhashx) )
+    for (GHashNode* node = mhashx->find_first();
+         node;
+         node = mhashx->find_next())
     {
         PortObject2* poa = (PortObject2*)node->data;
 
         if ( !poa )
             continue;
 
-        if (!poa->port_list)
-        {
+        if ( !poa->port_list )
             poa->port_list = new PortBitSet;
-
-            if ( !poa->port_list)
-                FatalError("Memory error in PortTableCompile\n");
-        }
     }
 
     /* Count how many ports each final port-object is used on */
     for ( int i = 0; i < SFPO_MAX_PORTS; i++ )
     {
-        PortObject2* poa;
-        poa = p->pt_port_object[i];
-        if (poa)
+        PortObject2* poa = p->pt_port_object[i];
+        if ( poa )
         {
             poa->port_cnt++;
 
             if ( poa->port_list )
                 poa->port_list->set(i);
-
             else
                 FatalError("NULL po->port_list in po on port %d\n", i);
         }
     }
 
     /* Process Port map and print final port-object usage stats */
-    for (GHashNode* node=ghash_findfirst(mhashx);
-        node;
-        node=ghash_findnext(mhashx) )
+    for (GHashNode* node = mhashx->find_first();
+         node;
+         node = mhashx->find_next())
     {
         PortObject2* po = (PortObject2*)node->data;
-
-        if ( !po )
-            FatalError("MergePortOBject-NormalizePorts -NULL po\n");
-
-        if ( !po->port_cnt ) /* port object is not used ignore it */
-            continue;
-
-        if ( !po->port_list )
-        {
-            //FatalError("MergePortOBject-NormalizePorts -NULL po->port_list\n");
+        assert( po );
+        if ( !po->port_cnt || !po->port_list ) /* port object is not used ignore it */
             continue;
-        }
 
         PortBitSet parray;
-
         /* Convert the port_list bits to a char array */
         for ( int i = 0; i < SFPO_MAX_PORTS; i++ )
             parray[ i ] = po->port_list->test(i);
@@ -670,22 +564,11 @@ static int PortTableCompileMergePortObjects(PortTable* p)
 
         /* Build a PortObjectItem list from the char array */
         SF_LIST* plist = PortObjectItemListFromBits(parray, SFPO_MAX_PORTS);
-
-        if ( !plist )
-        {
-            FatalError("MergePortObjects: No PortObjectItems in portobject\n");
-        }
-
-        /* free the original list */
-        sflist_free_all(po->item_list, snort_free);
-
-        /* set the new list - this is a list of port items for this port object */
-        po->item_list = plist;
-
+        sflist_free_all(po->item_list, snort_free);        // free the original list
+        po->item_list = plist;      // set the new port object list of port items
     }
 
     sflist_free_all(plx_list, plx_free);
-    return 0;
 }
 
 #ifdef DEBUG
@@ -704,7 +587,7 @@ static int _po2_include_po_rules(PortObject2* po2, PortObject* po)
         pid = (int*)sflist_next(&rpos) )
     {
         /* find it in po2 */
-        int* id = (int*)ghash_find(po2->rule_hash, pid);
+        int* id = (int*)po2->rule_hash->find(pid);
 
         /* make sure it's in po2 */
         if ( !id )
@@ -722,9 +605,9 @@ static bool PortTableConsistencyCheck(PortTable* p)
     char* parray = upA.get();
     memset(parray, 0, SFPO_MAX_PORTS);
 
-    for ( GHashNode* node=ghash_findfirst(p->pt_mpo_hash);
-        node;
-        node=ghash_findnext(p->pt_mpo_hash) )
+    for (GHashNode* node = p->pt_mpo_hash->find_first();
+         node;
+         node = p->pt_mpo_hash->find_next())
     {
         PortObject2* po = (PortObject2*)node->data;
 
@@ -741,9 +624,8 @@ static bool PortTableConsistencyCheck(PortTable* p)
             if ( PortObjectHasPort( (PortObject*)po, i) )
             {
                 if ( parray[i] )
-                {
                     return false;
-                }
+
                 parray[i] = 1;
             }
         }
@@ -812,13 +694,6 @@ PortTable* PortTableNew()
 {
     PortTable* p = (PortTable*)snort_calloc(sizeof(PortTable));
     p->pt_polist = sflist_new();
-
-    if (!p->pt_polist )
-    {
-        snort_free(p);
-        return nullptr;
-    }
-
     p->pt_lrc = PTBL_LRC_DEFAULT; /* 10 rules, user should really control these */
     p->pt_optimize = 1; /* if disabled, only one merged rule group is used */
 
@@ -834,22 +709,22 @@ void PortTableFree(PortTable* p)
     {
         sflist_free_all(p->pt_polist, PortObjectFree);
     }
+
     if (p->pt_mpo_hash)
     {
 
-        for ( GHashNode* node = ghash_findfirst(p->pt_mpo_hash);
-            node;
-            node = ghash_findnext(p->pt_mpo_hash) )
+        for (GHashNode* node = p->pt_mpo_hash->find_first();
+             node;
+             node = p->pt_mpo_hash->find_next())
         {
             PortObject2* po = (PortObject2*)node->data;
             PortObject2Free(po);
         }
-        ghash_delete(p->pt_mpo_hash);
+        delete p->pt_mpo_hash;
     }
+
     if (p->pt_mpxo_hash)
-    {
-        ghash_delete(p->pt_mpxo_hash);
-    }
+        delete p->pt_mpxo_hash;
 
     snort_free(p);
 }
@@ -857,7 +732,7 @@ void PortTableFree(PortTable* p)
 // FIXIT-P we should be able to free pt_mpo_hash early too
 void PortTableFinalize(PortTable* p)
 {
-    ghash_delete(p->pt_mpxo_hash);
+    delete p->pt_mpxo_hash;
     p->pt_mpxo_hash = nullptr;
 }
 
@@ -873,9 +748,7 @@ PortObject* PortTableFindInputPortObjectPorts(PortTable* pt, PortObject* pox)
         po = (PortObject*)sflist_next(&lpos) )
     {
         if ( PortObjectEqual(po, pox) )
-        {
             return po;
-        }
     }
     return nullptr;
 }
@@ -912,17 +785,11 @@ int PortTableAddObject(PortTable* p, PortObject* po)
 */
 int PortTableCompile(PortTable* p)
 {
-    /*
-    *  If not using an optimized Table use the rule_index_map in parser.c
-    */
+    // If not using an optimized Table use the rule_index_map in parser.c
     if ( !p->pt_optimize )
         return 0;
 
-    if ( PortTableCompileMergePortObjects(p) )
-    {
-        FatalError("Could not create PortArryayLists\n");
-    }
-
+    PortTableCompileMergePortObjects(p);
 
 #ifdef DEBUG
     assert(PortTableConsistencyCheck(p));
@@ -947,11 +814,11 @@ void PortTablePrintInputEx(PortTable* p, rim_print_f print_index_map)
 int PortTablePrintCompiledEx(PortTable* p, rim_print_f print_index_map)
 {
     LogMessage(" *** PortTableCompiled  [ %d compiled port groups ] \n\n",
-        p->pt_mpo_hash->count);
+        p->pt_mpo_hash->get_count());
 
-    for ( GHashNode* node = ghash_findfirst(p->pt_mpo_hash);
-        node!= nullptr;
-        node = ghash_findnext(p->pt_mpo_hash) )
+    for (GHashNode* node = p->pt_mpo_hash->find_first();
+         node != nullptr;
+         node = p->pt_mpo_hash->find_next())
     {
         PortObject2* po = (PortObject2*)node->data;
         PortObject2PrintEx(po, print_index_map);
@@ -999,11 +866,11 @@ void PortTablePrintPortGroups(PortTable* p)
 {
     /* normalized user PortObjects and rule ids */
     LogMessage(">>>PortTable - Compiled Port Groups\n");
-    LogMessage("   [ %d port groups ] \n\n", p->pt_mpo_hash->count);
+    LogMessage("   [ %d port groups ] \n\n", p->pt_mpo_hash->get_count());
 
-    for ( GHashNode* ponode = ghash_findfirst(p->pt_mpo_hash);
-        ponode!= nullptr;
-        ponode = ghash_findnext(p->pt_mpo_hash) )
+    for (GHashNode* ponode = p->pt_mpo_hash->find_first();
+         ponode != nullptr;
+         ponode = p->pt_mpo_hash->find_next())
     {
         PortObject2* po = (PortObject2*)ponode->data;
         PortObject2Print(po);
index 691cd12ab4776dc3fd4489ee60686b19ab28e2fd..11462c7f1ab9c74bc1975544bd87be4b71436797 100644 (file)
@@ -125,9 +125,6 @@ SF_LIST* PortObjectItemListFromBits(const PortBitSet& parray, int n)
     SF_LIST* plist = sflist_new();
     int nports = parray.count();
 
-    if ( !plist )
-        return nullptr;
-
     for (int i = 0; i < n && nports > 0; i++)
     {
         if ( parray[i] == 0 )
@@ -139,7 +136,7 @@ SF_LIST* PortObjectItemListFromBits(const PortBitSet& parray, int n)
         lport = hport = i;
         nports--;
 
-        for (i++; i<n; i++)
+        for (i++; i < n; i++)
         {
             if ( parray[i] )
             {
@@ -151,15 +148,8 @@ SF_LIST* PortObjectItemListFromBits(const PortBitSet& parray, int n)
         }
 
         PortObjectItem* poi = PortObjectItemNew();
-
-        if ( !poi )
-        {
-            sflist_free_all(plist, snort_free);
-            return nullptr;
-        }
-
-        poi->lport =(unsigned short)lport;
-        poi->hport =(unsigned short)hport;
+        poi->lport = (unsigned short)lport;
+        poi->hport = (unsigned short)hport;
         sflist_add_tail(plist, poi);
      }
 
index 213ffb417a579df256e1347c91689e77857ac533..ea5257ecb69cc6312b3b12f46ea5a3489e60e66e 100644 (file)
@@ -36,28 +36,15 @@ using namespace snort;
 */
 PortVarTable* PortVarTableCreate()
 {
-    PortObject* po;
-    GHash* h;
-
     /*
      * This is used during parsing of config,
      * so 1000 entries is ok, worst that happens is somewhat slower
      * config/rule processing.
      */
-    h = ghash_new(1000,0,0,PortObjectFree);
-    if ( !h )
-        return nullptr;
-
-    /* Create default port objects */
-    po = PortObjectNew();
-    if ( !po )
-        return nullptr;
-
-    /* Default has an ANY port */
-    PortObjectAddPortAny(po);
-
-    /* Add ANY to the table */
-    PortVarTableAdd(h, po);
+    GHash* h = new GHash(1000, 0, 0, PortObjectFree);
+    PortObject* po = PortObjectNew();       // Create default port objects
+    PortObjectAddPortAny(po);   // Default has an ANY port
+    PortVarTableAdd(h, po);     // Add ANY to the table
 
     return h;
 }
@@ -69,9 +56,8 @@ PortVarTable* PortVarTableCreate()
 int PortVarTableFree(PortVarTable* pvt)
 {
     if ( pvt )
-    {
-        ghash_delete(pvt);
-    }
+        delete pvt;
+
     return 0;
 }
 
@@ -85,12 +71,13 @@ int PortVarTableFree(PortVarTable* pvt)
 */
 int PortVarTableAdd(PortVarTable* h, PortObject* po)
 {
-    int stat;
-    stat = ghash_add(h,po->name,po);
+    int stat = h->insert(po->name, po);
     if ( stat == GHASH_INTABLE )
         return 1;
+
     if ( stat == GHASH_OK )
         return 0;
+
     return -1;
 }
 
@@ -99,6 +86,6 @@ PortObject* PortVarTableFind(PortVarTable* h, const char* name)
     if (!h || !name)
         return nullptr;
 
-    return (PortObject*)ghash_find(h,name);
+    return (PortObject*)h->find(name);
 }
 
index eaddb23f3e864cb206a2e0a9e345f9f62a89d4b4..78737834eed778fb0fa1f8da13b24266340017c1 100644 (file)
@@ -40,9 +40,6 @@ PortProto::PortProto()
     any = PortObjectNew();
     nfp = PortObjectNew();
 
-    if ( !src or !dst or !any or !nfp )
-        ParseAbort("can't allocate port structs");
-
    // someday these could be read from snort.conf, something like...
    // 'config portlist: large-rule-count <val>'
     src->pt_lrc = DEFAULT_LARGE_RULE_GROUP;
@@ -54,26 +51,17 @@ PortProto::PortProto()
 
 PortProto::~PortProto()
 {
-    if (src)
-        PortTableFree(src);
-
-    if (dst)
-        PortTableFree(dst);
-
-    if (any)
-        PortObjectFree(any);
-
-    if (nfp)
-        PortObjectFree(nfp);
+    PortTableFree(src);
+    PortTableFree(dst);
+    PortObjectFree(any);
+    PortObjectFree(nfp);
 }
 
 RulePortTables* PortTablesNew()
 {
     RulePortTables* rpt = new RulePortTables;
 
-    if ( !(rpt->svc_any = PortObjectNew()) )
-        ParseAbort("udp any-any PortObjectNew() failed");
-
+    rpt->svc_any = PortObjectNew();
     PortObjectAddPortAny(rpt->svc_any);
 
     return rpt;
index 6b4d3d3a13b1c8b8b61e5a55bce4da34bef90a5b..715e37c90433c174cd2edfb0f9b431adfe8c4616 100644 (file)
@@ -201,7 +201,7 @@ static std::vector<View> build_entries()
 
     std::vector<View> entries;
 
-    for ( auto* h = ghash_findfirst(otn_map); h; h = ghash_findnext(otn_map) )
+    for ( auto* h = otn_map->find_first(); h; h = otn_map->find_next() )
     {
         auto* otn = static_cast<OptTreeNode*>(h->data);
         assert(otn);
@@ -316,7 +316,7 @@ void reset_rule_profiler_stats()
     assert(SnortConfig::get_conf());
     auto* otn_map = SnortConfig::get_conf()->otn_map;
 
-    for ( auto* h = ghash_findfirst(otn_map); h; h = ghash_findnext(otn_map) )
+    for ( auto* h = otn_map->find_first(); h; h = otn_map->find_next() )
     {
         auto* otn = static_cast<OptTreeNode*>(h->data);
         assert(otn);
index 7c33c7bf2cf30fde88c6764934af040e040850a5..1620b6de17924f812d524ce4b70ee18c276d2433 100644 (file)
@@ -25,6 +25,8 @@
 
 #include "sip_config.h"
 
+#include <cassert>
+
 #include "log/messages.h"
 #include "main/snort_debug.h"
 #include "utils/util.h"
@@ -86,11 +88,8 @@ void SIP_SetDefaultMethods(SIP_PROTO_CONF* config)
     config->methodsConfig = SIP_METHOD_DEFAULT;
     for (i = 0; i < 6; i++)
     {
-        if (SIP_AddMethodToList(StandardMethods[i].name,
-            StandardMethods[i].methodFlag, &config->methods) == nullptr)
-        {
-            FatalError("Failed to add SIP default method: %s.\n", StandardMethods[i].name);
-        }
+        SIP_AddMethodToList(StandardMethods[i].name,
+            StandardMethods[i].methodFlag, &config->methods);
     }
 }
 
@@ -124,11 +123,7 @@ void SIP_ParseMethods(const char* cur_tokenp, uint32_t* methodsConfig, SIPMethod
     if (METHOD_NOT_FOUND != i_method )
     {
         *methodsConfig |= 1 << (StandardMethods[i_method].methodFlag - 1);
-        if (SIP_AddMethodToList(cur_tokenp,
-            StandardMethods[i_method].methodFlag, pmethods) == nullptr)
-        {
-            ParseError("Failed to add SIP method: %s.", cur_tokenp);
-        }
+        SIP_AddMethodToList(cur_tokenp, StandardMethods[i_method].methodFlag, pmethods);
     }
     else
     {
@@ -142,8 +137,7 @@ void SIP_ParseMethods(const char* cur_tokenp, uint32_t* methodsConfig, SIPMethod
 static SIPMethodNode* SIP_AddMethodToList(
     const char* methodName, SIPMethodsFlag methodConf, SIPMethodlist* p_methodList)
 {
-    if ( !methodName )
-        return nullptr;
+    assert (methodName );
 
     int methodLen = strlen(methodName);
     SIPMethodNode* method = *p_methodList;
index 397eb9d9a2d87e2a2aa7862aea845abe381d2b20..b8f8314ff87247ba37f7a9b4ab6663905807bd6d 100644 (file)
@@ -57,8 +57,7 @@ static void UdpSessionCleanup(Flow* lwssn)
         udpStats.released++;
 }
 
-static int ProcessUdp(
-    Flow* lwssn, Packet* p, StreamUdpConfig*, XHashNode*)
+static int ProcessUdp(Flow* lwssn, Packet* p, StreamUdpConfig*)
 {
     assert(lwssn->pkt_type == PktType::UDP);
 
@@ -191,7 +190,7 @@ int UdpSession::process(Packet* p)
         UdpHAManager::process_deletion(*flow);
     }
 
-    ProcessUdp(flow, p, pc, nullptr);
+    ProcessUdp(flow, p, pc);
     flow->markup_packet_flags(p);
 
     flow->set_expire(p, flow->default_session_timeout);
index b786c509f16492be3fa7df7443f3eeb67c313a8b..0627955ae34fbe404ff9c41b856b2ed633f5af45 100644 (file)
@@ -22,7 +22,7 @@
 *
 *   Simple list, queue, and dictionary implementations
 *   ( most of these implementations are list based - not performance monsters,
-*     and they all use snort_alloc via s_alloc/s_free )
+*     and they all use snort_alloc/snort_free )
 *
 *   11/05/2005 - man - Added sflist_firstx() and sflist_nextx() with user
 *   provided SF_NODE inputs for tracking the list position.  This allows
 
 #include "util.h"
 
-// private alloc
-static void* s_alloc(size_t n)
-{
-    return snort_calloc(n);
-}
-
-/*
-*  private free
-*/
-static void s_free(void* p)
-{
-    if ( p )
-        snort_free(p);
-}
-
 namespace snort
 {
 SF_LIST* sflist_new()
 {
-    SF_LIST* s;
-    s = (SF_LIST*)s_alloc(sizeof(SF_LIST) );
+    SF_LIST* s = (SF_LIST*)snort_calloc(sizeof(SF_LIST));
     sflist_init(s);
     return s;
 }
 
 void sflist_init(SF_LIST* s)
 {
-    s->count=0;
+    s->count = 0;
     s->head = s->tail = nullptr;
 }
 
 void sflist_add_before(SF_LIST* s, SF_LNODE* lnode, NODE_DATA ndata)
 {
-    SF_LNODE* q;
-
     if ( lnode )
     {
         /* Add to head of list */
@@ -79,12 +61,12 @@ void sflist_add_before(SF_LIST* s, SF_LNODE* lnode, NODE_DATA ndata)
             sflist_add_head (s, ndata);
         else
         {
-            q = (SF_LNODE*)s_alloc (sizeof (SF_LNODE) );
+            SF_LNODE* q = (SF_LNODE*)snort_calloc(sizeof (SF_LNODE));
             q->ndata = (NODE_DATA)ndata;
             q->next = lnode;
             q->prev = lnode->prev;
             lnode->prev->next = q;
-            lnode->prev       = q;
+            lnode->prev = q;
             s->count++;
         }
     }
@@ -95,14 +77,14 @@ void sflist_add_head(SF_LIST* s, NODE_DATA ndata)
     SF_LNODE* q;
     if (!s->head)
     {
-        q = s->tail = s->head = (SF_LNODE*)s_alloc (sizeof (SF_LNODE));
+        q = s->tail = s->head = (SF_LNODE*)snort_calloc(sizeof (SF_LNODE));
         q->ndata = (NODE_DATA)ndata;
         q->next = nullptr;
         q->prev = nullptr;
     }
     else
     {
-        q = (SF_LNODE*)s_alloc (sizeof (SF_LNODE));
+        q = (SF_LNODE*)snort_calloc(sizeof (SF_LNODE));
         q->ndata = ndata;
         q->next = s->head;
         q->prev = nullptr;
@@ -117,14 +99,14 @@ void sflist_add_tail(SF_LIST* s, NODE_DATA ndata)
     SF_LNODE* q;
     if (!s->head)
     {
-        q = s->tail = s->head = (SF_LNODE*)s_alloc (sizeof (SF_LNODE));
+        q = s->tail = s->head = (SF_LNODE*)snort_calloc(sizeof (SF_LNODE));
         q->ndata = (NODE_DATA)ndata;
         q->next = nullptr;
         q->prev = nullptr;
     }
     else
     {
-        q = (SF_LNODE*)s_alloc (sizeof (SF_LNODE));
+        q = (SF_LNODE*)snort_calloc(sizeof (SF_LNODE));
         q->ndata = ndata;
         q->next = nullptr;
         q->prev = s->tail;
@@ -176,7 +158,7 @@ NODE_DATA sflist_remove_head(SF_LIST* s)
         else
             s->head->prev = nullptr;
 
-        s_free(q);
+        snort_free(q);
     }
     return (NODE_DATA)ndata;
 }
@@ -198,7 +180,7 @@ NODE_DATA sflist_remove_tail(SF_LIST* s)
         else
             s->tail->next = nullptr;
 
-        s_free (q);
+        snort_free(q);
     }
     return (NODE_DATA)ndata;
 }
@@ -217,7 +199,7 @@ void sflist_remove_node(SF_LIST* s, SF_LNODE* n)
         else
             s->head->prev = nullptr;
 
-        s_free(n);
+        snort_free(n);
         return;
     }
     else if ( n == s->tail )
@@ -230,7 +212,7 @@ void sflist_remove_node(SF_LIST* s, SF_LNODE* n)
         else
             s->tail->next = nullptr;
 
-        s_free(n);
+        snort_free(n);
         return;
     }
 
@@ -244,7 +226,7 @@ void sflist_remove_node(SF_LIST* s, SF_LNODE* n)
             n->next->prev = n->prev;
             n->prev->next = n->next;
             s->count--;
-            s_free(n);
+            snort_free(n);
             return;
         }
     }
@@ -263,7 +245,7 @@ void sflist_free(SF_LIST* s)
     {
         sflist_remove_head(s);
     }
-    s_free(s);
+    snort_free(s);
 }
 
 void sflist_free_all(SF_LIST* s, void (* nfree)(void*) )
@@ -278,7 +260,7 @@ void sflist_free_all(SF_LIST* s, void (* nfree)(void*) )
         if ( p && nfree )
             nfree(p);
     }
-    s_free(s);
+    snort_free(s);
 }
 
 void sflist_static_free_all(SF_LIST* s, void (* nfree)(void*) )
@@ -308,7 +290,7 @@ SF_QUEUE* sfqueue_new()
 
 void sfqueue_add(SF_QUEUE* s, NODE_DATA ndata)
 {
-    sflist_add_tail (s, ndata);
+    sflist_add_tail(s, ndata);
 }
 
 
@@ -328,5 +310,3 @@ void sfqueue_free_all(SF_QUEUE* s,void (* nfree)(void*) )
 {
     sflist_free_all(s, nfree);
 }
-
-