tailnet

package
v2.21.3 Latest Latest
Warning

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

Go to latest
Published: Apr 29, 2025 License: AGPL-3.0 Imports: 80 Imported by: 0

Documentation

Index

Constants

View Source
const (
	WorkspaceAgentSSHPort             = 1
	WorkspaceAgentReconnectingPTYPort = 2
	WorkspaceAgentSpeedtestPort       = 3
	WorkspaceAgentStandardSSHPort     = 22
)
View Source
const (
	// ResponseBufferSize is the max number of responses to buffer per connection before we start
	// dropping updates
	ResponseBufferSize = 512
	// RequestBufferSize is the max number of requests to buffer per connection
	RequestBufferSize = 32
)
View Source
const (
	TelemetryApplicationSSH       string = "ssh"
	TelemetryApplicationSpeedtest string = "speedtest"
	TelemetryApplicationVSCode    string = "vscode"
)
View Source
const CoderDNSSuffix = "coder."

CoderDNSSuffix is the default DNS suffix that we append to Coder DNS records.

View Source
const (
	DefaultResumeTokenExpiry = 24 * time.Hour
)
View Source
const DisableSTUN = "disable"
View Source
const EnvMagicsockDebugLogging = "CODER_MAGICSOCK_DEBUG_LOGGING"

EnvMagicsockDebugLogging enables super-verbose logging for the magicsock internals. A logger must be supplied to the connection with the debug level enabled.

With this disabled, you still get a lot of output if you have a valid logger with the debug level enabled.

View Source
const LoggerName = "coord"

Variables

View Source
var (
	ErrClosed         = xerrors.New("coordinator is closed")
	ErrWouldBlock     = xerrors.New("would block")
	ErrAlreadyRemoved = xerrors.New("already removed")
)
View Source
var ErrConnClosed = xerrors.New("connection closed")
View Source
var ErrUnsupportedVersion = xerrors.New("unsupported version")

Functions

func CompareDERPMaps

func CompareDERPMaps(a *tailcfg.DERPMap, b *tailcfg.DERPMap) bool

CompareDERPMaps returns true if the given DERPMaps are equivalent. Ordering of slices is ignored.

If the first map is nil, the second map must also be nil for them to be considered equivalent. If the second map is nil, the first map can be any value and the function will return true.

func DERPMapFromProto added in v2.6.0

func DERPMapFromProto(derpMap *proto.DERPMap) *tailcfg.DERPMap

func DERPMapToProto added in v2.6.0

func DERPMapToProto(derpMap *tailcfg.DERPMap) *proto.DERPMap

func DERPNodeFromProto added in v2.6.0

func DERPNodeFromProto(node *proto.DERPMap_Region_Node) *tailcfg.DERPNode

func DERPNodeToProto added in v2.6.0

func DERPNodeToProto(node *tailcfg.DERPNode) *proto.DERPMap_Region_Node

func DERPRegionFromProto added in v2.6.0

func DERPRegionFromProto(region *proto.DERPMap_Region) *tailcfg.DERPRegion

func DERPRegionToProto added in v2.6.0

func DERPRegionToProto(region *tailcfg.DERPRegion) *proto.DERPMap_Region

func IsDRPCUnimplementedError added in v2.18.0

func IsDRPCUnimplementedError(err error) bool

IsDRPCUnimplementedError returns true if the error indicates the RPC called is not implemented by the server.

func Logger

func Logger(logger interface {
	Debug(ctx context.Context, str string, args ...any)
},
) tslogger.Logf

Logger converts the Tailscale logging function to use a slog-compatible logger.

func NewDERPMap

func NewDERPMap(ctx context.Context, region *tailcfg.DERPRegion, stunAddrs []string, remoteURL, localPath string, disableSTUN bool) (*tailcfg.DERPMap, error)

NewDERPMap constructs a DERPMap from a set of STUN addresses and optionally a remote URL to fetch a mapping from e.g. https://controlplane.tailscale.com/derpmap/default.

func NewDRPCClient added in v2.6.0

func NewDRPCClient(conn net.Conn, logger slog.Logger) (proto.DRPCTailnetClient, error)

func NodeID

func NodeID(uid uuid.UUID) tailcfg.NodeID

NodeID creates a Tailscale NodeID from the last 8 bytes of a UUID. It ensures the returned NodeID is always positive.

func NodeToProto added in v2.4.0

func NodeToProto(n *Node) (*proto.Node, error)

func RecvCtx added in v2.5.0

func RecvCtx[A any](ctx context.Context, c <-chan A) (a A, err error)

func STUNRegions

func STUNRegions(baseRegionID int, stunAddrs []string) ([]*tailcfg.DERPRegion, error)

func SendCtx added in v2.5.0

func SendCtx[A any](ctx context.Context, c chan<- A, a A) (err error)

func SingleNodeUpdate added in v2.4.0

func SingleNodeUpdate(id uuid.UUID, node *Node, reason string) (*proto.CoordinateResponse, error)

func UUIDToByteSlice added in v2.4.0

func UUIDToByteSlice(u uuid.UUID) []byte

func WithStreamID added in v2.6.0

func WithStreamID(ctx context.Context, streamID StreamID) context.Context

func WithWebsocketSupport

func WithWebsocketSupport(s *derp.Server, base http.Handler) (http.Handler, func())

WithWebsocketSupport returns an http.Handler that upgrades connections to the "derp" subprotocol to WebSockets and passes them to the DERP server. Taken from: https://github.com/tailscale/tailscale/blob/e3211ff88ba85435f70984cf67d9b353f3d650d8/cmd/derper/websocket.go#L21

func WorkspaceStatusToProto added in v2.18.0

func WorkspaceStatusToProto(status codersdk.WorkspaceStatus) proto.Workspace_Status

Types

type Agent added in v2.19.0

type Agent struct {
	ID          uuid.UUID
	Name        string
	WorkspaceID uuid.UUID
	Hosts       map[dnsname.FQDN][]netip.Addr
}

func (*Agent) Clone added in v2.19.0

func (a *Agent) Clone() Agent

type AgentCoordinateeAuth added in v2.9.0

type AgentCoordinateeAuth struct {
	ID uuid.UUID
}

AgentCoordinateeAuth disallows all tunnels, since agents are not allowed to initiate their own tunnels

func (AgentCoordinateeAuth) Authorize added in v2.9.0

type BasicCoordination added in v2.18.0

type BasicCoordination struct {
	sync.Mutex

	Client CoordinatorClient
	// contains filtered or unexported fields
}

BasicCoordination handles:

1. Sending local node updates to the control plane 2. Reading remote updates from the control plane and programming them into the Coordinatee.

It does *not* handle adding any Tunnels, but these can be handled by composing BasicCoordinationController with a more advanced controller.

func (*BasicCoordination) Close added in v2.18.0

func (c *BasicCoordination) Close(ctx context.Context) (retErr error)

Close the coordination gracefully. If the context expires before the remote API server has hung up on us, we forcibly close the Client connection.

func (*BasicCoordination) SendErr added in v2.18.0

func (c *BasicCoordination) SendErr(err error)

SendErr is not part of the CloserWaiter interface, and is intended to be called internally, or by Controllers that use BasicCoordinationController in composition. It triggers Wait() to report the error if an error has not already been reported.

func (*BasicCoordination) Wait added in v2.18.0

func (c *BasicCoordination) Wait() <-chan error

Wait for the Coordination to complete

type BasicCoordinationController added in v2.18.0

type BasicCoordinationController struct {
	Logger      slog.Logger
	Coordinatee Coordinatee
	SendAcks    bool
}

BasicCoordinationController handles the basic coordination operations common to all types of tailnet consumers:

  1. sending local node updates to the Coordinator
  2. receiving peer node updates and programming them into the Coordinatee (e.g. tailnet.Conn)
  3. (optionally) sending ReadyToHandshake acknowledgements for peer updates.

It is designed to be used on its own, or composed into more advanced CoordinationControllers.

func (*BasicCoordinationController) New added in v2.18.0

New satisfies the method on the CoordinationController interface

func (*BasicCoordinationController) NewCoordination added in v2.18.0

NewCoordination creates a BasicCoordination

type BasicTelemetryController added in v2.18.0

type BasicTelemetryController struct {
	sync.Mutex
	// contains filtered or unexported fields
}

func NewBasicTelemetryController added in v2.18.0

func NewBasicTelemetryController(logger slog.Logger) *BasicTelemetryController

func (*BasicTelemetryController) New added in v2.18.0

func (*BasicTelemetryController) SendTelemetryEvent added in v2.18.0

func (b *BasicTelemetryController) SendTelemetryEvent(event *proto.TelemetryEvent)

type ClientCoordinateeAuth added in v2.9.0

type ClientCoordinateeAuth struct {
	AgentID uuid.UUID
}

ClientCoordinateeAuth allows connecting to a single, given agent

func (ClientCoordinateeAuth) Authorize added in v2.9.0

type ClientService added in v2.6.0

type ClientService struct {
	Logger   slog.Logger
	CoordPtr *atomic.Pointer[Coordinator]
	// contains filtered or unexported fields
}

ClientService is a tailnet coordination service that accepts a connection and version from a tailnet client, and support versions 2.x of the Tailnet API protocol.

func NewClientService added in v2.6.0

func NewClientService(options ClientServiceOptions) (
	*ClientService, error,
)

NewClientService returns a ClientService based on the given Coordinator pointer. The pointer is loaded on each processed connection.

func (*ClientService) ServeClient added in v2.6.0

func (s *ClientService) ServeClient(ctx context.Context, version string, conn net.Conn, streamID StreamID) error

func (ClientService) ServeConnV2 added in v2.7.0

func (s ClientService) ServeConnV2(ctx context.Context, conn net.Conn, streamID StreamID) error

type ClientServiceOptions added in v2.14.0

type ClientServiceOptions struct {
	Logger                   slog.Logger
	CoordPtr                 *atomic.Pointer[Coordinator]
	DERPMapUpdateFrequency   time.Duration
	DERPMapFn                func() *tailcfg.DERPMap
	NetworkTelemetryHandler  func(batch []*proto.TelemetryEvent)
	ResumeTokenProvider      ResumeTokenProvider
	WorkspaceUpdatesProvider WorkspaceUpdatesProvider
}

type ClientUserCoordinateeAuth added in v2.18.0

type ClientUserCoordinateeAuth struct {
	Auth TunnelAuthorizer
}

func (ClientUserCoordinateeAuth) Authorize added in v2.18.0

type CloserWaiter added in v2.18.0

type CloserWaiter interface {
	Close(context.Context) error
	Wait() <-chan error
}

type Conn

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

Conn is an actively listening Wireguard connection.

func NewConn

func NewConn(options *Options) (conn *Conn, err error)

NewConn constructs a new Wireguard server that will accept connections from the addresses provided.

func (*Conn) AwaitReachable

func (c *Conn) AwaitReachable(ctx context.Context, ip netip.Addr) bool

AwaitReachable pings the provided IP continually until the address is reachable. It's the callers responsibility to provide a timeout, otherwise this function will block forever.

func (*Conn) Close

func (c *Conn) Close() error

Close shuts down the Wireguard connection.

func (*Conn) Closed

func (c *Conn) Closed() <-chan struct{}

Closed is a channel that ends when the connection has been closed.

func (*Conn) DERPMap

func (c *Conn) DERPMap() *tailcfg.DERPMap

DERPMap returns the currently set DERP mapping.

func (*Conn) DialContextTCP

func (c *Conn) DialContextTCP(ctx context.Context, ipp netip.AddrPort) (*gonet.TCPConn, error)

func (*Conn) DialContextUDP

func (c *Conn) DialContextUDP(ctx context.Context, ipp netip.AddrPort) (*gonet.UDPConn, error)

func (*Conn) GetBlockEndpoints added in v2.9.0

func (c *Conn) GetBlockEndpoints() bool

func (*Conn) GetKnownPeerIDs added in v2.15.0

func (c *Conn) GetKnownPeerIDs() []uuid.UUID

func (*Conn) GetNetInfo added in v2.15.0

func (c *Conn) GetNetInfo() *tailcfg.NetInfo

func (*Conn) GetPeerDiagnostics added in v2.9.0

func (c *Conn) GetPeerDiagnostics(peerID uuid.UUID) PeerDiagnostics

func (*Conn) InstallCaptureHook added in v2.8.0

func (c *Conn) InstallCaptureHook(f capture.Callback)

func (*Conn) Listen

func (c *Conn) Listen(network, addr string) (net.Listener, error)

Listen listens for connections only on the Tailscale network.

func (*Conn) MagicsockServeHTTPDebug

func (c *Conn) MagicsockServeHTTPDebug(w http.ResponseWriter, r *http.Request)

func (*Conn) MagicsockSetDebugLoggingEnabled

func (c *Conn) MagicsockSetDebugLoggingEnabled(enabled bool)

func (*Conn) Node

func (c *Conn) Node() *Node

Node returns the last node that was sent to the node callback.

func (*Conn) NodeAddresses

func (c *Conn) NodeAddresses(publicKey key.NodePublic) ([]netip.Prefix, bool)

NodeAddresses returns the addresses of a node from the NetworkMap.

func (*Conn) Ping

Ping sends a ping to the Wireguard engine. The bool returned is true if the ping was performed P2P.

func (*Conn) SendConnectedTelemetry added in v2.14.0

func (c *Conn) SendConnectedTelemetry(ip netip.Addr, application string)

SendConnectedTelemetry should be called when connection to a peer with the given IP is established.

func (*Conn) SendDisconnectedTelemetry added in v2.14.0

func (c *Conn) SendDisconnectedTelemetry()

func (*Conn) SendSpeedtestTelemetry added in v2.14.0

func (c *Conn) SendSpeedtestTelemetry(throughputMbits float64)

func (*Conn) SetAddresses

func (c *Conn) SetAddresses(ips []netip.Prefix) error

func (*Conn) SetAllPeersLost added in v2.7.1

func (c *Conn) SetAllPeersLost()

SetAllPeersLost marks all peers lost; typically used when we disconnect from a coordinator.

func (*Conn) SetBlockEndpoints

func (c *Conn) SetBlockEndpoints(blockEndpoints bool)

SetBlockEndpoints sets whether to block P2P endpoints. This setting will only apply to new peers.

func (*Conn) SetConnStatsCallback

func (c *Conn) SetConnStatsCallback(maxPeriod time.Duration, maxConns int, dump func(start, end time.Time, virtual, physical map[netlogtype.Connection]netlogtype.Counts))

SetConnStatsCallback sets a callback to be called after maxPeriod or maxConns, whichever comes first. Multiple calls overwrites the callback.

func (*Conn) SetDERPForceWebSockets added in v2.1.3

func (c *Conn) SetDERPForceWebSockets(v bool)

func (*Conn) SetDERPMap

func (c *Conn) SetDERPMap(derpMap *tailcfg.DERPMap)

SetDERPMap updates the DERPMap of a connection.

func (*Conn) SetDERPRegionDialer

func (c *Conn) SetDERPRegionDialer(dialer func(ctx context.Context, region *tailcfg.DERPRegion) net.Conn)

SetDERPRegionDialer updates the dialer to use for connecting to DERP regions.

func (*Conn) SetDNSHosts added in v2.18.0

func (c *Conn) SetDNSHosts(hosts map[dnsname.FQDN][]netip.Addr) error

SetDNSHosts replaces the map of DNS hosts for the connection.

func (*Conn) SetNodeCallback

func (c *Conn) SetNodeCallback(callback func(node *Node))

func (*Conn) SetTunnelDestination added in v2.11.0

func (c *Conn) SetTunnelDestination(id uuid.UUID)

func (*Conn) Status

func (c *Conn) Status() *ipnstate.Status

Status returns the current ipnstate of a connection.

func (*Conn) UpdatePeers added in v2.7.1

func (c *Conn) UpdatePeers(updates []*proto.CoordinateResponse_PeerUpdate) error

UpdatePeers connects with a set of peers. This can be constantly updated, and peers will continually be reconnected as necessary.

type ControlProtocolClients added in v2.18.0

type ControlProtocolClients struct {
	Closer           io.Closer
	Coordinator      CoordinatorClient
	DERP             DERPClient
	ResumeToken      ResumeTokenClient
	Telemetry        TelemetryClient
	WorkspaceUpdates WorkspaceUpdatesClient
}

ControlProtocolClients represents an abstract interface to the tailnet control plane via a set of protocol clients. The Closer should close all the clients (e.g. by closing the underlying connection).

type ControlProtocolDialer added in v2.18.0

type ControlProtocolDialer interface {
	// Dial connects to the tailnet control plane and returns clients for the different control
	// sub-protocols (coordination, DERP maps, resume tokens, and telemetry).  If the
	// ResumeTokenController is not nil, the dialer should query for a resume token and use it to
	// dial, if available.
	Dial(ctx context.Context, r ResumeTokenController) (ControlProtocolClients, error)
}

type Controller added in v2.18.0

type Controller struct {
	Dialer               ControlProtocolDialer
	CoordCtrl            CoordinationController
	DERPCtrl             DERPController
	ResumeTokenCtrl      ResumeTokenController
	TelemetryCtrl        TelemetryController
	WorkspaceUpdatesCtrl WorkspaceUpdatesController
	// contains filtered or unexported fields
}

A Controller connects to the tailnet control plane, and then uses the control protocols to program a tailnet.Conn in production (in test it could be an interface simulating the Conn). It delegates this task to sub-controllers responsible for the main areas of the tailnet control protocol: coordination, DERP map updates, resume tokens, telemetry, and workspace updates.

func NewController added in v2.18.0

func NewController(logger slog.Logger, dialer ControlProtocolDialer, opts ...ControllerOpt) *Controller

NewController creates a new Controller without running it

func (*Controller) Closed added in v2.18.0

func (c *Controller) Closed() <-chan struct{}

func (*Controller) Run added in v2.18.0

func (c *Controller) Run(ctx context.Context)

Run dials the API and uses it with the provided controllers.

type ControllerOpt added in v2.18.0

type ControllerOpt func(*Controller)

func WithGracefulTimeout added in v2.18.0

func WithGracefulTimeout(timeout time.Duration) ControllerOpt

func WithTestClock added in v2.18.0

func WithTestClock(clock quartz.Clock) ControllerOpt

type Coordinatee added in v2.7.1

type Coordinatee interface {
	UpdatePeers([]*proto.CoordinateResponse_PeerUpdate) error
	SetAllPeersLost()
	SetNodeCallback(func(*Node))
	// SetTunnelDestination indicates to tailnet that the peer id is a
	// destination.
	SetTunnelDestination(id uuid.UUID)
}

Coordinatee is something that can be coordinated over the Coordinate protocol. Usually this is a Conn.

type CoordinateeAuth added in v2.9.0

type CoordinateeAuth interface {
	Authorize(ctx context.Context, req *proto.CoordinateRequest) error
}

type CoordinationController added in v2.18.0

type CoordinationController interface {
	New(CoordinatorClient) CloserWaiter
}

A CoordinationController accepts connections to the control plane, and handles the Coordination protocol on behalf of some Coordinatee (tailnet.Conn in production). This is the "glue" code between them.

func NewAgentCoordinationController added in v2.18.0

func NewAgentCoordinationController(
	logger slog.Logger, coordinatee Coordinatee,
) CoordinationController

NewAgentCoordinationController creates a CoordinationController for Coder Agents, which never create tunnels and always send ReadyToHandshake acknowledgements.

type Coordinator

type Coordinator interface {
	CoordinatorV2
}

Coordinator exchanges nodes with agents to establish connections. ┌──────────────────┐ ┌────────────────────┐ ┌───────────────────┐ ┌──────────────────┐ │tailnet.Coordinate├──►│tailnet.AcceptClient│◄─►│tailnet.AcceptAgent│◄──┤tailnet.Coordinate│ └──────────────────┘ └────────────────────┘ └───────────────────┘ └──────────────────┘ Coordinators have different guarantees for HA support.

func NewCoordinator

func NewCoordinator(logger slog.Logger) Coordinator

NewCoordinator constructs a new in-memory connection coordinator. This coordinator is incompatible with multiple Coder replicas as all node data is in-memory.

type CoordinatorClient added in v2.18.0

type CoordinatorClient interface {
	Close() error
	Send(*proto.CoordinateRequest) error
	Recv() (*proto.CoordinateResponse, error)
}

CoordinatorClient is an abstraction of the Coordinator's control protocol interface from the perspective of a protocol client (i.e. the Coder Agent is also a client of this interface).

func NewInMemoryCoordinatorClient added in v2.18.0

func NewInMemoryCoordinatorClient(
	logger slog.Logger,
	clientID uuid.UUID,
	auth CoordinateeAuth,
	coordinator Coordinator,
) CoordinatorClient

NewInMemoryCoordinatorClient creates a coordination client that uses channels to connect to a local Coordinator. (The typical alternative is a DRPC-based client.)

type CoordinatorV2 added in v2.5.0

type CoordinatorV2 interface {
	// ServeHTTPDebug serves a debug webpage that shows the internal state of
	// the coordinator.
	ServeHTTPDebug(w http.ResponseWriter, r *http.Request)
	// Node returns a node by peer ID, if known to the coordinator.  Returns nil if unknown.
	Node(id uuid.UUID) *Node
	Close() error
	Coordinate(ctx context.Context, id uuid.UUID, name string, a CoordinateeAuth) (chan<- *proto.CoordinateRequest, <-chan *proto.CoordinateResponse)
}

CoordinatorV2 is the interface for interacting with the coordinator via the 2.0 tailnet API.

type DERPClient added in v2.18.0

type DERPClient interface {
	Close() error
	Recv() (*tailcfg.DERPMap, error)
}

DERPClient is an abstraction of the stream of DERPMap updates from the control plane.

type DERPController added in v2.18.0

type DERPController interface {
	New(DERPClient) CloserWaiter
}

A DERPController accepts connections to the control plane, and handles the DERPMap updates delivered over them by programming the data plane (tailnet.Conn or some test interface).

func NewBasicDERPController added in v2.18.0

func NewBasicDERPController(logger slog.Logger, setter DERPMapSetter) DERPController

type DERPFromDRPCWrapper added in v2.18.0

type DERPFromDRPCWrapper struct {
	Client proto.DRPCTailnet_StreamDERPMapsClient
}

func (*DERPFromDRPCWrapper) Close added in v2.18.0

func (w *DERPFromDRPCWrapper) Close() error

func (*DERPFromDRPCWrapper) Recv added in v2.18.0

func (w *DERPFromDRPCWrapper) Recv() (*tailcfg.DERPMap, error)

type DERPMapSetter added in v2.18.0

type DERPMapSetter interface {
	SetDERPMap(derpMap *tailcfg.DERPMap)
}

type DNSHostsSetter added in v2.18.0

type DNSHostsSetter interface {
	SetDNSHosts(hosts map[dnsname.FQDN][]netip.Addr) error
}

DNSHostsSetter is something that you can set a mapping of DNS names to IPs on. It's the subset of the tailnet.Conn that we use to configure DNS records.

type DRPCService added in v2.6.0

type DRPCService struct {
	CoordPtr                 *atomic.Pointer[Coordinator]
	Logger                   slog.Logger
	DerpMapUpdateFrequency   time.Duration
	DerpMapFn                func() *tailcfg.DERPMap
	NetworkTelemetryHandler  func(batch []*proto.TelemetryEvent)
	ResumeTokenProvider      ResumeTokenProvider
	WorkspaceUpdatesProvider WorkspaceUpdatesProvider
}

DRPCService is the dRPC-based, version 2.x of the tailnet API and implements proto.DRPCClientServer

func (*DRPCService) Coordinate added in v2.7.0

func (s *DRPCService) Coordinate(stream proto.DRPCTailnet_CoordinateStream) error

func (*DRPCService) PostTelemetry added in v2.13.0

func (*DRPCService) RefreshResumeToken added in v2.15.0

func (*DRPCService) StreamDERPMaps added in v2.6.0

func (*DRPCService) WorkspaceUpdates added in v2.18.0

type HTMLDebug

type HTMLDebug struct {
	Peers   []HTMLPeer
	Tunnels []HTMLTunnel
}

type HTMLPeer added in v2.5.0

type HTMLPeer struct {
	ID           uuid.UUID
	Name         string
	CreatedAge   time.Duration
	LastWriteAge time.Duration
	Overwrites   int
	Node         string
}

type HTMLTunnel added in v2.5.0

type HTMLTunnel struct {
	Src, Dst uuid.UUID
}

type NetworkTelemetryBatcher added in v2.14.0

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

func NewNetworkTelemetryBatcher added in v2.14.0

func NewNetworkTelemetryBatcher(clk quartz.Clock, frequency time.Duration, maxSize int, batchFn func(batch []*proto.TelemetryEvent)) *NetworkTelemetryBatcher

func (*NetworkTelemetryBatcher) Close added in v2.14.0

func (b *NetworkTelemetryBatcher) Close() error

func (*NetworkTelemetryBatcher) Handler added in v2.14.0

func (b *NetworkTelemetryBatcher) Handler(events []*proto.TelemetryEvent)

type Node

type Node struct {
	// ID is used to identify the connection.
	ID tailcfg.NodeID `json:"id"`
	// AsOf is the time the node was created.
	AsOf time.Time `json:"as_of"`
	// Key is the Wireguard public key of the node.
	Key key.NodePublic `json:"key"`
	// DiscoKey is used for discovery messages over DERP to establish
	// peer-to-peer connections.
	DiscoKey key.DiscoPublic `json:"disco"`
	// PreferredDERP is the DERP server that peered connections should meet at
	// to establish.
	PreferredDERP int `json:"preferred_derp"`
	// DERPLatency is the latency in seconds to each DERP server.
	DERPLatency map[string]float64 `json:"derp_latency"`
	// DERPForcedWebsocket contains a mapping of DERP regions to
	// error messages that caused the connection to be forced to
	// use WebSockets. We don't use WebSockets by default because
	// they are less performant.
	DERPForcedWebsocket map[int]string `json:"derp_forced_websockets"`
	// Addresses are the IP address ranges this connection exposes.
	Addresses []netip.Prefix `json:"addresses"`
	// AllowedIPs specify what addresses can dial the connection. We allow all
	// by default.
	AllowedIPs []netip.Prefix `json:"allowed_ips"`
	// Endpoints are ip:port combinations that can be used to establish
	// peer-to-peer connections.
	Endpoints []string `json:"endpoints"`
}

Node represents a node in the network.

func OnlyNodeUpdates added in v2.4.0

func OnlyNodeUpdates(resp *proto.CoordinateResponse) ([]*Node, error)

func ProtoToNode added in v2.4.0

func ProtoToNode(p *proto.Node) (*Node, error)

type Options

type Options struct {
	ID         uuid.UUID
	Addresses  []netip.Prefix
	DERPMap    *tailcfg.DERPMap
	DERPHeader *http.Header
	// DERPForceWebSockets determines whether websockets is always used for DERP
	// connections, rather than trying `Upgrade: derp` first and potentially
	// falling back. This is useful for misbehaving proxies that prevent
	// fallback due to odd behavior, like Azure App Proxy.
	DERPForceWebSockets bool
	// BlockEndpoints specifies whether P2P endpoints are blocked.
	// If so, only DERPs can establish connections.
	BlockEndpoints bool
	Logger         slog.Logger
	ListenPort     uint16
	// CaptureHook is a callback that captures Disco packets and packets sent
	// into the tailnet tunnel.
	CaptureHook capture.Callback
	// ForceNetworkUp forces the network to be considered up. magicsock will not
	// do anything if it thinks it can't reach the internet.
	ForceNetworkUp bool
	// Network Telemetry Client Type: CLI | Agent | coderd
	ClientType proto.TelemetryEvent_ClientType
	// TelemetrySink is optional.
	TelemetrySink TelemetrySink
	// DNSConfigurator is optional, and is passed to the underlying wireguard
	// engine.
	DNSConfigurator dns.OSConfigurator
	// Router is optional, and is passed to the underlying wireguard engine.
	Router router.Router
	// TUNDev is optional, and is passed to the underlying wireguard engine.
	TUNDev tun.Device
	// WireguardMonitor is optional, and is passed to the underlying wireguard
	// engine.
	WireguardMonitor *netmon.Monitor
}

type PeerDiagnostics added in v2.9.0

type PeerDiagnostics struct {
	// PreferredDERP is 0 if we are not connected to a DERP region. If non-zero, we are connected to
	// the given region as our home or "preferred" DERP.
	PreferredDERP   int
	DERPRegionNames map[int]string
	// SentNode is true if we have successfully transmitted our local Node via the most recently set
	// NodeCallback.
	SentNode bool
	// ReceivedNode is the last Node we received for the peer, or nil if we haven't received the node.
	ReceivedNode *tailcfg.Node
	// LastWireguardHandshake is the last time we completed a wireguard handshake
	LastWireguardHandshake time.Time
}

PeerDiagnostics is a checklist of human-readable conditions necessary to establish an encrypted tunnel to a peer via a Conn

type ResumeTokenClient added in v2.18.0

type ResumeTokenClient interface {
	RefreshResumeToken(ctx context.Context, in *proto.RefreshResumeTokenRequest) (*proto.RefreshResumeTokenResponse, error)
}

type ResumeTokenController added in v2.18.0

type ResumeTokenController interface {
	New(ResumeTokenClient) CloserWaiter
	Token() (string, bool)
}

func NewBasicResumeTokenController added in v2.18.0

func NewBasicResumeTokenController(logger slog.Logger, clock quartz.Clock) ResumeTokenController

type ResumeTokenKeyProvider added in v2.15.0

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

func (ResumeTokenKeyProvider) GenerateResumeToken added in v2.15.0

func (p ResumeTokenKeyProvider) GenerateResumeToken(ctx context.Context, peerID uuid.UUID) (*proto.RefreshResumeTokenResponse, error)

func (ResumeTokenKeyProvider) VerifyResumeToken added in v2.15.0

func (p ResumeTokenKeyProvider) VerifyResumeToken(ctx context.Context, str string) (uuid.UUID, error)

VerifyResumeToken parses a signed tailnet resume token with the given key and returns the payload. If the token is invalid or expired, an error is returned.

type ResumeTokenProvider added in v2.15.0

type ResumeTokenProvider interface {
	GenerateResumeToken(ctx context.Context, peerID uuid.UUID) (*proto.RefreshResumeTokenResponse, error)
	VerifyResumeToken(ctx context.Context, token string) (uuid.UUID, error)
}

func NewInsecureTestResumeTokenProvider added in v2.15.0

func NewInsecureTestResumeTokenProvider() ResumeTokenProvider

NewInsecureTestResumeTokenProvider returns a ResumeTokenProvider that uses a random key with short expiry for testing purposes. If any errors occur while generating the key, the function panics.

func NewResumeTokenKeyProvider added in v2.15.0

func NewResumeTokenKeyProvider(key jwtutils.SigningKeyManager, clock quartz.Clock, expiry time.Duration) ResumeTokenProvider

type ResumeTokenSigningKey added in v2.15.0

type ResumeTokenSigningKey [64]byte

func GenerateResumeTokenSigningKey added in v2.15.0

func GenerateResumeTokenSigningKey() (ResumeTokenSigningKey, error)

type ServicePrefix added in v2.17.0

type ServicePrefix [6]byte
var (
	// TailscaleServicePrefix is the IPv6 prefix for all tailnet nodes since it was first added to
	// Coder.  It is identical to the service prefix Tailscale.com uses. With the introduction of
	// CoderVPN, we would like to stop using the Tailscale prefix so that we don't conflict with
	// Tailscale if both are installed at the same time. However, there are a large number of agents
	// and clients using this prefix, so we need to carefully manage deprecation and eventual
	// removal.
	// fd7a:115c:a1e0:://48
	TailscaleServicePrefix ServicePrefix = [6]byte{0xfd, 0x7a, 0x11, 0x5c, 0xa1, 0xe0}
	// CoderServicePrefix is the Coder-specific IPv6 prefix for tailnet nodes, which we are in the
	// process of migrating to. It allows Coder to run alongside Tailscale without conflicts even
	// if both are set up as TUN interfaces into the OS (e.g. CoderVPN).
	// fd60:627a:a42b::/48
	CoderServicePrefix ServicePrefix = [6]byte{0xfd, 0x60, 0x62, 0x7a, 0xa4, 0x2b}
)

func (ServicePrefix) AddrFromUUID added in v2.17.0

func (p ServicePrefix) AddrFromUUID(uid uuid.UUID) netip.Addr

AddrFromUUID returns an IPv6 address corresponding to the given UUID in the service prefix.

func (ServicePrefix) AsNetip added in v2.18.0

func (p ServicePrefix) AsNetip() netip.Prefix

func (ServicePrefix) PrefixFromUUID added in v2.17.0

func (p ServicePrefix) PrefixFromUUID(uid uuid.UUID) netip.Prefix

PrefixFromUUID returns a single IPv6 /128 prefix corresponding to the given UUID.

func (ServicePrefix) RandomAddr added in v2.17.0

func (p ServicePrefix) RandomAddr() netip.Addr

RandomAddr returns a random IP address in the service prefix.

func (ServicePrefix) RandomPrefix added in v2.17.0

func (p ServicePrefix) RandomPrefix() netip.Prefix

RandomPrefix returns a single IPv6 /128 prefix within the service prefix.

type SingleTailnetCoordinateeAuth added in v2.9.0

type SingleTailnetCoordinateeAuth struct{}

SingleTailnetCoordinateeAuth allows all tunnels, since Coderd and wsproxy are allowed to initiate a tunnel to any agent

func (SingleTailnetCoordinateeAuth) Authorize added in v2.9.0

type StreamID added in v2.6.0

type StreamID struct {
	Name string
	ID   uuid.UUID
	Auth CoordinateeAuth
}

StreamID identifies the caller of the CoordinateTailnet RPC. We store this on the context, since the information is extracted at the HTTP layer for remote clients of the API, or set outside tailnet for local clients (e.g. Coderd's single_tailnet)

type Subscription added in v2.18.0

type Subscription interface {
	io.Closer
	Updates() <-chan *proto.WorkspaceUpdate
}

type TelemetryClient added in v2.18.0

type TelemetryClient interface {
	PostTelemetry(ctx context.Context, in *proto.TelemetryRequest) (*proto.TelemetryResponse, error)
}

type TelemetryController added in v2.18.0

type TelemetryController interface {
	New(TelemetryClient)
}

type TelemetrySink added in v2.14.0

type TelemetrySink interface {
	// SendTelemetryEvent sends a telemetry event to some external sink.
	SendTelemetryEvent(event *proto.TelemetryEvent)
}

TelemetrySink allows tailnet.Conn to send network telemetry to the Coder server.

type TelemetryStore added in v2.14.0

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

Responsible for storing and anonymizing networking telemetry state.

type TunnelAllOption added in v2.18.0

type TunnelAllOption func(t *TunnelAllWorkspaceUpdatesController)

func WithDNS added in v2.18.0

func WithDNS(d DNSHostsSetter, ownerUsername string) TunnelAllOption

WithDNS configures the tunnelAllWorkspaceUpdatesController to set DNS names for all workspaces and agents it learns about.

func WithHandler added in v2.19.0

func WithHandler(h UpdatesHandler) TunnelAllOption

type TunnelAllWorkspaceUpdatesController added in v2.19.0

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

func NewTunnelAllWorkspaceUpdatesController added in v2.18.0

func NewTunnelAllWorkspaceUpdatesController(
	logger slog.Logger, c *TunnelSrcCoordController, opts ...TunnelAllOption,
) *TunnelAllWorkspaceUpdatesController

NewTunnelAllWorkspaceUpdatesController creates a WorkspaceUpdatesController that creates tunnels (via the TunnelSrcCoordController) to all agents received over the WorkspaceUpdates RPC. If a DNSHostSetter is provided, it also programs DNS hosts based on the agent and workspace names.

func (*TunnelAllWorkspaceUpdatesController) CurrentState added in v2.19.0

func (*TunnelAllWorkspaceUpdatesController) New added in v2.19.0

type TunnelAuthorizer added in v2.18.0

type TunnelAuthorizer interface {
	AuthorizeTunnel(ctx context.Context, agentID uuid.UUID) error
}

type TunnelSrcCoordController added in v2.18.0

type TunnelSrcCoordController struct {
	*BasicCoordinationController
	// contains filtered or unexported fields
}

func NewTunnelSrcCoordController added in v2.18.0

func NewTunnelSrcCoordController(
	logger slog.Logger, coordinatee Coordinatee,
) *TunnelSrcCoordController

NewTunnelSrcCoordController creates a CoordinationController for peers that are exclusively tunnel sources (that is, they create tunnel --- Coder clients not workspaces).

func (*TunnelSrcCoordController) AddDestination added in v2.18.0

func (c *TunnelSrcCoordController) AddDestination(dest uuid.UUID)

func (*TunnelSrcCoordController) New added in v2.18.0

func (*TunnelSrcCoordController) RemoveDestination added in v2.18.0

func (c *TunnelSrcCoordController) RemoveDestination(dest uuid.UUID)

func (*TunnelSrcCoordController) SyncDestinations added in v2.18.0

func (c *TunnelSrcCoordController) SyncDestinations(destinations []uuid.UUID)

type UpdatesHandler added in v2.19.0

type UpdatesHandler interface {
	Update(WorkspaceUpdate) error
}

UpdatesHandler is anything that expects a stream of workspace update diffs.

type Workspace added in v2.19.0

type Workspace struct {
	ID     uuid.UUID
	Name   string
	Status proto.Workspace_Status
	// contains filtered or unexported fields
}

type WorkspaceUpdate added in v2.19.0

type WorkspaceUpdate struct {
	UpsertedWorkspaces []*Workspace
	UpsertedAgents     []*Agent
	DeletedWorkspaces  []*Workspace
	DeletedAgents      []*Agent
}

func (*WorkspaceUpdate) Clone added in v2.19.0

func (w *WorkspaceUpdate) Clone() WorkspaceUpdate

type WorkspaceUpdatesClient added in v2.18.0

type WorkspaceUpdatesClient interface {
	Close() error
	Recv() (*proto.WorkspaceUpdate, error)
}

type WorkspaceUpdatesController added in v2.18.0

type WorkspaceUpdatesController interface {
	New(WorkspaceUpdatesClient) CloserWaiter
}

type WorkspaceUpdatesProvider added in v2.18.0

type WorkspaceUpdatesProvider interface {
	io.Closer
	Subscribe(ctx context.Context, userID uuid.UUID) (Subscription, error)
}

Directories

Path Synopsis
Package tailnettest is a generated GoMock package.
Package tailnettest is a generated GoMock package.

Jump to

Keyboard shortcuts

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