From: Davis McPherson (davmcphe) Date: Thu, 13 Feb 2020 14:26:17 +0000 (+0000) Subject: Merge pull request #1965 in SNORT/snort3 from ~DAVMCPHE/snort3:reload_fatal_attractio... X-Git-Tag: 3.0.0-268~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7f9aca2b53c4741a0d85abfd351ba332dc52e8ab;p=thirdparty%2Fsnort3.git Merge pull request #1965 in SNORT/snort3 from ~DAVMCPHE/snort3:reload_fatal_attractions to master Squashed commit of the following: commit 24b57441e129bcfdd47bfaf62d55957a0ccc6c38 Author: davis mcpherson 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 --- diff --git a/src/detection/detection_options.cc b/src/detection/detection_options.cc index af2cbb6fd..a64f0944e 100644 --- a/src/detection/detection_options.cc +++ b/src/detection/detection_options.cc @@ -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; inum_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); diff --git a/src/detection/detection_options.h b/src/detection/detection_options.h index 14a0c66ef..6f6fdf4a9 100644 --- a/src/detection/detection_options.h +++ b/src/detection/detection_options.h @@ -43,7 +43,7 @@ namespace snort { struct Packet; struct SnortConfig; -struct XHash; +class XHash; } struct RuleLatencyState; diff --git a/src/detection/fp_create.cc b/src/detection/fp_create.cc index d9fc9b6e1..9f9fde9f0 100644 --- a/src/detection/fp_create.cc +++ b/src/detection/fp_create.cc @@ -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"); diff --git a/src/detection/fp_detect.cc b/src/detection/fp_detect.cc index 30cf8cba5..05cd9bf62 100644 --- a/src/detection/fp_detect.cc +++ b/src/detection/fp_detect.cc @@ -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 queue; diff --git a/src/detection/fp_detect.h b/src/detection/fp_detect.h index e567465a3..4efde0dc3 100644 --- a/src/detection/fp_detect.h +++ b/src/detection/fp_detect.h @@ -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; }; /* diff --git a/src/detection/pcrm.cc b/src/detection/pcrm.cc index 37998b231..4d2088b68 100644 --- a/src/detection/pcrm.cc +++ b/src/detection/pcrm.cc @@ -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)); } /* diff --git a/src/detection/rules.h b/src/detection/rules.h index 7b97b7684..c6659567a 100644 --- a/src/detection/rules.h +++ b/src/detection/rules.h @@ -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 */ }; diff --git a/src/detection/service_map.cc b/src/detection/service_map.cc index ce2eec53d..65eedc998 100644 --- a/src/detection/service_map.cc +++ b/src/detection/service_map.cc @@ -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; } //------------------------------------------------------------------------- diff --git a/src/detection/service_map.h b/src/detection/service_map.h index 92f9d6a4f..e1f1da18f 100644 --- a/src/detection/service_map.h +++ b/src/detection/service_map.h @@ -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 PortGroupVector; diff --git a/src/detection/signature.cc b/src/detection/signature.cc index 90b40b473..bed991f8a 100644 --- a/src/detection/signature.cc +++ b/src/detection/signature.cc @@ -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; } diff --git a/src/detection/signature.h b/src/detection/signature.h index 1949ab903..d27f93ad4 100644 --- a/src/detection/signature.h +++ b/src/detection/signature.h @@ -31,7 +31,7 @@ namespace snort { -struct GHash; +class GHash; struct SnortConfig; } diff --git a/src/detection/tag.cc b/src/detection/tag.cc index 1dcbd4cdc..afa2c3b0d 100644 --- a/src/detection/tag.cc +++ b/src/detection/tag.cc @@ -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"); } diff --git a/src/detection/treenodes.h b/src/detection/treenodes.h index 6affa8f0d..9e7f19580 100644 --- a/src/detection/treenodes.h +++ b/src/detection/treenodes.h @@ -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; diff --git a/src/file_api/file_cache.cc b/src/file_api/file_cache.cc index b8cb4c4ef..48019fde5 100644 --- a/src/file_api/file_cache.cc +++ b/src/file_api/file_cache.cc @@ -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 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 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; } diff --git a/src/file_api/file_cache.h b/src/file_api/file_cache.h index 539400098..1ee25d89d 100644 --- a/src/file_api/file_cache.h +++ b/src/file_api/file_cache.h @@ -30,8 +30,7 @@ namespace snort { -struct XHash; -struct XHashNode; +class XHash; } class FileCache diff --git a/src/file_api/file_identifier.cc b/src/file_api/file_identifier.cc index 2d7861662..2e7143ff5 100644 --- a/src/file_api/file_identifier.cc +++ b/src/file_api/file_identifier.cc @@ -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; diff --git a/src/filters/detection_filter.cc b/src/filters/detection_filter.cc index ae926b006..5d30a7818 100644 --- a/src/filters/detection_filter.cc +++ b/src/filters/detection_filter.cc @@ -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; } diff --git a/src/filters/rate_filter.cc b/src/filters/rate_filter.cc index bf9d9c7a9..3c8c392c9 100644 --- a/src/filters/rate_filter.cc +++ b/src/filters/rate_filter.cc @@ -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); diff --git a/src/filters/sfrf.cc b/src/filters/sfrf.cc index ff6e8e15e..a985f6cae 100644 --- a/src/filters/sfrf.cc +++ b/src/filters/sfrf.cc @@ -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. diff --git a/src/filters/sfrf.h b/src/filters/sfrf.h index f29d486b1..e58aa33b0 100644 --- a/src/filters/sfrf.h +++ b/src/filters/sfrf.h @@ -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; diff --git a/src/filters/sfthd.cc b/src/filters/sfthd.cc index fbdbe9524..b83ba0fa5 100644 --- a/src/filters/sfthd.cc +++ b/src/filters/sfthd.cc @@ -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; diff --git a/src/filters/sfthd.h b/src/filters/sfthd.h index 938109ce1..4b240acc1 100644 --- a/src/filters/sfthd.h +++ b/src/filters/sfthd.h @@ -30,8 +30,8 @@ namespace snort { -struct GHash; -struct XHash; +class GHash; +class XHash; struct SnortConfig; } diff --git a/src/filters/sfthd_test.cc b/src/filters/sfthd_test.cc index 15c426d72..5058d4a08 100644 --- a/src/filters/sfthd_test.cc +++ b/src/filters/sfthd_test.cc @@ -808,7 +808,8 @@ static void Term() p->rule = nullptr; } } - xhash_delete(dThd); + + delete dThd; } static int SetupCheck(int i) diff --git a/src/flow/expect_cache.cc b/src/flow/expect_cache.cc index 528541ddb..69873cc46 100644 --- a/src/flow/expect_cache.cc +++ b/src/flow/expect_cache.cc @@ -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) diff --git a/src/flow/flow_cache.cc b/src/flow/flow_cache.cc index 32d3317bf..b7ef59dc9 100644 --- a/src/flow/flow_cache.cc +++ b/src/flow/flow_cache.cc @@ -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; diff --git a/src/flow/flow_key.cc b/src/flow/flow_key.cc index 1438d2d85..72575eb1d 100644 --- a/src/flow/flow_key.cc +++ b/src/flow/flow_key.cc @@ -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; } diff --git a/src/flow/flow_key.h b/src/flow/flow_key.h index ddc7d11cf..4d9fb4ad8 100644 --- a/src/flow/flow_key.h +++ b/src/flow/flow_key.h @@ -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( diff --git a/src/flow/ha.cc b/src/flow/ha.cc index f7abe0dfd..edf8aebdd 100644 --- a/src/flow/ha.cc +++ b/src/flow/ha.cc @@ -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) { diff --git a/src/flow/test/ha_test.cc b/src/flow/test/ha_test.cc index d64c110c1..63a354407 100644 --- a/src/flow/test/ha_test.cc +++ b/src/flow/test/ha_test.cc @@ -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; } diff --git a/src/hash/CMakeLists.txt b/src/hash/CMakeLists.txt index f21b36c5b..8cbdd87e2 100644 --- a/src/hash/CMakeLists.txt +++ b/src/hash/CMakeLists.txt @@ -1,6 +1,7 @@ set (HASH_INCLUDES hashes.h + hash_defs.h ghash.h xhash.h hashfcn.h diff --git a/src/hash/dev_notes.txt b/src/hash/dev_notes.txt index 3e8b3d4b9..7765b6c6b 100644 --- a/src/hash/dev_notes.txt +++ b/src/hash/dev_notes.txt @@ -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. diff --git a/src/hash/ghash.cc b/src/hash/ghash.cc index cf742fe61..80e264bb4 100644 --- a/src/hash/ghash.cc +++ b/src/hash/ghash.cc @@ -62,450 +62,219 @@ #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; inrows; 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(onode->key)); + if ( !userkey && onode->key ) + snort_free(const_cast(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(hnode->key),key,klen); + memcpy(const_cast(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(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); } + } diff --git a/src/hash/ghash.h b/src/hash/ghash.h index ec6079344..17b874e74 100644 --- a/src/hash/ghash.h +++ b/src/hash/ghash.h @@ -26,57 +26,63 @@ #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 index 000000000..f66f16495 --- /dev/null +++ b/src/hash/hash_defs.h @@ -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 diff --git a/src/hash/hashfcn.cc b/src/hash/hashfcn.cc index 44990dfea..12b73a495 100644 --- a/src/hash/hashfcn.cc +++ b/src/hash/hashfcn.cc @@ -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 + #include "main/snort_config.h" #include "utils/util.h" @@ -42,10 +43,18 @@ 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> 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 diff --git a/src/hash/test/ghash_test.cc b/src/hash/test/ghash_test.cc index fc1dd044f..c1175a9cc 100644 --- a/src/hash/test/ghash_test.cc +++ b/src/hash/test/ghash_test.cc @@ -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; iinsert(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) diff --git a/src/hash/test/xhash_test.cc b/src/hash/test/xhash_test.cc index f83edbd7e..a52a4d92d 100644 --- a/src/hash/test/xhash_test.cc +++ b/src/hash/test/xhash_test.cc @@ -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) diff --git a/src/hash/xhash.cc b/src/hash/xhash.cc index 98ea27ae3..bcca7c412 100644 --- a/src/hash/xhash.cc +++ b/src/hash/xhash.cc @@ -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. * @@ -95,377 +94,159 @@ #include #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> 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 diff --git a/src/hash/xhash.h b/src/hash/xhash.h index cf27b79fd..d9ea5f7df 100644 --- a/src/hash/xhash.h +++ b/src/hash/xhash.h @@ -28,144 +28,120 @@ #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 diff --git a/src/hash/zhash.cc b/src/hash/zhash.cc index 7c70cda7d..f2b87d3ac 100644 --- a/src/hash/zhash.cc +++ b/src/hash/zhash.cc @@ -25,38 +25,27 @@ #include "zhash.h" +#include #include -#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( - ::operator new(sizeof(ZHashNode) + keysize)); + auto node = static_cast( + ::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> 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); } diff --git a/src/hash/zhash.h b/src/hash/zhash.h index 334245b49..27584532b 100644 --- a/src/hash/zhash.h +++ b/src/hash/zhash.h @@ -22,8 +22,12 @@ #include -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 diff --git a/src/ips_options/ips_flowbits.cc b/src/ips_options/ips_flowbits.cc index f5dc826a6..4205b3264 100644 --- a/src/ips_options/ips_flowbits.cc +++ b/src/ips_options/ips_flowbits.cc @@ -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; } diff --git a/src/ips_options/ips_session.cc b/src/ips_options/ips_session.cc index 1ac487019..c86362ab4 100644 --- a/src/ips_options/ips_session.cc +++ b/src/ips_options/ips_session.cc @@ -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); diff --git a/src/loggers/alert_sf_socket.cc b/src/loggers/alert_sf_socket.cc index 075aa2732..ea4f8d2a2 100644 --- a/src/loggers/alert_sf_socket.cc +++ b/src/loggers/alert_sf_socket.cc @@ -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); diff --git a/src/main/policy.h b/src/main/policy.h index 242eb8da7..de51b437c 100644 --- a/src/main/policy.h +++ b/src/main/policy.h @@ -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 { diff --git a/src/main/snort_config.cc b/src/main/snort_config.cc index 0ff9981af..8666ca5d8 100644 --- a/src/main/snort_config.cc +++ b/src/main/snort_config.cc @@ -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); diff --git a/src/main/snort_config.h b/src/main/snort_config.h index c2d69ee9c..4c099518c 100644 --- a/src/main/snort_config.h +++ b/src/main/snort_config.h @@ -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]; diff --git a/src/managers/inspector_manager.cc b/src/managers/inspector_manager.cc index afad7ad20..2ebb73c18 100644 --- a/src/managers/inspector_manager.cc +++ b/src/managers/inspector_manager.cc @@ -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(); diff --git a/src/mime/file_mime_process.cc b/src/mime/file_mime_process.cc index 44889bdc0..7c962b619 100644 --- a/src/mime/file_mime_process.cc +++ b/src/mime/file_mime_process.cc @@ -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); } diff --git a/src/network_inspectors/appid/service_state.cc b/src/network_inspectors/appid/service_state.cc index b21617574..6c3ff2980 100644 --- a/src/network_inspectors/appid/service_state.cc +++ b/src/network_inspectors/appid/service_state.cc @@ -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 ) diff --git a/src/network_inspectors/appid/service_state.h b/src/network_inspectors/appid/service_state.h index bbc0a06ef..715263b65 100644 --- a/src/network_inspectors/appid/service_state.h +++ b/src/network_inspectors/appid/service_state.h @@ -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); }; diff --git a/src/network_inspectors/perf_monitor/flow_ip_tracker.cc b/src/network_inspectors/perf_monitor/flow_ip_tracker.cc index 9943c51ca..85c5eb02c 100644 --- a/src/network_inspectors/perf_monitor/flow_ip_tracker.cc +++ b/src/network_inspectors/perf_monitor/flow_ip_tracker.cc @@ -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; diff --git a/src/network_inspectors/perf_monitor/perf_module.cc b/src/network_inspectors/perf_monitor/perf_module.cc index 189df9867..4b215808c 100644 --- a/src/network_inspectors/perf_monitor/perf_module.cc +++ b/src/network_inspectors/perf_monitor/perf_module.cc @@ -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", diff --git a/src/network_inspectors/perf_monitor/perf_monitor.cc b/src/network_inspectors/perf_monitor/perf_monitor.cc index 4658859e6..9df381e3b 100644 --- a/src/network_inspectors/perf_monitor/perf_monitor.cc +++ b/src/network_inspectors/perf_monitor/perf_monitor.cc @@ -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; diff --git a/src/network_inspectors/port_scan/ps_detect.cc b/src/network_inspectors/port_scan/ps_detect.cc index d04dd71bb..4ee4800b3 100644 --- a/src/network_inspectors/port_scan/ps_detect.cc +++ b/src/network_inspectors/port_scan/ps_detect.cc @@ -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)); diff --git a/src/parser/parse_ports.cc b/src/parser/parse_ports.cc index f26aee626..8ed5686c0 100644 --- a/src/parser/parse_ports.cc +++ b/src/parser/parse_ports.cc @@ -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 or : */ @@ -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); diff --git a/src/parser/parse_rule.cc b/src/parser/parse_rule.cc index 684ba679b..4cba6699e 100644 --- a/src/parser/parse_rule.cc +++ b/src/parser/parse_rule.cc @@ -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; diff --git a/src/parser/parser.cc b/src/parser/parser.cc index a845117d7..fe5860b61 100644 --- a/src/parser/parser.cc +++ b/src/parser/parser.cc @@ -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; } diff --git a/src/parser/vars.cc b/src/parser/vars.cc index f58c734f9..5e7f67b6a 100644 --- a/src/parser/vars.cc +++ b/src/parser/vars.cc @@ -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 */ diff --git a/src/ports/port_item.cc b/src/ports/port_item.cc index 07e837b2c..5b87aaf1a 100644 --- a/src/ports/port_item.cc +++ b/src/ports/port_item.cc @@ -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; } diff --git a/src/ports/port_object.cc b/src/ports/port_object.cc index 71bab6aeb..5e6114e3d 100644 --- a/src/ports/port_object.cc +++ b/src/ports/port_object.cc @@ -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; irule_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 ) { diff --git a/src/ports/port_object2.cc b/src/ports/port_object2.cc index 72ce99a42..090dd7430 100644 --- a/src/ports/port_object2.cc +++ b/src/ports/port_object2.cc @@ -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; irule_hash->count; i++) + for (i = 0; i < po->rule_hash->get_count(); i++) { if ( print_index_map ) { diff --git a/src/ports/port_object2.h b/src/ports/port_object2.h index 0c7136acf..e95cccf22 100644 --- a/src/ports/port_object2.h +++ b/src/ports/port_object2.h @@ -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*); diff --git a/src/ports/port_table.cc b/src/ports/port_table.cc index 25db02f8d..71e30bf0e 100644 --- a/src/ports/port_table.cc +++ b/src/ports/port_table.cc @@ -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 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); diff --git a/src/ports/port_utils.cc b/src/ports/port_utils.cc index 691cd12ab..11462c7f1 100644 --- a/src/ports/port_utils.cc +++ b/src/ports/port_utils.cc @@ -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++; ilport =(unsigned short)lport; - poi->hport =(unsigned short)hport; + poi->lport = (unsigned short)lport; + poi->hport = (unsigned short)hport; sflist_add_tail(plist, poi); } diff --git a/src/ports/port_var_table.cc b/src/ports/port_var_table.cc index 213ffb417..ea5257ecb 100644 --- a/src/ports/port_var_table.cc +++ b/src/ports/port_var_table.cc @@ -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); } diff --git a/src/ports/rule_port_tables.cc b/src/ports/rule_port_tables.cc index eaddb23f3..78737834e 100644 --- a/src/ports/rule_port_tables.cc +++ b/src/ports/rule_port_tables.cc @@ -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 ' 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; diff --git a/src/profiler/rule_profiler.cc b/src/profiler/rule_profiler.cc index 6b4d3d3a1..715e37c90 100644 --- a/src/profiler/rule_profiler.cc +++ b/src/profiler/rule_profiler.cc @@ -201,7 +201,7 @@ static std::vector build_entries() std::vector 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(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(h->data); assert(otn); diff --git a/src/service_inspectors/sip/sip_config.cc b/src/service_inspectors/sip/sip_config.cc index 7c33c7bf2..1620b6de1 100644 --- a/src/service_inspectors/sip/sip_config.cc +++ b/src/service_inspectors/sip/sip_config.cc @@ -25,6 +25,8 @@ #include "sip_config.h" +#include + #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; diff --git a/src/stream/udp/udp_session.cc b/src/stream/udp/udp_session.cc index 397eb9d9a..b8f8314ff 100644 --- a/src/stream/udp/udp_session.cc +++ b/src/stream/udp/udp_session.cc @@ -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); diff --git a/src/utils/sflsq.cc b/src/utils/sflsq.cc index b786c509f..0627955ae 100644 --- a/src/utils/sflsq.cc +++ b/src/utils/sflsq.cc @@ -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 @@ -37,41 +37,23 @@ #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); } - -