[ 
https://issues.apache.org/jira/browse/SSHD-1123?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17305362#comment-17305362
 ] 

Lyor Goldstein edited comment on SSHD-1123 at 3/20/21, 8:15 AM:
----------------------------------------------------------------

Hi [~ahuegendp] - thanks for the contribution - merged it in with 
acknowledgement (see 
[commit|https://github.com/apache/mina-sshd/commit/098760248c37e628723529c2c49c5a353606ff23]).
 I also took the liberty of adding +configurable+ support for this feature - 
see {{ChannelSession#isSendChunkIfRemoteWindowIsSmallerThanPacketSize}}. 
Basically, this enables you to register a {{SessionListener}} on the server 
side, examine each new session's reported client version and then set the 
relevant properties:
{code:java}
SshServer sshd= ...setup server...
sshd.addSessionListener(new SessionListener() {
    @Override
    public void sessionPeerIdentificationReceived(
            Session session, String version, List<String> extraLines) {
        if (isVersionOfInterest(version)) {
             
CoreModuleProperties.ASYNC_SERVER_STDOUT_CHUNK_BELOW_WINDOW_SIZE.set(session, 
true);
CoreModuleProperties.ASYNC_SERVER_STDERR_CHUNK_BELOW_WINDOW_SIZE.set(session, 
true);
        }
    }
})
{code}
This way you don't have to extend {{ChannelSession}} - which is not an easy 
task. BTW, you can also set this +globally+ by applying the properties to the 
_sshd_ server instance instead of registering a {{SessionListener}}.


was (Author: lgoldstein):
Hi [~ahuegendp] - thanks for the contribution - merged it in with 
acknowledgement (see 
[commit|https://github.com/apache/mina-sshd/commit/098760248c37e628723529c2c49c5a353606ff23]).
 I also took the liberty of adding +configurable+ support for this feature - 
see {{ChannelSession#isSendChunkIfRemoteWindowIsSmallerThanPacketSize}}. 
Basically, this enables you to register a {{SessionListener}} on the server 
side, examine each new session's reported client version and then set the 
relevant properties:
{code:java}
SshServer sshd= ...setup server...
sshd.addSessionListener(new SessionListener() {
    @Override
    public void sessionPeerIdentificationReceived(
            Session session, String version, List<String> extraLines) {
        if (isVersionOfInterest(version)) {
             
CoreModuleProperties.ASYNC_SERVER_STDOUT_CHUNK_BELOW_WINDOW_SIZE.set(session, 
true);
CoreModuleProperties.ASYNC_SERVER_STDERR_CHUNK_BELOW_WINDOW_SIZE.set(session, 
true);
        }
    }
})
{code}
This way you don't have to extend {{ChannelSession}} - which is not an easy task

> ChannelAsyncOutputStream breaks downloads of sftp client by not chunking when 
> the remote window is smaller than the packet size
> -------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: SSHD-1123
>                 URL: https://issues.apache.org/jira/browse/SSHD-1123
>             Project: MINA SSHD
>          Issue Type: Bug
>    Affects Versions: 2.6.0
>            Reporter: Achim Hügen
>            Assignee: Lyor Goldstein
>            Priority: Major
>             Fix For: 2.7.0
>
>         Attachments: download.js, package.json
>
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> After the upgrade from 2.4.0 to 2.6.0 we experienced issues with a SFTP 
> Client used in our test automation (Node.JS ssh2). The download of a file 
> hangs after about 1MB of 5MB has been downloaded. 
> Although this ssh2 version (0.4.15) is admittedly quite old and meanwhile a 
> fix is available, we are reluctant to rollout 2.6.0 to production where a 
> multitude of sftp clients is used by customers and might experience the same 
> issue. 
> Short story: the specific ssh2 client only adjusts its local windows size, if 
> the window size is down to 0. But mina in version 2.6 usually will stop 
> sending data before. So both parties are waiting for each other.
> Example: the window size of the client is 1048576 and packet size is 32768.
> After successfully requesting 1015808 of file data, when the clients reads 
> the next 32768 bytes, the remote window size as calculated by the MINA is 
> 31706 bytes. Thus the data to send is larger then the remaining space in the 
> window. 
> The old logic in 2.4 just filled the window to the brim by chunking the data. 
> Some newly introduced logic (see 
> https://github.com/apache/mina-sshd/commit/536d066349f41a6f6a7f95501506cd1ba66dad7a)
>  now decides to stop sending more data, because the remote window size is 
> smaller then the packet size.
> The server waits for the client to send a SSH_MSG_CHANNEL_WINDOW_ADJUST and 
> the client doesn't do this, because the window still has some space.
> Unfortunately the commit doesn't contain any reference to why this was 
> changed. As I understand the SSH specification, the packet size is a maximum 
> packet size. So, it should be ok to send a smaller packet. 
> This is the code causing the issue in ChannelAsyncOutputStream.
> {code:java}
> if (total > remoteWindowSize) {
>     // if we have a big message and there is enough space, send the next chunk
>     if (remoteWindowSize >= packetSize) {
>         // send the first chunk as we have enough space in the window
>         length = packetSize;
>     } else {
>         // do not chunk when the window is smaller than the packet size
>         length = 0;
>         // do a defensive copy in case the user reuses the buffer
>         IoWriteFutureImpl f = new IoWriteFutureImpl(future.getId(), new 
> ByteArrayBuffer(buffer.getCompactData()));
>         f.addListener(w -> future.setValue(w.getException() != null ? 
> w.getException() : w.isWritten()));
>         pendingWrite.set(f);
>         if (log.isTraceEnabled()) {
>             log.trace("doWriteIfPossible({})[resume={}] waiting for window 
> space {}",
>                     this, resume, remoteWindowSize);
>         }
>     }
>  {code}
> I have attached code for reproducing the issue. To run you need node.js and 
> npm installed: 
> {code}
> npm install
> nodejs download.js
> {code}
>  
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@mina.apache.org
For additional commands, e-mail: dev-h...@mina.apache.org

Reply via email to