Repository: envoyproxy/envoy
File: mobile/library/cc/engine_builder.cc (C++)

Code before:
    envoy::extensions::transport_sockets::quic::v3::QuicUpstreamTransport h3_inner_socket;
    tls_socket.mutable_common_tls_context()->mutable_alpn_protocols()->Clear();
    h3_inner_socket.mutable_upstream_tls_context()->CopyFrom(tls_socket);
    envoy::extensions::transport_sockets::http_11_proxy::v3::Http11ProxyUpstreamTransport
        h3_proxy_socket;
    h3_proxy_socket.mutable_transport_socket()->mutable_typed_config()->PackFrom(h3_inner_socket);
    h3_proxy_socket.mutable_transport_socket()->set_name("envoy.transport_sockets.quic");

    auto* quic_protocol_options = alpn_options.mutable_auto_config()
                                      ->mutable_http3_protocol_options()
                                      ->mutable_quic_protocol_options();
    if (!quic_connection_options_.empty()) {
      quic_protocol_options->set_connection_options(absl::StrJoin(quic_connection_options_, ","));
    } else {
      quic_protocol_options->set_connection_options(http3_connection_options_);
      quic_protocol_options->set_client_connection_options(http3_client_connection_options_);
    }
    quic_protocol_options->mutable_initial_stream_window_size()->set_value(
        initial_stream_window_size_);
    quic_protocol_options->mutable_initial_connection_window_size()->set_value(
        initial_connection_window_size_);
    quic_protocol_options->mutable_idle_network_timeout()->set_seconds(
        quic_connection_idle_timeout_seconds_);
    if (num_timeouts_to_trigger_port_migration_ > 0) {
      quic_protocol_options->mutable_num_timeouts_to_trigger_port_migration()->set_value(
          num_timeouts_to_trigger_port_migration_);
    }
    if (keepalive_initial_interval_ms_ > 0) {
      quic_protocol_options->mutable_connection_keepalive()->mutable_initial_interval()->set_nanos(
          keepalive_initial_interval_ms_ * 1000 * 1000);
    }
    if (max_concurrent_streams_ > 0) {
      quic_protocol_options->mutable_max_concurrent_streams()->set_value(max_concurrent_streams_);
    }

    alpn_options.mutable_auto_config()->mutable_alternate_protocols_cache_options()->set_name(
        "default_alternate_protocols_cache");
    for (const auto& [host, port] : quic_hints_) {
      auto* entry = alpn_options.mutable_auto_config()
                        ->mutable_alternate_protocols_cache_options()
                        ->add_prepopulated_entries();
      entry->set_hostname(host);
      entry->set_port(port);
    }
    for (const auto& suffix : quic_suffixes_) {
      alpn_options.mutable_auto_config()
          ->mutable_alternate_protocols_cache_options()
          ->add_canonical_suffixes(suffix);
    }

    base_cluster->mutable_transport_socket()->mutable_typed_config()->PackFrom(h3_proxy_socket);

Review comment (suggestion):
OOC, are we intentionally getting rid of client connection options? I believe we use both in QUICHE.

Code after:
  tls_socket.mutable_common_tls_context()->add_alpn_protocols("h2");
  ssl_proxy_socket.mutable_transport_socket()->mutable_typed_config()->PackFrom(tls_socket);

  // Edit base cluster to be an HTTP/3 cluster.
  if (enable_http3_) {
    envoy::extensions::transport_sockets::quic::v3::QuicUpstreamTransport h3_inner_socket;
    tls_socket.mutable_common_tls_context()->mutable_alpn_protocols()->Clear();
    h3_inner_socket.mutable_upstream_tls_context()->CopyFrom(tls_socket);
    envoy::extensions::transport_sockets::http_11_proxy::v3::Http11ProxyUpstreamTransport
        h3_proxy_socket;
    h3_proxy_socket.mutable_transport_socket()->mutable_typed_config()->PackFrom(h3_inner_socket);
    h3_proxy_socket.mutable_transport_socket()->set_name("envoy.transport_sockets.quic");

    auto* quic_protocol_options = alpn_options.mutable_auto_config()
                                      ->mutable_http3_protocol_options()
                                      ->mutable_quic_protocol_options();
    if (!quic_connection_options_.empty()) {
      quic_protocol_options->set_connection_options(absl::StrJoin(quic_connection_options_, ","));
    } else {
      quic_protocol_options->set_connection_options(http3_connection_options_);
    }
    if (!quic_client_connection_options_.empty()) {
      quic_protocol_options->set_client_connection_options(
          absl::StrJoin(quic_client_connection_options_, ","));
    } else {
      quic_protocol_options->set_client_connection_options(http3_client_connection_options_);
    }
    quic_protocol_options->set_client_connection_options(http3_client_connection_options_);
    quic_protocol_options->mutable_initial_stream_window_size()->set_value(
        initial_stream_window_size_);
    quic_protocol_options->mutable_initial_connection_window_size()->set_value(
        initial_connection_window_size_);
    quic_protocol_options->mutable_idle_network_timeout()->set_seconds(
        quic_connection_idle_timeout_seconds_);
    if (num_timeouts_to_trigger_port_migration_ > 0) {
      quic_protocol_options->mutable_num_timeouts_to_trigger_port_migration()->set_value(
          num_timeouts_to_trigger_port_migration_);
    }
    if (keepalive_initial_interval_ms_ > 0) {
      quic_protocol_options->mutable_connection_keepalive()->mutable_initial_interval()->set_nanos(
          keepalive_initial_interval_ms_ * 1000 * 1000);
    }
    if (max_concurrent_streams_ > 0) {
      quic_protocol_options->mutable_max_concurrent_streams()->set_value(max_concurrent_streams_);
    }

    alpn_options.mutable_auto_config()->mutable_alternate_protocols_cache_options()->set_name(
        "default_alternate_protocols_cache");
    for (const auto& [host, port] : quic_hints_) {
      auto* entry = alpn_options.mutable_auto_config()
                        ->mutable_alternate_protocols_cache_options()