Commit Graph

111 Commits (d81a2b2ce2639d3c119785195695606ffef80c48)

Author SHA1 Message Date
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
Maisem Ali 1f4669a380 all: standardize on LocalAPI
Signed-off-by: Maisem Ali <maisem@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
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
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
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
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 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
Maisem Ali 9f604f2bd3
derp: add (*Server).IsClientConnectedForTest func. (#4331)
This allows tests to verfiy that a DERP connection was actually
established.

Related to #4326
Updates tailscale/corp#2579

Signed-off-by: Maisem Ali <maisem@tailscale.com>
3 years ago
Brad Fitzpatrick 18818763d1 derp: set Basic Constraints on metacert
See https://github.com/golang/go/issues/51759#issuecomment-1071147836

Once we deploy this, tailscaled should work again for macOS users with
Go 1.18.

Updates golang/go#51759

Change-Id: I869b6ddc556a2de885e96ccf9f335dfc8f6f6a7e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Josh Bleecher Snyder 0868329936 all: use any instead of interface{}
My favorite part of generics.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
3 years ago
Brad Fitzpatrick 41fd4eab5c envknob: add new package for all the strconv.ParseBool(os.Getenv(..))
A new package can also later record/report which knobs are checked and
set. It also makes the code cleaner & easier to grep for env knobs.

Change-Id: Id8a123ab7539f1fadbd27e0cbeac79c2e4f09751
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Brad Fitzpatrick 2aeb93003f derp: add metrics to server got pings, sent pongs
Updates #3652

Change-Id: I1d350bcaee39ea36b0c71912028624d18fb541b4
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Brad Fitzpatrick 63d9c7b9b3 derp: add Client.LocalAddr method
So magicsock can later ask a DERP connection whether its source IP
would've changed if it reconnected.

Updates #3619

Change-Id: Ibc8810340c511d6786b60c78c1a61c09f5800e40
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Brad Fitzpatrick 434af15a04 derp: support client->server ping (and server->client pong)
In prep for a future change to have client ping derp connections
when their state is questionable, rather than aggressively tearing
them down and doing a heavy reconnect when their state is unknown.

We already support ping/pong in the other direction (servers probing
clients) so we already had the two frame types, but I'd never finished
this direction.

Updates #3619

Change-Id: I024b815d9db1bc57c20f82f80f95fb55fc9e2fcc
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
David Anderson 84c3a09a8d types/key: export constants for key size, not a method.
Signed-off-by: David Anderson <danderson@tailscale.com>
3 years ago
David Anderson c1d009b9e9 ipn/ipnstate: use key.NodePublic instead of the generic key.Public.
Updates #3206.

Signed-off-by: David Anderson <danderson@tailscale.com>
3 years ago
David Anderson 1f06f77dcb derp: remove package shadowing of types/key.
Updates #3206

Signed-off-by: David Anderson <danderson@tailscale.com>
3 years ago
David Anderson 37c150aee1 derp: use new node key type.
Update #3206

Signed-off-by: David Anderson <danderson@tailscale.com>
3 years ago
Brad Fitzpatrick 73f177e4d5 derp: throttle client sends if server advertises rate limits
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Brad Fitzpatrick fc160f80ee metrics: move currentFDs code to the metrics package
Updates #2784

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Brad Fitzpatrick 73280595a8 derp: accept dup clients without closing prior's connection
A public key should only have max one connection to a given
DERP node (or really: one connection to a node in a region).

But if people clone their machine keys (e.g. clone their VM, Raspbery
Pi SD card, etc), then we can get into a situation where a public key
is connected multiple times.

Originally, the DERP server handled this by just kicking out a prior
connections whenever a new one came. But this led to reconnect fights
where 2+ nodes were in hard loops trying to reconnect and kicking out
their peer.

Then a909d37a59 tried to add rate
limiting to how often that dup-kicking can happen, but empirically it
just doesn't work and ~leaks a bunch of goroutines and TCP
connections, tying them up for hour+ while more and more accumulate
and waste memory. Mostly because we were doing a time.Sleep forever
while not reading from their TCP connections.

Instead, just accept multiple connections per public key but track
which is the most recent. And if two both are writing back & forth,
then optionally disable them both. That last part is only enabled in
tests for now. The current default policy is just last-sender-wins
while we gather the next round of stats.

Updates #2751

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Brad Fitzpatrick ffd22050c0 derp: export current file descriptor metric 3 years ago
slowy07 ac0353e982 fix: typo spelling grammar
Signed-off-by: slowy07 <slowy.arfy@gmail.com>
3 years ago
Brad Fitzpatrick f35b8c3ead derp: fix meshing accounting edge case bug
If a peer is connected to multiple nodes in a region (so
multiForwarder is in use) and then a node restarts and re-sends all
its additions, this bug about whether an element is in the
multiForwarder could cause a one-time flip in the which peer node we
forward to.  Note a huge deal, but not written as intended.

Thanks to @lewgun for the bug report in #2141.

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Brad Fitzpatrick fd7b738e5b derp: use pad32 package for padding, reduce duplication
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Brad Fitzpatrick 7298e777d4 derp: reduce server memory by 30% by removing persistent bufio.Writer
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Brad Fitzpatrick b622c60ed0 derp,wgengine/magicsock: don't assume stringer is in $PATH for go:generate
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Brad Fitzpatrick a909d37a59 derp: rate limit how often same-key clients can kick each other off server
Updates #392
Updates #506

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Josh Bleecher Snyder 4dbbd0aa4a cmd/addlicense: add command to add licenseheaders to generated code
And use it to make our stringer invocations match the existing code.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
3 years ago
maddie d976a84d7e derp: allow self node when verifying clients
Fixes #2408

Signed-off-by: Maddie Zhan <maddie.zhan@cynovan.com>
3 years ago
Brad Fitzpatrick 4c0494185b derp: remove "fine for now" intentional slow memory leak from derp server
It was once believed that it might be useful. It wasn't. We never used it.

Remove it so we don't slowly leak memory.

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
David Anderson d98829583a derp: use a dedicated queue for disco traffic.
Signed-off-by: David Anderson <danderson@tailscale.com>
3 years ago
David Anderson 67158549ab derp: actually export the new drop counter.
Signed-off-by: David Anderson <danderson@tailscale.com>
3 years ago
David Anderson 36492ace9d derp: add counters to track the type of dropped packets.
Signed-off-by: David Anderson <danderson@tailscale.com>
3 years ago
julianknodt 148602a89a derp,cmd/derper: allow server to verify clients
This adds a flag to the DERP server which specifies to verify clients through a local
tailscaled. It is opt-in, so should not affect existing clients, and is mainly intended for
users who want to run their own DERP servers. It assumes there is a local tailscaled running and
will attempt to hit it for peer status information.

Updates #1264

Signed-off-by: julianknodt <julianknodt@gmail.com>
3 years ago
julianknodt 3687e5352b derp: fix traffic handler peer addresses
Before it was using the local address and port, so fix that.
The fields in the response from `ss` are:

State, Recv-Q, Send-Q, Local Address:Port, Peer Address:Port, Process

Signed-off-by: julianknodt <julianknodt@gmail.com>
3 years ago
julianknodt 3728634af9 derp: add debug traffic handler
This adds a handler on the DERP server for logging bytes send and received by clients of the
server, by holding open a connection and recording if there is a difference between the number
of bytes sent and received. It sends a JSON marshalled object if there is an increase in the
number of bytes.

Signed-off-by: julianknodt <julianknodt@gmail.com>
3 years ago
julianknodt fe54721e31 derp: add pkt queue latency timer
It would be useful to know the time that packets spend inside of a queue before they are sent
off, as that can be indicative of the load the server is handling (and there was also an
existing TODO). This adds a simple exponential moving average metric to track the average packet
queue duration.
Changes during review:
Add CAS loop for recording queue timing w/ expvar.Func, rm snake_case, annotate in milliseconds,
convert

Signed-off-by: julianknodt <julianknodt@gmail.com>
4 years ago
David Anderson 54e6c3a290 version: use OSS repo's version when building.
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>
4 years ago
Brad Fitzpatrick 169ff22a84 derp: set NotBefore and NotAfter in DERP server's metacert
Fixes regression from e415991256 that
only affected Windows users because Go only on Windows delegates x509
cert validation to the OS and Windows as unhappy with our "metacert"
lacking NotBefore and NotAfter.

Fixes #705
4 years ago
Brad Fitzpatrick e415991256 derp, derp/derphttp: remove one RTT from DERP setup
* 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>
4 years ago
Brad Fitzpatrick 805850add9 derp: remove JSON struct tags in comments
They don't work in comments.

Added a test too to show that there's no change in behavior.
(It does case insensitive matching on parse anyway)
4 years ago
Brad Fitzpatrick 93ffc565e5 derp: remove protocol version 1 support
It hasn't existed for a long time and there are no current users.

Fixes #199
4 years ago
Josh Bleecher Snyder 062bd67d3b derp: use rand instead of crypto/rand to generate jitter
We don't need crypto/rand. Let the OS keep its entropy bits.

Signed-off-by: Josh Bleecher Snyder <josharian@gmail.com>
4 years ago
David Anderson 37c19970b3 derp: add a debug option to verbosely log drops to a destination.
Signed-off-by: David Anderson <danderson@tailscale.com>
4 years ago
Josh Bleecher Snyder 909c165382 derp: remove two key.Public allocations
Reading and writing a [32]byte key to a bufio.Reader/bufio.Writer
can easily by done without allocating. Do so.

It is slower; on my machine, it adds about 100ns per read/write.
However, the overall request takes a minimum of several µs,
and it cuts allocations meaningfully, so it is probably worth it.

name                      old time/op    new time/op    delta
SendRecv/msgsize=10-8       9.21µs ± 9%    9.08µs ± 8%     ~     (p=0.250 n=15+15)
SendRecv/msgsize=100-8      6.51µs ± 9%    6.60µs ± 7%     ~     (p=0.259 n=15+13)
SendRecv/msgsize=1000-8     7.24µs ±13%    7.61µs ±36%     ~     (p=1.000 n=11+15)
SendRecv/msgsize=10000-8    19.5µs ±15%    19.9µs ±25%     ~     (p=0.890 n=14+15)

name                      old speed      new speed      delta
SendRecv/msgsize=10-8     1.09MB/s ± 8%  1.10MB/s ± 8%     ~     (p=0.286 n=15+15)
SendRecv/msgsize=100-8    15.4MB/s ± 8%  15.1MB/s ± 6%     ~     (p=0.129 n=15+12)
SendRecv/msgsize=1000-8    139MB/s ±15%   135MB/s ±28%     ~     (p=1.000 n=11+15)
SendRecv/msgsize=10000-8   516MB/s ±17%   506MB/s ±21%     ~     (p=0.880 n=14+15)

name                      old alloc/op   new alloc/op   delta
SendRecv/msgsize=10-8         170B ± 1%      108B ± 1%  -36.63%  (p=0.000 n=15+15)
SendRecv/msgsize=100-8        265B ± 1%      203B ± 1%  -23.34%  (p=0.000 n=15+15)
SendRecv/msgsize=1000-8     1.18kB ± 1%    1.12kB ± 0%   -5.31%  (p=0.000 n=14+14)
SendRecv/msgsize=10000-8    18.8kB ± 2%    18.8kB ± 2%     ~     (p=0.443 n=12+12)

name                      old allocs/op  new allocs/op  delta
SendRecv/msgsize=10-8         4.00 ± 0%      2.00 ± 0%  -50.00%  (p=0.000 n=15+15)
SendRecv/msgsize=100-8        4.00 ± 0%      2.00 ± 0%  -50.00%  (p=0.000 n=15+15)
SendRecv/msgsize=1000-8       4.00 ± 0%      2.00 ± 0%  -50.00%  (p=0.000 n=15+15)
SendRecv/msgsize=10000-8      5.00 ± 0%      3.00 ± 0%  -40.00%  (p=0.000 n=13+14)

Signed-off-by: Josh Bleecher Snyder <josharian@gmail.com>
4 years ago