mirror of
https://mirror.suhoan.cn/https://github.com/EasyTier/EasyTier.git
synced 2025-12-12 12:47:25 +08:00
Feat/web (Patchset 4) (#460)
support basic functions in frontend 1. create/del network 2. inspect network running status
This commit is contained in:
@@ -9,6 +9,28 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::tunnel::generate_digest_from_str;
|
||||
|
||||
pub type Flags = crate::proto::common::FlagsInConfig;
|
||||
|
||||
pub fn gen_default_flags() -> Flags {
|
||||
Flags {
|
||||
default_protocol: "tcp".to_string(),
|
||||
dev_name: "".to_string(),
|
||||
enable_encryption: true,
|
||||
enable_ipv6: true,
|
||||
mtu: 1380,
|
||||
latency_first: false,
|
||||
enable_exit_node: false,
|
||||
no_tun: false,
|
||||
use_smoltcp: false,
|
||||
foreign_network_whitelist: "*".to_string(),
|
||||
disable_p2p: false,
|
||||
relay_all_peer_rpc: false,
|
||||
disable_udp_hole_punching: false,
|
||||
ipv6_listener: "udp://[::]:0".to_string(),
|
||||
multi_thread: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[auto_impl::auto_impl(Box, &)]
|
||||
pub trait ConfigLoader: Send + Sync {
|
||||
fn get_id(&self) -> uuid::Uuid;
|
||||
@@ -127,7 +149,7 @@ pub struct PeerConfig {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
||||
pub struct NetworkConfig {
|
||||
pub struct ProxyNetworkConfig {
|
||||
pub cidr: String,
|
||||
pub allow: Option<Vec<String>>,
|
||||
}
|
||||
@@ -150,42 +172,6 @@ pub struct VpnPortalConfig {
|
||||
pub wireguard_listen: SocketAddr,
|
||||
}
|
||||
|
||||
// Flags is used to control the behavior of the program
|
||||
#[derive(derivative::Derivative, Deserialize, Serialize)]
|
||||
#[derivative(Debug, Clone, PartialEq, Default)]
|
||||
pub struct Flags {
|
||||
#[derivative(Default(value = "\"tcp\".to_string()"))]
|
||||
pub default_protocol: String,
|
||||
#[derivative(Default(value = "\"\".to_string()"))]
|
||||
pub dev_name: String,
|
||||
#[derivative(Default(value = "true"))]
|
||||
pub enable_encryption: bool,
|
||||
#[derivative(Default(value = "true"))]
|
||||
pub enable_ipv6: bool,
|
||||
#[derivative(Default(value = "1380"))]
|
||||
pub mtu: u16,
|
||||
#[derivative(Default(value = "false"))]
|
||||
pub latency_first: bool,
|
||||
#[derivative(Default(value = "false"))]
|
||||
pub enable_exit_node: bool,
|
||||
#[derivative(Default(value = "false"))]
|
||||
pub no_tun: bool,
|
||||
#[derivative(Default(value = "false"))]
|
||||
pub use_smoltcp: bool,
|
||||
#[derivative(Default(value = "\"*\".to_string()"))]
|
||||
pub foreign_network_whitelist: String,
|
||||
#[derivative(Default(value = "false"))]
|
||||
pub disable_p2p: bool,
|
||||
#[derivative(Default(value = "false"))]
|
||||
pub relay_all_peer_rpc: bool,
|
||||
#[derivative(Default(value = "false"))]
|
||||
pub disable_udp_hole_punching: bool,
|
||||
#[derivative(Default(value = "\"udp://[::]:0\".to_string()"))]
|
||||
pub ipv6_listener: String,
|
||||
#[derivative(Default(value = "false"))]
|
||||
pub multi_thread: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
||||
struct Config {
|
||||
netns: Option<String>,
|
||||
@@ -199,7 +185,7 @@ struct Config {
|
||||
exit_nodes: Option<Vec<Ipv4Addr>>,
|
||||
|
||||
peer: Option<Vec<PeerConfig>>,
|
||||
proxy_network: Option<Vec<NetworkConfig>>,
|
||||
proxy_network: Option<Vec<ProxyNetworkConfig>>,
|
||||
|
||||
file_logger: Option<FileLoggerConfig>,
|
||||
console_logger: Option<ConsoleLoggerConfig>,
|
||||
@@ -255,7 +241,7 @@ impl TomlConfigLoader {
|
||||
}
|
||||
|
||||
fn gen_flags(mut flags_hashmap: serde_json::Map<String, serde_json::Value>) -> Flags {
|
||||
let default_flags_json = serde_json::to_string(&Flags::default()).unwrap();
|
||||
let default_flags_json = serde_json::to_string(&gen_default_flags()).unwrap();
|
||||
let default_flags_hashmap =
|
||||
serde_json::from_str::<serde_json::Map<String, serde_json::Value>>(&default_flags_json)
|
||||
.unwrap();
|
||||
@@ -372,7 +358,7 @@ impl ConfigLoader for TomlConfigLoader {
|
||||
.proxy_network
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.push(NetworkConfig {
|
||||
.push(ProxyNetworkConfig {
|
||||
cidr: cidr_str,
|
||||
allow: None,
|
||||
});
|
||||
@@ -527,7 +513,7 @@ impl ConfigLoader for TomlConfigLoader {
|
||||
}
|
||||
|
||||
fn dump(&self) -> String {
|
||||
let default_flags_json = serde_json::to_string(&Flags::default()).unwrap();
|
||||
let default_flags_json = serde_json::to_string(&gen_default_flags()).unwrap();
|
||||
let default_flags_hashmap =
|
||||
serde_json::from_str::<serde_json::Map<String, serde_json::Value>>(&default_flags_json)
|
||||
.unwrap();
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
extern crate rust_i18n;
|
||||
|
||||
use std::{
|
||||
net::{Ipv4Addr, SocketAddr},
|
||||
net::{Ipv4Addr, SocketAddr},
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
@@ -505,7 +505,7 @@ impl From<Cli> for TomlConfigLoader {
|
||||
f.latency_first = cli.latency_first;
|
||||
f.dev_name = cli.dev_name.unwrap_or_default();
|
||||
if let Some(mtu) = cli.mtu {
|
||||
f.mtu = mtu;
|
||||
f.mtu = mtu as u32;
|
||||
}
|
||||
f.enable_exit_node = cli.enable_exit_node;
|
||||
f.no_tun = cli.no_tun || cfg!(not(feature = "tun"));
|
||||
@@ -653,13 +653,13 @@ pub fn handle_event(mut events: EventBusSubscriber) -> tokio::task::JoinHandle<(
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn win_service_event_loop(
|
||||
fn win_service_event_loop(
|
||||
stop_notify: std::sync::Arc<tokio::sync::Notify>,
|
||||
inst: launcher::NetworkInstance,
|
||||
status_handle: windows_service::service_control_handler::ServiceStatusHandle,
|
||||
) {
|
||||
use tokio::runtime::Runtime;
|
||||
inst: launcher::NetworkInstance,
|
||||
status_handle: windows_service::service_control_handler::ServiceStatusHandle,
|
||||
) {
|
||||
use std::time::Duration;
|
||||
use tokio::runtime::Runtime;
|
||||
use windows_service::service::*;
|
||||
|
||||
std::thread::spawn(move || {
|
||||
@@ -699,26 +699,23 @@ fn win_service_event_loop(
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn win_service_main(_: Vec<std::ffi::OsString>) {
|
||||
use std::time::Duration;
|
||||
use windows_service::service_control_handler::*;
|
||||
use windows_service::service::*;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tokio::sync::Notify;
|
||||
|
||||
use windows_service::service::*;
|
||||
use windows_service::service_control_handler::*;
|
||||
|
||||
let cli = Cli::parse();
|
||||
let cfg = TomlConfigLoader::from(cli);
|
||||
|
||||
init_logger(&cfg, false).unwrap();
|
||||
init_logger(&cfg, false).unwrap();
|
||||
|
||||
let stop_notify_send = Arc::new(Notify::new());
|
||||
let stop_notify_recv = Arc::clone(&stop_notify_send);
|
||||
let event_handler = move |control_event| -> ServiceControlHandlerResult {
|
||||
match control_event {
|
||||
ServiceControl::Interrogate => {
|
||||
ServiceControlHandlerResult::NoError
|
||||
}
|
||||
ServiceControl::Stop =>
|
||||
{
|
||||
ServiceControl::Interrogate => ServiceControlHandlerResult::NoError,
|
||||
ServiceControl::Stop => {
|
||||
stop_notify_send.notify_one();
|
||||
ServiceControlHandlerResult::NoError
|
||||
}
|
||||
@@ -736,10 +733,12 @@ fn win_service_main(_: Vec<std::ffi::OsString>) {
|
||||
process_id: None,
|
||||
};
|
||||
let mut inst = launcher::NetworkInstance::new(cfg).set_fetch_node_info(false);
|
||||
|
||||
inst.start().unwrap();
|
||||
status_handle.set_service_status(next_status).expect("set service status fail");
|
||||
win_service_event_loop(stop_notify_recv, inst, status_handle);
|
||||
|
||||
inst.start().unwrap();
|
||||
status_handle
|
||||
.set_service_status(next_status)
|
||||
.expect("set service status fail");
|
||||
win_service_event_loop(stop_notify_recv, inst, status_handle);
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
@@ -750,18 +749,19 @@ async fn main() {
|
||||
#[cfg(target_os = "windows")]
|
||||
match windows_service::service_dispatcher::start(String::new(), ffi_service_main) {
|
||||
Ok(_) => std::thread::park(),
|
||||
Err(e) =>
|
||||
{
|
||||
let should_panic = if let windows_service::Error::Winapi(ref io_error) = e {
|
||||
io_error.raw_os_error() != Some(0x427) // ERROR_FAILED_SERVICE_CONTROLLER_CONNECT
|
||||
} else { true };
|
||||
|
||||
if should_panic {
|
||||
panic!("SCM start an error: {}", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Err(e) => {
|
||||
let should_panic = if let windows_service::Error::Winapi(ref io_error) = e {
|
||||
io_error.raw_os_error() != Some(0x427) // ERROR_FAILED_SERVICE_CONTROLLER_CONNECT
|
||||
} else {
|
||||
true
|
||||
};
|
||||
|
||||
if should_panic {
|
||||
panic!("SCM start an error: {}", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let cli = Cli::parse();
|
||||
|
||||
setup_panic_handler();
|
||||
|
||||
@@ -5,7 +5,10 @@ use std::{
|
||||
|
||||
use crate::{
|
||||
common::{
|
||||
config::{ConfigLoader, TomlConfigLoader},
|
||||
config::{
|
||||
gen_default_flags, ConfigLoader, NetworkIdentity, PeerConfig, TomlConfigLoader,
|
||||
VpnPortalConfig,
|
||||
},
|
||||
constants::EASYTIER_VERSION,
|
||||
global_ctx::{EventBusSubscriber, GlobalCtxEvent},
|
||||
stun::StunInfoCollectorTrait,
|
||||
@@ -14,6 +17,7 @@ use crate::{
|
||||
peers::rpc_service::PeerManagerRpcService,
|
||||
proto::cli::{list_peer_route_pair, PeerInfo, Route},
|
||||
};
|
||||
use anyhow::Context;
|
||||
use chrono::{DateTime, Local};
|
||||
use tokio::{sync::broadcast, task::JoinSet};
|
||||
|
||||
@@ -388,3 +392,132 @@ impl NetworkInstance {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type NetworkingMethod = crate::proto::web::NetworkingMethod;
|
||||
pub type NetworkConfig = crate::proto::web::NetworkConfig;
|
||||
|
||||
impl NetworkConfig {
|
||||
pub fn gen_config(&self) -> Result<TomlConfigLoader, anyhow::Error> {
|
||||
let cfg = TomlConfigLoader::default();
|
||||
cfg.set_id(
|
||||
self.instance_id
|
||||
.clone()
|
||||
.unwrap_or(uuid::Uuid::new_v4().to_string())
|
||||
.parse()
|
||||
.with_context(|| format!("failed to parse instance id: {:?}", self.instance_id))?,
|
||||
);
|
||||
cfg.set_hostname(self.hostname.clone());
|
||||
cfg.set_dhcp(self.dhcp.unwrap_or_default());
|
||||
cfg.set_inst_name(self.network_name.clone().unwrap_or_default());
|
||||
cfg.set_network_identity(NetworkIdentity::new(
|
||||
self.network_name.clone().unwrap_or_default(),
|
||||
self.network_secret.clone().unwrap_or_default(),
|
||||
));
|
||||
|
||||
if !cfg.get_dhcp() {
|
||||
let virtual_ipv4 = self.virtual_ipv4.clone().unwrap_or_default();
|
||||
if virtual_ipv4.len() > 0 {
|
||||
let ip = format!("{}/{}", virtual_ipv4, self.network_length.unwrap_or(24))
|
||||
.parse()
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"failed to parse ipv4 inet address: {}, {:?}",
|
||||
virtual_ipv4, self.network_length
|
||||
)
|
||||
})?;
|
||||
cfg.set_ipv4(Some(ip));
|
||||
}
|
||||
}
|
||||
|
||||
match NetworkingMethod::try_from(self.networking_method.unwrap_or_default())
|
||||
.unwrap_or_default()
|
||||
{
|
||||
NetworkingMethod::PublicServer => {
|
||||
let public_server_url = self.public_server_url.clone().unwrap_or_default();
|
||||
cfg.set_peers(vec![PeerConfig {
|
||||
uri: public_server_url.parse().with_context(|| {
|
||||
format!("failed to parse public server uri: {}", public_server_url)
|
||||
})?,
|
||||
}]);
|
||||
}
|
||||
NetworkingMethod::Manual => {
|
||||
let mut peers = vec![];
|
||||
for peer_url in self.peer_urls.iter() {
|
||||
if peer_url.is_empty() {
|
||||
continue;
|
||||
}
|
||||
peers.push(PeerConfig {
|
||||
uri: peer_url
|
||||
.parse()
|
||||
.with_context(|| format!("failed to parse peer uri: {}", peer_url))?,
|
||||
});
|
||||
}
|
||||
|
||||
cfg.set_peers(peers);
|
||||
}
|
||||
NetworkingMethod::Standalone => {}
|
||||
}
|
||||
|
||||
let mut listener_urls = vec![];
|
||||
for listener_url in self.listener_urls.iter() {
|
||||
if listener_url.is_empty() {
|
||||
continue;
|
||||
}
|
||||
listener_urls.push(
|
||||
listener_url
|
||||
.parse()
|
||||
.with_context(|| format!("failed to parse listener uri: {}", listener_url))?,
|
||||
);
|
||||
}
|
||||
cfg.set_listeners(listener_urls);
|
||||
|
||||
for n in self.proxy_cidrs.iter() {
|
||||
cfg.add_proxy_cidr(
|
||||
n.parse()
|
||||
.with_context(|| format!("failed to parse proxy network: {}", n))?,
|
||||
);
|
||||
}
|
||||
|
||||
cfg.set_rpc_portal(
|
||||
format!("0.0.0.0:{}", self.rpc_port.unwrap_or_default())
|
||||
.parse()
|
||||
.with_context(|| format!("failed to parse rpc portal port: {:?}", self.rpc_port))?,
|
||||
);
|
||||
|
||||
if self.enable_vpn_portal.unwrap_or_default() {
|
||||
let cidr = format!(
|
||||
"{}/{}",
|
||||
self.vpn_portal_client_network_addr
|
||||
.clone()
|
||||
.unwrap_or_default(),
|
||||
self.vpn_portal_client_network_len.unwrap_or(24)
|
||||
);
|
||||
cfg.set_vpn_portal_config(VpnPortalConfig {
|
||||
client_cidr: cidr
|
||||
.parse()
|
||||
.with_context(|| format!("failed to parse vpn portal client cidr: {}", cidr))?,
|
||||
wireguard_listen: format!(
|
||||
"0.0.0.0:{}",
|
||||
self.vpn_portal_listen_port.unwrap_or_default()
|
||||
)
|
||||
.parse()
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"failed to parse vpn portal wireguard listen port. {:?}",
|
||||
self.vpn_portal_listen_port
|
||||
)
|
||||
})?,
|
||||
});
|
||||
}
|
||||
let mut flags = gen_default_flags();
|
||||
if let Some(latency_first) = self.latency_first {
|
||||
flags.latency_first = latency_first;
|
||||
}
|
||||
|
||||
if let Some(dev_name) = self.dev_name.clone() {
|
||||
flags.dev_name = dev_name;
|
||||
}
|
||||
cfg.set_flags(flags);
|
||||
Ok(cfg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,24 @@ import "error.proto";
|
||||
|
||||
package common;
|
||||
|
||||
message FlagsInConfig {
|
||||
string default_protocol = 1;
|
||||
string dev_name = 2;
|
||||
bool enable_encryption = 3;
|
||||
bool enable_ipv6 = 4;
|
||||
uint32 mtu = 5;
|
||||
bool latency_first = 6;
|
||||
bool enable_exit_node = 7;
|
||||
bool no_tun = 8;
|
||||
bool use_smoltcp = 9;
|
||||
string foreign_network_whitelist = 10;
|
||||
bool disable_p2p = 11;
|
||||
bool relay_all_peer_rpc = 12;
|
||||
bool disable_udp_hole_punching = 13;
|
||||
string ipv6_listener = 14;
|
||||
bool multi_thread = 15;
|
||||
}
|
||||
|
||||
message RpcDescriptor {
|
||||
// allow same service registered multiple times in different domain
|
||||
string domain_name = 1;
|
||||
@@ -45,8 +63,10 @@ message RpcPacket {
|
||||
message Void {}
|
||||
|
||||
message UUID {
|
||||
uint64 high = 1;
|
||||
uint64 low = 2;
|
||||
uint32 part1 = 1;
|
||||
uint32 part2 = 2;
|
||||
uint32 part3 = 3;
|
||||
uint32 part4 = 4;
|
||||
}
|
||||
|
||||
enum NatType {
|
||||
|
||||
@@ -7,13 +7,21 @@ include!(concat!(env!("OUT_DIR"), "/common.rs"));
|
||||
impl From<uuid::Uuid> for Uuid {
|
||||
fn from(uuid: uuid::Uuid) -> Self {
|
||||
let (high, low) = uuid.as_u64_pair();
|
||||
Uuid { low, high }
|
||||
Uuid {
|
||||
part1: (high >> 32) as u32,
|
||||
part2: (high & 0xFFFFFFFF) as u32,
|
||||
part3: (low >> 32) as u32,
|
||||
part4: (low & 0xFFFFFFFF) as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Uuid> for uuid::Uuid {
|
||||
fn from(uuid: Uuid) -> Self {
|
||||
uuid::Uuid::from_u64_pair(uuid.high, uuid.low)
|
||||
uuid::Uuid::from_u64_pair(
|
||||
(u64::from(uuid.part1) << 32) | u64::from(uuid.part2),
|
||||
(u64::from(uuid.part3) << 32) | u64::from(uuid.part4),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,42 @@ import "cli.proto";
|
||||
|
||||
package web;
|
||||
|
||||
enum NetworkingMethod {
|
||||
PublicServer = 0;
|
||||
Manual = 1;
|
||||
Standalone = 2;
|
||||
}
|
||||
|
||||
message NetworkConfig {
|
||||
optional string instance_id = 1;
|
||||
|
||||
optional bool dhcp = 2;
|
||||
optional string virtual_ipv4 = 3;
|
||||
optional int32 network_length = 4;
|
||||
optional string hostname = 5;
|
||||
optional string network_name = 6;
|
||||
optional string network_secret = 7;
|
||||
optional NetworkingMethod networking_method = 8;
|
||||
|
||||
optional string public_server_url = 9;
|
||||
repeated string peer_urls = 10;
|
||||
|
||||
repeated string proxy_cidrs = 11;
|
||||
|
||||
optional bool enable_vpn_portal = 12;
|
||||
optional int32 vpn_portal_listen_port = 13;
|
||||
optional string vpn_portal_client_network_addr = 14;
|
||||
optional int32 vpn_portal_client_network_len = 15;
|
||||
|
||||
optional bool advanced_settings = 16;
|
||||
|
||||
repeated string listener_urls = 17;
|
||||
optional int32 rpc_port = 18;
|
||||
optional bool latency_first = 19;
|
||||
|
||||
optional string dev_name = 20;
|
||||
}
|
||||
|
||||
message MyNodeInfo {
|
||||
common.Ipv4Addr virtual_ipv4 = 1;
|
||||
string hostname = 2;
|
||||
@@ -52,10 +88,11 @@ service WebServerService {
|
||||
}
|
||||
|
||||
message ValidateConfigRequest {
|
||||
string config = 1;
|
||||
NetworkConfig config = 1;
|
||||
}
|
||||
|
||||
message ValidateConfigResponse {
|
||||
string toml_config = 1;
|
||||
}
|
||||
|
||||
message RunNetworkInstanceRequest {
|
||||
|
||||
@@ -234,13 +234,13 @@ mod tests {
|
||||
async fn ipv6_domain_pingpong() {
|
||||
let listener = QUICTunnelListener::new("quic://[::1]:31016".parse().unwrap());
|
||||
let mut connector =
|
||||
QUICTunnelConnector::new("quic://test.kkrainbow.top:31016".parse().unwrap());
|
||||
QUICTunnelConnector::new("quic://test.easytier.top:31016".parse().unwrap());
|
||||
connector.set_ip_version(IpVersion::V6);
|
||||
_tunnel_pingpong(listener, connector).await;
|
||||
|
||||
let listener = QUICTunnelListener::new("quic://127.0.0.1:31016".parse().unwrap());
|
||||
let mut connector =
|
||||
QUICTunnelConnector::new("quic://test.kkrainbow.top:31016".parse().unwrap());
|
||||
QUICTunnelConnector::new("quic://test.easytier.top:31016".parse().unwrap());
|
||||
connector.set_ip_version(IpVersion::V4);
|
||||
_tunnel_pingpong(listener, connector).await;
|
||||
}
|
||||
|
||||
@@ -248,13 +248,13 @@ mod tests {
|
||||
async fn ipv6_domain_pingpong() {
|
||||
let listener = TcpTunnelListener::new("tcp://[::1]:31015".parse().unwrap());
|
||||
let mut connector =
|
||||
TcpTunnelConnector::new("tcp://test.kkrainbow.top:31015".parse().unwrap());
|
||||
TcpTunnelConnector::new("tcp://test.easytier.top:31015".parse().unwrap());
|
||||
connector.set_ip_version(IpVersion::V6);
|
||||
_tunnel_pingpong(listener, connector).await;
|
||||
|
||||
let listener = TcpTunnelListener::new("tcp://127.0.0.1:31015".parse().unwrap());
|
||||
let mut connector =
|
||||
TcpTunnelConnector::new("tcp://test.kkrainbow.top:31015".parse().unwrap());
|
||||
TcpTunnelConnector::new("tcp://test.easytier.top:31015".parse().unwrap());
|
||||
connector.set_ip_version(IpVersion::V4);
|
||||
_tunnel_pingpong(listener, connector).await;
|
||||
}
|
||||
|
||||
@@ -905,13 +905,13 @@ mod tests {
|
||||
async fn ipv6_domain_pingpong() {
|
||||
let listener = UdpTunnelListener::new("udp://[::1]:31016".parse().unwrap());
|
||||
let mut connector =
|
||||
UdpTunnelConnector::new("udp://test.kkrainbow.top:31016".parse().unwrap());
|
||||
UdpTunnelConnector::new("udp://test.easytier.top:31016".parse().unwrap());
|
||||
connector.set_ip_version(IpVersion::V6);
|
||||
_tunnel_pingpong(listener, connector).await;
|
||||
|
||||
let listener = UdpTunnelListener::new("udp://127.0.0.1:31016".parse().unwrap());
|
||||
let mut connector =
|
||||
UdpTunnelConnector::new("udp://test.kkrainbow.top:31016".parse().unwrap());
|
||||
UdpTunnelConnector::new("udp://test.easytier.top:31016".parse().unwrap());
|
||||
connector.set_ip_version(IpVersion::V4);
|
||||
_tunnel_pingpong(listener, connector).await;
|
||||
}
|
||||
|
||||
@@ -895,14 +895,14 @@ pub mod tests {
|
||||
let (server_cfg, client_cfg) = create_wg_config();
|
||||
let listener = WgTunnelListener::new("wg://[::1]:31016".parse().unwrap(), server_cfg);
|
||||
let mut connector =
|
||||
WgTunnelConnector::new("wg://test.kkrainbow.top:31016".parse().unwrap(), client_cfg);
|
||||
WgTunnelConnector::new("wg://test.easytier.top:31016".parse().unwrap(), client_cfg);
|
||||
connector.set_ip_version(IpVersion::V6);
|
||||
_tunnel_pingpong(listener, connector).await;
|
||||
|
||||
let (server_cfg, client_cfg) = create_wg_config();
|
||||
let listener = WgTunnelListener::new("wg://127.0.0.1:31016".parse().unwrap(), server_cfg);
|
||||
let mut connector =
|
||||
WgTunnelConnector::new("wg://test.kkrainbow.top:31016".parse().unwrap(), client_cfg);
|
||||
WgTunnelConnector::new("wg://test.easytier.top:31016".parse().unwrap(), client_cfg);
|
||||
connector.set_ip_version(IpVersion::V4);
|
||||
_tunnel_pingpong(listener, connector).await;
|
||||
}
|
||||
|
||||
@@ -91,8 +91,8 @@ impl WebClientService for Controller {
|
||||
_: BaseController,
|
||||
req: ValidateConfigRequest,
|
||||
) -> Result<ValidateConfigResponse, rpc_types::error::Error> {
|
||||
let _ = TomlConfigLoader::new_from_str(&req.config)?;
|
||||
Ok(ValidateConfigResponse {})
|
||||
let toml_config = req.config.unwrap_or_default().gen_config()?.dump();
|
||||
Ok(ValidateConfigResponse { toml_config })
|
||||
}
|
||||
|
||||
async fn run_network_instance(
|
||||
|
||||
Reference in New Issue
Block a user