Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

quiche: use max header size configured in HCM #15912

Merged
merged 66 commits into from
Apr 29, 2021
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
bb02ae6
enable protocol integration test
danzh1989 Mar 9, 2021
09fc660
visibility
danzh1989 Mar 9, 2021
6ed3c94
make protocol test pass
danzh1989 Mar 10, 2021
186a69d
add more test
danzh1989 Mar 11, 2021
66dbde0
quic_pause_filter
danzh1989 Mar 11, 2021
d5cbd00
address comments
danzh1989 Mar 13, 2021
cf08311
fix const reference
danzh1989 Mar 15, 2021
97a3033
Merge branch 'master' into addprotointegrationtest
danzh1989 Mar 15, 2021
e00fd2b
Merge branch 'master' into addprotointegrationtest
danzh1989 Mar 16, 2021
5682791
fix in filters
danzh1989 Mar 16, 2021
96c587e
Merge branch 'master' into addprotointegrationtest
danzh1989 Mar 16, 2021
725d93e
stop using udp_listener_name
danzh1989 Mar 16, 2021
354a322
fix IPv6 test failure
danzh1989 Mar 17, 2021
2b94626
fix setSan
danzh1989 Mar 17, 2021
77cb937
fix asan and gcc
danzh1989 Mar 17, 2021
4e9e56a
test size to large
danzh1989 Mar 17, 2021
88398b8
test size to large
danzh1989 Mar 18, 2021
5c11723
move config setup to config helper
danzh1989 Mar 18, 2021
39e3f9a
Merge branch 'master' into addprotointegrationtest
danzh1989 Mar 18, 2021
4c2b490
fix setSan
danzh1989 Mar 19, 2021
97292b2
change send single request
danzh1989 Mar 22, 2021
fdc6189
Merge branch 'master' into addprotointegrationtest
danzh1989 Mar 22, 2021
280fc25
address comments
danzh1989 Mar 22, 2021
3c02978
fix comment
danzh1989 Mar 22, 2021
c31225b
comment about \0
danzh1989 Mar 23, 2021
e1fd5d7
Merge branch 'master' into addprotointegrationtest
danzh1989 Mar 23, 2021
2dd1ae5
fix typo
danzh1989 Mar 23, 2021
60015bf
plumb header size and underscore action
danzh1989 Mar 24, 2021
55da362
Merge branch 'master' into headersize
danzh1989 Mar 24, 2021
71eb14c
fail at QUICHE_CHECK
danzh1989 Mar 24, 2021
4c45c9f
fix filter initialize order
danzh1989 Mar 25, 2021
8da2e26
Merge branch 'master' into headersize
danzh1989 Apr 8, 2021
852a392
protocol test fail
danzh1989 Apr 9, 2021
ec6a58c
test pass
danzh1989 Apr 9, 2021
cf32e9d
close connection during filter initialization
danzh1989 Apr 10, 2021
dd14732
enable upstream test
danzh1989 Apr 10, 2021
8730535
fix format
danzh1989 Apr 11, 2021
f423074
format
danzh1989 Apr 11, 2021
87cd212
use absl::string_view
danzh1989 Apr 12, 2021
6c48a12
fix ClientCodec test
danzh1989 Apr 12, 2021
59322e6
fix asan
danzh1989 Apr 13, 2021
669ef78
remove unused include
danzh1989 Apr 13, 2021
0396a8f
fix clang-tidy
danzh1989 Apr 13, 2021
fecd6ba
split QuicFilterManagerConnection interface
danzh1989 Apr 15, 2021
75e85ce
add client codec connect()
danzh1989 Apr 16, 2021
dbac8ea
Merge branch 'master' into headersize
danzh1989 Apr 16, 2021
1b9a3b2
fix clang-tidy
danzh1989 Apr 16, 2021
836a6e8
reverted misfired replacement
danzh1989 Apr 16, 2021
a8297cb
address comments
danzh1989 Apr 19, 2021
885a7b9
address comments
danzh1989 Apr 23, 2021
7953bc8
Merge branch 'master' into headersize
danzh1989 Apr 23, 2021
95561c4
quic_header_size_limit_includes_overhead default to false
danzh1989 Apr 24, 2021
6eefb38
initialize flag registry
danzh1989 Apr 24, 2021
96aad88
register flags for client side
danzh1989 Apr 24, 2021
f929456
Merge branch 'master' into headersize
danzh1989 Apr 24, 2021
6c38879
NOLINT(namespace-envoy)
danzh1989 Apr 25, 2021
7b29d70
typo
danzh1989 Apr 26, 2021
b6e3ace
connected_called_ NDEBUG
danzh1989 Apr 26, 2021
09aca06
Merge branch 'master' into headersize
danzh1989 Apr 26, 2021
5d77b16
remove DDEBUG
danzh1989 Apr 26, 2021
5d4469a
Merge branch 'master' into headersize
danzh1989 Apr 26, 2021
42c08af
Merge branch 'master' into headersize
danzh1989 Apr 27, 2021
1677acc
remove quic_includes_ignores
danzh1989 Apr 27, 2021
0651906
delay close
danzh1989 Apr 28, 2021
55fd7b3
disable ManyLargeRequestHeadersAccepted
danzh1989 Apr 28, 2021
874a4b0
spell dict
danzh1989 Apr 28, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions source/common/http/codec_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,17 @@ CodecClient::CodecClient(Type type, Network::ClientConnectionPtr&& connection,
connection_->addConnectionCallbacks(*this);
connection_->addReadFilter(Network::ReadFilterSharedPtr{new CodecReadFilter(*this)});

// In general, codecs are handed new not-yet-connected connections, but in the
// case of ALPN, the codec may be handed an already connected connection.
if (!connection_->connecting()) {
ASSERT(connection_->state() == Network::Connection::State::Open);
connected_ = true;
} else {
ENVOY_CONN_LOG(debug, "connecting", *connection_);
connection_->connect();
// Do not start handshake for H3 connection till it is initialized.
if (type_ != Type::HTTP3) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to not special case HTTP/3 here.

How about we add an initialize() or connect() function for the codec client, and do all the work there consistently for H1-H3?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you suggesting a stand alone interface to be called after construction?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I prefer that to H1 and H2 auto-connecting and H3 not doing so. Happy to tag Snow or Matt if you want a second opinion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I prefer that to H1 and H2 auto-connecting and H3 not doing so.
H3 indeed does in CodecCientProd().

I'm okay with making connect() explicit:

CodecClientProd codec;
codec.connect();

@mattklein123 WDYT?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure SGTM!

// In general, codecs are handed new not-yet-connected connections, but in the
// case of ALPN, the codec may be handed an already connected connection.
if (!connection_->connecting()) {
ASSERT(connection_->state() == Network::Connection::State::Open);
connected_ = true;
} else {
ENVOY_CONN_LOG(debug, "connecting", *connection_);
connection_->connect();
}
}

if (idle_timeout_) {
Expand Down Expand Up @@ -185,10 +188,21 @@ CodecClientProd::CodecClientProd(Type type, Network::ClientConnectionPtr&& conne
}
case Type::HTTP3: {
#ifdef ENVOY_ENABLE_QUIC
auto& quic_session = dynamic_cast<Quic::EnvoyQuicClientSession&>(*connection_);
codec_ = std::make_unique<Quic::QuicHttpClientConnectionImpl>(
dynamic_cast<Quic::EnvoyQuicClientSession&>(*connection_), *this,
host->cluster().http3CodecStats(), host->cluster().http3Options(),
quic_session, *this, host->cluster().http3CodecStats(), host->cluster().http3Options(),
Http::DEFAULT_MAX_REQUEST_HEADERS_KB);
// Initialize the session after max request header size is changed in above http client
// connection creation.
quic_session.Initialize();
Comment on lines +197 to +199
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we call quic_session.Initialize in QuicHttpClientConnectionImpl's constructor?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we could. But explicitly call Initialize() is more consistent with QUICHE code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, quic_session has already been created before this function is called, so the initialize is already far away from the constructor. Your call.

// The other two codecs have already connected in base class.
if (!connection_->connecting()) {
ASSERT(connection_->state() == Network::Connection::State::Open);
connected_ = true;
} else {
ENVOY_CONN_LOG(debug, "connecting", *connection_);
connection_->connect();
}
break;
#else
// Should be blocked by configuration checking at an earlier point.
Expand Down
4 changes: 2 additions & 2 deletions source/common/http/codec_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class CodecClientCallbacks {
* This is an HTTP client that multiple stream management and underlying connection management
* across multiple HTTP codec types.
*/
class CodecClient : Logger::Loggable<Logger::Id::client>,
class CodecClient : protected Logger::Loggable<Logger::Id::client>,
public Http::ConnectionCallbacks,
public Network::ConnectionCallbacks,
public Event::DeferredDeletable {
Expand Down Expand Up @@ -177,6 +177,7 @@ class CodecClient : Logger::Loggable<Logger::Id::client>,
ClientConnectionPtr codec_;
Event::TimerPtr idle_timer_;
const absl::optional<std::chrono::milliseconds> idle_timeout_;
bool connected_{};

private:
/**
Expand Down Expand Up @@ -254,7 +255,6 @@ class CodecClient : Logger::Loggable<Logger::Id::client>,
std::list<ActiveRequestPtr> active_requests_;
Http::ConnectionCallbacks* codec_callbacks_{};
CodecClientCallbacks* codec_client_callbacks_{};
bool connected_{};
bool remote_closed_{};
bool protocol_error_{false};
};
Expand Down
2 changes: 2 additions & 0 deletions source/common/quic/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,8 @@ envoy_cc_library(
"//source/common/network:address_lib",
"//source/common/network:listen_socket_lib",
"//source/common/network:socket_option_factory_lib",
"//source/common/quic:quic_io_handle_wrapper_lib",
"//source/extensions/transport_sockets:well_known_names",
"@com_googlesource_quiche//:quic_core_http_header_list_lib",
"@envoy_api//envoy/config/core/v3:pkg_cc_proto",
],
Expand Down
1 change: 1 addition & 0 deletions source/common/quic/active_quic_listener.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ ActiveQuicListener::ActiveQuicListener(
kernel_worker_routing_(kernel_worker_routing) {
// This flag fix a QUICHE issue which may crash Envoy during connection close.
SetQuicReloadableFlag(quic_single_ack_in_packet2, true);
SetQuicFlag(FLAGS_quic_header_size_limit_includes_overhead, false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is going to be permanent right? Let's comment what it does.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this will be permanent to align with nghttp2.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also comment on why the default needs to be true but we need to turn it off here?

If the default(in quic_protocol_flags_list.h) needs to be true, could we turn it off once at envoy startup?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default doesn't needs to be true. It is true just because the upstream QUICHE set so. Envoy can definitely start with this flag being false.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Feel free to address this as a follow up)

The default doesn't needs to be true. It is true just because the upstream QUICHE set so.

In that case, how about change the default to false too.

Envoy can definitely start with this flag being false.

Please make it so.


if (Runtime::LoaderSingleton::getExisting()) {
enabled_.emplace(Runtime::FeatureFlag(enabled, Runtime::LoaderSingleton::get()));
Expand Down
2 changes: 1 addition & 1 deletion source/common/quic/client_connection_factory_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ createQuicNetworkConnection(Http::PersistentQuicInfo& info, Event::Dispatcher& d
info_impl->alarm_factory_, quic::ParsedQuicVersionVector{info_impl->supported_versions_[0]},
local_addr, dispatcher, nullptr);
auto& static_info = StaticInfo::get();
SetQuicFlag(FLAGS_quic_header_size_limit_includes_overhead, false);
auto ret = std::make_unique<EnvoyQuicClientSession>(
static_info.quic_config_, info_impl->supported_versions_, std::move(connection),
info_impl->server_id_, info_impl->crypto_config_.get(), &static_info.push_promise_index_,
dispatcher, 0);
ret->Initialize();
return ret;
}

Expand Down
6 changes: 4 additions & 2 deletions source/common/quic/codec_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ QuicHttpServerConnectionImpl::QuicHttpServerConnectionImpl(
EnvoyQuicServerSession& quic_session, Http::ServerConnectionCallbacks& callbacks,
Http::Http3::CodecStats& stats,
const envoy::config::core::v3::Http3ProtocolOptions& http3_options,
const uint32_t /*max_request_headers_kb*/,
const uint32_t max_request_headers_kb,
envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction
headers_with_underscores_action)
: QuicHttpConnectionImplBase(quic_session, stats), quic_server_session_(quic_session) {
quic_session.setCodecStats(stats);
quic_session.setHttp3Options(http3_options);
quic_session.setHeadersWithUnderscoreAction(headers_with_underscores_action);
quic_session.setHttpConnectionCallbacks(callbacks);
quic_session.set_max_inbound_header_list_size(max_request_headers_kb * 1024u);
}

void QuicHttpServerConnectionImpl::onUnderlyingConnectionAboveWriteBufferHighWatermark() {
Expand Down Expand Up @@ -68,11 +69,12 @@ QuicHttpClientConnectionImpl::QuicHttpClientConnectionImpl(
EnvoyQuicClientSession& session, Http::ConnectionCallbacks& callbacks,
Http::Http3::CodecStats& stats,
const envoy::config::core::v3::Http3ProtocolOptions& http3_options,
const uint32_t /*max_request_headers_kb*/)
const uint32_t max_request_headers_kb)
: QuicHttpConnectionImplBase(session, stats), quic_client_session_(session) {
session.setCodecStats(stats);
session.setHttp3Options(http3_options);
session.setHttpConnectionCallbacks(callbacks);
session.set_max_inbound_header_list_size(max_request_headers_kb * 1024);
}

Http::RequestEncoder&
Expand Down
6 changes: 2 additions & 4 deletions source/common/quic/envoy_quic_client_session.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ EnvoyQuicClientSession::EnvoyQuicClientSession(
: QuicFilterManagerConnectionImpl(*connection, dispatcher, send_buffer_limit),
quic::QuicSpdyClientSession(config, supported_versions, connection.release(), server_id,
crypto_config, push_promise_index),
host_name_(server_id.host()) {
// HTTP/3 header limits should be configurable, but for now hard-code to Envoy defaults.
set_max_inbound_header_list_size(Http::DEFAULT_MAX_REQUEST_HEADERS_KB * 1000);
}
host_name_(server_id.host()) {}

EnvoyQuicClientSession::~EnvoyQuicClientSession() {
ASSERT(!connection()->connected());
Expand All @@ -41,6 +38,7 @@ void EnvoyQuicClientSession::OnConnectionClosed(const quic::QuicConnectionCloseF

void EnvoyQuicClientSession::Initialize() {
quic::QuicSpdyClientSession::Initialize();
initialized_ = true;
quic_connection_->setEnvoyConnection(*this);
}

Expand Down
16 changes: 14 additions & 2 deletions source/common/quic/envoy_quic_dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "common/http/utility.h"
#include "common/quic/envoy_quic_server_connection.h"
#include "common/quic/envoy_quic_server_session.h"
#include "common/quic/envoy_quic_utils.h"

namespace Envoy {
namespace Quic {
Expand Down Expand Up @@ -48,8 +49,8 @@ void EnvoyQuicDispatcher::OnConnectionClosed(quic::QuicConnectionId connection_i

std::unique_ptr<quic::QuicSession> EnvoyQuicDispatcher::CreateQuicSession(
quic::QuicConnectionId server_connection_id, const quic::QuicSocketAddress& self_address,
const quic::QuicSocketAddress& peer_address, absl::string_view /*alpn*/,
const quic::ParsedQuicVersion& version, absl::string_view /*sni*/) {
const quic::QuicSocketAddress& peer_address, absl::string_view alpn,
const quic::ParsedQuicVersion& version, absl::string_view sni) {
quic::QuicConfig quic_config = config();
// TODO(danzh) setup flow control window via config.
quic_config.SetInitialStreamFlowControlWindowToSend(
Expand All @@ -63,6 +64,17 @@ std::unique_ptr<quic::QuicSession> EnvoyQuicDispatcher::CreateQuicSession(
quic_config, quic::ParsedQuicVersionVector{version}, std::move(quic_connection), this,
session_helper(), crypto_config(), compressed_certs_cache(), dispatcher_,
listener_config_.perConnectionBufferLimitBytes(), listener_config_);

const Network::FilterChain* filter_chain =
getFilterChain(listen_socket_.ioHandle(), listener_config_.filterChainManager(), self_address,
peer_address, std::string(sni), alpn);
ASSERT(filter_chain);
if (filter_chain != nullptr) {
const bool has_filter_initialized =
listener_config_.filterChainFactory().createNetworkFilterChain(
*quic_session, filter_chain->networkFilterFactories());
ASSERT(has_filter_initialized);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you comment about the validity of this ASSERT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. As long as HCM is configured, the ASSERT should pass here.

}
quic_session->Initialize();
// Filter chain can't be retrieved here as self address is unknown at this
// point.
Expand Down
12 changes: 3 additions & 9 deletions source/common/quic/envoy_quic_proof_source.cc
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,10 @@ EnvoyQuicProofSource::getTlsCertConfigAndFilterChain(const quic::QuicSocketAddre
const quic::QuicSocketAddress& client_address,
const std::string& hostname) {
ENVOY_LOG(trace, "Getting cert chain for {}", hostname);
Network::ConnectionSocketImpl connection_socket(
std::make_unique<QuicIoHandleWrapper>(listen_socket_.ioHandle()),
quicAddressToEnvoyAddressInstance(server_address),
quicAddressToEnvoyAddressInstance(client_address));
connection_socket.setDetectedTransportProtocol(
Extensions::TransportSockets::TransportProtocolNames::get().Quic);
connection_socket.setRequestedServerName(hostname);
connection_socket.setRequestedApplicationProtocols({"h2"});
const Network::FilterChain* filter_chain =
filter_chain_manager_.findFilterChain(connection_socket);
getFilterChain(listen_socket_.ioHandle(), filter_chain_manager_, server_address,
client_address, hostname, "h3-29");

if (filter_chain == nullptr) {
listener_stats_.no_filter_chain_match_.inc();
return {absl::nullopt, absl::nullopt};
Expand Down
22 changes: 3 additions & 19 deletions source/common/quic/envoy_quic_server_session.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,11 @@ EnvoyQuicServerSession::EnvoyQuicServerSession(
std::unique_ptr<EnvoyQuicConnection> connection, quic::QuicSession::Visitor* visitor,
quic::QuicCryptoServerStream::Helper* helper, const quic::QuicCryptoServerConfig* crypto_config,
quic::QuicCompressedCertsCache* compressed_certs_cache, Event::Dispatcher& dispatcher,
uint32_t send_buffer_limit, Network::ListenerConfig& listener_config)
uint32_t send_buffer_limit, Network::ListenerConfig& /*listener_config*/)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the listener_config argument should be removed; the call to createNetworkFilterChain was moved to the parent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

: quic::QuicServerSessionBase(config, supported_versions, connection.get(), visitor, helper,
crypto_config, compressed_certs_cache),
QuicFilterManagerConnectionImpl(*connection, dispatcher, send_buffer_limit),
quic_connection_(std::move(connection)), listener_config_(listener_config) {
// HTTP/3 header limits should be configurable, but for now hard-code to Envoy defaults.
set_max_inbound_header_list_size(Http::DEFAULT_MAX_REQUEST_HEADERS_KB * 1000);
}
quic_connection_(std::move(connection)) {}

EnvoyQuicServerSession::~EnvoyQuicServerSession() {
ASSERT(!quic_connection_->connected());
Expand Down Expand Up @@ -89,6 +86,7 @@ void EnvoyQuicServerSession::OnConnectionClosed(const quic::QuicConnectionCloseF

void EnvoyQuicServerSession::Initialize() {
quic::QuicServerSessionBase::Initialize();
initialized_ = true;
quic_connection_->setEnvoyConnection(*this);
}

Expand All @@ -109,7 +107,6 @@ void EnvoyQuicServerSession::SetDefaultEncryptionLevel(quic::EncryptionLevel lev
if (level != quic::ENCRYPTION_FORWARD_SECURE) {
return;
}
maybeCreateNetworkFilters();
// This is only reached once, when handshake is done.
raiseConnectionEvent(Network::ConnectionEvent::Connected);
}
Expand All @@ -118,22 +115,9 @@ bool EnvoyQuicServerSession::hasDataToWrite() { return HasDataToWrite(); }

void EnvoyQuicServerSession::OnTlsHandshakeComplete() {
quic::QuicServerSessionBase::OnTlsHandshakeComplete();
maybeCreateNetworkFilters();
raiseConnectionEvent(Network::ConnectionEvent::Connected);
}

void EnvoyQuicServerSession::maybeCreateNetworkFilters() {
auto proof_source_details =
dynamic_cast<const EnvoyQuicProofSourceDetails*>(GetCryptoStream()->ProofSourceDetails());
ASSERT(proof_source_details != nullptr,
"ProofSource didn't provide ProofSource::Details. No filter chain will be installed.");

const bool has_filter_initialized =
listener_config_.filterChainFactory().createNetworkFilterChain(
*this, proof_source_details->filterChain().networkFilterFactories());
ASSERT(has_filter_initialized);
}

size_t EnvoyQuicServerSession::WriteHeadersOnHeadersStream(
quic::QuicStreamId id, spdy::SpdyHeaderBlock headers, bool fin,
const spdy::SpdyStreamPrecedence& precedence,
Expand Down
2 changes: 0 additions & 2 deletions source/common/quic/envoy_quic_server_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,8 @@ class EnvoyQuicServerSession : public quic::QuicServerSessionBase,

private:
void setUpRequestDecoder(EnvoyQuicServerStream& stream);
void maybeCreateNetworkFilters();

std::unique_ptr<EnvoyQuicConnection> quic_connection_;
Network::ListenerConfig& listener_config_;
// These callbacks are owned by network filters and quic session should out live
// them.
Http::ServerConnectionCallbacks* http_connection_callbacks_{nullptr};
Expand Down
17 changes: 17 additions & 0 deletions source/common/quic/envoy_quic_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "common/network/socket_option_factory.h"
#include "common/network/utility.h"

#include "extensions/transport_sockets/well_known_names.h"

namespace Envoy {
namespace Quic {

Expand Down Expand Up @@ -223,5 +225,20 @@ int deduceSignatureAlgorithmFromPublicKey(const EVP_PKEY* public_key, std::strin
return sign_alg;
}

const Network::FilterChain* getFilterChain(Network::IoHandle& io_handle,
Network::FilterChainManager& filter_chain_manager,
const quic::QuicSocketAddress& self_address,
const quic::QuicSocketAddress& peer_address,
const std::string& hostname, absl::string_view alpn) {
Network::ConnectionSocketImpl connection_socket(std::make_unique<QuicIoHandleWrapper>(io_handle),
quicAddressToEnvoyAddressInstance(self_address),
quicAddressToEnvoyAddressInstance(peer_address));
connection_socket.setDetectedTransportProtocol(
Extensions::TransportSockets::TransportProtocolNames::get().Quic);
connection_socket.setRequestedServerName(hostname);
connection_socket.setRequestedApplicationProtocols({alpn});
return filter_chain_manager.findFilterChain(connection_socket);
}

} // namespace Quic
} // namespace Envoy
7 changes: 7 additions & 0 deletions source/common/quic/envoy_quic_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "common/http/header_map_impl.h"
#include "common/network/address_impl.h"
#include "common/network/listen_socket_impl.h"
#include "common/quic/quic_io_handle_wrapper.h"

#if defined(__GNUC__)
#pragma GCC diagnostic push
Expand Down Expand Up @@ -125,5 +126,11 @@ bssl::UniquePtr<X509> parseDERCertificate(const std::string& der_bytes, std::str
// not supported, return 0 with error_details populated correspondingly.
int deduceSignatureAlgorithmFromPublicKey(const EVP_PKEY* public_key, std::string* error_details);

const Network::FilterChain* getFilterChain(Network::IoHandle& io_handle,
Network::FilterChainManager& filter_chain_manager,
const quic::QuicSocketAddress& self_address,
const quic::QuicSocketAddress& peer_address,
const std::string& hostname, absl::string_view alpn);

} // namespace Quic
} // namespace Envoy
6 changes: 6 additions & 0 deletions source/common/quic/quic_filter_manager_connection_impl.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "common/quic/quic_filter_manager_connection_impl.h"

#include <initializer_list>
#include <memory>

namespace Envoy {
Expand Down Expand Up @@ -65,6 +66,11 @@ void QuicFilterManagerConnectionImpl::close(Network::ConnectionCloseType type) {
// Already detached from quic connection.
return;
}
if (!initialized_) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we get here? I thought quicConnection would return null above if not initialized.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point! We need to distinguish between already closed and not initialized. In latter case, we need to retain close type and close in OnCanWrite().

// Delay close till the first OnCanWrite() call.
delayed_close_state_ = DelayedCloseState::CloseAfterFlush;
return;
}
const bool delayed_close_timeout_configured = delayed_close_timeout_.count() > 0;
if (hasDataToWrite() && type != Network::ConnectionCloseType::NoFlush) {
if (delayed_close_timeout_configured) {
Expand Down
10 changes: 6 additions & 4 deletions source/common/quic/quic_filter_manager_connection_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,16 @@ class QuicFilterManagerConnectionImpl : public Network::ConnectionImplBase,
}
Ssl::ConnectionInfoConstSharedPtr ssl() const override;
Network::Connection::State state() const override {
if (quic_connection_ != nullptr && quic_connection_->connected()) {
if (!initialized_ || (quic_connection_ != nullptr && quic_connection_->connected())) {
return Network::Connection::State::Open;
}
return Network::Connection::State::Closed;
}
bool connecting() const override {
if (quic_connection_ != nullptr && !quic_connection_->IsHandshakeComplete()) {
return true;
if (initialized_ && (quic_connection_ == nullptr || quic_connection_->IsHandshakeComplete())) {
return false;
}
return false;
return true;
}
void write(Buffer::Instance& /*data*/, bool /*end_stream*/) override {
// All writes should be handled by Quic internally.
Expand Down Expand Up @@ -143,6 +143,8 @@ class QuicFilterManagerConnectionImpl : public Network::ConnectionImplBase,
absl::optional<std::reference_wrapper<Http::Http3::CodecStats>> codec_stats_;
absl::optional<std::reference_wrapper<const envoy::config::core::v3::Http3ProtocolOptions>>
http3_options_;
// If false, do not call into quic_connection_.
bool initialized_{false};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it makes sense to have a helper for quic_connection() which returned nullptr if not initialized?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactory QuicFilterManagerConnection and EnvoyQuicConnection so that EnvoyQuicConnection doesn't grant access to QuicConnection interface. And added quic_connection() to the subclasses of QuicFilterManagerConnection which returns nullptrl if not initialized.


private:
friend class Envoy::TestPauseFilterForQuic;
Expand Down
Loading