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.