Commit Graph

225 Commits (d0f2c0664b394370face42c183ea79982f4a7bd7)

Author SHA1 Message Date
Anton Tolchanov c3313133b9 derp/derphttp: close DERP client to avoid data race in test
Fixes #10041

Signed-off-by: Anton Tolchanov <anton@tailscale.com>
1 year ago
Anton Tolchanov 3114a1c88d derp/derphttp: add watch reconnection tests from #9719
Co-authored-by: Val <valerie@tailscale.com>
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
1 year ago
Brad Fitzpatrick 3d7fb6c21d derp/derphttp: fix race in mesh watcher
The derphttp client automatically reconnects upon failure.

RunWatchConnectionLoop called derphttp.Client.WatchConnectionChanges
once, but that wrapper method called the underlying
derp.Client.WatchConnectionChanges exactly once on derphttp.Client's
currently active connection. If there's a failure, we need to re-subscribe
upon all reconnections.

This removes the derphttp.Client.WatchConnectionChanges method, which
was basically impossible to use correctly, and changes it to be a
boolean field on derphttp.Client alongside MeshKey and IsProber. Then
it moves the call to the underlying derp.Client.WatchConnectionChanges
to derphttp's client connection code, so it's resubscribed on any
reconnect.

Some paranoia is then added to make sure people hold the API right,
not calling derphttp.Client.RunWatchConnectionLoop on an
already-started Client without having set the bool to true. (But still
auto-setting it to true if that's the first method that's been called
on that derphttp.Client, as is commonly the case, and prevents
existing code from breaking)

Fixes tailscale/corp#9916
Supercedes tailscale/tailscale#9719

Co-authored-by: Val <valerie@tailscale.com>
Co-authored-by: Irbe Krumina <irbe@tailscale.com>
Co-authored-by: Anton Tolchanov <anton@tailscale.com>
Signed-off-by: Brad Fitzpatrick <brad@danga.com>
1 year ago
Thomas Kosiewski b2ae8fdf80
derp/derphttp: strip port numbers from URL hostname
When trying to set up multiple derper instances meshing with each
other, it turned out that while one can specify an alternative
listening port using the -a flag, the TLS hostname gets incorrectly
determined and includes the set alternative listening port as part of
the hostname. Thus, the TLS hostname validation always fails when the
-mesh-with values have ports.

Updates #9949

Signed-off-by: Thomas Kosiewski <thomas.kosiewski@loft.sh>
1 year ago
David Anderson 8b492b4121 net/wsconn: accept a remote addr string and plumb it through
This makes wsconn.Conns somewhat present reasonably when they are
the client of an http.Request, rather than just put a placeholder
in that field.

Updates tailscale/corp#13777

Signed-off-by: David Anderson <danderson@tailscale.com>
1 year ago
Brad Fitzpatrick 3bce9632d9 derp/derphttp: fix data race and crash in proxy dial error path
Named result meant error paths assigned that variable to nil.
But a goroutine was concurrently using that variable.

Don't use a named result for that first parameter. Then then return
paths don't overwrite it.

Fixes #9129

Change-Id: Ie57f99d40ca8110085097780686d9bd620aaf160
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
1 year ago
Brad Fitzpatrick 6c791f7d60 derp: include src IPs in mesh watch messages
Updates tailscale/corp#13945

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
1 year ago
Brad Fitzpatrick be4eb6a39e derp, net/dns/recursive: use Go 1.21 min
Updates #8419

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
1 year ago
Brad Fitzpatrick 5ebb271322 derp/derphttp: add optional Client.BaseContext hook
Like net/http.Server.BaseContext, this lets callers specify a base
context for dials.

Updates tailscale/corp#12702

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
1 year ago
Claire Wang 90a7d3066c
derp: use tstime (#8634)
Updates #8587

Signed-off-by: Claire Wang <claire@tailscale.com>
1 year ago
Andrew Dunham ab310a7f60 derp: use new net/tcpinfo package
Updates #8413

Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I8bf8046517195a6d42cabb32d6ec7f1f79cef860
1 year ago
Brad Fitzpatrick eefee6f149 all: use cmpx.Or where it made sense
I left a few out where writing it explicitly was better
for various reasons.

Updates #8296

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
1 year ago
valscale 5ae786988c
derp: remove default logging of disconnecting clients (#8163)
~97% of the log messages derper outputs are related to the normal
non-error state of a client disconnecting in some manner. Add a
verbose logging feature that only logs these messages when enabled.

Fixes #8024

Signed-off-by: Val <valerie@tailscale.com>
2 years ago
Brad Fitzpatrick c1e6888fc7 derp: add a README.md with some docs
Updates #docs

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Mihai Parparita 7330aa593e all: avoid repeated default interface lookups
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>
2 years ago
Mihai Parparita edb02b63f8 net/sockstats: pass in logger to sockstats.WithSockStats
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>
2 years ago
valscale 7bfb7744b7
derp,magicsock: add debug envknobs for HTTP and derp server name (#7744)
Make developing derp easier by:

1. Creating an envknob telling clients to use HTTP to connect to derp
servers, so devs don't have to acquire a valid TLS cert.

2. Creating an envknob telling clients which derp server to connect
to, so devs don't have to edit the ACLs in the admin console to add a
custom DERP map.

3. Explaining how the -dev and -a command lines args to derper
interact.

To use this:

1. Run derper with -dev.

2. Run tailscaled with TS_DEBUG_USE_DERP_HTTP=1 and
TS_DEBUG_USE_DERP_ADDR=localhost

This will result in the client connecting to derp via HTTP on port
3340.

Fixes #7700

Signed-off-by: Val <valerie@tailscale.com>
2 years ago
valscale 74eb99aed1
derp, derphttp, magicsock: send new unknown peer frame when destination is unknown (#7552)
* wgengine/magicsock: add envknob to send CallMeMaybe to non-existent peer

For testing older client version responses to the PeerGone packet format change.

Updates #4326

Signed-off-by: Val <valerie@tailscale.com>

* derp: remove dead sclient struct member replaceLimiter

Leftover from an previous solution to the duplicate client problem.

Updates #2751

Signed-off-by: Val <valerie@tailscale.com>

* derp, derp/derphttp, wgengine/magicsock: add new PeerGone message type Not Here

Extend the PeerGone message type by adding a reason byte. Send a
PeerGone "Not Here" message when an endpoint sends a disco message to
a peer that this server has no record of.

Fixes #4326

Signed-off-by: Val <valerie@tailscale.com>

---------

Signed-off-by: Val <valerie@tailscale.com>
2 years ago
Anton Tolchanov 654b5a0616 derp: add optional debug logging for prober clients
This allows tracking packet flow via logs for prober clients. Note that
the new sclient.debug() function is called on every received packet, but
will do nothing for most clients.

I have adjusted sclient logging to print public keys in short format
rather than full. This takes effect even for existing non-debug logging
(mostly client disconnect messages).

Example logs for a packet being sent from client [SbsJn] (connected to
derper [dM2E3]) to client [10WOo] (connected to derper [AVxvv]):

```
derper [dM2E3]:
derp client 10.0.0.1:35470[SbsJn]: register single client mesh("10.0.1.1"): 4 peers
derp client 10.0.0.1:35470[SbsJn]: read frame type 4 len 40 err <nil>
derp client 10.0.0.1:35470[SbsJn]: SendPacket for [10WOo], forwarding via <derphttp_client.Client [AVxvv] url=https://10.0.1.1/derp>: <nil>
derp client 10.0.0.1:35470[SbsJn]: read frame type 0 len 0 err EOF
derp client 10.0.0.1:35470[SbsJn]: read EOF
derp client 10.0.0.1:35470[SbsJn]: sender failed: context canceled
derp client 10.0.0.1:35470[SbsJn]: removing connection

derper [AVxvv]:
derp client 10.0.1.1:50650[10WOo]: register single client
derp client 10.0.1.1:50650[10WOo]: received forwarded packet from [SbsJn] via [dM2E3]
derp client 10.0.1.1:50650[10WOo]: sendPkt attempt 0 enqueued
derp client 10.0.1.1:50650[10WOo]: sendPacket from [SbsJn]: <nil>
derp client 10.0.1.1:50650[10WOo]: read frame type 0 len 0 err EOF
derp client 10.0.1.1:50650[10WOo]: read EOF
derp client 10.0.1.1:50650[10WOo]: sender failed: context canceled
derp client 10.0.1.1:50650[10WOo]: removing connection
```

Signed-off-by: Anton Tolchanov <anton@tailscale.com>
2 years ago
Kyle Carberry 3862a1e1d5 derp/derphttp: cleanup WebSocket connection on close
This was causing a leak in our CI!

Signed-off-by: Kyle Carberry <kyle@carberry.com>
2 years ago
Mihai Parparita 6ac6ddbb47 sockstats: switch label to enum
Makes it cheaper/simpler to persist values, and encourages reuse of
labels as opposed to generating an arbitrary number.

Updates tailscale/corp#9230
Updates #3363

Signed-off-by: Mihai Parparita <mihai@tailscale.com>
2 years ago
Mihai Parparita 9cb332f0e2 sockstats: instrument networking code paths
Uses the hooks added by tailscale/go#45 to instrument the reads and
writes on the major code paths that do network I/O in the client. The
convention is to use "<package>.<type>:<label>" as the annotation for
the responsible code path.

Enabled on iOS, macOS and Android only, since mobile platforms are the
ones we're most interested in, and we are less sensitive to any
throughput degradation due to the per-I/O callback overhead (macOS is
also enabled for ease of testing during development).

For now just exposed as counters on a /v0/sockstats PeerAPI endpoint.

We also keep track of the current interface so that we can break out
the stats by interface.

Updates tailscale/corp#9230
Updates #3363

Signed-off-by: Mihai Parparita <mihai@tailscale.com>
2 years ago
David Anderson 8b2ae47c31 version: unexport all vars, turn Short/Long into funcs
The other formerly exported values aren't used outside the package,
so just unexport them.

Signed-off-by: David Anderson <danderson@tailscale.com>
2 years ago
Brad Fitzpatrick cf8dd7aa09 all: use Go 1.20's bytes.Clone
Updates #7123
Updates #6257 (more to do in other repos)

Change-Id: I073e2a6d81a5d7fbecc29caddb7e057ff65239d0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Brad Fitzpatrick b1248442c3 all: update to Go 1.20, use strings.CutPrefix/Suffix instead of our fork
Updates #7123
Updates #5309

Change-Id: I90bcd87a2fb85a91834a0dd4be6e03db08438672
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Maisem Ali 5bba65e978 net/memnet: rename from net/nettest
This is just #cleanup to resolve a TODO

Also add a package doc.

Signed-off-by: Maisem Ali <maisem@tailscale.com>
2 years ago
Will Norris 947c14793a all: update tools that manage copyright headers
Update all code generation tools, and those that check for license
headers to use the new standard header.

Also update copyright statement in LICENSE file.

Fixes #6865

Signed-off-by: Will Norris <will@tailscale.com>
2 years ago
Will Norris 71029cea2d all: update copyright and license headers
This updates all source files to use a new standard header for copyright
and license declaration.  Notably, copyright no longer includes a date,
and we now use the standard SPDX-License-Identifier header.

This commit was done almost entirely mechanically with perl, and then
some minimal manual fixes.

Updates #6865

Signed-off-by: Will Norris <will@tailscale.com>
2 years ago
Anton Tolchanov 6cc6c70d70 derp: prevent concurrent access to multiForwarder map
Instead of iterating over the map to determine the preferred forwarder
on every packet (which could happen concurrently with map mutations),
store it separately in an atomic variable.

Fixes #6445

Signed-off-by: Anton Tolchanov <anton@tailscale.com>
2 years ago
Mihai Parparita 33520920c3 all: use strs.CutPrefix and strs.CutSuffix more
Updates places where we use HasPrefix + TrimPrefix to use the combined
function.

Updates #5309

Signed-off-by: Mihai Parparita <mihai@tailscale.com>
2 years ago
Maisem Ali 1f4669a380 all: standardize on LocalAPI
Signed-off-by: Maisem Ali <maisem@tailscale.com>
2 years ago
Brad Fitzpatrick da8def8e13 all: remove old +build tags
The //go:build syntax was introduced in Go 1.17:

https://go.dev/doc/go1.17#build-lines

gofmt has kept the +build and go:build lines in sync since
then, but enough time has passed. Time to remove them.

Done with:

    perl -i -npe 's,^// \+build.*\n,,' $(git grep -l -F '+build')

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Brad Fitzpatrick f4ff26f577 types/pad32: delete package
Use Go 1.19's new 64-bit alignment ~hidden feature instead.

Fixes #5356

Change-Id: Ifcbcb115875a7da01df3bc29e9e7feadce5bc956
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Mihai Parparita 9d04ffc782 net/wsconn: add back custom wrapper for turning a websocket.Conn into a net.Conn
We removed it in #4806 in favor of the built-in functionality from the
nhooyr.io/websocket package. However, it has an issue with deadlines
that has not been fixed yet (see nhooyr/websocket#350). Temporarily
go back to using a custom wrapper (using the fix from our fork) so that
derpers will stop closing connections too aggressively.

Updates #5921

Signed-off-by: Mihai Parparita <mihai@tailscale.com>
2 years ago
Andrew Dunham 64ea60aaa3
derp: add TCP RTT metric on Linux (#5949)
Periodically poll the TCP RTT metric from all open TCP connections and
update a (bucketed) histogram metric.

Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I6214902196b05bf7829c9d0ea501ce0e13d984cf
2 years ago
Mihai Parparita b2855cfd86 derp/derphttp: fix nil pointer dereference when closing a netcheck client
NewNetcheckClient only initializes a subset of fields of derphttp.Client,
and the Close() call added by #5707 was result in a nil pointer dereference.
Make Close() safe to call when using NewNetcheckClient() too.

Fixes #5919

Signed-off-by: Mihai Parparita <mihai@tailscale.com>
2 years ago
Josh Soref d4811f11a0 all: fix spelling mistakes
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2 years ago
Eng Zer Jun f0347e841f refactor: move from io/ioutil to io and os packages
The io/ioutil package has been deprecated as of Go 1.16 [1]. This commit
replaces the existing io/ioutil functions with their new definitions in
io and os packages.

Reference: https://golang.org/doc/go1.16#ioutil
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2 years ago
Mihai Parparita 027111fb5a derp: update DERP acronym expansion
Makes the package description consistent with other documentation.

Signed-off-by: Mihai Parparita <mihai@tailscale.com>
2 years ago
Brad Fitzpatrick 74674b110d envknob: support changing envknobs post-init
Updates #5114

Change-Id: Ia423fc7486e1b3f3180a26308278be0086fae49b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Maisem Ali a9f6cd41fd all: use syncs.AtomicValue
Signed-off-by: Maisem Ali <maisem@tailscale.com>
2 years ago
Brad Fitzpatrick 4950fe60bd syncs, all: move to using Go's new atomic types instead of ours
Fixes #5185

Change-Id: I850dd532559af78c3895e2924f8237ccc328449d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Brad Fitzpatrick 116f55ff66 all: gofmt for Go 1.19
Updates #5210

Change-Id: Ib02cd5e43d0a8db60c1f09755a8ac7b140b670be
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Brad Fitzpatrick a12aad6b47 all: convert more code to use net/netip directly
perl -i -npe 's,netaddr.IPPrefixFrom,netip.PrefixFrom,' $(git grep -l -F netaddr.)
    perl -i -npe 's,netaddr.IPPortFrom,netip.AddrPortFrom,' $(git grep -l -F netaddr. )
    perl -i -npe 's,netaddr.IPPrefix,netip.Prefix,g' $(git grep -l -F netaddr. )
    perl -i -npe 's,netaddr.IPPort,netip.AddrPort,g' $(git grep -l -F netaddr. )
    perl -i -npe 's,netaddr.IP\b,netip.Addr,g' $(git grep -l -F netaddr. )
    perl -i -npe 's,netaddr.IPv6Raw\b,netip.AddrFrom16,g' $(git grep -l -F netaddr. )
    goimports -w .

Then delete some stuff from the net/netaddr shim package which is no
longer neeed.

Updates #5162

Change-Id: Ia7a86893fe21c7e3ee1ec823e8aba288d4566cd8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Brad Fitzpatrick 6a396731eb all: use various net/netip parse funcs directly
Mechanical change with perl+goimports.

Changed {Must,}Parse{IP,IPPrefix,IPPort} to their netip variants, then
goimports -d .

Finally, removed the net/netaddr wrappers, to prevent future use.

Updates #5162

Change-Id: I59c0e38b5fbca5a935d701645789cddf3d7863ad
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Brad Fitzpatrick 7eaf5e509f net/netaddr: start migrating to net/netip via new netaddr adapter package
Updates #5162

Change-Id: Id7bdec303b25471f69d542f8ce43805328d56c12
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Charlotte Brandhorst-Satzkorn 4c0feba38e
derp: plumb '/derp' request context through (#5083)
This change is required to implement tracing for derp.

Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
2 years ago
Brad Fitzpatrick 931f18b575 derp: add missing docs on clientInfo.Version
It's not the Tailscale version.

Change-Id: Icfbd5ff36300b2125b19cd2fa6caa22876965317
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Mihai Parparita edc90ebc61 net/wsconn: remove homegrown wrapper for turning a websocket.Conn into a net.Conn
The one from the nhooyr/websocket package seems to work equally well.

Signed-off-by: Mihai Parparita <mihai@tailscale.com>
2 years ago
Mihai Parparita a9f32656f5 control/controlhttp: allow client and server to communicate over WebSockets
We can't do Noise-over-HTTP in Wasm/JS (because we don't have bidirectional
communication), but we should be able to do it over WebSockets. Reuses
derp WebSocket support that allows us to turn a WebSocket connection
into a net.Conn.

Updates #3157

Signed-off-by: Mihai Parparita <mihai@tailscale.com>
2 years ago