topology_test.go 27 KB

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