Documentation
¶
Index ¶
- Constants
- Variables
- func CompareDERPMaps(a *tailcfg.DERPMap, b *tailcfg.DERPMap) bool
- func CoordinatorHTTPDebug(data HTMLDebug) func(w http.ResponseWriter, _ *http.Request)
- func IP() netip.Addr
- func IPFromUUID(uid uuid.UUID) netip.Addr
- func Logger(logger slog.Logger) tslogger.Logf
- func NewDERPMap(ctx context.Context, region *tailcfg.DERPRegion, stunAddrs []string, ...) (*tailcfg.DERPMap, error)
- func NodeID(uid uuid.UUID) tailcfg.NodeID
- func STUNRegions(baseRegionID int, stunAddrs []string) ([]*tailcfg.DERPRegion, error)
- func ServeCoordinator(conn net.Conn, updateNodes func(node []*Node) error) (func(node *Node), <-chan error)
- func WithWebsocketSupport(s *derp.Server, base http.Handler) (http.Handler, func())
- type Conn
- func (c *Conn) Addresses() []netip.Prefix
- func (c *Conn) AwaitReachable(ctx context.Context, ip netip.Addr) bool
- func (c *Conn) BlockEndpoints() bool
- func (c *Conn) Close() error
- func (c *Conn) Closed() <-chan struct{}
- func (c *Conn) DERPMap() *tailcfg.DERPMap
- func (c *Conn) DialContextTCP(ctx context.Context, ipp netip.AddrPort) (*gonet.TCPConn, error)
- func (c *Conn) DialContextUDP(ctx context.Context, ipp netip.AddrPort) (*gonet.UDPConn, error)
- func (c *Conn) Listen(network, addr string) (net.Listener, error)
- func (c *Conn) MagicsockServeHTTPDebug(w http.ResponseWriter, r *http.Request)
- func (c *Conn) MagicsockSetDebugLoggingEnabled(enabled bool)
- func (c *Conn) Node() *Node
- func (c *Conn) NodeAddresses(publicKey key.NodePublic) ([]netip.Prefix, bool)
- func (c *Conn) Ping(ctx context.Context, ip netip.Addr) (time.Duration, bool, *ipnstate.PingResult, error)
- func (c *Conn) RemovePeer(selector PeerSelector) (deleted bool, err error)
- func (c *Conn) SetAddresses(ips []netip.Prefix) error
- func (c *Conn) SetBlockEndpoints(blockEndpoints bool)
- func (c *Conn) SetConnStatsCallback(maxPeriod time.Duration, maxConns int, dump func(start, end time.Time, ...))
- func (c *Conn) SetDERPForceWebSockets(v bool)
- func (c *Conn) SetDERPMap(derpMap *tailcfg.DERPMap)
- func (c *Conn) SetDERPRegionDialer(dialer func(ctx context.Context, region *tailcfg.DERPRegion) net.Conn)
- func (c *Conn) SetNodeCallback(callback func(node *Node))
- func (c *Conn) Status() *ipnstate.Status
- func (c *Conn) UpdateNodes(nodes []*Node, replacePeers bool) error
- type Coordinator
- type HTMLAgent
- type HTMLClient
- type HTMLDebug
- type HTMLNode
- type MultiAgent
- func (m *MultiAgent) AgentIsLegacy(agentID uuid.UUID) bool
- func (m *MultiAgent) Close() error
- func (m *MultiAgent) CoordinatorClose() error
- func (m *MultiAgent) Done() <-chan struct{}
- func (m *MultiAgent) Enqueue(nodes []*Node) error
- func (m *MultiAgent) Init() *MultiAgent
- func (m *MultiAgent) IsClosed() bool
- func (*MultiAgent) Kind() QueueKind
- func (m *MultiAgent) Name() string
- func (m *MultiAgent) NextUpdate(ctx context.Context) ([]*Node, bool)
- func (m *MultiAgent) Overwrites() int64
- func (m *MultiAgent) Stats() (start int64, lastWrite int64)
- func (m *MultiAgent) SubscribeAgent(agentID uuid.UUID) error
- func (m *MultiAgent) UniqueID() uuid.UUID
- func (m *MultiAgent) UnsubscribeAgent(agentID uuid.UUID) error
- func (m *MultiAgent) UpdateSelf(node *Node) error
- type MultiAgentConn
- type Node
- type Options
- type PeerSelector
- type Queue
- type QueueKind
- type TrackedConn
- func (t *TrackedConn) Close() error
- func (t *TrackedConn) CoordinatorClose() error
- func (t *TrackedConn) Done() <-chan struct{}
- func (t *TrackedConn) Enqueue(n []*Node) (err error)
- func (t *TrackedConn) Kind() QueueKind
- func (t *TrackedConn) Name() string
- func (t *TrackedConn) Overwrites() int64
- func (t *TrackedConn) SendUpdates()
- func (t *TrackedConn) Stats() (start, lastWrite int64)
- func (t *TrackedConn) UniqueID() uuid.UUID
Constants ¶
const ( WorkspaceAgentSSHPort = 1 WorkspaceAgentReconnectingPTYPort = 2 WorkspaceAgentSpeedtestPort = 3 )
const DisableSTUN = "disable"
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.
const LoggerName = "coord"
const WriteTimeout = time.Second * 5
WriteTimeout is the amount of time we wait to write a node update to a connection before we declare it hung. It is exported so that tests can use it.
Variables ¶
var ErrConnClosed = xerrors.New("connection closed")
var ErrMultiAgentClosed = xerrors.New("multiagent is closed")
var ErrWouldBlock = xerrors.New("would block")
Functions ¶
func CompareDERPMaps ¶
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 CoordinatorHTTPDebug ¶
func CoordinatorHTTPDebug(data HTMLDebug) func(w http.ResponseWriter, _ *http.Request)
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 NodeID ¶
NodeID creates a Tailscale NodeID from the last 8 bytes of a UUID. It ensures the returned NodeID is always positive.
func STUNRegions ¶
func STUNRegions(baseRegionID int, stunAddrs []string) ([]*tailcfg.DERPRegion, error)
func ServeCoordinator ¶
func ServeCoordinator(conn net.Conn, updateNodes func(node []*Node) error) (func(node *Node), <-chan error)
ServeCoordinator matches the RW structure of a coordinator to exchange node messages.
func WithWebsocketSupport ¶
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
Types ¶
type Conn ¶
type Conn struct {
// contains filtered or unexported fields
}
Conn is an actively listening Wireguard connection.
func NewConn ¶
NewConn constructs a new Wireguard server that will accept connections from the addresses provided.
func (*Conn) AwaitReachable ¶
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) BlockEndpoints ¶
BlockEndpoints returns whether or not P2P is blocked.
func (*Conn) Closed ¶
func (c *Conn) Closed() <-chan struct{}
Closed is a channel that ends when the connection has been closed.
func (*Conn) DialContextTCP ¶
func (*Conn) DialContextUDP ¶
func (*Conn) MagicsockServeHTTPDebug ¶
func (c *Conn) MagicsockServeHTTPDebug(w http.ResponseWriter, r *http.Request)
func (*Conn) MagicsockSetDebugLoggingEnabled ¶
func (*Conn) NodeAddresses ¶
NodeAddresses returns the addresses of a node from the NetworkMap.
func (*Conn) Ping ¶
func (c *Conn) Ping(ctx context.Context, ip netip.Addr) (time.Duration, bool, *ipnstate.PingResult, error)
Ping sends a Disco ping to the Wireguard engine. The bool returned is true if the ping was performed P2P.
func (*Conn) RemovePeer ¶
func (c *Conn) RemovePeer(selector PeerSelector) (deleted bool, err error)
func (*Conn) SetBlockEndpoints ¶
SetBlockEndpoints sets whether or not 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 (*Conn) SetDERPMap ¶
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) SetNodeCallback ¶
func (*Conn) UpdateNodes ¶
UpdateNodes connects with a set of peers. This can be constantly updated, and peers will continually be reconnected as necessary. If replacePeers is true, all peers will be removed before adding the new ones.
type Coordinator ¶
type Coordinator interface { // ServeHTTPDebug serves a debug webpage that shows the internal state of // the coordinator. ServeHTTPDebug(w http.ResponseWriter, r *http.Request) // Node returns an in-memory node by ID. Node(id uuid.UUID) *Node // ServeClient accepts a WebSocket connection that wants to connect to an agent // with the specified ID. ServeClient(conn net.Conn, id uuid.UUID, agent uuid.UUID) error // ServeAgent accepts a WebSocket connection to an agent that listens to // incoming connections and publishes node updates. // Name is just used for debug information. It can be left blank. ServeAgent(conn net.Conn, id uuid.UUID, name string) error // Close closes the coordinator. Close() error ServeMultiAgent(id uuid.UUID) MultiAgentConn }
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 HTMLClient ¶
type MultiAgent ¶
type MultiAgent struct { ID uuid.UUID AgentIsLegacyFunc func(agentID uuid.UUID) bool OnSubscribe func(enq Queue, agent uuid.UUID) (*Node, error) OnUnsubscribe func(enq Queue, agent uuid.UUID) error OnNodeUpdate func(id uuid.UUID, node *Node) error OnRemove func(enq Queue) // contains filtered or unexported fields }
func (*MultiAgent) AgentIsLegacy ¶
func (m *MultiAgent) AgentIsLegacy(agentID uuid.UUID) bool
func (*MultiAgent) Close ¶
func (m *MultiAgent) Close() error
func (*MultiAgent) CoordinatorClose ¶
func (m *MultiAgent) CoordinatorClose() error
func (*MultiAgent) Done ¶ added in v2.2.0
func (m *MultiAgent) Done() <-chan struct{}
func (*MultiAgent) Enqueue ¶
func (m *MultiAgent) Enqueue(nodes []*Node) error
func (*MultiAgent) Init ¶
func (m *MultiAgent) Init() *MultiAgent
func (*MultiAgent) IsClosed ¶
func (m *MultiAgent) IsClosed() bool
func (*MultiAgent) Kind ¶ added in v2.2.0
func (*MultiAgent) Kind() QueueKind
func (*MultiAgent) Name ¶
func (m *MultiAgent) Name() string
func (*MultiAgent) NextUpdate ¶
func (m *MultiAgent) NextUpdate(ctx context.Context) ([]*Node, bool)
func (*MultiAgent) Overwrites ¶
func (m *MultiAgent) Overwrites() int64
func (*MultiAgent) Stats ¶
func (m *MultiAgent) Stats() (start int64, lastWrite int64)
func (*MultiAgent) SubscribeAgent ¶
func (m *MultiAgent) SubscribeAgent(agentID uuid.UUID) error
func (*MultiAgent) UniqueID ¶
func (m *MultiAgent) UniqueID() uuid.UUID
func (*MultiAgent) UnsubscribeAgent ¶
func (m *MultiAgent) UnsubscribeAgent(agentID uuid.UUID) error
func (*MultiAgent) UpdateSelf ¶
func (m *MultiAgent) UpdateSelf(node *Node) error
type MultiAgentConn ¶
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.
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 }
type PeerSelector ¶
PeerSelector is used to select a peer from within a Tailnet.
type Queue ¶
type Queue interface { UniqueID() uuid.UUID Kind() QueueKind Enqueue(n []*Node) error Name() string Stats() (start, lastWrite int64) Overwrites() int64 // CoordinatorClose is used by the coordinator when closing a Queue. It // should skip removing itself from the coordinator. CoordinatorClose() error Done() <-chan struct{} Close() error }
type TrackedConn ¶
type TrackedConn struct {
// contains filtered or unexported fields
}
func NewTrackedConn ¶
func (*TrackedConn) Close ¶
func (t *TrackedConn) Close() error
Close the connection and cancel the context for reading node updates from the queue
func (*TrackedConn) CoordinatorClose ¶
func (t *TrackedConn) CoordinatorClose() error
func (*TrackedConn) Done ¶ added in v2.2.0
func (t *TrackedConn) Done() <-chan struct{}
func (*TrackedConn) Enqueue ¶
func (t *TrackedConn) Enqueue(n []*Node) (err error)
func (*TrackedConn) Kind ¶ added in v2.2.0
func (t *TrackedConn) Kind() QueueKind
func (*TrackedConn) Name ¶
func (t *TrackedConn) Name() string
func (*TrackedConn) Overwrites ¶
func (t *TrackedConn) Overwrites() int64
func (*TrackedConn) SendUpdates ¶
func (t *TrackedConn) SendUpdates()
SendUpdates reads node updates and writes them to the connection. Ends when writes hit an error or context is canceled.
func (*TrackedConn) Stats ¶
func (t *TrackedConn) Stats() (start, lastWrite int64)
func (*TrackedConn) UniqueID ¶
func (t *TrackedConn) UniqueID() uuid.UUID
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
Package tailnettest is a generated GoMock package.
|
Package tailnettest is a generated GoMock package. |