[
https://issues.apache.org/jira/browse/SSHD-1262?focusedWorklogId=770489&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-770489
]
ASF GitHub Bot logged work on SSHD-1262:
----------------------------------------
Author: ASF GitHub Bot
Created on: 14/May/22 12:55
Start Date: 14/May/22 12:55
Worklog Time Spent: 10m
Work Description: tomaswolf opened a new pull request, #223:
URL: https://github.com/apache/mina-sshd/pull/223
TCP/IP port forwarding started reading on the local port before the SSH
tunnel was established, i.e., before SSH_MSG_CHANNEL_OPEN_CONFIRMATION
was received. It buffered data until then, and then tried to flush the
buffer once the confirmation was received.
This didn't work if the channel window was exhausted while that buffered
data was to be written, and in particular it failed when the channel was
opened with an initial window size of zero.
Change the whole forwarding setup: first set up the SSH tunnel, only
then start reading from the local port. That way, no data needs to be
buffered at all.
Use a ChannelAsyncOutputStream to forward data read into the SSH tunnel;
this nicely adapts to the channel window. To avoid concurrent writes on
this channel, suspend reading from the local port before writing, and
resume it only after the data was written. This automatically throttles
reading to the speed of writing, which is what one wants in this case.
Implement IOSession.suspendRead() and IOSession.resumeRead() also for
the MINA and Netty back-ends. Fix the implementation for the NIO2
back-end: the former implementation of resumeRead() could cause
concurrent reads if the channel indeed did an asynchronous read, and if
the channel did a synchronous read it led to deep completion handler
chains on the stack, and could delay the next read on some other
session's completion handler. Resolve this for our use-case by
scheduling an asynchronous read explicitly if necessary, and letting
the normal read completion handler do the read if possible.
Do this also for the TcpipServerChannel: it started reading from the
connected port before it even sent SSH_MSG_CHANNEL_OPEN_CONFIRMATION.
Remove the BufferedIoOutputStream and use a ChannelAsyncOutputStream
always.
Include technical documentation on TCP/IP port forwarding.
Issue Time Tracking
-------------------
Worklog Id: (was: 770489)
Remaining Estimate: 0h
Time Spent: 10m
> Unhandled SSH_MSG_CHANNEL_WINDOW_ADJUST leeds to SocketTimeoutException
> -----------------------------------------------------------------------
>
> Key: SSHD-1262
> URL: https://issues.apache.org/jira/browse/SSHD-1262
> Project: MINA SSHD
> Issue Type: Bug
> Affects Versions: 2.7.0, 2.8.0
> Reporter: Stefan Maute
> Assignee: Thomas Wolf
> Priority: Major
> Labels: mina, sshd
> Attachments: failing-pf-trace-logs.txt
>
> Time Spent: 10m
> Remaining Estimate: 0h
>
> Wanted to open a local port forwarding to an SSH server and afterwards
> connect to MQTT server over the SSh tunnel. During the MQTT connection
> attempt I encountered a SocketTimeoutException in the logs (StackTrace below).
> What I could see in the logs is that the server is sending an initial window
> size of 0 and afterwards the _waitForCondition_ method is throwing the
> SocketTimeoutException .
> After analyzing the logs I maybe have an idea what is going on here. My
> assumption is that there is some deadlock in case the initial window size is
> 0 and the SSH_MSG_CHANNEL_WINDOW_ADJUST isn't handled properly.
> I have attached the whole log file. Lines of interest are from 169 to 229.
> Tested with 2.7.0 and 2.8.0.
>
> {code:java}
> WARN org.apache.sshd.common.forward.DefaultForwarder -
> exceptionCaught(Nio2Session[local=/127.0.0.1:44259, remote=/127.0.0.1:60188])
> SocketTimeoutException:
> waitForCondition(Window[client/remote](TcpipClientChannel[id=0,
> recipient=0]-ClientSessionImpl[Admin@/x.xxx.xx.x:xxxx])) timeout exceeded:
> PT30S java.net.SocketTimeoutException:
> waitForCondition(Window[client/remote](TcpipClientChannel[id=0,
> recipient=0]-ClientSessionImpl[Admin@/x.xxx.xx.x:xxxx])) timeout exceeded:
> PT30S at
> org.apache.sshd.common.channel.Window.waitForCondition(Window.java:332)
> at org.apache.sshd.common.channel.Window.waitForSpace(Window.java:286) at
> org.apache.sshd.common.channel.ChannelOutputStream.write(ChannelOutputStream.java:154)
> at
> org.apache.sshd.client.channel.ClientChannelPendingMessagesQueue.writeMessage(ClientChannelPendingMessagesQueue.java:174)
> at
> org.apache.sshd.client.channel.ClientChannelPendingMessagesQueue.flushPendingQueue(ClientChannelPendingMessagesQueue.java:221)
> at
> org.apache.sshd.client.channel.ClientChannelPendingMessagesQueue.operationComplete(ClientChannelPendingMessagesQueue.java:206)
> at
> org.apache.sshd.client.channel.ClientChannelPendingMessagesQueue.operationComplete(ClientChannelPendingMessagesQueue.java:51)
> at
> org.apache.sshd.common.future.AbstractSshFuture.notifyListener(AbstractSshFuture.java:159)
> at
> org.apache.sshd.common.future.DefaultSshFuture.notifyListeners(DefaultSshFuture.java:215)
> at
> org.apache.sshd.common.future.DefaultSshFuture.setValue(DefaultSshFuture.java:112)
> at
> org.apache.sshd.client.future.DefaultOpenFuture.setOpened(DefaultOpenFuture.java:68)
> at
> org.apache.sshd.client.channel.AbstractClientChannel.handleOpenSuccess(AbstractClientChannel.java:360)
> at
> org.apache.sshd.common.session.helpers.AbstractConnectionService.channelOpenConfirmation(AbstractConnectionService.java:545)
> at
> org.apache.sshd.common.session.helpers.AbstractConnectionService.process(AbstractConnectionService.java:456)
> at
> org.apache.sshd.common.session.helpers.AbstractSession.doHandleMessage(AbstractSession.java:503)
> at
> org.apache.sshd.common.session.helpers.AbstractSession.handleMessage(AbstractSession.java:429)
> at
> org.apache.sshd.common.session.helpers.AbstractSession.decode(AbstractSession.java:1466)
> at
> org.apache.sshd.common.session.helpers.AbstractSession.messageReceived(AbstractSession.java:389)
> at
> org.apache.sshd.common.session.helpers.AbstractSessionIoHandler.messageReceived(AbstractSessionIoHandler.java:64)
> at
> org.apache.sshd.common.io.nio2.Nio2Session.handleReadCycleCompletion(Nio2Session.java:359)
> at
> org.apache.sshd.common.io.nio2.Nio2Session$1.onCompleted(Nio2Session.java:336)
> at
> org.apache.sshd.common.io.nio2.Nio2Session$1.onCompleted(Nio2Session.java:333)
> at
> org.apache.sshd.common.io.nio2.Nio2CompletionHandler.lambda$completed$0(Nio2CompletionHandler.java:38)
> at
> java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
> at
> org.apache.sshd.common.io.nio2.Nio2CompletionHandler.completed(Nio2CompletionHandler.java:37)
> at java.base/sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:129) at
> java.base/sun.nio.ch.Invoker$2.run(Invoker.java:221) at
> java.base/sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:113)
> at
> java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
> at
> java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
> at java.base/java.lang.Thread.run(Thread.java:833) {code}
>
>
--
This message was sent by Atlassian Jira
(v8.20.7#820007)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]