feat: Windows DNS configuration via netsh #28

Merged
razvandimescu merged 16 commits from feat/windows-dns-config into main 2026-04-01 23:17:52 +08:00

16 Commits

Author SHA1 Message Date
Razvan Dimescu
8ae86a3e13 chore: remove docs from git tracking (already gitignored)
docs/ is in .gitignore but files were force-added. Remove from
tracking — files remain on disk.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 18:15:40 +03:00
Razvan Dimescu
787733cbea docs: update README, Windows plan, and launch drafts for Windows support
- README: platform-specific Quick Start, install/uninstall table
- Windows plan: Phase 2 complete, Phase 3 scoped
- Launch drafts: updated "Does it support Windows?" response

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 17:57:21 +03:00
Razvan Dimescu
045018ad88 feat: auto-start numa on Windows boot via registry Run key
Without a Windows Service, rebooting after numa install leaves DNS
broken (pointing at 127.0.0.1 with nothing listening). Register
numa in HKLM\...\Run so it starts automatically. Removed on
uninstall.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 17:51:48 +03:00
Razvan Dimescu
e28747a339 fix: ignore ConnectionReset on UDP socket (Windows ICMP error)
Windows delivers ICMP port-unreachable as ConnectionReset on the
next UDP recv_from, crashing numa. Linux/macOS silently ignore these.
Catch and continue the recv loop.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 17:21:39 +03:00
Razvan Dimescu
4f279b5f29 refactor: remove dead test helpers, fix constant placement
Remove unused get_srtt_ms() and saturated_penalty_cache() left over
from SRTT test rewrite. Move QUAD9_IP/DOH_FALLBACK after use block.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:36:15 +03:00
Razvan Dimescu
82c4491690 refactor: extract QUAD9_IP constant
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:22:58 +03:00
Razvan Dimescu
f4342b9844 refactor: extract DOH_FALLBACK constant
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:19:09 +03:00
Razvan Dimescu
a464d60f12 fix: use Quad9 IP (9.9.9.9) for DoH fallback, not hostname
DoH to dns.quad9.net requires DNS to resolve the hostname, which
creates a chicken-and-egg loop when numa IS the system resolver
(e.g. after numa install on Windows). Using the IP directly avoids
the bootstrap dependency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:14:38 +03:00
Razvan Dimescu
232e6fa412 fix: rewrite SRTT decay tests as pure functions
Decay tests manipulated Instant timestamps which panics on Windows
(Instant can't go before boot time). Rewrite to test decay_for_age()
directly — a pure function taking srtt_ms and age_secs, no platform
dependency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:01:16 +03:00
Razvan Dimescu
4f9946dcd6 feat: disable Dnscache on Windows install, re-enable on uninstall
Windows DNS Client (Dnscache) holds port 53 at kernel level and
can't be stopped via sc/net stop. Disable via registry during
install (requires reboot), re-enable on uninstall.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:50:57 +03:00
Razvan Dimescu
19b59d8c4c fix: use ProgramData for Windows DNS backup path
APPDATA differs between user and admin contexts — install runs as
admin but uninstall might resolve a different APPDATA. Use
ProgramData which is consistent across elevation contexts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 12:39:38 +03:00
Razvan Dimescu
e59e25e1a1 fix: SRTT decay tests use binary search for max Instant age
Replace age() helper with set_age_secs() on SrttCache that
binary-searches for the maximum subtractable duration. Prevents
panic on Windows (Instant starts at boot) while still producing
the oldest representable instant for correct decay calculations.

Also removes ephemeral test-ubuntu.sh from git.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 12:12:57 +03:00
Razvan Dimescu
ccf9b13e04 fix: SRTT decay tests panic on Windows due to Instant underflow
On Windows, Instant starts near boot time — subtracting large
durations panics. Use checked_sub with a process-start fallback.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 12:07:19 +03:00
Razvan Dimescu
7ed5415be6 ci: upload Windows binary as artifact for testing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:58:06 +03:00
Razvan Dimescu
51c0d066d2 ci: add cargo test to Windows CI job
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:39:30 +03:00
Razvan Dimescu
280e45c6be feat: Windows DNS configuration via netsh
numa install/uninstall now set/restore system DNS on Windows via
netsh. Parses ipconfig /all per-interface (adapter name, DHCP status,
DNS servers), saves backup to %APPDATA%\numa\original-dns.json, and
restores on uninstall (DHCP or static with secondary servers).

Handles localization (German adapter/DHCP/DNS labels), disconnected
adapters, multiple interfaces, and missing admin privileges. Adds IP
validation to discover_windows() for consistency.

No Windows Service or CA trust yet — user runs numa in a terminal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 11:32:42 +03:00