unsigned FlowCache::prune_stale(uint32_t thetime, const Flow* save_me)
{
- ActiveSuspendContext act_susp;
+ ActiveSuspendContext act_susp(Active::ASP_PRUNE);
unsigned pruned = 0;
auto flow = static_cast<Flow*>(hash_table->lru_first());
unsigned FlowCache::prune_unis(PktType pkt_type)
{
- ActiveSuspendContext act_susp;
+ ActiveSuspendContext act_susp(Active::ASP_PRUNE);
// we may have many or few unis; need to find reasonable ratio
// FIXIT-M max_uni should be based on typical ratios seen in perfmon
unsigned FlowCache::prune_excess(const Flow* save_me)
{
- ActiveSuspendContext act_susp;
+ ActiveSuspendContext act_susp(Active::ASP_PRUNE);
auto max_cap = config.max_flows - cleanup_flows;
assert(max_cap > 0);
unsigned FlowCache::timeout(unsigned num_flows, time_t thetime)
{
- ActiveSuspendContext act_susp;
+ ActiveSuspendContext act_susp(Active::ASP_TIMEOUT);
unsigned retired = 0;
auto flow = static_cast<Flow*>(hash_table->lru_current());
unsigned FlowCache::delete_flows(unsigned num_to_delete)
{
- ActiveSuspendContext act_susp;
+ ActiveSuspendContext act_susp(Active::ASP_RELOAD);
unsigned deleted = 0;
// Remove all flows from the hash table.
unsigned FlowCache::purge()
{
- ActiveSuspendContext act_susp;
+ ActiveSuspendContext act_susp(Active::ASP_EXIT);
FlagContext<decltype(flags)>(flags, SESSION_CACHE_FLAG_PURGING);
unsigned retired = 0;
void FlowControl::timeout_flows(time_t cur_time)
{
- ActiveSuspendContext act_susp;
+ ActiveSuspendContext act_susp(Active::ASP_TIMEOUT);
cache->timeout(1, cur_time);
}
using namespace snort;
THREAD_LOCAL bool Active::s_suspend = false;
+THREAD_LOCAL Active::ActiveSuspendReason Active::s_suspend_reason = Active::ASP_NONE;
THREAD_LOCAL PacketTracer* snort::s_pkt_trace = nullptr;
using namespace snort;
THREAD_LOCAL bool Active::s_suspend = false;
+THREAD_LOCAL Active::ActiveSuspendReason Active::s_suspend_reason = Active::ASP_NONE;
THREAD_LOCAL PacketTracer* snort::s_pkt_trace = nullptr;
{
const char* drop_reason = p->active->get_drop_reason();
if (drop_reason)
- PacketTracer::log("Verdict Reason: %s\n", drop_reason);
+ PacketTracer::log("Verdict Reason: %s, %s\n", drop_reason, p->active->get_action_string() );
LogMessage(s_pkt_trace->log_fh, "%s\n", s_pkt_trace->buffer);
}
THREAD_LOCAL uint8_t Active::s_attempts = 0;
THREAD_LOCAL bool Active::s_suspend = false;
+THREAD_LOCAL Active::ActiveSuspendReason Active::s_suspend_reason = Active::ASP_NONE;
THREAD_LOCAL Active::Counts snort::active_counts;
typedef int (* send_t) (
void Active::cant_drop()
{
if ( active_status < AST_CANT )
+ {
active_status = AST_CANT;
-
+ active_would_reason = get_whd_reason_from_suspend_reason();
+ }
else if ( active_status < AST_WOULD )
+ {
+ active_status = AST_WOULD;
+ active_would_reason = get_whd_reason_from_suspend_reason();
+ }
+}
+
+void Active::update_status_actionable(const Packet* p)
+{
+ if ( p->context->conf->inline_mode() )
+ {
+ if ( !SFDAQ::forwarding_packet(p->pkth) )
+ {
+ active_status = AST_WOULD;
+ active_would_reason = WHD_INTERFACE_IDS;
+ }
+ }
+ else if ( p->context->conf->inline_test_mode() )
+ {
active_status = AST_WOULD;
+ active_would_reason = WHD_IPS_INLINE_TEST;
+ }
}
void Active::update_status(const Packet* p, bool force)
{
if ( s_suspend )
- cant_drop();
+ {
+ update_status_actionable(p);
+
+ if(!active_status)
+ cant_drop();
+ }
else if ( force )
active_status = AST_FORCE;
else if ( active_status != AST_FORCE)
{
- if ( p->context->conf->inline_mode() )
- {
- if ( !SFDAQ::forwarding_packet(p->pkth) )
- active_status = AST_WOULD;
- }
- else if ( p->context->conf->inline_test_mode() )
- {
- active_status = AST_WOULD;
- }
+ update_status_actionable(p);
}
}
{
if ( s_suspend )
{
- cant_drop();
+ update_status_actionable(p);
+
+ if(!active_status)
+ cant_drop();
}
else if ( active_status != AST_FORCE )
{
- if ( !SFDAQ::forwarding_packet(p->pkth) )
- active_status = AST_WOULD;
+ update_status_actionable(p);
}
}
void Active::reset_session(Packet* p, ActiveAction* reject, bool force)
{
- update_status(p, force);
active_action = ACT_RESET;
+ update_status(p, force);
if ( force or p->context->conf->inline_mode() or p->context->conf->treat_drop_as_ignore() )
Stream::drop_flow(p);
active_tunnel_bypass = 0;
prevent_trust_action = false;
active_status = AST_ALLOW;
+ active_would_reason = WHD_NONE;
active_action = ACT_ALLOW;
delayed_active_action = ACT_ALLOW;
delayed_reject = nullptr;
enum ActiveStatus : uint8_t
{ AST_ALLOW, AST_CANT, AST_WOULD, AST_FORCE, AST_MAX };
+ enum ActiveWouldReason : uint8_t
+ { WHD_NONE, WHD_INTERFACE_IDS, WHD_IPS_INLINE_TEST, WHD_NAP_INLINE_TEST, WHD_TIMEOUT, WHD_PRUNE, WHD_RELOAD, WHD_EXIT };
+
+ enum ActiveSuspendReason : uint8_t
+ { ASP_NONE, ASP_PRUNE, ASP_TIMEOUT, ASP_RELOAD, ASP_EXIT };
+
// FIXIT-M: these are only used in set_delayed_action and
// apply_delayed_action, in a big switch(action). Do away with these and
// use the actual (Base)Action objects.
static bool thread_init(const SnortConfig*);
static void thread_term();
- static void suspend()
- { s_suspend = true; }
+ static void suspend(ActiveSuspendReason suspend_reason)
+ {
+ s_suspend = true;
+ s_suspend_reason = suspend_reason;
+ }
static void resume()
- { s_suspend = false; }
+ {
+ s_suspend = false;
+ s_suspend_reason = ASP_NONE;
+ }
+
+ static ActiveWouldReason get_whd_reason_from_suspend_reason()
+ {
+ switch ( s_suspend_reason )
+ {
+ case ASP_NONE: return WHD_NONE;
+ case ASP_PRUNE: return WHD_PRUNE;
+ case ASP_TIMEOUT: return WHD_TIMEOUT;
+ case ASP_RELOAD: return WHD_RELOAD;
+ case ASP_EXIT: return WHD_EXIT;
+ }
+ return WHD_NONE;
+ }
void send_reset(Packet*, EncodeFlags);
void send_unreach(Packet*, snort::UnreachResponse);
bool packet_would_be_dropped() const
{ return active_status == AST_WOULD; }
+ ActiveWouldReason get_would_be_dropped_reason() const
+ { return active_would_reason; }
+
+ bool can_partial_block_session() const
+ { return active_status == AST_CANT and s_suspend_reason > ASP_NONE and s_suspend_reason != ASP_TIMEOUT; }
+
bool packet_retry_requested() const
{ return active_action == ACT_RETRY; }
void set_drop_reason(const char*);
void send_reason_to_daq(Packet&);
- const char* get_drop_reason()
+ const char* get_drop_reason()
{ return drop_reason; }
private:
static int send_eth(DAQ_Msg_h, int, const uint8_t* buf, uint32_t len);
static int send_ip(DAQ_Msg_h, int, const uint8_t* buf, uint32_t len);
+ void update_status_actionable(const Packet*);
void update_status(const Packet*, bool force = false);
void daq_update_status(const Packet*);
static const char* act_str[ACT_MAX][AST_MAX];
static THREAD_LOCAL uint8_t s_attempts;
static THREAD_LOCAL bool s_suspend;
+ static THREAD_LOCAL ActiveSuspendReason s_suspend_reason;
int active_tunnel_bypass;
const char* drop_reason;
// of these flags following all processing and the drop
// or response may have been produced by a pseudopacket.
ActiveStatus active_status;
+ ActiveWouldReason active_would_reason;
ActiveActionType active_action;
ActiveActionType delayed_active_action;
ActiveAction* delayed_reject; // set with set_delayed_action()
struct ActiveSuspendContext
{
- ActiveSuspendContext()
- { Active::suspend(); }
+ ActiveSuspendContext(Active::ActiveSuspendReason suspend_reason)
+ { Active::suspend(suspend_reason); }
~ActiveSuspendContext()
{ Active::resume(); }