Permit weird sampling rate of 0.

This change allows a weird sampling rate of 0, which completely suppresses
all notifications (previously this crashed Bro). If also fixes the sampling
threshold to work with sampling rates of 0.
This commit is contained in:
Johanna Amann 2018-08-31 21:32:41 -07:00
parent e275927a64
commit 5c68093bc3
5 changed files with 57 additions and 14 deletions

View file

@ -4850,21 +4850,22 @@ export {
const sampling_whitelist: set[string] &redef; const sampling_whitelist: set[string] &redef;
## How many weirds of a given type to tolerate before sampling begins. ## How many weirds of a given type to tolerate before sampling begins.
## i.e. this many consecutive weirds of a given type will be allowed to ## I.e. this many consecutive weirds of a given type will be allowed to
## raise events for script-layer handling before being rate-limited. ## raise events for script-layer handling before being rate-limited.
const sampling_threshold = 25 &redef; const sampling_threshold = 25 &redef;
## The rate-limiting sampling rate. One out of every of this number of ## The rate-limiting sampling rate. One out of every of this number of
## rate-limited weirds of a given type will be allowed to raise events ## rate-limited weirds of a given type will be allowed to raise events
## for further script-layer handling. ## for further script-layer handling. Setting the sampling rate to 0
## will disable all output of rate-limited weirds.
const sampling_rate = 1000 &redef; const sampling_rate = 1000 &redef;
## How long a weird of a given type is allowed to keep state/counters in ## How long a weird of a given type is allowed to keep state/counters in
## memory. For "net" weirds an expiration timer starts per weird name when ## memory. For "net" weirds an expiration timer starts per weird name when
## first initializing its counter. For "flow" weirds an expiration timer ## first initializing its counter. For "flow" weirds an expiration timer
## starts once per src/dst IP pair for the first weird of any name. For ## starts once per src/dst IP pair for the first weird of any name. For
## "conn" weirds, counters and expiration timers are kept for the duration ## "conn" weirds, counters and expiration timers are kept for the duration
## of the connection for each named weird and reset when necessary. e.g. ## of the connection for each named weird and reset when necessary. E.g.
## if a "conn" weird by the name of "foo" is seen more than ## if a "conn" weird by the name of "foo" is seen more than
## :bro:see:`Weird::sampling_threshold` times, then an expiration timer ## :bro:see:`Weird::sampling_threshold` times, then an expiration timer
## begins for "foo" and upon triggering will reset the counter for "foo" ## begins for "foo" and upon triggering will reset the counter for "foo"

View file

@ -1078,10 +1078,10 @@ bool Connection::PermitWeird(const char* name, uint64 threshold, uint64 rate,
auto& state = weird_state[name]; auto& state = weird_state[name];
++state.count; ++state.count;
if ( state.count < threshold ) if ( state.count <= threshold )
return true; return true;
if ( state.count == threshold ) if ( state.count == threshold + 1)
state.sampling_start_time = network_time; state.sampling_start_time = network_time;
else else
{ {
@ -1094,5 +1094,8 @@ bool Connection::PermitWeird(const char* name, uint64 threshold, uint64 rate,
} }
auto num_above_threshold = state.count - threshold; auto num_above_threshold = state.count - threshold;
return num_above_threshold % rate == 0; if ( rate )
return num_above_threshold % rate == 0;
else
return false;
} }

View file

@ -296,11 +296,14 @@ bool Reporter::PermitNetWeird(const char* name)
timer_mgr->Add(new NetWeirdTimer(network_time, name, timer_mgr->Add(new NetWeirdTimer(network_time, name,
weird_sampling_duration)); weird_sampling_duration));
if ( count < weird_sampling_threshold ) if ( count <= weird_sampling_threshold )
return true; return true;
auto num_above_threshold = count - weird_sampling_threshold; auto num_above_threshold = count - weird_sampling_threshold;
return num_above_threshold % weird_sampling_rate == 0; if ( weird_sampling_rate )
return num_above_threshold % weird_sampling_rate == 0;
else
return false;
} }
bool Reporter::PermitFlowWeird(const char* name, bool Reporter::PermitFlowWeird(const char* name,
@ -316,11 +319,14 @@ bool Reporter::PermitFlowWeird(const char* name,
auto& count = map[name]; auto& count = map[name];
++count; ++count;
if ( count < weird_sampling_threshold ) if ( count <= weird_sampling_threshold )
return true; return true;
auto num_above_threshold = count - weird_sampling_threshold; auto num_above_threshold = count - weird_sampling_threshold;
return num_above_threshold % weird_sampling_rate == 0; if ( weird_sampling_rate )
return num_above_threshold % weird_sampling_rate == 0;
else
return false;
} }
void Reporter::Weird(const char* name) void Reporter::Weird(const char* name)

View file

@ -0,0 +1 @@
net_weird, my_net_weird

View file

@ -0,0 +1,32 @@
# @TEST-EXEC: bro -b -r $TRACES/http/bro.org.pcap %INPUT >output
# @TEST-EXEC: btest-diff output
redef Weird::sampling_threshold = 1;
redef Weird::sampling_rate = 0;
event net_weird(name: string)
{
print "net_weird", name;
}
event gen_weirds(c: connection)
{
local num = 5;
while ( num != 0 )
{
Reporter::net_weird("my_net_weird");
--num;
}
}
global did_one_connection = F;
event new_connection(c: connection)
{
if ( did_one_connection )
return;
did_one_connection = T;
event gen_weirds(c);
}