feat: Enable core to use local config files while being managed via the web (#1540)
EasyTier Core / pre_job (push) Has been cancelled
EasyTier GUI / pre_job (push) Has been cancelled
EasyTier Mobile / pre_job (push) Has been cancelled
EasyTier OHOS / cargo_fmt_check (push) Has been cancelled
EasyTier OHOS / pre_job (push) Has been cancelled
EasyTier Test / pre_job (push) Has been cancelled
EasyTier Core / build_web (push) Has been cancelled
EasyTier Core / build (freebsd-13.2-x86_64, 13.2, ubuntu-22.04, x86_64-unknown-freebsd) (push) Has been cancelled
EasyTier Core / build (linux-aarch64, ubuntu-22.04, aarch64-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (linux-arm, ubuntu-22.04, arm-unknown-linux-musleabi) (push) Has been cancelled
EasyTier Core / build (linux-armhf, ubuntu-22.04, arm-unknown-linux-musleabihf) (push) Has been cancelled
EasyTier Core / build (linux-armv7, ubuntu-22.04, armv7-unknown-linux-musleabi) (push) Has been cancelled
EasyTier Core / build (linux-armv7hf, ubuntu-22.04, armv7-unknown-linux-musleabihf) (push) Has been cancelled
EasyTier Core / build (linux-loongarch64, ubuntu-24.04, loongarch64-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (linux-mips, ubuntu-22.04, mips-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (linux-mipsel, ubuntu-22.04, mipsel-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (linux-riscv64, ubuntu-22.04, riscv64gc-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (linux-x86_64, ubuntu-22.04, x86_64-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (macos-aarch64, macos-latest, aarch64-apple-darwin) (push) Has been cancelled
EasyTier Core / build (macos-x86_64, macos-latest, x86_64-apple-darwin) (push) Has been cancelled
EasyTier Core / build (windows-arm64, windows-latest, aarch64-pc-windows-msvc) (push) Has been cancelled
EasyTier Core / build (windows-i686, windows-latest, i686-pc-windows-msvc) (push) Has been cancelled
EasyTier Core / build (windows-x86_64, windows-latest, x86_64-pc-windows-msvc) (push) Has been cancelled
EasyTier Core / core-result (push) Has been cancelled
EasyTier Core / magisk_build (push) Has been cancelled
EasyTier GUI / build-gui (linux-aarch64, aarch64-unknown-linux-gnu, ubuntu-22.04, aarch64-unknown-linux-musl) (push) Has been cancelled
EasyTier GUI / build-gui (linux-x86_64, x86_64-unknown-linux-gnu, ubuntu-22.04, x86_64-unknown-linux-musl) (push) Has been cancelled
EasyTier GUI / build-gui (macos-aarch64, aarch64-apple-darwin, macos-latest, aarch64-apple-darwin) (push) Has been cancelled
EasyTier GUI / build-gui (macos-x86_64, x86_64-apple-darwin, macos-latest, x86_64-apple-darwin) (push) Has been cancelled
EasyTier GUI / build-gui (windows-arm64, aarch64-pc-windows-msvc, windows-latest, aarch64-pc-windows-msvc) (push) Has been cancelled
EasyTier GUI / build-gui (windows-i686, i686-pc-windows-msvc, windows-latest, i686-pc-windows-msvc) (push) Has been cancelled
EasyTier GUI / build-gui (windows-x86_64, x86_64-pc-windows-msvc, windows-latest, x86_64-pc-windows-msvc) (push) Has been cancelled
EasyTier GUI / gui-result (push) Has been cancelled
EasyTier Mobile / build-mobile (android, ubuntu-22.04, android) (push) Has been cancelled
EasyTier Mobile / mobile-result (push) Has been cancelled
EasyTier OHOS / build-ohos (push) Has been cancelled
EasyTier Test / test (push) Has been cancelled

This commit is contained in:
Mg Pig
2025-11-08 20:32:00 +08:00
committed by GitHub
parent b50744690e
commit 1273426009
24 changed files with 800 additions and 228 deletions
+104 -3
View File
@@ -1,9 +1,17 @@
use std::sync::Arc;
use crate::{
common::scoped_task::ScopedTask, instance_manager::NetworkInstanceManager,
tunnel::TunnelConnector,
common::{
config::TomlConfigLoader, global_ctx::GlobalCtx, scoped_task::ScopedTask,
set_default_machine_id, stun::MockStunInfoCollector,
},
connector::create_connector_by_url,
instance_manager::{NetworkInstanceManager, WebClientGuard},
proto::common::NatType,
tunnel::{IpVersion, TunnelConnector},
};
use anyhow::{Context as _, Result};
use url::Url;
pub mod controller;
pub mod session;
@@ -11,6 +19,7 @@ pub mod session;
pub struct WebClient {
controller: Arc<controller::Controller>,
tasks: ScopedTask<()>,
manager_guard: WebClientGuard,
}
impl WebClient {
@@ -20,6 +29,7 @@ impl WebClient {
hostname: H,
manager: Arc<NetworkInstanceManager>,
) -> Self {
let manager_guard = manager.register_web_client();
let controller = Arc::new(controller::Controller::new(
token.to_string(),
hostname.to_string(),
@@ -31,7 +41,11 @@ impl WebClient {
Self::routine(controller_clone, Box::new(connector)).await;
}));
WebClient { controller, tasks }
WebClient {
controller,
tasks,
manager_guard,
}
}
async fn routine(
@@ -58,3 +72,90 @@ impl WebClient {
}
}
}
pub async fn run_web_client(
config_server_url_s: &str,
machine_id: Option<String>,
hostname: Option<String>,
manager: Arc<NetworkInstanceManager>,
) -> Result<WebClient> {
set_default_machine_id(machine_id);
let config_server_url = match Url::parse(config_server_url_s) {
Ok(u) => u,
Err(_) => format!(
"udp://config-server.easytier.cn:22020/{}",
config_server_url_s
)
.parse()
.unwrap(),
};
let mut c_url = config_server_url.clone();
c_url.set_path("");
let token = config_server_url
.path_segments()
.and_then(|mut x| x.next())
.map(|x| percent_encoding::percent_decode_str(x).decode_utf8())
.transpose()
.with_context(|| "failed to decode config server token")?
.map(|x| x.to_string())
.unwrap_or_default();
if token.is_empty() {
return Err(anyhow::anyhow!("empty token"));
}
let config = TomlConfigLoader::default();
let global_ctx = Arc::new(GlobalCtx::new(config));
global_ctx.replace_stun_info_collector(Box::new(MockStunInfoCollector {
udp_nat_type: NatType::Unknown,
}));
let mut flags = global_ctx.get_flags();
flags.bind_device = false;
global_ctx.set_flags(flags);
let hostname = match hostname {
None => gethostname::gethostname().to_string_lossy().to_string(),
Some(hostname) => hostname,
};
Ok(WebClient::new(
create_connector_by_url(c_url.as_str(), &global_ctx, IpVersion::Both).await?,
token.to_string(),
hostname,
manager.clone(),
))
}
#[cfg(test)]
mod tests {
use std::sync::{atomic::AtomicBool, Arc};
use crate::instance_manager::NetworkInstanceManager;
#[tokio::test]
async fn test_manager_wait() {
let manager = Arc::new(NetworkInstanceManager::new());
let client = super::run_web_client(
format!("ring://{}/test", uuid::Uuid::new_v4()).as_str(),
None,
None,
manager.clone(),
)
.await
.unwrap();
let sleep_finish = Arc::new(AtomicBool::new(false));
let sleep_finish_clone = sleep_finish.clone();
tokio::spawn(async move {
tokio::time::sleep(std::time::Duration::from_secs(3)).await;
println!("Dropping client...");
sleep_finish_clone.store(true, std::sync::atomic::Ordering::Relaxed);
drop(client);
println!("Client dropped.");
});
println!("Waiting for manager...");
manager.wait().await;
assert!(sleep_finish.load(std::sync::atomic::Ordering::Relaxed));
println!("Manager stopped.");
}
}