Skip to main content

Tracker

Struct Tracker 

Source
pub struct Tracker { /* private fields */ }
Expand description

Bounded per-pid liveness ledger.

The slot table is a Vec<Slot> pre-allocated at construction to the configured capacity; subsequent inserts push into that pre-allocated space without reallocation. Lookups use a fixed-size [PidIndex] for O(1) pid-to-index mapping — replaces the original HashMap so the hot path is WCET-bounded (deterministic hash, bounded probe budget, no rehashing on growth).

Implementations§

Source§

impl Tracker

Source

pub fn new( capacity: usize, eviction_policy: EvictionPolicy, eviction_scan_window: usize, ) -> Self

Create an empty tracker with capacity for capacity pids.

The slot table is pre-allocated to capacity entries; pushing beyond that boundary yields Update::CapacityExceeded rather than reallocating.

eviction_scan_window caps the number of slots inspected per eviction attempt. Values outside [MIN_EVICTION_SCAN_WINDOW, MAX_EVICTION_SCAN_WINDOW] are clamped as defense in depth; the config layer rejects out-of-range values loudly at startup.

Source

pub fn record( &mut self, frame: &Frame, now_ns: u64, threshold_ns: u64, origin: BeatOrigin, peer_pid_ns_inode: Option<u64>, ) -> Update

Record a frame against the tracker.

Uses O(1) HashMap pid lookup to find the slot for frame.pid. Returns Update::Inserted for a brand-new pid, Update::Refreshed for an existing pid whose nonce moved forward, Update::OutOfOrder if the nonce did not strictly increase, Update::CapacityExceeded if the slot table is full (and no stale slot could be reclaimed) and the pid is not yet tracked, or Update::OriginConflict if the frame’s transport origin disagrees with the slot’s pinned origin.

origin is the transport-class classification surfaced by the receiving listener (KernelAttested for UDS, NetworkUnverified for any UDP variant). The first beat for a pid pins the slot’s origin; subsequent beats from a different origin are dropped without mutating the slot.

peer_pid_ns_inode is the kernel-attested PID-namespace inode of the sending process (Linux only; None on non-Linux or when /proc/<peer_pid>/ns/pid was unreadable). The first beat pins the slot’s namespace inode; a later beat carrying a different Some(_) inode for the same pid is rejected as Update::NamespaceConflict. A None → Some(_) upgrade is permitted (peer became readable after a transient failure); a Some(_) → None regression is treated as a conflict.

Source

pub fn take_evictions(&mut self) -> u64

Take and reset the eviction counter. Returns the number of slots reclaimed since the last call.

Source

pub fn take_evicted_pid(&mut self) -> Option<u32>

Return the pid of the most recently evicted slot, if any slots have been evicted since the last call.

Source

pub fn take_nonce_wraps(&mut self) -> u64

Take and reset the nonce-wrap counter. Returns the number of nonce-space wraps detected since the last call.

Source

pub fn take_capacity_exceeded(&mut self) -> u64

Take and reset the capacity-exceeded counter. Returns the number of beats dropped due to a full tracker since the last call.

Source

pub fn len(&self) -> usize

Number of pids currently tracked.

Source

pub fn last_ns_of(&self, pid: u32) -> Option<u64>

Return the last_ns timestamp for a tracked pid, if present. Used by the observer for per-pid rate limiting without exposing internal slot layout.

Source

pub fn origin_of(&self, pid: u32) -> Option<BeatOrigin>

Return the pinned transport origin of a tracked pid, if present. Used by the observer to populate Event::OriginConflict::slot_origin before calling record (which may produce the conflict).

Source

pub fn pid_ns_inode_of(&self, pid: u32) -> Option<Option<u64>>

Return the pinned PID-namespace inode of a tracked pid, if present.

The outer Option is Some when the pid is tracked at all; the inner Option is the inode (or None for non-Linux / unreadable). Used by the observer to populate Event::NamespaceConflict::slot_ns_inode without an extra slot lookup.

Source

pub fn is_empty(&self) -> bool

True iff no pids are tracked.

Source

pub fn drain_stalled_slots( &mut self, now_ns: u64, threshold_ns: u64, cb: impl FnMut(u32, u64, u64, BeatOrigin, Option<u64>), )

Find newly-stalled slots and mark them emitted in one atomic pass.

A slot is “newly stalled” when its silence duration exceeds threshold_ns and the observer has not yet surfaced a stall event for the current silence run (stall_emitted == false). Qualifying slots are marked stall_emitted = true and the callback is invoked with (pid, last_nonce, last_ns, origin, pid_ns_inode) — all within the same mutable borrow, closing the TOCTOU window that existed between the former iter_stalled / mark_stall_emitted pair.

Source

pub fn take_origin_conflicts(&mut self) -> u64

Take and reset the origin-conflict counter.

Surfaced as varta_origin_conflict_total by the Prometheus exporter; non-zero values indicate that beats for a tracked pid arrived from a transport other than the one that first claimed the pid — either a misconfigured agent or an active spoofing attempt.

Source

pub fn take_namespace_conflicts(&mut self) -> u64

Take and reset the namespace-conflict counter.

Surfaced as varta_tracker_namespace_conflict_total by the Prometheus exporter; non-zero values mean beats for a tracked pid arrived from a different PID namespace than the one pinned by the slot’s first beat. Linux-only signal; on non-Linux platforms this counter stays at 0.

Source

pub fn take_eviction_scan_truncated(&mut self) -> u64

Take and reset the bounded-window truncated-scan counter.

Surfaced as varta_tracker_eviction_scan_truncated_total by the Prometheus exporter; non-zero values prove the window cap actually engaged (i.e. the table was full and no victim was found within EVICTION_SCAN_WINDOW slots).

Source

pub fn take_invariant_violations(&mut self) -> u64

Take and reset the invariant-violation counter.

Surfaced as varta_tracker_invariant_violations_total by the Prometheus exporter. In correctly-operating code this counter stays at 0 forever — non-zero values mean one of the defensive .get() fall-throughs in the hot path triggered (e.g. a stale PidIndex entry pointed at an out-of-range slot). The tracker recovers without panicking; ops should still treat any non-zero value as a bug worth investigating.

Source

pub fn take_probe_exhausted(&mut self) -> u64

Take and reset the [PidIndex] probe-exhaustion counter.

Surfaced as varta_tracker_pid_index_probe_exhausted_total by the Prometheus exporter. Non-zero values mean a pid lookup walked [PidIndex::MAX_PROBE] slots without resolving — at load factor ≤ 0.5 this is effectively unreachable, so any non-zero value is a red flag (pathological pid distribution, or an attempt to fill the index past its safe load factor).

Trait Implementations§

Source§

impl Default for Tracker

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.