Most /etc/os-release files set the VERSION_ID to a `MAJOR.MINOR`
string, but we were trying to compare this numerically against a major
version number. I can only assume that Linux Mint used switched from a
plain integer, since shells only do integer comparisons.
This patch extracts a VERSION_MAJOR from the VERSION_ID using
parameter expansion and unifies all the other ad-hoc comparisons to
use it.
Fixes#15841
Signed-off-by: Simon Law <sfllaw@tailscale.com>
Co-authored-by: Xavier <xhienne@users.noreply.github.com>
This patch removes some code that didn’t get removed before merging
the changes in #16580.
Updates #cleanup
Updates #16551
Signed-off-by: Simon Law <sfllaw@tailscale.com>
The control plane will sometimes determine that a node is not online,
while the node is still able to connect to its peers. This patch
doesn’t solve this problem, but it does mitigate it.
This PR introduces the `client-side-reachability` node attribute that
switches the node to completely ignore the online signal from control.
In the future, the client itself should collect reachability data from
active Wireguard flows and Tailscale pings.
Updates #17366
Updates tailscale/corp#30379
Updates tailscale/corp#32686
Signed-off-by: Simon Law <sfllaw@tailscale.com>
PR #17258 extracted `derp.Server` into `derp/derpserver.Server`.
This followup patch adds the following cleanups:
1. Rename `derp_server*.go` files to `derpserver*.go` to match
the package name.
2. Rename the `derpserver.NewServer` constructor to `derpserver.New`
to reduce stuttering.
3. Remove the unnecessary `derpserver.Conn` type alias.
Updates #17257
Updates #cleanup
Signed-off-by: Simon Law <sfllaw@tailscale.com>
Apparently, #16989 introduced a bug in request-dataplane-review.yml:
> you may only define one of `paths` and `paths-ignore` for a single event
Related #16372
Updates #cleanup
Signed-off-by: Simon Law <sfllaw@tailscale.com>
@tailscale/dataplane almost never needs to review depaware.txt, when
it is the only change to the DERP implementation.
Related #16372
Updates #cleanup
Signed-off-by: Simon Law <sfllaw@tailscale.com>
In #16625, I introduced a mechanism for sending the selected exit node
to Control via tailcfg.Hostinfo.ExitNodeID as part of the MapRequest.
@nickkhyl pointed out that LocalBackend.doSetHostinfoFilterServices
needs to be triggered in order to actually send this update. This
patch adds that command. It also prevents the client from sending
"auto:any" in that field, because that’s not a real exit node ID.
This patch also fills in some missing checks in TestConfigureExitNode.
Updates tailscale/corp#30536
Signed-off-by: Simon Law <sfllaw@tailscale.com>
When a client selects a particular exit node, Control may use that as
a signal for deciding other routes.
This patch causes the client to report whenever the current exit node
changes, through tailcfg.Hostinfo.ExitNodeID. It relies on a properly
set ipn.Prefs.ExitNodeID, which should already be resolved by
`tailscale set`.
Updates tailscale/corp#30536
Signed-off-by: Simon Law <sfllaw@tailscale.com>
Package geo provides functionality to represent and process
geographical locations on a sphere. The main type, geo.Point,
represents a pair of latitude and longitude coordinates.
Updates tailscale/corp#29968
Signed-off-by: Simon Law <sfllaw@tailscale.com>
With auto exit nodes enabled, the client picks exit nodes from the
ones advertised in the network map. Usually, it picks the one with the
highest priority score, but when the top spot is tied, it used to pick
randomly. Then, once it made a selection, it would strongly prefer to
stick with that exit node. It wouldn’t even consider another exit node
unless the client was shutdown or the exit node went offline. This is
to prevent flapping, where a client constantly chooses a different
random exit node.
The major problem with this algorithm is that new exit nodes don’t get
selected as often as they should. In fact, they wouldn’t even move
over if a higher scoring exit node appeared.
Let’s say that you have an exit node and it’s overloaded. So you spin
up a new exit node, right beside your existing one, in the hopes that
the traffic will be split across them. But since the client had this
strong affinity, they stick with the exit node they know and love.
Using rendezvous hashing, we can have different clients spread
their selections equally across their top scoring exit nodes. When an
exit node shuts down, its clients will spread themselves evenly to
their other equal options. When an exit node starts, a proportional
number of clients will migrate to their new best option.
Read more: https://en.wikipedia.org/wiki/Rendezvous_hashing
The trade-off is that starting up a new exit node may cause some
clients to move over, interrupting their existing network connections.
So this change is only enabled for tailnets with `traffic-steering`
enabled.
Updates tailscale/corp#29966
Fixes#16551
Signed-off-by: Simon Law <sfllaw@tailscale.com>
@nickkyl added an peer.Online check to suggestExitNodeUsingDERP, so it
should also check when running suggestExitNodeUsingTrafficSteering.
Updates tailscale/corp#29966
Signed-off-by: Simon Law <sfllaw@tailscale.com>
Thanks to @nickkhyl for pointing out that NetMap.Peers doesn’t get
incremental updates since the last full NetMap update. Instead, he
recommends using ipn/ipnlocal.nodeBackend.AppendMatchingPeers.
Updates #cleanup
Signed-off-by: Simon Law <sfllaw@tailscale.com>
When `tailscale exit-node suggest` contacts the LocalAPI for a
suggested exit node, the client consults its netmap for peers that
contain the `suggest-exit-node` peercap. It currently uses a series of
heuristics to determine the exit node to suggest.
When the `traffic-steering` feature flag is enabled on its tailnet,
the client will defer to Control’s priority scores for a particular
peer. These scores, in `tailcfg.Hostinfo.Location.Priority`, were
historically only used for Mullvad exit nodes, but they have now been
extended to score any peer that could host a redundant resource.
Client capability version 119 is the earliest client that understands
these traffic steering scores. Control tells the client to switch to
rely on these scores by adding `tailcfg.NodeAttrTrafficSteering` to
its `AllCaps`.
Updates tailscale/corp#29966
Signed-off-by: Simon Law <sfllaw@tailscale.com>
To signal when a tailnet has the `traffic-steering` feature flag,
Control will send a `traffic-steering` NodeCapability in netmap’s
AllCaps.
This patch adds `tailcfg.NodeAttrTrafficSteering` so that it can be
used in the control plane. Future patches will implement the actual
steering mechanisms.
Updates tailscale/corp#29966
Signed-off-by: Simon Law <sfllaw@tailscale.com>
When running `tailscale exit-node list`, an empty city or country name
should be displayed as a hyphen "-". However, this only happened when
there was no location at all. If a node provides a Hostinfo.Location,
then the list would display exactly what was provided.
This patch changes the listing so that empty cities and countries will
either render the provided name or "-".
Fixes#16500
Signed-off-by: Simon Law <sfllaw@tailscale.com>
GitHub used to recommend the tibdex/github-app-token GitHub Action
until they wrote their own actions/create-github-app-token.
This patch replaces the use of the third-party action with the
official one.
Updates #cleanup
Signed-off-by: Simon Law <sfllaw@tailscale.com>
For any changes that involve DERP, automatically add the
@tailscale/dataplane team as a reviewer.
Updates #cleanup
Signed-off-by: Simon Law <sfllaw@tailscale.com>
This patch contains the following cleanups:
1. Simplify `ffcli.Command` definitions;
2. Word-wrap help text, consistent with other commands;
3. `tailscale dns --help` usage makes subcommand usage more obvious;
4. `tailscale dns query --help` describes DNS record types.
Updates #cleanup
Signed-off-by: Simon Law <sfllaw@tailscale.com>
To authenticate mesh keys, the DERP servers used a simple == comparison,
which is susceptible to a side channel timing attack.
By extracting the mesh key for a DERP server, an attacker could DoS it
by forcing disconnects using derp.Client.ClosePeer. They could also
enumerate the public Wireguard keys, IP addresses and ports for nodes
connected to that DERP server.
DERP servers configured without mesh keys deny all such requests.
This patch also extracts the mesh key logic into key.DERPMesh, to
prevent this from happening again.
Security bulletin: https://tailscale.com/security-bulletins#ts-2025-003Fixestailscale/corp#28720
Signed-off-by: Simon Law <sfllaw@tailscale.com>
`cmd/derpprobe --once` didn’t respect the convention of non-zero exit
status for a failed run. It would always exit zero (i.e. success),
even. This patch fixes that, but only for `--once` mode.
Fixes: #15925
Signed-off-by: Simon Law <sfllaw@tailscale.com>