OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / ipv4 / multicastsockopt_test.go
1 // 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 package ipv4_test
6
7 import (
8         "net"
9         "runtime"
10         "testing"
11
12         "golang.org/x/net/internal/nettest"
13         "golang.org/x/net/ipv4"
14 )
15
16 var packetConnMulticastSocketOptionTests = []struct {
17         net, proto, addr string
18         grp, src         net.Addr
19 }{
20         {"udp4", "", "224.0.0.0:0", &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}, nil}, // see RFC 4727
21         {"ip4", ":icmp", "0.0.0.0", &net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}, nil},  // see RFC 4727
22
23         {"udp4", "", "232.0.0.0:0", &net.UDPAddr{IP: net.IPv4(232, 0, 1, 249)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
24         {"ip4", ":icmp", "0.0.0.0", &net.IPAddr{IP: net.IPv4(232, 0, 1, 250)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}},  // see RFC 5771
25 }
26
27 func TestPacketConnMulticastSocketOptions(t *testing.T) {
28         switch runtime.GOOS {
29         case "nacl", "plan9":
30                 t.Skipf("not supported on %s", runtime.GOOS)
31         }
32         ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
33         if ifi == nil {
34                 t.Skipf("not available on %s", runtime.GOOS)
35         }
36
37         m, ok := nettest.SupportsRawIPSocket()
38         for _, tt := range packetConnMulticastSocketOptionTests {
39                 if tt.net == "ip4" && !ok {
40                         t.Log(m)
41                         continue
42                 }
43                 c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
44                 if err != nil {
45                         t.Fatal(err)
46                 }
47                 defer c.Close()
48                 p := ipv4.NewPacketConn(c)
49                 defer p.Close()
50
51                 if tt.src == nil {
52                         testMulticastSocketOptions(t, p, ifi, tt.grp)
53                 } else {
54                         testSourceSpecificMulticastSocketOptions(t, p, ifi, tt.grp, tt.src)
55                 }
56         }
57 }
58
59 var rawConnMulticastSocketOptionTests = []struct {
60         grp, src net.Addr
61 }{
62         {&net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}, nil}, // see RFC 4727
63
64         {&net.IPAddr{IP: net.IPv4(232, 0, 1, 250)}, &net.IPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
65 }
66
67 func TestRawConnMulticastSocketOptions(t *testing.T) {
68         switch runtime.GOOS {
69         case "nacl", "plan9":
70                 t.Skipf("not supported on %s", runtime.GOOS)
71         }
72         if m, ok := nettest.SupportsRawIPSocket(); !ok {
73                 t.Skip(m)
74         }
75         ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
76         if ifi == nil {
77                 t.Skipf("not available on %s", runtime.GOOS)
78         }
79
80         for _, tt := range rawConnMulticastSocketOptionTests {
81                 c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
82                 if err != nil {
83                         t.Fatal(err)
84                 }
85                 defer c.Close()
86                 r, err := ipv4.NewRawConn(c)
87                 if err != nil {
88                         t.Fatal(err)
89                 }
90                 defer r.Close()
91
92                 if tt.src == nil {
93                         testMulticastSocketOptions(t, r, ifi, tt.grp)
94                 } else {
95                         testSourceSpecificMulticastSocketOptions(t, r, ifi, tt.grp, tt.src)
96                 }
97         }
98 }
99
100 type testIPv4MulticastConn interface {
101         MulticastTTL() (int, error)
102         SetMulticastTTL(ttl int) error
103         MulticastLoopback() (bool, error)
104         SetMulticastLoopback(bool) error
105         JoinGroup(*net.Interface, net.Addr) error
106         LeaveGroup(*net.Interface, net.Addr) error
107         JoinSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
108         LeaveSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
109         ExcludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
110         IncludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
111 }
112
113 func testMulticastSocketOptions(t *testing.T, c testIPv4MulticastConn, ifi *net.Interface, grp net.Addr) {
114         const ttl = 255
115         if err := c.SetMulticastTTL(ttl); err != nil {
116                 t.Error(err)
117                 return
118         }
119         if v, err := c.MulticastTTL(); err != nil {
120                 t.Error(err)
121                 return
122         } else if v != ttl {
123                 t.Errorf("got %v; want %v", v, ttl)
124                 return
125         }
126
127         for _, toggle := range []bool{true, false} {
128                 if err := c.SetMulticastLoopback(toggle); err != nil {
129                         t.Error(err)
130                         return
131                 }
132                 if v, err := c.MulticastLoopback(); err != nil {
133                         t.Error(err)
134                         return
135                 } else if v != toggle {
136                         t.Errorf("got %v; want %v", v, toggle)
137                         return
138                 }
139         }
140
141         if err := c.JoinGroup(ifi, grp); err != nil {
142                 t.Error(err)
143                 return
144         }
145         if err := c.LeaveGroup(ifi, grp); err != nil {
146                 t.Error(err)
147                 return
148         }
149 }
150
151 func testSourceSpecificMulticastSocketOptions(t *testing.T, c testIPv4MulticastConn, ifi *net.Interface, grp, src net.Addr) {
152         // MCAST_JOIN_GROUP -> MCAST_BLOCK_SOURCE -> MCAST_UNBLOCK_SOURCE -> MCAST_LEAVE_GROUP
153         if err := c.JoinGroup(ifi, grp); err != nil {
154                 t.Error(err)
155                 return
156         }
157         if err := c.ExcludeSourceSpecificGroup(ifi, grp, src); err != nil {
158                 switch runtime.GOOS {
159                 case "freebsd", "linux":
160                 default: // platforms that don't support IGMPv2/3 fail here
161                         t.Logf("not supported on %s", runtime.GOOS)
162                         return
163                 }
164                 t.Error(err)
165                 return
166         }
167         if err := c.IncludeSourceSpecificGroup(ifi, grp, src); err != nil {
168                 t.Error(err)
169                 return
170         }
171         if err := c.LeaveGroup(ifi, grp); err != nil {
172                 t.Error(err)
173                 return
174         }
175
176         // MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_SOURCE_GROUP
177         if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
178                 t.Error(err)
179                 return
180         }
181         if err := c.LeaveSourceSpecificGroup(ifi, grp, src); err != nil {
182                 t.Error(err)
183                 return
184         }
185
186         // MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_GROUP
187         if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
188                 t.Error(err)
189                 return
190         }
191         if err := c.LeaveGroup(ifi, grp); err != nil {
192                 t.Error(err)
193                 return
194         }
195 }