topology_test.go 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955
  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/kylelemons/godebug/pretty"
  20. "github.com/squat/kilo/pkg/wireguard"
  21. )
  22. func allowedIPs(ips ...string) string {
  23. return strings.Join(ips, ", ")
  24. }
  25. func setup(t *testing.T) (map[string]*Node, map[string]*Peer, []byte, uint32) {
  26. key := []byte("private")
  27. e1 := &net.IPNet{IP: net.ParseIP("10.1.0.1").To4(), Mask: net.CIDRMask(16, 32)}
  28. e2 := &net.IPNet{IP: net.ParseIP("10.1.0.2").To4(), Mask: net.CIDRMask(16, 32)}
  29. e3 := &net.IPNet{IP: net.ParseIP("10.1.0.3").To4(), Mask: net.CIDRMask(16, 32)}
  30. e4 := &net.IPNet{IP: net.ParseIP("10.1.0.4").To4(), Mask: net.CIDRMask(16, 32)}
  31. i1 := &net.IPNet{IP: net.ParseIP("192.168.0.1").To4(), Mask: net.CIDRMask(32, 32)}
  32. i2 := &net.IPNet{IP: net.ParseIP("192.168.0.2").To4(), Mask: net.CIDRMask(32, 32)}
  33. nodes := map[string]*Node{
  34. "a": {
  35. Name: "a",
  36. Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e1.IP}, Port: DefaultKiloPort},
  37. InternalIP: i1,
  38. Location: "1",
  39. Subnet: &net.IPNet{IP: net.ParseIP("10.2.1.0"), Mask: net.CIDRMask(24, 32)},
  40. Key: []byte("key1"),
  41. PersistentKeepalive: 25,
  42. },
  43. "b": {
  44. Name: "b",
  45. Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e2.IP}, Port: DefaultKiloPort},
  46. InternalIP: i1,
  47. Location: "2",
  48. Subnet: &net.IPNet{IP: net.ParseIP("10.2.2.0"), Mask: net.CIDRMask(24, 32)},
  49. Key: []byte("key2"),
  50. },
  51. "c": {
  52. Name: "c",
  53. Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e3.IP}, Port: DefaultKiloPort},
  54. InternalIP: i2,
  55. // Same location as node b.
  56. Location: "2",
  57. Subnet: &net.IPNet{IP: net.ParseIP("10.2.3.0"), Mask: net.CIDRMask(24, 32)},
  58. Key: []byte("key3"),
  59. },
  60. "d": {
  61. Name: "d",
  62. Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e4.IP}, Port: DefaultKiloPort},
  63. // Same location as node a, but without private IP
  64. Location: "1",
  65. Subnet: &net.IPNet{IP: net.ParseIP("10.2.4.0"), Mask: net.CIDRMask(24, 32)},
  66. Key: []byte("key4"),
  67. },
  68. }
  69. peers := map[string]*Peer{
  70. "a": {
  71. Name: "a",
  72. Peer: wireguard.Peer{
  73. AllowedIPs: []*net.IPNet{
  74. {IP: net.ParseIP("10.5.0.1"), Mask: net.CIDRMask(24, 32)},
  75. {IP: net.ParseIP("10.5.0.2"), Mask: net.CIDRMask(24, 32)},
  76. },
  77. PublicKey: []byte("key4"),
  78. },
  79. },
  80. "b": {
  81. Name: "b",
  82. Peer: wireguard.Peer{
  83. AllowedIPs: []*net.IPNet{
  84. {IP: net.ParseIP("10.5.0.3"), Mask: net.CIDRMask(24, 32)},
  85. },
  86. Endpoint: &wireguard.Endpoint{
  87. DNSOrIP: wireguard.DNSOrIP{IP: net.ParseIP("192.168.0.1")},
  88. Port: DefaultKiloPort,
  89. },
  90. PublicKey: []byte("key5"),
  91. },
  92. },
  93. }
  94. return nodes, peers, key, DefaultKiloPort
  95. }
  96. func TestNewTopology(t *testing.T) {
  97. nodes, peers, key, port := setup(t)
  98. w1 := net.ParseIP("10.4.0.1").To4()
  99. w2 := net.ParseIP("10.4.0.2").To4()
  100. w3 := net.ParseIP("10.4.0.3").To4()
  101. w4 := net.ParseIP("10.4.0.4").To4()
  102. for _, tc := range []struct {
  103. name string
  104. granularity Granularity
  105. hostname string
  106. result *Topology
  107. }{
  108. {
  109. name: "logical from a",
  110. granularity: LogicalGranularity,
  111. hostname: nodes["a"].Name,
  112. result: &Topology{
  113. hostname: nodes["a"].Name,
  114. leader: true,
  115. location: logicalLocationPrefix + nodes["a"].Location,
  116. subnet: nodes["a"].Subnet,
  117. privateIP: nodes["a"].InternalIP,
  118. wireGuardCIDR: &net.IPNet{IP: w1, Mask: net.CIDRMask(16, 32)},
  119. segments: []*segment{
  120. {
  121. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  122. endpoint: nodes["a"].Endpoint,
  123. key: nodes["a"].Key,
  124. persistentKeepalive: nodes["a"].PersistentKeepalive,
  125. location: logicalLocationPrefix + nodes["a"].Location,
  126. cidrs: []*net.IPNet{nodes["a"].Subnet},
  127. hostnames: []string{"a"},
  128. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  129. wireGuardIP: w1,
  130. },
  131. {
  132. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  133. endpoint: nodes["b"].Endpoint,
  134. key: nodes["b"].Key,
  135. persistentKeepalive: nodes["b"].PersistentKeepalive,
  136. location: logicalLocationPrefix + nodes["b"].Location,
  137. cidrs: []*net.IPNet{nodes["b"].Subnet, nodes["c"].Subnet},
  138. hostnames: []string{"b", "c"},
  139. privateIPs: []net.IP{nodes["b"].InternalIP.IP, nodes["c"].InternalIP.IP},
  140. wireGuardIP: w2,
  141. },
  142. {
  143. allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w3, Mask: net.CIDRMask(32, 32)}},
  144. endpoint: nodes["d"].Endpoint,
  145. key: nodes["d"].Key,
  146. persistentKeepalive: nodes["d"].PersistentKeepalive,
  147. location: nodeLocationPrefix + nodes["d"].Name,
  148. cidrs: []*net.IPNet{nodes["d"].Subnet},
  149. hostnames: []string{"d"},
  150. privateIPs: nil,
  151. wireGuardIP: w3,
  152. },
  153. },
  154. peers: []*Peer{peers["a"], peers["b"]},
  155. },
  156. },
  157. {
  158. name: "logical from b",
  159. granularity: LogicalGranularity,
  160. hostname: nodes["b"].Name,
  161. result: &Topology{
  162. hostname: nodes["b"].Name,
  163. leader: true,
  164. location: logicalLocationPrefix + nodes["b"].Location,
  165. subnet: nodes["b"].Subnet,
  166. privateIP: nodes["b"].InternalIP,
  167. wireGuardCIDR: &net.IPNet{IP: w2, Mask: net.CIDRMask(16, 32)},
  168. segments: []*segment{
  169. {
  170. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  171. endpoint: nodes["a"].Endpoint,
  172. key: nodes["a"].Key,
  173. persistentKeepalive: nodes["a"].PersistentKeepalive,
  174. location: logicalLocationPrefix + nodes["a"].Location,
  175. cidrs: []*net.IPNet{nodes["a"].Subnet},
  176. hostnames: []string{"a"},
  177. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  178. wireGuardIP: w1,
  179. },
  180. {
  181. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  182. endpoint: nodes["b"].Endpoint,
  183. key: nodes["b"].Key,
  184. persistentKeepalive: nodes["b"].PersistentKeepalive,
  185. location: logicalLocationPrefix + nodes["b"].Location,
  186. cidrs: []*net.IPNet{nodes["b"].Subnet, nodes["c"].Subnet},
  187. hostnames: []string{"b", "c"},
  188. privateIPs: []net.IP{nodes["b"].InternalIP.IP, nodes["c"].InternalIP.IP},
  189. wireGuardIP: w2,
  190. },
  191. {
  192. allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w3, Mask: net.CIDRMask(32, 32)}},
  193. endpoint: nodes["d"].Endpoint,
  194. key: nodes["d"].Key,
  195. persistentKeepalive: nodes["d"].PersistentKeepalive,
  196. location: nodeLocationPrefix + nodes["d"].Name,
  197. cidrs: []*net.IPNet{nodes["d"].Subnet},
  198. hostnames: []string{"d"},
  199. privateIPs: nil,
  200. wireGuardIP: w3,
  201. },
  202. },
  203. peers: []*Peer{peers["a"], peers["b"]},
  204. },
  205. },
  206. {
  207. name: "logical from c",
  208. granularity: LogicalGranularity,
  209. hostname: nodes["c"].Name,
  210. result: &Topology{
  211. hostname: nodes["c"].Name,
  212. leader: false,
  213. location: logicalLocationPrefix + nodes["b"].Location,
  214. subnet: nodes["c"].Subnet,
  215. privateIP: nodes["c"].InternalIP,
  216. wireGuardCIDR: DefaultKiloSubnet,
  217. segments: []*segment{
  218. {
  219. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  220. endpoint: nodes["a"].Endpoint,
  221. key: nodes["a"].Key,
  222. persistentKeepalive: nodes["a"].PersistentKeepalive,
  223. location: logicalLocationPrefix + nodes["a"].Location,
  224. cidrs: []*net.IPNet{nodes["a"].Subnet},
  225. hostnames: []string{"a"},
  226. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  227. wireGuardIP: w1,
  228. },
  229. {
  230. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  231. endpoint: nodes["b"].Endpoint,
  232. key: nodes["b"].Key,
  233. persistentKeepalive: nodes["b"].PersistentKeepalive,
  234. location: logicalLocationPrefix + nodes["b"].Location,
  235. cidrs: []*net.IPNet{nodes["b"].Subnet, nodes["c"].Subnet},
  236. hostnames: []string{"b", "c"},
  237. privateIPs: []net.IP{nodes["b"].InternalIP.IP, nodes["c"].InternalIP.IP},
  238. wireGuardIP: w2,
  239. },
  240. {
  241. allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w3, Mask: net.CIDRMask(32, 32)}},
  242. endpoint: nodes["d"].Endpoint,
  243. key: nodes["d"].Key,
  244. persistentKeepalive: nodes["d"].PersistentKeepalive,
  245. location: nodeLocationPrefix + nodes["d"].Name,
  246. cidrs: []*net.IPNet{nodes["d"].Subnet},
  247. hostnames: []string{"d"},
  248. privateIPs: nil,
  249. wireGuardIP: w3,
  250. },
  251. },
  252. peers: []*Peer{peers["a"], peers["b"]},
  253. },
  254. },
  255. {
  256. name: "full from a",
  257. granularity: FullGranularity,
  258. hostname: nodes["a"].Name,
  259. result: &Topology{
  260. hostname: nodes["a"].Name,
  261. leader: true,
  262. location: nodeLocationPrefix + nodes["a"].Name,
  263. subnet: nodes["a"].Subnet,
  264. privateIP: nodes["a"].InternalIP,
  265. wireGuardCIDR: &net.IPNet{IP: w1, Mask: net.CIDRMask(16, 32)},
  266. segments: []*segment{
  267. {
  268. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  269. endpoint: nodes["a"].Endpoint,
  270. key: nodes["a"].Key,
  271. persistentKeepalive: nodes["a"].PersistentKeepalive,
  272. location: nodeLocationPrefix + nodes["a"].Name,
  273. cidrs: []*net.IPNet{nodes["a"].Subnet},
  274. hostnames: []string{"a"},
  275. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  276. wireGuardIP: w1,
  277. },
  278. {
  279. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  280. endpoint: nodes["b"].Endpoint,
  281. key: nodes["b"].Key,
  282. persistentKeepalive: nodes["b"].PersistentKeepalive,
  283. location: nodeLocationPrefix + nodes["b"].Name,
  284. cidrs: []*net.IPNet{nodes["b"].Subnet},
  285. hostnames: []string{"b"},
  286. privateIPs: []net.IP{nodes["b"].InternalIP.IP},
  287. wireGuardIP: w2,
  288. },
  289. {
  290. allowedIPs: []*net.IPNet{nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
  291. endpoint: nodes["c"].Endpoint,
  292. key: nodes["c"].Key,
  293. persistentKeepalive: nodes["c"].PersistentKeepalive,
  294. location: nodeLocationPrefix + nodes["c"].Name,
  295. cidrs: []*net.IPNet{nodes["c"].Subnet},
  296. hostnames: []string{"c"},
  297. privateIPs: []net.IP{nodes["c"].InternalIP.IP},
  298. wireGuardIP: w3,
  299. },
  300. {
  301. allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w4, Mask: net.CIDRMask(32, 32)}},
  302. endpoint: nodes["d"].Endpoint,
  303. key: nodes["d"].Key,
  304. persistentKeepalive: nodes["d"].PersistentKeepalive,
  305. location: nodeLocationPrefix + nodes["d"].Name,
  306. cidrs: []*net.IPNet{nodes["d"].Subnet},
  307. hostnames: []string{"d"},
  308. privateIPs: nil,
  309. wireGuardIP: w4,
  310. },
  311. },
  312. peers: []*Peer{peers["a"], peers["b"]},
  313. },
  314. },
  315. {
  316. name: "full from b",
  317. granularity: FullGranularity,
  318. hostname: nodes["b"].Name,
  319. result: &Topology{
  320. hostname: nodes["b"].Name,
  321. leader: true,
  322. location: nodeLocationPrefix + nodes["b"].Name,
  323. subnet: nodes["b"].Subnet,
  324. privateIP: nodes["b"].InternalIP,
  325. wireGuardCIDR: &net.IPNet{IP: w2, Mask: net.CIDRMask(16, 32)},
  326. segments: []*segment{
  327. {
  328. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  329. endpoint: nodes["a"].Endpoint,
  330. key: nodes["a"].Key,
  331. persistentKeepalive: nodes["a"].PersistentKeepalive,
  332. location: nodeLocationPrefix + nodes["a"].Name,
  333. cidrs: []*net.IPNet{nodes["a"].Subnet},
  334. hostnames: []string{"a"},
  335. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  336. wireGuardIP: w1,
  337. },
  338. {
  339. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  340. endpoint: nodes["b"].Endpoint,
  341. key: nodes["b"].Key,
  342. persistentKeepalive: nodes["b"].PersistentKeepalive,
  343. location: nodeLocationPrefix + nodes["b"].Name,
  344. cidrs: []*net.IPNet{nodes["b"].Subnet},
  345. hostnames: []string{"b"},
  346. privateIPs: []net.IP{nodes["b"].InternalIP.IP},
  347. wireGuardIP: w2,
  348. },
  349. {
  350. allowedIPs: []*net.IPNet{nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
  351. endpoint: nodes["c"].Endpoint,
  352. key: nodes["c"].Key,
  353. persistentKeepalive: nodes["c"].PersistentKeepalive,
  354. location: nodeLocationPrefix + nodes["c"].Name,
  355. cidrs: []*net.IPNet{nodes["c"].Subnet},
  356. hostnames: []string{"c"},
  357. privateIPs: []net.IP{nodes["c"].InternalIP.IP},
  358. wireGuardIP: w3,
  359. },
  360. {
  361. allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w4, Mask: net.CIDRMask(32, 32)}},
  362. endpoint: nodes["d"].Endpoint,
  363. key: nodes["d"].Key,
  364. persistentKeepalive: nodes["d"].PersistentKeepalive,
  365. location: nodeLocationPrefix + nodes["d"].Name,
  366. cidrs: []*net.IPNet{nodes["d"].Subnet},
  367. hostnames: []string{"d"},
  368. privateIPs: nil,
  369. wireGuardIP: w4,
  370. },
  371. },
  372. peers: []*Peer{peers["a"], peers["b"]},
  373. },
  374. },
  375. {
  376. name: "full from c",
  377. granularity: FullGranularity,
  378. hostname: nodes["c"].Name,
  379. result: &Topology{
  380. hostname: nodes["c"].Name,
  381. leader: true,
  382. location: nodeLocationPrefix + nodes["c"].Name,
  383. subnet: nodes["c"].Subnet,
  384. privateIP: nodes["c"].InternalIP,
  385. wireGuardCIDR: &net.IPNet{IP: w3, Mask: net.CIDRMask(16, 32)},
  386. segments: []*segment{
  387. {
  388. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  389. endpoint: nodes["a"].Endpoint,
  390. key: nodes["a"].Key,
  391. persistentKeepalive: nodes["a"].PersistentKeepalive,
  392. location: nodeLocationPrefix + nodes["a"].Name,
  393. cidrs: []*net.IPNet{nodes["a"].Subnet},
  394. hostnames: []string{"a"},
  395. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  396. wireGuardIP: w1,
  397. },
  398. {
  399. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  400. endpoint: nodes["b"].Endpoint,
  401. key: nodes["b"].Key,
  402. persistentKeepalive: nodes["b"].PersistentKeepalive,
  403. location: nodeLocationPrefix + nodes["b"].Name,
  404. cidrs: []*net.IPNet{nodes["b"].Subnet},
  405. hostnames: []string{"b"},
  406. privateIPs: []net.IP{nodes["b"].InternalIP.IP},
  407. wireGuardIP: w2,
  408. },
  409. {
  410. allowedIPs: []*net.IPNet{nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
  411. endpoint: nodes["c"].Endpoint,
  412. key: nodes["c"].Key,
  413. persistentKeepalive: nodes["c"].PersistentKeepalive,
  414. location: nodeLocationPrefix + nodes["c"].Name,
  415. cidrs: []*net.IPNet{nodes["c"].Subnet},
  416. hostnames: []string{"c"},
  417. privateIPs: []net.IP{nodes["c"].InternalIP.IP},
  418. wireGuardIP: w3,
  419. },
  420. {
  421. allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w4, Mask: net.CIDRMask(32, 32)}},
  422. endpoint: nodes["d"].Endpoint,
  423. key: nodes["d"].Key,
  424. persistentKeepalive: nodes["d"].PersistentKeepalive,
  425. location: nodeLocationPrefix + nodes["d"].Name,
  426. cidrs: []*net.IPNet{nodes["d"].Subnet},
  427. hostnames: []string{"d"},
  428. privateIPs: nil,
  429. wireGuardIP: w4,
  430. },
  431. },
  432. peers: []*Peer{peers["a"], peers["b"]},
  433. },
  434. },
  435. {
  436. name: "full from d",
  437. granularity: FullGranularity,
  438. hostname: nodes["d"].Name,
  439. result: &Topology{
  440. hostname: nodes["d"].Name,
  441. leader: true,
  442. location: nodeLocationPrefix + nodes["d"].Name,
  443. subnet: nodes["d"].Subnet,
  444. privateIP: nil,
  445. wireGuardCIDR: &net.IPNet{IP: w4, Mask: net.CIDRMask(16, 32)},
  446. segments: []*segment{
  447. {
  448. allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
  449. endpoint: nodes["a"].Endpoint,
  450. key: nodes["a"].Key,
  451. persistentKeepalive: nodes["a"].PersistentKeepalive,
  452. location: nodeLocationPrefix + nodes["a"].Name,
  453. cidrs: []*net.IPNet{nodes["a"].Subnet},
  454. hostnames: []string{"a"},
  455. privateIPs: []net.IP{nodes["a"].InternalIP.IP},
  456. wireGuardIP: w1,
  457. },
  458. {
  459. allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
  460. endpoint: nodes["b"].Endpoint,
  461. key: nodes["b"].Key,
  462. persistentKeepalive: nodes["b"].PersistentKeepalive,
  463. location: nodeLocationPrefix + nodes["b"].Name,
  464. cidrs: []*net.IPNet{nodes["b"].Subnet},
  465. hostnames: []string{"b"},
  466. privateIPs: []net.IP{nodes["b"].InternalIP.IP},
  467. wireGuardIP: w2,
  468. },
  469. {
  470. allowedIPs: []*net.IPNet{nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
  471. endpoint: nodes["c"].Endpoint,
  472. key: nodes["c"].Key,
  473. persistentKeepalive: nodes["c"].PersistentKeepalive,
  474. location: nodeLocationPrefix + nodes["c"].Name,
  475. cidrs: []*net.IPNet{nodes["c"].Subnet},
  476. hostnames: []string{"c"},
  477. privateIPs: []net.IP{nodes["c"].InternalIP.IP},
  478. wireGuardIP: w3,
  479. },
  480. {
  481. allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w4, Mask: net.CIDRMask(32, 32)}},
  482. endpoint: nodes["d"].Endpoint,
  483. key: nodes["d"].Key,
  484. persistentKeepalive: nodes["d"].PersistentKeepalive,
  485. location: nodeLocationPrefix + nodes["d"].Name,
  486. cidrs: []*net.IPNet{nodes["d"].Subnet},
  487. hostnames: []string{"d"},
  488. privateIPs: nil,
  489. wireGuardIP: w4,
  490. },
  491. },
  492. peers: []*Peer{peers["a"], peers["b"]},
  493. },
  494. },
  495. } {
  496. tc.result.key = key
  497. tc.result.port = port
  498. topo, err := NewTopology(nodes, peers, tc.granularity, tc.hostname, port, key, DefaultKiloSubnet, 0)
  499. if err != nil {
  500. t.Errorf("test case %q: failed to generate Topology: %v", tc.name, err)
  501. }
  502. if diff := pretty.Compare(topo, tc.result); diff != "" {
  503. t.Errorf("test case %q: got diff: %v", tc.name, diff)
  504. }
  505. }
  506. }
  507. 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 {
  508. topo, err := NewTopology(nodes, peers, granularity, hostname, port, key, subnet, persistentKeepalive)
  509. if err != nil {
  510. t.Errorf("failed to generate Topology: %v", err)
  511. }
  512. return topo
  513. }
  514. func TestConf(t *testing.T) {
  515. nodes, peers, key, port := setup(t)
  516. for _, tc := range []struct {
  517. name string
  518. topology *Topology
  519. result string
  520. }{
  521. {
  522. name: "logical from a",
  523. topology: mustTopo(t, nodes, peers, LogicalGranularity, nodes["a"].Name, port, key, DefaultKiloSubnet, nodes["a"].PersistentKeepalive),
  524. result: `[Interface]
  525. PrivateKey = private
  526. ListenPort = 51820
  527. [Peer]
  528. PublicKey = key2
  529. Endpoint = 10.1.0.2:51820
  530. 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
  531. PersistentKeepalive = 25
  532. [Peer]
  533. PublicKey = key4
  534. Endpoint = 10.1.0.4:51820
  535. AllowedIPs = 10.2.4.0/24, 10.4.0.3/32
  536. PersistentKeepalive = 25
  537. [Peer]
  538. PublicKey = key4
  539. AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
  540. PersistentKeepalive = 25
  541. [Peer]
  542. PublicKey = key5
  543. Endpoint = 192.168.0.1:51820
  544. AllowedIPs = 10.5.0.3/24
  545. PersistentKeepalive = 25
  546. `,
  547. },
  548. {
  549. name: "logical from b",
  550. topology: mustTopo(t, nodes, peers, LogicalGranularity, nodes["b"].Name, port, key, DefaultKiloSubnet, nodes["b"].PersistentKeepalive),
  551. result: `[Interface]
  552. PrivateKey = private
  553. ListenPort = 51820
  554. [Peer]
  555. PublicKey = key1
  556. Endpoint = 10.1.0.1:51820
  557. AllowedIPs = 10.2.1.0/24, 192.168.0.1/32, 10.4.0.1/32
  558. [Peer]
  559. PublicKey = key4
  560. Endpoint = 10.1.0.4:51820
  561. AllowedIPs = 10.2.4.0/24, 10.4.0.3/32
  562. [Peer]
  563. PublicKey = key4
  564. AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
  565. [Peer]
  566. PublicKey = key5
  567. Endpoint = 192.168.0.1:51820
  568. AllowedIPs = 10.5.0.3/24
  569. `,
  570. },
  571. {
  572. name: "logical from c",
  573. topology: mustTopo(t, nodes, peers, LogicalGranularity, nodes["c"].Name, port, key, DefaultKiloSubnet, nodes["c"].PersistentKeepalive),
  574. result: `[Interface]
  575. PrivateKey = private
  576. ListenPort = 51820
  577. [Peer]
  578. PublicKey = key1
  579. Endpoint = 10.1.0.1:51820
  580. AllowedIPs = 10.2.1.0/24, 192.168.0.1/32, 10.4.0.1/32
  581. [Peer]
  582. PublicKey = key4
  583. Endpoint = 10.1.0.4:51820
  584. AllowedIPs = 10.2.4.0/24, 10.4.0.3/32
  585. [Peer]
  586. PublicKey = key4
  587. AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
  588. [Peer]
  589. PublicKey = key5
  590. Endpoint = 192.168.0.1:51820
  591. AllowedIPs = 10.5.0.3/24
  592. `,
  593. },
  594. {
  595. name: "full from a",
  596. topology: mustTopo(t, nodes, peers, FullGranularity, nodes["a"].Name, port, key, DefaultKiloSubnet, nodes["a"].PersistentKeepalive),
  597. result: `[Interface]
  598. PrivateKey = private
  599. ListenPort = 51820
  600. [Peer]
  601. PublicKey = key2
  602. Endpoint = 10.1.0.2:51820
  603. AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.4.0.2/32
  604. PersistentKeepalive = 25
  605. [Peer]
  606. PublicKey = key3
  607. Endpoint = 10.1.0.3:51820
  608. AllowedIPs = 10.2.3.0/24, 192.168.0.2/32, 10.4.0.3/32
  609. PersistentKeepalive = 25
  610. [Peer]
  611. PublicKey = key4
  612. Endpoint = 10.1.0.4:51820
  613. AllowedIPs = 10.2.4.0/24, 10.4.0.4/32
  614. PersistentKeepalive = 25
  615. [Peer]
  616. PublicKey = key4
  617. AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
  618. PersistentKeepalive = 25
  619. [Peer]
  620. PublicKey = key5
  621. Endpoint = 192.168.0.1:51820
  622. AllowedIPs = 10.5.0.3/24
  623. PersistentKeepalive = 25
  624. `,
  625. },
  626. {
  627. name: "full from b",
  628. topology: mustTopo(t, nodes, peers, FullGranularity, nodes["b"].Name, port, key, DefaultKiloSubnet, nodes["b"].PersistentKeepalive),
  629. result: `[Interface]
  630. PrivateKey = private
  631. ListenPort = 51820
  632. [Peer]
  633. PublicKey = key1
  634. Endpoint = 10.1.0.1:51820
  635. AllowedIPs = 10.2.1.0/24, 192.168.0.1/32, 10.4.0.1/32
  636. [Peer]
  637. PublicKey = key3
  638. Endpoint = 10.1.0.3:51820
  639. AllowedIPs = 10.2.3.0/24, 192.168.0.2/32, 10.4.0.3/32
  640. [Peer]
  641. PublicKey = key4
  642. Endpoint = 10.1.0.4:51820
  643. AllowedIPs = 10.2.4.0/24, 10.4.0.4/32
  644. [Peer]
  645. PublicKey = key4
  646. AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
  647. [Peer]
  648. PublicKey = key5
  649. Endpoint = 192.168.0.1:51820
  650. AllowedIPs = 10.5.0.3/24
  651. `,
  652. },
  653. {
  654. name: "full from c",
  655. topology: mustTopo(t, nodes, peers, FullGranularity, nodes["c"].Name, port, key, DefaultKiloSubnet, nodes["c"].PersistentKeepalive),
  656. result: `[Interface]
  657. PrivateKey = private
  658. ListenPort = 51820
  659. [Peer]
  660. PublicKey = key1
  661. Endpoint = 10.1.0.1:51820
  662. AllowedIPs = 10.2.1.0/24, 192.168.0.1/32, 10.4.0.1/32
  663. [Peer]
  664. PublicKey = key2
  665. Endpoint = 10.1.0.2:51820
  666. AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.4.0.2/32
  667. [Peer]
  668. PublicKey = key4
  669. Endpoint = 10.1.0.4:51820
  670. AllowedIPs = 10.2.4.0/24, 10.4.0.4/32
  671. [Peer]
  672. PublicKey = key4
  673. AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
  674. [Peer]
  675. PublicKey = key5
  676. Endpoint = 192.168.0.1:51820
  677. AllowedIPs = 10.5.0.3/24
  678. `,
  679. },
  680. } {
  681. conf := tc.topology.Conf()
  682. if !conf.Equal(wireguard.Parse([]byte(tc.result))) {
  683. buf, err := conf.Bytes()
  684. if err != nil {
  685. t.Errorf("test case %q: failed to render conf: %v", tc.name, err)
  686. }
  687. t.Errorf("test case %q: expected %s got %s", tc.name, tc.result, string(buf))
  688. }
  689. }
  690. }
  691. func TestFindLeader(t *testing.T) {
  692. ip, e1, err := net.ParseCIDR("10.0.0.1/32")
  693. if err != nil {
  694. t.Fatalf("failed to parse external IP CIDR: %v", err)
  695. }
  696. e1.IP = ip
  697. ip, e2, err := net.ParseCIDR("8.8.8.8/32")
  698. if err != nil {
  699. t.Fatalf("failed to parse external IP CIDR: %v", err)
  700. }
  701. e2.IP = ip
  702. nodes := []*Node{
  703. {
  704. Name: "a",
  705. Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e1.IP}, Port: DefaultKiloPort},
  706. },
  707. {
  708. Name: "b",
  709. Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e2.IP}, Port: DefaultKiloPort},
  710. },
  711. {
  712. Name: "c",
  713. Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e2.IP}, Port: DefaultKiloPort},
  714. },
  715. {
  716. Name: "d",
  717. Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e1.IP}, Port: DefaultKiloPort},
  718. Leader: true,
  719. },
  720. {
  721. Name: "2",
  722. Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e2.IP}, Port: DefaultKiloPort},
  723. Leader: true,
  724. },
  725. }
  726. for _, tc := range []struct {
  727. name string
  728. nodes []*Node
  729. out int
  730. }{
  731. {
  732. name: "nil",
  733. nodes: nil,
  734. out: 0,
  735. },
  736. {
  737. name: "one",
  738. nodes: []*Node{nodes[0]},
  739. out: 0,
  740. },
  741. {
  742. name: "non-leaders",
  743. nodes: []*Node{nodes[0], nodes[1], nodes[2]},
  744. out: 1,
  745. },
  746. {
  747. name: "leaders",
  748. nodes: []*Node{nodes[3], nodes[4]},
  749. out: 1,
  750. },
  751. {
  752. name: "public",
  753. nodes: []*Node{nodes[1], nodes[2], nodes[4]},
  754. out: 2,
  755. },
  756. {
  757. name: "private",
  758. nodes: []*Node{nodes[0], nodes[3]},
  759. out: 1,
  760. },
  761. {
  762. name: "all",
  763. nodes: nodes,
  764. out: 4,
  765. },
  766. } {
  767. l := findLeader(tc.nodes)
  768. if l != tc.out {
  769. t.Errorf("test case %q: expected %d got %d", tc.name, tc.out, l)
  770. }
  771. }
  772. }
  773. func TestDeduplicatePeerIPs(t *testing.T) {
  774. p1 := &Peer{
  775. Name: "1",
  776. Peer: wireguard.Peer{
  777. PublicKey: []byte("key1"),
  778. AllowedIPs: []*net.IPNet{
  779. {IP: net.ParseIP("10.0.0.1"), Mask: net.CIDRMask(24, 32)},
  780. {IP: net.ParseIP("10.0.0.2"), Mask: net.CIDRMask(24, 32)},
  781. },
  782. },
  783. }
  784. p2 := &Peer{
  785. Name: "2",
  786. Peer: wireguard.Peer{
  787. PublicKey: []byte("key2"),
  788. AllowedIPs: []*net.IPNet{
  789. {IP: net.ParseIP("10.0.0.1"), Mask: net.CIDRMask(24, 32)},
  790. {IP: net.ParseIP("10.0.0.3"), Mask: net.CIDRMask(24, 32)},
  791. },
  792. },
  793. }
  794. p3 := &Peer{
  795. Name: "3",
  796. Peer: wireguard.Peer{
  797. PublicKey: []byte("key3"),
  798. AllowedIPs: []*net.IPNet{
  799. {IP: net.ParseIP("10.0.0.2"), Mask: net.CIDRMask(24, 32)},
  800. {IP: net.ParseIP("10.0.0.3"), Mask: net.CIDRMask(24, 32)},
  801. {IP: net.ParseIP("10.0.0.1"), Mask: net.CIDRMask(24, 32)},
  802. },
  803. },
  804. }
  805. p4 := &Peer{
  806. Name: "4",
  807. Peer: wireguard.Peer{
  808. PublicKey: []byte("key4"),
  809. AllowedIPs: []*net.IPNet{
  810. {IP: net.ParseIP("10.0.0.3"), Mask: net.CIDRMask(24, 32)},
  811. {IP: net.ParseIP("10.0.0.3"), Mask: net.CIDRMask(24, 32)},
  812. },
  813. },
  814. }
  815. for _, tc := range []struct {
  816. name string
  817. peers []*Peer
  818. out []*Peer
  819. }{
  820. {
  821. name: "nil",
  822. peers: nil,
  823. out: nil,
  824. },
  825. {
  826. name: "simple dupe",
  827. peers: []*Peer{p1, p2},
  828. out: []*Peer{
  829. p1,
  830. {
  831. Name: "2",
  832. Peer: wireguard.Peer{
  833. PublicKey: []byte("key2"),
  834. AllowedIPs: []*net.IPNet{
  835. {IP: net.ParseIP("10.0.0.3"), Mask: net.CIDRMask(24, 32)},
  836. },
  837. },
  838. },
  839. },
  840. },
  841. {
  842. name: "simple dupe reversed",
  843. peers: []*Peer{p2, p1},
  844. out: []*Peer{
  845. p2,
  846. {
  847. Name: "1",
  848. Peer: wireguard.Peer{
  849. PublicKey: []byte("key1"),
  850. AllowedIPs: []*net.IPNet{
  851. {IP: net.ParseIP("10.0.0.2"), Mask: net.CIDRMask(24, 32)},
  852. },
  853. },
  854. },
  855. },
  856. },
  857. {
  858. name: "one duplicates all",
  859. peers: []*Peer{p3, p2, p1, p4},
  860. out: []*Peer{
  861. p3,
  862. {
  863. Name: "2",
  864. Peer: wireguard.Peer{
  865. PublicKey: []byte("key2"),
  866. },
  867. },
  868. {
  869. Name: "1",
  870. Peer: wireguard.Peer{
  871. PublicKey: []byte("key1"),
  872. },
  873. },
  874. {
  875. Name: "4",
  876. Peer: wireguard.Peer{
  877. PublicKey: []byte("key4"),
  878. },
  879. },
  880. },
  881. },
  882. {
  883. name: "one duplicates itself",
  884. peers: []*Peer{p4, p1},
  885. out: []*Peer{
  886. {
  887. Name: "4",
  888. Peer: wireguard.Peer{
  889. PublicKey: []byte("key4"),
  890. AllowedIPs: []*net.IPNet{
  891. {IP: net.ParseIP("10.0.0.3"), Mask: net.CIDRMask(24, 32)},
  892. },
  893. },
  894. },
  895. {
  896. Name: "1",
  897. Peer: wireguard.Peer{
  898. PublicKey: []byte("key1"),
  899. AllowedIPs: []*net.IPNet{
  900. {IP: net.ParseIP("10.0.0.1"), Mask: net.CIDRMask(24, 32)},
  901. {IP: net.ParseIP("10.0.0.2"), Mask: net.CIDRMask(24, 32)},
  902. },
  903. },
  904. },
  905. },
  906. },
  907. } {
  908. out := deduplicatePeerIPs(tc.peers)
  909. if diff := pretty.Compare(out, tc.out); diff != "" {
  910. t.Errorf("test case %q: got diff: %v", tc.name, diff)
  911. }
  912. }
  913. }