* feat: SRTT-based nameserver selection for recursive resolver
BIND-style Smoothed RTT (EWMA) tracking per NS IP address. The resolver
learns which nameservers respond fastest and prefers them, eliminating
cascading timeouts from slow/unreachable IPv6 servers.
- New src/srtt.rs: SrttCache with record_rtt, record_failure, sort_by_rtt
- EWMA formula: new = (old * 7 + sample) / 8, 5s failure penalty, 5min decay
- TCP penalty (+100ms) lets SRTT naturally deprioritize IPv6-over-TCP
- Enabled flag embedded in SrttCache (no-op when disabled)
- Batch eviction (64 entries) for O(1) amortized writes at capacity
- Configurable via [upstream] srtt = true/false (default: true)
- Benchmark script: scripts/benchmark.sh (full, cold, warm, compare-all)
- Benchmarks show 12x avg improvement, 0% queries >1s (was 58%)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: show DNSSEC and SRTT status in dashboard + API
Add dnssec and srtt boolean fields to /stats API response.
Display on/off indicators in the dashboard footer.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: apply SRTT decay before EWMA so recovered servers rehabilitate
Without decay-before-EWMA, a server penalized at 5000ms stayed near
that value even after recovery — the stale raw penalty was used as the
EWMA base instead of the decayed estimate. Extract decayed_srtt()
helper and call it in record_rtt() before the smoothing step.
Also restores removed "why" comments in send_query / resolve_recursive.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs: add install/upgrade instructions, smarter benchmark priming
README: document `numa install`, `numa service`, Homebrew upgrade,
and `make deploy` workflows. Benchmark: replace fixed `sleep 4` with
`wait_for_priming` that polls cache entry count for stability.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Cross-platform paths: config_dir() uses %APPDATA%, data_dir() uses
%PROGRAMDATA% on Windows. TLS cert directory uses data_dir() instead
of hardcoded /usr/local/var/numa. Windows DNS discovery via ipconfig.
Fixed cfg gates from not(macos) to explicit linux to prevent Linux
code compiling on Windows. Added Windows target to CI and release
workflows with zip packaging.
System integration (numa install/service) not yet supported on Windows
— users run numa.exe manually.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Numa instances on the same network auto-discover each other's .numa
services. No config, no cloud — just multicast on 239.255.70.78:5390.
- PeerStore with lazy expiry (90s timeout, 30s broadcast interval)
- DNS resolves remote .numa services to peer's LAN IP (not localhost)
- Proxy forwards to peer IP for remote services
- Graceful degradation if multicast bind fails
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
HTTP reverse proxy on port 80 lets developers use clean domain names
(frontend.numa, api.numa) instead of localhost:PORT. Includes WebSocket
upgrade support for HMR, TCP health checks, dashboard UI panel, and
REST API for service management. numa.numa is preconfigured for the
dashboard itself.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- DNS-level ad blocking: 385K+ domains via Hagezi Pro blocklist, subdomain
matching, one-click allowlist, pause/toggle, background refresh every 24h
- Live dashboard at :5380 with real-time stats, query log, override
management (create/edit/delete), blocking controls
- System DNS auto-discovery: parses scutil --dns on macOS to find
conditional forwarding rules (Tailscale, VPN split-DNS)
- REST API expanded to 18 endpoints (blocking, overrides, diagnostics)
- Startup banner with colored system info
- Performance benchmarks (bench/dns-bench.sh)
- Landing page updated with new positioning and comparison table
- CI, Dockerfile, LICENSE, development plan docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>