github.com/tailscale/wireguard-go@v0.0.20201119-0.20210522003738-46b531feb08a/device/allowedips_test.go (about) 1 /* SPDX-License-Identifier: MIT 2 * 3 * Copyright (C) 2017-2021 WireGuard LLC. All Rights Reserved. 4 */ 5 6 package device 7 8 import ( 9 "math/rand" 10 "net" 11 "testing" 12 ) 13 14 /* Todo: More comprehensive 15 */ 16 17 type testPairCommonBits struct { 18 s1 []byte 19 s2 []byte 20 match uint 21 } 22 23 func TestCommonBits(t *testing.T) { 24 25 tests := []testPairCommonBits{ 26 {s1: []byte{1, 4, 53, 128}, s2: []byte{0, 0, 0, 0}, match: 7}, 27 {s1: []byte{0, 4, 53, 128}, s2: []byte{0, 0, 0, 0}, match: 13}, 28 {s1: []byte{0, 4, 53, 253}, s2: []byte{0, 4, 53, 252}, match: 31}, 29 {s1: []byte{192, 168, 1, 1}, s2: []byte{192, 169, 1, 1}, match: 15}, 30 {s1: []byte{65, 168, 1, 1}, s2: []byte{192, 169, 1, 1}, match: 0}, 31 } 32 33 for _, p := range tests { 34 v := commonBits(p.s1, p.s2) 35 if v != p.match { 36 t.Error( 37 "For slice", p.s1, p.s2, 38 "expected match", p.match, 39 ",but got", v, 40 ) 41 } 42 } 43 } 44 45 func benchmarkTrie(peerNumber int, addressNumber int, addressLength int, b *testing.B) { 46 var trie *trieEntry 47 var peers []*Peer 48 49 rand.Seed(1) 50 51 const AddressLength = 4 52 53 for n := 0; n < peerNumber; n++ { 54 peers = append(peers, &Peer{}) 55 } 56 57 for n := 0; n < addressNumber; n++ { 58 var addr [AddressLength]byte 59 rand.Read(addr[:]) 60 cidr := uint(rand.Uint32() % (AddressLength * 8)) 61 index := rand.Int() % peerNumber 62 trie = trie.insert(addr[:], cidr, peers[index]) 63 } 64 65 for n := 0; n < b.N; n++ { 66 var addr [AddressLength]byte 67 rand.Read(addr[:]) 68 trie.lookup(addr[:]) 69 } 70 } 71 72 func BenchmarkTrieIPv4Peers100Addresses1000(b *testing.B) { 73 benchmarkTrie(100, 1000, net.IPv4len, b) 74 } 75 76 func BenchmarkTrieIPv4Peers10Addresses10(b *testing.B) { 77 benchmarkTrie(10, 10, net.IPv4len, b) 78 } 79 80 func BenchmarkTrieIPv6Peers100Addresses1000(b *testing.B) { 81 benchmarkTrie(100, 1000, net.IPv6len, b) 82 } 83 84 func BenchmarkTrieIPv6Peers10Addresses10(b *testing.B) { 85 benchmarkTrie(10, 10, net.IPv6len, b) 86 } 87 88 /* Test ported from kernel implementation: 89 * selftest/allowedips.h 90 */ 91 func TestTrieIPv4(t *testing.T) { 92 a := &Peer{} 93 b := &Peer{} 94 c := &Peer{} 95 d := &Peer{} 96 e := &Peer{} 97 g := &Peer{} 98 h := &Peer{} 99 100 var trie *trieEntry 101 102 insert := func(peer *Peer, a, b, c, d byte, cidr uint) { 103 trie = trie.insert([]byte{a, b, c, d}, cidr, peer) 104 } 105 106 assertEQ := func(peer *Peer, a, b, c, d byte) { 107 p := trie.lookup([]byte{a, b, c, d}) 108 if p != peer { 109 t.Error("Assert EQ failed") 110 } 111 } 112 113 assertNEQ := func(peer *Peer, a, b, c, d byte) { 114 p := trie.lookup([]byte{a, b, c, d}) 115 if p == peer { 116 t.Error("Assert NEQ failed") 117 } 118 } 119 120 insert(a, 192, 168, 4, 0, 24) 121 insert(b, 192, 168, 4, 4, 32) 122 insert(c, 192, 168, 0, 0, 16) 123 insert(d, 192, 95, 5, 64, 27) 124 insert(c, 192, 95, 5, 65, 27) 125 insert(e, 0, 0, 0, 0, 0) 126 insert(g, 64, 15, 112, 0, 20) 127 insert(h, 64, 15, 123, 211, 25) 128 insert(a, 10, 0, 0, 0, 25) 129 insert(b, 10, 0, 0, 128, 25) 130 insert(a, 10, 1, 0, 0, 30) 131 insert(b, 10, 1, 0, 4, 30) 132 insert(c, 10, 1, 0, 8, 29) 133 insert(d, 10, 1, 0, 16, 29) 134 135 assertEQ(a, 192, 168, 4, 20) 136 assertEQ(a, 192, 168, 4, 0) 137 assertEQ(b, 192, 168, 4, 4) 138 assertEQ(c, 192, 168, 200, 182) 139 assertEQ(c, 192, 95, 5, 68) 140 assertEQ(e, 192, 95, 5, 96) 141 assertEQ(g, 64, 15, 116, 26) 142 assertEQ(g, 64, 15, 127, 3) 143 144 insert(a, 1, 0, 0, 0, 32) 145 insert(a, 64, 0, 0, 0, 32) 146 insert(a, 128, 0, 0, 0, 32) 147 insert(a, 192, 0, 0, 0, 32) 148 insert(a, 255, 0, 0, 0, 32) 149 150 assertEQ(a, 1, 0, 0, 0) 151 assertEQ(a, 64, 0, 0, 0) 152 assertEQ(a, 128, 0, 0, 0) 153 assertEQ(a, 192, 0, 0, 0) 154 assertEQ(a, 255, 0, 0, 0) 155 156 trie = trie.removeByPeer(a) 157 158 assertNEQ(a, 1, 0, 0, 0) 159 assertNEQ(a, 64, 0, 0, 0) 160 assertNEQ(a, 128, 0, 0, 0) 161 assertNEQ(a, 192, 0, 0, 0) 162 assertNEQ(a, 255, 0, 0, 0) 163 164 trie = nil 165 166 insert(a, 192, 168, 0, 0, 16) 167 insert(a, 192, 168, 0, 0, 24) 168 169 trie = trie.removeByPeer(a) 170 171 assertNEQ(a, 192, 168, 0, 1) 172 } 173 174 /* Test ported from kernel implementation: 175 * selftest/allowedips.h 176 */ 177 func TestTrieIPv6(t *testing.T) { 178 a := &Peer{} 179 b := &Peer{} 180 c := &Peer{} 181 d := &Peer{} 182 e := &Peer{} 183 f := &Peer{} 184 g := &Peer{} 185 h := &Peer{} 186 187 var trie *trieEntry 188 189 expand := func(a uint32) []byte { 190 var out [4]byte 191 out[0] = byte(a >> 24 & 0xff) 192 out[1] = byte(a >> 16 & 0xff) 193 out[2] = byte(a >> 8 & 0xff) 194 out[3] = byte(a & 0xff) 195 return out[:] 196 } 197 198 insert := func(peer *Peer, a, b, c, d uint32, cidr uint) { 199 var addr []byte 200 addr = append(addr, expand(a)...) 201 addr = append(addr, expand(b)...) 202 addr = append(addr, expand(c)...) 203 addr = append(addr, expand(d)...) 204 trie = trie.insert(addr, cidr, peer) 205 } 206 207 assertEQ := func(peer *Peer, a, b, c, d uint32) { 208 var addr []byte 209 addr = append(addr, expand(a)...) 210 addr = append(addr, expand(b)...) 211 addr = append(addr, expand(c)...) 212 addr = append(addr, expand(d)...) 213 p := trie.lookup(addr) 214 if p != peer { 215 t.Error("Assert EQ failed") 216 } 217 } 218 219 insert(d, 0x26075300, 0x60006b00, 0, 0xc05f0543, 128) 220 insert(c, 0x26075300, 0x60006b00, 0, 0, 64) 221 insert(e, 0, 0, 0, 0, 0) 222 insert(f, 0, 0, 0, 0, 0) 223 insert(g, 0x24046800, 0, 0, 0, 32) 224 insert(h, 0x24046800, 0x40040800, 0xdeadbeef, 0xdeadbeef, 64) 225 insert(a, 0x24046800, 0x40040800, 0xdeadbeef, 0xdeadbeef, 128) 226 insert(c, 0x24446800, 0x40e40800, 0xdeaebeef, 0xdefbeef, 128) 227 insert(b, 0x24446800, 0xf0e40800, 0xeeaebeef, 0, 98) 228 229 assertEQ(d, 0x26075300, 0x60006b00, 0, 0xc05f0543) 230 assertEQ(c, 0x26075300, 0x60006b00, 0, 0xc02e01ee) 231 assertEQ(f, 0x26075300, 0x60006b01, 0, 0) 232 assertEQ(g, 0x24046800, 0x40040806, 0, 0x1006) 233 assertEQ(g, 0x24046800, 0x40040806, 0x1234, 0x5678) 234 assertEQ(f, 0x240467ff, 0x40040806, 0x1234, 0x5678) 235 assertEQ(f, 0x24046801, 0x40040806, 0x1234, 0x5678) 236 assertEQ(h, 0x24046800, 0x40040800, 0x1234, 0x5678) 237 assertEQ(h, 0x24046800, 0x40040800, 0, 0) 238 assertEQ(h, 0x24046800, 0x40040800, 0x10101010, 0x10101010) 239 assertEQ(a, 0x24046800, 0x40040800, 0xdeadbeef, 0xdeadbeef) 240 }