Dmitri Shuralyov | 5d99779 | 2016-11-07 15:05:57 -0800 | [diff] [blame] | 1 | // Copyright 2013 The Go Authors. All rights reserved. |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 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 ( |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 8 | "net" |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 9 | "runtime" |
| 10 | "testing" |
Mikio Hara | 77ebfc5 | 2014-11-09 20:14:20 +0900 | [diff] [blame] | 11 | |
Andrew Gerrand | fbe893d | 2014-11-10 09:04:43 +1100 | [diff] [blame] | 12 | "golang.org/x/net/ipv6" |
Mikio Hara | 63eda1e | 2018-07-11 01:05:18 +0900 | [diff] [blame] | 13 | "golang.org/x/net/nettest" |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 14 | ) |
| 15 | |
| 16 | var packetConnMulticastSocketOptionTests = []struct { |
| 17 | net, proto, addr string |
Mikio Hara | 40ad15c | 2014-11-14 17:45:32 +0900 | [diff] [blame] | 18 | grp, src net.Addr |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 19 | }{ |
Mikio Hara | 40ad15c | 2014-11-14 17:45:32 +0900 | [diff] [blame] | 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 |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 25 | } |
| 26 | |
| 27 | func TestPacketConnMulticastSocketOptions(t *testing.T) { |
| 28 | switch runtime.GOOS { |
Tobias Klauser | 938ff15 | 2023-04-18 13:22:30 +0200 | [diff] [blame] | 29 | case "fuchsia", "hurd", "js", "nacl", "plan9", "wasip1", "windows": |
Mikio Hara | 9dd48c2 | 2015-01-30 09:55:20 +0900 | [diff] [blame] | 30 | t.Skipf("not supported on %s", runtime.GOOS) |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 31 | } |
Mikio Hara | 63eda1e | 2018-07-11 01:05:18 +0900 | [diff] [blame] | 32 | if !nettest.SupportsIPv6() { |
Mikio Hara | a46af89 | 2013-06-06 17:12:18 +0900 | [diff] [blame] | 33 | t.Skip("ipv6 is not supported") |
| 34 | } |
Mikio Hara | 63eda1e | 2018-07-11 01:05:18 +0900 | [diff] [blame] | 35 | ifi, err := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagMulticast|net.FlagLoopback) |
| 36 | if err != nil { |
Mikio Hara | 9dd48c2 | 2015-01-30 09:55:20 +0900 | [diff] [blame] | 37 | t.Skipf("not available on %s", runtime.GOOS) |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 38 | } |
| 39 | |
Mikio Hara | 63eda1e | 2018-07-11 01:05:18 +0900 | [diff] [blame] | 40 | ok := nettest.SupportsRawSocket() |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 41 | for _, tt := range packetConnMulticastSocketOptionTests { |
Mikio Hara | 1439fec | 2015-01-28 12:10:59 +0900 | [diff] [blame] | 42 | if tt.net == "ip6" && !ok { |
Mikio Hara | 63eda1e | 2018-07-11 01:05:18 +0900 | [diff] [blame] | 43 | t.Logf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH) |
Mikio Hara | 40ad15c | 2014-11-14 17:45:32 +0900 | [diff] [blame] | 44 | continue |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 45 | } |
| 46 | c, err := net.ListenPacket(tt.net+tt.proto, tt.addr) |
| 47 | if err != nil { |
Mikio Hara | 40ad15c | 2014-11-14 17:45:32 +0900 | [diff] [blame] | 48 | t.Fatal(err) |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 49 | } |
| 50 | defer c.Close() |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 51 | p := ipv6.NewPacketConn(c) |
Mikio Hara | 40ad15c | 2014-11-14 17:45:32 +0900 | [diff] [blame] | 52 | defer p.Close() |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 53 | |
Mikio Hara | 40ad15c | 2014-11-14 17:45:32 +0900 | [diff] [blame] | 54 | if tt.src == nil { |
| 55 | testMulticastSocketOptions(t, p, ifi, tt.grp) |
| 56 | } else { |
| 57 | testSourceSpecificMulticastSocketOptions(t, p, ifi, tt.grp, tt.src) |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 58 | } |
Mikio Hara | 40ad15c | 2014-11-14 17:45:32 +0900 | [diff] [blame] | 59 | } |
| 60 | } |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 61 | |
Mikio Hara | 40ad15c | 2014-11-14 17:45:32 +0900 | [diff] [blame] | 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 | } |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 74 | |
Mikio Hara | 40ad15c | 2014-11-14 17:45:32 +0900 | [diff] [blame] | 75 | func testMulticastSocketOptions(t *testing.T, c testIPv6MulticastConn, ifi *net.Interface, grp net.Addr) { |
Mikio Hara | 9f648a6 | 2019-03-13 15:50:29 +0900 | [diff] [blame] | 76 | t.Helper() |
| 77 | |
Mikio Hara | 40ad15c | 2014-11-14 17:45:32 +0900 | [diff] [blame] | 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 { |
Mikio Hara | b56b609 | 2014-11-16 11:31:00 +0900 | [diff] [blame] | 87 | t.Errorf("got %v; want %v", v, hoplim) |
Mikio Hara | 40ad15c | 2014-11-14 17:45:32 +0900 | [diff] [blame] | 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 |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 95 | } |
Mikio Hara | 40ad15c | 2014-11-14 17:45:32 +0900 | [diff] [blame] | 96 | if v, err := c.MulticastLoopback(); err != nil { |
| 97 | t.Error(err) |
| 98 | return |
| 99 | } else if v != toggle { |
Mikio Hara | b56b609 | 2014-11-16 11:31:00 +0900 | [diff] [blame] | 100 | t.Errorf("got %v; want %v", v, toggle) |
Mikio Hara | 40ad15c | 2014-11-14 17:45:32 +0900 | [diff] [blame] | 101 | return |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 102 | } |
| 103 | } |
Mikio Hara | 40ad15c | 2014-11-14 17:45:32 +0900 | [diff] [blame] | 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) { |
Mikio Hara | 9f648a6 | 2019-03-13 15:50:29 +0900 | [diff] [blame] | 116 | t.Helper() |
| 117 | |
Mikio Hara | 40ad15c | 2014-11-14 17:45:32 +0900 | [diff] [blame] | 118 | // MCAST_JOIN_GROUP -> MCAST_BLOCK_SOURCE -> MCAST_UNBLOCK_SOURCE -> MCAST_LEAVE_GROUP |
| 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": |
Mikio Hara | b56b609 | 2014-11-16 11:31:00 +0900 | [diff] [blame] | 126 | default: // platforms that don't support MLDv2 fail here |
Mikio Hara | 9dd48c2 | 2015-01-30 09:55:20 +0900 | [diff] [blame] | 127 | t.Logf("not supported on %s", runtime.GOOS) |
Mikio Hara | 40ad15c | 2014-11-14 17:45:32 +0900 | [diff] [blame] | 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 | // MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_SOURCE_GROUP |
| 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 | // MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_GROUP |
| 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 | } |
Mikio Hara | cdfc4ce | 2013-06-04 17:42:58 +0900 | [diff] [blame] | 161 | } |