diff options
Diffstat (limited to 'src/net/addrselect_test.go')
-rw-r--r-- | src/net/addrselect_test.go | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/src/net/addrselect_test.go b/src/net/addrselect_test.go new file mode 100644 index 0000000..d6e0e63 --- /dev/null +++ b/src/net/addrselect_test.go @@ -0,0 +1,249 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd linux netbsd openbsd solaris + +package net + +import ( + "reflect" + "testing" +) + +func TestSortByRFC6724(t *testing.T) { + tests := []struct { + in []IPAddr + srcs []IP + want []IPAddr + reverse bool // also test it starting backwards + }{ + // Examples from RFC 6724 section 10.2: + + // Prefer matching scope. + { + in: []IPAddr{ + {IP: ParseIP("2001:db8:1::1")}, + {IP: ParseIP("198.51.100.121")}, + }, + srcs: []IP{ + ParseIP("2001:db8:1::2"), + ParseIP("169.254.13.78"), + }, + want: []IPAddr{ + {IP: ParseIP("2001:db8:1::1")}, + {IP: ParseIP("198.51.100.121")}, + }, + reverse: true, + }, + + // Prefer matching scope. + { + in: []IPAddr{ + {IP: ParseIP("2001:db8:1::1")}, + {IP: ParseIP("198.51.100.121")}, + }, + srcs: []IP{ + ParseIP("fe80::1"), + ParseIP("198.51.100.117"), + }, + want: []IPAddr{ + {IP: ParseIP("198.51.100.121")}, + {IP: ParseIP("2001:db8:1::1")}, + }, + reverse: true, + }, + + // Prefer higher precedence. + { + in: []IPAddr{ + {IP: ParseIP("2001:db8:1::1")}, + {IP: ParseIP("10.1.2.3")}, + }, + srcs: []IP{ + ParseIP("2001:db8:1::2"), + ParseIP("10.1.2.4"), + }, + want: []IPAddr{ + {IP: ParseIP("2001:db8:1::1")}, + {IP: ParseIP("10.1.2.3")}, + }, + reverse: true, + }, + + // Prefer smaller scope. + { + in: []IPAddr{ + {IP: ParseIP("2001:db8:1::1")}, + {IP: ParseIP("fe80::1")}, + }, + srcs: []IP{ + ParseIP("2001:db8:1::2"), + ParseIP("fe80::2"), + }, + want: []IPAddr{ + {IP: ParseIP("fe80::1")}, + {IP: ParseIP("2001:db8:1::1")}, + }, + reverse: true, + }, + + // Issue 13283. Having a 10/8 source address does not + // mean we should prefer 23/8 destination addresses. + { + in: []IPAddr{ + {IP: ParseIP("54.83.193.112")}, + {IP: ParseIP("184.72.238.214")}, + {IP: ParseIP("23.23.172.185")}, + {IP: ParseIP("75.101.148.21")}, + {IP: ParseIP("23.23.134.56")}, + {IP: ParseIP("23.21.50.150")}, + }, + srcs: []IP{ + ParseIP("10.2.3.4"), + ParseIP("10.2.3.4"), + ParseIP("10.2.3.4"), + ParseIP("10.2.3.4"), + ParseIP("10.2.3.4"), + ParseIP("10.2.3.4"), + }, + want: []IPAddr{ + {IP: ParseIP("54.83.193.112")}, + {IP: ParseIP("184.72.238.214")}, + {IP: ParseIP("23.23.172.185")}, + {IP: ParseIP("75.101.148.21")}, + {IP: ParseIP("23.23.134.56")}, + {IP: ParseIP("23.21.50.150")}, + }, + reverse: false, + }, + } + for i, tt := range tests { + inCopy := make([]IPAddr, len(tt.in)) + copy(inCopy, tt.in) + srcCopy := make([]IP, len(tt.in)) + copy(srcCopy, tt.srcs) + sortByRFC6724withSrcs(inCopy, srcCopy) + if !reflect.DeepEqual(inCopy, tt.want) { + t.Errorf("test %d:\nin = %s\ngot: %s\nwant: %s\n", i, tt.in, inCopy, tt.want) + } + if tt.reverse { + copy(inCopy, tt.in) + copy(srcCopy, tt.srcs) + for j := 0; j < len(inCopy)/2; j++ { + k := len(inCopy) - j - 1 + inCopy[j], inCopy[k] = inCopy[k], inCopy[j] + srcCopy[j], srcCopy[k] = srcCopy[k], srcCopy[j] + } + sortByRFC6724withSrcs(inCopy, srcCopy) + if !reflect.DeepEqual(inCopy, tt.want) { + t.Errorf("test %d, starting backwards:\nin = %s\ngot: %s\nwant: %s\n", i, tt.in, inCopy, tt.want) + } + } + + } + +} + +func TestRFC6724PolicyTableClassify(t *testing.T) { + tests := []struct { + ip IP + want policyTableEntry + }{ + { + ip: ParseIP("127.0.0.1"), + want: policyTableEntry{ + Prefix: &IPNet{IP: ParseIP("::ffff:0:0"), Mask: CIDRMask(96, 128)}, + Precedence: 35, + Label: 4, + }, + }, + { + ip: ParseIP("2601:645:8002:a500:986f:1db8:c836:bd65"), + want: policyTableEntry{ + Prefix: &IPNet{IP: ParseIP("::"), Mask: CIDRMask(0, 128)}, + Precedence: 40, + Label: 1, + }, + }, + { + ip: ParseIP("::1"), + want: policyTableEntry{ + Prefix: &IPNet{IP: ParseIP("::1"), Mask: CIDRMask(128, 128)}, + Precedence: 50, + Label: 0, + }, + }, + { + ip: ParseIP("2002::ab12"), + want: policyTableEntry{ + Prefix: &IPNet{IP: ParseIP("2002::"), Mask: CIDRMask(16, 128)}, + Precedence: 30, + Label: 2, + }, + }, + } + for i, tt := range tests { + got := rfc6724policyTable.Classify(tt.ip) + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("%d. Classify(%s) = %v; want %v", i, tt.ip, got, tt.want) + } + } +} + +func TestRFC6724ClassifyScope(t *testing.T) { + tests := []struct { + ip IP + want scope + }{ + {ParseIP("127.0.0.1"), scopeLinkLocal}, // rfc6724#section-3.2 + {ParseIP("::1"), scopeLinkLocal}, // rfc4007#section-4 + {ParseIP("169.254.1.2"), scopeLinkLocal}, // rfc6724#section-3.2 + {ParseIP("fec0::1"), scopeSiteLocal}, + {ParseIP("8.8.8.8"), scopeGlobal}, + + {ParseIP("ff02::"), scopeLinkLocal}, // IPv6 multicast + {ParseIP("ff05::"), scopeSiteLocal}, // IPv6 multicast + {ParseIP("ff04::"), scopeAdminLocal}, // IPv6 multicast + {ParseIP("ff0e::"), scopeGlobal}, // IPv6 multicast + + {IPv4(0xe0, 0, 0, 0), scopeGlobal}, // IPv4 link-local multicast as 16 bytes + {IPv4(0xe0, 2, 2, 2), scopeGlobal}, // IPv4 global multicast as 16 bytes + {IPv4(0xe0, 0, 0, 0).To4(), scopeGlobal}, // IPv4 link-local multicast as 4 bytes + {IPv4(0xe0, 2, 2, 2).To4(), scopeGlobal}, // IPv4 global multicast as 4 bytes + } + for i, tt := range tests { + got := classifyScope(tt.ip) + if got != tt.want { + t.Errorf("%d. classifyScope(%s) = %x; want %x", i, tt.ip, got, tt.want) + } + } +} + +func TestRFC6724CommonPrefixLength(t *testing.T) { + tests := []struct { + a, b IP + want int + }{ + {ParseIP("fe80::1"), ParseIP("fe80::2"), 64}, + {ParseIP("fe81::1"), ParseIP("fe80::2"), 15}, + {ParseIP("127.0.0.1"), ParseIP("fe80::1"), 0}, // diff size + {IPv4(1, 2, 3, 4), IP{1, 2, 3, 4}, 32}, + {IP{1, 2, 255, 255}, IP{1, 2, 0, 0}, 16}, + {IP{1, 2, 127, 255}, IP{1, 2, 0, 0}, 17}, + {IP{1, 2, 63, 255}, IP{1, 2, 0, 0}, 18}, + {IP{1, 2, 31, 255}, IP{1, 2, 0, 0}, 19}, + {IP{1, 2, 15, 255}, IP{1, 2, 0, 0}, 20}, + {IP{1, 2, 7, 255}, IP{1, 2, 0, 0}, 21}, + {IP{1, 2, 3, 255}, IP{1, 2, 0, 0}, 22}, + {IP{1, 2, 1, 255}, IP{1, 2, 0, 0}, 23}, + {IP{1, 2, 0, 255}, IP{1, 2, 0, 0}, 24}, + } + for i, tt := range tests { + got := commonPrefixLen(tt.a, tt.b) + if got != tt.want { + t.Errorf("%d. commonPrefixLen(%s, %s) = %d; want %d", i, tt.a, tt.b, got, tt.want) + } + } + +} |