From: Oleksii Shumeiko -X (oshumeik - SOFTSERVE INC at Cisco) Date: Thu, 27 Oct 2022 13:48:59 +0000 (+0000) Subject: Pull request #3637: parser: improve port_object hash function X-Git-Tag: 3.1.47.0~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e04094050de276c98e7d991b0c91c0afc86fb3fa;p=thirdparty%2Fsnort3.git Pull request #3637: parser: improve port_object hash function Merge in SNORT/snort3 from ~VHORBATO/snort3:rtn_hash_fix to master Squashed commit of the following: commit 2d4ffd9c1da97b19a40c41909133ef961686f317 Author: Vitalii Date: Tue Oct 11 16:09:48 2022 +0300 parser: improve port_object hash function --- diff --git a/src/parser/parser.cc b/src/parser/parser.cc index a34aa9a15..d44da15aa 100644 --- a/src/parser/parser.cc +++ b/src/parser/parser.cc @@ -91,6 +91,8 @@ public: mix(a,b,c); a += (uint32_t)(uintptr_t)rtnk->policyId; + b += PortObjectHash(rtn->src_portobject, seed, scale, hardener); + c += PortObjectHash(rtn->dst_portobject, seed, scale, hardener); finalize(a,b,c); diff --git a/src/ports/port_item.cc b/src/ports/port_item.cc index 9b652cb88..5ccbd2adb 100644 --- a/src/ports/port_item.cc +++ b/src/ports/port_item.cc @@ -87,3 +87,23 @@ void PortObjectItemPrint(PortObjectItem* poi, char* dstbuf, int bufsize) SnortSnprintfAppend(dstbuf, bufsize, "%hu:%hu",poi->lport,poi->hport); } +/* + Calculate the hash value of the port item. +*/ +unsigned PortObjectItemHash(PortObjectItem* poi, unsigned hash, unsigned scale) +{ + if ( poi->any() ) + return 0; + + hash *= scale; + hash += poi->lport & 0xff; + hash *= scale; + hash += (poi->lport >> 8) & 0xff; + + hash *= scale; + hash += poi->hport & 0xff; + hash *= scale; + hash += (poi->hport >> 8) & 0xff; + + return hash; +} diff --git a/src/ports/port_item.h b/src/ports/port_item.h index c4f7a41e6..532479988 100644 --- a/src/ports/port_item.h +++ b/src/ports/port_item.h @@ -54,6 +54,7 @@ void PortObjectItemFree(PortObjectItem*); PortObjectItem* PortObjectItemDup(PortObjectItem*); int PortObjectItemsEqual(PortObjectItem* a, PortObjectItem* b); void PortObjectItemPrint(PortObjectItem*, char* dstbuf, int bufsize); +unsigned PortObjectItemHash(PortObjectItem*, unsigned hash, unsigned scale); #endif diff --git a/src/ports/port_object.cc b/src/ports/port_object.cc index d6488fec4..2c426eba5 100644 --- a/src/ports/port_object.cc +++ b/src/ports/port_object.cc @@ -136,9 +136,9 @@ int PortObjectAddPortObject(PortObject* podst, PortObject* posrc, int* errflag) if (errflag) *errflag = 0; - for (po=(PortObjectItem*)sflist_first(posrc->item_list, &pos); + for (po = (PortObjectItem*)sflist_first(posrc->item_list, &pos); po != nullptr; - po=(PortObjectItem*)sflist_next(&pos) ) + po = (PortObjectItem*)sflist_next(&pos)) { PortObjectItem* poi = PortObjectItemDup(po); if ((ret = PortObjectAddItem(podst, poi, errflag)) != 0) @@ -212,7 +212,7 @@ PortObject* PortObjectDup(PortObject* po) { 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); PortObjectAddItem(ponew, poinew, nullptr); @@ -224,7 +224,7 @@ PortObject* PortObjectDup(PortObject* po) { for (int* prid = (int*)sflist_first(po->rule_list, &lpos); prid != nullptr; - prid = (int*)sflist_next(&lpos) ) + prid = (int*)sflist_next(&lpos)) { int* prule = (int*)snort_calloc(sizeof(int)); *prule = *prid; @@ -334,9 +334,9 @@ int PortObjectPortCount(PortObject* po) if ( !po ) return 0; - for (PortObjectItem* poi=(PortObjectItem*)sflist_first(po->item_list, &cursor); + for (PortObjectItem* poi = (PortObjectItem*)sflist_first(po->item_list, &cursor); poi != nullptr; - poi=(PortObjectItem*)sflist_next(&cursor) ) + poi = (PortObjectItem*)sflist_next(&cursor)) { if ( poi->any() ) return -1; @@ -376,9 +376,9 @@ int PortObjectHasPort(PortObject* po, int port) if ( !po ) return 0; - for (poi=(PortObjectItem*)sflist_first(po->item_list, &cursor); + for (poi = (PortObjectItem*)sflist_first(po->item_list, &cursor); poi != nullptr; - poi=(PortObjectItem*)sflist_next(&cursor) ) + poi = (PortObjectItem*)sflist_next(&cursor)) { if ( poi->any() ) return 0; @@ -402,9 +402,9 @@ void PortObjectToggle(PortObject* po) if (!po) return; - 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)) { poi->negate = !poi->negate; } @@ -419,9 +419,9 @@ int PortObjectIsPureNot(PortObject* po) if ( !po ) return 0; - for (poi=(PortObjectItem*)sflist_first(po->item_list, &cursor); + for (poi = (PortObjectItem*)sflist_first(po->item_list, &cursor); poi != nullptr; - poi=(PortObjectItem*)sflist_next(&cursor) ) + poi = (PortObjectItem*)sflist_next(&cursor)) { cnt++; if ( !poi->negate ) @@ -442,9 +442,9 @@ int PortObjectHasAny(PortObject* po) if ( !po ) return 0; - for (poi=(PortObjectItem*)sflist_first(po->item_list, &cursor); + for (poi = (PortObjectItem*)sflist_first(po->item_list, &cursor); poi != nullptr; - poi=(PortObjectItem*)sflist_next(&cursor) ) + poi = (PortObjectItem*)sflist_next(&cursor)) { if ( poi->any() ) return 1; @@ -481,8 +481,8 @@ 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) ) + poib != nullptr; + poib = (PortObjectItem*)sflist_next(&cursor)) { PortObjectItem* poia = PortObjectItemNew(); @@ -521,9 +521,9 @@ void PortObjectPrintPortsRaw(PortObject* po) buf = (char*)snort_calloc(bufsize); SnortSnprintfAppend(buf, bufsize, " ["); - 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, buf, bufsize); } @@ -582,7 +582,7 @@ void PortObjectPrintEx(PortObject* po, po_print_f print_index_map) { 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); } @@ -616,3 +616,24 @@ void PortObjectPrintEx(PortObject* po, po_print_f print_index_map) snort_free(rlist); } +unsigned PortObjectHash(const PortObject* po, unsigned hash, unsigned scale, unsigned hardener) +{ +#ifndef DEBUG + if (po->hash != 0) + return po->hash; +#endif + + SF_LNODE* pos; + + for (PortObjectItem* poi = (PortObjectItem*)sflist_first(po->item_list, &pos); + poi != nullptr; + poi = (PortObjectItem*)sflist_next(&pos)) + { + hash = PortObjectItemHash(poi, hash, scale); + } + + assert(po->hash == 0 or po->hash == (hash ^ hardener)); + po->hash = hash ^ hardener; + + return po->hash; +} diff --git a/src/ports/port_object.h b/src/ports/port_object.h index 85d9eda05..e4d69e69b 100644 --- a/src/ports/port_object.h +++ b/src/ports/port_object.h @@ -37,6 +37,7 @@ struct PortObject // FIXIT-L convert char* to C++ string char* name; /* user name */ int id; /* internal tracking - compiling sets this value */ + mutable unsigned hash = 0; SF_LIST* item_list; /* list of port and port-range items */ SF_LIST* rule_list; /* list of rules */ @@ -77,5 +78,7 @@ void PortObjectPrintPortsRaw(PortObject*); typedef void (*po_print_f)(int index, char* buf, int bufsize); void PortObjectPrintEx(PortObject*, po_print_f); +unsigned PortObjectHash(const PortObject*, unsigned hash, unsigned scale, unsigned hardener); + #endif diff --git a/src/ports/port_table.cc b/src/ports/port_table.cc index c6abfcaff..6b6775da8 100644 --- a/src/ports/port_table.cc +++ b/src/ports/port_table.cc @@ -149,28 +149,8 @@ public: unsigned do_hash(const unsigned char* k, int) override { - unsigned hash = seed; const PortObject* po = *(PortObject* const*)k; - SF_LNODE* pos; - - for (PortObjectItem* poi = (PortObjectItem*)sflist_first(po->item_list, &pos); - poi != nullptr; - poi = (PortObjectItem*)sflist_next(&pos) ) - { - if ( poi->any() ) - continue; - - hash *= scale; - hash += poi->lport & 0xff; - hash *= scale; - hash += (poi->lport >> 8) & 0xff; - - hash *= scale; - hash += poi->hport & 0xff; - hash *= scale; - hash += (poi->hport >> 8) & 0xff; - } - return hash ^ hardener; + return PortObjectHash(po, seed, scale, hardener); } bool key_compare(const void* k1, const void* k2, size_t) override @@ -898,4 +878,3 @@ void PortTableSortUniqRules(PortTable* p) RuleListSortUniq(po->rule_list); } } -