]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2094 in SNORT/snort3 from ~SMINUT/snort3:expect_cache_min_prune...
authorMike Stepanek (mstepane) <mstepane@cisco.com>
Tue, 24 Mar 2020 17:51:01 +0000 (17:51 +0000)
committerMike Stepanek (mstepane) <mstepane@cisco.com>
Tue, 24 Mar 2020 17:51:01 +0000 (17:51 +0000)
Squashed commit of the following:

commit 9eb02b8dabe4bee0a03cbcbf0a991913f014d059
Author: Silviu Minut <sminut@cisco.com>
Date:   Fri Mar 20 22:30:54 2020 -0400

    flow: allow the ExpectCache to force prune, so that we can always make room when the cache is full.

    flow: change the ExpectCache prune logic to only remove a specified number of oldest entries, regardless of node expiration time.

    flow: do away altogether with the loop in ExpectCache::prune, just remove one, only when the cache is full.

src/flow/expect_cache.cc
src/flow/expect_cache.h
src/hash/xhash.h

index d63b6c6a4b5f69ce91db54bcf93a0d94ea857341..bcc8fc321b874e8716b247e72e19ef123ee00a51 100644 (file)
@@ -40,7 +40,6 @@ using namespace snort;
 #define MAX_LIST    8
 #define MAX_DATA    4
 #define MAX_WAIT  300
-#define MAX_PRUNE   5
 
 static THREAD_LOCAL std::vector<ExpectFlow*>* packet_expect_flows = nullptr;
 
@@ -127,22 +126,13 @@ void ExpectNode::clear(ExpectFlow*& list)
 // private ExpectCache methods
 //-------------------------------------------------------------------------
 
-// Clean the hash table of at most MAX_PRUNE expired nodes
-void ExpectCache::prune()
+void ExpectCache::prune_lru()
 {
-    time_t now = packet_time();
-
-    for (unsigned i = 0; i < MAX_PRUNE; ++i )
-    {
-        ExpectNode* node = (ExpectNode*)hash_table->lru_first();
-
-        if ( !node || now <= node->expires )
-            break;
-
-        node->clear(free_list);
-        hash_table->release();
-        ++prunes;
-    }
+    ExpectNode* node = static_cast<ExpectNode*>( hash_table->lru_first() );
+    assert(node);
+    node->clear(free_list);
+    hash_table->release();
+    ++prunes;
 }
 
 ExpectNode* ExpectCache::find_node_by_packet(Packet* p, FlowKey &key)
@@ -171,7 +161,7 @@ ExpectNode* ExpectCache::find_node_by_packet(Packet* p, FlowKey &key)
     */
     // FIXIT-P X This should be optimized to only do full matches when full keys
     //      are present, likewise for partial keys.
-    ExpectNode* node = (ExpectNode*) hash_table->get_user_data(&key);
+    ExpectNode* node = static_cast<ExpectNode*>( hash_table->get_user_data(&key) );
     if (!node)
     {
         // FIXIT-M X This logic could fail if IPs were equal because the original key
@@ -192,12 +182,12 @@ ExpectNode* ExpectCache::find_node_by_packet(Packet* p, FlowKey &key)
             port2 = key.port_h;
             key.port_h = 0;
         }
-        node = (ExpectNode*) hash_table->get_user_data(&key);
+        node = static_cast<ExpectNode*> ( hash_table->get_user_data(&key) );
         if (!node)
         {
             key.port_l = port1;
             key.port_h = port2;
-            node = (ExpectNode*) hash_table->get_user_data(&key);
+            node = static_cast<ExpectNode*> ( hash_table->get_user_data(&key) );
             if (!node)
                 return nullptr;
         }
@@ -288,8 +278,6 @@ ExpectCache::ExpectCache(uint32_t max)
         free_list = p;
     }
 
-    expects = realized = 0;
-    prunes = overflows = 0;
     if (packet_expect_flows == nullptr)
         packet_expect_flows = new std::vector<ExpectFlow*>;
 }
@@ -335,11 +323,12 @@ int ExpectCache::add_flow(const Packet *ctrlPkt, PktType type, IpProtocol ip_pro
             vlanId, mplsId, addressSpaceId);
 
     bool new_node = false;
-    ExpectNode* node = (ExpectNode*) hash_table->get_user_data(&key);
+    ExpectNode* node = static_cast<ExpectNode*> ( hash_table->get_user_data(&key) );
     if ( !node )
     {
-        prune();
-        node = (ExpectNode*) hash_table->get(&key);
+        if ( hash_table->full() )
+            prune_lru();
+        node = static_cast<ExpectNode*> ( hash_table->get(&key) );
         assert(node);
         new_node = true;
     }
index 1bb2fd6eedaa807d9e86d91ee460f461cdce2443..a69ba7391b10e9ece47dfdd27c3cd6f66b4a3e75 100644 (file)
@@ -109,7 +109,7 @@ public:
     unsigned long get_overflows() { return overflows; }
 
 private:
-    void prune();
+    void prune_lru();
 
     ExpectNode* get_node(snort::FlowKey&, bool&);
     snort::ExpectFlow* get_flow(ExpectNode*, uint32_t, int16_t);
@@ -123,8 +123,10 @@ private:
     snort::ExpectFlow* pool;
     snort::ExpectFlow* free_list;
 
-    unsigned long expects, realized;
-    unsigned long prunes, overflows;
+    unsigned long expects = 0;
+    unsigned long realized = 0;
+    unsigned long prunes = 0;
+    unsigned long overflows = 0;
 };
 
 #endif
index 2d0e2f36c37254b9047e445bcfa49d46c4f9d6d5..98e3ed360f8cf89ea62c2f2b959499dda0b02f8c 100644 (file)
@@ -65,6 +65,7 @@ public:
     void* get_lru_user_data();
     bool delete_lru_node();
     void clear_hash();
+    bool full() const { return !fhead; }
 
     // set max hash nodes, 0 == no limit
     void set_max_nodes(int max)