net: ensure identical queries are not sent multiple times in builtin stub resolver
Prevents non-rooted queries with > ndots dots from being tried twice on error.
Fixes #8616.
Benchmark results on linux/amd64
benchmark old ns/op new ns/op delta
BenchmarkGoLookupIPNoSuchHost 8212394 4413293 -46.26%
benchmark old allocs new allocs delta
BenchmarkGoLookupIPNoSuchHost 216 108 -50.00%
benchmark old bytes new bytes delta
BenchmarkGoLookupIPNoSuchHost 17460 8726 -50.02%
LGTM=iant, mikioh.mikioh
R=golang-codereviews, iant, mikioh.mikioh
CC=golang-codereviews
https://golang.org/cl/137870043
diff --git a/src/pkg/net/dnsclient_unix.go b/src/pkg/net/dnsclient_unix.go
index eb4b590..dc5eed9 100644
--- a/src/pkg/net/dnsclient_unix.go
+++ b/src/pkg/net/dnsclient_unix.go
@@ -310,13 +310,10 @@
}
// Can try as ordinary name.
cname, addrs, err = tryOneName(cfg.dnsConfig, rname, qtype)
- if err == nil {
+ if rooted || err == nil {
return
}
}
- if rooted {
- return
- }
// Otherwise, try suffixes.
for i := 0; i < len(cfg.dnsConfig.search); i++ {
@@ -330,15 +327,15 @@
}
}
- // Last ditch effort: try unsuffixed.
- rname := name
- if !rooted {
- rname += "."
+ // Last ditch effort: try unsuffixed only if we haven't already,
+ // that is, name is not rooted and has less than ndots dots.
+ if count(name, '.') < cfg.dnsConfig.ndots {
+ cname, addrs, err = tryOneName(cfg.dnsConfig, name+".", qtype)
+ if err == nil {
+ return
+ }
}
- cname, addrs, err = tryOneName(cfg.dnsConfig, rname, qtype)
- if err == nil {
- return
- }
+
if e, ok := err.(*DNSError); ok {
// Show original name passed to lookup, not suffixed one.
// In general we might have tried many suffixes; showing
diff --git a/src/pkg/net/dnsclient_unix_test.go b/src/pkg/net/dnsclient_unix_test.go
index 39d82d99..204c8b7 100644
--- a/src/pkg/net/dnsclient_unix_test.go
+++ b/src/pkg/net/dnsclient_unix_test.go
@@ -217,3 +217,9 @@
r.SetConf("nameserver 8.8.4.4")
r.WantServers([]string{"[8.8.4.4]"})
}
+
+func BenchmarkGoLookupIPNoSuchHost(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ goLookupIP("some.nonexistent")
+ }
+}