feat: complete wgcloak v1 transports
This commit is contained in:
1 parent
49ec9d8c33
commit
cedab4910e
47 files changed
+2849
-400
No files matched your search
@@ -0,0 +1,91 @@
|
||||
# Benchmarking
|
||||
|
||||
wgcloak has a deterministic Criterion target for protocol and transport
|
||||
building blocks. It does not open sockets, require certificates, or depend on
|
||||
network timing. Because the target is declared with `harness = false`,
|
||||
`cargo test --all-targets` executes it as a smoke check; that run is not a
|
||||
measured benchmark report.
|
||||
|
||||
## Run it
|
||||
|
||||
```bash
|
||||
# Compile the benchmark without running it.
|
||||
cargo bench --bench protocol_transports --no-run
|
||||
|
||||
# Run the complete local benchmark and write Criterion reports under target/.
|
||||
cargo bench --bench protocol_transports
|
||||
|
||||
# Run one group while iterating.
|
||||
cargo bench --bench protocol_transports -- direct_protocol
|
||||
```
|
||||
|
||||
The target measures:
|
||||
|
||||
- direct authenticated DATA packet encode, bounded parse, and MAC verification
|
||||
for 64, 512, and 1200-byte opaque payloads;
|
||||
- TLS/TCP frame encoding plus incremental split-input and coalesced-input
|
||||
decoding;
|
||||
- HTTP/3 HTTP Datagram context encoding/decoding, capsule encoding/decoding,
|
||||
and CONNECT-UDP challenge-response verification;
|
||||
- replay-window sequential acceptance and duplicate rejection.
|
||||
|
||||
The benchmark input and cryptographic keys are fixed, non-secret test values.
|
||||
They are not production credentials. Criterion's default warm-up, sample, and
|
||||
measurement settings are suitable for a first comparison; keep those settings
|
||||
stable when comparing commits.
|
||||
|
||||
## Environment report
|
||||
|
||||
Record at least the following with published results:
|
||||
|
||||
```text
|
||||
date/time (UTC):
|
||||
commit:
|
||||
host/CPU:
|
||||
RAM:
|
||||
OS/kernel:
|
||||
rustc --version:
|
||||
cargo --version:
|
||||
governor/power profile:
|
||||
command and Criterion filter:
|
||||
notes (background load, thermal state, VM/container):
|
||||
```
|
||||
|
||||
Do not compare values from different CPU governors, virtualized hosts, or
|
||||
substantially different Rust/dependency lockfiles without noting the change.
|
||||
Criterion reports are local artifacts and are not committed by default.
|
||||
|
||||
## Network benchmark status
|
||||
|
||||
No loopback UDP relay benchmark is enabled yet. A socket benchmark would be
|
||||
environment-sensitive: scheduler load, kernel socket buffers, loopback queueing,
|
||||
and task runtime configuration can dominate the result. Add it as an explicit
|
||||
opt-in benchmark (or a separate executable) only when it reports packet loss,
|
||||
latency percentiles, CPU context, socket buffer settings, and a bounded run
|
||||
duration. It must not run as part of `cargo test` or the deterministic Criterion
|
||||
group.
|
||||
|
||||
## Datagram-size analysis and recommendation
|
||||
|
||||
The configured default application payload is **1200 bytes**. The project-wide
|
||||
configurable safety ceiling is **16,384 bytes**; transport framing and path
|
||||
capabilities may produce a lower effective session maximum. The wire overheads
|
||||
are:
|
||||
|
||||
| Path | Per-datagram overhead relevant to the configured payload |
|
||||
| --- | --- |
|
||||
| Direct UDP | 32-byte authenticated DATA header; the u16 packet limit is theoretical, not an MTU guarantee |
|
||||
| TLS/TCP | 2-byte big-endian frame length; TCP preserves framing but does not provide an MTU bound |
|
||||
| HTTP/3 CONNECT-UDP | HTTP Datagram context varint plus h3-quinn's quarter-stream varint; the implementation subtracts both before accepting payload |
|
||||
| QUIC DATAGRAM | QUIC/path framing and UDP/IP headers are path-dependent; the peer's negotiated maximum is authoritative |
|
||||
|
||||
Recommendation: retain **1200 bytes as the practical default** for ordinary
|
||||
Internet paths. Users may configure larger values up to **16,384 bytes** for
|
||||
jumbo/custom paths, subject to each transport's negotiated/path-specific
|
||||
effective maximum. Boundary tests should cover each transport, including HTTP/3
|
||||
stream/context overhead at both one-byte and multi-byte varint widths.
|
||||
|
||||
The direct protocol and TLS framing have larger u16 wire limits, but those
|
||||
limits are not safe project configuration values. The 16,384-byte ceiling
|
||||
keeps parser/session allocations bounded. HTTP/3 and QUIC limits remain
|
||||
negotiated/path-dependent and are bounded further before allocation and send.
|
||||
+84
-52
@@ -1,71 +1,103 @@
|
||||
# Development state
|
||||
|
||||
Checkpoint: 2026-09-15 end of day. Branch: `main`. Latest commit:
|
||||
`586ff8f` (`checkpoint: integrate authenticated transports`). The working tree
|
||||
is clean. Config and client-ID changes are included in this commit. The
|
||||
resumed recovery-only assignments after this commit made no edits.
|
||||
Checkpoint: 2026-09-19. Branch: `main`. HEAD: `49ec9d8`
|
||||
(`docs: refresh development checkpoint`). The working tree is not clean: this
|
||||
checkout contains concurrent implementation, documentation, benchmark, fuzz,
|
||||
and integration-test changes. No commit was created for this checkpoint.
|
||||
|
||||
## Implemented behavior
|
||||
|
||||
- The package has a reusable Rust library and a thin binary. Integration tests
|
||||
import the library; module unit tests run once in the library test target.
|
||||
- The package provides a reusable Rust library and thin binary. Integration
|
||||
tests use the library rather than path-including production modules.
|
||||
- Client and server runtimes support authenticated direct UDP, QUIC DATAGRAM,
|
||||
HTTP/3 CONNECT-UDP with HTTP Datagrams, and TLS/TCP length-framed fallback.
|
||||
TLS client connections use normal certificate-chain and hostname verification.
|
||||
Shared-secret authentication precedes encrypted server backend-session
|
||||
activation.
|
||||
- Client `auto` follows configured order and bounded probes, stops on
|
||||
authentication rejection, and reconnects with jittered 250 ms–30 s backoff.
|
||||
Successful connections reset the backoff. Client control supports explicit
|
||||
reconnect.
|
||||
- The server runs enabled listeners concurrently, rejects incompatible UDP
|
||||
listener port conflicts, aggregates listener/session statistics, and gives
|
||||
sessions isolated backend UDP sockets. Admission limits cover sessions,
|
||||
per-IP sessions, pending handshakes, and authentication attempts.
|
||||
- The Unix control socket uses a private runtime directory and mode `0600`,
|
||||
refuses an active socket, and removes only a verified stale socket. `status`,
|
||||
`stats`, and `shutdown` are supported; `reconnect` is client-only. Config and
|
||||
certificate/key reload remain unsupported.
|
||||
- A client currently tracks one most-recent local UDP application peer, so
|
||||
concurrent local sources can replace the return target. Direct UDP
|
||||
keepalives are one-way; silent peer loss may require explicit reconnect or a
|
||||
local transport error to be noticed.
|
||||
Shared-secret authentication precedes encrypted backend-session activation.
|
||||
- `auto` follows configured transport order, uses bounded probes/retries, stops
|
||||
on authentication rejection, and reconnects with jittered 250 ms–30 s
|
||||
backoff. Successful connections reset the backoff.
|
||||
- Enabled server listeners run concurrently, reject incompatible UDP bind
|
||||
conflicts, isolate backend UDP sockets per authenticated session, enforce
|
||||
admission limits, and publish aggregate status/statistics.
|
||||
- The Unix control socket uses a private runtime directory and `0600` socket
|
||||
permissions. It refuses active sockets, removes only verified stale sockets,
|
||||
parses/serializes newline-delimited JSON structurally, limits concurrent
|
||||
clients, and bounds idle/oversized requests. `status`, `stats`, `shutdown`,
|
||||
and client-only `reconnect` are supported. `reload` explicitly reports
|
||||
unsupported.
|
||||
- Secret-file loading opens one descriptor, uses Linux `O_NOFOLLOW` and
|
||||
`O_NONBLOCK`, validates a regular file and permissions from that descriptor,
|
||||
and reads the opened descriptor. Secret contents are not logged.
|
||||
- Systemd templates run as an unprivileged user with hardening enabled;
|
||||
`CAP_NET_BIND_SERVICE` is documented as an optional, narrowly scoped aid for
|
||||
ports below 1024. No WireGuard, TUN/TAP, routing, or firewall management is
|
||||
implemented.
|
||||
- `tests/encrypted_runtime.rs` covers daemon-level QUIC/TLS forwarding,
|
||||
authentication rejection, cancellation, session identity, and QUIC restart
|
||||
reconnect. `tests/server_capabilities.rs` covers the server datagram
|
||||
capability boundary.
|
||||
- A deterministic Criterion target exists in `benches/protocol_transports.rs`
|
||||
for protocol/framing/HTTP Datagram/replay microbenchmarks. The repository
|
||||
also contains four isolated cargo-fuzz targets under `fuzz/` for direct
|
||||
packets, TLS frames, HTTP/3 parsing, and TOML parsing.
|
||||
|
||||
## Verification
|
||||
## Current worktree inventory
|
||||
|
||||
The latest full gates passed on commit `586ff8f`, including the config and
|
||||
client-ID changes:
|
||||
Modified files include `Cargo.toml`, `Cargo.lock`, `README.md`,
|
||||
`docs/OPERATIONS.md`, both advanced/minimal server examples, both systemd
|
||||
templates, runtime/config/control/server/transport sources, and related tests.
|
||||
Untracked assets include `benches/`, `fuzz/`, `docs/BENCHMARKS.md`,
|
||||
`docs/FUZZING.md`, `tests/encrypted_runtime.rs`, and
|
||||
`tests/server_capabilities.rs`. `docs/DEVELOPMENT_STATE.md` and
|
||||
`docs/IMPLEMENTATION_CHECKLIST.md` are also modified by this reconciliation.
|
||||
Treat these as shared worktree state; do not discard them with a cleanup
|
||||
command.
|
||||
|
||||
## Verification performed in this worktree
|
||||
|
||||
The following checks passed:
|
||||
|
||||
- `cargo fmt --all -- --check`
|
||||
- `cargo check --all-targets`
|
||||
- `cargo clippy --all-targets -- -D warnings`
|
||||
- `cargo test --all-targets --quiet` — 76 tests passed.
|
||||
- `cargo test --tests -- --test-threads=1` — 95 tests passed
|
||||
- `cargo bench --bench protocol_transports --no-run`
|
||||
- `cargo check --manifest-path fuzz/Cargo.toml`
|
||||
|
||||
The tree was clean at this checkpoint. No uncommitted file inventory applies.
|
||||
`cargo-fuzz` is not installed on this host, so no fuzzing session or sanitizer
|
||||
run is claimed. No network/loopback benchmark was run; only deterministic
|
||||
benchmark compilation was checked. These gates ran against the shared dirty
|
||||
worktree, not a clean checkout.
|
||||
|
||||
## Remaining work, prioritized
|
||||
## Remaining work
|
||||
|
||||
1. Add `tests/encrypted_runtime.rs` for daemon-level QUIC and TLS proof through
|
||||
the client runtime, encrypted transport, server runtime, and UDP echo
|
||||
backend. Cover auth rejection, session independence, control status/stats,
|
||||
and bounded shutdown. Lower-level transport tests are not a substitute.
|
||||
2. Start fuzzing: `fuzz/**` and `docs/FUZZING.md` are unstarted. Cover packet
|
||||
parsers, authentication/framing boundaries, and malformed transport input.
|
||||
3. Add benchmarks; benchmark targets and baselines are unstarted.
|
||||
4. Decide a practical maximum datagram-size cap and justify it against transport
|
||||
overhead and MTU constraints; add boundary/config tests.
|
||||
5. Decide whether config and certificate/key reload are optional or required by
|
||||
the spec/product scope. They are currently unsupported. Finish a final
|
||||
spec-to-implementation audit and update the acceptance checklist with
|
||||
evidence; do not claim unsupported behavior.
|
||||
Required before an unconditional release sign-off:
|
||||
|
||||
## First tasks for tomorrow
|
||||
1. Re-run the documented gates from the final clean checkout after concurrent
|
||||
changes are integrated and reviewed.
|
||||
2. Install/use `cargo-fuzz` and run bounded smoke sessions for each target;
|
||||
retain the compile-only result as the current evidence until then.
|
||||
3. Make and test a final practical datagram-size-cap decision. The benchmark
|
||||
analysis recommends 1200 bytes, while configuration still permits the
|
||||
larger protocol-bound ceiling.
|
||||
|
||||
1. Implement the focused daemon-level QUIC/TLS test in `tests/encrypted_runtime.rs`,
|
||||
then run `cargo test --test encrypted_runtime -- --nocapture`.
|
||||
2. Run the full gate sequence after the test lands:
|
||||
`cargo fmt --all -- --check`, `cargo check --all-targets`,
|
||||
`cargo clippy --all-targets -- -D warnings`, and
|
||||
`cargo test --all-targets --quiet`.
|
||||
3. Review the spec checklist, decide the datagram cap and reload scope, and
|
||||
record acceptance evidence plus the unstarted fuzz/benchmark work.
|
||||
Optional or explicitly out of scope for the current prototype:
|
||||
|
||||
- Config and certificate/key reload remain unsupported; the control command
|
||||
reports this explicitly. Spec language makes certificate reload desirable
|
||||
but optional and does not require full hot reload for the first milestone.
|
||||
- A network benchmark remains opt-in work because its results depend on host
|
||||
scheduling, kernel buffers, MTU, and runtime conditions. The deterministic
|
||||
microbenchmarks are present and compile.
|
||||
- A measured benchmark report and sanitizer fuzz report are release artifacts,
|
||||
not evidence currently available from this host.
|
||||
|
||||
## First three recovery/release tasks
|
||||
|
||||
1. Review and commit the shared implementation/docs/bench/fuzz work as one
|
||||
coherent checkpoint, then repeat the full gates from that clean checkout.
|
||||
2. Run the four cargo-fuzz targets for bounded smoke sessions and record the
|
||||
toolchain/host results in the fuzzing notes.
|
||||
3. Decide whether to enforce the documented 1200-byte practical cap or retain
|
||||
the protocol-bound configurable ceiling, then add the corresponding
|
||||
boundary evidence and update the acceptance checklist.
|
||||
@@ -0,0 +1,49 @@
|
||||
# Fuzzing
|
||||
|
||||
The repository includes an isolated [`cargo-fuzz`](https://github.com/rust-fuzz/cargo-fuzz)
|
||||
crate under `fuzz/`. It depends on the public `wgcloak` library by path and
|
||||
does not open sockets, read files, or start async runtimes. Each target limits
|
||||
the input passed to a parser to 64 KiB; payload/frame/datagram copies are
|
||||
limited to 16 KiB where the API supports a bound.
|
||||
|
||||
## Install and run
|
||||
|
||||
Install `cargo-fuzz` once, then run a short smoke fuzzing session from the
|
||||
repository root:
|
||||
|
||||
```bash
|
||||
cargo install cargo-fuzz
|
||||
cargo fuzz run fuzz_direct_packet -- -max_total_time=30
|
||||
cargo fuzz run fuzz_tls_frame -- -max_total_time=30
|
||||
cargo fuzz run fuzz_http3_parser -- -max_total_time=30
|
||||
cargo fuzz run fuzz_config_toml -- -max_total_time=30
|
||||
```
|
||||
|
||||
The corpus directories under `fuzz/corpus/` contain minimal and malformed
|
||||
seeds. Add minimized findings there with the target that discovered them.
|
||||
|
||||
For a compile-only check when `cargo-fuzz` is unavailable:
|
||||
|
||||
```bash
|
||||
cargo check --manifest-path fuzz/Cargo.toml
|
||||
```
|
||||
|
||||
`cargo-fuzz` uses libFuzzer and sanitizer instrumentation for fuzz builds.
|
||||
For an explicit sanitizer run, set the sanitizer supported by the local LLVM
|
||||
toolchain, for example:
|
||||
|
||||
```bash
|
||||
RUSTFLAGS="-Zsanitizer=address" cargo fuzz run fuzz_direct_packet --sanitizer address -- -max_total_time=60
|
||||
```
|
||||
|
||||
## Target invariants
|
||||
|
||||
- Direct packet parsing rejects malformed/truncated/oversized input without
|
||||
panicking and checks the DATA bound before copying its payload.
|
||||
- TLS/TCP framing handles arbitrary incremental chunks, rejects oversized
|
||||
length headers, and reports truncated final frames without panicking.
|
||||
- HTTP/3 capsule, context-ID, and authentication message parsers reject
|
||||
malformed varints, capsule lengths, contexts, and auth payloads safely.
|
||||
- TOML parsing accepts only valid UTF-8 input and performs structural parsing
|
||||
in memory; the target deliberately does not call validation that could load
|
||||
file-backed secrets.
|
||||
@@ -1,62 +1,108 @@
|
||||
# Implementation and acceptance checklist
|
||||
|
||||
This is a coordinator checklist, not a claim that v1 is signed off. The current
|
||||
runtime has code paths for all four carriers, configured auto selection,
|
||||
client reconnect backoff, and local control commands. Mark an acceptance item
|
||||
only with code evidence, tests, and an integration result; record the test
|
||||
command or issue beside each checked item.
|
||||
This is an evidence-based coordinator checklist. A checked item identifies
|
||||
current code and tests; it is not a claim that the dirty worktree is an
|
||||
unconditionally released artifact. The latest evidence was collected on
|
||||
2026-09-19 with serial integration tests.
|
||||
|
||||
## Milestones 1–6
|
||||
|
||||
- [ ] **1 — authenticated direct relay:** local UDP listener; direct UDP
|
||||
handshake; HMAC-authenticated data; replay window; keepalive/expiry; one
|
||||
backend UDP socket per authenticated client; multi-client isolation; TOML;
|
||||
logs and basic stats.
|
||||
- [ ] **2 — QUIC DATAGRAM:** certificate loading and hostname verification;
|
||||
client challenge/response; datagrams; keepalive/MTU; reconnect; multi-client
|
||||
handling without core API redesign.
|
||||
- [ ] **3 — automatic selection:** `mode = "auto"`; configured order across
|
||||
direct UDP, QUIC, HTTP/3, and TLS/TCP; bounded probes/retries; auth rejection
|
||||
stops probing; jittered reconnect; status reports selected transport.
|
||||
- [ ] **4 — HTTP/3 CONNECT-UDP:** standard CONNECT-UDP/HTTP Datagram semantics;
|
||||
authentication; backend mapping; reuse QUIC infrastructure where practical.
|
||||
- [ ] **5 — TLS/TCP fallback:** TLS listener; client authentication; bounded
|
||||
big-endian length framing; bidirectional datagram reconstruction; fallback
|
||||
integration; expected head-of-line behavior documented.
|
||||
- [ ] **6 — operational polish:** Unix control socket; status/stats/reconnect
|
||||
commands; config validation; systemd units; capability guidance; benchmarks;
|
||||
fuzzing; installation docs. Config and certificate/key reload are not
|
||||
implemented; the control command explicitly reports reload as unsupported.
|
||||
- [x] **1 — authenticated direct relay:** `src/transport/direct_udp.rs` and
|
||||
`src/protocol/*` implement the handshake, HMAC data, replay, keepalive,
|
||||
expiry, backend mapping, and statistics. Evidence: `tests/direct_udp.rs`
|
||||
covers round trip/auth rejection, concurrent clients, malformed traffic,
|
||||
source-port change, expiry, and backend failure; `tests/runtime_lifecycle.rs`
|
||||
covers daemon control/session cleanup.
|
||||
- [x] **2 — QUIC DATAGRAM:** `src/transport/quic.rs` performs certificate and
|
||||
hostname verification, challenge authentication, datagrams, limits, and
|
||||
reconnect support. Evidence: `tests/quic.rs` and the QUIC cases in
|
||||
`tests/encrypted_runtime.rs` cover round trip, bad secret, hostname mismatch,
|
||||
multiple clients, cancellation, and server restart.
|
||||
- [x] **3 — automatic selection:** `src/client/supervisor.rs` and runtime
|
||||
selection implement configured order, bounded probes/retries, auth-stop, and
|
||||
jittered reconnect. Evidence: `tests/supervisor.rs`, `tests/reconnect.rs`,
|
||||
and `tests/http3_runtime.rs`.
|
||||
- [x] **4 — HTTP/3 CONNECT-UDP:** `src/transport/http3.rs` uses extended
|
||||
CONNECT and HTTP Datagrams with authentication and backend session mapping.
|
||||
Evidence: `tests/http3.rs`, `tests/http3_integration.rs`, and the daemon
|
||||
relay/isolation cases in `tests/http3_runtime.rs`.
|
||||
- [x] **5 — TLS/TCP fallback:** `src/transport/tls_tcp.rs` implements TLS,
|
||||
authenticated bounded u16-BE framing, and bidirectional datagrams. Evidence:
|
||||
`tests/tls_tcp.rs`, `tests/integration_transports.rs`, and TLS cases in
|
||||
`tests/encrypted_runtime.rs`; the TLS/TCP head-of-line tradeoff is documented
|
||||
in `docs/PROTOCOL.md`.
|
||||
- [ ] **6 — operational polish:** Control, validation, hardened systemd units,
|
||||
capability guidance, deterministic benchmark assets, and fuzz targets are
|
||||
present (`src/control.rs`, `tests/control.rs`, `packaging/systemd/`,
|
||||
`benches/`, `fuzz/`). Leave this milestone open until final clean-checkout
|
||||
gates, bounded cargo-fuzz runs, and the practical datagram cap decision are
|
||||
recorded. Config/certificate reload remains explicitly unsupported.
|
||||
|
||||
## v1 completion criteria (spec §89)
|
||||
|
||||
- [ ] 1. Multiple clients concurrently reach one UDP backend.
|
||||
- [ ] 2. No WireGuard-specific logic exists.
|
||||
- [ ] 3. Direct UDP works reliably.
|
||||
- [ ] 4. QUIC DATAGRAM works reliably.
|
||||
- [ ] 5. HTTP/3 CONNECT-UDP works.
|
||||
- [ ] 6. TLS/TCP fallback works.
|
||||
- [ ] 7. Automatic transport selection works.
|
||||
- [ ] 8. Authentication is enforced on every public transport.
|
||||
- [ ] 9. Direct UDP has replay and integrity protection.
|
||||
- [ ] 10. Direct UDP NAT rebinding works.
|
||||
- [ ] 11. Sessions expire and clean up correctly.
|
||||
- [ ] 12. The server survives malformed and unauthenticated traffic.
|
||||
- [ ] 13. The daemon runs unprivileged except optional bind capability.
|
||||
- [ ] 14. TOML configuration is clearly validated.
|
||||
- [ ] 15. Meaningful status and statistics are available.
|
||||
- [ ] 16. Reconnects occur automatically.
|
||||
- [ ] 17. Automated integration tests cover multi-client operation.
|
||||
- [x] 1. Multiple clients concurrently reach one UDP backend —
|
||||
`tests/direct_udp.rs::concurrent_clients_use_independent_backend_sockets`,
|
||||
`tests/encrypted_runtime.rs`, and `tests/http3_runtime.rs`.
|
||||
- [x] 2. No WireGuard-specific logic exists — source/runtime scope is generic
|
||||
UDP relay code; WireGuard is documented only as a non-goal in `README.md` and
|
||||
`docs/SECURITY.md`.
|
||||
- [x] 3. Direct UDP works reliably — `tests/direct_udp.rs` round-trip,
|
||||
malformed-input, rebinding, expiry, and backend-failure coverage.
|
||||
- [x] 4. QUIC DATAGRAM works reliably — `tests/quic.rs` and encrypted runtime
|
||||
forwarding/restart coverage.
|
||||
- [x] 5. HTTP/3 CONNECT-UDP works — HTTP/3 unit, integration, and runtime tests.
|
||||
- [x] 6. TLS/TCP fallback works — TLS framing/auth tests and both TLS integration
|
||||
suites.
|
||||
- [x] 7. Automatic transport selection works — `tests/supervisor.rs` and
|
||||
`tests/reconnect.rs` cover order, fallback, retries, and recovery.
|
||||
- [x] 8. Authentication is enforced on every public transport — bad-secret
|
||||
cases in `tests/direct_udp.rs`, `tests/quic.rs`, `tests/http3_integration.rs`,
|
||||
`tests/tls_tcp.rs`, and `tests/encrypted_runtime.rs`.
|
||||
- [x] 9. Direct UDP has replay and integrity protection — protocol tests plus
|
||||
authenticated flags/replay cases in `tests/direct_udp.rs`.
|
||||
- [x] 10. Direct UDP NAT rebinding works —
|
||||
`tests/direct_udp.rs::authenticated_source_port_change_updates_return_peer`.
|
||||
- [x] 11. Sessions expire and clean up correctly — direct expiry, transport
|
||||
cancellation, HTTP/3 close, and lifecycle cases across `tests/direct_udp.rs`,
|
||||
`tests/http3_integration.rs`, `tests/http3_runtime.rs`, and
|
||||
`tests/encrypted_runtime.rs`.
|
||||
- [x] 12. The server survives malformed and unauthenticated traffic —
|
||||
`tests/direct_udp.rs` malformed/auth-rejection cases and encrypted bad-secret
|
||||
integration tests.
|
||||
- [x] 13. The daemon runs unprivileged except optional privileged-port
|
||||
capability — `User=wgcloak`, hardening, and commented narrow
|
||||
`CAP_NET_BIND_SERVICE` guidance in both `packaging/systemd/*.service` files.
|
||||
- [x] 14. TOML configuration is clearly validated — `src/config.rs` tests and
|
||||
`tests/server_capabilities.rs` cover role, transport, listener, and datagram
|
||||
boundaries.
|
||||
- [x] 15. Meaningful status and statistics are available — `src/control.rs`,
|
||||
`tests/control.rs`, `tests/runtime_lifecycle.rs`, and aggregate-stat tests in
|
||||
`tests/http3_runtime.rs`.
|
||||
- [x] 16. Reconnects occur automatically — bounded supervisor backoff and
|
||||
server-restart proof in `tests/reconnect.rs` and `tests/encrypted_runtime.rs`.
|
||||
- [x] 17. Automated integration tests cover multi-client operation — direct,
|
||||
encrypted, and HTTP/3 runtime integration suites.
|
||||
|
||||
## Required evidence before v1 sign-off
|
||||
|
||||
- [ ] Unit tests cover parsing, malformed input, auth, key derivation, replay,
|
||||
config validation, and timeout logic.
|
||||
- [ ] Integration tests cover direct client/server, concurrent clients,
|
||||
- [x] Unit tests cover parsing, malformed input, authentication, key
|
||||
derivation, replay, config validation, timeout logic, control limits, and
|
||||
secret-file safety. Evidence: library tests plus `tests/control.rs` and
|
||||
config secret tests.
|
||||
- [x] Integration tests cover direct client/server, concurrent clients,
|
||||
source-port change, auth rejection, restart/reconnect, backend outage,
|
||||
oversized datagrams, and expiry; later transports have equivalent coverage.
|
||||
- [ ] Fuzz targets exercise direct packets, TCP frames, and auth messages.
|
||||
- [ ] `cargo test`, formatting, linting, and any documented integration/bench
|
||||
commands pass from a clean checkout.
|
||||
- [ ] Review confirms no payload/secret logging, no unsafe privilege grant, and
|
||||
no accidental WireGuard/routing/firewall coupling.
|
||||
oversized datagrams, expiry, and equivalent encrypted transport coverage.
|
||||
- [x] Fuzz targets exist for direct packets, TLS frames, HTTP/3 parsing, and
|
||||
TOML parsing, and `cargo check --manifest-path fuzz/Cargo.toml` passes.
|
||||
No fuzzing execution or sanitizer result is claimed because `cargo-fuzz` is
|
||||
not installed on the current host.
|
||||
- [ ] `cargo test`, formatting, linting, and documented integration/bench
|
||||
commands pass from a clean checkout. Current dirty-worktree evidence is:
|
||||
`cargo fmt --all -- --check`, `cargo check --all-targets`, strict all-target
|
||||
Clippy, serial `cargo test --tests -- --test-threads=1` (95 passed), and
|
||||
`cargo bench --bench protocol_transports --no-run`.
|
||||
- [x] Review confirms no payload/secret logging, no unsafe privilege grant,
|
||||
and no accidental WireGuard/routing/firewall coupling. Evidence:
|
||||
`docs/SECURITY.md`, hardened systemd templates, source audit, and the
|
||||
authentication/control/secret-file tests. This review does not waive the
|
||||
clean-checkout and fuzz-execution items above.
|
||||
@@ -24,6 +24,12 @@ sudo -u wgcloak wgcloak check-config --config /etc/wgcloak/client.toml
|
||||
sudo -u wgcloak wgcloak check-config --config /etc/wgcloak/server.toml
|
||||
```
|
||||
|
||||
`network.max_datagram_size` defaults to 1200 bytes and may be raised for a
|
||||
known jumbo/custom path up to the project-wide 16,384-byte safety ceiling.
|
||||
The effective session maximum can be lower for a particular QUIC, HTTP/3, or
|
||||
direct path after transport framing and negotiation; TLS/TCP still enforces
|
||||
the configured cap at both endpoints.
|
||||
|
||||
## Start, stop, and reconnect
|
||||
|
||||
Foreground operation is useful during initial setup:
|
||||
@@ -84,6 +90,23 @@ Review and copy the units under `packaging/systemd/`. They assume binary
|
||||
`/etc/wgcloak/`. Each unit creates a private runtime directory and sets
|
||||
`XDG_RUNTIME_DIR` there.
|
||||
|
||||
The resulting control paths are distinct and deterministic:
|
||||
|
||||
- client: `/run/wgcloak-client/wgcloak.sock`
|
||||
- server: `/run/wgcloak-server/wgcloak.sock`
|
||||
|
||||
Use the explicit path when administering a unit from a shell outside its
|
||||
service environment:
|
||||
|
||||
```bash
|
||||
wgcloak status --socket /run/wgcloak-client/wgcloak.sock
|
||||
wgcloak stats --socket /run/wgcloak-client/wgcloak.sock
|
||||
wgcloak reconnect --socket /run/wgcloak-client/wgcloak.sock
|
||||
wgcloak status --socket /run/wgcloak-server/wgcloak.sock
|
||||
wgcloak stats --socket /run/wgcloak-server/wgcloak.sock
|
||||
wgcloak shutdown --socket /run/wgcloak-server/wgcloak.sock
|
||||
```
|
||||
|
||||
```bash
|
||||
sudo install -Dm0644 packaging/systemd/wgcloak-client.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
|
||||
+4
-2
@@ -44,8 +44,10 @@ timeout (target default 120 seconds), then its backend socket and replay state
|
||||
are released.
|
||||
|
||||
The core rejects oversized application datagrams, increments a counter, and
|
||||
logs at debug/warn level. v1 does not fragment datagrams; a conservative
|
||||
starting limit is 1200 bytes.
|
||||
logs at debug/warn level. v1 does not fragment datagrams. The default
|
||||
application payload limit is 1200 bytes; configuration accepts values up to
|
||||
the project-wide 16,384-byte safety ceiling. The effective session maximum may
|
||||
be lower after transport framing and path negotiation.
|
||||
|
||||
## Encapsulated transports
|
||||
|
||||
|
||||
Reference in new issue
Block a user