github.com/Andyfoo/golang/x/net@v0.0.0-20190901054642-57c1bf301704/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 "github.com/Andyfoo/golang/x/net/ipv4" 13 "github.com/Andyfoo/golang/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", "windows": 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", "windows": 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", "windows": 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 serivce 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 switch runtime.GOOS { 175 case "fuchsia", "hurd", "js", "nacl", "plan9", "windows": 176 t.Skipf("not supported on %s", runtime.GOOS) 177 } 178 if testing.Short() { 179 t.Skip("to avoid external network") 180 } 181 if !nettest.SupportsRawSocket() { 182 t.Skipf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH) 183 } 184 185 c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") // wildcard address 186 if err != nil { 187 t.Fatal(err) 188 } 189 defer c.Close() 190 191 r, err := ipv4.NewRawConn(c) 192 if err != nil { 193 t.Fatal(err) 194 } 195 gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727 196 var mift []*net.Interface 197 198 ift, err := net.Interfaces() 199 if err != nil { 200 t.Fatal(err) 201 } 202 for i, ifi := range ift { 203 if _, err := nettest.MulticastSource("ip4", &ifi); err != nil { 204 continue 205 } 206 if err := r.JoinGroup(&ifi, &gaddr); err != nil { 207 t.Fatal(err) 208 } 209 mift = append(mift, &ift[i]) 210 } 211 for _, ifi := range mift { 212 if err := r.LeaveGroup(ifi, &gaddr); err != nil { 213 t.Fatal(err) 214 } 215 } 216 } 217 218 func TestIPPerInterfaceSingleRawConnWithSingleGroupListener(t *testing.T) { 219 switch runtime.GOOS { 220 case "fuchsia", "hurd", "js", "nacl", "plan9", "windows": 221 t.Skipf("not supported on %s", runtime.GOOS) 222 } 223 if testing.Short() { 224 t.Skip("to avoid external network") 225 } 226 if !nettest.SupportsRawSocket() { 227 t.Skipf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH) 228 } 229 230 gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727 231 type ml struct { 232 c *ipv4.RawConn 233 ifi *net.Interface 234 } 235 var mlt []*ml 236 237 ift, err := net.Interfaces() 238 if err != nil { 239 t.Fatal(err) 240 } 241 for i, ifi := range ift { 242 ip, err := nettest.MulticastSource("ip4", &ifi) 243 if err != nil { 244 continue 245 } 246 c, err := net.ListenPacket("ip4:253", ip.String()) // unicast address 247 if err != nil { 248 t.Fatal(err) 249 } 250 defer c.Close() 251 r, err := ipv4.NewRawConn(c) 252 if err != nil { 253 t.Fatal(err) 254 } 255 if err := r.JoinGroup(&ifi, &gaddr); err != nil { 256 t.Fatal(err) 257 } 258 mlt = append(mlt, &ml{r, &ift[i]}) 259 } 260 for _, m := range mlt { 261 if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil { 262 t.Fatal(err) 263 } 264 } 265 }