use crate::bpv7::EndpointId;
use crate::cla::peer::ClaPeer;
use crate::store::bundle_descriptor::BundleDescriptor;
use async_trait::async_trait;
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct RouteEntry {
pub destination: EndpointId,
pub next_hop: EndpointId,
pub cla_type: String,
pub cost: u32,
pub is_active: bool,
}
#[derive(Debug, Default)]
pub struct RoutingTable {
routes: HashMap<EndpointId, Vec<RouteEntry>>,
}
impl RoutingTable {
pub fn new() -> Self {
Self {
routes: HashMap::new(),
}
}
pub fn add_route(&mut self, entry: RouteEntry) {
self.routes
.entry(entry.destination.clone())
.or_default()
.push(entry);
}
pub fn get_routes_for_destination(&self, destination: &EndpointId) -> Vec<&RouteEntry> {
self.routes
.get(destination)
.map(|routes| routes.iter().filter(|r| r.is_active).collect())
.unwrap_or_default()
}
pub fn get_all_routes(&self) -> Vec<&RouteEntry> {
self.routes
.values()
.flatten()
.filter(|r| r.is_active)
.collect()
}
pub fn find_best_route(&self, destination: &EndpointId) -> Option<&RouteEntry> {
self.get_routes_for_destination(destination)
.into_iter()
.min_by_key(|route| route.cost)
}
}
#[async_trait]
pub trait RoutingAlgorithm: Send + Sync {
fn notify_new_bundle(&mut self, descriptor: &BundleDescriptor);
fn select_peers_for_forwarding<'a>(
&self,
descriptor: &BundleDescriptor,
all_peers: &'a [Box<dyn ClaPeer>],
) -> Vec<&'a dyn ClaPeer>;
async fn select_peers_for_forwarding_async<'a>(
&self,
descriptor: &BundleDescriptor,
all_peers: &'a [Box<dyn ClaPeer>],
) -> Vec<&'a dyn ClaPeer> {
self.select_peers_for_forwarding(descriptor, all_peers)
}
fn select_routes_for_forwarding(
&self,
descriptor: &BundleDescriptor,
routing_table: &RoutingTable,
) -> Vec<RouteEntry>;
}
#[derive(Debug)]
pub enum RoutingAlgorithmType {
Epidemic,
Prophet,
}
pub struct RoutingConfig {
pub algorithm_type: RoutingAlgorithmType,
}
impl RoutingConfig {
pub fn new(algorithm_type: RoutingAlgorithmType) -> Self {
Self { algorithm_type }
}
pub fn create_algorithm(&self) -> Box<dyn RoutingAlgorithm> {
match self.algorithm_type {
RoutingAlgorithmType::Epidemic => Box::new(crate::routing::epidemic::EpidemicRouting),
RoutingAlgorithmType::Prophet => {
eprintln!("Warning: Prophet routing not yet implemented, falling back to epidemic");
Box::new(crate::routing::epidemic::EpidemicRouting)
}
}
}
}