mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
RunState: Implement forward_network_time_if_applicable()
Add a central place where the decision when it's okay to update network time to the current time (wallclock) is. It checks for pseudo_realtime and packet source existence as well as packet source idleness. A new const &redef allows to completely disable forwarding of network time.
This commit is contained in:
parent
eefa0150b9
commit
d4e31e7d2b
4 changed files with 80 additions and 13 deletions
|
@ -161,6 +161,32 @@ type PacketSource: record {
|
||||||
netmask: count;
|
netmask: count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
## If a packet source does not yield packets for this amount of time,
|
||||||
|
## it is considered idle. When a packet source is found to be idle,
|
||||||
|
## Zeek will update network_time to current time in order for timer expiration
|
||||||
|
## to function. A packet source queueing up packets and not yielding them for
|
||||||
|
## longer than this interval without yielding any packets will provoke
|
||||||
|
## not-very-well-defined timer behavior.
|
||||||
|
##
|
||||||
|
## On Zeek workers with low packet rates, timer expiration may be delayed
|
||||||
|
## by this many milliseconds after the last packet has been received.
|
||||||
|
const packet_source_inactivity_timeout = 100msec &redef;
|
||||||
|
|
||||||
|
## Whether Zeek will forward network_time to the current time upon
|
||||||
|
## observing an idle packet source (or no configured packet source).
|
||||||
|
##
|
||||||
|
## Only set this to *F* if you really know what you're doing. Setting this to
|
||||||
|
## *F* on non-worker systems causes :zeek:see:`network_time` to be stuck
|
||||||
|
## at 0.0 and timer expiration will be non-functional.
|
||||||
|
##
|
||||||
|
## The main purpose of this option is to yield control over network time
|
||||||
|
## to plugins or scripts via broker or other non-timer events.
|
||||||
|
##
|
||||||
|
## .. zeek:see:: network_time set_network_time packet_source_inactivity_timeout
|
||||||
|
##
|
||||||
|
const allow_network_time_forward = T &redef;
|
||||||
|
|
||||||
## A connection's transport-layer protocol. Note that Zeek uses the term
|
## A connection's transport-layer protocol. Note that Zeek uses the term
|
||||||
## "connection" broadly, using flow semantics for ICMP and UDP.
|
## "connection" broadly, using flow semantics for ICMP and UDP.
|
||||||
type transport_proto: enum {
|
type transport_proto: enum {
|
||||||
|
|
|
@ -137,6 +137,44 @@ void update_network_time(double new_network_time)
|
||||||
PLUGIN_HOOK_VOID(HOOK_UPDATE_NETWORK_TIME, HookUpdateNetworkTime(new_network_time));
|
PLUGIN_HOOK_VOID(HOOK_UPDATE_NETWORK_TIME, HookUpdateNetworkTime(new_network_time));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Logic to decide when updating network_time is acceptable:
|
||||||
|
static bool should_forward_network_time()
|
||||||
|
{
|
||||||
|
// In pseudo_realtime mode, always update time once
|
||||||
|
// we've dispatched and processed the first packet.
|
||||||
|
// run_state::detail::first_timestamp is currently set
|
||||||
|
// in PktSrc::ExtractNextPacketInternal()
|
||||||
|
if ( pseudo_realtime != 0.0 && run_state::detail::first_timestamp != 0.0 )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ( iosource::PktSrc* ps = iosource_mgr->GetPktSrc() )
|
||||||
|
{
|
||||||
|
// Offline packet sources always control network time
|
||||||
|
// unless we're running pseudo_realtime, see above.
|
||||||
|
if ( ! ps->IsLive() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( ! ps->HasBeenIdleFor(BifConst::packet_source_inactivity_timeout) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We determined that we don't have a packet source, or it is idle.
|
||||||
|
// Unless it has been disabled, network_time will now be moved forward.
|
||||||
|
return BifConst::allow_network_time_forward;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void forward_network_time_if_applicable()
|
||||||
|
{
|
||||||
|
if ( ! should_forward_network_time() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
double now = util::current_time(true);
|
||||||
|
if ( now > network_time )
|
||||||
|
update_network_time(now);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void init_run(const std::optional<std::string>& interface,
|
void init_run(const std::optional<std::string>& interface,
|
||||||
const std::optional<std::string>& pcap_input_file,
|
const std::optional<std::string>& pcap_input_file,
|
||||||
const std::optional<std::string>& pcap_output_file, bool do_watchdog)
|
const std::optional<std::string>& pcap_output_file, bool do_watchdog)
|
||||||
|
@ -319,21 +357,21 @@ void run_loop()
|
||||||
// date on timers and events. Because we only
|
// date on timers and events. Because we only
|
||||||
// have timers as sources, going to sleep here
|
// have timers as sources, going to sleep here
|
||||||
// doesn't risk blocking on other inputs.
|
// doesn't risk blocking on other inputs.
|
||||||
update_network_time(util::current_time());
|
//
|
||||||
|
// TBD: Is this actually still relevant given that the TimerMgr
|
||||||
|
// is an IO source now? It'll be processed once its
|
||||||
|
// GetNextTimeout() yields 0 and before that there's nothing
|
||||||
|
// to expire anyway.
|
||||||
|
forward_network_time_if_applicable();
|
||||||
expire_timers();
|
expire_timers();
|
||||||
|
|
||||||
|
// Prevent another forward_network_time_if_applicable() below
|
||||||
|
// even if time wasn't actually updated.
|
||||||
|
time_updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that the time gets updated every pass if we're reading live.
|
if ( ! time_updated )
|
||||||
// This is necessary for e.g. packet sources that don't have a selectable
|
forward_network_time_if_applicable();
|
||||||
// file descriptor. They'll always be ready on a very short timeout, but
|
|
||||||
// won't necessarily have a packet to process. In these case, sometimes
|
|
||||||
// the time won't get updated for a long time and timers don't function
|
|
||||||
// correctly.
|
|
||||||
if ( (! time_updated && reading_live) )
|
|
||||||
{
|
|
||||||
update_network_time(util::current_time());
|
|
||||||
expire_timers();
|
|
||||||
}
|
|
||||||
|
|
||||||
event_mgr.Drain();
|
event_mgr.Drain();
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
##! internally. Documentation and default values for the scripting-layer
|
##! internally. Documentation and default values for the scripting-layer
|
||||||
##! variables themselves are found in :doc:`/scripts/base/init-bare.zeek`.
|
##! variables themselves are found in :doc:`/scripts/base/init-bare.zeek`.
|
||||||
|
|
||||||
|
const packet_source_inactivity_timeout: interval;
|
||||||
|
const allow_network_time_forward: bool;
|
||||||
const ignore_keep_alive_rexmit: bool;
|
const ignore_keep_alive_rexmit: bool;
|
||||||
const skip_http_data: bool;
|
const skip_http_data: bool;
|
||||||
const use_conn_size_analyzer: bool;
|
const use_conn_size_analyzer: bool;
|
||||||
|
|
|
@ -1036,7 +1036,8 @@ SetupResult setup(int argc, char** argv, Options* zopts)
|
||||||
segment_logger = profiling_logger;
|
segment_logger = profiling_logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! run_state::reading_live && ! run_state::reading_traces )
|
if ( ! run_state::reading_live && ! run_state::reading_traces &&
|
||||||
|
id::find_const("allow_network_time_forward")->AsBool() )
|
||||||
// Set up network_time to track real-time, since
|
// Set up network_time to track real-time, since
|
||||||
// we don't have any other source for it.
|
// we don't have any other source for it.
|
||||||
run_state::detail::update_network_time(util::current_time());
|
run_state::detail::update_network_time(util::current_time());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue