~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/golang.org/x/net/ipv6/multicast_test.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2013 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 ipv6_test
 
6
 
 
7
import (
 
8
        "bytes"
 
9
        "net"
 
10
        "os"
 
11
        "runtime"
 
12
        "testing"
 
13
        "time"
 
14
 
 
15
        "golang.org/x/net/icmp"
 
16
        "golang.org/x/net/internal/iana"
 
17
        "golang.org/x/net/internal/nettest"
 
18
        "golang.org/x/net/ipv6"
 
19
)
 
20
 
 
21
var packetConnReadWriteMulticastUDPTests = []struct {
 
22
        addr     string
 
23
        grp, src *net.UDPAddr
 
24
}{
 
25
        {"[ff02::]:0", &net.UDPAddr{IP: net.ParseIP("ff02::114")}, nil}, // see RFC 4727
 
26
 
 
27
        {"[ff30::8000:0]:0", &net.UDPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.UDPAddr{IP: net.IPv6loopback}}, // see RFC 5771
 
28
}
 
29
 
 
30
func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
 
31
        switch runtime.GOOS {
 
32
        case "freebsd": // due to a bug on loopback marking
 
33
                // See http://www.freebsd.org/cgi/query-pr.cgi?pr=180065.
 
34
                t.Skipf("not supported on %s", runtime.GOOS)
 
35
        case "nacl", "plan9", "solaris", "windows":
 
36
                t.Skipf("not supported on %s", runtime.GOOS)
 
37
        }
 
38
        if !supportsIPv6 {
 
39
                t.Skip("ipv6 is not supported")
 
40
        }
 
41
        ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
 
42
        if ifi == nil {
 
43
                t.Skipf("not available on %s", runtime.GOOS)
 
44
        }
 
45
 
 
46
        for _, tt := range packetConnReadWriteMulticastUDPTests {
 
47
                c, err := net.ListenPacket("udp6", tt.addr)
 
48
                if err != nil {
 
49
                        t.Fatal(err)
 
50
                }
 
51
                defer c.Close()
 
52
 
 
53
                grp := *tt.grp
 
54
                grp.Port = c.LocalAddr().(*net.UDPAddr).Port
 
55
                p := ipv6.NewPacketConn(c)
 
56
                defer p.Close()
 
57
                if tt.src == nil {
 
58
                        if err := p.JoinGroup(ifi, &grp); err != nil {
 
59
                                t.Fatal(err)
 
60
                        }
 
61
                        defer p.LeaveGroup(ifi, &grp)
 
62
                } else {
 
63
                        if err := p.JoinSourceSpecificGroup(ifi, &grp, tt.src); err != nil {
 
64
                                switch runtime.GOOS {
 
65
                                case "freebsd", "linux":
 
66
                                default: // platforms that don't support MLDv2 fail here
 
67
                                        t.Logf("not supported on %s", runtime.GOOS)
 
68
                                        continue
 
69
                                }
 
70
                                t.Fatal(err)
 
71
                        }
 
72
                        defer p.LeaveSourceSpecificGroup(ifi, &grp, tt.src)
 
73
                }
 
74
                if err := p.SetMulticastInterface(ifi); err != nil {
 
75
                        t.Fatal(err)
 
76
                }
 
77
                if _, err := p.MulticastInterface(); err != nil {
 
78
                        t.Fatal(err)
 
79
                }
 
80
                if err := p.SetMulticastLoopback(true); err != nil {
 
81
                        t.Fatal(err)
 
82
                }
 
83
                if _, err := p.MulticastLoopback(); err != nil {
 
84
                        t.Fatal(err)
 
85
                }
 
86
 
 
87
                cm := ipv6.ControlMessage{
 
88
                        TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
 
89
                        Src:          net.IPv6loopback,
 
90
                        IfIndex:      ifi.Index,
 
91
                }
 
92
                cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
 
93
                wb := []byte("HELLO-R-U-THERE")
 
94
 
 
95
                for i, toggle := range []bool{true, false, true} {
 
96
                        if err := p.SetControlMessage(cf, toggle); err != nil {
 
97
                                if nettest.ProtocolNotSupported(err) {
 
98
                                        t.Logf("not supported on %s", runtime.GOOS)
 
99
                                        continue
 
100
                                }
 
101
                                t.Fatal(err)
 
102
                        }
 
103
                        if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
 
104
                                t.Fatal(err)
 
105
                        }
 
106
                        cm.HopLimit = i + 1
 
107
                        if n, err := p.WriteTo(wb, &cm, &grp); err != nil {
 
108
                                t.Fatal(err)
 
109
                        } else if n != len(wb) {
 
110
                                t.Fatal(err)
 
111
                        }
 
112
                        rb := make([]byte, 128)
 
113
                        if n, cm, _, err := p.ReadFrom(rb); err != nil {
 
114
                                t.Fatal(err)
 
115
                        } else if !bytes.Equal(rb[:n], wb) {
 
116
                                t.Fatalf("got %v; want %v", rb[:n], wb)
 
117
                        } else {
 
118
                                t.Logf("rcvd cmsg: %v", cm)
 
119
                        }
 
120
                }
 
121
        }
 
122
}
 
123
 
 
124
var packetConnReadWriteMulticastICMPTests = []struct {
 
125
        grp, src *net.IPAddr
 
126
}{
 
127
        {&net.IPAddr{IP: net.ParseIP("ff02::114")}, nil}, // see RFC 4727
 
128
 
 
129
        {&net.IPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.IPAddr{IP: net.IPv6loopback}}, // see RFC 5771
 
130
}
 
131
 
 
132
func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
 
133
        switch runtime.GOOS {
 
134
        case "freebsd": // due to a bug on loopback marking
 
135
                // See http://www.freebsd.org/cgi/query-pr.cgi?pr=180065.
 
136
                t.Skipf("not supported on %s", runtime.GOOS)
 
137
        case "nacl", "plan9", "solaris", "windows":
 
138
                t.Skipf("not supported on %s", runtime.GOOS)
 
139
        }
 
140
        if !supportsIPv6 {
 
141
                t.Skip("ipv6 is not supported")
 
142
        }
 
143
        if m, ok := nettest.SupportsRawIPSocket(); !ok {
 
144
                t.Skip(m)
 
145
        }
 
146
        ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
 
147
        if ifi == nil {
 
148
                t.Skipf("not available on %s", runtime.GOOS)
 
149
        }
 
150
 
 
151
        for _, tt := range packetConnReadWriteMulticastICMPTests {
 
152
                c, err := net.ListenPacket("ip6:ipv6-icmp", "::")
 
153
                if err != nil {
 
154
                        t.Fatal(err)
 
155
                }
 
156
                defer c.Close()
 
157
 
 
158
                pshicmp := icmp.IPv6PseudoHeader(c.LocalAddr().(*net.IPAddr).IP, tt.grp.IP)
 
159
                p := ipv6.NewPacketConn(c)
 
160
                defer p.Close()
 
161
                if tt.src == nil {
 
162
                        if err := p.JoinGroup(ifi, tt.grp); err != nil {
 
163
                                t.Fatal(err)
 
164
                        }
 
165
                        defer p.LeaveGroup(ifi, tt.grp)
 
166
                } else {
 
167
                        if err := p.JoinSourceSpecificGroup(ifi, tt.grp, tt.src); err != nil {
 
168
                                switch runtime.GOOS {
 
169
                                case "freebsd", "linux":
 
170
                                default: // platforms that don't support MLDv2 fail here
 
171
                                        t.Logf("not supported on %s", runtime.GOOS)
 
172
                                        continue
 
173
                                }
 
174
                                t.Fatal(err)
 
175
                        }
 
176
                        defer p.LeaveSourceSpecificGroup(ifi, tt.grp, tt.src)
 
177
                }
 
178
                if err := p.SetMulticastInterface(ifi); err != nil {
 
179
                        t.Fatal(err)
 
180
                }
 
181
                if _, err := p.MulticastInterface(); err != nil {
 
182
                        t.Fatal(err)
 
183
                }
 
184
                if err := p.SetMulticastLoopback(true); err != nil {
 
185
                        t.Fatal(err)
 
186
                }
 
187
                if _, err := p.MulticastLoopback(); err != nil {
 
188
                        t.Fatal(err)
 
189
                }
 
190
 
 
191
                cm := ipv6.ControlMessage{
 
192
                        TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
 
193
                        Src:          net.IPv6loopback,
 
194
                        IfIndex:      ifi.Index,
 
195
                }
 
196
                cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
 
197
 
 
198
                var f ipv6.ICMPFilter
 
199
                f.SetAll(true)
 
200
                f.Accept(ipv6.ICMPTypeEchoReply)
 
201
                if err := p.SetICMPFilter(&f); err != nil {
 
202
                        t.Fatal(err)
 
203
                }
 
204
 
 
205
                var psh []byte
 
206
                for i, toggle := range []bool{true, false, true} {
 
207
                        if toggle {
 
208
                                psh = nil
 
209
                                if err := p.SetChecksum(true, 2); err != nil {
 
210
                                        t.Fatal(err)
 
211
                                }
 
212
                        } else {
 
213
                                psh = pshicmp
 
214
                                // Some platforms never allow to
 
215
                                // disable the kernel checksum
 
216
                                // processing.
 
217
                                p.SetChecksum(false, -1)
 
218
                        }
 
219
                        wb, err := (&icmp.Message{
 
220
                                Type: ipv6.ICMPTypeEchoRequest, Code: 0,
 
221
                                Body: &icmp.Echo{
 
222
                                        ID: os.Getpid() & 0xffff, Seq: i + 1,
 
223
                                        Data: []byte("HELLO-R-U-THERE"),
 
224
                                },
 
225
                        }).Marshal(psh)
 
226
                        if err != nil {
 
227
                                t.Fatal(err)
 
228
                        }
 
229
                        if err := p.SetControlMessage(cf, toggle); err != nil {
 
230
                                if nettest.ProtocolNotSupported(err) {
 
231
                                        t.Logf("not supported on %s", runtime.GOOS)
 
232
                                        continue
 
233
                                }
 
234
                                t.Fatal(err)
 
235
                        }
 
236
                        if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
 
237
                                t.Fatal(err)
 
238
                        }
 
239
                        cm.HopLimit = i + 1
 
240
                        if n, err := p.WriteTo(wb, &cm, tt.grp); err != nil {
 
241
                                t.Fatal(err)
 
242
                        } else if n != len(wb) {
 
243
                                t.Fatalf("got %v; want %v", n, len(wb))
 
244
                        }
 
245
                        rb := make([]byte, 128)
 
246
                        if n, cm, _, err := p.ReadFrom(rb); err != nil {
 
247
                                switch runtime.GOOS {
 
248
                                case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket
 
249
                                        t.Logf("not supported on %s", runtime.GOOS)
 
250
                                        continue
 
251
                                }
 
252
                                t.Fatal(err)
 
253
                        } else {
 
254
                                t.Logf("rcvd cmsg: %v", cm)
 
255
                                if m, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, rb[:n]); err != nil {
 
256
                                        t.Fatal(err)
 
257
                                } else if m.Type != ipv6.ICMPTypeEchoReply || m.Code != 0 {
 
258
                                        t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv6.ICMPTypeEchoReply, 0)
 
259
                                }
 
260
                        }
 
261
                }
 
262
        }
 
263
}