Return transport parameters from TlsChloExtractor
Protected by FLAGS_quic_reloadable_flag_quic_parse_transport_parameters_from_chlo.
PiperOrigin-RevId: 704748800
diff --git a/quiche/common/quiche_feature_flags_list.h b/quiche/common/quiche_feature_flags_list.h
index b5047ca..1c2ddd7 100755
--- a/quiche/common/quiche_feature_flags_list.h
+++ b/quiche/common/quiche_feature_flags_list.h
@@ -51,6 +51,7 @@
QUICHE_FLAG(bool, quiche_reloadable_flag_quic_optimize_qpack_blocking_manager, false, false, "If true, optimize qpack_blocking_manager for CPU efficiency.")
QUICHE_FLAG(bool, quiche_reloadable_flag_quic_pacing_remove_non_initial_burst, false, false, "If true, remove the non-initial burst in QUIC PacingSender.")
QUICHE_FLAG(bool, quiche_reloadable_flag_quic_parse_cert_compression_algos_from_chlo, true, true, "If true, parse offered cert compression algorithms from received CHLOs.")
+QUICHE_FLAG(bool, quiche_reloadable_flag_quic_parse_transport_parameters_from_chlo, false, false, "If true, parse QUIC transport parameters from received CHLOs.")
QUICHE_FLAG(bool, quiche_reloadable_flag_quic_priority_respect_incremental, false, false, "If true, respect the incremental parameter of each stream in QuicWriteBlockedList.")
QUICHE_FLAG(bool, quiche_reloadable_flag_quic_require_handshake_confirmation, true, true, "If true, require handshake confirmation for QUIC connections, functionally disabling 0-rtt handshakes.")
QUICHE_FLAG(bool, quiche_reloadable_flag_quic_send_placeholder_ticket_when_encrypt_ticket_fails, true, true, "If true, when TicketCrypter fails to encrypt a session ticket, quic::TlsServerHandshaker will send a placeholder ticket, instead of an empty one, to the client.")
diff --git a/quiche/quic/core/tls_chlo_extractor.cc b/quiche/quic/core/tls_chlo_extractor.cc
index 7466642..356338c 100644
--- a/quiche/quic/core/tls_chlo_extractor.cc
+++ b/quiche/quic/core/tls_chlo_extractor.cc
@@ -108,6 +108,20 @@
return cert_compression_algos;
}
+std::vector<uint8_t> GetTransportParameters(
+ const SSL_CLIENT_HELLO* client_hello) {
+ const uint8_t* transport_params_data;
+ size_t transport_params_len;
+ int rv = SSL_early_callback_ctx_extension_get(
+ client_hello, TLSEXT_TYPE_quic_transport_parameters,
+ &transport_params_data, &transport_params_len);
+ if (rv != 1) {
+ return {};
+ }
+ return std::vector<uint8_t>(transport_params_data,
+ transport_params_data + transport_params_len);
+}
+
} // namespace
TlsChloExtractor::TlsChloExtractor()
@@ -423,6 +437,12 @@
}
}
+ if (GetQuicReloadableFlag(quic_parse_transport_parameters_from_chlo)) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_parse_transport_parameters_from_chlo);
+
+ transport_params_ = GetTransportParameters(client_hello);
+ }
+
// Update our state now that we've parsed a full CHLO.
if (state_ == State::kInitial) {
state_ = State::kParsedFullSinglePacketChlo;
diff --git a/quiche/quic/core/tls_chlo_extractor.h b/quiche/quic/core/tls_chlo_extractor.h
index 8ded967..297063c 100644
--- a/quiche/quic/core/tls_chlo_extractor.h
+++ b/quiche/quic/core/tls_chlo_extractor.h
@@ -57,6 +57,9 @@
const std::vector<uint16_t>& cert_compression_algos() const {
return cert_compression_algos_;
}
+ absl::Span<const uint8_t> transport_params() const {
+ return transport_params_;
+ }
absl::Span<const uint8_t> client_hello_bytes() const {
return client_hello_bytes_;
}
@@ -282,6 +285,9 @@
// If set, contains the TLS alert that caused an unrecoverable error, which is
// an AlertDescription value defined in go/rfc/8446#appendix-B.2.
std::optional<uint8_t> tls_alert_;
+ // QUIC Transport Parameters, if present in the CHLO.
+ // Not populated for draft29.
+ std::vector<uint8_t> transport_params_;
// Exact TLS message bytes.
std::vector<uint8_t> client_hello_bytes_;
};
diff --git a/quiche/quic/core/tls_chlo_extractor_test.cc b/quiche/quic/core/tls_chlo_extractor_test.cc
index 2bc2044..64e0ec9 100644
--- a/quiche/quic/core/tls_chlo_extractor_test.cc
+++ b/quiche/quic/core/tls_chlo_extractor_test.cc
@@ -284,6 +284,25 @@
}
}
+TEST_P(TlsChloExtractorTest, TlsExtensionInfo_QuicTransportParameters) {
+ Initialize();
+ EXPECT_EQ(packets_.size(), 1u);
+ IngestPackets();
+ ValidateChloDetails();
+
+ if (GetQuicReloadableFlag(quic_parse_transport_parameters_from_chlo)) {
+ // RFC QUIC has transport parameters, drafts doesn't.
+ if (version_ == ParsedQuicVersion::RFCv1() ||
+ version_ == ParsedQuicVersion::RFCv2()) {
+ EXPECT_FALSE(tls_chlo_extractor_->transport_params().empty());
+ } else {
+ EXPECT_TRUE(tls_chlo_extractor_->transport_params().empty());
+ }
+ } else {
+ EXPECT_TRUE(tls_chlo_extractor_->transport_params().empty());
+ }
+}
+
TEST_P(TlsChloExtractorTest, MultiPacket) {
IncreaseSizeOfChlo();
Initialize();