diff --git a/client/local/routecheck.go b/client/local/routecheck.go index dc9242232..bf64842f7 100644 --- a/client/local/routecheck.go +++ b/client/local/routecheck.go @@ -7,15 +7,24 @@ import ( "context" + "errors" "fmt" + "net/http" "tailscale.com/net/routecheck" ) +// ErrReportPending is returned by [Client.RouteCheck] and [Client.RouteCheckProbe] +// when the report is pending. +var ErrRouteCheckReportUnavailable = errors.New("report pending") + // RouteCheckProbe performs a routecheck probe and waits for its report. func (lc *Client) RouteCheckProbe(ctx context.Context) (*routecheck.Report, error) { - body, err := lc.send(ctx, "POST", "/localapi/v0/routecheck?probe=true", 200, nil) + body, err := lc.send(ctx, "POST", "/localapi/v0/routecheck?probe=true", http.StatusOK, nil) if err != nil { + if hs, ok := errors.AsType[httpStatusError](err); ok && hs.HTTPStatus == http.StatusNoContent { + return nil, ErrRouteCheckReportUnavailable + } return nil, fmt.Errorf("error %w: %s", err, body) } return decodeJSON[*routecheck.Report](body) @@ -23,8 +32,11 @@ func (lc *Client) RouteCheckProbe(ctx context.Context) (*routecheck.Report, erro // RouteCheck requests the report compiled by the latest routecheck probe. func (lc *Client) RouteCheck(ctx context.Context) (*routecheck.Report, error) { - body, err := lc.send(ctx, "POST", "/localapi/v0/routecheck", 200, nil) + body, err := lc.send(ctx, "POST", "/localapi/v0/routecheck", http.StatusOK, nil) if err != nil { + if hs, ok := errors.AsType[httpStatusError](err); ok && hs.HTTPStatus == http.StatusNoContent { + return nil, ErrRouteCheckReportUnavailable + } return nil, fmt.Errorf("error %w: %s", err, body) } return decodeJSON[*routecheck.Report](body) diff --git a/net/routecheck/routes.go b/net/routecheck/routes.go index c646f3894..ad1b663e2 100644 --- a/net/routecheck/routes.go +++ b/net/routecheck/routes.go @@ -39,11 +39,10 @@ func (c *Client) RoutersByPrefix() RoutersByPrefix { // The result omits any prefix that is one of the node’s local addresses. func routes(n tailcfg.NodeView) []netip.Prefix { var routes []netip.Prefix -AllowedIPs: for _, pfx := range n.AllowedIPs().All() { // Routers never forward their own local addresses. if views.SliceContains(n.Addresses(), pfx) { - continue AllowedIPs + continue } routes = append(routes, pfx) }