diff --git a/cmd/cli/prog.go b/cmd/cli/prog.go index 54ade0d..c112ada 100644 --- a/cmd/cli/prog.go +++ b/cmd/cli/prog.go @@ -651,6 +651,8 @@ func (p *prog) dnsWatchdog(iface *net.Interface, nameservers []string, allIfaces if dnsChanged(i, ns) { if err := setDnsIgnoreUnusableInterface(i, nameservers); err != nil { mainLog.Load().Error().Err(err).Str("iface", i.Name).Msgf("could not re-apply DNS settings") + } else { + mainLog.Load().Debug().Msgf("re-applying DNS for interface %q successfully", i.Name) } } return nil diff --git a/cmd/cli/resolvconf_darwin.go b/cmd/cli/resolvconf_darwin.go index 7e26f41..eb70eed 100644 --- a/cmd/cli/resolvconf_darwin.go +++ b/cmd/cli/resolvconf_darwin.go @@ -3,15 +3,44 @@ package cli import ( "net" "net/netip" + "os" + "slices" + + "github.com/Control-D-Inc/ctrld/internal/dns/resolvconffile" ) +const resolvConfPath = "/etc/resolv.conf" + // setResolvConf sets the content of resolv.conf file using the given nameservers list. func setResolvConf(iface *net.Interface, ns []netip.Addr) error { servers := make([]string, len(ns)) for i := range ns { servers[i] = ns[i].String() } - return setDNS(iface, servers) + if err := setDNS(iface, servers); err != nil { + return err + } + slices.Sort(servers) + curNs := currentDNS(iface) + slices.Sort(curNs) + if !slices.Equal(curNs, servers) { + c, err := resolvconffile.ParseFile(resolvConfPath) + if err != nil { + return err + } + c.Nameservers = ns + f, err := os.Create(resolvConfPath) + if err != nil { + return err + } + defer f.Close() + + if err := c.Write(f); err != nil { + return err + } + return f.Close() + } + return nil } // shouldWatchResolvconf reports whether ctrld should watch changes to resolv.conf file with given OS configurator.