github.com/c9s/go@v0.0.0-20180120015821-984e81f64e0c/src/net/listen_test.go (about) 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 }