Skip to content

Commit

Permalink
punchy-respond on first ipv6 instead of primary address in some cases
Browse files Browse the repository at this point in the history
  • Loading branch information
JackDoanRivian committed Oct 28, 2024
1 parent f2c3242 commit f030856
Showing 1 changed file with 21 additions and 5 deletions.
26 changes: 21 additions & 5 deletions lighthouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -1099,11 +1099,26 @@ func (lhh *LightHouseHandler) handleHostQuery(n *NebulaMeta, fromVpnAddrs []neti
lhh.lh.metricTx(NebulaMeta_HostQueryReply, 1)
w.SendMessageToVpnAddr(header.LightHouse, 0, fromVpnAddrs[0], lhh.pb[:ln], lhh.nb, lhh.out[:0])

// This signals the other side to punch some zero byte udp packets
found, ln, err = lhh.lh.queryAndPrepMessage(fromVpnAddrs[0], func(c *cache) (int, error) {
lhh.sendHostPunchNotification(n, fromVpnAddrs, queryVpnAddr, w)
}

// sendHostPunchNotification signals the other side to punch some zero byte udp packets
func (lhh *LightHouseHandler) sendHostPunchNotification(n *NebulaMeta, fromVpnAddrs []netip.Addr, punchNotifDest netip.Addr, w EncWriter) {
// if the other side is v6-only, tell them to punch to the first v6-addr in fromVpnAddrs
whereToPunch := fromVpnAddrs[0]
if punchNotifDest.Is6() {
for i := range fromVpnAddrs {
if fromVpnAddrs[i].Is6() {
whereToPunch = fromVpnAddrs[i]
}
}
}

found, ln, err := lhh.lh.queryAndPrepMessage(whereToPunch, func(c *cache) (int, error) {
n = lhh.resetMeta()
n.Type = NebulaMeta_HostPunchNotification
targetHI := lhh.lh.ifce.GetHostInfo(queryVpnAddr)
targetHI := lhh.lh.ifce.GetHostInfo(punchNotifDest)
var useVersion cert.Version
if targetHI == nil {
useVersion = lhh.lh.ifce.GetCertState().defaultVersion
} else {
Expand All @@ -1119,7 +1134,7 @@ func (lhh *LightHouseHandler) handleHostQuery(n *NebulaMeta, fromVpnAddrs []neti
lhh.coalesceAnswers(useVersion, c, n)

} else if useVersion == cert.Version2 {
n.Details.VpnAddr = netAddrToProtoAddr(fromVpnAddrs[0])
n.Details.VpnAddr = netAddrToProtoAddr(whereToPunch)
lhh.coalesceAnswers(useVersion, c, n)

} else {
Expand All @@ -1139,7 +1154,7 @@ func (lhh *LightHouseHandler) handleHostQuery(n *NebulaMeta, fromVpnAddrs []neti
}

lhh.lh.metricTx(NebulaMeta_HostPunchNotification, 1)
w.SendMessageToVpnAddr(header.LightHouse, 0, queryVpnAddr, lhh.pb[:ln], lhh.nb, lhh.out[:0])
w.SendMessageToVpnAddr(header.LightHouse, 0, punchNotifDest, lhh.pb[:ln], lhh.nb, lhh.out[:0])
}

func (lhh *LightHouseHandler) coalesceAnswers(v cert.Version, c *cache, n *NebulaMeta) {
Expand Down Expand Up @@ -1377,6 +1392,7 @@ func (lhh *LightHouseHandler) handleHostPunchNotification(n *NebulaMeta, fromVpn
//NOTE: we have to allocate a new output buffer here since we are spawning a new goroutine
// for each punchBack packet. We should move this into a timerwheel or a single goroutine
// managed by a channel.
//todo if the host we're punchy-responding to is dual stack and we are not (bc we are v6-only), their primary IP is probably not reachable!
w.SendMessageToVpnAddr(header.Test, header.TestRequest, queryVpnAddr, []byte(""), make([]byte, 12, 12), make([]byte, mtu))
}()
}
Expand Down

0 comments on commit f030856

Please sign in to comment.