Cache DNS results of earlier login.tailscale.com control dials, and use
them for future dials if DNS is slow or broken.
Fixes various issues with trickier setups with the domain's DNS server
behind a subnet router.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
These accidentally make the tag syntax more flexible than was intended,
which will create forward compatibility problems later. Let's go back
to the old stricter parser.
Revert "cmd/tailscale/cli: fix double tag: prefix in tailscale up"
Revert "cmd/tailscale/cli, tailcfg: allow tag without "tag:" prefix in 'tailscale up'"
This reverts commit a702921620.
This reverts commit cd07437ade.
Affects #861.
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
os.IsNotExist doesn't unwrap errors. errors.Is does.
The ioutil.ReadFile ones happened to be fine but I changed them so
we're consistent with the rule: if the error comes from os, you can
use os.IsNotExist, but from any other package, use errors.Is.
(errors.Is always would also work, but not worth updating all the code)
The motivation here was that we were logging about failure to migrate
legacy relay node prefs file on startup, even though the code tried
to avoid that.
See golang/go#41122
When building with redo, also include the git commit hash
from the proprietary repo, so that we have a precise commit
that identifies all build info (including Go toolchain version).
Add a top-level build script demonstrating to downstream distros
how to burn the right information into builds.
Adjust `tailscale version` to print commit hashes when available.
Fixes#841.
Signed-off-by: David Anderson <danderson@tailscale.com>
The RusagePrefixLog is rarely useful, hasn't been useful in a long
time, is rarely the measurement we need, and is pretty spammy (and
syscall-heavy). Disable it by default. We can enable it when we're
debugging memory.
Use golang.zx2c4.com/wireguard/windows/tunnel/winipcfg
instead of github.com/tailscale/winipcfg-go package.
Updates #760
Signed-off-by: Alex Brainman <alex.brainman@gmail.com>
This partially (but not yet fully) migrates Windows to tailscaled's
StateStore storage system.
This adds a new bool Pref, ForceDaemon, defined as:
// ForceDaemon specifies whether a platform that normally
// operates in "client mode" (that is, requires an active user
// logged in with the GUI app running) should keep running after the
// GUI ends and/or the user logs out.
//
// The only current applicable platform is Windows. This
// forced Windows to go into "server mode" where Tailscale is
// running even with no users logged in. This might also be
// used for macOS in the future. This setting has no effect
// for Linux/etc, which always operate in daemon mode.
Then, when ForceDaemon becomes true, we now write use the StateStore
to track which user started it in server mode, and store their prefs
under that key.
The ipnserver validates the connections/identities and informs that
LocalBackend which userid is currently in charge.
The GUI can then enable/disable server mode at runtime, without using
the CLI.
But the "tailscale up" CLI was also fixed, so Windows users can use
authkeys or ACL tags, etc.
Updates #275
When the network link changes, existing UDP sockets fail immediately
and permanently on macOS.
The forwarder set up a single UDP conn and never changed it.
As a result, any time there was a network link change,
all forwarded DNS queries failed.
To fix this, create a new connection when send requests
fail because of network unreachability.
This change is darwin-only, although extended it to other platforms
should be straightforward.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
Part of unforking our winipcfg-go and using upstream (#760), move our
additions into our repo. (We might upstream them later if upstream has
interest)
Originally these were:
@apenwarr: "Add ifc.SyncAddresses() and SyncRoutes()."
609dcf2df5
@bradfitz: "winipcfg: make Interface.AddRoutes do as much as possible, return combined error"
e9f93d53f3
@bradfitz: "prevent unnecessary Interface.SyncAddresses work; normalize IPNets in deltaNets"
decb9ee8e1
We depend on DERP for NAT traversal now[0] so disabling it entirely can't
work.
What we'll do instead in the future is let people specify
alternate/additional DERP servers. And perhaps in the future we could
also add a pref for nodes to say when they expect to never need/want
to use DERP for data (but allow it for NAT traversal communication).
But this isn't the right pref and it doesn't work, so delete it.
Fixes#318
[0] https://tailscale.com/blog/how-nat-traversal-works/
This change is to restore /etc/resolv.conf after tailscale down is called. This is done by setting the dns.Manager before errors occur. Error collection is also added.
Fixes#723
Also remove rebinding logic from the windows router. Magicsock will
instead rebind based on link change signals.
Signed-off-by: David Anderson <danderson@tailscale.com>
For now. Get it working again so it's not stuck on 0.98.
Subnet relay can come later.
Updates #451
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This Clone function knows how to clone any types
for which it has generated Clone methods.
This allows callers to efficiently clone
an inbound interface{} that might contain one of these types.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This was causing any type to be reported as found,
as long as there were any type decls at all. Oops.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
If you change a struct and don't re-run cloner,
your Cloner method might be inaccurate, leading to bad things.
To prevent this, write out the struct as it is at the moment that
cloner is caller, and attempt a conversion from that type.
If the struct gets changed in any way, this conversion will fail.
This will yield false positives: If you change a non-pointer field,
you will be forced to re-run cloner, even though the actual generated
code won't change. I think this is an acceptable cost: It is a minor
annoyance, which will prevent real bugs.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* advertise server's DERP public key following its ServerHello
* have client look for that DEPR public key in the response
PeerCertificates
* let client advertise it's going into a "fast start" mode
if it finds it
* modify server to support that fast start mode, just not
sending the HTTP response header
Cuts down another round trip, bringing the latency of being able to
write our first DERP frame from SF to Bangalore from ~725ms
(3 RTT) to ~481ms (2 RTT: TCP and TLS).
Fixes#693
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
For example:
$ tailscale ping -h
USAGE
ping <hostname-or-IP>
FLAGS
-c 10 max number of pings to send
-stop-once-direct true stop once a direct path is established
-verbose false verbose output
$ tailscale ping mon.ts.tailscale.com
pong from monitoring (100.88.178.64) via DERP(sfo) in 65ms
pong from monitoring (100.88.178.64) via DERP(sfo) in 252ms
pong from monitoring (100.88.178.64) via [2604:a880:2:d1::36:d001]:41641 in 33ms
Fixes#661
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This will make it easier for a human to tell what
version is deployed, for (say) correlating line numbers
in profiles or panics to corresponding source code.
It'll also let us observe version changes in prometheus.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
SIGPIPE can be generated when CLIs disconnect from tailscaled. This
should not terminate the process.
Signed-off-by: David Anderson <danderson@tailscale.com>
tailscaled receives a SIGPIPE when CLIs disconnect from it. We shouldn't
shut down in that case.
This reverts commit 43b271cb26.
Signed-off-by: David Anderson <danderson@tailscale.com>
It appears that systemd has sensible defaults for limiting
crash loops:
DefaultStartLimitIntervalSec=10s
DefaultStartLimitBurst=5
Remove our insta-restart configuration so that it works.
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
So a backend in server-an-error state (as used by Windows) can try to
create a new Engine again each time somebody re-connects, relaunching
the GUI app.
(The proper fix is actually fixing Windows issues, but this makes things better
in the short term)
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
There's a lot of confusion around what tailscale status shows, so make it better:
show region names, last write time, and put stars around DERP too if active.
Now stars are always present if activity, and always somewhere.
The remove hook implementation was copy/pasted from the line above and
I didn't change the body, resulting in packet forwarding routes never
being removed.
Fortunately we weren't using this path yet, but it led to stats being
off, and (very) slow memory growth.
The magicsock derpReader was holding onto 65KB for each DERP
connection forever, just in case.
Make the derp{,http}.Client be in charge of memory instead. It can
reuse its bufio.Reader buffer space.
This lets a trusted DERP client that knows a pre-shared key subscribe
to the connection list. Upon subscribing, they get the current set
of connected public keys, and then all changes over time.
This lets a set of DERP server peers within a region all stay connected to
each other and know which clients are connected to which nodes.
Updates #388
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The flags were --no-blah for a brief time, then we switched them to
--blah=true/false with a default of true, but didn't fix the boolean
inversions in the code. So up was down, true was false, etc.
Signed-off-by: David Anderson <danderson@tailscale.com>
Also:
* add -verbose flag to cmd/tailscale netcheck
* remove some API from the interfaces package
* convert some of the interfaces package to netaddr.IP
* don't even send IPv4 probes on machines with no IPv4 (or only v4
loopback)
* and once three regions have replied, stop waiting for other probes
at 2x the slowest duration.
Updates #376
On startup, and when switching into =off and =nodivert, we were
deleting netfilter rules even if we weren't the ones that added them.
In order to avoid interfering with rules added by the sysadmin, we have
to be sure to delete rules only in the case that we added them in the
first place.
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
Let's actually list the file we checked
(/proc/sys/net/ipv4/ip_forward). That gives the admin something
specific to look for when they get this message.
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
We would print a message about "nothing more to do", which some people
thought was an error or warning. Let's only print a message after
authenticating if we previously asked for interaction, and let's
shorten that message to just "Success," which is what it means.
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
Instead of hard-coding the DERP map (except for cmd/tailscale netcheck
for now), get it from the control server at runtime.
And make the DERP map support multiple nodes per region with clients
picking the first one that's available. (The server will balance the
order presented to clients for load balancing)
This deletes the stunner package, merging it into the netcheck package
instead, to minimize all the config hooks that would've been
required.
Also fix some test flakes & races.
Fixes#387 (Don't hard-code the DERP map)
Updates #388 (Add DERP region support)
Fixes#399 (wgengine: flaky tests)
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
- Reformat the warning about a message being rate limited to print the
format string, rather than the formatted message. This helps give a
clue what "type" of message is being limited.
- Change the rate limit warning to be [RATE LIMITED] in all caps. This
uses less space on each line, plus is more noticeable.
- In tailscaled, change the frequency to be less often (once every 5
seconds per format string) but to allow bursts of up to 5 messages.
This greatly reduces the number of messages that are rate limited
during startup, but allows us to tighten the limit even further during
normal runtime.
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
This cuts RSS from ~30MB to ~20MB on my machine, after the previous fix
to get rid of unnecessary zstd buffers.
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
Also stop logging data sent/received from nodes we're not connected to (ie all those `x`s being logged in the `peers: ` line)
Signed-off-by: Wendi <wendi.yu@yahoo.ca>
For "tailscale status" on macOS (from separately downloaded
cmd/tailscale binary against App Store IPNExtension).
(This isn't all of it, but I've had this sitting around uncommitted.)
Implement rate limiting on log messages
Addresses issue #317, where logs can get spammed with the same message
nonstop. Created a rate limiting closure on logging functions, which
limits the number of messages being logged per second based on format
string. To keep memory usage as constant as possible, the previous cache
purging at periodic time intervals has been replaced by an LRU that
discards the oldest string when the capacity of the cache is reached.
Signed-off-by: Wendi Yu <wendi.yu@yahoo.ca>
These will be used for dynamically changing the identity of a node, so
its ACL rights can be different from your own.
Note: Not all implemented yet on the server side, but we need this so
we can request the tagged rights in the first place.
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
This sets a default packet filter that blocks all incoming requests,
giving end users more control over who can get into their machine, even
if the admin hasn't set any central ACLs.
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
The name's been bugging me for a long time.
I liked neither the overlap between tsweb.Handler and http.Handler,
nor the name "ServeHTTPErr" which sounds like it's an error being
returned, like it's an error handler and not sometimes a happy path.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This avoids the server blocking on misbehaving or heavily contended
clients. We attempt to drop from the head of the queue to keep
overall queueing time lower.
Also:
- fixes server->client keepalives, which weren't happening.
- removes read rate-limiter, deferring instead to kernel-level
global limiter/fair queuer.
Signed-off-by: David Anderson <dave@natulte.net>
This removes the need for go-cmp, which is extremely bloaty so we had
to leave it out of iOS. As a result, we had also left it out of macOS,
and so we didn't print netmap diffs at all on darwin-based platforms.
Oops.
As a bonus, the output format of the new function is way better.
Minor oddity: because I used the dumbest possible diff algorithm, the
sort order is a bit dumb. We print all "removed" lines and then print
all "added" lines, rather than doing the usual diff-like thing of
interspersing them. This probably doesn't matter (maybe it's an
improvement).
Basically, don't trust the OS-level link monitor to only tell you
interesting things. Sanity check it.
Also, move the interfaces package into the net directory now that we
have it.
The device name "tailscale0" will be used for all platforms except for
OpenBSD where "tun" is enforced by the kernel. `CreateTUN()` in
`wireguard-go` will select the next available "tunX" device name on the
OpenBSD system.
Signed-off-by: Martin Baillie <martin@baillie.email>
This lets us publish sets of vars that are breakdowns along one
dimension in a format that Prometheus and Grafana natively know
how to do useful things with.
Signed-off-by: David Anderson <dave@natulte.net>
Both RPM and Deb require us to specify both Replaces and Conflicts:
Conflicts tells them that the packages cannot coexist on the system,
Replaces tells them which one to keep.
Two commands for now, `up` and `netcheck`. The commands and the flags they take
will change a bunch in the future, but this is good enough to launch on parity
with relaynode.
Signed-Off-By: David Anderson <dave@natulte.net>
* adds new packet "netcheck" to do the checking of UDP, IPv6, and
nearest DERP server, and the Report type for all that (and more
in the future, probably pulling in danderson's natprobe)
* new tailcfg.NetInfo type
* cmd/tailscale netcheck subcommand (tentative name, likely to
change/move) to print out the netcheck.Report.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Prefs has become a heavy object with non-memcpy copy
semantics. We should not pass such a thing by value.
Signed-off-by: David Anderson <dave@natulte.net>
relaynode itself is not long for this world, deprecated in favour of
tailscale/tailscaled. But now that the control server supports central
distribution of packet filters, let's actually take advantage of it in
a final, backward compatible release of relaynode.
The autoselection should pick sensible paths for all of:
- Windows (LocalAppData)
- Mac (Library/Caches)
- Unix user (XDG_CACHE_DIR)
- Linux systemd service (CACHE_DIRECTORY)
As a last resort, if cache dir lookup fails, plops sufficiently
uniquely named files into the current working directory.
Signed-off-by: David Anderson <dave@natulte.net>
We can't rely on a frontend to provide a control
server URL, so this naturally belongs in server-persisted
state.
Signed-off-by: David Anderson <dave@natulte.net>
Port number has to be by itself for substitution to work.
Disabling the restart rate-limiting has to be in [Unit] not
[Service].
Signed-off-by: David Anderson <dave@natulte.net>
On unix, we want to provide a full path to the desired unix socket.
On windows, currently we want to provide a TCP port, but someday
we'll also provide a "path-ish" object for a named pipe.
For now, simplify the API down to exactly a path and a TCP port.
Signed-off-by: David Anderson <dave@natulte.net>
With this change, tailscaled can be restarted and reconnect
without interaction from `tailscale`, and `tailscale` is merely
there to provide login assistance and adjust preferences.
Signed-off-by: David Anderson <dave@natulte.net>
* make RouterGen return an error, not take both tunname and tundev
* also remove RouteGen taking a wireguard/device.Device; currently unused
* remove derp parameter (it'll work differently)
* unexport NewUserspaceRouter in per-OS impls, add documented wrapper
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It was previously used by the MacOS client, but it now does
something different. ipnserver should never obey a client's
request to exit.
Signed-off-by: David Anderson <dave@natulte.net>
The store is passed-in by callers of NewLocalBackend and
ipnserver.Run, but currently all callers are hardcoded to
an in-memory store. The store is unused.
Signed-Off-By: David Anderson <dave@natulte.net>
This is a prelude to making it truly optional, once state
management has moved into the backend. For now though, it's
still required. This change is just isolating the bubbling-up
of the pointerification into other layers.
Signed-Off-By: David Anderson <dave@natulte.net>
- It was only used in one currently-unused client.
- It's an imperative command, not a configuration setting.
- The LoginFlags stuff in controlclient feels like it needs
a refactor anyway.
I'll put this logic back once ipnd owns its state and Backend
commands reflect that.
Signed-Off-By: David Anderson <dave@natulte.net>