SumStats framework

Hi,

I’m using SumStats framework to record features in the SSL handshake packets. There are lots of features (30+) I need to record and I created a reducer for each feature. In the SumStats::create(), I check if “feature_x” in result, and record result[“feature_x”]$num. However, the SumStats::create function looks absurdly long. My question is: is it more efficient to break up the current SumStats::create function into multiple (each only have one reducer), or is it better to keep the code I currently have? Which one is faster?

Thanks a lot!

Hi Xu,

Can you share the script you’ve written?

-AK

Hi Anthony,
I have not finished the whole script yet.
But Basically it is
event bro_init()
{
local r: set[SumStats::Reducer];

local chellos = SumStats::Reducer($stream=“client_hello_num”, $apply=set(SumStats::SUM));

add r[chellos];

local shellos = SumStats::Reducer($stream=“server_hello_num”, $apply=set(SumStats::SUM));

add r[shellos];

… (a couple of other reducers )

SumStats::create([$name = “ssl stats”,

$epoch = 1hr,

$reducers = r,

$epoch_result(ts: time, key: SumStats::Key, result: SumStats::Result) =
{
if (“client_hello_num” in result)

bla;
if (“server_hello_num” in result)
bla;
…(a couple of IFs)
}]);
}

Yeah, it looks like you're making that a lot more complicated than it needs to be. You just need a single stream and a single reducer.

When you do the observations just do

    SumStats::observe("ssl_events", [$str="client_hello"], [$num=1]);

or

    SumStats::observe("ssl_events", [$str="server_hello"], [$num=1]);

etc

and then look at 'key' inside of the reducer, not result.

Hi,
Just make sure I understand correctly. So you are saying make a couple of SumStats::create(), each SumStat::create() has only one reducer.
Could you give an example of “looking at ‘key’ inside of the reducer, not result”?
Thanks a lot!

No… I’m saying that you should have a single create.

By looking at the key I mean use the ‘key’ variable that is present in the epoch_result function.

Attached is a script I wrote a few years ago. It lets you track arbitrary statistics using sumstats - but it should only be used for a finite number of ‘key’ values… 1-500 keys would be ok… using something like an id.orig_h as a key will break sumstats.

To use it you can just do

event ssl_server_hello(c: connection, version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count)
{
StatMetrics::increment(“server_hello”, 1);
}

event ssl_client_hello(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec)
{
StatMetrics::increment(“client_hello”, 1);

}

stat_metrics.bro (1.52 KB)

Sorry I did not provide enough information for my problem. You approach would work for client hello and server hello. But for other features, i need to record the value: for example
event ssl_server_hello(…)
{
SumStats::observe(“server_hello_version”,[$str=SSL::version_strings[version]],[$num=1]);

}
I’m using the key field to keep the actual value of that feature. So I cannot reuse the same reducer “ssl_events” because it will lose the actual value of that feature.
SumStats::observe(“ssl_events”,[$str=“server_hello_version”],[$num=1]);

For a small number of values like this you can just set the string to

fmt("server_hello_version.%s", SSL::version_strings[version])

and then you'll get counts of

server_hello_version.SSLv3
server_hello_version.TLSv13

etc.

Hi Justin,

I rewrote my code as you suggested. It works great and reduces more than 100 lines. Thanks a lot!
Now I just need to pay attention to the number of possible values for each feature (str$key). I assume some values may be more than 500, for example, possible ssl_extensions or cipher suites.