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}