mirror of
https://github.com/tailscale/tailscale.git
synced 2026-05-06 04:36:15 +02:00
Replace the UAPI text protocol-based wireguard configuration with wireguard-go's new direct callback API (SetPeerLookupFunc, SetPeerByIPPacketFunc, RemoveMatchingPeers, SetPrivateKey). Instead of computing a trimmed wireguard config ahead of time upon control plane updates and pushing it via UAPI, install callbacks so wireguard-go creates peers on demand when packets arrive. This removes all the LazyWG trimming machinery: idle peer tracking, activity maps, noteRecvActivity callbacks, the KeepFullWGConfig control knob, and the ts_omit_lazywg build tag. For incoming packets, PeerLookupFunc answers wireguard-go's questions about unknown public keys by looking up the peer in the full config. For outgoing packets, PeerByIPPacketFunc (installed from LocalBackend.lookupPeerByIP) maps destination IPs to node public keys using the existing nodeByAddr index. Updates tailscale/corp#12345 Change-Id: I4cba80979ac49a1231d00a01fdba5f0c2af95dd8 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
84 lines
2.4 KiB
Go
84 lines
2.4 KiB
Go
// Copyright (c) Tailscale Inc & contributors
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
// Package wgcfg has types and a parser for representing WireGuard config.
|
|
package wgcfg
|
|
|
|
import (
|
|
"net/netip"
|
|
"slices"
|
|
|
|
"tailscale.com/types/key"
|
|
"tailscale.com/types/logid"
|
|
)
|
|
|
|
//go:generate go run tailscale.com/cmd/cloner -type=Config,Peer
|
|
|
|
// Config is a WireGuard configuration.
|
|
// It only supports the set of things Tailscale uses.
|
|
type Config struct {
|
|
PrivateKey key.NodePrivate
|
|
Addresses []netip.Prefix
|
|
MTU uint16
|
|
DNS []netip.Addr
|
|
Peers []Peer
|
|
|
|
// NetworkLogging enables network logging.
|
|
// It is disabled if either ID is the zero value.
|
|
// LogExitFlowEnabled indicates whether or not exit flows should be logged.
|
|
NetworkLogging struct {
|
|
NodeID logid.PrivateID
|
|
DomainID logid.PrivateID
|
|
LogExitFlowEnabled bool
|
|
}
|
|
}
|
|
|
|
func (c *Config) Equal(o *Config) bool {
|
|
if c == nil || o == nil {
|
|
return c == o
|
|
}
|
|
return c.PrivateKey.Equal(o.PrivateKey) &&
|
|
c.MTU == o.MTU &&
|
|
c.NetworkLogging == o.NetworkLogging &&
|
|
slices.Equal(c.Addresses, o.Addresses) &&
|
|
slices.Equal(c.DNS, o.DNS) &&
|
|
slices.EqualFunc(c.Peers, o.Peers, Peer.Equal)
|
|
}
|
|
|
|
type Peer struct {
|
|
PublicKey key.NodePublic
|
|
DiscoKey key.DiscoPublic // present only so we can handle restarts within wgengine, not passed to WireGuard
|
|
AllowedIPs []netip.Prefix
|
|
V4MasqAddr *netip.Addr // if non-nil, masquerade IPv4 traffic to this peer using this address
|
|
V6MasqAddr *netip.Addr // if non-nil, masquerade IPv6 traffic to this peer using this address
|
|
IsJailed bool // if true, this peer is jailed and cannot initiate connections
|
|
PersistentKeepalive uint16 // in seconds between keep-alives; 0 to disable
|
|
}
|
|
|
|
func addrPtrEq(a, b *netip.Addr) bool {
|
|
if a == nil || b == nil {
|
|
return a == b
|
|
}
|
|
return *a == *b
|
|
}
|
|
|
|
func (p Peer) Equal(o Peer) bool {
|
|
return p.PublicKey == o.PublicKey &&
|
|
p.DiscoKey == o.DiscoKey &&
|
|
slices.Equal(p.AllowedIPs, o.AllowedIPs) &&
|
|
p.IsJailed == o.IsJailed &&
|
|
p.PersistentKeepalive == o.PersistentKeepalive &&
|
|
addrPtrEq(p.V4MasqAddr, o.V4MasqAddr) &&
|
|
addrPtrEq(p.V6MasqAddr, o.V6MasqAddr)
|
|
}
|
|
|
|
// PeerWithKey returns the Peer with key k and reports whether it was found.
|
|
func (config Config) PeerWithKey(k key.NodePublic) (Peer, bool) {
|
|
for _, p := range config.Peers {
|
|
if p.PublicKey == k {
|
|
return p, true
|
|
}
|
|
}
|
|
return Peer{}, false
|
|
}
|