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.
5 //go:build !js && !plan9
20 func (ln
*TCPListener
) port() string {
21 _
, port
, err
:= SplitHostPort(ln
.Addr().String())
28 func (c
*UDPConn
) port() string {
29 _
, port
, err
:= SplitHostPort(c
.LocalAddr().String())
36 var tcpListenerTests
= []struct {
42 {"tcp", "::ffff:0.0.0.0"},
46 {"tcp", "::ffff:127.0.0.1"},
51 {"tcp4", "::ffff:0.0.0.0"},
53 {"tcp4", "127.0.0.1"},
54 {"tcp4", "::ffff:127.0.0.1"},
62 // TestTCPListener tests both single and double listen to a test
63 // listener with same address family, same listening address and
65 func TestTCPListener(t
*testing
.T
) {
68 t
.Skipf("not supported on %s", runtime
.GOOS
)
71 for _
, tt
:= range tcpListenerTests
{
72 if !testableListenArgs(tt
.network
, JoinHostPort(tt
.address
, "0"), "") {
73 t
.Logf("skipping %s test", tt
.network
+" "+tt
.address
)
77 ln1
, err
:= Listen(tt
.network
, JoinHostPort(tt
.address
, "0"))
81 if err
:= checkFirstListener(tt
.network
, ln1
); err
!= nil {
85 ln2
, err
:= Listen(tt
.network
, JoinHostPort(tt
.address
, ln1
.(*TCPListener
).port()))
89 if err
:= checkSecondListener(tt
.network
, tt
.address
, err
); err
!= nil {
97 var udpListenerTests
= []struct {
103 {"udp", "::ffff:0.0.0.0"},
106 {"udp", "127.0.0.1"},
107 {"udp", "::ffff:127.0.0.1"},
112 {"udp4", "::ffff:0.0.0.0"},
114 {"udp4", "127.0.0.1"},
115 {"udp4", "::ffff:127.0.0.1"},
123 // TestUDPListener tests both single and double listen to a test
124 // listener with same address family, same listening address and
126 func TestUDPListener(t
*testing
.T
) {
127 switch runtime
.GOOS
{
129 t
.Skipf("not supported on %s", runtime
.GOOS
)
132 for _
, tt
:= range udpListenerTests
{
133 if !testableListenArgs(tt
.network
, JoinHostPort(tt
.address
, "0"), "") {
134 t
.Logf("skipping %s test", tt
.network
+" "+tt
.address
)
138 c1
, err
:= ListenPacket(tt
.network
, JoinHostPort(tt
.address
, "0"))
142 if err
:= checkFirstListener(tt
.network
, c1
); err
!= nil {
146 c2
, err
:= ListenPacket(tt
.network
, JoinHostPort(tt
.address
, c1
.(*UDPConn
).port()))
150 if err
:= checkSecondListener(tt
.network
, tt
.address
, err
); err
!= nil {
158 var dualStackTCPListenerTests
= []struct {
159 network1
, address1
string // first listener
160 network2
, address2
string // second listener
161 xerr error
// expected error value, nil or other
163 // Test cases and expected results for the attempting 2nd listen on the same port
164 // 1st listen 2nd listen darwin freebsd linux openbsd
165 // ------------------------------------------------------------------------------------
166 // "tcp" "" "tcp" "" - - - -
167 // "tcp" "" "tcp" "0.0.0.0" - - - -
168 // "tcp" "0.0.0.0" "tcp" "" - - - -
169 // ------------------------------------------------------------------------------------
170 // "tcp" "" "tcp" "[::]" - - - ok
171 // "tcp" "[::]" "tcp" "" - - - ok
172 // "tcp" "0.0.0.0" "tcp" "[::]" - - - ok
173 // "tcp" "[::]" "tcp" "0.0.0.0" - - - ok
174 // "tcp" "[::ffff:0.0.0.0]" "tcp" "[::]" - - - ok
175 // "tcp" "[::]" "tcp" "[::ffff:0.0.0.0]" - - - ok
176 // ------------------------------------------------------------------------------------
177 // "tcp4" "" "tcp6" "" ok ok ok ok
178 // "tcp6" "" "tcp4" "" ok ok ok ok
179 // "tcp4" "0.0.0.0" "tcp6" "[::]" ok ok ok ok
180 // "tcp6" "[::]" "tcp4" "0.0.0.0" ok ok ok ok
181 // ------------------------------------------------------------------------------------
182 // "tcp" "127.0.0.1" "tcp" "[::1]" ok ok ok ok
183 // "tcp" "[::1]" "tcp" "127.0.0.1" ok ok ok ok
184 // "tcp4" "127.0.0.1" "tcp6" "[::1]" ok ok ok ok
185 // "tcp6" "[::1]" "tcp4" "127.0.0.1" ok ok ok ok
187 // Platform default configurations:
188 // darwin, kernel version 11.3.0
189 // net.inet6.ip6.v6only=0 (overridable by sysctl or IPV6_V6ONLY option)
190 // freebsd, kernel version 8.2
191 // net.inet6.ip6.v6only=1 (overridable by sysctl or IPV6_V6ONLY option)
192 // linux, kernel version 3.0.0
193 // net.ipv6.bindv6only=0 (overridable by sysctl or IPV6_V6ONLY option)
194 // openbsd, kernel version 5.0
195 // net.inet6.ip6.v6only=1 (overriding is prohibited)
197 {"tcp", "", "tcp", "", syscall
.EADDRINUSE
},
198 {"tcp", "", "tcp", "0.0.0.0", syscall
.EADDRINUSE
},
199 {"tcp", "0.0.0.0", "tcp", "", syscall
.EADDRINUSE
},
201 {"tcp", "", "tcp", "::", syscall
.EADDRINUSE
},
202 {"tcp", "::", "tcp", "", syscall
.EADDRINUSE
},
203 {"tcp", "0.0.0.0", "tcp", "::", syscall
.EADDRINUSE
},
204 {"tcp", "::", "tcp", "0.0.0.0", syscall
.EADDRINUSE
},
205 {"tcp", "::ffff:0.0.0.0", "tcp", "::", syscall
.EADDRINUSE
},
206 {"tcp", "::", "tcp", "::ffff:0.0.0.0", syscall
.EADDRINUSE
},
208 {"tcp4", "", "tcp6", "", nil},
209 {"tcp6", "", "tcp4", "", nil},
210 {"tcp4", "0.0.0.0", "tcp6", "::", nil},
211 {"tcp6", "::", "tcp4", "0.0.0.0", nil},
213 {"tcp", "127.0.0.1", "tcp", "::1", nil},
214 {"tcp", "::1", "tcp", "127.0.0.1", nil},
215 {"tcp4", "127.0.0.1", "tcp6", "::1", nil},
216 {"tcp6", "::1", "tcp4", "127.0.0.1", nil},
219 // TestDualStackTCPListener tests both single and double listen
220 // to a test listener with various address families, different
221 // listening address and same port.
223 // On DragonFly BSD, we expect the kernel version of node under test
224 // to be greater than or equal to 4.4.
225 func TestDualStackTCPListener(t
*testing
.T
) {
226 switch runtime
.GOOS
{
228 t
.Skipf("not supported on %s", runtime
.GOOS
)
230 if !supportsIPv4() ||
!supportsIPv6() {
231 t
.Skip("both IPv4 and IPv6 are required")
234 for _
, tt
:= range dualStackTCPListenerTests
{
235 if !testableListenArgs(tt
.network1
, JoinHostPort(tt
.address1
, "0"), "") {
236 t
.Logf("skipping %s test", tt
.network1
+" "+tt
.address1
)
240 if !supportsIPv4map() && differentWildcardAddr(tt
.address1
, tt
.address2
) {
243 var firstErr
, secondErr error
244 for i
:= 0; i
< 5; i
++ {
245 lns
, err
:= newDualStackListener()
249 port
:= lns
[0].port()
250 for _
, ln
:= range lns
{
254 ln1
, firstErr
= Listen(tt
.network1
, JoinHostPort(tt
.address1
, port
))
258 if err
:= checkFirstListener(tt
.network1
, ln1
); err
!= nil {
262 ln2
, err
:= Listen(tt
.network2
, JoinHostPort(tt
.address2
, ln1
.(*TCPListener
).port()))
266 if secondErr
= checkDualStackSecondListener(tt
.network2
, tt
.address2
, err
, tt
.xerr
); secondErr
!= nil {
276 if secondErr
!= nil {
282 var dualStackUDPListenerTests
= []struct {
283 network1
, address1
string // first listener
284 network2
, address2
string // second listener
285 xerr error
// expected error value, nil or other
287 {"udp", "", "udp", "", syscall
.EADDRINUSE
},
288 {"udp", "", "udp", "0.0.0.0", syscall
.EADDRINUSE
},
289 {"udp", "0.0.0.0", "udp", "", syscall
.EADDRINUSE
},
291 {"udp", "", "udp", "::", syscall
.EADDRINUSE
},
292 {"udp", "::", "udp", "", syscall
.EADDRINUSE
},
293 {"udp", "0.0.0.0", "udp", "::", syscall
.EADDRINUSE
},
294 {"udp", "::", "udp", "0.0.0.0", syscall
.EADDRINUSE
},
295 {"udp", "::ffff:0.0.0.0", "udp", "::", syscall
.EADDRINUSE
},
296 {"udp", "::", "udp", "::ffff:0.0.0.0", syscall
.EADDRINUSE
},
298 {"udp4", "", "udp6", "", nil},
299 {"udp6", "", "udp4", "", nil},
300 {"udp4", "0.0.0.0", "udp6", "::", nil},
301 {"udp6", "::", "udp4", "0.0.0.0", nil},
303 {"udp", "127.0.0.1", "udp", "::1", nil},
304 {"udp", "::1", "udp", "127.0.0.1", nil},
305 {"udp4", "127.0.0.1", "udp6", "::1", nil},
306 {"udp6", "::1", "udp4", "127.0.0.1", nil},
309 // TestDualStackUDPListener tests both single and double listen
310 // to a test listener with various address families, different
311 // listening address and same port.
313 // On DragonFly BSD, we expect the kernel version of node under test
314 // to be greater than or equal to 4.4.
315 func TestDualStackUDPListener(t
*testing
.T
) {
316 switch runtime
.GOOS
{
318 t
.Skipf("not supported on %s", runtime
.GOOS
)
320 if !supportsIPv4() ||
!supportsIPv6() {
321 t
.Skip("both IPv4 and IPv6 are required")
324 for _
, tt
:= range dualStackUDPListenerTests
{
325 if !testableListenArgs(tt
.network1
, JoinHostPort(tt
.address1
, "0"), "") {
326 t
.Logf("skipping %s test", tt
.network1
+" "+tt
.address1
)
330 if !supportsIPv4map() && differentWildcardAddr(tt
.address1
, tt
.address2
) {
333 var firstErr
, secondErr error
334 for i
:= 0; i
< 5; i
++ {
335 cs
, err
:= newDualStackPacketListener()
340 for _
, c
:= range cs
{
344 c1
, firstErr
= ListenPacket(tt
.network1
, JoinHostPort(tt
.address1
, port
))
348 if err
:= checkFirstListener(tt
.network1
, c1
); err
!= nil {
352 c2
, err
:= ListenPacket(tt
.network2
, JoinHostPort(tt
.address2
, c1
.(*UDPConn
).port()))
356 if secondErr
= checkDualStackSecondListener(tt
.network2
, tt
.address2
, err
, tt
.xerr
); secondErr
!= nil {
366 if secondErr
!= nil {
372 func differentWildcardAddr(i
, j
string) bool {
373 if (i
== "" || i
== "0.0.0.0" || i
== "::ffff:0.0.0.0") && (j
== "" || j
== "0.0.0.0" || j
== "::ffff:0.0.0.0") {
376 if i
== "[::]" && j
== "[::]" {
382 func checkFirstListener(network
string, ln any
) error
{
385 fd
:= ln
.(*TCPListener
).fd
386 if err
:= checkDualStackAddrFamily(fd
); err
!= nil {
390 fd
:= ln
.(*TCPListener
).fd
391 if fd
.family
!= syscall
.AF_INET
{
392 return fmt
.Errorf("%v got %v; want %v", fd
.laddr
, fd
.family
, syscall
.AF_INET
)
395 fd
:= ln
.(*TCPListener
).fd
396 if fd
.family
!= syscall
.AF_INET6
{
397 return fmt
.Errorf("%v got %v; want %v", fd
.laddr
, fd
.family
, syscall
.AF_INET6
)
400 fd
:= ln
.(*UDPConn
).fd
401 if err
:= checkDualStackAddrFamily(fd
); err
!= nil {
405 fd
:= ln
.(*UDPConn
).fd
406 if fd
.family
!= syscall
.AF_INET
{
407 return fmt
.Errorf("%v got %v; want %v", fd
.laddr
, fd
.family
, syscall
.AF_INET
)
410 fd
:= ln
.(*UDPConn
).fd
411 if fd
.family
!= syscall
.AF_INET6
{
412 return fmt
.Errorf("%v got %v; want %v", fd
.laddr
, fd
.family
, syscall
.AF_INET6
)
415 return UnknownNetworkError(network
)
420 func checkSecondListener(network
, address
string, err error
) error
{
422 case "tcp", "tcp4", "tcp6":
424 return fmt
.Errorf("%s should fail", network
+" "+address
)
426 case "udp", "udp4", "udp6":
428 return fmt
.Errorf("%s should fail", network
+" "+address
)
431 return UnknownNetworkError(network
)
436 func checkDualStackSecondListener(network
, address
string, err
, xerr error
) error
{
438 case "tcp", "tcp4", "tcp6":
439 if xerr
== nil && err
!= nil || xerr
!= nil && err
== nil {
440 return fmt
.Errorf("%s got %v; want %v", network
+" "+address
, err
, xerr
)
442 case "udp", "udp4", "udp6":
443 if xerr
== nil && err
!= nil || xerr
!= nil && err
== nil {
444 return fmt
.Errorf("%s got %v; want %v", network
+" "+address
, err
, xerr
)
447 return UnknownNetworkError(network
)
452 func checkDualStackAddrFamily(fd
*netFD
) error
{
453 switch a
:= fd
.laddr
.(type) {
455 // If a node under test supports both IPv6 capability
456 // and IPv6 IPv4-mapping capability, we can assume
457 // that the node listens on a wildcard address with an
459 if supportsIPv4map() && fd
.laddr
.(*TCPAddr
).isWildcard() {
460 if fd
.family
!= syscall
.AF_INET6
{
461 return fmt
.Errorf("Listen(%s, %v) returns %v; want %v", fd
.net
, fd
.laddr
, fd
.family
, syscall
.AF_INET6
)
464 if fd
.family
!= a
.family() {
465 return fmt
.Errorf("Listen(%s, %v) returns %v; want %v", fd
.net
, fd
.laddr
, fd
.family
, a
.family())
469 // If a node under test supports both IPv6 capability
470 // and IPv6 IPv4-mapping capability, we can assume
471 // that the node listens on a wildcard address with an
473 if supportsIPv4map() && fd
.laddr
.(*UDPAddr
).isWildcard() {
474 if fd
.family
!= syscall
.AF_INET6
{
475 return fmt
.Errorf("ListenPacket(%s, %v) returns %v; want %v", fd
.net
, fd
.laddr
, fd
.family
, syscall
.AF_INET6
)
478 if fd
.family
!= a
.family() {
479 return fmt
.Errorf("ListenPacket(%s, %v) returns %v; want %v", fd
.net
, fd
.laddr
, fd
.family
, a
.family())
483 return fmt
.Errorf("unexpected protocol address type: %T", a
)
488 func TestWildWildcardListener(t
*testing
.T
) {
489 testenv
.MustHaveExternalNetwork(t
)
491 switch runtime
.GOOS
{
493 t
.Skipf("not supported on %s", runtime
.GOOS
)
497 if p
:= recover(); p
!= nil {
498 t
.Fatalf("panicked: %v", p
)
502 if ln
, err
:= Listen("tcp", ""); err
== nil {
505 if ln
, err
:= ListenPacket("udp", ""); err
== nil {
508 if ln
, err
:= ListenTCP("tcp", nil); err
== nil {
511 if ln
, err
:= ListenUDP("udp", nil); err
== nil {
514 if ln
, err
:= ListenIP("ip:icmp", nil); err
== nil {
519 var ipv4MulticastListenerTests
= []struct {
521 gaddr
*UDPAddr
// see RFC 4727
523 {"udp", &UDPAddr
{IP
: IPv4(224, 0, 0, 254), Port
: 12345}},
525 {"udp4", &UDPAddr
{IP
: IPv4(224, 0, 0, 254), Port
: 12345}},
528 // TestIPv4MulticastListener tests both single and double listen to a
529 // test listener with same address family, same group address and same
531 func TestIPv4MulticastListener(t
*testing
.T
) {
532 testenv
.MustHaveExternalNetwork(t
)
534 switch runtime
.GOOS
{
535 case "android", "plan9":
536 t
.Skipf("not supported on %s", runtime
.GOOS
)
539 t
.Skip("IPv4 is not supported")
542 closer
:= func(cs
[]*UDPConn
) {
543 for _
, c
:= range cs
{
550 for _
, ifi
:= range []*Interface
{loopbackInterface(), nil} {
551 // Note that multicast interface assignment by system
552 // is not recommended because it usually relies on
553 // routing stuff for finding out an appropriate
554 // nexthop containing both network and link layer
556 if ifi
== nil ||
!*testIPv4
{
559 for _
, tt
:= range ipv4MulticastListenerTests
{
561 cs
:= make([]*UDPConn
, 2)
562 if cs
[0], err
= ListenMulticastUDP(tt
.net
, ifi
, tt
.gaddr
); err
!= nil {
565 if err
:= checkMulticastListener(cs
[0], tt
.gaddr
.IP
); err
!= nil {
569 if cs
[1], err
= ListenMulticastUDP(tt
.net
, ifi
, tt
.gaddr
); err
!= nil {
573 if err
:= checkMulticastListener(cs
[1], tt
.gaddr
.IP
); err
!= nil {
582 var ipv6MulticastListenerTests
= []struct {
584 gaddr
*UDPAddr
// see RFC 4727
586 {"udp", &UDPAddr
{IP
: ParseIP("ff01::114"), Port
: 12345}},
587 {"udp", &UDPAddr
{IP
: ParseIP("ff02::114"), Port
: 12345}},
588 {"udp", &UDPAddr
{IP
: ParseIP("ff04::114"), Port
: 12345}},
589 {"udp", &UDPAddr
{IP
: ParseIP("ff05::114"), Port
: 12345}},
590 {"udp", &UDPAddr
{IP
: ParseIP("ff08::114"), Port
: 12345}},
591 {"udp", &UDPAddr
{IP
: ParseIP("ff0e::114"), Port
: 12345}},
593 {"udp6", &UDPAddr
{IP
: ParseIP("ff01::114"), Port
: 12345}},
594 {"udp6", &UDPAddr
{IP
: ParseIP("ff02::114"), Port
: 12345}},
595 {"udp6", &UDPAddr
{IP
: ParseIP("ff04::114"), Port
: 12345}},
596 {"udp6", &UDPAddr
{IP
: ParseIP("ff05::114"), Port
: 12345}},
597 {"udp6", &UDPAddr
{IP
: ParseIP("ff08::114"), Port
: 12345}},
598 {"udp6", &UDPAddr
{IP
: ParseIP("ff0e::114"), Port
: 12345}},
601 // TestIPv6MulticastListener tests both single and double listen to a
602 // test listener with same address family, same group address and same
604 func TestIPv6MulticastListener(t
*testing
.T
) {
605 testenv
.MustHaveExternalNetwork(t
)
607 switch runtime
.GOOS
{
609 t
.Skipf("not supported on %s", runtime
.GOOS
)
612 t
.Skip("IPv6 is not supported")
614 if os
.Getuid() != 0 {
615 t
.Skip("must be root")
618 closer
:= func(cs
[]*UDPConn
) {
619 for _
, c
:= range cs
{
626 for _
, ifi
:= range []*Interface
{loopbackInterface(), nil} {
627 // Note that multicast interface assignment by system
628 // is not recommended because it usually relies on
629 // routing stuff for finding out an appropriate
630 // nexthop containing both network and link layer
632 if ifi
== nil && !*testIPv6
{
635 for _
, tt
:= range ipv6MulticastListenerTests
{
637 cs
:= make([]*UDPConn
, 2)
638 if cs
[0], err
= ListenMulticastUDP(tt
.net
, ifi
, tt
.gaddr
); err
!= nil {
641 if err
:= checkMulticastListener(cs
[0], tt
.gaddr
.IP
); err
!= nil {
645 if cs
[1], err
= ListenMulticastUDP(tt
.net
, ifi
, tt
.gaddr
); err
!= nil {
649 if err
:= checkMulticastListener(cs
[1], tt
.gaddr
.IP
); err
!= nil {
658 func checkMulticastListener(c
*UDPConn
, ip IP
) error
{
659 if ok
, err
:= multicastRIBContains(ip
); err
!= nil {
662 return fmt
.Errorf("%s not found in multicast rib", ip
.String())
665 if la
, ok
:= la
.(*UDPAddr
); !ok || la
.Port
== 0 {
666 return fmt
.Errorf("got %v; want a proper address with non-zero port number", la
)
671 func multicastRIBContains(ip IP
) (bool, error
) {
672 switch runtime
.GOOS
{
673 case "aix", "dragonfly", "netbsd", "openbsd", "plan9", "solaris", "illumos", "windows":
674 return true, nil // not implemented yet
676 if runtime
.GOARCH
== "arm" || runtime
.GOARCH
== "alpha" {
677 return true, nil // not implemented yet
680 ift
, err
:= Interfaces()
684 for _
, ifi
:= range ift
{
685 ifmat
, err
:= ifi
.MulticastAddrs()
689 for _
, ifma
:= range ifmat
{
690 if ifma
.(*IPAddr
).IP
.Equal(ip
) {
699 func TestClosingListener(t
*testing
.T
) {
700 ln
:= newLocalListener(t
, "tcp")
705 c
, err
:= ln
.Accept()
713 // Let the goroutine start. We don't sleep long: if the
714 // goroutine doesn't start, the test will pass without really
715 // testing anything, which is OK.
716 time
.Sleep(time
.Millisecond
)
720 ln2
, err
:= Listen("tcp", addr
.String())
727 func TestListenConfigControl(t
*testing
.T
) {
728 switch runtime
.GOOS
{
730 t
.Skipf("not supported on %s", runtime
.GOOS
)
733 t
.Run("StreamListen", func(t
*testing
.T
) {
734 for _
, network
:= range []string{"tcp", "tcp4", "tcp6", "unix", "unixpacket"} {
735 if !testableNetwork(network
) {
738 ln
:= newLocalListener(t
, network
)
739 address
:= ln
.Addr().String()
740 // TODO: This is racy. The selected address could be reused in between
741 // this Close and the subsequent Listen.
743 lc
:= ListenConfig
{Control
: controlOnConnSetup
}
744 ln
, err
:= lc
.Listen(context
.Background(), network
, address
)
752 t
.Run("PacketListen", func(t
*testing
.T
) {
753 for _
, network
:= range []string{"udp", "udp4", "udp6", "unixgram"} {
754 if !testableNetwork(network
) {
757 c
:= newLocalPacketListener(t
, network
)
758 address
:= c
.LocalAddr().String()
759 // TODO: This is racy. The selected address could be reused in between
760 // this Close and the subsequent ListenPacket.
762 if network
== "unixgram" {
765 lc
:= ListenConfig
{Control
: controlOnConnSetup
}
766 c
, err
:= lc
.ListenPacket(context
.Background(), network
, address
)
772 if network
== "unixgram" {