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
razvandimescu commented 2026-04-01 16:33:17 +08:00 (Migrated from github.com)

Summary

  • numa install on Windows — sets system DNS to 127.0.0.1 via netsh for all active interfaces, disables Dnscache via registry (holds port 53 at kernel level), registers auto-start on boot via registry Run key
  • numa uninstall on Windows — restores original DNS from backup (DHCP or static with secondary servers), re-enables Dnscache, removes auto-start
  • ipconfig /all parser — extracts per-interface adapter name, DHCP status, DNS servers. Handles localized output (German), skips disconnected adapters
  • Backup%PROGRAMDATA%\numa\original-dns.json (consistent across admin contexts)
  • Dnscache handling — disable on install, re-enable on uninstall, reboot required both ways
  • Auto-start — registry Run key (HKLM\...\Run\Numa) so numa starts on boot after Dnscache is disabled
  • DoH fallback fix — use Quad9 IP (9.9.9.9) instead of hostname to avoid DNS bootstrap loop
  • UDP ConnectionReset fix — Windows ICMP port-unreachable crashes numa via error 10054. Now caught and ignored.
  • SRTT decay tests — rewritten as pure function tests, fixes panic on Windows
  • Constants — extracted QUAD9_IP, DOH_FALLBACK, DEFAULT_API_PORT
  • CI — added cargo test + binary artifact upload to Windows job

Test plan

  • make all passes (fmt, clippy, audit, build, 120 tests)
  • CI green — Linux + Windows (clippy, build, test)
  • parse_ipconfig_interfaces unit test: DHCP + static, multi-server
  • parse_ipconfig_interfaces unit test: skips disconnected adapters
  • Windows: numa install sets DNS to 127.0.0.1 on all interfaces
  • Windows: Dnscache disabled via registry
  • Windows: numa starts, binds port 53, resolves DNS
  • Windows: no ConnectionReset crash
  • Windows: numa uninstall restores original DNS (static with secondary: 213.154.124.1, 193.231.252.1)
  • Windows: Dnscache re-enabled after uninstall

🤖 Generated with Claude Code

## Summary - **`numa install` on Windows** — sets system DNS to 127.0.0.1 via `netsh` for all active interfaces, disables Dnscache via registry (holds port 53 at kernel level), registers auto-start on boot via registry Run key - **`numa uninstall` on Windows** — restores original DNS from backup (DHCP or static with secondary servers), re-enables Dnscache, removes auto-start - **`ipconfig /all` parser** — extracts per-interface adapter name, DHCP status, DNS servers. Handles localized output (German), skips disconnected adapters - **Backup** — `%PROGRAMDATA%\numa\original-dns.json` (consistent across admin contexts) - **Dnscache handling** — disable on install, re-enable on uninstall, reboot required both ways - **Auto-start** — registry Run key (`HKLM\...\Run\Numa`) so numa starts on boot after Dnscache is disabled - **DoH fallback fix** — use Quad9 IP (`9.9.9.9`) instead of hostname to avoid DNS bootstrap loop - **UDP ConnectionReset fix** — Windows ICMP port-unreachable crashes numa via error 10054. Now caught and ignored. - **SRTT decay tests** — rewritten as pure function tests, fixes panic on Windows - **Constants** — extracted `QUAD9_IP`, `DOH_FALLBACK`, `DEFAULT_API_PORT` - **CI** — added `cargo test` + binary artifact upload to Windows job ## Test plan - [x] `make all` passes (fmt, clippy, audit, build, 120 tests) - [x] CI green — Linux + Windows (clippy, build, test) - [x] `parse_ipconfig_interfaces` unit test: DHCP + static, multi-server - [x] `parse_ipconfig_interfaces` unit test: skips disconnected adapters - [x] Windows: `numa install` sets DNS to 127.0.0.1 on all interfaces - [x] Windows: Dnscache disabled via registry - [x] Windows: numa starts, binds port 53, resolves DNS - [x] Windows: no ConnectionReset crash - [x] Windows: `numa uninstall` restores original DNS (static with secondary: `213.154.124.1, 193.231.252.1`) - [x] Windows: Dnscache re-enabled after uninstall 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.