-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
quic: add QUIC downstream connection close error stats. #16584
Merged
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
b7b52e1
Add QUIC downstream connection close error stats.
RenjieTang a704f7d
change naming style
RenjieTang e77ca28
more naming change
RenjieTang 1b9275b
Change QuicStats to QuicStatNames and move its ownership to
RenjieTang a47dc19
Merge remote-tracking branch 'upstream/main' into quic-stats
RenjieTang c4394c5
fix format
RenjieTang 71f28c3
Remove OptRef and set quic_stat_names_ in constructors.
RenjieTang a71c23c
format
RenjieTang 79e200b
pre initialize more popular connection close error stats.
RenjieTang 8957117
add more tests
RenjieTang 5c83f5f
Merge remote-tracking branch 'upstream/main' into quic-stats
RenjieTang 6cd0d83
address Alyssa's comments.
RenjieTang 4fe3fc5
update stat name
RenjieTang ac867ce
doc formatting
RenjieTang d009105
attempt to fix flaky tests
RenjieTang 832b098
address Matt's comments.
RenjieTang 8b7047a
add corner case test.
RenjieTang 0cc03f4
fix doc underline
RenjieTang File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#include "common/quic/quic_stat_names.h" | ||
|
||
namespace Envoy { | ||
namespace Quic { | ||
|
||
// TODO(renjietang): Currently these stats are only available in downstream. Wire it up to upstream | ||
// QUIC also. | ||
QuicStatNames::QuicStatNames(Stats::SymbolTable& symbol_table) | ||
: stat_name_pool_(symbol_table), symbol_table_(symbol_table), | ||
http3_prefix_(stat_name_pool_.add("http3")), downstream_(stat_name_pool_.add("downstream")), | ||
upstream_(stat_name_pool_.add("upstream")), from_self_(stat_name_pool_.add("tx")), | ||
from_peer_(stat_name_pool_.add("rx")) { | ||
// Preallocate most used counters | ||
// Most popular in client initiated connection close. | ||
connectionCloseStatName(quic::QUIC_NETWORK_IDLE_TIMEOUT); | ||
RenjieTang marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Most popular in server initiated connection close. | ||
connectionCloseStatName(quic::QUIC_SILENT_IDLE_TIMEOUT); | ||
} | ||
|
||
void QuicStatNames::incCounter(Stats::Scope& scope, const Stats::StatNameVec& names) { | ||
Stats::SymbolTable::StoragePtr stat_name_storage = symbol_table_.join(names); | ||
RenjieTang marked this conversation as resolved.
Show resolved
Hide resolved
|
||
scope.counterFromStatName(Stats::StatName(stat_name_storage.get())).inc(); | ||
} | ||
|
||
void QuicStatNames::chargeQuicConnectionCloseStats(Stats::Scope& scope, | ||
quic::QuicErrorCode error_code, | ||
quic::ConnectionCloseSource source, | ||
bool is_upstream) { | ||
ASSERT(&symbol_table_ == &scope.symbolTable()); | ||
|
||
if (error_code > quic::QUIC_LAST_ERROR) { | ||
error_code = quic::QUIC_LAST_ERROR; | ||
} | ||
|
||
const Stats::StatName connection_close = connectionCloseStatName(error_code); | ||
incCounter(scope, {http3_prefix_, is_upstream ? upstream_ : downstream_, | ||
source == quic::ConnectionCloseSource::FROM_SELF ? from_self_ : from_peer_, | ||
connection_close}); | ||
} | ||
|
||
Stats::StatName QuicStatNames::connectionCloseStatName(quic::QuicErrorCode error_code) { | ||
ASSERT(error_code <= quic::QUIC_LAST_ERROR); | ||
|
||
return Stats::StatName( | ||
connection_error_stat_names_.get(error_code, [this, error_code]() -> const uint8_t* { | ||
return stat_name_pool_.addReturningStorage( | ||
absl::StrCat("quic_connection_close_error_code_", QuicErrorCodeToString(error_code))); | ||
})); | ||
} | ||
|
||
} // namespace Quic | ||
} // namespace Envoy |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#pragma once | ||
|
||
#include "envoy/stats/scope.h" | ||
|
||
#include "common/common/thread.h" | ||
#include "common/stats/symbol_table_impl.h" | ||
|
||
#include "quiche/quic/core/quic_error_codes.h" | ||
#include "quiche/quic/core/quic_types.h" | ||
|
||
namespace Envoy { | ||
namespace Quic { | ||
|
||
class QuicStatNames { | ||
public: | ||
// This class holds lazily symbolized stat names and is responsible for charging them. | ||
explicit QuicStatNames(Stats::SymbolTable& symbol_table); | ||
|
||
void chargeQuicConnectionCloseStats(Stats::Scope& scope, quic::QuicErrorCode error_code, | ||
quic::ConnectionCloseSource source, bool is_upstream); | ||
|
||
private: | ||
// Find the actual counter in |scope| and increment it. | ||
// An example counter name: "http3.downstream.tx.quic_connection_close_error_code_QUIC_NO_ERROR". | ||
void incCounter(Stats::Scope& scope, const Stats::StatNameVec& names); | ||
|
||
Stats::StatName connectionCloseStatName(quic::QuicErrorCode error_code); | ||
|
||
Stats::StatNamePool stat_name_pool_; | ||
Stats::SymbolTable& symbol_table_; | ||
const Stats::StatName http3_prefix_; | ||
const Stats::StatName downstream_; | ||
const Stats::StatName upstream_; | ||
alyssawilk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const Stats::StatName from_self_; | ||
const Stats::StatName from_peer_; | ||
Thread::AtomicPtrArray<const uint8_t, quic::QUIC_LAST_ERROR + 1, | ||
Thread::AtomicPtrAllocMode::DoNotDelete> | ||
connection_error_stat_names_; | ||
}; | ||
|
||
} // namespace Quic | ||
} // namespace Envoy |
This file contains 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
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a quick read through it's not clear to me that this won't create an unbounded number of stats controlled by downstream (for exampled if the name somehow has the code number in it and the client controls the codes). This is probably not the case, but can you add more comments about why this is safe for use with uncontrolled peers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great point!
I initially had an assertion in QuicStatNames::connectionCloseStatName() to make sure we don't create unlimited amount of stats.
But after some investigation, I found that if the connection close is initiated from peers, the error_code is parsed from the wire and no enum range checking is done. So an assertion here is too strong and malicious clients might be able to attack Envoy by sending out-of-range error codes.
Instead, I now added a check in QuicStatNames::chargeQuicConnectionCloseStats() to ignore out-of-range error_codes and log a warning.
I will follow up to dig deeper into the quiche code and see if bad error code handling can be done earlier.