Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions pkg/daemon/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ type TunnelManager struct {
// key" events. Prevents amplification if a peer floods us with gibberish.
rekeyMu sync.Mutex
lastRekeyReq map[uint32]time.Time
// PILOT-345: per-peer whitelist that bypasses BOTH the
// rekeyRequestInterval gate AND the maxRekeyRequesters map cap.
// Whitelisted peers can always trigger a rekey request without
// being throttled or counted against the 4096 bound.
rekeyWhitelist atomic.Pointer[map[uint32]struct{}]

// routing is the L4 manager. It owns:
// - relayPeers, relayPinned, blackholeMissCount, directClearCount,
Expand Down Expand Up @@ -404,14 +409,23 @@ func (tm *TunnelManager) maybeRequestRekey(peerNodeID uint32, from *net.UDPAddr)
if tm.sock == nil {
return false
}
// PILOT-345: whitelisted peers skip both the interval gate and the
// map cap. They still record a timestamp so the prune sweep can
// reclaim entries if the whitelist shrinks later.
whitelisted := false
if wl := tm.rekeyWhitelist.Load(); wl != nil {
if _, ok := (*wl)[peerNodeID]; ok {
whitelisted = true
}
}
tm.rekeyMu.Lock()
last, known := tm.lastRekeyReq[peerNodeID]
now := time.Now()
if known && now.Sub(last) < rekeyRequestInterval {
if !whitelisted && known && now.Sub(last) < rekeyRequestInterval {
tm.rekeyMu.Unlock()
return false
}
if !known && !tm.pruneRekeyBudgetLocked(now) {
if !whitelisted && !known && !tm.pruneRekeyBudgetLocked(now) {
tm.rekeyMu.Unlock()
return false
}
Expand Down Expand Up @@ -529,6 +543,22 @@ func (tm *TunnelManager) SetPeerVerifyFunc(fn func(uint32) (ed25519.PublicKey, e
tm.kx.SetPeerVerifyFunc(keyexchange.VerifyFunc(fn))
}

// SetRekeyWhitelist replaces the per-peer whitelist for the
// maybeRequestRekey gate (PILOT-345). Whitelisted peers bypass BOTH
// the rekeyRequestInterval (3 s) and the maxRekeyRequesters (4096)
// map cap. Empty slice clears the whitelist. Safe to call
// concurrently with maybeRequestRekey.
func (tm *TunnelManager) SetRekeyWhitelist(nodeIDs []uint32) {
wm := make(map[uint32]struct{}, len(nodeIDs))
for _, id := range nodeIDs {
if id == 0 {
continue
}
wm[id] = struct{}{}
}
tm.rekeyWhitelist.Store(&wm)
}

// SetBeaconAddr configures the beacon address for NAT hole-punching and relay.
// Thin shim over routing.Manager.SetBeaconAddr.
func (tm *TunnelManager) SetBeaconAddr(addr string) error {
Expand Down
Loading