| 
									
										
										
										
											2013-08-13 09:44:12 -07:00
										 |  |  | // Copyright 2013 The Go Authors. All rights reserved. | 
					
						
							|  |  |  | // Use of this source code is governed by a BSD-style | 
					
						
							|  |  |  | // license that can be found in the LICENSE file. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-30 23:26:07 +09:00
										 |  |  | // +build darwin dragonfly freebsd linux netbsd openbsd solaris | 
					
						
							| 
									
										
										
										
											2013-08-14 00:44:57 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-13 09:44:12 -07:00
										 |  |  | package net | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2016-04-14 17:47:25 -07:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2016-04-14 12:17:44 +09:00
										 |  |  | 	"internal/testenv" | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | 	"io/ioutil" | 
					
						
							|  |  |  | 	"os" | 
					
						
							|  |  |  | 	"path" | 
					
						
							|  |  |  | 	"reflect" | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 	"strings" | 
					
						
							|  |  |  | 	"sync" | 
					
						
							| 
									
										
										
										
											2013-08-13 09:44:12 -07:00
										 |  |  | 	"testing" | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2013-08-13 09:44:12 -07:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-06 09:58:47 +09:00
										 |  |  | var dnsTransportFallbackTests = []struct { | 
					
						
							|  |  |  | 	server  string | 
					
						
							|  |  |  | 	name    string | 
					
						
							|  |  |  | 	qtype   uint16 | 
					
						
							|  |  |  | 	timeout int | 
					
						
							|  |  |  | 	rcode   int | 
					
						
							|  |  |  | }{ | 
					
						
							|  |  |  | 	// Querying "com." with qtype=255 usually makes an answer | 
					
						
							|  |  |  | 	// which requires more than 512 bytes. | 
					
						
							|  |  |  | 	{"8.8.8.8:53", "com.", dnsTypeALL, 2, dnsRcodeSuccess}, | 
					
						
							|  |  |  | 	{"8.8.4.4:53", "com.", dnsTypeALL, 4, dnsRcodeSuccess}, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestDNSTransportFallback(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-04-14 12:17:44 +09:00
										 |  |  | 	testenv.MustHaveExternalNetwork(t) | 
					
						
							| 
									
										
										
										
											2014-08-06 09:58:47 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for _, tt := range dnsTransportFallbackTests { | 
					
						
							|  |  |  | 		timeout := time.Duration(tt.timeout) * time.Second | 
					
						
							|  |  |  | 		msg, err := exchange(tt.server, tt.name, tt.qtype, timeout) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Error(err) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		switch msg.rcode { | 
					
						
							|  |  |  | 		case tt.rcode, dnsRcodeServerFailure: | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			t.Errorf("got %v from %v; want %v", msg.rcode, tt.server, tt.rcode) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // See RFC 6761 for further information about the reserved, pseudo | 
					
						
							|  |  |  | // domain names. | 
					
						
							|  |  |  | var specialDomainNameTests = []struct { | 
					
						
							|  |  |  | 	name  string | 
					
						
							|  |  |  | 	qtype uint16 | 
					
						
							|  |  |  | 	rcode int | 
					
						
							|  |  |  | }{ | 
					
						
							| 
									
										
										
										
											2015-01-14 21:25:26 -08:00
										 |  |  | 	// Name resolution APIs and libraries should not recognize the | 
					
						
							| 
									
										
										
										
											2014-08-06 09:58:47 +09:00
										 |  |  | 	// followings as special. | 
					
						
							|  |  |  | 	{"1.0.168.192.in-addr.arpa.", dnsTypePTR, dnsRcodeNameError}, | 
					
						
							|  |  |  | 	{"test.", dnsTypeALL, dnsRcodeNameError}, | 
					
						
							|  |  |  | 	{"example.com.", dnsTypeALL, dnsRcodeSuccess}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-14 21:25:26 -08:00
										 |  |  | 	// Name resolution APIs and libraries should recognize the | 
					
						
							| 
									
										
										
										
											2014-08-06 09:58:47 +09:00
										 |  |  | 	// followings as special and should not send any queries. | 
					
						
							| 
									
										
										
										
											2016-02-24 11:55:20 +01:00
										 |  |  | 	// Though, we test those names here for verifying negative | 
					
						
							| 
									
										
										
										
											2014-08-06 09:58:47 +09:00
										 |  |  | 	// answers at DNS query-response interaction level. | 
					
						
							|  |  |  | 	{"localhost.", dnsTypeALL, dnsRcodeNameError}, | 
					
						
							|  |  |  | 	{"invalid.", dnsTypeALL, dnsRcodeNameError}, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestSpecialDomainName(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-04-14 12:17:44 +09:00
										 |  |  | 	testenv.MustHaveExternalNetwork(t) | 
					
						
							| 
									
										
										
										
											2014-08-06 09:58:47 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	server := "8.8.8.8:53" | 
					
						
							|  |  |  | 	for _, tt := range specialDomainNameTests { | 
					
						
							| 
									
										
										
										
											2016-01-14 16:36:43 -05:00
										 |  |  | 		msg, err := exchange(server, tt.name, tt.qtype, 3*time.Second) | 
					
						
							| 
									
										
										
										
											2014-08-06 09:58:47 +09:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Error(err) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		switch msg.rcode { | 
					
						
							|  |  |  | 		case tt.rcode, dnsRcodeServerFailure: | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			t.Errorf("got %v from %v; want %v", msg.rcode, server, tt.rcode) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-08-13 09:44:12 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-30 23:08:44 -07:00
										 |  |  | // Issue 13705: don't try to resolve onion addresses, etc | 
					
						
							|  |  |  | func TestAvoidDNSName(t *testing.T) { | 
					
						
							|  |  |  | 	tests := []struct { | 
					
						
							|  |  |  | 		name  string | 
					
						
							|  |  |  | 		avoid bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{"foo.com", false}, | 
					
						
							|  |  |  | 		{"foo.com.", false}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{"foo.onion.", true}, | 
					
						
							|  |  |  | 		{"foo.onion", true}, | 
					
						
							|  |  |  | 		{"foo.ONION", true}, | 
					
						
							|  |  |  | 		{"foo.ONION.", true}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{"foo.local.", true}, | 
					
						
							|  |  |  | 		{"foo.local", true}, | 
					
						
							|  |  |  | 		{"foo.LOCAL", true}, | 
					
						
							|  |  |  | 		{"foo.LOCAL.", true}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{"", true}, // will be rejected earlier too | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Without stuff before onion/local, they're fine to | 
					
						
							|  |  |  | 		// use DNS. With a search path, | 
					
						
							|  |  |  | 		// "onion.vegegtables.com" can use DNS. Without a | 
					
						
							|  |  |  | 		// search path (or with a trailing dot), the queries | 
					
						
							|  |  |  | 		// are just kinda useless, but don't reveal anything | 
					
						
							|  |  |  | 		// private. | 
					
						
							|  |  |  | 		{"local", false}, | 
					
						
							|  |  |  | 		{"onion", false}, | 
					
						
							|  |  |  | 		{"local.", false}, | 
					
						
							|  |  |  | 		{"onion.", false}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for _, tt := range tests { | 
					
						
							|  |  |  | 		got := avoidDNS(tt.name) | 
					
						
							|  |  |  | 		if got != tt.avoid { | 
					
						
							|  |  |  | 			t.Errorf("avoidDNS(%q) = %v; want %v", tt.name, got, tt.avoid) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Issue 13705: don't try to resolve onion addresses, etc | 
					
						
							|  |  |  | func TestLookupTorOnion(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-04-14 17:47:25 -07:00
										 |  |  | 	addrs, err := goLookupIP(context.Background(), "foo.onion") | 
					
						
							| 
									
										
										
										
											2016-03-30 23:08:44 -07:00
										 |  |  | 	if len(addrs) > 0 { | 
					
						
							|  |  |  | 		t.Errorf("unexpected addresses: %v", addrs) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("lookup = %v; want nil", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | type resolvConfTest struct { | 
					
						
							| 
									
										
										
										
											2015-05-12 23:56:56 -04:00
										 |  |  | 	dir  string | 
					
						
							|  |  |  | 	path string | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 	*resolverConfig | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | func newResolvConfTest() (*resolvConfTest, error) { | 
					
						
							| 
									
										
										
										
											2015-05-06 10:41:01 +09:00
										 |  |  | 	dir, err := ioutil.TempDir("", "go-resolvconftest") | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 		return nil, err | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 	conf := &resolvConfTest{ | 
					
						
							|  |  |  | 		dir:            dir, | 
					
						
							|  |  |  | 		path:           path.Join(dir, "resolv.conf"), | 
					
						
							|  |  |  | 		resolverConfig: &resolvConf, | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 	conf.initOnce.Do(conf.init) | 
					
						
							|  |  |  | 	return conf, nil | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | func (conf *resolvConfTest) writeAndUpdate(lines []string) error { | 
					
						
							|  |  |  | 	f, err := os.OpenFile(conf.path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600) | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 	if _, err := f.WriteString(strings.Join(lines, "\n")); err != nil { | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | 		f.Close() | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	f.Close() | 
					
						
							| 
									
										
										
										
											2016-02-20 20:33:34 -08:00
										 |  |  | 	if err := conf.forceUpdate(conf.path, time.Now().Add(time.Hour)); err != nil { | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-20 20:33:34 -08:00
										 |  |  | func (conf *resolvConfTest) forceUpdate(name string, lastChecked time.Time) error { | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 	dnsConf := dnsReadConfig(name) | 
					
						
							|  |  |  | 	conf.mu.Lock() | 
					
						
							|  |  |  | 	conf.dnsConfig = dnsConf | 
					
						
							|  |  |  | 	conf.mu.Unlock() | 
					
						
							|  |  |  | 	for i := 0; i < 5; i++ { | 
					
						
							|  |  |  | 		if conf.tryAcquireSema() { | 
					
						
							| 
									
										
										
										
											2016-02-20 20:33:34 -08:00
										 |  |  | 			conf.lastChecked = lastChecked | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 			conf.releaseSema() | 
					
						
							|  |  |  | 			return nil | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 	return fmt.Errorf("tryAcquireSema for %s failed", name) | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | func (conf *resolvConfTest) servers() []string { | 
					
						
							|  |  |  | 	conf.mu.RLock() | 
					
						
							|  |  |  | 	servers := conf.dnsConfig.servers | 
					
						
							|  |  |  | 	conf.mu.RUnlock() | 
					
						
							|  |  |  | 	return servers | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-04-25 20:50:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | func (conf *resolvConfTest) teardown() error { | 
					
						
							| 
									
										
										
										
											2016-02-20 20:33:34 -08:00
										 |  |  | 	err := conf.forceUpdate("/etc/resolv.conf", time.Time{}) | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 	os.RemoveAll(conf.dir) | 
					
						
							|  |  |  | 	return err | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-04-25 20:50:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | var updateResolvConfTests = []struct { | 
					
						
							|  |  |  | 	name    string   // query name | 
					
						
							|  |  |  | 	lines   []string // resolver configuration lines | 
					
						
							|  |  |  | 	servers []string // expected name servers | 
					
						
							|  |  |  | }{ | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		name:    "golang.org", | 
					
						
							|  |  |  | 		lines:   []string{"nameserver 8.8.8.8"}, | 
					
						
							|  |  |  | 		servers: []string{"8.8.8.8"}, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		name:    "", | 
					
						
							|  |  |  | 		lines:   nil, // an empty resolv.conf should use defaultNS as name servers | 
					
						
							|  |  |  | 		servers: defaultNS, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		name:    "www.example.com", | 
					
						
							|  |  |  | 		lines:   []string{"nameserver 8.8.4.4"}, | 
					
						
							|  |  |  | 		servers: []string{"8.8.4.4"}, | 
					
						
							|  |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | func TestUpdateResolvConf(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-04-14 12:17:44 +09:00
										 |  |  | 	testenv.MustHaveExternalNetwork(t) | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 	conf, err := newResolvConfTest() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-05-01 12:38:42 +09:00
										 |  |  | 		t.Fatal(err) | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 	defer conf.teardown() | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 	for i, tt := range updateResolvConfTests { | 
					
						
							|  |  |  | 		if err := conf.writeAndUpdate(tt.lines); err != nil { | 
					
						
							|  |  |  | 			t.Error(err) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if tt.name != "" { | 
					
						
							|  |  |  | 			var wg sync.WaitGroup | 
					
						
							|  |  |  | 			const N = 10 | 
					
						
							|  |  |  | 			wg.Add(N) | 
					
						
							|  |  |  | 			for j := 0; j < N; j++ { | 
					
						
							|  |  |  | 				go func(name string) { | 
					
						
							|  |  |  | 					defer wg.Done() | 
					
						
							| 
									
										
										
										
											2016-04-14 17:47:25 -07:00
										 |  |  | 					ips, err := goLookupIP(context.Background(), name) | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 					if err != nil { | 
					
						
							|  |  |  | 						t.Error(err) | 
					
						
							|  |  |  | 						return | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					if len(ips) == 0 { | 
					
						
							|  |  |  | 						t.Errorf("no records for %s", name) | 
					
						
							|  |  |  | 						return | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				}(tt.name) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			wg.Wait() | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		servers := conf.servers() | 
					
						
							|  |  |  | 		if !reflect.DeepEqual(servers, tt.servers) { | 
					
						
							|  |  |  | 			t.Errorf("#%d: got %v; want %v", i, servers, tt.servers) | 
					
						
							|  |  |  | 			continue | 
					
						
							| 
									
										
										
										
											2015-04-25 20:50:21 -04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-05-14 17:11:00 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-08-30 07:50:50 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-09 17:30:00 +09:00
										 |  |  | var goLookupIPWithResolverConfigTests = []struct { | 
					
						
							|  |  |  | 	name  string | 
					
						
							|  |  |  | 	lines []string // resolver configuration lines | 
					
						
							|  |  |  | 	error | 
					
						
							|  |  |  | 	a, aaaa bool // whether response contains A, AAAA-record | 
					
						
							|  |  |  | }{ | 
					
						
							|  |  |  | 	// no records, transport timeout | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		"jgahvsekduiv9bw4b3qhn4ykdfgj0493iohkrjfhdvhjiu4j", | 
					
						
							|  |  |  | 		[]string{ | 
					
						
							|  |  |  | 			"options timeout:1 attempts:1", | 
					
						
							|  |  |  | 			"nameserver 255.255.255.255", // please forgive us for abuse of limited broadcast address | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		&DNSError{Name: "jgahvsekduiv9bw4b3qhn4ykdfgj0493iohkrjfhdvhjiu4j", Server: "255.255.255.255:53", IsTimeout: true}, | 
					
						
							|  |  |  | 		false, false, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// no records, non-existent domain | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		"jgahvsekduiv9bw4b3qhn4ykdfgj0493iohkrjfhdvhjiu4j", | 
					
						
							|  |  |  | 		[]string{ | 
					
						
							|  |  |  | 			"options timeout:3 attempts:1", | 
					
						
							|  |  |  | 			"nameserver 8.8.8.8", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		&DNSError{Name: "jgahvsekduiv9bw4b3qhn4ykdfgj0493iohkrjfhdvhjiu4j", Server: "8.8.8.8:53", IsTimeout: false}, | 
					
						
							|  |  |  | 		false, false, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// a few A records, no AAAA records | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		"ipv4.google.com.", | 
					
						
							|  |  |  | 		[]string{ | 
					
						
							|  |  |  | 			"nameserver 8.8.8.8", | 
					
						
							|  |  |  | 			"nameserver 2001:4860:4860::8888", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		nil, | 
					
						
							|  |  |  | 		true, false, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		"ipv4.google.com", | 
					
						
							|  |  |  | 		[]string{ | 
					
						
							|  |  |  | 			"domain golang.org", | 
					
						
							|  |  |  | 			"nameserver 2001:4860:4860::8888", | 
					
						
							|  |  |  | 			"nameserver 8.8.8.8", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		nil, | 
					
						
							|  |  |  | 		true, false, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		"ipv4.google.com", | 
					
						
							|  |  |  | 		[]string{ | 
					
						
							|  |  |  | 			"search x.golang.org y.golang.org", | 
					
						
							|  |  |  | 			"nameserver 2001:4860:4860::8888", | 
					
						
							|  |  |  | 			"nameserver 8.8.8.8", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		nil, | 
					
						
							|  |  |  | 		true, false, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// no A records, a few AAAA records | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		"ipv6.google.com.", | 
					
						
							|  |  |  | 		[]string{ | 
					
						
							|  |  |  | 			"nameserver 2001:4860:4860::8888", | 
					
						
							|  |  |  | 			"nameserver 8.8.8.8", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		nil, | 
					
						
							|  |  |  | 		false, true, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		"ipv6.google.com", | 
					
						
							|  |  |  | 		[]string{ | 
					
						
							|  |  |  | 			"domain golang.org", | 
					
						
							|  |  |  | 			"nameserver 8.8.8.8", | 
					
						
							|  |  |  | 			"nameserver 2001:4860:4860::8888", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		nil, | 
					
						
							|  |  |  | 		false, true, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		"ipv6.google.com", | 
					
						
							|  |  |  | 		[]string{ | 
					
						
							|  |  |  | 			"search x.golang.org y.golang.org", | 
					
						
							|  |  |  | 			"nameserver 8.8.8.8", | 
					
						
							|  |  |  | 			"nameserver 2001:4860:4860::8888", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		nil, | 
					
						
							|  |  |  | 		false, true, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// both A and AAAA records | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		"hostname.as112.net", // see RFC 7534 | 
					
						
							|  |  |  | 		[]string{ | 
					
						
							|  |  |  | 			"domain golang.org", | 
					
						
							|  |  |  | 			"nameserver 2001:4860:4860::8888", | 
					
						
							|  |  |  | 			"nameserver 8.8.8.8", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		nil, | 
					
						
							|  |  |  | 		true, true, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		"hostname.as112.net", // see RFC 7534 | 
					
						
							|  |  |  | 		[]string{ | 
					
						
							|  |  |  | 			"search x.golang.org y.golang.org", | 
					
						
							|  |  |  | 			"nameserver 2001:4860:4860::8888", | 
					
						
							|  |  |  | 			"nameserver 8.8.8.8", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		nil, | 
					
						
							|  |  |  | 		true, true, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestGoLookupIPWithResolverConfig(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-04-14 12:17:44 +09:00
										 |  |  | 	testenv.MustHaveExternalNetwork(t) | 
					
						
							| 
									
										
										
										
											2015-06-09 17:30:00 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	conf, err := newResolvConfTest() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer conf.teardown() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, tt := range goLookupIPWithResolverConfigTests { | 
					
						
							|  |  |  | 		if err := conf.writeAndUpdate(tt.lines); err != nil { | 
					
						
							|  |  |  | 			t.Error(err) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-04-14 17:47:25 -07:00
										 |  |  | 		addrs, err := goLookupIP(context.Background(), tt.name) | 
					
						
							| 
									
										
										
										
											2015-06-09 17:30:00 +09:00
										 |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2016-02-24 11:59:49 +09:00
										 |  |  | 			// This test uses external network connectivity. | 
					
						
							|  |  |  | 			// We need to take care with errors on both | 
					
						
							|  |  |  | 			// DNS message exchange layer and DNS | 
					
						
							|  |  |  | 			// transport layer because goLookupIP may fail | 
					
						
							|  |  |  | 			// when the IP connectivty on node under test | 
					
						
							|  |  |  | 			// gets lost during its run. | 
					
						
							|  |  |  | 			if err, ok := err.(*DNSError); !ok || tt.error != nil && (err.Name != tt.error.(*DNSError).Name || err.Server != tt.error.(*DNSError).Server || err.IsTimeout != tt.error.(*DNSError).IsTimeout) { | 
					
						
							| 
									
										
										
										
											2015-06-09 17:30:00 +09:00
										 |  |  | 				t.Errorf("got %v; want %v", err, tt.error) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if len(addrs) == 0 { | 
					
						
							|  |  |  | 			t.Errorf("no records for %s", tt.name) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if !tt.a && !tt.aaaa && len(addrs) > 0 { | 
					
						
							|  |  |  | 			t.Errorf("unexpected %v for %s", addrs, tt.name) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		for _, addr := range addrs { | 
					
						
							|  |  |  | 			if !tt.a && addr.IP.To4() != nil { | 
					
						
							|  |  |  | 				t.Errorf("got %v; must not be IPv4 address", addr) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if !tt.aaaa && addr.IP.To16() != nil && addr.IP.To4() == nil { | 
					
						
							|  |  |  | 				t.Errorf("got %v; must not be IPv6 address", addr) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-30 13:08:46 +08:00
										 |  |  | // Test that goLookupIPOrder falls back to the host file when no DNS servers are available. | 
					
						
							|  |  |  | func TestGoLookupIPOrderFallbackToFile(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-04-14 12:17:44 +09:00
										 |  |  | 	testenv.MustHaveExternalNetwork(t) | 
					
						
							| 
									
										
										
										
											2015-11-30 13:08:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Add a config that simulates no dns servers being available. | 
					
						
							|  |  |  | 	conf, err := newResolvConfTest() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := conf.writeAndUpdate([]string{}); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Redirect host file lookups. | 
					
						
							|  |  |  | 	defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath) | 
					
						
							|  |  |  | 	testHookHostsPath = "testdata/hosts" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, order := range []hostLookupOrder{hostLookupFilesDNS, hostLookupDNSFiles} { | 
					
						
							|  |  |  | 		name := fmt.Sprintf("order %v", order) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-24 11:55:20 +01:00
										 |  |  | 		// First ensure that we get an error when contacting a non-existent host. | 
					
						
							| 
									
										
										
										
											2016-04-14 17:47:25 -07:00
										 |  |  | 		_, err := goLookupIPOrder(context.Background(), "notarealhost", order) | 
					
						
							| 
									
										
										
										
											2015-11-30 13:08:46 +08:00
										 |  |  | 		if err == nil { | 
					
						
							|  |  |  | 			t.Errorf("%s: expected error while looking up name not in hosts file", name) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Now check that we get an address when the name appears in the hosts file. | 
					
						
							| 
									
										
										
										
											2016-04-14 17:47:25 -07:00
										 |  |  | 		addrs, err := goLookupIPOrder(context.Background(), "thor", order) // entry is in "testdata/hosts" | 
					
						
							| 
									
										
										
										
											2015-11-30 13:08:46 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Errorf("%s: expected to successfully lookup host entry", name) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-12-02 11:02:04 +08:00
										 |  |  | 		if len(addrs) != 1 { | 
					
						
							|  |  |  | 			t.Errorf("%s: expected exactly one result, but got %v", name, addrs) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if got, want := addrs[0].String(), "127.1.1.1"; got != want { | 
					
						
							| 
									
										
										
										
											2015-11-30 13:08:46 +08:00
										 |  |  | 			t.Errorf("%s: address doesn't match expectation. got %v, want %v", name, got, want) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer conf.teardown() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-19 15:24:42 -04:00
										 |  |  | // Issue 12712. | 
					
						
							|  |  |  | // When using search domains, return the error encountered | 
					
						
							|  |  |  | // querying the original name instead of an error encountered | 
					
						
							|  |  |  | // querying a generated name. | 
					
						
							|  |  |  | func TestErrorForOriginalNameWhenSearching(t *testing.T) { | 
					
						
							|  |  |  | 	const fqdn = "doesnotexist.domain" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	origTestHookDNSDialer := testHookDNSDialer | 
					
						
							|  |  |  | 	defer func() { testHookDNSDialer = origTestHookDNSDialer }() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	conf, err := newResolvConfTest() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer conf.teardown() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := conf.writeAndUpdate([]string{"search servfail"}); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	d := &fakeDNSConn{} | 
					
						
							|  |  |  | 	testHookDNSDialer = func(time.Duration) dnsDialer { return d } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	d.rh = func(q *dnsMsg) (*dnsMsg, error) { | 
					
						
							|  |  |  | 		r := &dnsMsg{ | 
					
						
							|  |  |  | 			dnsMsgHdr: dnsMsgHdr{ | 
					
						
							|  |  |  | 				id: q.id, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		switch q.question[0].Name { | 
					
						
							|  |  |  | 		case fqdn + ".servfail.": | 
					
						
							|  |  |  | 			r.rcode = dnsRcodeServerFailure | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			r.rcode = dnsRcodeNameError | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return r, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-14 17:47:25 -07:00
										 |  |  | 	_, err = goLookupIP(context.Background(), fqdn) | 
					
						
							| 
									
										
										
										
											2015-11-19 15:24:42 -04:00
										 |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Fatal("expected an error") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	want := &DNSError{Name: fqdn, Err: errNoSuchHost.Error()} | 
					
						
							|  |  |  | 	if err, ok := err.(*DNSError); !ok || err.Name != want.Name || err.Err != want.Err { | 
					
						
							|  |  |  | 		t.Errorf("got %v; want %v", err, want) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-30 13:12:28 +09:00
										 |  |  | func BenchmarkGoLookupIP(b *testing.B) { | 
					
						
							| 
									
										
										
										
											2015-05-14 09:25:24 +09:00
										 |  |  | 	testHookUninstaller.Do(uninstallTestHooks) | 
					
						
							| 
									
										
										
										
											2016-04-14 17:47:25 -07:00
										 |  |  | 	ctx := context.Background() | 
					
						
							| 
									
										
											  
											
												net: add socket system call hooks for testing
This change adds socket system call hooks to existing test cases for
simulating a bit complicated network conditions to help making timeout
and dual IP stack test cases work more properly in followup changes.
Also test cases print debugging information in non-short mode like the
following:
Leaked goroutines:
net.TestWriteTimeout.func2(0xc20802a5a0, 0xc20801d000, 0x1000, 0x1000, 0xc2081d2ae0)
	/go/src/net/timeout_test.go:170 +0x98
created by net.TestWriteTimeout
	/go/src/net/timeout_test.go:173 +0x745
net.runDatagramPacketConnServer(0xc2080730e0, 0x2bd270, 0x3, 0x2c1770, 0xb, 0xc2081d2ba0, 0xc2081d2c00)
	/go/src/net/server_test.go:398 +0x667
created by net.TestTimeoutUDP
	/go/src/net/timeout_test.go:247 +0xc9
	(snip)
Leaked sockets:
3: {Cookie:615726511685632 Err:<nil> SocketErr:0}
5: {Cookie:7934075906097152 Err:<nil> SocketErr:0}
Socket statistical information:
{Family:1 Type:805306370 Protocol:0 Opened:17 Accepted:0 Connected:5 Closed:17}
{Family:2 Type:805306369 Protocol:0 Opened:450 Accepted:234 Connected:279 Closed:636}
{Family:1 Type:805306369 Protocol:0 Opened:11 Accepted:5 Connected:5 Closed:16}
{Family:28 Type:805306369 Protocol:0 Opened:95 Accepted:22 Connected:16 Closed:116}
{Family:2 Type:805306370 Protocol:0 Opened:84 Accepted:0 Connected:34 Closed:83}
{Family:28 Type:805306370 Protocol:0 Opened:52 Accepted:0 Connected:4 Closed:52}
Change-Id: I0e84be59a0699bc31245c78e2249423459b8cdda
Reviewed-on: https://go-review.googlesource.com/6390
Reviewed-by: Ian Lance Taylor <iant@golang.org>
											
										 
											2015-03-01 12:27:01 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-30 13:12:28 +09:00
										 |  |  | 	for i := 0; i < b.N; i++ { | 
					
						
							| 
									
										
										
										
											2016-04-14 17:47:25 -07:00
										 |  |  | 		goLookupIP(ctx, "www.example.com") | 
					
						
							| 
									
										
										
										
											2014-08-30 13:12:28 +09:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-30 07:50:50 +09:00
										 |  |  | func BenchmarkGoLookupIPNoSuchHost(b *testing.B) { | 
					
						
							| 
									
										
										
										
											2015-05-14 09:25:24 +09:00
										 |  |  | 	testHookUninstaller.Do(uninstallTestHooks) | 
					
						
							| 
									
										
										
										
											2016-04-14 17:47:25 -07:00
										 |  |  | 	ctx := context.Background() | 
					
						
							| 
									
										
											  
											
												net: add socket system call hooks for testing
This change adds socket system call hooks to existing test cases for
simulating a bit complicated network conditions to help making timeout
and dual IP stack test cases work more properly in followup changes.
Also test cases print debugging information in non-short mode like the
following:
Leaked goroutines:
net.TestWriteTimeout.func2(0xc20802a5a0, 0xc20801d000, 0x1000, 0x1000, 0xc2081d2ae0)
	/go/src/net/timeout_test.go:170 +0x98
created by net.TestWriteTimeout
	/go/src/net/timeout_test.go:173 +0x745
net.runDatagramPacketConnServer(0xc2080730e0, 0x2bd270, 0x3, 0x2c1770, 0xb, 0xc2081d2ba0, 0xc2081d2c00)
	/go/src/net/server_test.go:398 +0x667
created by net.TestTimeoutUDP
	/go/src/net/timeout_test.go:247 +0xc9
	(snip)
Leaked sockets:
3: {Cookie:615726511685632 Err:<nil> SocketErr:0}
5: {Cookie:7934075906097152 Err:<nil> SocketErr:0}
Socket statistical information:
{Family:1 Type:805306370 Protocol:0 Opened:17 Accepted:0 Connected:5 Closed:17}
{Family:2 Type:805306369 Protocol:0 Opened:450 Accepted:234 Connected:279 Closed:636}
{Family:1 Type:805306369 Protocol:0 Opened:11 Accepted:5 Connected:5 Closed:16}
{Family:28 Type:805306369 Protocol:0 Opened:95 Accepted:22 Connected:16 Closed:116}
{Family:2 Type:805306370 Protocol:0 Opened:84 Accepted:0 Connected:34 Closed:83}
{Family:28 Type:805306370 Protocol:0 Opened:52 Accepted:0 Connected:4 Closed:52}
Change-Id: I0e84be59a0699bc31245c78e2249423459b8cdda
Reviewed-on: https://go-review.googlesource.com/6390
Reviewed-by: Ian Lance Taylor <iant@golang.org>
											
										 
											2015-03-01 12:27:01 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-30 07:50:50 +09:00
										 |  |  | 	for i := 0; i < b.N; i++ { | 
					
						
							| 
									
										
										
										
											2016-04-14 17:47:25 -07:00
										 |  |  | 		goLookupIP(ctx, "some.nonexistent") | 
					
						
							| 
									
										
										
										
											2014-08-30 07:50:50 +09:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-08-30 13:12:28 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | func BenchmarkGoLookupIPWithBrokenNameServer(b *testing.B) { | 
					
						
							| 
									
										
										
										
											2015-05-14 09:25:24 +09:00
										 |  |  | 	testHookUninstaller.Do(uninstallTestHooks) | 
					
						
							| 
									
										
											  
											
												net: add socket system call hooks for testing
This change adds socket system call hooks to existing test cases for
simulating a bit complicated network conditions to help making timeout
and dual IP stack test cases work more properly in followup changes.
Also test cases print debugging information in non-short mode like the
following:
Leaked goroutines:
net.TestWriteTimeout.func2(0xc20802a5a0, 0xc20801d000, 0x1000, 0x1000, 0xc2081d2ae0)
	/go/src/net/timeout_test.go:170 +0x98
created by net.TestWriteTimeout
	/go/src/net/timeout_test.go:173 +0x745
net.runDatagramPacketConnServer(0xc2080730e0, 0x2bd270, 0x3, 0x2c1770, 0xb, 0xc2081d2ba0, 0xc2081d2c00)
	/go/src/net/server_test.go:398 +0x667
created by net.TestTimeoutUDP
	/go/src/net/timeout_test.go:247 +0xc9
	(snip)
Leaked sockets:
3: {Cookie:615726511685632 Err:<nil> SocketErr:0}
5: {Cookie:7934075906097152 Err:<nil> SocketErr:0}
Socket statistical information:
{Family:1 Type:805306370 Protocol:0 Opened:17 Accepted:0 Connected:5 Closed:17}
{Family:2 Type:805306369 Protocol:0 Opened:450 Accepted:234 Connected:279 Closed:636}
{Family:1 Type:805306369 Protocol:0 Opened:11 Accepted:5 Connected:5 Closed:16}
{Family:28 Type:805306369 Protocol:0 Opened:95 Accepted:22 Connected:16 Closed:116}
{Family:2 Type:805306370 Protocol:0 Opened:84 Accepted:0 Connected:34 Closed:83}
{Family:28 Type:805306370 Protocol:0 Opened:52 Accepted:0 Connected:4 Closed:52}
Change-Id: I0e84be59a0699bc31245c78e2249423459b8cdda
Reviewed-on: https://go-review.googlesource.com/6390
Reviewed-by: Ian Lance Taylor <iant@golang.org>
											
										 
											2015-03-01 12:27:01 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 	conf, err := newResolvConfTest() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		b.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer conf.teardown() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lines := []string{ | 
					
						
							|  |  |  | 		"nameserver 203.0.113.254", // use TEST-NET-3 block, see RFC 5737 | 
					
						
							|  |  |  | 		"nameserver 8.8.8.8", | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := conf.writeAndUpdate(lines); err != nil { | 
					
						
							|  |  |  | 		b.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-04-14 17:47:25 -07:00
										 |  |  | 	ctx := context.Background() | 
					
						
							| 
									
										
										
										
											2015-06-11 12:46:01 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-30 13:12:28 +09:00
										 |  |  | 	for i := 0; i < b.N; i++ { | 
					
						
							| 
									
										
										
										
											2016-04-14 17:47:25 -07:00
										 |  |  | 		goLookupIP(ctx, "www.example.com") | 
					
						
							| 
									
										
										
										
											2014-08-30 13:12:28 +09:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-11-19 15:24:42 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | type fakeDNSConn struct { | 
					
						
							|  |  |  | 	// last query | 
					
						
							| 
									
										
										
										
											2015-12-17 16:50:03 +00:00
										 |  |  | 	qmu sync.Mutex // guards q | 
					
						
							|  |  |  | 	q   *dnsMsg | 
					
						
							| 
									
										
										
										
											2015-11-19 15:24:42 -04:00
										 |  |  | 	// reply handler | 
					
						
							|  |  |  | 	rh func(*dnsMsg) (*dnsMsg, error) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (f *fakeDNSConn) dialDNS(n, s string) (dnsConn, error) { | 
					
						
							|  |  |  | 	return f, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (f *fakeDNSConn) Close() error { | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (f *fakeDNSConn) SetDeadline(time.Time) error { | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (f *fakeDNSConn) writeDNSQuery(q *dnsMsg) error { | 
					
						
							| 
									
										
										
										
											2015-12-17 16:50:03 +00:00
										 |  |  | 	f.qmu.Lock() | 
					
						
							|  |  |  | 	defer f.qmu.Unlock() | 
					
						
							| 
									
										
										
										
											2015-11-19 15:24:42 -04:00
										 |  |  | 	f.q = q | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (f *fakeDNSConn) readDNSResponse() (*dnsMsg, error) { | 
					
						
							| 
									
										
										
										
											2015-12-17 16:50:03 +00:00
										 |  |  | 	f.qmu.Lock() | 
					
						
							|  |  |  | 	q := f.q | 
					
						
							|  |  |  | 	f.qmu.Unlock() | 
					
						
							|  |  |  | 	return f.rh(q) | 
					
						
							| 
									
										
										
										
											2015-11-19 15:24:42 -04:00
										 |  |  | } |