mirror of
https://github.com/tailscale/tailscale.git
synced 2026-04-04 22:53:38 -04:00
net/udprelay: advertise addresses from cloud metadata service (#18368)
Polls IMDS (currently only AWS) for extra IPs to advertise as udprelay. Updates #17796 Change-Id: Iaaa899ef4575dc23b09a5b713ce6693f6a6a6964 Signed-off-by: Alex Valiushko <alexvaliushko@tailscale.com>
This commit is contained in:
@@ -423,7 +423,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
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"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"
|
||||
@@ -81,6 +82,7 @@ type Server struct {
|
||||
netChecker *netcheck.Client
|
||||
metrics *metrics
|
||||
netMon *netmon.Monitor
|
||||
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
|
||||
@@ -336,6 +338,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)
|
||||
@@ -402,11 +405,13 @@ func (s *Server) startPacketReaders() {
|
||||
|
||||
func (s *Server) addrDiscoveryLoop() {
|
||||
defer s.wg.Done()
|
||||
|
||||
timer := time.NewTimer(0) // fire immediately
|
||||
defer timer.Stop()
|
||||
|
||||
getAddrPorts := func() ([]netip.AddrPort, error) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
var addrPorts set.Set[netip.AddrPort]
|
||||
addrPorts.Make()
|
||||
|
||||
@@ -425,6 +430,21 @@ func (s *Server) addrDiscoveryLoop() {
|
||||
}
|
||||
}
|
||||
|
||||
// Get cloud metadata service addresses.
|
||||
// TODO(illotum) Same is done within magicsock, consider caching within cloudInfo
|
||||
cloudIPs, err := s.cloudInfo.GetPublicIPs(ctx)
|
||||
if err == nil { // Not handling the err, GetPublicIPs already printed to log.
|
||||
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
|
||||
@@ -434,9 +454,7 @@ func (s *Server) addrDiscoveryLoop() {
|
||||
}
|
||||
|
||||
// get addrPorts as visible from DERP
|
||||
netCheckerCtx, netCheckerCancel := context.WithTimeout(context.Background(), netcheck.ReportTimeout)
|
||||
defer netCheckerCancel()
|
||||
rep, err := s.netChecker.GetReport(netCheckerCtx, dm, &netcheck.GetReportOpts{
|
||||
rep, err := s.netChecker.GetReport(ctx, dm, &netcheck.GetReportOpts{
|
||||
OnlySTUN: true,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -474,6 +492,8 @@ func (s *Server) addrDiscoveryLoop() {
|
||||
// Mirror magicsock behavior for duration between STUN. We consider
|
||||
// 30s a min bound for NAT timeout.
|
||||
timer.Reset(tstime.RandomDurationBetween(20*time.Second, 26*time.Second))
|
||||
// TODO(illotum) Pass in context bound to the [s.closeCh] lifetime,
|
||||
// and do not block on getAddrPorts IO.
|
||||
addrPorts, err := getAddrPorts()
|
||||
if err != nil {
|
||||
s.logf("error discovering IP:port candidates: %v", err)
|
||||
|
||||
Reference in New Issue
Block a user