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
- Variables
- func IPCVersion() string
- func IsLoginServerSynonym(val any) bool
- func IsReadonlyContext(ctx context.Context) bool
- func PutStoreInt(store StateStore, id StateKey, val int64) error
- func ReadMsg(r io.Reader) ([]byte, error)
- func ReadStoreInt(store StateStore, id StateKey) (int64, error)
- func ReadonlyContextOf(ctx context.Context) context.Context
- func SavePrefs(filename string, p *Prefs)
- func WriteMsg(w io.Writer, b []byte) error
- type Backend
- type BackendClient
- func (bc *BackendClient) GotNotifyMsg(b []byte)
- func (bc *BackendClient) Login(token *tailcfg.Oauth2Token)
- func (bc *BackendClient) Logout()
- func (bc *BackendClient) Quit() error
- func (bc *BackendClient) RequestEngineStatus()
- func (bc *BackendClient) RequestStatus()
- func (bc *BackendClient) SetNotifyCallback(fn func(Notify))
- func (bc *BackendClient) SetPrefs(new *Prefs)
- func (bc *BackendClient) Start(opts Options) error
- func (bc *BackendClient) StartLoginInteractive()
- type BackendServer
- type Command
- type EngineStatus
- type ExitNodeLocalIPError
- type Handle
- func (h *Handle) AdminPageURL() string
- func (h *Handle) EngineStatus() EngineStatus
- func (h *Handle) Expiry() time.Time
- func (h *Handle) LocalAddrs() []netip.Prefix
- func (h *Handle) Login(token *tailcfg.Oauth2Token)
- func (h *Handle) Logout()
- func (h *Handle) NetMap() *netmap.NetworkMap
- func (h *Handle) Prefs() *Prefs
- func (h *Handle) RequestEngineStatus()
- func (h *Handle) Reset()
- func (h *Handle) SetNotifyCallback(notify func(Notify))
- func (h *Handle) Start(opts Options) error
- func (h *Handle) StartLoginInteractive()
- func (h *Handle) State() State
- func (h *Handle) UpdatePrefs(updateFn func(p *Prefs))
- type MaskedPrefs
- type NoArgs
- type Notify
- type Options
- type PartialFile
- type Prefs
- func (p *Prefs) AdminPageURL() string
- func (p *Prefs) AdvertisesExitNode() bool
- func (p *Prefs) ApplyEdits(m *MaskedPrefs)
- func (p *Prefs) ClearExitNode()
- func (src *Prefs) Clone() *Prefs
- func (p *Prefs) ControlURLOrDefault() string
- func (p *Prefs) Equals(p2 *Prefs) bool
- func (p *Prefs) IsEmpty() bool
- func (p *Prefs) Pretty() string
- func (p *Prefs) SetAdvertiseExitNode(runExit bool)
- func (p *Prefs) SetExitNodeIP(s string, st *ipnstate.Status) error
- func (p *Prefs) ShouldSSHBeRunning() bool
- func (p *Prefs) ToBytes() []byte
- type SetPrefsArgs
- type StartArgs
- type State
- type StateKey
- type StateStore
Constants ¶
const ( NoState = State(iota) InUseOtherUser NeedsLogin NeedsMachineAuth Stopped Starting Running )
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") )
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.
const ErrMsgPermissionDenied = "permission denied"
ErrMsgPermissionDenied is the Notify.ErrMessage value used an operation was done from a user/context that didn't have permission.
const GoogleIDTokenType = "ts_android_google_login"
GoogleIDToken Type is the tailcfg.Oauth2Token.TokenType for the Google ID tokens used by the Android client.
const MaxMessageSize = 10 << 20
MaxMessageSize is the maximum message size, in bytes.
Variables ¶
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") )
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
IsLoginServerSynonym reports whether a URL is a drop-in replacement for the primary Tailscale login server.
func IsReadonlyContext ¶ added in v1.4.0
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 ¶
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
ReadonlyContextOf returns ctx wrapped with a context value that will make IsReadonlyContext reports true.
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 (*Handle) AdminPageURL ¶
func (*Handle) EngineStatus ¶
func (h *Handle) EngineStatus() EngineStatus
func (*Handle) LocalAddrs ¶
func (*Handle) Login ¶ added in v1.0.0
func (h *Handle) Login(token *tailcfg.Oauth2Token)
func (*Handle) NetMap ¶
func (h *Handle) NetMap() *netmap.NetworkMap
func (*Handle) RequestEngineStatus ¶
func (h *Handle) RequestEngineStatus()
func (*Handle) SetNotifyCallback ¶ added in v1.8.0
func (*Handle) StartLoginInteractive ¶
func (h *Handle) StartLoginInteractive()
func (*Handle) UpdatePrefs ¶
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 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.
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 ¶
LoadPrefs loads a legacy relaynode config file into Prefs with sensible migration defaults set.
func PrefsFromBytes ¶
PrefsFromBytes deserializes Prefs from a JSON blob.
func (*Prefs) AdminPageURL ¶ added in v1.12.0
AdminPageURL returns the admin web site URL for the current ControlURL.
func (*Prefs) AdvertisesExitNode ¶ added in v1.20.0
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 ¶
Clone makes a deep copy of Prefs. The result aliases no memory with the original.
func (*Prefs) ControlURLOrDefault ¶ added in v1.8.0
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) SetAdvertiseExitNode ¶ added in v1.20.0
SetAdvertiseExitNode mutates p (if non-nil) to add or remove the two /0 exit node routes.
func (*Prefs) SetExitNodeIP ¶ added in v1.24.0
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
ShouldSSHBeRunning reports whether the SSH server should be running based on the prefs.
type SetPrefsArgs ¶
type SetPrefsArgs struct {
New *Prefs
}
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.
Source Files ¶
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. |