feature

package
v1.102.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2026 License: BSD-3-Clause Imports: 12 Imported by: 4

README

Modular Tailscale features

This directory contains Tailscale's modular feature system. The Tailscale client has grown large; not every user wants every feature (an IoT device on a few-dollar chip does not need Taildrop, WebDAV, ACME, or SSH). The feature/ tree is how we make individual features conditionally linkable so that resource-constrained builds can omit them, and so that new code lives in small self-contained packages instead of being dumped into LocalBackend.

New code lives here

The preferred home for new functionality is a feature/<name> package. If there is any plausible user who might not want your feature in their build (which is almost always the case), it should be modular from the start. A feature package should install itself into the rest of Tailscale via hooks, extensions, and registrations from its own init (see "Hooks and registration" below). It should not export API used by callers elsewhere in the tree; callers reach the feature through the hook, not by importing it.

Think your functionality is so core that it must always be linked in? Imagine any plausible user who might not want it. If you cannot, ask before dumping code into ipn/ipnlocal or similar.

The half-migrated reality

Much of the tree is in a half-migrated state. A given feature may:

  • Have a ts_omit_<name> build tag declared in featuretags/featuretags.go, and
  • Have some of its code moved to feature/<name>/, but
  • Still have significant code living in ipn/ipnlocal, cmd/tailscaled, or elsewhere, either:
    • Behind a build-tag-conditional file (a whole .go file gated with //go:build !ts_omit_<name>), or
    • Guarded at runtime by an if buildfeatures.HasFoo { ... } block that the compiler and linker dead-code-eliminate when the tag is set.

When you touch one of these features, prefer to keep migrating code into its feature/<name> package rather than adding more to the old location. But do not feel obligated to finish the migration in one PR.

The registry: feature/featuretags

featuretags/featuretags.go is the single source of truth. It declares the Features map: for each feature tag (a lowercase string like acme or taildrop), it records the exported symbol name used by generated constants, a human-readable description, and any other features it depends on (forming a DAG).

Adding a new feature starts with adding an entry there. See the top of the file for the tag naming convention: feature foo corresponds to build tag ts_omit_foo (opt-out). The one exception is cli, which is opt-in via ts_include_cli; see FeatureTag.IsOmittable.

Features can be marked ImplementationDetail: true when they are internal plumbing (e.g. dbus, c2n) that users would not select directly; they exist only so that user-visible features can depend on them.

Generated constants: feature/buildfeatures

After editing featuretags.go, run:

./tool/go generate ./feature/buildfeatures

(or the meta make generate). That regenerates two files per feature in buildfeatures/: feature_<name>_enabled.go and feature_<name>_disabled.go, gated with //go:build !ts_omit_<name> and //go:build ts_omit_<name> respectively. Each pair exports a single boolean constant, e.g. HasACME. Because these are Go constants, code of the form:

if buildfeatures.HasACME {
    // ...
}

is dead-code-eliminated by the compiler and linker when the feature is omitted. Constants can eliminate code but they cannot remove imports; for that you still need a build-tag-gated file.

Use constants when moving code to feature/<name> is impractical (e.g. the code has to sit inside LocalBackend), or when a small conditional inside otherwise-shared logic is clearer than splitting into two files. Prefer separate packages when you can.

feature/condregister: opt-out registration

condregister/ is the one central package that tailscaled (and the macOS/iOS closed-source client) empty-imports so that all "on by default" features get registered. Every feature that should ship in tailscaled by default has a maybe_<name>.go file here of the form:

//go:build !ts_omit_<name>

package condregister

import _ "tailscale.com/feature/<name>"

That is the whole file. The build tag is the only mechanism that decides whether the feature is compiled in. Because tailscaled imports condregister, all these maybe_* files pull in their respective feature/<name> packages by default; adding ts_omit_<name> to the build removes the file, and with it the import, and with it the package's init and everything it transitively depends on.

Some maybe_* files carry additional build tags (e.g. //go:build !ios && !ts_omit_capture) when a feature should be excluded on specific platforms.

The feature/<name> package should not carry ts_omit_* tags

The ts_omit_<name> tag lives only on the condregister/maybe_<name>.go (and analogous tsnet/maybe_<name>.go) import shim, not on the feature/<name>/*.go files themselves. Keeping the feature package free of its own omit tag lets any program directly opt in with a blank import regardless of what ts_omit_* tags are set on the top-level build:

import _ "tailscale.com/feature/foo"

That is how a tsnet-using application pulls a feature in on its own terms without having to reason about which ts_omit_* tags are in effect.

OS-specific build tags inside feature/<name>/ are fine, and often desirable: if the feature only makes sense on some platforms, gating its files with //go:build linux (or !ios, etc.) both keeps go test ./... passing on every GOOS and prevents a tsnet user on an unsupported platform from accidentally blank-importing a package that would fail to compile or run there.

tsnet does NOT depend on condregister

tsnet is a library, not a daemon, and it links in a different (and generally smaller) default feature set than tailscaled. tsnet has its own top-level maybe_*.go files that decide which features it opts in to, and its own depaware.txt.

Consequence: you cannot assume buildfeatures.HasFoo == true means feature foo was actually linked. In a tsnet build, ts_omit_foo may not be set (so HasFoo is true), yet tsnet may have never imported feature/foo, so its init never ran and no hooks were installed.

buildfeatures.HasFoo really means "not explicitly omitted by build tag." Whether the feature is actually present is feature.IsRegistered("foo"). The idiom is:

buildfeatures.HasFoo && feature.IsRegistered("foo")

HasFoo lets the compiler DCE the whole expression in ts_omit_foo builds; IsRegistered guards against the tsnet case where the tag is unset but the package was never imported.

The feature API

Package feature itself exposes the small runtime API used by feature packages and their callers:

  • feature.Register(name): a feature package calls this from its init to record that it was linked in. Callers use feature.IsRegistered(name) to check.
  • feature.Hook[Func]: a single-writer, single-reader hook. The extension point declares a var HookX feature.Hook[func(...)], the feature package Sets it once from init, and callers use GetOk/GetOrNil/IsSet to invoke it. Set panics if called twice.
  • feature.Hooks[Func]: a slice of hooks for extension points that may legitimately have multiple registrants.
  • Common cross-feature hooks (auto-update, proxy, TPM, SSH host keys, hardware attestation) live in hooks.go alongside their small dispatcher functions like feature.CanAutoUpdate() and feature.TPMAvailable(). Add hooks here only sparingly: every hook in this package is loaded by every consumer of feature, so its function signature must not reference types from "heavy" packages. By heavy we mean any package whose presence in this signature would unnecessarily grow cmd/tailscaled/depaware-min.txt: packages with a large API/dependency footprint (e.g. net/http, crypto/tls, golang.org/x/crypto/ssh, k8s.io/...), or packages that trigger expensive runtime features like reflect-based registration. The minimal build's depaware file is sacred and must not grow without good reason. Prefer primitives, small types/... packages, or interfaces. If your hook needs a wide type, keep the hook (and its dispatcher) in the caller's package instead of promoting it here.

ipnext.RegisterExtension (in ipn/ipnext) is the corresponding mechanism for features that need to hook into LocalBackend; see the next section.

IPN extensions: ipn/ipnext

For features that need to attach state and behavior to LocalBackend, the plain feature.Hook mechanism is not enough; you also need per-LocalBackend state and a well-defined lifecycle. That is what ipn/ipnext provides.

Per-LocalBackend state matters because a single process can have more than one LocalBackend alive at once: a tsnet program can host many tsnet.Server nodes concurrently, each with its own LocalBackend. Package-global variables in a feature package would be shared across all of them, which should be avoided unless it is otherwise infeasible. An ipnext.Extension is instantiated once per LocalBackend, so each node gets its own copy of the extension's state.

(A related, not-yet-realized goal is letting different tsnet nodes in the same process opt in to different sets of hooks. Today the hook registration is still process-global (the init runs once and the hook is on for every LocalBackend), but the extension design leaves room to make this per-node in the future. Don't rely on the process-global behavior; keep state on the extension instance, not in globals.)

An ipnext.Extension is created once per LocalBackend. From init, a feature package registers a factory:

func init() {
    feature.Register("taildrop")
    ipnext.RegisterExtension("taildrop", newExtension)
}

When LocalBackend.Start runs, it instantiates each registered extension and calls its Init(host ipnext.Host) error method. Init is where the extension wires up its per-backend hooks against host.Hooks():

func (e *extension) Init(h ipnext.Host) error {
    h.Hooks().ProfileStateChange.Add(e.onChangeProfile)
    h.Hooks().OnSelfChange.Add(e.onSelfChange)
    h.Hooks().MutateNotifyLocked.Add(e.setNotifyFilesWaiting)
    h.Hooks().SetPeerStatus.Add(e.setPeerStatus)
    h.Hooks().BackendStateChange.Add(e.onBackendStateChange)
    return nil
}

ipnext.Hooks is a struct of feature.Hook/feature.Hooks fields covering LocalBackend's extension points: backend and profile state changes, netmap toggles, self-node changes, notify mutation, peer status, packet-filter hooks, audit logging, and more. Read the type in ipn/ipnext/ipnext.go for the current list; new hooks are added there as needed.

Extension hooks run synchronously with the triggering LocalBackend operation and can influence its outcome. Because multiple extensions may touch the same shared state (prefs, active profile, exit node, etc.), new hooks should be designed with a clear conflict-resolution story rather than assuming a single writer.

To get back to your extension from a LocalBackend inside a LocalAPI or C2N handler, use ipnlocal.GetExt[*yourExtType](b).

Canonical examples:

The ipnext mechanism is a work in progress and not every part of LocalBackend has been converted to hooks yet. If you need a new extension point, ask.

Tests: featuretags and depaware / depchecker

Tests come in three flavors:

  1. feature/featuretags self-tests (featuretags_test.go) validate the registry itself: that every declared dependency exists, that there are no cycles, that Requires/RequiredBy return the expected sets, and that every ts_omit_* string that appears anywhere in the tree (via git grep) is declared in the map.

  2. depaware (github.com/tailscale/depaware) snapshots the full set of Go packages linked into each binary into a checked-in depaware.txt file. Its job is right there in the name: to force us to be aware of our deps. Every change to the dependency graph shows up as a diff to depaware.txt in the same PR that introduced it, so reviewers can see, prominently, exactly what got pulled in or dropped. We use this to have an auditable history of the dependency footprint of key programs and libraries. We track several flavors:

    • full tailscaled on all GOOSes
    • full tailscale CLI on all GOOSes
    • cmd/derper
    • minimal tailscaled+CLI (depaware-min.txt, depaware-minbox.txt)
    • tsnet (has its own depaware.txt)
    • k8s-operator, which uses tsnet

    When reviewing a PR, look at the depaware diff to see what got pulled in or dropped, and make sure the changes make sense.

  3. deptest.DepChecker lets you lock down omissions once you've achieved them. Rather than hoping nobody accidentally adds a taildrop import back into a ts_omit_taildrop build, you write:

     func TestOmitACME(t *testing.T) {
         deptest.DepChecker{
             GOOS:   "linux",
             GOARCH: "amd64",
             Tags:   "ts_omit_acme,ts_include_cli",
             OnDep: func(dep string) {
                 if strings.Contains(dep, "/acme") {
                     t.Errorf("unexpected dep with ts_omit_acme: %q", dep)
                 }
             },
         }.Check(t)
     }
    

    cmd/tailscaled/deps_test.go has many examples; add new ones there or wherever they fit. tsnet has its own TestDeps in tsnet_test.go with a BadDeps map asserting that things like feature/remoteconfig, feature/syspolicy, and x/crypto/ssh never sneak into tsnet.

Tooling

  • cmd/featuretags constructs valid sets of Go omit build tags. Start from a minimal build and add features with --min --add=..., or start from a full build and remove with --remove=...; either way it respects the declared dependency DAG.
  • build_dist.sh uses cmd/featuretags under the hood, so you do not need to hand-maintain its build-tag lists as new features are added.

Summary of what to do for a new feature

  1. Add an entry to Features in feature/featuretags/featuretags.go, including any Deps.
  2. Run ./tool/go generate ./feature/buildfeatures (or make generate).
  3. Create feature/<name>/ with the code, and register hooks and any ipnext.Extension from its init. Call feature.Register("<name>") from init too.
  4. If the feature should be on by default in tailscaled, add feature/condregister/maybe_<name>.go with //go:build !ts_omit_<name> and a blank import of tailscale.com/feature/<name>.
  5. If tsnet should also link it, add an equivalent maybe_<name>.go under tsnet/. Otherwise remember buildfeatures.HasFoo alone is not enough; pair it with feature.IsRegistered("foo").
  6. Add a deptest.DepChecker test to lock down what does not get linked when the feature is omitted.
  7. Regenerate depaware and review the diff.

Asking questions

If something in this document is unclear, if you are not sure whether your work should be modular, or if you need a new extension point:

Documentation

Overview

Package feature tracks which features are linked into the binary.

Index

Constants

View Source
const CanSystemdStatus = runtime.GOOS == "linux" && buildfeatures.HasSDNotify

CanSystemdStatus reports whether the current build has systemd notifications linked in.

It's effectively the same as HookSystemdStatus.IsSet(), but a constant for dead code elimination reasons.

Variables

View Source
var ErrUnavailable = errors.New("feature not included in this build")

Functions

func CanAutoUpdate added in v1.90.0

func CanAutoUpdate() bool

CanAutoUpdate reports whether the current binary is built with auto-update support and, if so, whether the current platform supports it.

func HardwareAttestationAvailable added in v1.90.0

func HardwareAttestationAvailable() bool

HardwareAttestationAvailable reports whether hardware attestation is supported and available (TPM on Windows/Linux, Secure Enclave on macOS|iOS, KeyStore on Android)

func IsRegistered added in v1.102.0

func IsRegistered(name string) bool

IsRegistered reports whether the named feature package's init function has run and registered itself via Register in this binary. It is distinct from the compile-time buildfeatures constants: a feature package can be present in the binary but not imported (e.g. tsnet deliberately does not import many features), in which case its init does not run.

func Register

func Register(name string)

Register notes that the named feature is linked into the binary.

func Registered added in v1.90.4

func Registered() map[string]bool

Registered reports the set of registered features.

The returned map should not be modified by the caller, not accessed concurrently with calls to Register.

func SystemdStatus added in v1.90.0

func SystemdStatus(format string, args ...any)

SystemdStatus sends a single line status update to systemd so that information shows up in systemctl output.

It does nothing on non-Linux systems or if the binary was built without the sdnotify feature.

func TPMAvailable added in v1.90.0

func TPMAvailable() bool

TPMAvailable reports whether a TPM device is supported and available.

Types

type Hook

type Hook[Func any] struct {
	// contains filtered or unexported fields
}

Hook is a func that can only be set once.

It is not safe for concurrent use.

var HookCanAutoUpdate Hook[func() bool]

HookCanAutoUpdate is a hook for the clientupdate package to conditionally initialize.

var HookGenerateAttestationKeyIfEmpty Hook[func(p *persist.Persist, logf logger.Logf) (bool, error)]
var HookGetSSHHostKeyPublicStrings Hook[func(varRoot string, logf logger.Logf) ([]string, error)]

HookGetSSHHostKeyPublicStrings is a hook for the ssh/hostkeys package to provide SSH host key public strings to ipn/ipnlocal without ipnlocal needing to import golang.org/x/crypto/ssh.

var HookHardwareAttestationAvailable Hook[func() bool]

HookHardwareAttestationAvailable is a hook that reports whether hardware attestation is supported and available.

var HookLogSink Hook[func() io.Writer]

HookLogSink is a hook for the syslog feature to redirect the process's logs to an alternate sink. If set, tailscaled calls it once early in main, after flag parsing; on that first call, if the user requested an alternate sink, it points the standard library's default logger at that sink. It returns the sink, or nil if logs are not being redirected. Later callers (such as logpolicy, which otherwise writes its console copy of logs to stderr) use the returned writer to send their logs to the same place.

var HookProxyFromEnvironment Hook[func(*http.Request) (*url.URL, error)]

HookProxyFromEnvironment is a hook for feature/useproxy to register a function to use as http.ProxyFromEnvironment.

var HookProxyGetAuthHeader Hook[func(*url.URL) (string, error)]

HookProxyGetAuthHeader is a hook for feature/useproxy to register [tshttpproxy.GetAuthHeader].

var HookProxyInvalidateCache Hook[func()]

HookProxyInvalidateCache is a hook for feature/useproxy to register [tshttpproxy.InvalidateCache].

var HookProxySetSelfProxy Hook[func(...string)]

HookProxySetSelfProxy is a hook for feature/useproxy to register [tshttpproxy.SetSelfProxy].

var HookProxySetTransportGetProxyConnectHeader Hook[func(*http.Transport)]

HookProxySetTransportGetProxyConnectHeader is a hook for feature/useproxy to register [tshttpproxy.SetTransportGetProxyConnectHeader].

var HookRegisterLogSinkFlags Hook[func()]

HookRegisterLogSinkFlags is a hook for the syslog feature to register its flags (such as tailscaled's --syslog) with the process's default flag set. If set, tailscaled calls it before flag parsing.

var HookSystemdReady Hook[func()]

HookSystemdReady sends a readiness to systemd. This will unblock service dependents from starting.

var HookSystemdStatus Hook[func(format string, args ...any)]

HookSystemdStatus holds a func that will send a single line status update to systemd so that information shows up in systemctl output.

var HookTPMAvailable Hook[func() bool]

HookTPMAvailable is a hook that reports whether a TPM device is supported and available.

func (*Hook[Func]) Get

func (h *Hook[Func]) Get() Func

Get returns the hook function, or panics if it hasn't been set. Use IsSet to check if it's been set, or use GetOrNil if you're okay with a nil return value.

func (*Hook[Func]) GetOk added in v1.84.0

func (h *Hook[Func]) GetOk() (f Func, ok bool)

GetOk returns the hook function and true if it has been set, otherwise its zero value and false.

func (*Hook[Func]) GetOrNil added in v1.90.0

func (h *Hook[Func]) GetOrNil() Func

GetOrNil returns the hook function or nil if it hasn't been set.

func (*Hook[Func]) IsSet

func (h *Hook[Func]) IsSet() bool

IsSet reports whether the hook has been set.

func (*Hook[Func]) Set

func (h *Hook[Func]) Set(f Func)

Set sets the hook function, panicking if it's already been set or f is the zero value.

It's meant to be called in init.

func (*Hook[Func]) SetForTest added in v1.92.0

func (h *Hook[Func]) SetForTest(f Func) (restore func())

SetForTest sets the hook function for tests, blowing away any previous value. It will panic if called from non-test code.

It returns a restore function that resets the hook to its previous value.

type Hooks added in v1.84.0

type Hooks[Func any] []Func

Hooks is a slice of funcs.

As opposed to a single Hook, this is meant to be used when multiple parties are able to install the same hook.

func (*Hooks[Func]) Add added in v1.84.0

func (h *Hooks[Func]) Add(f Func)

Add adds a hook to the list of hooks.

Add should only be called during early program startup before Tailscale has started. It is not safe for concurrent use.

Directories

Path Synopsis
Package ace registers support for Alternate Connectivity Endpoints (ACE).
Package ace registers support for Alternate Connectivity Endpoints (ACE).
Package acme registers the ACME/TLS-cert feature and implements its associated ipnext.Extension.
Package acme registers the ACME/TLS-cert feature and implements its associated ipnext.Extension.
Package appconnectors registers support for Tailscale App Connectors.
Package appconnectors registers support for Tailscale App Connectors.
Package awsparamstore registers support for fetching secret values from AWS Parameter Store.
Package awsparamstore registers support for fetching secret values from AWS Parameter Store.
Package bird integrates Tailscale with the BIRD Internet Routing Daemon: it enables the "tailscale" protocol in BIRD while this node is a primary subnet router and disables it otherwise.
Package bird integrates Tailscale with the BIRD Internet Routing Daemon: it enables the "tailscale" protocol in BIRD while this node is a primary subnet router and disables it otherwise.
The buildfeatures package contains boolean constants indicating which features were included in the binary (via build tags), for use in dead code elimination when using separate build tag protected files is impractical or undesirable.
The buildfeatures package contains boolean constants indicating which features were included in the binary (via build tags), for use in dead code elimination when using separate build tag protected files is impractical or undesirable.
Package c2n registers support for C2N (Control-to-Node) communications.
Package c2n registers support for C2N (Control-to-Node) communications.
Package captiveportal provides optional captive portal detection, warning the user via the health tracker when their network requires a browser login before traffic can flow.
Package captiveportal provides optional captive portal detection, warning the user via the health tracker when their network requires a browser login before traffic can flow.
netcheckhook
Package netcheckhook makes netcheck probe for captive portals during full reports.
Package netcheckhook makes netcheck probe for captive portals during full reports.
Package capture formats packet logging into a debug pcap stream.
Package capture formats packet logging into a debug pcap stream.
dissector
Package dissector contains the Lua dissector for Tailscale packets.
Package dissector contains the Lua dissector for Tailscale packets.
Package clientupdate enables the client update feature.
Package clientupdate enables the client update feature.
condlite
expvar
Package expvar contains type aliases for expvar types, to allow conditionally excluding the package from builds.
Package expvar contains type aliases for expvar types, to allow conditionally excluding the package from builds.
The condregister package registers all conditional features guarded by build tags.
The condregister package registers all conditional features guarded by build tags.
awsparamstore
Package awsparamstore conditionally registers the awsparamstore feature for resolving secrets from AWS Parameter Store.
Package awsparamstore conditionally registers the awsparamstore feature for resolving secrets from AWS Parameter Store.
identityfederation
Package identityfederation registers support for authkey resolution via identity federation if it's not disabled by the ts_omit_identityfederation build tag.
Package identityfederation registers support for authkey resolution via identity federation if it's not disabled by the ts_omit_identityfederation build tag.
netlog
Package netlog registers support for network flow logging if it's not disabled via the ts_omit_netlog or ts_omit_logtail build tags.
Package netlog registers support for network flow logging if it's not disabled via the ts_omit_netlog or ts_omit_logtail build tags.
oauthkey
Package oauthkey registers support for OAuth key resolution if it's not disabled via the ts_omit_oauthkey build tag.
Package oauthkey registers support for OAuth key resolution if it's not disabled via the ts_omit_oauthkey build tag.
portmapper
Package portmapper registers support for portmapper if it's not disabled via the ts_omit_portmapper build tag.
Package portmapper registers support for portmapper if it's not disabled via the ts_omit_portmapper build tag.
useproxy
Package useproxy registers support for using proxies if it's not disabled via the ts_omit_useproxy build tag.
Package useproxy registers support for using proxies if it's not disabled via the ts_omit_useproxy build tag.
Package conn25 registers the conn25 feature and implements its associated ipnext.Extension.
Package conn25 registers the conn25 feature and implements its associated ipnext.Extension.
Package debugportmapper registers support for debugging Tailscale's portmapping support.
Package debugportmapper registers support for debugging Tailscale's portmapping support.
The doctor package registers the "doctor" problem diagnosis support into the rest of Tailscale.
The doctor package registers the "doctor" problem diagnosis support into the rest of Tailscale.
Package drive registers the Taildrive (file server) feature.
Package drive registers the Taildrive (file server) feature.
The featuretags package is a registry of all the ts_omit-able build tags.
The featuretags package is a registry of all the ts_omit-able build tags.
Package identityfederation registers support for using ID tokens to automatically request authkeys for logging in.
Package identityfederation registers support for using ID tokens to automatically request authkeys for logging in.
Package linkspeed registers support for setting the TUN link speed on Linux, to better integrate with system monitoring tools.
Package linkspeed registers support for setting the TUN link speed on Linux, to better integrate with system monitoring tools.
Package linuxdnsfight provides Linux support for detecting DNS fights (inotify watching of /etc/resolv.conf).
Package linuxdnsfight provides Linux support for detecting DNS fights (inotify watching of /etc/resolv.conf).
Package netlog registers the network flow logging feature and wires it into the WireGuard engine.
Package netlog registers the network flow logging feature and wires it into the WireGuard engine.
Package oauthkey registers support for using OAuth client secrets to automatically request authkeys for logging in.
Package oauthkey registers support for using OAuth client secrets to automatically request authkeys for logging in.
Package portlist contains code to poll the local system for open ports and report them to the control plane, if enabled on the tailnet.
Package portlist contains code to poll the local system for open ports and report them to the control plane, if enabled on the tailnet.
Package portmapper registers support for NAT-PMP, PCP, and UPnP port mapping protocols to help get direction connections through NATs.
Package portmapper registers support for NAT-PMP, PCP, and UPnP port mapping protocols to help get direction connections through NATs.
Package posture registers support for device posture checking, reporting machine-specific information to the control plane when enabled by the user and tailnet.
Package posture registers support for device posture checking, reporting machine-specific information to the control plane when enabled by the user and tailnet.
Package relayserver registers the relay server feature and implements its associated ipnext.Extension.
Package relayserver registers the relay server feature and implements its associated ipnext.Extension.
Package remoteconfig registers a c2n endpoint that lets the control plane invoke this node's LocalAPI when Prefs.RemoteConfig is true.
Package remoteconfig registers a c2n endpoint that lets the control plane invoke this node's LocalAPI when Prefs.RemoteConfig is true.
Package routecheck registers support for RouteCheck, which checks the reachability of overlapping routers.
Package routecheck registers support for RouteCheck, which checks the reachability of overlapping routers.
Package runtimemetrics exports select runtime/metrics as tailscale.com/util/clientmetric's.
Package runtimemetrics exports select runtime/metrics as tailscale.com/util/clientmetric's.
Package sdnotify contains a minimal wrapper around systemd-notify to enable applications to signal readiness and status to systemd.
Package sdnotify contains a minimal wrapper around systemd-notify to enable applications to signal readiness and status to systemd.
Package serviceclientprefs stores the desktop clients' saved service launch preferences, in a file per login profile.
Package serviceclientprefs stores the desktop clients' saved service launch preferences, in a file per login profile.
serviceclient
Package serviceclient holds the types for the desktop clients' saved service launch preferences.
Package serviceclient holds the types for the desktop clients' saved service launch preferences.
Package ssh registers the Tailscale SSH feature, including host key management and the SSH server.
Package ssh registers the Tailscale SSH feature, including host key management and the SSH server.
Package syslog provides the tailscaled --syslog flag, which sends the daemon's logs to the system syslog daemon instead of stderr.
Package syslog provides the tailscaled --syslog flag, which sends the daemon's logs to the system syslog daemon instead of stderr.
Package syspolicy provides an interface for system-wide policy management.
Package syspolicy provides an interface for system-wide policy management.
Package taildrop contains the implementation of the Taildrop functionality including sending and retrieving files.
Package taildrop contains the implementation of the Taildrop functionality including sending and retrieving files.
package tailnetlock registers the tailnet lock debug C2N handler.
package tailnetlock registers the tailnet lock debug C2N handler.
Package tap registers Tailscale's experimental (demo) Linux TAP (Layer 2) support.
Package tap registers Tailscale's experimental (demo) Linux TAP (Layer 2) support.
Package tpm implements support for TPM 2.0 devices.
Package tpm implements support for TPM 2.0 devices.
Package tundevstats provides a mechanism for exposing TUN device statistics via clientmetrics.
Package tundevstats provides a mechanism for exposing TUN device statistics via clientmetrics.
Package useproxy registers support for using system proxies.
Package useproxy registers support for using system proxies.
Package wakeonlan registers the Wake-on-LAN feature.
Package wakeonlan registers the Wake-on-LAN feature.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL