wgengine/{,magicsock},tstest/natlab/vmtest: send disco on cached netmap (#19878)
Originally found when adding tests for working with cached netmaps, and finding the added tests to be flakey. When working off of a cached netmap, if a node exists in the cached netmap but does not yet have any endpoints, DERP connections are available but not direct ones. By sending callMeMaybe to nodes without endpoints in the cached netmap, we can establish direct connections for this edge case. Aditionally, ensure that TSMP disco advert messages are not sent if the endpoint does not have a valid address yet. Fixes #19843 Updates #19597 Signed-off-by: Claus Lensbøl <claus@tailscale.com>
This commit is contained in:
@@ -1381,12 +1381,19 @@ func (de *endpoint) sendDiscoPingsLocked(now mono.Time, sendCallMeMaybe bool) {
|
||||
de.startDiscoPingLocked(epAddr{ap: ep}, now, pingDiscovery, 0, nil)
|
||||
}
|
||||
derpAddr := de.derpAddr
|
||||
if sentAny && sendCallMeMaybe && derpAddr.IsValid() {
|
||||
if sendCallMeMaybe && derpAddr.IsValid() && (sentAny || de.c.usingCachedNetmap.Load()) {
|
||||
// Have our magicsock.Conn figure out its STUN endpoint (if
|
||||
// it doesn't know already) and then send a CallMeMaybe
|
||||
// message to our peer via DERP informing them that we've
|
||||
// sent so our firewall ports are probably open and now
|
||||
// would be a good time for them to connect.
|
||||
//
|
||||
// When working off of a cached netmap, send out a CallMeMaybe
|
||||
// even if we don't know about any peer endpoints.
|
||||
// Since we cannot rely on control to transfer endpoints for us,
|
||||
// this makes establishing direct connections more reliable
|
||||
// as the peer will respond with its own message and initiate
|
||||
// the connection.
|
||||
go de.c.enqueueCallMeMaybe(derpAddr, de)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4444,6 +4444,10 @@ func (c *Conn) maybeSendTSMPDiscoAdvert(de *endpoint) {
|
||||
de.mu.Lock()
|
||||
defer de.mu.Unlock()
|
||||
|
||||
if !de.nodeAddr.IsValid() {
|
||||
return
|
||||
}
|
||||
|
||||
now := mono.Now()
|
||||
if now.Sub(de.lastDiscoKeyAdvertisement) <= discoKeyAdvertisementInterval ||
|
||||
(!de.lastDiscoKeyAdvertisement.IsZero() && de.bestAddr.isDirect()) {
|
||||
|
||||
@@ -614,6 +614,9 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
|
||||
})
|
||||
var tsmpRequestGroup singleflight.Group[netip.Addr, struct{}]
|
||||
eventbus.SubscribeFunc(ec, func(req magicsock.NewDiscoKeyAvailable) {
|
||||
if !req.NodeFirstAddr.IsValid() {
|
||||
return
|
||||
}
|
||||
go tsmpRequestGroup.Do(req.NodeFirstAddr, func() (struct{}, error) {
|
||||
e.sendTSMPDiscoAdvertisement(req.NodeFirstAddr)
|
||||
e.logf("wgengine: sending TSMP disco key advertisement to %v", req.NodeFirstAddr)
|
||||
|
||||
Reference in New Issue
Block a user