net/dns/resolver: handle tabs as whitespace when ExitDNS parses resolv.conf

On Synology, the /etc/resolv.conf has tabs in it, which this
resolv.conf parser (we have two, sigh) didn't handle.

Updates #3710

Change-Id: I86f8e09ad1867ee32fa211e85c382a27191418ea
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2022-01-12 12:30:25 -08:00 committed by Brad Fitzpatrick
parent 51bc9a6d9d
commit 24a04d07d1

View File

@ -529,6 +529,10 @@ func stubResolverForOS() (ip netaddr.IP, err error) {
if c, ok := resolvConfCacheValue.Load().(resolvConfCache); ok && c.mod == cur.mod && c.size == cur.size { if c, ok := resolvConfCacheValue.Load().(resolvConfCache); ok && c.mod == cur.mod && c.size == cur.size {
return c.ip, nil return c.ip, nil
} }
// TODO(bradfitz): unify this /etc/resolv.conf parsing code with readResolv
// in net/dns, which we can't use due to circular dependency reasons.
// Move it to a leaf, including the OSConfig type (perhaps in its own dnstype
// package?)
err = lineread.File("/etc/resolv.conf", func(line []byte) error { err = lineread.File("/etc/resolv.conf", func(line []byte) error {
if !ip.IsZero() { if !ip.IsZero() {
return nil return nil
@ -537,6 +541,12 @@ func stubResolverForOS() (ip netaddr.IP, err error) {
if len(line) == 0 || line[0] == '#' { if len(line) == 0 || line[0] == '#' {
return nil return nil
} }
// Normalize tabs to spaces to simplify parsing code later.
for i, b := range line {
if b == '\t' {
line[i] = ' '
}
}
if mem.HasPrefix(mem.B(line), mem.S("nameserver ")) { if mem.HasPrefix(mem.B(line), mem.S("nameserver ")) {
s := strings.TrimSpace(strings.TrimPrefix(string(line), "nameserver ")) s := strings.TrimSpace(strings.TrimPrefix(string(line), "nameserver "))
ip, err = netaddr.ParseIP(s) ip, err = netaddr.ParseIP(s)