tailscale.comtailscale.com/wgengine Index | Files | Directories

package wgengine

import "tailscale.com/wgengine"

Package wgengine provides the Tailscale WireGuard engine interface.

Index

Variables

var ErrEngineClosing = errors.New("engine closing; no status")
var ErrNoChanges = errors.New("no changes made to Engine config")

ErrNoChanges is returned by Engine.Reconfig if no changes were made.

Types

type BIRDClient

type BIRDClient interface {
	EnableProtocol(proto string) error
	DisableProtocol(proto string) error
	Close() error
}

BIRDClient handles communication with the BIRD Internet Routing Daemon.

type Config

type Config struct {
	// Tun is the device used by the Engine to exchange packets with
	// the OS.
	// If nil, a fake Device that does nothing is used.
	Tun tun.Device

	// IsTAP is whether Tun is actually a TAP (Layer 2) device that'll
	// require ethernet headers.
	IsTAP bool

	// Router interfaces the Engine to the OS network stack.
	// If nil, a fake Router that does nothing is used.
	Router router.Router

	// DNS interfaces the Engine to the OS DNS resolver configuration.
	// If nil, a fake OSConfigurator that does nothing is used.
	DNS dns.OSConfigurator

	// ReconfigureVPN provides an optional hook for platforms like Android to
	// know when it's time to reconfigure their VPN implementation. Such
	// platforms can only set their entire VPN configuration (routes, DNS, etc)
	// at all once and can't make piecemeal incremental changes, so this
	// provides a hook to "flush" a batch of Router and/or DNS changes.
	ReconfigureVPN func() error

	// NetMon optionally provides an existing network monitor to re-use.
	// If nil, a new network monitor is created.
	NetMon *netmon.Monitor

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

	// Metrics is the usermetrics registry to use.
	// Mandatory, if not set, an error is returned.
	Metrics *usermetric.Registry

	// Dialer is the dialer to use for outbound connections.
	// If nil, a new Dialer is created.
	Dialer *tsdial.Dialer

	// ControlKnobs is the set of control plane-provied knobs
	// to use.
	// If nil, defaults are used.
	ControlKnobs *controlknobs.Knobs

	// ListenPort is the port on which the engine will listen.
	// If zero, a port is automatically selected.
	ListenPort uint16

	// RespondToPing determines whether this engine should internally
	// reply to ICMP pings, without involving the OS.
	// Used in "fake" mode for development.
	RespondToPing bool

	// BIRDClient, if non-nil, will be used to configure BIRD whenever
	// this node is a primary subnet router.
	BIRDClient BIRDClient

	// SetSubsystem, if non-nil, is called for each new subsystem created, just before a successful return.
	SetSubsystem func(any)

	// DriveForLocal, if populated, will cause the engine to expose a Taildrive
	// listener at 100.100.100.100:8080.
	DriveForLocal drive.FileSystemForLocal

	// EventBus, if non-nil, is used for event publication and subscription by
	// the Engine and its subsystems.
	//
	// TODO(creachadair): As of 2025-03-19 this is optional, but is intended to
	// become required non-nil.
	EventBus *eventbus.Bus
}

Config is the engine configuration.

type Engine

type Engine interface {
	// Reconfig reconfigures WireGuard and makes sure it's running.
	// This also handles setting up any kernel routes.
	//
	// This is called whenever tailcontrol (the control plane)
	// sends an updated network map.
	//
	// The returned error is ErrNoChanges if no changes were made.
	Reconfig(*wgcfg.Config, *router.Config, *dns.Config) 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)

	// GetFilter returns the current packet filter, if any.
	GetFilter() *filter.Filter

	// SetFilter updates the packet filter.
	SetFilter(*filter.Filter)

	// GetJailedFilter returns the current packet filter for jailed nodes,
	// if any.
	GetJailedFilter() *filter.Filter

	// SetJailedFilter updates the packet filter for jailed nodes.
	SetJailedFilter(*filter.Filter)

	// SetStatusCallback sets the function to call when the
	// WireGuard status changes.
	SetStatusCallback(StatusCallback)

	// RequestStatus requests a WireGuard status update right
	// away, sent to the callback registered via SetStatusCallback.
	RequestStatus()

	// PeerByKey returns the WireGuard status of the provided peer.
	// If the peer is not found, ok is false.
	PeerByKey(key.NodePublic) (_ wgint.Peer, ok bool)

	// Close shuts down this wireguard instance, remove any routes
	// it added, etc. To bring it up again later, you'll need a
	// new Engine.
	Close()

	// Done returns a channel that is closed when the Engine's
	// Close method is called, the engine aborts with an error,
	// or it shuts down due to the closure of the underlying device.
	// 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)

	// UpdateStatus populates the network state using the provided
	// status builder.
	UpdateStatus(*ipnstate.StatusBuilder)

	// Ping is a request to start a ping of the given message size to the peer
	// handling the given IP, then call cb with its ping latency & method.
	//
	// If size is zero too small, it is ignored. See tailscale.PingOpts for details.
	Ping(ip netip.Addr, pingType tailcfg.PingType, size int, cb func(*ipnstate.PingResult))

	// InstallCaptureHook registers a function to be called to capture
	// packets traversing the data path. The hook can be uninstalled by
	// calling this function with a nil value.
	InstallCaptureHook(packet.CaptureCallback)
}

Engine is the Tailscale WireGuard engine interface.

func NewFakeUserspaceEngine

func NewFakeUserspaceEngine(logf logger.Logf, opts ...any) (Engine, error)

NewFakeUserspaceEngine returns a new userspace engine for testing.

The opts may contain the following types:

func NewUserspaceEngine

func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)

NewUserspaceEngine creates the named tun device and returns a Tailscale Engine running on it.

func NewWatchdog

func NewWatchdog(e Engine) Engine

NewWatchdog wraps an Engine and makes sure that all methods complete within a reasonable amount of time.

If they do not, the watchdog crashes the process.

type NetworkMapCallback

type NetworkMapCallback func(*netmap.NetworkMap)

NetworkMapCallback is the type used by callbacks that hook into network map updates.

type PeerForIP

type PeerForIP struct {
	// Node is the matched node. It's always a valid value when
	// Engine.PeerForIP returns ok==true.
	Node tailcfg.NodeView

	// IsSelf is whether the Node is the local process.
	IsSelf bool

	// Route is the route that matched the IP provided
	// to Engine.PeerForIP.
	Route netip.Prefix
}

PeerForIP is the type returned by Engine.PeerForIP.

type Status

type Status struct {
	AsOf       time.Time // the time at which the status was calculated
	Peers      []ipnstate.PeerStatusLite
	LocalAddrs []tailcfg.Endpoint // the set of possible endpoints for the magic conn
	DERPs      int                // number of active DERP connections
}

Status is the Engine status.

TODO(bradfitz): remove this, subset of ipnstate? Need to migrate users.

type StatusCallback

type StatusCallback func(*Status, error)

StatusCallback is the type of status callbacks used by Engine.SetStatusCallback.

Exactly one of Status or error is non-nil.

Source Files

pendopen.go userspace.go watchdog.go wgengine.go

Directories

PathSynopsis
wgengine/benchCreate two wgengine instances and pass data through them, measuring throughput, latency, and packet loss.
wgengine/filterPackage filter is a stateful packet filter.
wgengine/filter/filtertypePackage filtertype defines the types used by wgengine/filter.
wgengine/magicsockPackage magicsock implements a socket that can change its communication path while in use, actively searching for the best way to communicate.
wgengine/netlogPackage netlog provides a logger that monitors a TUN device and periodically records any traffic into a log stream.
wgengine/netstackPackage netstack wires up gVisor's netstack into Tailscale.
wgengine/netstack/groPackage gro implements GRO for the receive (write) path into gVisor.
wgengine/routerPackage router presents an interface to manipulate the host network stack's state.
wgengine/wgcfgPackage wgcfg has types and a parser for representing WireGuard config.
wgengine/wgcfg/nmcfgPackage nmcfg converts a controlclient.NetMap into a wgcfg config.
wgengine/wgintPackage wgint provides somewhat shady access to wireguard-go internals that don't (yet) have public APIs.
wgengine/wglogPackage wglog contains logging helpers for wireguard-go.
Version
v1.84.0 (latest)
Published
May 21, 2025
Platform
linux/amd64
Imports
59 packages
Last checked
1 day ago

Tools for package owners.