diff --git a/.azure-pipelines/pipelines.yml b/.azure-pipelines/pipelines.yml index 462e28c471..c3b706ff1c 100644 --- a/.azure-pipelines/pipelines.yml +++ b/.azure-pipelines/pipelines.yml @@ -3,9 +3,6 @@ trigger: include: - "main" - "release/v*" - tags: - include: - - "v*" # PR build config is manually overridden in Azure pipelines UI with different secrets diff --git a/.azure-pipelines/stages.yml b/.azure-pipelines/stages.yml index 8693671b52..9a97067cc7 100644 --- a/.azure-pipelines/stages.yml +++ b/.azure-pipelines/stages.yml @@ -63,6 +63,7 @@ stages: authGPGPath: $(MaintainerGPGKey.secureFilePath) bucketGCP: $(GcsArtifactBucket) publishGithubRelease: variables['PUBLISH_GITHUB_RELEASE'] + runBuild: stageDependencies.env.repo.outputs['run.releaseTests'] runPrechecks: stageDependencies.env.repo.outputs['run.releaseTests'] - stage: check diff --git a/.github/workflows/envoy-sync.yml b/.github/workflows/envoy-sync.yml index acd3de4ef8..197387b0ff 100644 --- a/.github/workflows/envoy-sync.yml +++ b/.github/workflows/envoy-sync.yml @@ -7,6 +7,8 @@ on: push: branches: - main + - release/v1.28 + - release/v1.31 workflow_dispatch: concurrency: @@ -19,6 +21,7 @@ jobs: if: >- ${{ github.repository == 'envoyproxy/envoy' + && (github.ref_name == 'main') && (github.event.push || !contains(github.actor, '[bot]')) }} @@ -42,3 +45,32 @@ jobs: ref: main token: ${{ steps.appauth.outputs.token }} workflow: envoy-sync.yaml + + sync-release: + runs-on: ubuntu-22.04 + if: >- + ${{ + github.repository == 'envoyproxy/envoy' + && contains(fromJSON('["main", "release/v1.28", "release/v1.31"]'), github.ref_name) + && (github.event.push + || !contains(github.actor, '[bot]')) + }} + strategy: + fail-fast: false + matrix: + downstream: + - envoy-openssl + steps: + - uses: envoyproxy/toolshed/gh-actions/appauth@actions-v0.2.35 + id: appauth + with: + app_id: ${{ secrets.ENVOY_CI_SYNC_APP_ID }} + key: ${{ secrets.ENVOY_CI_SYNC_APP_KEY }} + - uses: envoyproxy/toolshed/gh-actions/dispatch@actions-v0.2.35 + with: + repository: "envoyproxy/${{ matrix.downstream }}" + ref: release/v1.28 + token: ${{ steps.appauth.outputs.token }} + workflow: envoy-sync-receive.yaml + inputs: | + branch: ${{ github.ref_name }} diff --git a/api/BUILD b/api/BUILD index 12dafa02ee..d31540adcf 100644 --- a/api/BUILD +++ b/api/BUILD @@ -382,6 +382,7 @@ proto_library( visibility = ["//visibility:public"], deps = [ "@com_github_cncf_xds//xds/core/v3:pkg", + "@com_github_cncf_xds//xds/data/orca/v3:pkg", "@com_github_cncf_xds//xds/type/matcher/v3:pkg", "@com_github_cncf_xds//xds/type/v3:pkg", ], diff --git a/api/bazel/repository_locations.bzl b/api/bazel/repository_locations.bzl index f69f44ef04..6c353c8591 100644 --- a/api/bazel/repository_locations.bzl +++ b/api/bazel/repository_locations.bzl @@ -52,9 +52,9 @@ REPOSITORY_LOCATIONS_SPEC = dict( project_desc = "xDS API Working Group (xDS-WG)", project_url = "https://github.com/cncf/xds", # During the UDPA -> xDS migration, we aren't working with releases. - version = "555b57ec207be86f811fb0c04752db6f85e3d7e2", - sha256 = "0c8c4f0f67fed967b51049f7d5e2ca7a9bd433970a29c88e272c8665328172f5", - release_date = "2024-04-23", + version = "b4127c9b8d78b77423fd25169f05b7476b6ea932", + sha256 = "aa5f1596bbef3f277dcf4700e4c1097b34301ae66f3b79cd731e3adfbaff2f8f", + release_date = "2024-09-05", strip_prefix = "xds-{version}", urls = ["https://github.com/cncf/xds/archive/{version}.tar.gz"], use_category = ["api"], diff --git a/api/envoy/config/cluster/v3/cluster.proto b/api/envoy/config/cluster/v3/cluster.proto index 0e034b3dde..0d2d6f1918 100644 --- a/api/envoy/config/cluster/v3/cluster.proto +++ b/api/envoy/config/cluster/v3/cluster.proto @@ -1162,14 +1162,13 @@ message Cluster { // from the LRS stream here.] core.v3.ConfigSource lrs_server = 42; - // [#not-implemented-hide:] - // A list of metric names from ORCA load reports to propagate to LRS. + // A list of metric names from :ref:`ORCA load reports ` to propagate to LRS. // // If not specified, then ORCA load reports will not be propagated to LRS. // // For map fields in the ORCA proto, the string will be of the form ``.``. // For example, the string ``named_metrics.foo`` will mean to look for the key ``foo`` in the ORCA - // ``named_metrics`` field. + // :ref:`named_metrics ` field. // // The special map key ``*`` means to report all entries in the map (e.g., ``named_metrics.*`` means to // report all entries in the ORCA named_metrics field). Note that this should be used only with trusted diff --git a/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto b/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto index 3b6a67cc90..17b0353c1d 100644 --- a/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto +++ b/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto @@ -30,7 +30,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // External Authorization :ref:`configuration overview `. // [#extension: envoy.filters.http.ext_authz] -// [#next-free-field: 29] +// [#next-free-field: 30] message ExtAuthz { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.ext_authz.v3.ExtAuthz"; @@ -296,6 +296,17 @@ message ExtAuthz { // added to StreamInfo's filter state under the namespace corresponding to the ext_authz filter // name. google.protobuf.Struct filter_metadata = 28; + + // When set to true, the filter will emit per-stream stats for access logging. The filter state + // key will be the same as the filter name. + // + // If using Envoy GRPC, emits latency, bytes sent / received, upstream info, and upstream cluster + // info. If not using Envoy GRPC, emits only latency. Note that stats are ONLY added to filter + // state if a check request is actually made to an ext_authz service. + // + // If this is false the filter will not emit stats, but filter_metadata will still be respected if + // it has a value. + bool emit_filter_state_stats = 29; } // Configuration for buffering the request data. diff --git a/api/envoy/extensions/filters/http/oauth2/v3/oauth.proto b/api/envoy/extensions/filters/http/oauth2/v3/oauth.proto index 06d851a796..df377fd6ad 100644 --- a/api/envoy/extensions/filters/http/oauth2/v3/oauth.proto +++ b/api/envoy/extensions/filters/http/oauth2/v3/oauth.proto @@ -27,7 +27,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#next-free-field: 6] message OAuth2Credentials { - // [#next-free-field: 6] + // [#next-free-field: 7] message CookieNames { // Cookie name to hold OAuth bearer token value. When the authentication server validates the // client and returns an authorization token back to the OAuth filter, no matter what format @@ -52,6 +52,10 @@ message OAuth2Credentials { // Cookie name to hold the refresh token. Defaults to ``RefreshToken``. string refresh_token = 5 [(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; + + // Cookie name to hold the nonce value. Defaults to ``OauthNonce``. + string oauth_nonce = 6 + [(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; } // The client_id to be used in the authorize calls. This value will be URL encoded when sent to the OAuth server. diff --git a/bazel/dependency_imports.bzl b/bazel/dependency_imports.bzl index 6f782ef732..476ca5b9d2 100644 --- a/bazel/dependency_imports.bzl +++ b/bazel/dependency_imports.bzl @@ -18,7 +18,7 @@ load("@rules_rust//rust:defs.bzl", "rust_common") load("@rules_rust//rust:repositories.bzl", "rules_rust_dependencies", "rust_register_toolchains", "rust_repository_set") # go version for rules_go -GO_VERSION = "1.22.5" +GO_VERSION = "1.23.1" JQ_VERSION = "1.7" YQ_VERSION = "4.24.4" diff --git a/bazel/external/quiche.BUILD b/bazel/external/quiche.BUILD index ad11894e39..950f9426a6 100644 --- a/bazel/external/quiche.BUILD +++ b/bazel/external/quiche.BUILD @@ -433,9 +433,6 @@ envoy_cc_library( "quiche/http2/adapter/oghttp2_session.h", ], copts = quiche_copts, - external_deps = [ - "abseil_algorithm", - ], repository = "@envoy", deps = [ ":http2_adapter_chunked_buffer", @@ -457,6 +454,7 @@ envoy_cc_library( ":http2_no_op_headers_handler_lib", ":quiche_common_callbacks", ":spdy_core_http2_header_block_lib", + "@com_google_absl//absl/algorithm", "@com_google_absl//absl/cleanup", ], ) @@ -2296,13 +2294,11 @@ envoy_quic_cc_library( hdrs = [ "quiche/quic/core/quic_connection_context.h", ], - external_deps = [ - "abseil_str_format", - ], deps = [ ":quic_platform_export", ":quiche_common_platform", ":quiche_common_text_utils_lib", + "@com_google_absl//absl/strings:str_format", ], ) @@ -2664,7 +2660,6 @@ envoy_quic_cc_library( hdrs = ["quiche/quic/core/crypto/proof_source_x509.h"], external_deps = [ "ssl", - "abseil_node_hash_map", ], deps = [ ":quic_core_crypto_certificate_view_lib", @@ -2675,6 +2670,7 @@ envoy_quic_cc_library( ":quic_platform_base", ":quiche_common_endian_lib", "@com_google_absl//absl/base:core_headers", + "@com_google_absl//absl/container:node_hash_map", ], ) @@ -5091,13 +5087,11 @@ envoy_cc_test( envoy_cc_library( name = "quiche_common_print_elements_lib", hdrs = ["quiche/common/print_elements.h"], - external_deps = [ - "abseil_inlined_vector", - ], repository = "@envoy", tags = ["nofips"], deps = [ ":quiche_common_platform_export", + "@com_google_absl//absl/container:inlined_vector", ], ) @@ -5123,14 +5117,12 @@ envoy_cc_library( name = "quiche_common_text_utils_lib", srcs = ["quiche/common/quiche_text_utils.cc"], hdrs = ["quiche/common/quiche_text_utils.h"], - external_deps = [ - "abseil_str_format", - ], repository = "@envoy", tags = ["nofips"], deps = [ ":quiche_common_platform_export", "@com_google_absl//absl/hash", + "@com_google_absl//absl/strings:str_format", ], ) diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index 2b4d0d7682..f0fed861ee 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -696,24 +696,8 @@ def _com_google_absl(): patches = ["@envoy//bazel:abseil.patch"], patch_args = ["-p1"], ) - native.bind( - name = "abseil_any", - actual = "@com_google_absl//absl/types:any", - ) - native.bind( - name = "abseil_base", - actual = "@com_google_absl//absl/base:base", - ) - # Bind for grpc. - native.bind( - name = "absl-base", - actual = "@com_google_absl//absl/base", - ) - native.bind( - name = "abseil_btree", - actual = "@com_google_absl//absl/container:btree", - ) + # keep these until jwt_verify_lib is updated. native.bind( name = "abseil_flat_hash_map", actual = "@com_google_absl//absl/container:flat_hash_map", @@ -722,93 +706,15 @@ def _com_google_absl(): name = "abseil_flat_hash_set", actual = "@com_google_absl//absl/container:flat_hash_set", ) - native.bind( - name = "abseil_hash", - actual = "@com_google_absl//absl/hash:hash", - ) - native.bind( - name = "abseil_hash_testing", - actual = "@com_google_absl//absl/hash:hash_testing", - ) - native.bind( - name = "abseil_inlined_vector", - actual = "@com_google_absl//absl/container:inlined_vector", - ) - native.bind( - name = "abseil_memory", - actual = "@com_google_absl//absl/memory:memory", - ) - native.bind( - name = "abseil_node_hash_map", - actual = "@com_google_absl//absl/container:node_hash_map", - ) - native.bind( - name = "abseil_node_hash_set", - actual = "@com_google_absl//absl/container:node_hash_set", - ) - native.bind( - name = "abseil_str_format", - actual = "@com_google_absl//absl/strings:str_format", - ) native.bind( name = "abseil_strings", actual = "@com_google_absl//absl/strings:strings", ) - native.bind( - name = "abseil_int128", - actual = "@com_google_absl//absl/numeric:int128", - ) - native.bind( - name = "abseil_optional", - actual = "@com_google_absl//absl/types:optional", - ) - native.bind( - name = "abseil_synchronization", - actual = "@com_google_absl//absl/synchronization:synchronization", - ) - native.bind( - name = "abseil_symbolize", - actual = "@com_google_absl//absl/debugging:symbolize", - ) - native.bind( - name = "abseil_stacktrace", - actual = "@com_google_absl//absl/debugging:stacktrace", - ) - native.bind( - name = "abseil_statusor", - actual = "@com_google_absl//absl/status:statusor", - ) - - # Require abseil_time as an indirect dependency as it is needed by the - # direct dependency jwt_verify_lib. native.bind( name = "abseil_time", actual = "@com_google_absl//absl/time:time", ) - # Bind for grpc. - native.bind( - name = "absl-time", - actual = "@com_google_absl//absl/time:time", - ) - - native.bind( - name = "abseil_algorithm", - actual = "@com_google_absl//absl/algorithm:algorithm", - ) - native.bind( - name = "abseil_variant", - actual = "@com_google_absl//absl/types:variant", - ) - native.bind( - name = "abseil_status", - actual = "@com_google_absl//absl/status", - ) - native.bind( - name = "abseil_cleanup", - actual = "@com_google_absl//absl/cleanup:cleanup", - ) - def _com_google_protobuf(): external_http_archive( name = "rules_python", diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index f3372054d7..d382a58b13 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -948,13 +948,13 @@ REPOSITORY_LOCATIONS_SPEC = dict( project_name = "grpc-httpjson-transcoding", project_desc = "Library that supports transcoding so that HTTP/JSON can be converted to gRPC", project_url = "https://github.com/grpc-ecosystem/grpc-httpjson-transcoding", - version = "ff41eb3fc9209e6197595b54f7addfa244c0bdb6", - sha256 = "dea66b3d2dfc150373697e25b1327877e0b7480dc2bacfff1e3fd7aa00b12790", + version = "20e58e7ef9c3878ae9fc89123b9aba36d6f98a7f", + sha256 = "2f0ea248c59f51e5376f23590a986813b96076531ffe27a805f7a37407a81a87", strip_prefix = "grpc-httpjson-transcoding-{version}", urls = ["https://github.com/grpc-ecosystem/grpc-httpjson-transcoding/archive/{version}.tar.gz"], use_category = ["dataplane_ext"], extensions = ["envoy.filters.http.grpc_json_transcoder", "envoy.filters.http.grpc_field_extraction", "envoy.filters.http.proto_message_extraction"], - release_date = "2023-06-07", + release_date = "2024-08-30", cpe = "N/A", license = "Apache-2.0", license_url = "https://github.com/grpc-ecosystem/grpc-httpjson-transcoding/blob/{version}/LICENSE", @@ -1208,12 +1208,12 @@ REPOSITORY_LOCATIONS_SPEC = dict( project_name = "QUICHE", project_desc = "QUICHE (QUIC, HTTP/2, Etc) is Google‘s implementation of QUIC and related protocols", project_url = "https://github.com/google/quiche", - version = "e94fbe61aae27c2587fe5c1ff0141ac7b2cacb30", - sha256 = "ef31887f0bd3542a9f266cd50a38bbe65022653439994675486c473e3b56dcfd", + version = "9808dac40e034f09d7af53d3d79589a02e39c211", + sha256 = "b59e6e5b9b249a8d0cb521851d54a09ac74d2beb01a233498a006f75c86c9b76", urls = ["https://github.com/google/quiche/archive/{version}.tar.gz"], strip_prefix = "quiche-{version}", use_category = ["controlplane", "dataplane_core"], - release_date = "2024-09-05", + release_date = "2024-09-10", cpe = "N/A", license = "BSD-3-Clause", license_url = "https://github.com/google/quiche/blob/{version}/LICENSE", diff --git a/changelogs/1.28.6.yaml b/changelogs/1.28.6.yaml new file mode 100644 index 0000000000..ab308c36c6 --- /dev/null +++ b/changelogs/1.28.6.yaml @@ -0,0 +1,9 @@ +date: September 13, 2024 + +bug_fixes: +- area: stateful_session + change: | + Support 0 TTL for proto-encoded cookies, which disables cookie expiration by Envoy. +- area: dependencies + change: | + Update curl to mitigate CVE-2024-7264. diff --git a/changelogs/1.29.8.yaml b/changelogs/1.29.8.yaml new file mode 100644 index 0000000000..3f99587d7a --- /dev/null +++ b/changelogs/1.29.8.yaml @@ -0,0 +1,9 @@ +date: September 14, 2024 + +bug_fixes: +- area: stateful_session + change: | + Support 0 TTL for proto-encoded cookies, which disables cookie expiration by Envoy. +- area: dependencies + change: | + Update curl to mitigate CVE-2024-7264. diff --git a/changelogs/1.30.5.yaml b/changelogs/1.30.5.yaml new file mode 100644 index 0000000000..5808e044cf --- /dev/null +++ b/changelogs/1.30.5.yaml @@ -0,0 +1,6 @@ +date: September 14, 2024 + +bug_fixes: +- area: dependencies + change: | + Update curl to mitigate CVE-2024-7264. diff --git a/changelogs/1.31.1.yaml b/changelogs/1.31.1.yaml new file mode 100644 index 0000000000..25546e342a --- /dev/null +++ b/changelogs/1.31.1.yaml @@ -0,0 +1,15 @@ +date: September 14, 2024 + +bug_fixes: +- area: c-ares + change: | + Applying a C-ares patch to fix DNS resoultion by the Google gRPC library. +- area: dependencies + change: | + Update curl to mitigate CVE-2024-7264. + +new_features: +- area: access_log + change: | + added %UPSTREAM_CLUSTER_RAW% access log formatter to log the original upstream cluster name, regadless of whether + ``alt_stat_name`` is set. diff --git a/changelogs/current.yaml b/changelogs/current.yaml index b7da07e70c..a8f9ca6d88 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -128,6 +128,11 @@ bug_fixes: the number of requests per I/O cycle is configured and an HTTP decoder filter that pauses filter chain is present. This behavior can be reverted by setting the runtime guard ``envoy.reloadable_features.use_filter_manager_state_for_downstream_end_stream`` to false. +- area: proxy_filter + change: | + Fixed a bug in the ``CONNECT`` implementation that would cause the ``CONNECT`` request created to be invalid when the + hostname contains a port number. When the port number is not specified, the port 443 will be automatically added. + This behavior can be reverted by setting the runtime guard ``envoy.reloadable_features.proxy_ssl_port`` to ``false``. - area: runtime change: | Fixed an inconsistency in how boolean values are loaded in RTDS, where they were previously converted to "1"/"0" @@ -191,6 +196,9 @@ removed_config_or_runtime: - area: dynamic forward proxy change: | Removed ``envoy.reloadable_features.normalize_host_for_preresolve_dfp_dns`` runtime flag and legacy code paths. +- area: http + change: | + Removed the ``envoy.reloadable_features.http2_validate_authority_with_quiche`` runtime flag and its legacy code paths. - area: http change: | Removed ``envoy.reloadable_features.use_http3_header_normalisation`` runtime flag and legacy code paths. @@ -252,6 +260,8 @@ new_features: the auth server when a connection fails to be established. Added :ref:`cookie_domain ` field to OAuth2 filter to allow setting the domain of cookies. + Added a nonce to the state parameter in the authorization request to mitigate CSRF attacks. The nonce is generated by the + OAuth2 filter and stored in a cookie. This feature is enabled by defaut starting from this release. - area: access log change: | Added support for :ref:`%DOWNSTREAM_PEER_CHAIN_FINGERPRINTS_1% `, @@ -284,6 +294,10 @@ new_features: change: | Added :ref:`delay_deny ` to support deny connection after the configured duration. +- area: ext_authz + change: | + Added :ref:`emit_filter_state_stats ` + which when true enables filter state stats for access logging. - area: extension_discovery_service change: | added ECDS support for :ref:`UDP session filters diff --git a/ci/Dockerfile-envoy b/ci/Dockerfile-envoy index 67135ed640..826b3e869f 100644 --- a/ci/Dockerfile-envoy +++ b/ci/Dockerfile-envoy @@ -1,5 +1,5 @@ ARG BUILD_OS=ubuntu -ARG BUILD_TAG=22.04@sha256:340d9b015b194dc6e2a13938944e0d016e57b9679963fdeb9ce021daac430221 +ARG BUILD_TAG=22.04@sha256:adbb90115a21969d2fe6fa7f9af4253e16d45f8d4c1e930182610c4731962658 ARG ENVOY_VRP_BASE_IMAGE=envoy-base diff --git a/contrib/config/source/BUILD b/contrib/config/source/BUILD index 07ae49bf54..d807ee238d 100644 --- a/contrib/config/source/BUILD +++ b/contrib/config/source/BUILD @@ -12,7 +12,6 @@ envoy_cc_contrib_extension( name = "kv_store_xds_delegate", srcs = ["kv_store_xds_delegate.cc"], hdrs = ["kv_store_xds_delegate.h"], - external_deps = ["abseil_optional"], deps = [ "//envoy/common:key_value_store_interface", "//envoy/common:time_interface", @@ -21,6 +20,7 @@ envoy_cc_contrib_extension( "//envoy/stats:stats_macros", "//source/common/config:utility_lib", "//source/common/protobuf:utility_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//contrib/envoy/extensions/config/v3alpha:pkg_cc_proto", "@envoy_api//envoy/service/discovery/v3:pkg_cc_proto", ], diff --git a/contrib/golang/filters/http/test/test_data/access_log/go.mod b/contrib/golang/filters/http/test/test_data/access_log/go.mod index 7994171a8b..a019ffa882 100644 --- a/contrib/golang/filters/http/test/test_data/access_log/go.mod +++ b/contrib/golang/filters/http/test/test_data/access_log/go.mod @@ -1,6 +1,6 @@ module example.com/access_log -go 1.20 +go 1.23 require github.com/envoyproxy/envoy v1.24.0 diff --git a/contrib/golang/filters/http/test/test_data/action/go.mod b/contrib/golang/filters/http/test/test_data/action/go.mod index 56a3bc4ad1..0c6cbba1b5 100644 --- a/contrib/golang/filters/http/test/test_data/action/go.mod +++ b/contrib/golang/filters/http/test/test_data/action/go.mod @@ -1,6 +1,6 @@ module example.com/action -go 1.20 +go 1.23 require github.com/envoyproxy/envoy v1.24.0 diff --git a/contrib/golang/filters/http/test/test_data/basic/go.mod b/contrib/golang/filters/http/test/test_data/basic/go.mod index 77ecc15879..12f18783fe 100644 --- a/contrib/golang/filters/http/test/test_data/basic/go.mod +++ b/contrib/golang/filters/http/test/test_data/basic/go.mod @@ -1,6 +1,6 @@ module example.com/basic -go 1.20 +go 1.23 require github.com/envoyproxy/envoy v1.24.0 diff --git a/contrib/golang/filters/http/test/test_data/buffer/go.mod b/contrib/golang/filters/http/test/test_data/buffer/go.mod index 15b60c9a61..2f4c5c44b8 100644 --- a/contrib/golang/filters/http/test/test_data/buffer/go.mod +++ b/contrib/golang/filters/http/test/test_data/buffer/go.mod @@ -1,6 +1,6 @@ module example.com/buffer -go 1.20 +go 1.23 require ( github.com/envoyproxy/envoy v1.24.0 diff --git a/contrib/golang/filters/http/test/test_data/dummy/go.mod b/contrib/golang/filters/http/test/test_data/dummy/go.mod index 7f3cef1416..e8c9ba548e 100644 --- a/contrib/golang/filters/http/test/test_data/dummy/go.mod +++ b/contrib/golang/filters/http/test/test_data/dummy/go.mod @@ -1,6 +1,6 @@ module example.com/dummy -go 1.20 +go 1.23 require github.com/envoyproxy/envoy v1.24.0 diff --git a/contrib/golang/filters/http/test/test_data/echo/go.mod b/contrib/golang/filters/http/test/test_data/echo/go.mod index 9ec24823d2..3647faba91 100644 --- a/contrib/golang/filters/http/test/test_data/echo/go.mod +++ b/contrib/golang/filters/http/test/test_data/echo/go.mod @@ -1,6 +1,6 @@ module example.com/echo -go 1.20 +go 1.23 require ( github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa diff --git a/contrib/golang/filters/http/test/test_data/metric/go.mod b/contrib/golang/filters/http/test/test_data/metric/go.mod index c9f7f23cdb..f35013f025 100644 --- a/contrib/golang/filters/http/test/test_data/metric/go.mod +++ b/contrib/golang/filters/http/test/test_data/metric/go.mod @@ -1,6 +1,6 @@ module example.com/basic -go 1.20 +go 1.23 require github.com/envoyproxy/envoy v1.24.0 diff --git a/contrib/golang/filters/http/test/test_data/passthrough/go.mod b/contrib/golang/filters/http/test/test_data/passthrough/go.mod index 7830ee8c62..bf3abff8c5 100644 --- a/contrib/golang/filters/http/test/test_data/passthrough/go.mod +++ b/contrib/golang/filters/http/test/test_data/passthrough/go.mod @@ -1,6 +1,6 @@ module example.com/passthrough -go 1.20 +go 1.23 require github.com/envoyproxy/envoy v1.24.0 diff --git a/contrib/golang/filters/http/test/test_data/property/go.mod b/contrib/golang/filters/http/test/test_data/property/go.mod index 3759c66997..830e11ad80 100644 --- a/contrib/golang/filters/http/test/test_data/property/go.mod +++ b/contrib/golang/filters/http/test/test_data/property/go.mod @@ -1,6 +1,6 @@ module example.com/property -go 1.20 +go 1.23 require ( github.com/envoyproxy/envoy v1.24.0 diff --git a/contrib/golang/filters/http/test/test_data/routeconfig/go.mod b/contrib/golang/filters/http/test/test_data/routeconfig/go.mod index a745d13e13..6359d3e96b 100644 --- a/contrib/golang/filters/http/test/test_data/routeconfig/go.mod +++ b/contrib/golang/filters/http/test/test_data/routeconfig/go.mod @@ -1,6 +1,6 @@ module example.com/routeconfig -go 1.20 +go 1.23 require ( github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa diff --git a/contrib/golang/filters/http/test/test_data/websocket/go.mod b/contrib/golang/filters/http/test/test_data/websocket/go.mod index a348a66b3b..15446803fe 100644 --- a/contrib/golang/filters/http/test/test_data/websocket/go.mod +++ b/contrib/golang/filters/http/test/test_data/websocket/go.mod @@ -1,6 +1,6 @@ module example.com/websocket -go 1.20 +go 1.23 require github.com/envoyproxy/envoy v1.24.0 diff --git a/contrib/golang/filters/network/test/test_data/go.mod b/contrib/golang/filters/network/test/test_data/go.mod index e1a332e437..6e19aa70b3 100644 --- a/contrib/golang/filters/network/test/test_data/go.mod +++ b/contrib/golang/filters/network/test/test_data/go.mod @@ -1,6 +1,6 @@ module github.com/envoyproxy/envoy/contrib/golang/filters/network/test/test_data -go 1.18 +go 1.23 require github.com/envoyproxy/envoy v1.24.0 diff --git a/contrib/golang/router/cluster_specifier/test/test_data/simple/go.mod b/contrib/golang/router/cluster_specifier/test/test_data/simple/go.mod index cd81d5a6fa..20bada9d81 100644 --- a/contrib/golang/router/cluster_specifier/test/test_data/simple/go.mod +++ b/contrib/golang/router/cluster_specifier/test/test_data/simple/go.mod @@ -1,6 +1,6 @@ module example.com/routeconfig -go 1.18 +go 1.23 require ( github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa diff --git a/contrib/kafka/filters/network/source/BUILD b/contrib/kafka/filters/network/source/BUILD index a7e075125b..438d87ee48 100644 --- a/contrib/kafka/filters/network/source/BUILD +++ b/contrib/kafka/filters/network/source/BUILD @@ -246,8 +246,8 @@ envoy_cc_library( hdrs = [ "kafka_types.h", ], - external_deps = ["abseil_optional"], deps = [ "//source/common/common:macros", + "@com_google_absl//absl/types:optional", ], ) diff --git a/contrib/rocketmq_proxy/filters/network/source/BUILD b/contrib/rocketmq_proxy/filters/network/source/BUILD index e421666b9f..7fe92542ba 100644 --- a/contrib/rocketmq_proxy/filters/network/source/BUILD +++ b/contrib/rocketmq_proxy/filters/network/source/BUILD @@ -139,8 +139,8 @@ envoy_cc_contrib_extension( envoy_cc_library( name = "metadata_lib", hdrs = ["metadata.h"], - external_deps = ["abseil_optional"], deps = [ "//source/common/http:header_map_lib", + "@com_google_absl//absl/types:optional", ], ) diff --git a/contrib/sip_proxy/filters/network/source/BUILD b/contrib/sip_proxy/filters/network/source/BUILD index 109ae63de1..167cd61f3f 100644 --- a/contrib/sip_proxy/filters/network/source/BUILD +++ b/contrib/sip_proxy/filters/network/source/BUILD @@ -44,7 +44,6 @@ envoy_cc_library( name = "conn_manager_lib", srcs = ["conn_manager.cc"], hdrs = ["conn_manager.h"], - external_deps = ["abseil_any"], deps = [ ":app_exception_lib", ":decoder_lib", @@ -67,6 +66,7 @@ envoy_cc_library( "//source/common/stats:timespan_lib", "//source/common/stream_info:stream_info_lib", "//source/common/tracing:http_tracer_lib", + "@com_google_absl//absl/types:any", ], ) @@ -112,12 +112,12 @@ envoy_cc_library( "metadata.h", "operation.h", ], - external_deps = ["abseil_optional"], deps = [ ":sip_lib", "//envoy/buffer:buffer_interface", "//source/common/common:macros", "//source/common/http:header_map_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//contrib/envoy/extensions/filters/network/sip_proxy/v3alpha:pkg_cc_proto", ], ) @@ -138,7 +138,6 @@ envoy_cc_library( hdrs = [ "utility.h", ], - external_deps = ["abseil_optional"], deps = [ ":decoder_events_lib", ":metadata_lib", @@ -150,6 +149,7 @@ envoy_cc_library( "//source/common/config:utility_lib", "//source/common/protobuf", "//source/common/singleton:const_singleton", + "@com_google_absl//absl/types:optional", "@envoy_api//contrib/envoy/extensions/filters/network/sip_proxy/tra/v3alpha:pkg_cc_proto", "@envoy_api//contrib/envoy/extensions/filters/network/sip_proxy/v3alpha:pkg_cc_proto", ], diff --git a/contrib/sip_proxy/filters/network/source/router/BUILD b/contrib/sip_proxy/filters/network/source/router/BUILD index 4f9b933eb8..abc8223673 100644 --- a/contrib/sip_proxy/filters/network/source/router/BUILD +++ b/contrib/sip_proxy/filters/network/source/router/BUILD @@ -27,10 +27,10 @@ envoy_cc_contrib_extension( envoy_cc_library( name = "router_interface", hdrs = ["router.h"], - external_deps = ["abseil_optional"], deps = [ "//contrib/sip_proxy/filters/network/source:metadata_lib", "//envoy/router:router_interface", + "@com_google_absl//absl/types:optional", ], ) diff --git a/contrib/sip_proxy/filters/network/source/tra/BUILD b/contrib/sip_proxy/filters/network/source/tra/BUILD index da11318b7b..7d1c69681f 100644 --- a/contrib/sip_proxy/filters/network/source/tra/BUILD +++ b/contrib/sip_proxy/filters/network/source/tra/BUILD @@ -34,13 +34,11 @@ envoy_cc_contrib_extension( envoy_cc_library( name = "tra_client_interface", hdrs = ["tra.h"], - external_deps = [ - "abseil_optional", - "abseil_any", - ], deps = [ "//envoy/singleton:manager_interface", "//envoy/tracing:tracer_interface", "//source/common/stats:symbol_table_lib", + "@com_google_absl//absl/types:any", + "@com_google_absl//absl/types:optional", ], ) diff --git a/contrib/vcl/source/BUILD b/contrib/vcl/source/BUILD index b8b3de1f70..8a5a5ca0c2 100644 --- a/contrib/vcl/source/BUILD +++ b/contrib/vcl/source/BUILD @@ -80,10 +80,8 @@ genrule( "external/vppcom.h", ], cmd = """ - EXTERNAL_DIR=$$(dirname $(location external/libsvm.a)) \ - && mkdir -p $$EXTERNAL_DIR \ - && find . -name "*.a" | xargs -I{} cp -a {} $$EXTERNAL_DIR \ - && find . -name "vppcom.h" | xargs -I{} cp -a {} $$EXTERNAL_DIR + find . -name "*.a" | grep -v copy_build | xargs -I{} cp -a {} $(RULEDIR)/external \ + && find . -name "vppcom.h" | grep -v copy_build | xargs -I{} cp -a {} $(RULEDIR)/external """, tools = [":build"], ) diff --git a/docs/inventories/v1.28/objects.inv b/docs/inventories/v1.28/objects.inv index 0cffae7aa1..2fd3b18a0d 100644 Binary files a/docs/inventories/v1.28/objects.inv and b/docs/inventories/v1.28/objects.inv differ diff --git a/docs/inventories/v1.29/objects.inv b/docs/inventories/v1.29/objects.inv index dda68cc966..11b1c785f6 100644 Binary files a/docs/inventories/v1.29/objects.inv and b/docs/inventories/v1.29/objects.inv differ diff --git a/docs/inventories/v1.30/objects.inv b/docs/inventories/v1.30/objects.inv index 7f19724f3b..2a52602afc 100644 Binary files a/docs/inventories/v1.30/objects.inv and b/docs/inventories/v1.30/objects.inv differ diff --git a/docs/inventories/v1.31/objects.inv b/docs/inventories/v1.31/objects.inv new file mode 100644 index 0000000000..144ce7dbd8 Binary files /dev/null and b/docs/inventories/v1.31/objects.inv differ diff --git a/docs/root/api-v3/common_messages/common_messages_xds.rst b/docs/root/api-v3/common_messages/common_messages_xds.rst index 4147798a6f..7ae2a5e595 100644 --- a/docs/root/api-v3/common_messages/common_messages_xds.rst +++ b/docs/root/api-v3/common_messages/common_messages_xds.rst @@ -24,3 +24,4 @@ Common messages (XDS) ../../xds/core/v3/resource_locator.proto ../../xds/core/v3/resource_name.proto ../../xds/type/v3/typed_struct.proto + ../../xds/data/orca/v3/orca_load_report.proto diff --git a/docs/versions.yaml b/docs/versions.yaml index d3bb346bce..adc638b90e 100644 --- a/docs/versions.yaml +++ b/docs/versions.yaml @@ -21,6 +21,7 @@ "1.25": 1.25.11 "1.26": 1.26.8 "1.27": 1.27.7 -"1.28": 1.28.5 -"1.29": 1.29.7 -"1.30": 1.30.4 +"1.28": 1.28.6 +"1.29": 1.29.8 +"1.30": 1.30.5 +"1.31": 1.31.1 diff --git a/envoy/api/BUILD b/envoy/api/BUILD index 3ac0872aac..2753a6e624 100644 --- a/envoy/api/BUILD +++ b/envoy/api/BUILD @@ -36,8 +36,8 @@ envoy_cc_library( "os_sys_calls_hot_restart.h", "os_sys_calls_linux.h", ], - external_deps = ["abseil_optional"], deps = [ "//envoy/network:address_interface", + "@com_google_absl//absl/types:optional", ], ) diff --git a/envoy/buffer/BUILD b/envoy/buffer/BUILD index 6913dc1bd1..3ca278369d 100644 --- a/envoy/buffer/BUILD +++ b/envoy/buffer/BUILD @@ -11,9 +11,6 @@ envoy_package() envoy_cc_library( name = "buffer_interface", hdrs = ["buffer.h"], - external_deps = [ - "abseil_inlined_vector", - ], deps = [ "//envoy/api:os_sys_calls_interface", "//envoy/common:exception_lib", @@ -21,5 +18,6 @@ envoy_cc_library( "//source/common/common:assert_lib", "//source/common/common:byte_order_lib", "//source/common/common:utility_lib", + "@com_google_absl//absl/container:inlined_vector", ], ) diff --git a/envoy/common/BUILD b/envoy/common/BUILD index e1ee7d1f36..3c8680576e 100644 --- a/envoy/common/BUILD +++ b/envoy/common/BUILD @@ -14,7 +14,7 @@ envoy_basic_cc_library( hdrs = [ "platform.h", ], - external_deps = ["abseil_strings"], + deps = ["@com_google_absl//absl/strings"], ) envoy_basic_cc_library( @@ -39,7 +39,7 @@ envoy_basic_cc_library( hdrs = [ "optref.h", ], - external_deps = ["abseil_optional"], + deps = ["@com_google_absl//absl/types:optional"], ) envoy_cc_library( @@ -146,12 +146,10 @@ envoy_cc_library( hdrs = [ "union_string.h", ], - external_deps = [ - "abseil_inlined_vector", - "abseil_variant", - ], deps = [ "//source/common/common:assert_lib", "//source/common/common:utility_lib", + "@com_google_absl//absl/container:inlined_vector", + "@com_google_absl//absl/types:variant", ], ) diff --git a/envoy/config/BUILD b/envoy/config/BUILD index 6a24595f40..a76ac86f50 100644 --- a/envoy/config/BUILD +++ b/envoy/config/BUILD @@ -11,11 +11,11 @@ envoy_package() envoy_cc_library( name = "config_provider_interface", hdrs = ["config_provider.h"], - external_deps = ["abseil_optional"], deps = [ "//envoy/common:time_interface", "//source/common/common:assert_lib", "//source/common/protobuf", + "@com_google_absl//absl/types:optional", ], ) @@ -125,12 +125,12 @@ envoy_cc_library( envoy_cc_library( name = "xds_resources_delegate_interface", hdrs = ["xds_resources_delegate.h"], - external_deps = ["abseil_optional"], deps = [ ":subscription_interface", ":typed_config_interface", "//envoy/api:api_interface", "//envoy/protobuf:message_validator_interface", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/service/discovery/v3:pkg_cc_proto", ], ) diff --git a/envoy/grpc/BUILD b/envoy/grpc/BUILD index 62c5f36b1a..47b9631194 100644 --- a/envoy/grpc/BUILD +++ b/envoy/grpc/BUILD @@ -11,7 +11,6 @@ envoy_package() envoy_cc_library( name = "async_client_interface", hdrs = ["async_client.h"], - external_deps = ["abseil_optional"], deps = [ ":status", "//envoy/buffer:buffer_interface", @@ -21,6 +20,7 @@ envoy_cc_library( "//envoy/tracing:tracer_interface", "//source/common/common:assert_lib", "//source/common/protobuf", + "@com_google_absl//absl/types:optional", ], ) diff --git a/envoy/grpc/async_client.h b/envoy/grpc/async_client.h index eea2a37701..df9c2376f4 100644 --- a/envoy/grpc/async_client.h +++ b/envoy/grpc/async_client.h @@ -29,6 +29,11 @@ class AsyncRequest { * Signals that the request should be cancelled. No further callbacks will be invoked. */ virtual void cancel() PURE; + + /** + * Returns the underlying stream info. + */ + virtual const StreamInfo::StreamInfo& streamInfo() const PURE; }; /** diff --git a/envoy/http/BUILD b/envoy/http/BUILD index eea971bfec..0d4854c722 100644 --- a/envoy/http/BUILD +++ b/envoy/http/BUILD @@ -27,7 +27,6 @@ envoy_cc_library( envoy_cc_library( name = "async_client_interface", hdrs = ["async_client.h"], - external_deps = ["abseil_optional"], deps = [ ":filter_interface", ":message_interface", @@ -36,6 +35,7 @@ envoy_cc_library( "//envoy/tracing:tracer_interface", "//source/common/protobuf", "//source/common/protobuf:utility_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/route/v3:pkg_cc_proto", ], ) @@ -91,18 +91,17 @@ envoy_cc_library( envoy_cc_library( name = "filter_factory_interface", hdrs = ["filter_factory.h"], - external_deps = ["abseil_optional"], deps = [ ":header_map_interface", "//envoy/access_log:access_log_interface", "//envoy/grpc:status", + "@com_google_absl//absl/types:optional", ], ) envoy_cc_library( name = "filter_interface", hdrs = ["filter.h"], - external_deps = ["abseil_optional"], deps = [ ":codec_interface", ":filter_factory_interface", @@ -119,6 +118,7 @@ envoy_cc_library( "//envoy/tracing:tracer_interface", "//envoy/upstream:load_balancer_interface", "//source/common/common:scope_tracked_object_stack", + "@com_google_absl//absl/types:optional", ], ) @@ -135,15 +135,13 @@ envoy_cc_library( envoy_cc_library( name = "header_map_interface", hdrs = ["header_map.h"], - external_deps = [ - "abseil_inlined_vector", - ], deps = [ ":header_formatter_interface", "//envoy/common:union_string", "//envoy/stream_info:filter_state_interface", "//source/common/common:assert_lib", "//source/common/common:hash_lib", + "@com_google_absl//absl/container:inlined_vector", ], ) @@ -164,13 +162,13 @@ envoy_cc_library( envoy_cc_library( name = "query_params_interface", hdrs = ["query_params.h"], - external_deps = ["abseil_btree"], + deps = ["@com_google_absl//absl/container:btree"], ) envoy_cc_library( name = "metadata_interface", hdrs = ["metadata_interface.h"], - external_deps = ["abseil_node_hash_map"], + deps = ["@com_google_absl//absl/container:node_hash_map"], ) envoy_cc_library( diff --git a/envoy/matcher/BUILD b/envoy/matcher/BUILD index 604c1bf4a8..63f02e8a20 100644 --- a/envoy/matcher/BUILD +++ b/envoy/matcher/BUILD @@ -11,14 +11,12 @@ envoy_package() envoy_cc_library( name = "matcher_interface", hdrs = ["matcher.h"], - external_deps = [ - "abseil_base", - "abseil_hash", - ], deps = [ "//envoy/config:typed_config_interface", "//envoy/protobuf:message_validator_interface", "@com_github_cncf_xds//xds/type/matcher/v3:pkg_cc_proto", + "@com_google_absl//absl/base", + "@com_google_absl//absl/hash", "@envoy_api//envoy/config/common/matcher/v3:pkg_cc_proto", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], diff --git a/envoy/network/BUILD b/envoy/network/BUILD index cef61c8cb9..f40b97d530 100644 --- a/envoy/network/BUILD +++ b/envoy/network/BUILD @@ -20,7 +20,6 @@ envoy_cc_library( envoy_cc_library( name = "connection_interface", hdrs = ["connection.h"], - external_deps = ["abseil_int128"], deps = [ ":address_interface", ":filter_interface", @@ -29,6 +28,7 @@ envoy_cc_library( "//envoy/event:deferred_deletable", "//envoy/ssl:connection_interface", "//envoy/stream_info:stream_info_interface", + "@com_google_absl//absl/numeric:int128", ], ) @@ -99,8 +99,10 @@ envoy_cc_library( envoy_cc_library( name = "drain_decision_interface", hdrs = ["drain_decision.h"], - external_deps = ["abseil_base"], - deps = ["//envoy/common:callback"], + deps = [ + "//envoy/common:callback", + "@com_google_absl//absl/base", + ], ) envoy_cc_library( @@ -126,16 +128,15 @@ envoy_cc_library( envoy_cc_library( name = "hash_policy_interface", hdrs = ["hash_policy.h"], - external_deps = ["abseil_optional"], deps = [ ":connection_interface", + "@com_google_absl//absl/types:optional", ], ) envoy_cc_library( name = "io_handle_interface", hdrs = ["io_handle.h"], - external_deps = ["abseil_optional"], deps = [ ":address_interface", "//envoy/api:io_error_interface", @@ -143,6 +144,7 @@ envoy_cc_library( "//envoy/buffer:buffer_interface", "//envoy/event:file_event_interface", "//source/common/common:assert_lib", + "@com_google_absl//absl/types:optional", ], ) diff --git a/envoy/router/BUILD b/envoy/router/BUILD index 9e03be2321..33af45f78f 100644 --- a/envoy/router/BUILD +++ b/envoy/router/BUILD @@ -49,11 +49,11 @@ envoy_cc_library( envoy_cc_library( name = "route_config_update_info_interface", hdrs = ["route_config_update_receiver.h"], - external_deps = ["abseil_optional"], deps = [ ":rds_interface", "//envoy/common:time_interface", "//source/common/protobuf", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/route/v3:pkg_cc_proto", "@envoy_api//envoy/service/discovery/v3:pkg_cc_proto", ], @@ -62,7 +62,6 @@ envoy_cc_library( envoy_cc_library( name = "router_filter_interface", hdrs = ["router_filter_interface.h"], - external_deps = ["abseil_optional"], deps = [ "//envoy/http:filter_interface", "//envoy/http:header_map_interface", @@ -70,13 +69,13 @@ envoy_cc_library( "//envoy/stream_info:stream_info_interface", "//envoy/upstream:cluster_manager_interface", "//envoy/upstream:host_description_interface", + "@com_google_absl//absl/types:optional", ], ) envoy_cc_library( name = "router_interface", hdrs = ["router.h"], - external_deps = ["abseil_optional"], deps = [ ":internal_redirect_interface", ":path_matcher_interface", @@ -98,6 +97,7 @@ envoy_cc_library( "//envoy/upstream:retry_interface", "//source/common/protobuf", "//source/common/protobuf:utility_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/config/route/v3:pkg_cc_proto", "@envoy_api//envoy/type/v3:pkg_cc_proto", @@ -136,9 +136,9 @@ envoy_cc_library( envoy_cc_library( name = "string_accessor_interface", hdrs = ["string_accessor.h"], - external_deps = ["abseil_optional"], deps = [ "//envoy/stream_info:filter_state_interface", + "@com_google_absl//absl/types:optional", ], ) diff --git a/envoy/runtime/BUILD b/envoy/runtime/BUILD index da5c1527ab..4a384841ed 100644 --- a/envoy/runtime/BUILD +++ b/envoy/runtime/BUILD @@ -11,15 +11,13 @@ envoy_package() envoy_cc_library( name = "runtime_interface", hdrs = ["runtime.h"], - external_deps = [ - "abseil_node_hash_map", - "abseil_optional", - ], deps = [ "//envoy/stats:stats_interface", "//envoy/thread_local:thread_local_object", "//source/common/common:assert_lib", "//source/common/singleton:threadsafe_singleton", + "@com_google_absl//absl/container:node_hash_map", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/type/v3:pkg_cc_proto", ], ) diff --git a/envoy/server/BUILD b/envoy/server/BUILD index 0ea9b6a3b5..b7b22fde0a 100644 --- a/envoy/server/BUILD +++ b/envoy/server/BUILD @@ -30,11 +30,11 @@ envoy_cc_library( envoy_cc_library( name = "configuration_interface", hdrs = ["configuration.h"], - external_deps = ["abseil_optional"], deps = [ "//envoy/http:context_interface", "//envoy/stats:sink_interface", "//envoy/upstream:cluster_manager_interface", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", ], ) diff --git a/envoy/ssl/BUILD b/envoy/ssl/BUILD index beb3102764..89efc64bf0 100644 --- a/envoy/ssl/BUILD +++ b/envoy/ssl/BUILD @@ -11,10 +11,10 @@ envoy_package() envoy_cc_library( name = "connection_interface", hdrs = ["connection.h"], - external_deps = ["abseil_optional"], deps = [ ":ssl_socket_state", "//envoy/common:time_interface", + "@com_google_absl//absl/types:optional", ], ) @@ -61,8 +61,8 @@ envoy_cc_library( envoy_cc_library( name = "certificate_validation_context_config_interface", hdrs = ["certificate_validation_context_config.h"], - external_deps = ["abseil_optional"], deps = [ + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/extensions/transport_sockets/tls/v3:pkg_cc_proto", "@envoy_api//envoy/type/matcher/v3:pkg_cc_proto", ], diff --git a/envoy/stats/BUILD b/envoy/stats/BUILD index d707c449b0..20815c1ec7 100644 --- a/envoy/stats/BUILD +++ b/envoy/stats/BUILD @@ -32,13 +32,13 @@ envoy_cc_library( "tag_extractor.h", "tag_producer.h", ], - external_deps = ["abseil_inlined_vector"], deps = [ ":refcount_ptr_interface", ":tag_interface", "//envoy/common:interval_set_interface", "//envoy/common:optref_lib", "//envoy/common:time_interface", + "@com_google_absl//absl/container:inlined_vector", ], ) diff --git a/envoy/stream_info/BUILD b/envoy/stream_info/BUILD index cb79d23921..ad7a490ecc 100644 --- a/envoy/stream_info/BUILD +++ b/envoy/stream_info/BUILD @@ -11,7 +11,6 @@ envoy_package() envoy_cc_library( name = "stream_info_interface", hdrs = ["stream_info.h"], - external_deps = ["abseil_optional"], deps = [ ":filter_state_interface", ":stream_id_provider_interface", @@ -25,6 +24,7 @@ envoy_cc_library( "//source/common/common:assert_lib", "//source/common/protobuf", "//source/common/singleton:const_singleton", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], ) @@ -32,12 +32,12 @@ envoy_cc_library( envoy_cc_library( name = "filter_state_interface", hdrs = ["filter_state.h"], - external_deps = ["abseil_optional"], deps = [ "//envoy/config:typed_config_interface", "//source/common/common:fmt_lib", "//source/common/common:utility_lib", "//source/common/protobuf", + "@com_google_absl//absl/types:optional", ], ) diff --git a/envoy/thread/thread.h b/envoy/thread/thread.h index 7b969f3e2c..0093a7b520 100644 --- a/envoy/thread/thread.h +++ b/envoy/thread/thread.h @@ -55,7 +55,16 @@ using ThreadPtr = std::unique_ptr; // Options specified during thread creation. struct Options { - std::string name_; // A name supplied for the thread. On Linux this is limited to 15 chars. + // A name supplied for the thread. On Linux this is limited to 15 chars. + std::string name_; + // An optional thread priority for the thread. The value will mean different things on different + // platforms. For example, on Linux or Android, the values can range from -20 to 19. On Apple + // platforms, the value can range from 1 to 100, which is used to divide by 100 to get a [0,1] + // value that can be used on Apple's NSThread.setThreadPriority method. + // + // If no value is set, the thread will be created with the default thread priority for the + // platform. + absl::optional priority_{absl::nullopt}; }; using OptionsOptConstRef = const absl::optional&; @@ -79,7 +88,7 @@ class ThreadFactory { /** * Return the current system thread ID */ - virtual ThreadId currentThreadId() PURE; + virtual ThreadId currentThreadId() const PURE; }; using ThreadFactoryPtr = std::unique_ptr; diff --git a/envoy/udp/BUILD b/envoy/udp/BUILD index 8454b0e897..e89a26ea31 100644 --- a/envoy/udp/BUILD +++ b/envoy/udp/BUILD @@ -11,8 +11,8 @@ envoy_package() envoy_cc_library( name = "hash_policy_interface", hdrs = ["hash_policy.h"], - external_deps = ["abseil_optional"], deps = [ "//envoy/network:address_interface", + "@com_google_absl//absl/types:optional", ], ) diff --git a/envoy/upstream/BUILD b/envoy/upstream/BUILD index 0ea30e9fb3..ec48479d79 100644 --- a/envoy/upstream/BUILD +++ b/envoy/upstream/BUILD @@ -11,9 +11,6 @@ envoy_package() envoy_cc_library( name = "cluster_manager_interface", hdrs = ["cluster_manager.h"], - external_deps = [ - "abseil_node_hash_map", - ], deps = [ ":health_checker_interface", ":load_balancer_interface", @@ -35,6 +32,7 @@ envoy_cc_library( "//envoy/singleton:manager_interface", "//envoy/tcp:conn_pool_interface", "//envoy/thread_local:thread_local_interface", + "@com_google_absl//absl/container:node_hash_map", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/config/cluster/v3:pkg_cc_proto", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", @@ -102,9 +100,9 @@ envoy_cc_library( envoy_cc_library( name = "outlier_detection_interface", hdrs = ["outlier_detection.h"], - external_deps = ["abseil_optional"], deps = [ "//envoy/common:time_interface", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/data/cluster/v3:pkg_cc_proto", ], ) @@ -147,7 +145,6 @@ envoy_cc_library( envoy_cc_library( name = "upstream_interface", hdrs = ["upstream.h"], - external_deps = ["abseil_optional"], deps = [ ":health_check_host_monitor_interface", ":locality_lib", @@ -164,6 +161,7 @@ envoy_cc_library( "//envoy/ssl:context_interface", "//envoy/ssl:context_manager_interface", "//envoy/upstream:types_interface", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/cluster/v3:pkg_cc_proto", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], diff --git a/go.mod b/go.mod index 0837f8f31a..ecd12d00ec 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,7 @@ module github.com/envoyproxy/envoy -go 1.20 +go 1.23 -require google.golang.org/protobuf v1.34.1 +require google.golang.org/protobuf v1.34.2 require github.com/google/go-cmp v0.5.9 // indirect diff --git a/go.sum b/go.sum index c98d9cdfd6..2fc4d88980 100644 --- a/go.sum +++ b/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= diff --git a/mobile/examples/cc/fetch_client/BUILD b/mobile/examples/cc/fetch_client/BUILD index 70f4c4900a..67afac03f1 100644 --- a/mobile/examples/cc/fetch_client/BUILD +++ b/mobile/examples/cc/fetch_client/BUILD @@ -16,13 +16,13 @@ envoy_cc_library( hdrs = [ "fetch_client.h", ], - external_deps = ["abseil_synchronization"], repository = "@envoy", deps = [ "//library/cc:engine_builder_lib", "//library/common/http:client_lib", "//library/common/http:header_utility_lib", "//library/common/types:c_types_lib", + "@com_google_absl//absl/synchronization", "@envoy//envoy/http:header_map_interface", "@envoy//source/common/http:header_map_lib", ], diff --git a/mobile/library/cc/BUILD b/mobile/library/cc/BUILD index 24e706ee18..d3cad91906 100644 --- a/mobile/library/cc/BUILD +++ b/mobile/library/cc/BUILD @@ -20,11 +20,11 @@ envoy_cc_library( "//bazel:exclude_certificates": ["-DEXCLUDE_CERTIFICATES"], "//conditions:default": [], }), - external_deps = ["abseil_optional"], repository = "@envoy", visibility = ["//visibility:public"], deps = [ ":envoy_engine_cc_lib_no_stamp", + "@com_google_absl//absl/types:optional", "@envoy//source/common/common:assert_lib", "@envoy//source/common/protobuf", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", @@ -75,7 +75,6 @@ envoy_cc_library( "stream_prototype.h", "string_accessor.h", ], - external_deps = ["abseil_optional"], repository = "@envoy", visibility = ["//visibility:public"], deps = [ @@ -84,6 +83,7 @@ envoy_cc_library( "//library/common/api:c_types", "//library/common/bridge:utility_lib", "//library/common/extensions/key_value/platform:config", + "@com_google_absl//absl/types:optional", "@envoy//source/common/buffer:buffer_lib", "@envoy//source/common/http:header_map_lib", "@envoy//source/common/http:utility_lib", diff --git a/mobile/library/cc/engine_builder.cc b/mobile/library/cc/engine_builder.cc index 0d1ffc57a1..53518b8cd9 100644 --- a/mobile/library/cc/engine_builder.cc +++ b/mobile/library/cc/engine_builder.cc @@ -56,6 +56,11 @@ EngineBuilder& EngineBuilder::setUseCares(bool use_cares) { use_cares_ = use_cares; return *this; } + +EngineBuilder& EngineBuilder::addCaresFallbackResolver(std::string host, int port) { + cares_fallback_resolvers_.emplace_back(std::move(host), port); + return *this; +} #endif EngineBuilder& EngineBuilder::setLogLevel(Logger::Logger::Levels log_level) { log_level_ = log_level; @@ -491,6 +496,14 @@ std::unique_ptr EngineBuilder::generate #else if (use_cares_) { envoy::extensions::network::dns_resolver::cares::v3::CaresDnsResolverConfig resolver_config; + if (!cares_fallback_resolvers_.empty()) { + for (const auto& [host, port] : cares_fallback_resolvers_) { + auto* address = resolver_config.add_resolvers(); + address->mutable_socket_address()->set_address(host); + address->mutable_socket_address()->set_port_value(port); + } + resolver_config.set_use_resolvers_as_fallback(true); + } dns_cache_config->mutable_typed_dns_resolver_config()->set_name( "envoy.network.dns_resolver.cares"); dns_cache_config->mutable_typed_dns_resolver_config()->mutable_typed_config()->PackFrom( @@ -554,6 +567,9 @@ std::unique_ptr EngineBuilder::generate if (platform_certificates_validation_on_) { envoy_mobile::extensions::cert_validator::platform_bridge::PlatformBridgeCertValidator validator; + if (network_thread_priority_.has_value()) { + validator.mutable_thread_priority()->set_value(*network_thread_priority_); + } validation->mutable_custom_validator_config()->set_name( "envoy_mobile.cert_validator.platform_bridge_cert_validator"); validation->mutable_custom_validator_config()->mutable_typed_config()->PackFrom(validator); diff --git a/mobile/library/cc/engine_builder.h b/mobile/library/cc/engine_builder.h index cb2c0d06b9..7636eab146 100644 --- a/mobile/library/cc/engine_builder.h +++ b/mobile/library/cc/engine_builder.h @@ -114,6 +114,7 @@ class EngineBuilder { #else // Only android supports c_ares EngineBuilder& setUseCares(bool use_cares); + EngineBuilder& addCaresFallbackResolver(std::string host, int port); #endif // This is separated from build() for the sake of testability @@ -169,6 +170,7 @@ class EngineBuilder { bool enable_http3_ = true; #if !defined(__APPLE__) bool use_cares_ = false; + std::vector> cares_fallback_resolvers_; #endif std::string http3_connection_options_ = ""; std::string http3_client_connection_options_ = ""; diff --git a/mobile/library/common/event/BUILD b/mobile/library/common/event/BUILD index b50a08a0bf..2219fd750a 100644 --- a/mobile/library/common/event/BUILD +++ b/mobile/library/common/event/BUILD @@ -8,10 +8,10 @@ envoy_cc_library( name = "provisional_dispatcher_lib", srcs = ["provisional_dispatcher.cc"], hdrs = ["provisional_dispatcher.h"], - external_deps = ["abseil_optional"], repository = "@envoy", deps = [ "//library/common/types:c_types_lib", + "@com_google_absl//absl/types:optional", "@envoy//envoy/event:deferred_deletable", "@envoy//envoy/event:dispatcher_interface", "@envoy//source/common/common:lock_guard_lib", diff --git a/mobile/library/common/extensions/cert_validator/platform_bridge/BUILD b/mobile/library/common/extensions/cert_validator/platform_bridge/BUILD index b6493dfe6f..682ae1b07d 100644 --- a/mobile/library/common/extensions/cert_validator/platform_bridge/BUILD +++ b/mobile/library/common/extensions/cert_validator/platform_bridge/BUILD @@ -38,6 +38,7 @@ envoy_cc_library( "@envoy//envoy/thread:thread_interface", "@envoy//source/common/common:macros", "@envoy//source/common/common:thread_impl_lib_posix", + "@envoy//source/common/config:utility_lib", "@envoy//source/common/tls/cert_validator:cert_validator_lib", ], ) diff --git a/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge.proto b/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge.proto index e44e013151..6aeb60ad7d 100644 --- a/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge.proto +++ b/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge.proto @@ -2,5 +2,15 @@ syntax = "proto3"; package envoy_mobile.extensions.cert_validator.platform_bridge; +import "google/protobuf/wrappers.proto"; + +// Configuration for the platform bridge cert validator. message PlatformBridgeCertValidator { + // The thread priority that will be set on the thread that is created to execute platform cert + // validation. The exact values and meaning of the thread priority is OS dependent. For example, + // on Android, the values range from -20 to 19. On iOS, supply a value between 1 to 100, which + // will be divided by 100 to provide a value to the OS in the range of 0 to 1. + // + // If this field is not set, the platform-specific default thread priorities will be used. + google.protobuf.Int32Value thread_priority = 1; } diff --git a/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator.cc b/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator.cc index 1d6ffbfc33..cc162a29b0 100644 --- a/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator.cc +++ b/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator.cc @@ -3,7 +3,11 @@ #include #include +#include "source/common/config/utility.h" +#include "source/common/protobuf/message_validator_impl.h" + #include "library/common/bridge//utility.h" +#include "library/common/extensions/cert_validator/platform_bridge/platform_bridge.pb.h" #include "library/common/system/system_helper.h" namespace Envoy { @@ -22,6 +26,15 @@ PlatformBridgeCertValidator::PlatformBridgeCertValidator( ENVOY_BUG(config != nullptr && config->caCert().empty() && config->certificateRevocationList().empty(), "Invalid certificate validation context config."); + if (config != nullptr && config->customValidatorConfig().has_value()) { + envoy_mobile::extensions::cert_validator::platform_bridge::PlatformBridgeCertValidator cfg; + Envoy::Config::Utility::translateOpaqueConfig( + config->customValidatorConfig().value().typed_config(), + ProtobufMessage::getStrictValidationVisitor(), cfg); + if (cfg.has_thread_priority()) { + thread_priority_ = cfg.thread_priority().value(); + } + } } PlatformBridgeCertValidator::PlatformBridgeCertValidator( @@ -89,12 +102,14 @@ ValidationResults PlatformBridgeCertValidator::doVerifyCertChain( ValidationJob job; job.result_callback_ = std::move(callback); Event::Dispatcher& dispatcher = job.result_callback_->dispatcher(); + Thread::Options thread_options; + thread_options.priority_ = thread_priority_; job.validation_thread_ = thread_factory_->createThread( [this, &dispatcher, certs = std::move(certs), host = std::string(host), subject_alt_names = std::move(subject_alt_names)]() -> void { - verifyCertChainByPlatform(&dispatcher, certs, host, subject_alt_names, this); + verifyCertChainByPlatform(&dispatcher, certs, host, subject_alt_names); }, - /* options= */ absl::nullopt, /* crash_on_failure=*/false); + thread_options, /* crash_on_failure=*/false); if (job.validation_thread_ == nullptr) { return {ValidationResults::ValidationStatus::Failed, Envoy::Ssl::ClientValidationStatus::NotValidated, absl::nullopt, @@ -108,7 +123,7 @@ ValidationResults PlatformBridgeCertValidator::doVerifyCertChain( void PlatformBridgeCertValidator::verifyCertChainByPlatform( Event::Dispatcher* dispatcher, std::vector cert_chain, std::string hostname, - std::vector subject_alt_names, PlatformBridgeCertValidator* parent) { + std::vector subject_alt_names) { ASSERT(!cert_chain.empty()); ENVOY_LOG(trace, "Start verifyCertChainByPlatform for host {}", hostname); // This is running in a stand alone thread other than the engine thread. @@ -122,7 +137,7 @@ void PlatformBridgeCertValidator::verifyCertChainByPlatform( if (!success) { ENVOY_LOG(debug, result.error_details); postVerifyResultAndCleanUp(success, std::move(hostname), result.error_details, result.tls_alert, - ValidationFailureType::FailVerifyError, dispatcher, parent); + ValidationFailureType::FailVerifyError, dispatcher, this); return; } @@ -135,12 +150,12 @@ void PlatformBridgeCertValidator::verifyCertChainByPlatform( error_details = "PlatformBridgeCertValidator_verifySubjectAltName failed: SNI mismatch."; ENVOY_LOG(debug, error_details); postVerifyResultAndCleanUp(success, std::move(hostname), error_details, SSL_AD_BAD_CERTIFICATE, - ValidationFailureType::FailVerifySan, dispatcher, parent); + ValidationFailureType::FailVerifySan, dispatcher, this); return; } postVerifyResultAndCleanUp(success, std::move(hostname), error_details, SSL_AD_CERTIFICATE_UNKNOWN, ValidationFailureType::Success, dispatcher, - parent); + this); } void PlatformBridgeCertValidator::postVerifyResultAndCleanUp(bool success, std::string hostname, diff --git a/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator.h b/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator.h index 7bde7390a3..54f187b6fc 100644 --- a/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator.h +++ b/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator.h @@ -57,12 +57,7 @@ class PlatformBridgeCertValidator : public CertValidator, Logger::Loggable cert_chain, std::string hostname, - std::vector subject_alt_names, - PlatformBridgeCertValidator* parent); + // + // `protected` for testing purposes. + virtual void verifyCertChainByPlatform(Event::Dispatcher* dispatcher, + std::vector cert_chain, std::string hostname, + std::vector subject_alt_names); // Must be called on the validation thread. + // `protected` for testing purposes. static void postVerifyResultAndCleanUp(bool success, std::string hostname, absl::string_view error_details, uint8_t tls_alert, ValidationFailureType failure_type, Event::Dispatcher* dispatcher, PlatformBridgeCertValidator* parent); +private: + GTEST_FRIEND_CLASS(PlatformBridgeCertValidatorTest, ThreadCreationFailed); + + PlatformBridgeCertValidator(const Envoy::Ssl::CertificateValidationContextConfig* config, + SslStats& stats, Thread::PosixThreadFactoryPtr thread_factory); + // Called when a pending verification completes. Must be invoked on the main thread. void onVerificationComplete(const Thread::ThreadId& thread_id, const std::string& hostname, bool success, const std::string& error_details, uint8_t tls_alert, @@ -100,6 +103,7 @@ class PlatformBridgeCertValidator : public CertValidator, Logger::Loggable validation_jobs_; std::shared_ptr alive_indicator_{new size_t(1)}; Thread::PosixThreadFactoryPtr thread_factory_; + absl::optional thread_priority_; }; } // namespace Tls diff --git a/mobile/library/common/http/BUILD b/mobile/library/common/http/BUILD index f2d693855d..e3a82e5ef9 100644 --- a/mobile/library/common/http/BUILD +++ b/mobile/library/common/http/BUILD @@ -8,7 +8,6 @@ envoy_cc_library( name = "client_lib", srcs = ["client.cc"], hdrs = ["client.h"], - external_deps = ["abseil_optional"], repository = "@envoy", deps = [ ":header_utility_lib", @@ -23,6 +22,7 @@ envoy_cc_library( "//library/common/stream_info:extra_stream_info_lib", "//library/common/system:system_helper_lib", "//library/common/types:c_types_lib", + "@com_google_absl//absl/types:optional", "@envoy//envoy/buffer:buffer_interface", "@envoy//envoy/common:scope_tracker_interface", "@envoy//envoy/event:deferred_deletable", diff --git a/mobile/library/common/internal_engine.cc b/mobile/library/common/internal_engine.cc index 708daf1112..4ca9a9075e 100644 --- a/mobile/library/common/internal_engine.cc +++ b/mobile/library/common/internal_engine.cc @@ -95,20 +95,10 @@ envoy_status_t InternalEngine::cancelStream(envoy_stream_t stream) { // copy-constructible type, so it's not possible to move capture `std::unique_ptr` with // `std::function`. envoy_status_t InternalEngine::run(std::shared_ptr options) { - main_thread_ = thread_factory_->createThread( - [this, options]() mutable -> void { - if (thread_priority_) { - // Set the thread priority before invoking the thread routine. - const int rc = setpriority(PRIO_PROCESS, thread_factory_->currentThreadId().getId(), - *thread_priority_); - if (rc != 0) { - ENVOY_LOG(debug, "failed to set thread priority: {}", Envoy::errorDetails(errno)); - } - } - - main(options); - }, - /* options= */ absl::nullopt, /* crash_on_failure= */ false); + Thread::Options thread_options; + thread_options.priority_ = thread_priority_; + main_thread_ = thread_factory_->createThread([this, options]() mutable -> void { main(options); }, + thread_options, /* crash_on_failure= */ false); return (main_thread_ != nullptr) ? ENVOY_SUCCESS : ENVOY_FAILURE; } @@ -330,7 +320,9 @@ envoy_status_t InternalEngine::recordCounterInc(absl::string_view elements, envo }); } -Event::ProvisionalDispatcher& InternalEngine::dispatcher() { return *dispatcher_; } +Event::ProvisionalDispatcher& InternalEngine::dispatcher() const { return *dispatcher_; } + +Thread::PosixThreadFactory& InternalEngine::threadFactory() const { return *thread_factory_; } void statsAsText(const std::map& all_stats, const std::vector& histograms, diff --git a/mobile/library/common/internal_engine.h b/mobile/library/common/internal_engine.h index 2c0323cfb7..7566d2f4cb 100644 --- a/mobile/library/common/internal_engine.h +++ b/mobile/library/common/internal_engine.h @@ -56,7 +56,12 @@ class InternalEngine : public Logger::Loggable { * Accessor for the provisional event dispatcher. * @return Event::ProvisionalDispatcher&, the engine dispatcher. */ - Event::ProvisionalDispatcher& dispatcher(); + Event::ProvisionalDispatcher& dispatcher() const; + + /** + * Accessor for the thread factory. + */ + Thread::PosixThreadFactory& threadFactory() const; envoy_stream_t initStream(); @@ -158,6 +163,7 @@ class InternalEngine : public Logger::Loggable { Stats::Store& getStatsStore(); private: + // Needs access to the private constructor. GTEST_FRIEND_CLASS(InternalEngineTest, ThreadCreationFailed); InternalEngine(std::unique_ptr callbacks, std::unique_ptr logger, diff --git a/mobile/library/java/io/envoyproxy/envoymobile/engine/EnvoyConfiguration.java b/mobile/library/java/io/envoyproxy/envoymobile/engine/EnvoyConfiguration.java index a87b74d9f3..40f6f4dfc0 100644 --- a/mobile/library/java/io/envoyproxy/envoymobile/engine/EnvoyConfiguration.java +++ b/mobile/library/java/io/envoyproxy/envoymobile/engine/EnvoyConfiguration.java @@ -1,5 +1,6 @@ package io.envoyproxy.envoymobile.engine; +import android.util.Pair; import java.util.Collections; import java.util.List; import java.util.ArrayList; @@ -36,6 +37,7 @@ public enum TrustChainVerification { public final boolean enableDrainPostDnsRefresh; public final boolean enableHttp3; public final boolean useCares; + public final List> caresFallbackResolvers; public final boolean forceV6; public final boolean useGro; public final String http3ConnectionOptions; @@ -126,6 +128,8 @@ public enum TrustChainVerification { * @param keyValueStores platform key-value store implementations. * @param enablePlatformCertificatesValidation whether to use the platform verifier. * @param upstreamTlsSni the upstream TLS socket SNI override. + * @param caresFallbackResolvers A list of host port pair that's used as + * c-ares's fallback resolvers. */ public EnvoyConfiguration( int connectTimeoutSeconds, int dnsRefreshSeconds, int dnsFailureRefreshSecondsBase, @@ -144,7 +148,8 @@ public EnvoyConfiguration( List httpPlatformFilterFactories, Map stringAccessors, Map keyValueStores, Map runtimeGuards, - boolean enablePlatformCertificatesValidation, String upstreamTlsSni) { + boolean enablePlatformCertificatesValidation, String upstreamTlsSni, + List> caresFallbackResolvers) { JniLibrary.load(); this.connectTimeoutSeconds = connectTimeoutSeconds; this.dnsRefreshSeconds = dnsRefreshSeconds; @@ -159,6 +164,11 @@ public EnvoyConfiguration( this.enableDrainPostDnsRefresh = enableDrainPostDnsRefresh; this.enableHttp3 = enableHttp3; this.useCares = useCares; + this.caresFallbackResolvers = new ArrayList<>(); + for (Pair hostAndPort : caresFallbackResolvers) { + this.caresFallbackResolvers.add( + new Pair(hostAndPort.first, String.valueOf(hostAndPort.second))); + } this.forceV6 = forceV6; this.useGro = useGro; this.http3ConnectionOptions = http3ConnectionOptions; @@ -215,6 +225,8 @@ public long createBootstrap() { byte[][] runtimeGuards = JniBridgeUtility.mapToJniBytes(this.runtimeGuards); byte[][] quicHints = JniBridgeUtility.mapToJniBytes(this.quicHints); byte[][] quicSuffixes = JniBridgeUtility.stringsToJniBytes(quicCanonicalSuffixes); + byte[][] caresFallbackResolvers = + JniBridgeUtility.listOfStringPairsToJniBytes(this.caresFallbackResolvers); return JniLibrary.createBootstrap( connectTimeoutSeconds, dnsRefreshSeconds, dnsFailureRefreshSecondsBase, @@ -226,6 +238,6 @@ public long createBootstrap() { h2ConnectionKeepaliveIdleIntervalMilliseconds, h2ConnectionKeepaliveTimeoutSeconds, maxConnectionsPerHost, streamIdleTimeoutSeconds, perTryIdleTimeoutSeconds, appVersion, appId, enforceTrustChainVerification, filterChain, enablePlatformCertificatesValidation, - upstreamTlsSni, runtimeGuards); + upstreamTlsSni, runtimeGuards, caresFallbackResolvers); } } diff --git a/mobile/library/java/io/envoyproxy/envoymobile/engine/JniBridgeUtility.java b/mobile/library/java/io/envoyproxy/envoymobile/engine/JniBridgeUtility.java index bcd5cd7c48..60c0b66745 100644 --- a/mobile/library/java/io/envoyproxy/envoymobile/engine/JniBridgeUtility.java +++ b/mobile/library/java/io/envoyproxy/envoymobile/engine/JniBridgeUtility.java @@ -1,5 +1,6 @@ package io.envoyproxy.envoymobile.engine; +import android.util.Pair; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; @@ -57,6 +58,15 @@ public static byte[][] mapToJniBytes(Map stringMap) { return convertedBytes.toArray(new byte[0][0]); } + public static byte[][] listOfStringPairsToJniBytes(List> stringList) { + final List convertedBytes = new ArrayList(stringList.size() * 2); + for (Pair entry : stringList) { + convertedBytes.add(entry.first.getBytes(StandardCharsets.UTF_8)); + convertedBytes.add(entry.second.getBytes(StandardCharsets.UTF_8)); + } + return convertedBytes.toArray(new byte[0][0]); + } + public static byte[][] toJniTags(Map tags) { if (tags == null) { return null; diff --git a/mobile/library/java/io/envoyproxy/envoymobile/engine/JniLibrary.java b/mobile/library/java/io/envoyproxy/envoymobile/engine/JniLibrary.java index bb1d255079..fc728abdba 100644 --- a/mobile/library/java/io/envoyproxy/envoymobile/engine/JniLibrary.java +++ b/mobile/library/java/io/envoyproxy/envoymobile/engine/JniLibrary.java @@ -311,7 +311,8 @@ public static native long createBootstrap( long h2ConnectionKeepaliveIdleIntervalMilliseconds, long h2ConnectionKeepaliveTimeoutSeconds, long maxConnectionsPerHost, long streamIdleTimeoutSeconds, long perTryIdleTimeoutSeconds, String appVersion, String appId, boolean trustChainVerification, byte[][] filterChain, - boolean enablePlatformCertificatesValidation, String upstreamTlsSni, byte[][] runtimeGuards); + boolean enablePlatformCertificatesValidation, String upstreamTlsSni, byte[][] runtimeGuards, + byte[][] cares_fallback_resolvers); /** * Initializes c-ares. diff --git a/mobile/library/java/org/chromium/net/impl/NativeCronvoyEngineBuilderImpl.java b/mobile/library/java/org/chromium/net/impl/NativeCronvoyEngineBuilderImpl.java index 1292387f4e..8cdaed009a 100644 --- a/mobile/library/java/org/chromium/net/impl/NativeCronvoyEngineBuilderImpl.java +++ b/mobile/library/java/org/chromium/net/impl/NativeCronvoyEngineBuilderImpl.java @@ -4,6 +4,7 @@ import java.nio.charset.StandardCharsets; import android.content.Context; +import android.util.Pair; import androidx.annotation.VisibleForTesting; import com.google.protobuf.Struct; import io.envoyproxy.envoymobile.engine.AndroidEngineImpl; @@ -50,6 +51,7 @@ public class NativeCronvoyEngineBuilderImpl extends CronvoyEngineBuilderImpl { private final List mDnsFallbackNameservers = Collections.emptyList(); private final boolean mEnableDnsFilterUnroutableFamilies = true; private boolean mUseCares = false; + private final List> mCaresFallbackResolvers = new ArrayList<>(); private boolean mForceV6 = true; private boolean mUseGro = false; private boolean mEnableDrainPostDnsRefresh = false; @@ -98,6 +100,17 @@ public NativeCronvoyEngineBuilderImpl setUseCares(boolean enable) { return this; } + /** + * Add a fallback resolver to c_cares. + * + * @param host ip address string + * @param port port for the resolver + */ + public NativeCronvoyEngineBuilderImpl addCaresFallbackResolver(String host, int port) { + mCaresFallbackResolvers.add(new Pair(host, port)); + return this; + } + /** * Set whether to map v4 address to v6. * @@ -283,6 +296,6 @@ mUseGro, quicConnectionOptions(), quicClientConnectionOptions(), quicHints(), mH2ConnectionKeepaliveTimeoutSeconds, mMaxConnectionsPerHost, mStreamIdleTimeoutSeconds, mPerTryIdleTimeoutSeconds, mAppVersion, mAppId, mTrustChainVerification, nativeFilterChain, platformFilterChain, stringAccessors, keyValueStores, mRuntimeGuards, - mEnablePlatformCertificatesValidation, mUpstreamTlsSni); + mEnablePlatformCertificatesValidation, mUpstreamTlsSni, mCaresFallbackResolvers); } } diff --git a/mobile/library/jni/jni_impl.cc b/mobile/library/jni/jni_impl.cc index 4fcf589776..fd8d0de69c 100644 --- a/mobile/library/jni/jni_impl.cc +++ b/mobile/library/jni/jni_impl.cc @@ -1230,6 +1230,7 @@ void configureBuilder(Envoy::JNI::JniHelper& jni_helper, jlong connect_timeout_s jstring app_version, jstring app_id, jboolean trust_chain_verification, jobjectArray filter_chain, jboolean enable_platform_certificates_validation, jstring upstream_tls_sni, jobjectArray runtime_guards, + jobjectArray cares_fallback_resolvers, Envoy::Platform::EngineBuilder& builder) { builder.addConnectTimeoutSeconds((connect_timeout_seconds)); builder.addDnsRefreshSeconds((dns_refresh_seconds)); @@ -1271,6 +1272,12 @@ void configureBuilder(Envoy::JNI::JniHelper& jni_helper, jlong connect_timeout_s } builder.enablePortMigration(enable_port_migration); builder.setUseCares(use_cares == JNI_TRUE); + if (use_cares == JNI_TRUE) { + auto resolvers = javaObjectArrayToStringPairVector(jni_helper, cares_fallback_resolvers); + for (const auto& [host, port] : resolvers) { + builder.addCaresFallbackResolver(host, stoi(port)); + } + } builder.setUseGroIfAvailable(use_gro == JNI_TRUE); builder.enableInterfaceBinding(enable_interface_binding == JNI_TRUE); builder.enableDrainPostDnsRefresh(enable_drain_post_dns_refresh == JNI_TRUE); @@ -1326,22 +1333,23 @@ extern "C" JNIEXPORT jlong JNICALL Java_io_envoyproxy_envoymobile_engine_JniLibr jlong stream_idle_timeout_seconds, jlong per_try_idle_timeout_seconds, jstring app_version, jstring app_id, jboolean trust_chain_verification, jobjectArray filter_chain, jboolean enable_platform_certificates_validation, jstring upstream_tls_sni, - jobjectArray runtime_guards) { + jobjectArray runtime_guards, jobjectArray cares_fallback_resolvers) { Envoy::JNI::JniHelper jni_helper(env); Envoy::Platform::EngineBuilder builder; - configureBuilder( - jni_helper, connect_timeout_seconds, dns_refresh_seconds, dns_failure_refresh_seconds_base, - dns_failure_refresh_seconds_max, dns_query_timeout_seconds, dns_min_refresh_seconds, - dns_preresolve_hostnames, enable_dns_cache, dns_cache_save_interval_seconds, dns_num_retries, - enable_drain_post_dns_refresh, enable_http3, use_cares, force_v6, use_gro, - http3_connection_options, http3_client_connection_options, quic_hints, - quic_canonical_suffixes, enable_gzip_decompression, enable_brotli_decompression, - enable_port_migration, enable_socket_tagging, enable_interface_binding, - h2_connection_keepalive_idle_interval_milliseconds, h2_connection_keepalive_timeout_seconds, - max_connections_per_host, stream_idle_timeout_seconds, per_try_idle_timeout_seconds, - app_version, app_id, trust_chain_verification, filter_chain, - enable_platform_certificates_validation, upstream_tls_sni, runtime_guards, builder); + configureBuilder(jni_helper, connect_timeout_seconds, dns_refresh_seconds, + dns_failure_refresh_seconds_base, dns_failure_refresh_seconds_max, + dns_query_timeout_seconds, dns_min_refresh_seconds, dns_preresolve_hostnames, + enable_dns_cache, dns_cache_save_interval_seconds, dns_num_retries, + enable_drain_post_dns_refresh, enable_http3, use_cares, force_v6, use_gro, + http3_connection_options, http3_client_connection_options, quic_hints, + quic_canonical_suffixes, enable_gzip_decompression, enable_brotli_decompression, + enable_port_migration, enable_socket_tagging, enable_interface_binding, + h2_connection_keepalive_idle_interval_milliseconds, + h2_connection_keepalive_timeout_seconds, max_connections_per_host, + stream_idle_timeout_seconds, per_try_idle_timeout_seconds, app_version, app_id, + trust_chain_verification, filter_chain, enable_platform_certificates_validation, + upstream_tls_sni, runtime_guards, cares_fallback_resolvers, builder); return reinterpret_cast(builder.generateBootstrap().release()); } diff --git a/mobile/library/kotlin/io/envoyproxy/envoymobile/EngineBuilder.kt b/mobile/library/kotlin/io/envoyproxy/envoymobile/EngineBuilder.kt index 98aa4265be..bbc6ff7a51 100644 --- a/mobile/library/kotlin/io/envoyproxy/envoymobile/EngineBuilder.kt +++ b/mobile/library/kotlin/io/envoyproxy/envoymobile/EngineBuilder.kt @@ -1,5 +1,6 @@ package io.envoyproxy.envoymobile +import android.util.Pair import io.envoyproxy.envoymobile.engine.EnvoyConfiguration import io.envoyproxy.envoymobile.engine.EnvoyConfiguration.TrustChainVerification import io.envoyproxy.envoymobile.engine.EnvoyEngine @@ -39,6 +40,7 @@ open class EngineBuilder() { private var enableDrainPostDnsRefresh = false internal var enableHttp3 = true internal var useCares = false + internal var caresFallbackResolvers = mutableListOf>() internal var forceV6 = true private var useGro = false private var http3ConnectionOptions = "" @@ -219,6 +221,18 @@ open class EngineBuilder() { return this } + /** + * Add fallback resolver to c_ares. + * + * @param host ip address string + * @param port port for the resolver + * @return This builder. + */ + fun addCaresFallbackResolver(host: String, port: Int): EngineBuilder { + this.caresFallbackResolvers.add(Pair(host, port)) + return this + } + /** * Specify whether local ipv4 addresses should be mapped to ipv6. Defaults to true. * @@ -582,6 +596,7 @@ open class EngineBuilder() { runtimeGuards, enablePlatformCertificatesValidation, upstreamTlsSni, + caresFallbackResolvers, ) return EngineImpl(engineType(), engineConfiguration, logLevel) diff --git a/mobile/test/common/extensions/cert_validator/platform_bridge/BUILD b/mobile/test/common/extensions/cert_validator/platform_bridge/BUILD index 1c743e436a..03c5cb928d 100644 --- a/mobile/test/common/extensions/cert_validator/platform_bridge/BUILD +++ b/mobile/test/common/extensions/cert_validator/platform_bridge/BUILD @@ -18,6 +18,7 @@ envoy_extension_cc_test( repository = "@envoy", deps = [ "//library/common/extensions/cert_validator/platform_bridge:config", + "//library/common/extensions/cert_validator/platform_bridge:platform_bridge_cc_proto", "//test/common/mocks/common:common_mocks", "@envoy//source/common/tls/cert_validator:cert_validator_lib", "@envoy//test/common/tls:ssl_test_utils", diff --git a/mobile/test/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator_test.cc b/mobile/test/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator_test.cc index 46f536026e..e4a956c44f 100644 --- a/mobile/test/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator_test.cc +++ b/mobile/test/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator_test.cc @@ -24,6 +24,7 @@ #include "gtest/gtest.h" #include "library/common/bridge/utility.h" #include "library/common/extensions/cert_validator/platform_bridge/config.h" +#include "library/common/extensions/cert_validator/platform_bridge/platform_bridge.pb.h" #include "openssl/ssl.h" #include "openssl/x509v3.h" @@ -60,6 +61,30 @@ class MockValidator { (const std::vector& certs, absl::string_view hostname)); }; +class PlatformBridgeCertValidatorCustomValidate : public PlatformBridgeCertValidator { +public: + PlatformBridgeCertValidatorCustomValidate( + const Envoy::Ssl::CertificateValidationContextConfig* config, SslStats& stats, + Thread::PosixThreadFactory& thread_factory) + : PlatformBridgeCertValidator(config, stats), thread_factory_(thread_factory) {} + + int recordedThreadPriority() const { return recorded_thread_priority_; } + +protected: + void verifyCertChainByPlatform(Event::Dispatcher* dispatcher, + std::vector /* cert_chain */, std::string hostname, + std::vector /* subject_alt_names */) override { + recorded_thread_priority_ = thread_factory_.currentThreadPriority(); + postVerifyResultAndCleanUp(/* success = */ true, std::move(hostname), "", + SSL_AD_CERTIFICATE_UNKNOWN, ValidationFailureType::Success, + dispatcher, this); + } + +private: + Thread::PosixThreadFactory& thread_factory_; + int recorded_thread_priority_; +}; + class PlatformBridgeCertValidatorTest : public testing::TestWithParam { protected: @@ -84,6 +109,8 @@ class PlatformBridgeCertValidatorTest EXPECT_CALL(config_, caCert()).WillOnce(ReturnRef(empty_string_)); EXPECT_CALL(config_, certificateRevocationList()).WillOnce(ReturnRef(empty_string_)); EXPECT_CALL(config_, trustChainVerification()).WillOnce(Return(GetParam())); + EXPECT_CALL(config_, customValidatorConfig()) + .WillRepeatedly(ReturnRef(platform_bridge_config_)); } ~PlatformBridgeCertValidatorTest() { @@ -136,6 +163,7 @@ class PlatformBridgeCertValidatorTest std::unique_ptr mock_validator_; Thread::ThreadId main_thread_id_; std::unique_ptr helper_handle_; + absl::optional platform_bridge_config_; }; INSTANTIATE_TEST_SUITE_P(TrustMode, PlatformBridgeCertValidatorTest, @@ -152,6 +180,7 @@ TEST_P(PlatformBridgeCertValidatorTest, NonEmptyCaCert) { EXPECT_CALL(config_, caCert()).WillRepeatedly(ReturnRef(ca_cert)); EXPECT_CALL(config_, certificateRevocationList()).WillRepeatedly(ReturnRef(empty_string_)); EXPECT_CALL(config_, trustChainVerification()).WillRepeatedly(Return(GetParam())); + EXPECT_CALL(config_, customValidatorConfig()).WillRepeatedly(ReturnRef(platform_bridge_config_)); EXPECT_ENVOY_BUG({ PlatformBridgeCertValidator validator(&config_, stats_); }, "Invalid certificate validation context config."); @@ -162,6 +191,7 @@ TEST_P(PlatformBridgeCertValidatorTest, NonEmptyRevocationList) { EXPECT_CALL(config_, caCert()).WillRepeatedly(ReturnRef(empty_string_)); EXPECT_CALL(config_, certificateRevocationList()).WillRepeatedly(ReturnRef(revocation_list)); EXPECT_CALL(config_, trustChainVerification()).WillRepeatedly(Return(GetParam())); + EXPECT_CALL(config_, customValidatorConfig()).WillRepeatedly(ReturnRef(platform_bridge_config_)); EXPECT_ENVOY_BUG({ PlatformBridgeCertValidator validator(&config_, stats_); }, "Invalid certificate validation context config."); @@ -412,6 +442,42 @@ TEST_P(PlatformBridgeCertValidatorTest, ThreadCreationFailed) { EXPECT_EQ("Failed creating a thread for cert chain validation.", *results.error_details); } +TEST_P(PlatformBridgeCertValidatorTest, ThreadPriority) { + const int expected_thread_priority = 15; + envoy_mobile::extensions::cert_validator::platform_bridge::PlatformBridgeCertValidator + platform_bridge_config; + platform_bridge_config.mutable_thread_priority()->set_value(expected_thread_priority); + envoy::config::core::v3::TypedExtensionConfig typed_config; + typed_config.set_name("PlatformBridgeCertValidator"); + typed_config.mutable_typed_config()->PackFrom(platform_bridge_config); + platform_bridge_config_ = std::move(typed_config); + + EXPECT_CALL(helper_handle_->mock_helper(), cleanupAfterCertificateValidation()); + + initializeConfig(); + PlatformBridgeCertValidatorCustomValidate validator(&config_, stats_, *thread_factory_); + + std::string hostname = "server1.example.com"; + bssl::UniquePtr cert_chain = readCertChainFromFile( + TestEnvironment::substitute("{{ test_rundir }}/test/common/tls/test_data/san_dns2_cert.pem")); + EXPECT_CALL(*mock_validator_, cleanup()); + auto& callback_ref = *callback_; + EXPECT_CALL(callback_ref, dispatcher()).WillRepeatedly(ReturnRef(*dispatcher_)); + + ValidationResults results = + validator.doVerifyCertChain(*cert_chain, std::move(callback_), transport_socket_options_, + *ssl_ctx_, validation_context_, is_server_, hostname); + EXPECT_EQ(ValidationResults::ValidationStatus::Pending, results.status); + + EXPECT_CALL(callback_ref, + onCertValidationResult(true, Envoy::Ssl::ClientValidationStatus::Validated, "", 46)) + .WillOnce(Invoke([this, &validator, expected_thread_priority]() { + EXPECT_EQ(validator.recordedThreadPriority(), expected_thread_priority); + dispatcher_->exit(); + })); + EXPECT_FALSE(waitForDispatcherToExit()); +} + } // namespace Tls } // namespace TransportSockets } // namespace Extensions diff --git a/mobile/test/common/integration/client_integration_test.cc b/mobile/test/common/integration/client_integration_test.cc index 4c47ed94cc..d428ebf4e8 100644 --- a/mobile/test/common/integration/client_integration_test.cc +++ b/mobile/test/common/integration/client_integration_test.cc @@ -206,13 +206,7 @@ void ClientIntegrationTest::basicTest() { std::to_string(request_data.length())); EnvoyStreamCallbacks stream_callbacks = createDefaultStreamCallbacks(); - stream_callbacks.on_data_ = [this](const Buffer::Instance& buffer, uint64_t length, - bool end_stream, envoy_stream_intel) { - if (end_stream) { - std::string response_body(length, ' '); - buffer.copyOut(0, length, response_body.data()); - EXPECT_EQ(response_body, ""); - } + stream_callbacks.on_data_ = [this](const Buffer::Instance&, uint64_t, bool, envoy_stream_intel) { cc_.on_data_calls_++; }; diff --git a/mobile/test/common/internal_engine_test.cc b/mobile/test/common/internal_engine_test.cc index c9b909bad0..c15cf0c434 100644 --- a/mobile/test/common/internal_engine_test.cc +++ b/mobile/test/common/internal_engine_test.cc @@ -476,7 +476,7 @@ class ThreadPriorityInternalEngineTest : public InternalEngineTest { stream_callbacks.on_headers_ = [&](const Http::ResponseHeaderMap&, bool /* end_stream */, envoy_stream_intel) { // Gets the thread priority, so we can check that it's the same thread priority we set. - context.thread_priority = getpriority(PRIO_PROCESS, 0); + context.thread_priority = engine->threadFactory().currentThreadPriority(); }; stream_callbacks.on_complete_ = [&](envoy_stream_intel, envoy_final_stream_intel) { context.on_complete_notification.Notify(); @@ -496,15 +496,11 @@ class ThreadPriorityInternalEngineTest : public InternalEngineTest { } }; -// The setpriority() call fails on some Apple environments. -// TODO(abeyad): investigate what to do for Apple. -#ifndef __APPLE__ TEST_F(ThreadPriorityInternalEngineTest, SetThreadPriority) { const int expected_thread_priority = 10; const int actual_thread_priority = startEngineWithPriority(expected_thread_priority); EXPECT_EQ(actual_thread_priority, expected_thread_priority); } -#endif TEST_F(ThreadPriorityInternalEngineTest, SetOutOfRangeThreadPriority) { // 42 is outside the range of acceptable thread priorities. diff --git a/mobile/test/java/io/envoyproxy/envoymobile/engine/EnvoyConfigurationTest.kt b/mobile/test/java/io/envoyproxy/envoymobile/engine/EnvoyConfigurationTest.kt index ac0e43fc15..276072825e 100644 --- a/mobile/test/java/io/envoyproxy/envoymobile/engine/EnvoyConfigurationTest.kt +++ b/mobile/test/java/io/envoyproxy/envoymobile/engine/EnvoyConfigurationTest.kt @@ -1,5 +1,6 @@ package io.envoyproxy.envoymobile.engine +import android.util.Pair import io.envoyproxy.envoymobile.engine.types.EnvoyHTTPFilter import io.envoyproxy.envoymobile.engine.types.EnvoyHTTPFilterFactory import io.envoyproxy.envoymobile.engine.EnvoyConfiguration.TrustChainVerification @@ -82,6 +83,7 @@ class EnvoyConfigurationTest { enableDrainPostDnsRefresh: Boolean = false, enableHttp3: Boolean = true, enableCares: Boolean = false, + caresFallbackResolvers: MutableList> = mutableListOf(Pair("1.2.3.4", 88)), forceV6: Boolean = true, enableGro: Boolean = false, http3ConnectionOptions: String = "5RTO", @@ -156,6 +158,7 @@ class EnvoyConfigurationTest { runtimeGuards, enablePlatformCertificatesValidation, upstreamTlsSni, + caresFallbackResolvers, ) } @@ -261,6 +264,8 @@ class EnvoyConfigurationTest { // enableCares = true assertThat(resolvedTemplate).contains("envoy.network.dns_resolver.cares") + assertThat(resolvedTemplate).contains("address: \"1.2.3.4\""); + assertThat(resolvedTemplate).contains("port_value: 88"); // enableGro = true assertThat(resolvedTemplate).contains("key: \"prefer_quic_client_udp_gro\" value { bool_value: true }") diff --git a/mobile/test/kotlin/integration/proxying/BUILD b/mobile/test/kotlin/integration/proxying/BUILD index eea8dd00eb..6f6866cf28 100644 --- a/mobile/test/kotlin/integration/proxying/BUILD +++ b/mobile/test/kotlin/integration/proxying/BUILD @@ -34,9 +34,6 @@ envoy_mobile_android_test( srcs = [ "ProxyInfoIntentPerformHTTPSRequestUsingProxyTest.kt", ], - exec_properties = { - "dockerNetwork": "standard", - }, native_deps = [ "//test/jni:libenvoy_jni_with_test_and_listener_extensions.so", ] + select({ @@ -52,6 +49,7 @@ envoy_mobile_android_test( "//library/kotlin/io/envoyproxy/envoymobile:envoy_lib", "//test/java/io/envoyproxy/envoymobile/engine/testing", "//test/java/io/envoyproxy/envoymobile/engine/testing:http_proxy_test_server_factory_lib", + "//test/java/io/envoyproxy/envoymobile/engine/testing:http_test_server_factory_lib", ], ) @@ -60,9 +58,6 @@ envoy_mobile_android_test( srcs = [ "ProxyInfoIntentPerformHTTPSRequestUsingAsyncProxyTest.kt", ], - exec_properties = { - "dockerNetwork": "standard", - }, native_deps = [ "//test/jni:libenvoy_jni_with_test_and_listener_extensions.so", ] + select({ @@ -78,6 +73,7 @@ envoy_mobile_android_test( "//library/kotlin/io/envoyproxy/envoymobile:envoy_lib", "//test/java/io/envoyproxy/envoymobile/engine/testing", "//test/java/io/envoyproxy/envoymobile/engine/testing:http_proxy_test_server_factory_lib", + "//test/java/io/envoyproxy/envoymobile/engine/testing:http_test_server_factory_lib", ], ) @@ -86,9 +82,6 @@ envoy_mobile_android_test( srcs = [ "ProxyInfoIntentPerformHTTPSRequestBadHostnameTest.kt", ], - exec_properties = { - "dockerNetwork": "standard", - }, native_deps = [ "//test/jni:libenvoy_jni_with_test_and_listener_extensions.so", ] + select({ @@ -104,6 +97,7 @@ envoy_mobile_android_test( "//library/kotlin/io/envoyproxy/envoymobile:envoy_lib", "//test/java/io/envoyproxy/envoymobile/engine/testing", "//test/java/io/envoyproxy/envoymobile/engine/testing:http_proxy_test_server_factory_lib", + "//test/java/io/envoyproxy/envoymobile/engine/testing:http_test_server_factory_lib", ], ) @@ -112,9 +106,6 @@ envoy_mobile_android_test( srcs = [ "ProxyPollPerformHTTPRequestUsingProxyTest.kt", ], - exec_properties = { - "dockerNetwork": "standard", - }, native_deps = [ "//test/jni:libenvoy_jni_with_test_and_listener_extensions.so", ] + select({ @@ -130,6 +121,7 @@ envoy_mobile_android_test( "//library/kotlin/io/envoyproxy/envoymobile:envoy_lib", "//test/java/io/envoyproxy/envoymobile/engine/testing", "//test/java/io/envoyproxy/envoymobile/engine/testing:http_proxy_test_server_factory_lib", + "//test/java/io/envoyproxy/envoymobile/engine/testing:http_test_server_factory_lib", ], ) diff --git a/mobile/test/kotlin/integration/proxying/ProxyInfoIntentPerformHTTPRequestUsingProxyTest.kt b/mobile/test/kotlin/integration/proxying/ProxyInfoIntentPerformHTTPRequestUsingProxyTest.kt index e6a44edda8..417809fb35 100644 --- a/mobile/test/kotlin/integration/proxying/ProxyInfoIntentPerformHTTPRequestUsingProxyTest.kt +++ b/mobile/test/kotlin/integration/proxying/ProxyInfoIntentPerformHTTPRequestUsingProxyTest.kt @@ -66,7 +66,7 @@ class ProxyInfoIntentPerformHTTPRequestUsingProxyTest { shadowOf(connectivityManager) .setProxyForNetwork( connectivityManager.activeNetwork, - ProxyInfo.buildDirectProxy("127.0.0.1", httpProxyTestServer.port) + ProxyInfo.buildDirectProxy(httpProxyTestServer.ipAddress, httpProxyTestServer.port) ) val onEngineRunningLatch = CountDownLatch(1) diff --git a/mobile/test/kotlin/integration/proxying/ProxyInfoIntentPerformHTTPSRequestBadHostnameTest.kt b/mobile/test/kotlin/integration/proxying/ProxyInfoIntentPerformHTTPSRequestBadHostnameTest.kt index 8cfb4591b1..ede10c1391 100644 --- a/mobile/test/kotlin/integration/proxying/ProxyInfoIntentPerformHTTPSRequestBadHostnameTest.kt +++ b/mobile/test/kotlin/integration/proxying/ProxyInfoIntentPerformHTTPSRequestBadHostnameTest.kt @@ -11,8 +11,10 @@ import io.envoyproxy.envoymobile.AndroidEngineBuilder import io.envoyproxy.envoymobile.LogLevel import io.envoyproxy.envoymobile.RequestHeadersBuilder import io.envoyproxy.envoymobile.RequestMethod +import io.envoyproxy.envoymobile.engine.EnvoyConfiguration import io.envoyproxy.envoymobile.engine.JniLibrary import io.envoyproxy.envoymobile.engine.testing.HttpProxyTestServerFactory +import io.envoyproxy.envoymobile.engine.testing.HttpTestServerFactory import java.util.concurrent.CountDownLatch import java.util.concurrent.Executors import java.util.concurrent.TimeUnit @@ -41,16 +43,19 @@ class ProxyInfoIntentPerformHTTPSRequestBadHostnameTest { } private lateinit var httpProxyTestServer: HttpProxyTestServerFactory.HttpProxyTestServer + private lateinit var httpTestServer: HttpTestServerFactory.HttpTestServer @Before fun setUp() { httpProxyTestServer = HttpProxyTestServerFactory.start(HttpProxyTestServerFactory.Type.HTTPS_PROXY) + httpTestServer = HttpTestServerFactory.start(HttpTestServerFactory.Type.HTTP1_WITH_TLS) } @After fun tearDown() { httpProxyTestServer.shutdown() + httpTestServer.shutdown() } @Test @@ -62,7 +67,7 @@ class ProxyInfoIntentPerformHTTPSRequestBadHostnameTest { Shadows.shadowOf(connectivityManager) .setProxyForNetwork( connectivityManager.activeNetwork, - ProxyInfo.buildDirectProxy("loopback", httpProxyTestServer.port) + ProxyInfo.buildDirectProxy("bad.hostname", httpProxyTestServer.port) ) val onEngineRunningLatch = CountDownLatch(1) @@ -77,6 +82,7 @@ class ProxyInfoIntentPerformHTTPSRequestBadHostnameTest { .setLogger { _, msg -> print(msg) } .enableProxying(true) .setOnEngineRunning { onEngineRunningLatch.countDown() } + .setTrustChainVerification(EnvoyConfiguration.TrustChainVerification.ACCEPT_UNTRUSTED) .build() onEngineRunningLatch.await(10, TimeUnit.SECONDS) @@ -86,8 +92,8 @@ class ProxyInfoIntentPerformHTTPSRequestBadHostnameTest { RequestHeadersBuilder( method = RequestMethod.GET, scheme = "https", - authority = "api.lyft.com", - path = "/ping" + authority = httpTestServer.address, + path = "/" ) .build() diff --git a/mobile/test/kotlin/integration/proxying/ProxyInfoIntentPerformHTTPSRequestUsingAsyncProxyTest.kt b/mobile/test/kotlin/integration/proxying/ProxyInfoIntentPerformHTTPSRequestUsingAsyncProxyTest.kt index 0931e111c3..61000b350c 100644 --- a/mobile/test/kotlin/integration/proxying/ProxyInfoIntentPerformHTTPSRequestUsingAsyncProxyTest.kt +++ b/mobile/test/kotlin/integration/proxying/ProxyInfoIntentPerformHTTPSRequestUsingAsyncProxyTest.kt @@ -11,8 +11,10 @@ import io.envoyproxy.envoymobile.AndroidEngineBuilder import io.envoyproxy.envoymobile.LogLevel import io.envoyproxy.envoymobile.RequestHeadersBuilder import io.envoyproxy.envoymobile.RequestMethod +import io.envoyproxy.envoymobile.engine.EnvoyConfiguration import io.envoyproxy.envoymobile.engine.JniLibrary import io.envoyproxy.envoymobile.engine.testing.HttpProxyTestServerFactory +import io.envoyproxy.envoymobile.engine.testing.HttpTestServerFactory import java.util.concurrent.CountDownLatch import java.util.concurrent.Executors import java.util.concurrent.TimeUnit @@ -41,16 +43,19 @@ class ProxyInfoIntentPerformHTTPSRequestUsingAsyncProxyTest { } private lateinit var httpProxyTestServer: HttpProxyTestServerFactory.HttpProxyTestServer + private lateinit var httpTestServer: HttpTestServerFactory.HttpTestServer @Before fun setUp() { httpProxyTestServer = HttpProxyTestServerFactory.start(HttpProxyTestServerFactory.Type.HTTPS_PROXY) + httpTestServer = HttpTestServerFactory.start(HttpTestServerFactory.Type.HTTP1_WITH_TLS) } @After fun tearDown() { httpProxyTestServer.shutdown() + httpTestServer.shutdown() } @Test @@ -62,7 +67,7 @@ class ProxyInfoIntentPerformHTTPSRequestUsingAsyncProxyTest { Shadows.shadowOf(connectivityManager) .setProxyForNetwork( connectivityManager.activeNetwork, - ProxyInfo.buildDirectProxy("localhost", httpProxyTestServer.port) + ProxyInfo.buildDirectProxy(httpProxyTestServer.ipAddress, httpProxyTestServer.port) ) val onEngineRunningLatch = CountDownLatch(1) @@ -77,6 +82,7 @@ class ProxyInfoIntentPerformHTTPSRequestUsingAsyncProxyTest { .setLogger { _, msg -> print(msg) } .enableProxying(true) .setOnEngineRunning { onEngineRunningLatch.countDown() } + .setTrustChainVerification(EnvoyConfiguration.TrustChainVerification.ACCEPT_UNTRUSTED) .build() onEngineRunningLatch.await(10, TimeUnit.SECONDS) @@ -86,8 +92,8 @@ class ProxyInfoIntentPerformHTTPSRequestUsingAsyncProxyTest { RequestHeadersBuilder( method = RequestMethod.GET, scheme = "https", - authority = "api.lyft.com", - path = "/ping" + authority = httpTestServer.address, + path = "/" ) .build() diff --git a/mobile/test/kotlin/integration/proxying/ProxyInfoIntentPerformHTTPSRequestUsingProxyTest.kt b/mobile/test/kotlin/integration/proxying/ProxyInfoIntentPerformHTTPSRequestUsingProxyTest.kt index 0e5c65b88d..be62bbdc90 100644 --- a/mobile/test/kotlin/integration/proxying/ProxyInfoIntentPerformHTTPSRequestUsingProxyTest.kt +++ b/mobile/test/kotlin/integration/proxying/ProxyInfoIntentPerformHTTPSRequestUsingProxyTest.kt @@ -11,8 +11,10 @@ import io.envoyproxy.envoymobile.AndroidEngineBuilder import io.envoyproxy.envoymobile.LogLevel import io.envoyproxy.envoymobile.RequestHeadersBuilder import io.envoyproxy.envoymobile.RequestMethod +import io.envoyproxy.envoymobile.engine.EnvoyConfiguration import io.envoyproxy.envoymobile.engine.JniLibrary import io.envoyproxy.envoymobile.engine.testing.HttpProxyTestServerFactory +import io.envoyproxy.envoymobile.engine.testing.HttpTestServerFactory import java.util.concurrent.CountDownLatch import java.util.concurrent.Executors import java.util.concurrent.TimeUnit @@ -41,21 +43,23 @@ class ProxyInfoIntentPerformHTTPSRequestUsingProxyTest { } private lateinit var httpProxyTestServer: HttpProxyTestServerFactory.HttpProxyTestServer + private lateinit var httpTestServer: HttpTestServerFactory.HttpTestServer @Before fun setUp() { httpProxyTestServer = HttpProxyTestServerFactory.start(HttpProxyTestServerFactory.Type.HTTPS_PROXY) + httpTestServer = HttpTestServerFactory.start(HttpTestServerFactory.Type.HTTP1_WITH_TLS) } @After fun tearDown() { httpProxyTestServer.shutdown() + httpTestServer.shutdown() } @Test fun `performs an HTTPs request through a proxy`() { - println("IP ADDRESS: ${httpProxyTestServer.ipAddress}") val context = ApplicationProvider.getApplicationContext() val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager @@ -78,6 +82,7 @@ class ProxyInfoIntentPerformHTTPSRequestUsingProxyTest { .setLogger { _, msg -> print(msg) } .enableProxying(true) .setOnEngineRunning { onEngineRunningLatch.countDown() } + .setTrustChainVerification(EnvoyConfiguration.TrustChainVerification.ACCEPT_UNTRUSTED) .build() onEngineRunningLatch.await(10, TimeUnit.SECONDS) @@ -87,8 +92,8 @@ class ProxyInfoIntentPerformHTTPSRequestUsingProxyTest { RequestHeadersBuilder( method = RequestMethod.GET, scheme = "https", - authority = "api.lyft.com", - path = "/ping" + authority = httpTestServer.address, + path = "/" ) .build() diff --git a/mobile/test/kotlin/integration/proxying/ProxyPollPerformHTTPRequestUsingProxyTest.kt b/mobile/test/kotlin/integration/proxying/ProxyPollPerformHTTPRequestUsingProxyTest.kt index b1613d4e11..137e1374ef 100644 --- a/mobile/test/kotlin/integration/proxying/ProxyPollPerformHTTPRequestUsingProxyTest.kt +++ b/mobile/test/kotlin/integration/proxying/ProxyPollPerformHTTPRequestUsingProxyTest.kt @@ -11,6 +11,7 @@ import io.envoyproxy.envoymobile.RequestHeadersBuilder import io.envoyproxy.envoymobile.RequestMethod import io.envoyproxy.envoymobile.engine.JniLibrary import io.envoyproxy.envoymobile.engine.testing.HttpProxyTestServerFactory +import io.envoyproxy.envoymobile.engine.testing.HttpTestServerFactory import java.util.concurrent.CountDownLatch import java.util.concurrent.Executors import java.util.concurrent.TimeUnit @@ -39,16 +40,19 @@ class ProxyPollPerformHTTPRequestUsingProxyTest { } private lateinit var httpProxyTestServer: HttpProxyTestServerFactory.HttpProxyTestServer + private lateinit var httpTestServer: HttpTestServerFactory.HttpTestServer @Before fun setUp() { httpProxyTestServer = HttpProxyTestServerFactory.start(HttpProxyTestServerFactory.Type.HTTP_PROXY) + httpTestServer = HttpTestServerFactory.start(HttpTestServerFactory.Type.HTTP1_WITHOUT_TLS) } @After fun tearDown() { httpProxyTestServer.shutdown() + httpTestServer.shutdown() } @Test @@ -60,7 +64,7 @@ class ProxyPollPerformHTTPRequestUsingProxyTest { Shadows.shadowOf(connectivityManager) .setProxyForNetwork( connectivityManager.activeNetwork, - ProxyInfo.buildDirectProxy("127.0.0.1", httpProxyTestServer.port) + ProxyInfo.buildDirectProxy(httpProxyTestServer.ipAddress, httpProxyTestServer.port) ) val onEngineRunningLatch = CountDownLatch(1) @@ -82,8 +86,8 @@ class ProxyPollPerformHTTPRequestUsingProxyTest { RequestHeadersBuilder( method = RequestMethod.GET, scheme = "http", - authority = "api.lyft.com", - path = "/ping" + authority = httpTestServer.address, + path = "/" ) .build() @@ -92,7 +96,7 @@ class ProxyPollPerformHTTPRequestUsingProxyTest { .newStreamPrototype() .setOnResponseHeaders { responseHeaders, _, _ -> val status = responseHeaders.httpStatus ?: 0L - assertThat(status).isEqualTo(301) + assertThat(status).isEqualTo(200) assertThat(responseHeaders.value("x-proxy-response")).isEqualTo(listOf("true")) onResponseHeadersLatch.countDown() } diff --git a/source/common/access_log/BUILD b/source/common/access_log/BUILD index 869662afa0..7359f9b104 100644 --- a/source/common/access_log/BUILD +++ b/source/common/access_log/BUILD @@ -12,9 +12,6 @@ envoy_cc_library( name = "access_log_lib", srcs = ["access_log_impl.cc"], hdrs = ["access_log_impl.h"], - external_deps = [ - "abseil_hash", - ], deps = [ "//envoy/access_log:access_log_config_interface", "//envoy/access_log:access_log_interface", @@ -34,6 +31,7 @@ envoy_cc_library( "//source/common/protobuf:utility_lib", "//source/common/stream_info:stream_info_lib", "//source/common/tracing:http_tracer_lib", + "@com_google_absl//absl/hash", "@envoy_api//envoy/config/accesslog/v3:pkg_cc_proto", "@envoy_api//envoy/type/v3:pkg_cc_proto", ], diff --git a/source/common/common/BUILD b/source/common/common/BUILD index ec85b28e5b..415b71d4c2 100644 --- a/source/common/common/BUILD +++ b/source/common/common/BUILD @@ -21,13 +21,13 @@ envoy_cc_library( name = "assert_lib", srcs = ["assert.cc"], hdrs = ["assert.h"], - external_deps = [ - "abseil_base", - "abseil_synchronization", - "abseil_stacktrace", - "abseil_symbolize", + deps = [ + ":minimal_logger_lib", + "@com_google_absl//absl/base", + "@com_google_absl//absl/debugging:stacktrace", + "@com_google_absl//absl/debugging:symbolize", + "@com_google_absl//absl/synchronization", ], - deps = [":minimal_logger_lib"], ) envoy_cc_library( @@ -128,12 +128,12 @@ envoy_basic_cc_library( name = "fmt_lib", hdrs = ["fmt.h"], external_deps = [ - "abseil_strings", "fmtlib", ], deps = [ "//envoy/common:base_includes", "@com_google_absl//absl/status", + "@com_google_absl//absl/strings", ], ) @@ -168,7 +168,6 @@ envoy_cc_library( srcs = ["key_value_store_base.cc"], hdrs = ["key_value_store_base.h"], external_deps = [ - "abseil_cleanup", "quiche_quic_platform", ], deps = [ @@ -177,6 +176,7 @@ envoy_cc_library( "//envoy/filesystem:filesystem_interface", "//source/common/config:ttl_lib", "@com_github_google_quiche//:quiche_common_lib", + "@com_google_absl//absl/cleanup", ], ) @@ -210,10 +210,6 @@ envoy_cc_library( "json_escape_string.h", "logger.h", ], - external_deps = [ - "abseil_synchronization", - "abseil_flat_hash_map", - ], deps = [ ":base_logger_lib", ":fmt_lib", @@ -221,6 +217,8 @@ envoy_cc_library( ":macros", ":non_copyable", "//source/common/protobuf", + "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/synchronization", ] + select({ "//bazel:android_logger": ["logger_impl_lib_android"], "//conditions:default": ["logger_impl_lib_standard"], @@ -232,9 +230,11 @@ envoy_cc_library( srcs = ["base_logger.cc"], hdrs = ["base_logger.h"], external_deps = [ - "abseil_strings", "spdlog", ], + deps = [ + "@com_google_absl//absl/strings", + ], ) envoy_cc_library( @@ -277,10 +277,10 @@ envoy_cc_library( name = "mutex_tracer_lib", srcs = ["mutex_tracer_impl.cc"], hdrs = ["mutex_tracer_impl.h"], - external_deps = ["abseil_synchronization"], deps = [ ":assert_lib", "//envoy/common:mutex_tracer", + "@com_google_absl//absl/synchronization", ], ) @@ -316,7 +316,6 @@ envoy_cc_library( name = "matchers_lib", srcs = ["matchers.cc"], hdrs = ["matchers.h"], - external_deps = ["abseil_optional"], deps = [ ":utility_lib", "//envoy/common:matchers_interface", @@ -325,6 +324,7 @@ envoy_cc_library( "//source/common/config:utility_lib", "//source/common/http:path_utility_lib", "//source/common/protobuf", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/type/matcher/v3:pkg_cc_proto", ], @@ -401,16 +401,16 @@ envoy_cc_library( envoy_cc_library( name = "thread_annotations", hdrs = ["thread_annotations.h"], - external_deps = ["abseil_base"], + deps = ["@com_google_absl//absl/base"], ) envoy_cc_library( name = "thread_synchronizer_lib", srcs = ["thread_synchronizer.cc"], hdrs = ["thread_synchronizer.h"], - external_deps = ["abseil_synchronization"], deps = [ ":assert_lib", + "@com_google_absl//absl/synchronization", ], ) @@ -418,10 +418,10 @@ envoy_cc_library( name = "thread_lib", srcs = ["thread.cc"], hdrs = ["thread.h"], - external_deps = ["abseil_synchronization"], deps = envoy_cc_platform_dep("thread_impl_lib") + [ ":macros", ":non_copyable", + "@com_google_absl//absl/synchronization", ], ) @@ -433,6 +433,7 @@ envoy_cc_posix_library( strip_include_prefix = "posix", deps = [ ":assert_lib", + ":utility_lib", "//envoy/thread:thread_interface", ], ) @@ -467,7 +468,6 @@ envoy_cc_library( name = "utility_lib", srcs = ["utility.cc"], hdrs = ["utility.h"], - external_deps = ["abseil_node_hash_map"], deps = [ ":assert_lib", ":hash_lib", @@ -476,6 +476,7 @@ envoy_cc_library( "//envoy/common:interval_set_interface", "//envoy/common:time_interface", "//source/common/singleton:const_singleton", + "@com_google_absl//absl/container:node_hash_map", "@com_googlesource_code_re2//:re2", ], ) @@ -483,12 +484,10 @@ envoy_cc_library( envoy_cc_library( name = "compiled_string_map_lib", hdrs = ["compiled_string_map.h"], - external_deps = [ - "abseil_strings", - ], deps = [ "//envoy/common:pure_lib", "//source/common/common:assert_lib", + "@com_google_absl//absl/strings", ], ) @@ -616,12 +615,10 @@ envoy_cc_library( hdrs = [ "inline_map.h", ], - external_deps = [ - "abseil_node_hash_set", - ], deps = [ "//source/common/common:assert_lib", "//source/common/common:macros", "//source/common/common:utility_lib", + "@com_google_absl//absl/container:node_hash_set", ], ) diff --git a/source/common/common/posix/thread_impl.cc b/source/common/common/posix/thread_impl.cc index 012474e1a6..6e53869e6f 100644 --- a/source/common/common/posix/thread_impl.cc +++ b/source/common/common/posix/thread_impl.cc @@ -3,11 +3,16 @@ #include "envoy/thread/thread.h" #include "source/common/common/assert.h" +#include "source/common/common/utility.h" #include "absl/strings/str_cat.h" #if defined(__linux__) +#include #include +#elif defined(__APPLE__) +#include +#include #endif namespace Envoy { @@ -34,6 +39,29 @@ int64_t getCurrentThreadId() { return tid; } +void setThreadPriority(const int64_t tid, const int priority) { +#if defined(__linux__) + const int rc = setpriority(PRIO_PROCESS, tid, priority); + if (rc != 0) { + ENVOY_LOG_MISC(warn, "failed to set thread priority: {}", Envoy::errorDetails(errno)); + } +#elif defined(__APPLE__) + UNREFERENCED_PARAMETER(tid); + // Use NSThread via the Objective-C runtime to set the thread priority; it's the best way to set + // the thread priority on Apple platforms, and directly invoking `setpriority()` on iOS fails with + // permissions issues, as discovered through manual testing. + Class nsthread = objc_getClass("NSThread"); + id (*getCurrentNSThread)(Class, SEL) = reinterpret_cast(objc_msgSend); + id current_thread = getCurrentNSThread(nsthread, sel_registerName("currentThread")); + void (*setNSThreadPriority)(id, SEL, double) = + reinterpret_cast(objc_msgSend); + double ns_priority = static_cast(priority) / 100.0; + setNSThreadPriority(current_thread, sel_registerName("setThreadPriority:"), ns_priority); +#else +#error "Enable and test pthread id retrieval code for you arch in pthread/thread_impl.cc" +#endif +} + } // namespace // See https://www.man7.org/linux/man-pages/man3/pthread_setname_np.3.html. @@ -41,11 +69,14 @@ int64_t getCurrentThreadId() { // so we need to truncate the string_view to 15 bytes. #define PTHREAD_MAX_THREADNAME_LEN_INCLUDING_NULL_BYTE 16 -ThreadHandle::ThreadHandle(std::function thread_routine) - : thread_routine_(thread_routine) {} +ThreadHandle::ThreadHandle(std::function thread_routine, + absl::optional thread_priority) + : thread_routine_(thread_routine), thread_priority_(thread_priority) {} /** Returns the thread routine. */ -std::function& ThreadHandle::routine() { return thread_routine_; }; +std::function& ThreadHandle::routine() { return thread_routine_; } + +absl::optional ThreadHandle::priority() const { return thread_priority_; } /** Returns the thread handle. */ pthread_t& ThreadHandle::handle() { return thread_handle_; } @@ -140,7 +171,11 @@ int PosixThreadFactory::createPthread(ThreadHandle* thread_handle) { return pthread_create( &thread_handle->handle(), nullptr, [](void* arg) -> void* { - static_cast(arg)->routine()(); + ThreadHandle* handle = static_cast(arg); + if (handle->priority()) { + setThreadPriority(getCurrentThreadId(), *handle->priority()); + } + handle->routine()(); return nullptr; }, reinterpret_cast(thread_handle)); @@ -148,7 +183,8 @@ int PosixThreadFactory::createPthread(ThreadHandle* thread_handle) { PosixThreadPtr PosixThreadFactory::createThread(std::function thread_routine, OptionsOptConstRef options, bool crash_on_failure) { - auto thread_handle = new ThreadHandle(thread_routine); + auto thread_handle = + new ThreadHandle(thread_routine, options ? options->priority_ : absl::nullopt); const int rc = createPthread(thread_handle); if (rc != 0) { delete thread_handle; @@ -162,9 +198,24 @@ PosixThreadPtr PosixThreadFactory::createThread(std::function thread_rou return std::make_unique(thread_handle, options); }; -ThreadId PosixThreadFactory::currentThreadId() { return ThreadId(getCurrentThreadId()); }; +ThreadId PosixThreadFactory::currentThreadId() const { return ThreadId(getCurrentThreadId()); }; + +int PosixThreadFactory::currentThreadPriority() const { +#if defined(__linux__) + return static_cast(getpriority(PRIO_PROCESS, getCurrentThreadId())); +#elif defined(__APPLE__) + Class nsthread = objc_getClass("NSThread"); + SEL selector = sel_registerName("threadPriority"); + double (*getNSThreadPriority)(Class, SEL) = + reinterpret_cast(objc_msgSend); + double thread_priority = getNSThreadPriority(nsthread, selector); + return static_cast(std::round(thread_priority * 100.0)); +#else +#error "Enable and test pthread id retrieval code for you arch in pthread/thread_impl.cc" +#endif +} -ThreadId PosixThreadFactory::currentPthreadId() { +ThreadId PosixThreadFactory::currentPthreadId() const { #if defined(__linux__) return static_cast(static_cast(pthread_self())); #elif defined(__APPLE__) diff --git a/source/common/common/posix/thread_impl.h b/source/common/common/posix/thread_impl.h index 027051115b..dbfadb96aa 100644 --- a/source/common/common/posix/thread_impl.h +++ b/source/common/common/posix/thread_impl.h @@ -12,16 +12,20 @@ namespace Thread { class ThreadHandle { public: - explicit ThreadHandle(std::function thread_routine); + ThreadHandle(std::function thread_routine, absl::optional thread_priority); /** Returns the thread routine. */ std::function& routine(); + /** Returns the thread priority, if any. */ + absl::optional priority() const; + /** Returns the thread handle. */ pthread_t& handle(); private: std::function thread_routine_; + const absl::optional thread_priority_; pthread_t thread_handle_; }; @@ -78,7 +82,7 @@ class PosixThreadFactory : public ThreadFactory { * Creates a new generic thread from the specified `thread_routine`. When the * thread cannot be created, this function will crash. */ - ThreadPtr createThread(std::function thread_routine, OptionsOptConstRef options); + ThreadPtr createThread(std::function thread_routine, OptionsOptConstRef options) override; /** * Creates a new POSIX thread from the specified `thread_routine`. When @@ -93,10 +97,17 @@ class PosixThreadFactory : public ThreadFactory { * thread ID. The thread ID returned from this call is not the same as the * thread ID returned from `currentPThreadId()`. */ - ThreadId currentThreadId(); + ThreadId currentThreadId() const override; + + /** + * On Linux and Android, this will return an integer value between [-20, 19]. + * On Apple platforms, thread priorities range from [0,1] but this API normalizes the values to + * [0, 100] for consistency with the Options.priority_ values. + */ + int currentThreadPriority() const; /** Returns the current pthread ID. It uses `pthread_self()`. */ - virtual ThreadId currentPthreadId(); + virtual ThreadId currentPthreadId() const; protected: virtual int createPthread(ThreadHandle* thread_handle); diff --git a/source/common/common/win32/thread_impl.cc b/source/common/common/win32/thread_impl.cc index e7e548883a..c1beac6a52 100644 --- a/source/common/common/win32/thread_impl.cc +++ b/source/common/common/win32/thread_impl.cc @@ -22,6 +22,10 @@ ThreadImplWin32::ThreadImplWin32(std::function thread_routine, OptionsOp return 0; }, this, 0, nullptr)); + if (options && options.thread_priority_ && + !SetThreadPriority(thread_handle_, *options.thread_priority_)) { + ENVOY_LOG_MISC(warn, "Could not set the thread priority to {}", *options.thread_priority_); + } RELEASE_ASSERT(thread_handle_ != 0, ""); } diff --git a/source/common/config/BUILD b/source/common/config/BUILD index dca8c82270..f44bd06da5 100644 --- a/source/common/config/BUILD +++ b/source/common/config/BUILD @@ -216,7 +216,6 @@ envoy_cc_library( name = "utility_lib", srcs = ["utility.cc"], hdrs = ["utility.h"], - external_deps = ["abseil_optional"], deps = [ "//envoy/config:grpc_mux_interface", "//envoy/config:subscription_interface", @@ -235,6 +234,7 @@ envoy_cc_library( "//source/common/version:api_version_lib", "@com_github_cncf_xds//udpa/type/v1:pkg_cc_proto", "@com_github_cncf_xds//xds/type/v3:pkg_cc_proto", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/config/cluster/v3:pkg_cc_proto", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", diff --git a/source/common/config/utility.h b/source/common/config/utility.h index 6c8e5a6ca8..ae9702984b 100644 --- a/source/common/config/utility.h +++ b/source/common/config/utility.h @@ -237,7 +237,7 @@ class Utility { * Get a Factory from the registry with a particular name or return nullptr. * @param name string identifier for the particular implementation. */ - template static Factory* getFactoryByName(const std::string& name) { + template static Factory* getFactoryByName(absl::string_view name) { if (name.empty()) { return nullptr; } diff --git a/source/common/event/BUILD b/source/common/event/BUILD index 41d65b47e3..659d8e76b0 100644 --- a/source/common/event/BUILD +++ b/source/common/event/BUILD @@ -114,9 +114,6 @@ envoy_cc_library( "file_event_impl.h", "schedulable_cb_impl.h", ], - external_deps = [ - "abseil_inlined_vector", - ], deps = [ ":libevent_lib", ":libevent_scheduler_lib", @@ -128,6 +125,7 @@ envoy_cc_library( "//source/common/common:minimal_logger_lib", "//source/common/common:thread_lib", "//source/common/signal:fatal_error_handler_lib", + "@com_google_absl//absl/container:inlined_vector", ] + envoy_select_signal_trace(["//source/common/signal:sigaction_lib"]), ) diff --git a/source/common/formatter/BUILD b/source/common/formatter/BUILD index 0d67f123ee..393eb6daa9 100644 --- a/source/common/formatter/BUILD +++ b/source/common/formatter/BUILD @@ -18,7 +18,6 @@ envoy_cc_library( "http_formatter_context.h", "substitution_formatter.h", ], - external_deps = ["abseil_str_format"], deps = [ "//envoy/api:api_interface", "//envoy/formatter:substitution_formatter_interface", @@ -27,6 +26,7 @@ envoy_cc_library( "//source/common/http:header_map_lib", "//source/common/http:utility_lib", "//source/common/json:json_loader_lib", + "@com_google_absl//absl/strings:str_format", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], ) diff --git a/source/common/grpc/BUILD b/source/common/grpc/BUILD index ed55b58cb6..3e183c19e2 100644 --- a/source/common/grpc/BUILD +++ b/source/common/grpc/BUILD @@ -75,9 +75,9 @@ envoy_cc_library( name = "status_lib", srcs = ["status.cc"], hdrs = ["status.h"], - external_deps = ["abseil_optional"], deps = [ "//envoy/grpc:status", + "@com_google_absl//absl/types:optional", ], ) @@ -85,7 +85,6 @@ envoy_cc_library( name = "common_lib", srcs = ["common.cc"], hdrs = ["common.h"], - external_deps = ["abseil_optional"], deps = [ "//envoy/http:header_map_interface", "//envoy/http:message_interface", @@ -109,6 +108,7 @@ envoy_cc_library( "//source/common/http:message_lib", "//source/common/http:utility_lib", "//source/common/protobuf", + "@com_google_absl//absl/types:optional", ], ) @@ -116,7 +116,6 @@ envoy_cc_library( name = "context_lib", srcs = ["context_impl.cc"], hdrs = ["context_impl.h"], - external_deps = ["abseil_optional"], deps = [ ":common_lib", ":stat_names_lib", @@ -126,6 +125,7 @@ envoy_cc_library( "//source/common/common:hash_lib", "//source/common/stats:symbol_table_lib", "//source/common/stats:utility_lib", + "@com_google_absl//absl/types:optional", ], ) @@ -134,7 +134,6 @@ envoy_cc_library( srcs = ["google_grpc_utils.cc"], hdrs = ["google_grpc_utils.h"], external_deps = [ - "abseil_optional", "grpc", ], deps = [ @@ -148,6 +147,7 @@ envoy_cc_library( "//source/common/common:macros", "//source/common/common:utility_lib", "//source/common/grpc:status_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], ) @@ -167,7 +167,6 @@ envoy_cc_library( srcs = ["google_async_client_impl.cc"], hdrs = ["google_async_client_impl.h"], external_deps = [ - "abseil_synchronization", "grpc", ], deps = [ @@ -187,6 +186,7 @@ envoy_cc_library( "//source/common/common:linked_object", "//source/common/common:thread_annotations", "//source/common/tracing:http_tracer_lib", + "@com_google_absl//absl/synchronization", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], ) diff --git a/source/common/grpc/async_client_impl.cc b/source/common/grpc/async_client_impl.cc index 43f32db72b..7138a9ea85 100644 --- a/source/common/grpc/async_client_impl.cc +++ b/source/common/grpc/async_client_impl.cc @@ -333,6 +333,10 @@ void AsyncRequestImpl::cancel() { this->resetStream(); } +const StreamInfo::StreamInfo& AsyncRequestImpl::streamInfo() const { + return AsyncStreamImpl::streamInfo(); +} + void AsyncRequestImpl::onCreateInitialMetadata(Http::RequestHeaderMap& metadata) { Tracing::HttpTraceContext trace_context(metadata); Tracing::UpstreamContext upstream_context(nullptr, // host_ diff --git a/source/common/grpc/async_client_impl.h b/source/common/grpc/async_client_impl.h index aa4fb58045..3e23db01f3 100644 --- a/source/common/grpc/async_client_impl.h +++ b/source/common/grpc/async_client_impl.h @@ -138,8 +138,10 @@ class AsyncRequestImpl : public AsyncRequest, public AsyncStreamImpl, RawAsyncSt // Grpc::AsyncRequest void cancel() override; + const StreamInfo::StreamInfo& streamInfo() const override; private: + using AsyncStreamImpl::streamInfo; // Grpc::AsyncStreamCallbacks void onCreateInitialMetadata(Http::RequestHeaderMap& metadata) override; void onReceiveInitialMetadata(Http::ResponseHeaderMapPtr&&) override; diff --git a/source/common/grpc/google_async_client_impl.h b/source/common/grpc/google_async_client_impl.h index 9ee8bdc28b..09053dc902 100644 --- a/source/common/grpc/google_async_client_impl.h +++ b/source/common/grpc/google_async_client_impl.h @@ -346,8 +346,12 @@ class GoogleAsyncRequestImpl : public AsyncRequest, // Grpc::AsyncRequest void cancel() override; + const StreamInfo::StreamInfo& streamInfo() const override { + return GoogleAsyncStreamImpl::streamInfo(); + } private: + using GoogleAsyncStreamImpl::streamInfo; // Grpc::RawAsyncStreamCallbacks void onCreateInitialMetadata(Http::RequestHeaderMap& metadata) override; void onReceiveInitialMetadata(Http::ResponseHeaderMapPtr&&) override; diff --git a/source/common/http/BUILD b/source/common/http/BUILD index d3a4d70d7f..c9d337388d 100644 --- a/source/common/http/BUILD +++ b/source/common/http/BUILD @@ -166,11 +166,9 @@ envoy_cc_library( name = "dependency_manager", srcs = ["dependency_manager.cc"], hdrs = ["dependency_manager.h"], - external_deps = [ - "abseil_flat_hash_set", - "abseil_status", - ], deps = [ + "@com_google_absl//absl/container:flat_hash_set", + "@com_google_absl//absl/status", "@envoy_api//envoy/extensions/filters/common/dependency/v3:pkg_cc_proto", ], ) @@ -522,8 +520,6 @@ envoy_cc_library( srcs = ["utility.cc"], hdrs = ["utility.h"], external_deps = [ - "abseil_node_hash_set", - "abseil_optional", "http_parser", "quiche_http2_protocol", ], @@ -549,6 +545,8 @@ envoy_cc_library( "//source/common/network:utility_lib", "//source/common/protobuf:utility_lib", "//source/common/runtime:runtime_features_lib", + "@com_google_absl//absl/container:node_hash_set", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/config/route/v3:pkg_cc_proto", ], @@ -588,13 +586,11 @@ envoy_cc_library( name = "path_utility_lib", srcs = ["path_utility.cc"], hdrs = ["path_utility.h"], - external_deps = [ - "abseil_optional", - ], deps = [ "//envoy/http:header_map_interface", "//source/common/common:logger_lib", "//source/common/runtime:runtime_features_lib", + "@com_google_absl//absl/types:optional", "@com_googlesource_googleurl//url", ], ) @@ -619,12 +615,10 @@ envoy_cc_library( name = "status_lib", srcs = ["status.cc"], hdrs = ["status.h"], - external_deps = [ - "abseil_status", - ], deps = [ "//envoy/http:codes_interface", "//source/common/common:assert_lib", + "@com_google_absl//absl/status", ], ) diff --git a/source/common/http/conn_manager_impl.cc b/source/common/http/conn_manager_impl.cc index 8ab90fe0c1..ef4bb44f46 100644 --- a/source/common/http/conn_manager_impl.cc +++ b/source/common/http/conn_manager_impl.cc @@ -792,6 +792,10 @@ absl::optional ConnectionManagerImpl::HttpStreamIdProviderImpl::toInte *parent_.request_headers_); } +namespace { +constexpr absl::string_view kRouteFactoryName = "envoy.route_config_update_requester.default"; +} // namespace + ConnectionManagerImpl::ActiveStream::ActiveStream(ConnectionManagerImpl& connection_manager, uint32_t buffer_limit, Buffer::BufferMemoryAccountSharedPtr account) @@ -834,9 +838,8 @@ ConnectionManagerImpl::ActiveStream::ActiveStream(ConnectionManagerImpl& connect connection_manager.config_->shouldSchemeMatchUpstream()); // TODO(chaoqin-li1123): can this be moved to the on demand filter? - static const std::string route_factory = "envoy.route_config_update_requester.default"; - auto factory = - Envoy::Config::Utility::getFactoryByName(route_factory); + auto factory = Envoy::Config::Utility::getFactoryByName( + kRouteFactoryName); if (connection_manager_.config_->isRoutable() && connection_manager.config_->routeConfigProvider() != nullptr && factory) { route_config_update_requester_ = factory->createRouteConfigUpdateRequester( diff --git a/source/common/http/header_utility.cc b/source/common/http/header_utility.cc index bf8dd0b8d3..9375f4fc68 100644 --- a/source/common/http/header_utility.cc +++ b/source/common/http/header_utility.cc @@ -324,14 +324,6 @@ bool HeaderUtility::authorityIsValid(const absl::string_view header_value) { "envoy.reloadable_features.internal_authority_header_validator")) { return check_authority_h1_h2(header_value); } - -#ifdef ENVOY_NGHTTP2 - if (!Runtime::runtimeFeatureEnabled( - "envoy.reloadable_features.http2_validate_authority_with_quiche")) { - return nghttp2_check_authority(reinterpret_cast(header_value.data()), - header_value.size()) != 0; - } -#endif return http2::adapter::HeaderValidator::IsValidAuthority(header_value); } diff --git a/source/common/http/http1/BUILD b/source/common/http/http1/BUILD index b2d52f504d..84f8e2d7c3 100644 --- a/source/common/http/http1/BUILD +++ b/source/common/http/http1/BUILD @@ -70,7 +70,6 @@ envoy_cc_library( name = "conn_pool_lib", srcs = ["conn_pool.cc"], hdrs = ["conn_pool.h"], - external_deps = ["abseil_optional"], deps = [ "//envoy/event:deferred_deletable", "//envoy/event:dispatcher_interface", @@ -85,6 +84,7 @@ envoy_cc_library( "//source/common/http:headers_lib", "//source/common/runtime:runtime_features_lib", "//source/common/upstream:upstream_lib", + "@com_google_absl//absl/types:optional", ], ) @@ -92,12 +92,12 @@ envoy_cc_library( name = "settings_lib", srcs = ["settings.cc"], hdrs = ["settings.h"], - external_deps = ["abseil_optional"], deps = [ "//envoy/http:codec_interface", "//envoy/protobuf:message_validator_interface", "//source/common/config:utility_lib", "//source/common/runtime:runtime_features_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], ) diff --git a/source/common/http/http2/BUILD b/source/common/http/http2/BUILD index d4ba05d759..26fa680b9f 100644 --- a/source/common/http/http2/BUILD +++ b/source/common/http/http2/BUILD @@ -30,10 +30,6 @@ envoy_cc_library( hdrs = ["codec_impl.h"], external_deps = [ "quiche_http2_adapter", - "abseil_optional", - "abseil_inlined_vector", - "abseil_algorithm", - "abseil_cleanup", ], deps = [ ":codec_stats_lib", @@ -65,6 +61,10 @@ envoy_cc_library( "//source/common/http:utility_lib", "//source/common/network:common_connection_filter_states_lib", "//source/common/runtime:runtime_features_lib", + "@com_google_absl//absl/algorithm", + "@com_google_absl//absl/cleanup", + "@com_google_absl//absl/container:inlined_vector", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ] + envoy_select_nghttp2([envoy_external_dep_path("nghttp2")]), ) diff --git a/source/common/json/BUILD b/source/common/json/BUILD index 6967d116de..1ca1e30c9d 100644 --- a/source/common/json/BUILD +++ b/source/common/json/BUILD @@ -62,7 +62,7 @@ envoy_cc_library( envoy_cc_library( name = "constants_lib", hdrs = ["constants.h"], - external_deps = [ - "abseil_strings", + deps = [ + "@com_google_absl//absl/strings", ], ) diff --git a/source/common/network/BUILD b/source/common/network/BUILD index 3ec9a93e75..7eefab3fa3 100644 --- a/source/common/network/BUILD +++ b/source/common/network/BUILD @@ -102,7 +102,6 @@ envoy_cc_library( name = "connection_impl", srcs = ["connection_impl.cc"], hdrs = ["connection_impl.h"], - external_deps = ["abseil_optional"], deps = [ ":address_lib", ":connection_base_lib", @@ -123,6 +122,7 @@ envoy_cc_library( "//source/common/network:socket_option_factory_lib", "//source/common/runtime:runtime_features_lib", "//source/common/stream_info:stream_info_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], ) @@ -219,15 +219,13 @@ envoy_cc_library( envoy_cc_library( name = "lc_trie_lib", hdrs = ["lc_trie.h"], - external_deps = [ - "abseil_node_hash_set", - "abseil_int128", - ], deps = [ ":address_lib", ":cidr_range_lib", ":utility_lib", "//source/common/common:assert_lib", + "@com_google_absl//absl/container:node_hash_set", + "@com_google_absl//absl/numeric:int128", ], ) @@ -415,7 +413,6 @@ envoy_cc_library( name = "socket_option_lib", srcs = ["socket_option_impl.cc"], hdrs = ["socket_option_impl.h"], - external_deps = ["abseil_optional"], deps = [ ":address_lib", "//envoy/api:os_sys_calls_interface", @@ -425,6 +422,7 @@ envoy_cc_library( "//source/common/common:minimal_logger_lib", "//source/common/common:scalar_to_byte_vector_lib", "//source/common/common:utility_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], ) @@ -433,7 +431,6 @@ envoy_cc_library( name = "addr_family_aware_socket_option_lib", srcs = ["addr_family_aware_socket_option_impl.cc"], hdrs = ["addr_family_aware_socket_option_impl.h"], - external_deps = ["abseil_optional"], deps = [ ":address_lib", ":socket_lib", @@ -442,6 +439,7 @@ envoy_cc_library( "//source/common/api:os_sys_calls_lib", "//source/common/common:assert_lib", "//source/common/common:logger_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], ) @@ -467,7 +465,6 @@ envoy_cc_library( name = "socket_option_factory_lib", srcs = ["socket_option_factory.cc"], hdrs = ["socket_option_factory.h"], - external_deps = ["abseil_optional"], deps = [ ":addr_family_aware_socket_option_lib", ":address_lib", @@ -475,6 +472,7 @@ envoy_cc_library( ":win32_redirect_records_option_lib", "//envoy/network:listen_socket_interface", "//source/common/common:logger_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], ) @@ -574,12 +572,10 @@ envoy_cc_library( "filter_matcher.cc", ], hdrs = ["filter_matcher.h"], - external_deps = [ - "abseil_str_format", - ], deps = [ "//envoy/network:filter_interface", "//envoy/network:listen_socket_interface", + "@com_google_absl//absl/strings:str_format", "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", ], ) diff --git a/source/common/orca/BUILD b/source/common/orca/BUILD index fab411692e..c558cee04e 100644 --- a/source/common/orca/BUILD +++ b/source/common/orca/BUILD @@ -13,14 +13,14 @@ envoy_cc_library( srcs = ["orca_parser.cc"], hdrs = ["orca_parser.h"], external_deps = [ - "abseil_strings", - "abseil_statusor", "fmtlib", ], deps = [ "//envoy/http:header_map_interface", "//source/common/common:base64_lib", "@com_github_cncf_xds//xds/data/orca/v3:pkg_cc_proto", + "@com_google_absl//absl/status:statusor", + "@com_google_absl//absl/strings", ], ) @@ -29,10 +29,6 @@ envoy_cc_library( srcs = ["orca_load_metrics.cc"], hdrs = ["orca_load_metrics.h"], external_deps = [ - "abseil_flat_hash_set", - "abseil_status", - "abseil_strings", - "abseil_statusor", "fmtlib", ], deps = [ @@ -41,5 +37,9 @@ envoy_cc_library( "//source/common/http:header_utility_lib", "//source/common/protobuf:utility_lib_header", "@com_github_cncf_xds//xds/data/orca/v3:pkg_cc_proto", + "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/status", + "@com_google_absl//absl/status:statusor", + "@com_google_absl//absl/strings", ], ) diff --git a/source/common/quic/BUILD b/source/common/quic/BUILD index 8a91e57052..62a54d13e6 100644 --- a/source/common/quic/BUILD +++ b/source/common/quic/BUILD @@ -287,9 +287,6 @@ envoy_cc_library( "envoy_quic_server_session.h", "envoy_quic_server_stream.h", ], - external_deps = [ - "abseil_optional", - ], tags = ["nofips"], deps = [ ":envoy_quic_connection_debug_visitor_factory_interface", @@ -305,6 +302,7 @@ envoy_cc_library( "//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", ]), diff --git a/source/common/quic/platform/BUILD b/source/common/quic/platform/BUILD index f77f960786..4852feee02 100644 --- a/source/common/quic/platform/BUILD +++ b/source/common/quic/platform/BUILD @@ -40,11 +40,9 @@ envoy_package() envoy_cc_library( name = "quiche_flags_constants", hdrs = ["quiche_flags_constants.h"], - external_deps = [ - "abseil_base", - ], deps = [ "//source/common/http:http_option_limits_lib", + "@com_google_absl//absl/base", ], ) @@ -52,16 +50,14 @@ envoy_quiche_platform_impl_cc_library( name = "quiche_flags_impl_lib", srcs = ["quiche_flags_impl.cc"], hdrs = ["quiche_flags_impl.h"], - external_deps = [ - "abseil_base", - "abseil_synchronization", - ], deps = [ ":quiche_flags_constants", "//source/common/common:assert_lib", "@com_github_google_quiche//:quiche_feature_flags_list_lib", "@com_github_google_quiche//:quiche_protocol_flags_list_lib", + "@com_google_absl//absl/base", "@com_google_absl//absl/flags:flag", + "@com_google_absl//absl/synchronization", ], ) @@ -69,10 +65,10 @@ envoy_quiche_platform_impl_cc_library( name = "quiche_time_utils_impl_lib", srcs = ["quiche_time_utils_impl.cc"], hdrs = ["quiche_time_utils_impl.h"], - external_deps = [ - "abseil_base", - "abseil_optional", - "abseil_time", + deps = [ + "@com_google_absl//absl/base", + "@com_google_absl//absl/time", + "@com_google_absl//absl/types:optional", ], ) @@ -96,20 +92,18 @@ envoy_quiche_platform_impl_cc_library( envoy_quiche_platform_impl_cc_library( name = "quic_base_impl_lib", - external_deps = [ - "abseil_base", - "abseil_hash", - "abseil_inlined_vector", - "abseil_memory", - "abseil_node_hash_map", - "abseil_node_hash_set", - ], tags = ["nofips"], deps = [ ":quiche_flags_impl_lib", "//source/common/common:assert_lib", "@com_github_google_quiche//:quic_platform_export", + "@com_google_absl//absl/base", "@com_google_absl//absl/container:btree", + "@com_google_absl//absl/container:inlined_vector", + "@com_google_absl//absl/container:node_hash_map", + "@com_google_absl//absl/container:node_hash_set", + "@com_google_absl//absl/hash", + "@com_google_absl//absl/memory", ], ) @@ -144,16 +138,14 @@ envoy_quiche_platform_impl_cc_library( hdrs = [ "quiche_mem_slice_impl.h", ], - external_deps = [ - "abseil_hash", - "abseil_node_hash_map", - ], deps = [ ":quiche_flags_impl_lib", ":quiche_logging_impl_lib", "//source/common/buffer:buffer_lib", "@com_github_google_quiche//:quiche_common_buffer_allocator_lib", "@com_github_google_quiche//:quiche_common_callbacks", + "@com_google_absl//absl/container:node_hash_map", + "@com_google_absl//absl/hash", ], ) @@ -167,6 +159,6 @@ envoy_quiche_platform_impl_cc_library( envoy_quiche_platform_impl_cc_library( name = "quiche_export_impl_lib", hdrs = ["quiche_export_impl.h"], - external_deps = ["abseil_base"], tags = ["nofips"], + deps = ["@com_google_absl//absl/base"], ) diff --git a/source/common/router/BUILD b/source/common/router/BUILD index 70200e05ea..6f86c99850 100644 --- a/source/common/router/BUILD +++ b/source/common/router/BUILD @@ -35,7 +35,6 @@ envoy_cc_library( name = "config_lib", srcs = ["config_impl.cc"], hdrs = ["config_impl.h"], - external_deps = ["abseil_optional"], deps = [ ":config_utility_lib", ":context_lib", @@ -77,6 +76,7 @@ envoy_cc_library( "//source/extensions/matching/network/common:inputs_lib", "//source/extensions/path/match/uri_template:config", "//source/extensions/path/rewrite/uri_template:config", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/common/matcher/v3:pkg_cc_proto", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/config/route/v3:pkg_cc_proto", @@ -235,15 +235,13 @@ envoy_cc_library( name = "scoped_config_lib", srcs = ["scoped_config_impl.cc"], hdrs = ["scoped_config_impl.h"], - external_deps = [ - "abseil_str_format", - ], deps = [ ":config_lib", "//envoy/router:rds_interface", "//envoy/router:scopes_interface", "//envoy/thread_local:thread_local_interface", "//source/common/protobuf:utility_lib", + "@com_google_absl//absl/strings:str_format", "@envoy_api//envoy/config/route/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg_cc_proto", ], @@ -284,7 +282,6 @@ envoy_cc_library( name = "retry_state_lib", srcs = ["retry_state_impl.cc"], hdrs = ["retry_state_impl.h"], - external_deps = ["abseil_optional"], deps = [ "//envoy/event:timer_interface", "//envoy/http:codec_interface", @@ -300,6 +297,7 @@ envoy_cc_library( "//source/common/http:header_utility_lib", "//source/common/http:headers_lib", "//source/common/http:utility_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/route/v3:pkg_cc_proto", ], ) diff --git a/source/common/router/config_impl.cc b/source/common/router/config_impl.cc index 7c70a5f42e..a3c9b8ba20 100644 --- a/source/common/router/config_impl.cc +++ b/source/common/router/config_impl.cc @@ -380,9 +380,20 @@ Upstream::RetryPrioritySharedPtr RetryPolicyImpl::retryPriority() const { *validation_visitor_, num_retries_); } +absl::StatusOr> InternalRedirectPolicyImpl::create( + const envoy::config::route::v3::InternalRedirectPolicy& policy_config, + ProtobufMessage::ValidationVisitor& validator, absl::string_view current_route_name) { + absl::Status creation_status = absl::OkStatus(); + auto ret = std::unique_ptr(new InternalRedirectPolicyImpl( + policy_config, validator, current_route_name, creation_status)); + RETURN_IF_NOT_OK(creation_status); + return ret; +} + InternalRedirectPolicyImpl::InternalRedirectPolicyImpl( const envoy::config::route::v3::InternalRedirectPolicy& policy_config, - ProtobufMessage::ValidationVisitor& validator, absl::string_view current_route_name) + ProtobufMessage::ValidationVisitor& validator, absl::string_view current_route_name, + absl::Status& creation_status) : current_route_name_(current_route_name), redirect_response_codes_(buildRedirectResponseCodes(policy_config)), max_internal_redirects_( @@ -397,7 +408,9 @@ InternalRedirectPolicyImpl::InternalRedirectPolicyImpl( } for (const auto& header : policy_config.response_headers_to_copy()) { if (!Http::HeaderUtility::isModifiableHeader(header)) { - throwEnvoyExceptionOrPanic(":-prefixed headers or Hosts may not be specified here."); + creation_status = + absl::InvalidArgumentError(":-prefixed headers or Hosts may not be specified here."); + return; } response_headers_to_copy_.emplace_back(header); } @@ -560,7 +573,8 @@ RouteEntryImplBase::RouteEntryImplBase(const CommonVirtualHostSharedPtr& vhost, : nullptr), hedge_policy_(buildHedgePolicy(vhost->hedgePolicy(), route.route())), internal_redirect_policy_( - buildInternalRedirectPolicy(route.route(), validator, route.name())), + THROW_OR_RETURN_VALUE(buildInternalRedirectPolicy(route.route(), validator, route.name()), + std::unique_ptr)), config_headers_( Http::HeaderUtility::buildHeaderDataVector(route.match().headers(), factory_context)), dynamic_metadata_([&]() { @@ -1186,12 +1200,13 @@ absl::StatusOr> RouteEntryImplBase::buildRetryP return nullptr; } -std::unique_ptr RouteEntryImplBase::buildInternalRedirectPolicy( +absl::StatusOr> +RouteEntryImplBase::buildInternalRedirectPolicy( const envoy::config::route::v3::RouteAction& route_config, ProtobufMessage::ValidationVisitor& validator, absl::string_view current_route_name) const { if (route_config.has_internal_redirect_policy()) { - return std::make_unique(route_config.internal_redirect_policy(), - validator, current_route_name); + return InternalRedirectPolicyImpl::create(route_config.internal_redirect_policy(), validator, + current_route_name); } envoy::config::route::v3::InternalRedirectPolicy policy_config; switch (route_config.internal_redirect_action()) { @@ -1205,7 +1220,7 @@ std::unique_ptr RouteEntryImplBase::buildInternalRed if (route_config.has_max_internal_redirects()) { *policy_config.mutable_max_internal_redirects() = route_config.max_internal_redirects(); } - return std::make_unique(policy_config, validator, current_route_name); + return InternalRedirectPolicyImpl::create(policy_config, validator, current_route_name); } RouteEntryImplBase::OptionalTimeouts RouteEntryImplBase::buildOptionalTimeouts( diff --git a/source/common/router/config_impl.h b/source/common/router/config_impl.h index c8dce5ceec..0b3ffdaefd 100644 --- a/source/common/router/config_impl.h +++ b/source/common/router/config_impl.h @@ -598,11 +598,11 @@ class RouteTracingImpl : public RouteTracing { */ class InternalRedirectPolicyImpl : public InternalRedirectPolicy { public: + static absl::StatusOr> + create(const envoy::config::route::v3::InternalRedirectPolicy& policy_config, + ProtobufMessage::ValidationVisitor& validator, absl::string_view current_route_name); // Constructor that enables internal redirect with policy_config controlling the configurable // behaviors. - InternalRedirectPolicyImpl(const envoy::config::route::v3::InternalRedirectPolicy& policy_config, - ProtobufMessage::ValidationVisitor& validator, - absl::string_view current_route_name); // Default constructor that disables internal redirect. InternalRedirectPolicyImpl() = default; @@ -620,6 +620,9 @@ class InternalRedirectPolicyImpl : public InternalRedirectPolicy { bool isCrossSchemeRedirectAllowed() const override { return allow_cross_scheme_redirect_; } private: + InternalRedirectPolicyImpl(const envoy::config::route::v3::InternalRedirectPolicy& policy_config, + ProtobufMessage::ValidationVisitor& validator, + absl::string_view current_route_name, absl::Status& creation_status); absl::flat_hash_set buildRedirectResponseCodes( const envoy::config::route::v3::InternalRedirectPolicy& policy_config) const; @@ -1175,7 +1178,7 @@ class RouteEntryImplBase : public RouteEntryAndRoute, ProtobufMessage::ValidationVisitor& validation_visitor, Server::Configuration::ServerFactoryContext& factory_context) const; - std::unique_ptr + absl::StatusOr> buildInternalRedirectPolicy(const envoy::config::route::v3::RouteAction& route_config, ProtobufMessage::ValidationVisitor& validator, absl::string_view current_route_name) const; diff --git a/source/common/router/router.cc b/source/common/router/router.cc index 1aaf6bb77d..6fab5c046a 100644 --- a/source/common/router/router.cc +++ b/source/common/router/router.cc @@ -2147,7 +2147,8 @@ void Filter::maybeProcessOrcaLoadReport(const Envoy::Http::HeaderMap& headers_or if (orca_load_report_callbacks_.has_value()) { const absl::Status status = orca_load_report_callbacks_->onOrcaLoadReport(*orca_load_report); if (!status.ok()) { - ENVOY_LOG_MISC(error, "Failed to invoke OrcaLoadReportCallbacks: {}", status.message()); + ENVOY_STREAM_LOG(error, "Failed to invoke OrcaLoadReportCallbacks: {}", *callbacks_, + status.message()); } } } diff --git a/source/common/runtime/runtime_features.cc b/source/common/runtime/runtime_features.cc index 860aaf353e..ac6d760161 100644 --- a/source/common/runtime/runtime_features.cc +++ b/source/common/runtime/runtime_features.cc @@ -58,7 +58,6 @@ RUNTIME_GUARD(envoy_reloadable_features_http2_discard_host_header); // Ignore the automated "remove this flag" issue: we should keep this for 1 year. RUNTIME_GUARD(envoy_reloadable_features_http2_use_oghttp2); RUNTIME_GUARD(envoy_reloadable_features_http2_use_visitor_for_data); -RUNTIME_GUARD(envoy_reloadable_features_http2_validate_authority_with_quiche); RUNTIME_GUARD(envoy_reloadable_features_http3_happy_eyeballs); RUNTIME_GUARD(envoy_reloadable_features_http3_remove_empty_trailers); RUNTIME_GUARD(envoy_reloadable_features_http_filter_avoid_reentrant_local_reply); @@ -75,6 +74,7 @@ RUNTIME_GUARD(envoy_reloadable_features_no_timer_based_rate_limit_token_bucket); RUNTIME_GUARD(envoy_reloadable_features_original_dst_rely_on_idle_timeout); RUNTIME_GUARD(envoy_reloadable_features_prefer_ipv6_dns_on_macos); RUNTIME_GUARD(envoy_reloadable_features_proxy_104); +RUNTIME_GUARD(envoy_reloadable_features_proxy_ssl_port); RUNTIME_GUARD(envoy_reloadable_features_proxy_status_mapping_more_core_response_flags); RUNTIME_GUARD(envoy_reloadable_features_quic_connect_client_udp_sockets); RUNTIME_GUARD(envoy_reloadable_features_quic_receive_ecn); diff --git a/source/common/singleton/BUILD b/source/common/singleton/BUILD index 728c2ed782..1580ec85b2 100644 --- a/source/common/singleton/BUILD +++ b/source/common/singleton/BUILD @@ -29,6 +29,8 @@ envoy_cc_library( envoy_cc_library( name = "threadsafe_singleton", hdrs = ["threadsafe_singleton.h"], - external_deps = ["abseil_base"], - deps = ["//source/common/common:assert_lib"], + deps = [ + "//source/common/common:assert_lib", + "@com_google_absl//absl/base", + ], ) diff --git a/source/common/ssl/BUILD b/source/common/ssl/BUILD index 4526fe428f..9a903309ba 100644 --- a/source/common/ssl/BUILD +++ b/source/common/ssl/BUILD @@ -26,12 +26,12 @@ envoy_cc_library( name = "certificate_validation_context_config_impl_lib", srcs = ["certificate_validation_context_config_impl.cc"], hdrs = ["certificate_validation_context_config_impl.h"], - external_deps = ["abseil_optional"], deps = [ "//envoy/api:api_interface", "//envoy/ssl:certificate_validation_context_config_interface", "//source/common/common:empty_string", "//source/common/config:datasource_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/transport_sockets/tls/v3:pkg_cc_proto", "@envoy_api//envoy/type/matcher/v3:pkg_cc_proto", diff --git a/source/common/stats/BUILD b/source/common/stats/BUILD index 5c35a29df6..b2852de43a 100644 --- a/source/common/stats/BUILD +++ b/source/common/stats/BUILD @@ -29,12 +29,12 @@ envoy_cc_library( name = "custom_stat_namespaces_lib", srcs = ["custom_stat_namespaces_impl.cc"], hdrs = ["custom_stat_namespaces_impl.h"], - external_deps = ["abseil_flat_hash_set"], deps = [ "//envoy/stats:custom_stat_namespaces_interface", "//source/common/common:assert_lib", "//source/common/common:macros", "//source/common/common:thread_lib", + "@com_google_absl//absl/container:flat_hash_set", ], ) @@ -181,10 +181,6 @@ envoy_cc_library( name = "symbol_table_lib", srcs = ["symbol_table.cc"], hdrs = ["symbol_table.h"], - external_deps = [ - "abseil_base", - "abseil_inlined_vector", - ], deps = [ ":recent_lookups_lib", "//source/common/common:assert_lib", @@ -192,6 +188,8 @@ envoy_cc_library( "//source/common/common:minimal_logger_lib", "//source/common/common:thread_lib", "//source/common/common:utility_lib", + "@com_google_absl//absl/base", + "@com_google_absl//absl/container:inlined_vector", ], ) @@ -211,7 +209,6 @@ envoy_cc_library( name = "tag_producer_lib", srcs = ["tag_producer_impl.cc"], hdrs = ["tag_producer_impl.h"], - external_deps = ["abseil_node_hash_set"], deps = [ ":symbol_table_lib", ":tag_extractor_lib", @@ -220,6 +217,7 @@ envoy_cc_library( "//source/common/common:perf_annotation_lib", "//source/common/config:well_known_names", "//source/common/protobuf", + "@com_google_absl//absl/container:node_hash_set", "@envoy_api//envoy/config/metrics/v3:pkg_cc_proto", ], ) diff --git a/source/common/stream_info/BUILD b/source/common/stream_info/BUILD index 452ccb42d0..175913e022 100644 --- a/source/common/stream_info/BUILD +++ b/source/common/stream_info/BUILD @@ -38,16 +38,14 @@ envoy_cc_library( name = "utility_lib", srcs = ["utility.cc"], hdrs = ["utility.h"], - external_deps = [ - "abseil_optional", - "abseil_node_hash_map", - ], deps = [ "//envoy/common:time_interface", "//envoy/http:codes_interface", "//envoy/stream_info:stream_info_interface", "//source/common/http:default_server_string_lib", "//source/common/runtime:runtime_features_lib", + "@com_google_absl//absl/container:node_hash_map", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg_cc_proto", ], ) diff --git a/source/common/tcp/BUILD b/source/common/tcp/BUILD index cbe05d4b15..9d944f895c 100644 --- a/source/common/tcp/BUILD +++ b/source/common/tcp/BUILD @@ -16,7 +16,6 @@ envoy_cc_library( hdrs = [ "conn_pool.h", ], - external_deps = ["abseil_optional"], deps = [ "//envoy/event:deferred_deletable", "//envoy/event:dispatcher_interface", @@ -33,6 +32,7 @@ envoy_cc_library( "//source/common/network:utility_lib", "//source/common/stats:timespan_lib", "//source/common/upstream:upstream_lib", + "@com_google_absl//absl/types:optional", ], ) diff --git a/source/common/tls/BUILD b/source/common/tls/BUILD index ca18f49206..4a0b1b3b71 100644 --- a/source/common/tls/BUILD +++ b/source/common/tls/BUILD @@ -64,10 +64,6 @@ envoy_cc_library( srcs = ["ssl_socket.cc"], hdrs = ["ssl_socket.h"], external_deps = [ - "abseil_hash", - "abseil_node_hash_map", - "abseil_optional", - "abseil_synchronization", "ssl", ], # TLS is core functionality. @@ -91,6 +87,10 @@ envoy_cc_library( "//source/common/common:thread_annotations", "//source/common/http:headers_lib", "//source/common/network:transport_socket_options_lib", + "@com_google_absl//absl/container:node_hash_set", + "@com_google_absl//absl/hash", + "@com_google_absl//absl/synchronization", + "@com_google_absl//absl/types:optional", ], ) @@ -99,14 +99,14 @@ envoy_cc_library( srcs = ["client_ssl_socket.cc"], hdrs = ["client_ssl_socket.h"], external_deps = [ - "abseil_hash", - "abseil_node_hash_map", - "abseil_optional", - "abseil_synchronization", "ssl", ], deps = [ ":ssl_socket_base", + "@com_google_absl//absl/container:node_hash_set", + "@com_google_absl//absl/hash", + "@com_google_absl//absl/synchronization", + "@com_google_absl//absl/types:optional", ], ) @@ -115,14 +115,14 @@ envoy_cc_library( srcs = ["server_ssl_socket.cc"], hdrs = ["server_ssl_socket.h"], external_deps = [ - "abseil_hash", - "abseil_node_hash_map", - "abseil_optional", - "abseil_synchronization", "ssl", ], deps = [ ":ssl_socket_base", + "@com_google_absl//absl/container:node_hash_set", + "@com_google_absl//absl/hash", + "@com_google_absl//absl/synchronization", + "@com_google_absl//absl/types:optional", ], ) @@ -186,8 +186,6 @@ envoy_cc_library( "context_manager_impl.h", ], external_deps = [ - "abseil_node_hash_set", - "abseil_synchronization", "ssl", ], # TLS is core functionality. @@ -215,6 +213,8 @@ envoy_cc_library( "//source/common/tls/cert_validator:cert_validator_lib", "//source/common/tls/private_key:private_key_manager_lib", "@com_github_google_quiche//:quic_core_crypto_proof_source_lib", + "@com_google_absl//absl/container:node_hash_set", + "@com_google_absl//absl/synchronization", "@envoy_api//envoy/admin/v3:pkg_cc_proto", "@envoy_api//envoy/type/matcher/v3:pkg_cc_proto", ], diff --git a/source/common/tls/cert_validator/BUILD b/source/common/tls/cert_validator/BUILD index f0b1b69e8f..ed1619c6d5 100644 --- a/source/common/tls/cert_validator/BUILD +++ b/source/common/tls/cert_validator/BUILD @@ -25,8 +25,6 @@ envoy_cc_library( ], external_deps = [ "ssl", - "abseil_base", - "abseil_hash", ], visibility = ["//visibility:public"], deps = [ @@ -44,6 +42,8 @@ envoy_cc_library( "//source/common/stats:utility_lib", "//source/common/tls:stats_lib", "//source/common/tls:utility_lib", + "@com_google_absl//absl/base", + "@com_google_absl//absl/hash", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/transport_sockets/tls/v3:pkg_cc_proto", "@envoy_api//envoy/type/matcher/v3:pkg_cc_proto", diff --git a/source/common/upstream/BUILD b/source/common/upstream/BUILD index a483b745f5..e96b08a318 100644 --- a/source/common/upstream/BUILD +++ b/source/common/upstream/BUILD @@ -427,7 +427,6 @@ envoy_cc_library( "transport_socket_match_impl.h", "upstream_impl.h", ], - external_deps = ["abseil_synchronization"], deps = [ ":load_balancer_context_base_lib", ":resource_manager_lib", @@ -467,6 +466,7 @@ envoy_cc_library( "//source/extensions/upstreams/http:config", "//source/extensions/upstreams/tcp:config", "//source/server:transport_socket_config_lib", + "@com_google_absl//absl/synchronization", "@envoy_api//envoy/config/cluster/v3:pkg_cc_proto", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/config/endpoint/v3:pkg_cc_proto", @@ -554,9 +554,9 @@ envoy_cc_library( hdrs = [ "default_local_address_selector.h", ], - external_deps = ["abseil_optional"], deps = [ "//envoy/upstream:upstream_interface", + "@com_google_absl//absl/types:optional", ], ) @@ -568,7 +568,6 @@ envoy_cc_library( hdrs = [ "default_local_address_selector_factory.h", ], - external_deps = ["abseil_optional"], deps = [ ":default_local_address_selector", "//envoy/network:address_interface", @@ -576,6 +575,7 @@ envoy_cc_library( "//envoy/registry", "//envoy/upstream:upstream_interface", "//source/common/network:resolver_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/upstream/local_address_selector/v3:pkg_cc_proto", ], # Ensure this factory in the source is always linked in. diff --git a/source/exe/BUILD b/source/exe/BUILD index 8885a49239..0a6038e01f 100644 --- a/source/exe/BUILD +++ b/source/exe/BUILD @@ -57,14 +57,12 @@ envoy_cc_library( envoy_cc_library( name = "envoy_main_entry_lib", srcs = ["main.cc"], - external_deps = [ - "abseil_symbolize", - ], deps = [ ":envoy_main_common_lib", ":platform_impl_lib", ":scm_impl_lib", "//source/server:options_lib", + "@com_google_absl//absl/debugging:symbolize", ], ) diff --git a/source/extensions/access_loggers/open_telemetry/BUILD b/source/extensions/access_loggers/open_telemetry/BUILD index c1042afa52..1d03346d0a 100644 --- a/source/extensions/access_loggers/open_telemetry/BUILD +++ b/source/extensions/access_loggers/open_telemetry/BUILD @@ -78,11 +78,11 @@ envoy_cc_library( name = "substitution_formatter_lib", srcs = ["substitution_formatter.cc"], hdrs = ["substitution_formatter.h"], - external_deps = ["abseil_str_format"], deps = [ "//envoy/stream_info:stream_info_interface", "//source/common/common:assert_lib", "//source/common/formatter:substitution_formatter_lib", + "@com_google_absl//absl/strings:str_format", "@opentelemetry_proto//:common_cc_proto", ], ) diff --git a/source/extensions/common/aws/BUILD b/source/extensions/common/aws/BUILD index cd651d362a..fda282db82 100644 --- a/source/extensions/common/aws/BUILD +++ b/source/extensions/common/aws/BUILD @@ -92,7 +92,9 @@ envoy_cc_library( envoy_cc_library( name = "credentials_provider_interface", hdrs = ["credentials_provider.h"], - external_deps = ["abseil_optional"], + deps = [ + "@com_google_absl//absl/types:optional", + ], ) envoy_cc_library( @@ -111,7 +113,6 @@ envoy_cc_library( name = "credentials_provider_impl_lib", srcs = ["credentials_provider_impl.cc"], hdrs = ["credentials_provider_impl.h"], - external_deps = ["abseil_time"], deps = [ ":credentials_provider_interface", ":metadata_fetcher_lib", @@ -124,6 +125,7 @@ envoy_cc_library( "//source/common/json:json_loader_lib", "//source/common/runtime:runtime_features_lib", "//source/common/tracing:http_tracer_lib", + "@com_google_absl//absl/time", ], ) @@ -155,7 +157,9 @@ envoy_cc_library( envoy_cc_library( name = "region_provider_interface", hdrs = ["region_provider.h"], - external_deps = ["abseil_optional"], + deps = [ + "@com_google_absl//absl/types:optional", + ], ) envoy_cc_library( diff --git a/source/extensions/common/dubbo/BUILD b/source/extensions/common/dubbo/BUILD index d3c9340fdb..ec22a68ea7 100644 --- a/source/extensions/common/dubbo/BUILD +++ b/source/extensions/common/dubbo/BUILD @@ -38,10 +38,10 @@ envoy_cc_library( envoy_cc_library( name = "metadata_lib", hdrs = ["metadata.h"], - external_deps = ["abseil_optional"], deps = [ ":message_lib", "//source/common/buffer:buffer_lib", + "@com_google_absl//absl/types:optional", ], ) diff --git a/source/extensions/common/wasm/BUILD b/source/extensions/common/wasm/BUILD index 8022b0d744..c45b87e200 100644 --- a/source/extensions/common/wasm/BUILD +++ b/source/extensions/common/wasm/BUILD @@ -98,8 +98,6 @@ envoy_cc_extension( ":wasm_hdr", ":wasm_runtime_factory_interface", "//envoy/server:lifecycle_notifier_interface", - "//external:abseil_base", - "//external:abseil_node_hash_map", "//external:zlib", "//source/common/buffer:buffer_lib", "//source/common/common:enum_to_int", @@ -115,6 +113,8 @@ envoy_cc_extension( "//source/extensions/common/wasm/ext:set_envoy_filter_state_cc_proto", "//source/extensions/common/wasm/ext:verify_signature_cc_proto", "//source/extensions/filters/common/expr:context_lib", + "@com_google_absl//absl/base", + "@com_google_absl//absl/container:node_hash_map", "@com_google_cel_cpp//eval/public:builtin_func_registrar", "@com_google_cel_cpp//eval/public:cel_expr_builder_factory", "@com_google_cel_cpp//eval/public:cel_value", diff --git a/source/extensions/extensions_metadata.yaml b/source/extensions/extensions_metadata.yaml index 8bde254269..0b20fe9edf 100644 --- a/source/extensions/extensions_metadata.yaml +++ b/source/extensions/extensions_metadata.yaml @@ -408,7 +408,7 @@ envoy.filters.http.grpc_stats: categories: - envoy.filters.http security_posture: unknown - status: alpha + status: stable type_urls: - envoy.extensions.filters.http.grpc_stats.v3.FilterConfig envoy.filters.http.grpc_web: @@ -1309,7 +1309,7 @@ envoy.transport_sockets.tcp_stats: - envoy.transport_sockets.downstream - envoy.transport_sockets.upstream security_posture: robust_to_untrusted_downstream_and_upstream - status: alpha + status: stable type_urls: - envoy.extensions.transport_sockets.tcp_stats.v3.Config envoy.transport_sockets.tls: diff --git a/source/extensions/filters/common/ext_authz/ext_authz.h b/source/extensions/filters/common/ext_authz/ext_authz.h index c639e8c3d4..4aa08a1c14 100644 --- a/source/extensions/filters/common/ext_authz/ext_authz.h +++ b/source/extensions/filters/common/ext_authz/ext_authz.h @@ -165,6 +165,11 @@ class Client { virtual void check(RequestCallbacks& callback, const envoy::service::auth::v3::CheckRequest& request, Tracing::Span& parent_span, const StreamInfo::StreamInfo& stream_info) PURE; + + /** + * Returns streamInfo of the current request if possible. By default just return a nullptr. + */ + virtual StreamInfo::StreamInfo const* streamInfo() const { return nullptr; } }; using ClientPtr = std::unique_ptr; diff --git a/source/extensions/filters/common/ext_authz/ext_authz_grpc_impl.h b/source/extensions/filters/common/ext_authz/ext_authz_grpc_impl.h index 845a79cdfa..425ef493a7 100644 --- a/source/extensions/filters/common/ext_authz/ext_authz_grpc_impl.h +++ b/source/extensions/filters/common/ext_authz/ext_authz_grpc_impl.h @@ -51,6 +51,9 @@ class GrpcClientImpl : public Client, void cancel() override; void check(RequestCallbacks& callbacks, const envoy::service::auth::v3::CheckRequest& request, Tracing::Span& parent_span, const StreamInfo::StreamInfo& stream_info) override; + StreamInfo::StreamInfo const* streamInfo() const override { + return request_ ? &request_->streamInfo() : nullptr; + } // Grpc::AsyncRequestCallbacks void onCreateInitialMetadata(Http::RequestHeaderMap&) override {} diff --git a/source/extensions/filters/common/ratelimit/BUILD b/source/extensions/filters/common/ratelimit/BUILD index 6529fa3851..d69ea98a71 100644 --- a/source/extensions/filters/common/ratelimit/BUILD +++ b/source/extensions/filters/common/ratelimit/BUILD @@ -33,12 +33,12 @@ envoy_cc_library( envoy_cc_library( name = "ratelimit_client_interface", hdrs = ["ratelimit.h"], - external_deps = ["abseil_optional"], deps = [ "//envoy/ratelimit:ratelimit_interface", "//envoy/singleton:manager_interface", "//envoy/tracing:tracer_interface", "//source/common/stats:symbol_table_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/service/ratelimit/v3:pkg_cc_proto", ], ) diff --git a/source/extensions/filters/common/rbac/BUILD b/source/extensions/filters/common/rbac/BUILD index 5cb7ee9d20..bf3dcf04d2 100644 --- a/source/extensions/filters/common/rbac/BUILD +++ b/source/extensions/filters/common/rbac/BUILD @@ -27,7 +27,6 @@ envoy_cc_library( "matcher_extension.h", "matchers.h", ], - external_deps = ["abseil_optional"], tags = ["skip_on_windows"], deps = [ "//envoy/http:header_map_interface", @@ -39,6 +38,7 @@ envoy_cc_library( "//source/common/network:cidr_range_lib", "//source/extensions/filters/common/expr:evaluator_lib", "//source/extensions/path/match/uri_template:uri_template_match_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/config/rbac/v3:pkg_cc_proto", "@envoy_api//envoy/config/route/v3:pkg_cc_proto", diff --git a/source/extensions/filters/http/cache/BUILD b/source/extensions/filters/http/cache/BUILD index 7eaf3a4114..9107e06fc5 100644 --- a/source/extensions/filters/http/cache/BUILD +++ b/source/extensions/filters/http/cache/BUILD @@ -111,7 +111,6 @@ envoy_cc_library( name = "range_utils_lib", srcs = ["range_utils.cc"], hdrs = ["range_utils.h"], - external_deps = ["abseil_optional"], deps = [ ":cache_headers_utils_lib", ":key_cc_proto", @@ -120,6 +119,7 @@ envoy_cc_library( "//source/common/common:assert_lib", "//source/common/common:logger_lib", "//source/common/http:headers_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/extensions/filters/http/cache/v3:pkg_cc_proto", ], ) @@ -128,7 +128,6 @@ envoy_cc_library( name = "cache_headers_utils_lib", srcs = ["cache_headers_utils.cc"], hdrs = ["cache_headers_utils.h"], - external_deps = ["abseil_optional"], deps = [ ":cache_custom_headers", "//envoy/common:time_interface", @@ -139,6 +138,7 @@ envoy_cc_library( "//source/common/http:headers_lib", "//source/common/protobuf", "@com_google_absl//absl/container:btree", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/extensions/filters/http/cache/v3:pkg_cc_proto", ], ) diff --git a/source/extensions/filters/http/cors/BUILD b/source/extensions/filters/http/cors/BUILD index 60b5e0d42a..5aefb9449c 100644 --- a/source/extensions/filters/http/cors/BUILD +++ b/source/extensions/filters/http/cors/BUILD @@ -16,9 +16,6 @@ envoy_cc_library( name = "cors_filter_lib", srcs = ["cors_filter.cc"], hdrs = ["cors_filter.h"], - external_deps = [ - "abseil_inlined_vector", - ], deps = [ "//envoy/http:codes_interface", "//envoy/http:filter_interface", @@ -28,6 +25,7 @@ envoy_cc_library( "//source/common/http:header_map_lib", "//source/common/http:headers_lib", "//source/common/http:utility_lib", + "@com_google_absl//absl/container:inlined_vector", ], ) diff --git a/source/extensions/filters/http/ext_authz/ext_authz.cc b/source/extensions/filters/http/ext_authz/ext_authz.cc index 92bde93d37..b1713614ca 100644 --- a/source/extensions/filters/http/ext_authz/ext_authz.cc +++ b/source/extensions/filters/http/ext_authz/ext_authz.cc @@ -90,6 +90,7 @@ FilterConfig::FilterConfig(const envoy::extensions::filters::http::ext_authz::v3 runtime_(factory_context.runtime()), http_context_(factory_context.httpContext()), filter_metadata_(config.has_filter_metadata() ? absl::optional(config.filter_metadata()) : absl::nullopt), + emit_filter_state_stats_(config.emit_filter_state_stats()), filter_enabled_(config.has_filter_enabled() ? absl::optional( Runtime::FractionalPercent(config.filter_enabled(), runtime_)) @@ -176,6 +177,20 @@ void Filter::initiateCall(const Http::RequestHeaderMap& headers) { return; } + // Now that we'll definitely be making the request, add filter state stats if configured to do so. + const Envoy::StreamInfo::FilterStateSharedPtr& filter_state = + decoder_callbacks_->streamInfo().filterState(); + if ((config_->emitFilterStateStats() || config_->filterMetadata().has_value()) && + !filter_state->hasData(decoder_callbacks_->filterConfigName())) { + filter_state->setData(decoder_callbacks_->filterConfigName(), + std::make_shared(config_->filterMetadata()), + Envoy::StreamInfo::FilterState::StateType::Mutable, + Envoy::StreamInfo::FilterState::LifeSpan::Request); + + logging_info_ = + filter_state->getDataMutable(decoder_callbacks_->filterConfigName()); + } + absl::optional maybe_merged_per_route_config; for (const auto* cfg : Http::Utility::getAllPerFilterConfig(decoder_callbacks_)) { @@ -384,14 +399,36 @@ Http::FilterMetadataStatus Filter::encodeMetadata(Http::MetadataMap&) { void Filter::setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) { decoder_callbacks_ = &callbacks; - const Envoy::StreamInfo::FilterStateSharedPtr& filter_state = - decoder_callbacks_->streamInfo().filterState(); - if (config_->filterMetadata().has_value() && - !filter_state->hasData(decoder_callbacks_->filterConfigName())) { - filter_state->setData(decoder_callbacks_->filterConfigName(), - std::make_shared(*config_->filterMetadata()), - Envoy::StreamInfo::FilterState::StateType::ReadOnly, - Envoy::StreamInfo::FilterState::LifeSpan::Request); +} + +void Filter::updateLoggingInfo() { + if (!config_->emitFilterStateStats()) { + return; + } + + // Latency is the only stat available if we aren't using envoy grpc. + if (start_time_.has_value()) { + logging_info_->setLatency(std::chrono::duration_cast( + decoder_callbacks_->dispatcher().timeSource().monotonicTime() - start_time_.value())); + } + + auto const* stream_info = client_->streamInfo(); + if (stream_info == nullptr) { + return; + } + + const auto& bytes_meter = stream_info->getUpstreamBytesMeter(); + if (bytes_meter != nullptr) { + logging_info_->setBytesSent(bytes_meter->wireBytesSent()); + logging_info_->setBytesReceived(bytes_meter->wireBytesReceived()); + } + if (stream_info->upstreamInfo().has_value()) { + logging_info_->setUpstreamHost(stream_info->upstreamInfo()->upstreamHost()); + } + absl::optional cluster_info = + stream_info->upstreamClusterInfo(); + if (cluster_info) { + logging_info_->setClusterInfo(std::move(*cluster_info)); } } @@ -422,6 +459,8 @@ void Filter::onComplete(Filters::Common::ExtAuthz::ResponsePtr&& response) { using Filters::Common::ExtAuthz::CheckStatus; Stats::StatName empty_stat_name; + updateLoggingInfo(); + if (!response->dynamic_metadata.fields().empty()) { if (!config_->enableDynamicMetadataIngestion()) { ENVOY_STREAM_LOG(trace, diff --git a/source/extensions/filters/http/ext_authz/ext_authz.h b/source/extensions/filters/http/ext_authz/ext_authz.h index 5e740e6dfb..61ec151ccc 100644 --- a/source/extensions/filters/http/ext_authz/ext_authz.h +++ b/source/extensions/filters/http/ext_authz/ext_authz.h @@ -53,13 +53,41 @@ struct ExtAuthzFilterStats { class ExtAuthzLoggingInfo : public Envoy::StreamInfo::FilterState::Object { public: - explicit ExtAuthzLoggingInfo(const Envoy::ProtobufWkt::Struct& filter_metadata) + explicit ExtAuthzLoggingInfo(const absl::optional filter_metadata) : filter_metadata_(filter_metadata) {} - const ProtobufWkt::Struct& filterMetadata() const { return filter_metadata_; } + const absl::optional& filterMetadata() const { return filter_metadata_; } + absl::optional latency() const { return latency_; }; + absl::optional bytesSent() const { return bytes_sent_; } + absl::optional bytesReceived() const { return bytes_received_; } + Upstream::ClusterInfoConstSharedPtr clusterInfo() const { return cluster_info_; } + Upstream::HostDescriptionConstSharedPtr upstreamHost() const { return upstream_host_; } + + void setLatency(std::chrono::microseconds ms) { latency_ = ms; }; + void setBytesSent(uint64_t bytes_sent) { bytes_sent_ = bytes_sent; } + void setBytesReceived(uint64_t bytes_received) { bytes_received_ = bytes_received; } + void setClusterInfo(Upstream::ClusterInfoConstSharedPtr cluster_info) { + cluster_info_ = std::move(cluster_info); + } + void setUpstreamHost(Upstream::HostDescriptionConstSharedPtr upstream_host) { + upstream_host_ = std::move(upstream_host); + } + + // For convenience in testing. + void clearLatency() { latency_ = absl::nullopt; }; + void clearBytesSent() { bytes_sent_ = absl::nullopt; } + void clearBytesReceived() { bytes_received_ = absl::nullopt; } + void clearClusterInfo() { cluster_info_ = nullptr; } + void clearUpstreamHost() { upstream_host_ = nullptr; } private: - const Envoy::ProtobufWkt::Struct filter_metadata_; + const absl::optional filter_metadata_; + absl::optional latency_; + // The following stats are populated for ext_authz filters using Envoy gRPC only. + absl::optional bytes_sent_; + absl::optional bytes_received_; + Upstream::ClusterInfoConstSharedPtr cluster_info_; + Upstream::HostDescriptionConstSharedPtr upstream_host_; }; /** @@ -152,6 +180,8 @@ class FilterConfig { const absl::optional& filterMetadata() const { return filter_metadata_; } + bool emitFilterStateStats() const { return emit_filter_state_stats_; } + bool chargeClusterResponseStats() const { return charge_cluster_response_stats_; } const Filters::Common::ExtAuthz::MatcherSharedPtr& allowedHeadersMatcher() const { @@ -203,6 +233,7 @@ class FilterConfig { Http::Context& http_context_; LabelsMap destination_labels_; const absl::optional filter_metadata_; + const bool emit_filter_state_stats_; const absl::optional filter_enabled_; const absl::optional filter_enabled_metadata_; @@ -337,6 +368,7 @@ class Filter : public Logger::Loggable, void initiateCall(const Http::RequestHeaderMap& headers); void continueDecoding(); bool isBufferFull(uint64_t num_bytes_processing) const; + void updateLoggingInfo(); // This holds a set of flags defined in per-route configuration. struct PerRouteFlags { @@ -370,6 +402,7 @@ class Filter : public Logger::Loggable, Upstream::ClusterInfoConstSharedPtr cluster_; // The stats for the filter. ExtAuthzFilterStats stats_; + ExtAuthzLoggingInfo* logging_info_; // This is used to hold the final configs after we merge them with per-route configs. bool allow_partial_message_{}; diff --git a/source/extensions/filters/http/gcp_authn/BUILD b/source/extensions/filters/http/gcp_authn/BUILD index cc19cccf8e..ecb021ee00 100644 --- a/source/extensions/filters/http/gcp_authn/BUILD +++ b/source/extensions/filters/http/gcp_authn/BUILD @@ -29,7 +29,6 @@ envoy_cc_library( name = "gcp_authn_lib", srcs = ["gcp_authn_impl.cc"], hdrs = ["gcp_authn_impl.h"], - external_deps = ["abseil_optional"], deps = [ "token_cache", "//source/common/http:headers_lib", @@ -37,6 +36,7 @@ envoy_cc_library( "//source/common/http:utility_lib", "//source/extensions/filters/http/common:factory_base_lib", "//source/extensions/filters/http/common:pass_through_filter_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/extensions/filters/http/gcp_authn/v3:pkg_cc_proto", ], ) diff --git a/source/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter.cc b/source/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter.cc index 2ffc80e637..d4ea9bdbf9 100644 --- a/source/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter.cc +++ b/source/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter.cc @@ -45,6 +45,7 @@ using TranscoderPtr = std::unique_ptr; using google::grpc::transcoding::TranscoderInputStream; using TranscoderInputStreamPtr = std::unique_ptr; using envoy::extensions::filters::http::grpc_json_transcoder::v3::UnknownQueryParams; +using google::grpc::transcoding::VariableBinding; namespace Envoy { namespace Extensions { diff --git a/source/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter.h b/source/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter.h index dd3550967e..28766f34ac 100644 --- a/source/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter.h +++ b/source/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter.h @@ -25,23 +25,6 @@ namespace Extensions { namespace HttpFilters { namespace GrpcJsonTranscoder { -/** - * VariableBinding specifies a value for a single field in the request message. - * When transcoding HTTP/REST/JSON to gRPC/proto the request message is - * constructed using the HTTP body and the variable bindings (specified through - * request url). - * See https://github.com/googleapis/googleapis/blob/master/google/api/http.proto - * for details of variable binding. - */ -struct VariableBinding { - // The location of the field in the protobuf message, where the value - // needs to be inserted, e.g. "shelf.theme" would mean the "theme" field - // of the nested "shelf" message of the request protobuf message. - std::vector field_path; - // The value to be inserted. - std::string value; -}; - struct MethodInfo { const Protobuf::MethodDescriptor* descriptor_ = nullptr; std::vector request_body_field_path; diff --git a/source/extensions/filters/http/oauth2/filter.cc b/source/extensions/filters/http/oauth2/filter.cc index 453187a428..e35d664b0e 100644 --- a/source/extensions/filters/http/oauth2/filter.cc +++ b/source/extensions/filters/http/oauth2/filter.cc @@ -45,9 +45,13 @@ constexpr const char* CookieDomainFormatString = ";domain={}"; constexpr absl::string_view UnauthorizedBodyMessage = "OAuth flow failed."; -const std::string& queryParamsError() { CONSTRUCT_ON_FIRST_USE(std::string, "error"); } -const std::string& queryParamsCode() { CONSTRUCT_ON_FIRST_USE(std::string, "code"); } -const std::string& queryParamsState() { CONSTRUCT_ON_FIRST_USE(std::string, "state"); } +constexpr absl::string_view queryParamsError = "error"; +constexpr absl::string_view queryParamsCode = "code"; +constexpr absl::string_view queryParamsState = "state"; +constexpr absl::string_view queryParamsRedirectUri = "redirect_uri"; + +constexpr absl::string_view stateParamsUrl = "url"; +constexpr absl::string_view stateParamsNonce = "nonce"; constexpr absl::string_view REDIRECT_RACE = "oauth.race_redirect"; constexpr absl::string_view REDIRECT_LOGGED_IN = "oauth.logged_in"; @@ -169,6 +173,21 @@ std::string encodeHmac(const std::vector& secret, absl::string_view dom return encodeHmacBase64(secret, domain, expires, token, id_token, refresh_token); } +// Generates a nonce based on the current time +std::string generateFixedLengthNonce(TimeSource& time_source) { + constexpr size_t length = 16; + + std::string nonce = fmt::format("{}", time_source.systemTime().time_since_epoch().count()); + + if (nonce.length() < length) { + nonce.append(length - nonce.length(), '0'); + } else if (nonce.length() > length) { + nonce = nonce.substr(0, length); + } + + return nonce; +} + } // namespace FilterConfig::FilterConfig( @@ -320,37 +339,37 @@ Http::FilterHeadersStatus OAuth2Filter::decodeHeaders(Http::RequestHeaderMap& he // auth server. A cached login on the authorization server side will set cookies // correctly but cause a race condition on future requests that have their location set // to the callback path. - if (config_->redirectPathMatcher().match(path_str)) { - Http::Utility::QueryParamsMulti query_parameters = - Http::Utility::QueryParamsMulti::parseQueryString(path_str); - - auto stateVal = query_parameters.getFirstValue(queryParamsState()); - if (!stateVal.has_value()) { - ENVOY_LOG(error, "state query param does not exist: \n{}", query_parameters.data()); + // Even though we're already logged in and don't technically need to validate the presence + // of the auth code, we still perform the validation to ensure consistency and reuse the + // validateOAuthCallback method. This is acceptable because the auth code is always present + // in the query string of the callback path according to the OAuth2 spec. + // More information can be found here: + // https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2 + const CallbackValidationResult result = validateOAuthCallback(headers, path_str); + if (!result.is_valid_) { sendUnauthorizedResponse(); return Http::FilterHeadersStatus::StopIteration; } - std::string state; - state = Http::Utility::PercentEncoding::urlDecodeQueryParameter(stateVal.value()); - Http::Utility::Url state_url; - if (!state_url.initialize(state, false)) { - ENVOY_LOG(debug, "state url {} can not be initialized", state_url.toString()); - sendUnauthorizedResponse(); - return Http::FilterHeadersStatus::StopIteration; - } - // Avoid infinite redirect storm - if (config_->redirectPathMatcher().match(state_url.pathAndQueryParams())) { - ENVOY_LOG(debug, "state url query params {} does not match redirect config", - state_url.pathAndQueryParams()); + // Return 401 unauthorized if the original request URL in the state matches the redirect + // config to avoid infinite redirect loops. + Http::Utility::Url original_request_url; + original_request_url.initialize(result.original_request_url_, false); + if (config_->redirectPathMatcher().match(original_request_url.pathAndQueryParams())) { + ENVOY_LOG(debug, "state url query params {} matches the redirect path matcher", + original_request_url.pathAndQueryParams()); + // TODO(zhaohuabing): Should return 401 unauthorized or 400 bad request? sendUnauthorizedResponse(); return Http::FilterHeadersStatus::StopIteration; } + + // Since the user is already logged in, we don't need to exchange the auth code for tokens. + // Instead, we redirect the user back to the original request URL. Http::ResponseHeaderMapPtr response_headers{ Http::createHeaderMap( {{Http::Headers::get().Status, std::to_string(enumToInt(Http::Code::Found))}, - {Http::Headers::get().Location, state}})}; + {Http::Headers::get().Location, result.original_request_url_}})}; decoder_callbacks_->encodeHeaders(std::move(response_headers), true, REDIRECT_RACE); return Http::FilterHeadersStatus::StopIteration; } @@ -392,30 +411,15 @@ Http::FilterHeadersStatus OAuth2Filter::decodeHeaders(Http::RequestHeaderMap& he // At this point, we *are* on /_oauth. We believe this request comes from the authorization // server and we expect the query strings to contain the information required to get the access - // token - const auto query_parameters = Http::Utility::QueryParamsMulti::parseQueryString(path_str); - if (query_parameters.getFirstValue(queryParamsError()).has_value()) { - sendUnauthorizedResponse(); - return Http::FilterHeadersStatus::StopIteration; - } - - // if the data we need is not present on the URL, stop execution - auto codeVal = query_parameters.getFirstValue(queryParamsCode()); - auto stateVal = query_parameters.getFirstValue(queryParamsState()); - if (!codeVal.has_value() || !stateVal.has_value()) { - sendUnauthorizedResponse(); - return Http::FilterHeadersStatus::StopIteration; - } - - auth_code_ = codeVal.value(); - state_ = Http::Utility::PercentEncoding::urlDecodeQueryParameter(stateVal.value()); - - Http::Utility::Url state_url; - if (!state_url.initialize(state_, false)) { + // token. + const CallbackValidationResult result = validateOAuthCallback(headers, path_str); + if (!result.is_valid_) { sendUnauthorizedResponse(); return Http::FilterHeadersStatus::StopIteration; } + original_request_url_ = result.original_request_url_; + auth_code_ = result.auth_code_; Formatter::FormatterImpl formatter(config_->redirectUri()); const auto redirect_uri = formatter.formatWithContext({&headers}, decoder_callbacks_->streamInfo()); @@ -477,9 +481,41 @@ void OAuth2Filter::redirectToOAuthServer(Http::RequestHeaderMap& headers) const } const std::string base_path = absl::StrCat(scheme, "://", host_); - const std::string state_path = absl::StrCat(base_path, headers.Path()->value().getStringView()); - const std::string escaped_state = - Http::Utility::PercentEncoding::urlEncodeQueryParameter(state_path); + const std::string full_url = absl::StrCat(base_path, headers.Path()->value().getStringView()); + const std::string escaped_url = Http::Utility::PercentEncoding::urlEncodeQueryParameter(full_url); + + // Generate a nonce to prevent CSRF attacks + std::string nonce; + bool nonce_cookie_exists = false; + const auto nonce_cookie = Http::Utility::parseCookies(headers, [this](absl::string_view key) { + return key == config_->cookieNames().oauth_nonce_; + }); + if (nonce_cookie.find(config_->cookieNames().oauth_nonce_) != nonce_cookie.end()) { + nonce = nonce_cookie.at(config_->cookieNames().oauth_nonce_); + nonce_cookie_exists = true; + } else { + nonce = generateFixedLengthNonce(time_source_); + } + + // Set the nonce cookie if it does not exist. + if (!nonce_cookie_exists) { + // Expire the nonce cookie in 10 minutes. + // This should be enough time for the user to complete the OAuth flow. + std::string expire_in = std::to_string(10 * 60); + std::string cookie_tail_http_only = fmt::format(CookieTailHttpOnlyFormatString, expire_in); + if (!config_->cookieDomain().empty()) { + cookie_tail_http_only = absl::StrCat( + fmt::format(CookieDomainFormatString, config_->cookieDomain()), cookie_tail_http_only); + } + response_headers->addReferenceKey( + Http::Headers::get().SetCookie, + absl::StrCat(config_->cookieNames().oauth_nonce_, "=", nonce, cookie_tail_http_only)); + } + + // Encode the original request URL and the nonce to the state parameter + const std::string state = + absl::StrCat(stateParamsUrl, "=", escaped_url, "&", stateParamsNonce, "=", nonce); + const std::string escaped_state = Http::Utility::PercentEncoding::urlEncodeQueryParameter(state); Formatter::FormatterImpl formatter(config_->redirectUri()); const auto redirect_uri = @@ -488,8 +524,8 @@ void OAuth2Filter::redirectToOAuthServer(Http::RequestHeaderMap& headers) const Http::Utility::PercentEncoding::urlEncodeQueryParameter(redirect_uri); auto query_params = config_->authorizationQueryParams(); - query_params.overwrite("redirect_uri", escaped_redirect_uri); - query_params.overwrite("state", escaped_state); + query_params.overwrite(queryParamsRedirectUri, escaped_redirect_uri); + query_params.overwrite(queryParamsState, escaped_state); // Copy the authorization endpoint URL to replace its query params. auto authorization_endpoint_url = config_->authorizationEndpointUrl(); const std::string path_and_query_params = query_params.replaceQueryString( @@ -498,6 +534,7 @@ void OAuth2Filter::redirectToOAuthServer(Http::RequestHeaderMap& headers) const const std::string new_url = authorization_endpoint_url.toString(); response_headers->setLocation(new_url + config_->encodedResourceQueryParams()); + decoder_callbacks_->encodeHeaders(std::move(response_headers), true, REDIRECT_FOR_CREDENTIALS); config_->stats().oauth_unauthorized_rq_.inc(); @@ -658,7 +695,7 @@ void OAuth2Filter::finishGetAccessTokenFlow() { {{Http::Headers::get().Status, std::to_string(enumToInt(Http::Code::Found))}})}; addResponseCookies(*response_headers, getEncodedToken()); - response_headers->setLocation(state_); + response_headers->setLocation(original_request_url_); decoder_callbacks_->encodeHeaders(std::move(response_headers), true, REDIRECT_LOGGED_IN); config_->stats().oauth_success_.inc(); @@ -759,6 +796,74 @@ void OAuth2Filter::sendUnauthorizedResponse() { absl::nullopt, EMPTY_STRING); } +// Validates the OAuth callback request. +// * Does the query parameters contain an error response? +// * Does the query parameters contain the code and state? +// * Does the state contain the original request URL and nonce? +// * Does the nonce in the state match the nonce in the cookie? +CallbackValidationResult OAuth2Filter::validateOAuthCallback(const Http::RequestHeaderMap& headers, + const absl::string_view path_str) { + // Return 401 unauthorized if the query parameters contain an error response. + const auto query_parameters = Http::Utility::QueryParamsMulti::parseQueryString(path_str); + if (query_parameters.getFirstValue(queryParamsError).has_value()) { + ENVOY_LOG(debug, "OAuth server returned an error: \n{}", query_parameters.data()); + return {false, "", ""}; + } + + // Return 401 unauthorized if the query parameters do not contain the code and state. + auto codeVal = query_parameters.getFirstValue(queryParamsCode); + auto stateVal = query_parameters.getFirstValue(queryParamsState); + if (!codeVal.has_value() || !stateVal.has_value()) { + ENVOY_LOG(error, "code or state query param does not exist: \n{}", query_parameters.data()); + return {false, "", ""}; + } + + // Return 401 unauthorized if the state query parameter does not contain the original request URL + // and nonce. state is an HTTP URL encoded string that contains the url and nonce, for example: + // state=url%3Dhttp%253A%252F%252Ftraffic.example.com%252Fnot%252F_oauth%26nonce%3D1234567890000000". + std::string state = Http::Utility::PercentEncoding::urlDecodeQueryParameter(stateVal.value()); + const auto state_parameters = Http::Utility::QueryParamsMulti::parseParameters(state, 0, true); + auto urlVal = state_parameters.getFirstValue(stateParamsUrl); + auto nonceVal = state_parameters.getFirstValue(stateParamsNonce); + if (!urlVal.has_value() || !nonceVal.has_value()) { + ENVOY_LOG(error, "state query param does not contain url or nonce: \n{}", state); + return {false, "", ""}; + } + + // Return 401 unauthorized if the URL in the state is not valid. + std::string original_request_url = urlVal.value(); + Http::Utility::Url url; + if (!url.initialize(original_request_url, false)) { + ENVOY_LOG(error, "state url {} can not be initialized", original_request_url); + return {false, "", ""}; + } + + // Return 401 unauthorized if the nonce cookie does not match the nonce in the state. + // + // This is to prevent attackers from injecting their own access token into a victim's + // sessions via CSRF attack. The attack can result in victims saving their sensitive data + // in the attacker's account. + // More information can be found at https://datatracker.ietf.org/doc/html/rfc6819#section-5.3.5 + if (!validateNonce(headers, nonceVal.value())) { + ENVOY_LOG(error, "nonce cookie does not match nonce query param: \n{}", nonceVal.value()); + return {false, "", ""}; + } + + return {true, codeVal.value(), original_request_url}; +} + +bool OAuth2Filter::validateNonce(const Http::RequestHeaderMap& headers, const std::string& nonce) { + const auto nonce_cookie = Http::Utility::parseCookies(headers, [this](absl::string_view key) { + return key == config_->cookieNames().oauth_nonce_; + }); + + if (nonce_cookie.find(config_->cookieNames().oauth_nonce_) != nonce_cookie.end() && + nonce_cookie.at(config_->cookieNames().oauth_nonce_) == nonce) { + return true; + } + return false; +} + } // namespace Oauth2 } // namespace HttpFilters } // namespace Extensions diff --git a/source/extensions/filters/http/oauth2/filter.h b/source/extensions/filters/http/oauth2/filter.h index beb09d76f2..c4f6680ea7 100644 --- a/source/extensions/filters/http/oauth2/filter.h +++ b/source/extensions/filters/http/oauth2/filter.h @@ -84,24 +84,29 @@ struct CookieNames { cookie_names) : CookieNames(cookie_names.bearer_token(), cookie_names.oauth_hmac(), cookie_names.oauth_expires(), cookie_names.id_token(), - cookie_names.refresh_token()) {} + cookie_names.refresh_token(), cookie_names.oauth_nonce()) {} CookieNames(const std::string& bearer_token, const std::string& oauth_hmac, const std::string& oauth_expires, const std::string& id_token, - const std::string& refresh_token) - : bearer_token_(bearer_token.empty() ? "BearerToken" : bearer_token), - oauth_hmac_(oauth_hmac.empty() ? "OauthHMAC" : oauth_hmac), + const std::string& refresh_token, const std::string& oauth_nonce) + : bearer_token_(bearer_token.empty() ? BearerToken : bearer_token), + oauth_hmac_(oauth_hmac.empty() ? OauthHMAC : oauth_hmac), oauth_expires_(oauth_expires.empty() ? OauthExpires : oauth_expires), id_token_(id_token.empty() ? IdToken : id_token), - refresh_token_(refresh_token.empty() ? RefreshToken : refresh_token) {} + refresh_token_(refresh_token.empty() ? RefreshToken : refresh_token), + oauth_nonce_(oauth_nonce.empty() ? OauthNonce : oauth_nonce) {} const std::string bearer_token_; const std::string oauth_hmac_; const std::string oauth_expires_; const std::string id_token_; const std::string refresh_token_; + const std::string oauth_nonce_; static constexpr absl::string_view OauthExpires = "OauthExpires"; + static constexpr absl::string_view BearerToken = "BearerToken"; + static constexpr absl::string_view OauthHMAC = "OauthHMAC"; + static constexpr absl::string_view OauthNonce = "OauthNonce"; static constexpr absl::string_view IdToken = "IdToken"; static constexpr absl::string_view RefreshToken = "RefreshToken"; }; @@ -235,6 +240,12 @@ class OAuth2CookieValidator : public CookieValidator { const std::string cookie_domain_; }; +struct CallbackValidationResult { + bool is_valid_; + std::string auth_code_; + std::string original_request_url_; +}; + /** * The filter is the primary entry point for the OAuth workflow. Its responsibilities are to * receive incoming requests and decide at what state of the OAuth workflow they are in. Logic @@ -270,6 +281,7 @@ class OAuth2Filter : public Http::PassThroughFilter, void finishRefreshAccessTokenFlow(); void updateTokens(const std::string& access_token, const std::string& id_token, const std::string& refresh_token, std::chrono::seconds expires_in); + bool validateNonce(const Http::RequestHeaderMap& headers, const std::string& nonce); private: friend class OAuth2Test; @@ -286,7 +298,7 @@ class OAuth2Filter : public Http::PassThroughFilter, std::string expires_id_token_in_; std::string new_expires_; absl::string_view host_; - std::string state_; + std::string original_request_url_; Http::RequestHeaderMap* request_headers_{nullptr}; bool was_refresh_token_flow_{false}; @@ -309,6 +321,8 @@ class OAuth2Filter : public Http::PassThroughFilter, const std::chrono::seconds& expires_in) const; void addResponseCookies(Http::ResponseHeaderMap& headers, const std::string& encoded_token) const; const std::string& bearerPrefix() const; + CallbackValidationResult validateOAuthCallback(const Http::RequestHeaderMap& headers, + const absl::string_view path_str); }; } // namespace Oauth2 diff --git a/source/extensions/filters/network/dubbo_proxy/BUILD b/source/extensions/filters/network/dubbo_proxy/BUILD index 0f91338b37..909bb29b7f 100644 --- a/source/extensions/filters/network/dubbo_proxy/BUILD +++ b/source/extensions/filters/network/dubbo_proxy/BUILD @@ -119,11 +119,11 @@ envoy_cc_extension( envoy_cc_library( name = "metadata_lib", hdrs = ["metadata.h"], - external_deps = ["abseil_optional"], deps = [ ":message_lib", "//source/common/buffer:buffer_lib", "//source/common/http:header_map_lib", + "@com_google_absl//absl/types:optional", ], ) diff --git a/source/extensions/filters/network/generic_proxy/BUILD b/source/extensions/filters/network/generic_proxy/BUILD index 7559e538ed..c4759e9bf8 100644 --- a/source/extensions/filters/network/generic_proxy/BUILD +++ b/source/extensions/filters/network/generic_proxy/BUILD @@ -184,15 +184,13 @@ envoy_cc_library( hdrs = [ "tracing.h", ], - external_deps = [ - "abseil_strings", - "abseil_optional", - "abseil_status", - ], deps = [ "//envoy/common:pure_lib", "//envoy/tracing:trace_context_interface", "//source/extensions/filters/network/generic_proxy/interface:stream_interface", + "@com_google_absl//absl/status", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/types:optional", ], ) diff --git a/source/extensions/filters/network/redis_proxy/proxy_filter.cc b/source/extensions/filters/network/redis_proxy/proxy_filter.cc index 1bfa1c07a1..072ced769d 100644 --- a/source/extensions/filters/network/redis_proxy/proxy_filter.cc +++ b/source/extensions/filters/network/redis_proxy/proxy_filter.cc @@ -108,6 +108,19 @@ void ProxyFilter::initializeReadFilterCallbacks(Network::ReadFilterCallbacks& ca void ProxyFilter::onRespValue(Common::Redis::RespValuePtr&& value) { pending_requests_.emplace_back(*this); PendingRequest& request = pending_requests_.back(); + + // If external authentication is enabled and an AUTH command is ongoing, + // we keep the request in the queue and let it be processed when the + // authentication response is received. + if (external_auth_call_status_ == ExternalAuthCallStatus::Pending) { + request.pending_request_value_ = std::move(value); + return; + } + + processRespValue(std::move(value), request); +} + +void ProxyFilter::processRespValue(Common::Redis::RespValuePtr&& value, PendingRequest& request) { CommandSplitter::SplitRequestPtr split = splitter_.makeRequest(std::move(value), request, callbacks_->connection().dispatcher(), callbacks_->connection().streamInfo()); @@ -186,20 +199,19 @@ void ProxyFilter::onAuthenticateExternal(CommandSplitter::SplitCallbacks& reques external_auth_call_status_ = ExternalAuthCallStatus::Ready; request.onResponse(std::move(redis_response)); + + // Resume processing of pending requests. + while (!pending_requests_.empty() && pending_requests_.front().pending_request_value_) { + processRespValue(std::move(pending_requests_.front().pending_request_value_), + pending_requests_.front()); + } } void ProxyFilter::onAuth(PendingRequest& request, const std::string& password) { if (config_->external_auth_enabled_) { - if (external_auth_call_status_ == ExternalAuthCallStatus::Ready) { - auth_client_->authenticateExternal(*this, request, callbacks_->connection().streamInfo(), - EMPTY_STRING, password); - external_auth_call_status_ = ExternalAuthCallStatus::Pending; - } else { - Common::Redis::RespValuePtr response{new Common::Redis::RespValue()}; - response->type(Common::Redis::RespType::Error); - response->asString() = "ERR an existing authentication request is pending"; - request.onResponse(std::move(response)); - } + external_auth_call_status_ = ExternalAuthCallStatus::Pending; + auth_client_->authenticateExternal(*this, request, callbacks_->connection().streamInfo(), + EMPTY_STRING, password); return; } @@ -222,16 +234,9 @@ void ProxyFilter::onAuth(PendingRequest& request, const std::string& password) { void ProxyFilter::onAuth(PendingRequest& request, const std::string& username, const std::string& password) { if (config_->external_auth_enabled_) { - if (external_auth_call_status_ == ExternalAuthCallStatus::Ready) { - auth_client_->authenticateExternal(*this, request, callbacks_->connection().streamInfo(), - username, password); - external_auth_call_status_ = ExternalAuthCallStatus::Pending; - } else { - Common::Redis::RespValuePtr response{new Common::Redis::RespValue()}; - response->type(Common::Redis::RespType::Error); - response->asString() = "ERR an existing authentication request is pending"; - request.onResponse(std::move(response)); - } + auth_client_->authenticateExternal(*this, request, callbacks_->connection().streamInfo(), + username, password); + external_auth_call_status_ = ExternalAuthCallStatus::Pending; return; } diff --git a/source/extensions/filters/network/redis_proxy/proxy_filter.h b/source/extensions/filters/network/redis_proxy/proxy_filter.h index 2d325ecbea..be6fe36edb 100644 --- a/source/extensions/filters/network/redis_proxy/proxy_filter.h +++ b/source/extensions/filters/network/redis_proxy/proxy_filter.h @@ -139,6 +139,8 @@ class ProxyFilter : public Network::ReadFilter, Common::Redis::Client::Transaction& transaction() override { return parent_.transaction(); } ProxyFilter& parent_; + // This value is set when the request is on hold, waiting for an external auth response. + Common::Redis::RespValuePtr pending_request_value_; Common::Redis::RespValuePtr pending_response_; CommandSplitter::SplitRequestPtr request_handle_; }; @@ -148,6 +150,7 @@ class ProxyFilter : public Network::ReadFilter, void onAuth(PendingRequest& request, const std::string& username, const std::string& password); void onResponse(PendingRequest& request, Common::Redis::RespValuePtr&& value); bool checkPassword(const std::string& password); + void processRespValue(Common::Redis::RespValuePtr&& value, PendingRequest& request); Common::Redis::DecoderPtr decoder_; Common::Redis::EncoderPtr encoder_; diff --git a/source/extensions/filters/network/thrift_proxy/BUILD b/source/extensions/filters/network/thrift_proxy/BUILD index 2d2b0448d6..85ca7b672b 100644 --- a/source/extensions/filters/network/thrift_proxy/BUILD +++ b/source/extensions/filters/network/thrift_proxy/BUILD @@ -68,7 +68,6 @@ envoy_cc_library( name = "conn_manager_lib", srcs = ["conn_manager.cc"], hdrs = ["conn_manager.h"], - external_deps = ["abseil_any"], deps = [ ":app_exception_lib", ":decoder_lib", @@ -93,6 +92,7 @@ envoy_cc_library( "//source/common/stats:timespan_lib", "//source/common/stream_info:stream_info_lib", "//source/extensions/filters/network/thrift_proxy/router:router_interface", + "@com_google_absl//absl/types:any", ], ) @@ -139,21 +139,20 @@ envoy_cc_library( envoy_cc_library( name = "metadata_lib", hdrs = ["metadata.h"], - external_deps = ["abseil_optional"], deps = [ ":thrift_lib", ":tracing_interface", "//envoy/buffer:buffer_interface", "//source/common/common:macros", "//source/common/http:header_map_lib", + "@com_google_absl//absl/types:optional", ], ) envoy_cc_library( name = "tracing_interface", hdrs = ["tracing.h"], - external_deps = ["abseil_optional"], - deps = [], + deps = ["@com_google_absl//absl/types:optional"], ) envoy_cc_library( @@ -173,7 +172,6 @@ envoy_cc_library( hdrs = [ "protocol.h", ], - external_deps = ["abseil_optional"], deps = [ ":conn_state_lib", ":decoder_events_lib", @@ -187,6 +185,7 @@ envoy_cc_library( "//source/common/common:assert_lib", "//source/common/config:utility_lib", "//source/common/singleton:const_singleton", + "@com_google_absl//absl/types:optional", ], ) @@ -234,12 +233,12 @@ envoy_cc_library( hdrs = [ "compact_protocol_impl.h", ], - external_deps = ["abseil_optional"], deps = [ ":buffer_helper_lib", ":protocol_interface", "//source/common/common:macros", "//source/common/runtime:runtime_features_lib", + "@com_google_absl//absl/types:optional", ], alwayslink = 1, ) @@ -274,7 +273,6 @@ envoy_cc_library( envoy_cc_library( name = "transport_interface", hdrs = ["transport.h"], - external_deps = ["abseil_optional"], deps = [ ":buffer_helper_lib", ":metadata_lib", @@ -285,6 +283,7 @@ envoy_cc_library( "//source/common/common:assert_lib", "//source/common/config:utility_lib", "//source/common/singleton:const_singleton", + "@com_google_absl//absl/types:optional", ], ) diff --git a/source/extensions/filters/network/thrift_proxy/router/BUILD b/source/extensions/filters/network/thrift_proxy/router/BUILD index 6910d7abaf..9bf5cd3547 100644 --- a/source/extensions/filters/network/thrift_proxy/router/BUILD +++ b/source/extensions/filters/network/thrift_proxy/router/BUILD @@ -25,7 +25,6 @@ envoy_cc_extension( envoy_cc_library( name = "router_interface", hdrs = ["router.h"], - external_deps = ["abseil_optional"], deps = [ "//envoy/rds:rds_interface", "//envoy/router:router_interface", @@ -37,6 +36,7 @@ envoy_cc_library( "//source/extensions/filters/network/thrift_proxy:metadata_lib", "//source/extensions/filters/network/thrift_proxy:protocol_converter_lib", "//source/extensions/filters/network/thrift_proxy:protocol_options_config_lib", + "@com_google_absl//absl/types:optional", ], ) diff --git a/source/extensions/http/header_validators/envoy_default/BUILD b/source/extensions/http/header_validators/envoy_default/BUILD index 73dc0481ea..6aabbe9ca1 100644 --- a/source/extensions/http/header_validators/envoy_default/BUILD +++ b/source/extensions/http/header_validators/envoy_default/BUILD @@ -26,9 +26,9 @@ envoy_cc_library( ":path_normalizer", "//envoy/http:header_validator_errors", "//envoy/http:header_validator_interface", - "//external:abseil_node_hash_map", - "//external:abseil_node_hash_set", "//source/common/http:headers_lib", + "@com_google_absl//absl/container:node_hash_map", + "@com_google_absl//absl/container:node_hash_set", "@envoy_api//envoy/extensions/http/header_validators/envoy_default/v3:pkg_cc_proto", ], ) @@ -98,10 +98,10 @@ envoy_cc_library( ":header_validator_common", "//envoy/http:header_validator_errors", "//envoy/http:header_validator_interface", - "//external:abseil_node_hash_set", "//source/common/http:header_utility_lib", "//source/common/http:headers_lib", "//source/common/http:utility_lib", + "@com_google_absl//absl/container:node_hash_set", "@com_google_absl//absl/functional:bind_front", ], ) @@ -122,12 +122,12 @@ envoy_cc_library( ":header_validator_common", "//envoy/http:header_validator_errors", "//envoy/http:header_validator_interface", - "//external:abseil_node_hash_map", - "//external:abseil_node_hash_set", "//source/common/http:header_map_lib", "//source/common/http:header_utility_lib", "//source/common/http:headers_lib", "//source/common/http:utility_lib", + "@com_google_absl//absl/container:node_hash_map", + "@com_google_absl//absl/container:node_hash_set", "@com_google_absl//absl/functional:bind_front", ], ) diff --git a/source/extensions/load_balancing_policies/common/BUILD b/source/extensions/load_balancing_policies/common/BUILD index cd4ea6a5cc..8d6dd75634 100644 --- a/source/extensions/load_balancing_policies/common/BUILD +++ b/source/extensions/load_balancing_policies/common/BUILD @@ -21,12 +21,12 @@ envoy_cc_library( name = "thread_aware_lb_lib", srcs = ["thread_aware_lb_impl.cc"], hdrs = ["thread_aware_lb_impl.h"], - external_deps = ["abseil_synchronization"], deps = [ ":load_balancer_lib", "//source/common/common:minimal_logger_lib", "//source/common/config:metadata_lib", "//source/common/config:well_known_names", + "@com_google_absl//absl/synchronization", "@envoy_api//envoy/config/cluster/v3:pkg_cc_proto", ], ) diff --git a/source/extensions/load_balancing_policies/ring_hash/BUILD b/source/extensions/load_balancing_policies/ring_hash/BUILD index 435b97c0ea..be9df9c2d2 100644 --- a/source/extensions/load_balancing_policies/ring_hash/BUILD +++ b/source/extensions/load_balancing_policies/ring_hash/BUILD @@ -13,13 +13,11 @@ envoy_cc_library( name = "ring_hash_lb_lib", srcs = ["ring_hash_lb.cc"], hdrs = ["ring_hash_lb.h"], - external_deps = [ - "abseil_inlined_vector", - ], deps = [ "//envoy/upstream:load_balancer_interface", "//source/common/common:minimal_logger_lib", "//source/extensions/load_balancing_policies/common:thread_aware_lb_lib", + "@com_google_absl//absl/container:inlined_vector", "@envoy_api//envoy/config/cluster/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/load_balancing_policies/ring_hash/v3:pkg_cc_proto", ], diff --git a/source/extensions/tracers/zipkin/BUILD b/source/extensions/tracers/zipkin/BUILD index 6601088503..171080ecb7 100644 --- a/source/extensions/tracers/zipkin/BUILD +++ b/source/extensions/tracers/zipkin/BUILD @@ -34,9 +34,6 @@ envoy_cc_library( "zipkin_json_field_names.h", "zipkin_tracer_impl.h", ], - external_deps = [ - "abseil_optional", - ], deps = [ "//envoy/common:time_interface", "//envoy/local_info:local_info_interface", @@ -59,6 +56,7 @@ envoy_cc_library( "//source/common/tracing:http_tracer_lib", "//source/common/upstream:cluster_update_tracker_lib", "@com_github_openzipkin_zipkinapi//:zipkin_cc_proto", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/trace/v3:pkg_cc_proto", ], ) diff --git a/source/extensions/transport_sockets/alts/BUILD b/source/extensions/transport_sockets/alts/BUILD index fe03259a73..7d66d8dd9b 100644 --- a/source/extensions/transport_sockets/alts/BUILD +++ b/source/extensions/transport_sockets/alts/BUILD @@ -35,9 +35,6 @@ envoy_cc_extension( hdrs = [ "config.h", ], - external_deps = [ - "abseil_node_hash_set", - ], deps = [ ":alts_channel_pool", ":tsi_handshaker", @@ -45,6 +42,7 @@ envoy_cc_extension( "//envoy/registry", "//envoy/server:transport_socket_config_interface", "//source/common/grpc:google_grpc_context_lib", + "@com_google_absl//absl/container:node_hash_set", "@envoy_api//envoy/extensions/transport_sockets/alts/v3:pkg_cc_proto", ], ) @@ -135,13 +133,13 @@ envoy_cc_library( srcs = ["alts_proxy.cc"], hdrs = ["alts_proxy.h"], external_deps = [ - "abseil_memory", - "abseil_status", - "abseil_statusor", "grpc", ], deps = [ ":handshaker_cc_grpc", + "@com_google_absl//absl/memory", + "@com_google_absl//absl/status", + "@com_google_absl//absl/status:statusor", ], ) @@ -150,13 +148,13 @@ envoy_cc_library( srcs = ["alts_tsi_handshaker.cc"], hdrs = ["alts_tsi_handshaker.h"], external_deps = [ - "abseil_memory", - "abseil_status", "grpc", ], deps = [ ":alts_proxy", ":handshaker_cc_grpc", ":tsi_frame_protector", + "@com_google_absl//absl/memory", + "@com_google_absl//absl/status", ], ) diff --git a/source/extensions/transport_sockets/http_11_proxy/BUILD b/source/extensions/transport_sockets/http_11_proxy/BUILD index 78df614fb2..c33fe2db68 100644 --- a/source/extensions/transport_sockets/http_11_proxy/BUILD +++ b/source/extensions/transport_sockets/http_11_proxy/BUILD @@ -37,6 +37,7 @@ envoy_cc_library( "//source/common/common:scalar_to_byte_vector_lib", "//source/common/common:utility_lib", "//source/common/config:well_known_names", + "//source/common/http:header_utility_lib", "//source/common/http/http1:balsa_parser_lib", "//source/common/http/http1:legacy_parser_lib", "//source/common/network:address_lib", diff --git a/source/extensions/transport_sockets/http_11_proxy/connect.cc b/source/extensions/transport_sockets/http_11_proxy/connect.cc index 5e1c10f7d5..69bd12ba02 100644 --- a/source/extensions/transport_sockets/http_11_proxy/connect.cc +++ b/source/extensions/transport_sockets/http_11_proxy/connect.cc @@ -8,6 +8,7 @@ #include "source/common/common/scalar_to_byte_vector.h" #include "source/common/common/utility.h" #include "source/common/config/well_known_names.h" +#include "source/common/http/header_utility.h" #include "source/common/network/address_impl.h" #include "source/common/runtime/runtime_features.h" @@ -37,11 +38,17 @@ UpstreamHttp11ConnectSocket::UpstreamHttp11ConnectSocket( // options, we want to maintain the original behavior of this transport socket. if (options_ && options_->http11ProxyInfo()) { if (transport_socket_->ssl()) { - header_buffer_.add( - absl::StrCat("CONNECT ", options_->http11ProxyInfo()->hostname, ":443 HTTP/1.1\r\n\r\n")); + if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.proxy_ssl_port")) { + header_buffer_.add(absl::StrCat( + "CONNECT ", options_->http11ProxyInfo()->hostname, + Http::HeaderUtility::hostHasPort(options_->http11ProxyInfo()->hostname) ? "" : ":443", + " HTTP/1.1\r\n\r\n")); + } else { + header_buffer_.add(absl::StrCat("CONNECT ", options_->http11ProxyInfo()->hostname, + ":443 HTTP/1.1\r\n\r\n")); + } need_to_strip_connect_response_ = true; } - return; } diff --git a/source/extensions/transport_sockets/starttls/BUILD b/source/extensions/transport_sockets/starttls/BUILD index 6740d1b68f..1117a147ab 100644 --- a/source/extensions/transport_sockets/starttls/BUILD +++ b/source/extensions/transport_sockets/starttls/BUILD @@ -30,8 +30,6 @@ envoy_cc_library( srcs = ["starttls_socket.cc"], hdrs = ["starttls_socket.h"], external_deps = [ - "abseil_optional", - "abseil_synchronization", "ssl", ], deps = [ @@ -44,6 +42,8 @@ envoy_cc_library( "//source/common/common:minimal_logger_lib", "//source/common/common:thread_annotations", "//source/common/network:transport_socket_options_lib", + "@com_google_absl//absl/synchronization", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/extensions/transport_sockets/starttls/v3:pkg_cc_proto", ], ) diff --git a/source/extensions/transport_sockets/tls/cert_validator/spiffe/BUILD b/source/extensions/transport_sockets/tls/cert_validator/spiffe/BUILD index 72f5fedd2d..150928e553 100644 --- a/source/extensions/transport_sockets/tls/cert_validator/spiffe/BUILD +++ b/source/extensions/transport_sockets/tls/cert_validator/spiffe/BUILD @@ -18,8 +18,6 @@ envoy_cc_extension( ], external_deps = [ "ssl", - "abseil_base", - "abseil_hash", ], deps = [ "//envoy/ssl:context_config_interface", @@ -36,6 +34,8 @@ envoy_cc_extension( "//source/common/tls:stats_lib", "//source/common/tls:utility_lib", "//source/common/tls/cert_validator:cert_validator_lib", + "@com_google_absl//absl/base", + "@com_google_absl//absl/hash", "@envoy_api//envoy/extensions/transport_sockets/tls/v3:pkg_cc_proto", ], ) diff --git a/source/extensions/watchdog/profile_action/BUILD b/source/extensions/watchdog/profile_action/BUILD index 5f01f35e2f..e8fccf3218 100644 --- a/source/extensions/watchdog/profile_action/BUILD +++ b/source/extensions/watchdog/profile_action/BUILD @@ -13,9 +13,6 @@ envoy_cc_library( name = "profile_action_lib", srcs = ["profile_action.cc"], hdrs = ["profile_action.h"], - external_deps = [ - "abseil_optional", - ], deps = [ "//envoy/api:api_interface", "//envoy/common:time_interface", @@ -25,6 +22,7 @@ envoy_cc_library( "//source/common/profiler:profiler_lib", "//source/common/protobuf:utility_lib", "//source/common/stats:symbol_table_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/extensions/watchdog/profile_action/v3:pkg_cc_proto", ], ) diff --git a/source/server/BUILD b/source/server/BUILD index 35b6e173c8..7420331d1f 100644 --- a/source/server/BUILD +++ b/source/server/BUILD @@ -14,14 +14,12 @@ envoy_cc_library( name = "backtrace_lib", srcs = ["backtrace.cc"], hdrs = ["backtrace.h"], - external_deps = [ - "abseil_stacktrace", - "abseil_symbolize", - ], tags = ["backtrace"], deps = [ "//source/common/common:minimal_logger_lib", "//source/common/version:version_lib", + "@com_google_absl//absl/debugging:stacktrace", + "@com_google_absl//absl/debugging:symbolize", ], ) @@ -128,7 +126,6 @@ envoy_cc_library( name = "guarddog_lib", srcs = ["guarddog_impl.cc"], hdrs = ["guarddog_impl.h"], - external_deps = ["abseil_optional"], deps = [ ":watchdog_lib", "//envoy/api:api_interface", @@ -149,6 +146,7 @@ envoy_cc_library( "//source/common/protobuf:utility_lib", "//source/common/stats:symbol_table_lib", "//source/common/watchdog:abort_action_config", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/watchdog/v3:pkg_cc_proto", ], @@ -408,10 +406,6 @@ envoy_cc_library( name = "server_base_lib", srcs = ["server.cc"], hdrs = ["server.h"], - external_deps = [ - "abseil_node_hash_map", - "abseil_optional", - ], deps = [ ":api_listener_lib", ":configuration_lib", @@ -466,6 +460,8 @@ envoy_cc_library( "//source/common/upstream:health_discovery_service_lib", "//source/common/version:version_lib", "//source/server/admin:admin_lib", + "@com_google_absl//absl/container:node_hash_map", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/admin/v3:pkg_cc_proto", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", ], diff --git a/source/server/config_validation/BUILD b/source/server/config_validation/BUILD index 49732a80f8..2bc89abf8e 100644 --- a/source/server/config_validation/BUILD +++ b/source/server/config_validation/BUILD @@ -63,7 +63,6 @@ envoy_cc_library( name = "server_lib", srcs = ["server.cc"], hdrs = ["server.h"], - external_deps = ["abseil_optional"], deps = [ ":admin_lib", ":api_lib", @@ -96,6 +95,7 @@ envoy_cc_library( "//source/server:server_lib", "//source/server:utils_lib", "//source/server/admin:admin_factory_context", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", diff --git a/test/common/common/BUILD b/test/common/common/BUILD index 23daa9263d..cac07a646a 100644 --- a/test/common/common/BUILD +++ b/test/common/common/BUILD @@ -275,15 +275,13 @@ envoy_cc_test( envoy_cc_test( name = "utility_test", srcs = ["utility_test.cc"], - external_deps = [ - "abseil_strings", - ], deps = [ "//source/common/common:utility_lib", "//test/common/memory:memory_test_utility_lib", "//test/test_common:simulated_time_system_lib", "//test/test_common:test_time_lib", "//test/test_common:utility_lib", + "@com_google_absl//absl/strings", ], ) @@ -385,12 +383,12 @@ envoy_cc_benchmark_binary( name = "utility_speed_test", srcs = ["utility_speed_test.cc"], external_deps = [ - "abseil_strings", "benchmark", ], deps = [ "//source/common/common:assert_lib", "//source/common/common:utility_lib", + "@com_google_absl//absl/strings", ], ) @@ -403,11 +401,11 @@ envoy_cc_benchmark_binary( name = "trie_lookup_table_speed_test", srcs = ["trie_lookup_table_speed_test.cc"], external_deps = [ - "abseil_strings", "benchmark", ], deps = [ "//source/common/common:trie_lookup_table_lib", + "@com_google_absl//absl/strings", ], ) @@ -428,10 +426,10 @@ envoy_cc_test( envoy_cc_test( name = "thread_id_test", srcs = ["thread_id_test.cc"], - external_deps = ["abseil_hash_testing"], deps = [ "//source/common/common:thread_lib", "//test/test_common:thread_factory_for_test_lib", + "@com_google_absl//absl/hash:hash_testing", ], ) @@ -457,11 +455,9 @@ envoy_cc_test( name = "version_test", srcs = ["version_test.cc"], copts = envoy_select_boringssl(["-DENVOY_SSL_FIPS"]), - external_deps = [ - "abseil_strings", - ], deps = [ "//source/common/version:version_lib", + "@com_google_absl//absl/strings", ], ) diff --git a/test/common/common/thread_test.cc b/test/common/common/thread_test.cc index ff3a8bd5a3..92c017afca 100644 --- a/test/common/common/thread_test.cc +++ b/test/common/common/thread_test.cc @@ -275,6 +275,32 @@ TEST(PosixThreadTest, Joinable) { EXPECT_FALSE(thread->joinable()); } +TEST(PosixThreadTest, ThreadPriority) { + auto thread_factory = PosixThreadFactory::create(); + Options options; + options.priority_ = 15; + double thread_priority; + auto thread = thread_factory->createThread( + [&]() { thread_priority = thread_factory->currentThreadPriority(); }, options, + /* crash_on_failure= */ false); + thread->join(); + + EXPECT_EQ(thread_priority, options.priority_); +} + +TEST(PosixThreadTest, InvalidThreadPriority) { + auto thread_factory = PosixThreadFactory::create(); + Options options; + options.priority_ = -200; + double thread_priority; + auto thread = thread_factory->createThread( + [&]() { thread_priority = thread_factory->currentThreadPriority(); }, options, + /* crash_on_failure= */ false); + thread->join(); + + EXPECT_NE(thread_priority, options.priority_); +} + class PosixThreadFactoryFailCreate : public PosixThreadFactory { protected: int createPthread(ThreadHandle*) override { return 1; } diff --git a/test/common/config/BUILD b/test/common/config/BUILD index b72678b008..409bfc62f0 100644 --- a/test/common/config/BUILD +++ b/test/common/config/BUILD @@ -123,7 +123,6 @@ envoy_cc_test( envoy_cc_test( name = "utility_test", srcs = ["utility_test.cc"], - external_deps = ["abseil_optional"], deps = [ "//source/common/config:api_version_lib", "//source/common/config:utility_lib", @@ -141,6 +140,7 @@ envoy_cc_test( "//test/test_common:utility_lib", "@com_github_cncf_xds//udpa/type/v1:pkg_cc_proto", "@com_github_cncf_xds//xds/type/v3:pkg_cc_proto", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/api/v2:pkg_cc_proto", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/config/cluster/v3:pkg_cc_proto", diff --git a/test/common/http/http2/BUILD b/test/common/http/http2/BUILD index 100c619945..f6a8835d42 100644 --- a/test/common/http/http2/BUILD +++ b/test/common/http/http2/BUILD @@ -53,13 +53,13 @@ envoy_cc_test_library( name = "codec_impl_test_util", hdrs = ["codec_impl_test_util.h"], external_deps = [ - "abseil_optional", "quiche_http2_adapter", ], deps = [ "//source/common/http/http2:codec_lib", "//test/mocks:common_lib", "//test/mocks/server:overload_manager_mocks", + "@com_google_absl//absl/types:optional", ], ) diff --git a/test/common/network/BUILD b/test/common/network/BUILD index bfbc24def4..8c7e54a689 100644 --- a/test/common/network/BUILD +++ b/test/common/network/BUILD @@ -332,7 +332,6 @@ envoy_cc_test( envoy_cc_test( name = "socket_option_factory_test", srcs = ["socket_option_factory_test.cc"], - external_deps = ["abseil_str_format"], deps = [ "//source/common/network:address_lib", "//source/common/network:socket_option_factory_lib", @@ -341,6 +340,7 @@ envoy_cc_test( "//test/mocks/network:network_mocks", "//test/test_common:environment_lib", "//test/test_common:threadsafe_singleton_injector_lib", + "@com_google_absl//absl/strings:str_format", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], ) diff --git a/test/common/orca/BUILD b/test/common/orca/BUILD index ea012a118e..c63c06cd9e 100644 --- a/test/common/orca/BUILD +++ b/test/common/orca/BUILD @@ -12,8 +12,6 @@ envoy_cc_test( name = "orca_load_metrics_test", srcs = ["orca_load_metrics_test.cc"], external_deps = [ - "abseil_status", - "abseil_strings", "fmtlib", ], deps = [ @@ -22,6 +20,8 @@ envoy_cc_test( "//test/test_common:status_utility_lib", "//test/test_common:utility_lib", "@com_github_cncf_xds//xds/data/orca/v3:pkg_cc_proto", + "@com_google_absl//absl/status", + "@com_google_absl//absl/strings", ], ) @@ -29,8 +29,6 @@ envoy_cc_test( name = "orca_parser_test", srcs = ["orca_parser_test.cc"], external_deps = [ - "abseil_status", - "abseil_strings", "fmtlib", ], deps = [ @@ -39,5 +37,7 @@ envoy_cc_test( "//test/test_common:status_utility_lib", "//test/test_common:utility_lib", "@com_github_cncf_xds//xds/data/orca/v3:pkg_cc_proto", + "@com_google_absl//absl/status", + "@com_google_absl//absl/strings", ], ) diff --git a/test/common/router/BUILD b/test/common/router/BUILD index 90ba278292..414d769202 100644 --- a/test/common/router/BUILD +++ b/test/common/router/BUILD @@ -137,13 +137,11 @@ envoy_cc_test( envoy_cc_test( name = "scoped_config_impl_test", srcs = ["scoped_config_impl_test.cc"], - external_deps = [ - "abseil_strings", - ], deps = [ "//source/common/router:scoped_config_lib", "//test/mocks/router:router_mocks", "//test/test_common:utility_lib", + "@com_google_absl//absl/strings", "@envoy_api//envoy/config/route/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg_cc_proto", ], @@ -152,9 +150,6 @@ envoy_cc_test( envoy_cc_test( name = "scoped_rds_test", srcs = ["scoped_rds_test.cc"], - external_deps = [ - "abseil_strings", - ], deps = [ "//envoy/config:subscription_interface", "//envoy/init:manager_interface", @@ -175,6 +170,7 @@ envoy_cc_test( "//test/test_common:simulated_time_system_lib", "//test/test_common:test_runtime_lib", "//test/test_common:utility_lib", + "@com_google_absl//absl/strings", "@envoy_api//envoy/admin/v3:pkg_cc_proto", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/config/route/v3:pkg_cc_proto", @@ -387,7 +383,6 @@ envoy_cc_test_library( envoy_cc_test( name = "router_upstream_log_test", srcs = ["router_upstream_log_test.cc"], - external_deps = ["abseil_optional"], deps = [ "//source/common/buffer:buffer_lib", "//source/common/formatter:formatter_extension_lib", @@ -408,6 +403,7 @@ envoy_cc_test( "//test/mocks/server:factory_context_mocks", "//test/mocks/ssl:ssl_mocks", "//test/test_common:utility_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/accesslog/v3:pkg_cc_proto", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/filters/http/router/v3:pkg_cc_proto", diff --git a/test/common/stats/BUILD b/test/common/stats/BUILD index 6aed0a2e9e..95ccb0e0e0 100644 --- a/test/common/stats/BUILD +++ b/test/common/stats/BUILD @@ -116,9 +116,6 @@ envoy_cc_test_library( name = "stat_test_utility_lib", srcs = ["stat_test_utility.cc"], hdrs = ["stat_test_utility.h"], - external_deps = [ - "abseil_strings", - ], deps = [ "//envoy/stats:stats_interface", "//source/common/common:assert_lib", @@ -126,6 +123,7 @@ envoy_cc_test_library( "//source/common/stats:isolated_store_lib", "//test/common/memory:memory_test_utility_lib", "//test/test_common:global_lib", + "@com_google_absl//absl/strings", ], ) @@ -160,7 +158,6 @@ envoy_cc_test( envoy_cc_test( name = "symbol_table_impl_test", srcs = ["symbol_table_impl_test.cc"], - external_deps = ["abseil_hash_testing"], deps = [ ":stat_test_utility_lib", "//source/common/common:mutex_tracer_lib", @@ -170,6 +167,7 @@ envoy_cc_test( "//test/mocks/stats:stats_mocks", "//test/test_common:logging_lib", "//test/test_common:utility_lib", + "@com_google_absl//absl/hash:hash_testing", ], ) @@ -218,7 +216,6 @@ envoy_cc_benchmark_binary( "symbol_table_speed_test.cc", ], external_deps = [ - "abseil_strings", "benchmark", ], deps = [ @@ -232,6 +229,7 @@ envoy_cc_benchmark_binary( "//test/mocks/stats:stats_mocks", "//test/test_common:logging_lib", "//test/test_common:utility_lib", + "@com_google_absl//absl/strings", ], ) @@ -282,7 +280,6 @@ envoy_cc_benchmark_binary( "stats_matcher_impl_speed_test.cc", ], external_deps = [ - "abseil_strings", "benchmark", ], deps = [ @@ -291,6 +288,7 @@ envoy_cc_benchmark_binary( "//test/mocks/server:server_factory_context_mocks", "//test/test_common:logging_lib", "//test/test_common:utility_lib", + "@com_google_absl//absl/strings", "@envoy_api//envoy/config/metrics/v3:pkg_cc_proto", "@envoy_api//envoy/type/matcher/v3:pkg_cc_proto", ], @@ -369,7 +367,6 @@ envoy_cc_benchmark_binary( name = "thread_local_store_speed_test", srcs = ["thread_local_store_speed_test.cc"], external_deps = [ - "abseil_strings", "benchmark", ], deps = [ @@ -383,6 +380,7 @@ envoy_cc_benchmark_binary( "//test/test_common:simulated_time_system_lib", "//test/test_common:test_time_lib", "//test/test_common:utility_lib", + "@com_google_absl//absl/strings", "@envoy_api//envoy/config/metrics/v3:pkg_cc_proto", ], ) diff --git a/test/common/upstream/BUILD b/test/common/upstream/BUILD index 1891a2d1d4..97fdd20407 100644 --- a/test/common/upstream/BUILD +++ b/test/common/upstream/BUILD @@ -60,9 +60,6 @@ envoy_cc_test( envoy_cc_test( name = "deferred_cluster_initialization_test", srcs = ["deferred_cluster_initialization_test.cc"], - external_deps = [ - "abseil_base", - ], deps = [ ":test_cluster_manager", "//envoy/upstream:cluster_manager_interface", @@ -73,6 +70,7 @@ envoy_cc_test( "//test/mocks/config:config_mocks", "//test/test_common:simulated_time_system_lib", "//test/test_common:utility_lib", + "@com_google_absl//absl/base", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/config/cluster/v3:pkg_cc_proto", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", @@ -85,9 +83,6 @@ envoy_cc_test( name = "cluster_manager_impl_test", size = "large", srcs = ["cluster_manager_impl_test.cc"], - external_deps = [ - "abseil_optional", - ], deps = [ ":test_cluster_manager", "//source/common/router:context_lib", @@ -124,6 +119,7 @@ envoy_cc_test( "//test/mocks/upstream:od_cds_api_mocks", "//test/mocks/upstream:thread_aware_load_balancer_mocks", "//test/test_common:test_runtime_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/admin/v3:pkg_cc_proto", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/config/cluster/v3:pkg_cc_proto", @@ -353,7 +349,6 @@ envoy_cc_test( envoy_cc_test( name = "outlier_detection_impl_test", srcs = ["outlier_detection_impl_test.cc"], - external_deps = ["abseil_optional"], deps = [ ":utility_lib", "//envoy/common:time_interface", @@ -372,6 +367,7 @@ envoy_cc_test( "//test/mocks/upstream:host_set_mocks", "//test/test_common:simulated_time_system_lib", "//test/test_common:utility_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/cluster/v3:pkg_cc_proto", "@envoy_api//envoy/data/cluster/v3:pkg_cc_proto", ], @@ -654,8 +650,8 @@ envoy_cc_test_library( hdrs = [ "test_local_address_selector.h", ], - external_deps = ["abseil_optional"], deps = [ "//envoy/upstream:upstream_interface", + "@com_google_absl//absl/types:optional", ], ) diff --git a/test/common/watchdog/BUILD b/test/common/watchdog/BUILD index e5c085ccb6..aed829e57a 100644 --- a/test/common/watchdog/BUILD +++ b/test/common/watchdog/BUILD @@ -11,9 +11,6 @@ envoy_package() envoy_cc_test( name = "abort_action_test", srcs = ["abort_action_test.cc"], - external_deps = [ - "abseil_synchronization", - ], deps = [ "//envoy/common:time_interface", "//envoy/registry", @@ -22,6 +19,7 @@ envoy_cc_test( "//source/common/watchdog:abort_action_lib", "//test/common/stats:stat_test_utility_lib", "//test/test_common:utility_lib", + "@com_google_absl//absl/synchronization", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/watchdog/v3:pkg_cc_proto", ], diff --git a/test/extensions/access_loggers/wasm/test_data/BUILD b/test/extensions/access_loggers/wasm/test_data/BUILD index d9b33eead0..74e25a2c25 100644 --- a/test/extensions/access_loggers/wasm/test_data/BUILD +++ b/test/extensions/access_loggers/wasm/test_data/BUILD @@ -3,10 +3,9 @@ load( "envoy_cc_test_library", "envoy_package", ) - load( - "@envoy_build_config//:extensions_build_config.bzl", - "LEGACY_ALWAYSLINK", + "@envoy_build_config//:extensions_build_config.bzl", + "LEGACY_ALWAYSLINK", ) load("//bazel/wasm:wasm.bzl", "envoy_wasm_cc_binary") @@ -22,11 +21,11 @@ envoy_cc_test_library( ], copts = ["-DNULL_PLUGIN=1"], deps = [ - "//external:abseil_node_hash_map", "//source/common/common:assert_lib", "//source/common/common:c_smart_ptr_lib", "//source/extensions/common/wasm:wasm_hdr", "//source/extensions/common/wasm:wasm_lib", + "@com_google_absl//absl/container:node_hash_map", ], ) diff --git a/test/extensions/bootstrap/wasm/BUILD b/test/extensions/bootstrap/wasm/BUILD index c655f032da..fd54284031 100644 --- a/test/extensions/bootstrap/wasm/BUILD +++ b/test/extensions/bootstrap/wasm/BUILD @@ -31,7 +31,6 @@ envoy_extension_cc_test( "//test/extensions/bootstrap/wasm/test_data:logging_rust.wasm", ]), extension_names = ["envoy.bootstrap.wasm"], - external_deps = ["abseil_optional"], tags = ["skip_on_windows"], deps = [ "//source/common/event:dispatcher_lib", @@ -45,6 +44,7 @@ envoy_extension_cc_test( "//test/mocks/upstream:upstream_mocks", "//test/test_common:environment_lib", "//test/test_common:simulated_time_system_lib", + "@com_google_absl//absl/types:optional", ], ) @@ -98,7 +98,6 @@ envoy_extension_cc_test_binary( ]), extension_names = ["envoy.bootstrap.wasm"], external_deps = [ - "abseil_optional", "benchmark", ], tags = ["skip_on_windows"], @@ -114,5 +113,6 @@ envoy_extension_cc_test_binary( "//test/mocks/upstream:upstream_mocks", "//test/test_common:environment_lib", "//test/test_common:simulated_time_system_lib", + "@com_google_absl//absl/types:optional", ], ) diff --git a/test/extensions/bootstrap/wasm/test_data/BUILD b/test/extensions/bootstrap/wasm/test_data/BUILD index e5fca0841f..e0003964ed 100644 --- a/test/extensions/bootstrap/wasm/test_data/BUILD +++ b/test/extensions/bootstrap/wasm/test_data/BUILD @@ -27,10 +27,10 @@ envoy_cc_test_library( ], copts = ["-DNULL_PLUGIN=1"], deps = [ - "//external:abseil_node_hash_map", "//source/common/common:assert_lib", "//source/common/common:c_smart_ptr_lib", "//source/extensions/common/wasm:wasm_lib", + "@com_google_absl//absl/container:node_hash_map", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], ) @@ -43,11 +43,11 @@ envoy_cc_test_library( ], copts = ["-DNULL_PLUGIN=1"], deps = [ - "//external:abseil_node_hash_map", "//source/common/common:assert_lib", "//source/common/common:c_smart_ptr_lib", "//source/extensions/common/wasm:wasm_hdr", "//source/extensions/common/wasm:wasm_lib", + "@com_google_absl//absl/container:node_hash_map", ], ) @@ -59,11 +59,11 @@ envoy_cc_test_library( ], copts = ["-DNULL_PLUGIN=1"], deps = [ - "//external:abseil_node_hash_map", "//source/common/common:assert_lib", "//source/common/common:c_smart_ptr_lib", "//source/extensions/common/wasm:wasm_hdr", "//source/extensions/common/wasm:wasm_lib", + "@com_google_absl//absl/container:node_hash_map", ], ) diff --git a/test/extensions/common/wasm/BUILD b/test/extensions/common/wasm/BUILD index cbd4bb7ade..f46b84d59e 100644 --- a/test/extensions/common/wasm/BUILD +++ b/test/extensions/common/wasm/BUILD @@ -40,7 +40,6 @@ envoy_cc_test( "//test/extensions/common/wasm/test_data:test_cpp.wasm", "//test/extensions/common/wasm/test_data:test_restriction_cpp.wasm", ]), - external_deps = ["abseil_optional"], tags = ["skip_on_windows"], deps = [ "//source/common/common:hex_lib", @@ -59,6 +58,7 @@ envoy_cc_test( "//test/test_common:registry_lib", "//test/test_common:simulated_time_system_lib", "//test/test_common:wasm_lib", + "@com_google_absl//absl/types:optional", ], ) @@ -76,7 +76,6 @@ envoy_cc_test_binary( name = "wasm_speed_test", srcs = ["wasm_speed_test.cc"], external_deps = [ - "abseil_optional", "benchmark", ], tags = ["skip_on_windows"], @@ -87,6 +86,7 @@ envoy_cc_test_binary( "//test/mocks/server:server_mocks", "//test/mocks/upstream:upstream_mocks", "//test/test_common:environment_lib", + "@com_google_absl//absl/types:optional", ], ) diff --git a/test/extensions/common/wasm/test_data/BUILD b/test/extensions/common/wasm/test_data/BUILD index 4a3760381f..e83f8a6017 100644 --- a/test/extensions/common/wasm/test_data/BUILD +++ b/test/extensions/common/wasm/test_data/BUILD @@ -25,11 +25,11 @@ envoy_cc_test_library( ], copts = ["-DNULL_PLUGIN=1"], deps = [ - "//external:abseil_node_hash_map", "//source/common/common:assert_lib", "//source/common/common:c_smart_ptr_lib", "//source/extensions/common/wasm:wasm_hdr", "//source/extensions/common/wasm:wasm_lib", + "@com_google_absl//absl/container:node_hash_map", ], ) @@ -41,12 +41,12 @@ envoy_cc_test_library( ], copts = ["-DNULL_PLUGIN=1"], deps = [ - "//external:abseil_node_hash_map", "//source/common/common:assert_lib", "//source/common/common:c_smart_ptr_lib", "//source/extensions/common/wasm:wasm_hdr", "//source/extensions/common/wasm:wasm_lib", "//source/extensions/common/wasm/ext:envoy_null_plugin", + "@com_google_absl//absl/container:node_hash_map", ], ) @@ -58,12 +58,12 @@ envoy_cc_test_library( ], copts = ["-DNULL_PLUGIN=1"], deps = [ - "//external:abseil_node_hash_map", "//source/common/common:assert_lib", "//source/common/common:c_smart_ptr_lib", "//source/extensions/common/wasm:wasm_hdr", "//source/extensions/common/wasm:wasm_lib", "//source/extensions/common/wasm/ext:envoy_null_plugin", + "@com_google_absl//absl/container:node_hash_map", ], ) diff --git a/test/extensions/config_subscription/grpc/BUILD b/test/extensions/config_subscription/grpc/BUILD index b3f06ff1c7..0474338885 100644 --- a/test/extensions/config_subscription/grpc/BUILD +++ b/test/extensions/config_subscription/grpc/BUILD @@ -136,7 +136,6 @@ envoy_cc_test_library( envoy_cc_test( name = "sotw_subscription_state_test", srcs = ["sotw_subscription_state_test.cc"], - external_deps = ["abseil_flat_hash_set"], deps = [ "//source/common/config:resource_name_lib", "//source/common/stats:isolated_store_lib", @@ -149,6 +148,7 @@ envoy_cc_test( "//test/mocks/runtime:runtime_mocks", "//test/test_common:logging_lib", "//test/test_common:utility_lib", + "@com_google_absl//absl/container:flat_hash_set", "@envoy_api//envoy/config/endpoint/v3:pkg_cc_proto", ], ) diff --git a/test/extensions/filters/common/ext_authz/ext_authz_grpc_impl_test.cc b/test/extensions/filters/common/ext_authz/ext_authz_grpc_impl_test.cc index a7832ddeda..abe226b1dd 100644 --- a/test/extensions/filters/common/ext_authz/ext_authz_grpc_impl_test.cc +++ b/test/extensions/filters/common/ext_authz/ext_authz_grpc_impl_test.cc @@ -100,6 +100,21 @@ TEST_F(ExtAuthzGrpcClientTest, AuthorizationOk) { client_->onSuccess(std::move(check_response), span_); } +TEST_F(ExtAuthzGrpcClientTest, StreamInfo) { + initialize(); + + envoy::service::auth::v3::CheckRequest request; + EXPECT_CALL(*async_client_, sendRaw(_, _, _, _, _, _)).WillOnce(Return(&async_request_)); + client_->check(request_callbacks_, request, Tracing::NullSpan::instance(), stream_info_); + + NiceMock ext_authz_stream_info; + EXPECT_CALL(async_request_, streamInfo()).WillOnce(ReturnRef(ext_authz_stream_info)); + EXPECT_NE(client_->streamInfo(), nullptr); + + EXPECT_CALL(async_request_, cancel()); + client_->cancel(); +} + // Test the client when an ok response is received. TEST_F(ExtAuthzGrpcClientTest, AuthorizationOkWithAllAtributes) { initialize(); diff --git a/test/extensions/filters/common/ext_authz/ext_authz_http_impl_test.cc b/test/extensions/filters/common/ext_authz/ext_authz_http_impl_test.cc index ad5aa4d809..3420decb41 100644 --- a/test/extensions/filters/common/ext_authz/ext_authz_http_impl_test.cc +++ b/test/extensions/filters/common/ext_authz/ext_authz_http_impl_test.cc @@ -209,6 +209,16 @@ class ExtAuthzHttpClientTest : public testing::Test { NiceMock stream_info_; }; +TEST_F(ExtAuthzHttpClientTest, StreamInfo) { + envoy::service::auth::v3::CheckRequest request; + client_->check(request_callbacks_, request, parent_span_, stream_info_); + EXPECT_EQ(client_->streamInfo(), nullptr); + auto check_response = TestCommon::makeMessageResponse( + TestCommon::makeHeaderValueOption({{":status", "200", false}})); + EXPECT_CALL(request_callbacks_, onComplete_(_)); + client_->onSuccess(async_request_, std::move(check_response)); +} + // Test HTTP client config default values. TEST_F(ExtAuthzHttpClientTest, ClientConfig) { const Http::LowerCaseString foo{"foo"}; diff --git a/test/extensions/filters/common/ext_authz/mocks.h b/test/extensions/filters/common/ext_authz/mocks.h index 1a3462d532..37d3afaee4 100644 --- a/test/extensions/filters/common/ext_authz/mocks.h +++ b/test/extensions/filters/common/ext_authz/mocks.h @@ -25,6 +25,7 @@ class MockClient : public Client { MOCK_METHOD(void, check, (RequestCallbacks & callbacks, const envoy::service::auth::v3::CheckRequest& request, Tracing::Span& parent_span, const StreamInfo::StreamInfo& stream_info)); + MOCK_METHOD(StreamInfo::StreamInfo const*, streamInfo, (), (const)); }; class MockRequestCallbacks : public RequestCallbacks { diff --git a/test/extensions/filters/http/ext_authz/BUILD b/test/extensions/filters/http/ext_authz/BUILD index 07b68c449a..f3436633bf 100644 --- a/test/extensions/filters/http/ext_authz/BUILD +++ b/test/extensions/filters/http/ext_authz/BUILD @@ -8,6 +8,7 @@ load( load( "//test/extensions:extensions_build_system.bzl", "envoy_extension_cc_test", + "envoy_extension_cc_test_library", ) licenses(["notice"]) # Apache 2 @@ -73,6 +74,8 @@ envoy_extension_cc_test( ], extension_names = ["envoy.filters.http.ext_authz"], deps = [ + ":ext_authz_fuzz_proto_cc_proto", + ":logging_test_filter_lib", "//source/extensions/clusters/strict_dns:strict_dns_cluster_lib", "//source/extensions/filters/http/ext_authz:config", "//source/extensions/listener_managers/validation_listener_manager:validation_listener_manager_lib", @@ -149,3 +152,27 @@ envoy_cc_test_library( "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], ) + +envoy_proto_library( + name = "logging_test_filter_proto", + srcs = ["logging_test_filter.proto"], +) + +envoy_extension_cc_test_library( + name = "logging_test_filter_lib", + srcs = [ + "logging_test_filter.cc", + ], + extension_names = ["envoy.filters.http.ext_authz"], + deps = [ + ":logging_test_filter_proto_cc_proto", + "//envoy/http:filter_interface", + "//envoy/registry", + "//envoy/server:filter_config_interface", + "//source/common/router:string_accessor_lib", + "//source/extensions/filters/http/common:factory_base_lib", + "//source/extensions/filters/http/common:pass_through_filter_lib", + "//source/extensions/filters/http/ext_authz", + "//test/test_common:utility_lib", + ], +) diff --git a/test/extensions/filters/http/ext_authz/ext_authz_integration_test.cc b/test/extensions/filters/http/ext_authz/ext_authz_integration_test.cc index fe08ee214d..0586b80e7a 100644 --- a/test/extensions/filters/http/ext_authz/ext_authz_integration_test.cc +++ b/test/extensions/filters/http/ext_authz/ext_authz_integration_test.cc @@ -8,6 +8,7 @@ #include "source/server/config_validation/server.h" #include "test/common/grpc/grpc_client_integration.h" +#include "test/extensions/filters/http/ext_authz/logging_test_filter.pb.h" #include "test/integration/http_integration.h" #include "test/mocks/server/options.h" #include "test/test_common/test_runtime.h" @@ -25,6 +26,8 @@ namespace Envoy { using Headers = std::vector>; +constexpr char ExtAuthzFilterName[] = "envoy.filters.http.ext_authz"; + struct GrpcInitializeConfigOpts { bool disable_with_metadata = false; bool failure_mode_allow = false; @@ -32,6 +35,11 @@ struct GrpcInitializeConfigOpts { uint64_t timeout_ms = 300'000; // 5 minutes. bool validate_mutations = false; bool retry_5xx = false; + // In some tests a request is never sent. If a request is never sent, stats are not set. In those + // tests, we need to be able to override this to false. + absl::optional expect_stats_override; + // In timeout tests we expect zero response bytes. + bool stats_expect_response_bytes = true; }; struct WaitForSuccessfulUpstreamResponseOpts { @@ -48,7 +56,7 @@ class ExtAuthzGrpcIntegrationTest : public Grpc::BaseGrpcClientIntegrationParamTest, public HttpIntegrationTest, public testing::TestWithParam< - std::tuple, bool>> { + std::tuple, bool, bool>> { public: ExtAuthzGrpcIntegrationTest() @@ -56,12 +64,13 @@ class ExtAuthzGrpcIntegrationTest static std::string testParamsToString( const ::testing::TestParamInfo< - std::tuple, bool>>& p) { + std::tuple, bool, bool>>& p) { return fmt::format( - "{}_{}_{}", TestUtility::ipVersionToString(std::get<0>(std::get<0>(p.param))), + "{}_{}_{}_{}", TestUtility::ipVersionToString(std::get<0>(std::get<0>(p.param))), std::get<1>(std::get<0>(p.param)) == Grpc::ClientType::GoogleGrpc ? "GoogleGrpc" : "EnvoyGrpc", - std::get<1>(p.param) ? "RawHeaders" : "LegacyHeaders"); + std::get<1>(p.param) ? "RawHeaders" : "LegacyHeaders", + std::get<2>(p.param) ? "EmitFilterStateStats" : "DoNotEmitFilterStateStats"); } // BaseGrpcClientIntegrationParamTest @@ -73,6 +82,8 @@ class ExtAuthzGrpcIntegrationTest bool encodeRawHeaders() const { return std::get<1>(GetParam()); } + bool emitFilterStateStats() const { return std::get<2>(GetParam()); } + void createUpstreams() override { HttpIntegrationTest::createUpstreams(); addFakeUpstream(Http::CodecType::HTTP2); @@ -119,6 +130,12 @@ class ExtAuthzGrpcIntegrationTest proto_config_.set_validate_mutations(opts.validate_mutations); proto_config_.set_encode_raw_headers(encodeRawHeaders()); + if (emitFilterStateStats()) { + proto_config_.set_emit_filter_state_stats(true); + *(*proto_config_.mutable_filter_metadata()->mutable_fields())["foo"] + .mutable_string_value() = "bar"; + } + // Add labels and verify they are passed. std::map labels; labels["label_1"] = "value_1"; @@ -137,9 +154,28 @@ class ExtAuthzGrpcIntegrationTest *bootstrap.mutable_node()->mutable_metadata() = metadata; envoy::config::listener::v3::Filter ext_authz_filter; - ext_authz_filter.set_name("envoy.filters.http.ext_authz"); + ext_authz_filter.set_name(ExtAuthzFilterName); ext_authz_filter.mutable_typed_config()->PackFrom(proto_config_); config_helper_.prependFilter(MessageUtil::getJsonStringFromMessageOrError(ext_authz_filter)); + + if (emitFilterStateStats()) { + test::integration::filters::LoggingTestFilterConfig logging_filter_config; + logging_filter_config.set_logging_id("envoy.filters.http.ext_authz"); + logging_filter_config.set_upstream_cluster_name("ext_authz_cluster"); + logging_filter_config.set_expect_stats(opts.expect_stats_override.value_or(true)); + logging_filter_config.set_expect_envoy_grpc_specific_stats(clientType() == + Grpc::ClientType::EnvoyGrpc); + logging_filter_config.set_expect_response_bytes(opts.stats_expect_response_bytes); + + // Set the same filter metadata to the ext authz filter and the logging test filter. + *(*logging_filter_config.mutable_filter_metadata()->mutable_fields())["foo"] + .mutable_string_value() = "bar"; + + envoy::extensions::filters::network::http_connection_manager::v3::HttpFilter logging_filter; + logging_filter.set_name("logging_filter"); + logging_filter.mutable_typed_config()->PackFrom(logging_filter_config); + config_helper_.prependFilter(MessageUtil::getJsonStringFromMessageOrError(logging_filter)); + } }); } @@ -600,6 +636,8 @@ class ExtAuthzGrpcIntegrationTest void expectFilterDisableCheck(bool deny_at_disable, bool disable_with_metadata, const std::string& expected_status) { GrpcInitializeConfigOpts opts; + // Request is never sent; stats will not be emitted. + opts.expect_stats_override = false; opts.disable_with_metadata = disable_with_metadata; initializeConfig(opts); setDenyAtDisableRuntimeConfig(deny_at_disable, disable_with_metadata); @@ -936,7 +974,8 @@ class ExtAuthzHttpIntegrationTest }; INSTANTIATE_TEST_SUITE_P(IpVersionsCientType, ExtAuthzGrpcIntegrationTest, - testing::Combine(GRPC_CLIENT_INTEGRATION_PARAMS, testing::Bool()), + testing::Combine(GRPC_CLIENT_INTEGRATION_PARAMS, testing::Bool(), + testing::Bool()), ExtAuthzGrpcIntegrationTest::testParamsToString); // Verifies that the request body is included in the CheckRequest when the downstream protocol is @@ -1104,6 +1143,7 @@ TEST_P(ExtAuthzGrpcIntegrationTest, DownstreamHeadersOnSuccess) { TEST_P(ExtAuthzGrpcIntegrationTest, TimeoutFailClosed) { GrpcInitializeConfigOpts opts; + opts.stats_expect_response_bytes = false; opts.failure_mode_allow = false; opts.timeout_ms = 1; initializeConfig(opts); @@ -1181,6 +1221,7 @@ TEST_P(ExtAuthzGrpcIntegrationTest, ValidateMutations) { TEST_P(ExtAuthzGrpcIntegrationTest, TimeoutFailOpen) { GrpcInitializeConfigOpts init_opts; + init_opts.stats_expect_response_bytes = false; init_opts.failure_mode_allow = true; init_opts.timeout_ms = 1; initializeConfig(init_opts); diff --git a/test/extensions/filters/http/ext_authz/ext_authz_test.cc b/test/extensions/filters/http/ext_authz/ext_authz_test.cc index fab44855d8..7dd8d30971 100644 --- a/test/extensions/filters/http/ext_authz/ext_authz_test.cc +++ b/test/extensions/filters/http/ext_authz/ext_authz_test.cc @@ -70,7 +70,7 @@ template class HttpFilterTestBase : public T { void initialize(const envoy::extensions::filters::http::ext_authz::v3::ExtAuthz& proto_config) { config_ = std::make_shared(proto_config, *stats_store_.rootScope(), "ext_authz_prefix", factory_context_); - client_ = new Filters::Common::ExtAuthz::MockClient(); + client_ = new NiceMock(); filter_ = std::make_unique(config_, Filters::Common::ExtAuthz::ClientPtr{client_}); ON_CALL(decoder_filter_callbacks_, filterConfigName()).WillByDefault(Return(FilterConfigName)); filter_->setDecoderFilterCallbacks(decoder_filter_callbacks_); @@ -79,7 +79,8 @@ template class HttpFilterTestBase : public T { } static envoy::extensions::filters::http::ext_authz::v3::ExtAuthz - getFilterConfig(bool failure_mode_allow, bool http_client) { + getFilterConfig(bool failure_mode_allow, bool http_client, bool emit_filter_state_stats = false, + absl::optional filter_metadata = absl::nullopt) { const std::string http_config = R"EOF( failure_mode_allow_header_add: true http_service: @@ -99,6 +100,12 @@ template class HttpFilterTestBase : public T { envoy::extensions::filters::http::ext_authz::v3::ExtAuthz proto_config{}; TestUtility::loadFromYaml(http_client ? http_config : grpc_config, proto_config); proto_config.set_failure_mode_allow(failure_mode_allow); + if (emit_filter_state_stats) { + proto_config.set_emit_filter_state_stats(true); + } + if (filter_metadata.has_value()) { + *proto_config.mutable_filter_metadata() = *filter_metadata; + } return proto_config; } @@ -200,6 +207,116 @@ INSTANTIATE_TEST_SUITE_P(ParameterizedFilterConfig, HttpFilterTestParam, testing::Combine(testing::Bool(), testing::Bool()), HttpFilterTestParam::ParamsToString); +class EmitFilterStateTest + : public HttpFilterTestBase>> { +public: + EmitFilterStateTest() : expected_output_(filterMetadata()) {} + + absl::optional filterMetadata() const { + if (!std::get<2>(GetParam())) { + return absl::nullopt; + } + + auto filter_metadata = Envoy::ProtobufWkt::Struct(); + *(*filter_metadata.mutable_fields())["foo"].mutable_string_value() = "bar"; + return filter_metadata; + } + + void SetUp() override { + initialize(getFilterConfig(/*failure_mode_allow=*/false, std::get<0>(GetParam()), + std::get<1>(GetParam()), filterMetadata())); + + stream_info_ = std::make_unique>(); + + auto bytes_meter = std::make_shared(); + bytes_meter->addWireBytesSent(123); + bytes_meter->addWireBytesReceived(456); + stream_info_->upstream_bytes_meter_ = bytes_meter; + + auto upstream_info = std::make_shared>(); + auto upstream_host = std::make_shared>(); + upstream_info->upstream_host_ = upstream_host; + stream_info_->upstream_info_ = upstream_info; + + auto upstream_cluster_info = std::make_shared>(); + stream_info_->upstream_cluster_info_ = upstream_cluster_info; + + absl::optional filter_metadata = absl::nullopt; + if (std::get<2>(GetParam())) { + filter_metadata = Envoy::ProtobufWkt::Struct(); + *(*filter_metadata->mutable_fields())["foo"].mutable_string_value() = "bar"; + } + + expected_output_.setLatency(std::chrono::milliseconds(1)); + expected_output_.setUpstreamHost(upstream_host); + expected_output_.setClusterInfo(upstream_cluster_info); + expected_output_.setBytesSent(123); + expected_output_.setBytesReceived(456); + } + + static std::string + ParamsToString(const testing::TestParamInfo>& info) { + return absl::StrCat(std::get<0>(info.param) ? "HttpClient" : "GrpcClient", "_", + std::get<1>(info.param) ? "EmitStats" : "DoNotEmitStats", "_", + std::get<2>(info.param) ? "EmitFilterMetadata" : "DoNotEmitFilterMetadata"); + } + + // Convenience function to save rewriting the same boilerplate & checks for all these tests. + void test(const Filters::Common::ExtAuthz::Response& response) { + InSequence s; + + prepareCheck(); + + // ext_authz makes a single call to the external auth service once it sees the end of stream. + EXPECT_CALL(*client_, check(_, _, _, _)) + .WillOnce(Invoke([&](Filters::Common::ExtAuthz::RequestCallbacks& callbacks, + const envoy::service::auth::v3::CheckRequest&, Tracing::Span&, + const StreamInfo::StreamInfo&) -> void { + decoder_filter_callbacks_.dispatcher_.globalTimeSystem().advanceTimeWait( + std::chrono::milliseconds(1)); + request_callbacks_ = &callbacks; + })); + + EXPECT_CALL(*client_, streamInfo()).WillRepeatedly(Return(stream_info_.get())); + + EXPECT_EQ(Http::FilterHeadersStatus::StopAllIterationAndWatermark, + filter_->decodeHeaders(request_headers_, true)); + + request_callbacks_->onComplete(std::make_unique(response)); + + auto filter_state = decoder_filter_callbacks_.streamInfo().filterState(); + + // Will exist if either of stats or filter metadata is emitted or both. + ASSERT_EQ(filter_state->hasData(FilterConfigName), + std::get<1>(GetParam()) || std::get<2>(GetParam())); + + if (std::get<1>(GetParam())) { + auto actual = filter_state->getDataReadOnly(FilterConfigName); + + EXPECT_EQ(actual->latency(), expected_output_.latency()); + EXPECT_EQ(actual->upstreamHost(), expected_output_.upstreamHost()); + EXPECT_EQ(actual->clusterInfo(), expected_output_.clusterInfo()); + EXPECT_EQ(actual->bytesSent(), expected_output_.bytesSent()); + EXPECT_EQ(actual->bytesReceived(), expected_output_.bytesReceived()); + } + + if (std::get<2>(GetParam())) { + auto actual = filter_state->getDataReadOnly(FilterConfigName); + ASSERT_TRUE(actual->filterMetadata().has_value()); + EXPECT_EQ(actual->filterMetadata()->DebugString(), + expected_output_.filterMetadata()->DebugString()); + } + } + + std::unique_ptr> stream_info_; + ExtAuthzLoggingInfo expected_output_; +}; + +INSTANTIATE_TEST_SUITE_P(EmitFilterStateTestParams, EmitFilterStateTest, + testing::Combine(testing::Bool(), testing::Bool(), testing::Bool()), + EmitFilterStateTest::ParamsToString); + class InvalidMutationTest : public HttpFilterTestBase { public: InvalidMutationTest() : invalid_value_(reinterpret_cast(invalid_value_bytes_)) {} @@ -2273,6 +2390,7 @@ TEST_F(HttpFilterTest, FilterDisabled) { default_value: numerator: 0 denominator: HUNDRED + emit_filter_state_stats: true )EOF"); ON_CALL(factory_context_.runtime_loader_.snapshot_, @@ -2284,6 +2402,9 @@ TEST_F(HttpFilterTest, FilterDisabled) { EXPECT_CALL(*client_, check(_, _, _, _)).Times(0); // Engage the filter. EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers_, false)); + // The stats / logging filter state should not be added if no request is sent. + auto filter_state = decoder_filter_callbacks_.streamInfo().filterState(); + EXPECT_FALSE(filter_state->hasData(FilterConfigName)); } // Test that filter can be enabled via the filter_enabled field. @@ -2927,71 +3048,6 @@ TEST_P(HttpFilterTestParam, ImmediateOkResponse) { EXPECT_EQ(1U, config_->stats().ok_.value()); } -TEST_F(HttpFilterTest, LoggingInfoOK) { - InSequence s; - - initialize(R"EOF( - grpc_service: - envoy_grpc: - cluster_name: "ext_authz_server" - filter_metadata: - foo: "bar" - )EOF"); - - prepareCheck(); - - Filters::Common::ExtAuthz::Response response{}; - response.status = Filters::Common::ExtAuthz::CheckStatus::OK; - - EXPECT_CALL(*client_, check(_, _, _, _)) - .WillOnce(Invoke([&](Filters::Common::ExtAuthz::RequestCallbacks& callbacks, - const envoy::service::auth::v3::CheckRequest&, Tracing::Span&, - const StreamInfo::StreamInfo&) -> void { - callbacks.onComplete(std::make_unique(response)); - })); - EXPECT_CALL(decoder_filter_callbacks_, continueDecoding()).Times(0); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers_, false)); - EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); - - auto filter_state = decoder_filter_callbacks_.streamInfo().filterState(); - ASSERT_TRUE(filter_state->hasData(FilterConfigName)); - - auto logging_info = filter_state->getDataReadOnly(FilterConfigName); - ASSERT_TRUE(logging_info->filterMetadata().fields().contains("foo")); - EXPECT_EQ(logging_info->filterMetadata().fields().at("foo").string_value(), "bar"); -} - -// Test that if no filter metadata is configured, filter state is not added to stream info. -TEST_F(HttpFilterTest, LoggingInfoEmpty) { - InSequence s; - - initialize(R"EOF( - grpc_service: - envoy_grpc: - cluster_name: "ext_authz_server" - )EOF"); - - prepareCheck(); - - Filters::Common::ExtAuthz::Response response{}; - response.status = Filters::Common::ExtAuthz::CheckStatus::OK; - - EXPECT_CALL(*client_, check(_, _, _, _)) - .WillOnce(Invoke([&](Filters::Common::ExtAuthz::RequestCallbacks& callbacks, - const envoy::service::auth::v3::CheckRequest&, Tracing::Span&, - const StreamInfo::StreamInfo&) -> void { - callbacks.onComplete(std::make_unique(response)); - })); - EXPECT_CALL(decoder_filter_callbacks_, continueDecoding()).Times(0); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers_, false)); - EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); - - auto filter_state = decoder_filter_callbacks_.streamInfo().filterState(); - EXPECT_FALSE(filter_state->hasData(FilterConfigName)); -} - // Test that an synchronous denied response from the authorization service passing additional HTTP // attributes to the downstream. TEST_P(HttpFilterTestParam, ImmediateDeniedResponseWithHttpAttributes) { @@ -3888,6 +3944,78 @@ TEST_P(HttpFilterTestParam, DisableRequestBodyBufferingOnRoute) { EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); } +TEST_P(EmitFilterStateTest, OkResponse) { + Filters::Common::ExtAuthz::Response response{}; + response.status = Filters::Common::ExtAuthz::CheckStatus::OK; + + test(response); +} + +TEST_P(EmitFilterStateTest, Error) { + Filters::Common::ExtAuthz::Response response{}; + response.status = Filters::Common::ExtAuthz::CheckStatus::Error; + + test(response); +} + +TEST_P(EmitFilterStateTest, Denied) { + Filters::Common::ExtAuthz::Response response{}; + response.status = Filters::Common::ExtAuthz::CheckStatus::Denied; + + test(response); +} + +// Tests that if for whatever reason the client's stream info is null, it doesn't result in a null +// pointer dereference or other issue. +TEST_P(EmitFilterStateTest, NullStreamInfo) { + stream_info_ = nullptr; + + // Everything except latency will be empty. + expected_output_.clearUpstreamHost(); + expected_output_.clearClusterInfo(); + expected_output_.clearBytesSent(); + expected_output_.clearBytesReceived(); + + Filters::Common::ExtAuthz::Response response{}; + response.status = Filters::Common::ExtAuthz::CheckStatus::OK; + + test(response); +} + +// Tests that if any stream info fields are null, it doesn't result in a null pointer dereference or +// other issue. +TEST_P(EmitFilterStateTest, NullStreamInfoFields) { + stream_info_->upstream_bytes_meter_ = nullptr; + stream_info_->upstream_info_ = nullptr; + stream_info_->upstream_cluster_info_ = nullptr; + + // Everything except latency will be empty. + expected_output_.clearUpstreamHost(); + expected_output_.clearClusterInfo(); + expected_output_.clearBytesSent(); + expected_output_.clearBytesReceived(); + + Filters::Common::ExtAuthz::Response response{}; + response.status = Filters::Common::ExtAuthz::CheckStatus::OK; + + test(response); +} + +// Tests that if upstream host is null, it doesn't result in a null pointer dereference or other +// issue. +TEST_P(EmitFilterStateTest, NullUpstreamHost) { + auto upstream_info = std::make_shared>(); + upstream_info->upstream_host_ = nullptr; + stream_info_->upstream_info_ = upstream_info; + + expected_output_.clearUpstreamHost(); + + Filters::Common::ExtAuthz::Response response{}; + response.status = Filters::Common::ExtAuthz::CheckStatus::OK; + + test(response); +} + } // namespace } // namespace ExtAuthz } // namespace HttpFilters diff --git a/test/extensions/filters/http/ext_authz/logging_test_filter.cc b/test/extensions/filters/http/ext_authz/logging_test_filter.cc new file mode 100644 index 0000000000..9d2e8e8548 --- /dev/null +++ b/test/extensions/filters/http/ext_authz/logging_test_filter.cc @@ -0,0 +1,102 @@ +#include + +#include "envoy/http/filter.h" +#include "envoy/registry/registry.h" +#include "envoy/server/filter_config.h" + +#include "source/extensions/filters/http/common/factory_base.h" +#include "source/extensions/filters/http/common/pass_through_filter.h" +#include "source/extensions/filters/http/ext_authz/ext_authz.h" + +#include "test/extensions/filters/http/ext_authz/logging_test_filter.pb.h" +#include "test/extensions/filters/http/ext_authz/logging_test_filter.pb.validate.h" +#include "test/test_common/utility.h" + +#include "gtest/gtest.h" + +namespace Envoy { +namespace Extensions { +namespace HttpFilters { +namespace ExternalProcessing { + +// A test filter that retrieve the logging info on encodeComplete. +class LoggingTestFilter : public Http::PassThroughFilter { +public: + LoggingTestFilter(const std::string& logging_id, const std::string& cluster_name, + bool expect_stats, bool expect_envoy_grpc_specific_stats, + bool expect_response_bytes, const ProtobufWkt::Struct& filter_metadata) + : logging_id_(logging_id), expected_cluster_name_(cluster_name), expect_stats_(expect_stats), + expect_envoy_grpc_specific_stats_(expect_envoy_grpc_specific_stats), + expect_response_bytes_(expect_response_bytes), filter_metadata_(filter_metadata) {} + void encodeComplete() override { + ASSERT(decoder_callbacks_ != nullptr); + const Envoy::StreamInfo::FilterStateSharedPtr& filter_state = + decoder_callbacks_->streamInfo().filterState(); + + ASSERT_EQ(filter_state->hasData(logging_id_), expect_stats_); + if (!expect_stats_) { + return; + } + + const ExtAuthz::ExtAuthzLoggingInfo* ext_authz_logging_info = + filter_state->getDataReadOnly(logging_id_); + + ASSERT_EQ(ext_authz_logging_info->filterMetadata().has_value(), filter_metadata_.has_value()); + if (filter_metadata_.has_value()) { + // TODO: Is there a better way to do deep comparison of protos? + EXPECT_EQ(ext_authz_logging_info->filterMetadata()->DebugString(), + filter_metadata_->DebugString()); + } + + ASSERT_TRUE(ext_authz_logging_info->latency().has_value()); + EXPECT_GT(ext_authz_logging_info->latency()->count(), 0); + if (expect_envoy_grpc_specific_stats_) { + // If the stats exist a request should always have been sent. + EXPECT_GT(ext_authz_logging_info->bytesSent(), 0); + + // A response may or may not have been received depending on the test. + if (expect_response_bytes_) { + EXPECT_GT(ext_authz_logging_info->bytesReceived(), 0); + } else { + EXPECT_EQ(ext_authz_logging_info->bytesReceived(), 0); + } + ASSERT_NE(ext_authz_logging_info->upstreamHost(), nullptr); + EXPECT_EQ(ext_authz_logging_info->upstreamHost()->cluster().name(), expected_cluster_name_); + } + } + +private: + const std::string logging_id_; + const std::string expected_cluster_name_; + const bool expect_stats_; + const bool expect_envoy_grpc_specific_stats_; + const bool expect_response_bytes_; + const absl::optional filter_metadata_; +}; + +class LoggingTestFilterFactory : public Extensions::HttpFilters::Common::FactoryBase< + test::integration::filters::LoggingTestFilterConfig> { +public: + LoggingTestFilterFactory() : FactoryBase("logging-test-filter"){}; + + Http::FilterFactoryCb createFilterFactoryFromProtoTyped( + const test::integration::filters::LoggingTestFilterConfig& proto_config, const std::string&, + Server::Configuration::FactoryContext&) override { + return [=](Http::FilterChainFactoryCallbacks& callbacks) -> void { + callbacks.addStreamFilter(std::make_shared( + proto_config.logging_id(), proto_config.upstream_cluster_name(), + proto_config.expect_stats(), proto_config.expect_envoy_grpc_specific_stats(), + proto_config.expect_response_bytes(), proto_config.filter_metadata())); + }; + } +}; + +// Perform static registration +static Registry::RegisterFactory + register_; + +} // namespace ExternalProcessing +} // namespace HttpFilters +} // namespace Extensions +} // namespace Envoy diff --git a/test/extensions/filters/http/ext_authz/logging_test_filter.proto b/test/extensions/filters/http/ext_authz/logging_test_filter.proto new file mode 100644 index 0000000000..799dbd1d68 --- /dev/null +++ b/test/extensions/filters/http/ext_authz/logging_test_filter.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package test.integration.filters; + +import "google/protobuf/struct.proto"; + +message LoggingTestFilterConfig { + string logging_id = 1; + string upstream_cluster_name = 2; + bool expect_stats = 3; + bool expect_envoy_grpc_specific_stats = 4; + bool expect_response_bytes = 5; + google.protobuf.Struct filter_metadata = 6; +} diff --git a/test/extensions/filters/http/oauth2/filter_test.cc b/test/extensions/filters/http/oauth2/filter_test.cc index b73bcf5890..e5110a4762 100644 --- a/test/extensions/filters/http/oauth2/filter_test.cc +++ b/test/extensions/filters/http/oauth2/filter_test.cc @@ -367,8 +367,13 @@ TEST_F(OAuth2Test, DefaultAuthScope) { {Http::Headers::get().Scheme.get(), "http"}, }; + // Set SystemTime to a fixed point so we get consistent nonce between test runs. + test_time_.setSystemTime(SystemTime(std::chrono::seconds(123456789))); + Http::TestResponseHeaderMapImpl response_headers{ {Http::Headers::get().Status.get(), "302"}, + {Http::Headers::get().SetCookie.get(), + "OauthNonce=1234567890000000;path=/;Max-Age=600;secure;HttpOnly"}, {Http::Headers::get().Location.get(), "https://auth.example.com/oauth/" "authorize/?client_id=" + @@ -376,7 +381,9 @@ TEST_F(OAuth2Test, DefaultAuthScope) { "&redirect_uri=http%3A%2F%2Ftraffic.example.com%2F_oauth" "&response_type=code" "&scope=" + - TEST_DEFAULT_SCOPE + "&state=http%3A%2F%2Ftraffic.example.com%2Fnot%2F_oauth"}, + TEST_DEFAULT_SCOPE + + "&state=url%3Dhttp%253A%252F%252Ftraffic.example.com%252Fnot%252F_oauth%26nonce%" + "3D1234567890000000"}, }; // explicitly tell the validator to fail the validation. @@ -423,9 +430,13 @@ TEST_F(OAuth2Test, PreservesQueryParametersInAuthorizationEndpoint) { EXPECT_CALL(*validator_, setParams(_, _)); EXPECT_CALL(*validator_, isValid()).WillOnce(Return(false)); + // Set SystemTime to a fixed point so we get consistent nonce between test runs. + test_time_.setSystemTime(SystemTime(std::chrono::seconds(123456789))); // Verify that the foo=bar query parameter is preserved in the redirect. Http::TestResponseHeaderMapImpl response_headers{ {Http::Headers::get().Status.get(), "302"}, + {Http::Headers::get().SetCookie.get(), + "OauthNonce=1234567890000000;path=/;Max-Age=600;secure;HttpOnly"}, {Http::Headers::get().Location.get(), "https://auth.example.com/oauth/" "authorize/?client_id=" + @@ -434,7 +445,9 @@ TEST_F(OAuth2Test, PreservesQueryParametersInAuthorizationEndpoint) { "&redirect_uri=http%3A%2F%2Ftraffic.example.com%2F_oauth" "&response_type=code" "&scope=" + - TEST_DEFAULT_SCOPE + "&state=http%3A%2F%2Ftraffic.example.com%2Fnot%2F_oauth"}, + TEST_DEFAULT_SCOPE + + "&state=url%3Dhttp%253A%252F%252Ftraffic.example.com%252Fnot%252F_oauth%26nonce%" + "3D1234567890000000"}, }; EXPECT_CALL(decoder_callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), true)); @@ -475,9 +488,14 @@ TEST_F(OAuth2Test, PreservesQueryParametersInAuthorizationEndpointWithUrlEncodin EXPECT_CALL(*validator_, setParams(_, _)); EXPECT_CALL(*validator_, isValid()).WillOnce(Return(false)); + // Set SystemTime to a fixed point so we get consistent nonce between test runs. + test_time_.setSystemTime(SystemTime(std::chrono::seconds(123456789))); + // Verify that the foo=bar query parameter is preserved in the redirect. Http::TestResponseHeaderMapImpl response_headers{ {Http::Headers::get().Status.get(), "302"}, + {Http::Headers::get().SetCookie.get(), + "OauthNonce=1234567890000000;path=/;Max-Age=600;secure;HttpOnly"}, {Http::Headers::get().Location.get(), "https://auth.example.com/oauth/" "authorize/?client_id=" + @@ -486,7 +504,9 @@ TEST_F(OAuth2Test, PreservesQueryParametersInAuthorizationEndpointWithUrlEncodin "&redirect_uri=http%3A%2F%2Ftraffic.example.com%2F_oauth" "&response_type=code" "&scope=" + - TEST_DEFAULT_SCOPE + "&state=http%3A%2F%2Ftraffic.example.com%2Fnot%2F_oauth"}, + TEST_DEFAULT_SCOPE + + "&state=url%3Dhttp%253A%252F%252Ftraffic.example.com%252Fnot%252F_oauth%26nonce%" + "3D1234567890000000"}, }; EXPECT_CALL(decoder_callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), true)); @@ -682,9 +702,14 @@ TEST_F(OAuth2Test, OAuthErrorNonOAuthHttpCallback) { {Http::Headers::get().Scheme.get(), "https"}, }; + // Set SystemTime to a fixed point so we get consistent nonce between test runs. + test_time_.setSystemTime(SystemTime(std::chrono::seconds(123456789))); + // This is the immediate response - a redirect to the auth cluster. Http::TestResponseHeaderMapImpl first_response_headers{ {Http::Headers::get().Status.get(), "302"}, + {Http::Headers::get().SetCookie.get(), + "OauthNonce=1234567890000000;path=/;Max-Age=600;secure;HttpOnly"}, {Http::Headers::get().Location.get(), "https://auth.example.com/oauth/" "authorize/?client_id=" + @@ -693,7 +718,8 @@ TEST_F(OAuth2Test, OAuthErrorNonOAuthHttpCallback) { "&response_type=code" "&scope=" + TEST_ENCODED_AUTH_SCOPES + - "&state=https%3A%2F%2Ftraffic.example.com%2Ftest%3Fname%3Dadmin%26level%3Dtrace" + "&state=url%3Dhttps%253A%252F%252Ftraffic.example.com%252Ftest%253Fname%253Dadmin%" + "2526level%253Dtrace%26nonce%3D1234567890000000" "&resource=oauth2-resource&resource=http%3A%2F%2Fexample.com" "&resource=https%3A%2F%2Fexample.com%2Fsome%2Fpath%252F..%252F%2Futf8%C3%83%3Bfoo%3Dbar%" "3Fvar1%3D1%26var2%3D2"}, @@ -712,8 +738,11 @@ TEST_F(OAuth2Test, OAuthErrorNonOAuthHttpCallback) { // This represents the callback request from the authorization server. Http::TestRequestHeaderMapImpl second_request_headers{ - {Http::Headers::get().Path.get(), "/_oauth?code=123&state=https%3A%2F%2Ftraffic.example.com%" - "2Ftest%3Fname%3Dadmin%26level%3Dtrace"}, + {Http::Headers::get().Path.get(), + "/_oauth?code=123&state=url%3Dhttps%253A%252F%252Ftraffic.example.com%252Ftest%253Fname%" + "253Dadmin%2526level%253Dtrace%26nonce%3D1234567890000000"}, + {Http::Headers::get().Cookie.get(), + "OauthNonce=1234567890000000;path=/;Max-Age=600;secure;HttpOnly"}, {Http::Headers::get().Host.get(), "traffic.example.com"}, {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Get}, {Http::Headers::get().Scheme.get(), "https"}, @@ -798,14 +827,17 @@ TEST_F(OAuth2Test, OAuthErrorQueryString) { } /** - * Scenario: The OAuth filter requests credentials from auth.example.com which returns a - * response without expires_in (JSON response is mocked out) + * Scenario: The OAuth filter receives a callback request from the OAuth server. * - * Expected behavior: the filter should return a 401 directly to the user. + * Expected behavior: the filter should pause the request and call the OAuth client to get the + * tokens. */ TEST_F(OAuth2Test, OAuthCallbackStartsAuthentication) { Http::TestRequestHeaderMapImpl request_headers{ - {Http::Headers::get().Path.get(), "/_oauth?code=123&state=https://asdf&method=GET"}, + {Http::Headers::get().Path.get(), + "/_oauth?code=123&state=url%3Dhttps%253A%252F%252Fasdf%26nonce%3D1234567890000000"}, + {Http::Headers::get().Cookie.get(), + "OauthNonce=1234567890000000;path=/;Max-Age=600;secure;HttpOnly"}, {Http::Headers::get().Host.get(), "traffic.example.com"}, {Http::Headers::get().Scheme.get(), "https"}, {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Get}, @@ -823,6 +855,91 @@ TEST_F(OAuth2Test, OAuthCallbackStartsAuthentication) { filter_->decodeHeaders(request_headers, false)); } +/** + * Scenario: The OAuth filter receives a callback request from the OAuth server that lacks a nonce. + * This scenario simulates a CSRF attack where the original OAuth request was inserted to the user's + * browser by a malicious actor, and the user was tricked into clicking on the link. + * + * Expected behavior: the filter should fail the request and return a 401 Unauthorized response. + */ +TEST_F(OAuth2Test, OAuthCallbackStartsAuthenticationNoNonce) { + Http::TestRequestHeaderMapImpl request_headers{ + {Http::Headers::get().Path.get(), "/_oauth?code=123&state=url%3Dhttps%253A%252F%252Fasdf"}, + {Http::Headers::get().Cookie.get(), + "OauthNonce=1234567890000000;path=/;Max-Age=600;secure;HttpOnly"}, + {Http::Headers::get().Host.get(), "traffic.example.com"}, + {Http::Headers::get().Scheme.get(), "https"}, + {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Get}, + }; + + // Deliberately fail the HMAC Validation check. + EXPECT_CALL(*validator_, setParams(_, _)); + EXPECT_CALL(*validator_, isValid()).WillOnce(Return(false)); + + EXPECT_CALL(decoder_callbacks_, sendLocalReply(Http::Code::Unauthorized, _, _, _, _)); + + EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, + filter_->decodeHeaders(request_headers, false)); +} + +/** + * Scenario: The OAuth filter receives a callback request from the OAuth server that has an invalid + * nonce. This scenario simulates a CSRF attack where the original OAuth request was inserted to the + * user's browser by a malicious actor, and the user was tricked into clicking on the link. + * + * Expected behavior: the filter should fail the request and return a 401 Unauthorized response. + */ +TEST_F(OAuth2Test, OAuthCallbackStartsAuthenticationInvalidNonce) { + Http::TestRequestHeaderMapImpl request_headers{ + {Http::Headers::get().Path.get(), + "/_oauth?code=123&state=url%3Dhttps%253A%252F%252Fasdf%26nonce%3D123456788000000"}, + {Http::Headers::get().Cookie.get(), + "OauthNonce=1234567890000000;path=/;Max-Age=600;secure;HttpOnly"}, + {Http::Headers::get().Host.get(), "traffic.example.com"}, + {Http::Headers::get().Scheme.get(), "https"}, + {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Get}, + }; + + // Deliberately fail the HMAC Validation check. + EXPECT_CALL(*validator_, setParams(_, _)); + EXPECT_CALL(*validator_, isValid()).WillOnce(Return(false)); + + EXPECT_CALL(decoder_callbacks_, sendLocalReply(Http::Code::Unauthorized, _, _, _, _)); + + EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, + filter_->decodeHeaders(request_headers, false)); +} + +/** + * Scenario: The OAuth filter receives a callback request from the OAuth server that has a malformed + * state. This scenario simulates a CSRF attack where the original OAuth request was inserted to the + * user's browser by a malicious actor, and the user was tricked into clicking on the link. + * + * Expected behavior: the filter should fail the request and return a 401 Unauthorized response. + */ +TEST_F(OAuth2Test, OAuthCallbackStartsAuthenticationMalformedState) { + // Set SystemTime to a fixed point so we get consistent HMAC encodings between test runs. + test_time_.setSystemTime(SystemTime(std::chrono::seconds(0))); + + Http::TestRequestHeaderMapImpl request_headers{ + {Http::Headers::get().Path.get(), "/_oauth?code=123&state=https%253A%252F%252Fasdf"}, + {Http::Headers::get().Cookie.get(), + "OauthNonce=1234567890000000;path=/;Max-Age=600;secure;HttpOnly"}, + {Http::Headers::get().Host.get(), "traffic.example.com"}, + {Http::Headers::get().Scheme.get(), "https"}, + {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Get}, + }; + + // Deliberately fail the HMAC Validation check. + EXPECT_CALL(*validator_, setParams(_, _)); + EXPECT_CALL(*validator_, isValid()).WillOnce(Return(false)); + + EXPECT_CALL(decoder_callbacks_, sendLocalReply(Http::Code::Unauthorized, _, _, _, _)); + + EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, + filter_->decodeHeaders(request_headers, false)); +} + /** * Scenario: Protoc in opted-in to allow OPTIONS requests to pass-through. This is important as * POST requests initiate an OPTIONS request first in order to ensure POST is supported. During a @@ -881,22 +998,23 @@ TEST_F(OAuth2Test, AjaxDoesNotRedirect) { // Validates the behavior of the cookie validator. TEST_F(OAuth2Test, CookieValidator) { - expectValidCookies( - CookieNames{"BearerToken", "OauthHMAC", "OauthExpires", "IdToken", "RefreshToken"}, ""); + expectValidCookies(CookieNames{"BearerToken", "OauthHMAC", "OauthExpires", "IdToken", + "RefreshToken", "OauthNonce"}, + ""); } // Validates the behavior of the cookie validator with custom cookie names. TEST_F(OAuth2Test, CookieValidatorWithCustomNames) { expectValidCookies(CookieNames{"CustomBearerToken", "CustomOauthHMAC", "CustomOauthExpires", - "CustomIdToken", "CustomRefreshToken"}, + "CustomIdToken", "CustomRefreshToken", "CustomOauthNonce"}, ""); } // Validates the behavior of the cookie validator with custom cookie domain. TEST_F(OAuth2Test, CookieValidatorWithCookieDomain) { test_time_.setSystemTime(SystemTime(std::chrono::seconds(0))); - auto cookie_names = - CookieNames{"BearerToken", "OauthHMAC", "OauthExpires", "IdToken", "RefreshToken"}; + auto cookie_names = CookieNames{"BearerToken", "OauthHMAC", "OauthExpires", + "IdToken", "RefreshToken", "OauthNonce"}; const auto expires_at_s = DateUtil::nowToSeconds(test_time_.timeSystem()) + 5; Http::TestRequestHeaderMapImpl request_headers{ @@ -925,8 +1043,8 @@ TEST_F(OAuth2Test, CookieValidatorWithCookieDomain) { // Validates the behavior of the cookie validator when the combination of some fields could be same. TEST_F(OAuth2Test, CookieValidatorSame) { test_time_.setSystemTime(SystemTime(std::chrono::seconds(0))); - auto cookie_names = - CookieNames{"BearerToken", "OauthHMAC", "OauthExpires", "IdToken", "RefreshToken"}; + auto cookie_names = CookieNames{"BearerToken", "OauthHMAC", "OauthExpires", + "IdToken", "RefreshToken", "OauthNonce"}; const auto expires_at_s = DateUtil::nowToSeconds(test_time_.timeSystem()) + 5; // Host name is `traffic.example.com:101` and the expire time is 5. @@ -998,7 +1116,9 @@ TEST_F(OAuth2Test, CookieValidatorInvalidExpiresAt) { auto cookie_validator = std::make_shared( test_time_, - CookieNames{"BearerToken", "OauthHMAC", "OauthExpires", "IdToken", "RefreshToken"}, ""); + CookieNames{"BearerToken", "OauthHMAC", "OauthExpires", "IdToken", "RefreshToken", + "OauthNonce"}, + ""); cookie_validator->setParams(request_headers, "mock-secret"); EXPECT_TRUE(cookie_validator->hmacIsValid()); @@ -1018,7 +1138,9 @@ TEST_F(OAuth2Test, CookieValidatorCanUpdateToken) { auto cookie_validator = std::make_shared( test_time_, - CookieNames("BearerToken", "OauthHMAC", "OauthExpires", "IdToken", "RefreshToken"), ""); + CookieNames("BearerToken", "OauthHMAC", "OauthExpires", "IdToken", "RefreshToken", + "OauthNonce"), + ""); cookie_validator->setParams(request_headers, "mock-secret"); EXPECT_TRUE(cookie_validator->canUpdateTokenByRefreshToken()); @@ -1112,19 +1234,24 @@ TEST_F(OAuth2Test, OAuthTestCallbackUrlInStateQueryParam) { } TEST_F(OAuth2Test, OAuthTestUpdatePathAfterSuccess) { + // Set SystemTime to a fixed point so we get consistent HMAC encodings between test runs. + test_time_.setSystemTime(SystemTime(std::chrono::seconds(0))); + init(); Http::TestRequestHeaderMapImpl request_headers{ {Http::Headers::get().Host.get(), "traffic.example.com"}, {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Get}, {Http::Headers::get().Path.get(), "/_oauth?code=abcdefxyz123&scope=" + TEST_ENCODED_AUTH_SCOPES + - "&state=https://traffic.example.com/original_path?var1=1%26var2=2"}, + "&state=url%3Dhttps%3A%2F%2Ftraffic.example.com%2Foriginal_path%3Fvar1%3D1%2526var2%3D2%" + "26nonce%3D1234567890000000"}, {Http::Headers::get().Cookie.get(), "OauthExpires=123"}, {Http::Headers::get().Cookie.get(), "BearerToken=legit_token"}, {Http::Headers::get().Cookie.get(), "OauthHMAC=" "ZTRlMzU5N2Q4ZDIwZWE5ZTU5NTg3YTU3YTcxZTU0NDFkMzY1ZTc1NjMyODYyMj" "RlNjMxZTJmNTZkYzRmZTM0ZQ===="}, + {Http::Headers::get().Cookie.get(), "OauthNonce=1234567890000000"}, }; Http::TestRequestHeaderMapImpl expected_response_headers{ @@ -1150,13 +1277,15 @@ TEST_F(OAuth2Test, OAuthTestUpdatePathAfterSuccess) { {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Get}, {Http::Headers::get().Path.get(), "/_oauth?code=abcdefxyz123&scope=" + TEST_ENCODED_AUTH_SCOPES + - "&state=https://traffic.example.com/original_path?var1=1%26var2=2"}, + "&state=url%3Dhttps%3A%2F%2Ftraffic.example.com%2Foriginal_path%3Fvar1%3D1%2526var2%3D2%" + "26nonce%3D1234567890000000"}, {Http::Headers::get().Cookie.get(), "OauthExpires=123"}, {Http::Headers::get().Cookie.get(), "BearerToken=legit_token"}, {Http::Headers::get().Cookie.get(), "OauthHMAC=" "ZTRlMzU5N2Q4ZDIwZWE5ZTU5NTg3YTU3YTcxZTU0NDFkMzY1ZTc1NjMyODYyMj" "RlNjMxZTJmNTZkYzRmZTM0ZQ===="}, + {Http::Headers::get().Cookie.get(), "OauthNonce=1234567890000000"}, {Http::CustomHeaders::get().Authorization.get(), "Bearer legit_token"}, }; @@ -1169,96 +1298,103 @@ TEST_F(OAuth2Test, OAuthTestUpdatePathAfterSuccess) { * Expected behavior: HTTP Utility should not strip the parameters of the original request. */ TEST_F(OAuth2Test, OAuthTestFullFlowPostWithParameters) { - { - TestScopedRuntime scoped_runtime; - scoped_runtime.mergeValues({ - {"envoy.reloadable_features.hmac_base64_encoding_only", "true"}, - }); - init(); - // First construct the initial request to the oauth filter with URI parameters. - Http::TestRequestHeaderMapImpl first_request_headers{ - {Http::Headers::get().Path.get(), "/test?name=admin&level=trace"}, - {Http::Headers::get().Host.get(), "traffic.example.com"}, - {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Post}, - {Http::Headers::get().Scheme.get(), "https"}, - }; + // Set SystemTime to a fixed point so we get consistent nonce between test runs. + test_time_.setSystemTime(SystemTime(std::chrono::seconds(123456789))); - // This is the immediate response - a redirect to the auth cluster. - Http::TestResponseHeaderMapImpl first_response_headers{ - {Http::Headers::get().Status.get(), "302"}, - {Http::Headers::get().Location.get(), - "https://auth.example.com/oauth/" - "authorize/?client_id=" + - TEST_CLIENT_ID + - "&redirect_uri=https%3A%2F%2Ftraffic.example.com%2F_oauth" - "&response_type=code" - "&scope=" + - TEST_ENCODED_AUTH_SCOPES + - "&state=https%3A%2F%2Ftraffic.example.com%2Ftest%3Fname%3Dadmin%26level%3Dtrace" - "&resource=oauth2-resource&resource=http%3A%2F%2Fexample.com" - "&resource=https%3A%2F%2Fexample.com%2Fsome%2Fpath%252F..%252F%2Futf8%C3%83%3Bfoo%" - "3Dbar%" - "3Fvar1%3D1%26var2%3D2"}, - }; + TestScopedRuntime scoped_runtime; + scoped_runtime.mergeValues({ + {"envoy.reloadable_features.hmac_base64_encoding_only", "true"}, + }); + init(); + // First construct the initial request to the oauth filter with URI parameters. + Http::TestRequestHeaderMapImpl first_request_headers{ + {Http::Headers::get().Path.get(), "/test?name=admin&level=trace"}, + {Http::Headers::get().Host.get(), "traffic.example.com"}, + {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Post}, + {Http::Headers::get().Scheme.get(), "https"}, + }; - // Fail the validation to trigger the OAuth flow. - EXPECT_CALL(*validator_, setParams(_, _)); - EXPECT_CALL(*validator_, isValid()).WillOnce(Return(false)); + // This is the immediate response - a redirect to the auth cluster. + Http::TestResponseHeaderMapImpl first_response_headers{ + {Http::Headers::get().Status.get(), "302"}, + {Http::Headers::get().SetCookie.get(), + "OauthNonce=1234567890000000;path=/;Max-Age=600;secure;HttpOnly"}, + {Http::Headers::get().Location.get(), + "https://auth.example.com/oauth/" + "authorize/?client_id=" + + TEST_CLIENT_ID + + "&redirect_uri=https%3A%2F%2Ftraffic.example.com%2F_oauth" + "&response_type=code" + "&scope=" + + TEST_ENCODED_AUTH_SCOPES + + "&state=url%3Dhttps%253A%252F%252Ftraffic.example.com%252Ftest%253Fname%253Dadmin%" + "2526level%253Dtrace%26nonce%3D1234567890000000" + "&resource=oauth2-resource&resource=http%3A%2F%2Fexample.com" + "&resource=https%3A%2F%2Fexample.com%2Fsome%2Fpath%252F..%252F%2Futf8%C3%83%3Bfoo%" + "3Dbar%" + "3Fvar1%3D1%26var2%3D2"}, + }; + + // Fail the validation to trigger the OAuth flow. + EXPECT_CALL(*validator_, setParams(_, _)); + EXPECT_CALL(*validator_, isValid()).WillOnce(Return(false)); - // Check that the redirect includes URL encoded query parameter characters. - EXPECT_CALL(decoder_callbacks_, - encodeHeaders_(HeaderMapEqualRef(&first_response_headers), true)); + // Check that the redirect includes URL encoded query parameter characters. + EXPECT_CALL(decoder_callbacks_, encodeHeaders_(HeaderMapEqualRef(&first_response_headers), true)); - // This represents the beginning of the OAuth filter. - EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, - filter_->decodeHeaders(first_request_headers, false)); + // This represents the beginning of the OAuth filter. + EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, + filter_->decodeHeaders(first_request_headers, false)); - // This represents the callback request from the authorization server. - Http::TestRequestHeaderMapImpl second_request_headers{ - {Http::Headers::get().Path.get(), - "/_oauth?code=123&state=https%3A%2F%2Ftraffic.example.com%" - "2Ftest%3Fname%3Dadmin%26level%3Dtrace"}, - {Http::Headers::get().Host.get(), "traffic.example.com"}, - {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Get}, - {Http::Headers::get().Scheme.get(), "https"}, - }; - // Deliberately fail the HMAC validation check. - EXPECT_CALL(*validator_, setParams(_, _)); - EXPECT_CALL(*validator_, isValid()).WillOnce(Return(false)); + // This represents the callback request from the authorization server. + Http::TestRequestHeaderMapImpl second_request_headers{ + {Http::Headers::get().Cookie.get(), + "OauthNonce=1234567890000000;path=/;Max-Age=600;secure;HttpOnly"}, + {Http::Headers::get().Path.get(), + "/_oauth?code=123&state=url%3Dhttps%253A%252F%252Ftraffic.example.com%252Ftest%253Fname%" + "253Dadmin%2526level%253Dtrace%26nonce%3D1234567890000000"}, + {Http::Headers::get().Host.get(), "traffic.example.com"}, + {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Get}, + {Http::Headers::get().Scheme.get(), "https"}, + }; + // Deliberately fail the HMAC validation check. + EXPECT_CALL(*validator_, setParams(_, _)); + EXPECT_CALL(*validator_, isValid()).WillOnce(Return(false)); - EXPECT_CALL(*oauth_client_, - asyncGetAccessToken("123", TEST_CLIENT_ID, "asdf_client_secret_fdsa", - "https://traffic.example.com" + TEST_CALLBACK, - AuthType::UrlEncodedBody)); + EXPECT_CALL(*oauth_client_, asyncGetAccessToken("123", TEST_CLIENT_ID, "asdf_client_secret_fdsa", + "https://traffic.example.com" + TEST_CALLBACK, + AuthType::UrlEncodedBody)); - // Invoke the callback logic. As a side effect, state_ will be populated. - EXPECT_EQ(Http::FilterHeadersStatus::StopAllIterationAndBuffer, - filter_->decodeHeaders(second_request_headers, false)); + // Invoke the callback logic. As a side effect, state_ will be populated. + EXPECT_EQ(Http::FilterHeadersStatus::StopAllIterationAndBuffer, + filter_->decodeHeaders(second_request_headers, false)); - EXPECT_EQ(1, config_->stats().oauth_unauthorized_rq_.value()); - EXPECT_EQ(config_->clusterName(), "auth.example.com"); + EXPECT_EQ(1, config_->stats().oauth_unauthorized_rq_.value()); + EXPECT_EQ(config_->clusterName(), "auth.example.com"); - // Expected response after the callback & validation is complete - verifying we kept the - // state and method of the original request, including the query string parameters. - Http::TestRequestHeaderMapImpl second_response_headers{ - {Http::Headers::get().Status.get(), "302"}, - {Http::Headers::get().SetCookie.get(), "OauthHMAC=" - "fV62OgLipChTQQC3UFgDp+l5sCiSb3zt7nCoJiVivWw=;" - "path=/;Max-Age=;secure;HttpOnly"}, - {Http::Headers::get().SetCookie.get(), "OauthExpires=;path=/;Max-Age=;secure;HttpOnly"}, - {Http::Headers::get().SetCookie.get(), "BearerToken=;path=/;Max-Age=;secure;HttpOnly"}, - {Http::Headers::get().Location.get(), - "https://traffic.example.com/test?name=admin&level=trace"}, - }; + // Expected response after the callback & validation is complete - verifying we kept the + // state and method of the original request, including the query string parameters. + Http::TestRequestHeaderMapImpl second_response_headers{ + {Http::Headers::get().Status.get(), "302"}, + {Http::Headers::get().SetCookie.get(), "OauthHMAC=" + "fV62OgLipChTQQC3UFgDp+l5sCiSb3zt7nCoJiVivWw=;" + "path=/;Max-Age=;secure;HttpOnly"}, + {Http::Headers::get().SetCookie.get(), "OauthExpires=;path=/;Max-Age=;secure;HttpOnly"}, + {Http::Headers::get().SetCookie.get(), "BearerToken=;path=/;Max-Age=;secure;HttpOnly"}, + {Http::Headers::get().Location.get(), + "https://traffic.example.com/test?name=admin&level=trace"}, + }; - EXPECT_CALL(decoder_callbacks_, - encodeHeaders_(HeaderMapEqualRef(&second_response_headers), true)); + EXPECT_CALL(decoder_callbacks_, + encodeHeaders_(HeaderMapEqualRef(&second_response_headers), true)); - filter_->finishGetAccessTokenFlow(); - } + filter_->finishGetAccessTokenFlow(); } TEST_F(OAuth2Test, OAuthTestFullFlowPostWithParametersFillRefreshAndIdToken) { + // Set SystemTime to a fixed point so we get consistent nonce between test runs. + test_time_.setSystemTime(SystemTime(std::chrono::seconds(123456789))); + // First construct the initial request to the oauth filter with URI parameters. Http::TestRequestHeaderMapImpl first_request_headers{ {Http::Headers::get().Path.get(), "/test?name=admin&level=trace"}, @@ -1270,6 +1406,8 @@ TEST_F(OAuth2Test, OAuthTestFullFlowPostWithParametersFillRefreshAndIdToken) { // This is the immediate response - a redirect to the auth cluster. Http::TestResponseHeaderMapImpl first_response_headers{ {Http::Headers::get().Status.get(), "302"}, + {Http::Headers::get().SetCookie.get(), + "OauthNonce=1234567890000000;path=/;Max-Age=600;secure;HttpOnly"}, {Http::Headers::get().Location.get(), "https://auth.example.com/oauth/" "authorize/?client_id=" + @@ -1278,7 +1416,8 @@ TEST_F(OAuth2Test, OAuthTestFullFlowPostWithParametersFillRefreshAndIdToken) { "&response_type=code" "&scope=" + TEST_ENCODED_AUTH_SCOPES + - "&state=https%3A%2F%2Ftraffic.example.com%2Ftest%3Fname%3Dadmin%26level%3Dtrace" + "&state=url%3Dhttps%253A%252F%252Ftraffic.example.com%252Ftest%253Fname%253Dadmin%" + "2526level%253Dtrace%26nonce%3D1234567890000000" "&resource=oauth2-resource&resource=http%3A%2F%2Fexample.com" "&resource=https%3A%2F%2Fexample.com%2Fsome%2Fpath%252F..%252F%2Futf8%C3%83%3Bfoo%3Dbar%" "3Fvar1%3D1%26var2%3D2"}, @@ -1297,8 +1436,11 @@ TEST_F(OAuth2Test, OAuthTestFullFlowPostWithParametersFillRefreshAndIdToken) { // This represents the callback request from the authorization server. Http::TestRequestHeaderMapImpl second_request_headers{ - {Http::Headers::get().Path.get(), "/_oauth?code=123&state=https%3A%2F%2Ftraffic.example.com%" - "2Ftest%3Fname%3Dadmin%26level%3Dtrace"}, + {Http::Headers::get().Cookie.get(), + "OauthNonce=1234567890000000;path=/;Max-Age=600;secure;HttpOnly"}, + {Http::Headers::get().Path.get(), + "/_oauth?code=123&state=url%3Dhttps%253A%252F%252Ftraffic.example.com%252Ftest%253Fname%" + "253Dadmin%2526level%253Dtrace%26nonce%3D1234567890000000"}, {Http::Headers::get().Host.get(), "traffic.example.com"}, {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Get}, {Http::Headers::get().Scheme.get(), "https"}, @@ -1353,98 +1495,102 @@ TEST_F(OAuth2Test, OAuthTestFullFlowPostWithParametersFillRefreshAndIdToken) { * Expected behavior: Cookie domain should be set to the domain in the config. */ TEST_F(OAuth2Test, OAuthTestFullFlowPostWithCookieDomain) { - { - TestScopedRuntime scoped_runtime; - scoped_runtime.mergeValues({ - {"envoy.reloadable_features.hmac_base64_encoding_only", "true"}, - }); - init(getConfig(true, false, - ::envoy::extensions::filters::http::oauth2::v3::OAuth2Config_AuthType:: - OAuth2Config_AuthType_URL_ENCODED_BODY, - 0, false, false, true /* set_cookie_domain */)); - // First construct the initial request to the oauth filter with URI parameters. - Http::TestRequestHeaderMapImpl first_request_headers{ - {Http::Headers::get().Path.get(), "/test?name=admin&level=trace"}, - {Http::Headers::get().Host.get(), "traffic.example.com"}, - {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Post}, - {Http::Headers::get().Scheme.get(), "https"}, - }; + // Set SystemTime to a fixed point so we get consistent nonce between test runs. + test_time_.setSystemTime(SystemTime(std::chrono::seconds(123456789))); - // This is the immediate response - a redirect to the auth cluster. - Http::TestResponseHeaderMapImpl first_response_headers{ - {Http::Headers::get().Status.get(), "302"}, - {Http::Headers::get().Location.get(), - "https://auth.example.com/oauth/" - "authorize/?client_id=" + - TEST_CLIENT_ID + - "&redirect_uri=https%3A%2F%2Ftraffic.example.com%2F_oauth" - "&response_type=code" - "&scope=" + - TEST_ENCODED_AUTH_SCOPES + - "&state=https%3A%2F%2Ftraffic.example.com%2Ftest%3Fname%3Dadmin%26level%3Dtrace" - "&resource=oauth2-resource&resource=http%3A%2F%2Fexample.com" - "&resource=https%3A%2F%2Fexample.com%2Fsome%2Fpath%252F..%252F%2Futf8%C3%83%3Bfoo%" - "3Dbar%" - "3Fvar1%3D1%26var2%3D2"}, - }; + TestScopedRuntime scoped_runtime; + scoped_runtime.mergeValues({ + {"envoy.reloadable_features.hmac_base64_encoding_only", "true"}, + }); + init(getConfig(true, false, + ::envoy::extensions::filters::http::oauth2::v3::OAuth2Config_AuthType:: + OAuth2Config_AuthType_URL_ENCODED_BODY, + 0, false, false, true /* set_cookie_domain */)); + // First construct the initial request to the oauth filter with URI parameters. + Http::TestRequestHeaderMapImpl first_request_headers{ + {Http::Headers::get().Path.get(), "/test?name=admin&level=trace"}, + {Http::Headers::get().Host.get(), "traffic.example.com"}, + {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Post}, + {Http::Headers::get().Scheme.get(), "https"}, + }; - // Fail the validation to trigger the OAuth flow. - EXPECT_CALL(*validator_, setParams(_, _)); - EXPECT_CALL(*validator_, isValid()).WillOnce(Return(false)); + // This is the immediate response - a redirect to the auth cluster. + Http::TestResponseHeaderMapImpl first_response_headers{ + {Http::Headers::get().Status.get(), "302"}, + {Http::Headers::get().SetCookie.get(), + "OauthNonce=1234567890000000;domain=example.com;path=/;Max-Age=600;secure;HttpOnly"}, + {Http::Headers::get().Location.get(), + "https://auth.example.com/oauth/" + "authorize/?client_id=" + + TEST_CLIENT_ID + + "&redirect_uri=https%3A%2F%2Ftraffic.example.com%2F_oauth" + "&response_type=code" + "&scope=" + + TEST_ENCODED_AUTH_SCOPES + + "&state=url%3Dhttps%253A%252F%252Ftraffic.example.com%252Ftest%253Fname%253Dadmin%" + "2526level%253Dtrace%26nonce%3D1234567890000000" + "&resource=oauth2-resource&resource=http%3A%2F%2Fexample.com" + "&resource=https%3A%2F%2Fexample.com%2Fsome%2Fpath%252F..%252F%2Futf8%C3%83%3Bfoo%" + "3Dbar%" + "3Fvar1%3D1%26var2%3D2"}, + }; - // Check that the redirect includes URL encoded query parameter characters. - EXPECT_CALL(decoder_callbacks_, - encodeHeaders_(HeaderMapEqualRef(&first_response_headers), true)); + // Fail the validation to trigger the OAuth flow. + EXPECT_CALL(*validator_, setParams(_, _)); + EXPECT_CALL(*validator_, isValid()).WillOnce(Return(false)); - // This represents the beginning of the OAuth filter. - EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, - filter_->decodeHeaders(first_request_headers, false)); + // Check that the redirect includes URL encoded query parameter characters. + EXPECT_CALL(decoder_callbacks_, encodeHeaders_(HeaderMapEqualRef(&first_response_headers), true)); - // This represents the callback request from the authorization server. - Http::TestRequestHeaderMapImpl second_request_headers{ - {Http::Headers::get().Path.get(), - "/_oauth?code=123&state=https%3A%2F%2Ftraffic.example.com%" - "2Ftest%3Fname%3Dadmin%26level%3Dtrace"}, - {Http::Headers::get().Host.get(), "traffic.example.com"}, - {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Get}, - {Http::Headers::get().Scheme.get(), "https"}, - }; - // Deliberately fail the HMAC validation check. - EXPECT_CALL(*validator_, setParams(_, _)); - EXPECT_CALL(*validator_, isValid()).WillOnce(Return(false)); + // This represents the beginning of the OAuth filter. + EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, + filter_->decodeHeaders(first_request_headers, false)); - EXPECT_CALL(*oauth_client_, - asyncGetAccessToken("123", TEST_CLIENT_ID, "asdf_client_secret_fdsa", - "https://traffic.example.com" + TEST_CALLBACK, - AuthType::UrlEncodedBody)); + // This represents the callback request from the authorization server. + Http::TestRequestHeaderMapImpl second_request_headers{ + {Http::Headers::get().Cookie.get(), + "OauthNonce=1234567890000000;domain=example.com;path=/;Max-Age=600;secure;HttpOnly"}, + {Http::Headers::get().Path.get(), + "/_oauth?code=123&state=url%3Dhttps%253A%252F%252Ftraffic.example.com%252Ftest%253Fname%" + "253Dadmin%2526level%253Dtrace%26nonce%3D1234567890000000"}, + {Http::Headers::get().Host.get(), "traffic.example.com"}, + {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Get}, + {Http::Headers::get().Scheme.get(), "https"}, + }; + // Deliberately fail the HMAC validation check. + EXPECT_CALL(*validator_, setParams(_, _)); + EXPECT_CALL(*validator_, isValid()).WillOnce(Return(false)); - // Invoke the callback logic. As a side effect, state_ will be populated. - EXPECT_EQ(Http::FilterHeadersStatus::StopAllIterationAndBuffer, - filter_->decodeHeaders(second_request_headers, false)); + EXPECT_CALL(*oauth_client_, asyncGetAccessToken("123", TEST_CLIENT_ID, "asdf_client_secret_fdsa", + "https://traffic.example.com" + TEST_CALLBACK, + AuthType::UrlEncodedBody)); - EXPECT_EQ(1, config_->stats().oauth_unauthorized_rq_.value()); - EXPECT_EQ(config_->clusterName(), "auth.example.com"); + // Invoke the callback logic. As a side effect, state_ will be populated. + EXPECT_EQ(Http::FilterHeadersStatus::StopAllIterationAndBuffer, + filter_->decodeHeaders(second_request_headers, false)); - // Expected response after the callback & validation is complete - verifying we kept the - // state and method of the original request, including the query string parameters. - Http::TestRequestHeaderMapImpl second_response_headers{ - {Http::Headers::get().Status.get(), "302"}, - {Http::Headers::get().SetCookie.get(), - "OauthHMAC=aPoIhN7QYMrYc9nTGCCWgd3rJpZIEdjOtxPDdmVDS6E=;" - "domain=example.com;path=/;Max-Age=;secure;HttpOnly"}, - {Http::Headers::get().SetCookie.get(), - "OauthExpires=;domain=example.com;path=/;Max-Age=;secure;HttpOnly"}, - {Http::Headers::get().SetCookie.get(), - "BearerToken=;domain=example.com;path=/;Max-Age=;secure;HttpOnly"}, - {Http::Headers::get().Location.get(), - "https://traffic.example.com/test?name=admin&level=trace"}, - }; + EXPECT_EQ(1, config_->stats().oauth_unauthorized_rq_.value()); + EXPECT_EQ(config_->clusterName(), "auth.example.com"); + + // Expected response after the callback & validation is complete - verifying we kept the + // state and method of the original request, including the query string parameters. + Http::TestRequestHeaderMapImpl second_response_headers{ + {Http::Headers::get().Status.get(), "302"}, + {Http::Headers::get().SetCookie.get(), + "OauthHMAC=aPoIhN7QYMrYc9nTGCCWgd3rJpZIEdjOtxPDdmVDS6E=;" + "domain=example.com;path=/;Max-Age=;secure;HttpOnly"}, + {Http::Headers::get().SetCookie.get(), + "OauthExpires=;domain=example.com;path=/;Max-Age=;secure;HttpOnly"}, + {Http::Headers::get().SetCookie.get(), + "BearerToken=;domain=example.com;path=/;Max-Age=;secure;HttpOnly"}, + {Http::Headers::get().Location.get(), + "https://traffic.example.com/test?name=admin&level=trace"}, + }; - EXPECT_CALL(decoder_callbacks_, - encodeHeaders_(HeaderMapEqualRef(&second_response_headers), true)); + EXPECT_CALL(decoder_callbacks_, + encodeHeaders_(HeaderMapEqualRef(&second_response_headers), true)); - filter_->finishGetAccessTokenFlow(); - } + filter_->finishGetAccessTokenFlow(); } class DisabledIdTokenTests : public OAuth2Test { @@ -2020,7 +2166,9 @@ TEST_F(OAuth2Test, CookieValidatorInTransition) { auto cookie_validator = std::make_shared( test_time_, - CookieNames{"BearerToken", "OauthHMAC", "OauthExpires", "IdToken", "RefreshToken"}, ""); + CookieNames{"BearerToken", "OauthHMAC", "OauthExpires", "IdToken", "RefreshToken", + "OauthNonce"}, + ""); cookie_validator->setParams(request_headers_base64only, "mock-secret"); EXPECT_TRUE(cookie_validator->hmacIsValid()); @@ -2052,6 +2200,9 @@ TEST_F(OAuth2Test, CookieValidatorInTransition) { // - The filter gets a new bearer and refresh tokens via the current refresh token // - The filter continues to handler the request without redirection to the user agent TEST_F(OAuth2Test, OAuthTestFullFlowWithUseRefreshToken) { + // Set SystemTime to a fixed point so we get consistent nonce between test runs. + test_time_.setSystemTime(SystemTime(std::chrono::seconds(123456789))); + init(getConfig(true /* forward_bearer_token */, true /* use_refresh_token */)); // First construct the initial request to the oauth filter with URI parameters. Http::TestRequestHeaderMapImpl first_request_headers{ @@ -2064,6 +2215,8 @@ TEST_F(OAuth2Test, OAuthTestFullFlowWithUseRefreshToken) { // This is the immediate response - a redirect to the auth cluster. Http::TestResponseHeaderMapImpl first_response_headers{ {Http::Headers::get().Status.get(), "302"}, + {Http::Headers::get().SetCookie.get(), + "OauthNonce=1234567890000000;path=/;Max-Age=600;secure;HttpOnly"}, {Http::Headers::get().Location.get(), "https://auth.example.com/oauth/" "authorize/?client_id=" + @@ -2072,7 +2225,8 @@ TEST_F(OAuth2Test, OAuthTestFullFlowWithUseRefreshToken) { "&response_type=code" "&scope=" + TEST_ENCODED_AUTH_SCOPES + - "&state=https%3A%2F%2Ftraffic.example.com%2Ftest%3Fname%3Dadmin%26level%3Dtrace" + "&state=url%3Dhttps%253A%252F%252Ftraffic.example.com%252Ftest%253Fname%253Dadmin%" + "2526level%253Dtrace%26nonce%3D1234567890000000" "&resource=oauth2-resource&resource=http%3A%2F%2Fexample.com" "&resource=https%3A%2F%2Fexample.com%2Fsome%2Fpath%252F..%252F%2Futf8%C3%83%3Bfoo%3Dbar%" "3Fvar1%3D1%26var2%3D2"}, @@ -2093,8 +2247,11 @@ TEST_F(OAuth2Test, OAuthTestFullFlowWithUseRefreshToken) { // This represents the callback request from the authorization server. Http::TestRequestHeaderMapImpl second_request_headers{ - {Http::Headers::get().Path.get(), "/_oauth?code=123&state=https%3A%2F%2Ftraffic.example.com%" - "2Ftest%3Fname%3Dadmin%26level%3Dtrace"}, + {Http::Headers::get().Cookie.get(), + "OauthNonce=1234567890000000;domain=example.com;path=/;Max-Age=600;secure;HttpOnly"}, + {Http::Headers::get().Path.get(), + "/_oauth?code=123&state=url%3Dhttps%253A%252F%252Ftraffic.example.com%252Ftest%253Fname%" + "253Dadmin%2526level%253Dtrace%26nonce%3D1234567890000000"}, {Http::Headers::get().Host.get(), "traffic.example.com"}, {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Get}, {Http::Headers::get().Scheme.get(), "https"}, @@ -2217,6 +2374,8 @@ TEST_F(OAuth2Test, OAuthTestRefreshAccessTokenSuccess) { } TEST_F(OAuth2Test, OAuthTestRefreshAccessTokenFail) { + // Set SystemTime to a fixed point so we get consistent nonce between test runs. + test_time_.setSystemTime(SystemTime(std::chrono::seconds(123456789))); init(getConfig(true /* forward_bearer_token */, true /* use_refresh_token */)); // First construct the initial request to the oauth filter with URI parameters. @@ -2248,6 +2407,8 @@ TEST_F(OAuth2Test, OAuthTestRefreshAccessTokenFail) { Http::TestResponseHeaderMapImpl redirect_response_headers{ {Http::Headers::get().Status.get(), "302"}, + {Http::Headers::get().SetCookie.get(), + "OauthNonce=1234567890000000;path=/;Max-Age=600;secure;HttpOnly"}, {Http::Headers::get().Location.get(), "https://auth.example.com/oauth/" "authorize/?client_id=" + @@ -2256,7 +2417,8 @@ TEST_F(OAuth2Test, OAuthTestRefreshAccessTokenFail) { "&response_type=code" "&scope=" + TEST_ENCODED_AUTH_SCOPES + - "&state=https%3A%2F%2Ftraffic.example.com%2Ftest%3Fname%3Dadmin%26level%3Dtrace" + "&state=url%3Dhttps%253A%252F%252Ftraffic.example.com%252Ftest%253Fname%253Dadmin%" + "2526level%253Dtrace%26nonce%3D1234567890000000" "&resource=oauth2-resource&resource=http%3A%2F%2Fexample.com" "&resource=https%3A%2F%2Fexample.com%2Fsome%2Fpath%252F..%252F%2Futf8%C3%83%3Bfoo%3Dbar%" "3Fvar1%3D1%26var2%3D2"}, diff --git a/test/extensions/filters/http/oauth2/oauth_integration_test.cc b/test/extensions/filters/http/oauth2/oauth_integration_test.cc index 8f74766416..0ee7b5e6eb 100644 --- a/test/extensions/filters/http/oauth2/oauth_integration_test.cc +++ b/test/extensions/filters/http/oauth2/oauth_integration_test.cc @@ -317,11 +317,13 @@ name: oauth Http::TestRequestHeaderMapImpl headers{ {":method", "GET"}, - {":path", "/callback?code=foo&state=http%3A%2F%2Ftraffic.example.com%2Fnot%2F_oauth"}, + {":path", "/callback?code=foo&state=url%3Dhttp%253A%252F%252Ftraffic.example.com%252Fnot%" + "252F_oauth%26nonce%3D1234567890000000"}, {":scheme", "http"}, {"x-forwarded-proto", "http"}, {":authority", "authority"}, - {"authority", "Bearer token"}}; + {"authority", "Bearer token"}, + {"cookie", absl::StrCat(default_cookie_names_.oauth_nonce_, "=1234567890000000")}}; auto encoder_decoder = codec_client_->startRequest(headers); request_encoder_ = &encoder_decoder.first; @@ -348,13 +350,15 @@ name: oauth codec_client_ = makeHttpConnection(lookupPort("http")); Http::TestRequestHeaderMapImpl headersWithCookie{ {":method", "GET"}, - {":path", "/callback?code=foo&state=http%3A%2F%2Ftraffic.example.com%2Fnot%2F_oauth"}, + {":path", "/callback?code=foo&state=url%3Dhttp%253A%252F%252Ftraffic.example.com%252Fnot%" + "252F_oauth%26nonce%3D1234567890000000"}, {":scheme", "http"}, {"x-forwarded-proto", "http"}, {":authority", "authority"}, {"authority", "Bearer token"}, {"cookie", absl::StrCat(default_cookie_names_.oauth_hmac_, "=", hmac)}, {"cookie", absl::StrCat(default_cookie_names_.oauth_expires_, "=", oauth_expires)}, + {"cookie", absl::StrCat(default_cookie_names_.oauth_nonce_, "=1234567890000000")}, }; auto encoder_decoder2 = codec_client_->startRequest(headersWithCookie, true); response = std::move(encoder_decoder2.second); @@ -402,8 +406,8 @@ name: oauth cleanup(); } - const CookieNames default_cookie_names_{"BearerToken", "OauthHMAC", "OauthExpires", "IdToken", - "RefreshToken"}; + const CookieNames default_cookie_names_{"BearerToken", "OauthHMAC", "OauthExpires", + "IdToken", "RefreshToken", "OauthNonce"}; envoy::config::listener::v3::Listener listener_config_; std::string listener_name_{"http"}; FakeHttpConnectionPtr lds_connection_; diff --git a/test/extensions/filters/http/wasm/test_data/BUILD b/test/extensions/filters/http/wasm/test_data/BUILD index c9e28cd8de..3cebdbc4fc 100644 --- a/test/extensions/filters/http/wasm/test_data/BUILD +++ b/test/extensions/filters/http/wasm/test_data/BUILD @@ -129,12 +129,12 @@ envoy_cc_test_library( copts = ["-DNULL_PLUGIN=1"], deps = [ ":test_cc_proto", - "//external:abseil_node_hash_map", "//source/common/common:assert_lib", "//source/common/common:c_smart_ptr_lib", "//source/extensions/common/wasm:wasm_hdr", "//source/extensions/common/wasm:wasm_lib", "//source/extensions/common/wasm/ext:envoy_null_plugin", + "@com_google_absl//absl/container:node_hash_map", "@proxy_wasm_cpp_sdk//contrib:contrib_lib", ], ) diff --git a/test/extensions/filters/network/redis_proxy/proxy_filter_test.cc b/test/extensions/filters/network/redis_proxy/proxy_filter_test.cc index af7b1a37a7..32a1ae2aab 100644 --- a/test/extensions/filters/network/redis_proxy/proxy_filter_test.cc +++ b/test/extensions/filters/network/redis_proxy/proxy_filter_test.cc @@ -1172,19 +1172,21 @@ TEST_F(RedisProxyFilterWithExternalAuthAndExpiration, ExternalAuthPasswordCorrec EXPECT_EQ(Network::FilterStatus::Continue, filter_->onData(fake_data, false)); } -TEST_F(RedisProxyFilterWithExternalAuthAndExpiration, ExternalAuthPasswordCorrectButThenExpires) { +TEST_F(RedisProxyFilterWithExternalAuthAndExpiration, ExternalAuthWithPipelining) { InSequence s; Buffer::OwnedImpl fake_data; - Common::Redis::RespValuePtr request(new Common::Redis::RespValue()); + Common::Redis::RespValuePtr auth_request(new Common::Redis::RespValue()); EXPECT_CALL(*decoder_, decode(Ref(fake_data))).WillOnce(Invoke([&](Buffer::Instance&) -> void { - decoder_callbacks_->onRespValue(std::move(request)); + decoder_callbacks_->onRespValue(std::move(auth_request)); })); - EXPECT_CALL(splitter_, makeRequest_(Ref(*request), _, _, _)) + + // AUTH expectation + EXPECT_CALL(splitter_, makeRequest_(Ref(*auth_request), _, _, _)) .WillOnce(Invoke([&](const Common::Redis::RespValue&, CommandSplitter::SplitCallbacks& callbacks, Event::Dispatcher&, const StreamInfo::StreamInfo&) -> CommandSplitter::SplitRequest* { - EXPECT_FALSE(callbacks.connectionAllowed()); + // External auth expectation. EXPECT_CALL(*external_auth_client_, authenticateExternal(_, _, _, EMPTY_STRING, "password")) .WillOnce(WithArgs<0, 1>( Invoke([&](ExternalAuth::AuthenticateCallback& callback, @@ -1193,51 +1195,44 @@ TEST_F(RedisProxyFilterWithExternalAuthAndExpiration, ExternalAuthPasswordCorrec std::make_unique( ExternalAuth::AuthenticateResponse{}); auth_response->status = ExternalAuth::AuthenticationRequestStatus::Authorized; - auto time = time_source_.systemTime() + std::chrono::hours(1); + auto time = time_source_.systemTime() + std::chrono::hours(12); auth_response->expiration.set_seconds( duration_cast(time.time_since_epoch()).count()); - callback.onAuthenticateExternal(pending_request, std::move(auth_response)); - }))); - Common::Redis::RespValuePtr reply(new Common::Redis::RespValue()); - reply->type(Common::Redis::RespType::SimpleString); - reply->asString() = "OK"; - EXPECT_CALL(*encoder_, encode(Eq(ByRef(*reply)), _)); - EXPECT_CALL(filter_callbacks_.connection_, write(_, _)); - callbacks.onAuth("password"); - // callbacks can be accessed now. - EXPECT_TRUE(filter_->connectionAllowed()); - // but then expiration passes - time_source_.advanceTimeWait(std::chrono::hours(2)); - // and callbacks are not accessible anymore. - EXPECT_FALSE(filter_->connectionAllowed()); - return nullptr; - })); - EXPECT_EQ(Network::FilterStatus::Continue, filter_->onData(fake_data, false)); -} + // Expect that we receive OK from AUTH first + Common::Redis::RespValuePtr reply(new Common::Redis::RespValue()); + reply->type(Common::Redis::RespType::SimpleString); + reply->asString() = "OK"; + EXPECT_CALL(*encoder_, encode(Eq(ByRef(*reply)), _)); + EXPECT_CALL(filter_callbacks_.connection_, write(_, _)); + + // PING expectation, will be processed after AUTH. + Common::Redis::RespValuePtr ping_request(new Common::Redis::RespValue()); + EXPECT_CALL(splitter_, makeRequest_(Ref(*ping_request), _, _, _)) + .WillOnce(Invoke( + [&](const Common::Redis::RespValue&, + CommandSplitter::SplitCallbacks& callbacks, Event::Dispatcher&, + const StreamInfo::StreamInfo&) -> CommandSplitter::SplitRequest* { + // Having connection allowed proves pipelining was respected. + EXPECT_TRUE(filter_->connectionAllowed()); + + Common::Redis::RespValuePtr reply_ping(new Common::Redis::RespValue()); + reply_ping->type(Common::Redis::RespType::SimpleString); + reply_ping->asString() = "PONG"; + EXPECT_CALL(*encoder_, encode(Eq(ByRef(*reply_ping)), _)); + EXPECT_CALL(filter_callbacks_.connection_, write(_, _)); + + callbacks.onResponse(std::move(reply_ping)); + return nullptr; + })); + + // Simulate that before the auth response is received, another command is + // pipelined. + decoder_callbacks_->onRespValue(std::move(ping_request)); -TEST_F(RedisProxyFilterWithExternalAuthAndExpiration, ExternalAuthPendingRequest) { - InSequence s; + callback.onAuthenticateExternal(pending_request, std::move(auth_response)); + }))); - Buffer::OwnedImpl fake_data; - Common::Redis::RespValuePtr request(new Common::Redis::RespValue()); - EXPECT_CALL(*decoder_, decode(Ref(fake_data))).WillOnce(Invoke([&](Buffer::Instance&) -> void { - decoder_callbacks_->onRespValue(std::move(request)); - })); - EXPECT_CALL(splitter_, makeRequest_(Ref(*request), _, _, _)) - .WillOnce(Invoke([&](const Common::Redis::RespValue&, - CommandSplitter::SplitCallbacks& callbacks, Event::Dispatcher&, - const StreamInfo::StreamInfo&) -> CommandSplitter::SplitRequest* { - EXPECT_FALSE(callbacks.connectionAllowed()); - EXPECT_CALL(*external_auth_client_, - authenticateExternal(_, _, _, EMPTY_STRING, "password")); - Common::Redis::RespValuePtr reply(new Common::Redis::RespValue()); - reply->type(Common::Redis::RespType::Error); - reply->asString() = "ERR an existing authentication request is pending"; - EXPECT_CALL(*encoder_, encode(Eq(ByRef(*reply)), _)); - EXPECT_CALL(filter_callbacks_.connection_, write(_, _)); - callbacks.onAuth("password"); - // Call again (pending request will cause error) callbacks.onAuth("password"); return nullptr; })); @@ -1245,7 +1240,7 @@ TEST_F(RedisProxyFilterWithExternalAuthAndExpiration, ExternalAuthPendingRequest EXPECT_EQ(Network::FilterStatus::Continue, filter_->onData(fake_data, false)); } -TEST_F(RedisProxyFilterWithExternalAuthAndExpiration, ExternalAuthPendingRequestUsername) { +TEST_F(RedisProxyFilterWithExternalAuthAndExpiration, ExternalAuthPasswordCorrectButThenExpires) { InSequence s; Buffer::OwnedImpl fake_data; @@ -1258,15 +1253,31 @@ TEST_F(RedisProxyFilterWithExternalAuthAndExpiration, ExternalAuthPendingRequest CommandSplitter::SplitCallbacks& callbacks, Event::Dispatcher&, const StreamInfo::StreamInfo&) -> CommandSplitter::SplitRequest* { EXPECT_FALSE(callbacks.connectionAllowed()); - EXPECT_CALL(*external_auth_client_, authenticateExternal(_, _, _, "username", "password")); + EXPECT_CALL(*external_auth_client_, authenticateExternal(_, _, _, EMPTY_STRING, "password")) + .WillOnce(WithArgs<0, 1>( + Invoke([&](ExternalAuth::AuthenticateCallback& callback, + CommandSplitter::SplitCallbacks& pending_request) -> void { + ExternalAuth::AuthenticateResponsePtr auth_response = + std::make_unique( + ExternalAuth::AuthenticateResponse{}); + auth_response->status = ExternalAuth::AuthenticationRequestStatus::Authorized; + auto time = time_source_.systemTime() + std::chrono::hours(1); + auth_response->expiration.set_seconds( + duration_cast(time.time_since_epoch()).count()); + callback.onAuthenticateExternal(pending_request, std::move(auth_response)); + }))); Common::Redis::RespValuePtr reply(new Common::Redis::RespValue()); - reply->type(Common::Redis::RespType::Error); - reply->asString() = "ERR an existing authentication request is pending"; + reply->type(Common::Redis::RespType::SimpleString); + reply->asString() = "OK"; EXPECT_CALL(*encoder_, encode(Eq(ByRef(*reply)), _)); EXPECT_CALL(filter_callbacks_.connection_, write(_, _)); - callbacks.onAuth("username", "password"); - // Call again (pending request will cause error) - callbacks.onAuth("username", "password"); + callbacks.onAuth("password"); + // callbacks can be accessed now. + EXPECT_TRUE(filter_->connectionAllowed()); + // but then expiration passes + time_source_.advanceTimeWait(std::chrono::hours(2)); + // and callbacks are not accessible anymore. + EXPECT_FALSE(filter_->connectionAllowed()); return nullptr; })); diff --git a/test/extensions/filters/network/redis_proxy/redis_proxy_integration_test.cc b/test/extensions/filters/network/redis_proxy/redis_proxy_integration_test.cc index d317d58b23..8b50ef4e66 100644 --- a/test/extensions/filters/network/redis_proxy/redis_proxy_integration_test.cc +++ b/test/extensions/filters/network/redis_proxy/redis_proxy_integration_test.cc @@ -1597,5 +1597,27 @@ TEST_P(RedisProxyWithExternalAuthIntegrationTest, ErrorsUntilCorrectPasswordSent redis_client->close(); } +TEST_P(RedisProxyWithExternalAuthIntegrationTest, ExternalAuthRespectsPipelining) { + initialize(); + + IntegrationTcpClientPtr redis_client = makeTcpConnection(lookupPort("redis_proxy")); + FakeHttpConnectionPtr fake_upstream_external_auth; + + // Send an AUTH command followed immediately by a PING command should return OK and PONG. + proxyRequestStep(makeBulkStringArray({"AUTH", "somepassword"}), redis_client); + FakeStreamPtr auth_request; + expectExternalAuthRequest(fake_upstream_external_auth, auth_request, "somepassword"); + auto expiration_time = timeSystem().systemTime() + std::chrono::hours(1); + // PING is sent before the response to the AUTH command is received. + proxyRequestStep(makeBulkStringArray({"PING"}), redis_client); + sendExternalAuthResponse( + auth_request, true, + duration_cast(expiration_time.time_since_epoch()).count()); + proxyResponseOnlyStep("+OK\r\n+PONG\r\n", redis_client); + + EXPECT_TRUE(fake_upstream_external_auth->close()); + redis_client->close(); +} + } // namespace } // namespace Envoy diff --git a/test/extensions/filters/network/wasm/test_data/BUILD b/test/extensions/filters/network/wasm/test_data/BUILD index ba975cbba2..7095acc432 100644 --- a/test/extensions/filters/network/wasm/test_data/BUILD +++ b/test/extensions/filters/network/wasm/test_data/BUILD @@ -55,11 +55,11 @@ envoy_cc_test_library( ], copts = ["-DNULL_PLUGIN=1"], deps = [ - "//external:abseil_node_hash_map", "//source/common/common:assert_lib", "//source/common/common:c_smart_ptr_lib", "//source/extensions/common/wasm:wasm_hdr", "//source/extensions/common/wasm:wasm_lib", + "@com_google_absl//absl/container:node_hash_map", ], ) diff --git a/test/extensions/geoip_providers/maxmind/geoip_provider_test.cc b/test/extensions/geoip_providers/maxmind/geoip_provider_test.cc index 6d3e8961d8..14bb461843 100644 --- a/test/extensions/geoip_providers/maxmind/geoip_provider_test.cc +++ b/test/extensions/geoip_providers/maxmind/geoip_provider_test.cc @@ -94,7 +94,6 @@ class GeoipProviderTestBase { Registry::FactoryRegistry::getFactory( "envoy.geoip_providers.maxmind")); ASSERT(provider_factory_); - on_changed_cbs_.reserve(1); } ~GeoipProviderTestBase() { @@ -116,6 +115,7 @@ class GeoipProviderTestBase { Filesystem::Watcher::OnChangedCb cb) { { absl::WriterMutexLock lock(&mutex_); + on_changed_cbs_.reserve(1); on_changed_cbs_.emplace_back(std::move(cb)); } if (conditional.has_value()) { diff --git a/test/extensions/network/dns_resolver/apple/BUILD b/test/extensions/network/dns_resolver/apple/BUILD index 8f0aa1689d..ba3373879d 100644 --- a/test/extensions/network/dns_resolver/apple/BUILD +++ b/test/extensions/network/dns_resolver/apple/BUILD @@ -14,7 +14,6 @@ envoy_cc_test( "//bazel:apple": ["apple_dns_impl_test.cc"], "//conditions:default": [], }), - external_deps = ["abseil_synchronization"], deps = [ "//envoy/event:dispatcher_interface", "//envoy/event:file_event_interface", @@ -30,6 +29,7 @@ envoy_cc_test( "//test/test_common:network_utility_lib", "//test/test_common:threadsafe_singleton_injector_lib", "//test/test_common:utility_lib", + "@com_google_absl//absl/synchronization", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ] + select({ "//bazel:apple": [ diff --git a/test/extensions/resource_monitors/cpu_utilization/BUILD b/test/extensions/resource_monitors/cpu_utilization/BUILD index 22d752a5f0..b20bff2da8 100644 --- a/test/extensions/resource_monitors/cpu_utilization/BUILD +++ b/test/extensions/resource_monitors/cpu_utilization/BUILD @@ -15,11 +15,11 @@ envoy_extension_cc_test( name = "cpu_utilization_monitor_test", srcs = ["cpu_utilization_monitor_test.cc"], extension_names = ["envoy.resource_monitors.cpu_utilization"], - external_deps = ["abseil_optional"], tags = ["skip_on_windows"], deps = [ "//source/extensions/resource_monitors/cpu_utilization:cpu_utilization_monitor", "//source/extensions/resource_monitors/cpu_utilization:linux_cpu_stats_reader", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/extensions/resource_monitors/cpu_utilization/v3:pkg_cc_proto", ], ) @@ -28,11 +28,11 @@ envoy_extension_cc_test( name = "linux_cpu_stats_reader_test", srcs = ["linux_cpu_stats_reader_test.cc"], extension_names = ["envoy.resource_monitors.cpu_utilization"], - external_deps = ["abseil_optional"], tags = ["skip_on_windows"], deps = [ "//source/extensions/resource_monitors/cpu_utilization:linux_cpu_stats_reader", "//test/test_common:environment_lib", + "@com_google_absl//absl/types:optional", ], ) diff --git a/test/extensions/resource_monitors/downstream_connections/BUILD b/test/extensions/resource_monitors/downstream_connections/BUILD index e6f9535d0a..8b8c603df9 100644 --- a/test/extensions/resource_monitors/downstream_connections/BUILD +++ b/test/extensions/resource_monitors/downstream_connections/BUILD @@ -16,9 +16,9 @@ envoy_extension_cc_test( name = "downstream_connections_monitor_test", srcs = ["downstream_connections_monitor_test.cc"], extension_names = ["envoy.resource_monitors.global_downstream_max_connections"], - external_deps = ["abseil_optional"], deps = [ "//source/extensions/resource_monitors/downstream_connections:downstream_connections_monitor", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/extensions/resource_monitors/downstream_connections/v3:pkg_cc_proto", ], ) diff --git a/test/extensions/resource_monitors/fixed_heap/BUILD b/test/extensions/resource_monitors/fixed_heap/BUILD index 47d8d0c324..7bd5295841 100644 --- a/test/extensions/resource_monitors/fixed_heap/BUILD +++ b/test/extensions/resource_monitors/fixed_heap/BUILD @@ -15,9 +15,9 @@ envoy_extension_cc_test( name = "fixed_heap_monitor_test", srcs = ["fixed_heap_monitor_test.cc"], extension_names = ["envoy.resource_monitors.fixed_heap"], - external_deps = ["abseil_optional"], deps = [ "//source/extensions/resource_monitors/fixed_heap:fixed_heap_monitor", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/extensions/resource_monitors/fixed_heap/v3:pkg_cc_proto", ], ) diff --git a/test/extensions/stats_sinks/wasm/BUILD b/test/extensions/stats_sinks/wasm/BUILD index 9ad8c633cf..eca515eebf 100644 --- a/test/extensions/stats_sinks/wasm/BUILD +++ b/test/extensions/stats_sinks/wasm/BUILD @@ -39,7 +39,6 @@ envoy_extension_cc_test( "//test/extensions/stats_sinks/wasm/test_data:test_context_cpp.wasm", ]), extension_names = ["envoy.stat_sinks.wasm"], - external_deps = ["abseil_optional"], tags = ["skip_on_windows"], deps = [ "//source/common/stats:stats_lib", @@ -49,5 +48,6 @@ envoy_extension_cc_test( "//test/extensions/stats_sinks/wasm/test_data:test_context_cpp_plugin", "//test/mocks/stats:stats_mocks", "//test/test_common:wasm_lib", + "@com_google_absl//absl/types:optional", ], ) diff --git a/test/extensions/tracers/opentelemetry/BUILD b/test/extensions/tracers/opentelemetry/BUILD index c336cc9119..8aa5bb003b 100644 --- a/test/extensions/tracers/opentelemetry/BUILD +++ b/test/extensions/tracers/opentelemetry/BUILD @@ -23,7 +23,6 @@ envoy_extension_cc_test( ], extension_names = ["envoy.tracers.opentelemetry"], external_deps = [ - "abseil_optional", "opentelemetry_api", ], deps = [ @@ -49,6 +48,7 @@ envoy_extension_cc_test( "//test/mocks/upstream:thread_local_cluster_mocks", "//test/test_common:simulated_time_system_lib", "//test/test_common:utility_lib", + "@com_google_absl//absl/types:optional", ], ) diff --git a/test/extensions/tracers/zipkin/BUILD b/test/extensions/tracers/zipkin/BUILD index 68e5a6d8aa..f83810b16c 100644 --- a/test/extensions/tracers/zipkin/BUILD +++ b/test/extensions/tracers/zipkin/BUILD @@ -21,7 +21,6 @@ envoy_extension_cc_test( "zipkin_tracer_impl_test.cc", ], extension_names = ["envoy.tracers.zipkin"], - external_deps = ["abseil_optional"], deps = [ "//envoy/common:time_interface", "//envoy/runtime:runtime_interface", @@ -44,6 +43,7 @@ envoy_extension_cc_test( "//test/mocks/upstream:thread_local_cluster_mocks", "//test/test_common:simulated_time_system_lib", "//test/test_common:utility_lib", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/config/trace/v3:pkg_cc_proto", ], ) diff --git a/test/extensions/transport_sockets/http_11_proxy/connect_integration_test.cc b/test/extensions/transport_sockets/http_11_proxy/connect_integration_test.cc index 826f711b63..37ecf34ad0 100644 --- a/test/extensions/transport_sockets/http_11_proxy/connect_integration_test.cc +++ b/test/extensions/transport_sockets/http_11_proxy/connect_integration_test.cc @@ -124,8 +124,9 @@ name: envoy.clusters.dynamic_forward_proxy // Strip the CONNECT upgrade. std::string prefix_data; const std::string hostname(default_request_headers_.getHostValue()); + const std::string port = Http::HeaderUtility::hostHasPort(hostname) ? "" : ":443"; ASSERT_TRUE(fake_upstream_connection_->waitForInexactRawData("\r\n\r\n", &prefix_data)); - EXPECT_EQ(absl::StrCat("CONNECT ", hostname, ":443 HTTP/1.1\r\n\r\n"), prefix_data); + EXPECT_EQ(absl::StrCat("CONNECT ", hostname, port, " HTTP/1.1\r\n\r\n"), prefix_data); absl::string_view content_length = include_content_length ? "Content-Length: 0\r\n" : ""; // Ship the CONNECT response. @@ -510,5 +511,33 @@ TEST_P(Http11ConnectHttpIntegrationTest, DfpWithProxyAddressLegacy) { EXPECT_EQ("503", response->headers().getStatusValue()); } +TEST_P(Http11ConnectHttpIntegrationTest, HostWithPort) { + initialize(); + + absl::string_view second_upstream_address(fake_upstreams_[1]->localAddress()->asStringView()); + codec_client_ = makeHttpConnection(lookupPort("http")); + // The connect-proxy header will be stripped by the header-to-proxy-filter and inserted as + // metadata. + default_request_headers_.setCopy(Envoy::Http::LowerCaseString("connect-proxy"), + second_upstream_address); + default_request_headers_.setHost("sni.lyft.com:443"); + auto response = codec_client_->makeHeaderOnlyRequest(default_request_headers_); + + ASSERT_TRUE(fake_upstreams_[1]->waitForHttpConnection(*dispatcher_, fake_upstream_connection_)); + + stripConnectUpgradeAndRespond(); + + // Enable reading on the new stream, and read the encapsulated request. + ASSERT_TRUE(fake_upstream_connection_->readDisable(false)); + ASSERT_TRUE(fake_upstream_connection_->waitForNewStream(*dispatcher_, upstream_request_)); + ASSERT_TRUE(upstream_request_->waitForEndStream(*dispatcher_)); + + upstream_request_->encodeHeaders(default_response_headers_, true); + + // Wait for the encapsulated response to be received. + ASSERT_TRUE(response->waitForEndStream()); + EXPECT_EQ("200", response->headers().getStatusValue()); +} + } // namespace } // namespace Envoy diff --git a/test/extensions/transport_sockets/http_11_proxy/connect_test.cc b/test/extensions/transport_sockets/http_11_proxy/connect_test.cc index 816a5db8a8..e6b9c3a1ae 100644 --- a/test/extensions/transport_sockets/http_11_proxy/connect_test.cc +++ b/test/extensions/transport_sockets/http_11_proxy/connect_test.cc @@ -39,10 +39,12 @@ class Http11ConnectTest : public testing::TestWithParam target_port = {}) { + initializeInternal(no_proxy_protocol, false, target_port); + } // Initialize the test with the proxy address provided via endpoint metadata. - void initializeWithMetadataProxyAddr() { initializeInternal(false, true); } + void initializeWithMetadataProxyAddr() { initializeInternal(false, true, {}); } void setAddress() { std::string address_string = @@ -86,13 +88,15 @@ class Http11ConnectTest : public testing::TestWithParam>()}; private: - void initializeInternal(bool no_proxy_protocol, bool use_metadata_proxy_addr) { + void initializeInternal(bool no_proxy_protocol, bool use_metadata_proxy_addr, + absl::optional target_port) { std::string address_string = absl::StrCat(Network::Test::getLoopbackAddressUrlString(GetParam()), ":1234"); Network::Address::InstanceConstSharedPtr address = Network::Utility::parseInternetAddressAndPortNoThrow(address_string); - const std::string proxy_info_hostname = "www.foo.com"; + const std::string port = target_port.has_value() ? absl::StrCat(":", *target_port) : ""; + const std::string proxy_info_hostname = absl::StrCat("www.foo.com", port); auto host = std::make_shared>(); std::unique_ptr info; @@ -144,6 +148,19 @@ TEST_P(Http11ConnectTest, InjectsHeaderOnlyOnceTransportSocketOpts) { injectHeaderOnceTest(); } +TEST_P(Http11ConnectTest, HostWithPort) { + initialize(false, 443); + injectHeaderOnceTest(); +} + +TEST_P(Http11ConnectTest, ProxySslPortRuntimeGuardDisabled) { + TestScopedRuntime scoped_runtime; + scoped_runtime.mergeValues({{"envoy.reloadable_features.proxy_ssl_port", "false"}}); + + initialize(); + injectHeaderOnceTest(); +} + // Test injects CONNECT only once. Configured via endpoint metadata. TEST_P(Http11ConnectTest, InjectsHeaderOnlyOnceEndpointMetadata) { initializeWithMetadataProxyAddr(); diff --git a/test/extensions/watchdog/profile_action/BUILD b/test/extensions/watchdog/profile_action/BUILD index 18b1f5f938..ccf98b33d2 100644 --- a/test/extensions/watchdog/profile_action/BUILD +++ b/test/extensions/watchdog/profile_action/BUILD @@ -15,9 +15,6 @@ envoy_extension_cc_test( name = "profile_action_test", srcs = ["profile_action_test.cc"], extension_names = ["envoy.watchdog.profile_action"], - external_deps = [ - "abseil_synchronization", - ], deps = [ "//envoy/common:time_interface", "//envoy/registry", @@ -31,6 +28,7 @@ envoy_extension_cc_test( "//test/test_common:environment_lib", "//test/test_common:simulated_time_system_lib", "//test/test_common:utility_lib", + "@com_google_absl//absl/synchronization", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/watchdog/profile_action/v3:pkg_cc_proto", ], diff --git a/test/fuzz/BUILD b/test/fuzz/BUILD index 8a613fd72f..4de7a506c7 100644 --- a/test/fuzz/BUILD +++ b/test/fuzz/BUILD @@ -26,9 +26,6 @@ exports_files(["headers.dict"]) envoy_cc_test_library( name = "main", srcs = ["main.cc"], - external_deps = [ - "abseil_symbolize", - ], deps = [ ":fuzz_runner_lib", "//source/common/common:assert_lib", @@ -37,6 +34,7 @@ envoy_cc_test_library( "//test:test_listener_lib", "//test/test_common:environment_lib", "//test/test_common:utility_lib", + "@com_google_absl//absl/synchronization", ] + envoy_select_signal_trace(["//source/common/signal:sigaction_lib"]), ) diff --git a/test/integration/BUILD b/test/integration/BUILD index fdfa59a6cf..2de4af651c 100644 --- a/test/integration/BUILD +++ b/test/integration/BUILD @@ -343,9 +343,6 @@ exports_files(["test_utility.sh"]) envoy_cc_test_binary( name = "hotrestart_main", srcs = ["hotrestart_main.cc"], - external_deps = [ - "abseil_symbolize", - ], deps = [ ":common_extensions_lib", "//source/common/http:rds_lib", @@ -359,15 +356,13 @@ envoy_cc_test_binary( "//source/extensions/load_balancing_policies/ring_hash:config", "//source/extensions/load_balancing_policies/round_robin:config", "//source/extensions/transport_sockets/tls:config", + "@com_google_absl//absl/debugging:symbolize", ], ) envoy_cc_test_binary( name = "hotrestart_small_main", srcs = ["hotrestart_main.cc"], - external_deps = [ - "abseil_symbolize", - ], linkstatic = envoy_select_linkstatic(), deps = [ ":common_extensions_lib", @@ -377,6 +372,7 @@ envoy_cc_test_binary( "//source/exe:stripped_main_base_lib", "//source/extensions/listener_managers/validation_listener_manager:validation_listener_manager_lib", "//source/extensions/transport_sockets/tls:config", + "@com_google_absl//absl/debugging:symbolize", ], ) @@ -2614,7 +2610,6 @@ envoy_cc_test( srcs = envoy_select_admin_functionality([ "xds_delegate_extension_integration_test.cc", ]), - external_deps = ["abseil_strings"], tags = [ "cpu:3", ], @@ -2625,6 +2620,7 @@ envoy_cc_test( "//test/common/grpc:grpc_client_integration_lib", "//test/config:v2_link_hacks", "//test/test_common:registry_lib", + "@com_google_absl//absl/strings", "@envoy_api//envoy/service/discovery/v3:pkg_cc_proto", "@envoy_api//envoy/service/runtime/v3:pkg_cc_proto", ], @@ -2639,7 +2635,6 @@ envoy_cc_test( name = "xds_config_tracker_integration_test", size = "large", srcs = ["xds_config_tracker_integration_test.cc"], - external_deps = ["abseil_strings"], tags = [ "cpu:3", ], @@ -2652,6 +2647,7 @@ envoy_cc_test( "//test/common/grpc:grpc_client_integration_lib", "//test/config:v2_link_hacks", "//test/test_common:registry_lib", + "@com_google_absl//absl/strings", "@envoy_api//envoy/config/route/v3:pkg_cc_proto", "@envoy_api//envoy/service/discovery/v3:pkg_cc_proto", "@envoy_api//envoy/service/runtime/v3:pkg_cc_proto", diff --git a/test/integration/admin_html/BUILD b/test/integration/admin_html/BUILD index bf4e9b8aa8..e633f407db 100644 --- a/test/integration/admin_html/BUILD +++ b/test/integration/admin_html/BUILD @@ -13,9 +13,6 @@ envoy_package() envoy_cc_test_binary( name = "test_server", srcs = ["test_server.cc"], - external_deps = [ - "abseil_symbolize", - ], deps = [ "//source/common/formatter:formatter_extension_lib", "//source/exe:envoy_main_common_with_core_extensions_lib", @@ -23,6 +20,7 @@ envoy_cc_test_binary( "//source/extensions/clusters/logical_dns:logical_dns_cluster_lib", "//source/extensions/clusters/static:static_cluster_lib", "//source/server/admin:admin_html_util", + "@com_google_absl//absl/debugging:symbolize", ], ) diff --git a/test/integration/filters/BUILD b/test/integration/filters/BUILD index dfebb8f118..35e062867d 100644 --- a/test/integration/filters/BUILD +++ b/test/integration/filters/BUILD @@ -129,7 +129,6 @@ envoy_cc_test_library( hdrs = [ "tee_filter.h", ], - external_deps = ["abseil_synchronization"], deps = [ "//envoy/http:filter_interface", "//envoy/registry", @@ -139,6 +138,7 @@ envoy_cc_test_library( "//source/common/http:header_map_lib", "//source/extensions/filters/http/common:pass_through_filter_lib", "//test/extensions/filters/http/common:empty_http_filter_config_lib", + "@com_google_absl//absl/synchronization", ], ) diff --git a/test/integration/load_stats_integration_test.cc b/test/integration/load_stats_integration_test.cc index e98aa4b752..9f9fad52f6 100644 --- a/test/integration/load_stats_integration_test.cc +++ b/test/integration/load_stats_integration_test.cc @@ -6,6 +6,8 @@ #include "envoy/config/endpoint/v3/load_report.pb.h" #include "envoy/service/load_stats/v3/lrs.pb.h" +#include "source/common/common/base64.h" + #include "test/config/utility.h" #include "test/integration/http_integration.h" #include "test/test_common/network_utility.h" @@ -317,7 +319,8 @@ class LoadStatsIntegrationTest : public Grpc::GrpcClientIntegrationParamTest, return testing::AssertionSuccess(); } - void waitForUpstreamResponse(uint32_t endpoint_index, uint32_t response_code = 200) { + void waitForUpstreamResponse(uint32_t endpoint_index, uint32_t response_code = 200, + bool send_orca_load_report = false) { AssertionResult result = service_upstream_[endpoint_index]->waitForHttpConnection( *dispatcher_, fake_upstream_connection_); RELEASE_ASSERT(result, result.message()); @@ -326,8 +329,19 @@ class LoadStatsIntegrationTest : public Grpc::GrpcClientIntegrationParamTest, result = upstream_request_->waitForEndStream(*dispatcher_); RELEASE_ASSERT(result, result.message()); - upstream_request_->encodeHeaders( - Http::TestResponseHeaderMapImpl{{":status", std::to_string(response_code)}}, false); + Http::TestResponseHeaderMapImpl response_headers = {{":status", std::to_string(response_code)}}; + if (send_orca_load_report) { + // Send three metrics, one of which is not in the config. + xds::data::orca::v3::OrcaLoadReport orca_load_report; + orca_load_report.set_cpu_utilization(0.3); + orca_load_report.mutable_named_metrics()->insert({"not-in-config", 0.1}); + orca_load_report.mutable_named_metrics()->insert({"foo", 0.6}); + std::string proto_string = TestUtility::getProtobufBinaryStringFromMessage(orca_load_report); + std::string orca_load_report_header_bin = + Envoy::Base64::encode(proto_string.c_str(), proto_string.length()); + response_headers.addCopy("endpoint-load-metrics-bin", orca_load_report_header_bin); + } + upstream_request_->encodeHeaders(response_headers, false); upstream_request_->encodeData(response_size_, true); ASSERT_TRUE(response_->waitForEndStream()); @@ -372,6 +386,31 @@ class LoadStatsIntegrationTest : public Grpc::GrpcClientIntegrationParamTest, return locality_stats; } + envoy::config::endpoint::v3::UpstreamLocalityStats + addExpectedCustomMetrics(envoy::config::endpoint::v3::UpstreamLocalityStats locality_stats, + uint64_t num_requests_with_metric) { + { + auto* load_metric_stats = locality_stats.add_load_metric_stats(); + load_metric_stats->set_metric_name("cpu_utilization"); + load_metric_stats->set_num_requests_finished_with_metric(num_requests_with_metric); + load_metric_stats->set_total_metric_value(num_requests_with_metric * 0.3); + } + { + auto* load_metric_stats = locality_stats.add_load_metric_stats(); + load_metric_stats->set_metric_name("named_metrics.foo"); + load_metric_stats->set_num_requests_finished_with_metric(num_requests_with_metric); + load_metric_stats->set_total_metric_value(num_requests_with_metric * 0.6); + } + return locality_stats; + } + + envoy::config::endpoint::v3::UpstreamLocalityStats + localityStatsWithCustomMetrics(const std::string& sub_zone, uint64_t success, uint64_t error, + uint64_t active, uint64_t issued, uint32_t priority = 0) { + return addExpectedCustomMetrics( + localityStats(sub_zone, success, error, active, issued, priority), issued); + } + void cleanupLoadStatsConnection() { if (fake_loadstats_connection_ != nullptr) { AssertionResult result = fake_loadstats_connection_->close(); @@ -381,9 +420,10 @@ class LoadStatsIntegrationTest : public Grpc::GrpcClientIntegrationParamTest, } } - void sendAndReceiveUpstream(uint32_t endpoint_index, uint32_t response_code = 200) { + void sendAndReceiveUpstream(uint32_t endpoint_index, uint32_t response_code = 200, + bool send_orca_load_report = false) { initiateClientConnection(); - waitForUpstreamResponse(endpoint_index, response_code); + waitForUpstreamResponse(endpoint_index, response_code, send_orca_load_report); cleanupUpstreamAndDownstream(); } @@ -703,5 +743,169 @@ TEST_P(LoadStatsIntegrationTest, DropOverloadDropped) { cleanupLoadStatsConnection(); } +// Validate the load reports with custom metrics for successful requests as cluster membership +// changes. +TEST_P(LoadStatsIntegrationTest, SuccessWithCustomMetrics) { + config_helper_.addConfigModifier([](envoy::config::bootstrap::v3::Bootstrap& bootstrap) { + auto* cluster_0 = bootstrap.mutable_static_resources()->mutable_clusters(0); + // Add names of endpoint metrics for reporting to LRS. + cluster_0->add_lrs_report_endpoint_metrics("cpu_utilization"); + cluster_0->add_lrs_report_endpoint_metrics("named_metrics.foo"); + }); + initialize(); + + waitForLoadStatsStream(); + ASSERT_TRUE(waitForLoadStatsRequest({})); + loadstats_stream_->startGrpcStream(); + + // Simple 50%/50% split between dragon/winter localities. Also include an + // unknown cluster to exercise the handling of this case. + requestLoadStatsResponse({"cluster_0", "cluster_1"}); + + updateClusterLoadAssignment({{0}}, {{1}}, {{3}}, {}); + + for (uint32_t i = 0; i < 4; ++i) { + sendAndReceiveUpstream(i % 2, 200, true); + } + + // Verify we do not get empty stats for non-zero priorities. + ASSERT_TRUE(waitForLoadStatsRequest({localityStatsWithCustomMetrics("winter", 2, 0, 0, 2), + localityStatsWithCustomMetrics("dragon", 2, 0, 0, 2)})); + + EXPECT_EQ(1, test_server_->counter("load_reporter.requests")->value()); + // On slow machines, more than one load stats response may be pushed while we are simulating load. + EXPECT_LE(2, test_server_->counter("load_reporter.responses")->value()); + EXPECT_EQ(0, test_server_->counter("load_reporter.errors")->value()); + + // 33%/67% split between dragon/winter primary localities. + updateClusterLoadAssignment({{0}}, {{1, 2}}, {}, {{4}}); + // Verify that send_all_clusters works. + requestLoadStatsResponse({}, true); + + for (uint32_t i = 0; i < 6; ++i) { + sendAndReceiveUpstream((4 + i) % 3, 200, true); + } + + // No locality for priority=1 since there's no "winter" endpoints. + // The hosts for dragon were received because membership_total is accurate. + ASSERT_TRUE(waitForLoadStatsRequest({localityStatsWithCustomMetrics("winter", 2, 0, 0, 2), + localityStatsWithCustomMetrics("dragon", 4, 0, 0, 4)})); + + EXPECT_EQ(2, test_server_->counter("load_reporter.requests")->value()); + EXPECT_LE(3, test_server_->counter("load_reporter.responses")->value()); + EXPECT_EQ(0, test_server_->counter("load_reporter.errors")->value()); + + // Change to 50/50 for the failover clusters. + updateClusterLoadAssignment({}, {}, {{3}}, {{4}}); + requestLoadStatsResponse({"cluster_0"}); + test_server_->waitForGaugeEq("cluster.cluster_0.membership_total", 2); + + for (uint32_t i = 0; i < 4; ++i) { + sendAndReceiveUpstream(i % 2 + 3, 200, true); + } + + ASSERT_TRUE(waitForLoadStatsRequest({localityStatsWithCustomMetrics("winter", 2, 0, 0, 2, 1), + localityStatsWithCustomMetrics("dragon", 2, 0, 0, 2, 1)})); + EXPECT_EQ(3, test_server_->counter("load_reporter.requests")->value()); + EXPECT_LE(4, test_server_->counter("load_reporter.responses")->value()); + EXPECT_EQ(0, test_server_->counter("load_reporter.errors")->value()); + + // 100% winter locality. + updateClusterLoadAssignment({}, {}, {}, {}); + updateClusterLoadAssignment({{1}}, {}, {}, {}); + requestLoadStatsResponse({"cluster_0"}); + + for (uint32_t i = 0; i < 1; ++i) { + sendAndReceiveUpstream(1, 200, true); + } + + ASSERT_TRUE(waitForLoadStatsRequest({localityStatsWithCustomMetrics("winter", 1, 0, 0, 1)})); + EXPECT_EQ(4, test_server_->counter("load_reporter.requests")->value()); + EXPECT_LE(5, test_server_->counter("load_reporter.responses")->value()); + EXPECT_EQ(0, test_server_->counter("load_reporter.errors")->value()); + + // A LoadStatsResponse arrives before the expiration of the reporting + // interval. Since we are keep tracking cluster_0, stats rollover. + requestLoadStatsResponse({"cluster_0"}); + sendAndReceiveUpstream(1, 200, true); + requestLoadStatsResponse({"cluster_0"}); + sendAndReceiveUpstream(1, 200, true); + sendAndReceiveUpstream(1, 200, true); + + ASSERT_TRUE(waitForLoadStatsRequest({localityStatsWithCustomMetrics("winter", 3, 0, 0, 3)})); + + EXPECT_EQ(6, test_server_->counter("load_reporter.requests")->value()); + EXPECT_LE(6, test_server_->counter("load_reporter.responses")->value()); + EXPECT_EQ(0, test_server_->counter("load_reporter.errors")->value()); + + cleanupLoadStatsConnection(); +} + +// Validate that the custom metrics are NOT reported if cluster config doesn't have them +// configured. +TEST_P(LoadStatsIntegrationTest, SuccessWithCustomMetricsNotConfigured) { + initialize(); + + waitForLoadStatsStream(); + ASSERT_TRUE(waitForLoadStatsRequest({})); + loadstats_stream_->startGrpcStream(); + + // Simple 50%/50% split between dragon/winter localities. Also include an + // unknown cluster to exercise the handling of this case. + requestLoadStatsResponse({"cluster_0", "cluster_1"}); + + updateClusterLoadAssignment({{0}}, {{1}}, {{3}}, {}); + + for (uint32_t i = 0; i < 4; ++i) { + sendAndReceiveUpstream(i % 2, 200, true); + } + + // Verify we do not get empty stats for non-zero priorities. + ASSERT_TRUE(waitForLoadStatsRequest( + {localityStats("winter", 2, 0, 0, 2), localityStats("dragon", 2, 0, 0, 2)})); + + EXPECT_EQ(1, test_server_->counter("load_reporter.requests")->value()); + // On slow machines, more than one load stats response may be pushed while we are simulating load. + EXPECT_LE(2, test_server_->counter("load_reporter.responses")->value()); + EXPECT_EQ(0, test_server_->counter("load_reporter.errors")->value()); + + cleanupLoadStatsConnection(); +} + +// Validate that load reports are sent if custom metrics are configured but not sent. +TEST_P(LoadStatsIntegrationTest, SuccessWithCustomMetricsNotSent) { + config_helper_.addConfigModifier([](envoy::config::bootstrap::v3::Bootstrap& bootstrap) { + auto* cluster_0 = bootstrap.mutable_static_resources()->mutable_clusters(0); + // Add names of endpoint metrics for reporting to LRS. + cluster_0->add_lrs_report_endpoint_metrics("cpu_utilization"); + cluster_0->add_lrs_report_endpoint_metrics("named_metrics.foo"); + }); + initialize(); + + waitForLoadStatsStream(); + ASSERT_TRUE(waitForLoadStatsRequest({})); + loadstats_stream_->startGrpcStream(); + + // Simple 50%/50% split between dragon/winter localities. Also include an + // unknown cluster to exercise the handling of this case. + requestLoadStatsResponse({"cluster_0", "cluster_1"}); + + updateClusterLoadAssignment({{0}}, {{1}}, {{3}}, {}); + + for (uint32_t i = 0; i < 4; ++i) { + sendAndReceiveUpstream(i % 2); + } + + // Verify we do not get empty stats for non-zero priorities. + ASSERT_TRUE(waitForLoadStatsRequest( + {localityStats("winter", 2, 0, 0, 2), localityStats("dragon", 2, 0, 0, 2)})); + + EXPECT_EQ(1, test_server_->counter("load_reporter.requests")->value()); + // On slow machines, more than one load stats response may be pushed while we are simulating load. + EXPECT_LE(2, test_server_->counter("load_reporter.responses")->value()); + EXPECT_EQ(0, test_server_->counter("load_reporter.errors")->value()); + cleanupLoadStatsConnection(); +} + } // namespace } // namespace Envoy diff --git a/test/integration/quic_protocol_integration_test.cc b/test/integration/quic_protocol_integration_test.cc index 94601c9356..2572976dfb 100644 --- a/test/integration/quic_protocol_integration_test.cc +++ b/test/integration/quic_protocol_integration_test.cc @@ -1,7 +1,63 @@ +#include "source/common/network/socket_option_impl.h" + #include "test/integration/protocol_integration_test.h" namespace Envoy { +// Test that the quiche code can handle packets getting batched together, i.e. +// that it will re-register to read even without incoming packets. +TEST_P(DownstreamProtocolIntegrationTest, BatchedPackets) { + if (downstreamProtocol() != Http::CodecType::HTTP3) { + return; // Testing H3 client talking to H3 upstream only. + } + setUpstreamProtocol(Http::CodecType::HTTP3); + initialize(); + + // Set up the transport factory so the codec client will have credentials to + // talk to the upstream. + quic_transport_socket_factory_ = IntegrationUtil::createQuicUpstreamTransportSocketFactory( + *api_, stats_store_, context_manager_, thread_local_, san_to_match_, + true /*connect to upstream*/); + + // Connect directly to the upstream. + int upstream_port = fake_upstreams_[0]->localAddress()->ip()->port(); + // Make sure the client receive buffer can handle all the packets without loss. + auto options = std::make_shared(); + options->emplace_back(std::make_shared( + envoy::config::core::v3::SocketOption::STATE_PREBIND, + ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_SOCKET, SO_RCVBUF), 1024 * 100)); + + codec_client_ = makeHttpConnection(makeClientConnectionWithOptions(upstream_port, options)); + + // Send a request and a response that can not be handled in one read. + auto response = codec_client_->makeHeaderOnlyRequest(default_request_headers_); + waitForNextUpstreamRequest(); + upstream_request_->encodeHeaders(default_response_headers_, false); + // Send more than the 32 packets. Generally all packets will be read in one pass. + // All packet are sent here where the client is not looping, so can not read. The upstream is + // then deadlocked, guaranteeing all packets are sent to the kernel before the client performs + // any reads. Manual testing confirms they're consistently read at once. There are no guarantees + // of this, but given the test uses loopback sockets it's likely to continue to be the case. + upstream_request_->encodeData(1024 * 35, true); + + // Now deadlock the upstream so it can not do anything - no acks, no + // retransmissions. + absl::Notification unblock_upstream; + absl::Notification upstream_blocked; + fake_upstreams_[0]->runOnDispatcherThread([&] { + upstream_blocked.Notify(); + unblock_upstream.WaitForNotification(); + }); + upstream_blocked.WaitForNotification(); + + // Make sure all the packets are read by the client. + ASSERT_TRUE(response->waitForEndStream()); + EXPECT_TRUE(response->complete()); + // Unblock the upstream. + unblock_upstream.Notify(); + ASSERT_TRUE(fake_upstream_connection_->close()); +} + // These will run with HTTP/3 downstream, and Http upstream. INSTANTIATE_TEST_SUITE_P(DownstreamProtocols, DownstreamProtocolIntegrationTest, testing::ValuesIn(HttpProtocolIntegrationTest::getProtocolTestParams( diff --git a/test/integration/ssl_utility.cc b/test/integration/ssl_utility.cc index 6c48ffdd5c..2ff475cb56 100644 --- a/test/integration/ssl_utility.cc +++ b/test/integration/ssl_utility.cc @@ -25,8 +25,18 @@ namespace Ssl { void initializeUpstreamTlsContextConfig( const ClientSslTransportOptions& options, - envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext& tls_context) { + envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext& tls_context, + bool connect_to_upstream) { const std::string rundir = TestEnvironment::runfilesDirectory(); + if (connect_to_upstream) { + tls_context.mutable_common_tls_context() + ->mutable_validation_context() + ->mutable_trusted_ca() + ->set_filename(rundir + "/test/config/integration/certs/upstreamcacert.pem"); + tls_context.set_sni("foo.lyft.com"); + return; + } + tls_context.mutable_common_tls_context() ->mutable_validation_context() ->mutable_trusted_ca() diff --git a/test/integration/ssl_utility.h b/test/integration/ssl_utility.h index 2c1565fc6c..e6ebdd2b55 100644 --- a/test/integration/ssl_utility.h +++ b/test/integration/ssl_utility.h @@ -81,7 +81,9 @@ struct ClientSslTransportOptions { void initializeUpstreamTlsContextConfig( const ClientSslTransportOptions& options, - envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext& tls_context); + envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext& tls_context, + // By default, clients connect to Envoy. Allow configuring to connect to upstreams. + bool connect_to_upstream = false); Network::UpstreamTransportSocketFactoryPtr createClientSslTransportSocketFactory(const ClientSslTransportOptions& options, diff --git a/test/integration/utility.cc b/test/integration/utility.cc index fcb020cf81..40d3a53363 100644 --- a/test/integration/utility.cc +++ b/test/integration/utility.cc @@ -143,7 +143,8 @@ Network::UpstreamTransportSocketFactoryPtr IntegrationUtil::createQuicUpstreamTransportSocketFactory(Api::Api& api, Stats::Store& store, Ssl::ContextManager& context_manager, ThreadLocal::Instance& threadlocal, - const std::string& san_to_match) { + const std::string& san_to_match, + bool connect_to_upstreams) { NiceMock context; ON_CALL(context.server_context_, api()).WillByDefault(testing::ReturnRef(api)); ON_CALL(context, statsScope()).WillByDefault(testing::ReturnRef(*store.rootScope())); @@ -155,10 +156,11 @@ IntegrationUtil::createQuicUpstreamTransportSocketFactory(Api::Api& api, Stats:: #ifdef ENVOY_ENABLE_YAML initializeUpstreamTlsContextConfig( Ssl::ClientSslTransportOptions().setAlpn(true).setSan(san_to_match).setSni("lyft.com"), - *tls_context); + *tls_context, connect_to_upstreams); #else UNREFERENCED_PARAMETER(tls_context); UNREFERENCED_PARAMETER(san_to_match); + UNREFERENCED_PARAMETER(connect_to_upstreams); RELEASE_ASSERT(0, "unsupported"); #endif // ENVOY_ENABLE_YAML diff --git a/test/integration/utility.h b/test/integration/utility.h index 64e4fbe63a..a86e6d40a6 100644 --- a/test/integration/utility.h +++ b/test/integration/utility.h @@ -208,7 +208,9 @@ class IntegrationUtil { */ static Network::UpstreamTransportSocketFactoryPtr createQuicUpstreamTransportSocketFactory( Api::Api& api, Stats::Store& store, Ssl::ContextManager& context_manager, - ThreadLocal::Instance& threadlocal, const std::string& san_to_match); + ThreadLocal::Instance& threadlocal, const std::string& san_to_match, + // Allow configuring TLS to talk to upstreams instead of Envoy + bool connect_to_fake_upstreams = false); static Http::HeaderValidatorFactoryPtr makeHeaderValidationFactory( const ::envoy::extensions::http::header_validators::envoy_default::v3::HeaderValidatorConfig& diff --git a/test/mocks/grpc/mocks.h b/test/mocks/grpc/mocks.h index d1d41f2111..f0e0b71545 100644 --- a/test/mocks/grpc/mocks.h +++ b/test/mocks/grpc/mocks.h @@ -11,6 +11,7 @@ #include "source/common/grpc/typed_async_client.h" +#include "test/mocks/stream_info/mocks.h" #include "test/test_common/utility.h" #include "gmock/gmock.h" @@ -24,6 +25,7 @@ class MockAsyncRequest : public AsyncRequest { ~MockAsyncRequest() override; MOCK_METHOD(void, cancel, ()); + MOCK_METHOD(const StreamInfo::StreamInfo&, streamInfo, (), (const)); }; class MockAsyncStream : public RawAsyncStream { diff --git a/test/mocks/http/BUILD b/test/mocks/http/BUILD index 7fa206749a..9afca00530 100644 --- a/test/mocks/http/BUILD +++ b/test/mocks/http/BUILD @@ -51,9 +51,6 @@ envoy_cc_mock( name = "http_mocks", srcs = ["mocks.cc"], hdrs = ["mocks.h"], - external_deps = [ - "abseil_strings", - ], deps = [ ":conn_pool_mocks", ":stream_decoder_mock", @@ -76,6 +73,7 @@ envoy_cc_mock( "//test/mocks/stream_info:stream_info_mocks", "//test/mocks/tracing:tracing_mocks", "//test/mocks/upstream:host_mocks", + "@com_google_absl//absl/strings", ], ) diff --git a/test/mocks/runtime/BUILD b/test/mocks/runtime/BUILD index 180056c3d5..87b8a48844 100644 --- a/test/mocks/runtime/BUILD +++ b/test/mocks/runtime/BUILD @@ -12,12 +12,12 @@ envoy_cc_mock( name = "runtime_mocks", srcs = ["mocks.cc"], hdrs = ["mocks.h"], - external_deps = ["abseil_optional"], deps = [ "//envoy/runtime:runtime_interface", "//envoy/upstream:cluster_manager_interface", "//test/mocks:common_lib", "//test/mocks/stats:stats_mocks", + "@com_google_absl//absl/types:optional", "@envoy_api//envoy/type/v3:pkg_cc_proto", ], ) diff --git a/test/mocks/thread/mocks.h b/test/mocks/thread/mocks.h index ae6d63935b..b67f16d3d2 100644 --- a/test/mocks/thread/mocks.h +++ b/test/mocks/thread/mocks.h @@ -14,7 +14,7 @@ namespace Thread { class MockThreadFactory : public ThreadFactory { public: MOCK_METHOD(ThreadPtr, createThread, (std::function, OptionsOptConstRef)); - MOCK_METHOD(ThreadId, currentThreadId, ()); + MOCK_METHOD(ThreadId, currentThreadId, (), (const)); }; #if defined(__linux__) || defined(__APPLE__) @@ -23,8 +23,8 @@ class MockPosixThreadFactory : public PosixThreadFactory { MOCK_METHOD(ThreadPtr, createThread, (std::function, OptionsOptConstRef)); MOCK_METHOD(PosixThreadPtr, createThread, (std::function, OptionsOptConstRef, bool crash_on_failure)); - MOCK_METHOD(ThreadId, currentThreadId, ()); - MOCK_METHOD(ThreadId, currentPthreadId, ()); + MOCK_METHOD(ThreadId, currentThreadId, (), (const)); + MOCK_METHOD(ThreadId, currentPthreadId, (), (const)); }; #endif diff --git a/test/per_file_coverage.sh b/test/per_file_coverage.sh index 4a9420f376..eae1d69683 100755 --- a/test/per_file_coverage.sh +++ b/test/per_file_coverage.sh @@ -6,6 +6,7 @@ declare -a KNOWN_LOW_COVERAGE=( "source/common:96.2" "source/common/api:84.5" # flaky due to posix: be careful adjusting "source/common/api/posix:83.8" # flaky (accept failover non-deterministic): be careful adjusting +"source/common/common/posix:96.2" # flaky due to posix: be careful adjusting "source/common/config:96.1" "source/common/crypto:95.5" "source/common/event:95.2" # Emulated edge events guards don't report LCOV @@ -20,6 +21,9 @@ declare -a KNOWN_LOW_COVERAGE=( "source/common/secret:95.4" "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:94.8" +"source/common/tls/cert_validator:94.4" +"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/extensions/common:93.0" #flaky: be careful adjusting @@ -46,9 +50,6 @@ declare -a KNOWN_LOW_COVERAGE=( "source/extensions/tracers/opencensus:94.0" "source/extensions/tracers/zipkin:95.8" "source/extensions/transport_sockets:97.4" -"source/common/tls:94.8" -"source/common/tls/cert_validator:94.4" -"source/common/tls/private_key:88.9" "source/extensions/wasm_runtime/wamr:0.0" # Not enabled in coverage build "source/extensions/wasm_runtime/wasmtime:0.0" # Not enabled in coverage build "source/extensions/watchdog:83.3" # Death tests within extensions diff --git a/test/test_common/BUILD b/test/test_common/BUILD index 61fdf06171..f218ddd510 100644 --- a/test/test_common/BUILD +++ b/test/test_common/BUILD @@ -18,8 +18,6 @@ envoy_cc_test_library( srcs = ["environment.cc"], hdrs = ["environment.h"], external_deps = [ - "abseil_optional", - "abseil_symbolize", "bazel_runfiles", ], deps = [ @@ -33,6 +31,8 @@ envoy_cc_test_library( "//source/common/json:json_loader_lib", "//source/common/network:utility_lib", "//source/server:options_base", + "@com_google_absl//absl/debugging:symbolize", + "@com_google_absl//absl/types:optional", ] + envoy_select_signal_trace(["//source/common/signal:sigaction_lib"]) + envoy_select_enable_exceptions([ "//source/server:options_lib", ]), @@ -126,9 +126,6 @@ envoy_cc_test_library( name = "utility_lib", srcs = ["utility.cc"], hdrs = ["utility.h"], - external_deps = [ - "abseil_strings", - ], deps = [ ":file_system_for_test_lib", ":logging_lib", @@ -158,6 +155,7 @@ envoy_cc_test_library( "//source/common/protobuf:utility_lib", "//source/common/stats:stats_lib", "//test/mocks/stats:stats_mocks", + "@com_google_absl//absl/strings", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/config/cluster/v3:pkg_cc_proto", "@envoy_api//envoy/config/endpoint/v3:pkg_cc_proto", diff --git a/tools/type_whisperer/proto_build_targets_gen.py b/tools/type_whisperer/proto_build_targets_gen.py index f0b26f1779..947ea22015 100644 --- a/tools/type_whisperer/proto_build_targets_gen.py +++ b/tools/type_whisperer/proto_build_targets_gen.py @@ -63,6 +63,7 @@ visibility = ["//visibility:public"], deps = [ "@com_github_cncf_xds//xds/core/v3:pkg", + "@com_github_cncf_xds//xds/data/orca/v3:pkg", "@com_github_cncf_xds//xds/type/matcher/v3:pkg", "@com_github_cncf_xds//xds/type/v3:pkg", ],