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;
|
||||
};
|
||||
|
||||
|
||||
## 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
|
||||
## "connection" broadly, using flow semantics for ICMP and UDP.
|
||||
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));
|
||||
}
|
||||
|
||||
// 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,
|
||||
const std::optional<std::string>& pcap_input_file,
|
||||
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
|
||||
// have timers as sources, going to sleep here
|
||||
// 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();
|
||||
|
||||
// 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.
|
||||
// This is necessary for e.g. packet sources that don't have a selectable
|
||||
// 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();
|
||||
}
|
||||
if ( ! time_updated )
|
||||
forward_network_time_if_applicable();
|
||||
|
||||
event_mgr.Drain();
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
##! internally. Documentation and default values for the scripting-layer
|
||||
##! 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 skip_http_data: bool;
|
||||
const use_conn_size_analyzer: bool;
|
||||
|
|
|
@ -1036,7 +1036,8 @@ SetupResult setup(int argc, char** argv, Options* zopts)
|
|||
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
|
||||
// we don't have any other source for it.
|
||||
run_state::detail::update_network_time(util::current_time());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue