1 // Copyright 2009 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.
23 func lookupLocalhost(ctx context
.Context
, fn
func(context
.Context
, string) ([]IPAddr
, error
), host
string) ([]IPAddr
, error
) {
27 {IP
: IPv4(127, 0, 0, 1)},
35 // The Lookup APIs use various sources such as local database, DNS or
36 // mDNS, and may use platform-dependent DNS stub resolver if possible.
37 // The APIs accept any of forms for a query; host name in various
38 // encodings, UTF-8 encoded net name, domain name, FQDN or absolute
39 // FQDN, but the result would be one of the forms and it depends on
42 var lookupGoogleSRVTests
= []struct {
43 service
, proto
, name
string
47 "xmpp-server", "tcp", "google.com",
48 "google.com.", "google.com.",
51 "xmpp-server", "tcp", "google.com.",
52 "google.com.", "google.com.",
55 // non-standard back door
57 "", "", "_xmpp-server._tcp.google.com",
58 "google.com.", "google.com.",
61 "", "", "_xmpp-server._tcp.google.com.",
62 "google.com.", "google.com.",
66 var backoffDuration
= [...]time
.Duration
{time
.Second
, 5 * time
.Second
, 30 * time
.Second
}
68 func TestLookupGoogleSRV(t
*testing
.T
) {
70 mustHaveExternalNetwork(t
)
72 if runtime
.GOOS
== "darwin" && (runtime
.GOARCH
== "arm" || runtime
.GOARCH
== "arm64") {
73 t
.Skip("no resolv.conf on iOS")
76 if !supportsIPv4() ||
!*testIPv4
{
77 t
.Skip("IPv4 is required")
81 for i
:= 0; i
< len(lookupGoogleSRVTests
); i
++ {
82 tt
:= lookupGoogleSRVTests
[i
]
83 cname
, srvs
, err
:= LookupSRV(tt
.service
, tt
.proto
, tt
.name
)
85 testenv
.SkipFlakyNet(t
)
86 if attempts
< len(backoffDuration
) {
87 dur
:= backoffDuration
[attempts
]
88 t
.Logf("backoff %v after failure %v\n", dur
, err
)
97 t
.Error("got no record")
99 if !strings
.HasSuffix(cname
, tt
.cname
) {
100 t
.Errorf("got %s; want %s", cname
, tt
.cname
)
102 for _
, srv
:= range srvs
{
103 if !strings
.HasSuffix(srv
.Target
, tt
.target
) {
104 t
.Errorf("got %v; want a record containing %s", srv
, tt
.target
)
110 var lookupGmailMXTests
= []struct {
113 {"gmail.com", "google.com."},
114 {"gmail.com.", "google.com."},
117 func TestLookupGmailMX(t
*testing
.T
) {
119 mustHaveExternalNetwork(t
)
121 if runtime
.GOOS
== "darwin" && (runtime
.GOARCH
== "arm" || runtime
.GOARCH
== "arm64") {
122 t
.Skip("no resolv.conf on iOS")
125 if !supportsIPv4() ||
!*testIPv4
{
126 t
.Skip("IPv4 is required")
130 for i
:= 0; i
< len(lookupGmailMXTests
); i
++ {
131 tt
:= lookupGmailMXTests
[i
]
132 mxs
, err
:= LookupMX(tt
.name
)
134 testenv
.SkipFlakyNet(t
)
135 if attempts
< len(backoffDuration
) {
136 dur
:= backoffDuration
[attempts
]
137 t
.Logf("backoff %v after failure %v\n", dur
, err
)
146 t
.Error("got no record")
148 for _
, mx
:= range mxs
{
149 if !strings
.HasSuffix(mx
.Host
, tt
.host
) {
150 t
.Errorf("got %v; want a record containing %s", mx
, tt
.host
)
156 var lookupGmailNSTests
= []struct {
159 {"gmail.com", "google.com."},
160 {"gmail.com.", "google.com."},
163 func TestLookupGmailNS(t
*testing
.T
) {
165 mustHaveExternalNetwork(t
)
167 if runtime
.GOOS
== "darwin" && (runtime
.GOARCH
== "arm" || runtime
.GOARCH
== "arm64") {
168 t
.Skip("no resolv.conf on iOS")
171 if !supportsIPv4() ||
!*testIPv4
{
172 t
.Skip("IPv4 is required")
176 for i
:= 0; i
< len(lookupGmailNSTests
); i
++ {
177 tt
:= lookupGmailNSTests
[i
]
178 nss
, err
:= LookupNS(tt
.name
)
180 testenv
.SkipFlakyNet(t
)
181 if attempts
< len(backoffDuration
) {
182 dur
:= backoffDuration
[attempts
]
183 t
.Logf("backoff %v after failure %v\n", dur
, err
)
192 t
.Error("got no record")
194 for _
, ns
:= range nss
{
195 if !strings
.HasSuffix(ns
.Host
, tt
.host
) {
196 t
.Errorf("got %v; want a record containing %s", ns
, tt
.host
)
202 var lookupGmailTXTTests
= []struct {
203 name
, txt
, host
string
205 {"gmail.com", "spf", "google.com"},
206 {"gmail.com.", "spf", "google.com"},
209 func TestLookupGmailTXT(t
*testing
.T
) {
211 mustHaveExternalNetwork(t
)
213 if runtime
.GOOS
== "darwin" && (runtime
.GOARCH
== "arm" || runtime
.GOARCH
== "arm64") {
214 t
.Skip("no resolv.conf on iOS")
217 if !supportsIPv4() ||
!*testIPv4
{
218 t
.Skip("IPv4 is required")
222 for i
:= 0; i
< len(lookupGmailTXTTests
); i
++ {
223 tt
:= lookupGmailTXTTests
[i
]
224 txts
, err
:= LookupTXT(tt
.name
)
226 testenv
.SkipFlakyNet(t
)
227 if attempts
< len(backoffDuration
) {
228 dur
:= backoffDuration
[attempts
]
229 t
.Logf("backoff %v after failure %v\n", dur
, err
)
238 t
.Error("got no record")
240 for _
, txt
:= range txts
{
241 if !strings
.Contains(txt
, tt
.txt
) ||
(!strings
.HasSuffix(txt
, tt
.host
) && !strings
.HasSuffix(txt
, tt
.host
+".")) {
242 t
.Errorf("got %s; want a record containing %s, %s", txt
, tt
.txt
, tt
.host
)
248 var lookupGooglePublicDNSAddrTests
= []struct {
251 {"8.8.8.8", ".google.com."},
252 {"8.8.4.4", ".google.com."},
254 {"2001:4860:4860::8888", ".google.com."},
255 {"2001:4860:4860::8844", ".google.com."},
258 func TestLookupGooglePublicDNSAddr(t
*testing
.T
) {
259 mustHaveExternalNetwork(t
)
261 if !supportsIPv4() ||
!supportsIPv6() ||
!*testIPv4 ||
!*testIPv6
{
262 t
.Skip("both IPv4 and IPv6 are required")
265 defer dnsWaitGroup
.Wait()
267 for _
, tt
:= range lookupGooglePublicDNSAddrTests
{
268 names
, err
:= LookupAddr(tt
.addr
)
273 t
.Error("got no record")
275 for _
, name
:= range names
{
276 if !strings
.HasSuffix(name
, tt
.name
) {
277 t
.Errorf("got %s; want a record containing %s", name
, tt
.name
)
283 func TestLookupIPv6LinkLocalAddr(t
*testing
.T
) {
284 if !supportsIPv6() ||
!*testIPv6
{
285 t
.Skip("IPv6 is required")
288 defer dnsWaitGroup
.Wait()
290 addrs
, err
:= LookupHost("localhost")
295 for _
, addr
:= range addrs
{
296 if addr
== "fe80::1%lo0" {
302 t
.Skipf("not supported on %s", runtime
.GOOS
)
304 if _
, err
:= LookupAddr("fe80::1%lo0"); err
!= nil {
309 func TestLookupIPv6LinkLocalAddrWithZone(t
*testing
.T
) {
310 if !supportsIPv6() ||
!*testIPv6
{
311 t
.Skip("IPv6 is required")
314 ipaddrs
, err
:= DefaultResolver
.LookupIPAddr(context
.Background(), "fe80::1%lo0")
318 for _
, addr
:= range ipaddrs
{
319 if e
, a
:= "lo0", addr
.Zone
; e
!= a
{
320 t
.Errorf("wrong zone: want %q, got %q", e
, a
)
324 addrs
, err
:= DefaultResolver
.LookupHost(context
.Background(), "fe80::1%lo0")
328 for _
, addr
:= range addrs
{
329 if e
, a
:= "fe80::1%lo0", addr
; e
!= a
{
330 t
.Errorf("wrong host: want %q got %q", e
, a
)
335 var lookupCNAMETests
= []struct {
338 {"www.iana.org", "icann.org."},
339 {"www.iana.org.", "icann.org."},
340 {"www.google.com", "google.com."},
343 func TestLookupCNAME(t
*testing
.T
) {
344 mustHaveExternalNetwork(t
)
346 if !supportsIPv4() ||
!*testIPv4
{
347 t
.Skip("IPv4 is required")
350 defer dnsWaitGroup
.Wait()
353 for i
:= 0; i
< len(lookupCNAMETests
); i
++ {
354 tt
:= lookupCNAMETests
[i
]
355 cname
, err
:= LookupCNAME(tt
.name
)
357 testenv
.SkipFlakyNet(t
)
358 if attempts
< len(backoffDuration
) {
359 dur
:= backoffDuration
[attempts
]
360 t
.Logf("backoff %v after failure %v\n", dur
, err
)
368 if !strings
.HasSuffix(cname
, tt
.cname
) {
369 t
.Errorf("got %s; want a record containing %s", cname
, tt
.cname
)
374 var lookupGoogleHostTests
= []struct {
381 func TestLookupGoogleHost(t
*testing
.T
) {
382 mustHaveExternalNetwork(t
)
384 if !supportsIPv4() ||
!*testIPv4
{
385 t
.Skip("IPv4 is required")
388 defer dnsWaitGroup
.Wait()
390 for _
, tt
:= range lookupGoogleHostTests
{
391 addrs
, err
:= LookupHost(tt
.name
)
396 t
.Error("got no record")
398 for _
, addr
:= range addrs
{
399 if ParseIP(addr
) == nil {
400 t
.Errorf("got %q; want a literal IP address", addr
)
406 func TestLookupLongTXT(t
*testing
.T
) {
407 testenv
.SkipFlaky(t
, 22857)
408 mustHaveExternalNetwork(t
)
410 defer dnsWaitGroup
.Wait()
412 txts
, err
:= LookupTXT("golang.rsc.io")
418 strings
.Repeat("abcdefghijklmnopqrstuvwxyABCDEFGHJIKLMNOPQRSTUVWXY", 10),
421 if !reflect
.DeepEqual(txts
, want
) {
422 t
.Fatalf("LookupTXT golang.rsc.io incorrect\nhave %q\nwant %q", txts
, want
)
426 var lookupGoogleIPTests
= []struct {
433 func TestLookupGoogleIP(t
*testing
.T
) {
434 mustHaveExternalNetwork(t
)
436 if !supportsIPv4() ||
!*testIPv4
{
437 t
.Skip("IPv4 is required")
440 defer dnsWaitGroup
.Wait()
442 for _
, tt
:= range lookupGoogleIPTests
{
443 ips
, err
:= LookupIP(tt
.name
)
448 t
.Error("got no record")
450 for _
, ip
:= range ips
{
451 if ip
.To4() == nil && ip
.To16() == nil {
452 t
.Errorf("got %v; want an IP address", ip
)
458 var revAddrTests
= []struct {
463 {"1.2.3.4", "4.3.2.1.in-addr.arpa.", ""},
464 {"245.110.36.114", "114.36.110.245.in-addr.arpa.", ""},
465 {"::ffff:12.34.56.78", "78.56.34.12.in-addr.arpa.", ""},
466 {"::1", "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", ""},
467 {"1::", "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.ip6.arpa.", ""},
468 {"1234:567::89a:bcde", "e.d.c.b.a.9.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.7.6.5.0.4.3.2.1.ip6.arpa.", ""},
469 {"1234:567:fefe:bcbc:adad:9e4a:89a:bcde", "e.d.c.b.a.9.8.0.a.4.e.9.d.a.d.a.c.b.c.b.e.f.e.f.7.6.5.0.4.3.2.1.ip6.arpa.", ""},
470 {"1.2.3", "", "unrecognized address"},
471 {"1.2.3.4.5", "", "unrecognized address"},
472 {"1234:567:bcbca::89a:bcde", "", "unrecognized address"},
473 {"1234:567::bcbc:adad::89a:bcde", "", "unrecognized address"},
476 func TestReverseAddress(t
*testing
.T
) {
477 defer dnsWaitGroup
.Wait()
478 for i
, tt
:= range revAddrTests
{
479 a
, err
:= reverseaddr(tt
.Addr
)
480 if len(tt
.ErrPrefix
) > 0 && err
== nil {
481 t
.Errorf("#%d: expected %q, got <nil> (error)", i
, tt
.ErrPrefix
)
484 if len(tt
.ErrPrefix
) == 0 && err
!= nil {
485 t
.Errorf("#%d: expected <nil>, got %q (error)", i
, err
)
487 if err
!= nil && err
.(*DNSError
).Err
!= tt
.ErrPrefix
{
488 t
.Errorf("#%d: expected %q, got %q (mismatched error)", i
, tt
.ErrPrefix
, err
.(*DNSError
).Err
)
491 t
.Errorf("#%d: expected %q, got %q (reverse address)", i
, tt
.Reverse
, a
)
496 func TestDNSFlood(t
*testing
.T
) {
498 t
.Skip("test disabled; use -dnsflood to enable")
501 defer dnsWaitGroup
.Wait()
504 if runtime
.GOOS
== "darwin" {
505 // On Darwin this test consumes kernel threads much
506 // than other platforms for some reason.
507 // When we monitor the number of allocated Ms by
508 // observing on runtime.newm calls, we can see that it
509 // easily reaches the per process ceiling
510 // kern.num_threads when CGO_ENABLED=1 and
511 // GODEBUG=netdns=go.
515 const timeout
= 3 * time
.Second
516 ctxHalfTimeout
, cancel
:= context
.WithTimeout(context
.Background(), timeout
/2)
518 ctxTimeout
, cancel
:= context
.WithTimeout(context
.Background(), timeout
)
521 c
:= make(chan error
, 2*N
)
522 for i
:= 0; i
< N
; i
++ {
523 name
:= fmt
.Sprintf("%d.net-test.golang.org", i
)
525 _
, err
:= DefaultResolver
.LookupIPAddr(ctxHalfTimeout
, name
)
529 _
, err
:= DefaultResolver
.LookupIPAddr(ctxTimeout
, name
)
534 succeeded
, failed
int
535 timeout
, temporary
, other
int
538 deadline
:= time
.After(timeout
+ time
.Second
)
539 for i
:= 0; i
< 2*N
; i
++ {
542 t
.Fatal("deadline exceeded")
544 switch err
:= err
.(type) {
555 if !err
.Timeout() && !err
.Temporary() {
565 // A high volume of DNS queries for sub-domain of golang.org
566 // would be coordinated by authoritative or recursive server,
567 // or stub resolver which implements query-response rate
568 // limitation, so we can expect some query successes and more
569 // failures including timeout, temporary and other here.
570 // As a rule, unknown must not be shown but it might possibly
571 // happen due to issue 4856 for now.
572 t
.Logf("%v succeeded, %v failed (%v timeout, %v temporary, %v other, %v unknown)", qstats
.succeeded
, qstats
.failed
, qstats
.timeout
, qstats
.temporary
, qstats
.other
, qstats
.unknown
)
575 func TestLookupDotsWithLocalSource(t
*testing
.T
) {
576 if !supportsIPv4() ||
!*testIPv4
{
577 t
.Skip("IPv4 is required")
580 mustHaveExternalNetwork(t
)
582 defer dnsWaitGroup
.Wait()
584 for i
, fn
:= range []func() func(){forceGoDNS
, forceCgoDNS
} {
589 names
, err
:= LookupAddr("127.0.0.1")
592 t
.Logf("#%d: %v", i
, err
)
600 for i
, name
:= range names
{
601 if strings
.Index(name
, ".") == len(name
)-1 { // "localhost" not "localhost."
602 for j
:= range names
{
606 if names
[j
] == name
[:len(name
)-1] {
607 // It's OK if we find the name without the dot,
608 // as some systems say 127.0.0.1 localhost localhost.
612 t
.Errorf("%s: got %s; want %s", mode
, name
, name
[:len(name
)-1])
613 } else if strings
.Contains(name
, ".") && !strings
.HasSuffix(name
, ".") { // "localhost.localdomain." not "localhost.localdomain"
614 t
.Errorf("%s: got %s; want name ending with trailing dot", mode
, name
)
620 func TestLookupDotsWithRemoteSource(t
*testing
.T
) {
621 mustHaveExternalNetwork(t
)
623 if !supportsIPv4() ||
!*testIPv4
{
624 t
.Skip("IPv4 is required")
627 if runtime
.GOOS
== "darwin" && (runtime
.GOARCH
== "arm" || runtime
.GOARCH
== "arm64") {
628 t
.Skip("no resolv.conf on iOS")
631 defer dnsWaitGroup
.Wait()
633 if fixup
:= forceGoDNS(); fixup
!= nil {
637 if fixup
:= forceCgoDNS(); fixup
!= nil {
643 func testDots(t
*testing
.T
, mode
string) {
644 names
, err
:= LookupAddr("8.8.8.8") // Google dns server
646 testenv
.SkipFlakyNet(t
)
647 t
.Errorf("LookupAddr(8.8.8.8): %v (mode=%v)", err
, mode
)
649 for _
, name
:= range names
{
650 if !strings
.HasSuffix(name
, ".google.com.") {
651 t
.Errorf("LookupAddr(8.8.8.8) = %v, want names ending in .google.com. with trailing dot (mode=%v)", names
, mode
)
657 cname
, err
:= LookupCNAME("www.mit.edu")
659 testenv
.SkipFlakyNet(t
)
660 t
.Errorf("LookupCNAME(www.mit.edu, mode=%v): %v", mode
, err
)
661 } else if !strings
.HasSuffix(cname
, ".") {
662 t
.Errorf("LookupCNAME(www.mit.edu) = %v, want cname ending in . with trailing dot (mode=%v)", cname
, mode
)
665 mxs
, err
:= LookupMX("google.com")
667 testenv
.SkipFlakyNet(t
)
668 t
.Errorf("LookupMX(google.com): %v (mode=%v)", err
, mode
)
670 for _
, mx
:= range mxs
{
671 if !strings
.HasSuffix(mx
.Host
, ".google.com.") {
672 t
.Errorf("LookupMX(google.com) = %v, want names ending in .google.com. with trailing dot (mode=%v)", mxString(mxs
), mode
)
678 nss
, err
:= LookupNS("google.com")
680 testenv
.SkipFlakyNet(t
)
681 t
.Errorf("LookupNS(google.com): %v (mode=%v)", err
, mode
)
683 for _
, ns
:= range nss
{
684 if !strings
.HasSuffix(ns
.Host
, ".google.com.") {
685 t
.Errorf("LookupNS(google.com) = %v, want names ending in .google.com. with trailing dot (mode=%v)", nsString(nss
), mode
)
691 cname
, srvs
, err
:= LookupSRV("xmpp-server", "tcp", "google.com")
693 testenv
.SkipFlakyNet(t
)
694 t
.Errorf("LookupSRV(xmpp-server, tcp, google.com): %v (mode=%v)", err
, mode
)
696 if !strings
.HasSuffix(cname
, ".google.com.") {
697 t
.Errorf("LookupSRV(xmpp-server, tcp, google.com) returned cname=%v, want name ending in .google.com. with trailing dot (mode=%v)", cname
, mode
)
699 for _
, srv
:= range srvs
{
700 if !strings
.HasSuffix(srv
.Target
, ".google.com.") {
701 t
.Errorf("LookupSRV(xmpp-server, tcp, google.com) returned addrs=%v, want names ending in .google.com. with trailing dot (mode=%v)", srvString(srvs
), mode
)
708 func mxString(mxs
[]*MX
) string {
711 fmt
.Fprintf(&buf
, "[")
712 for _
, mx
:= range mxs
{
713 fmt
.Fprintf(&buf
, "%s%s:%d", sep
, mx
.Host
, mx
.Pref
)
716 fmt
.Fprintf(&buf
, "]")
720 func nsString(nss
[]*NS
) string {
723 fmt
.Fprintf(&buf
, "[")
724 for _
, ns
:= range nss
{
725 fmt
.Fprintf(&buf
, "%s%s", sep
, ns
.Host
)
728 fmt
.Fprintf(&buf
, "]")
732 func srvString(srvs
[]*SRV
) string {
735 fmt
.Fprintf(&buf
, "[")
736 for _
, srv
:= range srvs
{
737 fmt
.Fprintf(&buf
, "%s%s:%d:%d:%d", sep
, srv
.Target
, srv
.Port
, srv
.Priority
, srv
.Weight
)
740 fmt
.Fprintf(&buf
, "]")
744 func TestLookupPort(t
*testing
.T
) {
745 // See https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml
747 // Please be careful about adding new test cases.
748 // There are platforms which have incomplete mappings for
749 // restricted resource access and security reasons.
757 {"tcp", "0", 0, true},
758 {"udp", "0", 0, true},
759 {"udp", "domain", 53, true},
761 {"--badnet--", "zzz", 0, false},
762 {"tcp", "--badport--", 0, false},
763 {"tcp", "-1", 0, false},
764 {"tcp", "65536", 0, false},
765 {"udp", "-1", 0, false},
766 {"udp", "65536", 0, false},
767 {"tcp", "123456789", 0, false},
769 // Issue 13610: LookupPort("tcp", "")
770 {"tcp", "", 0, true},
771 {"tcp4", "", 0, true},
772 {"tcp6", "", 0, true},
773 {"udp", "", 0, true},
774 {"udp4", "", 0, true},
775 {"udp6", "", 0, true},
778 switch runtime
.GOOS
{
781 t
.Skipf("not supported on %s without cgo; see golang.org/issues/14576", runtime
.GOOS
)
784 tests
= append(tests
, test
{"tcp", "http", 80, true})
787 for _
, tt
:= range tests
{
788 port
, err
:= LookupPort(tt
.network
, tt
.name
)
789 if port
!= tt
.port ||
(err
== nil) != tt
.ok
{
790 t
.Errorf("LookupPort(%q, %q) = %d, %v; want %d, error=%t", tt
.network
, tt
.name
, port
, err
, tt
.port
, !tt
.ok
)
793 if perr
:= parseLookupPortError(err
); perr
!= nil {
800 // Like TestLookupPort but with minimal tests that should always pass
801 // because the answers are baked-in to the net package.
802 func TestLookupPort_Minimal(t
*testing
.T
) {
810 {"tcp", "HTTP", 80}, // case shouldn't matter
811 {"tcp", "https", 443},
813 {"tcp", "gopher", 70},
814 {"tcp4", "http", 80},
815 {"tcp6", "http", 80},
818 for _
, tt
:= range tests
{
819 port
, err
:= LookupPort(tt
.network
, tt
.name
)
820 if port
!= tt
.port || err
!= nil {
821 t
.Errorf("LookupPort(%q, %q) = %d, %v; want %d, error=nil", tt
.network
, tt
.name
, port
, err
, tt
.port
)
826 func TestLookupProtocol_Minimal(t
*testing
.T
) {
833 {"TcP", 6}, // case shouldn't matter
840 for _
, tt
:= range tests
{
841 got
, err
:= lookupProtocol(context
.Background(), tt
.name
)
842 if got
!= tt
.want || err
!= nil {
843 t
.Errorf("LookupProtocol(%q) = %d, %v; want %d, error=nil", tt
.name
, got
, err
, tt
.want
)
849 func TestLookupNonLDH(t
*testing
.T
) {
850 if runtime
.GOOS
== "nacl" {
851 t
.Skip("skip on nacl")
854 defer dnsWaitGroup
.Wait()
856 if fixup
:= forceGoDNS(); fixup
!= nil {
860 // "LDH" stands for letters, digits, and hyphens and is the usual
861 // description of standard DNS names.
862 // This test is checking that other kinds of names are reported
863 // as not found, not reported as invalid names.
864 addrs
, err
:= LookupHost("!!!.###.bogus..domain.")
866 t
.Fatalf("lookup succeeded: %v", addrs
)
868 if !strings
.HasSuffix(err
.Error(), errNoSuchHost
.Error()) {
869 t
.Fatalf("lookup error = %v, want %v", err
, errNoSuchHost
)
873 func TestLookupContextCancel(t
*testing
.T
) {
874 mustHaveExternalNetwork(t
)
875 if runtime
.GOOS
== "nacl" {
876 t
.Skip("skip on nacl")
879 defer dnsWaitGroup
.Wait()
881 ctx
, ctxCancel
:= context
.WithCancel(context
.Background())
883 _
, err
:= DefaultResolver
.LookupIPAddr(ctx
, "google.com")
884 if err
!= errCanceled
{
885 testenv
.SkipFlakyNet(t
)
888 ctx
= context
.Background()
889 _
, err
= DefaultResolver
.LookupIPAddr(ctx
, "google.com")
891 testenv
.SkipFlakyNet(t
)
896 // Issue 24330: treat the nil *Resolver like a zero value. Verify nothing
897 // crashes if nil is used.
898 func TestNilResolverLookup(t
*testing
.T
) {
899 mustHaveExternalNetwork(t
)
900 if runtime
.GOOS
== "nacl" {
901 t
.Skip("skip on nacl")
903 var r
*Resolver
= nil
904 ctx
:= context
.Background()
906 // Don't care about the results, just that nothing panics:
907 r
.LookupAddr(ctx
, "8.8.8.8")
908 r
.LookupCNAME(ctx
, "google.com")
909 r
.LookupHost(ctx
, "google.com")
910 r
.LookupIPAddr(ctx
, "google.com")
911 r
.LookupMX(ctx
, "gmail.com")
912 r
.LookupNS(ctx
, "google.com")
913 r
.LookupPort(ctx
, "tcp", "smtp")
914 r
.LookupSRV(ctx
, "service", "proto", "name")
915 r
.LookupTXT(ctx
, "gmail.com")
918 // TestLookupHostCancel verifies that lookup works even after many
919 // canceled lookups (see golang.org/issue/24178 for details).
920 func TestLookupHostCancel(t
*testing
.T
) {
921 mustHaveExternalNetwork(t
)
922 if runtime
.GOOS
== "nacl" {
923 t
.Skip("skip on nacl")
927 google
= "www.google.com"
928 invalidDomain
= "nonexistentdomain.golang.org"
929 n
= 600 // this needs to be larger than threadLimit size
932 _
, err
:= LookupHost(google
)
937 ctx
, cancel
:= context
.WithCancel(context
.Background())
939 for i
:= 0; i
< n
; i
++ {
940 addr
, err
:= DefaultResolver
.LookupHost(ctx
, invalidDomain
)
942 t
.Fatalf("LookupHost(%q): returns %v, but should fail", invalidDomain
, addr
)
944 if !strings
.Contains(err
.Error(), "canceled") {
945 t
.Fatalf("LookupHost(%q): failed with unexpected error: %v", invalidDomain
, err
)
947 time
.Sleep(time
.Millisecond
* 1)
950 _
, err
= LookupHost(google
)
956 type lookupCustomResolver
struct {
962 func (lcr
*lookupCustomResolver
) dial() func(ctx context
.Context
, network
, address
string) (Conn
, error
) {
963 return func(ctx context
.Context
, network
, address
string) (Conn
, error
) {
967 return Dial(network
, address
)
971 // TestConcurrentPreferGoResolversDial tests that multiple resolvers with the
972 // PreferGo option used concurrently are all dialed properly.
973 func TestConcurrentPreferGoResolversDial(t
*testing
.T
) {
974 // The windows implementation of the resolver does not use the Dial
976 if runtime
.GOOS
== "windows" {
977 t
.Skip("skip on windows")
980 testenv
.MustHaveExternalNetwork(t
)
981 testenv
.SkipFlakyNet(t
)
983 defer dnsWaitGroup
.Wait()
985 resolvers
:= make([]*lookupCustomResolver
, 2)
986 for i
:= range resolvers
{
987 cs
:= lookupCustomResolver
{Resolver
: &Resolver
{PreferGo
: true}}
992 var wg sync
.WaitGroup
993 wg
.Add(len(resolvers
))
994 for i
, resolver
:= range resolvers
{
995 go func(r
*Resolver
, index
int) {
997 _
, err
:= r
.LookupIPAddr(context
.Background(), "google.com")
999 t
.Fatalf("lookup failed for resolver %d: %q", index
, err
)
1001 }(resolver
.Resolver
, i
)
1005 for i
, resolver
:= range resolvers
{
1006 if !resolver
.dialed
{
1007 t
.Errorf("custom resolver %d not dialed during lookup", i
)