81 Commits

Author SHA1 Message Date
Brad Fitzpatrick
311dd3839d wgengine/magicsock: replace peers slice with peersByID map; add Upsert/RemovePeer
Replace Conn.peers (sorted views.Slice) with peersByID, a
map[tailcfg.NodeID]tailcfg.NodeView. The only caller that needed
the sorted slice (the disco message receive path's binary search)
becomes a single map lookup. Drop nodesEqual.

Add Conn.UpsertPeer / Conn.RemovePeer for O(1) single-peer endpoint
work. RemovePeer also performs a targeted single-disco-key cleanup
(previously that scan was O(discoInfo)).

Extract the shared per-peer upsert body as upsertPeerLocked; still
used by SetNetworkMap's bulk path. SetNetworkMap is documented as
the bulk / initial / self-change path; UpsertPeer and RemovePeer
are preferred for single-peer changes.

Make the relay server set update O(1) per peer: add serverUpsertCh
/ serverRemoveCh to relayManager with matching run-loop handlers.
UpsertPeer / RemovePeer evaluate the per-peer relay predicate
locally and dispatch upsert or remove. The full-rebuild
updateRelayServersSet stays for the initial netmap, filter
changes, and fallback.

Move the hasPeerRelayServers atomic from Conn onto relayManager,
next to the serversByNodeKey map it summarizes. The run loop is
now the single writer and needs no back-pointer to Conn;
endpoint's two hot-path readers take one extra hop to
de.c.relayManager.hasPeerRelayServers but the cost is the same
atomic load.

No callers use UpsertPeer/RemovePeer yet; a subsequent change will
plumb per-peer add/remove through the incremental map update path.

Updates #12542

Change-Id: If6a3442fe29ccbd77890ea61b754a4d1ad6ef225
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-04-22 15:07:11 -07:00
Alex Valiushko
d3ba1480f5
magicsock: invalidate endpoint on trust timeout (#19415)
Endpoint's best address was cleared on trustBestAddrUntil expiry
only if it was a udprelay connection. This generalizes invalidation
to also cover direct UDP.

Trust deadline is checked in two cases:

On disco ping timeout from the endpoint's best address.
Traffic goes DERP-only, heartbeats to the old address stop.
The discovery pings are still in flight, handled by the following.

On disco ping success from an alternative. BestAddr switches to the
working path, trust refreshed, eager discovery stops. The still
in flight pongs are handled by betterAddr().

Updates #19407


Change-Id: Ic41ed18edb4a6e4350a2d49271ba01566a6a6964

Signed-off-by: Alex Valiushko <alexvaliushko@tailscale.com>
2026-04-15 19:22:07 -07:00
Claus Lensbøl
c76113ac75
wgengine/magicsock: send out disco keys over TSMP periodically (#19212)
Instead of sending out disco keys via TSMP once, send them out in
intervals of 60+ seconds. The trigger is still callmemaaybe and the keys
will not be send if no direct connection needs to be established.

This fixes a case where a node can have stale keys but have communicated
with the other peer before, leading to an infinite DERP state.

Updates #12639

Signed-off-by: Claus Lensbøl <claus@tailscale.com>
2026-04-01 17:20:03 -04:00
Claus Lensbøl
85bb5f84a5
wgengine/magicsock,control/controlclient: do not overwrite discokey with old key (#18606)
When a client starts up without being able to connect to control, it
sends its discoKey to other nodes it wants to communicate with over
TSMP. This disco key will be a newer key than the one control knows
about.

If the client that can connect to control gets a full netmap, ensure
that the disco key for the node not connected to control is not
overwritten with the stale key control knows about.

This is implemented through keeping track of mapSession and use that for
the discokey injection if it is available. This ensures that we are not
constantly resetting the wireguard connection when getting the wrong
keys from control.

This is implemented as:
 - If the key is received via TSMP:
   - Set lastSeen for the peer to now()
   - Set online for the peer to false
 - When processing new keys, only accept keys where either:
   - Peer is online
   - lastSeen is newer than existing last seen

If mapSession is not available, as in we are not yet connected to
control, punt down the disco key injection to magicsock.

Ideally, we will want to have mapSession be long lived at some point in
the near future so we only need to inject keys in one location and then
also use that for testing and loading the cache, but that is a yak for
another PR.

Updates #12639

Signed-off-by: Claus Lensbøl <claus@tailscale.com>
2026-03-20 08:56:27 -04:00
Brad Fitzpatrick
2810f0c6f1 all: fix typos in comments
Fix its/it's, who's/whose, wether/whether, missing apostrophes
in contractions, and other misspellings across the codebase.

Updates #cleanup

Change-Id: I20453b81a7aceaa14ea2a551abba08a2e7f0a1d8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-03-05 13:52:01 -08:00
Will Norris
3ec5be3f51 all: remove AUTHORS file and references to it
This file was never truly necessary and has never actually been used in
the history of Tailscale's open source releases.

A Brief History of AUTHORS files
---

The AUTHORS file was a pattern developed at Google, originally for
Chromium, then adopted by Go and a bunch of other projects. The problem
was that Chromium originally had a copyright line only recognizing
Google as the copyright holder. Because Google (and most open source
projects) do not require copyright assignemnt for contributions, each
contributor maintains their copyright. Some large corporate contributors
then tried to add their own name to the copyright line in the LICENSE
file or in file headers. This quickly becomes unwieldy, and puts a
tremendous burden on anyone building on top of Chromium, since the
license requires that they keep all copyright lines intact.

The compromise was to create an AUTHORS file that would list all of the
copyright holders. The LICENSE file and source file headers would then
include that list by reference, listing the copyright holder as "The
Chromium Authors".

This also become cumbersome to simply keep the file up to date with a
high rate of new contributors. Plus it's not always obvious who the
copyright holder is. Sometimes it is the individual making the
contribution, but many times it may be their employer. There is no way
for the proejct maintainer to know.

Eventually, Google changed their policy to no longer recommend trying to
keep the AUTHORS file up to date proactively, and instead to only add to
it when requested: https://opensource.google/docs/releasing/authors.
They are also clear that:

> Adding contributors to the AUTHORS file is entirely within the
> project's discretion and has no implications for copyright ownership.

It was primarily added to appease a small number of large contributors
that insisted that they be recognized as copyright holders (which was
entirely their right to do). But it's not truly necessary, and not even
the most accurate way of identifying contributors and/or copyright
holders.

In practice, we've never added anyone to our AUTHORS file. It only lists
Tailscale, so it's not really serving any purpose. It also causes
confusion because Tailscalars put the "Tailscale Inc & AUTHORS" header
in other open source repos which don't actually have an AUTHORS file, so
it's ambiguous what that means.

Instead, we just acknowledge that the contributors to Tailscale (whoever
they are) are copyright holders for their individual contributions. We
also have the benefit of using the DCO (developercertificate.org) which
provides some additional certification of their right to make the
contribution.

The source file changes were purely mechanical with:

    git ls-files | xargs sed -i -e 's/\(Tailscale Inc &\) AUTHORS/\1 contributors/g'

Updates #cleanup

Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
2026-01-23 15:49:45 -08:00
Claus Lensbøl
151644f647
wgengine: send disco key via TSMP on first contact (#18215)
When we have not yet communicated with a peer, send a
TSMPDiscoAdvertisement to let the peer know of our disco key. This is in
most cases redundant, but will allow us to set up direct connections
when the client cannot access control.

Some parts taken from: #18073

Updates #12639

Signed-off-by: Claus Lensbøl <claus@tailscale.com>
2026-01-22 14:50:24 -05:00
James Tucker
c09c95ef67 types/key,wgengine/magicsock,control/controlclient,ipn: add debug disco key rotation
Adds the ability to rotate discovery keys on running clients, needed for
testing upcoming disco key distribution changes.

Introduces key.DiscoKey, an atomic container for a disco private key,
public key, and the public key's ShortString, replacing the prior
separate atomic fields.

magicsock.Conn has a new RotateDiscoKey method, and access to this is
provided via localapi and a CLI debug command.

Note that this implementation is primarily for testing as it stands, and
regular use should likely introduce an additional mechanism that allows
the old key to be used for some time, to provide a seamless key rotation
rather than one that invalidates all sessions.

Updates tailscale/corp#34037

Signed-off-by: James Tucker <james@tailscale.com>
2025-11-18 12:16:15 -08:00
Brad Fitzpatrick
99b06eac49 syncs: add Mutex/RWMutex alias/wrappers for future mutex debugging
Updates #17852

Change-Id: I477340fb8e40686870e981ade11cd61597c34a20
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-11-16 19:13:59 -08:00
Joe Tsai
e75f13bd93
net/connstats: prepare to remove package (#17554)
The connstats package was an unnecessary layer of indirection.
It was seperated out of wgengine/netlog so that net/tstun and
wgengine/magicsock wouldn't need a depenedency on the concrete
implementation of network flow logging.

Instead, we simply register a callback for counting connections.
This PR does the bare minimum work to prepare tstun and magicsock
to only care about that callback.

A future PR will delete connstats and merge it into netlog.

Updates tailscale/corp#33352

Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2025-10-15 14:57:32 -07:00
Jordan Whited
4543ea5c8a
wgengine/magicsock: start peer relay path discovery sooner (#17485)
This commit also shuffles the hasPeerRelayServers atomic load
to happen sooner, reducing the cost for clients with no peer relay
servers.

Updates tailscale/corp#33099

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-10-08 09:53:32 -07:00
Jordan Whited
3aa8b6d683
wgengine/magicsock: remove misleading unexpected log message (#17445)
Switching to a Geneve-encapsulated (peer relay) path in
endpoint.handlePongConnLocked is expected around port rebinds, which end
up clearing endpoint.bestAddr.

Fixes tailscale/corp#33036

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-10-04 15:05:41 -07:00
Jordan Whited
fb9d9ba86e
wgengine/magicsock: add TS_DEBUG_NEVER_DIRECT_UDP debug knob (#17094)
Updates tailscale/corp#30903

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-09-10 16:48:40 -07:00
James Tucker
d42f0b6a21 util/ringbuffer: rename to ringlog
I need a ringbuffer in the more traditional sense, one that has a notion
of item removal as well as tail loss on overrun. This implementation is
really a clearable log window, and is used as such where it is used.

Updates #cleanup
Updates tailscale/corp#31762

Signed-off-by: James Tucker <james@tailscale.com>
2025-08-28 15:41:07 -07:00
Jordan Whited
575664b263
wgengine/magicsock: make endpoint.discoPing peer relay aware (#16946)
Updates tailscale/corp#30333

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-08-26 09:22:36 -07:00
Jordan Whited
9403ba8c69
wgengine/magicsock: trigger peer relay path discovery on CallMeMaybe RX (#16929)
Updates tailscale/corp#30333

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-08-25 09:40:15 -07:00
Jordan Whited
16bc0a5558
net/{batching,packet},wgengine/magicsock: export batchingConn (#16848)
For eventual use by net/udprelay.Server.

Updates tailscale/corp#31164

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-08-13 13:13:11 -07:00
Jordan Whited
1677fb1905
wgengine/magicsock,all: allocate peer relay over disco instead of PeerAPI (#16603)
Updates tailscale/corp#30583
Updates tailscale/corp#30534
Updates tailscale/corp#30557

Signed-off-by: Dylan Bargatze <dylan@tailscale.com>
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Co-authored-by: Dylan Bargatze <dylan@tailscale.com>
2025-07-21 10:02:37 -07:00
Jordan Whited
36aeacb297
wgengine/magicsock: add peer relay metrics (#16582)
Updates tailscale/corp#30040

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-07-16 14:34:05 -07:00
Jordan Whited
b63f8a457d
wgengine/magicsock: prioritize trusted peer relay paths over untrusted (#16559)
A trusted peer relay path is always better than an untrusted direct or
peer relay path.

Updates tailscale/corp#30412

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-07-14 15:09:31 -07:00
Jordan Whited
fc5050048e
wgengine/magicsock: don't acquire Conn.mu in udpRelayEndpointReady (#16557)
udpRelayEndpointReady used to write into the peerMap, which required
holding Conn.mu, but this changed in f9e7131.

Updates #cleanup

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-07-14 10:42:56 -07:00
Jordan Whited
f9bfd8118a
wgengine/magicsock: resolve epAddr collisions across peer relay conns (#16526)
Updates tailscale/corp#30042
Updates tailscale/corp#29422

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-07-10 12:41:14 -07:00
Jordan Whited
ae8641735d
cmd/tailscale/cli,ipn/ipnstate,wgengine/magicsock: label peer-relay (#16510)
Updates tailscale/corp#30033

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-07-09 15:17:51 -07:00
Jordan Whited
3b32cc7586
wgengine/magicsock: simplify Geneve-encapsulated disco.Ping handling (#16448)
Just make [relayManager] always handle it, there's no benefit to
checking bestAddr's.

Also, remove passing of disco.Pong to [relayManager] in
endpoint.handlePongConnLocked(), which is redundant with the callsite in
Conn.handleDiscoMessage(). Conn.handleDiscoMessage() already passes to
[relayManager] if the txID us not known to any [*endpoint].

Updates tailscale/corp#27502

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-07-07 09:38:10 -07:00
Jordan Whited
f9e7131772
wgengine/magicsock: make lazyEndpoint load bearing for UDP relay (#16435)
Cryptokey Routing identification is now required to set an [epAddr] into
the peerMap for Geneve-encapsulated [epAddr]s.

Updates tailscale/corp#27502
Updates tailscale/corp#29422
Updates tailscale/corp#30042

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-07-02 13:27:30 -07:00
Jordan Whited
47e77565c6
wgengine/magicsock: avoid handshaking relay endpoints that are trusted (#16412)
Changes to our src/address family can trigger blackholes.

This commit also adds a missing set of trustBestAddrUntil when setting
a UDP relay path as bestAddr.

Updates tailscale/corp#27502

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-06-30 12:12:57 -07:00
Jordan Whited
3dc694b4f1
wgengine/magicsock: clear UDP relay bestAddr's on disco ping timeout (#16410)
Otherwise we can end up mirroring packets to them forever. We may
eventually want to relax this to direct paths as well, but start with
UDP relay paths, which have a higher chance of becoming untrusted and
never working again, to be conservative.

Updates tailscale/corp#27502

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-06-27 19:11:59 -07:00
Jordan Whited
0a64e86a0d
wgengine/magicsock: move UDP relay path discovery to heartbeat() (#16407)
This was previously hooked around direct UDP path discovery /
CallMeMaybe transmission, and related conditions. Now it is subject to
relay-specific considerations.

Updates tailscale/corp#27502

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-06-27 13:56:55 -07:00
Jordan Whited
61958f531c
wgengine/magicsock: set conn field in relayHandshakeDiscoMsgEvent (#16348)
Updates tailscale/corp#27502

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-06-21 19:09:36 -07:00
Jordan Whited
6a93b17c8c
types/netmap,wgengine/magicsock: propagate CapVer to magicsock.endpoint (#16244)
This enables us to mark nodes as relay capable or not. We don't actually
do that yet, as we haven't established a relay CapVer.

Updates tailscale/corp#27502

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-06-10 17:31:14 -07:00
Jordan Whited
67b1693c13
wgengine/magicsock: enable setting relay epAddr's as bestAddr (#16229)
relayManager can now hand endpoint a relay epAddr for it to consider
as bestAddr.

endpoint and Conn disco ping/pong handling are now VNI-aware.

Updates tailscale/corp#27502
Updates tailscale/corp#29422

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-06-09 13:17:14 -07:00
Jordan Whited
66ae8737f4
wgengine/magicsock: make endpoint.bestAddr Geneve-aware (#16195)
This commit adds a new type to magicsock, epAddr, which largely ends up
replacing netip.AddrPort in packet I/O paths throughout, enabling
Geneve encapsulation over UDP awareness.

The conn.ReceiveFunc for UDP has been revamped to fix and more clearly
distinguish the different classes of packets we expect to receive: naked
STUN binding messages, naked disco, naked WireGuard, Geneve-encapsulated
disco, and Geneve-encapsulated WireGuard.

Prior to this commit, STUN matching logic in the RX path could swallow
a naked WireGuard packet if the keypair index, which is randomly
generated, happened to overlap with a subset of the STUN magic cookie.

Updates tailscale/corp#27502
Updates tailscale/corp#29326

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-06-06 09:46:29 -07:00
Jordan Whited
5f35143d83
go.mod,wgengine/magicsock: update wireguard-go (#16148)
Our conn.Bind implementation is updated to make Send() offset-aware for
future VXLAN/Geneve encapsulation support.

Updates tailscale/corp#27502

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-06-02 13:22:28 -07:00
Jordan Whited
ffc8ec289b
wgengine/magicsock: implement relayManager endpoint probing (#16029)
relayManager is responsible for disco ping/pong probing of relay
endpoints once a handshake is complete.

Future work will enable relayManager to set a relay endpoint as the best
UDP path on an endpoint if appropriate.

Updates tailscale/corp#27502

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-05-28 10:45:59 -07:00
Jordan Whited
70b6e8ca98
wgengine/magicsock: fix outdated heartbeat comment (#16023)
heartbeatInterval is currently 3s.

Updates #cleanup

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-05-20 08:46:37 -07:00
Jordan Whited
3cc80cce6a
wgengine/magicsock: introduce virtualNetworkID type (#16021)
This type improves code clarity and reduces the chance of heap alloc as
we pass it as a non-pointer. VNI being a 3-byte value enables us to
track set vs unset via the reserved/unused byte.

Updates tailscale/corp#27502

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-05-19 19:14:08 -07:00
Jordan Whited
87a4f17883
wgengine/magicsock: fix pong handling 'EndpointChange' reporting (#16018)
Updates #cleanup

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-05-19 11:42:13 -07:00
Jordan Whited
469fabd8de
wgengine/magicsock: add missing logf arg (#15995)
Also, add the short version of the node key in parens to match existing
patterns.

Updates #cleanup

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-05-16 16:12:59 -07:00
Jordan Whited
6de4a021bb
wgengine/magicsock: implement relayManager handshaking (#15977)
CallMeMaybeVia reception and endpoint allocation have been collapsed to
a single event channel. discoInfo caching for active relay handshakes
is now implemented.

Updates tailscale/corp#27502

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-05-16 13:51:40 -07:00
Jordan Whited
0f4f808e70
wgengine/magicsock: re-shape relayManager to use an event loop (#15935)
The event loop removes the need for growing locking complexities and
synchronization. Now we simply use channels. The event loop only runs
while there is active work to do.

relayManager remains no-op inside magicsock for the time being.
endpoints are never 'relayCapable' and therefore endpoint & Conn will
not feed CallMeMaybeVia or allocation events into it.

A number of relayManager events remain unimplemented, e.g.
CallMeMaybeVia reception and relay handshaking.

Updates tailscale/corp#27502

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-05-09 14:50:01 -07:00
Jordan Whited
61635f8670
wgengine/magicsock: support Geneve-encap'd Disco transmission (#15811)
Updates tailscale/corp#27502

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-04-28 15:55:49 -07:00
Brad Fitzpatrick
75a03fc719 wgengine/magicsock: use learned DERP route as send path of last resort
If we get a packet in over some DERP and don't otherwise know how to
reply (no known DERP home or UDP endpoint), this makes us use the
DERP connection on which we received the packet to reply. This will
almost always be our own home DERP region.

This is particularly useful for large one-way nodes (such as
hello.ts.net) that don't actively reach out to other nodes, so don't
need to be told the DERP home of peers. They can instead learn the
DERP home upon getting the first connection.

This can also help nodes from a slow or misbehaving control plane.

Updates tailscale/corp#26438

Change-Id: I6241ec92828bf45982e0eb83ad5c7404df5968bc
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-03-07 05:37:24 -08:00
Brad Fitzpatrick
2fc4455e6d all: add Node.HomeDERP int, phase out "127.3.3.40:$region" hack [capver 111]
This deprecates the old "DERP string" packing a DERP region ID into an
IP:port of 127.3.3.40:$REGION_ID and just uses an integer, like
PeerChange.DERPRegion does.

We still support servers sending the old form; they're converted to
the new form internally right when they're read off the network.

Updates #14636

Change-Id: I9427ec071f02a2c6d75ccb0fcbf0ecff9f19f26f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-01-14 12:27:14 -08:00
Brad Fitzpatrick
1e2e319e7d util/slicesx: add MapKeys and MapValues from golang.org/x/exp/maps
Importing the ~deprecated golang.org/x/exp/maps as "xmaps" to not
shadow the std "maps" was getting ugly.

And using slices.Collect on an iterator is verbose & allocates more.

So copy (x)maps.Keys+Values into our slicesx package instead.

Updates #cleanup
Updates #12912
Updates #14514 (pulled out of that change)

Change-Id: I5e68d12729934de93cf4a9cd87c367645f86123a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-01-03 10:48:31 -08:00
Brad Fitzpatrick
4e0fc037e6 all: use iterators over slice views more
This gets close to all of the remaining ones.

Updates #12912

Change-Id: I9c672bbed2654a6c5cab31e0cbece6c107d8c6fa
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-11-11 13:22:34 -08:00
Anton Tolchanov
532b26145a wgengine/magicsock: exclude disco from throughput metrics
The user-facing metrics are intended to track data transmitted at
the overlay network level.

Updates tailscale/corp#22075

Signed-off-by: Anton Tolchanov <anton@tailscale.com>
2024-10-31 08:01:19 +00:00
Anton Tolchanov
11e96760ff wgengine/magicsock: fix stats packet counter on derp egress
Updates tailscale/corp#22075

Signed-off-by: Anton Tolchanov <anton@tailscale.com>
2024-10-29 15:07:45 +00:00
Kristoffer Dalby
e0d711c478 {net/connstats,wgengine/magicsock}: fix packet counting in connstats
connstats currently increments the packet counter whenever it is called
to store a length of data, however when udp batch sending was introduced
we pass the length for a series of packages, and it is only incremented
ones, making it count wrongly if we are on a platform supporting udp
batches.

Updates tailscale/corp#22075

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
2024-10-14 14:17:56 +02:00
Kristoffer Dalby
40c991f6b8 wgengine: instrument with usermetrics
Updates tailscale/corp#22075

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
2024-10-14 11:34:31 +02:00
tomholford
16bb541adb wgengine/magicsock: replace deprecated poly1305 (#13184)
Signed-off-by: tomholford <tomholford@users.noreply.github.com>
2024-08-19 14:20:58 -07:00