Skip to content

examples, apps: half close and drain at shutdown - #1305

Merged
philljj merged 3 commits into
wolfSSL:masterfrom
ejohnstown:example-shutdown-drain
Oct 13, 2026
Merged

philljj merged 3 commits into
wolfSSL:masterfrom
ejohnstown:example-shutdown-drain

Conversation

@ejohnstown

@ejohnstown ejohnstown commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Both examples and all the apps half close the socket at shutdown and read until the peer hangs up, instead of spinning wolfSSH_worker() a fixed number of times. Clients send a disconnect first; servers do not, since OpenSSH's client exits 255 on a disconnect that lands before it is done.

  • test.h adds HalfCloseAndDrain() and SendDisconnectAndDrain(), with unit coverage over a socket pair.
  • wolfsshd's teardown is now bounded at ten seconds for a peer that never hangs up.

Copilot AI balanced review requested due to automatic review settings October 8, 2026 22:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Normal worker events can truncate queued output, and the drain does not enforce the stated ten-second wall-clock bound.

2 open findings
What changed in this PR

Adds graceful socket half-close and drain handling across clients and servers, replacing fixed worker retries.

Changes:

  • Adds shared shutdown/drain helpers with platform handling.
  • Updates applications and examples to use graceful draining.
  • Adds socket-pair unit coverage.
File Description
wolfssh/​test.h Adds half-close and disconnect-drain helpers.
tests/​unit.c Tests disconnect and half-close paths.
examples/​sftpclient/​sftpclient.c Uses graceful client draining.
examples/​scpclient/​scpclient.c Uses graceful client draining.
examples/​portfwd/​portfwd.c Drains the forwarding connection.
examples/​echoserver/​echoserver.c Half-closes server connections.
examples/​client/​client.c Uses disconnect-and-drain teardown.
apps/​wolfsshd/​wolfsshd.c Adds bounded daemon connection draining.
apps/​wolfssh/​wolfssh.c Uses shared graceful teardown.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread wolfssh/test.h
Comment thread wolfssh/test.h Outdated

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #1305

Scan targets checked: wolfssh-src, wolfssh-bugs
Coverage: 7 of 9 in-scope changed file(s) opened by the reviewer; not opened: examples/portfwd/portfwd.c, tests/unit.c

Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Reported findings require changes before merge.

Review tier: Lite

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #1305

Scan targets checked: wolfssh-src, wolfssh-bugs
Coverage: 2 of 2 in-scope changed file(s) opened by the reviewer

Fenrir result: Approved ✅

No new issues found in the changed files.

Advisory only — this automated result does not count as a GitHub approval.

Review tier: Lite

@wolfSSL-Fenrir-bot
wolfSSL-Fenrir-bot dismissed their stale review October 8, 2026 23:01

Fenrir's latest completed scan found no issues; clearing the prior automated change request.

@ejohnstown
ejohnstown force-pushed the example-shutdown-drain branch from 54ec4cd to 5cc58fe Compare October 9, 2026 22:20

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #1305

Scan targets checked: none
Unchanged since last review (not re-run): 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.

Review tier: Lite

@ejohnstown
ejohnstown force-pushed the example-shutdown-drain branch from 5cc58fe to b2a1946 Compare October 12, 2026 16:54
@philljj philljj self-assigned this Oct 12, 2026
The client and the echoserver both sent their shutdown messages and then
spun wolfSSH_worker() a fixed number of times, so whether the peer's
close was seen at all depended on timing. Both now half close the
socket and read until the peer hangs up; the client sends a disconnect
first, the echoserver does not.

- test.h adds WSHUTDOWN(), a write-side shutdown() on POSIX and Windows,
  left undefined where the stack has no half close.
- test.h adds HalfCloseAndDrain(). It flushes a queued write, then reads
  the raw socket, since the library reads nothing after the session
  ends, and gives up ten seconds in or after 256 reads. MQX gets a stub.
- SendDisconnectAndDrain() sends MSG_DISCONNECT for up to ten seconds,
  then drains. It returns WS_WANT_READ for a peer that never hung up,
  WS_WANT_WRITE for a disconnect still queued, WS_SUCCESS for a reset.
- test.h adds WaitForChannelClose(), which runs the session until the
  peer's channel close, bounded at ten seconds, and returns at once on a
  session an error already ended. MQX gets one pass.
- client.c waits for the close, keeping a late exit status, and reports
  an unexpected shutdown result. It exits 0 on either give-up and fails
  on a broken wait or a disconnect it could not send.
- echoserver.c replaces its 10-attempt worker loop with the drain alone:
  the close exchange ended the session, and OpenSSH's client exits 255
  on a disconnect that lands before it is done.
Run the helpers over a socket pair with the test playing the peer.
configure checks for socketpair(), and unit.c builds these tests only
when it is found, since custom-IO builds such as the STM32 Cube pack
have no sockets API.

- peer hangs up after the disconnect, or resets before it goes out
- first send would block, the retry flushes it
- peer disconnected first, nothing is sent
- the drain alone sees the hang up, and sends a disconnect of ours a
  short send left queued
- an exit status after the peer's EOF and an IGNORE is still read, and
  the wait returns at once on a session an error already ended
The remaining teardown sites spun wolfSSH_worker() ten times after
wolfSSH_shutdown(), the loop the client and the echoserver just
replaced. The clients now send a disconnect and drain, and wolfsshd
half closes and drains like the echoserver.

- sftpclient.c, scpclient.c, portfwd.c and the wolfssh app call
  SendDisconnectAndDrain() and treat either give-up as a clean close.
- scpclient.c and the wolfssh app report an unexpected shutdown result,
  as the client does.
- the wolfssh app waits for the channel close before draining, as the
  client does, and fails on an error that broke the wait.
- wolfsshd drained by hand after wolfSSH_free(), with no bound on a peer
  that never hung up. HalfCloseAndDrain() bounds it at ten seconds, and
  a peer that let the login grace time run out is not drained.

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #1305

Scan targets checked: wolfssh-src, wolfssh-bugs
Coverage: 5 of 5 in-scope changed file(s) opened by the reviewer

Fenrir result: Approved ✅

No new issues found in the changed files.

Advisory only — this automated result does not count as a GitHub approval.

Review tier: Lite

@philljj
philljj merged commit 7320687 into wolfSSL:master Oct 13, 2026
202 checks passed
@ejohnstown
ejohnstown deleted the example-shutdown-drain branch October 13, 2026 17:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants