mirror of
https://github.com/slackhq/nebula.git
synced 2025-11-22 16:34:25 +01:00
add calculated_remotes (#759)
* add calculated_remotes
This setting allows us to "guess" what the remote might be for a host
while we wait for the lighthouse response. For networks that hard
designed with in mind, it can help speed up handshake performance, as well as
improve resiliency in the case that all lighthouses are down.
Example:
lighthouse:
# ...
calculated_remotes:
# For any Nebula IPs in 10.0.10.0/24, this will apply the mask and add
# the calculated IP as an initial remote (while we wait for the response
# from the lighthouse). Both CIDRs must have the same mask size.
# For example, Nebula IP 10.0.10.123 will have a calculated remote of
# 192.168.1.123
10.0.10.0/24:
- mask: 192.168.1.0/24
port: 4242
* figure out what is up with this test
* add test
* better logic for sending handshakes
Keep track of the last light of hosts we sent handshakes to. Only log
handshake sent messages if the list has changed.
Remove the test Test_NewHandshakeManagerTrigger because it is faulty and
makes no sense. It relys on the fact that no handshake packets actually
get sent, but with these changes we would send packets now (which it
should!)
* use atomic.Pointer
* cleanup to make it clearer
* fix typo in example
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/rcrowley/go-metrics"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/slackhq/nebula/cidr"
|
||||
"github.com/slackhq/nebula/config"
|
||||
"github.com/slackhq/nebula/header"
|
||||
"github.com/slackhq/nebula/iputil"
|
||||
@@ -72,6 +73,8 @@ type LightHouse struct {
|
||||
// IP's of relays that can be used by peers to access me
|
||||
relaysForMe atomic.Pointer[[]iputil.VpnIp]
|
||||
|
||||
calculatedRemotes atomic.Pointer[cidr.Tree4] // Maps VpnIp to []*calculatedRemote
|
||||
|
||||
metrics *MessageMetrics
|
||||
metricHolepunchTx metrics.Counter
|
||||
l *logrus.Logger
|
||||
@@ -161,6 +164,10 @@ func (lh *LightHouse) GetRelaysForMe() []iputil.VpnIp {
|
||||
return *lh.relaysForMe.Load()
|
||||
}
|
||||
|
||||
func (lh *LightHouse) getCalculatedRemotes() *cidr.Tree4 {
|
||||
return lh.calculatedRemotes.Load()
|
||||
}
|
||||
|
||||
func (lh *LightHouse) GetUpdateInterval() int64 {
|
||||
return lh.interval.Load()
|
||||
}
|
||||
@@ -237,6 +244,19 @@ func (lh *LightHouse) reload(c *config.C, initial bool) error {
|
||||
}
|
||||
}
|
||||
|
||||
if initial || c.HasChanged("lighthouse.calculated_remotes") {
|
||||
cr, err := NewCalculatedRemotesFromConfig(c, "lighthouse.calculated_remotes")
|
||||
if err != nil {
|
||||
return util.NewContextualError("Invalid lighthouse.calculated_remotes", nil, err)
|
||||
}
|
||||
|
||||
lh.calculatedRemotes.Store(cr)
|
||||
if !initial {
|
||||
//TODO: a diff will be annoyingly difficult
|
||||
lh.l.Info("lighthouse.calculated_remotes has changed")
|
||||
}
|
||||
}
|
||||
|
||||
//NOTE: many things will get much simpler when we combine static_host_map and lighthouse.hosts in config
|
||||
if initial || c.HasChanged("static_host_map") {
|
||||
staticList := make(map[iputil.VpnIp]struct{})
|
||||
@@ -488,6 +508,39 @@ func (lh *LightHouse) addStaticRemote(vpnIp iputil.VpnIp, toAddr *udp.Addr, stat
|
||||
staticList[vpnIp] = struct{}{}
|
||||
}
|
||||
|
||||
// addCalculatedRemotes adds any calculated remotes based on the
|
||||
// lighthouse.calculated_remotes configuration. It returns true if any
|
||||
// calculated remotes were added
|
||||
func (lh *LightHouse) addCalculatedRemotes(vpnIp iputil.VpnIp) bool {
|
||||
tree := lh.getCalculatedRemotes()
|
||||
if tree == nil {
|
||||
return false
|
||||
}
|
||||
value := tree.MostSpecificContains(vpnIp)
|
||||
if value == nil {
|
||||
return false
|
||||
}
|
||||
calculatedRemotes := value.([]*calculatedRemote)
|
||||
|
||||
var calculated []*Ip4AndPort
|
||||
for _, cr := range calculatedRemotes {
|
||||
c := cr.Apply(vpnIp)
|
||||
if c != nil {
|
||||
calculated = append(calculated, c)
|
||||
}
|
||||
}
|
||||
|
||||
lh.Lock()
|
||||
am := lh.unlockedGetRemoteList(vpnIp)
|
||||
am.Lock()
|
||||
defer am.Unlock()
|
||||
lh.Unlock()
|
||||
|
||||
am.unlockedSetV4(lh.myVpnIp, vpnIp, calculated, lh.unlockedShouldAddV4)
|
||||
|
||||
return len(calculated) > 0
|
||||
}
|
||||
|
||||
// unlockedGetRemoteList assumes you have the lh lock
|
||||
func (lh *LightHouse) unlockedGetRemoteList(vpnIp iputil.VpnIp) *RemoteList {
|
||||
am, ok := lh.addrMap[vpnIp]
|
||||
|
||||
Reference in New Issue
Block a user