github.com/roboticscm/goman@v0.0.0-20210203095141-87c07b4a0a55/src/net/unicast_posix_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 "runtime" 11 "syscall" 12 "testing" 13 ) 14 15 var listenerTests = []struct { 16 net string 17 laddr string 18 ipv6 bool // test with underlying AF_INET6 socket 19 wildcard bool // test with wildcard address 20 }{ 21 {net: "tcp", laddr: "", wildcard: true}, 22 {net: "tcp", laddr: "0.0.0.0", wildcard: true}, 23 {net: "tcp", laddr: "[::ffff:0.0.0.0]", wildcard: true}, 24 {net: "tcp", laddr: "[::]", ipv6: true, wildcard: true}, 25 26 {net: "tcp", laddr: "127.0.0.1"}, 27 {net: "tcp", laddr: "[::ffff:127.0.0.1]"}, 28 {net: "tcp", laddr: "[::1]", ipv6: true}, 29 30 {net: "tcp4", laddr: "", wildcard: true}, 31 {net: "tcp4", laddr: "0.0.0.0", wildcard: true}, 32 {net: "tcp4", laddr: "[::ffff:0.0.0.0]", wildcard: true}, 33 34 {net: "tcp4", laddr: "127.0.0.1"}, 35 {net: "tcp4", laddr: "[::ffff:127.0.0.1]"}, 36 37 {net: "tcp6", laddr: "", ipv6: true, wildcard: true}, 38 {net: "tcp6", laddr: "[::]", ipv6: true, wildcard: true}, 39 40 {net: "tcp6", laddr: "[::1]", ipv6: true}, 41 } 42 43 // TestTCPListener tests both single and double listen to a test 44 // listener with same address family, same listening address and 45 // same port. 46 func TestTCPListener(t *testing.T) { 47 switch runtime.GOOS { 48 case "plan9": 49 t.Skipf("skipping test on %q", runtime.GOOS) 50 } 51 52 for _, tt := range listenerTests { 53 if tt.wildcard && (testing.Short() || !*testExternal) { 54 continue 55 } 56 if tt.ipv6 && !supportsIPv6 { 57 continue 58 } 59 l1, port := usableListenPort(t, tt.net, tt.laddr) 60 checkFirstListener(t, tt.net, tt.laddr+":"+port, l1) 61 l2, err := Listen(tt.net, tt.laddr+":"+port) 62 checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2) 63 l1.Close() 64 } 65 } 66 67 // TestUDPListener tests both single and double listen to a test 68 // listener with same address family, same listening address and 69 // same port. 70 func TestUDPListener(t *testing.T) { 71 switch runtime.GOOS { 72 case "plan9": 73 t.Skipf("skipping test on %q", runtime.GOOS) 74 } 75 76 toudpnet := func(net string) string { 77 switch net { 78 case "tcp": 79 return "udp" 80 case "tcp4": 81 return "udp4" 82 case "tcp6": 83 return "udp6" 84 } 85 return "<nil>" 86 } 87 88 for _, tt := range listenerTests { 89 if tt.wildcard && (testing.Short() || !*testExternal) { 90 continue 91 } 92 if tt.ipv6 && !supportsIPv6 { 93 continue 94 } 95 tt.net = toudpnet(tt.net) 96 l1, port := usableListenPacketPort(t, tt.net, tt.laddr) 97 checkFirstListener(t, tt.net, tt.laddr+":"+port, l1) 98 l2, err := ListenPacket(tt.net, tt.laddr+":"+port) 99 checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2) 100 l1.Close() 101 } 102 } 103 104 var dualStackListenerTests = []struct { 105 net1 string // first listener 106 laddr1 string 107 net2 string // second listener 108 laddr2 string 109 wildcard bool // test with wildcard address 110 xerr error // expected error value, nil or other 111 }{ 112 // Test cases and expected results for the attemping 2nd listen on the same port 113 // 1st listen 2nd listen darwin freebsd linux openbsd 114 // ------------------------------------------------------------------------------------ 115 // "tcp" "" "tcp" "" - - - - 116 // "tcp" "" "tcp" "0.0.0.0" - - - - 117 // "tcp" "0.0.0.0" "tcp" "" - - - - 118 // ------------------------------------------------------------------------------------ 119 // "tcp" "" "tcp" "[::]" - - - ok 120 // "tcp" "[::]" "tcp" "" - - - ok 121 // "tcp" "0.0.0.0" "tcp" "[::]" - - - ok 122 // "tcp" "[::]" "tcp" "0.0.0.0" - - - ok 123 // "tcp" "[::ffff:0.0.0.0]" "tcp" "[::]" - - - ok 124 // "tcp" "[::]" "tcp" "[::ffff:0.0.0.0]" - - - ok 125 // ------------------------------------------------------------------------------------ 126 // "tcp4" "" "tcp6" "" ok ok ok ok 127 // "tcp6" "" "tcp4" "" ok ok ok ok 128 // "tcp4" "0.0.0.0" "tcp6" "[::]" ok ok ok ok 129 // "tcp6" "[::]" "tcp4" "0.0.0.0" ok ok ok ok 130 // ------------------------------------------------------------------------------------ 131 // "tcp" "127.0.0.1" "tcp" "[::1]" ok ok ok ok 132 // "tcp" "[::1]" "tcp" "127.0.0.1" ok ok ok ok 133 // "tcp4" "127.0.0.1" "tcp6" "[::1]" ok ok ok ok 134 // "tcp6" "[::1]" "tcp4" "127.0.0.1" ok ok ok ok 135 // 136 // Platform default configurations: 137 // darwin, kernel version 11.3.0 138 // net.inet6.ip6.v6only=0 (overridable by sysctl or IPV6_V6ONLY option) 139 // freebsd, kernel version 8.2 140 // net.inet6.ip6.v6only=1 (overridable by sysctl or IPV6_V6ONLY option) 141 // linux, kernel version 3.0.0 142 // net.ipv6.bindv6only=0 (overridable by sysctl or IPV6_V6ONLY option) 143 // openbsd, kernel version 5.0 144 // net.inet6.ip6.v6only=1 (overriding is prohibited) 145 146 {net1: "tcp", laddr1: "", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE}, 147 {net1: "tcp", laddr1: "", net2: "tcp", laddr2: "0.0.0.0", wildcard: true, xerr: syscall.EADDRINUSE}, 148 {net1: "tcp", laddr1: "0.0.0.0", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE}, 149 150 {net1: "tcp", laddr1: "", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE}, 151 {net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE}, 152 {net1: "tcp", laddr1: "0.0.0.0", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE}, 153 {net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "0.0.0.0", wildcard: true, xerr: syscall.EADDRINUSE}, 154 {net1: "tcp", laddr1: "[::ffff:0.0.0.0]", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE}, 155 {net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "[::ffff:0.0.0.0]", wildcard: true, xerr: syscall.EADDRINUSE}, 156 157 {net1: "tcp4", laddr1: "", net2: "tcp6", laddr2: "", wildcard: true}, 158 {net1: "tcp6", laddr1: "", net2: "tcp4", laddr2: "", wildcard: true}, 159 {net1: "tcp4", laddr1: "0.0.0.0", net2: "tcp6", laddr2: "[::]", wildcard: true}, 160 {net1: "tcp6", laddr1: "[::]", net2: "tcp4", laddr2: "0.0.0.0", wildcard: true}, 161 162 {net1: "tcp", laddr1: "127.0.0.1", net2: "tcp", laddr2: "[::1]"}, 163 {net1: "tcp", laddr1: "[::1]", net2: "tcp", laddr2: "127.0.0.1"}, 164 {net1: "tcp4", laddr1: "127.0.0.1", net2: "tcp6", laddr2: "[::1]"}, 165 {net1: "tcp6", laddr1: "[::1]", net2: "tcp4", laddr2: "127.0.0.1"}, 166 } 167 168 // TestDualStackTCPListener tests both single and double listen 169 // to a test listener with various address families, different 170 // listening address and same port. 171 func TestDualStackTCPListener(t *testing.T) { 172 if testing.Short() { 173 t.Skip("skipping in -short mode, see issue 5001") 174 } 175 switch runtime.GOOS { 176 case "plan9": 177 t.Skipf("skipping test on %q", runtime.GOOS) 178 } 179 if !supportsIPv6 { 180 t.Skip("ipv6 is not supported") 181 } 182 183 for _, tt := range dualStackListenerTests { 184 if tt.wildcard && !*testExternal { 185 continue 186 } 187 switch runtime.GOOS { 188 case "openbsd": 189 if tt.wildcard && differentWildcardAddr(tt.laddr1, tt.laddr2) { 190 tt.xerr = nil 191 } 192 } 193 l1, port := usableListenPort(t, tt.net1, tt.laddr1) 194 laddr := tt.laddr1 + ":" + port 195 checkFirstListener(t, tt.net1, laddr, l1) 196 laddr = tt.laddr2 + ":" + port 197 l2, err := Listen(tt.net2, laddr) 198 checkDualStackSecondListener(t, tt.net2, laddr, tt.xerr, err, l2) 199 l1.Close() 200 } 201 } 202 203 // TestDualStackUDPListener tests both single and double listen 204 // to a test listener with various address families, differnet 205 // listening address and same port. 206 func TestDualStackUDPListener(t *testing.T) { 207 if testing.Short() { 208 t.Skip("skipping in -short mode, see issue 5001") 209 } 210 switch runtime.GOOS { 211 case "plan9": 212 t.Skipf("skipping test on %q", runtime.GOOS) 213 } 214 if !supportsIPv6 { 215 t.Skip("ipv6 is not supported") 216 } 217 218 toudpnet := func(net string) string { 219 switch net { 220 case "tcp": 221 return "udp" 222 case "tcp4": 223 return "udp4" 224 case "tcp6": 225 return "udp6" 226 } 227 return "<nil>" 228 } 229 230 for _, tt := range dualStackListenerTests { 231 if tt.wildcard && (testing.Short() || !*testExternal) { 232 continue 233 } 234 tt.net1 = toudpnet(tt.net1) 235 tt.net2 = toudpnet(tt.net2) 236 switch runtime.GOOS { 237 case "openbsd": 238 if tt.wildcard && differentWildcardAddr(tt.laddr1, tt.laddr2) { 239 tt.xerr = nil 240 } 241 } 242 l1, port := usableListenPacketPort(t, tt.net1, tt.laddr1) 243 laddr := tt.laddr1 + ":" + port 244 checkFirstListener(t, tt.net1, laddr, l1) 245 laddr = tt.laddr2 + ":" + port 246 l2, err := ListenPacket(tt.net2, laddr) 247 checkDualStackSecondListener(t, tt.net2, laddr, tt.xerr, err, l2) 248 l1.Close() 249 } 250 } 251 252 func usableListenPort(t *testing.T, net, laddr string) (l Listener, port string) { 253 var nladdr string 254 var err error 255 switch net { 256 default: 257 panic("usableListenPort net=" + net) 258 case "tcp", "tcp4", "tcp6": 259 l, err = Listen(net, laddr+":0") 260 if err != nil { 261 t.Fatalf("Probe Listen(%q, %q) failed: %v", net, laddr, err) 262 } 263 nladdr = l.(*TCPListener).Addr().String() 264 } 265 _, port, err = SplitHostPort(nladdr) 266 if err != nil { 267 t.Fatalf("SplitHostPort failed: %v", err) 268 } 269 return l, port 270 } 271 272 func usableListenPacketPort(t *testing.T, net, laddr string) (l PacketConn, port string) { 273 var nladdr string 274 var err error 275 switch net { 276 default: 277 panic("usableListenPacketPort net=" + net) 278 case "udp", "udp4", "udp6": 279 l, err = ListenPacket(net, laddr+":0") 280 if err != nil { 281 t.Fatalf("Probe ListenPacket(%q, %q) failed: %v", net, laddr, err) 282 } 283 nladdr = l.(*UDPConn).LocalAddr().String() 284 } 285 _, port, err = SplitHostPort(nladdr) 286 if err != nil { 287 t.Fatalf("SplitHostPort failed: %v", err) 288 } 289 return l, port 290 } 291 292 func differentWildcardAddr(i, j string) bool { 293 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") { 294 return false 295 } 296 if i == "[::]" && j == "[::]" { 297 return false 298 } 299 return true 300 } 301 302 func checkFirstListener(t *testing.T, net, laddr string, l interface{}) { 303 switch net { 304 case "tcp": 305 fd := l.(*TCPListener).fd 306 checkDualStackAddrFamily(t, net, laddr, fd) 307 case "tcp4": 308 fd := l.(*TCPListener).fd 309 if fd.family != syscall.AF_INET { 310 t.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET) 311 } 312 case "tcp6": 313 fd := l.(*TCPListener).fd 314 if fd.family != syscall.AF_INET6 { 315 t.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6) 316 } 317 case "udp": 318 fd := l.(*UDPConn).fd 319 checkDualStackAddrFamily(t, net, laddr, fd) 320 case "udp4": 321 fd := l.(*UDPConn).fd 322 if fd.family != syscall.AF_INET { 323 t.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET) 324 } 325 case "udp6": 326 fd := l.(*UDPConn).fd 327 if fd.family != syscall.AF_INET6 { 328 t.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6) 329 } 330 default: 331 t.Fatalf("Unexpected network: %q", net) 332 } 333 } 334 335 func checkSecondListener(t *testing.T, net, laddr string, err error, l interface{}) { 336 switch net { 337 case "tcp", "tcp4", "tcp6": 338 if err == nil { 339 l.(*TCPListener).Close() 340 t.Fatalf("Second Listen(%q, %q) should fail", net, laddr) 341 } 342 case "udp", "udp4", "udp6": 343 if err == nil { 344 l.(*UDPConn).Close() 345 t.Fatalf("Second ListenPacket(%q, %q) should fail", net, laddr) 346 } 347 default: 348 t.Fatalf("Unexpected network: %q", net) 349 } 350 } 351 352 func checkDualStackSecondListener(t *testing.T, net, laddr string, xerr, err error, l interface{}) { 353 switch net { 354 case "tcp", "tcp4", "tcp6": 355 if xerr == nil && err != nil || xerr != nil && err == nil { 356 t.Fatalf("Second Listen(%q, %q) returns %v, expected %v", net, laddr, err, xerr) 357 } 358 if err == nil { 359 l.(*TCPListener).Close() 360 } 361 case "udp", "udp4", "udp6": 362 if xerr == nil && err != nil || xerr != nil && err == nil { 363 t.Fatalf("Second ListenPacket(%q, %q) returns %v, expected %v", net, laddr, err, xerr) 364 } 365 if err == nil { 366 l.(*UDPConn).Close() 367 } 368 default: 369 t.Fatalf("Unexpected network: %q", net) 370 } 371 } 372 373 func checkDualStackAddrFamily(t *testing.T, net, laddr string, fd *netFD) { 374 switch a := fd.laddr.(type) { 375 case *TCPAddr: 376 // If a node under test supports both IPv6 capability 377 // and IPv6 IPv4-mapping capability, we can assume 378 // that the node listens on a wildcard address with an 379 // AF_INET6 socket. 380 if supportsIPv4map && fd.laddr.(*TCPAddr).isWildcard() { 381 if fd.family != syscall.AF_INET6 { 382 t.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6) 383 } 384 } else { 385 if fd.family != a.family() { 386 t.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, a.family()) 387 } 388 } 389 case *UDPAddr: 390 // If a node under test supports both IPv6 capability 391 // and IPv6 IPv4-mapping capability, we can assume 392 // that the node listens on a wildcard address with an 393 // AF_INET6 socket. 394 if supportsIPv4map && fd.laddr.(*UDPAddr).isWildcard() { 395 if fd.family != syscall.AF_INET6 { 396 t.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6) 397 } 398 } else { 399 if fd.family != a.family() { 400 t.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, a.family()) 401 } 402 } 403 default: 404 t.Fatalf("Unexpected protocol address type: %T", a) 405 } 406 } 407 408 var prohibitionaryDialArgTests = []struct { 409 net string 410 addr string 411 }{ 412 {"tcp6", "127.0.0.1"}, 413 {"tcp6", "[::ffff:127.0.0.1]"}, 414 } 415 416 func TestProhibitionaryDialArgs(t *testing.T) { 417 switch runtime.GOOS { 418 case "plan9": 419 t.Skipf("skipping test on %q", runtime.GOOS) 420 } 421 // This test requires both IPv6 and IPv6 IPv4-mapping functionality. 422 if !supportsIPv4map || testing.Short() || !*testExternal { 423 return 424 } 425 426 l, port := usableListenPort(t, "tcp", "[::]") 427 defer l.Close() 428 429 for _, tt := range prohibitionaryDialArgTests { 430 c, err := Dial(tt.net, tt.addr+":"+port) 431 if err == nil { 432 c.Close() 433 t.Fatalf("Dial(%q, %q) should fail", tt.net, tt.addr) 434 } 435 } 436 } 437 438 func TestWildWildcardListener(t *testing.T) { 439 switch runtime.GOOS { 440 case "plan9": 441 t.Skipf("skipping test on %q", runtime.GOOS) 442 } 443 444 if testing.Short() || !*testExternal { 445 t.Skip("skipping test to avoid external network") 446 } 447 448 defer func() { 449 if p := recover(); p != nil { 450 t.Fatalf("Listen, ListenPacket or protocol-specific Listen panicked: %v", p) 451 } 452 }() 453 454 if ln, err := Listen("tcp", ""); err == nil { 455 ln.Close() 456 } 457 if ln, err := ListenPacket("udp", ""); err == nil { 458 ln.Close() 459 } 460 if ln, err := ListenTCP("tcp", nil); err == nil { 461 ln.Close() 462 } 463 if ln, err := ListenUDP("udp", nil); err == nil { 464 ln.Close() 465 } 466 if ln, err := ListenIP("ip:icmp", nil); err == nil { 467 ln.Close() 468 } 469 }