mirror of
https://github.com/EasyTier/EasyTier.git
synced 2024-11-16 11:42:27 +08:00
commit
bee9565225
|
@ -235,15 +235,13 @@ static INSTANCE_MAP: once_cell::sync::Lazy<DashMap<String, NetworkInstance>> =
|
||||||
|
|
||||||
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
|
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
fn parse_network_config(cfg: &str) -> Result<String, String> {
|
fn parse_network_config(cfg: NetworkConfig) -> Result<String, String> {
|
||||||
let cfg: NetworkConfig = serde_json::from_str(cfg).map_err(|e| e.to_string())?;
|
|
||||||
let toml = cfg.gen_config().map_err(|e| e.to_string())?;
|
let toml = cfg.gen_config().map_err(|e| e.to_string())?;
|
||||||
Ok(toml.dump())
|
Ok(toml.dump())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
fn run_network_instance(cfg: &str) -> Result<String, String> {
|
fn run_network_instance(cfg: NetworkConfig) -> Result<(), String> {
|
||||||
let cfg: NetworkConfig = serde_json::from_str(cfg).map_err(|e| e.to_string())?;
|
|
||||||
if INSTANCE_MAP.contains_key(&cfg.instance_id) {
|
if INSTANCE_MAP.contains_key(&cfg.instance_id) {
|
||||||
return Err("instance already exists".to_string());
|
return Err("instance already exists".to_string());
|
||||||
}
|
}
|
||||||
|
@ -254,13 +252,11 @@ fn run_network_instance(cfg: &str) -> Result<String, String> {
|
||||||
|
|
||||||
println!("instance {} started", instance_id);
|
println!("instance {} started", instance_id);
|
||||||
INSTANCE_MAP.insert(instance_id, instance);
|
INSTANCE_MAP.insert(instance_id, instance);
|
||||||
Ok("".to_string())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
fn retain_network_instance(instance_ids: &str) -> Result<(), String> {
|
fn retain_network_instance(instance_ids: Vec<String>) -> Result<(), String> {
|
||||||
let instance_ids: Vec<String> =
|
|
||||||
serde_json::from_str(instance_ids).map_err(|e| e.to_string())?;
|
|
||||||
let _ = INSTANCE_MAP.retain(|k, _| instance_ids.contains(k));
|
let _ = INSTANCE_MAP.retain(|k, _| instance_ids.contains(k));
|
||||||
println!(
|
println!(
|
||||||
"instance {:?} retained",
|
"instance {:?} retained",
|
||||||
|
@ -273,14 +269,14 @@ fn retain_network_instance(instance_ids: &str) -> Result<(), String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
fn collect_network_infos() -> Result<String, String> {
|
fn collect_network_infos() -> Result<BTreeMap<String, NetworkInstanceRunningInfo>, String> {
|
||||||
let mut ret = BTreeMap::new();
|
let mut ret = BTreeMap::new();
|
||||||
for instance in INSTANCE_MAP.iter() {
|
for instance in INSTANCE_MAP.iter() {
|
||||||
if let Some(info) = instance.get_running_info() {
|
if let Some(info) = instance.get_running_info() {
|
||||||
ret.insert(instance.key().clone(), info);
|
ret.insert(instance.key().clone(), info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(serde_json::to_string(&ret).map_err(|e| e.to_string())?)
|
Ok(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { NodeInfo } from '~/types/network'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
instanceId?: string
|
instanceId?: string
|
||||||
}>()
|
}>()
|
||||||
|
@ -92,7 +94,7 @@ function lossRate(info: any) {
|
||||||
|
|
||||||
const myNodeInfo = computed(() => {
|
const myNodeInfo = computed(() => {
|
||||||
if (!curNetworkInst.value)
|
if (!curNetworkInst.value)
|
||||||
return {}
|
return {} as NodeInfo
|
||||||
|
|
||||||
return curNetworkInst.value.detail?.my_node_info
|
return curNetworkInst.value.detail?.my_node_info
|
||||||
})
|
})
|
||||||
|
@ -233,7 +235,7 @@ onUnmounted(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
const dialogContent = ref('')
|
const dialogContent = ref<any>('')
|
||||||
|
|
||||||
function showVpnPortalConfig() {
|
function showVpnPortalConfig() {
|
||||||
const my_node_info = myNodeInfo.value
|
const my_node_info = myNodeInfo.value
|
||||||
|
|
|
@ -1,26 +1,22 @@
|
||||||
import { invoke } from '@tauri-apps/api/tauri'
|
import { invoke } from '@tauri-apps/api/tauri'
|
||||||
import type { NetworkConfig } from '~/types/network'
|
import type { NetworkConfig, NetworkInstanceRunningInfo } from '~/types/network'
|
||||||
|
|
||||||
export async function parseNetworkConfig(cfg: NetworkConfig): Promise<string> {
|
export async function parseNetworkConfig(cfg: NetworkConfig) {
|
||||||
const ret: string = await invoke('parse_network_config', { cfg: JSON.stringify(cfg) })
|
return invoke<string>('parse_network_config', { cfg })
|
||||||
return ret
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function runNetworkInstance(cfg: NetworkConfig) {
|
export async function runNetworkInstance(cfg: NetworkConfig) {
|
||||||
const ret: string = await invoke('run_network_instance', { cfg: JSON.stringify(cfg) })
|
return invoke('run_network_instance', { cfg })
|
||||||
return ret
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function retainNetworkInstance(instanceIds: Array<string>) {
|
export async function retainNetworkInstance(instanceIds: string[]) {
|
||||||
const ret: string = await invoke('retain_network_instance', { instanceIds: JSON.stringify(instanceIds) })
|
return invoke('retain_network_instance', { instanceIds })
|
||||||
return ret
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function collectNetworkInfos() {
|
export async function collectNetworkInfos() {
|
||||||
const ret: string = await invoke('collect_network_infos', {})
|
return await invoke<Record<string, NetworkInstanceRunningInfo>>('collect_network_infos')
|
||||||
return JSON.parse(ret)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getOsHostname(): Promise<string> {
|
export async function getOsHostname() {
|
||||||
return await invoke('get_os_hostname')
|
return await invoke<string>('get_os_hostname')
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type { NetworkConfig, NetworkInstance } from '~/types/network'
|
import type { NetworkConfig, NetworkInstance, NetworkInstanceRunningInfo } from '~/types/network'
|
||||||
import { DEFAULT_NETWORK_CONFIG } from '~/types/network'
|
import { DEFAULT_NETWORK_CONFIG } from '~/types/network'
|
||||||
|
|
||||||
export const useNetworkStore = defineStore('networkStore', {
|
export const useNetworkStore = defineStore('networkStore', {
|
||||||
|
@ -13,7 +13,7 @@ export const useNetworkStore = defineStore('networkStore', {
|
||||||
// uuid -> instance
|
// uuid -> instance
|
||||||
instances: {} as Record<string, NetworkInstance>,
|
instances: {} as Record<string, NetworkInstance>,
|
||||||
|
|
||||||
networkInfos: {} as Record<string, any>,
|
networkInfos: {} as Record<string, NetworkInstanceRunningInfo>,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -56,35 +56,36 @@ export const useNetworkStore = defineStore('networkStore', {
|
||||||
instance_id: instanceId,
|
instance_id: instanceId,
|
||||||
running: false,
|
running: false,
|
||||||
error_msg: '',
|
error_msg: '',
|
||||||
detail: {},
|
detail: {} as NetworkInstanceRunningInfo,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
updateWithNetworkInfos(networkInfos: Record<string, any>) {
|
updateWithNetworkInfos(networkInfos: Record<string, NetworkInstanceRunningInfo>) {
|
||||||
this.networkInfos = networkInfos
|
this.networkInfos = networkInfos
|
||||||
for (const [instanceId, info] of Object.entries(networkInfos)) {
|
for (const [instanceId, info] of Object.entries(networkInfos)) {
|
||||||
if (this.instances[instanceId] === undefined)
|
if (this.instances[instanceId] === undefined)
|
||||||
this.addNetworkInstance(instanceId)
|
this.addNetworkInstance(instanceId)
|
||||||
|
|
||||||
this.instances[instanceId].running = info.running
|
this.instances[instanceId].running = info.running
|
||||||
this.instances[instanceId].error_msg = info.error_msg
|
this.instances[instanceId].error_msg = info.error_msg || ''
|
||||||
this.instances[instanceId].detail = info
|
this.instances[instanceId].detail = info
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
loadFromLocalStorage() {
|
loadFromLocalStorage() {
|
||||||
const networkList = JSON.parse(localStorage.getItem('networkList') || '[]')
|
let networkList: NetworkConfig[]
|
||||||
const result = []
|
|
||||||
for (const cfg of networkList) {
|
try {
|
||||||
result.push({
|
networkList = JSON.parse(localStorage.getItem('networkList') || '[]')
|
||||||
...DEFAULT_NETWORK_CONFIG,
|
networkList = networkList.map((cfg) => {
|
||||||
...cfg,
|
return { ...DEFAULT_NETWORK_CONFIG(), ...cfg } as NetworkConfig
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (result.length === 0)
|
catch {
|
||||||
result.push(DEFAULT_NETWORK_CONFIG)
|
networkList = [DEFAULT_NETWORK_CONFIG()]
|
||||||
|
}
|
||||||
|
|
||||||
this.networkList = result
|
this.networkList = networkList
|
||||||
this.curNetwork = this.networkList[0]
|
this.curNetwork = this.networkList[0]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -69,5 +69,92 @@ export interface NetworkInstance {
|
||||||
running: boolean
|
running: boolean
|
||||||
error_msg: string
|
error_msg: string
|
||||||
|
|
||||||
detail: any
|
detail: NetworkInstanceRunningInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NetworkInstanceRunningInfo {
|
||||||
|
my_node_info: NodeInfo
|
||||||
|
events: Record<string, any>
|
||||||
|
node_info: NodeInfo
|
||||||
|
routes: Route[]
|
||||||
|
peers: PeerInfo[]
|
||||||
|
peer_route_pairs: PeerRoutePair[]
|
||||||
|
running: boolean
|
||||||
|
error_msg?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NodeInfo {
|
||||||
|
virtual_ipv4: string
|
||||||
|
ips: {
|
||||||
|
public_ipv4: string
|
||||||
|
interface_ipv4s: string[]
|
||||||
|
public_ipv6: string
|
||||||
|
interface_ipv6s: string[]
|
||||||
|
listeners: {
|
||||||
|
serialization: string
|
||||||
|
scheme_end: number
|
||||||
|
username_end: number
|
||||||
|
host_start: number
|
||||||
|
host_end: number
|
||||||
|
host: any
|
||||||
|
port?: number
|
||||||
|
path_start: number
|
||||||
|
query_start?: number
|
||||||
|
fragment_start?: number
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
stun_info: StunInfo
|
||||||
|
listeners: string[]
|
||||||
|
vpn_portal_cfg?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StunInfo {
|
||||||
|
udp_nat_type: number
|
||||||
|
tcp_nat_type: number
|
||||||
|
last_update_time: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Route {
|
||||||
|
peer_id: number
|
||||||
|
ipv4_addr: string
|
||||||
|
next_hop_peer_id: number
|
||||||
|
cost: number
|
||||||
|
proxy_cidrs: string[]
|
||||||
|
hostname: string
|
||||||
|
stun_info?: StunInfo
|
||||||
|
inst_id: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PeerInfo {
|
||||||
|
peer_id: number
|
||||||
|
conns: PeerConnInfo[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PeerConnInfo {
|
||||||
|
conn_id: string
|
||||||
|
my_peer_id: number
|
||||||
|
peer_id: number
|
||||||
|
features: string[]
|
||||||
|
tunnel?: TunnelInfo
|
||||||
|
stats?: PeerConnStats
|
||||||
|
loss_rate: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PeerRoutePair {
|
||||||
|
route: Route
|
||||||
|
peer?: PeerInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TunnelInfo {
|
||||||
|
tunnel_type: string
|
||||||
|
local_addr: string
|
||||||
|
remote_addr: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PeerConnStats {
|
||||||
|
rx_bytes: number
|
||||||
|
tx_bytes: number
|
||||||
|
rx_packets: number
|
||||||
|
tx_packets: number
|
||||||
|
latency_us: number
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user