Repository: mina-sshd
Updated Branches:
  refs/heads/master 51eaca295 -> 3abb90189


[SSHD-848] Possible race condition when tunnel peer closes its side before 
channel fully established


Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/3abb9018
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/3abb9018
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/3abb9018

Branch: refs/heads/master
Commit: 3abb90189065d930fd3c5f572c110295f0f03189
Parents: 51eaca2
Author: roberto.deandrea <[email protected]>
Authored: Thu Oct 11 08:09:39 2018 +0300
Committer: Lyor Goldstein <[email protected]>
Committed: Thu Oct 11 20:19:12 2018 +0300

----------------------------------------------------------------------
 .../apache/sshd/client/future/OpenFuture.java   |  1 -
 .../common/forward/DefaultForwardingFilter.java | 33 +++++++++++++++-----
 2 files changed, 26 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3abb9018/sshd-core/src/main/java/org/apache/sshd/client/future/OpenFuture.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/client/future/OpenFuture.java 
b/sshd-core/src/main/java/org/apache/sshd/client/future/OpenFuture.java
index 2fe780c..587354f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/future/OpenFuture.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/future/OpenFuture.java
@@ -68,5 +68,4 @@ public interface OpenFuture extends SshFuture<OpenFuture>, 
VerifiableFuture<Open
      * this future.
      */
     void cancel();
-
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3abb9018/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultForwardingFilter.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultForwardingFilter.java
 
b/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultForwardingFilter.java
index 040b263..a5cae0d 100644
--- 
a/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultForwardingFilter.java
+++ 
b/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultForwardingFilter.java
@@ -1034,13 +1034,32 @@ public class DefaultForwardingFilter
         public void sessionClosed(IoSession session) throws Exception {
             TcpipClientChannel channel = (TcpipClientChannel) 
session.removeAttribute(TcpipClientChannel.class);
             Throwable cause = (Throwable) 
session.removeAttribute(TcpipForwardingExceptionMarker.class);
-            if (channel != null) {
-                if (debugEnabled) {
-                    log.debug("sessionClosed({}) closing channel={} after {} 
messages - cause={}",
-                            session, channel, messagesCounter, (cause == null) 
? null : cause.getClass().getSimpleName());
-                }
-                // If exception signaled then close channel immediately
-                channel.close(cause != null);
+            if (debugEnabled) {
+                log.debug("sessionClosed({}) closing channel={} after {} 
messages - cause={}",
+                    session, channel, messagesCounter, (cause == null) ? null 
: cause.getClass().getSimpleName());
+            }
+            if (channel == null) {
+                return;
+            }
+
+            if (cause != null) {
+                // If exception occurred close the channel immediately
+                channel.close(true);
+            } else {
+                /*
+                 *  Make sure channel is fully open in case the client was 
very fast
+                 *  and sent data + closed the connection before channel open 
was completed.
+                 */
+                OpenFuture openFuture = channel.getOpenFuture();
+                // If channel is established then listener is invoked 
immediately
+                openFuture.addListener(f -> {
+                    Throwable err = f.getException();
+                    if (err != null) {
+                        log.warn("sessionClosed({}) closing incompletely open 
channel={} after {} messages due to {}[{}]",
+                            session, channel, messagesCounter, 
err.getClass().getSimpleName(), err.getMessage());
+                    }
+                    channel.close(err != null);
+                });
             }
         }
 

Reply via email to