summaryrefslogtreecommitdiffhomepage
AgeCommit message (Collapse)AuthorFilesLines
2025-12-09.github/workflows: try using a DevDrive on Windowsbradfitz/devdriveBrad Fitzpatrick1-0/+8
At least locally on my Windows laptop, this makes the build take a quarter of the time. Updates tailscale/corp#28679 Change-Id: I8b5fbbfcb8b3bae864d0eca31ed5955e1e75b945 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-12-09.github: add cigocacher release workflowTom Proctor1-0/+73
To save rebuilding cigocacher on each CI job, build it on-demand, and publish a release similar to how we publish releases for tool/go to consume. Once the first release is done, we can add a new tool/cigocacher script that pins to a specific release for each branch to download. Updates tailscale/corp#10808 Change-Id: I7694b2c2240020ba2335eb467522cdd029469b6c Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
2025-12-09cmd/tailscale/cli: stabilise the output of `tailscale lock status --json`Alex Chan6-21/+441
This patch stabilises the JSON output, and improves it in the following ways: * The AUM hash in Head uses the base32-encoded form of an AUM hash, consistent with how it's presented elsewhere * TrustedKeys are the same format as the keys as `tailnet lock log --json` * SigKind, Pubkey and KeyID are all presented consistently with other JSON output in NodeKeySignature * FilteredPeers don't have a NodeKeySignature, because it will always be empty For reference, here's the JSON output from the CLI prior to this change: ```json { "Enabled": true, "Head": [ 196, 69, 63, 243, 213, 133, 123, 46, 183, 203, 143, 34, 184, 85, 80, 1, 221, 92, 49, 213, 93, 106, 5, 206, 176, 250, 58, 165, 155, 136, 11, 13 ], "PublicKey": "nlpub:0f99af5c02216193963ce9304bb4ca418846eddebe237f37a6de1c59097ed0b8", "NodeKey": "nodekey:8abfe98b38151748919f6e346ad16436201c3ecd453b01e9d6d3a38e1826000d", "NodeKeySigned": true, "NodeKeySignature": { "SigKind": 1, "Pubkey": "bnCKv+mLOBUXSJGfbjRq0WQ2IBw+zUU7AenW06OOGCYADQ==", "KeyID": "D5mvXAIhYZOWPOkwS7TKQYhG7d6+I383pt4cWQl+0Lg=", "Signature": "4DPW4v6MyLLwQ8AMDm27BVDGABjeC9gg1EfqRdKgzVXi/mJDwY9PTAoX0+0WTRs5SUksWjY0u1CLxq5xgjFGBA==", "Nested": null, "WrappingPubkey": "D5mvXAIhYZOWPOkwS7TKQYhG7d6+I383pt4cWQl+0Lg=" }, "TrustedKeys": [ { "Key": "nlpub:0f99af5c02216193963ce9304bb4ca418846eddebe237f37a6de1c59097ed0b8", "Metadata": null, "Votes": 1 }, { "Key": "nlpub:de2254c040e728140d92bc967d51284e9daea103a28a97a215694c5bda2128b8", "Metadata": null, "Votes": 1 } ], "VisiblePeers": [ { "Name": "signing2.taila62b.unknown.c.ts.net.", "ID": 7525920332164264, "StableID": "nRX6TbAWm121DEVEL", "TailscaleIPs": [ "100.110.67.20", "fd7a:115c:a1e0::9c01:4314" ], "NodeKey": "nodekey:10bf4a5c168051d700a29123cd81568377849da458abef4b328794ca9cae4313", "NodeKeySignature": { "SigKind": 1, "Pubkey": "bnAQv0pcFoBR1wCikSPNgVaDd4SdpFir70syh5TKnK5DEw==", "KeyID": "D5mvXAIhYZOWPOkwS7TKQYhG7d6+I383pt4cWQl+0Lg=", "Signature": "h9fhwHiNdkTqOGVQNdW6AVFoio6MFaFobPiK9ydywgmtYxcExJ38b76Tabdc56aNLxf8IfCaRw2VYPcQG2J/AA==", "Nested": null, "WrappingPubkey": "3iJUwEDnKBQNkryWfVEoTp2uoQOiipeiFWlMW9ohKLg=" } } ], "FilteredPeers": [ { "Name": "node3.taila62b.unknown.c.ts.net.", "ID": 5200614049042386, "StableID": "n3jAr7KNch11DEVEL", "TailscaleIPs": [ "100.95.29.124", "fd7a:115c:a1e0::f901:1d7c" ], "NodeKey": "nodekey:454d2c8602c10574c5ec3a6790f159714802012b7b8bb8d2ab47d637f9df1d7b", "NodeKeySignature": { "SigKind": 0, "Pubkey": null, "KeyID": null, "Signature": null, "Nested": null, "WrappingPubkey": null } } ], "StateID": 16885615198276932820 } ``` Updates https://github.com/tailscale/corp/issues/22355 Updates https://github.com/tailscale/tailscale/issues/17619 Signed-off-by: Alex Chan <alexc@tailscale.com> Change-Id: I65b58ff4520033e6b70fc3b1ba7fc91c1f70a960
2025-12-08Revert "ipn/ipnlocal: shut down old control client synchronously on reset"Nick Khyl1-10/+29
It appears (*controlclient.Auto).Shutdown() can still deadlock when called with b.mu held, and therefore the changes in #18127 are unsafe. This reverts #18127 until we figure out what causes it. This reverts commit d199ecac80083e64d32baf3b473c67b11a6e6936. Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-12-08scripts/installer.sh: add SteamOS handling (#18159)Erisa A1-0/+5
Fixes #12943 Signed-off-by: Erisa A <erisa@tailscale.com>
2025-12-08tka: add some more tests for Bootstrap()Alex Chan1-0/+60
This improves our test coverage of the Bootstrap() method, especially around catching AUMs that shouldn't pass validation. Updates #cleanup Change-Id: Idc61fcbc6daaa98c36d20ec61e45ce48771b85de Signed-off-by: Alex Chan <alexc@tailscale.com>
2025-12-08cmd/k8s-operator: warn if users attempt to expose a headless Service (#18140)Irbe Krumina2-86/+88
Previously, if users attempted to expose a headless Service to tailnet, this just silently did not work. This PR makes the operator throw a warning event + update Service's status with an error message. Updates #18139 Signed-off-by: Irbe Krumina <irbe@tailscale.com>
2025-12-08cmd/k8s-operator: don't log errors on not found objects. (#18142)Irbe Krumina1-3/+10
The event queue gets deleted events, which means that sometimes the object that should be reconciled no longer exists. Don't log user facing errors if that is the case. Updates #18141 Signed-off-by: Irbe Krumina <irbe@tailscale.com>
2025-12-05client/systray: change systray to start after graphical.target (#18138)Claus Lensbøl1-1/+1
The service was starting after systemd itself, and while this surprisingly worked for some situations, it broke for others. Change it to start after a GUI has been initialized. Updates #17656 Signed-off-by: Claus Lensbøl <claus@tailscale.com>
2025-12-05ipn/ipnlocal: add peer API endpoints to Hostinfo on initial client creation ↵James 'zofrex' Sanderson2-10/+102
(#17851) Previously we only set this when it updated, which was fine for the first call to Start(), but after that point future updates would be skipped if nothing had changed. If Start() was called again, it would wipe the peer API endpoints and they wouldn't get added back again, breaking exit nodes (and anything else requiring peer API to be advertised). Updates tailscale/corp#27173 Signed-off-by: James Sanderson <jsanderson@tailscale.com>
2025-12-04cmd/tailscale,ipn: add Unix socket support for servePeter A.8-3/+482
Based on PR #16700 by @lox, adapted to current codebase. Adds support for proxying HTTP requests to Unix domain sockets via tailscale serve unix:/path/to/socket, enabling exposure of services like Docker, containerd, PHP-FPM over Tailscale without TCP bridging. The implementation includes reasonable protections against exposure of tailscaled's own socket. Adaptations from original PR: - Use net.Dialer.DialContext instead of net.Dial for context propagation - Use http.Transport with Protocols API (current h2c approach, not http2.Transport) - Resolve conflicts with hasScheme variable in ExpandProxyTargetValue Updates #9771 Signed-off-by: Peter A. <ink.splatters@pm.me> Co-authored-by: Lachlan Donald <lachlan@ljd.cc>
2025-12-04ipn/ipnlocal: fix LocalBackend deadlock when packet arrives during profile ↵Nick Khyl1-10/+10
switch (#18126) If a packet arrives while WireGuard is being reconfigured with b.mu held, such as during a profile switch, calling back into (*LocalBackend).GetPeerAPIPort from (*Wrapper).filterPacketInboundFromWireGuard may deadlock when it tries to acquire b.mu. This occurs because a peer cannot be removed while an inbound packet is being processed. The reconfig and profile switch wait for (*Peer).RoutineSequentialReceiver to return, but it never finishes because GetPeerAPIPort needs b.mu, which the waiting goroutine already holds. In this PR, we make peerAPIPorts a new syncs.AtomicValue field that is written with b.mu held but can be read by GetPeerAPIPort without holding the mutex, which fixes the deadlock. There might be other long-term ways to address the issue, such as moving peer API listeners from LocalBackend to nodeBackend so they can be accessed without holding b.mu, but these changes are too large and risky at this stage in the v1.92 release cycle. Updates #18124 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-12-03ipn/ipnlocal: shut down old control client synchronously on resetNick Khyl1-29/+10
Previously, callers of (*LocalBackend).resetControlClientLocked were supposed to call Shutdown on the returned controlclient.Client after releasing b.mu. In #17804, we started calling Shutdown while holding b.mu, which caused deadlocks during profile switches due to the (*ExecQueue).RunSync implementation. We first patched this in #18053 by calling Shutdown in a new goroutine, which avoided the deadlocks but made TestStateMachine flaky because the shutdown order was no longer guaranteed. In #18070, we updated (*ExecQueue).RunSync to allow shutting down the queue without waiting for RunSync to return. With that change, shutting down the control client while holding b.mu became safe. Therefore, this PR updates (*LocalBackend).resetControlClientLocked to shut down the old client synchronously during the reset, instead of returning it and shifting that responsibility to the callers. This fixes the flaky tests and simplifies the code. Fixes #18052 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-12-03go.toolchain.rev: update to Go 1.25.5 (#18123)Andrew Lytvynov4-4/+4
Updates #18122 Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2025-12-03net/udprelay: bind multiple sockets per af on LinuxJordan Whited3-58/+165
This commit uses SO_REUSEPORT (when supported) to bind multiple sockets per address family. Increasing the number of sockets can increase aggregate throughput when serving many peer relay client flows. Benchmarks show 3x improvement in max aggregate bitrate in some environments. Updates tailscale/corp#34745 Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-12-03go.mod: bump the version of setecAlex Chan6-11/+10
Updates https://github.com/tailscale/corp/issues/34813 Change-Id: I926f1bad5bf143d82ddb36f51f70deb24fa11e71 Signed-off-by: Alex Chan <alexc@tailscale.com>
2025-12-02.github: make cigocacher script more robustTom Proctor1-7/+36
We got a flake in https://github.com/tailscale/tailscale/actions/runs/19867229792/job/56933249360 but it's not obvious to me where it failed. Make it more robust and print out more useful error messages for next time. Updates tailscale/corp#10808 Change-Id: I9ca08ea1103b9ad968c9cc0c42a493981ea62435 Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
2025-12-02wgengine: fix TSMP/ICMP callback leakBrad Fitzpatrick1-0/+2
Fixes #18112 Change-Id: I85d5c482b01673799d51faeb6cb0579903597502 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-12-02tsnet: enable node registration via federated identityGesa Stupperich7-47/+522
Updates: tailscale.com/corp#34148 Signed-off-by: Gesa Stupperich <gesa@tailscale.com>
2025-12-02cmd/netlogfmt: allow empty --resolve-addrs flag (#18103)Joe Tsai1-0/+1
Updates tailscale/corp#33352 Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2025-12-02scripts/installer: add TAILSCALE_VERSION environment variable (#18014)Raj Singh2-12/+88
Add support for pinning specific Tailscale versions during installation via the TAILSCALE_VERSION environment variable. Example usage: curl -fsSL https://tailscale.com/install.sh | TAILSCALE_VERSION=1.88.4 sh Fixes #17776 Signed-off-by: Raj Singh <raj@tailscale.com>
2025-12-02tool: bump binaryen wasm optimiser version 111 -> 125Tom Proctor1-1/+1
111 is 3 years old, and there have been a lot of speed improvements since then. We run wasm-opt twice as part of the CI wasm job, and it currently takes about 3 minutes each time. With 125, it takes ~40 seconds, a 4.5x speed-up. Updates #cleanup Change-Id: I671ae6cefa3997a23cdcab6871896b6b03e83a4f Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
2025-12-02licenses: update license noticesLicense Updater4-40/+43
Signed-off-by: License Updater <noreply+license-updater@tailscale.com>
2025-12-02cleanup: fix typos across multiple filesNaasir5-5/+5
Does not affect code. Updates #cleanup Signed-off-by: Naasir <yoursdeveloper@protonmail.com>
2025-12-02.github,cmd/cigocacher: use cigocacher for windowsTom Proctor7-56/+372
Implements a new disk put function for cigocacher that does not cause locking issues on Windows when there are multiple processes reading and writing the same files concurrently. Integrates cigocacher into test.yml for Windows where we are running on larger runners that support connecting to private Azure vnet resources where cigocached is hosted. Updates tailscale/corp#10808 Change-Id: I0d0e9b670e49e0f9abf01ff3d605cd660dd85ebb Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
2025-12-02.github: only save cache on mainTom Proctor1-58/+95
The cache artifacts from a full run of test.yml are 14GB. Only save artifacts from the main branch to ensure we don't thrash too much. Most branches should get decent performance with a hit from recent main. Fixes tailscale/corp#34739 Change-Id: Ia83269d878e4781e3ddf33f1db2f21d06ea2130f Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
2025-12-01k8s-operator: Fix typos in egress-pod-readiness.goShaikh Naasir1-2/+2
Updates #cleanup Signed-off-by: Alex Chan <alexc@tailscale.com>
2025-12-01cmd/tailscale/cli: soften the warning on `--force-reauth` for seamlessAlex Chan1-1/+1
Thanks to seamless key renewal, you can now do a force-reauth without losing your connection in all circumstances. We softened the interactive warning (see #17262) so let's soften the help text as well. Updates https://github.com/tailscale/corp/issues/32429 Signed-off-by: Alex Chan <alexc@tailscale.com>
2025-12-01feature/posture: log method and full URL for posture identity requestsAnton Tolchanov1-1/+1
Updates tailscale/corp#34676 Signed-off-by: Anton Tolchanov <anton@tailscale.com>
2025-11-28cmd/k8s-operator fix populateTLSSecret on tests (#18088)Fernando Serboncini1-2/+2
The call for populateTLSSecret was broken between PRs. Updates #cleanup Signed-off-by: Fernando Serboncini <fserb@tailscale.com>
2025-11-28cmd/k8s-operator: add support for taiscale.com/http-redirect (#17596)Fernando Serboncini5-36/+429
* cmd/k8s-operator: add support for taiscale.com/http-redirect The k8s-operator now supports a tailscale.com/http-redirect annotation on Ingress resources. When enabled, this automatically creates port 80 handlers that automatically redirect to the equivalent HTTPS location. Fixes #11252 Signed-off-by: Fernando Serboncini <fserb@tailscale.com> * Fix for permanent redirect Signed-off-by: Fernando Serboncini <fserb@tailscale.com> * lint Signed-off-by: Fernando Serboncini <fserb@tailscale.com> * warn for redirect+endpoint Signed-off-by: Fernando Serboncini <fserb@tailscale.com> * tests Signed-off-by: Fernando Serboncini <fserb@tailscale.com> --------- Signed-off-by: Fernando Serboncini <fserb@tailscale.com>
2025-11-27.github/workflows: only run golang ci lint when go files have changedMario Minardi1-1/+5
Restrict running the golangci-lint workflow to when the workflow file itself or a .go file, go.mod, or go.sum have actually been modified. Updates #cleanup Signed-off-by: Mario Minardi <mario@tailscale.com>
2025-11-27build(deps): bump braces from 3.0.2 to 3.0.3 in /client/webdependabot[bot]1-8/+8
Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3. - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: braces dependency-version: 3.0.3 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>
2025-11-27build(deps): bump cross-spawn from 7.0.3 to 7.0.6 in /client/webdependabot[bot]1-3/+3
Bumps [cross-spawn](https://github.com/moxystudio/node-cross-spawn) from 7.0.3 to 7.0.6. - [Changelog](https://github.com/moxystudio/node-cross-spawn/blob/master/CHANGELOG.md) - [Commits](https://github.com/moxystudio/node-cross-spawn/compare/v7.0.3...v7.0.6) --- updated-dependencies: - dependency-name: cross-spawn dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>
2025-11-27build(deps-dev): bump vitest from 1.3.1 to 1.6.1 in /client/webdependabot[bot]2-49/+44
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 1.3.1 to 1.6.1. - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Commits](https://github.com/vitest-dev/vitest/commits/v1.6.1/packages/vitest) --- updated-dependencies: - dependency-name: vitest dependency-type: direct:development ... Signed-off-by: dependabot[bot] <support@github.com>
2025-11-27build(deps-dev): bump vite from 5.1.7 to 5.4.21 in /client/webdependabot[bot]2-213/+277
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.1.7 to 5.4.21. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v5.4.21/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v5.4.21/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-version: 5.4.21 dependency-type: direct:development ... Signed-off-by: dependabot[bot] <support@github.com>
2025-11-27build(deps): bump js-yaml from 4.1.0 to 4.1.1 in /client/webdependabot[bot]1-3/+3
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.1.0 to 4.1.1. - [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1) --- updated-dependencies: - dependency-name: js-yaml dependency-version: 4.1.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>
2025-11-26.github/workflows: skip draft PRs for request review workflowsMario Minardi1-0/+2
Skip the "request review" workflows for PRs that are in draft to reduce noise / skip adding reviewers to PRs that are intentionally marked as not ready to review. Updates #cleanup Signed-off-by: Mario Minardi <mario@tailscale.com>
2025-11-26syncs: add means of declare locking assumptions for debug mode validationBrad Fitzpatrick3-0/+48
Updates #17852 Change-Id: I42a64a990dcc8f708fa23a516a40731a19967aba Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-11-26VERSION.txt: this is v1.93.0 (#18074)v1.93.0-preJonathan Nobels1-1/+1
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
2025-11-26derp/derpserver: add a unique sender cardinality estimateJames Tucker8-4/+238
Adds an observation point that may identify potentially abusive traffic patterns at outlier values. Updates tailscale/corp#24681 Signed-off-by: James Tucker <james@tailscale.com>
2025-11-26feature/tpm: return opening errors from both /dev/tpmrm0 and /dev/tpm0 (#18071)Andrew Lytvynov1-1/+8
This might help users diagnose why TPM access is failing for tpmrm0. Fixes #18026 Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2025-11-26util/execqueue: don't hold mutex in RunSyncBrad Fitzpatrick2-17/+29
We don't hold q.mu while running normal ExecQueue.Add funcs, so we shouldn't in RunSync either. Otherwise code it calls can't shut down the queue, as seen in #18502. Updates #18052 Co-authored-by: Nick Khyl <nickk@tailscale.com> Change-Id: Ic5e53440411eca5e9fabac7f4a68a9f6ef026de1 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-11-26tstest/integration: add integration test for Tailnet LockAlex Chan7-286/+573
This patch adds an integration test for Tailnet Lock, checking that a node can't talk to peers in the tailnet until it becomes signed. This patch also introduces a new package `tstest/tkatest`, which has some helpers for constructing a mock control server that responds to TKA requests. This allows us to reduce boilerplate in the IPN tests. Updates tailscale/corp#33599 Signed-off-by: Alex Chan <alexc@tailscale.com>
2025-11-25cmd/tailscale/cli,ipn,all: make peer relay server port a *uint16Jordan Whited9-51/+48
In preparation for exposing its configuration via ipn.ConfigVAlpha, change {Masked}Prefs.RelayServerPort from *int to *uint16. This takes a defensive stance against invalid inputs at JSON decode time. 'tailscale set --relay-server-port' is currently the only input to this pref, and has always sanitized input to fit within a uint16. Updates tailscale/corp#34591 Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-11-25ipn/serve: validate service paths in HasPathHandlerSachin Iyer2-0/+44
Fixes #17839 Signed-off-by: Sachin Iyer <siyer@detail.dev>
2025-11-25net/tstun: add TSMPDiscoAdvertisement to TSMPPing (#17995)Claus Lensbøl7-25/+280
Adds a new types of TSMP messages for advertising disco keys keys to/from a peer, and implements the advertising triggered by a TSMP ping. Needed as part of the effort to cache the netmap and still let clients connect without control being reachable. Updates #12639 Signed-off-by: Claus Lensbøl <claus@tailscale.com> Co-authored-by: James Tucker <james@tailscale.com>
2025-11-25ipn/ipnlocal: don't panic if there are no suitable exit nodesAlex Chan2-0/+66
In suggestExitNodeLocked, if no exit node candidates have a home DERP or valid location info, `bestCandidates` is an empty slice. This slice is passed to `selectNode` (`randomNode` in prod): ```go func randomNode(nodes views.Slice[tailcfg.NodeView], …) tailcfg.NodeView { … return nodes.At(rand.IntN(nodes.Len())) } ``` An empty slice becomes a call to `rand.IntN(0)`, which panics. This patch changes the behaviour, so if we've filtered out all the candidates before calling `selectNode`, reset the list and then pick from any of the available candidates. This patch also updates our tests to give us more coverage of `randomNode`, so we can spot other potential issues. Updates #17661 Change-Id: I63eb5e4494d45a1df5b1f4b1b5c6d5576322aa72 Signed-off-by: Alex Chan <alexc@tailscale.com>
2025-11-25tsconsensus: skip integration tests in CIFran Bull1-11/+2
There is an issue to add non-integration tests: #18022 Fixes #15627 #16340 Signed-off-by: Fran Bull <fran@tailscale.com>
2025-11-25tailcfg, control/controlclient: start moving MapResponse.DefaultAutoUpdate ↵Brad Fitzpatrick9-43/+147
to a nodeattr And fix up the TestAutoUpdateDefaults integration tests as they weren't testing reality: the DefaultAutoUpdate is supposed to only be relevant on the first MapResponse in the stream, but the tests weren't testing that. They were instead injecting a 2nd+ MapResponse. This changes the test control server to add a hook to modify the first map response, and then makes the test control when the node goes up and down to make new map responses. Also, the test now runs on macOS where the auto-update feature being disabled would've previously t.Skipped the whole test. Updates #11502 Change-Id: If2319bd1f71e108b57d79fe500b2acedbc76e1a6 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>