Documentation
¶
Overview ¶
Package conn25 registers the conn25 feature and implements its associated ipnext.Extension. conn25 will be an app connector like feature that routes traffic for configured domains via connector devices and avoids the "too many routes" pitfall of app connector. It is currently (2026-02-04) some peer API routes for clients to tell connectors about their desired routing.
Index ¶
- Constants
- Variables
- type Conn25
- func (c *Conn25) ClientFlowCreated(transitIP netip.Addr)
- func (c *Conn25) ClientFlowRemoved(transitIP netip.Addr)
- func (c *Conn25) ClientTransitIPForMagicIP(m netip.Addr) (netip.Addr, error)
- func (c *Conn25) ConnectorRealIPForTransitIPConnection(src, transit netip.Addr) (netip.Addr, error)
- func (c *Conn25) GetActiveState() appctype.Conn25ActiveState
- type Conn25Datapath
- type ConnectorTransitIPRequest
- type ConnectorTransitIPResponse
- type FlowData
- type FlowTable
- type FlowTableOption
- type Origin
- type PacketAction
- type TransitIPRequest
- type TransitIPResponse
- type TransitIPResponseCode
- type TupleAndAction
Constants ¶
const ( // OK indicates that the mapping was created as requested. OK TransitIPResponseCode = 0 // OtherFailure indicates that the mapping failed for a reason that does not have // another relevant [TransitIPResponseCode]. OtherFailure TransitIPResponseCode = 1 // DuplicateTransitIP indicates that the same transit address appeared more than // once in a [ConnectorTransitIPRequest]. DuplicateTransitIP TransitIPResponseCode = 2 // NoMatchingPeerIPFamily indicates that the peer did not have an associated // IP with the same family as transit IP being registered. NoMatchingPeerIPFamily = 3 // AddrFamilyMismatch indicates that the transit IP and destination IP addresses // do not belong to the same IP family. AddrFamilyMismatch = 4 // UnknownAppName indicates that the connector is not configured to handle requests // for the App name that was specified in the request. UnknownAppName = 5 )
const ( // DefaultFlowIdleTimeout is the default idle timeout for a flow. // See also [WithFlowIdleTimeout]. DefaultFlowIdleTimeout = 5 * time.Minute // DefaultFlowSweepInterval is the default sweep interval for // automatically removing expired flows. See also [WithFlowSweepInterval]. DefaultFlowSweepInterval = 3 * time.Minute // DefaultMaxRemovedFlowsPerSweep is the default maximum number of // flows removed per sweep. It can be used to tune how long the table // mutex is held during sweeps. See also [WithMaxRemovedFlowsPerSweep]. DefaultMaxRemovedFlowsPerSweep = 1000 )
const AppConnectorsExperimentalAttrName = "tailscale.com/app-connectors-experimental"
const AppConnectorsExperimentalIPPoolsAttrName = "tailscale.com/app-connectors-experimental-ippools"
Variables ¶
var ( ErrUnmappedMagicIP = errors.New("unmapped magic IP") ErrUnmappedSrcAndTransitIP = errors.New("unmapped src and transit IP") )
Functions ¶
This section is empty.
Types ¶
type Conn25 ¶
type Conn25 struct {
// contains filtered or unexported fields
}
Conn25 holds state for routing traffic for a domain via a connector.
func (*Conn25) ClientFlowCreated ¶ added in v1.102.0
ClientFlowCreated implements Conn25Datapath. The datapath notifies Conn25 that a flow with transitIP has been created so that Conn25 can prevent that transit IP and associated addresses from being removed from its state and returned to their pools.
func (*Conn25) ClientFlowRemoved ¶ added in v1.102.0
ClientFlowRemoved implements Conn25Datapath. See Conn25.ClientFlowCreated.
func (*Conn25) ClientTransitIPForMagicIP ¶ added in v1.98.0
ClientTransitIPForMagicIP implements Conn25Datapath.
func (*Conn25) ConnectorRealIPForTransitIPConnection ¶ added in v1.98.0
ConnectorRealIPForTransitIPConnection implements Conn25Datapath.
func (*Conn25) GetActiveState ¶ added in v1.102.0
func (c *Conn25) GetActiveState() appctype.Conn25ActiveState
GetActiveState returns active state for the client and the connector, including IP pool usage, address mappings, domains, and active flow counts.
type Conn25Datapath ¶ added in v1.102.0
type Conn25Datapath interface {
// ClientTransitIPForMagicIP returns a Transit IP for the given magicIP on a client.
// If the magicIP is within a configured Magic IP range for an app on the client,
// but not mapped to an active Transit IP, implementations should return [ErrUnmappedMagicIP].
// If magicIP is not within a configured Magic IP range, i.e. it is not actually a Magic IP,
// implementations should return a nil error, and a zero-value [netip.Addr] to indicate
// this potentially valid, non-app-connector traffic.
ClientTransitIPForMagicIP(magicIP netip.Addr) (netip.Addr, error)
// ConnectorRealIPForTransitIPConnection returns a real destination IP for the given
// srcIP and transitIP on a connector. If the transitIP is within a configured Transit IP
// range for an app on the connector, but not mapped to the client at srcIP, implementations
// should return [ErrUnmappedSrcAndTransitIP]. If the transitIP is not within a configured
// Transit IP range, i.e. it is not actually a Transit IP, implementations should return
// a nil error, and a zero-value [netip.Addr] to indicate this is potentially valid,
// non-app-connector traffic.
ConnectorRealIPForTransitIPConnection(srcIP netip.Addr, transitIP netip.Addr) (netip.Addr, error)
// ClientFlowCreated is called after a client-side flow for transitIP has
// been installed in the client flow table.
ClientFlowCreated(transitIP netip.Addr)
// ClientFlowRemoved is called after such a flow is removed. For each
// flow installed in the client flow table, ClientFlowCreated is called
// before any ClientFlowRemoved that fires for it.
ClientFlowRemoved(transitIP netip.Addr)
}
Conn25Datapath is the interface for the surface of *Conn25 that the datapath handler needs. It provides methods for address mapping to help the datapath handler implement DNAT/SNAT, and flow lifecycle handlers so that *Conn25 can keep address assignments active for active flows.
*Conn25 is the only production implementation; the interface exists to let datapath tests substitute a lightweight fake.
type ConnectorTransitIPRequest ¶
type ConnectorTransitIPRequest struct {
// TransitIPs is the list of requested mappings.
TransitIPs []TransitIPRequest `json:"transitIPs,omitempty"`
}
ConnectorTransitIPRequest is the request body for a PeerAPI request to /connector/transit-ip and can include zero or more TransitIP allocation requests.
type ConnectorTransitIPResponse ¶
type ConnectorTransitIPResponse struct {
// TransitIPs is the list of outcomes for each requested mapping. Elements
// correspond to the order of [ConnectorTransitIPRequest.TransitIPs].
TransitIPs []TransitIPResponse `json:"transitIPs,omitempty"`
}
ConnectorTransitIPResponse is the response to a ConnectorTransitIPRequest
type FlowData ¶ added in v1.98.0
type FlowData struct {
FromTun TupleAndAction
FromWG TupleAndAction
// OnRemove, if non-nil, is invoked when the flow is removed from the
// table for any reason (idle expiration, tuple-collision displacement
// in [FlowTable.NewFlow], or capacity eviction). It is called once,
// outside the table's mutex, so it may safely acquire other locks.
OnRemove func()
}
FlowData is an entry stored in the FlowTable constructed by the consumer of the table. It specifies tuples and actions for each direction of the flow.
type FlowTable ¶ added in v1.98.0
type FlowTable struct {
// contains filtered or unexported fields
}
FlowTable stores and retrieves FlowData that can be looked up by 5-tuple flowtrack.Tuple and direction. New entries specify the tuple to use for both directions of traffic flow. The underlying cache is LRU, and the maximum number of entries is specified in calls to NewFlowTable. FlowTable has its own mutex and is safe for concurrent use.
func NewFlowTable ¶ added in v1.98.0
func NewFlowTable(maxEntries int, opts ...FlowTableOption) *FlowTable
NewFlowTable returns a FlowTable with maxEntries maximum entries. A maxEntries of 0 indicates no maximum. See also FlowTable.
func (*FlowTable) LookupFromTunDevice ¶ added in v1.98.0
func (t *FlowTable) LookupFromTunDevice(k flowtrack.Tuple) (PacketAction, bool)
LookupFromTunDevice looks up a PacketAction that is valid to run on packets observed as coming from the tun device. The tuple must match the direction it was stored with.
func (*FlowTable) LookupFromWireGuard ¶ added in v1.98.0
func (t *FlowTable) LookupFromWireGuard(k flowtrack.Tuple) (PacketAction, bool)
LookupFromWireGuard looks up a PacketAction that is valid to run for packets observed as coming from the WireGuard tunnel. The tuple must match the direction it was stored with.
func (*FlowTable) NewFlow ¶ added in v1.100.0
NewFlow installs data as an flow in the table, and evicts any flow that either tuple already points at. This can result in two flows being evicted if each of the new tuples point at distinct existing flows. If the new flow would cause the table to exceed its maximum size, the least recently used (looked-up or created) flow is evicted. data is not validated, the caller must supply non-nil packet actions.
Any FlowData.OnRemove callbacks belonging to displaced or evicted flows are invoked after the table's mutex is released, before NewFlow returns.
func (*FlowTable) StartExpiredSweeper ¶ added in v1.102.0
StartExpiredSweeper starts a sweeper that removes idle flows that have not been created or looked up for a duration greater than the configured idle timeout. See WithFlowIdleTimeout. The sweep runs at the configured sweep interval. See WithFlowSweepInterval. The sweeper stops when ctx is canceled.
type FlowTableOption ¶ added in v1.102.0
type FlowTableOption func(ft *FlowTable)
FlowTableOption configures options for use with NewFlowTable.
func WithFlowIdleTimeout ¶ added in v1.102.0
func WithFlowIdleTimeout(timeout time.Duration) FlowTableOption
WithFlowIdleTimeout sets the threshold duration for flow idle time before it is eligible for removal. A flow is considered idle for the time that elapses since its creation or last lookup. A duration of 0 means that expiration is disabled. If WithFlowIdleTimeout is not passed to NewFlowTable, then DefaultFlowIdleTimeout is used.
func WithFlowSweepInterval ¶ added in v1.102.0
func WithFlowSweepInterval(ival time.Duration) FlowTableOption
WithFlowSweepInterval sets the interval to automatically remove idle flows that exceed the idle timeout. A value of 0 disables automatic sweeping. If WithFlowSweepInterval is not passed to NewFlowTable, then DefaultFlowSweepInterval is used.
func WithMaxRemovedFlowsPerSweep ¶ added in v1.102.0
func WithMaxRemovedFlowsPerSweep(maxPer int) FlowTableOption
WithMaxRemovedFlowsPerSweep sets maximum number of expired flows that can be removed per sweep. A value of 0 means no maximum. If WithMaxRemovedFlowsPerSweep is not passed to NewFlowTable, then DefaultMaxRemovedFlowsPerSweep is used.
type PacketAction ¶ added in v1.98.0
PacketAction may modify the packet.
type TransitIPRequest ¶
type TransitIPRequest struct {
// TransitIP is the intermediate destination IP that will be received at this
// connector and will be replaced by DestinationIP when performing DNAT.
TransitIP netip.Addr `json:"transitIP,omitzero"`
// DestinationIP is the final destination IP that connections to the TransitIP
// should be mapped to when performing DNAT.
DestinationIP netip.Addr `json:"destinationIP,omitzero"`
// App is the name of the connector application from the tailnet
// configuration.
App string `json:"app,omitzero"`
}
TransitIPRequest details a single TransitIP allocation request from a client to a connector.
type TransitIPResponse ¶
type TransitIPResponse struct {
// Code is an error code indicating success or failure of the [TransitIPRequest].
Code TransitIPResponseCode `json:"code,omitzero"`
// Message is an error message explaining what happened, suitable for logging but
// not necessarily suitable for displaying in a UI to non-technical users. It
// should be empty when [Code] is [OK].
Message string `json:"message,omitzero"`
}
TransitIPResponse is the response to a TransitIPRequest
type TransitIPResponseCode ¶
type TransitIPResponseCode int
TransitIPResponseCode appears in TransitIPResponse and signifies success or failure status.
type TupleAndAction ¶ added in v1.100.0
type TupleAndAction struct {
Tuple flowtrack.Tuple
Action PacketAction
}
TupleAndAction wraps the flowtrack.Tuple and the PacketAction to return on lookups to that tuple.