diff --git a/apps/wolfsshd/wolfsshd.c b/apps/wolfsshd/wolfsshd.c index 4991b62dc..f014cc85e 100644 --- a/apps/wolfsshd/wolfsshd.c +++ b/apps/wolfsshd/wolfsshd.c @@ -704,6 +704,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh, byte shellBuffer[EXAMPLE_BUFFER_SZ]; byte channelBuffer[EXAMPLE_BUFFER_SZ]; char* forcedCmd; + int windowFull = 0; forcedCmd = wolfSSHD_ConfigGetForcedCmd(usrConf); @@ -876,7 +877,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh, pending = 1; /* found some pending SSH data */ } - if (pending || FD_ISSET(sshFd, &readFds)) { + if (windowFull || pending || FD_ISSET(sshFd, &readFds)) { word32 lastChannel = 0; /* The following tries to read from the first channel inside @@ -910,6 +911,19 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh, } } + /* if the window was previously full, try resending the data */ + if (windowFull) { + cnt_w = wolfSSH_ChannelIdSend(ssh, shellChannelId, + shellBuffer, cnt_r); + if (cnt_w == WS_WINDOW_FULL) { + windowFull = 1; + continue; + } + else { + windowFull = 0; + } + } + if (FD_ISSET(childFd, &readFds)) { cnt_r = (int)read(childFd, shellBuffer, sizeof shellBuffer); /* This read will return 0 on EOF */ @@ -923,7 +937,11 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh, if (cnt_r > 0) { cnt_w = wolfSSH_ChannelIdSend(ssh, shellChannelId, shellBuffer, cnt_r); - if (cnt_w < 0) + if (cnt_w == WS_WINDOW_FULL) { + windowFull = 1; + continue; + } + else if (cnt_w < 0) break; } } diff --git a/examples/client/client.c b/examples/client/client.c index 045fb4ff1..88c48d9fa 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -148,10 +148,17 @@ static int NonBlockSSH_connect(WOLFSSH* ssh) printf("... client would write block\n"); select_ret = tcp_select(sockfd, 1); - if (select_ret == WS_SELECT_RECV_READY || + + /* Continue in want write cases even if did not select on socket + * because there could be pending data to be written. Added continue + * on want write for test cases where a forced want read was introduced + * and the socket will not be receiving more data. */ + if (error == WS_WANT_WRITE || error == WS_WANT_READ || + select_ret == WS_SELECT_RECV_READY || select_ret == WS_SELECT_ERROR_READY) { ret = wolfSSH_connect(ssh); + error = wolfSSH_get_error(ssh); } else if (select_ret == WS_SELECT_TIMEOUT) error = WS_WANT_READ; diff --git a/src/internal.c b/src/internal.c index 3315521f6..f927bdc2b 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2264,8 +2264,14 @@ static int GetInputData(WOLFSSH* ssh, word32 size) /* Take into account the data already in the buffer. Update size * for what is missing in the request. */ - word32 haveDataSz = ssh->inputBuffer.length - ssh->inputBuffer.idx; + word32 haveDataSz; + /* reset want read state before attempting to read */ + if (ssh->error == WS_WANT_READ) { + ssh->error = 0; + } + + haveDataSz = ssh->inputBuffer.length - ssh->inputBuffer.idx; if (haveDataSz >= size) { WLOG(WS_LOG_INFO, "GID: have enough already, return early"); return WS_SUCCESS;