From 150ad93a07c44f95fe967793f163932944b803d4 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 8 Apr 2019 14:13:41 -0700 Subject: [PATCH 1/2] Memory Refactor 1. Add functions to print out the sizes of various structures. --- examples/client/client.c | 9 +++++++- src/ssh.c | 23 +++++++++++++++++++ src/wolfsftp.c | 48 ++++++++++++++++++++++++++++++++++++++++ wolfssh/ssh.h | 3 +++ wolfssh/wolfsftp.h | 1 + 5 files changed, 83 insertions(+), 1 deletion(-) diff --git a/examples/client/client.c b/examples/client/client.c index c7d9a76..ad8a262 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -393,12 +393,19 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args) char** argv = ((func_args*)args)->argv; ((func_args*)args)->return_code = 0; - while ((ch = mygetopt(argc, argv, "?NP:h:p:u:xc:Rt")) != -1) { + while ((ch = mygetopt(argc, argv, "?NP:h:p:u:xc:Rtz")) != -1) { switch (ch) { case 'h': host = myoptarg; break; + case 'z': + #ifdef WOLFSSH_SHOW_SIZES + wolfSSH_ShowSizes(); + exit(EXIT_SUCCESS); + #endif + break; + case 'p': port = (word16)atoi(myoptarg); #if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API) diff --git a/src/ssh.c b/src/ssh.c index b3e9fcf..61c8d9a 100644 --- a/src/ssh.c +++ b/src/ssh.c @@ -1521,3 +1521,26 @@ void wolfSSH_CheckReceivePending(WOLFSSH* ssh) WIOCTL(wolfSSH_get_fd(ssh), FIONREAD, &bytes); } } + + +#ifdef WOLFSSH_SHOW_SIZES + +void wolfSSH_ShowSizes(void) +{ + fprintf(stderr, "wolfSSH struct sizes:\n"); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WOLFSSH_CTX", + (word32)sizeof(struct WOLFSSH_CTX)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WOLFSSH", + (word32)sizeof(struct WOLFSSH)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "HandshakeInfo", + (word32)sizeof(struct HandshakeInfo)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WOLFSSH_CHANNEL", + (word32)sizeof(struct WOLFSSH_CHANNEL)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "Buffer", + (word32)sizeof(struct Buffer)); + #ifdef WOLFSSH_SFTP + wolfSSH_SFTP_ShowSizes(); + #endif +} + +#endif /* WOLFSSH_SHOW_SIZES */ diff --git a/src/wolfsftp.c b/src/wolfsftp.c index 6589f8b..db44357 100644 --- a/src/wolfsftp.c +++ b/src/wolfsftp.c @@ -7384,4 +7384,52 @@ int wolfSSH_SFTP_free(WOLFSSH* ssh) return WS_SUCCESS; } + +#ifdef WOLFSSH_SHOW_SIZES + +void wolfSSH_SFTP_ShowSizes(void) +{ + fprintf(stderr, "wolfSFTP struct sizes:\n"); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_CHMOD_STATE", + (word32)sizeof(struct WS_SFTP_CHMOD_STATE)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_SETATR_STATE", + (word32)sizeof(struct WS_SFTP_SETATR_STATE)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_LSTAT_STATE", + (word32)sizeof(struct WS_SFTP_LSTAT_STATE)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_OPEN_STATE", + (word32)sizeof(struct WS_SFTP_OPEN_STATE)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_NAME_STATE", + (word32)sizeof(struct WS_SFTP_NAME_STATE)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_SEND_STATE", + (word32)sizeof(struct WS_SFTP_SEND_STATE)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_READDIR_STATE", + (word32)sizeof(struct WS_SFTP_READDIR_STATE)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_RM_STATE", + (word32)sizeof(struct WS_SFTP_RM_STATE)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_MKDIR_STATE", + (word32)sizeof(struct WS_SFTP_MKDIR_STATE)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_RMDIR_STATE", + (word32)sizeof(struct WS_SFTP_RMDIR_STATE)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_RECV_STATE", + (word32)sizeof(struct WS_SFTP_RECV_STATE)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_LS_STATE", + (word32)sizeof(struct WS_SFTP_LS_STATE)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_GET_STATE", + (word32)sizeof(struct WS_SFTP_GET_STATE)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_PUT_STATE", + (word32)sizeof(struct WS_SFTP_PUT_STATE)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_SEND_READ_STATE", + (word32)sizeof(struct WS_SFTP_SEND_READ_STATE)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_SEND_WRITE_STATE", + (word32)sizeof(struct WS_SFTP_SEND_WRITE_STATE)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_CLOSE_STATE", + (word32)sizeof(struct WS_SFTP_CLOSE_STATE)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_GET_HANDLE_STATE", + (word32)sizeof(struct WS_SFTP_GET_HANDLE_STATE)); + fprintf(stderr, " sizeof(struct %s) = %u\n", "WS_SFTP_RENAME_STATE", + (word32)sizeof(struct WS_SFTP_RENAME_STATE)); +} + +#endif /* WOLFSSH_SHOW_SIZES */ + #endif /* WOLFSSH_SFTP */ diff --git a/wolfssh/ssh.h b/wolfssh/ssh.h index 1b3a228..f5ebc0d 100644 --- a/wolfssh/ssh.h +++ b/wolfssh/ssh.h @@ -251,6 +251,9 @@ enum WS_DisconnectReasonCodes { }; +WOLFSSH_API void wolfSSH_ShowSizes(void); + + #ifndef WOLFSSH_MAX_FILENAME #define WOLFSSH_MAX_FILENAME 256 #endif diff --git a/wolfssh/wolfsftp.h b/wolfssh/wolfsftp.h index 8871fc6..d244241 100644 --- a/wolfssh/wolfsftp.h +++ b/wolfssh/wolfsftp.h @@ -236,6 +236,7 @@ WOLFSSL_LOCAL int wolfSSH_SFTP_free(WOLFSSH* ssh); WOLFSSL_LOCAL int SFTP_AddHandleNode(WOLFSSH* ssh, byte* handle, word32 handleSz, char* name); WOLFSSL_LOCAL int SFTP_RemoveHandleNode(WOLFSSH* ssh, byte* handle, word32 handleSz); +WOLFSSH_LOCAL void wolfSSH_SFTP_ShowSizes(void); #ifdef __cplusplus } From 2547a213e3f478ecb4aa7a9c9ad7a6621b84054e Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 9 May 2019 15:06:50 -0700 Subject: [PATCH 2/2] Receive Window 1. Fix bug when setting the receive window to 2048 bytes and the LS would fail. The OpenSSH server is splitting a single full names message across mulitple SSH data records. Needed to treat partial reads at the LS level as a would-block. --- src/wolfsftp.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/wolfsftp.c b/src/wolfsftp.c index db44357..066f5bc 100644 --- a/src/wolfsftp.c +++ b/src/wolfsftp.c @@ -4730,13 +4730,25 @@ static WS_SFTPNAME* wolfSSH_SFTP_DoName(WOLFSSH* ssh) case SFTP_NAME_GET_PACKET: /* get number of files */ - ret = wolfSSH_stream_read(ssh, state->data, state->sz); - if (ret < 0) { + /* using idx as an offset for partial reads */ + ret = wolfSSH_stream_read(ssh, + state->data + state->idx, state->sz - state->idx); + if (ret <= 0) { if (ssh->error != WS_WANT_READ) { wolfSSH_SFTP_ClearState(ssh, STATE_ID_NAME); } return NULL; } + if ((word32)ret < state->sz - state->idx) { + /* Partial read, treat like a want-read. */ + state->idx += ret; + ssh->error = WS_WANT_READ; + state->state = SFTP_NAME_GET_PACKET; + return NULL; + } + + /* Reset idx back to 0 for parsing the buffer. */ + state->idx = 0; if (state->idx + UINT32_SZ > (word32)state->sz) { ssh->error = WS_BUFFER_E;