Group some client hello information into ParsedClientHello, a new struct that can be passed around easily.
PiperOrigin-RevId: 404857674
diff --git a/quic/core/quic_dispatcher.cc b/quic/core/quic_dispatcher.cc
index ad17281..02a0c8f 100644
--- a/quic/core/quic_dispatcher.cc
+++ b/quic/core/quic_dispatcher.cc
@@ -719,27 +719,27 @@
QuicPacketFate fate = ValidityChecks(*packet_info);
if (fate == kFateProcess) {
- std::string sni, uaid, legacy_version_encapsulation_inner_packet;
- std::vector<std::string> alpns;
- if (!TryExtractChloOrBufferEarlyPacket(
- *packet_info, &sni, &uaid, &alpns,
- &legacy_version_encapsulation_inner_packet)) {
+ absl::optional<ParsedClientHello> parsed_chlo =
+ TryExtractChloOrBufferEarlyPacket(*packet_info);
+ if (!parsed_chlo.has_value()) {
// Client Hello incomplete. Packet has been buffered or (rarely) dropped.
return;
}
// Client Hello fully received.
- fate = ValidityChecksOnFullChlo(*packet_info, sni, uaid, alpns);
+ fate = ValidityChecksOnFullChlo(*packet_info, *parsed_chlo);
if (fate == kFateProcess) {
- QUICHE_DCHECK(legacy_version_encapsulation_inner_packet.empty() ||
- !packet_info->version.UsesTls());
+ QUICHE_DCHECK(
+ parsed_chlo->legacy_version_encapsulation_inner_packet.empty() ||
+ !packet_info->version.UsesTls());
if (MaybeHandleLegacyVersionEncapsulation(
- this, legacy_version_encapsulation_inner_packet, *packet_info)) {
+ this, parsed_chlo->legacy_version_encapsulation_inner_packet,
+ *packet_info)) {
return;
}
- ProcessChlo(alpns, sni, packet_info);
+ ProcessChlo(*parsed_chlo, packet_info);
return;
}
}
@@ -775,26 +775,20 @@
}
}
-bool QuicDispatcher::TryExtractChloOrBufferEarlyPacket(
- const ReceivedPacketInfo& packet_info,
- std::string* sni,
- std::string* uaid,
- std::vector<std::string>* alpns,
- std::string* legacy_version_encapsulation_inner_packet) {
- sni->clear();
- uaid->clear();
- alpns->clear();
- legacy_version_encapsulation_inner_packet->clear();
-
+absl::optional<QuicDispatcher::ParsedClientHello>
+QuicDispatcher::TryExtractChloOrBufferEarlyPacket(
+ const ReceivedPacketInfo& packet_info) {
if (packet_info.version.UsesTls()) {
bool has_full_tls_chlo = false;
+ std::string sni;
+ std::vector<std::string> alpns;
if (buffered_packets_.HasBufferedPackets(
packet_info.destination_connection_id)) {
// If we already have buffered packets for this connection ID,
// use the associated TlsChloExtractor to parse this packet.
has_full_tls_chlo = buffered_packets_.IngestPacketForTlsChloExtraction(
packet_info.destination_connection_id, packet_info.version,
- packet_info.packet, alpns, sni);
+ packet_info.packet, &alpns, &sni);
} else {
// If we do not have a BufferedPacketList for this connection ID,
// create a single-use one to check whether this packet contains a
@@ -804,8 +798,8 @@
if (tls_chlo_extractor.HasParsedFullChlo()) {
// This packet contains a full single-packet CHLO.
has_full_tls_chlo = true;
- *alpns = tls_chlo_extractor.alpns();
- *sni = tls_chlo_extractor.server_name();
+ alpns = tls_chlo_extractor.alpns();
+ sni = tls_chlo_extractor.server_name();
}
}
if (!has_full_tls_chlo) {
@@ -813,9 +807,13 @@
// packet that arrived before the CHLO (due to loss or reordering),
// or it could be a fragment of a multi-packet CHLO.
BufferEarlyPacket(packet_info);
+ return absl::nullopt;
}
- return has_full_tls_chlo;
+ ParsedClientHello parsed_chlo;
+ parsed_chlo.sni = std::move(sni);
+ parsed_chlo.alpns = std::move(alpns);
+ return parsed_chlo;
}
ChloAlpnSniExtractor alpn_extractor;
@@ -826,7 +824,7 @@
packet_info.destination_connection_id.length())) {
// Buffer non-CHLO packets.
BufferEarlyPacket(packet_info);
- return false;
+ return absl::nullopt;
}
// We only apply this check for versions that do not use the IETF
@@ -839,15 +837,16 @@
QUIC_DVLOG(1) << "Dropping CHLO packet which is too short, length: "
<< packet_info.packet.length();
QUIC_CODE_COUNT(quic_drop_small_chlo_packets);
- return false;
+ return absl::nullopt;
}
- *legacy_version_encapsulation_inner_packet =
+ ParsedClientHello parsed_chlo;
+ parsed_chlo.legacy_version_encapsulation_inner_packet =
alpn_extractor.ConsumeLegacyVersionEncapsulationInnerPacket();
- *sni = alpn_extractor.ConsumeSni();
- *uaid = alpn_extractor.ConsumeUaid();
- *alpns = {alpn_extractor.ConsumeAlpn()};
- return true;
+ parsed_chlo.sni = alpn_extractor.ConsumeSni();
+ parsed_chlo.uaid = alpn_extractor.ConsumeUaid();
+ parsed_chlo.alpns = {alpn_extractor.ConsumeAlpn()};
+ return parsed_chlo;
}
std::string QuicDispatcher::SelectAlpn(const std::vector<std::string>& alpns) {
@@ -1312,8 +1311,7 @@
}
}
-void QuicDispatcher::ProcessChlo(const std::vector<std::string>& alpns,
- absl::string_view sni,
+void QuicDispatcher::ProcessChlo(const ParsedClientHello& parsed_chlo,
ReceivedPacketInfo* packet_info) {
if (!buffered_packets_.HasBufferedPackets(
packet_info->destination_connection_id) &&
@@ -1329,7 +1327,8 @@
packet_info->destination_connection_id,
packet_info->form != GOOGLE_QUIC_PACKET, packet_info->packet,
packet_info->self_address, packet_info->peer_address,
- /*is_chlo=*/true, alpns, sni, packet_info->version);
+ /*is_chlo=*/true, parsed_chlo.alpns, parsed_chlo.sni,
+ packet_info->version);
if (rs != EnqueuePacketResult::SUCCESS) {
OnBufferPacketFailure(rs, packet_info->destination_connection_id);
}
@@ -1341,10 +1340,10 @@
packet_info->destination_connection_id = MaybeReplaceServerConnectionId(
original_connection_id, packet_info->version);
// Creates a new session and process all buffered packets for this connection.
- std::string alpn = SelectAlpn(alpns);
+ std::string alpn = SelectAlpn(parsed_chlo.alpns);
std::unique_ptr<QuicSession> session = CreateQuicSession(
packet_info->destination_connection_id, packet_info->self_address,
- packet_info->peer_address, alpn, packet_info->version, sni);
+ packet_info->peer_address, alpn, packet_info->version, parsed_chlo.sni);
if (QUIC_PREDICT_FALSE(session == nullptr)) {
QUIC_BUG(quic_bug_10287_8)
<< "CreateQuicSession returned nullptr for "
diff --git a/quic/core/quic_dispatcher.h b/quic/core/quic_dispatcher.h
index 0073666..1c4e53b 100644
--- a/quic/core/quic_dispatcher.h
+++ b/quic/core/quic_dispatcher.h
@@ -169,6 +169,15 @@
}
protected:
+ // ParsedClientHello contains client hello information extracted from a fully
+ // received client hello.
+ struct QUIC_NO_EXPORT ParsedClientHello {
+ std::string sni; // QUIC crypto and TLS.
+ std::string uaid; // QUIC crypto only.
+ std::vector<std::string> alpns; // QUIC crypto and TLS.
+ std::string legacy_version_encapsulation_inner_packet; // QUIC crypto only.
+ };
+
virtual std::unique_ptr<QuicSession> CreateQuicSession(
QuicConnectionId server_connection_id,
const QuicSocketAddress& self_address,
@@ -232,9 +241,7 @@
// Only called if ValidityChecks returns kFateProcess.
virtual QuicPacketFate ValidityChecksOnFullChlo(
const ReceivedPacketInfo& /*packet_info*/,
- const std::string& /*sni*/,
- const std::string& /*uaid*/,
- const std::vector<std::string>& /*alpns*/) const {
+ const ParsedClientHello& /*parsed_chlo*/) const {
return kFateProcess;
}
@@ -245,10 +252,10 @@
// Buffers packet until it can be delivered to a connection.
void BufferEarlyPacket(const ReceivedPacketInfo& packet_info);
- // Called when |packet_info| is a CHLO packet. Creates a new connection and
- // delivers any buffered packets for that connection id.
- void ProcessChlo(const std::vector<std::string>& alpns,
- absl::string_view sni,
+ // Called when |packet_info| is the last received packet of the client hello.
+ // |parsed_chlo| is the parsed version of the client hello. Creates a new
+ // connection and delivers any buffered packets for that connection id.
+ void ProcessChlo(const ParsedClientHello& parsed_chlo,
ReceivedPacketInfo* packet_info);
// Return true if dispatcher wants to destroy session outside of
@@ -387,17 +394,13 @@
// Try to extract information(sni, alpns, ...) if the full Client Hello has
// been parsed.
//
- // If the full Client Hello has been parsed, return true and set |sni|,
- // |alpns| and |legacy_version_encapsulation_inner_packet|. |uaid| will be
- // populated for QUIC_CRYPTO only.
+ // Return the parsed client hello if the full Client Hello has been
+ // successfully parsed.
//
- // Otherwise return false and either buffer or (rarely) drop the packet.
- bool TryExtractChloOrBufferEarlyPacket(
- const ReceivedPacketInfo& packet_info,
- std::string* sni,
- std::string* uaid,
- std::vector<std::string>* alpns,
- std::string* legacy_version_encapsulation_inner_packet);
+ // Otherwise return absl::nullopt and either buffer or (rarely) drop the
+ // packet.
+ absl::optional<ParsedClientHello> TryExtractChloOrBufferEarlyPacket(
+ const ReceivedPacketInfo& packet_info);
// Deliver |packets| to |session| for further processing.
void DeliverPacketsToSession(