Home | History | Annotate | Download | only in net
      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.
      4 
      5 // +build !plan9
      6 
      7 package net
      8 
      9 import (
     10 	"fmt"
     11 	"internal/testenv"
     12 	"os"
     13 	"runtime"
     14 	"syscall"
     15 	"testing"
     16 	"time"
     17 )
     18 
     19 func (ln *TCPListener) port() string {
     20 	_, port, err := SplitHostPort(ln.Addr().String())
     21 	if err != nil {
     22 		return ""
     23 	}
     24 	return port
     25 }
     26 
     27 func (c *UDPConn) port() string {
     28 	_, port, err := SplitHostPort(c.LocalAddr().String())
     29 	if err != nil {
     30 		return ""
     31 	}
     32 	return port
     33 }
     34 
     35 var tcpListenerTests = []struct {
     36 	network string
     37 	address string
     38 }{
     39 	{"tcp", ""},
     40 	{"tcp", "0.0.0.0"},
     41 	{"tcp", "::ffff:0.0.0.0"},
     42 	{"tcp", "::"},
     43 
     44 	{"tcp", "127.0.0.1"},
     45 	{"tcp", "::ffff:127.0.0.1"},
     46 	{"tcp", "::1"},
     47 
     48 	{"tcp4", ""},
     49 	{"tcp4", "0.0.0.0"},
     50 	{"tcp4", "::ffff:0.0.0.0"},
     51 
     52 	{"tcp4", "127.0.0.1"},
     53 	{"tcp4", "::ffff:127.0.0.1"},
     54 
     55 	{"tcp6", ""},
     56 	{"tcp6", "::"},
     57 
     58 	{"tcp6", "::1"},
     59 }
     60 
     61 // TestTCPListener tests both single and double listen to a test
     62 // listener with same address family, same listening address and
     63 // same port.
     64 func TestTCPListener(t *testing.T) {
     65 	switch runtime.GOOS {
     66 	case "plan9":
     67 		t.Skipf("not supported on %s", runtime.GOOS)
     68 	}
     69 
     70 	for _, tt := range tcpListenerTests {
     71 		if !testableListenArgs(tt.network, JoinHostPort(tt.address, "0"), "") {
     72 			t.Logf("skipping %s test", tt.network+" "+tt.address)
     73 			continue
     74 		}
     75 
     76 		ln1, err := Listen(tt.network, JoinHostPort(tt.address, "0"))
     77 		if err != nil {
     78 			t.Fatal(err)
     79 		}
     80 		if err := checkFirstListener(tt.network, ln1); err != nil {
     81 			ln1.Close()
     82 			t.Fatal(err)
     83 		}
     84 		ln2, err := Listen(tt.network, JoinHostPort(tt.address, ln1.(*TCPListener).port()))
     85 		if err == nil {
     86 			ln2.Close()
     87 		}
     88 		if err := checkSecondListener(tt.network, tt.address, err); err != nil {
     89 			ln1.Close()
     90 			t.Fatal(err)
     91 		}
     92 		ln1.Close()
     93 	}
     94 }
     95 
     96 var udpListenerTests = []struct {
     97 	network string
     98 	address string
     99 }{
    100 	{"udp", ""},
    101 	{"udp", "0.0.0.0"},
    102 	{"udp", "::ffff:0.0.0.0"},
    103 	{"udp", "::"},
    104 
    105 	{"udp", "127.0.0.1"},
    106 	{"udp", "::ffff:127.0.0.1"},
    107 	{"udp", "::1"},
    108 
    109 	{"udp4", ""},
    110 	{"udp4", "0.0.0.0"},
    111 	{"udp4", "::ffff:0.0.0.0"},
    112 
    113 	{"udp4", "127.0.0.1"},
    114 	{"udp4", "::ffff:127.0.0.1"},
    115 
    116 	{"udp6", ""},
    117 	{"udp6", "::"},
    118 
    119 	{"udp6", "::1"},
    120 }
    121 
    122 // TestUDPListener tests both single and double listen to a test
    123 // listener with same address family, same listening address and
    124 // same port.
    125 func TestUDPListener(t *testing.T) {
    126 	switch runtime.GOOS {
    127 	case "plan9":
    128 		t.Skipf("not supported on %s", runtime.GOOS)
    129 	}
    130 
    131 	for _, tt := range udpListenerTests {
    132 		if !testableListenArgs(tt.network, JoinHostPort(tt.address, "0"), "") {
    133 			t.Logf("skipping %s test", tt.network+" "+tt.address)
    134 			continue
    135 		}
    136 
    137 		c1, err := ListenPacket(tt.network, JoinHostPort(tt.address, "0"))
    138 		if err != nil {
    139 			t.Fatal(err)
    140 		}
    141 		if err := checkFirstListener(tt.network, c1); err != nil {
    142 			c1.Close()
    143 			t.Fatal(err)
    144 		}
    145 		c2, err := ListenPacket(tt.network, JoinHostPort(tt.address, c1.(*UDPConn).port()))
    146 		if err == nil {
    147 			c2.Close()
    148 		}
    149 		if err := checkSecondListener(tt.network, tt.address, err); err != nil {
    150 			c1.Close()
    151 			t.Fatal(err)
    152 		}
    153 		c1.Close()
    154 	}
    155 }
    156 
    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
    161 }{
    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
    185 	//
    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)
    195 
    196 	{"tcp", "", "tcp", "", syscall.EADDRINUSE},
    197 	{"tcp", "", "tcp", "0.0.0.0", syscall.EADDRINUSE},
    198 	{"tcp", "0.0.0.0", "tcp", "", syscall.EADDRINUSE},
    199 
    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},
    206 
    207 	{"tcp4", "", "tcp6", "", nil},
    208 	{"tcp6", "", "tcp4", "", nil},
    209 	{"tcp4", "0.0.0.0", "tcp6", "::", nil},
    210 	{"tcp6", "::", "tcp4", "0.0.0.0", nil},
    211 
    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},
    216 }
    217 
    218 // TestDualStackTCPListener tests both single and double listen
    219 // to a test listener with various address families, different
    220 // listening address and same port.
    221 //
    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 {
    226 	case "nacl", "plan9":
    227 		t.Skipf("not supported on %s", runtime.GOOS)
    228 	}
    229 	if !supportsIPv4() || !supportsIPv6() {
    230 		t.Skip("both IPv4 and IPv6 are required")
    231 	}
    232 
    233 	for _, tt := range dualStackTCPListenerTests {
    234 		if !testableListenArgs(tt.network1, JoinHostPort(tt.address1, "0"), "") {
    235 			t.Logf("skipping %s test", tt.network1+" "+tt.address1)
    236 			continue
    237 		}
    238 
    239 		if !supportsIPv4map() && differentWildcardAddr(tt.address1, tt.address2) {
    240 			tt.xerr = nil
    241 		}
    242 		var firstErr, secondErr error
    243 		for i := 0; i < 5; i++ {
    244 			lns, err := newDualStackListener()
    245 			if err != nil {
    246 				t.Fatal(err)
    247 			}
    248 			port := lns[0].port()
    249 			for _, ln := range lns {
    250 				ln.Close()
    251 			}
    252 			var ln1 Listener
    253 			ln1, firstErr = Listen(tt.network1, JoinHostPort(tt.address1, port))
    254 			if firstErr != nil {
    255 				continue
    256 			}
    257 			if err := checkFirstListener(tt.network1, ln1); err != nil {
    258 				ln1.Close()
    259 				t.Fatal(err)
    260 			}
    261 			ln2, err := Listen(tt.network2, JoinHostPort(tt.address2, ln1.(*TCPListener).port()))
    262 			if err == nil {
    263 				ln2.Close()
    264 			}
    265 			if secondErr = checkDualStackSecondListener(tt.network2, tt.address2, err, tt.xerr); secondErr != nil {
    266 				ln1.Close()
    267 				continue
    268 			}
    269 			ln1.Close()
    270 			break
    271 		}
    272 		if firstErr != nil {
    273 			t.Error(firstErr)
    274 		}
    275 		if secondErr != nil {
    276 			t.Error(secondErr)
    277 		}
    278 	}
    279 }
    280 
    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
    285 }{
    286 	{"udp", "", "udp", "", syscall.EADDRINUSE},
    287 	{"udp", "", "udp", "0.0.0.0", syscall.EADDRINUSE},
    288 	{"udp", "0.0.0.0", "udp", "", syscall.EADDRINUSE},
    289 
    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},
    296 
    297 	{"udp4", "", "udp6", "", nil},
    298 	{"udp6", "", "udp4", "", nil},
    299 	{"udp4", "0.0.0.0", "udp6", "::", nil},
    300 	{"udp6", "::", "udp4", "0.0.0.0", nil},
    301 
    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},
    306 }
    307 
    308 // TestDualStackUDPListener tests both single and double listen
    309 // to a test listener with various address families, different
    310 // listening address and same port.
    311 //
    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 {
    316 	case "nacl", "plan9":
    317 		t.Skipf("not supported on %s", runtime.GOOS)
    318 	}
    319 	if !supportsIPv4() || !supportsIPv6() {
    320 		t.Skip("both IPv4 and IPv6 are required")
    321 	}
    322 
    323 	for _, tt := range dualStackUDPListenerTests {
    324 		if !testableListenArgs(tt.network1, JoinHostPort(tt.address1, "0"), "") {
    325 			t.Logf("skipping %s test", tt.network1+" "+tt.address1)
    326 			continue
    327 		}
    328 
    329 		if !supportsIPv4map() && differentWildcardAddr(tt.address1, tt.address2) {
    330 			tt.xerr = nil
    331 		}
    332 		var firstErr, secondErr error
    333 		for i := 0; i < 5; i++ {
    334 			cs, err := newDualStackPacketListener()
    335 			if err != nil {
    336 				t.Fatal(err)
    337 			}
    338 			port := cs[0].port()
    339 			for _, c := range cs {
    340 				c.Close()
    341 			}
    342 			var c1 PacketConn
    343 			c1, firstErr = ListenPacket(tt.network1, JoinHostPort(tt.address1, port))
    344 			if firstErr != nil {
    345 				continue
    346 			}
    347 			if err := checkFirstListener(tt.network1, c1); err != nil {
    348 				c1.Close()
    349 				t.Fatal(err)
    350 			}
    351 			c2, err := ListenPacket(tt.network2, JoinHostPort(tt.address2, c1.(*UDPConn).port()))
    352 			if err == nil {
    353 				c2.Close()
    354 			}
    355 			if secondErr = checkDualStackSecondListener(tt.network2, tt.address2, err, tt.xerr); secondErr != nil {
    356 				c1.Close()
    357 				continue
    358 			}
    359 			c1.Close()
    360 			break
    361 		}
    362 		if firstErr != nil {
    363 			t.Error(firstErr)
    364 		}
    365 		if secondErr != nil {
    366 			t.Error(secondErr)
    367 		}
    368 	}
    369 }
    370 
    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") {
    373 		return false
    374 	}
    375 	if i == "[::]" && j == "[::]" {
    376 		return false
    377 	}
    378 	return true
    379 }
    380 
    381 func checkFirstListener(network string, ln interface{}) error {
    382 	switch network {
    383 	case "tcp":
    384 		fd := ln.(*TCPListener).fd
    385 		if err := checkDualStackAddrFamily(fd); err != nil {
    386 			return err
    387 		}
    388 	case "tcp4":
    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)
    392 		}
    393 	case "tcp6":
    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)
    397 		}
    398 	case "udp":
    399 		fd := ln.(*UDPConn).fd
    400 		if err := checkDualStackAddrFamily(fd); err != nil {
    401 			return err
    402 		}
    403 	case "udp4":
    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)
    407 		}
    408 	case "udp6":
    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)
    412 		}
    413 	default:
    414 		return UnknownNetworkError(network)
    415 	}
    416 	return nil
    417 }
    418 
    419 func checkSecondListener(network, address string, err error) error {
    420 	switch network {
    421 	case "tcp", "tcp4", "tcp6":
    422 		if err == nil {
    423 			return fmt.Errorf("%s should fail", network+" "+address)
    424 		}
    425 	case "udp", "udp4", "udp6":
    426 		if err == nil {
    427 			return fmt.Errorf("%s should fail", network+" "+address)
    428 		}
    429 	default:
    430 		return UnknownNetworkError(network)
    431 	}
    432 	return nil
    433 }
    434 
    435 func checkDualStackSecondListener(network, address string, err, xerr error) error {
    436 	switch network {
    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)
    440 		}
    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)
    444 		}
    445 	default:
    446 		return UnknownNetworkError(network)
    447 	}
    448 	return nil
    449 }
    450 
    451 func checkDualStackAddrFamily(fd *netFD) error {
    452 	switch a := fd.laddr.(type) {
    453 	case *TCPAddr:
    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
    457 		// AF_INET6 socket.
    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)
    461 			}
    462 		} else {
    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())
    465 			}
    466 		}
    467 	case *UDPAddr:
    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
    471 		// AF_INET6 socket.
    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)
    475 			}
    476 		} else {
    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())
    479 			}
    480 		}
    481 	default:
    482 		return fmt.Errorf("unexpected protocol address type: %T", a)
    483 	}
    484 	return nil
    485 }
    486 
    487 func TestWildWildcardListener(t *testing.T) {
    488 	testenv.MustHaveExternalNetwork(t)
    489 
    490 	switch runtime.GOOS {
    491 	case "plan9":
    492 		t.Skipf("not supported on %s", runtime.GOOS)
    493 	}
    494 
    495 	defer func() {
    496 		if p := recover(); p != nil {
    497 			t.Fatalf("panicked: %v", p)
    498 		}
    499 	}()
    500 
    501 	if ln, err := Listen("tcp", ""); err == nil {
    502 		ln.Close()
    503 	}
    504 	if ln, err := ListenPacket("udp", ""); err == nil {
    505 		ln.Close()
    506 	}
    507 	if ln, err := ListenTCP("tcp", nil); err == nil {
    508 		ln.Close()
    509 	}
    510 	if ln, err := ListenUDP("udp", nil); err == nil {
    511 		ln.Close()
    512 	}
    513 	if ln, err := ListenIP("ip:icmp", nil); err == nil {
    514 		ln.Close()
    515 	}
    516 }
    517 
    518 var ipv4MulticastListenerTests = []struct {
    519 	net   string
    520 	gaddr *UDPAddr // see RFC 4727
    521 }{
    522 	{"udp", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}},
    523 
    524 	{"udp4", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}},
    525 }
    526 
    527 // TestIPv4MulticastListener tests both single and double listen to a
    528 // test listener with same address family, same group address and same
    529 // port.
    530 func TestIPv4MulticastListener(t *testing.T) {
    531 	testenv.MustHaveExternalNetwork(t)
    532 
    533 	switch runtime.GOOS {
    534 	case "android", "nacl", "plan9":
    535 		t.Skipf("not supported on %s", runtime.GOOS)
    536 	case "solaris":
    537 		t.Skipf("not supported on solaris, see golang.org/issue/7399")
    538 	}
    539 	if !supportsIPv4() {
    540 		t.Skip("IPv4 is not supported")
    541 	}
    542 
    543 	closer := func(cs []*UDPConn) {
    544 		for _, c := range cs {
    545 			if c != nil {
    546 				c.Close()
    547 			}
    548 		}
    549 	}
    550 
    551 	for _, ifi := range []*Interface{loopbackInterface(), nil} {
    552 		// Note that multicast interface assignment by system
    553 		// is not recommended because it usually relies on
    554 		// routing stuff for finding out an appropriate
    555 		// nexthop containing both network and link layer
    556 		// adjacencies.
    557 		if ifi == nil || !*testIPv4 {
    558 			continue
    559 		}
    560 		for _, tt := range ipv4MulticastListenerTests {
    561 			var err error
    562 			cs := make([]*UDPConn, 2)
    563 			if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
    564 				t.Fatal(err)
    565 			}
    566 			if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
    567 				closer(cs)
    568 				t.Fatal(err)
    569 			}
    570 			if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
    571 				closer(cs)
    572 				t.Fatal(err)
    573 			}
    574 			if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
    575 				closer(cs)
    576 				t.Fatal(err)
    577 			}
    578 			closer(cs)
    579 		}
    580 	}
    581 }
    582 
    583 var ipv6MulticastListenerTests = []struct {
    584 	net   string
    585 	gaddr *UDPAddr // see RFC 4727
    586 }{
    587 	{"udp", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
    588 	{"udp", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
    589 	{"udp", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
    590 	{"udp", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
    591 	{"udp", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
    592 	{"udp", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
    593 
    594 	{"udp6", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
    595 	{"udp6", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
    596 	{"udp6", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
    597 	{"udp6", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
    598 	{"udp6", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
    599 	{"udp6", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
    600 }
    601 
    602 // TestIPv6MulticastListener tests both single and double listen to a
    603 // test listener with same address family, same group address and same
    604 // port.
    605 func TestIPv6MulticastListener(t *testing.T) {
    606 	testenv.MustHaveExternalNetwork(t)
    607 
    608 	switch runtime.GOOS {
    609 	case "plan9":
    610 		t.Skipf("not supported on %s", runtime.GOOS)
    611 	case "solaris":
    612 		t.Skipf("not supported on solaris, see issue 7399")
    613 	}
    614 	if !supportsIPv6() {
    615 		t.Skip("IPv6 is not supported")
    616 	}
    617 	if os.Getuid() != 0 {
    618 		t.Skip("must be root")
    619 	}
    620 
    621 	closer := func(cs []*UDPConn) {
    622 		for _, c := range cs {
    623 			if c != nil {
    624 				c.Close()
    625 			}
    626 		}
    627 	}
    628 
    629 	for _, ifi := range []*Interface{loopbackInterface(), nil} {
    630 		// Note that multicast interface assignment by system
    631 		// is not recommended because it usually relies on
    632 		// routing stuff for finding out an appropriate
    633 		// nexthop containing both network and link layer
    634 		// adjacencies.
    635 		if ifi == nil && !*testIPv6 {
    636 			continue
    637 		}
    638 		for _, tt := range ipv6MulticastListenerTests {
    639 			var err error
    640 			cs := make([]*UDPConn, 2)
    641 			if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
    642 				t.Fatal(err)
    643 			}
    644 			if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
    645 				closer(cs)
    646 				t.Fatal(err)
    647 			}
    648 			if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
    649 				closer(cs)
    650 				t.Fatal(err)
    651 			}
    652 			if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
    653 				closer(cs)
    654 				t.Fatal(err)
    655 			}
    656 			closer(cs)
    657 		}
    658 	}
    659 }
    660 
    661 func checkMulticastListener(c *UDPConn, ip IP) error {
    662 	if ok, err := multicastRIBContains(ip); err != nil {
    663 		return err
    664 	} else if !ok {
    665 		return fmt.Errorf("%s not found in multicast rib", ip.String())
    666 	}
    667 	la := c.LocalAddr()
    668 	if la, ok := la.(*UDPAddr); !ok || la.Port == 0 {
    669 		return fmt.Errorf("got %v; want a proper address with non-zero port number", la)
    670 	}
    671 	return nil
    672 }
    673 
    674 func multicastRIBContains(ip IP) (bool, error) {
    675 	switch runtime.GOOS {
    676 	case "dragonfly", "netbsd", "openbsd", "plan9", "solaris", "windows":
    677 		return true, nil // not implemented yet
    678 	case "linux":
    679 		if runtime.GOARCH == "arm" || runtime.GOARCH == "alpha" {
    680 			return true, nil // not implemented yet
    681 		}
    682 	}
    683 	ift, err := Interfaces()
    684 	if err != nil {
    685 		return false, err
    686 	}
    687 	for _, ifi := range ift {
    688 		ifmat, err := ifi.MulticastAddrs()
    689 		if err != nil {
    690 			return false, err
    691 		}
    692 		for _, ifma := range ifmat {
    693 			if ifma.(*IPAddr).IP.Equal(ip) {
    694 				return true, nil
    695 			}
    696 		}
    697 	}
    698 	return false, nil
    699 }
    700 
    701 // Issue 21856.
    702 func TestClosingListener(t *testing.T) {
    703 	ln, err := newLocalListener("tcp")
    704 	if err != nil {
    705 		t.Fatal(err)
    706 	}
    707 	addr := ln.Addr()
    708 
    709 	go func() {
    710 		for {
    711 			c, err := ln.Accept()
    712 			if err != nil {
    713 				return
    714 			}
    715 			c.Close()
    716 		}
    717 	}()
    718 
    719 	// Let the goroutine start. We don't sleep long: if the
    720 	// goroutine doesn't start, the test will pass without really
    721 	// testing anything, which is OK.
    722 	time.Sleep(time.Millisecond)
    723 
    724 	ln.Close()
    725 
    726 	ln2, err := Listen("tcp", addr.String())
    727 	if err != nil {
    728 		t.Fatal(err)
    729 	}
    730 	ln2.Close()
    731 }
    732