Support 0-RTT in quic_client_interop_test_bin.cc PiperOrigin-RevId: 315602326 Change-Id: I3dda38033268b3e5f6577b579dc3c194a90c86e4
diff --git a/quic/core/quic_versions.cc b/quic/core/quic_versions.cc index 0bbc1b8..192ba99 100644 --- a/quic/core/quic_versions.cc +++ b/quic/core/quic_versions.cc
@@ -660,6 +660,7 @@ void QuicVersionInitializeSupportForIetfDraft() { // Enable necessary flags. + SetQuicReloadableFlag(quic_enable_tls_resumption, true); SetQuicReloadableFlag(quic_enable_zero_rtt_for_tls, true); }
diff --git a/quic/tools/quic_client_interop_test_bin.cc b/quic/tools/quic_client_interop_test_bin.cc index 803e313..aadf459 100644 --- a/quic/tools/quic_client_interop_test_bin.cc +++ b/quic/tools/quic_client_interop_test_bin.cc
@@ -41,6 +41,8 @@ kConnectionClose, // The connection was established using TLS resumption. kResumption, + // 0-RTT data is being sent and acted on. + kZeroRtt, // A RETRY packet was successfully processed. kRetry, @@ -68,6 +70,8 @@ return 'C'; case Feature::kResumption: return 'R'; + case Feature::kZeroRtt: + return 'Z'; case Feature::kRetry: return 'S'; case Feature::kRebinding: @@ -90,7 +94,7 @@ // Attempts a resumption using |client| by disconnecting and reconnecting. If // resumption is successful, |features_| is modified to add // Feature::kResumption to it, otherwise it is left unmodified. - void AttemptResumption(QuicClient* client); + void AttemptResumption(QuicClient* client, const std::string& authority); void AttemptRequest(QuicSocketAddress addr, std::string authority, @@ -99,6 +103,14 @@ bool test_version_negotiation, bool attempt_rebind); + // Constructs a SpdyHeaderBlock containing the pseudo-headers needed to make a + // GET request to "/" on the hostname |authority|. + spdy::SpdyHeaderBlock ConstructHeaderBlock(const std::string& authority); + + // Sends an HTTP request represented by |header_block| using |client|. + void SendRequest(QuicClient* client, + const spdy::SpdyHeaderBlock& header_block); + void OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override { switch (frame.close_type) { case GOOGLE_QUIC_CONNECTION_CLOSE: @@ -134,20 +146,37 @@ std::set<Feature> features_; }; -void QuicClientInteropRunner::AttemptResumption(QuicClient* client) { +void QuicClientInteropRunner::AttemptResumption(QuicClient* client, + const std::string& authority) { client->Disconnect(); if (!client->Initialize()) { QUIC_LOG(ERROR) << "Failed to reinitialize client"; return; } - if (!client->Connect() || !client->session()->OneRttKeysAvailable()) { + if (!client->Connect()) { return; } + + bool zero_rtt_attempt = !client->session()->OneRttKeysAvailable(); + + spdy::SpdyHeaderBlock header_block = ConstructHeaderBlock(authority); + SendRequest(client, header_block); + + if (!client->session()->OneRttKeysAvailable()) { + return; + } + if (static_cast<QuicCryptoClientStream*>( test::QuicSessionPeer::GetMutableCryptoStream(client->session())) ->IsResumption()) { InsertFeature(Feature::kResumption); } + if (static_cast<QuicCryptoClientStream*>( + test::QuicSessionPeer::GetMutableCryptoStream(client->session())) + ->EarlyDataAccepted() && + zero_rtt_attempt && client->latest_response_code() != -1) { + InsertFeature(Feature::kZeroRtt); + } } void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr, @@ -200,25 +229,8 @@ } InsertFeature(Feature::kHandshake); - // Construct and send a request. - spdy::SpdyHeaderBlock header_block; - header_block[":method"] = "GET"; - header_block[":scheme"] = "https"; - header_block[":authority"] = authority; - header_block[":path"] = "/"; - client->set_store_response(true); - client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true); - - client_stats = connection->GetStats(); - QuicSentPacketManager* sent_packet_manager = - test::QuicConnectionPeer::GetSentPacketManager(connection); - const bool received_forward_secure_ack = - sent_packet_manager != nullptr && - sent_packet_manager->GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE) - .IsInitialized(); - if (client_stats.stream_bytes_received > 0 && received_forward_secure_ack) { - InsertFeature(Feature::kStreamData); - } + spdy::SpdyHeaderBlock header_block = ConstructHeaderBlock(authority); + SendRequest(client.get(), header_block); if (!client->connected()) { return; @@ -259,7 +271,41 @@ InsertFeature(Feature::kConnectionClose); } - AttemptResumption(client.get()); + AttemptResumption(client.get(), authority); +} + +spdy::SpdyHeaderBlock QuicClientInteropRunner::ConstructHeaderBlock( + const std::string& authority) { + // Construct and send a request. + spdy::SpdyHeaderBlock header_block; + header_block[":method"] = "GET"; + header_block[":scheme"] = "https"; + header_block[":authority"] = authority; + header_block[":path"] = "/"; + return header_block; +} + +void QuicClientInteropRunner::SendRequest( + QuicClient* client, + const spdy::SpdyHeaderBlock& header_block) { + client->set_store_response(true); + client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true); + + QuicConnection* connection = client->session()->connection(); + if (connection == nullptr) { + QUIC_LOG(ERROR) << "No QuicConnection object"; + return; + } + QuicConnectionStats client_stats = connection->GetStats(); + QuicSentPacketManager* sent_packet_manager = + test::QuicConnectionPeer::GetSentPacketManager(connection); + const bool received_forward_secure_ack = + sent_packet_manager != nullptr && + sent_packet_manager->GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE) + .IsInitialized(); + if (client_stats.stream_bytes_received > 0 && received_forward_secure_ack) { + InsertFeature(Feature::kStreamData); + } } std::set<Feature> ServerSupport(std::string dns_host,