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.
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
20 func testUnixAddr() string {
21 f
, err
:= ioutil
.TempFile("", "go-nettest")
31 func newLocalListener(network
string) (Listener
, error
) {
35 if ln
, err
:= Listen("tcp4", "127.0.0.1:0"); err
== nil {
40 return Listen("tcp6", "[::1]:0")
44 return Listen("tcp4", "127.0.0.1:0")
48 return Listen("tcp6", "[::1]:0")
50 case "unix", "unixpacket":
51 return Listen(network
, testUnixAddr())
53 return nil, fmt
.Errorf("%s is not supported", network
)
56 func newDualStackListener() (lns
[]*TCPListener
, err error
) {
61 {"tcp4", TCPAddr
{IP
: IPv4(127, 0, 0, 1)}},
62 {"tcp6", TCPAddr
{IP
: IPv6loopback
}},
64 for i
:= 0; i
< 64; i
++ {
66 var lns
[]*TCPListener
67 for _
, arg
:= range args
{
68 arg
.TCPAddr
.Port
= port
69 ln
, err
:= ListenTCP(arg
.network
, &arg
.TCPAddr
)
73 port
= ln
.Addr().(*TCPAddr
).Port
76 if len(lns
) != len(args
) {
77 for _
, ln
:= range lns
{
84 return nil, errors
.New("no dualstack port available")
87 type localServer
struct {
90 done
chan bool // signal that indicates server stopped
93 func (ls
*localServer
) buildup(handler
func(*localServer
, Listener
)) error
{
95 handler(ls
, ls
.Listener
)
101 func (ls
*localServer
) teardown() error
{
103 if ls
.Listener
!= nil {
104 network
:= ls
.Listener
.Addr().Network()
105 address
:= ls
.Listener
.Addr().String()
110 case "unix", "unixpacket":
118 func newLocalServer(network
string) (*localServer
, error
) {
119 ln
, err
:= newLocalListener(network
)
123 return &localServer
{Listener
: ln
, done
: make(chan bool)}, nil
126 type streamListener
struct {
127 network
, address
string
129 done
chan bool // signal that indicates server stopped
132 func (sl
*streamListener
) newLocalServer() (*localServer
, error
) {
133 return &localServer
{Listener
: sl
.Listener
, done
: make(chan bool)}, nil
136 type dualStackServer
struct {
142 cs
[]Conn
// established connections at the passive open side
145 func (dss
*dualStackServer
) buildup(handler
func(*dualStackServer
, Listener
)) error
{
146 for i
:= range dss
.lns
{
148 handler(dss
, dss
.lns
[i
].Listener
)
149 close(dss
.lns
[i
].done
)
155 func (dss
*dualStackServer
) teardownNetwork(network
string) error
{
157 for i
:= range dss
.lns
{
158 if network
== dss
.lns
[i
].network
&& dss
.lns
[i
].Listener
!= nil {
159 dss
.lns
[i
].Listener
.Close()
161 dss
.lns
[i
].Listener
= nil
168 func (dss
*dualStackServer
) teardown() error
{
170 for i
:= range dss
.lns
{
171 if dss
.lns
[i
].Listener
!= nil {
172 dss
.lns
[i
].Listener
.Close()
176 dss
.lns
= dss
.lns
[:0]
179 for _
, c
:= range dss
.cs
{
187 func newDualStackServer() (*dualStackServer
, error
) {
188 lns
, err
:= newDualStackListener()
192 _
, port
, err
:= SplitHostPort(lns
[0].Addr().String())
198 return &dualStackServer
{
199 lns
: []streamListener
{
200 {network
: "tcp4", address
: lns
[0].Addr().String(), Listener
: lns
[0], done
: make(chan bool)},
201 {network
: "tcp6", address
: lns
[1].Addr().String(), Listener
: lns
[1], done
: make(chan bool)},
207 func transponder(ln Listener
, ch
chan<- error
) {
210 switch ln
:= ln
.(type) {
212 ln
.SetDeadline(time
.Now().Add(someTimeout
))
214 ln
.SetDeadline(time
.Now().Add(someTimeout
))
216 c
, err
:= ln
.Accept()
218 if perr
:= parseAcceptError(err
); perr
!= nil {
226 network
:= ln
.Addr().Network()
227 if c
.LocalAddr().Network() != network || c
.RemoteAddr().Network() != network
{
228 ch
<- fmt
.Errorf("got %v->%v; expected %v->%v", c
.LocalAddr().Network(), c
.RemoteAddr().Network(), network
, network
)
231 c
.SetDeadline(time
.Now().Add(someTimeout
))
232 c
.SetReadDeadline(time
.Now().Add(someTimeout
))
233 c
.SetWriteDeadline(time
.Now().Add(someTimeout
))
235 b
:= make([]byte, 256)
238 if perr
:= parseReadError(err
); perr
!= nil {
244 if _
, err
:= c
.Write(b
[:n
]); err
!= nil {
245 if perr
:= parseWriteError(err
); perr
!= nil {
253 func transceiver(c Conn
, wb
[]byte, ch
chan<- error
) {
256 c
.SetDeadline(time
.Now().Add(someTimeout
))
257 c
.SetReadDeadline(time
.Now().Add(someTimeout
))
258 c
.SetWriteDeadline(time
.Now().Add(someTimeout
))
260 n
, err
:= c
.Write(wb
)
262 if perr
:= parseWriteError(err
); perr
!= nil {
269 ch
<- fmt
.Errorf("wrote %d; want %d", n
, len(wb
))
271 rb
:= make([]byte, len(wb
))
274 if perr
:= parseReadError(err
); perr
!= nil {
281 ch
<- fmt
.Errorf("read %d; want %d", n
, len(wb
))
285 func timeoutReceiver(c Conn
, d
, min
, max time
.Duration
, ch
chan<- error
) {
287 defer func() { ch
<- err
}()
290 if err
= c
.SetReadDeadline(time
.Now().Add(d
)); err
!= nil {
293 b
:= make([]byte, 256)
297 if n
!= 0 || err
== nil ||
!err
.(Error
).Timeout() {
298 err
= fmt
.Errorf("Read did not return (0, timeout): (%d, %v)", n
, err
)
301 if dt
:= t1
.Sub(t0
); min
> dt || dt
> max
&& !testing
.Short() {
302 err
= fmt
.Errorf("Read took %s; expected %s", dt
, d
)
307 func timeoutTransmitter(c Conn
, d
, min
, max time
.Duration
, ch
chan<- error
) {
309 defer func() { ch
<- err
}()
312 if err
= c
.SetWriteDeadline(time
.Now().Add(d
)); err
!= nil {
317 n
, err
= c
.Write([]byte("TIMEOUT TRANSMITTER"))
323 if err
== nil ||
!err
.(Error
).Timeout() {
324 err
= fmt
.Errorf("Write did not return (any, timeout): (%d, %v)", n
, err
)
327 if dt
:= t1
.Sub(t0
); min
> dt || dt
> max
&& !testing
.Short() {
328 err
= fmt
.Errorf("Write took %s; expected %s", dt
, d
)
333 func newLocalPacketListener(network
string) (PacketConn
, error
) {
337 return ListenPacket("udp4", "127.0.0.1:0")
340 return ListenPacket("udp6", "[::1]:0")
344 return ListenPacket("udp4", "127.0.0.1:0")
348 return ListenPacket("udp6", "[::1]:0")
351 return ListenPacket(network
, testUnixAddr())
353 return nil, fmt
.Errorf("%s is not supported", network
)
356 func newDualStackPacketListener() (cs
[]*UDPConn
, err error
) {
357 var args
= []struct {
361 {"udp4", UDPAddr
{IP
: IPv4(127, 0, 0, 1)}},
362 {"udp6", UDPAddr
{IP
: IPv6loopback
}},
364 for i
:= 0; i
< 64; i
++ {
367 for _
, arg
:= range args
{
368 arg
.UDPAddr
.Port
= port
369 c
, err
:= ListenUDP(arg
.network
, &arg
.UDPAddr
)
373 port
= c
.LocalAddr().(*UDPAddr
).Port
376 if len(cs
) != len(args
) {
377 for _
, c
:= range cs
{
384 return nil, errors
.New("no dualstack port available")
387 type localPacketServer
struct {
390 done
chan bool // signal that indicates server stopped
393 func (ls
*localPacketServer
) buildup(handler
func(*localPacketServer
, PacketConn
)) error
{
395 handler(ls
, ls
.PacketConn
)
401 func (ls
*localPacketServer
) teardown() error
{
403 if ls
.PacketConn
!= nil {
404 network
:= ls
.PacketConn
.LocalAddr().Network()
405 address
:= ls
.PacketConn
.LocalAddr().String()
406 ls
.PacketConn
.Close()
418 func newLocalPacketServer(network
string) (*localPacketServer
, error
) {
419 c
, err
:= newLocalPacketListener(network
)
423 return &localPacketServer
{PacketConn
: c
, done
: make(chan bool)}, nil
426 type packetListener
struct {
430 func (pl
*packetListener
) newLocalServer() (*localPacketServer
, error
) {
431 return &localPacketServer
{PacketConn
: pl
.PacketConn
, done
: make(chan bool)}, nil
434 func packetTransponder(c PacketConn
, ch
chan<- error
) {
437 c
.SetDeadline(time
.Now().Add(someTimeout
))
438 c
.SetReadDeadline(time
.Now().Add(someTimeout
))
439 c
.SetWriteDeadline(time
.Now().Add(someTimeout
))
441 b
:= make([]byte, 256)
442 n
, peer
, err
:= c
.ReadFrom(b
)
444 if perr
:= parseReadError(err
); perr
!= nil {
450 if peer
== nil { // for connected-mode sockets
451 switch c
.LocalAddr().Network() {
453 peer
, err
= ResolveUDPAddr("udp", string(b
[:n
]))
455 peer
, err
= ResolveUnixAddr("unixgram", string(b
[:n
]))
462 if _
, err
:= c
.WriteTo(b
[:n
], peer
); err
!= nil {
463 if perr
:= parseWriteError(err
); perr
!= nil {
471 func packetTransceiver(c PacketConn
, wb
[]byte, dst Addr
, ch
chan<- error
) {
474 c
.SetDeadline(time
.Now().Add(someTimeout
))
475 c
.SetReadDeadline(time
.Now().Add(someTimeout
))
476 c
.SetWriteDeadline(time
.Now().Add(someTimeout
))
478 n
, err
:= c
.WriteTo(wb
, dst
)
480 if perr
:= parseWriteError(err
); perr
!= nil {
487 ch
<- fmt
.Errorf("wrote %d; want %d", n
, len(wb
))
489 rb
:= make([]byte, len(wb
))
490 n
, _
, err
= c
.ReadFrom(rb
)
492 if perr
:= parseReadError(err
); perr
!= nil {
499 ch
<- fmt
.Errorf("read %d; want %d", n
, len(wb
))
503 func timeoutPacketReceiver(c PacketConn
, d
, min
, max time
.Duration
, ch
chan<- error
) {
505 defer func() { ch
<- err
}()
508 if err
= c
.SetReadDeadline(time
.Now().Add(d
)); err
!= nil {
511 b
:= make([]byte, 256)
513 n
, _
, err
= c
.ReadFrom(b
)
515 if n
!= 0 || err
== nil ||
!err
.(Error
).Timeout() {
516 err
= fmt
.Errorf("ReadFrom did not return (0, timeout): (%d, %v)", n
, err
)
519 if dt
:= t1
.Sub(t0
); min
> dt || dt
> max
&& !testing
.Short() {
520 err
= fmt
.Errorf("ReadFrom took %s; expected %s", dt
, d
)