mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-09-01 00:39:24 +00:00
fix(shared-tun): close mobile routing gaps
Translate IPv6 traffic across shared mobile members, including transport checksums and reverse-flow handling. Normalize saved Android TUN configs and detach runtimes before the VPN fd closes. Restore the mainline lockfile after resolving the merge.
This commit is contained in:
@@ -73,7 +73,7 @@ static RPC_SERVER: once_cell::sync::Lazy<Mutex<Option<RpcServer>>> =
|
||||
static WEB_CLIENT: once_cell::sync::Lazy<RwLock<Option<WebClient>>> =
|
||||
once_cell::sync::Lazy::new(|| RwLock::new(None));
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
#[cfg(any(target_os = "android", test))]
|
||||
const ANDROID_SHARED_TUN_DEV_NAME: &str = "easytier-shared";
|
||||
|
||||
macro_rules! get_client_manager {
|
||||
@@ -88,15 +88,18 @@ macro_rules! get_client_manager {
|
||||
|
||||
fn normalize_network_config_for_runtime(cfg: &mut NetworkConfig) {
|
||||
#[cfg(target_os = "android")]
|
||||
{
|
||||
if !cfg.no_tun() && cfg.dev_name.as_deref().map(str::is_empty).unwrap_or(true) {
|
||||
cfg.dev_name = Some(ANDROID_SHARED_TUN_DEV_NAME.to_owned());
|
||||
}
|
||||
}
|
||||
normalize_android_network_config(cfg);
|
||||
#[cfg(not(target_os = "android"))]
|
||||
let _ = cfg;
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android", test))]
|
||||
fn normalize_android_network_config(cfg: &mut NetworkConfig) {
|
||||
if !cfg.no_tun() && cfg.dev_name.as_deref().map(str::is_empty).unwrap_or(true) {
|
||||
cfg.dev_name = Some(ANDROID_SHARED_TUN_DEV_NAME.to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn easytier_version() -> Result<String, String> {
|
||||
Ok(easytier::VERSION.to_string())
|
||||
@@ -252,6 +255,31 @@ async fn set_tun_fd(
|
||||
return Err("duplicate instance id in TUN fd attachment group".to_string());
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||
if fd <= 0 {
|
||||
let mut errors = Vec::new();
|
||||
for instance_id in target_ids {
|
||||
if let Err(error) = attach_mobile_tun_fd(
|
||||
instance_manager.as_ref(),
|
||||
instance_id,
|
||||
fd,
|
||||
easytier::instance::virtual_nic::MobileTunSources::default(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
errors.push(format!("{instance_id}: {error}"));
|
||||
}
|
||||
}
|
||||
return if errors.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!(
|
||||
"failed to detach tun fd from the instance group: {}",
|
||||
errors.join("; ")
|
||||
))
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||
let mut source_map = parse_tun_fd_instance_sources(instance_sources.unwrap_or_default())?;
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
@@ -955,9 +983,10 @@ mod manager {
|
||||
&self,
|
||||
app: &AppHandle,
|
||||
inst_id: Uuid,
|
||||
cfg: NetworkConfig,
|
||||
mut cfg: NetworkConfig,
|
||||
source: PersistedConfigSource,
|
||||
) -> anyhow::Result<()> {
|
||||
normalize_network_config_for_runtime(&mut cfg);
|
||||
let source = self
|
||||
.network_configs
|
||||
.get(&inst_id)
|
||||
@@ -1436,8 +1465,33 @@ mod manager {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{PersistedConfigSource, StoredGuiConfig};
|
||||
use crate::{ANDROID_SHARED_TUN_DEV_NAME, normalize_android_network_config};
|
||||
use easytier::proto::api::manage::NetworkConfig;
|
||||
|
||||
#[test]
|
||||
fn android_default_tun_config_uses_shared_device_name() {
|
||||
let mut config = NetworkConfig::default();
|
||||
|
||||
normalize_android_network_config(&mut config);
|
||||
|
||||
assert_eq!(
|
||||
config.dev_name.as_deref(),
|
||||
Some(ANDROID_SHARED_TUN_DEV_NAME)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn android_no_tun_config_keeps_empty_device_name() {
|
||||
let mut config = NetworkConfig {
|
||||
no_tun: Some(true),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
normalize_android_network_config(&mut config);
|
||||
|
||||
assert!(config.dev_name.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stored_gui_config_defaults_missing_source_to_legacy() {
|
||||
let stored: StoredGuiConfig = serde_json::from_value(serde_json::json!({
|
||||
|
||||
Reference in New Issue
Block a user