lighthouse_test.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. package nebula
  2. import (
  3. "context"
  4. "encoding/binary"
  5. "fmt"
  6. "net/netip"
  7. "testing"
  8. "github.com/gaissmai/bart"
  9. "github.com/slackhq/nebula/cert"
  10. "github.com/slackhq/nebula/config"
  11. "github.com/slackhq/nebula/header"
  12. "github.com/slackhq/nebula/test"
  13. "github.com/stretchr/testify/assert"
  14. "github.com/stretchr/testify/require"
  15. "gopkg.in/yaml.v3"
  16. )
  17. func TestOldIPv4Only(t *testing.T) {
  18. // This test ensures our new ipv6 enabled LH protobuf IpAndPorts works with the old style to enable backwards compatibility
  19. b := []byte{8, 129, 130, 132, 80, 16, 10}
  20. var m V4AddrPort
  21. err := m.Unmarshal(b)
  22. require.NoError(t, err)
  23. ip := netip.MustParseAddr("10.1.1.1")
  24. bp := ip.As4()
  25. assert.Equal(t, binary.BigEndian.Uint32(bp[:]), m.GetAddr())
  26. }
  27. func Test_lhStaticMapping(t *testing.T) {
  28. l := test.NewLogger()
  29. myVpnNet := netip.MustParsePrefix("10.128.0.1/16")
  30. nt := new(bart.Lite)
  31. nt.Insert(myVpnNet)
  32. cs := &CertState{
  33. myVpnNetworks: []netip.Prefix{myVpnNet},
  34. myVpnNetworksTable: nt,
  35. }
  36. lh1 := "10.128.0.2"
  37. c := config.NewC(l)
  38. c.Settings["lighthouse"] = map[string]any{"hosts": []any{lh1}}
  39. c.Settings["static_host_map"] = map[string]any{lh1: []any{"1.1.1.1:4242"}}
  40. _, err := NewLightHouseFromConfig(context.Background(), l, c, cs, nil, nil)
  41. require.NoError(t, err)
  42. lh2 := "10.128.0.3"
  43. c = config.NewC(l)
  44. c.Settings["lighthouse"] = map[string]any{"hosts": []any{lh1, lh2}}
  45. c.Settings["static_host_map"] = map[string]any{lh1: []any{"100.1.1.1:4242"}}
  46. _, err = NewLightHouseFromConfig(context.Background(), l, c, cs, nil, nil)
  47. require.EqualError(t, err, "lighthouse 10.128.0.3 does not have a static_host_map entry")
  48. }
  49. func TestReloadLighthouseInterval(t *testing.T) {
  50. l := test.NewLogger()
  51. myVpnNet := netip.MustParsePrefix("10.128.0.1/16")
  52. nt := new(bart.Lite)
  53. nt.Insert(myVpnNet)
  54. cs := &CertState{
  55. myVpnNetworks: []netip.Prefix{myVpnNet},
  56. myVpnNetworksTable: nt,
  57. }
  58. lh1 := "10.128.0.2"
  59. c := config.NewC(l)
  60. c.Settings["lighthouse"] = map[string]any{
  61. "hosts": []any{lh1},
  62. "interval": "1s",
  63. }
  64. c.Settings["static_host_map"] = map[string]any{lh1: []any{"1.1.1.1:4242"}}
  65. lh, err := NewLightHouseFromConfig(context.Background(), l, c, cs, nil, nil)
  66. require.NoError(t, err)
  67. lh.ifce = &mockEncWriter{}
  68. // The first one routine is kicked off by main.go currently, lets make sure that one dies
  69. require.NoError(t, c.ReloadConfigString("lighthouse:\n interval: 5"))
  70. assert.Equal(t, int64(5), lh.interval.Load())
  71. // Subsequent calls are killed off by the LightHouse.Reload function
  72. require.NoError(t, c.ReloadConfigString("lighthouse:\n interval: 10"))
  73. assert.Equal(t, int64(10), lh.interval.Load())
  74. // If this completes then nothing is stealing our reload routine
  75. require.NoError(t, c.ReloadConfigString("lighthouse:\n interval: 11"))
  76. assert.Equal(t, int64(11), lh.interval.Load())
  77. }
  78. func BenchmarkLighthouseHandleRequest(b *testing.B) {
  79. l := test.NewLogger()
  80. myVpnNet := netip.MustParsePrefix("10.128.0.1/0")
  81. nt := new(bart.Lite)
  82. nt.Insert(myVpnNet)
  83. cs := &CertState{
  84. myVpnNetworks: []netip.Prefix{myVpnNet},
  85. myVpnNetworksTable: nt,
  86. }
  87. c := config.NewC(l)
  88. lh, err := NewLightHouseFromConfig(context.Background(), l, c, cs, nil, nil)
  89. require.NoError(b, err)
  90. hAddr := netip.MustParseAddrPort("4.5.6.7:12345")
  91. hAddr2 := netip.MustParseAddrPort("4.5.6.7:12346")
  92. vpnIp3 := netip.MustParseAddr("0.0.0.3")
  93. lh.addrMap[vpnIp3] = NewRemoteList([]netip.Addr{vpnIp3}, nil)
  94. lh.addrMap[vpnIp3].unlockedSetV4(
  95. vpnIp3,
  96. vpnIp3,
  97. []*V4AddrPort{
  98. netAddrToProtoV4AddrPort(hAddr.Addr(), hAddr.Port()),
  99. netAddrToProtoV4AddrPort(hAddr2.Addr(), hAddr2.Port()),
  100. },
  101. func(netip.Addr, *V4AddrPort) bool { return true },
  102. )
  103. rAddr := netip.MustParseAddrPort("1.2.2.3:12345")
  104. rAddr2 := netip.MustParseAddrPort("1.2.2.3:12346")
  105. vpnIp2 := netip.MustParseAddr("0.0.0.3")
  106. lh.addrMap[vpnIp2] = NewRemoteList([]netip.Addr{vpnIp2}, nil)
  107. lh.addrMap[vpnIp2].unlockedSetV4(
  108. vpnIp3,
  109. vpnIp3,
  110. []*V4AddrPort{
  111. netAddrToProtoV4AddrPort(rAddr.Addr(), rAddr.Port()),
  112. netAddrToProtoV4AddrPort(rAddr2.Addr(), rAddr2.Port()),
  113. },
  114. func(netip.Addr, *V4AddrPort) bool { return true },
  115. )
  116. mw := &mockEncWriter{}
  117. hostinfo := &HostInfo{
  118. ConnectionState: &ConnectionState{
  119. eKey: nil,
  120. dKey: nil,
  121. },
  122. vpnAddrs: []netip.Addr{vpnIp2},
  123. }
  124. b.Run("notfound", func(b *testing.B) {
  125. lhh := lh.NewRequestHandler()
  126. req := &NebulaMeta{
  127. Type: NebulaMeta_HostQuery,
  128. Details: &NebulaMetaDetails{
  129. OldVpnAddr: 4,
  130. V4AddrPorts: nil,
  131. },
  132. }
  133. p, err := req.Marshal()
  134. require.NoError(b, err)
  135. for n := 0; n < b.N; n++ {
  136. lhh.HandleRequest(rAddr, hostinfo, p, mw)
  137. }
  138. })
  139. b.Run("found", func(b *testing.B) {
  140. lhh := lh.NewRequestHandler()
  141. req := &NebulaMeta{
  142. Type: NebulaMeta_HostQuery,
  143. Details: &NebulaMetaDetails{
  144. OldVpnAddr: 3,
  145. V4AddrPorts: nil,
  146. },
  147. }
  148. p, err := req.Marshal()
  149. require.NoError(b, err)
  150. for n := 0; n < b.N; n++ {
  151. lhh.HandleRequest(rAddr, hostinfo, p, mw)
  152. }
  153. })
  154. }
  155. func TestLighthouse_Memory(t *testing.T) {
  156. l := test.NewLogger()
  157. myUdpAddr0 := netip.MustParseAddrPort("10.0.0.2:4242")
  158. myUdpAddr1 := netip.MustParseAddrPort("192.168.0.2:4242")
  159. myUdpAddr2 := netip.MustParseAddrPort("172.16.0.2:4242")
  160. myUdpAddr3 := netip.MustParseAddrPort("100.152.0.2:4242")
  161. myUdpAddr4 := netip.MustParseAddrPort("24.15.0.2:4242")
  162. myUdpAddr5 := netip.MustParseAddrPort("192.168.0.2:4243")
  163. myUdpAddr6 := netip.MustParseAddrPort("192.168.0.2:4244")
  164. myUdpAddr7 := netip.MustParseAddrPort("192.168.0.2:4245")
  165. myUdpAddr8 := netip.MustParseAddrPort("192.168.0.2:4246")
  166. myUdpAddr9 := netip.MustParseAddrPort("192.168.0.2:4247")
  167. myUdpAddr10 := netip.MustParseAddrPort("192.168.0.2:4248")
  168. myUdpAddr11 := netip.MustParseAddrPort("192.168.0.2:4249")
  169. myVpnIp := netip.MustParseAddr("10.128.0.2")
  170. theirUdpAddr0 := netip.MustParseAddrPort("10.0.0.3:4242")
  171. theirUdpAddr1 := netip.MustParseAddrPort("192.168.0.3:4242")
  172. theirUdpAddr2 := netip.MustParseAddrPort("172.16.0.3:4242")
  173. theirUdpAddr3 := netip.MustParseAddrPort("100.152.0.3:4242")
  174. theirUdpAddr4 := netip.MustParseAddrPort("24.15.0.3:4242")
  175. theirVpnIp := netip.MustParseAddr("10.128.0.3")
  176. c := config.NewC(l)
  177. c.Settings["lighthouse"] = map[string]any{"am_lighthouse": true}
  178. c.Settings["listen"] = map[string]any{"port": 4242}
  179. myVpnNet := netip.MustParsePrefix("10.128.0.1/24")
  180. nt := new(bart.Lite)
  181. nt.Insert(myVpnNet)
  182. cs := &CertState{
  183. myVpnNetworks: []netip.Prefix{myVpnNet},
  184. myVpnNetworksTable: nt,
  185. }
  186. lh, err := NewLightHouseFromConfig(context.Background(), l, c, cs, nil, nil)
  187. lh.ifce = &mockEncWriter{}
  188. require.NoError(t, err)
  189. lhh := lh.NewRequestHandler()
  190. // Test that my first update responds with just that
  191. newLHHostUpdate(myUdpAddr0, myVpnIp, []netip.AddrPort{myUdpAddr1, myUdpAddr2}, lhh)
  192. r := newLHHostRequest(myUdpAddr0, myVpnIp, myVpnIp, lhh)
  193. assertIp4InArray(t, r.msg.Details.V4AddrPorts, myUdpAddr1, myUdpAddr2)
  194. // Ensure we don't accumulate addresses
  195. newLHHostUpdate(myUdpAddr0, myVpnIp, []netip.AddrPort{myUdpAddr3}, lhh)
  196. r = newLHHostRequest(myUdpAddr0, myVpnIp, myVpnIp, lhh)
  197. assertIp4InArray(t, r.msg.Details.V4AddrPorts, myUdpAddr3)
  198. // Grow it back to 2
  199. newLHHostUpdate(myUdpAddr0, myVpnIp, []netip.AddrPort{myUdpAddr1, myUdpAddr4}, lhh)
  200. r = newLHHostRequest(myUdpAddr0, myVpnIp, myVpnIp, lhh)
  201. assertIp4InArray(t, r.msg.Details.V4AddrPorts, myUdpAddr1, myUdpAddr4)
  202. // Update a different host and ask about it
  203. newLHHostUpdate(theirUdpAddr0, theirVpnIp, []netip.AddrPort{theirUdpAddr1, theirUdpAddr2, theirUdpAddr3, theirUdpAddr4}, lhh)
  204. r = newLHHostRequest(theirUdpAddr0, theirVpnIp, theirVpnIp, lhh)
  205. assertIp4InArray(t, r.msg.Details.V4AddrPorts, theirUdpAddr1, theirUdpAddr2, theirUdpAddr3, theirUdpAddr4)
  206. // Have both hosts ask about the other
  207. r = newLHHostRequest(theirUdpAddr0, theirVpnIp, myVpnIp, lhh)
  208. assertIp4InArray(t, r.msg.Details.V4AddrPorts, myUdpAddr1, myUdpAddr4)
  209. r = newLHHostRequest(myUdpAddr0, myVpnIp, theirVpnIp, lhh)
  210. assertIp4InArray(t, r.msg.Details.V4AddrPorts, theirUdpAddr1, theirUdpAddr2, theirUdpAddr3, theirUdpAddr4)
  211. // Make sure we didn't get changed
  212. r = newLHHostRequest(myUdpAddr0, myVpnIp, myVpnIp, lhh)
  213. assertIp4InArray(t, r.msg.Details.V4AddrPorts, myUdpAddr1, myUdpAddr4)
  214. // Ensure proper ordering and limiting
  215. // Send 12 addrs, get 10 back, the last 2 removed, allowing the duplicate to remain (clients dedupe)
  216. newLHHostUpdate(
  217. myUdpAddr0,
  218. myVpnIp,
  219. []netip.AddrPort{
  220. myUdpAddr1,
  221. myUdpAddr2,
  222. myUdpAddr3,
  223. myUdpAddr4,
  224. myUdpAddr5,
  225. myUdpAddr5, //Duplicated on purpose
  226. myUdpAddr6,
  227. myUdpAddr7,
  228. myUdpAddr8,
  229. myUdpAddr9,
  230. myUdpAddr10,
  231. myUdpAddr11, // This should get cut
  232. }, lhh)
  233. r = newLHHostRequest(myUdpAddr0, myVpnIp, myVpnIp, lhh)
  234. assertIp4InArray(
  235. t,
  236. r.msg.Details.V4AddrPorts,
  237. myUdpAddr1, myUdpAddr2, myUdpAddr3, myUdpAddr4, myUdpAddr5, myUdpAddr5, myUdpAddr6, myUdpAddr7, myUdpAddr8, myUdpAddr9,
  238. )
  239. // Make sure we won't add ips in our vpn network
  240. bad1 := netip.MustParseAddrPort("10.128.0.99:4242")
  241. bad2 := netip.MustParseAddrPort("10.128.0.100:4242")
  242. good := netip.MustParseAddrPort("1.128.0.99:4242")
  243. newLHHostUpdate(myUdpAddr0, myVpnIp, []netip.AddrPort{bad1, bad2, good}, lhh)
  244. r = newLHHostRequest(myUdpAddr0, myVpnIp, myVpnIp, lhh)
  245. assertIp4InArray(t, r.msg.Details.V4AddrPorts, good)
  246. }
  247. func TestLighthouse_reload(t *testing.T) {
  248. l := test.NewLogger()
  249. c := config.NewC(l)
  250. c.Settings["lighthouse"] = map[string]any{"am_lighthouse": true}
  251. c.Settings["listen"] = map[string]any{"port": 4242}
  252. myVpnNet := netip.MustParsePrefix("10.128.0.1/24")
  253. nt := new(bart.Lite)
  254. nt.Insert(myVpnNet)
  255. cs := &CertState{
  256. myVpnNetworks: []netip.Prefix{myVpnNet},
  257. myVpnNetworksTable: nt,
  258. }
  259. lh, err := NewLightHouseFromConfig(context.Background(), l, c, cs, nil, nil)
  260. require.NoError(t, err)
  261. nc := map[string]any{
  262. "static_host_map": map[string]any{
  263. "10.128.0.2": []any{"1.1.1.1:4242"},
  264. },
  265. }
  266. rc, err := yaml.Marshal(nc)
  267. require.NoError(t, err)
  268. c.ReloadConfigString(string(rc))
  269. err = lh.reload(c, false)
  270. require.NoError(t, err)
  271. }
  272. func newLHHostRequest(fromAddr netip.AddrPort, myVpnIp, queryVpnIp netip.Addr, lhh *LightHouseHandler) testLhReply {
  273. req := &NebulaMeta{
  274. Type: NebulaMeta_HostQuery,
  275. Details: &NebulaMetaDetails{},
  276. }
  277. if queryVpnIp.Is4() {
  278. bip := queryVpnIp.As4()
  279. req.Details.OldVpnAddr = binary.BigEndian.Uint32(bip[:])
  280. } else {
  281. req.Details.VpnAddr = netAddrToProtoAddr(queryVpnIp)
  282. }
  283. b, err := req.Marshal()
  284. if err != nil {
  285. panic(err)
  286. }
  287. filter := NebulaMeta_HostQueryReply
  288. w := &testEncWriter{
  289. metaFilter: &filter,
  290. }
  291. hostinfo := &HostInfo{
  292. ConnectionState: &ConnectionState{
  293. eKey: nil,
  294. dKey: nil,
  295. },
  296. vpnAddrs: []netip.Addr{myVpnIp},
  297. }
  298. lhh.HandleRequest(fromAddr, hostinfo, b, w)
  299. return w.lastReply
  300. }
  301. func newLHHostUpdate(fromAddr netip.AddrPort, vpnIp netip.Addr, addrs []netip.AddrPort, lhh *LightHouseHandler) {
  302. req := &NebulaMeta{
  303. Type: NebulaMeta_HostUpdateNotification,
  304. Details: &NebulaMetaDetails{},
  305. }
  306. if vpnIp.Is4() {
  307. bip := vpnIp.As4()
  308. req.Details.OldVpnAddr = binary.BigEndian.Uint32(bip[:])
  309. } else {
  310. req.Details.VpnAddr = netAddrToProtoAddr(vpnIp)
  311. }
  312. for _, v := range addrs {
  313. if v.Addr().Is4() {
  314. req.Details.V4AddrPorts = append(req.Details.V4AddrPorts, netAddrToProtoV4AddrPort(v.Addr(), v.Port()))
  315. } else {
  316. req.Details.V6AddrPorts = append(req.Details.V6AddrPorts, netAddrToProtoV6AddrPort(v.Addr(), v.Port()))
  317. }
  318. }
  319. b, err := req.Marshal()
  320. if err != nil {
  321. panic(err)
  322. }
  323. hostinfo := &HostInfo{
  324. ConnectionState: &ConnectionState{
  325. eKey: nil,
  326. dKey: nil,
  327. },
  328. vpnAddrs: []netip.Addr{vpnIp},
  329. }
  330. w := &testEncWriter{}
  331. lhh.HandleRequest(fromAddr, hostinfo, b, w)
  332. }
  333. type testLhReply struct {
  334. nebType header.MessageType
  335. nebSubType header.MessageSubType
  336. vpnIp netip.Addr
  337. msg *NebulaMeta
  338. }
  339. type testEncWriter struct {
  340. lastReply testLhReply
  341. metaFilter *NebulaMeta_MessageType
  342. protocolVersion cert.Version
  343. }
  344. func (tw *testEncWriter) SendVia(via *HostInfo, relay *Relay, ad, nb, out []byte, nocopy bool) {
  345. }
  346. func (tw *testEncWriter) Handshake(vpnIp netip.Addr) {
  347. }
  348. func (tw *testEncWriter) SendMessageToHostInfo(t header.MessageType, st header.MessageSubType, hostinfo *HostInfo, p, _, _ []byte) {
  349. msg := &NebulaMeta{}
  350. err := msg.Unmarshal(p)
  351. if tw.metaFilter == nil || msg.Type == *tw.metaFilter {
  352. tw.lastReply = testLhReply{
  353. nebType: t,
  354. nebSubType: st,
  355. vpnIp: hostinfo.vpnAddrs[0],
  356. msg: msg,
  357. }
  358. }
  359. if err != nil {
  360. panic(err)
  361. }
  362. }
  363. func (tw *testEncWriter) SendMessageToVpnAddr(t header.MessageType, st header.MessageSubType, vpnIp netip.Addr, p, _, _ []byte) {
  364. msg := &NebulaMeta{}
  365. err := msg.Unmarshal(p)
  366. if tw.metaFilter == nil || msg.Type == *tw.metaFilter {
  367. tw.lastReply = testLhReply{
  368. nebType: t,
  369. nebSubType: st,
  370. vpnIp: vpnIp,
  371. msg: msg,
  372. }
  373. }
  374. if err != nil {
  375. panic(err)
  376. }
  377. }
  378. func (tw *testEncWriter) GetHostInfo(vpnIp netip.Addr) *HostInfo {
  379. return nil
  380. }
  381. func (tw *testEncWriter) GetCertState() *CertState {
  382. return &CertState{initiatingVersion: tw.protocolVersion}
  383. }
  384. // assertIp4InArray asserts every address in want is at the same position in have and that the lengths match
  385. func assertIp4InArray(t *testing.T, have []*V4AddrPort, want ...netip.AddrPort) {
  386. if !assert.Len(t, have, len(want)) {
  387. return
  388. }
  389. for k, w := range want {
  390. h := protoV4AddrPortToNetAddrPort(have[k])
  391. if !(h == w) {
  392. assert.Fail(t, fmt.Sprintf("Response did not contain: %v at %v, found %v", w, k, h))
  393. }
  394. }
  395. }
  396. func Test_findNetworkUnion(t *testing.T) {
  397. var out netip.Addr
  398. var ok bool
  399. tenDot := netip.MustParsePrefix("10.0.0.0/8")
  400. oneSevenTwo := netip.MustParsePrefix("172.16.0.0/16")
  401. fe80 := netip.MustParsePrefix("fe80::/8")
  402. fc00 := netip.MustParsePrefix("fc00::/7")
  403. a1 := netip.MustParseAddr("10.0.0.1")
  404. afe81 := netip.MustParseAddr("fe80::1")
  405. //simple
  406. out, ok = findNetworkUnion([]netip.Prefix{tenDot}, []netip.Addr{a1})
  407. assert.True(t, ok)
  408. assert.Equal(t, out, a1)
  409. //mixed lengths
  410. out, ok = findNetworkUnion([]netip.Prefix{tenDot}, []netip.Addr{a1, afe81})
  411. assert.True(t, ok)
  412. assert.Equal(t, out, a1)
  413. out, ok = findNetworkUnion([]netip.Prefix{tenDot, oneSevenTwo}, []netip.Addr{a1})
  414. assert.True(t, ok)
  415. assert.Equal(t, out, a1)
  416. //mixed family
  417. out, ok = findNetworkUnion([]netip.Prefix{tenDot, oneSevenTwo, fe80}, []netip.Addr{a1})
  418. assert.True(t, ok)
  419. assert.Equal(t, out, a1)
  420. out, ok = findNetworkUnion([]netip.Prefix{tenDot, oneSevenTwo, fe80}, []netip.Addr{a1, afe81})
  421. assert.True(t, ok)
  422. assert.Equal(t, out, a1)
  423. //ordering
  424. out, ok = findNetworkUnion([]netip.Prefix{tenDot, oneSevenTwo, fe80}, []netip.Addr{afe81, a1})
  425. assert.True(t, ok)
  426. assert.Equal(t, out, a1)
  427. out, ok = findNetworkUnion([]netip.Prefix{fe80, tenDot, oneSevenTwo}, []netip.Addr{afe81, a1})
  428. assert.True(t, ok)
  429. assert.Equal(t, out, afe81)
  430. //some mismatches
  431. out, ok = findNetworkUnion([]netip.Prefix{tenDot, oneSevenTwo, fe80}, []netip.Addr{afe81})
  432. assert.True(t, ok)
  433. assert.Equal(t, out, afe81)
  434. out, ok = findNetworkUnion([]netip.Prefix{oneSevenTwo, fe80}, []netip.Addr{a1, afe81})
  435. assert.True(t, ok)
  436. assert.Equal(t, out, afe81)
  437. //falsey cases
  438. out, ok = findNetworkUnion([]netip.Prefix{oneSevenTwo, fe80}, []netip.Addr{a1})
  439. assert.False(t, ok)
  440. out, ok = findNetworkUnion([]netip.Prefix{fc00, fe80}, []netip.Addr{a1})
  441. assert.False(t, ok)
  442. out, ok = findNetworkUnion([]netip.Prefix{oneSevenTwo, fc00}, []netip.Addr{a1, afe81})
  443. assert.False(t, ok)
  444. out, ok = findNetworkUnion([]netip.Prefix{fc00}, []netip.Addr{a1, afe81})
  445. assert.False(t, ok)
  446. }
  447. func TestLighthouse_Dont_Delete_Static_Hosts(t *testing.T) {
  448. l := test.NewLogger()
  449. myUdpAddr2 := netip.MustParseAddrPort("1.2.3.4:4242")
  450. testSameHostNotStatic := netip.MustParseAddr("10.128.0.41")
  451. testStaticHost := netip.MustParseAddr("10.128.0.42")
  452. //myVpnIp := netip.MustParseAddr("10.128.0.2")
  453. c := config.NewC(l)
  454. lh1 := "10.128.0.2"
  455. c.Settings["lighthouse"] = map[string]any{
  456. "hosts": []any{lh1},
  457. "interval": "1s",
  458. }
  459. c.Settings["listen"] = map[string]any{"port": 4242}
  460. c.Settings["static_host_map"] = map[string]any{
  461. lh1: []any{"1.1.1.1:4242"},
  462. "10.128.0.42": []any{"1.2.3.4:4242"},
  463. }
  464. myVpnNet := netip.MustParsePrefix("10.128.0.1/24")
  465. nt := new(bart.Lite)
  466. nt.Insert(myVpnNet)
  467. cs := &CertState{
  468. myVpnNetworks: []netip.Prefix{myVpnNet},
  469. myVpnNetworksTable: nt,
  470. }
  471. lh, err := NewLightHouseFromConfig(context.Background(), l, c, cs, nil, nil)
  472. require.NoError(t, err)
  473. lh.ifce = &mockEncWriter{}
  474. //test that we actually have the static entry:
  475. out := lh.Query(testStaticHost)
  476. assert.NotNil(t, out)
  477. assert.Equal(t, out.vpnAddrs[0], testStaticHost)
  478. out.Rebuild([]netip.Prefix{}) //why tho
  479. assert.Equal(t, out.addrs[0], myUdpAddr2)
  480. //bolt on a lower numbered primary IP
  481. am := lh.unlockedGetRemoteList([]netip.Addr{testStaticHost})
  482. am.vpnAddrs = []netip.Addr{testSameHostNotStatic, testStaticHost}
  483. lh.addrMap[testSameHostNotStatic] = am
  484. out.Rebuild([]netip.Prefix{}) //???
  485. //test that we actually have the static entry:
  486. out = lh.Query(testStaticHost)
  487. assert.NotNil(t, out)
  488. assert.Equal(t, out.vpnAddrs[0], testSameHostNotStatic)
  489. assert.Equal(t, out.vpnAddrs[1], testStaticHost)
  490. assert.Equal(t, out.addrs[0], myUdpAddr2)
  491. //test that we actually have the static entry for BOTH:
  492. out2 := lh.Query(testSameHostNotStatic)
  493. assert.Same(t, out2, out)
  494. //now do the delete
  495. lh.DeleteVpnAddrs([]netip.Addr{testSameHostNotStatic, testStaticHost})
  496. //verify
  497. out = lh.Query(testSameHostNotStatic)
  498. assert.NotNil(t, out)
  499. if out == nil {
  500. t.Fatal("expected non-nil query for the static host")
  501. }
  502. assert.Equal(t, out.vpnAddrs[0], testSameHostNotStatic)
  503. assert.Equal(t, out.vpnAddrs[1], testStaticHost)
  504. assert.Equal(t, out.addrs[0], myUdpAddr2)
  505. }
  506. func TestLighthouse_DeletesWork(t *testing.T) {
  507. l := test.NewLogger()
  508. myUdpAddr2 := netip.MustParseAddrPort("1.2.3.4:4242")
  509. testHost := netip.MustParseAddr("10.128.0.42")
  510. c := config.NewC(l)
  511. lh1 := "10.128.0.2"
  512. c.Settings["lighthouse"] = map[string]any{
  513. "hosts": []any{lh1},
  514. "interval": "1s",
  515. }
  516. c.Settings["listen"] = map[string]any{"port": 4242}
  517. c.Settings["static_host_map"] = map[string]any{
  518. lh1: []any{"1.1.1.1:4242"},
  519. }
  520. myVpnNet := netip.MustParsePrefix("10.128.0.1/24")
  521. nt := new(bart.Lite)
  522. nt.Insert(myVpnNet)
  523. cs := &CertState{
  524. myVpnNetworks: []netip.Prefix{myVpnNet},
  525. myVpnNetworksTable: nt,
  526. }
  527. lh, err := NewLightHouseFromConfig(context.Background(), l, c, cs, nil, nil)
  528. require.NoError(t, err)
  529. lh.ifce = &mockEncWriter{}
  530. //insert the host
  531. am := lh.unlockedGetRemoteList([]netip.Addr{testHost})
  532. am.vpnAddrs = []netip.Addr{testHost}
  533. am.addrs = []netip.AddrPort{myUdpAddr2}
  534. lh.addrMap[testHost] = am
  535. am.Rebuild([]netip.Prefix{}) //???
  536. //test that we actually have the entry:
  537. out := lh.Query(testHost)
  538. assert.NotNil(t, out)
  539. assert.Equal(t, out.vpnAddrs[0], testHost)
  540. out.Rebuild([]netip.Prefix{}) //why tho
  541. assert.Equal(t, out.addrs[0], myUdpAddr2)
  542. //now do the delete
  543. lh.DeleteVpnAddrs([]netip.Addr{testHost})
  544. //verify
  545. out = lh.Query(testHost)
  546. assert.Nil(t, out)
  547. }