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