github.com/psiphon-labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/common/subnet_test.go (about)

     1  /*
     2   * Copyright (c) 2016, Psiphon Inc.
     3   * All rights reserved.
     4   *
     5   * This program is free software: you can redistribute it and/or modify
     6   * it under the terms of the GNU General Public License as published by
     7   * the Free Software Foundation, either version 3 of the License, or
     8   * (at your option) any later version.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package common
    21  
    22  import (
    23  	"encoding/binary"
    24  	"io/ioutil"
    25  	"math/rand"
    26  	"net"
    27  	"testing"
    28  )
    29  
    30  func TestSubnetLookup(t *testing.T) {
    31  	CIDRs := []string{
    32  		"192.168.0.0/16",
    33  		"10.0.0.0/8",
    34  		"172.16.0.0/12",
    35  		"100.64.0.0/10"}
    36  
    37  	routes := []byte("192.168.0.0\t255.255.0.0\n10.0.0.0\t255.0.0.0\n" +
    38  		"172.16.0.0\t255.240.0.0\n100.64.0.0\t255.192.0.0\n")
    39  
    40  	var subnetLookup SubnetLookup
    41  
    42  	t.Run("new subnet lookup", func(t *testing.T) {
    43  
    44  		var err error
    45  		subnetLookup, err = NewSubnetLookup(CIDRs)
    46  		if err != nil {
    47  			t.Fatalf("NewSubnetLookup failed: %s", err)
    48  		}
    49  	})
    50  
    51  	var subnetLookupRoutes SubnetLookup
    52  
    53  	t.Run("new subnet lookup (routes case)", func(t *testing.T) {
    54  
    55  		var err error
    56  		subnetLookupRoutes, err = NewSubnetLookupFromRoutes(routes)
    57  		if err != nil {
    58  			t.Fatalf("NewSubnetLookupFromRoutes failed: %s", err)
    59  		}
    60  	})
    61  
    62  	if subnetLookup == nil || subnetLookupRoutes == nil {
    63  		t.Fatalf("new subnet list failed")
    64  	}
    65  
    66  	testCases := []struct {
    67  		description    string
    68  		ipAddress      net.IP
    69  		expectedResult bool
    70  	}{
    71  		{"IP address in subnet", net.ParseIP("172.17.3.2"), true},
    72  		{"IP address not in subnet", net.ParseIP("169.254.1.1"), false},
    73  		{"IP address not in subnet (prefix case)", net.ParseIP("172.15.3.2"), false},
    74  	}
    75  
    76  	for _, testCase := range testCases {
    77  		t.Run(testCase.description, func(t *testing.T) {
    78  
    79  			result := subnetLookup.ContainsIPAddress(testCase.ipAddress)
    80  			if result != testCase.expectedResult {
    81  				t.Fatalf(
    82  					"ContainsIPAddress returned %+v expected %+v",
    83  					result, testCase.expectedResult)
    84  			}
    85  
    86  			result = subnetLookupRoutes.ContainsIPAddress(testCase.ipAddress)
    87  			if result != testCase.expectedResult {
    88  				t.Fatalf(
    89  					"ContainsIPAddress (routes case) returned %+v expected %+v",
    90  					result, testCase.expectedResult)
    91  			}
    92  		})
    93  	}
    94  }
    95  
    96  func BenchmarkSubnetLookup(b *testing.B) {
    97  
    98  	var subnetLookup SubnetLookup
    99  
   100  	b.Run("load routes file", func(b *testing.B) {
   101  
   102  		routesData, err := ioutil.ReadFile("test_routes.dat")
   103  		if err != nil {
   104  			b.Skipf("can't load test routes file: %s", err)
   105  		}
   106  
   107  		for n := 0; n < b.N; n++ {
   108  			subnetLookup, err = NewSubnetLookupFromRoutes(routesData)
   109  			if err != nil {
   110  				b.Fatalf("NewSubnetLookup failed: %s", err)
   111  			}
   112  		}
   113  	})
   114  
   115  	if subnetLookup == nil {
   116  		b.Skipf("no test routes file")
   117  	}
   118  
   119  	b.Run("lookup random IP address", func(b *testing.B) {
   120  		for n := 0; n < b.N; n++ {
   121  			ip := make([]byte, 4)
   122  			binary.BigEndian.PutUint32(ip, rand.Uint32())
   123  			_ = subnetLookup.ContainsIPAddress(net.IP(ip))
   124  		}
   125  	})
   126  }