Support resumption in quic_client_interop_test_bin

gfe-relnote: n/a (quic tools only change)
PiperOrigin-RevId: 279826630
Change-Id: I0f36d9b70c84ab1470b4cc09db267f1f03ae1a8a
diff --git a/quic/qbone/qbone_client.cc b/quic/qbone/qbone_client.cc
index e585d05..95e3aea 100644
--- a/quic/qbone/qbone_client.cc
+++ b/quic/qbone/qbone_client.cc
@@ -40,7 +40,8 @@
           new QuicEpollConnectionHelper(epoll_server, QuicAllocator::SIMPLE),
           new QuicEpollAlarmFactory(epoll_server),
           CreateNetworkHelper(epoll_server, this),
-          std::move(proof_verifier)),
+          std::move(proof_verifier),
+          nullptr),
       qbone_writer_(qbone_writer),
       qbone_handler_(qbone_handler),
       session_owner_(session_owner) {
diff --git a/quic/tools/quic_client.cc b/quic/tools/quic_client.cc
index cccb7ba..379cfac 100644
--- a/quic/tools/quic_client.cc
+++ b/quic/tools/quic_client.cc
@@ -70,7 +70,24 @@
           QuicConfig(),
           epoll_server,
           QuicWrapUnique(new QuicClientEpollNetworkHelper(epoll_server, this)),
-          std::move(proof_verifier)) {}
+          std::move(proof_verifier),
+          nullptr) {}
+
+QuicClient::QuicClient(QuicSocketAddress server_address,
+                       const QuicServerId& server_id,
+                       const ParsedQuicVersionVector& supported_versions,
+                       QuicEpollServer* epoll_server,
+                       std::unique_ptr<ProofVerifier> proof_verifier,
+                       std::unique_ptr<SessionCache> session_cache)
+    : QuicClient(
+          server_address,
+          server_id,
+          supported_versions,
+          QuicConfig(),
+          epoll_server,
+          QuicWrapUnique(new QuicClientEpollNetworkHelper(epoll_server, this)),
+          std::move(proof_verifier),
+          std::move(session_cache)) {}
 
 QuicClient::QuicClient(
     QuicSocketAddress server_address,
@@ -85,7 +102,8 @@
                  QuicConfig(),
                  epoll_server,
                  std::move(network_helper),
-                 std::move(proof_verifier)) {}
+                 std::move(proof_verifier),
+                 nullptr) {}
 
 QuicClient::QuicClient(
     QuicSocketAddress server_address,
@@ -95,6 +113,24 @@
     QuicEpollServer* epoll_server,
     std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
     std::unique_ptr<ProofVerifier> proof_verifier)
+    : QuicClient(server_address,
+                 server_id,
+                 supported_versions,
+                 config,
+                 epoll_server,
+                 std::move(network_helper),
+                 std::move(proof_verifier),
+                 nullptr) {}
+
+QuicClient::QuicClient(
+    QuicSocketAddress server_address,
+    const QuicServerId& server_id,
+    const ParsedQuicVersionVector& supported_versions,
+    const QuicConfig& config,
+    QuicEpollServer* epoll_server,
+    std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
+    std::unique_ptr<ProofVerifier> proof_verifier,
+    std::unique_ptr<SessionCache> session_cache)
     : QuicSpdyClientBase(
           server_id,
           supported_versions,
@@ -102,7 +138,8 @@
           new QuicEpollConnectionHelper(epoll_server, QuicAllocator::SIMPLE),
           new QuicEpollAlarmFactory(epoll_server),
           std::move(network_helper),
-          std::move(proof_verifier)) {
+          std::move(proof_verifier),
+          std::move(session_cache)) {
   set_server_address(server_address);
 }
 
diff --git a/quic/tools/quic_client.h b/quic/tools/quic_client.h
index 8e43be8..10c61f3 100644
--- a/quic/tools/quic_client.h
+++ b/quic/tools/quic_client.h
@@ -37,12 +37,18 @@
 
 class QuicClient : public QuicSpdyClientBase {
  public:
-  // This will create its own QuicClientEpollNetworkHelper.
+  // These will create their own QuicClientEpollNetworkHelper.
   QuicClient(QuicSocketAddress server_address,
              const QuicServerId& server_id,
              const ParsedQuicVersionVector& supported_versions,
              QuicEpollServer* epoll_server,
              std::unique_ptr<ProofVerifier> proof_verifier);
+  QuicClient(QuicSocketAddress server_address,
+             const QuicServerId& server_id,
+             const ParsedQuicVersionVector& supported_versions,
+             QuicEpollServer* epoll_server,
+             std::unique_ptr<ProofVerifier> proof_verifier,
+             std::unique_ptr<SessionCache> session_cache);
   // This will take ownership of a passed in network primitive.
   QuicClient(QuicSocketAddress server_address,
              const QuicServerId& server_id,
@@ -57,6 +63,14 @@
              QuicEpollServer* epoll_server,
              std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
              std::unique_ptr<ProofVerifier> proof_verifier);
+  QuicClient(QuicSocketAddress server_address,
+             const QuicServerId& server_id,
+             const ParsedQuicVersionVector& supported_versions,
+             const QuicConfig& config,
+             QuicEpollServer* epoll_server,
+             std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
+             std::unique_ptr<ProofVerifier> proof_verifier,
+             std::unique_ptr<SessionCache> session_cache);
   QuicClient(const QuicClient&) = delete;
   QuicClient& operator=(const QuicClient&) = delete;
 
diff --git a/quic/tools/quic_client_base.cc b/quic/tools/quic_client_base.cc
index b03f7cc..b6c3375 100644
--- a/quic/tools/quic_client_base.cc
+++ b/quic/tools/quic_client_base.cc
@@ -23,12 +23,13 @@
     QuicConnectionHelperInterface* helper,
     QuicAlarmFactory* alarm_factory,
     std::unique_ptr<NetworkHelper> network_helper,
-    std::unique_ptr<ProofVerifier> proof_verifier)
+    std::unique_ptr<ProofVerifier> proof_verifier,
+    std::unique_ptr<SessionCache> session_cache)
     : server_id_(server_id),
       initialized_(false),
       local_port_(0),
       config_(config),
-      crypto_config_(std::move(proof_verifier)),
+      crypto_config_(std::move(proof_verifier), std::move(session_cache)),
       helper_(helper),
       alarm_factory_(alarm_factory),
       supported_versions_(supported_versions),
diff --git a/quic/tools/quic_client_base.h b/quic/tools/quic_client_base.h
index fb15b86..8cb639b 100644
--- a/quic/tools/quic_client_base.h
+++ b/quic/tools/quic_client_base.h
@@ -23,6 +23,7 @@
 
 class ProofVerifier;
 class QuicServerId;
+class SessionCache;
 
 // QuicClientBase handles establishing a connection to the passed in
 // server id, including ensuring that it supports the passed in versions
@@ -64,7 +65,8 @@
                  QuicConnectionHelperInterface* helper,
                  QuicAlarmFactory* alarm_factory,
                  std::unique_ptr<NetworkHelper> network_helper,
-                 std::unique_ptr<ProofVerifier> proof_verifier);
+                 std::unique_ptr<ProofVerifier> proof_verifier,
+                 std::unique_ptr<SessionCache> session_cache);
   QuicClientBase(const QuicClientBase&) = delete;
   QuicClientBase& operator=(const QuicClientBase&) = delete;
 
diff --git a/quic/tools/quic_client_interop_test_bin.cc b/quic/tools/quic_client_interop_test_bin.cc
index be65979..47d87a5 100644
--- a/quic/tools/quic_client_interop_test_bin.cc
+++ b/quic/tools/quic_client_interop_test_bin.cc
@@ -13,6 +13,8 @@
 #include "net/third_party/quiche/src/quic/platform/api/quic_system_event_loop.h"
 #include "net/quic/platform/impl/quic_epoll_clock.h"
 #include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/simple_session_cache.h"
 #include "net/third_party/quiche/src/quic/tools/fake_proof_verifier.h"
 #include "net/third_party/quiche/src/quic/tools/quic_client.h"
 #include "net/third_party/quiche/src/quic/tools/quic_url.h"
@@ -36,6 +38,8 @@
   kStreamData,
   // The connection close procedcure completes with a zero error code.
   kConnectionClose,
+  // The connection was established using TLS resumption.
+  kResumption,
   // A RETRY packet was successfully processed.
   kRetry,
 
@@ -58,12 +62,33 @@
       return 'D';
     case Feature::kConnectionClose:
       return 'C';
-    case Feature::kHttp3:
-      return '3';
+    case Feature::kResumption:
+      return 'R';
     case Feature::kRetry:
       return 'S';
     case Feature::kRebinding:
       return 'B';
+    case Feature::kHttp3:
+      return '3';
+  }
+}
+
+// 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, std::set<Feature>* features) {
+  client->Disconnect();
+  if (!client->Initialize()) {
+    QUIC_LOG(ERROR) << "Failed to reinitialize client";
+    return;
+  }
+  if (!client->Connect() || !client->session()->IsCryptoHandshakeConfirmed()) {
+    return;
+  }
+  if (static_cast<QuicCryptoClientStream*>(
+          test::QuicSessionPeer::GetMutableCryptoStream(client->session()))
+          ->IsResumption()) {
+    features->insert(Feature::kResumption);
   }
 }
 
@@ -80,10 +105,12 @@
 
   std::set<Feature> features;
   auto proof_verifier = std::make_unique<FakeProofVerifier>();
+  auto session_cache = std::make_unique<test::SimpleSessionCache>();
   QuicEpollServer epoll_server;
   QuicEpollClock epoll_clock(&epoll_server);
   auto client = std::make_unique<QuicClient>(
-      addr, server_id, versions, &epoll_server, std::move(proof_verifier));
+      addr, server_id, versions, &epoll_server, std::move(proof_verifier),
+      std::move(session_cache));
   if (!client->Initialize()) {
     QUIC_LOG(ERROR) << "Failed to initialize client";
     return features;
@@ -188,6 +215,7 @@
       client->epoll_network_helper()->RunEventLoop();
       if (epoll_clock.Now() - close_start_time >= close_timeout) {
         QUIC_LOG(ERROR) << "Timed out waiting for connection close";
+        AttemptResumption(client.get(), &features);
         return features;
       }
     }
@@ -201,6 +229,7 @@
     }
   }
 
+  AttemptResumption(client.get(), &features);
   return features;
 }
 
diff --git a/quic/tools/quic_spdy_client_base.cc b/quic/tools/quic_spdy_client_base.cc
index 3cd4cbd..6b4cc8d 100644
--- a/quic/tools/quic_spdy_client_base.cc
+++ b/quic/tools/quic_spdy_client_base.cc
@@ -37,14 +37,16 @@
     QuicConnectionHelperInterface* helper,
     QuicAlarmFactory* alarm_factory,
     std::unique_ptr<NetworkHelper> network_helper,
-    std::unique_ptr<ProofVerifier> proof_verifier)
+    std::unique_ptr<ProofVerifier> proof_verifier,
+    std::unique_ptr<SessionCache> session_cache)
     : QuicClientBase(server_id,
                      supported_versions,
                      config,
                      helper,
                      alarm_factory,
                      std::move(network_helper),
-                     std::move(proof_verifier)),
+                     std::move(proof_verifier),
+                     std::move(session_cache)),
       store_response_(false),
       latest_response_code_(-1),
       max_allowed_push_id_(0),
diff --git a/quic/tools/quic_spdy_client_base.h b/quic/tools/quic_spdy_client_base.h
index 2a1267f..d953038 100644
--- a/quic/tools/quic_spdy_client_base.h
+++ b/quic/tools/quic_spdy_client_base.h
@@ -23,6 +23,7 @@
 
 class ProofVerifier;
 class QuicServerId;
+class SessionCache;
 
 class QuicSpdyClientBase : public QuicClientBase,
                            public QuicClientPushPromiseIndex::Delegate,
@@ -69,7 +70,8 @@
                      QuicConnectionHelperInterface* helper,
                      QuicAlarmFactory* alarm_factory,
                      std::unique_ptr<NetworkHelper> network_helper,
-                     std::unique_ptr<ProofVerifier> proof_verifier);
+                     std::unique_ptr<ProofVerifier> proof_verifier,
+                     std::unique_ptr<SessionCache> session_cache);
   QuicSpdyClientBase(const QuicSpdyClientBase&) = delete;
   QuicSpdyClientBase& operator=(const QuicSpdyClientBase&) = delete;