mirror of
https://mirror.suhoan.cn/https://github.com/EasyTier/EasyTier.git
synced 2025-12-17 07:07:22 +08:00
remove lock of routes
This commit is contained in:
@@ -4,8 +4,8 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
use arc_swap::ArcSwap;
|
||||||
use dashmap::{DashMap, DashSet};
|
use dashmap::{DashMap, DashSet};
|
||||||
use tokio::sync::RwLock;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
common::{
|
common::{
|
||||||
@@ -32,7 +32,7 @@ pub struct PeerMap {
|
|||||||
my_peer_id: PeerId,
|
my_peer_id: PeerId,
|
||||||
peer_map: DashMap<PeerId, Arc<Peer>>,
|
peer_map: DashMap<PeerId, Arc<Peer>>,
|
||||||
packet_send: PacketRecvChan,
|
packet_send: PacketRecvChan,
|
||||||
routes: RwLock<Vec<ArcRoute>>,
|
route: ArcSwap<Option<ArcRoute>>,
|
||||||
alive_conns: Arc<DashMap<(PeerId, PeerConnId), PeerConnInfo>>,
|
alive_conns: Arc<DashMap<(PeerId, PeerConnId), PeerConnInfo>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ impl PeerMap {
|
|||||||
my_peer_id,
|
my_peer_id,
|
||||||
peer_map: DashMap::new(),
|
peer_map: DashMap::new(),
|
||||||
packet_send,
|
packet_send,
|
||||||
routes: RwLock::new(Vec::new()),
|
route: ArcSwap::from(Arc::new(None)),
|
||||||
alive_conns: Arc::new(DashMap::new()),
|
alive_conns: Arc::new(DashMap::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,7 +154,7 @@ impl PeerMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get route info
|
// get route info
|
||||||
for route in self.routes.read().await.iter() {
|
if let Some(route) = self.route.load().as_ref() {
|
||||||
if let Some(gateway_peer_id) = route
|
if let Some(gateway_peer_id) = route
|
||||||
.get_next_hop_with_policy(dst_peer_id, policy.clone())
|
.get_next_hop_with_policy(dst_peer_id, policy.clone())
|
||||||
.await
|
.await
|
||||||
@@ -171,14 +171,13 @@ impl PeerMap {
|
|||||||
&self,
|
&self,
|
||||||
network_identity: &NetworkIdentity,
|
network_identity: &NetworkIdentity,
|
||||||
) -> Vec<PeerId> {
|
) -> Vec<PeerId> {
|
||||||
let mut ret = Vec::new();
|
if let Some(route) = self.route.load().as_ref() {
|
||||||
for route in self.routes.read().await.iter() {
|
route
|
||||||
let peers = route
|
|
||||||
.list_peers_own_foreign_network(&network_identity)
|
.list_peers_own_foreign_network(&network_identity)
|
||||||
.await;
|
.await
|
||||||
ret.extend(peers);
|
} else {
|
||||||
|
Vec::new()
|
||||||
}
|
}
|
||||||
ret
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_msg(
|
pub async fn send_msg(
|
||||||
@@ -199,32 +198,27 @@ impl PeerMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_peer_id_by_ipv4(&self, ipv4: &Ipv4Addr) -> Option<PeerId> {
|
pub async fn get_peer_id_by_ipv4(&self, ipv4: &Ipv4Addr) -> Option<PeerId> {
|
||||||
for route in self.routes.read().await.iter() {
|
if let Some(route) = self.route.load().as_ref() {
|
||||||
let peer_id = route.get_peer_id_by_ipv4(ipv4).await;
|
route.get_peer_id_by_ipv4(ipv4).await
|
||||||
if peer_id.is_some() {
|
} else {
|
||||||
return peer_id;
|
None
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_peer_id_by_ipv6(&self, ipv6: &Ipv6Addr) -> Option<PeerId> {
|
pub async fn get_peer_id_by_ipv6(&self, ipv6: &Ipv6Addr) -> Option<PeerId> {
|
||||||
for route in self.routes.read().await.iter() {
|
if let Some(route) = self.route.load().as_ref() {
|
||||||
let peer_id = route.get_peer_id_by_ipv6(ipv6).await;
|
route.get_peer_id_by_ipv6(ipv6).await
|
||||||
if peer_id.is_some() {
|
} else {
|
||||||
return peer_id;
|
None
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_route_peer_info(&self, peer_id: PeerId) -> Option<RoutePeerInfo> {
|
pub async fn get_route_peer_info(&self, peer_id: PeerId) -> Option<RoutePeerInfo> {
|
||||||
for route in self.routes.read().await.iter() {
|
if let Some(route) = self.route.load().as_ref() {
|
||||||
if let Some(info) = route.get_peer_info(peer_id).await {
|
route.get_peer_info(peer_id).await
|
||||||
return Some(info);
|
} else {
|
||||||
}
|
None
|
||||||
}
|
}
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_origin_my_peer_id(
|
pub async fn get_origin_my_peer_id(
|
||||||
@@ -232,15 +226,13 @@ impl PeerMap {
|
|||||||
network_name: &str,
|
network_name: &str,
|
||||||
foreign_my_peer_id: PeerId,
|
foreign_my_peer_id: PeerId,
|
||||||
) -> Option<PeerId> {
|
) -> Option<PeerId> {
|
||||||
for route in self.routes.read().await.iter() {
|
if let Some(route) = self.route.load().as_ref() {
|
||||||
let origin_peer_id = route
|
route
|
||||||
.get_origin_my_peer_id(network_name, foreign_my_peer_id)
|
.get_origin_my_peer_id(network_name, foreign_my_peer_id)
|
||||||
.await;
|
.await
|
||||||
if origin_peer_id.is_some() {
|
} else {
|
||||||
return origin_peer_id;
|
None
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
@@ -309,8 +301,7 @@ impl PeerMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add_route(&self, route: ArcRoute) {
|
pub async fn add_route(&self, route: ArcRoute) {
|
||||||
let mut routes = self.routes.write().await;
|
self.route.store(Arc::new(Some(route)));
|
||||||
routes.insert(0, route);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn clean_peer_without_conn(&self) {
|
pub async fn clean_peer_without_conn(&self) {
|
||||||
@@ -330,7 +321,7 @@ impl PeerMap {
|
|||||||
|
|
||||||
pub async fn list_routes(&self) -> DashMap<PeerId, PeerId> {
|
pub async fn list_routes(&self) -> DashMap<PeerId, PeerId> {
|
||||||
let route_map = DashMap::new();
|
let route_map = DashMap::new();
|
||||||
for route in self.routes.read().await.iter() {
|
if let Some(route) = self.route.load().as_ref() {
|
||||||
for item in route.list_routes().await.iter() {
|
for item in route.list_routes().await.iter() {
|
||||||
route_map.insert(item.peer_id, item.next_hop_peer_id);
|
route_map.insert(item.peer_id, item.next_hop_peer_id);
|
||||||
}
|
}
|
||||||
@@ -339,10 +330,11 @@ impl PeerMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn list_route_infos(&self) -> Vec<cli::Route> {
|
pub async fn list_route_infos(&self) -> Vec<cli::Route> {
|
||||||
for route in self.routes.read().await.iter() {
|
if let Some(route) = self.route.load().as_ref() {
|
||||||
return route.list_routes().await;
|
route.list_routes().await
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
}
|
}
|
||||||
vec![]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn need_relay_by_foreign_network(&self, dst_peer_id: PeerId) -> Result<bool, Error> {
|
pub async fn need_relay_by_foreign_network(&self, dst_peer_id: PeerId) -> Result<bool, Error> {
|
||||||
@@ -383,3 +375,42 @@ impl Drop for PeerMap {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::common::global_ctx::tests::get_mock_global_ctx;
|
||||||
|
use tokio::sync::mpsc;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_peer_map_route_arcswap() {
|
||||||
|
let (packet_send, _packet_recv) = mpsc::channel(128);
|
||||||
|
let global_ctx = get_mock_global_ctx();
|
||||||
|
let my_peer_id = 1;
|
||||||
|
|
||||||
|
let peer_map = PeerMap::new(packet_send, global_ctx, my_peer_id);
|
||||||
|
|
||||||
|
// Initially, no route should be set
|
||||||
|
assert!(peer_map.route.load().is_none());
|
||||||
|
|
||||||
|
// Test that methods return None/empty when no route is set
|
||||||
|
assert_eq!(
|
||||||
|
peer_map
|
||||||
|
.get_gateway_peer_id(2, NextHopPolicy::LeastHop)
|
||||||
|
.await,
|
||||||
|
None
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
peer_map
|
||||||
|
.get_peer_id_by_ipv4(&"192.168.1.1".parse().unwrap())
|
||||||
|
.await,
|
||||||
|
None
|
||||||
|
);
|
||||||
|
assert_eq!(peer_map.get_route_peer_info(2).await, None);
|
||||||
|
assert_eq!(peer_map.list_route_infos().await.len(), 0);
|
||||||
|
|
||||||
|
// The route field should be accessible and work with ArcSwap
|
||||||
|
let route_loaded = peer_map.route.load();
|
||||||
|
assert!(route_loaded.is_none());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user