fix: close underlying TCP conn on stop during TLS handshake#20
Merged
isaac-lee-apex merged 1 commit intomainfrom Feb 10, 2026
Merged
fix: close underlying TCP conn on stop during TLS handshake#20isaac-lee-apex merged 1 commit intomainfrom
isaac-lee-apex merged 1 commit intomainfrom
Conversation
Initiator.Stop() hangs indefinitely when the session is stuck in a TLS handshake (e.g. TCP connects to a server that never sends a TLS ServerHello). The stop-cancellation goroutine cancels the dial context, but after DialContext succeeds the context is no longer relevant and nothing closes the raw net.Conn, so tls.Handshake() blocks forever. Track the raw TCP connection in a mutex-protected variable during the TLS handshake window so the stop-goroutine can close it, which immediately unblocks Handshake() with an error and allows handleConnection to exit normally. Amp-Thread-ID: https://ampcode.com/threads/T-019c4926-8512-75e5-9f4c-9c62f6b65a25 Co-authored-by: Amp <amp@ampcode.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.
Problem
Initiator.Stop()hangs indefinitely when a session is stuck in a TLS handshake.This occurs when TCP connects successfully to a host that never responds to the TLS
ClientHello(e.g. a plain TCP server, a misconfigured endpoint, or a firewall that accepts TCP but drops TLS). The existing stop-cancellation goroutine inhandleConnectioncancels thecontext.Contextused byDialContext, but afterDialContextreturns successfully, the context is no longer relevant. The subsequenttls.Client(netConn, tlsConfig).Handshake()call is a plain blocking operation with no cancellation mechanism — so whenstopChancloses, nothing closes the underlyingnet.Conn, andHandshake()blocks forever. This causesStop()to block onwg.Wait()indefinitely.Other disconnection scenarios (DNS failure, TCP black-hole, TLS to unreachable IP) are unaffected because
Stop()can cancel the TCP dial via the context.Fix
Track the raw TCP connection in a mutex-protected
pendingConnvariable during the TLS handshake window. The stop-cancellation goroutine now closespendingConn(in addition to cancelling the dial context) when a stop signal is received. Closing the underlyingnet.Connimmediately unblocksHandshake()with a "use of closed network connection" error, allowinghandleConnectionto proceed to the reconnect path where it detectsstopChanis closed and exits normally.The
pendingConnis set just beforeHandshake()and cleared immediately after (on both success and error paths), so the close only happens during the TLS handshake window.Testing
Verified with an e2e test (
TestStopDisconnectedInitiatorSession_TLSHandshakeHang) that starts a plain TCP listener, points an SSL-enabled initiator at it, waits for the TLS handshake to stall, then callsStopSession. Before this fix the test timed out after 15s; with the fix it completes in ~4s.Amp Threads: