Repository navigation
Conversation
Every peer the daemon had exchanged keys with got a NAT keepalive every 25 s, path-watchdog probes and resets when quiet, and, when relayed, a direct-upgrade attempt every 15 s (beacon punch, five probes, a registry resolve each minute), forever. The keepalives also counted as contact, so the stale-peer reaper never fired. A service agent with ~4,000 peers and no open connection sent ~120 KB/s of this. Track application traffic per peer. A peer with none for 2 minutes and no open connection gets no keepalives, path probes or upgrade attempts; the reaper then drops it five minutes after its last frame. The reaper now counts relayed inbound frames as contact, so a peer still sending to us is kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two Docker scenarios on a cone NAT with a 10 s UDP conntrack timeout: idle 160 s (keepalives stopped, mapping expired) and idle 8 minutes (both sides reap each other), then an echo in each direction. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The daemon kept every peer it had ever exchanged keys with warm, forever:
relayProbeLoop→tryDirectUpgrade: a beacon punch request, which makes the beacon send a punch command to both sides, plus 5 probes) and a registryResolveevery 60 s (resolve-cache TTL).None of it stopped when the peer stopped being used. It also kept the stale-peer reaper from ever firing:
reapStalePeersdrops a peer with no open connection and no contact for 5 minutes, and the keepalives counted as contact.This change tracks application traffic per peer: anything sent through
SendTo, a new key exchange, and anything delivered to a port other than path probes. A peer with no application traffic for 2 minutes and no open connection gets no keepalives, no path-watchdog probes and no upgrade attempts. Five minutes later the existing reaper removes it, as it was meant to.Why: the service-agent fleet (read-only measurements, 2026-10-06)
pilot-rendezvous, registry + beacon)At ~3,600 relayed peers per agent, the 15 s upgrade loop alone is ~240 attempts/s per daemon. Across 432 agents that is on the order of 100k beacon punch requests/s and 26k registry resolves/s, almost all for peers that have sent nothing in hours. The rendezvous load is an estimate from the code and the counters; a canary agent would measure it.
Functionality
test_tunnel_desync_recovery,test_peer_restarted_*).Tests
TestKeepaliveSweepSkipsIdlePeers,TestOnlyApplicationTrafficCountsAsActivity,TestPathWatchSkipsIdlePeers,TestReaperDropsIdlePeersButKeepsTalkingOnes(the last fails onmain: a peer sending over the relay was reaped).go test ./pkg/... ./cmd/... ./internal/... -shortandgo test ./tests/pass.test_nat_idle_peer_resume.sh: cone NAT with a 10 s UDP conntrack timeout, idle 160 s (keepalives stopped, mapping expired), then an echo each way: pass (also passes onmain).test_nat_idle_peer_reaped.sh: same NAT, idle 8 minutes. On this branch both daemons reaped each other (a-forgot-b b-forgot-a) and the echo each way passes after a fresh key exchange. Onmain:reaped: none, echoes pass.mainpass on this branch. The image was built from a checkout of this branch with tests: make the Docker integration suite build and boot again #506 merged, and the tests ran from that checkout, so the NAT tests'compose up --buildrebuilt the same code.🤖 Generated with Claude Code