Skip to content

Commit

Permalink
Remove handshake race avoidance (slackhq#820)
Browse files Browse the repository at this point in the history
Co-authored-by: Wade Simmons <[email protected]>
  • Loading branch information
nbrownus and wadey authored Mar 13, 2023
1 parent 2ea360e commit 92cc32f
Show file tree
Hide file tree
Showing 18 changed files with 741 additions and 157 deletions.
24 changes: 23 additions & 1 deletion connection_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,14 @@ func (n *connectionManager) HandleMonitorTick(now time.Time, p, nb, out []byte)
continue
}

// Does the vpnIp point to this hostinfo or is it ancillary? If we have ancillary hostinfos then we need to
// decide if this should be the main hostinfo if we are seeing traffic on it
primary, _ := n.hostMap.QueryVpnIp(hostinfo.vpnIp)
mainHostInfo := true
if primary != nil && primary != hostinfo {
mainHostInfo = false
}

// If we saw an incoming packets from this ip and peer's certificate is not
// expired, just ignore.
if traf {
Expand All @@ -191,14 +199,28 @@ func (n *connectionManager) HandleMonitorTick(now time.Time, p, nb, out []byte)
}
n.ClearLocalIndex(localIndex)
n.ClearPendingDeletion(localIndex)

if !mainHostInfo {
if hostinfo.vpnIp > n.intf.myVpnIp {
// We are receiving traffic on the non primary hostinfo and we really just want 1 tunnel. Make
// This the primary and prime the old primary hostinfo for testing
n.hostMap.MakePrimary(hostinfo)
n.Out(primary.localIndexId)
} else {
// This hostinfo is still being used despite not being the primary hostinfo for this vpn ip
// Keep tracking so that we can tear it down when it goes away
n.Out(hostinfo.localIndexId)
}
}

continue
}

hostinfo.logger(n.l).
WithField("tunnelCheck", m{"state": "testing", "method": "active"}).
Debug("Tunnel status")

if hostinfo != nil && hostinfo.ConnectionState != nil {
if hostinfo != nil && hostinfo.ConnectionState != nil && mainHostInfo {
// Send a test packet to trigger an authenticated tunnel test, this should suss out any lingering tunnel issues
n.intf.sendMessageToVpnIp(header.Test, header.TestRequest, hostinfo, p, nb, out)

Expand Down
4 changes: 2 additions & 2 deletions connection_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func Test_NewConnectionManagerTest(t *testing.T) {
certState: cs,
H: &noise.HandshakeState{},
}
nc.hostMap.addHostInfo(hostinfo, ifce)
nc.hostMap.unlockedAddHostInfo(hostinfo, ifce)

// We saw traffic out to vpnIp
nc.Out(hostinfo.localIndexId)
Expand Down Expand Up @@ -156,7 +156,7 @@ func Test_NewConnectionManagerTest2(t *testing.T) {
certState: cs,
H: &noise.HandshakeState{},
}
nc.hostMap.addHostInfo(hostinfo, ifce)
nc.hostMap.unlockedAddHostInfo(hostinfo, ifce)

// We saw traffic out to vpnIp
nc.Out(hostinfo.localIndexId)
Expand Down
32 changes: 27 additions & 5 deletions control.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,21 @@ func (c *Control) RebindUDPServer() {
c.f.rebindCount++
}

// ListHostmap returns details about the actual or pending (handshaking) hostmap
func (c *Control) ListHostmap(pendingMap bool) []ControlHostInfo {
// ListHostmapHosts returns details about the actual or pending (handshaking) hostmap by vpn ip
func (c *Control) ListHostmapHosts(pendingMap bool) []ControlHostInfo {
if pendingMap {
return listHostMap(c.f.handshakeManager.pendingHostMap)
return listHostMapHosts(c.f.handshakeManager.pendingHostMap)
} else {
return listHostMap(c.f.hostMap)
return listHostMapHosts(c.f.hostMap)
}
}

// ListHostmapIndexes returns details about the actual or pending (handshaking) hostmap by local index id
func (c *Control) ListHostmapIndexes(pendingMap bool) []ControlHostInfo {
if pendingMap {
return listHostMapIndexes(c.f.handshakeManager.pendingHostMap)
} else {
return listHostMapIndexes(c.f.hostMap)
}
}

Expand Down Expand Up @@ -232,7 +241,7 @@ func copyHostInfo(h *HostInfo, preferredRanges []*net.IPNet) ControlHostInfo {
return chi
}

func listHostMap(hm *HostMap) []ControlHostInfo {
func listHostMapHosts(hm *HostMap) []ControlHostInfo {
hm.RLock()
hosts := make([]ControlHostInfo, len(hm.Hosts))
i := 0
Expand All @@ -244,3 +253,16 @@ func listHostMap(hm *HostMap) []ControlHostInfo {

return hosts
}

func listHostMapIndexes(hm *HostMap) []ControlHostInfo {
hm.RLock()
hosts := make([]ControlHostInfo, len(hm.Indexes))
i := 0
for _, v := range hm.Indexes {
hosts[i] = copyHostInfo(v, hm.preferredRanges)
i++
}
hm.RUnlock()

return hosts
}
Loading

0 comments on commit 92cc32f

Please sign in to comment.