Merge branch 'EasyTier:main' into perf/ts-type

This commit is contained in:
m1m1sha
2024-05-10 00:16:39 +08:00
committed by GitHub
24 changed files with 174 additions and 65 deletions

View File

@@ -1,8 +1,14 @@
[target.x86_64-unknown-linux-musl]
linker = "rust-lld"
rustflags = ["-C", "linker-flavor=ld.lld"]
[target.aarch64-unknown-linux-gnu] [target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc" linker = "aarch64-linux-gnu-gcc"
[target.aarch64-unknown-linux-musl] [target.aarch64-unknown-linux-musl]
linker = "aarch64-linux-musl-gcc" linker = "aarch64-linux-musl-gcc"
rustflags = ["-C", "target-feature=+crt-static"] rustflags = ["-C", "target-feature=+crt-static"]
[target.'cfg(all(windows, target_env = "msvc"))'] [target.'cfg(all(windows, target_env = "msvc"))']
rustflags = ["-C", "target-feature=+crt-static"] rustflags = ["-C", "target-feature=+crt-static"]

3
.gitignore vendored
View File

@@ -26,3 +26,6 @@ nohup.out
components.d.ts components.d.ts
musl_gcc musl_gcc
# log
easytier-panic.log

6
Cargo.lock generated
View File

@@ -387,7 +387,7 @@ dependencies = [
[[package]] [[package]]
name = "boringtun" name = "boringtun"
version = "0.6.0" version = "0.6.0"
source = "git+https://github.com/KKRainbow/boringtun.git#449204c3eca736dc23b075d81426527a357e2f2a" source = "git+https://github.com/EasyTier/boringtun.git?rev=449204c#449204c3eca736dc23b075d81426527a357e2f2a"
dependencies = [ dependencies = [
"aead", "aead",
"atomic-shim", "atomic-shim",
@@ -1266,7 +1266,7 @@ checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b"
[[package]] [[package]]
name = "easytier" name = "easytier"
version = "1.0.0" version = "1.0.1-pre"
dependencies = [ dependencies = [
"aes-gcm", "aes-gcm",
"anyhow", "anyhow",
@@ -1309,6 +1309,7 @@ dependencies = [
"quinn", "quinn",
"rand 0.8.5", "rand 0.8.5",
"rcgen", "rcgen",
"regex",
"reqwest", "reqwest",
"ring 0.17.8", "ring 0.17.8",
"rstest", "rstest",
@@ -1348,6 +1349,7 @@ dependencies = [
"chrono", "chrono",
"dashmap", "dashmap",
"easytier", "easytier",
"gethostname",
"once_cell", "once_cell",
"privilege", "privilege",
"serde", "serde",

View File

@@ -8,3 +8,8 @@ panic = "unwind"
[profile.release] [profile.release]
panic = "unwind" panic = "unwind"
# panic = "abort"
# lto = true
# codegen-units = 1
# strip = true
# opt-level = "z"

View File

@@ -218,19 +218,22 @@ After successfully starting easytier-core, use easytier-cli to obtain the WireGu
$> easytier-cli vpn-portal $> easytier-cli vpn-portal
portal_name: wireguard portal_name: wireguard
client_config: ############### client_config_start ###############
[Interface] [Interface]
PrivateKey = 9VDvlaIC9XHUvRuE06hD2CEDrtGF+0lDthgr9SZfIho= PrivateKey = 9VDvlaIC9XHUvRuE06hD2CEDrtGF+0lDthgr9SZfIho=
Address = 10.14.14.0/24 # should assign an ip from this cidr manually Address = 10.14.14.0/32 # should assign an ip from this cidr manually
[Peer] [Peer]
PublicKey = zhrZQg4QdPZs8CajT3r4fmzcNsWpBL9ImQCUsnlXyGM= PublicKey = zhrZQg4QdPZs8CajT3r4fmzcNsWpBL9ImQCUsnlXyGM=
AllowedIPs = 192.168.80.0/20,10.147.223.0/24,10.144.144.0/24 AllowedIPs = 10.144.144.0/24,10.14.14.0/24
Endpoint = 0.0.0.0:11013 # should be the public ip of the vpn server Endpoint = 0.0.0.0:11013 # should be the public ip(or domain) of the vpn server
PersistentKeepalive = 25
############### client_config_end ###############
connected_clients: connected_clients:
[] []
``` ```
Before using the Client Config, you need to modify the Interface Address and Peer Endpoint to the client's IP and the IP of the EasyTier node, respectively. Import the configuration file into the WireGuard client to access the EasyTier network. Before using the Client Config, you need to modify the Interface Address and Peer Endpoint to the client's IP and the IP of the EasyTier node, respectively. Import the configuration file into the WireGuard client to access the EasyTier network.

View File

@@ -219,19 +219,22 @@ easytier-core 启动成功后,使用 easytier-cli 获取 WireGuard Client 的
$> easytier-cli vpn-portal $> easytier-cli vpn-portal
portal_name: wireguard portal_name: wireguard
client_config: ############### client_config_start ###############
[Interface] [Interface]
PrivateKey = 9VDvlaIC9XHUvRuE06hD2CEDrtGF+0lDthgr9SZfIho= PrivateKey = 9VDvlaIC9XHUvRuE06hD2CEDrtGF+0lDthgr9SZfIho=
Address = 10.14.14.0/24 # should assign an ip from this cidr manually Address = 10.14.14.0/32 # should assign an ip from this cidr manually
[Peer] [Peer]
PublicKey = zhrZQg4QdPZs8CajT3r4fmzcNsWpBL9ImQCUsnlXyGM= PublicKey = zhrZQg4QdPZs8CajT3r4fmzcNsWpBL9ImQCUsnlXyGM=
AllowedIPs = 192.168.80.0/20,10.147.223.0/24,10.144.144.0/24 AllowedIPs = 10.144.144.0/24,10.14.14.0/24
Endpoint = 0.0.0.0:11013 # should be the public ip of the vpn server Endpoint = 0.0.0.0:11013 # should be the public ip(or domain) of the vpn server
PersistentKeepalive = 25
############### client_config_end ###############
connected_clients: connected_clients:
[] []
``` ```
使用 Client Config 前,需要将 Interface Address 和 Peer Endpoint 分别修改为客户端的 IP 和 EasyTier 节点的 IP。将配置文件导入 WireGuard 客户端,即可访问 EasyTier 网络。 使用 Client Config 前,需要将 Interface Address 和 Peer Endpoint 分别修改为客户端的 IP 和 EasyTier 节点的 IP。将配置文件导入 WireGuard 客户端,即可访问 EasyTier 网络。

View File

@@ -32,6 +32,7 @@ settings: 设置
exchange_language: Switch to English exchange_language: Switch to English
exit: 退出 exit: 退出
chips_placeholder: 例如: {0}, 按回车添加 chips_placeholder: 例如: {0}, 按回车添加
hostname_placeholder: '留空默认为主机名: {0}'
off_text: 点击关闭 off_text: 点击关闭
on_text: 点击开启 on_text: 点击开启
show_config: 显示配置 show_config: 显示配置

View File

@@ -33,6 +33,7 @@ exchange_language: 切换中文
exit: Exit exit: Exit
chips_placeholder: 'e.g: {0}, press Enter to add' chips_placeholder: 'e.g: {0}, press Enter to add'
hostname_placeholder: 'Leave blank and default to host name: {0}'
off_text: Press to disable off_text: Press to disable
on_text: Press to enable on_text: Press to enable
show_config: Show Config show_config: Show Config

View File

@@ -11,7 +11,11 @@ edition = "2021"
tauri-build = { version = "1", features = [] } tauri-build = { version = "1", features = [] }
[dependencies] [dependencies]
tauri = { version = "1", features = [ "process-exit", "system-tray", "shell-open"] } tauri = { version = "1", features = [
"process-exit",
"system-tray",
"shell-open",
] }
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
@@ -24,7 +28,7 @@ once_cell = "1.18.0"
dashmap = "5.5.3" dashmap = "5.5.3"
privilege = "0.3" privilege = "0.3"
gethostname = "0.4.3"
[features] [features]
# This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!! # This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!!
custom-protocol = ["tauri/custom-protocol"] custom-protocol = ["tauri/custom-protocol"]

View File

@@ -42,6 +42,7 @@ struct NetworkConfig {
instance_id: String, instance_id: String,
virtual_ipv4: String, virtual_ipv4: String,
hostname: Option<String>,
network_name: String, network_name: String,
network_secret: String, network_secret: String,
networking_method: NetworkingMethod, networking_method: NetworkingMethod,
@@ -70,6 +71,7 @@ impl NetworkConfig {
.parse() .parse()
.with_context(|| format!("failed to parse instance id: {}", self.instance_id))?, .with_context(|| format!("failed to parse instance id: {}", self.instance_id))?,
); );
cfg.set_hostname(self.hostname.clone());
cfg.set_inst_name(self.network_name.clone()); cfg.set_inst_name(self.network_name.clone());
cfg.set_network_identity(NetworkIdentity::new( cfg.set_network_identity(NetworkIdentity::new(
self.network_name.clone(), self.network_name.clone(),
@@ -281,6 +283,11 @@ fn collect_network_infos() -> Result<String, String> {
Ok(serde_json::to_string(&ret).map_err(|e| e.to_string())?) Ok(serde_json::to_string(&ret).map_err(|e| e.to_string())?)
} }
#[tauri::command]
fn get_os_hostname() -> Result<String, String> {
Ok(gethostname::gethostname().to_string_lossy().to_string())
}
fn toggle_window_visibility(window: &Window) { fn toggle_window_visibility(window: &Window) {
if window.is_visible().unwrap() { if window.is_visible().unwrap() {
window.hide().unwrap(); window.hide().unwrap();
@@ -318,7 +325,8 @@ fn main() {
parse_network_config, parse_network_config,
run_network_instance, run_network_instance,
retain_network_instance, retain_network_instance,
collect_network_infos collect_network_infos,
get_os_hostname
]) ])
.system_tray(SystemTray::new().with_menu(tray_menu)) .system_tray(SystemTray::new().with_menu(tray_menu))
.on_system_tray_event(|app, event| match event { .on_system_tray_event(|app, event| match event {

View File

@@ -20,6 +20,7 @@ declare global {
const getActivePinia: typeof import('pinia')['getActivePinia'] const getActivePinia: typeof import('pinia')['getActivePinia']
const getCurrentInstance: typeof import('vue')['getCurrentInstance'] const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope'] const getCurrentScope: typeof import('vue')['getCurrentScope']
const getOsHostname: typeof import('./composables/network')['getOsHostname']
const h: typeof import('vue')['h'] const h: typeof import('vue')['h']
const inject: typeof import('vue')['inject'] const inject: typeof import('vue')['inject']
const isProxy: typeof import('vue')['isProxy'] const isProxy: typeof import('vue')['isProxy']
@@ -108,6 +109,7 @@ declare module 'vue' {
readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']> readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']>
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']> readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']> readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
readonly getOsHostname: UnwrapRef<typeof import('./composables/network')['getOsHostname']>
readonly h: UnwrapRef<typeof import('vue')['h']> readonly h: UnwrapRef<typeof import('vue')['h']>
readonly inject: UnwrapRef<typeof import('vue')['inject']> readonly inject: UnwrapRef<typeof import('vue')['inject']>
readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']> readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>
@@ -189,6 +191,7 @@ declare module '@vue/runtime-core' {
readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']> readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']>
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']> readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']> readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
readonly getOsHostname: UnwrapRef<typeof import('./composables/network')['getOsHostname']>
readonly h: UnwrapRef<typeof import('vue')['h']> readonly h: UnwrapRef<typeof import('vue')['h']>
readonly inject: UnwrapRef<typeof import('vue')['inject']> readonly inject: UnwrapRef<typeof import('vue')['inject']>
readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']> readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>

View File

@@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import InputGroup from 'primevue/inputgroup' import InputGroup from 'primevue/inputgroup'
import InputGroupAddon from 'primevue/inputgroupaddon' import InputGroupAddon from 'primevue/inputgroupaddon'
import { getOsHostname } from '~/composables/network'
import { i18n } from '~/modules/i18n' import { i18n } from '~/modules/i18n'
import { NetworkingMethod } from '~/types/network' import { NetworkingMethod } from '~/types/network'
@@ -32,6 +33,24 @@ const curNetwork = computed(() => {
const presetPublicServers = [ const presetPublicServers = [
'tcp://easytier.public.kkrainbow.top:11010', 'tcp://easytier.public.kkrainbow.top:11010',
] ]
function validateHostname() {
if (curNetwork.value.hostname) {
// eslint no-useless-escape
let name = curNetwork.value.hostname!.replaceAll(/[^\u4E00-\u9FA5a-zA-Z0-9\-]*/g, '')
if (name.length > 32)
name = name.substring(0, 32)
if (curNetwork.value.hostname !== name)
curNetwork.value.hostname = name
}
}
const osHostname = ref<string>('')
onMounted(async () => {
osHostname.value = await getOsHostname()
})
</script> </script>
<template> <template>
@@ -151,6 +170,15 @@ const presetPublicServers = [
/> />
</div> </div>
</div> </div>
<div class="flex flex-row gap-x-9 flex-wrap">
<div class="flex flex-column gap-2 basis-5/12 grow">
<label for="hostname">{{ $t('hostname') }}</label>
<InputText
id="hostname" v-model="curNetwork.hostname" aria-describedby="hostname-help" :format="true"
:placeholder="$t('hostname_placeholder', [osHostname])" @blur="validateHostname"
/>
</div>
</div>
</div> </div>
</Panel> </Panel>

View File

@@ -350,14 +350,14 @@ function showEventLogs() {
{{ $t('peer_info') }} {{ $t('peer_info') }}
</template> </template>
<template #content> <template #content>
<DataTable :value="peerRouteInfos" table-style="min-width: 50rem"> <DataTable :value="peerRouteInfos" column-resize-mode="fit" table-style="width: 100%">
<Column field="route.ipv4_addr" :header="$t('virtual_ipv4')" /> <Column field="route.ipv4_addr" style="width: 100px;" :header="$t('virtual_ipv4')" />
<Column field="route.hostname" :header="$t('hostname')" /> <Column field="route.hostname" style="max-width: 250px;" :header="$t('hostname')" />
<Column :field="routeCost" :header="$t('route_cost')" /> <Column :field="routeCost" style="width: 60px;" :header="$t('route_cost')" />
<Column :field="latencyMs" :header="$t('latency')" /> <Column :field="latencyMs" style="width: 80px;" :header="$t('latency')" />
<Column :field="txBytes" :header="$t('upload_bytes')" /> <Column :field="txBytes" style="width: 80px;" :header="$t('upload_bytes')" />
<Column :field="rxBytes" :header="$t('download_bytes')" /> <Column :field="rxBytes" style="width: 80px;" :header="$t('download_bytes')" />
<Column :field="lossRate" :header="$t('loss_rate')" /> <Column :field="lossRate" style="width: 60px;" :header="$t('loss_rate')" />
</DataTable> </DataTable>
</template> </template>
</Card> </Card>

View File

@@ -16,3 +16,7 @@ export async function retainNetworkInstance(instanceIds: string[]): Promise<stri
export async function collectNetworkInfos(): Promise<Record<string, NetworkInstanceRunningInfo>> { export async function collectNetworkInfos(): Promise<Record<string, NetworkInstanceRunningInfo>> {
return JSON.parse(await invoke<string>('collect_network_infos')) return JSON.parse(await invoke<string>('collect_network_infos'))
} }
export async function getOsHostname(): Promise<string> {
return await invoke('get_os_hostname')
}

View File

@@ -10,6 +10,7 @@ export interface NetworkConfig {
instance_id: string instance_id: string
virtual_ipv4: string virtual_ipv4: string
hostname?: string
network_name: string network_name: string
network_secret: string network_secret: string

View File

@@ -3,7 +3,7 @@ name = "easytier"
description = "A full meshed p2p VPN, connecting all your devices in one network with one command." description = "A full meshed p2p VPN, connecting all your devices in one network with one command."
homepage = "https://github.com/KKRainbow/EasyTier" homepage = "https://github.com/KKRainbow/EasyTier"
repository = "https://github.com/KKRainbow/EasyTier" repository = "https://github.com/KKRainbow/EasyTier"
version = "1.0.0" version = "1.0.1-pre"
edition = "2021" edition = "2021"
authors = ["kkrainbow"] authors = ["kkrainbow"]
keywords = ["vpn", "p2p", "network", "easytier"] keywords = ["vpn", "p2p", "network", "easytier"]
@@ -58,6 +58,8 @@ async-trait = "0.1.74"
dashmap = "5.5.3" dashmap = "5.5.3"
timedmap = "=1.0.1" timedmap = "=1.0.1"
regex = "1"
# for full-path zero-copy # for full-path zero-copy
zerocopy = { version = "0.7.32", features = ["derive", "simd"] } zerocopy = { version = "0.7.32", features = ["derive", "simd"] }
bytes = "1.5.0" bytes = "1.5.0"
@@ -125,7 +127,7 @@ network-interface = "1.1.1"
pathfinding = "4.9.1" pathfinding = "4.9.1"
# for encryption # for encryption
boringtun = { git = "https://github.com/EasyTier/boringtun.git", optional = true } boringtun = { git = "https://github.com/EasyTier/boringtun.git", optional = true, rev = "449204c" }
ring = { version = "0.17", optional = true } ring = { version = "0.17", optional = true }
bitflags = "2.5" bitflags = "2.5"
aes-gcm = { version = "0.10.3", optional = true } aes-gcm = { version = "0.10.3", optional = true }

View File

@@ -14,6 +14,9 @@ pub trait ConfigLoader: Send + Sync {
fn get_id(&self) -> uuid::Uuid; fn get_id(&self) -> uuid::Uuid;
fn set_id(&self, id: uuid::Uuid); fn set_id(&self, id: uuid::Uuid);
fn get_hostname(&self) -> String;
fn set_hostname(&self, name: Option<String>);
fn get_inst_name(&self) -> String; fn get_inst_name(&self) -> String;
fn set_inst_name(&self, name: String); fn set_inst_name(&self, name: String);
@@ -152,6 +155,7 @@ pub struct Flags {
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)] #[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
struct Config { struct Config {
netns: Option<String>, netns: Option<String>,
hostname: Option<String>,
instance_name: Option<String>, instance_name: Option<String>,
instance_id: Option<uuid::Uuid>, instance_id: Option<uuid::Uuid>,
ipv4: Option<String>, ipv4: Option<String>,
@@ -190,6 +194,7 @@ impl TomlConfigLoader {
config_str, config_str config_str, config_str
) )
})?; })?;
Ok(TomlConfigLoader { Ok(TomlConfigLoader {
config: Arc::new(Mutex::new(config)), config: Arc::new(Mutex::new(config)),
}) })
@@ -216,6 +221,36 @@ impl ConfigLoader for TomlConfigLoader {
self.config.lock().unwrap().instance_name = Some(name); self.config.lock().unwrap().instance_name = Some(name);
} }
fn get_hostname(&self) -> String {
let hostname = self.config.lock().unwrap().hostname.clone();
match hostname {
Some(hostname) => {
if !hostname.is_empty() {
let re = regex::Regex::new(r"[^\u4E00-\u9FA5a-zA-Z0-9\-]*").unwrap();
let mut name = re.replace_all(&hostname, "").to_string();
if name.len() > 32 {
name = name.chars().take(32).collect::<String>();
}
if hostname != name {
self.set_hostname(Some(name.clone()));
}
name
} else {
self.set_hostname(None);
gethostname::gethostname().to_string_lossy().to_string()
}
}
None => gethostname::gethostname().to_string_lossy().to_string(),
}
}
fn set_hostname(&self, name: Option<String>) {
self.config.lock().unwrap().hostname = name;
}
fn get_netns(&self) -> Option<String> { fn get_netns(&self) -> Option<String> {
self.config.lock().unwrap().netns.clone() self.config.lock().unwrap().netns.clone()
} }

View File

@@ -54,7 +54,7 @@ pub struct GlobalCtx {
ip_collector: Arc<IPCollector>, ip_collector: Arc<IPCollector>,
hotname: AtomicCell<Option<String>>, hostname: String,
stun_info_collection: Box<dyn StunInfoCollectorTrait>, stun_info_collection: Box<dyn StunInfoCollectorTrait>,
@@ -80,6 +80,7 @@ impl GlobalCtx {
let id = config_fs.get_id(); let id = config_fs.get_id();
let network = config_fs.get_network_identity(); let network = config_fs.get_network_identity();
let net_ns = NetNS::new(config_fs.get_netns()); let net_ns = NetNS::new(config_fs.get_netns());
let hostname = config_fs.get_hostname();
let (event_bus, _) = tokio::sync::broadcast::channel(100); let (event_bus, _) = tokio::sync::broadcast::channel(100);
@@ -96,7 +97,7 @@ impl GlobalCtx {
ip_collector: Arc::new(IPCollector::new(net_ns)), ip_collector: Arc::new(IPCollector::new(net_ns)),
hotname: AtomicCell::new(None), hostname,
stun_info_collection: Box::new(StunInfoCollector::new_with_default_servers()), stun_info_collection: Box::new(StunInfoCollector::new_with_default_servers()),
@@ -165,15 +166,8 @@ impl GlobalCtx {
self.ip_collector.clone() self.ip_collector.clone()
} }
pub fn get_hostname(&self) -> Option<String> { pub fn get_hostname(&self) -> String {
if let Some(hostname) = self.hotname.take() { return self.hostname.clone();
self.hotname.store(Some(hostname.clone()));
return Some(hostname);
}
let hostname = gethostname::gethostname().to_string_lossy().to_string();
self.hotname.store(Some(hostname.clone()));
return Some(hostname);
} }
pub fn get_stun_info_collector(&self) -> impl StunInfoCollectorTrait + '_ { pub fn get_stun_info_collector(&self) -> impl StunInfoCollectorTrait + '_ {

View File

@@ -167,7 +167,6 @@ impl ManualConnectorManager {
let mut reconn_interval = tokio::time::interval(std::time::Duration::from_millis( let mut reconn_interval = tokio::time::interval(std::time::Duration::from_millis(
use_global_var!(MANUAL_CONNECTOR_RECONNECT_INTERVAL_MS), use_global_var!(MANUAL_CONNECTOR_RECONNECT_INTERVAL_MS),
)); ));
let mut reconn_tasks = JoinSet::new();
let (reconn_result_send, mut reconn_result_recv) = mpsc::channel(100); let (reconn_result_send, mut reconn_result_recv) = mpsc::channel(100);
loop { loop {
@@ -176,8 +175,8 @@ impl ManualConnectorManager {
if let Ok(event) = event { if let Ok(event) = event {
Self::handle_event(&event, data.clone()).await; Self::handle_event(&event, data.clone()).await;
} else { } else {
log::warn!("event_recv closed"); tracing::warn!(?event, "event_recv got error");
panic!("event_recv closed"); panic!("event_recv got error, err: {:?}", event);
} }
} }
@@ -193,7 +192,7 @@ impl ManualConnectorManager {
let insert_succ = data.reconnecting.insert(dead_url.clone()); let insert_succ = data.reconnecting.insert(dead_url.clone());
assert!(insert_succ); assert!(insert_succ);
reconn_tasks.spawn(async move { tokio::spawn(async move {
let reconn_ret = Self::conn_reconnect(data_clone.clone(), dead_url.clone(), connector.clone()).await; let reconn_ret = Self::conn_reconnect(data_clone.clone(), dead_url.clone(), connector.clone()).await;
sender.send(reconn_ret).await.unwrap(); sender.send(reconn_ret).await.unwrap();
@@ -205,8 +204,7 @@ impl ManualConnectorManager {
} }
ret = reconn_result_recv.recv() => { ret = reconn_result_recv.recv() => {
log::warn!("reconn_tasks done, out: {:?}", ret); log::warn!("reconn_tasks done, reconn result: {:?}", ret);
let _ = reconn_tasks.join_next().await.unwrap();
} }
} }
} }

View File

@@ -25,7 +25,7 @@ use humansize::format_size;
use tabled::settings::Style; use tabled::settings::Style;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)] #[command(name = "easytier-cli", author, version, about, long_about = None)]
struct Cli { struct Cli {
/// the instance name /// the instance name
#[arg(short = 'p', long, default_value = "127.0.0.1:15888")] #[arg(short = 'p', long, default_value = "127.0.0.1:15888")]
@@ -360,8 +360,15 @@ async fn main() -> Result<(), Error> {
.into_inner() .into_inner()
.vpn_portal_info .vpn_portal_info
.unwrap_or_default(); .unwrap_or_default();
println!("portal_name: {}\n", resp.vpn_type); println!("portal_name: {}", resp.vpn_type);
println!("client_config:{}", resp.client_config); println!(
r#"
############### client_config_start ###############
{}
############### client_config_end ###############
"#,
resp.client_config
);
println!("connected_clients:\n{:#?}", resp.connected_clients); println!("connected_clients:\n{:#?}", resp.connected_clients);
} }
} }

View File

@@ -41,7 +41,7 @@ use mimalloc_rust::*;
static GLOBAL_MIMALLOC: GlobalMiMalloc = GlobalMiMalloc; static GLOBAL_MIMALLOC: GlobalMiMalloc = GlobalMiMalloc;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)] #[command(name = "easytier-core", author, version, about, long_about = None)]
struct Cli { struct Cli {
#[arg( #[arg(
short, short,
@@ -111,6 +111,9 @@ struct Cli {
#[arg(long, help = "directory to store log files")] #[arg(long, help = "directory to store log files")]
file_log_dir: Option<String>, file_log_dir: Option<String>,
#[arg(long, help = "host name to identify this device")]
hostname: Option<String>,
#[arg( #[arg(
short = 'm', short = 'm',
long, long,
@@ -177,6 +180,9 @@ impl From<Cli> for TomlConfigLoader {
let cfg = TomlConfigLoader::default(); let cfg = TomlConfigLoader::default();
cfg.set_inst_name(cli.instance_name.clone()); cfg.set_inst_name(cli.instance_name.clone());
cfg.set_hostname(cli.hostname.clone());
cfg.set_network_identity(NetworkIdentity::new( cfg.set_network_identity(NetworkIdentity::new(
cli.network_name.clone(), cli.network_name.clone(),
cli.network_secret.clone(), cli.network_secret.clone(),
@@ -422,7 +428,7 @@ pub async fn async_main(cli: Cli) {
}); });
println!("Starting easytier with config:"); println!("Starting easytier with config:");
println!("############### TOML ##############\n"); println!("############### TOML ###############\n");
println!("{}", cfg.dump()); println!("{}", cfg.dump());
println!("-----------------------------------"); println!("-----------------------------------");

View File

@@ -101,7 +101,7 @@ impl RoutePeerInfo {
.map(|x| x.to_string()) .map(|x| x.to_string())
.chain(global_ctx.get_vpn_portal_cidr().map(|x| x.to_string())) .chain(global_ctx.get_vpn_portal_cidr().map(|x| x.to_string()))
.collect(), .collect(),
hostname: global_ctx.get_hostname(), hostname: Some(global_ctx.get_hostname()),
udp_stun_info: global_ctx udp_stun_info: global_ctx
.get_stun_info_collector() .get_stun_info_collector()
.get_stun_info() .get_stun_info()
@@ -138,11 +138,7 @@ impl Into<crate::rpc::Route> for RoutePeerInfo {
next_hop_peer_id: 0, next_hop_peer_id: 0,
cost: self.cost as i32, cost: self.cost as i32,
proxy_cidrs: self.proxy_cidrs.clone(), proxy_cidrs: self.proxy_cidrs.clone(),
hostname: if let Some(hostname) = &self.hostname { hostname: self.hostname.unwrap_or_default(),
hostname.clone()
} else {
"".to_string()
},
stun_info: { stun_info: {
let mut stun_info = StunInfo::default(); let mut stun_info = StunInfo::default();
if let Ok(udp_nat_type) = NatType::try_from(self.udp_stun_info as i32) { if let Ok(udp_nat_type) = NatType::try_from(self.udp_stun_info as i32) {

View File

@@ -52,7 +52,7 @@ impl SyncPeerInfo {
.map(|x| x.to_string()) .map(|x| x.to_string())
.chain(global_ctx.get_vpn_portal_cidr().map(|x| x.to_string())) .chain(global_ctx.get_vpn_portal_cidr().map(|x| x.to_string()))
.collect(), .collect(),
hostname: global_ctx.get_hostname(), hostname: Some(global_ctx.get_hostname()),
udp_stun_info: global_ctx udp_stun_info: global_ctx
.get_stun_info_collector() .get_stun_info_collector()
.get_stun_info() .get_stun_info()
@@ -585,11 +585,7 @@ impl Route for BasicRoute {
route.next_hop_peer_id = route_info.peer_id; route.next_hop_peer_id = route_info.peer_id;
route.cost = route_info.cost as i32; route.cost = route_info.cost as i32;
route.proxy_cidrs = route_info.proxy_cidrs.clone(); route.proxy_cidrs = route_info.proxy_cidrs.clone();
route.hostname = if let Some(hostname) = &route_info.hostname { route.hostname = route_info.hostname.clone().unwrap_or_default();
hostname.clone()
} else {
"".to_string()
};
let mut stun_info = StunInfo::default(); let mut stun_info = StunInfo::default();
if let Ok(udp_nat_type) = NatType::try_from(route_info.udp_stun_info as i32) { if let Ok(udp_nat_type) = NatType::try_from(route_info.udp_stun_info as i32) {

View File

@@ -264,32 +264,35 @@ impl VpnPortal for WireGuard {
break; break;
} }
let vpn_cfg = global_ctx.config.get_vpn_portal_config().unwrap();
let client_cidr = vpn_cfg.client_cidr;
allow_ips.push(client_cidr.to_string());
let allow_ips = allow_ips let allow_ips = allow_ips
.into_iter() .into_iter()
.map(|x| x.to_string()) .map(|x| x.to_string())
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(","); .join(",");
let vpn_cfg = global_ctx.config.get_vpn_portal_config().unwrap();
let client_cidr = vpn_cfg.client_cidr;
let cfg = self.inner.as_ref().unwrap().wg_config.clone(); let cfg = self.inner.as_ref().unwrap().wg_config.clone();
let cfg_str = format!( let cfg_str = format!(
r#" r#"
[Interface] [Interface]
PrivateKey = {peer_secret_key} PrivateKey = {peer_secret_key}
Address = {client_cidr} # should assign an ip from this cidr manually Address = {address} # should assign an ip from this cidr manually
[Peer] [Peer]
PublicKey = {my_public_key} PublicKey = {my_public_key}
AllowedIPs = {allow_ips} AllowedIPs = {allow_ips}
Endpoint = {listenr_addr} # should be the public ip of the vpn server Endpoint = {listenr_addr} # should be the public ip(or domain) of the vpn server
PersistentKeepalive = 25
"#, "#,
peer_secret_key = BASE64_STANDARD.encode(cfg.peer_secret_key()), peer_secret_key = BASE64_STANDARD.encode(cfg.peer_secret_key()),
my_public_key = BASE64_STANDARD.encode(cfg.my_public_key()), my_public_key = BASE64_STANDARD.encode(cfg.my_public_key()),
listenr_addr = self.inner.as_ref().unwrap().listenr_addr, listenr_addr = self.inner.as_ref().unwrap().listenr_addr,
allow_ips = allow_ips, allow_ips = allow_ips,
client_cidr = client_cidr, address = client_cidr.first_address().to_string() + "/32",
); );
cfg_str cfg_str