Files
wz-phone/docs/PRD-netcheck.md
Siavash Sameni f83361895e
Some checks failed
Mirror to GitHub / mirror (push) Failing after 23s
Build Release Binaries / build-amd64 (push) Failing after 3m35s
docs: add PRDs for Phase 8 Tailscale-inspired features
5 new PRDs:
- PRD-public-stun.md — RFC 5389 STUN client
- PRD-portmap.md — NAT-PMP/PCP/UPnP port mapping
- PRD-ice-regather.md — Mid-call ICE re-gathering
- PRD-netcheck.md — Network diagnostic
- PRD-relay-selection.md — Region-based relay selection

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 11:08:46 +04:00

3.2 KiB

PRD: Network Diagnostic (Netcheck)

Phase: Implemented Status: Done (2026-04-14) Crate: wzp-client

Problem

When P2P connections fail or call quality is poor, there is no diagnostic tool to understand why. Users and developers must manually probe STUN, check NAT type, test relay connectivity, and verify port mapping support — all separately. Tailscale's netcheck consolidates all of this into a single diagnostic report.

Solution

A comprehensive run_netcheck() function that probes all network capabilities in parallel and produces a structured NetcheckReport. Exposed as a CLI subcommand (wzp-client --netcheck) and available for in-app diagnostics.

Implementation

New Module: crates/wzp-client/src/netcheck.rs

NetcheckReport:

pub struct NetcheckReport {
    pub nat_type: NatType,
    pub reflexive_addr: Option<String>,
    pub ipv4_reachable: bool,
    pub ipv6_reachable: bool,
    pub hairpin_works: Option<bool>,
    pub port_mapping: Option<PortMapProtocol>,
    pub relay_latencies: Vec<RelayLatency>,
    pub preferred_relay: Option<String>,
    pub stun_latency_ms: Option<u32>,
    pub upnp_available: bool,
    pub pcp_available: bool,
    pub nat_pmp_available: bool,
    pub gateway: Option<String>,
    pub duration_ms: u32,
    pub stun_probes: Vec<NatProbeResult>,
}

Probes (all parallel via tokio::join!):

  1. STUN probesprobe_stun_servers() to all configured STUN servers
  2. Relay latenciesprobe_reflect_addr() to each configured relay
  3. Port mappingacquire_port_mapping() to detect NAT-PMP/PCP/UPnP
  4. Gatewaydefault_gateway() for the router address
  5. IPv6 — attempt to bind [::]:0 and send to an IPv6 STUN server

Derived fields:

  • nat_type / reflexive_addr — from classify_nat() on STUN probes
  • ipv4_reachable — true if any STUN probe succeeded
  • preferred_relay — relay with lowest RTT
  • port_mapping / nat_pmp_available / pcp_available / upnp_available — from portmap result

Human-readable output: format_report() produces a formatted text report with sections for NAT info, port mapping, STUN probes, relay latencies.

CLI Integration

wzp-client --netcheck <relay-addr> — runs the diagnostic using the specified relay plus default STUN servers, prints the report, and exits.

Deferred

  • Hairpin test — send packet from shared endpoint to own reflexive addr to test NAT hairpinning. Architecture is in place (hairpin_works: Option<bool>) but the actual probe is not yet implemented.
  • Android/Desktop in-app UI — expose via JNI (Android) and Tauri command (desktop) for user-facing diagnostics.

Files

File Change
crates/wzp-client/src/netcheck.rs New — NetcheckReport + run_netcheck + format_report
crates/wzp-client/src/lib.rs Add pub mod netcheck
crates/wzp-client/src/cli.rs --netcheck flag + handler

Testing

  • 5 unit tests: default config, report JSON serialization + roundtrip, RelayLatency serialization, format_report with empty relays, format_report with full data (STUN probes, relay latencies, preferred relay, port mapping)
  • 1 integration test (#[ignore]): full netcheck run