1// Copyright 2012 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	"fmt"
11	"internal/testenv"
12	"io"
13	"os"
14	"reflect"
15	"runtime"
16	"sync"
17	"testing"
18	"time"
19)
20
21func BenchmarkTCP4OneShot(b *testing.B) {
22	benchmarkTCP(b, false, false, "127.0.0.1:0")
23}
24
25func BenchmarkTCP4OneShotTimeout(b *testing.B) {
26	benchmarkTCP(b, false, true, "127.0.0.1:0")
27}
28
29func BenchmarkTCP4Persistent(b *testing.B) {
30	benchmarkTCP(b, true, false, "127.0.0.1:0")
31}
32
33func BenchmarkTCP4PersistentTimeout(b *testing.B) {
34	benchmarkTCP(b, true, true, "127.0.0.1:0")
35}
36
37func BenchmarkTCP6OneShot(b *testing.B) {
38	if !supportsIPv6() {
39		b.Skip("ipv6 is not supported")
40	}
41	benchmarkTCP(b, false, false, "[::1]:0")
42}
43
44func BenchmarkTCP6OneShotTimeout(b *testing.B) {
45	if !supportsIPv6() {
46		b.Skip("ipv6 is not supported")
47	}
48	benchmarkTCP(b, false, true, "[::1]:0")
49}
50
51func BenchmarkTCP6Persistent(b *testing.B) {
52	if !supportsIPv6() {
53		b.Skip("ipv6 is not supported")
54	}
55	benchmarkTCP(b, true, false, "[::1]:0")
56}
57
58func BenchmarkTCP6PersistentTimeout(b *testing.B) {
59	if !supportsIPv6() {
60		b.Skip("ipv6 is not supported")
61	}
62	benchmarkTCP(b, true, true, "[::1]:0")
63}
64
65func benchmarkTCP(b *testing.B, persistent, timeout bool, laddr string) {
66	testHookUninstaller.Do(uninstallTestHooks)
67
68	const msgLen = 512
69	conns := b.N
70	numConcurrent := runtime.GOMAXPROCS(-1) * 2
71	msgs := 1
72	if persistent {
73		conns = numConcurrent
74		msgs = b.N / conns
75		if msgs == 0 {
76			msgs = 1
77		}
78		if conns > b.N {
79			conns = b.N
80		}
81	}
82	sendMsg := func(c Conn, buf []byte) bool {
83		n, err := c.Write(buf)
84		if n != len(buf) || err != nil {
85			b.Log(err)
86			return false
87		}
88		return true
89	}
90	recvMsg := func(c Conn, buf []byte) bool {
91		for read := 0; read != len(buf); {
92			n, err := c.Read(buf)
93			read += n
94			if err != nil {
95				b.Log(err)
96				return false
97			}
98		}
99		return true
100	}
101	ln, err := Listen("tcp", laddr)
102	if err != nil {
103		b.Fatal(err)
104	}
105	defer ln.Close()
106	serverSem := make(chan bool, numConcurrent)
107	// Acceptor.
108	go func() {
109		for {
110			c, err := ln.Accept()
111			if err != nil {
112				break
113			}
114			serverSem <- true
115			// Server connection.
116			go func(c Conn) {
117				defer func() {
118					c.Close()
119					<-serverSem
120				}()
121				if timeout {
122					c.SetDeadline(time.Now().Add(time.Hour)) // Not intended to fire.
123				}
124				var buf [msgLen]byte
125				for m := 0; m < msgs; m++ {
126					if !recvMsg(c, buf[:]) || !sendMsg(c, buf[:]) {
127						break
128					}
129				}
130			}(c)
131		}
132	}()
133	clientSem := make(chan bool, numConcurrent)
134	for i := 0; i < conns; i++ {
135		clientSem <- true
136		// Client connection.
137		go func() {
138			defer func() {
139				<-clientSem
140			}()
141			c, err := Dial("tcp", ln.Addr().String())
142			if err != nil {
143				b.Log(err)
144				return
145			}
146			defer c.Close()
147			if timeout {
148				c.SetDeadline(time.Now().Add(time.Hour)) // Not intended to fire.
149			}
150			var buf [msgLen]byte
151			for m := 0; m < msgs; m++ {
152				if !sendMsg(c, buf[:]) || !recvMsg(c, buf[:]) {
153					break
154				}
155			}
156		}()
157	}
158	for i := 0; i < numConcurrent; i++ {
159		clientSem <- true
160		serverSem <- true
161	}
162}
163
164func BenchmarkTCP4ConcurrentReadWrite(b *testing.B) {
165	benchmarkTCPConcurrentReadWrite(b, "127.0.0.1:0")
166}
167
168func BenchmarkTCP6ConcurrentReadWrite(b *testing.B) {
169	if !supportsIPv6() {
170		b.Skip("ipv6 is not supported")
171	}
172	benchmarkTCPConcurrentReadWrite(b, "[::1]:0")
173}
174
175func benchmarkTCPConcurrentReadWrite(b *testing.B, laddr string) {
176	testHookUninstaller.Do(uninstallTestHooks)
177
178	// The benchmark creates GOMAXPROCS client/server pairs.
179	// Each pair creates 4 goroutines: client reader/writer and server reader/writer.
180	// The benchmark stresses concurrent reading and writing to the same connection.
181	// Such pattern is used in net/http and net/rpc.
182
183	b.StopTimer()
184
185	P := runtime.GOMAXPROCS(0)
186	N := b.N / P
187	W := 1000
188
189	// Setup P client/server connections.
190	clients := make([]Conn, P)
191	servers := make([]Conn, P)
192	ln, err := Listen("tcp", laddr)
193	if err != nil {
194		b.Fatal(err)
195	}
196	defer ln.Close()
197	done := make(chan bool)
198	go func() {
199		for p := 0; p < P; p++ {
200			s, err := ln.Accept()
201			if err != nil {
202				b.Error(err)
203				return
204			}
205			servers[p] = s
206		}
207		done <- true
208	}()
209	for p := 0; p < P; p++ {
210		c, err := Dial("tcp", ln.Addr().String())
211		if err != nil {
212			b.Fatal(err)
213		}
214		clients[p] = c
215	}
216	<-done
217
218	b.StartTimer()
219
220	var wg sync.WaitGroup
221	wg.Add(4 * P)
222	for p := 0; p < P; p++ {
223		// Client writer.
224		go func(c Conn) {
225			defer wg.Done()
226			var buf [1]byte
227			for i := 0; i < N; i++ {
228				v := byte(i)
229				for w := 0; w < W; w++ {
230					v *= v
231				}
232				buf[0] = v
233				_, err := c.Write(buf[:])
234				if err != nil {
235					b.Error(err)
236					return
237				}
238			}
239		}(clients[p])
240
241		// Pipe between server reader and server writer.
242		pipe := make(chan byte, 128)
243
244		// Server reader.
245		go func(s Conn) {
246			defer wg.Done()
247			var buf [1]byte
248			for i := 0; i < N; i++ {
249				_, err := s.Read(buf[:])
250				if err != nil {
251					b.Error(err)
252					return
253				}
254				pipe <- buf[0]
255			}
256		}(servers[p])
257
258		// Server writer.
259		go func(s Conn) {
260			defer wg.Done()
261			var buf [1]byte
262			for i := 0; i < N; i++ {
263				v := <-pipe
264				for w := 0; w < W; w++ {
265					v *= v
266				}
267				buf[0] = v
268				_, err := s.Write(buf[:])
269				if err != nil {
270					b.Error(err)
271					return
272				}
273			}
274			s.Close()
275		}(servers[p])
276
277		// Client reader.
278		go func(c Conn) {
279			defer wg.Done()
280			var buf [1]byte
281			for i := 0; i < N; i++ {
282				_, err := c.Read(buf[:])
283				if err != nil {
284					b.Error(err)
285					return
286				}
287			}
288			c.Close()
289		}(clients[p])
290	}
291	wg.Wait()
292}
293
294type resolveTCPAddrTest struct {
295	network       string
296	litAddrOrName string
297	addr          *TCPAddr
298	err           error
299}
300
301var resolveTCPAddrTests = []resolveTCPAddrTest{
302	{"tcp", "127.0.0.1:0", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil},
303	{"tcp4", "127.0.0.1:65535", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 65535}, nil},
304
305	{"tcp", "[::1]:0", &TCPAddr{IP: ParseIP("::1"), Port: 0}, nil},
306	{"tcp6", "[::1]:65535", &TCPAddr{IP: ParseIP("::1"), Port: 65535}, nil},
307
308	{"tcp", "[::1%en0]:1", &TCPAddr{IP: ParseIP("::1"), Port: 1, Zone: "en0"}, nil},
309	{"tcp6", "[::1%911]:2", &TCPAddr{IP: ParseIP("::1"), Port: 2, Zone: "911"}, nil},
310
311	{"", "127.0.0.1:0", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil}, // Go 1.0 behavior
312	{"", "[::1]:0", &TCPAddr{IP: ParseIP("::1"), Port: 0}, nil},         // Go 1.0 behavior
313
314	{"tcp", ":12345", &TCPAddr{Port: 12345}, nil},
315
316	{"http", "127.0.0.1:0", nil, UnknownNetworkError("http")},
317
318	{"tcp", "127.0.0.1:http", &TCPAddr{IP: ParseIP("127.0.0.1"), Port: 80}, nil},
319	{"tcp", "[::ffff:127.0.0.1]:http", &TCPAddr{IP: ParseIP("::ffff:127.0.0.1"), Port: 80}, nil},
320	{"tcp", "[2001:db8::1]:http", &TCPAddr{IP: ParseIP("2001:db8::1"), Port: 80}, nil},
321	{"tcp4", "127.0.0.1:http", &TCPAddr{IP: ParseIP("127.0.0.1"), Port: 80}, nil},
322	{"tcp4", "[::ffff:127.0.0.1]:http", &TCPAddr{IP: ParseIP("127.0.0.1"), Port: 80}, nil},
323	{"tcp6", "[2001:db8::1]:http", &TCPAddr{IP: ParseIP("2001:db8::1"), Port: 80}, nil},
324
325	{"tcp4", "[2001:db8::1]:http", nil, &AddrError{Err: errNoSuitableAddress.Error(), Addr: "2001:db8::1"}},
326	{"tcp6", "127.0.0.1:http", nil, &AddrError{Err: errNoSuitableAddress.Error(), Addr: "127.0.0.1"}},
327	{"tcp6", "[::ffff:127.0.0.1]:http", nil, &AddrError{Err: errNoSuitableAddress.Error(), Addr: "::ffff:127.0.0.1"}},
328}
329
330func TestResolveTCPAddr(t *testing.T) {
331	origTestHookLookupIP := testHookLookupIP
332	defer func() { testHookLookupIP = origTestHookLookupIP }()
333	testHookLookupIP = lookupLocalhost
334
335	for _, tt := range resolveTCPAddrTests {
336		addr, err := ResolveTCPAddr(tt.network, tt.litAddrOrName)
337		if !reflect.DeepEqual(addr, tt.addr) || !reflect.DeepEqual(err, tt.err) {
338			t.Errorf("ResolveTCPAddr(%q, %q) = %#v, %v, want %#v, %v", tt.network, tt.litAddrOrName, addr, err, tt.addr, tt.err)
339			continue
340		}
341		if err == nil {
342			addr2, err := ResolveTCPAddr(addr.Network(), addr.String())
343			if !reflect.DeepEqual(addr2, tt.addr) || err != tt.err {
344				t.Errorf("(%q, %q): ResolveTCPAddr(%q, %q) = %#v, %v, want %#v, %v", tt.network, tt.litAddrOrName, addr.Network(), addr.String(), addr2, err, tt.addr, tt.err)
345			}
346		}
347	}
348}
349
350var tcpListenerNameTests = []struct {
351	net   string
352	laddr *TCPAddr
353}{
354	{"tcp4", &TCPAddr{IP: IPv4(127, 0, 0, 1)}},
355	{"tcp4", &TCPAddr{}},
356	{"tcp4", nil},
357}
358
359func TestTCPListenerName(t *testing.T) {
360	testenv.MustHaveExternalNetwork(t)
361
362	for _, tt := range tcpListenerNameTests {
363		ln, err := ListenTCP(tt.net, tt.laddr)
364		if err != nil {
365			t.Fatal(err)
366		}
367		defer ln.Close()
368		la := ln.Addr()
369		if a, ok := la.(*TCPAddr); !ok || a.Port == 0 {
370			t.Fatalf("got %v; expected a proper address with non-zero port number", la)
371		}
372	}
373}
374
375func TestIPv6LinkLocalUnicastTCP(t *testing.T) {
376	testenv.MustHaveExternalNetwork(t)
377
378	if !supportsIPv6() {
379		t.Skip("IPv6 is not supported")
380	}
381
382	for i, tt := range ipv6LinkLocalUnicastTCPTests {
383		ln, err := Listen(tt.network, tt.address)
384		if err != nil {
385			// It might return "LookupHost returned no
386			// suitable address" error on some platforms.
387			t.Log(err)
388			continue
389		}
390		ls, err := (&streamListener{Listener: ln}).newLocalServer()
391		if err != nil {
392			t.Fatal(err)
393		}
394		defer ls.teardown()
395		ch := make(chan error, 1)
396		handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
397		if err := ls.buildup(handler); err != nil {
398			t.Fatal(err)
399		}
400		if la, ok := ln.Addr().(*TCPAddr); !ok || !tt.nameLookup && la.Zone == "" {
401			t.Fatalf("got %v; expected a proper address with zone identifier", la)
402		}
403
404		c, err := Dial(tt.network, ls.Listener.Addr().String())
405		if err != nil {
406			t.Fatal(err)
407		}
408		defer c.Close()
409		if la, ok := c.LocalAddr().(*TCPAddr); !ok || !tt.nameLookup && la.Zone == "" {
410			t.Fatalf("got %v; expected a proper address with zone identifier", la)
411		}
412		if ra, ok := c.RemoteAddr().(*TCPAddr); !ok || !tt.nameLookup && ra.Zone == "" {
413			t.Fatalf("got %v; expected a proper address with zone identifier", ra)
414		}
415
416		if _, err := c.Write([]byte("TCP OVER IPV6 LINKLOCAL TEST")); err != nil {
417			t.Fatal(err)
418		}
419		b := make([]byte, 32)
420		if _, err := c.Read(b); err != nil {
421			t.Fatal(err)
422		}
423
424		for err := range ch {
425			t.Errorf("#%d: %v", i, err)
426		}
427	}
428}
429
430func TestTCPConcurrentAccept(t *testing.T) {
431	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
432	ln, err := Listen("tcp", "127.0.0.1:0")
433	if err != nil {
434		t.Fatal(err)
435	}
436	const N = 10
437	var wg sync.WaitGroup
438	wg.Add(N)
439	for i := 0; i < N; i++ {
440		go func() {
441			for {
442				c, err := ln.Accept()
443				if err != nil {
444					break
445				}
446				c.Close()
447			}
448			wg.Done()
449		}()
450	}
451	attempts := 10 * N
452	fails := 0
453	d := &Dialer{Timeout: 200 * time.Millisecond}
454	for i := 0; i < attempts; i++ {
455		c, err := d.Dial("tcp", ln.Addr().String())
456		if err != nil {
457			fails++
458		} else {
459			c.Close()
460		}
461	}
462	ln.Close()
463	wg.Wait()
464	if fails > attempts/9 { // see issues 7400 and 7541
465		t.Fatalf("too many Dial failed: %v", fails)
466	}
467	if fails > 0 {
468		t.Logf("# of failed Dials: %v", fails)
469	}
470}
471
472func TestTCPReadWriteAllocs(t *testing.T) {
473	if runtime.Compiler == "gccgo" {
474		t.Skip("skipping for gccgo until escape analysis is enabled")
475	}
476
477	switch runtime.GOOS {
478	case "plan9":
479		// The implementation of asynchronous cancelable
480		// I/O on Plan 9 allocates memory.
481		// See net/fd_io_plan9.go.
482		t.Skipf("not supported on %s", runtime.GOOS)
483	}
484
485	ln, err := Listen("tcp", "127.0.0.1:0")
486	if err != nil {
487		t.Fatal(err)
488	}
489	defer ln.Close()
490	var server Conn
491	errc := make(chan error, 1)
492	go func() {
493		var err error
494		server, err = ln.Accept()
495		errc <- err
496	}()
497	client, err := Dial("tcp", ln.Addr().String())
498	if err != nil {
499		t.Fatal(err)
500	}
501	defer client.Close()
502	if err := <-errc; err != nil {
503		t.Fatal(err)
504	}
505	defer server.Close()
506
507	var buf [128]byte
508	allocs := testing.AllocsPerRun(1000, func() {
509		_, err := server.Write(buf[:])
510		if err != nil {
511			t.Fatal(err)
512		}
513		_, err = io.ReadFull(client, buf[:])
514		if err != nil {
515			t.Fatal(err)
516		}
517	})
518	// For gccgo changed "> 0" to "> 7".
519	if allocs > 7 {
520		t.Fatalf("got %v; want 0", allocs)
521	}
522
523	var bufwrt [128]byte
524	ch := make(chan bool)
525	defer close(ch)
526	go func() {
527		for <-ch {
528			_, err := server.Write(bufwrt[:])
529			errc <- err
530		}
531	}()
532	allocs = testing.AllocsPerRun(1000, func() {
533		ch <- true
534		if _, err = io.ReadFull(client, buf[:]); err != nil {
535			t.Fatal(err)
536		}
537		if err := <-errc; err != nil {
538			t.Fatal(err)
539		}
540	})
541	if allocs > 0 {
542		t.Fatalf("got %v; want 0", allocs)
543	}
544}
545
546func TestTCPStress(t *testing.T) {
547	const conns = 2
548	const msgLen = 512
549	msgs := int(1e4)
550	if testing.Short() {
551		msgs = 1e2
552	}
553
554	sendMsg := func(c Conn, buf []byte) bool {
555		n, err := c.Write(buf)
556		if n != len(buf) || err != nil {
557			t.Log(err)
558			return false
559		}
560		return true
561	}
562	recvMsg := func(c Conn, buf []byte) bool {
563		for read := 0; read != len(buf); {
564			n, err := c.Read(buf)
565			read += n
566			if err != nil {
567				t.Log(err)
568				return false
569			}
570		}
571		return true
572	}
573
574	ln, err := Listen("tcp", "127.0.0.1:0")
575	if err != nil {
576		t.Fatal(err)
577	}
578	done := make(chan bool)
579	// Acceptor.
580	go func() {
581		defer func() {
582			done <- true
583		}()
584		for {
585			c, err := ln.Accept()
586			if err != nil {
587				break
588			}
589			// Server connection.
590			go func(c Conn) {
591				defer c.Close()
592				var buf [msgLen]byte
593				for m := 0; m < msgs; m++ {
594					if !recvMsg(c, buf[:]) || !sendMsg(c, buf[:]) {
595						break
596					}
597				}
598			}(c)
599		}
600	}()
601	for i := 0; i < conns; i++ {
602		// Client connection.
603		go func() {
604			defer func() {
605				done <- true
606			}()
607			c, err := Dial("tcp", ln.Addr().String())
608			if err != nil {
609				t.Log(err)
610				return
611			}
612			defer c.Close()
613			var buf [msgLen]byte
614			for m := 0; m < msgs; m++ {
615				if !sendMsg(c, buf[:]) || !recvMsg(c, buf[:]) {
616					break
617				}
618			}
619		}()
620	}
621	for i := 0; i < conns; i++ {
622		<-done
623	}
624	ln.Close()
625	<-done
626}
627
628func TestTCPSelfConnect(t *testing.T) {
629	if runtime.GOOS == "windows" {
630		// TODO(brainman): do not know why it hangs.
631		t.Skip("known-broken test on windows")
632	}
633
634	ln, err := newLocalListener("tcp")
635	if err != nil {
636		t.Fatal(err)
637	}
638	var d Dialer
639	c, err := d.Dial(ln.Addr().Network(), ln.Addr().String())
640	if err != nil {
641		ln.Close()
642		t.Fatal(err)
643	}
644	network := c.LocalAddr().Network()
645	laddr := *c.LocalAddr().(*TCPAddr)
646	c.Close()
647	ln.Close()
648
649	// Try to connect to that address repeatedly.
650	n := 100000
651	if testing.Short() {
652		n = 1000
653	}
654	switch runtime.GOOS {
655	case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd", "plan9", "illumos", "solaris", "windows":
656		// Non-Linux systems take a long time to figure
657		// out that there is nothing listening on localhost.
658		n = 100
659	}
660	for i := 0; i < n; i++ {
661		d.Timeout = time.Millisecond
662		c, err := d.Dial(network, laddr.String())
663		if err == nil {
664			addr := c.LocalAddr().(*TCPAddr)
665			if addr.Port == laddr.Port || addr.IP.Equal(laddr.IP) {
666				t.Errorf("Dial %v should fail", addr)
667			} else {
668				t.Logf("Dial %v succeeded - possibly racing with other listener", addr)
669			}
670			c.Close()
671		}
672	}
673}
674
675// Test that >32-bit reads work on 64-bit systems.
676// On 32-bit systems this tests that maxint reads work.
677func TestTCPBig(t *testing.T) {
678	if !*testTCPBig {
679		t.Skip("test disabled; use -tcpbig to enable")
680	}
681
682	for _, writev := range []bool{false, true} {
683		t.Run(fmt.Sprintf("writev=%v", writev), func(t *testing.T) {
684			ln, err := newLocalListener("tcp")
685			if err != nil {
686				t.Fatal(err)
687			}
688			defer ln.Close()
689
690			x := int(1 << 30)
691			x = x*5 + 1<<20 // just over 5 GB on 64-bit, just over 1GB on 32-bit
692			done := make(chan int)
693			go func() {
694				defer close(done)
695				c, err := ln.Accept()
696				if err != nil {
697					t.Error(err)
698					return
699				}
700				buf := make([]byte, x)
701				var n int
702				if writev {
703					var n64 int64
704					n64, err = (&Buffers{buf}).WriteTo(c)
705					n = int(n64)
706				} else {
707					n, err = c.Write(buf)
708				}
709				if n != len(buf) || err != nil {
710					t.Errorf("Write(buf) = %d, %v, want %d, nil", n, err, x)
711				}
712				c.Close()
713			}()
714
715			c, err := Dial("tcp", ln.Addr().String())
716			if err != nil {
717				t.Fatal(err)
718			}
719			buf := make([]byte, x)
720			n, err := io.ReadFull(c, buf)
721			if n != len(buf) || err != nil {
722				t.Errorf("Read(buf) = %d, %v, want %d, nil", n, err, x)
723			}
724			c.Close()
725			<-done
726		})
727	}
728}
729
730func TestCopyPipeIntoTCP(t *testing.T) {
731	ln, err := newLocalListener("tcp")
732	if err != nil {
733		t.Fatal(err)
734	}
735	defer ln.Close()
736
737	errc := make(chan error, 1)
738	defer func() {
739		if err := <-errc; err != nil {
740			t.Error(err)
741		}
742	}()
743	go func() {
744		c, err := ln.Accept()
745		if err != nil {
746			errc <- err
747			return
748		}
749		defer c.Close()
750
751		buf := make([]byte, 100)
752		n, err := io.ReadFull(c, buf)
753		if err != io.ErrUnexpectedEOF || n != 2 {
754			errc <- fmt.Errorf("got err=%q n=%v; want err=%q n=2", err, n, io.ErrUnexpectedEOF)
755			return
756		}
757
758		errc <- nil
759	}()
760
761	c, err := Dial("tcp", ln.Addr().String())
762	if err != nil {
763		t.Fatal(err)
764	}
765	defer c.Close()
766
767	r, w, err := os.Pipe()
768	if err != nil {
769		t.Fatal(err)
770	}
771	defer r.Close()
772
773	errc2 := make(chan error, 1)
774	defer func() {
775		if err := <-errc2; err != nil {
776			t.Error(err)
777		}
778	}()
779
780	defer w.Close()
781
782	go func() {
783		_, err := io.Copy(c, r)
784		errc2 <- err
785	}()
786
787	// Split write into 2 packets. That makes Windows TransmitFile
788	// drop second packet.
789	packet := make([]byte, 1)
790	_, err = w.Write(packet)
791	if err != nil {
792		t.Fatal(err)
793	}
794	time.Sleep(100 * time.Millisecond)
795	_, err = w.Write(packet)
796	if err != nil {
797		t.Fatal(err)
798	}
799}
800
801func BenchmarkSetReadDeadline(b *testing.B) {
802	ln, err := newLocalListener("tcp")
803	if err != nil {
804		b.Fatal(err)
805	}
806	defer ln.Close()
807	var serv Conn
808	done := make(chan error)
809	go func() {
810		var err error
811		serv, err = ln.Accept()
812		done <- err
813	}()
814	c, err := Dial("tcp", ln.Addr().String())
815	if err != nil {
816		b.Fatal(err)
817	}
818	defer c.Close()
819	if err := <-done; err != nil {
820		b.Fatal(err)
821	}
822	defer serv.Close()
823	c.SetWriteDeadline(time.Now().Add(2 * time.Hour))
824	deadline := time.Now().Add(time.Hour)
825	b.ResetTimer()
826	for i := 0; i < b.N; i++ {
827		c.SetReadDeadline(deadline)
828		deadline = deadline.Add(1)
829	}
830}
831