Make port descriptors caller-owned - #13518
Draft
bneradt wants to merge 1 commit into
Draft
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR addresses a long-standing leak in the TSPortDescriptor API by changing the API from returning an unfreeable heap-allocated handle to using caller-owned opaque storage, and adds end-to-end coverage to verify a plugin can actually listen on a parsed descriptor.
Changes:
- Redesign
TSPortDescriptorto be caller-owned opaque storage; updateTSPortDescriptorParse/TSPortDescriptorAcceptsignatures and all in-tree call sites. - Add an AuTest plugin + gold test that parses a dynamically selected port descriptor and successfully accepts a connection.
- Remove the
TSPortDescriptorregression-test leak suppression now that the leak is fixed.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
include/ts/apidefs.h.in |
Redefines TSPortDescriptor as caller-owned opaque storage. |
include/ts/ts.h |
Updates API declarations and docs for the new parse/accept signatures and ownership model. |
src/api/InkAPI.cc |
Implements storage-backed parsing (placement-new) and updates accept to use the new descriptor representation. |
src/api/InkAPITest.cc |
Updates the regression test to use the new parse/accept API shape. |
example/plugins/c-api/passthru/passthru.cc |
Updates example plugin to use the new parse/accept signatures. |
tests/tools/plugins/port_descriptor.cc |
Adds an autest plugin that parses/accepts a descriptor and closes accepted connections. |
tests/tools/plugins/CMakeLists.txt |
Builds the new port_descriptor autest plugin. |
tests/gold_tests/pluginTest/port_descriptor/port_descriptor.test.py |
Adds a gold test that connects to the dynamically chosen descriptor port (via nc). |
ci/asan_leak_suppression/regression.txt |
Drops the suppression for the previously-leaking regression test. |
bneradt
force-pushed
the
fix-port-descriptor-api
branch
from
August 7, 2026 20:02
31787d2 to
c59e412
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.
Suppressed comments (2)
src/api/InkAPI.cc:27
- InkAPI.cc now uses std::is_trivially_destructible_v but does not include <type_traits> directly, relying on transitive includes. Add the header here to keep dependencies explicit and avoid build breaks if include graphs change.
#include <tuple>
include/ts/apidefs.h.in:1155
- TSPortDescriptor’s opaque storage is hard-coded to 216 bytes with 8-byte alignment, while the implementation enforces exact size/alignment equality with HttpProxyPort. This is brittle across platform/compiler/flag variations and requires manual updates whenever HttpProxyPort layout changes. Consider generating the size/alignment into apidefs.h from the build (or providing headroom and using >= static_asserts) to reduce churn and portability risk.
class alignas(std::uint64_t) TSPortDescriptor
{
friend TSReturnCode TSPortDescriptorParse(const char *, TSPortDescriptor *);
friend TSReturnCode TSPortDescriptorAccept(const TSPortDescriptor *, struct tsapi_cont *);
private:
std::byte _opaque[216];
};
bneradt
force-pushed
the
fix-port-descriptor-api
branch
from
August 7, 2026 20:24
c59e412 to
229c40c
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.
Suppressed comments (1)
include/ts/apidefs.h.in:1156
- TSPortDescriptorParse() placement-news HttpProxyPort into
result->_opaque. Right now_opaqueitself has alignment 1 (std::byte), so correct alignment relies on_opaquestaying the first member and the class-levelalignasnot changing. If a future change adds a member before_opaque, the placement-new could become misaligned and trigger UB. Align_opaqueitself so its address is always sufficiently aligned regardless of member ordering.
private:
std::byte _opaque[216];
bool _is_valid{false};
};
TSPortDescriptorParse allocates an HttpProxyPort that plugins cannot release, so every parsed descriptor leaks for the lifetime of Traffic Server. The API also lacks end-to-end coverage for accepting connections on a parsed port. This patch replaces the pointer handle with caller-owned opaque storage whose size and alignment are checked against HttpProxyPort. It updates API users and adds an AuTest plugin that listens on a dynamically selected port. Fixes: apache#6894
bneradt
force-pushed
the
fix-port-descriptor-api
branch
from
August 7, 2026 20:32
229c40c to
c93d398
Compare
bneradt
marked this pull request as draft
August 7, 2026 20:39
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.
Marking as a draft pending community approval from a
dev@trafficserver.apache.orgemail.TSPortDescriptorParse allocates an HttpProxyPort that plugins cannot
release, so every parsed descriptor leaks for the lifetime of Traffic
Server. The API also lacks end-to-end coverage for accepting
connections on a parsed port.
This patch replaces the pointer handle with caller-owned opaque storage
whose size and alignment are checked against HttpProxyPort. It updates
API users and adds an AuTest plugin that listens on a dynamically
selected port.
Fixes: #6894