libgo: Update to weekly.2012-01-15.
[gcc.git] / libgo / go / net / multicast_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 "flag"
9 "os"
10 "runtime"
11 "testing"
12 )
13
14 var multicast = flag.Bool("multicast", false, "enable multicast tests")
15
16 var multicastUDPTests = []struct {
17 net string
18 laddr IP
19 gaddr IP
20 flags Flags
21 ipv6 bool
22 }{
23 // cf. RFC 4727: Experimental Values in IPv4, IPv6, ICMPv4, ICMPv6, UDP, and TCP Headers
24 {"udp", IPv4zero, IPv4(224, 0, 0, 254), (FlagUp | FlagLoopback), false},
25 {"udp4", IPv4zero, IPv4(224, 0, 0, 254), (FlagUp | FlagLoopback), false},
26 {"udp", IPv6unspecified, ParseIP("ff0e::114"), (FlagUp | FlagLoopback), true},
27 {"udp6", IPv6unspecified, ParseIP("ff01::114"), (FlagUp | FlagLoopback), true},
28 {"udp6", IPv6unspecified, ParseIP("ff02::114"), (FlagUp | FlagLoopback), true},
29 {"udp6", IPv6unspecified, ParseIP("ff04::114"), (FlagUp | FlagLoopback), true},
30 {"udp6", IPv6unspecified, ParseIP("ff05::114"), (FlagUp | FlagLoopback), true},
31 {"udp6", IPv6unspecified, ParseIP("ff08::114"), (FlagUp | FlagLoopback), true},
32 {"udp6", IPv6unspecified, ParseIP("ff0e::114"), (FlagUp | FlagLoopback), true},
33 }
34
35 func TestMulticastUDP(t *testing.T) {
36 if runtime.GOOS == "plan9" || runtime.GOOS == "windows" {
37 return
38 }
39 if !*multicast {
40 t.Logf("test disabled; use --multicast to enable")
41 return
42 }
43
44 for _, tt := range multicastUDPTests {
45 var (
46 ifi *Interface
47 found bool
48 )
49 if tt.ipv6 && (!supportsIPv6 || os.Getuid() != 0) {
50 continue
51 }
52 ift, err := Interfaces()
53 if err != nil {
54 t.Fatalf("Interfaces failed: %v", err)
55 }
56 for _, x := range ift {
57 if x.Flags&tt.flags == tt.flags {
58 ifi = &x
59 break
60 }
61 }
62 if ifi == nil {
63 t.Logf("an appropriate multicast interface not found")
64 return
65 }
66 c, err := ListenUDP(tt.net, &UDPAddr{IP: tt.laddr})
67 if err != nil {
68 t.Fatalf("ListenUDP failed: %v", err)
69 }
70 defer c.Close()
71 if err := c.JoinGroup(ifi, tt.gaddr); err != nil {
72 t.Fatalf("JoinGroup failed: %v", err)
73 }
74 if !tt.ipv6 {
75 testIPv4MulticastSocketOptions(t, c.fd, ifi)
76 } else {
77 testIPv6MulticastSocketOptions(t, c.fd, ifi)
78 }
79 ifmat, err := ifi.MulticastAddrs()
80 if err != nil {
81 t.Fatalf("MulticastAddrs failed: %v", err)
82 }
83 for _, ifma := range ifmat {
84 if ifma.(*IPAddr).IP.Equal(tt.gaddr) {
85 found = true
86 break
87 }
88 }
89 if !found {
90 t.Fatalf("%q not found in RIB", tt.gaddr.String())
91 }
92 if err := c.LeaveGroup(ifi, tt.gaddr); err != nil {
93 t.Fatalf("LeaveGroup failed: %v", err)
94 }
95 }
96 }
97
98 func TestSimpleMulticastUDP(t *testing.T) {
99 if runtime.GOOS == "plan9" {
100 return
101 }
102 if !*multicast {
103 t.Logf("test disabled; use --multicast to enable")
104 return
105 }
106
107 for _, tt := range multicastUDPTests {
108 var ifi *Interface
109 if tt.ipv6 {
110 continue
111 }
112 tt.flags = FlagUp | FlagMulticast
113 ift, err := Interfaces()
114 if err != nil {
115 t.Fatalf("Interfaces failed: %v", err)
116 }
117 for _, x := range ift {
118 if x.Flags&tt.flags == tt.flags {
119 ifi = &x
120 break
121 }
122 }
123 if ifi == nil {
124 t.Logf("an appropriate multicast interface not found")
125 return
126 }
127 c, err := ListenUDP(tt.net, &UDPAddr{IP: tt.laddr})
128 if err != nil {
129 t.Fatalf("ListenUDP failed: %v", err)
130 }
131 defer c.Close()
132 if err := c.JoinGroup(ifi, tt.gaddr); err != nil {
133 t.Fatalf("JoinGroup failed: %v", err)
134 }
135 if err := c.LeaveGroup(ifi, tt.gaddr); err != nil {
136 t.Fatalf("LeaveGroup failed: %v", err)
137 }
138 }
139 }
140
141 func testIPv4MulticastSocketOptions(t *testing.T, fd *netFD, ifi *Interface) {
142 ifmc, err := ipv4MulticastInterface(fd)
143 if err != nil {
144 t.Fatalf("ipv4MulticastInterface failed: %v", err)
145 }
146 t.Logf("IPv4 multicast interface: %v", ifmc)
147 err = setIPv4MulticastInterface(fd, ifi)
148 if err != nil {
149 t.Fatalf("setIPv4MulticastInterface failed: %v", err)
150 }
151
152 ttl, err := ipv4MulticastTTL(fd)
153 if err != nil {
154 t.Fatalf("ipv4MulticastTTL failed: %v", err)
155 }
156 t.Logf("IPv4 multicast TTL: %v", ttl)
157 err = setIPv4MulticastTTL(fd, 1)
158 if err != nil {
159 t.Fatalf("setIPv4MulticastTTL failed: %v", err)
160 }
161
162 loop, err := ipv4MulticastLoopback(fd)
163 if err != nil {
164 t.Fatalf("ipv4MulticastLoopback failed: %v", err)
165 }
166 t.Logf("IPv4 multicast loopback: %v", loop)
167 err = setIPv4MulticastLoopback(fd, false)
168 if err != nil {
169 t.Fatalf("setIPv4MulticastLoopback failed: %v", err)
170 }
171 }
172
173 func testIPv6MulticastSocketOptions(t *testing.T, fd *netFD, ifi *Interface) {
174 ifmc, err := ipv6MulticastInterface(fd)
175 if err != nil {
176 t.Fatalf("ipv6MulticastInterface failed: %v", err)
177 }
178 t.Logf("IPv6 multicast interface: %v", ifmc)
179 err = setIPv6MulticastInterface(fd, ifi)
180 if err != nil {
181 t.Fatalf("setIPv6MulticastInterface failed: %v", err)
182 }
183
184 hoplim, err := ipv6MulticastHopLimit(fd)
185 if err != nil {
186 t.Fatalf("ipv6MulticastHopLimit failed: %v", err)
187 }
188 t.Logf("IPv6 multicast hop limit: %v", hoplim)
189 err = setIPv6MulticastHopLimit(fd, 1)
190 if err != nil {
191 t.Fatalf("setIPv6MulticastHopLimit failed: %v", err)
192 }
193
194 loop, err := ipv6MulticastLoopback(fd)
195 if err != nil {
196 t.Fatalf("ipv6MulticastLoopback failed: %v", err)
197 }
198 t.Logf("IPv6 multicast loopback: %v", loop)
199 err = setIPv6MulticastLoopback(fd, false)
200 if err != nil {
201 t.Fatalf("setIPv6MulticastLoopback failed: %v", err)
202 }
203 }