Home | History | Annotate | Download | only in net
      1 // Copyright 2013 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 	"errors"
      9 	"fmt"
     10 	"io/ioutil"
     11 	"os"
     12 	"sync"
     13 	"testing"
     14 	"time"
     15 )
     16 
     17 // testUnixAddr uses ioutil.TempFile to get a name that is unique.
     18 // It also uses /tmp directory in case it is prohibited to create UNIX
     19 // sockets in TMPDIR.
     20 func testUnixAddr() string {
     21 	f, err := ioutil.TempFile("", "go-nettest")
     22 	if err != nil {
     23 		panic(err)
     24 	}
     25 	addr := f.Name()
     26 	f.Close()
     27 	os.Remove(addr)
     28 	return addr
     29 }
     30 
     31 func newLocalListener(network string) (Listener, error) {
     32 	switch network {
     33 	case "tcp", "tcp4", "tcp6":
     34 		if supportsIPv4 {
     35 			return Listen("tcp4", "127.0.0.1:0")
     36 		}
     37 		if supportsIPv6 {
     38 			return Listen("tcp6", "[::1]:0")
     39 		}
     40 	case "unix", "unixpacket":
     41 		return Listen(network, testUnixAddr())
     42 	}
     43 	return nil, fmt.Errorf("%s is not supported", network)
     44 }
     45 
     46 func newDualStackListener() (lns []*TCPListener, err error) {
     47 	var args = []struct {
     48 		network string
     49 		TCPAddr
     50 	}{
     51 		{"tcp4", TCPAddr{IP: IPv4(127, 0, 0, 1)}},
     52 		{"tcp6", TCPAddr{IP: IPv6loopback}},
     53 	}
     54 	for i := 0; i < 64; i++ {
     55 		var port int
     56 		var lns []*TCPListener
     57 		for _, arg := range args {
     58 			arg.TCPAddr.Port = port
     59 			ln, err := ListenTCP(arg.network, &arg.TCPAddr)
     60 			if err != nil {
     61 				continue
     62 			}
     63 			port = ln.Addr().(*TCPAddr).Port
     64 			lns = append(lns, ln)
     65 		}
     66 		if len(lns) != len(args) {
     67 			for _, ln := range lns {
     68 				ln.Close()
     69 			}
     70 			continue
     71 		}
     72 		return lns, nil
     73 	}
     74 	return nil, errors.New("no dualstack port available")
     75 }
     76 
     77 type localServer struct {
     78 	lnmu sync.RWMutex
     79 	Listener
     80 	done chan bool // signal that indicates server stopped
     81 }
     82 
     83 func (ls *localServer) buildup(handler func(*localServer, Listener)) error {
     84 	go func() {
     85 		handler(ls, ls.Listener)
     86 		close(ls.done)
     87 	}()
     88 	return nil
     89 }
     90 
     91 func (ls *localServer) teardown() error {
     92 	ls.lnmu.Lock()
     93 	if ls.Listener != nil {
     94 		network := ls.Listener.Addr().Network()
     95 		address := ls.Listener.Addr().String()
     96 		ls.Listener.Close()
     97 		<-ls.done
     98 		ls.Listener = nil
     99 		switch network {
    100 		case "unix", "unixpacket":
    101 			os.Remove(address)
    102 		}
    103 	}
    104 	ls.lnmu.Unlock()
    105 	return nil
    106 }
    107 
    108 func newLocalServer(network string) (*localServer, error) {
    109 	ln, err := newLocalListener(network)
    110 	if err != nil {
    111 		return nil, err
    112 	}
    113 	return &localServer{Listener: ln, done: make(chan bool)}, nil
    114 }
    115 
    116 type streamListener struct {
    117 	network, address string
    118 	Listener
    119 	done chan bool // signal that indicates server stopped
    120 }
    121 
    122 func (sl *streamListener) newLocalServer() (*localServer, error) {
    123 	return &localServer{Listener: sl.Listener, done: make(chan bool)}, nil
    124 }
    125 
    126 type dualStackServer struct {
    127 	lnmu sync.RWMutex
    128 	lns  []streamListener
    129 	port string
    130 
    131 	cmu sync.RWMutex
    132 	cs  []Conn // established connections at the passive open side
    133 }
    134 
    135 func (dss *dualStackServer) buildup(handler func(*dualStackServer, Listener)) error {
    136 	for i := range dss.lns {
    137 		go func(i int) {
    138 			handler(dss, dss.lns[i].Listener)
    139 			close(dss.lns[i].done)
    140 		}(i)
    141 	}
    142 	return nil
    143 }
    144 
    145 func (dss *dualStackServer) putConn(c Conn) error {
    146 	dss.cmu.Lock()
    147 	dss.cs = append(dss.cs, c)
    148 	dss.cmu.Unlock()
    149 	return nil
    150 }
    151 
    152 func (dss *dualStackServer) teardownNetwork(network string) error {
    153 	dss.lnmu.Lock()
    154 	for i := range dss.lns {
    155 		if network == dss.lns[i].network && dss.lns[i].Listener != nil {
    156 			dss.lns[i].Listener.Close()
    157 			<-dss.lns[i].done
    158 			dss.lns[i].Listener = nil
    159 		}
    160 	}
    161 	dss.lnmu.Unlock()
    162 	return nil
    163 }
    164 
    165 func (dss *dualStackServer) teardown() error {
    166 	dss.lnmu.Lock()
    167 	for i := range dss.lns {
    168 		if dss.lns[i].Listener != nil {
    169 			dss.lns[i].Listener.Close()
    170 			<-dss.lns[i].done
    171 		}
    172 	}
    173 	dss.lns = dss.lns[:0]
    174 	dss.lnmu.Unlock()
    175 	dss.cmu.Lock()
    176 	for _, c := range dss.cs {
    177 		c.Close()
    178 	}
    179 	dss.cs = dss.cs[:0]
    180 	dss.cmu.Unlock()
    181 	return nil
    182 }
    183 
    184 func newDualStackServer(lns []streamListener) (*dualStackServer, error) {
    185 	dss := &dualStackServer{lns: lns, port: "0"}
    186 	for i := range dss.lns {
    187 		ln, err := Listen(dss.lns[i].network, JoinHostPort(dss.lns[i].address, dss.port))
    188 		if err != nil {
    189 			for _, ln := range dss.lns[:i] {
    190 				ln.Listener.Close()
    191 			}
    192 			return nil, err
    193 		}
    194 		dss.lns[i].Listener = ln
    195 		dss.lns[i].done = make(chan bool)
    196 		if dss.port == "0" {
    197 			if _, dss.port, err = SplitHostPort(ln.Addr().String()); err != nil {
    198 				for _, ln := range dss.lns {
    199 					ln.Listener.Close()
    200 				}
    201 				return nil, err
    202 			}
    203 		}
    204 	}
    205 	return dss, nil
    206 }
    207 
    208 func transponder(ln Listener, ch chan<- error) {
    209 	defer close(ch)
    210 
    211 	switch ln := ln.(type) {
    212 	case *TCPListener:
    213 		ln.SetDeadline(time.Now().Add(someTimeout))
    214 	case *UnixListener:
    215 		ln.SetDeadline(time.Now().Add(someTimeout))
    216 	}
    217 	c, err := ln.Accept()
    218 	if err != nil {
    219 		if perr := parseAcceptError(err); perr != nil {
    220 			ch <- perr
    221 		}
    222 		ch <- err
    223 		return
    224 	}
    225 	defer c.Close()
    226 
    227 	network := ln.Addr().Network()
    228 	if c.LocalAddr().Network() != network || c.LocalAddr().Network() != network {
    229 		ch <- fmt.Errorf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), network, network)
    230 		return
    231 	}
    232 	c.SetDeadline(time.Now().Add(someTimeout))
    233 	c.SetReadDeadline(time.Now().Add(someTimeout))
    234 	c.SetWriteDeadline(time.Now().Add(someTimeout))
    235 
    236 	b := make([]byte, 256)
    237 	n, err := c.Read(b)
    238 	if err != nil {
    239 		if perr := parseReadError(err); perr != nil {
    240 			ch <- perr
    241 		}
    242 		ch <- err
    243 		return
    244 	}
    245 	if _, err := c.Write(b[:n]); err != nil {
    246 		if perr := parseWriteError(err); perr != nil {
    247 			ch <- perr
    248 		}
    249 		ch <- err
    250 		return
    251 	}
    252 }
    253 
    254 func transceiver(c Conn, wb []byte, ch chan<- error) {
    255 	defer close(ch)
    256 
    257 	c.SetDeadline(time.Now().Add(someTimeout))
    258 	c.SetReadDeadline(time.Now().Add(someTimeout))
    259 	c.SetWriteDeadline(time.Now().Add(someTimeout))
    260 
    261 	n, err := c.Write(wb)
    262 	if err != nil {
    263 		if perr := parseWriteError(err); perr != nil {
    264 			ch <- perr
    265 		}
    266 		ch <- err
    267 		return
    268 	}
    269 	if n != len(wb) {
    270 		ch <- fmt.Errorf("wrote %d; want %d", n, len(wb))
    271 	}
    272 	rb := make([]byte, len(wb))
    273 	n, err = c.Read(rb)
    274 	if err != nil {
    275 		if perr := parseReadError(err); perr != nil {
    276 			ch <- perr
    277 		}
    278 		ch <- err
    279 		return
    280 	}
    281 	if n != len(wb) {
    282 		ch <- fmt.Errorf("read %d; want %d", n, len(wb))
    283 	}
    284 }
    285 
    286 func timeoutReceiver(c Conn, d, min, max time.Duration, ch chan<- error) {
    287 	var err error
    288 	defer func() { ch <- err }()
    289 
    290 	t0 := time.Now()
    291 	if err = c.SetReadDeadline(time.Now().Add(d)); err != nil {
    292 		return
    293 	}
    294 	b := make([]byte, 256)
    295 	var n int
    296 	n, err = c.Read(b)
    297 	t1 := time.Now()
    298 	if n != 0 || err == nil || !err.(Error).Timeout() {
    299 		err = fmt.Errorf("Read did not return (0, timeout): (%d, %v)", n, err)
    300 		return
    301 	}
    302 	if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() {
    303 		err = fmt.Errorf("Read took %s; expected %s", dt, d)
    304 		return
    305 	}
    306 }
    307 
    308 func timeoutTransmitter(c Conn, d, min, max time.Duration, ch chan<- error) {
    309 	var err error
    310 	defer func() { ch <- err }()
    311 
    312 	t0 := time.Now()
    313 	if err = c.SetWriteDeadline(time.Now().Add(d)); err != nil {
    314 		return
    315 	}
    316 	var n int
    317 	for {
    318 		n, err = c.Write([]byte("TIMEOUT TRANSMITTER"))
    319 		if err != nil {
    320 			break
    321 		}
    322 	}
    323 	t1 := time.Now()
    324 	if err == nil || !err.(Error).Timeout() {
    325 		err = fmt.Errorf("Write did not return (any, timeout): (%d, %v)", n, err)
    326 		return
    327 	}
    328 	if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() {
    329 		err = fmt.Errorf("Write took %s; expected %s", dt, d)
    330 		return
    331 	}
    332 }
    333 
    334 func newLocalPacketListener(network string) (PacketConn, error) {
    335 	switch network {
    336 	case "udp", "udp4", "udp6":
    337 		if supportsIPv4 {
    338 			return ListenPacket("udp4", "127.0.0.1:0")
    339 		}
    340 		if supportsIPv6 {
    341 			return ListenPacket("udp6", "[::1]:0")
    342 		}
    343 	case "unixgram":
    344 		return ListenPacket(network, testUnixAddr())
    345 	}
    346 	return nil, fmt.Errorf("%s is not supported", network)
    347 }
    348 
    349 func newDualStackPacketListener() (cs []*UDPConn, err error) {
    350 	var args = []struct {
    351 		network string
    352 		UDPAddr
    353 	}{
    354 		{"udp4", UDPAddr{IP: IPv4(127, 0, 0, 1)}},
    355 		{"udp6", UDPAddr{IP: IPv6loopback}},
    356 	}
    357 	for i := 0; i < 64; i++ {
    358 		var port int
    359 		var cs []*UDPConn
    360 		for _, arg := range args {
    361 			arg.UDPAddr.Port = port
    362 			c, err := ListenUDP(arg.network, &arg.UDPAddr)
    363 			if err != nil {
    364 				continue
    365 			}
    366 			port = c.LocalAddr().(*UDPAddr).Port
    367 			cs = append(cs, c)
    368 		}
    369 		if len(cs) != len(args) {
    370 			for _, c := range cs {
    371 				c.Close()
    372 			}
    373 			continue
    374 		}
    375 		return cs, nil
    376 	}
    377 	return nil, errors.New("no dualstack port available")
    378 }
    379 
    380 type localPacketServer struct {
    381 	pcmu sync.RWMutex
    382 	PacketConn
    383 	done chan bool // signal that indicates server stopped
    384 }
    385 
    386 func (ls *localPacketServer) buildup(handler func(*localPacketServer, PacketConn)) error {
    387 	go func() {
    388 		handler(ls, ls.PacketConn)
    389 		close(ls.done)
    390 	}()
    391 	return nil
    392 }
    393 
    394 func (ls *localPacketServer) teardown() error {
    395 	ls.pcmu.Lock()
    396 	if ls.PacketConn != nil {
    397 		network := ls.PacketConn.LocalAddr().Network()
    398 		address := ls.PacketConn.LocalAddr().String()
    399 		ls.PacketConn.Close()
    400 		<-ls.done
    401 		ls.PacketConn = nil
    402 		switch network {
    403 		case "unixgram":
    404 			os.Remove(address)
    405 		}
    406 	}
    407 	ls.pcmu.Unlock()
    408 	return nil
    409 }
    410 
    411 func newLocalPacketServer(network string) (*localPacketServer, error) {
    412 	c, err := newLocalPacketListener(network)
    413 	if err != nil {
    414 		return nil, err
    415 	}
    416 	return &localPacketServer{PacketConn: c, done: make(chan bool)}, nil
    417 }
    418 
    419 type packetListener struct {
    420 	PacketConn
    421 }
    422 
    423 func (pl *packetListener) newLocalServer() (*localPacketServer, error) {
    424 	return &localPacketServer{PacketConn: pl.PacketConn, done: make(chan bool)}, nil
    425 }
    426 
    427 func packetTransponder(c PacketConn, ch chan<- error) {
    428 	defer close(ch)
    429 
    430 	c.SetDeadline(time.Now().Add(someTimeout))
    431 	c.SetReadDeadline(time.Now().Add(someTimeout))
    432 	c.SetWriteDeadline(time.Now().Add(someTimeout))
    433 
    434 	b := make([]byte, 256)
    435 	n, peer, err := c.ReadFrom(b)
    436 	if err != nil {
    437 		if perr := parseReadError(err); perr != nil {
    438 			ch <- perr
    439 		}
    440 		ch <- err
    441 		return
    442 	}
    443 	if peer == nil { // for connected-mode sockets
    444 		switch c.LocalAddr().Network() {
    445 		case "udp":
    446 			peer, err = ResolveUDPAddr("udp", string(b[:n]))
    447 		case "unixgram":
    448 			peer, err = ResolveUnixAddr("unixgram", string(b[:n]))
    449 		}
    450 		if err != nil {
    451 			ch <- err
    452 			return
    453 		}
    454 	}
    455 	if _, err := c.WriteTo(b[:n], peer); err != nil {
    456 		if perr := parseWriteError(err); perr != nil {
    457 			ch <- perr
    458 		}
    459 		ch <- err
    460 		return
    461 	}
    462 }
    463 
    464 func packetTransceiver(c PacketConn, wb []byte, dst Addr, ch chan<- error) {
    465 	defer close(ch)
    466 
    467 	c.SetDeadline(time.Now().Add(someTimeout))
    468 	c.SetReadDeadline(time.Now().Add(someTimeout))
    469 	c.SetWriteDeadline(time.Now().Add(someTimeout))
    470 
    471 	n, err := c.WriteTo(wb, dst)
    472 	if err != nil {
    473 		if perr := parseWriteError(err); perr != nil {
    474 			ch <- perr
    475 		}
    476 		ch <- err
    477 		return
    478 	}
    479 	if n != len(wb) {
    480 		ch <- fmt.Errorf("wrote %d; want %d", n, len(wb))
    481 	}
    482 	rb := make([]byte, len(wb))
    483 	n, _, err = c.ReadFrom(rb)
    484 	if err != nil {
    485 		if perr := parseReadError(err); perr != nil {
    486 			ch <- perr
    487 		}
    488 		ch <- err
    489 		return
    490 	}
    491 	if n != len(wb) {
    492 		ch <- fmt.Errorf("read %d; want %d", n, len(wb))
    493 	}
    494 }
    495 
    496 func timeoutPacketReceiver(c PacketConn, d, min, max time.Duration, ch chan<- error) {
    497 	var err error
    498 	defer func() { ch <- err }()
    499 
    500 	t0 := time.Now()
    501 	if err = c.SetReadDeadline(time.Now().Add(d)); err != nil {
    502 		return
    503 	}
    504 	b := make([]byte, 256)
    505 	var n int
    506 	n, _, err = c.ReadFrom(b)
    507 	t1 := time.Now()
    508 	if n != 0 || err == nil || !err.(Error).Timeout() {
    509 		err = fmt.Errorf("ReadFrom did not return (0, timeout): (%d, %v)", n, err)
    510 		return
    511 	}
    512 	if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() {
    513 		err = fmt.Errorf("ReadFrom took %s; expected %s", dt, d)
    514 		return
    515 	}
    516 }
    517