Commit 9dee7771 authored by Vishvananda Ishaya's avatar Vishvananda Ishaya Committed by Matthew Dempsky

net: allow netgo to use lookup from nsswitch.conf

Change https://golang.org/cl/8945 allowed Go to use its own DNS resolver
instead of libc in a number of cases. The code parses nsswitch.conf and
attempts to resolve things in the same order. Unfortunately, builds with
netgo completely ignore this parsing and always search via
hostLookupFilesDNS.

This commit modifies the logic to allow binaries built with netgo to
parse nsswitch.conf and attempt to resolve using the order specified
there. If the parsing results in hostLookupCGo, it falls back to the
original hostLookupFilesDNS. Tests are also added to ensure that both
the parsing and the fallback work properly.

Fixes #14354

Change-Id: Ib079ad03d7036a4ec57f18352a15ba55d933f261
Reviewed-on: https://go-review.googlesource.com/19523
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
parent 84e80804
...@@ -124,16 +124,17 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { ...@@ -124,16 +124,17 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) {
print("go package net: hostLookupOrder(", hostname, ") = ", ret.String(), "\n") print("go package net: hostLookupOrder(", hostname, ") = ", ret.String(), "\n")
}() }()
} }
fallbackOrder := hostLookupCgo
if c.netGo { if c.netGo {
return hostLookupFilesDNS fallbackOrder = hostLookupFilesDNS
} }
if c.forceCgoLookupHost || c.resolv.unknownOpt || c.goos == "android" { if c.forceCgoLookupHost || c.resolv.unknownOpt || c.goos == "android" {
return hostLookupCgo return fallbackOrder
} }
if byteIndex(hostname, '\\') != -1 || byteIndex(hostname, '%') != -1 { if byteIndex(hostname, '\\') != -1 || byteIndex(hostname, '%') != -1 {
// Don't deal with special form hostnames with backslashes // Don't deal with special form hostnames with backslashes
// or '%'. // or '%'.
return hostLookupCgo return fallbackOrder
} }
// OpenBSD is unique and doesn't use nsswitch.conf. // OpenBSD is unique and doesn't use nsswitch.conf.
...@@ -154,7 +155,7 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { ...@@ -154,7 +155,7 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) {
return hostLookupDNSFiles return hostLookupDNSFiles
} }
if len(lookup) < 1 || len(lookup) > 2 { if len(lookup) < 1 || len(lookup) > 2 {
return hostLookupCgo return fallbackOrder
} }
switch lookup[0] { switch lookup[0] {
case "bind": case "bind":
...@@ -162,7 +163,7 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { ...@@ -162,7 +163,7 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) {
if lookup[1] == "file" { if lookup[1] == "file" {
return hostLookupDNSFiles return hostLookupDNSFiles
} }
return hostLookupCgo return fallbackOrder
} }
return hostLookupDNS return hostLookupDNS
case "file": case "file":
...@@ -170,11 +171,11 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { ...@@ -170,11 +171,11 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) {
if lookup[1] == "bind" { if lookup[1] == "bind" {
return hostLookupFilesDNS return hostLookupFilesDNS
} }
return hostLookupCgo return fallbackOrder
} }
return hostLookupFiles return hostLookupFiles
default: default:
return hostLookupCgo return fallbackOrder
} }
} }
...@@ -189,7 +190,7 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { ...@@ -189,7 +190,7 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) {
// because Go's native resolver doesn't do mDNS or // because Go's native resolver doesn't do mDNS or
// similar local resolution mechanisms, assume that // similar local resolution mechanisms, assume that
// libc might (via Avahi, etc) and use cgo. // libc might (via Avahi, etc) and use cgo.
return hostLookupCgo return fallbackOrder
} }
nss := c.nss nss := c.nss
...@@ -199,7 +200,7 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { ...@@ -199,7 +200,7 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) {
if os.IsNotExist(nss.err) || (nss.err == nil && len(srcs) == 0) { if os.IsNotExist(nss.err) || (nss.err == nil && len(srcs) == 0) {
if c.goos == "solaris" { if c.goos == "solaris" {
// illumos defaults to "nis [NOTFOUND=return] files" // illumos defaults to "nis [NOTFOUND=return] files"
return hostLookupCgo return fallbackOrder
} }
if c.goos == "linux" { if c.goos == "linux" {
// glibc says the default is "dns [!UNAVAIL=return] files" // glibc says the default is "dns [!UNAVAIL=return] files"
...@@ -212,7 +213,7 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { ...@@ -212,7 +213,7 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) {
// We failed to parse or open nsswitch.conf, so // We failed to parse or open nsswitch.conf, so
// conservatively assume we should use cgo if it's // conservatively assume we should use cgo if it's
// available. // available.
return hostLookupCgo return fallbackOrder
} }
var mdnsSource, filesSource, dnsSource bool var mdnsSource, filesSource, dnsSource bool
...@@ -222,11 +223,11 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { ...@@ -222,11 +223,11 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) {
if hasDot { if hasDot {
continue continue
} }
return hostLookupCgo return fallbackOrder
} }
if src.source == "files" || src.source == "dns" { if src.source == "files" || src.source == "dns" {
if !src.standardCriteria() { if !src.standardCriteria() {
return hostLookupCgo // non-standard; let libc deal with it. return fallbackOrder // non-standard; let libc deal with it.
} }
if src.source == "files" { if src.source == "files" {
filesSource = true filesSource = true
...@@ -246,14 +247,14 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { ...@@ -246,14 +247,14 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) {
continue continue
} }
// Some source we don't know how to deal with. // Some source we don't know how to deal with.
return hostLookupCgo return fallbackOrder
} }
// We don't parse mdns.allow files. They're rare. If one // We don't parse mdns.allow files. They're rare. If one
// exists, it might list other TLDs (besides .local) or even // exists, it might list other TLDs (besides .local) or even
// '*', so just let libc deal with it. // '*', so just let libc deal with it.
if mdnsSource && c.hasMDNSAllow { if mdnsSource && c.hasMDNSAllow {
return hostLookupCgo return fallbackOrder
} }
// Cases where Go can handle it without cgo and C thread // Cases where Go can handle it without cgo and C thread
...@@ -272,7 +273,7 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { ...@@ -272,7 +273,7 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) {
} }
// Something weird. Let libc deal with it. // Something weird. Let libc deal with it.
return hostLookupCgo return fallbackOrder
} }
// goDebugNetDNS parses the value of the GODEBUG "netdns" value. // goDebugNetDNS parses the value of the GODEBUG "netdns" value.
......
...@@ -46,6 +46,28 @@ func TestConfHostLookupOrder(t *testing.T) { ...@@ -46,6 +46,28 @@ func TestConfHostLookupOrder(t *testing.T) {
{"google.com", hostLookupCgo}, {"google.com", hostLookupCgo},
}, },
}, },
{
name: "netgo_dns_before_files",
c: &conf{
netGo: true,
nss: nssStr("hosts: dns files"),
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{
{"x.com", hostLookupDNSFiles},
},
},
{
name: "netgo_fallback_on_cgo",
c: &conf{
netGo: true,
nss: nssStr("hosts: dns files something_custom"),
resolv: defaultResolvConf,
},
hostTests: []nssHostTest{
{"x.com", hostLookupFilesDNS},
},
},
{ {
name: "ubuntu_trusty_avahi", name: "ubuntu_trusty_avahi",
c: &conf{ c: &conf{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment