From 5f42489e00ef0dccb6fa65c98bf43822b5801347 Mon Sep 17 00:00:00 2001 From: Simon Law Date: Mon, 18 May 2026 14:07:07 -0700 Subject: [PATCH] ipn/localapi,net/captivedetection,net/netcheck: track DERPRegion.Active In PR #15245, we deprecated the tailscale.com/tailcfg.DERPRegion.Avoid field because its implementation had drifted from its documented meaning. Yet it is still being used in some specific cases. This patch adds metrics to track when the Avoid flag is set so we can burn down any lingering uses and eliminate them. Updates tailscale/corp#24697 Fixes #19793 Signed-off-by: Simon Law --- ipn/localapi/debugderp.go | 6 ++++++ net/captivedetection/endpoints.go | 11 ++++++++++- net/netcheck/netcheck.go | 14 ++++++++++++-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/ipn/localapi/debugderp.go b/ipn/localapi/debugderp.go index 52987ee0a..755edc93e 100644 --- a/ipn/localapi/debugderp.go +++ b/ipn/localapi/debugderp.go @@ -25,8 +25,13 @@ "tailscale.com/tailcfg" "tailscale.com/types/key" "tailscale.com/types/nettype" + "tailscale.com/util/clientmetric" ) +// MetricDERPRegionAvoidTrue tracks the usage of DERPRegion.Avoid in the DERPMap +// as it gets replaced with better alternatives. See tailscale/corp#24697. +var metricDERPRegionAvoidTrue = clientmetric.NewCounter("localapi_derpregion_avoid_true") + func (h *Handler) serveDebugDERPRegion(w http.ResponseWriter, r *http.Request) { if !h.PermitWrite { http.Error(w, "debug access denied", http.StatusForbidden) @@ -70,6 +75,7 @@ func (h *Handler) serveDebugDERPRegion(w http.ResponseWriter, r *http.Request) { } if reg.Avoid { + metricDERPRegionAvoidTrue.Add(1) st.Warnings = append(st.Warnings, "Region is marked with Avoid bit") } if len(reg.Nodes) == 0 { diff --git a/net/captivedetection/endpoints.go b/net/captivedetection/endpoints.go index 5c1d31d0c..c72192927 100644 --- a/net/captivedetection/endpoints.go +++ b/net/captivedetection/endpoints.go @@ -15,8 +15,13 @@ "tailscale.com/net/dnsfallback" "tailscale.com/tailcfg" "tailscale.com/types/logger" + "tailscale.com/util/clientmetric" ) +// MetricDERPRegionAvoidTrue tracks the usage of DERPRegion.Avoid in the DERPMap +// as it gets replaced with better alternatives. See tailscale/corp#24697. +var metricDERPRegionAvoidTrue = clientmetric.NewCounter("captivedetection_derpregion_avoid_true") + // EndpointProvider is an enum that represents the source of an Endpoint. type EndpointProvider int @@ -89,7 +94,11 @@ func availableEndpoints(derpMap *tailcfg.DERPMap, preferredDERPRegionID int, log // Use the DERP IPs as captive portal detection endpoints. Using IPs is better than hostnames // because they do not depend on DNS resolution. for _, region := range derpMap.Regions { - if region.Avoid || region.NoMeasureNoHome { + if region.Avoid { + metricDERPRegionAvoidTrue.Add(1) + continue + } + if region.NoMeasureNoHome { continue } for _, node := range region.Nodes { diff --git a/net/netcheck/netcheck.go b/net/netcheck/netcheck.go index a64c358c5..b87cff990 100644 --- a/net/netcheck/netcheck.go +++ b/net/netcheck/netcheck.go @@ -394,8 +394,11 @@ func sortRegions(dm *tailcfg.DERPMap, last *Report, preferredDERP int) (prev []* continue } // include an otherwise avoid region if it is the current preferred region - if reg.Avoid && reg.RegionID != preferredDERP { - continue + if reg.Avoid { + metricDERPRegionAvoidTrue.Add(1) + if reg.RegionID != preferredDERP { + continue + } } prev = append(prev, reg) } @@ -964,6 +967,9 @@ func (c *Client) GetReport(ctx context.Context, dm *tailcfg.DERPMap, opts *GetRe var wg sync.WaitGroup var need []*tailcfg.DERPRegion for rid, reg := range dm.Regions { + if reg.Avoid { + metricDERPRegionAvoidTrue.Add(1) + } if !rs.haveRegionLatency(rid) && regionHasDERPNode(reg) && !reg.Avoid && !reg.NoMeasureNoHome { need = append(need, reg) } @@ -1713,4 +1719,8 @@ func conciseOptBool(b opt.Bool, trueVal string) string { metricSTUNRecv4 = clientmetric.NewCounter("netcheck_stun_recv_ipv4") metricSTUNRecv6 = clientmetric.NewCounter("netcheck_stun_recv_ipv6") metricHTTPSend = clientmetric.NewCounter("netcheck_https_measure") + + // MetricDERPRegionAvoidTrue tracks the usage of DERPRegion.Avoid in the DERPMap + // as it gets replaced with better alternatives. See tailscale/corp#24697. + metricDERPRegionAvoidTrue = clientmetric.NewCounter("netcheck_derpregion_avoid_true") )