mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-07-16 13:17:19 +02:00
5ef0a59081
On macOS DNS-intercept mode, when mDNSResponder owns *:53 ctrld falls back to listening on 127.0.0.1:5354, and the pf rdr rules correctly redirect DNS to the bound port at startup. However, DNS resolution later breaks with an endless watchdog "anchor intact but probe FAILED -> force reload" loop and `dig @127.0.0.1` timeouts. Root cause is config reload. In CD mode, apiConfigReload refetches the generated config (which always declares port 53) every hour and the reload merge in runWait only inherits the running port when the new port is 0. The generated config explicitly says 53, so `*p.cfg = *newCfg` reverts p.cfg to port 53. The DNS listener goroutines are started only when !reload, so they are never re-bound and stay on 5354. Every subsequent pf rebuild reads p.cfg and targets the dead port 53. Fix: after applying the reloaded config in DNS-intercept mode on darwin, restore the actual bound listener IP/Port into the in-memory config via the new preserveBoundListeners helper, logging the configured-vs-actual divergence. A reload cannot move the running listener anyway, so this keeps p.cfg consistent with reality; all pf rdr rules and the watchdog probe then target the live port. The on-disk generated config is intentionally left unchanged (still 53), so no generated-config change is required.