From 843c59dde9d820c0b9ce6dc7015d27be04deb46a Mon Sep 17 00:00:00 2001 From: Alex Valiushko Date: Thu, 8 Jan 2026 14:53:33 -0800 Subject: [PATCH] net/udprelay: advertise addresses from cloud metadata service Polls IMDS (currently only AWS) for extra IPs to advertise as udprelay. Updates #17796 Signed-off-by: Alex Valiushko Change-Id: Iaaa899ef4575dc23b09a5b713ce6693f6a6a6964 --- cmd/tailscaled/depaware.txt | 2 +- net/udprelay/server.go | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/cmd/tailscaled/depaware.txt b/cmd/tailscaled/depaware.txt index ed8f6a512..a49cefa63 100644 --- a/cmd/tailscaled/depaware.txt +++ b/cmd/tailscaled/depaware.txt @@ -422,7 +422,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de tailscale.com/util/cibuild from tailscale.com/health+ tailscale.com/util/clientmetric from tailscale.com/control/controlclient+ tailscale.com/util/cloudenv from tailscale.com/net/dns/resolver+ - tailscale.com/util/cloudinfo from tailscale.com/wgengine/magicsock + tailscale.com/util/cloudinfo from tailscale.com/wgengine/magicsock+ tailscale.com/util/cmpver from tailscale.com/net/dns+ tailscale.com/util/ctxkey from tailscale.com/ipn/ipnlocal+ 💣 tailscale.com/util/deephash from tailscale.com/util/syspolicy/setting diff --git a/net/udprelay/server.go b/net/udprelay/server.go index acdbf5ad6..26117a57a 100644 --- a/net/udprelay/server.go +++ b/net/udprelay/server.go @@ -41,6 +41,7 @@ import ( "tailscale.com/types/logger" "tailscale.com/types/nettype" "tailscale.com/types/views" + "tailscale.com/util/cloudinfo" "tailscale.com/util/eventbus" "tailscale.com/util/set" "tailscale.com/util/usermetric" @@ -78,6 +79,7 @@ type Server struct { closeCh chan struct{} netChecker *netcheck.Client metrics *metrics + cloudInfo *cloudinfo.CloudInfo // used to query cloud metadata services mu sync.Mutex // guards the following fields macSecrets views.Slice[[blake2s.Size]byte] // [0] is most recent, max 2 elements @@ -333,6 +335,7 @@ func NewServer(logf logger.Logf, port uint16, onlyStaticAddrPorts bool, metrics onlyStaticAddrPorts: onlyStaticAddrPorts, serverEndpointByDisco: make(map[key.SortedPairOfDiscoPublic]*serverEndpoint), nextVNI: minVNI, + cloudInfo: cloudinfo.New(logf), } s.discoPublic = s.disco.Public() s.metrics = registerMetrics(metrics) @@ -398,6 +401,8 @@ func (s *Server) startPacketReaders() { func (s *Server) addrDiscoveryLoop() { defer s.wg.Done() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() // propagate [s.closeCh] to ctx timer := time.NewTimer(0) // fire immediately defer timer.Stop() @@ -421,6 +426,22 @@ func (s *Server) addrDiscoveryLoop() { } } + // get cloud metadata service addresses + cloudIPs, err := s.cloudInfo.GetPublicIPs(ctx) + if err != nil { + s.logf("error querying cloud metadata service IPs: %v", err) + } else { + for _, ip := range cloudIPs { + if ip.IsValid() { + if ip.Is4() { + addrPorts.Add(netip.AddrPortFrom(ip, s.uc4Port)) + } else { + addrPorts.Add(netip.AddrPortFrom(ip, s.uc6Port)) + } + } + } + } + dm := s.getDERPMap() if dm == nil { // We don't have a DERPMap which is required to dynamically