[
https://issues.apache.org/jira/browse/SSHD-1288?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17576406#comment-17576406
]
Thomas Wolf commented on SSHD-1288:
-----------------------------------
Yes, it looks like this case is not handled.
OpenSSH falls back to sequential read requests when it detects that it is
beyond the expected eof. Which makes sense, the client doesn't know anymore how
much data there is, so it cannot send multiple requests ahead.
{{SftpInputStreamAsync}} must account for this, and once it hits the expected
length of the file it must
* not issue more "ahead of time" read requests,
* issue only a single request for the next chunk.
> Infinite loop in org.apache.sshd.sftp.client.impl.SftpInputStreamAsync#doRead
> -----------------------------------------------------------------------------
>
> Key: SSHD-1288
> URL: https://issues.apache.org/jira/browse/SSHD-1288
> Project: MINA SSHD
> Issue Type: Bug
> Affects Versions: 2.8.0
> Reporter: Ivan Fiorentini
> Priority: Major
> Attachments: image-2022-08-05-17-08-55-698.png
>
>
> I reported an infinite loop in
> org.apache.sshd.sftp.client.impl.SftpInputStreamAsync#doRead:
> and after the production of a thread and system dump the point in execution
> was:
> {code:java}
> private long doRead(long max, BufferConsumer consumer) throws IOException {
> long orgOffset = clientOffset;
> while (max > 0) {
> if (hasNoData()) {
> if (eofIndicator) {
> break;
> }
> if (!pendingReads.isEmpty()) {
> fillData();
> }
> if (!eofIndicator) {
> sendRequests(); <- (do not send any request ! it does nothing
> !)
> }
> } else {
> int nb = (int) Math.min(max, buffer.available());
> consumer.consume(new ByteArrayBuffer(buffer.array(),
> buffer.rpos(), nb));
> buffer.rpos(buffer.rpos() + nb);
> clientOffset += nb;
> max -= nb;
> }
> }
> return clientOffset - orgOffset;
> }
> {code}
>
> In the system dump it seems the size of file to receive is obtained before
> to start the transfer... this size is 82.132.992 bytes; but during the
> receipt of the data it seems (at the time of the dump) that 82.156.760 was
> successfully received... *_this could happen if , during the file receipt, at
> the remote site the file is written (expanded) with more data._*
> ... but when the size of the received data is greater than the original it
> seems an infinite loop could happen in the
> org.apache.sshd.sftp.client.impl.SftpInputStreamAsync#doRead when the
> sendRequests() is invoked to obtain more data (or receive the end of file);
> In the sendRequest():
> {code:java}
> while (pendingReads.size() < Math.max(1, windowSize / bufferSize)
> && (fileSize <= 0 || requestOffset < fileSize + bufferSize)) {
>
> ... do the send request to obtain more data (or to receive the end of
> file)
> requestOffset += bufferSize;
> }
> {code}
> ... the condition *requestOffset < fileSize + bufferSize*
> is not satisfied if the *requestOffset* >= *fileSize + bufferSize*
> preventing the code from sending a request to receive more data (and/or
> obtain the end of file) and causing the infinite loop.
> The values of the above variables at time of the dump was:
> !image-2022-08-05-17-08-55-698.png!
> ... so that "{*}(fileSize <= 0 || requestOffset < fileSize + bufferSize)"{*}
> is {color:#de350b}*FALSE*{color}
> To reproduce the problem:
> # create the remote file to receive (1Mb size)
> # create SftpClient sftp =
> DefaultSftpClientFactory.NSTANCE.createSftpClient(clientSession)
> # create InputStream is = sftp.read(file, 32768) end read the inputstrem 4kb
> at time
> # stop at the end of while loop block in
> org.apache.sshd.sftp.client.impl.SftpInputStreamAsync#sendRequests
> when the requestOffset > fileSize
> # expand the remote file size to 2Mb
> # remove the stop at point 4 and continue
> # {color:#ffbdad}the code enter into an infinite loop{color}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]