This is an automated email from the ASF dual-hosted git repository. twolf pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mina-sshd.git
commit 1b9084f2fdc0d53822cdb423332d74ca1d84b288 Author: Thomas Wolf <tw...@apache.org> AuthorDate: Tue Mar 12 22:11:17 2024 +0100 AbstractClientChannel: fix waiting for channel having closed channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED), timeout) would not wait until the channel was closed, but would return with the CLOSED event already when the channel was still closing. The closeSignaled flag was set already in preClose(), but at that point the SSH_MSG_CHANNEL_CLOSE handshake still had to be done. In the common usage of ``` try (ClientSession session = ...) { // Authenticate, then: try (ChannelExec channel = session.createExecChannel(...)) { // Open the channel, perhaps do something with input/output streams // ... Collection<ClientChannelEvent> result = channel.waitFor(numSet.of(ClientChannelEvent.CLOSED), timeout); } } ``` the call to waitFor() would return early already when the server's SSH_MSG_CHANNEL_CLOSE was received, but before the client's reply was sent. The thread executing this code would then close the channel and then the session, which results in a race with sending that client reply out. If the session got closed first, the client would log an exception about a write attempt on a closed session. Fix this by removing closeSignaled.get() from the conditions for being in CLOSED state. The state is not CLOSED yet; it would be IS_CLOSING at best. --- .../main/java/org/apache/sshd/client/channel/AbstractClientChannel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/AbstractClientChannel.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/AbstractClientChannel.java index a3ed6ffb6..fd12580de 100644 --- a/sshd-core/src/main/java/org/apache/sshd/client/channel/AbstractClientChannel.java +++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/AbstractClientChannel.java @@ -323,7 +323,7 @@ public abstract class AbstractClientChannel extends AbstractChannel implements C if ((openFuture != null) && openFuture.isOpened()) { state.add(ClientChannelEvent.OPENED); } - if (closeFuture.isClosed() || closeSignaled.get() || unregisterSignaled.get() || isClosed()) { + if (closeFuture.isClosed() || unregisterSignaled.get() || isClosed()) { state.add(ClientChannelEvent.CLOSED); } if (isEofSignalled()) {