7 Commits

Author SHA1 Message Date
Brad Fitzpatrick
3bc10ea585 ipn/ipnext: remove some interface indirection to add hooks
Now that 25c4dc5fd70 removed unregistering hooks and made them into
slices, just expose the slices and remove the setter funcs.

This removes boilerplate ceremony around adding new hooks.

This does export the hooks and make them mutable at runtime in theory,
but that'd be a data race. If we really wanted to lock it down in the
future we could make the feature.Hooks slice type be an opaque struct
with an All() iterator and a "frozen" bool and we could freeze all the
hooks after init. But that doesn't seem worth it.

This means that hook registration is also now all in one place, rather
than being mixed into ProfilesService vs ipnext.Host vs FooService vs
BarService. I view that as a feature. When we have a ton of hooks and
the list is long, then we can rearrange the fields in the Hooks struct
as needed, or make sub-structs, or big comments.

Updates #12614

Change-Id: I05ce5baa45a61e79c04591c2043c05f3288d8587
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-04-25 09:03:39 -07:00
Brad Fitzpatrick
3d8533b5d0 ipn/{ipnext,ipnlocal}: add a SafeBackend interface
Updates #12614

Change-Id: I197e673666e86ea74c19e3935ed71aec269b6c94
Co-authored-by: Nick Khyl <nickk@tailscale.com>
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-04-24 14:48:58 -07:00
Brad Fitzpatrick
25c4dc5fd7 ipn/ipnext: remove support for unregistering extension
Updates #12614

Change-Id: I893e3ea74831deaa6f88e31bba2d95dc017e0470
Co-authored-by: Nick Khyl <nickk@tailscale.com>
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-04-24 13:38:00 -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
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
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
Nick Khyl
6a9a7f35d9 cmd/tailscaled,ipn/{auditlog,ipnlocal},tsd: omit auditlog unless explicitly imported
In this PR, we update ipnlocal.LocalBackend to allow registering callbacks for control client creation
and profile changes. We also allow to register ipnauth.AuditLogFunc to be called when an auditable
action is attempted.

We then use all this to invert the dependency between the auditlog and ipnlocal packages and make
the auditlog functionality optional, where it only registers its callbacks via ipnlocal-provided hooks
when the auditlog package is imported.

We then underscore-import it when building tailscaled for Windows, and we'll explicitly
import it when building xcode/ipn-go-bridge for macOS. Since there's no default log-store
location for macOS, we'll also need to call auditlog.SetStoreFilePath to specify where
pending audit logs should be persisted.

Fixes #15394
Updates tailscale/corp#26435
Updates tailscale/corp#27012

Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-03-28 10:36:49 -05:00