1// Copyright 2011 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 !js
6
7package net
8
9import (
10	"bufio"
11	"context"
12	"internal/testenv"
13	"io"
14	"os"
15	"runtime"
16	"strings"
17	"sync"
18	"testing"
19	"time"
20)
21
22var prohibitionaryDialArgTests = []struct {
23	network string
24	address string
25}{
26	{"tcp6", "127.0.0.1"},
27	{"tcp6", "::ffff:127.0.0.1"},
28}
29
30func TestProhibitionaryDialArg(t *testing.T) {
31	testenv.MustHaveExternalNetwork(t)
32
33	switch runtime.GOOS {
34	case "plan9":
35		t.Skipf("not supported on %s", runtime.GOOS)
36	}
37	if !supportsIPv4map() {
38		t.Skip("mapping ipv4 address inside ipv6 address not supported")
39	}
40
41	ln, err := Listen("tcp", "[::]:0")
42	if err != nil {
43		t.Fatal(err)
44	}
45	defer ln.Close()
46
47	_, port, err := SplitHostPort(ln.Addr().String())
48	if err != nil {
49		t.Fatal(err)
50	}
51
52	for i, tt := range prohibitionaryDialArgTests {
53		c, err := Dial(tt.network, JoinHostPort(tt.address, port))
54		if err == nil {
55			c.Close()
56			t.Errorf("#%d: %v", i, err)
57		}
58	}
59}
60
61func TestDialLocal(t *testing.T) {
62	ln, err := newLocalListener("tcp")
63	if err != nil {
64		t.Fatal(err)
65	}
66	defer ln.Close()
67	_, port, err := SplitHostPort(ln.Addr().String())
68	if err != nil {
69		t.Fatal(err)
70	}
71	c, err := Dial("tcp", JoinHostPort("", port))
72	if err != nil {
73		t.Fatal(err)
74	}
75	c.Close()
76}
77
78func TestDialerDualStackFDLeak(t *testing.T) {
79	switch runtime.GOOS {
80	case "plan9":
81		t.Skipf("%s does not have full support of socktest", runtime.GOOS)
82	case "windows":
83		t.Skipf("not implemented a way to cancel dial racers in TCP SYN-SENT state on %s", runtime.GOOS)
84	case "openbsd":
85		testenv.SkipFlaky(t, 15157)
86	}
87	if !supportsIPv4() || !supportsIPv6() {
88		t.Skip("both IPv4 and IPv6 are required")
89	}
90
91	before := sw.Sockets()
92	origTestHookLookupIP := testHookLookupIP
93	defer func() { testHookLookupIP = origTestHookLookupIP }()
94	testHookLookupIP = lookupLocalhost
95	handler := func(dss *dualStackServer, ln Listener) {
96		for {
97			c, err := ln.Accept()
98			if err != nil {
99				return
100			}
101			c.Close()
102		}
103	}
104	dss, err := newDualStackServer()
105	if err != nil {
106		t.Fatal(err)
107	}
108	if err := dss.buildup(handler); err != nil {
109		dss.teardown()
110		t.Fatal(err)
111	}
112
113	const N = 10
114	var wg sync.WaitGroup
115	wg.Add(N)
116	d := &Dialer{DualStack: true, Timeout: 5 * time.Second}
117	for i := 0; i < N; i++ {
118		go func() {
119			defer wg.Done()
120			c, err := d.Dial("tcp", JoinHostPort("localhost", dss.port))
121			if err != nil {
122				t.Error(err)
123				return
124			}
125			c.Close()
126		}()
127	}
128	wg.Wait()
129	dss.teardown()
130	after := sw.Sockets()
131	if len(after) != len(before) {
132		t.Errorf("got %d; want %d", len(after), len(before))
133	}
134}
135
136// Define a pair of blackholed (IPv4, IPv6) addresses, for which dialTCP is
137// expected to hang until the timeout elapses. These addresses are reserved
138// for benchmarking by RFC 6890.
139const (
140	slowDst4 = "198.18.0.254"
141	slowDst6 = "2001:2::254"
142)
143
144// In some environments, the slow IPs may be explicitly unreachable, and fail
145// more quickly than expected. This test hook prevents dialTCP from returning
146// before the deadline.
147func slowDialTCP(ctx context.Context, network string, laddr, raddr *TCPAddr) (*TCPConn, error) {
148	sd := &sysDialer{network: network, address: raddr.String()}
149	c, err := sd.doDialTCP(ctx, laddr, raddr)
150	if ParseIP(slowDst4).Equal(raddr.IP) || ParseIP(slowDst6).Equal(raddr.IP) {
151		// Wait for the deadline, or indefinitely if none exists.
152		<-ctx.Done()
153	}
154	return c, err
155}
156
157func dialClosedPort(t *testing.T) (actual, expected time.Duration) {
158	// Estimate the expected time for this platform.
159	// On Windows, dialing a closed port takes roughly 1 second,
160	// but other platforms should be instantaneous.
161	if runtime.GOOS == "windows" {
162		expected = 1500 * time.Millisecond
163	} else if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
164		expected = 150 * time.Millisecond
165	} else {
166		expected = 95 * time.Millisecond
167	}
168
169	l, err := Listen("tcp", "127.0.0.1:0")
170	if err != nil {
171		t.Logf("dialClosedPort: Listen failed: %v", err)
172		return 999 * time.Hour, expected
173	}
174	addr := l.Addr().String()
175	l.Close()
176	// On OpenBSD, interference from TestTCPSelfConnect is mysteriously
177	// causing the first attempt to hang for a few seconds, so we throw
178	// away the first result and keep the second.
179	for i := 1; ; i++ {
180		startTime := time.Now()
181		c, err := Dial("tcp", addr)
182		if err == nil {
183			c.Close()
184		}
185		elapsed := time.Now().Sub(startTime)
186		if i == 2 {
187			t.Logf("dialClosedPort: measured delay %v", elapsed)
188			return elapsed, expected
189		}
190	}
191}
192
193func TestDialParallel(t *testing.T) {
194	testenv.MustHaveExternalNetwork(t)
195
196	if !supportsIPv4() || !supportsIPv6() {
197		t.Skip("both IPv4 and IPv6 are required")
198	}
199
200	closedPortDelay, expectClosedPortDelay := dialClosedPort(t)
201	if closedPortDelay > expectClosedPortDelay {
202		t.Errorf("got %v; want <= %v", closedPortDelay, expectClosedPortDelay)
203	}
204
205	const instant time.Duration = 0
206	const fallbackDelay = 200 * time.Millisecond
207
208	// Some cases will run quickly when "connection refused" is fast,
209	// or trigger the fallbackDelay on Windows. This value holds the
210	// lesser of the two delays.
211	var closedPortOrFallbackDelay time.Duration
212	if closedPortDelay < fallbackDelay {
213		closedPortOrFallbackDelay = closedPortDelay
214	} else {
215		closedPortOrFallbackDelay = fallbackDelay
216	}
217
218	origTestHookDialTCP := testHookDialTCP
219	defer func() { testHookDialTCP = origTestHookDialTCP }()
220	testHookDialTCP = slowDialTCP
221
222	nCopies := func(s string, n int) []string {
223		out := make([]string, n)
224		for i := 0; i < n; i++ {
225			out[i] = s
226		}
227		return out
228	}
229
230	var testCases = []struct {
231		primaries       []string
232		fallbacks       []string
233		teardownNetwork string
234		expectOk        bool
235		expectElapsed   time.Duration
236	}{
237		// These should just work on the first try.
238		{[]string{"127.0.0.1"}, []string{}, "", true, instant},
239		{[]string{"::1"}, []string{}, "", true, instant},
240		{[]string{"127.0.0.1", "::1"}, []string{slowDst6}, "tcp6", true, instant},
241		{[]string{"::1", "127.0.0.1"}, []string{slowDst4}, "tcp4", true, instant},
242		// Primary is slow; fallback should kick in.
243		{[]string{slowDst4}, []string{"::1"}, "", true, fallbackDelay},
244		// Skip a "connection refused" in the primary thread.
245		{[]string{"127.0.0.1", "::1"}, []string{}, "tcp4", true, closedPortDelay},
246		{[]string{"::1", "127.0.0.1"}, []string{}, "tcp6", true, closedPortDelay},
247		// Skip a "connection refused" in the fallback thread.
248		{[]string{slowDst4, slowDst6}, []string{"::1", "127.0.0.1"}, "tcp6", true, fallbackDelay + closedPortDelay},
249		// Primary refused, fallback without delay.
250		{[]string{"127.0.0.1"}, []string{"::1"}, "tcp4", true, closedPortOrFallbackDelay},
251		{[]string{"::1"}, []string{"127.0.0.1"}, "tcp6", true, closedPortOrFallbackDelay},
252		// Everything is refused.
253		{[]string{"127.0.0.1"}, []string{}, "tcp4", false, closedPortDelay},
254		// Nothing to do; fail instantly.
255		{[]string{}, []string{}, "", false, instant},
256		// Connecting to tons of addresses should not trip the deadline.
257		{nCopies("::1", 1000), []string{}, "", true, instant},
258	}
259
260	handler := func(dss *dualStackServer, ln Listener) {
261		for {
262			c, err := ln.Accept()
263			if err != nil {
264				return
265			}
266			c.Close()
267		}
268	}
269
270	// Convert a list of IP strings into TCPAddrs.
271	makeAddrs := func(ips []string, port string) addrList {
272		var out addrList
273		for _, ip := range ips {
274			addr, err := ResolveTCPAddr("tcp", JoinHostPort(ip, port))
275			if err != nil {
276				t.Fatal(err)
277			}
278			out = append(out, addr)
279		}
280		return out
281	}
282
283	for i, tt := range testCases {
284		dss, err := newDualStackServer()
285		if err != nil {
286			t.Fatal(err)
287		}
288		defer dss.teardown()
289		if err := dss.buildup(handler); err != nil {
290			t.Fatal(err)
291		}
292		if tt.teardownNetwork != "" {
293			// Destroy one of the listening sockets, creating an unreachable port.
294			dss.teardownNetwork(tt.teardownNetwork)
295		}
296
297		primaries := makeAddrs(tt.primaries, dss.port)
298		fallbacks := makeAddrs(tt.fallbacks, dss.port)
299		d := Dialer{
300			FallbackDelay: fallbackDelay,
301		}
302		startTime := time.Now()
303		sd := &sysDialer{
304			Dialer:  d,
305			network: "tcp",
306			address: "?",
307		}
308		c, err := sd.dialParallel(context.Background(), primaries, fallbacks)
309		elapsed := time.Since(startTime)
310
311		if c != nil {
312			c.Close()
313		}
314
315		if tt.expectOk && err != nil {
316			t.Errorf("#%d: got %v; want nil", i, err)
317		} else if !tt.expectOk && err == nil {
318			t.Errorf("#%d: got nil; want non-nil", i)
319		}
320
321		// We used to always use 95 milliseconds as the slop,
322		// but that was flaky on Windows.  See issue 35616.
323		slop := 95 * time.Millisecond
324		if fifth := tt.expectElapsed / 5; fifth > slop {
325			slop = fifth
326		}
327		expectElapsedMin := tt.expectElapsed - slop
328		expectElapsedMax := tt.expectElapsed + slop
329		if elapsed < expectElapsedMin {
330			t.Errorf("#%d: got %v; want >= %v", i, elapsed, expectElapsedMin)
331		} else if elapsed > expectElapsedMax {
332			t.Errorf("#%d: got %v; want <= %v", i, elapsed, expectElapsedMax)
333		}
334
335		// Repeat each case, ensuring that it can be canceled quickly.
336		ctx, cancel := context.WithCancel(context.Background())
337		var wg sync.WaitGroup
338		wg.Add(1)
339		go func() {
340			time.Sleep(5 * time.Millisecond)
341			cancel()
342			wg.Done()
343		}()
344		startTime = time.Now()
345		c, err = sd.dialParallel(ctx, primaries, fallbacks)
346		if c != nil {
347			c.Close()
348		}
349		elapsed = time.Now().Sub(startTime)
350		if elapsed > 100*time.Millisecond {
351			t.Errorf("#%d (cancel): got %v; want <= 100ms", i, elapsed)
352		}
353		wg.Wait()
354	}
355}
356
357func lookupSlowFast(ctx context.Context, fn func(context.Context, string, string) ([]IPAddr, error), network, host string) ([]IPAddr, error) {
358	switch host {
359	case "slow6loopback4":
360		// Returns a slow IPv6 address, and a local IPv4 address.
361		return []IPAddr{
362			{IP: ParseIP(slowDst6)},
363			{IP: ParseIP("127.0.0.1")},
364		}, nil
365	default:
366		return fn(ctx, network, host)
367	}
368}
369
370func TestDialerFallbackDelay(t *testing.T) {
371	testenv.MustHaveExternalNetwork(t)
372
373	if !supportsIPv4() || !supportsIPv6() {
374		t.Skip("both IPv4 and IPv6 are required")
375	}
376
377	origTestHookLookupIP := testHookLookupIP
378	defer func() { testHookLookupIP = origTestHookLookupIP }()
379	testHookLookupIP = lookupSlowFast
380
381	origTestHookDialTCP := testHookDialTCP
382	defer func() { testHookDialTCP = origTestHookDialTCP }()
383	testHookDialTCP = slowDialTCP
384
385	var testCases = []struct {
386		dualstack     bool
387		delay         time.Duration
388		expectElapsed time.Duration
389	}{
390		// Use a very brief delay, which should fallback immediately.
391		{true, 1 * time.Nanosecond, 0},
392		// Use a 200ms explicit timeout.
393		{true, 200 * time.Millisecond, 200 * time.Millisecond},
394		// The default is 300ms.
395		{true, 0, 300 * time.Millisecond},
396	}
397
398	handler := func(dss *dualStackServer, ln Listener) {
399		for {
400			c, err := ln.Accept()
401			if err != nil {
402				return
403			}
404			c.Close()
405		}
406	}
407	dss, err := newDualStackServer()
408	if err != nil {
409		t.Fatal(err)
410	}
411	defer dss.teardown()
412	if err := dss.buildup(handler); err != nil {
413		t.Fatal(err)
414	}
415
416	for i, tt := range testCases {
417		d := &Dialer{DualStack: tt.dualstack, FallbackDelay: tt.delay}
418
419		startTime := time.Now()
420		c, err := d.Dial("tcp", JoinHostPort("slow6loopback4", dss.port))
421		elapsed := time.Now().Sub(startTime)
422		if err == nil {
423			c.Close()
424		} else if tt.dualstack {
425			t.Error(err)
426		}
427		expectMin := tt.expectElapsed - 1*time.Millisecond
428		expectMax := tt.expectElapsed + 95*time.Millisecond
429		if elapsed < expectMin {
430			t.Errorf("#%d: got %v; want >= %v", i, elapsed, expectMin)
431		}
432		if elapsed > expectMax {
433			t.Errorf("#%d: got %v; want <= %v", i, elapsed, expectMax)
434		}
435	}
436}
437
438func TestDialParallelSpuriousConnection(t *testing.T) {
439	if !supportsIPv4() || !supportsIPv6() {
440		t.Skip("both IPv4 and IPv6 are required")
441	}
442
443	var readDeadline time.Time
444	if td, ok := t.Deadline(); ok {
445		const arbitraryCleanupMargin = 1 * time.Second
446		readDeadline = td.Add(-arbitraryCleanupMargin)
447	} else {
448		readDeadline = time.Now().Add(5 * time.Second)
449	}
450
451	var wg sync.WaitGroup
452	wg.Add(2)
453	handler := func(dss *dualStackServer, ln Listener) {
454		// Accept one connection per address.
455		c, err := ln.Accept()
456		if err != nil {
457			t.Fatal(err)
458		}
459		// The client should close itself, without sending data.
460		c.SetReadDeadline(readDeadline)
461		var b [1]byte
462		if _, err := c.Read(b[:]); err != io.EOF {
463			t.Errorf("got %v; want %v", err, io.EOF)
464		}
465		c.Close()
466		wg.Done()
467	}
468	dss, err := newDualStackServer()
469	if err != nil {
470		t.Fatal(err)
471	}
472	defer dss.teardown()
473	if err := dss.buildup(handler); err != nil {
474		t.Fatal(err)
475	}
476
477	const fallbackDelay = 100 * time.Millisecond
478
479	origTestHookDialTCP := testHookDialTCP
480	defer func() { testHookDialTCP = origTestHookDialTCP }()
481	testHookDialTCP = func(ctx context.Context, net string, laddr, raddr *TCPAddr) (*TCPConn, error) {
482		// Sleep long enough for Happy Eyeballs to kick in, and inhibit cancellation.
483		// This forces dialParallel to juggle two successful connections.
484		time.Sleep(fallbackDelay * 2)
485
486		// Now ignore the provided context (which will be canceled) and use a
487		// different one to make sure this completes with a valid connection,
488		// which we hope to be closed below:
489		sd := &sysDialer{network: net, address: raddr.String()}
490		return sd.doDialTCP(context.Background(), laddr, raddr)
491	}
492
493	d := Dialer{
494		FallbackDelay: fallbackDelay,
495	}
496	sd := &sysDialer{
497		Dialer:  d,
498		network: "tcp",
499		address: "?",
500	}
501
502	makeAddr := func(ip string) addrList {
503		addr, err := ResolveTCPAddr("tcp", JoinHostPort(ip, dss.port))
504		if err != nil {
505			t.Fatal(err)
506		}
507		return addrList{addr}
508	}
509
510	// dialParallel returns one connection (and closes the other.)
511	c, err := sd.dialParallel(context.Background(), makeAddr("127.0.0.1"), makeAddr("::1"))
512	if err != nil {
513		t.Fatal(err)
514	}
515	c.Close()
516
517	// The server should've seen both connections.
518	wg.Wait()
519}
520
521func TestDialerPartialDeadline(t *testing.T) {
522	now := time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)
523	var testCases = []struct {
524		now            time.Time
525		deadline       time.Time
526		addrs          int
527		expectDeadline time.Time
528		expectErr      error
529	}{
530		// Regular division.
531		{now, now.Add(12 * time.Second), 1, now.Add(12 * time.Second), nil},
532		{now, now.Add(12 * time.Second), 2, now.Add(6 * time.Second), nil},
533		{now, now.Add(12 * time.Second), 3, now.Add(4 * time.Second), nil},
534		// Bump against the 2-second sane minimum.
535		{now, now.Add(12 * time.Second), 999, now.Add(2 * time.Second), nil},
536		// Total available is now below the sane minimum.
537		{now, now.Add(1900 * time.Millisecond), 999, now.Add(1900 * time.Millisecond), nil},
538		// Null deadline.
539		{now, noDeadline, 1, noDeadline, nil},
540		// Step the clock forward and cross the deadline.
541		{now.Add(-1 * time.Millisecond), now, 1, now, nil},
542		{now.Add(0 * time.Millisecond), now, 1, noDeadline, errTimeout},
543		{now.Add(1 * time.Millisecond), now, 1, noDeadline, errTimeout},
544	}
545	for i, tt := range testCases {
546		deadline, err := partialDeadline(tt.now, tt.deadline, tt.addrs)
547		if err != tt.expectErr {
548			t.Errorf("#%d: got %v; want %v", i, err, tt.expectErr)
549		}
550		if !deadline.Equal(tt.expectDeadline) {
551			t.Errorf("#%d: got %v; want %v", i, deadline, tt.expectDeadline)
552		}
553	}
554}
555
556func TestDialerLocalAddr(t *testing.T) {
557	if !supportsIPv4() || !supportsIPv6() {
558		t.Skip("both IPv4 and IPv6 are required")
559	}
560
561	type test struct {
562		network, raddr string
563		laddr          Addr
564		error
565	}
566	var tests = []test{
567		{"tcp4", "127.0.0.1", nil, nil},
568		{"tcp4", "127.0.0.1", &TCPAddr{}, nil},
569		{"tcp4", "127.0.0.1", &TCPAddr{IP: ParseIP("0.0.0.0")}, nil},
570		{"tcp4", "127.0.0.1", &TCPAddr{IP: ParseIP("0.0.0.0").To4()}, nil},
571		{"tcp4", "127.0.0.1", &TCPAddr{IP: ParseIP("::")}, &AddrError{Err: "some error"}},
572		{"tcp4", "127.0.0.1", &TCPAddr{IP: ParseIP("127.0.0.1").To4()}, nil},
573		{"tcp4", "127.0.0.1", &TCPAddr{IP: ParseIP("127.0.0.1").To16()}, nil},
574		{"tcp4", "127.0.0.1", &TCPAddr{IP: IPv6loopback}, errNoSuitableAddress},
575		{"tcp4", "127.0.0.1", &UDPAddr{}, &AddrError{Err: "some error"}},
576		{"tcp4", "127.0.0.1", &UnixAddr{}, &AddrError{Err: "some error"}},
577
578		{"tcp6", "::1", nil, nil},
579		{"tcp6", "::1", &TCPAddr{}, nil},
580		{"tcp6", "::1", &TCPAddr{IP: ParseIP("0.0.0.0")}, nil},
581		{"tcp6", "::1", &TCPAddr{IP: ParseIP("0.0.0.0").To4()}, nil},
582		{"tcp6", "::1", &TCPAddr{IP: ParseIP("::")}, nil},
583		{"tcp6", "::1", &TCPAddr{IP: ParseIP("127.0.0.1").To4()}, errNoSuitableAddress},
584		{"tcp6", "::1", &TCPAddr{IP: ParseIP("127.0.0.1").To16()}, errNoSuitableAddress},
585		{"tcp6", "::1", &TCPAddr{IP: IPv6loopback}, nil},
586		{"tcp6", "::1", &UDPAddr{}, &AddrError{Err: "some error"}},
587		{"tcp6", "::1", &UnixAddr{}, &AddrError{Err: "some error"}},
588
589		{"tcp", "127.0.0.1", nil, nil},
590		{"tcp", "127.0.0.1", &TCPAddr{}, nil},
591		{"tcp", "127.0.0.1", &TCPAddr{IP: ParseIP("0.0.0.0")}, nil},
592		{"tcp", "127.0.0.1", &TCPAddr{IP: ParseIP("0.0.0.0").To4()}, nil},
593		{"tcp", "127.0.0.1", &TCPAddr{IP: ParseIP("127.0.0.1").To4()}, nil},
594		{"tcp", "127.0.0.1", &TCPAddr{IP: ParseIP("127.0.0.1").To16()}, nil},
595		{"tcp", "127.0.0.1", &TCPAddr{IP: IPv6loopback}, errNoSuitableAddress},
596		{"tcp", "127.0.0.1", &UDPAddr{}, &AddrError{Err: "some error"}},
597		{"tcp", "127.0.0.1", &UnixAddr{}, &AddrError{Err: "some error"}},
598
599		{"tcp", "::1", nil, nil},
600		{"tcp", "::1", &TCPAddr{}, nil},
601		{"tcp", "::1", &TCPAddr{IP: ParseIP("0.0.0.0")}, nil},
602		{"tcp", "::1", &TCPAddr{IP: ParseIP("0.0.0.0").To4()}, nil},
603		{"tcp", "::1", &TCPAddr{IP: ParseIP("::")}, nil},
604		{"tcp", "::1", &TCPAddr{IP: ParseIP("127.0.0.1").To4()}, errNoSuitableAddress},
605		{"tcp", "::1", &TCPAddr{IP: ParseIP("127.0.0.1").To16()}, errNoSuitableAddress},
606		{"tcp", "::1", &TCPAddr{IP: IPv6loopback}, nil},
607		{"tcp", "::1", &UDPAddr{}, &AddrError{Err: "some error"}},
608		{"tcp", "::1", &UnixAddr{}, &AddrError{Err: "some error"}},
609	}
610
611	if supportsIPv4map() {
612		tests = append(tests, test{
613			"tcp", "127.0.0.1", &TCPAddr{IP: ParseIP("::")}, nil,
614		})
615	} else {
616		tests = append(tests, test{
617			"tcp", "127.0.0.1", &TCPAddr{IP: ParseIP("::")}, &AddrError{Err: "some error"},
618		})
619	}
620
621	origTestHookLookupIP := testHookLookupIP
622	defer func() { testHookLookupIP = origTestHookLookupIP }()
623	testHookLookupIP = lookupLocalhost
624	handler := func(ls *localServer, ln Listener) {
625		for {
626			c, err := ln.Accept()
627			if err != nil {
628				return
629			}
630			c.Close()
631		}
632	}
633	var err error
634	var lss [2]*localServer
635	for i, network := range []string{"tcp4", "tcp6"} {
636		lss[i], err = newLocalServer(network)
637		if err != nil {
638			t.Fatal(err)
639		}
640		defer lss[i].teardown()
641		if err := lss[i].buildup(handler); err != nil {
642			t.Fatal(err)
643		}
644	}
645
646	for _, tt := range tests {
647		d := &Dialer{LocalAddr: tt.laddr}
648		var addr string
649		ip := ParseIP(tt.raddr)
650		if ip.To4() != nil {
651			addr = lss[0].Listener.Addr().String()
652		}
653		if ip.To16() != nil && ip.To4() == nil {
654			addr = lss[1].Listener.Addr().String()
655		}
656		c, err := d.Dial(tt.network, addr)
657		if err == nil && tt.error != nil || err != nil && tt.error == nil {
658			// A suspected kernel bug in macOS 10.12 occasionally results in
659			// timeout errors when dialing address ::1. The errors have not
660			// been observed on newer versions of the OS, so we don't plan to work
661			// around them. See https://golang.org/issue/22019.
662			if tt.raddr == "::1" && os.Getenv("GO_BUILDER_NAME") == "darwin-amd64-10_12" && os.IsTimeout(err) {
663				t.Logf("ignoring timeout error on Darwin; see https://golang.org/issue/22019")
664			} else {
665				t.Errorf("%s %v->%s: got %v; want %v", tt.network, tt.laddr, tt.raddr, err, tt.error)
666			}
667		}
668		if err != nil {
669			if perr := parseDialError(err); perr != nil {
670				t.Error(perr)
671			}
672			continue
673		}
674		c.Close()
675	}
676}
677
678func TestDialerDualStack(t *testing.T) {
679	testenv.SkipFlaky(t, 13324)
680
681	if !supportsIPv4() || !supportsIPv6() {
682		t.Skip("both IPv4 and IPv6 are required")
683	}
684
685	closedPortDelay, expectClosedPortDelay := dialClosedPort(t)
686	if closedPortDelay > expectClosedPortDelay {
687		t.Errorf("got %v; want <= %v", closedPortDelay, expectClosedPortDelay)
688	}
689
690	origTestHookLookupIP := testHookLookupIP
691	defer func() { testHookLookupIP = origTestHookLookupIP }()
692	testHookLookupIP = lookupLocalhost
693	handler := func(dss *dualStackServer, ln Listener) {
694		for {
695			c, err := ln.Accept()
696			if err != nil {
697				return
698			}
699			c.Close()
700		}
701	}
702
703	var timeout = 150*time.Millisecond + closedPortDelay
704	for _, dualstack := range []bool{false, true} {
705		dss, err := newDualStackServer()
706		if err != nil {
707			t.Fatal(err)
708		}
709		defer dss.teardown()
710		if err := dss.buildup(handler); err != nil {
711			t.Fatal(err)
712		}
713
714		d := &Dialer{DualStack: dualstack, Timeout: timeout}
715		for range dss.lns {
716			c, err := d.Dial("tcp", JoinHostPort("localhost", dss.port))
717			if err != nil {
718				t.Error(err)
719				continue
720			}
721			switch addr := c.LocalAddr().(*TCPAddr); {
722			case addr.IP.To4() != nil:
723				dss.teardownNetwork("tcp4")
724			case addr.IP.To16() != nil && addr.IP.To4() == nil:
725				dss.teardownNetwork("tcp6")
726			}
727			c.Close()
728		}
729	}
730}
731
732func TestDialerKeepAlive(t *testing.T) {
733	handler := func(ls *localServer, ln Listener) {
734		for {
735			c, err := ln.Accept()
736			if err != nil {
737				return
738			}
739			c.Close()
740		}
741	}
742	ls, err := newLocalServer("tcp")
743	if err != nil {
744		t.Fatal(err)
745	}
746	defer ls.teardown()
747	if err := ls.buildup(handler); err != nil {
748		t.Fatal(err)
749	}
750	defer func() { testHookSetKeepAlive = func(time.Duration) {} }()
751
752	tests := []struct {
753		ka       time.Duration
754		expected time.Duration
755	}{
756		{-1, -1},
757		{0, 15 * time.Second},
758		{5 * time.Second, 5 * time.Second},
759		{30 * time.Second, 30 * time.Second},
760	}
761
762	for _, test := range tests {
763		var got time.Duration = -1
764		testHookSetKeepAlive = func(d time.Duration) { got = d }
765		d := Dialer{KeepAlive: test.ka}
766		c, err := d.Dial("tcp", ls.Listener.Addr().String())
767		if err != nil {
768			t.Fatal(err)
769		}
770		c.Close()
771		if got != test.expected {
772			t.Errorf("Dialer.KeepAlive = %v: SetKeepAlive set to %v, want %v", d.KeepAlive, got, test.expected)
773		}
774	}
775}
776
777func TestDialCancel(t *testing.T) {
778	mustHaveExternalNetwork(t)
779
780	blackholeIPPort := JoinHostPort(slowDst4, "1234")
781	if !supportsIPv4() {
782		blackholeIPPort = JoinHostPort(slowDst6, "1234")
783	}
784
785	ticker := time.NewTicker(10 * time.Millisecond)
786	defer ticker.Stop()
787
788	const cancelTick = 5 // the timer tick we cancel the dial at
789	const timeoutTick = 100
790
791	var d Dialer
792	cancel := make(chan struct{})
793	d.Cancel = cancel
794	errc := make(chan error, 1)
795	connc := make(chan Conn, 1)
796	go func() {
797		if c, err := d.Dial("tcp", blackholeIPPort); err != nil {
798			errc <- err
799		} else {
800			connc <- c
801		}
802	}()
803	ticks := 0
804	for {
805		select {
806		case <-ticker.C:
807			ticks++
808			if ticks == cancelTick {
809				close(cancel)
810			}
811			if ticks == timeoutTick {
812				t.Fatal("timeout waiting for dial to fail")
813			}
814		case c := <-connc:
815			c.Close()
816			t.Fatal("unexpected successful connection")
817		case err := <-errc:
818			if perr := parseDialError(err); perr != nil {
819				t.Error(perr)
820			}
821			if ticks < cancelTick {
822				// Using strings.Contains is ugly but
823				// may work on plan9 and windows.
824				if strings.Contains(err.Error(), "connection refused") {
825					t.Skipf("connection to %v failed fast with %v", blackholeIPPort, err)
826				}
827				t.Fatalf("dial error after %d ticks (%d before cancel sent): %v",
828					ticks, cancelTick-ticks, err)
829			}
830			if oe, ok := err.(*OpError); !ok || oe.Err != errCanceled {
831				t.Fatalf("dial error = %v (%T); want OpError with Err == errCanceled", err, err)
832			}
833			return // success.
834		}
835	}
836}
837
838func TestCancelAfterDial(t *testing.T) {
839	if testing.Short() {
840		t.Skip("avoiding time.Sleep")
841	}
842
843	ln, err := newLocalListener("tcp")
844	if err != nil {
845		t.Fatal(err)
846	}
847
848	var wg sync.WaitGroup
849	wg.Add(1)
850	defer func() {
851		ln.Close()
852		wg.Wait()
853	}()
854
855	// Echo back the first line of each incoming connection.
856	go func() {
857		for {
858			c, err := ln.Accept()
859			if err != nil {
860				break
861			}
862			rb := bufio.NewReader(c)
863			line, err := rb.ReadString('\n')
864			if err != nil {
865				t.Error(err)
866				c.Close()
867				continue
868			}
869			if _, err := c.Write([]byte(line)); err != nil {
870				t.Error(err)
871			}
872			c.Close()
873		}
874		wg.Done()
875	}()
876
877	try := func() {
878		cancel := make(chan struct{})
879		d := &Dialer{Cancel: cancel}
880		c, err := d.Dial("tcp", ln.Addr().String())
881
882		// Immediately after dialing, request cancellation and sleep.
883		// Before Issue 15078 was fixed, this would cause subsequent operations
884		// to fail with an i/o timeout roughly 50% of the time.
885		close(cancel)
886		time.Sleep(10 * time.Millisecond)
887
888		if err != nil {
889			t.Fatal(err)
890		}
891		defer c.Close()
892
893		// Send some data to confirm that the connection is still alive.
894		const message = "echo!\n"
895		if _, err := c.Write([]byte(message)); err != nil {
896			t.Fatal(err)
897		}
898
899		// The server should echo the line, and close the connection.
900		rb := bufio.NewReader(c)
901		line, err := rb.ReadString('\n')
902		if err != nil {
903			t.Fatal(err)
904		}
905		if line != message {
906			t.Errorf("got %q; want %q", line, message)
907		}
908		if _, err := rb.ReadByte(); err != io.EOF {
909			t.Errorf("got %v; want %v", err, io.EOF)
910		}
911	}
912
913	// This bug manifested about 50% of the time, so try it a few times.
914	for i := 0; i < 10; i++ {
915		try()
916	}
917}
918
919// Issue 18806: it should always be possible to net.Dial a
920// net.Listener().Addr().String when the listen address was ":n", even
921// if the machine has halfway configured IPv6 such that it can bind on
922// "::" not connect back to that same address.
923func TestDialListenerAddr(t *testing.T) {
924	mustHaveExternalNetwork(t)
925	ln, err := Listen("tcp", ":0")
926	if err != nil {
927		t.Fatal(err)
928	}
929	defer ln.Close()
930	addr := ln.Addr().String()
931	c, err := Dial("tcp", addr)
932	if err != nil {
933		t.Fatalf("for addr %q, dial error: %v", addr, err)
934	}
935	c.Close()
936}
937
938func TestDialerControl(t *testing.T) {
939	switch runtime.GOOS {
940	case "plan9":
941		t.Skipf("not supported on %s", runtime.GOOS)
942	}
943
944	t.Run("StreamDial", func(t *testing.T) {
945		for _, network := range []string{"tcp", "tcp4", "tcp6", "unix", "unixpacket"} {
946			if !testableNetwork(network) {
947				continue
948			}
949			ln, err := newLocalListener(network)
950			if err != nil {
951				t.Error(err)
952				continue
953			}
954			defer ln.Close()
955			d := Dialer{Control: controlOnConnSetup}
956			c, err := d.Dial(network, ln.Addr().String())
957			if err != nil {
958				t.Error(err)
959				continue
960			}
961			c.Close()
962		}
963	})
964	t.Run("PacketDial", func(t *testing.T) {
965		for _, network := range []string{"udp", "udp4", "udp6", "unixgram"} {
966			if !testableNetwork(network) {
967				continue
968			}
969			c1, err := newLocalPacketListener(network)
970			if err != nil {
971				t.Error(err)
972				continue
973			}
974			if network == "unixgram" {
975				defer os.Remove(c1.LocalAddr().String())
976			}
977			defer c1.Close()
978			d := Dialer{Control: controlOnConnSetup}
979			c2, err := d.Dial(network, c1.LocalAddr().String())
980			if err != nil {
981				t.Error(err)
982				continue
983			}
984			c2.Close()
985		}
986	})
987}
988
989// mustHaveExternalNetwork is like testenv.MustHaveExternalNetwork
990// except that it won't skip testing on non-mobile builders.
991func mustHaveExternalNetwork(t *testing.T) {
992	t.Helper()
993	mobile := runtime.GOOS == "android" || runtime.GOOS == "ios"
994	if testenv.Builder() == "" || mobile {
995		testenv.MustHaveExternalNetwork(t)
996	}
997}
998
999type contextWithNonZeroDeadline struct {
1000	context.Context
1001}
1002
1003func (contextWithNonZeroDeadline) Deadline() (time.Time, bool) {
1004	// Return non-zero time.Time value with false indicating that no deadline is set.
1005	return time.Unix(0, 0), false
1006}
1007
1008func TestDialWithNonZeroDeadline(t *testing.T) {
1009	ln, err := newLocalListener("tcp")
1010	if err != nil {
1011		t.Fatal(err)
1012	}
1013	defer ln.Close()
1014	_, port, err := SplitHostPort(ln.Addr().String())
1015	if err != nil {
1016		t.Fatal(err)
1017	}
1018
1019	ctx := contextWithNonZeroDeadline{Context: context.Background()}
1020	var dialer Dialer
1021	c, err := dialer.DialContext(ctx, "tcp", JoinHostPort("", port))
1022	if err != nil {
1023		t.Fatal(err)
1024	}
1025	c.Close()
1026}
1027