SFTP Large File Fix

1. There were a couple spots during a large file transfer where the
   client rekeying the session would interrupt the transfer and/or
   reset the amount of file data transfered. Fixed that with a check
   for WS_CHAN_RXD.
2. Added a build option to interrupt a file transfer after 2 minutes.
   Large files will take longer.
pull/480/head
John Safranek 2022-12-22 09:52:18 -08:00
parent b211634680
commit bef7f758cc
No known key found for this signature in database
GPG Key ID: 8CE817DE0D3CCB4A
3 changed files with 20 additions and 7 deletions

View File

@ -19,6 +19,7 @@
- Fixes for compiler complaints using GCC 4.0.2
- Fixes for the directory path cleanup function for SFTP
- Fixes for SFTP directory listing when on Windows
- Fixes for large file transfers with SFTP
- Fixes for port forwarding
- Fix for building with QNX
- Fix for the wolfSSHd grace time alarm

View File

@ -123,12 +123,14 @@ static void myStatusCb(WOLFSSH* sshIn, word32* bytes, char* name)
currentTime = current_time(0) - startTime;
WSNPRINTF(buf, sizeof(buf), "Processed %8llu\t bytes in %d seconds\r",
(unsigned long long)longBytes, currentTime);
#ifndef WOLFSSH_NO_SFTP_TIMEOUT
if (currentTime > TIMEOUT_VALUE) {
WSNPRINTF(buf, sizeof(buf), "\nProcess timed out at %d seconds, "
"stopping\r", currentTime);
WMEMSET(currentFile, 0, WOLFSSH_MAX_FILENAME);
wolfSSH_SFTP_Interrupt(ssh);
}
#endif
#else
WSNPRINTF(buf, sizeof(buf), "Processed %8llu\t bytes \r",
(unsigned long long)longBytes);
@ -1016,7 +1018,8 @@ static int doCmds(func_args* args)
if (ret != WS_SUCCESS) {
ret = wolfSSH_get_error(ssh);
}
} while (ret == WS_WANT_READ || ret == WS_WANT_WRITE);
} while (ret == WS_WANT_READ || ret == WS_WANT_WRITE ||
ret == WS_CHAN_RXD);
#ifndef WOLFSSH_NO_TIMESTAMP
WMEMSET(currentFile, 0, WOLFSSH_MAX_FILENAME);
@ -1111,8 +1114,8 @@ static int doCmds(func_args* args)
do {
ret = wolfSSH_SFTP_Put(ssh, pt, to, resume, &myStatusCb);
err = wolfSSH_get_error(ssh);
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE)
&& ret != WS_SUCCESS);
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE ||
err == WS_CHAN_RXD) && ret != WS_SUCCESS);
#ifndef WOLFSSH_NO_TIMESTAMP
WMEMSET(currentFile, 0, WOLFSSH_MAX_FILENAME);
@ -1521,8 +1524,8 @@ static int doAutopilot(int cmd, char* local, char* remote)
ret = wolfSSH_SFTP_Get(ssh, fullpath, local, 0, NULL);
}
err = wolfSSH_get_error(ssh);
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE) &&
ret != WS_SUCCESS);
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE ||
err == WS_CHAN_RXD) && ret != WS_SUCCESS);
if (ret != WS_SUCCESS) {
if (cmd == AUTOPILOT_PUT) {

View File

@ -398,6 +398,16 @@ static WS_SFTPNAME* wolfSSH_SFTPNAME_new(void* heap);
static int SFTP_CreateLongName(WS_SFTPNAME* name);
/* A few errors are OK to get. They are a notice rather that a fault.
* return TRUE if ssh->error is one of the following: */
INLINE int NoticeError(WOLFSSH* ssh)
{
return (ssh->error == WS_WANT_READ ||
ssh->error == WS_WANT_WRITE ||
ssh->error == WS_CHAN_RXD);
}
static byte* wolfSSH_SFTP_buffer_data(WS_SFTP_BUFFER* buffer)
{
byte* ret = NULL;
@ -8117,8 +8127,7 @@ int wolfSSH_SFTP_Get(WOLFSSH* ssh, char* from,
state->gOfst, state->r,
WOLFSSH_MAX_SFTP_RW);
if (sz < 0) {
if (ssh->error == WS_WANT_READ ||
ssh->error == WS_WANT_WRITE) {
if (NoticeError(ssh)) {
return WS_FATAL_ERROR;
}
WLOG(WS_LOG_SFTP, "Error reading packet");