2021-04-14 12:50:09 -06:00
|
|
|
package nebula
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net"
|
|
|
|
"testing"
|
|
|
|
|
2021-11-03 19:54:04 -06:00
|
|
|
"github.com/slackhq/nebula/iputil"
|
2021-04-14 12:50:09 -06:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestRemoteList_Rebuild(t *testing.T) {
|
2023-05-09 09:22:08 -06:00
|
|
|
rl := NewRemoteList(nil)
|
2021-04-14 12:50:09 -06:00
|
|
|
rl.unlockedSetV4(
|
2021-10-19 08:54:30 -06:00
|
|
|
0,
|
2021-04-14 12:50:09 -06:00
|
|
|
0,
|
|
|
|
[]*Ip4AndPort{
|
2021-11-03 19:54:04 -06:00
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("70.199.182.92"))), Port: 1475}, // this is duped
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.17.0.182"))), Port: 10101},
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.17.1.1"))), Port: 10101}, // this is duped
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.18.0.1"))), Port: 10101}, // this is duped
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.18.0.1"))), Port: 10101}, // this is a dupe
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.19.0.1"))), Port: 10101},
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.31.0.1"))), Port: 10101},
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.17.1.1"))), Port: 10101}, // this is a dupe
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("70.199.182.92"))), Port: 1476}, // almost dupe of 0 with a diff port
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("70.199.182.92"))), Port: 1475}, // this is a dupe
|
2021-04-14 12:50:09 -06:00
|
|
|
},
|
2021-11-03 19:54:04 -06:00
|
|
|
func(iputil.VpnIp, *Ip4AndPort) bool { return true },
|
2021-04-14 12:50:09 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
rl.unlockedSetV6(
|
2021-10-19 08:54:30 -06:00
|
|
|
1,
|
2021-04-14 12:50:09 -06:00
|
|
|
1,
|
|
|
|
[]*Ip6AndPort{
|
|
|
|
NewIp6AndPort(net.ParseIP("1::1"), 1), // this is duped
|
|
|
|
NewIp6AndPort(net.ParseIP("1::1"), 2), // almost dupe of 0 with a diff port, also gets duped
|
|
|
|
NewIp6AndPort(net.ParseIP("1:100::1"), 1),
|
|
|
|
NewIp6AndPort(net.ParseIP("1::1"), 1), // this is a dupe
|
|
|
|
NewIp6AndPort(net.ParseIP("1::1"), 2), // this is a dupe
|
|
|
|
},
|
2021-11-03 19:54:04 -06:00
|
|
|
func(iputil.VpnIp, *Ip6AndPort) bool { return true },
|
2021-04-14 12:50:09 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
rl.Rebuild([]*net.IPNet{})
|
|
|
|
assert.Len(t, rl.addrs, 10, "addrs contains too many entries")
|
|
|
|
|
|
|
|
// ipv6 first, sorted lexically within
|
|
|
|
assert.Equal(t, "[1::1]:1", rl.addrs[0].String())
|
|
|
|
assert.Equal(t, "[1::1]:2", rl.addrs[1].String())
|
|
|
|
assert.Equal(t, "[1:100::1]:1", rl.addrs[2].String())
|
|
|
|
|
|
|
|
// ipv4 last, sorted by public first, then private, lexically within them
|
|
|
|
assert.Equal(t, "70.199.182.92:1475", rl.addrs[3].String())
|
|
|
|
assert.Equal(t, "70.199.182.92:1476", rl.addrs[4].String())
|
|
|
|
assert.Equal(t, "172.17.0.182:10101", rl.addrs[5].String())
|
|
|
|
assert.Equal(t, "172.17.1.1:10101", rl.addrs[6].String())
|
|
|
|
assert.Equal(t, "172.18.0.1:10101", rl.addrs[7].String())
|
|
|
|
assert.Equal(t, "172.19.0.1:10101", rl.addrs[8].String())
|
|
|
|
assert.Equal(t, "172.31.0.1:10101", rl.addrs[9].String())
|
|
|
|
|
|
|
|
// Now ensure we can hoist ipv4 up
|
|
|
|
_, ipNet, err := net.ParseCIDR("0.0.0.0/0")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
rl.Rebuild([]*net.IPNet{ipNet})
|
|
|
|
assert.Len(t, rl.addrs, 10, "addrs contains too many entries")
|
|
|
|
|
|
|
|
// ipv4 first, public then private, lexically within them
|
|
|
|
assert.Equal(t, "70.199.182.92:1475", rl.addrs[0].String())
|
|
|
|
assert.Equal(t, "70.199.182.92:1476", rl.addrs[1].String())
|
|
|
|
assert.Equal(t, "172.17.0.182:10101", rl.addrs[2].String())
|
|
|
|
assert.Equal(t, "172.17.1.1:10101", rl.addrs[3].String())
|
|
|
|
assert.Equal(t, "172.18.0.1:10101", rl.addrs[4].String())
|
|
|
|
assert.Equal(t, "172.19.0.1:10101", rl.addrs[5].String())
|
|
|
|
assert.Equal(t, "172.31.0.1:10101", rl.addrs[6].String())
|
|
|
|
|
|
|
|
// ipv6 last, sorted by public first, then private, lexically within them
|
|
|
|
assert.Equal(t, "[1::1]:1", rl.addrs[7].String())
|
|
|
|
assert.Equal(t, "[1::1]:2", rl.addrs[8].String())
|
|
|
|
assert.Equal(t, "[1:100::1]:1", rl.addrs[9].String())
|
|
|
|
|
|
|
|
// Ensure we can hoist a specific ipv4 range over anything else
|
|
|
|
_, ipNet, err = net.ParseCIDR("172.17.0.0/16")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
rl.Rebuild([]*net.IPNet{ipNet})
|
|
|
|
assert.Len(t, rl.addrs, 10, "addrs contains too many entries")
|
|
|
|
|
|
|
|
// Preferred ipv4 first
|
|
|
|
assert.Equal(t, "172.17.0.182:10101", rl.addrs[0].String())
|
|
|
|
assert.Equal(t, "172.17.1.1:10101", rl.addrs[1].String())
|
|
|
|
|
|
|
|
// ipv6 next
|
|
|
|
assert.Equal(t, "[1::1]:1", rl.addrs[2].String())
|
|
|
|
assert.Equal(t, "[1::1]:2", rl.addrs[3].String())
|
|
|
|
assert.Equal(t, "[1:100::1]:1", rl.addrs[4].String())
|
|
|
|
|
|
|
|
// the remaining ipv4 last
|
|
|
|
assert.Equal(t, "70.199.182.92:1475", rl.addrs[5].String())
|
|
|
|
assert.Equal(t, "70.199.182.92:1476", rl.addrs[6].String())
|
|
|
|
assert.Equal(t, "172.18.0.1:10101", rl.addrs[7].String())
|
|
|
|
assert.Equal(t, "172.19.0.1:10101", rl.addrs[8].String())
|
|
|
|
assert.Equal(t, "172.31.0.1:10101", rl.addrs[9].String())
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkFullRebuild(b *testing.B) {
|
2023-05-09 09:22:08 -06:00
|
|
|
rl := NewRemoteList(nil)
|
2021-04-14 12:50:09 -06:00
|
|
|
rl.unlockedSetV4(
|
2021-10-19 08:54:30 -06:00
|
|
|
0,
|
2021-04-14 12:50:09 -06:00
|
|
|
0,
|
|
|
|
[]*Ip4AndPort{
|
2021-11-03 19:54:04 -06:00
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("70.199.182.92"))), Port: 1475},
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.17.0.182"))), Port: 10101},
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.17.1.1"))), Port: 10101},
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.18.0.1"))), Port: 10101},
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.19.0.1"))), Port: 10101},
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.31.0.1"))), Port: 10101},
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.17.1.1"))), Port: 10101}, // this is a dupe
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("70.199.182.92"))), Port: 1476}, // dupe of 0 with a diff port
|
2021-04-14 12:50:09 -06:00
|
|
|
},
|
2021-11-03 19:54:04 -06:00
|
|
|
func(iputil.VpnIp, *Ip4AndPort) bool { return true },
|
2021-04-14 12:50:09 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
rl.unlockedSetV6(
|
2021-10-19 08:54:30 -06:00
|
|
|
0,
|
2021-04-14 12:50:09 -06:00
|
|
|
0,
|
|
|
|
[]*Ip6AndPort{
|
|
|
|
NewIp6AndPort(net.ParseIP("1::1"), 1),
|
|
|
|
NewIp6AndPort(net.ParseIP("1::1"), 2), // dupe of 0 with a diff port
|
|
|
|
NewIp6AndPort(net.ParseIP("1:100::1"), 1),
|
|
|
|
NewIp6AndPort(net.ParseIP("1::1"), 1), // this is a dupe
|
|
|
|
},
|
2021-11-03 19:54:04 -06:00
|
|
|
func(iputil.VpnIp, *Ip6AndPort) bool { return true },
|
2021-04-14 12:50:09 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
b.Run("no preferred", func(b *testing.B) {
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
rl.shouldRebuild = true
|
|
|
|
rl.Rebuild([]*net.IPNet{})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
_, ipNet, err := net.ParseCIDR("172.17.0.0/16")
|
|
|
|
assert.NoError(b, err)
|
|
|
|
b.Run("1 preferred", func(b *testing.B) {
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
rl.shouldRebuild = true
|
|
|
|
rl.Rebuild([]*net.IPNet{ipNet})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
_, ipNet2, err := net.ParseCIDR("70.0.0.0/8")
|
|
|
|
assert.NoError(b, err)
|
|
|
|
b.Run("2 preferred", func(b *testing.B) {
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
rl.shouldRebuild = true
|
|
|
|
rl.Rebuild([]*net.IPNet{ipNet, ipNet2})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
_, ipNet3, err := net.ParseCIDR("0.0.0.0/0")
|
|
|
|
assert.NoError(b, err)
|
|
|
|
b.Run("3 preferred", func(b *testing.B) {
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
rl.shouldRebuild = true
|
|
|
|
rl.Rebuild([]*net.IPNet{ipNet, ipNet2, ipNet3})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkSortRebuild(b *testing.B) {
|
2023-05-09 09:22:08 -06:00
|
|
|
rl := NewRemoteList(nil)
|
2021-04-14 12:50:09 -06:00
|
|
|
rl.unlockedSetV4(
|
2021-10-19 08:54:30 -06:00
|
|
|
0,
|
2021-04-14 12:50:09 -06:00
|
|
|
0,
|
|
|
|
[]*Ip4AndPort{
|
2021-11-03 19:54:04 -06:00
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("70.199.182.92"))), Port: 1475},
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.17.0.182"))), Port: 10101},
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.17.1.1"))), Port: 10101},
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.18.0.1"))), Port: 10101},
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.19.0.1"))), Port: 10101},
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.31.0.1"))), Port: 10101},
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.17.1.1"))), Port: 10101}, // this is a dupe
|
|
|
|
{Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("70.199.182.92"))), Port: 1476}, // dupe of 0 with a diff port
|
2021-04-14 12:50:09 -06:00
|
|
|
},
|
2021-11-03 19:54:04 -06:00
|
|
|
func(iputil.VpnIp, *Ip4AndPort) bool { return true },
|
2021-04-14 12:50:09 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
rl.unlockedSetV6(
|
2021-10-19 08:54:30 -06:00
|
|
|
0,
|
2021-04-14 12:50:09 -06:00
|
|
|
0,
|
|
|
|
[]*Ip6AndPort{
|
|
|
|
NewIp6AndPort(net.ParseIP("1::1"), 1),
|
|
|
|
NewIp6AndPort(net.ParseIP("1::1"), 2), // dupe of 0 with a diff port
|
|
|
|
NewIp6AndPort(net.ParseIP("1:100::1"), 1),
|
|
|
|
NewIp6AndPort(net.ParseIP("1::1"), 1), // this is a dupe
|
|
|
|
},
|
2021-11-03 19:54:04 -06:00
|
|
|
func(iputil.VpnIp, *Ip6AndPort) bool { return true },
|
2021-04-14 12:50:09 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
b.Run("no preferred", func(b *testing.B) {
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
rl.shouldRebuild = true
|
|
|
|
rl.Rebuild([]*net.IPNet{})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
_, ipNet, err := net.ParseCIDR("172.17.0.0/16")
|
|
|
|
rl.Rebuild([]*net.IPNet{ipNet})
|
|
|
|
|
|
|
|
assert.NoError(b, err)
|
|
|
|
b.Run("1 preferred", func(b *testing.B) {
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
rl.Rebuild([]*net.IPNet{ipNet})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
_, ipNet2, err := net.ParseCIDR("70.0.0.0/8")
|
|
|
|
rl.Rebuild([]*net.IPNet{ipNet, ipNet2})
|
|
|
|
|
|
|
|
assert.NoError(b, err)
|
|
|
|
b.Run("2 preferred", func(b *testing.B) {
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
rl.Rebuild([]*net.IPNet{ipNet, ipNet2})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
_, ipNet3, err := net.ParseCIDR("0.0.0.0/0")
|
|
|
|
rl.Rebuild([]*net.IPNet{ipNet, ipNet2, ipNet3})
|
|
|
|
|
|
|
|
assert.NoError(b, err)
|
|
|
|
b.Run("3 preferred", func(b *testing.B) {
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
rl.Rebuild([]*net.IPNet{ipNet, ipNet2, ipNet3})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|