github.com/d4l3k/go@v0.0.0-20151015000803-65fc379daeda/src/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 // +build darwin dragonfly freebsd linux netbsd openbsd solaris 6 7 package net 8 9 import ( 10 "reflect" 11 "testing" 12 ) 13 14 func TestSortByRFC6724(t *testing.T) { 15 tests := []struct { 16 in []IPAddr 17 srcs []IP 18 want []IPAddr 19 reverse bool // also test it starting backwards 20 }{ 21 // Examples from RFC 6724 section 10.2: 22 23 // Prefer matching scope. 24 { 25 in: []IPAddr{ 26 {IP: ParseIP("2001:db8:1::1")}, 27 {IP: ParseIP("198.51.100.121")}, 28 }, 29 srcs: []IP{ 30 ParseIP("2001:db8:1::2"), 31 ParseIP("169.254.13.78"), 32 }, 33 want: []IPAddr{ 34 {IP: ParseIP("2001:db8:1::1")}, 35 {IP: ParseIP("198.51.100.121")}, 36 }, 37 reverse: true, 38 }, 39 40 // Prefer matching scope. 41 { 42 in: []IPAddr{ 43 {IP: ParseIP("2001:db8:1::1")}, 44 {IP: ParseIP("198.51.100.121")}, 45 }, 46 srcs: []IP{ 47 ParseIP("fe80::1"), 48 ParseIP("198.51.100.117"), 49 }, 50 want: []IPAddr{ 51 {IP: ParseIP("198.51.100.121")}, 52 {IP: ParseIP("2001:db8:1::1")}, 53 }, 54 reverse: true, 55 }, 56 57 // Prefer higher precedence. 58 { 59 in: []IPAddr{ 60 {IP: ParseIP("2001:db8:1::1")}, 61 {IP: ParseIP("10.1.2.3")}, 62 }, 63 srcs: []IP{ 64 ParseIP("2001:db8:1::2"), 65 ParseIP("10.1.2.4"), 66 }, 67 want: []IPAddr{ 68 {IP: ParseIP("2001:db8:1::1")}, 69 {IP: ParseIP("10.1.2.3")}, 70 }, 71 reverse: true, 72 }, 73 74 // Prefer smaller scope. 75 { 76 in: []IPAddr{ 77 {IP: ParseIP("2001:db8:1::1")}, 78 {IP: ParseIP("fe80::1")}, 79 }, 80 srcs: []IP{ 81 ParseIP("2001:db8:1::2"), 82 ParseIP("fe80::2"), 83 }, 84 want: []IPAddr{ 85 {IP: ParseIP("fe80::1")}, 86 {IP: ParseIP("2001:db8:1::1")}, 87 }, 88 reverse: true, 89 }, 90 } 91 for i, tt := range tests { 92 inCopy := make([]IPAddr, len(tt.in)) 93 copy(inCopy, tt.in) 94 srcCopy := make([]IP, len(tt.in)) 95 copy(srcCopy, tt.srcs) 96 sortByRFC6724withSrcs(inCopy, srcCopy) 97 if !reflect.DeepEqual(inCopy, tt.want) { 98 t.Errorf("test %d:\nin = %s\ngot: %s\nwant: %s\n", i, tt.in, inCopy, tt.want) 99 } 100 if tt.reverse { 101 copy(inCopy, tt.in) 102 copy(srcCopy, tt.srcs) 103 for j := 0; j < len(inCopy)/2; j++ { 104 k := len(inCopy) - j - 1 105 inCopy[j], inCopy[k] = inCopy[k], inCopy[j] 106 srcCopy[j], srcCopy[k] = srcCopy[k], srcCopy[j] 107 } 108 sortByRFC6724withSrcs(inCopy, srcCopy) 109 if !reflect.DeepEqual(inCopy, tt.want) { 110 t.Errorf("test %d, starting backwards:\nin = %s\ngot: %s\nwant: %s\n", i, tt.in, inCopy, tt.want) 111 } 112 } 113 114 } 115 116 } 117 118 func TestRFC6724PolicyTableClassify(t *testing.T) { 119 tests := []struct { 120 ip IP 121 want policyTableEntry 122 }{ 123 { 124 ip: ParseIP("127.0.0.1"), 125 want: policyTableEntry{ 126 Prefix: &IPNet{IP: ParseIP("::ffff:0:0"), Mask: CIDRMask(96, 128)}, 127 Precedence: 35, 128 Label: 4, 129 }, 130 }, 131 { 132 ip: ParseIP("2601:645:8002:a500:986f:1db8:c836:bd65"), 133 want: policyTableEntry{ 134 Prefix: &IPNet{IP: ParseIP("::"), Mask: CIDRMask(0, 128)}, 135 Precedence: 40, 136 Label: 1, 137 }, 138 }, 139 { 140 ip: ParseIP("::1"), 141 want: policyTableEntry{ 142 Prefix: &IPNet{IP: ParseIP("::1"), Mask: CIDRMask(128, 128)}, 143 Precedence: 50, 144 Label: 0, 145 }, 146 }, 147 { 148 ip: ParseIP("2002::ab12"), 149 want: policyTableEntry{ 150 Prefix: &IPNet{IP: ParseIP("2002::"), Mask: CIDRMask(16, 128)}, 151 Precedence: 30, 152 Label: 2, 153 }, 154 }, 155 } 156 for i, tt := range tests { 157 got := rfc6724policyTable.Classify(tt.ip) 158 if !reflect.DeepEqual(got, tt.want) { 159 t.Errorf("%d. Classify(%s) = %v; want %v", i, tt.ip, got, tt.want) 160 } 161 } 162 } 163 164 func TestRFC6724ClassifyScope(t *testing.T) { 165 tests := []struct { 166 ip IP 167 want scope 168 }{ 169 {ParseIP("127.0.0.1"), scopeLinkLocal}, // rfc6724#section-3.2 170 {ParseIP("::1"), scopeLinkLocal}, // rfc4007#section-4 171 {ParseIP("169.254.1.2"), scopeLinkLocal}, // rfc6724#section-3.2 172 {ParseIP("fec0::1"), scopeSiteLocal}, 173 {ParseIP("8.8.8.8"), scopeGlobal}, 174 175 {ParseIP("ff02::"), scopeLinkLocal}, // IPv6 multicast 176 {ParseIP("ff05::"), scopeSiteLocal}, // IPv6 multicast 177 {ParseIP("ff04::"), scopeAdminLocal}, // IPv6 multicast 178 {ParseIP("ff0e::"), scopeGlobal}, // IPv6 multicast 179 180 {IPv4(0xe0, 0, 0, 0), scopeGlobal}, // IPv4 link-local multicast as 16 bytes 181 {IPv4(0xe0, 2, 2, 2), scopeGlobal}, // IPv4 global multicast as 16 bytes 182 {IPv4(0xe0, 0, 0, 0).To4(), scopeGlobal}, // IPv4 link-local multicast as 4 bytes 183 {IPv4(0xe0, 2, 2, 2).To4(), scopeGlobal}, // IPv4 global multicast as 4 bytes 184 } 185 for i, tt := range tests { 186 got := classifyScope(tt.ip) 187 if got != tt.want { 188 t.Errorf("%d. classifyScope(%s) = %x; want %x", i, tt.ip, got, tt.want) 189 } 190 } 191 } 192 193 func TestRFC6724CommonPrefixLength(t *testing.T) { 194 tests := []struct { 195 a, b IP 196 want int 197 }{ 198 {ParseIP("fe80::1"), ParseIP("fe80::2"), 64}, 199 {ParseIP("fe81::1"), ParseIP("fe80::2"), 15}, 200 {ParseIP("127.0.0.1"), ParseIP("fe80::1"), 0}, // diff size 201 {IPv4(1, 2, 3, 4), IP{1, 2, 3, 4}, 32}, 202 {IP{1, 2, 255, 255}, IP{1, 2, 0, 0}, 16}, 203 {IP{1, 2, 127, 255}, IP{1, 2, 0, 0}, 17}, 204 {IP{1, 2, 63, 255}, IP{1, 2, 0, 0}, 18}, 205 {IP{1, 2, 31, 255}, IP{1, 2, 0, 0}, 19}, 206 {IP{1, 2, 15, 255}, IP{1, 2, 0, 0}, 20}, 207 {IP{1, 2, 7, 255}, IP{1, 2, 0, 0}, 21}, 208 {IP{1, 2, 3, 255}, IP{1, 2, 0, 0}, 22}, 209 {IP{1, 2, 1, 255}, IP{1, 2, 0, 0}, 23}, 210 {IP{1, 2, 0, 255}, IP{1, 2, 0, 0}, 24}, 211 } 212 for i, tt := range tests { 213 got := commonPrefixLen(tt.a, tt.b) 214 if got != tt.want { 215 t.Errorf("%d. commonPrefixLen(%s, %s) = %d; want %d", i, tt.a, tt.b, got, tt.want) 216 } 217 } 218 219 }