add chinese help message
Some checks are pending
EasyTier Core / pre_job (push) Waiting to run
EasyTier Core / build (linux-aarch64, ubuntu-latest, aarch64-unknown-linux-musl) (push) Blocked by required conditions
EasyTier Core / build (linux-arm, ubuntu-latest, arm-unknown-linux-musleabi) (push) Blocked by required conditions
EasyTier Core / build (linux-armhf, ubuntu-latest, arm-unknown-linux-musleabihf) (push) Blocked by required conditions
EasyTier Core / build (linux-armv7, ubuntu-latest, armv7-unknown-linux-musleabi) (push) Blocked by required conditions
EasyTier Core / build (linux-armv7hf, ubuntu-latest, armv7-unknown-linux-musleabihf) (push) Blocked by required conditions
EasyTier Core / build (linux-mips, ubuntu-latest, mips-unknown-linux-musl) (push) Blocked by required conditions
EasyTier Core / build (linux-mipsel, ubuntu-latest, mipsel-unknown-linux-musl) (push) Blocked by required conditions
EasyTier Core / build (linux-x86_64, ubuntu-latest, x86_64-unknown-linux-musl) (push) Blocked by required conditions
EasyTier Core / build (macos-aarch64, macos-latest, aarch64-apple-darwin) (push) Blocked by required conditions
EasyTier Core / build (macos-x86_64, macos-latest, x86_64-apple-darwin) (push) Blocked by required conditions
EasyTier Core / build (windows-x86_64, windows-latest, x86_64-pc-windows-msvc) (push) Blocked by required conditions
EasyTier Core / core-result (push) Blocked by required conditions
EasyTier GUI / pre_job (push) Waiting to run
EasyTier GUI / build-gui (linux-aarch64, aarch64-unknown-linux-gnu, ubuntu-latest, aarch64-unknown-linux-musl) (push) Blocked by required conditions
EasyTier GUI / build-gui (linux-x86_64, x86_64-unknown-linux-gnu, ubuntu-latest, x86_64-unknown-linux-musl) (push) Blocked by required conditions
EasyTier GUI / build-gui (macos-aarch64, aarch64-apple-darwin, macos-latest, aarch64-apple-darwin) (push) Blocked by required conditions
EasyTier GUI / build-gui (macos-x86_64, x86_64-apple-darwin, macos-latest, x86_64-apple-darwin) (push) Blocked by required conditions
EasyTier GUI / build-gui (windows-x86_64, x86_64-pc-windows-msvc, windows-latest, x86_64-pc-windows-msvc) (push) Blocked by required conditions
EasyTier GUI / gui-result (push) Blocked by required conditions
EasyTier Mobile / pre_job (push) Waiting to run
EasyTier Mobile / build-mobile (android, ubuntu-latest, android) (push) Blocked by required conditions
EasyTier Mobile / mobile-result (push) Blocked by required conditions
EasyTier Test / pre_job (push) Waiting to run
EasyTier Test / test (push) Blocked by required conditions

This commit is contained in:
sijie.sun 2024-08-08 00:08:59 +08:00 committed by Sijie.Sun
parent 3e52490d1b
commit cca105e91d
5 changed files with 390 additions and 52 deletions

158
Cargo.lock generated
View File

@ -164,6 +164,12 @@ dependencies = [
"x11rb",
]
[[package]]
name = "arc-swap"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
[[package]]
name = "async-event"
version = "0.2.1"
@ -485,6 +491,16 @@ dependencies = [
"alloc-stdlib",
]
[[package]]
name = "bstr"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c"
dependencies = [
"memchr",
"serde",
]
[[package]]
name = "bumpalo"
version = "3.16.0"
@ -1393,6 +1409,7 @@ dependencies = [
"encoding",
"futures",
"gethostname 0.5.0",
"globwalk",
"http 1.1.0",
"humansize",
"indexmap 1.9.3",
@ -1410,15 +1427,18 @@ dependencies = [
"quinn",
"rand 0.8.5",
"rcgen",
"regex",
"reqwest 0.11.27",
"ring 0.17.8",
"rstest",
"rust-i18n",
"rustls",
"serde",
"serial_test",
"smoltcp",
"socket2",
"stun_codec",
"sys-locale",
"tabled",
"tachyonix",
"tarpc",
@ -2127,6 +2147,30 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "globset"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1"
dependencies = [
"aho-corasick",
"bstr",
"log",
"regex-automata 0.4.7",
"regex-syntax 0.8.4",
]
[[package]]
name = "globwalk"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc"
dependencies = [
"bitflags 1.3.2",
"ignore",
"walkdir",
]
[[package]]
name = "gobject-sys"
version = "0.18.0"
@ -2571,6 +2615,22 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "ignore"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1"
dependencies = [
"crossbeam-deque",
"globset",
"log",
"memchr",
"regex-automata 0.4.7",
"same-file",
"walkdir",
"winapi-util",
]
[[package]]
name = "image"
version = "0.24.9"
@ -2933,6 +2993,12 @@ dependencies = [
"libc",
]
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "linux-raw-sys"
version = "0.4.14"
@ -3306,6 +3372,15 @@ version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
[[package]]
name = "normpath"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "nu-ansi-term"
version = "0.46.0"
@ -4643,6 +4718,57 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "rust-i18n"
version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dcd94370631e5658a0a23635f7f47e43d06a00ad948e0bb5de79b00d85b880c"
dependencies = [
"globwalk",
"once_cell",
"regex",
"rust-i18n-macro",
"rust-i18n-support",
"smallvec",
]
[[package]]
name = "rust-i18n-macro"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "355763801dcf287e777e42def7c578410783477b804b1107852119e0b2518396"
dependencies = [
"glob",
"once_cell",
"proc-macro2",
"quote",
"rust-i18n-support",
"serde",
"serde_json",
"serde_yaml",
"syn 2.0.72",
]
[[package]]
name = "rust-i18n-support"
version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "399801f4d955abf1c3ce3ce2215dc76bd40beb4ae39e3a84936b21a79ce2caa5"
dependencies = [
"arc-swap",
"globwalk",
"lazy_static",
"normpath",
"once_cell",
"proc-macro2",
"regex",
"serde",
"serde_json",
"serde_yaml",
"toml 0.7.8",
"triomphe",
]
[[package]]
name = "rustc-demangle"
version = "0.1.24"
@ -5019,6 +5145,18 @@ dependencies = [
"syn 2.0.72",
]
[[package]]
name = "serde_yaml"
version = "0.8.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b"
dependencies = [
"indexmap 1.9.3",
"ryu",
"serde",
"yaml-rust",
]
[[package]]
name = "serial_test"
version = "3.1.1"
@ -6351,6 +6489,17 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "triomphe"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6631e42e10b40c0690bf92f404ebcfe6e1fdb480391d15f17cc8e96eeed5369"
dependencies = [
"arc-swap",
"serde",
"stable_deref_trait",
]
[[package]]
name = "try-lock"
version = "0.2.5"
@ -7328,6 +7477,15 @@ dependencies = [
"zeroize",
]
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]
[[package]]
name = "yasna"
version = "0.5.2"

View File

@ -128,7 +128,12 @@ rand = "0.8.5"
serde = { version = "1.0", features = ["derive"] }
pnet = { version = "0.35.0", features = ["serde"] }
clap = { version = "4.4.8", features = ["unicode", "derive", "wrap_help"] }
clap = { version = "4.4.8", features = [
"string",
"unicode",
"derive",
"wrap_help",
] }
async-recursion = "1.0.5"
@ -169,6 +174,9 @@ parking_lot = { version = "0.12.0", optional = true }
wildmatch = "2.3.4"
rust-i18n = "3"
sys-locale = "0.3"
[target.'cfg(windows)'.dependencies]
windows-sys = { version = "0.52", features = [
"Win32_Networking_WinSock",
@ -181,6 +189,8 @@ winreg = "0.52"
[build-dependencies]
tonic-build = "0.12"
globwalk = "0.8.1"
regex = "1"
[target.'cfg(windows)'.build-dependencies]
reqwest = { version = "0.11", features = ["blocking"] }

View File

@ -86,6 +86,45 @@ impl WindowsBuild {
}
}
fn workdir() -> Option<String> {
if let Ok(cargo_manifest_dir) = std::env::var("CARGO_MANIFEST_DIR") {
return Some(cargo_manifest_dir);
}
let dest = std::env::var("OUT_DIR");
if dest.is_err() {
return None;
}
let dest = dest.unwrap();
let seperator = regex::Regex::new(r"(/target/(.+?)/build/)|(\\target\\(.+?)\\build\\)")
.expect("Invalid regex");
let parts = seperator.split(dest.as_str()).collect::<Vec<_>>();
if parts.len() >= 2 {
return Some(parts[0].to_string());
}
None
}
fn check_locale() {
let workdir = workdir().unwrap_or("./".to_string());
let locale_path = format!("{workdir}/**/locales/**/*");
if let Ok(globs) = globwalk::glob(locale_path) {
for entry in globs {
if let Err(e) = entry {
println!("cargo:i18n-error={}", e);
continue;
}
let entry = entry.unwrap().into_path();
println!("cargo:rerun-if-changed={}", entry.display());
}
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
#[cfg(target_os = "windows")]
WindowsBuild::check_for_win();
@ -98,5 +137,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.compile(&["proto/cli.proto"], &["proto/"])
.unwrap();
// tonic_build::compile_protos("proto/cli.proto")?;
check_locale();
Ok(())
}

101
easytier/locales/app.yml Normal file
View File

@ -0,0 +1,101 @@
_version: 2
core_clap:
config_file:
en: "path to the config file, NOTE: if this is set, all other options will be ignored"
zh-CN: "配置文件路径,注意:如果设置了这个选项,其他所有选项都将被忽略"
network_name:
en: "network name to identify this vpn network"
zh-CN: "用于标识此VPN网络的网络名称"
network_secret:
en: "network secret to verify this node belongs to the vpn network"
zh-CN: "网络密钥用于验证此节点属于VPN网络"
ipv4:
en: "ipv4 address of this vpn node, if empty, this node will only forward packets and no TUN device will be created"
zh-CN: "此VPN节点的IPv4地址如果为空则此节点将仅转发数据包不会创建TUN设备"
dhcp:
en: "automatically determine and set IP address by Easytier, and the IP address starts from 10.0.0.1 by default. Warning, if there is an IP conflict in the network when using DHCP, the IP will be automatically changed."
zh-CN: "由Easytier自动确定并设置IP地址默认从10.0.0.1开始。警告在使用DHCP时如果网络中出现IP冲突IP将自动更改。"
peers:
en: "peers to connect initially"
zh-CN: "最初要连接的对等节点"
external_node:
en: "use a public shared node to discover peers"
zh-CN: "使用公共共享节点来发现对等节点"
proxy_networks:
en: "export local networks to other peers in the vpn"
zh-CN: "将本地网络导出到VPN中的其他对等节点"
rpc_portal:
en: "rpc portal address to listen for management. 0 means random port, 12345 means listen on 12345 of localhost, 0.0.0.0:12345 means listen on 12345 of all interfaces. default is 0 and will try 15888 first"
zh-CN: "用于管理的RPC门户地址。0表示随机端口12345表示在localhost的12345上监听0.0.0.0:12345表示在所有接口的12345上监听。默认是0首先尝试15888"
listeners:
en: |+
listeners to accept connections, allow format:
port number: <11010>. means tcp/udp will listen on 11010, ws/wss will listen on 11010 and 11011, wg will listen on 11011
url: <tcp://0.0.0.0:11010>. tcp can be tcp, udp, ring, wg, ws, wss\n
proto & port pair: <proto:port>. wg:11011, means listen on 11011 with wireguard protocol url and proto:port can occur multiple times.
zh-CN: |+
监听器用于接受连接,允许以下格式:
端口号:<11010>意味着tcp/udp将在11010端口监听ws/wss将在11010和11011端口监听wg将在11011端口监听。
url<tcp://0.0.0.0:11010>其中tcp可以是tcp、udp、ring、wg、ws、wss协议。
协议和端口对:<proto:port>例如wg:11011表示使用WireGuard协议在11011端口监听。URL 和 协议端口对 可以多次出现。
no_listener:
en: "do not listen on any port, only connect to peers"
zh-CN: "不监听任何端口,只连接到对等节点"
console_log_level:
en: "console log level"
zh-CN: "控制台日志级别"
file_log_level:
en: "file log level"
zh-CN: "文件日志级别"
file_log_dir:
en: "directory to store log files"
zh-CN: "存储日志文件的目录"
hostname:
en: "host name to identify this device"
zh-CN: "用于标识此设备的主机名"
instance_name:
en: "instance name to identify this vpn node in same machine"
zh-CN: "实例名称用于在同一台机器上标识此VPN节点"
vpn_portal:
en: "url that defines the vpn portal, allow other vpn clients to connect. example: wg://0.0.0.0:11010/10.14.14.0/24, means the vpn portal is a wireguard server listening on vpn.example.com:11010, and the vpn client is in network of 10.14.14.0/24"
zh-CN: "定义VPN门户的URL允许其他VPN客户端连接。示例wg://0.0.0.0:11010/10.14.14.0/24表示VPN门户是监听在vpn.example.com:11010的wireguard服务器VPN客户端在10.14.14.0/24网络中"
default_protocol:
en: "default protocol to use when connecting to peers"
zh-CN: "连接到对等节点时使用的默认协议"
disable_encryption:
en: "disable encryption for peers communication, default is false, must be same with peers"
zh-CN: "禁用对等节点通信的加密默认为false必须与对等节点相同"
multi_thread:
en: "use multi-thread runtime, default is single-thread"
zh-CN: "使用多线程运行时,默认为单线程"
disable_ipv6:
en: "do not use ipv6"
zh-CN: "不使用IPv6"
dev_name:
en: "optional tun interface name"
zh-CN: "可选的TUN接口名称"
mtu:
en: "mtu of the TUN device, default is 1420 for non-encryption, 1400 for encryption"
zh-CN: "TUN设备的MTU默认为非加密时为1420加密时为1400"
latency_first:
en: "latency first mode, will try to relay traffic with lowest latency path, default is using shortest path"
zh-CN: "延迟优先模式,将尝试使用最低延迟路径转发流量,默认使用最短路径"
exit_nodes:
en: "exit nodes to forward all traffic to, a virtual ipv4 address, priority is determined by the order of the list"
zh-CN: "转发所有流量的出口节点虚拟IPv4地址优先级由列表顺序决定"
enable_exit_node:
en: "allow this node to be an exit node"
zh-CN: "允许此节点成为出口节点"
no_tun:
en: "do not create TUN device, can use subnet proxy to access node"
zh-CN: "不创建TUN设备可以使用子网代理访问节点"
use_smoltcp:
en: "enable smoltcp stack for subnet proxy"
zh-CN: "为子网代理启用smoltcp堆栈"
manual_routes:
en: "assign routes cidr manually, will disable subnet proxy and wireguard routes propagated from peers. e.g.: 192.168.0.0/16"
zh-CN: "手动分配路由CIDR将禁用子网代理和从对等节点传播的wireguard路由。例如192.168.0.0/16"
relay_network_whitelist:
en: "only relay traffic of whitelisted networks, input is a wildcard string, e.g.: '*' (all networks), 'def*' (network prefixed with def), can specify multiple networks disable relay if arg is empty. default is allowing all networks"
zh-CN: "仅转发白名单网络的流量,输入是通配符字符串,例如:'*'(所有网络),'def*'以def为前缀的网络可以指定多个网络。如果参数为空则禁用转发。默认允许所有网络"

View File

@ -10,6 +10,9 @@ use std::{
path::PathBuf,
};
#[macro_use]
extern crate rust_i18n;
use anyhow::Context;
use clap::Parser;
@ -52,19 +55,20 @@ struct Cli {
#[arg(
short,
long,
help = "path to the config file, NOTE: if this is set, all other options will be ignored"
help = t!("core_clap.config_file").to_string()
)]
config_file: Option<PathBuf>,
#[arg(
long,
help = "network name to identify this vpn network",
help = t!("core_clap.network_name").to_string(),
default_value = "default"
)]
network_name: String,
#[arg(
long,
help = "network secret to verify this node belongs to the vpn network",
help = t!("core_clap.network_secret").to_string(),
default_value = ""
)]
network_secret: String,
@ -72,171 +76,193 @@ struct Cli {
#[arg(
short,
long,
help = "ipv4 address of this vpn node, if empty, this node will only forward packets and no TUN device will be created"
help = t!("core_clap.ipv4").to_string()
)]
ipv4: Option<String>,
#[arg(
short,
long,
help = "automatically determine and set IP address by Easytier, and the
IP address starts from 10.0.0.1 by default. Warning, if there is an IP
conflict in the network when using DHCP, the IP will be automatically
changed."
help = t!("core_clap.dhcp").to_string()
)]
dhcp: bool,
#[arg(short, long, help = "peers to connect initially", num_args = 0..)]
#[arg(
short,
long,
help = t!("core_clap.peers").to_string(),
num_args = 0..
)]
peers: Vec<String>,
#[arg(short, long, help = "use a public shared node to discover peers")]
#[arg(
short,
long,
help = t!("core_clap.external_node").to_string()
)]
external_node: Option<String>,
#[arg(
short = 'n',
long,
help = "export local networks to other peers in the vpn"
help = t!("core_clap.proxy_networks").to_string()
)]
proxy_networks: Vec<String>,
#[arg(
short,
long,
default_value = "0",
help = "rpc portal address to listen for management. 0 means random
port, 12345 means listen on 12345 of localhost, 0.0.0.0:12345 means
listen on 12345 of all interfaces. default is 0 and will try 15888 first"
help = t!("core_clap.rpc_portal").to_string(),
default_value = "0"
)]
rpc_portal: String,
#[arg(short, long, help = "listeners to accept connections, allow format:
a port number: 11010, means tcp/udp will listen on 11010, ws/wss will listen on 11010 and 11011, wg will listen on 11011
url: tcp://0.0.0.0:11010, tcp can be tcp, udp, ring, wg, ws, wss,
proto:port: wg:11011, means listen on 11011 with wireguard protocol
url and proto:port can occur multiple times.
", default_values_t = ["11010".to_string()],
num_args = 0..)]
#[arg(
short,
long,
help = t!("core_clap.listeners").to_string(),
default_values_t = ["11010".to_string()],
num_args = 0..
)]
listeners: Vec<String>,
#[arg(
long,
help = "do not listen on any port, only connect to peers",
help = t!("core_clap.no_listener").to_string(),
default_value = "false"
)]
no_listener: bool,
#[arg(long, help = "console log level",
value_parser = clap::builder::PossibleValuesParser::new(["trace", "debug", "info", "warn", "error", "off"]))]
#[arg(
long,
help = t!("core_clap.console_log_level").to_string()
)]
console_log_level: Option<String>,
#[arg(long, help = "file log level",
value_parser = clap::builder::PossibleValuesParser::new(["trace", "debug", "info", "warn", "error", "off"]))]
#[arg(
long,
help = t!("core_clap.file_log_level").to_string()
)]
file_log_level: Option<String>,
#[arg(long, help = "directory to store log files")]
#[arg(
long,
help = t!("core_clap.file_log_dir").to_string()
)]
file_log_dir: Option<String>,
#[arg(long, help = "host name to identify this device")]
#[arg(
long,
help = t!("core_clap.hostname").to_string()
)]
hostname: Option<String>,
#[arg(
short = 'm',
long,
default_value = "default",
help = "instance name to identify this vpn node in same machine"
help = t!("core_clap.instance_name").to_string(),
default_value = "default"
)]
instance_name: String,
#[arg(
long,
help = "url that defines the vpn portal, allow other vpn clients to connect.
example: wg://0.0.0.0:11010/10.14.14.0/24, means the vpn portal is a wireguard server listening on vpn.example.com:11010,
and the vpn client is in network of 10.14.14.0/24"
help = t!("core_clap.vpn_portal").to_string()
)]
vpn_portal: Option<String>,
#[arg(long, help = "default protocol to use when connecting to peers")]
#[arg(
long,
help = t!("core_clap.default_protocol").to_string()
)]
default_protocol: Option<String>,
#[arg(
short = 'u',
long,
help = "disable encryption for peers communication, default is false, must be same with peers",
help = t!("core_clap.disable_encryption").to_string(),
default_value = "false"
)]
disable_encryption: bool,
#[arg(
long,
help = "use multi-thread runtime, default is single-thread",
help = t!("core_clap.multi_thread").to_string(),
default_value = "false"
)]
multi_thread: bool,
#[arg(long, help = "do not use ipv6", default_value = "false")]
#[arg(
long,
help = t!("core_clap.disable_ipv6").to_string(),
default_value = "false"
)]
disable_ipv6: bool,
#[arg(long, help = "optional tun interface name")]
#[arg(
long,
help = t!("core_clap.dev_name").to_string()
)]
dev_name: Option<String>,
#[arg(
long,
help = "mtu of the TUN device, default is 1420 for non-encryption, 1400 for encryption"
help = t!("core_clap.mtu").to_string()
)]
mtu: Option<u16>,
#[arg(
long,
help = "latency first mode, will try to relay traffic with lowest latency path, default is using shortest path",
help = t!("core_clap.latency_first").to_string(),
default_value = "false"
)]
latency_first: bool,
#[arg(
long,
help = "exit nodes to forward all traffic to, a virtual ipv4 address, priority is determined by the order of the list",
help = t!("core_clap.exit_nodes").to_string(),
num_args = 0..
)]
exit_nodes: Vec<Ipv4Addr>,
#[arg(
long,
help = "allow this node to be an exit node, default is false",
help = t!("core_clap.enable_exit_node").to_string(),
default_value = "false"
)]
enable_exit_node: bool,
#[arg(
long,
help = "do not create TUN device, can use subnet proxy to access node",
help = t!("core_clap.no_tun").to_string(),
default_value = "false"
)]
no_tun: bool,
#[arg(
long,
help = "enable smoltcp stack for subnet proxy",
help = t!("core_clap.use_smoltcp").to_string(),
default_value = "false"
)]
use_smoltcp: bool,
#[arg(
long,
help = "assign routes cidr manually, will disable subnet proxy and
wireguard routes propogated from peers. e.g.: 192.168.0.0/16",
help = t!("core_clap.manual_routes").to_string(),
num_args = 0..
)]
manual_routes: Option<Vec<String>>,
#[arg(
long,
help = "only relay traffic of whitelisted networks, input is a wildcard
string, e.g.: '*' (all networks), 'def*' (network prefixed with def), can specify multiple networks
disable relay if arg is empty. default is allowing all networks",
num_args = 0..,
help = t!("core_clap.relay_network_whitelist").to_string(),
num_args = 0..
)]
relay_network_whitelist: Option<Vec<String>>,
}
rust_i18n::i18n!("locales");
impl Cli {
fn parse_listeners(&self) -> Vec<String> {
println!("parsing listeners: {:?}", self.listeners);
@ -628,6 +654,9 @@ pub async fn async_main(cli: Cli) {
fn main() {
setup_panic_handler();
let locale = sys_locale::get_locale().unwrap_or_else(|| String::from("en-US"));
rust_i18n::set_locale(&locale);
let cli = Cli::parse();
tracing::info!(cli = ?cli, "cli args parsed");