mirror of
https://github.com/juanfont/headscale.git
synced 2026-10-31 18:54:11 +09:00
The ephemeral garbage collector was only armed when a long-poll session ended, or for every ephemeral node at startup. A client that registered and went away before its first long-poll reached Connect, for example a pod killed right after login, never ended a session, so no deletion timer was armed. The node then stayed until headscale restarted, well past node.ephemeral.inactivity_timeout. Schedule the GC right after the auth-key registration, before the error check: a failed policy refresh still returns the saved node. The existing Cancel in serveLongPoll stops the timer once the node connects. A timer that fires while a session is live is still skipped by the ActiveSessions check. TestEphemeralGCDoesNotDeleteReconnectedNode now checks that registration arms the timer and cancels it before replaying its sessions. Otherwise the 50ms timer could fire while the test's Connect was still waiting for a NodeStore flush. TestFailedReconnectDoesNotCancelEphemeralGC and TestDeleteNodeCancelsEphemeralGC ran with a zero inactivity timeout, so the registration timer deleted the node at once, and the delete cancelled the timer the tests armed themselves. They now use 5s, which outlasts the tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>