Home | History | Annotate | Download | only in net
      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