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,