Skip to content

Commit

Permalink
more lh+hostmap multi-ip
Browse files Browse the repository at this point in the history
  • Loading branch information
JackDoanRivian committed Sep 22, 2024
1 parent 8e9072d commit a003f4a
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 30 deletions.
12 changes: 10 additions & 2 deletions hostmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ func (hm *HostMap) MakePrimary(hostinfo *HostInfo) {
}

func (hm *HostMap) unlockedMakePrimary(hostinfo *HostInfo) {
//don't need to iterate here -- all vpnaddr entries should be the same
oldHostinfo := hm.Hosts[hostinfo.vpnAddrs[0]]
if oldHostinfo == hostinfo {
return
Expand All @@ -334,7 +335,10 @@ func (hm *HostMap) unlockedMakePrimary(hostinfo *HostInfo) {
hostinfo.next.prev = hostinfo.prev
}

hm.Hosts[hostinfo.vpnAddrs[0]] = hostinfo
//do need to iterate here, since we're setting the pointer value
for i := range hostinfo.vpnAddrs {
hm.Hosts[hostinfo.vpnAddrs[i]] = hostinfo
}

if oldHostinfo == nil {
return
Expand All @@ -346,6 +350,7 @@ func (hm *HostMap) unlockedMakePrimary(hostinfo *HostInfo) {
}

func (hm *HostMap) unlockedDeleteHostInfo(hostinfo *HostInfo, dontRecurse bool) {
//don't need to iterate here -- all vpnaddr entries should be the same
primary, ok := hm.Hosts[hostinfo.vpnAddrs[0]]
if ok && primary == hostinfo {
// The vpnIp pointer points to the same hostinfo as the local index id, we can remove it
Expand Down Expand Up @@ -595,7 +600,10 @@ func (i *HostInfo) TryPromoteBest(preferredRanges []netip.Prefix, ifce *Interfac
}

i.nextLHQuery.Store(now + ifce.reQueryWait.Load())
ifce.lightHouse.QueryServer(i.vpnAddrs[0])
//TODO do we need to query all entries? Hosts can gain and lose addresses
for j := range i.vpnAddrs {
ifce.lightHouse.QueryServer(i.vpnAddrs[j])
}
}
}

Expand Down
42 changes: 14 additions & 28 deletions lighthouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"fmt"
"net"
"net/netip"
"slices"
"strconv"
"sync"
"sync/atomic"
Expand Down Expand Up @@ -1165,40 +1164,28 @@ func (lhh *LightHouseHandler) handleHostUpdateNotification(n *NebulaMeta, fromVp
lhh.l.Debugln("I am not a lighthouse, do not take host updates: ", fromVpnAddrs)
}
return
} else if lhh.l.Level >= logrus.DebugLevel {
lhh.l.WithField("vpnAddrs", fromVpnAddrs).WithField("details", n.Details.String()).Debugln("got HostUpdateNotification")
}

//Simple check that the host sent this not someone else
var detailsVpnIp netip.Addr
var useVersion cert.Version
if n.Details.OldVpnAddr != 0 {
b := [4]byte{}
binary.BigEndian.PutUint32(b[:], n.Details.OldVpnAddr)
detailsVpnIp = netip.AddrFrom4(b)
if n.Details.OldVpnAddr != 0 { //todo this is a bit of a hack
useVersion = 1
} else if n.Details.VpnAddr != nil {
detailsVpnIp = protoAddrToNetAddr(n.Details.VpnAddr)
useVersion = 2
}

//todo hosts with only v2 certs cannot provide their ipv6 addr when contacting the lighthouse via v4?
//todo why do we care about the vpnip in the packet? We know where it came from, right?

if !slices.Contains(fromVpnAddrs, detailsVpnIp) {
if lhh.l.Level >= logrus.DebugLevel {
lhh.l.WithField("vpnAddrs", fromVpnAddrs).WithField("detailsVpnIp", detailsVpnIp).Debugln("Host sent invalid update")
}
return
} else {
lhh.l.WithField("vpnAddrs", fromVpnAddrs).WithField("detailsVpnIp", detailsVpnIp).Debugln("got HostUpdateNotification")
useVersion = 2
}

lhh.lh.Lock()
am := lhh.lh.unlockedGetRemoteList(fromVpnAddrs)
am.Lock()
lhh.lh.Unlock()

am.unlockedSetV4(fromVpnAddrs[0], detailsVpnIp, n.Details.V4AddrPorts, lhh.lh.unlockedShouldAddV4)
am.unlockedSetV6(fromVpnAddrs[0], detailsVpnIp, n.Details.V6AddrPorts, lhh.lh.unlockedShouldAddV6)
//todo why do we care about the vpnip in the packet? We know where it came from, right?
//todo if the zeroth IP changes things will get weird
for i := range fromVpnAddrs {
am.unlockedSetV4(fromVpnAddrs[0], fromVpnAddrs[i], n.Details.V4AddrPorts, lhh.lh.unlockedShouldAddV4)
am.unlockedSetV6(fromVpnAddrs[0], fromVpnAddrs[i], n.Details.V6AddrPorts, lhh.lh.unlockedShouldAddV6)
}

var relays []netip.Addr
if len(n.Details.OldRelayVpnAddrs) > 0 {
Expand All @@ -1215,7 +1202,8 @@ func (lhh *LightHouseHandler) handleHostUpdateNotification(n *NebulaMeta, fromVp
}
}

am.unlockedSetRelay(fromVpnAddrs[0], detailsVpnIp, relays)
//todo does this need to be per-vpnip?
am.unlockedSetRelay(fromVpnAddrs[0], fromVpnAddrs[0], relays)
am.Unlock()

//begin sending update notif ack
Expand All @@ -1230,11 +1218,8 @@ func (lhh *LightHouseHandler) handleHostUpdateNotification(n *NebulaMeta, fromVp
vpnIpB := fromVpnAddrs[0].As4()
n.Details.OldVpnAddr = binary.BigEndian.Uint32(vpnIpB[:])

} else if useVersion == cert.Version2 {
n.Details.VpnAddr = netAddrToProtoAddr(fromVpnAddrs[0])

} else {
panic("unsupported version")
n.Details.VpnAddr = netAddrToProtoAddr(fromVpnAddrs[0])
}

ln, err := n.MarshalTo(lhh.pb)
Expand All @@ -1244,6 +1229,7 @@ func (lhh *LightHouseHandler) handleHostUpdateNotification(n *NebulaMeta, fromVp
}

lhh.lh.metricTx(NebulaMeta_HostUpdateNotificationAck, 1)
//all vpnaddrs transit the same tunnel, so we only need to send one
w.SendMessageToVpnIp(header.LightHouse, 0, fromVpnAddrs[0], lhh.pb[:ln], lhh.nb, lhh.out[:0])
}

Expand Down

0 comments on commit a003f4a

Please sign in to comment.