OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / ipv6 / multicastsockopt_test.go
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         "net"
9         "runtime"
10         "testing"
11
12         "golang.org/x/net/internal/nettest"
13         "golang.org/x/net/ipv6"
14 )
15
16 var packetConnMulticastSocketOptionTests = []struct {
17         net, proto, addr string
18         grp, src         net.Addr
19 }{
20         {"udp6", "", "[ff02::]:0", &net.UDPAddr{IP: net.ParseIP("ff02::114")}, nil}, // see RFC 4727
21         {"ip6", ":ipv6-icmp", "::", &net.IPAddr{IP: net.ParseIP("ff02::115")}, nil}, // see RFC 4727
22
23         {"udp6", "", "[ff30::8000:0]:0", &net.UDPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.UDPAddr{IP: net.IPv6loopback}}, // see RFC 5771
24         {"ip6", ":ipv6-icmp", "::", &net.IPAddr{IP: net.ParseIP("ff30::8000:2")}, &net.IPAddr{IP: net.IPv6loopback}},        // see RFC 5771
25 }
26
27 func TestPacketConnMulticastSocketOptions(t *testing.T) {
28         switch runtime.GOOS {
29         case "nacl", "plan9", "windows":
30                 t.Skipf("not supported on %s", runtime.GOOS)
31         }
32         if !supportsIPv6 {
33                 t.Skip("ipv6 is not supported")
34         }
35         ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
36         if ifi == nil {
37                 t.Skipf("not available on %s", runtime.GOOS)
38         }
39
40         m, ok := nettest.SupportsRawIPSocket()
41         for _, tt := range packetConnMulticastSocketOptionTests {
42                 if tt.net == "ip6" && !ok {
43                         t.Log(m)
44                         continue
45                 }
46                 c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
47                 if err != nil {
48                         t.Fatal(err)
49                 }
50                 defer c.Close()
51                 p := ipv6.NewPacketConn(c)
52                 defer p.Close()
53
54                 if tt.src == nil {
55                         testMulticastSocketOptions(t, p, ifi, tt.grp)
56                 } else {
57                         testSourceSpecificMulticastSocketOptions(t, p, ifi, tt.grp, tt.src)
58                 }
59         }
60 }
61
62 type testIPv6MulticastConn interface {
63         MulticastHopLimit() (int, error)
64         SetMulticastHopLimit(ttl int) error
65         MulticastLoopback() (bool, error)
66         SetMulticastLoopback(bool) error
67         JoinGroup(*net.Interface, net.Addr) error
68         LeaveGroup(*net.Interface, net.Addr) error
69         JoinSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
70         LeaveSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
71         ExcludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
72         IncludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
73 }
74
75 func testMulticastSocketOptions(t *testing.T, c testIPv6MulticastConn, ifi *net.Interface, grp net.Addr) {
76         const hoplim = 255
77         if err := c.SetMulticastHopLimit(hoplim); err != nil {
78                 t.Error(err)
79                 return
80         }
81         if v, err := c.MulticastHopLimit(); err != nil {
82                 t.Error(err)
83                 return
84         } else if v != hoplim {
85                 t.Errorf("got %v; want %v", v, hoplim)
86                 return
87         }
88
89         for _, toggle := range []bool{true, false} {
90                 if err := c.SetMulticastLoopback(toggle); err != nil {
91                         t.Error(err)
92                         return
93                 }
94                 if v, err := c.MulticastLoopback(); err != nil {
95                         t.Error(err)
96                         return
97                 } else if v != toggle {
98                         t.Errorf("got %v; want %v", v, toggle)
99                         return
100                 }
101         }
102
103         if err := c.JoinGroup(ifi, grp); err != nil {
104                 t.Error(err)
105                 return
106         }
107         if err := c.LeaveGroup(ifi, grp); err != nil {
108                 t.Error(err)
109                 return
110         }
111 }
112
113 func testSourceSpecificMulticastSocketOptions(t *testing.T, c testIPv6MulticastConn, ifi *net.Interface, grp, src net.Addr) {
114         // MCAST_JOIN_GROUP -> MCAST_BLOCK_SOURCE -> MCAST_UNBLOCK_SOURCE -> MCAST_LEAVE_GROUP
115         if err := c.JoinGroup(ifi, grp); err != nil {
116                 t.Error(err)
117                 return
118         }
119         if err := c.ExcludeSourceSpecificGroup(ifi, grp, src); err != nil {
120                 switch runtime.GOOS {
121                 case "freebsd", "linux":
122                 default: // platforms that don't support MLDv2 fail here
123                         t.Logf("not supported on %s", runtime.GOOS)
124                         return
125                 }
126                 t.Error(err)
127                 return
128         }
129         if err := c.IncludeSourceSpecificGroup(ifi, grp, src); err != nil {
130                 t.Error(err)
131                 return
132         }
133         if err := c.LeaveGroup(ifi, grp); err != nil {
134                 t.Error(err)
135                 return
136         }
137
138         // MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_SOURCE_GROUP
139         if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
140                 t.Error(err)
141                 return
142         }
143         if err := c.LeaveSourceSpecificGroup(ifi, grp, src); err != nil {
144                 t.Error(err)
145                 return
146         }
147
148         // MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_GROUP
149         if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
150                 t.Error(err)
151                 return
152         }
153         if err := c.LeaveGroup(ifi, grp); err != nil {
154                 t.Error(err)
155                 return
156         }
157 }