github.com/mtsmfm/go/src@v0.0.0-20221020090648-44bdcb9f8fde/net/addrselect_test.go (about) 1 // Copyright 2015 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 //go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris 6 7 package net 8 9 import ( 10 "net/netip" 11 "reflect" 12 "testing" 13 ) 14 15 func TestSortByRFC6724(t *testing.T) { 16 tests := []struct { 17 in []IPAddr 18 srcs []netip.Addr 19 want []IPAddr 20 reverse bool // also test it starting backwards 21 }{ 22 // Examples from RFC 6724 section 10.2: 23 24 // Prefer matching scope. 25 { 26 in: []IPAddr{ 27 {IP: ParseIP("2001:db8:1::1")}, 28 {IP: ParseIP("198.51.100.121")}, 29 }, 30 srcs: []netip.Addr{ 31 netip.MustParseAddr("2001:db8:1::2"), 32 netip.MustParseAddr("169.254.13.78"), 33 }, 34 want: []IPAddr{ 35 {IP: ParseIP("2001:db8:1::1")}, 36 {IP: ParseIP("198.51.100.121")}, 37 }, 38 reverse: true, 39 }, 40 41 // Prefer matching scope. 42 { 43 in: []IPAddr{ 44 {IP: ParseIP("2001:db8:1::1")}, 45 {IP: ParseIP("198.51.100.121")}, 46 }, 47 srcs: []netip.Addr{ 48 netip.MustParseAddr("fe80::1"), 49 netip.MustParseAddr("198.51.100.117"), 50 }, 51 want: []IPAddr{ 52 {IP: ParseIP("198.51.100.121")}, 53 {IP: ParseIP("2001:db8:1::1")}, 54 }, 55 reverse: true, 56 }, 57 58 // Prefer higher precedence. 59 { 60 in: []IPAddr{ 61 {IP: ParseIP("2001:db8:1::1")}, 62 {IP: ParseIP("10.1.2.3")}, 63 }, 64 srcs: []netip.Addr{ 65 netip.MustParseAddr("2001:db8:1::2"), 66 netip.MustParseAddr("10.1.2.4"), 67 }, 68 want: []IPAddr{ 69 {IP: ParseIP("2001:db8:1::1")}, 70 {IP: ParseIP("10.1.2.3")}, 71 }, 72 reverse: true, 73 }, 74 75 // Prefer smaller scope. 76 { 77 in: []IPAddr{ 78 {IP: ParseIP("2001:db8:1::1")}, 79 {IP: ParseIP("fe80::1")}, 80 }, 81 srcs: []netip.Addr{ 82 netip.MustParseAddr("2001:db8:1::2"), 83 netip.MustParseAddr("fe80::2"), 84 }, 85 want: []IPAddr{ 86 {IP: ParseIP("fe80::1")}, 87 {IP: ParseIP("2001:db8:1::1")}, 88 }, 89 reverse: true, 90 }, 91 92 // Issue 13283. Having a 10/8 source address does not 93 // mean we should prefer 23/8 destination addresses. 94 { 95 in: []IPAddr{ 96 {IP: ParseIP("54.83.193.112")}, 97 {IP: ParseIP("184.72.238.214")}, 98 {IP: ParseIP("23.23.172.185")}, 99 {IP: ParseIP("75.101.148.21")}, 100 {IP: ParseIP("23.23.134.56")}, 101 {IP: ParseIP("23.21.50.150")}, 102 }, 103 srcs: []netip.Addr{ 104 netip.MustParseAddr("10.2.3.4"), 105 netip.MustParseAddr("10.2.3.4"), 106 netip.MustParseAddr("10.2.3.4"), 107 netip.MustParseAddr("10.2.3.4"), 108 netip.MustParseAddr("10.2.3.4"), 109 netip.MustParseAddr("10.2.3.4"), 110 }, 111 want: []IPAddr{ 112 {IP: ParseIP("54.83.193.112")}, 113 {IP: ParseIP("184.72.238.214")}, 114 {IP: ParseIP("23.23.172.185")}, 115 {IP: ParseIP("75.101.148.21")}, 116 {IP: ParseIP("23.23.134.56")}, 117 {IP: ParseIP("23.21.50.150")}, 118 }, 119 reverse: false, 120 }, 121 } 122 for i, tt := range tests { 123 inCopy := make([]IPAddr, len(tt.in)) 124 copy(inCopy, tt.in) 125 srcCopy := make([]netip.Addr, len(tt.in)) 126 copy(srcCopy, tt.srcs) 127 sortByRFC6724withSrcs(inCopy, srcCopy) 128 if !reflect.DeepEqual(inCopy, tt.want) { 129 t.Errorf("test %d:\nin = %s\ngot: %s\nwant: %s\n", i, tt.in, inCopy, tt.want) 130 } 131 if tt.reverse { 132 copy(inCopy, tt.in) 133 copy(srcCopy, tt.srcs) 134 for j := 0; j < len(inCopy)/2; j++ { 135 k := len(inCopy) - j - 1 136 inCopy[j], inCopy[k] = inCopy[k], inCopy[j] 137 srcCopy[j], srcCopy[k] = srcCopy[k], srcCopy[j] 138 } 139 sortByRFC6724withSrcs(inCopy, srcCopy) 140 if !reflect.DeepEqual(inCopy, tt.want) { 141 t.Errorf("test %d, starting backwards:\nin = %s\ngot: %s\nwant: %s\n", i, tt.in, inCopy, tt.want) 142 } 143 } 144 145 } 146 147 } 148 149 func TestRFC6724PolicyTableOrder(t *testing.T) { 150 for i := 0; i < len(rfc6724policyTable)-1; i++ { 151 if !(rfc6724policyTable[i].Prefix.Bits() >= rfc6724policyTable[i+1].Prefix.Bits()) { 152 t.Errorf("rfc6724policyTable item number %d sorted in wrong order = %d bits, next item = %d bits;", i, rfc6724policyTable[i].Prefix.Bits(), rfc6724policyTable[i+1].Prefix.Bits()) 153 } 154 } 155 } 156 157 func TestRFC6724PolicyTableContent(t *testing.T) { 158 expectedRfc6724policyTable := policyTable{ 159 { 160 Prefix: netip.MustParsePrefix("::1/128"), 161 Precedence: 50, 162 Label: 0, 163 }, 164 { 165 Prefix: netip.MustParsePrefix("::ffff:0:0/96"), 166 Precedence: 35, 167 Label: 4, 168 }, 169 { 170 Prefix: netip.MustParsePrefix("::/96"), 171 Precedence: 1, 172 Label: 3, 173 }, 174 { 175 Prefix: netip.MustParsePrefix("2001::/32"), 176 Precedence: 5, 177 Label: 5, 178 }, 179 { 180 Prefix: netip.MustParsePrefix("2002::/16"), 181 Precedence: 30, 182 Label: 2, 183 }, 184 { 185 Prefix: netip.MustParsePrefix("3ffe::/16"), 186 Precedence: 1, 187 Label: 12, 188 }, 189 { 190 Prefix: netip.MustParsePrefix("fec0::/10"), 191 Precedence: 1, 192 Label: 11, 193 }, 194 { 195 Prefix: netip.MustParsePrefix("fc00::/7"), 196 Precedence: 3, 197 Label: 13, 198 }, 199 { 200 Prefix: netip.MustParsePrefix("::/0"), 201 Precedence: 40, 202 Label: 1, 203 }, 204 } 205 if !reflect.DeepEqual(rfc6724policyTable, expectedRfc6724policyTable) { 206 t.Errorf("rfc6724policyTable has wrong contend = %v; want %v", rfc6724policyTable, expectedRfc6724policyTable) 207 } 208 } 209 210 func TestRFC6724PolicyTableClassify(t *testing.T) { 211 tests := []struct { 212 ip netip.Addr 213 want policyTableEntry 214 }{ 215 { 216 ip: netip.MustParseAddr("127.0.0.1"), 217 want: policyTableEntry{ 218 Prefix: netip.MustParsePrefix("::ffff:0:0/96"), 219 Precedence: 35, 220 Label: 4, 221 }, 222 }, 223 { 224 ip: netip.MustParseAddr("2601:645:8002:a500:986f:1db8:c836:bd65"), 225 want: policyTableEntry{ 226 Prefix: netip.MustParsePrefix("::/0"), 227 Precedence: 40, 228 Label: 1, 229 }, 230 }, 231 { 232 ip: netip.MustParseAddr("::1"), 233 want: policyTableEntry{ 234 Prefix: netip.MustParsePrefix("::1/128"), 235 Precedence: 50, 236 Label: 0, 237 }, 238 }, 239 { 240 ip: netip.MustParseAddr("2002::ab12"), 241 want: policyTableEntry{ 242 Prefix: netip.MustParsePrefix("2002::/16"), 243 Precedence: 30, 244 Label: 2, 245 }, 246 }, 247 } 248 for i, tt := range tests { 249 got := rfc6724policyTable.Classify(tt.ip) 250 if !reflect.DeepEqual(got, tt.want) { 251 t.Errorf("%d. Classify(%s) = %v; want %v", i, tt.ip, got, tt.want) 252 } 253 } 254 } 255 256 func TestRFC6724ClassifyScope(t *testing.T) { 257 tests := []struct { 258 ip netip.Addr 259 want scope 260 }{ 261 {netip.MustParseAddr("127.0.0.1"), scopeLinkLocal}, // rfc6724#section-3.2 262 {netip.MustParseAddr("::1"), scopeLinkLocal}, // rfc4007#section-4 263 {netip.MustParseAddr("169.254.1.2"), scopeLinkLocal}, // rfc6724#section-3.2 264 {netip.MustParseAddr("fec0::1"), scopeSiteLocal}, 265 {netip.MustParseAddr("8.8.8.8"), scopeGlobal}, 266 267 {netip.MustParseAddr("ff02::"), scopeLinkLocal}, // IPv6 multicast 268 {netip.MustParseAddr("ff05::"), scopeSiteLocal}, // IPv6 multicast 269 {netip.MustParseAddr("ff04::"), scopeAdminLocal}, // IPv6 multicast 270 {netip.MustParseAddr("ff0e::"), scopeGlobal}, // IPv6 multicast 271 272 {netip.AddrFrom16([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xe0, 0, 0, 0}), scopeGlobal}, // IPv4 link-local multicast as 16 bytes 273 {netip.AddrFrom16([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xe0, 2, 2, 2}), scopeGlobal}, // IPv4 global multicast as 16 bytes 274 {netip.AddrFrom4([4]byte{0xe0, 0, 0, 0}), scopeGlobal}, // IPv4 link-local multicast as 4 bytes 275 {netip.AddrFrom4([4]byte{0xe0, 2, 2, 2}), scopeGlobal}, // IPv4 global multicast as 4 bytes 276 } 277 for i, tt := range tests { 278 got := classifyScope(tt.ip) 279 if got != tt.want { 280 t.Errorf("%d. classifyScope(%s) = %x; want %x", i, tt.ip, got, tt.want) 281 } 282 } 283 } 284 285 func TestRFC6724CommonPrefixLength(t *testing.T) { 286 tests := []struct { 287 a netip.Addr 288 b IP 289 want int 290 }{ 291 {netip.MustParseAddr("fe80::1"), ParseIP("fe80::2"), 64}, 292 {netip.MustParseAddr("fe81::1"), ParseIP("fe80::2"), 15}, 293 {netip.MustParseAddr("127.0.0.1"), ParseIP("fe80::1"), 0}, // diff size 294 {netip.AddrFrom4([4]byte{1, 2, 3, 4}), IP{1, 2, 3, 4}, 32}, 295 {netip.AddrFrom4([4]byte{1, 2, 255, 255}), IP{1, 2, 0, 0}, 16}, 296 {netip.AddrFrom4([4]byte{1, 2, 127, 255}), IP{1, 2, 0, 0}, 17}, 297 {netip.AddrFrom4([4]byte{1, 2, 63, 255}), IP{1, 2, 0, 0}, 18}, 298 {netip.AddrFrom4([4]byte{1, 2, 31, 255}), IP{1, 2, 0, 0}, 19}, 299 {netip.AddrFrom4([4]byte{1, 2, 15, 255}), IP{1, 2, 0, 0}, 20}, 300 {netip.AddrFrom4([4]byte{1, 2, 7, 255}), IP{1, 2, 0, 0}, 21}, 301 {netip.AddrFrom4([4]byte{1, 2, 3, 255}), IP{1, 2, 0, 0}, 22}, 302 {netip.AddrFrom4([4]byte{1, 2, 1, 255}), IP{1, 2, 0, 0}, 23}, 303 {netip.AddrFrom4([4]byte{1, 2, 0, 255}), IP{1, 2, 0, 0}, 24}, 304 } 305 for i, tt := range tests { 306 got := commonPrefixLen(tt.a, tt.b) 307 if got != tt.want { 308 t.Errorf("%d. commonPrefixLen(%s, %s) = %d; want %d", i, tt.a, tt.b, got, tt.want) 309 } 310 } 311 312 }