topology_test.go 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111
  1. // Copyright 2019 the Kilo authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package mesh
  15. import (
  16. "net"
  17. "strings"
  18. "testing"
  19. "github.com/go-kit/kit/log"
  20. "github.com/kylelemons/godebug/pretty"
  21. "github.com/kilo-io/kilo/pkg/wireguard"
  22. )
  23. func allowedIPs(ips ...string) string {
  24. return strings.Join(ips, ", ")
  25. }
  26. func mustParseCIDR(s string) (r *net.IPNet) {
  27. if _, ip, err := net.ParseCIDR(s); err != nil {
  28. panic("failed to parse CIDR")
  29. } else {
  30. r = ip
  31. }
  32. return
  33. }
  34. func setup(t *testing.T) (map[string]*Node, map[string]*Peer, []byte, uint32) {
  35. key := []byte("private")
  36. e1 := &net.IPNet{IP: net.ParseIP("10.1.0.1").To4(), Mask: net.CIDRMask(16, 32)}
  37. e2 := &net.IPNet{IP: net.ParseIP("10.1.0.2").To4(), Mask: net.CIDRMask(16, 32)}
  38. e3 := &net.IPNet{IP: net.ParseIP("10.1.0.3").To4(), Mask: net.CIDRMask(16, 32)}
  39. e4 := &net.IPNet{IP: net.ParseIP("10.1.0.4").To4(), Mask: net.CIDRMask(16, 32)}
  40. i1 := &net.IPNet{IP: net.ParseIP("192.168.0.1").To4(), Mask: net.CIDRMask(32, 32)}
  41. i2 := &net.IPNet{IP: net.ParseIP("192.168.0.2").To4(), Mask: net.CIDRMask(32, 32)}
  42. i3 := &net.IPNet{IP: net.ParseIP("192.168.178.3").To4(), Mask: net.CIDRMask(32, 32)}
  43. nodes := map[string]*Node{
  44. "a": {
  45. Name: "a",
  46. Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e1.IP}, Port: DefaultKiloPort},
  47. InternalIP: i1,
  48. Location: "1",
  49. Subnet: &net.IPNet{IP: net.ParseIP("10.2.1.0"), Mask: net.CIDRMask(24, 32)},
  50. Key: []byte("key1"),
  51. PersistentKeepalive: 25,
  52. },
  53. "b": {
  54. Name: "b",
  55. Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e2.IP}, Port: DefaultKiloPort},
  56. InternalIP: i1,
  57. Location: "2",
  58. Subnet: &net.IPNet{IP: net.ParseIP("10.2.2.0"), Mask: net.CIDRMask(24, 32)},
  59. Key: []byte("key2"),
  60. AllowedLocationIPs: []*net.IPNet{i3},
  61. },
  62. "c": {
  63. Name: "c",
  64. Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e3.IP}, Port: DefaultKiloPort},
  65. InternalIP: i2,
  66. // Same location as node b.
  67. Location: "2",
  68. Subnet: &net.IPNet{IP: net.ParseIP("10.2.3.0"), Mask: net.CIDRMask(24, 32)},
  69. Key: []byte("key3"),
  70. },
  71. "d": {
  72. Name: "d",
  73. Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e4.IP}, Port: DefaultKiloPort},
  74. // Same location as node a, but without private IP
  75. Location: "1",
  76. Subnet: &net.IPNet{IP: net.ParseIP("10.2.4.0"), Mask: net.CIDRMask(24, 32)},
  77. Key: []byte("key4"),
  78. },
  79. }
  80. peers := map[string]*Peer{
  81. "a": {
  82. Name: "a",
  83. Peer: wireguard.Peer{
  84. AllowedIPs: []*net.IPNet{
  85. {IP: net.ParseIP("10.5.0.1"), Mask: net.CIDRMask(24, 32)},
  86. {IP: net.ParseIP("10.5.0.2"), Mask: net.CIDRMask(24, 32)},
  87. },
  88. PublicKey: []byte("key4"),
  89. },
  90. },
  91. "b": {
  92. Name: "b",
  93. Peer: wireguard.Peer{
  94. AllowedIPs: []*net.IPNet{
  95. {IP: net.ParseIP("10.5.0.3"), Mask: net.CIDRMask(24, 32)},
  96. },
  97. Endpoint: &wireguard.Endpoint{
  98. DNSOrIP: wireguard.DNSOrIP{IP: net.ParseIP("192.168.0.1")},
  99. Port: DefaultKiloPort,
  100. },
  101. PublicKey: []byte("key5"),
  102. },
  103. },
  104. }
  105. return nodes, peers, key, DefaultKiloPort
  106. }
  107. func TestNewTopology(t *testing.T) {
  108. nodes, peers, key, port := setup(t)
  109. w1 := net.ParseIP("10.4.0.1").To4()
  110. w2 := net.ParseIP("10.4.0.2").To4()
  111. w3 := net.ParseIP("10.4.0.3").To4()
  112. w4 := net.ParseIP("10.4.0.4").To4()
  113. for _, tc := range []struct {
  114. name string
  115. granularity Granularity
  116. hostname string
  117. result *Topology
  118. }{
  119. {
  120. name: "logical from a",
  121. granularity: LogicalGranularity,
  122. hostname: nodes["a"].Name,
  123. result: &Topology{
  124. hostname: nodes["a"].Name,
  125. leader: true,
  126. location: logicalLocationPrefix + nodes["a"].Location,
  127. subnet: nodes["a"].Subnet,
  128. privateIP: nodes["a"].InternalIP,
  129. wireGuardCIDR: &net.IPNet{IP: w1, Mask: net.CIDRMask(16, 32)},
  130. segments: []*segment{
  131. {
  132. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  133. endpoint: nodes["a"].Endpoint,
  134. key: nodes["a"].Key,
  135. persistentKeepalive: nodes["a"].PersistentKeepalive,
  136. location: logicalLocationPrefix + nodes["a"].Location,
  137. cidrs: []*net.IPNet{nodes["a"].Subnet},
  138. hostnames: []string{"a"},
  139. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  140. wireGuardIP: w1,
  141. },
  142. {
  143. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  144. endpoint: nodes["b"].Endpoint,
  145. key: nodes["b"].Key,
  146. persistentKeepalive: nodes["b"].PersistentKeepalive,
  147. location: logicalLocationPrefix + nodes["b"].Location,
  148. cidrs: []*net.IPNet{nodes["b"].Subnet, nodes["c"].Subnet},
  149. hostnames: []string{"b", "c"},
  150. privateIPs: []net.IP{nodes["b"].InternalIP.IP, nodes["c"].InternalIP.IP},
  151. wireGuardIP: w2,
  152. allowedLocationIPs: nodes["b"].AllowedLocationIPs,
  153. },
  154. {
  155. allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w3, Mask: net.CIDRMask(32, 32)}},
  156. endpoint: nodes["d"].Endpoint,
  157. key: nodes["d"].Key,
  158. persistentKeepalive: nodes["d"].PersistentKeepalive,
  159. location: nodeLocationPrefix + nodes["d"].Name,
  160. cidrs: []*net.IPNet{nodes["d"].Subnet},
  161. hostnames: []string{"d"},
  162. privateIPs: nil,
  163. wireGuardIP: w3,
  164. },
  165. },
  166. peers: []*Peer{peers["a"], peers["b"]},
  167. logger: log.NewNopLogger(),
  168. },
  169. },
  170. {
  171. name: "logical from b",
  172. granularity: LogicalGranularity,
  173. hostname: nodes["b"].Name,
  174. result: &Topology{
  175. hostname: nodes["b"].Name,
  176. leader: true,
  177. location: logicalLocationPrefix + nodes["b"].Location,
  178. subnet: nodes["b"].Subnet,
  179. privateIP: nodes["b"].InternalIP,
  180. wireGuardCIDR: &net.IPNet{IP: w2, Mask: net.CIDRMask(16, 32)},
  181. segments: []*segment{
  182. {
  183. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  184. endpoint: nodes["a"].Endpoint,
  185. key: nodes["a"].Key,
  186. persistentKeepalive: nodes["a"].PersistentKeepalive,
  187. location: logicalLocationPrefix + nodes["a"].Location,
  188. cidrs: []*net.IPNet{nodes["a"].Subnet},
  189. hostnames: []string{"a"},
  190. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  191. wireGuardIP: w1,
  192. },
  193. {
  194. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  195. endpoint: nodes["b"].Endpoint,
  196. key: nodes["b"].Key,
  197. persistentKeepalive: nodes["b"].PersistentKeepalive,
  198. location: logicalLocationPrefix + nodes["b"].Location,
  199. cidrs: []*net.IPNet{nodes["b"].Subnet, nodes["c"].Subnet},
  200. hostnames: []string{"b", "c"},
  201. privateIPs: []net.IP{nodes["b"].InternalIP.IP, nodes["c"].InternalIP.IP},
  202. wireGuardIP: w2,
  203. allowedLocationIPs: nodes["b"].AllowedLocationIPs,
  204. },
  205. {
  206. allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w3, Mask: net.CIDRMask(32, 32)}},
  207. endpoint: nodes["d"].Endpoint,
  208. key: nodes["d"].Key,
  209. persistentKeepalive: nodes["d"].PersistentKeepalive,
  210. location: nodeLocationPrefix + nodes["d"].Name,
  211. cidrs: []*net.IPNet{nodes["d"].Subnet},
  212. hostnames: []string{"d"},
  213. privateIPs: nil,
  214. wireGuardIP: w3,
  215. },
  216. },
  217. peers: []*Peer{peers["a"], peers["b"]},
  218. logger: log.NewNopLogger(),
  219. },
  220. },
  221. {
  222. name: "logical from c",
  223. granularity: LogicalGranularity,
  224. hostname: nodes["c"].Name,
  225. result: &Topology{
  226. hostname: nodes["c"].Name,
  227. leader: false,
  228. location: logicalLocationPrefix + nodes["b"].Location,
  229. subnet: nodes["c"].Subnet,
  230. privateIP: nodes["c"].InternalIP,
  231. wireGuardCIDR: DefaultKiloSubnet,
  232. segments: []*segment{
  233. {
  234. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  235. endpoint: nodes["a"].Endpoint,
  236. key: nodes["a"].Key,
  237. persistentKeepalive: nodes["a"].PersistentKeepalive,
  238. location: logicalLocationPrefix + nodes["a"].Location,
  239. cidrs: []*net.IPNet{nodes["a"].Subnet},
  240. hostnames: []string{"a"},
  241. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  242. wireGuardIP: w1,
  243. },
  244. {
  245. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  246. endpoint: nodes["b"].Endpoint,
  247. key: nodes["b"].Key,
  248. persistentKeepalive: nodes["b"].PersistentKeepalive,
  249. location: logicalLocationPrefix + nodes["b"].Location,
  250. cidrs: []*net.IPNet{nodes["b"].Subnet, nodes["c"].Subnet},
  251. hostnames: []string{"b", "c"},
  252. privateIPs: []net.IP{nodes["b"].InternalIP.IP, nodes["c"].InternalIP.IP},
  253. wireGuardIP: w2,
  254. allowedLocationIPs: nodes["b"].AllowedLocationIPs,
  255. },
  256. {
  257. allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w3, Mask: net.CIDRMask(32, 32)}},
  258. endpoint: nodes["d"].Endpoint,
  259. key: nodes["d"].Key,
  260. persistentKeepalive: nodes["d"].PersistentKeepalive,
  261. location: nodeLocationPrefix + nodes["d"].Name,
  262. cidrs: []*net.IPNet{nodes["d"].Subnet},
  263. hostnames: []string{"d"},
  264. privateIPs: nil,
  265. wireGuardIP: w3,
  266. },
  267. },
  268. peers: []*Peer{peers["a"], peers["b"]},
  269. logger: log.NewNopLogger(),
  270. },
  271. },
  272. {
  273. name: "full from a",
  274. granularity: FullGranularity,
  275. hostname: nodes["a"].Name,
  276. result: &Topology{
  277. hostname: nodes["a"].Name,
  278. leader: true,
  279. location: nodeLocationPrefix + nodes["a"].Name,
  280. subnet: nodes["a"].Subnet,
  281. privateIP: nodes["a"].InternalIP,
  282. wireGuardCIDR: &net.IPNet{IP: w1, Mask: net.CIDRMask(16, 32)},
  283. segments: []*segment{
  284. {
  285. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  286. endpoint: nodes["a"].Endpoint,
  287. key: nodes["a"].Key,
  288. persistentKeepalive: nodes["a"].PersistentKeepalive,
  289. location: nodeLocationPrefix + nodes["a"].Name,
  290. cidrs: []*net.IPNet{nodes["a"].Subnet},
  291. hostnames: []string{"a"},
  292. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  293. wireGuardIP: w1,
  294. },
  295. {
  296. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  297. endpoint: nodes["b"].Endpoint,
  298. key: nodes["b"].Key,
  299. persistentKeepalive: nodes["b"].PersistentKeepalive,
  300. location: nodeLocationPrefix + nodes["b"].Name,
  301. cidrs: []*net.IPNet{nodes["b"].Subnet},
  302. hostnames: []string{"b"},
  303. privateIPs: []net.IP{nodes["b"].InternalIP.IP},
  304. wireGuardIP: w2,
  305. allowedLocationIPs: nodes["b"].AllowedLocationIPs,
  306. },
  307. {
  308. allowedIPs: []*net.IPNet{nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
  309. endpoint: nodes["c"].Endpoint,
  310. key: nodes["c"].Key,
  311. persistentKeepalive: nodes["c"].PersistentKeepalive,
  312. location: nodeLocationPrefix + nodes["c"].Name,
  313. cidrs: []*net.IPNet{nodes["c"].Subnet},
  314. hostnames: []string{"c"},
  315. privateIPs: []net.IP{nodes["c"].InternalIP.IP},
  316. wireGuardIP: w3,
  317. },
  318. {
  319. allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w4, Mask: net.CIDRMask(32, 32)}},
  320. endpoint: nodes["d"].Endpoint,
  321. key: nodes["d"].Key,
  322. persistentKeepalive: nodes["d"].PersistentKeepalive,
  323. location: nodeLocationPrefix + nodes["d"].Name,
  324. cidrs: []*net.IPNet{nodes["d"].Subnet},
  325. hostnames: []string{"d"},
  326. privateIPs: nil,
  327. wireGuardIP: w4,
  328. },
  329. },
  330. peers: []*Peer{peers["a"], peers["b"]},
  331. logger: log.NewNopLogger(),
  332. },
  333. },
  334. {
  335. name: "full from b",
  336. granularity: FullGranularity,
  337. hostname: nodes["b"].Name,
  338. result: &Topology{
  339. hostname: nodes["b"].Name,
  340. leader: true,
  341. location: nodeLocationPrefix + nodes["b"].Name,
  342. subnet: nodes["b"].Subnet,
  343. privateIP: nodes["b"].InternalIP,
  344. wireGuardCIDR: &net.IPNet{IP: w2, Mask: net.CIDRMask(16, 32)},
  345. segments: []*segment{
  346. {
  347. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  348. endpoint: nodes["a"].Endpoint,
  349. key: nodes["a"].Key,
  350. persistentKeepalive: nodes["a"].PersistentKeepalive,
  351. location: nodeLocationPrefix + nodes["a"].Name,
  352. cidrs: []*net.IPNet{nodes["a"].Subnet},
  353. hostnames: []string{"a"},
  354. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  355. wireGuardIP: w1,
  356. },
  357. {
  358. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  359. endpoint: nodes["b"].Endpoint,
  360. key: nodes["b"].Key,
  361. persistentKeepalive: nodes["b"].PersistentKeepalive,
  362. location: nodeLocationPrefix + nodes["b"].Name,
  363. cidrs: []*net.IPNet{nodes["b"].Subnet},
  364. hostnames: []string{"b"},
  365. privateIPs: []net.IP{nodes["b"].InternalIP.IP},
  366. wireGuardIP: w2,
  367. allowedLocationIPs: nodes["b"].AllowedLocationIPs,
  368. },
  369. {
  370. allowedIPs: []*net.IPNet{nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
  371. endpoint: nodes["c"].Endpoint,
  372. key: nodes["c"].Key,
  373. persistentKeepalive: nodes["c"].PersistentKeepalive,
  374. location: nodeLocationPrefix + nodes["c"].Name,
  375. cidrs: []*net.IPNet{nodes["c"].Subnet},
  376. hostnames: []string{"c"},
  377. privateIPs: []net.IP{nodes["c"].InternalIP.IP},
  378. wireGuardIP: w3,
  379. },
  380. {
  381. allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w4, Mask: net.CIDRMask(32, 32)}},
  382. endpoint: nodes["d"].Endpoint,
  383. key: nodes["d"].Key,
  384. persistentKeepalive: nodes["d"].PersistentKeepalive,
  385. location: nodeLocationPrefix + nodes["d"].Name,
  386. cidrs: []*net.IPNet{nodes["d"].Subnet},
  387. hostnames: []string{"d"},
  388. privateIPs: nil,
  389. wireGuardIP: w4,
  390. },
  391. },
  392. peers: []*Peer{peers["a"], peers["b"]},
  393. logger: log.NewNopLogger(),
  394. },
  395. },
  396. {
  397. name: "full from c",
  398. granularity: FullGranularity,
  399. hostname: nodes["c"].Name,
  400. result: &Topology{
  401. hostname: nodes["c"].Name,
  402. leader: true,
  403. location: nodeLocationPrefix + nodes["c"].Name,
  404. subnet: nodes["c"].Subnet,
  405. privateIP: nodes["c"].InternalIP,
  406. wireGuardCIDR: &net.IPNet{IP: w3, Mask: net.CIDRMask(16, 32)},
  407. segments: []*segment{
  408. {
  409. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  410. endpoint: nodes["a"].Endpoint,
  411. key: nodes["a"].Key,
  412. persistentKeepalive: nodes["a"].PersistentKeepalive,
  413. location: nodeLocationPrefix + nodes["a"].Name,
  414. cidrs: []*net.IPNet{nodes["a"].Subnet},
  415. hostnames: []string{"a"},
  416. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  417. wireGuardIP: w1,
  418. },
  419. {
  420. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  421. endpoint: nodes["b"].Endpoint,
  422. key: nodes["b"].Key,
  423. persistentKeepalive: nodes["b"].PersistentKeepalive,
  424. location: nodeLocationPrefix + nodes["b"].Name,
  425. cidrs: []*net.IPNet{nodes["b"].Subnet},
  426. hostnames: []string{"b"},
  427. privateIPs: []net.IP{nodes["b"].InternalIP.IP},
  428. wireGuardIP: w2,
  429. allowedLocationIPs: nodes["b"].AllowedLocationIPs,
  430. },
  431. {
  432. allowedIPs: []*net.IPNet{nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
  433. endpoint: nodes["c"].Endpoint,
  434. key: nodes["c"].Key,
  435. persistentKeepalive: nodes["c"].PersistentKeepalive,
  436. location: nodeLocationPrefix + nodes["c"].Name,
  437. cidrs: []*net.IPNet{nodes["c"].Subnet},
  438. hostnames: []string{"c"},
  439. privateIPs: []net.IP{nodes["c"].InternalIP.IP},
  440. wireGuardIP: w3,
  441. },
  442. {
  443. allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w4, Mask: net.CIDRMask(32, 32)}},
  444. endpoint: nodes["d"].Endpoint,
  445. key: nodes["d"].Key,
  446. persistentKeepalive: nodes["d"].PersistentKeepalive,
  447. location: nodeLocationPrefix + nodes["d"].Name,
  448. cidrs: []*net.IPNet{nodes["d"].Subnet},
  449. hostnames: []string{"d"},
  450. privateIPs: nil,
  451. wireGuardIP: w4,
  452. },
  453. },
  454. peers: []*Peer{peers["a"], peers["b"]},
  455. logger: log.NewNopLogger(),
  456. },
  457. },
  458. {
  459. name: "full from d",
  460. granularity: FullGranularity,
  461. hostname: nodes["d"].Name,
  462. result: &Topology{
  463. hostname: nodes["d"].Name,
  464. leader: true,
  465. location: nodeLocationPrefix + nodes["d"].Name,
  466. subnet: nodes["d"].Subnet,
  467. privateIP: nil,
  468. wireGuardCIDR: &net.IPNet{IP: w4, Mask: net.CIDRMask(16, 32)},
  469. segments: []*segment{
  470. {
  471. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  472. endpoint: nodes["a"].Endpoint,
  473. key: nodes["a"].Key,
  474. persistentKeepalive: nodes["a"].PersistentKeepalive,
  475. location: nodeLocationPrefix + nodes["a"].Name,
  476. cidrs: []*net.IPNet{nodes["a"].Subnet},
  477. hostnames: []string{"a"},
  478. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  479. wireGuardIP: w1,
  480. },
  481. {
  482. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  483. endpoint: nodes["b"].Endpoint,
  484. key: nodes["b"].Key,
  485. persistentKeepalive: nodes["b"].PersistentKeepalive,
  486. location: nodeLocationPrefix + nodes["b"].Name,
  487. cidrs: []*net.IPNet{nodes["b"].Subnet},
  488. hostnames: []string{"b"},
  489. privateIPs: []net.IP{nodes["b"].InternalIP.IP},
  490. wireGuardIP: w2,
  491. allowedLocationIPs: nodes["b"].AllowedLocationIPs,
  492. },
  493. {
  494. allowedIPs: []*net.IPNet{nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
  495. endpoint: nodes["c"].Endpoint,
  496. key: nodes["c"].Key,
  497. persistentKeepalive: nodes["c"].PersistentKeepalive,
  498. location: nodeLocationPrefix + nodes["c"].Name,
  499. cidrs: []*net.IPNet{nodes["c"].Subnet},
  500. hostnames: []string{"c"},
  501. privateIPs: []net.IP{nodes["c"].InternalIP.IP},
  502. wireGuardIP: w3,
  503. },
  504. {
  505. allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w4, Mask: net.CIDRMask(32, 32)}},
  506. endpoint: nodes["d"].Endpoint,
  507. key: nodes["d"].Key,
  508. persistentKeepalive: nodes["d"].PersistentKeepalive,
  509. location: nodeLocationPrefix + nodes["d"].Name,
  510. cidrs: []*net.IPNet{nodes["d"].Subnet},
  511. hostnames: []string{"d"},
  512. privateIPs: nil,
  513. wireGuardIP: w4,
  514. },
  515. },
  516. peers: []*Peer{peers["a"], peers["b"]},
  517. logger: log.NewNopLogger(),
  518. },
  519. },
  520. } {
  521. tc.result.key = key
  522. tc.result.port = port
  523. topo, err := NewTopology(nodes, peers, tc.granularity, tc.hostname, port, key, DefaultKiloSubnet, 0, nil)
  524. if err != nil {
  525. t.Errorf("test case %q: failed to generate Topology: %v", tc.name, err)
  526. }
  527. if diff := pretty.Compare(topo, tc.result); diff != "" {
  528. t.Errorf("test case %q: got diff: %v", tc.name, diff)
  529. }
  530. }
  531. }
  532. func mustTopo(t *testing.T, nodes map[string]*Node, peers map[string]*Peer, granularity Granularity, hostname string, port uint32, key []byte, subnet *net.IPNet, persistentKeepalive int) *Topology {
  533. topo, err := NewTopology(nodes, peers, granularity, hostname, port, key, subnet, persistentKeepalive, nil)
  534. if err != nil {
  535. t.Errorf("failed to generate Topology: %v", err)
  536. }
  537. return topo
  538. }
  539. func TestConf(t *testing.T) {
  540. nodes, peers, key, port := setup(t)
  541. for _, tc := range []struct {
  542. name string
  543. topology *Topology
  544. result string
  545. }{
  546. {
  547. name: "logical from a",
  548. topology: mustTopo(t, nodes, peers, LogicalGranularity, nodes["a"].Name, port, key, DefaultKiloSubnet, nodes["a"].PersistentKeepalive),
  549. result: `[Interface]
  550. PrivateKey = private
  551. ListenPort = 51820
  552. [Peer]
  553. PublicKey = key2
  554. Endpoint = 10.1.0.2:51820
  555. AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.2.3.0/24, 192.168.0.2/32, 10.4.0.2/32, 192.168.178.3/32
  556. PersistentKeepalive = 25
  557. [Peer]
  558. PublicKey = key4
  559. Endpoint = 10.1.0.4:51820
  560. AllowedIPs = 10.2.4.0/24, 10.4.0.3/32
  561. PersistentKeepalive = 25
  562. [Peer]
  563. PublicKey = key4
  564. AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
  565. PersistentKeepalive = 25
  566. [Peer]
  567. PublicKey = key5
  568. Endpoint = 192.168.0.1:51820
  569. AllowedIPs = 10.5.0.3/24
  570. PersistentKeepalive = 25
  571. `,
  572. },
  573. {
  574. name: "logical from b",
  575. topology: mustTopo(t, nodes, peers, LogicalGranularity, nodes["b"].Name, port, key, DefaultKiloSubnet, nodes["b"].PersistentKeepalive),
  576. result: `[Interface]
  577. PrivateKey = private
  578. ListenPort = 51820
  579. [Peer]
  580. PublicKey = key1
  581. Endpoint = 10.1.0.1:51820
  582. AllowedIPs = 10.2.1.0/24, 192.168.0.1/32, 10.4.0.1/32
  583. [Peer]
  584. PublicKey = key4
  585. Endpoint = 10.1.0.4:51820
  586. AllowedIPs = 10.2.4.0/24, 10.4.0.3/32
  587. [Peer]
  588. PublicKey = key4
  589. AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
  590. [Peer]
  591. PublicKey = key5
  592. Endpoint = 192.168.0.1:51820
  593. AllowedIPs = 10.5.0.3/24
  594. `,
  595. },
  596. {
  597. name: "logical from c",
  598. topology: mustTopo(t, nodes, peers, LogicalGranularity, nodes["c"].Name, port, key, DefaultKiloSubnet, nodes["c"].PersistentKeepalive),
  599. result: `[Interface]
  600. PrivateKey = private
  601. ListenPort = 51820
  602. [Peer]
  603. PublicKey = key1
  604. Endpoint = 10.1.0.1:51820
  605. AllowedIPs = 10.2.1.0/24, 192.168.0.1/32, 10.4.0.1/32
  606. [Peer]
  607. PublicKey = key4
  608. Endpoint = 10.1.0.4:51820
  609. AllowedIPs = 10.2.4.0/24, 10.4.0.3/32
  610. [Peer]
  611. PublicKey = key4
  612. AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
  613. [Peer]
  614. PublicKey = key5
  615. Endpoint = 192.168.0.1:51820
  616. AllowedIPs = 10.5.0.3/24
  617. `,
  618. },
  619. {
  620. name: "full from a",
  621. topology: mustTopo(t, nodes, peers, FullGranularity, nodes["a"].Name, port, key, DefaultKiloSubnet, nodes["a"].PersistentKeepalive),
  622. result: `[Interface]
  623. PrivateKey = private
  624. ListenPort = 51820
  625. [Peer]
  626. PublicKey = key2
  627. Endpoint = 10.1.0.2:51820
  628. AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.4.0.2/32, 192.168.178.3/32
  629. PersistentKeepalive = 25
  630. [Peer]
  631. PublicKey = key3
  632. Endpoint = 10.1.0.3:51820
  633. AllowedIPs = 10.2.3.0/24, 192.168.0.2/32, 10.4.0.3/32
  634. PersistentKeepalive = 25
  635. [Peer]
  636. PublicKey = key4
  637. Endpoint = 10.1.0.4:51820
  638. AllowedIPs = 10.2.4.0/24, 10.4.0.4/32
  639. PersistentKeepalive = 25
  640. [Peer]
  641. PublicKey = key4
  642. AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
  643. PersistentKeepalive = 25
  644. [Peer]
  645. PublicKey = key5
  646. Endpoint = 192.168.0.1:51820
  647. AllowedIPs = 10.5.0.3/24
  648. PersistentKeepalive = 25
  649. `,
  650. },
  651. {
  652. name: "full from b",
  653. topology: mustTopo(t, nodes, peers, FullGranularity, nodes["b"].Name, port, key, DefaultKiloSubnet, nodes["b"].PersistentKeepalive),
  654. result: `[Interface]
  655. PrivateKey = private
  656. ListenPort = 51820
  657. [Peer]
  658. PublicKey = key1
  659. Endpoint = 10.1.0.1:51820
  660. AllowedIPs = 10.2.1.0/24, 192.168.0.1/32, 10.4.0.1/32
  661. [Peer]
  662. PublicKey = key3
  663. Endpoint = 10.1.0.3:51820
  664. AllowedIPs = 10.2.3.0/24, 192.168.0.2/32, 10.4.0.3/32
  665. [Peer]
  666. PublicKey = key4
  667. Endpoint = 10.1.0.4:51820
  668. AllowedIPs = 10.2.4.0/24, 10.4.0.4/32
  669. [Peer]
  670. PublicKey = key4
  671. AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
  672. [Peer]
  673. PublicKey = key5
  674. Endpoint = 192.168.0.1:51820
  675. AllowedIPs = 10.5.0.3/24
  676. `,
  677. },
  678. {
  679. name: "full from c",
  680. topology: mustTopo(t, nodes, peers, FullGranularity, nodes["c"].Name, port, key, DefaultKiloSubnet, nodes["c"].PersistentKeepalive),
  681. result: `[Interface]
  682. PrivateKey = private
  683. ListenPort = 51820
  684. [Peer]
  685. PublicKey = key1
  686. Endpoint = 10.1.0.1:51820
  687. AllowedIPs = 10.2.1.0/24, 192.168.0.1/32, 10.4.0.1/32
  688. [Peer]
  689. PublicKey = key2
  690. Endpoint = 10.1.0.2:51820
  691. AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.4.0.2/32, 192.168.178.3/32
  692. [Peer]
  693. PublicKey = key4
  694. Endpoint = 10.1.0.4:51820
  695. AllowedIPs = 10.2.4.0/24, 10.4.0.4/32
  696. [Peer]
  697. PublicKey = key4
  698. AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
  699. [Peer]
  700. PublicKey = key5
  701. Endpoint = 192.168.0.1:51820
  702. AllowedIPs = 10.5.0.3/24
  703. `,
  704. },
  705. } {
  706. conf := tc.topology.Conf()
  707. if !conf.Equal(wireguard.Parse([]byte(tc.result))) {
  708. buf, err := conf.Bytes()
  709. if err != nil {
  710. t.Errorf("test case %q: failed to render conf: %v", tc.name, err)
  711. }
  712. t.Errorf("test case %q: expected %s got %s", tc.name, tc.result, string(buf))
  713. }
  714. }
  715. }
  716. func TestFindLeader(t *testing.T) {
  717. ip, e1, err := net.ParseCIDR("10.0.0.1/32")
  718. if err != nil {
  719. t.Fatalf("failed to parse external IP CIDR: %v", err)
  720. }
  721. e1.IP = ip
  722. ip, e2, err := net.ParseCIDR("8.8.8.8/32")
  723. if err != nil {
  724. t.Fatalf("failed to parse external IP CIDR: %v", err)
  725. }
  726. e2.IP = ip
  727. nodes := []*Node{
  728. {
  729. Name: "a",
  730. Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e1.IP}, Port: DefaultKiloPort},
  731. },
  732. {
  733. Name: "b",
  734. Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e2.IP}, Port: DefaultKiloPort},
  735. },
  736. {
  737. Name: "c",
  738. Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e2.IP}, Port: DefaultKiloPort},
  739. },
  740. {
  741. Name: "d",
  742. Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e1.IP}, Port: DefaultKiloPort},
  743. Leader: true,
  744. },
  745. {
  746. Name: "2",
  747. Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e2.IP}, Port: DefaultKiloPort},
  748. Leader: true,
  749. },
  750. }
  751. for _, tc := range []struct {
  752. name string
  753. nodes []*Node
  754. out int
  755. }{
  756. {
  757. name: "nil",
  758. nodes: nil,
  759. out: 0,
  760. },
  761. {
  762. name: "one",
  763. nodes: []*Node{nodes[0]},
  764. out: 0,
  765. },
  766. {
  767. name: "non-leaders",
  768. nodes: []*Node{nodes[0], nodes[1], nodes[2]},
  769. out: 1,
  770. },
  771. {
  772. name: "leaders",
  773. nodes: []*Node{nodes[3], nodes[4]},
  774. out: 1,
  775. },
  776. {
  777. name: "public",
  778. nodes: []*Node{nodes[1], nodes[2], nodes[4]},
  779. out: 2,
  780. },
  781. {
  782. name: "private",
  783. nodes: []*Node{nodes[0], nodes[3]},
  784. out: 1,
  785. },
  786. {
  787. name: "all",
  788. nodes: nodes,
  789. out: 4,
  790. },
  791. } {
  792. l := findLeader(tc.nodes)
  793. if l != tc.out {
  794. t.Errorf("test case %q: expected %d got %d", tc.name, tc.out, l)
  795. }
  796. }
  797. }
  798. func TestDeduplicatePeerIPs(t *testing.T) {
  799. p1 := &Peer{
  800. Name: "1",
  801. Peer: wireguard.Peer{
  802. PublicKey: []byte("key1"),
  803. AllowedIPs: []*net.IPNet{
  804. {IP: net.ParseIP("10.0.0.1"), Mask: net.CIDRMask(24, 32)},
  805. {IP: net.ParseIP("10.0.0.2"), Mask: net.CIDRMask(24, 32)},
  806. },
  807. },
  808. }
  809. p2 := &Peer{
  810. Name: "2",
  811. Peer: wireguard.Peer{
  812. PublicKey: []byte("key2"),
  813. AllowedIPs: []*net.IPNet{
  814. {IP: net.ParseIP("10.0.0.1"), Mask: net.CIDRMask(24, 32)},
  815. {IP: net.ParseIP("10.0.0.3"), Mask: net.CIDRMask(24, 32)},
  816. },
  817. },
  818. }
  819. p3 := &Peer{
  820. Name: "3",
  821. Peer: wireguard.Peer{
  822. PublicKey: []byte("key3"),
  823. AllowedIPs: []*net.IPNet{
  824. {IP: net.ParseIP("10.0.0.2"), Mask: net.CIDRMask(24, 32)},
  825. {IP: net.ParseIP("10.0.0.3"), Mask: net.CIDRMask(24, 32)},
  826. {IP: net.ParseIP("10.0.0.1"), Mask: net.CIDRMask(24, 32)},
  827. },
  828. },
  829. }
  830. p4 := &Peer{
  831. Name: "4",
  832. Peer: wireguard.Peer{
  833. PublicKey: []byte("key4"),
  834. AllowedIPs: []*net.IPNet{
  835. {IP: net.ParseIP("10.0.0.3"), Mask: net.CIDRMask(24, 32)},
  836. {IP: net.ParseIP("10.0.0.3"), Mask: net.CIDRMask(24, 32)},
  837. },
  838. },
  839. }
  840. for _, tc := range []struct {
  841. name string
  842. peers []*Peer
  843. out []*Peer
  844. }{
  845. {
  846. name: "nil",
  847. peers: nil,
  848. out: nil,
  849. },
  850. {
  851. name: "simple dupe",
  852. peers: []*Peer{p1, p2},
  853. out: []*Peer{
  854. p1,
  855. {
  856. Name: "2",
  857. Peer: wireguard.Peer{
  858. PublicKey: []byte("key2"),
  859. AllowedIPs: []*net.IPNet{
  860. {IP: net.ParseIP("10.0.0.3"), Mask: net.CIDRMask(24, 32)},
  861. },
  862. },
  863. },
  864. },
  865. },
  866. {
  867. name: "simple dupe reversed",
  868. peers: []*Peer{p2, p1},
  869. out: []*Peer{
  870. p2,
  871. {
  872. Name: "1",
  873. Peer: wireguard.Peer{
  874. PublicKey: []byte("key1"),
  875. AllowedIPs: []*net.IPNet{
  876. {IP: net.ParseIP("10.0.0.2"), Mask: net.CIDRMask(24, 32)},
  877. },
  878. },
  879. },
  880. },
  881. },
  882. {
  883. name: "one duplicates all",
  884. peers: []*Peer{p3, p2, p1, p4},
  885. out: []*Peer{
  886. p3,
  887. {
  888. Name: "2",
  889. Peer: wireguard.Peer{
  890. PublicKey: []byte("key2"),
  891. },
  892. },
  893. {
  894. Name: "1",
  895. Peer: wireguard.Peer{
  896. PublicKey: []byte("key1"),
  897. },
  898. },
  899. {
  900. Name: "4",
  901. Peer: wireguard.Peer{
  902. PublicKey: []byte("key4"),
  903. },
  904. },
  905. },
  906. },
  907. {
  908. name: "one duplicates itself",
  909. peers: []*Peer{p4, p1},
  910. out: []*Peer{
  911. {
  912. Name: "4",
  913. Peer: wireguard.Peer{
  914. PublicKey: []byte("key4"),
  915. AllowedIPs: []*net.IPNet{
  916. {IP: net.ParseIP("10.0.0.3"), Mask: net.CIDRMask(24, 32)},
  917. },
  918. },
  919. },
  920. {
  921. Name: "1",
  922. Peer: wireguard.Peer{
  923. PublicKey: []byte("key1"),
  924. AllowedIPs: []*net.IPNet{
  925. {IP: net.ParseIP("10.0.0.1"), Mask: net.CIDRMask(24, 32)},
  926. {IP: net.ParseIP("10.0.0.2"), Mask: net.CIDRMask(24, 32)},
  927. },
  928. },
  929. },
  930. },
  931. },
  932. } {
  933. out := deduplicatePeerIPs(tc.peers)
  934. if diff := pretty.Compare(out, tc.out); diff != "" {
  935. t.Errorf("test case %q: got diff: %v", tc.name, diff)
  936. }
  937. }
  938. }
  939. func TestFilterAllowedIPs(t *testing.T) {
  940. nodes, peers, key, port := setup(t)
  941. topo := mustTopo(t, nodes, peers, LogicalGranularity, nodes["a"].Name, port, key, DefaultKiloSubnet, nodes["a"].PersistentKeepalive)
  942. for _, tc := range []struct {
  943. name string
  944. allowedLocationIPs map[int][]*net.IPNet
  945. result map[int][]*net.IPNet
  946. }{
  947. {
  948. name: "nothing to filter",
  949. allowedLocationIPs: map[int][]*net.IPNet{
  950. 0: {
  951. mustParseCIDR("192.168.178.4/32"),
  952. },
  953. 1: {
  954. mustParseCIDR("192.168.178.5/32"),
  955. },
  956. 2: {
  957. mustParseCIDR("192.168.178.6/32"),
  958. mustParseCIDR("192.168.178.7/32"),
  959. },
  960. },
  961. result: map[int][]*net.IPNet{
  962. 0: {
  963. mustParseCIDR("192.168.178.4/32"),
  964. },
  965. 1: {
  966. mustParseCIDR("192.168.178.5/32"),
  967. },
  968. 2: {
  969. mustParseCIDR("192.168.178.6/32"),
  970. mustParseCIDR("192.168.178.7/32"),
  971. },
  972. },
  973. },
  974. {
  975. name: "intersections between segments",
  976. allowedLocationIPs: map[int][]*net.IPNet{
  977. 0: {
  978. mustParseCIDR("192.168.178.4/32"),
  979. mustParseCIDR("192.168.178.8/32"),
  980. },
  981. 1: {
  982. mustParseCIDR("192.168.178.5/32"),
  983. },
  984. 2: {
  985. mustParseCIDR("192.168.178.6/32"),
  986. mustParseCIDR("192.168.178.7/32"),
  987. mustParseCIDR("192.168.178.4/32"),
  988. },
  989. },
  990. result: map[int][]*net.IPNet{
  991. 0: {
  992. mustParseCIDR("192.168.178.8/32"),
  993. },
  994. 1: {
  995. mustParseCIDR("192.168.178.5/32"),
  996. },
  997. 2: {
  998. mustParseCIDR("192.168.178.6/32"),
  999. mustParseCIDR("192.168.178.7/32"),
  1000. mustParseCIDR("192.168.178.4/32"),
  1001. },
  1002. },
  1003. },
  1004. {
  1005. name: "intersections with wireGuardCIDR",
  1006. allowedLocationIPs: map[int][]*net.IPNet{
  1007. 0: {
  1008. mustParseCIDR("10.4.0.1/32"),
  1009. mustParseCIDR("192.168.178.8/32"),
  1010. },
  1011. 1: {
  1012. mustParseCIDR("192.168.178.5/32"),
  1013. },
  1014. 2: {
  1015. mustParseCIDR("192.168.178.6/32"),
  1016. mustParseCIDR("192.168.178.7/32"),
  1017. },
  1018. },
  1019. result: map[int][]*net.IPNet{
  1020. 0: {
  1021. mustParseCIDR("192.168.178.8/32"),
  1022. },
  1023. 1: {
  1024. mustParseCIDR("192.168.178.5/32"),
  1025. },
  1026. 2: {
  1027. mustParseCIDR("192.168.178.6/32"),
  1028. mustParseCIDR("192.168.178.7/32"),
  1029. },
  1030. },
  1031. },
  1032. {
  1033. name: "intersections with more than one allowedLocationIPs",
  1034. allowedLocationIPs: map[int][]*net.IPNet{
  1035. 0: {
  1036. mustParseCIDR("192.168.178.8/32"),
  1037. },
  1038. 1: {
  1039. mustParseCIDR("192.168.178.5/32"),
  1040. },
  1041. 2: {
  1042. mustParseCIDR("192.168.178.7/24"),
  1043. },
  1044. },
  1045. result: map[int][]*net.IPNet{
  1046. 0: {},
  1047. 1: {},
  1048. 2: {
  1049. mustParseCIDR("192.168.178.7/24"),
  1050. },
  1051. },
  1052. },
  1053. } {
  1054. for k, v := range tc.allowedLocationIPs {
  1055. topo.segments[k].allowedLocationIPs = v
  1056. }
  1057. for k, v := range topo.segments {
  1058. f := topo.filterAllowedLocationIPs(v.allowedLocationIPs, v.location)
  1059. // Overwrite the allowedLocationIPs to mimic the actual usage of the filterAllowedLocationIPs function.
  1060. topo.segments[k].allowedLocationIPs = f
  1061. if !ipNetSlicesEqual(f, tc.result[k]) {
  1062. t.Errorf("test case %q:\n\texpected:\n\t%q\n\tgot:\n\t%q\n", tc.name, tc.result[k], f)
  1063. }
  1064. }
  1065. }
  1066. }