gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/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 "gitee.com/ks-custle/core-gm/net/ipv4" 13 "gitee.com/ks-custle/core-gm/net/nettest" 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 "fuchsia", "hurd", "js", "nacl", "plan9", "zos": 30 t.Skipf("not supported on %s", runtime.GOOS) 31 } 32 ifi, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback) 33 if err != nil { 34 t.Skipf("not available on %s", runtime.GOOS) 35 } 36 37 ok := nettest.SupportsRawSocket() 38 for _, tt := range packetConnMulticastSocketOptionTests { 39 if tt.net == "ip4" && !ok { 40 t.Logf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH) 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 "fuchsia", "hurd", "js", "nacl", "plan9", "zos": 70 t.Skipf("not supported on %s", runtime.GOOS) 71 } 72 if !nettest.SupportsRawSocket() { 73 t.Skipf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH) 74 } 75 ifi, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback) 76 if err != 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 t.Helper() 115 116 const ttl = 255 117 if err := c.SetMulticastTTL(ttl); err != nil { 118 t.Error(err) 119 return 120 } 121 if v, err := c.MulticastTTL(); err != nil { 122 t.Error(err) 123 return 124 } else if v != ttl { 125 t.Errorf("got %v; want %v", v, ttl) 126 return 127 } 128 129 for _, toggle := range []bool{true, false} { 130 if err := c.SetMulticastLoopback(toggle); err != nil { 131 t.Error(err) 132 return 133 } 134 if v, err := c.MulticastLoopback(); err != nil { 135 t.Error(err) 136 return 137 } else if v != toggle { 138 t.Errorf("got %v; want %v", v, toggle) 139 return 140 } 141 } 142 143 if err := c.JoinGroup(ifi, grp); err != nil { 144 t.Error(err) 145 return 146 } 147 if err := c.LeaveGroup(ifi, grp); err != nil { 148 t.Error(err) 149 return 150 } 151 } 152 153 func testSourceSpecificMulticastSocketOptions(t *testing.T, c testIPv4MulticastConn, ifi *net.Interface, grp, src net.Addr) { 154 t.Helper() 155 156 // MCAST_JOIN_GROUP -> MCAST_BLOCK_SOURCE -> MCAST_UNBLOCK_SOURCE -> MCAST_LEAVE_GROUP 157 if err := c.JoinGroup(ifi, grp); err != nil { 158 t.Error(err) 159 return 160 } 161 if err := c.ExcludeSourceSpecificGroup(ifi, grp, src); err != nil { 162 switch runtime.GOOS { 163 case "freebsd", "linux": 164 default: // platforms that don't support IGMPv2/3 fail here 165 t.Logf("not supported on %s", runtime.GOOS) 166 return 167 } 168 t.Error(err) 169 return 170 } 171 if err := c.IncludeSourceSpecificGroup(ifi, grp, src); err != nil { 172 t.Error(err) 173 return 174 } 175 if err := c.LeaveGroup(ifi, grp); err != nil { 176 t.Error(err) 177 return 178 } 179 180 // MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_SOURCE_GROUP 181 if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil { 182 t.Error(err) 183 return 184 } 185 if err := c.LeaveSourceSpecificGroup(ifi, grp, src); err != nil { 186 t.Error(err) 187 return 188 } 189 190 // MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_GROUP 191 if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil { 192 t.Error(err) 193 return 194 } 195 if err := c.LeaveGroup(ifi, grp); err != nil { 196 t.Error(err) 197 return 198 } 199 }