blob: 2ece9a7fb03d824e89c2b1226a3dffbe0e3c39bb [file] [log] [blame]
Mikio Harad2e5a122012-09-26 21:03:09 +09001// Copyright 2012 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 darwin freebsd linux netbsd openbsd
6
7package ipv4_test
8
9import (
10 "code.google.com/p/go.net/ipv4"
11 "net"
12 "os"
13 "testing"
14)
15
16var udpMultipleGroupListenerTests = []struct {
17 gaddr *net.UDPAddr
18}{
19 {&net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}}, // see RFC 4727
20 {&net.UDPAddr{IP: net.IPv4(224, 0, 0, 250)}}, // see RFC 4727
21 {&net.UDPAddr{IP: net.IPv4(224, 0, 0, 254)}}, // see RFC 4727
22}
23
24func TestUDPSingleConnWithMultipleGroupListeners(t *testing.T) {
25 if testing.Short() || !*testExternal {
26 t.Logf("skipping test to avoid external network")
27 return
28 }
29
30 for _, tt := range udpMultipleGroupListenerTests {
31 // listen to a wildcard address with no reusable port
32 c, err := net.ListenPacket("udp4", "0.0.0.0:0")
33 if err != nil {
34 t.Fatalf("net.ListenPacket failed: %v", err)
35 }
36 defer c.Close()
37
38 p := ipv4.NewPacketConn(c)
39
40 var mift []*net.Interface
41 ift, err := net.Interfaces()
42 if err != nil {
43 t.Fatalf("net.Interfaces failed: %v", err)
44 }
45 for i, ifi := range ift {
Mikio Hara6b91bf22013-02-16 13:02:07 +090046 if _, ok := isMulticastAvailable(&ifi); !ok {
Mikio Harad2e5a122012-09-26 21:03:09 +090047 continue
48 }
49 if err := p.JoinGroup(&ifi, tt.gaddr); err != nil {
50 t.Fatalf("ipv4.PacketConn.JoinGroup %v on %v failed: %v", tt.gaddr, ifi, err)
51 }
52 mift = append(mift, &ift[i])
53 }
54 for _, ifi := range mift {
55 if err := p.LeaveGroup(ifi, tt.gaddr); err != nil {
56 t.Fatalf("ipv4.PacketConn.LeaveGroup %v on %v failed: %v", tt.gaddr, ifi, err)
57 }
58 }
59 }
60}
61
62func TestUDPMultipleConnWithMultipleGroupListeners(t *testing.T) {
63 if testing.Short() || !*testExternal {
64 t.Logf("skipping test to avoid external network")
65 return
66 }
67
68 for _, tt := range udpMultipleGroupListenerTests {
69 // listen to a group address, actually a wildcard address
70 // with reusable port
71 c1, err := net.ListenPacket("udp4", "224.0.0.0:1024") // see RFC 4727
72 if err != nil {
73 t.Fatalf("net.ListenPacket failed: %v", err)
74 }
75 defer c1.Close()
76
77 c2, err := net.ListenPacket("udp4", "224.0.0.0:1024") // see RFC 4727
78 if err != nil {
79 t.Fatalf("net.ListenPacket failed: %v", err)
80 }
81 defer c2.Close()
82
83 var ps [2]*ipv4.PacketConn
84 ps[0] = ipv4.NewPacketConn(c1)
85 ps[1] = ipv4.NewPacketConn(c2)
86
87 var mift []*net.Interface
88 ift, err := net.Interfaces()
89 if err != nil {
90 t.Fatalf("net.Interfaces failed: %v", err)
91 }
92 for i, ifi := range ift {
Mikio Hara6b91bf22013-02-16 13:02:07 +090093 if _, ok := isMulticastAvailable(&ifi); !ok {
Mikio Harad2e5a122012-09-26 21:03:09 +090094 continue
95 }
96 for _, p := range ps {
97 if err := p.JoinGroup(&ifi, tt.gaddr); err != nil {
98 t.Fatalf("ipv4.PacketConn.JoinGroup %v on %v failed: %v", tt.gaddr, ifi, err)
99 }
100 }
101 mift = append(mift, &ift[i])
102 }
103 for _, ifi := range mift {
104 for _, p := range ps {
105 if err := p.LeaveGroup(ifi, tt.gaddr); err != nil {
106 t.Fatalf("ipv4.PacketConn.LeaveGroup %v on %v failed: %v", tt.gaddr, ifi, err)
107 }
108 }
109 }
110 }
111}
112
113func TestIPSingleConnWithSingleGroupListener(t *testing.T) {
114 if testing.Short() || !*testExternal {
115 t.Logf("skipping test to avoid external network")
116 return
117 }
118 if os.Getuid() != 0 {
119 t.Logf("skipping test; must be root")
120 return
121 }
122
123 // listen to a wildcard address
124 c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
125 if err != nil {
126 t.Fatalf("net.ListenPacket failed: %v", err)
127 }
128 defer c.Close()
129
130 r, err := ipv4.NewRawConn(c)
131 if err != nil {
132 t.Fatalf("ipv4.RawConn failed: %v", err)
133 }
134
135 gaddr := &net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727
136 var mift []*net.Interface
137 ift, err := net.Interfaces()
138 if err != nil {
139 t.Fatalf("net.Interfaces failed: %v", err)
140 }
141 for i, ifi := range ift {
Mikio Hara6b91bf22013-02-16 13:02:07 +0900142 if _, ok := isMulticastAvailable(&ifi); !ok {
Mikio Harad2e5a122012-09-26 21:03:09 +0900143 continue
144 }
145 if err := r.JoinGroup(&ifi, gaddr); err != nil {
146 t.Fatalf("ipv4.RawConn.JoinGroup on %v failed: %v", ifi, err)
147 }
148 mift = append(mift, &ift[i])
149 }
150 for _, ifi := range mift {
151 if err := r.LeaveGroup(ifi, gaddr); err != nil {
152 t.Fatalf("ipv4.RawConn.LeaveGroup on %v failed: %v", ifi, err)
153 }
154 }
155}
156
157func TestUDPPerInterfaceSingleConnWithSingleGroupListener(t *testing.T) {
158 if testing.Short() || !*testExternal {
159 t.Logf("skipping test to avoid external network")
160 return
161 }
162
163 gaddr := &net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727
164 type ml struct {
165 c *ipv4.PacketConn
166 ifi *net.Interface
167 }
168 var mlt []*ml
169
170 ift, err := net.Interfaces()
171 if err != nil {
172 t.Fatalf("net.Interfaces failed: %v", err)
173 }
174 for i, ifi := range ift {
Mikio Hara6b91bf22013-02-16 13:02:07 +0900175 ip, ok := isMulticastAvailable(&ifi)
Mikio Harad2e5a122012-09-26 21:03:09 +0900176 if !ok {
177 continue
178 }
179 // listen to a unicast interface address
180 c, err := net.ListenPacket("udp4", ip.String()+":"+"1024") // see RFC 4727
181 if err != nil {
182 t.Fatalf("net.ListenPacket with %v failed: %v", ip, err)
183 }
184 defer c.Close()
185 p := ipv4.NewPacketConn(c)
186 if err := p.JoinGroup(&ifi, gaddr); err != nil {
187 t.Fatalf("ipv4.PacketConn.JoinGroup on %v failed: %v", ifi, err)
188 }
189 mlt = append(mlt, &ml{p, &ift[i]})
190 }
191 for _, m := range mlt {
192 if err := m.c.LeaveGroup(m.ifi, gaddr); err != nil {
193 t.Fatalf("ipv4.PacketConn.LeaveGroup on %v failed: %v", m.ifi, err)
194 }
195 }
196}
197
198func TestIPPerInterfaceSingleConnWithSingleGroupListener(t *testing.T) {
199 if testing.Short() || !*testExternal {
200 t.Logf("skipping test to avoid external network")
201 return
202 }
203 if os.Getuid() != 0 {
204 t.Logf("skipping test; must be root")
205 return
206 }
207
208 gaddr := &net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727
209 type ml struct {
210 c *ipv4.RawConn
211 ifi *net.Interface
212 }
213 var mlt []*ml
214
215 ift, err := net.Interfaces()
216 if err != nil {
217 t.Fatalf("net.Interfaces failed: %v", err)
218 }
219 for i, ifi := range ift {
Mikio Hara6b91bf22013-02-16 13:02:07 +0900220 ip, ok := isMulticastAvailable(&ifi)
Mikio Harad2e5a122012-09-26 21:03:09 +0900221 if !ok {
222 continue
223 }
224 // listen to a unicast interface address
225 c, err := net.ListenPacket("ip4:253", ip.String()) // see RFC 4727
226 if err != nil {
227 t.Fatalf("net.ListenPacket with %v failed: %v", ip, err)
228 }
229 defer c.Close()
230 r, err := ipv4.NewRawConn(c)
231 if err != nil {
232 t.Fatalf("ipv4.NewRawConn failed: %v", err)
233 }
234 if err := r.JoinGroup(&ifi, gaddr); err != nil {
235 t.Fatalf("ipv4.RawConn.JoinGroup on %v failed: %v", ifi, err)
236 }
237 mlt = append(mlt, &ml{r, &ift[i]})
238 }
239 for _, m := range mlt {
240 if err := m.c.LeaveGroup(m.ifi, gaddr); err != nil {
241 t.Fatalf("ipv4.RawConn.LeaveGroup on %v failed: %v", m.ifi, err)
242 }
243 }
244}