use cidr::Ipv6Inet; use cidr::{Ipv4Cidr, Ipv6Cidr}; use dashmap::DashMap; use std::{ collections::BTreeSet, net::{Ipv4Addr, Ipv6Addr}, sync::Arc, }; use crate::{ common::{PeerId, global_ctx::NetworkIdentity}, proto::{ api::instance::ListPublicIpv6InfoResponse, peer_rpc::{ ForeignNetworkRouteInfoEntry, ForeignNetworkRouteInfoKey, PeerIdentityType, RouteForeignNetworkInfos, RouteForeignNetworkSummary, RoutePeerInfo, }, }, }; #[derive(Clone, Debug, Default)] pub enum NextHopPolicy { #[default] LeastHop, LeastCost, } pub type ForeignNetworkRouteInfoMap = DashMap; #[async_trait::async_trait] pub trait RouteInterface { async fn list_peers(&self) -> Vec; fn my_peer_id(&self) -> PeerId; fn need_periodic_requery_peers(&self) -> bool { false } async fn close_peer(&self, _peer_id: PeerId) {} async fn get_peer_public_key(&self, _peer_id: PeerId) -> Option> { None } async fn get_peer_identity_type(&self, _peer_id: PeerId) -> Option { None } async fn list_foreign_networks(&self) -> ForeignNetworkRouteInfoMap { DashMap::new() } } pub type RouteInterfaceBox = Box; #[auto_impl::auto_impl(Box , &mut)] pub trait RouteCostCalculatorInterface: Send + Sync { fn begin_update(&mut self) {} fn end_update(&mut self) {} fn calculate_cost(&self, _src: PeerId, _dst: PeerId) -> i32 { 1 } fn need_update(&self) -> bool { false } fn dump(&self) -> String { "All routes have cost 1".to_string() } } #[derive(Clone, Debug, Default)] pub struct DefaultRouteCostCalculator; impl RouteCostCalculatorInterface for DefaultRouteCostCalculator {} pub type RouteCostCalculator = Box; #[async_trait::async_trait] #[auto_impl::auto_impl(Box, Arc)] pub trait Route { async fn open(&self, interface: RouteInterfaceBox) -> Result; async fn close(&self); async fn get_next_hop(&self, peer_id: PeerId) -> Option; async fn get_next_hop_with_policy( &self, peer_id: PeerId, _policy: NextHopPolicy, ) -> Option { self.get_next_hop(peer_id).await } async fn list_routes(&self) -> Vec; // TODO: rewrite route management, remove this async fn list_proxy_cidrs(&self) -> BTreeSet; // TODO: rewrite route management, remove this async fn list_proxy_cidrs_v6(&self) -> BTreeSet; async fn list_public_ipv6_routes(&self) -> BTreeSet { BTreeSet::new() } async fn get_my_public_ipv6_addr(&self) -> Option { None } async fn get_public_ipv6_gateway_peer_id(&self) -> Option { None } async fn get_local_public_ipv6_info(&self) -> ListPublicIpv6InfoResponse { ListPublicIpv6InfoResponse::default() } async fn get_peer_id_by_ipv4(&self, _ipv4: &Ipv4Addr) -> Option { None } async fn get_peer_id_by_ipv6(&self, _ipv6: &Ipv6Addr) -> Option { None } async fn get_peer_id_by_ip(&self, ip: &std::net::IpAddr) -> Option { match ip { std::net::IpAddr::V4(v4) => self.get_peer_id_by_ipv4(v4).await, std::net::IpAddr::V6(v6) => self.get_peer_id_by_ipv6(v6).await, } } async fn list_peers_own_foreign_network( &self, _network_identity: &NetworkIdentity, ) -> Vec { vec![] } async fn list_foreign_network_info(&self) -> RouteForeignNetworkInfos { Default::default() } async fn get_foreign_network_summary(&self) -> RouteForeignNetworkSummary { Default::default() } // my peer id in foreign network is different from the one in local network // this function is used to get the peer id in local network async fn get_origin_my_peer_id( &self, _network_name: &str, _foreign_my_peer_id: PeerId, ) -> Option { None } async fn set_route_cost_fn(&self, _cost_fn: RouteCostCalculator) {} async fn get_peer_info(&self, peer_id: PeerId) -> Option; async fn get_peer_info_last_update_time(&self) -> std::time::Instant; fn get_peer_groups(&self, peer_id: PeerId) -> Arc>; async fn refresh_acl_groups(&self) {} async fn get_peer_groups_by_ip(&self, ip: &std::net::IpAddr) -> Arc> { match self.get_peer_id_by_ip(ip).await { Some(peer_id) => self.get_peer_groups(peer_id), None => Arc::new(Vec::new()), } } async fn get_peer_groups_by_ipv4(&self, ipv4: &Ipv4Addr) -> Arc> { match self.get_peer_id_by_ipv4(ipv4).await { Some(peer_id) => self.get_peer_groups(peer_id), None => Arc::new(Vec::new()), } } async fn dump(&self) -> String { "this route implementation does not support dump".to_string() } } pub type ArcRoute = Arc>; pub struct MockRoute {} #[async_trait::async_trait] impl Route for MockRoute { async fn open(&self, _interface: RouteInterfaceBox) -> Result { panic!("mock route") } async fn close(&self) { panic!("mock route") } async fn get_next_hop(&self, _peer_id: PeerId) -> Option { panic!("mock route") } async fn list_routes(&self) -> Vec { panic!("mock route") } // TODO: rewrite route management, remove this async fn list_proxy_cidrs(&self) -> BTreeSet { unimplemented!() } // TODO: rewrite route management, remove this async fn list_proxy_cidrs_v6(&self) -> BTreeSet { unimplemented!() } async fn list_public_ipv6_routes(&self) -> BTreeSet { unimplemented!() } async fn get_my_public_ipv6_addr(&self) -> Option { panic!("mock route") } async fn get_peer_info(&self, _peer_id: PeerId) -> Option { panic!("mock route") } async fn get_peer_info_last_update_time(&self) -> std::time::Instant { panic!("mock route") } fn get_peer_groups(&self, _peer_id: PeerId) -> Arc> { panic!("mock route") } }