Repository navigation
libtailscale: key connection cleanup by the Go-owned socket - #69
Open
jamesyong-42 wants to merge 1 commit into
Open
jamesyong-42 wants to merge 1 commit into
jamesyong-42 wants to merge 1 commit into
Conversation
newConn registered each connection in conns under fds[0], the C side of its socketpair, and connCleanup only acts if the entry under that number still belongs to it. TsnetListen closes fds[0] right after passing it to C with SCM_RIGHTS, so the next accepted connection's socketpair usually gets the same number and overwrites the entry while the first connection is still alive. When the first connection ends, its connCleanup finds the newer entry and returns: its net.Conn is never closed, and its end of the socketpair is only closed once the os.File is garbage collected. conns still drains to empty, so TestConn cannot see it. TsnetDial has the same race when C closes its fd and the number is reused before cleanup runs. Key the entry by fds[1] instead. The Go side keeps that fd open until connCleanup deletes the entry and closes it, so its number cannot be reused while the connection is alive. newConn now returns the C fd instead of writing through a *C.int, so the new test can call it directly (test files cannot use cgo types). TestConnCleanupAfterFDReuse fails on main and passes with this change. Fixes tailscale/tailscale#21934 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jamesyong-42
added a commit
to vibecook-dev/truffle
that referenced
this pull request
Oct 25, 2026
The Apple provenance record and upgrade log said the conn-cleanup fix was prepared for upstream. It is now tailscale/libtailscale#69, for tailscale/tailscale#21934. Truffle's patch is the same diff; drop it once the PR lands. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
newConnkeyedconnsby the C side of each connection's socketpair.TsnetListencloses that fd right aftersendmsg, so the next accepted connection usually reuses its number and overwrites the entry while the first connection is still alive. The first connection'sconnCleanupthen skips cleanup: itsnet.Connis never closed, and its socketpair end is only closed by theos.Filefinalizer.connsstill drains to empty, soTestConndoesn't notice.This keys the entry by
fds[1], the Go-owned end. That fd stays open untilconnCleanupdeletes the entry and closes it, so its number can't be reused while the connection is alive. This also coversTsnetDial, where C can close its fd, and the number can be reused, before cleanup runs.newConnnow returns the C fd instead of writing through*C.int, so the new test can call it directly (test files can't use cgo types).TestConnCleanupAfterFDReusefails onmain(all eight C-side fds get the same number, and connection 0 is never closed) and passes with this change.go test -race -count=3 ./...passes on macOS.Found while moving truffle's TailscaleKit build onto
main. Truffle carries an equivalent fix as a local patch until this lands.Fixes tailscale/tailscale#21934
🤖 Generated with Claude Code