Update
This commit is contained in:
1 parent
3530afb854
commit
6903fcff27
2146 files changed
+112256
-190703
No files matched your search
+133
-10
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// Package wgengine provides the Tailscale WireGuard engine interface.
|
||||
@@ -9,9 +9,11 @@ import (
|
||||
"net/netip"
|
||||
"time"
|
||||
|
||||
"github.com/gaissmai/bart"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/net/dns"
|
||||
"tailscale.com/net/packet"
|
||||
"tailscale.com/net/routemanager"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/netmap"
|
||||
@@ -41,6 +43,28 @@ type StatusCallback func(*Status, error)
|
||||
// into network map updates.
|
||||
type NetworkMapCallback func(*netmap.NetworkMap)
|
||||
|
||||
// PeerWireGuardState is the current WireGuard session state for a peer.
|
||||
type PeerWireGuardState uint8
|
||||
|
||||
const (
|
||||
// PeerWireGuardStateNone means there is no handshake in progress and no
|
||||
// session key material retained for this peer.
|
||||
PeerWireGuardStateNone PeerWireGuardState = 0
|
||||
|
||||
// PeerWireGuardStateHandshake means a handshake is in progress for this
|
||||
// peer, but there is not currently a usable WireGuard session.
|
||||
PeerWireGuardStateHandshake PeerWireGuardState = 1
|
||||
|
||||
// PeerWireGuardStateEstablished means the peer has a completed WireGuard
|
||||
// session with usable session key material.
|
||||
PeerWireGuardStateEstablished PeerWireGuardState = 2
|
||||
|
||||
// PeerWireGuardStateExpired means the peer's session key material is no
|
||||
// longer considered usable, but final key cleanup or lazy peer removal may
|
||||
// not have happened yet.
|
||||
PeerWireGuardStateExpired PeerWireGuardState = 3
|
||||
)
|
||||
|
||||
// ErrNoChanges is returned by Engine.Reconfig if no changes were made.
|
||||
var ErrNoChanges = errors.New("no changes made to Engine config")
|
||||
|
||||
@@ -76,9 +100,19 @@ type Engine interface {
|
||||
// Unlike Reconfig, it does not return ErrNoChanges.
|
||||
ResetAndStop() (*Status, error)
|
||||
|
||||
// PeerForIP returns the node to which the provided IP routes,
|
||||
// if any. If none is found, (nil, false) is returned.
|
||||
PeerForIP(netip.Addr) (_ PeerForIP, ok bool)
|
||||
// SetPeerForIPFunc installs the IP-to-node lookup used by the
|
||||
// engine's internal cold paths (Ping, TSMP, pendopen diagnostics).
|
||||
// It parallels [Engine.SetPeerByIPPacketFunc] but returns richer
|
||||
// data (a full NodeView, the matched route prefix, and the IsSelf
|
||||
// flag).
|
||||
//
|
||||
// If fn is nil, those lookups fail for every IP.
|
||||
//
|
||||
// LocalBackend installs a func backed by the live nodeBackend for
|
||||
// exact-match and self addresses, with the RouteManager's outbound
|
||||
// table supplying the subnet-route / exit-node fallback; the engine
|
||||
// itself holds no peer-lookup state on this path.
|
||||
SetPeerForIPFunc(fn func(netip.Addr) (_ PeerForIP, ok bool))
|
||||
|
||||
// GetFilter returns the current packet filter, if any.
|
||||
GetFilter() *filter.Filter
|
||||
@@ -93,6 +127,17 @@ type Engine interface {
|
||||
// SetJailedFilter updates the packet filter for jailed nodes.
|
||||
SetJailedFilter(*filter.Filter)
|
||||
|
||||
// SetPeerRoutes updates the per-peer route attributes used by the
|
||||
// tun-layer data plane for per-packet NAT rewrites and
|
||||
// jailed-filter selection. native4 and native6 are this node's own
|
||||
// Tailscale addresses, and routes maps each peer's addresses and
|
||||
// routed prefixes to its attributes; it is a shared immutable
|
||||
// snapshot from [routemanager.RouteManager.Outbound].
|
||||
//
|
||||
// A nil routes table disables all per-packet peer processing;
|
||||
// callers pass nil when no current peer has any such attributes.
|
||||
SetPeerRoutes(native4, native6 netip.Addr, routes *bart.Table[*routemanager.PeerRoute])
|
||||
|
||||
// SetStatusCallback sets the function to call when the
|
||||
// WireGuard status changes.
|
||||
SetStatusCallback(StatusCallback)
|
||||
@@ -116,12 +161,9 @@ type Engine interface {
|
||||
// You don't have to call this.
|
||||
Done() <-chan struct{}
|
||||
|
||||
// SetNetworkMap informs the engine of the latest network map
|
||||
// from the server. The network map's DERPMap field should be
|
||||
// ignored as as it might be disabled; get it from SetDERPMap
|
||||
// instead.
|
||||
// The network map should only be read from.
|
||||
SetNetworkMap(*netmap.NetworkMap)
|
||||
// SetSelfNode informs the engine of the current self node.
|
||||
// The zero (invalid) NodeView indicates no self node.
|
||||
SetSelfNode(tailcfg.NodeView)
|
||||
|
||||
// UpdateStatus populates the network state using the provided
|
||||
// status builder.
|
||||
@@ -137,4 +179,85 @@ type Engine interface {
|
||||
// packets traversing the data path. The hook can be uninstalled by
|
||||
// calling this function with a nil value.
|
||||
InstallCaptureHook(packet.CaptureCallback)
|
||||
|
||||
// SetPeerByIPPacketFunc installs a callback used by wireguard-go to
|
||||
// look up which peer should handle an outbound packet by destination IP.
|
||||
SetPeerByIPPacketFunc(func(netip.Addr) (_ key.NodePublic, ok bool))
|
||||
|
||||
// SetPeerConfigFunc installs the live source of per-peer WireGuard
|
||||
// configuration: given a peer's public key, fn returns its current
|
||||
// WireGuard configuration, including the prefixes it may originate and
|
||||
// its optional pre-shared key. It returns ok=false if the peer is unknown,
|
||||
// in which case it must not exist in the WireGuard device. The engine installs a single
|
||||
// [device.PeerLookupFunc] wrapping fn, so lazily-created peers
|
||||
// always see current state and the lookup func never needs to be
|
||||
// reinstalled as peers come and go.
|
||||
//
|
||||
// It is expected to be called once during LocalBackend construction,
|
||||
// before the first [Engine.Reconfig]. fn is called rarely (when
|
||||
// wireguard-go first hears from a peer it doesn't have) and may
|
||||
// acquire locks.
|
||||
SetPeerConfigFunc(fn func(key.NodePublic) (config wgcfg.PeerConfig, ok bool))
|
||||
|
||||
// SyncDevicePeer synchronizes the WireGuard device's state for a
|
||||
// single peer with the config source installed via
|
||||
// [Engine.SetPeerConfigFunc]: if the source no longer knows the
|
||||
// peer, it is removed from the device; if the peer is active in the
|
||||
// device, its allowed IPs and pre-shared key are updated. It does O(1)
|
||||
// work (plus the config source lookup) and is intended to be called for
|
||||
// each peer
|
||||
// added, updated, or removed by an incremental netmap delta,
|
||||
// avoiding a full [Engine.Reconfig].
|
||||
//
|
||||
// It is a no-op if no config source is installed.
|
||||
SyncDevicePeer(key.NodePublic)
|
||||
|
||||
// MarkDevicePeerForHandshake marks the peer for an opportunistic handshake in the
|
||||
// WireGuard device.
|
||||
//
|
||||
// LocalBackend calls it when a peer's disco key changes, which
|
||||
// means the peer restarted and its old sessions are dead, or that control
|
||||
// caught up to a key learned via TSMP previously.
|
||||
MarkDevicePeerForHandshake(key.NodePublic)
|
||||
|
||||
// SetNetLogSource installs the [NetLogSource] consulted by the
|
||||
// engine's network flow logger for node lookups and the current
|
||||
// audit logging identity.
|
||||
//
|
||||
// It is expected to be called once during LocalBackend construction,
|
||||
// before any [Engine.Reconfig] call that starts up the network logger.
|
||||
SetNetLogSource(NetLogSource)
|
||||
|
||||
// SetWGPeerLookup installs the function used by the engine's
|
||||
// wireguard-go log wrapper to rewrite peer references in log lines
|
||||
// (mapping wireguard-go's "peer(XXXX…YYYY)" form to the
|
||||
// Tailscale-conventional short string form).
|
||||
//
|
||||
// It is expected to be called once during LocalBackend construction.
|
||||
// The function is called concurrently and must be safe to call with
|
||||
// no Engine locks held.
|
||||
SetWGPeerLookup(func(wgString string) (tsString string, ok bool))
|
||||
|
||||
// SetPeerSessionStateFunc installs a callback used to observe WireGuard
|
||||
// peer session state transitions.
|
||||
//
|
||||
// Calls are serialized per Engine and delivered in transition order from
|
||||
// wireguard-go, while wireguard-go is holding locks. The callback must be
|
||||
// cheap and must not call back into wireguard-go.
|
||||
//
|
||||
// It does not replay current state. Callers that need a complete view should
|
||||
// set it before peers are started or lazily created, and maintain any
|
||||
// snapshots, sequence numbers, and pubsub state outside wireguard-go.
|
||||
//
|
||||
// In Tailscale, the usual implementation is
|
||||
// ipnlocal.LocalBackend.onPeerWireGuardState, installed early in
|
||||
// LocalBackend construction.
|
||||
SetPeerSessionStateFunc(func(key.NodePublic, PeerWireGuardState))
|
||||
|
||||
SetPeerPriorityMessageOnEstablishmentFunc(fn func(key.NodePublic) (msg []byte))
|
||||
|
||||
// ProbeLocks acquires and releases the engine's internal locks so
|
||||
// that [ipnlocal.LocalBackend]'s watchdog can detect deadlocks in
|
||||
// the engine. It is otherwise a no-op.
|
||||
ProbeLocks()
|
||||
}
|
||||
Reference in new issue
Block a user