Files
wgcloak/docs/ARCHITECTURE.md
T

3.7 KiB

Architecture

wgcloak is a single Linux userspace process with a client or server role. The core moves opaque datagrams between a local UDP socket and a transport session. It does not know whether the payload is WireGuard, DNS, or another UDP protocol.

CLIENT                                      SERVER
local UDP peer                              transport listener
     │                                             │
     ▼                                             ▼
local listener ── tunnel core ── transport ── authenticated session
                                                   │
                                                   ▼
                                      dedicated connected UDP backend socket
                                                   │
                                                   ▼
                                          configured UDP backend

Ownership boundaries

  • The local listener receives datagrams and remembers the most recently active local peer for return traffic. One active peer per v1 tunnel is sufficient.
  • The core owns session lifecycle, limits, datagram-size checks, reconnect policy, and statistics. Payload bytes remain opaque.
  • A transport owns connection establishment and wire representation. Every transport exposes the same logical send/receive/close behavior and a maximum datagram size.
  • Authentication is a separate concern. Direct UDP uses the documented challenge/HMAC packet protocol; TLS-capable transports authenticate the client after transport establishment.
  • The server creates a backend UDP socket only after client authentication and maps that socket to one session. A backend response therefore has natural session ownership without inspecting the backend protocol.

Transport lifecycle

The client state machine is:

STARTING → RESOLVING → PROBING → AUTHENTICATING → CONNECTED
                                            │           │
                                            └───────────┘ failure
                                                        ▼
                                                   RECONNECTING
                                                        │
                                                        └→ PROBING

In auto mode the configured order defaults to direct UDP, QUIC DATAGRAM, HTTP/3 CONNECT-UDP, then TLS/TCP. Authentication rejection is a configuration error, not permission to probe indefinitely. Network failures use bounded exponential backoff with jitter (250 ms to 30 s), reset after a successful connection. These transports are wired into the current runtime; the acceptance checklist distinguishes implementation from completed v1 sign-off.

Server isolation

One malformed or unauthenticated packet must be rejected without terminating the listener or affecting another client. Server limits cover active sessions, per-source sessions, pending handshakes, handshake duration, authentication attempts, and maximum datagram size. Expiry closes the backend socket and releases replay/session state.

Privileges and filesystem

Normal operation uses ordinary UDP/TCP/Unix sockets and needs no root, CAP_NET_ADMIN, or CAP_SYS_ADMIN. CAP_NET_BIND_SERVICE is optional when a reviewed deployment must bind a port below 1024. The control socket is local and protected by filesystem ownership/mode; it is not a network listener.

Configuration reload and certificate/key reload are not implemented. The control reload command returns an explicit unsupported response. The reconnect command applies to the client, while the server supports status, stats, and graceful shutdown.