Repository: envoyproxy/envoy
File: source/common/quic/envoy_quic_client_session.cc (C++)

Code before:
      manager.max_outgoing_bidirectional_streams() - manager.outgoing_bidirectional_stream_count();
  return streams_available;
}

void EnvoyQuicClientSession::OnTlsHandshakeComplete() {
  quic::QuicSpdyClientSession::OnTlsHandshakeComplete();

  // Fake this to make sure we set the connection pool stream limit correctly
  // before use. This may result in OnCanCreateNewOutgoingStream with zero
  // available streams.
  OnCanCreateNewOutgoingStream(false);
  streamInfo().upstreamInfo()->upstreamTiming().onUpstreamConnectComplete(dispatcher_.timeSource());
  streamInfo().upstreamInfo()->upstreamTiming().onUpstreamHandshakeComplete(
      dispatcher_.timeSource());

  raiseConnectionEvent(Network::ConnectionEvent::Connected);
}

std::unique_ptr<quic::QuicCryptoClientStreamBase> EnvoyQuicClientSession::CreateQuicCryptoStream() {
  return crypto_stream_factory_.createEnvoyQuicCryptoClientStream(
      server_id(), this,
      std::make_unique<EnvoyQuicProofVerifyContextImpl>(
          dispatcher_, /*is_server=*/false, transport_socket_options_, *quic_ssl_info_,
          std::make_unique<CertValidationContext>(
              *this, network_connection_->connectionSocket()->ioHandle())),
      crypto_config(), this, /*has_application_state = */ true);
}

void EnvoyQuicClientSession::setHttp3Options(
    const envoy::config::core::v3::Http3ProtocolOptions& http3_options) {
  QuicFilterManagerConnectionImpl::setHttp3Options(http3_options);
  if (http3_options_->disable_qpack()) {
    DisableHuffmanEncoding();
    DisableCookieCrumbling();
    set_qpack_maximum_dynamic_table_capacity(0);
  }
  if (!http3_options_->has_quic_protocol_options()) {
    return;
  }
  static_cast<EnvoyQuicClientConnection*>(connection())
      ->setNumPtosForPortMigration(PROTOBUF_GET_WRAPPED_OR_DEFAULT(
          http3_options.quic_protocol_options(), num_timeouts_to_trigger_port_migration, 0));

  if (http3_options_->quic_protocol_options().has_connection_keepalive()) {
    const uint64_t initial_interval = PROTOBUF_GET_MS_OR_DEFAULT(
        http3_options_->quic_protocol_options().connection_keepalive(), initial_interval, 0);
    const uint64_t max_interval =
        PROTOBUF_GET_MS_OR_DEFAULT(http3_options_->quic_protocol_options().connection_keepalive(),
                                   max_interval, quic::kPingTimeoutSecs);
    // If the keepalive max_interval is configured to zero, disable the probe completely.
    if (max_interval == 0u) {

Review comment (refactor):
If `has_application_state` is always true, can we remove this argument completely?

Code after:
      manager.max_outgoing_bidirectional_streams() - manager.outgoing_bidirectional_stream_count();
  return streams_available;
}

void EnvoyQuicClientSession::OnTlsHandshakeComplete() {
  quic::QuicSpdyClientSession::OnTlsHandshakeComplete();

  // Fake this to make sure we set the connection pool stream limit correctly
  // before use. This may result in OnCanCreateNewOutgoingStream with zero
  // available streams.
  OnCanCreateNewOutgoingStream(false);
  streamInfo().upstreamInfo()->upstreamTiming().onUpstreamConnectComplete(dispatcher_.timeSource());
  streamInfo().upstreamInfo()->upstreamTiming().onUpstreamHandshakeComplete(
      dispatcher_.timeSource());

  raiseConnectionEvent(Network::ConnectionEvent::Connected);
}

std::unique_ptr<quic::QuicCryptoClientStreamBase> EnvoyQuicClientSession::CreateQuicCryptoStream() {
  return crypto_stream_factory_.createEnvoyQuicCryptoClientStream(
      server_id(), this,
      std::make_unique<EnvoyQuicProofVerifyContextImpl>(
          dispatcher_, /*is_server=*/false, transport_socket_options_, *quic_ssl_info_,
          std::make_unique<CertValidationContext>(
              *this, network_connection_->connectionSocket()->ioHandle())),
      crypto_config(), this);
}

void EnvoyQuicClientSession::setHttp3Options(
    const envoy::config::core::v3::Http3ProtocolOptions& http3_options) {
  QuicFilterManagerConnectionImpl::setHttp3Options(http3_options);
  if (http3_options_->disable_qpack()) {
    DisableHuffmanEncoding();
    DisableCookieCrumbling();
    set_qpack_maximum_dynamic_table_capacity(0);
  }
  if (!http3_options_->has_quic_protocol_options()) {
    return;
  }
  static_cast<EnvoyQuicClientConnection*>(connection())
      ->setNumPtosForPortMigration(PROTOBUF_GET_WRAPPED_OR_DEFAULT(
          http3_options.quic_protocol_options(), num_timeouts_to_trigger_port_migration, 0));

  if (http3_options_->quic_protocol_options().has_connection_keepalive()) {
    const uint64_t initial_interval = PROTOBUF_GET_MS_OR_DEFAULT(
        http3_options_->quic_protocol_options().connection_keepalive(), initial_interval, 0);
    const uint64_t max_interval =
        PROTOBUF_GET_MS_OR_DEFAULT(http3_options_->quic_protocol_options().connection_keepalive(),
                                   max_interval, quic::kPingTimeoutSecs);
    // If the keepalive max_interval is configured to zero, disable the probe completely.
    if (max_interval == 0u) {