ts2021

package
v1.90.3 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2025 License: BSD-3-Clause Imports: 28 Imported by: 0

Documentation

Overview

Package ts2021 handles the details of the Tailscale 2021 control protocol that are after (above) the Noise layer. In particular, the "tailcfg.EarlyNoise" message and the subsequent HTTP/2 connection.

Index

Constants

View Source
const EarlyPayloadMagic = "\xff\xff\xffTS"

EarlyPayloadMagic is the 5-byte magic prefix that indicates an early payload.

Variables

This section is empty.

Functions

func AddLBHeader

func AddLBHeader(req *http.Request, nodeKey key.NodePublic)

AddLBHeader adds the load balancer header to req if nodeKey is non-zero.

Types

type Client

type Client struct {
	// Client is an HTTP client to talk to the coordination server.
	// It automatically makes a new Noise connection as needed.
	*http.Client
	// contains filtered or unexported fields
}

Client provides a http.Client to connect to tailcontrol over the ts2021 protocol.

func NewClient

func NewClient(opts ClientOpts) (*Client, error)

NewClient returns a new noiseClient for the provided server and machine key.

netMon may be nil, if non-nil it's used to do faster interface lookups. dialPlan may be nil

func (*Client) Close

func (nc *Client) Close() error

Close closes all the underlying noise connections. It is a no-op and returns nil if the connection is already closed.

func (*Client) DoWithBody

func (nc *Client) DoWithBody(ctx context.Context, method, path string, nodeKey key.NodePublic, body any) (*http.Response, error)

func (*Client) Post

func (nc *Client) Post(ctx context.Context, path string, nodeKey key.NodePublic, body any) (*http.Response, error)

post does a POST to the control server at the given path, JSON-encoding body. The provided nodeKey is an optional load balancing hint.

type ClientOpts

type ClientOpts struct {
	// ServerURL is the URL of the server to connect to.
	ServerURL string

	// PrivKey is this node's private key.
	PrivKey key.MachinePrivate

	// ServerPubKey is the public key of the server.
	// It is of the form https://<host>:<port> (no trailing slash).
	ServerPubKey key.MachinePublic

	// Dialer's SystemDial function is used to connect to the server.
	Dialer *tsdial.Dialer

	// Logf is the log function to use.
	// If nil, log.Printf is used.
	Logf logger.Logf

	// NetMon is the network monitor that will be used to get the
	// network interface state. This field can be nil; if so, the current
	// state will be looked up dynamically.
	NetMon *netmon.Monitor

	// DNSCache is the caching Resolver to use to connect to the server.
	//
	// This field can be nil.
	DNSCache *dnscache.Resolver

	// HealthTracker, if non-nil, is the health tracker to use.
	HealthTracker *health.Tracker

	// DialPlan, if set, is a function that should return an explicit plan
	// on how to connect to the server.
	DialPlan func() *tailcfg.ControlDialPlan

	// ProtocolVersion, if non-zero, specifies an alternate
	// protocol version to use instead of the default,
	// of [tailcfg.CurrentCapabilityVersion].
	ProtocolVersion uint16
}

ClientOpts contains options for the NewClient function. All fields are required unless otherwise specified.

type Conn

type Conn struct {
	*controlbase.Conn
	// contains filtered or unexported fields
}

Conn is a wrapper around controlbase.Conn.

It allows attaching an ID to a connection to allow cleaning up references in the pool when the connection is closed, properly handles an optional "early payload" that's sent prior to beginning the HTTP/2 session, and provides a way to return a connection to a pool when the connection is closed.

Use NewConn to build a new Conn if you want Conn.GetEarlyPayload to work. Otherwise making a Conn directly, only setting Conn, is fine.

func NewConn

func NewConn(conn *controlbase.Conn, onClose func()) *Conn

NewConn creates a new Conn that wraps the given controlbase.Conn.

h2t is the HTTP/2 transport to use for the connection; a new http2.ClientConn will be created that reads from the returned Conn.

connID should be a unique ID for this connection. When the Conn is closed, the onClose function will be called if it is non-nil.

func (*Conn) Close

func (c *Conn) Close() error

Close closes the connection.

func (*Conn) GetEarlyPayload

func (c *Conn) GetEarlyPayload(ctx context.Context) (*tailcfg.EarlyNoise, error)

GetEarlyPayload waits for the early Noise payload to arrive. It may return (nil, nil) if the server begins HTTP/2 without one.

It is safe to call this multiple times; all callers will block until the early Noise payload is ready (if any) and will return the same result for the lifetime of the Conn.

func (*Conn) Read

func (c *Conn) Read(p []byte) (n int, err error)

Read is basically the same as controlbase.Conn.Read, but it first reads the "early payload" header from the server which may or may not be present, depending on the server.

Jump to

Keyboard shortcuts

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