diff --git a/netclient/functions/daemon.go b/netclient/functions/daemon.go index 89b0e62a..e347a45b 100644 --- a/netclient/functions/daemon.go +++ b/netclient/functions/daemon.go @@ -280,13 +280,16 @@ func NodeUpdate(client mqtt.Client, msg mqtt.Message) { } if newNode.DNSOn == "yes" { ncutils.Log("setting up DNS") - if err = local.UpdateDNS(cfg.Node.Interface, cfg.Network, cfg.Server.CoreDNSAddr); err != nil { - ncutils.Log("error applying dns" + err.Error()) + for _, server := range cfg.Node.NetworkSettings.DefaultServerAddrs { + if server.IsLeader { + go setDNS(cfg.Node.Interface, cfg.Network, server.Address) + break + } } } } //deal with DNS - if newNode.DNSOn != "yes" && shouldDNSChange { + if newNode.DNSOn != "yes" && shouldDNSChange && cfg.Node.Interface != "" { ncutils.Log("settng DNS off") _, err := ncutils.RunCmd("/usr/bin/resolvectl revert "+cfg.Node.Interface, true) if err != nil { @@ -295,6 +298,18 @@ func NodeUpdate(client mqtt.Client, msg mqtt.Message) { } }() } +func setDNS(iface, network, address string) { + var reachable bool + for counter := 0; !reachable && counter < 5; counter++ { + reachable = local.IsDNSReachable(address) + time.Sleep(time.Second << 1) + } + if !reachable { + ncutils.Log("not setting dns, server unreachable: " + address) + } else if err := local.UpdateDNS(iface, network, address); err != nil { + ncutils.Log("error applying dns" + err.Error()) + } +} // UpdatePeers -- mqtt message handler for peers// topic func UpdatePeers(client mqtt.Client, msg mqtt.Message) { diff --git a/netclient/local/dns.go b/netclient/local/dns.go index fe9cf1c7..4dc10359 100644 --- a/netclient/local/dns.go +++ b/netclient/local/dns.go @@ -1,8 +1,11 @@ package local import ( + "fmt" + "net" "os" "strings" + "time" //"github.com/davecgh/go-spew/spew" "log" @@ -11,6 +14,8 @@ import ( "github.com/gravitl/netmaker/netclient/ncutils" ) +const DNS_UNREACHABLE_ERROR = "nameserver unreachable" + // SetDNS - sets the DNS of a local machine func SetDNS(nameserver string) error { bytes, err := os.ReadFile("/etc/resolv.conf") @@ -35,9 +40,21 @@ func SetDNS(nameserver string) error { // UpdateDNS - updates local DNS of client func UpdateDNS(ifacename string, network string, nameserver string) error { + if ifacename == "" { + return fmt.Errorf("cannot set dns: interface name is blank") + } + if network == "" { + return fmt.Errorf("cannot set dns: network name is blank") + } + if nameserver == "" { + return fmt.Errorf("cannot set dns: nameserver is blank") + } if ncutils.IsWindows() { return nil } + if !IsDNSReachable(nameserver) { + return fmt.Errorf(DNS_UNREACHABLE_ERROR + " : " + nameserver + ":53") + } _, err := exec.LookPath("resolvectl") if err != nil { log.Println(err) @@ -60,3 +77,21 @@ func UpdateDNS(ifacename string, network string, nameserver string) error { } return err } + +func IsDNSReachable(nameserver string) bool { + port := "53" + protocols := [2]string{"tcp", "udp"} + for _, proto := range protocols { + timeout := time.Second + conn, err := net.DialTimeout(proto, net.JoinHostPort(nameserver, port), timeout) + if err != nil { + return false + } + if conn != nil { + defer conn.Close() + } else { + return false + } + } + return true +}