Skip to content

hcm: Ensure operations are not called on deleted stream decoders #39346

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

abeyad
Copy link
Contributor

@abeyad abeyad commented May 5, 2025

Previously, it was possible for the ActiveStream in the HttpConnectionManager to get deleted while still trying to process packets from the codec.

This change uses the ActiveStreamHandle with weak pointer semantics to ensure that even with incoming data packets, methods are not called on a deleted ActiveStream, which represents the HCM's RequestDecoder.

Previously, it was possible for the `ActiveStream` in the
`HttpConnectionManager` to get deleted while still trying to process
packets from the codec.

This change uses the `ActiveStreamHandle` with weak pointer semantics to
ensure that even with incoming data packets, methods are not called on a
deleted `ActiveStream`, which represents the HCM's `RequestDecoder`.

Signed-off-by: Ali Beyad <[email protected]>
@abeyad
Copy link
Contributor Author

abeyad commented May 5, 2025

cc @wu-bin

@abeyad
Copy link
Contributor Author

abeyad commented May 6, 2025

/wait

Copy link
Contributor

@KBaichoo KBaichoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for working on this.

IIUC we use the ActiveStreamHandle weak pointer semantics (the shared ptr gets dtored on when the stream is deleted) to check that the HCM ActiveStream is still alive. We only need to do this for server-side streams since it's only an issue with HCM interactions between the two.

A release note in current.yaml is probably worth adding as a bug fix -- and CI is failing.

Otherwise LGTM.

@@ -608,8 +617,12 @@ void ConnectionImpl::ServerStreamImpl::decodeTrailers() {
// Consume any buffered trailers.
stream_manager_.trailers_buffered_ = false;

request_decoder_->decodeTrailers(
std::move(absl::get<RequestTrailerMapPtr>(headers_or_trailers_)));
RequestDecoder* request_decoder = request_decoder_handle_->get().ptr();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just call decoder() method here? like RequestDecoder* request_decoder = decoder();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, done!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually the reason I did that is decoder() returns a StreamDecoder* which doesn't have methods to decode headers or trailers, hence why I directly get the RequestDecoder*.

@@ -585,7 +585,9 @@ class ConnectionImpl : public virtual Connection,
// written out before force resetting the stream, assuming there is enough H2 connection flow
// control window is available.
bool useDeferredReset() const override { return true; }
StreamDecoder& decoder() override { return *request_decoder_; }
StreamDecoder* decoder() override {
return request_decoder_handle_->get().ptr();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get() should get you the raw pointer. Is the .ptr() redundant?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get() gets an OptRef:

OptRef<RequestDecoder> get() override {
, on which you have to call ptr() to get the raw pointer.

Signed-off-by: Ali Beyad <[email protected]>
@abeyad
Copy link
Contributor Author

abeyad commented May 8, 2025

Thank you for working on this.

IIUC we use the ActiveStreamHandle weak pointer semantics (the shared ptr gets dtored on when the stream is deleted) to check that the HCM ActiveStream is still alive. We only need to do this for server-side streams since it's only an issue with HCM interactions between the two.

A release note in current.yaml is probably worth adding as a bug fix -- and CI is failing.

Otherwise LGTM.

Thanks, added a note to current.yaml.

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.

3 participants