Skip to content

Commit 8196c22

Browse files
authored
store lighthouses as a slice (#1473)
* store lighthouses as a slice. If you have fewer than 16 lighthouses (and fewer than 16 vpnaddrs on a host, I guess), it's faster
1 parent 65cc253 commit 8196c22

2 files changed

Lines changed: 31 additions & 25 deletions

File tree

connection_manager_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func newTestLighthouse() *LightHouse {
2222
addrMap: map[netip.Addr]*RemoteList{},
2323
queryChan: make(chan netip.Addr, 10),
2424
}
25-
lighthouses := map[netip.Addr]struct{}{}
25+
lighthouses := []netip.Addr{}
2626
staticList := map[netip.Addr]struct{}{}
2727

2828
lh.lighthouses.Store(&lighthouses)

lighthouse.go

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ type LightHouse struct {
5757
// staticList exists to avoid having a bool in each addrMap entry
5858
// since static should be rare
5959
staticList atomic.Pointer[map[netip.Addr]struct{}]
60-
lighthouses atomic.Pointer[map[netip.Addr]struct{}]
60+
lighthouses atomic.Pointer[[]netip.Addr]
6161

6262
interval atomic.Int64
6363
updateCancel context.CancelFunc
@@ -108,7 +108,7 @@ func NewLightHouseFromConfig(ctx context.Context, l *logrus.Logger, c *config.C,
108108
queryChan: make(chan netip.Addr, c.GetUint32("handshakes.query_buffer", 64)),
109109
l: l,
110110
}
111-
lighthouses := make(map[netip.Addr]struct{})
111+
lighthouses := make([]netip.Addr, 0)
112112
h.lighthouses.Store(&lighthouses)
113113
staticList := make(map[netip.Addr]struct{})
114114
h.staticList.Store(&staticList)
@@ -144,7 +144,7 @@ func (lh *LightHouse) GetStaticHostList() map[netip.Addr]struct{} {
144144
return *lh.staticList.Load()
145145
}
146146

147-
func (lh *LightHouse) GetLighthouses() map[netip.Addr]struct{} {
147+
func (lh *LightHouse) GetLighthouses() []netip.Addr {
148148
return *lh.lighthouses.Load()
149149
}
150150

@@ -307,13 +307,12 @@ func (lh *LightHouse) reload(c *config.C, initial bool) error {
307307
}
308308

309309
if initial || c.HasChanged("lighthouse.hosts") {
310-
lhMap := make(map[netip.Addr]struct{})
311-
err := lh.parseLighthouses(c, lhMap)
310+
lhList, err := lh.parseLighthouses(c)
312311
if err != nil {
313312
return err
314313
}
315314

316-
lh.lighthouses.Store(&lhMap)
315+
lh.lighthouses.Store(&lhList)
317316
if !initial {
318317
//NOTE: we are not tearing down existing lighthouse connections because they might be used for non lighthouse traffic
319318
lh.l.Info("lighthouse.hosts has changed")
@@ -347,36 +346,37 @@ func (lh *LightHouse) reload(c *config.C, initial bool) error {
347346
return nil
348347
}
349348

350-
func (lh *LightHouse) parseLighthouses(c *config.C, lhMap map[netip.Addr]struct{}) error {
349+
func (lh *LightHouse) parseLighthouses(c *config.C) ([]netip.Addr, error) {
351350
lhs := c.GetStringSlice("lighthouse.hosts", []string{})
352351
if lh.amLighthouse && len(lhs) != 0 {
353352
lh.l.Warn("lighthouse.am_lighthouse enabled on node but upstream lighthouses exist in config")
354353
}
354+
out := make([]netip.Addr, len(lhs))
355355

356356
for i, host := range lhs {
357357
addr, err := netip.ParseAddr(host)
358358
if err != nil {
359-
return util.NewContextualError("Unable to parse lighthouse host entry", m{"host": host, "entry": i + 1}, err)
359+
return nil, util.NewContextualError("Unable to parse lighthouse host entry", m{"host": host, "entry": i + 1}, err)
360360
}
361361

362362
if !lh.myVpnNetworksTable.Contains(addr) {
363-
return util.NewContextualError("lighthouse host is not in our networks, invalid", m{"vpnAddr": addr, "networks": lh.myVpnNetworks}, nil)
363+
return nil, util.NewContextualError("lighthouse host is not in our networks, invalid", m{"vpnAddr": addr, "networks": lh.myVpnNetworks}, nil)
364364
}
365-
lhMap[addr] = struct{}{}
365+
out[i] = addr
366366
}
367367

368-
if !lh.amLighthouse && len(lhMap) == 0 {
368+
if !lh.amLighthouse && len(out) == 0 {
369369
lh.l.Warn("No lighthouse.hosts configured, this host will only be able to initiate tunnels with static_host_map entries")
370370
}
371371

372372
staticList := lh.GetStaticHostList()
373-
for lhAddr, _ := range lhMap {
374-
if _, ok := staticList[lhAddr]; !ok {
375-
return fmt.Errorf("lighthouse %s does not have a static_host_map entry", lhAddr)
373+
for i := range out {
374+
if _, ok := staticList[out[i]]; !ok {
375+
return nil, fmt.Errorf("lighthouse %s does not have a static_host_map entry", out[i])
376376
}
377377
}
378378

379-
return nil
379+
return out, nil
380380
}
381381

382382
func getStaticMapCadence(c *config.C) (time.Duration, error) {
@@ -711,15 +711,22 @@ func (lh *LightHouse) unlockedShouldAddV6(vpnAddr netip.Addr, to *V6AddrPort) bo
711711
}
712712

713713
func (lh *LightHouse) IsLighthouseAddr(vpnAddr netip.Addr) bool {
714-
_, ok := lh.GetLighthouses()[vpnAddr]
715-
return ok
714+
l := lh.GetLighthouses()
715+
for i := range l {
716+
if l[i] == vpnAddr {
717+
return true
718+
}
719+
}
720+
return false
716721
}
717722

718-
func (lh *LightHouse) IsAnyLighthouseAddr(vpnAddr []netip.Addr) bool {
723+
func (lh *LightHouse) IsAnyLighthouseAddr(vpnAddrs []netip.Addr) bool {
719724
l := lh.GetLighthouses()
720-
for _, a := range vpnAddr {
721-
if _, ok := l[a]; ok {
722-
return true
725+
for i := range vpnAddrs {
726+
for j := range l {
727+
if l[j] == vpnAddrs[i] {
728+
return true
729+
}
723730
}
724731
}
725732
return false
@@ -761,7 +768,7 @@ func (lh *LightHouse) innerQueryServer(addr netip.Addr, nb, out []byte) {
761768
queried := 0
762769
lighthouses := lh.GetLighthouses()
763770

764-
for lhVpnAddr := range lighthouses {
771+
for _, lhVpnAddr := range lighthouses {
765772
hi := lh.ifce.GetHostInfo(lhVpnAddr)
766773
if hi != nil {
767774
v = hi.ConnectionState.myCert.Version()
@@ -879,7 +886,7 @@ func (lh *LightHouse) SendUpdate() {
879886
updated := 0
880887
lighthouses := lh.GetLighthouses()
881888

882-
for lhVpnAddr := range lighthouses {
889+
for _, lhVpnAddr := range lighthouses {
883890
var v cert.Version
884891
hi := lh.ifce.GetHostInfo(lhVpnAddr)
885892
if hi != nil {
@@ -1289,7 +1296,6 @@ func (lhh *LightHouseHandler) handleHostUpdateNotification(n *NebulaMeta, fromVp
12891296
func (lhh *LightHouseHandler) handleHostPunchNotification(n *NebulaMeta, fromVpnAddrs []netip.Addr, w EncWriter) {
12901297
//It's possible the lighthouse is communicating with us using a non primary vpn addr,
12911298
//which means we need to compare all fromVpnAddrs against all configured lighthouse vpn addrs.
1292-
//maybe one day we'll have a better idea, if it matters.
12931299
if !lhh.lh.IsAnyLighthouseAddr(fromVpnAddrs) {
12941300
return
12951301
}

0 commit comments

Comments
 (0)