ipn/ipnlocal,wgengine/magicsock: send TSMPDiscoAdvert on wg established

Instead of using CallMeMaybe to trigger the sending of TSMPDiscoAdverts,
use a new event trigger based on
https://github.com/tailscale/wireguard-go/pull/67 to send out the
messages once a connection is established (from the perspective of wg).

This does have an issue where a rekey event due to a restart of one node
will not trigger a TSMP disco message being sent from the non-restarting
node, which has the consequence of keeping a connection on DERP until a
connection to control is established or the connection times out from
wireguard (due to no traffic) and a new connection is initiated.

Updates #20081

Signed-off-by: Claus Lensbøl <claus@tailscale.com>
This commit is contained in:
Claus Lensbøl
2026-07-08 16:16:09 -04:00
parent 2051c5f358
commit 687ac2cc0d
2 changed files with 13 additions and 4 deletions

View File

@@ -5830,6 +5830,9 @@ func (b *LocalBackend) handlePeerWireGuardState(peerKey key.NodePublic, st ipn.P
delete(b.peerWGStableIDByKey, peerKey)
addPeerWGStateMetric(old.PeerWireGuardState, -1)
} else {
if st == ipn.PeerWireGuardStateEstablished {
b.MagicConn().MaybeSendTSMPDiscoAdvert(peerKey)
}
old := b.peerWGState[id].PeerWireGuardState
if old == st {
return

View File

@@ -2678,7 +2678,7 @@ func (c *Conn) enqueueCallMeMaybe(derpAddr netip.AddrPort, de *endpoint) {
return
}
c.maybeSendTSMPDiscoAdvert(de)
//c.maybeSendTSMPDiscoAdvert(de)
eps := make([]netip.AddrPort, 0, len(c.lastEndpoints))
for _, ep := range c.lastEndpoints {
@@ -4552,6 +4552,12 @@ type NewDiscoKeyAvailable struct {
NodeID tailcfg.NodeID
}
func (c *Conn) MaybeSendTSMPDiscoAdvert(nk key.NodePublic) {
if ep, ok := c.peerMap.endpointForNodeKey(nk); ok {
c.maybeSendTSMPDiscoAdvert(ep)
}
}
// maybeSendTSMPDiscoAdvert conditionally emits an event indicating that we
// should send our DiscoKey to the first node address of the magicksock endpoint.
//
@@ -4572,9 +4578,9 @@ func (c *Conn) maybeSendTSMPDiscoAdvert(de *endpoint) {
// here has pathological behaviors. Therefore, it should be disabled for
// almost all tailnets, and we lean on the network map caching control knob
// for this purpose. See #20081.
if c.controlKnobs == nil || !c.controlKnobs.CacheNetworkMaps.Load() {
return
}
//if c.controlKnobs == nil || !c.controlKnobs.CacheNetworkMaps.Load() {
// return
//}
de.mu.Lock()
defer de.mu.Unlock()