fix(ohos): keep local proxy subnets off tun

Treat locally configured proxy CIDRs as advertisements rather than local VPN routes. Preserve the virtual CIDR, manual routes, and proxy CIDRs learned from remote nodes.
This commit is contained in:
FrankHan committed 2026-09-04 02:34:39 +08:00
1 parent 6e3460db7d
commit 8c64949dde
2 files changed
+82 -11

No files matched your search

@@ -54,17 +54,14 @@ pub(crate) fn get_runtime_config_snapshot(config_id: &str) -> Option<RuntimeConf
.and_then(|guard| guard.get(config_id).cloned())
}
pub(crate) fn get_runtime_config_route_overrides(config_id: &str) -> (Vec<String>, Vec<String>) {
pub(crate) fn get_runtime_config_manual_routes(config_id: &str) -> Vec<String> {
RUNTIME_CONFIG_SNAPSHOTS
.lock()
.ok()
.and_then(|guard| {
guard.get(config_id).map(|snapshot| {
(
snapshot.config.routes.clone(),
snapshot.config.proxy_cidrs.clone(),
)
})
guard
.get(config_id)
.map(|snapshot| snapshot.config.routes.clone())
})
.unwrap_or_default()
}
@@ -1,4 +1,4 @@
use crate::config::repository::get_runtime_config_route_overrides;
use crate::config::repository::get_runtime_config_manual_routes;
use crate::runtime::state::runtime_state::RuntimeInstanceState;
use ipnet::IpNet;
use std::collections::HashSet;
@@ -59,8 +59,7 @@ pub(crate) fn aggregate_tun_routes(instance: &RuntimeInstanceState) -> Vec<Strin
.my_node_info
.as_ref()
.and_then(|info| info.virtual_ipv4_cidr.clone());
let (manual_routes, config_proxy_cidrs) =
get_runtime_config_route_overrides(&instance.config_id);
let manual_routes = get_runtime_config_manual_routes(&instance.config_id);
let runtime_proxy_cidrs = instance
.routes
.iter()
@@ -73,7 +72,9 @@ pub(crate) fn aggregate_tun_routes(instance: &RuntimeInstanceState) -> Vec<Strin
}
raw_routes.extend(manual_routes.iter().cloned());
raw_routes.extend(config_proxy_cidrs.iter().cloned());
// Locally configured proxy CIDRs are advertisements for networks reached
// through this node. Installing them into this node's TUN would recapture
// the proxy's own destination sockets instead of using the physical LAN.
raw_routes.extend(runtime_proxy_cidrs.iter().cloned());
simplify_routes(raw_routes)
}
@@ -90,3 +91,76 @@ pub(crate) fn aggregate_requested_tun_routes(instances: &[RuntimeInstanceState])
}
aggregated_routes
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::repository::{cache_runtime_config_snapshot, clear_runtime_config_snapshot};
use crate::runtime::state::runtime_state::{MyNodeInfo, RouteView};
use easytier::proto::api::manage::NetworkConfig;
fn runtime_instance(config_id: &str) -> RuntimeInstanceState {
RuntimeInstanceState {
config_id: config_id.to_string(),
instance_id: "test-instance".to_string(),
display_name: "test".to_string(),
running: true,
tun_required: true,
tun_attached: false,
magic_dns_enabled: false,
need_exit_node: false,
error_message: None,
my_node_info: Some(MyNodeInfo {
virtual_ipv4: Some("10.144.144.1".to_string()),
virtual_ipv4_cidr: Some("10.144.144.1/24".to_string()),
hostname: None,
version: None,
peer_id: Some(1),
listeners: Vec::new(),
vpn_portal_cfg: None,
udp_nat_type: None,
tcp_nat_type: None,
}),
events: Vec::new(),
routes: vec![RouteView {
peer_id: 2,
hostname: None,
ipv4: Some("10.144.144.2".to_string()),
ipv4_cidr: Some("10.144.144.2/24".to_string()),
ipv6_cidr: None,
proxy_cidrs: vec!["10.20.0.0/16".to_string()],
next_hop_peer_id: Some(2),
cost: Some(1),
path_latency: None,
udp_nat_type: None,
tcp_nat_type: None,
inst_id: None,
version: None,
is_public_server: None,
}],
peers: Vec::new(),
}
}
#[test]
fn local_proxy_cidr_is_not_installed_in_tun_routes() {
let config_id = "routing-test-local-proxy";
cache_runtime_config_snapshot(
config_id.to_string(),
"test".to_string(),
NetworkConfig {
routes: vec!["172.16.0.0/16".to_string()],
proxy_cidrs: vec!["192.168.1.0/24".to_string()],
..Default::default()
},
);
let routes = aggregate_tun_routes(&runtime_instance(config_id));
clear_runtime_config_snapshot(config_id);
assert!(routes.contains(&"10.144.144.0/24".to_string()));
assert!(routes.contains(&"172.16.0.0/16".to_string()));
assert!(routes.contains(&"10.20.0.0/16".to_string()));
assert!(!routes.contains(&"192.168.1.0/24".to_string()));
}
}