From 45a22be0c94a0144e283ac67e4c1a90f28d84c51 Mon Sep 17 00:00:00 2001 From: "Mike Stepanek (mstepane)" Date: Tue, 24 Mar 2020 17:51:01 +0000 Subject: [PATCH] Merge pull request #2094 in SNORT/snort3 from ~SMINUT/snort3:expect_cache_min_prune to master Squashed commit of the following: commit 9eb02b8dabe4bee0a03cbcbf0a991913f014d059 Author: Silviu Minut 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 | 37 +++++++++++++------------------------ src/flow/expect_cache.h | 8 +++++--- src/hash/xhash.h | 1 + 3 files changed, 19 insertions(+), 27 deletions(-) diff --git a/src/flow/expect_cache.cc b/src/flow/expect_cache.cc index d63b6c6a4..bcc8fc321 100644 --- a/src/flow/expect_cache.cc +++ b/src/flow/expect_cache.cc @@ -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* 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( 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( 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 ( 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 ( 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; } @@ -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 ( hash_table->get_user_data(&key) ); if ( !node ) { - prune(); - node = (ExpectNode*) hash_table->get(&key); + if ( hash_table->full() ) + prune_lru(); + node = static_cast ( hash_table->get(&key) ); assert(node); new_node = true; } diff --git a/src/flow/expect_cache.h b/src/flow/expect_cache.h index 1bb2fd6ee..a69ba7391 100644 --- a/src/flow/expect_cache.h +++ b/src/flow/expect_cache.h @@ -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 diff --git a/src/hash/xhash.h b/src/hash/xhash.h index 2d0e2f36c..98e3ed360 100644 --- a/src/hash/xhash.h +++ b/src/hash/xhash.h @@ -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) -- 2.47.3