feature/relayserver,ipn/ipnlocal,net/udprelay: plumb DERPMap (#17881)

This commit replaces usage of local.Client in net/udprelay with DERPMap
plumbing over the eventbus. This has been a longstanding TODO. This work
was also accelerated by a memory leak in net/http when using
local.Client over long periods of time. So, this commit also addresses
said leak.

Updates #17801

Signed-off-by: Jordan Whited <jordan@tailscale.com>
This commit is contained in:
Jordan Whited
2025-11-13 20:57:48 -08:00
committed by GitHub
parent 146ea42822
commit 9e4d1fd87f
4 changed files with 324 additions and 169 deletions

View File

@@ -21,7 +21,6 @@ import (
"go4.org/mem"
"golang.org/x/net/ipv6"
"tailscale.com/client/local"
"tailscale.com/disco"
"tailscale.com/net/batching"
"tailscale.com/net/netaddr"
@@ -32,6 +31,7 @@ import (
"tailscale.com/net/stun"
"tailscale.com/net/udprelay/endpoint"
"tailscale.com/net/udprelay/status"
"tailscale.com/tailcfg"
"tailscale.com/tstime"
"tailscale.com/types/key"
"tailscale.com/types/logger"
@@ -72,7 +72,8 @@ type Server struct {
closeCh chan struct{}
netChecker *netcheck.Client
mu sync.Mutex // guards the following fields
mu sync.Mutex // guards the following fields
derpMap *tailcfg.DERPMap
addrDiscoveryOnce bool // addrDiscovery completed once (successfully or unsuccessfully)
addrPorts []netip.AddrPort // the ip:port pairs returned as candidate endpoints
closed bool
@@ -374,15 +375,12 @@ func (s *Server) addrDiscoveryLoop() {
}
}
// fetch DERPMap to feed to netcheck
derpMapCtx, derpMapCancel := context.WithTimeout(context.Background(), time.Second)
defer derpMapCancel()
localClient := &local.Client{}
// TODO(jwhited): We are in-process so use eventbus or similar.
// local.Client gets us going.
dm, err := localClient.CurrentDERPMap(derpMapCtx)
if err != nil {
return nil, err
dm := s.getDERPMap()
if dm == nil {
// We don't have a DERPMap which is required to dynamically
// discover external addresses, but we can return the endpoints we
// do have.
return addrPorts.Slice(), nil
}
// get addrPorts as visible from DERP
@@ -864,3 +862,21 @@ func (s *Server) GetSessions() []status.ServerSession {
}
return sessions
}
// SetDERPMapView sets the [tailcfg.DERPMapView] to use for future netcheck
// reports.
func (s *Server) SetDERPMapView(view tailcfg.DERPMapView) {
s.mu.Lock()
defer s.mu.Unlock()
if !view.Valid() {
s.derpMap = nil
return
}
s.derpMap = view.AsStruct()
}
func (s *Server) getDERPMap() *tailcfg.DERPMap {
s.mu.Lock()
defer s.mu.Unlock()
return s.derpMap
}