From b5629eae466b82484411327e0a3fbc4f90eaa21f Mon Sep 17 00:00:00 2001 From: ssrlive <30760636+ssrlive@users.noreply.github.com> Date: Tue, 26 Aug 2025 22:10:04 +0800 Subject: [PATCH] serde for Args --- Cargo.toml | 4 ++-- src/args.rs | 19 ++++++++++++++----- src/lib.rs | 2 ++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a47c5d9..42f81b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,9 +42,10 @@ ipstack = { version = "0.4" } log = { version = "0.4", features = ["std"] } mimalloc = { version = "0.1", default-features = false, optional = true } percent-encoding = "2" +serde = { version = "1", features = ["derive"] } shlex = "1.3.0" socks5-impl = { version = "0.7", default-features = false, features = [ - "tokio", + "tokio", "serde" ] } thiserror = "2" tokio = { version = "1", features = ["full"] } @@ -61,7 +62,6 @@ jni = { version = "0.21", default-features = false } [target.'cfg(target_os="linux")'.dependencies] bincode = "2" -serde = { version = "1", features = ["derive"] } [target.'cfg(target_os="windows")'.dependencies] windows-service = "0.8" diff --git a/src/args.rs b/src/args.rs index 333e758..fe87fac 100644 --- a/src/args.rs +++ b/src/args.rs @@ -19,7 +19,7 @@ fn about_info() -> &'static str { concat!("Tunnel interface to proxy.\nVersion: ", version_info!()) } -#[derive(Debug, Clone, clap::Parser)] +#[derive(Debug, Clone, clap::Parser, serde::Serialize, serde::Deserialize)] #[command(author, version = version_info!(), about = about_info(), long_about = None)] pub struct Args { /// Proxy URL in the form proto://[username[:password]@]host:port, @@ -33,17 +33,20 @@ pub struct Args { /// If this option is not provided, the OS will generate a random one. #[arg(short, long, value_name = "name", value_parser = validate_tun)] #[cfg_attr(unix, arg(conflicts_with = "tun_fd"))] + #[serde(skip_serializing_if = "Option::is_none")] pub tun: Option, /// File descriptor of the tun interface #[cfg(unix)] #[arg(long, value_name = "fd", conflicts_with = "tun")] + #[serde(skip_serializing_if = "Option::is_none")] pub tun_fd: Option, /// Set whether to close the received raw file descriptor on drop or not. /// This setting is dependent on [tun_fd]. #[cfg(unix)] #[arg(long, value_name = "true or false", conflicts_with = "tun", requires = "tun_fd")] + #[serde(skip_serializing_if = "Option::is_none")] pub close_fd_on_drop: Option, /// Create a tun interface in a newly created unprivileged namespace @@ -55,6 +58,7 @@ pub struct Args { /// Create a pidfile of `unshare` process when using `--unshare`. #[cfg(target_os = "linux")] #[arg(long)] + #[serde(skip_serializing_if = "Option::is_none")] pub unshare_pidfile: Option, /// File descriptor for UNIX datagram socket meant to transfer @@ -62,6 +66,7 @@ pub struct Args { /// See `unshare(1)`, `namespaces(7)`, `sendmsg(2)`, `unix(7)`. #[cfg(target_os = "linux")] #[arg(long, value_name = "fd", hide(true))] + #[serde(skip_serializing_if = "Option::is_none")] pub socket_transfer_fd: Option, /// Specify a command to run with root-like capabilities in the new namespace @@ -126,16 +131,19 @@ pub struct Args { /// UDP gateway server address, forwards UDP packets via specified TCP server #[cfg(feature = "udpgw")] #[arg(long, value_name = "IP:PORT")] + #[serde(skip_serializing_if = "Option::is_none")] pub udpgw_server: Option, /// Max connections for the UDP gateway, default value is 5 #[cfg(feature = "udpgw")] #[arg(long, value_name = "number", requires = "udpgw_server")] + #[serde(skip_serializing_if = "Option::is_none")] pub udpgw_connections: Option, /// Keepalive interval in seconds for the UDP gateway, default value is 30 #[cfg(feature = "udpgw")] #[arg(long, value_name = "seconds", requires = "udpgw_server")] + #[serde(skip_serializing_if = "Option::is_none")] pub udpgw_keepalive: Option, } @@ -268,7 +276,7 @@ impl Args { } #[repr(C)] -#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, clap::ValueEnum)] +#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, clap::ValueEnum, serde::Serialize, serde::Deserialize)] pub enum ArgVerbosity { Off = 0, Error, @@ -338,7 +346,7 @@ impl std::fmt::Display for ArgVerbosity { /// - OverTcp: Use TCP to send DNS queries to the DNS server /// - Direct: Do not handle DNS by relying on DNS server bypassing #[repr(C)] -#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, clap::ValueEnum)] +#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, clap::ValueEnum, serde::Serialize, serde::Deserialize)] pub enum ArgDns { Virtual = 0, OverTcp, @@ -359,10 +367,11 @@ impl TryFrom for ArgDns { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] pub struct ArgProxy { pub proxy_type: ProxyType, pub addr: SocketAddr, + #[serde(skip_serializing_if = "Option::is_none")] pub credentials: Option, } @@ -432,7 +441,7 @@ impl TryFrom<&str> for ArgProxy { } #[repr(C)] -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, serde::Serialize, serde::Deserialize)] pub enum ProxyType { Http = 0, Socks4, diff --git a/src/lib.rs b/src/lib.rs index 737a82d..1f9e68f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,7 @@ use crate::{ session_info::{IpProtocol, SessionInfo}, virtual_dns::VirtualDns, }; +pub use clap::ValueEnum; use ipstack::{IpStackStream, IpStackTcpStream, IpStackUdpStream}; use proxy_handler::{ProxyHandler, ProxyHandlerManager}; use socks::SocksProxyManager; @@ -26,6 +27,7 @@ use tokio::{ }; pub use tokio_util::sync::CancellationToken; use tproxy_config::is_private_ip; +pub use tun::DEFAULT_MTU; use udp_stream::UdpStream; #[cfg(feature = "udpgw")] use udpgw::{UDPGW_KEEPALIVE_TIME, UDPGW_MAX_CONNECTIONS, UdpGwClientStream, UdpGwResponse};