golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/ipv6/multicastlistener_test.go (about) 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/ipv6" 13 "golang.org/x/net/nettest" 14 ) 15 16 var udpMultipleGroupListenerTests = []net.Addr{ 17 &net.UDPAddr{IP: net.ParseIP("ff02::114")}, // see RFC 4727 18 &net.UDPAddr{IP: net.ParseIP("ff02::1:114")}, 19 &net.UDPAddr{IP: net.ParseIP("ff02::2:114")}, 20 } 21 22 func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) { 23 switch runtime.GOOS { 24 case "fuchsia", "hurd", "js", "nacl", "plan9", "wasip1", "windows": 25 t.Skipf("not supported on %s", runtime.GOOS) 26 } 27 if !nettest.SupportsIPv6() { 28 t.Skip("ipv6 is not supported") 29 } 30 31 for _, gaddr := range udpMultipleGroupListenerTests { 32 c, err := net.ListenPacket("udp6", "[::]:0") // wildcard address with non-reusable port 33 if err != nil { 34 t.Fatal(err) 35 } 36 defer c.Close() 37 38 p := ipv6.NewPacketConn(c) 39 var mift []*net.Interface 40 41 ift, err := net.Interfaces() 42 if err != nil { 43 t.Fatal(err) 44 } 45 for i, ifi := range ift { 46 if _, err := nettest.MulticastSource("ip6", &ifi); err != nil { 47 continue 48 } 49 if err := p.JoinGroup(&ifi, gaddr); err != nil { 50 t.Fatal(err) 51 } 52 mift = append(mift, &ift[i]) 53 } 54 for _, ifi := range mift { 55 if err := p.LeaveGroup(ifi, gaddr); err != nil { 56 t.Fatal(err) 57 } 58 } 59 } 60 } 61 62 func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) { 63 switch runtime.GOOS { 64 case "fuchsia", "hurd", "js", "nacl", "plan9", "wasip1", "windows", "zos": 65 t.Skipf("not supported on %s", runtime.GOOS) 66 } 67 if !nettest.SupportsIPv6() { 68 t.Skip("ipv6 is not supported") 69 } 70 71 for _, gaddr := range udpMultipleGroupListenerTests { 72 c1, err := net.ListenPacket("udp6", "[ff02::]:0") // wildcard address with reusable port 73 if err != nil { 74 t.Fatal(err) 75 } 76 defer c1.Close() 77 _, port, err := net.SplitHostPort(c1.LocalAddr().String()) 78 if err != nil { 79 t.Fatal(err) 80 } 81 c2, err := net.ListenPacket("udp6", net.JoinHostPort("ff02::", port)) // wildcard address with reusable port 82 if err != nil { 83 t.Fatal(err) 84 } 85 defer c2.Close() 86 87 var ps [2]*ipv6.PacketConn 88 ps[0] = ipv6.NewPacketConn(c1) 89 ps[1] = ipv6.NewPacketConn(c2) 90 var mift []*net.Interface 91 92 ift, err := net.Interfaces() 93 if err != nil { 94 t.Fatal(err) 95 } 96 for i, ifi := range ift { 97 if _, err := nettest.MulticastSource("ip6", &ifi); err != nil { 98 continue 99 } 100 for _, p := range ps { 101 if err := p.JoinGroup(&ifi, gaddr); err != nil { 102 t.Fatal(err) 103 } 104 } 105 mift = append(mift, &ift[i]) 106 } 107 for _, ifi := range mift { 108 for _, p := range ps { 109 if err := p.LeaveGroup(ifi, gaddr); err != nil { 110 t.Fatal(err) 111 } 112 } 113 } 114 } 115 } 116 117 func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) { 118 switch runtime.GOOS { 119 case "fuchsia", "hurd", "js", "nacl", "plan9", "wasip1", "windows": 120 t.Skipf("not supported on %s", runtime.GOOS) 121 } 122 if !nettest.SupportsIPv6() { 123 t.Skip("ipv6 is not supported") 124 } 125 126 gaddr := net.IPAddr{IP: net.ParseIP("ff02::114")} // see RFC 4727 127 type ml struct { 128 c *ipv6.PacketConn 129 ifi *net.Interface 130 } 131 var mlt []*ml 132 133 ift, err := net.Interfaces() 134 if err != nil { 135 t.Fatal(err) 136 } 137 port := "0" 138 for i, ifi := range ift { 139 ip, err := nettest.MulticastSource("ip6", &ifi) 140 if err != nil { 141 continue 142 } 143 c, err := net.ListenPacket("udp6", net.JoinHostPort(ip.String()+"%"+ifi.Name, port)) // unicast address with non-reusable port 144 if err != nil { 145 // The listen may fail when the service is 146 // already in use, but it's fine because the 147 // purpose of this is not to test the 148 // bookkeeping of IP control block inside the 149 // kernel. 150 t.Log(err) 151 continue 152 } 153 defer c.Close() 154 if port == "0" { 155 _, port, err = net.SplitHostPort(c.LocalAddr().String()) 156 if err != nil { 157 t.Fatal(err) 158 } 159 } 160 p := ipv6.NewPacketConn(c) 161 if err := p.JoinGroup(&ifi, &gaddr); err != nil { 162 t.Fatal(err) 163 } 164 mlt = append(mlt, &ml{p, &ift[i]}) 165 } 166 for _, m := range mlt { 167 if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil { 168 t.Fatal(err) 169 } 170 } 171 } 172 173 func TestIPSinglePacketConnWithSingleGroupListener(t *testing.T) { 174 if !nettest.SupportsIPv6() { 175 t.Skip("ipv6 is not supported") 176 } 177 if !nettest.SupportsRawSocket() { 178 t.Skipf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH) 179 } 180 181 c, err := net.ListenPacket("ip6:ipv6-icmp", "::") // wildcard address 182 if err != nil { 183 t.Fatal(err) 184 } 185 defer c.Close() 186 187 p := ipv6.NewPacketConn(c) 188 gaddr := net.IPAddr{IP: net.ParseIP("ff02::114")} // see RFC 4727 189 var mift []*net.Interface 190 191 ift, err := net.Interfaces() 192 if err != nil { 193 t.Fatal(err) 194 } 195 for i, ifi := range ift { 196 if _, err := nettest.MulticastSource("ip6", &ifi); err != nil { 197 continue 198 } 199 if err := p.JoinGroup(&ifi, &gaddr); err != nil { 200 t.Fatal(err) 201 } 202 mift = append(mift, &ift[i]) 203 } 204 for _, ifi := range mift { 205 if err := p.LeaveGroup(ifi, &gaddr); err != nil { 206 t.Fatal(err) 207 } 208 } 209 } 210 211 func TestIPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) { 212 switch runtime.GOOS { 213 case "darwin", "ios", "dragonfly", "openbsd": // platforms that return fe80::1%lo0: bind: can't assign requested address 214 t.Skipf("not supported on %s", runtime.GOOS) 215 } 216 if !nettest.SupportsIPv6() { 217 t.Skip("ipv6 is not supported") 218 } 219 if !nettest.SupportsRawSocket() { 220 t.Skipf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH) 221 } 222 223 gaddr := net.IPAddr{IP: net.ParseIP("ff02::114")} // see RFC 4727 224 type ml struct { 225 c *ipv6.PacketConn 226 ifi *net.Interface 227 } 228 var mlt []*ml 229 230 ift, err := net.Interfaces() 231 if err != nil { 232 t.Fatal(err) 233 } 234 for i, ifi := range ift { 235 ip, err := nettest.MulticastSource("ip6", &ifi) 236 if err != nil { 237 continue 238 } 239 c, err := net.ListenPacket("ip6:ipv6-icmp", ip.String()+"%"+ifi.Name) // unicast address 240 if err != nil { 241 t.Fatal(err) 242 } 243 defer c.Close() 244 p := ipv6.NewPacketConn(c) 245 if err := p.JoinGroup(&ifi, &gaddr); err != nil { 246 t.Fatal(err) 247 } 248 mlt = append(mlt, &ml{p, &ift[i]}) 249 } 250 for _, m := range mlt { 251 if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil { 252 t.Fatal(err) 253 } 254 } 255 }