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();