1
2
3
4
5 package ipv6_test
6
7 import (
8 "net"
9 "runtime"
10 "testing"
11
12 "golang.org/x/net/ipv6"
13 "golang.org/x/net/nettest"
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},
21 {"ip6", ":ipv6-icmp", "::", &net.IPAddr{IP: net.ParseIP("ff02::115")}, nil},
22
23 {"udp6", "", "[ff30::8000:0]:0", &net.UDPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.UDPAddr{IP: net.IPv6loopback}},
24 {"ip6", ":ipv6-icmp", "::", &net.IPAddr{IP: net.ParseIP("ff30::8000:2")}, &net.IPAddr{IP: net.IPv6loopback}},
25 }
26
27 func TestPacketConnMulticastSocketOptions(t *testing.T) {
28 switch runtime.GOOS {
29 case "fuchsia", "hurd", "js", "nacl", "plan9", "wasip1", "windows":
30 t.Skipf("not supported on %s", runtime.GOOS)
31 }
32 if !nettest.SupportsIPv6() {
33 t.Skip("ipv6 is not supported")
34 }
35 ifi, err := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
36 if err != nil {
37 t.Skipf("not available on %s", runtime.GOOS)
38 }
39
40 ok := nettest.SupportsRawSocket()
41 for _, tt := range packetConnMulticastSocketOptionTests {
42 if tt.net == "ip6" && !ok {
43 t.Logf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
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 t.Helper()
77
78 const hoplim = 255
79 if err := c.SetMulticastHopLimit(hoplim); err != nil {
80 t.Error(err)
81 return
82 }
83 if v, err := c.MulticastHopLimit(); err != nil {
84 t.Error(err)
85 return
86 } else if v != hoplim {
87 t.Errorf("got %v; want %v", v, hoplim)
88 return
89 }
90
91 for _, toggle := range []bool{true, false} {
92 if err := c.SetMulticastLoopback(toggle); err != nil {
93 t.Error(err)
94 return
95 }
96 if v, err := c.MulticastLoopback(); err != nil {
97 t.Error(err)
98 return
99 } else if v != toggle {
100 t.Errorf("got %v; want %v", v, toggle)
101 return
102 }
103 }
104
105 if err := c.JoinGroup(ifi, grp); err != nil {
106 t.Error(err)
107 return
108 }
109 if err := c.LeaveGroup(ifi, grp); err != nil {
110 t.Error(err)
111 return
112 }
113 }
114
115 func testSourceSpecificMulticastSocketOptions(t *testing.T, c testIPv6MulticastConn, ifi *net.Interface, grp, src net.Addr) {
116 t.Helper()
117
118
119 if err := c.JoinGroup(ifi, grp); err != nil {
120 t.Error(err)
121 return
122 }
123 if err := c.ExcludeSourceSpecificGroup(ifi, grp, src); err != nil {
124 switch runtime.GOOS {
125 case "freebsd", "linux":
126 default:
127 t.Logf("not supported on %s", runtime.GOOS)
128 return
129 }
130 t.Error(err)
131 return
132 }
133 if err := c.IncludeSourceSpecificGroup(ifi, grp, src); err != nil {
134 t.Error(err)
135 return
136 }
137 if err := c.LeaveGroup(ifi, grp); err != nil {
138 t.Error(err)
139 return
140 }
141
142
143 if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
144 t.Error(err)
145 return
146 }
147 if err := c.LeaveSourceSpecificGroup(ifi, grp, src); err != nil {
148 t.Error(err)
149 return
150 }
151
152
153 if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
154 t.Error(err)
155 return
156 }
157 if err := c.LeaveGroup(ifi, grp); err != nil {
158 t.Error(err)
159 return
160 }
161 }
162
View as plain text