device: add API for on-demand configuration of peers
Updates tailscale/tailscale#17858 Signed-off-by: Brad Fitzpatrick <brad@danga.com>
This commit is contained in:
parent
70b09a6edd
commit
e924a91e99
5 changed files with 151 additions and 10 deletions
|
|
@ -8,6 +8,8 @@ package device
|
|||
import (
|
||||
"container/list"
|
||||
"errors"
|
||||
"net/netip"
|
||||
"slices"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
|
@ -27,6 +29,12 @@ type Peer struct {
|
|||
|
||||
queuedOutboundPackets atomic.Int32 // packets in staged+outbound queues, for input backpressure
|
||||
|
||||
// deleteOnIdle indicates whether the peer should be deleted when idle
|
||||
// because it was auto-created via a Device.PeerLookupFunc.
|
||||
//
|
||||
// This field should only be set once, before the peer is started.
|
||||
deleteOnIdle bool
|
||||
|
||||
endpoint struct {
|
||||
sync.Mutex
|
||||
val conn.Endpoint
|
||||
|
|
@ -46,7 +54,9 @@ type Peer struct {
|
|||
}
|
||||
|
||||
state struct {
|
||||
sync.Mutex // protects against concurrent Start/Stop
|
||||
sync.Mutex // protects against concurrent Start/Stop, and fields below
|
||||
|
||||
allowedIPs []netip.Prefix
|
||||
}
|
||||
|
||||
queue struct {
|
||||
|
|
@ -89,7 +99,7 @@ func (device *Device) NewPeer(pk NoisePublicKey) (*Peer, error) {
|
|||
// map public key
|
||||
_, ok := device.peers.keyMap[pk]
|
||||
if ok {
|
||||
return nil, errors.New("adding existing peer")
|
||||
return nil, errAddExistingPeer
|
||||
}
|
||||
|
||||
// pre-compute DH
|
||||
|
|
@ -115,6 +125,22 @@ func (device *Device) NewPeer(pk NoisePublicKey) (*Peer, error) {
|
|||
return peer, nil
|
||||
}
|
||||
|
||||
// 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 (p *Peer) SetAllowedIPs(allowedIPs []netip.Prefix) {
|
||||
p.state.Lock()
|
||||
defer p.state.Unlock()
|
||||
|
||||
if slices.Equal(p.state.allowedIPs, allowedIPs) {
|
||||
return
|
||||
}
|
||||
p.device.allowedips.setPeerPrefixes(p, allowedIPs)
|
||||
p.state.allowedIPs = slices.Clone(allowedIPs) // avoid retaining caller's slice
|
||||
}
|
||||
|
||||
// SendBuffers sends buffers to peer. WireGuard packet data in each element of
|
||||
// buffers must be preceded by MessageEncapsulatingTransportSize number of
|
||||
// bytes.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue