github.com/palcoin-project/palcd@v1.0.0/addrmgr/addrmanager_test.go (about)

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