X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=netconf%2Fnetconf-netty-util%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetconf%2Fnettyutil%2Fhandler%2Fssh%2Fclient%2FAsyncSshHandler.java;h=15882ded63ec8d1acfdf09f0f9284e5d59a65f8e;hb=0a078764e40c24d565098ddff5ec8be01b5e79f6;hp=fa59b344b86ad1ca29c26c3cf7a3d2f971207523;hpb=df1a4dbb37e0fb187c6d50d3bab1f9d88b888928;p=netconf.git diff --git a/netconf/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/client/AsyncSshHandler.java b/netconf/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/client/AsyncSshHandler.java index fa59b344b8..15882ded63 100644 --- a/netconf/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/client/AsyncSshHandler.java +++ b/netconf/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/client/AsyncSshHandler.java @@ -16,6 +16,7 @@ import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import java.io.IOException; import java.net.SocketAddress; +import java.util.concurrent.atomic.AtomicBoolean; import org.apache.sshd.client.SshClient; import org.apache.sshd.client.channel.ClientChannel; import org.apache.sshd.client.future.AuthFuture; @@ -52,6 +53,7 @@ public class AsyncSshHandler extends ChannelOutboundHandlerAdapter { private final AuthenticationHandler authenticationHandler; private final SshClient sshClient; + private final AtomicBoolean isDisconnected = new AtomicBoolean(); private Future negotiationFuture; private AsyncSshHandlerReader sshReadAsyncListener; @@ -164,7 +166,7 @@ public class AsyncSshHandler extends ChannelOutboundHandlerAdapter { ClientChannel localChannel = channel; sshReadAsyncListener = new AsyncSshHandlerReader(() -> AsyncSshHandler.this.disconnect(ctx, ctx.newPromise()), - msg -> ctx.fireChannelRead(msg), localChannel.toString(), localChannel.getAsyncOut()); + ctx::fireChannelRead, localChannel.toString(), localChannel.getAsyncOut()); // if readAsyncListener receives immediate close, // it will close this handler and closing this handler sets channel variable to null @@ -213,11 +215,17 @@ public class AsyncSshHandler extends ChannelOutboundHandlerAdapter { disconnect(ctx, promise); } - @SuppressWarnings("checkstyle:IllegalCatch") @Override - public synchronized void disconnect(final ChannelHandlerContext ctx, final ChannelPromise promise) { + public void disconnect(final ChannelHandlerContext ctx, final ChannelPromise promise) { + if (isDisconnected.compareAndSet(false, true)) { + safelyDisconnect(ctx, promise); + } + } + + @SuppressWarnings("checkstyle:IllegalCatch") + private synchronized void safelyDisconnect(final ChannelHandlerContext ctx, final ChannelPromise promise) { LOG.trace("Closing SSH session on channel: {} with connect promise in state: {}", - ctx.channel(),connectPromise); + ctx.channel(), connectPromise); // If we have already succeeded and the session was dropped after, // we need to fire inactive to notify reconnect logic @@ -272,5 +280,4 @@ public class AsyncSshHandler extends ChannelOutboundHandlerAdapter { promise.setSuccess(); LOG.debug("SSH session closed on channel: {}", ctx.channel()); } - }