OSDN Git Service

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