Take a hybrid tunnel on msg3 even over a newer one, the initiator has committed to it

This commit is contained in:
JackDoan committed 2026-10-14 12:56:12 -05:00
1 parent cbf8146bda
commit bbade4dc9a
2 files changed
+12 -2

No files matched your search

+8 -1
View File
@@ -495,6 +495,13 @@ var (
// ErrLocalIndexCollision if we already have an entry in the main or pending // ErrLocalIndexCollision if we already have an entry in the main or pending
// hostmap for the hostinfo.localIndexId. // hostmap for the hostinfo.localIndexId.
func (hm *HandshakeManager) CheckAndComplete(hostinfo *HostInfo, handshakePacket uint8, f *Interface) (*HostInfo, error) { func (hm *HandshakeManager) CheckAndComplete(hostinfo *HostInfo, handshakePacket uint8, f *Interface) (*HostInfo, error) {
return hm.checkAndComplete(hostinfo, handshakePacket, f, false)
}
// checkAndComplete is CheckAndComplete. committed means the initiator has shown it
// uses this tunnel, as a hybrid msg3 does, so an existing tunnel is replaced even
// when its handshake is newer.
func (hm *HandshakeManager) checkAndComplete(hostinfo *HostInfo, handshakePacket uint8, f *Interface, committed bool) (*HostInfo, error) {
hm.mainHostMap.Lock() hm.mainHostMap.Lock()
defer hm.mainHostMap.Unlock() defer hm.mainHostMap.Unlock()
hm.Lock() hm.Lock()
@@ -511,7 +518,7 @@ func (hm *HandshakeManager) CheckAndComplete(hostinfo *HostInfo, handshakePacket
} }
// Is this a newer handshake? // Is this a newer handshake?
if existingHostInfo.lastHandshakeTime >= hostinfo.lastHandshakeTime && !existingHostInfo.ConnectionState.initiator { if !committed && existingHostInfo.lastHandshakeTime >= hostinfo.lastHandshakeTime && !existingHostInfo.ConnectionState.initiator {
return existingHostInfo, ErrExistingHostInfo return existingHostInfo, ErrExistingHostInfo
} }
+4 -1
View File
@@ -214,7 +214,10 @@ func (hm *HandshakeManager) completeHybridResponder(via ViaSender, hh *Handshake
remoteCert := result.RemoteCert remoteCert := result.RemoteCert
hostinfo.buildNetworks(f.myVpnNetworksTable, remoteCert.Certificate) hostinfo.buildNetworks(f.myVpnNetworksTable, remoteCert.Certificate)
existing, err := hm.CheckAndComplete(hostinfo, handshakePacketStage0, f) // The initiator only sends msg3 once it settled on this handshake, so this
// tunnel wins even over a newer one: a classical attempt that crossed it, say,
// which the initiator has already given up on.
existing, err := hm.checkAndComplete(hostinfo, handshakePacketStage0, f, true)
if err != nil { if err != nil {
hm.handleCheckAndCompleteError(err, existing, hostinfo, via, machine.Subtype(), 0) hm.handleCheckAndCompleteError(err, existing, hostinfo, via, machine.Subtype(), 0)
return return