ipn/ipnlocal: use routecheck reports to make exit node suggestions
Now that the routecheck subsystem is continuously collecting reachability reports in the background, we can add a hook to LocalBackend for fetching its report. That allows suggestExitNodeUsingTrafficSteering to consult that report when disqualifying candidates, instead of blocking on an immediate probe. Exit node suggestions will only consult the report when the `client-side-reachability` and `client-side-reachability-routecheck` node attributes are both set on the current node. Updates #17366 Updates tailscale/corp#33033 Signed-off-by: Simon Law <sfllaw@tailscale.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// Package peernode contains constants that describe a peer node in the routecheck report.
|
||||
package peernode
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package peernode
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Reachability reports whether a peer node is reachable.
|
||||
type Reachability int
|
||||
|
||||
const (
|
||||
// Unknown is a peer node whose reachability is unknown.
|
||||
// This peer is new and we have yet to probe it.
|
||||
Unknown Reachability = iota
|
||||
// Reachable is a peer node that is reachable from this node.
|
||||
Reachable
|
||||
// Unreachable is a peer node that is unreachable from this node.
|
||||
// This peer is not responding to probes.
|
||||
Unreachable
|
||||
)
|
||||
|
||||
// String implements [fmt.Stringer].
|
||||
func (r Reachability) String() string {
|
||||
switch r {
|
||||
case Unknown:
|
||||
return "Unknown"
|
||||
case Reachable:
|
||||
return "Reachable"
|
||||
case Unreachable:
|
||||
return "Unreachable"
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown %#v", r))
|
||||
}
|
||||
}
|
||||
|
||||
// IsReachable reports if r is [Reachable].
|
||||
func (r Reachability) IsReachable() bool {
|
||||
return r == Reachable
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/go-json-experiment/json/jsontext"
|
||||
jsonv1 "github.com/go-json-experiment/json/v1"
|
||||
|
||||
"tailscale.com/net/routecheck/peernode"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/util/clientmetric"
|
||||
"tailscale.com/util/mak"
|
||||
@@ -46,6 +47,19 @@ type Report struct {
|
||||
LastProbed map[tailcfg.NodeID]time.Time `json:"-"` // not marshaled
|
||||
}
|
||||
|
||||
// IsReachable reports whether a peer is reachable by the current node.
|
||||
func (rp Report) IsReachable(id tailcfg.NodeID) peernode.Reachability {
|
||||
// TODO(sfllaw): We should actually track all routers and consider the
|
||||
// absence of a router in the report as it being recently added for
|
||||
// consideration, so it is unknown. Then we should positively track
|
||||
// whether a node was reachable or not.
|
||||
_, k := rp.Reachable[id]
|
||||
if k {
|
||||
return peernode.Reachable
|
||||
}
|
||||
return peernode.Unknown
|
||||
}
|
||||
|
||||
// RoutablePrefixes returns a map of routable network prefixes associated with
|
||||
// each prefix’s routers that were reachable by the current host,
|
||||
// at the time the report was finished.
|
||||
|
||||
Reference in New Issue
Block a user