123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- package nebula
- import (
- "net"
- "testing"
- "github.com/slackhq/nebula/iputil"
- "github.com/stretchr/testify/assert"
- )
- func TestRemoteList_Rebuild(t *testing.T) {
- rl := NewRemoteList(nil)
- rl.unlockedSetV4(
- 0,
- 0,
- []*Ip4AndPort{
- {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
- },
- func(iputil.VpnIp, *Ip4AndPort) bool { return true },
- )
- rl.unlockedSetV6(
- 1,
- 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
- },
- func(iputil.VpnIp, *Ip6AndPort) bool { return true },
- )
- 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) {
- rl := NewRemoteList(nil)
- rl.unlockedSetV4(
- 0,
- 0,
- []*Ip4AndPort{
- {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
- },
- func(iputil.VpnIp, *Ip4AndPort) bool { return true },
- )
- rl.unlockedSetV6(
- 0,
- 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
- },
- func(iputil.VpnIp, *Ip6AndPort) bool { return true },
- )
- 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) {
- rl := NewRemoteList(nil)
- rl.unlockedSetV4(
- 0,
- 0,
- []*Ip4AndPort{
- {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
- },
- func(iputil.VpnIp, *Ip4AndPort) bool { return true },
- )
- rl.unlockedSetV6(
- 0,
- 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
- },
- func(iputil.VpnIp, *Ip6AndPort) bool { return true },
- )
- 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})
- }
- })
- }
|