Documentation
¶
Index ¶
- Constants
- Variables
- func DiscardLogf(format string, args ...any)
- func HMAC1(sum *[blake2s.Size]byte, key, in0 []byte)
- func HMAC2(sum *[blake2s.Size]byte, key, in0, in1 []byte)
- func KDF1(t0 *[blake2s.Size]byte, key, input []byte)
- func KDF2(t0, t1 *[blake2s.Size]byte, key, input []byte)
- func KDF3(t0, t1, t2 *[blake2s.Size]byte, key, input []byte)
- func PacketIsRetry(b []byte) bool
- type AllowedIPs
- func (table *AllowedIPs) EntriesForPeer(peer *Peer, cb func(prefix netip.Prefix) bool)
- func (table *AllowedIPs) Insert(prefix netip.Prefix, peer *Peer)
- func (table *AllowedIPs) Lookup(ip []byte) *Peerdeprecated
- func (table *AllowedIPs) LookupFromPacket(src, dst netip.Addr, ipPkt []byte) *Peer
- func (table *AllowedIPs) RemoveByPeer(peer *Peer)
- type CookieChecker
- type CookieGenerator
- type Counter
- type Device
- func (device *Device) BatchSize() int
- func (device *Device) Bind() conn.Bind
- func (device *Device) BindClose() error
- func (device *Device) BindSetMark(mark uint32) error
- func (device *Device) BindUpdate() error
- func (device *Device) Close()
- func (device *Device) ConsumeMessageInitiation(msg *MessageInitiation, endpoint conn.Endpoint) *Peer
- func (device *Device) ConsumeMessageResponse(msg *MessageResponse) (peer *Peer, duplicate bool)
- func (device *Device) CreateMessageInitiation(peer *Peer) (*MessageInitiation, error)
- func (device *Device) CreateMessageResponse(peer *Peer) (*MessageResponse, error)
- func (device *Device) DeleteKeypair(key *Keypair)
- func (device *Device) Down() error
- func (device *Device) GetInboundElement() *QueueInboundElement
- func (device *Device) GetInboundElementsContainer() *QueueInboundElementsContainer
- func (device *Device) GetOutboundElement() *QueueOutboundElement
- func (device *Device) GetOutboundElementsContainer() *QueueOutboundElementsContainer
- func (device *Device) IpcGet() (string, error)
- func (device *Device) IpcGetOperation(w io.Writer) error
- func (device *Device) IpcHandle(socket net.Conn)
- func (device *Device) IpcSet(uapiConf string) error
- func (device *Device) IpcSetOperation(r io.Reader) (err error)
- func (device *Device) IsUnderLoad() bool
- func (device *Device) LookupActivePeer(pk NoisePublicKey) (_ *Peer, ok bool)
- func (device *Device) LookupPeer(pk NoisePublicKey) *Peer
- func (device *Device) NewPeer(pk NoisePublicKey) (*Peer, error)
- func (device *Device) PopulatePools()
- func (device *Device) PutInboundElement(elem *QueueInboundElement)
- func (device *Device) PutInboundElementsContainer(c *QueueInboundElementsContainer)
- func (device *Device) PutOutboundElement(elem *QueueOutboundElement)
- func (device *Device) PutOutboundElementsContainer(c *QueueOutboundElementsContainer)
- func (device *Device) RemoveAllPeers()
- func (device *Device) RemoveMatchingPeers(shouldRemove func(NoisePublicKey) bool) (numRemoved int)
- func (device *Device) RemovePeer(key NoisePublicKey)
- func (device *Device) RoutineDecryption(id int)
- func (device *Device) RoutineEncryption(id int)
- func (device *Device) RoutineHandshake(id int)
- func (device *Device) RoutineReadFromTUN(id int, queue tun.Reader)
- func (device *Device) RoutineReceiveIncoming(recvName string, maxBatchSize int, recv conn.ReceiveFunc)
- func (device *Device) RoutineTUNEventReader()
- func (device *Device) ScheduleHandshakeOnUserSend(peer NoisePublicKey)
- func (device *Device) SendHandshakeCookie(initiatingElem *QueueHandshakeElement) error
- func (device *Device) SendKeepalivesToPeersWithCurrentKeypair()
- func (device *Device) SetPeerByIPPacketFunc(f PeerByIPPacketFunc)
- func (device *Device) SetPeerLookupFunc(f PeerLookupFunc)
- func (device *Device) SetPriorityMessageOnEstablishmentFunc(f PeerPriorityMessageFunc)
- func (device *Device) SetPrivateKey(sk NoisePrivateKey) error
- func (device *Device) SetSessionStateFunc(f PeerSessionStateFunc)
- func (device *Device) Up() error
- func (device *Device) Wait() chan struct{}
- type Handshake
- type IPCError
- type IndexTable
- func (table *IndexTable) Delete(index uint32)
- func (table *IndexTable) Init()
- func (table *IndexTable) Lookup(id uint32) IndexTableEntry
- func (table *IndexTable) NewIndexForHandshake(peer *Peer, handshake *Handshake) (uint32, error)
- func (table *IndexTable) SwapIndexForKeypair(index uint32, keypair *Keypair)
- type IndexTableEntry
- type Keypair
- type Keypairs
- type Logger
- type MessageCookieReply
- type MessageInitiation
- type MessageResponse
- type MessageTransport
- type Metrics
- type NewPeerConfig
- type NoiseNonce
- type NoisePresharedKey
- type NoisePrivateKey
- type NoisePublicKey
- type Option
- func WithMetrics(metrics Metrics) Option
- func WithPeerQueueInboundSize(size int) Option
- func WithPeerQueueOutboundSize(size int) Option
- func WithQueueHandshakeSize(size int) Option
- func WithQueueInboundSize(size int) Option
- func WithQueueOutboundSize(size int) Option
- func WithQueueStagedGlobalLimit(limit int) Option
- func WithQueueStagedSize(size int) Option
- type Peer
- func (peer *Peer) AllowedPeerSourceIP(src netip.Addr) bool
- func (peer *Peer) BeginSymmetricSession() error
- func (peer *Peer) ExpireCurrentKeypairs()
- func (peer *Peer) FlushStagedPackets(limit int)
- func (peer *Peer) NewTimer(expirationFunction func(*Peer)) *Timer
- func (peer *Peer) ReceivedWithKeypair(receivedKeypair *Keypair) bool
- func (peer *Peer) RoutineSequentialReceiver(maxBatchSize int)
- func (peer *Peer) RoutineSequentialSender(maxBatchSize int)
- func (peer *Peer) SendBuffers(buffers [][]byte) error
- func (peer *Peer) SendHandshakeInitiation(isRetry bool) error
- func (peer *Peer) SendHandshakeResponse(isRetry bool) error
- func (peer *Peer) SendKeepalive()
- func (peer *Peer) SendPriorityMessage()
- func (peer *Peer) SendStagedPackets(stagedDelta int)
- func (p *Peer) SetAllowedIPs(allowedIPs []netip.Prefix)
- func (p *Peer) SetHybridHandshake(hybrid bool)
- func (p *Peer) SetPresharedKey(psk NoisePresharedKey)
- func (peer *Peer) StagePackets(elems *QueueOutboundElementsContainer) (stagedDelta int)
- func (peer *Peer) Start()
- func (peer *Peer) Stop()
- func (peer *Peer) String() string
- func (peer *Peer) ZeroAndFlushAll()
- type PeerByIPPacketFunc
- type PeerLookupFunc
- type PeerPriorityMessageFunc
- type PeerSessionState
- type PeerSessionStateFunc
- type QueueHandshakeElement
- type QueueInboundElement
- type QueueInboundElementsContainer
- type QueueOutboundElement
- type QueueOutboundElementsContainer
- type Timer
Constants ¶
const ( RekeyAfterMessages = (1 << 60) RejectAfterMessages = (1 << 64) - (1 << 13) - 1 RekeyAfterTime = time.Second * 120 RekeyAttemptTime = time.Second * 90 RekeyTimeout = time.Second * 5 MaxTimerHandshakes = 90 / 5 /* RekeyAttemptTime / RekeyTimeout */ RekeyTimeoutJitterMaxMs = 334 RejectAfterTime = time.Second * 180 KeepaliveTimeout = time.Second * 10 CookieRefreshTime = time.Second * 120 HandshakeInitationRate = time.Second / 50 PaddingMultiple = 16 )
const ( MinMessageSize = MessageKeepaliveSize // minimum size of transport message (keepalive) MaxMessageSize = MaxSegmentSize // maximum size of transport message MaxContentSize = MaxSegmentSize - MessageTransportSize - MessageEncapsulatingTransportSize // maximum size of transport message content )
const ( UnderLoadAfterTime = time.Second // how long does the device remain under load after detected MaxPeers = 1 << 16 // maximum number of configured peers )
const ( IPv4offsetTotalLength = 2 IPv4offsetSrc = 12 IPv4offsetDst = IPv4offsetSrc + net.IPv4len )
const ( IPv6offsetPayloadLength = 4 IPv6offsetSrc = 8 IPv6offsetDst = IPv6offsetSrc + net.IPv6len )
const ( LogLevelSilent = iota LogLevelError LogLevelVerbose )
Log levels for use with NewLogger.
const ( NoiseConstruction = "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s" HybridNoiseConstruction = "Noise_IKhfs+psk2_25519+MLKEM768_ChaChaPoly_BLAKE2s" WGIdentifier = "WireGuard v1 zx2c4 Jason@zx2c4.com" WGLabelMAC1 = "mac1----" WGLabelCookie = "cookie--" )
const ( MessageInitiationType = 1 MessageResponseType = 2 MessageCookieReplyType = 3 MessageTransportType = 4 )
const ( MessageInitiationSize = 148 // size of handshake initiation message MessageResponseSize = 92 // size of response message MessageHybridInitiationSize = MessageInitiationSize + NoiseKEMEncapsulationKeySize + poly1305.TagSize MessageHybridResponseSize = MessageResponseSize + NoiseKEMCiphertextSize + poly1305.TagSize MessageCookieReplySize = 64 // size of cookie reply message MessageTransportHeaderSize = 16 // size of data preceding content in transport message MessageEncapsulatingTransportSize = 8 // size of optional, free (for use by conn.Bind.Send()) space preceding the transport header MessageTransportSize = MessageTransportHeaderSize + poly1305.TagSize // size of empty transport MessageKeepaliveSize = MessageTransportSize // size of keepalive )
const ( MessageTransportOffsetReceiver = 4 MessageTransportOffsetCounter = 8 MessageTransportOffsetContent = 16 )
const ( NoisePublicKeySize = 32 NoisePrivateKeySize = 32 NoiseKEMEncapsulationKeySize = mlkem.EncapsulationKeySize768 NoiseKEMCiphertextSize = mlkem.CiphertextSize768 )
const ( DefaultQueueStagedSize = conn.IdealBatchSize DefaultQueueOutboundSize = 1024 DefaultQueueInboundSize = 1024 DefaultQueueHandshakeSize = 1024 MaxSegmentSize = (1 << 16) - 1 // largest possible UDP datagram DefaultQueueStagedGlobalLimit = 0 )
const DefaultMTU = 1420
const MaxPriorityMessageContentSize = 512
MaxPriorityMessageContentSize is the maximum size of a message returned by a PeerPriorityMessageFunc. It's a power of 2 that leaves significant space when accounting for all WireGuard overhead and encapsulating network protocol headers. Future adjustments to this value should consider all these overheads and any conn.Bind implementation limitations.
Variables ¶
Functions ¶
func DiscardLogf ¶
Function for use in Logger for discarding logged lines.
func PacketIsRetry ¶
PacketIsRetry reports whether the given packet appears to be a retried handshake.
Clients can use this to route retried handshake packets over more reliable but costlier data paths, to improve handshake success rates on problematic networks.
The returned indication is a hint with no cryptographic assurance. The caller must not make any security critical decisions based on this indication.
Retries are a Tailscale specific feature of handshake packets. PacketIsRetry always returns false for standard WireGuard handshake packets.
Types ¶
type AllowedIPs ¶
type AllowedIPs struct {
// contains filtered or unexported fields
}
func (*AllowedIPs) EntriesForPeer ¶
func (table *AllowedIPs) EntriesForPeer(peer *Peer, cb func(prefix netip.Prefix) bool)
func (*AllowedIPs) Lookup
deprecated
func (table *AllowedIPs) Lookup(ip []byte) *Peer
Deprecated: Lookup is only used by legacy tests. It does not call PeerByIPPacketFunc; use AllowedIPs.LookupFromPacket for production lookups.
func (*AllowedIPs) LookupFromPacket ¶
func (table *AllowedIPs) LookupFromPacket(src, dst netip.Addr, ipPkt []byte) *Peer
LookupFromPacket looks up the peer to which an outbound IP packet should be sent. It lives on AllowedIPs for legacy/structural reasons: historically WireGuard's only peer-selection mechanism was the AllowedIPs trie, and the send path already had a reference to the table. When a PeerByIPPacketFunc has been registered via Device.SetPeerByIPPacketFunc, that callback is used instead of the trie and the AllowedIPs table is not consulted at all.
When no callback is registered, only dst is used (standard WireGuard AllowedIPs trie lookup). When a callback is registered, all three parameters are forwarded to it; see PeerByIPPacketFunc for details.
func (*AllowedIPs) RemoveByPeer ¶
func (table *AllowedIPs) RemoveByPeer(peer *Peer)
type CookieChecker ¶
func (*CookieChecker) CheckMAC1 ¶
func (st *CookieChecker) CheckMAC1(msg []byte) bool
func (*CookieChecker) CheckMAC2 ¶
func (st *CookieChecker) CheckMAC2(msg, src []byte) bool
func (*CookieChecker) CreateReply ¶
func (st *CookieChecker) CreateReply( msg []byte, recv uint32, src []byte, ) (*MessageCookieReply, error)
func (*CookieChecker) Init ¶
func (st *CookieChecker) Init(pk NoisePublicKey)
type CookieGenerator ¶
func (*CookieGenerator) AddMacs ¶
func (st *CookieGenerator) AddMacs(msg []byte)
func (*CookieGenerator) ConsumeReply ¶
func (st *CookieGenerator) ConsumeReply(msg *MessageCookieReply) bool
func (*CookieGenerator) Init ¶
func (st *CookieGenerator) Init(pk NoisePublicKey)
type Counter ¶
type Counter interface {
// Add increments the Counter's value by n. n must not be negative. Add is
// called in performance-sensitive contexts, therefore it must be cheap. Add
// may be called concurrently.
Add(n int64)
}
Counter is a monotonically increasing counter used in Metrics.
type Device ¶
type Device struct {
// contains filtered or unexported fields
}
func (*Device) BatchSize ¶
BatchSize returns the BatchSize for the device as a whole which is the max of the bind batch size and the tun batch size. The batch size reported by device is the size used to construct memory pools, and is the allowed batch size for the lifetime of the device.
func (*Device) BindSetMark ¶
func (*Device) BindUpdate ¶
func (*Device) ConsumeMessageInitiation ¶
func (device *Device) ConsumeMessageInitiation(msg *MessageInitiation, endpoint conn.Endpoint) *Peer
func (*Device) ConsumeMessageResponse ¶
func (device *Device) ConsumeMessageResponse(msg *MessageResponse) (peer *Peer, duplicate bool)
func (*Device) CreateMessageInitiation ¶
func (device *Device) CreateMessageInitiation(peer *Peer) (*MessageInitiation, error)
func (*Device) CreateMessageResponse ¶
func (device *Device) CreateMessageResponse(peer *Peer) (*MessageResponse, error)
func (*Device) DeleteKeypair ¶
func (*Device) GetInboundElement ¶
func (device *Device) GetInboundElement() *QueueInboundElement
func (*Device) GetInboundElementsContainer ¶
func (device *Device) GetInboundElementsContainer() *QueueInboundElementsContainer
func (*Device) GetOutboundElement ¶
func (device *Device) GetOutboundElement() *QueueOutboundElement
GetOutboundElement returns a *QueueOutboundElement with all its fields set to their respective zero values.
func (*Device) GetOutboundElementsContainer ¶
func (device *Device) GetOutboundElementsContainer() *QueueOutboundElementsContainer
func (*Device) IpcGetOperation ¶
IpcGetOperation implements the WireGuard configuration protocol "get" operation. See https://www.wireguard.com/xplatform/#configuration-protocol for details.
func (*Device) IpcSetOperation ¶
IpcSetOperation implements the WireGuard configuration protocol "set" operation. See https://www.wireguard.com/xplatform/#configuration-protocol for details.
func (*Device) IsUnderLoad ¶
func (*Device) LookupActivePeer ¶
func (device *Device) LookupActivePeer(pk NoisePublicKey) (_ *Peer, ok bool)
LookupActivePeer looks up a peer by its public key.
Unlike Device.LookupPeer, this function does not use a PeerLookupFunc to create the peer if it does not already exist.
If the peer does not exist or was created lazily via PeerLookupFunc and has subsequently idled away, it returns (nil, false).
func (*Device) LookupPeer ¶
func (device *Device) LookupPeer(pk NoisePublicKey) *Peer
LookupPeer looks up a peer by its public key.
If the peer does not exist and a PeerLookupFunc is set (via Device.SetPeerLookupFunc), then that function is used to create the peer before returning it. Peers created via this mechanism exist only until their state machine reaches idle, and then the peers are removed.
If the peer does not exist and no PeerLookupFunc is set, nil is returned.
Use Device.LookupActivePeer to only return already-existing peers, without using a PeerLookupFunc.
func (*Device) NewPeer ¶
func (device *Device) NewPeer(pk NoisePublicKey) (*Peer, error)
NewPeer creates and publishes an unconfigured peer for pk.
Safe to configure post-factum in Device.IpcSetOperation because of the global ipc mutex.
func (*Device) PopulatePools ¶
func (device *Device) PopulatePools()
func (*Device) PutInboundElement ¶
func (device *Device) PutInboundElement(elem *QueueInboundElement)
func (*Device) PutInboundElementsContainer ¶
func (device *Device) PutInboundElementsContainer(c *QueueInboundElementsContainer)
func (*Device) PutOutboundElement ¶
func (device *Device) PutOutboundElement(elem *QueueOutboundElement)
func (*Device) PutOutboundElementsContainer ¶
func (device *Device) PutOutboundElementsContainer(c *QueueOutboundElementsContainer)
func (*Device) RemoveAllPeers ¶
func (device *Device) RemoveAllPeers()
func (*Device) RemoveMatchingPeers ¶
func (device *Device) RemoveMatchingPeers(shouldRemove func(NoisePublicKey) bool) (numRemoved int)
RemoveMatchingPeers removes all peers for which shouldRemove returns true.
It returns the number of peers removed.
func (*Device) RemovePeer ¶
func (device *Device) RemovePeer(key NoisePublicKey)
func (*Device) RoutineDecryption ¶
func (*Device) RoutineEncryption ¶
Encrypts the elements in the queue * and marks them for sequential consumption (by releasing the mutex) * * Obs. One instance per core
func (*Device) RoutineHandshake ¶
Handles incoming packets related to handshake
func (*Device) RoutineReadFromTUN ¶
func (*Device) RoutineReceiveIncoming ¶
func (device *Device) RoutineReceiveIncoming(recvName string, maxBatchSize int, recv conn.ReceiveFunc)
RoutineReceiveIncoming receives incoming datagrams from one of the bind's receive queues. A new routine is started for each queue every time the bind is updated. recvName identifies the queue in logs; see conn.NamesOf.
func (*Device) RoutineTUNEventReader ¶
func (device *Device) RoutineTUNEventReader()
func (*Device) ScheduleHandshakeOnUserSend ¶
func (device *Device) ScheduleHandshakeOnUserSend(peer NoisePublicKey)
ScheduleHandshakeOnUserSend marks the peer for handshake initiation immediately following its next outbound transport message. It is a no-op if the peer is unknown or currently holds no key material.
The initiation remains subject to RekeyTimeout elapsing since the last handshake message was sent. A request blocked by that window stays armed for a later transport message rather than being dropped.
func (*Device) SendHandshakeCookie ¶
func (device *Device) SendHandshakeCookie(initiatingElem *QueueHandshakeElement) error
func (*Device) SendKeepalivesToPeersWithCurrentKeypair ¶
func (device *Device) SendKeepalivesToPeersWithCurrentKeypair()
func (*Device) SetPeerByIPPacketFunc ¶
func (device *Device) SetPeerByIPPacketFunc(f PeerByIPPacketFunc)
SetPeerByIPPacketFunc sets the function used to look up peers by IP address when sending packets to unknown peers.
func (*Device) SetPeerLookupFunc ¶
func (device *Device) SetPeerLookupFunc(f PeerLookupFunc)
SetPeerLookupFunc sets the function used to look up peers by public key when receiving packets for unknown peers.
func (*Device) SetPriorityMessageOnEstablishmentFunc ¶
func (device *Device) SetPriorityMessageOnEstablishmentFunc(f PeerPriorityMessageFunc)
SetPriorityMessageOnEstablishmentFunc sets a function to be used for sending a priority message around session establishment. See PeerPriorityMessageFunc docs for more details. A nil value clears any previously set value.
func (*Device) SetPrivateKey ¶
func (device *Device) SetPrivateKey(sk NoisePrivateKey) error
func (*Device) SetSessionStateFunc ¶
func (device *Device) SetSessionStateFunc(f PeerSessionStateFunc)
SetSessionStateFunc sets the function used to observe peer WireGuard session state changes.
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.
The callback must be concurrent-safe and must not call back into Device.
type IndexTable ¶
func (*IndexTable) Delete ¶
func (table *IndexTable) Delete(index uint32)
func (*IndexTable) Init ¶
func (table *IndexTable) Init()
func (*IndexTable) Lookup ¶
func (table *IndexTable) Lookup(id uint32) IndexTableEntry
func (*IndexTable) NewIndexForHandshake ¶
func (table *IndexTable) NewIndexForHandshake(peer *Peer, handshake *Handshake) (uint32, error)
func (*IndexTable) SwapIndexForKeypair ¶
func (table *IndexTable) SwapIndexForKeypair(index uint32, keypair *Keypair)
type IndexTableEntry ¶
type IndexTableEntry struct {
// contains filtered or unexported fields
}
type Logger ¶
type Logger struct {
Verbosef func(format string, args ...any)
Errorf func(format string, args ...any)
}
A Logger provides logging for a Device. The functions are Printf-style functions. They must be safe for concurrent use. They do not require a trailing newline in the format. If nil, that level of logging will be silent.
type MessageCookieReply ¶
type MessageCookieReply struct {
Type uint32
Receiver uint32
Nonce [chacha20poly1305.NonceSizeX]byte
Cookie [blake2s.Size128 + poly1305.TagSize]byte
}
type MessageInitiation ¶
type MessageInitiation struct {
Type uint32
IsRetry bool
Sender uint32
Ephemeral NoisePublicKey
HasKEM bool
EphemeralKEM [NoiseKEMEncapsulationKeySize + poly1305.TagSize]byte
Static [NoisePublicKeySize + poly1305.TagSize]byte
Timestamp [tai64n.TimestampSize + poly1305.TagSize]byte
MAC1 [blake2s.Size128]byte
MAC2 [blake2s.Size128]byte
}
type MessageResponse ¶
type MessageTransport ¶
type Metrics ¶
type Metrics struct {
// MessageInitiationTXAttemptInitial counts non-retry handshake
// initiation messages passed to the network send path.
MessageInitiationTXAttemptInitial Counter
// MessageHybridInitiationTXAttemptInitial counts non-retry hybrid
// handshake initiation messages passed to the network send path.
MessageHybridInitiationTXAttemptInitial Counter
// MessageInitiationTXAttemptRetry counts retry handshake initiation
// messages passed to the network send path.
MessageInitiationTXAttemptRetry Counter
// MessageHybridInitiationTXAttemptRetry counts retry hybrid handshake
// initiation messages passed to the network send path.
MessageHybridInitiationTXAttemptRetry Counter
// MessageResponseTXAttempt counts handshake response messages passed to the
// network send path.
MessageResponseTXAttempt Counter
// MessageHybridResponseTXAttempt counts hybrid handshake response messages passed
// to the network send path.
MessageHybridResponseTXAttempt Counter
// MessageCookieReplyTXAttempt counts cookie reply messages passed to the
// network send path.
MessageCookieReplyTXAttempt Counter
// HandshakeInitiatorCompleted counts symmetric session establishment on the
// initiator side.
HandshakeInitiatorCompleted Counter
// HandshakeHybridInitiatorCompleted counts hybrid symmetric session establishment
// on the initiator side.
HandshakeHybridInitiatorCompleted Counter
// HandshakeResponderCompleted counts responder-side handshake completions,
// observed when an authenticated transport packet confirms the new keypair.
HandshakeResponderCompleted Counter
// HandshakeHybridResponderCompleted counts responder-side hybrid handshake
// completions, observed when an authenticated transport packet confirms the
// new keypair.
HandshakeHybridResponderCompleted Counter
// MessageTransportRXDroppedReplay counts inbound transport packets rejected by the
// replay filter.
MessageTransportRXDroppedReplay Counter
}
Metrics contains metrics that can be exported via WithMetrics.
type NewPeerConfig ¶
type NewPeerConfig struct {
// AllowedIPs is the initial set of allowed IPs for the new peer.
AllowedIPs []netip.Prefix
// value disables the optional WireGuard pre-shared-key layer.
PresharedKey NoisePresharedKey
// Hybrid is whether to use a hybrid post-quantum handshake with this peer.
//
// The hybrid handshake grants forward secrecy to session traffic in the face of a
// quantum attacker. That is, an attacker who records traffic today and acquires a quantum
// computer in the future will not be able to decrypt the recorded traffic.
//
// Both peers must agree on this setting to communicate, there is no fallback between
// handshake types.
Hybrid bool
// Endpoint, if non-nil, sets the endpoint for newly created peers.
// The endpoint is pinned for the lifetime of the peer.
Endpoint conn.Endpoint
}
NewPeerConfig are the configuration parameters for a new peer created via a PeerLookupFunc func.
type NoiseNonce ¶
type NoiseNonce uint64 // padded to 12-bytes
type NoisePresharedKey ¶
type NoisePresharedKey [NoisePresharedKeySize]byte
func (*NoisePresharedKey) FromHex ¶
func (key *NoisePresharedKey) FromHex(src string) error
type NoisePrivateKey ¶
type NoisePrivateKey [NoisePrivateKeySize]byte
func (NoisePrivateKey) Equals ¶
func (key NoisePrivateKey) Equals(tar NoisePrivateKey) bool
func (*NoisePrivateKey) FromHex ¶
func (key *NoisePrivateKey) FromHex(src string) (err error)
func (*NoisePrivateKey) FromMaybeZeroHex ¶
func (key *NoisePrivateKey) FromMaybeZeroHex(src string) (err error)
func (NoisePrivateKey) IsZero ¶
func (key NoisePrivateKey) IsZero() bool
type NoisePublicKey ¶
type NoisePublicKey [NoisePublicKeySize]byte
func (NoisePublicKey) Equals ¶
func (key NoisePublicKey) Equals(tar NoisePublicKey) bool
func (*NoisePublicKey) FromHex ¶
func (key *NoisePublicKey) FromHex(src string) error
func (NoisePublicKey) IsZero ¶
func (key NoisePublicKey) IsZero() bool
type Option ¶
type Option interface {
// contains filtered or unexported methods
}
An Option configures a Device.
func WithMetrics ¶
WithMetrics sets the provided Metrics to be used at instrumentation points.
func WithPeerQueueInboundSize ¶
WithPeerQueueInboundSize sets the capacity of each peer's inbound packet queue, overriding WithQueueInboundSize.
func WithPeerQueueOutboundSize ¶
WithPeerQueueOutboundSize sets the capacity of each peer's outbound packet queue, overriding WithQueueOutboundSize.
func WithQueueHandshakeSize ¶
WithQueueHandshakeSize sets the capacity of the device's handshake queue. DefaultQueueHandshakeSize is the default.
func WithQueueInboundSize ¶
WithQueueInboundSize sets the capacity of the device-wide outbound packet queue, defaulting to DefaultQueueInboundSize.
This also limits the per-peer outbound packet queue, unless overridden by WithPeerQueueInboundSize.
func WithQueueOutboundSize ¶
WithQueueOutboundSize sets the capacity of the device-wide outbound packet queue, defaulting to DefaultQueueOutboundSize.
This also limits the per-peer outbound packet queue, unless overridden by WithPeerQueueOutboundSize.
func WithQueueStagedGlobalLimit ¶
WithQueueStagedGlobalLimit sets the maximum number of packet container objects outstanding across all staged queues. DefaultQueueStagedGlobalLimit is the default. Non-positive values disable it. It counts objects which are long-lived, i.e. objects sitting in queues awaiting handshake. It is not an exact limit, it may temporarily over or undercount. It exists to limit the amount of memory consumed by packets. Packets awaiting handshake will be dropped if limit is exceeded. If limit is greater than zero, and less than the size of an individual peer's staged queue (WithQueueStagedSize), it will be silently raised to match.
func WithQueueStagedSize ¶
WithQueueStagedSize sets the capacity of each peer's staged packet queue. Staged packet queues must be buffered, so max(tun readers, size) is applied to the user-supplied value. DefaultQueueStagedSize is the default.
type Peer ¶
type Peer struct {
// contains filtered or unexported fields
}
func (*Peer) AllowedPeerSourceIP ¶
AllowedPeerSourceIP reports whether the given source IP address is allowed for the given peer.
func (*Peer) BeginSymmetricSession ¶
Derives a new keypair from the current handshake state *
func (*Peer) ExpireCurrentKeypairs ¶
func (peer *Peer) ExpireCurrentKeypairs()
func (*Peer) FlushStagedPackets ¶
FlushStagedPackets drains elements from [Peer.queue.staged] up to limit. If limit is zero, FlushStagedPackets drains all elements.
func (*Peer) ReceivedWithKeypair ¶
func (*Peer) RoutineSequentialReceiver ¶
func (*Peer) RoutineSequentialSender ¶
func (*Peer) SendBuffers ¶
SendBuffers sends buffers to peer. WireGuard packet data in each element of buffers must be preceded by MessageEncapsulatingTransportSize number of bytes.
func (*Peer) SendHandshakeInitiation ¶
func (*Peer) SendHandshakeResponse ¶
func (*Peer) SendKeepalive ¶
func (peer *Peer) SendKeepalive()
SendKeepalive queues a keepalive if no packets are queued for peer.
func (*Peer) SendPriorityMessage ¶
func (peer *Peer) SendPriorityMessage()
SendPriorityMessage invokes the PeerPriorityMessageFunc callback if one is set, and queues the returned message for encryption and transmission if the current keypair is valid.
func (*Peer) SendStagedPackets ¶
SendStagedPackets sends any staged packets to Peer, if a valid keypair and nonce are available.
It accepts a delta for preceding len(peer.queue.staged) operations. Said delta gets combined with what it performs, and committed to device-wide stage queue accounting, if a global staged queue limit is configured.
SendStagedPackets accepts stagedDelta in order to intentionally delay device-wide stage queue accounting commit until the end of this func. This strategy limits staged queue accounting to long-lived elements, i.e. those awaiting a future handshake, and does not include elements that stage and are immediately transmitted.
func (*Peer) SetAllowedIPs ¶
SetAllowedIPs sets the allowed IP prefixes for this peer.
If the allowedIPs are unchanged since the last call, this method is a no-op. It's the caller's responsibility to ensure that no two peers have duplicate allowed IPs. If so, the last writer wins.
func (*Peer) SetHybridHandshake ¶
SetHybridHandshake sets whether this peer should use hybrid post-quantum handshakes. Both peers must use the same setting for communication to be possible.
func (*Peer) SetPresharedKey ¶
func (p *Peer) SetPresharedKey(psk NoisePresharedKey)
SetPresharedKey sets the optional WireGuard pre-shared key for this peer. The zero value disables the pre-shared-key layer.
func (*Peer) StagePackets ¶
func (peer *Peer) StagePackets(elems *QueueOutboundElementsContainer) (stagedDelta int)
StagePackets attempts to enqueue elements into the peer's staging queue. If the queue is full, its oldest member is dropped to make room. If the peer is not running, the data is quietly dropped.
It returns a delta for len(peer.queue.staged) operations, which must be passed in a subsequent call to Peer.SendStagedPackets, where global stage queue accounting changes are committed.
[Peer.nonceMu] relies on this function being non-blocking.
func (*Peer) ZeroAndFlushAll ¶
func (peer *Peer) ZeroAndFlushAll()
type PeerByIPPacketFunc ¶
type PeerByIPPacketFunc func(src, dst netip.Addr, ipPkt []byte) (_ NoisePublicKey, ok bool)
PeerByIPPacketFunc is the type of function used to look up a peer to send to for a given src/dst IP pair. The ipPkt parameter is the raw IP packet being routed; callers needing transport-layer ports or other header fields may parse them from ipPkt, but must handle IP fragmentation (ports may be absent on non-first fragments) and protocols that do not use ports (e.g. ICMP).
Except for experimental use cases, dst is the only address that should be relied upon when looking up a peer.
If it returns ok=false, the peer is not known.
See Device.SetPeerByIPPacketFunc and Device.SetPeerLookupFunc.
type PeerLookupFunc ¶
type PeerLookupFunc func(NoisePublicKey) (_ *NewPeerConfig, ok bool)
PeerLookupFunc is the type of function used to look up peers by public key when receiving packets for unknown peers.
If it returns nil, the peer is not known.
Otherwise, returning non-nil signals that wireguard-go should create the peer with the provided allowed IPs.
type PeerPriorityMessageFunc ¶
type PeerPriorityMessageFunc func(peer NoisePublicKey) (msg []byte)
PeerPriorityMessageFunc is called when a peer's WireGuard session keypair is established (or re-keyed) for forward data transmission.
The returned message is transmitted to the peer in priority fashion. Priority means it cannot be evicted from the staged packet queue by non-priority (read from tun.Device) packets. It avoids the staged queue altogether.
The callback must be cheap and must not call back into Device. A zero length message or a message whose length exceeds MaxPriorityMessageContentSize will be silently dropped. Message should start with an IPv4 or IPv6 header as it is subject to allowed IPs lookup on the receiver, same as any other transport message.
type PeerSessionState ¶
type PeerSessionState uint8
PeerSessionState is the current WireGuard session state for a peer.
const ( // PeerSessionNone means there is no handshake in progress and no session key // material retained for this peer. PeerSessionNone PeerSessionState = iota // PeerSessionHandshake means a handshake is in progress for this peer, but // there is not currently a usable WireGuard session. PeerSessionHandshake // PeerSessionEstablished means the peer has a completed WireGuard session // with usable session key material. PeerSessionEstablished // PeerSessionExpired 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. PeerSessionExpired )
type PeerSessionStateFunc ¶
type PeerSessionStateFunc func(peer NoisePublicKey, state PeerSessionState)
PeerSessionStateFunc is called when a peer's WireGuard session state changes.
Calls are serialized per peer and delivered in that peer's transition order. The callback must be cheap and must not call back into Device.
type QueueHandshakeElement ¶
type QueueHandshakeElement struct {
// contains filtered or unexported fields
}
type QueueInboundElement ¶
type QueueInboundElement struct {
// contains filtered or unexported fields
}
type QueueInboundElementsContainer ¶
type QueueInboundElementsContainer struct {
// contains filtered or unexported fields
}
type QueueOutboundElement ¶
type QueueOutboundElement struct {
// contains filtered or unexported fields
}
type QueueOutboundElementsContainer ¶
type QueueOutboundElementsContainer struct {
// contains filtered or unexported fields
}