Allow QuicClientBase to use a fixed server connection id. Remove similar functionality from quic::test::MockableQuicClient.

Add flag --server_connection_id to quic_client to use a fixed server connection id.

PiperOrigin-RevId: 483763340
diff --git a/quiche/quic/core/http/end_to_end_test.cc b/quiche/quic/core/http/end_to_end_test.cc
index 3fc79a9..d9bed33 100644
--- a/quiche/quic/core/http/end_to_end_test.cc
+++ b/quiche/quic/core/http/end_to_end_test.cc
@@ -266,8 +266,13 @@
     if (!pre_shared_key_client_.empty()) {
       client->client()->SetPreSharedKey(pre_shared_key_client_);
     }
-    client->UseConnectionIdLength(override_server_connection_id_length_);
-    client->UseClientConnectionIdLength(override_client_connection_id_length_);
+    if (override_server_connection_id_length_ >= 0) {
+      client->UseConnectionIdLength(override_server_connection_id_length_);
+    }
+    if (override_client_connection_id_length_ >= 0) {
+      client->UseClientConnectionIdLength(
+          override_client_connection_id_length_);
+    }
     client->client()->set_connection_debug_visitor(connection_debug_visitor_);
     client->client()->set_enable_web_transport(enable_web_transport_);
     client->Connect();
diff --git a/quiche/quic/test_tools/quic_test_client.cc b/quiche/quic/test_tools/quic_test_client.cc
index 2d6de0d..f711036 100644
--- a/quiche/quic/test_tools/quic_test_client.cc
+++ b/quiche/quic/test_tools/quic_test_client.cc
@@ -217,8 +217,6 @@
                                                                    this),
           std::make_unique<RecordingProofVerifier>(std::move(proof_verifier)),
           std::move(session_cache)),
-      override_server_connection_id_(EmptyQuicConnectionId()),
-      server_connection_id_overridden_(false),
       override_client_connection_id_(EmptyQuicConnectionId()),
       client_connection_id_overridden_(false) {}
 
@@ -240,28 +238,6 @@
       default_network_helper());
 }
 
-QuicConnectionId MockableQuicClient::GenerateNewConnectionId() {
-  if (server_connection_id_overridden_) {
-    return override_server_connection_id_;
-  }
-  if (override_server_connection_id_length_ >= 0) {
-    return QuicUtils::CreateRandomConnectionId(
-        override_server_connection_id_length_);
-  }
-  return QuicDefaultClient::GenerateNewConnectionId();
-}
-
-void MockableQuicClient::UseConnectionId(
-    QuicConnectionId server_connection_id) {
-  server_connection_id_overridden_ = true;
-  override_server_connection_id_ = server_connection_id;
-}
-
-void MockableQuicClient::UseConnectionIdLength(
-    int server_connection_id_length) {
-  override_server_connection_id_length_ = server_connection_id_length;
-}
-
 QuicConnectionId MockableQuicClient::GetClientConnectionId() {
   if (client_connection_id_overridden_) {
     return override_client_connection_id_;
@@ -791,12 +767,13 @@
 
 void QuicTestClient::UseConnectionId(QuicConnectionId server_connection_id) {
   QUICHE_DCHECK(!connected());
-  client_->UseConnectionId(server_connection_id);
+  client_->set_server_connection_id_override(server_connection_id);
 }
 
-void QuicTestClient::UseConnectionIdLength(int server_connection_id_length) {
+void QuicTestClient::UseConnectionIdLength(
+    uint8_t server_connection_id_length) {
   QUICHE_DCHECK(!connected());
-  client_->UseConnectionIdLength(server_connection_id_length);
+  client_->set_server_connection_id_length(server_connection_id_length);
 }
 
 void QuicTestClient::UseClientConnectionId(
@@ -806,7 +783,7 @@
 }
 
 void QuicTestClient::UseClientConnectionIdLength(
-    int client_connection_id_length) {
+    uint8_t client_connection_id_length) {
   QUICHE_DCHECK(!connected());
   client_->UseClientConnectionIdLength(client_connection_id_length);
 }
diff --git a/quiche/quic/test_tools/quic_test_client.h b/quiche/quic/test_tools/quic_test_client.h
index a1f7b13..4756e99 100644
--- a/quiche/quic/test_tools/quic_test_client.h
+++ b/quiche/quic/test_tools/quic_test_client.h
@@ -59,9 +59,6 @@
 
   ~MockableQuicClient() override;
 
-  QuicConnectionId GenerateNewConnectionId() override;
-  void UseConnectionId(QuicConnectionId server_connection_id);
-  void UseConnectionIdLength(int server_connection_id_length);
   QuicConnectionId GetClientConnectionId() override;
   void UseClientConnectionId(QuicConnectionId client_connection_id);
   void UseClientConnectionIdLength(int client_connection_id_length);
@@ -78,11 +75,8 @@
   const MockableQuicClientDefaultNetworkHelper* mockable_network_helper() const;
 
  private:
-  // Server connection ID to use, if server_connection_id_overridden_
-  QuicConnectionId override_server_connection_id_;
-  bool server_connection_id_overridden_;
-  int override_server_connection_id_length_ = -1;
-  // Client connection ID to use, if client_connection_id_overridden_
+  // Client connection ID to use, if client_connection_id_overridden_.
+  // TODO(wub): Move client_connection_id_(length_) overrides to QuicClientBase.
   QuicConnectionId override_client_connection_id_;
   bool client_connection_id_overridden_;
   int override_client_connection_id_length_ = -1;
@@ -248,13 +242,13 @@
   void UseConnectionId(QuicConnectionId server_connection_id);
   // Configures client_ to use a specific server connection ID length instead
   // of the default of kQuicDefaultConnectionIdLength.
-  void UseConnectionIdLength(int server_connection_id_length);
+  void UseConnectionIdLength(uint8_t server_connection_id_length);
   // Configures client_ to use a specific client connection ID instead of an
   // empty one.
   void UseClientConnectionId(QuicConnectionId client_connection_id);
   // Configures client_ to use a specific client connection ID length instead
   // of the default of zero.
-  void UseClientConnectionIdLength(int client_connection_id_length);
+  void UseClientConnectionIdLength(uint8_t client_connection_id_length);
 
   // Returns nullptr if the maximum number of streams have already been created.
   QuicSpdyClientStream* GetOrCreateStream();
diff --git a/quiche/quic/tools/quic_client_base.cc b/quiche/quic/tools/quic_client_base.cc
index 9277913..948707a 100644
--- a/quiche/quic/tools/quic_client_base.cc
+++ b/quiche/quic/tools/quic_client_base.cc
@@ -410,6 +410,9 @@
 }
 
 QuicConnectionId QuicClientBase::GetNextConnectionId() {
+  if (server_connection_id_override_.has_value()) {
+    return *server_connection_id_override_;
+  }
   return GenerateNewConnectionId();
 }
 
diff --git a/quiche/quic/tools/quic_client_base.h b/quiche/quic/tools/quic_client_base.h
index d36eba6..ac29482 100644
--- a/quiche/quic/tools/quic_client_base.h
+++ b/quiche/quic/tools/quic_client_base.h
@@ -19,6 +19,7 @@
 #include "quiche/quic/core/http/quic_spdy_client_session.h"
 #include "quiche/quic/core/http/quic_spdy_client_stream.h"
 #include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_connection_id.h"
 #include "quiche/quic/platform/api/quic_socket_address.h"
 
 namespace quic {
@@ -278,6 +279,11 @@
 
   std::string interface_name() { return interface_name_; }
 
+  void set_server_connection_id_override(
+      const QuicConnectionId& connection_id) {
+    server_connection_id_override_ = connection_id;
+  }
+
   void set_server_connection_id_length(uint8_t server_connection_id_length) {
     server_connection_id_length_ = server_connection_id_length;
   }
@@ -424,6 +430,11 @@
   // Not owned, must be valid for the lifetime of the QuicClientBase instance.
   QuicConnectionDebugVisitor* connection_debug_visitor_;
 
+  // If set,
+  // - GetNextConnectionId will use this as the next server connection id.
+  // - GenerateNewConnectionId will not be called.
+  absl::optional<QuicConnectionId> server_connection_id_override_;
+
   // GenerateNewConnectionId creates a random connection ID of this length.
   // Defaults to 8.
   uint8_t server_connection_id_length_;
diff --git a/quiche/quic/tools/quic_toy_client.cc b/quiche/quic/tools/quic_toy_client.cc
index 1c7cdaf..10ca52a 100644
--- a/quiche/quic/tools/quic_toy_client.cc
+++ b/quiche/quic/tools/quic_toy_client.cc
@@ -173,8 +173,16 @@
                                 "If true, close the connection after each "
                                 "request. This allows testing 0-RTT.");
 
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, server_connection_id_length, -1,
-                                "Length of the server connection ID used.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    std::string, server_connection_id, "",
+    "If non-empty, the client will use the given server connection id for all "
+    "connections. The flag value is the hex-string of the on-wire connection id"
+    " bytes, e.g. '--server_connection_id=0123456789abcdef'.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    int32_t, server_connection_id_length, -1,
+    "Length of the server connection ID used. This flag has no effects if "
+    "--server_connection_id is non-empty.");
 
 DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, client_connection_id_length, -1,
                                 "Length of the client connection ID used.");
@@ -355,6 +363,17 @@
       initial_mtu != 0 ? initial_mtu : quic::kDefaultMaxPacketSize);
   client->set_drop_response_body(
       quiche::GetQuicheCommandLineFlag(FLAGS_drop_response_body));
+  const std::string server_connection_id_hex_string =
+      quiche::GetQuicheCommandLineFlag(FLAGS_server_connection_id);
+  QUICHE_CHECK(server_connection_id_hex_string.size() % 2 == 0)
+      << "The length of --server_connection_id must be even. It is "
+      << server_connection_id_hex_string.size() << "-byte long.";
+  if (!server_connection_id_hex_string.empty()) {
+    const std::string server_connection_id_bytes =
+        absl::HexStringToBytes(server_connection_id_hex_string);
+    client->set_server_connection_id_override(QuicConnectionId(
+        server_connection_id_bytes.data(), server_connection_id_bytes.size()));
+  }
   const int32_t server_connection_id_length =
       quiche::GetQuicheCommandLineFlag(FLAGS_server_connection_id_length);
   if (server_connection_id_length >= 0) {