github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/net/ipv6/multicast_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 "bytes" 9 "net" 10 "os" 11 "runtime" 12 "testing" 13 "time" 14 15 "golang.org/x/net/icmp" 16 "golang.org/x/net/internal/iana" 17 "golang.org/x/net/internal/nettest" 18 "golang.org/x/net/ipv6" 19 ) 20 21 var packetConnReadWriteMulticastUDPTests = []struct { 22 addr string 23 grp, src *net.UDPAddr 24 }{ 25 {"[ff02::]:0", &net.UDPAddr{IP: net.ParseIP("ff02::114")}, nil}, // see RFC 4727 26 27 {"[ff30::8000:0]:0", &net.UDPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.UDPAddr{IP: net.IPv6loopback}}, // see RFC 5771 28 } 29 30 func TestPacketConnReadWriteMulticastUDP(t *testing.T) { 31 switch runtime.GOOS { 32 case "freebsd": // due to a bug on loopback marking 33 // See http://www.freebsd.org/cgi/query-pr.cgi?pr=180065. 34 t.Skipf("not supported on %s", runtime.GOOS) 35 case "nacl", "plan9", "solaris", "windows": 36 t.Skipf("not supported on %s", runtime.GOOS) 37 } 38 if !supportsIPv6 { 39 t.Skip("ipv6 is not supported") 40 } 41 ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagMulticast|net.FlagLoopback) 42 if ifi == nil { 43 t.Skipf("not available on %s", runtime.GOOS) 44 } 45 46 for _, tt := range packetConnReadWriteMulticastUDPTests { 47 c, err := net.ListenPacket("udp6", tt.addr) 48 if err != nil { 49 t.Fatal(err) 50 } 51 defer c.Close() 52 53 grp := *tt.grp 54 grp.Port = c.LocalAddr().(*net.UDPAddr).Port 55 p := ipv6.NewPacketConn(c) 56 defer p.Close() 57 if tt.src == nil { 58 if err := p.JoinGroup(ifi, &grp); err != nil { 59 t.Fatal(err) 60 } 61 defer p.LeaveGroup(ifi, &grp) 62 } else { 63 if err := p.JoinSourceSpecificGroup(ifi, &grp, tt.src); err != nil { 64 switch runtime.GOOS { 65 case "freebsd", "linux": 66 default: // platforms that don't support MLDv2 fail here 67 t.Logf("not supported on %s", runtime.GOOS) 68 continue 69 } 70 t.Fatal(err) 71 } 72 defer p.LeaveSourceSpecificGroup(ifi, &grp, tt.src) 73 } 74 if err := p.SetMulticastInterface(ifi); err != nil { 75 t.Fatal(err) 76 } 77 if _, err := p.MulticastInterface(); err != nil { 78 t.Fatal(err) 79 } 80 if err := p.SetMulticastLoopback(true); err != nil { 81 t.Fatal(err) 82 } 83 if _, err := p.MulticastLoopback(); err != nil { 84 t.Fatal(err) 85 } 86 87 cm := ipv6.ControlMessage{ 88 TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced, 89 Src: net.IPv6loopback, 90 IfIndex: ifi.Index, 91 } 92 cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU 93 wb := []byte("HELLO-R-U-THERE") 94 95 for i, toggle := range []bool{true, false, true} { 96 if err := p.SetControlMessage(cf, toggle); err != nil { 97 if nettest.ProtocolNotSupported(err) { 98 t.Logf("not supported on %s", runtime.GOOS) 99 continue 100 } 101 t.Fatal(err) 102 } 103 if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil { 104 t.Fatal(err) 105 } 106 cm.HopLimit = i + 1 107 if n, err := p.WriteTo(wb, &cm, &grp); err != nil { 108 t.Fatal(err) 109 } else if n != len(wb) { 110 t.Fatal(err) 111 } 112 rb := make([]byte, 128) 113 if n, _, _, err := p.ReadFrom(rb); err != nil { 114 t.Fatal(err) 115 } else if !bytes.Equal(rb[:n], wb) { 116 t.Fatalf("got %v; want %v", rb[:n], wb) 117 } 118 } 119 } 120 } 121 122 var packetConnReadWriteMulticastICMPTests = []struct { 123 grp, src *net.IPAddr 124 }{ 125 {&net.IPAddr{IP: net.ParseIP("ff02::114")}, nil}, // see RFC 4727 126 127 {&net.IPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.IPAddr{IP: net.IPv6loopback}}, // see RFC 5771 128 } 129 130 func TestPacketConnReadWriteMulticastICMP(t *testing.T) { 131 switch runtime.GOOS { 132 case "freebsd": // due to a bug on loopback marking 133 // See http://www.freebsd.org/cgi/query-pr.cgi?pr=180065. 134 t.Skipf("not supported on %s", runtime.GOOS) 135 case "nacl", "plan9", "solaris", "windows": 136 t.Skipf("not supported on %s", runtime.GOOS) 137 } 138 if !supportsIPv6 { 139 t.Skip("ipv6 is not supported") 140 } 141 if m, ok := nettest.SupportsRawIPSocket(); !ok { 142 t.Skip(m) 143 } 144 ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagMulticast|net.FlagLoopback) 145 if ifi == nil { 146 t.Skipf("not available on %s", runtime.GOOS) 147 } 148 149 for _, tt := range packetConnReadWriteMulticastICMPTests { 150 c, err := net.ListenPacket("ip6:ipv6-icmp", "::") 151 if err != nil { 152 t.Fatal(err) 153 } 154 defer c.Close() 155 156 pshicmp := icmp.IPv6PseudoHeader(c.LocalAddr().(*net.IPAddr).IP, tt.grp.IP) 157 p := ipv6.NewPacketConn(c) 158 defer p.Close() 159 if tt.src == nil { 160 if err := p.JoinGroup(ifi, tt.grp); err != nil { 161 t.Fatal(err) 162 } 163 defer p.LeaveGroup(ifi, tt.grp) 164 } else { 165 if err := p.JoinSourceSpecificGroup(ifi, tt.grp, tt.src); err != nil { 166 switch runtime.GOOS { 167 case "freebsd", "linux": 168 default: // platforms that don't support MLDv2 fail here 169 t.Logf("not supported on %s", runtime.GOOS) 170 continue 171 } 172 t.Fatal(err) 173 } 174 defer p.LeaveSourceSpecificGroup(ifi, tt.grp, tt.src) 175 } 176 if err := p.SetMulticastInterface(ifi); err != nil { 177 t.Fatal(err) 178 } 179 if _, err := p.MulticastInterface(); err != nil { 180 t.Fatal(err) 181 } 182 if err := p.SetMulticastLoopback(true); err != nil { 183 t.Fatal(err) 184 } 185 if _, err := p.MulticastLoopback(); err != nil { 186 t.Fatal(err) 187 } 188 189 cm := ipv6.ControlMessage{ 190 TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced, 191 Src: net.IPv6loopback, 192 IfIndex: ifi.Index, 193 } 194 cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU 195 196 var f ipv6.ICMPFilter 197 f.SetAll(true) 198 f.Accept(ipv6.ICMPTypeEchoReply) 199 if err := p.SetICMPFilter(&f); err != nil { 200 t.Fatal(err) 201 } 202 203 var psh []byte 204 for i, toggle := range []bool{true, false, true} { 205 if toggle { 206 psh = nil 207 if err := p.SetChecksum(true, 2); err != nil { 208 t.Fatal(err) 209 } 210 } else { 211 psh = pshicmp 212 // Some platforms never allow to 213 // disable the kernel checksum 214 // processing. 215 p.SetChecksum(false, -1) 216 } 217 wb, err := (&icmp.Message{ 218 Type: ipv6.ICMPTypeEchoRequest, Code: 0, 219 Body: &icmp.Echo{ 220 ID: os.Getpid() & 0xffff, Seq: i + 1, 221 Data: []byte("HELLO-R-U-THERE"), 222 }, 223 }).Marshal(psh) 224 if err != nil { 225 t.Fatal(err) 226 } 227 if err := p.SetControlMessage(cf, toggle); err != nil { 228 if nettest.ProtocolNotSupported(err) { 229 t.Logf("not supported on %s", runtime.GOOS) 230 continue 231 } 232 t.Fatal(err) 233 } 234 if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil { 235 t.Fatal(err) 236 } 237 cm.HopLimit = i + 1 238 if n, err := p.WriteTo(wb, &cm, tt.grp); err != nil { 239 t.Fatal(err) 240 } else if n != len(wb) { 241 t.Fatalf("got %v; want %v", n, len(wb)) 242 } 243 rb := make([]byte, 128) 244 if n, _, _, err := p.ReadFrom(rb); err != nil { 245 switch runtime.GOOS { 246 case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket 247 t.Logf("not supported on %s", runtime.GOOS) 248 continue 249 } 250 t.Fatal(err) 251 } else { 252 if m, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, rb[:n]); err != nil { 253 t.Fatal(err) 254 } else if m.Type != ipv6.ICMPTypeEchoReply || m.Code != 0 { 255 t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv6.ICMPTypeEchoReply, 0) 256 } 257 } 258 } 259 } 260 }