From 3552532f90911f3c26e99f09255f986efc042a35 Mon Sep 17 00:00:00 2001 From: Bartosz Chwila <103247439+barchw@users.noreply.github.com> Date: Fri, 2 May 2025 18:47:17 +0200 Subject: [PATCH 01/35] uri_template: Add support for the "*" character matching in pattern rewrite and matching (#39169) Adds support for matching requests that include the `*` character in the path. A relevant issue was created: https://github.com/envoyproxy/envoy/issues/39168 Risk Level: Testing: Updated unit tests Docs Changes: N/A Release Notes: Added Platform Specific Features: N/A Runtime guard: envoy.reloadable_features.uri_template_match_on_asterisk Resolves: https://github.com/envoyproxy/envoy/issues/39168 --------- Signed-off-by: Chwila Signed-off-by: Yan Avlasov --- changelogs/current.yaml | 5 ++ source/common/runtime/runtime_features.cc | 1 + source/extensions/path/uri_template_lib/BUILD | 1 + .../uri_template_lib/uri_template_internal.cc | 53 +++++++++++-- .../path/match/uri_template/library_test.cc | 60 +++++++++++++++ .../path/rewrite/uri_template/library_test.cc | 56 ++++++++++++++ test/extensions/path/uri_template_lib/BUILD | 1 + .../uri_template_internal_test.cc | 77 +++++++++++++------ .../uri_template_lib/uri_template_test.cc | 18 ++--- tools/spelling/spelling_dictionary.txt | 3 + 10 files changed, 233 insertions(+), 42 deletions(-) diff --git a/changelogs/current.yaml b/changelogs/current.yaml index c29d5291c1..9416e93aaf 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -11,6 +11,11 @@ bug_fixes: - area: eds change: | Fixed crash when creating an EDS cluster with invalid configuration. +- area: url_template + change: | + Included the asterisk ``*`` in the match pattern when using the * or ** operators in the URL template. + This behavioral change can be temporarily reverted by setting runtime guard + ``envoy.reloadable_features.uri_template_match_on_asterisk`` to ``false``. removed_config_or_runtime: # *Normally occurs at the end of the* :ref:`deprecation period ` diff --git a/source/common/runtime/runtime_features.cc b/source/common/runtime/runtime_features.cc index c30e1e632f..6f15486b80 100644 --- a/source/common/runtime/runtime_features.cc +++ b/source/common/runtime/runtime_features.cc @@ -102,6 +102,7 @@ RUNTIME_GUARD(envoy_reloadable_features_test_feature_true); RUNTIME_GUARD(envoy_reloadable_features_udp_set_do_not_fragment); RUNTIME_GUARD(envoy_reloadable_features_udp_socket_apply_aggregated_read_limit); RUNTIME_GUARD(envoy_reloadable_features_uhv_allow_malformed_url_encoding); +RUNTIME_GUARD(envoy_reloadable_features_uri_template_match_on_asterisk); RUNTIME_GUARD(envoy_reloadable_features_use_config_in_happy_eyeballs); RUNTIME_GUARD(envoy_reloadable_features_use_filter_manager_state_for_downstream_end_stream); RUNTIME_GUARD(envoy_reloadable_features_use_route_host_mutation_for_auto_sni_san); diff --git a/source/extensions/path/uri_template_lib/BUILD b/source/extensions/path/uri_template_lib/BUILD index a7c407c728..1f7760519d 100644 --- a/source/extensions/path/uri_template_lib/BUILD +++ b/source/extensions/path/uri_template_lib/BUILD @@ -35,6 +35,7 @@ envoy_cc_library( hdrs = ["uri_template_internal.h"], deps = [ "//source/common/common:fmt_lib", + "//source/common/runtime:runtime_features_lib", "@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/flags:flag", "@com_google_absl//absl/functional:function_ref", diff --git a/source/extensions/path/uri_template_lib/uri_template_internal.cc b/source/extensions/path/uri_template_lib/uri_template_internal.cc index ec674d80bd..dda6e7bddb 100644 --- a/source/extensions/path/uri_template_lib/uri_template_internal.cc +++ b/source/extensions/path/uri_template_lib/uri_template_internal.cc @@ -7,6 +7,7 @@ #include #include "source/common/common/fmt.h" +#include "source/common/runtime/runtime_features.h" #include "absl/container/flat_hash_set.h" #include "absl/flags/flag.h" @@ -46,6 +47,16 @@ constexpr absl::string_view kLiteral = "a-zA-Z0-9-._~" // Unreserved ":@" "="; // user included "=" allowed +// Additional literal that allows "*" in the pattern. +// This should replace "kLiteral" after removal of +// "reloadable_features.uri_template_match_on_asterisk" runtime guard. +// Valid pchar from https://datatracker.ietf.org/doc/html/rfc3986#appendix-A +constexpr absl::string_view kLiteralWithAsterisk = "a-zA-Z0-9-._~" // Unreserved + "%" // pct-encoded + "!$&'()+,;" // sub-delims excluding *= + ":@" + "=*"; // reserved characters + // Default operator used for the variable when none specified. constexpr Operator kDefaultVariableOperator = Operator::PathGlob; @@ -122,17 +133,30 @@ std::string ParsedPathPattern::debugString() const { } bool isValidLiteral(absl::string_view literal) { + static const std::string* kValidLiteralRegexAsterisk = + new std::string(absl::StrCat("^[", kLiteralWithAsterisk, "]+$")); static const std::string* kValidLiteralRegex = new std::string(absl::StrCat("^[", kLiteral, "]+$")); + static const LazyRE2 literal_regex_asterisk = {kValidLiteralRegexAsterisk->data()}; static const LazyRE2 literal_regex = {kValidLiteralRegex->data()}; - return RE2::FullMatch(literal, *literal_regex); + + return Runtime::runtimeFeatureEnabled("envoy.reloadable_features.uri_template_match_on_asterisk") + ? RE2::FullMatch(literal, *literal_regex_asterisk) + : RE2::FullMatch(literal, *literal_regex); } bool isValidRewriteLiteral(absl::string_view literal) { static const std::string* kValidLiteralRegex = new std::string(absl::StrCat("^[", kLiteral, "/]+$")); + static const std::string* kValidLiteralRegexAsterisk = + new std::string(absl::StrCat("^[", kLiteralWithAsterisk, "/]+$")); + static const LazyRE2 literal_regex = {kValidLiteralRegex->data()}; - return RE2::FullMatch(literal, *literal_regex); + static const LazyRE2 literal_regex_asterisk = {kValidLiteralRegexAsterisk->data()}; + + return Runtime::runtimeFeatureEnabled("envoy.reloadable_features.uri_template_match_on_asterisk") + ? RE2::FullMatch(literal, *literal_regex_asterisk) + : RE2::FullMatch(literal, *literal_regex); } bool isValidVariableName(absl::string_view variable) { @@ -360,11 +384,26 @@ std::string toRegexPattern(absl::string_view pattern) { std::string toRegexPattern(Operator pattern) { static const std::string* kPathGlobRegex = new std::string(absl::StrCat("[", kLiteral, "]+")); static const std::string* kTextGlobRegex = new std::string(absl::StrCat("[", kLiteral, "/]*")); - switch (pattern) { - case Operator::PathGlob: // "*" - return *kPathGlobRegex; - case Operator::TextGlob: // "**" - return *kTextGlobRegex; + + static const std::string* kPathGlobRegexAsterisk = + new std::string(absl::StrCat("[", kLiteralWithAsterisk, "]+")); + static const std::string* kTextGlobRegexAsterisk = + new std::string(absl::StrCat("[", kLiteralWithAsterisk, "/]*")); + + if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.uri_template_match_on_asterisk")) { + switch (pattern) { + case Operator::PathGlob: // "*" + return *kPathGlobRegexAsterisk; + case Operator::TextGlob: // "**" + return *kTextGlobRegexAsterisk; + } + } else { + switch (pattern) { + case Operator::PathGlob: // "*" + return *kPathGlobRegex; + case Operator::TextGlob: // "**" + return *kTextGlobRegex; + } } return ""; } diff --git a/test/extensions/path/match/uri_template/library_test.cc b/test/extensions/path/match/uri_template/library_test.cc index e154986aa0..002fea5a8c 100644 --- a/test/extensions/path/match/uri_template/library_test.cc +++ b/test/extensions/path/match/uri_template/library_test.cc @@ -43,6 +43,66 @@ TEST(MatchTest, BasicUsage) { EXPECT_TRUE(matcher->match("/bar/en/us")); } +TEST(MatchTest, MatchSingleAsteriskInWildcard) { + const std::string yaml_string = R"EOF( + name: envoy.path.match.uri_template.uri_template_matcher + typed_config: + "@type": type.googleapis.com/envoy.extensions.path.match.uri_template.v3.UriTemplateMatchConfig + path_template: "/bar/{lang}/{country=**}" +)EOF"; + + Router::PathMatcherSharedPtr matcher = createMatcherFromYaml(yaml_string); + EXPECT_EQ(matcher->uriTemplate(), "/bar/{lang}/{country=**}"); + EXPECT_EQ(matcher->name(), "envoy.path.match.uri_template.uri_template_matcher"); + + EXPECT_TRUE(matcher->match("/bar/en/us*")); +} + +TEST(MatchTest, MatchDoubleAsteriskInWildcard) { + const std::string yaml_string = R"EOF( + name: envoy.path.match.uri_template.uri_template_matcher + typed_config: + "@type": type.googleapis.com/envoy.extensions.path.match.uri_template.v3.UriTemplateMatchConfig + path_template: "/bar/{lang}/{country=**}" +)EOF"; + + Router::PathMatcherSharedPtr matcher = createMatcherFromYaml(yaml_string); + EXPECT_EQ(matcher->uriTemplate(), "/bar/{lang}/{country=**}"); + EXPECT_EQ(matcher->name(), "envoy.path.match.uri_template.uri_template_matcher"); + + EXPECT_TRUE(matcher->match("/bar/en/us**")); +} + +TEST(MatchTest, MatchSingleAsterisk) { + const std::string yaml_string = R"EOF( + name: envoy.path.match.uri_template.uri_template_matcher + typed_config: + "@type": type.googleapis.com/envoy.extensions.path.match.uri_template.v3.UriTemplateMatchConfig + path_template: "/bar/{lang}/{country=**}" +)EOF"; + + Router::PathMatcherSharedPtr matcher = createMatcherFromYaml(yaml_string); + EXPECT_EQ(matcher->uriTemplate(), "/bar/{lang}/{country=**}"); + EXPECT_EQ(matcher->name(), "envoy.path.match.uri_template.uri_template_matcher"); + + EXPECT_TRUE(matcher->match("/bar/en*/us")); +} + +TEST(MatchTest, MatchDoubleAsterisk) { + const std::string yaml_string = R"EOF( + name: envoy.path.match.uri_template.uri_template_matcher + typed_config: + "@type": type.googleapis.com/envoy.extensions.path.match.uri_template.v3.UriTemplateMatchConfig + path_template: "/bar/{lang}/{country=**}" +)EOF"; + + Router::PathMatcherSharedPtr matcher = createMatcherFromYaml(yaml_string); + EXPECT_EQ(matcher->uriTemplate(), "/bar/{lang}/{country=**}"); + EXPECT_EQ(matcher->name(), "envoy.path.match.uri_template.uri_template_matcher"); + + EXPECT_TRUE(matcher->match("/bar/en**/us")); +} + TEST(MatchTest, MatchDoubleEqualsInWildcard) { const std::string yaml_string = R"EOF( name: envoy.path.match.uri_template.uri_template_matcher diff --git a/test/extensions/path/rewrite/uri_template/library_test.cc b/test/extensions/path/rewrite/uri_template/library_test.cc index 6d34771872..4783b8725f 100644 --- a/test/extensions/path/rewrite/uri_template/library_test.cc +++ b/test/extensions/path/rewrite/uri_template/library_test.cc @@ -71,6 +71,62 @@ TEST(RewriteTest, BasicUsage) { EXPECT_EQ(rewriter->name(), "envoy.path.rewrite.uri_template.uri_template_rewriter"); } +TEST(RewriteTest, SingleAsteriskAtEndOfPath) { + const std::string yaml_string = R"EOF( + name: envoy.path.rewrite.uri_template.uri_template_rewriter + typed_config: + "@type": type.googleapis.com/envoy.extensions.path.rewrite.uri_template.v3.UriTemplateRewriteConfig + path_template_rewrite: "/bar/{country}/{final}" +)EOF"; + + Router::PathRewriterSharedPtr rewriter = createRewriterFromYaml(yaml_string); + EXPECT_EQ(rewriter->rewritePath("/bar/usa/final*1", "/bar/{final}/{country}").value(), + "/bar/final*1/usa"); + EXPECT_EQ(rewriter->name(), "envoy.path.rewrite.uri_template.uri_template_rewriter"); +} + +TEST(RewriteTest, SingleAsterisk) { + const std::string yaml_string = R"EOF( + name: envoy.path.rewrite.uri_template.uri_template_rewriter + typed_config: + "@type": type.googleapis.com/envoy.extensions.path.rewrite.uri_template.v3.UriTemplateRewriteConfig + path_template_rewrite: "/bar/{country}/final" +)EOF"; + + Router::PathRewriterSharedPtr rewriter = createRewriterFromYaml(yaml_string); + EXPECT_EQ(rewriter->rewritePath("/bar/usa*/final", "/bar/{country}/final").value(), + "/bar/usa*/final"); + EXPECT_EQ(rewriter->name(), "envoy.path.rewrite.uri_template.uri_template_rewriter"); +} + +TEST(RewriteTest, DoubleAsteriskAtEndOfPath) { + const std::string yaml_string = R"EOF( + name: envoy.path.rewrite.uri_template.uri_template_rewriter + typed_config: + "@type": type.googleapis.com/envoy.extensions.path.rewrite.uri_template.v3.UriTemplateRewriteConfig + path_template_rewrite: "/bar/{country}/{final}" +)EOF"; + + Router::PathRewriterSharedPtr rewriter = createRewriterFromYaml(yaml_string); + EXPECT_EQ(rewriter->rewritePath("/bar/usa/final**1", "/bar/{final}/{country}").value(), + "/bar/final**1/usa"); + EXPECT_EQ(rewriter->name(), "envoy.path.rewrite.uri_template.uri_template_rewriter"); +} + +TEST(RewriteTest, DoubleAsterisk) { + const std::string yaml_string = R"EOF( + name: envoy.path.rewrite.uri_template.uri_template_rewriter + typed_config: + "@type": type.googleapis.com/envoy.extensions.path.rewrite.uri_template.v3.UriTemplateRewriteConfig + path_template_rewrite: "/bar/{country}/final" +)EOF"; + + Router::PathRewriterSharedPtr rewriter = createRewriterFromYaml(yaml_string); + EXPECT_EQ(rewriter->rewritePath("/bar/usa**/final", "/bar/{country}/final").value(), + "/bar/usa**/final"); + EXPECT_EQ(rewriter->name(), "envoy.path.rewrite.uri_template.uri_template_rewriter"); +} + TEST(RewriteTest, DoubleEqualAtEndOfPath) { const std::string yaml_string = R"EOF( name: envoy.path.rewrite.uri_template.uri_template_rewriter diff --git a/test/extensions/path/uri_template_lib/BUILD b/test/extensions/path/uri_template_lib/BUILD index f06fb8d100..f30d748afc 100644 --- a/test/extensions/path/uri_template_lib/BUILD +++ b/test/extensions/path/uri_template_lib/BUILD @@ -31,6 +31,7 @@ envoy_cc_test( deps = [ "//source/extensions/path/uri_template_lib:uri_template_internal_cc", "//test/test_common:status_utility_lib", + "//test/test_common:test_runtime_lib", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", diff --git a/test/extensions/path/uri_template_lib/uri_template_internal_test.cc b/test/extensions/path/uri_template_lib/uri_template_internal_test.cc index 254eef55ee..6ac17fe517 100644 --- a/test/extensions/path/uri_template_lib/uri_template_internal_test.cc +++ b/test/extensions/path/uri_template_lib/uri_template_internal_test.cc @@ -11,6 +11,7 @@ #include "test/test_common/logging.h" #include "test/test_common/status_utility.h" +#include "test/test_common/test_runtime.h" #include "test/test_common/utility.h" #include "absl/strings/str_cat.h" @@ -29,6 +30,10 @@ namespace { using ::Envoy::StatusHelpers::StatusIs; TEST(InternalParsing, ParsedPathDebugString) { + TestScopedRuntime scoped_runtime; + scoped_runtime.mergeValues( + {{"envoy.reloadable_features.uri_template_match_on_asterisk", "true"}}); + ParsedPathPattern patt1 = { { "abc", @@ -49,14 +54,23 @@ TEST(InternalParsing, ParsedPathDebugString) { EXPECT_EQ(patt2.debugString(), "/{var}"); } +TEST(InternalParsing, IsValidLiteralAsteriskDisabled) { + TestScopedRuntime scoped_runtime; + scoped_runtime.mergeValues( + {{"envoy.reloadable_features.uri_template_match_on_asterisk", "false"}}); + + EXPECT_FALSE(isValidLiteral("ab*c")); + EXPECT_FALSE(isValidLiteral("a**c")); +} + TEST(InternalParsing, IsValidLiteralWorks) { EXPECT_TRUE(isValidLiteral("123abcABC")); EXPECT_TRUE(isValidLiteral("._~-")); EXPECT_TRUE(isValidLiteral("-._~%20!$&'()+,;:@")); EXPECT_FALSE(isValidLiteral("`~!@#$%^&()-_+;:,<.>'\"\\| ")); EXPECT_FALSE(isValidLiteral("abc/")); - EXPECT_FALSE(isValidLiteral("ab*c")); - EXPECT_FALSE(isValidLiteral("a**c")); + EXPECT_TRUE(isValidLiteral("ab*c")); + EXPECT_TRUE(isValidLiteral("a**c")); EXPECT_TRUE(isValidLiteral("a=c")); EXPECT_FALSE(isValidLiteral("?abc")); EXPECT_FALSE(isValidLiteral("?a=c")); @@ -65,6 +79,14 @@ TEST(InternalParsing, IsValidLiteralWorks) { EXPECT_FALSE(isValidLiteral("{abc}")); } +TEST(InternalParsing, IsValidRewriteAsteriskDisabled) { + TestScopedRuntime scoped_runtime; + scoped_runtime.mergeValues( + {{"envoy.reloadable_features.uri_template_match_on_asterisk", "false"}}); + + EXPECT_FALSE(isValidRewriteLiteral("a*c")); +} + TEST(InternalParsing, IsValidRewriteLiteralWorks) { EXPECT_TRUE(isValidRewriteLiteral("123abcABC")); EXPECT_TRUE(isValidRewriteLiteral("abc/")); @@ -76,6 +98,7 @@ TEST(InternalParsing, IsValidRewriteLiteralWorks) { EXPECT_FALSE(isValidRewriteLiteral("ab}c")); EXPECT_FALSE(isValidRewriteLiteral("ab{c")); EXPECT_TRUE(isValidRewriteLiteral("a=c")); + EXPECT_TRUE(isValidRewriteLiteral("a*c")); EXPECT_FALSE(isValidRewriteLiteral("?a=c")); } @@ -151,7 +174,7 @@ class ParseVariableFailure : public testing::TestWithParam {}; INSTANTIATE_TEST_SUITE_P(ParseVariableFailureTestSuite, ParseVariableFailure, testing::Values("{var", "{=abc}", "{_var=*}", "{1v}", "{1v=abc}", - "{var=***}", "{v-a-r}", "{var=*/abc?q=1}", "{var=abc/a*}", + "{var=***}", "{v-a-r}", "{var=*/abc?q=1}", "{var=*def/abc}", "{var=}", "{rc=||||(A+yl/}", "/")); TEST_P(ParseVariableFailure, ParseVariableFailureTest) { @@ -190,15 +213,13 @@ class ParsePathPatternSyntaxFailure : public testing::TestWithParam INSTANTIATE_TEST_SUITE_P( ParsePathPatternSyntaxFailureTestSuite, ParsePathPatternSyntaxFailure, - testing::Values("/api/v*/1234", "/api/{version=v*}/1234", "/api/v{versionNum=*}/1234", - "/api/{version=*beta}/1234", "/media/eff456/ll-sd-out.{ext}", - "/media/eff456/ll-sd-out.{ext=*}", "/media/eff456/ll-sd-out.**", - "/media/{country=**}/{lang=*}/**", "/media/**/*/**", "/link/{id=*}/asset*", - "/link/{id=*}/{asset=asset*}", "/media/{id=/*}/*", "/media/{contentId=/**}", - "/api/{version}/{version}", "/api/{version.major}/{version.minor}", - "/media/***", "/media/*{*}*", "/media/{*}/", "/media/*/index?a=2", "media", - "/\001\002\003\004\005\006\007", "/*(/**", "/**/{var}", - "/{var1}/{var2}/{var3}/{var4}/{var5}/{var6}", "/{=*}", + testing::Values("/api/v{versionNum=*}/1234", "/api/{version=*beta}/1234", + "/media/eff456/ll-sd-out.{ext}", "/media/eff456/ll-sd-out.{ext=*}", + "/media/{country=**}/{lang=*}/**", "/media/**/*/**", "/media/{id=/*}/*", + "/media/{contentId=/**}", "/api/{version}/{version}", + "/api/{version.major}/{version.minor}", "/media/*{*}*", "/media/{*}/", + "/media/*/index?a=2", "media", "/\001\002\003\004\005\006\007", "/*(/**", + "/**/{var}", "/{var1}/{var2}/{var3}/{var4}/{var5}/{var6}", "/{=*}", "/{var12345678901234=*}")); TEST_P(ParsePathPatternSyntaxFailure, ParsePathPatternSyntaxFailureTest) { @@ -267,34 +288,43 @@ TEST(InternalRegexGen, DollarSignMatchesIfself) { EXPECT_FALSE(RE2::FullMatch("abc", toRegexPattern("abc$"))); } -TEST(InternalRegexGen, OperatorRegexPattern) { +TEST(InternalRegexGen, OperatorRegexPatternAsteriskDisabled) { + TestScopedRuntime scoped_runtime; + scoped_runtime.mergeValues( + {{"envoy.reloadable_features.uri_template_match_on_asterisk", "false"}}); + EXPECT_EQ(toRegexPattern(Operator::PathGlob), "[a-zA-Z0-9-._~%!$&'()+,;:@=]+"); EXPECT_EQ(toRegexPattern(Operator::TextGlob), "[a-zA-Z0-9-._~%!$&'()+,;:@=/]*"); } +TEST(InternalRegexGen, OperatorRegexPattern) { + EXPECT_EQ(toRegexPattern(Operator::PathGlob), "[a-zA-Z0-9-._~%!$&'()+,;:@=*]+"); + EXPECT_EQ(toRegexPattern(Operator::TextGlob), "[a-zA-Z0-9-._~%!$&'()+,;:@=*/]*"); +} + TEST(InternalRegexGen, PathGlobRegex) { EXPECT_TRUE(RE2::FullMatch("abc.123", toRegexPattern(Operator::PathGlob))); EXPECT_FALSE(RE2::FullMatch("", toRegexPattern(Operator::PathGlob))); EXPECT_FALSE(RE2::FullMatch("abc/123", toRegexPattern(Operator::PathGlob))); - EXPECT_FALSE(RE2::FullMatch("*", toRegexPattern(Operator::PathGlob))); - EXPECT_FALSE(RE2::FullMatch("**", toRegexPattern(Operator::PathGlob))); - EXPECT_FALSE(RE2::FullMatch("abc*123", toRegexPattern(Operator::PathGlob))); + EXPECT_TRUE(RE2::FullMatch("*", toRegexPattern(Operator::PathGlob))); + EXPECT_TRUE(RE2::FullMatch("**", toRegexPattern(Operator::PathGlob))); + EXPECT_TRUE(RE2::FullMatch("abc*123", toRegexPattern(Operator::PathGlob))); } TEST(InternalRegexGen, TextGlobRegex) { EXPECT_TRUE(RE2::FullMatch("abc.123", toRegexPattern(Operator::TextGlob))); EXPECT_TRUE(RE2::FullMatch("", toRegexPattern(Operator::TextGlob))); EXPECT_TRUE(RE2::FullMatch("abc/123", toRegexPattern(Operator::TextGlob))); - EXPECT_FALSE(RE2::FullMatch("*", toRegexPattern(Operator::TextGlob))); - EXPECT_FALSE(RE2::FullMatch("**", toRegexPattern(Operator::TextGlob))); - EXPECT_FALSE(RE2::FullMatch("abc*123", toRegexPattern(Operator::TextGlob))); + EXPECT_TRUE(RE2::FullMatch("*", toRegexPattern(Operator::TextGlob))); + EXPECT_TRUE(RE2::FullMatch("**", toRegexPattern(Operator::TextGlob))); + EXPECT_TRUE(RE2::FullMatch("abc*123", toRegexPattern(Operator::TextGlob))); } TEST(InternalRegexGen, VariableRegexPattern) { - EXPECT_EQ(toRegexPattern(Variable("var1", {})), "(?P[a-zA-Z0-9-._~%!$&'()+,;:@=]+)"); + EXPECT_EQ(toRegexPattern(Variable("var1", {})), "(?P[a-zA-Z0-9-._~%!$&'()+,;:@=*]+)"); EXPECT_EQ(toRegexPattern(Variable("var2", {Operator::PathGlob, "abc", Operator::TextGlob})), - "(?P[a-zA-Z0-9-._~%!$&'()+,;:@=]+/abc/" - "[a-zA-Z0-9-._~%!$&'()+,;:@=/]*)"); + "(?P[a-zA-Z0-9-._~%!$&'()+,;:@=*]+/abc/" + "[a-zA-Z0-9-._~%!$&'()+,;:@=*/]*)"); } TEST(InternalRegexGen, VariableRegexDefaultMatch) { @@ -456,8 +486,7 @@ INSTANTIATE_TEST_SUITE_P(GenPatternRegexWithoutMatchTestSuite, GenPatternRegexWi {"/media/eff456/ll-sd-out.js", "/media/*"}, {"/api/v1/1234/", "/api/*/v1/*"}, {"/api/v1/1234/broadcasts/get", "/api/*/{resource=*}/{method=*}"}, - {"/api/v1/1234/", "/api/*/v1/**"}, - {"/api/*/1234/", "/api/*/1234/"}}))); + {"/api/v1/1234/", "/api/*/v1/**"}}))); TEST_P(GenPatternRegexWithoutMatch, WithCapture) { absl::StatusOr pattern = parsePathPatternSyntax(pathPattern()); diff --git a/test/extensions/path/uri_template_lib/uri_template_test.cc b/test/extensions/path/uri_template_lib/uri_template_test.cc index f019c7c301..8939850bd8 100644 --- a/test/extensions/path/uri_template_lib/uri_template_test.cc +++ b/test/extensions/path/uri_template_lib/uri_template_test.cc @@ -33,22 +33,18 @@ static constexpr absl::string_view kCaptureRegex = "/(?P[a-zA-Z0-9-._~%!$& TEST(ConvertPathPattern, ValidPattern) { EXPECT_THAT(convertPathPatternSyntaxToRegex("/abc"), IsOkAndHolds("/abc")); EXPECT_THAT(convertPathPatternSyntaxToRegex("/**.mpd"), - IsOkAndHolds("/[a-zA-Z0-9-._~%!$&'()+,;:@=/]*\\.mpd")); + IsOkAndHolds("/[a-zA-Z0-9-._~%!$&'()+,;:@=*/]*\\.mpd")); EXPECT_THAT(convertPathPatternSyntaxToRegex("/api/*/{resource=*}/{method=**}"), - IsOkAndHolds("/api/[a-zA-Z0-9-._~%!$&'()+,;:@=]+/" - "(?P[a-zA-Z0-9-._~%!$&'()+,;:@=]+)/" - "(?P[a-zA-Z0-9-._~%!$&'()+,;:@=/]*)")); + IsOkAndHolds("/api/[a-zA-Z0-9-._~%!$&'()+,;:@=*]+/" + "(?P[a-zA-Z0-9-._~%!$&'()+,;:@=*]+)/" + "(?P[a-zA-Z0-9-._~%!$&'()+,;:@=*/]*)")); EXPECT_THAT(convertPathPatternSyntaxToRegex("/api/{VERSION}/{version}/{verSION}"), - IsOkAndHolds("/api/(?P[a-zA-Z0-9-._~%!$&'()+,;:@=]+)/" - "(?P[a-zA-Z0-9-._~%!$&'()+,;:@=]+)/" - "(?P[a-zA-Z0-9-._~%!$&'()+,;:@=]+)")); + IsOkAndHolds("/api/(?P[a-zA-Z0-9-._~%!$&'()+,;:@=*]+)/" + "(?P[a-zA-Z0-9-._~%!$&'()+,;:@=*]+)/" + "(?P[a-zA-Z0-9-._~%!$&'()+,;:@=*]+)")); } TEST(ConvertPathPattern, InvalidPattern) { - EXPECT_THAT(convertPathPatternSyntaxToRegex("/api/v*/1234"), - StatusIs(absl::StatusCode::kInvalidArgument)); - EXPECT_THAT(convertPathPatternSyntaxToRegex("/media/**/*/**"), - StatusIs(absl::StatusCode::kInvalidArgument)); EXPECT_THAT(convertPathPatternSyntaxToRegex("/\001\002\003\004\005\006\007"), StatusIs(absl::StatusCode::kInvalidArgument)); EXPECT_THAT(convertPathPatternSyntaxToRegex("/{var12345678901234=*}"), diff --git a/tools/spelling/spelling_dictionary.txt b/tools/spelling/spelling_dictionary.txt index e3b18eef44..c11e308cff 100644 --- a/tools/spelling/spelling_dictionary.txt +++ b/tools/spelling/spelling_dictionary.txt @@ -774,6 +774,8 @@ enqueues enum enums environ +eu +euprod epoll errno etag @@ -1103,6 +1105,7 @@ pcall pcap pchar pclose +pdf performant pfctl pipelined From 18670bb151fe7c5eec313b101b437311232a3278 Mon Sep 17 00:00:00 2001 From: phlax Date: Mon, 5 May 2025 19:44:10 +0100 Subject: [PATCH 02/35] release/docker: Bump release image -> 67cadaf (#39344) Signed-off-by: Ryan Northey --- ci/Dockerfile-envoy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/Dockerfile-envoy b/ci/Dockerfile-envoy index 55a50d2954..f6c7aa3621 100644 --- a/ci/Dockerfile-envoy +++ b/ci/Dockerfile-envoy @@ -1,6 +1,6 @@ ARG BUILD_OS=ubuntu ARG BUILD_TAG=22.04 -ARG BUILD_SHA=d80997daaa3811b175119350d84305e1ec9129e1799bba0bd1e3120da3ff52c3 +ARG BUILD_SHA=67cadaff1dca187079fce41360d5a7eb6f7dcd3745e53c79ad5efd8563118240 ARG ENVOY_VRP_BASE_IMAGE=envoy-base From 72b864bd5d953ade0a17930288aa547d851294cb Mon Sep 17 00:00:00 2001 From: Ryan Northey Date: Tue, 6 May 2025 13:36:15 +0100 Subject: [PATCH 03/35] changelogs: Blank summary Signed-off-by: Ryan Northey --- changelogs/summary.md | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/changelogs/summary.md b/changelogs/summary.md index bf63efe854..e69de29bb2 100644 --- a/changelogs/summary.md +++ b/changelogs/summary.md @@ -1,38 +0,0 @@ -**Summary of changes**: - -* Security: - - [CVE-2025-30157](https://github.com/envoyproxy/envoy/security/advisories/GHSA-cf3q-gqg7-3fm9): Fixed a bug where local replies were incorrectly sent to the ext_proc server. - - [CVE-2025-31498](https://github.com/c-ares/c-ares/security/advisories/GHSA-6hxc-62jh-p29v): Updated c-ares to version 1.34.5 to address a security vulnerability. - -* HTTP: - - Added support for async load balancing, allowing endpoints to respond with their ability to handle requests. - - Improved HTTP/1 parser to handle newlines between requests correctly per RFC 9112. - - Added option to ignore specific HTTP/1.1 upgrade values using configurable matchers. - - Implemented TCP proxy option to read from downstream connections before establishing upstream connections. - -* Performance: - - Improved performance for HTTP/1 ignored upgrades. - - Enhanced TCP proxy retries to run in a different event loop iteration to avoid connection issues. - - Added fixed value option for minimum RTT in adaptive concurrency filter. - - Enhanced dynamic forward proxy with async lookups for null hosts. - -* Reliability: - - Fixed a bug in preconnecting logic that could lead to excessive connection establishment. - - Fixed port exhaustion issues in the original_src filter by setting the `IP_BIND_ADDRESS_NO_PORT` socket option. - - Fixed socket option application for additional listener addresses. - - Fixed crash when creating an EDS cluster with invalid configuration. - -* Features: - - Added support for loading shared libraries at runtime through dynamic modules. - - Added support for io_uring in the default socket interface. - - Extended the compression filter with the ability to skip compression for specific response codes. - - Added support for QUIC-LB draft standard for connection ID generation. - - Enhanced ext_proc with graceful gRPC side stream closing and added a new `FULL_DUPLEX_STREAMED` body mode. - - Introduced PKCE support for OAuth2 authorization code flow and SameSite cookie attribute configuration. - - Added support for monitoring container CPU utilization in Linux Kubernetes environments. - - Enhanced proxy protocol TLV support to enable more flexible and customizable usage between downstream and upstream connections. - - Added multiple formatter attributes improvements, e.g., `QUERY_PARAM`, `CUSTOM_FLAGS`, and `PATH` - -* Observability: - - Enhanced Transport Tap with connection information output per event. - - Added support for directing LRS to report loads when requests are issued. From c435eeccd4201f8d6a200922b166f5dcee08272b Mon Sep 17 00:00:00 2001 From: "publish-envoy[bot]" <140627008+publish-envoy[bot]@users.noreply.github.com> Date: Wed, 7 May 2025 19:01:39 +0000 Subject: [PATCH 04/35] repo: Release v1.34.1 **Docker images**: https://hub.docker.com/r/envoyproxy/envoy/tags?page=1&name=v1.34.1 **Docs**: https://www.envoyproxy.io/docs/envoy/v1.34.1/ **Release notes**: https://www.envoyproxy.io/docs/envoy/v1.34.1/version_history/v1.34/v1.34.1 **Full changelog**: https://github.com/envoyproxy/envoy/compare/v1.34.0...v1.34.1 --- VERSION.txt | 2 +- changelogs/1.31.8.yaml | 8 ++++++++ changelogs/1.32.6.yaml | 8 ++++++++ changelogs/1.33.3.yaml | 11 +++++++++++ changelogs/current.yaml | 16 +--------------- docs/inventories/v1.31/objects.inv | Bin 176078 -> 176110 bytes docs/inventories/v1.32/objects.inv | Bin 178905 -> 178947 bytes docs/inventories/v1.33/objects.inv | Bin 181412 -> 181472 bytes docs/inventories/v1.34/objects.inv | Bin 0 -> 186365 bytes docs/versions.yaml | 7 ++++--- 10 files changed, 33 insertions(+), 19 deletions(-) create mode 100644 changelogs/1.31.8.yaml create mode 100644 changelogs/1.32.6.yaml create mode 100644 changelogs/1.33.3.yaml create mode 100644 docs/inventories/v1.34/objects.inv diff --git a/VERSION.txt b/VERSION.txt index f7b9816f33..a95a46d9fa 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -1.34.1-dev +1.34.1 diff --git a/changelogs/1.31.8.yaml b/changelogs/1.31.8.yaml new file mode 100644 index 0000000000..1dcf25dd48 --- /dev/null +++ b/changelogs/1.31.8.yaml @@ -0,0 +1,8 @@ +date: May 7, 2025 + +bug_fixes: +- area: url_template + change: | + Included the asterisk ``*`` in the match pattern when using the * or ** operators in the URL template. + This behavioral change can be temporarily reverted by setting runtime guard + ``envoy.reloadable_features.uri_template_match_on_asterisk`` to ``false``. diff --git a/changelogs/1.32.6.yaml b/changelogs/1.32.6.yaml new file mode 100644 index 0000000000..1dcf25dd48 --- /dev/null +++ b/changelogs/1.32.6.yaml @@ -0,0 +1,8 @@ +date: May 7, 2025 + +bug_fixes: +- area: url_template + change: | + Included the asterisk ``*`` in the match pattern when using the * or ** operators in the URL template. + This behavioral change can be temporarily reverted by setting runtime guard + ``envoy.reloadable_features.uri_template_match_on_asterisk`` to ``false``. diff --git a/changelogs/1.33.3.yaml b/changelogs/1.33.3.yaml new file mode 100644 index 0000000000..4f04153d22 --- /dev/null +++ b/changelogs/1.33.3.yaml @@ -0,0 +1,11 @@ +date: May 7, 2025 + +bug_fixes: +- area: eds + change: | + Fixed crash when creating an EDS cluster with invalid configuration. +- area: url_template + change: | + Included the asterisk ``*`` in the match pattern when using the * or ** operators in the URL template. + This behavioral change can be temporarily reverted by setting runtime guard + ``envoy.reloadable_features.uri_template_match_on_asterisk`` to ``false``. diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 9416e93aaf..4f04153d22 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -1,13 +1,6 @@ -date: Pending - -behavior_changes: -# *Changes that are expected to cause an incompatibility if applicable; deployment changes are likely required* - -minor_behavior_changes: -# *Changes that may cause incompatibilities for some users, but should not for most* +date: May 7, 2025 bug_fixes: -# *Changes expected to improve the state of the world and are unlikely to have negative effects* - area: eds change: | Fixed crash when creating an EDS cluster with invalid configuration. @@ -16,10 +9,3 @@ bug_fixes: Included the asterisk ``*`` in the match pattern when using the * or ** operators in the URL template. This behavioral change can be temporarily reverted by setting runtime guard ``envoy.reloadable_features.uri_template_match_on_asterisk`` to ``false``. - -removed_config_or_runtime: -# *Normally occurs at the end of the* :ref:`deprecation period ` - -new_features: - -deprecated: diff --git a/docs/inventories/v1.31/objects.inv b/docs/inventories/v1.31/objects.inv index c46179507b09602c9ab3e5c55dff7fe673fd4da2..6d14e4127cbc1e6587d77b480f65dfa32e616967 100644 GIT binary patch delta 21868 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 E4^C?KRR910 delta 7028 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

wI$Psw_iV7+?{R`{Zb) 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

QqUn@o-fbIsR_(DT?rF=`rk`6KChXP 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 sY#dF`^V5+WesN{{dZdzL Date: Thu, 8 May 2025 10:03:34 +0000 Subject: [PATCH 05/35] repo: Dev v1.34.2 Signed-off-by: Ryan Northey --- VERSION.txt | 2 +- changelogs/1.34.1.yaml | 11 +++++++++++ changelogs/current.yaml | 24 +++++++++++++++--------- 3 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 changelogs/1.34.1.yaml diff --git a/VERSION.txt b/VERSION.txt index a95a46d9fa..785c88e718 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -1.34.1 +1.34.2-dev diff --git a/changelogs/1.34.1.yaml b/changelogs/1.34.1.yaml new file mode 100644 index 0000000000..4f04153d22 --- /dev/null +++ b/changelogs/1.34.1.yaml @@ -0,0 +1,11 @@ +date: May 7, 2025 + +bug_fixes: +- area: eds + change: | + Fixed crash when creating an EDS cluster with invalid configuration. +- area: url_template + change: | + Included the asterisk ``*`` in the match pattern when using the * or ** operators in the URL template. + This behavioral change can be temporarily reverted by setting runtime guard + ``envoy.reloadable_features.uri_template_match_on_asterisk`` to ``false``. diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 4f04153d22..9ecf0d6e48 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -1,11 +1,17 @@ -date: May 7, 2025 +date: Pending + +behavior_changes: +# *Changes that are expected to cause an incompatibility if applicable; deployment changes are likely required* + +minor_behavior_changes: +# *Changes that may cause incompatibilities for some users, but should not for most* bug_fixes: -- area: eds - change: | - Fixed crash when creating an EDS cluster with invalid configuration. -- area: url_template - change: | - Included the asterisk ``*`` in the match pattern when using the * or ** operators in the URL template. - This behavioral change can be temporarily reverted by setting runtime guard - ``envoy.reloadable_features.uri_template_match_on_asterisk`` to ``false``. +# *Changes expected to improve the state of the world and are unlikely to have negative effects* + +removed_config_or_runtime: +# *Normally occurs at the end of the* :ref:`deprecation period ` + +new_features: + +deprecated: From e9fb31fa22ac1bce2fe24d55810ab15f0fc4cf65 Mon Sep 17 00:00:00 2001 From: Greg Greenway Date: Mon, 12 May 2025 15:20:11 -0700 Subject: [PATCH 06/35] conn pool: fix bugs leading to incorrect conns created (#39446) Backport #39310 and #39349 If a connection starts draining while it has negative unused capacity (which happens if a SETTINGS frame reduces allowed concurrency to below the current number of requests), that connections unused capacity will be included in total pool capacity even though it is unusable because it is draining. This can result in not enough connections being established for current pending requests. This is most problematic for long-lived requests (such as streaming gRPC requests or long-poll requests) because a connection could be in the draining state for a long time. Maybe fixes: #39238 Fixed an issue that could lead to too many connections when using :ref:`AutoHttpConfig ` if the established connection is ``http/2`` and Envoy predicted it would have lower concurrent capacity. --------- Signed-off-by: Greg Greenway --- changelogs/current.yaml | 13 ++++ source/common/conn_pool/conn_pool_base.cc | 18 +++-- source/common/http/mixed_conn_pool.cc | 4 +- test/common/http/http2/conn_pool_test.cc | 91 +++++++++++++++++++++++ test/common/http/mixed_conn_pool_test.cc | 12 +++ 5 files changed, 131 insertions(+), 7 deletions(-) diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 9ecf0d6e48..a976d411ae 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -8,6 +8,19 @@ minor_behavior_changes: bug_fixes: # *Changes expected to improve the state of the world and are unlikely to have negative effects* +- area: conn_pool + change: | + Fixed an issue that could lead to too many connections when using + :ref:`AutoHttpConfig ` if the + established connection is ``http/2`` and Envoy predicted it would have lower concurrent capacity. +- area: conn_pool + change: | + Fixed an issue that could lead to insufficient connections for current pending requests. If a connection starts draining while it + has negative unused capacity (which happens if an HTTP/2 ``SETTINGS`` frame reduces allowed concurrency to below the current number + of requests), that connection's unused capacity will be included in total pool capacity even though it is unusable because it is + draining. This can result in not enough connections being established for current pending requests. This is most problematic for + long-lived requests (such as streaming gRPC requests or long-poll requests) because a connection could be in the draining state + for a long time. removed_config_or_runtime: # *Normally occurs at the end of the* :ref:`deprecation period ` diff --git a/source/common/conn_pool/conn_pool_base.cc b/source/common/conn_pool/conn_pool_base.cc index bae03d93eb..3d10ba0931 100644 --- a/source/common/conn_pool/conn_pool_base.cc +++ b/source/common/conn_pool/conn_pool_base.cc @@ -261,7 +261,7 @@ void ConnPoolImplBase::onStreamClosed(Envoy::ConnectionPool::ActiveClient& clien // We don't update the capacity for HTTP/3 as the stream count should only // increase when a MAX_STREAMS frame is received. if (trackStreamCapacity()) { - // If the effective client capacity was limited by concurrency, increase connecting capacity. + // If the effective client capacity was limited by concurrency, increase connected capacity. bool limited_by_concurrency = client.remaining_streams_ > client.concurrent_stream_limit_ - client.numActiveStreams() - 1; // The capacity calculated by concurrency could be negative if a SETTINGS frame lowered the @@ -878,12 +878,20 @@ void ActiveClient::onConnectionDurationTimeout() { } void ActiveClient::drain() { - if (currentUnusedCapacity() <= 0) { - return; - } - parent_.decrConnectingAndConnectedStreamCapacity(currentUnusedCapacity(), *this); + const int64_t unused = currentUnusedCapacity(); + // Remove draining client's capacity from the pool. + // + // The code that adds capacity back to the pool in `onStreamClosed` will only add it back if + // it sees the connection as currently limited by concurrent capacity, not total lifetime streams. + // Setting this to zero ensures that the `limited_by_concurrency` check does not detect this + // connection as limited for that reason, because it is now being marked as having zero remaining + // lifetime requests. remaining_streams_ = 0; + + if (unused > 0) { + parent_.decrConnectingAndConnectedStreamCapacity(unused, *this); + } } } // namespace ConnectionPool diff --git a/source/common/http/mixed_conn_pool.cc b/source/common/http/mixed_conn_pool.cc index fbe7684dea..7869073697 100644 --- a/source/common/http/mixed_conn_pool.cc +++ b/source/common/http/mixed_conn_pool.cc @@ -86,8 +86,8 @@ void HttpConnPoolImplMixed::onConnected(Envoy::ConnectionPool::ActiveClient& cli // it to reflect any difference between the TCP stream limits and HTTP/2 // stream limits. if (new_client->effectiveConcurrentStreamLimit() > old_effective_limit) { - state_.incrConnectingAndConnectedStreamCapacity(new_client->effectiveConcurrentStreamLimit() - - old_effective_limit); + incrConnectingAndConnectedStreamCapacity( + new_client->effectiveConcurrentStreamLimit() - old_effective_limit, client); } new_client->setState(ActiveClient::State::Connecting); LinkedList::moveIntoList(std::move(new_client), owningList(new_client->state())); diff --git a/test/common/http/http2/conn_pool_test.cc b/test/common/http/http2/conn_pool_test.cc index 9df8814a06..80bfeefa45 100644 --- a/test/common/http/http2/conn_pool_test.cc +++ b/test/common/http/http2/conn_pool_test.cc @@ -1805,6 +1805,97 @@ TEST_F(Http2ConnPoolImplTest, TestUnusedCapacity) { CHECK_STATE(0 /*active*/, 0 /*pending*/, 0 /*capacity*/); } +TEST_F(Http2ConnPoolImplTest, TestNegativeUnusedCapacity) { + cluster_->http2_options_.mutable_max_concurrent_streams()->set_value(4); + + expectClientsCreate(2); + ActiveTestRequest r1(*this, 0, false); + CHECK_STATE(0 /*active*/, 1 /*pending*/, 4 /*capacity*/); + expectClientConnect(0, r1); + CHECK_STATE(1 /*active*/, 0 /*pending*/, 3 /*capacity*/); + + ActiveTestRequest r2(*this, 0, true); + ActiveTestRequest r3(*this, 0, true); + CHECK_STATE(3 /*active*/, 0 /*pending*/, 1 /*capacity*/); + + // Settings frame results in negative unused capacity. + NiceMock settings; + settings.max_concurrent_streams_ = 1; + test_clients_[0].codec_client_->onSettings(settings); + CHECK_STATE(3 /*active*/, 0 /*pending*/, -2 /*capacity*/); + + completeRequest(r1); + CHECK_STATE(2 /*active*/, 0 /*pending*/, -1 /*capacity*/); + + // With negative capacity, verify that a new request creates a new connection. + ActiveTestRequest r4(*this, 1, false); + CHECK_STATE(2 /*active*/, 1 /*pending*/, 3 /*capacity*/); + expectClientConnect(1, r4); + CHECK_STATE(3 /*active*/, 0 /*pending*/, 2 /*capacity*/); + + completeRequest(r2); + CHECK_STATE(2 /*active*/, 0 /*pending*/, 3 /*capacity*/); + + completeRequest(r3); + CHECK_STATE(1 /*active*/, 0 /*pending*/, 4 /*capacity*/); + + completeRequest(r4); + CHECK_STATE(0 /*active*/, 0 /*pending*/, 5 /*capacity*/); + + // Clean up with an outstanding stream. + pool_->drainConnections(Envoy::ConnectionPool::DrainBehavior::DrainExistingConnections); + closeAllClients(); + CHECK_STATE(0 /*active*/, 0 /*pending*/, 0 /*capacity*/); +} + +TEST_F(Http2ConnPoolImplTest, TestDrainingNegativeUnusedCapacity) { + cluster_->http2_options_.mutable_max_concurrent_streams()->set_value(4); + + expectClientsCreate(2); + ActiveTestRequest r1(*this, 0, false); + CHECK_STATE(0 /*active*/, 1 /*pending*/, 4 /*capacity*/); + expectClientConnect(0, r1); + CHECK_STATE(1 /*active*/, 0 /*pending*/, 3 /*capacity*/); + + ActiveTestRequest r2(*this, 0, true); + ActiveTestRequest r3(*this, 0, true); + CHECK_STATE(3 /*active*/, 0 /*pending*/, 1 /*capacity*/); + + // Settings frame results in negative unused capacity. + NiceMock settings; + settings.max_concurrent_streams_ = 2; + test_clients_[0].codec_client_->onSettings(settings); + CHECK_STATE(3 /*active*/, 0 /*pending*/, -1 /*capacity*/); + + // Clean up with an outstanding stream. + pool_->drainConnections(Envoy::ConnectionPool::DrainBehavior::DrainExistingConnections); + + completeRequest(r1); + CHECK_STATE(2 /*active*/, 0 /*pending*/, 0 /*capacity*/); + + // With negative capacity, verify that a new request creates a new connection. + ActiveTestRequest r4(*this, 1, false); + CHECK_STATE(2 /*active*/, 1 /*pending*/, 4 /*capacity*/); + expectClientConnect(1, r4); + CHECK_STATE(3 /*active*/, 0 /*pending*/, 3 /*capacity*/); + + // Completing this request does NOT add more capacity because the connection is + // draining, and that connection's capacity is no longer negative. + completeRequest(r2); + CHECK_STATE(2 /*active*/, 0 /*pending*/, 3 /*capacity*/); + + // After r3 completes, the draining connection should close. + EXPECT_CALL(*this, onClientDestroy()); + completeRequest(r3); + dispatcher_.clearDeferredDeleteList(); + CHECK_STATE(1 /*active*/, 0 /*pending*/, 3 /*capacity*/); + + completeRequest(r4); + CHECK_STATE(0 /*active*/, 0 /*pending*/, 4 /*capacity*/); + + closeClient(1); +} + TEST_F(Http2ConnPoolImplTest, TestStateWithMultiplexing) { cluster_->http2_options_.mutable_max_concurrent_streams()->set_value(2); cluster_->max_requests_per_connection_ = 4; diff --git a/test/common/http/mixed_conn_pool_test.cc b/test/common/http/mixed_conn_pool_test.cc index 8c8c097791..69bb7f6f0e 100644 --- a/test/common/http/mixed_conn_pool_test.cc +++ b/test/common/http/mixed_conn_pool_test.cc @@ -114,6 +114,18 @@ TEST_F(MixedConnPoolImplTest, HandshakeWithCachedLimit) { testAlpnHandshake({}); } +// Test that increasing the limit upon connect, versus what was in the cache before connection, +// works correctly. +TEST_F(MixedConnPoolImplTest, HandshakeWithCachedLimitAndEffectiveIncrease) { + expected_capacity_ = 1; + + // This simulates a previous connection being http 1. + EXPECT_CALL(mock_cache_, getConcurrentStreams(_)).WillOnce(Return(1)); + + // This makes the new connection http 2, which has more than 1 stream available. + testAlpnHandshake(Protocol::Http2); +} + TEST_F(MixedConnPoolImplTest, HandshakeWithCachedLimitCapped) { EXPECT_CALL(mock_cache_, getConcurrentStreams(_)) .WillOnce(Return(std::numeric_limits::max())); From 531355645afae543636c3d89a4cdd96a9520429c Mon Sep 17 00:00:00 2001 From: Ryan Northey Date: Wed, 11 Jun 2025 09:16:34 +0100 Subject: [PATCH 07/35] ci/coverage: Fix path Signed-off-by: Ryan Northey --- test/run_envoy_bazel_coverage.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/run_envoy_bazel_coverage.sh b/test/run_envoy_bazel_coverage.sh index 1c436572de..53fe4e27d0 100755 --- a/test/run_envoy_bazel_coverage.sh +++ b/test/run_envoy_bazel_coverage.sh @@ -113,13 +113,13 @@ else cp bazel-out/_coverage/_coverage_report.dat "${COVERAGE_DATA}" fi -COVERAGE_VALUE="$(genhtml --prefix "${PWD}" --output "${COVERAGE_DIR}" "${COVERAGE_DATA}" | tee /dev/stderr | grep lines... | cut -d ' ' -f 4)" +COVERAGE_VALUE="$(genhtml --prefix "${PWD}" --output "${COVERAGE_DIR}/html" "${COVERAGE_DATA}" | tee /dev/stderr | grep lines... | cut -d ' ' -f 4)" COVERAGE_VALUE=${COVERAGE_VALUE%?} echo "Compressing coveraged data" if [[ "${FUZZ_COVERAGE}" == "true" ]]; then if [[ -n "${ENVOY_FUZZ_COVERAGE_ARTIFACT}" ]]; then - tar cf - -C "${COVERAGE_DIR}" --transform 's/^\./fuzz_coverage/' . \ + tar cf - -C "${COVERAGE_DIR}/html" --transform 's/^\./fuzz_coverage/' . \ | bazel run "${BAZEL_BUILD_OPTIONS[@]}" //tools/zstd -- \ - -T0 -o "${ENVOY_FUZZ_COVERAGE_ARTIFACT}" fi @@ -128,7 +128,7 @@ elif [[ -n "${ENVOY_COVERAGE_ARTIFACT}" ]]; then rm "${ENVOY_COVERAGE_ARTIFACT}" fi - tar cf - -C "${COVERAGE_DIR}" --transform 's/^\./coverage/' . \ + tar cf - -C "${COVERAGE_DIR}/html" --transform 's/^\./coverage/' . \ | bazel run "${BAZEL_BUILD_OPTIONS[@]}" //tools/zstd -- \ - -T0 -o "${ENVOY_COVERAGE_ARTIFACT}" fi @@ -168,4 +168,4 @@ if [[ -e ./test/per_file_coverage.sh ]]; then else echo "No per-file-coverage file found" fi -echo "HTML coverage report is in ${COVERAGE_DIR}/index.html" +echo "HTML coverage report is in ${COVERAGE_DIR}/html/index.html" From 516ad5f0846f04ba17d7ebfa2af14fe3e897f024 Mon Sep 17 00:00:00 2001 From: "Krinkin, Mike" Date: Tue, 6 May 2025 13:25:27 +0100 Subject: [PATCH 08/35] Link test binaries statically when run coverage (#39354) Static linking helps to work around the issue with LLVM/Clang source-based coverage (see https://github.com/llvm/llvm-project/issues/32849). On the flip side, the coverage build and test run will take a bit longer (e.g., around 30m) with this change. This PR switches to static linking for just test coverage and does not do the same for fuzz coverage. That's because Envoy CI is hitting some resource constraints when building fuzz targets with coverage instrumentation. We will fix that by striping the fuzz targets of some unncessary dependencies and switching to EngFlow backend for coverage builds and tests, but that will require addressing a couple of hard to understand issues, so, for now, I'm just switching the coverage tests to static linking and will follow up with the fuzz tests later once we addressed all the blockers and switched to EngFlow backend for coverage. Additional Description: https://github.com/envoyproxy/envoy/pull/39030 provides some context for EngFlow migration and https://github.com/envoyproxy/envoy/issues/39248 is a tracking bug. Signed-off-by: Mikhail Krinkin Signed-off-by: Ryan Northey --- .bazelrc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.bazelrc b/.bazelrc index 51f693e143..72a40d24d1 100644 --- a/.bazelrc +++ b/.bazelrc @@ -245,7 +245,6 @@ build:coverage --action_env=GCOV=llvm-profdata build:coverage --copt=-DNDEBUG # 1.5x original timeout + 300s for trace merger in all categories build:coverage --test_timeout=390,750,1500,5700 -build:coverage --define=dynamic_link_tests=true build:coverage --define=ENVOY_CONFIG_COVERAGE=1 build:coverage --cxxopt="-DENVOY_CONFIG_COVERAGE=1" build:coverage --test_env=HEAPCHECK= @@ -268,9 +267,11 @@ build:coverage --test_env=ENVOY_IP_TEST_VERSIONS=v4only build:test-coverage --test_arg="-l trace" build:test-coverage --test_arg="--log-path /dev/null" build:test-coverage --test_tag_filters=-nocoverage,-fuzz_target +build:test-coverage --define=dynamic_link_tests=false build:fuzz-coverage --config=plain-fuzzer build:fuzz-coverage --run_under=@envoy//bazel/coverage:fuzz_coverage_wrapper.sh build:fuzz-coverage --test_tag_filters=-nocoverage +build:fuzz-coverage --define=dynamic_link_tests=true build:cache-local --remote_cache=grpc://localhost:9092 From 40ffc3239b91fbb2fc65776c252fff7b07354f8a Mon Sep 17 00:00:00 2001 From: "Krinkin, Mike" Date: Thu, 22 May 2025 20:50:57 +0100 Subject: [PATCH 09/35] Don't build WASM for fuzz-coverage tests (#39296) Commit Message: Simple grep over the codebase suggests that we don't have any WASM specific fuzz tests defined. And existing fuzz tests don't need a full WASM runtime. On top of that in general we don't really want to fuzz test our dependencies (e.g., we would like the dependencies to have their own infrastructure and be scrupulous when new dependencies are added). Disabling WASM reduces the build time and resources required for fuzz-coverage. One particular reason to try and optimize fuzz-coverage is that I want to move it to static linking to work around a bug in Clang/LLVM (see https://github.com/llvm/llvm-project/issues/32849) and static linking produces much large binaries and requires a larger linker footprint, which currently hits the limits of the RBE backend used. Additional Description: Some relevant discussions can be found in https://github.com/envoyproxy/envoy/pull/39030 which prompted me to work on this in the first place. And I will use https://github.com/envoyproxy/envoy/issues/39248 as a tracking bug for the coverage changes. Risk Level: low Testing: running fuzz-coverage on local machine with the changes included, I also confirmed that disabling wasm + moving fuzz-coverage to EngFlow + removing explicit RBE pool attributes from fuzz targets make it possible to successfully statically link fuzz tests Docs Changes: n/a Release Notes: n/a Platform Specific Features: n/a --------- Signed-off-by: Mikhail Krinkin Signed-off-by: Ryan Northey --- .bazelrc | 4 ++++ test/server/BUILD | 1 - test/server/config_validation/BUILD | 1 - 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.bazelrc b/.bazelrc index 72a40d24d1..59dde27ad5 100644 --- a/.bazelrc +++ b/.bazelrc @@ -272,6 +272,10 @@ build:fuzz-coverage --config=plain-fuzzer build:fuzz-coverage --run_under=@envoy//bazel/coverage:fuzz_coverage_wrapper.sh build:fuzz-coverage --test_tag_filters=-nocoverage build:fuzz-coverage --define=dynamic_link_tests=true +# Existing fuzz tests don't need a full WASM runtime and in generally we don't really want to +# fuzz dependencies anyways. On the other hand, disabling WASM reduces the build time and +# resources required to build and run the tests. +build:fuzz-coverage --define=wasm=disabled build:cache-local --remote_cache=grpc://localhost:9092 diff --git a/test/server/BUILD b/test/server/BUILD index fac1ee7196..7eee64fc20 100644 --- a/test/server/BUILD +++ b/test/server/BUILD @@ -320,7 +320,6 @@ envoy_cc_fuzz_test( size = "large", srcs = ["server_fuzz_test.cc"], corpus = "server_corpus", - rbe_pool = "6gig", deps = [ "//source/common/thread_local:thread_local_lib", "//source/server:server_lib", diff --git a/test/server/config_validation/BUILD b/test/server/config_validation/BUILD index 7560e35268..3c9c1a5d04 100644 --- a/test/server/config_validation/BUILD +++ b/test/server/config_validation/BUILD @@ -93,7 +93,6 @@ envoy_cc_fuzz_test( size = "large", srcs = ["config_fuzz_test.cc"], corpus = "//test/server:server_fuzz_test_corpus", - rbe_pool = "6gig", deps = [ "//source/common/common:thread_lib", "//source/server/config_validation:server_lib", From 2ca6b2340f1f980140f7f1cf3789c13807dcb552 Mon Sep 17 00:00:00 2001 From: "Krinkin, Mike" Date: Fri, 23 May 2025 20:10:49 +0100 Subject: [PATCH 10/35] Use static linking for fuzz coverage CI targets (#39612) Static linking helps to work around the issue with LLVM/Clang source-based coverage (see llvm/llvm-project#32849). On the flip side, the coverage build and test run will take a bit longer with this change. We already did this change for the regular test coverage, but we delayed the switch for the fuzz coverage because fuzz coverage hit RBE backend resource constraints and was OOMing during linking. Since then we did a few things to mitigate the issue with resources: 1. We switched coverage runs from Google RBE backend to EngFlow which allows for somewhat larger workers 2. We started building fuzz targets without WASM - there are not fuzz targets that actually need a full WASM runtime and elimnating it speeds things up and reduces the footprint noticably. With the above two changes I think we are ready to completely switch to static linking for all coverage tests. It also has a benefit of better cache re-use since we will be linking both coverage and fuzz coverage targets statically. Additional Description: https://github.com/envoyproxy/envoy/pull/39030 provides some context for EngFlow migration and https://github.com/envoyproxy/envoy/issues/39248 is a tracking bug. Risk Level: low Testing: regular CI tests Docs Changes: n/a Release Notes: n/a Platform Specific Features: n/a Signed-off-by: Mikhail Krinkin Signed-off-by: Ryan Northey --- .bazelrc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.bazelrc b/.bazelrc index 59dde27ad5..db2f9b60a4 100644 --- a/.bazelrc +++ b/.bazelrc @@ -263,15 +263,14 @@ build:coverage --define=no_debug_info=1 # `--no-relax` is required for coverage to not err with `relocation R_X86_64_REX_GOTPCRELX` build:coverage --linkopt=-Wl,-s,--no-relax build:coverage --test_env=ENVOY_IP_TEST_VERSIONS=v4only +build:coverage --define=dynamic_link_tests=false build:test-coverage --test_arg="-l trace" build:test-coverage --test_arg="--log-path /dev/null" build:test-coverage --test_tag_filters=-nocoverage,-fuzz_target -build:test-coverage --define=dynamic_link_tests=false build:fuzz-coverage --config=plain-fuzzer build:fuzz-coverage --run_under=@envoy//bazel/coverage:fuzz_coverage_wrapper.sh build:fuzz-coverage --test_tag_filters=-nocoverage -build:fuzz-coverage --define=dynamic_link_tests=true # Existing fuzz tests don't need a full WASM runtime and in generally we don't really want to # fuzz dependencies anyways. On the other hand, disabling WASM reduces the build time and # resources required to build and run the tests. From 37596f0bb713b2a9c1a91561a63c81b65b2ccd82 Mon Sep 17 00:00:00 2001 From: "Krinkin, Mike" Date: Fri, 2 May 2025 00:10:15 +0100 Subject: [PATCH 11/35] Fix environment-dependent UnexpectedFormatCpuAllocatedLine test (#39304) Commit Message: Tests were somewhat non-deterministic in the sense that the lines of code that this test exercises depend on the environment and whether /sys/fs/cgroup/cpu/cpuacct.usage exists. This issue affected Envoy coverage tests when we tried to migrate them from Google RBE backend to EngFlow. The same test worked fine and produced 100% coverage for LinuxContainerCpuStatsReader on Google RBE backends, but when we migrated to EngFlow the coverage changed and triggered a coverage test failure. This PR refactors the test a bit to make sure that both CPU allocation CPU times files are always available and valid, unless the test explicitly overrides it. Signed-off-by: Mikhail Krinkin Signed-off-by: Ryan Northey --- .../linux_cpu_stats_reader_test.cc | 154 +++++++----------- 1 file changed, 61 insertions(+), 93 deletions(-) diff --git a/test/extensions/resource_monitors/cpu_utilization/linux_cpu_stats_reader_test.cc b/test/extensions/resource_monitors/cpu_utilization/linux_cpu_stats_reader_test.cc index ea268a8e0c..43d70819ff 100644 --- a/test/extensions/resource_monitors/cpu_utilization/linux_cpu_stats_reader_test.cc +++ b/test/extensions/resource_monitors/cpu_utilization/linux_cpu_stats_reader_test.cc @@ -89,29 +89,50 @@ cpu1 1883161 620 375962 1448133 5963 0 85914 10 0 0 EXPECT_EQ(cpu_times.total_time, 0); } -TEST(LinuxContainerCpuStatsReader, ReadsCgroupContainerStats) { - Event::MockDispatcher dispatcher; - Api::ApiPtr api = Api::createApiForTest(); - Server::MockOptions options; - Server::Configuration::ResourceMonitorFactoryContextImpl context( - dispatcher, options, *api, ProtobufMessage::getStrictValidationVisitor()); - TimeSource& test_time_source = context.api().timeSource(); - - const std::string temp_path_cpu_allocated = - TestEnvironment::temporaryPath("cgroup_cpu_allocated_stats"); - AtomicFileUpdater file_updater_cpu_allocated(temp_path_cpu_allocated); - const std::string mock_contents_cpu_allocated = R"EOF(2000 -)EOF"; - file_updater_cpu_allocated.update(mock_contents_cpu_allocated); - - const std::string temp_path_cpu_times = TestEnvironment::temporaryPath("cgroup_cpu_times_stats"); - AtomicFileUpdater file_updater_cpu_times(temp_path_cpu_times); - const std::string mock_contents_cpu_times = R"EOF(1000 -)EOF"; - file_updater_cpu_times.update(mock_contents_cpu_times); - - LinuxContainerCpuStatsReader container_stats_reader(test_time_source, temp_path_cpu_allocated, - temp_path_cpu_times); +class LinuxContainerCpuStatsReaderTest : public testing::Test { +public: + LinuxContainerCpuStatsReaderTest() + : api_(Api::createApiForTest()), + context_(dispatcher_, options_, *api_, ProtobufMessage::getStrictValidationVisitor()), + cpu_allocated_path_(TestEnvironment::temporaryPath("cgroup_cpu_allocated_stats")), + cpu_times_path_(TestEnvironment::temporaryPath("cgroup_cpu_times_stats")) { + // We populate the files that LinuxContainerStatsReader tries to read with some default + // sane values, so the tests don't need to populate the files they don't actually care + // about keeping the test cases focused on what they actually want to test. + setCpuAllocated("2000\n"); + setCpuTimes("1000\n"); + } + + TimeSource& timeSource() { return context_.api().timeSource(); } + + const std::string& cpuAllocatedPath() const { return cpu_allocated_path_; } + void setCpuAllocated(const std::string& contents) { + AtomicFileUpdater cpu_allocated(cpuAllocatedPath()); + cpu_allocated.update(contents); + } + + const std::string& cpuTimesPath() const { return cpu_times_path_; } + void setCpuTimes(const std::string& contents) { + AtomicFileUpdater cpu_times(cpuTimesPath()); + cpu_times.update(contents); + } + +private: + Event::MockDispatcher dispatcher_; + Api::ApiPtr api_; + Server::MockOptions options_; + Server::Configuration::ResourceMonitorFactoryContextImpl context_; + std::string cpu_allocated_path_; + std::string cpu_times_path_; +}; + +TEST_F(LinuxContainerCpuStatsReaderTest, ReadsCgroupContainerStats) { + TimeSource& test_time_source = timeSource(); + setCpuAllocated("2000\n"); + setCpuTimes("1000\n"); + + LinuxContainerCpuStatsReader container_stats_reader(test_time_source, cpuAllocatedPath(), + cpuTimesPath()); CpuTimes envoy_container_stats = container_stats_reader.getCpuTimes(); const uint64_t current_monotonic_time = std::chrono::duration_cast( @@ -123,50 +144,25 @@ TEST(LinuxContainerCpuStatsReader, ReadsCgroupContainerStats) { EXPECT_GT(time_diff_ns, 0); } -TEST(LinuxContainerCpuStatsReader, CannotReadFileCpuAllocated) { - Event::MockDispatcher dispatcher; - Api::ApiPtr api = Api::createApiForTest(); - Server::MockOptions options; - Server::Configuration::ResourceMonitorFactoryContextImpl context( - dispatcher, options, *api, ProtobufMessage::getStrictValidationVisitor()); - TimeSource& test_time_source = context.api().timeSource(); - +TEST_F(LinuxContainerCpuStatsReaderTest, CannotReadFileCpuAllocated) { + TimeSource& test_time_source = timeSource(); const std::string temp_path_cpu_allocated = - TestEnvironment::temporaryPath("container_cpu_allocated_not_exists"); - - const std::string temp_path_cpu_times = TestEnvironment::temporaryPath("container_cpu_times"); - AtomicFileUpdater file_updater_cpu_times(temp_path_cpu_times); - const std::string cpu_times_contents = R"EOF(100000 -)EOF"; - file_updater_cpu_times.update(cpu_times_contents); + TestEnvironment::temporaryPath("container_cpu_times_not_exists"); LinuxContainerCpuStatsReader container_stats_reader(test_time_source, temp_path_cpu_allocated, - temp_path_cpu_times); + cpuTimesPath()); CpuTimes envoy_container_stats = container_stats_reader.getCpuTimes(); EXPECT_FALSE(envoy_container_stats.is_valid); EXPECT_EQ(envoy_container_stats.work_time, 0); EXPECT_EQ(envoy_container_stats.total_time, 0); } -TEST(LinuxContainerCpuStatsReader, CannotReadFileCpuTimes) { - Event::MockDispatcher dispatcher; - Api::ApiPtr api = Api::createApiForTest(); - Server::MockOptions options; - Server::Configuration::ResourceMonitorFactoryContextImpl context( - dispatcher, options, *api, ProtobufMessage::getStrictValidationVisitor()); - TimeSource& test_time_source = context.api().timeSource(); - - const std::string temp_path_cpu_allocated = - TestEnvironment::temporaryPath("container_cpu_allocated"); - AtomicFileUpdater file_updater_cpu_allocated(temp_path_cpu_allocated); - const std::string cpu_allocated_contents = R"EOF(1000101 -)EOF"; - file_updater_cpu_allocated.update(cpu_allocated_contents); - +TEST_F(LinuxContainerCpuStatsReaderTest, CannotReadFileCpuTimes) { + TimeSource& test_time_source = timeSource(); const std::string temp_path_cpu_times = TestEnvironment::temporaryPath("container_cpu_times_not_exists"); - LinuxContainerCpuStatsReader container_stats_reader(test_time_source, temp_path_cpu_allocated, + LinuxContainerCpuStatsReader container_stats_reader(test_time_source, cpuAllocatedPath(), temp_path_cpu_times); CpuTimes envoy_container_stats = container_stats_reader.getCpuTimes(); EXPECT_FALSE(envoy_container_stats.is_valid); @@ -174,52 +170,24 @@ TEST(LinuxContainerCpuStatsReader, CannotReadFileCpuTimes) { EXPECT_EQ(envoy_container_stats.total_time, 0); } -TEST(LinuxContainerCpuStatsReader, UnexpectedFormatCpuAllocatedLine) { - Event::MockDispatcher dispatcher; - Api::ApiPtr api = Api::createApiForTest(); - Server::MockOptions options; - Server::Configuration::ResourceMonitorFactoryContextImpl context( - dispatcher, options, *api, ProtobufMessage::getStrictValidationVisitor()); - TimeSource& test_time_source = context.api().timeSource(); +TEST_F(LinuxContainerCpuStatsReaderTest, UnexpectedFormatCpuAllocatedLine) { + TimeSource& test_time_source = timeSource(); + setCpuAllocated("notanumb3r\n"); - const std::string temp_path_cpu_allocated = - TestEnvironment::temporaryPath("container_cpu_allocated_unexpected_format"); - AtomicFileUpdater file_updater_cpu_allocated(temp_path_cpu_allocated); - const std::string cpu_allocated_contents = R"EOF(notanumb3r -)EOF"; - file_updater_cpu_allocated.update(cpu_allocated_contents); - - LinuxContainerCpuStatsReader container_stats_reader(test_time_source, temp_path_cpu_allocated); + LinuxContainerCpuStatsReader container_stats_reader(test_time_source, cpuAllocatedPath(), + cpuTimesPath()); CpuTimes envoy_container_stats = container_stats_reader.getCpuTimes(); EXPECT_FALSE(envoy_container_stats.is_valid); EXPECT_EQ(envoy_container_stats.work_time, 0); EXPECT_EQ(envoy_container_stats.total_time, 0); } -TEST(LinuxContainerCpuStatsReader, UnexpectedFormatCpuTimesLine) { - Event::MockDispatcher dispatcher; - Api::ApiPtr api = Api::createApiForTest(); - Server::MockOptions options; - Server::Configuration::ResourceMonitorFactoryContextImpl context( - dispatcher, options, *api, ProtobufMessage::getStrictValidationVisitor()); - TimeSource& test_time_source = context.api().timeSource(); - - const std::string temp_path_cpu_allocated = - TestEnvironment::temporaryPath("container_cpu_allocated"); - AtomicFileUpdater file_updater_cpu_allocated(temp_path_cpu_allocated); - const std::string cpu_allocated_contents = R"EOF(1000101 -)EOF"; - file_updater_cpu_allocated.update(cpu_allocated_contents); +TEST_F(LinuxContainerCpuStatsReaderTest, UnexpectedFormatCpuTimesLine) { + TimeSource& test_time_source = timeSource(); + setCpuTimes("notanumb3r\n"); - const std::string temp_path_cpu_times = - TestEnvironment::temporaryPath("container_cpu_times_unexpected_format"); - AtomicFileUpdater file_update_cpu_times(temp_path_cpu_times); - const std::string cpu_times_contents = R"EOF(notanumb3r -)EOF"; - file_update_cpu_times.update(cpu_times_contents); - - LinuxContainerCpuStatsReader container_stats_reader(test_time_source, temp_path_cpu_allocated, - temp_path_cpu_times); + LinuxContainerCpuStatsReader container_stats_reader(test_time_source, cpuAllocatedPath(), + cpuTimesPath()); CpuTimes envoy_container_stats = container_stats_reader.getCpuTimes(); EXPECT_FALSE(envoy_container_stats.is_valid); EXPECT_EQ(envoy_container_stats.work_time, 0); From b8bf68fde3ead9d5d0d13c21094f4d773315e38d Mon Sep 17 00:00:00 2001 From: Ryan Northey Date: Wed, 11 Jun 2025 09:22:35 +0100 Subject: [PATCH 12/35] mobile/ci: Remove unused config Signed-off-by: Ryan Northey --- .github/config.yml | 202 --------------------------------------------- 1 file changed, 202 deletions(-) diff --git a/.github/config.yml b/.github/config.yml index beab755813..bc36a3513b 100644 --- a/.github/config.yml +++ b/.github/config.yml @@ -35,66 +35,6 @@ checks: required: true on-run: - build-macos - mobile-android: - name: Mobile/Android - required: true - on-run: - - mobile-android - mobile-android-tests: - name: Mobile/Android tests - required: true - on-run: - - mobile-android-tests - mobile-asan: - name: Mobile/ASAN - required: true - on-run: - - mobile-asan - mobile-cc: - name: Mobile/CC - required: true - on-run: - - mobile-cc - mobile-coverage: - name: Mobile/Coverage - required: true - on-run: - - mobile-coverage - mobile-docs: - name: Mobile/Docs - on-run: - - mobile-docs - mobile-format: - name: Mobile/Format - required: true - on-run: - - mobile-format - mobile-ios: - name: Mobile/iOS - required: true - cache: - on-run: - - mobile-ios - mobile-ios-tests: - name: Mobile/iOS tests - required: true - on-run: - - mobile-ios-tests - mobile-perf: - name: Mobile/Perf - required: true - on-run: - - mobile-perf - mobile-release-validation: - name: Mobile/Release validation - required: true - on-run: - - mobile-release-validation - mobile-tsan: - name: Mobile/TSAN - required: true - on-run: - - mobile-tsan prechecks: name: Envoy/Prechecks on-run: @@ -173,148 +113,6 @@ run: check-san: paths: - "**/*" - mobile-android: - paths: - - .bazelrc - - .bazelversion - - .github/config.yml - - bazel/external/quiche.BUILD - - bazel/repository_locations.bzl - - mobile/.bazelrc - - mobile/**/* - - source/common/**/* - - tools/code_format/check_format.py - mobile-android-all: - paths: - - .bazelrc - - .bazelversion - - .github/config.yml - - bazel/external/quiche.BUILD - - bazel/repository_locations.bzl - - mobile/.bazelrc - - mobile/**/* - - source/common/**/* - - tools/code_format/check_format.py - push: never - mobile-android-tests: - paths: - - .bazelrc - - .bazelversion - - .github/config.yml - - bazel/external/quiche.BUILD - - bazel/repository_locations.bzl - - mobile/.bazelrc - - mobile/**/* - - tools/code_format/check_format.py - mobile-asan: - paths: - - .bazelrc - - .bazelversion - - .github/config.yml - - bazel/external/quiche.BUILD - - bazel/repository_locations.bzl - - mobile/.bazelrc - - mobile/**/* - - tools/code_format/check_format.py - mobile-cc: - paths: - - .bazelrc - - .bazelversion - - .github/config.yml - - api/**/* - - bazel/external/quiche.BUILD - - bazel/repository_locations.bzl - - envoy/**/* - - mobile/.bazelrc - - mobile/**/* - - source/**/* - - test/config/**/* - - test/integration/* - - test/mocks/**/* - - test/test_common/**/* - mobile-coverage: - paths: - - .bazelrc - - .bazelversion - - .github/config.yml - - bazel/external/quiche.BUILD - - bazel/repository_locations.bzl - - mobile/.bazelrc - - mobile/**/* - - tools/code_format/check_format.py - mobile-format: - paths: - - .bazelrc - - .bazelversion - - .github/config.yml - - bazel/external/quiche.BUILD - - bazel/repository_locations.bzl - - mobile/.bazelrc - - mobile/**/* - - tools/code_format/check_format.py - mobile-ios: - paths: - - .bazelrc - - .bazelversion - - .github/config.yml - - bazel/external/quiche.BUILD - - bazel/repository_locations.bzl - - mobile/.bazelrc - - mobile/**/* - - source/common/**/* - - tools/code_format/check_format.py - mobile-ios-all: - paths: - - .bazelrc - - .bazelversion - - .github/config.yml - - bazel/external/quiche.BUILD - - bazel/repository_locations.bzl - - mobile/.bazelrc - - mobile/**/* - - source/common/**/* - - tools/code_format/check_format.py - push: never - mobile-ios-tests: - paths: - - .bazelrc - - .bazelversion - - .github/config.yml - - bazel/external/quiche.BUILD - - bazel/repository_locations.bzl - - mobile/.bazelrc - - mobile/**/* - - tools/code_format/check_format.py - mobile-perf: - paths: - - .bazelrc - - .bazelversion - - .github/config.yml - - bazel/external/quiche.BUILD - - bazel/repository_locations.bzl - - mobile/.bazelrc - - mobile/**/* - - tools/code_format/check_format.py - mobile-release-validation: - paths: - - .bazelrc - - .bazelversion - - .github/config.yml - - bazel/external/quiche.BUILD - - bazel/repository_locations.bzl - - mobile/.bazelrc - - mobile/**/* - - tools/code_format/check_format.py - mobile-tsan: - paths: - - .bazelrc - - .bazelversion - - .github/config.yml - - bazel/external/quiche.BUILD - - bazel/repository_locations.bzl - - mobile/.bazelrc - - mobile/**/* - - tools/code_format/check_format.py precheck-deps: paths: - .bazelrc From 1a1866f09e8b5443000a7abaed3b001153eaa50d Mon Sep 17 00:00:00 2001 From: Rohit Agrawal Date: Sat, 29 Mar 2025 14:57:15 -0700 Subject: [PATCH 13/35] quic: re-enable tests for FIPS build Signed-off-by: Rohit Agrawal --- bazel/BUILD | 1 - bazel/external/quiche.BUILD | 106 -- bazel/external/quiche.bzl | 6 +- source/common/http/http3/BUILD | 31 +- source/common/quic/BUILD | 1226 ++++++++++------- source/common/quic/platform/BUILD | 6 - source/common/quic/platform/mobile_impl/BUILD | 1 - .../quic/connection_debug_visitor/basic/BUILD | 54 +- .../connection_debug_visitor/quic_stats/BUILD | 42 +- .../deterministic/BUILD | 42 +- .../connection_id_generator/quic_lb/BUILD | 74 +- source/extensions/quic/crypto_stream/BUILD | 60 +- source/extensions/quic/proof_source/BUILD | 40 +- .../quic/server_preferred_address/BUILD | 110 +- source/extensions/udp_packet_writer/gso/BUILD | 1 - test/common/http/http3/BUILD | 1 - test/common/listener_manager/BUILD | 42 +- test/common/network/BUILD | 47 +- test/common/quic/BUILD | 690 ++++++---- test/common/quic/platform/BUILD | 4 - .../connection_debug_visitor/quic_stats/BUILD | 38 +- .../connection_id_generator/quic_lb/BUILD | 42 +- test/extensions/quic/proof_source/BUILD | 1 - .../quic/server_preferred_address/BUILD | 38 +- test/integration/BUILD | 19 +- test/integration/filters/BUILD | 27 +- 26 files changed, 1556 insertions(+), 1193 deletions(-) diff --git a/bazel/BUILD b/bazel/BUILD index 528cfbf012..e710f090a6 100644 --- a/bazel/BUILD +++ b/bazel/BUILD @@ -298,7 +298,6 @@ selects.config_setting_group( name = "disable_http3", match_any = [ ":disable_http3_setting", - ":boringssl_fips", ], ) diff --git a/bazel/external/quiche.BUILD b/bazel/external/quiche.BUILD index eb1b0256e4..302a3dbcc6 100644 --- a/bazel/external/quiche.BUILD +++ b/bazel/external/quiche.BUILD @@ -1511,7 +1511,6 @@ envoy_cc_library( envoy_cc_library( name = "quic_platform", repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_core_time_lib", @@ -1526,7 +1525,6 @@ envoy_cc_library( "quiche/quic/platform/api/quic_hostname_utils.h", ], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_hostname_utils", @@ -1539,7 +1537,6 @@ envoy_cc_library( "quiche/quic/platform/api/quic_stack_trace.h", ], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_stack_trace", @@ -1552,7 +1549,6 @@ envoy_cc_library( "quiche/quic/platform/api/quic_server_stats.h", ], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_server_stats", @@ -1594,7 +1590,6 @@ envoy_cc_library( "quiche/quic/platform/api/quic_bug_tracker.h", ], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_bug_tracker", @@ -1605,7 +1600,6 @@ envoy_cc_library( name = "quic_platform_export", hdrs = ["quiche/quic/platform/api/quic_export.h"], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_export", @@ -1616,7 +1610,6 @@ envoy_cc_test_library( name = "quic_platform_expect_bug", hdrs = ["quiche/quic/platform/api/quic_expect_bug.h"], repository = "@envoy", - tags = ["nofips"], deps = [":quiche_common_platform_expect_bug"], ) @@ -1624,7 +1617,6 @@ envoy_cc_library( name = "quic_platform_ip_address_family", hdrs = ["quiche/quic/platform/api/quic_ip_address_family.h"], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_platform_bug_tracker", @@ -1637,7 +1629,6 @@ envoy_cc_library( srcs = ["quiche/common/quiche_ip_address_family.cc"], hdrs = ["quiche/common/quiche_ip_address_family.h"], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_platform_bug_tracker", @@ -1663,7 +1654,6 @@ envoy_cc_library( hdrs = ["quiche/common/quiche_ip_address.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_platform_base", @@ -1679,7 +1669,6 @@ envoy_cc_library( "//conditions:default": [], }), repository = "@envoy", - tags = ["nofips"], deps = [":quiche_common_platform_udp_socket_platform"], ) @@ -1713,7 +1702,6 @@ envoy_cc_test_library( name = "quic_platform_test", hdrs = ["quiche/quic/platform/api/quic_test.h"], repository = "@envoy", - tags = ["nofips"], deps = [ ":quic_platform_base", ":quiche_common_platform_test", @@ -1725,7 +1713,6 @@ envoy_cc_test_library( name = "quic_platform_test_output", hdrs = ["quiche/quic/platform/api/quic_test_output.h"], repository = "@envoy", - tags = ["nofips"], deps = [":quiche_common_platform_test_output"], ) @@ -1733,7 +1720,6 @@ envoy_cc_test_library( name = "quic_platform_thread", hdrs = ["quiche/quic/platform/api/quic_thread.h"], repository = "@envoy", - tags = ["nofips"], deps = [":quiche_common_platform_thread"], ) @@ -1752,7 +1738,6 @@ envoy_cc_library( name = "quic_core_proto_cached_network_parameters_proto_header", hdrs = ["quiche/quic/core/proto/cached_network_parameters_proto.h"], repository = "@envoy", - tags = ["nofips"], deps = [":quic_core_proto_cached_network_parameters_proto_cc"], ) @@ -1771,7 +1756,6 @@ envoy_cc_library( name = "quic_core_proto_source_address_token_proto_header", hdrs = ["quiche/quic/core/proto/source_address_token_proto.h"], repository = "@envoy", - tags = ["nofips"], deps = [":quic_core_proto_source_address_token_proto_cc"], ) @@ -1789,7 +1773,6 @@ envoy_cc_library( name = "quic_core_proto_crypto_server_config_proto_header", hdrs = ["quiche/quic/core/proto/crypto_server_config_proto.h"], repository = "@envoy", - tags = ["nofips"], deps = [":quic_core_proto_crypto_server_config_proto_cc"], ) @@ -1799,7 +1782,6 @@ envoy_cc_library( hdrs = ["quiche/quic/core/quic_ack_listener_interface.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_core_time_lib", @@ -1834,7 +1816,6 @@ envoy_cc_library( hdrs = ["quiche/quic/core/quic_bandwidth.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_core_constants_lib", @@ -1860,7 +1841,6 @@ envoy_cc_library( }), copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_core_linux_socket_utils_lib", @@ -1886,7 +1866,6 @@ envoy_cc_library( }), copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_core_batch_writer_batch_writer_buffer_lib", @@ -1906,7 +1885,6 @@ envoy_cc_test_library( }), copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ ":quic_core_batch_writer_batch_writer_base_lib", ":quic_core_udp_socket_lib", @@ -1930,7 +1908,6 @@ envoy_cc_library( }), copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":flow_label_lib", @@ -1956,7 +1933,6 @@ envoy_cc_library( }), copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_core_batch_writer_batch_writer_base_lib", @@ -1967,7 +1943,6 @@ envoy_cc_library( envoy_quic_cc_library( name = "quic_core_blocked_writer_interface_lib", hdrs = ["quiche/quic/core/quic_blocked_writer_interface.h"], - tags = ["nofips"], deps = [":quic_platform_export"], ) @@ -1988,7 +1963,6 @@ envoy_cc_test( srcs = ["quiche/quic/core/quic_blocked_writer_list_test.cc"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ ":quic_core_blocked_writer_interface_lib", ":quic_core_blocked_writer_list_lib", @@ -2413,7 +2387,6 @@ envoy_cc_library( hdrs = ["quiche/quic/core/quic_constants.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_core_types_lib", @@ -2432,7 +2405,6 @@ envoy_cc_library( copts = quiche_copts, external_deps = ["ssl"], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_logging", @@ -2699,7 +2671,6 @@ envoy_cc_library( copts = quiche_copts, external_deps = ["ssl"], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [":quiche_common_random_lib"], ) @@ -2762,7 +2733,6 @@ envoy_cc_library( "quiche/common/simple_buffer_allocator.h", ], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_export", @@ -2776,7 +2746,6 @@ envoy_cc_library( hdrs = ["quiche/common/quiche_circular_deque.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_platform", ":quiche_common_platform_export", @@ -2790,7 +2759,6 @@ envoy_cc_library( copts = quiche_copts, external_deps = ["ssl"], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [":quiche_common_platform_logging"], ) @@ -2800,7 +2768,6 @@ envoy_cc_library( hdrs = ["quiche/common/quiche_status_utils.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/status", @@ -2813,7 +2780,6 @@ envoy_cc_library( hdrs = ["quiche/common/wire_serialization.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_buffer_allocator_lib", ":quiche_common_lib", @@ -2828,7 +2794,6 @@ envoy_cc_library( hdrs = ["quiche/common/quiche_callbacks.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_export", @@ -2863,7 +2828,6 @@ envoy_cc_library( copts = quiche_copts, external_deps = ["ssl"], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_platform_base", @@ -2876,7 +2840,6 @@ envoy_cc_library( hdrs = ["quiche/common/quiche_feature_flags_list.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], ) @@ -2885,7 +2848,6 @@ envoy_cc_library( hdrs = ["quiche/common/quiche_protocol_flags_list.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], ) @@ -2979,7 +2941,6 @@ envoy_cc_library( "//conditions:default": [], }), repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_core_constants_lib", @@ -3283,7 +3244,6 @@ envoy_cc_library( hdrs = ["quiche/quic/core/quic_interval.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_platform_export", @@ -3306,7 +3266,6 @@ envoy_cc_library( hdrs = ["quiche/quic/core/quic_interval_set.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_core_interval_lib", @@ -3324,7 +3283,6 @@ envoy_cc_library( }), copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = select({ "@envoy//bazel:windows_x86_64": [], "@envoy//bazel:disable_http3": [], @@ -3350,7 +3308,6 @@ envoy_cc_library( ], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_core_types_lib", @@ -3387,7 +3344,6 @@ envoy_cc_library( }), copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = select({ "@envoy//bazel:windows_x86_64": [], "@envoy//bazel:disable_http3": [], @@ -3447,7 +3403,6 @@ envoy_cc_library( }), copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ ":quic_platform_export", ], @@ -3465,7 +3420,6 @@ envoy_cc_library( }), copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ ":quic_core_packet_writer_lib", ":quic_core_syscall_wrapper_lib", @@ -3529,7 +3483,6 @@ envoy_cc_library( ], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_core_packets_lib", @@ -3550,7 +3503,6 @@ envoy_cc_library( ], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":http2_core_priority_write_scheduler_lib", @@ -3963,7 +3915,6 @@ envoy_cc_library( copts = quiche_copts, external_deps = ["ssl"], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_core_types_lib", @@ -4155,7 +4106,6 @@ envoy_cc_library( hdrs = ["quiche/quic/core/quic_tag.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_platform_base", @@ -4168,7 +4118,6 @@ envoy_cc_library( srcs = ["quiche/quic/core/quic_time.cc"], hdrs = ["quiche/quic/core/quic_time.h"], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [":quic_platform_base"], ) @@ -4224,7 +4173,6 @@ envoy_cc_library( copts = quiche_copts, external_deps = ["ssl"], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_core_crypto_random_lib", @@ -4273,7 +4221,6 @@ envoy_cc_library( "//conditions:default": [], }), repository = "@envoy", - tags = ["nofips"], deps = [ ":flow_label_lib", ":quic_core_io_socket_lib", @@ -4305,7 +4252,6 @@ envoy_cc_library( hdrs = ["quiche/quic/core/quic_utils.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_core_constants_lib", @@ -4337,7 +4283,6 @@ envoy_cc_library( hdrs = ["quiche/quic/core/quic_versions.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_core_crypto_random_lib", @@ -4644,7 +4589,6 @@ envoy_cc_library( name = "quiche_common_endian_lib", hdrs = ["quiche/common/quiche_endian.h"], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ @@ -4658,7 +4602,6 @@ envoy_cc_library( "quiche/common/platform/api/quiche_client_stats.h", ], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [":quiche_common_platform_default_quiche_platform_impl_client_stats_impl_lib"], ) @@ -4676,7 +4619,6 @@ envoy_cc_test_library( "quiche/common/platform/api/quiche_system_event_loop.h", ], repository = "@envoy", - tags = ["nofips"], deps = [":quiche_common_platform_default_quiche_platform_impl_system_event_loop_impl_lib"], ) @@ -4691,7 +4633,6 @@ envoy_cc_library( name = "quiche_common_platform_googleurl", hdrs = ["quiche/common/platform/api/quiche_googleurl.h"], repository = "@envoy", - tags = ["nofips"], deps = [":quiche_common_platform_default_quiche_platform_impl_googleurl_impl_lib"], ) @@ -4700,7 +4641,6 @@ envoy_cc_library( srcs = ["quiche/common/platform/api/quiche_mem_slice.cc"], hdrs = ["quiche/common/platform/api/quiche_mem_slice.h"], repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_buffer_allocator_lib", ":quiche_common_callbacks", @@ -4725,7 +4665,6 @@ envoy_cc_library( "quiche/common/platform/api/quiche_iovec.h", ], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_bug_tracker", @@ -4740,7 +4679,6 @@ envoy_cc_library( "quiche/common/platform/api/quiche_bug_tracker.h", ], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_export", @@ -4761,7 +4699,6 @@ envoy_cc_library( "quiche/common/platform/api/quiche_logging.h", ], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_export", @@ -4801,7 +4738,6 @@ envoy_cc_library( "quiche/common/platform/api/quiche_hostname_utils.h", ], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_export", @@ -4816,7 +4752,6 @@ envoy_cc_test_library( "quiche/common/platform/api/quiche_thread.h", ], repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_platform_export", "@envoy//test/common/quic/platform:quiche_thread_impl_lib", @@ -4829,7 +4764,6 @@ envoy_cc_test_library( "quiche/common/platform/api/quiche_test_output.h", ], repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_platform_export", "@envoy//test/common/quic/platform:quiche_test_output_impl_lib", @@ -4842,7 +4776,6 @@ envoy_cc_test_library( "quiche/common/platform/api/quiche_expect_bug.h", ], repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_platform_export", "@envoy//test/common/quic/platform:quiche_expect_bug_impl_lib", @@ -4856,7 +4789,6 @@ envoy_cc_library( "//conditions:default": [], }), repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_core_types_lib", @@ -4870,7 +4802,6 @@ envoy_cc_library( name = "quiche_common_platform_server_stats", hdrs = ["quiche/common/platform/api/quiche_server_stats.h"], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_default_quiche_platform_impl_server_stats_impl_lib", @@ -4890,7 +4821,6 @@ envoy_cc_library( "quiche/common/platform/api/quiche_stack_trace.h", ], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_export", @@ -4904,7 +4834,6 @@ envoy_cc_library( "quiche/common/platform/api/quiche_containers.h", ], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_default_quiche_platform_impl_containers_impl_lib", @@ -4938,7 +4867,6 @@ envoy_cc_library( "quiche/common/platform/api/quiche_testvalue.h", ], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_export", @@ -4956,7 +4884,6 @@ envoy_cc_library( "quiche/common/platform/api/quiche_time_utils.h", ], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_bug_tracker", @@ -5029,7 +4956,6 @@ envoy_cc_library( "quiche/common/platform/api/quiche_export.h", ], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ "@envoy//source/common/quic/platform:quiche_export_impl_lib", @@ -5040,7 +4966,6 @@ envoy_cc_test_library( name = "quiche_common_platform_test", hdrs = ["quiche/common/platform/api/quiche_test.h"], repository = "@envoy", - tags = ["nofips"], deps = ["@envoy//test/common/quic/platform:quiche_test_impl_lib"], ) @@ -5049,7 +4974,6 @@ envoy_cc_test( srcs = ["quiche/common/platform/api/quiche_mem_slice_test.cc"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_buffer_allocator_lib", ":quiche_common_platform", @@ -5063,7 +4987,6 @@ envoy_cc_test( srcs = ["quiche/common/platform/api/quiche_time_utils_test.cc"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_platform", ":quiche_common_platform_test", @@ -5074,7 +4997,6 @@ envoy_cc_library( name = "quiche_common_print_elements_lib", hdrs = ["quiche/common/print_elements.h"], repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_platform_export", "@com_google_absl//absl/container:inlined_vector", @@ -5088,7 +5010,6 @@ envoy_cc_test_library( "quiche/common/test_tools/quiche_test_utils.h", ], repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_platform", ":quiche_common_platform_googleurl", @@ -5104,7 +5025,6 @@ envoy_cc_library( srcs = ["quiche/common/quiche_text_utils.cc"], hdrs = ["quiche/common/quiche_text_utils.h"], repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_platform_export", "@com_google_absl//absl/hash", @@ -5124,7 +5044,6 @@ envoy_cc_library( "quiche/common/quiche_linked_hash_map.h", ], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_endian_lib", @@ -5137,7 +5056,6 @@ envoy_cc_library( srcs = ["quiche/common/quiche_simple_arena.cc"], hdrs = ["quiche/common/quiche_simple_arena.h"], repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_platform_export", ":quiche_common_platform_logging", @@ -5149,7 +5067,6 @@ envoy_cc_library( srcs = ["quiche/common/http/http_header_storage.cc"], hdrs = ["quiche/common/http/http_header_storage.h"], repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_platform_export", ":quiche_common_platform_logging", @@ -5162,7 +5079,6 @@ envoy_cc_library( srcs = ["quiche/common/http/http_header_block.cc"], hdrs = ["quiche/common/http/http_header_block.h"], repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_lib", ":quiche_common_platform_export", @@ -5176,7 +5092,6 @@ envoy_cc_test( name = "quiche_http_header_block_test", srcs = ["quiche/common/http/http_header_block_test.cc"], repository = "@envoy", - tags = ["nofips"], deps = [ ":http2_test_tools_test_utils_lib", ":quiche_common_platform_test", @@ -5189,7 +5104,6 @@ envoy_cc_library( srcs = ["quiche/common/structured_headers.cc"], hdrs = ["quiche/common/structured_headers.h"], repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform", @@ -5213,7 +5127,6 @@ envoy_cc_test( ], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_lib", ":quiche_common_mem_slice_storage", @@ -5227,7 +5140,6 @@ envoy_cc_test( "quiche/http2/test_tools/http2_random_test.cc", ], repository = "@envoy", - tags = ["nofips"], deps = [ ":http2_test_tools_random", ":quiche_common_platform", @@ -5257,7 +5169,6 @@ envoy_cc_test( }), copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ ":quic_core_batch_writer_batch_writer_test_lib", ":quic_core_batch_writer_gso_batch_writer_lib", @@ -5272,7 +5183,6 @@ envoy_cc_library( hdrs = ["quiche/quic/load_balancer/load_balancer_server_id.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quic_core_types_lib", @@ -5315,7 +5225,6 @@ envoy_cc_library( name = "quiche_common_platform_lower_case_string", hdrs = ["quiche/common/platform/api/quiche_lower_case_string.h"], repository = "@envoy", - tags = ["nofips"], deps = ["@envoy//source/common/quic/platform:quiche_lower_case_string_impl_lib"], ) @@ -5323,7 +5232,6 @@ envoy_cc_library( name = "quiche_common_platform_header_policy", hdrs = ["quiche/common/platform/api/quiche_header_policy.h"], repository = "@envoy", - tags = ["nofips"], deps = [":quiche_common_platform_default_quiche_platform_impl_header_policy_impl_lib"], ) @@ -5338,7 +5246,6 @@ envoy_cc_library( hdrs = ["quiche/balsa/balsa_enums.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [":quiche_common_platform_export"], ) @@ -5348,7 +5255,6 @@ envoy_cc_library( hdrs = ["quiche/balsa/balsa_visitor_interface.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_balsa_balsa_enums_lib", @@ -5361,7 +5267,6 @@ envoy_cc_library( hdrs = ["quiche/balsa/noop_balsa_visitor.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_balsa_balsa_visitor_interface_lib", @@ -5375,7 +5280,6 @@ envoy_cc_library( hdrs = ["quiche/balsa/standard_header_map.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_text_utils_lib", "@com_google_absl//absl/container:flat_hash_set", @@ -5388,7 +5292,6 @@ envoy_cc_library( hdrs = ["quiche/balsa/framer_interface.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [":quiche_common_platform_export"], ) @@ -5397,7 +5300,6 @@ envoy_cc_library( hdrs = ["quiche/balsa/http_validation_policy.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_platform_export", ":quiche_common_platform_logging", @@ -5409,7 +5311,6 @@ envoy_cc_library( hdrs = ["quiche/balsa/header_api.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_callbacks", ":quiche_common_platform_export", @@ -5424,7 +5325,6 @@ envoy_cc_library( hdrs = ["quiche/balsa/simple_buffer.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_platform", ":quiche_common_platform_bug_tracker", @@ -5439,7 +5339,6 @@ envoy_cc_test( srcs = ["quiche/balsa/simple_buffer_test.cc"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_balsa_simple_buffer_lib", ":quiche_common_platform_expect_bug", @@ -5454,7 +5353,6 @@ envoy_cc_library( hdrs = ["quiche/balsa/header_properties.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_common_platform", ":quiche_common_platform_export", @@ -5469,7 +5367,6 @@ envoy_cc_test( srcs = ["quiche/balsa/header_properties_test.cc"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ ":quiche_balsa_header_properties_lib", ":quiche_common_platform_test", @@ -5482,7 +5379,6 @@ envoy_cc_library( hdrs = ["quiche/balsa/balsa_headers.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_balsa_balsa_enums_lib", @@ -5528,7 +5424,6 @@ envoy_cc_library( hdrs = ["quiche/balsa/balsa_frame.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_balsa_balsa_enums_lib", @@ -5573,7 +5468,6 @@ envoy_cc_library( hdrs = ["quiche/web_transport/web_transport.h"], copts = quiche_copts, repository = "@envoy", - tags = ["nofips"], deps = [ ":common_http_http_header_block_lib", ":quiche_common_callbacks", diff --git a/bazel/external/quiche.bzl b/bazel/external/quiche.bzl index 0868fb0eb8..e5df747a00 100644 --- a/bazel/external/quiche.bzl +++ b/bazel/external/quiche.bzl @@ -32,7 +32,6 @@ def envoy_quiche_platform_impl_cc_library( deps = deps, repository = "@envoy", strip_include_prefix = "quiche/common/platform/default/", - tags = ["nofips"], visibility = ["//visibility:public"], ) @@ -48,7 +47,6 @@ def envoy_quiche_platform_impl_cc_test_library( deps = deps, repository = "@envoy", strip_include_prefix = "quiche/common/platform/default/", - tags = ["nofips"], ) # Used for QUIC libraries @@ -66,7 +64,7 @@ def envoy_quic_cc_library( hdrs = envoy_select_enable_http3(hdrs, "@envoy"), repository = "@envoy", copts = quiche_copts, - tags = ["nofips"] + tags, + tags = tags, visibility = ["//visibility:public"], defines = defines, external_deps = external_deps, @@ -86,7 +84,7 @@ def envoy_quic_cc_test_library( hdrs = envoy_select_enable_http3(hdrs, "@envoy"), copts = quiche_copts, repository = "@envoy", - tags = ["nofips"] + tags, + tags = tags, external_deps = external_deps, deps = envoy_select_enable_http3(deps, "@envoy"), ) diff --git a/source/common/http/http3/BUILD b/source/common/http/http3/BUILD index bd6fd7aeef..c9820c2839 100644 --- a/source/common/http/http3/BUILD +++ b/source/common/http/http3/BUILD @@ -10,17 +10,26 @@ envoy_package() envoy_cc_library( name = "conn_pool_lib", - srcs = ["conn_pool.cc"], - hdrs = ["conn_pool.h"], - deps = [ - "//envoy/event:dispatcher_interface", - "//envoy/http:persistent_quic_info_interface", - "//envoy/upstream:upstream_interface", - "//source/common/http:codec_client_lib", - "//source/common/http:conn_pool_base_lib", - "//source/common/quic:client_connection_factory_lib", - "@com_github_google_quiche//:quic_core_deterministic_connection_id_generator_lib", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["conn_pool.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["conn_pool.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//envoy/event:dispatcher_interface", + "//envoy/http:persistent_quic_info_interface", + "//envoy/upstream:upstream_interface", + "//source/common/http:codec_client_lib", + "//source/common/http:conn_pool_base_lib", + "//source/common/quic:client_connection_factory_lib", + "@com_github_google_quiche//:quic_core_deterministic_connection_id_generator_lib", + ], + }), ) envoy_cc_library( diff --git a/source/common/quic/BUILD b/source/common/quic/BUILD index cf68a5cf6e..add884b5f4 100644 --- a/source/common/quic/BUILD +++ b/source/common/quic/BUILD @@ -1,3 +1,4 @@ +load("@bazel_skylib//lib:selects.bzl", "selects") load( "@envoy_build_config//:extensions_build_config.bzl", "LEGACY_ALWAYSLINK", @@ -12,6 +13,15 @@ load( licenses(["notice"]) # Apache 2 +# Create a condition for HTTP3 enabled AND Linux +selects.config_setting_group( + name = "http3_enabled_and_linux", + match_all = [ + "//bazel:linux", + "//bazel:enable_http3", + ], +) + # TODO(mattklein123): Default visibility for this package should not be public. We should have # default by private to within this package and package tests, and then only expose the libraries # that are required to be selected into the build for http3 to work. @@ -19,324 +29,456 @@ envoy_package() envoy_cc_library( name = "envoy_quic_alarm_lib", - srcs = ["envoy_quic_alarm.cc"], - hdrs = ["envoy_quic_alarm.h"], - tags = ["nofips"], - deps = [ - "//envoy/event:dispatcher_interface", - "//envoy/event:timer_interface", - "@com_github_google_quiche//:quic_core_alarm_lib", - "@com_github_google_quiche//:quic_core_clock_lib", - "@com_github_google_quiche//:quic_platform", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_alarm.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_alarm.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//envoy/event:dispatcher_interface", + "//envoy/event:timer_interface", + "@com_github_google_quiche//:quic_core_alarm_lib", + "@com_github_google_quiche//:quic_core_clock_lib", + "@com_github_google_quiche//:quic_platform", + ], + }), ) envoy_cc_library( name = "envoy_quic_alarm_factory_lib", - srcs = ["envoy_quic_alarm_factory.cc"], - hdrs = ["envoy_quic_alarm_factory.h"], - tags = ["nofips"], - deps = [ - ":envoy_quic_alarm_lib", - "@com_github_google_quiche//:quic_core_alarm_factory_lib", - "@com_github_google_quiche//:quic_core_arena_scoped_ptr_lib", - "@com_github_google_quiche//:quic_core_one_block_arena_lib", - "@com_github_google_quiche//:quic_platform", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_alarm_factory.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_alarm_factory.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_alarm_lib", + "@com_github_google_quiche//:quic_core_alarm_factory_lib", + "@com_github_google_quiche//:quic_core_arena_scoped_ptr_lib", + "@com_github_google_quiche//:quic_core_one_block_arena_lib", + "@com_github_google_quiche//:quic_platform", + ], + }), ) envoy_cc_library( name = "envoy_quic_clock_lib", - srcs = ["envoy_quic_clock.cc"], - hdrs = ["envoy_quic_clock.h"], - tags = ["nofips"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_clock.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_clock.h"], + }), visibility = ["//visibility:public"], - deps = [ - "//envoy/event:dispatcher_interface", - "@com_github_google_quiche//:quic_core_clock_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//envoy/event:dispatcher_interface", + "@com_github_google_quiche//:quic_core_clock_lib", + ], + }), ) envoy_cc_library( name = "envoy_quic_connection_debug_visitor_factory_interface", - hdrs = ["envoy_quic_connection_debug_visitor_factory_interface.h"], - tags = ["nofips"], - deps = [ - "//envoy/common:optref_lib", - "//envoy/common:pure_lib", - "//envoy/config:typed_config_interface", - "//envoy/server:factory_context_interface", - "//envoy/stream_info:stream_info_interface", - "@com_github_google_quiche//:quic_core_connection_lib", - "@com_github_google_quiche//:quic_core_session_lib", - ], + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_connection_debug_visitor_factory_interface.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//envoy/common:optref_lib", + "//envoy/common:pure_lib", + "//envoy/config:typed_config_interface", + "//envoy/server:factory_context_interface", + "//envoy/stream_info:stream_info_interface", + "@com_github_google_quiche//:quic_core_connection_lib", + "@com_github_google_quiche//:quic_core_session_lib", + ], + }), ) envoy_cc_library( name = "envoy_quic_connection_helper_lib", - hdrs = ["envoy_quic_connection_helper.h"], - tags = ["nofips"], - deps = [ - ":envoy_quic_clock_lib", - "@com_github_google_quiche//:quic_core_connection_lib", - "@com_github_google_quiche//:quiche_common_random_lib", - ], + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_connection_helper.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_clock_lib", + "@com_github_google_quiche//:quic_core_connection_lib", + "@com_github_google_quiche//:quiche_common_random_lib", + ], + }), ) envoy_cc_library( name = "quic_stat_names_lib", srcs = ["quic_stat_names.cc"], hdrs = ["quic_stat_names.h"], - tags = ["nofips"], - deps = [ - "//envoy/stats:stats_interface", - "//source/common/stats:symbol_table_lib", - "@com_github_google_quiche//:quic_core_error_codes_lib", - "@com_github_google_quiche//:quic_core_types_lib", - ], + deps = select({ + "//bazel:disable_http3": [ + "//envoy/stats:stats_interface", + "//source/common/stats:symbol_table_lib", + ], + "//conditions:default": [ + "//envoy/stats:stats_interface", + "//source/common/stats:symbol_table_lib", + "@com_github_google_quiche//:quic_core_error_codes_lib", + "@com_github_google_quiche//:quic_core_types_lib", + ], + }), ) envoy_cc_library( name = "envoy_quic_proof_source_base_lib", - srcs = ["envoy_quic_proof_source_base.cc"], - hdrs = ["envoy_quic_proof_source_base.h"], - tags = ["nofips"], - deps = [ - ":envoy_quic_utils_lib", - "@com_github_google_quiche//:quic_core_crypto_certificate_view_lib", - "@com_github_google_quiche//:quic_core_crypto_crypto_handshake_lib", - "@com_github_google_quiche//:quic_core_crypto_proof_source_lib", - "@com_github_google_quiche//:quic_core_data_lib", - "@com_github_google_quiche//:quic_core_versions_lib", - "@com_github_google_quiche//:quic_platform", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_proof_source_base.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_proof_source_base.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_utils_lib", + "@com_github_google_quiche//:quic_core_crypto_certificate_view_lib", + "@com_github_google_quiche//:quic_core_crypto_crypto_handshake_lib", + "@com_github_google_quiche//:quic_core_crypto_proof_source_lib", + "@com_github_google_quiche//:quic_core_data_lib", + "@com_github_google_quiche//:quic_core_versions_lib", + "@com_github_google_quiche//:quic_platform", + ], + }), ) envoy_cc_library( name = "envoy_quic_proof_source_lib", - srcs = ["envoy_quic_proof_source.cc"], - hdrs = ["envoy_quic_proof_source.h"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_proof_source.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_proof_source.h"], + }), external_deps = ["ssl"], - tags = ["nofips"], - deps = [ - ":envoy_quic_proof_source_base_lib", - ":envoy_quic_utils_lib", - ":quic_io_handle_wrapper_lib", - ":quic_transport_socket_factory_lib", - "//envoy/ssl:tls_certificate_config_interface", - "//source/common/quic:cert_compression_lib", - "//source/common/quic:quic_server_transport_socket_factory_lib", - "//source/common/stream_info:stream_info_lib", - "//source/server:listener_stats", - "@com_github_google_quiche//:quic_core_crypto_certificate_view_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_proof_source_base_lib", + ":envoy_quic_utils_lib", + ":quic_io_handle_wrapper_lib", + ":quic_transport_socket_factory_lib", + "//envoy/ssl:tls_certificate_config_interface", + "//source/common/quic:cert_compression_lib", + "//source/common/quic:quic_server_transport_socket_factory_lib", + "//source/common/stream_info:stream_info_lib", + "//source/server:listener_stats", + "@com_github_google_quiche//:quic_core_crypto_certificate_view_lib", + ], + }), ) envoy_cc_library( name = "envoy_quic_proof_verifier_base_lib", - srcs = ["envoy_quic_proof_verifier_base.cc"], - hdrs = ["envoy_quic_proof_verifier_base.h"], - tags = ["nofips"], - deps = [ - ":envoy_quic_utils_lib", - "@com_github_google_quiche//:quic_core_crypto_certificate_view_lib", - "@com_github_google_quiche//:quic_core_crypto_crypto_handshake_lib", - "@com_github_google_quiche//:quic_core_versions_lib", - "@com_github_google_quiche//:quic_platform", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_proof_verifier_base.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_proof_verifier_base.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_utils_lib", + "@com_github_google_quiche//:quic_core_crypto_certificate_view_lib", + "@com_github_google_quiche//:quic_core_crypto_crypto_handshake_lib", + "@com_github_google_quiche//:quic_core_versions_lib", + "@com_github_google_quiche//:quic_platform", + ], + }), ) envoy_cc_library( name = "envoy_quic_proof_verifier_lib", - srcs = ["envoy_quic_proof_verifier.cc"], - hdrs = ["envoy_quic_proof_verifier.h"], - tags = ["nofips"], - deps = [ - ":envoy_quic_proof_verifier_base_lib", - ":envoy_quic_utils_lib", - ":quic_ssl_connection_info_lib", - "//source/common/tls:context_lib", - "@com_github_google_quiche//:quic_platform", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_proof_verifier.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_proof_verifier.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_proof_verifier_base_lib", + ":envoy_quic_utils_lib", + ":quic_ssl_connection_info_lib", + "//source/common/tls:context_lib", + "@com_github_google_quiche//:quic_platform", + ], + }), ) envoy_cc_library( name = "envoy_quic_stream_lib", - srcs = ["envoy_quic_stream.cc"], - hdrs = ["envoy_quic_stream.h"], - tags = ["nofips"], - deps = [ - ":envoy_quic_simulated_watermark_buffer_lib", - ":envoy_quic_utils_lib", - ":quic_filter_manager_connection_lib", - ":quic_stats_gatherer", - ":send_buffer_monitor_lib", - "//envoy/event:dispatcher_interface", - "//envoy/http:codec_interface", - "//source/common/http:codec_helper_lib", - "@com_github_google_quiche//:http2_adapter", - "@com_github_google_quiche//:quic_core_http_client_lib", - "@com_github_google_quiche//:quic_core_http_http_encoder_lib", - "@envoy_api//envoy/config/core/v3:pkg_cc_proto", - ] + envoy_select_enable_http_datagrams([ + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_stream.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_stream.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_simulated_watermark_buffer_lib", + ":envoy_quic_utils_lib", + ":quic_filter_manager_connection_lib", + ":quic_stats_gatherer", + ":send_buffer_monitor_lib", + "//envoy/event:dispatcher_interface", + "//envoy/http:codec_interface", + "//source/common/http:codec_helper_lib", + "@com_github_google_quiche//:http2_adapter", + "@com_github_google_quiche//:quic_core_http_client_lib", + "@com_github_google_quiche//:quic_core_http_http_encoder_lib", + "@envoy_api//envoy/config/core/v3:pkg_cc_proto", + ], + }) + envoy_select_enable_http_datagrams([ ":http_datagram_handler", ]), ) envoy_cc_library( name = "client_connection_factory_lib", - srcs = ["client_connection_factory_impl.cc"], - hdrs = ["client_connection_factory_impl.h"], - tags = ["nofips"], - deps = [ - ":envoy_quic_alarm_factory_lib", - ":envoy_quic_client_session_lib", - ":envoy_quic_connection_helper_lib", - ":envoy_quic_proof_verifier_lib", - ":envoy_quic_utils_lib", - "//envoy/http:codec_interface", - "//envoy/http:persistent_quic_info_interface", - "//envoy/registry", - "//source/common/runtime:runtime_lib", - "//source/common/tls:client_ssl_socket_lib", - "//source/extensions/quic/crypto_stream:envoy_quic_crypto_client_stream_lib", - "@com_github_google_quiche//:quic_core_http_spdy_session_lib", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["client_connection_factory_impl.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["client_connection_factory_impl.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_alarm_factory_lib", + ":envoy_quic_client_session_lib", + ":envoy_quic_connection_helper_lib", + ":envoy_quic_proof_verifier_lib", + ":envoy_quic_utils_lib", + "//envoy/http:codec_interface", + "//envoy/http:persistent_quic_info_interface", + "//envoy/registry", + "//source/common/runtime:runtime_lib", + "//source/common/tls:client_ssl_socket_lib", + "//source/extensions/quic/crypto_stream:envoy_quic_crypto_client_stream_lib", + "@com_github_google_quiche//:quic_core_http_spdy_session_lib", + ], + }), ) envoy_cc_library( name = "client_codec_lib", - srcs = ["client_codec_impl.cc"], - hdrs = [ - "client_codec_impl.h", - "codec_impl.h", - ], - tags = ["nofips"], - deps = [ - ":envoy_quic_client_session_lib", - ":envoy_quic_utils_lib", - "//envoy/http:codec_interface", - "//envoy/registry", - "@com_github_google_quiche//:quic_core_http_spdy_session_lib", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["client_codec_impl.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "client_codec_impl.h", + "codec_impl.h", + ], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_client_session_lib", + ":envoy_quic_utils_lib", + "//envoy/http:codec_interface", + "//envoy/registry", + "@com_github_google_quiche//:quic_core_http_spdy_session_lib", + ], + }), ) envoy_cc_library( name = "server_codec_lib", - srcs = ["server_codec_impl.cc"], - hdrs = [ - "codec_impl.h", - "server_codec_impl.h", - ], - tags = ["nofips"], - deps = [ - ":envoy_quic_server_session_lib", - ":envoy_quic_utils_lib", - ":quic_server_factory_stub_lib", - "//envoy/http:codec_interface", - "//envoy/registry", - "@com_github_google_quiche//:quic_core_http_spdy_session_lib", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["server_codec_impl.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "codec_impl.h", + "server_codec_impl.h", + ], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_server_session_lib", + ":envoy_quic_utils_lib", + ":quic_server_factory_stub_lib", + "//envoy/http:codec_interface", + "//envoy/registry", + "@com_github_google_quiche//:quic_core_http_spdy_session_lib", + ], + }), alwayslink = LEGACY_ALWAYSLINK, ) envoy_cc_library( name = "quic_ssl_connection_info_lib", - hdrs = ["quic_ssl_connection_info.h"], + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["quic_ssl_connection_info.h"], + }), external_deps = ["ssl"], - tags = ["nofips"], - deps = [ - "//source/common/tls:connection_info_impl_base_lib", - "@com_github_google_quiche//:quic_core_session_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/common/tls:connection_info_impl_base_lib", + "@com_github_google_quiche//:quic_core_session_lib", + ], + }), ) envoy_cc_library( name = "quic_filter_manager_connection_lib", - srcs = ["quic_filter_manager_connection_impl.cc"], - hdrs = ["quic_filter_manager_connection_impl.h"], - tags = ["nofips"], - deps = [ - ":envoy_quic_simulated_watermark_buffer_lib", - ":quic_network_connection_lib", - ":quic_ssl_connection_info_lib", - ":quic_stat_names_lib", - ":send_buffer_monitor_lib", - "//envoy/event:dispatcher_interface", - "//envoy/network:connection_interface", - "//source/common/buffer:buffer_lib", - "//source/common/common:assert_lib", - "//source/common/common:empty_string", - "//source/common/http:header_map_lib", - "//source/common/http/http3:codec_stats_lib", - "//source/common/network:connection_base_lib", - "//source/common/stream_info:stream_info_lib", - "@com_github_google_quiche//:quic_core_connection_lib", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["quic_filter_manager_connection_impl.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["quic_filter_manager_connection_impl.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_simulated_watermark_buffer_lib", + ":quic_network_connection_lib", + ":quic_ssl_connection_info_lib", + ":quic_stat_names_lib", + ":send_buffer_monitor_lib", + "//envoy/event:dispatcher_interface", + "//envoy/network:connection_interface", + "//source/common/buffer:buffer_lib", + "//source/common/common:assert_lib", + "//source/common/common:empty_string", + "//source/common/http:header_map_lib", + "//source/common/http/http3:codec_stats_lib", + "//source/common/network:connection_base_lib", + "//source/common/stream_info:stream_info_lib", + "@com_github_google_quiche//:quic_core_connection_lib", + ], + }), ) envoy_cc_library( name = "envoy_quic_server_session_lib", - srcs = [ - "envoy_quic_server_session.cc", - "envoy_quic_server_stream.cc", - ], - hdrs = [ - "envoy_quic_server_session.h", - "envoy_quic_server_stream.h", - ], - tags = ["nofips"], - deps = [ - ":envoy_quic_connection_debug_visitor_factory_interface", - ":envoy_quic_proof_source_lib", - ":envoy_quic_server_connection_lib", - ":envoy_quic_server_crypto_stream_factory_lib", - ":envoy_quic_stream_lib", - ":envoy_quic_utils_lib", - ":quic_filter_manager_connection_lib", - ":quic_stat_names_lib", - ":quic_stats_gatherer", - "//source/common/buffer:buffer_lib", - "//source/common/common:assert_lib", - "//source/common/http:header_map_lib", - "@com_github_google_quiche//:quic_server_http_spdy_session_lib", - "@com_google_absl//absl/types:optional", - ] + envoy_select_enable_http_datagrams([ + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "envoy_quic_server_session.cc", + "envoy_quic_server_stream.cc", + ], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "envoy_quic_server_session.h", + "envoy_quic_server_stream.h", + ], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_connection_debug_visitor_factory_interface", + ":envoy_quic_proof_source_lib", + ":envoy_quic_server_connection_lib", + ":envoy_quic_server_crypto_stream_factory_lib", + ":envoy_quic_stream_lib", + ":envoy_quic_utils_lib", + ":quic_filter_manager_connection_lib", + ":quic_stat_names_lib", + ":quic_stats_gatherer", + "//source/common/buffer:buffer_lib", + "//source/common/common:assert_lib", + "//source/common/http:header_map_lib", + "@com_github_google_quiche//:quic_server_http_spdy_session_lib", + "@com_google_absl//absl/types:optional", + ], + }) + envoy_select_enable_http_datagrams([ ":http_datagram_handler", ]), ) envoy_cc_library( name = "envoy_quic_client_session_lib", - srcs = [ - "envoy_quic_client_session.cc", - "envoy_quic_client_stream.cc", - "quic_network_connectivity_observer.cc", - ], - hdrs = [ - "envoy_quic_client_session.h", - "envoy_quic_client_stream.h", - "envoy_quic_network_observer_registry_factory.h", - "quic_network_connectivity_observer.h", - ], - tags = ["nofips"], - deps = [ - ":envoy_quic_client_connection_lib", - ":envoy_quic_client_crypto_stream_factory_lib", - ":envoy_quic_proof_verifier_lib", - ":envoy_quic_stream_lib", - ":envoy_quic_utils_lib", - ":quic_filter_manager_connection_lib", - ":quic_stat_names_lib", - ":quic_transport_socket_factory_lib", - "//envoy/http:http_server_properties_cache_interface", - "//source/common/buffer:buffer_lib", - "//source/common/common:assert_lib", - "//source/common/http:codes_lib", - "//source/common/http:header_map_lib", - "//source/common/http:header_utility_lib", - "@com_github_google_quiche//:quic_core_http_client_lib", - ] + envoy_select_enable_http_datagrams([ + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "envoy_quic_client_session.cc", + "envoy_quic_client_stream.cc", + "quic_network_connectivity_observer.cc", + ], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "envoy_quic_client_session.h", + "envoy_quic_client_stream.h", + "envoy_quic_network_observer_registry_factory.h", + "quic_network_connectivity_observer.h", + ], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_client_connection_lib", + ":envoy_quic_client_crypto_stream_factory_lib", + ":envoy_quic_proof_verifier_lib", + ":envoy_quic_stream_lib", + ":envoy_quic_utils_lib", + ":quic_filter_manager_connection_lib", + ":quic_stat_names_lib", + ":quic_transport_socket_factory_lib", + "//envoy/http:http_server_properties_cache_interface", + "//source/common/buffer:buffer_lib", + "//source/common/common:assert_lib", + "//source/common/http:codes_lib", + "//source/common/http:header_map_lib", + "//source/common/http:header_utility_lib", + "@com_github_google_quiche//:quic_core_http_client_lib", + ], + }) + envoy_select_enable_http_datagrams([ ":http_datagram_handler", ]), ) @@ -346,7 +488,6 @@ envoy_cc_library( hdrs = [ "envoy_quic_network_observer_registry_factory.h", ], - tags = ["nofips"], deps = envoy_select_enable_http3([ ":envoy_quic_client_session_lib", ]), @@ -365,7 +506,6 @@ envoy_cc_library( name = "quic_network_connection_lib", srcs = ["quic_network_connection.cc"], hdrs = ["quic_network_connection.h"], - tags = ["nofips"], deps = [ "//envoy/network:connection_interface", ], @@ -373,54 +513,78 @@ envoy_cc_library( envoy_cc_library( name = "envoy_quic_server_connection_lib", - srcs = ["envoy_quic_server_connection.cc"], - hdrs = ["envoy_quic_server_connection.h"], - tags = ["nofips"], - deps = [ - ":quic_io_handle_wrapper_lib", - ":quic_network_connection_lib", - "//source/common/network:generic_listener_filter_impl_base_lib", - "//source/common/network:listen_socket_lib", - "//source/common/quic:envoy_quic_utils_lib", - "@com_github_google_quiche//:quic_core_connection_lib", - "@com_github_google_quiche//:quic_core_packet_writer_lib", - "@com_github_google_quiche//:quic_core_packets_lib", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_server_connection.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_server_connection.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":quic_io_handle_wrapper_lib", + ":quic_network_connection_lib", + "//source/common/network:generic_listener_filter_impl_base_lib", + "//source/common/network:listen_socket_lib", + "//source/common/quic:envoy_quic_utils_lib", + "@com_github_google_quiche//:quic_core_connection_lib", + "@com_github_google_quiche//:quic_core_packet_writer_lib", + "@com_github_google_quiche//:quic_core_packets_lib", + ], + }), ) envoy_cc_library( name = "envoy_quic_client_connection_lib", - srcs = ["envoy_quic_client_connection.cc"], - hdrs = ["envoy_quic_client_connection.h"], - tags = ["nofips"], - deps = [ - ":envoy_quic_packet_writer_lib", - ":quic_network_connection_lib", - "//envoy/event:dispatcher_interface", - "//source/common/network:socket_option_factory_lib", - "//source/common/network:udp_packet_writer_handler_lib", - "//source/common/runtime:runtime_lib", - "@com_github_google_quiche//:quic_core_connection_lib", - "@envoy_api//envoy/config/core/v3:pkg_cc_proto", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_client_connection.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_client_connection.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_packet_writer_lib", + ":quic_network_connection_lib", + "//envoy/event:dispatcher_interface", + "//source/common/network:socket_option_factory_lib", + "//source/common/network:udp_packet_writer_handler_lib", + "//source/common/runtime:runtime_lib", + "@com_github_google_quiche//:quic_core_connection_lib", + "@envoy_api//envoy/config/core/v3:pkg_cc_proto", + ], + }), ) envoy_cc_library( name = "envoy_quic_dispatcher_lib", - srcs = ["envoy_quic_dispatcher.cc"], - hdrs = ["envoy_quic_dispatcher.h"], - tags = ["nofips"], - deps = [ - ":envoy_quic_connection_debug_visitor_factory_interface", - ":envoy_quic_proof_source_lib", - ":envoy_quic_server_connection_lib", - ":envoy_quic_server_crypto_stream_factory_lib", - ":envoy_quic_server_session_lib", - ":quic_stat_names_lib", - "//envoy/network:listener_interface", - "@com_github_google_quiche//:quic_core_server_lib", - "@com_github_google_quiche//:quic_core_utils_lib", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_dispatcher.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_dispatcher.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_connection_debug_visitor_factory_interface", + ":envoy_quic_proof_source_lib", + ":envoy_quic_server_connection_lib", + ":envoy_quic_server_crypto_stream_factory_lib", + ":envoy_quic_server_session_lib", + ":quic_stat_names_lib", + "//envoy/network:listener_interface", + "@com_github_google_quiche//:quic_core_server_lib", + "@com_github_google_quiche//:quic_core_utils_lib", + ], + }), ) envoy_cc_library( @@ -431,105 +595,137 @@ envoy_cc_library( envoy_cc_library( name = "active_quic_listener_lib", - srcs = ["active_quic_listener.cc"], - hdrs = ["active_quic_listener.h"], - tags = ["nofips"], - deps = [ - ":envoy_quic_alarm_factory_lib", - ":envoy_quic_connection_debug_visitor_factory_interface", - ":envoy_quic_connection_helper_lib", - ":envoy_quic_dispatcher_lib", - ":envoy_quic_packet_writer_lib", - ":envoy_quic_proof_source_factory_interface", - ":envoy_quic_proof_source_lib", - ":envoy_quic_server_preferred_address_config_factory_interface", - ":envoy_quic_utils_lib", - "//envoy/network:listener_interface", - "//source/common/network:listener_lib", - "//source/common/protobuf:utility_lib", - "//source/common/runtime:runtime_lib", - "//source/extensions/quic/connection_id_generator/deterministic:envoy_deterministic_connection_id_generator_config", - "//source/server:active_udp_listener", - "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", - "@envoy_api//envoy/extensions/quic/connection_id_generator/v3:pkg_cc_proto", - "@envoy_api//envoy/extensions/quic/crypto_stream/v3:pkg_cc_proto", - "@envoy_api//envoy/extensions/quic/proof_source/v3:pkg_cc_proto", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["active_quic_listener.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["active_quic_listener.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_alarm_factory_lib", + ":envoy_quic_connection_debug_visitor_factory_interface", + ":envoy_quic_connection_helper_lib", + ":envoy_quic_dispatcher_lib", + ":envoy_quic_packet_writer_lib", + ":envoy_quic_proof_source_factory_interface", + ":envoy_quic_proof_source_lib", + ":envoy_quic_server_preferred_address_config_factory_interface", + ":envoy_quic_utils_lib", + "//envoy/network:listener_interface", + "//source/common/network:listener_lib", + "//source/common/protobuf:utility_lib", + "//source/common/runtime:runtime_lib", + "//source/extensions/quic/connection_id_generator/deterministic:envoy_deterministic_connection_id_generator_config", + "//source/server:active_udp_listener", + "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/quic/connection_id_generator/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/quic/crypto_stream/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/quic/proof_source/v3:pkg_cc_proto", + ], + }), ) envoy_cc_library( name = "envoy_quic_utils_lib", - srcs = ["envoy_quic_utils.cc"], - hdrs = ["envoy_quic_utils.h"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_utils.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_utils.h"], + }), external_deps = ["ssl"], - tags = ["nofips"], - deps = [ - "//envoy/http:codec_interface", - "//source/common/http:header_map_lib", - "//source/common/http:header_utility_lib", - "//source/common/network:address_lib", - "//source/common/network:connection_socket_lib", - "//source/common/network:socket_option_factory_lib", - "//source/common/protobuf:utility_lib", - "//source/common/quic:quic_io_handle_wrapper_lib", - "@com_github_google_quiche//:quic_core_config_lib", - "@com_github_google_quiche//:quic_core_http_header_list_lib", - "@com_github_google_quiche//:quic_platform", - "@envoy_api//envoy/config/core/v3:pkg_cc_proto", - "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//envoy/http:codec_interface", + "//source/common/http:header_map_lib", + "//source/common/http:header_utility_lib", + "//source/common/network:address_lib", + "//source/common/network:connection_socket_lib", + "//source/common/network:socket_option_factory_lib", + "//source/common/protobuf:utility_lib", + "//source/common/quic:quic_io_handle_wrapper_lib", + "@com_github_google_quiche//:quic_core_config_lib", + "@com_github_google_quiche//:quic_core_http_header_list_lib", + "@com_github_google_quiche//:quic_platform", + "@envoy_api//envoy/config/core/v3:pkg_cc_proto", + "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", + ], + }), ) envoy_cc_library( name = "quic_transport_socket_factory_lib", - srcs = [ - "quic_client_transport_socket_factory.cc", - "quic_transport_socket_factory.cc", - ], - hdrs = [ - "quic_client_transport_socket_factory.h", - "quic_transport_socket_factory.h", - ], - tags = ["nofips"], - deps = [ - ":envoy_quic_proof_verifier_lib", - "//envoy/network:transport_socket_interface", - "//envoy/server:transport_socket_config_interface", - "//envoy/ssl:context_config_interface", - "//source/common/common:assert_lib", - "//source/common/network:transport_socket_options_lib", - "//source/common/quic:cert_compression_lib", - "//source/common/tls:client_ssl_socket_lib", - "//source/common/tls:context_config_lib", - "@com_github_google_quiche//:quic_core_crypto_crypto_handshake_lib", - "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "quic_client_transport_socket_factory.cc", + "quic_transport_socket_factory.cc", + ], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "quic_client_transport_socket_factory.h", + "quic_transport_socket_factory.h", + ], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_proof_verifier_lib", + "//envoy/network:transport_socket_interface", + "//envoy/server:transport_socket_config_interface", + "//envoy/ssl:context_config_interface", + "//source/common/common:assert_lib", + "//source/common/network:transport_socket_options_lib", + "//source/common/quic:cert_compression_lib", + "//source/common/tls:client_ssl_socket_lib", + "//source/common/tls:context_config_lib", + "@com_github_google_quiche//:quic_core_crypto_crypto_handshake_lib", + "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", + ], + }), alwayslink = LEGACY_ALWAYSLINK, ) envoy_cc_library( name = "quic_server_transport_socket_factory_lib", - srcs = [ - "quic_server_transport_socket_factory.cc", - ], - hdrs = [ - "quic_server_transport_socket_factory.h", - ], - tags = ["nofips"], - deps = [ - ":envoy_quic_proof_verifier_lib", - ":quic_transport_socket_factory_lib", - "//envoy/network:transport_socket_interface", - "//envoy/server:transport_socket_config_interface", - "//envoy/ssl:context_config_interface", - "//source/common/common:assert_lib", - "//source/common/network:transport_socket_options_lib", - "//source/common/tls:server_context_config_lib", - "//source/common/tls:server_context_lib", - "//source/common/tls:server_ssl_socket_lib", - "@com_github_google_quiche//:quic_core_crypto_crypto_handshake_lib", - "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "quic_server_transport_socket_factory.cc", + ], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "quic_server_transport_socket_factory.h", + ], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_proof_verifier_lib", + ":quic_transport_socket_factory_lib", + "//envoy/network:transport_socket_interface", + "//envoy/server:transport_socket_config_interface", + "//envoy/ssl:context_config_interface", + "//source/common/common:assert_lib", + "//source/common/network:transport_socket_options_lib", + "//source/common/tls:server_context_config_lib", + "//source/common/tls:server_context_lib", + "//source/common/tls:server_ssl_socket_lib", + "@com_github_google_quiche//:quic_core_crypto_crypto_handshake_lib", + "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", + ], + }), alwayslink = LEGACY_ALWAYSLINK, ) @@ -537,13 +733,8 @@ envoy_cc_library( # All of these are needed for this extension to function. envoy_cc_library( name = "quic_client_factory_lib", - tags = ["nofips"], - # 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. deps = select({ - "//bazel:boringssl_fips": [], - "//bazel:boringssl_disabled": [], + "//bazel:disable_http3": [], "//conditions:default": [ ":client_codec_lib", ":quic_transport_socket_factory_lib", @@ -568,13 +759,8 @@ envoy_cc_library( # All of these are needed for this extension to function. envoy_cc_library( name = "quic_server_factory_lib", - tags = ["nofips"], - # 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. deps = select({ - "//bazel:boringssl_fips": [], - "//bazel:boringssl_disabled": [], + "//bazel:disable_http3": [], "//conditions:default": [ ":quic_transport_socket_factory_lib", ":server_codec_lib", @@ -586,155 +772,235 @@ envoy_cc_library( envoy_cc_library( name = "envoy_quic_packet_writer_lib", - srcs = ["envoy_quic_packet_writer.cc"], - hdrs = ["envoy_quic_packet_writer.h"], - tags = ["nofips"], - deps = [ - ":envoy_quic_utils_lib", - "@com_github_google_quiche//:quic_core_packet_writer_lib", - "@com_github_google_quiche//:quic_platform", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_packet_writer.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_packet_writer.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_utils_lib", + "@com_github_google_quiche//:quic_core_packet_writer_lib", + "@com_github_google_quiche//:quic_platform", + ], + }), ) envoy_cc_library( name = "udp_gso_batch_writer_lib", srcs = select({ - "//bazel:linux": ["udp_gso_batch_writer.cc"], + ":http3_enabled_and_linux": ["udp_gso_batch_writer.cc"], "//conditions:default": [], }), - hdrs = ["udp_gso_batch_writer.h"], - tags = ["nofips"], - deps = [ - ":envoy_quic_utils_lib", - "//envoy/network:udp_packet_writer_handler_interface", - "//source/common/network:io_socket_error_lib", - "//source/common/protobuf:utility_lib", - "//source/common/runtime:runtime_lib", - "@com_github_google_quiche//:quic_platform", - ] + select({ - "//bazel:linux": ["@com_github_google_quiche//:quic_core_batch_writer_gso_batch_writer_lib"], + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["udp_gso_batch_writer.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_utils_lib", + "//envoy/network:udp_packet_writer_handler_interface", + "//source/common/network:io_socket_error_lib", + "//source/common/protobuf:utility_lib", + "//source/common/runtime:runtime_lib", + "@com_github_google_quiche//:quic_platform", + ], + }) + select({ + ":http3_enabled_and_linux": ["@com_github_google_quiche//:quic_core_batch_writer_gso_batch_writer_lib"], "//conditions:default": [], }), ) envoy_cc_library( name = "send_buffer_monitor_lib", - srcs = ["send_buffer_monitor.cc"], - hdrs = ["send_buffer_monitor.h"], - tags = ["nofips"], - deps = [ - "//source/common/common:assert_lib", - "@com_github_google_quiche//:quic_core_session_lib", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["send_buffer_monitor.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["send_buffer_monitor.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/common/common:assert_lib", + "@com_github_google_quiche//:quic_core_session_lib", + ], + }), ) envoy_cc_library( name = "envoy_quic_client_crypto_stream_factory_lib", - hdrs = ["envoy_quic_client_crypto_stream_factory.h"], - tags = ["nofips"], - deps = [ - "//envoy/common:optref_lib", - "//envoy/config:typed_config_interface", - "//envoy/network:transport_socket_interface", - "@com_github_google_quiche//:quic_client_session_lib", - "@com_github_google_quiche//:quic_core_http_spdy_session_lib", - ], + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_client_crypto_stream_factory.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//envoy/common:optref_lib", + "//envoy/config:typed_config_interface", + "//envoy/network:transport_socket_interface", + "@com_github_google_quiche//:quic_client_session_lib", + "@com_github_google_quiche//:quic_core_http_spdy_session_lib", + ], + }), ) envoy_cc_library( name = "envoy_quic_server_crypto_stream_factory_lib", - hdrs = ["envoy_quic_server_crypto_stream_factory.h"], - tags = ["nofips"], - deps = [ - "//envoy/config:typed_config_interface", - "@com_github_google_quiche//:quic_core_http_spdy_session_lib", - "@com_github_google_quiche//:quic_server_session_lib", - ], + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_server_crypto_stream_factory.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//envoy/config:typed_config_interface", + "@com_github_google_quiche//:quic_core_http_spdy_session_lib", + "@com_github_google_quiche//:quic_server_session_lib", + ], + }), ) envoy_cc_library( name = "envoy_quic_proof_source_factory_interface", - hdrs = ["envoy_quic_proof_source_factory_interface.h"], - tags = ["nofips"], - deps = [ - "//envoy/config:typed_config_interface", - "@com_github_google_quiche//:quic_core_crypto_proof_source_lib", - ], + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_proof_source_factory_interface.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//envoy/config:typed_config_interface", + "@com_github_google_quiche//:quic_core_crypto_proof_source_lib", + ], + }), ) envoy_cc_library( name = "envoy_quic_connection_id_generator_factory_interface", - hdrs = ["envoy_quic_connection_id_generator_factory.h"], - tags = ["nofips"], - deps = [ - "//envoy/config:typed_config_interface", - "@com_github_google_quiche//:quic_core_connection_id_generator_interface_lib", - "@com_github_google_quiche//:quic_load_balancer_encoder_lib", - ], + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_connection_id_generator_factory.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//envoy/config:typed_config_interface", + "@com_github_google_quiche//:quic_core_connection_id_generator_interface_lib", + "@com_github_google_quiche//:quic_load_balancer_encoder_lib", + ], + }), ) envoy_cc_library( name = "envoy_deterministic_connection_id_generator_lib", - srcs = ["envoy_deterministic_connection_id_generator.cc"], - hdrs = ["envoy_deterministic_connection_id_generator.h"], - tags = ["nofips"], - deps = [ - ":envoy_quic_connection_id_generator_factory_interface", - ":envoy_quic_utils_lib", - "@com_github_google_quiche//:quic_core_deterministic_connection_id_generator_lib", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_deterministic_connection_id_generator.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_deterministic_connection_id_generator.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_connection_id_generator_factory_interface", + ":envoy_quic_utils_lib", + "@com_github_google_quiche//:quic_core_deterministic_connection_id_generator_lib", + ], + }), ) envoy_cc_library( name = "envoy_quic_server_preferred_address_config_factory_interface", - hdrs = ["envoy_quic_server_preferred_address_config_factory.h"], - tags = ["nofips"], - deps = [ - "//envoy/config:typed_config_interface", - "//envoy/network:address_interface", - "//envoy/server:factory_context_interface", - "@com_github_google_quiche//:quic_platform_socket_address", - ], + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_server_preferred_address_config_factory.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//envoy/config:typed_config_interface", + "//envoy/network:address_interface", + "//envoy/server:factory_context_interface", + "@com_github_google_quiche//:quic_platform_socket_address", + ], + }), ) envoy_cc_library( name = "quic_stats_gatherer", - srcs = ["quic_stats_gatherer.cc"], - hdrs = ["quic_stats_gatherer.h"], - tags = ["nofips"], - deps = [ - "//envoy/access_log:access_log_interface", - "//envoy/formatter:http_formatter_context_interface", - "//envoy/http:codec_interface", - "//source/common/formatter:substitution_formatter_lib", - "//source/common/http:header_map_lib", - "@com_github_google_quiche//:quic_core_ack_listener_interface_lib", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["quic_stats_gatherer.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["quic_stats_gatherer.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//envoy/access_log:access_log_interface", + "//envoy/formatter:http_formatter_context_interface", + "//envoy/http:codec_interface", + "//source/common/formatter:substitution_formatter_lib", + "//source/common/http:header_map_lib", + "@com_github_google_quiche//:quic_core_ack_listener_interface_lib", + ], + }), ) envoy_cc_library( name = "http_datagram_handler", - srcs = ["http_datagram_handler.cc"], - hdrs = ["http_datagram_handler.h"], - deps = [ - "//envoy/http:codec_interface", - "//source/common/buffer:buffer_lib", - "//source/common/common:logger_lib", - "//source/common/http:header_map_lib", - "@com_github_google_quiche//:quic_core_http_spdy_session_lib", - "@com_github_google_quiche//:quic_core_types_lib", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["http_datagram_handler.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["http_datagram_handler.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//envoy/http:codec_interface", + "//source/common/buffer:buffer_lib", + "//source/common/common:logger_lib", + "//source/common/http:header_map_lib", + "@com_github_google_quiche//:quic_core_http_spdy_session_lib", + "@com_github_google_quiche//:quic_core_types_lib", + ], + }), ) envoy_cc_library( name = "cert_compression_lib", - srcs = ["cert_compression.cc"], - hdrs = ["cert_compression.h"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["cert_compression.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["cert_compression.h"], + }), external_deps = ["ssl"], - deps = [ - "//bazel/foreign_cc:zlib", - "//source/common/common:assert_lib", - "//source/common/common:logger_lib", - "//source/common/runtime:runtime_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//bazel/foreign_cc:zlib", + "//source/common/common:assert_lib", + "//source/common/common:logger_lib", + "//source/common/runtime:runtime_lib", + ], + }), ) diff --git a/source/common/quic/platform/BUILD b/source/common/quic/platform/BUILD index 76f9fccfd0..172740fc6b 100644 --- a/source/common/quic/platform/BUILD +++ b/source/common/quic/platform/BUILD @@ -82,7 +82,6 @@ envoy_quiche_platform_impl_cc_library( "quiche_bug_tracker_impl.h", "quiche_logging_impl.h", ], - tags = ["nofips"], deps = [ "//source/common/common:assert_lib", "//source/common/common:utility_lib", @@ -91,7 +90,6 @@ envoy_quiche_platform_impl_cc_library( envoy_quiche_platform_impl_cc_library( name = "quic_base_impl_lib", - tags = ["nofips"], deps = [ ":quiche_flags_impl_lib", "//source/common/common:assert_lib", @@ -111,7 +109,6 @@ envoy_quiche_platform_impl_cc_library( hdrs = [ "quiche_iovec_impl.h", ], - tags = ["nofips"], deps = [ "//envoy/common:base_includes", ], @@ -122,7 +119,6 @@ envoy_quiche_platform_impl_cc_library( hdrs = [ "quiche_stack_trace_impl.h", ], - tags = ["nofips"], deps = [ "//source/server:backtrace_lib", "@com_github_google_quiche//:quiche_common_platform_export", @@ -151,13 +147,11 @@ envoy_quiche_platform_impl_cc_library( envoy_quiche_platform_impl_cc_library( name = "quiche_lower_case_string_impl_lib", hdrs = ["quiche_lower_case_string_impl.h"], - tags = ["nofips"], deps = ["//envoy/http:header_map_interface"], ) envoy_quiche_platform_impl_cc_library( name = "quiche_export_impl_lib", hdrs = ["quiche_export_impl.h"], - tags = ["nofips"], deps = ["@com_google_absl//absl/base"], ) diff --git a/source/common/quic/platform/mobile_impl/BUILD b/source/common/quic/platform/mobile_impl/BUILD index 45b447c35c..83fabaadf3 100644 --- a/source/common/quic/platform/mobile_impl/BUILD +++ b/source/common/quic/platform/mobile_impl/BUILD @@ -16,7 +16,6 @@ envoy_quiche_platform_impl_cc_library( hdrs = [ "quiche_bug_tracker_impl.h", ], - tags = ["nofips"], deps = [ "@com_github_google_quiche//:quiche_common_platform_logging", ], diff --git a/source/extensions/quic/connection_debug_visitor/basic/BUILD b/source/extensions/quic/connection_debug_visitor/basic/BUILD index f38a89aec3..f95ed8d6a2 100644 --- a/source/extensions/quic/connection_debug_visitor/basic/BUILD +++ b/source/extensions/quic/connection_debug_visitor/basic/BUILD @@ -17,24 +17,32 @@ envoy_extension_package() envoy_cc_library( name = "envoy_quic_connection_debug_visitor_basic_lib", - srcs = ["envoy_quic_connection_debug_visitor_basic.cc"], - hdrs = ["envoy_quic_connection_debug_visitor_basic.h"], - tags = ["nofips"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_connection_debug_visitor_basic.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_connection_debug_visitor_basic.h"], + }), visibility = [ "//source/common/quic:__subpackages__", ], - deps = [ - "//envoy/registry", - "//envoy/stream_info:stream_info_interface", - "//source/common/common:minimal_logger_lib", - "//source/common/protobuf:utility_lib", - "//source/common/quic:envoy_quic_connection_debug_visitor_factory_interface", - "@com_github_google_quiche//:quic_core_connection_lib", - "@com_github_google_quiche//:quic_core_frames_frames_lib", - "@com_github_google_quiche//:quic_core_session_lib", - "@com_github_google_quiche//:quic_core_types_lib", - "@envoy_api//envoy/extensions/quic/connection_debug_visitor/v3:pkg_cc_proto", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//envoy/registry", + "//envoy/stream_info:stream_info_interface", + "//source/common/common:minimal_logger_lib", + "//source/common/protobuf:utility_lib", + "//source/common/quic:envoy_quic_connection_debug_visitor_factory_interface", + "@com_github_google_quiche//:quic_core_connection_lib", + "@com_github_google_quiche//:quic_core_frames_frames_lib", + "@com_github_google_quiche//:quic_core_session_lib", + "@com_github_google_quiche//:quic_core_types_lib", + "@envoy_api//envoy/extensions/quic/connection_debug_visitor/v3:pkg_cc_proto", + ], + }), alwayslink = LEGACY_ALWAYSLINK, ) @@ -44,14 +52,10 @@ envoy_cc_extension( "//source/common/quic:__subpackages__", "//test:__subpackages__", ], - tags = ["nofips"], - deps = select( - { - "//bazel:boringssl_fips": [], - "//bazel:boringssl_disabled": [], - "//conditions:default": [ - ":envoy_quic_connection_debug_visitor_basic_lib", - ], - }, - ), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_connection_debug_visitor_basic_lib", + ], + }), ) diff --git a/source/extensions/quic/connection_debug_visitor/quic_stats/BUILD b/source/extensions/quic/connection_debug_visitor/quic_stats/BUILD index c4797c56b0..1586f522b8 100644 --- a/source/extensions/quic/connection_debug_visitor/quic_stats/BUILD +++ b/source/extensions/quic/connection_debug_visitor/quic_stats/BUILD @@ -15,18 +15,26 @@ envoy_extension_package() envoy_cc_library( name = "quic_stats_lib", - srcs = ["quic_stats.cc"], - hdrs = ["quic_stats.h"], - tags = ["nofips"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["quic_stats.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["quic_stats.h"], + }), visibility = [ "//test:__subpackages__", ], - deps = [ - "//envoy/registry", - "//source/common/protobuf:utility_lib", - "//source/common/quic:envoy_quic_connection_debug_visitor_factory_interface", - "@envoy_api//envoy/extensions/quic/connection_debug_visitor/quic_stats/v3:pkg_cc_proto", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//envoy/registry", + "//source/common/protobuf:utility_lib", + "//source/common/quic:envoy_quic_connection_debug_visitor_factory_interface", + "@envoy_api//envoy/extensions/quic/connection_debug_visitor/quic_stats/v3:pkg_cc_proto", + ], + }), alwayslink = LEGACY_ALWAYSLINK, ) @@ -36,14 +44,10 @@ envoy_cc_extension( "//source/common/quic:__subpackages__", "//test:__subpackages__", ], - tags = ["nofips"], - deps = select( - { - "//bazel:boringssl_fips": [], - "//bazel:boringssl_disabled": [], - "//conditions:default": [ - ":quic_stats_lib", - ], - }, - ), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":quic_stats_lib", + ], + }), ) diff --git a/source/extensions/quic/connection_id_generator/deterministic/BUILD b/source/extensions/quic/connection_id_generator/deterministic/BUILD index 9ba5a2f8a5..dd191bd936 100644 --- a/source/extensions/quic/connection_id_generator/deterministic/BUILD +++ b/source/extensions/quic/connection_id_generator/deterministic/BUILD @@ -17,15 +17,23 @@ envoy_extension_package() envoy_cc_library( name = "envoy_deterministic_connection_id_generator_config_lib", - srcs = ["envoy_deterministic_connection_id_generator_config.cc"], - hdrs = ["envoy_deterministic_connection_id_generator_config.h"], - tags = ["nofips"], - deps = [ - "//envoy/registry", - "//source/common/quic:envoy_deterministic_connection_id_generator_lib", - "//source/common/quic:envoy_quic_connection_id_generator_factory_interface", - "@envoy_api//envoy/extensions/quic/connection_id_generator/v3:pkg_cc_proto", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_deterministic_connection_id_generator_config.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_deterministic_connection_id_generator_config.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//envoy/registry", + "//source/common/quic:envoy_deterministic_connection_id_generator_lib", + "//source/common/quic:envoy_quic_connection_id_generator_factory_interface", + "@envoy_api//envoy/extensions/quic/connection_id_generator/v3:pkg_cc_proto", + ], + }), alwayslink = LEGACY_ALWAYSLINK, ) @@ -34,14 +42,10 @@ envoy_cc_extension( extra_visibility = [ "//source/common/quic:__subpackages__", ], - tags = ["nofips"], - deps = select( - { - "//bazel:boringssl_fips": [], - "//bazel:boringssl_disabled": [], - "//conditions:default": [ - ":envoy_deterministic_connection_id_generator_config_lib", - ], - }, - ), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_deterministic_connection_id_generator_config_lib", + ], + }), ) diff --git a/source/extensions/quic/connection_id_generator/quic_lb/BUILD b/source/extensions/quic/connection_id_generator/quic_lb/BUILD index 23f669de82..2c41663756 100644 --- a/source/extensions/quic/connection_id_generator/quic_lb/BUILD +++ b/source/extensions/quic/connection_id_generator/quic_lb/BUILD @@ -15,44 +15,56 @@ envoy_extension_package() envoy_cc_library( name = "quic_lb_lib", - srcs = ["quic_lb.cc"], - hdrs = ["quic_lb.h"], - tags = ["nofips"], - deps = [ - "//source/common/config:datasource_lib", - "//source/common/quic:envoy_quic_connection_id_generator_factory_interface", - "//source/common/quic:envoy_quic_utils_lib", - "@com_github_google_quiche//:quic_load_balancer_config_lib", - "@com_github_google_quiche//:quic_load_balancer_encoder_lib", - "@com_github_google_quiche//:quic_load_balancer_server_id_lib", - "@envoy_api//envoy/extensions/quic/connection_id_generator/quic_lb/v3:pkg_cc_proto", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["quic_lb.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["quic_lb.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/common/config:datasource_lib", + "//source/common/quic:envoy_quic_connection_id_generator_factory_interface", + "//source/common/quic:envoy_quic_utils_lib", + "@com_github_google_quiche//:quic_load_balancer_config_lib", + "@com_github_google_quiche//:quic_load_balancer_encoder_lib", + "@com_github_google_quiche//:quic_load_balancer_server_id_lib", + "@envoy_api//envoy/extensions/quic/connection_id_generator/quic_lb/v3:pkg_cc_proto", + ], + }), ) envoy_cc_library( name = "config_lib", - srcs = ["config.cc"], - hdrs = ["config.h"], - tags = ["nofips"], - deps = [ - ":quic_lb_lib", - "//envoy/registry", - "//source/common/quic:envoy_quic_connection_id_generator_factory_interface", - "@envoy_api//envoy/extensions/quic/connection_id_generator/quic_lb/v3:pkg_cc_proto", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["config.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["config.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":quic_lb_lib", + "//envoy/registry", + "//source/common/quic:envoy_quic_connection_id_generator_factory_interface", + "@envoy_api//envoy/extensions/quic/connection_id_generator/quic_lb/v3:pkg_cc_proto", + ], + }), alwayslink = LEGACY_ALWAYSLINK, ) envoy_cc_extension( name = "quic_lb_config", - tags = ["nofips"], - deps = select( - { - "//bazel:boringssl_fips": [], - "//bazel:boringssl_disabled": [], - "//conditions:default": [ - ":config_lib", - ], - }, - ), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":config_lib", + ], + }), ) diff --git a/source/extensions/quic/crypto_stream/BUILD b/source/extensions/quic/crypto_stream/BUILD index d358631954..c6786be588 100644 --- a/source/extensions/quic/crypto_stream/BUILD +++ b/source/extensions/quic/crypto_stream/BUILD @@ -17,18 +17,26 @@ envoy_extension_package() envoy_cc_library( name = "envoy_quic_crypto_server_stream_lib", - srcs = ["envoy_quic_crypto_server_stream.cc"], - hdrs = ["envoy_quic_crypto_server_stream.h"], - tags = ["nofips"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_crypto_server_stream.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_crypto_server_stream.h"], + }), visibility = [ "//source/common/quic:__subpackages__", "//test:__subpackages__", ], - deps = [ - "//envoy/registry", - "//source/common/quic:envoy_quic_server_crypto_stream_factory_lib", - "@envoy_api//envoy/extensions/quic/crypto_stream/v3:pkg_cc_proto", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//envoy/registry", + "//source/common/quic:envoy_quic_server_crypto_stream_factory_lib", + "@envoy_api//envoy/extensions/quic/crypto_stream/v3:pkg_cc_proto", + ], + }), alwayslink = LEGACY_ALWAYSLINK, ) @@ -38,29 +46,33 @@ envoy_cc_extension( "//source/common/quic:__subpackages__", "//test:__subpackages__", ], - tags = ["nofips"], - deps = select( - { - "//bazel:boringssl_fips": [], - "//bazel:boringssl_disabled": [], - "//conditions:default": [ - ":envoy_quic_crypto_server_stream_lib", - ], - }, - ), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_crypto_server_stream_lib", + ], + }), ) envoy_cc_library( name = "envoy_quic_crypto_client_stream_lib", - srcs = ["envoy_quic_crypto_client_stream.cc"], - hdrs = ["envoy_quic_crypto_client_stream.h"], - tags = ["nofips"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_crypto_client_stream.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_crypto_client_stream.h"], + }), visibility = [ "//source/common/quic:__subpackages__", "//test:__subpackages__", ], - deps = [ - "//source/common/quic:envoy_quic_client_crypto_stream_factory_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/common/quic:envoy_quic_client_crypto_stream_factory_lib", + ], + }), alwayslink = LEGACY_ALWAYSLINK, ) diff --git a/source/extensions/quic/proof_source/BUILD b/source/extensions/quic/proof_source/BUILD index 358e5123af..27ce732bd6 100644 --- a/source/extensions/quic/proof_source/BUILD +++ b/source/extensions/quic/proof_source/BUILD @@ -17,18 +17,26 @@ envoy_extension_package() envoy_cc_library( name = "envoy_quic_proof_source_factory_impl_lib", - srcs = ["envoy_quic_proof_source_factory_impl.cc"], - hdrs = ["envoy_quic_proof_source_factory_impl.h"], - tags = ["nofips"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_proof_source_factory_impl.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_proof_source_factory_impl.h"], + }), visibility = [ "//source/common/quic:__subpackages__", "//test:__subpackages__", ], - deps = [ - "//source/common/quic:envoy_quic_proof_source_factory_interface", - "//source/common/quic:envoy_quic_proof_source_lib", - "@envoy_api//envoy/extensions/quic/proof_source/v3:pkg_cc_proto", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/common/quic:envoy_quic_proof_source_factory_interface", + "//source/common/quic:envoy_quic_proof_source_lib", + "@envoy_api//envoy/extensions/quic/proof_source/v3:pkg_cc_proto", + ], + }), alwayslink = LEGACY_ALWAYSLINK, ) @@ -38,14 +46,10 @@ envoy_cc_extension( "//source/common/quic:__subpackages__", "//test:__subpackages__", ], - tags = ["nofips"], - deps = select( - { - "//bazel:boringssl_fips": [], - "//bazel:boringssl_disabled": [], - "//conditions:default": [ - ":envoy_quic_proof_source_factory_impl_lib", - ], - }, - ), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":envoy_quic_proof_source_factory_impl_lib", + ], + }), ) diff --git a/source/extensions/quic/server_preferred_address/BUILD b/source/extensions/quic/server_preferred_address/BUILD index c531ca057a..40deed67fc 100644 --- a/source/extensions/quic/server_preferred_address/BUILD +++ b/source/extensions/quic/server_preferred_address/BUILD @@ -17,26 +17,42 @@ envoy_extension_package() envoy_cc_library( name = "server_preferred_address_lib", - srcs = ["server_preferred_address.cc"], - hdrs = ["server_preferred_address.h"], - tags = ["nofips"], - deps = [ - "//source/common/quic:envoy_quic_server_preferred_address_config_factory_interface", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["server_preferred_address.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["server_preferred_address.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/common/quic:envoy_quic_server_preferred_address_config_factory_interface", + ], + }), ) envoy_cc_library( name = "fixed_server_preferred_address_config_lib", - srcs = ["fixed_server_preferred_address_config.cc"], - hdrs = ["fixed_server_preferred_address_config.h"], - tags = ["nofips"], - deps = [ - ":server_preferred_address_lib", - "//envoy/registry", - "//source/common/quic:envoy_quic_server_preferred_address_config_factory_interface", - "//source/common/quic:envoy_quic_utils_lib", - "@envoy_api//envoy/extensions/quic/server_preferred_address/v3:pkg_cc_proto", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["fixed_server_preferred_address_config.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["fixed_server_preferred_address_config.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":server_preferred_address_lib", + "//envoy/registry", + "//source/common/quic:envoy_quic_server_preferred_address_config_factory_interface", + "//source/common/quic:envoy_quic_utils_lib", + "@envoy_api//envoy/extensions/quic/server_preferred_address/v3:pkg_cc_proto", + ], + }), alwayslink = LEGACY_ALWAYSLINK, ) @@ -45,44 +61,44 @@ envoy_cc_extension( extra_visibility = [ "//test:__subpackages__", ], - tags = ["nofips"], - deps = select( - { - "//bazel:boringssl_fips": [], - "//bazel:boringssl_disabled": [], - "//conditions:default": [ - ":fixed_server_preferred_address_config_lib", - ], - }, - ), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":fixed_server_preferred_address_config_lib", + ], + }), ) envoy_cc_library( name = "datasource_server_preferred_address_config_lib", - srcs = ["datasource_server_preferred_address_config.cc"], - hdrs = ["datasource_server_preferred_address_config.h"], - tags = ["nofips"], - deps = [ - ":server_preferred_address_lib", - "//envoy/registry", - "//source/common/config:datasource_lib", - "//source/common/quic:envoy_quic_server_preferred_address_config_factory_interface", - "//source/common/quic:envoy_quic_utils_lib", - "@envoy_api//envoy/extensions/quic/server_preferred_address/v3:pkg_cc_proto", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["datasource_server_preferred_address_config.cc"], + }), + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["datasource_server_preferred_address_config.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":server_preferred_address_lib", + "//envoy/registry", + "//source/common/config:datasource_lib", + "//source/common/quic:envoy_quic_server_preferred_address_config_factory_interface", + "//source/common/quic:envoy_quic_utils_lib", + "@envoy_api//envoy/extensions/quic/server_preferred_address/v3:pkg_cc_proto", + ], + }), alwayslink = LEGACY_ALWAYSLINK, ) envoy_cc_extension( name = "datasource_server_preferred_address_config_factory_config", - tags = ["nofips"], - deps = select( - { - "//bazel:boringssl_fips": [], - "//bazel:boringssl_disabled": [], - "//conditions:default": [ - ":datasource_server_preferred_address_config_lib", - ], - }, - ), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":datasource_server_preferred_address_config_lib", + ], + }), ) diff --git a/source/extensions/udp_packet_writer/gso/BUILD b/source/extensions/udp_packet_writer/gso/BUILD index 59cbce650e..e98e170c41 100644 --- a/source/extensions/udp_packet_writer/gso/BUILD +++ b/source/extensions/udp_packet_writer/gso/BUILD @@ -21,7 +21,6 @@ envoy_cc_extension( "//source/server:__subpackages__", "//source/common/listener_manager:__subpackages__", ], - tags = ["nofips"], deps = [ "//envoy/config:typed_config_interface", "//envoy/network:udp_packet_writer_handler_interface", diff --git a/test/common/http/http3/BUILD b/test/common/http/http3/BUILD index 4e881a4c98..e34a486509 100644 --- a/test/common/http/http3/BUILD +++ b/test/common/http/http3/BUILD @@ -13,7 +13,6 @@ envoy_cc_test( name = "conn_pool_test", srcs = envoy_select_enable_http3(["conn_pool_test.cc"]), rbe_pool = "6gig", - tags = ["nofips"], deps = envoy_select_enable_http3([ "//source/common/event:dispatcher_lib", "//source/common/http/http3:conn_pool_lib", diff --git a/test/common/listener_manager/BUILD b/test/common/listener_manager/BUILD index 23917a4379..d5fd7e2b2f 100644 --- a/test/common/listener_manager/BUILD +++ b/test/common/listener_manager/BUILD @@ -109,25 +109,31 @@ envoy_cc_test( # Stand-alone quic test because of FIPS. envoy_cc_test( name = "listener_manager_impl_quic_only_test", - srcs = ["listener_manager_impl_quic_only_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["listener_manager_impl_quic_only_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - ":listener_manager_impl_test_lib", - "//source/common/formatter:formatter_extension_lib", - "//source/extensions/filters/http/router:config", - "//source/extensions/matching/network/common:inputs_lib", - "//source/extensions/quic/server_preferred_address:fixed_server_preferred_address_config_factory_config", - "//source/extensions/request_id/uuid:config", - "//source/extensions/transport_sockets/raw_buffer:config", - "//source/extensions/transport_sockets/tls:config", - "//test/integration/filters:test_listener_filter_lib", - "//test/integration/filters:test_network_filter_lib", - "//test/server:utility_lib", - "//test/test_common:threadsafe_singleton_injector_lib", - "@envoy_api//envoy/config/core/v3:pkg_cc_proto", - "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":listener_manager_impl_test_lib", + "//source/common/formatter:formatter_extension_lib", + "//source/extensions/filters/http/router:config", + "//source/extensions/filters/network/http_connection_manager:config", + "//source/extensions/matching/network/common:inputs_lib", + "//source/extensions/quic/server_preferred_address:fixed_server_preferred_address_config_factory_config", + "//source/extensions/request_id/uuid:config", + "//source/extensions/transport_sockets/raw_buffer:config", + "//source/extensions/transport_sockets/tls:config", + "//test/integration/filters:test_listener_filter_lib", + "//test/integration/filters:test_network_filter_lib", + "//test/server:utility_lib", + "//test/test_common:threadsafe_singleton_injector_lib", + "@envoy_api//envoy/config/core/v3:pkg_cc_proto", + "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", + ], + }), ) envoy_cc_test( diff --git a/test/common/network/BUILD b/test/common/network/BUILD index 54d435c2a6..c889510a34 100644 --- a/test/common/network/BUILD +++ b/test/common/network/BUILD @@ -273,32 +273,37 @@ envoy_cc_test( envoy_cc_test( name = "udp_listener_impl_batch_writer_test", - srcs = ["udp_listener_impl_batch_writer_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["udp_listener_impl_batch_writer_test.cc"], + }), rbe_pool = "6gig", # Skipping as quiche quic_gso_batch_writer.h does not exist on Windows tags = [ - "nofips", "skip_on_windows", ], - deps = [ - ":udp_listener_impl_test_base_lib", - "//source/common/event:dispatcher_lib", - "//source/common/network:address_lib", - "//source/common/network:listener_lib", - "//source/common/network:socket_option_lib", - "//source/common/network:udp_packet_writer_handler_lib", - "//source/common/network:utility_lib", - "//source/common/quic:udp_gso_batch_writer_lib", - "//source/common/stats:stats_lib", - "//test/common/network:listener_impl_test_base_lib", - "//test/mocks/network:network_mocks", - "//test/test_common:environment_lib", - "//test/test_common:network_utility_lib", - "//test/test_common:threadsafe_singleton_injector_lib", - "//test/test_common:utility_lib", - "@com_github_google_quiche//:quic_test_tools_mock_syscall_wrapper_lib", - "@envoy_api//envoy/config/core/v3:pkg_cc_proto", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":udp_listener_impl_test_base_lib", + "//source/common/event:dispatcher_lib", + "//source/common/network:address_lib", + "//source/common/network:listener_lib", + "//source/common/network:socket_option_lib", + "//source/common/network:udp_packet_writer_handler_lib", + "//source/common/network:utility_lib", + "//source/common/quic:udp_gso_batch_writer_lib", + "//source/common/stats:stats_lib", + "//test/common/network:listener_impl_test_base_lib", + "//test/mocks/network:network_mocks", + "//test/test_common:environment_lib", + "//test/test_common:network_utility_lib", + "//test/test_common:threadsafe_singleton_injector_lib", + "//test/test_common:utility_lib", + "@com_github_google_quiche//:quic_test_tools_mock_syscall_wrapper_lib", + "@envoy_api//envoy/config/core/v3:pkg_cc_proto", + ], + }), ) envoy_cc_test( diff --git a/test/common/quic/BUILD b/test/common/quic/BUILD index 91fc850d2b..dccc5b0e81 100644 --- a/test/common/quic/BUILD +++ b/test/common/quic/BUILD @@ -5,7 +5,7 @@ load( "envoy_cc_test_library", "envoy_package", "envoy_proto_library", - "envoy_select_enable_http_datagrams", + "envoy_select_enable_http3", ) licenses(["notice"]) # Apache 2 @@ -14,289 +14,358 @@ envoy_package() envoy_cc_test( name = "envoy_quic_alarm_test", - srcs = ["envoy_quic_alarm_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_alarm_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - "//source/common/quic:envoy_quic_alarm_factory_lib", - "//source/common/quic:envoy_quic_alarm_lib", - "//source/common/quic:envoy_quic_clock_lib", - "//test/test_common:simulated_time_system_lib", - "//test/test_common:utility_lib", - "@com_github_google_quiche//:quic_platform", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/common/quic:envoy_quic_alarm_factory_lib", + "//source/common/quic:envoy_quic_alarm_lib", + "//source/common/quic:envoy_quic_clock_lib", + "//test/test_common:simulated_time_system_lib", + "//test/test_common:utility_lib", + "@com_github_google_quiche//:quic_platform", + ], + }), ) envoy_cc_test( name = "envoy_quic_clock_test", - srcs = ["envoy_quic_clock_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_clock_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - "//source/common/quic:envoy_quic_clock_lib", - "//test/test_common:simulated_time_system_lib", - "//test/test_common:test_time_lib", - "//test/test_common:utility_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/common/quic:envoy_quic_clock_lib", + "//test/test_common:simulated_time_system_lib", + "//test/test_common:test_time_lib", + "//test/test_common:utility_lib", + ], + }), ) envoy_cc_test( name = "envoy_quic_writer_test", - srcs = ["envoy_quic_writer_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_writer_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - "//source/common/network:io_socket_error_lib", - "//source/common/network:udp_packet_writer_handler_lib", - "//source/common/quic:envoy_quic_packet_writer_lib", - "//test/mocks/api:api_mocks", - "//test/mocks/network:network_mocks", - "//test/test_common:threadsafe_singleton_injector_lib", - "@com_github_google_quiche//:quic_platform", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/common/network:io_socket_error_lib", + "//source/common/network:udp_packet_writer_handler_lib", + "//source/common/quic:envoy_quic_packet_writer_lib", + "//test/mocks/api:api_mocks", + "//test/mocks/network:network_mocks", + "//test/test_common:threadsafe_singleton_injector_lib", + "@com_github_google_quiche//:quic_platform", + ], + }), ) envoy_cc_test( name = "envoy_quic_proof_source_test", - srcs = ["envoy_quic_proof_source_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_proof_source_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - ":test_utils_lib", - "//source/common/quic:envoy_quic_proof_source_lib", - "//source/common/quic:envoy_quic_proof_verifier_lib", - "//source/common/tls:context_config_lib", - "//source/common/tls:server_context_lib", - "//test/mocks/network:network_mocks", - "//test/mocks/server:server_factory_context_mocks", - "//test/mocks/ssl:ssl_mocks", - "//test/test_common:test_runtime_lib", - "@com_github_google_quiche//:quic_core_versions_lib", - "@com_github_google_quiche//:quic_platform", - "@com_github_google_quiche//:quic_test_tools_test_certificates_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":test_utils_lib", + "//source/common/quic:envoy_quic_proof_source_lib", + "//source/common/quic:envoy_quic_proof_verifier_lib", + "//source/common/tls:context_config_lib", + "//source/common/tls:server_context_lib", + "//test/mocks/network:network_mocks", + "//test/mocks/server:server_factory_context_mocks", + "//test/mocks/ssl:ssl_mocks", + "//test/test_common:test_runtime_lib", + "@com_github_google_quiche//:quic_core_versions_lib", + "@com_github_google_quiche//:quic_platform", + "@com_github_google_quiche//:quic_test_tools_test_certificates_lib", + ], + }), ) envoy_cc_test( name = "quic_filter_manager_connection_impl_test", - srcs = ["quic_filter_manager_connection_impl_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["quic_filter_manager_connection_impl_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - "//source/common/quic:quic_filter_manager_connection_lib", - "//test/mocks/event:event_mocks", - "//test/mocks/network:network_mocks", - "//test/test_common:utility_lib", - "@com_github_google_quiche//:quic_test_tools_test_utils_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/common/quic:quic_filter_manager_connection_lib", + "//test/mocks/event:event_mocks", + "//test/mocks/network:network_mocks", + "//test/test_common:utility_lib", + "@com_github_google_quiche//:quic_test_tools_test_utils_lib", + ], + }), ) envoy_cc_test( name = "quic_stat_names_test", - srcs = ["quic_stat_names_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["quic_stat_names_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - "//source/common/quic:quic_stat_names_lib", - "//source/common/stats:stats_lib", - "//test/mocks/stats:stats_mocks", - "//test/test_common:utility_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/common/quic:quic_stat_names_lib", + "//source/common/stats:stats_lib", + "//test/mocks/stats:stats_mocks", + "//test/test_common:utility_lib", + ], + }), ) envoy_cc_test( name = "envoy_quic_proof_verifier_test", - srcs = ["envoy_quic_proof_verifier_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_proof_verifier_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - ":test_utils_lib", - "//source/common/quic:envoy_quic_proof_verifier_lib", - "//source/common/tls:context_config_lib", - "//test/common/config:dummy_config_proto_cc_proto", - "//test/common/tls/cert_validator:timed_cert_validator", - "//test/mocks/event:event_mocks", - "//test/mocks/server:server_factory_context_mocks", - "//test/mocks/ssl:ssl_mocks", - "@com_github_google_quiche//:quic_platform", - "@com_github_google_quiche//:quic_test_tools_test_certificates_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":test_utils_lib", + "//source/common/quic:envoy_quic_proof_verifier_lib", + "//source/common/tls:context_config_lib", + "//test/common/config:dummy_config_proto_cc_proto", + "//test/common/tls/cert_validator:timed_cert_validator", + "//test/mocks/event:event_mocks", + "//test/mocks/server:server_factory_context_mocks", + "//test/mocks/ssl:ssl_mocks", + "@com_github_google_quiche//:quic_platform", + "@com_github_google_quiche//:quic_test_tools_test_certificates_lib", + ], + }), ) envoy_cc_test( name = "envoy_quic_server_stream_test", - srcs = ["envoy_quic_server_stream_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_server_stream_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - ":test_utils_lib", - "//source/common/http:headers_lib", - "//source/common/quic:envoy_quic_alarm_factory_lib", - "//source/common/quic:envoy_quic_connection_helper_lib", - "//source/common/quic:envoy_quic_server_connection_lib", - "//source/common/quic:envoy_quic_server_session_lib", - "//source/server:active_listener_base", - "//test/mocks/http:http_mocks", - "//test/mocks/http:stream_decoder_mock", - "//test/mocks/network:network_mocks", - "//test/test_common:utility_lib", - "@com_github_google_quiche//:quic_core_http_spdy_session_lib", - "@com_github_google_quiche//:quic_test_tools_qpack_qpack_test_utils_lib", - "@com_github_google_quiche//:quic_test_tools_session_peer_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":test_utils_lib", + "//source/common/http:headers_lib", + "//source/common/quic:envoy_quic_alarm_factory_lib", + "//source/common/quic:envoy_quic_connection_helper_lib", + "//source/common/quic:envoy_quic_server_connection_lib", + "//source/common/quic:envoy_quic_server_session_lib", + "//source/server:active_listener_base", + "//test/mocks/http:http_mocks", + "//test/mocks/http:stream_decoder_mock", + "//test/mocks/network:network_mocks", + "//test/test_common:utility_lib", + "@com_github_google_quiche//:quic_core_http_spdy_session_lib", + "@com_github_google_quiche//:quic_test_tools_qpack_qpack_test_utils_lib", + "@com_github_google_quiche//:quic_test_tools_session_peer_lib", + ], + }), ) envoy_cc_test( name = "envoy_quic_client_stream_test", - srcs = ["envoy_quic_client_stream_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_client_stream_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - ":test_utils_lib", - "//source/common/http:headers_lib", - "//source/common/quic:envoy_quic_alarm_factory_lib", - "//source/common/quic:envoy_quic_client_connection_lib", - "//source/common/quic:envoy_quic_client_session_lib", - "//source/common/quic:envoy_quic_connection_helper_lib", - "//test/mocks/http:http_mocks", - "//test/mocks/http:stream_decoder_mock", - "//test/mocks/network:network_mocks", - "//test/test_common:utility_lib", - "@com_github_google_quiche//:quic_core_http_spdy_session_lib", - "@com_github_google_quiche//:quic_test_tools_qpack_qpack_test_utils_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":test_utils_lib", + "//source/common/http:headers_lib", + "//source/common/quic:envoy_quic_alarm_factory_lib", + "//source/common/quic:envoy_quic_client_connection_lib", + "//source/common/quic:envoy_quic_client_session_lib", + "//source/common/quic:envoy_quic_connection_helper_lib", + "//test/mocks/http:http_mocks", + "//test/mocks/http:stream_decoder_mock", + "//test/mocks/network:network_mocks", + "//test/test_common:utility_lib", + "@com_github_google_quiche//:quic_core_http_spdy_session_lib", + "@com_github_google_quiche//:quic_test_tools_qpack_qpack_test_utils_lib", + ], + }), ) envoy_cc_test( name = "envoy_quic_server_session_test", - srcs = ["envoy_quic_server_session_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_server_session_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - ":test_proof_source_lib", - ":test_utils_lib", - "//envoy/stats:stats_macros", - "//source/common/quic:envoy_quic_alarm_factory_lib", - "//source/common/quic:envoy_quic_connection_helper_lib", - "//source/common/quic:envoy_quic_server_connection_lib", - "//source/common/quic:envoy_quic_server_session_lib", - "//source/common/quic:server_codec_lib", - "//source/server:configuration_lib", - "//test/mocks/event:event_mocks", - "//test/mocks/http:http_mocks", - "//test/mocks/http:stream_decoder_mock", - "//test/mocks/network:network_mocks", - "//test/mocks/stats:stats_mocks", - "//test/test_common:global_lib", - "//test/test_common:logging_lib", - "//test/test_common:simulated_time_system_lib", - "@com_github_google_quiche//:quic_test_tools_config_peer_lib", - "@com_github_google_quiche//:quic_test_tools_server_session_base_peer", - "@com_github_google_quiche//:quic_test_tools_test_utils_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":test_proof_source_lib", + ":test_utils_lib", + "//envoy/stats:stats_macros", + "//source/common/quic:envoy_quic_alarm_factory_lib", + "//source/common/quic:envoy_quic_connection_helper_lib", + "//source/common/quic:envoy_quic_server_connection_lib", + "//source/common/quic:envoy_quic_server_session_lib", + "//source/common/quic:server_codec_lib", + "//source/server:configuration_lib", + "//test/mocks/event:event_mocks", + "//test/mocks/http:http_mocks", + "//test/mocks/http:stream_decoder_mock", + "//test/mocks/network:network_mocks", + "//test/mocks/stats:stats_mocks", + "//test/test_common:global_lib", + "//test/test_common:logging_lib", + "//test/test_common:simulated_time_system_lib", + "@com_github_google_quiche//:quic_test_tools_config_peer_lib", + "@com_github_google_quiche//:quic_test_tools_server_session_base_peer", + "@com_github_google_quiche//:quic_test_tools_test_utils_lib", + ], + }), ) envoy_cc_test( name = "envoy_quic_client_session_test", - srcs = ["envoy_quic_client_session_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_client_session_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - ":test_utils_lib", - "//envoy/stats:stats_macros", - "//source/common/api:os_sys_calls_lib", - "//source/common/quic:client_codec_lib", - "//source/common/quic:envoy_quic_alarm_factory_lib", - "//source/common/quic:envoy_quic_client_connection_lib", - "//source/common/quic:envoy_quic_client_session_lib", - "//source/common/quic:envoy_quic_connection_helper_lib", - "//source/extensions/quic/crypto_stream:envoy_quic_crypto_client_stream_lib", - "//test/mocks/api:api_mocks", - "//test/mocks/http:http_mocks", - "//test/mocks/http:stream_decoder_mock", - "//test/mocks/network:network_mocks", - "//test/mocks/stats:stats_mocks", - "//test/test_common:logging_lib", - "//test/test_common:simulated_time_system_lib", - "//test/test_common:test_runtime_lib", - "//test/test_common:threadsafe_singleton_injector_lib", - "@com_github_google_quiche//:quic_test_tools_session_peer_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":test_utils_lib", + "//envoy/stats:stats_macros", + "//source/common/api:os_sys_calls_lib", + "//source/common/quic:client_codec_lib", + "//source/common/quic:envoy_quic_alarm_factory_lib", + "//source/common/quic:envoy_quic_client_connection_lib", + "//source/common/quic:envoy_quic_client_session_lib", + "//source/common/quic:envoy_quic_connection_helper_lib", + "//source/extensions/quic/crypto_stream:envoy_quic_crypto_client_stream_lib", + "//test/mocks/api:api_mocks", + "//test/mocks/http:http_mocks", + "//test/mocks/http:stream_decoder_mock", + "//test/mocks/network:network_mocks", + "//test/mocks/stats:stats_mocks", + "//test/test_common:logging_lib", + "//test/test_common:simulated_time_system_lib", + "//test/test_common:test_runtime_lib", + "//test/test_common:threadsafe_singleton_injector_lib", + "@com_github_google_quiche//:quic_test_tools_session_peer_lib", + ], + }), ) envoy_cc_test( name = "active_quic_listener_test", - srcs = ["active_quic_listener_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["active_quic_listener_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - ":test_proof_source_lib", - ":test_utils_lib", - "//source/common/http:utility_lib", - "//source/common/listener_manager:connection_handler_lib", - "//source/common/network:udp_packet_writer_handler_lib", - "//source/common/quic:active_quic_listener_lib", - "//source/common/quic:envoy_quic_utils_lib", - "//source/common/quic:udp_gso_batch_writer_lib", - "//source/extensions/quic/crypto_stream:envoy_quic_crypto_server_stream_lib", - "//source/extensions/quic/proof_source:envoy_quic_proof_source_factory_impl_lib", - "//source/server:configuration_lib", - "//source/server:process_context_lib", - "//test/mocks/network:network_mocks", - "//test/mocks/server:instance_mocks", - "//test/mocks/server:listener_factory_context_mocks", - "//test/test_common:network_utility_lib", - "//test/test_common:simulated_time_system_lib", - "//test/test_common:test_runtime_lib", - "@com_github_google_quiche//:quic_test_tools_crypto_server_config_peer_lib", - "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":test_proof_source_lib", + ":test_utils_lib", + "//source/common/http:utility_lib", + "//source/common/listener_manager:connection_handler_lib", + "//source/common/network:udp_packet_writer_handler_lib", + "//source/common/quic:active_quic_listener_lib", + "//source/common/quic:envoy_quic_utils_lib", + "//source/common/quic:udp_gso_batch_writer_lib", + "//source/extensions/quic/crypto_stream:envoy_quic_crypto_server_stream_lib", + "//source/extensions/quic/proof_source:envoy_quic_proof_source_factory_impl_lib", + "//source/server:configuration_lib", + "//source/server:process_context_lib", + "//test/mocks/network:network_mocks", + "//test/mocks/server:instance_mocks", + "//test/mocks/server:listener_factory_context_mocks", + "//test/test_common:network_utility_lib", + "//test/test_common:simulated_time_system_lib", + "//test/test_common:test_runtime_lib", + "@com_github_google_quiche//:quic_test_tools_crypto_server_config_peer_lib", + "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", + ], + }), ) envoy_cc_test( name = "envoy_quic_dispatcher_test", - srcs = ["envoy_quic_dispatcher_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_dispatcher_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - ":test_proof_source_lib", - ":test_utils_lib", - "//envoy/stats:stats_macros", - "//source/common/listener_manager:connection_handler_lib", - "//source/common/quic:envoy_quic_alarm_factory_lib", - "//source/common/quic:envoy_quic_connection_helper_lib", - "//source/common/quic:envoy_quic_dispatcher_lib", - "//source/common/quic:envoy_quic_proof_source_lib", - "//source/common/quic:envoy_quic_server_session_lib", - "//source/common/quic:quic_server_transport_socket_factory_lib", - "//source/extensions/quic/crypto_stream:envoy_quic_crypto_server_stream_lib", - "//source/server:configuration_lib", - "//test/mocks/event:event_mocks", - "//test/mocks/http:http_mocks", - "//test/mocks/network:network_mocks", - "//test/mocks/ssl:ssl_mocks", - "//test/mocks/stats:stats_mocks", - "//test/test_common:global_lib", - "//test/test_common:simulated_time_system_lib", - "//test/test_common:test_runtime_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":test_proof_source_lib", + ":test_utils_lib", + "//envoy/stats:stats_macros", + "//source/common/listener_manager:connection_handler_lib", + "//source/common/quic:envoy_quic_alarm_factory_lib", + "//source/common/quic:envoy_quic_connection_helper_lib", + "//source/common/quic:envoy_quic_dispatcher_lib", + "//source/common/quic:envoy_quic_proof_source_lib", + "//source/common/quic:envoy_quic_server_session_lib", + "//source/common/quic:quic_server_transport_socket_factory_lib", + "//source/extensions/quic/crypto_stream:envoy_quic_crypto_server_stream_lib", + "//source/server:configuration_lib", + "//test/mocks/event:event_mocks", + "//test/mocks/http:http_mocks", + "//test/mocks/network:network_mocks", + "//test/mocks/ssl:ssl_mocks", + "//test/mocks/stats:stats_mocks", + "//test/test_common:global_lib", + "//test/test_common:simulated_time_system_lib", + "//test/test_common:test_runtime_lib", + ], + }), ) envoy_cc_test_library( name = "test_proof_source_lib", - hdrs = ["test_proof_source.h"], - tags = ["nofips"], - deps = [ - "//source/common/quic:envoy_quic_proof_source_base_lib", - "//test/mocks/network:network_mocks", - "@com_github_google_quiche//:quic_test_tools_test_certificates_lib", - ], + hdrs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["test_proof_source.h"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/common/quic:envoy_quic_proof_source_base_lib", + "//test/mocks/network:network_mocks", + "@com_github_google_quiche//:quic_test_tools_test_certificates_lib", + ], + }), ) envoy_cc_test_library( name = "test_proof_verifier_lib", hdrs = ["test_proof_verifier.h"], - tags = ["nofips"], deps = [ "//source/common/quic:envoy_quic_proof_verifier_base_lib", ], @@ -304,71 +373,90 @@ envoy_cc_test_library( envoy_cc_test( name = "client_connection_factory_impl_test", - srcs = ["client_connection_factory_impl_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["client_connection_factory_impl_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - "//source/common/event:dispatcher_lib", - "//source/common/http/http3:conn_pool_lib", - "//source/common/network:utility_lib", - "//source/common/upstream:upstream_includes", - "//source/common/upstream:upstream_lib", - "//test/common/http:common_lib", - "//test/common/upstream:utility_lib", - "//test/mocks/event:event_mocks", - "//test/mocks/http:http_mocks", - "//test/mocks/http:http_server_properties_cache_mocks", - "//test/mocks/network:network_mocks", - "//test/mocks/runtime:runtime_mocks", - "//test/mocks/server:factory_context_mocks", - "//test/mocks/upstream:cluster_info_mocks", - "//test/mocks/upstream:transport_socket_match_mocks", - "//test/test_common:test_runtime_lib", - "//test/test_common:threadsafe_singleton_injector_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/common/event:dispatcher_lib", + "//source/common/http/http3:conn_pool_lib", + "//source/common/network:utility_lib", + "//source/common/upstream:upstream_includes", + "//source/common/upstream:upstream_lib", + "//test/common/http:common_lib", + "//test/common/upstream:utility_lib", + "//test/mocks/event:event_mocks", + "//test/mocks/http:http_mocks", + "//test/mocks/http:http_server_properties_cache_mocks", + "//test/mocks/network:network_mocks", + "//test/mocks/runtime:runtime_mocks", + "//test/mocks/server:factory_context_mocks", + "//test/mocks/upstream:cluster_info_mocks", + "//test/mocks/upstream:transport_socket_match_mocks", + "//test/test_common:test_runtime_lib", + "//test/test_common:threadsafe_singleton_injector_lib", + ], + }), ) envoy_cc_test( name = "quic_io_handle_wrapper_test", - srcs = ["quic_io_handle_wrapper_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["quic_io_handle_wrapper_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - "//source/common/quic:quic_io_handle_wrapper_lib", - "//test/mocks/api:api_mocks", - "//test/mocks/network:io_handle_mocks", - "//test/mocks/network:network_mocks", - "//test/test_common:threadsafe_singleton_injector_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/common/quic:quic_io_handle_wrapper_lib", + "//test/mocks/api:api_mocks", + "//test/mocks/network:io_handle_mocks", + "//test/mocks/network:network_mocks", + "//test/test_common:threadsafe_singleton_injector_lib", + ], + }), ) envoy_cc_test( name = "envoy_quic_utils_test", - srcs = ["envoy_quic_utils_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_utils_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - "//source/common/quic:envoy_quic_utils_lib", - "//test/mocks/api:api_mocks", - "//test/test_common:threadsafe_singleton_injector_lib", - "@com_github_google_quiche//:quic_test_tools_test_utils_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/common/quic:envoy_quic_utils_lib", + "//test/mocks/api:api_mocks", + "//test/test_common:threadsafe_singleton_injector_lib", + "@com_github_google_quiche//:quic_test_tools_test_utils_lib", + ], + }), ) envoy_cc_test( name = "envoy_quic_simulated_watermark_buffer_test", - srcs = ["envoy_quic_simulated_watermark_buffer_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_quic_simulated_watermark_buffer_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = ["//source/common/quic:envoy_quic_simulated_watermark_buffer_lib"], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["//source/common/quic:envoy_quic_simulated_watermark_buffer_lib"], + }), ) envoy_cc_test_library( name = "test_utils_lib", - hdrs = ["test_utils.h"], + hdrs = envoy_select_enable_http3(["test_utils.h"]), external_deps = ["bazel_runfiles"], - tags = ["nofips"], - deps = [ + deps = envoy_select_enable_http3([ "//envoy/stream_info:stream_info_interface", "//source/common/quic:envoy_quic_client_connection_lib", "//source/common/quic:envoy_quic_client_session_lib", @@ -382,48 +470,64 @@ envoy_cc_test_library( "@com_github_google_quiche//:quic_core_http_spdy_session_lib", "@com_github_google_quiche//:quic_test_tools_first_flight_lib", "@com_github_google_quiche//:quic_test_tools_qpack_qpack_test_utils_lib", - ], + ]), ) envoy_cc_test( name = "quic_transport_socket_factory_test", - srcs = ["quic_transport_socket_factory_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["quic_transport_socket_factory_test.cc"], + }), data = [ "//test/common/tls/test_data:certs", ], rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - "//source/common/quic:quic_server_transport_socket_factory_lib", - "//source/common/quic:quic_transport_socket_factory_lib", - "//source/common/tls:context_config_lib", - "//test/mocks/server:factory_context_mocks", - "//test/mocks/ssl:ssl_mocks", - "//test/test_common:environment_lib", - "//test/test_common:utility_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/common/quic:quic_server_transport_socket_factory_lib", + "//source/common/quic:quic_transport_socket_factory_lib", + "//source/common/tls:context_config_lib", + "//test/mocks/server:factory_context_mocks", + "//test/mocks/ssl:ssl_mocks", + "//test/test_common:environment_lib", + "//test/test_common:utility_lib", + ], + }), ) envoy_cc_test( name = "http_datagram_handler_test", - srcs = envoy_select_enable_http_datagrams(["http_datagram_handler_test.cc"]), + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["http_datagram_handler_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = envoy_select_enable_http_datagrams([ - "//source/common/quic:http_datagram_handler", - "//test/mocks/buffer:buffer_mocks", - "//test/test_common:utility_lib", - "@com_github_google_quiche//:quic_test_tools_test_utils_lib", - ]), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/common/quic:http_datagram_handler", + "//test/mocks/buffer:buffer_mocks", + "//test/test_common:utility_lib", + "@com_github_google_quiche//:quic_test_tools_test_utils_lib", + ], + }), ) envoy_cc_test( name = "cert_compression_test", - srcs = ["cert_compression_test.cc"], - deps = [ - "//source/common/quic:cert_compression_lib", - "//test/test_common:logging_lib", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["cert_compression_test.cc"], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/common/quic:cert_compression_lib", + "//test/test_common:logging_lib", + ], + }), ) envoy_cc_test_library( @@ -434,14 +538,19 @@ envoy_cc_test_library( envoy_cc_test( name = "envoy_deterministic_connection_id_generator_test", - srcs = ["envoy_deterministic_connection_id_generator_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["envoy_deterministic_connection_id_generator_test.cc"], + }), rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - ":connection_id_matchers", - "//source/common/quic:envoy_deterministic_connection_id_generator_lib", - "@com_github_google_quiche//:quic_test_tools_test_utils_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + ":connection_id_matchers", + "//source/common/quic:envoy_deterministic_connection_id_generator_lib", + "@com_github_google_quiche//:quic_test_tools_test_utils_lib", + ], + }), ) envoy_proto_library( @@ -454,7 +563,6 @@ envoy_cc_test_library( name = "envoy_quic_h3_fuzz_helper_lib", srcs = ["envoy_quic_h3_fuzz_helper.cc"], hdrs = ["envoy_quic_h3_fuzz_helper.h"], - tags = ["nofips"], deps = [ ":envoy_quic_h3_fuzz_proto_cc_proto", "//source/common/common:assert_lib", diff --git a/test/common/quic/platform/BUILD b/test/common/quic/platform/BUILD index 5033d92fba..5e5e14286c 100644 --- a/test/common/quic/platform/BUILD +++ b/test/common/quic/platform/BUILD @@ -24,7 +24,6 @@ envoy_cc_test( }), data = ["//test/common/tls/test_data:certs"], rbe_pool = "6gig", - tags = ["nofips"], deps = [ "//source/common/memory:stats_lib", "//source/common/quic/platform:quiche_flags_impl_lib", @@ -50,7 +49,6 @@ envoy_cc_test( envoy_quiche_platform_impl_cc_test_library( name = "quiche_expect_bug_impl_lib", hdrs = ["quiche_expect_bug_impl.h"], - tags = ["nofips"], deps = [ "@com_github_google_quiche//:quic_platform_base", ], @@ -59,7 +57,6 @@ envoy_quiche_platform_impl_cc_test_library( envoy_quiche_platform_impl_cc_test_library( name = "quiche_thread_impl_lib", hdrs = ["quiche_thread_impl.h"], - tags = ["nofips"], deps = [ "//envoy/thread:thread_interface", "//source/common/common:assert_lib", @@ -71,7 +68,6 @@ envoy_quiche_platform_impl_cc_test_library( name = "quiche_test_output_impl_lib", srcs = ["quiche_test_output_impl.cc"], hdrs = ["quiche_test_output_impl.h"], - tags = ["nofips"], deps = [ "//test/test_common:file_system_for_test_lib", "@com_github_google_quiche//:quic_platform_base", diff --git a/test/extensions/quic/connection_debug_visitor/quic_stats/BUILD b/test/extensions/quic/connection_debug_visitor/quic_stats/BUILD index 3acfa99766..09f8604492 100644 --- a/test/extensions/quic/connection_debug_visitor/quic_stats/BUILD +++ b/test/extensions/quic/connection_debug_visitor/quic_stats/BUILD @@ -13,26 +13,36 @@ envoy_package() envoy_extension_cc_test( name = "quic_stats_test", - srcs = ["quic_stats_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["quic_stats_test.cc"], + }), extension_names = ["envoy.quic.connection_debug_visitor.quic_stats"], - tags = ["nofips"], - deps = [ - "//source/extensions/quic/connection_debug_visitor/quic_stats:quic_stats_lib", - "//test/mocks/event:event_mocks", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/extensions/quic/connection_debug_visitor/quic_stats:quic_stats_lib", + "//test/mocks/event:event_mocks", + ], + }), ) envoy_extension_cc_test( name = "integration_test", size = "large", - srcs = ["integration_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["integration_test.cc"], + }), extension_names = ["envoy.quic.connection_debug_visitor.quic_stats"], rbe_pool = "2core", - tags = ["nofips"], - deps = [ - "//source/extensions/quic/connection_debug_visitor/quic_stats:config", - "//test/integration:http_integration_lib", - "@envoy_api//envoy/extensions/quic/connection_debug_visitor/quic_stats/v3:pkg_cc_proto", - "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/extensions/quic/connection_debug_visitor/quic_stats:config", + "//test/integration:http_integration_lib", + "@envoy_api//envoy/extensions/quic/connection_debug_visitor/quic_stats/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", + ], + }), ) diff --git a/test/extensions/quic/connection_id_generator/quic_lb/BUILD b/test/extensions/quic/connection_id_generator/quic_lb/BUILD index b5c25c401e..32a2b64afa 100644 --- a/test/extensions/quic/connection_id_generator/quic_lb/BUILD +++ b/test/extensions/quic/connection_id_generator/quic_lb/BUILD @@ -13,29 +13,39 @@ envoy_package() envoy_extension_cc_test( name = "quic_lb_test", - srcs = ["quic_lb_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["quic_lb_test.cc"], + }), extension_names = ["envoy.quic.connection_id_generator.quic_lb"], rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - "//source/extensions/quic/connection_id_generator/quic_lb:quic_lb_lib", - "//test/mocks/server:factory_context_mocks", - "@com_github_google_quiche//:quic_test_tools_test_utils_lib", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/extensions/quic/connection_id_generator/quic_lb:quic_lb_lib", + "//test/mocks/server:factory_context_mocks", + "@com_github_google_quiche//:quic_test_tools_test_utils_lib", + ], + }), ) envoy_extension_cc_test( name = "integration_test", size = "large", - srcs = ["integration_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["integration_test.cc"], + }), extension_names = ["envoy.quic.connection_id_generator.quic_lb"], rbe_pool = "4core", - tags = ["nofips"], - deps = [ - "//source/extensions/quic/connection_id_generator/quic_lb:quic_lb_config", - "//test/integration:http_integration_lib", - "//test/integration:quic_http_integration_test_lib", - "@envoy_api//envoy/extensions/quic/connection_id_generator/quic_lb/v3:pkg_cc_proto", - "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/extensions/quic/connection_id_generator/quic_lb:quic_lb_config", + "//test/integration:http_integration_lib", + "//test/integration:quic_http_integration_test_lib", + "@envoy_api//envoy/extensions/quic/connection_id_generator/quic_lb/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", + ], + }), ) diff --git a/test/extensions/quic/proof_source/BUILD b/test/extensions/quic/proof_source/BUILD index 43dcae1863..a4dfefc50e 100644 --- a/test/extensions/quic/proof_source/BUILD +++ b/test/extensions/quic/proof_source/BUILD @@ -12,7 +12,6 @@ envoy_cc_test_library( name = "pending_proof_source_factory_impl_lib", srcs = ["pending_proof_source_factory_impl.cc"], hdrs = ["pending_proof_source_factory_impl.h"], - tags = ["nofips"], deps = [ "//envoy/registry", "//source/common/quic:envoy_quic_proof_source_factory_interface", diff --git a/test/extensions/quic/server_preferred_address/BUILD b/test/extensions/quic/server_preferred_address/BUILD index 664f75d882..20f5f47ed8 100644 --- a/test/extensions/quic/server_preferred_address/BUILD +++ b/test/extensions/quic/server_preferred_address/BUILD @@ -13,26 +13,36 @@ envoy_package() envoy_extension_cc_test( name = "datasource_server_preferred_address_test", - srcs = ["datasource_server_preferred_address_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["datasource_server_preferred_address_test.cc"], + }), extension_names = ["envoy.quic.server_preferred_address.datasource"], rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - "//source/extensions/quic/server_preferred_address:datasource_server_preferred_address_config_lib", - "//test/mocks/protobuf:protobuf_mocks", - "//test/mocks/server:server_factory_context_mocks", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/extensions/quic/server_preferred_address:datasource_server_preferred_address_config_lib", + "//test/mocks/protobuf:protobuf_mocks", + "//test/mocks/server:server_factory_context_mocks", + ], + }), ) envoy_extension_cc_test( name = "fixed_server_preferred_address_test", - srcs = ["fixed_server_preferred_address_test.cc"], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": ["fixed_server_preferred_address_test.cc"], + }), extension_names = ["envoy.quic.server_preferred_address.fixed"], rbe_pool = "6gig", - tags = ["nofips"], - deps = [ - "//source/extensions/quic/server_preferred_address:fixed_server_preferred_address_config_lib", - "//test/mocks/protobuf:protobuf_mocks", - "//test/mocks/server:server_factory_context_mocks", - ], + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//source/extensions/quic/server_preferred_address:fixed_server_preferred_address_config_lib", + "//test/mocks/protobuf:protobuf_mocks", + "//test/mocks/server:server_factory_context_mocks", + ], + }), ) diff --git a/test/integration/BUILD b/test/integration/BUILD index 7fa04fe205..85d9472e5e 100644 --- a/test/integration/BUILD +++ b/test/integration/BUILD @@ -1485,16 +1485,19 @@ envoy_cc_test( shard_count = 2, tags = [ "cpu:3", - "nofips", ], deps = [ ":http_protocol_integration_lib", "//source/common/http:header_map_lib", - "//test/integration/filters:pause_filter_for_quic_lib", "//test/test_common:utility_lib", "@envoy_api//envoy/config/route/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg_cc_proto", - ], + ] + select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//test/integration/filters:pause_filter_for_quic_lib", + ], + }), ) envoy_cc_test( @@ -2556,7 +2559,6 @@ envoy_cc_test( shard_count = 16, tags = [ "cpu:4", - "nofips", ], deps = select({ "//bazel:disable_http3": [], @@ -2575,10 +2577,10 @@ envoy_cc_test( envoy_cc_test_library( name = "quic_http_integration_test_lib", - hdrs = [ + hdrs = envoy_select_enable_http3([ "quic_http_integration_test.h", - ], - deps = [ + ]), + deps = envoy_select_enable_http3([ ":http_integration_lib", ":socket_interface_swap_lib", "//source/common/quic:client_connection_factory_lib", @@ -2604,7 +2606,7 @@ envoy_cc_test_library( "@envoy_api//envoy/extensions/quic/connection_debug_visitor/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/quic/server_preferred_address/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", - ], + ]), ) # TODO(mattklein123): Use target_compatible_with when we switch to Bazel 4.0 instead of multiple @@ -2631,7 +2633,6 @@ envoy_cc_test( "cpu:3", "fails_on_clang_cl", "fails_on_windows", - "nofips", ], deps = envoy_select_enable_http3([ ":quic_http_integration_test_lib", diff --git a/test/integration/filters/BUILD b/test/integration/filters/BUILD index 2af61c2574..71999ad353 100644 --- a/test/integration/filters/BUILD +++ b/test/integration/filters/BUILD @@ -469,17 +469,22 @@ envoy_cc_test_library( envoy_cc_test_library( name = "pause_filter_for_quic_lib", - srcs = [ - "pause_filter_for_quic.cc", - ], - tags = ["nofips"], - deps = [ - "//envoy/http:filter_interface", - "//envoy/registry", - "//source/common/quic:quic_filter_manager_connection_lib", - "//source/extensions/filters/http/common:pass_through_filter_lib", - "//test/extensions/filters/http/common:empty_http_filter_config_lib", - ], + srcs = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "pause_filter_for_quic.cc", + ], + }), + deps = select({ + "//bazel:disable_http3": [], + "//conditions:default": [ + "//envoy/http:filter_interface", + "//envoy/registry", + "//source/common/quic:quic_filter_manager_connection_lib", + "//source/extensions/filters/http/common:pass_through_filter_lib", + "//test/extensions/filters/http/common:empty_http_filter_config_lib", + ], + }), ) envoy_cc_test_library( From 327bbe16fdc7fa7b56740eb9c4f5f883f6155242 Mon Sep 17 00:00:00 2001 From: Rohit Agrawal Date: Tue, 10 Jun 2025 14:37:19 -0700 Subject: [PATCH 14/35] quic: make the FIPS build macros consistent (#39809) ## Description This PR migrates everything to use the consistent `envoy_select_enable_http3` macro we have. --- **Commit Message:** quic: make the FIPS build macros consistent **Additional Description:** Make BUILD files consistent by using the recommended macro everywhere. **Risk Level:** Low **Testing:** CI **Docs Changes:** N/A **Release Notes:** N/A Signed-off-by: Rohit Agrawal --- source/common/http/http3/BUILD | 32 +- source/common/quic/BUILD | 1195 ++++++----------- .../network/http_connection_manager/config.cc | 9 + .../quic/connection_debug_visitor/basic/BUILD | 47 +- .../connection_debug_visitor/quic_stats/BUILD | 35 +- .../deterministic/BUILD | 35 +- .../connection_id_generator/quic_lb/BUILD | 66 +- source/extensions/quic/crypto_stream/BUILD | 52 +- source/extensions/quic/proof_source/BUILD | 33 +- .../quic/server_preferred_address/BUILD | 94 +- test/common/listener_manager/BUILD | 43 +- test/common/network/BUILD | 47 +- test/common/quic/BUILD | 658 ++++----- .../connection_debug_visitor/quic_stats/BUILD | 37 +- .../connection_id_generator/quic_lb/BUILD | 41 +- .../quic/server_preferred_address/BUILD | 37 +- test/integration/BUILD | 9 +- test/integration/filters/BUILD | 27 +- test/per_file_coverage.sh | 6 +- 19 files changed, 952 insertions(+), 1551 deletions(-) diff --git a/source/common/http/http3/BUILD b/source/common/http/http3/BUILD index c9820c2839..d2c9d66670 100644 --- a/source/common/http/http3/BUILD +++ b/source/common/http/http3/BUILD @@ -2,6 +2,7 @@ load( "//bazel:envoy_build_system.bzl", "envoy_cc_library", "envoy_package", + "envoy_select_enable_http3", ) licenses(["notice"]) # Apache 2 @@ -10,26 +11,17 @@ envoy_package() envoy_cc_library( name = "conn_pool_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["conn_pool.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["conn_pool.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//envoy/event:dispatcher_interface", - "//envoy/http:persistent_quic_info_interface", - "//envoy/upstream:upstream_interface", - "//source/common/http:codec_client_lib", - "//source/common/http:conn_pool_base_lib", - "//source/common/quic:client_connection_factory_lib", - "@com_github_google_quiche//:quic_core_deterministic_connection_id_generator_lib", - ], - }), + srcs = envoy_select_enable_http3(["conn_pool.cc"]), + hdrs = envoy_select_enable_http3(["conn_pool.h"]), + deps = envoy_select_enable_http3([ + "//envoy/event:dispatcher_interface", + "//envoy/http:persistent_quic_info_interface", + "//envoy/upstream:upstream_interface", + "//source/common/http:codec_client_lib", + "//source/common/http:conn_pool_base_lib", + "//source/common/quic:client_connection_factory_lib", + "@com_github_google_quiche//:quic_core_deterministic_connection_id_generator_lib", + ]), ) envoy_cc_library( diff --git a/source/common/quic/BUILD b/source/common/quic/BUILD index add884b5f4..c44d4a489a 100644 --- a/source/common/quic/BUILD +++ b/source/common/quic/BUILD @@ -29,102 +29,63 @@ envoy_package() envoy_cc_library( name = "envoy_quic_alarm_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_alarm.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_alarm.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//envoy/event:dispatcher_interface", - "//envoy/event:timer_interface", - "@com_github_google_quiche//:quic_core_alarm_lib", - "@com_github_google_quiche//:quic_core_clock_lib", - "@com_github_google_quiche//:quic_platform", - ], - }), + srcs = envoy_select_enable_http3(["envoy_quic_alarm.cc"]), + hdrs = envoy_select_enable_http3(["envoy_quic_alarm.h"]), + deps = envoy_select_enable_http3([ + "//envoy/event:dispatcher_interface", + "//envoy/event:timer_interface", + "@com_github_google_quiche//:quic_core_alarm_lib", + "@com_github_google_quiche//:quic_core_clock_lib", + "@com_github_google_quiche//:quic_platform", + ]), ) envoy_cc_library( name = "envoy_quic_alarm_factory_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_alarm_factory.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_alarm_factory.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_alarm_lib", - "@com_github_google_quiche//:quic_core_alarm_factory_lib", - "@com_github_google_quiche//:quic_core_arena_scoped_ptr_lib", - "@com_github_google_quiche//:quic_core_one_block_arena_lib", - "@com_github_google_quiche//:quic_platform", - ], - }), + srcs = envoy_select_enable_http3(["envoy_quic_alarm_factory.cc"]), + hdrs = envoy_select_enable_http3(["envoy_quic_alarm_factory.h"]), + deps = envoy_select_enable_http3([ + ":envoy_quic_alarm_lib", + "@com_github_google_quiche//:quic_core_alarm_factory_lib", + "@com_github_google_quiche//:quic_core_arena_scoped_ptr_lib", + "@com_github_google_quiche//:quic_core_one_block_arena_lib", + "@com_github_google_quiche//:quic_platform", + ]), ) envoy_cc_library( name = "envoy_quic_clock_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_clock.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_clock.h"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_clock.cc"]), + hdrs = envoy_select_enable_http3(["envoy_quic_clock.h"]), visibility = ["//visibility:public"], - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//envoy/event:dispatcher_interface", - "@com_github_google_quiche//:quic_core_clock_lib", - ], - }), + deps = envoy_select_enable_http3([ + "//envoy/event:dispatcher_interface", + "@com_github_google_quiche//:quic_core_clock_lib", + ]), ) envoy_cc_library( name = "envoy_quic_connection_debug_visitor_factory_interface", - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_connection_debug_visitor_factory_interface.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//envoy/common:optref_lib", - "//envoy/common:pure_lib", - "//envoy/config:typed_config_interface", - "//envoy/server:factory_context_interface", - "//envoy/stream_info:stream_info_interface", - "@com_github_google_quiche//:quic_core_connection_lib", - "@com_github_google_quiche//:quic_core_session_lib", - ], - }), + hdrs = envoy_select_enable_http3(["envoy_quic_connection_debug_visitor_factory_interface.h"]), + deps = envoy_select_enable_http3([ + "//envoy/common:optref_lib", + "//envoy/common:pure_lib", + "//envoy/config:typed_config_interface", + "//envoy/server:factory_context_interface", + "//envoy/stream_info:stream_info_interface", + "@com_github_google_quiche//:quic_core_connection_lib", + "@com_github_google_quiche//:quic_core_session_lib", + ]), ) envoy_cc_library( name = "envoy_quic_connection_helper_lib", - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_connection_helper.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_clock_lib", - "@com_github_google_quiche//:quic_core_connection_lib", - "@com_github_google_quiche//:quiche_common_random_lib", - ], - }), + hdrs = envoy_select_enable_http3(["envoy_quic_connection_helper.h"]), + deps = envoy_select_enable_http3([ + ":envoy_quic_clock_lib", + "@com_github_google_quiche//:quic_core_connection_lib", + "@com_github_google_quiche//:quiche_common_random_lib", + ]), ) envoy_cc_library( @@ -147,338 +108,233 @@ envoy_cc_library( envoy_cc_library( name = "envoy_quic_proof_source_base_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_proof_source_base.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_proof_source_base.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_utils_lib", - "@com_github_google_quiche//:quic_core_crypto_certificate_view_lib", - "@com_github_google_quiche//:quic_core_crypto_crypto_handshake_lib", - "@com_github_google_quiche//:quic_core_crypto_proof_source_lib", - "@com_github_google_quiche//:quic_core_data_lib", - "@com_github_google_quiche//:quic_core_versions_lib", - "@com_github_google_quiche//:quic_platform", - ], - }), + srcs = envoy_select_enable_http3(["envoy_quic_proof_source_base.cc"]), + hdrs = envoy_select_enable_http3(["envoy_quic_proof_source_base.h"]), + deps = envoy_select_enable_http3([ + ":envoy_quic_utils_lib", + "@com_github_google_quiche//:quic_core_crypto_certificate_view_lib", + "@com_github_google_quiche//:quic_core_crypto_crypto_handshake_lib", + "@com_github_google_quiche//:quic_core_crypto_proof_source_lib", + "@com_github_google_quiche//:quic_core_data_lib", + "@com_github_google_quiche//:quic_core_versions_lib", + "@com_github_google_quiche//:quic_platform", + ]), ) envoy_cc_library( name = "envoy_quic_proof_source_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_proof_source.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_proof_source.h"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_proof_source.cc"]), + hdrs = envoy_select_enable_http3(["envoy_quic_proof_source.h"]), external_deps = ["ssl"], - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_proof_source_base_lib", - ":envoy_quic_utils_lib", - ":quic_io_handle_wrapper_lib", - ":quic_transport_socket_factory_lib", - "//envoy/ssl:tls_certificate_config_interface", - "//source/common/quic:cert_compression_lib", - "//source/common/quic:quic_server_transport_socket_factory_lib", - "//source/common/stream_info:stream_info_lib", - "//source/server:listener_stats", - "@com_github_google_quiche//:quic_core_crypto_certificate_view_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":envoy_quic_proof_source_base_lib", + ":envoy_quic_utils_lib", + ":quic_io_handle_wrapper_lib", + ":quic_transport_socket_factory_lib", + "//envoy/ssl:tls_certificate_config_interface", + "//source/common/quic:cert_compression_lib", + "//source/common/quic:quic_server_transport_socket_factory_lib", + "//source/common/stream_info:stream_info_lib", + "//source/server:listener_stats", + "@com_github_google_quiche//:quic_core_crypto_certificate_view_lib", + ]), ) envoy_cc_library( name = "envoy_quic_proof_verifier_base_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_proof_verifier_base.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_proof_verifier_base.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_utils_lib", - "@com_github_google_quiche//:quic_core_crypto_certificate_view_lib", - "@com_github_google_quiche//:quic_core_crypto_crypto_handshake_lib", - "@com_github_google_quiche//:quic_core_versions_lib", - "@com_github_google_quiche//:quic_platform", - ], - }), + srcs = envoy_select_enable_http3(["envoy_quic_proof_verifier_base.cc"]), + hdrs = envoy_select_enable_http3(["envoy_quic_proof_verifier_base.h"]), + deps = envoy_select_enable_http3([ + ":envoy_quic_utils_lib", + "@com_github_google_quiche//:quic_core_crypto_certificate_view_lib", + "@com_github_google_quiche//:quic_core_crypto_crypto_handshake_lib", + "@com_github_google_quiche//:quic_core_versions_lib", + "@com_github_google_quiche//:quic_platform", + ]), ) envoy_cc_library( name = "envoy_quic_proof_verifier_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_proof_verifier.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_proof_verifier.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_proof_verifier_base_lib", - ":envoy_quic_utils_lib", - ":quic_ssl_connection_info_lib", - "//source/common/tls:context_lib", - "@com_github_google_quiche//:quic_platform", - ], - }), + srcs = envoy_select_enable_http3(["envoy_quic_proof_verifier.cc"]), + hdrs = envoy_select_enable_http3(["envoy_quic_proof_verifier.h"]), + deps = envoy_select_enable_http3([ + ":envoy_quic_proof_verifier_base_lib", + ":envoy_quic_utils_lib", + ":quic_ssl_connection_info_lib", + "//source/common/tls:context_lib", + "@com_github_google_quiche//:quic_platform", + ]), ) envoy_cc_library( name = "envoy_quic_stream_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_stream.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_stream.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_simulated_watermark_buffer_lib", - ":envoy_quic_utils_lib", - ":quic_filter_manager_connection_lib", - ":quic_stats_gatherer", - ":send_buffer_monitor_lib", - "//envoy/event:dispatcher_interface", - "//envoy/http:codec_interface", - "//source/common/http:codec_helper_lib", - "@com_github_google_quiche//:http2_adapter", - "@com_github_google_quiche//:quic_core_http_client_lib", - "@com_github_google_quiche//:quic_core_http_http_encoder_lib", - "@envoy_api//envoy/config/core/v3:pkg_cc_proto", - ], - }) + envoy_select_enable_http_datagrams([ + srcs = envoy_select_enable_http3(["envoy_quic_stream.cc"]), + hdrs = envoy_select_enable_http3(["envoy_quic_stream.h"]), + deps = envoy_select_enable_http3([ + ":envoy_quic_simulated_watermark_buffer_lib", + ":envoy_quic_utils_lib", + ":quic_filter_manager_connection_lib", + ":quic_stats_gatherer", + ":send_buffer_monitor_lib", + "//envoy/event:dispatcher_interface", + "//envoy/http:codec_interface", + "//source/common/http:codec_helper_lib", + "@com_github_google_quiche//:http2_adapter", + "@com_github_google_quiche//:quic_core_http_client_lib", + "@com_github_google_quiche//:quic_core_http_http_encoder_lib", + "@envoy_api//envoy/config/core/v3:pkg_cc_proto", + ]) + envoy_select_enable_http_datagrams([ ":http_datagram_handler", ]), ) envoy_cc_library( name = "client_connection_factory_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["client_connection_factory_impl.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["client_connection_factory_impl.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_alarm_factory_lib", - ":envoy_quic_client_session_lib", - ":envoy_quic_connection_helper_lib", - ":envoy_quic_proof_verifier_lib", - ":envoy_quic_utils_lib", - "//envoy/http:codec_interface", - "//envoy/http:persistent_quic_info_interface", - "//envoy/registry", - "//source/common/runtime:runtime_lib", - "//source/common/tls:client_ssl_socket_lib", - "//source/extensions/quic/crypto_stream:envoy_quic_crypto_client_stream_lib", - "@com_github_google_quiche//:quic_core_http_spdy_session_lib", - ], - }), + srcs = envoy_select_enable_http3(["client_connection_factory_impl.cc"]), + hdrs = envoy_select_enable_http3(["client_connection_factory_impl.h"]), + deps = envoy_select_enable_http3([ + ":envoy_quic_alarm_factory_lib", + ":envoy_quic_client_session_lib", + ":envoy_quic_connection_helper_lib", + ":envoy_quic_proof_verifier_lib", + ":envoy_quic_utils_lib", + "//envoy/http:codec_interface", + "//envoy/http:persistent_quic_info_interface", + "//envoy/registry", + "//source/common/runtime:runtime_lib", + "//source/common/tls:client_ssl_socket_lib", + "//source/extensions/quic/crypto_stream:envoy_quic_crypto_client_stream_lib", + "@com_github_google_quiche//:quic_core_http_spdy_session_lib", + ]), ) envoy_cc_library( name = "client_codec_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["client_codec_impl.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "client_codec_impl.h", - "codec_impl.h", - ], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_client_session_lib", - ":envoy_quic_utils_lib", - "//envoy/http:codec_interface", - "//envoy/registry", - "@com_github_google_quiche//:quic_core_http_spdy_session_lib", - ], - }), + srcs = envoy_select_enable_http3(["client_codec_impl.cc"]), + hdrs = envoy_select_enable_http3([ + "client_codec_impl.h", + "codec_impl.h", + ]), + deps = envoy_select_enable_http3([ + ":envoy_quic_client_session_lib", + ":envoy_quic_utils_lib", + "//envoy/http:codec_interface", + "//envoy/registry", + "@com_github_google_quiche//:quic_core_http_spdy_session_lib", + ]), ) envoy_cc_library( name = "server_codec_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["server_codec_impl.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "codec_impl.h", - "server_codec_impl.h", - ], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_server_session_lib", - ":envoy_quic_utils_lib", - ":quic_server_factory_stub_lib", - "//envoy/http:codec_interface", - "//envoy/registry", - "@com_github_google_quiche//:quic_core_http_spdy_session_lib", - ], - }), + srcs = envoy_select_enable_http3(["server_codec_impl.cc"]), + hdrs = envoy_select_enable_http3([ + "codec_impl.h", + "server_codec_impl.h", + ]), + deps = envoy_select_enable_http3([ + ":envoy_quic_server_session_lib", + ":envoy_quic_utils_lib", + ":quic_server_factory_stub_lib", + "//envoy/http:codec_interface", + "//envoy/registry", + "@com_github_google_quiche//:quic_core_http_spdy_session_lib", + ]), alwayslink = LEGACY_ALWAYSLINK, ) envoy_cc_library( name = "quic_ssl_connection_info_lib", - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["quic_ssl_connection_info.h"], - }), + hdrs = envoy_select_enable_http3(["quic_ssl_connection_info.h"]), external_deps = ["ssl"], - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/common/tls:connection_info_impl_base_lib", - "@com_github_google_quiche//:quic_core_session_lib", - ], - }), + deps = envoy_select_enable_http3([ + "//source/common/tls:connection_info_impl_base_lib", + "@com_github_google_quiche//:quic_core_session_lib", + ]), ) envoy_cc_library( name = "quic_filter_manager_connection_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["quic_filter_manager_connection_impl.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["quic_filter_manager_connection_impl.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_simulated_watermark_buffer_lib", - ":quic_network_connection_lib", - ":quic_ssl_connection_info_lib", - ":quic_stat_names_lib", - ":send_buffer_monitor_lib", - "//envoy/event:dispatcher_interface", - "//envoy/network:connection_interface", - "//source/common/buffer:buffer_lib", - "//source/common/common:assert_lib", - "//source/common/common:empty_string", - "//source/common/http:header_map_lib", - "//source/common/http/http3:codec_stats_lib", - "//source/common/network:connection_base_lib", - "//source/common/stream_info:stream_info_lib", - "@com_github_google_quiche//:quic_core_connection_lib", - ], - }), + srcs = envoy_select_enable_http3(["quic_filter_manager_connection_impl.cc"]), + hdrs = envoy_select_enable_http3(["quic_filter_manager_connection_impl.h"]), + deps = envoy_select_enable_http3([ + ":envoy_quic_simulated_watermark_buffer_lib", + ":quic_network_connection_lib", + ":quic_ssl_connection_info_lib", + ":quic_stat_names_lib", + ":send_buffer_monitor_lib", + "//envoy/event:dispatcher_interface", + "//envoy/network:connection_interface", + "//source/common/buffer:buffer_lib", + "//source/common/common:assert_lib", + "//source/common/common:empty_string", + "//source/common/http:header_map_lib", + "//source/common/http/http3:codec_stats_lib", + "//source/common/network:connection_base_lib", + "//source/common/stream_info:stream_info_lib", + "@com_github_google_quiche//:quic_core_connection_lib", + ]), ) envoy_cc_library( name = "envoy_quic_server_session_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "envoy_quic_server_session.cc", - "envoy_quic_server_stream.cc", - ], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "envoy_quic_server_session.h", - "envoy_quic_server_stream.h", - ], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_connection_debug_visitor_factory_interface", - ":envoy_quic_proof_source_lib", - ":envoy_quic_server_connection_lib", - ":envoy_quic_server_crypto_stream_factory_lib", - ":envoy_quic_stream_lib", - ":envoy_quic_utils_lib", - ":quic_filter_manager_connection_lib", - ":quic_stat_names_lib", - ":quic_stats_gatherer", - "//source/common/buffer:buffer_lib", - "//source/common/common:assert_lib", - "//source/common/http:header_map_lib", - "@com_github_google_quiche//:quic_server_http_spdy_session_lib", - "@com_google_absl//absl/types:optional", - ], - }) + envoy_select_enable_http_datagrams([ + srcs = envoy_select_enable_http3([ + "envoy_quic_server_session.cc", + "envoy_quic_server_stream.cc", + ]), + hdrs = envoy_select_enable_http3([ + "envoy_quic_server_session.h", + "envoy_quic_server_stream.h", + ]), + deps = envoy_select_enable_http3([ + ":envoy_quic_connection_debug_visitor_factory_interface", + ":envoy_quic_proof_source_lib", + ":envoy_quic_server_connection_lib", + ":envoy_quic_server_crypto_stream_factory_lib", + ":envoy_quic_stream_lib", + ":envoy_quic_utils_lib", + ":quic_filter_manager_connection_lib", + ":quic_stat_names_lib", + ":quic_stats_gatherer", + "//source/common/buffer:buffer_lib", + "//source/common/common:assert_lib", + "//source/common/http:header_map_lib", + "@com_github_google_quiche//:quic_server_http_spdy_session_lib", + "@com_google_absl//absl/types:optional", + ]) + envoy_select_enable_http_datagrams([ ":http_datagram_handler", ]), ) envoy_cc_library( name = "envoy_quic_client_session_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "envoy_quic_client_session.cc", - "envoy_quic_client_stream.cc", - "quic_network_connectivity_observer.cc", - ], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "envoy_quic_client_session.h", - "envoy_quic_client_stream.h", - "envoy_quic_network_observer_registry_factory.h", - "quic_network_connectivity_observer.h", - ], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_client_connection_lib", - ":envoy_quic_client_crypto_stream_factory_lib", - ":envoy_quic_proof_verifier_lib", - ":envoy_quic_stream_lib", - ":envoy_quic_utils_lib", - ":quic_filter_manager_connection_lib", - ":quic_stat_names_lib", - ":quic_transport_socket_factory_lib", - "//envoy/http:http_server_properties_cache_interface", - "//source/common/buffer:buffer_lib", - "//source/common/common:assert_lib", - "//source/common/http:codes_lib", - "//source/common/http:header_map_lib", - "//source/common/http:header_utility_lib", - "@com_github_google_quiche//:quic_core_http_client_lib", - ], - }) + envoy_select_enable_http_datagrams([ + srcs = envoy_select_enable_http3([ + "envoy_quic_client_session.cc", + "envoy_quic_client_stream.cc", + "quic_network_connectivity_observer.cc", + ]), + hdrs = envoy_select_enable_http3([ + "envoy_quic_client_session.h", + "envoy_quic_client_stream.h", + "envoy_quic_network_observer_registry_factory.h", + "quic_network_connectivity_observer.h", + ]), + deps = envoy_select_enable_http3([ + ":envoy_quic_client_connection_lib", + ":envoy_quic_client_crypto_stream_factory_lib", + ":envoy_quic_proof_verifier_lib", + ":envoy_quic_stream_lib", + ":envoy_quic_utils_lib", + ":quic_filter_manager_connection_lib", + ":quic_stat_names_lib", + ":quic_transport_socket_factory_lib", + "//envoy/http:http_server_properties_cache_interface", + "//source/common/buffer:buffer_lib", + "//source/common/common:assert_lib", + "//source/common/http:codes_lib", + "//source/common/http:header_map_lib", + "//source/common/http:header_utility_lib", + "@com_github_google_quiche//:quic_core_http_client_lib", + ]) + envoy_select_enable_http_datagrams([ ":http_datagram_handler", ]), ) @@ -495,237 +351,174 @@ envoy_cc_library( envoy_cc_library( name = "quic_io_handle_wrapper_lib", - hdrs = ["quic_io_handle_wrapper.h"], - deps = [ + hdrs = envoy_select_enable_http3(["quic_io_handle_wrapper.h"]), + deps = envoy_select_enable_http3([ "//envoy/network:io_handle_interface", "//source/common/network:io_socket_error_lib", - ], + ]), ) envoy_cc_library( name = "quic_network_connection_lib", - srcs = ["quic_network_connection.cc"], - hdrs = ["quic_network_connection.h"], - deps = [ + srcs = envoy_select_enable_http3(["quic_network_connection.cc"]), + hdrs = envoy_select_enable_http3(["quic_network_connection.h"]), + deps = envoy_select_enable_http3([ "//envoy/network:connection_interface", - ], + ]), ) envoy_cc_library( name = "envoy_quic_server_connection_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_server_connection.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_server_connection.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":quic_io_handle_wrapper_lib", - ":quic_network_connection_lib", - "//source/common/network:generic_listener_filter_impl_base_lib", - "//source/common/network:listen_socket_lib", - "//source/common/quic:envoy_quic_utils_lib", - "@com_github_google_quiche//:quic_core_connection_lib", - "@com_github_google_quiche//:quic_core_packet_writer_lib", - "@com_github_google_quiche//:quic_core_packets_lib", - ], - }), + srcs = envoy_select_enable_http3(["envoy_quic_server_connection.cc"]), + hdrs = envoy_select_enable_http3(["envoy_quic_server_connection.h"]), + deps = envoy_select_enable_http3([ + ":quic_io_handle_wrapper_lib", + ":quic_network_connection_lib", + "//source/common/network:generic_listener_filter_impl_base_lib", + "//source/common/network:listen_socket_lib", + "//source/common/quic:envoy_quic_utils_lib", + "@com_github_google_quiche//:quic_core_connection_lib", + "@com_github_google_quiche//:quic_core_packet_writer_lib", + "@com_github_google_quiche//:quic_core_packets_lib", + ]), ) envoy_cc_library( name = "envoy_quic_client_connection_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_client_connection.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_client_connection.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_packet_writer_lib", - ":quic_network_connection_lib", - "//envoy/event:dispatcher_interface", - "//source/common/network:socket_option_factory_lib", - "//source/common/network:udp_packet_writer_handler_lib", - "//source/common/runtime:runtime_lib", - "@com_github_google_quiche//:quic_core_connection_lib", - "@envoy_api//envoy/config/core/v3:pkg_cc_proto", - ], - }), + srcs = envoy_select_enable_http3(["envoy_quic_client_connection.cc"]), + hdrs = envoy_select_enable_http3(["envoy_quic_client_connection.h"]), + deps = envoy_select_enable_http3([ + ":envoy_quic_packet_writer_lib", + ":quic_network_connection_lib", + "//envoy/event:dispatcher_interface", + "//source/common/network:socket_option_factory_lib", + "//source/common/network:udp_packet_writer_handler_lib", + "//source/common/runtime:runtime_lib", + "@com_github_google_quiche//:quic_core_connection_lib", + "@envoy_api//envoy/config/core/v3:pkg_cc_proto", + ]), ) envoy_cc_library( name = "envoy_quic_dispatcher_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_dispatcher.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_dispatcher.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_connection_debug_visitor_factory_interface", - ":envoy_quic_proof_source_lib", - ":envoy_quic_server_connection_lib", - ":envoy_quic_server_crypto_stream_factory_lib", - ":envoy_quic_server_session_lib", - ":quic_stat_names_lib", - "//envoy/network:listener_interface", - "@com_github_google_quiche//:quic_core_server_lib", - "@com_github_google_quiche//:quic_core_utils_lib", - ], - }), + srcs = envoy_select_enable_http3(["envoy_quic_dispatcher.cc"]), + hdrs = envoy_select_enable_http3(["envoy_quic_dispatcher.h"]), + deps = envoy_select_enable_http3([ + ":envoy_quic_connection_debug_visitor_factory_interface", + ":envoy_quic_proof_source_lib", + ":envoy_quic_server_connection_lib", + ":envoy_quic_server_crypto_stream_factory_lib", + ":envoy_quic_server_session_lib", + ":quic_stat_names_lib", + "//envoy/network:listener_interface", + "@com_github_google_quiche//:quic_core_server_lib", + "@com_github_google_quiche//:quic_core_utils_lib", + ]), ) envoy_cc_library( name = "envoy_quic_simulated_watermark_buffer_lib", - hdrs = ["envoy_quic_simulated_watermark_buffer.h"], - deps = ["//source/common/common:assert_lib"], + hdrs = envoy_select_enable_http3(["envoy_quic_simulated_watermark_buffer.h"]), + deps = envoy_select_enable_http3(["//source/common/common:assert_lib"]), ) envoy_cc_library( name = "active_quic_listener_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["active_quic_listener.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["active_quic_listener.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_alarm_factory_lib", - ":envoy_quic_connection_debug_visitor_factory_interface", - ":envoy_quic_connection_helper_lib", - ":envoy_quic_dispatcher_lib", - ":envoy_quic_packet_writer_lib", - ":envoy_quic_proof_source_factory_interface", - ":envoy_quic_proof_source_lib", - ":envoy_quic_server_preferred_address_config_factory_interface", - ":envoy_quic_utils_lib", - "//envoy/network:listener_interface", - "//source/common/network:listener_lib", - "//source/common/protobuf:utility_lib", - "//source/common/runtime:runtime_lib", - "//source/extensions/quic/connection_id_generator/deterministic:envoy_deterministic_connection_id_generator_config", - "//source/server:active_udp_listener", - "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", - "@envoy_api//envoy/extensions/quic/connection_id_generator/v3:pkg_cc_proto", - "@envoy_api//envoy/extensions/quic/crypto_stream/v3:pkg_cc_proto", - "@envoy_api//envoy/extensions/quic/proof_source/v3:pkg_cc_proto", - ], - }), + srcs = envoy_select_enable_http3(["active_quic_listener.cc"]), + hdrs = envoy_select_enable_http3(["active_quic_listener.h"]), + deps = envoy_select_enable_http3([ + ":envoy_quic_alarm_factory_lib", + ":envoy_quic_connection_debug_visitor_factory_interface", + ":envoy_quic_connection_helper_lib", + ":envoy_quic_dispatcher_lib", + ":envoy_quic_packet_writer_lib", + ":envoy_quic_proof_source_factory_interface", + ":envoy_quic_proof_source_lib", + ":envoy_quic_server_preferred_address_config_factory_interface", + ":envoy_quic_utils_lib", + "//envoy/network:listener_interface", + "//source/common/network:listener_lib", + "//source/common/protobuf:utility_lib", + "//source/common/runtime:runtime_lib", + "//source/extensions/quic/connection_id_generator/deterministic:envoy_deterministic_connection_id_generator_config", + "//source/server:active_udp_listener", + "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/quic/connection_id_generator/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/quic/crypto_stream/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/quic/proof_source/v3:pkg_cc_proto", + ]), ) envoy_cc_library( name = "envoy_quic_utils_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_utils.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_utils.h"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_utils.cc"]), + hdrs = envoy_select_enable_http3(["envoy_quic_utils.h"]), external_deps = ["ssl"], - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//envoy/http:codec_interface", - "//source/common/http:header_map_lib", - "//source/common/http:header_utility_lib", - "//source/common/network:address_lib", - "//source/common/network:connection_socket_lib", - "//source/common/network:socket_option_factory_lib", - "//source/common/protobuf:utility_lib", - "//source/common/quic:quic_io_handle_wrapper_lib", - "@com_github_google_quiche//:quic_core_config_lib", - "@com_github_google_quiche//:quic_core_http_header_list_lib", - "@com_github_google_quiche//:quic_platform", - "@envoy_api//envoy/config/core/v3:pkg_cc_proto", - "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", - ], - }), + deps = envoy_select_enable_http3([ + "//envoy/http:codec_interface", + "//source/common/http:header_map_lib", + "//source/common/http:header_utility_lib", + "//source/common/network:address_lib", + "//source/common/network:connection_socket_lib", + "//source/common/network:socket_option_factory_lib", + "//source/common/protobuf:utility_lib", + "//source/common/quic:quic_io_handle_wrapper_lib", + "@com_github_google_quiche//:quic_core_config_lib", + "@com_github_google_quiche//:quic_core_http_header_list_lib", + "@com_github_google_quiche//:quic_platform", + "@envoy_api//envoy/config/core/v3:pkg_cc_proto", + "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", + ]), ) envoy_cc_library( name = "quic_transport_socket_factory_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "quic_client_transport_socket_factory.cc", - "quic_transport_socket_factory.cc", - ], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "quic_client_transport_socket_factory.h", - "quic_transport_socket_factory.h", - ], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_proof_verifier_lib", - "//envoy/network:transport_socket_interface", - "//envoy/server:transport_socket_config_interface", - "//envoy/ssl:context_config_interface", - "//source/common/common:assert_lib", - "//source/common/network:transport_socket_options_lib", - "//source/common/quic:cert_compression_lib", - "//source/common/tls:client_ssl_socket_lib", - "//source/common/tls:context_config_lib", - "@com_github_google_quiche//:quic_core_crypto_crypto_handshake_lib", - "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", - ], - }), + srcs = envoy_select_enable_http3([ + "quic_client_transport_socket_factory.cc", + "quic_transport_socket_factory.cc", + ]), + hdrs = envoy_select_enable_http3([ + "quic_client_transport_socket_factory.h", + "quic_transport_socket_factory.h", + ]), + deps = envoy_select_enable_http3([ + ":envoy_quic_proof_verifier_lib", + "//envoy/network:transport_socket_interface", + "//envoy/server:transport_socket_config_interface", + "//envoy/ssl:context_config_interface", + "//source/common/common:assert_lib", + "//source/common/network:transport_socket_options_lib", + "//source/common/quic:cert_compression_lib", + "//source/common/tls:client_ssl_socket_lib", + "//source/common/tls:context_config_lib", + "@com_github_google_quiche//:quic_core_crypto_crypto_handshake_lib", + "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", + ]), alwayslink = LEGACY_ALWAYSLINK, ) envoy_cc_library( name = "quic_server_transport_socket_factory_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "quic_server_transport_socket_factory.cc", - ], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "quic_server_transport_socket_factory.h", - ], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_proof_verifier_lib", - ":quic_transport_socket_factory_lib", - "//envoy/network:transport_socket_interface", - "//envoy/server:transport_socket_config_interface", - "//envoy/ssl:context_config_interface", - "//source/common/common:assert_lib", - "//source/common/network:transport_socket_options_lib", - "//source/common/tls:server_context_config_lib", - "//source/common/tls:server_context_lib", - "//source/common/tls:server_ssl_socket_lib", - "@com_github_google_quiche//:quic_core_crypto_crypto_handshake_lib", - "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", - ], - }), + srcs = envoy_select_enable_http3([ + "quic_server_transport_socket_factory.cc", + ]), + hdrs = envoy_select_enable_http3([ + "quic_server_transport_socket_factory.h", + ]), + deps = envoy_select_enable_http3([ + ":envoy_quic_proof_verifier_lib", + ":quic_transport_socket_factory_lib", + "//envoy/network:transport_socket_interface", + "//envoy/server:transport_socket_config_interface", + "//envoy/ssl:context_config_interface", + "//source/common/common:assert_lib", + "//source/common/network:transport_socket_options_lib", + "//source/common/tls:server_context_config_lib", + "//source/common/tls:server_context_lib", + "//source/common/tls:server_ssl_socket_lib", + "@com_github_google_quiche//:quic_core_crypto_crypto_handshake_lib", + "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", + ]), alwayslink = LEGACY_ALWAYSLINK, ) @@ -733,61 +526,46 @@ envoy_cc_library( # All of these are needed for this extension to function. envoy_cc_library( name = "quic_client_factory_lib", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":client_codec_lib", - ":quic_transport_socket_factory_lib", - "//source/extensions/quic/proof_source:envoy_quic_proof_source_factory_impl_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":client_codec_lib", + ":quic_transport_socket_factory_lib", + "//source/extensions/quic/proof_source:envoy_quic_proof_source_factory_impl_lib", + ]), ) # The factory for server connection creation. envoy_cc_library( name = "quic_server_factory_stub_lib", - hdrs = ["server_connection_factory.h"], - deps = [ + hdrs = envoy_select_enable_http3(["server_connection_factory.h"]), + deps = envoy_select_enable_http3([ "//envoy/http:codec_interface", "//envoy/network:connection_interface", "//source/common/http/http3:codec_stats_lib", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", - ], + ]), ) # Create a single target that contains all the libraries that register factories. # All of these are needed for this extension to function. envoy_cc_library( name = "quic_server_factory_lib", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":quic_transport_socket_factory_lib", - ":server_codec_lib", - "//source/extensions/quic/crypto_stream:envoy_quic_crypto_server_stream_lib", - "//source/extensions/quic/proof_source:envoy_quic_proof_source_factory_impl_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":quic_transport_socket_factory_lib", + ":server_codec_lib", + "//source/extensions/quic/crypto_stream:envoy_quic_crypto_server_stream_lib", + "//source/extensions/quic/proof_source:envoy_quic_proof_source_factory_impl_lib", + ]), ) envoy_cc_library( name = "envoy_quic_packet_writer_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_packet_writer.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_packet_writer.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_utils_lib", - "@com_github_google_quiche//:quic_core_packet_writer_lib", - "@com_github_google_quiche//:quic_platform", - ], - }), + srcs = envoy_select_enable_http3(["envoy_quic_packet_writer.cc"]), + hdrs = envoy_select_enable_http3(["envoy_quic_packet_writer.h"]), + deps = envoy_select_enable_http3([ + ":envoy_quic_utils_lib", + "@com_github_google_quiche//:quic_core_packet_writer_lib", + "@com_github_google_quiche//:quic_platform", + ]), ) envoy_cc_library( @@ -796,21 +574,15 @@ envoy_cc_library( ":http3_enabled_and_linux": ["udp_gso_batch_writer.cc"], "//conditions:default": [], }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["udp_gso_batch_writer.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_utils_lib", - "//envoy/network:udp_packet_writer_handler_interface", - "//source/common/network:io_socket_error_lib", - "//source/common/protobuf:utility_lib", - "//source/common/runtime:runtime_lib", - "@com_github_google_quiche//:quic_platform", - ], - }) + select({ + hdrs = envoy_select_enable_http3(["udp_gso_batch_writer.h"]), + deps = envoy_select_enable_http3([ + ":envoy_quic_utils_lib", + "//envoy/network:udp_packet_writer_handler_interface", + "//source/common/network:io_socket_error_lib", + "//source/common/protobuf:utility_lib", + "//source/common/runtime:runtime_lib", + "@com_github_google_quiche//:quic_platform", + ]) + select({ ":http3_enabled_and_linux": ["@com_github_google_quiche//:quic_core_batch_writer_gso_batch_writer_lib"], "//conditions:default": [], }), @@ -818,189 +590,114 @@ envoy_cc_library( envoy_cc_library( name = "send_buffer_monitor_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["send_buffer_monitor.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["send_buffer_monitor.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/common/common:assert_lib", - "@com_github_google_quiche//:quic_core_session_lib", - ], - }), + srcs = envoy_select_enable_http3(["send_buffer_monitor.cc"]), + hdrs = envoy_select_enable_http3(["send_buffer_monitor.h"]), + deps = envoy_select_enable_http3([ + "//source/common/common:assert_lib", + "@com_github_google_quiche//:quic_core_session_lib", + ]), ) envoy_cc_library( name = "envoy_quic_client_crypto_stream_factory_lib", - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_client_crypto_stream_factory.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//envoy/common:optref_lib", - "//envoy/config:typed_config_interface", - "//envoy/network:transport_socket_interface", - "@com_github_google_quiche//:quic_client_session_lib", - "@com_github_google_quiche//:quic_core_http_spdy_session_lib", - ], - }), + hdrs = envoy_select_enable_http3(["envoy_quic_client_crypto_stream_factory.h"]), + deps = envoy_select_enable_http3([ + "//envoy/common:optref_lib", + "//envoy/config:typed_config_interface", + "//envoy/network:transport_socket_interface", + "@com_github_google_quiche//:quic_client_session_lib", + "@com_github_google_quiche//:quic_core_http_spdy_session_lib", + ]), ) envoy_cc_library( name = "envoy_quic_server_crypto_stream_factory_lib", - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_server_crypto_stream_factory.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//envoy/config:typed_config_interface", - "@com_github_google_quiche//:quic_core_http_spdy_session_lib", - "@com_github_google_quiche//:quic_server_session_lib", - ], - }), + hdrs = envoy_select_enable_http3(["envoy_quic_server_crypto_stream_factory.h"]), + deps = envoy_select_enable_http3([ + "//envoy/config:typed_config_interface", + "@com_github_google_quiche//:quic_core_http_spdy_session_lib", + "@com_github_google_quiche//:quic_server_session_lib", + ]), ) envoy_cc_library( name = "envoy_quic_proof_source_factory_interface", - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_proof_source_factory_interface.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//envoy/config:typed_config_interface", - "@com_github_google_quiche//:quic_core_crypto_proof_source_lib", - ], - }), + hdrs = envoy_select_enable_http3(["envoy_quic_proof_source_factory_interface.h"]), + deps = envoy_select_enable_http3([ + "//envoy/config:typed_config_interface", + "@com_github_google_quiche//:quic_core_crypto_proof_source_lib", + ]), ) envoy_cc_library( name = "envoy_quic_connection_id_generator_factory_interface", - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_connection_id_generator_factory.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//envoy/config:typed_config_interface", - "@com_github_google_quiche//:quic_core_connection_id_generator_interface_lib", - "@com_github_google_quiche//:quic_load_balancer_encoder_lib", - ], - }), + hdrs = envoy_select_enable_http3(["envoy_quic_connection_id_generator_factory.h"]), + deps = envoy_select_enable_http3([ + "//envoy/config:typed_config_interface", + "@com_github_google_quiche//:quic_core_connection_id_generator_interface_lib", + "@com_github_google_quiche//:quic_load_balancer_encoder_lib", + ]), ) envoy_cc_library( name = "envoy_deterministic_connection_id_generator_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_deterministic_connection_id_generator.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_deterministic_connection_id_generator.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_connection_id_generator_factory_interface", - ":envoy_quic_utils_lib", - "@com_github_google_quiche//:quic_core_deterministic_connection_id_generator_lib", - ], - }), + srcs = envoy_select_enable_http3(["envoy_deterministic_connection_id_generator.cc"]), + hdrs = envoy_select_enable_http3(["envoy_deterministic_connection_id_generator.h"]), + deps = envoy_select_enable_http3([ + ":envoy_quic_connection_id_generator_factory_interface", + ":envoy_quic_utils_lib", + "@com_github_google_quiche//:quic_core_deterministic_connection_id_generator_lib", + ]), ) envoy_cc_library( name = "envoy_quic_server_preferred_address_config_factory_interface", - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_server_preferred_address_config_factory.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//envoy/config:typed_config_interface", - "//envoy/network:address_interface", - "//envoy/server:factory_context_interface", - "@com_github_google_quiche//:quic_platform_socket_address", - ], - }), + hdrs = envoy_select_enable_http3(["envoy_quic_server_preferred_address_config_factory.h"]), + deps = envoy_select_enable_http3([ + "//envoy/config:typed_config_interface", + "//envoy/network:address_interface", + "//envoy/server:factory_context_interface", + "@com_github_google_quiche//:quic_platform_socket_address", + ]), ) envoy_cc_library( name = "quic_stats_gatherer", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["quic_stats_gatherer.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["quic_stats_gatherer.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//envoy/access_log:access_log_interface", - "//envoy/formatter:http_formatter_context_interface", - "//envoy/http:codec_interface", - "//source/common/formatter:substitution_formatter_lib", - "//source/common/http:header_map_lib", - "@com_github_google_quiche//:quic_core_ack_listener_interface_lib", - ], - }), + srcs = envoy_select_enable_http3(["quic_stats_gatherer.cc"]), + hdrs = envoy_select_enable_http3(["quic_stats_gatherer.h"]), + deps = envoy_select_enable_http3([ + "//envoy/access_log:access_log_interface", + "//envoy/formatter:http_formatter_context_interface", + "//envoy/http:codec_interface", + "//source/common/formatter:substitution_formatter_lib", + "//source/common/http:header_map_lib", + "@com_github_google_quiche//:quic_core_ack_listener_interface_lib", + ]), ) envoy_cc_library( name = "http_datagram_handler", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["http_datagram_handler.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["http_datagram_handler.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//envoy/http:codec_interface", - "//source/common/buffer:buffer_lib", - "//source/common/common:logger_lib", - "//source/common/http:header_map_lib", - "@com_github_google_quiche//:quic_core_http_spdy_session_lib", - "@com_github_google_quiche//:quic_core_types_lib", - ], - }), + srcs = envoy_select_enable_http3(["http_datagram_handler.cc"]), + hdrs = envoy_select_enable_http3(["http_datagram_handler.h"]), + deps = envoy_select_enable_http3([ + "//envoy/http:codec_interface", + "//source/common/buffer:buffer_lib", + "//source/common/common:logger_lib", + "//source/common/http:header_map_lib", + "@com_github_google_quiche//:quic_core_http_spdy_session_lib", + "@com_github_google_quiche//:quic_core_types_lib", + ]), ) envoy_cc_library( name = "cert_compression_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["cert_compression.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["cert_compression.h"], - }), + srcs = envoy_select_enable_http3(["cert_compression.cc"]), + hdrs = envoy_select_enable_http3(["cert_compression.h"]), external_deps = ["ssl"], - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//bazel/foreign_cc:zlib", - "//source/common/common:assert_lib", - "//source/common/common:logger_lib", - "//source/common/runtime:runtime_lib", - ], - }), + deps = envoy_select_enable_http3([ + "//bazel/foreign_cc:zlib", + "//source/common/common:assert_lib", + "//source/common/common:logger_lib", + "//source/common/runtime:runtime_lib", + ]), ) diff --git a/source/extensions/filters/network/http_connection_manager/config.cc b/source/extensions/filters/network/http_connection_manager/config.cc index 6f90b0a19b..8d1942464b 100644 --- a/source/extensions/filters/network/http_connection_manager/config.cc +++ b/source/extensions/filters/network/http_connection_manager/config.cc @@ -32,7 +32,10 @@ #include "source/common/http/utility.h" #include "source/common/local_reply/local_reply.h" #include "source/common/protobuf/utility.h" + +#ifdef ENVOY_ENABLE_QUIC #include "source/common/quic/server_connection_factory.h" +#endif #include "source/common/router/route_provider_manager.h" #include "source/common/runtime/runtime_impl.h" #include "source/common/tracing/custom_tag_impl.h" @@ -772,6 +775,7 @@ Http::ServerConnectionPtr HttpConnectionManagerConfig::createCodec( maxRequestHeadersKb(), maxRequestHeadersCount(), headersWithUnderscoresAction(), overload_manager); case CodecType::HTTP3: +#ifdef ENVOY_ENABLE_QUIC return Config::Utility::getAndCheckFactoryByName( "quic.http_server_connection.default") .createQuicHttpServerConnectionImpl( @@ -779,6 +783,11 @@ Http::ServerConnectionPtr HttpConnectionManagerConfig::createCodec( Http::Http3::CodecStats::atomicGet(http3_codec_stats_, context_.scope()), http3_options_, maxRequestHeadersKb(), maxRequestHeadersCount(), headersWithUnderscoresAction()); +#else + // Should be blocked by configuration checking at an earlier point. + PANIC("unexpected"); +#endif + break; case CodecType::AUTO: return Http::ConnectionManagerUtility::autoCreateCodec( connection, data, callbacks, context_.scope(), diff --git a/source/extensions/quic/connection_debug_visitor/basic/BUILD b/source/extensions/quic/connection_debug_visitor/basic/BUILD index f95ed8d6a2..0ed81c7a68 100644 --- a/source/extensions/quic/connection_debug_visitor/basic/BUILD +++ b/source/extensions/quic/connection_debug_visitor/basic/BUILD @@ -7,6 +7,7 @@ load( "envoy_cc_extension", "envoy_cc_library", "envoy_extension_package", + "envoy_select_enable_http3", ) licenses(["notice"]) # Apache 2 @@ -17,32 +18,23 @@ envoy_extension_package() envoy_cc_library( name = "envoy_quic_connection_debug_visitor_basic_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_connection_debug_visitor_basic.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_connection_debug_visitor_basic.h"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_connection_debug_visitor_basic.cc"]), + hdrs = envoy_select_enable_http3(["envoy_quic_connection_debug_visitor_basic.h"]), visibility = [ "//source/common/quic:__subpackages__", ], - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//envoy/registry", - "//envoy/stream_info:stream_info_interface", - "//source/common/common:minimal_logger_lib", - "//source/common/protobuf:utility_lib", - "//source/common/quic:envoy_quic_connection_debug_visitor_factory_interface", - "@com_github_google_quiche//:quic_core_connection_lib", - "@com_github_google_quiche//:quic_core_frames_frames_lib", - "@com_github_google_quiche//:quic_core_session_lib", - "@com_github_google_quiche//:quic_core_types_lib", - "@envoy_api//envoy/extensions/quic/connection_debug_visitor/v3:pkg_cc_proto", - ], - }), + deps = envoy_select_enable_http3([ + "//envoy/registry", + "//envoy/stream_info:stream_info_interface", + "//source/common/common:minimal_logger_lib", + "//source/common/protobuf:utility_lib", + "//source/common/quic:envoy_quic_connection_debug_visitor_factory_interface", + "@com_github_google_quiche//:quic_core_connection_lib", + "@com_github_google_quiche//:quic_core_frames_frames_lib", + "@com_github_google_quiche//:quic_core_session_lib", + "@com_github_google_quiche//:quic_core_types_lib", + "@envoy_api//envoy/extensions/quic/connection_debug_visitor/v3:pkg_cc_proto", + ]), alwayslink = LEGACY_ALWAYSLINK, ) @@ -52,10 +44,7 @@ envoy_cc_extension( "//source/common/quic:__subpackages__", "//test:__subpackages__", ], - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_connection_debug_visitor_basic_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":envoy_quic_connection_debug_visitor_basic_lib", + ]), ) diff --git a/source/extensions/quic/connection_debug_visitor/quic_stats/BUILD b/source/extensions/quic/connection_debug_visitor/quic_stats/BUILD index 1586f522b8..0cc5124831 100644 --- a/source/extensions/quic/connection_debug_visitor/quic_stats/BUILD +++ b/source/extensions/quic/connection_debug_visitor/quic_stats/BUILD @@ -7,6 +7,7 @@ load( "envoy_cc_extension", "envoy_cc_library", "envoy_extension_package", + "envoy_select_enable_http3", ) licenses(["notice"]) # Apache 2 @@ -15,26 +16,17 @@ envoy_extension_package() envoy_cc_library( name = "quic_stats_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["quic_stats.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["quic_stats.h"], - }), + srcs = envoy_select_enable_http3(["quic_stats.cc"]), + hdrs = envoy_select_enable_http3(["quic_stats.h"]), visibility = [ "//test:__subpackages__", ], - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//envoy/registry", - "//source/common/protobuf:utility_lib", - "//source/common/quic:envoy_quic_connection_debug_visitor_factory_interface", - "@envoy_api//envoy/extensions/quic/connection_debug_visitor/quic_stats/v3:pkg_cc_proto", - ], - }), + deps = envoy_select_enable_http3([ + "//envoy/registry", + "//source/common/protobuf:utility_lib", + "//source/common/quic:envoy_quic_connection_debug_visitor_factory_interface", + "@envoy_api//envoy/extensions/quic/connection_debug_visitor/quic_stats/v3:pkg_cc_proto", + ]), alwayslink = LEGACY_ALWAYSLINK, ) @@ -44,10 +36,7 @@ envoy_cc_extension( "//source/common/quic:__subpackages__", "//test:__subpackages__", ], - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":quic_stats_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":quic_stats_lib", + ]), ) diff --git a/source/extensions/quic/connection_id_generator/deterministic/BUILD b/source/extensions/quic/connection_id_generator/deterministic/BUILD index dd191bd936..125d6ffc7b 100644 --- a/source/extensions/quic/connection_id_generator/deterministic/BUILD +++ b/source/extensions/quic/connection_id_generator/deterministic/BUILD @@ -7,6 +7,7 @@ load( "envoy_cc_extension", "envoy_cc_library", "envoy_extension_package", + "envoy_select_enable_http3", ) licenses(["notice"]) # Apache 2 @@ -17,23 +18,14 @@ envoy_extension_package() envoy_cc_library( name = "envoy_deterministic_connection_id_generator_config_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_deterministic_connection_id_generator_config.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_deterministic_connection_id_generator_config.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//envoy/registry", - "//source/common/quic:envoy_deterministic_connection_id_generator_lib", - "//source/common/quic:envoy_quic_connection_id_generator_factory_interface", - "@envoy_api//envoy/extensions/quic/connection_id_generator/v3:pkg_cc_proto", - ], - }), + srcs = envoy_select_enable_http3(["envoy_deterministic_connection_id_generator_config.cc"]), + hdrs = envoy_select_enable_http3(["envoy_deterministic_connection_id_generator_config.h"]), + deps = envoy_select_enable_http3([ + "//envoy/registry", + "//source/common/quic:envoy_deterministic_connection_id_generator_lib", + "//source/common/quic:envoy_quic_connection_id_generator_factory_interface", + "@envoy_api//envoy/extensions/quic/connection_id_generator/v3:pkg_cc_proto", + ]), alwayslink = LEGACY_ALWAYSLINK, ) @@ -42,10 +34,7 @@ envoy_cc_extension( extra_visibility = [ "//source/common/quic:__subpackages__", ], - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_deterministic_connection_id_generator_config_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":envoy_deterministic_connection_id_generator_config_lib", + ]), ) diff --git a/source/extensions/quic/connection_id_generator/quic_lb/BUILD b/source/extensions/quic/connection_id_generator/quic_lb/BUILD index 2c41663756..b5ee28656d 100644 --- a/source/extensions/quic/connection_id_generator/quic_lb/BUILD +++ b/source/extensions/quic/connection_id_generator/quic_lb/BUILD @@ -7,6 +7,7 @@ load( "envoy_cc_extension", "envoy_cc_library", "envoy_extension_package", + "envoy_select_enable_http3", ) licenses(["notice"]) # Apache 2 @@ -15,56 +16,35 @@ envoy_extension_package() envoy_cc_library( name = "quic_lb_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["quic_lb.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["quic_lb.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/common/config:datasource_lib", - "//source/common/quic:envoy_quic_connection_id_generator_factory_interface", - "//source/common/quic:envoy_quic_utils_lib", - "@com_github_google_quiche//:quic_load_balancer_config_lib", - "@com_github_google_quiche//:quic_load_balancer_encoder_lib", - "@com_github_google_quiche//:quic_load_balancer_server_id_lib", - "@envoy_api//envoy/extensions/quic/connection_id_generator/quic_lb/v3:pkg_cc_proto", - ], - }), + srcs = envoy_select_enable_http3(["quic_lb.cc"]), + hdrs = envoy_select_enable_http3(["quic_lb.h"]), + deps = envoy_select_enable_http3([ + "//source/common/config:datasource_lib", + "//source/common/quic:envoy_quic_connection_id_generator_factory_interface", + "//source/common/quic:envoy_quic_utils_lib", + "@com_github_google_quiche//:quic_load_balancer_config_lib", + "@com_github_google_quiche//:quic_load_balancer_encoder_lib", + "@com_github_google_quiche//:quic_load_balancer_server_id_lib", + "@envoy_api//envoy/extensions/quic/connection_id_generator/quic_lb/v3:pkg_cc_proto", + ]), ) envoy_cc_library( name = "config_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["config.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["config.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":quic_lb_lib", - "//envoy/registry", - "//source/common/quic:envoy_quic_connection_id_generator_factory_interface", - "@envoy_api//envoy/extensions/quic/connection_id_generator/quic_lb/v3:pkg_cc_proto", - ], - }), + srcs = envoy_select_enable_http3(["config.cc"]), + hdrs = envoy_select_enable_http3(["config.h"]), + deps = envoy_select_enable_http3([ + ":quic_lb_lib", + "//envoy/registry", + "//source/common/quic:envoy_quic_connection_id_generator_factory_interface", + "@envoy_api//envoy/extensions/quic/connection_id_generator/quic_lb/v3:pkg_cc_proto", + ]), alwayslink = LEGACY_ALWAYSLINK, ) envoy_cc_extension( name = "quic_lb_config", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":config_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":config_lib", + ]), ) diff --git a/source/extensions/quic/crypto_stream/BUILD b/source/extensions/quic/crypto_stream/BUILD index c6786be588..6e2e7acb21 100644 --- a/source/extensions/quic/crypto_stream/BUILD +++ b/source/extensions/quic/crypto_stream/BUILD @@ -7,6 +7,7 @@ load( "envoy_cc_extension", "envoy_cc_library", "envoy_extension_package", + "envoy_select_enable_http3", ) licenses(["notice"]) # Apache 2 @@ -17,26 +18,17 @@ envoy_extension_package() envoy_cc_library( name = "envoy_quic_crypto_server_stream_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_crypto_server_stream.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_crypto_server_stream.h"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_crypto_server_stream.cc"]), + hdrs = envoy_select_enable_http3(["envoy_quic_crypto_server_stream.h"]), visibility = [ "//source/common/quic:__subpackages__", "//test:__subpackages__", ], - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//envoy/registry", - "//source/common/quic:envoy_quic_server_crypto_stream_factory_lib", - "@envoy_api//envoy/extensions/quic/crypto_stream/v3:pkg_cc_proto", - ], - }), + deps = envoy_select_enable_http3([ + "//envoy/registry", + "//source/common/quic:envoy_quic_server_crypto_stream_factory_lib", + "@envoy_api//envoy/extensions/quic/crypto_stream/v3:pkg_cc_proto", + ]), alwayslink = LEGACY_ALWAYSLINK, ) @@ -46,33 +38,21 @@ envoy_cc_extension( "//source/common/quic:__subpackages__", "//test:__subpackages__", ], - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_crypto_server_stream_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":envoy_quic_crypto_server_stream_lib", + ]), ) envoy_cc_library( name = "envoy_quic_crypto_client_stream_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_crypto_client_stream.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_crypto_client_stream.h"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_crypto_client_stream.cc"]), + hdrs = envoy_select_enable_http3(["envoy_quic_crypto_client_stream.h"]), visibility = [ "//source/common/quic:__subpackages__", "//test:__subpackages__", ], - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/common/quic:envoy_quic_client_crypto_stream_factory_lib", - ], - }), + deps = envoy_select_enable_http3([ + "//source/common/quic:envoy_quic_client_crypto_stream_factory_lib", + ]), alwayslink = LEGACY_ALWAYSLINK, ) diff --git a/source/extensions/quic/proof_source/BUILD b/source/extensions/quic/proof_source/BUILD index 27ce732bd6..42d05a27d2 100644 --- a/source/extensions/quic/proof_source/BUILD +++ b/source/extensions/quic/proof_source/BUILD @@ -7,6 +7,7 @@ load( "envoy_cc_extension", "envoy_cc_library", "envoy_extension_package", + "envoy_select_enable_http3", ) licenses(["notice"]) # Apache 2 @@ -17,26 +18,17 @@ envoy_extension_package() envoy_cc_library( name = "envoy_quic_proof_source_factory_impl_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_proof_source_factory_impl.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_proof_source_factory_impl.h"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_proof_source_factory_impl.cc"]), + hdrs = envoy_select_enable_http3(["envoy_quic_proof_source_factory_impl.h"]), visibility = [ "//source/common/quic:__subpackages__", "//test:__subpackages__", ], - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/common/quic:envoy_quic_proof_source_factory_interface", - "//source/common/quic:envoy_quic_proof_source_lib", - "@envoy_api//envoy/extensions/quic/proof_source/v3:pkg_cc_proto", - ], - }), + deps = envoy_select_enable_http3([ + "//source/common/quic:envoy_quic_proof_source_factory_interface", + "//source/common/quic:envoy_quic_proof_source_lib", + "@envoy_api//envoy/extensions/quic/proof_source/v3:pkg_cc_proto", + ]), alwayslink = LEGACY_ALWAYSLINK, ) @@ -46,10 +38,7 @@ envoy_cc_extension( "//source/common/quic:__subpackages__", "//test:__subpackages__", ], - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":envoy_quic_proof_source_factory_impl_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":envoy_quic_proof_source_factory_impl_lib", + ]), ) diff --git a/source/extensions/quic/server_preferred_address/BUILD b/source/extensions/quic/server_preferred_address/BUILD index 40deed67fc..b4a2ffacf0 100644 --- a/source/extensions/quic/server_preferred_address/BUILD +++ b/source/extensions/quic/server_preferred_address/BUILD @@ -7,6 +7,7 @@ load( "envoy_cc_extension", "envoy_cc_library", "envoy_extension_package", + "envoy_select_enable_http3", ) licenses(["notice"]) # Apache 2 @@ -17,42 +18,24 @@ envoy_extension_package() envoy_cc_library( name = "server_preferred_address_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["server_preferred_address.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["server_preferred_address.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/common/quic:envoy_quic_server_preferred_address_config_factory_interface", - ], - }), + srcs = envoy_select_enable_http3(["server_preferred_address.cc"]), + hdrs = envoy_select_enable_http3(["server_preferred_address.h"]), + deps = envoy_select_enable_http3([ + "//source/common/quic:envoy_quic_server_preferred_address_config_factory_interface", + ]), ) envoy_cc_library( name = "fixed_server_preferred_address_config_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["fixed_server_preferred_address_config.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["fixed_server_preferred_address_config.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":server_preferred_address_lib", - "//envoy/registry", - "//source/common/quic:envoy_quic_server_preferred_address_config_factory_interface", - "//source/common/quic:envoy_quic_utils_lib", - "@envoy_api//envoy/extensions/quic/server_preferred_address/v3:pkg_cc_proto", - ], - }), + srcs = envoy_select_enable_http3(["fixed_server_preferred_address_config.cc"]), + hdrs = envoy_select_enable_http3(["fixed_server_preferred_address_config.h"]), + deps = envoy_select_enable_http3([ + ":server_preferred_address_lib", + "//envoy/registry", + "//source/common/quic:envoy_quic_server_preferred_address_config_factory_interface", + "//source/common/quic:envoy_quic_utils_lib", + "@envoy_api//envoy/extensions/quic/server_preferred_address/v3:pkg_cc_proto", + ]), alwayslink = LEGACY_ALWAYSLINK, ) @@ -61,44 +44,29 @@ envoy_cc_extension( extra_visibility = [ "//test:__subpackages__", ], - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":fixed_server_preferred_address_config_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":fixed_server_preferred_address_config_lib", + ]), ) envoy_cc_library( name = "datasource_server_preferred_address_config_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["datasource_server_preferred_address_config.cc"], - }), - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["datasource_server_preferred_address_config.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":server_preferred_address_lib", - "//envoy/registry", - "//source/common/config:datasource_lib", - "//source/common/quic:envoy_quic_server_preferred_address_config_factory_interface", - "//source/common/quic:envoy_quic_utils_lib", - "@envoy_api//envoy/extensions/quic/server_preferred_address/v3:pkg_cc_proto", - ], - }), + srcs = envoy_select_enable_http3(["datasource_server_preferred_address_config.cc"]), + hdrs = envoy_select_enable_http3(["datasource_server_preferred_address_config.h"]), + deps = envoy_select_enable_http3([ + ":server_preferred_address_lib", + "//envoy/registry", + "//source/common/config:datasource_lib", + "//source/common/quic:envoy_quic_server_preferred_address_config_factory_interface", + "//source/common/quic:envoy_quic_utils_lib", + "@envoy_api//envoy/extensions/quic/server_preferred_address/v3:pkg_cc_proto", + ]), alwayslink = LEGACY_ALWAYSLINK, ) envoy_cc_extension( name = "datasource_server_preferred_address_config_factory_config", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":datasource_server_preferred_address_config_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":datasource_server_preferred_address_config_lib", + ]), ) diff --git a/test/common/listener_manager/BUILD b/test/common/listener_manager/BUILD index d5fd7e2b2f..b2fa018e2f 100644 --- a/test/common/listener_manager/BUILD +++ b/test/common/listener_manager/BUILD @@ -6,6 +6,7 @@ load( "envoy_cc_test_library", "envoy_package", "envoy_proto_library", + "envoy_select_enable_http3", ) licenses(["notice"]) # Apache 2 @@ -109,31 +110,25 @@ envoy_cc_test( # Stand-alone quic test because of FIPS. envoy_cc_test( name = "listener_manager_impl_quic_only_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["listener_manager_impl_quic_only_test.cc"], - }), + srcs = envoy_select_enable_http3(["listener_manager_impl_quic_only_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":listener_manager_impl_test_lib", - "//source/common/formatter:formatter_extension_lib", - "//source/extensions/filters/http/router:config", - "//source/extensions/filters/network/http_connection_manager:config", - "//source/extensions/matching/network/common:inputs_lib", - "//source/extensions/quic/server_preferred_address:fixed_server_preferred_address_config_factory_config", - "//source/extensions/request_id/uuid:config", - "//source/extensions/transport_sockets/raw_buffer:config", - "//source/extensions/transport_sockets/tls:config", - "//test/integration/filters:test_listener_filter_lib", - "//test/integration/filters:test_network_filter_lib", - "//test/server:utility_lib", - "//test/test_common:threadsafe_singleton_injector_lib", - "@envoy_api//envoy/config/core/v3:pkg_cc_proto", - "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", - ], - }), + deps = envoy_select_enable_http3([ + ":listener_manager_impl_test_lib", + "//source/common/formatter:formatter_extension_lib", + "//source/extensions/filters/http/router:config", + "//source/extensions/filters/network/http_connection_manager:config", + "//source/extensions/matching/network/common:inputs_lib", + "//source/extensions/quic/server_preferred_address:fixed_server_preferred_address_config_factory_config", + "//source/extensions/request_id/uuid:config", + "//source/extensions/transport_sockets/raw_buffer:config", + "//source/extensions/transport_sockets/tls:config", + "//test/integration/filters:test_listener_filter_lib", + "//test/integration/filters:test_network_filter_lib", + "//test/server:utility_lib", + "//test/test_common:threadsafe_singleton_injector_lib", + "@envoy_api//envoy/config/core/v3:pkg_cc_proto", + "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", + ]), ) envoy_cc_test( diff --git a/test/common/network/BUILD b/test/common/network/BUILD index c889510a34..3da01af646 100644 --- a/test/common/network/BUILD +++ b/test/common/network/BUILD @@ -7,6 +7,7 @@ load( "envoy_cc_test_library", "envoy_package", "envoy_proto_library", + "envoy_select_enable_http3", ) licenses(["notice"]) # Apache 2 @@ -273,37 +274,31 @@ envoy_cc_test( envoy_cc_test( name = "udp_listener_impl_batch_writer_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["udp_listener_impl_batch_writer_test.cc"], - }), + srcs = envoy_select_enable_http3(["udp_listener_impl_batch_writer_test.cc"]), rbe_pool = "6gig", # Skipping as quiche quic_gso_batch_writer.h does not exist on Windows tags = [ "skip_on_windows", ], - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":udp_listener_impl_test_base_lib", - "//source/common/event:dispatcher_lib", - "//source/common/network:address_lib", - "//source/common/network:listener_lib", - "//source/common/network:socket_option_lib", - "//source/common/network:udp_packet_writer_handler_lib", - "//source/common/network:utility_lib", - "//source/common/quic:udp_gso_batch_writer_lib", - "//source/common/stats:stats_lib", - "//test/common/network:listener_impl_test_base_lib", - "//test/mocks/network:network_mocks", - "//test/test_common:environment_lib", - "//test/test_common:network_utility_lib", - "//test/test_common:threadsafe_singleton_injector_lib", - "//test/test_common:utility_lib", - "@com_github_google_quiche//:quic_test_tools_mock_syscall_wrapper_lib", - "@envoy_api//envoy/config/core/v3:pkg_cc_proto", - ], - }), + deps = envoy_select_enable_http3([ + ":udp_listener_impl_test_base_lib", + "//source/common/event:dispatcher_lib", + "//source/common/network:address_lib", + "//source/common/network:listener_lib", + "//source/common/network:socket_option_lib", + "//source/common/network:udp_packet_writer_handler_lib", + "//source/common/network:utility_lib", + "//source/common/quic:udp_gso_batch_writer_lib", + "//source/common/stats:stats_lib", + "//test/common/network:listener_impl_test_base_lib", + "//test/mocks/network:network_mocks", + "//test/test_common:environment_lib", + "//test/test_common:network_utility_lib", + "//test/test_common:threadsafe_singleton_injector_lib", + "//test/test_common:utility_lib", + "@com_github_google_quiche//:quic_test_tools_mock_syscall_wrapper_lib", + "@envoy_api//envoy/config/core/v3:pkg_cc_proto", + ]), ) envoy_cc_test( diff --git a/test/common/quic/BUILD b/test/common/quic/BUILD index dccc5b0e81..6852200522 100644 --- a/test/common/quic/BUILD +++ b/test/common/quic/BUILD @@ -14,353 +14,269 @@ envoy_package() envoy_cc_test( name = "envoy_quic_alarm_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_alarm_test.cc"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_alarm_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/common/quic:envoy_quic_alarm_factory_lib", - "//source/common/quic:envoy_quic_alarm_lib", - "//source/common/quic:envoy_quic_clock_lib", - "//test/test_common:simulated_time_system_lib", - "//test/test_common:utility_lib", - "@com_github_google_quiche//:quic_platform", - ], - }), + deps = envoy_select_enable_http3([ + "//source/common/quic:envoy_quic_alarm_factory_lib", + "//source/common/quic:envoy_quic_alarm_lib", + "//source/common/quic:envoy_quic_clock_lib", + "//test/test_common:simulated_time_system_lib", + "//test/test_common:utility_lib", + "@com_github_google_quiche//:quic_platform", + ]), ) envoy_cc_test( name = "envoy_quic_clock_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_clock_test.cc"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_clock_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/common/quic:envoy_quic_clock_lib", - "//test/test_common:simulated_time_system_lib", - "//test/test_common:test_time_lib", - "//test/test_common:utility_lib", - ], - }), + deps = envoy_select_enable_http3([ + "//source/common/quic:envoy_quic_clock_lib", + "//test/test_common:simulated_time_system_lib", + "//test/test_common:test_time_lib", + "//test/test_common:utility_lib", + ]), ) envoy_cc_test( name = "envoy_quic_writer_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_writer_test.cc"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_writer_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/common/network:io_socket_error_lib", - "//source/common/network:udp_packet_writer_handler_lib", - "//source/common/quic:envoy_quic_packet_writer_lib", - "//test/mocks/api:api_mocks", - "//test/mocks/network:network_mocks", - "//test/test_common:threadsafe_singleton_injector_lib", - "@com_github_google_quiche//:quic_platform", - ], - }), + deps = envoy_select_enable_http3([ + "//source/common/network:io_socket_error_lib", + "//source/common/network:udp_packet_writer_handler_lib", + "//source/common/quic:envoy_quic_packet_writer_lib", + "//test/mocks/api:api_mocks", + "//test/mocks/network:network_mocks", + "//test/test_common:threadsafe_singleton_injector_lib", + "@com_github_google_quiche//:quic_platform", + ]), ) envoy_cc_test( name = "envoy_quic_proof_source_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_proof_source_test.cc"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_proof_source_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":test_utils_lib", - "//source/common/quic:envoy_quic_proof_source_lib", - "//source/common/quic:envoy_quic_proof_verifier_lib", - "//source/common/tls:context_config_lib", - "//source/common/tls:server_context_lib", - "//test/mocks/network:network_mocks", - "//test/mocks/server:server_factory_context_mocks", - "//test/mocks/ssl:ssl_mocks", - "//test/test_common:test_runtime_lib", - "@com_github_google_quiche//:quic_core_versions_lib", - "@com_github_google_quiche//:quic_platform", - "@com_github_google_quiche//:quic_test_tools_test_certificates_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":test_utils_lib", + "//source/common/quic:envoy_quic_proof_source_lib", + "//source/common/quic:envoy_quic_proof_verifier_lib", + "//source/common/tls:context_config_lib", + "//source/common/tls:server_context_lib", + "//test/mocks/network:network_mocks", + "//test/mocks/server:server_factory_context_mocks", + "//test/mocks/ssl:ssl_mocks", + "//test/test_common:test_runtime_lib", + "@com_github_google_quiche//:quic_core_versions_lib", + "@com_github_google_quiche//:quic_platform", + "@com_github_google_quiche//:quic_test_tools_test_certificates_lib", + ]), ) envoy_cc_test( name = "quic_filter_manager_connection_impl_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["quic_filter_manager_connection_impl_test.cc"], - }), + srcs = envoy_select_enable_http3(["quic_filter_manager_connection_impl_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/common/quic:quic_filter_manager_connection_lib", - "//test/mocks/event:event_mocks", - "//test/mocks/network:network_mocks", - "//test/test_common:utility_lib", - "@com_github_google_quiche//:quic_test_tools_test_utils_lib", - ], - }), + deps = envoy_select_enable_http3([ + "//source/common/quic:quic_filter_manager_connection_lib", + "//test/mocks/event:event_mocks", + "//test/mocks/network:network_mocks", + "//test/test_common:utility_lib", + "@com_github_google_quiche//:quic_test_tools_test_utils_lib", + ]), ) envoy_cc_test( name = "quic_stat_names_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["quic_stat_names_test.cc"], - }), + srcs = envoy_select_enable_http3(["quic_stat_names_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/common/quic:quic_stat_names_lib", - "//source/common/stats:stats_lib", - "//test/mocks/stats:stats_mocks", - "//test/test_common:utility_lib", - ], - }), + deps = envoy_select_enable_http3([ + "//source/common/quic:quic_stat_names_lib", + "//source/common/stats:stats_lib", + "//test/mocks/stats:stats_mocks", + "//test/test_common:utility_lib", + ]), ) envoy_cc_test( name = "envoy_quic_proof_verifier_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_proof_verifier_test.cc"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_proof_verifier_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":test_utils_lib", - "//source/common/quic:envoy_quic_proof_verifier_lib", - "//source/common/tls:context_config_lib", - "//test/common/config:dummy_config_proto_cc_proto", - "//test/common/tls/cert_validator:timed_cert_validator", - "//test/mocks/event:event_mocks", - "//test/mocks/server:server_factory_context_mocks", - "//test/mocks/ssl:ssl_mocks", - "@com_github_google_quiche//:quic_platform", - "@com_github_google_quiche//:quic_test_tools_test_certificates_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":test_utils_lib", + "//source/common/quic:envoy_quic_proof_verifier_lib", + "//source/common/tls:context_config_lib", + "//test/common/config:dummy_config_proto_cc_proto", + "//test/common/tls/cert_validator:timed_cert_validator", + "//test/mocks/event:event_mocks", + "//test/mocks/server:server_factory_context_mocks", + "//test/mocks/ssl:ssl_mocks", + "@com_github_google_quiche//:quic_platform", + "@com_github_google_quiche//:quic_test_tools_test_certificates_lib", + ]), ) envoy_cc_test( name = "envoy_quic_server_stream_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_server_stream_test.cc"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_server_stream_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":test_utils_lib", - "//source/common/http:headers_lib", - "//source/common/quic:envoy_quic_alarm_factory_lib", - "//source/common/quic:envoy_quic_connection_helper_lib", - "//source/common/quic:envoy_quic_server_connection_lib", - "//source/common/quic:envoy_quic_server_session_lib", - "//source/server:active_listener_base", - "//test/mocks/http:http_mocks", - "//test/mocks/http:stream_decoder_mock", - "//test/mocks/network:network_mocks", - "//test/test_common:utility_lib", - "@com_github_google_quiche//:quic_core_http_spdy_session_lib", - "@com_github_google_quiche//:quic_test_tools_qpack_qpack_test_utils_lib", - "@com_github_google_quiche//:quic_test_tools_session_peer_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":test_utils_lib", + "//source/common/http:headers_lib", + "//source/common/quic:envoy_quic_alarm_factory_lib", + "//source/common/quic:envoy_quic_connection_helper_lib", + "//source/common/quic:envoy_quic_server_connection_lib", + "//source/common/quic:envoy_quic_server_session_lib", + "//source/server:active_listener_base", + "//test/mocks/http:http_mocks", + "//test/mocks/http:stream_decoder_mock", + "//test/mocks/network:network_mocks", + "//test/test_common:utility_lib", + "@com_github_google_quiche//:quic_core_http_spdy_session_lib", + "@com_github_google_quiche//:quic_test_tools_qpack_qpack_test_utils_lib", + "@com_github_google_quiche//:quic_test_tools_session_peer_lib", + ]), ) envoy_cc_test( name = "envoy_quic_client_stream_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_client_stream_test.cc"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_client_stream_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":test_utils_lib", - "//source/common/http:headers_lib", - "//source/common/quic:envoy_quic_alarm_factory_lib", - "//source/common/quic:envoy_quic_client_connection_lib", - "//source/common/quic:envoy_quic_client_session_lib", - "//source/common/quic:envoy_quic_connection_helper_lib", - "//test/mocks/http:http_mocks", - "//test/mocks/http:stream_decoder_mock", - "//test/mocks/network:network_mocks", - "//test/test_common:utility_lib", - "@com_github_google_quiche//:quic_core_http_spdy_session_lib", - "@com_github_google_quiche//:quic_test_tools_qpack_qpack_test_utils_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":test_utils_lib", + "//source/common/http:headers_lib", + "//source/common/quic:envoy_quic_alarm_factory_lib", + "//source/common/quic:envoy_quic_client_connection_lib", + "//source/common/quic:envoy_quic_client_session_lib", + "//source/common/quic:envoy_quic_connection_helper_lib", + "//test/mocks/http:http_mocks", + "//test/mocks/http:stream_decoder_mock", + "//test/mocks/network:network_mocks", + "//test/test_common:utility_lib", + "@com_github_google_quiche//:quic_core_http_spdy_session_lib", + "@com_github_google_quiche//:quic_test_tools_qpack_qpack_test_utils_lib", + ]), ) envoy_cc_test( name = "envoy_quic_server_session_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_server_session_test.cc"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_server_session_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":test_proof_source_lib", - ":test_utils_lib", - "//envoy/stats:stats_macros", - "//source/common/quic:envoy_quic_alarm_factory_lib", - "//source/common/quic:envoy_quic_connection_helper_lib", - "//source/common/quic:envoy_quic_server_connection_lib", - "//source/common/quic:envoy_quic_server_session_lib", - "//source/common/quic:server_codec_lib", - "//source/server:configuration_lib", - "//test/mocks/event:event_mocks", - "//test/mocks/http:http_mocks", - "//test/mocks/http:stream_decoder_mock", - "//test/mocks/network:network_mocks", - "//test/mocks/stats:stats_mocks", - "//test/test_common:global_lib", - "//test/test_common:logging_lib", - "//test/test_common:simulated_time_system_lib", - "@com_github_google_quiche//:quic_test_tools_config_peer_lib", - "@com_github_google_quiche//:quic_test_tools_server_session_base_peer", - "@com_github_google_quiche//:quic_test_tools_test_utils_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":test_proof_source_lib", + ":test_utils_lib", + "//envoy/stats:stats_macros", + "//source/common/quic:envoy_quic_alarm_factory_lib", + "//source/common/quic:envoy_quic_connection_helper_lib", + "//source/common/quic:envoy_quic_server_connection_lib", + "//source/common/quic:envoy_quic_server_session_lib", + "//source/common/quic:server_codec_lib", + "//source/server:configuration_lib", + "//test/mocks/event:event_mocks", + "//test/mocks/http:http_mocks", + "//test/mocks/http:stream_decoder_mock", + "//test/mocks/network:network_mocks", + "//test/mocks/stats:stats_mocks", + "//test/test_common:global_lib", + "//test/test_common:logging_lib", + "//test/test_common:simulated_time_system_lib", + "@com_github_google_quiche//:quic_test_tools_config_peer_lib", + "@com_github_google_quiche//:quic_test_tools_server_session_base_peer", + "@com_github_google_quiche//:quic_test_tools_test_utils_lib", + ]), ) envoy_cc_test( name = "envoy_quic_client_session_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_client_session_test.cc"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_client_session_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":test_utils_lib", - "//envoy/stats:stats_macros", - "//source/common/api:os_sys_calls_lib", - "//source/common/quic:client_codec_lib", - "//source/common/quic:envoy_quic_alarm_factory_lib", - "//source/common/quic:envoy_quic_client_connection_lib", - "//source/common/quic:envoy_quic_client_session_lib", - "//source/common/quic:envoy_quic_connection_helper_lib", - "//source/extensions/quic/crypto_stream:envoy_quic_crypto_client_stream_lib", - "//test/mocks/api:api_mocks", - "//test/mocks/http:http_mocks", - "//test/mocks/http:stream_decoder_mock", - "//test/mocks/network:network_mocks", - "//test/mocks/stats:stats_mocks", - "//test/test_common:logging_lib", - "//test/test_common:simulated_time_system_lib", - "//test/test_common:test_runtime_lib", - "//test/test_common:threadsafe_singleton_injector_lib", - "@com_github_google_quiche//:quic_test_tools_session_peer_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":test_utils_lib", + "//envoy/stats:stats_macros", + "//source/common/api:os_sys_calls_lib", + "//source/common/quic:client_codec_lib", + "//source/common/quic:envoy_quic_alarm_factory_lib", + "//source/common/quic:envoy_quic_client_connection_lib", + "//source/common/quic:envoy_quic_client_session_lib", + "//source/common/quic:envoy_quic_connection_helper_lib", + "//source/extensions/quic/crypto_stream:envoy_quic_crypto_client_stream_lib", + "//test/mocks/api:api_mocks", + "//test/mocks/http:http_mocks", + "//test/mocks/http:stream_decoder_mock", + "//test/mocks/network:network_mocks", + "//test/mocks/stats:stats_mocks", + "//test/test_common:logging_lib", + "//test/test_common:simulated_time_system_lib", + "//test/test_common:test_runtime_lib", + "//test/test_common:threadsafe_singleton_injector_lib", + "@com_github_google_quiche//:quic_test_tools_session_peer_lib", + ]), ) envoy_cc_test( name = "active_quic_listener_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["active_quic_listener_test.cc"], - }), + srcs = envoy_select_enable_http3(["active_quic_listener_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":test_proof_source_lib", - ":test_utils_lib", - "//source/common/http:utility_lib", - "//source/common/listener_manager:connection_handler_lib", - "//source/common/network:udp_packet_writer_handler_lib", - "//source/common/quic:active_quic_listener_lib", - "//source/common/quic:envoy_quic_utils_lib", - "//source/common/quic:udp_gso_batch_writer_lib", - "//source/extensions/quic/crypto_stream:envoy_quic_crypto_server_stream_lib", - "//source/extensions/quic/proof_source:envoy_quic_proof_source_factory_impl_lib", - "//source/server:configuration_lib", - "//source/server:process_context_lib", - "//test/mocks/network:network_mocks", - "//test/mocks/server:instance_mocks", - "//test/mocks/server:listener_factory_context_mocks", - "//test/test_common:network_utility_lib", - "//test/test_common:simulated_time_system_lib", - "//test/test_common:test_runtime_lib", - "@com_github_google_quiche//:quic_test_tools_crypto_server_config_peer_lib", - "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", - ], - }), + deps = envoy_select_enable_http3([ + ":test_proof_source_lib", + ":test_utils_lib", + "//source/common/http:utility_lib", + "//source/common/listener_manager:connection_handler_lib", + "//source/common/network:udp_packet_writer_handler_lib", + "//source/common/quic:active_quic_listener_lib", + "//source/common/quic:envoy_quic_utils_lib", + "//source/common/quic:udp_gso_batch_writer_lib", + "//source/extensions/quic/crypto_stream:envoy_quic_crypto_server_stream_lib", + "//source/extensions/quic/proof_source:envoy_quic_proof_source_factory_impl_lib", + "//source/server:configuration_lib", + "//source/server:process_context_lib", + "//test/mocks/network:network_mocks", + "//test/mocks/server:instance_mocks", + "//test/mocks/server:listener_factory_context_mocks", + "//test/test_common:network_utility_lib", + "//test/test_common:simulated_time_system_lib", + "//test/test_common:test_runtime_lib", + "@com_github_google_quiche//:quic_test_tools_crypto_server_config_peer_lib", + "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", + ]), ) envoy_cc_test( name = "envoy_quic_dispatcher_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_dispatcher_test.cc"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_dispatcher_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":test_proof_source_lib", - ":test_utils_lib", - "//envoy/stats:stats_macros", - "//source/common/listener_manager:connection_handler_lib", - "//source/common/quic:envoy_quic_alarm_factory_lib", - "//source/common/quic:envoy_quic_connection_helper_lib", - "//source/common/quic:envoy_quic_dispatcher_lib", - "//source/common/quic:envoy_quic_proof_source_lib", - "//source/common/quic:envoy_quic_server_session_lib", - "//source/common/quic:quic_server_transport_socket_factory_lib", - "//source/extensions/quic/crypto_stream:envoy_quic_crypto_server_stream_lib", - "//source/server:configuration_lib", - "//test/mocks/event:event_mocks", - "//test/mocks/http:http_mocks", - "//test/mocks/network:network_mocks", - "//test/mocks/ssl:ssl_mocks", - "//test/mocks/stats:stats_mocks", - "//test/test_common:global_lib", - "//test/test_common:simulated_time_system_lib", - "//test/test_common:test_runtime_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":test_proof_source_lib", + ":test_utils_lib", + "//envoy/stats:stats_macros", + "//source/common/listener_manager:connection_handler_lib", + "//source/common/quic:envoy_quic_alarm_factory_lib", + "//source/common/quic:envoy_quic_connection_helper_lib", + "//source/common/quic:envoy_quic_dispatcher_lib", + "//source/common/quic:envoy_quic_proof_source_lib", + "//source/common/quic:envoy_quic_server_session_lib", + "//source/common/quic:quic_server_transport_socket_factory_lib", + "//source/extensions/quic/crypto_stream:envoy_quic_crypto_server_stream_lib", + "//source/server:configuration_lib", + "//test/mocks/event:event_mocks", + "//test/mocks/http:http_mocks", + "//test/mocks/network:network_mocks", + "//test/mocks/ssl:ssl_mocks", + "//test/mocks/stats:stats_mocks", + "//test/test_common:global_lib", + "//test/test_common:simulated_time_system_lib", + "//test/test_common:test_runtime_lib", + ]), ) envoy_cc_test_library( name = "test_proof_source_lib", - hdrs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["test_proof_source.h"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/common/quic:envoy_quic_proof_source_base_lib", - "//test/mocks/network:network_mocks", - "@com_github_google_quiche//:quic_test_tools_test_certificates_lib", - ], - }), + hdrs = envoy_select_enable_http3(["test_proof_source.h"]), + deps = envoy_select_enable_http3([ + "//source/common/quic:envoy_quic_proof_source_base_lib", + "//test/mocks/network:network_mocks", + "@com_github_google_quiche//:quic_test_tools_test_certificates_lib", + ]), ) envoy_cc_test_library( @@ -373,83 +289,59 @@ envoy_cc_test_library( envoy_cc_test( name = "client_connection_factory_impl_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["client_connection_factory_impl_test.cc"], - }), + srcs = envoy_select_enable_http3(["client_connection_factory_impl_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/common/event:dispatcher_lib", - "//source/common/http/http3:conn_pool_lib", - "//source/common/network:utility_lib", - "//source/common/upstream:upstream_includes", - "//source/common/upstream:upstream_lib", - "//test/common/http:common_lib", - "//test/common/upstream:utility_lib", - "//test/mocks/event:event_mocks", - "//test/mocks/http:http_mocks", - "//test/mocks/http:http_server_properties_cache_mocks", - "//test/mocks/network:network_mocks", - "//test/mocks/runtime:runtime_mocks", - "//test/mocks/server:factory_context_mocks", - "//test/mocks/upstream:cluster_info_mocks", - "//test/mocks/upstream:transport_socket_match_mocks", - "//test/test_common:test_runtime_lib", - "//test/test_common:threadsafe_singleton_injector_lib", - ], - }), + deps = envoy_select_enable_http3([ + "//source/common/event:dispatcher_lib", + "//source/common/http/http3:conn_pool_lib", + "//source/common/network:utility_lib", + "//source/common/upstream:upstream_includes", + "//source/common/upstream:upstream_lib", + "//test/common/http:common_lib", + "//test/common/upstream:utility_lib", + "//test/mocks/event:event_mocks", + "//test/mocks/http:http_mocks", + "//test/mocks/http:http_server_properties_cache_mocks", + "//test/mocks/network:network_mocks", + "//test/mocks/runtime:runtime_mocks", + "//test/mocks/server:factory_context_mocks", + "//test/mocks/upstream:cluster_info_mocks", + "//test/mocks/upstream:transport_socket_match_mocks", + "//test/test_common:test_runtime_lib", + "//test/test_common:threadsafe_singleton_injector_lib", + ]), ) envoy_cc_test( name = "quic_io_handle_wrapper_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["quic_io_handle_wrapper_test.cc"], - }), + srcs = envoy_select_enable_http3(["quic_io_handle_wrapper_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/common/quic:quic_io_handle_wrapper_lib", - "//test/mocks/api:api_mocks", - "//test/mocks/network:io_handle_mocks", - "//test/mocks/network:network_mocks", - "//test/test_common:threadsafe_singleton_injector_lib", - ], - }), + deps = envoy_select_enable_http3([ + "//source/common/quic:quic_io_handle_wrapper_lib", + "//test/mocks/api:api_mocks", + "//test/mocks/network:io_handle_mocks", + "//test/mocks/network:network_mocks", + "//test/test_common:threadsafe_singleton_injector_lib", + ]), ) envoy_cc_test( name = "envoy_quic_utils_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_utils_test.cc"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_utils_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/common/quic:envoy_quic_utils_lib", - "//test/mocks/api:api_mocks", - "//test/test_common:threadsafe_singleton_injector_lib", - "@com_github_google_quiche//:quic_test_tools_test_utils_lib", - ], - }), + deps = envoy_select_enable_http3([ + "//source/common/quic:envoy_quic_utils_lib", + "//test/mocks/api:api_mocks", + "//test/test_common:threadsafe_singleton_injector_lib", + "@com_github_google_quiche//:quic_test_tools_test_utils_lib", + ]), ) envoy_cc_test( name = "envoy_quic_simulated_watermark_buffer_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_quic_simulated_watermark_buffer_test.cc"], - }), + srcs = envoy_select_enable_http3(["envoy_quic_simulated_watermark_buffer_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["//source/common/quic:envoy_quic_simulated_watermark_buffer_lib"], - }), + deps = envoy_select_enable_http3(["//source/common/quic:envoy_quic_simulated_watermark_buffer_lib"]), ) envoy_cc_test_library( @@ -475,59 +367,41 @@ envoy_cc_test_library( envoy_cc_test( name = "quic_transport_socket_factory_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["quic_transport_socket_factory_test.cc"], - }), + srcs = envoy_select_enable_http3(["quic_transport_socket_factory_test.cc"]), data = [ "//test/common/tls/test_data:certs", ], rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/common/quic:quic_server_transport_socket_factory_lib", - "//source/common/quic:quic_transport_socket_factory_lib", - "//source/common/tls:context_config_lib", - "//test/mocks/server:factory_context_mocks", - "//test/mocks/ssl:ssl_mocks", - "//test/test_common:environment_lib", - "//test/test_common:utility_lib", - ], - }), + deps = envoy_select_enable_http3([ + "//source/common/quic:quic_server_transport_socket_factory_lib", + "//source/common/quic:quic_transport_socket_factory_lib", + "//source/common/tls:context_config_lib", + "//test/mocks/server:factory_context_mocks", + "//test/mocks/ssl:ssl_mocks", + "//test/test_common:environment_lib", + "//test/test_common:utility_lib", + ]), ) envoy_cc_test( name = "http_datagram_handler_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["http_datagram_handler_test.cc"], - }), + srcs = envoy_select_enable_http3(["http_datagram_handler_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/common/quic:http_datagram_handler", - "//test/mocks/buffer:buffer_mocks", - "//test/test_common:utility_lib", - "@com_github_google_quiche//:quic_test_tools_test_utils_lib", - ], - }), + deps = envoy_select_enable_http3([ + "//source/common/quic:http_datagram_handler", + "//test/mocks/buffer:buffer_mocks", + "//test/test_common:utility_lib", + "@com_github_google_quiche//:quic_test_tools_test_utils_lib", + ]), ) envoy_cc_test( name = "cert_compression_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["cert_compression_test.cc"], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/common/quic:cert_compression_lib", - "//test/test_common:logging_lib", - ], - }), + srcs = envoy_select_enable_http3(["cert_compression_test.cc"]), + deps = envoy_select_enable_http3([ + "//source/common/quic:cert_compression_lib", + "//test/test_common:logging_lib", + ]), ) envoy_cc_test_library( @@ -538,19 +412,13 @@ envoy_cc_test_library( envoy_cc_test( name = "envoy_deterministic_connection_id_generator_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["envoy_deterministic_connection_id_generator_test.cc"], - }), + srcs = envoy_select_enable_http3(["envoy_deterministic_connection_id_generator_test.cc"]), rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - ":connection_id_matchers", - "//source/common/quic:envoy_deterministic_connection_id_generator_lib", - "@com_github_google_quiche//:quic_test_tools_test_utils_lib", - ], - }), + deps = envoy_select_enable_http3([ + ":connection_id_matchers", + "//source/common/quic:envoy_deterministic_connection_id_generator_lib", + "@com_github_google_quiche//:quic_test_tools_test_utils_lib", + ]), ) envoy_proto_library( diff --git a/test/extensions/quic/connection_debug_visitor/quic_stats/BUILD b/test/extensions/quic/connection_debug_visitor/quic_stats/BUILD index 09f8604492..e692103a8f 100644 --- a/test/extensions/quic/connection_debug_visitor/quic_stats/BUILD +++ b/test/extensions/quic/connection_debug_visitor/quic_stats/BUILD @@ -1,6 +1,7 @@ load( "//bazel:envoy_build_system.bzl", "envoy_package", + "envoy_select_enable_http3", ) load( "//test/extensions:extensions_build_system.bzl", @@ -13,36 +14,24 @@ envoy_package() envoy_extension_cc_test( name = "quic_stats_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["quic_stats_test.cc"], - }), + srcs = envoy_select_enable_http3(["quic_stats_test.cc"]), extension_names = ["envoy.quic.connection_debug_visitor.quic_stats"], - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/extensions/quic/connection_debug_visitor/quic_stats:quic_stats_lib", - "//test/mocks/event:event_mocks", - ], - }), + deps = envoy_select_enable_http3([ + "//source/extensions/quic/connection_debug_visitor/quic_stats:quic_stats_lib", + "//test/mocks/event:event_mocks", + ]), ) envoy_extension_cc_test( name = "integration_test", size = "large", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["integration_test.cc"], - }), + srcs = envoy_select_enable_http3(["integration_test.cc"]), extension_names = ["envoy.quic.connection_debug_visitor.quic_stats"], rbe_pool = "2core", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/extensions/quic/connection_debug_visitor/quic_stats:config", - "//test/integration:http_integration_lib", - "@envoy_api//envoy/extensions/quic/connection_debug_visitor/quic_stats/v3:pkg_cc_proto", - "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", - ], - }), + deps = envoy_select_enable_http3([ + "//source/extensions/quic/connection_debug_visitor/quic_stats:config", + "//test/integration:http_integration_lib", + "@envoy_api//envoy/extensions/quic/connection_debug_visitor/quic_stats/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", + ]), ) diff --git a/test/extensions/quic/connection_id_generator/quic_lb/BUILD b/test/extensions/quic/connection_id_generator/quic_lb/BUILD index 32a2b64afa..e52da315db 100644 --- a/test/extensions/quic/connection_id_generator/quic_lb/BUILD +++ b/test/extensions/quic/connection_id_generator/quic_lb/BUILD @@ -1,6 +1,7 @@ load( "//bazel:envoy_build_system.bzl", "envoy_package", + "envoy_select_enable_http3", ) load( "//test/extensions:extensions_build_system.bzl", @@ -13,39 +14,27 @@ envoy_package() envoy_extension_cc_test( name = "quic_lb_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["quic_lb_test.cc"], - }), + srcs = envoy_select_enable_http3(["quic_lb_test.cc"]), extension_names = ["envoy.quic.connection_id_generator.quic_lb"], rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/extensions/quic/connection_id_generator/quic_lb:quic_lb_lib", - "//test/mocks/server:factory_context_mocks", - "@com_github_google_quiche//:quic_test_tools_test_utils_lib", - ], - }), + deps = envoy_select_enable_http3([ + "//source/extensions/quic/connection_id_generator/quic_lb:quic_lb_lib", + "//test/mocks/server:factory_context_mocks", + "@com_github_google_quiche//:quic_test_tools_test_utils_lib", + ]), ) envoy_extension_cc_test( name = "integration_test", size = "large", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["integration_test.cc"], - }), + srcs = envoy_select_enable_http3(["integration_test.cc"]), extension_names = ["envoy.quic.connection_id_generator.quic_lb"], rbe_pool = "4core", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/extensions/quic/connection_id_generator/quic_lb:quic_lb_config", - "//test/integration:http_integration_lib", - "//test/integration:quic_http_integration_test_lib", - "@envoy_api//envoy/extensions/quic/connection_id_generator/quic_lb/v3:pkg_cc_proto", - "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", - ], - }), + deps = envoy_select_enable_http3([ + "//source/extensions/quic/connection_id_generator/quic_lb:quic_lb_config", + "//test/integration:http_integration_lib", + "//test/integration:quic_http_integration_test_lib", + "@envoy_api//envoy/extensions/quic/connection_id_generator/quic_lb/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", + ]), ) diff --git a/test/extensions/quic/server_preferred_address/BUILD b/test/extensions/quic/server_preferred_address/BUILD index 20f5f47ed8..251f0d8aba 100644 --- a/test/extensions/quic/server_preferred_address/BUILD +++ b/test/extensions/quic/server_preferred_address/BUILD @@ -1,6 +1,7 @@ load( "//bazel:envoy_build_system.bzl", "envoy_package", + "envoy_select_enable_http3", ) load( "//test/extensions:extensions_build_system.bzl", @@ -13,36 +14,24 @@ envoy_package() envoy_extension_cc_test( name = "datasource_server_preferred_address_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["datasource_server_preferred_address_test.cc"], - }), + srcs = envoy_select_enable_http3(["datasource_server_preferred_address_test.cc"]), extension_names = ["envoy.quic.server_preferred_address.datasource"], rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/extensions/quic/server_preferred_address:datasource_server_preferred_address_config_lib", - "//test/mocks/protobuf:protobuf_mocks", - "//test/mocks/server:server_factory_context_mocks", - ], - }), + deps = envoy_select_enable_http3([ + "//source/extensions/quic/server_preferred_address:datasource_server_preferred_address_config_lib", + "//test/mocks/protobuf:protobuf_mocks", + "//test/mocks/server:server_factory_context_mocks", + ]), ) envoy_extension_cc_test( name = "fixed_server_preferred_address_test", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": ["fixed_server_preferred_address_test.cc"], - }), + srcs = envoy_select_enable_http3(["fixed_server_preferred_address_test.cc"]), extension_names = ["envoy.quic.server_preferred_address.fixed"], rbe_pool = "6gig", - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//source/extensions/quic/server_preferred_address:fixed_server_preferred_address_config_lib", - "//test/mocks/protobuf:protobuf_mocks", - "//test/mocks/server:server_factory_context_mocks", - ], - }), + deps = envoy_select_enable_http3([ + "//source/extensions/quic/server_preferred_address:fixed_server_preferred_address_config_lib", + "//test/mocks/protobuf:protobuf_mocks", + "//test/mocks/server:server_factory_context_mocks", + ]), ) diff --git a/test/integration/BUILD b/test/integration/BUILD index 85d9472e5e..81734e5281 100644 --- a/test/integration/BUILD +++ b/test/integration/BUILD @@ -1492,12 +1492,9 @@ envoy_cc_test( "//test/test_common:utility_lib", "@envoy_api//envoy/config/route/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg_cc_proto", - ] + select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//test/integration/filters:pause_filter_for_quic_lib", - ], - }), + ] + envoy_select_enable_http3([ + "//test/integration/filters:pause_filter_for_quic_lib", + ]), ) envoy_cc_test( diff --git a/test/integration/filters/BUILD b/test/integration/filters/BUILD index 71999ad353..fea543cfd7 100644 --- a/test/integration/filters/BUILD +++ b/test/integration/filters/BUILD @@ -3,6 +3,7 @@ load( "envoy_cc_test_library", "envoy_package", "envoy_proto_library", + "envoy_select_enable_http3", ) licenses(["notice"]) # Apache 2 @@ -469,22 +470,16 @@ envoy_cc_test_library( envoy_cc_test_library( name = "pause_filter_for_quic_lib", - srcs = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "pause_filter_for_quic.cc", - ], - }), - deps = select({ - "//bazel:disable_http3": [], - "//conditions:default": [ - "//envoy/http:filter_interface", - "//envoy/registry", - "//source/common/quic:quic_filter_manager_connection_lib", - "//source/extensions/filters/http/common:pass_through_filter_lib", - "//test/extensions/filters/http/common:empty_http_filter_config_lib", - ], - }), + srcs = envoy_select_enable_http3([ + "pause_filter_for_quic.cc", + ]), + deps = envoy_select_enable_http3([ + "//envoy/http:filter_interface", + "//envoy/registry", + "//source/common/quic:quic_filter_manager_connection_lib", + "//source/extensions/filters/http/common:pass_through_filter_lib", + "//test/extensions/filters/http/common:empty_http_filter_config_lib", + ]), ) envoy_cc_test_library( diff --git a/test/per_file_coverage.sh b/test/per_file_coverage.sh index b496e8301b..57d0906699 100755 --- a/test/per_file_coverage.sh +++ b/test/per_file_coverage.sh @@ -4,6 +4,7 @@ # for existing directories with low coverage. declare -a KNOWN_LOW_COVERAGE=( "source/common:96.4" +"source/common/common:96.5" "source/common/common/posix:96.2" # flaky due to posix: be careful adjusting "source/common/config:96.4" "source/common/crypto:95.5" @@ -15,14 +16,14 @@ declare -a KNOWN_LOW_COVERAGE=( "source/common/memory:74.5" # tcmalloc code path is not enabled in coverage build, only gperf tcmalloc, see PR#32589 "source/common/network:94.4" # Flaky, `activateFileEvents`, `startSecureTransport` and `ioctl`, listener_socket do not always report LCOV "source/common/network/dns_resolver:91.4" # A few lines of MacOS code not tested in linux scripts. Tested in MacOS scripts -"source/common/quic:93.2" +"source/common/quic:92.9" "source/common/signal:87.2" # Death tests don't report LCOV "source/common/thread:0.0" # Death tests don't report LCOV "source/common/tls:95.5" "source/common/tls/cert_validator:94.7" "source/common/tls/private_key:88.9" "source/common/watchdog:58.6" # Death tests don't report LCOV -"source/exe:94.2" # increased by #32346, need coverage for terminate_handler and hot restart failures +"source/exe:87.9" # increased by #32346, need coverage for terminate_handler and hot restart failures "source/extensions/common/proxy_protocol:93.8" # Adjusted for security patch "source/extensions/common/tap:94.6" "source/extensions/common/wasm:95.3" # flaky: be careful adjusting @@ -40,6 +41,7 @@ declare -a KNOWN_LOW_COVERAGE=( "source/extensions/filters/network/sni_cluster:88.9" "source/extensions/rate_limit_descriptors:95.0" "source/extensions/rate_limit_descriptors/expr:95.0" +"source/extensions/resource_monitors/cpu_utilization:96.3" "source/extensions/stat_sinks/graphite_statsd:82.8" # Death tests don't report LCOV "source/extensions/stat_sinks/statsd:85.2" # Death tests don't report LCOV "source/extensions/tracers/zipkin:95.8" From 71b07fcf8540eed720456f966bf738d6a24a7d84 Mon Sep 17 00:00:00 2001 From: code Date: Wed, 11 Jun 2025 23:16:01 +0800 Subject: [PATCH 15/35] fix: fix a bug where the validate mode may assert failure (#39761) --- changelogs/current.yaml | 4 ++++ source/server/config_validation/server.cc | 12 ++++++++++ source/server/config_validation/server.h | 2 ++ test/config/utility.cc | 24 ++++++++++++++++++- test/config/utility.h | 8 +++---- .../config_validation/xds_verifier_test.cc | 2 +- 6 files changed, 46 insertions(+), 6 deletions(-) diff --git a/changelogs/current.yaml b/changelogs/current.yaml index a976d411ae..abcb7d97b4 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -21,6 +21,10 @@ bug_fixes: draining. This can result in not enough connections being established for current pending requests. This is most problematic for long-lived requests (such as streaming gRPC requests or long-poll requests) because a connection could be in the draining state for a long time. +- area: config_validation + change: | + Fixed an bug where the config validation server will crash when the configuration contains + ``%CEL%`` or ``%METADATA%`` substitution formatter. removed_config_or_runtime: # *Normally occurs at the end of the* :ref:`deprecation period ` diff --git a/source/server/config_validation/server.cc b/source/server/config_validation/server.cc index bc75abbd7d..a37a224195 100644 --- a/source/server/config_validation/server.cc +++ b/source/server/config_validation/server.cc @@ -65,16 +65,28 @@ ValidationInstance::ValidationInstance( grpc_context_(stats_store_.symbolTable()), http_context_(stats_store_.symbolTable()), router_context_(stats_store_.symbolTable()), time_system_(time_system), server_contexts_(*this), quic_stat_names_(stats_store_.symbolTable()) { + + // Register the server factory context on the main thread. + Configuration::ServerFactoryContextInstance::initialize(&server_contexts_); + TRY_ASSERT_MAIN_THREAD { initialize(options, local_address, component_factory); } END_TRY catch (const EnvoyException& e) { ENVOY_LOG(critical, "error initializing configuration '{}': {}", options.configPath(), e.what()); shutdown(); + + // Clear the server factory context on the main thread. + Configuration::ServerFactoryContextInstance::clear(); throw; } } +ValidationInstance::~ValidationInstance() { + // Clear the server factory context on the main thread. + Configuration::ServerFactoryContextInstance::clear(); +} + void ValidationInstance::initialize(const Options& options, const Network::Address::InstanceConstSharedPtr& local_address, ComponentFactory& component_factory) { diff --git a/source/server/config_validation/server.h b/source/server/config_validation/server.h index e7a3fb2071..47d9495f50 100644 --- a/source/server/config_validation/server.h +++ b/source/server/config_validation/server.h @@ -71,6 +71,8 @@ class ValidationInstance final : Logger::Loggable, Filesystem::Instance& file_system, const ProcessContextOptRef& process_context = absl::nullopt); + ~ValidationInstance() override; + // Server::Instance void run() override { PANIC("not implemented"); } OptRef admin() override { diff --git a/test/config/utility.cc b/test/config/utility.cc index c752048d46..d80781f839 100644 --- a/test/config/utility.cc +++ b/test/config/utility.cc @@ -672,7 +672,8 @@ envoy::config::listener::v3::Listener ConfigHelper::buildListener(const std::str } envoy::config::route::v3::RouteConfiguration -ConfigHelper::buildRouteConfig(const std::string& name, const std::string& cluster) { +ConfigHelper::buildRouteConfig(const std::string& name, const std::string& cluster, + bool header_mutations) { API_NO_BOOST(envoy::config::route::v3::RouteConfiguration) route; #ifdef ENVOY_ENABLE_YAML TestUtility::loadFromYaml(fmt::format(R"EOF( @@ -686,10 +687,31 @@ ConfigHelper::buildRouteConfig(const std::string& name, const std::string& clust )EOF", name, cluster), route); + + if (header_mutations) { + auto* route_entry = route.mutable_virtual_hosts(0)->mutable_routes(0); + auto* header1 = route_entry->add_request_headers_to_add(); + *header1->mutable_header()->mutable_key() = "test-metadata"; + *header1->mutable_header()->mutable_value() = "%METADATA(ROUTE:com.test.my_filter)%"; + + auto* header2 = route_entry->add_response_headers_to_add(); + *header2->mutable_header()->mutable_key() = "test-cel"; + *header2->mutable_header()->mutable_value() = "%CEL(request.headers['some-header'])%"; + + auto* header3 = route_entry->add_response_headers_to_add(); + *header3->mutable_header()->mutable_key() = "test-other-command"; + *header3->mutable_header()->mutable_value() = "%START_TIME%"; + + auto* header4 = route_entry->add_response_headers_to_add(); + *header4->mutable_header()->mutable_key() = "test-plain"; + *header4->mutable_header()->mutable_value() = "plain"; + } + return route; #else UNREFERENCED_PARAMETER(name); UNREFERENCED_PARAMETER(cluster); + UNREFERENCED_PARAMETER(header_mutations); PANIC("YAML support compiled out"); #endif } diff --git a/test/config/utility.h b/test/config/utility.h index b9f530fe49..fcb6cc6575 100644 --- a/test/config/utility.h +++ b/test/config/utility.h @@ -164,8 +164,7 @@ class ConfigHelper { bool keylog_multiple_ips_{false}; std::string keylog_path_; Network::Address::IpVersion ip_version_{Network::Address::IpVersion::v4}; - std::vector - san_matchers_{}; + std::vector san_matchers_; std::string tls_cert_selector_yaml_{""}; bool client_with_intermediate_cert_{false}; bool trust_root_only_{false}; @@ -280,8 +279,9 @@ class ConfigHelper { const std::string& address, const std::string& stat_prefix); - static envoy::config::route::v3::RouteConfiguration buildRouteConfig(const std::string& name, - const std::string& cluster); + static envoy::config::route::v3::RouteConfiguration + buildRouteConfig(const std::string& name, const std::string& cluster, + bool header_mutations = false); // Builds a standard Endpoint suitable for population by finalize(). static envoy::config::endpoint::v3::Endpoint buildEndpoint(const std::string& address); diff --git a/test/server/config_validation/xds_verifier_test.cc b/test/server/config_validation/xds_verifier_test.cc index f0cbef7fdc..d5f73e9bec 100644 --- a/test/server/config_validation/xds_verifier_test.cc +++ b/test/server/config_validation/xds_verifier_test.cc @@ -11,7 +11,7 @@ envoy::config::listener::v3::Listener buildListener(const std::string& listener_ } envoy::config::route::v3::RouteConfiguration buildRoute(const std::string& route_name) { - return ConfigHelper::buildRouteConfig(route_name, "cluster_0"); + return ConfigHelper::buildRouteConfig(route_name, "cluster_0", true); } // Add, warm, drain and remove a listener. From c0f09f5a0ed52945993df5a27a02817288c89aeb Mon Sep 17 00:00:00 2001 From: phlax Date: Wed, 11 Jun 2025 22:06:55 +0100 Subject: [PATCH 16/35] ci/cache: Shift cache create action to do_ci.sh (#39845) Signed-off-by: Ryan Northey --- .github/workflows/_request_cache_bazel.yml | 107 --------------------- ci/do_ci.sh | 21 ++++ 2 files changed, 21 insertions(+), 107 deletions(-) delete mode 100644 .github/workflows/_request_cache_bazel.yml diff --git a/.github/workflows/_request_cache_bazel.yml b/.github/workflows/_request_cache_bazel.yml deleted file mode 100644 index ae829a488a..0000000000 --- a/.github/workflows/_request_cache_bazel.yml +++ /dev/null @@ -1,107 +0,0 @@ -name: Request/Cache prime (bazel) - -permissions: - contents: read - -on: - workflow_call: - secrets: - app-id: - required: true - app-key: - required: true - gcs-cache-key: - required: true - - inputs: - gcs-cache-bucket: - type: string - required: true - - arch: - type: string - default: x64 - bazel-extra: - type: string - default: >- - --config=remote-envoy-engflow - caches: - type: string - required: true - request: - type: string - required: true - runs-on: - type: string - default: - lock-repository: - type: string - default: envoyproxy/ci-mutex - targets: - type: string - default: ... - - -jobs: - bazel: - permissions: - contents: read - packages: read - runs-on: ${{ inputs.runs-on || fromJSON(inputs.request).config.ci.agent-ubuntu }} - name: "[${{ inputs.arch }}] Prime Bazel cache" - if: ${{ ! fromJSON(inputs.caches).bazel[inputs.arch] }} - steps: - - uses: envoyproxy/toolshed/gh-actions/github/checkout@actions-v0.3.16 - id: checkout-target - name: Checkout Envoy repository (target branch) - with: - branch: ${{ fromJSON(inputs.request).request.target-branch }} - config: | - fetch-depth: 1 - - - uses: envoyproxy/toolshed/gh-actions/appauth@actions-v0.3.16 - id: appauth - name: Appauth (mutex lock) - with: - app_id: ${{ secrets.app-id }} - key: ${{ secrets.app-key }} - - - uses: envoyproxy/toolshed/gh-actions/gcp/setup@actions-v0.3.16 - name: Setup GCP - with: - key: ${{ secrets.gcs-cache-key }} - force-install: ${{ contains(fromJSON('["envoy-arm64-medium", "github-arm64-2c-8gb"]'), inputs.runs-on) }} - - run: | - # Simulate container build directory - sudo mkdir /build - sudo chown runner:docker /build - echo "GITHUB_TOKEN=${{ github.token }}" >> $GITHUB_ENV - - uses: envoyproxy/toolshed/gh-actions/cache/prime@actions-v0.3.16 - id: bazel-cache - name: Prime Bazel cache - with: - change-directory: false - # TODO(phlax): add loop for multiple targets - command: | - # Simulate container source directory - sudo mkdir /source - sudo chown runner:docker /source - cd /source - git clone "$GITHUB_WORKSPACE" . - - echo "Fetching: ${{ inputs.targets }}" - # ironically the repository_cache is just about the only thing you dont want to cache - bazel --output_user_root=/build/bazel_root \ - --output_base=/build/bazel_root/base \ - aquery "deps(${{ inputs.targets }})" \ - --config=ci \ - --repository_cache=/tmp/cache \ - ${{ inputs.bazel-extra }} \ - > /dev/null - gcs-bucket: ${{ inputs.gcs-cache-bucket }} - key: ${{ fromJSON(inputs.request).config.ci.cache.bazel }}-${{ inputs.arch }} - lock-token: ${{ steps.appauth.outputs.token }} - lock-repository: ${{ inputs.lock-repository }} - mount-tmpfs: false - path: /build/bazel_root - run-as-sudo: false diff --git a/ci/do_ci.sh b/ci/do_ci.sh index d540eddb0a..cba082a87c 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -325,6 +325,27 @@ case $CI_TARGET in # fi ;; + cache-create) + if [[ -z "${ENVOY_CACHE_TARGETS}" ]]; then + echo "ENVOY_CACHE_TARGETS not set" >&2 + exit 1 + fi + if [[ -z "${ENVOY_CACHE_ROOT}" ]]; then + echo "ENVOY_CACHE_ROOT not set" >&2 + exit 1 + fi + BAZEL_BUILD_OPTIONS=() + setup_clang_toolchain + echo "Fetching cache: ${ENVOY_CACHE_TARGETS}" + bazel --output_user_root="${ENVOY_CACHE_ROOT}" \ + --output_base="${ENVOY_CACHE_ROOT}/base" \ + aquery "deps(${ENVOY_CACHE_TARGETS})" \ + --repository_cache="${ENVOY_REPOSITORY_CACHE}" \ + "${BAZEL_BUILD_OPTIONS[@]}" \ + "${BAZEL_BUILD_EXTRA_OPTIONS[@]}" \ + > /dev/null + ;; + format-api|check_and_fix_proto_format) setup_clang_toolchain echo "Check and fix proto format ..." From 0ce4bac1ca9018ef7f83b5fe97a9b6b73bc619cf Mon Sep 17 00:00:00 2001 From: kishor7007 <148222973+kishor7007@users.noreply.github.com> Date: Wed, 25 Jun 2025 21:13:39 +0530 Subject: [PATCH 17/35] DNS Logs: Back-port - categorising dns non-error logs to trace log levels (#40011) Cherry-pick of https://github.com/envoyproxy/envoy/pull/39954 PR to fix https://github.com/envoyproxy/envoy/issues/39142 for 1.34 branch On strict dns / logical dns resolutions if there are errors on the DNS resolution, the failure logs are getting written only when debug log level enabled and general logs are also in debug level. So, making the general/success logs in the trace level to suppress the general logs when user wants only error logs. Signed-off-by: kishor7007 --- .../dns_resolver/apple/apple_dns_impl.cc | 22 +++++++++---------- .../network/dns_resolver/cares/dns_impl.cc | 18 +++++++-------- .../dns_resolver/getaddrinfo/getaddrinfo.cc | 18 +++++++-------- .../dns_resolver/getaddrinfo/getaddrinfo.h | 2 +- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/source/extensions/network/dns_resolver/apple/apple_dns_impl.cc b/source/extensions/network/dns_resolver/apple/apple_dns_impl.cc index b7a877db83..36f70e778a 100644 --- a/source/extensions/network/dns_resolver/apple/apple_dns_impl.cc +++ b/source/extensions/network/dns_resolver/apple/apple_dns_impl.cc @@ -60,7 +60,7 @@ AppleDnsResolverStats AppleDnsResolverImpl::generateAppleDnsResolverStats(Stats: AppleDnsResolverImpl::StartResolutionResult AppleDnsResolverImpl::startResolution(const std::string& dns_name, DnsLookupFamily dns_lookup_family, ResolveCb callback) { - ENVOY_LOG_EVENT(debug, "apple_dns_start", "DNS resolution for {} started", dns_name); + ENVOY_LOG_EVENT(trace, "apple_dns_start", "DNS resolution for {} started", dns_name); // When an IP address is submitted to c-ares in DnsResolverImpl, c-ares synchronously returns // the IP without submitting a DNS query. Because Envoy has come to rely on this behavior, this @@ -69,7 +69,7 @@ AppleDnsResolverImpl::startResolution(const std::string& dns_name, auto address = Utility::parseInternetAddressNoThrow(dns_name); if (address != nullptr) { - ENVOY_LOG_EVENT(debug, "apple_dns_immediate_resolution", + ENVOY_LOG_EVENT(trace, "apple_dns_immediate_resolution", "DNS resolver resolved ({}) to ({}) without issuing call to Apple API", dns_name, address->asString()); callback(DnsResolver::ResolutionStatus::Completed, "apple_dns_immediate_success", @@ -148,7 +148,7 @@ AppleDnsResolverImpl::PendingResolution::PendingResolution(AppleDnsResolverImpl& pending_response_(PendingResponse()), dns_lookup_family_(dns_lookup_family) {} AppleDnsResolverImpl::PendingResolution::~PendingResolution() { - ENVOY_LOG(debug, "Destroying PendingResolution for {}", dns_name_); + ENVOY_LOG(trace, "Destroying PendingResolution for {}", dns_name_); // dns_sd.h says: // If the reference's underlying socket is used in a run loop or select() call, it should @@ -162,7 +162,7 @@ AppleDnsResolverImpl::PendingResolution::~PendingResolution() { // thus the DNSServiceRef is null. // Therefore, only deallocate if the ref is not null. if (sd_ref_) { - ENVOY_LOG(debug, "DNSServiceRefDeallocate individual sd ref"); + ENVOY_LOG(trace, "DNSServiceRefDeallocate individual sd ref"); DnsServiceSingleton::get().dnsServiceRefDeallocate(sd_ref_); } } @@ -191,7 +191,7 @@ std::string AppleDnsResolverImpl::PendingResolution::getTraces() { } void AppleDnsResolverImpl::PendingResolution::onEventCallback(uint32_t events) { - ENVOY_LOG(debug, "DNS resolver file event ({})", events); + ENVOY_LOG(trace, "DNS resolver file event ({})", events); RELEASE_ASSERT(events & Event::FileReadyType::Read, fmt::format("invalid FileReadyType event={}", events)); DNSServiceErrorType error = DnsServiceSingleton::get().dnsServiceProcessResult(sd_ref_); @@ -246,7 +246,7 @@ std::list& AppleDnsResolverImpl::PendingResolution::finalAddressLis } void AppleDnsResolverImpl::PendingResolution::finishResolve(AppleDnsTrace trace) { - ENVOY_LOG_EVENT(debug, "apple_dns_resolution_complete", + ENVOY_LOG_EVENT(trace, "apple_dns_resolution_complete", "dns resolution for {} completed with status {}", dns_name_, static_cast(pending_response_.status_)); addTrace(static_cast(trace)); @@ -254,10 +254,10 @@ void AppleDnsResolverImpl::PendingResolution::finishResolve(AppleDnsTrace trace) std::move(finalAddressList())); if (owned_) { - ENVOY_LOG(debug, "Resolution for {} completed (async)", dns_name_); + ENVOY_LOG(trace, "Resolution for {} completed (async)", dns_name_); delete this; } else { - ENVOY_LOG(debug, "Resolution for {} completed (synchronously)", dns_name_); + ENVOY_LOG(trace, "Resolution for {} completed (synchronously)", dns_name_); synchronously_completed_ = true; } } @@ -337,7 +337,7 @@ void AppleDnsResolverImpl::PendingResolution::onDNSServiceGetAddrInfoReply( // still be non-null and its `sa_family` will be the address family of the query (even if the // address itself isn't a meaningful IP address). - ENVOY_LOG(debug, + ENVOY_LOG(trace, "DNS for {} resolved with: flags={}[MoreComing={}, Add={}], interface_index={}, " "error_code={}, hostname={}", dns_name_, flags, flags & kDNSServiceFlagsMoreComing ? "yes" : "no", @@ -380,7 +380,7 @@ void AppleDnsResolverImpl::PendingResolution::onDNSServiceGetAddrInfoReply( // Therefore, only add this address to the list if kDNSServiceFlagsAdd is set. if (error_code == kDNSServiceErr_NoError && (flags & kDNSServiceFlagsAdd)) { auto dns_response = buildDnsResponse(address, ttl); - ENVOY_LOG(debug, "Address to add address={}, ttl={}", + ENVOY_LOG(trace, "Address to add address={}, ttl={}", dns_response.addrInfo().address_->ip()->addressAsString(), ttl); if (dns_response.addrInfo().address_->ip()->ipv4()) { pending_response_.v4_responses_.push_back(dns_response); @@ -392,7 +392,7 @@ void AppleDnsResolverImpl::PendingResolution::onDNSServiceGetAddrInfoReply( if (!(flags & kDNSServiceFlagsMoreComing) && isAddressFamilyProcessed(kDNSServiceProtocol_IPv4) && isAddressFamilyProcessed(kDNSServiceProtocol_IPv6)) { - ENVOY_LOG(debug, "DNS Resolver flushing queries pending callback"); + ENVOY_LOG(trace, "DNS Resolver flushing queries pending callback"); pending_response_.status_ = ResolutionStatus::Completed; pending_response_.details_ = absl::StrCat("apple_dns_completed_", error_code); AppleDnsTrace trace = (error_code == kDNSServiceErr_NoSuchRecord) ? AppleDnsTrace::NoResult diff --git a/source/extensions/network/dns_resolver/cares/dns_impl.cc b/source/extensions/network/dns_resolver/cares/dns_impl.cc index 0896963c7d..69588e9897 100644 --- a/source/extensions/network/dns_resolver/cares/dns_impl.cc +++ b/source/extensions/network/dns_resolver/cares/dns_impl.cc @@ -212,7 +212,7 @@ void DnsResolverImpl::AddrInfoPendingResolution::onAresGetAddrInfoCallback( // ARES_ECONNREFUSED. If the PendingResolution has not been cancelled that means that the // callback_ target _should_ still be around. In that case, raise the callback_ so the target // can be done with this query and initiate a new one. - ENVOY_LOG_EVENT(debug, "cares_dns_resolution_destroyed", "dns resolution for {} destroyed", + ENVOY_LOG_EVENT(trace, "cares_dns_resolution_destroyed", "dns resolution for {} destroyed", dns_name_); // Nothing can follow a call to finishResolve due to the deletion of this object upon @@ -322,7 +322,7 @@ void DnsResolverImpl::AddrInfoPendingResolution::onAresGetAddrInfoCallback( } void DnsResolverImpl::PendingResolution::finishResolve() { - ENVOY_LOG_EVENT(debug, "cares_dns_resolution_complete", + ENVOY_LOG_EVENT(trace, "cares_dns_resolution_complete", "dns resolution for {} completed with status {:#06x}: \"{}\"", dns_name_, static_cast(pending_response_.status_), pending_response_.details_); @@ -419,7 +419,7 @@ void DnsResolverImpl::reinitializeChannel() { int result = ares_reinit(channel_); RELEASE_ASSERT(result == ARES_SUCCESS, "c-ares channel re-initialization failed"); stats_.reinits_.inc(); - ENVOY_LOG_EVENT(debug, "cares_channel_reinitialized", + ENVOY_LOG_EVENT(trace, "cares_channel_reinitialized", "Reinitialized cares channel via ares_reinit"); if (resolvers_csv_.has_value()) { @@ -439,7 +439,7 @@ void DnsResolverImpl::reinitializeChannel() { ActiveDnsQuery* DnsResolverImpl::resolve(const std::string& dns_name, DnsLookupFamily dns_lookup_family, ResolveCb callback) { - ENVOY_LOG_EVENT(debug, "cares_dns_resolution_start", "dns resolution for {} started", dns_name); + ENVOY_LOG_EVENT(trace, "cares_dns_resolution_start", "dns resolution for {} started", dns_name); // TODO(hennna): Add DNS caching which will allow testing the edge case of a // failed initial call to getAddrInfo followed by a synchronous IPv4 @@ -451,7 +451,7 @@ ActiveDnsQuery* DnsResolverImpl::resolve(const std::string& dns_name, if (pending_resolution->completed_) { // Resolution does not need asynchronous behavior or network events. For // example, localhost lookup. - ENVOY_LOG_EVENT(debug, "cares_resolution_completed", + ENVOY_LOG_EVENT(trace, "cares_resolution_completed", "dns resolution for {} completed with no async or network events", dns_name); return nullptr; } else { @@ -520,14 +520,14 @@ void DnsResolverImpl::AddrInfoPendingResolution::startResolutionImpl(int family) switch (family) { case AF_INET: if (!available_interfaces_.v4_available_) { - ENVOY_LOG_EVENT(debug, "cares_resolution_filtered", "filtered v4 lookup"); + ENVOY_LOG_EVENT(trace, "cares_resolution_filtered", "filtered v4 lookup"); onAresGetAddrInfoCallback(ARES_EBADFAMILY, 0, nullptr); return; } break; case AF_INET6: if (!available_interfaces_.v6_available_) { - ENVOY_LOG_EVENT(debug, "cares_resolution_filtered", "filtered v6 lookup"); + ENVOY_LOG_EVENT(trace, "cares_resolution_filtered", "filtered v6 lookup"); onAresGetAddrInfoCallback(ARES_EBADFAMILY, 0, nullptr); return; } @@ -644,7 +644,7 @@ class CaresDnsResolverFactory : public DnsResolverFactory, absl::MutexLock lock(&mutex_); if (!ares_library_initialized_) { ares_library_initialized_ = true; - ENVOY_LOG(debug, "c-ares library initialized."); + ENVOY_LOG(trace, "c-ares library initialized."); ares_library_init(ARES_LIB_INIT_ALL); } } @@ -653,7 +653,7 @@ class CaresDnsResolverFactory : public DnsResolverFactory, absl::MutexLock lock(&mutex_); if (ares_library_initialized_) { ares_library_initialized_ = false; - ENVOY_LOG(debug, "c-ares library cleaned up."); + ENVOY_LOG(trace, "c-ares library cleaned up."); ares_library_cleanup(); } } diff --git a/source/extensions/network/dns_resolver/getaddrinfo/getaddrinfo.cc b/source/extensions/network/dns_resolver/getaddrinfo/getaddrinfo.cc index 0a1bed228a..82bbb2964a 100644 --- a/source/extensions/network/dns_resolver/getaddrinfo/getaddrinfo.cc +++ b/source/extensions/network/dns_resolver/getaddrinfo/getaddrinfo.cc @@ -34,8 +34,8 @@ GetAddrInfoDnsResolver::~GetAddrInfoDnsResolver() { ActiveDnsQuery* GetAddrInfoDnsResolver::resolve(const std::string& dns_name, DnsLookupFamily dns_lookup_family, ResolveCb callback) { - ENVOY_LOG(debug, "adding new query [{}] to pending queries", dns_name); - auto new_query = std::make_unique(dns_name, dns_lookup_family, callback); + ENVOY_LOG(trace, "adding new query [{}] to pending queries", dns_name); + auto new_query = std::make_unique(dns_name, dns_lookup_family, std::move(callback)); new_query->addTrace(static_cast(GetAddrInfoTrace::NotStarted)); ActiveDnsQuery* active_query; { @@ -109,7 +109,7 @@ GetAddrInfoDnsResolver::processResponse(const PendingQuery& query, break; } - ENVOY_LOG(debug, "getaddrinfo resolution complete for host '{}': {}", query.dns_name_, + ENVOY_LOG(trace, "getaddrinfo resolution complete for host '{}': {}", query.dns_name_, accumulateToString(final_results, [](const auto& dns_response) { return dns_response.addrInfo().address_->asString(); })); @@ -119,7 +119,7 @@ GetAddrInfoDnsResolver::processResponse(const PendingQuery& query, // Background thread which wakes up and does resolutions. void GetAddrInfoDnsResolver::resolveThreadRoutine() { - ENVOY_LOG(debug, "starting getaddrinfo resolver thread"); + ENVOY_LOG(trace, "starting getaddrinfo resolver thread"); while (true) { std::unique_ptr next_query; @@ -143,7 +143,7 @@ void GetAddrInfoDnsResolver::resolveThreadRoutine() { } } - ENVOY_LOG(debug, "popped pending query [{}]", next_query->dns_name_); + ENVOY_LOG(trace, "popped pending query [{}]", next_query->dns_name_); // For mock testing make sure the getaddrinfo() response is freed prior to the post. std::pair> response; @@ -170,7 +170,7 @@ void GetAddrInfoDnsResolver::resolveThreadRoutine() { (*num_retries)--; } if (!num_retries.has_value()) { - ENVOY_LOG(debug, "retrying query [{}]", next_query->dns_name_); + ENVOY_LOG(trace, "retrying query [{}]", next_query->dns_name_); next_query->addTrace(static_cast(GetAddrInfoTrace::Retrying)); { absl::MutexLock guard(&mutex_); @@ -179,7 +179,7 @@ void GetAddrInfoDnsResolver::resolveThreadRoutine() { continue; } if (*num_retries > 0) { - ENVOY_LOG(debug, "retrying query [{}], num_retries: {}", next_query->dns_name_, + ENVOY_LOG(trace, "retrying query [{}], num_retries: {}", next_query->dns_name_, *num_retries); next_query->addTrace(static_cast(GetAddrInfoTrace::Retrying)); { @@ -215,7 +215,7 @@ void GetAddrInfoDnsResolver::resolveThreadRoutine() { details = std::string(details)]() mutable { if (finished_query->isCancelled()) { finished_query->addTrace(static_cast(GetAddrInfoTrace::Cancelled)); - ENVOY_LOG(debug, "dropping cancelled query [{}]", finished_query->dns_name_); + ENVOY_LOG(trace, "dropping cancelled query [{}]", finished_query->dns_name_); } else { finished_query->addTrace(static_cast(GetAddrInfoTrace::Callback)); finished_query->callback_(response.first, std::move(details), std::move(response.second)); @@ -223,7 +223,7 @@ void GetAddrInfoDnsResolver::resolveThreadRoutine() { }); } - ENVOY_LOG(debug, "getaddrinfo resolver thread exiting"); + ENVOY_LOG(trace, "getaddrinfo resolver thread exiting"); } // Register the CaresDnsResolverFactory diff --git a/source/extensions/network/dns_resolver/getaddrinfo/getaddrinfo.h b/source/extensions/network/dns_resolver/getaddrinfo/getaddrinfo.h index 2357fdb4ac..17c7818116 100644 --- a/source/extensions/network/dns_resolver/getaddrinfo/getaddrinfo.h +++ b/source/extensions/network/dns_resolver/getaddrinfo/getaddrinfo.h @@ -51,7 +51,7 @@ class GetAddrInfoDnsResolver : public DnsResolver, public Logger::Loggable Date: Wed, 25 Jun 2025 16:37:57 +0100 Subject: [PATCH 18/35] docker/release: Bump Ubuntu -> 01a3ee0 (#40026) Fix https://ubuntu.com/security/CVE-2025-4802 Signed-off-by: Ryan Northey --- ci/Dockerfile-envoy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/Dockerfile-envoy b/ci/Dockerfile-envoy index f6c7aa3621..b98e6b3703 100644 --- a/ci/Dockerfile-envoy +++ b/ci/Dockerfile-envoy @@ -1,6 +1,6 @@ ARG BUILD_OS=ubuntu ARG BUILD_TAG=22.04 -ARG BUILD_SHA=67cadaff1dca187079fce41360d5a7eb6f7dcd3745e53c79ad5efd8563118240 +ARG BUILD_SHA=01a3ee0b5e413cefaaffc6abe68c9c37879ae3cced56a8e088b1649e5b269eee ARG ENVOY_VRP_BASE_IMAGE=envoy-base From c050fd6b0d8b43fdab295da33f1c76459d09192d Mon Sep 17 00:00:00 2001 From: phlax Date: Tue, 8 Jul 2025 17:57:52 +0100 Subject: [PATCH 19/35] docker/release: Bump Ubuntu -> 3c61d37 (#40130) Signed-off-by: Ryan Northey Signed-off-by: Rohit Agrawal --- ci/Dockerfile-envoy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/Dockerfile-envoy b/ci/Dockerfile-envoy index b98e6b3703..df751ccf30 100644 --- a/ci/Dockerfile-envoy +++ b/ci/Dockerfile-envoy @@ -1,6 +1,6 @@ ARG BUILD_OS=ubuntu ARG BUILD_TAG=22.04 -ARG BUILD_SHA=01a3ee0b5e413cefaaffc6abe68c9c37879ae3cced56a8e088b1649e5b269eee +ARG BUILD_SHA=3c61d3759c2639d4b836d32a2d3c83fa0214e36f195a3421018dbaaf79cbe37f ARG ENVOY_VRP_BASE_IMAGE=envoy-base From 174fb5db5205a4d102da1cf6d4cf51b7050acf06 Mon Sep 17 00:00:00 2001 From: Ryan Northey Date: Wed, 9 Jul 2025 10:10:12 +0100 Subject: [PATCH 20/35] changelogs: Add note for container vulnerabilities/updates Signed-off-by: Ryan Northey --- changelogs/current.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/changelogs/current.yaml b/changelogs/current.yaml index abcb7d97b4..05a57935ff 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -25,6 +25,9 @@ bug_fixes: change: | Fixed an bug where the config validation server will crash when the configuration contains ``%CEL%`` or ``%METADATA%`` substitution formatter. +- area: release + change: | + Container (Ubuntu) updates to resolve glibc vulnerabilities. removed_config_or_runtime: # *Normally occurs at the end of the* :ref:`deprecation period ` From 5f980671cc4a82a0cbbab504b884c7435beb909a Mon Sep 17 00:00:00 2001 From: phlax Date: Wed, 9 Jul 2025 12:53:01 +0100 Subject: [PATCH 21/35] changelogs: Add summary (#40152) Signed-off-by: Ryan Northey --- changelogs/summary.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelogs/summary.md b/changelogs/summary.md index e69de29bb2..ad07fcb08f 100644 --- a/changelogs/summary.md +++ b/changelogs/summary.md @@ -0,0 +1,4 @@ +**Summary of changes:** + +- Container update to resolve glibc vulnerabilities +- Minor fixes From d608ffbd9fb4ab5c5d16903335accc1480af82c6 Mon Sep 17 00:00:00 2001 From: phlax Date: Wed, 9 Jul 2025 15:27:47 +0100 Subject: [PATCH 22/35] examples: Disable flakey dynamic-config-cp (#40159) Signed-off-by: Ryan Northey --- bazel/examples.patch | 13 +++++++++++++ bazel/repositories.bzl | 6 +++++- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 bazel/examples.patch diff --git a/bazel/examples.patch b/bazel/examples.patch new file mode 100644 index 0000000000..a3120f790f --- /dev/null +++ b/bazel/examples.patch @@ -0,0 +1,13 @@ +diff --git a/BUILD b/BUILD +index d271833..8386adc 100644 +--- a/BUILD ++++ b/BUILD +@@ -10,7 +10,7 @@ EXAMPLE_TESTS = [ + "cors", + "csrf", + "double-proxy", +- "dynamic-config-cp", ++ # "dynamic-config-cp", + "dynamic-config-fs", + "ext_authz", + # "fault-injection", diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index 32208e3e43..3eca321f71 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -215,7 +215,11 @@ def envoy_dependencies(skip_targets = []): external_http_archive("bazel_features") external_http_archive("bazel_toolchains") external_http_archive("bazel_compdb") - external_http_archive("envoy_examples") + external_http_archive( + name = "envoy_examples", + patch_args = ["-p1"], + patches = ["@envoy//bazel:examples.patch"], + ) _com_github_maxmind_libmaxminddb() From 83ac62a5a9d4abd4762fc33d105aa1273202f3d4 Mon Sep 17 00:00:00 2001 From: Ryan Hamilton Date: Mon, 23 Jun 2025 06:59:51 -0700 Subject: [PATCH 23/35] http3: Change Envoy's HTTP/3 implementation to validate pseudo headers (#39615) Can be disabled by setting ``envoy.restart_features.do_not_validate_http3_pseudo_headers`` to false. --------- Signed-off-by: Ryan Hamilton --- changelogs/current.yaml | 4 ++ .../common/quic/envoy_quic_server_stream.cc | 4 ++ source/common/quic/envoy_quic_stream.h | 25 ++++++++ source/common/quic/envoy_quic_utils.h | 12 ++++ source/common/runtime/runtime_features.cc | 1 + test/common/quic/envoy_quic_utils_test.cc | 57 ++++++++++++++----- .../integration/quic_http_integration_test.cc | 21 ++++++- 7 files changed, 108 insertions(+), 16 deletions(-) diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 05a57935ff..6c96d2ed8d 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -29,6 +29,10 @@ bug_fixes: change: | Container (Ubuntu) updates to resolve glibc vulnerabilities. +- area: http3 + change: | + Validate HTTP/3 pseudo headers. Can be disabled by setting ``envoy.restart_features.validate_http3_pseudo_headers`` to false. + removed_config_or_runtime: # *Normally occurs at the end of the* :ref:`deprecation period ` diff --git a/source/common/quic/envoy_quic_server_stream.cc b/source/common/quic/envoy_quic_server_stream.cc index f4f8f9b161..4cbf43a12c 100644 --- a/source/common/quic/envoy_quic_server_stream.cc +++ b/source/common/quic/envoy_quic_server_stream.cc @@ -44,6 +44,10 @@ EnvoyQuicServerStream::EnvoyQuicServerStream( stats_gatherer_ = new QuicStatsGatherer(&filterManagerConnection()->dispatcher().timeSource()); set_ack_listener(stats_gatherer_); RegisterMetadataVisitor(this); + if (Runtime::runtimeFeatureEnabled("envoy.restart_features.validate_http3_pseudo_headers") && + session->allow_extended_connect()) { + header_validator().SetAllowExtendedConnect(); + } } void EnvoyQuicServerStream::encode1xxHeaders(const Http::ResponseHeaderMap& headers) { diff --git a/source/common/quic/envoy_quic_stream.h b/source/common/quic/envoy_quic_stream.h index 34deca6a28..6b54da2c8f 100644 --- a/source/common/quic/envoy_quic_stream.h +++ b/source/common/quic/envoy_quic_stream.h @@ -143,6 +143,29 @@ class EnvoyQuicStream : public virtual Http::StreamEncoder, return Http::HeaderUtility::HeaderValidationResult::ACCEPT; } + void startHeaderBlock() override { + if (!Runtime::runtimeFeatureEnabled("envoy.restart_features.validate_http3_pseudo_headers")) { + return; + } + header_validator_.StartHeaderBlock(); + } + + bool finishHeaderBlock(bool is_trailing_headers) override { + if (!Runtime::runtimeFeatureEnabled("envoy.restart_features.validate_http3_pseudo_headers")) { + return true; + } + if (is_trailing_headers) { + return header_validator_.FinishHeaderBlock(quic_session_.perspective() == + quic::Perspective::IS_CLIENT + ? http2::adapter::HeaderType::RESPONSE_TRAILER + : http2::adapter::HeaderType::REQUEST_TRAILER); + } + return header_validator_.FinishHeaderBlock(quic_session_.perspective() == + quic::Perspective::IS_CLIENT + ? http2::adapter::HeaderType::RESPONSE + : http2::adapter::HeaderType::REQUEST); + } + absl::string_view responseDetails() override { return details_; } const StreamInfo::BytesMeterSharedPtr& bytesMeter() override { return bytes_meter_; } @@ -191,6 +214,8 @@ class EnvoyQuicStream : public virtual Http::StreamEncoder, return received_metadata_bytes_ > 1 << 20; } + http2::adapter::HeaderValidator& header_validator() { return header_validator_; } + #ifdef ENVOY_ENABLE_HTTP_DATAGRAMS // Setting |http_datagram_handler_| enables HTTP Datagram support. std::unique_ptr http_datagram_handler_; diff --git a/source/common/quic/envoy_quic_utils.h b/source/common/quic/envoy_quic_utils.h index 7ded20c854..9431d89143 100644 --- a/source/common/quic/envoy_quic_utils.h +++ b/source/common/quic/envoy_quic_utils.h @@ -57,8 +57,12 @@ quic::QuicSocketAddress envoyIpAddressToQuicSocketAddress(const Network::Address class HeaderValidator { public: virtual ~HeaderValidator() = default; + virtual void startHeaderBlock() = 0; virtual Http::HeaderUtility::HeaderValidationResult validateHeader(absl::string_view name, absl::string_view header_value) = 0; + // Returns true if all required pseudo-headers and no extra pseudo-headers are + // present for the given header type. + virtual bool finishHeaderBlock(bool is_trailing_headers) = 0; }; // The returned header map has all keys in lower case. @@ -67,6 +71,7 @@ std::unique_ptr quicHeadersToEnvoyHeaders(const quic::QuicHeaderList& header_list, HeaderValidator& validator, uint32_t max_headers_kb, uint32_t max_headers_allowed, absl::string_view& details, quic::QuicRstStreamErrorCode& rst) { + validator.startHeaderBlock(); auto headers = T::create(max_headers_kb, max_headers_allowed); for (const auto& entry : header_list) { if (max_headers_allowed == 0) { @@ -96,6 +101,9 @@ quicHeadersToEnvoyHeaders(const quic::QuicHeaderList& header_list, HeaderValidat } } } + if (!validator.finishHeaderBlock(/*is_trailing_headers=*/false)) { + return nullptr; + } return headers; } @@ -111,6 +119,7 @@ http2HeaderBlockToEnvoyTrailers(const quiche::HttpHeaderBlock& header_block, rst = quic::QUIC_STREAM_EXCESSIVE_LOAD; return nullptr; } + validator.startHeaderBlock(); for (auto entry : header_block) { // TODO(danzh): Avoid temporary strings and addCopy() with string_view. std::string key(entry.first); @@ -136,6 +145,9 @@ http2HeaderBlockToEnvoyTrailers(const quiche::HttpHeaderBlock& header_block, } } } + if (!validator.finishHeaderBlock(/*is_trailing_headers=*/true)) { + return nullptr; + } return headers; } diff --git a/source/common/runtime/runtime_features.cc b/source/common/runtime/runtime_features.cc index 6f15486b80..b1394bf069 100644 --- a/source/common/runtime/runtime_features.cc +++ b/source/common/runtime/runtime_features.cc @@ -115,6 +115,7 @@ RUNTIME_GUARD(envoy_reloadable_features_xds_prevent_resource_copy); RUNTIME_GUARD(envoy_restart_features_fix_dispatcher_approximate_now); RUNTIME_GUARD(envoy_restart_features_skip_backing_cluster_check_for_sds); RUNTIME_GUARD(envoy_restart_features_use_eds_cache_for_ads); +RUNTIME_GUARD(envoy_restart_features_validate_http3_pseudo_headers); // Begin false flags. Most of them should come with a TODO to flip true. diff --git a/test/common/quic/envoy_quic_utils_test.cc b/test/common/quic/envoy_quic_utils_test.cc index 7ebbc84657..299a2cbdcb 100644 --- a/test/common/quic/envoy_quic_utils_test.cc +++ b/test/common/quic/envoy_quic_utils_test.cc @@ -40,6 +40,8 @@ TEST(EnvoyQuicUtilsTest, ConversionBetweenQuicAddressAndEnvoyAddress) { class MockServerHeaderValidator : public HeaderValidator { public: ~MockServerHeaderValidator() override = default; + MOCK_METHOD(void, startHeaderBlock, ()); + MOCK_METHOD(bool, finishHeaderBlock, (bool is_trailing_headers)); MOCK_METHOD(Http::HeaderUtility::HeaderValidationResult, validateHeader, (absl::string_view header_name, absl::string_view header_value)); }; @@ -59,6 +61,8 @@ TEST(EnvoyQuicUtilsTest, HeadersConversion) { NiceMock validator; absl::string_view details; quic::QuicRstStreamErrorCode rst = quic::QUIC_REFUSED_STREAM; + EXPECT_CALL(validator, startHeaderBlock()); + EXPECT_CALL(validator, finishHeaderBlock(true)).WillOnce(Return(true)); auto envoy_headers = http2HeaderBlockToEnvoyTrailers( headers_block, 60, 100, validator, details, rst); // Envoy header block is 3 headers larger because QUICHE header block does coalescing. @@ -87,6 +91,7 @@ TEST(EnvoyQuicUtilsTest, HeadersConversion) { quic_headers.OnHeader("key1", "value2"); quic_headers.OnHeader("key-to-drop", ""); quic_headers.OnHeaderBlockEnd(0, 0); + EXPECT_CALL(validator, startHeaderBlock()); EXPECT_CALL(validator, validateHeader(_, _)) .WillRepeatedly([](absl::string_view header_name, absl::string_view) { if (header_name == "key-to-drop") { @@ -94,6 +99,7 @@ TEST(EnvoyQuicUtilsTest, HeadersConversion) { } return Http::HeaderUtility::HeaderValidationResult::ACCEPT; }); + EXPECT_CALL(validator, finishHeaderBlock(false)).WillOnce(Return(true)); auto envoy_headers2 = quicHeadersToEnvoyHeaders( quic_headers, validator, 60, 100, details, rst); EXPECT_EQ(*envoy_headers, *envoy_headers2); @@ -105,6 +111,7 @@ TEST(EnvoyQuicUtilsTest, HeadersConversion) { quic_headers2.OnHeader(":scheme", "https"); quic_headers2.OnHeader("invalid_key", ""); quic_headers2.OnHeaderBlockEnd(0, 0); + EXPECT_CALL(validator, startHeaderBlock()); EXPECT_CALL(validator, validateHeader(_, _)) .WillRepeatedly([](absl::string_view header_name, absl::string_view) { if (header_name == "invalid_key") { @@ -118,23 +125,29 @@ TEST(EnvoyQuicUtilsTest, HeadersConversion) { } TEST(EnvoyQuicUtilsTest, HeadersSizeBounds) { - quiche::HttpHeaderBlock headers_block; - headers_block[":authority"] = "www.google.com"; - headers_block[":path"] = "/index.hml"; - headers_block[":scheme"] = "https"; - headers_block["foo"] = std::string("bar\0eep\0baz", 11); + quic::QuicHeaderList quic_headers; + quic_headers.OnHeader(":authority", "www.google.com"); + quic_headers.OnHeader(":path", "/index.hml"); + quic_headers.OnHeader(":scheme", "https"); + quic_headers.OnHeader("foo1", "bar"); + quic_headers.OnHeader("foo2", "bar"); + quic_headers.OnHeader("foo3", "bar"); + quic_headers.OnHeaderBlockEnd(0, 0); absl::string_view details; - // 6 headers are allowed. NiceMock validator; quic::QuicRstStreamErrorCode rst = quic::QUIC_REFUSED_STREAM; - EXPECT_NE(nullptr, http2HeaderBlockToEnvoyTrailers( - headers_block, 60, 6, validator, details, rst)); + EXPECT_CALL(validator, finishHeaderBlock(false)).WillOnce(Return(true)); + // 6 headers are allowed. + EXPECT_NE(nullptr, quicHeadersToEnvoyHeaders(quic_headers, validator, + 60, 6, details, rst)); // Given the cap is 6, make sure anything lower, exact or otherwise, is rejected. - EXPECT_EQ(nullptr, http2HeaderBlockToEnvoyTrailers( - headers_block, 60, 5, validator, details, rst)); - EXPECT_EQ("http3.too_many_trailers", details); - EXPECT_EQ(nullptr, http2HeaderBlockToEnvoyTrailers( - headers_block, 60, 4, validator, details, rst)); + EXPECT_EQ(nullptr, quicHeadersToEnvoyHeaders(quic_headers, validator, + 60, 5, details, rst)); + EXPECT_EQ("http3.too_many_headers", details); + EXPECT_EQ(rst, quic::QUIC_STREAM_EXCESSIVE_LOAD); + EXPECT_EQ(nullptr, quicHeadersToEnvoyHeaders(quic_headers, validator, + 60, 4, details, rst)); + EXPECT_EQ("http3.too_many_headers", details); EXPECT_EQ(rst, quic::QUIC_STREAM_EXCESSIVE_LOAD); } @@ -147,13 +160,18 @@ TEST(EnvoyQuicUtilsTest, TrailersSizeBounds) { absl::string_view details; NiceMock validator; quic::QuicRstStreamErrorCode rst = quic::QUIC_REFUSED_STREAM; + EXPECT_CALL(validator, finishHeaderBlock(true)).WillOnce(Return(true)); + // 6 headers are allowed. EXPECT_NE(nullptr, http2HeaderBlockToEnvoyTrailers( headers_block, 60, 6, validator, details, rst)); + // Given the cap is 6, make sure anything lower, exact or otherwise, is rejected. EXPECT_EQ(nullptr, http2HeaderBlockToEnvoyTrailers( - headers_block, 60, 2, validator, details, rst)); + headers_block, 60, 5, validator, details, rst)); EXPECT_EQ("http3.too_many_trailers", details); + EXPECT_EQ(rst, quic::QUIC_STREAM_EXCESSIVE_LOAD); EXPECT_EQ(nullptr, http2HeaderBlockToEnvoyTrailers( - headers_block, 60, 2, validator, details, rst)); + headers_block, 60, 4, validator, details, rst)); + EXPECT_EQ("http3.too_many_trailers", details); EXPECT_EQ(rst, quic::QUIC_STREAM_EXCESSIVE_LOAD); } @@ -164,6 +182,7 @@ TEST(EnvoyQuicUtilsTest, TrailerCharacters) { headers_block[":scheme"] = "https"; absl::string_view details; NiceMock validator; + EXPECT_CALL(validator, startHeaderBlock()); EXPECT_CALL(validator, validateHeader(_, _)) .WillRepeatedly(Return(Http::HeaderUtility::HeaderValidationResult::REJECT)); quic::QuicRstStreamErrorCode rst = quic::QUIC_REFUSED_STREAM; @@ -228,10 +247,12 @@ TEST(EnvoyQuicUtilsTest, HeaderMapMaxSizeLimit) { quic_headers.OnHeader(":path", "/index.hml"); quic_headers.OnHeader(":scheme", "https"); quic_headers.OnHeaderBlockEnd(0, 0); + EXPECT_CALL(validator, startHeaderBlock()); EXPECT_CALL(validator, validateHeader(_, _)) .WillRepeatedly([](absl::string_view, absl::string_view) { return Http::HeaderUtility::HeaderValidationResult::ACCEPT; }); + EXPECT_CALL(validator, finishHeaderBlock(false)).WillOnce(Return(true)); // Request header map test. auto request_header = quicHeadersToEnvoyHeaders( quic_headers, validator, 60, 100, details, rst); @@ -239,6 +260,8 @@ TEST(EnvoyQuicUtilsTest, HeaderMapMaxSizeLimit) { EXPECT_EQ(request_header->maxHeadersKb(), 60); // Response header map test. + EXPECT_CALL(validator, startHeaderBlock()); + EXPECT_CALL(validator, finishHeaderBlock(false)).WillOnce(Return(true)); auto response_header = quicHeadersToEnvoyHeaders( quic_headers, validator, 60, 100, details, rst); EXPECT_EQ(response_header->maxHeadersCount(), 100); @@ -250,12 +273,16 @@ TEST(EnvoyQuicUtilsTest, HeaderMapMaxSizeLimit) { headers_block[":scheme"] = "https"; // Request trailer map test. + EXPECT_CALL(validator, startHeaderBlock()); + EXPECT_CALL(validator, finishHeaderBlock(true)).WillOnce(Return(true)); auto request_trailer = http2HeaderBlockToEnvoyTrailers( headers_block, 60, 100, validator, details, rst); EXPECT_EQ(request_trailer->maxHeadersCount(), 100); EXPECT_EQ(request_trailer->maxHeadersKb(), 60); // Response trailer map test. + EXPECT_CALL(validator, startHeaderBlock()); + EXPECT_CALL(validator, finishHeaderBlock(true)).WillOnce(Return(true)); auto response_trailer = http2HeaderBlockToEnvoyTrailers( headers_block, 60, 100, validator, details, rst); EXPECT_EQ(response_trailer->maxHeadersCount(), 100); diff --git a/test/integration/quic_http_integration_test.cc b/test/integration/quic_http_integration_test.cc index d0f6a7ec6c..12b63d3510 100644 --- a/test/integration/quic_http_integration_test.cc +++ b/test/integration/quic_http_integration_test.cc @@ -560,6 +560,24 @@ TEST_P(QuicHttpIntegrationTest, ResetRequestWithoutAuthorityHeader) { codec_client_->close(); } +// Test to ensure code coverage of the flag codepath. +TEST_P(QuicHttpIntegrationTest, DoNotValidatePseudoHeaders) { + config_helper_.addRuntimeOverride("envoy.restart_features.validate_http3_pseudo_headers", + "false"); + + initialize(); + + codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http"))); + auto response = codec_client_->makeHeaderOnlyRequest(default_request_headers_); + + waitForNextUpstreamRequest(); + upstream_request_->encodeHeaders(default_response_headers_, true); + + EXPECT_TRUE(response->waitForEndStream()); + ASSERT_TRUE(response->complete()); + codec_client_->close(); +} + TEST_P(QuicHttpIntegrationTest, ResetRequestWithInvalidCharacter) { config_helper_.addRuntimeOverride("envoy.reloadable_features.validate_upstream_headers", "false"); @@ -1017,7 +1035,8 @@ TEST_P(QuicHttpIntegrationTest, DeferredLoggingWithQuicReset) { EXPECT_EQ(/* request headers */ metrics.at(19), metrics.at(20)); } -TEST_P(QuicHttpIntegrationTest, DeferredLoggingWithEnvoyReset) { +// TODO(RyanTheOptimist): Re-enable after figuring out how to cause this reset. +TEST_P(QuicHttpIntegrationTest, DISABLED_DeferredLoggingWithEnvoyReset) { config_helper_.addRuntimeOverride( "envoy.reloadable_features.FLAGS_envoy_quiche_reloadable_flag_quic_act_upon_invalid_header", "false"); From c657e59fac461e406c8fdbe57ced833ddc236ee1 Mon Sep 17 00:00:00 2001 From: "publish-envoy[bot]" <140627008+publish-envoy[bot]@users.noreply.github.com> Date: Wed, 9 Jul 2025 20:31:10 +0000 Subject: [PATCH 24/35] repo: Release v1.34.2 **Summary of changes:** - Container update to resolve glibc vulnerabilities - Minor fixes **Docker images**: https://hub.docker.com/r/envoyproxy/envoy/tags?page=1&name=v1.34.2 **Docs**: https://www.envoyproxy.io/docs/envoy/v1.34.2/ **Release notes**: https://www.envoyproxy.io/docs/envoy/v1.34.2/version_history/v1.34/v1.34.2 **Full changelog**: https://github.com/envoyproxy/envoy/compare/v1.34.1...v1.34.2 --- VERSION.txt | 2 +- changelogs/1.31.9.yaml | 12 ++++++++++++ changelogs/1.32.7.yaml | 12 ++++++++++++ changelogs/1.33.4.yaml | 22 ++++++++++++++++++++++ changelogs/current.yaml | 17 +---------------- docs/inventories/v1.31/objects.inv | Bin 176110 -> 176135 bytes docs/inventories/v1.32/objects.inv | Bin 178947 -> 178987 bytes docs/inventories/v1.33/objects.inv | Bin 181472 -> 181556 bytes docs/inventories/v1.34/objects.inv | Bin 186365 -> 186455 bytes docs/versions.yaml | 8 ++++---- 10 files changed, 52 insertions(+), 21 deletions(-) create mode 100644 changelogs/1.31.9.yaml create mode 100644 changelogs/1.32.7.yaml create mode 100644 changelogs/1.33.4.yaml diff --git a/VERSION.txt b/VERSION.txt index 785c88e718..00e952d041 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -1.34.2-dev +1.34.2 diff --git a/changelogs/1.31.9.yaml b/changelogs/1.31.9.yaml new file mode 100644 index 0000000000..a22b29dc19 --- /dev/null +++ b/changelogs/1.31.9.yaml @@ -0,0 +1,12 @@ +date: July 9, 2025 + +bug_fixes: +- area: release + change: | + Container (Ubuntu) updates to resolve glibc vulnerabilities. +- area: eds + change: | + Fixed crash when creating an EDS cluster with invalid configuration. +- area: http3 + change: | + Validate HTTP/3 pseudo headers. Can be disabled by setting ``envoy.restart_features.validate_http3_pseudo_headers`` to false. diff --git a/changelogs/1.32.7.yaml b/changelogs/1.32.7.yaml new file mode 100644 index 0000000000..a22b29dc19 --- /dev/null +++ b/changelogs/1.32.7.yaml @@ -0,0 +1,12 @@ +date: July 9, 2025 + +bug_fixes: +- area: release + change: | + Container (Ubuntu) updates to resolve glibc vulnerabilities. +- area: eds + change: | + Fixed crash when creating an EDS cluster with invalid configuration. +- area: http3 + change: | + Validate HTTP/3 pseudo headers. Can be disabled by setting ``envoy.restart_features.validate_http3_pseudo_headers`` to false. diff --git a/changelogs/1.33.4.yaml b/changelogs/1.33.4.yaml new file mode 100644 index 0000000000..4b26caaf66 --- /dev/null +++ b/changelogs/1.33.4.yaml @@ -0,0 +1,22 @@ +date: July 9, 2025 + +bug_fixes: +- area: conn_pool + change: | + Fixed an issue that could lead to too many connections when using + :ref:`AutoHttpConfig ` if the + established connection is ``http/2`` and Envoy predicted it would have lower concurrent capacity. +- area: conn_pool + change: | + Fixed an issue that could lead to insufficient connections for current pending requests. If a connection starts draining while it + has negative unused capacity (which happens if an HTTP/2 ``SETTINGS`` frame reduces allowed concurrency to below the current number + of requests), that connection's unused capacity will be included in total pool capacity even though it is unusable because it is + draining. This can result in not enough connections being established for current pending requests. This is most problematic for + long-lived requests (such as streaming gRPC requests or long-poll requests) because a connection could be in the draining state + for a long time. +- area: release + change: | + Container (Ubuntu) updates to resolve glibc vulnerabilities. +- area: http3 + change: | + Validate HTTP/3 pseudo headers. Can be disabled by setting ``envoy.restart_features.validate_http3_pseudo_headers`` to false. diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 6c96d2ed8d..ba448745c0 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -1,13 +1,6 @@ -date: Pending - -behavior_changes: -# *Changes that are expected to cause an incompatibility if applicable; deployment changes are likely required* - -minor_behavior_changes: -# *Changes that may cause incompatibilities for some users, but should not for most* +date: July 9, 2025 bug_fixes: -# *Changes expected to improve the state of the world and are unlikely to have negative effects* - area: conn_pool change: | Fixed an issue that could lead to too many connections when using @@ -28,14 +21,6 @@ bug_fixes: - area: release change: | Container (Ubuntu) updates to resolve glibc vulnerabilities. - - area: http3 change: | Validate HTTP/3 pseudo headers. Can be disabled by setting ``envoy.restart_features.validate_http3_pseudo_headers`` to false. - -removed_config_or_runtime: -# *Normally occurs at the end of the* :ref:`deprecation period ` - -new_features: - -deprecated: diff --git a/docs/inventories/v1.31/objects.inv b/docs/inventories/v1.31/objects.inv index 6d14e4127cbc1e6587d77b480f65dfa32e616967..b65d7aa97c45d8a030b3359c9c46c72142cdabd0 100644 GIT binary patch delta 4288 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 LUous$f3E%ykJAQ| delta 4263 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 S&@*h)Z;vy-Z|PZCnEfv_Q1B`M diff --git a/docs/inventories/v1.32/objects.inv b/docs/inventories/v1.32/objects.inv index 64c2f9afb2f490cbd0006bd6274e292e2ceef654..57c54bd292cc335df9e806b920053325721bff12 100644 GIT binary patch delta 4620 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 delta 4579 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 X_Xp~(nRTFr4|1!n|1`HHvK9Xa%95t# diff --git a/docs/inventories/v1.33/objects.inv b/docs/inventories/v1.33/objects.inv index 9c5ebdcd8e1f0c320be0078750db942f418abe36..f5ec3fff47eaa4774a2659f4b3bc15939ea9138f 100644 GIT binary patch delta 6884 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 HOp^FNuP7%Y delta 6820 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 diff --git a/docs/inventories/v1.34/objects.inv b/docs/inventories/v1.34/objects.inv index 480861173a2f4ea5fa78a3c2bf18b12a95e71664..5cf9bc3b37f6c6e51c9ce5e3e0d99ff8d57ce5a2 100644 GIT binary patch delta 3221 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 delta 3131 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 Date: Thu, 10 Jul 2025 07:24:28 +0000 Subject: [PATCH 25/35] repo: Dev v1.34.3 Signed-off-by: Ryan Northey --- VERSION.txt | 2 +- changelogs/1.34.2.yaml | 26 ++++++++++++++++++++++++++ changelogs/current.yaml | 39 +++++++++++++++------------------------ changelogs/summary.md | 4 ---- 4 files changed, 42 insertions(+), 29 deletions(-) create mode 100644 changelogs/1.34.2.yaml diff --git a/VERSION.txt b/VERSION.txt index 00e952d041..1c944b1fef 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -1.34.2 +1.34.3-dev diff --git a/changelogs/1.34.2.yaml b/changelogs/1.34.2.yaml new file mode 100644 index 0000000000..ba448745c0 --- /dev/null +++ b/changelogs/1.34.2.yaml @@ -0,0 +1,26 @@ +date: July 9, 2025 + +bug_fixes: +- area: conn_pool + change: | + Fixed an issue that could lead to too many connections when using + :ref:`AutoHttpConfig ` if the + established connection is ``http/2`` and Envoy predicted it would have lower concurrent capacity. +- area: conn_pool + change: | + Fixed an issue that could lead to insufficient connections for current pending requests. If a connection starts draining while it + has negative unused capacity (which happens if an HTTP/2 ``SETTINGS`` frame reduces allowed concurrency to below the current number + of requests), that connection's unused capacity will be included in total pool capacity even though it is unusable because it is + draining. This can result in not enough connections being established for current pending requests. This is most problematic for + long-lived requests (such as streaming gRPC requests or long-poll requests) because a connection could be in the draining state + for a long time. +- area: config_validation + change: | + Fixed an bug where the config validation server will crash when the configuration contains + ``%CEL%`` or ``%METADATA%`` substitution formatter. +- area: release + change: | + Container (Ubuntu) updates to resolve glibc vulnerabilities. +- area: http3 + change: | + Validate HTTP/3 pseudo headers. Can be disabled by setting ``envoy.restart_features.validate_http3_pseudo_headers`` to false. diff --git a/changelogs/current.yaml b/changelogs/current.yaml index ba448745c0..9ecf0d6e48 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -1,26 +1,17 @@ -date: July 9, 2025 +date: Pending + +behavior_changes: +# *Changes that are expected to cause an incompatibility if applicable; deployment changes are likely required* + +minor_behavior_changes: +# *Changes that may cause incompatibilities for some users, but should not for most* bug_fixes: -- area: conn_pool - change: | - Fixed an issue that could lead to too many connections when using - :ref:`AutoHttpConfig ` if the - established connection is ``http/2`` and Envoy predicted it would have lower concurrent capacity. -- area: conn_pool - change: | - Fixed an issue that could lead to insufficient connections for current pending requests. If a connection starts draining while it - has negative unused capacity (which happens if an HTTP/2 ``SETTINGS`` frame reduces allowed concurrency to below the current number - of requests), that connection's unused capacity will be included in total pool capacity even though it is unusable because it is - draining. This can result in not enough connections being established for current pending requests. This is most problematic for - long-lived requests (such as streaming gRPC requests or long-poll requests) because a connection could be in the draining state - for a long time. -- area: config_validation - change: | - Fixed an bug where the config validation server will crash when the configuration contains - ``%CEL%`` or ``%METADATA%`` substitution formatter. -- area: release - change: | - Container (Ubuntu) updates to resolve glibc vulnerabilities. -- area: http3 - change: | - Validate HTTP/3 pseudo headers. Can be disabled by setting ``envoy.restart_features.validate_http3_pseudo_headers`` to false. +# *Changes expected to improve the state of the world and are unlikely to have negative effects* + +removed_config_or_runtime: +# *Normally occurs at the end of the* :ref:`deprecation period ` + +new_features: + +deprecated: diff --git a/changelogs/summary.md b/changelogs/summary.md index ad07fcb08f..e69de29bb2 100644 --- a/changelogs/summary.md +++ b/changelogs/summary.md @@ -1,4 +0,0 @@ -**Summary of changes:** - -- Container update to resolve glibc vulnerabilities -- Minor fixes From 67317f51bca2a74ed4f329f1a821e2fcfa30e800 Mon Sep 17 00:00:00 2001 From: Greg Greenway Date: Thu, 10 Jul 2025 14:37:26 -0700 Subject: [PATCH 26/35] tls: fix incorrectly cached empty peer certificate values (#40179) If tls connection data was queried before it was available, and empty value was being incorrectly cached, preventing later calls from getting the correct value. One way this could be triggered was with an access log entry being emitted before the TLS peer certificate was received during the TLS handshake, which can be configured with tcp_proxy. Fixes #40137 Signed-off-by: Greg Greenway --- changelogs/current.yaml | 7 +++ .../common/tls/connection_info_impl_base.cc | 20 +++++++++ .../integration/tcp_proxy_integration_test.cc | 44 +++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 9ecf0d6e48..1756372a57 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -8,6 +8,13 @@ minor_behavior_changes: bug_fixes: # *Changes expected to improve the state of the world and are unlikely to have negative effects* +- area: tls + change: | + Fixed an issue with incorrectly cached connection properties on TLS connections. + If TLS connection data was queried before it was available, an empty value was being incorrectly cached, preventing later calls from + getting the correct value. This could be triggered with a ``tcp_proxy`` access log configured to emit a log upon connection + establishment if the log contains fields of the the TLS peer certificate. Then a later use of the data, such as the network RBAC + filter validating a peer certificate SAN, may incorrectly fail due to the empty cached value. removed_config_or_runtime: # *Normally occurs at the end of the* :ref:`deprecation period ` diff --git a/source/common/tls/connection_info_impl_base.cc b/source/common/tls/connection_info_impl_base.cc index e46a313e05..244f01b7fe 100644 --- a/source/common/tls/connection_info_impl_base.cc +++ b/source/common/tls/connection_info_impl_base.cc @@ -17,6 +17,16 @@ namespace Extensions { namespace TransportSockets { namespace Tls { +namespace { +// There must be an version of this function for each type possible in variant `CachedValue`. +bool shouldRecalculateCachedEntry(const std::string& str) { return str.empty(); } +bool shouldRecalculateCachedEntry(const std::vector& vec) { return vec.empty(); } +bool shouldRecalculateCachedEntry(const Ssl::ParsedX509NamePtr& ptr) { return ptr == nullptr; } +bool shouldRecalculateCachedEntry(const bssl::UniquePtr& ptr) { + return ptr == nullptr; +} +} // namespace + template const ValueType& ConnectionInfoImplBase::getCachedValueOrCreate(CachedValueTag tag, @@ -26,6 +36,16 @@ ConnectionInfoImplBase::getCachedValueOrCreate(CachedValueTag tag, const ValueType* val = absl::get_if(&it->second); ASSERT(val != nullptr, "Incorrect type in variant"); if (val != nullptr) { + + // Some values are retrieved too early, for example if properties of a peer certificate are + // retrieved before the handshake is complete, an empty value is cached. The value must be + // in the cache, so that we can return a valid reference, but in those cases if another caller + // later retrieves the same value, we must recalculate the value. + if (shouldRecalculateCachedEntry(*val)) { + it->second = create(ssl()); + val = &absl::get(it->second); + } + return *val; } } diff --git a/test/integration/tcp_proxy_integration_test.cc b/test/integration/tcp_proxy_integration_test.cc index 22e3edf615..a8cfd0790a 100644 --- a/test/integration/tcp_proxy_integration_test.cc +++ b/test/integration/tcp_proxy_integration_test.cc @@ -1521,6 +1521,50 @@ TEST_P(TcpProxySslIntegrationTest, LargeBidirectionalTlsWrites) { sendAndReceiveTlsData(large_data, large_data); } +// Test that if SSL connection data, such as peer certificate data, is read before it is +// available, it is not cached when it is read again later when available. +TEST_P(TcpProxySslIntegrationTest, SslConnectionDataEarlyReadNotCached) { + std::string access_log_path = TestEnvironment::temporaryPath( + fmt::format("access_log{}{}.txt", version_ == Network::Address::IpVersion::v4 ? "v4" : "v6", + TestUtility::uniqueFilename())); + config_helper_.addConfigModifier([&](envoy::config::bootstrap::v3::Bootstrap& bootstrap) -> void { + auto* listener = bootstrap.mutable_static_resources()->mutable_listeners(0); + auto* filter_chain = listener->mutable_filter_chains(0); + auto* config_blob = filter_chain->mutable_filters(0)->mutable_typed_config(); + + ASSERT_TRUE(config_blob->Is()); + auto tcp_proxy_config = + MessageUtil::anyConvert( + *config_blob); + + auto* access_log = tcp_proxy_config.add_access_log(); + access_log->set_name("accesslog"); + envoy::extensions::access_loggers::file::v3::FileAccessLog access_log_config; + access_log_config.set_path(access_log_path); + access_log_config.mutable_log_format()->mutable_text_format_source()->set_inline_string( + "san=%DOWNSTREAM_PEER_URI_SAN% fingerprint=%DOWNSTREAM_PEER_FINGERPRINT_256%\n"); + access_log->mutable_typed_config()->PackFrom(access_log_config); + tcp_proxy_config.mutable_access_log_options()->set_flush_access_log_on_connected(true); + config_blob->PackFrom(tcp_proxy_config); + }); + + setupConnections(); + std::string large_data(1024 * 8, 'a'); + sendAndReceiveTlsData(large_data, large_data); + + // The test set `flush_access_log_on_connected`, so the first access log is emitted before the + // handshake has completed. + auto log_result = waitForAccessLog(access_log_path, 0, true); + EXPECT_EQ(log_result, "san=- fingerprint=-"); + + // The second access log is when the connection closes, so the handshake is complete and + // a valid peer cert is now available. + log_result = waitForAccessLog(access_log_path, 1, false); + EXPECT_EQ(log_result, + "san=spiffe://lyft.com/frontend-team,http://frontend.lyft.com " + "fingerprint=7346b3836cfc41385351191b5e6163f1a69704cfdf0a03634ed2019128e6fdc4"); +} + // Test that a half-close on the downstream side is proxied correctly. TEST_P(TcpProxySslIntegrationTest, DownstreamHalfClose) { setupConnections(); From 1994e72b6ac337ee899e882b86c043ff0a890714 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Mon, 14 Jul 2025 13:15:33 +0200 Subject: [PATCH 27/35] [bp/1.34] dynatracesampler: avoid div by zero (#40220) (#40225) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit Message: Backport #40220 Additional Description: Risk Level: Low Testing: Unit tests Docs Changes: N/A Release Notes: N/A Platform Specific Features: N/A [Optional Runtime guard:] [Optional Fixes #37983] [Optional Fixes commit #PR or SHA] [Optional Deprecated:] [Optional [API Considerations](https://github.com/envoyproxy/envoy/blob/main/api/review_checklist.md):] Signed-off-by: Gerhard Stöbich <18708370+Flarna@users.noreply.github.com> Signed-off-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Co-authored-by: Gerhard Stöbich --- .../samplers/dynatrace/sampling_controller.cc | 5 +---- .../dynatrace/sampling_controller_test.cc | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/source/extensions/tracers/opentelemetry/samplers/dynatrace/sampling_controller.cc b/source/extensions/tracers/opentelemetry/samplers/dynatrace/sampling_controller.cc index e4a7643730..49fbddf0ba 100644 --- a/source/extensions/tracers/opentelemetry/samplers/dynatrace/sampling_controller.cc +++ b/source/extensions/tracers/opentelemetry/samplers/dynatrace/sampling_controller.cc @@ -123,12 +123,9 @@ void SamplingController::calculateSamplingExponents( return; } - // number of requests which are allowed for every entry - const uint32_t allowed_per_entry = total_wanted / top_k_size; - for (auto& counter : top_k) { // allowed multiplicity for this entry - auto wanted_multiplicity = counter.getValue() / allowed_per_entry; + auto wanted_multiplicity = counter.getValue() * top_k_size / total_wanted; auto sampling_state = new_sampling_exponents.find(counter.getItem()); // sampling exponent has to be a power of 2. Find the exponent to have multiplicity near to // wanted_multiplicity diff --git a/test/extensions/tracers/opentelemetry/samplers/dynatrace/sampling_controller_test.cc b/test/extensions/tracers/opentelemetry/samplers/dynatrace/sampling_controller_test.cc index 17da6ac7cb..f449af1226 100644 --- a/test/extensions/tracers/opentelemetry/samplers/dynatrace/sampling_controller_test.cc +++ b/test/extensions/tracers/opentelemetry/samplers/dynatrace/sampling_controller_test.cc @@ -89,6 +89,24 @@ TEST(SamplingControllerTest, TestWithOneAllowedSpan) { EXPECT_EQ(sc.getSamplingState("1").getMultiplicity(), 1); } +// Test with 1 root span per minute and more offered entries +TEST(SamplingControllerTest, TestWithOneAllowedSpanMoreEntries) { + auto scf = std::make_unique(1); + SamplingController sc(std::move(scf)); + sc.update(); + EXPECT_EQ(sc.getSamplingState("1").getExponent(), SamplingController::MAX_SAMPLING_EXPONENT); + offerEntry(sc, "1", 1); + offerEntry(sc, "2", 1); + offerEntry(sc, "3", 1); + EXPECT_EQ(sc.getSamplingState("1").getExponent(), SamplingController::MAX_SAMPLING_EXPONENT); + EXPECT_EQ(sc.getSamplingState("2").getExponent(), SamplingController::MAX_SAMPLING_EXPONENT); + EXPECT_EQ(sc.getSamplingState("3").getExponent(), SamplingController::MAX_SAMPLING_EXPONENT); + sc.update(); + EXPECT_EQ(sc.getSamplingState("1").getMultiplicity(), 2); + EXPECT_EQ(sc.getSamplingState("2").getMultiplicity(), 2); + EXPECT_EQ(sc.getSamplingState("3").getMultiplicity(), 1); +} + // Test with StreamSummary size not exceeded TEST(SamplingControllerTest, TestStreamSummarySizeNotExceeded) { auto scf = std::make_unique(); From 2e365892328be20c90677717fabb7b6248b79ecc Mon Sep 17 00:00:00 2001 From: phlax Date: Sat, 10 May 2025 17:29:29 +0100 Subject: [PATCH 28/35] build/docker: Fix permissions in distroless image (#39427) Fix #39421 Signed-off-by: Ryan Northey --- ci/Dockerfile-envoy | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ci/Dockerfile-envoy b/ci/Dockerfile-envoy index df751ccf30..7bac880f0a 100644 --- a/ci/Dockerfile-envoy +++ b/ci/Dockerfile-envoy @@ -63,6 +63,8 @@ FROM gcr.io/distroless/base-nossl-debian12:nonroot@sha256:d1fc914c43cea489c26c89 EXPOSE 10000 ENTRYPOINT ["/usr/local/bin/envoy"] CMD ["-c", "/etc/envoy/envoy.yaml"] +COPY --from=binary --chown=0:0 --chmod=755 \ + /etc/envoy /etc/envoy COPY --from=binary --chown=0:0 --chmod=644 \ /etc/envoy/envoy.yaml /etc/envoy/envoy.yaml COPY --from=binary --chown=0:0 --chmod=755 \ From d9a46c386d101a72b11f15906aef33118ca0a71c Mon Sep 17 00:00:00 2001 From: phlax Date: Tue, 15 Jul 2025 22:40:11 +0100 Subject: [PATCH 29/35] ci/docker: Pin buildkit and test distroless build (#40209) Fix https://github.com/envoyproxy/envoy/issues/40207 --------- Signed-off-by: Ryan Northey --- .github/workflows/_publish_verify.yml | 46 +++++++++++++++++++++++++++ ci/Dockerfile-buildkit | 3 ++ ci/Dockerfile-distroless-testing | 3 ++ ci/do_ci.sh | 6 +++- ci/docker_ci.sh | 5 +-- 5 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 ci/Dockerfile-buildkit create mode 100644 ci/Dockerfile-distroless-testing diff --git a/.github/workflows/_publish_verify.yml b/.github/workflows/_publish_verify.yml index 906375c952..e8b46bfb1f 100644 --- a/.github/workflows/_publish_verify.yml +++ b/.github/workflows/_publish_verify.yml @@ -83,6 +83,52 @@ jobs: - run: docker images | grep envoy shell: bash + distroless: + permissions: + contents: read + packages: read + name: ${{ matrix.name || matrix.target }} + uses: ./.github/workflows/_run.yml + with: + bazel-extra: ${{ matrix.bazel-extra || '--config=remote-envoy-engflow' }} + cache-build-image: ${{ matrix.cache-build-image }} + cache-build-image-key-suffix: ${{ matrix.arch == 'arm64' && format('-{0}', matrix.arch) || '' }} + container-command: ${{ matrix.container-command }} + concurrency-suffix: -${{ matrix.arch || 'x64' }} + downloads: ${{ matrix.downloads }} + rbe: ${{ matrix.rbe }} + request: ${{ inputs.request }} + steps-pre: ${{ matrix.steps-pre }} + source: ${{ matrix.source }} + target: ${{ matrix.target }} + trusted: ${{ inputs.trusted }} + strategy: + fail-fast: false + matrix: + include: + - name: distroless + target: verify-distroless + downloads: | + docker: build_images + rbe: false + source: | + export NO_BUILD_SETUP=1 + steps-pre: | + - run: | + IMAGES=( + envoy-distroless:distroless-dev) + for image in "${IMAGES[@]}"; do + src_name="$(echo ${image} | cut -d: -f1)" + dest_name="$(echo ${image} | cut -d: -f2)" + src="oci-archive:%{{ runner.temp }}/build_images/${src_name}.tar" + dest="docker-daemon:envoyproxy/envoy:${dest_name}" + echo "Copy image: ${src} ${dest}" + skopeo copy -q "${src}" "${dest}" + done + shell: bash + - run: docker images | grep envoy + shell: bash + distro: secrets: gcs-cache-key: ${{ secrets.gcs-cache-key }} diff --git a/ci/Dockerfile-buildkit b/ci/Dockerfile-buildkit new file mode 100644 index 0000000000..b974a589eb --- /dev/null +++ b/ci/Dockerfile-buildkit @@ -0,0 +1,3 @@ +# We dont build from this dockerfile - we just parse the version, but storing +# here means we get the dependabot updates +FROM moby/buildkit:v0.23.2 diff --git a/ci/Dockerfile-distroless-testing b/ci/Dockerfile-distroless-testing new file mode 100644 index 0000000000..1de43f8d92 --- /dev/null +++ b/ci/Dockerfile-distroless-testing @@ -0,0 +1,3 @@ +FROM debian:bullseye-slim +COPY --from=envoyproxy/envoy:distroless-dev / /distroless-dev +CMD ["/bin/sh", "-c", "stat -c '%A' /distroless-dev/etc/envoy | grep -q '...x' && echo OK || (echo FAIL: Envoy config is not readable in distroless container; exit 1)"] diff --git a/ci/do_ci.sh b/ci/do_ci.sh index cba082a87c..7ab22924f4 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -18,7 +18,6 @@ echo "building for ${ENVOY_BUILD_ARCH}" cd "${SRCDIR}" - if [[ "${ENVOY_BUILD_ARCH}" == "x86_64" ]]; then BUILD_ARCH_DIR="/linux/amd64" elif [[ "${ENVOY_BUILD_ARCH}" == "aarch64" ]]; then @@ -875,6 +874,11 @@ case $CI_TARGET in "$PACKAGE_BUILD" ;; + verify-distroless) + docker build -f ci/Dockerfile-distroless-testing -t distroless-testing . + docker run --rm distroless-testing + ;; + verify_examples) DEV_CONTAINER_ID=$(docker inspect --format='{{.Id}}' envoyproxy/envoy:dev) bazel run --config=ci \ diff --git a/ci/docker_ci.sh b/ci/docker_ci.sh index daec697619..637ba8b369 100755 --- a/ci/docker_ci.sh +++ b/ci/docker_ci.sh @@ -74,7 +74,8 @@ fi # Setting environments for buildx tools config_env() { - echo ">> BUILDX: install" + BUILDKIT_VERSION=$(grep '^FROM moby/buildkit:' ci/Dockerfile-buildkit | cut -d ':' -f2) + echo ">> BUILDX: install ${BUILDKIT_VERSION}" echo "> docker run --rm --privileged tonistiigi/binfmt --install all" echo "> docker buildx rm multi-builder 2> /dev/null || :" echo "> docker buildx create --use --name multi-builder --platform ${DOCKER_PLATFORM}" @@ -88,7 +89,7 @@ config_env() { # Remove older build instance docker buildx rm multi-builder 2> /dev/null || : - docker buildx create --use --name multi-builder --platform "${DOCKER_PLATFORM}" + docker buildx create --use --name multi-builder --platform "${DOCKER_PLATFORM}" --driver-opt "image=moby/buildkit:${BUILDKIT_VERSION}" } # "-google-vrp" must come afer "" to ensure we rebuild the local base image dependency. From 0c5afdcccac1a1c5c73f83a489ed14e16da25716 Mon Sep 17 00:00:00 2001 From: Greg Greenway Date: Thu, 17 Jul 2025 12:04:29 -0700 Subject: [PATCH 30/35] oghttp2: fix window buffer leak Backport fix for #40085 Signed-off-by: Greg Greenway --- bazel/external/quiche.patch | 226 ++++++++++++++++++++++++++++++++++++ bazel/repositories.bzl | 2 + changelogs/current.yaml | 3 + 3 files changed, 231 insertions(+) create mode 100644 bazel/external/quiche.patch diff --git a/bazel/external/quiche.patch b/bazel/external/quiche.patch new file mode 100644 index 0000000000..83ed96bb74 --- /dev/null +++ b/bazel/external/quiche.patch @@ -0,0 +1,226 @@ +commit 6c726cca04b68c5593fbded31fadb001771844ef +Author: danzh +Date: Wed Jul 9 08:28:21 2025 -0700 + + Patch a fix from https://github.com/villainb-dg for the issue of leaking connection flow control window when a HTTP2 stream receives a DATA frame after being closed (reset, etc). + + When a stream receives a DATA frame while it is already closed, the data is counted against the connection flow control window, but is never marked as consumed. + Fix: Mark the data as consumed when the received DATA frame is on a reset or invalid stream. + + Reported QUICHE issue https://github.com/google/quiche/issues/91 + Reported Envoy issue https://github.com/envoyproxy/envoy/issues/40085 + Proposed external fix: https://github.com/google/quiche/pull/92 + + PiperOrigin-RevId: 781064590 + +diff --git a/quiche/http2/adapter/oghttp2_session.cc b/quiche/http2/adapter/oghttp2_session.cc +index c25b2917b..9b1afb22b 100644 +--- a/quiche/http2/adapter/oghttp2_session.cc ++++ b/quiche/http2/adapter/oghttp2_session.cc +@@ -1152,11 +1152,15 @@ void OgHttp2Session::OnDataFrameHeader(spdy::SpdyStreamId stream_id, + + void OgHttp2Session::OnStreamFrameData(spdy::SpdyStreamId stream_id, + const char* data, size_t len) { +- // Count the data against flow control, even if the stream is unknown. ++ // Count the data against flow control, even if the stream is unknown, so that ++ // the connection flow control window is in sync with peer's. + MarkDataBuffered(stream_id, len); + + auto iter = stream_map_.find(stream_id); + if (iter == stream_map_.end()) { ++ // Mark the data consumed immediately as we are dropping them. This will ++ // allow the connection flow control window to shift. ++ Consume(stream_id, len); + return; + } + // Validate against the content-length if it exists. +@@ -1171,6 +1175,9 @@ void OgHttp2Session::OnStreamFrameData(spdy::SpdyStreamId stream_id, + if (streams_reset_.contains(stream_id)) { + // If the stream was unknown due to a protocol error, the visitor was + // informed in OnDataFrameHeader(). ++ // Mark the data consumed immediately as we are dropping them. This will ++ // allow the connection flow control window to shift. ++ Consume(stream_id, len); + return; + } + +diff --git a/quiche/http2/adapter/oghttp2_session_test.cc b/quiche/http2/adapter/oghttp2_session_test.cc +index 34a387bec..4afcf1a3d 100644 +--- a/quiche/http2/adapter/oghttp2_session_test.cc ++++ b/quiche/http2/adapter/oghttp2_session_test.cc +@@ -1217,6 +1217,175 @@ TEST(OgHttp2SessionTest, ServerClosesStreamDuringOnEndStream) { + EXPECT_EQ(result, frames.size()); + } + ++TEST(OgHttp2SessionTest, ResetStreamRaceWithIncomingData) { ++ TestVisitor visitor; ++ OgHttp2Session::Options options; ++ options.perspective = Perspective::kServer; ++ OgHttp2Session session(visitor, options); ++ ++ const std::string frames = TestFrameSequence() ++ .ClientPreface() ++ .Headers(1, ++ {{":method", "POST"}, ++ {":scheme", "https"}, ++ {":authority", "example.com"}, ++ {":path", "/"}}, ++ /*fin=*/false) ++ .Data(1, "Request body", false) ++ .Serialize(); ++ testing::InSequence s; ++ ++ // Client preface (empty SETTINGS) ++ EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0)); ++ EXPECT_CALL(visitor, OnSettingsStart()); ++ EXPECT_CALL(visitor, OnSettingsEnd()); ++ // Stream 1 ++ EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x4)); ++ EXPECT_CALL(visitor, OnBeginHeadersForStream(1)); ++ EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST")); ++ EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https")); ++ EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com")); ++ EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/")); ++ EXPECT_CALL(visitor, OnEndHeadersForStream(1)); ++ ++ EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0x0)); ++ EXPECT_CALL(visitor, OnBeginDataForStream(1, _)); ++ EXPECT_CALL(visitor, OnDataForStream(1, "Request body")) ++ .WillOnce(testing::InvokeWithoutArgs([&session]() { ++ session.Consume(1, 12); ++ return true; ++ })); ++ ++ session.ProcessBytes(frames); ++ ++ EXPECT_TRUE(session.want_write()); ++ EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0)); ++ EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0)); ++ EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1)); ++ EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0)); ++ int result1 = session.Send(); ++ EXPECT_EQ(0, result1); ++ absl::string_view serialized1 = visitor.data(); ++ EXPECT_THAT(serialized1, ++ EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS})); ++ EXPECT_FALSE(session.want_write()); ++ ++ EXPECT_LT(session.GetReceiveWindowSize(), kInitialFlowControlWindowSize); ++ ++ // Reset the stream and receive more data on this stream. ++ session.EnqueueFrame(std::make_unique( ++ 1, spdy::ERROR_CODE_PROTOCOL_ERROR)); ++ const std::string more_frames = ++ TestFrameSequence() ++ .Data(1, std::string(16 * 1024, 'x'), false) ++ .Data(1, std::string(16 * 1024, 'y'), false) ++ .Serialize(); ++ // These bytes are counted against the connection flow control window but ++ // should be dropped right away and considerred as consumed. ++ EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, _)).Times(0); ++ EXPECT_CALL(visitor, OnBeginDataForStream(1, _)).Times(0); ++ EXPECT_CALL(visitor, OnDataForStream(1, _)).Times(0); ++ ++ session.ProcessBytes(more_frames); ++ EXPECT_TRUE(session.want_write()); ++ ++ EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0)); ++ EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, 1, _, 0x0, 1)); ++ EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR)); ++ EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, _, 0x0)); ++ EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, _, 0x0, 0)); ++ int result2 = session.Send(); ++ EXPECT_EQ(0, result2); ++ absl::string_view serialized2 = visitor.data(); ++ serialized2.remove_prefix(serialized1.size()); ++ EXPECT_THAT(serialized2, EqualsFrames({SpdyFrameType::RST_STREAM, ++ SpdyFrameType::WINDOW_UPDATE})); ++ EXPECT_EQ(session.GetReceiveWindowSize(), kInitialFlowControlWindowSize); ++} ++ ++TEST(OgHttp2SessionTest, ResetAndCloseStreamRaceWithIncomingData) { ++ TestVisitor visitor; ++ OgHttp2Session::Options options; ++ options.perspective = Perspective::kServer; ++ OgHttp2Session session(visitor, options); ++ ++ const std::string frames = TestFrameSequence() ++ .ClientPreface() ++ .Headers(1, ++ {{":method", "POST"}, ++ {":scheme", "https"}, ++ {":authority", "example.com"}, ++ {":path", "/"}}, ++ /*fin=*/false) ++ .Data(1, "Request body", false) ++ .Serialize(); ++ testing::InSequence s; ++ ++ // Client preface (empty SETTINGS) ++ EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0)); ++ EXPECT_CALL(visitor, OnSettingsStart()); ++ EXPECT_CALL(visitor, OnSettingsEnd()); ++ // Stream 1 ++ EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x4)); ++ EXPECT_CALL(visitor, OnBeginHeadersForStream(1)); ++ EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST")); ++ EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https")); ++ EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com")); ++ EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/")); ++ EXPECT_CALL(visitor, OnEndHeadersForStream(1)); ++ ++ EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0x0)); ++ EXPECT_CALL(visitor, OnBeginDataForStream(1, _)); ++ EXPECT_CALL(visitor, OnDataForStream(1, "Request body")) ++ .WillOnce(testing::InvokeWithoutArgs([&session]() { ++ session.Consume(1, 12); ++ return true; ++ })); ++ ++ session.ProcessBytes(frames); ++ ++ EXPECT_TRUE(session.want_write()); ++ EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0)); ++ EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0)); ++ EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1)); ++ EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0)); ++ int result1 = session.Send(); ++ EXPECT_EQ(0, result1); ++ absl::string_view serialized1 = visitor.data(); ++ EXPECT_THAT(serialized1, ++ EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS})); ++ EXPECT_FALSE(session.want_write()); ++ ++ EXPECT_LT(session.GetReceiveWindowSize(), kInitialFlowControlWindowSize); ++ ++ // Reset the stream and receive more data on this stream. ++ session.EnqueueFrame(std::make_unique( ++ 1, spdy::ERROR_CODE_PROTOCOL_ERROR)); ++ EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0)); ++ EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, 1, _, 0x0, 1)); ++ EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR)); ++ EXPECT_EQ(0, session.Send()); ++ ++ const std::string more_frames = ++ TestFrameSequence() ++ .Data(1, std::string(16 * 1024, 'x'), false) ++ .Data(1, std::string(16 * 1024, 'y'), false) ++ .Serialize(); ++ // These bytes are counted against the connection flow control window but ++ // should be dropped right away and considered as consumed. ++ EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, _)).Times(2); ++ EXPECT_CALL(visitor, OnBeginDataForStream(1, _)).Times(0); ++ EXPECT_CALL(visitor, OnDataForStream(1, _)).Times(0); ++ ++ session.ProcessBytes(more_frames); ++ EXPECT_TRUE(session.want_write()); ++ ++ EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, _, 0x0)); ++ EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, _, 0x0, 0)); ++ EXPECT_EQ(0, session.Send()); ++ EXPECT_EQ(session.GetReceiveWindowSize(), kInitialFlowControlWindowSize); ++} ++ + } // namespace test + } // namespace adapter + } // namespace http2 diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index 3eca321f71..b12061e8b1 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -739,6 +739,8 @@ def _com_github_google_quiche(): name = "com_github_google_quiche", patch_cmds = ["find quiche/ -type f -name \"*.bazel\" -delete"], build_file = "@envoy//bazel/external:quiche.BUILD", + patches = ["@envoy//bazel/external:quiche.patch"], + patch_args = ["-p1"], ) def _com_googlesource_googleurl(): diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 1756372a57..cd95665bf0 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -15,6 +15,9 @@ bug_fixes: getting the correct value. This could be triggered with a ``tcp_proxy`` access log configured to emit a log upon connection establishment if the log contains fields of the the TLS peer certificate. Then a later use of the data, such as the network RBAC filter validating a peer certificate SAN, may incorrectly fail due to the empty cached value. +- area: http2 + change: | + Fixed an issue where http/2 connections using the default codec of ``oghttp2`` could get stuck due to a window buffer leak. removed_config_or_runtime: # *Normally occurs at the end of the* :ref:`deprecation period ` From 75d667dced3d34bcdb70eab3be2b3ba0686ee716 Mon Sep 17 00:00:00 2001 From: Ryan Northey Date: Fri, 18 Jul 2025 17:24:10 +0100 Subject: [PATCH 31/35] changelogs: Add entry for fixed release container images Signed-off-by: Ryan Northey --- changelogs/current.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/changelogs/current.yaml b/changelogs/current.yaml index cd95665bf0..6eaae1327a 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -18,6 +18,9 @@ bug_fixes: - area: http2 change: | Fixed an issue where http/2 connections using the default codec of ``oghttp2`` could get stuck due to a window buffer leak. +- area: release + change: | + Container (Ubuntu/distroless) updates, and fixed permissions for distroless config directory. removed_config_or_runtime: # *Normally occurs at the end of the* :ref:`deprecation period ` From f32ca1fc7f4d9fcbc1fb9a0701a48c28439960f0 Mon Sep 17 00:00:00 2001 From: phlax Date: Fri, 18 Jul 2025 17:26:39 +0100 Subject: [PATCH 32/35] changelogs: Add entry for dynatrace div by zero fix (#40290) Changelog for #40220 Signed-off-by: Ryan Northey --- changelogs/current.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 6eaae1327a..7ae789dd9a 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -21,6 +21,10 @@ bug_fixes: - area: release change: | Container (Ubuntu/distroless) updates, and fixed permissions for distroless config directory. +- area: dynatrace + change: | + Fixed a division by zero bug in the Dynatrace sampling controller that occurred when ``total_wanted`` was less than + ``top_k_size``. The calculation was refactored to avoid the intermediate division that could result in zero. removed_config_or_runtime: # *Normally occurs at the end of the* :ref:`deprecation period ` From d512ba0c7eec5f5716241a482dad84db8d995c19 Mon Sep 17 00:00:00 2001 From: Ryan Northey Date: Fri, 18 Jul 2025 18:30:44 +0100 Subject: [PATCH 33/35] changelogs: Add summary Signed-off-by: Ryan Northey --- changelogs/summary.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/changelogs/summary.md b/changelogs/summary.md index e69de29bb2..4f3cfb5b32 100644 --- a/changelogs/summary.md +++ b/changelogs/summary.md @@ -0,0 +1,14 @@ +**Summary of changes**: + +* TLS: + - Fixed incorrectly cached connection properties on TLS connections that could cause network RBAC filters to fail. + +* HTTP/2: + - Fixed connection window buffer leak in oghttp2 that could cause connections to get stuck. + +* Observability: + - Fixed division by zero bug in Dynatrace sampling controller. + +* Release: + - Fixed permissions for distroless config directory. + - Updated container images (Ubuntu/distroless). From 450460d95fed1d27118d396594ff97c6cc7dbe75 Mon Sep 17 00:00:00 2001 From: "publish-envoy[bot]" <140627008+publish-envoy[bot]@users.noreply.github.com> Date: Fri, 18 Jul 2025 18:55:21 +0000 Subject: [PATCH 34/35] repo: Release v1.34.3 **Summary of changes**: * TLS: - Fixed incorrectly cached connection properties on TLS connections that could cause network RBAC filters to fail. * HTTP/2: - Fixed connection window buffer leak in oghttp2 that could cause connections to get stuck. * Observability: - Fixed division by zero bug in Dynatrace sampling controller. * Release: - Fixed permissions for distroless config directory. - Updated container images (Ubuntu/distroless). **Docker images**: https://hub.docker.com/r/envoyproxy/envoy/tags?page=1&name=v1.34.3 **Docs**: https://www.envoyproxy.io/docs/envoy/v1.34.3/ **Release notes**: https://www.envoyproxy.io/docs/envoy/v1.34.3/version_history/v1.34/v1.34.3 **Full changelog**: https://github.com/envoyproxy/envoy/compare/v1.34.2...v1.34.3 --- VERSION.txt | 2 +- changelogs/1.31.10.yaml | 10 ++++++++++ changelogs/1.32.8.yaml | 10 ++++++++++ changelogs/1.33.5.yaml | 17 +++++++++++++++++ changelogs/current.yaml | 16 +--------------- docs/inventories/v1.31/objects.inv | Bin 176135 -> 176162 bytes docs/inventories/v1.32/objects.inv | Bin 178987 -> 179031 bytes docs/inventories/v1.33/objects.inv | Bin 181556 -> 181632 bytes docs/inventories/v1.34/objects.inv | Bin 186455 -> 186551 bytes docs/versions.yaml | 8 ++++---- 10 files changed, 43 insertions(+), 20 deletions(-) create mode 100644 changelogs/1.31.10.yaml create mode 100644 changelogs/1.32.8.yaml create mode 100644 changelogs/1.33.5.yaml diff --git a/VERSION.txt b/VERSION.txt index 1c944b1fef..7e3856fe87 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -1.34.3-dev +1.34.3 diff --git a/changelogs/1.31.10.yaml b/changelogs/1.31.10.yaml new file mode 100644 index 0000000000..b6f30a929f --- /dev/null +++ b/changelogs/1.31.10.yaml @@ -0,0 +1,10 @@ +date: July 18, 2025 + +bug_fixes: +- area: release + change: | + Container (Ubuntu/distroless) updates, and fixed permissions for distroless config directory. +- area: dynatrace + change: | + Fixed a division by zero bug in the Dynatrace sampling controller that occurred when ``total_wanted`` was less than + ``top_k_size``. The calculation was refactored to avoid the intermediate division that could result in zero. diff --git a/changelogs/1.32.8.yaml b/changelogs/1.32.8.yaml new file mode 100644 index 0000000000..b6f30a929f --- /dev/null +++ b/changelogs/1.32.8.yaml @@ -0,0 +1,10 @@ +date: July 18, 2025 + +bug_fixes: +- area: release + change: | + Container (Ubuntu/distroless) updates, and fixed permissions for distroless config directory. +- area: dynatrace + change: | + Fixed a division by zero bug in the Dynatrace sampling controller that occurred when ``total_wanted`` was less than + ``top_k_size``. The calculation was refactored to avoid the intermediate division that could result in zero. diff --git a/changelogs/1.33.5.yaml b/changelogs/1.33.5.yaml new file mode 100644 index 0000000000..fed61d514f --- /dev/null +++ b/changelogs/1.33.5.yaml @@ -0,0 +1,17 @@ +date: July 18, 2025 + +bug_fixes: +- area: tls + change: | + Fixed an issue with incorrectly cached connection properties on TLS connections. + If TLS connection data was queried before it was available, an empty value was being incorrectly cached, preventing later calls from + getting the correct value. This could be triggered with a ``tcp_proxy`` access log configured to emit a log upon connection + establishment if the log contains fields of the the TLS peer certificate. Then a later use of the data, such as the network RBAC + filter validating a peer certificate SAN, may incorrectly fail due to the empty cached value. +- area: release + change: | + Container (Ubuntu/distroless) updates, and fixed permissions for distroless config directory. +- area: dynatrace + change: | + Fixed a division by zero bug in the Dynatrace sampling controller that occurred when ``total_wanted`` was less than + ``top_k_size``. The calculation was refactored to avoid the intermediate division that could result in zero. diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 7ae789dd9a..e01bff7742 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -1,13 +1,6 @@ -date: Pending - -behavior_changes: -# *Changes that are expected to cause an incompatibility if applicable; deployment changes are likely required* - -minor_behavior_changes: -# *Changes that may cause incompatibilities for some users, but should not for most* +date: July 18, 2025 bug_fixes: -# *Changes expected to improve the state of the world and are unlikely to have negative effects* - area: tls change: | Fixed an issue with incorrectly cached connection properties on TLS connections. @@ -25,10 +18,3 @@ bug_fixes: change: | Fixed a division by zero bug in the Dynatrace sampling controller that occurred when ``total_wanted`` was less than ``top_k_size``. The calculation was refactored to avoid the intermediate division that could result in zero. - -removed_config_or_runtime: -# *Normally occurs at the end of the* :ref:`deprecation period ` - -new_features: - -deprecated: diff --git a/docs/inventories/v1.31/objects.inv b/docs/inventories/v1.31/objects.inv index b65d7aa97c45d8a030b3359c9c46c72142cdabd0..054d6f7874152a37766ce53ab692f0bef9d8d749 100644 GIT binary patch delta 4389 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 JXwo{;^Zz0EI*I@Q delta 4361 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 bg<`csG_<;xGq|#THq`n%Kc%W%|6ctc;(sY; diff --git a/docs/inventories/v1.32/objects.inv b/docs/inventories/v1.32/objects.inv index 57c54bd292cc335df9e806b920053325721bff12..a124ffb64b78e57d9da9eb8930e3bec073444fb6 100644 GIT binary patch delta 4789 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 AcK`qY diff --git a/docs/inventories/v1.33/objects.inv b/docs/inventories/v1.33/objects.inv index f5ec3fff47eaa4774a2659f4b3bc15939ea9138f..699a73b388336b826807400ed54fc91c35144d42 100644 GIT binary patch delta 7251 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 diff --git a/docs/inventories/v1.34/objects.inv b/docs/inventories/v1.34/objects.inv index 5cf9bc3b37f6c6e51c9ce5e3e0d99ff8d57ce5a2..41d63ef51a4abefdade5b962f5114c4937322ed8 100644 GIT binary patch delta 4580 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 Date: Mon, 21 Jul 2025 17:17:08 +0100 Subject: [PATCH 35/35] repo: Dev v1.34.4 (#40319) Signed-off-by: Ryan Northey --- VERSION.txt | 2 +- changelogs/1.34.3.yaml | 20 ++++++++++++++++++++ changelogs/current.yaml | 33 +++++++++++++++------------------ 3 files changed, 36 insertions(+), 19 deletions(-) create mode 100644 changelogs/1.34.3.yaml diff --git a/VERSION.txt b/VERSION.txt index 7e3856fe87..358f65f3ff 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -1.34.3 +1.34.4-dev diff --git a/changelogs/1.34.3.yaml b/changelogs/1.34.3.yaml new file mode 100644 index 0000000000..e01bff7742 --- /dev/null +++ b/changelogs/1.34.3.yaml @@ -0,0 +1,20 @@ +date: July 18, 2025 + +bug_fixes: +- area: tls + change: | + Fixed an issue with incorrectly cached connection properties on TLS connections. + If TLS connection data was queried before it was available, an empty value was being incorrectly cached, preventing later calls from + getting the correct value. This could be triggered with a ``tcp_proxy`` access log configured to emit a log upon connection + establishment if the log contains fields of the the TLS peer certificate. Then a later use of the data, such as the network RBAC + filter validating a peer certificate SAN, may incorrectly fail due to the empty cached value. +- area: http2 + change: | + Fixed an issue where http/2 connections using the default codec of ``oghttp2`` could get stuck due to a window buffer leak. +- area: release + change: | + Container (Ubuntu/distroless) updates, and fixed permissions for distroless config directory. +- area: dynatrace + change: | + Fixed a division by zero bug in the Dynatrace sampling controller that occurred when ``total_wanted`` was less than + ``top_k_size``. The calculation was refactored to avoid the intermediate division that could result in zero. diff --git a/changelogs/current.yaml b/changelogs/current.yaml index e01bff7742..9ecf0d6e48 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -1,20 +1,17 @@ -date: July 18, 2025 +date: Pending + +behavior_changes: +# *Changes that are expected to cause an incompatibility if applicable; deployment changes are likely required* + +minor_behavior_changes: +# *Changes that may cause incompatibilities for some users, but should not for most* bug_fixes: -- area: tls - change: | - Fixed an issue with incorrectly cached connection properties on TLS connections. - If TLS connection data was queried before it was available, an empty value was being incorrectly cached, preventing later calls from - getting the correct value. This could be triggered with a ``tcp_proxy`` access log configured to emit a log upon connection - establishment if the log contains fields of the the TLS peer certificate. Then a later use of the data, such as the network RBAC - filter validating a peer certificate SAN, may incorrectly fail due to the empty cached value. -- area: http2 - change: | - Fixed an issue where http/2 connections using the default codec of ``oghttp2`` could get stuck due to a window buffer leak. -- area: release - change: | - Container (Ubuntu/distroless) updates, and fixed permissions for distroless config directory. -- area: dynatrace - change: | - Fixed a division by zero bug in the Dynatrace sampling controller that occurred when ``total_wanted`` was less than - ``top_k_size``. The calculation was refactored to avoid the intermediate division that could result in zero. +# *Changes expected to improve the state of the world and are unlikely to have negative effects* + +removed_config_or_runtime: +# *Normally occurs at the end of the* :ref:`deprecation period ` + +new_features: + +deprecated: