8979 Commits

Author SHA1 Message Date
M. J. Fromberger
dda2c0d2c2 wgengine/magicsock: subscribe to portmapper updates
When an event bus is plumbed in, use it to subscribe and react to port mapping
updates instead of using the client's callback mechanism. For now, the callback
remains available as a fallback when an event bus is not provided.

Updates #15160

Change-Id: I026adca44bf6187692ee87ae8ec02641c12f7774
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-04-16 10:10:45 -07:00
David Anderson
5399fa159a net/netmon: publish events to event bus
Updates #15160

Signed-off-by: David Anderson <dave@tailscale.com>
2025-04-16 10:10:45 -07:00
David Anderson
6d6f69e735 derp/derphttp: remove ban on websockets dependency
The event bus's debug page uses websockets.

Updates #15160

Signed-off-by: David Anderson <dave@tailscale.com>
2025-04-16 10:10:45 -07:00
David Anderson
e8cacd2a32 cmd/tailscaled: clean up unnecessary logf indirection #cleanup
Signed-off-by: David Anderson <dave@tailscale.com>
2025-04-16 10:10:45 -07:00
M. J. Fromberger
2731171c5e net/portmapper: fire an event when a port mapping is updated (#15371)
When an event bus is configured publish an event each time a new port mapping
is updated. Publication is unconditional and occurs prior to calling any
callback that is registered. For now, the callback is still fired in a separate
goroutine as before -- later, those callbacks should become subscriptions to
the published event.

For now, the event type is defined as a new type here in the package. We will
want to move it to a more central package when there are subscribers. The event
wrapper is effectively a subset of the data exported by the internal mapping
interface, but on a concrete struct so the bus plumbing can inspect it.

Updates #15160

Change-Id: I951f212429ac791223af8d75b6eb39a0d2a0053a
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-04-16 10:10:45 -07:00
M. J. Fromberger
deb0b255ff all: update the tsd.System constructor name (#15372)
Replace NewSystemWithEventBus with plain NewSystem, and update all usage.
See https://github.com/tailscale/tailscale/pull/15355#discussion_r2003910766

Updates #15160

Change-Id: I64d337f09576b41d9ad78eba301a74b9a9d6ebf4
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-04-16 10:10:45 -07:00
M. J. Fromberger
baead61e44 {wgengine,util/portmapper}: add and plumb an event bus (#15359)
Updates #15160

Change-Id: I2510fb4a8905fb0abe8a8e0c5b81adb15d50a6f8
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-04-16 10:10:45 -07:00
M. J. Fromberger
418e19fb5e portmapper: update NewClient to use a Config argument
In preparation for adding more parameters (and later, moving some away), rework
the portmapper constructor to accept its arguments on a Config struct rather
than positionally.

This is a breaking change to the function signature, but one that is very easy
to update, and a search of GitHub reveals only six instances of usage outside
clones and forks of Tailscale itself, that are not direct copies of the code
fixed up here.

While we could stub in another constructor, I think it is safe to let those
folks do the update in-place, since their usage is already affected by other
changes we can't test for anyway.

Updates #15160

Change-Id: I9f8a5e12b38885074c98894b7376039261b43f43
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-04-16 10:10:45 -07:00
M. J. Fromberger
2ac6e1edfd wgengine: plumb an event bus into the userspace engine
Updates #15160

Change-Id: Ia695ccdddd09cd950de22abd000d4c531d6bf3c8
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-04-16 10:10:45 -07:00
M. J. Fromberger
bcd6a0d0ac tsnet: shut down the event bus on Close
Updates #15160

Change-Id: I29c8194b4b41e95848e5f160e9970db352588449
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-04-16 10:10:45 -07:00
M. J. Fromberger
ffb22ee353 all: construct new System values with an event bus pre-populated
Although, at the moment, we do not yet require an event bus to be present, as
we start to add more pieces we will want to ensure it is always available.  Add
a new constructor and replace existing uses of new(tsd.System) throughout.
Update generated files for import changes.

Updates #15160

Change-Id: Ie5460985571ade87b8eac8b416948c7f49f0f64b
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-04-16 10:10:45 -07:00
David Anderson
6b8bbb4c37 tsd: wire up the event bus to tailscaled
Updates #15160

Signed-off-by: David Anderson <dave@tailscale.com>
2025-04-16 10:10:45 -07:00
David Anderson
a3cc7123ff tsweb: don't hook up pprof handlers in javascript builds
Updates #15160

Signed-off-by: David Anderson <dave@tailscale.com>
2025-04-16 10:10:45 -07:00
Jordan Whited
37f5fd2ec1
feature/{condregister,relayserver}: implement the skeleton for the relayserver feature (#15699)
This feature is "registered" as an ipnlocal.Extension, and
conditionally linked depending on GOOS and ts_omit_relayserver build
tag.

The feature is not linked on iOS in attempt to limit the impact to
binary size and resulting effect of pushing up against NetworkExtension
limits. Eventually we will want to support the relay server on iOS,
specifically on the Apple TV. Apple TVs are well-fitted to act as
underlay relay servers as they are effectively always-on servers.

This skeleton begins to tie a PeerAPI endpoint to a net/udprelay.Server.
The PeerAPI endpoint is currently no-op as
extension.shouldRunRelayServer() always returns false. Follow-up commits
will implement extension.shouldRunRelayServer().

Updates tailscale/corp#27502

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-04-16 09:50:48 -07:00
Mario Minardi
450bcbcb08
node.rev: bump to latest 22.x LTS release (#15652)
Bump to latest 22.x LTS release for node as the 18.x line is going EOL this month.

Updates https://github.com/tailscale/corp/issues/27737

Signed-off-by: Mario Minardi <mario@tailscale.com>
2025-04-15 16:51:21 -06:00
Andrew Lytvynov
34b97a3c75
ipn/ipnlocal: fix TestOnTailnetDefaultAutoUpdate on macOS (#15697)
https://github.com/tailscale/tailscale/pull/15395 changed the logic to
skip `EditPrefs` when the platform doesn't support auto-updates. But the
old logic would only fail `EditPrefs` if the auto-update value was
`true`. If it was `false`, `EditPrefs` would succeed and store `false`
in prefs. The new logic will keep the value `unset` even if the tailnet
default is `false`.

Fixes #15691

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2025-04-15 14:01:53 -07:00
Nick Khyl
e6eba4efee ipn/{auditlog,ipnext,ipnlocal}: convert the profile-change callback to a profile-state-change callback
In this PR, we enable extensions to track changes in the current prefs. These changes can result from a profile switch
or from the user or system modifying the current profile’s prefs. Since some extensions may want to distinguish between
the two events, while others may treat them similarly, we rename the existing profile-change callback to become
a profile-state-change callback and invoke it whenever the current profile or its preferences change. Extensions can still
use the sameNode parameter to distinguish between situations where the profile information, including its preferences,
has been updated but still represents the same tailnet node, and situations where a switch to a different profile has been made.

Having dedicated prefs-change callbacks is being considered, but currently seems redundant. A single profile-state-change callback
is easier to maintain. We’ll revisit the idea of adding a separate callback as we progress on extracting existing features from LocalBackend,
but the conversion to a profile-state-change callback is intended to be permanent.

Finally, we let extensions retrieve the current prefs or profile state (profile info + prefs) at any time using the new
CurrentProfileState and CurrentPrefs methods. We also simplify the NewControlClientCallback signature to exclude
profile prefs. It’s optional, and extensions can retrieve the current prefs themselves if needed.

Updates #12614
Updates tailscale/corp#27645
Updates tailscale/corp#26435
Updates tailscale/corp#27502

Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-04-15 15:08:04 -05:00
Satyam Soni
b926cd7fc6
k8s-operator: add age column to all custom resources (#15663)
This change introduces an Age column in the output for all custom
resources to enhance visibility into their lifecycle status.

Fixes #15499

Signed-off-by: satyampsoni <satyampsoni@gmail.com>
2025-04-15 20:13:56 +01:00
Jordan Whited
7833145289
ipn/auditlog: fix featureName doc typo (#15696)
Updates #cleanup

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-04-15 11:18:04 -07:00
Brad Fitzpatrick
4107056612 ipn/ipnlocal: skip broken TestOnTailnetDefaultAutoUpdate on macOS
Updates #15691

Change-Id: I131aed8bcd83be8e97399c905683e046381c9106
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-04-15 11:05:02 -07:00
Nick Khyl
60614fa4e5 ipn/desktop: fix panics on Windows 10, x86
[G,S]etWindowLongPtrW are not available on 32-bit Windows, where [G,S]etWindowLongW should be used instead.
The initial revision of #14945 imported the win package for calling and other Win32 API functions, which exported
the correct API depending on the platform. However, the same logic wasn't implemented when we removed
the win package dependency in a later revision, resulting in panics on Windows 10 x86 (there's no 32-bit Windows 11).

In this PR, we update the ipn/desktop package to use either [G,S]etWindowLongPtrW or [G,S]etWindowLongW
depending on the platform.

Fixes #15684

Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-04-15 12:05:06 -05:00
Jordan Whited
21400756a0
tstest/integration: simplify TestDNSOverTCPIntervalResolver (#15686)
Query for the const quad-100 reverse DNS name, for which a forward
record will also be served. This test was previously dependent on
search domain behavior, and now it is not.

Updates #15607

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-04-14 17:13:59 -07:00
dependabot[bot]
d8e3bce0b4
.github: Bump golangci/golangci-lint-action from 6.5.0 to 7.0.0 (#15476)
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 6.5.0 to 7.0.0.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](2226d7cb06...1481404843)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-14 16:04:36 -06:00
Fran Bull
4cb9d5c183 cmd/natc: cleanup unused state
perPeerState no longer needs to know the v6ULA.

Updates #14667

Signed-off-by: Fran Bull <fran@tailscale.com>
2025-04-14 14:06:56 -07:00
James Tucker
10fd61f1bb go.mod: bump golang.org/x/crypto and related
Updates #15680

Signed-off-by: James Tucker <james@tailscale.com>
2025-04-14 13:17:14 -07:00
Jonathan Nobels
d6fd865d41
hostinfo, ipnlocal: add optional os-specific callback for querying the hostname (#15647)
updates tailscale/tailscale#13476

On darwin, os.Hostname is no longer reliable when called
from a sandboxed process.  To fix this, we will allow clients
to set an optional callback to query the hostname via an
alternative native API.

We will leave the default implementation as os.Hostname since
this works perfectly well for almost everything besides sandboxed
darwin clients.

Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
2025-04-14 15:02:32 -04:00
Jordan Whited
62182fc37d
wgengine/netstack: revert cubic cc to reno cc (#15677)
Updates google/gvisor#11632
Updates tailscale/corp#27717

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-04-14 10:09:56 -07:00
dependabot[bot]
40e0c349a7
.github: Bump github/codeql-action from 3.28.14 to 3.28.15 (#15665)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.14 to 3.28.15.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](fc7e4a0fa0...45775bd823)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.28.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-14 11:05:33 -06:00
Erisa A
6502b7d667
scripts/installer.sh: add Miracle Linux as a RHEL derivative (#15671)
Fixes #15669
Signed-off-by: Erisa A <erisa@tailscale.com>
2025-04-14 16:54:51 +01:00
Irbe Krumina
624c25bd49
docs/commit-messages.md: merge two 'commit messages' sections (#15668)
Updates#cleanup

Signed-off-by: Irbe Krumina <irbe@tailscale.com>
2025-04-14 15:20:50 +01:00
Kristoffer Dalby
e84522e3e3 release/dist/cli: add option to override out path
Allow builds to be outputted to a specific directory.
By default, or if unset, artifacts are written to PWD/dist.

Updates tailscale/corp#27638

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
2025-04-14 15:26:30 +02:00
Nick Khyl
f28c8d0ec0 ipn/ipn{ext,local}: allow extension lookup by name or type
In this PR, we add two methods to facilitate extension lookup by both extensions,
and non-extensions (e.g., PeerAPI or LocalAPI handlers):
 - FindExtensionByName returns an extension with the specified name.
   It can then be type asserted to a given type.
 - FindMatchingExtension is like errors.As, but for extensions.
   It returns the first extension that matches the target type (either a specific extension
   or an interface).

Updates tailscale/corp#27645
Updates tailscale/corp#27502

Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-04-11 18:34:46 -05:00
Fran Bull
1e290867bd cmd/natc: only store v4 addresses
Because we derive v6 addresses from v4 addresses we only need to store
the v4 address, not both.

Updates #14667

Signed-off-by: Fran Bull <fran@tailscale.com>
2025-04-11 14:30:49 -07:00
Nick Khyl
4941cd7c73 cmd/tailscaled,ipn/{auditlog,desktop,ipnext,ipnlocal},tsd: extract LocalBackend extension interfaces and implementation
In this PR, we refactor the LocalBackend extension system, moving from direct callbacks to a more organized extension host model.

Specifically, we:
- Extract interface and callback types used by packages extending LocalBackend functionality into a new ipn/ipnext package.
- Define ipnext.Host as a new interface that bridges extensions with LocalBackend.
  It enables extensions to register callbacks and interact with LocalBackend in a concurrency-safe, well-defined, and controlled way.
- Move existing callback registration and invocation code from ipnlocal.LocalBackend into a new type called ipnlocal.ExtensionHost,
  implementing ipnext.Host.
- Improve docs for existing types and methods while adding docs for the new interfaces.
- Add test coverage for both the extracted and the new code.
- Remove ipn/desktop.SessionManager from tsd.System since ipn/desktop is now self-contained.
- Update existing extensions (e.g., ipn/auditlog and ipn/desktop) to use the new interfaces where appropriate.

We're not introducing new callback and hook types (e.g., for ipn.Prefs changes) just yet, nor are we enhancing current callbacks,
such as by improving conflict resolution when more than one extension tries to influence profile selection via a background profile resolver.
These further improvements will be submitted separately.

Updates #12614
Updates tailscale/corp#27645
Updates tailscale/corp#26435
Updates tailscale/corp#18342

Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-04-11 13:00:08 -05:00
Fran Bull
11d1dd2aed tsconsensus: mark 2 tests that were flaky in CI
Updates #15627

Signed-off-by: Fran Bull <fran@tailscale.com>
2025-04-11 07:59:10 -07:00
Brad Fitzpatrick
6c914409cd Revert "ipn/ipnstate: add home DERP to tailscale status JSON"
This reverts commit 476a4c6ff174d46ce3b125c018c07c43713e1c10.

Reason: redundant with `tailscale status --json | jq '.Self.Relay'`
which we all forgot about. Whoops.

Updates #15625
2025-04-10 11:34:48 -07:00
Tom Proctor
d446e04635
docs/k8s: add architecture diagram for ProxyGroup Ingress (#15593)
Adds a new diagram for ProxyGroups running in Ingress mode.
Documentation is currently not publicly available, but a link needs
adding once it is.

Updates tailscale/corp#24795

Change-Id: I0d5dd6bf6f0e1b8b0becae848dc97d8b4bfb9ccb
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
2025-04-10 18:42:00 +01:00
Nick Khyl
94f4f83731 ipn, ipn/ipnlocal: reduce coupling between LocalBackend/profileManager and the Windows-specific "current user" model
Ultimately, we'd like to get rid of the concept of the "current user". It is only used on Windows,
but even then it doesn't work well in multi-user and enterprise/managed Windows environments.

In this PR, we update LocalBackend and profileManager to decouple them a bit more from this obsolete concept.
This is done in a preparation for extracting ipnlocal.Extension-related interfaces and types, and using them
to implement optional features like tailscale/corp#27645, instead of continuing growing the core ipnlocal logic.

Notably, we rename (*profileManager).SetCurrentUserAndProfile() to SwitchToProfile() and change its signature
to accept an ipn.LoginProfileView instead of an ipn.ProfileID and ipn.WindowsUserID. Since we're not removing
the "current user" completely just yet, the method sets the current user to the owner of the target profile.

We also update the profileResolver callback type, which is typically implemented by LocalBackend extensions,
to return an ipn.LoginProfileView instead of ipn.ProfileID and ipn.WindowsUserID.

Updates tailscale/corp#27645
Updates tailscale/corp#18342

Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-04-10 12:24:00 -05:00
Brad Fitzpatrick
476a4c6ff1 ipn/ipnstate: add home DERP to tailscale status JSON
Fixes #15625

Change-Id: Ic20dad2dab4ac52c666057845bdc3cf5c0ffcd8f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-04-10 10:09:32 -07:00
kari-ts
6fb5e3b0cb
go.toolchain.rev: bump go 1.24 for Android pidfd changes (#15613)
Updates tailscale/tailscale#13452

Signed-off-by: kari-ts <kari@tailscale.com>
2025-04-10 09:14:26 -07:00
Paul Scott
ed052eac62
tstest: parse goroutines for diff in ResourceCheck (#15619)
ResourceCheck was previously using cmp.Diff on multiline goroutine stacks
The produced output was difficult to read for a number of reasons:

- the goroutines were sorted by count, and a changing count caused them to
  jump around
- diffs would be in the middle of stacks

Instead, we now parse the pprof/goroutines?debug=1 format goroutines and
only diff whole stacks.

Updates #1253

Signed-off-by: Paul Scott <paul@tailscale.com>
2025-04-10 16:01:39 +01:00
kari-ts
5c562116fc
ipnlocal: log when client reports new peerAPI ports (#15463)
Updates tailscale/tailscale#14393

Signed-off-by: kari-ts <kari@tailscale.com>
2025-04-09 16:49:33 -07:00
Andrew Lytvynov
1da78d8718
build_dist.sh: allow settings custom build tags (#15589)
Default tags to `$TAGS` if set, so that people can choose arbitrary
subsets of features.

Updates #12614

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2025-04-09 14:33:52 -07:00
Craig Hesling
b9277ade1f
drive: fix index out of bounds when parsing request local paths (#15517)
Fix the index out of bound panic when a request is made to the local
fileserver mux with a valid secret-token, but missing share name.

Example error:

    http: panic serving 127.0.0.1:40974: runtime error: slice bounds out of range [2:1]

Additionally, we document the edge case behavior of utilities that
this fileserver mux depends on.

Signed-off-by: Craig Hesling <craig@hesling.com>
2025-04-09 14:12:23 -07:00
Anton Tolchanov
d486ea388d logpolicy: fix log target override with a custom HTTP client
This makes sure that the log target override is respected even if a
custom HTTP client is passed to logpolicy.

Updates tailscale/maple#29

Signed-off-by: Anton Tolchanov <anton@tailscale.com>
2025-04-09 22:04:23 +01:00
Jordan Whited
6133f44344
ipn/ipnlocal: fix peerapi ingress endpoint (#15611)
The http.StatusMethodNotAllowed status code was being erroneously
set instead of http.StatusBadRequest in multiple places.

Updates #cleanup

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-04-09 13:43:29 -07:00
Nick Khyl
e7325213a7 clientupdate: fix MSI exit code handling, preserve MSI and updater logs on Windows
In this PR, we update the Windows client updater to:
- Run msiexec with logging enabled and preserve the log file in %ProgramData%\Tailscale\Logs;
- Preserve the updater's own log file in the same location;
- Properly handle ERROR_SUCCESS_REBOOT_REQUIRED, ERROR_SUCCESS_REBOOT_INITIATED, and ERROR_INSTALL_ALREADY_RUNNING exit codes. The first two values indicate that installation
completed successfully and no further retries are needed. The last one means the Windows Installer
service is busy. Retrying immediately is likely to fail and may be risky; it could uninstall the current version
without successfully installing the new one, potentially leaving the user without Tailscale.

Updates tailscale/corp#27496
Updates tailscale#15554

Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-04-09 15:25:42 -05:00
Jason O'Donnell
9ff9c5af04
.github: add cron schedule to installer tests (#15603)
Installer tests only run when changes are made to pkgserve. This PR schedules
these tests to be run daily and report any failures to Slack.

Fixes tailscale/corp#19103

Signed-off-by: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com>
2025-04-09 14:35:32 -04:00
Jordan Whited
e17abbf461
cmd/tailscale,ipn: add relay-server-port "tailscale set" flag and Prefs field (#15594)
This flag is currently no-op and hidden. The flag does round trip
through the related pref. Subsequent commits will tie them to
net/udprelay.Server. There is no corresponding "tailscale up" flag,
enabling/disabling of the relay server will only be supported via
"tailscale set".

This is a string flag in order to support disablement via empty string
as a port value of 0 means "enable the server and listen on a random
unused port". Disablement via empty string also follows existing flag
convention, e.g. advertise-routes.

Early internal discussions settled on "tailscale set --relay="<port>",
but the author felt this was too ambiguous around client vs server, and
may cause confusion in the future if we add related flags.

Updates tailscale/corp#27502

Signed-off-by: Jordan Whited <jordan@tailscale.com>
2025-04-09 10:25:57 -07:00
Simon Law
7e296923ab cmd/tailscale: test for new flags in tailscale up
`tailscale set` was created to set preferences, which used to be
overloaded into `tailscale up`. To move people over to the new
command, `up` was supposed to be frozen and no new preference flags
would be added. But people forgot, there was no test to warn them, and
so new flags were added anyway.

TestUpFlagSetIsFrozen complains when new flags are added to
`tailscale up`. It doesn’t try all combinations of GOOS, but since
the CI builds in every OS, the pull-request tests should cover this.

Updates #15460

Signed-off-by: Simon Law <sfllaw@sfllaw.ca>
2025-04-09 08:50:57 -07:00