Attach a pending handshake's RemoteList when the handshake starts (#1909)

StartHandshake returned a hostinfo with no RemoteList; handleOutbound attached
one lazily on its first tick. Anything that touched the pending host before
then, notably create-tunnel -address, dereferenced nil and took the daemon
down. StartHandshake now attaches the lighthouse's list as it builds the
hostinfo. To keep the surrounding locking sound, a lighthouse now resolves a
punch target before taking the querier's RemoteList lock, and closeTunnel
deletes the host and evicts its RemoteList under a single hostmap write lock so
a completing handshake cannot land in between. The lock order, now documented
on the handshake manager mutex, is hostmap, then handshake manager, then
lighthouse, then RemoteList; no RemoteList lock is ever held across a hostmap
lookup.
This commit is contained in:
Matt Richardson authored and GitHub committed 2026-10-07 11:22:50 -04:00
1 parent d5062dacf0
commit f9b0853476
8 files changed
+213 -27

No files matched your search

+8 -4
View File
@@ -684,10 +684,14 @@ func sshCreateTunnel(ifce *Interface, fs any, a []string, w sshd.StringWriter) e
}
}
hostInfo = ifce.handshakeManager.StartHandshake(vpnAddr, nil)
if addr.IsValid() {
hostInfo.SetRemote(addr)
}
// Set the remote from the callback, which StartHandshake runs under the handshake manager lock
// before the hostinfo reaches the handshake loop or the static-host trigger, so the address is
// in the RemoteList before the first handshake is sent.
ifce.handshakeManager.StartHandshake(vpnAddr, func(hh *HandshakeHostInfo) {
if addr.IsValid() {
hh.hostinfo.SetRemote(addr)
}
})
return w.WriteLine("Created")
}