mirror of https://github.com/wolfSSL/wolfssh.git
Rx Window
1. Remove the CheckPendingReceive() function and the WIOCTL wrapper. 2. If the peer's receive window is considered full, call wolfSSH_worker() which will process a receive.pull/252/head
parent
2c710dcfd8
commit
66f8a47a6a
|
@ -20,9 +20,7 @@
|
|||
*/
|
||||
|
||||
#define RENESAS_CSPLUS
|
||||
#define WIOCTL ws_Ioctl
|
||||
//#define DEBUG_WOLFSSH
|
||||
#define WOLFSSH_NO_TIMESTAMP
|
||||
#define WOLFSSH_USER_IO
|
||||
#define FIONREAD 1
|
||||
#define WOLFSSH_THREAD
|
||||
|
|
|
@ -287,6 +287,9 @@ const char* GetErrorString(int err)
|
|||
case WC_CHANGE_AUTH_E:
|
||||
return "changing auth type attempt";
|
||||
|
||||
case WS_WINDOW_FULL:
|
||||
return "peer's channel window full";
|
||||
|
||||
default:
|
||||
return "Unknown error code";
|
||||
}
|
||||
|
@ -8180,6 +8183,13 @@ int SendChannelData(WOLFSSH* ssh, word32 peerChannel,
|
|||
}
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
if (channel->peerWindowSz == 0) {
|
||||
WLOG(WS_LOG_DEBUG, "channel window is full");
|
||||
ret = WS_WINDOW_FULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
word32 bound = min(channel->peerWindowSz, channel->peerMaxPacketSz);
|
||||
|
||||
|
|
35
src/ssh.c
35
src/ssh.c
|
@ -1645,41 +1645,6 @@ int wolfSSH_ChannelGetEof(WOLFSSH_CHANNEL* channel)
|
|||
}
|
||||
|
||||
|
||||
/* Protocols that have loops over wolfSSH_stream_send without doing any reads
|
||||
* will run into the issue of not checking for a peer window adjustment packet.
|
||||
* This function allows for checking for a peer window adjustment packet without
|
||||
* requiring a read buffer and call to wolfSSH_stream_read.
|
||||
*
|
||||
* Data that is read and is not related to packet headers is stored in the
|
||||
* WOLFSSH input buffer and can be gotten with a call to wolfSSH_stream_read. If
|
||||
* more data is stored then MAX_PACKET_SZ then no more window adjustment packets
|
||||
* are searched for.
|
||||
*/
|
||||
void wolfSSH_CheckReceivePending(WOLFSSH* ssh)
|
||||
{
|
||||
int bytes = 0;
|
||||
Buffer* inputBuffer;
|
||||
|
||||
WLOG(WS_LOG_DEBUG, "Entering wolfSSH_CheckReceivePending()");
|
||||
|
||||
if (ssh == NULL)
|
||||
return;
|
||||
|
||||
inputBuffer = &ssh->channelList->inputBuffer;
|
||||
WIOCTL(wolfSSH_get_fd(ssh), WFIONREAD, &bytes);
|
||||
while (bytes > 0) { /* there is something to read off the wire */
|
||||
if (inputBuffer->length - inputBuffer->idx > MAX_PACKET_SZ) {
|
||||
WLOG(WS_LOG_DEBUG, "Application data to be read");
|
||||
break; /* too much application data! */
|
||||
}
|
||||
if (DoReceive(ssh) < 0) {
|
||||
WLOG(WS_LOG_ERROR, "Error trying to read potential window adjust");
|
||||
}
|
||||
WIOCTL(wolfSSH_get_fd(ssh), WFIONREAD, &bytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef WOLFSSH_SHOW_SIZES
|
||||
|
||||
void wolfSSH_ShowSizes(void)
|
||||
|
|
|
@ -574,7 +574,11 @@ int DoScpSource(WOLFSSH* ssh)
|
|||
|
||||
ret = wolfSSH_stream_send(ssh, ssh->scpFileBuffer,
|
||||
ssh->scpBufferedSz);
|
||||
wolfSSH_CheckReceivePending(ssh); /*check for adjust window packet*/
|
||||
if (ret == WS_WINDOW_FULL) {
|
||||
ret = wolfSSH_worker(ssh, NULL);
|
||||
if (ret == WS_SUCCESS)
|
||||
continue;
|
||||
}
|
||||
if (ret < 0) {
|
||||
WLOG(WS_LOG_ERROR, scpError, "failed to send file", ret);
|
||||
break;
|
||||
|
@ -1575,7 +1579,7 @@ static int wolfSSH_SCP_cmd(WOLFSSH* ssh, const char* localName,
|
|||
else {
|
||||
WLOG(WS_LOG_SCP, "Cannot build scp command");
|
||||
ssh->error = WS_MEMORY_E;
|
||||
ret = WS_FATAL_ERROR;
|
||||
ret = WS_ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -1205,7 +1205,8 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
|
|||
state->sz - state->idx);
|
||||
if (ret < 0) {
|
||||
if (ssh->error != WS_WANT_READ &&
|
||||
ssh->error != WS_WANT_WRITE)
|
||||
ssh->error != WS_WANT_WRITE &&
|
||||
ssh->error != WS_WINDOW_FULL)
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_RECV);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
|
@ -1217,7 +1218,7 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
|
|||
state->toSend = 1;
|
||||
|
||||
if ((int)state->idx < state->sz) {
|
||||
wolfSSH_CheckReceivePending(ssh);
|
||||
ret = wolfSSH_worker(ssh, NULL);
|
||||
if (ssh->error == WS_WANT_READ) {
|
||||
/* was something there to read, try again */
|
||||
state->toSend = 2;
|
||||
|
@ -4607,7 +4608,8 @@ int SendPacketType(WOLFSSH* ssh, byte type, byte* buf, word32 bufSz)
|
|||
|
||||
/* check for adjust window packet */
|
||||
err = wolfSSH_get_error(ssh);
|
||||
wolfSSH_CheckReceivePending(ssh);
|
||||
if (err == WS_WINDOW_FULL)
|
||||
ret = wolfSSH_worker(ssh, NULL);
|
||||
ssh->error = err; /* don't save potential want read here */
|
||||
if (ret > 0)
|
||||
state->idx += (word32)ret;
|
||||
|
@ -7672,7 +7674,8 @@ int wolfSSH_SFTP_Put(WOLFSSH* ssh, char* from, char* to, byte resume,
|
|||
state->r, state->rSz);
|
||||
if (sz <= 0) {
|
||||
if (ssh->error == WS_WANT_READ ||
|
||||
ssh->error == WS_WANT_WRITE)
|
||||
ssh->error == WS_WANT_WRITE ||
|
||||
ssh->error == WS_WINDOW_FULL)
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
else {
|
||||
|
@ -7686,8 +7689,6 @@ int wolfSSH_SFTP_Put(WOLFSSH* ssh, char* from, char* to, byte resume,
|
|||
statusCb(ssh, state->pOfst, from);
|
||||
}
|
||||
}
|
||||
/* check for adjust window packet */
|
||||
wolfSSH_CheckReceivePending(ssh);
|
||||
} while (sz > 0 && ssh->sftpInt == 0);
|
||||
|
||||
if (ssh->sftpInt) {
|
||||
|
|
|
@ -111,8 +111,9 @@ enum WS_ErrorCodes {
|
|||
WS_SSH_CTX_NULL_E = -1070, /* SSH_CTX was null */
|
||||
WS_CHANNEL_NOT_CONF = -1071, /* Channel open not confirmed. */
|
||||
WC_CHANGE_AUTH_E = -1072, /* Changing auth type attempt */
|
||||
WS_WINDOW_FULL = -1073,
|
||||
|
||||
WS_LAST_E = -1072 /* Update this to indicate last error */
|
||||
WS_LAST_E = -1073 /* Update this to indicate last error */
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1078,60 +1078,6 @@ extern "C" {
|
|||
#define FALL_THROUGH
|
||||
#endif
|
||||
|
||||
/* used for checking bytes on wire for window adjust packet read */
|
||||
#ifndef WIOCTL
|
||||
#ifdef WOLFSSL_NUCLEUS
|
||||
#include "nucleus.h"
|
||||
#include "networking/nu_networking.h"
|
||||
#define WFIONREAD FIONREAD
|
||||
static inline void ws_Ioctl(int fd, int flag, int* ret)
|
||||
{
|
||||
SCK_IOCTL_OPTION op;
|
||||
op.s_optval = (unsigned char*)&fd;
|
||||
if (NU_Ioctl(flag, &op, sizeof(op)) != NU_SUCCESS) {
|
||||
*ret = 0;
|
||||
}
|
||||
else {
|
||||
*ret = op.s_ret.sck_bytes_pending;
|
||||
}
|
||||
}
|
||||
#define WIOCTL ws_Ioctl
|
||||
#elif defined(FREESCALE_MQX)
|
||||
/* MQX does not have FIONREAD, use SO_RCVNUM with getsockopt() instead */
|
||||
#include <ioctl.h>
|
||||
#include <rtcs.h>
|
||||
#define WFIONREAD SO_RCVNUM
|
||||
static inline void ws_Ioctl(int fd, int flag, int* ret)
|
||||
{
|
||||
int status;
|
||||
uint32_t bytesSz;
|
||||
|
||||
bytesSz = sizeof(*ret);
|
||||
status = getsockopt(fd, SOL_SOCKET, SO_RCVNUM, ret, &bytesSz);
|
||||
if (status != RTCS_OK) {
|
||||
WLOG(WS_LOG_ERROR, "Error calling getsockopt()");
|
||||
*ret = 0;
|
||||
}
|
||||
}
|
||||
#define WIOCTL ws_Ioctl
|
||||
#elif defined(USE_WINDOWS_API)
|
||||
#define WFIONREAD FIONREAD
|
||||
#define WIOCTL ioctlsocket
|
||||
#elif defined(WOLFSSL_VXWORKS)
|
||||
#include "ioLib.h"
|
||||
#include <sys/ioctl.h>
|
||||
#define WIOCTL ioctl
|
||||
#else
|
||||
#if defined(__CYGWIN__) && !defined(FIONREAD)
|
||||
/* Cygwin defines FIONREAD in socket.h instead of ioctl.h */
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#include <sys/ioctl.h>
|
||||
#define WFIONREAD FIONREAD
|
||||
#define WIOCTL ioctl
|
||||
#endif
|
||||
#endif /* WIOCTL */
|
||||
|
||||
|
||||
#if defined(USE_WINDOWS_API)
|
||||
#define WS_SOCKET_T SOCKET
|
||||
|
|
Loading…
Reference in New Issue