golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/ipv4/multicastlistener_test.go (about) 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/ipv4" 13 "golang.org/x/net/nettest" 14 ) 15 16 var udpMultipleGroupListenerTests = []net.Addr{ 17 &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}, // see RFC 4727 18 &net.UDPAddr{IP: net.IPv4(224, 0, 0, 250)}, 19 &net.UDPAddr{IP: net.IPv4(224, 0, 0, 254)}, 20 } 21 22 func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) { 23 switch runtime.GOOS { 24 case "fuchsia", "hurd", "js", "nacl", "plan9", "wasip1", "windows", "zos": 25 t.Skipf("not supported on %s", runtime.GOOS) 26 } 27 if testing.Short() { 28 t.Skip("to avoid external network") 29 } 30 31 for _, gaddr := range udpMultipleGroupListenerTests { 32 c, err := net.ListenPacket("udp4", "0.0.0.0:0") // wildcard address with no reusable port 33 if err != nil { 34 t.Fatal(err) 35 } 36 defer c.Close() 37 38 p := ipv4.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("ip4", &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 testing.Short() { 68 t.Skip("to avoid external network") 69 } 70 71 for _, gaddr := range udpMultipleGroupListenerTests { 72 c1, err := net.ListenPacket("udp4", "224.0.0.0: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("udp4", net.JoinHostPort("224.0.0.0", port)) // wildcard address with reusable port 82 if err != nil { 83 t.Fatal(err) 84 } 85 defer c2.Close() 86 87 var ps [2]*ipv4.PacketConn 88 ps[0] = ipv4.NewPacketConn(c1) 89 ps[1] = ipv4.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("ip4", &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", "zos": 120 t.Skipf("not supported on %s", runtime.GOOS) 121 } 122 if testing.Short() { 123 t.Skip("to avoid external network") 124 } 125 126 gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727 127 type ml struct { 128 c *ipv4.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("ip4", &ifi) 140 if err != nil { 141 continue 142 } 143 c, err := net.ListenPacket("udp4", net.JoinHostPort(ip.String(), 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 := ipv4.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 TestIPSingleRawConnWithSingleGroupListener(t *testing.T) { 174 if testing.Short() { 175 t.Skip("to avoid external network") 176 } 177 if !nettest.SupportsRawSocket() { 178 t.Skipf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH) 179 } 180 181 c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") // wildcard address 182 if err != nil { 183 t.Fatal(err) 184 } 185 defer c.Close() 186 187 r, err := ipv4.NewRawConn(c) 188 if err != nil { 189 t.Fatal(err) 190 } 191 gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727 192 var mift []*net.Interface 193 194 ift, err := net.Interfaces() 195 if err != nil { 196 t.Fatal(err) 197 } 198 for i, ifi := range ift { 199 if _, err := nettest.MulticastSource("ip4", &ifi); err != nil { 200 continue 201 } 202 if err := r.JoinGroup(&ifi, &gaddr); err != nil { 203 t.Fatal(err) 204 } 205 mift = append(mift, &ift[i]) 206 } 207 for _, ifi := range mift { 208 if err := r.LeaveGroup(ifi, &gaddr); err != nil { 209 t.Fatal(err) 210 } 211 } 212 } 213 214 func TestIPPerInterfaceSingleRawConnWithSingleGroupListener(t *testing.T) { 215 if testing.Short() { 216 t.Skip("to avoid external network") 217 } 218 if !nettest.SupportsRawSocket() { 219 t.Skipf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH) 220 } 221 222 gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727 223 type ml struct { 224 c *ipv4.RawConn 225 ifi *net.Interface 226 } 227 var mlt []*ml 228 229 ift, err := net.Interfaces() 230 if err != nil { 231 t.Fatal(err) 232 } 233 for i, ifi := range ift { 234 ip, err := nettest.MulticastSource("ip4", &ifi) 235 if err != nil { 236 continue 237 } 238 c, err := net.ListenPacket("ip4:253", ip.String()) // unicast address 239 if err != nil { 240 t.Fatal(err) 241 } 242 defer c.Close() 243 r, err := ipv4.NewRawConn(c) 244 if err != nil { 245 t.Fatal(err) 246 } 247 if err := r.JoinGroup(&ifi, &gaddr); err != nil { 248 t.Fatal(err) 249 } 250 mlt = append(mlt, &ml{r, &ift[i]}) 251 } 252 for _, m := range mlt { 253 if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil { 254 t.Fatal(err) 255 } 256 } 257 }