diff --git a/src/main/java/net/schmizz/sshj/connection/channel/AbstractChannel.java b/src/main/java/net/schmizz/sshj/connection/channel/AbstractChannel.java index 922018102..e31d0f4ee 100644 --- a/src/main/java/net/schmizz/sshj/connection/channel/AbstractChannel.java +++ b/src/main/java/net/schmizz/sshj/connection/channel/AbstractChannel.java @@ -102,7 +102,8 @@ protected AbstractChannel(Connection conn, String type, Charset remoteCharset) { protected void init(int recipient, long remoteWinSize, long remoteMaxPacketSize) { this.recipient = recipient; - rwin = new Window.Remote(remoteWinSize, (int) Math.min(remoteMaxPacketSize, REMOTE_MAX_PACKET_SIZE_CEILING), loggerFactory); + rwin = new Window.Remote(remoteWinSize, (int) Math.min(remoteMaxPacketSize, REMOTE_MAX_PACKET_SIZE_CEILING), + conn.getTimeoutMs(), loggerFactory); out = new ChannelOutputStream(this, trans, rwin); log.debug("Initialized - {}", this); } diff --git a/src/main/java/net/schmizz/sshj/connection/channel/Window.java b/src/main/java/net/schmizz/sshj/connection/channel/Window.java index 0d6faa12b..5292cea3d 100644 --- a/src/main/java/net/schmizz/sshj/connection/channel/Window.java +++ b/src/main/java/net/schmizz/sshj/connection/channel/Window.java @@ -20,6 +20,8 @@ import net.schmizz.sshj.connection.ConnectionException; import org.slf4j.Logger; +import java.util.concurrent.TimeUnit; + public abstract class Window { protected final Logger log; @@ -73,17 +75,23 @@ public String toString() { /** Controls how much data we can send before an adjustment notification from remote end is required. */ public static final class Remote extends Window { + private final long timeoutMs; - public Remote(long initialWinSize, int maxPacketSize, LoggerFactory loggerFactory) { + public Remote(long initialWinSize, int maxPacketSize, long timeoutMs, LoggerFactory loggerFactory) { super(initialWinSize, maxPacketSize, loggerFactory); + this.timeoutMs = timeoutMs; } public long awaitExpansion(long was) throws ConnectionException { synchronized (lock) { + long end = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(timeoutMs); while (size <= was) { log.debug("Waiting, need size to grow from {} bytes", was); try { - lock.wait(); + lock.wait(timeoutMs); + if ((size <= was) && (end < System.nanoTime())) { + throw new ConnectionException("Timeout when trying to expand the window size"); + } } catch (InterruptedException ie) { throw new ConnectionException(ie); }