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.
19 func (ln *TCPListener) port() string {
20 _, port, err := SplitHostPort(ln.Addr().String())
27 func (c *UDPConn) port() string {
28 _, port, err := SplitHostPort(c.LocalAddr().String())
35 var tcpListenerTests = []struct {
41 {"tcp", "::ffff:0.0.0.0"},
45 {"tcp", "::ffff:127.0.0.1"},
50 {"tcp4", "::ffff:0.0.0.0"},
52 {"tcp4", "127.0.0.1"},
53 {"tcp4", "::ffff:127.0.0.1"},
61 // TestTCPListener tests both single and double listen to a test
62 // listener with same address family, same listening address and
64 func TestTCPListener(t *testing.T) {
67 t.Skipf("not supported on %s", runtime.GOOS)
70 for _, tt := range tcpListenerTests {
71 if !testableListenArgs(tt.network, JoinHostPort(tt.address, "0"), "") {
72 t.Logf("skipping %s test", tt.network+" "+tt.address)
76 ln1, err := Listen(tt.network, JoinHostPort(tt.address, "0"))
80 if err := checkFirstListener(tt.network, ln1); err != nil {
84 ln2, err := Listen(tt.network, JoinHostPort(tt.address, ln1.(*TCPListener).port()))
88 if err := checkSecondListener(tt.network, tt.address, err); err != nil {
96 var udpListenerTests = []struct {
102 {"udp", "::ffff:0.0.0.0"},
105 {"udp", "127.0.0.1"},
106 {"udp", "::ffff:127.0.0.1"},
111 {"udp4", "::ffff:0.0.0.0"},
113 {"udp4", "127.0.0.1"},
114 {"udp4", "::ffff:127.0.0.1"},
122 // TestUDPListener tests both single and double listen to a test
123 // listener with same address family, same listening address and
125 func TestUDPListener(t *testing.T) {
126 switch runtime.GOOS {
128 t.Skipf("not supported on %s", runtime.GOOS)
131 for _, tt := range udpListenerTests {
132 if !testableListenArgs(tt.network, JoinHostPort(tt.address, "0"), "") {
133 t.Logf("skipping %s test", tt.network+" "+tt.address)
137 c1, err := ListenPacket(tt.network, JoinHostPort(tt.address, "0"))
141 if err := checkFirstListener(tt.network, c1); err != nil {
145 c2, err := ListenPacket(tt.network, JoinHostPort(tt.address, c1.(*UDPConn).port()))
149 if err := checkSecondListener(tt.network, tt.address, err); err != nil {
157 var dualStackTCPListenerTests = []struct {
158 network1, address1 string // first listener
159 network2, address2 string // second listener
160 xerr error // expected error value, nil or other
162 // Test cases and expected results for the attempting 2nd listen on the same port
163 // 1st listen 2nd listen darwin freebsd linux openbsd
164 // ------------------------------------------------------------------------------------
165 // "tcp" "" "tcp" "" - - - -
166 // "tcp" "" "tcp" "0.0.0.0" - - - -
167 // "tcp" "0.0.0.0" "tcp" "" - - - -
168 // ------------------------------------------------------------------------------------
169 // "tcp" "" "tcp" "[::]" - - - ok
170 // "tcp" "[::]" "tcp" "" - - - ok
171 // "tcp" "0.0.0.0" "tcp" "[::]" - - - ok
172 // "tcp" "[::]" "tcp" "0.0.0.0" - - - ok
173 // "tcp" "[::ffff:0.0.0.0]" "tcp" "[::]" - - - ok
174 // "tcp" "[::]" "tcp" "[::ffff:0.0.0.0]" - - - ok
175 // ------------------------------------------------------------------------------------
176 // "tcp4" "" "tcp6" "" ok ok ok ok
177 // "tcp6" "" "tcp4" "" ok ok ok ok
178 // "tcp4" "0.0.0.0" "tcp6" "[::]" ok ok ok ok
179 // "tcp6" "[::]" "tcp4" "0.0.0.0" ok ok ok ok
180 // ------------------------------------------------------------------------------------
181 // "tcp" "127.0.0.1" "tcp" "[::1]" ok ok ok ok
182 // "tcp" "[::1]" "tcp" "127.0.0.1" ok ok ok ok
183 // "tcp4" "127.0.0.1" "tcp6" "[::1]" ok ok ok ok
184 // "tcp6" "[::1]" "tcp4" "127.0.0.1" ok ok ok ok
186 // Platform default configurations:
187 // darwin, kernel version 11.3.0
188 // net.inet6.ip6.v6only=0 (overridable by sysctl or IPV6_V6ONLY option)
189 // freebsd, kernel version 8.2
190 // net.inet6.ip6.v6only=1 (overridable by sysctl or IPV6_V6ONLY option)
191 // linux, kernel version 3.0.0
192 // net.ipv6.bindv6only=0 (overridable by sysctl or IPV6_V6ONLY option)
193 // openbsd, kernel version 5.0
194 // net.inet6.ip6.v6only=1 (overriding is prohibited)
196 {"tcp", "", "tcp", "", syscall.EADDRINUSE},
197 {"tcp", "", "tcp", "0.0.0.0", syscall.EADDRINUSE},
198 {"tcp", "0.0.0.0", "tcp", "", syscall.EADDRINUSE},
200 {"tcp", "", "tcp", "::", syscall.EADDRINUSE},
201 {"tcp", "::", "tcp", "", syscall.EADDRINUSE},
202 {"tcp", "0.0.0.0", "tcp", "::", syscall.EADDRINUSE},
203 {"tcp", "::", "tcp", "0.0.0.0", syscall.EADDRINUSE},
204 {"tcp", "::ffff:0.0.0.0", "tcp", "::", syscall.EADDRINUSE},
205 {"tcp", "::", "tcp", "::ffff:0.0.0.0", syscall.EADDRINUSE},
207 {"tcp4", "", "tcp6", "", nil},
208 {"tcp6", "", "tcp4", "", nil},
209 {"tcp4", "0.0.0.0", "tcp6", "::", nil},
210 {"tcp6", "::", "tcp4", "0.0.0.0", nil},
212 {"tcp", "127.0.0.1", "tcp", "::1", nil},
213 {"tcp", "::1", "tcp", "127.0.0.1", nil},
214 {"tcp4", "127.0.0.1", "tcp6", "::1", nil},
215 {"tcp6", "::1", "tcp4", "127.0.0.1", nil},
218 // TestDualStackTCPListener tests both single and double listen
219 // to a test listener with various address families, different
220 // listening address and same port.
222 // On DragonFly BSD, we expect the kernel version of node under test
223 // to be greater than or equal to 4.4.
224 func TestDualStackTCPListener(t *testing.T) {
225 switch runtime.GOOS {
227 t.Skipf("not supported on %s", runtime.GOOS)
229 if !supportsIPv4() || !supportsIPv6() {
230 t.Skip("both IPv4 and IPv6 are required")
233 for _, tt := range dualStackTCPListenerTests {
234 if !testableListenArgs(tt.network1, JoinHostPort(tt.address1, "0"), "") {
235 t.Logf("skipping %s test", tt.network1+" "+tt.address1)
239 if !supportsIPv4map() && differentWildcardAddr(tt.address1, tt.address2) {
242 var firstErr, secondErr error
243 for i := 0; i < 5; i++ {
244 lns, err := newDualStackListener()
248 port := lns[0].port()
249 for _, ln := range lns {
253 ln1, firstErr = Listen(tt.network1, JoinHostPort(tt.address1, port))
257 if err := checkFirstListener(tt.network1, ln1); err != nil {
261 ln2, err := Listen(tt.network2, JoinHostPort(tt.address2, ln1.(*TCPListener).port()))
265 if secondErr = checkDualStackSecondListener(tt.network2, tt.address2, err, tt.xerr); secondErr != nil {
275 if secondErr != nil {
281 var dualStackUDPListenerTests = []struct {
282 network1, address1 string // first listener
283 network2, address2 string // second listener
284 xerr error // expected error value, nil or other
286 {"udp", "", "udp", "", syscall.EADDRINUSE},
287 {"udp", "", "udp", "0.0.0.0", syscall.EADDRINUSE},
288 {"udp", "0.0.0.0", "udp", "", syscall.EADDRINUSE},
290 {"udp", "", "udp", "::", syscall.EADDRINUSE},
291 {"udp", "::", "udp", "", syscall.EADDRINUSE},
292 {"udp", "0.0.0.0", "udp", "::", syscall.EADDRINUSE},
293 {"udp", "::", "udp", "0.0.0.0", syscall.EADDRINUSE},
294 {"udp", "::ffff:0.0.0.0", "udp", "::", syscall.EADDRINUSE},
295 {"udp", "::", "udp", "::ffff:0.0.0.0", syscall.EADDRINUSE},
297 {"udp4", "", "udp6", "", nil},
298 {"udp6", "", "udp4", "", nil},
299 {"udp4", "0.0.0.0", "udp6", "::", nil},
300 {"udp6", "::", "udp4", "0.0.0.0", nil},
302 {"udp", "127.0.0.1", "udp", "::1", nil},
303 {"udp", "::1", "udp", "127.0.0.1", nil},
304 {"udp4", "127.0.0.1", "udp6", "::1", nil},
305 {"udp6", "::1", "udp4", "127.0.0.1", nil},
308 // TestDualStackUDPListener tests both single and double listen
309 // to a test listener with various address families, different
310 // listening address and same port.
312 // On DragonFly BSD, we expect the kernel version of node under test
313 // to be greater than or equal to 4.4.
314 func TestDualStackUDPListener(t *testing.T) {
315 switch runtime.GOOS {
317 t.Skipf("not supported on %s", runtime.GOOS)
319 if !supportsIPv4() || !supportsIPv6() {
320 t.Skip("both IPv4 and IPv6 are required")
323 for _, tt := range dualStackUDPListenerTests {
324 if !testableListenArgs(tt.network1, JoinHostPort(tt.address1, "0"), "") {
325 t.Logf("skipping %s test", tt.network1+" "+tt.address1)
329 if !supportsIPv4map() && differentWildcardAddr(tt.address1, tt.address2) {
332 var firstErr, secondErr error
333 for i := 0; i < 5; i++ {
334 cs, err := newDualStackPacketListener()
339 for _, c := range cs {
343 c1, firstErr = ListenPacket(tt.network1, JoinHostPort(tt.address1, port))
347 if err := checkFirstListener(tt.network1, c1); err != nil {
351 c2, err := ListenPacket(tt.network2, JoinHostPort(tt.address2, c1.(*UDPConn).port()))
355 if secondErr = checkDualStackSecondListener(tt.network2, tt.address2, err, tt.xerr); secondErr != nil {
365 if secondErr != nil {
371 func differentWildcardAddr(i, j string) bool {
372 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") {
375 if i == "[::]" && j == "[::]" {
381 func checkFirstListener(network string, ln any) error {
384 fd := ln.(*TCPListener).fd
385 if err := checkDualStackAddrFamily(fd); err != nil {
389 fd := ln.(*TCPListener).fd
390 if fd.family != syscall.AF_INET {
391 return fmt.Errorf("%v got %v; want %v", fd.laddr, fd.family, syscall.AF_INET)
394 fd := ln.(*TCPListener).fd
395 if fd.family != syscall.AF_INET6 {
396 return fmt.Errorf("%v got %v; want %v", fd.laddr, fd.family, syscall.AF_INET6)
399 fd := ln.(*UDPConn).fd
400 if err := checkDualStackAddrFamily(fd); err != nil {
404 fd := ln.(*UDPConn).fd
405 if fd.family != syscall.AF_INET {
406 return fmt.Errorf("%v got %v; want %v", fd.laddr, fd.family, syscall.AF_INET)
409 fd := ln.(*UDPConn).fd
410 if fd.family != syscall.AF_INET6 {
411 return fmt.Errorf("%v got %v; want %v", fd.laddr, fd.family, syscall.AF_INET6)
414 return UnknownNetworkError(network)
419 func checkSecondListener(network, address string, err error) error {
421 case "tcp", "tcp4", "tcp6":
423 return fmt.Errorf("%s should fail", network+" "+address)
425 case "udp", "udp4", "udp6":
427 return fmt.Errorf("%s should fail", network+" "+address)
430 return UnknownNetworkError(network)
435 func checkDualStackSecondListener(network, address string, err, xerr error) error {
437 case "tcp", "tcp4", "tcp6":
438 if xerr == nil && err != nil || xerr != nil && err == nil {
439 return fmt.Errorf("%s got %v; want %v", network+" "+address, err, xerr)
441 case "udp", "udp4", "udp6":
442 if xerr == nil && err != nil || xerr != nil && err == nil {
443 return fmt.Errorf("%s got %v; want %v", network+" "+address, err, xerr)
446 return UnknownNetworkError(network)
451 func checkDualStackAddrFamily(fd *netFD) error {
452 switch a := fd.laddr.(type) {
454 // If a node under test supports both IPv6 capability
455 // and IPv6 IPv4-mapping capability, we can assume
456 // that the node listens on a wildcard address with an
458 if supportsIPv4map() && fd.laddr.(*TCPAddr).isWildcard() {
459 if fd.family != syscall.AF_INET6 {
460 return fmt.Errorf("Listen(%s, %v) returns %v; want %v", fd.net, fd.laddr, fd.family, syscall.AF_INET6)
463 if fd.family != a.family() {
464 return fmt.Errorf("Listen(%s, %v) returns %v; want %v", fd.net, fd.laddr, fd.family, a.family())
468 // If a node under test supports both IPv6 capability
469 // and IPv6 IPv4-mapping capability, we can assume
470 // that the node listens on a wildcard address with an
472 if supportsIPv4map() && fd.laddr.(*UDPAddr).isWildcard() {
473 if fd.family != syscall.AF_INET6 {
474 return fmt.Errorf("ListenPacket(%s, %v) returns %v; want %v", fd.net, fd.laddr, fd.family, syscall.AF_INET6)
477 if fd.family != a.family() {
478 return fmt.Errorf("ListenPacket(%s, %v) returns %v; want %v", fd.net, fd.laddr, fd.family, a.family())
482 return fmt.Errorf("unexpected protocol address type: %T", a)
487 func TestWildWildcardListener(t *testing.T) {
488 testenv.MustHaveExternalNetwork(t)
490 switch runtime.GOOS {
492 t.Skipf("not supported on %s", runtime.GOOS)
496 if p := recover(); p != nil {
497 t.Fatalf("panicked: %v", p)
501 if ln, err := Listen("tcp", ""); err == nil {
504 if ln, err := ListenPacket("udp", ""); err == nil {
507 if ln, err := ListenTCP("tcp", nil); err == nil {
510 if ln, err := ListenUDP("udp", nil); err == nil {
513 if ln, err := ListenIP("ip:icmp", nil); err == nil {
518 var ipv4MulticastListenerTests = []struct {
520 gaddr *UDPAddr // see RFC 4727
522 {"udp", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}},
524 {"udp4", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}},
527 // TestIPv4MulticastListener tests both single and double listen to a
528 // test listener with same address family, same group address and same
530 func TestIPv4MulticastListener(t *testing.T) {
531 testenv.MustHaveExternalNetwork(t)
533 switch runtime.GOOS {
534 case "android", "plan9":
535 t.Skipf("not supported on %s", runtime.GOOS)
538 t.Skip("IPv4 is not supported")
541 closer := func(cs []*UDPConn) {
542 for _, c := range cs {
549 for _, ifi := range []*Interface{loopbackInterface(), nil} {
550 // Note that multicast interface assignment by system
551 // is not recommended because it usually relies on
552 // routing stuff for finding out an appropriate
553 // nexthop containing both network and link layer
555 if ifi == nil || !*testIPv4 {
558 for _, tt := range ipv4MulticastListenerTests {
560 cs := make([]*UDPConn, 2)
561 if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
564 if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
568 if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
572 if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
581 var ipv6MulticastListenerTests = []struct {
583 gaddr *UDPAddr // see RFC 4727
585 {"udp", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
586 {"udp", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
587 {"udp", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
588 {"udp", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
589 {"udp", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
590 {"udp", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
592 {"udp6", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
593 {"udp6", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
594 {"udp6", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
595 {"udp6", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
596 {"udp6", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
597 {"udp6", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
600 // TestIPv6MulticastListener tests both single and double listen to a
601 // test listener with same address family, same group address and same
603 func TestIPv6MulticastListener(t *testing.T) {
604 testenv.MustHaveExternalNetwork(t)
606 switch runtime.GOOS {
608 t.Skipf("not supported on %s", runtime.GOOS)
611 t.Skip("IPv6 is not supported")
613 if os.Getuid() != 0 {
614 t.Skip("must be root")
617 closer := func(cs []*UDPConn) {
618 for _, c := range cs {
625 for _, ifi := range []*Interface{loopbackInterface(), nil} {
626 // Note that multicast interface assignment by system
627 // is not recommended because it usually relies on
628 // routing stuff for finding out an appropriate
629 // nexthop containing both network and link layer
631 if ifi == nil && !*testIPv6 {
634 for _, tt := range ipv6MulticastListenerTests {
636 cs := make([]*UDPConn, 2)
637 if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
640 if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
644 if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
648 if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
657 func checkMulticastListener(c *UDPConn, ip IP) error {
658 if ok, err := multicastRIBContains(ip); err != nil {
661 return fmt.Errorf("%s not found in multicast rib", ip.String())
664 if la, ok := la.(*UDPAddr); !ok || la.Port == 0 {
665 return fmt.Errorf("got %v; want a proper address with non-zero port number", la)
670 func multicastRIBContains(ip IP) (bool, error) {
671 switch runtime.GOOS {
672 case "aix", "dragonfly", "netbsd", "openbsd", "plan9", "solaris", "illumos", "windows":
673 return true, nil // not implemented yet
675 if runtime.GOARCH == "arm" || runtime.GOARCH == "alpha" {
676 return true, nil // not implemented yet
679 ift, err := Interfaces()
683 for _, ifi := range ift {
684 ifmat, err := ifi.MulticastAddrs()
688 for _, ifma := range ifmat {
689 if ifma.(*IPAddr).IP.Equal(ip) {
698 func TestClosingListener(t *testing.T) {
699 ln := newLocalListener(t, "tcp")
704 c, err := ln.Accept()
712 // Let the goroutine start. We don't sleep long: if the
713 // goroutine doesn't start, the test will pass without really
714 // testing anything, which is OK.
715 time.Sleep(time.Millisecond)
719 ln2, err := Listen("tcp", addr.String())
726 func TestListenConfigControl(t *testing.T) {
727 switch runtime.GOOS {
729 t.Skipf("not supported on %s", runtime.GOOS)
732 t.Run("StreamListen", func(t *testing.T) {
733 for _, network := range []string{"tcp", "tcp4", "tcp6", "unix", "unixpacket"} {
734 if !testableNetwork(network) {
737 ln := newLocalListener(t, network, &ListenConfig{Control: controlOnConnSetup})
741 t.Run("PacketListen", func(t *testing.T) {
742 for _, network := range []string{"udp", "udp4", "udp6", "unixgram"} {
743 if !testableNetwork(network) {
746 c := newLocalPacketListener(t, network, &ListenConfig{Control: controlOnConnSetup})