@@ -28,8 +28,6 @@ type conf struct {
28
28
29
29
goos string // the runtime.GOOS, to ease testing
30
30
dnsDebugLevel int
31
-
32
- resolv * dnsConfig
33
31
}
34
32
35
33
var (
@@ -111,16 +109,6 @@ func initConfVal() {
111
109
return
112
110
}
113
111
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
-
124
112
if _ , err := os .Stat ("/etc/mdns.allow" ); err == nil {
125
113
confVal .hasMDNSAllow = true
126
114
}
@@ -129,12 +117,14 @@ func initConfVal() {
129
117
// canUseCgo reports whether calling cgo functions is allowed
130
118
// for non-hostname lookups.
131
119
func (c * conf ) canUseCgo () bool {
132
- return c .hostLookupOrder (nil , "" ) == hostLookupCgo
120
+ ret , _ := c .hostLookupOrder (nil , "" )
121
+ return ret == hostLookupCgo
133
122
}
134
123
135
124
// hostLookupOrder determines which strategy to use to resolve hostname.
136
125
// 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 ) {
138
128
if c .dnsDebugLevel > 1 {
139
129
defer func () {
140
130
print ("go package net: hostLookupOrder(" , hostname , ") = " , ret .String (), "\n " )
@@ -153,16 +143,26 @@ func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrde
153
143
fallbackOrder = hostLookupFilesDNS
154
144
}
155
145
}
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
161
148
}
162
149
if bytealg .IndexByteString (hostname , '\\' ) != - 1 || bytealg .IndexByteString (hostname , '%' ) != - 1 {
163
150
// Don't deal with special form hostnames with backslashes
164
151
// 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
166
166
}
167
167
168
168
// OpenBSD is unique and doesn't use nsswitch.conf.
@@ -171,39 +171,40 @@ func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrde
171
171
// OpenBSD's resolv.conf manpage says that a non-existent
172
172
// resolv.conf means "lookup" defaults to only "files",
173
173
// without DNS lookups.
174
- if os .IsNotExist (c . resolv .err ) {
175
- return hostLookupFiles
174
+ if os .IsNotExist (conf .err ) {
175
+ return hostLookupFiles , conf
176
176
}
177
- lookup := c .resolv .lookup
177
+
178
+ lookup := conf .lookup
178
179
if len (lookup ) == 0 {
179
180
// https://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/resolv.conf.5
180
181
// "If the lookup keyword is not used in the
181
182
// system's resolv.conf file then the assumed
182
183
// order is 'bind file'"
183
- return hostLookupDNSFiles
184
+ return hostLookupDNSFiles , conf
184
185
}
185
186
if len (lookup ) < 1 || len (lookup ) > 2 {
186
- return fallbackOrder
187
+ return fallbackOrder , conf
187
188
}
188
189
switch lookup [0 ] {
189
190
case "bind" :
190
191
if len (lookup ) == 2 {
191
192
if lookup [1 ] == "file" {
192
- return hostLookupDNSFiles
193
+ return hostLookupDNSFiles , conf
193
194
}
194
- return fallbackOrder
195
+ return fallbackOrder , conf
195
196
}
196
- return hostLookupDNS
197
+ return hostLookupDNS , conf
197
198
case "file" :
198
199
if len (lookup ) == 2 {
199
200
if lookup [1 ] == "bind" {
200
- return hostLookupFilesDNS
201
+ return hostLookupFilesDNS , conf
201
202
}
202
- return fallbackOrder
203
+ return fallbackOrder , conf
203
204
}
204
- return hostLookupFiles
205
+ return hostLookupFiles , conf
205
206
default :
206
- return fallbackOrder
207
+ return fallbackOrder , conf
207
208
}
208
209
}
209
210
@@ -216,7 +217,7 @@ func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrde
216
217
// because Go's native resolver doesn't do mDNS or
217
218
// similar local resolution mechanisms, assume that
218
219
// libc might (via Avahi, etc) and use cgo.
219
- return fallbackOrder
220
+ return fallbackOrder , conf
220
221
}
221
222
222
223
nss := getSystemNSS ()
@@ -226,33 +227,34 @@ func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrde
226
227
if os .IsNotExist (nss .err ) || (nss .err == nil && len (srcs ) == 0 ) {
227
228
if c .goos == "solaris" {
228
229
// illumos defaults to "nis [NOTFOUND=return] files"
229
- return fallbackOrder
230
+ return fallbackOrder , conf
230
231
}
231
- return hostLookupFilesDNS
232
+
233
+ return hostLookupFilesDNS , conf
232
234
}
233
235
if nss .err != nil {
234
236
// We failed to parse or open nsswitch.conf, so
235
237
// conservatively assume we should use cgo if it's
236
238
// available.
237
- return fallbackOrder
239
+ return fallbackOrder , conf
238
240
}
239
241
240
242
var mdnsSource , filesSource , dnsSource bool
241
243
var first string
242
244
for _ , src := range srcs {
243
245
if src .source == "myhostname" {
244
246
if isLocalhost (hostname ) || isGateway (hostname ) || isOutbound (hostname ) {
245
- return fallbackOrder
247
+ return fallbackOrder , conf
246
248
}
247
249
hn , err := getHostname ()
248
250
if err != nil || stringsEqualFold (hostname , hn ) {
249
- return fallbackOrder
251
+ return fallbackOrder , conf
250
252
}
251
253
continue
252
254
}
253
255
if src .source == "files" || src .source == "dns" {
254
256
if ! src .standardCriteria () {
255
- return fallbackOrder // non-standard; let libc deal with it.
257
+ return fallbackOrder , conf // non-standard; let libc deal with it.
256
258
}
257
259
if src .source == "files" {
258
260
filesSource = true
@@ -272,33 +274,33 @@ func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrde
272
274
continue
273
275
}
274
276
// Some source we don't know how to deal with.
275
- return fallbackOrder
277
+ return fallbackOrder , conf
276
278
}
277
279
278
280
// We don't parse mdns.allow files. They're rare. If one
279
281
// exists, it might list other TLDs (besides .local) or even
280
282
// '*', so just let libc deal with it.
281
283
if mdnsSource && c .hasMDNSAllow {
282
- return fallbackOrder
284
+ return fallbackOrder , conf
283
285
}
284
286
285
287
// Cases where Go can handle it without cgo and C thread
286
288
// overhead.
287
289
switch {
288
290
case filesSource && dnsSource :
289
291
if first == "files" {
290
- return hostLookupFilesDNS
292
+ return hostLookupFilesDNS , conf
291
293
} else {
292
- return hostLookupDNSFiles
294
+ return hostLookupDNSFiles , conf
293
295
}
294
296
case filesSource :
295
- return hostLookupFiles
297
+ return hostLookupFiles , conf
296
298
case dnsSource :
297
- return hostLookupDNS
299
+ return hostLookupDNS , conf
298
300
}
299
301
300
302
// Something weird. Let libc deal with it.
301
- return fallbackOrder
303
+ return fallbackOrder , conf
302
304
}
303
305
304
306
var netdns = godebug .New ("netdns" )
0 commit comments