Commit Graph

635 Commits

Author SHA1 Message Date
Brad Fitzpatrick 61d83f759b wgengine/magicsock: remove redundant derpMagicIP comparison
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-03-06 11:31:39 -08:00
David Anderson bd60a750e8 wgengine/magicsock: fix packet spraying test to (mostly) pass.
It previously passed incorrectly due to bugs. With those fixed,
it becomes flaky for 2 reasons. One of them is the wireguard handshake
race, which can eat the 1st sprayed packet and prevent roamAddr
discovery. This change fixes that failure, by spreading the test
traffic out enough that additional spraying occurs.

Signed-Off-By: David Anderson <danderson@tailscale.com>
2020-03-06 11:10:13 -08:00
David Anderson ef31dd7bb5 wgengine/magicsock: check all 3 fast paths independently.
The previous code would skip the DERP short-circuit if roamAddr
was set, which is not what we wanted. More generally, hitting
any of the fast path conditions is a direct return, so we can
just have 3 standalone branches rather than 'else if' stuff.

Signed-Off-By: David Anderson <danderson@tailscale.com>
2020-03-06 11:10:13 -08:00
David Anderson 05a52746a4 wgengine/magicsock: fix destination selection logic to work with DERP.
The effect is subtle: when we're not spraying packets, and have not yet
figured out a curAddr, and we're not spraying, we end up sending to
whatever the first IP is in the iteration order. In English, that
means "when we have no idea where to send packets, and we've given
up on sending to everyone, just send to the first addr we see in
the list."

This is, in general, what we want, because the addrs are in sorted
preference order, low to high, and DERP is the least preferred
destination. So, when we have no idea where to send, send to DERP,
right?

... Except for very historical reasons, appendDests iterated through
addresses in _reverse_ order, most preferred to least preferred.
crawshaw@ believes this was part of the earliest handshaking
algorithm magicsock had, where it slowly iterated through possible
destinations and poked handshakes to them one at a time.

Anyway, because of this historical reverse iteration, in the case
described above of "we have no idea where to send", the code would
end up sending to the _most_ preferred candidate address, rather
than the _least_ preferred. So when in doubt, we'd end up firing
packets into the blackhole of some LAN address that doesn't work,
and connectivity would not work.

This case only comes up if all your non-DERP connectivity options
have failed, so we more or less failed to detect it because we
didn't have a pathological test box deployed. Worse, codependent
bug 2839854994 made DERP accidentally
work sometimes anyway by incorrectly exploiting roamAddr behavior,
albeit at the cost of making DERP traffic symmetric. In fixing
DERP to once again be asymmetric, we effectively removed the
bandaid that was concealing this bug.

Signed-Off-By: David Anderson <danderson@tailscale.com>
2020-03-06 11:10:13 -08:00
David Anderson 97e58ad44d wgengine/magicsock: only set addrByKey once in CreateEndpoint.
Signed-Off-By: David Anderson <danderson@tailscale.com>
2020-03-06 11:10:13 -08:00
Brad Fitzpatrick fbab12c94c wgengine/magicsock: skip netcheck if external STUN aren't in use
Updates #146 (not a complete fix yet probably)
2020-03-06 07:47:54 -08:00
Brad Fitzpatrick fe0051fafd wgengine/magicsock: expand AddrSet.addrs comment 2020-03-05 21:17:41 -08:00
David Anderson 2839854994 wgengine/magicsock: never set a DERP server as a roamAddr.
DERP traffic is asymmetric by design, with nodes always sending
to their peer's home DERP server. However, if roamAddr is set,
magicsock will always push data there, rather than let DERP
server selection do its thing, so we end up accidentally
creating a symmetric flow.

Signed-Off-By: David Anderson <danderson@tailscale.com>
2020-03-05 17:45:17 -08:00
David Anderson 4f5c0da1ae wgengine/magicsock: log when home DERP server changes. 2020-03-05 17:18:05 -08:00
Brad Fitzpatrick 6978b93bdd derp, magicsock: track home (preferred) vs visiting connections for stats 2020-03-05 15:00:56 -08:00
Brad Fitzpatrick 12b77f30ad wgengine/magicsock: close stale DERP connections 2020-03-05 12:49:37 -08:00
Brad Fitzpatrick 2cff9016e4 net/dnscache: add overly simplistic DNS cache package for selective use
I started to write a full DNS caching resolver and I realized it was
overkill and wouldn't work on Windows even in Go 1.14 yet, so I'm
doing this tiny one instead for now, just for all our netcheck STUN
derp lookups, and connections to DERP servers. (This will be caching a
exactly 8 DNS entries, all ours.)

Fixes #145 (can be better later, of course)
2020-03-05 12:23:37 -08:00
Brad Fitzpatrick a36ccb8525 wgengine/magicsock: actually add to the activeDerp map
Fixes bug just introduced in 8f9849c140; not tested enough :(
2020-03-05 12:23:37 -08:00
Brad Fitzpatrick 8f9849c140 wgengine/magicsock: collapse three DERP maps down into one 2020-03-05 08:54:08 -08:00
Brad Fitzpatrick 40ebba1373 magicsock: use [unexpected] convention more
Fixes #136 (not entirely, but we have a convention now)
2020-03-05 08:18:55 -08:00
Brad Fitzpatrick 848a2bddf0 wgengine/magicsock: update set of DERP nodes 2020-03-05 08:18:55 -08:00
David Crawshaw 7932481b95 magicsock: lookup AddrSet by key from DERP
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-04 18:07:27 -05:00
Brad Fitzpatrick eac62ec5ff ipn, wgengine/magicsock: add ipn.Prefs.DisableDERP bool
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-03-04 12:53:37 -08:00
Brad Fitzpatrick bf704a5218 derp: protocol negotiation, add v2: send src pub keys to clients in packets
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-03-04 09:55:13 -08:00
David Crawshaw a65b2a0efd magicsock: add some DERP tests
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-04 12:40:33 -05:00
David Crawshaw a33419167b magicsock: plumb through derpTLSConfig variable (for testing)
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-04 12:40:33 -05:00
David Crawshaw caec2c7e8b magicsock: test sequence of pings
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-04 12:40:33 -05:00
David Crawshaw 9f584414d9 magicsock: simple ping test via magicsock
Passes `go test -count=20 -race ./wgengine/magicsock`

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-04 12:40:33 -05:00
David Crawshaw 34859f8e7d wgengine, magicsock: add a CreateBind method
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-04 12:40:33 -05:00
David Crawshaw 75e62d318f magicsock: use local STUN server in tests
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-04 12:40:33 -05:00
Brad Fitzpatrick b27d4c017a magicsock, wgengine, ipn, controlclient: plumb regular netchecks to map poll
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-03-04 08:19:45 -08:00
Brad Fitzpatrick 724c37fb41 wgengine/magicsock: start tracking nearest DERP node 2020-03-03 17:50:17 -08:00
Brad Fitzpatrick 89a2c3eb04 wgengine: don't create duplicate iptables rules on Linux, clean up
Fixes #131

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-03-03 13:46:53 -08:00
Brad Fitzpatrick 657f9593ae Reduce some logspam. 2020-03-02 14:55:12 -08:00
Brad Fitzpatrick 4675c70464 wgengine/magicsock: check STUN regularly 2020-03-02 12:37:52 -08:00
Brad Fitzpatrick bc7bc43fb8 magicsock, interfaces: move some code from magicsock to interfaces 2020-03-02 10:38:44 -08:00
Brad Fitzpatrick af7a01d6f0 wgengine/magicsock: drop donec channel, rename epUpdateCtx to serve its purpose 2020-03-02 09:31:25 -08:00
David Crawshaw cc4afa775f magicsock: rate limit send error log messages
The x/time/rate dependency adds 24kb to tailscaled binary size.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-02 08:10:06 -05:00
David Crawshaw 0752c77dc2 magicsock: keep DERP magic IPs out of the address map
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-01 07:29:48 -05:00
David Crawshaw c6550135d5 magicsock: remove the index from indexedAddrs
The value predates the introduction of AddrSet which replaces
the index by tracking curAddr directly.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-01 07:29:48 -05:00
David Crawshaw d417be6a4b controlclinet: clone filter.MatchAllowAll
This avoids a non-obvious data race, where the JSON decoder ends
up creating do-nothing writes into global variables.

	==================
	WARNING: DATA RACE
	Write at 0x0000011e1860 by goroutine 201:
	  tailscale.com/wgengine/packet.(*IP).UnmarshalJSON()
	      /home/crawshaw/repo/corp/oss/wgengine/packet/packet.go:83 +0x2d9
	  encoding/json.(*decodeState).literalStore()
	      /home/crawshaw/go/go/src/encoding/json/decode.go:877 +0x445e
	...
	  encoding/json.Unmarshal()
	      /home/crawshaw/go/go/src/encoding/json/decode.go:107 +0x1de
	  tailscale.com/control/controlclient.(*Direct).decodeMsg()
	      /home/crawshaw/repo/corp/oss/control/controlclient/direct.go:615 +0x1ab
	  tailscale.com/control/controlclient.(*Direct).PollNetMap()
	      /home/crawshaw/repo/corp/oss/control/controlclient/direct.go:525 +0x1053
	  tailscale.com/control/controlclient.(*Client).mapRoutine()
	      /home/crawshaw/repo/corp/oss/control/controlclient/auto.go:428 +0x3a6
	Previous read at 0x0000011e1860 by goroutine 86:
	  tailscale.com/wgengine/filter.matchIPWithoutPorts()
	      /home/crawshaw/repo/corp/oss/wgengine/filter/match.go:108 +0x91
	  tailscale.com/wgengine/filter.(*Filter).runIn()
	      /home/crawshaw/repo/corp/oss/wgengine/filter/filter.go:147 +0x3c6
	  tailscale.com/wgengine/filter.(*Filter).RunIn()
	      /home/crawshaw/repo/corp/oss/wgengine/filter/filter.go:127 +0xb0
	  tailscale.com/wgengine.(*userspaceEngine).SetFilter.func1()
	      /home/crawshaw/repo/corp/oss/wgengine/userspace.go:390 +0xfc
	  github.com/tailscale/wireguard-go/device.(*Device).RoutineDecryption()
	      /home/crawshaw/repo/corp/wireguard-go/device/receive.go:295 +0xa1f

For #112

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-28 22:33:06 -05:00
Brad Fitzpatrick 1abf2da392 wgengine/magicsock: reset favorite address on handshakes
Updates #92 (not a complete fix; could be better/faster?)

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-28 17:23:09 -05:00
Brad Fitzpatrick 67ede8d6d2 wgengine, magicsock: fix SetPrivateKey data race
Updates #112

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-28 11:15:07 -08:00
Brad Fitzpatrick 19b54d0ae7 wgengine: fix a data race on StatusCallback
Updates tailscale/tailscale#112

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-28 09:32:06 -08:00
David Crawshaw c576a57067 wgengine: avoid holding any locks during HandshakeDone
Because wgLock is held while some wireguard-go methods run,
trying to hold wgLock during HandshakeDone potentially creates
lock cycles between wgengine and internals of wireguard-go.

Arguably wireguard-go should call HandshakeDone in a new goroutine,
but until its API promises that, don't make any assumptions here.

Maybe for #110.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-28 06:32:38 -05:00
Brad Fitzpatrick c185e6b4b0 stunner: support IPv6, add latency info to callbacks, use unique TxIDs per retry
And some more docs.

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-27 09:23:51 -08:00
David Crawshaw 44670d0da9 wgengine: revert wgdev.Close on Close from last commit
Causes as-yet-unknown problems in some tests.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-25 17:00:37 -05:00
wardn 9390a3ef55 wgengine: properly clean up freebsd routes and interfaces on close
Signed-off-by: wardn <wardn@users.noreply.github.com>
2020-02-25 16:40:10 -05:00
David Crawshaw 7a3be96199 wgengine: add pinger to generate initial spray packets
For 3 seconds after a successful handshake, wgengine will send a
ping packet every 300ms to its peer. This ensures the spray logic
in magicsock has something to spray.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-25 15:09:08 -05:00
David Crawshaw a6ad3c46e2 magicsock: spray some normal packets after a handshake
In particular, this is designed to catch the case where a
HandshakeInitiation packet is sent out but the intermediate NATs
have not been primed, so the packet passes over DERP.
In that case, the HandshakeResponse also comes back over DERP,
and the connection proceeds via DERP without ever trying to punch
through the NAT.

With this change, the HandshakeResponse (which was sprayed out
and so primed one NAT) triggers an UpdateDst, which triggers
the extra spray logic.

(For this to work, there has to be an initial supply of packets
to send on to a peer for the three seconds following a handshake.
The source of these packets is left as a future exercise.)

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-24 17:29:35 -05:00
Brad Fitzpatrick 8696b17b5f wgengine/magicsock: turn off DERP log spamminess by default
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-24 10:24:12 -08:00
Brad Fitzpatrick 7a3b91390b wgengine/magicsock: fix crash in Send when Endpoint isn't an AddrSet
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-24 08:47:20 -08:00
David Crawshaw 868cfae84f wgengine, magicsock: adjust for wireguard-go conn/device package split
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-24 07:30:14 -05:00
wardn c51b8c206d wgengine: resolv.conf spelling corrections
Signed-off-by: wardn <wardn@users.noreply.github.com>
2020-02-22 06:44:56 -08:00
Brad Fitzpatrick cc7b9b0dff control/controlclient: fix priority of DERP server, add comment 2020-02-21 14:47:05 -08:00
Brad Fitzpatrick c02f4b5a1f control/controlclient: add temporary mechanism to force derp on
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-21 14:09:24 -08:00
Brad Fitzpatrick 525bf1f3d2 wgengine/magicsock: remember fixed port number preference
So LinkChange events rebind to the same port when possible.
2020-02-21 13:51:18 -08:00
Brad Fitzpatrick 379a3125fd derp, wgengine/magicsock: support more than just packets from Client.Recv
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-20 22:08:13 -08:00
David Crawshaw 4ebc0fa70f wgengine: incremental update of peers on network map change
This is the first, and easier, part of incremental wireguard-go
reconfiguration. It means that a new node appearing on the
network does not cause all existing nodes to re-handshake with
the other nodes they are talking to.

(This code has been running on hello.ipn.dev for a few weeks and
peers have successfully reconnected to it through many network
map updates.)

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-20 13:48:34 -05:00
Brad Fitzpatrick d298d5b1f8 wgengine/magicsock: support multiple derp servers, and not just for handshakes
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-20 08:10:12 -08:00
Martin Baillie a9bff99a9b wgengine: add OpenBSD router DNS update handling
Also removes validated TODO comments.

Signed-off-by: Martin Baillie <martin@baillie.email>
2020-02-20 08:03:07 -08:00
David Crawshaw 45d687e213 wgengine: fix build on linux/freebsd/openbsd/windows
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-19 11:58:59 -05:00
David Crawshaw d0f697ee07 wgengine: update for wgcfg changes
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-19 11:44:37 -05:00
Brad Fitzpatrick fd1aa4f7f6 wgengine/magicsock: add a reSTUN method
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-18 10:55:36 -08:00
Brad Fitzpatrick e06ca40650 wgengine, magicsock, derp: misc cleanups, docs
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-18 08:58:00 -08:00
wardn 5d79530caa wgengine: create freebsd-specific implementation
Signed-off-by: wardn <wardn@users.noreply.github.com>
2020-02-17 19:16:08 -08:00
Brad Fitzpatrick 259406e797 derp: move away from [32]byte key types
And some minor cleanup in the process.

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-17 14:18:09 -08:00
Tobias Klauser 4d09316f9a wgengine/monitor: use RTMGRP_* consts from x/sys/unix
Bump golang.org/x/sys/unix to get the RTMGRP_* consts and use them.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
2020-02-17 14:15:08 -08:00
Brad Fitzpatrick 997678f540 wgengine/monitor: make Close not block forever on Linux
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-17 11:39:33 -08:00
Brad Fitzpatrick 7f5e3febe5 wgengine: move link monitor to be owned by the engine, not the router
And make the monitor package portable with no-op implementations on
unsupported operating systems.

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-17 09:53:17 -08:00
Brad Fitzpatrick 79295b1138 wgengine: simplify, change some signatures
* 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>
2020-02-17 08:04:31 -08:00
Brad Fitzpatrick 2896be60db Move "logger" package to under types, now that we have it.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-14 20:23:05 -08:00
Brad Fitzpatrick 587c3fcac4 control/controlclient, wgengine/magicsock: misc cleanups
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-14 09:50:08 -08:00
wardn 58ce50389e wgengine: build for freebsd
Signed-off-by: wardn <wardn@users.noreply.github.com>
2020-02-14 08:40:04 -08:00
wardn 2cafbd74c7 monitor: refactor for architecture-specific connection implementations
Signed-off-by: wardn <wardn@users.noreply.github.com>
2020-02-13 09:46:17 -08:00
Brad Fitzpatrick c773abde77 wgengine: fix nil pointer deref crash from earlier change
Fixes #45
2020-02-13 08:59:31 -08:00
Brad Fitzpatrick 745c8c92b1 wgengine: fix windows build for winipcfg-go
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-12 22:05:13 -08:00
David Anderson 36f5433476 wgengine: fix the build on darwin, windows, openbsd.
7e5e3277 changed the Router interface definition, but forgot to
fix up these platform files.

Signed-off-by: David Anderson <dave@natulte.net>
2020-02-12 16:16:05 -08:00
David Anderson 5c2deb66be wgengine: remove MTU TODO.
The MTU is currently set when creating the tun device,
elsewhere in the code. Maybe someday we'll want some kind
of per-platform MTU configuration here, but not in the
short-medium term.

Signed-off-by: David Anderson <dave@natulte.net>
2020-02-12 15:59:13 -08:00
David Anderson afa83358f7 wgenging: use logger.Logf type in openbsd router.
Signed-off-by: David Anderson <dave@natulte.net>
2020-02-12 15:58:49 -08:00
Martin Baillie 15f8c8dde4 wgengine: add initial rough OpenBSD implementation
Signed-off-by: Martin Baillie <martin@baillie.email>
2020-02-12 15:57:49 -08:00
Brad Fitzpatrick 7e5e32775a wgengine: flesh out some docs, minor cleanups
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-12 13:37:45 -08:00
Brad Fitzpatrick 819daf10e2 wgengine: flesh out some docs
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-12 13:37:45 -08:00
wardn 490e586eac wgengine: add required NewFakeRouter parameter
Signed-off-by: wardn <wardn@users.noreply.github.com>
2020-02-12 13:09:33 -08:00
Brad Fitzpatrick a59dc5f155 Use logger.Logf consistently. It was used in most places.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-02-11 09:38:32 -08:00
David Anderson 2f9cdd0aac wgengine: fix error string.
Signed-off-by: David Anderson <dave@natulte.net>
2020-02-11 00:01:58 -08:00
David Anderson 43becc4334 wgengine/packet: fix minor lint errors.
Signed-off-by: David Anderson <dave@natulte.net>
2020-02-11 00:01:14 -08:00
David Anderson a07906d1d8 wgengine: make SetRoutesFunc less appealing to use.
It exists as a way to glue the mac-specific xcode logic with the OSS
logic, and shouldn't be used by anything but the xcode glue.
2020-02-10 21:40:00 -08:00
David Crawshaw 87334fb332 wgengine, controlclient: fewer pointers in wgcfg key types
Signed-off-by: David Crawshaw <david@zentus.com>
2020-02-10 22:09:59 -05:00
Earl Lee a8d8b8719a Move Linux client & common packages into a public repo. 2020-02-09 09:32:57 -08:00