mirror of
https://github.com/fosrl/gerbil.git
synced 2026-07-15 12:37:11 -05:00
[GH-ISSUE #96] Hole-punch endpoint dedup skips re-registration on reconnect → clients stuck "connected but not registered" (regression in 1.4.x) #767
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @DanivosYoun on GitHub (Jun 13, 2026).
Original GitHub issue: https://github.com/fosrl/gerbil/issues/96
Originally assigned to: @oschwartz10612 on GitHub.
Affected versions
gerbil 1.4.0 / 1.4.1 (works on 1.3.1). Seen with olm 1.6.0 (latest), newt 1.12.2, Pangolin 1.19.x, gerbil running on a remote exit node.
Symptom
After upgrading the remote node's gerbil to 1.4.x, olm clients can no longer finish connecting. The control-plane websocket comes up but registration never completes.
olm /status:The client is stuck on "Registering" indefinitely. Downgrading gerbil to 1.3.1 restores connectivity. The latest olm (1.6.0) does not help — so this is gerbil-side.
Root cause
relay/relay.go(1.4.x) added an endpoint-notification dedup (lastEndpointCache). On a hole-punch packet, gerbil skipsnotifyServer()(POST /gerbil/update-hole-punch) when the client's endpoint state is unchanged:notifyServer()is what registers the client with the server and returns theProxyMappingthat establishes routing — not just an idempotent endpoint update. Because olm credentials/public key are persistent and reconnects often land on the same NAT IP:port, thenewStatematches the cached one, sonotifyServer()is skipped. The server has already torn down the client's session on disconnect, so it never re-registers the client and never returns a freshProxyMapping→registered: false. The cache is in-process, so once primed, every reconnect from the same endpoint is deduplicated → permanent failure until gerbil restarts or the endpoint changes.Reproduce
lastEndpointCache).connected: true, registered: false; noProxyMappingis created.Suggested fix
The dedup must not suppress re-registration when the server no longer has the client's session. Options:
lastEndpointCacheentry whenever the client's sessions are cleared, so a reconnect always re-notifies (simplest), orProxyMappingfor the client still exists, orRelevant code:
relay/relay.go— thelastEndpointCache/cachedEndpointStatededup block, andnotifyServer()→POST /gerbil/update-hole-punch.Hotfix PR
I've already opened a hotfix PR implementing the first option (invalidate the cache entry in the dedup path): #95. Happy to adjust to whichever approach the maintainers prefer.
@oschwartz10612 commented on GitHub (Jun 13, 2026):
Ahh this sounds like it could be an issue