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 !js,!plan9 6 7 package net 8 9 import ( 10 "context" 11 "fmt" 12 "internal/testenv" 13 "os" 14 "runtime" 15 "syscall" 16 "testing" 17 "time" 18 ) 19 20 func (ln *TCPListener) port() string { 21 _, port, err := SplitHostPort(ln.Addr().String()) 22 if err != nil { 23 return "" 24 } 25 return port 26 } 27 28 func (c *UDPConn) port() string { 29 _, port, err := SplitHostPort(c.LocalAddr().String()) 30 if err != nil { 31 return "" 32 } 33 return port 34 } 35 36 var tcpListenerTests = []struct { 37 network string 38 address string 39 }{ 40 {"tcp", ""}, 41 {"tcp", "0.0.0.0"}, 42 {"tcp", "::ffff:0.0.0.0"}, 43 {"tcp", "::"}, 44 45 {"tcp", "127.0.0.1"}, 46 {"tcp", "::ffff:127.0.0.1"}, 47 {"tcp", "::1"}, 48 49 {"tcp4", ""}, 50 {"tcp4", "0.0.0.0"}, 51 {"tcp4", "::ffff:0.0.0.0"}, 52 53 {"tcp4", "127.0.0.1"}, 54 {"tcp4", "::ffff:127.0.0.1"}, 55 56 {"tcp6", ""}, 57 {"tcp6", "::"}, 58 59 {"tcp6", "::1"}, 60 } 61 62 // TestTCPListener tests both single and double listen to a test 63 // listener with same address family, same listening address and 64 // same port. 65 func TestTCPListener(t *testing.T) { 66 switch runtime.GOOS { 67 case "plan9": 68 t.Skipf("not supported on %s", runtime.GOOS) 69 } 70 71 for _, tt := range tcpListenerTests { 72 if !testableListenArgs(tt.network, JoinHostPort(tt.address, "0"), "") { 73 t.Logf("skipping %s test", tt.network+" "+tt.address) 74 continue 75 } 76 77 ln1, err := Listen(tt.network, JoinHostPort(tt.address, "0")) 78 if err != nil { 79 t.Fatal(err) 80 } 81 if err := checkFirstListener(tt.network, ln1); err != nil { 82 ln1.Close() 83 t.Fatal(err) 84 } 85 ln2, err := Listen(tt.network, JoinHostPort(tt.address, ln1.(*TCPListener).port())) 86 if err == nil { 87 ln2.Close() 88 } 89 if err := checkSecondListener(tt.network, tt.address, err); err != nil { 90 ln1.Close() 91 t.Fatal(err) 92 } 93 ln1.Close() 94 } 95 } 96 97 var udpListenerTests = []struct { 98 network string 99 address string 100 }{ 101 {"udp", ""}, 102 {"udp", "0.0.0.0"}, 103 {"udp", "::ffff:0.0.0.0"}, 104 {"udp", "::"}, 105 106 {"udp", "127.0.0.1"}, 107 {"udp", "::ffff:127.0.0.1"}, 108 {"udp", "::1"}, 109 110 {"udp4", ""}, 111 {"udp4", "0.0.0.0"}, 112 {"udp4", "::ffff:0.0.0.0"}, 113 114 {"udp4", "127.0.0.1"}, 115 {"udp4", "::ffff:127.0.0.1"}, 116 117 {"udp6", ""}, 118 {"udp6", "::"}, 119 120 {"udp6", "::1"}, 121 } 122 123 // TestUDPListener tests both single and double listen to a test 124 // listener with same address family, same listening address and 125 // same port. 126 func TestUDPListener(t *testing.T) { 127 switch runtime.GOOS { 128 case "plan9": 129 t.Skipf("not supported on %s", runtime.GOOS) 130 } 131 132 for _, tt := range udpListenerTests { 133 if !testableListenArgs(tt.network, JoinHostPort(tt.address, "0"), "") { 134 t.Logf("skipping %s test", tt.network+" "+tt.address) 135 continue 136 } 137 138 c1, err := ListenPacket(tt.network, JoinHostPort(tt.address, "0")) 139 if err != nil { 140 t.Fatal(err) 141 } 142 if err := checkFirstListener(tt.network, c1); err != nil { 143 c1.Close() 144 t.Fatal(err) 145 } 146 c2, err := ListenPacket(tt.network, JoinHostPort(tt.address, c1.(*UDPConn).port())) 147 if err == nil { 148 c2.Close() 149 } 150 if err := checkSecondListener(tt.network, tt.address, err); err != nil { 151 c1.Close() 152 t.Fatal(err) 153 } 154 c1.Close() 155 } 156 } 157 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 162 }{ 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 186 // 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) 196 197 {"tcp", "", "tcp", "", syscall.EADDRINUSE}, 198 {"tcp", "", "tcp", "0.0.0.0", syscall.EADDRINUSE}, 199 {"tcp", "0.0.0.0", "tcp", "", syscall.EADDRINUSE}, 200 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}, 207 208 {"tcp4", "", "tcp6", "", nil}, 209 {"tcp6", "", "tcp4", "", nil}, 210 {"tcp4", "0.0.0.0", "tcp6", "::", nil}, 211 {"tcp6", "::", "tcp4", "0.0.0.0", nil}, 212 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}, 217 } 218 219 // TestDualStackTCPListener tests both single and double listen 220 // to a test listener with various address families, different 221 // listening address and same port. 222 // 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) 229 } 230 if !supportsIPv4() || !supportsIPv6() { 231 t.Skip("both IPv4 and IPv6 are required") 232 } 233 234 for _, tt := range dualStackTCPListenerTests { 235 if !testableListenArgs(tt.network1, JoinHostPort(tt.address1, "0"), "") { 236 t.Logf("skipping %s test", tt.network1+" "+tt.address1) 237 continue 238 } 239 240 if !supportsIPv4map() && differentWildcardAddr(tt.address1, tt.address2) { 241 tt.xerr = nil 242 } 243 var firstErr, secondErr error 244 for i := 0; i < 5; i++ { 245 lns, err := newDualStackListener() 246 if err != nil { 247 t.Fatal(err) 248 } 249 port := lns[0].port() 250 for _, ln := range lns { 251 ln.Close() 252 } 253 var ln1 Listener 254 ln1, firstErr = Listen(tt.network1, JoinHostPort(tt.address1, port)) 255 if firstErr != nil { 256 continue 257 } 258 if err := checkFirstListener(tt.network1, ln1); err != nil { 259 ln1.Close() 260 t.Fatal(err) 261 } 262 ln2, err := Listen(tt.network2, JoinHostPort(tt.address2, ln1.(*TCPListener).port())) 263 if err == nil { 264 ln2.Close() 265 } 266 if secondErr = checkDualStackSecondListener(tt.network2, tt.address2, err, tt.xerr); secondErr != nil { 267 ln1.Close() 268 continue 269 } 270 ln1.Close() 271 break 272 } 273 if firstErr != nil { 274 t.Error(firstErr) 275 } 276 if secondErr != nil { 277 t.Error(secondErr) 278 } 279 } 280 } 281 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 286 }{ 287 {"udp", "", "udp", "", syscall.EADDRINUSE}, 288 {"udp", "", "udp", "0.0.0.0", syscall.EADDRINUSE}, 289 {"udp", "0.0.0.0", "udp", "", syscall.EADDRINUSE}, 290 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}, 297 298 {"udp4", "", "udp6", "", nil}, 299 {"udp6", "", "udp4", "", nil}, 300 {"udp4", "0.0.0.0", "udp6", "::", nil}, 301 {"udp6", "::", "udp4", "0.0.0.0", nil}, 302 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}, 307 } 308 309 // TestDualStackUDPListener tests both single and double listen 310 // to a test listener with various address families, different 311 // listening address and same port. 312 // 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) 319 } 320 if !supportsIPv4() || !supportsIPv6() { 321 t.Skip("both IPv4 and IPv6 are required") 322 } 323 324 for _, tt := range dualStackUDPListenerTests { 325 if !testableListenArgs(tt.network1, JoinHostPort(tt.address1, "0"), "") { 326 t.Logf("skipping %s test", tt.network1+" "+tt.address1) 327 continue 328 } 329 330 if !supportsIPv4map() && differentWildcardAddr(tt.address1, tt.address2) { 331 tt.xerr = nil 332 } 333 var firstErr, secondErr error 334 for i := 0; i < 5; i++ { 335 cs, err := newDualStackPacketListener() 336 if err != nil { 337 t.Fatal(err) 338 } 339 port := cs[0].port() 340 for _, c := range cs { 341 c.Close() 342 } 343 var c1 PacketConn 344 c1, firstErr = ListenPacket(tt.network1, JoinHostPort(tt.address1, port)) 345 if firstErr != nil { 346 continue 347 } 348 if err := checkFirstListener(tt.network1, c1); err != nil { 349 c1.Close() 350 t.Fatal(err) 351 } 352 c2, err := ListenPacket(tt.network2, JoinHostPort(tt.address2, c1.(*UDPConn).port())) 353 if err == nil { 354 c2.Close() 355 } 356 if secondErr = checkDualStackSecondListener(tt.network2, tt.address2, err, tt.xerr); secondErr != nil { 357 c1.Close() 358 continue 359 } 360 c1.Close() 361 break 362 } 363 if firstErr != nil { 364 t.Error(firstErr) 365 } 366 if secondErr != nil { 367 t.Error(secondErr) 368 } 369 } 370 } 371 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") { 374 return false 375 } 376 if i == "[::]" && j == "[::]" { 377 return false 378 } 379 return true 380 } 381 382 func checkFirstListener(network string, ln interface{}) error { 383 switch network { 384 case "tcp": 385 fd := ln.(*TCPListener).fd 386 if err := checkDualStackAddrFamily(fd); err != nil { 387 return err 388 } 389 case "tcp4": 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) 393 } 394 case "tcp6": 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) 398 } 399 case "udp": 400 fd := ln.(*UDPConn).fd 401 if err := checkDualStackAddrFamily(fd); err != nil { 402 return err 403 } 404 case "udp4": 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) 408 } 409 case "udp6": 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) 413 } 414 default: 415 return UnknownNetworkError(network) 416 } 417 return nil 418 } 419 420 func checkSecondListener(network, address string, err error) error { 421 switch network { 422 case "tcp", "tcp4", "tcp6": 423 if err == nil { 424 return fmt.Errorf("%s should fail", network+" "+address) 425 } 426 case "udp", "udp4", "udp6": 427 if err == nil { 428 return fmt.Errorf("%s should fail", network+" "+address) 429 } 430 default: 431 return UnknownNetworkError(network) 432 } 433 return nil 434 } 435 436 func checkDualStackSecondListener(network, address string, err, xerr error) error { 437 switch network { 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) 441 } 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) 445 } 446 default: 447 return UnknownNetworkError(network) 448 } 449 return nil 450 } 451 452 func checkDualStackAddrFamily(fd *netFD) error { 453 switch a := fd.laddr.(type) { 454 case *TCPAddr: 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 458 // AF_INET6 socket. 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) 462 } 463 } else { 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()) 466 } 467 } 468 case *UDPAddr: 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 472 // AF_INET6 socket. 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) 476 } 477 } else { 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()) 480 } 481 } 482 default: 483 return fmt.Errorf("unexpected protocol address type: %T", a) 484 } 485 return nil 486 } 487 488 func TestWildWildcardListener(t *testing.T) { 489 testenv.MustHaveExternalNetwork(t) 490 491 switch runtime.GOOS { 492 case "plan9": 493 t.Skipf("not supported on %s", runtime.GOOS) 494 } 495 496 defer func() { 497 if p := recover(); p != nil { 498 t.Fatalf("panicked: %v", p) 499 } 500 }() 501 502 if ln, err := Listen("tcp", ""); err == nil { 503 ln.Close() 504 } 505 if ln, err := ListenPacket("udp", ""); err == nil { 506 ln.Close() 507 } 508 if ln, err := ListenTCP("tcp", nil); err == nil { 509 ln.Close() 510 } 511 if ln, err := ListenUDP("udp", nil); err == nil { 512 ln.Close() 513 } 514 if ln, err := ListenIP("ip:icmp", nil); err == nil { 515 ln.Close() 516 } 517 } 518 519 var ipv4MulticastListenerTests = []struct { 520 net string 521 gaddr *UDPAddr // see RFC 4727 522 }{ 523 {"udp", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}}, 524 525 {"udp4", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}}, 526 } 527 528 // TestIPv4MulticastListener tests both single and double listen to a 529 // test listener with same address family, same group address and same 530 // port. 531 func TestIPv4MulticastListener(t *testing.T) { 532 testenv.MustHaveExternalNetwork(t) 533 534 switch runtime.GOOS { 535 case "android", "nacl", "plan9": 536 t.Skipf("not supported on %s", runtime.GOOS) 537 case "solaris", "illumos": 538 t.Skipf("not supported on solaris or illumos, see golang.org/issue/7399") 539 } 540 if !supportsIPv4() { 541 t.Skip("IPv4 is not supported") 542 } 543 544 closer := func(cs []*UDPConn) { 545 for _, c := range cs { 546 if c != nil { 547 c.Close() 548 } 549 } 550 } 551 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 557 // adjacencies. 558 if ifi == nil || !*testIPv4 { 559 continue 560 } 561 for _, tt := range ipv4MulticastListenerTests { 562 var err error 563 cs := make([]*UDPConn, 2) 564 if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil { 565 t.Fatal(err) 566 } 567 if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil { 568 closer(cs) 569 t.Fatal(err) 570 } 571 if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil { 572 closer(cs) 573 t.Fatal(err) 574 } 575 if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil { 576 closer(cs) 577 t.Fatal(err) 578 } 579 closer(cs) 580 } 581 } 582 } 583 584 var ipv6MulticastListenerTests = []struct { 585 net string 586 gaddr *UDPAddr // see RFC 4727 587 }{ 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}}, 594 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}}, 601 } 602 603 // TestIPv6MulticastListener tests both single and double listen to a 604 // test listener with same address family, same group address and same 605 // port. 606 func TestIPv6MulticastListener(t *testing.T) { 607 testenv.MustHaveExternalNetwork(t) 608 609 switch runtime.GOOS { 610 case "plan9": 611 t.Skipf("not supported on %s", runtime.GOOS) 612 case "solaris", "illumos": 613 t.Skipf("not supported on solaris or illumos, see issue 7399") 614 } 615 if !supportsIPv6() { 616 t.Skip("IPv6 is not supported") 617 } 618 if os.Getuid() != 0 { 619 t.Skip("must be root") 620 } 621 622 closer := func(cs []*UDPConn) { 623 for _, c := range cs { 624 if c != nil { 625 c.Close() 626 } 627 } 628 } 629 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 635 // adjacencies. 636 if ifi == nil && !*testIPv6 { 637 continue 638 } 639 for _, tt := range ipv6MulticastListenerTests { 640 var err error 641 cs := make([]*UDPConn, 2) 642 if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil { 643 t.Fatal(err) 644 } 645 if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil { 646 closer(cs) 647 t.Fatal(err) 648 } 649 if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil { 650 closer(cs) 651 t.Fatal(err) 652 } 653 if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil { 654 closer(cs) 655 t.Fatal(err) 656 } 657 closer(cs) 658 } 659 } 660 } 661 662 func checkMulticastListener(c *UDPConn, ip IP) error { 663 if ok, err := multicastRIBContains(ip); err != nil { 664 return err 665 } else if !ok { 666 return fmt.Errorf("%s not found in multicast rib", ip.String()) 667 } 668 la := c.LocalAddr() 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) 671 } 672 return nil 673 } 674 675 func multicastRIBContains(ip IP) (bool, error) { 676 switch runtime.GOOS { 677 case "aix", "dragonfly", "netbsd", "openbsd", "plan9", "solaris", "illumos", "windows": 678 return true, nil // not implemented yet 679 case "linux": 680 if runtime.GOARCH == "arm" || runtime.GOARCH == "alpha" { 681 return true, nil // not implemented yet 682 } 683 } 684 ift, err := Interfaces() 685 if err != nil { 686 return false, err 687 } 688 for _, ifi := range ift { 689 ifmat, err := ifi.MulticastAddrs() 690 if err != nil { 691 return false, err 692 } 693 for _, ifma := range ifmat { 694 if ifma.(*IPAddr).IP.Equal(ip) { 695 return true, nil 696 } 697 } 698 } 699 return false, nil 700 } 701 702 // Issue 21856. 703 func TestClosingListener(t *testing.T) { 704 ln, err := newLocalListener("tcp") 705 if err != nil { 706 t.Fatal(err) 707 } 708 addr := ln.Addr() 709 710 go func() { 711 for { 712 c, err := ln.Accept() 713 if err != nil { 714 return 715 } 716 c.Close() 717 } 718 }() 719 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) 724 725 ln.Close() 726 727 ln2, err := Listen("tcp", addr.String()) 728 if err != nil { 729 t.Fatal(err) 730 } 731 ln2.Close() 732 } 733 734 func TestListenConfigControl(t *testing.T) { 735 switch runtime.GOOS { 736 case "nacl", "plan9": 737 t.Skipf("not supported on %s", runtime.GOOS) 738 } 739 740 t.Run("StreamListen", func(t *testing.T) { 741 for _, network := range []string{"tcp", "tcp4", "tcp6", "unix", "unixpacket"} { 742 if !testableNetwork(network) { 743 continue 744 } 745 ln, err := newLocalListener(network) 746 if err != nil { 747 t.Error(err) 748 continue 749 } 750 address := ln.Addr().String() 751 ln.Close() 752 lc := ListenConfig{Control: controlOnConnSetup} 753 ln, err = lc.Listen(context.Background(), network, address) 754 if err != nil { 755 t.Error(err) 756 continue 757 } 758 ln.Close() 759 } 760 }) 761 t.Run("PacketListen", func(t *testing.T) { 762 for _, network := range []string{"udp", "udp4", "udp6", "unixgram"} { 763 if !testableNetwork(network) { 764 continue 765 } 766 c, err := newLocalPacketListener(network) 767 if err != nil { 768 t.Error(err) 769 continue 770 } 771 address := c.LocalAddr().String() 772 c.Close() 773 if network == "unixgram" { 774 os.Remove(address) 775 } 776 lc := ListenConfig{Control: controlOnConnSetup} 777 c, err = lc.ListenPacket(context.Background(), network, address) 778 if err != nil { 779 t.Error(err) 780 continue 781 } 782 c.Close() 783 if network == "unixgram" { 784 os.Remove(address) 785 } 786 } 787 }) 788 } 789
View as plain text