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