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: 's avatarMatthew Dempsky <mdempsky@google.com>
parent 84e80804
......@@ -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.
......
......@@ -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{
......
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