Skip to content

fix: parallel DNS resolution and robust domain addition#9

Merged
GeiserX merged 1 commit intomainfrom
fix/parallel-dns-resolution
Feb 25, 2026
Merged

fix: parallel DNS resolution and robust domain addition#9
GeiserX merged 1 commit intomainfrom
fix/parallel-dns-resolution

Conversation

@GeiserX
Copy link
Owner

@GeiserX GeiserX commented Feb 25, 2026

Summary

  • Parallel DNS with trust hierarchy: dig and DoH now race simultaneously, but dig-based resolvers get a 200ms head start. When VPN blocks UDP DNS, DoH wins in ~2s instead of waiting 8+ seconds for sequential dig timeouts. When DNS works normally, trusted local resolvers win before DoH even fires.
  • Fix addDomain hosts/cache gap: applyRoutesForDomain now populates dnsCache and dnsDiskCache immediately, and addDomain updates /etc/hosts on success — previously hosts entries were only created during periodic refresh.
  • Tracked auto-retry on failure: When DNS fails on domain addition, a 15-second retry is scheduled with proper cancellation support. Retries read the current gateway (not stale captured value), check for duplicate routes, and set isApplyingRoutes correctly.
  • Hardening: failedDomains changed to Set (prevents unbounded growth), setAllDomainsEnabled does a single disk write instead of N, toggleDomain now updates hosts file, redundant MainActor.run wrappers removed, retry tasks cancelled on VPN disconnect/domain removal.

Test plan

  • Build succeeds (release mode)
  • App launches, detects VPN, applies routes from cache
  • Background DNS refresh completes and updates routes
  • /etc/hosts file populated with domain→IP mappings
  • Routing table has entries through real gateway (192.168.10.1)
  • DNS cache file populated on disk
  • Add a custom domain while connected to VPN — should resolve and route within ~2 seconds
  • Verify log shows warning + retry when DNS resolution fails
  • Remove domain during retry window — retry should be cancelled
  • Toggle domain on/off — routes added/removed, hosts file updated
  • Enable All domains — should not thrash disk (single save)
  • VPN disconnect clears routes and cancels pending retries

DNS resolution was sequential: dig timeouts (~8s) blocked DoH from
running when VPN blocks UDP. Now dig and DoH race in parallel with a
trust hierarchy — dig-based resolvers fire immediately, DoH fires
after a 200ms grace period. First success wins. Resolves in ~2s on
VPN instead of 8+.

Also fixes addDomain: DNS cache, disk cache, and /etc/hosts are now
updated immediately on success (was only done during periodic refresh).
DNS failures trigger a tracked 15s auto-retry with fresh gateway lookup,
deduplication guards, and proper cancellation on domain removal or VPN
disconnect.

Additional hardening:
- failedDomains changed to Set (prevents unbounded growth)
- setAllDomainsEnabled uses single disk write instead of N
- toggleDomain now updates hosts file on enable
- Redundant MainActor.run wrappers removed (already on MainActor)
- isApplyingRoutes properly managed during retries
@GeiserX GeiserX force-pushed the fix/parallel-dns-resolution branch from 917df3d to ecb7ac3 Compare February 25, 2026 15:34
@GeiserX GeiserX merged commit 1e2ecde into main Feb 25, 2026
2 checks passed
@GeiserX GeiserX deleted the fix/parallel-dns-resolution branch February 25, 2026 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant