Take the worker's status before the EOF drain

The drain runs between wolfSSH_worker() and the get_error() that classifies
its result, and its reads and sends latch their own status: WS_WINDOW_FULL
and WS_WANT_WRITE from a send, WS_REKEYING from a read. The ladder then read
the drain's status as the worker's, matched no arm, and ended the session
with the backlog unsent and no EOF.

- Read the error once, right after the worker returns
pull/1218/head
John Safranek 2026-08-28 15:08:15 -07:00 committed by philljj
parent 033646ce0a
commit fc3b0a86bd
2 changed files with 6 additions and 2 deletions

View File

@ -1011,6 +1011,9 @@ static int ssh_worker(thread_ctx_t* threadCtx)
channel. The additional channel is only used with the
agent. */
cnt_r = wolfSSH_worker(ssh, &lastChannel);
/* Take the worker's status before the drain below: its
* reads and sends latch their own into ssh->error. */
rc = wolfSSH_get_error(ssh);
/* The peer is done sending: hand back the backlog and answer
* its EOF, or a client that half-closed waits on a server
@ -1072,7 +1075,6 @@ static int ssh_worker(thread_ctx_t* threadCtx)
}
if (cnt_r < 0) {
rc = wolfSSH_get_error(ssh);
/* wolfSSH_worker() reports WS_REKEYING in place of
* WS_CHAN_RXD while a rekey is in flight, and the data
* report is never raised again, so drain on both or the

View File

@ -995,6 +995,9 @@ static int ssh_worker(thread_ctx_t* threadCtx)
channel. The additional channel is only used with the
agent. */
cnt_r = wolfSSH_worker(ssh, &lastChannel);
/* Take the worker's status before the drain below: its
* reads and sends latch their own into ssh->error. */
rc = wolfSSH_get_error(ssh);
/* The peer is done sending: hand back the backlog and answer
* its EOF, or a client that half-closed waits on a server
@ -1056,7 +1059,6 @@ static int ssh_worker(thread_ctx_t* threadCtx)
}
if (cnt_r < 0) {
rc = wolfSSH_get_error(ssh);
if (rc == WS_CHAN_RXD) {
if (lastChannel == shellChannelId) {
cnt_r = wolfSSH_ChannelIdRead(ssh, shellChannelId,