github.com/anthdm/go-ethereum@v1.8.4-0.20180412101906-60516c83b011/p2p/netutil/net_test.go (about)

     1  // Copyright 2016 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package netutil
    18  
    19  import (
    20  	"fmt"
    21  	"net"
    22  	"reflect"
    23  	"testing"
    24  	"testing/quick"
    25  
    26  	"github.com/davecgh/go-spew/spew"
    27  )
    28  
    29  func TestParseNetlist(t *testing.T) {
    30  	var tests = []struct {
    31  		input    string
    32  		wantErr  error
    33  		wantList *Netlist
    34  	}{
    35  		{
    36  			input:    "",
    37  			wantList: &Netlist{},
    38  		},
    39  		{
    40  			input:    "127.0.0.0/8",
    41  			wantErr:  nil,
    42  			wantList: &Netlist{{IP: net.IP{127, 0, 0, 0}, Mask: net.CIDRMask(8, 32)}},
    43  		},
    44  		{
    45  			input:   "127.0.0.0/44",
    46  			wantErr: &net.ParseError{Type: "CIDR address", Text: "127.0.0.0/44"},
    47  		},
    48  		{
    49  			input: "127.0.0.0/16, 23.23.23.23/24,",
    50  			wantList: &Netlist{
    51  				{IP: net.IP{127, 0, 0, 0}, Mask: net.CIDRMask(16, 32)},
    52  				{IP: net.IP{23, 23, 23, 0}, Mask: net.CIDRMask(24, 32)},
    53  			},
    54  		},
    55  	}
    56  
    57  	for _, test := range tests {
    58  		l, err := ParseNetlist(test.input)
    59  		if !reflect.DeepEqual(err, test.wantErr) {
    60  			t.Errorf("%q: got error %q, want %q", test.input, err, test.wantErr)
    61  			continue
    62  		}
    63  		if !reflect.DeepEqual(l, test.wantList) {
    64  			spew.Dump(l)
    65  			spew.Dump(test.wantList)
    66  			t.Errorf("%q: got %v, want %v", test.input, l, test.wantList)
    67  		}
    68  	}
    69  }
    70  
    71  func TestNilNetListContains(t *testing.T) {
    72  	var list *Netlist
    73  	checkContains(t, list.Contains, nil, []string{"1.2.3.4"})
    74  }
    75  
    76  func TestIsLAN(t *testing.T) {
    77  	checkContains(t, IsLAN,
    78  		[]string{ // included
    79  			"0.0.0.0",
    80  			"0.2.0.8",
    81  			"127.0.0.1",
    82  			"10.0.1.1",
    83  			"10.22.0.3",
    84  			"172.31.252.251",
    85  			"192.168.1.4",
    86  			"fe80::f4a1:8eff:fec5:9d9d",
    87  			"febf::ab32:2233",
    88  			"fc00::4",
    89  		},
    90  		[]string{ // excluded
    91  			"192.0.2.1",
    92  			"1.0.0.0",
    93  			"172.32.0.1",
    94  			"fec0::2233",
    95  		},
    96  	)
    97  }
    98  
    99  func TestIsSpecialNetwork(t *testing.T) {
   100  	checkContains(t, IsSpecialNetwork,
   101  		[]string{ // included
   102  			"192.0.2.1",
   103  			"192.0.2.44",
   104  			"2001:db8:85a3:8d3:1319:8a2e:370:7348",
   105  			"255.255.255.255",
   106  			"224.0.0.22", // IPv4 multicast
   107  			"ff05::1:3",  // IPv6 multicast
   108  		},
   109  		[]string{ // excluded
   110  			"192.0.3.1",
   111  			"1.0.0.0",
   112  			"172.32.0.1",
   113  			"fec0::2233",
   114  		},
   115  	)
   116  }
   117  
   118  func checkContains(t *testing.T, fn func(net.IP) bool, inc, exc []string) {
   119  	for _, s := range inc {
   120  		if !fn(parseIP(s)) {
   121  			t.Error("returned false for included address", s)
   122  		}
   123  	}
   124  	for _, s := range exc {
   125  		if fn(parseIP(s)) {
   126  			t.Error("returned true for excluded address", s)
   127  		}
   128  	}
   129  }
   130  
   131  func parseIP(s string) net.IP {
   132  	ip := net.ParseIP(s)
   133  	if ip == nil {
   134  		panic("invalid " + s)
   135  	}
   136  	return ip
   137  }
   138  
   139  func TestCheckRelayIP(t *testing.T) {
   140  	tests := []struct {
   141  		sender, addr string
   142  		want         error
   143  	}{
   144  		{"127.0.0.1", "0.0.0.0", errUnspecified},
   145  		{"192.168.0.1", "0.0.0.0", errUnspecified},
   146  		{"23.55.1.242", "0.0.0.0", errUnspecified},
   147  		{"127.0.0.1", "255.255.255.255", errSpecial},
   148  		{"192.168.0.1", "255.255.255.255", errSpecial},
   149  		{"23.55.1.242", "255.255.255.255", errSpecial},
   150  		{"192.168.0.1", "127.0.2.19", errLoopback},
   151  		{"23.55.1.242", "192.168.0.1", errLAN},
   152  
   153  		{"127.0.0.1", "127.0.2.19", nil},
   154  		{"127.0.0.1", "192.168.0.1", nil},
   155  		{"127.0.0.1", "23.55.1.242", nil},
   156  		{"192.168.0.1", "192.168.0.1", nil},
   157  		{"192.168.0.1", "23.55.1.242", nil},
   158  		{"23.55.1.242", "23.55.1.242", nil},
   159  	}
   160  
   161  	for _, test := range tests {
   162  		err := CheckRelayIP(parseIP(test.sender), parseIP(test.addr))
   163  		if err != test.want {
   164  			t.Errorf("%s from %s: got %q, want %q", test.addr, test.sender, err, test.want)
   165  		}
   166  	}
   167  }
   168  
   169  func BenchmarkCheckRelayIP(b *testing.B) {
   170  	sender := parseIP("23.55.1.242")
   171  	addr := parseIP("23.55.1.2")
   172  	for i := 0; i < b.N; i++ {
   173  		CheckRelayIP(sender, addr)
   174  	}
   175  }
   176  
   177  func TestSameNet(t *testing.T) {
   178  	tests := []struct {
   179  		ip, other string
   180  		bits      uint
   181  		want      bool
   182  	}{
   183  		{"0.0.0.0", "0.0.0.0", 32, true},
   184  		{"0.0.0.0", "0.0.0.1", 0, true},
   185  		{"0.0.0.0", "0.0.0.1", 31, true},
   186  		{"0.0.0.0", "0.0.0.1", 32, false},
   187  		{"0.33.0.1", "0.34.0.2", 8, true},
   188  		{"0.33.0.1", "0.34.0.2", 13, true},
   189  		{"0.33.0.1", "0.34.0.2", 15, false},
   190  	}
   191  
   192  	for _, test := range tests {
   193  		if ok := SameNet(test.bits, parseIP(test.ip), parseIP(test.other)); ok != test.want {
   194  			t.Errorf("SameNet(%d, %s, %s) == %t, want %t", test.bits, test.ip, test.other, ok, test.want)
   195  		}
   196  	}
   197  }
   198  
   199  func ExampleSameNet() {
   200  	// This returns true because the IPs are in the same /24 network:
   201  	fmt.Println(SameNet(24, net.IP{127, 0, 0, 1}, net.IP{127, 0, 0, 3}))
   202  	// This call returns false:
   203  	fmt.Println(SameNet(24, net.IP{127, 3, 0, 1}, net.IP{127, 5, 0, 3}))
   204  	// Output:
   205  	// true
   206  	// false
   207  }
   208  
   209  func TestDistinctNetSet(t *testing.T) {
   210  	ops := []struct {
   211  		add, remove string
   212  		fails       bool
   213  	}{
   214  		{add: "127.0.0.1"},
   215  		{add: "127.0.0.2"},
   216  		{add: "127.0.0.3", fails: true},
   217  		{add: "127.32.0.1"},
   218  		{add: "127.32.0.2"},
   219  		{add: "127.32.0.3", fails: true},
   220  		{add: "127.33.0.1", fails: true},
   221  		{add: "127.34.0.1"},
   222  		{add: "127.34.0.2"},
   223  		{add: "127.34.0.3", fails: true},
   224  		// Make room for an address, then add again.
   225  		{remove: "127.0.0.1"},
   226  		{add: "127.0.0.3"},
   227  		{add: "127.0.0.3", fails: true},
   228  	}
   229  
   230  	set := DistinctNetSet{Subnet: 15, Limit: 2}
   231  	for _, op := range ops {
   232  		var desc string
   233  		if op.add != "" {
   234  			desc = fmt.Sprintf("Add(%s)", op.add)
   235  			if ok := set.Add(parseIP(op.add)); ok != !op.fails {
   236  				t.Errorf("%s == %t, want %t", desc, ok, !op.fails)
   237  			}
   238  		} else {
   239  			desc = fmt.Sprintf("Remove(%s)", op.remove)
   240  			set.Remove(parseIP(op.remove))
   241  		}
   242  		t.Logf("%s: %v", desc, set)
   243  	}
   244  }
   245  
   246  func TestDistinctNetSetAddRemove(t *testing.T) {
   247  	cfg := &quick.Config{}
   248  	fn := func(ips []net.IP) bool {
   249  		s := DistinctNetSet{Limit: 3, Subnet: 2}
   250  		for _, ip := range ips {
   251  			s.Add(ip)
   252  		}
   253  		for _, ip := range ips {
   254  			s.Remove(ip)
   255  		}
   256  		return s.Len() == 0
   257  	}
   258  
   259  	if err := quick.Check(fn, cfg); err != nil {
   260  		t.Fatal(err)
   261  	}
   262  }