[GH-ISSUE #2002] Pass quinn::Endpoint for DoQ and DoH3 #845

Open
opened 2026-03-16 00:32:32 +03:00 by kerem · 3 comments
Owner

Originally created by @daxpedda on GitHub (Aug 21, 2023).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/2002

Is your feature request related to a problem? Please describe.
In an effort to reduce the resources used in my application, I would like to reuse the socket and other resources held by quinn::Endpoint across multiple libraries in use.

Describe the solution you'd like
Add a method to trust_dns_proto::quic::QuicClientStreamBuilder and trust_dns_resolver::config::NameServerConfigGroup to supply a quinn::Endpoint.

Describe alternatives you've considered
There isn't a real alternative I can think of.

Additional context
Happy to write up the PR!

Originally created by @daxpedda on GitHub (Aug 21, 2023). Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/2002 **Is your feature request related to a problem? Please describe.** In an effort to reduce the resources used in my application, I would like to reuse the socket and other resources held by `quinn::Endpoint` across multiple libraries in use. **Describe the solution you'd like** Add a method to `trust_dns_proto::quic::QuicClientStreamBuilder` and `trust_dns_resolver::config::NameServerConfigGroup` to supply a `quinn::Endpoint`. **Describe alternatives you've considered** There isn't a real alternative I can think of. **Additional context** Happy to write up the PR!
Author
Owner

@djc commented on GitHub (Aug 21, 2023):

Makes sense to me.

<!-- gh-comment-id:1686789760 --> @djc commented on GitHub (Aug 21, 2023): Makes sense to me.
Author
Owner

@daxpedda commented on GitHub (Aug 21, 2023):

Was just working on an implementation but hit a roadblock:
github.com/bluejekyll/trust-dns@fba0c67f8f/crates/proto/src/quic/quic_client_stream.rs (L244)
github.com/bluejekyll/trust-dns@fba0c67f8f/crates/proto/src/quic/quic_client_stream.rs (L254-L261)

There is currently no way to get that information out of an Endpoint. I was about to make a PR to Quinn to expose the default client configuration from Endpoint, but that didn't seem to actually help, because quinn::Endpoint stores these as dyn quinn::crypto::ClientConfig, which doesn't require Any so I can't upcast it.

So an easy solution that comes to mind is to extend quinn::crypto::ClientConfig with a method that returns if early data is enabled or not.

That said, I have the suspicion that this check isn't needed in the first place because I think that quinn::Connecting::into_0rtt() doesn't succeed if rustls::client::ClientConfig::enable_early_data isn't enabled in the first place?

Any guidance would be appreciated.

<!-- gh-comment-id:1687069256 --> @daxpedda commented on GitHub (Aug 21, 2023): Was just working on an implementation but hit a roadblock: https://github.com/bluejekyll/trust-dns/blob/fba0c67f8fd65956bc4eb8ca95c04ccd5314088e/crates/proto/src/quic/quic_client_stream.rs#L244 https://github.com/bluejekyll/trust-dns/blob/fba0c67f8fd65956bc4eb8ca95c04ccd5314088e/crates/proto/src/quic/quic_client_stream.rs#L254-L261 There is currently no way to get that information out of an `Endpoint`. I was about to make a PR to Quinn to expose the default client configuration from `Endpoint`, but that didn't seem to actually help, because `quinn::Endpoint` stores these as [`dyn quinn::crypto::ClientConfig`](https://docs.rs/quinn/0.10.2/quinn/crypto/trait.ClientConfig.html), which doesn't require `Any` so I can't upcast it. So an easy solution that comes to mind is to extend [`quinn::crypto::ClientConfig`](https://docs.rs/quinn/0.10.2/quinn/crypto/trait.ClientConfig.html) with a method that returns if early data is enabled or not. That said, I have the suspicion that this check isn't needed in the first place because I think that [`quinn::Connecting::into_0rtt()`](https://docs.rs/quinn/0.10.2/quinn/struct.Connecting.html#method.into_0rtt) doesn't succeed if [`rustls::client::ClientConfig::enable_early_data`](https://docs.rs/rustls/0.21.6/rustls/client/struct.ClientConfig.html#structfield.enable_early_data) isn't enabled in the first place? Any guidance would be appreciated.
Author
Owner

@djc commented on GitHub (Aug 22, 2023):

That said, I have the suspicion that this check isn't needed in the first place because I think that quinn::Connecting::into_0rtt() doesn't succeed if rustls::client::ClientConfig::enable_early_data isn't enabled in the first place?

That sounds right, and I think I figured out how it works:

<!-- gh-comment-id:1687714407 --> @djc commented on GitHub (Aug 22, 2023): > That said, I have the suspicion that this check isn't needed in the first place because I think that [`quinn::Connecting::into_0rtt()`](https://docs.rs/quinn/0.10.2/quinn/struct.Connecting.html#method.into_0rtt) doesn't succeed if [`rustls::client::ClientConfig::enable_early_data`](https://docs.rs/rustls/0.21.6/rustls/client/struct.ClientConfig.html#structfield.enable_early_data) isn't enabled in the first place? That sounds right, and I think I figured out how it works: * [`quinn::Connecting::into_0rtt()`] [calls](https://github.com/quinn-rs/quinn/blob/main/quinn/src/connection.rs#L101C17-L101C17) [`quinn_proto::Connection::has_0rtt()`](https://github.com/quinn-rs/quinn/blob/main/quinn-proto/src/connection/mod.rs#L1214), which yields the value from `Connection::zero_rtt_enabled`. * That value is set in [`quinn_proto::Connection::init_0rtt()`](https://github.com/quinn-rs/quinn/blob/main/quinn-proto/src/connection/mod.rs#L1214), which calls into `crypto::Session::early_crypto()` to decide if early data is enabled. * The [`<quinn::crypto::rustls::TlsSession as quinn::crypto::Session>::early_crypto()`](https://github.com/quinn-rs/quinn/blob/main/quinn-proto/src/crypto/rustls.rs#L69) implementation calls [`rustls::quic::ConnectionCommon<Data>::zero_rtt_keys()`](https://github.com/rustls/rustls/blob/main/rustls/src/quic.rs#L319). * This gets the early secret from `common_state.quic.early_secret`, which is set in [`rustls::KeyScheduleEarly::client_early_traffic_secret()`](https://github.com/rustls/rustls/blob/main/rustls/src/tls13/key_schedule.rs#L93). However, that mentions the 0-RTT secret will be clobbered by `ExtensionProcessing` if 0-RTT should be rejected (but this only applies on the server). * On the client, `client_early_traffic_secret()` gets called from [`rustls::client::tls13::derive_early_traffic_secret`](https://github.com/rustls/rustls/blob/main/rustls/src/client/tls13.rs#L297). * This in turn gets called from [`rustls::client::hs::emit_client_hello_for_retry()`](https://github.com/rustls/rustls/blob/main/rustls/src/client/hs.rs#L336), after an early return for `!cx.data.early_data.is_enabled()`.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/hickory-dns#845
No description provided.