Skip to content

Fix connections being closed after an unrelated SSL failure - #116

Merged
SeanTAllen merged 1 commit into
mainfrom
clear-error-queue-before-ssl-io
Aug 1, 2026
Merged

Fix connections being closed after an unrelated SSL failure#116
SeanTAllen merged 1 commit into
mainfrom
clear-error-queue-before-ssl-io

Conversation

@SeanTAllen

Copy link
Copy Markdown
Member

SSL_get_error only describes the call it is asked about when the calling thread's OpenSSL error queue was empty before that call ran. Nothing cleared that queue, so one failed operation could put an unrelated healthy session into SSLError and get its connection closed. @ERR_clear_error() now runs immediately before each of the five SSL I/O calls.

Two tests. One checks that a session reading after an unrelated failed handshake stays SSLReady; it also asserts the failure actually left an entry on the queue, because without that the test cannot fail whatever read does. The other checks that a read whose record will not decrypt still reports SSLError, so clearing the queue cannot cost a session its own errors — before this, _state = SSLError could be deleted outright and the suite stayed green.

Measured on every backend the package supports. With the fix removed, the regression test fails on OpenSSL 1.1.1w, OpenSSL 3.6.2, LibreSSL 3.9.2 and LibreSSL 4.2.1, and passes on OpenSSL 4.0.0, which does not have the bug. The full suite passes on all five with the fix.

Closes #115

SSL_get_error only describes the call it is given when the calling thread's
OpenSSL error queue was empty beforehand. Nothing cleared that queue, so a
failed operation left an entry behind and the next session to read on the same
thread got SSL_ERROR_SSL instead of SSL_ERROR_WANT_READ. That session moved to
SSLError, and callers branching on the state closed a connection that was
working.

The handshake path does not misreport, because OpenSSL's handshake machinery
empties the queue itself. The clear goes before all five SSL I/O calls anyway:
an empty queue going in is the documented contract, not a property to work out
one call site at a time.

Closes #115
@SeanTAllen SeanTAllen added the changelog - fixed Automatically add "Fixed" CHANGELOG entry on merge label Aug 1, 2026
@ponylang-main ponylang-main added the discuss during sync Should be discussed during an upcoming sync label Aug 1, 2026
@SeanTAllen
SeanTAllen merged commit 50c10f0 into main Aug 1, 2026
16 checks passed
@SeanTAllen
SeanTAllen deleted the clear-error-queue-before-ssl-io branch August 1, 2026 02:48
@ponylang-main ponylang-main removed the discuss during sync Should be discussed during an upcoming sync label Aug 1, 2026
github-actions Bot pushed a commit that referenced this pull request Aug 1, 2026
github-actions Bot pushed a commit that referenced this pull request Aug 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog - fixed Automatically add "Fixed" CHANGELOG entry on merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A failed handshake puts unrelated healthy sessions into SSLError

2 participants