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  }