diff --git a/CHANGES b/CHANGES index db376385e4..a9aa780088 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,10 @@ +3.2.0-dev.466 | 2020-05-04 17:50:14 -0700 + + * Add network_time_init() event. (Jan Grashoefer) + + This event is generated upon first initialization of network_time. + 3.2.0-dev.461 | 2020-05-04 17:08:46 -0700 * Avoid scheduling multiple inactivity timers (Justin Azoff and Jon Siwek, Corelight) diff --git a/VERSION b/VERSION index 2cbfa37a31..6abf7aa3ab 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.2.0-dev.461 +3.2.0-dev.466 diff --git a/doc b/doc index e862aa7a89..c5a1ae5793 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit e862aa7a89c044e7eea96671d9b832a5dfccbf56 +Subproject commit c5a1ae5793b46d65ee3ba9b269a7fc899490734b diff --git a/src/Net.cc b/src/Net.cc index 1334aacd44..faac9e569a 100644 --- a/src/Net.cc +++ b/src/Net.cc @@ -223,8 +223,13 @@ void expire_timers(iosource::PktSrc* src_ps) void net_packet_dispatch(double t, const Packet* pkt, iosource::PktSrc* src_ps) { if ( ! bro_start_network_time ) + { bro_start_network_time = t; + if ( network_time_init ) + mgr.Enqueue(network_time_init, zeek::Args{}); + } + // network_time never goes back. net_update_time(timer_mgr->Time() < t ? t : timer_mgr->Time()); diff --git a/src/event.bif b/src/event.bif index 8927aefa2c..e894d2f5e3 100644 --- a/src/event.bif +++ b/src/event.bif @@ -35,7 +35,7 @@ ## one-time initialization code at startup. At the time a handler runs, Zeek will ## have executed any global initializations and statements. ## -## .. zeek:see:: zeek_done +## .. zeek:see:: zeek_done network_time_init ## ## .. note:: ## @@ -61,6 +61,14 @@ event zeek_init%(%); ## is not generated. event zeek_done%(%); +## Generated when network time is initialized. The event engine generates this +## event after the network time has been determined but before processing of +## packets is started. +## +## .. zeek:see:: zeek_init network_time +## +event network_time_init%(%); + ## Generated for every new connection. This event is raised with the first ## packet of a previously unknown connection. Zeek uses a flow-based definition ## of "connection" here that includes not only TCP sessions but also UDP and diff --git a/testing/btest/Baseline/core.network-time/output b/testing/btest/Baseline/core.network-time/output new file mode 100644 index 0000000000..dfbf750f31 --- /dev/null +++ b/testing/btest/Baseline/core.network-time/output @@ -0,0 +1,8 @@ +zeek_init: 1970-01-01-00:00:00.000000000 +scheduled_event: 2011-03-18-19:06:07.096534967 +network_time_init: 2011-03-18-19:06:07.096534967 +Processing packet 25 at 2011-03-18-19:06:08.858649015 +Processing packet 50 at 2011-03-18-19:06:08.915958881 +Processing packet 75 at 2011-03-18-19:06:08.976326942 +Processing packet 100 at 2011-03-18-19:06:09.073806047 +scheduled_delayed_event: 2011-03-18-19:06:09.073806047 diff --git a/testing/btest/core/network-time.zeek b/testing/btest/core/network-time.zeek new file mode 100644 index 0000000000..0b786f69d7 --- /dev/null +++ b/testing/btest/core/network-time.zeek @@ -0,0 +1,54 @@ +# @TEST-EXEC: zeek -b -C -r $TRACES/wikipedia.trace %INPUT > output +# @TEST-EXEC: btest-diff output + +redef exit_only_after_terminate = T; + +global sde_init: bool = F; + +event scheduled_delayed_event() + { + if ( ! sde_init ) + { + # When network_time is set we (usually) leap forward and the event + # fires with the first packet. Thus, we reschedule. + sde_init = T; + schedule 2sec { scheduled_delayed_event() }; + } + else + { + print fmt("scheduled_delayed_event: %T", network_time()); + } + } + +event scheduled_event() + { + # This event is immediately executed + print fmt("scheduled_event: %T", network_time()); + } + +event zeek_init() + { + # Reading a PCAP network_time is not initialized yet + print fmt("zeek_init: %T", network_time()); + schedule 0sec { scheduled_event() }; + schedule 2sec { scheduled_delayed_event() }; + } + +event network_time_init() + { + # This event is executed when network_time is initialized + print fmt("network_time_init: %T", network_time()); + } + +global pkt_count: count = 0; + +event new_packet(c: connection, p: pkt_hdr) &priority=10 + { + pkt_count += 1; + + if ( pkt_count % 25 == 0 ) + print fmt("Processing packet %s at %T", pkt_count, network_time()); + + if ( pkt_count == 100) + terminate(); + }