Companion to v3.5 — the new force_vpn_cidrs field broke the two integration
tests that used positional SplitRoutes literals instead of struct-update
syntax. Switched both to .. Default::default() so the test sites are
forward-compatible with any further SplitRoutes additions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Windows is now first-class for client use:
- aura-cli::os_routes Windows path is no longer a stub. Real install via
`route ADD <net> MASK <mask> <gw> METRIC 1` for DIRECT bypass (rollback:
`route DELETE ...`) and `netsh interface ipv4 add route <cidr> "Aura"
<tun_local_ip> store=active` for VPN default/CIDR (rollback: `netsh ...
delete route ...`). Default-gateway detection by parsing `route print 0`
output via parse_windows_route_print_default; rejects `On-link` rows. Dry
run works on every host.
- aura-tunnel::tun wintun audit fixed a real bug: AuraTun was holding only
Arc<Session> while Session does NOT keep Arc<Adapter> alive (only the
Wintun DLL handle). On Drop the adapter was being closed under the
session. Fixed by adding _adapter: Arc<wintun::Adapter> to AuraTun, with
field order ensuring Session is dropped before Adapter so end-session
precedes close-adapter. Also wired mtu into write_packet (hard limit) +
read_packet (warn).
- Cross-compile verified: cargo check --target x86_64-pc-windows-gnu
--workspace and clippy on the windows target are both clean (added
mingw-w64 + x86_64-pc-windows-gnu via rustup).
- docs/deployment.md: §6 updated (Windows OS-routes now Done), new §8
«Windows как клиент» with download wintun.dll, Admin run, [tunnel.os_routes]
enabled, known no-ops (run_as, [server.nat]).
9 new tests (7 parser/plan/undo unit + 1 windows dry-run integration + 1
existing). Workspace: 293 tests passed (+9), clippy -D warnings clean, fmt
clean. macOS host + windows-gnu cross-target both green.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
DIRECT-destination traffic now bypasses the TUN entirely via OS routing
table edits, instead of going through user-space and hitting the v1
send_direct stub. The user-space router only sees VPN-bound packets,
making the split-tunnel real.
- aura_cli::os_routes::OsRouteGuard: RAII install + rollback of OS routes.
Linux: `ip route show default` parser -> DIRECT CIDRs via original gw,
VPN default via TUN with metric 50. macOS: `route -n get default`
parser -> `route add -net/-host ... <gw>` for DIRECT, `route add -net
... -interface <tun>` for VPN. Windows: stub + warning (v3).
- dry_run works on every platform (logs `would run: ...`); useful for
tests and operator confidence-checks.
- SplitRoutes::from_config folds [[tunnel.split.direct]]/[[...vpn]] +
resolved domains (via AuraDns) into one declarative plan.
- New [tunnel.os_routes] {enabled (default true), dry_run, gateway,
egress_iface}; absent section = old user-space behavior (back-compat).
- client::run installs routes after AuraTun::create, before privdrop;
guard's Drop reverts everything on shutdown.
- aura-tunnel::router unchanged; AuraRouter::send_direct kept as a
defensive fallback (in v2 it should never fire — OS routes prevent
DIRECT packets from reaching the TUN at all).
20 new tests (linux/macos parser unit tests, install dry-run, config
back-compat). Workspace: 174 tests passed (+19), clippy -D warnings
clean, fmt clean.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>