Prepare for path MTU discovery by splitting up the concept of
DefaultMTU() into the concepts of the Tailscale TUN MTU, MTUs of
underlying network interfaces, minimum "safe" TUN MTU, user configured
TUN MTU, probed path MTU to a peer, and maximum probed MTU. Add a set
of likely MTUs to probe.
Updates #311
Signed-off-by: Val <valerie@tailscale.com>
Use buffer pools for UDP packet forwarding to prepare for increasing the
forwarded UDP packet size for peer path MTU discovery.
Updates #311
Co-authored-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Signed-off-by: Val <valerie@tailscale.com>
Replace CanPMTUD() with ShouldPMTUD() to check if peer path MTU discovery should
be enabled, in preparation for adding support for enabling/disabling peer MTU
dynamically.
Updated #311
Signed-off-by: Val <valerie@tailscale.com>
Add an enable/disable argument to setDontFragment() in preparation for dynamic
enable/disable of peer path MTU discovery. Add getDontFragment() to get the
status of the don't fragment bit from a socket.
Updates #311
Co-authored-by: James Tucker <james@tailscale.com>
Signed-off-by: Val <valerie@tailscale.com>
Use IPV6_MTU_DISCOVER for setting don't fragment on IPv6 sockets on Linux (was
using IP_MTU_DISCOVER, the IPv4 arg).
Updates #311
Signed-off-by: Val <valerie@tailscale.com>
Make the debugknob variable name for enabling peer path MTU discovery match the
env variable name.
Updates #311
Signed-off-by: Val <valerie@tailscale.com>
This PR plumbs through awareness of an IPv6 SNAT/masquerade address from the wire protocol
through to the low-level (tstun / wgengine). This PR is the first in two PRs for implementing
IPv6 NAT support to/from peers.
A subsequent PR will implement the data-plane changes to implement IPv6 NAT - this is just plumbing.
Signed-off-by: Tom DNetto <tom@tailscale.com>
Updates ENG-991
This adds a new RawMessage type backed by string instead of the
json.RawMessage which is backed by []byte. The byte slice makes
the generated views be a lot more defensive than the need to be
which we can get around by using a string instead.
Updates #cleanup
Signed-off-by: Maisem Ali <maisem@tailscale.com>
And convert all callers over to the methods that check SelfNode.
Now we don't have multiple ways to express things in tests (setting
fields on SelfNode vs NetworkMap, sometimes inconsistently) and don't
have multiple ways to check those two fields (often only checking one
or the other).
Updates #9443
Change-Id: I2d7ba1cf6556142d219fae2be6f484f528756e3c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
NetworkMap.Addresses is redundant with the SelfNode.Addresses. This
works towards a TODO to delete NetworkMap.Addresses and replace it
with a method.
This is similar to #9389.
Updates #cleanup
Change-Id: Id000509ca5d16bb636401763d41bdb5f38513ba0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
tailcfg.Node zero-value clone equality checks failed when I added a
[]*foo to the structure, as the zero value and it's clone contained a
different slice header.
Updates #9377
Updates #9408
Signed-off-by: James Tucker <james@tailscale.com>
It has one user (LocalBackend) which can ask magicsock itself.
Updates #cleanup
Change-Id: I8c03cbb1e5ba57b0b442621b5fa467030c14a2e2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
(continuing the mission of removing rando methods from the Engine
interface that we don't need anymore)
Updates #cleanup
Change-Id: Id5190917596bf04d7185c3b331a852724a3f5a16
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It was only used by Android, until
https://github.com/tailscale/tailscale-android/pull/131
which does the call to the netMon directly instead.
Updates #cleanup
Change-Id: Iab8a1d8f1e63250705835c75f40e2cd8c1c4d5b8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
LocalBackend can talk to magicsock on its own to do this without
the "Engine" being involved.
(Continuing a little side quest of cleaning up the Engine
interface...)
Updates #cleanup
Change-Id: I8654acdca2b883b1bd557fdc0cfb90cd3a418a62
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It had exactly one user: netstack. Just have LocalBackend notify
netstack when here's a new netmap instead, simplifying the bloated
Engine interface that has grown a bunch of non-Engine-y things.
(plenty of rando stuff remains after this, but it's a start)
Updates #cleanup
Change-Id: I45e10ab48119e962fc4967a95167656e35b141d8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Currently only the top four most popular changes: endpoints, DERP
home, online, and LastSeen.
Updates #1909
Change-Id: I03152da176b2b95232b56acabfb55dcdfaa16b79
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We're trying to start using that monster type less and eventually get
rid of it.
Updates #1909
Change-Id: I8e1e725bce5324fb820a9be6c7952767863e6542
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I guess we missed this one earlier when we unified the various
copies into set.HandleSet.
Updates #cleanup
Change-Id: I7e6de9ce16e8fc4846abf384dfcc8eaec4d99e60
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This is both more efficient (because the knobs' bool is only updated
whenever Node is changed, rarely) and also gets us one step closer to
removing a case of storing a netmap.NetworkMap in
magicsock. (eventually we want to phase out much of the use of that
type internally)
Updates #1909
Change-Id: I37e81789f94133175064fdc09984e4f3a431f1a1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Previously two tsnet nodes in the same process couldn't have disjoint
sets of controlknob settings from control as both would overwrite each
other's global variables.
This plumbs a new controlknobs.Knobs type around everywhere and hangs
the knobs sent by control on that instead.
Updates #9351
Change-Id: I75338646d36813ed971b4ffad6f9a8b41ec91560
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
In prep for incremental netmap update plumbing (#1909), make peerMap
also keyed by NodeID, as all the netmap node mutations passed around
later will be keyed by NodeID.
In the process, also:
* add envknob.InDevMode, as a signal that we can panic more aggressively
in unexpected cases.
* pull two moderately large blocks of code in Conn.SetNetworkMap out
into their own methods
* convert a few more sets from maps to set.Set
Updates #1909
Change-Id: I7acdd64452ba58e9d554140ee7a8760f9043f961
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I didn't clean up the more idiomatic map[T]bool with true values, at
least yet. I just converted the relatively awkward struct{}-valued
maps.
Updates #cleanup
Change-Id: I758abebd2bb1f64bc7a9d0f25c32298f4679c14f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Replace %w verb with %v verb when logging errors.
Use %w only for wrapping errors with fmt.Errorf()
Fixes: #9213
Signed-off-by: Craig Rodrigues <rodrigc@crodrigues.org>
I'm not saying it works, but it compiles.
Updates #5794
Change-Id: I2f3c99732e67fe57a05edb25b758d083417f083e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Upcoming work on incremental netmap change handling will require some
replumbing of which subsystems get notified about what. Done naively,
it could break "tailscale status --json" visibility later. To make sure
I understood the flow of all the updates I was rereading the status code
and realized parts of ipnstate.Status were being populated by the wrong
subsystems.
The engine (wireguard) and magicsock (data plane, NAT traveral) should
only populate the stuff that they uniquely know. The WireGuard bits
were fine but magicsock was populating stuff stuff that LocalBackend
could've better handled, so move it there.
Updates #1909
Change-Id: I6d1b95d19a2d1b70fbb3c875fac8ea1e169e8cb0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
If we don't have the ICMP hint available, such as on Android, we can use
the signal of rx traffic to bias toward a particular endpoint.
We don't want to stick to a particular endpoint for a very long time
without any signals, so the sticky time is reduced to 1 second, which is
large enough to avoid excessive packet reordering in the common case,
but should be small enough that either rx provides a strong signal, or
we rotate in a user-interactive schedule to another endpoint, improving
the feel of failover to other endpoints.
Updates #8999
Co-authored-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Signed-off-by: James Tucker <james@tailscale.com>
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
There are cases where we do not detect the non-viability of a route, but
we will instead observe a failure to send. In a Disco path this would
normally be handled as a side effect of Disco, which is not available to
non-Disco WireGuard nodes. In both cases, recognizing the failure as
such will result in faster convergence.
Updates #8999
Signed-off-by: James Tucker <james@tailscale.com>
LastFullPing is now used for disco or wireguard only endpoints. This
change updates the comment to make that clear.
Updates #7826
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
There are latency values stored in bestAddr and endpointState that are
no longer applicable after a connectivity change and should be cleared
out, following the documented behavior of the function.
Updates #8999
Signed-off-by: James Tucker <james@tailscale.com>
It was in SelfNode.Hostinfo anyway. The redundant copy was just
costing us an allocation per netmap (a Hostinfo.Clone).
Updates #1909
Change-Id: Ifac568aa5f8054d9419828489442a0f4559bc099
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
When sending a ping from the CLI, only accept a pong that is in reply
to the specific CLI ping we sent.
Updates #311
Signed-off-by: Val <valerie@tailscale.com>
Due to the conflict between our nftables implementation and ufw, which is a common utility used
on linux. We now want to take a step back to prevent regression. This will give us more chance to
let users to test our nftables support and heuristic.
Updates: #391
Signed-off-by: KevinLiang10 <kevinliang@tailscale.com>
Now a nodeAttr: ForceBackgroundSTUN, DERPRoute, TrimWGConfig,
DisableSubnetsIfPAC, DisableUPnP.
Kept support for, but also now a NodeAttr: RandomizeClientPort.
Removed: SetForceBackgroundSTUN, SetRandomizeClientPort (both never
used, sadly... never got around to them. But nodeAttrs are better
anyway), EnableSilentDisco (will be a nodeAttr later when that effort
resumes).
Updates #8923
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
To record wether user is using iptables or nftables after we add support to nftables on linux, we
are adding a field FirewallMode to NetInfo in HostInfo to reflect what firewall mode the host is
running, and form metrics. The information is gained from a global constant in hostinfo.go. We
set it when selection heuristic made the decision, and magicsock reports this to control.
Updates: tailscale/corp#13943
Signed-off-by: KevinLiang10 <kevinliang@tailscale.com>
If a node is flapping or otherwise generating lots of STUN endpoints, we
can end up caching a ton of useless values and sending them to peers.
Instead, let's apply a fixed per-Addr limit of endpoints that we cache,
so that we're only sending peers up to the N most recent.
Updates tailscale/corp#13890
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I8079a05b44220c46da55016c0e5fc96dd2135ef8
The current router errors out when neither iptables nor nftables support is present. We
should fall back to the previous behaviour which we creates a dummy iptablesRunner.
Fixes: #8878
Signed-off-by: KevinLiang10 <kevinliang@tailscale.com>
Netcheck no longer performs I/O itself, instead it makes requests via
SendPacket and expects users to route reply traffic to
ReceiveSTUNPacket.
Netcheck gains a Standalone function that stands up sockets and
goroutines to implement I/O when used in a standalone fashion.
Magicsock now unconditionally routes STUN traffic to the netcheck.Client
that it hosts, and plumbs the send packet sink.
The CLI is updated to make use of the Standalone mode.
Fixes#8723
Signed-off-by: James Tucker <james@tailscale.com>
This sets the Don't Fragment flag, for now behind the
TS_DEBUG_ENABLE_PMTUD envknob.
Updates #311.
Signed-off-by: Val <valerie@tailscale.com>
Signed-off-by: salman <salman@tailscale.com>
This commit replaces the TS_DEBUG_USE_NETLINK_NFTABLES envknob with
a TS_DEBUG_FIREWALL_MODE that should be set to either 'iptables' or
'nftables' to select firewall mode manually, other wise tailscaled
will automatically choose between iptables and nftables depending on
environment and system availability.
updates: #319
Signed-off-by: KevinLiang10 <kevinliang@tailscale.com>
This adds the capability to pad disco ping message payloads to reach a
specified size. It also plumbs it through to the tailscale ping -size
flag.
Disco pings used for actual endpoint discovery do not use this yet.
Updates #311.
Signed-off-by: salman <salman@tailscale.com>
Co-authored-by: Val <valerie@tailscale.com>
The nonce value is not read by anything, and di.sharedKey.Seal()
a few lines below generates its own. #cleanup
Signed-off-by: salman <salman@tailscale.com>
Define PeerCapabilty and PeerCapMap as the new way of sending down
inter-peer capability information.
Previously, this was unstructured and you could only send down strings
which got too limiting for certain usecases. Instead add the ability
to send down raw JSON messages that are opaque to Tailscale but provide
the applications to define them however they wish.
Also update accessors to use the new values.
Updates #4217
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This commit adds nftable rule injection for tailscaled. If tailscaled is
started with envknob TS_DEBUG_USE_NETLINK_NFTABLES = true, the router
will use nftables to manage firewall rules.
Updates: #391
Signed-off-by: KevinLiang10 <kevinliang@tailscale.com>
The MacOS client can't set the MTU when creating the tun due to lack
of permissions, so add it to the router config and have MacOS set it
in the callback using a method that it does have permissions for.
Updates #8219
Signed-off-by: Val <valerie@tailscale.com>
This allows sending logs from the "logpolicy" package (and associated
callees) to something other than the log package. The behaviour for
tailscaled remains the same, passing in log.Printf
Updates #8249
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ie1d43b75fa7281933d9225bffd388462c08a5f31
The server hasn't sent it in ages.
Updates #cleanup
Change-Id: I9695ab0f074ec6fb006e11faf3cdfc5ca049fbf8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This change removes the noV4/noV6 check from addrForSendWireGuardLocked.
On Android, the client panics when reaching `rand.Intn()`, likely due to
the candidates list being containing no candidates. The suspicion is
that the `noV4` and the `noV6` are both being triggered causing the
loop to continue.
Updates tailscale/corp#12938
Updates #7826
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
This change is introducing new netfilterRunner interface and moving iptables manipulation to a lower leveled iptables runner.
For #391
Signed-off-by: KevinLiang10 <kevinliang@tailscale.com>
The netstack code had a bunch of logic to figure out if the LocalBackend should handle an
incoming connection and then would call the function directly on LocalBackend. Move that
logic to LocalBackend and refactor the methods to return conn handlers.
Updates #cleanup
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Switch our best address selection to use a scoring-based approach, where
we boost each address based on whether it's a private IP or IPv6.
For users in cloud environments, this biases endpoint selection towards
using an endpoint that is less likely to cost the user money, and should
be less surprising to users.
This also involves updating the tests to not use private IPv4 addresses;
other than that change, the behaviour should be identical for existing
endpoints.
Updates #8097
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I069e3b399daea28be66b81f7e44fc27b2943d8af
Various BSD-derived operating systems including macOS and FreeBSD
require that ping6 be used for IPv6 destinations. The "ping" command
does not understand an IPv6 destination.
FreeBSD 13.x and later do handle IPv6 in the regular ping command,
but also retain a ping6 command. We use ping6 on all versions of
FreeBSD.
Fixes https://github.com/tailscale/tailscale/issues/8225
Signed-off-by: Denton Gentry <dgentry@tailscale.com>
This is part of an effort to clean up tailscaled initialization between
tailscaled, tailscaled Windows service, tsnet, and the mac GUI.
Updates #8036
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This change introduces address selection for wireguard only endpoints.
If a endpoint has not been used before, an address is randomly selected
to be used based on information we know about, such as if they are able
to use IPv4 or IPv6. When an address is initially selected, we also
initiate a new ICMP ping to the endpoints addresses to determine which
endpoint offers the best latency. This information is then used to
update which endpoint we should be using based on the best possible
route. If the latency is the same for a IPv4 and an IPv6 address, IPv6
will be used.
Updates #7826
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Avoid selecting an endpoint as "better" than the current endpoint if the
total latency improvement is less than 1%. This adds some hysteresis to
avoid flapping between endpoints for a minimal improvement in latency.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: If8312e1768ea65c4b4d4e13d8de284b3825d7a73
On some platforms (notably macOS and iOS) we look up the default
interface to bind outgoing connections to. This is both duplicated
work and results in logspam when the default interface is not available
(i.e. when a phone has no connectivity, we log an error and thus cause
more things that we will try to upload and fail).
Fixed by passing around a netmon.Monitor to more places, so that we can
use its cached interface state.
Fixes#7850
Updates #7621
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
We're using it in more and more places, and it's not really specific to
our use of Wireguard (and does more just link/interface monitoring).
Also removes the separate interface we had for it in sockstats -- it's
a small enough package (we already pull in all of its dependencies
via other paths) that it's not worth the extra complexity.
Updates #7621
Updates #7850
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
This is a follow-up to #7905 that adds two more linters and fixes the corresponding findings. As per the previous PR, this only flags things that are "obviously" wrong, and fixes the issues found.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I8739bdb7bc4f75666a7385a7a26d56ec13741b7c
This adds an initial and intentionally minimal configuration for
golang-ci, fixes the issues reported, and adds a GitHub Action to check
new pull requests against this linter configuration.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I8f38fbc315836a19a094d0d3e986758b9313f163
TestMonitorMode skips by default, without the --monitor flag, and then
it previously ran forever. This adds an option --monitor-duration flag
that defaults to zero (run forever) but if non-zero bounds how long
the tests runs. This means you can then also use e.g. `go test
--cpuprofile` and capture a CPU/mem profile for a minute or two.
Updates #7621
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Previously, when updating endpoints we would immediately stop
advertising any endpoint that wasn't discovered during
determineEndpoints. This could result in, for example, a case where we
performed an incremental netcheck, didn't get any of our three STUN
packets back, and then dropped our STUN endpoint from the set of
advertised endpoints... which would result in clients falling back to a
DERP connection until the next call to determineEndpoints.
Instead, let's cache endpoints that we've discovered and continue
reporting them to clients until a timeout expires. In the above case
where we temporarily don't have a discovered STUN endpoint, we would
continue reporting the old value, then re-discover the STUN endpoint
again and continue reporting it as normal, so clients never see a
withdrawal.
Updates tailscale/coral#108
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I42de72e7418ab328a6c732bdefc74549708cf8b9
The comment still said *magicsock.Conn implemented wireguard-go conn.Bind.
That wasn't accurate anymore.
A doc #cleanup.
Change-Id: I7fd003b939497889cc81147bfb937b93e4f6865c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
So we're staying within the netip.Addr/AddrPort consistently and
avoiding allocs/conversions to the legacy net addr types.
Updates #5162
Change-Id: I59feba60d3de39f773e68292d759766bac98c917
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
These tests are passing locally and on CI. They had failed earlier in
the day when first fixing up CI, and it is not immediately clear why. I
have cycled IPv6 support locally, but this should not have a substantial
effect.
Updates #7876
Signed-off-by: James Tucker <jftucker@gmail.com>
We accidentally switched to ./tool/go in
4022796484 which resulted in no longer
running Windows builds, as this is attempting to run a bash script.
I was unable to quickly fix the various tests that have regressed, so
instead I've added skips referencing #7876, which we need to back and
fix.
Updates #7262
Updates #7876
Signed-off-by: James Tucker <james@tailscale.com>
This also adds a bunch of tests for this function to ensure that we're
returning the proper IP(s) in all cases.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I0d9d57170dbab5f2bf07abdf78ecd17e0e635399
This makes `omitempty` actually work, and saves bytes in each map response.
Updates tailscale/corp#8020
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Using log.Printf may end up being printed out to the console, which
is not desirable. I noticed this when I was investigating some client
logs with `sockstats: trace "NetcheckClient" was overwritten by another`.
That turns to be harmless/expected (the netcheck client will fall back
to the DERP client in some cases, which does its own sockstats trace).
However, the log output could be visible to users if running the
`tailscale netcheck` CLI command, which would be needlessly confusing.
Updates tailscale/corp#9230
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
The lazy initialization of the disco key is not necessary, and
contributes to unnecessary locking and state checking.
Updates #cleanup
Signed-off-by: James Tucker <james@tailscale.com>