From 7cfe640de15aa348aae04999edb63174d390eb07 Mon Sep 17 00:00:00 2001 From: Thomas Wolf Date: Tue, 2 Aug 2022 22:32:49 +0200 Subject: [PATCH] [SSHD-1281] Close Nio2Session properly on failure after connecting If there's an exception in Nio2Connector after the session was set on the DefaultIoConnectFuture, a program might just hang on that session until the next read or write attempt, or until a timeout expired. This was caused by closing the underlying connection, but not properly closing the already existing session, and because the session was already set on the future, setting the exception had no effect anymore. Fix this by immediately closing the Nio2Session properly in that case. --- CHANGES.md | 5 ++++ .../sshd/common/io/nio2/Nio2Connector.java | 26 +++++++++++-------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 3b5b7e418..57ff237e7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,3 +17,8 @@ # [Version 2.8.0 to 2.9.0](./docs/changes/2.9.0.md) # Planned for next version + +## Bug fixes + +* [SSHD-1281](https://issues.apache.org/jira/browse/SSHD-1281) ClientSession.auth().verify() is terminated with timeout +* [SSHD-1285](https://issues.apache.org/jira/browse/SSHD-1285) 2.9.0 release broken on Java 8 diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java index a38dfd0b7..7af9e46ae 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java @@ -179,20 +179,24 @@ protected void onCompleted(Void result, Object attachment) { } } - debug("onCompleted - failed {} to start session: {}", - t.getClass().getSimpleName(), t.getMessage(), t); + log.debug("onCompleted - failed to start session: {} {}", t.getClass().getSimpleName(), t.getMessage(), t); - try { - socket.close(); - } catch (IOException err) { - if (debugEnabled) { - log.debug("onCompleted - failed {} to close socket: {}", - err.getClass().getSimpleName(), err.getMessage()); + IoSession session = future.getSession(); + if (session != null) { + session.close(true); + } else { + try { + socket.close(); + } catch (IOException err) { + if (debugEnabled) { + log.debug("onCompleted - failed to close socket: {} {}", err.getClass().getSimpleName(), + err.getMessage()); + } } - } - future.setException(t); - unmapSession(sessionId); + future.setException(t); + unmapSession(sessionId); + } } }