Repository navigation
architecture
Last updated: 2026-10-01 - Content re-verified against v1.6.14 (the figures below still hold: eight sponsor-funded relays, on-by-default telemetry with the ping-saved metric, GUI auto-select of the fastest relay, installer pipeline (cargo-dist), self-hosted proxy model, token authentication, TCP tunnel, configurable ports, 19-game support). Originally written for v1.6.5.
┌──────────────────────┐ UDP Tunnel ┌──────────────────────┐ Direct UDP ┌──────────────┐
│ │ (20B header + │ │ │ │
│ Game Client PC │ optional FEC) │ Proxy Node │──────────────▶│ Game Server │
│ + LightSpeed │────────────────▶│ (your VPS, │ │ (Epic/Valve) │
│ Client (Rust) │ │ ~500KB RAM) │◀──────────────│ │
│ │◀────────────────│ │ │ │
└──────────────────────┘ └──────────────────────┘ └──────────────┘
User PC Proxy VPS Game Infra
QUIC Control ◄──────────────────────► QUIC Control
(quinn, port 4433) (quinn, port 4433)
Key Principles:
- Data plane (game packets) uses raw UDP for minimum latency
- Control plane uses QUIC for reliability
- No encryption on the data plane - transparency is a feature, not a bug
- FEC adds loss recovery without retransmission (protocol v2)
- WARP integration provides free local route optimization
- Clients discover relays through a signed registry and auto-select the fastest on first run
By default the client uses the community relay network (eight sponsor-funded relays discovered through the signed registry, see Community Relay Network). Each user can also run their own proxy nodes. This is an example of a 2-node self-hosted setup:
All nodes are identical. Both boxes run the same
lightspeed-proxybinary. The words "primary" and "relay" below are topology role labels - not separate node types or products. Any node can serve both roles simultaneously.
┌──────────────────────────────────────────────────────────────────┐
│ Your Cloud VPS │
│ │
│ ┌────────────────────┐ ┌────────────────────┐ │
│ │ relay-us-west │ │ relay-asia-se │ │
│ │ <your-ip-1> │◄────────▶│ <your-ip-2> │ │
│ │ US-West (LA) │ │ Asia (Singapore) │ │
│ │ │ │ │ │
│ │ UDP :4434 (data) │ │ UDP :4434 (data) │ │
│ │ HTTP :8080 (health)│ │ HTTP :8080 (health)│ │
│ │ ~500KB RAM │ │ ~500KB RAM │ │
│ │ │ │ │ │
│ │ Topology role: │ │ Topology role: │ │
│ │ primary US proxy │ │ FEC multipath path │ │
│ │ (same binary) │ │ + SEA coverage │ │
│ └────────────────────┘ └────────────────────┘ │
│ │
│ Deployment: Native binary + systemd (no Docker overhead) │
└──────────────────────────────────────────────────────────────────┘
Latency depends on your own connection, not a fixed benchmark. A relay only
helps when the route through it beats your ISP's default path to the game
server, so the client probes every relay and picks the fastest for your
connection. See live relay health at https://shibbityshwab.github.io/lightspeed/.
main.rs ──────────────────────────── CLI, orchestration, test modes
├── config.rs ← TOML configuration management
├── error.rs ← Centralized error types (thiserror)
├── warp.rs ← Cloudflare WARP detection + management
├── redirect.rs ← UDP redirect proxy (game integration)
│
├── tunnel/ ← Core UDP tunnel engine
│ ├── mod.rs ← TunnelEngineState, TunnelStats, TunnelPacket
│ ├── header.rs ← Re-exports lightspeed_protocol header
│ ├── capture.rs ← CapturedPacket, CaptureFilter, PacketCapture trait
│ └── relay.rs ← UdpRelay: async send/recv, keepalive, RTT measurement
│
├── capture/ ← Platform-specific packet capture
│ ├── mod.rs ← Factory: create_default_capture(), list_interfaces()
│ ├── pcap_backend.rs ← Cross-platform pcap (feature: pcap-capture)
│ ├── windows.rs ← WFP backend (planned)
│ ├── linux.rs ← AF_PACKET backend (planned)
│ └── macos.rs ← BPF backend (planned)
│
├── route/ ← Proxy selection & failover
│ ├── mod.rs ← ProxyNode, RouteSelector trait, ProxyHealth
│ ├── selector.rs ← NearestSelector (latency), MlSelector (Linear Ensemble)
│ ├── multipath.rs ← Multi-path routing config
│ └── failover.rs ← Automatic failover state machine
│
├── quic/ ← QUIC control plane (feature: quic)
│ ├── mod.rs ← ControlClient (register, ping, disconnect)
│ ├── discovery.rs ← ProxyDiscovery (static, DNS, peer exchange)
│ └── health.rs ← HealthChecker, periodic proxy probing
│
├── ml/ ← ML route prediction
│ ├── mod.rs ← RouteModel wrapper (load/save/predict/train)
│ ├── data.rs ← Synthetic training data generation
│ ├── features.rs ← NetworkFeatures (11 inputs), LatencyTracker
│ ├── predict.rs ← Inference: linfa RF or heuristic fallback
│ └── trainer.rs ← Model training pipeline (Linear Ensemble)
│
│
├── telemetry.rs ← Session telemetry: collector, TelemetryEvent, report (on by default)
├── latency.rs ← direct (ICMP) vs relayed RTT tracking, saved_ms (RTT saved)
├── cli.rs ← CLI flag definitions (clap derive)
├── modes/ ← Run-mode handlers
│ ├── capture_mode.rs ← pcap capture + tunnel pipeline
│ ├── tunnel_test.rs ← Connectivity / RTT test
│ ├── live_test.rs ← Live session test with stats
│ └── proxy_probe.rs ← Proxy health probe
│
└── games/ ← Game-specific configuration
├── mod.rs ← GameConfig trait, detect_game(), auto_detect()
├── fortnite.rs ← Fortnite: EAC, ports 7000-9000
├── cs2.rs ← CS2: VAC, ports 27015-27050, SDR
├── dota2.rs ← Dota 2: VAC, ports 27015-27050, SDR
├── rust_game.rs ← Rust (Facepunch): EAC, ports 28015-28017
├── valorant.rs ← Valorant: Riot Vanguard, ports 7000-7500
├── apex.rs ← Apex Legends: EAC, ports 37000-37050
├── ow2.rs ← Overwatch 2: Blizzard Warden, ports 3478-6250
├── lol.rs ← League of Legends: Vanguard, ports 5000-5500
└── pubg.rs ← PUBG: BattlEye, ports 7000-17999
main.rs ──────────────────────────── Windows system-tray app (tray-item, WinAPI)
├── Tray icon: Connect / Disconnect / Quit menu items
├── Spawns lightspeed-client child process
└── Displays connection status in taskbar tooltip
main.rs ──────────────────────────── CLI, task spawning, graceful shutdown
├── config.rs ← ProxyConfig (server, network, security, rate_limit, metrics)
├── relay.rs ← RelayEngine: session mgmt, packet forward, FEC decode, ClientSender (UDP/TCP), run_tcp_inbound
├── auth.rs ← Authenticator: per-client token auth
├── metrics.rs ← ProxyMetrics: atomic counters, Prometheus export
├── health.rs ← HealthResponse: HTTP /health endpoint (JSON)
├── rate_limit.rs ← RateLimiter: per-client PPS/BPS limits
├── abuse.rs ← AbuseDetector: amplification/reflection, private IP block
└── control.rs ← QUIC control server (feature-gated)
lib.rs ──────────────────────────── Crate root, re-exports
├── header.rs ← TunnelHeader: 20-byte binary, v1/v2, encode/decode
├── control.rs ← ControlMessage: binary QUIC messages
├── fec.rs ← FecEncoder/FecDecoder: XOR parity, FecHeader, FecStats
├── framing.rs ← TCP length-prefixed framing (client→proxy TCP leg)
└── telemetry.rs ← TelemetryEvent schema, POST /telemetry JSON payload
1. Game client configured to connect to localhost:LOCAL_PORT
2. [redirect] UdpRedirect receives game packet on local socket
3. [tunnel] TunnelHeader created (20 bytes: version, seq, timestamp, orig addrs)
4. [fec] If FEC enabled: FecEncoder groups K packets, generates parity
5. [relay] Header + payload sent to proxy via UDP (port 4434) - or TCP (port 4434) when `--tcp` is set
6. [proxy] Proxy receives, strips header, validates session
7. [proxy] Original UDP packet forwarded to game server
8. [game] Game server sees user's ORIGINAL IP (preserved!)
1. Game sends UDP to game server IP:port normally
2. [capture] pcap/WFP intercepts packet on network interface
3. [capture] Packet parsed → CapturedPacket { src, dst, payload }
4. [route] RouteSelector picks optimal proxy (Nearest or ML)
5. [tunnel] TunnelHeader created (20 bytes)
6. [fec] If FEC enabled: FecEncoder adds parity packets
7. [relay] Header + payload sent to proxy via UDP (port 4434) - or TCP when `--tcp` is set
8-9. Same as redirect mode
1. Game server sends UDP response to proxy (via session mapping)
2. [proxy] Proxy wraps response in TunnelHeader
3. [proxy] Wrapped packet sent back to client
4. [relay] Client receives wrapped packet
5. [fec] If FEC enabled: FecDecoder reassembles, recovers any lost packets
6. [tunnel] Header stripped, latency measured from timestamp
7. [deliver] Original response delivered to game client
Sender (Client):
Packet 1 ─┐
Packet 2 ─┤ XOR together
Packet 3 ─┤ ──────────▶ Parity Packet P
Packet 4 ─┘
Send: [P1, P2, P3, P4, P_parity] (K+1 packets per group)
Receiver (Proxy / Client):
Received: [P1, __, P3, P4, P_parity] (P2 lost!)
Recovery: P2 = P1 ⊕ P3 ⊕ P4 ⊕ P_parity (XOR recovery in ~3ms)
Without FEC: P2 lost → game retransmits → +400ms penalty
With FEC: P2 recovered instantly → no visible impact to gameplay
Without WARP:
User → True ISP → SBN/AWN SGP → HGC SGP (+29ms detour!) → Pacific → LA
Total: ~203-206ms
With WARP:
User → CF BKK PoP (4ms) → CF backbone → NTT (36ms) → Pacific (166ms) → LA
Total: ~193-197ms (bypasses HGC detour via Cloudflare NTT peering)
[quic/health] Periodic health checks → update ProxyHealth
[quic/discovery] Discover new proxy nodes → update proxy list
[route/failover] Monitor keepalive → trigger failover if needed
[ml/predict] Collect latency feedback → update route predictions
[warp] Detect/manage WARP state → optimize local routing
pub trait PacketCapture: Send + Sync {
fn start(&mut self, filter: &CaptureFilter) -> Result<(), CaptureError>;
fn stop(&mut self) -> Result<(), CaptureError>;
fn next_packet(&mut self) -> Result<CapturedPacket, CaptureError>;
fn is_active(&self) -> bool;
}pub trait RouteSelector: Send + Sync {
fn select(&self, game_server: SocketAddrV4, proxies: &[ProxyNode])
-> Result<SelectedRoute, RouteError>;
fn feedback(&mut self, proxy_id: &str, observed_latency_us: u64);
fn strategy(&self) -> RouteStrategy;
}pub trait GameConfig: Send + Sync {
fn name(&self) -> &str;
fn process_names(&self) -> &[&str];
fn ports(&self) -> (u16, u16);
fn anti_cheat(&self) -> &str;
fn typical_pps(&self) -> u32;
fn packet_size_range(&self) -> (usize, usize);
}| Crate | Purpose | Why This One |
|---|---|---|
| tokio | Async runtime | Industry standard, full-featured, excellent for networking |
| bytes | Zero-copy buffers | Efficient packet handling without allocation |
| pcap | Packet capture | Cross-platform libpcap binding, well-maintained |
| quinn | QUIC client/server | Pure Rust, built on rustls, active development |
| linfa | ML toolkit | Native Rust ML - no Python dependency, fast inference |
| clap | CLI parsing | Derive-based, excellent UX, industry standard |
| tracing | Structured logging | Async-aware, spans for latency tracking, filterable |
| serde/toml | Config parsing | Standard serialization, human-readable config format |
| thiserror | Error types | Ergonomic custom error enums |
| anyhow | Error handling | Flexible error propagation for application code |
| socket2 | Advanced sockets | Low-level socket options for UDP performance tuning |
| prometheus | Metrics | Standard metrics format, compatible with free monitoring |
| rand | RNG | Used in FEC, ML synthetic data, session tokens |
Heavy dependencies requiring a C compiler are behind cargo features:
-
pcap-capture- requires Npcap (Windows) or libpcap (Linux) -
quic- requires ring (via rustls) → needs C compiler -
ml- requires linfa ecosystem → may need BLAS -
full- enables all of the above
Default build (no features) compiles with just the Rust toolchain.
- Capture: Npcap via pcap crate (MVP), WFP native (planned)
- Redirect: Local UDP proxy - no admin privileges needed
- Anti-cheat: Must not trigger EAC/VAC. pcap is passive capture, not modification
- Admin: Packet capture requires Administrator privileges; redirect mode does not
-
Binary: Single
.exe, no runtime dependencies (except Npcap for capture) - WARP: Cloudflare WARP CLI auto-detected if installed
- Capture: libpcap (MVP), AF_PACKET with PACKET_MMAP (planned)
- Proxy: Primary proxy deployment target (any Linux VPS)
-
Permissions: Requires
CAP_NET_RAWcapability or root for capture; redirect mode unprivileged - Deployment: Native binary + systemd, ~500KB RAM
- Capture: libpcap via pcap crate
- Permissions: Requires root or BPF group membership
- Priority: Lower priority, but supported via cross-platform pcap
| Decision | Choice | Rationale |
|---|---|---|
| Language | Rust | Zero-cost abstractions, memory safety, excellent async |
| Async Runtime | Tokio | Most mature, best ecosystem support |
| Protocol | Custom UDP + QUIC control | Minimum overhead on data path |
| No Encryption | Deliberate | Anti-cheat friendly, no overhead, IP preservation |
| Feature Gating | Cargo features | Allow compilation without C compiler for dev |
| IP Preservation | Header carries original IP | Game servers see real user IP |
| ML Framework | linfa | Native Rust, no Python, fast inference |
| Config Format | TOML | Human-readable, Rust ecosystem standard |
| FEC | XOR parity | Simple, low overhead, recovers single packet loss per group |
| WARP | Optional integration | Free 5-10ms improvement, auto-detected |
| Infra Provider | Any Linux VPS | Provider-agnostic; the proxy is a single static binary |
| No Docker | Native binary | 350x less RAM (500KB vs 175MB), simpler systemd |
| Redirect Mode | Local UDP proxy | No admin/root needed, game connects to localhost |