github.com/slackhq/nebula@v1.9.0/remote_list_test.go (about) 1 package nebula 2 3 import ( 4 "net" 5 "testing" 6 7 "github.com/slackhq/nebula/iputil" 8 "github.com/stretchr/testify/assert" 9 ) 10 11 func TestRemoteList_Rebuild(t *testing.T) { 12 rl := NewRemoteList(nil) 13 rl.unlockedSetV4( 14 0, 15 0, 16 []*Ip4AndPort{ 17 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("70.199.182.92"))), Port: 1475}, // this is duped 18 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.17.0.182"))), Port: 10101}, 19 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.17.1.1"))), Port: 10101}, // this is duped 20 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.18.0.1"))), Port: 10101}, // this is duped 21 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.18.0.1"))), Port: 10101}, // this is a dupe 22 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.19.0.1"))), Port: 10101}, 23 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.31.0.1"))), Port: 10101}, 24 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.17.1.1"))), Port: 10101}, // this is a dupe 25 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("70.199.182.92"))), Port: 1476}, // almost dupe of 0 with a diff port 26 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("70.199.182.92"))), Port: 1475}, // this is a dupe 27 }, 28 func(iputil.VpnIp, *Ip4AndPort) bool { return true }, 29 ) 30 31 rl.unlockedSetV6( 32 1, 33 1, 34 []*Ip6AndPort{ 35 NewIp6AndPort(net.ParseIP("1::1"), 1), // this is duped 36 NewIp6AndPort(net.ParseIP("1::1"), 2), // almost dupe of 0 with a diff port, also gets duped 37 NewIp6AndPort(net.ParseIP("1:100::1"), 1), 38 NewIp6AndPort(net.ParseIP("1::1"), 1), // this is a dupe 39 NewIp6AndPort(net.ParseIP("1::1"), 2), // this is a dupe 40 }, 41 func(iputil.VpnIp, *Ip6AndPort) bool { return true }, 42 ) 43 44 rl.Rebuild([]*net.IPNet{}) 45 assert.Len(t, rl.addrs, 10, "addrs contains too many entries") 46 47 // ipv6 first, sorted lexically within 48 assert.Equal(t, "[1::1]:1", rl.addrs[0].String()) 49 assert.Equal(t, "[1::1]:2", rl.addrs[1].String()) 50 assert.Equal(t, "[1:100::1]:1", rl.addrs[2].String()) 51 52 // ipv4 last, sorted by public first, then private, lexically within them 53 assert.Equal(t, "70.199.182.92:1475", rl.addrs[3].String()) 54 assert.Equal(t, "70.199.182.92:1476", rl.addrs[4].String()) 55 assert.Equal(t, "172.17.0.182:10101", rl.addrs[5].String()) 56 assert.Equal(t, "172.17.1.1:10101", rl.addrs[6].String()) 57 assert.Equal(t, "172.18.0.1:10101", rl.addrs[7].String()) 58 assert.Equal(t, "172.19.0.1:10101", rl.addrs[8].String()) 59 assert.Equal(t, "172.31.0.1:10101", rl.addrs[9].String()) 60 61 // Now ensure we can hoist ipv4 up 62 _, ipNet, err := net.ParseCIDR("0.0.0.0/0") 63 assert.NoError(t, err) 64 rl.Rebuild([]*net.IPNet{ipNet}) 65 assert.Len(t, rl.addrs, 10, "addrs contains too many entries") 66 67 // ipv4 first, public then private, lexically within them 68 assert.Equal(t, "70.199.182.92:1475", rl.addrs[0].String()) 69 assert.Equal(t, "70.199.182.92:1476", rl.addrs[1].String()) 70 assert.Equal(t, "172.17.0.182:10101", rl.addrs[2].String()) 71 assert.Equal(t, "172.17.1.1:10101", rl.addrs[3].String()) 72 assert.Equal(t, "172.18.0.1:10101", rl.addrs[4].String()) 73 assert.Equal(t, "172.19.0.1:10101", rl.addrs[5].String()) 74 assert.Equal(t, "172.31.0.1:10101", rl.addrs[6].String()) 75 76 // ipv6 last, sorted by public first, then private, lexically within them 77 assert.Equal(t, "[1::1]:1", rl.addrs[7].String()) 78 assert.Equal(t, "[1::1]:2", rl.addrs[8].String()) 79 assert.Equal(t, "[1:100::1]:1", rl.addrs[9].String()) 80 81 // Ensure we can hoist a specific ipv4 range over anything else 82 _, ipNet, err = net.ParseCIDR("172.17.0.0/16") 83 assert.NoError(t, err) 84 rl.Rebuild([]*net.IPNet{ipNet}) 85 assert.Len(t, rl.addrs, 10, "addrs contains too many entries") 86 87 // Preferred ipv4 first 88 assert.Equal(t, "172.17.0.182:10101", rl.addrs[0].String()) 89 assert.Equal(t, "172.17.1.1:10101", rl.addrs[1].String()) 90 91 // ipv6 next 92 assert.Equal(t, "[1::1]:1", rl.addrs[2].String()) 93 assert.Equal(t, "[1::1]:2", rl.addrs[3].String()) 94 assert.Equal(t, "[1:100::1]:1", rl.addrs[4].String()) 95 96 // the remaining ipv4 last 97 assert.Equal(t, "70.199.182.92:1475", rl.addrs[5].String()) 98 assert.Equal(t, "70.199.182.92:1476", rl.addrs[6].String()) 99 assert.Equal(t, "172.18.0.1:10101", rl.addrs[7].String()) 100 assert.Equal(t, "172.19.0.1:10101", rl.addrs[8].String()) 101 assert.Equal(t, "172.31.0.1:10101", rl.addrs[9].String()) 102 } 103 104 func BenchmarkFullRebuild(b *testing.B) { 105 rl := NewRemoteList(nil) 106 rl.unlockedSetV4( 107 0, 108 0, 109 []*Ip4AndPort{ 110 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("70.199.182.92"))), Port: 1475}, 111 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.17.0.182"))), Port: 10101}, 112 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.17.1.1"))), Port: 10101}, 113 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.18.0.1"))), Port: 10101}, 114 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.19.0.1"))), Port: 10101}, 115 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.31.0.1"))), Port: 10101}, 116 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.17.1.1"))), Port: 10101}, // this is a dupe 117 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("70.199.182.92"))), Port: 1476}, // dupe of 0 with a diff port 118 }, 119 func(iputil.VpnIp, *Ip4AndPort) bool { return true }, 120 ) 121 122 rl.unlockedSetV6( 123 0, 124 0, 125 []*Ip6AndPort{ 126 NewIp6AndPort(net.ParseIP("1::1"), 1), 127 NewIp6AndPort(net.ParseIP("1::1"), 2), // dupe of 0 with a diff port 128 NewIp6AndPort(net.ParseIP("1:100::1"), 1), 129 NewIp6AndPort(net.ParseIP("1::1"), 1), // this is a dupe 130 }, 131 func(iputil.VpnIp, *Ip6AndPort) bool { return true }, 132 ) 133 134 b.Run("no preferred", func(b *testing.B) { 135 for i := 0; i < b.N; i++ { 136 rl.shouldRebuild = true 137 rl.Rebuild([]*net.IPNet{}) 138 } 139 }) 140 141 _, ipNet, err := net.ParseCIDR("172.17.0.0/16") 142 assert.NoError(b, err) 143 b.Run("1 preferred", func(b *testing.B) { 144 for i := 0; i < b.N; i++ { 145 rl.shouldRebuild = true 146 rl.Rebuild([]*net.IPNet{ipNet}) 147 } 148 }) 149 150 _, ipNet2, err := net.ParseCIDR("70.0.0.0/8") 151 assert.NoError(b, err) 152 b.Run("2 preferred", func(b *testing.B) { 153 for i := 0; i < b.N; i++ { 154 rl.shouldRebuild = true 155 rl.Rebuild([]*net.IPNet{ipNet, ipNet2}) 156 } 157 }) 158 159 _, ipNet3, err := net.ParseCIDR("0.0.0.0/0") 160 assert.NoError(b, err) 161 b.Run("3 preferred", func(b *testing.B) { 162 for i := 0; i < b.N; i++ { 163 rl.shouldRebuild = true 164 rl.Rebuild([]*net.IPNet{ipNet, ipNet2, ipNet3}) 165 } 166 }) 167 } 168 169 func BenchmarkSortRebuild(b *testing.B) { 170 rl := NewRemoteList(nil) 171 rl.unlockedSetV4( 172 0, 173 0, 174 []*Ip4AndPort{ 175 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("70.199.182.92"))), Port: 1475}, 176 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.17.0.182"))), Port: 10101}, 177 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.17.1.1"))), Port: 10101}, 178 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.18.0.1"))), Port: 10101}, 179 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.19.0.1"))), Port: 10101}, 180 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.31.0.1"))), Port: 10101}, 181 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("172.17.1.1"))), Port: 10101}, // this is a dupe 182 {Ip: uint32(iputil.Ip2VpnIp(net.ParseIP("70.199.182.92"))), Port: 1476}, // dupe of 0 with a diff port 183 }, 184 func(iputil.VpnIp, *Ip4AndPort) bool { return true }, 185 ) 186 187 rl.unlockedSetV6( 188 0, 189 0, 190 []*Ip6AndPort{ 191 NewIp6AndPort(net.ParseIP("1::1"), 1), 192 NewIp6AndPort(net.ParseIP("1::1"), 2), // dupe of 0 with a diff port 193 NewIp6AndPort(net.ParseIP("1:100::1"), 1), 194 NewIp6AndPort(net.ParseIP("1::1"), 1), // this is a dupe 195 }, 196 func(iputil.VpnIp, *Ip6AndPort) bool { return true }, 197 ) 198 199 b.Run("no preferred", func(b *testing.B) { 200 for i := 0; i < b.N; i++ { 201 rl.shouldRebuild = true 202 rl.Rebuild([]*net.IPNet{}) 203 } 204 }) 205 206 _, ipNet, err := net.ParseCIDR("172.17.0.0/16") 207 rl.Rebuild([]*net.IPNet{ipNet}) 208 209 assert.NoError(b, err) 210 b.Run("1 preferred", func(b *testing.B) { 211 for i := 0; i < b.N; i++ { 212 rl.Rebuild([]*net.IPNet{ipNet}) 213 } 214 }) 215 216 _, ipNet2, err := net.ParseCIDR("70.0.0.0/8") 217 rl.Rebuild([]*net.IPNet{ipNet, ipNet2}) 218 219 assert.NoError(b, err) 220 b.Run("2 preferred", func(b *testing.B) { 221 for i := 0; i < b.N; i++ { 222 rl.Rebuild([]*net.IPNet{ipNet, ipNet2}) 223 } 224 }) 225 226 _, ipNet3, err := net.ParseCIDR("0.0.0.0/0") 227 rl.Rebuild([]*net.IPNet{ipNet, ipNet2, ipNet3}) 228 229 assert.NoError(b, err) 230 b.Run("3 preferred", func(b *testing.B) { 231 for i := 0; i < b.N; i++ { 232 rl.Rebuild([]*net.IPNet{ipNet, ipNet2, ipNet3}) 233 } 234 }) 235 }