ndn_strategy/context.rs
1use std::sync::Arc;
2
3use ndn_packet::Name;
4use ndn_store::PitToken;
5use ndn_transport::{AnyMap, FaceId};
6
7use crate::MeasurementsTable;
8
9/// A single FIB nexthop.
10#[derive(Clone, Copy, Debug)]
11pub struct FibNexthop {
12 pub face_id: FaceId,
13 pub cost: u32,
14}
15
16/// FIB entry: one or more nexthops with associated costs.
17#[derive(Clone, Debug)]
18pub struct FibEntry {
19 pub nexthops: Vec<FibNexthop>,
20}
21
22impl FibEntry {
23 /// Return nexthops filtered to exclude a specific face (split-horizon).
24 pub fn nexthops_excluding(&self, exclude: FaceId) -> Vec<FibNexthop> {
25 self.nexthops
26 .iter()
27 .copied()
28 .filter(|n| n.face_id != exclude)
29 .collect()
30 }
31}
32
33/// An immutable view of the engine state provided to strategy methods.
34///
35/// Strategies cannot mutate forwarding tables directly — they return
36/// `ForwardingAction` values and the pipeline runner acts on them.
37pub struct StrategyContext<'a> {
38 /// The name being forwarded.
39 pub name: &'a Arc<Name>,
40 /// The face the Interest or Data arrived on.
41 pub in_face: FaceId,
42 /// FIB entry for the longest matching prefix of `name`.
43 pub fib_entry: Option<&'a FibEntry>,
44 /// PIT token for the current Interest, if applicable.
45 pub pit_token: Option<PitToken>,
46 /// Read-only access to EWMA measurements per (prefix, face).
47 pub measurements: &'a MeasurementsTable,
48 /// Cross-layer enrichment data (radio metrics, flow stats, etc.).
49 ///
50 /// Populated by [`ContextEnricher`](ndn_engine::ContextEnricher) instances
51 /// before the strategy runs. Strategies access typed data via
52 /// `ctx.extensions.get::<T>()`.
53 pub extensions: &'a AnyMap,
54}