Commit Graph
97 Commits
Author SHA1 Message Date
David CrawshawandDavid Crawshaw 990e2f1ae9 tailcfg: generate some Clone methods
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-07-27 11:08:09 +10:00
David CrawshawandDavid Crawshaw 961b9c8abf cmd/cloner: tool to generate Clone methods
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-07-27 11:08:09 +10:00
David CrawshawandBrad Fitzpatrick 9258d64261 wgengine/router: do not call ifconfig up if SetRoutesFunc is set
The NetworkExtension brings up the interface itself and does not have
access to `ifconfig`, which the underlying BSD userspace router attempts
to use when Up is called.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-06-26 09:45:28 -07:00
David CrawshawandDavid Crawshaw cf5d25e15b wgengine: ensure pingers are gone before returning from Close
We canceled the pingers in Close, but didn't wait around for their
goroutines to be cleaned up. This caused the ipn/e2e_test to catch
pingers in its resource leak check.

This commit introduces an object, but also simplifies the semantics
around the pinger's cancel functions. They no longer need to be called
while holding the mutex.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-05-30 05:30:26 +10:00
David Crawshaw 5650f1ecf9 controlclient, ipn: adjust tests for tailscale.com keepalive change 2020-05-01 13:44:47 +10:00
David Crawshaw c10f90357e ipn/e2e_test: fix flaky logout state drain 2020-05-01 13:44:47 +10:00
David Crawshaw 2372530964 logtail/backoff: only log backoffs > 2sec
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-04-29 17:41:48 +10:00
David Crawshaw d2b7cb1e45 ipn, controlclient: add control.New parameter
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-04-29 08:06:06 +10:00
David CrawshawandDavid Crawshaw 5b95aa81ea wgengine: remove IpcSetOperation on LinkChange
This was only done occasionally, but was extremely disruptive
when done and is no longer necessary.

It used to be that when switching links, we had to immediately
generate handshakes to everyone we were communicating with to
punch a hole in any NAT we were talking through. (This ended up
not really working, because in the process we got rid of our
session keys and ended up having a futile conversation for many
seconds.)

Now we have DERP, our link change propogates to the other side
as a new list of endpoints, so they start spraying packets.
We will definitely get one thanks to DERP, which will cause us
to spray, opening any NAT we are behind.

The result is that for good connections, we don't trash session
keys and cause an interruption.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-04-10 15:07:20 +10:00
David Crawshaw 6b2e29867e controlclient: add auth key test
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-04-09 20:17:09 +10:00
David Crawshaw f8b72d2b5b cmd/tailscale: add up --authkey flag
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-04-09 20:17:09 +10:00
David Crawshaw 1747d099e9 ipn: add auth key
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-04-09 20:17:09 +10:00
David Crawshaw 3f087466f5 controlclient: add auth key
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-04-09 20:17:09 +10:00
David Crawshaw 22a0acff39 tailcfg: add auth key to RegisterRequest
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-04-09 20:17:09 +10:00
David CrawshawandDavid Crawshaw 2f8719741e controlclient: do not send duplicate hostinfo/netinfo
This should never happen, so log when it does so we can fix it.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-04-02 13:12:29 +11:00
David Crawshaw 0590ad68be controlclient, ipn: adjust tests for authURL semantic changes
The tests cheat at filling out web forms by directly POSTing to
the target. The target for authURLs has changed slightly, the base
authURL now redirects the user to the login page.

Additionally, the authURL cycle now checks the cookie is set
correctly, so we add cookie jars where necessary to pass the
cookie through.
2020-03-30 15:51:46 +11:00
David Crawshaw e60b433831 tailcfg: NetInfo.String: handle nil object without panicing
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-23 13:34:33 +11:00
David Crawshaw 13eed1e88b controlclient: remove common log on very quiet nodes
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-21 07:11:10 +11:00
David Crawshaw 6ddbcab71e logtail: rename the unused CheckLogs to DrainLogs
Its semantics has changed slightly, this will let us use it to
drive batched logging in special circumstances.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-20 13:26:33 +11:00
David Crawshaw 51a12d1307 filch: a few minor comments
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-20 13:20:45 +11:00
David Crawshaw addbdce296 wgengine, ipn: include number of active DERPs in status
Use this when making the ipn state transition from Starting to
Running. This way a network of quiet nodes with no active
handshaking will still transition to Active.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-19 17:55:16 +11:00
David Crawshaw 1ad78ce698 magicsock: reconnect to home DERP on key change
Typically the home DERP server is found and set on startup before
magicsock's SetPrivateKey can be called, so no DERP connection is
established. Make sure one is by kicking the home DERP tires in
SetPrivateKey.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-19 17:53:44 +11:00
David Crawshaw 455ba751d9 magicsock: start connection to HOME derp immediately
The code as written intended to do this, but it repeated the
comparison of derpNum and c.myDerp after c.myDerp had been
updated, so it never executed.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-19 17:36:30 +11:00
David Crawshaw 73cae4eb11 tailcfg, controlclient: standardize on wgcfg ShortString key printing
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-19 09:17:34 +11:00
David Crawshaw acd14960f8 go.mod: bump wireguard-go
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-19 09:10:13 +11:00
David Crawshaw 131541c06d derp: deflake test
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-18 16:33:25 +11:00
David Crawshaw 5a0822eefd controlclient, ipn: fix tests for new control param 2020-03-18 08:35:34 +11:00
David Crawshaw 1b2be3f1c8 controlclient: test peer keepalive directive
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-14 14:11:07 -05:00
David Crawshaw 8712164a0a controlclient: use per-peer KeepAlive signal
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-14 14:11:03 -05:00
David Crawshaw 290f83e9f6 tailcfg: fix test
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-14 11:03:00 -05:00
David Crawshaw 7a57ab1793 tailcfg: add a per-peer KeepAlive field 2020-03-14 10:56:52 -05:00
David CrawshawandDavid Crawshaw 5ad947c761 cmd/derper: set a write timeout
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-12 14:42:48 -04:00
David CrawshawandDavid Crawshaw 72dbf26f63 derp: test that client a->b and a->c relaying do not interfere
Without the recent write deadline introduction, this test fails.

They still do interfere, but the interference is now bound by
the write deadline. Many improvements are possible.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-12 14:42:48 -04:00
David CrawshawandDavid Crawshaw e838b3fb59 derp: use a write timeout when sending to clients
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-12 14:42:48 -04:00
David CrawshawandDavid Crawshaw 3df1b97ea8 derp: do not treat failure to relay as the fault of the sender
If Alice attempts to send a packet to Bob and the DERP server
encounters an error on the socket to Bob, we should not disconnect
Alice for that.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-12 14:42:48 -04:00
David CrawshawandDavid Crawshaw 43aa8595dd derp: introduce Conn interface
This lets us test with something other than a net.Conn.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-12 14:42:48 -04:00
David CrawshawandDavid Crawshaw 41ac4a79d6 net/nettest: new package with net-like testing primitives
This is a lot like wiring up a local UDP socket, read and write
deadlines work. The big difference is the Block feature, which
lets you stop the packet flow without breaking the connection.
This lets you emulate broken sockets and test timeouts actually
work.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-12 14:42:48 -04:00
David Crawshaw 57f220656c ipn: search for ErrStateNotExist with errors.Is
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-12 08:44:24 -04:00
David CrawshawandDavid Crawshaw 7ec54e0064 wgengine/magicsock: remove TODO
The TODO above derphttp.NewClient suggests it does network I/O,
but the derphttp client connects lazily and so creating one is
very cheap.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-11 12:17:37 -04:00
David Crawshaw af58cfc476 go.mod: bump wireguard-go version
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-11 11:29:14 -04:00
David CrawshawandDavid Crawshaw 5f2a17482b ipn: when enforcing defaults, set UsePacketFilter=true
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-09 14:58:20 -04:00
David Crawshaw cac68fe102 net/dnscache: do not PreferGo on macOS/iOS
With this commit my iPhone can now DERP.
2020-03-09 14:20:09 -04:00
David Crawshaw 5a1ce4adae net/dnscache: parse passed CIDR
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-09 13:11:35 -04:00
David Crawshaw e201f63230 magicsock: unskip tests that are reliable
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-08 09:29:37 -04:00
David Crawshaw f5e0407e97 ipn: exercise logout in e2e test
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-08 09:03:27 -04:00
David Crawshaw 0f73070a57 wgengine: shut down wireguard on Close
This was (presumably) missing from wgengine because the
interactions between magicsock and wireguard-go meant that the
shutdown never worked. Now those are fixed, actually shut down.

Fixes occasional flake in expanded ipn/e2e_test.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-08 09:03:27 -04:00
David Crawshaw d99498bee2 controlclient: set default TimeNow function
Panic on call to nil func found by expanded ipn/e2e_test.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-08 09:03:27 -04:00
David Crawshaw 1dee36a984 ipn: put e2e login section in its own subtest
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-08 09:03:27 -04:00
David Crawshaw 66505358c0 ipn: move e2e test skipping into subtests
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-08 09:03:07 -04:00
David Crawshaw ce7f6b2df1 wgengine: have pinger use all single-IP routes
Fixes #139

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-08 07:09:38 -04:00
David Crawshaw 5562fae9f0 ipn: use NewPrefs in e2e_test
We weren't setting UsePacketFilter, so the synthetic ping packets
used to establish a connection were never being sent.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-06 14:43:24 -05:00
David Crawshaw 551964c562 go.mod: update wireguard-go version
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-04 21:29:53 -05:00
David Crawshaw 4a7638c319 go.mod: update wireguard-go version
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-04 18:13:56 -05:00
David CrawshawandDavid 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
David CrawshawandDavid Crawshaw a65b2a0efd magicsock: add some DERP tests
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-04 12:40:33 -05:00
David CrawshawandDavid 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 CrawshawandDavid Crawshaw 9be9738f62 derphttp: add TLSConfig field
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-04 12:40:33 -05:00
David CrawshawandDavid Crawshaw caec2c7e8b magicsock: test sequence of pings
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-04 12:40:33 -05:00
David CrawshawandDavid 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 CrawshawandDavid 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 CrawshawandDavid 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
David CrawshawandDavid Crawshaw 61529ac459 controlclient, tailcfg: deliver DERP addresses in a separate field
We still include them directly in the controlclient network map
just where we have been. Client plumbing we can do later.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-02 17:16:17 -05:00
David CrawshawandDavid 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 719c974c38 go.mod: update wireguard-go version
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-03-01 12:17:10 -05:00
David CrawshawandDavid 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 CrawshawandDavid 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 1dbd1babc9 go.mod: use latest wireguard-go version
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-29 16:08:28 -05:00
David Crawshaw d5050c37a5 go.mod: use latest wireguard-go version 2020-02-29 11:26:44 -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
David Crawshaw 8aa2090919 go.mod: roll forward wireguard-go
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-28 22:12:05 -05:00
David Crawshaw d133339216 ipn: always guard LocalBackend.prefs with mu
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-28 21:54:22 -05:00
David Crawshaw cdc10b74f1 ipn: always guard LocalBackend.endpoints with mu
For #112

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-28 15:13:01 -05:00
David Crawshaw 3425d8d84f ipn: always guard LocalBackend.engineStatus with mu
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-28 14:58:52 -05:00
David Crawshaw e7cdc11654 ipn: always guard LocalBackend.netMapCache with mu
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-28 14:39:36 -05: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
David Crawshaw 06bf0d980e go.mod: bump wireguard-go version
For #110
2020-02-28 06:21:07 -05:00
David Crawshaw 4e3ff4b63b controlclient: allow prefixed endpoints in tests 2020-02-27 16:52:14 -05:00
David Crawshaw 6879581891 controlclient: adjust user expiry test
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-26 09:44:42 -05:00
David Crawshaw 6d2ac01464 go.mod: bump wireguard-go version
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-25 17:03:20 -05: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
David CrawshawandDavid 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 CrawshawandDavid 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
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
David Crawshaw 8994a59e20 go.mod: update wireguard-go version
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-23 13:49:21 -05:00
David Crawshaw ebc70acac7 go.mod: update wireguard-go version 2020-02-21 21:30:00 -05: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
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 431929c09a go.mod: fix wireguard-go version 2020-02-19 11:48: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
David Crawshaw a23a0d9c9f tailcfg: add RegisterRequest.Copy
Add some docs while I'm here.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-18 06:45:56 -05:00
David Crawshaw aa73b7972c Merge branch 'master' of github.com:tailscale/tailscale into HEAD 2020-02-13 12:16:01 -05:00
David Crawshaw 3bf9d53d40 Merge branch 'master' of github.com:tailscale/tailscale into HEAD 2020-02-13 10:40:05 -05:00
David Crawshaw cbfef0c8b7 Merge branch 'master' of github.com:tailscale/tailscale into HEAD 2020-02-13 10:12:06 -05:00
David CrawshawandDavid Crawshaw e180bd67e6 controlclient: handle nil Logf option 2020-02-11 15:20:45 -05:00
David Crawshaw 2b947b3b40 controlclient: handle nil Logf option 2020-02-11 15:08:07 -05:00
David CrawshawandDavid Crawshaw 33dfb8999e controlclient, ipn: update tests for key pointer change
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
2020-02-11 04:55:07 -05:00
David CrawshawandGitHub d539a950ca README.md: add content 2020-02-10 14:56:04 -05:00