Skip to content

Commit

Permalink
add workaround for Rebex SSH server (described workaround in code);
Browse files Browse the repository at this point in the history
add  possibility to activate the workaround by setting an entry in the specificConfig;

Signed-off-by: Stefan Maute <stefan.maute@bosch.io>
  • Loading branch information
Stefan Maute committed Apr 13, 2022
1 parent c412699 commit 26fad35
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
Expand Up @@ -177,7 +177,8 @@ private void handleConnectResult(final ConnectFuture connectFuture) throws IOExc
logger.debug("SSH session connected successfully.");
sshSession = connectFuture.getClientSession();
sshSession.addSessionListener(new TunnelSessionListener(getSelf(), logger));
sshSession.addChannelListener(new TunnelChannelListener(getSelf(), logger));
sshSession.addChannelListener(new TunnelChannelListener(getSelf(),
this.connection.getSpecificConfig().getOrDefault("initialWindowSize","0"), logger));
sshSession.setServerKeyVerifier(serverKeyVerifier);
sshSession.setUserAuthFactoriesNames(sshUserAuthMethod);
connection.getSshTunnel()
Expand Down
Expand Up @@ -25,18 +25,29 @@
*/
final class TunnelChannelListener implements ChannelListener {

private static final String TUNNEL_EXCEPTION_MESSAGE = "Opening SSH channel failed with exception";
private final ActorRef sshTunnelActor;
private final LoggingAdapter logger;
private int initialWindowSize;

/**
* Instantiates a new {@code TunnelChannelListener}.
*
* @param sshTunnelActor actor reference of SshTunnelActor to notify about errors
* @param initialWindowSize the initial window size to use for the Remote Window
* @param logger the logger
*/
TunnelChannelListener(final ActorRef sshTunnelActor, final LoggingAdapter logger) {
TunnelChannelListener(final ActorRef sshTunnelActor, final String initialWindowSize, final LoggingAdapter logger) {
this.sshTunnelActor = sshTunnelActor;
this.logger = logger;
try {
this.initialWindowSize = Integer.parseInt(initialWindowSize);
}
catch (final NumberFormatException e) {
final SshTunnelActor.TunnelClosed tunnelClosed =
new SshTunnelActor.TunnelClosed(TUNNEL_EXCEPTION_MESSAGE, e);
sshTunnelActor.tell(tunnelClosed, ActorRef.noSender());
}
}

@Override
Expand All @@ -46,14 +57,22 @@ public void channelInitialized(final Channel channel) {

@Override
public void channelOpenSuccess(final Channel channel) {
if (initialWindowSize > 0) {
// workaround for Rebex SSH server
// SSH server sends initial window size of 0 which causes problems when sending data over
// the SSH channel right after creation. Write results in SocketTimeoutException and
// SSH_MSG_CHANNEL_WINDOW_ADJUST from server is not handled properly.
// Expanding the remote window fixes the problem
channel.getRemoteWindow().expand(initialWindowSize);
}
logger.debug("SSH channel opened successfully: {}", channel);
}

@Override
public void channelOpenFailure(final Channel channel, final Throwable reason) {
if (reason != null) {
final SshTunnelActor.TunnelClosed tunnelClosed =
new SshTunnelActor.TunnelClosed("Opening SSH channel failed with exception", reason);
new SshTunnelActor.TunnelClosed(TUNNEL_EXCEPTION_MESSAGE, reason);
sshTunnelActor.tell(tunnelClosed, ActorRef.noSender());
}
}
Expand Down Expand Up @@ -83,8 +102,7 @@ public void channelClosed(final Channel channel, final Throwable reason) {
final Throwable exception = future.getException();
if (exception != null) {
final SshTunnelActor.TunnelClosed tunnelClosed =
new SshTunnelActor.TunnelClosed("Opening SSH channel failed with exception",
exception);
new SshTunnelActor.TunnelClosed(TUNNEL_EXCEPTION_MESSAGE, exception);
sshTunnelActor.tell(tunnelClosed, ActorRef.noSender());
}
});
Expand Down

0 comments on commit 26fad35

Please sign in to comment.