From 1f9b73a5310943ba8cc6c3f7a071730a45435422 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 14 Apr 2021 15:34:59 -0700 Subject: [PATCH] net/dns: fix freebsd DNS manager selection. Signed-off-by: David Anderson --- net/dns/direct.go | 30 ++++++++++++++++++++++++++++++ net/dns/manager_freebsd.go | 23 ++++++++++++++++------- net/dns/manager_linux.go | 31 ------------------------------- 3 files changed, 46 insertions(+), 38 deletions(-) diff --git a/net/dns/direct.go b/net/dns/direct.go index 23a5153b0..dfb6cf026 100644 --- a/net/dns/direct.go +++ b/net/dns/direct.go @@ -92,6 +92,36 @@ func readResolvConf() (OSConfig, error) { return readResolvFile(resolvConf) } +// resolvOwner returns the apparent owner of the resolv.conf +// configuration in bs - one of "resolvconf", "systemd-resolved" or +// "NetworkManager", or "" if no known owner was found. +func resolvOwner(bs []byte) string { + b := bytes.NewBuffer(bs) + for { + line, err := b.ReadString('\n') + if err != nil { + return "" + } + line = strings.TrimSpace(line) + if line == "" { + continue + } + if line[0] != '#' { + // First non-empty, non-comment line. Assume the owner + // isn't hiding further down. + return "" + } + + if strings.Contains(line, "systemd-resolved") { + return "systemd-resolved" + } else if strings.Contains(line, "NetworkManager") { + return "NetworkManager" + } else if strings.Contains(line, "resolvconf") { + return "resolvconf" + } + } +} + // isResolvedRunning reports whether systemd-resolved is running on the system, // even if it is not managing the system DNS settings. func isResolvedRunning() bool { diff --git a/net/dns/manager_freebsd.go b/net/dns/manager_freebsd.go index ce6891f37..64eb5d4b8 100644 --- a/net/dns/manager_freebsd.go +++ b/net/dns/manager_freebsd.go @@ -4,16 +4,25 @@ package dns -import "tailscale.com/types/logger" +import ( + "fmt" + "io/ioutil" + "os" -func isResolvconfActive() bool { - // TODO(danderson): implement somewhere. - return false -} + "tailscale.com/types/logger" +) func NewOSConfigurator(logf logger.Logf, _ string) (OSConfigurator, error) { - switch { - case isResolvconfActive(): + bs, err := ioutil.ReadFile("/etc/resolv.conf") + if os.IsNotExist(err) { + return newDirectManager() + } + if err != nil { + return nil, fmt.Errorf("reading /etc/resolv.conf: %w", err) + } + + switch resolvOwner(bs) { + case "resolvconf": return newResolvconfManager(logf) default: return newDirectManager() diff --git a/net/dns/manager_linux.go b/net/dns/manager_linux.go index 93d5b81e2..c7884e5f5 100644 --- a/net/dns/manager_linux.go +++ b/net/dns/manager_linux.go @@ -12,7 +12,6 @@ "io/ioutil" "os" "os/exec" - "strings" "time" "github.com/godbus/dbus/v5" @@ -132,33 +131,3 @@ func dbusPing(name, objectPath string) error { call := obj.CallWithContext(ctx, "org.freedesktop.DBus.Peer.Ping", 0) return call.Err } - -// resolvOwner returns the apparent owner of the resolv.conf -// configuration in bs - one of "resolvconf", "systemd-resolved" or -// "NetworkManager", or "" if no known owner was found. -func resolvOwner(bs []byte) string { - b := bytes.NewBuffer(bs) - for { - line, err := b.ReadString('\n') - if err != nil { - return "" - } - line = strings.TrimSpace(line) - if line == "" { - continue - } - if line[0] != '#' { - // First non-empty, non-comment line. Assume the owner - // isn't hiding further down. - return "" - } - - if strings.Contains(line, "systemd-resolved") { - return "systemd-resolved" - } else if strings.Contains(line, "NetworkManager") { - return "NetworkManager" - } else if strings.Contains(line, "resolvconf") { - return "resolvconf" - } - } -}