2013-02-11 Sebastian Huber <sebastian.huber@embedded-brains.de>
[official-gcc.git] / libgo / go / net / unicast_posix_test.go
bloba8855cab7da7441f9087b17d2a846430ccd81719
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", "windows":
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", "windows":
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 func TestSimpleTCPListener(t *testing.T) {
105 switch runtime.GOOS {
106 case "plan9":
107 t.Skipf("skipping test on %q", runtime.GOOS)
108 return
111 for _, tt := range listenerTests {
112 if tt.wildcard && (testing.Short() || !*testExternal) {
113 continue
115 if tt.ipv6 {
116 continue
118 l1, port := usableListenPort(t, tt.net, tt.laddr)
119 checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
120 l2, err := Listen(tt.net, tt.laddr+":"+port)
121 checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
122 l1.Close()
126 func TestSimpleUDPListener(t *testing.T) {
127 switch runtime.GOOS {
128 case "plan9":
129 t.Skipf("skipping test on %q", runtime.GOOS)
130 return
133 toudpnet := func(net string) string {
134 switch net {
135 case "tcp":
136 return "udp"
137 case "tcp4":
138 return "udp4"
139 case "tcp6":
140 return "udp6"
142 return "<nil>"
145 for _, tt := range listenerTests {
146 if tt.wildcard && (testing.Short() || !*testExternal) {
147 continue
149 if tt.ipv6 {
150 continue
152 tt.net = toudpnet(tt.net)
153 l1, port := usableListenPacketPort(t, tt.net, tt.laddr)
154 checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
155 l2, err := ListenPacket(tt.net, tt.laddr+":"+port)
156 checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
157 l1.Close()
161 var dualStackListenerTests = []struct {
162 net1 string // first listener
163 laddr1 string
164 net2 string // second listener
165 laddr2 string
166 wildcard bool // test with wildcard address
167 xerr error // expected error value, nil or other
169 // Test cases and expected results for the attemping 2nd listen on the same port
170 // 1st listen 2nd listen darwin freebsd linux openbsd
171 // ------------------------------------------------------------------------------------
172 // "tcp" "" "tcp" "" - - - -
173 // "tcp" "" "tcp" "0.0.0.0" - - - -
174 // "tcp" "0.0.0.0" "tcp" "" - - - -
175 // ------------------------------------------------------------------------------------
176 // "tcp" "" "tcp" "[::]" - - - ok
177 // "tcp" "[::]" "tcp" "" - - - ok
178 // "tcp" "0.0.0.0" "tcp" "[::]" - - - ok
179 // "tcp" "[::]" "tcp" "0.0.0.0" - - - ok
180 // "tcp" "[::ffff:0.0.0.0]" "tcp" "[::]" - - - ok
181 // "tcp" "[::]" "tcp" "[::ffff:0.0.0.0]" - - - ok
182 // ------------------------------------------------------------------------------------
183 // "tcp4" "" "tcp6" "" ok ok ok ok
184 // "tcp6" "" "tcp4" "" ok ok ok ok
185 // "tcp4" "0.0.0.0" "tcp6" "[::]" ok ok ok ok
186 // "tcp6" "[::]" "tcp4" "0.0.0.0" ok ok ok ok
187 // ------------------------------------------------------------------------------------
188 // "tcp" "127.0.0.1" "tcp" "[::1]" ok ok ok ok
189 // "tcp" "[::1]" "tcp" "127.0.0.1" ok ok ok ok
190 // "tcp4" "127.0.0.1" "tcp6" "[::1]" ok ok ok ok
191 // "tcp6" "[::1]" "tcp4" "127.0.0.1" ok ok ok ok
193 // Platform default configurations:
194 // darwin, kernel version 11.3.0
195 // net.inet6.ip6.v6only=0 (overridable by sysctl or IPV6_V6ONLY option)
196 // freebsd, kernel version 8.2
197 // net.inet6.ip6.v6only=1 (overridable by sysctl or IPV6_V6ONLY option)
198 // linux, kernel version 3.0.0
199 // net.ipv6.bindv6only=0 (overridable by sysctl or IPV6_V6ONLY option)
200 // openbsd, kernel version 5.0
201 // net.inet6.ip6.v6only=1 (overriding is prohibited)
203 {net1: "tcp", laddr1: "", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
204 {net1: "tcp", laddr1: "", net2: "tcp", laddr2: "0.0.0.0", wildcard: true, xerr: syscall.EADDRINUSE},
205 {net1: "tcp", laddr1: "0.0.0.0", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
207 {net1: "tcp", laddr1: "", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
208 {net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
209 {net1: "tcp", laddr1: "0.0.0.0", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
210 {net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "0.0.0.0", wildcard: true, xerr: syscall.EADDRINUSE},
211 {net1: "tcp", laddr1: "[::ffff:0.0.0.0]", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
212 {net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "[::ffff:0.0.0.0]", wildcard: true, xerr: syscall.EADDRINUSE},
214 {net1: "tcp4", laddr1: "", net2: "tcp6", laddr2: "", wildcard: true},
215 {net1: "tcp6", laddr1: "", net2: "tcp4", laddr2: "", wildcard: true},
216 {net1: "tcp4", laddr1: "0.0.0.0", net2: "tcp6", laddr2: "[::]", wildcard: true},
217 {net1: "tcp6", laddr1: "[::]", net2: "tcp4", laddr2: "0.0.0.0", wildcard: true},
219 {net1: "tcp", laddr1: "127.0.0.1", net2: "tcp", laddr2: "[::1]"},
220 {net1: "tcp", laddr1: "[::1]", net2: "tcp", laddr2: "127.0.0.1"},
221 {net1: "tcp4", laddr1: "127.0.0.1", net2: "tcp6", laddr2: "[::1]"},
222 {net1: "tcp6", laddr1: "[::1]", net2: "tcp4", laddr2: "127.0.0.1"},
225 // TestDualStackTCPListener tests both single and double listen
226 // to a test listener with various address families, differnet
227 // listening address and same port.
228 func TestDualStackTCPListener(t *testing.T) {
229 switch runtime.GOOS {
230 case "plan9":
231 t.Skipf("skipping test on %q", runtime.GOOS)
233 if !supportsIPv6 {
234 return
237 for _, tt := range dualStackListenerTests {
238 if tt.wildcard && (testing.Short() || !*testExternal) {
239 continue
241 switch runtime.GOOS {
242 case "openbsd":
243 if tt.wildcard && differentWildcardAddr(tt.laddr1, tt.laddr2) {
244 tt.xerr = nil
247 l1, port := usableListenPort(t, tt.net1, tt.laddr1)
248 laddr := tt.laddr1 + ":" + port
249 checkFirstListener(t, tt.net1, laddr, l1)
250 laddr = tt.laddr2 + ":" + port
251 l2, err := Listen(tt.net2, laddr)
252 checkDualStackSecondListener(t, tt.net2, laddr, tt.xerr, err, l2)
253 l1.Close()
257 // TestDualStackUDPListener tests both single and double listen
258 // to a test listener with various address families, differnet
259 // listening address and same port.
260 func TestDualStackUDPListener(t *testing.T) {
261 switch runtime.GOOS {
262 case "plan9":
263 t.Skipf("skipping test on %q", runtime.GOOS)
265 if !supportsIPv6 {
266 return
269 toudpnet := func(net string) string {
270 switch net {
271 case "tcp":
272 return "udp"
273 case "tcp4":
274 return "udp4"
275 case "tcp6":
276 return "udp6"
278 return "<nil>"
281 for _, tt := range dualStackListenerTests {
282 if tt.wildcard && (testing.Short() || !*testExternal) {
283 continue
285 tt.net1 = toudpnet(tt.net1)
286 tt.net2 = toudpnet(tt.net2)
287 switch runtime.GOOS {
288 case "openbsd":
289 if tt.wildcard && differentWildcardAddr(tt.laddr1, tt.laddr2) {
290 tt.xerr = nil
293 l1, port := usableListenPacketPort(t, tt.net1, tt.laddr1)
294 laddr := tt.laddr1 + ":" + port
295 checkFirstListener(t, tt.net1, laddr, l1)
296 laddr = tt.laddr2 + ":" + port
297 l2, err := ListenPacket(tt.net2, laddr)
298 checkDualStackSecondListener(t, tt.net2, laddr, tt.xerr, err, l2)
299 l1.Close()
303 func usableListenPort(t *testing.T, net, laddr string) (l Listener, port string) {
304 var nladdr string
305 var err error
306 switch net {
307 default:
308 panic("usableListenPort net=" + net)
309 case "tcp", "tcp4", "tcp6":
310 l, err = Listen(net, laddr+":0")
311 if err != nil {
312 t.Fatalf("Probe Listen(%q, %q) failed: %v", net, laddr, err)
314 nladdr = l.(*TCPListener).Addr().String()
316 _, port, err = SplitHostPort(nladdr)
317 if err != nil {
318 t.Fatalf("SplitHostPort failed: %v", err)
320 return l, port
323 func usableListenPacketPort(t *testing.T, net, laddr string) (l PacketConn, port string) {
324 var nladdr string
325 var err error
326 switch net {
327 default:
328 panic("usableListenPacketPort net=" + net)
329 case "udp", "udp4", "udp6":
330 l, err = ListenPacket(net, laddr+":0")
331 if err != nil {
332 t.Fatalf("Probe ListenPacket(%q, %q) failed: %v", net, laddr, err)
334 nladdr = l.(*UDPConn).LocalAddr().String()
336 _, port, err = SplitHostPort(nladdr)
337 if err != nil {
338 t.Fatalf("SplitHostPort failed: %v", err)
340 return l, port
343 func differentWildcardAddr(i, j string) bool {
344 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") {
345 return false
347 if i == "[::]" && j == "[::]" {
348 return false
350 return true
353 func checkFirstListener(t *testing.T, net, laddr string, l interface{}) {
354 switch net {
355 case "tcp":
356 fd := l.(*TCPListener).fd
357 checkDualStackAddrFamily(t, net, laddr, fd)
358 case "tcp4":
359 fd := l.(*TCPListener).fd
360 if fd.family != syscall.AF_INET {
361 t.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET)
363 case "tcp6":
364 fd := l.(*TCPListener).fd
365 if fd.family != syscall.AF_INET6 {
366 t.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
368 case "udp":
369 fd := l.(*UDPConn).fd
370 checkDualStackAddrFamily(t, net, laddr, fd)
371 case "udp4":
372 fd := l.(*UDPConn).fd
373 if fd.family != syscall.AF_INET {
374 t.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET)
376 case "udp6":
377 fd := l.(*UDPConn).fd
378 if fd.family != syscall.AF_INET6 {
379 t.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
381 default:
382 t.Fatalf("Unexpected network: %q", net)
386 func checkSecondListener(t *testing.T, net, laddr string, err error, l interface{}) {
387 switch net {
388 case "tcp", "tcp4", "tcp6":
389 if err == nil {
390 l.(*TCPListener).Close()
391 t.Fatalf("Second Listen(%q, %q) should fail", net, laddr)
393 case "udp", "udp4", "udp6":
394 if err == nil {
395 l.(*UDPConn).Close()
396 t.Fatalf("Second ListenPacket(%q, %q) should fail", net, laddr)
398 default:
399 t.Fatalf("Unexpected network: %q", net)
403 func checkDualStackSecondListener(t *testing.T, net, laddr string, xerr, err error, l interface{}) {
404 switch net {
405 case "tcp", "tcp4", "tcp6":
406 if xerr == nil && err != nil || xerr != nil && err == nil {
407 t.Fatalf("Second Listen(%q, %q) returns %v, expected %v", net, laddr, err, xerr)
409 l.(*TCPListener).Close()
410 case "udp", "udp4", "udp6":
411 if xerr == nil && err != nil || xerr != nil && err == nil {
412 t.Fatalf("Second ListenPacket(%q, %q) returns %v, expected %v", net, laddr, err, xerr)
414 l.(*UDPConn).Close()
415 default:
416 t.Fatalf("Unexpected network: %q", net)
420 func checkDualStackAddrFamily(t *testing.T, net, laddr string, fd *netFD) {
421 switch a := fd.laddr.(type) {
422 case *TCPAddr:
423 // If a node under test supports both IPv6 capability
424 // and IPv6 IPv4-mapping capability, we can assume
425 // that the node listens on a wildcard address with an
426 // AF_INET6 socket.
427 if supportsIPv4map && fd.laddr.(*TCPAddr).isWildcard() {
428 if fd.family != syscall.AF_INET6 {
429 t.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
431 } else {
432 if fd.family != a.family() {
433 t.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, a.family())
436 case *UDPAddr:
437 // If a node under test supports both IPv6 capability
438 // and IPv6 IPv4-mapping capability, we can assume
439 // that the node listens on a wildcard address with an
440 // AF_INET6 socket.
441 if supportsIPv4map && fd.laddr.(*UDPAddr).isWildcard() {
442 if fd.family != syscall.AF_INET6 {
443 t.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
445 } else {
446 if fd.family != a.family() {
447 t.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, a.family())
450 default:
451 t.Fatalf("Unexpected protocol address type: %T", a)
455 var prohibitionaryDialArgTests = []struct {
456 net string
457 addr string
459 {"tcp6", "127.0.0.1"},
460 {"tcp6", "[::ffff:127.0.0.1]"},
463 func TestProhibitionaryDialArgs(t *testing.T) {
464 switch runtime.GOOS {
465 case "plan9":
466 t.Skipf("skipping test on %q", runtime.GOOS)
468 // This test requires both IPv6 and IPv6 IPv4-mapping functionality.
469 if !supportsIPv4map || testing.Short() || !*testExternal {
470 return
473 l, port := usableListenPort(t, "tcp", "[::]")
474 defer l.Close()
476 for _, tt := range prohibitionaryDialArgTests {
477 c, err := Dial(tt.net, tt.addr+":"+port)
478 if err == nil {
479 c.Close()
480 t.Fatalf("Dial(%q, %q) should fail", tt.net, tt.addr)
485 func TestWildWildcardListener(t *testing.T) {
486 switch runtime.GOOS {
487 case "plan9":
488 t.Skipf("skipping test on %q", runtime.GOOS)
491 if testing.Short() || !*testExternal {
492 t.Skip("skipping test to avoid external network")
495 defer func() {
496 if recover() != nil {
497 t.Fatalf("panicked")
501 if ln, err := Listen("tcp", ""); err == nil {
502 ln.Close()
504 if ln, err := ListenPacket("udp", ""); err == nil {
505 ln.Close()
507 if ln, err := ListenTCP("tcp", nil); err == nil {
508 ln.Close()
510 if ln, err := ListenUDP("udp", nil); err == nil {
511 ln.Close()
513 if ln, err := ListenIP("ip:icmp", nil); err == nil {
514 ln.Close()