Fix issue with shutting down a channel. It would try to do it twice and error out.

pull/343/head
John Safranek 2021-10-04 11:08:34 -07:00
parent 4435ed40fa
commit dd79a54541
No known key found for this signature in database
GPG Key ID: 8CE817DE0D3CCB4A
4 changed files with 59 additions and 28 deletions

View File

@ -789,6 +789,20 @@ static int ssh_worker(thread_ctx_t* threadCtx)
}
#endif
}
else if (rc == WS_CHANNEL_CLOSED) {
#ifdef WOLFSSH_FWD
/* Read zero-returned. Socket is closed. Go back
to listening. */
WCLOSESOCKET(fwdFd);
fwdFd = -1;
if (threadCtx->fwdCbCtx.hostName != NULL) {
free(threadCtx->fwdCbCtx.hostName);
threadCtx->fwdCbCtx.hostName = NULL;
}
threadCtx->fwdCbCtx.state = FWD_STATE_LISTEN;
#endif
continue;
}
else if (rc != WS_WANT_READ) {
#ifdef SHELL_DEBUG
printf("Break:read sshFd returns %d: errno =%x\n",

View File

@ -4767,7 +4767,8 @@ static int DoGlobalRequestFwd(WOLFSSH* ssh,
if (ret == WS_SUCCESS) {
if (ssh->ctx->fwdCb) {
ret = ssh->ctx->fwdCb(WOLFSSH_FWD_REMOTE_SETUP,
ret = ssh->ctx->fwdCb(isCancel ? WOLFSSH_FWD_REMOTE_CLEANUP :
WOLFSSH_FWD_REMOTE_SETUP,
ssh->fwdCbCtx, bindAddr, bindPort);
}
}
@ -5129,8 +5130,13 @@ static int DoChannelEof(WOLFSSH* ssh,
ret = WS_INVALID_CHANID;
}
if (ret == WS_SUCCESS)
channel->receivedEof = 1;
if (ret == WS_SUCCESS) {
channel->eofRxd = 1;
if (!channel->eofTxd) {
ret = SendChannelEof(ssh, channel->peerChannel);
}
ssh->lastRxId = channelId;
}
WLOG(WS_LOG_DEBUG, "Leaving DoChannelEof(), ret = %d", ret);
return ret;
@ -5158,7 +5164,9 @@ static int DoChannelClose(WOLFSSH* ssh,
}
if (ret == WS_SUCCESS) {
ret = SendChannelClose(ssh, channel->peerChannel);
if (!channel->closeTxd) {
ret = SendChannelClose(ssh, channel->peerChannel);
}
}
if (ret == WS_SUCCESS) {
@ -5167,6 +5175,7 @@ static int DoChannelClose(WOLFSSH* ssh,
if (ret == WS_SUCCESS) {
ret = WS_CHANNEL_CLOSED;
ssh->lastRxId = channelId;
}
WLOG(WS_LOG_DEBUG, "Leaving DoChannelClose(), ret = %d", ret);
@ -5715,22 +5724,17 @@ static int DoPacket(WOLFSSH* ssh)
ret = SendUnimplemented(ssh);
}
if (ret == WS_SUCCESS || ret == WS_CHAN_RXD || ret == WS_EXTDATA) {
if (payloadSz > 0){
idx += payloadIdx;
if (idx + padSz > len)
{
WLOG(WS_LOG_DEBUG, "Not enough data in buffer for pad.");
ret = WS_BUFFER_E;
}
if (payloadSz > 0) {
idx += payloadIdx;
if (idx + padSz > len) {
WLOG(WS_LOG_DEBUG, "Not enough data in buffer for pad.");
ret = WS_BUFFER_E;
}
}
if (ret == WS_SUCCESS || ret == WS_CHAN_RXD || ret == WS_EXTDATA) {
idx += padSz;
ssh->inputBuffer.idx = idx;
ssh->peerSeq++;
}
idx += padSz;
ssh->inputBuffer.idx = idx;
ssh->peerSeq++;
return ret;
}
@ -9337,6 +9341,14 @@ int SendChannelEof(WOLFSSH* ssh, word32 peerChannelId)
ret = WS_INVALID_CHANID;
}
if (ret == WS_SUCCESS) {
if (channel->eofTxd) {
WLOG(WS_LOG_DEBUG, "Already sent EOF");
WLOG(WS_LOG_DEBUG, "Leaving SendChannelEof(), ret = %d", ret);
return ret;
}
}
if (ret == WS_SUCCESS)
ret = PreparePacket(ssh, MSG_ID_SZ + UINT32_SZ);
@ -9356,6 +9368,9 @@ int SendChannelEof(WOLFSSH* ssh, word32 peerChannelId)
if (ret == WS_SUCCESS)
ret = wolfSSH_SendPacket(ssh);
if (ret == WS_SUCCESS)
channel->eofTxd = 1;
WLOG(WS_LOG_DEBUG, "Leaving SendChannelEof(), ret = %d", ret);
return ret;
}
@ -9482,7 +9497,7 @@ int SendChannelClose(WOLFSSH* ssh, word32 peerChannelId)
channel = ChannelFind(ssh, peerChannelId, WS_CHANNEL_ID_PEER);
if (channel == NULL)
ret = WS_INVALID_CHANID;
else if (channel->closeSent) {
else if (channel->closeTxd) {
WLOG(WS_LOG_DEBUG, "Leaving SendChannelClose(), already sent");
return ret;
}
@ -9506,7 +9521,7 @@ int SendChannelClose(WOLFSSH* ssh, word32 peerChannelId)
if (ret == WS_SUCCESS) {
ret = wolfSSH_SendPacket(ssh);
channel->closeSent = 1;
channel->closeTxd = 1;
}
WLOG(WS_LOG_DEBUG, "Leaving SendChannelClose(), ret = %d", ret);

View File

@ -1036,7 +1036,7 @@ int wolfSSH_stream_read(WOLFSSH* ssh, byte* buf, word32 bufSz)
if (ret == WS_SUCCESS) {
while (inputBuffer->length - inputBuffer->idx == 0) {
ret = DoReceive(ssh);
if (ssh->channelList == NULL || ssh->channelList->receivedEof)
if (ssh->channelList == NULL || ssh->channelList->eofRxd)
ret = WS_EOF;
if (ret < 0 && ret != WS_CHAN_RXD) {
break;
@ -1767,12 +1767,12 @@ int wolfSSH_worker(WOLFSSH* ssh, word32* channelId)
}
/* Attempt to receive data from the peer. */
if (ret == WS_SUCCESS)
if (ret == WS_SUCCESS) {
ret = DoReceive(ssh);
}
if (ret == WS_CHAN_RXD) {
if (channelId != NULL)
*channelId = ssh->lastRxId;
if (channelId != NULL && ssh != NULL) {
*channelId = ssh->lastRxId;
}
if (ret == WS_CHAN_RXD)
@ -2127,7 +2127,7 @@ int wolfSSH_ChannelGetEof(WOLFSSH_CHANNEL* channel)
WLOG(WS_LOG_DEBUG, "Entering wolfSSH_ChannelGetEof()");
if (channel)
eof = (int)channel->receivedEof;
eof = (int)channel->eofRxd;
WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_ChannelGetEof(), %s",
eof ? "true" : "false");

View File

@ -701,9 +701,11 @@ struct WOLFSSH {
struct WOLFSSH_CHANNEL {
byte channelType;
byte sessionType;
byte closeSent;
byte receivedEof;
byte openConfirmed;
byte closeRxd : 1;
byte closeTxd : 1;
byte eofRxd : 1;
byte eofTxd : 1;
byte openConfirmed : 1;
word32 channel;
word32 windowSz;
word32 maxPacketSz;