From 9dee7771f561cf6aee081c0af6658cc81fac3918 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 16 Feb 2016 17:58:11 -0800 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Matthew Dempsky --- src/net/conf.go | 31 ++++++++++++++++--------------- src/net/conf_test.go | 22 ++++++++++++++++++++++ 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/net/conf.go b/src/net/conf.go index 36566a49e2..48372e5197 100644 --- a/src/net/conf.go +++ b/src/net/conf.go @@ -124,16 +124,17 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { print("go package net: hostLookupOrder(", hostname, ") = ", ret.String(), "\n") }() } + fallbackOrder := hostLookupCgo if c.netGo { - return hostLookupFilesDNS + fallbackOrder = hostLookupFilesDNS } if c.forceCgoLookupHost || c.resolv.unknownOpt || c.goos == "android" { - return hostLookupCgo + return fallbackOrder } if byteIndex(hostname, '\\') != -1 || byteIndex(hostname, '%') != -1 { // Don't deal with special form hostnames with backslashes // or '%'. - return hostLookupCgo + return fallbackOrder } // OpenBSD is unique and doesn't use nsswitch.conf. @@ -154,7 +155,7 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { return hostLookupDNSFiles } if len(lookup) < 1 || len(lookup) > 2 { - return hostLookupCgo + return fallbackOrder } switch lookup[0] { case "bind": @@ -162,7 +163,7 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { if lookup[1] == "file" { return hostLookupDNSFiles } - return hostLookupCgo + return fallbackOrder } return hostLookupDNS case "file": @@ -170,11 +171,11 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { if lookup[1] == "bind" { return hostLookupFilesDNS } - return hostLookupCgo + return fallbackOrder } return hostLookupFiles default: - return hostLookupCgo + return fallbackOrder } } @@ -189,7 +190,7 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { // because Go's native resolver doesn't do mDNS or // similar local resolution mechanisms, assume that // libc might (via Avahi, etc) and use cgo. - return hostLookupCgo + return fallbackOrder } nss := c.nss @@ -199,7 +200,7 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { if os.IsNotExist(nss.err) || (nss.err == nil && len(srcs) == 0) { if c.goos == "solaris" { // illumos defaults to "nis [NOTFOUND=return] files" - return hostLookupCgo + return fallbackOrder } if c.goos == "linux" { // glibc says the default is "dns [!UNAVAIL=return] files" @@ -212,7 +213,7 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { // We failed to parse or open nsswitch.conf, so // conservatively assume we should use cgo if it's // available. - return hostLookupCgo + return fallbackOrder } var mdnsSource, filesSource, dnsSource bool @@ -222,11 +223,11 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { if hasDot { continue } - return hostLookupCgo + return fallbackOrder } if src.source == "files" || src.source == "dns" { 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" { filesSource = true @@ -246,14 +247,14 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { continue } // 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 // exists, it might list other TLDs (besides .local) or even // '*', so just let libc deal with it. if mdnsSource && c.hasMDNSAllow { - return hostLookupCgo + return fallbackOrder } // Cases where Go can handle it without cgo and C thread @@ -272,7 +273,7 @@ func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) { } // Something weird. Let libc deal with it. - return hostLookupCgo + return fallbackOrder } // goDebugNetDNS parses the value of the GODEBUG "netdns" value. diff --git a/src/net/conf_test.go b/src/net/conf_test.go index f4659f407d..8f39847804 100644 --- a/src/net/conf_test.go +++ b/src/net/conf_test.go @@ -46,6 +46,28 @@ func TestConfHostLookupOrder(t *testing.T) { {"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", c: &conf{ -- 2.50.0