1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build darwin dragonfly freebsd linux netbsd openbsd solaris 6 7 package net 8 9 import ( 10 "os" 11 "strings" 12 "testing" 13 ) 14 15 type nssHostTest struct { 16 host string 17 want hostLookupOrder 18 } 19 20 func nssStr(s string) *nssConf { return parseNSSConf(strings.NewReader(s)) } 21 22 // represents a dnsConfig returned by parsing a nonexistent resolv.conf 23 var defaultResolvConf = &dnsConfig{ 24 servers: defaultNS, 25 ndots: 1, 26 timeout: 5, 27 attempts: 2, 28 err: os.ErrNotExist, 29 } 30 31 func TestConfHostLookupOrder(t *testing.T) { 32 tests := []struct { 33 name string 34 c *conf 35 goos string 36 hostTests []nssHostTest 37 }{ 38 { 39 name: "force", 40 c: &conf{ 41 forceCgoLookupHost: true, 42 nss: nssStr("foo: bar"), 43 resolv: defaultResolvConf, 44 }, 45 hostTests: []nssHostTest{ 46 {"foo.local", hostLookupCgo}, 47 {"google.com", hostLookupCgo}, 48 }, 49 }, 50 { 51 name: "ubuntu_trusty_avahi", 52 c: &conf{ 53 nss: nssStr("hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4"), 54 resolv: defaultResolvConf, 55 }, 56 hostTests: []nssHostTest{ 57 {"foo.local", hostLookupCgo}, 58 {"foo.local.", hostLookupCgo}, 59 {"foo.LOCAL", hostLookupCgo}, 60 {"foo.LOCAL.", hostLookupCgo}, 61 {"google.com", hostLookupFilesDNS}, 62 }, 63 }, 64 { 65 name: "freebsdlinux_no_resolv_conf", 66 c: &conf{ 67 goos: "freebsd", 68 nss: nssStr("foo: bar"), 69 resolv: defaultResolvConf, 70 }, 71 hostTests: []nssHostTest{{"google.com", hostLookupFilesDNS}}, 72 }, 73 // On OpenBSD, no resolv.conf means no DNS. 74 { 75 name: "openbsd_no_resolv_conf", 76 c: &conf{ 77 goos: "openbsd", 78 resolv: defaultResolvConf, 79 }, 80 hostTests: []nssHostTest{{"google.com", hostLookupFiles}}, 81 }, 82 { 83 name: "solaris_no_nsswitch", 84 c: &conf{ 85 goos: "solaris", 86 nss: &nssConf{err: os.ErrNotExist}, 87 resolv: defaultResolvConf, 88 }, 89 hostTests: []nssHostTest{{"google.com", hostLookupCgo}}, 90 }, 91 { 92 name: "openbsd_lookup_bind_file", 93 c: &conf{ 94 goos: "openbsd", 95 resolv: &dnsConfig{lookup: []string{"bind", "file"}}, 96 }, 97 hostTests: []nssHostTest{ 98 {"google.com", hostLookupDNSFiles}, 99 {"foo.local", hostLookupDNSFiles}, 100 }, 101 }, 102 { 103 name: "openbsd_lookup_file_bind", 104 c: &conf{ 105 goos: "openbsd", 106 resolv: &dnsConfig{lookup: []string{"file", "bind"}}, 107 }, 108 hostTests: []nssHostTest{{"google.com", hostLookupFilesDNS}}, 109 }, 110 { 111 name: "openbsd_lookup_bind", 112 c: &conf{ 113 goos: "openbsd", 114 resolv: &dnsConfig{lookup: []string{"bind"}}, 115 }, 116 hostTests: []nssHostTest{{"google.com", hostLookupDNS}}, 117 }, 118 { 119 name: "openbsd_lookup_file", 120 c: &conf{ 121 goos: "openbsd", 122 resolv: &dnsConfig{lookup: []string{"file"}}, 123 }, 124 hostTests: []nssHostTest{{"google.com", hostLookupFiles}}, 125 }, 126 { 127 name: "openbsd_lookup_yp", 128 c: &conf{ 129 goos: "openbsd", 130 resolv: &dnsConfig{lookup: []string{"file", "bind", "yp"}}, 131 }, 132 hostTests: []nssHostTest{{"google.com", hostLookupCgo}}, 133 }, 134 { 135 name: "openbsd_lookup_two", 136 c: &conf{ 137 goos: "openbsd", 138 resolv: &dnsConfig{lookup: []string{"file", "foo"}}, 139 }, 140 hostTests: []nssHostTest{{"google.com", hostLookupCgo}}, 141 }, 142 { 143 name: "openbsd_lookup_empty", 144 c: &conf{ 145 goos: "openbsd", 146 resolv: &dnsConfig{lookup: nil}, 147 }, 148 hostTests: []nssHostTest{{"google.com", hostLookupDNSFiles}}, 149 }, 150 // glibc lacking an nsswitch.conf, per 151 // http://www.gnu.org/software/libc/manual/html_node/Notes-on-NSS-Configuration-File.html 152 { 153 name: "linux_no_nsswitch.conf", 154 c: &conf{ 155 goos: "linux", 156 nss: &nssConf{err: os.ErrNotExist}, 157 resolv: defaultResolvConf, 158 }, 159 hostTests: []nssHostTest{{"google.com", hostLookupDNSFiles}}, 160 }, 161 { 162 name: "files_mdns_dns", 163 c: &conf{ 164 nss: nssStr("hosts: files mdns dns"), 165 resolv: defaultResolvConf, 166 }, 167 hostTests: []nssHostTest{ 168 {"x.com", hostLookupFilesDNS}, 169 {"x.local", hostLookupCgo}, 170 }, 171 }, 172 { 173 name: "dns_special_hostnames", 174 c: &conf{ 175 nss: nssStr("hosts: dns"), 176 resolv: defaultResolvConf, 177 }, 178 hostTests: []nssHostTest{ 179 {"x.com", hostLookupDNS}, 180 {"x\\.com", hostLookupCgo}, // punt on weird glibc escape 181 {"foo.com%en0", hostLookupCgo}, // and IPv6 zones 182 }, 183 }, 184 { 185 name: "mdns_allow", 186 c: &conf{ 187 nss: nssStr("hosts: files mdns dns"), 188 resolv: defaultResolvConf, 189 hasMDNSAllow: true, 190 }, 191 hostTests: []nssHostTest{ 192 {"x.com", hostLookupCgo}, 193 {"x.local", hostLookupCgo}, 194 }, 195 }, 196 { 197 name: "files_dns", 198 c: &conf{ 199 nss: nssStr("hosts: files dns"), 200 resolv: defaultResolvConf, 201 }, 202 hostTests: []nssHostTest{ 203 {"x.com", hostLookupFilesDNS}, 204 {"x", hostLookupFilesDNS}, 205 {"x.local", hostLookupCgo}, 206 }, 207 }, 208 { 209 name: "dns_files", 210 c: &conf{ 211 nss: nssStr("hosts: dns files"), 212 resolv: defaultResolvConf, 213 }, 214 hostTests: []nssHostTest{ 215 {"x.com", hostLookupDNSFiles}, 216 {"x", hostLookupDNSFiles}, 217 {"x.local", hostLookupCgo}, 218 }, 219 }, 220 { 221 name: "something_custom", 222 c: &conf{ 223 nss: nssStr("hosts: dns files something_custom"), 224 resolv: defaultResolvConf, 225 }, 226 hostTests: []nssHostTest{ 227 {"x.com", hostLookupCgo}, 228 }, 229 }, 230 { 231 name: "myhostname", 232 c: &conf{ 233 nss: nssStr("hosts: files dns myhostname"), 234 resolv: defaultResolvConf, 235 }, 236 hostTests: []nssHostTest{ 237 {"x.com", hostLookupFilesDNS}, 238 {"somehostname", hostLookupCgo}, 239 }, 240 }, 241 { 242 name: "ubuntu14.04.02", 243 c: &conf{ 244 nss: nssStr("hosts: files myhostname mdns4_minimal [NOTFOUND=return] dns mdns4"), 245 resolv: defaultResolvConf, 246 }, 247 hostTests: []nssHostTest{ 248 {"x.com", hostLookupFilesDNS}, 249 {"somehostname", hostLookupCgo}, 250 }, 251 }, 252 // Debian Squeeze is just "dns,files", but lists all 253 // the default criteria for dns, but then has a 254 // non-standard but redundant notfound=return for the 255 // files. 256 { 257 name: "debian_squeeze", 258 c: &conf{ 259 nss: nssStr("hosts: dns [success=return notfound=continue unavail=continue tryagain=continue] files [notfound=return]"), 260 resolv: defaultResolvConf, 261 }, 262 hostTests: []nssHostTest{ 263 {"x.com", hostLookupDNSFiles}, 264 {"somehostname", hostLookupDNSFiles}, 265 }, 266 }, 267 { 268 name: "resolv.conf-unknown", 269 c: &conf{ 270 nss: nssStr("foo: bar"), 271 resolv: &dnsConfig{servers: defaultNS, ndots: 1, timeout: 5, attempts: 2, unknownOpt: true}, 272 }, 273 hostTests: []nssHostTest{{"google.com", hostLookupCgo}}, 274 }, 275 // Android should always use cgo. 276 { 277 name: "android", 278 c: &conf{ 279 goos: "android", 280 nss: nssStr(""), 281 resolv: defaultResolvConf, 282 }, 283 hostTests: []nssHostTest{ 284 {"x.com", hostLookupCgo}, 285 }, 286 }, 287 } 288 for _, tt := range tests { 289 for _, ht := range tt.hostTests { 290 gotOrder := tt.c.hostLookupOrder(ht.host) 291 if gotOrder != ht.want { 292 t.Errorf("%s: hostLookupOrder(%q) = %v; want %v", tt.name, ht.host, gotOrder, ht.want) 293 } 294 } 295 } 296 297 } 298 299 func TestSystemConf(t *testing.T) { 300 systemConf() 301 } 302