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