Commit Graph
100 Commits
Author SHA1 Message Date
Josh Bleecher SnyderandJosh Bleecher Snyder 8cf6d0a17b tailcfg: add MapResponse.ControlTime field
And log it when provided in map responses.

The test uses the date on which I joined Tailscale. :)

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2022-02-16 20:18:03 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder b486448ab9 go.toolchain.rev: bump to Go 1.17.7
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2022-02-15 13:29:17 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 1dc4151f8b logtail: add MustParsePublicID
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2022-02-14 16:00:17 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 84046d6f7c Revert "cmd/derper: stop setting content header in handleBootstrapDNS"
Didn't help enough. We are setting another header anyway. Restore it.

This reverts commit 60abeb027b.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2022-02-11 14:15:28 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder ec62217f52 cmd/derper: close connections once bootstrap DNS has been served
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2022-02-11 14:08:43 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 60abeb027b cmd/derper: stop setting content header in handleBootstrapDNS
No one really cares. Its cost outweighs its usefulness.

name                   old time/op    new time/op    delta
HandleBootstrapDNS-10     105ns ± 4%      65ns ± 2%   -37.68%  (p=0.000 n=15+14)

name                   old alloc/op   new alloc/op   delta
HandleBootstrapDNS-10      416B ± 0%        0B       -100.00%  (p=0.000 n=15+15)

name                   old allocs/op  new allocs/op  delta
HandleBootstrapDNS-10      3.00 ± 0%      0.00       -100.00%  (p=0.000 n=15+15)

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2022-02-11 12:43:19 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder b9c92b90db cmd/derper: optimize handleBootstrapDNS
Do json formatting once, rather than on every request.

Use an atomic.Value.

name                   old time/op    new time/op    delta
HandleBootstrapDNS-10    6.35µs ± 0%    0.10µs ± 4%  -98.35%  (p=0.000 n=14+15)

name                   old alloc/op   new alloc/op   delta
HandleBootstrapDNS-10    3.20kB ± 0%    0.42kB ± 0%  -86.99%  (p=0.000 n=12+15)

name                   old allocs/op  new allocs/op  delta
HandleBootstrapDNS-10      41.0 ± 0%       3.0 ± 0%  -92.68%  (p=0.000 n=15+15)

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2022-02-11 12:43:19 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder e206a3663f cmd/derper: add BenchmarkHandleBootstrapDNS
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2022-02-11 12:43:19 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder e45d51b060 logtail: add a few new methods to PublicID
These are for use in our internal systems.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2022-01-31 14:14:10 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder de4696da10 wgengine/magicsock: fix deadlock on shutdown
This fixes a deadlock on shutdown.
One goroutine is waiting to send on c.derpRecvCh before unlocking c.mu.
The other goroutine is waiting to lock c.mu before receiving from c.derpRecvCh.

#3736 has a more detailed explanation of the sequence of events.

Fixes #3736

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2022-01-19 14:39:28 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 8cf1af8a07 tstime/rate: deflake TestLongRunningQPS
This test set the bar too high.
Just a couple of missed timers was enough to fail.
Change the test to more of a sanity check.
While we're here, run it for just 1s instead of 5s.

Prior to this change, on a 13" M1 MPB, with

stress -p 512 ./rate.test -test.run=QPS

I saw 90%+ failures.

After this change, I'm at 30k runs with no failures yet.

Fixes #3733

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2022-01-13 16:48:29 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 9fe5ece833 logtail: cap the buffer size in encodeText
This started as an attempt to placate GitHub's code scanner,
but it's also probably generally a good idea.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2022-01-13 14:37:27 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder a076aaecc6 cmd/tailscale: use html/template for synoTokenRedirect
The GitHub code scanner flagged this as a security vulnerability.
I don't believe it was, but I couldn't convince myself of it 100%.
Err on the safe side and use html/template to generate the HTML,
with all necessary escaping.

Fixes tailscale/corp#2698

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2022-01-13 13:32:45 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 1dc1c8b709 .github/workflows: upgrade to setup-go@v2
The rest of our workflows use v2.1.4.
For reasons I do not understand, we must set GOPATH here.
Maybe the GitHub Action builds come with GOPATH already set?

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2022-01-10 16:19:06 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 408522ddad go.toolchain.rev: add update script
Also go.toolchain.branch.

Both migrated from the corp repo.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2022-01-10 14:55:04 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder add6dc8ccc ipn/ipnlocal: make TestShrinkDefaultRoute hermetic
Make shrinkDefaultRoute a pure function.
Instead of calling interfaceRoutes, accept that information as parameters.
Hard-code those parameters in TestShrinkDefaultRoute.

Fixes #3580

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-12-16 11:31:20 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 4512e213d5 cmd/tailscale: improve ping error message when logged out
Refactor out the pretty status printing code from status, use it in ping.

Fixes #3549

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-12-16 10:46:18 -08:00
Josh Bleecher SnyderandBrad Fitzpatrick 681d4897cc tstest/integration: remove t param in testNode methods
testNodes have a reference to a testing.TB via their env.
Use it instead of making the caller pass theirs.
We did this in some methods but not others; finish the job.
This simplifies the call sites.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-12-15 18:06:14 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 93ae11105d ipn/ipnlocal: clear magicsock's netmap on logout
magicsock was hanging onto its netmap on logout,
which caused tailscale status to display partial
information about a bunch of zombie peers.
After logout, there should be no peers.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-12-15 17:00:08 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 84a1106fa7 tstest/integration: make -verbose-tailscaled pass -verbose=2 to tailscaled
If you're using -verbose-tailscaled, you're doing in-the-weeds debugging,
so you probably want the verbose output.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-12-15 17:00:08 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 4691e012a9 tstest/integration: build binaries only once
The existing code relied on the Go build cache to avoid
needless work when obtaining the tailscale binaries.

For non-obvious reasons, the binaries were getting re-linked
every time, which added 600ms or so on my machine to every test.

Instead, build the binaries exactly once, on demand.
This reduces the time to run 'go test -count=5' from 34s to 10s
on my machine.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-12-13 14:38:08 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 63cd581c3f safesocket: add ConnectionStrategy, provide control over fallbacks
fee2d9fad added support for cmd/tailscale to connect to IPNExtension.
It came in two parts: If no socket was provided, dial IPNExtension first,
and also, if dialing the socket failed, fall back to IPNExtension.

The second half of that support caused the integration tests to fail
when run on a machine that was also running IPNExtension.
The integration tests want to wait until the tailscaled instances
that they spun up are listening. They do that by dialing the new
instance. But when that dial failed, it was falling back to IPNExtension,
so it appeared (incorrectly) that tailscaled was running.
Hilarity predictably ensued.

If a user (or a test) explicitly provides a socket to dial,
it is a reasonable assumption that they have a specific tailscaled
in mind and don't want to fall back to IPNExtension.
It is certainly true of the integration tests.

Instead of adding a bool to Connect, split out the notion of a
connection strategy. For now, the implementation remains the same,
but with the details hidden a bit. Later, we can improve that.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-12-09 15:46:38 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder a5235e165c tstest/integration: fix running with -verbose-tailscale
Without this fix, any run with -verbose-tailscale fails.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-12-09 15:46:38 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder c8829b742b all: minor code cleanup
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-12-09 15:46:38 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 1813c2a162 .: add .gitattributes entry to use Go hunk-header driver
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-12-03 17:56:02 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder de635ac0a8 cmd/tailscale: print more detail in connection failure error message
Before:

failed to connect to local tailscaled (which appears to be running). Got error: Get "http://local-tailscaled.sock/localapi/v0/status": EOF

After:

failed to connect to local tailscaled (which appears to be running as IPNExtension, pid 2118). Got error: Get "http://local-tailscaled.sock/localapi/v0/status": EOF

This was useful just now, as it made it clear that tailscaled I thought
I was connecting to might not in fact be running; there was
a second tailscaled running that made the error message slightly misleading.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-12-03 12:46:50 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 768baafcb5 tstest/integration: use t.Cleanup
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-12-02 11:11:11 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 25eab78573 control/noise: clean up resources in TestNoReuse
Close the server and client.
Without this, we leak system threads.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-12-01 12:50:21 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 2075c39fd7 net/portmapper: deflake TestPCPIntegration
Logging in goroutines after the test completed
caused data races and panics. Prevent that.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-12-01 10:13:27 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder deb2f5e793 types/logger: add Context and related helpers
We often need both a log function and a context.
We can do this by adding the log function as a context value.
This commit adds helper glue to make that easy.
It is designed to allow incremental adoption.

Updates tailscale/corp#3138

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-30 15:18:21 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder b800663779 tstest/integration: stop leaking zstd.Decoders
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-30 14:08:05 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder e16cb523aa net/nettest: deflake TestPipeTimeout
The block-write and block-read tests are both flaky,
because each assumes it can get a normal read/write
completed within 10ms. This isn’t always true.

We can’t increase the timeouts, because that slows down the test.
However, we don’t need to issue a regular read/write for this test.
The immediately preceding tests already test this code,
using a far more generous timeout.

Remove the extraneous read/write.

This drops the failure rate from 1 per 20,000 to undetectable
on my machine.

While we’re here, fix a typo in a debug print statement.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-30 12:21:59 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder a8cc519c70 net/portmapper: improve handling of UPnP parse errors
Without the continue, we might overwrite our current meta
with a zero meta.

Log the error, so that we can check for anything unexpected.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-30 12:13:15 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder fddf43f3d1 net/portmapper: fill out PCP/PMP client metrics
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-30 12:13:15 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 9787ec6f4a net/portmapper: add UPnP client metrics
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-30 12:13:15 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 40f11c50a1 net/portmapper: make PCP/PMP result codes stringers
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-30 12:13:15 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 38d90fa330 net/portmapper: add clientmetrics for PCP/PMP responses
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-30 12:13:15 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 999814e9e1 net/portmapper: handle pcp ADDRESS_MISMATCH response
These show up a fair amount in our logs.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-30 12:13:15 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder d9c21936c3 control/controlclient: stop logging about goal.url invariant
This isn't the ideal solution, but it's good enough for now.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-29 14:00:53 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder d10cefdb9b net/dns: require space after nameserver/search parsing resolv.conf
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-23 15:11:46 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 9f00510833 net/dns: handle comments in resolv.conf
Currently, comments in resolv.conf cause our parser to fail,
with error messages like:

ParseIP("192.168.0.100 # comment"): unexpected character (at " # comment")

Fix that.

Noticed while looking through logs.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-23 15:11:46 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 955aa188b3 ipn/ipnlocal: fix logging
We were missing an argument here.
Also, switch to %q, in case anything weird
is happening with these strings.

Updates tailscale/corp#461

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-23 13:36:59 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 73beaaf360 net/tstun: rate limit "self disco out packet" logging
When this happens, it is incredibly noisy in the logs.
It accounts for about a third of all remaining
"unexpected" log lines from a recent investigation.

It's not clear that we know how to fix this,
we have a functioning workaround,
and we now have a (cheap and efficient) metric for this
that we can use for measurements.

So reduce the logging to approximately once per minute.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-23 12:52:52 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder b0d543f7a1 cmd/tailscale: add ip -1 flag
This limits the output to a single IP address.

RELNOTE=tailscale ip now has a -1 flag (TODO: update docs to use it)

Fixes #1921

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-23 12:05:32 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 73beaf59fb cmd/tailscale: improve ip subcommand docs
Streamline the prose.
Clarify what peer may be.
Improve an error message.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-23 12:05:32 -08:00
Josh Bleecher SnyderandBrad Fitzpatrick 027b46d0c1 ipn/ipnstate: clarify PeerStatusLite.LastHandshake
And document the other fields, as long as we're here.

Updates #1182

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-22 22:01:20 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder ad5e04249b wgengine/monitor: ignore adding/removing uninteresting IPs
One of the most common "unexpected" log lines is:

"network state changed, but stringification didn't"

One way that this can occur is if an interesting interface
(non-Tailscale, has interesting IP address)
gains or loses an uninteresting IP address (link local or loopback).

The fact that the interface is interesting is enough for EqualFiltered
to inspect it. The fact that an IP address changed is enough for
EqualFiltered to declare that the interfaces are not equal.

But the State.String method reasonably declines to print any
uninteresting IP addresses. As a result, the network state appears
to have changed, but the stringification did not.

The String method is correct; nothing interesting happened.

This change fixes this by adding an IP address filter to EqualFiltered
in addition to the interface filter. This lets the network monitor
ignore the addition/removal of uninteresting IP addresses.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-22 16:33:15 -08:00
60510a6ae7 .github/workflows: check that repo is clean after build and test
Linux-only for now, to avoid having to figure out why
powershell doesn't like my shell scripting. (Not that I blame it.)
That'll be enough to catch most regressions.

Fixes #1083

Co-authored-by: Aaron Klotz <aaron@tailscale.com>
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-22 15:28:59 -08:00
ca1b3fe235 net/tshttpproxy: use correct size for Windows BOOL argument
The Windows BOOL type is an int32. We were using a bool,
which is a one byte wide. This could be responsible for the
ERROR_INVALID_PARAMETER errors we were seeing for calls to
WinHttpGetProxyForUrl.

We manually checked all other existing Windows syscalls
for similar mistakes and did not find any.

Updates #879

Co-authored-by: Aaron Klotz <aaron@tailscale.com>
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-22 12:24:24 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 1a629a4715 net/portmapper: mark fewer PMP probe failures as unexpected
There are lots of lines in the logs of the form:

portmapper: unexpected PMP probe response: {OpCode:128 ResultCode:3
SecondsSinceEpoch:NNN MappingValidSeconds:0 InternalPort:0
ExternalPort:0 PublicAddr:0.0.0.0}

ResultCode 3 here means a network failure, e.g. the NAT box itself has
not obtained a DHCP lease. This is not an indication that something
is wrong in the Tailscale client, so use different wording here
to reflect that. Keep logging, so that we can analyze and debug
the reasons that PMP probes fail.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-22 11:13:15 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 758c37b83d net/netns: thread logf into control functions
So that darwin can log there without panicking during tests.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-18 15:09:51 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 85184a58ed wgengine/wgcfg: recover from mismatched PublicKey/Endpoints
In rare circumstances (tailscale/corp#3016), the PublicKey
and Endpoints can diverge.

This by itself doesn't cause any harm, but our early exit
in response did, because it prevented us from recovering from it.

Remove the early exit.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-18 14:28:41 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder b3d6704aa3 wgengine/magicsock: fix data race on endpoint.discoKey
endpoint.discoKey is protected by endpoint.mu.
endpoint.sendDiscoMessage was reading it without holding the lock.
This showed up in a CI failure and is readily reproducible locally.

The fix is in two parts.

First, for Conn.enqueueCallMeMaybe, eliminate the one-line helper method endpoint.sendDiscoMessage; call Conn.sendDiscoMessage directly.
This makes it more natural to read endpoint.discoKey in a context
in which endpoint.mu is already held.

Second, for endpoint.sendDiscoPing, explicitly pass the disco key
as an argument. Again, this makes it easier to read endpoint.discoKey
in a context in which endpoint.mu is already held.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-17 17:49:33 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 5a60781919 wgengine/magicsock: increase TestDiscokeyChange connection timeout
I believe that this should eliminate the flakiness.
If GitHub CI manages to be even slower that can be believed
(and I can believe a lot at this point),
then we should roll this back and make some more invasive changes.

Updates #654
Fixes #3247 (I hope)

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-17 14:13:58 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 773af7292b wgengine/magicsock: simplify peerMap.upsertEndpoint
We can do the "maybe delete" check unilaterally:
In the case of an insert, both oldDiscoKey
and ep.discoKey will be the zero value.

And since we don't use pi again, we can skip
giving it a name, which makes scoping clearer.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-16 15:15:49 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 9da22dac3d wgengine/magicsock: fix bug in peerMap.upsertEndpoint
Found by inspection by David Crawshaw while
investigating tailscale/corp#3016.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-16 15:15:49 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder 16870cb754 wgengine/magicsock: fix typo in comment
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-16 15:15:49 -08:00
Josh Bleecher SnyderandJosh Bleecher Snyder c467ed0b62 wgengine/wgcfg: always close io.Pipe
In DeviceConfig, we did not close r after calling FromUAPI.
If FromUAPI returned early due to an error, then it might
not have read all the data that IpcGetOperation wanted to write.
As a result, IpcGetOperation could hang, as in #3220.

We were also closing the wrong end of the pipe after IpcSetOperation
in ReconfigDevice.

To ensure that we get all available information to diagnose
such a situation, include all errors anytime something goes wrong.

This should fix the immediate crashing problem in #3220.
We'll then need to figure out why IpcGetOperation was failing.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-02 17:50:15 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 3fd5f4380f util/multierr: new package
github.com/go-multierror/multierror served us well.
But we need a few feature from it (implement Is),
and it's not worth maintaining a fork of such a small module.

Instead, I did a clean room implementation inspired by its API.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-11-02 17:50:15 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 94fb42d4b2 all: use testingutil.MinAllocsPerRun
There are a few remaining uses of testing.AllocsPerRun:
Two in which we only log the number of allocations,
and one in which dynamically calculate the allocations
target based on a different AllocsPerRun run.

This also allows us to tighten the "no allocs"
test in wgengine/filter.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-10-28 12:48:37 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 1df865a580 wgengine/magicsock: allow even fewer allocs per UDP receive
We improved things again for Go 1.18. Lock that in.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-10-28 12:48:37 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder c1d377078d wgengine/magicsock: use testingutil.MinAllocsPerRun
This speeds up and deflakes the test.

Fixes #2826 (again)

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-10-28 12:48:37 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 4bb2c6980d util/testingutil: new package with MinAllocsPerRun
testing.AllocsPerRun measures the total allocations performed
by the entire program while repeatedly executing a function f.
If some unrelated part of the rest of the program happens to
allocate a lot during that period, you end up with a test failure.

Ideally, the rest of the program would be silent while
testing.AllocsPerRun executes.

Realistically, that is often unachievable.

AllocsPerRun attempts to mitigate this by setting GOMAXPROCS to 1,
but that doesn't prevent other code from running;
it only makes it less likely.

You can also mitigate this by passing a large iteration count to
AllocsPerRun, but that is unreliable and needlessly expensive.

Unlike most of package testing, AllocsPerRun doesn't use any
toolchain magic, so we can just write a replacement.

One wild idea is to change how we count mallocs.
Instead of using runtime.MemStats, turn on memory profiling with a
memprofilerate of 1. Discard all samples from the profile whose stack
does not contain testing.AllocsPerRun. Count the remaining samples to
determine the number of mallocs.

That's fun, but overkill.

Instead, this change adds a simple API that attempts to get f to
run at least once with a target number of allocations.
This is useful when you know that f should allocate consistently.
We can then assume that any iterations with too many allocations
are probably due to one-time costs or background noise.

This suits most uses of AllocsPerRun.

Ratcheting tests tend to be significantly less flaky,
because they are biased towards success.
They can also be faster, because they can exit early,
once success has been reached.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-10-28 12:48:37 -07:00
Josh Bleecher Snyder 640de1921f depaware: update
To fix build broken by c9bf773312.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-10-28 12:35:14 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder cf8fcc1254 syncs: mark as safe for Go 1.18
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-10-27 18:10:09 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder f27950e97f go.mod: upgrade netaddr, netstack
For Go 1.18 support.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-10-27 15:47:15 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder b14db5d943 util/codegen: reorder AssertStructUnchanged args
The fully qualified name of the type is thisPkg.tname,
so write the args like that too.

Suggested-by: Joe Tsai <joetsai@digital-static.net>
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-17 16:46:08 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 3cd85c0ca6 util/codegen: add ContainsPointers
And use it in cmd/cloner.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-17 16:46:08 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder d5a0a4297e cmd/cloner: unify switch cases
And in the process, fix a bug:
The fmt formatting was being applied by writef,
not fmt.Sprintf, thus emitting a MISSING string.
And there's no guarantee that fmt will be imported
in the generated code.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-17 16:46:08 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder d8a8f70000 util/codegen: add NamedTypes
And use it in cmd/cloner.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-17 16:46:08 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 367a973dc2 cmd/cloner: delete some debug code
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-17 16:46:08 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 081be3e96b cmd/cloner: simplify code
Change from a single-case type switch to a type assertion
with an early return.

That exposes that the name arg to gen is unneeded.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-17 16:46:08 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder d5ab18b2e6 cmd/cloner: add Clone context to regen struct assignments
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-17 16:46:08 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 618376dbc0 util/codegen: add AssertStructUnchanged
Refactored out from cmd/cloner.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-17 16:46:08 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder fb66ff7c78 util/codegen: add package
This is a package for shared utilities used in doing codegen programs.
The inaugural API is for writing gofmt'd code to a file.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-17 16:46:08 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder a722e48cef wgengine/magicsock: skip alloc test with -race
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-17 09:56:32 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 07c09f470d ipn/ipnlocal: do not shut down the backend halfway through TestStateMachine
LocalBackend.Shutdown's docs say:

> The backend can no longer be used after Shutdown returns.

Nevertheless, TestStateMachine blithely calls Shutdown, talks some smack,
and continues on, expecting things to work. Other uses of Shutdown
in the codebase are as intended.

Things mostly kinda work anyway, except that the wgengine.Engine has been
shut down, so calls to Reconfig fail. Those get logged:

> local.go:603: wgengine status error: engine closing; no status

but otherwise ignored.

However, the Reconfig failure caused one fewer call to pause/unpause
than normal. Now the assertCalls lines match the equivalent ones
earlier in the test.

I don't see an obvious correct replacement for Shutdown in the context
of this test; I'm not sure entirely what it is trying to accomplish.
It is possible that many of the tests remaining after the prior call
to Shutdown are now extraneous. They don't harm anything, though,
so err on the side of safety and leave them for now.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-17 09:56:32 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder f834a4ade5 ipn/ipnlocal: fix minor typo in comment
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-17 09:56:32 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 221cc5f8f2 ipn/ipnlocal: reduce line noise in tests
Use helpers and variadic functions to make the call sites
a lot easier to read, since they occur a lot.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-17 09:56:32 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 45d3174c0d ipn/ipnlocal: add LocalBackend.broadcastStatusChanged
To reduce repetition.

Also, document why we acquire the lock.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-16 13:36:41 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder b7ede14396 Revert "ipn/ipnlocal: remove locks around sync.Cond.Broadcast call"
Reason for revert: Causes ipnlocal tests to deadlock intermittently.

This reverts commit 1b15349e01.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-16 13:36:41 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 3ea8cf9c62 ipn/ipnlocal: use quicktest.IsNotNil in tests
This didn't exist when the test was written.
Now it does (frankban/quicktest#94); use it.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-15 15:31:51 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 1b15349e01 ipn/ipnlocal: remove locks around sync.Cond.Broadcast call
They are unnecessary.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-15 15:31:51 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 3b58c118dd ipn/ipnlocal: inline LocalBackend.getEngineStatus
For uniformity.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-15 15:31:51 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 0f4c0e558b ipn/ipnlocal: use a switch statement instead of an else-if chain
For clarity.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-15 15:31:51 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 7421ba91ec ipn/ipnlocal: only call UpdateEndpoints when the endpoints change
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-15 15:31:51 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 5b02ad16b9 control/controlclient: replace TODO with explanation
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-15 15:31:51 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder b681edc572 ipn/ipnlocal: add failing test
Concurrent calls to LocalBackend.setWgengineStatus
could result in some of the status updates being dropped.
This was exacerbated by 92077ae78c,
which increases the probability of concurrent status updates,
causing test failures (tailscale/corp#2579).

It's going to take a bit of work to fix this test.
The ipnlocal state machine is difficult to reason about,
particularly in the face of concurrency.
We could fix the test trivially by throwing a new mutex around
setWgengineStatus to serialize calls to it,
but I'd like to at least try to do better than cosmetics.

In the meantime, commit the test.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-15 15:31:51 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 7693d36aed all: close fake userspace engines when tests complete
We were leaking FDs.
In a few places, switch from defer to t.Cleanup.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-15 15:31:51 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 008f36986e .github/workflows: remove separate "build stringer" step
We now use "go run" instead of compiling stringer separately.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-15 12:17:57 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 9faee90744 .github/workflows: skip net/dnsfallback go generate check on release branch
We don't want to force ourselves to update the DERP list
every time we want to cut a new release.
Having an outdated DERP list on release branches is OK.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-15 12:17:57 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 4bbf5a8636 cmd/cloner: reduce diff noise when changing command
Spelling out the command to run for every type
means that changing the command makes for a large, repetitive diff.
Stop doing that.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-15 10:58:12 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 865d8c0d23 cmd: upgrade to ffcli v3
None of the breaking changes from v2 to v3 are relevant to us.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-14 13:21:55 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder a3c5de641b portlist: stop logging stray UDP ports
These "weird" port lines show up in logs frequently.
They're the result of uninteresting races,
and they're not actionable. Remove the noise.

Remove the isLoopbackAddr case to placate staticcheck.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-14 11:18:09 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 3759fb8987 derp: deflake TestSendFreeze
On about 1 out of 500 runs, TestSendFreeze failed:

    derp_test.go:416: bob: unexpected message type derp.PeerGoneMessage

Closing alice before bob created a race.
If bob closed promptly, the test passed.
If bob closed slowly, and alice's disappearance caused
bob to receive a PeerGoneMessage before closing, the test failed.

Deflake the test by closing bob first.
With this fix, the test passed 12,000 times locally.

Fixes #2668

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-09-13 15:58:04 -07:00
Josh Bleecher SnyderandBrad Fitzpatrick 4ff0757d44 cmd/testcontrol: add test control server
This is useful for manual performance testing
of networks with many nodes.
I imagine it'll grow more knobs over time.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-08-19 17:50:48 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 6ef734e493 wgengine: predict min.Peers length across calls
The number of peers we have will be pretty stable across time.
Allocate roughly the right slice size.
This reduces memory usage when there are many peers.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-08-18 16:12:45 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder adf696172d wgengine/userspace: reduce allocations in getStatus
Two optimizations.

Use values instead of pointers.
We were using pointers to make track the "peer in progress" easier.
It's not too hard to do it manually, though.

Make two passes through the data, so that we can size our
return value accurately from the beginning.
This is cheap enough compared to the allocation,
which grows linearly in the number of peers,
that it is worth doing.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-08-18 16:12:08 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder fcca374fa7 tstest/integration/testcontrol: sort peers in map response
This is part of the control protocol.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-08-18 14:49:26 -07:00
Josh Bleecher SnyderandJosh Bleecher Snyder 4c8b5fdec4 control/controlclient: do not periodically print full netmap
The netmaps can get really large.
Printing, processing, and uploading them is expensive.
Only print the header on an ongoing basis.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-08-17 12:57:49 -07:00