fix: rustfmt

This commit is contained in:
FrankHan
2026-05-08 16:35:08 +08:00
parent f030e3ab36
commit bf427a5d6f
13 changed files with 264 additions and 103 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
pub(crate) mod services;
pub(crate) mod repository; pub(crate) mod repository;
pub(crate) mod services;
pub(crate) mod storage; pub(crate) mod storage;
pub(crate) mod types; pub(crate) mod types;
@@ -82,7 +82,9 @@ fn field_default_value_text(field: &FieldDescriptor) -> Option<String> {
| Kind::Fixed64 | Kind::Fixed64
| Kind::Float | Kind::Float
| Kind::Double => Some("0".to_string()), | Kind::Double => Some("0".to_string()),
Kind::Enum(enum_desc) => enum_desc.get_value(0).map(|value| value.number().to_string()), Kind::Enum(enum_desc) => enum_desc
.get_value(0)
.map(|value| value.number().to_string()),
Kind::Message(_) => None, Kind::Message(_) => None,
} }
} }
@@ -126,7 +128,10 @@ fn enum_options(kind: Kind) -> Vec<FieldOption> {
fn should_expose_field(field: &FieldDescriptor) -> bool { fn should_expose_field(field: &FieldDescriptor) -> bool {
match field.containing_oneof() { match field.containing_oneof() {
Some(_) => field.field_descriptor_proto().proto3_optional.unwrap_or(false), Some(_) => field
.field_descriptor_proto()
.proto3_optional
.unwrap_or(false),
None => true, None => true,
} }
} }
@@ -216,7 +221,10 @@ fn build_map_entry_node(message_desc: &MessageDescriptor) -> NetworkConfigSchema
None, None,
Vec::new(), Vec::new(),
Vec::new(), Vec::new(),
vec![build_schema_field_node(&key_field), build_schema_field_node(&value_field)], vec![
build_schema_field_node(&key_field),
build_schema_field_node(&value_field),
],
Vec::new(), Vec::new(),
) )
} }
@@ -355,7 +363,10 @@ mod tests {
let schema = get_network_config_schema(); let schema = get_network_config_schema();
assert_eq!(schema.node_kind, "schema"); assert_eq!(schema.node_kind, "schema");
assert_eq!(schema.name, "NetworkConfig"); assert_eq!(schema.name, "NetworkConfig");
assert_eq!(schema.type_name.as_deref(), Some("api.manage.NetworkConfig")); assert_eq!(
schema.type_name.as_deref(),
Some("api.manage.NetworkConfig")
);
let virtual_ipv4 = schema let virtual_ipv4 = schema
.children .children
@@ -369,26 +380,35 @@ mod tests {
.iter() .iter()
.find(|field| field.name == "secure_mode") .find(|field| field.name == "secure_mode")
.expect("secure_mode field"); .expect("secure_mode field");
assert!(secure_mode.children.iter().any(|field| field.name == "enabled")); assert!(
secure_mode
.children
.iter()
.any(|field| field.name == "enabled")
);
let secure_mode_definition = schema let secure_mode_definition = schema
.definitions .definitions
.iter() .iter()
.find(|definition| definition.name == "common.SecureModeConfig") .find(|definition| definition.name == "common.SecureModeConfig")
.expect("secure mode definition"); .expect("secure mode definition");
assert!(secure_mode_definition assert!(
.children secure_mode_definition
.iter() .children
.any(|field| field.name == "local_private_key")); .iter()
.any(|field| field.name == "local_private_key")
);
let networking_method_definition = schema let networking_method_definition = schema
.definitions .definitions
.iter() .iter()
.find(|definition| definition.name == "api.manage.NetworkingMethod") .find(|definition| definition.name == "api.manage.NetworkingMethod")
.expect("networking method enum definition"); .expect("networking method enum definition");
assert!(networking_method_definition assert!(
.enum_options networking_method_definition
.iter() .enum_options
.any(|option| option.label == "PublicServer")); .iter()
.any(|option| option.label == "PublicServer")
);
} }
} }
@@ -75,7 +75,9 @@ fn decompress_from_base64url(raw: &str) -> Result<String, String> {
let compressed = URL_SAFE_NO_PAD.decode(raw).map_err(|err| err.to_string())?; let compressed = URL_SAFE_NO_PAD.decode(raw).map_err(|err| err.to_string())?;
let mut decoder = ZlibDecoder::new(compressed.as_slice()); let mut decoder = ZlibDecoder::new(compressed.as_slice());
let mut out = String::new(); let mut out = String::new();
decoder.read_to_string(&mut out).map_err(|err| err.to_string())?; decoder
.read_to_string(&mut out)
.map_err(|err| err.to_string())?;
Ok(out) Ok(out)
} }
@@ -88,7 +90,9 @@ pub fn build_config_share_link(
let config = serde_json::from_str::<NetworkConfig>(&record.config_json).ok()?; let config = serde_json::from_str::<NetworkConfig>(&record.config_json).ok()?;
let mapped_json = map_config_json(&config).ok()?; let mapped_json = map_config_json(&config).ok()?;
let compressed = compress_to_base64url(&mapped_json).ok()?; let compressed = compress_to_base64url(&mapped_json).ok()?;
let final_name = display_name.or(Some(record.meta.display_name)).filter(|name| !name.is_empty()); let final_name = display_name
.or(Some(record.meta.display_name))
.filter(|name| !name.is_empty());
let mut url = Url::parse(&format!("https://{SHARE_LINK_HOST}{SHARE_LINK_PATH}")).ok()?; let mut url = Url::parse(&format!("https://{SHARE_LINK_HOST}{SHARE_LINK_PATH}")).ok()?;
url.query_pairs_mut().append_pair("cfg", &compressed); url.query_pairs_mut().append_pair("cfg", &compressed);
@@ -107,7 +111,11 @@ pub fn parse_config_share_link(share_link: &str) -> Option<SharedConfigLinkPaylo
return None; return None;
} }
let cfg = url.query_pairs().find(|(key, _)| key == "cfg")?.1.to_string(); let cfg = url
.query_pairs()
.find(|(key, _)| key == "cfg")?
.1
.to_string();
let mapped_json = decompress_from_base64url(&cfg).ok()?; let mapped_json = decompress_from_base64url(&cfg).ok()?;
let mut config = unmap_config_json(&mapped_json).ok()?; let mut config = unmap_config_json(&mapped_json).ok()?;
config.instance_id = Some(Uuid::new_v4().to_string()); config.instance_id = Some(Uuid::new_v4().to_string());
@@ -171,11 +179,13 @@ mod tests {
#[test] #[test]
fn share_link_roundtrip_works() { fn share_link_roundtrip_works() {
assert!(init_config_store(test_root())); assert!(init_config_store(test_root()));
create_config_record("cfg-share".to_string(), "share-demo".to_string()).expect("create config"); create_config_record("cfg-share".to_string(), "share-demo".to_string())
.expect("create config");
let link = build_config_share_link("cfg-share", None, true).expect("share link"); let link = build_config_share_link("cfg-share", None, true).expect("share link");
let payload = parse_config_share_link(&link).expect("parse link"); let payload = parse_config_share_link(&link).expect("parse link");
let config = serde_json::from_str::<NetworkConfig>(&payload.config_json).expect("config json"); let config =
serde_json::from_str::<NetworkConfig>(&payload.config_json).expect("config json");
assert!(payload.only_start); assert!(payload.only_start);
assert_eq!(payload.display_name.as_deref(), Some("share-demo")); assert_eq!(payload.display_name.as_deref(), Some("share-demo"));
@@ -67,7 +67,11 @@ pub(crate) fn open_db() -> Option<Connection> {
}; };
if let Err(e) = init_schema(&conn) { if let Err(e) = init_schema(&conn) {
hilog_error!("[Rust] failed to initialize config db {}: {}", path.display(), e); hilog_error!(
"[Rust] failed to initialize config db {}: {}",
path.display(),
e
);
return None; return None;
} }
@@ -111,7 +115,11 @@ fn to_meta(record: StoredConfigMetaRecord) -> StoredConfigMeta {
pub fn init_config_meta_store(root_dir: String) -> bool { pub fn init_config_meta_store(root_dir: String) -> bool {
let root = PathBuf::from(root_dir); let root = PathBuf::from(root_dir);
if let Err(e) = std::fs::create_dir_all(&root) { if let Err(e) = std::fs::create_dir_all(&root) {
hilog_error!("[Rust] failed to create config db dir {}: {}", root.display(), e); hilog_error!(
"[Rust] failed to create config db dir {}: {}",
root.display(),
e
);
return false; return false;
} }
@@ -287,7 +295,10 @@ pub(crate) fn upsert_config_meta_in_tx(
})) }))
} }
pub fn set_config_display_name(config_id: String, display_name: String) -> Option<StoredConfigMeta> { pub fn set_config_display_name(
config_id: String,
display_name: String,
) -> Option<StoredConfigMeta> {
let conn = open_db()?; let conn = open_db()?;
let mut record = load_meta_record(&conn, &config_id)?; let mut record = load_meta_record(&conn, &config_id)?;
record.display_name = display_name; record.display_name = display_name;
@@ -1,9 +1,9 @@
use super::{field_store, import_export, legacy_migration, validation};
use crate::config::storage::config_meta::{ use crate::config::storage::config_meta::{
delete_config_meta, get_config_meta, init_config_meta_store, list_config_meta_entries, delete_config_meta, get_config_meta, init_config_meta_store, list_config_meta_entries, open_db,
open_db, upsert_config_meta_in_tx, upsert_config_meta_in_tx,
}; };
use crate::config::types::stored_config::{ExportTomlResult, StoredConfigRecord}; use crate::config::types::stored_config::{ExportTomlResult, StoredConfigRecord};
use super::{field_store, import_export, legacy_migration, validation};
use easytier::common::config::ConfigLoader; use easytier::common::config::ConfigLoader;
use easytier::proto::api::manage::NetworkConfig; use easytier::proto::api::manage::NetworkConfig;
use ohos_hilog_binding::{hilog_debug, hilog_error}; use ohos_hilog_binding::{hilog_debug, hilog_error};
@@ -35,7 +35,11 @@ pub fn init_config_store(root_dir: String) -> bool {
let root = PathBuf::from(root_dir); let root = PathBuf::from(root_dir);
let configs_dir = root.join(CONFIG_DIR_NAME); let configs_dir = root.join(CONFIG_DIR_NAME);
if let Err(e) = std::fs::create_dir_all(&configs_dir) { if let Err(e) = std::fs::create_dir_all(&configs_dir) {
hilog_error!("[Rust] failed to create config dir {}: {}", configs_dir.display(), e); hilog_error!(
"[Rust] failed to create config dir {}: {}",
configs_dir.display(),
e
);
return false; return false;
} }
@@ -53,12 +57,20 @@ pub fn init_config_store(root_dir: String) -> bool {
return false; return false;
} }
hilog_debug!("[Rust] initialized config repo at {}", configs_dir.display()); hilog_debug!(
"[Rust] initialized config repo at {}",
configs_dir.display()
);
true true
} }
fn migrate_legacy_file_if_needed(config_id: &str) -> Option<()> { fn migrate_legacy_file_if_needed(config_id: &str) -> Option<()> {
legacy_migration::migrate_legacy_file_if_needed(&config_root_dir(), CONFIG_DIR_NAME, config_id, save_config_record) legacy_migration::migrate_legacy_file_if_needed(
&config_root_dir(),
CONFIG_DIR_NAME,
config_id,
save_config_record,
)
} }
pub fn save_config_record( pub fn save_config_record(
@@ -77,7 +89,11 @@ pub fn save_config_record(
let normalized_json = match serde_json::to_string(&config) { let normalized_json = match serde_json::to_string(&config) {
Ok(raw) => raw, Ok(raw) => raw,
Err(e) => { Err(e) => {
hilog_error!("[Rust] failed to serialize normalized config {}: {}", config_id, e); hilog_error!(
"[Rust] failed to serialize normalized config {}: {}",
config_id,
e
);
return None; return None;
} }
}; };
@@ -90,7 +106,10 @@ pub fn save_config_record(
let conn = open_db()?; let conn = open_db()?;
let tx = conn.unchecked_transaction().ok()?; let tx = conn.unchecked_transaction().ok()?;
let existing_meta = get_config_meta(&config_id); let existing_meta = get_config_meta(&config_id);
let favorite = existing_meta.as_ref().map(|meta| meta.favorite).unwrap_or(false); let favorite = existing_meta
.as_ref()
.map(|meta| meta.favorite)
.unwrap_or(false);
let temporary = existing_meta let temporary = existing_meta
.as_ref() .as_ref()
.map(|meta| meta.temporary) .map(|meta| meta.temporary)
@@ -227,7 +246,10 @@ pub fn export_config_toml(config_id: &str) -> Option<ExportTomlResult> {
import_export::export_config_toml_from_record(&record) import_export::export_config_toml_from_record(&record)
} }
pub fn import_toml_config(toml_text: String, display_name: Option<String>) -> Option<StoredConfigRecord> { pub fn import_toml_config(
toml_text: String,
display_name: Option<String>,
) -> Option<StoredConfigRecord> {
import_export::import_toml_to_record(toml_text, display_name, save_config_record) import_export::import_toml_to_record(toml_text, display_name, save_config_record)
} }
@@ -253,12 +275,8 @@ mod tests {
assert!(init_config_store(root.clone())); assert!(init_config_store(root.clone()));
let config_json = crate::build_default_network_config_json().expect("default config"); let config_json = crate::build_default_network_config_json().expect("default config");
let saved = save_config_record( let saved = save_config_record("cfg-1".to_string(), "test-config".to_string(), config_json)
"cfg-1".to_string(), .expect("save config");
"test-config".to_string(),
config_json,
)
.expect("save config");
assert_eq!(saved.meta.config_id, "cfg-1"); assert_eq!(saved.meta.config_id, "cfg-1");
assert_eq!(saved.meta.display_name, "test-config"); assert_eq!(saved.meta.display_name, "test-config");
@@ -27,7 +27,11 @@ pub(super) fn load_config_map_from_db(config_id: &str) -> Option<Map<String, Val
object.insert(field_name, value); object.insert(field_name, value);
} }
if object.is_empty() { None } else { Some(object) } if object.is_empty() {
None
} else {
Some(object)
}
} }
pub(super) fn replace_config_fields( pub(super) fn replace_config_fields(
@@ -39,7 +43,11 @@ pub(super) fn replace_config_fields(
"DELETE FROM stored_config_fields WHERE config_id = ?1", "DELETE FROM stored_config_fields WHERE config_id = ?1",
params![config_id], params![config_id],
) { ) {
hilog_error!("[Rust] failed to clear existing config fields {}: {}", config_id, e); hilog_error!(
"[Rust] failed to clear existing config fields {}: {}",
config_id,
e
);
return None; return None;
} }
@@ -2,10 +2,14 @@ use crate::config::types::stored_config::{ExportTomlResult, StoredConfigRecord};
use easytier::common::config::{ConfigLoader, TomlConfigLoader}; use easytier::common::config::{ConfigLoader, TomlConfigLoader};
use easytier::proto::api::manage::NetworkConfig; use easytier::proto::api::manage::NetworkConfig;
pub(super) fn export_config_toml_from_record(record: &StoredConfigRecord) -> Option<ExportTomlResult> { pub(super) fn export_config_toml_from_record(
record: &StoredConfigRecord,
) -> Option<ExportTomlResult> {
let config = serde_json::from_str::<NetworkConfig>(&record.config_json).ok()?; let config = serde_json::from_str::<NetworkConfig>(&record.config_json).ok()?;
let toml = config.gen_config().ok()?; let toml = config.gen_config().ok()?;
Some(ExportTomlResult { toml_text: toml.dump() }) Some(ExportTomlResult {
toml_text: toml.dump(),
})
} }
pub(super) fn import_toml_to_record( pub(super) fn import_toml_to_record(
@@ -13,7 +17,8 @@ pub(super) fn import_toml_to_record(
display_name: Option<String>, display_name: Option<String>,
save_config_record: impl Fn(String, String, String) -> Option<StoredConfigRecord>, save_config_record: impl Fn(String, String, String) -> Option<StoredConfigRecord>,
) -> Option<StoredConfigRecord> { ) -> Option<StoredConfigRecord> {
let config = NetworkConfig::new_from_config(TomlConfigLoader::new_from_str(&toml_text).ok()?).ok()?; let config =
NetworkConfig::new_from_config(TomlConfigLoader::new_from_str(&toml_text).ok()?).ok()?;
let config_id = config.instance_id.clone()?; let config_id = config.instance_id.clone()?;
let name_from_toml = toml_text let name_from_toml = toml_text
@@ -23,9 +28,13 @@ pub(super) fn import_toml_to_record(
if !trimmed.starts_with("instance_name") { if !trimmed.starts_with("instance_name") {
return None; return None;
} }
trimmed trimmed.split_once('=').map(|(_, value)| {
.split_once('=') value
.map(|(_, value)| value.trim().trim_matches('"').trim_matches('\'').to_string()) .trim()
.trim_matches('"')
.trim_matches('\'')
.to_string()
})
}) })
.filter(|name| !name.is_empty()); .filter(|name| !name.is_empty());
@@ -2,15 +2,26 @@ use crate::config::storage::config_meta::get_config_meta;
use ohos_hilog_binding::hilog_error; use ohos_hilog_binding::hilog_error;
use std::path::PathBuf; use std::path::PathBuf;
pub(super) fn legacy_config_file_path(root_dir: &Option<PathBuf>, config_dir_name: &str, config_id: &str) -> Option<PathBuf> { pub(super) fn legacy_config_file_path(
root_dir.as_ref().map(|root| root.join(config_dir_name).join(format!("{}.json", config_id))) root_dir: &Option<PathBuf>,
config_dir_name: &str,
config_id: &str,
) -> Option<PathBuf> {
root_dir.as_ref().map(|root| {
root.join(config_dir_name)
.join(format!("{}.json", config_id))
})
} }
pub(super) fn migrate_legacy_file_if_needed( pub(super) fn migrate_legacy_file_if_needed(
root_dir: &Option<PathBuf>, root_dir: &Option<PathBuf>,
config_dir_name: &str, config_dir_name: &str,
config_id: &str, config_id: &str,
save_config_record: impl Fn(String, String, String) -> Option<crate::config::types::stored_config::StoredConfigRecord>, save_config_record: impl Fn(
String,
String,
String,
) -> Option<crate::config::types::stored_config::StoredConfigRecord>,
) -> Option<()> { ) -> Option<()> {
let legacy_path = legacy_config_file_path(root_dir, config_dir_name, config_id)?; let legacy_path = legacy_config_file_path(root_dir, config_dir_name, config_id)?;
if !legacy_path.exists() { if !legacy_path.exists() {
@@ -24,7 +35,11 @@ pub(super) fn migrate_legacy_file_if_needed(
save_config_record(config_id.to_string(), display_name, raw)?; save_config_record(config_id.to_string(), display_name, raw)?;
if let Err(e) = std::fs::remove_file(&legacy_path) { if let Err(e) = std::fs::remove_file(&legacy_path) {
hilog_error!("[Rust] failed to remove legacy config file {}: {}", legacy_path.display(), e); hilog_error!(
"[Rust] failed to remove legacy config file {}: {}",
legacy_path.display(),
e
);
} }
Some(()) Some(())
} }
@@ -37,7 +37,8 @@ pub(crate) fn set_config_field(config_id: String, field: String, json_value: Str
} }
pub(crate) fn import_toml(toml_text: String, display_name: Option<String>) -> Option<String> { pub(crate) fn import_toml(toml_text: String, display_name: Option<String>) -> Option<String> {
config::repository::import_toml_config(toml_text, display_name).map(|record| record.meta.config_id) config::repository::import_toml_config(toml_text, display_name)
.map(|record| record.meta.config_id)
} }
pub(crate) fn export_toml(config_id: String) -> Option<String> { pub(crate) fn export_toml(config_id: String) -> Option<String> {
@@ -1,14 +1,23 @@
use crate::config::repository::load_config_json; use crate::config::repository::load_config_json;
use crate::kernel_bridge::{aggregate_requested_tun_routes, start_local_socket_server as start_local_socket_server_inner, stop_local_socket_server as stop_local_socket_server_inner};
use crate::runtime::state::runtime_state::{RuntimeAggregateState, TunAggregateState, clear_tun_attached, mark_tun_attached, runtime_instance_from_running_info};
use crate::{ASYNC_RUNTIME, EASYTIER_VERSION, INSTANCE_MANAGER, WEB_CLIENTS};
use crate::config::storage::config_meta::get_config_display_name; use crate::config::storage::config_meta::get_config_display_name;
use crate::config::types::stored_config::KeyValuePair; use crate::config::types::stored_config::KeyValuePair;
use crate::kernel_bridge::{
aggregate_requested_tun_routes, start_local_socket_server as start_local_socket_server_inner,
stop_local_socket_server as stop_local_socket_server_inner,
};
use crate::runtime::state::runtime_state::{
RuntimeAggregateState, TunAggregateState, clear_tun_attached, mark_tun_attached,
runtime_instance_from_running_info,
};
use crate::{ASYNC_RUNTIME, EASYTIER_VERSION, INSTANCE_MANAGER, WEB_CLIENTS};
use easytier::proto::api::manage::NetworkConfig; use easytier::proto::api::manage::NetworkConfig;
use ohos_hilog_binding::{hilog_error, hilog_info}; use ohos_hilog_binding::{hilog_error, hilog_info};
use std::sync::Arc; use std::sync::Arc;
pub(crate) fn start_kernel(config_id: String, start_kernel_with_config_id: impl Fn(&str) -> bool) -> bool { pub(crate) fn start_kernel(
config_id: String,
start_kernel_with_config_id: impl Fn(&str) -> bool,
) -> bool {
start_kernel_with_config_id(&config_id) start_kernel_with_config_id(&config_id)
} }
@@ -58,12 +67,15 @@ pub(crate) fn collect_network_infos() -> Vec<KeyValuePair> {
} }
}; };
infos.into_iter() infos
.into_iter()
.filter_map(|(key, value)| { .filter_map(|(key, value)| {
serde_json::to_string(&value).ok().map(|value_json| KeyValuePair { serde_json::to_string(&value)
key: key.to_string(), .ok()
value: value_json, .map(|value_json| KeyValuePair {
}) key: key.to_string(),
value: value_json,
})
}) })
.collect() .collect()
} }
@@ -82,7 +94,11 @@ pub(crate) fn set_tun_fd(
.set_tun_fd(&instance_id, fd) .set_tun_fd(&instance_id, fd)
.map(|_| { .map(|_| {
mark_tun_attached(&config_id); mark_tun_attached(&config_id);
hilog_info!("[Rust] set_tun_fd success instance={} fd={} marked_attached=true", config_id, fd); hilog_info!(
"[Rust] set_tun_fd success instance={} fd={} marked_attached=true",
config_id,
fd
);
true true
}) })
.unwrap_or_else(|err| { .unwrap_or_else(|err| {
@@ -139,14 +155,19 @@ pub(crate) fn get_runtime_snapshot_inner() -> RuntimeAggregateState {
)); ));
} }
instances.sort_by(|a, b| a.display_name.cmp(&b.display_name).then_with(|| a.instance_id.cmp(&b.instance_id))); instances.sort_by(|a, b| {
a.display_name
.cmp(&b.display_name)
.then_with(|| a.instance_id.cmp(&b.instance_id))
});
let attached_instance_ids = instances let attached_instance_ids = instances
.iter() .iter()
.filter(|instance| instance.tun_required) .filter(|instance| instance.tun_required)
.map(|instance| instance.instance_id.clone()) .map(|instance| instance.instance_id.clone())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let aggregated_routes = aggregate_requested_tun_routes(&instances); let aggregated_routes = aggregate_requested_tun_routes(&instances);
let running_instance_count = instances.iter().filter(|instance| instance.running).count() as i32; let running_instance_count =
instances.iter().filter(|instance| instance.running).count() as i32;
let tun_active = !attached_instance_ids.is_empty(); let tun_active = !attached_instance_ids.is_empty();
RuntimeAggregateState { RuntimeAggregateState {
@@ -1,6 +1,7 @@
use super::protocol::{broadcast_local_socket_message, TunRequestPayload}; use super::protocol::{TunRequestPayload, broadcast_local_socket_message};
use crate::config::repository::kernel_socket_path; use crate::config::repository::kernel_socket_path;
use crate::get_runtime_snapshot_inner; use crate::get_runtime_snapshot_inner;
use crate::kernel_bridge::routing::aggregate_tun_routes;
use ohos_hilog_binding::{hilog_error, hilog_info}; use ohos_hilog_binding::{hilog_error, hilog_info};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
@@ -11,7 +12,6 @@ use std::sync::Mutex;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::thread::{self, JoinHandle}; use std::thread::{self, JoinHandle};
use std::time::Duration; use std::time::Duration;
use crate::kernel_bridge::routing::aggregate_tun_routes;
struct LocalSocketState { struct LocalSocketState {
stop_flag: std::sync::Arc<AtomicBool>, stop_flag: std::sync::Arc<AtomicBool>,
@@ -46,7 +46,11 @@ pub fn start_local_socket_server() -> bool {
let listener = match UnixListener::bind(&socket_path) { let listener = match UnixListener::bind(&socket_path) {
Ok(listener) => listener, Ok(listener) => listener,
Err(err) => { Err(err) => {
hilog_error!("[Rust] bind localsocket failed {}: {}", socket_path.display(), err); hilog_error!(
"[Rust] bind localsocket failed {}: {}",
socket_path.display(),
err
);
return false; return false;
} }
}; };
@@ -91,7 +95,11 @@ pub fn start_local_socket_server() -> bool {
}; };
if accepted_client || snapshot_json != last_snapshot_json { if accepted_client || snapshot_json != last_snapshot_json {
let _ = broadcast_local_socket_message(&mut clients, "runtime_snapshot", &snapshot_json); let _ = broadcast_local_socket_message(
&mut clients,
"runtime_snapshot",
&snapshot_json,
);
last_snapshot_json = snapshot_json; last_snapshot_json = snapshot_json;
} }
@@ -141,7 +149,8 @@ pub fn start_local_socket_server() -> bool {
}; };
if broadcast_local_socket_message(&mut clients, "tun_request", &payload_json) { if broadcast_local_socket_message(&mut clients, "tun_request", &payload_json) {
delivered_tun_requests.insert(instance.instance_id.clone()); delivered_tun_requests.insert(instance.instance_id.clone());
last_tun_route_signatures.insert(instance.instance_id.clone(), route_signature); last_tun_route_signatures
.insert(instance.instance_id.clone(), route_signature);
} }
} else { } else {
delivered_tun_requests.remove(&instance.instance_id); delivered_tun_requests.remove(&instance.instance_id);
+62 -33
View File
@@ -4,6 +4,11 @@ mod kernel_bridge;
mod platform; mod platform;
mod runtime; mod runtime;
use config::repository::{
create_config_record, delete_config_record, export_config_toml, get_config_field_value,
get_default_config_json, import_toml_config, init_config_store as init_repo_store,
list_config_meta_json, save_config_record, set_config_field_value, start_kernel_with_config_id,
};
use config::services::schema_service::{ use config::services::schema_service::{
ConfigFieldMapping, NetworkConfigSchema, ConfigFieldMapping, NetworkConfigSchema,
get_network_config_field_mappings as build_network_config_field_mappings, get_network_config_field_mappings as build_network_config_field_mappings,
@@ -16,28 +21,22 @@ use config::services::share_link_service::{
}; };
use config::storage::config_meta::get_config_display_name; use config::storage::config_meta::get_config_display_name;
use config::types::stored_config::{KeyValuePair, SharedConfigLinkPayload}; use config::types::stored_config::{KeyValuePair, SharedConfigLinkPayload};
use config::repository::{
create_config_record, delete_config_record, export_config_toml, get_config_field_value,
get_default_config_json, import_toml_config, init_config_store as init_repo_store,
list_config_meta_json, save_config_record, set_config_field_value, start_kernel_with_config_id,
};
use kernel_bridge::{
aggregate_requested_tun_routes,
start_local_socket_server as start_local_socket_server_inner,
stop_local_socket_server as stop_local_socket_server_inner,
};
use runtime::state::runtime_state::{
RuntimeAggregateState, TunAggregateState, clear_tun_attached, mark_tun_attached,
runtime_instance_from_running_info,
};
use easytier::common::config::{ConfigFileControl, ConfigLoader, TomlConfigLoader}; use easytier::common::config::{ConfigFileControl, ConfigLoader, TomlConfigLoader};
use easytier::common::constants::EASYTIER_VERSION; use easytier::common::constants::EASYTIER_VERSION;
use easytier::instance_manager::NetworkInstanceManager; use easytier::instance_manager::NetworkInstanceManager;
use easytier::proto::api::manage::NetworkConfig; use easytier::proto::api::manage::NetworkConfig;
use easytier::proto::api::manage::NetworkingMethod; use easytier::proto::api::manage::NetworkingMethod;
use easytier::web_client::{WebClient, WebClientHooks, run_web_client}; use easytier::web_client::{WebClient, WebClientHooks, run_web_client};
use kernel_bridge::{
aggregate_requested_tun_routes, start_local_socket_server as start_local_socket_server_inner,
stop_local_socket_server as stop_local_socket_server_inner,
};
use napi_derive_ohos::napi; use napi_derive_ohos::napi;
use ohos_hilog_binding::{hilog_error, hilog_info}; use ohos_hilog_binding::{hilog_error, hilog_info};
use runtime::state::runtime_state::{
RuntimeAggregateState, TunAggregateState, clear_tun_attached, mark_tun_attached,
runtime_instance_from_running_info,
};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::format; use std::format;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
@@ -86,7 +85,8 @@ impl WebClientHooks for TrackedWebClientHooks {
fn is_config_server_config(config: &NetworkConfig) -> bool { fn is_config_server_config(config: &NetworkConfig) -> bool {
matches!( matches!(
NetworkingMethod::try_from(config.networking_method.unwrap_or_default()).unwrap_or_default(), NetworkingMethod::try_from(config.networking_method.unwrap_or_default())
.unwrap_or_default(),
NetworkingMethod::PublicServer NetworkingMethod::PublicServer
) && config ) && config
.public_server_url .public_server_url
@@ -124,7 +124,11 @@ fn stop_web_client(config_id: &str) -> bool {
.delete_network_instance(tracked_ids) .delete_network_instance(tracked_ids)
.map(|_| true) .map(|_| true)
.unwrap_or_else(|err| { .unwrap_or_else(|err| {
hilog_error!("[Rust] stop config server instances failed {}: {}", config_id, err); hilog_error!(
"[Rust] stop config server instances failed {}: {}",
config_id,
err
);
false false
}); });
maybe_stop_local_socket_server(); maybe_stop_local_socket_server();
@@ -137,14 +141,22 @@ fn ensure_local_socket_server_started() -> bool {
fn maybe_stop_local_socket_server() { fn maybe_stop_local_socket_server() {
let no_local_instances = INSTANCE_MANAGER.list_network_instance_ids().is_empty(); let no_local_instances = INSTANCE_MANAGER.list_network_instance_ids().is_empty();
let no_web_clients = WEB_CLIENTS.lock().map(|guard| guard.is_empty()).unwrap_or(false); let no_web_clients = WEB_CLIENTS
.lock()
.map(|guard| guard.is_empty())
.unwrap_or(false);
if no_local_instances && no_web_clients { if no_local_instances && no_web_clients {
let _ = stop_local_socket_server_inner(); let _ = stop_local_socket_server_inner();
} }
} }
fn run_config_server_instance(config_id: &str, config: &NetworkConfig) -> bool { fn run_config_server_instance(config_id: &str, config: &NetworkConfig) -> bool {
if INSTANCE_MANAGER.list_network_instance_ids().iter().next().is_some() { if INSTANCE_MANAGER
.list_network_instance_ids()
.iter()
.next()
.is_some()
{
hilog_error!("[Rust] there is a running instance!"); hilog_error!("[Rust] there is a running instance!");
return false; return false;
} }
@@ -154,7 +166,11 @@ fn run_config_server_instance(config_id: &str, config: &NetworkConfig) -> bool {
return false; return false;
}; };
let hooks = Arc::new(TrackedWebClientHooks::default()); let hooks = Arc::new(TrackedWebClientHooks::default());
let secure_mode = config.secure_mode.as_ref().map(|mode| mode.enabled).unwrap_or(false); let secure_mode = config
.secure_mode
.as_ref()
.map(|mode| mode.enabled)
.unwrap_or(false);
let hostname = config.hostname.clone(); let hostname = config.hostname.clone();
if !ensure_local_socket_server_started() { if !ensure_local_socket_server_started() {
@@ -203,8 +219,10 @@ pub(crate) fn build_default_network_config_json() -> Result<String, String> {
} }
fn convert_toml_to_network_config_inner(toml_text: &str) -> Result<String, String> { fn convert_toml_to_network_config_inner(toml_text: &str) -> Result<String, String> {
let config = NetworkConfig::new_from_config(TomlConfigLoader::new_from_str(toml_text).map_err(|e| e.to_string())?) let config = NetworkConfig::new_from_config(
.map_err(|e| e.to_string())?; TomlConfigLoader::new_from_str(toml_text).map_err(|e| e.to_string())?,
)
.map_err(|e| e.to_string())?;
serde_json::to_string(&config).map_err(|e| e.to_string()) serde_json::to_string(&config).map_err(|e| e.to_string())
} }
@@ -250,7 +268,10 @@ pub(crate) fn run_network_instance_from_json(cfg_json: &str) -> bool {
} }
let inst_id = cfg.get_id(); let inst_id = cfg.get_id();
if INSTANCE_MANAGER.list_network_instance_ids().contains(&inst_id) { if INSTANCE_MANAGER
.list_network_instance_ids()
.contains(&inst_id)
{
hilog_error!("[Rust] instance {} already exists", inst_id); hilog_error!("[Rust] instance {} already exists", inst_id);
return false; return false;
} }
@@ -346,7 +367,12 @@ pub fn start_kernel(config_id: String) -> bool {
#[napi] #[napi]
pub fn stop_kernel(config_id: String) -> bool { pub fn stop_kernel(config_id: String) -> bool {
exports::runtime_api::stop_kernel(config_id, stop_web_client, parse_instance_uuid, maybe_stop_local_socket_server) exports::runtime_api::stop_kernel(
config_id,
stop_web_client,
parse_instance_uuid,
maybe_stop_local_socket_server,
)
} }
#[napi] #[napi]
@@ -366,8 +392,7 @@ pub fn default_network_config() -> String {
#[napi] #[napi]
pub fn convert_toml_to_network_config(toml_text: String) -> String { pub fn convert_toml_to_network_config(toml_text: String) -> String {
convert_toml_to_network_config_inner(&toml_text) convert_toml_to_network_config_inner(&toml_text).unwrap_or_else(|err| format!("ERROR: {err}"))
.unwrap_or_else(|err| format!("ERROR: {err}"))
} }
#[napi] #[napi]
@@ -409,19 +434,23 @@ mod tests {
let schema = get_network_config_schema(); let schema = get_network_config_schema();
assert_eq!(schema.name, "NetworkConfig"); assert_eq!(schema.name, "NetworkConfig");
assert_eq!(schema.node_kind, "schema"); assert_eq!(schema.node_kind, "schema");
assert!(schema assert!(
.children schema
.iter() .children
.any(|field| field.name == "network_name")); .iter()
.any(|field| field.name == "network_name")
);
let secure_mode = schema let secure_mode = schema
.children .children
.iter() .iter()
.find(|field| field.name == "secure_mode") .find(|field| field.name == "secure_mode")
.expect("secure_mode field"); .expect("secure_mode field");
assert!(secure_mode assert!(
.children secure_mode
.iter() .children
.any(|field| field.name == "enabled")); .iter()
.any(|field| field.name == "enabled")
);
} }
} }
@@ -208,8 +208,14 @@ fn peer_conn_to_view(conn: api::instance::PeerConnInfo) -> PeerConnInfo {
peer_id: conn.peer_id as i64, peer_id: conn.peer_id as i64,
features: conn.features, features: conn.features,
tunnel_type: conn.tunnel.as_ref().map(|t| t.tunnel_type.clone()), tunnel_type: conn.tunnel.as_ref().map(|t| t.tunnel_type.clone()),
local_addr: conn.tunnel.as_ref().and_then(|t| stringify_url(t.local_addr.clone())), local_addr: conn
remote_addr: conn.tunnel.as_ref().and_then(|t| stringify_url(t.remote_addr.clone())), .tunnel
.as_ref()
.and_then(|t| stringify_url(t.local_addr.clone())),
remote_addr: conn
.tunnel
.as_ref()
.and_then(|t| stringify_url(t.remote_addr.clone())),
resolved_remote_addr: conn resolved_remote_addr: conn
.tunnel .tunnel
.as_ref() .as_ref()
@@ -248,7 +254,11 @@ fn my_node_info_to_view(info: api::manage::MyNodeInfo) -> MyNodeInfo {
hostname: (!info.hostname.is_empty()).then_some(info.hostname), hostname: (!info.hostname.is_empty()).then_some(info.hostname),
version: (!info.version.is_empty()).then_some(info.version), version: (!info.version.is_empty()).then_some(info.version),
peer_id: Some(info.peer_id as i64), peer_id: Some(info.peer_id as i64),
listeners: info.listeners.into_iter().map(|url| url.to_string()).collect(), listeners: info
.listeners
.into_iter()
.map(|url| url.to_string())
.collect(),
vpn_portal_cfg: info.vpn_portal_cfg, vpn_portal_cfg: info.vpn_portal_cfg,
udp_nat_type: info.stun_info.as_ref().map(|stun| stun.udp_nat_type), udp_nat_type: info.stun_info.as_ref().map(|stun| stun.udp_nat_type),
tcp_nat_type: info.stun_info.as_ref().map(|stun| stun.tcp_nat_type), tcp_nat_type: info.stun_info.as_ref().map(|stun| stun.tcp_nat_type),