fix(web): HTTPS receive buffer holds a whole TLS record; document the feature - #84
Merged
Conversation
… feature The server's 4096 B receive buffer killed every upload past ~4 KB over TLS (bisected on hardware: 3.5 KB passes, 5 KB dies mid-body): a TLS record must fit the receive buffer whole, the max-fragment-length extension is offered by clients only, and stock OpenSSL/browsers never offer it — they ship 16 KB records for any large body. Language packs and OTA images were impossible to upload over HTTPS while downloads worked fine, because our own transmit records are small. The receive buffer is now 16,709 B (BR_SSL_BUFSIZE_INPUT, one full record). It is allocated per accepted connection, not at boot; the post-boot largest free block measures 33.6 KB, so one TLS client fits with room. Under long-uptime fragmentation the accept can fail and that connection drops — the listener keeps running. Documented while at it, since the v2.2.6-beta feature never reached the manual: MANUAL §6 gains "Serving the UI over HTTPS" (openssl one-liner, Files-page provisioning, the 443 default, fallback = the off switch, and the one-TLS-client-at-a-time limit), SECURITY.md's attack surface covers the HTTPS mode, and the README comparison row mentions it in all three languages.
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.
First full hardware test of the HTTPS transport (shipped in v2.2.6-beta, never exercised end-to-end) found that every upload past ~4 KB killed the TLS connection mid-body — clean bisection: 3.5 KB passes, 5 KB dies in 0.5 s. Language packs (30 KB) and OTA images could not cross an encrypted session, while downloads worked, because our own transmit records are small.
Cause and fix
TLS record framing: a record must fit the receive buffer whole; the max-fragment-length extension is offered by clients only, and stock OpenSSL/browsers never offer it — they ship 16 KB records for any large body. The server's RX buffer was 4,096 B. It is now 16,709 B (
BR_SSL_BUFSIZE_INPUT, one full record), allocated per accepted connection, not at boot (post-boot largest free block: 33.6 KB — one TLS client fits).Measured on the rig (image
9ae86012, over OTA)/api/langover TLSECDHE-ECDSA-AES256-GCM-SHA384Secure+HttpOnlyKnown and documented (not fixed — buffer economics): one TLS client at a time; a second simultaneous connection is dropped without a response, and connections opened in a tight burst right after another closes can be reset.
Docs (the v2.2.6 feature never reached them)
MANUAL.md§6: new Serving the UI over HTTPS section — openssl one-liner, Files-page provisioning, the 443 default, fallback contract, limitations.SECURITY.md: attack-surface entry covers the HTTPS mode.