From db4d3cbe8cc53af780d72385400de45be50b46ce Mon Sep 17 00:00:00 2001 From: Samuel Tam Date: Mon, 30 Jun 2025 23:13:08 +0800 Subject: [PATCH] Initial manual pages and long --help message --- Cargo.toml | 1 + Earthfile | 8 +- lightway-client/Cargo.toml | 10 +++ lightway-client/build.rs | 103 ++++++++++++++++++++++ lightway-client/src/args.rs | 165 ++++++++++++++++++++++-------------- lightway-server/Cargo.toml | 9 ++ lightway-server/build.rs | 110 ++++++++++++++++++++++++ lightway-server/src/args.rs | 143 +++++++++++++++++++------------ 8 files changed, 427 insertions(+), 122 deletions(-) create mode 100644 lightway-client/build.rs create mode 100644 lightway-server/build.rs diff --git a/Cargo.toml b/Cargo.toml index 9ac072ad..59698ca8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ async-trait = "0.1.77" bytes = "1.5.0" bytesize = { version = "1.3.0", features = ["serde"] } clap = { version = "4.4.7", features = ["derive"] } +clap_mangen = "0.2" ctrlc = { version = "3.4.6", features = ["termination"] } delegate = "0.12.0" educe = { version = "0.6.0", default-features = false, features = ["Debug"] } diff --git a/Earthfile b/Earthfile index 5aa3ba83..a4708075 100644 --- a/Earthfile +++ b/Earthfile @@ -57,10 +57,12 @@ build: SET target = "riscv64gc-unknown-linux-gnu" END - DO lib-rust+CARGO --args="build --release --features io-uring --target=$target" --output="$target/release/lightway-(client|server)$" + DO lib-rust+CARGO --args="build --release --features io-uring --target=$target" - SAVE ARTIFACT ./target/$target/release/lightway-client AS LOCAL ./target/$target/release/ - SAVE ARTIFACT ./target/$target/release/lightway-server AS LOCAL ./target/$target/release/ + DO lib-rust+COPY_OUTPUT --output="$target/release/lightway-(client|server)$" + DO lib-rust+COPY_OUTPUT --output="$target/release/man/lightway-(client|server).1$" + + SAVE ARTIFACT ./target/$target/release AS LOCAL ./target/$target/release # build-arm64 build for arm64. Support building from an amd64 or arm64 host build-arm64: diff --git a/lightway-client/Cargo.toml b/lightway-client/Cargo.toml index 3d608247..dd0fe4f4 100644 --- a/lightway-client/Cargo.toml +++ b/lightway-client/Cargo.toml @@ -5,6 +5,7 @@ repository.workspace = true edition.workspace = true authors.workspace = true license.workspace = true +build = "build.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -40,6 +41,15 @@ tracing.workspace = true tracing-subscriber = { workspace = true} twelf.workspace = true +[build-dependencies] +anyhow = { workspace = true } +bytesize = { workspace = true } +clap = { workspace = true } +clap_mangen = { workspace = true } +lightway-app-utils = { workspace = true } +lightway-core = { workspace = true } +twelf = { workspace = true } + [dev-dependencies] more-asserts.workspace = true test-case.workspace = true diff --git a/lightway-client/build.rs b/lightway-client/build.rs new file mode 100644 index 00000000..36cfe7ee --- /dev/null +++ b/lightway-client/build.rs @@ -0,0 +1,103 @@ +use std::env; +use std::fs; +use std::path::Path; + +use clap::CommandFactory; + +#[path = "src/args.rs"] +mod args; + +fn create_client_command() -> clap::Command { + // Get the base command from the derive macro + let cmd = args::Config::command(); + + // Add the detailed help text + let long_about = [ + "Lightway is a modern VPN client that implements the Lightway protocol. It provides", + "a fast, secure, and reliable VPN connection using modern cryptographic algorithms", + "and optimized network protocols.", + "", + "The client connects to a Lightway server and establishes a secure tunnel for", + "routing network traffic. It supports both TCP and UDP transport protocols and", + "includes advanced features like Path MTU Discovery, keepalive mechanisms, and", + "io_uring optimization on Linux.", + "", + "Configuration can be provided via YAML files, environment variables (LW_CLIENT_*),", + "or command-line arguments. Command-line arguments have the highest priority.", + "", + "Security Note: Avoid passing passwords via command-line arguments as they may be", + "visible to other users. Use configuration files or environment variables instead.", + ] + .join("\n"); + + let after_help = [ + "CONFIGURATION FILE:", + "The client requires a configuration file in YAML format. Environment variables can", + "override configuration file settings using the LW_CLIENT_ prefix. Command-line", + "arguments have the highest priority.", + "", + "Example configuration:", + " mode: tcp", + " server: \"vpn.example.com:27690\"", + " user: \"myuser\"", + " password: \"mypassword\"", + " ca_cert: \"/etc/lightway/ca.crt\"", + " log_level: info", + "", + "AUTHENTICATION:", + "The client supports two authentication methods:", + " • Username/Password: Traditional username and password authentication", + " • JWT Token: JSON Web Token authentication using RS256 algorithm", + "", + "If both token and username/password are provided, token authentication takes precedence.", + "", + "EXAMPLES:", + " lightway-client --config-file /etc/lightway/client.yaml", + " lightway-client -c client.yaml --server vpn.example.com:27690 --log-level debug", + " lightway-client -c client.yaml --mode udp --enable-pmtud", + "", + "FILES:", + " /etc/lightway/client.yaml System-wide client configuration", + " ~/.config/lightway/client.yaml User-specific client configuration", + " ./ca_cert.crt Default CA certificate location", + "", + "ENVIRONMENT:", + " LW_CLIENT_SERVER Server address", + " LW_CLIENT_USER Username for authentication", + " LW_CLIENT_PASSWORD Password for authentication", + " LW_CLIENT_LOG_LEVEL Logging level", + "", + "SEE ALSO:", + " lightway-server(1), ip(8), iptables(8)", + "", + "REPORT BUGS:", + " https://github.com/expressvpn/lightway/issues", + ] + .join("\n"); + + cmd.long_about(long_about) + .after_help(after_help) +} + +fn main() -> std::io::Result<()> { + // Generate man page using clap_mangen + let cmd = create_client_command(); + let man = clap_mangen::Man::new(cmd); + let mut buffer = Vec::new(); + man.render(&mut buffer)?; + + // We can't use CARGO_TARGET_DIR in build.rs, ugly hack to get the target directory + let out_dir = env::var("OUT_DIR").unwrap(); + let target_path = Path::new(&out_dir).ancestors().nth(3).unwrap(); + + // Create man directory if it doesn't exist + let man_path = target_path.join("man"); + fs::create_dir_all(&man_path).unwrap(); + + // Write to file + let name = env::var("CARGO_PKG_NAME").unwrap(); + let manpage = man_path.join(format!("{}.1", name)); + fs::write(manpage, buffer)?; + + Ok(()) +} diff --git a/lightway-client/src/args.rs b/lightway-client/src/args.rs index 7120ef3e..c1e0e819 100644 --- a/lightway-client/src/args.rs +++ b/lightway-client/src/args.rs @@ -8,129 +8,166 @@ use twelf::config; #[config] #[derive(Parser, Debug)] -#[command(about = "A lightway client")] +#[command( + about = "Lightway client - high-performance, secure, reliable VPN protocol in Rust", + version, + author = "ExpressVPN ", + after_help = concat!( + "EXAMPLES:\n", + " lightway-client -c client.yaml\n", + " lightway-client -c client.yaml --server vpn.example.com:27690\n", + " lightway-client -c client.yaml --mode udp --enable-pmtud\n", + "\n", + "See lightway-client(1) manpage for detailed configuration and usage information." + ) +)] pub struct Config { - /// Config File to load - #[clap(short, long)] + /// Configuration file path (YAML format) + /// + /// Supports both absolute and relative paths + #[clap(short, long, value_name = "FILE")] pub config_file: PathBuf, - /// Connection mode - #[clap(short, long, value_enum, default_value_t = ConnectionType::Tcp)] + /// Transport protocol to use for VPN connection + /// TCP provides reliability, UDP provides better performance + #[clap(short, long, value_enum, default_value_t = ConnectionType::Tcp, value_name = "PROTOCOL")] pub mode: ConnectionType, - /// Auth token - /// If both token and user/pass are provided, token auth will - /// be used. user/pass will be ignored in this case - #[clap(long, hide = true)] + /// JWT authentication token (takes precedence over username/password) + /// Use configuration file or environment variable instead of CLI argument + #[clap(long, value_name = "TOKEN", hide = true)] pub token: Option, - /// Username for auth - #[clap(short, long, hide = true)] + /// Username for authentication + /// Use configuration file or environment variable instead of CLI argument + #[clap(short, long, value_name = "USER")] pub user: Option, - /// Password for auth - #[clap(short, long, hide = true)] + /// Password for authentication + /// WARNING: Visible to other users when passed via CLI. Use config file or LW_CLIENT_PASSWORD env var + #[clap(short, long, value_name = "PASSWORD")] pub password: Option, - /// CA certificate - #[clap(long, default_value = "./ca_cert.crt")] + /// Path to CA certificate file for server validation + /// Ensures secure connection to authentic Lightway server + #[clap(long, default_value = "./ca_cert.crt", value_name = "FILE")] pub ca_cert: PathBuf, - /// Outside (wire) MTU - #[clap(long, default_value_t = MAX_OUTSIDE_MTU)] + /// Maximum Transmission Unit for network packets + /// Adjust based on your network infrastructure to avoid fragmentation + #[clap(long, default_value_t = MAX_OUTSIDE_MTU, value_name = "SIZE")] pub outside_mtu: usize, - /// Inside (tunnel) MTU (requires `CAP_NET_ADMIN`) - #[clap(long)] + /// MTU for tunnel interface (requires CAP_NET_ADMIN capability) + /// Override default MTU of tunnel device for performance tuning + #[clap(long, value_name = "SIZE")] pub inside_mtu: Option, - /// Tun device name to use - #[clap(short, long, default_value = None)] + /// TUN device name (leave empty for auto-assignment) + /// On macOS, must follow format 'utun[0-9]+' or leave empty + #[clap(short, long, value_name = "NAME")] pub tun_name: Option, - /// Local IP to use in Tun device - #[clap(long, default_value = "100.64.0.6")] + /// Local IP address for tunnel interface + /// Must be within the same subnet as peer IP + #[clap(long, default_value = "100.64.0.6", value_name = "IP")] pub tun_local_ip: Ipv4Addr, - /// Peer IP to use in Tun device - #[clap(long, default_value = "100.64.0.5")] + /// Peer IP address for tunnel interface + /// Represents the server endpoint within the tunnel + #[clap(long, default_value = "100.64.0.5", value_name = "IP")] pub tun_peer_ip: Ipv4Addr, - /// DNS IP to use in Tun device - #[clap(long, default_value = "100.64.0.1")] + /// DNS server IP address for tunnel traffic + /// Used for resolving domain names through the VPN + #[clap(long, default_value = "100.64.0.1", value_name = "IP")] pub tun_dns_ip: Ipv4Addr, - /// Cipher to use for encryption - #[clap(long, value_enum, default_value_t = Cipher::Aes256)] + /// Encryption cipher algorithm + /// Both ciphers offer strong security. + /// However, if hardware acceleration for AES-256 is not available, + /// ChaCha20 may provide better performance in software implementations + #[clap(long, value_enum, default_value_t = Cipher::Aes256, value_name = "CIPHER")] pub cipher: Cipher, - /// Enable Post Quantum Crypto + /// Enable Post-Quantum Cryptography + /// Provides protection against future quantum computing attacks #[cfg(feature = "postquantum")] - #[clap(long, default_value_t)] + #[clap(long)] pub enable_pqc: bool, - /// Interval between keepalives - #[clap(long, default_value = "0s")] + /// Interval between keepalive packets (0s = disabled) + /// Helps maintain connection through NAT devices and firewalls + #[clap(long, default_value = "0s", value_name = "DURATION")] pub keepalive_interval: Duration, - /// Keepalive timeout - #[clap(long, default_value = "0s")] + /// Timeout for keepalive responses (0s = disabled) + /// Connection considered dead if no response within this time + #[clap(long, default_value = "0s", value_name = "DURATION")] pub keepalive_timeout: Duration, - /// Socket send buffer size - #[clap(long)] + /// Socket send buffer size for performance tuning + /// Larger buffers may improve throughput on high-bandwidth connections + #[clap(long, value_name = "SIZE")] pub sndbuf: Option, - /// Socket receive buffer size - #[clap(long)] + /// Socket receive buffer size for performance tuning + /// Larger buffers may improve throughput on high-bandwidth connections + #[clap(long, value_name = "SIZE")] pub rcvbuf: Option, - /// Log level to use - #[clap(long, value_enum, default_value_t = LogLevel::Info)] + /// Logging verbosity level + /// Use 'debug' or 'trace' for troubleshooting connection issues + #[clap(long, value_enum, default_value_t = LogLevel::Info, value_name = "LEVEL")] pub log_level: LogLevel, - /// Enable PMTU discovery for [`ConnectionType::Udp`] connections + /// Enable Path MTU Discovery for UDP connections + /// Automatically determines optimal packet size for the network path #[clap(long)] pub enable_pmtud: bool, - /// Base MTU to use for PMTU discovery - #[clap(long)] + /// Starting MTU size for Path MTU Discovery process + /// Only used when --enable-pmtud is set + #[clap(long, value_name = "SIZE")] pub pmtud_base_mtu: Option, - /// Enable IO-uring interface for Tunnel - #[clap(long, default_value_t)] + /// Enable io_uring for high-performance tunnel I/O (Linux only) + /// Provides better performance but requires recent Linux kernel + #[clap(long)] pub enable_tun_iouring: bool, - /// IO-uring submission queue count. Only applicable when - /// `enable_tun_iouring` is `true` - // Any value more than 1024 negatively impact the throughput - #[clap(long, default_value_t = 1024)] + /// io_uring submission queue size (max 1024 for optimal performance) + /// Only used when --enable-tun-iouring is enabled + #[clap(long, default_value_t = 1024, value_name = "COUNT")] pub iouring_entry_count: usize, - /// IO-uring sqpoll idle time. If non-zero use a kernel thread to - /// perform submission queue polling. After the given idle time - /// the thread will go to sleep. - #[clap(long, default_value = "100ms")] + /// io_uring kernel polling idle time (0 = disabled) + /// Uses kernel thread for polling; reduces CPU usage but may increase latency + #[clap(long, default_value = "100ms", value_name = "DURATION")] pub iouring_sqpoll_idle_time: Duration, - /// Server domain name - #[clap(long, default_value = None)] + /// Server domain name for certificate validation + /// Used to verify server certificate matches expected hostname + #[clap(long, value_name = "DOMAIN")] pub server_dn: Option, - /// Server to connect to - #[clap(short, long, default_value_t)] + /// Server address to connect to (host:port) + /// Can be IP address or domain name with port number + #[clap(short, long, value_name = "ADDRESS")] pub server: String, - /// Enable inside packet encoding once lightway connects - /// Only used if a codec is set - #[clap(short, long, default_value_t)] + /// Enable packet encoding after connection + /// Provides additional traffic encoding when codec is configured + #[clap(short, long)] pub enable_inside_pkt_encoding_at_connect: bool, - /// File path to save wireshark keylog + /// Path to save TLS keylog for Wireshark decryption (only available with `debug` feature) + /// Enables traffic analysis and debugging of encrypted connections #[cfg(feature = "debug")] - #[clap(long, default_value = None)] + #[clap(long, value_name = "FILE")] pub keylog: Option, - /// Enable WolfSSL debug logging + /// Enable detailed TLS/SSL debug logging (only available with `debug` feature) + /// Provides verbose cryptographic handshake information #[cfg(feature = "debug")] #[clap(long)] pub tls_debug: bool, diff --git a/lightway-server/Cargo.toml b/lightway-server/Cargo.toml index 3cb12b84..1665e133 100644 --- a/lightway-server/Cargo.toml +++ b/lightway-server/Cargo.toml @@ -5,6 +5,7 @@ repository.workspace = true edition.workspace = true authors.workspace = true license.workspace = true +build = "build.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -51,6 +52,14 @@ tracing-log = "0.2.0" tracing-subscriber = { workspace = true, features = ["json"] } twelf.workspace = true +[build-dependencies] +bytesize = { workspace = true } +clap = { workspace = true } +clap_mangen = { workspace = true } +ipnet = { workspace = true } +lightway-app-utils = { workspace = true } +twelf = { workspace = true } + [dev-dependencies] more-asserts.workspace = true test-case.workspace = true diff --git a/lightway-server/build.rs b/lightway-server/build.rs new file mode 100644 index 00000000..43b00e82 --- /dev/null +++ b/lightway-server/build.rs @@ -0,0 +1,110 @@ +use std::env; +use std::fs; +use std::path::Path; + +use clap::CommandFactory; + +#[path = "src/args.rs"] +mod args; + +fn create_server_command() -> clap::Command { + // Get the base command from the derive macro + let cmd = args::Config::command(); + + // Add the detailed help text + let long_about = [ + "Lightway is a modern VPN server that implements the Lightway protocol. It provides", + "a high-performance, secure VPN service using modern cryptographic algorithms and", + "optimized network protocols.", + "", + "The server accepts connections from Lightway clients and provides secure tunneling", + "services. It supports multiple authentication methods, dynamic IP assignment, and", + "advanced features like PROXY protocol support and io_uring optimization on Linux.", + "", + "Configuration can be provided via YAML files, environment variables (LW_SERVER_*),", + "or command-line arguments. Command-line arguments have the highest priority.", + "", + "Authentication: Supports both username/password (htpasswd format) and JWT token", + "authentication. Only bcrypt, SHA-256, and SHA-512 password hashes are supported.", + ] + .join("\n"); + + let after_help = [ + "CONFIGURATION FILE:", + "The server requires a configuration file in YAML format. Environment variables can", + "override configuration file settings using the LW_SERVER_ prefix. Command-line", + "arguments have the highest priority.", + "", + "Example configuration:", + " mode: tcp", + " bind_address: \"0.0.0.0:27690\"", + " server_cert: \"/etc/lightway/server.crt\"", + " server_key: \"/etc/lightway/server.key\"", + " user_db: \"/etc/lightway/users.db\"", + " ip_pool: \"10.125.0.0/16\"", + " log_level: info", + " key_update_interval: \"15m\"", + "", + "AUTHENTICATION:", + "The server supports multiple authentication methods:", + " • Username/Password: Uses Apache htpasswd compatible format. Only bcrypt,", + " SHA-256, and SHA-512 hashes are supported (not Apache MD5).", + " • JWT Token: Uses RSA public key to validate JWT tokens with RS256 algorithm.", + " Tokens must include a valid \"exp\" claim.", + "", + "Both methods can be enabled simultaneously. Each client connection uses one", + "method chosen by the client.", + "", + "SECURITY CONSIDERATIONS:", + " • Ensure proper file permissions on certificate files (600 recommended)", + " • Use strong passwords and modern hashing algorithms for user database", + " • Regularly rotate JWT signing keys", + " • Monitor key update intervals for optimal security", + " • Use appropriate IP pool ranges to avoid conflicts", + "", + "EXAMPLES:", + " lightway-server --config-file /etc/lightway/server.yaml", + " lightway-server -c server.yaml --ip-pool 192.168.100.0/24 --log-level debug", + " lightway-server -c server.yaml --mode udp", + " lightway-server -c server.yaml --proxy-protocol", + "", + "ENVIRONMENT:", + " LW_SERVER_BIND_ADDRESS Server bind address", + " LW_SERVER_LOG_LEVEL Logging level", + " LW_SERVER_USER_DB Path to user database file", + " LW_SERVER_IP_POOL Client IP pool subnet", + "", + "SEE ALSO:", + " lightway-client(1), htpasswd(1), ip(8), iptables(8)", + "", + "REPORT BUGS:", + " https://github.com/expressvpn/lightway/issues", + ] + .join("\n"); + + cmd.long_about(long_about) + .after_help(after_help) +} + +fn main() -> std::io::Result<()> { + // Generate man page using clap_mangen + let cmd = create_server_command(); + let man = clap_mangen::Man::new(cmd); + let mut buffer = Vec::new(); + man.render(&mut buffer)?; + + // We can't use CARGO_TARGET_DIR in build.rs, ugly hack to get the target directory + let out_dir = env::var("OUT_DIR").unwrap(); + let target_path = Path::new(&out_dir).ancestors().nth(3).unwrap(); + + // Create man directory if it doesn't exist + let man_path = target_path.join("man"); + fs::create_dir_all(&man_path).unwrap(); + + // Write to file + let name = env::var("CARGO_PKG_NAME").unwrap(); + let manpage = man_path.join(format!("{}.1", name)); + fs::write(manpage, buffer)?; + + Ok(()) +} diff --git a/lightway-server/src/args.rs b/lightway-server/src/args.rs index a7578b36..f355be38 100644 --- a/lightway-server/src/args.rs +++ b/lightway-server/src/args.rs @@ -13,111 +13,144 @@ use lightway_app_utils::args::{ConnectionType, Duration, IpMap, LogFormat, LogLe #[config] #[derive(Parser, Debug)] -#[clap(about = "A lightway server")] +#[command( + about = "Lightway server - high-performance, secure, reliable VPN protocol in Rust", + version, + author = "ExpressVPN ", + after_help = concat!( + "EXAMPLES:\n", + " lightway-server -c server.yaml\n", + " lightway-server -c server.yaml --ip-pool 192.168.100.0/24\n", + " lightway-server -c server.yaml --mode udp --proxy-protocol\n", + "\n", + "See lightway-server(1) manpage for detailed configuration and usage information." + ) +)] pub struct Config { - /// Config File to load - #[clap(short, long)] + /// Configuration file path (YAML format) + /// Supports both absolute and relative paths + #[clap(short, long, value_name = "FILE")] pub config_file: PathBuf, - /// Connection mode - #[clap(short, long, value_enum, default_value_t=ConnectionType::Tcp)] + /// Transport protocol for client connections + /// TCP provides reliability, UDP provides better performance + #[clap(short, long, value_enum, default_value_t=ConnectionType::Tcp, value_name = "PROTOCOL")] pub mode: ConnectionType, - /// user database, in Apache htpasswd format - #[clap(long)] + /// Path to user database file (Apache htpasswd format) + /// Supports bcrypt, SHA-256, and SHA-512 password hashes only + #[clap(long, value_name = "FILE")] pub user_db: Option, - #[clap(long)] + /// RSA public key file for JWT token validation (PEM format) + /// Used to verify RS256-signed JWT tokens from clients + #[clap(long, value_name = "FILE")] pub token_rsa_pub_key_pem: Option, - /// Server certificate - #[clap(long, default_value = "./server.crt")] + /// Path to server TLS certificate file + /// Must be valid X.509 certificate in PEM format + #[clap(long, default_value = "./server.crt", value_name = "FILE")] pub server_cert: PathBuf, - /// Server key - #[clap(long, default_value = "./server.key")] + /// Path to server TLS private key file + /// Must correspond to the server certificate + #[clap(long, default_value = "./server.key", value_name = "FILE")] pub server_key: PathBuf, - /// Tun device name to use - #[clap(long, default_value = "lightway")] + /// TUN device name for tunnel interface + /// Must be unique if running multiple server instances + #[clap(long, default_value = "lightway", value_name = "NAME")] pub tun_name: String, - /// IP pool to assign clients - #[clap(long, default_value = "10.125.0.0/16")] + /// IP address pool for client assignment (CIDR notation) + /// All connected clients receive IPs from this range + #[clap(long, default_value = "10.125.0.0/16", value_name = "SUBNET")] pub ip_pool: Ipv4Net, - /// Additional IP address map. Maps from incoming IP address to - /// a subnet of "ip_pool" to use for that address. - #[clap(long)] + /// Custom IP mapping for specific client source addresses + /// Maps incoming IP to a specific subnet within the main IP pool + #[clap(long, value_name = "MAP")] pub ip_map: Option, - /// The IP assigned to the Tun device. If this is within `ip_pool` - /// then it will be reserved. - #[clap(long)] + /// IP address for the server's TUN device + /// Reserved from the IP pool if within that range + #[clap(long, value_name = "IP")] pub tun_ip: Option, - /// Server IP to send in network_config message - #[clap(long, default_value = "10.125.0.6")] + /// Server IP address sent to clients in network configuration + /// Represents the server endpoint within the tunnel + #[clap(long, default_value = "10.125.0.6", value_name = "IP")] pub lightway_server_ip: Ipv4Addr, - /// Client IP to send in network_config message - #[clap(long, default_value = "10.125.0.5")] + /// Default client IP address for network configuration + /// Template for client tunnel interface configuration + #[clap(long, default_value = "10.125.0.5", value_name = "IP")] pub lightway_client_ip: Ipv4Addr, - /// DNS IP to send in network_config message - #[clap(long, default_value = "10.125.0.1")] + /// DNS server IP address sent to clients + /// Used by clients for domain name resolution through VPN + #[clap(long, default_value = "10.125.0.1", value_name = "IP")] pub lightway_dns_ip: Ipv4Addr, - /// Enable Post Quantum Crypto - #[clap(long, default_value_t)] + /// Enable Post-Quantum Cryptography + /// Provides protection against future quantum computing attacks + #[clap(long)] pub enable_pqc: bool, - /// Enable IO-uring interface for Tunnel - #[clap(long, default_value_t)] + /// Enable io_uring for high-performance tunnel I/O (Linux only) + /// Provides better performance but requires recent Linux kernel + #[clap(long)] pub enable_tun_iouring: bool, - /// IO-uring submission queue count. Only applicable when - /// `enable_tun_iouring` is `true` - // Any value more than 1024 negatively impact the throughput - #[clap(long, default_value_t = 1024)] + /// io_uring submission queue size (max 1024 for optimal performance) + /// Only used when --enable-tun-iouring is enabled + #[clap(long, default_value_t = 1024, value_name = "COUNT")] pub iouring_entry_count: usize, - /// IO-uring sqpoll idle time. If non-zero use a kernel thread to - /// perform submission queue polling. After the given idle time - /// the thread will go to sleep. - #[clap(long, default_value = "100ms")] + /// Submission-queue polling idle time (milliseconds): + /// how long the kernel SQPOLL thread will wait for new submissions + /// before sleeping. 0 disables SQPOLL entirely. Higher values + /// reduce CPU usage (longer sleeps) but add latency on wakeup. + #[clap(long, default_value = "100ms", value_name = "DURATION")] pub iouring_sqpoll_idle_time: Duration, - /// Log format - #[clap(long, value_enum, default_value_t = LogFormat::Full)] + /// Log output format for different use cases + /// 'json' is recommended for structured logging and monitoring + #[clap(long, value_enum, default_value_t = LogFormat::Full, value_name = "FORMAT")] pub log_format: LogFormat, - /// Log level to use - #[clap(long, value_enum, default_value_t = LogLevel::Info)] + /// Logging verbosity level + /// Use 'debug' or 'trace' for troubleshooting server issues + #[clap(long, value_enum, default_value_t = LogLevel::Info, value_name = "LEVEL")] pub log_level: LogLevel, - /// The key update interval for DTLS/TLS 1.3 connections - #[clap(long, default_value = "15m")] + /// Interval for automatic TLS/DTLS key rotation + /// More frequent updates improve security but may impact performance + #[clap(long, default_value = "15m", value_name = "DURATION")] pub key_update_interval: Duration, - /// Address to listen to - #[clap(long, default_value = "0.0.0.0:27690")] + /// Server bind address and port (host:port) + /// Use 0.0.0.0 to listen on all interfaces + #[clap(long, default_value = "0.0.0.0:27690", value_name = "ADDRESS")] pub bind_address: SocketAddr, - /// Number of bind attempts, in case of AddrInUse failure - /// Will wait 1 second after failed attempt, before retrying - #[clap(long, default_value_t = NonZeroUsize::MIN)] + /// Number of bind retry attempts if address is in use + /// Waits 1 second between attempts; useful for service restarts + #[clap(long, default_value_t = NonZeroUsize::MIN, value_name = "COUNT")] pub bind_attempts: NonZeroUsize, - /// Enable PROXY protocol support (TCP only) + /// Enable PROXY protocol v1/v2 support (TCP mode only) + /// Required when running behind load balancers like HAProxy #[clap(long)] pub proxy_protocol: bool, - /// Set UDP buffer size. Default value is 15 MiB. - #[clap(long, default_value_t = ByteSize::mib(15))] + /// UDP socket buffer size for performance tuning + /// Larger buffers improve performance on high-throughput connections + #[clap(long, default_value_t = ByteSize::mib(15), value_name = "SIZE")] pub udp_buffer_size: ByteSize, - /// Enable WolfSSL debug logging + /// Enable detailed TLS/SSL debug logging (only available with `debug` feature) + /// Provides verbose cryptographic handshake information #[cfg(feature = "debug")] #[clap(long)] pub tls_debug: bool,