compiler: Do not declare type switch variable outside case statements.
[official-gcc.git] / libgo / go / net / unicast_posix_test.go
blobab7ef40a758da8bc58523235072bfd28638dc8ba
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.
5 // +build !plan9
7 package net
9 import (
10 "runtime"
11 "syscall"
12 "testing"
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
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},
26 {net: "tcp", laddr: "127.0.0.1"},
27 {net: "tcp", laddr: "[::ffff:127.0.0.1]"},
28 {net: "tcp", laddr: "[::1]", ipv6: true},
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},
34 {net: "tcp4", laddr: "127.0.0.1"},
35 {net: "tcp4", laddr: "[::ffff:127.0.0.1]"},
37 {net: "tcp6", laddr: "", ipv6: true, wildcard: true},
38 {net: "tcp6", laddr: "[::]", ipv6: true, wildcard: true},
40 {net: "tcp6", laddr: "[::1]", ipv6: true},
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)
52 for _, tt := range listenerTests {
53 if tt.wildcard && (testing.Short() || !*testExternal) {
54 continue
56 if tt.ipv6 && !supportsIPv6 {
57 continue
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()
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)
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"
85 return "<nil>"
88 for _, tt := range listenerTests {
89 if tt.wildcard && (testing.Short() || !*testExternal) {
90 continue
92 if tt.ipv6 && !supportsIPv6 {
93 continue
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()
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
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
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)
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},
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},
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},
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"},
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")
175 switch runtime.GOOS {
176 case "plan9":
177 t.Skipf("skipping test on %q", runtime.GOOS)
179 if !supportsIPv6 {
180 t.Skip("ipv6 is not supported")
183 for _, tt := range dualStackListenerTests {
184 if tt.wildcard && !*testExternal {
185 continue
187 switch runtime.GOOS {
188 case "openbsd":
189 if tt.wildcard && differentWildcardAddr(tt.laddr1, tt.laddr2) {
190 tt.xerr = nil
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()
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")
210 switch runtime.GOOS {
211 case "plan9":
212 t.Skipf("skipping test on %q", runtime.GOOS)
214 if !supportsIPv6 {
215 t.Skip("ipv6 is not supported")
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"
227 return "<nil>"
230 for _, tt := range dualStackListenerTests {
231 if tt.wildcard && (testing.Short() || !*testExternal) {
232 continue
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
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()
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)
263 nladdr = l.(*TCPListener).Addr().String()
265 _, port, err = SplitHostPort(nladdr)
266 if err != nil {
267 t.Fatalf("SplitHostPort failed: %v", err)
269 return l, port
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)
283 nladdr = l.(*UDPConn).LocalAddr().String()
285 _, port, err = SplitHostPort(nladdr)
286 if err != nil {
287 t.Fatalf("SplitHostPort failed: %v", err)
289 return l, port
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
296 if i == "[::]" && j == "[::]" {
297 return false
299 return true
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)
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)
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)
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)
330 default:
331 t.Fatalf("Unexpected network: %q", net)
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)
342 case "udp", "udp4", "udp6":
343 if err == nil {
344 l.(*UDPConn).Close()
345 t.Fatalf("Second ListenPacket(%q, %q) should fail", net, laddr)
347 default:
348 t.Fatalf("Unexpected network: %q", net)
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)
358 if err == nil {
359 l.(*TCPListener).Close()
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)
365 if err == nil {
366 l.(*UDPConn).Close()
368 default:
369 t.Fatalf("Unexpected network: %q", net)
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)
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())
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)
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())
403 default:
404 t.Fatalf("Unexpected protocol address type: %T", a)
408 var prohibitionaryDialArgTests = []struct {
409 net string
410 addr string
412 {"tcp6", "127.0.0.1"},
413 {"tcp6", "[::ffff:127.0.0.1]"},
416 func TestProhibitionaryDialArgs(t *testing.T) {
417 switch runtime.GOOS {
418 case "plan9":
419 t.Skipf("skipping test on %q", runtime.GOOS)
421 // This test requires both IPv6 and IPv6 IPv4-mapping functionality.
422 if !supportsIPv4map || testing.Short() || !*testExternal {
423 return
426 l, port := usableListenPort(t, "tcp", "[::]")
427 defer l.Close()
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)
438 func TestWildWildcardListener(t *testing.T) {
439 switch runtime.GOOS {
440 case "plan9":
441 t.Skipf("skipping test on %q", runtime.GOOS)
444 if testing.Short() || !*testExternal {
445 t.Skip("skipping test to avoid external network")
448 defer func() {
449 if p := recover(); p != nil {
450 t.Fatalf("Listen, ListenPacket or protocol-specific Listen panicked: %v", p)
454 if ln, err := Listen("tcp", ""); err == nil {
455 ln.Close()
457 if ln, err := ListenPacket("udp", ""); err == nil {
458 ln.Close()
460 if ln, err := ListenTCP("tcp", nil); err == nil {
461 ln.Close()
463 if ln, err := ListenUDP("udp", nil); err == nil {
464 ln.Close()
466 if ln, err := ListenIP("ip:icmp", nil); err == nil {
467 ln.Close()