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.
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 {
227 case "nacl", "plan9":
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 {
317 case "nacl", "plan9":
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 interface{}) 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", "nacl", "plan9":
536 t.Skipf("not supported on %s", runtime.GOOS)
538 t.Skipf("not supported on solaris, see golang.org/issue/7399")
541 t.Skip("IPv4 is not supported")
544 closer := func(cs []*UDPConn) {
545 for _, c := range cs {
552 for _, ifi := range []*Interface{loopbackInterface(), nil} {
553 // Note that multicast interface assignment by system
554 // is not recommended because it usually relies on
555 // routing stuff for finding out an appropriate
556 // nexthop containing both network and link layer
558 if ifi == nil || !*testIPv4 {
561 for _, tt := range ipv4MulticastListenerTests {
563 cs := make([]*UDPConn, 2)
564 if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
567 if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
571 if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
575 if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
584 var ipv6MulticastListenerTests = []struct {
586 gaddr *UDPAddr // see RFC 4727
588 {"udp", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
589 {"udp", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
590 {"udp", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
591 {"udp", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
592 {"udp", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
593 {"udp", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
595 {"udp6", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
596 {"udp6", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
597 {"udp6", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
598 {"udp6", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
599 {"udp6", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
600 {"udp6", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
603 // TestIPv6MulticastListener tests both single and double listen to a
604 // test listener with same address family, same group address and same
606 func TestIPv6MulticastListener(t *testing.T) {
607 testenv.MustHaveExternalNetwork(t)
609 switch runtime.GOOS {
611 t.Skipf("not supported on %s", runtime.GOOS)
613 t.Skipf("not supported on solaris, see issue 7399")
616 t.Skip("IPv6 is not supported")
618 if os.Getuid() != 0 {
619 t.Skip("must be root")
622 closer := func(cs []*UDPConn) {
623 for _, c := range cs {
630 for _, ifi := range []*Interface{loopbackInterface(), nil} {
631 // Note that multicast interface assignment by system
632 // is not recommended because it usually relies on
633 // routing stuff for finding out an appropriate
634 // nexthop containing both network and link layer
636 if ifi == nil && !*testIPv6 {
639 for _, tt := range ipv6MulticastListenerTests {
641 cs := make([]*UDPConn, 2)
642 if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
645 if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
649 if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
653 if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
662 func checkMulticastListener(c *UDPConn, ip IP) error {
663 if ok, err := multicastRIBContains(ip); err != nil {
666 return fmt.Errorf("%s not found in multicast rib", ip.String())
669 if la, ok := la.(*UDPAddr); !ok || la.Port == 0 {
670 return fmt.Errorf("got %v; want a proper address with non-zero port number", la)
675 func multicastRIBContains(ip IP) (bool, error) {
676 switch runtime.GOOS {
677 case "aix", "dragonfly", "netbsd", "openbsd", "plan9", "solaris", "windows":
678 return true, nil // not implemented yet
680 if runtime.GOARCH == "arm" || runtime.GOARCH == "alpha" {
681 return true, nil // not implemented yet
684 ift, err := Interfaces()
688 for _, ifi := range ift {
689 ifmat, err := ifi.MulticastAddrs()
693 for _, ifma := range ifmat {
694 if ifma.(*IPAddr).IP.Equal(ip) {
703 func TestClosingListener(t *testing.T) {
704 ln, err := newLocalListener("tcp")
712 c, err := ln.Accept()
720 // Let the goroutine start. We don't sleep long: if the
721 // goroutine doesn't start, the test will pass without really
722 // testing anything, which is OK.
723 time.Sleep(time.Millisecond)
727 ln2, err := Listen("tcp", addr.String())
734 func TestListenConfigControl(t *testing.T) {
735 switch runtime.GOOS {
736 case "nacl", "plan9":
737 t.Skipf("not supported on %s", runtime.GOOS)
740 t.Run("StreamListen", func(t *testing.T) {
741 for _, network := range []string{"tcp", "tcp4", "tcp6", "unix", "unixpacket"} {
742 if !testableNetwork(network) {
745 ln, err := newLocalListener(network)
750 address := ln.Addr().String()
752 lc := ListenConfig{Control: controlOnConnSetup}
753 ln, err = lc.Listen(context.Background(), network, address)
761 t.Run("PacketListen", func(t *testing.T) {
762 for _, network := range []string{"udp", "udp4", "udp6", "unixgram"} {
763 if !testableNetwork(network) {
766 c, err := newLocalPacketListener(network)
771 address := c.LocalAddr().String()
773 if network == "unixgram" {
776 lc := ListenConfig{Control: controlOnConnSetup}
777 c, err = lc.ListenPacket(context.Background(), network, address)
783 if network == "unixgram" {