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

http3: changing how http3 is built #15540

Merged
merged 7 commits into from
Mar 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 0 additions & 2 deletions api/envoy/config/listener/v3/quic_config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ option java_multiple_files = true;
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: QUIC listener config]
// [#comment:#extension: envoy.udp_listeners.quiche_quic_listener]
// [#comment:TODO(#12829): Remove this as an extension point.]

// Configuration specific to the UDP QUIC listener.
message QuicProtocolOptions {
Expand Down
2 changes: 0 additions & 2 deletions api/envoy/config/listener/v4alpha/quic_config.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions bazel/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ load("@rules_cc//cc:defs.bzl", "cc_library", "cc_proto_library")
load("//bazel:envoy_build_system.bzl", "envoy_package")
load("//bazel:envoy_internal.bzl", "envoy_select_force_libcpp")
load("@bazel_skylib//lib:selects.bzl", "selects")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")

licenses(["notice"]) # Apache 2

Expand Down Expand Up @@ -286,6 +287,18 @@ config_setting(
values = {"define": "deprecated_features=disabled"},
)

bool_flag(
name = "http3",
build_setting_default = True,
)

config_setting(
lizan marked this conversation as resolved.
Show resolved Hide resolved
name = "disable_http3",
flag_values = {
":http3": "False",
},
)

config_setting(
name = "disable_hot_restart",
values = {"define": "hot_restart=disabled"},
Expand Down
2 changes: 1 addition & 1 deletion bazel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ The following optional features can be disabled on the Bazel build command-line:
* tcmalloc with `--define tcmalloc=disabled`. Also you can choose Gperftools' implementation of
tcmalloc with `--define tcmalloc=gperftools` which is the default for builds other than x86_64 and aarch64.
* deprecated features with `--define deprecated_features=disabled`

* http3/quic with --//bazel:http3=False

## Enabling optional features

Expand Down
2 changes: 2 additions & 0 deletions bazel/envoy_build_system.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ load(
load(
":envoy_select.bzl",
_envoy_select_boringssl = "envoy_select_boringssl",
_envoy_select_enable_http3 = "envoy_select_enable_http3",
_envoy_select_google_grpc = "envoy_select_google_grpc",
_envoy_select_hot_restart = "envoy_select_hot_restart",
_envoy_select_wasm_cpp_tests = "envoy_select_wasm_cpp_tests",
Expand Down Expand Up @@ -203,6 +204,7 @@ def envoy_google_grpc_external_deps():
# Select wrappers (from envoy_select.bzl)
envoy_select_boringssl = _envoy_select_boringssl
envoy_select_google_grpc = _envoy_select_google_grpc
envoy_select_enable_http3 = _envoy_select_enable_http3
envoy_select_hot_restart = _envoy_select_hot_restart
envoy_select_wasm_cpp_tests = _envoy_select_wasm_cpp_tests
envoy_select_wasm_rust_tests = _envoy_select_wasm_rust_tests
Expand Down
3 changes: 2 additions & 1 deletion bazel/envoy_internal.bzl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# DO NOT LOAD THIS FILE. Targets from this file should be considered private
# and not used outside of the @envoy//bazel package.
load(":envoy_select.bzl", "envoy_select_google_grpc", "envoy_select_hot_restart")
load(":envoy_select.bzl", "envoy_select_enable_http3", "envoy_select_google_grpc", "envoy_select_hot_restart")

# Compute the final copts based on various options.
def envoy_copts(repository, test = False):
Expand Down Expand Up @@ -114,6 +114,7 @@ def envoy_copts(repository, test = False):
repository + "//bazel:apple": ["-D__APPLE_USE_RFC_3542"],
"//conditions:default": [],
}) + envoy_select_hot_restart(["-DENVOY_HOT_RESTART"], repository) + \
envoy_select_enable_http3(["-DENVOY_ENABLE_QUICHE"], repository) + \
_envoy_select_perf_annotation(["-DENVOY_PERF_ANNOTATION"]) + \
envoy_select_google_grpc(["-DENVOY_GOOGLE_GRPC"], repository) + \
_envoy_select_path_normalization_by_default(["-DENVOY_NORMALIZE_PATH_BY_DEFAULT"], repository)
Expand Down
7 changes: 7 additions & 0 deletions bazel/envoy_select.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ def envoy_select_google_grpc(xs, repository = ""):
"//conditions:default": xs,
})

# Selects the given values if http3 is enabled in the current build.
def envoy_select_enable_http3(xs, repository = ""):
return select({
repository + "//bazel:disable_http3": [],
"//conditions:default": xs,
})

# Selects the given values if hot restart is enabled in the current build.
def envoy_select_hot_restart(xs, repository = ""):
return select({
Expand Down
3 changes: 1 addition & 2 deletions bazel/repository_locations.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -773,8 +773,7 @@ REPOSITORY_LOCATIONS_SPEC = dict(
version = "6fec8e97a1ab1a945b86bd6b7252666294448ddb",
sha256 = "3045254cbf03c29ee7166fb01b1072a463c58df405669b8573677d4638869290",
urls = ["https://storage.googleapis.com/quiche-envoy-integration/{version}.tar.gz"],
use_category = ["dataplane_ext"],
extensions = ["envoy.transport_sockets.quic", "envoy.udp_listeners.quiche_quic_listener"],
use_category = ["dataplane_core"],
release_date = "2021-02-24",
cpe = "N/A",
),
Expand Down
1 change: 1 addition & 0 deletions docs/root/version_history/current.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Incompatible Behavior Changes
* config: the v2 xDS API is no longer supported by the Envoy binary.
* grpc_stats: the default value for :ref:`stats_for_all_methods <envoy_v3_api_field_extensions.filters.http.grpc_stats.v3.FilterConfig.stats_for_all_methods>` is switched from true to false, in order to avoid possible memory exhaustion due to an untrusted downstream sending a large number of unique method names. The previous default value was deprecated in version 1.14.0. This only changes the behavior when the value is not set. The previous behavior can be used by setting the value to true. This behavior change by be overridden by setting runtime feature `envoy.deprecated_features.grpc_stats_filter_enable_stats_for_all_methods_by_default`.
* http: fixing a standards compliance issue with :scheme. The :scheme header sent upstream is now based on the original URL scheme, rather than set based on the security of the upstream connection. This behavior can be temporarily reverted by setting `envoy.reloadable_features.preserve_downstream_scheme` to false.
* http: http3 is now enabled/disabled via build option `--define http3=disabled` rather than the extension framework. Behavior is the same, but builds may be affected for platforms or build configurations where http3 is not supported.
* http: resolving inconsistencies between :scheme and X-Forwarded-Proto. :scheme will now be set for all HTTP/1.1 requests. This changes the behavior of the gRPC access logger, Wasm filters, CSRF filter and oath2 filter for HTTP/1 traffic, where :scheme was previously not set. This change also validates that for front-line Envoys (Envoys configured with :ref:`xff_num_trusted_hops <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.xff_num_trusted_hops>` set to 0 and :ref:`use_remote_address <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.use_remote_address>` set to true) that HTTP/1.1 https schemed requests can not be sent over non-TLS connections. All behavioral changes listed here can be temporarily reverted by setting `envoy.reloadable_features.add_and_validate_scheme_header` to false.
* http: when a protocol error is detected in response from upstream, Envoy sends 502 BadGateway downstream and access log entry contains UPE flag. This behavior change can be overwritten to use error code 503 by setting `envoy.reloadable_features.return_502_for_upstream_protocol_errors` to false.

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions source/extensions/all_extensions.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ _required_extensions = {
"envoy.common.crypto.utility_lib": "//source/extensions/common/crypto:utility_lib",
"envoy.request_id.uuid": "//source/extensions/request_id/uuid:config",
"envoy.transport_sockets.tls": "//source/extensions/transport_sockets/tls:config",
#TODO(#12829) remove these.
"envoy.listener.quic": "//source/extensions/quic_listeners/quiche:quic_factory_lib",
"envoy.transport_sockets.quic": "//source/extensions/quic_listeners/quiche:quic_transport_socket_factory_lib",
Comment on lines +11 to +12
Copy link
Member

Choose a reason for hiding this comment

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

Is your plan to follow up here and completely remove these as extensions? TODO? Also this will allow us to use the GSO writer for udp_proxy also and remove all of that config as well. TODO around that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hm, I didn't think having quic as a "required" extension made any less sense than tls as a required extension, but if you want to remove it entirely we can. Want me to do that here, or a follow up?

I wasn't planning on following up on the GSO bits, I was largely hoping to just make the QUIC hackery I'm dealing with less hacky. Would you or @danzh2010 be up for tackling GSO as a followup?

Copy link
Member

Choose a reason for hiding this comment

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

hm, I didn't think having quic as a "required" extension made any less sense than tls as a required extension, but if you want to remove it entirely we can. Want me to do that here, or a follow up?

TLS as an extension is "required" because of the openssl stuff. I think if we completely remove QUIC as an extension it will clean up a lot of the places I have commented on where we are referencing extension code in core code and vice versa. I'm happy to do some of this work as a side project if you don't have time but let's add the TODO either way?

I wasn't planning on following up on the GSO bits, I was largely hoping to just make the QUIC hackery I'm dealing with less hacky. Would you or @danzh2010 be up for tackling GSO as a followup?

Yes I can work on this as part of ^ if you don't want to do it now.

}

# Return the extension cc_library target after select
Expand Down
7 changes: 0 additions & 7 deletions source/extensions/extensions_build_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,6 @@ EXTENSIONS = {
"envoy.tracers.xray": "//source/extensions/tracers/xray:config",
"envoy.tracers.skywalking": "//source/extensions/tracers/skywalking:config",

#
# Listener
#

"envoy.udp_listeners.quiche_quic_listener": "//source/extensions/quic_listeners/quiche:quic_factory_lib",

#
# Transport sockets
#
Expand All @@ -194,7 +188,6 @@ EXTENSIONS = {
"envoy.transport_sockets.upstream_proxy_protocol": "//source/extensions/transport_sockets/proxy_protocol:upstream_config",
"envoy.transport_sockets.raw_buffer": "//source/extensions/transport_sockets/raw_buffer:config",
"envoy.transport_sockets.tap": "//source/extensions/transport_sockets/tap:config",
"envoy.transport_sockets.quic": "//source/extensions/quic_listeners/quiche:quic_transport_socket_factory_lib",
"envoy.transport_sockets.starttls": "//source/extensions/transport_sockets/starttls:config",

#
Expand Down
6 changes: 2 additions & 4 deletions source/extensions/quic_listeners/quiche/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -382,13 +382,10 @@ envoy_cc_extension(
# Remove QUIC as an extension
"DELIBERATELY_OMITTED",
),
# Needed to verify that a quic specific configuration is used for quic transport socket.
extra_visibility = [
"//source/server:__subpackages__",
],
security_posture = "unknown",
tags = ["nofips"],
undocumented = True,
visibility = ["//visibility:public"],
deps = [
"//include/envoy/network:transport_socket_interface",
"//include/envoy/server:transport_socket_config_interface",
Expand All @@ -411,6 +408,7 @@ envoy_cc_extension(
security_posture = "unknown",
tags = ["nofips"],
undocumented = True,
visibility = ["//visibility:public"],
# QUICHE can't build against FIPS BoringSSL until the FIPS build
# is on a new enough version to have QUIC support. Remove it from
# the build until then. Re-enable as part of #7433.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ namespace quic {
using QuicLogLevel = spdlog::level::level_enum;

static const QuicLogLevel TRACE = spdlog::level::trace;
static const QuicLogLevel DEBUG = spdlog::level::debug;
static const QuicLogLevel QDEBUG = spdlog::level::debug;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

cc @danzh2010 David said you had a workaround for this - lmk if this conflicts or you have a better plan? Honestly I was surprised this compiled, having assumed we needed to match the google log defines...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

This works. I'll have a more complete fix which will bring back DEBUG (this time without breaking macOS) ASAP. Feel free to merge this.

Copy link
Contributor

Choose a reason for hiding this comment

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

The other fix I mentioned is at #15616

static const QuicLogLevel INFO = spdlog::level::info;
static const QuicLogLevel WARNING = spdlog::level::warn;
static const QuicLogLevel ERROR = spdlog::level::err;
Expand Down Expand Up @@ -184,7 +184,7 @@ inline spdlog::logger& GetLogger() {
#define QUICHE_IS_LOG_LEVEL_ENABLED_IMPL(severity) \
inline bool isLogLevelEnabled##severity() { return quic::severity >= GetLogger().level(); }
QUICHE_IS_LOG_LEVEL_ENABLED_IMPL(TRACE)
QUICHE_IS_LOG_LEVEL_ENABLED_IMPL(DEBUG)
QUICHE_IS_LOG_LEVEL_ENABLED_IMPL(QDEBUG)
QUICHE_IS_LOG_LEVEL_ENABLED_IMPL(INFO)
QUICHE_IS_LOG_LEVEL_ENABLED_IMPL(WARNING)
QUICHE_IS_LOG_LEVEL_ENABLED_IMPL(ERROR)
Expand Down
7 changes: 5 additions & 2 deletions source/server/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ load(
"envoy_cc_library",
"envoy_package",
"envoy_proto_library",
"envoy_select_enable_http3",
"envoy_select_hot_restart",
)

Expand Down Expand Up @@ -370,14 +371,16 @@ envoy_cc_library(
"//source/common/stream_info:stream_info_lib",
"//source/extensions/filters/listener:well_known_names",
"//source/extensions/filters/network/http_connection_manager:config",
"//source/extensions/quic_listeners/quiche:quic_transport_socket_factory_lib",
"//source/extensions/transport_sockets:well_known_names",
"//source/extensions/upstreams/http/generic:config",
"@envoy_api//envoy/admin/v3:pkg_cc_proto",
"@envoy_api//envoy/config/core/v3:pkg_cc_proto",
"@envoy_api//envoy/config/listener/v3:pkg_cc_proto",
"@envoy_api//envoy/extensions/filters/listener/proxy_protocol/v3:pkg_cc_proto",
],
] + envoy_select_enable_http3([
"//source/extensions/quic_listeners/quiche:quic_factory_lib",
"//source/extensions/quic_listeners/quiche:quic_transport_socket_factory_lib",
]),
)

envoy_cc_library(
Expand Down
6 changes: 5 additions & 1 deletion test/common/upstream/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ load(
"envoy_cc_test_library",
"envoy_package",
"envoy_proto_library",
"envoy_select_enable_http3",
)

licenses(["notice"]) # Apache 2
Expand Down Expand Up @@ -591,6 +592,7 @@ envoy_cc_test(
envoy_cc_test(
name = "upstream_impl_test",
srcs = ["upstream_impl_test.cc"],
data = ["//test/extensions/transport_sockets/tls/test_data:certs"],
deps = [
":utility_lib",
"@envoy_api//envoy/config/cluster/v3:pkg_cc_proto",
Expand Down Expand Up @@ -623,7 +625,9 @@ envoy_cc_test(
"//test/test_common:registry_lib",
"//test/test_common:test_runtime_lib",
"//test/test_common:utility_lib",
],
] + envoy_select_enable_http3([
"//source/extensions/quic_listeners/quiche:quic_transport_socket_factory_lib",
]),
)

envoy_cc_test_library(
Expand Down
76 changes: 76 additions & 0 deletions test/common/upstream/upstream_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3131,6 +3131,82 @@ TEST_F(ClusterInfoImplTest, UpstreamHttp11Protocol) {
cluster->info()->upstreamHttpProtocol({Http::Protocol::Http2})[0]);
}

#ifdef ENVOY_ENABLE_QUICHE
TEST_F(ClusterInfoImplTest, Http3) {
const std::string yaml = TestEnvironment::substitute(R"EOF(
name: name
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: MAGLEV
load_assignment:
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: foo.bar.com
port_value: 443
transport_socket:
name: envoy.transport_sockets.quic
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.quic.v3.QuicUpstreamTransport
upstream_tls_context:
common_tls_context:
tls_certificates:
- certificate_chain:
filename: "{{ test_rundir }}/test/extensions/transport_sockets/tls/test_data/san_uri_cert.pem"
private_key:
filename: "{{ test_rundir }}/test/extensions/transport_sockets/tls/test_data/san_uri_key.pem"
validation_context:
trusted_ca:
filename: "{{ test_rundir }}/test/extensions/transport_sockets/tls/test_data/ca_cert.pem"
match_subject_alt_names:
- exact: localhost
- exact: 127.0.0.1
)EOF",
Network::Address::IpVersion::v4);

auto cluster1 = makeCluster(yaml);
ASSERT_TRUE(cluster1->info()->idleTimeout().has_value());
EXPECT_EQ(std::chrono::hours(1), cluster1->info()->idleTimeout().value());

const std::string explicit_http3 = R"EOF(
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicit_http_config:
http3_protocol_options:
quic_protocol_options:
max_concurrent_streams: 2
common_http_protocol_options:
idle_timeout: 1s
)EOF";

const std::string downstream_http3 = R"EOF(
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
use_downstream_protocol_config:
http3_protocol_options: {}
common_http_protocol_options:
idle_timeout: 1s
)EOF";

auto explicit_h3 = makeCluster(yaml + explicit_http3);
EXPECT_EQ(Http::Protocol::Http3,
explicit_h3->info()->upstreamHttpProtocol({Http::Protocol::Http10})[0]);
EXPECT_EQ(
explicit_h3->info()->http3Options().quic_protocol_options().max_concurrent_streams().value(),
2);

auto downstream_h3 = makeCluster(yaml + downstream_http3);
EXPECT_EQ(Http::Protocol::Http3,
downstream_h3->info()->upstreamHttpProtocol({Http::Protocol::Http3})[0]);
EXPECT_FALSE(
downstream_h3->info()->http3Options().quic_protocol_options().has_max_concurrent_streams());
}
#endif // ENVOY_ENABLE_QUICHE

// Validate empty singleton for HostsPerLocalityImpl.
TEST(HostsPerLocalityImpl, Empty) {
EXPECT_FALSE(HostsPerLocalityImpl::empty()->hasLocalLocality());
Expand Down
28 changes: 0 additions & 28 deletions test/extensions/quic_listeners/quiche/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,6 @@ licenses(["notice"]) # Apache 2

envoy_package()

envoy_cc_test(
name = "quic_upstream_test",
srcs = ["quic_upstream_test.cc"],
data = ["//test/extensions/transport_sockets/tls/test_data:certs"],
deps = [
"//source/common/event:dispatcher_lib",
"//source/common/network:utility_lib",
"//source/common/upstream:strict_dns_cluster_lib",
"//source/extensions/quic_listeners/quiche:quic_transport_socket_factory_lib",
"//source/extensions/upstreams/http:config",
"//test/common/upstream:utility_lib",
"//test/mocks:common_lib",
"//test/mocks/local_info:local_info_mocks",
"//test/mocks/network:network_mocks",
"//test/mocks/protobuf:protobuf_mocks",
"//test/mocks/runtime:runtime_mocks",
"//test/mocks/server:server_mocks",
"//test/mocks/ssl:ssl_mocks",
"//test/mocks/upstream:cluster_info_mocks",
"//test/mocks/upstream:cluster_manager_mocks",
"//test/mocks/upstream:health_checker_mocks",
"//test/mocks/upstream:priority_set_mocks",
"//test/test_common:registry_lib",
"//test/test_common:test_runtime_lib",
"//test/test_common:utility_lib",
],
)

envoy_cc_test(
name = "envoy_quic_alarm_test",
srcs = ["envoy_quic_alarm_test.cc"],
Expand Down
4 changes: 4 additions & 0 deletions tools/extensions/generate_extension_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ def get_extension_metadata(target):
'//source/extensions/upstreams/http:config')
extension_db['envoy.request_id.uuid'] = get_extension_metadata(
'//source/extensions/request_id/uuid:config')
extension_db['envoy.listener.quic'] = get_extension_metadata(
'//source/extensions/quic_listeners/quiche:quic_factory_lib')
extension_db['envoy.transport_sockets.quic'] = get_extension_metadata(
'//source/extensions/quic_listeners/quiche:quic_transport_socket_factory_lib')

pathlib.Path(os.path.dirname(output_path)).mkdir(parents=True, exist_ok=True)
pathlib.Path(output_path).write_text(json.dumps(extension_db))