examples, ide: classify the worker's status where ssh->error is its own - #1251
Conversation
There was a problem hiding this comment.
🟢 Approval recommended
No unresolved blocking issues were identified.
Pull request overview
This pull request fixes worker-status classification in both echo servers so transient write back-pressure does not terminate live sessions.
Changes:
- Preserves and classifies
wolfSSH_worker()status immediately. - Simplifies terminal-status handling in both implementations.
File summaries
| File | Description |
|---|---|
ide/Espressif/ESP-IDF/examples/wolfssh_echoserver/main/echoserver.c |
Applies the worker status-handling fix. |
examples/echoserver/echoserver.c |
Preserves worker status across echo draining. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #1251
Scan targets checked: wolfssh-src, wolfssh-bugs
Fenrir result: Approved ✅
No new issues found in the changed files.
Advisory only — this automated result does not count as a GitHub approval.
e97e859 to
c957fd8
Compare
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #1251
Scan targets checked: wolfssh-src, wolfssh-bugs
Fenrir result: Approved ✅
No new issues found in the changed files.
Advisory only — this automated result does not count as a GitHub approval.
c957fd8 to
6084652
Compare
- ssh_worker() in both echoservers maps a WS_FATAL_ERROR return from wolfSSH_worker() to WS_WANT_READ or WS_WANT_WRITE at the call site, off a new local err, and keeps the result in rc. - The terminal arm tests rc in place of re-reading wolfSSH_get_error(): rc != WS_WANT_READ in examples/echoserver, and rc != WS_WANT_READ && rc != WS_WANT_WRITE in the Espressif copy, whose empty WS_WANT_WRITE arm is removed. - ssh_worker() in examples/echoserver sets wantWrite from wolfSSH_OutputPending() before it builds writeFds. - The comment above rc = cnt_r in both echoservers names cnt_r and ssh->error as the values that are reused. - scripts/sshclient.test and scripts/fwd-bulk.test name the client's missing non-blocking mode in the skip message where they echoed the macro name, and the comments above both skips are removed.
The non-blocking app-driven case runs under WOLFSSH_TEST_BLOCK again, reverting ba89960. It deadlocks there until ssh_worker() waits on the write side for a send wolfSSH_worker() reported through ssh->error, so this wants PR 1251 landed with the wantWrite arm kept.
6084652 to
fab6066
Compare
Problem
wolfSSH_worker()reports a blocked read or write two ways: as its return, oras
WS_FATAL_ERRORwith the code left inssh->error.ssh_worker()dispatched on the return alone, so the second shape arrived as a bare failure
with its meaning stranded in
ssh->error. That one gap has two consequences:wolfSSH_get_error()down in the terminal arm, ~200 lines later. The!eofAnswered && echoOnlydrain runs in between and latches its own code, soa
WS_WINDOW_FULLfrom the drain read as fatal and tore down a healthysession.
wantWriteretry is keyed onrc == WS_WANT_WRITE, which the second shape never produces.wantWritestayed 0, so
select()waited on readability alone while the peer waited onoutput the server was still holding.
A third case carries no want-status at all: an owed write riding a
WS_CHAN_RXD,WS_EOForWS_CHANNEL_CLOSEDreturn. InwolfSSH_worker()'sflush block,
ret == WS_CHAN_RXDwithsendRet == WS_WANT_WRITEfires none ofthe three branches, so the event return is handed back with output still
queued.
wolfssh/ssh.hsays to askwolfSSH_OutputPending()rather than reada status, which is what the POSIX
wolfsshdloop already does.Fix (
examples/echoserver/echoserver.c)Carry the worker's meaning forward in
rc, at the call site, whilessh->errorstill belongs to the worker:wantWrite = 1; continue;arm is kept. The remap feeds it thesecond shape, arming the write set where nothing did before, so this extends
echoserver: answer session requests in callbacks #1234 rather than competing with it.
wantWriteis additionally set fromwolfSSH_OutputPending()beforewriteFdsis built, which is the only form that covers the event-returncase.
wolfSSH_get_error()and testsrc. Thetwo echoservers deliberately differ here:
rc != WS_WANT_READin thisfile, whose
WS_WANT_WRITEarm consumes that case, andrc != WS_WANT_READ && rc != WS_WANT_WRITEin the ESP-IDF copy, which has nowrite set and whose empty
WS_WANT_WRITEarm is removed. Please do not"align" them.
if (cnt_r < 0), so aWS_SUCCESSpass neverreaches the terminal arm.
Includes
tests: run app-driven sftp in a block build(John Safranek), whichun-skips the case that exercises this.
scripts/sshclient.testandscripts/fwd-bulk.testname the client's missingnon-blocking mode in their skip messages, matching
scripts/scp.test. Theirold comments said the other echoserver scripts skip a block build for the same
reason, which stopped being true when
sftp.testun-skipped above. Message andcomment only; no logic changed.
Verification
-Werrorconfigs, all clean.unit+regress+testsuitepass;sshclient,scp,get-put,sftpandfwdpass run serially.--enable-sftp -DWOLFSSH_TEST_BLOCK -DWOLFSSH_NO_FPKI), with theapp-driven case now running rather than skipped: 21s / 39s / 88s at
WOLFSSH_BLOCK_PROB30 / 50 / 70.WS_FATAL_ERRORremap-1009, 77swantWritearmwolfSSH_OutputPending()linesThe third row is deliberate disclosure: no test distinguishes the
wolfSSH_OutputPending()arming.wolfSSH_worker()attempts a flush onevery call, so an owed write is retried for as long as the loop keeps calling
the worker; reaching the hole needs the peer to fall silent immediately after
sending channel data while the socket refuses writes. That line is contract
conformance, not a measured fix.
The echo/shell path also stays uncovered:
scripts/sshclient.testcannot rununder
WOLFSSH_TEST_BLOCKbecauseapps/wolfsshhas no non-blocking mode, andneither does
portfwdforscripts/fwd-bulk.test. That is what their skipmessages now say.