mirror of
https://github.com/EasyTier/EasyTier.git
synced 2024-11-16 11:42:27 +08:00
add version to rip route, reduce bandwidth (#23)
reduce bandwidth usage on route propagation
This commit is contained in:
parent
c6c505f9d7
commit
7918031d8b
|
@ -463,7 +463,7 @@ impl UdpHolePunchConnector {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
pub mod tests {
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::rpc::{NatType, StunInfo};
|
use crate::rpc::{NatType, StunInfo};
|
||||||
|
@ -499,7 +499,9 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_mock_peer_manager_with_mock_stun(udp_nat_type: NatType) -> Arc<PeerManager> {
|
pub async fn create_mock_peer_manager_with_mock_stun(
|
||||||
|
udp_nat_type: NatType,
|
||||||
|
) -> Arc<PeerManager> {
|
||||||
let p_a = create_mock_peer_manager().await;
|
let p_a = create_mock_peer_manager().await;
|
||||||
let collector = Box::new(MockStunInfoCollector { udp_nat_type });
|
let collector = Box::new(MockStunInfoCollector { udp_nat_type });
|
||||||
p_a.get_global_ctx().replace_stun_info_collector(collector);
|
p_a.get_global_ctx().replace_stun_info_collector(collector);
|
||||||
|
|
|
@ -413,7 +413,7 @@ impl PeerManager {
|
||||||
peer_map.close_peer(&peer_id).await.unwrap();
|
peer_map.close_peer(&peer_id).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
tokio::time::sleep(std::time::Duration::from_secs(10)).await;
|
tokio::time::sleep(std::time::Duration::from_secs(3)).await;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -447,4 +447,8 @@ impl PeerManager {
|
||||||
pub fn get_nic_channel(&self) -> mpsc::Sender<SinkItem> {
|
pub fn get_nic_channel(&self) -> mpsc::Sender<SinkItem> {
|
||||||
self.nic_channel.clone()
|
self.nic_channel.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_basic_route(&self) -> Arc<BasicRoute> {
|
||||||
|
self.basic_route.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
use std::{net::Ipv4Addr, sync::Arc, time::Duration};
|
use std::{
|
||||||
|
net::Ipv4Addr,
|
||||||
|
sync::{atomic::AtomicU32, Arc},
|
||||||
|
time::{Duration, Instant},
|
||||||
|
};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use rkyv::{Archive, Deserialize, Serialize};
|
use rkyv::{Archive, Deserialize, Serialize};
|
||||||
use tokio::{sync::Mutex, task::JoinSet};
|
use tokio::{
|
||||||
|
sync::{Mutex, RwLock},
|
||||||
|
task::JoinSet,
|
||||||
|
};
|
||||||
use tokio_util::bytes::Bytes;
|
use tokio_util::bytes::Bytes;
|
||||||
use tracing::Instrument;
|
use tracing::Instrument;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -25,7 +32,9 @@ use crate::{
|
||||||
|
|
||||||
use super::{packet::ArchivedPacketBody, peer_manager::PeerPacketFilter};
|
use super::{packet::ArchivedPacketBody, peer_manager::PeerPacketFilter};
|
||||||
|
|
||||||
#[derive(Archive, Deserialize, Serialize, Clone, Debug)]
|
type Version = u32;
|
||||||
|
|
||||||
|
#[derive(Archive, Deserialize, Serialize, Clone, Debug, PartialEq)]
|
||||||
#[archive(compare(PartialEq), check_bytes)]
|
#[archive(compare(PartialEq), check_bytes)]
|
||||||
// Derives can be passed through to the generated type:
|
// Derives can be passed through to the generated type:
|
||||||
#[archive_attr(derive(Debug))]
|
#[archive_attr(derive(Debug))]
|
||||||
|
@ -77,6 +86,12 @@ impl SyncPeerInfo {
|
||||||
pub struct SyncPeer {
|
pub struct SyncPeer {
|
||||||
pub myself: SyncPeerInfo,
|
pub myself: SyncPeerInfo,
|
||||||
pub neighbors: Vec<SyncPeerInfo>,
|
pub neighbors: Vec<SyncPeerInfo>,
|
||||||
|
// the route table version of myself
|
||||||
|
pub version: Version,
|
||||||
|
// the route table version of peer that we have received last time
|
||||||
|
pub peer_version: Option<Version>,
|
||||||
|
// if we do not have latest peer version, need_reply is true
|
||||||
|
pub need_reply: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SyncPeer {
|
impl SyncPeer {
|
||||||
|
@ -85,14 +100,21 @@ impl SyncPeer {
|
||||||
_to_peer: UUID,
|
_to_peer: UUID,
|
||||||
neighbors: Vec<SyncPeerInfo>,
|
neighbors: Vec<SyncPeerInfo>,
|
||||||
global_ctx: ArcGlobalCtx,
|
global_ctx: ArcGlobalCtx,
|
||||||
|
version: Version,
|
||||||
|
peer_version: Option<Version>,
|
||||||
|
need_reply: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
SyncPeer {
|
SyncPeer {
|
||||||
myself: SyncPeerInfo::new_self(from_peer, &global_ctx),
|
myself: SyncPeerInfo::new_self(from_peer, &global_ctx),
|
||||||
neighbors,
|
neighbors,
|
||||||
|
version,
|
||||||
|
peer_version,
|
||||||
|
need_reply,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct SyncPeerFromRemote {
|
struct SyncPeerFromRemote {
|
||||||
packet: SyncPeer,
|
packet: SyncPeer,
|
||||||
last_update: std::time::Instant,
|
last_update: std::time::Instant,
|
||||||
|
@ -100,7 +122,7 @@ struct SyncPeerFromRemote {
|
||||||
|
|
||||||
type SyncPeerFromRemoteMap = Arc<DashMap<uuid::Uuid, SyncPeerFromRemote>>;
|
type SyncPeerFromRemoteMap = Arc<DashMap<uuid::Uuid, SyncPeerFromRemote>>;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Debug)]
|
||||||
struct RouteTable {
|
struct RouteTable {
|
||||||
route_info: DashMap<uuid::Uuid, SyncPeerInfo>,
|
route_info: DashMap<uuid::Uuid, SyncPeerInfo>,
|
||||||
ipv4_peer_id_map: DashMap<Ipv4Addr, uuid::Uuid>,
|
ipv4_peer_id_map: DashMap<Ipv4Addr, uuid::Uuid>,
|
||||||
|
@ -137,6 +159,24 @@ impl RouteTable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct RouteVersion(Arc<AtomicU32>);
|
||||||
|
|
||||||
|
impl RouteVersion {
|
||||||
|
fn new() -> Self {
|
||||||
|
// RouteVersion(Arc::new(AtomicU32::new(rand::random())))
|
||||||
|
RouteVersion(Arc::new(AtomicU32::new(0)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get(&self) -> Version {
|
||||||
|
self.0.load(std::sync::atomic::Ordering::Relaxed)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inc(&self) {
|
||||||
|
self.0.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct BasicRoute {
|
pub struct BasicRoute {
|
||||||
my_peer_id: packet::UUID,
|
my_peer_id: packet::UUID,
|
||||||
global_ctx: ArcGlobalCtx,
|
global_ctx: ArcGlobalCtx,
|
||||||
|
@ -149,13 +189,17 @@ pub struct BasicRoute {
|
||||||
tasks: Mutex<JoinSet<()>>,
|
tasks: Mutex<JoinSet<()>>,
|
||||||
|
|
||||||
need_sync_notifier: Arc<tokio::sync::Notify>,
|
need_sync_notifier: Arc<tokio::sync::Notify>,
|
||||||
|
|
||||||
|
version: RouteVersion,
|
||||||
|
myself: Arc<RwLock<SyncPeerInfo>>,
|
||||||
|
last_send_time_map: Arc<DashMap<PeerId, Instant>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BasicRoute {
|
impl BasicRoute {
|
||||||
pub fn new(my_peer_id: Uuid, global_ctx: ArcGlobalCtx) -> Self {
|
pub fn new(my_peer_id: Uuid, global_ctx: ArcGlobalCtx) -> Self {
|
||||||
BasicRoute {
|
BasicRoute {
|
||||||
my_peer_id: my_peer_id.into(),
|
my_peer_id: my_peer_id.into(),
|
||||||
global_ctx,
|
global_ctx: global_ctx.clone(),
|
||||||
interface: Arc::new(Mutex::new(None)),
|
interface: Arc::new(Mutex::new(None)),
|
||||||
|
|
||||||
route_table: Arc::new(RouteTable::new()),
|
route_table: Arc::new(RouteTable::new()),
|
||||||
|
@ -164,6 +208,13 @@ impl BasicRoute {
|
||||||
tasks: Mutex::new(JoinSet::new()),
|
tasks: Mutex::new(JoinSet::new()),
|
||||||
|
|
||||||
need_sync_notifier: Arc::new(tokio::sync::Notify::new()),
|
need_sync_notifier: Arc::new(tokio::sync::Notify::new()),
|
||||||
|
|
||||||
|
version: RouteVersion::new(),
|
||||||
|
myself: Arc::new(RwLock::new(SyncPeerInfo::new_self(
|
||||||
|
my_peer_id.into(),
|
||||||
|
&global_ctx,
|
||||||
|
))),
|
||||||
|
last_send_time_map: Arc::new(DashMap::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,6 +237,16 @@ impl BasicRoute {
|
||||||
route_table.copy_from(&new_route_table);
|
route_table.copy_from(&new_route_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn update_myself(myself: &Arc<RwLock<SyncPeerInfo>>, global_ctx: &ArcGlobalCtx) -> bool {
|
||||||
|
let new_myself = SyncPeerInfo::new_self(global_ctx.get_id().into(), &global_ctx);
|
||||||
|
if *myself.read().await != new_myself {
|
||||||
|
*myself.write().await = new_myself;
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn update_route_table_with_req(
|
fn update_route_table_with_req(
|
||||||
my_id: packet::UUID,
|
my_id: packet::UUID,
|
||||||
packet: &SyncPeer,
|
packet: &SyncPeer,
|
||||||
|
@ -210,7 +271,7 @@ impl BasicRoute {
|
||||||
.value()
|
.value()
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
if ret.cost > 32 {
|
if ret.cost > 6 {
|
||||||
log::error!(
|
log::error!(
|
||||||
"cost too large: {}, may lost connection, remove it",
|
"cost too large: {}, may lost connection, remove it",
|
||||||
ret.cost
|
ret.cost
|
||||||
|
@ -260,6 +321,9 @@ impl BasicRoute {
|
||||||
global_ctx: ArcGlobalCtx,
|
global_ctx: ArcGlobalCtx,
|
||||||
peer_id: PeerId,
|
peer_id: PeerId,
|
||||||
route_table: Arc<RouteTable>,
|
route_table: Arc<RouteTable>,
|
||||||
|
my_version: Version,
|
||||||
|
peer_version: Option<Version>,
|
||||||
|
need_reply: bool,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let mut route_info_copy: Vec<SyncPeerInfo> = Vec::new();
|
let mut route_info_copy: Vec<SyncPeerInfo> = Vec::new();
|
||||||
// copy the route info
|
// copy the route info
|
||||||
|
@ -267,7 +331,15 @@ impl BasicRoute {
|
||||||
let (k, v) = item.pair();
|
let (k, v) = item.pair();
|
||||||
route_info_copy.push(v.clone().clone_for_route_table(&(*k).into(), v.cost, &v));
|
route_info_copy.push(v.clone().clone_for_route_table(&(*k).into(), v.cost, &v));
|
||||||
}
|
}
|
||||||
let msg = SyncPeer::new(my_peer_id, peer_id.into(), route_info_copy, global_ctx);
|
let msg = SyncPeer::new(
|
||||||
|
my_peer_id,
|
||||||
|
peer_id.into(),
|
||||||
|
route_info_copy,
|
||||||
|
global_ctx,
|
||||||
|
my_version,
|
||||||
|
peer_version,
|
||||||
|
need_reply,
|
||||||
|
);
|
||||||
// TODO: this may exceed the MTU of the tunnel
|
// TODO: this may exceed the MTU of the tunnel
|
||||||
interface
|
interface
|
||||||
.send_route_packet(encode_to_bytes::<_, 4096>(&msg), 1, &peer_id)
|
.send_route_packet(encode_to_bytes::<_, 4096>(&msg), 1, &peer_id)
|
||||||
|
@ -280,19 +352,54 @@ impl BasicRoute {
|
||||||
let my_peer_id = self.my_peer_id.clone();
|
let my_peer_id = self.my_peer_id.clone();
|
||||||
let interface = self.interface.clone();
|
let interface = self.interface.clone();
|
||||||
let notifier = self.need_sync_notifier.clone();
|
let notifier = self.need_sync_notifier.clone();
|
||||||
|
let sync_peer_from_remote = self.sync_peer_from_remote.clone();
|
||||||
|
let myself = self.myself.clone();
|
||||||
|
let version = self.version.clone();
|
||||||
|
let last_send_time_map = self.last_send_time_map.clone();
|
||||||
self.tasks.lock().await.spawn(
|
self.tasks.lock().await.spawn(
|
||||||
async move {
|
async move {
|
||||||
loop {
|
loop {
|
||||||
|
if Self::update_myself(&myself, &global_ctx).await {
|
||||||
|
version.inc();
|
||||||
|
tracing::info!(
|
||||||
|
my_id = ?my_peer_id,
|
||||||
|
version = version.get(),
|
||||||
|
"update route table version when myself changed"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let lockd_interface = interface.lock().await;
|
let lockd_interface = interface.lock().await;
|
||||||
let interface = lockd_interface.as_ref().unwrap();
|
let interface = lockd_interface.as_ref().unwrap();
|
||||||
|
let last_send_time_map_new = DashMap::new();
|
||||||
let peers = interface.list_peers().await;
|
let peers = interface.list_peers().await;
|
||||||
for peer in peers.iter() {
|
for peer in peers.iter() {
|
||||||
|
let last_send_time = last_send_time_map.get(peer).map(|v| *v).unwrap_or(Instant::now() - Duration::from_secs(3600));
|
||||||
|
let my_version_peer_saved = sync_peer_from_remote.get(&peer).and_then(|v| v.packet.peer_version);
|
||||||
|
let peer_have_latest_version = my_version_peer_saved == Some(version.get());
|
||||||
|
if peer_have_latest_version && last_send_time.elapsed().as_secs() < 60 {
|
||||||
|
last_send_time_map_new.insert(*peer, last_send_time);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracing::info!(
|
||||||
|
my_id = ?my_peer_id,
|
||||||
|
dst_peer_id = ?peer,
|
||||||
|
version = version.get(),
|
||||||
|
?my_version_peer_saved,
|
||||||
|
last_send_elapse = ?last_send_time.elapsed().as_secs(),
|
||||||
|
"need send route info"
|
||||||
|
);
|
||||||
|
last_send_time_map_new.insert(*peer, Instant::now());
|
||||||
|
let peer_version_we_saved = sync_peer_from_remote.get(&peer).and_then(|v| Some(v.packet.version));
|
||||||
let ret = Self::send_sync_peer_request(
|
let ret = Self::send_sync_peer_request(
|
||||||
interface,
|
interface,
|
||||||
my_peer_id.clone(),
|
my_peer_id.clone(),
|
||||||
global_ctx.clone(),
|
global_ctx.clone(),
|
||||||
*peer,
|
*peer,
|
||||||
route_table.clone(),
|
route_table.clone(),
|
||||||
|
version.get(),
|
||||||
|
peer_version_we_saved,
|
||||||
|
!peer_have_latest_version,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
@ -312,6 +419,13 @@ impl BasicRoute {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
last_send_time_map.clear();
|
||||||
|
for item in last_send_time_map_new.iter() {
|
||||||
|
let (k, v) = item.pair();
|
||||||
|
last_send_time_map.insert(*k, *v);
|
||||||
|
}
|
||||||
|
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = notifier.notified() => {
|
_ = notifier.notified() => {
|
||||||
log::trace!("sync peer request triggered by notifier");
|
log::trace!("sync peer request triggered by notifier");
|
||||||
|
@ -333,14 +447,19 @@ impl BasicRoute {
|
||||||
let my_peer_id = self.my_peer_id.clone();
|
let my_peer_id = self.my_peer_id.clone();
|
||||||
let sync_peer_from_remote = self.sync_peer_from_remote.clone();
|
let sync_peer_from_remote = self.sync_peer_from_remote.clone();
|
||||||
let notifier = self.need_sync_notifier.clone();
|
let notifier = self.need_sync_notifier.clone();
|
||||||
|
let interface = self.interface.clone();
|
||||||
|
let version = self.version.clone();
|
||||||
self.tasks.lock().await.spawn(async move {
|
self.tasks.lock().await.spawn(async move {
|
||||||
loop {
|
loop {
|
||||||
let mut need_update_route = false;
|
let mut need_update_route = false;
|
||||||
let now = std::time::Instant::now();
|
let now = std::time::Instant::now();
|
||||||
let mut need_remove = Vec::new();
|
let mut need_remove = Vec::new();
|
||||||
|
let connected_peers = interface.lock().await.as_ref().unwrap().list_peers().await;
|
||||||
for item in sync_peer_from_remote.iter() {
|
for item in sync_peer_from_remote.iter() {
|
||||||
let (k, v) = item.pair();
|
let (k, v) = item.pair();
|
||||||
if now.duration_since(v.last_update).as_secs() > 5 {
|
if now.duration_since(v.last_update).as_secs() > 70
|
||||||
|
|| !connected_peers.contains(k)
|
||||||
|
{
|
||||||
need_update_route = true;
|
need_update_route = true;
|
||||||
need_remove.insert(0, k.clone());
|
need_remove.insert(0, k.clone());
|
||||||
}
|
}
|
||||||
|
@ -357,6 +476,12 @@ impl BasicRoute {
|
||||||
sync_peer_from_remote.clone(),
|
sync_peer_from_remote.clone(),
|
||||||
route_table.clone(),
|
route_table.clone(),
|
||||||
);
|
);
|
||||||
|
version.inc();
|
||||||
|
tracing::info!(
|
||||||
|
my_id = ?my_peer_id,
|
||||||
|
version = version.get(),
|
||||||
|
"update route table when check expired peer"
|
||||||
|
);
|
||||||
notifier.notify_one();
|
notifier.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,11 +510,13 @@ impl BasicRoute {
|
||||||
self.sync_peer_from_remote
|
self.sync_peer_from_remote
|
||||||
.entry(packet.myself.peer_id.to_uuid())
|
.entry(packet.myself.peer_id.to_uuid())
|
||||||
.and_modify(|v| {
|
.and_modify(|v| {
|
||||||
if v.packet == *packet {
|
if v.packet.myself == p.myself && v.packet.neighbors == p.neighbors {
|
||||||
updated = false;
|
updated = false;
|
||||||
} else {
|
} else {
|
||||||
v.packet = p.clone();
|
v.packet = p.clone();
|
||||||
}
|
}
|
||||||
|
v.packet.version = p.version;
|
||||||
|
v.packet.peer_version = p.peer_version;
|
||||||
v.last_update = std::time::Instant::now();
|
v.last_update = std::time::Instant::now();
|
||||||
})
|
})
|
||||||
.or_insert(SyncPeerFromRemote {
|
.or_insert(SyncPeerFromRemote {
|
||||||
|
@ -403,6 +530,21 @@ impl BasicRoute {
|
||||||
self.sync_peer_from_remote.clone(),
|
self.sync_peer_from_remote.clone(),
|
||||||
self.route_table.clone(),
|
self.route_table.clone(),
|
||||||
);
|
);
|
||||||
|
self.version.inc();
|
||||||
|
tracing::info!(
|
||||||
|
my_id = ?self.my_peer_id,
|
||||||
|
?p,
|
||||||
|
version = self.version.get(),
|
||||||
|
"update route table when receive route packet"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if packet.need_reply {
|
||||||
|
self.last_send_time_map
|
||||||
|
.remove(&packet.myself.peer_id.to_uuid());
|
||||||
|
}
|
||||||
|
|
||||||
|
if updated || packet.need_reply {
|
||||||
self.need_sync_notifier.notify_one();
|
self.need_sync_notifier.notify_one();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -502,3 +644,111 @@ impl PeerPacketFilter for BasicRoute {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
connector::udp_hole_punch::tests::create_mock_peer_manager_with_mock_stun,
|
||||||
|
peers::{
|
||||||
|
peer_manager::PeerManager,
|
||||||
|
peer_rip_route::Version,
|
||||||
|
tests::{connect_peer_manager, wait_route_appear},
|
||||||
|
PeerId,
|
||||||
|
},
|
||||||
|
rpc::NatType,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_rip_route() {
|
||||||
|
let peer_mgr_a = create_mock_peer_manager_with_mock_stun(NatType::Unknown).await;
|
||||||
|
let peer_mgr_b = create_mock_peer_manager_with_mock_stun(NatType::Unknown).await;
|
||||||
|
let peer_mgr_c = create_mock_peer_manager_with_mock_stun(NatType::Unknown).await;
|
||||||
|
connect_peer_manager(peer_mgr_a.clone(), peer_mgr_b.clone()).await;
|
||||||
|
connect_peer_manager(peer_mgr_b.clone(), peer_mgr_c.clone()).await;
|
||||||
|
wait_route_appear(peer_mgr_a.clone(), peer_mgr_b.my_node_id())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
wait_route_appear(peer_mgr_a.clone(), peer_mgr_c.my_node_id())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mgrs = vec![peer_mgr_a.clone(), peer_mgr_b.clone(), peer_mgr_c.clone()];
|
||||||
|
|
||||||
|
tokio::time::sleep(tokio::time::Duration::from_secs(4)).await;
|
||||||
|
|
||||||
|
let check_version = |version: Version, uuid: PeerId, mgrs: &Vec<Arc<PeerManager>>| {
|
||||||
|
for mgr in mgrs.iter() {
|
||||||
|
tracing::warn!(
|
||||||
|
"check version: {:?}, {:?}, {:?}, {:?}",
|
||||||
|
version,
|
||||||
|
uuid,
|
||||||
|
mgr,
|
||||||
|
mgr.get_basic_route().sync_peer_from_remote
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
version,
|
||||||
|
mgr.get_basic_route()
|
||||||
|
.sync_peer_from_remote
|
||||||
|
.get(&uuid)
|
||||||
|
.unwrap()
|
||||||
|
.packet
|
||||||
|
.version,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
mgr.get_basic_route()
|
||||||
|
.sync_peer_from_remote
|
||||||
|
.get(&uuid)
|
||||||
|
.unwrap()
|
||||||
|
.packet
|
||||||
|
.peer_version
|
||||||
|
.unwrap(),
|
||||||
|
mgr.get_basic_route().version.get()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let check_sanity = || {
|
||||||
|
// check peer version in other peer mgr are correct.
|
||||||
|
check_version(
|
||||||
|
peer_mgr_b.get_basic_route().version.get(),
|
||||||
|
peer_mgr_b.my_node_id(),
|
||||||
|
&vec![peer_mgr_a.clone(), peer_mgr_c.clone()],
|
||||||
|
);
|
||||||
|
|
||||||
|
check_version(
|
||||||
|
peer_mgr_a.get_basic_route().version.get(),
|
||||||
|
peer_mgr_a.my_node_id(),
|
||||||
|
&vec![peer_mgr_b.clone()],
|
||||||
|
);
|
||||||
|
|
||||||
|
check_version(
|
||||||
|
peer_mgr_c.get_basic_route().version.get(),
|
||||||
|
peer_mgr_c.my_node_id(),
|
||||||
|
&vec![peer_mgr_b.clone()],
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
check_sanity();
|
||||||
|
|
||||||
|
let versions = mgrs
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.get_basic_route().version.get())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
|
||||||
|
|
||||||
|
let versions2 = mgrs
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.get_basic_route().version.get())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
assert_eq!(versions, versions2);
|
||||||
|
check_sanity();
|
||||||
|
|
||||||
|
assert!(peer_mgr_a.get_basic_route().version.get() <= 3);
|
||||||
|
assert!(peer_mgr_b.get_basic_route().version.get() <= 6);
|
||||||
|
assert!(peer_mgr_c.get_basic_route().version.get() <= 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -616,7 +616,7 @@ mod tests {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn udp_multiple_conns() {
|
async fn udp_multiple_conns() {
|
||||||
let mut listener = UdpTunnelListener::new("udp://0.0.0.0:5556".parse().unwrap());
|
let mut listener = UdpTunnelListener::new("udp://0.0.0.0:5557".parse().unwrap());
|
||||||
listener.listen().await.unwrap();
|
listener.listen().await.unwrap();
|
||||||
|
|
||||||
let _lis = tokio::spawn(async move {
|
let _lis = tokio::spawn(async move {
|
||||||
|
@ -630,8 +630,8 @@ mod tests {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut connector1 = UdpTunnelConnector::new("udp://127.0.0.1:5556".parse().unwrap());
|
let mut connector1 = UdpTunnelConnector::new("udp://127.0.0.1:5557".parse().unwrap());
|
||||||
let mut connector2 = UdpTunnelConnector::new("udp://127.0.0.1:5556".parse().unwrap());
|
let mut connector2 = UdpTunnelConnector::new("udp://127.0.0.1:5557".parse().unwrap());
|
||||||
|
|
||||||
let t1 = connector1.connect().await.unwrap();
|
let t1 = connector1.connect().await.unwrap();
|
||||||
let t2 = connector2.connect().await.unwrap();
|
let t2 = connector2.connect().await.unwrap();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user