github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/net/ipv4/multicastsockopt_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/internal/nettest" 13 "golang.org/x/net/ipv4" 14 ) 15 16 var packetConnMulticastSocketOptionTests = []struct { 17 net, proto, addr string 18 grp, src net.Addr 19 }{ 20 {"udp4", "", "224.0.0.0:0", &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}, nil}, // see RFC 4727 21 {"ip4", ":icmp", "0.0.0.0", &net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}, nil}, // see RFC 4727 22 23 {"udp4", "", "232.0.0.0:0", &net.UDPAddr{IP: net.IPv4(232, 0, 1, 249)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771 24 {"ip4", ":icmp", "0.0.0.0", &net.IPAddr{IP: net.IPv4(232, 0, 1, 250)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771 25 } 26 27 func TestPacketConnMulticastSocketOptions(t *testing.T) { 28 switch runtime.GOOS { 29 case "nacl", "plan9", "solaris": 30 t.Skipf("not supported on %s", runtime.GOOS) 31 } 32 ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback) 33 if ifi == nil { 34 t.Skipf("not available on %s", runtime.GOOS) 35 } 36 37 m, ok := nettest.SupportsRawIPSocket() 38 for _, tt := range packetConnMulticastSocketOptionTests { 39 if tt.net == "ip4" && !ok { 40 t.Log(m) 41 continue 42 } 43 c, err := net.ListenPacket(tt.net+tt.proto, tt.addr) 44 if err != nil { 45 t.Fatal(err) 46 } 47 defer c.Close() 48 p := ipv4.NewPacketConn(c) 49 defer p.Close() 50 51 if tt.src == nil { 52 testMulticastSocketOptions(t, p, ifi, tt.grp) 53 } else { 54 testSourceSpecificMulticastSocketOptions(t, p, ifi, tt.grp, tt.src) 55 } 56 } 57 } 58 59 var rawConnMulticastSocketOptionTests = []struct { 60 grp, src net.Addr 61 }{ 62 {&net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}, nil}, // see RFC 4727 63 64 {&net.IPAddr{IP: net.IPv4(232, 0, 1, 250)}, &net.IPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771 65 } 66 67 func TestRawConnMulticastSocketOptions(t *testing.T) { 68 switch runtime.GOOS { 69 case "nacl", "plan9", "solaris": 70 t.Skipf("not supported on %s", runtime.GOOS) 71 } 72 if m, ok := nettest.SupportsRawIPSocket(); !ok { 73 t.Skip(m) 74 } 75 ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback) 76 if ifi == nil { 77 t.Skipf("not available on %s", runtime.GOOS) 78 } 79 80 for _, tt := range rawConnMulticastSocketOptionTests { 81 c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") 82 if err != nil { 83 t.Fatal(err) 84 } 85 defer c.Close() 86 r, err := ipv4.NewRawConn(c) 87 if err != nil { 88 t.Fatal(err) 89 } 90 defer r.Close() 91 92 if tt.src == nil { 93 testMulticastSocketOptions(t, r, ifi, tt.grp) 94 } else { 95 testSourceSpecificMulticastSocketOptions(t, r, ifi, tt.grp, tt.src) 96 } 97 } 98 } 99 100 type testIPv4MulticastConn interface { 101 MulticastTTL() (int, error) 102 SetMulticastTTL(ttl int) error 103 MulticastLoopback() (bool, error) 104 SetMulticastLoopback(bool) error 105 JoinGroup(*net.Interface, net.Addr) error 106 LeaveGroup(*net.Interface, net.Addr) error 107 JoinSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error 108 LeaveSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error 109 ExcludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error 110 IncludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error 111 } 112 113 func testMulticastSocketOptions(t *testing.T, c testIPv4MulticastConn, ifi *net.Interface, grp net.Addr) { 114 const ttl = 255 115 if err := c.SetMulticastTTL(ttl); err != nil { 116 t.Error(err) 117 return 118 } 119 if v, err := c.MulticastTTL(); err != nil { 120 t.Error(err) 121 return 122 } else if v != ttl { 123 t.Errorf("got %v; want %v", v, ttl) 124 return 125 } 126 127 for _, toggle := range []bool{true, false} { 128 if err := c.SetMulticastLoopback(toggle); err != nil { 129 t.Error(err) 130 return 131 } 132 if v, err := c.MulticastLoopback(); err != nil { 133 t.Error(err) 134 return 135 } else if v != toggle { 136 t.Errorf("got %v; want %v", v, toggle) 137 return 138 } 139 } 140 141 if err := c.JoinGroup(ifi, grp); err != nil { 142 t.Error(err) 143 return 144 } 145 if err := c.LeaveGroup(ifi, grp); err != nil { 146 t.Error(err) 147 return 148 } 149 } 150 151 func testSourceSpecificMulticastSocketOptions(t *testing.T, c testIPv4MulticastConn, ifi *net.Interface, grp, src net.Addr) { 152 // MCAST_JOIN_GROUP -> MCAST_BLOCK_SOURCE -> MCAST_UNBLOCK_SOURCE -> MCAST_LEAVE_GROUP 153 if err := c.JoinGroup(ifi, grp); err != nil { 154 t.Error(err) 155 return 156 } 157 if err := c.ExcludeSourceSpecificGroup(ifi, grp, src); err != nil { 158 switch runtime.GOOS { 159 case "freebsd", "linux": 160 default: // platforms that don't support IGMPv2/3 fail here 161 t.Logf("not supported on %s", runtime.GOOS) 162 return 163 } 164 t.Error(err) 165 return 166 } 167 if err := c.IncludeSourceSpecificGroup(ifi, grp, src); err != nil { 168 t.Error(err) 169 return 170 } 171 if err := c.LeaveGroup(ifi, grp); err != nil { 172 t.Error(err) 173 return 174 } 175 176 // MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_SOURCE_GROUP 177 if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil { 178 t.Error(err) 179 return 180 } 181 if err := c.LeaveSourceSpecificGroup(ifi, grp, src); err != nil { 182 t.Error(err) 183 return 184 } 185 186 // MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_GROUP 187 if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil { 188 t.Error(err) 189 return 190 } 191 if err := c.LeaveGroup(ifi, grp); err != nil { 192 t.Error(err) 193 return 194 } 195 }