magicsock

package
v0.0.0-...-113f59a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 16, 2024 License: BSD-3-Clause Imports: 76 Imported by: 0

Documentation

Overview

Package magicsock implements a socket that can change its communication path while in use, actively searching for the best way to communicate.

Index

Constants

This section is empty.

Variables

View Source
var MaxDiscoPingSize = tstun.MaxPacketSize - 20 - 8

MaxDiscoPingSize is the largest useful ping message size that we can send - the maximum packet size minus the IPv4 and UDP headers.

Functions

This section is empty.

Types

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

A Conn routes UDP packets and actively manages a list of its endpoints.

func NewConn

func NewConn(opts Options) (*Conn, error)

NewConn creates a magic Conn listening on opts.Port. As the set of possible endpoints for a Conn changes, the callback opts.EndpointsFunc is called.

func (*Conn) Bind

func (c *Conn) Bind() conn.Bind

Bind returns the wireguard-go conn.Bind for c.

See https://pkg.go.dev/golang.zx2c4.com/wireguard/conn#Bind

func (*Conn) Close

func (c *Conn) Close() error

Close closes the connection.

Only the first close does anything. Any later closes return nil.

func (*Conn) DERPs

func (c *Conn) DERPs() int

DERPs reports the number of active DERP connections.

func (*Conn) DebugBreakDERPConns

func (c *Conn) DebugBreakDERPConns() error

DebugBreakDERPConns breaks all DERP connections for debug/testing reasons.

func (*Conn) DebugPickNewDERP

func (c *Conn) DebugPickNewDERP() error

DebugPickNewDERP picks a new DERP random home temporarily (even if just for seconds) and reports it to control. It exists to test DERP home changes and netmap deltas, etc. It serves no useful user purpose.

func (*Conn) DiscoPublicKey

func (c *Conn) DiscoPublicKey() key.DiscoPublic

DiscoPublicKey returns the discovery public key.

func (*Conn) DontFragSetting

func (c *Conn) DontFragSetting() (bool, error)

DontFragSetting returns true if at least one of the underlying sockets of this connection is a UDP socket with the don't fragment bit set, otherwise it returns false. It also returns an error if either connection returned an error other than errUnsupportedConnType.

func (*Conn) GetEndpointChanges

func (c *Conn) GetEndpointChanges(peer tailcfg.NodeView) ([]EndpointChange, error)

GetEndpointChanges returns the most recent changes for a particular endpoint. The returned EndpointChange structs are for debug use only and there are no guarantees about order, size, or content.

func (*Conn) InstallCaptureHook

func (c *Conn) InstallCaptureHook(cb capture.Callback)

InstallCaptureHook installs a callback which is called to log debug information into the pcap stream. This function can be called with a nil argument to uninstall the capture hook.

func (*Conn) LastRecvActivityOfNodeKey

func (c *Conn) LastRecvActivityOfNodeKey(nk key.NodePublic) string

LastRecvActivityOfNodeKey describes the time we last got traffic from this endpoint (updated every ~10 seconds).

func (*Conn) LocalPort

func (c *Conn) LocalPort() uint16

LocalPort returns the current IPv4 listener's port number.

func (*Conn) ParseEndpoint

func (c *Conn) ParseEndpoint(nodeKeyStr string) (conn.Endpoint, error)

ParseEndpoint implements conn.Bind; it's called by WireGuard to connect to an endpoint.

See https://pkg.go.dev/golang.zx2c4.com/wireguard/conn#Bind.ParseEndpoint

func (*Conn) PeerMTUEnabled

func (c *Conn) PeerMTUEnabled() bool

PeerMTUEnabled reports whether peer path MTU discovery is enabled.

func (*Conn) Ping

func (c *Conn) Ping(peer tailcfg.NodeView, res *ipnstate.PingResult, size int, cb func(*ipnstate.PingResult))

Ping handles a "tailscale ping" CLI query.

func (*Conn) ReSTUN

func (c *Conn) ReSTUN(why string)

ReSTUN triggers an address discovery. The provided why string is for debug logging only.

func (*Conn) Rebind

func (c *Conn) Rebind()

Rebind closes and re-binds the UDP sockets and resets the DERP connection. It should be followed by a call to ReSTUN.

func (*Conn) Send

func (c *Conn) Send(buffs [][]byte, ep conn.Endpoint) error

Send implements conn.Bind.

See https://pkg.go.dev/golang.zx2c4.com/wireguard/conn#Bind.Send

func (*Conn) ServeHTTPDebug

func (c *Conn) ServeHTTPDebug(w http.ResponseWriter, r *http.Request)

ServeHTTPDebug serves an HTML representation of the innards of c for debugging.

It's accessible either from tailscaled's debug port (at /debug/magicsock) or via peerapi to a peer that's owned by the same user (so they can e.g. inspect their phones).

func (*Conn) SetDERPMap

func (c *Conn) SetDERPMap(dm *tailcfg.DERPMap)

SetDERPMap controls which (if any) DERP servers are used. A nil value means to disable DERP; it's disabled by default.

func (*Conn) SetDebugLoggingEnabled

func (c *Conn) SetDebugLoggingEnabled(v bool)

SetDebugLoggingEnabled controls whether spammy debug logging is enabled.

Note that this is currently independent from the log levels, even though they're pretty correlated: debugging logs should be [v1] (or higher), but some non-debug logs may also still have a [vN] annotation. The [vN] level controls which gets shown in stderr. The dlogf method, on the other hand, controls which gets even printed or uploaded at any level.

func (*Conn) SetHomeless

func (c *Conn) SetHomeless(v bool)

SetHomeless sets whether magicsock should idle harder and not have a DERP home connection active and not search for its nearest DERP home. In this homeless mode, the node is unreachable by others.

func (*Conn) SetNetInfoCallback

func (c *Conn) SetNetInfoCallback(fn func(*tailcfg.NetInfo))

SetNetInfoCallback sets the func to be called whenever the network conditions change.

At most one func can be registered; the most recent one replaces any previous registration.

This is called by LocalBackend.

func (*Conn) SetNetworkMap

func (c *Conn) SetNetworkMap(nm *netmap.NetworkMap)

SetNetworkMap is called when the control client gets a new network map from the control server. It must always be non-nil.

It should not use the DERPMap field of NetworkMap; that's conditionally sent to SetDERPMap instead.

func (*Conn) SetNetworkUp

func (c *Conn) SetNetworkUp(up bool)

func (*Conn) SetPreferredPort

func (c *Conn) SetPreferredPort(port uint16)

SetPreferredPort sets the connection's preferred local port.

func (*Conn) SetPrivateKey

func (c *Conn) SetPrivateKey(privateKey key.NodePrivate) error

SetPrivateKey sets the connection's private key.

This is only used to be able prove our identity when connecting to DERP servers.

If the private key changes, any DERP connections are torn down & recreated when needed.

func (*Conn) SetProbeUDPLifetime

func (c *Conn) SetProbeUDPLifetime(v bool)

SetProbeUDPLifetime toggles probing of UDP lifetime based on v.

func (*Conn) SetSilentDisco

func (c *Conn) SetSilentDisco(v bool)

SetSilentDisco toggles silent disco based on v.

func (*Conn) SetStatistics

func (c *Conn) SetStatistics(stats *connstats.Statistics)

SetStatistics specifies a per-connection statistics aggregator. Nil may be specified to disable statistics gathering.

func (*Conn) ShouldPMTUD

func (c *Conn) ShouldPMTUD() bool

ShouldPMTUD returns true if this client should try to enable peer MTU discovery, false otherwise.

func (*Conn) SilentDisco

func (c *Conn) SilentDisco() bool

SilentDisco returns true if silent disco is enabled, otherwise false.

func (*Conn) UpdateNetmapDelta

func (c *Conn) UpdateNetmapDelta(muts []netmap.NodeMutation) (handled bool)

UpdateNetmapDelta implements controlclient.NetmapDeltaUpdater.

func (*Conn) UpdatePMTUD

func (c *Conn) UpdatePMTUD()

UpdatePMTUD configures the underlying sockets of this Conn to enable or disable peer path MTU discovery according to the current configuration.

Enabling or disabling peer path MTU discovery requires setting the don't fragment bit on its two underlying pconns. There are three distinct results for this operation on each pconn:

1. Success 2. Failure (not supported on this platform, or supported but failed) 3. Not a UDP socket (most likely one of IPv4 or IPv6 couldn't be used)

To simplify the fast path for the most common case, we set the PMTUD status of the overall Conn according to the results of setting the sockopt on pconn as follows:

1. Both setsockopts succeed: PMTUD status update succeeds 2. One succeeds, one returns not a UDP socket: PMTUD status update succeeds 4. Neither setsockopt succeeds: PMTUD disabled 3. Either setsockopt fails: PMTUD disabled

If the PMTUD settings changed, it resets the endpoint state so that it will re-probe path MTUs to this peer.

func (*Conn) UpdatePeers

func (c *Conn) UpdatePeers(newPeers set.Set[key.NodePublic])

UpdatePeers is called when the set of WireGuard peers changes. It then removes any state for old peers.

The caller passes ownership of newPeers map to UpdatePeers.

func (*Conn) UpdateStatus

func (c *Conn) UpdateStatus(sb *ipnstate.StatusBuilder)

UpdateStatus implements the interface nede by ipnstate.StatusBuilder.

This method adds in the magicsock-specific information only. Most of the status is otherwise populated by LocalBackend.

type EndpointChange

type EndpointChange struct {
	When time.Time // when the change occurred
	What string    // what this change is
	From any       `json:",omitempty"` // information about the previous state
	To   any       `json:",omitempty"` // information about the new state
}

EndpointChange is a structure containing information about changes made to a particular endpoint. This is not a stable interface and could change at any time.

type Options

type Options struct {
	// Logf optionally provides a log function to use.
	// Must not be nil.
	Logf logger.Logf

	// Port is the port to listen on.
	// Zero means to pick one automatically.
	Port uint16

	// EndpointsFunc optionally provides a func to be called when
	// endpoints change. The called func does not own the slice.
	EndpointsFunc func([]tailcfg.Endpoint)

	// DERPActiveFunc optionally provides a func to be called when
	// a connection is made to a DERP server.
	DERPActiveFunc func()

	// IdleFunc optionally provides a func to return how long
	// it's been since a TUN packet was sent or received.
	IdleFunc func() time.Duration

	// TestOnlyPacketListener optionally specifies how to create PacketConns.
	// Only used by tests.
	TestOnlyPacketListener nettype.PacketListener

	// NoteRecvActivity, if provided, is a func for magicsock to call
	// whenever it receives a packet from a a peer if it's been more
	// than ~10 seconds since the last one. (10 seconds is somewhat
	// arbitrary; the sole user just doesn't need or want it called on
	// every packet, just every minute or two for WireGuard timeouts,
	// and 10 seconds seems like a good trade-off between often enough
	// and not too often.)
	// The provided func is likely to call back into
	// Conn.ParseEndpoint, which acquires Conn.mu. As such, you should
	// not hold Conn.mu while calling it.
	NoteRecvActivity func(key.NodePublic)

	// NetMon is the network monitor to use.
	// With one, the portmapper won't be used.
	NetMon *netmon.Monitor

	// ControlKnobs are the set of control knobs to use.
	// If nil, they're ignored and not updated.
	ControlKnobs *controlknobs.Knobs

	// OnPortUpdate is called with the new port when magicsock rebinds to
	// a new port.
	OnPortUpdate func(port uint16, network string)
}

Options contains options for Listen.

type ProbeUDPLifetimeConfig

type ProbeUDPLifetimeConfig struct {
	// The timeout cliffs to probe. Values are in ascending order. Ascending
	// order is chosen over descending because we have limited opportunities to
	// probe. With a descending order we are stuck waiting for a new UDP
	// path/session if the first value times out. When that new path is
	// established is anyone's guess.
	Cliffs []time.Duration
	// CycleCanStartEvery represents the min duration between cycles starting
	// up.
	CycleCanStartEvery time.Duration
}

ProbeUDPLifetimeConfig represents the configuration for probing UDP path lifetime.

func (*ProbeUDPLifetimeConfig) Equals

Equals returns true if b equals p, otherwise false. If both sides are nil, Equals returns true. If only one side is nil, Equals returns false.

func (*ProbeUDPLifetimeConfig) Valid

func (p *ProbeUDPLifetimeConfig) Valid() bool

Valid returns true if p is valid, otherwise false. p must be non-nil.

type RebindingUDPConn

type RebindingUDPConn struct {
	// contains filtered or unexported fields
}

RebindingUDPConn is a UDP socket that can be re-bound. Unix has no notion of re-binding a socket, so we swap it out for a new one.

func (*RebindingUDPConn) Close

func (c *RebindingUDPConn) Close() error

func (*RebindingUDPConn) LocalAddr

func (c *RebindingUDPConn) LocalAddr() *net.UDPAddr

func (*RebindingUDPConn) Port

func (c *RebindingUDPConn) Port() uint16

func (*RebindingUDPConn) ReadBatch

func (c *RebindingUDPConn) ReadBatch(msgs []ipv6.Message, flags int) (int, error)

ReadBatch reads messages from c into msgs. It returns the number of messages the caller should evaluate for nonzero len, as a zero len message may fall on either side of a nonzero.

func (*RebindingUDPConn) ReadFromUDPAddrPort

func (c *RebindingUDPConn) ReadFromUDPAddrPort(b []byte) (int, netip.AddrPort, error)

ReadFromUDPAddrPort reads a packet from c into b. It returns the number of bytes copied and the source address.

func (*RebindingUDPConn) SyscallConn

func (c *RebindingUDPConn) SyscallConn() (syscall.RawConn, error)

func (*RebindingUDPConn) WriteBatchTo

func (c *RebindingUDPConn) WriteBatchTo(buffs [][]byte, addr netip.AddrPort) error

WriteBatchTo writes buffs to addr.

func (*RebindingUDPConn) WriteToUDPAddrPort

func (c *RebindingUDPConn) WriteToUDPAddrPort(b []byte, addr netip.AddrPort) (int, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL