Thanks for the feedback!
I found this: "Bro generates this event reliably once for every
connection when it is about to delete the internal state. As such, the
event is well-suited for script-level cleanup that needs to be
performed for every connection."
The oddities seem to exist around UDP, I split it up into
connection_finished and udp_session_done. The TCP stuff seems to
always work/get persisted and the UDP stuff never does.
The expanded script (for anybody interested):
module DF;
# IP -> DHH -> proto -> [0] = number of connections [1] = bytes transferred
global ip_to_connection_info: table[addr] of table[int] of
table[string] of vector of count &persistent &synchronized;
event bro_init()
{
if ( rescan_state() )
print "Success!";
print ip_to_connection_info;
print "------";
}
event bro_done()
{
if ( checkpoint_state() )
print "Success!";
print ip_to_connection_info;
}
#event connection_state_remove(c: connection)
event connection_finished(c: connection)
{
local net_time = network_time();
local date = to_int(strftime("%w%H", net_time));
#local proto = fmt("%s", c$conn$proto);
local proto = "tcp";
local ip = c$id$orig_h;
if ( ip !in ip_to_connection_info )
{
ip_to_connection_info[ip] = table();
}
if ( ip in ip_to_connection_info && date !in ip_to_connection_info[ip] )
{
ip_to_connection_info[ip][date] = table();
}
if ( ip in ip_to_connection_info && date in
ip_to_connection_info[ip] && proto !in ip_to_connection_info[ip][date]
)
{
ip_to_connection_info[ip][date][proto] = vector();
ip_to_connection_info[ip][date][proto][0] = 1;
ip_to_connection_info[ip][date][proto][1] = c$orig$num_bytes_ip;
}
else
{
ip_to_connection_info[ip][date][proto][0] =
ip_to_connection_info[ip][date][proto][0] + 1;
ip_to_connection_info[ip][date][proto][1] =
ip_to_connection_info[ip][date][proto][1] + c$orig$num_bytes_ip;
}
print fmt("ips[%s][%d][%s][connections] = %d", ip, date, proto,
ip_to_connection_info[ip][date][proto][0]);
print fmt("ips[%s][%d][%s][total_bytes] = %d", ip, date, proto,
ip_to_connection_info[ip][date][proto][1]);
print "-------";
}
event udp_session_done(u: connection)
{
local net_time = network_time();
local date = to_int(strftime("%w%H", net_time));
local proto = "udp";
local ip = u$id$orig_h;
if ( ip !in ip_to_connection_info )
{
ip_to_connection_info[ip] = table();
}
if ( ip in ip_to_connection_info && date !in ip_to_connection_info[ip] )
{
ip_to_connection_info[ip][date] = table();
}
if ( ip in ip_to_connection_info && date in
ip_to_connection_info[ip] && proto !in ip_to_connection_info[ip][date]
)
{
ip_to_connection_info[ip][date][proto] = vector();
ip_to_connection_info[ip][date][proto][0] = 1;
ip_to_connection_info[ip][date][proto][1] = u$orig$num_bytes_ip;
}
else
{
ip_to_connection_info[ip][date][proto][0] =
ip_to_connection_info[ip][date][proto][0] + 1;
ip_to_connection_info[ip][date][proto][1] =
ip_to_connection_info[ip][date][proto][1] + u$orig$num_bytes_ip;
}
print fmt("ips[%s][%d][%s][connections] = %d", ip, date, proto,
ip_to_connection_info[ip][date][proto][0]);
print fmt("ips[%s][%d][%s][total_bytes] = %d", ip, date, proto,
ip_to_connection_info[ip][date][proto][1]);
print "-------";
}