]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #3637: parser: improve port_object hash function
authorOleksii Shumeiko -X (oshumeik - SOFTSERVE INC at Cisco) <oshumeik@cisco.com>
Thu, 27 Oct 2022 13:48:59 +0000 (13:48 +0000)
committerOleksii Shumeiko -X (oshumeik - SOFTSERVE INC at Cisco) <oshumeik@cisco.com>
Thu, 27 Oct 2022 13:48:59 +0000 (13:48 +0000)
Merge in SNORT/snort3 from ~VHORBATO/snort3:rtn_hash_fix to master

Squashed commit of the following:

commit 2d4ffd9c1da97b19a40c41909133ef961686f317
Author: Vitalii <vhorbato@cisco.com>
Date:   Tue Oct 11 16:09:48 2022 +0300

    parser: improve port_object hash function

src/parser/parser.cc
src/ports/port_item.cc
src/ports/port_item.h
src/ports/port_object.cc
src/ports/port_object.h
src/ports/port_table.cc

index a34aa9a155d8c432aefd022a564c2de63fcc4af2..d44da15aa7e0105cb62a2525a2abd31222907d54 100644 (file)
@@ -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);
 
index 9b652cb88c9bfa18d8d0bd71590fdccc4cffe783..5ccbd2adbeafe7d520a016242857e4ebfc9eb09a 100644 (file)
@@ -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;
+}
index c4f7a41e664de7a9a86f03d32078b32c47250b6d..532479988477135566773cab4bda4883cede0cb0 100644 (file)
@@ -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
 
index d6488fec45d21b996cf83958f8581812780aa84c..2c426eba592d4621bda7ea8900cbb22721dd5b94 100644 (file)
@@ -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;
+}
index 85d9eda05e766388b69318a926a434a0ac0d2767..e4d69e69bf2e9c4819af405d70f5a1ce9408254d 100644 (file)
@@ -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
 
index c6abfcaff0fcacb4bc44029f1129ed280888722d..6b6775da85b8f4f163c0b69c3431b4ba0bd6563a 100644 (file)
@@ -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);
     }
 }
-