Add TLS receive read-ahead support#10944
Open
Frauschi wants to merge 1 commit into
Open
Conversation
Add WOLFSSL_TLS_READ_AHEAD (--enable-readahead), toggled at runtime via wolfSSL_set_read_ahead(). When enabled, the record-header read pulls a full record in one recv() so the body arrives without a second syscall. The receive window is configurable with wolfSSL_CTX/SSL_set_default_read_buffer_len() (OpenSSL-compatible): 0 keeps the one-record default, a larger value coalesces several records per recv(), a smaller value caps the per-connection buffer footprint. Records exceeding the window are still received correctly, the buffer grows on demand and is reallocated back down to the window afterwards so the retained footprint stays bounded. Includes docs, API tests, and a benchmark toggle.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds an optional TLS receive read-ahead mode that cuts the number of
recv()syscalls on the TLS receive path.Without read-ahead, reading one TLS record needs at least two socket reads: one for the 5-byte record header (to learn the record length), then one (or more) for the body. With read-ahead enabled, the header read instead requests a full record's worth of data in a single
recv(), so the body — and any following records the peer already sent — arrive without a second syscall.The feature is:
--enable-readahead(WOLFSSL_TLS_READ_AHEAD).WOLFSSL/WOLFSSL_CTXviawolfSSL_set_read_ahead()(the existing OpenSSL-compatible flag).wolfSSL_CTX_set_default_read_buffer_len()/wolfSSL_set_default_read_buffer_len()(OpenSSL-compatible), which set the read-ahead window.New API
The existing
wolfSSL_[CTX_]set/get_read_ahead()flag functions are now alsoavailable under
WOLFSSL_TLS_READ_AHEAD(previouslyOPENSSL_EXTRAonly).Behavior and design
set_default_read_buffer_len):0selects the one-record default (WOLFSSL_READ_AHEAD_SZ, one max TLS record) — this is also the value a fresh context carries.recv()coalesce several back-to-back records.WOLFSSL_MAX_READ_AHEAD_SZ(16 MB) so a caller-supplied size can never overflow the receive-path arithmetic.wolfSSL_has_pending()reports buffered-but-undecrypted data so event-driven (select/poll) apps drain everything before returning to the poll loop. As with OpenSSL'sSSL_has_pending, a non-zero return does not guarantee a full record — apps should read untilWANT_READ.OpenSSL compatibility
SSL_CTX/SSL_set_default_read_buffer_len()andSSL_[CTX_]set/get_read_ahead()map to these functions, so existing OpenSSL code compiles unchanged. The wolfSSL setters return a status code (OpenSSL returnsvoid; callers that ignore the return remain source-compatible) and additionally honour sub-record window sizes, whereas OpenSSL only ever enlarges the buffer.Benchmarks
curl 100 MB HTTP/1.1 downloads through wolfSSL against httpd 2.4.68 (
scorecard.py, 10 samples each; aarch64-apple-darwin, curl 8.22.0-DEV / wolfSSL 5.9.2). Format isthroughput [cpu%/rss].The A/B toggle used here is wired into
examples/benchmark/tls_bench.candexamples/client/client.cbehind theWOLF_BENCH_READ_AHEADenvironment variable (active when built with read-ahead and filesystem support).Testing
New API tests in
tests/api.c:test_wolfSSL_read_ahead— confirms the record header + body are fetched in a singlerecv()(fewer callbacks than the two-read default).test_wolfSSL_read_ahead_coalesced— an app-data record coalesced with a following close_notify is delivered before the close, and stays visible towolfSSL_has_pending().test_wolfSSL_read_ahead_buffer_len— window sizing, coalescing, retained footprint, and shrink-back after an oversized record.test_wolfSSL_read_ahead_ctx_inherit— CTX-level accessors, CTX->SSL inheritance, NULL-argument handling,0-resets-to-default, and the oversized-window clamp.Verified building and passing under
--enable-readahead(feature on) and--enable-opensslextra(accessors compiled, read-ahead I/O off, tests skip); the client and benchmark examples compile in both configurations.Configuration
--enable-readahead->WOLFSSL_TLS_READ_AHEADBackward compatibility
No public API signatures changed. The
wolfSSL_[CTX_]set/get_read_ahead()declarations are now guarded byOPENSSL_EXTRA || WOLFSSL_TLS_READ_AHEADto match their definitions and the underlying struct members; existingOPENSSL_EXTRAbuilds are unaffected.