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
- func AddLBHeader(req *http.Request, nodeKey key.NodePublic)
- type Client
- func (nc *Client) Close() error
- func (nc *Client) Do(req *http.Request) (*http.Response, error)
- func (nc *Client) DoWithBody(ctx context.Context, method, path string, nodeKey key.NodePublic, body any) (*http.Response, error)
- func (nc *Client) Post(ctx context.Context, path string, nodeKey key.NodePublic, body any) (*http.Response, error)
- type ClientOpts
- type Conn
Constants ¶
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 ¶
Close closes all the underlying noise connections. It is a no-op and returns nil if the connection is already closed.
func (*Client) Do ¶ added in v1.104.0
Do does req against the control server and caps the response body with httpbody.LimitSize, using the size limit in the request's context per httpbody.WithMaxSize, httpbody.DefaultMaxSize by default, so a malicious or buggy control server cannot make us buffer an unbounded response body. Reads past the cap fail with an error wrapping httpbody.ErrTooLarge rather than silently truncating.
It shadows the embedded http.Client's Do method, so all noise requests, including those made with Client.Post and Client.DoWithBody, get the cap.
func (*Client) DoWithBody ¶
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
// ExtraRootCAs, if non-nil, specifies additional trusted root CAs for TLS.
ExtraRootCAs *x509.CertPool
// 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) GetEarlyPayload ¶
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.