Skip to content

eof spun forever on a record truncated by the peer closing - #87

Draft
krynju wants to merge 1 commit into
JuliaWeb:mainfrom
krynju:kr/eof-truncated-record
Draft

krynju wants to merge 1 commit into
JuliaWeb:mainfrom
krynju:kr/eof-truncated-record

Conversation

@krynju

@krynju krynju commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Split out of #73, as asked in the review there: an independent fix, against main.

Bug. When the peer closes mid-record, SSL_peek_ex keeps returning WANT_READ, haspending stays true for the partial record, and eof(ssl.io) returns true at once. eof then loops without ever yielding, which starves every other task on the thread; on one thread the process hangs.

Fix. In the WANT_READ branch of eof, return true when the socket is at EOF: the bytes that would complete the record are never coming, so this is the end of the stream. One more round is allowed first (review finding): a concurrent unsafe_read waiting on the socket ahead of this task can take the rest of the record while eof waits, in which case bytesavailable shows the decrypted bytes on the next round and eof is false.

Test. TruncatedRecordEOF sends a record header announcing 100 bytes followed by 3 of them, then closes the socket with a FIN (a reader task keeps the client socket drained of the server's session tickets, so the close is not a RST). On main the test spins until the job timeout instead of failing.

The test file gains the same three helpers as #86 (self-signed server context, handshake loop, connected pair), in the same place, so whichever lands later only has to re-append its testset.

No version bump; the fixes can be released together.

🤖 Generated with Claude Code

@codecov

codecov Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.79%. Comparing base (10f7b7b) to head (0e75202).
⚠️ Report is 41 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #87      +/-   ##
==========================================
+ Coverage   77.56%   78.79%   +1.23%     
==========================================
  Files           2        2              
  Lines        1083     1193     +110     
==========================================
+ Hits          840      940     +100     
- Misses        243      253      +10     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@krynju
krynju marked this pull request as draft October 16, 2026 10:16
When the peer closes mid-record, `SSL_peek_ex` keeps returning
WANT_READ, `haspending` stays true for the partial record, and
`eof(ssl.io)` returns true at once, so `eof` looped without ever
yielding, starving every other task on the thread. Return true there:
the bytes that would complete the record are never coming.

One more round is allowed first: a concurrent read waiting on the socket
ahead of this task may have taken the rest of the record while this
task waited, in which case `bytesavailable` shows the decrypted bytes
and `eof` is false.

Adds `TruncatedRecordEOF`, which sends a partial record header and
closes the socket cleanly. Without the fix it spins instead of failing.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@krynju
krynju force-pushed the kr/eof-truncated-record branch from 3e2a2e6 to 0e75202 Compare October 16, 2026 10:50
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.

1 participant