use crate::bpv7::EndpointId;
use crate::store::bundle_descriptor::BundleDescriptor;
use std::collections::HashMap;
pub trait ConvergenceSender {
fn get_peer_endpoint_id(&self) -> EndpointId;
}
pub struct TcpSender {
pub peer_id: EndpointId,
}
impl TcpSender {
pub fn new(peer_id: EndpointId) -> Self {
Self { peer_id }
}
}
impl ConvergenceSender for TcpSender {
fn get_peer_endpoint_id(&self) -> EndpointId {
self.peer_id.clone()
}
}
#[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)
}
}
pub trait RoutingAlgorithm: Send + Sync {
fn notify_new_bundle(&mut self, descriptor: &BundleDescriptor);
fn select_peers_for_forwarding<'a>(
&self,
descriptor: &BundleDescriptor,
all_senders: &'a [Box<dyn ConvergenceSender>],
) -> Vec<&'a dyn ConvergenceSender>;
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)
}
}
}
}