addrmanager_test.go raw
1 package addrmgr_test
2
3 import (
4 "errors"
5 "fmt"
6 "net"
7 "reflect"
8 "testing"
9 "time"
10
11 "github.com/p9c/p9/pkg/addrmgr"
12 "github.com/p9c/p9/pkg/wire"
13 )
14
15 // naTest is used to describe a test to be performed against the NetAddressKey method.
16 type naTest struct {
17 in wire.NetAddress
18 want string
19 }
20
21 // naTests houses all of the tests to be performed against the NetAddressKey method.
22 var naTests = make([]naTest, 0)
23
24 // Put some IP in here for convenience. Points to google.
25 var someIP = "173.194.115.66"
26
27 // addNaTests
28 func addNaTests() {
29 // IPv4
30 // Localhost
31 addNaTest("127.0.0.1", 11047, "127.0.0.1:11047")
32 addNaTest("127.0.0.1", 11048, "127.0.0.1:11048")
33 // Class A
34 addNaTest("1.0.0.1", 11047, "1.0.0.1:11047")
35 addNaTest("2.2.2.2", 11048, "2.2.2.2:11048")
36 addNaTest("27.253.252.251", 8335, "27.253.252.251:8335")
37 addNaTest("123.3.2.1", 8336, "123.3.2.1:8336")
38 // Private Class A
39 addNaTest("10.0.0.1", 11047, "10.0.0.1:11047")
40 addNaTest("10.1.1.1", 11048, "10.1.1.1:11048")
41 addNaTest("10.2.2.2", 8335, "10.2.2.2:8335")
42 addNaTest("10.10.10.10", 8336, "10.10.10.10:8336")
43 // Class B
44 addNaTest("128.0.0.1", 11047, "128.0.0.1:11047")
45 addNaTest("129.1.1.1", 11048, "129.1.1.1:11048")
46 addNaTest("180.2.2.2", 8335, "180.2.2.2:8335")
47 addNaTest("191.10.10.10", 8336, "191.10.10.10:8336")
48 // Private Class B
49 addNaTest("172.16.0.1", 11047, "172.16.0.1:11047")
50 addNaTest("172.16.1.1", 11048, "172.16.1.1:11048")
51 addNaTest("172.16.2.2", 8335, "172.16.2.2:8335")
52 addNaTest("172.16.172.172", 8336, "172.16.172.172:8336")
53 // Class C
54 addNaTest("193.0.0.1", 11047, "193.0.0.1:11047")
55 addNaTest("200.1.1.1", 11048, "200.1.1.1:11048")
56 addNaTest("205.2.2.2", 8335, "205.2.2.2:8335")
57 addNaTest("223.10.10.10", 8336, "223.10.10.10:8336")
58 // Private Class C
59 addNaTest("192.168.0.1", 11047, "192.168.0.1:11047")
60 addNaTest("192.168.1.1", 11048, "192.168.1.1:11048")
61 addNaTest("192.168.2.2", 8335, "192.168.2.2:8335")
62 addNaTest("192.168.192.192", 8336, "192.168.192.192:8336")
63 // IPv6
64 // Localhost
65 addNaTest("::1", 11047, "[::1]:11047")
66 addNaTest("fe80::1", 11048, "[fe80::1]:11048")
67 // Link-local
68 addNaTest("fe80::1:1", 11047, "[fe80::1:1]:11047")
69 addNaTest("fe91::2:2", 11048, "[fe91::2:2]:11048")
70 addNaTest("fea2::3:3", 8335, "[fea2::3:3]:8335")
71 addNaTest("feb3::4:4", 8336, "[feb3::4:4]:8336")
72 // Site-local
73 addNaTest("fec0::1:1", 11047, "[fec0::1:1]:11047")
74 addNaTest("fed1::2:2", 11048, "[fed1::2:2]:11048")
75 addNaTest("fee2::3:3", 8335, "[fee2::3:3]:8335")
76 addNaTest("fef3::4:4", 8336, "[fef3::4:4]:8336")
77 }
78 func addNaTest(ip string, port uint16, want string) {
79 nip := net.ParseIP(ip)
80 na := *wire.NewNetAddressIPPort(nip, port, wire.SFNodeNetwork)
81 test := naTest{na, want}
82 naTests = append(naTests, test)
83 }
84 func lookupFunc(host string) ([]net.IP, error) {
85 return nil, errors.New("not implemented")
86 }
87 func TestStartStop(t *testing.T) {
88 n := addrmgr.New("teststartstop", lookupFunc)
89 n.Start()
90 e := n.Stop()
91 if e != nil {
92 t.Fatalf("Address Manager failed to stop: %v", e)
93 }
94 }
95 func TestAddAddressByIP(t *testing.T) {
96 fmtErr := fmt.Errorf("")
97 addrErr := &net.AddrError{}
98 var tests = []struct {
99 addrIP string
100 err error
101 }{
102 {
103 someIP + ":11047", nil,
104 },
105 {
106 someIP,
107 addrErr,
108 },
109 {
110 someIP[:12] + ":11047",
111 fmtErr,
112 },
113 {
114 someIP + ":abcd",
115 fmtErr,
116 },
117 }
118 amgr := addrmgr.New("testaddressbyip", nil)
119 for i, test := range tests {
120 e := amgr.AddAddressByIP(test.addrIP)
121 if test.err != nil && e == nil {
122 t.Errorf("TestGood test %d failed expected an error and got none", i)
123 continue
124 }
125 if test.err == nil && e != nil {
126 t.Errorf("TestGood test %d failed expected no error and got one", i)
127 continue
128 }
129 if reflect.TypeOf(e) != reflect.TypeOf(test.err) {
130 t.Errorf("TestGood test %d failed got %v, want %v", i,
131 reflect.TypeOf(e), reflect.TypeOf(test.err),
132 )
133 continue
134 }
135 }
136 }
137 func TestAddLocalAddress(t *testing.T) {
138 var tests = []struct {
139 address wire.NetAddress
140 priority addrmgr.AddressPriority
141 valid bool
142 }{
143 {
144 wire.NetAddress{IP: net.ParseIP("192.168.0.100")},
145 addrmgr.InterfacePrio,
146 false,
147 },
148 {
149 wire.NetAddress{IP: net.ParseIP("204.124.1.1")},
150 addrmgr.InterfacePrio,
151 true,
152 },
153 {
154 wire.NetAddress{IP: net.ParseIP("204.124.1.1")},
155 addrmgr.BoundPrio,
156 true,
157 },
158 {
159 wire.NetAddress{IP: net.ParseIP("::1")},
160 addrmgr.InterfacePrio,
161 false,
162 },
163 {
164 wire.NetAddress{IP: net.ParseIP("fe80::1")},
165 addrmgr.InterfacePrio,
166 false,
167 },
168 {
169 wire.NetAddress{IP: net.ParseIP("2620:100::1")},
170 addrmgr.InterfacePrio,
171 true,
172 },
173 }
174 amgr := addrmgr.New("testaddlocaladdress", nil)
175 for x, test := range tests {
176 result := amgr.AddLocalAddress(&test.address, test.priority)
177 if result == nil && !test.valid {
178 t.Errorf("TestAddLocalAddress test #%d failed: %s should have been accepted", x, test.address.IP)
179 continue
180 }
181 if result != nil && test.valid {
182 t.Errorf("TestAddLocalAddress test #%d failed: %s should not have been accepted", x, test.address.IP)
183 continue
184 }
185 }
186 }
187 func TestAttempt(t *testing.T) {
188 n := addrmgr.New("testattempt", lookupFunc)
189 // Add a new address and get it
190 e := n.AddAddressByIP(someIP + ":11047")
191 if e != nil {
192 t.Fatalf("Adding address failed: %v", e)
193 }
194 ka := n.GetAddress()
195 if !ka.LastAttempt().IsZero() {
196 t.Errorf("Address should not have attempts, but does")
197 }
198 na := ka.NetAddress()
199 n.Attempt(na)
200 if ka.LastAttempt().IsZero() {
201 t.Errorf("Address should have an attempt, but does not")
202 }
203 }
204 func TestConnected(t *testing.T) {
205 n := addrmgr.New("testconnected", lookupFunc)
206 // Add a new address and get it
207 e := n.AddAddressByIP(someIP + ":11047")
208 if e != nil {
209 t.Fatalf("Adding address failed: %v", e)
210 }
211 ka := n.GetAddress()
212 na := ka.NetAddress()
213 // make it an hour ago
214 na.Timestamp = time.Unix(time.Now().Add(time.Hour*-1).Unix(), 0)
215 n.Connected(na)
216 if !ka.NetAddress().Timestamp.After(na.Timestamp) {
217 t.Errorf("Address should have a new timestamp, but does not")
218 }
219 }
220 func TestNeedMoreAddresses(t *testing.T) {
221 n := addrmgr.New("testneedmoreaddresses", lookupFunc)
222 addrsToAdd := 1500
223 b := n.NeedMoreAddresses()
224 if !b {
225 t.Errorf("Expected that we need more addresses")
226 }
227 addrs := make([]*wire.NetAddress, addrsToAdd)
228 var e error
229 for i := 0; i < addrsToAdd; i++ {
230 s := fmt.Sprintf("%d.%d.173.147:11047", i/128+60, i%128+60)
231 addrs[i], e = n.DeserializeNetAddress(s)
232 if e != nil {
233 t.Errorf("Failed to turn %s into an address: %v", s, e)
234 }
235 }
236 srcAddr := wire.NewNetAddressIPPort(net.IPv4(173, 144, 173, 111), 11047, 0)
237 n.AddAddresses(addrs, srcAddr)
238 numAddrs := n.NumAddresses()
239 if numAddrs > addrsToAdd {
240 t.Errorf("Number of addresses is too many %d vs %d", numAddrs, addrsToAdd)
241 }
242 b = n.NeedMoreAddresses()
243 if b {
244 t.Errorf("Expected that we don't need more addresses")
245 }
246 }
247 func TestGood(t *testing.T) {
248 n := addrmgr.New("testgood", lookupFunc)
249 addrsToAdd := 64 * 64
250 addrs := make([]*wire.NetAddress, addrsToAdd)
251 var e error
252 for i := 0; i < addrsToAdd; i++ {
253 s := fmt.Sprintf("%d.173.147.%d:11047", i/64+60, i%64+60)
254 addrs[i], e = n.DeserializeNetAddress(s)
255 if e != nil {
256 t.Errorf("Failed to turn %s into an address: %v", s, e)
257 }
258 }
259 srcAddr := wire.NewNetAddressIPPort(net.IPv4(173, 144, 173, 111), 11047, 0)
260 n.AddAddresses(addrs, srcAddr)
261 for _, addr := range addrs {
262 n.Good(addr)
263 }
264 numAddrs := n.NumAddresses()
265 if numAddrs >= addrsToAdd {
266 t.Errorf("Number of addresses is too many: %d vs %d", numAddrs, addrsToAdd)
267 }
268 numCache := len(n.AddressCache())
269 if numCache >= numAddrs/4 {
270 t.Errorf("Number of addresses in cache: got %d, want %d", numCache, numAddrs/4)
271 }
272 }
273 func TestGetAddress(t *testing.T) {
274 n := addrmgr.New("testgetaddress", lookupFunc)
275 // Get an address from an empty set (should error)
276 if rv := n.GetAddress(); rv != nil {
277 t.Errorf("GetAddress failed: got: %v want: %v\n", rv, nil)
278 }
279 // Add a new address and get it
280 e := n.AddAddressByIP(someIP + ":11047")
281 if e != nil {
282 t.Fatalf("Adding address failed: %v", e)
283 }
284 ka := n.GetAddress()
285 if ka == nil {
286 t.Fatalf("Did not get an address where there is one in the pool")
287 }
288 if ka.NetAddress().IP.String() != someIP {
289 t.Errorf("Wrong IP: got %v, want %v", ka.NetAddress().IP.String(), someIP)
290 }
291 // Mark this as a good address and get it
292 n.Good(ka.NetAddress())
293 ka = n.GetAddress()
294 if ka == nil {
295 t.Fatalf("Did not get an address where there is one in the pool")
296 }
297 if ka.NetAddress().IP.String() != someIP {
298 t.Errorf("Wrong IP: got %v, want %v", ka.NetAddress().IP.String(), someIP)
299 }
300 numAddrs := n.NumAddresses()
301 if numAddrs != 1 {
302 t.Errorf("Wrong number of addresses: got %d, want %d", numAddrs, 1)
303 }
304 }
305 func TestGetBestLocalAddress(t *testing.T) {
306 localAddrs := []wire.NetAddress{
307 {IP: net.ParseIP("192.168.0.100")},
308 {IP: net.ParseIP("::1")},
309 {IP: net.ParseIP("fe80::1")},
310 {IP: net.ParseIP("2001:470::1")},
311 }
312 var tests = []struct {
313 remoteAddr wire.NetAddress
314 want0 wire.NetAddress
315 want1 wire.NetAddress
316 want2 wire.NetAddress
317 want3 wire.NetAddress
318 }{
319 {
320 // Remote connection from public IPv4
321 wire.NetAddress{IP: net.ParseIP("204.124.8.1")},
322 wire.NetAddress{IP: net.IPv4zero},
323 wire.NetAddress{IP: net.IPv4zero},
324 wire.NetAddress{IP: net.ParseIP("204.124.8.100")},
325 wire.NetAddress{IP: net.ParseIP("fd87:d87e:eb43:25::1")},
326 },
327 {
328 // Remote connection from private IPv4
329 wire.NetAddress{IP: net.ParseIP("172.16.0.254")},
330 wire.NetAddress{IP: net.IPv4zero},
331 wire.NetAddress{IP: net.IPv4zero},
332 wire.NetAddress{IP: net.IPv4zero},
333 wire.NetAddress{IP: net.IPv4zero},
334 },
335 {
336 // Remote connection from public IPv6
337 wire.NetAddress{IP: net.ParseIP("2602:100:abcd::102")},
338 wire.NetAddress{IP: net.IPv6zero},
339 wire.NetAddress{IP: net.ParseIP("2001:470::1")},
340 wire.NetAddress{IP: net.ParseIP("2001:470::1")},
341 wire.NetAddress{IP: net.ParseIP("2001:470::1")},
342 },
343 /* XXX
344 {
345 // Remote connection from Tor
346 wire.NetAddress{IP: net.ParseIP("fd87:d87e:eb43::100")},
347 wire.NetAddress{IP: net.IPv4zero},
348 wire.NetAddress{IP: net.ParseIP("204.124.8.100")},
349 wire.NetAddress{IP: net.ParseIP("fd87:d87e:eb43:25::1")},
350 },
351 */
352 }
353 amgr := addrmgr.New("testgetbestlocaladdress", nil)
354 // Test against default when there's no address
355 for x, test := range tests {
356 got := amgr.GetBestLocalAddress(&test.remoteAddr)
357 if !test.want0.IP.Equal(got.IP) {
358 t.Errorf("TestGetBestLocalAddress test1 #%d failed for remote address %s: want %s got %s",
359 x, test.remoteAddr.IP, test.want1.IP, got.IP,
360 )
361 continue
362 }
363 }
364 var e error
365 for _, localAddr := range localAddrs {
366 e = amgr.AddLocalAddress(&localAddr, addrmgr.InterfacePrio)
367 if e != nil {
368 t.Log(e)
369 }
370 }
371 // Test against want1
372 for x, test := range tests {
373 got := amgr.GetBestLocalAddress(&test.remoteAddr)
374 if !test.want1.IP.Equal(got.IP) {
375 t.Errorf("TestGetBestLocalAddress test1 #%d failed for remote address %s: want %s got %s",
376 x, test.remoteAddr.IP, test.want1.IP, got.IP,
377 )
378 continue
379 }
380 }
381 // Add a public IP to the list of local addresses.
382 localAddr := wire.NetAddress{IP: net.ParseIP("204.124.8.100")}
383 e = amgr.AddLocalAddress(&localAddr, addrmgr.InterfacePrio)
384 if e != nil {
385 t.Log(e)
386 }
387 // Test against want2
388 for x, test := range tests {
389 got := amgr.GetBestLocalAddress(&test.remoteAddr)
390 if !test.want2.IP.Equal(got.IP) {
391 t.Errorf("TestGetBestLocalAddress test2 #%d failed for remote address %s: want %s got %s",
392 x, test.remoteAddr.IP, test.want2.IP, got.IP,
393 )
394 continue
395 }
396 }
397 /*
398 // Add a Tor generated IP address
399 localAddr = wire.NetAddress{IP: net.ParseIP("fd87:d87e:eb43:25::1")}
400 amgr.AddLocalAddress(&localAddr, addrmgr.ManualPrio)
401 // Test against want3
402
403 for x, test := range tests {
404
405 got := amgr.GetBestLocalAddress(&test.remoteAddr)
406
407 if !test.want3.IP.Equal(got.IP) {
408
409
410 t.Errorf("TestGetBestLocalAddress test3 #%d failed for remote address %s: want %s got %s",
411 x, test.remoteAddr.IP, test.want3.IP, got.IP)
412 continue
413 }
414 }
415 */
416 }
417 func TestNetAddressKey(t *testing.T) {
418 addNaTests()
419 t.Logf("Running %d tests", len(naTests))
420 for i, test := range naTests {
421 key := addrmgr.NetAddressKey(&test.in)
422 if key != test.want {
423 t.Errorf("NetAddressKey #%d\n got: %s want: %s", i, key, test.want)
424 continue
425 }
426 }
427 }
428