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 RENESAS_CSPLUS
|
||||||
#define WIOCTL ws_Ioctl
|
|
||||||
//#define DEBUG_WOLFSSH
|
//#define DEBUG_WOLFSSH
|
||||||
#define WOLFSSH_NO_TIMESTAMP
|
#define WOLFSSH_NO_TIMESTAMP
|
||||||
#define WOLFSSH_USER_IO
|
#define WOLFSSH_USER_IO
|
||||||
#define FIONREAD 1
|
|
||||||
#define WOLFSSH_THREAD
|
#define WOLFSSH_THREAD
|
||||||
|
|
|
@ -287,6 +287,9 @@ const char* GetErrorString(int err)
|
||||||
case WC_CHANGE_AUTH_E:
|
case WC_CHANGE_AUTH_E:
|
||||||
return "changing auth type attempt";
|
return "changing auth type attempt";
|
||||||
|
|
||||||
|
case WS_WINDOW_FULL:
|
||||||
|
return "peer's channel window full";
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return "Unknown error code";
|
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) {
|
if (ret == WS_SUCCESS) {
|
||||||
word32 bound = min(channel->peerWindowSz, channel->peerMaxPacketSz);
|
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
|
#ifdef WOLFSSH_SHOW_SIZES
|
||||||
|
|
||||||
void wolfSSH_ShowSizes(void)
|
void wolfSSH_ShowSizes(void)
|
||||||
|
|
|
@ -574,7 +574,11 @@ int DoScpSource(WOLFSSH* ssh)
|
||||||
|
|
||||||
ret = wolfSSH_stream_send(ssh, ssh->scpFileBuffer,
|
ret = wolfSSH_stream_send(ssh, ssh->scpFileBuffer,
|
||||||
ssh->scpBufferedSz);
|
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) {
|
if (ret < 0) {
|
||||||
WLOG(WS_LOG_ERROR, scpError, "failed to send file", ret);
|
WLOG(WS_LOG_ERROR, scpError, "failed to send file", ret);
|
||||||
break;
|
break;
|
||||||
|
@ -1575,7 +1579,7 @@ static int wolfSSH_SCP_cmd(WOLFSSH* ssh, const char* localName,
|
||||||
else {
|
else {
|
||||||
WLOG(WS_LOG_SCP, "Cannot build scp command");
|
WLOG(WS_LOG_SCP, "Cannot build scp command");
|
||||||
ssh->error = WS_MEMORY_E;
|
ssh->error = WS_MEMORY_E;
|
||||||
ret = WS_FATAL_ERROR;
|
ret = WS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -1205,7 +1205,8 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
|
||||||
state->sz - state->idx);
|
state->sz - state->idx);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (ssh->error != WS_WANT_READ &&
|
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);
|
wolfSSH_SFTP_ClearState(ssh, STATE_ID_RECV);
|
||||||
return WS_FATAL_ERROR;
|
return WS_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -1217,7 +1218,7 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
|
||||||
state->toSend = 1;
|
state->toSend = 1;
|
||||||
|
|
||||||
if ((int)state->idx < state->sz) {
|
if ((int)state->idx < state->sz) {
|
||||||
wolfSSH_CheckReceivePending(ssh);
|
ret = wolfSSH_worker(ssh, NULL);
|
||||||
if (ssh->error == WS_WANT_READ) {
|
if (ssh->error == WS_WANT_READ) {
|
||||||
/* was something there to read, try again */
|
/* was something there to read, try again */
|
||||||
state->toSend = 2;
|
state->toSend = 2;
|
||||||
|
@ -4607,7 +4608,8 @@ int SendPacketType(WOLFSSH* ssh, byte type, byte* buf, word32 bufSz)
|
||||||
|
|
||||||
/* check for adjust window packet */
|
/* check for adjust window packet */
|
||||||
err = wolfSSH_get_error(ssh);
|
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 */
|
ssh->error = err; /* don't save potential want read here */
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
state->idx += (word32)ret;
|
state->idx += (word32)ret;
|
||||||
|
@ -7672,7 +7674,8 @@ int wolfSSH_SFTP_Put(WOLFSSH* ssh, char* from, char* to, byte resume,
|
||||||
state->r, state->rSz);
|
state->r, state->rSz);
|
||||||
if (sz <= 0) {
|
if (sz <= 0) {
|
||||||
if (ssh->error == WS_WANT_READ ||
|
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;
|
return WS_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -7686,8 +7689,6 @@ int wolfSSH_SFTP_Put(WOLFSSH* ssh, char* from, char* to, byte resume,
|
||||||
statusCb(ssh, state->pOfst, from);
|
statusCb(ssh, state->pOfst, from);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* check for adjust window packet */
|
|
||||||
wolfSSH_CheckReceivePending(ssh);
|
|
||||||
} while (sz > 0 && ssh->sftpInt == 0);
|
} while (sz > 0 && ssh->sftpInt == 0);
|
||||||
|
|
||||||
if (ssh->sftpInt) {
|
if (ssh->sftpInt) {
|
||||||
|
|
|
@ -111,8 +111,9 @@ enum WS_ErrorCodes {
|
||||||
WS_SSH_CTX_NULL_E = -1070, /* SSH_CTX was null */
|
WS_SSH_CTX_NULL_E = -1070, /* SSH_CTX was null */
|
||||||
WS_CHANNEL_NOT_CONF = -1071, /* Channel open not confirmed. */
|
WS_CHANNEL_NOT_CONF = -1071, /* Channel open not confirmed. */
|
||||||
WC_CHANGE_AUTH_E = -1072, /* Changing auth type attempt */
|
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
|
#define FALL_THROUGH
|
||||||
#endif
|
#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)
|
#if defined(USE_WINDOWS_API)
|
||||||
#define WS_SOCKET_T SOCKET
|
#define WS_SOCKET_T SOCKET
|
||||||
|
|
Loading…
Reference in New Issue