Skip to content
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

http2: fixing a (known) potential stall in the filter chain for H2 #7093

Merged
merged 3 commits into from
May 30, 2019

Conversation

alyssawilk
Copy link
Contributor

@alyssawilk alyssawilk commented May 28, 2019

Fixing a bug where if pausing with StopIterationNoBuffer, continuing with fin-only payload wouldn't result in the filter chain continuing.

Risk Level: High (tweak to the HCM)
Testing: new integration test
Docs Changes: n/a
Release Notes: n/a

Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
@alyssawilk
Copy link
Contributor Author

Alternately we could always just create the buffer on returning StopIterationNoBuffer, but that felt higher risk

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Thanks for fixing this long standing issue. A few questions.

/wait

@@ -164,6 +164,9 @@ class ConnectionManagerImpl : Logger::Loggable<Logger::Id::http>,
// current filter instead of the next one. If true, filter iteration starts with the current
// filter. Otherwise, starts with the next filter in the chain.
bool iterate_from_current_filter_;
// Tracks if the stream end has been sent with an encode/decodeData call, to handle the case
// where commonContinue is called with the only information being a terminal fin.
bool end_stream_sent_with_data_;
Copy link
Member

Choose a reason for hiding this comment

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

Can we add this bool to the bitfield below? IIRC the reason the one above isn't in it is because it needs to be passed by address somewhere.

doData(complete() && !trailers());
// Make sure we handle filters returning StopIterationNoBuffer and then commonContinue by tracking
// if the terminal fin has already been proxied.
bool end_stream_with_data = complete() && !trailers();
Copy link
Member

Choose a reason for hiding this comment

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

nit: const

// buffer but encode/decodeData expects the buffer to exist, so create one.
bufferedData() = createBuffer();
}
end_stream_sent_with_data_ = true;
Copy link
Member

Choose a reason for hiding this comment

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

Sorry why do we need the member variable? Can't we just compute this locally and then decide whether to create the buffer or not?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My concern was there might be some case with StopAllIIteration where we might end up relaying the FIN twice. if you're confident that commonDecodePrefix will pick up the right filter (which theoretically it ought to when bodies are present, so ought to when they're absent?) I'm fine nixing the local state.

Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Very nice. Thanks for the integration test! LGTM.

@alyssawilk alyssawilk merged commit 1065ee4 into envoyproxy:master May 30, 2019
@alyssawilk alyssawilk deleted the h2_fix branch December 9, 2019 21:11
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.

2 participants