2018-05-03 13:04:00 +00:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0
|
|
|
|
*
|
|
|
|
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
|
|
|
*/
|
|
|
|
|
2017-06-02 15:58:46 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"math/rand"
|
|
|
|
"sort"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
NumberOfPeers = 100
|
|
|
|
NumberOfAddresses = 250
|
|
|
|
NumberOfTests = 10000
|
|
|
|
)
|
|
|
|
|
2017-06-02 16:02:04 +00:00
|
|
|
type SlowNode struct {
|
|
|
|
peer *Peer
|
|
|
|
cidr uint
|
|
|
|
bits []byte
|
|
|
|
}
|
|
|
|
|
|
|
|
type SlowRouter []*SlowNode
|
2017-06-02 15:58:46 +00:00
|
|
|
|
|
|
|
func (r SlowRouter) Len() int {
|
|
|
|
return len(r)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r SlowRouter) Less(i, j int) bool {
|
|
|
|
return r[i].cidr > r[j].cidr
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r SlowRouter) Swap(i, j int) {
|
|
|
|
r[i], r[j] = r[j], r[i]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r SlowRouter) Insert(addr []byte, cidr uint, peer *Peer) SlowRouter {
|
|
|
|
for _, t := range r {
|
|
|
|
if t.cidr == cidr && commonBits(t.bits, addr) >= cidr {
|
|
|
|
t.peer = peer
|
|
|
|
t.bits = addr
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
}
|
2017-06-02 16:02:04 +00:00
|
|
|
r = append(r, &SlowNode{
|
2017-06-02 15:58:46 +00:00
|
|
|
cidr: cidr,
|
|
|
|
bits: addr,
|
|
|
|
peer: peer,
|
|
|
|
})
|
|
|
|
sort.Sort(r)
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r SlowRouter) Lookup(addr []byte) *Peer {
|
|
|
|
for _, t := range r {
|
|
|
|
common := commonBits(t.bits, addr)
|
|
|
|
if common >= t.cidr {
|
|
|
|
return t.peer
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTrieRandomIPv4(t *testing.T) {
|
2018-05-13 17:33:41 +00:00
|
|
|
var trie *trieEntry
|
2017-06-02 15:58:46 +00:00
|
|
|
var slow SlowRouter
|
|
|
|
var peers []*Peer
|
|
|
|
|
|
|
|
rand.Seed(1)
|
|
|
|
|
|
|
|
const AddressLength = 4
|
|
|
|
|
|
|
|
for n := 0; n < NumberOfPeers; n += 1 {
|
|
|
|
peers = append(peers, &Peer{})
|
|
|
|
}
|
|
|
|
|
|
|
|
for n := 0; n < NumberOfAddresses; n += 1 {
|
|
|
|
var addr [AddressLength]byte
|
|
|
|
rand.Read(addr[:])
|
|
|
|
cidr := uint(rand.Uint32() % (AddressLength * 8))
|
|
|
|
index := rand.Int() % NumberOfPeers
|
2018-05-13 17:33:41 +00:00
|
|
|
trie = trie.insert(addr[:], cidr, peers[index])
|
2017-06-02 15:58:46 +00:00
|
|
|
slow = slow.Insert(addr[:], cidr, peers[index])
|
|
|
|
}
|
|
|
|
|
|
|
|
for n := 0; n < NumberOfTests; n += 1 {
|
|
|
|
var addr [AddressLength]byte
|
|
|
|
rand.Read(addr[:])
|
|
|
|
peer1 := slow.Lookup(addr[:])
|
2018-05-13 17:33:41 +00:00
|
|
|
peer2 := trie.lookup(addr[:])
|
2017-06-02 15:58:46 +00:00
|
|
|
if peer1 != peer2 {
|
2018-05-13 17:33:41 +00:00
|
|
|
t.Error("trieEntry did not match naive implementation, for:", addr)
|
2017-06-02 15:58:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTrieRandomIPv6(t *testing.T) {
|
2018-05-13 17:33:41 +00:00
|
|
|
var trie *trieEntry
|
2017-06-02 15:58:46 +00:00
|
|
|
var slow SlowRouter
|
|
|
|
var peers []*Peer
|
|
|
|
|
|
|
|
rand.Seed(1)
|
|
|
|
|
|
|
|
const AddressLength = 16
|
|
|
|
|
|
|
|
for n := 0; n < NumberOfPeers; n += 1 {
|
|
|
|
peers = append(peers, &Peer{})
|
|
|
|
}
|
|
|
|
|
|
|
|
for n := 0; n < NumberOfAddresses; n += 1 {
|
|
|
|
var addr [AddressLength]byte
|
|
|
|
rand.Read(addr[:])
|
|
|
|
cidr := uint(rand.Uint32() % (AddressLength * 8))
|
|
|
|
index := rand.Int() % NumberOfPeers
|
2018-05-13 17:33:41 +00:00
|
|
|
trie = trie.insert(addr[:], cidr, peers[index])
|
2017-06-02 15:58:46 +00:00
|
|
|
slow = slow.Insert(addr[:], cidr, peers[index])
|
|
|
|
}
|
|
|
|
|
|
|
|
for n := 0; n < NumberOfTests; n += 1 {
|
|
|
|
var addr [AddressLength]byte
|
|
|
|
rand.Read(addr[:])
|
|
|
|
peer1 := slow.Lookup(addr[:])
|
2018-05-13 17:33:41 +00:00
|
|
|
peer2 := trie.lookup(addr[:])
|
2017-06-02 15:58:46 +00:00
|
|
|
if peer1 != peer2 {
|
2018-05-13 17:33:41 +00:00
|
|
|
t.Error("trieEntry did not match naive implementation, for:", addr)
|
2017-06-02 15:58:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|