ipn

package
v1.32.1 Latest Latest
Warning

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

Go to latest
Published: Oct 21, 2022 License: BSD-3-Clause Imports: 32 Imported by: 93

Documentation

Overview

Package ipn implements the interactions between the Tailscale cloud control plane and the local network stack.

IPN is the abbreviated name for a Tailscale network. What's less clear is what it's an abbreviation for: Identified Private Network? IP Network? Internet Private Network? I Privately Network?

Index

Constants

View Source
const (
	NoState = State(iota)
	InUseOtherUser
	NeedsLogin
	NeedsMachineAuth
	Stopped
	Starting
	Running
)
View Source
const (
	// MachineKeyStateKey is the key under which we store the machine key,
	// in its key.NodePrivate.MarshalText representation.
	MachineKeyStateKey = StateKey("_machinekey")

	// GlobalDaemonStateKey is the ipn.StateKey that tailscaled
	// loads on startup.
	//
	// We have to support multiple state keys for other OSes (Windows in
	// particular), but right now Unix daemons run with a single
	// node-global state. To keep open the option of having per-user state
	// later, the global state key doesn't look like a username.
	GlobalDaemonStateKey = StateKey("_daemon")

	// ServerModeStartKey's value, if non-empty, is the value of a
	// StateKey containing the prefs to start with which to start the
	// server.
	//
	// For example, the value might be "user-1234", meaning the
	// the server should start with the Prefs JSON loaded from
	// StateKey "user-1234".
	ServerModeStartKey = StateKey("server-mode-start-key")

	// NLKeyStateKey is the key under which we store the node's
	// network-lock node key, in its key.NLPrivate.MarshalText representation.
	NLKeyStateKey = StateKey("_nl-node-key")
)
View Source
const DefaultControlURL = "https://controlplane.tailscale.com"

DefaultControlURL is the URL base of the control plane ("coordination server") for use when no explicit one is configured. The default control plane is the hosted version run by Tailscale.com.

View Source
const ErrMsgPermissionDenied = "permission denied"

ErrMsgPermissionDenied is the Notify.ErrMessage value used an operation was done from a user/context that didn't have permission.

View Source
const GoogleIDTokenType = "ts_android_google_login"

GoogleIDToken Type is the tailcfg.Oauth2Token.TokenType for the Google ID tokens used by the Android client.

View Source
const MaxMessageSize = 10 << 20

MaxMessageSize is the maximum message size, in bytes.

Variables

View Source
var (
	// ErrExitNodeIDAlreadySet is returned from (*Prefs).SetExitNodeIP when the
	// Prefs.ExitNodeID field is already set.
	ErrExitNodeIDAlreadySet = errors.New("cannot set ExitNodeIP when ExitNodeID is already set")
)
View Source
var ErrStateNotExist = errors.New("no state with given ID")

ErrStateNotExist is returned by StateStore.ReadState when the requested state ID doesn't exist.

Functions

func IPCVersion added in v1.26.0

func IPCVersion() string

IPCVersion returns version.Long usually, unless TS_DEBUG_FAKE_IPC_VERSION is set, in which it contains that value. This is only used for weird development cases when testing mismatched versions and you want the client to act like it's compatible with the server.

func IsLoginServerSynonym added in v1.12.0

func IsLoginServerSynonym(val any) bool

IsLoginServerSynonym reports whether a URL is a drop-in replacement for the primary Tailscale login server.

func IsReadonlyContext added in v1.4.0

func IsReadonlyContext(ctx context.Context) bool

IsReadonlyContext reports whether ctx is a read-only context, as currently used by Unix non-root users running the "tailscale" CLI command. They can run "status", but not much else.

func PutStoreInt added in v1.32.0

func PutStoreInt(store StateStore, id StateKey, val int64) error

PutStoreInt puts an integer into a StateStore.

func ReadMsg

func ReadMsg(r io.Reader) ([]byte, error)

TODO(apenwarr): incremental json decode? That would let us avoid storing the whole byte array uselessly in RAM.

func ReadStoreInt added in v1.32.0

func ReadStoreInt(store StateStore, id StateKey) (int64, error)

ReadStoreInt reads an integer from a StateStore.

func ReadonlyContextOf added in v1.4.0

func ReadonlyContextOf(ctx context.Context) context.Context

ReadonlyContextOf returns ctx wrapped with a context value that will make IsReadonlyContext reports true.

func SavePrefs

func SavePrefs(filename string, p *Prefs)

func WriteMsg

func WriteMsg(w io.Writer, b []byte) error

Types

type Backend

type Backend interface {
	// SetNotifyCallback sets the callback to be called on updates
	// from the backend to the client.
	SetNotifyCallback(func(Notify))
	// Start starts or restarts the backend, typically when a
	// frontend client connects.
	Start(Options) error
	// StartLoginInteractive requests to start a new interactive login
	// flow. This should trigger a new BrowseToURL notification
	// eventually.
	StartLoginInteractive()
	// Login logs in with an OAuth2 token.
	Login(token *tailcfg.Oauth2Token)
	// Logout terminates the current login session and stops the
	// wireguard engine.
	Logout()
	// SetPrefs installs a new set of user preferences, including
	// WantRunning. This may cause the wireguard engine to
	// reconfigure or stop.
	SetPrefs(*Prefs)
	// RequestEngineStatus polls for an update from the wireguard
	// engine. Only needed if you want to display byte
	// counts. Connection events are emitted automatically without
	// polling.
	RequestEngineStatus()
}

Backend is the interface between Tailscale frontends (e.g. cmd/tailscale, iOS/MacOS/Windows GUIs) and the tailscale backend (e.g. cmd/tailscaled) running on the same machine. (It has nothing to do with the interface between the backends and the cloud control plane.)

type BackendClient

type BackendClient struct {

	// AllowVersionSkew controls whether to allow mismatched
	// frontend & backend versions.
	AllowVersionSkew bool
	// contains filtered or unexported fields
}

func NewBackendClient

func NewBackendClient(logf logger.Logf, sendCommandMsg func(jsonb []byte)) *BackendClient

func (*BackendClient) GotNotifyMsg

func (bc *BackendClient) GotNotifyMsg(b []byte)

func (*BackendClient) Login added in v1.0.0

func (bc *BackendClient) Login(token *tailcfg.Oauth2Token)

func (*BackendClient) Logout

func (bc *BackendClient) Logout()

func (*BackendClient) Quit

func (bc *BackendClient) Quit() error

func (*BackendClient) RequestEngineStatus

func (bc *BackendClient) RequestEngineStatus()

func (*BackendClient) RequestStatus added in v0.98.0

func (bc *BackendClient) RequestStatus()

func (*BackendClient) SetNotifyCallback added in v0.98.0

func (bc *BackendClient) SetNotifyCallback(fn func(Notify))

func (*BackendClient) SetPrefs

func (bc *BackendClient) SetPrefs(new *Prefs)

func (*BackendClient) Start

func (bc *BackendClient) Start(opts Options) error

func (*BackendClient) StartLoginInteractive

func (bc *BackendClient) StartLoginInteractive()

type BackendServer

type BackendServer struct {
	GotQuit bool // a Quit command was received
	// contains filtered or unexported fields
}

func NewBackendServer

func NewBackendServer(logf logger.Logf, b Backend, sendNotifyMsg func(Notify)) *BackendServer

NewBackendServer creates a new BackendServer using b.

If sendNotifyMsg is non-nil, it additionally sets the Backend's notification callback to call the func with ipn.Notify messages in JSON form. If nil, it does not change the notification callback.

func (*BackendServer) GotCommand

func (bs *BackendServer) GotCommand(ctx context.Context, cmd *Command) error

func (*BackendServer) GotCommandMsg

func (bs *BackendServer) GotCommandMsg(ctx context.Context, b []byte) error

GotCommandMsg parses the incoming message b as a JSON Command and calls GotCommand with it.

func (*BackendServer) SendErrorMessage added in v1.0.0

func (bs *BackendServer) SendErrorMessage(msg string)

func (*BackendServer) SendInUseOtherUserErrorMessage added in v1.2.1

func (bs *BackendServer) SendInUseOtherUserErrorMessage(msg string)

SendInUseOtherUserErrorMessage sends a Notify message to the client that both sets the state to 'InUseOtherUser' and sets the associated reason to msg.

type Command

type Command struct {

	// Version is the binary version of the frontend (the client).
	Version string

	// AllowVersionSkew controls whether it's permitted for the
	// client and server to have a different version. The default
	// (false) means to be strict.
	AllowVersionSkew bool

	// Exactly one of the following must be non-nil.
	Quit                  *NoArgs
	Start                 *StartArgs
	StartLoginInteractive *NoArgs
	Login                 *tailcfg.Oauth2Token
	Logout                *NoArgs
	SetPrefs              *SetPrefsArgs
	RequestEngineStatus   *NoArgs
	RequestStatus         *NoArgs
	// contains filtered or unexported fields
}

Command is a command message that is JSON encoded and sent by a frontend to a backend.

type EngineStatus

type EngineStatus struct {
	RBytes, WBytes int64
	NumLive        int
	LiveDERPs      int // number of active DERP connections
	LivePeers      map[key.NodePublic]ipnstate.PeerStatusLite
}

EngineStatus contains WireGuard engine stats.

type ExitNodeLocalIPError added in v1.24.0

type ExitNodeLocalIPError struct {
	// contains filtered or unexported fields
}

ExitNodeLocalIPError is returned when the requested IP address for an exit node belongs to the local machine.

func (ExitNodeLocalIPError) Error added in v1.24.0

func (e ExitNodeLocalIPError) Error() string

type Handle

type Handle struct {
	// contains filtered or unexported fields
}

func NewHandle

func NewHandle(b Backend, logf logger.Logf, notify func(Notify), opts Options) (*Handle, error)

func (*Handle) AdminPageURL

func (h *Handle) AdminPageURL() string

func (*Handle) EngineStatus

func (h *Handle) EngineStatus() EngineStatus

func (*Handle) Expiry

func (h *Handle) Expiry() time.Time

func (*Handle) LocalAddrs

func (h *Handle) LocalAddrs() []netip.Prefix

func (*Handle) Login added in v1.0.0

func (h *Handle) Login(token *tailcfg.Oauth2Token)

func (*Handle) Logout

func (h *Handle) Logout()

func (*Handle) NetMap

func (h *Handle) NetMap() *netmap.NetworkMap

func (*Handle) Prefs

func (h *Handle) Prefs() *Prefs

func (*Handle) RequestEngineStatus

func (h *Handle) RequestEngineStatus()

func (*Handle) Reset

func (h *Handle) Reset()

func (*Handle) SetNotifyCallback added in v1.8.0

func (h *Handle) SetNotifyCallback(notify func(Notify))

func (*Handle) Start

func (h *Handle) Start(opts Options) error

func (*Handle) StartLoginInteractive

func (h *Handle) StartLoginInteractive()

func (*Handle) State

func (h *Handle) State() State

func (*Handle) UpdatePrefs

func (h *Handle) UpdatePrefs(updateFn func(p *Prefs))

type MaskedPrefs added in v1.8.0

type MaskedPrefs struct {
	Prefs

	ControlURLSet             bool `json:",omitempty"`
	RouteAllSet               bool `json:",omitempty"`
	AllowSingleHostsSet       bool `json:",omitempty"`
	ExitNodeIDSet             bool `json:",omitempty"`
	ExitNodeIPSet             bool `json:",omitempty"`
	ExitNodeAllowLANAccessSet bool `json:",omitempty"`
	CorpDNSSet                bool `json:",omitempty"`
	RunSSHSet                 bool `json:",omitempty"`
	WantRunningSet            bool `json:",omitempty"`
	LoggedOutSet              bool `json:",omitempty"`
	ShieldsUpSet              bool `json:",omitempty"`
	AdvertiseTagsSet          bool `json:",omitempty"`
	HostnameSet               bool `json:",omitempty"`
	NotepadURLsSet            bool `json:",omitempty"`
	ForceDaemonSet            bool `json:",omitempty"`
	EggSet                    bool `json:",omitempty"`
	AdvertiseRoutesSet        bool `json:",omitempty"`
	NoSNATSet                 bool `json:",omitempty"`
	NetfilterModeSet          bool `json:",omitempty"`
	OperatorUserSet           bool `json:",omitempty"`
}

MaskedPrefs is a Prefs with an associated bitmask of which fields are set.

func (*MaskedPrefs) Pretty added in v1.8.0

func (m *MaskedPrefs) Pretty() string

type NoArgs

type NoArgs struct{}

type Notify

type Notify struct {
	Version string // version number of IPN backend

	// ErrMessage, if non-nil, contains a critical error message.
	// For State InUseOtherUser, ErrMessage is not critical and just contains the details.
	ErrMessage *string

	LoginFinished *empty.Message     // non-nil when/if the login process succeeded
	State         *State             // if non-nil, the new or current IPN state
	Prefs         *Prefs             // if non-nil, the new or current preferences
	NetMap        *netmap.NetworkMap // if non-nil, the new or current netmap
	Engine        *EngineStatus      // if non-nil, the new or current wireguard stats
	BrowseToURL   *string            // if non-nil, UI should open a browser right now
	BackendLogID  *string            // if non-nil, the public logtail ID used by backend

	// FilesWaiting if non-nil means that files are buffered in
	// the Tailscale daemon and ready for local transfer to the
	// user's preferred storage location.
	FilesWaiting *empty.Message `json:",omitempty"`

	// IncomingFiles, if non-nil, specifies which files are in the
	// process of being received. A nil IncomingFiles means this
	// Notify should not update the state of file transfers. A non-nil
	// but empty IncomingFiles means that no files are in the middle
	// of being transferred.
	IncomingFiles []PartialFile `json:",omitempty"`

	// LocalTCPPort, if non-nil, informs the UI frontend which
	// (non-zero) localhost TCP port it's listening on.
	// This is currently only used by Tailscale when run in the
	// macOS Network Extension.
	LocalTCPPort *uint16 `json:",omitempty"`
	// contains filtered or unexported fields
}

Notify is a communication from a backend (e.g. tailscaled) to a frontend (cmd/tailscale, iOS, macOS, Win Tasktray). In any given notification, any or all of these may be nil, meaning that they have not changed. They are JSON-encoded on the wire, despite the lack of struct tags.

func (Notify) String added in v1.8.0

func (n Notify) String() string

type Options

type Options struct {
	// FrontendLogID is the public logtail id used by the frontend.
	FrontendLogID string
	// StateKey and Prefs together define the state the backend should
	// use:
	//  - StateKey=="" && Prefs!=nil: use Prefs for internal state,
	//    don't persist changes in the backend, except for the machine key
	//    for migration purposes.
	//  - StateKey!="" && Prefs==nil: load the given backend-side
	//    state and use/update that.
	//  - StateKey!="" && Prefs!=nil: like the previous case, but do
	//    an initial overwrite of backend state with Prefs.
	//
	// NOTE(apenwarr): The above means that this Prefs field does not do
	// what you probably think it does. It will overwrite your encryption
	// keys. Do not use unless you know what you're doing.
	StateKey StateKey
	Prefs    *Prefs
	// UpdatePrefs, if provided, overrides Options.Prefs *and* the Prefs
	// already stored in the backend state, *except* for the Persist
	// Persist member. If you just want to provide prefs, this is
	// probably what you want.
	//
	// UpdatePrefs.Persist is always ignored. Prefs.Persist will still
	// be used even if UpdatePrefs is provided. Other than Persist,
	// UpdatePrefs takes precedence over Prefs.
	//
	// This is intended as a purely temporary workaround for the
	// currently unexpected behaviour of Options.Prefs.
	//
	// TODO(apenwarr): Remove this, or rename Prefs to something else
	//   and rename this to Prefs. Or, move Prefs.Persist elsewhere
	//   entirely (as it always should have been), and then we wouldn't
	//   need two separate fields at all. Or, move the fancy state
	//   migration stuff out of Start().
	UpdatePrefs *Prefs
	// AuthKey is an optional node auth key used to authorize a
	// new node key without user interaction.
	AuthKey string
}

type PartialFile added in v1.8.0

type PartialFile struct {
	Name         string    // e.g. "foo.jpg"
	Started      time.Time // time transfer started
	DeclaredSize int64     // or -1 if unknown
	Received     int64     // bytes copied thus far

	// PartialPath is set non-empty in "direct" file mode to the
	// in-progress '*.partial' file's path when the peerapi isn't
	// being used; see LocalBackend.SetDirectFileRoot.
	PartialPath string `json:",omitempty"`

	// Done is set in "direct" mode when the partial file has been
	// closed and is ready for the caller to rename away the
	// ".partial" suffix.
	Done bool `json:",omitempty"`
}

PartialFile represents an in-progress file transfer.

type Prefs

type Prefs struct {
	// ControlURL is the URL of the control server to use.
	//
	// If empty, the default for new installs, DefaultControlURL
	// is used. It's set non-empty once the daemon has been started
	// for the first time.
	//
	// TODO(apenwarr): Make it safe to update this with SetPrefs().
	// Right now, you have to pass it in the initial prefs in Start(),
	// which is the only code that actually uses the ControlURL value.
	// It would be more consistent to restart controlclient
	// automatically whenever this variable changes.
	//
	// Meanwhile, you have to provide this as part of Options.Prefs or
	// Options.UpdatePrefs when calling Backend.Start().
	ControlURL string

	// RouteAll specifies whether to accept subnets advertised by
	// other nodes on the Tailscale network. Note that this does not
	// include default routes (0.0.0.0/0 and ::/0), those are
	// controlled by ExitNodeID/IP below.
	RouteAll bool

	// AllowSingleHosts specifies whether to install routes for each
	// node IP on the tailscale network, in addition to a route for
	// the whole network.
	// This corresponds to the "tailscale up --host-routes" value,
	// which defaults to true.
	//
	// TODO(danderson): why do we have this? It dumps a lot of stuff
	// into the routing table, and a single network route _should_ be
	// all that we need. But when I turn this off in my tailscaled,
	// packets stop flowing. What's up with that?
	AllowSingleHosts bool

	// ExitNodeID and ExitNodeIP specify the node that should be used
	// as an exit node for internet traffic. At most one of these
	// should be non-zero.
	//
	// The preferred way to express the chosen node is ExitNodeID, but
	// in some cases it's not possible to use that ID (e.g. in the
	// linux CLI, before tailscaled has a netmap). For those
	// situations, we allow specifying the exit node by IP, and
	// ipnlocal.LocalBackend will translate the IP into an ID when the
	// node is found in the netmap.
	//
	// If the selected exit node doesn't exist (e.g. it's not part of
	// the current tailnet), or it doesn't offer exit node services, a
	// blackhole route will be installed on the local system to
	// prevent any traffic escaping to the local network.
	ExitNodeID tailcfg.StableNodeID
	ExitNodeIP netip.Addr

	// ExitNodeAllowLANAccess indicates whether locally accessible subnets should be
	// routed directly or via the exit node.
	ExitNodeAllowLANAccess bool

	// CorpDNS specifies whether to install the Tailscale network's
	// DNS configuration, if it exists.
	CorpDNS bool

	// RunSSH bool is whether this node should run an SSH
	// server, permitting access to peers according to the
	// policies as configured by the Tailnet's admin(s).
	RunSSH bool

	// WantRunning indicates whether networking should be active on
	// this node.
	WantRunning bool

	// LoggedOut indicates whether the user intends to be logged out.
	// There are other reasons we may be logged out, including no valid
	// keys.
	// We need to remember this state so that, on next startup, we can
	// generate the "Login" vs "Connect" buttons correctly, without having
	// to contact the server to confirm our nodekey status first.
	LoggedOut bool

	// ShieldsUp indicates whether to block all incoming connections,
	// regardless of the control-provided packet filter. If false, we
	// use the packet filter as provided. If true, we block incoming
	// connections. This overrides tailcfg.Hostinfo's ShieldsUp.
	ShieldsUp bool

	// AdvertiseTags specifies groups that this node wants to join, for
	// purposes of ACL enforcement. These can be referenced from the ACL
	// security policy. Note that advertising a tag doesn't guarantee that
	// the control server will allow you to take on the rights for that
	// tag.
	AdvertiseTags []string

	// Hostname is the hostname to use for identifying the node. If
	// not set, os.Hostname is used.
	Hostname string

	// NotepadURLs is a debugging setting that opens OAuth URLs in
	// notepad.exe on Windows, rather than loading them in a browser.
	//
	// apenwarr 2020-04-29: Unfortunately this is still needed sometimes.
	// Windows' default browser setting is sometimes screwy and this helps
	// users narrow it down a bit.
	NotepadURLs bool

	// ForceDaemon specifies whether a platform that normally
	// operates in "client mode" (that is, requires an active user
	// logged in with the GUI app running) should keep running after the
	// GUI ends and/or the user logs out.
	//
	// The only current applicable platform is Windows. This
	// forced Windows to go into "server mode" where Tailscale is
	// running even with no users logged in. This might also be
	// used for macOS in the future. This setting has no effect
	// for Linux/etc, which always operate in daemon mode.
	ForceDaemon bool `json:"ForceDaemon,omitempty"`

	// Egg is a optional debug flag.
	Egg bool

	// AdvertiseRoutes specifies CIDR prefixes to advertise into the
	// Tailscale network as reachable through the current
	// node.
	AdvertiseRoutes []netip.Prefix

	// NoSNAT specifies whether to source NAT traffic going to
	// destinations in AdvertiseRoutes. The default is to apply source
	// NAT, which makes the traffic appear to come from the router
	// machine rather than the peer's Tailscale IP.
	//
	// Disabling SNAT requires additional manual configuration in your
	// network to route Tailscale traffic back to the subnet relay
	// machine.
	//
	// Linux-only.
	NoSNAT bool

	// NetfilterMode specifies how much to manage netfilter rules for
	// Tailscale, if at all.
	NetfilterMode preftype.NetfilterMode

	// OperatorUser is the local machine user name who is allowed to
	// operate tailscaled without being root or using sudo.
	OperatorUser string `json:",omitempty"`

	// The Persist field is named 'Config' in the file for backward
	// compatibility with earlier versions.
	// TODO(apenwarr): We should move this out of here, it's not a pref.
	//  We can maybe do that once we're sure which module should persist
	//  it (backend or frontend?)
	Persist *persist.Persist `json:"Config"`
}

Prefs are the user modifiable settings of the Tailscale node agent.

func LoadPrefs

func LoadPrefs(filename string) (*Prefs, error)

LoadPrefs loads a legacy relaynode config file into Prefs with sensible migration defaults set.

func NewPrefs

func NewPrefs() *Prefs

NewPrefs returns the default preferences to use.

func PrefsFromBytes

func PrefsFromBytes(b []byte) (*Prefs, error)

PrefsFromBytes deserializes Prefs from a JSON blob.

func (*Prefs) AdminPageURL added in v1.12.0

func (p *Prefs) AdminPageURL() string

AdminPageURL returns the admin web site URL for the current ControlURL.

func (*Prefs) AdvertisesExitNode added in v1.20.0

func (p *Prefs) AdvertisesExitNode() bool

AdvertisesExitNode reports whether p is advertising both the v4 and v6 /0 exit node routes.

func (*Prefs) ApplyEdits added in v1.8.0

func (p *Prefs) ApplyEdits(m *MaskedPrefs)

ApplyEdits mutates p, assigning fields from m.Prefs for each MaskedPrefs Set field that's true.

func (*Prefs) ClearExitNode added in v1.24.0

func (p *Prefs) ClearExitNode()

ClearExitNode sets the ExitNodeID and ExitNodeIP to their zero values.

func (*Prefs) Clone

func (src *Prefs) Clone() *Prefs

Clone makes a deep copy of Prefs. The result aliases no memory with the original.

func (*Prefs) ControlURLOrDefault added in v1.8.0

func (p *Prefs) ControlURLOrDefault() string

ControlURLOrDefault returns the coordination server's URL base.

If not configured, or if the configured value is a legacy name equivalent to the default, then DefaultControlURL is returned instead.

func (*Prefs) Equals

func (p *Prefs) Equals(p2 *Prefs) bool

func (*Prefs) IsEmpty

func (p *Prefs) IsEmpty() bool

IsEmpty reports whether p is nil or pointing to a Prefs zero value.

func (*Prefs) Pretty

func (p *Prefs) Pretty() string

func (*Prefs) SetAdvertiseExitNode added in v1.20.0

func (p *Prefs) SetAdvertiseExitNode(runExit bool)

SetAdvertiseExitNode mutates p (if non-nil) to add or remove the two /0 exit node routes.

func (*Prefs) SetExitNodeIP added in v1.24.0

func (p *Prefs) SetExitNodeIP(s string, st *ipnstate.Status) error

SetExitNodeIP validates and sets the ExitNodeIP from a user-provided string specifying either an IP address or a MagicDNS base name ("foo", as opposed to "foo.bar.beta.tailscale.net"). This method does not mutate ExitNodeID and will fail if ExitNodeID is already set.

func (*Prefs) ShouldSSHBeRunning added in v1.26.0

func (p *Prefs) ShouldSSHBeRunning() bool

ShouldSSHBeRunning reports whether the SSH server should be running based on the prefs.

func (*Prefs) ToBytes

func (p *Prefs) ToBytes() []byte

type SetPrefsArgs

type SetPrefsArgs struct {
	New *Prefs
}

type StartArgs

type StartArgs struct {
	Opts Options
}

type State

type State int

func (State) String

func (s State) String() string

type StateKey

type StateKey string

StateKey is an opaque identifier for a set of LocalBackend state (preferences, private keys, etc.).

The reason we need this is that the Tailscale agent may be running on a multi-user machine, in a context where a single daemon is shared by several consecutive users. Ideally we would just use the username of the connected frontend as the StateKey.

Various platforms currently set StateKey in different ways:

  • the macOS/iOS GUI apps set it to "ipn-go-bridge"
  • the Android app sets it to "ipn-android"
  • on Windows, it's the empty string (in client mode) or, via LocalBackend.userID, a string like "user-$USER_ID" (used in server mode).
  • on Linux/etc, it's always "_daemon" (ipn.GlobalDaemonStateKey)

Additionally, the StateKey can be debug setting name:

  • "_debug_magicsock_until" with value being a unix timestamp stringified
  • "_debug_<component>_until" with value being a unix timestamp stringified

type StateStore

type StateStore interface {
	// ReadState returns the bytes associated with ID. Returns (nil,
	// ErrStateNotExist) if the ID doesn't have associated state.
	ReadState(id StateKey) ([]byte, error)
	// WriteState saves bs as the state associated with ID.
	WriteState(id StateKey, bs []byte) error
}

StateStore persists state, and produces it back on request.

Directories

Path Synopsis
Package ipnstate captures the entire state of the Tailscale network.
Package ipnstate captures the entire state of the Tailscale network.
Package localapi contains the HTTP server handlers for tailscaled's API server.
Package localapi contains the HTTP server handlers for tailscaled's API server.
Package policy contains various policy decisions that need to be shared between the node client & control server.
Package policy contains various policy decisions that need to be shared between the node client & control server.
Package store provides various implementation of ipn.StateStore.
Package store provides various implementation of ipn.StateStore.
awsstore
Package awsstore contains an ipn.StateStore implementation using AWS SSM.
Package awsstore contains an ipn.StateStore implementation using AWS SSM.
mem
Package mem provides an in-memory ipn.StateStore implementation.
Package mem provides an in-memory ipn.StateStore implementation.

Jump to

Keyboard shortcuts

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