refactor: clap CLI parser, safety docs, dead code docs, cross-refs
Some checks failed
Mirror to GitHub / mirror (push) Failing after 26s
Build Release Binaries / build-amd64 (push) Failing after 4m1s

Audit items 6, 8, 9, 10:

#6 - Relay CLI: replaced 154-line manual parse_args() with clap derive
     (13 flags/options preserved, auto --help, --version from build hash)
#8 - wzp-native: added # Safety docs to all 3 unsafe extern "C" fns
#9 - wzp-crypto: documented x25519_static_secret/public as reserved for
     future static-key federation auth (not dead code, intentionally unused)
#10 - Cross-references between quality.rs ↔ dred_tuner.rs module docs

368 tests passing, 0 regressions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Siavash Sameni
2026-04-13 15:40:49 +04:00
parent d539a6dfb9
commit 81b5522942
7 changed files with 265 additions and 136 deletions

119
Cargo.lock generated
View File

@@ -88,6 +88,56 @@ dependencies = [
"libc",
]
[[package]]
name = "anstream"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
[[package]]
name = "anstyle-parse"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys 0.61.2",
]
[[package]]
name = "anyhow"
version = "1.0.102"
@@ -851,7 +901,7 @@ checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
dependencies = [
"atty",
"bitflags 1.3.2",
"clap_lex",
"clap_lex 0.2.4",
"indexmap 1.9.3",
"once_cell",
"strsim 0.10.0",
@@ -859,6 +909,40 @@ dependencies = [
"textwrap",
]
[[package]]
name = "clap"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f"
dependencies = [
"anstream",
"anstyle",
"clap_lex 1.1.0",
"strsim 0.11.1",
]
[[package]]
name = "clap_derive"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a"
dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "clap_lex"
version = "0.2.4"
@@ -868,6 +952,12 @@ dependencies = [
"os_str_bytes",
]
[[package]]
name = "clap_lex"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
[[package]]
name = "cmake"
version = "0.1.58"
@@ -883,6 +973,12 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cefd04ca4a2f096acf5f44da5e5931436d030a620901f1fe8fa773e6b9de65b"
[[package]]
name = "colorchoice"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
[[package]]
name = "combine"
version = "4.6.7"
@@ -2829,6 +2925,12 @@ dependencies = [
"once_cell",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
[[package]]
name = "itertools"
version = "0.13.0"
@@ -3355,7 +3457,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "805d5964d1e7a0006a7fdced7dae75084d66d18b35f1dfe81bd76929b1f8da0c"
dependencies = [
"anyhow",
"clap",
"clap 3.2.25",
"dasp",
"dasp_interpolate",
"dasp_ring_buffer",
@@ -3632,6 +3734,12 @@ version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "once_cell_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
[[package]]
name = "opaque-debug"
version = "0.3.1"
@@ -6560,6 +6668,12 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
version = "1.23.0"
@@ -7805,6 +7919,7 @@ dependencies = [
"axum 0.7.9",
"bytes",
"chrono",
"clap 4.6.0",
"dashmap",
"dirs",
"futures-util",

View File

@@ -18,10 +18,14 @@ use crate::session::ChaChaSession;
pub struct WarzoneKeyExchange {
/// Ed25519 signing key (identity).
signing_key: SigningKey,
/// X25519 static secret (derived from seed, used for identity encryption).
/// X25519 static secret derived from identity seed. Reserved for future
/// use in static-key federation authentication (not used in current
/// ephemeral-only handshake protocol).
#[allow(dead_code)]
x25519_static_secret: StaticSecret,
/// X25519 static public key.
/// X25519 static public key derived from identity seed. Reserved for
/// future use in static-key federation authentication (not used in
/// current ephemeral-only handshake protocol).
#[allow(dead_code)]
x25519_static_public: X25519PublicKey,
/// Ephemeral X25519 secret for the current call (set by generate_ephemeral).

View File

@@ -26,6 +26,11 @@ pub extern "C" fn wzp_native_version() -> i32 {
/// Writes a NUL-terminated string into `out` (capped at `cap`) and
/// returns bytes written excluding the NUL.
///
/// # Safety
/// `out` must be a valid pointer to at least `cap` contiguous bytes of
/// writable memory. Passing a null pointer or zero capacity is safe
/// (returns 0), but a dangling non-null pointer is undefined behaviour.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wzp_native_hello(out: *mut u8, cap: usize) -> usize {
const MSG: &[u8] = b"hello from wzp-native\0";
@@ -273,6 +278,11 @@ pub extern "C" fn wzp_native_audio_capture_available() -> usize {
/// Read captured PCM samples from the capture ring. Returns the number
/// of `i16` samples actually copied into `out` (may be less than
/// `out_len` if the ring is empty).
///
/// # Safety
/// `out` must be a valid pointer to `out_len` contiguous `i16` values.
/// The caller must ensure no other thread writes to the same buffer
/// concurrently. Passing a null pointer or zero length is safe (returns 0).
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wzp_native_audio_read_capture(out: *mut i16, out_len: usize) -> usize {
if out.is_null() || out_len == 0 {
@@ -286,6 +296,12 @@ pub unsafe extern "C" fn wzp_native_audio_read_capture(out: *mut i16, out_len: u
/// samples actually enqueued (may be less than `in_len` if the ring
/// is nearly full — in practice the caller should pace to 20 ms
/// frames and spin briefly if the ring is full).
///
/// # Safety
/// `input` must be a valid pointer to `in_len` contiguous `i16` values
/// that remain valid for the duration of the call. Passing a null pointer
/// or zero length is safe (returns 0). The caller must not free or mutate
/// the buffer while this function is executing.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wzp_native_audio_write_playout(input: *const i16, in_len: usize) -> usize {
if input.is_null() || in_len == 0 {

View File

@@ -10,6 +10,10 @@
//! prediction): when jitter variance spikes >30% over a 200 ms window — typical
//! of Starlink satellite handovers — it temporarily boosts DRED to the maximum
//! allowed for the current codec before packets actually start dropping.
//!
//! See also: [`crate::quality`] for discrete tier classification that drives
//! codec switching. DredTuner operates within a tier, adjusting DRED
//! parameters continuously based on live network metrics.
use crate::CodecId;

View File

@@ -1,3 +1,5 @@
//! See also: [`crate::dred_tuner`] for continuous DRED tuning within a tier.
use std::collections::VecDeque;
use std::time::{Duration, Instant};

View File

@@ -20,6 +20,7 @@ bytes = { workspace = true }
serde = { workspace = true }
toml = "0.8"
anyhow = "1"
clap = { version = "4", features = ["derive"] }
reqwest = { version = "0.12", features = ["json"] }
serde_json = "1"
rustls = { version = "0.23", default-features = false, features = ["ring", "std"] }

View File

@@ -12,6 +12,7 @@ use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
use std::time::Duration;
use clap::Parser;
use tokio::sync::Mutex;
use tracing::{debug, error, info, warn};
@@ -30,6 +31,72 @@ async fn close_transport(t: &dyn wzp_proto::MediaTransport, context: &str) {
}
}
/// WarzonePhone relay daemon — SFU, federation, direct-call signaling
#[derive(Parser, Debug)]
#[command(name = "wzp-relay", version = env!("WZP_BUILD_HASH"))]
struct Args {
/// Load config from TOML file (creates example if missing)
#[arg(short = 'c', long = "config")]
config_file: Option<String>,
/// Identity file path (creates if missing, uses OsRng)
#[arg(short = 'i', long)]
identity: Option<String>,
/// Listen address for QUIC connections
#[arg(long)]
listen: Option<SocketAddr>,
/// Remote relay address for forwarding (disables room mode)
#[arg(long)]
remote: Option<SocketAddr>,
/// featherChat auth endpoint (e.g., https://chat.example.com/v1/auth/validate).
/// When set, clients must send a bearer token as first signal message.
#[arg(long)]
auth_url: Option<String>,
/// Prometheus metrics HTTP port (e.g., 9090). Disabled if not set.
#[arg(long)]
metrics_port: Option<u16>,
/// Peer relay to probe for health monitoring (repeatable)
#[arg(long = "probe")]
probe: Vec<SocketAddr>,
/// Enable mesh mode (probes all --probe targets concurrently)
#[arg(long)]
probe_mesh: bool,
/// Enable trunk batching for outgoing media in room mode
#[arg(long)]
trunking: bool,
/// WebSocket listener port for browser clients (e.g., 8080)
#[arg(long)]
ws_port: Option<u16>,
/// Directory to serve static files from (HTML/JS/WASM)
#[arg(long)]
static_dir: Option<String>,
/// Declare a room as global (bridged across federation). Repeatable.
#[arg(long = "global-room")]
global_room: Vec<String>,
/// Log packet headers for a room ('*' for all rooms)
#[arg(long)]
debug_tap: Option<String>,
/// JSONL event log file path for protocol analysis
#[arg(long)]
event_log: Option<String>,
/// Print mesh health table and exit (diagnostic)
#[arg(long)]
mesh_status: bool,
}
/// Parsed CLI result — config + identity path.
struct CliResult {
config: RelayConfig,
@@ -39,25 +106,21 @@ struct CliResult {
}
fn parse_args() -> CliResult {
let args: Vec<String> = std::env::args().collect();
let args = Args::parse();
// First pass: extract --config and --identity
let mut config_file = None;
let mut identity_path = None;
let mut i = 1;
while i < args.len() {
match args[i].as_str() {
"--config" | "-c" => { i += 1; config_file = args.get(i).cloned(); }
"--identity" | "-i" => { i += 1; identity_path = args.get(i).cloned(); }
_ => {}
}
i += 1;
// Handle --mesh-status: print and exit
if args.mesh_status {
let m = RelayMetrics::new();
print!("{}", wzp_relay::probe::mesh_summary(m.registry()));
std::process::exit(0);
}
// Track if we need to create the config after identity is known
let config_needs_create = config_file.as_ref().map(|p| !std::path::Path::new(p).exists()).unwrap_or(false);
let config_needs_create = args.config_file.as_ref()
.map(|p| !std::path::Path::new(p).exists())
.unwrap_or(false);
let mut config = if let Some(ref path) = config_file {
let mut config = if let Some(ref path) = args.config_file {
if config_needs_create {
// Will be re-created with personalized info after identity is loaded
RelayConfig::default()
@@ -73,125 +136,49 @@ fn parse_args() -> CliResult {
};
// CLI flags override config file values
let mut i = 1;
while i < args.len() {
match args[i].as_str() {
"--config" | "-c" => { i += 1; } // already handled
"--identity" | "-i" => { i += 1; } // already handled
"--listen" => {
i += 1;
config.listen_addr = args.get(i).expect("--listen requires an address")
.parse().expect("invalid --listen address");
if let Some(addr) = args.listen {
config.listen_addr = addr;
}
"--remote" => {
i += 1;
config.remote_relay = Some(
args.get(i).expect("--remote requires an address")
.parse().expect("invalid --remote address"),
);
if let Some(addr) = args.remote {
config.remote_relay = Some(addr);
}
"--auth-url" => {
i += 1;
config.auth_url = Some(
args.get(i).expect("--auth-url requires a URL").to_string(),
);
if let Some(url) = args.auth_url {
config.auth_url = Some(url);
}
"--metrics-port" => {
i += 1;
config.metrics_port = Some(
args.get(i).expect("--metrics-port requires a port number")
.parse().expect("invalid --metrics-port number"),
);
if let Some(port) = args.metrics_port {
config.metrics_port = Some(port);
}
"--probe" => {
i += 1;
let addr: SocketAddr = args.get(i)
.expect("--probe requires an address")
.parse()
.expect("invalid --probe address");
config.probe_targets.push(addr);
if !args.probe.is_empty() {
config.probe_targets.extend(args.probe);
}
"--probe-mesh" => {
if args.probe_mesh {
config.probe_mesh = true;
}
"--trunking" => {
if args.trunking {
config.trunking_enabled = true;
}
"--ws-port" => {
i += 1;
config.ws_port = Some(
args.get(i).expect("--ws-port requires a port number")
.parse().expect("invalid --ws-port number"),
);
if let Some(port) = args.ws_port {
config.ws_port = Some(port);
}
"--static-dir" => {
i += 1;
config.static_dir = Some(
args.get(i).expect("--static-dir requires a directory path").to_string(),
);
if let Some(dir) = args.static_dir {
config.static_dir = Some(dir);
}
"--global-room" => {
i += 1;
config.global_rooms.push(wzp_relay::config::GlobalRoomConfig {
name: args.get(i).expect("--global-room requires a room name").to_string(),
});
for name in args.global_room {
config.global_rooms.push(wzp_relay::config::GlobalRoomConfig { name });
}
"--debug-tap" => {
i += 1;
config.debug_tap = Some(
args.get(i).expect("--debug-tap requires a room name (or '*' for all)").to_string(),
);
if let Some(tap) = args.debug_tap {
config.debug_tap = Some(tap);
}
"--event-log" => {
i += 1;
config.event_log = Some(
args.get(i).expect("--event-log requires a file path").to_string(),
);
if let Some(log) = args.event_log {
config.event_log = Some(log);
}
"--version" | "-V" => {
println!("wzp-relay {}", env!("WZP_BUILD_HASH"));
std::process::exit(0);
CliResult {
config,
identity_path: args.identity,
config_file: args.config_file,
config_needs_create,
}
"--mesh-status" => {
// Print mesh table from a fresh registry and exit.
// In practice this is useful after the relay has been running;
// here we just demonstrate the formatter with an empty registry.
let m = RelayMetrics::new();
print!("{}", wzp_relay::probe::mesh_summary(m.registry()));
std::process::exit(0);
}
"--help" | "-h" => {
eprintln!("Usage: wzp-relay [--config <path>] [--listen <addr>] [--remote <addr>] [--auth-url <url>] [--metrics-port <port>] [--probe <addr>]... [--probe-mesh] [--mesh-status]");
eprintln!();
eprintln!("Options:");
eprintln!(" -c, --config <path> Load config from TOML file (creates example if missing)");
eprintln!(" -i, --identity <path> Identity file path (creates if missing, uses OsRng)");
eprintln!(" --listen <addr> Listen address (default: 0.0.0.0:4433)");
eprintln!(" --remote <addr> Remote relay for forwarding (disables room mode)");
eprintln!(" --auth-url <url> featherChat auth endpoint (e.g., https://chat.example.com/v1/auth/validate)");
eprintln!(" When set, clients must send a bearer token as first signal message.");
eprintln!(" --metrics-port <port> Prometheus metrics HTTP port (e.g., 9090). Disabled if not set.");
eprintln!(" --probe <addr> Peer relay to probe for health monitoring (repeatable).");
eprintln!(" --probe-mesh Enable mesh mode (mark config flag, probes all --probe targets).");
eprintln!(" --mesh-status Print mesh health table and exit (diagnostic).");
eprintln!(" --trunking Enable trunk batching for outgoing media in room mode.");
eprintln!(" --global-room <name> Declare a room as global (bridged across federation). Repeatable.");
eprintln!(" --debug-tap <room> Log packet headers for a room ('*' for all rooms).");
eprintln!(" --ws-port <port> WebSocket listener port for browser clients (e.g., 8080).");
eprintln!(" --static-dir <dir> Directory to serve static files from (HTML/JS/WASM).");
eprintln!();
eprintln!("Room mode (default):");
eprintln!(" Clients join rooms by name. Packets forwarded to all others (SFU).");
std::process::exit(0);
}
other => {
eprintln!("unknown argument: {other}");
std::process::exit(1);
}
}
i += 1;
}
CliResult { config, identity_path, config_file, config_needs_create }
}
struct RelayStats {