mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-15 18:35:47 +00:00
513695297c
* [OHOS.with ai] 将配置管理/配置分享/路由聚合/实例状态解析下沉至 Rust 内核,收敛职责并提升性能 (#2209) * feat: add ohrs config store and startup error logging * feat: full ability core for ohos * feat: full ability core for ohos * feat: clean code --------- Co-authored-by: FrankHan <frankhan@FrankHans-Mac-mini.local> * fix: 添加缺失文件 * fix: 修复更新路由启动两次TUN问题,并调整日志 * fix: rustfmt * fix: 适配Cidr忽略/32格式路由 * fix: 修复Option适配错误 * fix: rustfmt * fix: rustfmt --------- Co-authored-by: FrankHan <frankhan@FrankHans-Mac-mini.local>
106 lines
3.4 KiB
Rust
106 lines
3.4 KiB
Rust
use crate::config::repository::load_config_json;
|
|
use crate::runtime::state::runtime_state::RuntimeInstanceState;
|
|
use easytier::proto::api::manage::NetworkConfig;
|
|
use ipnet::IpNet;
|
|
use ohos_hilog_binding::hilog_debug;
|
|
use std::collections::HashSet;
|
|
use std::net::IpAddr;
|
|
|
|
pub(crate) fn load_manual_routes(config_id: &str) -> Vec<String> {
|
|
load_config_json(config_id)
|
|
.and_then(|raw| serde_json::from_str::<NetworkConfig>(&raw).ok())
|
|
.map(|config| config.routes)
|
|
.unwrap_or_default()
|
|
}
|
|
|
|
fn normalize_route_cidr(route: &str) -> Option<String> {
|
|
route
|
|
.parse::<IpNet>()
|
|
.ok()
|
|
.map(|network| match network {
|
|
IpNet::V4(net) => net.trunc().to_string(),
|
|
IpNet::V6(net) => net.trunc().to_string(),
|
|
})
|
|
.or_else(|| {
|
|
route.parse::<IpAddr>().ok().map(|addr| match addr {
|
|
IpAddr::V4(ip) => format!("{}/32", ip),
|
|
IpAddr::V6(ip) => format!("{}/128", ip),
|
|
})
|
|
})
|
|
}
|
|
|
|
fn simplify_routes(routes: Vec<String>) -> Vec<String> {
|
|
let mut parsed = routes
|
|
.into_iter()
|
|
.filter_map(|route| normalize_route_cidr(&route))
|
|
.filter_map(|route| route.parse::<IpNet>().ok())
|
|
.collect::<Vec<_>>();
|
|
parsed.sort_by(|left, right| {
|
|
left.prefix_len()
|
|
.cmp(&right.prefix_len())
|
|
.then_with(|| left.network().to_string().cmp(&right.network().to_string()))
|
|
});
|
|
|
|
let mut simplified = Vec::<IpNet>::new();
|
|
'outer: for route in parsed {
|
|
for existing in &simplified {
|
|
if existing.contains(&route.network()) && existing.prefix_len() <= route.prefix_len() {
|
|
continue 'outer;
|
|
}
|
|
}
|
|
simplified.retain(|existing| {
|
|
!(route.contains(&existing.network()) && route.prefix_len() <= existing.prefix_len())
|
|
});
|
|
simplified.push(route);
|
|
}
|
|
|
|
let mut seen = HashSet::new();
|
|
simplified
|
|
.into_iter()
|
|
.map(|route| route.to_string())
|
|
.filter(|route| seen.insert(route.clone()))
|
|
.collect()
|
|
}
|
|
|
|
pub(crate) fn aggregate_tun_routes(instance: &RuntimeInstanceState) -> Vec<String> {
|
|
let virtual_ipv4_cidr = instance
|
|
.my_node_info
|
|
.as_ref()
|
|
.and_then(|info| info.virtual_ipv4_cidr.clone());
|
|
let manual_routes = load_manual_routes(&instance.config_id);
|
|
let proxy_cidrs = instance
|
|
.routes
|
|
.iter()
|
|
.flat_map(|route| route.proxy_cidrs.iter().cloned())
|
|
.collect::<Vec<_>>();
|
|
let mut raw_routes = Vec::new();
|
|
|
|
if let Some(cidr) = virtual_ipv4_cidr.clone() {
|
|
raw_routes.push(cidr);
|
|
}
|
|
|
|
raw_routes.extend(manual_routes.iter().cloned());
|
|
raw_routes.extend(proxy_cidrs.iter().cloned());
|
|
let aggregated_routes = simplify_routes(raw_routes);
|
|
hilog_debug!(
|
|
"[Rust] aggregate_tun_routes instance={} proxy_cidrs={:?} aggregated_routes={:?}",
|
|
instance.instance_id,
|
|
proxy_cidrs,
|
|
aggregated_routes
|
|
);
|
|
aggregated_routes
|
|
}
|
|
|
|
pub(crate) fn aggregate_requested_tun_routes(instances: &[RuntimeInstanceState]) -> Vec<String> {
|
|
let mut aggregated_routes = Vec::new();
|
|
let mut seen_routes = HashSet::new();
|
|
for instance in instances.iter().filter(|instance| instance.tun_required) {
|
|
for route in aggregate_tun_routes(instance) {
|
|
if seen_routes.insert(route.clone()) {
|
|
aggregated_routes.push(route);
|
|
}
|
|
}
|
|
}
|
|
aggregated_routes
|
|
}
|