github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/go/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 //go:build !js && !plan9 6 // +build !js,!plan9 7 8 package net 9 10 import ( 11 "context" 12 "fmt" 13 "internal/testenv" 14 "os" 15 "runtime" 16 "syscall" 17 "testing" 18 "time" 19 ) 20 21 func (ln *TCPListener) port() string { 22 _, port, err := SplitHostPort(ln.Addr().String()) 23 if err != nil { 24 return "" 25 } 26 return port 27 } 28 29 func (c *UDPConn) port() string { 30 _, port, err := SplitHostPort(c.LocalAddr().String()) 31 if err != nil { 32 return "" 33 } 34 return port 35 } 36 37 var tcpListenerTests = []struct { 38 network string 39 address string 40 }{ 41 {"tcp", ""}, 42 {"tcp", "0.0.0.0"}, 43 {"tcp", "::ffff:0.0.0.0"}, 44 {"tcp", "::"}, 45 46 {"tcp", "127.0.0.1"}, 47 {"tcp", "::ffff:127.0.0.1"}, 48 {"tcp", "::1"}, 49 50 {"tcp4", ""}, 51 {"tcp4", "0.0.0.0"}, 52 {"tcp4", "::ffff:0.0.0.0"}, 53 54 {"tcp4", "127.0.0.1"}, 55 {"tcp4", "::ffff:127.0.0.1"}, 56 57 {"tcp6", ""}, 58 {"tcp6", "::"}, 59 60 {"tcp6", "::1"}, 61 } 62 63 // TestTCPListener tests both single and double listen to a test 64 // listener with same address family, same listening address and 65 // same port. 66 func TestTCPListener(t *testing.T) { 67 switch runtime.GOOS { 68 case "plan9": 69 t.Skipf("not supported on %s", runtime.GOOS) 70 } 71 72 for _, tt := range tcpListenerTests { 73 if !testableListenArgs(tt.network, JoinHostPort(tt.address, "0"), "") { 74 t.Logf("skipping %s test", tt.network+" "+tt.address) 75 continue 76 } 77 78 ln1, err := Listen(tt.network, JoinHostPort(tt.address, "0")) 79 if err != nil { 80 t.Fatal(err) 81 } 82 if err := checkFirstListener(tt.network, ln1); err != nil { 83 ln1.Close() 84 t.Fatal(err) 85 } 86 ln2, err := Listen(tt.network, JoinHostPort(tt.address, ln1.(*TCPListener).port())) 87 if err == nil { 88 ln2.Close() 89 } 90 if err := checkSecondListener(tt.network, tt.address, err); err != nil { 91 ln1.Close() 92 t.Fatal(err) 93 } 94 ln1.Close() 95 } 96 } 97 98 var udpListenerTests = []struct { 99 network string 100 address string 101 }{ 102 {"udp", ""}, 103 {"udp", "0.0.0.0"}, 104 {"udp", "::ffff:0.0.0.0"}, 105 {"udp", "::"}, 106 107 {"udp", "127.0.0.1"}, 108 {"udp", "::ffff:127.0.0.1"}, 109 {"udp", "::1"}, 110 111 {"udp4", ""}, 112 {"udp4", "0.0.0.0"}, 113 {"udp4", "::ffff:0.0.0.0"}, 114 115 {"udp4", "127.0.0.1"}, 116 {"udp4", "::ffff:127.0.0.1"}, 117 118 {"udp6", ""}, 119 {"udp6", "::"}, 120 121 {"udp6", "::1"}, 122 } 123 124 // TestUDPListener tests both single and double listen to a test 125 // listener with same address family, same listening address and 126 // same port. 127 func TestUDPListener(t *testing.T) { 128 switch runtime.GOOS { 129 case "plan9": 130 t.Skipf("not supported on %s", runtime.GOOS) 131 } 132 133 for _, tt := range udpListenerTests { 134 if !testableListenArgs(tt.network, JoinHostPort(tt.address, "0"), "") { 135 t.Logf("skipping %s test", tt.network+" "+tt.address) 136 continue 137 } 138 139 c1, err := ListenPacket(tt.network, JoinHostPort(tt.address, "0")) 140 if err != nil { 141 t.Fatal(err) 142 } 143 if err := checkFirstListener(tt.network, c1); err != nil { 144 c1.Close() 145 t.Fatal(err) 146 } 147 c2, err := ListenPacket(tt.network, JoinHostPort(tt.address, c1.(*UDPConn).port())) 148 if err == nil { 149 c2.Close() 150 } 151 if err := checkSecondListener(tt.network, tt.address, err); err != nil { 152 c1.Close() 153 t.Fatal(err) 154 } 155 c1.Close() 156 } 157 } 158 159 var dualStackTCPListenerTests = []struct { 160 network1, address1 string // first listener 161 network2, address2 string // second listener 162 xerr error // expected error value, nil or other 163 }{ 164 // Test cases and expected results for the attempting 2nd listen on the same port 165 // 1st listen 2nd listen darwin freebsd linux openbsd 166 // ------------------------------------------------------------------------------------ 167 // "tcp" "" "tcp" "" - - - - 168 // "tcp" "" "tcp" "0.0.0.0" - - - - 169 // "tcp" "0.0.0.0" "tcp" "" - - - - 170 // ------------------------------------------------------------------------------------ 171 // "tcp" "" "tcp" "[::]" - - - ok 172 // "tcp" "[::]" "tcp" "" - - - ok 173 // "tcp" "0.0.0.0" "tcp" "[::]" - - - ok 174 // "tcp" "[::]" "tcp" "0.0.0.0" - - - ok 175 // "tcp" "[::ffff:0.0.0.0]" "tcp" "[::]" - - - ok 176 // "tcp" "[::]" "tcp" "[::ffff:0.0.0.0]" - - - ok 177 // ------------------------------------------------------------------------------------ 178 // "tcp4" "" "tcp6" "" ok ok ok ok 179 // "tcp6" "" "tcp4" "" ok ok ok ok 180 // "tcp4" "0.0.0.0" "tcp6" "[::]" ok ok ok ok 181 // "tcp6" "[::]" "tcp4" "0.0.0.0" ok ok ok ok 182 // ------------------------------------------------------------------------------------ 183 // "tcp" "127.0.0.1" "tcp" "[::1]" ok ok ok ok 184 // "tcp" "[::1]" "tcp" "127.0.0.1" ok ok ok ok 185 // "tcp4" "127.0.0.1" "tcp6" "[::1]" ok ok ok ok 186 // "tcp6" "[::1]" "tcp4" "127.0.0.1" ok ok ok ok 187 // 188 // Platform default configurations: 189 // darwin, kernel version 11.3.0 190 // net.inet6.ip6.v6only=0 (overridable by sysctl or IPV6_V6ONLY option) 191 // freebsd, kernel version 8.2 192 // net.inet6.ip6.v6only=1 (overridable by sysctl or IPV6_V6ONLY option) 193 // linux, kernel version 3.0.0 194 // net.ipv6.bindv6only=0 (overridable by sysctl or IPV6_V6ONLY option) 195 // openbsd, kernel version 5.0 196 // net.inet6.ip6.v6only=1 (overriding is prohibited) 197 198 {"tcp", "", "tcp", "", syscall.EADDRINUSE}, 199 {"tcp", "", "tcp", "0.0.0.0", syscall.EADDRINUSE}, 200 {"tcp", "0.0.0.0", "tcp", "", syscall.EADDRINUSE}, 201 202 {"tcp", "", "tcp", "::", syscall.EADDRINUSE}, 203 {"tcp", "::", "tcp", "", syscall.EADDRINUSE}, 204 {"tcp", "0.0.0.0", "tcp", "::", syscall.EADDRINUSE}, 205 {"tcp", "::", "tcp", "0.0.0.0", syscall.EADDRINUSE}, 206 {"tcp", "::ffff:0.0.0.0", "tcp", "::", syscall.EADDRINUSE}, 207 {"tcp", "::", "tcp", "::ffff:0.0.0.0", syscall.EADDRINUSE}, 208 209 {"tcp4", "", "tcp6", "", nil}, 210 {"tcp6", "", "tcp4", "", nil}, 211 {"tcp4", "0.0.0.0", "tcp6", "::", nil}, 212 {"tcp6", "::", "tcp4", "0.0.0.0", nil}, 213 214 {"tcp", "127.0.0.1", "tcp", "::1", nil}, 215 {"tcp", "::1", "tcp", "127.0.0.1", nil}, 216 {"tcp4", "127.0.0.1", "tcp6", "::1", nil}, 217 {"tcp6", "::1", "tcp4", "127.0.0.1", nil}, 218 } 219 220 // TestDualStackTCPListener tests both single and double listen 221 // to a test listener with various address families, different 222 // listening address and same port. 223 // 224 // On DragonFly BSD, we expect the kernel version of node under test 225 // to be greater than or equal to 4.4. 226 func TestDualStackTCPListener(t *testing.T) { 227 switch runtime.GOOS { 228 case "plan9": 229 t.Skipf("not supported on %s", runtime.GOOS) 230 } 231 if !supportsIPv4() || !supportsIPv6() { 232 t.Skip("both IPv4 and IPv6 are required") 233 } 234 235 for _, tt := range dualStackTCPListenerTests { 236 if !testableListenArgs(tt.network1, JoinHostPort(tt.address1, "0"), "") { 237 t.Logf("skipping %s test", tt.network1+" "+tt.address1) 238 continue 239 } 240 241 if !supportsIPv4map() && differentWildcardAddr(tt.address1, tt.address2) { 242 tt.xerr = nil 243 } 244 var firstErr, secondErr error 245 for i := 0; i < 5; i++ { 246 lns, err := newDualStackListener() 247 if err != nil { 248 t.Fatal(err) 249 } 250 port := lns[0].port() 251 for _, ln := range lns { 252 ln.Close() 253 } 254 var ln1 Listener 255 ln1, firstErr = Listen(tt.network1, JoinHostPort(tt.address1, port)) 256 if firstErr != nil { 257 continue 258 } 259 if err := checkFirstListener(tt.network1, ln1); err != nil { 260 ln1.Close() 261 t.Fatal(err) 262 } 263 ln2, err := Listen(tt.network2, JoinHostPort(tt.address2, ln1.(*TCPListener).port())) 264 if err == nil { 265 ln2.Close() 266 } 267 if secondErr = checkDualStackSecondListener(tt.network2, tt.address2, err, tt.xerr); secondErr != nil { 268 ln1.Close() 269 continue 270 } 271 ln1.Close() 272 break 273 } 274 if firstErr != nil { 275 t.Error(firstErr) 276 } 277 if secondErr != nil { 278 t.Error(secondErr) 279 } 280 } 281 } 282 283 var dualStackUDPListenerTests = []struct { 284 network1, address1 string // first listener 285 network2, address2 string // second listener 286 xerr error // expected error value, nil or other 287 }{ 288 {"udp", "", "udp", "", syscall.EADDRINUSE}, 289 {"udp", "", "udp", "0.0.0.0", syscall.EADDRINUSE}, 290 {"udp", "0.0.0.0", "udp", "", syscall.EADDRINUSE}, 291 292 {"udp", "", "udp", "::", syscall.EADDRINUSE}, 293 {"udp", "::", "udp", "", syscall.EADDRINUSE}, 294 {"udp", "0.0.0.0", "udp", "::", syscall.EADDRINUSE}, 295 {"udp", "::", "udp", "0.0.0.0", syscall.EADDRINUSE}, 296 {"udp", "::ffff:0.0.0.0", "udp", "::", syscall.EADDRINUSE}, 297 {"udp", "::", "udp", "::ffff:0.0.0.0", syscall.EADDRINUSE}, 298 299 {"udp4", "", "udp6", "", nil}, 300 {"udp6", "", "udp4", "", nil}, 301 {"udp4", "0.0.0.0", "udp6", "::", nil}, 302 {"udp6", "::", "udp4", "0.0.0.0", nil}, 303 304 {"udp", "127.0.0.1", "udp", "::1", nil}, 305 {"udp", "::1", "udp", "127.0.0.1", nil}, 306 {"udp4", "127.0.0.1", "udp6", "::1", nil}, 307 {"udp6", "::1", "udp4", "127.0.0.1", nil}, 308 } 309 310 // TestDualStackUDPListener tests both single and double listen 311 // to a test listener with various address families, different 312 // listening address and same port. 313 // 314 // On DragonFly BSD, we expect the kernel version of node under test 315 // to be greater than or equal to 4.4. 316 func TestDualStackUDPListener(t *testing.T) { 317 switch runtime.GOOS { 318 case "plan9": 319 t.Skipf("not supported on %s", runtime.GOOS) 320 } 321 if !supportsIPv4() || !supportsIPv6() { 322 t.Skip("both IPv4 and IPv6 are required") 323 } 324 325 for _, tt := range dualStackUDPListenerTests { 326 if !testableListenArgs(tt.network1, JoinHostPort(tt.address1, "0"), "") { 327 t.Logf("skipping %s test", tt.network1+" "+tt.address1) 328 continue 329 } 330 331 if !supportsIPv4map() && differentWildcardAddr(tt.address1, tt.address2) { 332 tt.xerr = nil 333 } 334 var firstErr, secondErr error 335 for i := 0; i < 5; i++ { 336 cs, err := newDualStackPacketListener() 337 if err != nil { 338 t.Fatal(err) 339 } 340 port := cs[0].port() 341 for _, c := range cs { 342 c.Close() 343 } 344 var c1 PacketConn 345 c1, firstErr = ListenPacket(tt.network1, JoinHostPort(tt.address1, port)) 346 if firstErr != nil { 347 continue 348 } 349 if err := checkFirstListener(tt.network1, c1); err != nil { 350 c1.Close() 351 t.Fatal(err) 352 } 353 c2, err := ListenPacket(tt.network2, JoinHostPort(tt.address2, c1.(*UDPConn).port())) 354 if err == nil { 355 c2.Close() 356 } 357 if secondErr = checkDualStackSecondListener(tt.network2, tt.address2, err, tt.xerr); secondErr != nil { 358 c1.Close() 359 continue 360 } 361 c1.Close() 362 break 363 } 364 if firstErr != nil { 365 t.Error(firstErr) 366 } 367 if secondErr != nil { 368 t.Error(secondErr) 369 } 370 } 371 } 372 373 func differentWildcardAddr(i, j string) bool { 374 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 return false 376 } 377 if i == "[::]" && j == "[::]" { 378 return false 379 } 380 return true 381 } 382 383 func checkFirstListener(network string, ln interface{}) error { 384 switch network { 385 case "tcp": 386 fd := ln.(*TCPListener).fd 387 if err := checkDualStackAddrFamily(fd); err != nil { 388 return err 389 } 390 case "tcp4": 391 fd := ln.(*TCPListener).fd 392 if fd.family != syscall.AF_INET { 393 return fmt.Errorf("%v got %v; want %v", fd.laddr, fd.family, syscall.AF_INET) 394 } 395 case "tcp6": 396 fd := ln.(*TCPListener).fd 397 if fd.family != syscall.AF_INET6 { 398 return fmt.Errorf("%v got %v; want %v", fd.laddr, fd.family, syscall.AF_INET6) 399 } 400 case "udp": 401 fd := ln.(*UDPConn).fd 402 if err := checkDualStackAddrFamily(fd); err != nil { 403 return err 404 } 405 case "udp4": 406 fd := ln.(*UDPConn).fd 407 if fd.family != syscall.AF_INET { 408 return fmt.Errorf("%v got %v; want %v", fd.laddr, fd.family, syscall.AF_INET) 409 } 410 case "udp6": 411 fd := ln.(*UDPConn).fd 412 if fd.family != syscall.AF_INET6 { 413 return fmt.Errorf("%v got %v; want %v", fd.laddr, fd.family, syscall.AF_INET6) 414 } 415 default: 416 return UnknownNetworkError(network) 417 } 418 return nil 419 } 420 421 func checkSecondListener(network, address string, err error) error { 422 switch network { 423 case "tcp", "tcp4", "tcp6": 424 if err == nil { 425 return fmt.Errorf("%s should fail", network+" "+address) 426 } 427 case "udp", "udp4", "udp6": 428 if err == nil { 429 return fmt.Errorf("%s should fail", network+" "+address) 430 } 431 default: 432 return UnknownNetworkError(network) 433 } 434 return nil 435 } 436 437 func checkDualStackSecondListener(network, address string, err, xerr error) error { 438 switch network { 439 case "tcp", "tcp4", "tcp6": 440 if xerr == nil && err != nil || xerr != nil && err == nil { 441 return fmt.Errorf("%s got %v; want %v", network+" "+address, err, xerr) 442 } 443 case "udp", "udp4", "udp6": 444 if xerr == nil && err != nil || xerr != nil && err == nil { 445 return fmt.Errorf("%s got %v; want %v", network+" "+address, err, xerr) 446 } 447 default: 448 return UnknownNetworkError(network) 449 } 450 return nil 451 } 452 453 func checkDualStackAddrFamily(fd *netFD) error { 454 switch a := fd.laddr.(type) { 455 case *TCPAddr: 456 // If a node under test supports both IPv6 capability 457 // and IPv6 IPv4-mapping capability, we can assume 458 // that the node listens on a wildcard address with an 459 // AF_INET6 socket. 460 if supportsIPv4map() && fd.laddr.(*TCPAddr).isWildcard() { 461 if fd.family != syscall.AF_INET6 { 462 return fmt.Errorf("Listen(%s, %v) returns %v; want %v", fd.net, fd.laddr, fd.family, syscall.AF_INET6) 463 } 464 } else { 465 if fd.family != a.family() { 466 return fmt.Errorf("Listen(%s, %v) returns %v; want %v", fd.net, fd.laddr, fd.family, a.family()) 467 } 468 } 469 case *UDPAddr: 470 // If a node under test supports both IPv6 capability 471 // and IPv6 IPv4-mapping capability, we can assume 472 // that the node listens on a wildcard address with an 473 // AF_INET6 socket. 474 if supportsIPv4map() && fd.laddr.(*UDPAddr).isWildcard() { 475 if fd.family != syscall.AF_INET6 { 476 return fmt.Errorf("ListenPacket(%s, %v) returns %v; want %v", fd.net, fd.laddr, fd.family, syscall.AF_INET6) 477 } 478 } else { 479 if fd.family != a.family() { 480 return fmt.Errorf("ListenPacket(%s, %v) returns %v; want %v", fd.net, fd.laddr, fd.family, a.family()) 481 } 482 } 483 default: 484 return fmt.Errorf("unexpected protocol address type: %T", a) 485 } 486 return nil 487 } 488 489 func TestWildWildcardListener(t *testing.T) { 490 testenv.MustHaveExternalNetwork(t) 491 492 switch runtime.GOOS { 493 case "plan9": 494 t.Skipf("not supported on %s", runtime.GOOS) 495 } 496 497 defer func() { 498 if p := recover(); p != nil { 499 t.Fatalf("panicked: %v", p) 500 } 501 }() 502 503 if ln, err := Listen("tcp", ""); err == nil { 504 ln.Close() 505 } 506 if ln, err := ListenPacket("udp", ""); err == nil { 507 ln.Close() 508 } 509 if ln, err := ListenTCP("tcp", nil); err == nil { 510 ln.Close() 511 } 512 if ln, err := ListenUDP("udp", nil); err == nil { 513 ln.Close() 514 } 515 if ln, err := ListenIP("ip:icmp", nil); err == nil { 516 ln.Close() 517 } 518 } 519 520 var ipv4MulticastListenerTests = []struct { 521 net string 522 gaddr *UDPAddr // see RFC 4727 523 }{ 524 {"udp", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}}, 525 526 {"udp4", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}}, 527 } 528 529 // TestIPv4MulticastListener tests both single and double listen to a 530 // test listener with same address family, same group address and same 531 // port. 532 func TestIPv4MulticastListener(t *testing.T) { 533 testenv.MustHaveExternalNetwork(t) 534 535 switch runtime.GOOS { 536 case "android", "plan9": 537 t.Skipf("not supported on %s", runtime.GOOS) 538 case "solaris", "illumos": 539 t.Skipf("not supported on solaris or illumos, see golang.org/issue/7399") 540 } 541 if !supportsIPv4() { 542 t.Skip("IPv4 is not supported") 543 } 544 545 closer := func(cs []*UDPConn) { 546 for _, c := range cs { 547 if c != nil { 548 c.Close() 549 } 550 } 551 } 552 553 for _, ifi := range []*Interface{loopbackInterface(), nil} { 554 // Note that multicast interface assignment by system 555 // is not recommended because it usually relies on 556 // routing stuff for finding out an appropriate 557 // nexthop containing both network and link layer 558 // adjacencies. 559 if ifi == nil || !*testIPv4 { 560 continue 561 } 562 for _, tt := range ipv4MulticastListenerTests { 563 var err error 564 cs := make([]*UDPConn, 2) 565 if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil { 566 t.Fatal(err) 567 } 568 if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil { 569 closer(cs) 570 t.Fatal(err) 571 } 572 if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil { 573 closer(cs) 574 t.Fatal(err) 575 } 576 if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil { 577 closer(cs) 578 t.Fatal(err) 579 } 580 closer(cs) 581 } 582 } 583 } 584 585 var ipv6MulticastListenerTests = []struct { 586 net string 587 gaddr *UDPAddr // see RFC 4727 588 }{ 589 {"udp", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}}, 590 {"udp", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}}, 591 {"udp", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}}, 592 {"udp", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}}, 593 {"udp", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}}, 594 {"udp", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}}, 595 596 {"udp6", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}}, 597 {"udp6", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}}, 598 {"udp6", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}}, 599 {"udp6", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}}, 600 {"udp6", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}}, 601 {"udp6", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}}, 602 } 603 604 // TestIPv6MulticastListener tests both single and double listen to a 605 // test listener with same address family, same group address and same 606 // port. 607 func TestIPv6MulticastListener(t *testing.T) { 608 testenv.MustHaveExternalNetwork(t) 609 610 switch runtime.GOOS { 611 case "plan9": 612 t.Skipf("not supported on %s", runtime.GOOS) 613 case "solaris", "illumos": 614 t.Skipf("not supported on solaris or illumos, see issue 7399") 615 } 616 if !supportsIPv6() { 617 t.Skip("IPv6 is not supported") 618 } 619 if os.Getuid() != 0 { 620 t.Skip("must be root") 621 } 622 623 closer := func(cs []*UDPConn) { 624 for _, c := range cs { 625 if c != nil { 626 c.Close() 627 } 628 } 629 } 630 631 for _, ifi := range []*Interface{loopbackInterface(), nil} { 632 // Note that multicast interface assignment by system 633 // is not recommended because it usually relies on 634 // routing stuff for finding out an appropriate 635 // nexthop containing both network and link layer 636 // adjacencies. 637 if ifi == nil && !*testIPv6 { 638 continue 639 } 640 for _, tt := range ipv6MulticastListenerTests { 641 var err error 642 cs := make([]*UDPConn, 2) 643 if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil { 644 t.Fatal(err) 645 } 646 if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil { 647 closer(cs) 648 t.Fatal(err) 649 } 650 if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil { 651 closer(cs) 652 t.Fatal(err) 653 } 654 if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil { 655 closer(cs) 656 t.Fatal(err) 657 } 658 closer(cs) 659 } 660 } 661 } 662 663 func checkMulticastListener(c *UDPConn, ip IP) error { 664 if ok, err := multicastRIBContains(ip); err != nil { 665 return err 666 } else if !ok { 667 return fmt.Errorf("%s not found in multicast rib", ip.String()) 668 } 669 la := c.LocalAddr() 670 if la, ok := la.(*UDPAddr); !ok || la.Port == 0 { 671 return fmt.Errorf("got %v; want a proper address with non-zero port number", la) 672 } 673 return nil 674 } 675 676 func multicastRIBContains(ip IP) (bool, error) { 677 switch runtime.GOOS { 678 case "aix", "dragonfly", "netbsd", "openbsd", "plan9", "solaris", "illumos", "windows": 679 return true, nil // not implemented yet 680 case "linux": 681 if runtime.GOARCH == "arm" || runtime.GOARCH == "alpha" { 682 return true, nil // not implemented yet 683 } 684 } 685 ift, err := Interfaces() 686 if err != nil { 687 return false, err 688 } 689 for _, ifi := range ift { 690 ifmat, err := ifi.MulticastAddrs() 691 if err != nil { 692 return false, err 693 } 694 for _, ifma := range ifmat { 695 if ifma.(*IPAddr).IP.Equal(ip) { 696 return true, nil 697 } 698 } 699 } 700 return false, nil 701 } 702 703 // Issue 21856. 704 func TestClosingListener(t *testing.T) { 705 ln, err := newLocalListener("tcp") 706 if err != nil { 707 t.Fatal(err) 708 } 709 addr := ln.Addr() 710 711 go func() { 712 for { 713 c, err := ln.Accept() 714 if err != nil { 715 return 716 } 717 c.Close() 718 } 719 }() 720 721 // Let the goroutine start. We don't sleep long: if the 722 // goroutine doesn't start, the test will pass without really 723 // testing anything, which is OK. 724 time.Sleep(time.Millisecond) 725 726 ln.Close() 727 728 ln2, err := Listen("tcp", addr.String()) 729 if err != nil { 730 t.Fatal(err) 731 } 732 ln2.Close() 733 } 734 735 func TestListenConfigControl(t *testing.T) { 736 switch runtime.GOOS { 737 case "plan9": 738 t.Skipf("not supported on %s", runtime.GOOS) 739 } 740 741 t.Run("StreamListen", func(t *testing.T) { 742 for _, network := range []string{"tcp", "tcp4", "tcp6", "unix", "unixpacket"} { 743 if !testableNetwork(network) { 744 continue 745 } 746 ln, err := newLocalListener(network) 747 if err != nil { 748 t.Error(err) 749 continue 750 } 751 address := ln.Addr().String() 752 ln.Close() 753 lc := ListenConfig{Control: controlOnConnSetup} 754 ln, err = lc.Listen(context.Background(), network, address) 755 if err != nil { 756 t.Error(err) 757 continue 758 } 759 ln.Close() 760 } 761 }) 762 t.Run("PacketListen", func(t *testing.T) { 763 for _, network := range []string{"udp", "udp4", "udp6", "unixgram"} { 764 if !testableNetwork(network) { 765 continue 766 } 767 c, err := newLocalPacketListener(network) 768 if err != nil { 769 t.Error(err) 770 continue 771 } 772 address := c.LocalAddr().String() 773 c.Close() 774 if network == "unixgram" { 775 os.Remove(address) 776 } 777 lc := ListenConfig{Control: controlOnConnSetup} 778 c, err = lc.ListenPacket(context.Background(), network, address) 779 if err != nil { 780 t.Error(err) 781 continue 782 } 783 c.Close() 784 if network == "unixgram" { 785 os.Remove(address) 786 } 787 } 788 }) 789 }