Skip to content

Commit d52883f

Browse files
mateusz834gopherbot
authored andcommitted
net: use a consistent dnsConfig in hostLookupOrder
Use the same dnsConfig throughout a DNS lookup operation. Before this CL it was possible to decide to re-read a modified resolv.conf file during the DNS lookup, which could lead to inconsistencies between the lookup order and the name server list. Change-Id: I0689749272b8263268d00b9a9cb4458cd68b23eb GitHub-Last-Rev: 64810a2 GitHub-Pull-Request: golang#56690 Reviewed-on: https://go-review.googlesource.com/c/go/+/449337 Reviewed-by: Damien Neil <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]> Auto-Submit: Ian Lance Taylor <[email protected]>
1 parent f977ffe commit d52883f

9 files changed

+213
-193
lines changed

Diff for: src/net/conf.go

+48-46
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ type conf struct {
2828

2929
goos string // the runtime.GOOS, to ease testing
3030
dnsDebugLevel int
31-
32-
resolv *dnsConfig
3331
}
3432

3533
var (
@@ -111,16 +109,6 @@ func initConfVal() {
111109
return
112110
}
113111

114-
confVal.resolv = dnsReadConfig("/etc/resolv.conf")
115-
if confVal.resolv.err != nil && !os.IsNotExist(confVal.resolv.err) &&
116-
!os.IsPermission(confVal.resolv.err) {
117-
// If we can't read the resolv.conf file, assume it
118-
// had something important in it and defer to cgo.
119-
// libc's resolver might then fail too, but at least
120-
// it wasn't our fault.
121-
confVal.forceCgoLookupHost = true
122-
}
123-
124112
if _, err := os.Stat("/etc/mdns.allow"); err == nil {
125113
confVal.hasMDNSAllow = true
126114
}
@@ -129,12 +117,14 @@ func initConfVal() {
129117
// canUseCgo reports whether calling cgo functions is allowed
130118
// for non-hostname lookups.
131119
func (c *conf) canUseCgo() bool {
132-
return c.hostLookupOrder(nil, "") == hostLookupCgo
120+
ret, _ := c.hostLookupOrder(nil, "")
121+
return ret == hostLookupCgo
133122
}
134123

135124
// hostLookupOrder determines which strategy to use to resolve hostname.
136125
// The provided Resolver is optional. nil means to not consider its options.
137-
func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrder) {
126+
// It also returns dnsConfig when it was used to determine the lookup order.
127+
func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrder, dnsConfig *dnsConfig) {
138128
if c.dnsDebugLevel > 1 {
139129
defer func() {
140130
print("go package net: hostLookupOrder(", hostname, ") = ", ret.String(), "\n")
@@ -153,16 +143,26 @@ func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrde
153143
fallbackOrder = hostLookupFilesDNS
154144
}
155145
}
156-
if c.goos == "windows" || c.goos == "plan9" {
157-
return fallbackOrder
158-
}
159-
if c.forceCgoLookupHost || c.resolv.unknownOpt || c.goos == "android" {
160-
return fallbackOrder
146+
if c.forceCgoLookupHost || c.goos == "android" || c.goos == "windows" || c.goos == "plan9" {
147+
return fallbackOrder, nil
161148
}
162149
if bytealg.IndexByteString(hostname, '\\') != -1 || bytealg.IndexByteString(hostname, '%') != -1 {
163150
// Don't deal with special form hostnames with backslashes
164151
// or '%'.
165-
return fallbackOrder
152+
return fallbackOrder, nil
153+
}
154+
155+
conf := getSystemDNSConfig()
156+
if conf.err != nil && !os.IsNotExist(conf.err) && !os.IsPermission(conf.err) {
157+
// If we can't read the resolv.conf file, assume it
158+
// had something important in it and defer to cgo.
159+
// libc's resolver might then fail too, but at least
160+
// it wasn't our fault.
161+
return fallbackOrder, conf
162+
}
163+
164+
if conf.unknownOpt {
165+
return fallbackOrder, conf
166166
}
167167

168168
// OpenBSD is unique and doesn't use nsswitch.conf.
@@ -171,39 +171,40 @@ func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrde
171171
// OpenBSD's resolv.conf manpage says that a non-existent
172172
// resolv.conf means "lookup" defaults to only "files",
173173
// without DNS lookups.
174-
if os.IsNotExist(c.resolv.err) {
175-
return hostLookupFiles
174+
if os.IsNotExist(conf.err) {
175+
return hostLookupFiles, conf
176176
}
177-
lookup := c.resolv.lookup
177+
178+
lookup := conf.lookup
178179
if len(lookup) == 0 {
179180
// https://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/resolv.conf.5
180181
// "If the lookup keyword is not used in the
181182
// system's resolv.conf file then the assumed
182183
// order is 'bind file'"
183-
return hostLookupDNSFiles
184+
return hostLookupDNSFiles, conf
184185
}
185186
if len(lookup) < 1 || len(lookup) > 2 {
186-
return fallbackOrder
187+
return fallbackOrder, conf
187188
}
188189
switch lookup[0] {
189190
case "bind":
190191
if len(lookup) == 2 {
191192
if lookup[1] == "file" {
192-
return hostLookupDNSFiles
193+
return hostLookupDNSFiles, conf
193194
}
194-
return fallbackOrder
195+
return fallbackOrder, conf
195196
}
196-
return hostLookupDNS
197+
return hostLookupDNS, conf
197198
case "file":
198199
if len(lookup) == 2 {
199200
if lookup[1] == "bind" {
200-
return hostLookupFilesDNS
201+
return hostLookupFilesDNS, conf
201202
}
202-
return fallbackOrder
203+
return fallbackOrder, conf
203204
}
204-
return hostLookupFiles
205+
return hostLookupFiles, conf
205206
default:
206-
return fallbackOrder
207+
return fallbackOrder, conf
207208
}
208209
}
209210

@@ -216,7 +217,7 @@ func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrde
216217
// because Go's native resolver doesn't do mDNS or
217218
// similar local resolution mechanisms, assume that
218219
// libc might (via Avahi, etc) and use cgo.
219-
return fallbackOrder
220+
return fallbackOrder, conf
220221
}
221222

222223
nss := getSystemNSS()
@@ -226,33 +227,34 @@ func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrde
226227
if os.IsNotExist(nss.err) || (nss.err == nil && len(srcs) == 0) {
227228
if c.goos == "solaris" {
228229
// illumos defaults to "nis [NOTFOUND=return] files"
229-
return fallbackOrder
230+
return fallbackOrder, conf
230231
}
231-
return hostLookupFilesDNS
232+
233+
return hostLookupFilesDNS, conf
232234
}
233235
if nss.err != nil {
234236
// We failed to parse or open nsswitch.conf, so
235237
// conservatively assume we should use cgo if it's
236238
// available.
237-
return fallbackOrder
239+
return fallbackOrder, conf
238240
}
239241

240242
var mdnsSource, filesSource, dnsSource bool
241243
var first string
242244
for _, src := range srcs {
243245
if src.source == "myhostname" {
244246
if isLocalhost(hostname) || isGateway(hostname) || isOutbound(hostname) {
245-
return fallbackOrder
247+
return fallbackOrder, conf
246248
}
247249
hn, err := getHostname()
248250
if err != nil || stringsEqualFold(hostname, hn) {
249-
return fallbackOrder
251+
return fallbackOrder, conf
250252
}
251253
continue
252254
}
253255
if src.source == "files" || src.source == "dns" {
254256
if !src.standardCriteria() {
255-
return fallbackOrder // non-standard; let libc deal with it.
257+
return fallbackOrder, conf // non-standard; let libc deal with it.
256258
}
257259
if src.source == "files" {
258260
filesSource = true
@@ -272,33 +274,33 @@ func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrde
272274
continue
273275
}
274276
// Some source we don't know how to deal with.
275-
return fallbackOrder
277+
return fallbackOrder, conf
276278
}
277279

278280
// We don't parse mdns.allow files. They're rare. If one
279281
// exists, it might list other TLDs (besides .local) or even
280282
// '*', so just let libc deal with it.
281283
if mdnsSource && c.hasMDNSAllow {
282-
return fallbackOrder
284+
return fallbackOrder, conf
283285
}
284286

285287
// Cases where Go can handle it without cgo and C thread
286288
// overhead.
287289
switch {
288290
case filesSource && dnsSource:
289291
if first == "files" {
290-
return hostLookupFilesDNS
292+
return hostLookupFilesDNS, conf
291293
} else {
292-
return hostLookupDNSFiles
294+
return hostLookupDNSFiles, conf
293295
}
294296
case filesSource:
295-
return hostLookupFiles
297+
return hostLookupFiles, conf
296298
case dnsSource:
297-
return hostLookupDNS
299+
return hostLookupDNS, conf
298300
}
299301

300302
// Something weird. Let libc deal with it.
301-
return fallbackOrder
303+
return fallbackOrder, conf
302304
}
303305

304306
var netdns = godebug.New("netdns")

0 commit comments

Comments
 (0)