Skip to content

Fix/daemon concurrency - #49

Open
dkoryto wants to merge 2 commits into
alebeck:mainfrom
dkoryto:fix/daemon-concurrency
Open

dkoryto wants to merge 2 commits into
alebeck:mainfrom
dkoryto:fix/daemon-concurrency

Conversation

@dkoryto

@dkoryto dkoryto commented Sep 28, 2026

Copy link
Copy Markdown

No description provided.

Closing the same tunnel from several clients at once could crash the
daemon with "close of closed channel": Close only checked Status, which
stays Open until the run loop has shut the tunnel down. The stop channel
is now closed through a sync.Once, so Close is safe to call repeatedly.

Status and LastConn were written by the tunnel goroutines and read by
the daemon for 'list' without synchronization. They are now guarded by
a mutex in Tunnel, and the daemon lists tunnels through Snapshot.

Goroutines tracked by the tunnel's WaitGroup called Add from inside the
new goroutine, racing with Wait. goWait (formerly waitFor) now calls Add
before starting the goroutine.

Opening the same tunnel concurrently let every client past the 'already
running' check, so all but one failed with 'address already in use'.
The name is now reserved while Open is in progress. Other clients wait
for that attempt and report the tunnel as already running, or retry if
it failed.

A closed tunnel was removed from the daemon by name, so a tunnel that
was reopened quickly under the same name could be dropped from the map
while still running. Removal now checks it is the same tunnel, and
closeTunnel removes it before responding.

Covered by unit tests for Tunnel.Close, Snapshot and the daemon's name
reservation, plus e2e tests that open and close the same tunnel from
several clients at once.
A client can also lose the race after the tunnel has shut down but
before it was removed from the daemon, which is reported as 'trying to
close a closed tunnel'. That is as correct as the other two outcomes,
so the test must not fail on it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant