Conversation
Record::parse allocates a fresh buffer per incoming record and purge_handled_queue_rx returns each handled buffer to buffers_free, while only send/handshake paths pop from it. A mostly-receiving connection therefore grew the pool by one buffer per record without bound (~590 MB retained after receiving 1 GiB through str0m). Drop buffers once the pool holds 64 free entries. Fixes algesten#165
algesten
added a commit
that referenced
this pull request
Oct 1, 2026
## Summary DTLS 1.2 and DTLS 1.3 receive records now acquire buffers from the engine pool and recycle them on parsing failures, rejected datagrams, duplicate or old records, and receive-queue replacement. This prevents fresh receive allocations from accumulating in the pool and preserves reuse on discard paths. Retained handshake buffers also come from the pool. DTLS 1.2 key exchange transfers buffer ownership directly, and DTLS 1.3 retains derived traffic secrets without redundant copies. Remaining `Buf::new()` calls hold temporary work buffers, pre-engine probe state, or test fixtures. `BufferPool::push` uses an unconditional assertion to reject buffers that were not acquired from a pool, including in release builds. Regression tests cover repeated receive allocation reuse, malformed or oversized datagram cleanup, duplicate rejection, and rejection of fresh or replaced buffers. Fixes #165. Supersedes #166.
Owner
|
Restored the intended buffering behavior which I believe fixes this issue. |
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.
Fixes #165.
Problem
Record::parseallocates a fresh buffer for every incoming record.purge_handled_queue_rxthen returns each handled buffer tobuffers_free. Only the send and handshake paths take buffers back out of the pool, so a connection that mostly receives grows the pool by one buffer per record, with no upper bound. Through str0m, that was about 590 MB retained after receiving 1 GiB.Change
BufferPool::pushnow drops the buffer once the pool already holdsMAX_POOLED_BUFFERS(64) free entries.The cap of 64 is a judgment call. I'm happy to switch to a value derived from
max_queue_rx/max_queue_tx, or to makeRecord::parsetake its buffer from the pool, if you prefer.Verification
cargo test --lib: 303 passed with default features, 253 with--no-default-features --features aws-lc-rs, and 253 with--features rust-crypto.auto62 passed anddtls1273 passed, both with--features aws-lc-rs,rcgen.cargo fmt --checkandcargo clippy -D warningsare clean.dtls13,ossl), because my machine has no libclang forwolfssl-sys. CI should cover those.