tailcfg

package
v1.4.2 Latest Latest
Warning

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

Go to latest
Published: Feb 2, 2021 License: BSD-3-Clause Imports: 14 Imported by: 181

Documentation

Index

Constants

View Source
const (
	CapRead  = CapType("read")
	CapWrite = CapType("write")
)
View Source
const (
	MachineUnknown      = MachineStatus(iota)
	MachineUnauthorized // server has yet to approve
	MachineAuthorized   // server has approved
	MachineInvalid      // server has explicitly rejected this machine key
)
View Source
const (
	TCP = ServiceProto("tcp")
	UDP = ServiceProto("udp")
)
View Source
const CurrentMapRequestVersion = 10

CurrentMapRequestVersion is the current MapRequest.Version value.

History of versions:

 3: implicit compression, keep-alives
 4: opt-in keep-alives via KeepAlive field, opt-in compression via Compress
 5: 2020-10-19, implies IncludeIPv6, delta Peers/UserProfiles, supports MagicDNS
 6: 2020-12-07: means MapResponse.PacketFilter nil means unchanged
 7: 2020-12-15: FilterRule.SrcIPs accepts CIDRs+ranges, doesn't warn about 0.0.0.0/::
 8: 2020-12-19: client can receive IPv6 addresses and routes if beta enabled server-side
 9: 2020-12-30: client doesn't auto-add implicit search domains from peers; only DNSConfig.Domains
10: 2021-01-17: client understands MapResponse.PeerSeenChange

Variables

View Source
var FilterAllowAll = []FilterRule{
	{
		SrcIPs:  []string{"*"},
		SrcBits: nil,
		DstPorts: []NetPortRange{{
			IP:    "*",
			Bits:  nil,
			Ports: PortRange{0, 65535},
		}},
	},
}
View Source
var PortRangeAny = PortRange{0, 65535}

Functions

func CheckTag added in v0.98.1

func CheckTag(tag string) error

CheckTag validates tag for use as an ACL tag. For now we allow only ascii alphanumeric tags, and they need to start with a letter. No unicode shenanigans allowed, and we reserve punctuation marks other than '-' for a possible future URI scheme.

Because we're ignoring unicode entirely, we can treat utf-8 as a series of bytes. Anything >= 128 is disqualified anyway.

We might relax these rules later.

func Clone added in v1.2.0

func Clone(dst, src interface{}) bool

Clone duplicates src into dst and reports whether it succeeded. To succeed, <src, dst> must be of types <*T, *T> or <*T, **T>, where T is one of User,Node,Hostinfo,NetInfo,Group,Role,Capability,Login,DNSConfig,RegisterResponse.

Types

type CapType

type CapType string

type Capability

type Capability struct {
	ID   CapabilityID
	Type CapType
	Val  ID
}

func (*Capability) Clone added in v1.2.0

func (src *Capability) Clone() *Capability

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

type CapabilityID

type CapabilityID ID

func (CapabilityID) String

func (id CapabilityID) String() string

type DERPMap added in v0.98.1

type DERPMap struct {
	// Regions is the set of geographic regions running DERP node(s).
	//
	// It's keyed by the DERPRegion.RegionID.
	//
	// The numbers are not necessarily contiguous.
	Regions map[int]*DERPRegion
}

DERPMap describes the set of DERP packet relay servers that are available.

func (*DERPMap) RegionIDs added in v0.98.1

func (m *DERPMap) RegionIDs() []int

/ RegionIDs returns the sorted region IDs.

type DERPNode added in v0.98.1

type DERPNode struct {
	// Name is a unique node name (across all regions).
	// It is not a host name.
	// It's typically of the form "1b", "2a", "3b", etc. (region
	// ID + suffix within that region)
	Name string

	// RegionID is the RegionID of the DERPRegion that this node
	// is running in.
	RegionID int

	// HostName is the DERP node's hostname.
	//
	// It is required but need not be unique; multiple nodes may
	// have the same HostName but vary in configuration otherwise.
	HostName string

	// CertName optionally specifies the expected TLS cert common
	// name. If empty, HostName is used. If CertName is non-empty,
	// HostName is only used for the TCP dial (if IPv4/IPv6 are
	// not present) + TLS ClientHello.
	CertName string `json:",omitempty"`

	// IPv4 optionally forces an IPv4 address to use, instead of using DNS.
	// If empty, A record(s) from DNS lookups of HostName are used.
	// If the string is not an IPv4 address, IPv4 is not used; the
	// conventional string to disable IPv4 (and not use DNS) is
	// "none".
	IPv4 string `json:",omitempty"`

	// IPv6 optionally forces an IPv6 address to use, instead of using DNS.
	// If empty, AAAA record(s) from DNS lookups of HostName are used.
	// If the string is not an IPv6 address, IPv6 is not used; the
	// conventional string to disable IPv6 (and not use DNS) is
	// "none".
	IPv6 string `json:",omitempty"`

	// Port optionally specifies a STUN port to use.
	// Zero means 3478.
	// To disable STUN on this node, use -1.
	STUNPort int `json:",omitempty"`

	// STUNOnly marks a node as only a STUN server and not a DERP
	// server.
	STUNOnly bool `json:",omitempty"`

	// DERPTestPort is used in tests to override the port, instead
	// of using the default port of 443. If non-zero, TLS
	// verification is skipped.
	DERPTestPort int `json:",omitempty"`

	// STUNTestIP is used in tests to override the STUN server's IP.
	// If empty, it's assumed to be the same as the DERP server.
	STUNTestIP string `json:",omitempty"`
}

DERPNode describes a DERP packet relay node running within a DERPRegion.

type DERPRegion added in v0.98.1

type DERPRegion struct {
	// RegionID is a unique integer for a geographic region.
	//
	// It corresponds to the legacy derpN.tailscale.com hostnames
	// used by older clients. (Older clients will continue to resolve
	// derpN.tailscale.com when contacting peers, rather than use
	// the server-provided DERPMap)
	//
	// RegionIDs must be non-zero, positive, and guaranteed to fit
	// in a JavaScript number.
	RegionID int

	// RegionCode is a short name for the region. It's usually a popular
	// city or airport code in the region: "nyc", "sf", "sin",
	// "fra", etc.
	RegionCode string

	// RegionName is a long English name for the region: "New York City",
	// "San Francisco", "Singapore", "Frankfurt", etc.
	RegionName string

	// Nodes are the DERP nodes running in this region, in
	// priority order for the current client. Client TLS
	// connections should ideally only go to the first entry
	// (falling back to the second if necessary). STUN packets
	// should go to the first 1 or 2.
	//
	// If nodes within a region route packets amongst themselves,
	// but not to other regions. That said, each user/domain
	// should get a the same preferred node order, so if all nodes
	// for a user/network pick the first one (as they should, when
	// things are healthy), the inter-cluster routing is minimal
	// to zero.
	Nodes []*DERPNode
}

DERPRegion is a geographic region running DERP relay node(s).

Client nodes discover which region they're closest to, advertise that "home" DERP region (previously called "home node", when there was only 1 node per region) and maintain a persistent connection that region as long as it's the closest. Client nodes will further connect to other regions as necessary to communicate with peers advertising other regions as their homes.

type DNSConfig added in v1.0.1

type DNSConfig struct {
	// Nameservers are the IP addresses of the nameservers to use.
	Nameservers []netaddr.IP `json:",omitempty"`
	// Domains are the search domains to use.
	Domains []string `json:",omitempty"`
	// PerDomain indicates whether it is preferred to use Nameservers
	// only for DNS queries for subdomains of Domains.
	// Some OSes and OS configurations don't support per-domain DNS configuration,
	// in which case Nameservers applies to all DNS requests regardless of PerDomain's value.
	PerDomain bool
	// Proxied indicates whether DNS requests are proxied through a tsdns.Resolver.
	// This enables Magic DNS. It is togglable independently of PerDomain.
	Proxied bool
}

DNSConfig is the DNS configuration.

func (*DNSConfig) Clone added in v1.2.0

func (src *DNSConfig) Clone() *DNSConfig

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

type Debug added in v0.98.1

type Debug struct {
	// LogHeapPprof controls whether the client should log
	// its heap pprof data. Each true value sent from the server
	// means that client should do one more log.
	LogHeapPprof bool `json:",omitempty"`

	// LogHeapURL is the URL to POST its heap pprof to.
	// Empty means to not log.
	LogHeapURL string `json:",omitempty"`

	// ForceBackgroundSTUN controls whether magicsock should
	// always do its background STUN queries (see magicsock's
	// periodicReSTUN), regardless of inactivity.
	ForceBackgroundSTUN bool `json:",omitempty"`

	// DERPRoute controls whether the DERP reverse path
	// optimization (see Issue 150) should be enabled or
	// disabled. The environment variable in magicsock is the
	// highest priority (if set), then this (if set), then the
	// binary default value.
	DERPRoute opt.Bool `json:",omitempty"`

	// TrimWGConfig controls whether Tailscale does lazy, on-demand
	// wireguard configuration of peers.
	TrimWGConfig opt.Bool `json:",omitempty"`

	// DisableSubnetsIfPAC controls whether subnet routers should be
	// disabled if WPAD is present on the network.
	DisableSubnetsIfPAC opt.Bool `json:",omitempty"`
}

Debug are instructions from the control server to the client to adjust debug settings.

type DiscoKey added in v0.100.0

type DiscoKey [32]byte

DiscoKey is the curve25519 public key for path discovery key. It's never written to disk or reused between network start-ups.

func (DiscoKey) IsZero added in v0.100.0

func (k DiscoKey) IsZero() bool

IsZero reports whether k is the zero value.

func (DiscoKey) MarshalText added in v0.100.0

func (k DiscoKey) MarshalText() ([]byte, error)

func (DiscoKey) ShortString added in v0.100.0

func (k DiscoKey) ShortString() string

func (DiscoKey) String added in v0.100.0

func (k DiscoKey) String() string

func (*DiscoKey) UnmarshalText added in v0.100.0

func (k *DiscoKey) UnmarshalText(text []byte) error

type FilterRule added in v0.98.1

type FilterRule struct {
	// SrcIPs are the source IPs/networks to match.
	//
	// It may take the following forms:
	//     * an IP address (IPv4 or IPv6)
	//     * the string "*" to match everything (both IPv4 & IPv6)
	//     * a CIDR (e.g. "192.168.0.0/16")
	//     * a range of two IPs, inclusive, separated by hyphen ("2eff::1-2eff::0800")
	SrcIPs []string

	// SrcBits is deprecated; it's the old way to specify a CIDR
	// prior to MapRequest.Version 7. Its values correspond to the
	// SrcIPs above.
	//
	// If an entry of SrcBits is present for the same index as a
	// SrcIPs entry, it changes the SrcIP above to be a network
	// with /n CIDR bits. If the slice is nil or insufficiently
	// long, the default value (for an IPv4 address) for a
	// position is 32, as if the SrcIPs above were a /32 mask. For
	// a "*" SrcIPs value, the corresponding SrcBits value is
	// ignored.
	SrcBits []int `json:",omitempty"`

	// DstPorts are the port ranges to allow once a source IP
	// matches (is in the CIDR described by SrcIPs & SrcBits).
	DstPorts []NetPortRange
}

FilterRule represents one rule in a packet filter.

A rule is logically a set of source CIDRs to match (described by SrcIPs and SrcBits), and a set of destination targets that are then allowed if a source IP is mathces of those CIDRs.

type Group

type Group struct {
	ID      GroupID
	Name    string
	Members []ID
}

func (*Group) Clone added in v1.2.0

func (src *Group) Clone() *Group

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

type GroupID

type GroupID ID

func (GroupID) IsZero added in v1.2.0

func (u GroupID) IsZero() bool

func (GroupID) String

func (id GroupID) String() string

type Hostinfo

type Hostinfo struct {
	// TODO(crawshaw): mark all these fields ",omitempty" when all the
	// iOS apps are updated with the latest swift version of this struct.
	IPNVersion    string             `json:",omitempty"` // version of this code
	FrontendLogID string             `json:",omitempty"` // logtail ID of frontend instance
	BackendLogID  string             `json:",omitempty"` // logtail ID of backend instance
	OS            string             // operating system the client runs on (a version.OS value)
	OSVersion     string             `json:",omitempty"` // operating system version, with optional distro prefix ("Debian 10.4", "Windows 10 Pro 10.0.19041")
	DeviceModel   string             `json:",omitempty"` // mobile phone model ("Pixel 3a", "iPhone 11 Pro")
	Hostname      string             // name of the host the client runs on
	ShieldsUp     bool               `json:",omitempty"` // indicates whether the host is blocking incoming connections
	ShareeNode    bool               `json:",omitempty"` // indicates this node exists in netmap because it's owned by a shared-to user
	GoArch        string             `json:",omitempty"` // the host's GOARCH value (of the running binary)
	RoutableIPs   []netaddr.IPPrefix `json:",omitempty"` // set of IP ranges this client can route
	RequestTags   []string           `json:",omitempty"` // set of ACL tags this node wants to claim
	Services      []Service          `json:",omitempty"` // services advertised by this machine
	NetInfo       *NetInfo           `json:",omitempty"`
}

Hostinfo contains a summary of a Tailscale host.

Because it contains pointers (slices), this type should not be used as a value type.

func (*Hostinfo) CheckRequestTags added in v1.4.0

func (h *Hostinfo) CheckRequestTags() error

CheckRequestTags checks that all of h.RequestTags are valid.

func (*Hostinfo) Clone

func (src *Hostinfo) Clone() *Hostinfo

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

func (*Hostinfo) Equal

func (h *Hostinfo) Equal(h2 *Hostinfo) bool

Equal reports whether h and h2 are equal.

type ID

type ID int64

func (ID) String

func (id ID) String() string

type Login

type Login struct {
	ID            LoginID
	Provider      string
	LoginName     string
	DisplayName   string
	ProfilePicURL string
	Domain        string
	// contains filtered or unexported fields
}

func (*Login) Clone added in v1.2.0

func (src *Login) Clone() *Login

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

type LoginID

type LoginID ID

func (LoginID) IsZero added in v1.2.0

func (u LoginID) IsZero() bool

func (LoginID) String

func (id LoginID) String() string

type MachineKey

type MachineKey [32]byte

MachineKey is the curve25519 public key for a machine.

func (MachineKey) HexString added in v1.2.0

func (k MachineKey) HexString() string

func (MachineKey) IsZero added in v1.2.0

func (k MachineKey) IsZero() bool

IsZero reports whether k is the zero value.

func (MachineKey) MarshalText

func (k MachineKey) MarshalText() ([]byte, error)

func (MachineKey) String

func (k MachineKey) String() string

func (*MachineKey) UnmarshalText

func (k *MachineKey) UnmarshalText(text []byte) error

type MachineStatus

type MachineStatus int

func (MachineStatus) MarshalText

func (m MachineStatus) MarshalText() ([]byte, error)

func (MachineStatus) String

func (m MachineStatus) String() string

func (*MachineStatus) UnmarshalText

func (m *MachineStatus) UnmarshalText(b []byte) error

type MapRequest

type MapRequest struct {
	// Version is incremented whenever the client code changes enough that
	// we want to signal to the control server that we're capable of something
	// different.
	//
	// For current values and history, see CurrentMapRequestVersion above.
	Version int

	Compress    string // "zstd" or "" (no compression)
	KeepAlive   bool   // whether server should send keep-alives back to us
	NodeKey     NodeKey
	DiscoKey    DiscoKey
	Endpoints   []string // caller's endpoints (IPv4 or IPv6)
	IncludeIPv6 bool     `json:",omitempty"` // include IPv6 endpoints in returned Node Endpoints (for Version 4 clients)
	Stream      bool     // if true, multiple MapResponse objects are returned
	Hostinfo    *Hostinfo

	// ReadOnly is whether the client just wants to fetch the
	// MapResponse, without updating their Endpoints. The
	// Endpoints field will be ignored and LastSeen will not be
	// updated and peers will not be notified of changes.
	//
	// The intended use is for clients to discover the DERP map at
	// start-up before their first real endpoint update.
	ReadOnly bool `json:",omitempty"`

	// OmitPeers is whether the client is okay with the Peers list
	// being omitted in the response. (For example, a client on
	// start up using ReadOnly to get the DERP map.)
	//
	// If OmitPeers is true, Stream is false, and ReadOnly is false,
	// then the server will let clients update their endpoints without
	// breaking existing long-polling (Stream == true) connections.
	OmitPeers bool `json:",omitempty"`

	// DebugFlags is a list of strings specifying debugging and
	// development features to enable in handling this map
	// request. The values are deliberately unspecified, as they get
	// added and removed all the time during development, and offer no
	// compatibility promise. To roll out semantic changes, bump
	// Version instead.
	//
	// Current DebugFlags values are:
	//     * "warn-ip-forwarding-off": client is trying to be a subnet
	//       router but their IP forwarding is broken.
	//     * "minimize-netmap": have control minimize the netmap, removing
	//       peers that are unreachable per ACLS.
	DebugFlags []string `json:",omitempty"`
}

MapRequest is sent by a client to start a long-poll network map updates. The request includes a copy of the client's current set of WireGuard endpoints and general host information.

The request is encoded to JSON, encrypted with golang.org/x/crypto/nacl/box, using the local machine key, and sent to:

https://login.tailscale.com/machine/<mkey hex>/map

type MapResponse

type MapResponse struct {
	KeepAlive bool `json:",omitempty"` // if set, all other fields are ignored

	// Networking
	Node    *Node
	DERPMap *DERPMap `json:",omitempty"` // if non-empty, a change in the DERP map.

	// Peers, if non-empty, is the complete list of peers.
	// It will be set in the first MapResponse for a long-polled request/response.
	// Subsequent responses will be delta-encoded if MapRequest.Version >= 5 and server
	// chooses, in which case Peers will be nil or zero length.
	// If Peers is non-empty, PeersChanged and PeersRemoved should
	// be ignored (and should be empty).
	// Peers is always returned sorted by Node.ID.
	Peers []*Node `json:",omitempty"`
	// PeersChanged are the Nodes (identified by their ID) that
	// have changed or been added since the past update on the
	// HTTP response. It's not used by the server if MapRequest.Version < 5.
	// PeersChanged is always returned sorted by Node.ID.
	PeersChanged []*Node `json:",omitempty"`
	// PeersRemoved are the NodeIDs that are no longer in the peer list.
	PeersRemoved []NodeID `json:",omitempty"`

	// PeerSeenChange contains information on how to update peers' LastSeen
	// times. If the value is false, the peer is gone. If the value is true,
	// the LastSeen time is now. Absent means unchanged.
	PeerSeenChange map[NodeID]bool `json:",omitempty"`

	// DNS is the same as DNSConfig.Nameservers.
	//
	// TODO(dmytro): should be sent in DNSConfig.Nameservers once clients have updated.
	DNS []netaddr.IP `json:",omitempty"`

	// SearchPaths is the old way to specify DNS search
	// domains. Clients should use these values if set, but the
	// server will omit this field for clients with
	// MapRequest.Version >= 9. Clients should prefer to use
	// DNSConfig.Domains instead.
	SearchPaths []string `json:",omitempty"`

	// DNSConfig contains the DNS settings for the client to use.
	//
	// TODO(bradfitz): make this a pointer and conditionally sent
	// only if changed, like DERPMap, PacketFilter, etc. It's
	// small, though.
	DNSConfig DNSConfig `json:",omitempty"`

	// Domain is the name of the network that this node is
	// in. It's either of the form "example.com" (for user
	// foo@example.com, for multi-user networks) or
	// "foo@gmail.com" (for siloed users on shared email
	// providers). Its exact form should not be depended on; new
	// forms are coming later.
	Domain string

	// CollectServices reports whether this node's Tailnet has
	// requested that info about services be included in HostInfo.
	// If unset, the most recent non-empty MapResponse value in
	// the HTTP response stream is used.
	CollectServices opt.Bool `json:",omitempty"`

	// PacketFilter are the firewall rules.
	//
	// For MapRequest.Version >= 6, a nil value means the most
	// previously streamed non-nil MapResponse.PacketFilter within
	// the same HTTP response. A non-nil but empty list always means
	// no PacketFilter (that is, to block everything).
	PacketFilter []FilterRule

	UserProfiles []UserProfile // as of 1.1.541 (mapver 5): may be new or updated user profiles only
	Roles        []Role        // deprecated; clients should not rely on Roles

	// Debug is normally nil, except for when the control server
	// is setting debug settings on a node.
	Debug *Debug `json:",omitempty"`
}

type NetInfo

type NetInfo struct {
	// MappingVariesByDestIP says whether the host's NAT mappings
	// vary based on the destination IP.
	MappingVariesByDestIP opt.Bool

	// HairPinning is their router does hairpinning.
	// It reports true even if there's no NAT involved.
	HairPinning opt.Bool

	// WorkingIPv6 is whether IPv6 works.
	WorkingIPv6 opt.Bool

	// WorkingUDP is whether UDP works.
	WorkingUDP opt.Bool

	// UPnP is whether UPnP appears present on the LAN.
	// Empty means not checked.
	UPnP opt.Bool

	// PMP is whether NAT-PMP appears present on the LAN.
	// Empty means not checked.
	PMP opt.Bool

	// PCP is whether PCP appears present on the LAN.
	// Empty means not checked.
	PCP opt.Bool

	// PreferredDERP is this node's preferred DERP server
	// for incoming traffic. The node might be be temporarily
	// connected to multiple DERP servers (to send to other nodes)
	// but PreferredDERP is the instance number that the node
	// subscribes to traffic at.
	// Zero means disconnected or unknown.
	PreferredDERP int

	// LinkType is the current link type, if known.
	LinkType string `json:",omitempty"` // "wired", "wifi", "mobile" (LTE, 4G, 3G, etc)

	// DERPLatency is the fastest recent time to reach various
	// DERP STUN servers, in seconds. The map key is the
	// "regionID-v4" or "-v6"; it was previously the DERP server's
	// STUN host:port.
	//
	// This should only be updated rarely, or when there's a
	// material change, as any change here also gets uploaded to
	// the control plane.
	DERPLatency map[string]float64 `json:",omitempty"`
}

NetInfo contains information about the host's network state.

func (*NetInfo) BasicallyEqual

func (ni *NetInfo) BasicallyEqual(ni2 *NetInfo) bool

BasicallyEqual reports whether ni and ni2 are basically equal, ignoring changes in DERP ServerLatency & RegionLatency.

func (*NetInfo) Clone

func (src *NetInfo) Clone() *NetInfo

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

func (*NetInfo) String

func (ni *NetInfo) String() string

type NetPortRange added in v0.98.1

type NetPortRange struct {
	IP    string // IP, CIDR, Range, or "*" (same formats as FilterRule.SrcIPs)
	Bits  *int   // deprecated; the old way to turn IP into a CIDR
	Ports PortRange
	// contains filtered or unexported fields
}

NetPortRange represents a range of ports that's allowed for one or more IPs.

type Node

type Node struct {
	ID       NodeID
	StableID StableNodeID
	Name     string // DNS

	// User is the user who created the node. If ACL tags are in
	// use for the node then it doesn't reflect the ACL identity
	// that the node is running as.
	User UserID

	// Sharer, if non-zero, is the user who shared this node, if different than User.
	Sharer UserID `json:",omitempty"`

	Key        NodeKey
	KeyExpiry  time.Time
	Machine    MachineKey
	DiscoKey   DiscoKey
	Addresses  []netaddr.IPPrefix // IP addresses of this Node directly
	AllowedIPs []netaddr.IPPrefix // range of IP addresses to route to this node
	Endpoints  []string           `json:",omitempty"` // IP+port (public via STUN, and local LANs)
	DERP       string             `json:",omitempty"` // DERP-in-IP:port ("127.3.3.40:N") endpoint
	Hostinfo   Hostinfo
	Created    time.Time
	LastSeen   *time.Time `json:",omitempty"`

	KeepAlive bool `json:",omitempty"` // open and keep open a connection to this peer

	MachineAuthorized bool `json:",omitempty"` // TODO(crawshaw): replace with MachineStatus

	ComputedName string `json:",omitempty"` // MagicDNS base name (for normal non-shared-in nodes), FQDN (without trailing dot, for shared-in nodes), or Hostname (if no MagicDNS)

	ComputedNameWithHost string `json:",omitempty"` // either "ComputedName" or "ComputedName (computedHostIfDifferent)", if computedHostIfDifferent is set
	// contains filtered or unexported fields
}

func (*Node) Clone

func (src *Node) Clone() *Node

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

func (*Node) DisplayName added in v1.4.0

func (n *Node) DisplayName(forOwner bool) string

DisplayName returns the user-facing name for a node which should be shown in client UIs.

Parameter forOwner specifies whether the name is requested by the owner of the node. When forOwner is false, the hostname is never included in the return value.

Return value is either either "Name" or "Name (Hostname)", where Name is the node's MagicDNS base name (for normal non-shared-in nodes), FQDN (without trailing dot, for shared-in nodes), or Hostname (if no MagicDNS). Hostname is only included in the return value if it varies from Name and forOwner is provided true.

DisplayName is only valid if InitDisplayNames has been called.

func (*Node) DisplayNames added in v1.4.0

func (n *Node) DisplayNames(forOwner bool) (name, hostIfDifferent string)

DisplayName returns the decomposed user-facing name for a node.

Parameter forOwner specifies whether the name is requested by the owner of the node. When forOwner is false, hostIfDifferent is always returned empty.

Return value name is the node's primary name, populated with the node's MagicDNS base name (for normal non-shared-in nodes), FQDN (without trailing dot, for shared-in nodes), or Hostname (if no MagicDNS).

Return value hostIfDifferent, when non-empty, is the node's hostname. hostIfDifferent is only populated when the hostname varies from name and forOwner is provided as true.

DisplayNames is only valid if InitDisplayNames has been called.

func (*Node) Equal

func (n *Node) Equal(n2 *Node) bool

Equal reports whether n and n2 are equal.

func (*Node) InitDisplayNames added in v1.4.0

func (n *Node) InitDisplayNames(networkMagicDNSSuffix string)

InitDisplayNames computes and populates n's display name fields: n.ComputedName, n.computedHostIfDifferent, and n.ComputedNameWithHost.

type NodeID

type NodeID ID

func (NodeID) IsZero added in v1.2.0

func (u NodeID) IsZero() bool

func (NodeID) String

func (id NodeID) String() string

type NodeKey

type NodeKey [32]byte

NodeKey is the curve25519 public key for a node.

func (NodeKey) IsZero

func (k NodeKey) IsZero() bool

IsZero reports whether k is the zero value.

func (NodeKey) MarshalText

func (k NodeKey) MarshalText() ([]byte, error)

func (NodeKey) ShortString added in v0.98.0

func (k NodeKey) ShortString() string

func (NodeKey) String

func (k NodeKey) String() string

func (*NodeKey) UnmarshalText

func (k *NodeKey) UnmarshalText(text []byte) error

type PortRange added in v0.98.1

type PortRange struct {
	First uint16
	Last  uint16
}

PortRange represents a range of UDP or TCP port numbers.

type RegisterRequest

type RegisterRequest struct {
	Version    int // currently 1
	NodeKey    NodeKey
	OldNodeKey NodeKey
	Auth       struct {

		// One of Provider/LoginName, Oauth2Token, or AuthKey is set.
		Provider, LoginName string
		Oauth2Token         *oauth2.Token
		AuthKey             string
		// contains filtered or unexported fields
	}
	Expiry   time.Time // requested key expiry, server policy may override
	Followup string    // response waits until AuthURL is visited
	Hostinfo *Hostinfo
	// contains filtered or unexported fields
}

RegisterRequest is sent by a client to register the key for a node. It is encoded to JSON, encrypted with golang.org/x/crypto/nacl/box, using the local machine key, and sent to:

https://login.tailscale.com/machine/<mkey hex>

func (*RegisterRequest) Clone

func (req *RegisterRequest) Clone() *RegisterRequest

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

TODO: extend cmd/cloner to generate this method.

type RegisterResponse

type RegisterResponse struct {
	User              User
	Login             Login
	NodeKeyExpired    bool   // if true, the NodeKey needs to be replaced
	MachineAuthorized bool   // TODO(crawshaw): move to using MachineStatus
	AuthURL           string // if set, authorization pending
}

RegisterResponse is returned by the server in response to a RegisterRequest.

func (*RegisterResponse) Clone added in v1.2.0

func (src *RegisterResponse) Clone() *RegisterResponse

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

type Role

type Role struct {
	ID           RoleID
	Name         string
	Capabilities []CapabilityID
}

func (*Role) Clone added in v1.2.0

func (src *Role) Clone() *Role

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

type RoleID

type RoleID ID

func (RoleID) IsZero added in v1.2.0

func (u RoleID) IsZero() bool

func (RoleID) String

func (id RoleID) String() string

type Service

type Service struct {
	Proto       ServiceProto // TCP or UDP
	Port        uint16       // port number service is listening on
	Description string       `json:",omitempty"` // text description of service
	// contains filtered or unexported fields
}

type ServiceProto

type ServiceProto string

type StableID added in v1.4.0

type StableID string

type StableNodeID added in v1.4.0

type StableNodeID StableID

func (StableNodeID) IsZero added in v1.4.0

func (u StableNodeID) IsZero() bool

type User

type User struct {
	ID            UserID
	LoginName     string `json:"-"` // not stored, filled from Login // TODO REMOVE
	DisplayName   string // if non-empty overrides Login field
	ProfilePicURL string // if non-empty overrides Login field
	Domain        string
	Logins        []LoginID
	Roles         []RoleID
	Created       time.Time
}

User is an IPN user.

A user can have multiple logins associated with it (e.g. gmail and github oauth). (Note: none of our UIs support this yet.)

Some properties are inhereted from the logins and can be overridden, such as display name and profile picture.

Other properties must be the same for all logins associated with a user. In particular: domain. If a user has a "tailscale.io" domain login, they cannot have a general gmail address login associated with the user.

func (*User) Clone

func (src *User) Clone() *User

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

type UserID

type UserID ID

func (UserID) IsZero added in v1.2.0

func (u UserID) IsZero() bool

func (UserID) String

func (id UserID) String() string

type UserProfile

type UserProfile struct {
	ID            UserID
	LoginName     string // "alice@smith.com"; for display purposes only (provider is not listed)
	DisplayName   string // "Alice Smith"
	ProfilePicURL string
	Roles         []RoleID // deprecated; clients should not rely on Roles
}

A UserProfile is display-friendly data for a user. It includes the LoginName for display purposes but *not* the Provider. It also includes derived data from one of the user's logins.

Jump to

Keyboard shortcuts

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