Files
wgcloak/docs/ARCHITECTURE.md
T

74 lines
3.4 KiB
Markdown

# 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.
```text
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:
```text
STARTING → RESOLVING → PROBING → AUTHENTICATING → CONNECTED
│ │
└───────────┘ failure
▼
RECONNECTING
│
└→ PROBING
```
In `auto` mode the target order is 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.
## 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.
This document describes the intended v1 architecture. Check the milestone
matrix before relying on a transport or control command in a particular build.