// FlowCache stuff
//-------------------------------------------------------------------------
+THREAD_LOCAL bool FlowCache::pruning_in_progress = false;
+
FlowCache::FlowCache(const FlowCacheConfig& cfg) : config(cfg)
{
hash_table = new ZHash(config.max_flows, sizeof(FlowKey));
bool FlowCache::release(Flow* flow, PruneReason reason, bool do_cleanup)
{
+ assert(!pruning_in_progress);
+ pruning_in_progress = true;
+
if ( !flow->was_blocked() )
{
flow->flush(do_cleanup);
if ( flow->ssn_state.session_flags & SSNFLAG_KEEP_FLOW )
{
flow->ssn_state.session_flags &= ~SSNFLAG_KEEP_FLOW;
+ pruning_in_progress = false;
return false;
}
}
flow->reset(do_cleanup);
prune_stats.update(reason);
remove(flow);
+ pruning_in_progress = false;
return true;
}
FlagContext<decltype(flags)>(flags, SESSION_CACHE_FLAG_PURGING);
unsigned retired = 0;
-
+ assert(!pruning_in_progress);
+ pruning_in_progress = true;
while ( auto flow = static_cast<Flow*>(hash_table->lru_first()) )
{
retire(flow);
++retired;
}
+ pruning_in_progress = false;
while ( Flow* flow = (Flow*)hash_table->pop() )
{
#include <type_traits>
#include "framework/counts.h"
+#include "main/thread.h"
#include "flow_config.h"
#include "prune_stats.h"
unsigned get_flows_allocated() const
{ return flows_allocated; }
+ static bool is_pruning_in_progress()
+ { return pruning_in_progress; }
+
private:
void delete_uni();
void push(snort::Flow*);
(unsigned mode, unsigned num_to_delete, unsigned &deleted);
private:
+ static THREAD_LOCAL bool pruning_in_progress;
static const unsigned cleanup_flows = 1;
FlowCacheConfig config;
uint32_t flags;
THREAD_LOCAL Active::ActiveSuspendReason Active::s_suspend_reason = Active::ASP_NONE;
THREAD_LOCAL PacketTracer* snort::s_pkt_trace = nullptr;
+THREAD_LOCAL bool FlowCache::pruning_in_progress = false;
void Active::drop_packet(snort::Packet const*, bool) { }
PacketTracer::~PacketTracer() = default;
#include <mutex>
#include "detection/detection_engine.h"
+#include "flow/flow_cache.h"
#include "flow/flow_control.h"
#include "flow/flow_key.h"
#include "flow/ha.h"
void Stream::prune_flows()
{
- if ( flow_con )
+ if ( flow_con && !FlowCache::is_pruning_in_progress())
flow_con->prune_one(PruneReason::MEMCAP, false);
}