fix: filter overlapped proxy cidrs in ProxyCidrsMonitor (#2079)

* feat(route): add async methods to list proxy CIDRs for IPv4 and IPv6
* refactor(ProxyCidrsMonitor): get proxy cidrs from list_proxy_cidrs
This commit is contained in:
Luna Yao
2026-04-12 16:18:54 +02:00
committed by GitHub
parent 6f3e708679
commit ec7ddd3bad
4 changed files with 66 additions and 30 deletions
+9 -17
View File
@@ -32,35 +32,27 @@ impl ProxyCidrsMonitor {
Vec<cidr::Ipv4Cidr>, Vec<cidr::Ipv4Cidr>,
Vec<cidr::Ipv4Cidr>, Vec<cidr::Ipv4Cidr>,
) { ) {
let proxy_cidrs = if let Some(routes) = global_ctx.config.get_routes() {
// If manual routes exist, override entire proxy_cidrs
routes.into_iter().collect()
} else {
// Collect proxy_cidrs from routes // Collect proxy_cidrs from routes
let mut proxy_cidrs = BTreeSet::new(); let mut proxy_cidrs = peer_mgr.list_proxy_cidrs().await;
let routes = peer_mgr.list_routes().await;
for r in routes {
for cidr in r.proxy_cidrs {
let Ok(cidr) = cidr.parse::<cidr::Ipv4Cidr>() else {
continue;
};
proxy_cidrs.insert(cidr);
}
}
// Add VPN portal cidr to proxy_cidrs // Add VPN portal cidr to proxy_cidrs
if let Some(vpn_cfg) = global_ctx.config.get_vpn_portal_config() { if let Some(vpn_cfg) = global_ctx.config.get_vpn_portal_config() {
proxy_cidrs.insert(vpn_cfg.client_cidr); proxy_cidrs.insert(vpn_cfg.client_cidr);
} }
// If has manual routes, override entire proxy_cidrs proxy_cidrs
if let Some(routes) = global_ctx.config.get_routes() { };
proxy_cidrs = routes.into_iter().collect();
}
// Calculate diff // Calculate diff
if cur_proxy_cidrs == &proxy_cidrs { if cur_proxy_cidrs == &proxy_cidrs {
return (proxy_cidrs, Vec::new(), Vec::new()); return (proxy_cidrs, Vec::new(), Vec::new());
} }
let added: Vec<cidr::Ipv4Cidr> = proxy_cidrs.difference(cur_proxy_cidrs).cloned().collect(); let added = proxy_cidrs.difference(cur_proxy_cidrs).cloned().collect();
let removed: Vec<cidr::Ipv4Cidr> = let removed = cur_proxy_cidrs.difference(&proxy_cidrs).cloned().collect();
cur_proxy_cidrs.difference(&proxy_cidrs).cloned().collect();
(proxy_cidrs, added, removed) (proxy_cidrs, added, removed)
} }
+13 -6
View File
@@ -1,3 +1,8 @@
use anyhow::Context;
use async_trait::async_trait;
use cidr::{Ipv4Cidr, Ipv6Cidr};
use dashmap::DashMap;
use std::collections::BTreeSet;
use std::{ use std::{
fmt::Debug, fmt::Debug,
net::{IpAddr, Ipv4Addr, Ipv6Addr}, net::{IpAddr, Ipv4Addr, Ipv6Addr},
@@ -5,11 +10,6 @@ use std::{
time::{Duration, Instant, SystemTime}, time::{Duration, Instant, SystemTime},
}; };
use anyhow::Context;
use async_trait::async_trait;
use dashmap::DashMap;
use tokio::{ use tokio::{
sync::{ sync::{
Mutex, RwLock, Mutex, RwLock,
@@ -1254,6 +1254,14 @@ impl PeerManager {
self.get_route().get_peer_info_last_update_time().await self.get_route().get_peer_info_last_update_time().await
} }
pub async fn list_proxy_cidrs(&self) -> BTreeSet<Ipv4Cidr> {
self.get_route().list_proxy_cidrs().await
}
pub async fn list_proxy_cidrs_v6(&self) -> BTreeSet<Ipv6Cidr> {
self.get_route().list_proxy_cidrs_v6().await
}
pub async fn dump_route(&self) -> String { pub async fn dump_route(&self) -> String {
self.get_route().dump().await self.get_route().dump().await
} }
@@ -1985,7 +1993,6 @@ impl PeerManager {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::{ use std::{
fmt::Debug, fmt::Debug,
sync::Arc, sync::Arc,
+20
View File
@@ -3500,6 +3500,26 @@ impl Route for PeerRoute {
routes routes
} }
async fn list_proxy_cidrs(&self) -> BTreeSet<Ipv4Cidr> {
self.service_impl
.route_table
.cidr_peer_id_map
.load()
.iter()
.map(|(cidr, _)| *cidr)
.collect()
}
async fn list_proxy_cidrs_v6(&self) -> BTreeSet<Ipv6Cidr> {
self.service_impl
.route_table
.cidr_v6_peer_id_map
.load()
.iter()
.map(|(cidr, _)| *cidr)
.collect()
}
async fn get_peer_id_by_ipv4(&self, ipv4_addr: &Ipv4Addr) -> Option<PeerId> { async fn get_peer_id_by_ipv4(&self, ipv4_addr: &Ipv4Addr) -> Option<PeerId> {
let route_table = &self.service_impl.route_table; let route_table = &self.service_impl.route_table;
if let Some(p) = route_table.ipv4_peer_id_map.get(ipv4_addr) { if let Some(p) = route_table.ipv4_peer_id_map.get(ipv4_addr) {
+19 -2
View File
@@ -1,10 +1,11 @@
use cidr::{Ipv4Cidr, Ipv6Cidr};
use dashmap::DashMap;
use std::{ use std::{
collections::BTreeSet,
net::{Ipv4Addr, Ipv6Addr}, net::{Ipv4Addr, Ipv6Addr},
sync::Arc, sync::Arc,
}; };
use dashmap::DashMap;
use crate::{ use crate::{
common::{PeerId, global_ctx::NetworkIdentity}, common::{PeerId, global_ctx::NetworkIdentity},
proto::peer_rpc::{ proto::peer_rpc::{
@@ -86,6 +87,12 @@ pub trait Route {
async fn list_routes(&self) -> Vec<crate::proto::api::instance::Route>; async fn list_routes(&self) -> Vec<crate::proto::api::instance::Route>;
// TODO: rewrite route management, remove this
async fn list_proxy_cidrs(&self) -> BTreeSet<Ipv4Cidr>;
// TODO: rewrite route management, remove this
async fn list_proxy_cidrs_v6(&self) -> BTreeSet<Ipv6Cidr>;
async fn get_peer_id_by_ipv4(&self, _ipv4: &Ipv4Addr) -> Option<PeerId> { async fn get_peer_id_by_ipv4(&self, _ipv4: &Ipv4Addr) -> Option<PeerId> {
None None
} }
@@ -175,6 +182,16 @@ impl Route for MockRoute {
panic!("mock route") panic!("mock route")
} }
// TODO: rewrite route management, remove this
async fn list_proxy_cidrs(&self) -> BTreeSet<Ipv4Cidr> {
unimplemented!()
}
// TODO: rewrite route management, remove this
async fn list_proxy_cidrs_v6(&self) -> BTreeSet<Ipv6Cidr> {
unimplemented!()
}
async fn get_peer_info(&self, _peer_id: PeerId) -> Option<RoutePeerInfo> { async fn get_peer_info(&self, _peer_id: PeerId) -> Option<RoutePeerInfo> {
panic!("mock route") panic!("mock route")
} }