From e088d305b1246086c3c16d54edf764effc68db6d Mon Sep 17 00:00:00 2001 From: lbl <1791778603@qq.com> Date: Sun, 1 Mar 2026 10:41:35 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E8=BF=87=E6=9C=9F=E7=BB=9F?= =?UTF-8?q?=E8=AE=A1=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vnt-core/src/context/mod.rs | 12 ++++++++++ vnt-core/src/tunnel_core/p2p/route_table.rs | 24 ++++++++++--------- .../src/tunnel_core/p2p/transport/task.rs | 15 +++++++++--- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/vnt-core/src/context/mod.rs b/vnt-core/src/context/mod.rs index 3f2cf3d..8c2dc8b 100644 --- a/vnt-core/src/context/mod.rs +++ b/vnt-core/src/context/mod.rs @@ -259,6 +259,18 @@ impl PacketLossStats { } } + pub fn remove(&self, ip: &Ipv4Addr, route_key: &RouteKey) { + let mut write = self.inner.write(); + write.remove(&(*ip, *route_key)); + } + + pub fn remove_batch(&self, keys: &[(Ipv4Addr, RouteKey)]) { + let mut write = self.inner.write(); + for key in keys { + write.remove(key); + } + } + pub fn reset_all(&self) { let read = self.inner.read(); for stats in read.values() { diff --git a/vnt-core/src/tunnel_core/p2p/route_table.rs b/vnt-core/src/tunnel_core/p2p/route_table.rs index 71f1ae8..ece99cc 100644 --- a/vnt-core/src/tunnel_core/p2p/route_table.rs +++ b/vnt-core/src/tunnel_core/p2p/route_table.rs @@ -207,8 +207,8 @@ impl RouteTable { } /// 移除过期的路由 - pub fn remove_oldest_route(&self, expired_time: Instant) { - self.inner.remove_oldest_route(expired_time); + pub fn remove_oldest_route(&self, expired_time: Instant) -> Vec<(Ipv4Addr, RouteKey)> { + self.inner.remove_oldest_route(expired_time) } } @@ -280,7 +280,7 @@ impl RouteTableInner { list.insert(pos, route); } - fn remove_oldest_route(&self, expired_time: Instant) { + fn remove_oldest_route(&self, expired_time: Instant) -> Vec<(Ipv4Addr, RouteKey)> { let mut expired_keys = Vec::new(); { let mut time_map = self.route_key_time.lock(); @@ -295,25 +295,27 @@ impl RouteTableInner { } if expired_keys.is_empty() { - return; + return expired_keys; } let mut table = self.route_table.write(); let mut owner_map = self.route_key_owner.lock(); - for (id, route_key) in expired_keys { - if let Some(list) = table.get_mut(&id) { - list.retain(|r| r.route_key() != route_key); + for (id, route_key) in &expired_keys { + if let Some(list) = table.get_mut(id) { + list.retain(|r| r.route_key() != *route_key); if list.is_empty() { - table.remove(&id); + table.remove(id); } } - if let Some(owner_id) = owner_map.get(&route_key) { - if *owner_id == id { - owner_map.remove(&route_key); + if let Some(owner_id) = owner_map.get(route_key) { + if *owner_id == *id { + owner_map.remove(route_key); } } } + + expired_keys } } diff --git a/vnt-core/src/tunnel_core/p2p/transport/task.rs b/vnt-core/src/tunnel_core/p2p/transport/task.rs index d0d1eb8..d487567 100644 --- a/vnt-core/src/tunnel_core/p2p/transport/task.rs +++ b/vnt-core/src/tunnel_core/p2p/transport/task.rs @@ -56,7 +56,10 @@ pub async fn init_tunnel( )); task_group.spawn(query_tcp_public_addr_loop(app_state.clone(), manager)); - task_group.spawn(route_timeout_task(route_table.clone())); + task_group.spawn(route_timeout_task( + route_table.clone(), + app_state.packet_loss_stats.clone(), + )); let app_state_for_punch = app_state.clone(); let punch_ctx = PunchTaskContext { network: app_state.network.clone(), @@ -142,11 +145,17 @@ pub async fn ping_all( } } } -pub async fn route_timeout_task(route_table: RouteTable) { +pub async fn route_timeout_task( + route_table: RouteTable, + packet_loss_stats: PacketLossStats, +) { loop { tokio::time::sleep(Duration::from_secs(10)).await; let expired_time = std::time::Instant::now() - Duration::from_secs(10); - route_table.remove_oldest_route(expired_time); + let removed_keys = route_table.remove_oldest_route(expired_time); + if !removed_keys.is_empty() { + packet_loss_stats.remove_batch(&removed_keys); + } } }