From fc3b0a86bd8539234f0a77a3adbcbc116d3905bb Mon Sep 17 00:00:00 2001 From: John Safranek Date: Fri, 28 Aug 2026 15:08:15 -0700 Subject: [PATCH] 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 --- examples/echoserver/echoserver.c | 4 +++- .../ESP-IDF/examples/wolfssh_echoserver/main/echoserver.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index 482d184d..156ce308 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -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 diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_echoserver/main/echoserver.c b/ide/Espressif/ESP-IDF/examples/wolfssh_echoserver/main/echoserver.c index 6baa1af0..179d02c5 100644 --- a/ide/Espressif/ESP-IDF/examples/wolfssh_echoserver/main/echoserver.c +++ b/ide/Espressif/ESP-IDF/examples/wolfssh_echoserver/main/echoserver.c @@ -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,