Repository navigation
Conversation
ChannelForwardedTcpip ignored SSH_MSG_CHANNEL_EOF, so the connected host never received end-of-stream when the client stopped sending. Bind stayed blocked in ReadContinuous until the host closed the connection itself, which a host waiting for the client to speak first only does on its own timeout. Shut down the send direction of the socket on EOF, matching ChannelDirectTcpip. The host can still send data back over the channel.
Discolai
requested review from
Rob-Hague,
WojciechNagorski and
drieseng
as code owners
October 23, 2026 09:03
Discolai
marked this pull request as draft
October 23, 2026 09:24
Author
|
I will reopen the PR after i have fixed the flaky tests |
This branch has not been deployed
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.
Fixes #1754
ChannelForwardedTcpipignoredSSH_MSG_CHANNEL_EOF, so the connected host never receivedend-of-stream when the client stopped sending.
Bindstayed blocked inReadContinuousuntil thehost closed the connection itself, which a host waiting for the client to speak first only does on
its own timeout.
We hit this with a TLS server behind
ForwardedPortRemote. Clients that connect and disconnectwithout sending anything, such as TCP health checks, left the server waiting for a
ClientHello and a thread blocked in
Binduntil the server's read timeout expired.This overrides
OnEofto callShutdownSocket(SocketShutdown.Send), asChannelDirectTcpip.OnEofalready does. The socket is not closed. Only the send direction is shut down, so the host can still
send data back over the channel until it closes its own side, and the existing close path then runs
as before. This should address the concern raised in #1754 about data still flowing in the other
direction.
ChannelForwardedTcpipTest_ChannelEofReceivedcovers:SSH_MSG_CHANNEL_EOFSSH_MSG_CHANNEL_DATABindreturns without an exception once the host shuts down its sideAll three fail without the change.
AI usage
I used an AI assistant (Claude) throughout. It traced the root cause by decompiling SSH.NET to find where the thread was blocked, compared
ChannelForwardedTcpipwithChannelDirectTcpip, and wrote the fix and the test. I directed theinvestigation, reviewed the code and the test, chose the wording of the commit, and ran the tests locally.