Compare commits

...

240 Commits

Author SHA1 Message Date
katelyn martin e8cc4ec47b
nit(app): remove frivolous code (#4094)
this commit removes a piece of code that has been commented out.

it additionally removes a variable binding that is not needed. `dst` is
not moved, so we do not need to bind the address of the destination
service to a variable, nor do we need to clone it.

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-08-20 11:31:09 -04:00
dependabot[bot] b951a6c374
build(deps): bump tempfile from 3.20.0 to 3.21.0 (#4093)
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.20.0 to 3.21.0.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/commits)

---
updated-dependencies:
- dependency-name: tempfile
  dependency-version: 3.21.0
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-20 10:13:45 -04:00
dependabot[bot] 7f6ac15f13
build(deps): bump cfg-if from 1.0.1 to 1.0.3 (#4092)
Bumps [cfg-if](https://github.com/rust-lang/cfg-if) from 1.0.1 to 1.0.3.
- [Release notes](https://github.com/rust-lang/cfg-if/releases)
- [Changelog](https://github.com/rust-lang/cfg-if/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cfg-if/compare/v1.0.1...v1.0.3)

---
updated-dependencies:
- dependency-name: cfg-if
  dependency-version: 1.0.3
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-20 10:13:04 -04:00
dependabot[bot] 75e9caaeae
build(deps): bump thiserror from 2.0.15 to 2.0.16 (#4091)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 2.0.15 to 2.0.16.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/2.0.15...2.0.16)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-version: 2.0.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-20 10:12:43 -04:00
dependabot[bot] 02bbb3d617
build(deps): bump prettyplease from 0.2.36 to 0.2.37 (#4090)
Bumps [prettyplease](https://github.com/dtolnay/prettyplease) from 0.2.36 to 0.2.37.
- [Release notes](https://github.com/dtolnay/prettyplease/releases)
- [Commits](https://github.com/dtolnay/prettyplease/compare/0.2.36...0.2.37)

---
updated-dependencies:
- dependency-name: prettyplease
  dependency-version: 0.2.37
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-19 15:40:53 -04:00
dependabot[bot] 103c69ca75
build(deps): bump serde_json from 1.0.142 to 1.0.143 (#4088)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.142 to 1.0.143.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.142...v1.0.143)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-version: 1.0.143
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-19 15:40:39 -04:00
dependabot[bot] 4663cc4eb6
build(deps): bump tinyvec from 1.9.0 to 1.10.0 (#4087)
Bumps [tinyvec](https://github.com/Lokathor/tinyvec) from 1.9.0 to 1.10.0.
- [Changelog](https://github.com/Lokathor/tinyvec/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Lokathor/tinyvec/compare/v1.9.0...v1.10.0)

---
updated-dependencies:
- dependency-name: tinyvec
  dependency-version: 1.10.0
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-19 15:40:31 -04:00
dependabot[bot] 03374b9543
build(deps): bump hyper from 1.6.0 to 1.7.0 (#4089)
Bumps [hyper](https://github.com/hyperium/hyper) from 1.6.0 to 1.7.0.
- [Release notes](https://github.com/hyperium/hyper/releases)
- [Changelog](https://github.com/hyperium/hyper/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/hyper/compare/v1.6.0...v1.7.0)

---
updated-dependencies:
- dependency-name: hyper
  dependency-version: 1.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-19 15:40:03 -04:00
Scott Fleener 4c9ae74450 chore(metrics): Use `linkerd-rustls` for crypto provider metrics
Now that the `rustls` initialization/configuration has been decoupled from `linkerd-meshtls`, we can get the provider directly from there. This handles the uninitialized case better, which should be less of a problem now that we always directly initialize the provider in main.

Signed-off-by: Scott Fleener <scott@buoyant.io>
2025-08-19 14:06:32 -04:00
katelyn martin 94572d174d
refactor(http/classify): remove unused classification middleware (#4085)
`NewBroadcastClassification<C, X, N>` is not used.

`BroadcastClassification<C, S>` is only used by the `gate` submodule in
this crate.

this commit removes `NewBroadcastClassification`, since it is unused.
this commit demotes `channel` to an internal submodule, since it has no
external users.

the reëxport of `BroadcastClassification` is unused, though it is left
intact because it _is_ exposed by `NewClassifyGateSet`'s implementation
of `NewService<T>`.

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-08-19 09:33:29 -04:00
katelyn martin 897c7e85bc
refactor(app/core): remove unused `gate` reëxport (#4084)
`linkerd_app_core::classify` reëxports symbols from
`linkerd_proxy_http::classify::gate`.

nothing makes use of this, and these symbols are already reëxported from
`linkerd_proxy_http::classify`. existing callsites in the outbound proxy
import this middleware directly, or though the reëxport in
`linkerd_proxy_http`.

this commit removes this `pub use` directive, since it does nothing.

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-08-18 20:58:18 +00:00
Scott Fleener 036ca75c00
chore(tls): Install default rustls provider in main (#4083)
* chore(tls): Move rustls into dedicated crate

Signed-off-by: Scott Fleener <scott@buoyant.io>

* chore(tls): Remove extraneous provider installs from tests

Signed-off-by: Scott Fleener <scott@buoyant.io>

* chore(tls): Install default rustls provider in main

Signed-off-by: Scott Fleener <scott@buoyant.io>

---------

Signed-off-by: Scott Fleener <scott@buoyant.io>
2025-08-18 19:55:09 +00:00
Scott Fleener 98e731d841
chore(tls): Move `rustls` configuration into dedicated crate (#4082)
* chore(tls): Move rustls into dedicated crate

Signed-off-by: Scott Fleener <scott@buoyant.io>

* chore(tls): Remove extraneous provider installs from tests

Signed-off-by: Scott Fleener <scott@buoyant.io>

---------

Signed-off-by: Scott Fleener <scott@buoyant.io>
2025-08-18 12:48:28 -07:00
Scott Fleener d5b12ea5e2 chore(tls): Hoist rustls directly into linkerd-meshtls
Signed-off-by: Scott Fleener <scott@buoyant.io>
2025-08-18 15:37:05 -04:00
Scott Fleener a64170bd61
chore(tls): Refactor `rustls` shims out of `linkerd-meshtls` (#4080)
* chore(tls): Refactor shims out of meshtls

Meshtls previously assumed that mutliple TLS implementations could be used. Now that we've consolidated on rustls as the TLS implementation, we can remove these shims.

Signed-off-by: Scott Fleener <scott@buoyant.io>

* chore(tls): Refactor mode out of meshtls

Signed-off-by: Scott Fleener <scott@buoyant.io>

---------

Signed-off-by: Scott Fleener <scott@buoyant.io>
2025-08-18 12:27:09 -07:00
katelyn martin 973dfa6f4d
refactor(app/inbound): remove unused `proxy_metrics()` method (#4079)
this commit removes `linkerd_app_inbound::Inbound::proxy_metrics()`.

this accessor is not used anywhere.

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-08-18 14:36:31 -04:00
Scott Fleener 17bff6144a
feat(tls): Explicitly include post-quantum key exchange algorithms (#4070)
* feat(tls): Explicitly include post-quantum key exchange algorithms

This explicitly sets the key exchange algorithms the proxy uses. It adds `X25519MLKEM768` as the most preferred algorithm in non-FIPS mode, and `SECP256R1MLKEM768` in FIPS mode.

Note that `X25519MLKEM768` is still probably appropriate for FIPS environments according to [NIST's special publication 800-56Cr2](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Cr2.pdf) as it performs a FIPS-approved key-establishment first (`MLKEM768`), but we should evaluate this position more before committing to it.

Signed-off-by: Scott Fleener <scott@buoyant.io>
2025-08-18 14:09:34 -04:00
katelyn martin d385094caa
nit(app/inbound): fix `InboundMetrics` doc comment (#4078)
this comment changes this comment in two ways:

1. fix a copy-paste typo. this should say "inbound", not "outbound".
2. add note that this is a "legacy" structure.

the equivalent structure in the outbound proxy was labeled as such
in https://github.com/linkerd/linkerd2-proxy/pull/2887.

see:

```rust
 /// Holds LEGACY outbound proxy metrics.
 #[derive(Clone, Debug)]
 pub struct OutboundMetrics {
     pub(crate) http_errors: error::Http,
     pub(crate) tcp_errors: error::Tcp,

     // pub(crate) http_route_backends: RouteBackendMetrics,
     // pub(crate) grpc_route_backends: RouteBackendMetrics,
     /// Holds metrics that are common to both inbound and outbound proxies. These metrics are
     /// reported separately
     pub(crate) proxy: Proxy,

     pub(crate) prom: PromMetrics,
 }
```

\- <dce6b61191/linkerd/app/outbound/src/metrics.rs (L22-L35)>

`authz::HttpAuthzMetrics`, `error::HttpErrorMetrics`,
`authz::TcpAuthzMetrics`, and `error::TcpErrorMetrics` all make use of
the "legacy" metrics implementation defined in `linkerd_metrics`.

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-08-18 14:01:37 -04:00
dependabot[bot] dce6b61191
build(deps): bump syn from 2.0.105 to 2.0.106 (#4077)
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.105 to 2.0.106.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.105...2.0.106)

---
updated-dependencies:
- dependency-name: syn
  dependency-version: 2.0.106
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-18 12:12:30 -04:00
dependabot[bot] 28ebc47a6b
build(deps): bump cc from 1.2.32 to 1.2.33 (#4076)
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.2.32 to 1.2.33.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.32...cc-v1.2.33)

---
updated-dependencies:
- dependency-name: cc
  dependency-version: 1.2.33
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-18 11:38:09 -04:00
dependabot[bot] 4bae7e98f2
build(deps): bump proc-macro2 from 1.0.97 to 1.0.101 (#4075)
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.97 to 1.0.101.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.97...1.0.101)

---
updated-dependencies:
- dependency-name: proc-macro2
  dependency-version: 1.0.101
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-18 11:37:49 -04:00
dependabot[bot] b89c4902c6
build(deps): bump thiserror from 2.0.14 to 2.0.15 (#4074)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 2.0.14 to 2.0.15.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/2.0.14...2.0.15)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-version: 2.0.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-18 11:26:07 -04:00
dependabot[bot] 8a80f1ce95
build(deps): bump async-trait from 0.1.88 to 0.1.89 (#4073)
Bumps [async-trait](https://github.com/dtolnay/async-trait) from 0.1.88 to 0.1.89.
- [Release notes](https://github.com/dtolnay/async-trait/releases)
- [Commits](https://github.com/dtolnay/async-trait/compare/0.1.88...0.1.89)

---
updated-dependencies:
- dependency-name: async-trait
  dependency-version: 0.1.89
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-18 10:47:36 -04:00
dependabot[bot] edc35d6e18
build(deps): bump derive_arbitrary from 1.4.1 to 1.4.2 (#4072)
Bumps [derive_arbitrary](https://github.com/rust-fuzz/arbitrary) from 1.4.1 to 1.4.2.
- [Changelog](https://github.com/rust-fuzz/arbitrary/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/arbitrary/compare/v1.4.1...v1.4.2)

---
updated-dependencies:
- dependency-name: derive_arbitrary
  dependency-version: 1.4.2
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-18 10:44:51 -04:00
dependabot[bot] 99f322a9a0
build(deps): bump arbitrary from 1.4.1 to 1.4.2 (#4071)
Bumps [arbitrary](https://github.com/rust-fuzz/arbitrary) from 1.4.1 to 1.4.2.
- [Changelog](https://github.com/rust-fuzz/arbitrary/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/arbitrary/compare/v1.4.1...v1.4.2)

---
updated-dependencies:
- dependency-name: arbitrary
  dependency-version: 1.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-18 07:26:46 -07:00
Scott Fleener 627a5aad21
feat(tls): Remove boring as a TLS implementation (#4038)
* chore(tls): Remove ring as crypto backend

The broader ecosystem has mostly moved to aws-lc-rs as the primary rustls backend, and we should follow suit. This will also simplify the maintenance of the proxy's TLS implementation in the long term.

There will need to be some refactoring to clean up the rustls provider interfaces, but that will come in follow-ups.

Signed-off-by: Scott Fleener <scott@buoyant.io>

* feat(tls): Remove boring as a TLS implementation

BoringSSL, as we use it today, doesn't integrate well with the broader rustls ecosystem, so this removes it. This will also simplify the maintenance of the proxy's TLS implementation in the long term.

There will need to be some refactoring to clean up the rustls provider interfaces, but that will come in follow-ups.

Signed-off-by: Scott Fleener <scott@buoyant.io>

* chore(tls): Restore existing aws-lc feature names for compatibility

Signed-off-by: Scott Fleener <scott@buoyant.io>

* fix(tls): Use correct feature name for fips conditionals

Signed-off-by: Scott Fleener <scott@buoyant.io>

---------

Signed-off-by: Scott Fleener <scott@buoyant.io>
2025-08-14 23:27:58 -04:00
Scott Fleener 356f80b786
chore(tls): Improve `aws-lc` usage (#4069)
This adds a few small improvements to how we handle the `aws-lc` usage in the proxy:

- Pull provider customization to the `aws-lc` backend, reducing the amount that the module exposes
- Validate that the provider is actually FIPS compatible when fips is enabled
- Use the same signature verification algorithms in the `rustls` provider as we do in the cert verifier. Previously, the provider also included RSA_PSS_2048_8192_SHA256, which is marked as legacy and we don't have a strong reason to support.
- Add change detector tests for the cipher suites, key exchange groups, and signature algorithms. These should ideally never change unless `rustls` changes, at which point we can re-evaluate which algorithms are in use by the proxy.

Signed-off-by: Scott Fleener <scott@buoyant.io>
2025-08-14 18:56:35 +00:00
dependabot[bot] 0b3bc61263
build(deps): bump hashbrown from 0.15.2 to 0.15.5 (#4068)
Bumps [hashbrown](https://github.com/rust-lang/hashbrown) from 0.15.2 to 0.15.5.
- [Release notes](https://github.com/rust-lang/hashbrown/releases)
- [Changelog](https://github.com/rust-lang/hashbrown/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/hashbrown/commits/v0.15.5)

---
updated-dependencies:
- dependency-name: hashbrown
  dependency-version: 0.15.5
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-14 11:30:16 -04:00
Scott Fleener 2b0e723027
chore(deps): Update tonic deps to 0.13 (#4066)
* chore(deps): Update tonic deps to 0.13

Signed-off-by: Scott Fleener <scott@buoyant.io>

* chore(deps): Update linkerd2-proxy-api to 0.17.0

Signed-off-by: Scott Fleener <scott@buoyant.io>

---------

Signed-off-by: Scott Fleener <scott@buoyant.io>
2025-08-13 10:45:42 -07:00
Scott Fleener 2156c3d5e3
chore(tls): Remove `ring` as `rustls` crypto backend (#4029)
* chore(tls): Remove ring as crypto backend

The broader ecosystem has mostly moved to aws-lc-rs as the primary rustls backend, and we should follow suit. This will also simplify the maintenance of the proxy's TLS implementation in the long term.

There will need to be some refactoring to clean up the rustls provider interfaces, but that will come in follow-ups.

Signed-off-by: Scott Fleener <scott@buoyant.io>

* chore(tls): Restore existing aws-lc feature names for compatibility

Signed-off-by: Scott Fleener <scott@buoyant.io>

* fix(tls): Use correct feature name for fips conditionals

Signed-off-by: Scott Fleener <scott@buoyant.io>

---------

Signed-off-by: Scott Fleener <scott@buoyant.io>
2025-08-13 13:13:57 -04:00
dependabot[bot] c4cae21e11
build(deps): bump syn from 2.0.104 to 2.0.105 (#4067)
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.104 to 2.0.105.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.104...2.0.105)

---
updated-dependencies:
- dependency-name: syn
  dependency-version: 2.0.105
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-13 10:09:16 -07:00
Scott Fleener 89c88caf5c
chore(deps): Manually remove unused dependencies (#4065)
Signed-off-by: Scott Fleener <scott@buoyant.io>
2025-08-13 10:44:43 -04:00
dependabot[bot] bb612d3aac
build(deps): bump the symbolic group with 2 updates (#4063)
Bumps the symbolic group with 2 updates: [symbolic-common](https://github.com/getsentry/symbolic) and [symbolic-demangle](https://github.com/getsentry/symbolic).


Updates `symbolic-common` from 12.16.1 to 12.16.2
- [Release notes](https://github.com/getsentry/symbolic/releases)
- [Changelog](https://github.com/getsentry/symbolic/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/symbolic/compare/12.16.1...12.16.2)

Updates `symbolic-demangle` from 12.16.1 to 12.16.2
- [Release notes](https://github.com/getsentry/symbolic/releases)
- [Changelog](https://github.com/getsentry/symbolic/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/symbolic/compare/12.16.1...12.16.2)

---
updated-dependencies:
- dependency-name: symbolic-common
  dependency-version: 12.16.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: symbolic
- dependency-name: symbolic-demangle
  dependency-version: 12.16.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: symbolic
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 17:18:00 -07:00
dependabot[bot] 7030cc51ed
build(deps): bump anyhow from 1.0.98 to 1.0.99 (#4062)
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.98 to 1.0.99.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.98...1.0.99)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-version: 1.0.99
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 18:39:04 +00:00
dependabot[bot] af520dfd12
build(deps): bump proc-macro2 from 1.0.96 to 1.0.97 (#4061)
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.96 to 1.0.97.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.96...1.0.97)

---
updated-dependencies:
- dependency-name: proc-macro2
  dependency-version: 1.0.97
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 12:33:58 -04:00
dependabot[bot] ccf91dfb3e
build(deps): bump actions/checkout from 4.3.0 to 5.0.0 (#4060)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.3.0 to 5.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](08eba0b27e...08c6903cd8)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 16:18:00 +00:00
dependabot[bot] 69cd164da1
build(deps): bump thiserror from 2.0.12 to 2.0.14 (#4059)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 2.0.12 to 2.0.14.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/2.0.12...2.0.14)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-version: 2.0.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 15:56:38 +00:00
dependabot[bot] feb5f87713
build(deps): bump libc from 0.2.174 to 0.2.175 (#4057)
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.174 to 0.2.175.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.175/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.174...0.2.175)

---
updated-dependencies:
- dependency-name: libc
  dependency-version: 0.2.175
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-11 12:14:04 -04:00
dependabot[bot] fdd7f218a3
build(deps): bump actions/checkout from 4.2.2 to 4.3.0 (#4053)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.2 to 4.3.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](11bd71901b...08eba0b27e)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 4.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-11 11:06:10 -04:00
dependabot[bot] b4e2b7e24f
build(deps): bump glob from 0.3.2 to 0.3.3 (#4055)
Bumps [glob](https://github.com/rust-lang/glob) from 0.3.2 to 0.3.3.
- [Release notes](https://github.com/rust-lang/glob/releases)
- [Changelog](https://github.com/rust-lang/glob/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/glob/compare/v0.3.2...v0.3.3)

---
updated-dependencies:
- dependency-name: glob
  dependency-version: 0.3.3
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-11 11:05:55 -04:00
dependabot[bot] 1b07f277d7
build(deps): bump rustversion from 1.0.21 to 1.0.22 (#4056)
Bumps [rustversion](https://github.com/dtolnay/rustversion) from 1.0.21 to 1.0.22.
- [Release notes](https://github.com/dtolnay/rustversion/releases)
- [Commits](https://github.com/dtolnay/rustversion/compare/1.0.21...1.0.22)

---
updated-dependencies:
- dependency-name: rustversion
  dependency-version: 1.0.22
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-11 11:05:34 -04:00
dependabot[bot] 25cf0c7f11
build(deps): bump proc-macro2 from 1.0.95 to 1.0.96 (#4054)
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.95 to 1.0.96.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.95...1.0.96)

---
updated-dependencies:
- dependency-name: proc-macro2
  dependency-version: 1.0.96
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-11 14:52:05 +00:00
dependabot[bot] d46e7c0c82
build(deps): bump cc from 1.2.31 to 1.2.32 (#4051)
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.2.31 to 1.2.32.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.31...cc-v1.2.32)

---
updated-dependencies:
- dependency-name: cc
  dependency-version: 1.2.32
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-08 13:28:21 -04:00
dependabot[bot] 3305a890b0
build(deps): bump slab from 0.4.10 to 0.4.11 (#4052)
Bumps [slab](https://github.com/tokio-rs/slab) from 0.4.10 to 0.4.11.
- [Release notes](https://github.com/tokio-rs/slab/releases)
- [Changelog](https://github.com/tokio-rs/slab/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/slab/compare/v0.4.10...v0.4.11)

---
updated-dependencies:
- dependency-name: slab
  dependency-version: 0.4.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-08 13:28:01 -04:00
katelyn martin d850fa6f73
refactor(metrics): introduce a `legacy` namespace (#4050)
`linkerd-metrics` contains a suite of facilities for defining,
registering, and serving Prometheus metrics. these predate the
[`prometheus-client`](https://crates.io/crates/prometheus-client/)
crate, which should now be used for our metrics.

`linkerd-metrics` defines a `prom` namespace, which reëxports symbols
from the `prometheus-client` library. as the documentation comment for
this submodule notes, this should be used for all new metrics.

6b323d8457/linkerd/metrics/src/lib.rs (L30-L60)

`linkerd-metrics` still provides its legacy types in the public surface
of this library today, which can make it difficult to differentiate
between our two metrics implementations.

this branch introduces a new `legacy` namespace, to help clarify the
distinction between these two Prometheus implementations, and to smooth
the road to further adoption of `prometheus-client` interfaces across
the proxy.

---

* refactor(metrics): introduce empty `legacy` namespace

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor: move `Counter` into `legacy` namespace

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor: move `Gauge` into `legacy` namespace

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor: move `Histogram` into `legacy` namespace

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor: move `Metric` into `legacy` namespace

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor: move `FmtMetric` into `legacy` namespace

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor: move `FmtMetrics` into `legacy` namespace

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor: move `FmtLabels` into `legacy` namespace

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor: move `LastUpdate` into `legacy` namespace

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor: move `Store` into `legacy` namespace

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor: move `SharedStore` into `legacy` namespace

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor: move `Serve` into `legacy` namespace

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor: move `NewMetrics` into `legacy` namespace

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor: move `Factor` into `legacy` namespace

Signed-off-by: katelyn martin <kate@buoyant.io>

---------

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-08-07 15:33:17 -04:00
dependabot[bot] 6b323d8457
build(deps): bump governor from 0.10.0 to 0.10.1 (#4049)
Bumps [governor](https://github.com/boinkor-net/governor) from 0.10.0 to 0.10.1.
- [Release notes](https://github.com/boinkor-net/governor/releases)
- [Changelog](https://github.com/boinkor-net/governor/blob/master/release.toml)
- [Commits](https://github.com/boinkor-net/governor/compare/v0.10.0...v0.10.1)

---
updated-dependencies:
- dependency-name: governor
  dependency-version: 0.10.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-07 10:37:18 -04:00
dependabot[bot] 7f58cd56ed
build(deps): bump tokio-metrics from 0.4.3 to 0.4.4 (#4048)
Bumps [tokio-metrics](https://github.com/tokio-rs/tokio-metrics) from 0.4.3 to 0.4.4.
- [Release notes](https://github.com/tokio-rs/tokio-metrics/releases)
- [Changelog](https://github.com/tokio-rs/tokio-metrics/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/tokio-metrics/commits)

---
updated-dependencies:
- dependency-name: tokio-metrics
  dependency-version: 0.4.4
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-07 10:37:00 -04:00
Scott Fleener 43e3f630ec feat(tls): Include rustls crypto provider metrics
This includes a small set of metrics about the currently installed rustls crypto provider and the algorithms it is configured to use.

We don't have 100% assurance that a default crypto provider has been installed before registering the metric, but in local testing it never appeared to be a problem. When we refactor the rustls initialization we can add an extra guarantee that we've initialized it by this point.

Example metric:
```
# HELP rustls_info Proxy TLS info.
# TYPE rustls_info gauge
rustls_info{tls_suites="TLS13_AES_128_GCM_SHA256,TLS13_AES_256_GCM_SHA384,TLS13_CHACHA20_POLY1305_SHA256,",tls_kx_groups="X25519,secp256r1,secp384r1,X25519MLKEM768,",tls_rand="AwsLcRs",tls_key_provider="AwsLcRs",tls_fips="false"} 1
```

Signed-off-by: Scott Fleener <scott@buoyant.io>
2025-08-07 10:01:07 -04:00
Oliver Gould 7758436831
chore(ci): exercise all release platforms on workflow change (#4047)
We only build linux/amd64 during typical release CI runs. This means that the platform-
specific builds are not exercised. This change updates the release workflow so that
all platforms are built whenever the workflow itself is changed.
2025-08-06 14:29:05 +00:00
dependabot[bot] c0f921af33
build(deps): bump zerovec from 0.11.3 to 0.11.4 (#4046)
Bumps [zerovec](https://github.com/unicode-org/icu4x) from 0.11.3 to 0.11.4.
- [Release notes](https://github.com/unicode-org/icu4x/releases)
- [Changelog](https://github.com/unicode-org/icu4x/blob/main/CHANGELOG.md)
- [Commits](https://github.com/unicode-org/icu4x/compare/ind/zerovec@0.11.3...ind/zerovec@0.11.4)

---
updated-dependencies:
- dependency-name: zerovec
  dependency-version: 0.11.4
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-06 09:48:31 -04:00
Scott Fleener b558ce5320
chore(meshtls-rustls): use aws-lc as the default crypto backend (#4043)
The broader ecosystem has mostly moved to `aws-lc-rs` as the primary `rustls` backend, and we should follow suit. This will also simplify the maintenance of the proxy's TLS implementation in the long term.

This requires some extra configuration for successful cross-compilation, ideally we can remove this extra configuration once linkerd/dev v48 is available.

This doesn't remove `ring` as a crypto backend, that can come in a follow-up at https://github.com/linkerd/linkerd2-proxy/pull/4029
2025-08-05 13:22:26 -07:00
dependabot[bot] 894d3506df
build(deps): bump socket2 from 0.5.10 to 0.6.0 (#4003)
* build(deps): bump socket2 from 0.5.10 to 0.6.0

Bumps [socket2](https://github.com/rust-lang/socket2) from 0.5.10 to 0.6.0.
- [Release notes](https://github.com/rust-lang/socket2/releases)
- [Changelog](https://github.com/rust-lang/socket2/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/socket2/commits)

---
updated-dependencies:
- dependency-name: socket2
  dependency-version: 0.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(proxy/transport): use `original_dst_v*` methods

these have been renamed.

Signed-off-by: katelyn martin <kate@buoyant.io>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: katelyn martin <kate@buoyant.io>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: katelyn martin <kate@buoyant.io>
2025-08-05 13:09:56 -07:00
dependabot[bot] 01e7ec0820
build(deps): bump zerovec from 0.11.2 to 0.11.3 (#4044)
Bumps [zerovec](https://github.com/unicode-org/icu4x) from 0.11.2 to 0.11.3.
- [Release notes](https://github.com/unicode-org/icu4x/releases)
- [Changelog](https://github.com/unicode-org/icu4x/blob/main/CHANGELOG.md)
- [Commits](https://github.com/unicode-org/icu4x/commits/ind/zerovec@0.11.3)

---
updated-dependencies:
- dependency-name: zerovec
  dependency-version: 0.11.3
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-05 13:00:54 -07:00
dependabot[bot] 4f563fab68
build(deps): bump tokio-metrics from 0.4.2 to 0.4.3 (#3995)
Bumps [tokio-metrics](https://github.com/tokio-rs/tokio-metrics) from 0.4.2 to 0.4.3.
- [Release notes](https://github.com/tokio-rs/tokio-metrics/releases)
- [Changelog](https://github.com/tokio-rs/tokio-metrics/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/tokio-metrics/compare/v0.4.2...v0.4.3)

---
updated-dependencies:
- dependency-name: tokio-metrics
  dependency-version: 0.4.3
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-05 07:50:44 -07:00
dependabot[bot] 168c4bff7d
build(deps): bump tokio from 1.45.0 to 1.47.1 (#4040)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.45.0 to 1.47.1.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.45.0...tokio-1.47.1)

---
updated-dependencies:
- dependency-name: tokio
  dependency-version: 1.47.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-05 09:44:53 -04:00
dependabot[bot] 0df8cdbedb
build(deps): bump cc from 1.2.30 to 1.2.31 (#4042)
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.2.30 to 1.2.31.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.30...cc-v1.2.31)

---
updated-dependencies:
- dependency-name: cc
  dependency-version: 1.2.31
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-04 14:59:55 -07:00
dependabot[bot] 1b837b7f91
build(deps): bump tokio-util from 0.7.15 to 0.7.16 (#4041)
Bumps [tokio-util](https://github.com/tokio-rs/tokio) from 0.7.15 to 0.7.16.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-util-0.7.15...tokio-util-0.7.16)

---
updated-dependencies:
- dependency-name: tokio-util
  dependency-version: 0.7.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-04 14:59:00 -07:00
katelyn martin 40078c96ca
chore(deps): update from tokio 1.45 to 1.47 (#4032)
* build(deps): bump tokio from 1.45.0 to 1.47.0

Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.45.0 to 1.47.0.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.45.0...tokio-1.47.0)

---
updated-dependencies:
- dependency-name: tokio
  dependency-version: 1.47.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

---

chore(deny): ignore socket2@v0.5

there is now a v0.6 used by the latest tokio.

while we wait for this new version to propagate through the ecosystem,
allow for two socket2 dependencies.

Signed-off-by: katelyn martin <kate@buoyant.io>

* chore(app/integration): remove inbound_io_err test

> @cratelyn I think it would be appropriate to remove these tests, given
> that they can no longer behave properly. I don't think that this test
> case is particularly meaningful or load bearing, it's best just to
> unblock the dependency updates.

\- <https://github.com/BuoyantIO/enterprise-linkerd/issues/1645#issuecomment-3046905516>

Co-authored-by: Oliver Gould <ver@buoyant.io>
Signed-off-by: katelyn martin <kate@buoyant.io>

* chore(app/integration): remove inbound_multi test

this test exercises the same thing that the previous two tests do, as
the comment at the top of it points out.

this test is redundant, and we have removed the i/o error coverage that
this was redunant with. let's remove it.

Signed-off-by: katelyn martin <kate@buoyant.io>

---------

Signed-off-by: katelyn martin <kate@buoyant.io>
Co-authored-by: Oliver Gould <ver@buoyant.io>
2025-08-04 09:04:02 -07:00
dependabot[bot] 9eaf1425a7
build(deps): bump signal-hook-registry from 1.4.5 to 1.4.6 (#4039)
Bumps [signal-hook-registry](https://github.com/vorner/signal-hook) from 1.4.5 to 1.4.6.
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/signal-hook/compare/registry-v1.4.5...registry-v1.4.6)

---
updated-dependencies:
- dependency-name: signal-hook-registry
  dependency-version: 1.4.6
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-04 08:08:41 -07:00
dependabot[bot] 842452368c
build(deps): bump rustc-demangle from 0.1.25 to 0.1.26 (#4026)
Bumps [rustc-demangle](https://github.com/rust-lang/rustc-demangle) from 0.1.25 to 0.1.26.
- [Release notes](https://github.com/rust-lang/rustc-demangle/releases)
- [Changelog](https://github.com/rust-lang/rustc-demangle/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/rustc-demangle/commits/rustc-demangle-v0.1.26)

---
updated-dependencies:
- dependency-name: rustc-demangle
  dependency-version: 0.1.26
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-04 11:07:17 -04:00
dependabot[bot] 09333dc2b2
build(deps): bump the symbolic group with 2 updates (#4035)
Bumps the symbolic group with 2 updates: [symbolic-common](https://github.com/getsentry/symbolic) and [symbolic-demangle](https://github.com/getsentry/symbolic).


Updates `symbolic-common` from 12.16.0 to 12.16.1
- [Release notes](https://github.com/getsentry/symbolic/releases)
- [Changelog](https://github.com/getsentry/symbolic/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/symbolic/compare/12.16.0...12.16.1)

Updates `symbolic-demangle` from 12.16.0 to 12.16.1
- [Release notes](https://github.com/getsentry/symbolic/releases)
- [Changelog](https://github.com/getsentry/symbolic/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/symbolic/compare/12.16.0...12.16.1)

---
updated-dependencies:
- dependency-name: symbolic-common
  dependency-version: 12.16.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: symbolic
- dependency-name: symbolic-demangle
  dependency-version: 12.16.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: symbolic
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Oliver Gould <ver@buoyant.io>
2025-08-01 18:28:55 +00:00
dependabot[bot] ddc847ccc4
build(deps): bump serde_json from 1.0.141 to 1.0.142 (#4036)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.141 to 1.0.142.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.141...v1.0.142)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-version: 1.0.142
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-01 11:23:49 -07:00
Scott Fleener 8d56746c1f
feat!(ci): Remove arm/v7 support (#4037)
This architecture has become too significant of a maintenance burden, and isn't used often enough to justify the associated maintenance cost.

This removes arm/v7 from all the build infrastructure/dockerfiles/etc. Note that arm64 targets are still widely used and well supported.

Related: https://github.com/linkerd/linkerd2/pull/14308

Signed-off-by: Scott Fleener <scott@buoyant.io>
2025-08-01 13:26:12 -04:00
dependabot[bot] db0ed46978
build(deps): bump rustls from 0.23.29 to 0.23.31 in the rustls group (#4034)
Bumps the rustls group with 1 update: [rustls](https://github.com/rustls/rustls).


Updates `rustls` from 0.23.29 to 0.23.31
- [Release notes](https://github.com/rustls/rustls/releases)
- [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustls/rustls/compare/v/0.23.29...v/0.23.31)

---
updated-dependencies:
- dependency-name: rustls
  dependency-version: 0.23.31
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: rustls
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-31 05:53:48 -07:00
katelyn martin 1d94082d4b
chore(deps): downgrade deranged from 0.4.1 to 0.4.0 (#4031)
- https://crates.io/crates/deranged/versions
- https://crates.io/crates/deranged/0.4.1

this version has been yanked. this commit addresses this cargo deny
warning:

```
warning[yanked]: detected yanked crate (try `cargo update -p deranged`)
   ┌─ /home/katie/linkerd/linkerd2-proxy/Cargo.lock:41:1
   │
41 │ deranged 0.4.1 registry+https://github.com/rust-lang/crates.io-index
   │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ yanked version
   │
```

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-07-29 18:14:11 +00:00
dependabot[bot] 744e29e0bd
build(deps): bump rangemap from 1.5.1 to 1.6.0 (#4028)
Bumps [rangemap](https://github.com/jeffparsons/rangemap) from 1.5.1 to 1.6.0.
- [Changelog](https://github.com/jeffparsons/rangemap/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jeffparsons/rangemap/commits)

---
updated-dependencies:
- dependency-name: rangemap
  dependency-version: 1.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-29 10:59:35 -04:00
katelyn martin 83373d6b89
chore(deps): bump h2 from 0.4.8 to 0.4.11 (#4024)
- https://github.com/hyperium/h2/compare/v0.4.8...v0.4.11

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-07-28 21:23:25 +00:00
Scott Fleener 1dcb7a7d1a
fix(rustls): Make `ring` and `aws-lc-rs` exclusive features (#4009)
Currently, disabling the `ring` feature does not actually disable the dependency across the tree. Doing so requires a couple of tightly coupled steps:

- Making `ring` and `aws-lc` exclusive features, raising a compile error if they are both enabled.
- Removing a direct dependency on some `ring` types, and instead going through `rustls` for equivalent functionality.
- Removing a direct dependency on the `ring` crypto provider for integration tests, and instead using the provider from `linkerd-meshtls`.
- Installing the default crypto provider globally for the process and re-using it when requested, mostly to make the tests pass.

This was tested using a temporary `cargo deny` config that forbid `ring` when `aws-lc-rs` was used, and vice-versa. Note that it doesn't completely remove ring for dev dependencies, but that can be done as a follow-up.

Signed-off-by: Scott Fleener <scott@buoyant.io>
2025-07-28 15:28:47 -04:00
Scott Fleener 68a6b6d1e8
fix(tls): Update preferred cipher suite order (#4015)
This makes two changes to the preferred cipher suite order.
- Prefer AES algorithms over ChaCha20. AES is significantly faster when AES hardware is present, and AES hardware is on all x86 CPUs since ~2010, and all ARM server CPUs for a similar amount of time. For these reasons it's reasonable to default to AES for modern deployments, and it's the same default that `aws-lc-rs` makes anyway.
- Remove ChaCha20 when FIPS is enabled. It's no longer a supported algorithm, so we shouldn't have it as an option.

Signed-off-by: Scott Fleener <scott@buoyant.io>
2025-07-28 15:05:05 -04:00
Oliver Gould cdbb55fd53
build(linkerd2-proxy): make release artifacts auditable (#4023)
Auditing tools like Syft cannot inspect proxy dependencies, which makes it difficult to inspect the state of a binary. This change updates the release process to use cargo-auditable, which documents the proxy's crate dependencies in its release binary.
2025-07-28 17:00:06 +00:00
Oliver Gould 5997453393
build(deps): update linkerd/dev to v47 (#4022) 2025-07-28 11:49:06 -05:00
Joe 10643b9525
updating metrics descriptions (#4020)
Signed-off-by: Joe F <joe@buoyant.io>
2025-07-25 20:08:56 +00:00
dependabot[bot] fd0ea24b87
build(deps): bump serde_json from 1.0.140 to 1.0.141 (#4021)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.140 to 1.0.141.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.140...v1.0.141)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-version: 1.0.141
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-25 16:07:16 -04:00
dependabot[bot] 3a159be91a
build(deps): bump prettyplease from 0.2.35 to 0.2.36 (#4018)
Bumps [prettyplease](https://github.com/dtolnay/prettyplease) from 0.2.35 to 0.2.36.
- [Release notes](https://github.com/dtolnay/prettyplease/releases)
- [Commits](https://github.com/dtolnay/prettyplease/compare/0.2.35...0.2.36)

---
updated-dependencies:
- dependency-name: prettyplease
  dependency-version: 0.2.36
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-24 10:03:57 -04:00
dependabot[bot] b3bc6fe8cd
build(deps): bump hyper-util from 0.1.15 to 0.1.16 (#4019)
Bumps [hyper-util](https://github.com/hyperium/hyper-util) from 0.1.15 to 0.1.16.
- [Release notes](https://github.com/hyperium/hyper-util/releases)
- [Changelog](https://github.com/hyperium/hyper-util/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/hyper-util/compare/v0.1.15...v0.1.16)

---
updated-dependencies:
- dependency-name: hyper-util
  dependency-version: 0.1.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-24 10:02:38 -04:00
dependabot[bot] 5a00b70d11
build(deps): bump aws-lc-rs from 1.13.2 to 1.13.3 (#4016)
Bumps [aws-lc-rs](https://github.com/aws/aws-lc-rs) from 1.13.2 to 1.13.3.
- [Release notes](https://github.com/aws/aws-lc-rs/releases)
- [Commits](https://github.com/aws/aws-lc-rs/compare/v1.13.2...v1.13.3)

---
updated-dependencies:
- dependency-name: aws-lc-rs
  dependency-version: 1.13.3
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-23 07:02:52 -07:00
dependabot[bot] b91dd3e7af
build(deps): bump rcgen from 0.14.2 to 0.14.3 (#4017)
Bumps [rcgen](https://github.com/rustls/rcgen) from 0.14.2 to 0.14.3.
- [Release notes](https://github.com/rustls/rcgen/releases)
- [Commits](https://github.com/rustls/rcgen/compare/v0.14.2...v0.14.3)

---
updated-dependencies:
- dependency-name: rcgen
  dependency-version: 0.14.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-23 07:02:25 -07:00
dependabot[bot] a699b1cf58
build(deps): bump cc from 1.2.29 to 1.2.30 (#4014)
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.2.29 to 1.2.30.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.29...cc-v1.2.30)

---
updated-dependencies:
- dependency-name: cc
  dependency-version: 1.2.30
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-22 09:35:32 -04:00
dependabot[bot] 9f3c45874e
build(deps): bump rand from 0.9.1 to 0.9.2 (#4013)
Bumps [rand](https://github.com/rust-random/rand) from 0.9.1 to 0.9.2.
- [Release notes](https://github.com/rust-random/rand/releases)
- [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/rand/compare/rand_core-0.9.1...rand_core-0.9.2)

---
updated-dependencies:
- dependency-name: rand
  dependency-version: 0.9.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-22 09:35:19 -04:00
Oliver Gould 1de179e178
chore(deps): update jemallocator 0.5 to tikv-jemallocator 0.6 (#4012)
tikv-jemallocator supersedes jemallocator. To enable jemalloc profiling, this change updates the dependency and adds a `jemalloc-profiling` feature so that profiling can be enabled at build time.
2025-07-18 17:42:41 -04:00
dependabot[bot] f9d7e08242
build(deps): bump the rustls group with 2 updates (#4010)
---
updated-dependencies:
- dependency-name: rustls-webpki
  dependency-version: 0.103.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: rustls
- dependency-name: rustls
  dependency-version: 0.23.29
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: rustls
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-18 07:48:31 -07:00
dependabot[bot] bd454b4be8
build(deps): bump the symbolic group with 2 updates (#4011)
---
updated-dependencies:
- dependency-name: symbolic-common
  dependency-version: 12.16.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: symbolic
- dependency-name: symbolic-demangle
  dependency-version: 12.16.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: symbolic
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-18 07:48:06 -07:00
Oliver Gould b1f8fa5419
chore(ci): enable overriding the runner in workflows (#4008)
We use the ubuntu-24.04 runner by default, but in forks this may not be appropriate. This change updates the runners to support overriding via the LINKERD2_PROXY_RUNNER variable.
2025-07-17 17:22:42 -07:00
dependabot[bot] e04947610a
build(deps): bump aws-lc-rs from 1.13.1 to 1.13.2 (#4006)
---
updated-dependencies:
- dependency-name: aws-lc-rs
  dependency-version: 1.13.2
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-17 11:05:10 -07:00
Oliver Gould 9c48e2471e
fix(app/env): limit default inbound connection pool size (#4007)
The inbound connection pool is effectively unlimited. This change configures a
default limit of 10K.
2025-07-17 16:47:32 +00:00
dependabot[bot] df38a5a2c9
build(deps): bump the rustls group across 1 directory with 3 updates (#3908)
* build(deps): bump the rustls group across 1 directory with 3 updates

Bumps the rustls group with 3 updates in the / directory: [rustls-webpki](https://github.com/rustls/webpki), [rustls](https://github.com/rustls/rustls) and [rustls-pki-types](https://github.com/rustls/pki-types).


Updates `rustls-webpki` from 0.103.1 to 0.103.2
- [Release notes](https://github.com/rustls/webpki/releases)
- [Commits](https://github.com/rustls/webpki/compare/v/0.103.1...v/0.103.2)

Updates `rustls` from 0.23.26 to 0.23.27
- [Release notes](https://github.com/rustls/rustls/releases)
- [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustls/rustls/compare/v/0.23.26...v/0.23.27)

Updates `rustls-pki-types` from 1.11.0 to 1.12.0
- [Release notes](https://github.com/rustls/pki-types/releases)
- [Commits](https://github.com/rustls/pki-types/compare/v/1.11.0...v/1.12.0)

---
updated-dependencies:
- dependency-name: rustls-webpki
  dependency-version: 0.103.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: rustls
- dependency-name: rustls
  dependency-version: 0.23.27
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: rustls
- dependency-name: rustls-pki-types
  dependency-version: 1.12.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: rustls
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix(rustls): Remove dependency on most rustls internal types

We only used these types for generating a ClientHello message for testing. Instead, we can manually encode a sample message based on the TLS spec.

Signed-off-by: Scott Fleener <scott@buoyant.io>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Scott Fleener <scott@buoyant.io>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Scott Fleener <scott@buoyant.io>
2025-07-17 16:20:37 +00:00
dependabot[bot] 7c6882bb35
build(deps): bump rcgen from 0.13.2 to 0.14.2 (#4000)
* build(deps): bump rcgen from 0.13.2 to 0.14.2

Bumps [rcgen](https://github.com/rustls/rcgen) from 0.13.2 to 0.14.2.
- [Release notes](https://github.com/rustls/rcgen/releases)
- [Commits](https://github.com/rustls/rcgen/compare/v0.13.2...v0.14.2)

---
updated-dependencies:
- dependency-name: rcgen
  dependency-version: 0.14.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix(test): Fix breaking changes from rcgen 0.14

Signed-off-by: Scott Fleener <scott@buoyant.io>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Scott Fleener <scott@buoyant.io>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Scott Fleener <scott@buoyant.io>
2025-07-16 19:34:47 -04:00
katelyn martin a6e47d7e03
fix(app/env): a lower default maximum per-host connection limit (#4005)
* chore(app/env): fix typo

Signed-off-by: katelyn martin <kate@buoyant.io>

* fix(app/env): a lower default maximum per-host connection limit

see also:
* #4004
* linkerd/linkerd2#14204

in #4004 we fixed an issue related to our HTTP/1.1 client's connection
pool.

this further hedges against future issues related to our HTTP client
exhausting resources available to its container. today, the limit by
default is `usize::MAX`, which is dramatically higher than the practical
limit.

this commit changes the limit for outbound idle connections per-host to
10,000.

Signed-off-by: katelyn martin <kate@buoyant.io>

---------

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-07-15 13:01:54 -04:00
Oliver Gould 2cc8c7d80e
fix(proxy/http): fix HTTP/1 client idle timeouts (#4004)
When constructing the HTTP/1 client, we configure connection pooling, but
notably do not provide a timer implementation to Hyper. This causes hyper's
connection pool to be configured without idle timeouts, which may lead to
resource leaks, especially for clients that communicate with many virtual hosts.

This change updates the HTTP/1 client builder to use a Tokio timer, which allows
Hyper to manage idle timeouts correctly.
2025-07-14 14:56:35 -07:00
dependabot[bot] 21f3ffc6c1
build(deps): bump crc32fast from 1.4.2 to 1.5.0 (#4002)
Bumps [crc32fast](https://github.com/srijs/rust-crc32fast) from 1.4.2 to 1.5.0.
- [Commits](https://github.com/srijs/rust-crc32fast/compare/v1.4.2...v1.5.0)

---
updated-dependencies:
- dependency-name: crc32fast
  dependency-version: 1.5.0
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-14 11:49:32 -04:00
dependabot[bot] 1b85cf93a4
build(deps): bump memmap2 from 0.9.5 to 0.9.7 (#4001)
Bumps [memmap2](https://github.com/RazrFalcon/memmap2-rs) from 0.9.5 to 0.9.7.
- [Changelog](https://github.com/RazrFalcon/memmap2-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/RazrFalcon/memmap2-rs/commits)

---
updated-dependencies:
- dependency-name: memmap2
  dependency-version: 0.9.7
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-14 07:02:56 -07:00
dependabot[bot] ce5df7d026
build(deps): bump cc from 1.2.27 to 1.2.29 (#3999)
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.2.27 to 1.2.29.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.27...cc-v1.2.29)

---
updated-dependencies:
- dependency-name: cc
  dependency-version: 1.2.29
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-11 15:17:08 -04:00
Scott Fleener 79e612c2f9
feat(meshtls): Include AES_256_GCM as a supported ciphersuite (#3991)
This is a strong ciphersuite that's reasonable to include as a supported option. We still prefer CHACHA20_POLY1305 in non-FIPS modes for its speed, as well as keeping CHACHA20_POLY1305 as a backup for older proxies that only support it.

Signed-off-by: Scott Fleener <scott@buoyant.io>
Co-authored-by: Oliver Gould <ver@buoyant.io>
2025-07-10 15:23:47 -04:00
Oliver Gould 62ed64ea05
chore(build): bump linkerd/dev to v46 (#3984)
* Rust 1.88
2025-07-10 14:15:24 -04:00
dependabot[bot] e8de6359a5
build(deps): bump hyper-util from 0.1.14 to 0.1.15 (#3997)
Bumps [hyper-util](https://github.com/hyperium/hyper-util) from 0.1.14 to 0.1.15.
- [Release notes](https://github.com/hyperium/hyper-util/releases)
- [Changelog](https://github.com/hyperium/hyper-util/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/hyper-util/compare/v0.1.14...v0.1.15)

---
updated-dependencies:
- dependency-name: hyper-util
  dependency-version: 0.1.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-10 12:50:50 -04:00
dependabot[bot] 53a17808a7
build(deps): bump libfuzzer-sys from 0.4.9 to 0.4.10 (#3994)
Bumps [libfuzzer-sys](https://github.com/rust-fuzz/libfuzzer) from 0.4.9 to 0.4.10.
- [Changelog](https://github.com/rust-fuzz/libfuzzer/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-fuzz/libfuzzer/compare/0.4.9...0.4.10)

---
updated-dependencies:
- dependency-name: libfuzzer-sys
  dependency-version: 0.4.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-08 09:17:27 -04:00
katelyn martin 34b46ab6cd
refactor: `FmtLabels` impls use exhaustive bindings (#3988)
this is based on #3987.

in #3987 (_see https://github.com/linkerd/linkerd2/issues/13821_) we discovered that some of the types that implement [`FmtLabels`](085be9978d/linkerd/metrics/src/fmt.rs (L5)) could collide when used in registry keys; i.e., they might emit identical label sets, but distinct `Hash` values.

#3987 solves two bugs. this pull request proposes a follow-on change, introducing _exhaustive_ bindings to implementations of `FmtLabels`, to prevent this category of bug from reoccurring again in the future.

this change means that the introduction of an additional field to any of these label structures, e.g. `OutboundEndpointLabels` or `HTTPLocalRateLimitLabels`, will cause a compilation error unless said new field is handled in the corresponding `FmtLabels` implementation.

### 🔖 a note

in writing this pull request, i noticed one label that i believe is unintentionally being elided. i've refrained from changing behavior in this pull request. i do note it though, as an example of this syntax identifying the category of bug i hope to hedge against here.

---

* fix: do not key transport metrics registry on `ClientTls`

Signed-off-by: katelyn martin <kate@buoyant.io>

* fix: do not key transport metrics registry on `ServerTls`

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor(transport-metrics): exhaustive `Eos: FmtLabels`

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor(app/core): exhaustive `ServerLabels: FmtLabels`

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor(app/core): exhaustive `TlsAccept: FmtLabels`

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor(app/core): exhaustive `TargetAddr: FmtLabels`

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor(metrics): exhaustive `Label: FmtLabels`

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor(http/metrics): exhaustive `Status: FmtLabels`

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor(app/core): exhaustive `ControlLabels: FmtLabels`

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor(app/core): exhaustive `ProfileRouteLabels: FmtLabels`

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor(app/core): exhaustive `InboundEndpointLabels: FmtLabels`

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor(app/core): exhaustive `ServerLabel: FmtLabels`

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor(app/core): exhaustive `ServerAuthzLabels: FmtLabels`

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor(app/core): exhaustive `RouteLabels: FmtLabels`

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor(app/core): exhaustive `RouteAuthzLabels: FmtLabels`

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor(app/core): exhaustive `OutboundEndpointLabels: FmtLabels`

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor(app/core): exhaustive `Authority: FmtLabels`

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor(app/core): exhaustive `StackLabels: FmtLabels`

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor(app/inbound): exhaustive `HTTPLocalRateLimitLabels: FmtLabels`

Signed-off-by: katelyn martin <kate@buoyant.io>

* refactor(app/inbound): exhaustive `Key<L>: FmtLabels`

Signed-off-by: katelyn martin <kate@buoyant.io>

* nit(metrics): remove redundant banner comment

these impl blocks are all `FmtLabels`, following another series of the
same, above. we don't need another one of these comments.

Signed-off-by: katelyn martin <kate@buoyant.io>

* nit(metrics): exhaustive `AndThen: FmtMetrics`

Signed-off-by: katelyn martin <kate@buoyant.io>

* nit(app/core): note unused label

see #3262 (618838ec7), which introduced this label.

to preserve behavior, this label remains unused.

X-Ref: #3262
Signed-off-by: katelyn martin <kate@buoyant.io>

---------

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-07-03 11:56:14 -04:00
Oliver Gould 288fc74800
chore(app): increase default max backoff durations (#3992)
The inbound and outbound connect backoffs are now set at 500ms. This is very aggressive in practice, especially when an endpoint remains unavailable.

This change increases the maximum backoff durations:

* inbound: 10s
* outbound: 60s

The default minimum backoff durations remain unchanged at 100ms so that failed
connections are retried quickly. This change only increases the default _maximum_ backoff so that the timeout increases substantially when an endpoint is unavailable for a longer period of time.
2025-07-02 18:52:53 -07:00
katelyn martin 030fa28d55
fix: remove ambiguous metrics registry keys (#3987)
### 🖼️ background

the linkerd2 proxy implements, registers, and exports Prometheus metrics using a variety of systems, for historical reasons. new metrics broadly rely upon the official [`prometheus-client`](https://github.com/prometheus/client_rust/) library, whose interfaces are reexported for internal consumption in the [`linkerd_metrics::prom`](https://github.com/linkerd/linkerd2-proxy/blob/main/linkerd/metrics/src/lib.rs#L30-L60) namespace.

other metrics predate this library however, and rely on the metrics registry implemented in the workspace's [`linkerd-metrics`](https://github.com/linkerd/linkerd2-proxy/tree/main/linkerd/metrics) library.

### 🐛 bug report

* https://github.com/linkerd/linkerd2/issues/13821

linkerd/linkerd2#13821 reported a bug in which duplicate metrics could be observed and subsequently dropped by Prometheus when upgrading the control plane via helm with an existing workload running.

### 🦋 reproduction example

for posterity, i'll note the reproduction steps here.

i used these steps to identify the `2025.3.2` edge release as the affected release. upgrading from `2025.2.3` to `2025.3.1` did not exhibit this behavior. see below for more discussion about the cause.

generate certificates via <https://linkerd.io/2.18/tasks/generate-certificates/>

using these two deployments, courtesy of @GTRekter:

<details>
<summary>**💾 click to expand: app deployment**</summary>

```yaml
apiVersion: v1 
kind: Namespace 
metadata: 
  name: simple-app 
  annotations: 
    linkerd.io/inject: enabled 
---
apiVersion: v1 
kind: Service 
metadata: 
  name: simple-app-v1 
  namespace: simple-app 
spec: 
  selector: 
    app: simple-app-v1 
    version: v1 
  ports: 
    - port: 80 
      targetPort: 5678
---
apiVersion: apps/v1 
kind: Deployment 
metadata: 
  name: simple-app-v1 
  namespace: simple-app 
spec: 
  replicas: 1 
  selector: 
    matchLabels: 
      app: simple-app-v1 
      version: v1 
  template: 
    metadata: 
      labels: 
        app: simple-app-v1 
        version: v1 
    spec: 
      containers: 
        - name: http-app 
          image: hashicorp/http-echo:latest 
          args: 
            - "-text=Simple App v1" 
          ports: 
            - containerPort: 5678 
```
</details>

<details>
<summary>**🤠 click to expand: client deployment**</summary>

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: traffic
  namespace: simple-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: traffic
  template:
    metadata:
      labels:
        app: traffic
    spec:
      containers:
      - name: traffic
        image: curlimages/curl:latest
        command:
          - /bin/sh
          - -c
          - |
            while true; do
              TIMESTAMP_SEND=$(date '+%Y-%m-%d %H:%M:%S')
              PAYLOAD="{\"timestamp\":\"$TIMESTAMP_SEND\",\"test_id\":\"sniff_me\",\"message\":\"hello-world\"}"
              echo "$TIMESTAMP_SEND - Sending payload: $PAYLOAD"
              RESPONSE=$(curl -s -X POST \
                -H "Content-Type: application/json" \
                -d "$PAYLOAD" \
                http://simple-app-v1.simple-app.svc.cluster.local:80)
              TIMESTAMP_RESPONSE=$(date '+%Y-%m-%d %H:%M:%S')
              echo "$TIMESTAMP_RESPONSE - RESPONSE: $RESPONSE"
              sleep 1
            done
```
</details>

and this prometheus configuration:

<details>
<summary>**🔥 click to expand: prometheus configuration**</summary>

```yaml
global:
  scrape_interval: 10s

scrape_configs:
  - job_name: 'pod'
    scrape_interval: 10s
    static_configs:
    - targets: ['localhost:4191']
      labels:
        group: 'traffic'
```
</details>

we will perform the following steps:

```sh
# install the edge release

# specify the versions we'll migrate between.
export FROM="2025.3.1"
export TO="2025.3.2"

# create a cluster, and add the helm charts.
kind create cluster
helm repo add linkerd-edge https://helm.linkerd.io/edge

# install linkerd's crd's and control plane.
helm install linkerd-crds linkerd-edge/linkerd-crds \
  -n linkerd --create-namespace --version $FROM

helm install linkerd-control-plane \
  -n linkerd \
  --set-file identityTrustAnchorsPEM=cert/ca.crt \
  --set-file identity.issuer.tls.crtPEM=cert/issuer.crt \
  --set-file identity.issuer.tls.keyPEM=cert/issuer.key \
  --version $FROM \
  linkerd-edge/linkerd-control-plane

# install a simple app and a client to drive traffic.
kubectl apply -f duplicate-metrics-simple-app.yml
kubectl apply -f duplicate-metrics-traffic.yml

# bind the traffic pod's metrics port to the host.
kubectl port-forward -n simple-app deploy/traffic 4191

# start prometheus, begin scraping metrics
prometheus --config.file=prometheus.yml
```

now, open a browser and query `irate(request_total[1m])`.

next, upgrade the control plane:

```
helm upgrade linkerd-crds linkerd-edge/linkerd-crds \
  -n linkerd --create-namespace --version $TO
helm upgrade linkerd-control-plane \
  -n linkerd \
  --set-file identityTrustAnchorsPEM=cert/ca.crt \
  --set-file identity.issuer.tls.crtPEM=cert/issuer.crt \
  --set-file identity.issuer.tls.keyPEM=cert/issuer.key \
  --version $TO \
  linkerd-edge/linkerd-control-plane
```

prometheus will begin emitting warnings regarding 34 time series being dropped.

in your browser, querying `irate(request_total[1m])` once more will show that
the rate of requests has stopped, due to the new time series being dropped.

next, restart the workloads...

```
kubectl rollout restart deployment -n simple-app simple-app-v1 traffic
```

prometheus warnings will go away, as reported in linkerd/linkerd2#13821.

### 🔍 related changes

* https://github.com/linkerd/linkerd2/pull/13699
* https://github.com/linkerd/linkerd2/pull/13715

in linkerd/linkerd2#13715 and linkerd/linkerd2##13699, we made some changes to the destination controller. from the "Cautions" section of the `2025.3.2` edge release:

> Additionally, this release changes the default for `outbound-transport-mode`
> to `transport-header`, which will result in all traffic between meshed
> proxies flowing on port 4143, rather than using the original destination
> port.

linkerd/linkerd2#13699 (_included in `edge-25.3.1`_) introduced this outbound transport-protocol configuration surface, but maintained the default behavior, while linkerd/linkerd2#13715 (_included in `edge-25.3.2`_) altered the default behavior to route meshed traffic via port 4143.

this is a visible change in behavior that can be observed when upgrading from a version that preceded this change to the mesh. this means that when upgrading across `edge-25.3.2`, such as from the `2025.2.1` to `2025.3.2` versions of the helm charts, or from the `2025.2.3` to the `2025.3.4` versions of the helm charts (_reported upstream in linkerd/linkerd2#13821_), the freshly upgraded destination controller pods will begin routing meshed traffic differently.

i'll state explicitly, _that_ is not a bug! it is, however, an important clue to bear in mind: data plane pods that were started with the previous control plane version, and continue running after the control plane upgrade, will have seen both routing patterns. reporting a duplicate time series for affected metrics indicates that there is a hashing collision in our metrics system.

### 🐛 the bug(s)

we define a collection to structures to model labels for inbound and outbound endpoints'
metrics:

```rust
// linkerd/app/core/src/metrics.rs

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum EndpointLabels {
    Inbound(InboundEndpointLabels),
    Outbound(OutboundEndpointLabels),
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct InboundEndpointLabels {
    pub tls: tls::ConditionalServerTls,
    pub authority: Option<http::uri::Authority>,
    pub target_addr: SocketAddr,
    pub policy: RouteAuthzLabels,
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct OutboundEndpointLabels {
    pub server_id: tls::ConditionalClientTls,
    pub authority: Option<http::uri::Authority>,
    pub labels: Option<String>,
    pub zone_locality: OutboundZoneLocality,
    pub target_addr: SocketAddr,
}
```

\- <https://github.com/linkerd/linkerd2-proxy/blob/main/linkerd/app/core/src/metrics.rs>

bear particular attention to the derived `Hash` implementation. note the `tls::ConditionalClientTls` and `tls::ConditionalServerTls` types used in each of these labels. these are used by some of our types like `TlsConnect` to emit prometheus labels, using our legacy system's `FmtLabels` trait:

```rust
// linkerd/app/core/src/transport/labels.rs

impl FmtLabels for TlsConnect<'_> {
    fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self.0 {
            Conditional::None(tls::NoClientTls::Disabled) => {
                write!(f, "tls=\"disabled\"")
            }
            Conditional::None(why) => {
                write!(f, "tls=\"no_identity\",no_tls_reason=\"{}\"", why)
            }
            Conditional::Some(tls::ClientTls { server_id, .. }) => {
                write!(f, "tls=\"true\",server_id=\"{}\"", server_id)
            }
        }
    }
}
```

\- <99316f7898/linkerd/app/core/src/transport/labels.rs (L151-L165)>

note the `ClientTls` case, which ignores fields in the client tls information:

```rust
// linkerd/tls/src/client.rs

/// A stack parameter that configures a `Client` to establish a TLS connection.
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct ClientTls {
    pub server_name: ServerName,
    pub server_id: ServerId,
    pub alpn: Option<AlpnProtocols>,
}
```

\- <99316f7898/linkerd/tls/src/client.rs (L20-L26)>

this means that there is potential for an identical set of labels to be emitted given two `ClientTls` structures with distinct server names or ALPN protocols. for brevity, i'll elide the equivalent issue with `ServerTls`, and its corresponding `TlsAccept<'_>` label implementation, though it exhibits the same issue.

### 🔨 the fix

this pull request introduces two new types: `ClientTlsLabels` and `ServerTlsLabels`. these continue to implement `Hash`, for use as a key in our metrics registry, and for use in formatting labels.

`ClientTlsLabels` and `ServerTlsLabels` each resemble `ClientTls` and `ServerTls`, respectively, but do not contain any fields that are elided in label formatting, to prevent duplicate metrics from being emitted.

relatedly, #3988 audits our existing `FmtLabels` implementations and makes use of exhaustive bindings, to prevent this category of problem in the short-term future. ideally, we might eventually consider replacing the metrics interfaces in `linkerd-metrics`, but that is strictly kept out-of-scope for the purposes of this particular fix.

---

* fix: do not key transport metrics registry on `ClientTls`

Signed-off-by: katelyn martin <kate@buoyant.io>

* fix: do not key transport metrics registry on `ServerTls`

Signed-off-by: katelyn martin <kate@buoyant.io>

---------

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-07-02 12:38:04 -04:00
dependabot[bot] 085be9978d
build(deps): bump indexmap from 2.9.0 to 2.10.0 (#3986)
Bumps [indexmap](https://github.com/indexmap-rs/indexmap) from 2.9.0 to 2.10.0.
- [Changelog](https://github.com/indexmap-rs/indexmap/blob/main/RELEASES.md)
- [Commits](https://github.com/indexmap-rs/indexmap/compare/2.9.0...2.10.0)

---
updated-dependencies:
- dependency-name: indexmap
  dependency-version: 2.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-27 11:19:12 -04:00
dependabot[bot] 682421c98a
build(deps): bump Swatinem/rust-cache from 2.7.8 to 2.8.0 (#3983)
Bumps [Swatinem/rust-cache](https://github.com/swatinem/rust-cache) from 2.7.8 to 2.8.0.
- [Release notes](https://github.com/swatinem/rust-cache/releases)
- [Changelog](https://github.com/Swatinem/rust-cache/blob/master/CHANGELOG.md)
- [Commits](9d47c6ad4b...98c8021b55)

---
updated-dependencies:
- dependency-name: Swatinem/rust-cache
  dependency-version: 2.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-26 12:25:06 -04:00
katelyn martin 2b1e3925d5
fix(proxy/http): remove http/1 header read timeout (#3985)
this fixes #14131. this relates to #14147, though it does not introduce
a configurable option for this timeout.

 ###  background

in hyper 0.14, http/1.1 connections had no default header read timeout.
per the documentation for
[`hyper::server::Builder::http1_header_read_timeout()`][read-timeout-previous]:

> Set a timeout for reading client request headers. If a client does not
transmit the entire header within this time, the connection is closed.
>
> Default is None.

compare this with the latest hyper release, which enforces a
30 second timeout for http/1.1 connections. per the documentation for
[`hyper::server::conn::http1::Builder::header_read_timeout`][read-timeout-current]:

> Set a timeout for reading client request headers. If a client does not
> transmit the entire header within this time, the connection is closed.
>
> Requires a
> [Timer](https://docs.rs/hyper/latest/hyper/rt/trait.Timer.html) set by
> [Builder::timer](https://docs.rs/hyper/latest/hyper/server/conn/http1/struct.Builder.html#method.timer)
> to take effect. Panics if header_read_timeout is configured without a
> [Timer](https://docs.rs/hyper/latest/hyper/rt/trait.Timer.html).
>
> Pass None to disable.
>
> Default is 30 seconds.

this was changed in hyperium/hyper#3395, which was included in [the v1.0
release][v1-changelog].

[read-timeout-previous]: https://docs.rs/hyper/0.14.31/hyper/server/struct.Builder.html#method.http1_header_read_timeout
[read-timeout-current]: https://docs.rs/hyper/latest/hyper/server/conn/http1/struct.Builder.html#method.header_read_timeout
[v1-changelog]: https://github.com/hyperium/hyper/blob/master/CHANGELOG.md#v100-2023-11-15

 ### 🔨 changes

this commit passes `None` to the `linkerd-proxy-http::server::ServeHttp`
type's http/1 server-side connection builder, to remove the header read
timeout.

this restores the behavior that existed prior to linkerd/linkerd2#8733,
which upgraded our hyper dependency from 0.14 to 1.0.

X-Ref: https://github.com/linkerd/linkerd2/issues/14147
X-Ref: https://github.com/linkerd/linkerd2/issues/14131
X-Ref: https://github.com/linkerd/linkerd2/issues/8733
X-Ref: https://github.com/hyperium/hyper/issues/3395

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-06-26 12:08:38 -04:00
dependabot[bot] 504581e1d7
build(deps): bump bumpalo from 3.18.1 to 3.19.0 (#3982)
Bumps [bumpalo](https://github.com/fitzgen/bumpalo) from 3.18.1 to 3.19.0.
- [Changelog](https://github.com/fitzgen/bumpalo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fitzgen/bumpalo/commits)

---
updated-dependencies:
- dependency-name: bumpalo
  dependency-version: 3.19.0
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-25 08:32:25 -04:00
Zahari Dichev 2869076d58
identity(spire): provide named pipe support for spire (#3970)
This change does two things: 
- adds support for `NamedPipes` to our SPIRE client. This will allow the client to connect to spire agents running on Windows hosts
- renames the `LINKERD2_PROXY_IDENTITY_SPIRE_SOCKET` to `LINKERD2_PROXY_IDENTITY_SPIRE_WORKLOAD_API_ADDRESS` and deprecates the former.

Signed-off-by: Zahari Dichev <zaharidichev@gmail.com>
2025-06-25 11:01:45 +03:00
dependabot[bot] 99316f7898
build(deps): bump prettyplease from 0.2.34 to 0.2.35 (#3981)
Bumps [prettyplease](https://github.com/dtolnay/prettyplease) from 0.2.34 to 0.2.35.
- [Release notes](https://github.com/dtolnay/prettyplease/releases)
- [Commits](https://github.com/dtolnay/prettyplease/compare/0.2.34...0.2.35)

---
updated-dependencies:
- dependency-name: prettyplease
  dependency-version: 0.2.35
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-24 09:17:31 -04:00
dependabot[bot] 7255530037
build(deps): bump syn from 2.0.103 to 2.0.104 (#3980)
---
updated-dependencies:
- dependency-name: syn
  dependency-version: 2.0.104
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-23 08:04:23 -04:00
Oliver Gould 3fe2dee32e
fix(errno): comment typo (#3949) 2025-06-20 15:00:10 +00:00
dependabot[bot] 3590892686
build(deps): bump errno from 0.3.12 to 0.3.13 (#3979)
Bumps [errno](https://github.com/lambda-fairy/rust-errno) from 0.3.12 to 0.3.13.
- [Release notes](https://github.com/lambda-fairy/rust-errno/releases)
- [Changelog](https://github.com/lambda-fairy/rust-errno/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lambda-fairy/rust-errno/compare/v0.3.12...v0.3.13)

---
updated-dependencies:
- dependency-name: errno
  dependency-version: 0.3.13
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-20 10:09:16 -04:00
dependabot[bot] 80a216892d
build(deps): bump syn from 2.0.102 to 2.0.103 (#3978)
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.102 to 2.0.103.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.102...2.0.103)

---
updated-dependencies:
- dependency-name: syn
  dependency-version: 2.0.103
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-20 10:09:07 -04:00
dependabot[bot] 4dc6353d0c
build(deps): bump autocfg from 1.4.0 to 1.5.0 (#3977)
Bumps [autocfg](https://github.com/cuviper/autocfg) from 1.4.0 to 1.5.0.
- [Commits](https://github.com/cuviper/autocfg/compare/1.4.0...1.5.0)

---
updated-dependencies:
- dependency-name: autocfg
  dependency-version: 1.5.0
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-20 09:58:37 -04:00
dependabot[bot] c325f526af
build(deps): bump slab from 0.4.9 to 0.4.10 (#3976)
Bumps [slab](https://github.com/tokio-rs/slab) from 0.4.9 to 0.4.10.
- [Release notes](https://github.com/tokio-rs/slab/releases)
- [Changelog](https://github.com/tokio-rs/slab/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/slab/compare/v0.4.9...v0.4.10)

---
updated-dependencies:
- dependency-name: slab
  dependency-version: 0.4.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-18 07:52:57 -04:00
dependabot[bot] 9b3d93ddf6
build(deps): bump libc from 0.2.173 to 0.2.174 (#3975)
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.173 to 0.2.174.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.174/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.173...0.2.174)

---
updated-dependencies:
- dependency-name: libc
  dependency-version: 0.2.174
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-18 07:51:52 -04:00
dependabot[bot] dcd34222a9
build(deps): bump tracing-attributes in the tracing group (#3974)
Bumps the tracing group with 1 update: [tracing-attributes](https://github.com/tokio-rs/tracing).


Updates `tracing-attributes` from 0.1.29 to 0.1.30
- [Release notes](https://github.com/tokio-rs/tracing/releases)
- [Commits](https://github.com/tokio-rs/tracing/compare/tracing-attributes-0.1.29...tracing-attributes-0.1.30)

---
updated-dependencies:
- dependency-name: tracing-attributes
  dependency-version: 0.1.30
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: tracing
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-18 07:51:26 -04:00
dependabot[bot] 8203cd2e96
build(deps): bump jiff from 0.2.14 to 0.2.15 (#3973)
Bumps [jiff](https://github.com/BurntSushi/jiff) from 0.2.14 to 0.2.15.
- [Release notes](https://github.com/BurntSushi/jiff/releases)
- [Changelog](https://github.com/BurntSushi/jiff/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/jiff/compare/jiff-static-0.2.14...jiff-static-0.2.15)

---
updated-dependencies:
- dependency-name: jiff
  dependency-version: 0.2.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-17 12:12:22 -04:00
dependabot[bot] 19235e0841
build(deps): bump libc from 0.2.172 to 0.2.173 (#3972)
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.172 to 0.2.173.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.173/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.172...0.2.173)

---
updated-dependencies:
- dependency-name: libc
  dependency-version: 0.2.173
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-17 12:12:08 -04:00
dependabot[bot] 6f51389717
build(deps): bump thread_local from 1.1.8 to 1.1.9 (#3971)
Bumps [thread_local](https://github.com/Amanieu/thread_local-rs) from 1.1.8 to 1.1.9.
- [Release notes](https://github.com/Amanieu/thread_local-rs/releases)
- [Changelog](https://github.com/Amanieu/thread_local-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/thread_local-rs/compare/1.1.8...v1.1.9)

---
updated-dependencies:
- dependency-name: thread_local
  dependency-version: 1.1.9
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-17 12:11:57 -04:00
dependabot[bot] 3c2854beb1
build(deps): bump aws-lc-fips-sys from 0.13.6 to 0.13.7 (#3968)
Bumps [aws-lc-fips-sys](https://github.com/aws/aws-lc-rs) from 0.13.6 to 0.13.7.
- [Release notes](https://github.com/aws/aws-lc-rs/releases)
- [Commits](https://github.com/aws/aws-lc-rs/compare/aws-lc-fips-sys/v0.13.6...aws-lc-fips-sys/v0.13.7)

---
updated-dependencies:
- dependency-name: aws-lc-fips-sys
  dependency-version: 0.13.7
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 12:26:15 -04:00
dependabot[bot] 35ef9b3c8b
build(deps): bump cc from 1.2.26 to 1.2.27 (#3969)
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.2.26 to 1.2.27.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.26...cc-v1.2.27)

---
updated-dependencies:
- dependency-name: cc
  dependency-version: 1.2.27
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 12:26:07 -04:00
dependabot[bot] 4922138b3e
build(deps): bump prettyplease from 0.2.33 to 0.2.34 (#3967)
Bumps [prettyplease](https://github.com/dtolnay/prettyplease) from 0.2.33 to 0.2.34.
- [Release notes](https://github.com/dtolnay/prettyplease/releases)
- [Commits](https://github.com/dtolnay/prettyplease/compare/0.2.33...0.2.34)

---
updated-dependencies:
- dependency-name: prettyplease
  dependency-version: 0.2.34
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 12:22:48 -04:00
dependabot[bot] 47f3817dea
build(deps): bump memchr from 2.7.4 to 2.7.5 (#3966)
Bumps [memchr](https://github.com/BurntSushi/memchr) from 2.7.4 to 2.7.5.
- [Commits](https://github.com/BurntSushi/memchr/compare/2.7.4...2.7.5)

---
updated-dependencies:
- dependency-name: memchr
  dependency-version: 2.7.5
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-12 16:04:26 -04:00
dependabot[bot] 15bcb9a056
build(deps): bump cfg-if from 1.0.0 to 1.0.1 (#3965)
Bumps [cfg-if](https://github.com/rust-lang/cfg-if) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/rust-lang/cfg-if/releases)
- [Changelog](https://github.com/rust-lang/cfg-if/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cfg-if/compare/1.0.0...v1.0.1)

---
updated-dependencies:
- dependency-name: cfg-if
  dependency-version: 1.0.1
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-12 16:03:01 -04:00
dependabot[bot] 25212a4423
build(deps): bump softprops/action-gh-release from 2.3.0 to 2.3.2 (#3964)
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.3.0 to 2.3.2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](d5382d3e6f...72f2c25fcb)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: 2.3.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-12 08:45:20 -07:00
dependabot[bot] 4cd1fbf69a
build(deps): bump wasi (#3963)
Bumps [wasi](https://github.com/bytecodealliance/wasi) from 0.11.0+wasi-snapshot-preview1 to 0.11.1+wasi-snapshot-preview1.
- [Commits](https://github.com/bytecodealliance/wasi/compare/0.11.0...0.11.1)

---
updated-dependencies:
- dependency-name: wasi
  dependency-version: 0.11.1+wasi-snapshot-preview1
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-11 11:30:55 -04:00
dependabot[bot] f2c68aa010
build(deps): bump smallvec from 1.15.0 to 1.15.1 (#3962)
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.15.0 to 1.15.1.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.15.0...v1.15.1)

---
updated-dependencies:
- dependency-name: smallvec
  dependency-version: 1.15.1
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-11 11:30:31 -04:00
dependabot[bot] 14c3716fcd
build(deps): bump miniz_oxide from 0.8.8 to 0.8.9 (#3961)
Bumps [miniz_oxide](https://github.com/Frommi/miniz_oxide) from 0.8.8 to 0.8.9.
- [Changelog](https://github.com/Frommi/miniz_oxide/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Frommi/miniz_oxide/commits)

---
updated-dependencies:
- dependency-name: miniz_oxide
  dependency-version: 0.8.9
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-11 11:30:20 -04:00
dependabot[bot] 6118756991
build(deps): bump adler2 from 2.0.0 to 2.0.1 (#3960)
Bumps [adler2](https://github.com/oyvindln/adler2) from 2.0.0 to 2.0.1.
- [Changelog](https://github.com/oyvindln/adler2/blob/main/CHANGELOG.md)
- [Commits](https://github.com/oyvindln/adler2/commits)

---
updated-dependencies:
- dependency-name: adler2
  dependency-version: 2.0.1
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-10 10:11:16 -04:00
dependabot[bot] f508e7998c
build(deps): bump syn from 2.0.101 to 2.0.102 (#3959)
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.101 to 2.0.102.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.101...2.0.102)

---
updated-dependencies:
- dependency-name: syn
  dependency-version: 2.0.102
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-10 10:10:40 -04:00
dependabot[bot] 9ed7f8cf7d
build(deps): bump rustc-demangle from 0.1.24 to 0.1.25 (#3958)
Bumps [rustc-demangle](https://github.com/rust-lang/rustc-demangle) from 0.1.24 to 0.1.25.
- [Commits](https://github.com/rust-lang/rustc-demangle/commits)

---
updated-dependencies:
- dependency-name: rustc-demangle
  dependency-version: 0.1.25
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-10 10:10:15 -04:00
dependabot[bot] 3da6013871
build(deps): bump softprops/action-gh-release from 2.2.2 to 2.3.0 (#3957)
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.2.2 to 2.3.0.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](da05d55257...d5382d3e6f)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: 2.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-10 10:09:51 -04:00
dependabot[bot] 66d558b8b2
build(deps): bump cc from 1.2.25 to 1.2.26 (#3956)
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.2.25 to 1.2.26.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.25...cc-v1.2.26)

---
updated-dependencies:
- dependency-name: cc
  dependency-version: 1.2.26
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-09 11:35:37 -04:00
dependabot[bot] ede8a97d25
build(deps): bump tracing-attributes in the tracing group (#3955)
Bumps the tracing group with 1 update: [tracing-attributes](https://github.com/tokio-rs/tracing).


Updates `tracing-attributes` from 0.1.28 to 0.1.29
- [Release notes](https://github.com/tokio-rs/tracing/releases)
- [Commits](https://github.com/tokio-rs/tracing/compare/tracing-attributes-0.1.28...tracing-attributes-0.1.29)

---
updated-dependencies:
- dependency-name: tracing-attributes
  dependency-version: 0.1.29
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: tracing
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-09 11:35:23 -04:00
dependabot[bot] 44cfdfd7fe
build(deps): bump flate2 from 1.1.1 to 1.1.2 (#3954)
Bumps [flate2](https://github.com/rust-lang/flate2-rs) from 1.1.1 to 1.1.2.
- [Release notes](https://github.com/rust-lang/flate2-rs/releases)
- [Commits](https://github.com/rust-lang/flate2-rs/compare/1.1.1...1.1.2)

---
updated-dependencies:
- dependency-name: flate2
  dependency-version: 1.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-09 11:35:07 -04:00
dependabot[bot] 8a515a3cc0
build(deps): bump portable-atomic from 1.11.0 to 1.11.1 (#3952)
Bumps [portable-atomic](https://github.com/taiki-e/portable-atomic) from 1.11.0 to 1.11.1.
- [Release notes](https://github.com/taiki-e/portable-atomic/releases)
- [Changelog](https://github.com/taiki-e/portable-atomic/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/portable-atomic/compare/v1.11.0...v1.11.1)

---
updated-dependencies:
- dependency-name: portable-atomic
  dependency-version: 1.11.1
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-06 10:53:05 -04:00
dependabot[bot] d1ecb03c9f
build(deps): bump bumpalo from 3.17.0 to 3.18.1 (#3951)
Bumps [bumpalo](https://github.com/fitzgen/bumpalo) from 3.17.0 to 3.18.1.
- [Changelog](https://github.com/fitzgen/bumpalo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fitzgen/bumpalo/compare/3.17.0...v3.18.1)

---
updated-dependencies:
- dependency-name: bumpalo
  dependency-version: 3.18.1
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-06 10:52:47 -04:00
dependabot[bot] f4ae038d79
build(deps): bump tracing-core in the tracing group (#3950)
Bumps the tracing group with 1 update: [tracing-core](https://github.com/tokio-rs/tracing).


Updates `tracing-core` from 0.1.33 to 0.1.34
- [Release notes](https://github.com/tokio-rs/tracing/releases)
- [Commits](https://github.com/tokio-rs/tracing/compare/tracing-core-0.1.33...tracing-core-0.1.34)

---
updated-dependencies:
- dependency-name: tracing-core
  dependency-version: 0.1.34
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: tracing
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-06 10:52:38 -04:00
dependabot[bot] 3aa53596f7
build(deps): bump hyper-util from 0.1.13 to 0.1.14 (#3948)
Bumps [hyper-util](https://github.com/hyperium/hyper-util) from 0.1.13 to 0.1.14.
- [Release notes](https://github.com/hyperium/hyper-util/releases)
- [Changelog](https://github.com/hyperium/hyper-util/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/hyper-util/compare/v0.1.13...v0.1.14)

---
updated-dependencies:
- dependency-name: hyper-util
  dependency-version: 0.1.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-05 06:51:50 -07:00
katelyn martin 67dc85a367
chore(app/test): remove unused dependencies (#3932)
`linkerd-app-test` relies on some dependencies that are unused.

this commit removes these dependencies from the crate's manifest.

see #3928 and #3929.

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-06-02 15:10:53 -07:00
katelyn martin ea6f407c57
fix(http/retry): `PeekTrailersBody<B>` retains first frame (#3947)
see linkerd/linkerd2#14050.

this change fixes a logical bug with
`linkerd_http_retry::peek_trailers::PeekTrailersBody::<B>::read_body(..)`.

`read_body(..)` constructs a `PeekTrailersBody<B>`, by polling the inner
body to see whether or not it can reach the end of the stream by only
yielding to the asynchronous runtime once.

in linkerd/linkerd2-proxy#3559, we restructured this middleware's
internal modeling to reflect the `Frame<T>`-oriented signatures of the
`http_body::Body` trait's 1.0 interface.

unfortunately, this included a bug which could cause the first frame in
a stream to be discarded if the second `Body::poll_frame()` call
(_invoked via `now_or_never()`_) returns `Pending`. this could cause
non-deterministic errors for users when sending traffic to HTTPRoutes
and GRPCRoutes with retry annotations applied.

this change rectifies this problem, ensuring that the first frame is not
discarded when attempting to peek a body's trailers.

to confirm that this works as expected, additional test coverage is
introduced that confirms that the data and trailers of the inner body
are passed through faithfully.

---

* feat(http/retry): additional `PeekTrailersBody<B>` test coverage

this commit introduces additional test coverage to
`linker_http_retry::peek_trailers::PeekTrailersBody<B>`.

this body middleware is used to facilitate transparent http retries, and
allows callers to possibly inspect the trailers for a response, by
polling an `http_body::Body`.

this commit introduces additional unit test coverage that confirms that
the data and trailers of the inner body are passed through faithfully.

Signed-off-by: katelyn martin <kate@buoyant.io>

* feat(http/retry): another `PeekTrailersBody<B>` test case

this commit introduces some additional coverage for bodies that return
`Pending` when polled a second time.

Signed-off-by: katelyn martin <kate@buoyant.io>

* fix(http/retry): `PeekTrailersBody<B>` retains first frame

this commit fixes a logical bug with
`linkerd_http_retry::peek_trailers::PeekTrailersBody::<B>::read_body(..)`.

`read_body(..)` constructs a `PeekTrailersBody<B>`, by polling the inner
body to see whether or not it can reach the end of the stream by only
yielding to the asynchronous runtime once.

in linkerd/linkerd2-proxy#3559, we restructured this middleware's
internal modeling to reflect the `Frame<T>`-oriented signatures of the
`http_body::Body` trait's 1.0 interface.

unfortunately, this included a bug which could cause the first frame in
a stream to be discarded if the second `Body::poll_frame()` call
(_invoked via `now_or_never()`_) returns `Pending`. this could cause
non-deterministic errors for users when sending traffic to HTTPRoutes
and GRPCRoutes with retry annotations applied.

this commit rectifies this problem, ensuring that the first frame is not
discarded when attempting to peek a body's trailers.

Signed-off-by: katelyn martin <kate@buoyant.io>

---------

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-06-02 09:53:24 -07:00
dependabot[bot] c36bef6b47
build(deps): bump num_cpus from 1.16.0 to 1.17.0 (#3946)
Bumps [num_cpus](https://github.com/seanmonstar/num_cpus) from 1.16.0 to 1.17.0.
- [Release notes](https://github.com/seanmonstar/num_cpus/releases)
- [Changelog](https://github.com/seanmonstar/num_cpus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/num_cpus/compare/v1.16.0...v1.17.0)

---
updated-dependencies:
- dependency-name: num_cpus
  dependency-version: 1.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-02 08:51:23 -04:00
dependabot[bot] 12822d1848
build(deps): bump cc from 1.2.24 to 1.2.25 (#3945)
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.2.24 to 1.2.25.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.24...cc-v1.2.25)

---
updated-dependencies:
- dependency-name: cc
  dependency-version: 1.2.25
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-02 08:51:10 -04:00
dependabot[bot] 66b5f330c3
build(deps): bump prettyplease from 0.2.32 to 0.2.33 (#3944)
Bumps [prettyplease](https://github.com/dtolnay/prettyplease) from 0.2.32 to 0.2.33.
- [Release notes](https://github.com/dtolnay/prettyplease/releases)
- [Commits](https://github.com/dtolnay/prettyplease/compare/0.2.32...0.2.33)

---
updated-dependencies:
- dependency-name: prettyplease
  dependency-version: 0.2.33
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-02 08:50:58 -04:00
dependabot[bot] 423b5c07e6
build(deps): bump parking_lot from 0.12.3 to 0.12.4 (#3943)
Bumps [parking_lot](https://github.com/Amanieu/parking_lot) from 0.12.3 to 0.12.4.
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/0.12.3...parking_lot-v0.12.4)

---
updated-dependencies:
- dependency-name: parking_lot
  dependency-version: 0.12.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-30 08:18:04 -04:00
dependabot[bot] 0a17238d10
build(deps): bump parking_lot_core from 0.9.10 to 0.9.11 (#3942)
Bumps [parking_lot_core](https://github.com/Amanieu/parking_lot) from 0.9.10 to 0.9.11.
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/core-0.9.10...parking_lot_core-v0.9.11)

---
updated-dependencies:
- dependency-name: parking_lot_core
  dependency-version: 0.9.11
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-30 08:17:37 -04:00
dependabot[bot] cbfef553ce
build(deps): bump lock_api from 0.4.12 to 0.4.13 (#3941)
Bumps [lock_api](https://github.com/Amanieu/parking_lot) from 0.4.12 to 0.4.13.
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/lock_api-0.4.12...lock_api-v0.4.13)

---
updated-dependencies:
- dependency-name: lock_api
  dependency-version: 0.4.13
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-30 08:17:20 -04:00
dependabot[bot] 6233b47dd3
build(deps): bump libloading from 0.8.7 to 0.8.8 (#3940)
Bumps [libloading](https://github.com/nagisa/rust_libloading) from 0.8.7 to 0.8.8.
- [Commits](https://github.com/nagisa/rust_libloading/commits)

---
updated-dependencies:
- dependency-name: libloading
  dependency-version: 0.8.8
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-29 10:44:53 -04:00
dependabot[bot] 19bfb14f1f
build(deps): bump pprof from 0.14.0 to 0.15.0 (#3938)
Bumps [pprof](https://github.com/tikv/pprof-rs) from 0.14.0 to 0.15.0.
- [Changelog](https://github.com/tikv/pprof-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tikv/pprof-rs/commits)

---
updated-dependencies:
- dependency-name: pprof
  dependency-version: 0.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-28 11:13:34 -04:00
dependabot[bot] c6eea70f1a
build(deps): bump hyper-util from 0.1.12 to 0.1.13 (#3939)
Bumps [hyper-util](https://github.com/hyperium/hyper-util) from 0.1.12 to 0.1.13.
- [Release notes](https://github.com/hyperium/hyper-util/releases)
- [Changelog](https://github.com/hyperium/hyper-util/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/hyper-util/compare/v0.1.12...v0.1.13)

---
updated-dependencies:
- dependency-name: hyper-util
  dependency-version: 0.1.13
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-28 11:13:08 -04:00
dependabot[bot] 96d7c25704
build(deps): bump the boring group with 3 updates (#3937)
Bumps the boring group with 3 updates: [boring](https://github.com/cloudflare/boring), [tokio-boring](https://github.com/cloudflare/boring) and [boring-sys](https://github.com/cloudflare/boring).


Updates `boring` from 4.16.0 to 4.17.0
- [Release notes](https://github.com/cloudflare/boring/releases)
- [Changelog](https://github.com/cloudflare/boring/blob/master/RELEASE_NOTES)
- [Commits](https://github.com/cloudflare/boring/compare/v4.16.0...v4.17.0)

Updates `tokio-boring` from 4.16.0 to 4.17.0
- [Release notes](https://github.com/cloudflare/boring/releases)
- [Changelog](https://github.com/cloudflare/boring/blob/master/RELEASE_NOTES)
- [Commits](https://github.com/cloudflare/boring/compare/v4.16.0...v4.17.0)

Updates `boring-sys` from 4.16.0 to 4.17.0
- [Release notes](https://github.com/cloudflare/boring/releases)
- [Changelog](https://github.com/cloudflare/boring/blob/master/RELEASE_NOTES)
- [Commits](https://github.com/cloudflare/boring/compare/v4.16.0...v4.17.0)

---
updated-dependencies:
- dependency-name: boring
  dependency-version: 4.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: boring
- dependency-name: tokio-boring
  dependency-version: 4.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: boring
- dependency-name: boring-sys
  dependency-version: 4.17.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: boring
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-28 08:23:55 -04:00
dependabot[bot] 1450af00d8
build(deps): bump the opentelemetry group with 2 updates (#3934)
Bumps the opentelemetry group with 2 updates: [opentelemetry](https://github.com/open-telemetry/opentelemetry-rust) and [opentelemetry_sdk](https://github.com/open-telemetry/opentelemetry-rust).


Updates `opentelemetry` from 0.29.1 to 0.30.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-rust/releases)
- [Commits](https://github.com/open-telemetry/opentelemetry-rust/compare/opentelemetry-0.29.1...opentelemetry-0.30.0)

Updates `opentelemetry_sdk` from 0.29.0 to 0.30.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-rust/releases)
- [Commits](https://github.com/open-telemetry/opentelemetry-rust/compare/opentelemetry_sdk-0.29.0...opentelemetry_sdk-0.30.0)

---
updated-dependencies:
- dependency-name: opentelemetry
  dependency-version: 0.30.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: opentelemetry
- dependency-name: opentelemetry_sdk
  dependency-version: 0.30.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: opentelemetry
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-27 07:17:39 -07:00
dependabot[bot] 27f62ad034
build(deps): bump mio from 1.0.3 to 1.0.4 (#3933)
Bumps [mio](https://github.com/tokio-rs/mio) from 1.0.3 to 1.0.4.
- [Release notes](https://github.com/tokio-rs/mio/releases)
- [Changelog](https://github.com/tokio-rs/mio/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/mio/commits)

---
updated-dependencies:
- dependency-name: mio
  dependency-version: 1.0.4
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-27 09:35:24 -04:00
dependabot[bot] fefa7c0cbf
build(deps): bump socket2 from 0.5.9 to 0.5.10 (#3936)
Bumps [socket2](https://github.com/rust-lang/socket2) from 0.5.9 to 0.5.10.
- [Release notes](https://github.com/rust-lang/socket2/releases)
- [Changelog](https://github.com/rust-lang/socket2/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/socket2/commits)

---
updated-dependencies:
- dependency-name: socket2
  dependency-version: 0.5.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-27 09:33:06 -04:00
katelyn martin b3549bc767
chore(app/test): remove unused functions (#3929)
`linkerd-app-test` exposes some functions that we never use elsewhere.

this commit removes these functions.

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-05-23 09:25:12 -07:00
katelyn martin c00ce3241b
chore(app/test): remove unused `service` submodule (#3928)
`linkerd_app_test::service` contains facilities that are unused.

this commit removes this submodule from the `linkerd-app-test` library.

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-05-23 09:25:00 -07:00
dependabot[bot] 21fd4ec51b
build(deps): bump rustversion from 1.0.20 to 1.0.21 (#3931)
Bumps [rustversion](https://github.com/dtolnay/rustversion) from 1.0.20 to 1.0.21.
- [Release notes](https://github.com/dtolnay/rustversion/releases)
- [Commits](https://github.com/dtolnay/rustversion/compare/1.0.20...1.0.21)

---
updated-dependencies:
- dependency-name: rustversion
  dependency-version: 1.0.21
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-23 08:38:35 -04:00
dependabot[bot] fa0c104931
build(deps): bump cc from 1.2.23 to 1.2.24 (#3930)
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.2.23 to 1.2.24.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.23...cc-v1.2.24)

---
updated-dependencies:
- dependency-name: cc
  dependency-version: 1.2.24
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-23 08:38:10 -04:00
katelyn martin cab7adc456
chore(meshtls/boring): sort dependencies (#3927)
Signed-off-by: katelyn martin <kate@buoyant.io>
2025-05-22 16:20:58 -04:00
katelyn martin 478e1e151f
chore(deps): bump DavidAnson/markdownlint-cli2-action (#3923)
* chore(docs): address `no-generic-link-test` lint (#3923)

this addresses errors observed by dependabot when upgrading to the
latest version of `markdownlint`.

there is a new lint, added in DavidAnson/markdownlint#1459, that
introduces forbidden link text to discourage generic `here` text in
links.

this fixes sentences that included a link labeled "here".

* https://github.com/linkerd/linkerd2-proxy/pull/3918
* https://github.com/linkerd/linkerd2-proxy/actions/runs/15043224730/job/42279610780?pr=3918
* https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md059.md
* https://github.com/DavidAnson/markdownlint/pull/1459
* https://github.com/DavidAnson/markdownlint/issues/681

```
 Summary: 3 error(s)
Error: docs/FUZZING.md:17:13 MD059/descriptive-link-text Link text should be descriptive [Context: "[here]"] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md059.md
Error: docs/FUZZING.md💯2 MD059/descriptive-link-text Link text should be descriptive [Context: "[here]"] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md059.md
Error: README.md:90:2 MD059/descriptive-link-text Link text should be descriptive [Context: "[here]"] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md059.md
Error: Failed with exit code: 1
```

Signed-off-by: katelyn martin <kate@buoyant.io>

* build(deps): bump DavidAnson/markdownlint-cli2-action (#3923)

Bumps [DavidAnson/markdownlint-cli2-action](https://github.com/davidanson/markdownlint-cli2-action) from 19.1.0 to 20.0.0.
- [Release notes](https://github.com/davidanson/markdownlint-cli2-action/releases)
- [Commits](05f32210e8...992badcdf2)

---
updated-dependencies:
- dependency-name: DavidAnson/markdownlint-cli2-action
  dependency-version: 20.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

---------

Signed-off-by: katelyn martin <kate@buoyant.io>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-22 13:16:37 -07:00
dependabot[bot] 1eeae37018
build(deps): bump jiff from 0.2.13 to 0.2.14 (#3926)
Bumps [jiff](https://github.com/BurntSushi/jiff) from 0.2.13 to 0.2.14.
- [Release notes](https://github.com/BurntSushi/jiff/releases)
- [Changelog](https://github.com/BurntSushi/jiff/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/jiff/compare/jiff-static-0.2.13...jiff-static-0.2.14)

---
updated-dependencies:
- dependency-name: jiff
  dependency-version: 0.2.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-21 10:29:08 -04:00
dependabot[bot] 83d4eacb27
build(deps): bump hyper-util from 0.1.11 to 0.1.12 (#3925)
Bumps [hyper-util](https://github.com/hyperium/hyper-util) from 0.1.11 to 0.1.12.
- [Release notes](https://github.com/hyperium/hyper-util/releases)
- [Changelog](https://github.com/hyperium/hyper-util/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/hyper-util/compare/v0.1.11...v0.1.12)

---
updated-dependencies:
- dependency-name: hyper-util
  dependency-version: 0.1.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 09:15:20 -04:00
dependabot[bot] ddc590f38b
build(deps): bump the icu4x group with 2 updates (#3924)
Bumps the icu4x group with 2 updates: [icu_properties](https://github.com/unicode-org/icu4x) and [icu_properties_data](https://github.com/unicode-org/icu4x).


Updates `icu_properties` from 2.0.0 to 2.0.1
- [Release notes](https://github.com/unicode-org/icu4x/releases)
- [Changelog](https://github.com/unicode-org/icu4x/blob/main/CHANGELOG.md)
- [Commits](https://github.com/unicode-org/icu4x/commits)

Updates `icu_properties_data` from 2.0.0 to 2.0.1
- [Release notes](https://github.com/unicode-org/icu4x/releases)
- [Changelog](https://github.com/unicode-org/icu4x/blob/main/CHANGELOG.md)
- [Commits](https://github.com/unicode-org/icu4x/commits)

---
updated-dependencies:
- dependency-name: icu_properties
  dependency-version: 2.0.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: icu4x
- dependency-name: icu_properties_data
  dependency-version: 2.0.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: icu4x
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 09:14:43 -04:00
dependabot[bot] 0f42f15102
build(deps): bump codecov/codecov-action from 5.4.2 to 5.4.3 (#3920)
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.4.2 to 5.4.3.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](ad3126e916...18283e04ce)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-version: 5.4.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-16 16:21:34 -04:00
dependabot[bot] 20f47ad9de
build(deps): bump errno from 0.3.11 to 0.3.12 (#3922)
Bumps [errno](https://github.com/lambda-fairy/rust-errno) from 0.3.11 to 0.3.12.
- [Release notes](https://github.com/lambda-fairy/rust-errno/releases)
- [Changelog](https://github.com/lambda-fairy/rust-errno/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lambda-fairy/rust-errno/compare/v0.3.11...v0.3.12)

---
updated-dependencies:
- dependency-name: errno
  dependency-version: 0.3.12
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-16 10:01:34 -04:00
dependabot[bot] 7abe88119c
build(deps): bump cc from 1.2.22 to 1.2.23 (#3921)
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.2.22 to 1.2.23.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.22...cc-v1.2.23)

---
updated-dependencies:
- dependency-name: cc
  dependency-version: 1.2.23
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-16 10:01:02 -04:00
katelyn martin 37c0f96cfc
nit(app): consolidate `impl Config` blocks (#3919)
this is a trivial, cosmetic change.

`Config` has two consecutive `impl` blocks in the `linkerd-app` library.
these do not include distinct generics or trait bounds, so the methods
contained therein do not need to live in two distinct `impl` blocks.

this commit consolidates these blocks.

while we are performing this change, we add two `=== impl T ===`
banners, which are used throughout the project as greppable strings to
find methods and trait implementations for a given type.

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-05-16 09:37:02 -04:00
dependabot[bot] 79e10775f0
build(deps): bump generator from 0.8.4 to 0.8.5 (#3917)
Bumps [generator](https://github.com/Xudong-Huang/generator-rs) from 0.8.4 to 0.8.5.
- [Release notes](https://github.com/Xudong-Huang/generator-rs/releases)
- [Commits](https://github.com/Xudong-Huang/generator-rs/compare/0.8.4...0.8.5)

---
updated-dependencies:
- dependency-name: generator
  dependency-version: 0.8.5
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-14 09:29:51 -04:00
dependabot[bot] a2eadec54a
build(deps): bump resolv-conf from 0.7.3 to 0.7.4 (#3916)
Bumps [resolv-conf](https://github.com/hickory-dns/resolv-conf) from 0.7.3 to 0.7.4.
- [Release notes](https://github.com/hickory-dns/resolv-conf/releases)
- [Commits](https://github.com/hickory-dns/resolv-conf/compare/v0.7.3...v0.7.4)

---
updated-dependencies:
- dependency-name: resolv-conf
  dependency-version: 0.7.4
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-13 09:53:37 -04:00
katelyn martin 7b7ffbc69d
chore(deps): define `tracing` workspace dependency (#3834)
this commit hoists `tracing`, used liberally throughout our project,
such that it is managed as a single workspace dependency.

this will be helpful someday when a 0.2 release happens.

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-05-12 16:00:34 -04:00
katelyn martin 00b5de1936
refactor(proxy/http): a concrete `orig_proto` error (#3901)
this commit introduces a concrete error type for the `orig_proto`
upgrade layer.

this layer is used by the proxy's http client to transparently upgrade
outbound http/1 traffic to http/2. rather than boxing errors, we define
a concrete error type to facilitate inspecting errors in the future.

for now, the top-level http client continues to box errors thrown by the
"orig_proto" upgrade client.

see also, #3894 (ea75ac0).

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-05-12 15:59:56 -04:00
katelyn martin d3a176446c
fix: report error causes properly (#3915)
the `linkerd-error` crate includes two functions that can be used to
examine the cause of a dynamic, boxed error. for example, here is the
`is_caused_by()` function, used in some of our error recovery logic:

```rust
/// Determines whether the provided error was caused by an `E` typed error.
pub fn is_caused_by<E: std::error::Error + 'static>(
    mut error: &(dyn std::error::Error + 'static),
) -> bool {
    loop {
        if error.is::<E>() {
            return true;
        }
        error = match error.source() {
            Some(e) => e,
            None => return false,
        };
    }
}
```

we rely on [`thiserror`](https://github.com/dtolnay/thiserror/) to
generate boilerplate code for our error structures. this includes an
attribute called `transparent` that will delegate down to an inner
error.

however, this delegation means that the causal chains inspected by
the function above might not properly identify an inner error. this
test, for example, fails:

```rust
// linkerd/dns/src/lib.rs
#[derive(Debug, Clone, Error)]
#[error("invalid SRV record {:?}", self.0)]
struct InvalidSrv(rdata::SRV);

#[derive(Debug, Error)]
enum SrvRecordError {
    #[error(transparent)]
    Invalid(#[from] InvalidSrv),
    #[error("failed to resolve SRV record: {0}")]
    Resolve(#[from] hickory_resolver::ResolveError),
}

#[test]
fn srv_record_reports_cause_correctly() {
    let srv = "foobar.linkerd-dst-headless.linkerd.svc.cluster.local."
        .parse::<hickory_resolver::Name>()
        .map(|name| rdata::SRV::new(1, 1, 8086, name))
        .expect("a valid domain name");

    let error = SrvRecordError::Invalid(InvalidSrv(srv));
    let error: Box<dyn std::error::Error + 'static> = Box::new(error);

    assert!(linkerd_error::is_caused_by::<InvalidSrv>(&*error));
    assert!(linkerd_error::cause_ref::<InvalidSrv>(&*error).is_some());
}
```

the `transparent` attribute will delegate directly down to `InvalidSrv`
when `Error::source()` is invoked. this means that our downcasting logic
in `linkerd-error` used to ascertain causes of dynamic, boxed errors
will fail to identify a `SrvRecordError` as being caused by an
`InvalidSrv`.

by replacing the `transparent` attribute with a `"{0}"` display
attribute, we continue to transparently show the inner error when
printed as a string, but will include `InvalidSrv` in the causal chain.

this branch replaces `transparent` attributes in an assortment of
error variants.

---

* test(dns): add a failing test

this commit adds a failing unit test. this test shows that dns errors
might not report their cause correctly, due to thiserror's `transparent`
attribute passing directly through to `InvalidSrv`'s cause.

Signed-off-by: katelyn martin <kate@buoyant.io>

* fix(dns): replace `error(transparent)` attribute

this commit fixes the failing unit test introduced in the previous
commit.

the `transparent` attribute will delegate directly down to `InvalidSrv`
when `Error::source()` is invoke. this means that our downcasting logic
in `linkerd-error` used to ascertain causes of dynamic, boxed errors
will fail to identify a `SrvRecordError` as being caused by an
`InvalidSrv`.

by replacing the `transparent` attribute with a `"{0}"` display
attribute, we continue to transparently show the inner error when
printed as a string, but will include `InvalidSrv` in the causal chain.

Signed-off-by: katelyn martin <kate@buoyant.io>

* fix: errors report inner sources

this commit performs the same transformation as the previous commit,
replacing `transparent` with equivalent pass-through `"{0}"` display
strings, adding `#[source]` where needed.

Signed-off-by: katelyn martin <kate@buoyant.io>

---------

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-05-12 15:52:06 -04:00
katelyn martin 015c499891
refactor(app/outbound): `Connect` fields are not pub (#3895)
this structure exposes its fields, but those fields are never accessed
elsewhere, aside from test code.

this commit removes the `pub` directives from the address and tls
fields. in their stead, test interfaces are added to allow the
`tagged_transport` test suite to function.

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-05-12 15:38:59 -04:00
katelyn martin ea75ac0126
refactor(proxy/http): http/1 client is a `Service<T>` (#3894)
this is a small mechanical refactor to the http/1 client.

our http/2 and "orig_proto" clients are tower services. our http/1
client, on the other hand, exposes a concrete inherent method `request`.

to be consistent, this changes our http client to treat this http/1
client as a service as well.

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-05-12 15:38:26 -04:00
katelyn martin 3a795967af
nit(app/integration): sort cargo dependencies (#3887)
this alphabetizes dependencies in `linkerd-app-integration`'s
manifest.

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-05-12 15:37:52 -04:00
dependabot[bot] c5c2c24b0d
build(deps): bump libloading from 0.8.6 to 0.8.7 (#3914)
Bumps [libloading](https://github.com/nagisa/rust_libloading) from 0.8.6 to 0.8.7.
- [Commits](https://github.com/nagisa/rust_libloading/compare/0.8.6...0.8.7)

---
updated-dependencies:
- dependency-name: libloading
  dependency-version: 0.8.7
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-12 10:00:18 -04:00
dependabot[bot] 971ec0e14d
build(deps): bump multimap from 0.10.0 to 0.10.1 (#3913)
Bumps [multimap](https://github.com/havarnov/multimap) from 0.10.0 to 0.10.1.
- [Commits](https://github.com/havarnov/multimap/commits)

---
updated-dependencies:
- dependency-name: multimap
  dependency-version: 0.10.1
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-12 10:00:01 -04:00
dependabot[bot] f45a6185f6
build(deps): bump tempfile from 3.19.1 to 3.20.0 (#3912)
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.19.1 to 3.20.0.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.19.1...v3.20.0)

---
updated-dependencies:
- dependency-name: tempfile
  dependency-version: 3.20.0
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-12 09:58:57 -04:00
dependabot[bot] 6ea7f158a5
build(deps): bump aws-lc-rs from 1.13.0 to 1.13.1 (#3911)
Bumps [aws-lc-rs](https://github.com/aws/aws-lc-rs) from 1.13.0 to 1.13.1.
- [Release notes](https://github.com/aws/aws-lc-rs/releases)
- [Commits](https://github.com/aws/aws-lc-rs/compare/v1.13.0...v1.13.1)

---
updated-dependencies:
- dependency-name: aws-lc-rs
  dependency-version: 1.13.1
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-09 13:12:34 -04:00
dependabot[bot] 0e9f9443b8
build(deps): bump cc from 1.2.21 to 1.2.22 (#3910)
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.2.21 to 1.2.22.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.21...cc-v1.2.22)

---
updated-dependencies:
- dependency-name: cc
  dependency-version: 1.2.22
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-09 13:12:23 -04:00
dependabot[bot] 34dae165d6
build(deps): bump idna_adapter from 1.2.0 to 1.2.1 (#3909)
Bumps [idna_adapter](https://github.com/hsivonen/idna_adapter) from 1.2.0 to 1.2.1.
- [Commits](https://github.com/hsivonen/idna_adapter/compare/v1.2.0...v1.2.1)

---
updated-dependencies:
- dependency-name: idna_adapter
  dependency-version: 1.2.1
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-09 13:12:15 -04:00
dependabot[bot] 9063a6df66
build(deps): bump backtrace from 0.3.74 to 0.3.75 (#3907)
Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.74 to 0.3.75.
- [Release notes](https://github.com/rust-lang/backtrace-rs/releases)
- [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.74...0.3.75)

---
updated-dependencies:
- dependency-name: backtrace
  dependency-version: 0.3.75
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-07 10:21:51 -04:00
dependabot[bot] a9ce356bf8
build(deps): bump jiff from 0.2.12 to 0.2.13 (#3906)
Bumps [jiff](https://github.com/BurntSushi/jiff) from 0.2.12 to 0.2.13.
- [Release notes](https://github.com/BurntSushi/jiff/releases)
- [Changelog](https://github.com/BurntSushi/jiff/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/jiff/compare/jiff-static-0.2.12...jiff-static-0.2.13)

---
updated-dependencies:
- dependency-name: jiff
  dependency-version: 0.2.13
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-06 11:11:16 -04:00
dependabot[bot] dd432b3143
build(deps): bump tokio from 1.44.2 to 1.45.0 (#3905)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.44.2 to 1.45.0.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.44.2...tokio-1.45.0)

---
updated-dependencies:
- dependency-name: tokio
  dependency-version: 1.45.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-06 10:52:23 -04:00
dependabot[bot] d35e12facb
build(deps): bump jiff from 0.2.11 to 0.2.12 (#3900)
Bumps [jiff](https://github.com/BurntSushi/jiff) from 0.2.11 to 0.2.12.
- [Release notes](https://github.com/BurntSushi/jiff/releases)
- [Changelog](https://github.com/BurntSushi/jiff/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/jiff/compare/jiff-static-0.2.11...jiff-static-0.2.12)

---
updated-dependencies:
- dependency-name: jiff
  dependency-version: 0.2.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-05 09:19:42 -04:00
dependabot[bot] 430eb75667
build(deps): bump the hickory group with 2 updates (#3899)
Bumps the hickory group with 2 updates: [hickory-resolver](https://github.com/hickory-dns/hickory-dns) and [hickory-proto](https://github.com/hickory-dns/hickory-dns).


Updates `hickory-resolver` from 0.25.1 to 0.25.2
- [Release notes](https://github.com/hickory-dns/hickory-dns/releases)
- [Changelog](https://github.com/hickory-dns/hickory-dns/blob/main/OLD-CHANGELOG.md)
- [Commits](https://github.com/hickory-dns/hickory-dns/compare/v0.25.1...v0.25.2)

Updates `hickory-proto` from 0.25.1 to 0.25.2
- [Release notes](https://github.com/hickory-dns/hickory-dns/releases)
- [Changelog](https://github.com/hickory-dns/hickory-dns/blob/main/OLD-CHANGELOG.md)
- [Commits](https://github.com/hickory-dns/hickory-dns/compare/v0.25.1...v0.25.2)

---
updated-dependencies:
- dependency-name: hickory-resolver
  dependency-version: 0.25.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: hickory
- dependency-name: hickory-proto
  dependency-version: 0.25.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: hickory
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-05 09:18:40 -04:00
dependabot[bot] 025f0a19cb
build(deps): bump the symbolic group with 2 updates (#3896)
Bumps the symbolic group with 2 updates: [symbolic-common](https://github.com/getsentry/symbolic) and [symbolic-demangle](https://github.com/getsentry/symbolic).


Updates `symbolic-common` from 12.15.4 to 12.15.5
- [Release notes](https://github.com/getsentry/symbolic/releases)
- [Changelog](https://github.com/getsentry/symbolic/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/symbolic/compare/12.15.4...12.15.5)

Updates `symbolic-demangle` from 12.15.4 to 12.15.5
- [Release notes](https://github.com/getsentry/symbolic/releases)
- [Changelog](https://github.com/getsentry/symbolic/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/symbolic/compare/12.15.4...12.15.5)

---
updated-dependencies:
- dependency-name: symbolic-common
  dependency-version: 12.15.5
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: symbolic
- dependency-name: symbolic-demangle
  dependency-version: 12.15.5
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: symbolic
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-02 11:00:55 -04:00
dependabot[bot] d9ed5e3835
build(deps): bump jiff from 0.2.10 to 0.2.11 (#3898)
Bumps [jiff](https://github.com/BurntSushi/jiff) from 0.2.10 to 0.2.11.
- [Release notes](https://github.com/BurntSushi/jiff/releases)
- [Changelog](https://github.com/BurntSushi/jiff/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/jiff/compare/jiff-static-0.2.10...jiff-static-0.2.11)

---
updated-dependencies:
- dependency-name: jiff
  dependency-version: 0.2.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-02 11:00:28 -04:00
dependabot[bot] f2e4961a4b
build(deps): bump cc from 1.2.20 to 1.2.21 (#3897)
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.2.20 to 1.2.21.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.20...cc-v1.2.21)

---
updated-dependencies:
- dependency-name: cc
  dependency-version: 1.2.21
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-02 10:59:54 -04:00
dependabot[bot] facaf571d8
build(deps): bump sha2 from 0.10.8 to 0.10.9 (#3893)
Bumps [sha2](https://github.com/RustCrypto/hashes) from 0.10.8 to 0.10.9.
- [Commits](https://github.com/RustCrypto/hashes/compare/sha2-v0.10.8...sha2-v0.10.9)

---
updated-dependencies:
- dependency-name: sha2
  dependency-version: 0.10.9
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-01 10:55:25 -04:00
dependabot[bot] 905f71fa25
build(deps): bump resolv-conf from 0.7.1 to 0.7.3 (#3892)
Bumps [resolv-conf](https://github.com/hickory-dns/resolv-conf) from 0.7.1 to 0.7.3.
- [Release notes](https://github.com/hickory-dns/resolv-conf/releases)
- [Commits](https://github.com/hickory-dns/resolv-conf/compare/v0.7.1...v0.7.3)

---
updated-dependencies:
- dependency-name: resolv-conf
  dependency-version: 0.7.3
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-01 10:55:14 -04:00
dependabot[bot] c822b72786
build(deps): bump synstructure from 0.13.1 to 0.13.2 (#3891)
Bumps [synstructure](https://github.com/mystor/synstructure) from 0.13.1 to 0.13.2.
- [Commits](https://github.com/mystor/synstructure/commits)

---
updated-dependencies:
- dependency-name: synstructure
  dependency-version: 0.13.2
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-01 10:54:55 -04:00
dependabot[bot] b6a07aa01e
build(deps): bump tokio-metrics from 0.4.1 to 0.4.2 (#3890)
Bumps [tokio-metrics](https://github.com/tokio-rs/tokio-metrics) from 0.4.1 to 0.4.2.
- [Release notes](https://github.com/tokio-rs/tokio-metrics/releases)
- [Changelog](https://github.com/tokio-rs/tokio-metrics/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/tokio-metrics/compare/v0.4.1...v0.4.2)

---
updated-dependencies:
- dependency-name: tokio-metrics
  dependency-version: 0.4.2
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-01 10:54:44 -04:00
dependabot[bot] f657ceabb4
build(deps): bump aws-lc-fips-sys from 0.13.5 to 0.13.6 (#3889)
Bumps [aws-lc-fips-sys](https://github.com/aws/aws-lc-rs) from 0.13.5 to 0.13.6.
- [Release notes](https://github.com/aws/aws-lc-rs/releases)
- [Commits](https://github.com/aws/aws-lc-rs/compare/aws-lc-fips-sys/v0.13.5...aws-lc-fips-sys/v0.13.6)

---
updated-dependencies:
- dependency-name: aws-lc-fips-sys
  dependency-version: 0.13.6
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-29 09:12:22 -04:00
dependabot[bot] 89e28324da
build(deps): bump syn from 2.0.100 to 2.0.101 (#3886)
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.100 to 2.0.101.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.100...2.0.101)

---
updated-dependencies:
- dependency-name: syn
  dependency-version: 2.0.101
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-28 09:40:18 -04:00
Scott Fleener 577a67b2c6
feat(meshtls): Add aws-lc-rs as optional rustls backend (#3883)
This has a few benefits. Primarily this gives us a reasonable path to creating FIPS-enabled builds on architectures other than x86-64, as well as a path away from using BoringSSL as a backend.

Additionally, rustls has been using the aws-lc-rs library as the default backend for a little while now, so this gives us the opportunity to stay in line with the most widely used option in the ecosystem.

Signed-off-by: Scott Fleener <scott@buoyant.io>
2025-04-28 08:38:40 -04:00
dependabot[bot] b4fb4277d4
build(deps): bump actions/download-artifact from 4.2.1 to 4.3.0 (#3885)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4.2.1 to 4.3.0.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](95815c38cf...d3f86a106a)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: 4.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-25 10:28:33 -04:00
dependabot[bot] 5e626ef240
build(deps): bump cc from 1.2.19 to 1.2.20 (#3884)
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.2.19 to 1.2.20.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.19...cc-v1.2.20)

---
updated-dependencies:
- dependency-name: cc
  dependency-version: 1.2.20
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-25 09:35:30 -04:00
dependabot[bot] d4c8a74596
build(deps): bump tokio-util from 0.7.14 to 0.7.15 (#3882)
Bumps [tokio-util](https://github.com/tokio-rs/tokio) from 0.7.14 to 0.7.15.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-util-0.7.14...tokio-util-0.7.15)

---
updated-dependencies:
- dependency-name: tokio-util
  dependency-version: 0.7.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-24 13:22:17 -04:00
dependabot[bot] ff162dba22
build(deps): bump getrandom from 0.2.15 to 0.2.16 (#3881)
Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.2.15 to 0.2.16.
- [Changelog](https://github.com/rust-random/getrandom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/getrandom/compare/v0.2.15...v0.2.16)

---
updated-dependencies:
- dependency-name: getrandom
  dependency-version: 0.2.16
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-23 10:53:37 -04:00
dependabot[bot] 266ec108ac
build(deps): bump the symbolic group with 2 updates (#3880)
Bumps the symbolic group with 2 updates: [symbolic-common](https://github.com/getsentry/symbolic) and [symbolic-demangle](https://github.com/getsentry/symbolic).


Updates `symbolic-common` from 12.15.3 to 12.15.4
- [Release notes](https://github.com/getsentry/symbolic/releases)
- [Changelog](https://github.com/getsentry/symbolic/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/symbolic/compare/12.15.3...12.15.4)

Updates `symbolic-demangle` from 12.15.3 to 12.15.4
- [Release notes](https://github.com/getsentry/symbolic/releases)
- [Changelog](https://github.com/getsentry/symbolic/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/symbolic/compare/12.15.3...12.15.4)

---
updated-dependencies:
- dependency-name: symbolic-common
  dependency-version: 12.15.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: symbolic
- dependency-name: symbolic-demangle
  dependency-version: 12.15.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: symbolic
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-23 10:53:25 -04:00
dependabot[bot] c4ded832b8
build(deps): bump jiff from 0.2.9 to 0.2.10 (#3879)
Bumps [jiff](https://github.com/BurntSushi/jiff) from 0.2.9 to 0.2.10.
- [Release notes](https://github.com/BurntSushi/jiff/releases)
- [Changelog](https://github.com/BurntSushi/jiff/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/jiff/compare/jiff-static-0.2.9...jiff-static-0.2.10)

---
updated-dependencies:
- dependency-name: jiff
  dependency-version: 0.2.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-22 10:44:42 -04:00
dependabot[bot] dd38e6b45a
build(deps): bump tokio-metrics from 0.4.0 to 0.4.1 (#3878)
Bumps [tokio-metrics](https://github.com/tokio-rs/tokio-metrics) from 0.4.0 to 0.4.1.
- [Release notes](https://github.com/tokio-rs/tokio-metrics/releases)
- [Changelog](https://github.com/tokio-rs/tokio-metrics/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/tokio-metrics/compare/v0.4.0...v0.4.1)

---
updated-dependencies:
- dependency-name: tokio-metrics
  dependency-version: 0.4.1
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-22 10:43:19 -04:00
katelyn martin ad5952f021
nit(http/retry): remove extra body poll in tests (#3877)
the initial replay body, circa the usage of our "compatibility" layer
(4b53081, #3598), used to need an extra poll to confirm the absence of
trailers before it would report itself as reaching the end of the
stream. these tests were added in (afda8a7b3, #3583).

this was an artifact of how the compatibility middleware masked the
previous `poll_data()` and `poll_trailer()` methods behind a
forward-compatible `poll_frame()`- and `frame()`-oriented interface.

this commit removes these extra calls to `initial.frame().await`, now
that the initial body will report the end of stream without an extra
call to await a `None`.

X-ref: #3598
X-ref: #3583

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-04-21 09:54:12 -07:00
Oliver Gould d25bbf262a
chore(dev): introduce copilot instructions (#3873)
This introduces a GitHub Copilot instructions file under .github to guide AI-driven code generation and updates the devcontainer configuration accordingly.

The new instructions enforce Rust styling, error handling, and tracing conventions across the project. It ensures generated code passes `cargo fmt` and `clippy`, avoids unwraps, and uses structured logging.
2025-04-21 12:24:34 -04:00
Oliver Gould ce62199344
fix(client-policy): enable TLS hostnames via overrides (#3871)
In 65db3dd we enabled overriding the behavior to export TLS hostnames for
outbound traffic, but we omitted TLS hostname labels.

This change updates the tls module to mirror the http module's behavior.
2025-04-21 12:13:51 -04:00
dependabot[bot] 5ebea46ca2
build(deps): bump rand from 0.9.0 to 0.9.1 (#3872)
Bumps [rand](https://github.com/rust-random/rand) from 0.9.0 to 0.9.1.
- [Release notes](https://github.com/rust-random/rand/releases)
- [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/rand/compare/0.9.0...rand_core-0.9.1)

---
updated-dependencies:
- dependency-name: rand
  dependency-version: 0.9.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-21 07:59:03 -07:00
dependabot[bot] 0c343ce118
build(deps): bump jiff from 0.2.8 to 0.2.9 (#3876)
Bumps [jiff](https://github.com/BurntSushi/jiff) from 0.2.8 to 0.2.9.
- [Release notes](https://github.com/BurntSushi/jiff/releases)
- [Changelog](https://github.com/BurntSushi/jiff/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/jiff/compare/jiff-static-0.2.8...jiff-static-0.2.9)

---
updated-dependencies:
- dependency-name: jiff
  dependency-version: 0.2.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-21 09:24:57 -04:00
dependabot[bot] d3943c6833
build(deps): bump signal-hook-registry from 1.4.2 to 1.4.5 (#3875)
Bumps [signal-hook-registry](https://github.com/vorner/signal-hook) from 1.4.2 to 1.4.5.
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/signal-hook/compare/registry-v1.4.2...registry-v1.4.5)

---
updated-dependencies:
- dependency-name: signal-hook-registry
  dependency-version: 1.4.5
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-21 09:24:17 -04:00
dependabot[bot] 9135162dc8
build(deps): bump softprops/action-gh-release from 2.2.1 to 2.2.2 (#3874)
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.2.1 to 2.2.2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](c95fe14893...da05d55257)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: 2.2.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-21 09:23:36 -04:00
dependabot[bot] 2a34d40df4
build(deps): bump codecov/codecov-action from 5.4.0 to 5.4.2 (#3867)
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.4.0 to 5.4.2.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](0565863a31...ad3126e916)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-version: 5.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-17 21:24:48 -07:00
dependabot[bot] ea1aa58255
build(deps): bump libc from 0.2.171 to 0.2.172 (#3868)
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.171 to 0.2.172.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.172/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.171...0.2.172)

---
updated-dependencies:
- dependency-name: libc
  dependency-version: 0.2.172
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-17 21:24:26 -07:00
dependabot[bot] 46b90f8ae1
build(deps): bump proc-macro2 from 1.0.94 to 1.0.95 (#3869)
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.94 to 1.0.95.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.94...1.0.95)

---
updated-dependencies:
- dependency-name: proc-macro2
  dependency-version: 1.0.95
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-17 21:24:12 -07:00
dependabot[bot] 13ab2f4825
build(deps): bump jiff from 0.2.6 to 0.2.8 (#3866)
Bumps [jiff](https://github.com/BurntSushi/jiff) from 0.2.6 to 0.2.8.
- [Release notes](https://github.com/BurntSushi/jiff/releases)
- [Changelog](https://github.com/BurntSushi/jiff/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/jiff/compare/jiff-static-0.2.6...jiff-static-0.2.8)

---
updated-dependencies:
- dependency-name: jiff
  dependency-version: 0.2.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-14 10:14:56 -04:00
dependabot[bot] dc3a31c156
build(deps): bump anyhow from 1.0.97 to 1.0.98 (#3865)
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.97 to 1.0.98.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.97...1.0.98)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-version: 1.0.98
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-14 10:14:31 -04:00
dependabot[bot] c5e9098f3d
build(deps): bump data-encoding from 2.8.0 to 2.9.0 (#3864)
Bumps [data-encoding](https://github.com/ia0/data-encoding) from 2.8.0 to 2.9.0.
- [Commits](https://github.com/ia0/data-encoding/compare/v2.8.0...v2.9.0)

---
updated-dependencies:
- dependency-name: data-encoding
  dependency-version: 2.9.0
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-14 10:14:19 -04:00
katelyn martin 8a3a7aa072
chore(deps): group symbolic dependencies (#3863)
we use the `symbolic-common` and `symbolic-demangle` crates in our
dependency tree. these live in the same repo, here:
<https://github.com/getsentry/symbolic>

this commit introduces a "group" so that dependabot will upgrade them in
lockstep, rather than individually, such as in pull requests like
 #3853, #3852, #3857, #3858, or #3860.

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-04-11 16:07:49 -04:00
dependabot[bot] 6bd80d4898
build(deps): bump symbolic-common from 12.15.1 to 12.15.3 (#3862)
Bumps [symbolic-common](https://github.com/getsentry/symbolic) from 12.15.1 to 12.15.3.
- [Release notes](https://github.com/getsentry/symbolic/releases)
- [Changelog](https://github.com/getsentry/symbolic/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/symbolic/commits/12.15.3)

---
updated-dependencies:
- dependency-name: symbolic-common
  dependency-version: 12.15.3
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-11 10:04:42 -04:00
dependabot[bot] ab11b85fee
build(deps): bump cc from 1.2.18 to 1.2.19 (#3861)
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.2.18 to 1.2.19.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.18...cc-v1.2.19)

---
updated-dependencies:
- dependency-name: cc
  dependency-version: 1.2.19
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-11 10:04:26 -04:00
dependabot[bot] bd859fdb69
build(deps): bump symbolic-demangle from 12.15.1 to 12.15.3 (#3860)
Bumps [symbolic-demangle](https://github.com/getsentry/symbolic) from 12.15.1 to 12.15.3.
- [Release notes](https://github.com/getsentry/symbolic/releases)
- [Changelog](https://github.com/getsentry/symbolic/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/symbolic/commits/12.15.3)

---
updated-dependencies:
- dependency-name: symbolic-demangle
  dependency-version: 12.15.3
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-11 10:04:17 -04:00
dependabot[bot] 36f1fac274
build(deps): bump rustls from 0.23.25 to 0.23.26 in the rustls group (#3859)
Bumps the rustls group with 1 update: [rustls](https://github.com/rustls/rustls).


Updates `rustls` from 0.23.25 to 0.23.26
- [Release notes](https://github.com/rustls/rustls/releases)
- [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustls/rustls/compare/v/0.23.25...v/0.23.26)

---
updated-dependencies:
- dependency-name: rustls
  dependency-version: 0.23.26
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: rustls
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-11 10:04:03 -04:00
dependabot[bot] 2f345f9aea
build(deps): bump symbolic-common from 12.15.0 to 12.15.1 (#3858)
Bumps [symbolic-common](https://github.com/getsentry/symbolic) from 12.15.0 to 12.15.1.
- [Release notes](https://github.com/getsentry/symbolic/releases)
- [Changelog](https://github.com/getsentry/symbolic/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/symbolic/commits)

---
updated-dependencies:
- dependency-name: symbolic-common
  dependency-version: 12.15.1
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-10 09:55:34 -04:00
dependabot[bot] a9c123566f
build(deps): bump symbolic-demangle from 12.15.0 to 12.15.1 (#3857)
Bumps [symbolic-demangle](https://github.com/getsentry/symbolic) from 12.15.0 to 12.15.1.
- [Release notes](https://github.com/getsentry/symbolic/releases)
- [Changelog](https://github.com/getsentry/symbolic/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/symbolic/commits)

---
updated-dependencies:
- dependency-name: symbolic-demangle
  dependency-version: 12.15.1
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-10 09:55:24 -04:00
katelyn martin 6426c38906
fix(http/prom): record bodies when eos reached (#3856)
* chore(app/outbound): `linkerd-mock-http-body` test dependency

this adds a development dependency, so we can use this mock body type in
the outbound proxy's unit tests.

Signed-off-by: katelyn martin <kate@buoyant.io>

* chore(app/outbound): additional http route metrics tests

Signed-off-by: katelyn martin <kate@buoyant.io>

* chore(app/outbound): additional grpc route metrics tests

Signed-off-by: katelyn martin <kate@buoyant.io>

* fix(http/prom): record bodies when eos reached

this commit fixes a bug discovered by @alpeb, which was introduced in
proxy v2.288.0.

> The associated metric is `outbound_http_route_request_statuses_total`:
>
> ```
> $ linkerd dg proxy-metrics -n booksapp deploy/webapp|rg outbound_http_route_request_statuses_total.*authors
> outbound_http_route_request_statuses_total{parent_group="core",parent_kind="Service",parent_namespace="booksapp",parent_name="authors",parent_port="7001",parent_section_name="",route_group="",route_kind="default",route_namespace="",route_name="http",hostname="",http_status="204",error=""} 5
> outbound_http_route_request_statuses_total{parent_group="core",parent_kind="Service",parent_namespace="booksapp",parent_name="authors",parent_port="7001",parent_section_name="",route_group="",route_kind="default",route_namespace="",route_name="http",hostname="",http_status="201",error="UNKNOWN"} 5
> outbound_http_route_request_statuses_total{parent_group="core",parent_kind="Service",parent_namespace="booksapp",parent_name="authors",parent_port="7001",parent_section_name="",route_group="",route_kind="default",route_namespace="",route_name="http",hostname="",http_status="200",error="UNKNOWN"} 10
> ```
>
> The problem was introduced in `edge-25.3.4`, with the proxy `v2.288.0`.
> Before that the metrics looked like:
>
> ```
> $ linkerd dg proxy-metrics -n booksapp deploy/webapp|rg outbound_http_route_request_statuses_total.*authors
> outbound_http_route_request_statuses_total{parent_group="core",parent_kind="Service",parent_namespace="booksapp",parent_name="authors",parent_port="7001",parent_section_name="",route_group="",route_kind="default",route_namespace="",route_name="http",hostname="",http_status="200",error=""} 193
> outbound_http_route_request_statuses_total{parent_group="core",parent_kind="Service",parent_namespace="booksapp",parent_name="authors",parent_port="7001",parent_section_name="",route_group="",route_kind="default",route_namespace="",route_name="http",hostname="",http_status="204",error=""} 96
> outbound_http_route_request_statuses_total{parent_group="core",parent_kind="Service",parent_namespace="booksapp",parent_name="authors",parent_port="7001",parent_section_name="",route_group="",route_kind="default",route_namespace="",route_name="http",hostname="",http_status="201",error=""} 96
> ```
>
> So the difference is the non-empty value for `error=UNKNOWN` even
> when `https_status` is 2xx, which `linkerd viz stat-outbound`
> interprets as failed requests.

in #3086 we introduced a suite of route- and backend-level metrics. that
subsystem contains a body middleware that will report itself as having
reached the end-of-stream by delegating directly down to its inner
body's `is_end_stream()` hint.

this is roughly correct, but is slightly distinct from the actual
invariant: a `linkerd_http_prom::record_response::ResponseBody<B>` must
call its `end_stream` helper to classify the outcome and increment the
corresponding time series in the
`outbound_http_route_request_statuses_total` metric family.

in #3504 we upgraded our hyper dependency. while doing so, we neglected
to include a call to `end_stream` if a data frame is yielded and the
inner body reports itself as having reached the end-of-stream.

this meant that instrumented bodies would be polled until the end is
reached, but were being dropped before a `None` was encountered.

this commit fixes this issue in two ways, to be defensive:

* invoke `end_stream()` if a non-trailers frame is yielded, and the
  inner body now reports itself as having ended. this restores the
  behavior in place prior to #3504. see the relevant component of that
  diff, here:
  <https://github.com/linkerd/linkerd2-proxy/pull/3504/files#diff-45d0bc344f76c111551a8eaf5d3f0e0c22ee6e6836a626e46402a6ae3cbc0035L262-R274>

* rather than delegating to the inner `<B as Body>::is_end_stream()`
  method, report the end-of-stream being reached by inspecting whether
  or not the inner response state has been taken. this is the state that
  directly indicates whether or not the `ResponseBody<B>` middleware is
  finished.

X-ref: #3504
X-ref: #3086
X-ref: linkerd/linkerd2#8733
Signed-off-by: katelyn martin <kate@buoyant.io>

---------

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-04-09 15:30:55 -04:00
dependabot[bot] 985580f9b5
build(deps): bump miniz_oxide from 0.8.7 to 0.8.8 (#3855)
Bumps [miniz_oxide](https://github.com/Frommi/miniz_oxide) from 0.8.7 to 0.8.8.
- [Changelog](https://github.com/Frommi/miniz_oxide/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Frommi/miniz_oxide/compare/0.8.7...0.8.8)

---
updated-dependencies:
- dependency-name: miniz_oxide
  dependency-version: 0.8.8
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-09 10:59:41 -04:00
dependabot[bot] ad7fcf2dfb
build(deps): bump crossbeam-channel from 0.5.14 to 0.5.15 (#3854)
Bumps [crossbeam-channel](https://github.com/crossbeam-rs/crossbeam) from 0.5.14 to 0.5.15.
- [Release notes](https://github.com/crossbeam-rs/crossbeam/releases)
- [Changelog](https://github.com/crossbeam-rs/crossbeam/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crossbeam-rs/crossbeam/compare/crossbeam-channel-0.5.14...crossbeam-channel-0.5.15)

---
updated-dependencies:
- dependency-name: crossbeam-channel
  dependency-version: 0.5.15
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-09 10:59:35 -04:00
dependabot[bot] f6bbab6640
build(deps): bump symbolic-common from 12.14.1 to 12.15.0 (#3853)
Bumps [symbolic-common](https://github.com/getsentry/symbolic) from 12.14.1 to 12.15.0.
- [Release notes](https://github.com/getsentry/symbolic/releases)
- [Changelog](https://github.com/getsentry/symbolic/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/symbolic/commits)

---
updated-dependencies:
- dependency-name: symbolic-common
  dependency-version: 12.15.0
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-09 10:59:28 -04:00
dependabot[bot] 5f2f8fbacd
build(deps): bump symbolic-demangle from 12.14.1 to 12.15.0 (#3852)
Bumps [symbolic-demangle](https://github.com/getsentry/symbolic) from 12.14.1 to 12.15.0.
- [Release notes](https://github.com/getsentry/symbolic/releases)
- [Changelog](https://github.com/getsentry/symbolic/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/symbolic/commits)

---
updated-dependencies:
- dependency-name: symbolic-demangle
  dependency-version: 12.15.0
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-09 10:59:20 -04:00
dependabot[bot] 096f547ffb
build(deps): bump tj-actions/changed-files from 46.0.4 to 46.0.5 (#3851)
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 46.0.4 to 46.0.5.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](6cb76d07be...ed68ef82c0)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-version: 46.0.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-09 10:59:09 -04:00
dependabot[bot] abeb366500
build(deps): bump jiff from 0.2.5 to 0.2.6 (#3849)
Bumps [jiff](https://github.com/BurntSushi/jiff) from 0.2.5 to 0.2.6.
- [Release notes](https://github.com/BurntSushi/jiff/releases)
- [Changelog](https://github.com/BurntSushi/jiff/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/jiff/compare/jiff-static-0.2.5...jiff-static-0.2.6)

---
updated-dependencies:
- dependency-name: jiff
  dependency-version: 0.2.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-08 12:05:56 -04:00
dependabot[bot] c17a6acee8
build(deps): bump hostname from 0.4.0 to 0.4.1 (#3850)
Bumps [hostname](https://github.com/svartalf/hostname) from 0.4.0 to 0.4.1.
- [Release notes](https://github.com/svartalf/hostname/releases)
- [Changelog](https://github.com/djc/hostname/blob/main/CHANGELOG.md)
- [Commits](https://github.com/svartalf/hostname/commits)

---
updated-dependencies:
- dependency-name: hostname
  dependency-version: 0.4.1
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-08 12:05:23 -04:00
dependabot[bot] a9f7a9ae9d
build(deps): bump indexmap from 2.8.0 to 2.9.0 (#3848)
Bumps [indexmap](https://github.com/indexmap-rs/indexmap) from 2.8.0 to 2.9.0.
- [Changelog](https://github.com/indexmap-rs/indexmap/blob/main/RELEASES.md)
- [Commits](https://github.com/indexmap-rs/indexmap/compare/2.8.0...2.9.0)

---
updated-dependencies:
- dependency-name: indexmap
  dependency-version: 2.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-07 10:18:15 -04:00
dependabot[bot] 6de15c0a55
build(deps): bump tokio from 1.44.1 to 1.44.2 (#3847)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.44.1 to 1.44.2.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.44.1...tokio-1.44.2)

---
updated-dependencies:
- dependency-name: tokio
  dependency-version: 1.44.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-07 10:17:40 -04:00
dependabot[bot] 77837c5e45
build(deps): bump smallvec from 1.14.0 to 1.15.0 (#3846)
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.14.0 to 1.15.0.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.14.0...v1.15.0)

---
updated-dependencies:
- dependency-name: smallvec
  dependency-version: 1.15.0
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-07 10:17:17 -04:00
dependabot[bot] e6fee10099
build(deps): bump prettyplease from 0.2.31 to 0.2.32 (#3845)
Bumps [prettyplease](https://github.com/dtolnay/prettyplease) from 0.2.31 to 0.2.32.
- [Release notes](https://github.com/dtolnay/prettyplease/releases)
- [Commits](https://github.com/dtolnay/prettyplease/compare/0.2.31...0.2.32)

---
updated-dependencies:
- dependency-name: prettyplease
  dependency-version: 0.2.32
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-07 10:17:00 -04:00
dependabot[bot] 52a30254c7
build(deps): bump errno from 0.3.10 to 0.3.11 (#3844)
Bumps [errno](https://github.com/lambda-fairy/rust-errno) from 0.3.10 to 0.3.11.
- [Release notes](https://github.com/lambda-fairy/rust-errno/releases)
- [Changelog](https://github.com/lambda-fairy/rust-errno/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lambda-fairy/rust-errno/compare/v0.3.10...v0.3.11)

---
updated-dependencies:
- dependency-name: errno
  dependency-version: 0.3.11
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-04 12:25:48 -04:00
dependabot[bot] fee5b9734a
build(deps): bump cc from 1.2.17 to 1.2.18 (#3843)
Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.2.17 to 1.2.18.
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.17...cc-v1.2.18)

---
updated-dependencies:
- dependency-name: cc
  dependency-version: 1.2.18
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-04 15:55:47 +00:00
katelyn martin 33a177d054
chore(deps): add `tokio-boring` to dependabot group (#3842)
this adds `tokio-boring` to the `boring` group.

this will group these crates together and bump them in lockstep.

see, for example:
* #3838
* #3840

Signed-off-by: katelyn martin <kate@buoyant.io>
2025-04-04 11:44:05 -04:00
dependabot[bot] 6cc16b430e
build(deps): bump tokio-boring from 4.15.0 to 4.16.0 (#3838)
Bumps [tokio-boring](https://github.com/cloudflare/boring) from 4.15.0 to 4.16.0.
- [Release notes](https://github.com/cloudflare/boring/releases)
- [Changelog](https://github.com/cloudflare/boring/blob/master/RELEASE_NOTES)
- [Commits](https://github.com/cloudflare/boring/compare/v4.15.0...v4.16.0)

---
updated-dependencies:
- dependency-name: tokio-boring
  dependency-version: 4.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-04 11:34:16 -04:00
dependabot[bot] 18109a447e
build(deps): bump opentelemetry in the opentelemetry group (#3837)
Bumps the opentelemetry group with 1 update: [opentelemetry](https://github.com/open-telemetry/opentelemetry-rust).


Updates `opentelemetry` from 0.29.0 to 0.29.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-rust/releases)
- [Commits](https://github.com/open-telemetry/opentelemetry-rust/compare/opentelemetry-0.29.0...opentelemetry-0.29.1)

---
updated-dependencies:
- dependency-name: opentelemetry
  dependency-version: 0.29.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: opentelemetry
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-04 11:03:32 -04:00
dependabot[bot] 05b4ab7314
build(deps): bump miniz_oxide from 0.8.5 to 0.8.7 (#3841)
Bumps [miniz_oxide](https://github.com/Frommi/miniz_oxide) from 0.8.5 to 0.8.7.
- [Changelog](https://github.com/Frommi/miniz_oxide/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Frommi/miniz_oxide/compare/0.8.5...0.8.7)

---
updated-dependencies:
- dependency-name: miniz_oxide
  dependency-version: 0.8.7
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-04 10:51:20 -04:00
dependabot[bot] 483cd0d3ff
build(deps): bump tj-actions/changed-files (#3839)
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from b74df86ccb65173a8e33ba5492ac1a2ca6b216fd to 6cb76d07bee4c9772c6882c06c37837bf82a04d3.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](b74df86ccb...6cb76d07be)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-version: 6cb76d07bee4c9772c6882c06c37837bf82a04d3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-04 10:50:18 -04:00
dependabot[bot] 5444732bab
build(deps): bump flate2 from 1.1.0 to 1.1.1 (#3835)
Bumps [flate2](https://github.com/rust-lang/flate2-rs) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/rust-lang/flate2-rs/releases)
- [Commits](https://github.com/rust-lang/flate2-rs/compare/1.1.0...1.1.1)

---
updated-dependencies:
- dependency-name: flate2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-02 11:47:35 -04:00
249 changed files with 3048 additions and 3982 deletions

View File

@ -3,7 +3,7 @@
"build": {
"dockerfile": "Dockerfile",
"args": {
"DEV_VERSION": "v45",
"DEV_VERSION": "v47",
"http_proxy": "${localEnv:http_proxy}",
"https_proxy": "${localEnv:https_proxy}"
}
@ -23,7 +23,15 @@
"zxh404.vscode-proto3"
],
"settings": {
"files.insertFinalNewline": true
"files.insertFinalNewline": true,
"[git-commit]": {
"editor.rulers": [
72,
80
],
"editor.wordWrap": "wordWrapColumn",
"editor.wordWrapColumn": 80
}
}
}
},

156
.github/copilot-instructions.md vendored Normal file
View File

@ -0,0 +1,156 @@
# Linkerd2 Proxy Copilot Instructions
## Code Generation
- Code MUST pass `cargo fmt`.
- Code MUST pass `cargo clippy --all-targets --all-features -- -D warnings`.
- Markdown MUST pass `markdownlint-cli2`.
- Prefer `?` for error propagation.
- Avoid `unwrap()` and `expect()` outside tests.
- Use `tracing` crate macros (`tracing::info!`, etc.) for structured logging.
### Comments
Comments should explain **why**, not **what**. Focus on high-level rationale and
design intent at the function or block level, rather than line-by-line
descriptions.
- Use comments to capture:
- System-facing or interface-level concerns
- Key invariants, preconditions, and postconditions
- Design decisions and trade-offs
- Cross-references to architecture or design documentation
- Avoid:
- Line-by-line commentary explaining obvious code
- Restating what the code already clearly expresses
- For public APIs:
- Use `///` doc comments to describe the contract, behavior, parameters, and
usage examples
- For internal rationale:
- Use `//` comments sparingly to note non-obvious reasoning or edge-case
handling
- Be neutral and factual.
### Rust File Organization
For Rust source files, enforce this layout:
1. **Nonpublic imports**
- Declare all `use` statements for private/internal crates first.
- Group imports to avoid duplicates and do **not** add blank lines between
`use` statements.
2. **Module declarations**
- List all `mod` declarations.
3. **Reexports**
- Follow with `pub use` statements.
4. **Type definitions**
- Define `struct`, `enum`, `type`, and `trait` declarations.
- Sort by visibility: `pub` first, then `pub(crate)`, then private.
- Public types should be documented with `///` comments.
5. **Impl blocks**
- Implement methods in the same order as types above.
- Precede each types `impl` block with a header comment: `// === <TypeName> ===`
6. **Tests**
- End with a `tests` module guarded by `#[cfg(test)]`.
- If the infile test module exceeds 100lines, move it to
`tests/<filename>.rs` as a child integrationtest module.
## Test Generation
- Async tests MUST use `tokio::test`.
- Synchronous tests use `#[test]`.
- Include at least one failingedgecase test per public function.
- Use `tracing::info!` for logging in tests, usually in place of comments.
## Code Review
### Rust
- Point out any `unsafe` blocks and justify their safety.
- Flag functions >50 LOC for refactor suggestions.
- Highlight missing docs on public items.
### Markdown
- Use `markdownlint-cli2` to check for linting errors.
- Lines SHOULD be wrapped at 80 characters.
- Fenced code blocks MUST include a language identifier.
### Copilot Instructions
- Start each instruction with an imperative, presenttense verb.
- Keep each instruction under 120 characters.
- Provide one directive per instruction; avoid combining multiple ideas.
- Use "MUST" and "SHOULD" sparingly to emphasize critical rules.
- Avoid semicolons and complex punctuation within bullets.
- Do not reference external links, documents, or specific coding standards.
## Commit Messages
Commits follow the Conventional Commits specification:
### Subject
Subjects are in the form: `<type>[optional scope]: <description>`
- **Type**: feat, fix, docs, refactor, test, chore, ci, build, perf, revert
(others by agreement)
- **Scope**: optional, lowercase; may include `/` to denote submodules (e.g.
`http/detect`)
- **Description**: imperative mood, present tense, no trailing period
- MUST be less than 72 characters
- Omit needless words!
### Body
Non-trivial commits SHOULD include a body summarizing the change.
- Explain *why* the change was needed.
- Describe *what* was done at a high level.
- Use present-tense narration.
- Use complete sentences, paragraphs, and punctuation.
- Preceded by a blank line.
- Wrapped at 80 characters.
- Omit needless words!
### Breaking changes
If the change introduces a backwards-incompatible change, it MUST be marked as
such.
- Indicated by `!` after the type/scope (e.g. `feat(inbound)!: …`)
- Optionally including a `BREAKING CHANGE:` section in the footer explaining the
change in behavior.
### Examples
```text
feat(auth): add JWT refresh endpoint
There is currently no way to refresh a JWT token.
This exposes a new `/refresh` route that returns a refreshed token.
```
```text
feat(api)!: remove deprecated v1 routes
The `/v1/*` endpoints have been deprecated for a long time and are no
longer called by clients.
This change removes the `/v1/*` endpoints and all associated code,
including integration tests and documentation.
BREAKING CHANGE: The previously-deprecated `/v1/*` endpoints were removed.
```
## Pull Requests
- The subject line MUST be in the conventional commit format.
- Autogenerate a PR body summarizing the problem, solution, and verification steps.
- List breaking changes under a separate **Breaking Changes** heading.

View File

@ -21,6 +21,7 @@ updates:
groups:
boring:
patterns:
- "tokio-boring"
- "boring*"
futures:
patterns:
@ -43,6 +44,9 @@ updates:
- "tokio-rustls"
- "rustls*"
- "ring"
symbolic:
patterns:
- "symbolic-*"
tracing:
patterns:
- "tracing*"

View File

@ -22,13 +22,13 @@ permissions:
jobs:
build:
runs-on: ubuntu-24.04
container: ghcr.io/linkerd/dev:v45-rust
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
container: ghcr.io/linkerd/dev:v47-rust
timeout-minutes: 20
continue-on-error: true
steps:
- run: rustup toolchain install --profile=minimal beta
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- run: git config --global --add safe.directory "$PWD" # actions/runner#2033
- run: just toolchain=beta fetch
- run: just toolchain=beta build

View File

@ -21,11 +21,11 @@ env:
jobs:
meta:
timeout-minutes: 5
runs-on: ubuntu-24.04
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- id: changed
uses: tj-actions/changed-files@b74df86ccb65173a8e33ba5492ac1a2ca6b216fd
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c
with:
files: |
.codecov.yml
@ -40,19 +40,19 @@ jobs:
codecov:
needs: meta
if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || needs.meta.outputs.any_changed == 'true'
runs-on: ubuntu-24.04
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
timeout-minutes: 30
container:
image: docker://ghcr.io/linkerd/dev:v45-rust
image: docker://ghcr.io/linkerd/dev:v47-rust
options: --security-opt seccomp=unconfined # 🤷
env:
CXX: "/usr/bin/clang++-19"
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0
- run: cargo tarpaulin --locked --workspace --exclude=linkerd2-proxy --exclude=linkerd-transport-header --exclude=opencensus-proto --exclude=spire-proto --no-run
- run: cargo tarpaulin --locked --workspace --exclude=linkerd2-proxy --exclude=linkerd-transport-header --exclude=opencensus-proto --exclude=spire-proto --skip-clean --ignore-tests --no-fail-fast --out=Xml
# Some tests are especially flakey in coverage tests. That's fine. We
# only really care to measure how much of our codebase is covered.
continue-on-error: true
- uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574
- uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24

View File

@ -26,13 +26,13 @@ permissions:
jobs:
list-changed:
timeout-minutes: 3
runs-on: ubuntu-24.04
container: docker://rust:1.83.0
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
container: docker://rust:1.88.0
steps:
- run: apt update && apt install -y jo
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- run: git config --global --add safe.directory "$PWD" # actions/runner#2033
- uses: tj-actions/changed-files@b74df86ccb65173a8e33ba5492ac1a2ca6b216fd
- uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c
id: changed-files
- name: list changed crates
id: list-changed
@ -47,15 +47,15 @@ jobs:
build:
needs: [list-changed]
timeout-minutes: 40
runs-on: ubuntu-24.04
container: docker://rust:1.83.0
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
container: docker://rust:1.88.0
strategy:
matrix:
dir: ${{ fromJson(needs.list-changed.outputs.dirs) }}
steps:
- run: rustup toolchain add nightly
- run: cargo install cargo-fuzz
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- run: git config --global --add safe.directory "$PWD" # actions/runner#2033
- working-directory: ${{matrix.dir}}
run: cargo +nightly fetch

View File

@ -12,9 +12,9 @@ on:
jobs:
markdownlint:
timeout-minutes: 5
runs-on: ubuntu-24.04
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: DavidAnson/markdownlint-cli2-action@05f32210e84442804257b2a6f20b273450ec8265
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- uses: DavidAnson/markdownlint-cli2-action@992badcdf24e3b8eb7e87ff9287fe931bcb00c6e
with:
globs: "**/*.md"

View File

@ -22,13 +22,13 @@ permissions:
jobs:
build:
runs-on: ubuntu-24.04
container: ghcr.io/linkerd/dev:v45-rust
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
container: ghcr.io/linkerd/dev:v47-rust
timeout-minutes: 20
continue-on-error: true
steps:
- run: rustup toolchain install --profile=minimal nightly
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- run: git config --global --add safe.directory "$PWD" # actions/runner#2033
- run: just toolchain=nightly fetch
- run: just toolchain=nightly profile=release build

View File

@ -14,24 +14,24 @@ concurrency:
jobs:
meta:
timeout-minutes: 5
runs-on: ubuntu-24.04
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- id: build
uses: tj-actions/changed-files@b74df86ccb65173a8e33ba5492ac1a2ca6b216fd
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c
with:
files: |
.github/workflows/pr.yml
justfile
Dockerfile
- id: actions
uses: tj-actions/changed-files@b74df86ccb65173a8e33ba5492ac1a2ca6b216fd
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c
with:
files: |
.github/workflows/**
.devcontainer/*
- id: cargo
uses: tj-actions/changed-files@b74df86ccb65173a8e33ba5492ac1a2ca6b216fd
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c
with:
files_ignore: "Cargo.toml"
files: |
@ -40,7 +40,7 @@ jobs:
if: steps.cargo.outputs.any_changed == 'true'
run: ./.github/list-crates.sh ${{ steps.cargo.outputs.all_changed_files }}
- id: rust
uses: tj-actions/changed-files@b74df86ccb65173a8e33ba5492ac1a2ca6b216fd
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c
with:
files: |
**/*.rs
@ -57,7 +57,7 @@ jobs:
info:
timeout-minutes: 3
needs: meta
runs-on: ubuntu-24.04
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
steps:
- name: Info
run: |
@ -74,25 +74,25 @@ jobs:
actions:
needs: meta
if: needs.meta.outputs.actions_changed == 'true'
runs-on: ubuntu-24.04
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
steps:
- uses: linkerd/dev/actions/setup-tools@v45
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: linkerd/dev/actions/setup-tools@v47
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- run: just action-lint
- run: just action-dev-check
rust:
needs: meta
if: needs.meta.outputs.cargo_changed == 'true' || needs.meta.outputs.rust_changed == 'true'
runs-on: ubuntu-24.04
container: ghcr.io/linkerd/dev:v45-rust
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
container: ghcr.io/linkerd/dev:v47-rust
permissions:
contents: read
timeout-minutes: 20
steps:
- run: git config --global --add safe.directory "$PWD" # actions/runner#2033
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0
- run: just fetch
- run: cargo deny --all-features check bans licenses sources
- run: just check-fmt
@ -107,15 +107,15 @@ jobs:
needs: meta
if: needs.meta.outputs.cargo_changed == 'true'
timeout-minutes: 20
runs-on: ubuntu-24.04
container: ghcr.io/linkerd/dev:v45-rust
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
container: ghcr.io/linkerd/dev:v47-rust
strategy:
matrix:
crate: ${{ fromJson(needs.meta.outputs.cargo_crates) }}
steps:
- run: git config --global --add safe.directory "$PWD" # actions/runner#2033
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0
- run: just fetch
- run: just check-crate ${{ matrix.crate }}
@ -123,11 +123,11 @@ jobs:
needs: meta
if: needs.meta.outputs.cargo_changed == 'true' || needs.meta.outputs.rust_changed == 'true'
timeout-minutes: 20
runs-on: ubuntu-24.04
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
env:
WAIT_TIMEOUT: 2m
steps:
- uses: linkerd/dev/actions/setup-tools@v45
- uses: linkerd/dev/actions/setup-tools@v47
- name: scurl https://run.linkerd.io/install-edge | sh
run: |
scurl https://run.linkerd.io/install-edge | sh
@ -136,7 +136,7 @@ jobs:
tag=$(linkerd version --client --short)
echo "linkerd $tag"
echo "LINKERD_TAG=$tag" >> "$GITHUB_ENV"
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- run: just docker
- run: just k3d-create
- run: just k3d-load-linkerd
@ -149,7 +149,7 @@ jobs:
timeout-minutes: 3
needs: [meta, actions, rust, rust-crates, linkerd-install]
if: always()
runs-on: ubuntu-24.04
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
permissions:
contents: write
@ -168,7 +168,7 @@ jobs:
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
run: exit 1
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
if: needs.meta.outputs.is_dependabot == 'true' && needs.meta.outputs.any_changed == 'true'
- name: "Merge dependabot changes"
if: needs.meta.outputs.is_dependabot == 'true' && needs.meta.outputs.any_changed == 'true'

View File

@ -13,7 +13,7 @@ concurrency:
jobs:
last-release:
if: github.repository == 'linkerd/linkerd2-proxy' # Don't run this in forks.
runs-on: ubuntu-24.04
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
timeout-minutes: 5
env:
GH_REPO: ${{ github.repository }}
@ -41,10 +41,10 @@ jobs:
last-commit:
needs: last-release
runs-on: ubuntu-24.04
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
timeout-minutes: 5
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- name: Check if the most recent commit is after the last release
id: recency
env:
@ -62,7 +62,7 @@ jobs:
trigger-release:
needs: [last-release, last-commit]
if: needs.last-release.outputs.recent == 'false' && needs.last-commit.outputs.after-release == 'true'
runs-on: ubuntu-24.04
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
timeout-minutes: 5
permissions:
actions: write

View File

@ -46,6 +46,7 @@ on:
default: true
env:
CARGO: "cargo auditable"
CARGO_INCREMENTAL: 0
CARGO_NET_RETRY: 10
RUSTFLAGS: "-D warnings -A deprecated --cfg tokio_unstable"
@ -58,9 +59,25 @@ concurrency:
jobs:
meta:
timeout-minutes: 5
runs-on: ubuntu-24.04
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
steps:
- id: meta
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
if: github.event_name == 'pull_request'
- id: workflow
if: github.event_name == 'pull_request'
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c
with:
files: |
.github/workflows/release.yml
- id: build
if: github.event_name == 'pull_request'
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c
with:
files: |
justfile
Cargo.toml
- id: version
env:
VERSION: ${{ inputs.version }}
shell: bash
@ -68,47 +85,45 @@ jobs:
set -euo pipefail
shopt -s extglob
if [[ "$GITHUB_EVENT_NAME" == pull_request ]]; then
echo version="0.0.0-test.${GITHUB_SHA:0:7}"
echo archs='["amd64"]'
echo oses='["linux"]'
echo version="0.0.0-test.${GITHUB_SHA:0:7}" >> "$GITHUB_OUTPUT"
exit 0
fi >> "$GITHUB_OUTPUT"
fi
if ! [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z-]+)?(\+[0-9A-Za-z-]+)?$ ]]; then
echo "Invalid version: $VERSION" >&2
exit 1
fi
( echo version="${VERSION#v}"
echo archs='["amd64", "arm64", "arm"]'
echo version="${VERSION#v}" >> "$GITHUB_OUTPUT"
- id: platform
shell: bash
env:
WORKFLOW_CHANGED: ${{ steps.workflow.outputs.any_changed }}
run: |
if [[ "$GITHUB_EVENT_NAME" == pull_request && "$WORKFLOW_CHANGED" != 'true' ]]; then
( echo archs='["amd64"]'
echo oses='["linux"]' ) >> "$GITHUB_OUTPUT"
exit 0
fi
( echo archs='["amd64", "arm64"]'
echo oses='["linux", "windows"]'
) >> "$GITHUB_OUTPUT"
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
if: github.event_name == 'pull_request'
- id: changed
if: github.event_name == 'pull_request'
uses: tj-actions/changed-files@b74df86ccb65173a8e33ba5492ac1a2ca6b216fd
with:
files: |
.github/workflows/release.yml
justfile
Cargo.toml
outputs:
archs: ${{ steps.meta.outputs.archs }}
oses: ${{ steps.meta.outputs.oses }}
version: ${{ steps.meta.outputs.version }}
package: ${{ github.event_name == 'workflow_dispatch' || steps.changed.outputs.any_changed == 'true' }}
archs: ${{ steps.platform.outputs.archs }}
oses: ${{ steps.platform.outputs.oses }}
version: ${{ steps.version.outputs.version }}
package: ${{ github.event_name == 'workflow_dispatch' || steps.build.outputs.any_changed == 'true' || steps.workflow.outputs.any_changed == 'true' }}
profile: ${{ inputs.profile || 'release' }}
publish: ${{ inputs.publish }}
ref: ${{ inputs.ref || github.sha }}
tag: "${{ inputs.tag-prefix || 'release/' }}v${{ steps.meta.outputs.version }}"
tag: "${{ inputs.tag-prefix || 'release/' }}v${{ steps.version.outputs.version }}"
prerelease: ${{ inputs.prerelease }}
draft: ${{ inputs.draft }}
latest: ${{ inputs.latest }}
info:
needs: meta
runs-on: ubuntu-24.04
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
timeout-minutes: 3
steps:
- name: Inputs
@ -134,15 +149,13 @@ jobs:
exclude:
- os: windows
arch: arm64
- os: windows
arch: arm
# If we're not actually building on a release tag, don't short-circuit on
# errors. This helps us know whether a failure is platform-specific.
continue-on-error: ${{ needs.meta.outputs.publish != 'true' }}
runs-on: ubuntu-24.04
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
timeout-minutes: 40
container: docker://ghcr.io/linkerd/dev:v45-rust-musl
container: docker://ghcr.io/linkerd/dev:v47-rust-musl
env:
LINKERD2_PROXY_VENDOR: ${{ github.repository_owner }}
LINKERD2_PROXY_VERSION: ${{ needs.meta.outputs.version }}
@ -150,15 +163,19 @@ jobs:
# TODO: add to dev image
- name: Install MiniGW
if: matrix.os == 'windows'
run: apt-get update && apt-get install mingw-w64 -y
run: apt-get update && apt-get install -y mingw-w64
- name: Install cross compilation toolchain
if: matrix.arch == 'arm64'
run: apt-get update && apt-get install -y binutils-aarch64-linux-gnu
- name: Configure git
run: git config --global --add safe.directory "$PWD" # actions/runner#2033
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
with:
ref: ${{ needs.meta.outputs.ref }}
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0
with:
key: ${{ matrix.arch }}
key: ${{ matrix.os }}-${{ matrix.arch }}
- run: just fetch
- run: just arch=${{ matrix.arch }} libc=${{ matrix.libc }} os=${{ matrix.os }} rustup
- run: just arch=${{ matrix.arch }} libc=${{ matrix.libc }} os=${{ matrix.os }} profile=${{ needs.meta.outputs.profile }} build
@ -170,7 +187,7 @@ jobs:
publish:
needs: [meta, package]
runs-on: ubuntu-24.04
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
timeout-minutes: 5
permissions:
actions: write
@ -187,13 +204,13 @@ jobs:
git config --global user.name "$GITHUB_USERNAME"
git config --global user.email "$GITHUB_USERNAME"@users.noreply.github.com
# Tag the release.
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
with:
token: ${{ secrets.LINKERD2_PROXY_GITHUB_TOKEN || github.token }}
ref: ${{ needs.meta.outputs.ref }}
- run: git tag -a -m "$VERSION" "$TAG"
# Fetch the artifacts.
- uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
path: artifacts
- run: du -h artifacts/**/*
@ -201,7 +218,7 @@ jobs:
- if: needs.meta.outputs.publish == 'true'
run: git push origin "$TAG"
- if: needs.meta.outputs.publish == 'true'
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda
uses: softprops/action-gh-release@72f2c25fcb47643c292f7107632f7a47c1df5cd8
with:
name: ${{ env.VERSION }}
tag_name: ${{ env.TAG }}
@ -225,7 +242,7 @@ jobs:
needs: publish
if: always()
timeout-minutes: 3
runs-on: ubuntu-24.04
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
steps:
- name: Results
run: |

View File

@ -13,8 +13,8 @@ on:
jobs:
sh-lint:
timeout-minutes: 5
runs-on: ubuntu-24.04
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
steps:
- uses: linkerd/dev/actions/setup-tools@v45
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: linkerd/dev/actions/setup-tools@v47
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- run: just sh-lint

View File

@ -13,10 +13,10 @@ permissions:
jobs:
devcontainer:
runs-on: ubuntu-24.04
container: ghcr.io/linkerd/dev:v45-rust
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
container: ghcr.io/linkerd/dev:v47-rust
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- run: git config --global --add safe.directory "$PWD" # actions/runner#2033
- run: |
VERSION_REGEX='channel = "([0-9]+\.[0-9]+\.[0-9]+)"'
@ -35,10 +35,10 @@ jobs:
workflows:
runs-on: ubuntu-24.04
runs-on: ${{ vars.LINKERD2_PROXY_RUNNER || 'ubuntu-24.04' }}
steps:
- uses: linkerd/dev/actions/setup-tools@v45
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: linkerd/dev/actions/setup-tools@v47
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- shell: bash
run: |
VERSION_REGEX='channel = "([0-9]+\.[0-9]+\.[0-9]+)"'

1226
Cargo.lock

File diff suppressed because it is too large Load Diff

View File

@ -42,8 +42,6 @@ members = [
"linkerd/idle-cache",
"linkerd/io",
"linkerd/meshtls",
"linkerd/meshtls/boring",
"linkerd/meshtls/rustls",
"linkerd/meshtls/verifier",
"linkerd/metrics",
"linkerd/mock/http-body",
@ -71,6 +69,7 @@ members = [
"linkerd/reconnect",
"linkerd/retry",
"linkerd/router",
"linkerd/rustls",
"linkerd/service-profiles",
"linkerd/signal",
"linkerd/stack",
@ -115,14 +114,14 @@ prost = { version = "0.13" }
prost-build = { version = "0.13", default-features = false }
prost-types = { version = "0.13" }
tokio-rustls = { version = "0.26", default-features = false, features = [
"ring",
"logging",
] }
tonic = { version = "0.12", default-features = false }
tonic-build = { version = "0.12", default-features = false }
tonic = { version = "0.13", default-features = false }
tonic-build = { version = "0.13", default-features = false }
tower = { version = "0.5", default-features = false }
tower-service = { version = "0.3" }
tower-test = { version = "0.4" }
tracing = { version = "0.1" }
[workspace.dependencies.http-body-util]
version = "0.1.3"
@ -135,4 +134,4 @@ default-features = false
features = ["tokio", "tracing"]
[workspace.dependencies.linkerd2-proxy-api]
version = "0.16.0"
version = "0.17.0"

View File

@ -3,7 +3,7 @@
# This is intended **DEVELOPMENT ONLY**, i.e. so that proxy developers can
# easily test the proxy in the context of the larger `linkerd2` project.
ARG RUST_IMAGE=ghcr.io/linkerd/dev:v45-rust
ARG RUST_IMAGE=ghcr.io/linkerd/dev:v47-rust
# Use an arbitrary ~recent edge release image to get the proxy
# identity-initializing and linkerd-await wrappers.
@ -14,11 +14,16 @@ FROM $LINKERD2_IMAGE as linkerd2
FROM --platform=$BUILDPLATFORM $RUST_IMAGE as fetch
ARG PROXY_FEATURES=""
ARG TARGETARCH="amd64"
RUN apt-get update && \
apt-get install -y time && \
if [[ "$PROXY_FEATURES" =~ .*meshtls-boring.* ]] ; then \
apt-get install -y golang ; \
fi && \
case "$TARGETARCH" in \
amd64) true ;; \
arm64) apt-get install --no-install-recommends -y binutils-aarch64-linux-gnu ;; \
esac && \
rm -rf /var/lib/apt/lists/*
ENV CARGO_NET_RETRY=10
@ -33,7 +38,6 @@ RUN --mount=type=cache,id=cargo,target=/usr/local/cargo/registry \
FROM fetch as build
ENV CARGO_INCREMENTAL=0
ENV RUSTFLAGS="-D warnings -A deprecated --cfg tokio_unstable"
ARG TARGETARCH="amd64"
ARG PROFILE="release"
ARG LINKERD2_PROXY_VERSION=""
ARG LINKERD2_PROXY_VENDOR=""

View File

@ -86,8 +86,9 @@ minutes to review our [code of conduct][coc].
We test our code by way of fuzzing and this is described in [FUZZING.md](/docs/FUZZING.md).
A third party security audit focused on fuzzing Linkerd2-proxy was performed by
Ada Logics in 2021. The full report is available
[here](/docs/reports/linkerd2-proxy-fuzzing-report.pdf).
Ada Logics in 2021. The
[full report](/docs/reports/linkerd2-proxy-fuzzing-report.pdf) can be found in
the `docs/reports/` directory.
## License

View File

@ -2,7 +2,6 @@
targets = [
{ triple = "x86_64-unknown-linux-gnu" },
{ triple = "aarch64-unknown-linux-gnu" },
{ triple = "armv7-unknown-linux-gnu" },
]
[advisories]
@ -26,17 +25,12 @@ confidence-threshold = 0.8
exceptions = [
{ allow = [
"ISC",
"MIT",
"OpenSSL",
], name = "ring", version = "*" },
]
[[licenses.clarify]]
name = "ring"
version = "*"
expression = "MIT AND ISC AND OpenSSL"
license-files = [
{ path = "LICENSE", hash = 0xbd0eed23 },
], name = "aws-lc-sys", version = "*" },
{ allow = [
"ISC",
"OpenSSL",
], name = "aws-lc-fips-sys", version = "*" },
]
[bans]
@ -48,6 +42,8 @@ deny = [
{ name = "rustls", wrappers = ["tokio-rustls"] },
# rustls-webpki should be used instead.
{ name = "webpki" },
# aws-lc-rs should be used instead.
{ name = "ring" }
]
skip = [
# `linkerd-trace-context`, `rustls-pemfile` and `tonic` depend on `base64`
@ -66,6 +62,10 @@ skip-tree = [
{ name = "rustix", version = "0.38" },
# `pprof` uses a number of old dependencies. for now, we skip its subtree.
{ name = "pprof" },
# aws-lc-rs uses a slightly outdated version of bindgen
{ name = "bindgen", version = "0.69.5" },
# socket v0.6 is still propagating through the ecosystem
{ name = "socket2", version = "0.5" },
]
[sources]

View File

@ -12,9 +12,12 @@ engine.
We place the fuzz tests into folders within the individual crates that the fuzz
tests target. For example, we have a fuzz test that that target the crate
`/linkerd/addr` and the code in `/linkerd/addr/src` and thus the fuzz test that
targets this crate is put in `/linkerd/addr/fuzz`. The folder set up we use for
each of the fuzz tests is automatically generated by `cargo fuzz init`
(described [here](https://github.com/rust-fuzz/cargo-fuzz#cargo-fuzz-init)).
targets this crate is put in `/linkerd/addr/fuzz`.
The folder structure for each of the fuzz tests is automatically generated by
`cargo fuzz init`. See cargo fuzz's
[`README.md`](https://github.com/rust-fuzz/cargo-fuzz#cargo-fuzz-init) for more
information.
### Fuzz targets
@ -96,6 +99,5 @@ unit-test-like fuzzers, but are essentially just more substantial in nature. The
idea behind these fuzzers is to test end-to-end concepts more so than individual
components of the proxy.
The inbound fuzzer
[here](/linkerd/app/inbound/fuzz/fuzz_targets/fuzz_target_1.rs) is an example of
this.
The [inbound fuzzer](/linkerd/app/inbound/fuzz/fuzz_targets/fuzz_target_1.rs)
is an example of this.

View File

@ -18,6 +18,10 @@ features := ""
export LINKERD2_PROXY_VERSION := env_var_or_default("LINKERD2_PROXY_VERSION", "0.0.0-dev" + `git rev-parse --short HEAD`)
export LINKERD2_PROXY_VENDOR := env_var_or_default("LINKERD2_PROXY_VENDOR", `whoami` + "@" + `hostname`)
# TODO: these variables will be included in dev v48
export AWS_LC_SYS_CFLAGS_aarch64_unknown_linux_gnu := env_var_or_default("AWS_LC_SYS_CFLAGS_aarch64_unknown_linux_gnu", "-fuse-ld=/usr/aarch64-linux-gnu/bin/ld")
export AWS_LC_SYS_CFLAGS_aarch64_unknown_linux_musl := env_var_or_default("AWS_LC_SYS_CFLAGS_aarch64_unknown_linux_musl", "-fuse-ld=/usr/aarch64-linux-gnu/bin/ld")
# The version name to use for packages.
package_version := "v" + LINKERD2_PROXY_VERSION
@ -26,7 +30,7 @@ docker-repo := "localhost/linkerd/proxy"
docker-tag := `git rev-parse --abbrev-ref HEAD | sed 's|/|.|g'` + "." + `git rev-parse --short HEAD`
docker-image := docker-repo + ":" + docker-tag
# The architecture name to use for packages. Either 'amd64', 'arm64', or 'arm'.
# The architecture name to use for packages. Either 'amd64' or 'arm64'.
arch := "amd64"
# The OS name to use for packages. Either 'linux' or 'windows'.
os := "linux"
@ -39,8 +43,6 @@ _target := if os + '-' + arch == "linux-amd64" {
"x86_64-unknown-linux-" + libc
} else if os + '-' + arch == "linux-arm64" {
"aarch64-unknown-linux-" + libc
} else if os + '-' + arch == "linux-arm" {
"armv7-unknown-linux-" + libc + "eabihf"
} else if os + '-' + arch == "windows-amd64" {
"x86_64-pc-windows-" + libc
} else {
@ -139,7 +141,7 @@ _strip:
_package_bin := _package_dir / "bin" / "linkerd2-proxy"
# XXX {aarch64,arm}-musl builds do not enable PIE, so we use target-specific
# XXX aarch64-musl builds do not enable PIE, so we use target-specific
# files to document those differences.
_expected_checksec := '.checksec' / arch + '-' + libc + '.json'

View File

@ -13,7 +13,7 @@ cargo-fuzz = true
libfuzzer-sys = "0.4"
linkerd-addr = { path = ".." }
linkerd-tracing = { path = "../../tracing", features = ["ansi"] }
tracing = "0.1"
tracing = { workspace = true }
# Prevent this from interfering with workspaces
[workspace]

View File

@ -100,15 +100,11 @@ impl Addr {
// them ourselves.
format!("[{}]", a.ip())
};
http::uri::Authority::from_str(&ip).unwrap_or_else(|err| {
panic!("SocketAddr ({}) must be valid authority: {}", a, err)
})
}
Addr::Socket(a) => {
http::uri::Authority::from_str(&a.to_string()).unwrap_or_else(|err| {
panic!("SocketAddr ({}) must be valid authority: {}", a, err)
})
http::uri::Authority::from_str(&ip)
.unwrap_or_else(|err| panic!("SocketAddr ({a}) must be valid authority: {err}"))
}
Addr::Socket(a) => http::uri::Authority::from_str(&a.to_string())
.unwrap_or_else(|err| panic!("SocketAddr ({a}) must be valid authority: {err}")),
}
}
@ -265,14 +261,14 @@ mod tests {
];
for (host, expected_result) in cases {
let a = Addr::from_str(host).unwrap();
assert_eq!(a.is_loopback(), *expected_result, "{:?}", host)
assert_eq!(a.is_loopback(), *expected_result, "{host:?}")
}
}
fn test_to_http_authority(cases: &[&str]) {
let width = cases.iter().map(|s| s.len()).max().unwrap_or(0);
for host in cases {
print!("trying {:1$} ... ", host, width);
print!("trying {host:width$} ... ");
Addr::from_str(host).unwrap().to_http_authority();
println!("ok");
}

View File

@ -36,4 +36,4 @@ tokio = { version = "1", features = ["rt"] }
tokio-stream = { version = "0.1", features = ["time", "sync"] }
tonic = { workspace = true, default-features = false, features = ["prost"] }
tower = { workspace = true }
tracing = "0.1"
tracing = { workspace = true }

View File

@ -22,12 +22,12 @@ http-body = { workspace = true }
http-body-util = { workspace = true }
hyper = { workspace = true, features = ["http1", "http2"] }
futures = { version = "0.3", default-features = false }
pprof = { version = "0.14", optional = true, features = ["prost-codec"] }
pprof = { version = "0.15", optional = true, features = ["prost-codec"] }
serde = "1"
serde_json = "1"
thiserror = "2"
tokio = { version = "1", features = ["macros", "sync", "parking_lot"] }
tracing = "0.1"
tracing = { workspace = true }
linkerd-app-core = { path = "../core" }
linkerd-app-inbound = { path = "../inbound" }

View File

@ -13,7 +13,7 @@
use futures::future::{self, TryFutureExt};
use http::StatusCode;
use linkerd_app_core::{
metrics::{self as metrics, FmtMetrics},
metrics::{self as metrics, legacy::FmtMetrics},
proxy::http::{Body, BoxBody, ClientHandle, Request, Response},
trace, Error, Result,
};
@ -32,7 +32,7 @@ pub use self::readiness::{Latch, Readiness};
#[derive(Clone)]
pub struct Admin<M> {
metrics: metrics::Serve<M>,
metrics: metrics::legacy::Serve<M>,
tracing: trace::Handle,
ready: Readiness,
shutdown_tx: mpsc::UnboundedSender<()>,
@ -52,7 +52,7 @@ impl<M> Admin<M> {
tracing: trace::Handle,
) -> Self {
Self {
metrics: metrics::Serve::new(metrics),
metrics: metrics::legacy::Serve::new(metrics),
ready,
shutdown_tx,
enable_shutdown,

View File

@ -27,7 +27,7 @@ where
.into_body()
.collect()
.await
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?
.map_err(io::Error::other)?
.aggregate();
match level.set_from(body.chunk()) {
Ok(_) => mk_rsp(StatusCode::NO_CONTENT, BoxBody::empty()),

View File

@ -2,7 +2,7 @@ use linkerd_app_core::{
classify,
config::ServerConfig,
drain, errors, identity,
metrics::{self, FmtMetrics},
metrics::{self, legacy::FmtMetrics},
proxy::http,
serve,
svc::{self, ExtractParam, InsertParam, Param},
@ -214,7 +214,7 @@ impl Config {
impl Param<transport::labels::Key> for Tcp {
fn param(&self) -> transport::labels::Key {
transport::labels::Key::inbound_server(
self.tls.clone(),
self.tls.as_ref().map(|t| t.labels()),
self.addr.into(),
self.policy.server_label(),
)
@ -272,7 +272,7 @@ impl Param<metrics::ServerLabel> for Http {
impl Param<metrics::EndpointLabels> for Permitted {
fn param(&self) -> metrics::EndpointLabels {
metrics::InboundEndpointLabels {
tls: self.http.tcp.tls.clone(),
tls: self.http.tcp.tls.as_ref().map(|t| t.labels()),
authority: None,
target_addr: self.http.tcp.addr.into(),
policy: self.permit.labels.clone(),

View File

@ -13,31 +13,23 @@ independently of the inbound and outbound proxy logic.
"""
[dependencies]
bytes = { workspace = true }
drain = { workspace = true, features = ["retain"] }
http = { workspace = true }
http-body = { workspace = true }
http-body-util = { workspace = true }
hyper = { workspace = true, features = ["http1", "http2"] }
hyper-util = { workspace = true }
futures = { version = "0.3", default-features = false }
ipnet = "2.11"
prometheus-client = { workspace = true }
regex = "1"
serde_json = "1"
thiserror = "2"
tokio = { version = "1", features = ["macros", "sync", "parking_lot"] }
tokio-stream = { version = "0.1", features = ["time"] }
tonic = { workspace = true, default-features = false, features = ["prost"] }
tracing = "0.1"
parking_lot = "0.12"
tracing = { workspace = true }
pin-project = "1"
linkerd-addr = { path = "../../addr" }
linkerd-conditional = { path = "../../conditional" }
linkerd-dns = { path = "../../dns" }
linkerd-duplex = { path = "../../duplex" }
linkerd-errno = { path = "../../errno" }
linkerd-error = { path = "../../error" }
linkerd-error-respond = { path = "../../error-respond" }
linkerd-exp-backoff = { path = "../../exp-backoff" }
@ -64,6 +56,7 @@ linkerd-proxy-tcp = { path = "../../proxy/tcp" }
linkerd-proxy-transport = { path = "../../proxy/transport" }
linkerd-reconnect = { path = "../../reconnect" }
linkerd-router = { path = "../../router" }
linkerd-rustls = { path = "../../rustls" }
linkerd-service-profiles = { path = "../../service-profiles" }
linkerd-stack = { path = "../../stack" }
linkerd-stack-metrics = { path = "../../stack/metrics" }
@ -83,5 +76,6 @@ features = ["make", "spawn-ready", "timeout", "util", "limit"]
semver = "1"
[dev-dependencies]
bytes = { workspace = true }
http-body-util = { workspace = true }
linkerd-mock-http-body = { path = "../../mock/http-body" }
quickcheck = { version = "1", default-features = false }

View File

@ -4,11 +4,11 @@ fn set_env(name: &str, cmd: &mut Command) {
let value = match cmd.output() {
Ok(output) => String::from_utf8(output.stdout).unwrap(),
Err(err) => {
println!("cargo:warning={}", err);
println!("cargo:warning={err}");
"".to_string()
}
};
println!("cargo:rustc-env={}={}", name, value);
println!("cargo:rustc-env={name}={value}");
}
fn version() -> String {

View File

@ -1,5 +1,4 @@
use crate::profiles;
pub use classify::gate;
use linkerd_error::Error;
use linkerd_proxy_client_policy as client_policy;
use linkerd_proxy_http::{classify, HasH2Reason, ResponseTimeoutError};
@ -214,7 +213,7 @@ fn h2_error(err: &Error) -> String {
if let Some(reason) = err.h2_reason() {
// This should output the error code in the same format as the spec,
// for example: PROTOCOL_ERROR
format!("h2({:?})", reason)
format!("h2({reason:?})")
} else {
trace!("classifying found non-h2 error: {:?}", err);
String::from("unclassified")

View File

@ -101,7 +101,7 @@ impl Config {
identity: identity::NewClient,
) -> svc::ArcNewService<
(),
svc::BoxCloneSyncService<http::Request<tonic::body::BoxBody>, http::Response<RspBody>>,
svc::BoxCloneSyncService<http::Request<tonic::body::Body>, http::Response<RspBody>>,
> {
let addr = self.addr;
tracing::trace!(%addr, "Building");

View File

@ -25,6 +25,7 @@ pub mod metrics;
pub mod proxy;
pub mod serve;
pub mod svc;
pub mod tls_info;
pub mod transport;
pub use self::build_info::{BuildInfo, BUILD_INFO};

View File

@ -54,7 +54,7 @@ pub struct Proxy {
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ControlLabels {
addr: Addr,
server_id: tls::ConditionalClientTls,
server_id: tls::ConditionalClientTlsLabels,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
@ -65,7 +65,7 @@ pub enum EndpointLabels {
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct InboundEndpointLabels {
pub tls: tls::ConditionalServerTls,
pub tls: tls::ConditionalServerTlsLabels,
pub authority: Option<http::uri::Authority>,
pub target_addr: SocketAddr,
pub policy: RouteAuthzLabels,
@ -98,7 +98,7 @@ pub struct RouteAuthzLabels {
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct OutboundEndpointLabels {
pub server_id: tls::ConditionalClientTls,
pub server_id: tls::ConditionalClientTlsLabels,
pub authority: Option<http::uri::Authority>,
pub labels: Option<String>,
pub zone_locality: OutboundZoneLocality,
@ -155,10 +155,10 @@ where
I: Iterator<Item = (&'i String, &'i String)>,
{
let (k0, v0) = labels_iter.next()?;
let mut out = format!("{}_{}=\"{}\"", prefix, k0, v0);
let mut out = format!("{prefix}_{k0}=\"{v0}\"");
for (k, v) in labels_iter {
write!(out, ",{}_{}=\"{}\"", prefix, k, v).expect("label concat must succeed");
write!(out, ",{prefix}_{k}=\"{v}\"").expect("label concat must succeed");
}
Some(out)
}
@ -166,7 +166,7 @@ where
// === impl Metrics ===
impl Metrics {
pub fn new(retain_idle: Duration) -> (Self, impl FmtMetrics + Clone + Send + 'static) {
pub fn new(retain_idle: Duration) -> (Self, impl legacy::FmtMetrics + Clone + Send + 'static) {
let (control, control_report) = {
let m = http_metrics::Requests::<ControlLabels, Class>::default();
let r = m.clone().into_report(retain_idle).with_prefix("control");
@ -223,6 +223,7 @@ impl Metrics {
opentelemetry,
};
use legacy::FmtMetrics as _;
let report = endpoint_report
.and_report(profile_route_report)
.and_report(retry_report)
@ -243,15 +244,17 @@ impl svc::Param<ControlLabels> for control::ControlAddr {
fn param(&self) -> ControlLabels {
ControlLabels {
addr: self.addr.clone(),
server_id: self.identity.clone(),
server_id: self.identity.as_ref().map(tls::ClientTls::labels),
}
}
}
impl FmtLabels for ControlLabels {
impl legacy::FmtLabels for ControlLabels {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "addr=\"{}\",", self.addr)?;
TlsConnect::from(&self.server_id).fmt_labels(f)?;
let Self { addr, server_id } = self;
write!(f, "addr=\"{addr}\",")?;
TlsConnect::from(server_id).fmt_labels(f)?;
Ok(())
}
@ -279,13 +282,19 @@ impl ProfileRouteLabels {
}
}
impl FmtLabels for ProfileRouteLabels {
impl legacy::FmtLabels for ProfileRouteLabels {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.direction.fmt_labels(f)?;
write!(f, ",dst=\"{}\"", self.addr)?;
let Self {
direction,
addr,
labels,
} = self;
if let Some(labels) = self.labels.as_ref() {
write!(f, ",{}", labels)?;
direction.fmt_labels(f)?;
write!(f, ",dst=\"{addr}\"")?;
if let Some(labels) = labels.as_ref() {
write!(f, ",{labels}")?;
}
Ok(())
@ -306,7 +315,7 @@ impl From<OutboundEndpointLabels> for EndpointLabels {
}
}
impl FmtLabels for EndpointLabels {
impl legacy::FmtLabels for EndpointLabels {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Inbound(i) => (Direction::In, i).fmt_labels(f),
@ -315,32 +324,36 @@ impl FmtLabels for EndpointLabels {
}
}
impl FmtLabels for InboundEndpointLabels {
impl legacy::FmtLabels for InboundEndpointLabels {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(a) = self.authority.as_ref() {
let Self {
tls,
authority,
target_addr,
policy,
} = self;
if let Some(a) = authority.as_ref() {
Authority(a).fmt_labels(f)?;
write!(f, ",")?;
}
(
(TargetAddr(self.target_addr), TlsAccept::from(&self.tls)),
&self.policy,
)
.fmt_labels(f)?;
((TargetAddr(*target_addr), TlsAccept::from(tls)), policy).fmt_labels(f)?;
Ok(())
}
}
impl FmtLabels for ServerLabel {
impl legacy::FmtLabels for ServerLabel {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let Self(meta, port) = self;
write!(
f,
"srv_group=\"{}\",srv_kind=\"{}\",srv_name=\"{}\",srv_port=\"{}\"",
self.0.group(),
self.0.kind(),
self.0.name(),
self.1
meta.group(),
meta.kind(),
meta.name(),
port
)
}
}
@ -362,41 +375,47 @@ impl prom::EncodeLabelSetMut for ServerLabel {
}
}
impl FmtLabels for ServerAuthzLabels {
impl legacy::FmtLabels for ServerAuthzLabels {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.server.fmt_labels(f)?;
let Self { server, authz } = self;
server.fmt_labels(f)?;
write!(
f,
",authz_group=\"{}\",authz_kind=\"{}\",authz_name=\"{}\"",
self.authz.group(),
self.authz.kind(),
self.authz.name()
authz.group(),
authz.kind(),
authz.name()
)
}
}
impl FmtLabels for RouteLabels {
impl legacy::FmtLabels for RouteLabels {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.server.fmt_labels(f)?;
let Self { server, route } = self;
server.fmt_labels(f)?;
write!(
f,
",route_group=\"{}\",route_kind=\"{}\",route_name=\"{}\"",
self.route.group(),
self.route.kind(),
self.route.name(),
route.group(),
route.kind(),
route.name(),
)
}
}
impl FmtLabels for RouteAuthzLabels {
impl legacy::FmtLabels for RouteAuthzLabels {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.route.fmt_labels(f)?;
let Self { route, authz } = self;
route.fmt_labels(f)?;
write!(
f,
",authz_group=\"{}\",authz_kind=\"{}\",authz_name=\"{}\"",
self.authz.group(),
self.authz.kind(),
self.authz.name(),
authz.group(),
authz.kind(),
authz.name(),
)
}
}
@ -407,19 +426,28 @@ impl svc::Param<OutboundZoneLocality> for OutboundEndpointLabels {
}
}
impl FmtLabels for OutboundEndpointLabels {
impl legacy::FmtLabels for OutboundEndpointLabels {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(a) = self.authority.as_ref() {
let Self {
server_id,
authority,
labels,
// TODO(kate): this label is not currently emitted.
zone_locality: _,
target_addr,
} = self;
if let Some(a) = authority.as_ref() {
Authority(a).fmt_labels(f)?;
write!(f, ",")?;
}
let ta = TargetAddr(self.target_addr);
let tls = TlsConnect::from(&self.server_id);
let ta = TargetAddr(*target_addr);
let tls = TlsConnect::from(server_id);
(ta, tls).fmt_labels(f)?;
if let Some(labels) = self.labels.as_ref() {
write!(f, ",{}", labels)?;
if let Some(labels) = labels.as_ref() {
write!(f, ",{labels}")?;
}
Ok(())
@ -435,19 +463,20 @@ impl fmt::Display for Direction {
}
}
impl FmtLabels for Direction {
impl legacy::FmtLabels for Direction {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "direction=\"{}\"", self)
write!(f, "direction=\"{self}\"")
}
}
impl FmtLabels for Authority<'_> {
impl legacy::FmtLabels for Authority<'_> {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "authority=\"{}\"", self.0)
let Self(authority) = self;
write!(f, "authority=\"{authority}\"")
}
}
impl FmtLabels for Class {
impl legacy::FmtLabels for Class {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let class = |ok: bool| if ok { "success" } else { "failure" };
@ -469,8 +498,7 @@ impl FmtLabels for Class {
Class::Error(msg) => write!(
f,
"classification=\"failure\",grpc_status=\"\",error=\"{}\"",
msg
"classification=\"failure\",grpc_status=\"\",error=\"{msg}\""
),
}
}
@ -496,9 +524,15 @@ impl StackLabels {
}
}
impl FmtLabels for StackLabels {
impl legacy::FmtLabels for StackLabels {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.direction.fmt_labels(f)?;
write!(f, ",protocol=\"{}\",name=\"{}\"", self.protocol, self.name)
let Self {
direction,
protocol,
name,
} = self;
direction.fmt_labels(f)?;
write!(f, ",protocol=\"{protocol}\",name=\"{name}\"")
}
}

View File

@ -0,0 +1,70 @@
use linkerd_metrics::prom;
use prometheus_client::encoding::{EncodeLabelSet, EncodeLabelValue, LabelValueEncoder};
use std::{
fmt::{Error, Write},
sync::{Arc, OnceLock},
};
static TLS_INFO: OnceLock<Arc<TlsInfo>> = OnceLock::new();
#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, EncodeLabelSet)]
pub struct TlsInfo {
tls_suites: MetricValueList,
tls_kx_groups: MetricValueList,
tls_rand: String,
tls_key_provider: String,
tls_fips: bool,
}
#[derive(Clone, Debug, Default, Hash, PartialEq, Eq)]
struct MetricValueList {
values: Vec<&'static str>,
}
impl FromIterator<&'static str> for MetricValueList {
fn from_iter<T: IntoIterator<Item = &'static str>>(iter: T) -> Self {
MetricValueList {
values: iter.into_iter().collect(),
}
}
}
impl EncodeLabelValue for MetricValueList {
fn encode(&self, encoder: &mut LabelValueEncoder<'_>) -> Result<(), Error> {
for value in &self.values {
value.encode(encoder)?;
encoder.write_char(',')?;
}
Ok(())
}
}
pub fn metric() -> prom::Family<TlsInfo, prom::ConstGauge> {
let fam = prom::Family::<TlsInfo, prom::ConstGauge>::new_with_constructor(|| {
prom::ConstGauge::new(1)
});
let tls_info = TLS_INFO.get_or_init(|| {
let provider = linkerd_rustls::get_default_provider();
let tls_suites = provider
.cipher_suites
.iter()
.flat_map(|cipher_suite| cipher_suite.suite().as_str())
.collect::<MetricValueList>();
let tls_kx_groups = provider
.kx_groups
.iter()
.flat_map(|suite| suite.name().as_str())
.collect::<MetricValueList>();
Arc::new(TlsInfo {
tls_suites,
tls_kx_groups,
tls_rand: format!("{:?}", provider.secure_random),
tls_key_provider: format!("{:?}", provider.key_provider),
tls_fips: provider.fips(),
})
});
let _ = fam.get_or_create(tls_info);
fam
}

View File

@ -1,7 +1,7 @@
use crate::metrics::ServerLabel as PolicyServerLabel;
pub use crate::metrics::{Direction, OutboundEndpointLabels};
use linkerd_conditional::Conditional;
use linkerd_metrics::FmtLabels;
use linkerd_metrics::legacy::FmtLabels;
use linkerd_tls as tls;
use std::{fmt, net::SocketAddr};
@ -20,16 +20,16 @@ pub enum Key {
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct ServerLabels {
direction: Direction,
tls: tls::ConditionalServerTls,
tls: tls::ConditionalServerTlsLabels,
target_addr: SocketAddr,
policy: Option<PolicyServerLabel>,
}
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct TlsAccept<'t>(pub &'t tls::ConditionalServerTls);
pub struct TlsAccept<'t>(pub &'t tls::ConditionalServerTlsLabels);
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub(crate) struct TlsConnect<'t>(&'t tls::ConditionalClientTls);
pub(crate) struct TlsConnect<'t>(pub &'t tls::ConditionalClientTlsLabels);
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct TargetAddr(pub SocketAddr);
@ -38,7 +38,7 @@ pub struct TargetAddr(pub SocketAddr);
impl Key {
pub fn inbound_server(
tls: tls::ConditionalServerTls,
tls: tls::ConditionalServerTlsLabels,
target_addr: SocketAddr,
server: PolicyServerLabel,
) -> Self {
@ -62,7 +62,7 @@ impl FmtLabels for Key {
}
Self::InboundClient => {
const NO_TLS: tls::client::ConditionalClientTls =
const NO_TLS: tls::client::ConditionalClientTlsLabels =
Conditional::None(tls::NoClientTls::Loopback);
Direction::In.fmt_labels(f)?;
@ -75,7 +75,7 @@ impl FmtLabels for Key {
impl ServerLabels {
fn inbound(
tls: tls::ConditionalServerTls,
tls: tls::ConditionalServerTlsLabels,
target_addr: SocketAddr,
policy: PolicyServerLabel,
) -> Self {
@ -90,7 +90,7 @@ impl ServerLabels {
fn outbound(target_addr: SocketAddr) -> Self {
ServerLabels {
direction: Direction::Out,
tls: tls::ConditionalServerTls::None(tls::NoServerTls::Loopback),
tls: tls::ConditionalServerTlsLabels::None(tls::NoServerTls::Loopback),
target_addr,
policy: None,
}
@ -99,14 +99,17 @@ impl ServerLabels {
impl FmtLabels for ServerLabels {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.direction.fmt_labels(f)?;
let Self {
direction,
tls,
target_addr,
policy,
} = self;
direction.fmt_labels(f)?;
f.write_str(",peer=\"src\",")?;
(
(TargetAddr(self.target_addr), TlsAccept(&self.tls)),
self.policy.as_ref(),
)
.fmt_labels(f)?;
((TargetAddr(*target_addr), TlsAccept(tls)), policy.as_ref()).fmt_labels(f)?;
Ok(())
}
@ -114,27 +117,28 @@ impl FmtLabels for ServerLabels {
// === impl TlsAccept ===
impl<'t> From<&'t tls::ConditionalServerTls> for TlsAccept<'t> {
fn from(c: &'t tls::ConditionalServerTls) -> Self {
impl<'t> From<&'t tls::ConditionalServerTlsLabels> for TlsAccept<'t> {
fn from(c: &'t tls::ConditionalServerTlsLabels) -> Self {
TlsAccept(c)
}
}
impl FmtLabels for TlsAccept<'_> {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {
let Self(tls) = self;
match tls {
Conditional::None(tls::NoServerTls::Disabled) => {
write!(f, "tls=\"disabled\"")
}
Conditional::None(why) => {
write!(f, "tls=\"no_identity\",no_tls_reason=\"{}\"", why)
write!(f, "tls=\"no_identity\",no_tls_reason=\"{why}\"")
}
Conditional::Some(tls::ServerTls::Established { client_id, .. }) => match client_id {
Some(id) => write!(f, "tls=\"true\",client_id=\"{}\"", id),
Conditional::Some(tls::ServerTlsLabels::Established { client_id }) => match client_id {
Some(id) => write!(f, "tls=\"true\",client_id=\"{id}\""),
None => write!(f, "tls=\"true\",client_id=\"\""),
},
Conditional::Some(tls::ServerTls::Passthru { sni }) => {
write!(f, "tls=\"opaque\",sni=\"{}\"", sni)
Conditional::Some(tls::ServerTlsLabels::Passthru { sni }) => {
write!(f, "tls=\"opaque\",sni=\"{sni}\"")
}
}
}
@ -142,23 +146,25 @@ impl FmtLabels for TlsAccept<'_> {
// === impl TlsConnect ===
impl<'t> From<&'t tls::ConditionalClientTls> for TlsConnect<'t> {
fn from(s: &'t tls::ConditionalClientTls) -> Self {
impl<'t> From<&'t tls::ConditionalClientTlsLabels> for TlsConnect<'t> {
fn from(s: &'t tls::ConditionalClientTlsLabels) -> Self {
TlsConnect(s)
}
}
impl FmtLabels for TlsConnect<'_> {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {
let Self(tls) = self;
match tls {
Conditional::None(tls::NoClientTls::Disabled) => {
write!(f, "tls=\"disabled\"")
}
Conditional::None(why) => {
write!(f, "tls=\"no_identity\",no_tls_reason=\"{}\"", why)
write!(f, "tls=\"no_identity\",no_tls_reason=\"{why}\"")
}
Conditional::Some(tls::ClientTls { server_id, .. }) => {
write!(f, "tls=\"true\",server_id=\"{}\"", server_id)
Conditional::Some(tls::ClientTlsLabels { server_id }) => {
write!(f, "tls=\"true\",server_id=\"{server_id}\"")
}
}
}
@ -168,12 +174,13 @@ impl FmtLabels for TlsConnect<'_> {
impl FmtLabels for TargetAddr {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let Self(target_addr) = self;
write!(
f,
"target_addr=\"{}\",target_ip=\"{}\",target_port=\"{}\"",
self.0,
self.0.ip(),
self.0.port()
target_addr,
target_addr.ip(),
target_addr.port()
)
}
}
@ -194,9 +201,8 @@ mod tests {
use std::sync::Arc;
let labels = ServerLabels::inbound(
tls::ConditionalServerTls::Some(tls::ServerTls::Established {
tls::ConditionalServerTlsLabels::Some(tls::ServerTlsLabels::Established {
client_id: Some("foo.id.example.com".parse().unwrap()),
negotiated_protocol: None,
}),
([192, 0, 2, 4], 40000).into(),
PolicyServerLabel(

View File

@ -18,7 +18,7 @@ thiserror = "2"
tokio = { version = "1", features = ["sync"] }
tonic = { workspace = true, default-features = false }
tower = { workspace = true, default-features = false }
tracing = "0.1"
tracing = { workspace = true }
[dev-dependencies]
linkerd-app-inbound = { path = "../inbound", features = ["test-util"] }

View File

@ -90,7 +90,7 @@ impl Gateway {
detect_timeout,
queue,
addr,
meta,
meta.into(),
),
None => {
tracing::debug!(

View File

@ -153,7 +153,7 @@ fn mk_routes(profile: &profiles::Profile) -> Option<outbound::http::Routes> {
if let Some((addr, metadata)) = profile.endpoint.clone() {
return Some(outbound::http::Routes::Endpoint(
Remote(ServerAddr(addr)),
metadata,
metadata.into(),
));
}

View File

@ -13,8 +13,7 @@ Configures and runs the inbound proxy
test-util = [
"linkerd-app-test",
"linkerd-idle-cache/test-util",
"linkerd-meshtls/rustls",
"linkerd-meshtls-rustls/test-util",
"linkerd-meshtls/test-util",
]
[dependencies]
@ -25,8 +24,7 @@ linkerd-app-core = { path = "../core" }
linkerd-app-test = { path = "../test", optional = true }
linkerd-http-access-log = { path = "../../http/access-log" }
linkerd-idle-cache = { path = "../../idle-cache" }
linkerd-meshtls = { path = "../../meshtls", optional = true }
linkerd-meshtls-rustls = { path = "../../meshtls/rustls", optional = true }
linkerd-meshtls = { path = "../../meshtls", optional = true, default-features = false }
linkerd-proxy-client-policy = { path = "../../proxy/client-policy" }
linkerd-tonic-stream = { path = "../../tonic-stream" }
linkerd-tonic-watch = { path = "../../tonic-watch" }
@ -38,7 +36,7 @@ thiserror = "2"
tokio = { version = "1", features = ["sync"] }
tonic = { workspace = true, default-features = false }
tower = { workspace = true, features = ["util"] }
tracing = "0.1"
tracing = { workspace = true }
[dependencies.linkerd-proxy-server-policy]
path = "../../proxy/server-policy"
@ -49,7 +47,7 @@ hyper = { workspace = true, features = ["http1", "http2"] }
linkerd-app-test = { path = "../test" }
arbitrary = { version = "1", features = ["derive"] }
libfuzzer-sys = { version = "0.4", features = ["arbitrary-derive"] }
linkerd-meshtls-rustls = { path = "../../meshtls/rustls", features = [
linkerd-meshtls = { path = "../../meshtls", features = [
"test-util",
] }
@ -62,8 +60,7 @@ linkerd-http-metrics = { path = "../../http/metrics", features = ["test-util"] }
linkerd-http-box = { path = "../../http/box" }
linkerd-idle-cache = { path = "../../idle-cache", features = ["test-util"] }
linkerd-io = { path = "../../io", features = ["tokio-test"] }
linkerd-meshtls = { path = "../../meshtls", features = ["rustls"] }
linkerd-meshtls-rustls = { path = "../../meshtls/rustls", features = [
linkerd-meshtls = { path = "../../meshtls", features = [
"test-util",
] }
linkerd-proxy-server-policy = { path = "../../proxy/server-policy", features = [

View File

@ -18,13 +18,12 @@ linkerd-app-core = { path = "../../core" }
linkerd-app-inbound = { path = ".." }
linkerd-app-test = { path = "../../test" }
linkerd-idle-cache = { path = "../../../idle-cache", features = ["test-util"] }
linkerd-meshtls = { path = "../../../meshtls", features = ["rustls"] }
linkerd-meshtls-rustls = { path = "../../../meshtls/rustls", features = [
linkerd-meshtls = { path = "../../../meshtls", features = [
"test-util",
] }
linkerd-tracing = { path = "../../../tracing", features = ["ansi"] }
tokio = { version = "1", features = ["full"] }
tracing = "0.1"
tracing = { workspace = true }
# Prevent this from interfering with workspaces
[workspace]

View File

@ -325,7 +325,7 @@ impl svc::Param<Remote<ServerAddr>> for Forward {
impl svc::Param<transport::labels::Key> for Forward {
fn param(&self) -> transport::labels::Key {
transport::labels::Key::inbound_server(
self.tls.clone(),
self.tls.as_ref().map(|t| t.labels()),
self.orig_dst_addr.into(),
self.permit.labels.server.clone(),
)
@ -429,7 +429,7 @@ impl svc::Param<ServerLabel> for Http {
impl svc::Param<transport::labels::Key> for Http {
fn param(&self) -> transport::labels::Key {
transport::labels::Key::inbound_server(
self.tls.status.clone(),
self.tls.status.as_ref().map(|t| t.labels()),
self.tls.orig_dst_addr.into(),
self.tls.policy.server_label(),
)

View File

@ -117,7 +117,7 @@ impl<N> Inbound<N> {
let identity = rt
.identity
.server()
.with_alpn(vec![transport_header::PROTOCOL.into()])
.spawn_with_alpn(vec![transport_header::PROTOCOL.into()])
.expect("TLS credential store must be held");
inner
@ -311,9 +311,8 @@ impl Param<Remote<ServerAddr>> for AuthorizedLocalTcp {
impl Param<transport::labels::Key> for AuthorizedLocalTcp {
fn param(&self) -> transport::labels::Key {
transport::labels::Key::inbound_server(
tls::ConditionalServerTls::Some(tls::ServerTls::Established {
tls::ConditionalServerTlsLabels::Some(tls::ServerTlsLabels::Established {
client_id: Some(self.client_id.clone()),
negotiated_protocol: None,
}),
self.addr.into(),
self.permit.labels.server.clone(),
@ -344,9 +343,8 @@ impl Param<Remote<ClientAddr>> for LocalHttp {
impl Param<transport::labels::Key> for LocalHttp {
fn param(&self) -> transport::labels::Key {
transport::labels::Key::inbound_server(
tls::ConditionalServerTls::Some(tls::ServerTls::Established {
tls::ConditionalServerTlsLabels::Some(tls::ServerTlsLabels::Established {
client_id: Some(self.client.client_id.clone()),
negotiated_protocol: None,
}),
self.addr.into(),
self.policy.server_label(),
@ -435,6 +433,14 @@ impl Param<tls::ConditionalServerTls> for GatewayTransportHeader {
}
}
impl Param<tls::ConditionalServerTlsLabels> for GatewayTransportHeader {
fn param(&self) -> tls::ConditionalServerTlsLabels {
tls::ConditionalServerTlsLabels::Some(tls::ServerTlsLabels::Established {
client_id: Some(self.client.client_id.clone()),
})
}
}
impl Param<tls::ClientId> for GatewayTransportHeader {
fn param(&self) -> tls::ClientId {
self.client.client_id.clone()

View File

@ -395,7 +395,7 @@ fn endpoint_labels(
) -> impl svc::ExtractParam<metrics::EndpointLabels, Logical> + Clone {
move |t: &Logical| -> metrics::EndpointLabels {
metrics::InboundEndpointLabels {
tls: t.tls.clone(),
tls: t.tls.as_ref().map(|t| t.labels()),
authority: unsafe_authority_labels
.then(|| t.logical.as_ref().map(|d| d.as_http_authority()))
.flatten(),

View File

@ -664,7 +664,7 @@ async fn grpc_response_class() {
let response_total = metrics
.get_response_total(
&metrics::EndpointLabels::Inbound(metrics::InboundEndpointLabels {
tls: Target::meshed_h2().1,
tls: Target::meshed_h2().1.map(|t| t.labels()),
authority: None,
target_addr: "127.0.0.1:80".parse().unwrap(),
policy: metrics::RouteAuthzLabels {
@ -762,7 +762,7 @@ async fn test_unsafe_authority_labels(
let response_total = metrics
.get_response_total(
&metrics::EndpointLabels::Inbound(metrics::InboundEndpointLabels {
tls: Target::meshed_http1().1,
tls: Target::meshed_http1().1.as_ref().map(|t| t.labels()),
authority: expected_authority,
target_addr: "127.0.0.1:80".parse().unwrap(),
policy: metrics::RouteAuthzLabels {
@ -861,12 +861,7 @@ fn grpc_status_server(
#[tracing::instrument]
fn connect_error() -> impl Fn(Remote<ServerAddr>) -> io::Result<io::BoxedIo> {
move |_| {
Err(io::Error::new(
io::ErrorKind::Other,
"server is not listening",
))
}
move |_| Err(io::Error::other("server is not listening"))
}
#[tracing::instrument]

View File

@ -113,10 +113,6 @@ impl<S> Inbound<S> {
&self.runtime.identity
}
pub fn proxy_metrics(&self) -> &metrics::Proxy {
&self.runtime.metrics.proxy
}
/// A helper for gateways to instrument policy checks.
pub fn authorize_http<N>(
&self,

View File

@ -13,7 +13,7 @@ pub(crate) mod error;
pub use linkerd_app_core::metrics::*;
/// Holds outbound proxy metrics.
/// Holds LEGACY inbound proxy metrics.
#[derive(Clone, Debug)]
pub struct InboundMetrics {
pub http_authz: authz::HttpAuthzMetrics,
@ -50,7 +50,7 @@ impl InboundMetrics {
}
}
impl FmtMetrics for InboundMetrics {
impl legacy::FmtMetrics for InboundMetrics {
fn fmt_metrics(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.http_authz.fmt_metrics(f)?;
self.http_errors.fmt_metrics(f)?;

View File

@ -1,8 +1,9 @@
use crate::policy::{AllowPolicy, HttpRoutePermit, Meta, ServerPermit};
use linkerd_app_core::{
metrics::{
metrics, Counter, FmtLabels, FmtMetrics, RouteAuthzLabels, RouteLabels, ServerAuthzLabels,
ServerLabel, TargetAddr, TlsAccept,
legacy::{Counter, FmtLabels, FmtMetrics},
metrics, RouteAuthzLabels, RouteLabels, ServerAuthzLabels, ServerLabel, TargetAddr,
TlsAccept,
},
tls,
transport::OrigDstAddr,
@ -67,7 +68,7 @@ pub struct HTTPLocalRateLimitLabels {
#[derive(Debug, Hash, PartialEq, Eq)]
struct Key<L> {
target: TargetAddr,
tls: tls::ConditionalServerTls,
tls: tls::ConditionalServerTlsLabels,
labels: L,
}
@ -80,7 +81,7 @@ type HttpLocalRateLimitKey = Key<HTTPLocalRateLimitLabels>;
// === impl HttpAuthzMetrics ===
impl HttpAuthzMetrics {
pub fn allow(&self, permit: &HttpRoutePermit, tls: tls::ConditionalServerTls) {
pub fn allow(&self, permit: &HttpRoutePermit, tls: tls::ConditionalServerTlsLabels) {
self.0
.allow
.lock()
@ -93,7 +94,7 @@ impl HttpAuthzMetrics {
&self,
labels: ServerLabel,
dst: OrigDstAddr,
tls: tls::ConditionalServerTls,
tls: tls::ConditionalServerTlsLabels,
) {
self.0
.route_not_found
@ -103,7 +104,12 @@ impl HttpAuthzMetrics {
.incr();
}
pub fn deny(&self, labels: RouteLabels, dst: OrigDstAddr, tls: tls::ConditionalServerTls) {
pub fn deny(
&self,
labels: RouteLabels,
dst: OrigDstAddr,
tls: tls::ConditionalServerTlsLabels,
) {
self.0
.deny
.lock()
@ -116,7 +122,7 @@ impl HttpAuthzMetrics {
&self,
labels: HTTPLocalRateLimitLabels,
dst: OrigDstAddr,
tls: tls::ConditionalServerTls,
tls: tls::ConditionalServerTlsLabels,
) {
self.0
.http_local_rate_limit
@ -187,7 +193,7 @@ impl FmtMetrics for HttpAuthzMetrics {
// === impl TcpAuthzMetrics ===
impl TcpAuthzMetrics {
pub fn allow(&self, permit: &ServerPermit, tls: tls::ConditionalServerTls) {
pub fn allow(&self, permit: &ServerPermit, tls: tls::ConditionalServerTlsLabels) {
self.0
.allow
.lock()
@ -196,7 +202,7 @@ impl TcpAuthzMetrics {
.incr();
}
pub fn deny(&self, policy: &AllowPolicy, tls: tls::ConditionalServerTls) {
pub fn deny(&self, policy: &AllowPolicy, tls: tls::ConditionalServerTlsLabels) {
self.0
.deny
.lock()
@ -205,7 +211,7 @@ impl TcpAuthzMetrics {
.incr();
}
pub fn terminate(&self, policy: &AllowPolicy, tls: tls::ConditionalServerTls) {
pub fn terminate(&self, policy: &AllowPolicy, tls: tls::ConditionalServerTlsLabels) {
self.0
.terminate
.lock()
@ -246,18 +252,24 @@ impl FmtMetrics for TcpAuthzMetrics {
impl FmtLabels for HTTPLocalRateLimitLabels {
fn fmt_labels(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.server.fmt_labels(f)?;
if let Some(rl) = &self.rate_limit {
let Self {
server,
rate_limit,
scope,
} = self;
server.fmt_labels(f)?;
if let Some(rl) = rate_limit {
write!(
f,
",ratelimit_group=\"{}\",ratelimit_kind=\"{}\",ratelimit_name=\"{}\",ratelimit_scope=\"{}\"",
rl.group(),
rl.kind(),
rl.name(),
self.scope,
scope,
)
} else {
write!(f, ",ratelimit_scope=\"{}\"", self.scope)
write!(f, ",ratelimit_scope=\"{scope}\"")
}
}
}
@ -265,7 +277,7 @@ impl FmtLabels for HTTPLocalRateLimitLabels {
// === impl Key ===
impl<L> Key<L> {
fn new(labels: L, dst: OrigDstAddr, tls: tls::ConditionalServerTls) -> Self {
fn new(labels: L, dst: OrigDstAddr, tls: tls::ConditionalServerTlsLabels) -> Self {
Self {
tls,
target: TargetAddr(dst.into()),
@ -276,24 +288,30 @@ impl<L> Key<L> {
impl<L: FmtLabels> FmtLabels for Key<L> {
fn fmt_labels(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
(self.target, (&self.labels, TlsAccept(&self.tls))).fmt_labels(f)
let Self {
target,
tls,
labels,
} = self;
(target, (labels, TlsAccept(tls))).fmt_labels(f)
}
}
impl ServerKey {
fn from_policy(policy: &AllowPolicy, tls: tls::ConditionalServerTls) -> Self {
fn from_policy(policy: &AllowPolicy, tls: tls::ConditionalServerTlsLabels) -> Self {
Self::new(policy.server_label(), policy.dst_addr(), tls)
}
}
impl RouteAuthzKey {
fn from_permit(permit: &HttpRoutePermit, tls: tls::ConditionalServerTls) -> Self {
fn from_permit(permit: &HttpRoutePermit, tls: tls::ConditionalServerTlsLabels) -> Self {
Self::new(permit.labels.clone(), permit.dst, tls)
}
}
impl ServerAuthzKey {
fn from_permit(permit: &ServerPermit, tls: tls::ConditionalServerTls) -> Self {
fn from_permit(permit: &ServerPermit, tls: tls::ConditionalServerTlsLabels) -> Self {
Self::new(permit.labels.clone(), permit.dst, tls)
}
}

View File

@ -8,7 +8,7 @@ use crate::{
};
use linkerd_app_core::{
errors::{FailFastError, LoadShedError},
metrics::FmtLabels,
metrics::legacy::FmtLabels,
tls,
};
use std::fmt;

View File

@ -1,6 +1,9 @@
use super::ErrorKind;
use linkerd_app_core::{
metrics::{metrics, Counter, FmtMetrics, ServerLabel},
metrics::{
legacy::{Counter, FmtMetrics},
metrics, ServerLabel,
},
svc::{self, stack::NewMonitor},
transport::{labels::TargetAddr, OrigDstAddr},
Error,

View File

@ -1,6 +1,9 @@
use super::ErrorKind;
use linkerd_app_core::{
metrics::{metrics, Counter, FmtMetrics},
metrics::{
legacy::{Counter, FmtMetrics},
metrics,
},
svc::{self, stack::NewMonitor},
transport::{labels::TargetAddr, OrigDstAddr},
Error,

View File

@ -33,7 +33,7 @@ static INVALID_POLICY: once_cell::sync::OnceCell<ServerPolicy> = once_cell::sync
impl<S> Api<S>
where
S: tonic::client::GrpcService<tonic::body::BoxBody, Error = Error> + Clone,
S: tonic::client::GrpcService<tonic::body::Body, Error = Error> + Clone,
S::ResponseBody: http::Body<Data = tonic::codegen::Bytes, Error = Error> + Send + 'static,
{
pub(super) fn new(
@ -57,7 +57,7 @@ where
impl<S> Service<u16> for Api<S>
where
S: tonic::client::GrpcService<tonic::body::BoxBody, Error = Error>,
S: tonic::client::GrpcService<tonic::body::Body, Error = Error>,
S: Clone + Send + Sync + 'static,
S::ResponseBody: http::Body<Data = tonic::codegen::Bytes, Error = Error> + Send + 'static,
S::Future: Send + 'static,

View File

@ -40,7 +40,7 @@ impl Config {
limits: ReceiveLimits,
) -> impl GetPolicy + Clone + Send + Sync + 'static
where
C: tonic::client::GrpcService<tonic::body::BoxBody, Error = Error>,
C: tonic::client::GrpcService<tonic::body::Body, Error = Error>,
C: Clone + Unpin + Send + Sync + 'static,
C::ResponseBody: http::Body<Data = tonic::codegen::Bytes, Error = Error>,
C::ResponseBody: Send + 'static,

View File

@ -248,8 +248,11 @@ impl<T, N> HttpPolicyService<T, N> {
);
}
}
self.metrics
.deny(labels, self.connection.dst, self.connection.tls.clone());
self.metrics.deny(
labels,
self.connection.dst,
self.connection.tls.as_ref().map(|t| t.labels()),
);
return Err(HttpRouteUnauthorized(()).into());
}
};
@ -279,14 +282,19 @@ impl<T, N> HttpPolicyService<T, N> {
}
};
self.metrics.allow(&permit, self.connection.tls.clone());
self.metrics
.allow(&permit, self.connection.tls.as_ref().map(|t| t.labels()));
Ok((permit, r#match, route))
}
fn mk_route_not_found(&self) -> Error {
let labels = self.policy.server_label();
self.metrics
.route_not_found(labels, self.connection.dst, self.connection.tls.clone());
self.metrics.route_not_found(
labels,
self.connection.dst,
self.connection.tls.as_ref().map(|t| t.labels()),
);
HttpRouteNotFound(()).into()
}
@ -306,7 +314,7 @@ impl<T, N> HttpPolicyService<T, N> {
self.metrics.ratelimit(
self.policy.ratelimit_label(&err),
self.connection.dst,
self.connection.tls.clone(),
self.connection.tls.as_ref().map(|t| t.labels()),
);
err.into()
})

View File

@ -74,7 +74,7 @@ impl<S> Store<S> {
opaque_ports: RangeInclusiveSet<u16>,
) -> Self
where
S: tonic::client::GrpcService<tonic::body::BoxBody, Error = Error>,
S: tonic::client::GrpcService<tonic::body::Body, Error = Error>,
S: Clone + Send + Sync + 'static,
S::Future: Send,
S::ResponseBody: http::Body<Data = tonic::codegen::Bytes, Error = Error> + Send + 'static,
@ -138,7 +138,7 @@ impl<S> Store<S> {
impl<S> GetPolicy for Store<S>
where
S: tonic::client::GrpcService<tonic::body::BoxBody, Error = Error>,
S: tonic::client::GrpcService<tonic::body::Body, Error = Error>,
S: Clone + Send + Sync + 'static,
S::Future: Send,
S::ResponseBody: http::Body<Data = tonic::codegen::Bytes, Error = Error> + Send + 'static,

View File

@ -77,7 +77,8 @@ where
// This new services requires a ClientAddr, so it must necessarily be built for each
// connection. So we can just increment the counter here since the service can only
// be used at most once.
self.metrics.allow(&permit, tls.clone());
self.metrics
.allow(&permit, tls.as_ref().map(|t| t.labels()));
let inner = self.inner.new_service((permit, target));
TcpPolicy::Authorized(Authorized {
@ -97,7 +98,7 @@ where
?tls, %client,
"Connection denied"
);
self.metrics.deny(&policy, tls);
self.metrics.deny(&policy, tls.as_ref().map(|t| t.labels()));
TcpPolicy::Unauthorized(deny)
}
}
@ -167,7 +168,7 @@ where
%client,
"Connection terminated due to policy change",
);
metrics.terminate(&policy, tls);
metrics.terminate(&policy, tls.as_ref().map(|t| t.labels()));
return Err(denied.into());
}
}

View File

@ -263,7 +263,7 @@ fn orig_dst_addr() -> OrigDstAddr {
OrigDstAddr(([192, 0, 2, 2], 1000).into())
}
impl tonic::client::GrpcService<tonic::body::BoxBody> for MockSvc {
impl tonic::client::GrpcService<tonic::body::Body> for MockSvc {
type ResponseBody = linkerd_app_core::control::RspBody;
type Error = Error;
type Future = futures::future::Pending<Result<http::Response<Self::ResponseBody>, Self::Error>>;
@ -275,7 +275,7 @@ impl tonic::client::GrpcService<tonic::body::BoxBody> for MockSvc {
unreachable!()
}
fn call(&mut self, _req: http::Request<tonic::body::BoxBody>) -> Self::Future {
fn call(&mut self, _req: http::Request<tonic::body::Body>) -> Self::Future {
unreachable!()
}
}

View File

@ -27,7 +27,7 @@ impl Inbound<()> {
limits: ReceiveLimits,
) -> impl policy::GetPolicy + Clone + Send + Sync + 'static
where
C: tonic::client::GrpcService<tonic::body::BoxBody, Error = Error>,
C: tonic::client::GrpcService<tonic::body::Body, Error = Error>,
C: Clone + Unpin + Send + Sync + 'static,
C::ResponseBody: http::Body<Data = tonic::codegen::Bytes, Error = Error>,
C::ResponseBody: Send + 'static,

View File

@ -3,9 +3,7 @@ pub use futures::prelude::*;
use linkerd_app_core::{
config,
dns::Suffix,
drain, exp_backoff,
identity::rustls,
metrics,
drain, exp_backoff, identity, metrics,
proxy::{
http::{h1, h2},
tap,
@ -98,7 +96,7 @@ pub fn runtime() -> (ProxyRuntime, drain::Signal) {
let (tap, _) = tap::new();
let (metrics, _) = metrics::Metrics::new(std::time::Duration::from_secs(10));
let runtime = ProxyRuntime {
identity: rustls::creds::default_for_test().1.into(),
identity: identity::creds::default_for_test().1,
metrics: metrics.proxy,
tap,
span_sink: None,

View File

@ -23,38 +23,50 @@ h2 = { workspace = true }
http = { workspace = true }
http-body = { workspace = true }
http-body-util = { workspace = true }
hyper = { workspace = true, features = [
"http1",
"http2",
"client",
"server",
] }
hyper-util = { workspace = true, features = ["service"] }
ipnet = "2"
linkerd-app = { path = "..", features = ["allow-loopback"] }
linkerd-app-core = { path = "../core" }
linkerd-metrics = { path = "../../metrics", features = ["test_util"] }
linkerd2-proxy-api = { workspace = true, features = [
"destination",
"arbitrary",
] }
linkerd-app-test = { path = "../test" }
linkerd-meshtls = { path = "../../meshtls", features = ["test-util"] }
linkerd-metrics = { path = "../../metrics", features = ["test_util"] }
linkerd-rustls = { path = "../../rustls" }
linkerd-tracing = { path = "../../tracing" }
maplit = "1"
parking_lot = "0.12"
regex = "1"
socket2 = "0.5"
tokio = { version = "1", features = ["io-util", "net", "rt", "macros"] }
tokio-stream = { version = "0.1", features = ["sync"] }
tokio-rustls = { workspace = true }
rustls-pemfile = "2.2"
socket2 = "0.6"
tokio = { version = "1", features = ["io-util", "net", "rt", "macros"] }
tokio-rustls = { workspace = true }
tokio-stream = { version = "0.1", features = ["sync"] }
tonic = { workspace = true, features = ["transport", "router"], default-features = false }
tower = { workspace = true, default-features = false }
tonic = { workspace = true, features = ["transport"], default-features = false }
tracing = "0.1"
tracing-subscriber = { version = "0.3", default-features = false, features = [
tracing = { workspace = true }
[dependencies.hyper]
workspace = true
features = [
"client",
"http1",
"http2",
"server",
]
[dependencies.linkerd2-proxy-api]
workspace = true
features = [
"arbitrary",
"destination",
]
[dependencies.tracing-subscriber]
version = "0.3"
default-features = false
features = [
"fmt",
"std",
] }
]
[dev-dependencies]
flate2 = { version = "1", default-features = false, features = [
@ -62,8 +74,5 @@ flate2 = { version = "1", default-features = false, features = [
] }
# Log streaming isn't enabled by default globally, but we want to test it.
linkerd-app-admin = { path = "../admin", features = ["log-streaming"] }
# No code from this crate is actually used; only necessary to enable the Rustls
# implementation.
linkerd-meshtls = { path = "../../meshtls", features = ["rustls"] }
linkerd-tracing = { path = "../../tracing", features = ["ansi"] }
serde_json = "1"

View File

@ -262,10 +262,7 @@ impl pb::destination_server::Destination for Controller {
}
tracing::warn!(?dst, ?updates, "request does not match");
let msg = format!(
"expected get call for {:?} but got get call for {:?}",
dst, req
);
let msg = format!("expected get call for {dst:?} but got get call for {req:?}");
calls.push_front(Dst::Call(dst, updates));
return Err(grpc::Status::new(grpc::Code::Unavailable, msg));
}

View File

@ -8,7 +8,8 @@ use std::{
};
use linkerd2_proxy_api::identity as pb;
use tokio_rustls::rustls::{self, pki_types::CertificateDer, server::WebPkiClientVerifier};
use linkerd_rustls::get_default_provider;
use tokio_rustls::rustls::{self, server::WebPkiClientVerifier};
use tonic as grpc;
pub struct Identity {
@ -34,10 +35,6 @@ type Certify = Box<
> + Send,
>;
static TLS_VERSIONS: &[&rustls::SupportedProtocolVersion] = &[&rustls::version::TLS13];
static TLS_SUPPORTED_CIPHERSUITES: &[rustls::SupportedCipherSuite] =
&[rustls::crypto::ring::cipher_suite::TLS13_CHACHA20_POLY1305_SHA256];
struct Certificates {
pub leaf: Vec<u8>,
pub intermediates: Vec<Vec<u8>>,
@ -54,13 +51,13 @@ impl Certificates {
let leaf = certs
.next()
.expect("no leaf cert in pemfile")
.map_err(|_| io::Error::new(io::ErrorKind::Other, "rustls error reading certs"))?
.map_err(|_| io::Error::other("rustls error reading certs"))?
.as_ref()
.to_vec();
let intermediates = certs
.map(|cert| cert.map(|cert| cert.as_ref().to_vec()))
.collect::<Result<Vec<_>, _>>()
.map_err(|_| io::Error::new(io::ErrorKind::Other, "rustls error reading certs"))?;
.map_err(|_| io::Error::other("rustls error reading certs"))?;
Ok(Certificates {
leaf,
@ -104,19 +101,16 @@ impl Identity {
use std::io::Cursor;
let mut roots = rustls::RootCertStore::empty();
let trust_anchors = rustls_pemfile::certs(&mut Cursor::new(trust_anchors))
.map(|bytes| bytes.map(CertificateDer::from))
.collect::<Result<Vec<_>, _>>()
.expect("error parsing pemfile");
let (added, skipped) = roots.add_parsable_certificates(trust_anchors);
assert_ne!(added, 0, "trust anchors must include at least one cert");
assert_eq!(skipped, 0, "no certs in pemfile should be invalid");
let mut provider = rustls::crypto::ring::default_provider();
provider.cipher_suites = TLS_SUPPORTED_CIPHERSUITES.to_vec();
let provider = Arc::new(provider);
let provider = get_default_provider();
let client_config = rustls::ClientConfig::builder_with_provider(provider.clone())
.with_protocol_versions(TLS_VERSIONS)
.with_safe_default_protocol_versions()
.expect("client config must be valid")
.with_root_certificates(roots.clone())
.with_no_client_auth();
@ -128,7 +122,7 @@ impl Identity {
.expect("server verifier must be valid");
let server_config = rustls::ServerConfig::builder_with_provider(provider)
.with_protocol_versions(TLS_VERSIONS)
.with_safe_default_protocol_versions()
.expect("server config must be valid")
.with_client_cert_verifier(client_cert_verifier)
.with_single_cert(certs.chain(), key)
@ -219,7 +213,7 @@ impl Controller {
let f = f.take().expect("called twice?");
let fut = f(req)
.map_ok(grpc::Response::new)
.map_err(|e| grpc::Status::new(grpc::Code::Internal, format!("{}", e)));
.map_err(|e| grpc::Status::new(grpc::Code::Internal, format!("{e}")));
Box::pin(fut)
});
self.expect_calls.lock().push_back(func);

View File

@ -3,6 +3,7 @@
#![warn(rust_2018_idioms, clippy::disallowed_methods, clippy::disallowed_types)]
#![forbid(unsafe_code)]
#![recursion_limit = "256"]
#![allow(clippy::result_large_err)]
mod test_env;
@ -247,7 +248,7 @@ impl fmt::Display for HumanDuration {
let secs = self.0.as_secs();
let subsec_ms = self.0.subsec_nanos() as f64 / 1_000_000f64;
if secs == 0 {
write!(fmt, "{}ms", subsec_ms)
write!(fmt, "{subsec_ms}ms")
} else {
write!(fmt, "{}s", secs as f64 + subsec_ms)
}

View File

@ -302,7 +302,7 @@ impl Controller {
}
pub async fn run(self) -> controller::Listening {
let svc = grpc::transport::Server::builder()
let routes = grpc::service::Routes::default()
.add_service(
inbound_server_policies_server::InboundServerPoliciesServer::new(Server(Arc::new(
self.inbound,
@ -310,9 +310,9 @@ impl Controller {
)
.add_service(outbound_policies_server::OutboundPoliciesServer::new(
Server(Arc::new(self.outbound)),
))
.into_service();
controller::run(RoutesSvc(svc), "support policy controller", None).await
));
controller::run(RoutesSvc(routes), "support policy controller", None).await
}
}
@ -525,7 +525,9 @@ impl Service<Request<hyper::body::Incoming>> for RoutesSvc {
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
let Self(routes) = self;
routes.poll_ready(cx)
<grpc::service::Routes as Service<Request<UnsyncBoxBody<Bytes, grpc::Status>>>>::poll_ready(
routes, cx,
)
}
fn call(&mut self, req: Request<hyper::body::Incoming>) -> Self::Future {

View File

@ -108,7 +108,7 @@ impl fmt::Debug for MockOrigDst {
match self {
Self::Addr(addr) => f
.debug_tuple("MockOrigDst::Addr")
.field(&format_args!("{}", addr))
.field(&format_args!("{addr}"))
.finish(),
Self::Direct => f.debug_tuple("MockOrigDst::Direct").finish(),
Self::None => f.debug_tuple("MockOrigDst::None").finish(),
@ -416,9 +416,9 @@ async fn run(proxy: Proxy, mut env: TestEnv, random_ports: bool) -> Listening {
use std::fmt::Write;
let mut ports = inbound_default_ports.iter();
if let Some(port) = ports.next() {
let mut var = format!("{}", port);
let mut var = format!("{port}");
for port in ports {
write!(&mut var, ",{}", port).expect("writing to String should never fail");
write!(&mut var, ",{port}").expect("writing to String should never fail");
}
info!("{}={:?}", app::env::ENV_INBOUND_PORTS, var);
env.put(app::env::ENV_INBOUND_PORTS, var);

View File

@ -137,28 +137,28 @@ impl TapEventExt for pb::TapEvent {
fn request_init_authority(&self) -> &str {
match self.event() {
pb::tap_event::http::Event::RequestInit(ev) => &ev.authority,
e => panic!("not RequestInit event: {:?}", e),
e => panic!("not RequestInit event: {e:?}"),
}
}
fn request_init_path(&self) -> &str {
match self.event() {
pb::tap_event::http::Event::RequestInit(ev) => &ev.path,
e => panic!("not RequestInit event: {:?}", e),
e => panic!("not RequestInit event: {e:?}"),
}
}
fn response_init_status(&self) -> u16 {
match self.event() {
pb::tap_event::http::Event::ResponseInit(ev) => ev.http_status as u16,
e => panic!("not ResponseInit event: {:?}", e),
e => panic!("not ResponseInit event: {e:?}"),
}
}
fn response_end_bytes(&self) -> u64 {
match self.event() {
pb::tap_event::http::Event::ResponseEnd(ev) => ev.response_bytes,
e => panic!("not ResponseEnd event: {:?}", e),
e => panic!("not ResponseEnd event: {e:?}"),
}
}
@ -170,7 +170,7 @@ impl TapEventExt for pb::TapEvent {
}) => code,
_ => panic!("not Eos GrpcStatusCode: {:?}", ev.eos),
},
ev => panic!("not ResponseEnd event: {:?}", ev),
ev => panic!("not ResponseEnd event: {ev:?}"),
}
}
}

View File

@ -381,7 +381,7 @@ mod cross_version {
}
fn default_dst_name(port: u16) -> String {
format!("{}:{}", HOST, port)
format!("{HOST}:{port}")
}
fn send_default_dst(

View File

@ -63,7 +63,7 @@ async fn wait_for_profile_stage(client: &client::Client, metrics: &client::Clien
for _ in 0i32..10 {
assert_eq!(client.get("/load-profile").await, "");
let m = metrics.get("/metrics").await;
let stage_metric = format!("rt_load_profile=\"{}\"", stage);
let stage_metric = format!("rt_load_profile=\"{stage}\"");
if m.contains(stage_metric.as_str()) {
break;
}

View File

@ -88,12 +88,12 @@ impl TestBuilder {
let port = srv.addr.port();
let ctrl = controller::new();
let dst_tx = ctrl.destination_tx(format!("{}:{}", host, port));
let dst_tx = ctrl.destination_tx(format!("{host}:{port}"));
dst_tx.send_addr(srv.addr);
let ctrl = controller::new();
let dst_tx = ctrl.destination_tx(format!("{}:{}", host, port));
let dst_tx = ctrl.destination_tx(format!("{host}:{port}"));
dst_tx.send_addr(srv.addr);
let profile_tx = ctrl.profile_tx(srv.addr.to_string());

View File

@ -1318,9 +1318,9 @@ async fn metrics_compression() {
body.copy_to_bytes(body.remaining()),
));
let mut scrape = String::new();
decoder.read_to_string(&mut scrape).unwrap_or_else(|_| {
panic!("decode gzip (requested Accept-Encoding: {})", encoding)
});
decoder
.read_to_string(&mut scrape)
.unwrap_or_else(|_| panic!("decode gzip (requested Accept-Encoding: {encoding})"));
scrape
}
};

View File

@ -26,7 +26,7 @@ async fn is_valid_json() {
assert!(!json.is_empty());
for obj in json {
println!("{}\n", obj);
println!("{obj}\n");
}
}
@ -53,7 +53,7 @@ async fn query_is_valid_json() {
assert!(!json.is_empty());
for obj in json {
println!("{}\n", obj);
println!("{obj}\n");
}
}
@ -74,12 +74,9 @@ async fn valid_get_does_not_error() {
let json = logs.await.unwrap();
for obj in json {
println!("{}\n", obj);
println!("{obj}\n");
if obj.get("error").is_some() {
panic!(
"expected the log stream to contain no error responses!\njson = {}",
obj
);
panic!("expected the log stream to contain no error responses!\njson = {obj}");
}
}
}
@ -101,12 +98,9 @@ async fn valid_query_does_not_error() {
let json = logs.await.unwrap();
for obj in json {
println!("{}\n", obj);
println!("{obj}\n");
if obj.get("error").is_some() {
panic!(
"expected the log stream to contain no error responses!\njson = {}",
obj
);
panic!("expected the log stream to contain no error responses!\njson = {obj}");
}
}
}
@ -142,9 +136,7 @@ async fn multi_filter() {
level.and_then(|value| value.as_str()),
Some("DEBUG") | Some("INFO") | Some("WARN") | Some("ERROR")
),
"level must be DEBUG, INFO, WARN, or ERROR\n level: {:?}\n json: {:#?}",
level,
obj
"level must be DEBUG, INFO, WARN, or ERROR\n level: {level:?}\n json: {obj:#?}"
);
}
@ -175,7 +167,7 @@ async fn get_log_stream(
let req = client
.request_body(
client
.request_builder(&format!("{}?{}", PATH, filter))
.request_builder(&format!("{PATH}?{filter}"))
.method(http::Method::GET)
.body(http_body_util::Full::new(Bytes::from(filter)))
.unwrap(),
@ -231,7 +223,7 @@ where
}
}
Err(e) => {
println!("body failed: {}", e);
println!("body failed: {e}");
break;
}
};

View File

@ -80,10 +80,7 @@ impl Test {
.await
};
env.put(
app::env::ENV_INBOUND_DETECT_TIMEOUT,
format!("{:?}", TIMEOUT),
);
env.put(app::env::ENV_INBOUND_DETECT_TIMEOUT, format!("{TIMEOUT:?}"));
(self.set_env)(&mut env);
@ -127,26 +124,6 @@ async fn inbound_timeout() {
.await;
}
/// Tests that the detect metric is labeled and incremented on I/O error.
#[tokio::test]
async fn inbound_io_err() {
let _trace = trace_init();
let (proxy, metrics) = Test::default().run().await;
let client = crate::tcp::client(proxy.inbound);
let tcp_client = client.connect().await;
tcp_client.write(TcpFixture::HELLO_MSG).await;
drop(tcp_client);
metric(&proxy)
.label("error", "i/o")
.value(1u64)
.assert_in(&metrics)
.await;
}
/// Tests that the detect metric is not incremented when TLS is successfully
/// detected.
#[tokio::test]
@ -192,44 +169,6 @@ async fn inbound_success() {
metric.assert_in(&metrics).await;
}
/// Tests both of the above cases together.
#[tokio::test]
async fn inbound_multi() {
let _trace = trace_init();
let (proxy, metrics) = Test::default().run().await;
let client = crate::tcp::client(proxy.inbound);
let metric = metric(&proxy);
let timeout_metric = metric.clone().label("error", "tls detection timeout");
let io_metric = metric.label("error", "i/o");
let tcp_client = client.connect().await;
tokio::time::sleep(TIMEOUT + Duration::from_millis(15)) // just in case
.await;
timeout_metric.clone().value(1u64).assert_in(&metrics).await;
drop(tcp_client);
let tcp_client = client.connect().await;
tcp_client.write(TcpFixture::HELLO_MSG).await;
drop(tcp_client);
io_metric.clone().value(1u64).assert_in(&metrics).await;
timeout_metric.clone().value(1u64).assert_in(&metrics).await;
let tcp_client = client.connect().await;
tokio::time::sleep(TIMEOUT + Duration::from_millis(15)) // just in case
.await;
io_metric.clone().value(1u64).assert_in(&metrics).await;
timeout_metric.clone().value(2u64).assert_in(&metrics).await;
drop(tcp_client);
}
/// Tests that TLS detect failure metrics are collected for the direct stack.
#[tokio::test]
async fn inbound_direct_multi() {

View File

@ -13,7 +13,7 @@ Configures and runs the outbound proxy
default = []
allow-loopback = []
test-subscriber = []
test-util = ["linkerd-app-test", "linkerd-meshtls-rustls/test-util", "dep:http-body"]
test-util = ["linkerd-app-test", "linkerd-meshtls/test-util", "dep:http-body"]
prometheus-client-rust-242 = [] # TODO
@ -32,7 +32,7 @@ thiserror = "2"
tokio = { version = "1", features = ["sync"] }
tonic = { workspace = true, default-features = false }
tower = { workspace = true, features = ["util"] }
tracing = "0.1"
tracing = { workspace = true }
linkerd-app-core = { path = "../core" }
linkerd-app-test = { path = "../test", optional = true }
@ -42,7 +42,7 @@ linkerd-http-prom = { path = "../../http/prom" }
linkerd-http-retry = { path = "../../http/retry" }
linkerd-http-route = { path = "../../http/route" }
linkerd-identity = { path = "../../identity" }
linkerd-meshtls-rustls = { path = "../../meshtls/rustls", optional = true }
linkerd-meshtls = { path = "../../meshtls", optional = true, default-features = false }
linkerd-opaq-route = { path = "../../opaq-route" }
linkerd-proxy-client-policy = { path = "../../proxy/client-policy", features = [
"proto",
@ -67,10 +67,10 @@ linkerd-app-test = { path = "../test", features = ["client-policy"] }
linkerd-http-box = { path = "../../http/box" }
linkerd-http-prom = { path = "../../http/prom", features = ["test-util"] }
linkerd-io = { path = "../../io", features = ["tokio-test"] }
linkerd-meshtls = { path = "../../meshtls", features = ["rustls"] }
linkerd-meshtls-rustls = { path = "../../meshtls/rustls", features = [
linkerd-meshtls = { path = "../../meshtls", features = [
"test-util",
] }
linkerd-mock-http-body = { path = "../../mock/http-body" }
linkerd-stack = { path = "../../stack", features = ["test-util"] }
linkerd-tracing = { path = "../../tracing", features = ["ansi"] }

View File

@ -134,7 +134,13 @@ impl<N> Outbound<N> {
.unwrap_or_else(|| (orig_dst, Default::default()));
// TODO(ver) We should be able to figure out resource coordinates for
// the endpoint?
synthesize_forward_policy(&META, detect_timeout, queue, addr, meta)
synthesize_forward_policy(
&META,
detect_timeout,
queue,
addr,
meta.into(),
)
},
);
return Ok((Some(profile), policy));
@ -189,7 +195,7 @@ pub fn synthesize_forward_policy(
timeout: Duration,
queue: policy::Queue,
addr: SocketAddr,
metadata: policy::EndpointMetadata,
metadata: Arc<policy::EndpointMetadata>,
) -> ClientPolicy {
policy_for_backend(
meta,

View File

@ -32,7 +32,7 @@ pub use self::balance::BalancerMetrics;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum Dispatch {
Balance(NameAddr, EwmaConfig),
Forward(Remote<ServerAddr>, Metadata),
Forward(Remote<ServerAddr>, Arc<Metadata>),
/// A backend dispatcher that explicitly fails all requests.
Fail {
message: Arc<str>,
@ -49,7 +49,7 @@ pub struct DispatcherFailed(Arc<str>);
pub struct Endpoint<T> {
addr: Remote<ServerAddr>,
is_local: bool,
metadata: Metadata,
metadata: Arc<Metadata>,
parent: T,
queue: QueueConfig,
close_server_connection_on_remote_proxy_error: bool,
@ -279,6 +279,13 @@ impl<T> svc::Param<tls::ConditionalClientTls> for Endpoint<T> {
}
}
impl<T> svc::Param<tls::ConditionalClientTlsLabels> for Endpoint<T> {
fn param(&self) -> tls::ConditionalClientTlsLabels {
let tls: tls::ConditionalClientTls = self.param();
tls.as_ref().map(tls::ClientTls::labels)
}
}
impl<T> svc::Param<http::Variant> for Endpoint<T>
where
T: svc::Param<http::Variant>,

View File

@ -121,7 +121,7 @@ where
let http2 = http2.override_from(metadata.http2_client_params());
Endpoint {
addr: Remote(ServerAddr(addr)),
metadata,
metadata: metadata.into(),
is_local,
parent: target.parent,
queue: http_queue,

View File

@ -289,6 +289,12 @@ impl svc::Param<tls::ConditionalClientTls> for Endpoint {
}
}
impl svc::Param<tls::ConditionalClientTlsLabels> for Endpoint {
fn param(&self) -> tls::ConditionalClientTlsLabels {
tls::ConditionalClientTlsLabels::None(tls::NoClientTls::Disabled)
}
}
impl svc::Param<Option<tcp::tagged_transport::PortOverride>> for Endpoint {
fn param(&self) -> Option<tcp::tagged_transport::PortOverride> {
None

View File

@ -8,7 +8,7 @@ use linkerd_app_core::{
transport::addrs::*,
Addr, Error, Infallible, NameAddr, CANONICAL_DST_HEADER,
};
use std::{fmt::Debug, hash::Hash};
use std::{fmt::Debug, hash::Hash, sync::Arc};
use tokio::sync::watch;
pub mod policy;
@ -32,7 +32,7 @@ pub enum Routes {
/// Fallback endpoint forwarding.
// TODO(ver) Remove this variant when policy routes are fully wired up.
Endpoint(Remote<ServerAddr>, Metadata),
Endpoint(Remote<ServerAddr>, Arc<Metadata>),
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
@ -64,7 +64,7 @@ enum RouterParams<T: Clone + Debug + Eq + Hash> {
Profile(profile::Params<T>),
// TODO(ver) Remove this variant when policy routes are fully wired up.
Endpoint(Remote<ServerAddr>, Metadata, T),
Endpoint(Remote<ServerAddr>, Arc<Metadata>, T),
}
// Only applies to requests with profiles.

View File

@ -4,6 +4,9 @@ use super::{
test_util::*,
LabelGrpcRouteRsp, LabelHttpRouteRsp, RequestMetrics,
};
use bytes::{Buf, Bytes};
use http_body::Body;
use http_body_util::BodyExt;
use linkerd_app_core::{
dns,
svc::{
@ -14,6 +17,10 @@ use linkerd_app_core::{
};
use linkerd_http_prom::body_data::request::RequestBodyFamilies;
use linkerd_proxy_client_policy as policy;
use std::task::Poll;
static GRPC_STATUS: http::HeaderName = http::HeaderName::from_static("grpc-status");
static GRPC_STATUS_OK: http::HeaderValue = http::HeaderValue::from_static("0");
#[tokio::test(flavor = "current_thread", start_paused = true)]
async fn http_request_statuses() {
@ -520,6 +527,160 @@ async fn http_route_request_body_frames() {
tracing::info!("passed");
}
#[tokio::test(flavor = "current_thread", start_paused = true)]
async fn http_response_body_drop_on_eos() {
use linkerd_app_core::svc::{Service, ServiceExt};
const EXPORT_HOSTNAME_LABELS: bool = false;
let _trace = linkerd_tracing::test::trace_init();
let super::HttpRouteMetrics {
requests,
body_data,
..
} = super::HttpRouteMetrics::default();
let parent_ref = crate::ParentRef(policy::Meta::new_default("parent"));
let route_ref = crate::RouteRef(policy::Meta::new_default("route"));
let (mut svc, mut handle) = mock_http_route_metrics(
&requests,
&body_data,
&parent_ref,
&route_ref,
EXPORT_HOSTNAME_LABELS,
);
// Define a request and a response.
let req = http::Request::default();
let rsp = http::Response::builder()
.status(200)
.body(BoxBody::from_static("contents"))
.unwrap();
// Two counters for 200 responses that do/don't have an error.
let ok = requests.get_statuses(&labels::Rsp(
labels::Route::new(parent_ref.clone(), route_ref.clone(), None),
labels::HttpRsp {
status: Some(http::StatusCode::OK),
error: None,
},
));
let err = requests.get_statuses(&labels::Rsp(
labels::Route::new(parent_ref.clone(), route_ref.clone(), None),
labels::HttpRsp {
status: Some(http::StatusCode::OK),
error: Some(labels::Error::Unknown),
},
));
debug_assert_eq!(ok.get(), 0);
debug_assert_eq!(err.get(), 0);
// Send the request, and obtain the response.
let mut body = {
handle.allow(1);
svc.ready().await.expect("ready");
let mut call = svc.call(req);
let (_req, tx) = tokio::select! {
_ = (&mut call) => unreachable!(),
res = handle.next_request() => res.unwrap(),
};
assert_eq!(ok.get(), 0);
tx.send_response(rsp);
call.await.unwrap().into_body()
};
// The counters are not incremented yet.
assert_eq!(ok.get(), 0);
assert_eq!(err.get(), 0);
// Poll a frame out of the body.
let data = body
.frame()
.await
.expect("yields a result")
.expect("yields a frame")
.into_data()
.ok()
.expect("yields data");
assert_eq!(data.chunk(), "contents".as_bytes());
assert_eq!(data.remaining(), "contents".len());
// Show that the body reports itself as being complete.
debug_assert!(body.is_end_stream());
assert_eq!(ok.get(), 1);
assert_eq!(err.get(), 0);
}
#[tokio::test(flavor = "current_thread", start_paused = true)]
async fn http_response_body_drop_early() {
use linkerd_app_core::svc::{Service, ServiceExt};
const EXPORT_HOSTNAME_LABELS: bool = false;
let _trace = linkerd_tracing::test::trace_init();
let super::HttpRouteMetrics {
requests,
body_data,
..
} = super::HttpRouteMetrics::default();
let parent_ref = crate::ParentRef(policy::Meta::new_default("parent"));
let route_ref = crate::RouteRef(policy::Meta::new_default("route"));
let (mut svc, mut handle) = mock_http_route_metrics(
&requests,
&body_data,
&parent_ref,
&route_ref,
EXPORT_HOSTNAME_LABELS,
);
// Define a request and a response.
let req = http::Request::default();
let rsp = http::Response::builder()
.status(200)
.body(BoxBody::from_static("contents"))
.unwrap();
// Two counters for 200 responses that do/don't have an error.
let ok = requests.get_statuses(&labels::Rsp(
labels::Route::new(parent_ref.clone(), route_ref.clone(), None),
labels::HttpRsp {
status: Some(http::StatusCode::OK),
error: None,
},
));
let err = requests.get_statuses(&labels::Rsp(
labels::Route::new(parent_ref.clone(), route_ref.clone(), None),
labels::HttpRsp {
status: Some(http::StatusCode::OK),
error: Some(labels::Error::Unknown),
},
));
debug_assert_eq!(ok.get(), 0);
debug_assert_eq!(err.get(), 0);
// Send the request, and obtain the response.
let body = {
handle.allow(1);
svc.ready().await.expect("ready");
let mut call = svc.call(req);
let (_req, tx) = tokio::select! {
_ = (&mut call) => unreachable!(),
res = handle.next_request() => res.unwrap(),
};
assert_eq!(ok.get(), 0);
tx.send_response(rsp);
call.await.unwrap().into_body()
};
// The counters are not incremented yet.
assert_eq!(ok.get(), 0);
assert_eq!(err.get(), 0);
// The body reports an error if it was not completed.
drop(body);
assert_eq!(ok.get(), 0);
assert_eq!(err.get(), 1);
}
#[tokio::test(flavor = "current_thread", start_paused = true)]
async fn grpc_request_statuses_ok() {
const EXPORT_HOSTNAME_LABELS: bool = true;
@ -723,6 +884,210 @@ async fn grpc_request_statuses_error_body() {
.await;
}
#[tokio::test(flavor = "current_thread", start_paused = true)]
async fn grpc_response_body_drop_on_eos() {
use linkerd_app_core::svc::{Service, ServiceExt};
const EXPORT_HOSTNAME_LABELS: bool = false;
let _trace = linkerd_tracing::test::trace_init();
let super::GrpcRouteMetrics {
requests,
body_data,
..
} = super::GrpcRouteMetrics::default();
let parent_ref = crate::ParentRef(policy::Meta::new_default("parent"));
let route_ref = crate::RouteRef(policy::Meta::new_default("route"));
let (mut svc, mut handle) = mock_grpc_route_metrics(
&requests,
&body_data,
&parent_ref,
&route_ref,
EXPORT_HOSTNAME_LABELS,
);
// Define a request and a response.
let req = http::Request::default();
let rsp = http::Response::builder()
.status(200)
.body({
let data = Poll::Ready(Some(Ok(Bytes::from_static(b"contents"))));
let trailers = {
let mut trailers = http::HeaderMap::with_capacity(1);
trailers.insert(GRPC_STATUS.clone(), GRPC_STATUS_OK.clone());
Poll::Ready(Some(Ok(trailers)))
};
let body = linkerd_mock_http_body::MockBody::default()
.then_yield_data(data)
.then_yield_trailer(trailers);
BoxBody::new(body)
})
.unwrap();
// Two counters for 200 responses that do/don't have an error.
let ok = requests.get_statuses(&labels::Rsp(
labels::Route::new(parent_ref.clone(), route_ref.clone(), None),
labels::GrpcRsp {
status: Some(tonic::Code::Ok),
error: None,
},
));
let err = requests.get_statuses(&labels::Rsp(
labels::Route::new(parent_ref.clone(), route_ref.clone(), None),
labels::GrpcRsp {
status: Some(tonic::Code::Ok),
error: Some(labels::Error::Unknown),
},
));
debug_assert_eq!(ok.get(), 0);
debug_assert_eq!(err.get(), 0);
// Send the request, and obtain the response.
let mut body = {
handle.allow(1);
svc.ready().await.expect("ready");
let mut call = svc.call(req);
let (_req, tx) = tokio::select! {
_ = (&mut call) => unreachable!(),
res = handle.next_request() => res.unwrap(),
};
assert_eq!(ok.get(), 0);
tx.send_response(rsp);
call.await.unwrap().into_body()
};
// The counters are not incremented yet.
assert_eq!(ok.get(), 0);
assert_eq!(err.get(), 0);
// Poll a frame out of the body.
let data = body
.frame()
.await
.expect("yields a result")
.expect("yields a frame")
.into_data()
.ok()
.expect("yields data");
assert_eq!(data.chunk(), "contents".as_bytes());
assert_eq!(data.remaining(), "contents".len());
// Poll the trailers out of the body.
let trls = body
.frame()
.await
.expect("yields a result")
.expect("yields a frame")
.into_trailers()
.ok()
.expect("yields trailers");
assert_eq!(trls.get(&GRPC_STATUS).unwrap(), GRPC_STATUS_OK);
// Show that the body reports itself as being complete.
debug_assert!(body.is_end_stream());
assert_eq!(ok.get(), 1);
assert_eq!(err.get(), 0);
}
#[tokio::test(flavor = "current_thread", start_paused = true)]
async fn grpc_response_body_drop_early() {
use linkerd_app_core::svc::{Service, ServiceExt};
const EXPORT_HOSTNAME_LABELS: bool = false;
let _trace = linkerd_tracing::test::trace_init();
let super::GrpcRouteMetrics {
requests,
body_data,
..
} = super::GrpcRouteMetrics::default();
let parent_ref = crate::ParentRef(policy::Meta::new_default("parent"));
let route_ref = crate::RouteRef(policy::Meta::new_default("route"));
let (mut svc, mut handle) = mock_grpc_route_metrics(
&requests,
&body_data,
&parent_ref,
&route_ref,
EXPORT_HOSTNAME_LABELS,
);
// Define a request and a response.
let req = http::Request::default();
let rsp = http::Response::builder()
.status(200)
.body({
let data = Poll::Ready(Some(Ok(Bytes::from_static(b"contents"))));
let trailers = {
let mut trailers = http::HeaderMap::with_capacity(1);
trailers.insert(GRPC_STATUS.clone(), GRPC_STATUS_OK.clone());
Poll::Ready(Some(Ok(trailers)))
};
let body = linkerd_mock_http_body::MockBody::default()
.then_yield_data(data)
.then_yield_trailer(trailers);
BoxBody::new(body)
})
.unwrap();
// Two counters for 200 responses that do/don't have an error.
let ok = requests.get_statuses(&labels::Rsp(
labels::Route::new(parent_ref.clone(), route_ref.clone(), None),
labels::GrpcRsp {
status: Some(tonic::Code::Ok),
error: None,
},
));
let err = requests.get_statuses(&labels::Rsp(
labels::Route::new(parent_ref.clone(), route_ref.clone(), None),
labels::GrpcRsp {
status: None,
error: Some(labels::Error::Unknown),
},
));
debug_assert_eq!(ok.get(), 0);
debug_assert_eq!(err.get(), 0);
// Send the request, and obtain the response.
let mut body = {
handle.allow(1);
svc.ready().await.expect("ready");
let mut call = svc.call(req);
let (_req, tx) = tokio::select! {
_ = (&mut call) => unreachable!(),
res = handle.next_request() => res.unwrap(),
};
assert_eq!(ok.get(), 0);
tx.send_response(rsp);
call.await.unwrap().into_body()
};
// The counters are not incremented yet.
assert_eq!(ok.get(), 0);
assert_eq!(err.get(), 0);
// Poll a frame out of the body.
let data = body
.frame()
.await
.expect("yields a result")
.expect("yields a frame")
.into_data()
.ok()
.expect("yields data");
assert_eq!(data.chunk(), "contents".as_bytes());
assert_eq!(data.remaining(), "contents".len());
// The counters are not incremented yet.
debug_assert!(!body.is_end_stream());
assert_eq!(ok.get(), 0);
assert_eq!(err.get(), 0);
// Then, drop the body without polling the trailers.
drop(body);
assert_eq!(ok.get(), 0);
assert_eq!(err.get(), 1);
}
// === Utils ===
const MOCK_GRPC_REQ_URI: &str = "http://host/svc/method";

View File

@ -54,7 +54,7 @@ impl retry::Policy for RetryPolicy {
if let Some(codes) = self.retryable_grpc_statuses.as_ref() {
let grpc_status = Self::grpc_status(rsp);
let retryable = grpc_status.map_or(false, |c| codes.contains(c));
let retryable = grpc_status.is_some_and(|c| codes.contains(c));
tracing::debug!(retryable, grpc.status = ?grpc_status);
if retryable {
return true;

View File

@ -214,7 +214,7 @@ impl Outbound<()> {
detect_timeout,
queue,
addr,
meta,
meta.into(),
);
}

View File

@ -146,7 +146,7 @@ impl Outbound<()> {
export_hostname_labels: bool,
) -> impl policy::GetPolicy
where
C: tonic::client::GrpcService<tonic::body::BoxBody, Error = Error>,
C: tonic::client::GrpcService<tonic::body::Body, Error = Error>,
C: Clone + Unpin + Send + Sync + 'static,
C::ResponseBody: proxy::http::Body<Data = tonic::codegen::Bytes, Error = Error>,
C::ResponseBody: Send + 'static,

View File

@ -130,7 +130,7 @@ impl OutboundMetrics {
}
}
impl FmtMetrics for OutboundMetrics {
impl legacy::FmtMetrics for OutboundMetrics {
fn fmt_metrics(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.http_errors.fmt_metrics(f)?;
self.tcp_errors.fmt_metrics(f)?;
@ -243,7 +243,7 @@ impl EncodeLabelSet for RouteRef {
// === impl ConcreteLabels ===
impl FmtLabels for ConcreteLabels {
impl legacy::FmtLabels for ConcreteLabels {
fn fmt_labels(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let ConcreteLabels(parent, backend) = self;

View File

@ -5,7 +5,7 @@ pub(crate) use self::{http::Http, tcp::Tcp};
use crate::http::IdentityRequired;
use linkerd_app_core::{
errors::{FailFastError, LoadShedError},
metrics::FmtLabels,
metrics::legacy::FmtLabels,
proxy::http::ResponseTimeoutError,
};
use std::fmt;

View File

@ -1,6 +1,9 @@
use super::ErrorKind;
use linkerd_app_core::{
metrics::{metrics, Counter, FmtMetrics},
metrics::{
legacy::{Counter, FmtMetrics},
metrics,
},
svc, Error,
};
use parking_lot::RwLock;

View File

@ -1,6 +1,9 @@
use super::ErrorKind;
use linkerd_app_core::{
metrics::{metrics, Counter, FmtMetrics},
metrics::{
legacy::{Counter, FmtMetrics},
metrics,
},
svc,
transport::{labels::TargetAddr, OrigDstAddr},
Error,

View File

@ -32,7 +32,7 @@ use tracing::info_span;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum Dispatch {
Balance(NameAddr, balance::EwmaConfig),
Forward(Remote<ServerAddr>, Metadata),
Forward(Remote<ServerAddr>, Arc<Metadata>),
/// A backend dispatcher that explicitly fails all requests.
Fail {
message: Arc<str>,
@ -57,7 +57,7 @@ pub struct ConcreteError {
pub struct Endpoint<T> {
addr: Remote<ServerAddr>,
is_local: bool,
metadata: Metadata,
metadata: Arc<Metadata>,
parent: T,
}
@ -196,7 +196,7 @@ impl<C> Outbound<C> {
let is_local = inbound_ips.contains(&addr.ip());
Endpoint {
addr: Remote(ServerAddr(addr)),
metadata,
metadata: metadata.into(),
is_local,
parent: target.parent,
}
@ -419,3 +419,10 @@ impl<T> svc::Param<tls::ConditionalClientTls> for Endpoint<T> {
))
}
}
impl<T> svc::Param<tls::ConditionalClientTlsLabels> for Endpoint<T> {
fn param(&self) -> tls::ConditionalClientTlsLabels {
let tls: tls::ConditionalClientTls = self.param();
tls.as_ref().map(tls::ClientTls::labels)
}
}

View File

@ -160,9 +160,7 @@ async fn balances() {
}
assert!(
seen0 && seen1,
"Both endpoints must be used; ep0={} ep1={}",
seen0,
seen1
"Both endpoints must be used; ep0={seen0} ep1={seen1}"
);
// When we remove the ep0, all traffic goes to ep1:
@ -190,8 +188,7 @@ async fn balances() {
task.abort();
assert!(
errors::is_caused_by::<FailFastError>(&*err),
"unexpected error: {}",
err
"unexpected error: {err}"
);
assert!(resolved.only_configured(), "Resolution must be reused");
}

View File

@ -33,7 +33,7 @@ static INVALID_POLICY: once_cell::sync::OnceCell<ClientPolicy> = once_cell::sync
impl<S> Api<S>
where
S: tonic::client::GrpcService<tonic::body::BoxBody, Error = Error> + Clone,
S: tonic::client::GrpcService<tonic::body::Body, Error = Error> + Clone,
S::ResponseBody: http::Body<Data = tonic::codegen::Bytes, Error = Error> + Send + 'static,
{
pub(crate) fn new(
@ -59,7 +59,7 @@ where
impl<S> Service<Addr> for Api<S>
where
S: tonic::client::GrpcService<tonic::body::BoxBody, Error = Error>,
S: tonic::client::GrpcService<tonic::body::Body, Error = Error>,
S: Clone + Send + Sync + 'static,
S::ResponseBody: http::Body<Data = tonic::codegen::Bytes, Error = Error> + Send + 'static,
S::Future: Send + 'static,

View File

@ -8,8 +8,8 @@ use std::task::{Context, Poll};
#[derive(Clone, Debug)]
pub struct Connect {
pub addr: Remote<ServerAddr>,
pub tls: tls::ConditionalClientTls,
addr: Remote<ServerAddr>,
tls: tls::ConditionalClientTls,
}
/// Prevents outbound connections on the loopback interface, unless the
@ -77,6 +77,12 @@ where
// === impl Connect ===
impl Connect {
pub fn new(addr: Remote<ServerAddr>, tls: tls::ConditionalClientTls) -> Self {
Self { addr, tls }
}
}
impl svc::Param<Remote<ServerAddr>> for Connect {
fn param(&self) -> Remote<ServerAddr> {
self.addr
@ -88,3 +94,14 @@ impl svc::Param<tls::ConditionalClientTls> for Connect {
self.tls.clone()
}
}
#[cfg(test)]
impl Connect {
pub fn addr(&self) -> &Remote<ServerAddr> {
&self.addr
}
pub fn tls(&self) -> &tls::ConditionalClientTls {
&self.tls
}
}

View File

@ -67,10 +67,7 @@ where
let tls: tls::ConditionalClientTls = ep.param();
if let tls::ConditionalClientTls::None(reason) = tls {
trace!(%reason, "Not attempting opaque transport");
let target = Connect {
addr: ep.param(),
tls,
};
let target = Connect::new(ep.param(), tls);
return Box::pin(self.inner.connect(target).err_into::<Error>());
}
@ -109,10 +106,10 @@ where
let protocol: Option<SessionProtocol> = ep.param();
let connect = self.inner.connect(Connect {
addr: Remote(ServerAddr((addr.ip(), connect_port).into())),
let connect = self.inner.connect(Connect::new(
Remote(ServerAddr((addr.ip(), connect_port).into())),
tls,
});
));
Box::pin(async move {
let (mut io, meta) = connect.await.map_err(Into::into)?;
@ -203,9 +200,9 @@ mod test {
) -> impl Fn(Connect) -> futures::future::Ready<Result<(tokio_test::io::Mock, ConnectMeta), io::Error>>
{
move |ep| {
let Remote(ServerAddr(sa)) = ep.addr;
let Remote(ServerAddr(sa)) = ep.addr();
assert_eq!(sa.port(), 4143);
assert!(ep.tls.is_some());
assert!(ep.tls().is_some());
let buf = header.encode_prefaced_buf().expect("Must encode");
let io = tokio_test::io::Builder::new()
.write(&buf[..])
@ -225,9 +222,9 @@ mod test {
let svc = TaggedTransport {
inner: service_fn(|ep: Connect| {
let Remote(ServerAddr(sa)) = ep.addr;
let Remote(ServerAddr(sa)) = ep.addr();
assert_eq!(sa.port(), 4321);
assert!(ep.tls.is_none());
assert!(ep.tls().is_none());
let io = tokio_test::io::Builder::new().write(b"hello").build();
let meta = tls::ConnectMeta {
socket: Local(ClientAddr(([0, 0, 0, 0], 0).into())),

View File

@ -60,7 +60,7 @@ pub(crate) fn runtime() -> (ProxyRuntime, drain::Signal) {
let (tap, _) = tap::new();
let (metrics, _) = metrics::Metrics::new(std::time::Duration::from_secs(10));
let runtime = ProxyRuntime {
identity: linkerd_meshtls_rustls::creds::default_for_test().1.into(),
identity: linkerd_meshtls::creds::default_for_test().1,
metrics: metrics.proxy,
tap,
span_sink: None,

View File

@ -31,7 +31,7 @@ use tracing::info_span;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum Dispatch {
Balance(NameAddr, balance::EwmaConfig),
Forward(Remote<ServerAddr>, Metadata),
Forward(Remote<ServerAddr>, Arc<Metadata>),
/// A backend dispatcher that explicitly fails all requests.
Fail {
message: Arc<str>,
@ -56,7 +56,7 @@ pub struct ConcreteError {
pub struct Endpoint<T> {
addr: Remote<ServerAddr>,
is_local: bool,
metadata: Metadata,
metadata: Arc<Metadata>,
parent: T,
}
@ -174,7 +174,7 @@ impl<C> Outbound<C> {
let is_local = inbound_ips.contains(&addr.ip());
Endpoint {
addr: Remote(ServerAddr(addr)),
metadata,
metadata: metadata.into(),
is_local,
parent: target.parent,
}
@ -385,3 +385,10 @@ impl<T> svc::Param<tls::ConditionalClientTls> for Endpoint<T> {
))
}
}
impl<T> svc::Param<tls::ConditionalClientTlsLabels> for Endpoint<T> {
fn param(&self) -> tls::ConditionalClientTlsLabels {
let tls: tls::ConditionalClientTls = self.param();
tls.as_ref().map(tls::ClientTls::labels)
}
}

View File

@ -11,13 +11,18 @@ use linkerd_proxy_client_policy::{self as client_policy, tls::sni};
use parking_lot::Mutex;
use std::{
collections::HashMap,
marker::PhantomData,
net::SocketAddr,
sync::Arc,
task::{Context, Poll},
time::Duration,
};
use tokio::sync::watch;
use tokio_rustls::rustls::pki_types::DnsName;
use tokio_rustls::rustls::{
internal::msgs::codec::{Codec, Reader},
pki_types::DnsName,
InvalidMessage,
};
mod basic;
@ -142,7 +147,7 @@ fn default_backend(addr: SocketAddr) -> client_policy::Backend {
capacity: 100,
failfast_timeout: Duration::from_secs(10),
},
dispatcher: BackendDispatcher::Forward(addr, EndpointMetadata::default()),
dispatcher: BackendDispatcher::Forward(addr, EndpointMetadata::default().into()),
}
}
@ -170,44 +175,57 @@ fn sni_route(backend: client_policy::Backend, sni: sni::MatchSni) -> client_poli
// generates a sample ClientHello TLS message for testing
fn generate_client_hello(sni: &str) -> Vec<u8> {
use tokio_rustls::rustls::{
internal::msgs::{
base::Payload,
codec::{Codec, Reader},
enums::Compression,
handshake::{
ClientExtension, ClientHelloPayload, HandshakeMessagePayload, HandshakePayload,
Random, ServerName, SessionId,
},
message::{MessagePayload, PlainMessage},
},
CipherSuite, ContentType, HandshakeType, ProtocolVersion,
internal::msgs::{base::Payload, codec::Codec, message::PlainMessage},
ContentType, ProtocolVersion,
};
let sni = DnsName::try_from(sni.to_string()).unwrap();
let sni = trim_hostname_trailing_dot_for_sni(&sni);
let mut server_name_bytes = vec![];
0u8.encode(&mut server_name_bytes); // encode the type first
(sni.as_ref().len() as u16).encode(&mut server_name_bytes); // then the length as u16
server_name_bytes.extend_from_slice(sni.as_ref().as_bytes()); // then the server name itself
// rustls has internal-only types that can encode a ClientHello, but they are mostly
// inaccessible and an unstable part of the public API anyway. Manually encode one here for
// testing only instead.
let server_name =
ServerName::read(&mut Reader::init(&server_name_bytes)).expect("Server name is valid");
let mut hs_payload_bytes = vec![];
1u8.encode(&mut hs_payload_bytes); // client hello ID
let hs_payload = HandshakeMessagePayload {
typ: HandshakeType::ClientHello,
payload: HandshakePayload::ClientHello(ClientHelloPayload {
client_version: ProtocolVersion::TLSv1_2,
random: Random::from([0; 32]),
session_id: SessionId::read(&mut Reader::init(&[0])).unwrap(),
cipher_suites: vec![CipherSuite::TLS_NULL_WITH_NULL_NULL],
compression_methods: vec![Compression::Null],
extensions: vec![ClientExtension::ServerName(vec![server_name])],
}),
let client_hello_body = {
let mut payload = LengthPayload::<U24>::empty();
payload.buf.extend_from_slice(&[0x03, 0x03]); // client version, TLSv1.2
payload.buf.extend_from_slice(&[0u8; 32]); // random
0u8.encode(&mut payload.buf); // session ID
LengthPayload::<u16>::from_slice(&[0x00, 0x00] /* TLS_NULL_WITH_NULL_NULL */)
.encode(&mut payload.buf);
LengthPayload::<u8>::from_slice(&[0x00] /* no compression */).encode(&mut payload.buf);
let extensions = {
let mut payload = LengthPayload::<u16>::empty();
0u16.encode(&mut payload.buf); // server name extension ID
let server_name_extension = {
let mut payload = LengthPayload::<u16>::empty();
let server_name = {
let mut payload = LengthPayload::<u16>::empty();
0u8.encode(&mut payload.buf); // DNS hostname ID
LengthPayload::<u16>::from_slice(sni.as_ref().as_bytes())
.encode(&mut payload.buf);
payload
};
server_name.encode(&mut payload.buf);
payload
};
server_name_extension.encode(&mut payload.buf);
payload
};
extensions.encode(&mut payload.buf);
payload
};
let mut hs_payload_bytes = Vec::default();
MessagePayload::handshake(hs_payload).encode(&mut hs_payload_bytes);
client_hello_body.encode(&mut hs_payload_bytes);
let message = PlainMessage {
typ: ContentType::Handshake,
@ -218,6 +236,65 @@ fn generate_client_hello(sni: &str) -> Vec<u8> {
message.into_unencrypted_opaque().encode()
}
#[derive(Debug)]
struct LengthPayload<T> {
buf: Vec<u8>,
_boo: PhantomData<fn() -> T>,
}
impl<T> LengthPayload<T> {
fn empty() -> Self {
Self {
buf: vec![],
_boo: PhantomData,
}
}
fn from_slice(s: &[u8]) -> Self {
Self {
buf: s.to_vec(),
_boo: PhantomData,
}
}
}
impl Codec<'_> for LengthPayload<u8> {
fn encode(&self, bytes: &mut Vec<u8>) {
(self.buf.len() as u8).encode(bytes);
bytes.extend_from_slice(&self.buf);
}
fn read(_: &mut Reader<'_>) -> std::result::Result<Self, InvalidMessage> {
unimplemented!()
}
}
impl Codec<'_> for LengthPayload<u16> {
fn encode(&self, bytes: &mut Vec<u8>) {
(self.buf.len() as u16).encode(bytes);
bytes.extend_from_slice(&self.buf);
}
fn read(_: &mut Reader<'_>) -> std::result::Result<Self, InvalidMessage> {
unimplemented!()
}
}
#[derive(Debug)]
struct U24;
impl Codec<'_> for LengthPayload<U24> {
fn encode(&self, bytes: &mut Vec<u8>) {
let len = self.buf.len() as u32;
bytes.extend_from_slice(&len.to_be_bytes()[1..]);
bytes.extend_from_slice(&self.buf);
}
fn read(_: &mut Reader<'_>) -> std::result::Result<Self, InvalidMessage> {
unimplemented!()
}
}
fn trim_hostname_trailing_dot_for_sni(dns_name: &DnsName<'_>) -> DnsName<'static> {
let dns_name_str = dns_name.as_ref();

View File

@ -43,7 +43,7 @@ impl Config {
) -> Result<
Dst<
impl svc::Service<
http::Request<tonic::body::BoxBody>,
http::Request<tonic::body::Body>,
Response = http::Response<control::RspBody>,
Error = Error,
Future = impl Send,

View File

@ -83,8 +83,8 @@ pub enum ParseError {
),
#[error("not a valid port range")]
NotAPortRange,
#[error(transparent)]
AddrError(addr::Error),
#[error("{0}")]
AddrError(#[source] addr::Error),
#[error("only two addresses are supported")]
TooManyAddrs,
#[error("not a valid identity name")]
@ -233,8 +233,12 @@ pub const ENV_IDENTITY_IDENTITY_SERVER_ID: &str = "LINKERD2_PROXY_IDENTITY_SERVE
pub const ENV_IDENTITY_IDENTITY_SERVER_NAME: &str = "LINKERD2_PROXY_IDENTITY_SERVER_NAME";
// If this config is set, then the proxy will be configured to use Spire as identity
// provider
// provider. On Unix systems this needs to be a path to a UDS while on Windows - a
// named pipe path.
pub const ENV_IDENTITY_SPIRE_WORKLOAD_API_ADDRESS: &str =
"LINKERD2_PROXY_IDENTITY_SPIRE_WORKLOAD_API_ADDRESS";
pub const ENV_IDENTITY_SPIRE_SOCKET: &str = "LINKERD2_PROXY_IDENTITY_SPIRE_SOCKET";
pub const IDENTITY_SPIRE_BASE: &str = "LINKERD2_PROXY_IDENTITY_SPIRE";
const DEFAULT_SPIRE_BACKOFF: ExponentialBackoff =
ExponentialBackoff::new_unchecked(Duration::from_millis(100), Duration::from_secs(1), 0.1);
@ -290,7 +294,7 @@ const DEFAULT_INBOUND_HTTP_FAILFAST_TIMEOUT: Duration = Duration::from_secs(1);
const DEFAULT_INBOUND_DETECT_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_INBOUND_CONNECT_TIMEOUT: Duration = Duration::from_millis(300);
const DEFAULT_INBOUND_CONNECT_BACKOFF: ExponentialBackoff =
ExponentialBackoff::new_unchecked(Duration::from_millis(100), Duration::from_millis(500), 0.1);
ExponentialBackoff::new_unchecked(Duration::from_millis(100), Duration::from_secs(10), 0.1);
const DEFAULT_OUTBOUND_TCP_QUEUE_CAPACITY: usize = 10_000;
const DEFAULT_OUTBOUND_TCP_FAILFAST_TIMEOUT: Duration = Duration::from_secs(3);
@ -299,7 +303,7 @@ const DEFAULT_OUTBOUND_HTTP_FAILFAST_TIMEOUT: Duration = Duration::from_secs(3);
const DEFAULT_OUTBOUND_DETECT_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_OUTBOUND_CONNECT_TIMEOUT: Duration = Duration::from_secs(1);
const DEFAULT_OUTBOUND_CONNECT_BACKOFF: ExponentialBackoff =
ExponentialBackoff::new_unchecked(Duration::from_millis(100), Duration::from_millis(500), 0.1);
ExponentialBackoff::new_unchecked(Duration::from_millis(100), Duration::from_secs(60), 0.1);
const DEFAULT_CONTROL_QUEUE_CAPACITY: usize = 100;
const DEFAULT_CONTROL_FAILFAST_TIMEOUT: Duration = Duration::from_secs(10);
@ -339,12 +343,12 @@ const DEFAULT_INBOUND_HTTP1_CONNECTION_POOL_IDLE_TIMEOUT: Duration = Duration::f
// TODO(ver) This should be configurable at the load balancer level.
const DEFAULT_OUTBOUND_HTTP1_CONNECTION_POOL_IDLE_TIMEOUT: Duration = Duration::from_secs(3);
// By default, we don't limit the number of connections a connection pol may
// use, as doing so can severely impact CPU utilization for applications with
// many concurrent requests. It's generally preferable to use the MAX_IDLE_AGE
// limitations to quickly drop idle connections.
const DEFAULT_INBOUND_MAX_IDLE_CONNS_PER_ENDPOINT: usize = usize::MAX;
const DEFAULT_OUTBOUND_MAX_IDLE_CONNS_PER_ENDPOINT: usize = usize::MAX;
// By default, we limit the number of connections that may be opened per-host.
// We pick a high number (10k) that shouldn't interfere with most workloads, but
// will prevent issues with our outbound HTTP client from exhausting the file
// descriptors available to the process.
const DEFAULT_INBOUND_MAX_IDLE_CONNS_PER_ENDPOINT: usize = 10_000;
const DEFAULT_OUTBOUND_MAX_IDLE_CONNS_PER_ENDPOINT: usize = 10_000;
// These settings limit the number of requests that have not received responses,
// including those buffered in the proxy and dispatched to the destination
@ -909,8 +913,13 @@ pub fn parse_config<S: Strings>(strings: &S) -> Result<super::Config, EnvError>
let identity = {
let tls = tls?;
match strings.get(ENV_IDENTITY_SPIRE_SOCKET)? {
Some(socket) => match &tls.id {
match parse_deprecated(
strings,
ENV_IDENTITY_SPIRE_WORKLOAD_API_ADDRESS,
ENV_IDENTITY_SPIRE_SOCKET,
|s| Ok(s.to_string()),
)? {
Some(workload_api_addr) => match &tls.id {
// TODO: perform stricter SPIFFE ID validation following:
// https://github.com/spiffe/spiffe/blob/27b59b81ba8c56885ac5d4be73b35b9b3305fd7a/standards/SPIFFE-ID.md
identity::Id::Uri(uri)
@ -919,7 +928,7 @@ pub fn parse_config<S: Strings>(strings: &S) -> Result<super::Config, EnvError>
identity::Config::Spire {
tls,
client: spire::Config {
socket_addr: std::sync::Arc::new(socket),
workload_api_addr: std::sync::Arc::new(workload_api_addr),
backoff: parse_backoff(
strings,
IDENTITY_SPIRE_BASE,
@ -1108,11 +1117,11 @@ pub fn parse_backoff<S: Strings>(
base: &str,
default: ExponentialBackoff,
) -> Result<ExponentialBackoff, EnvError> {
let min_env = format!("LINKERD2_PROXY_{}_EXP_BACKOFF_MIN", base);
let min_env = format!("LINKERD2_PROXY_{base}_EXP_BACKOFF_MIN");
let min = parse(strings, &min_env, parse_duration);
let max_env = format!("LINKERD2_PROXY_{}_EXP_BACKOFF_MAX", base);
let max_env = format!("LINKERD2_PROXY_{base}_EXP_BACKOFF_MAX");
let max = parse(strings, &max_env, parse_duration);
let jitter_env = format!("LINKERD2_PROXY_{}_EXP_BACKOFF_JITTER", base);
let jitter_env = format!("LINKERD2_PROXY_{base}_EXP_BACKOFF_JITTER");
let jitter = parse(strings, &jitter_env, parse_number::<f64>);
match (min?, max?, jitter?) {
@ -1247,7 +1256,7 @@ pub fn parse_linkerd_identity_config<S: Strings>(
Ok((control, certify))
}
(addr, end_entity_dir, token, _minr, _maxr) => {
let s = format!("{0}_ADDR and {0}_NAME", ENV_IDENTITY_SVC_BASE);
let s = format!("{ENV_IDENTITY_SVC_BASE}_ADDR and {ENV_IDENTITY_SVC_BASE}_NAME");
let svc_env: &str = s.as_str();
for (unset, name) in &[
(addr.is_none(), svc_env),

View File

@ -172,11 +172,11 @@ mod tests {
fn test_unit<F: Fn(u64) -> Duration>(unit: &str, to_duration: F) {
for v in &[0, 1, 23, 456_789] {
let d = to_duration(*v);
let text = format!("{}{}", v, unit);
assert_eq!(parse_duration(&text), Ok(d), "text=\"{}\"", text);
let text = format!("{v}{unit}");
assert_eq!(parse_duration(&text), Ok(d), "text=\"{text}\"");
let text = format!(" {}{}\t", v, unit);
assert_eq!(parse_duration(&text), Ok(d), "text=\"{}\"", text);
let text = format!(" {v}{unit}\t");
assert_eq!(parse_duration(&text), Ok(d), "text=\"{text}\"");
}
}
@ -245,7 +245,7 @@ mod tests {
fn p(s: &str) -> Result<Vec<String>, ParseError> {
let mut sfxs = parse_dns_suffixes(s)?
.into_iter()
.map(|s| format!("{}", s))
.map(|s| format!("{s}"))
.collect::<Vec<_>>();
sfxs.sort();
Ok(sfxs)

View File

@ -4,7 +4,8 @@ pub use linkerd_app_core::identity::{client, Id};
use linkerd_app_core::{
control, dns,
identity::{
client::linkerd::Certify, creds, CertMetrics, Credentials, DerX509, Mode, WithCertMetrics,
client::linkerd::Certify, creds, watch as watch_identity, CertMetrics, Credentials,
DerX509, WithCertMetrics,
},
metrics::{prom, ControlHttp as ClientMetrics},
Result,
@ -109,7 +110,7 @@ impl Config {
}
}
Self::Spire { client, tls } => {
let addr = client.socket_addr.clone();
let addr = client.workload_api_addr.clone();
let spire = spire::client::Spire::new(tls.id.clone());
let (store, receiver, ready) = watch(tls, metrics.cert)?;
@ -137,8 +138,7 @@ fn watch(
watch::Receiver<bool>,
)> {
let (tx, ready) = watch::channel(false);
let (store, receiver) =
Mode::default().watch(tls.id, tls.server_name, &tls.trust_anchors_pem)?;
let (store, receiver) = watch_identity(tls.id, tls.server_name, &tls.trust_anchors_pem)?;
let cred = WithCertMetrics::new(metrics, NotifyReady { store, tx });
Ok((cred, receiver, ready))
}

View File

@ -19,9 +19,10 @@ use linkerd_app_core::{
config::ServerConfig,
control::{ControlAddr, Metrics as ControlMetrics},
dns, drain,
metrics::{prom, FmtMetrics},
metrics::{legacy::FmtMetrics, prom},
serve,
svc::Param,
tls_info,
transport::{addrs::*, listen::Bind},
Error, ProxyRuntime,
};
@ -83,13 +84,13 @@ pub struct App {
tap: tap::Tap,
}
// === impl Config ===
impl Config {
pub fn try_from_env() -> Result<Self, env::EnvError> {
env::Env.try_config()
}
}
impl Config {
/// Build an application.
///
/// It is currently required that this be run on a Tokio runtime, since some
@ -251,9 +252,6 @@ impl Config {
export_hostname_labels,
);
let dst_addr = dst.addr.clone();
// registry.sub_registry_with_prefix("gateway"),
let gateway = gateway::Gateway::new(gateway, inbound.clone(), outbound.clone()).stack(
dst.resolve.clone(),
dst.profiles.clone(),
@ -304,6 +302,7 @@ impl Config {
error!(%error, "Failed to register process metrics");
}
registry.register("proxy_build_info", "Proxy build info", BUILD_INFO.metric());
registry.register("rustls_info", "Proxy TLS info", tls_info::metric());
let admin = {
let identity = identity.receiver().server();
@ -330,7 +329,7 @@ impl Config {
Ok(App {
admin,
dst: dst_addr,
dst: dst.addr,
drain: drain_tx,
identity,
inbound_addr,
@ -358,6 +357,8 @@ impl Config {
}
}
// === impl App ===
impl App {
pub fn admin_addr(&self) -> Local<ServerAddr> {
self.admin.listen_addr
@ -396,7 +397,7 @@ impl App {
pub fn tracing_addr(&self) -> Option<&ControlAddr> {
match self.trace_collector {
trace_collector::TraceCollector::Disabled { .. } => None,
trace_collector::TraceCollector::Disabled => None,
crate::trace_collector::TraceCollector::Enabled(ref oc) => Some(&oc.addr),
}
}

View File

@ -46,7 +46,7 @@ impl Config {
) -> Result<
Policy<
impl svc::Service<
http::Request<tonic::body::BoxBody>,
http::Request<tonic::body::Body>,
Response = http::Response<control::RspBody>,
Error = Error,
Future = impl Send,

View File

@ -4,40 +4,26 @@ use tokio::sync::watch;
pub use linkerd_app_core::identity::client::spire as client;
#[cfg(target_os = "linux")]
const UNIX_PREFIX: &str = "unix:";
#[cfg(target_os = "linux")]
const TONIC_DEFAULT_URI: &str = "http://[::]:50051";
#[derive(Clone, Debug)]
pub struct Config {
pub socket_addr: Arc<String>,
pub workload_api_addr: Arc<String>,
pub backoff: ExponentialBackoff,
}
// Connects to SPIRE workload API via Unix Domain Socket
pub struct Client {
#[cfg_attr(not(target_os = "linux"), allow(dead_code))]
config: Config,
}
// === impl Client ===
#[cfg(target_os = "linux")]
impl From<Config> for Client {
fn from(config: Config) -> Self {
Self { config }
}
}
#[cfg(not(target_os = "linux"))]
impl From<Config> for Client {
fn from(_: Config) -> Self {
panic!("Spire is supported on Linux only")
}
}
#[cfg(target_os = "linux")]
impl tower::Service<()> for Client {
type Response = tonic::Response<watch::Receiver<client::SvidUpdate>>;
type Error = Error;
@ -51,25 +37,43 @@ impl tower::Service<()> for Client {
}
fn call(&mut self, _req: ()) -> Self::Future {
let socket = self.config.socket_addr.clone();
let addr = self.config.workload_api_addr.clone();
let backoff = self.config.backoff;
Box::pin(async move {
use tokio::net::UnixStream;
use tonic::transport::{Endpoint, Uri};
// Strip the 'unix:' prefix for tonic compatibility.
let stripped_path = socket
.strip_prefix(UNIX_PREFIX)
.unwrap_or(socket.as_str())
.to_string();
// We will ignore this uri because uds do not use it
// if your connector does use the uri it will be provided
// as the request to the `MakeConnection`.
let chan = Endpoint::try_from(TONIC_DEFAULT_URI)?
.connect_with_connector(tower::util::service_fn(move |_: Uri| {
use futures::TryFutureExt;
UnixStream::connect(stripped_path.clone()).map_ok(hyper_util::rt::TokioIo::new)
#[cfg(unix)]
{
use futures::TryFutureExt;
// The 'unix:' scheme must be stripped from socket paths.
let path = addr.strip_prefix("unix:").unwrap_or(addr.as_str());
tokio::net::UnixStream::connect(path.to_string())
.map_ok(hyper_util::rt::TokioIo::new)
}
#[cfg(windows)]
{
use tokio::net::windows::named_pipe;
let named_pipe_path = addr.clone();
let client = named_pipe::ClientOptions::new()
.open(named_pipe_path.as_str())
.map(hyper_util::rt::TokioIo::new);
futures::future::ready(client)
}
#[cfg(not(any(unix, windows)))]
{
compile_error!("Spire is supported only on Windows and Unix systems.");
futures::future::pending()
}
}))
.await?;
@ -80,21 +84,3 @@ impl tower::Service<()> for Client {
})
}
}
#[cfg(not(target_os = "linux"))]
impl tower::Service<()> for Client {
type Response = tonic::Response<watch::Receiver<client::SvidUpdate>>;
type Error = Error;
type Future = futures::future::BoxFuture<'static, Result<Self::Response, Self::Error>>;
fn poll_ready(
&mut self,
_cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Result<(), Self::Error>> {
unimplemented!("Spire is supported on Linux only")
}
fn call(&mut self, _req: ()) -> Self::Future {
unimplemented!("Spire is supported on Linux only")
}
}

Some files were not shown because too many files have changed in this diff Show More