From 61b361bac0c606746eaf051a865a35ab855091a7 Mon Sep 17 00:00:00 2001
From: David Anderson <danderson@tailscale.com>
Date: Sat, 10 Apr 2021 19:37:11 -0700
Subject: [PATCH] net/dns: teach the openresolv manager to read DNS config.

Signed-off-by: David Anderson <danderson@tailscale.com>
---
 net/dns/direct.go     | 25 +++++++++++++++----------
 net/dns/openresolv.go | 22 +++++++++++++++++++++-
 2 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/net/dns/direct.go b/net/dns/direct.go
index c58a1907c..6da43bc4a 100644
--- a/net/dns/direct.go
+++ b/net/dns/direct.go
@@ -44,15 +44,8 @@ func writeResolvConf(w io.Writer, servers []netaddr.IP, domains []dnsname.FQDN)
 	}
 }
 
-func readResolvFile(path string) (OSConfig, error) {
-	var config OSConfig
-
-	f, err := os.Open(path)
-	if err != nil {
-		return config, err
-	}
-
-	scanner := bufio.NewScanner(f)
+func readResolv(r io.Reader) (config OSConfig, err error) {
+	scanner := bufio.NewScanner(r)
 	for scanner.Scan() {
 		line := strings.TrimSpace(scanner.Text())
 
@@ -61,7 +54,7 @@ func readResolvFile(path string) (OSConfig, error) {
 			nameserver = strings.TrimSpace(nameserver)
 			ip, err := netaddr.ParseIP(nameserver)
 			if err != nil {
-				return config, err
+				return OSConfig{}, err
 			}
 			config.Nameservers = append(config.Nameservers, ip)
 			continue
@@ -82,6 +75,18 @@ func readResolvFile(path string) (OSConfig, error) {
 	return config, nil
 }
 
+func readResolvFile(path string) (OSConfig, error) {
+	var config OSConfig
+
+	f, err := os.Open(path)
+	if err != nil {
+		return config, err
+	}
+	defer f.Close()
+
+	return readResolv(f)
+}
+
 // readResolvConf reads DNS configuration from /etc/resolv.conf.
 func readResolvConf() (OSConfig, error) {
 	return readResolvFile(resolvConf)
diff --git a/net/dns/openresolv.go b/net/dns/openresolv.go
index 1d7083ec9..855f65dd3 100644
--- a/net/dns/openresolv.go
+++ b/net/dns/openresolv.go
@@ -8,6 +8,7 @@ import (
 	"bytes"
 	"fmt"
 	"os/exec"
+	"strings"
 )
 
 // resolvconfIsOpenresolv reports whether the `resolvconf` binary on
@@ -48,7 +49,26 @@ func (m openresolvManager) SupportsSplitDNS() bool {
 }
 
 func (m openresolvManager) GetBaseConfig() (OSConfig, error) {
-	return OSConfig{}, ErrGetBaseConfigNotSupported
+	bs, err := exec.Command("resolvconf", "-i").CombinedOutput()
+	if err != nil {
+		return OSConfig{}, err
+	}
+
+	args := []string{"-l"}
+	for _, f := range strings.Split(strings.TrimSpace(string(bs)), " ") {
+		if f == "tailscale" {
+			continue
+		}
+		args = append(args, f)
+	}
+
+	var buf bytes.Buffer
+	cmd := exec.Command("resolvconf", args...)
+	cmd.Stdout = &buf
+	if err := cmd.Run(); err != nil {
+		return OSConfig{}, err
+	}
+	return readResolv(&buf)
 }
 
 func (m openresolvManager) Close() error {