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 }