[pbs-devel] [POC proxmox-backup 4/4] client: http: Use custom resolver for statically linked binary
Christian Ebner
c.ebner at proxmox.com
Sat Sep 28 11:42:56 CEST 2024
The dependency on the `getaddrinfo` based `GaiResolver` used by
default for the `HttpClient` is not suitable for the statically
linked binary of the `proxmox-backup-client`, because of the
dependency on glibc NSS libraries, as described in glibc's FAQs [0].
As a workaround, conditionally compile the binary using the `hickory-dns`
resolver.
[0] https://sourceware.org/glibc/wiki/FAQ#Even_statically_linked_programs_need_some_shared_libraries_which_is_not_acceptable_for_me.__What_can_I_do.3F
Suggested-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
Signed-off-by: Christian Ebner <c.ebner at proxmox.com>
---
Cargo.toml | 6 +++
pbs-client/Cargo.toml | 1 +
pbs-client/src/http_client.rs | 81 +++++++++++++++++++++++++++++++++--
3 files changed, 84 insertions(+), 4 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
index fc1409d66..792226258 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -160,6 +160,7 @@ walkdir = "2"
xdg = "2.2"
zstd = { version = "0.12", features = [ "bindgen" ] }
zstd-safe = "6.0"
+hickory-resolver = { git = "https://github.com/hickory-dns/hickory-dns", tag = "v0.24.1", default-features = false }
[dependencies]
anyhow.workspace = true
@@ -254,6 +255,11 @@ proxmox-rrd-api-types.workspace = true
# Local path overrides
# NOTE: You must run `cargo update` after changing this for it to take effect!
[patch.crates-io]
+hickory-proto = { git = "https://github.com/hickory-dns/hickory-dns", tag = "v0.24.1" }
+ipconfig = { git = "https://github.com/liranringel/ipconfig", tag = "0.3.2" }
+widestring = { git = "https://github.com/starkat99/widestring-rs", tag = "v1.1.0" }
+windows-sys = { git = "https://github.com/microsoft/windows-rs", tag = "0.48.0" }
+winreg = { git = "https://github.com/gentoo90/winreg-rs", tag = "v0.50.0" }
#proxmox-apt = { path = "../proxmox/proxmox-apt" }
#proxmox-apt-api-types = { path = "../proxmox/proxmox-apt-api-types" }
diff --git a/pbs-client/Cargo.toml b/pbs-client/Cargo.toml
index 00c18b83a..785e7c4de 100644
--- a/pbs-client/Cargo.toml
+++ b/pbs-client/Cargo.toml
@@ -29,6 +29,7 @@ tokio = { workspace = true, features = [ "fs", "signal" ] }
tokio-stream.workspace = true
tower-service.workspace = true
xdg.workspace = true
+hickory-resolver = { workspace = true, features = [ "system-config", "tokio-runtime" ] }
pathpatterns.workspace = true
diff --git a/pbs-client/src/http_client.rs b/pbs-client/src/http_client.rs
index 8ae5edaa0..cdec8e42a 100644
--- a/pbs-client/src/http_client.rs
+++ b/pbs-client/src/http_client.rs
@@ -7,6 +7,8 @@ use futures::*;
use http::header::HeaderValue;
use http::Uri;
use http::{Request, Response};
+#[cfg(not(target_feature = "crt-static"))]
+use hyper::client::connect::dns::GaiResolver;
use hyper::client::{Client, HttpConnector};
use hyper::Body;
use openssl::{
@@ -32,6 +34,74 @@ use pbs_api_types::{Authid, RateLimitConfig, Userid};
use super::pipe_to_stream::PipeToSendStream;
use super::PROXMOX_BACKUP_TCP_KEEPALIVE_TIME;
+#[cfg(not(target_feature = "crt-static"))]
+type DnsResolver = GaiResolver;
+
+#[cfg(target_feature = "crt-static")]
+type DnsResolver = resolver::HickoryDnsResolver;
+
+#[cfg(target_feature = "crt-static")]
+mod resolver {
+ use std::net::SocketAddr;
+ use std::pin::Pin;
+ use std::sync::Arc;
+ use std::task::{Context, Poll};
+
+ use futures::Future;
+ use hickory_resolver::error::ResolveError;
+ use hickory_resolver::lookup_ip::LookupIpIntoIter;
+ use hickory_resolver::TokioAsyncResolver;
+ use hyper::client::connect::dns::Name;
+ use tower_service::Service;
+
+ pub(crate) struct SocketAddrIter {
+ inner: LookupIpIntoIter,
+ }
+
+ impl Iterator for SocketAddrIter {
+ type Item = SocketAddr;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.inner.next().map(|ip_addr| SocketAddr::new(ip_addr, 0))
+ }
+ }
+
+ #[derive(Clone)]
+ pub(crate) struct HickoryDnsResolver {
+ inner: Arc<TokioAsyncResolver>,
+ }
+
+ impl HickoryDnsResolver {
+ pub(crate) fn new() -> Self {
+ Self {
+ inner: Arc::new(TokioAsyncResolver::tokio_from_system_conf().unwrap()),
+ }
+ }
+ }
+
+ impl Service<Name> for HickoryDnsResolver {
+ type Response = SocketAddrIter;
+ type Error = ResolveError;
+ type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
+
+ fn poll_ready(&mut self, _ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ Poll::Ready(Ok(()))
+ }
+
+ fn call(&mut self, name: Name) -> Self::Future {
+ let inner = self.inner.clone();
+ Box::pin(async move {
+ inner
+ .lookup_ip(name.as_str())
+ .await
+ .map(|r| SocketAddrIter {
+ inner: r.into_iter(),
+ })
+ })
+ }
+ }
+}
+
/// Timeout used for several HTTP operations that are expected to finish quickly but may block in
/// certain error conditions. Keep it generous, to avoid false-positive under high load.
const HTTP_TIMEOUT: Duration = Duration::from_secs(2 * 60);
@@ -133,7 +203,7 @@ impl Default for HttpClientOptions {
/// HTTP(S) API client
pub struct HttpClient {
- client: Client<HttpsConnector>,
+ client: Client<HttpsConnector<DnsResolver>>,
server: String,
port: u16,
fingerprint: Arc<Mutex<Option<String>>>,
@@ -364,7 +434,8 @@ impl HttpClient {
ssl_connector_builder.set_verify(openssl::ssl::SslVerifyMode::NONE);
}
- let mut httpc = HttpConnector::new();
+ let resolver = DnsResolver::new();
+ let mut httpc = HttpConnector::new_with_resolver(resolver);
httpc.set_nodelay(true); // important for h2 download performance!
httpc.enforce_http(false); // we want https...
@@ -525,7 +596,9 @@ impl HttpClient {
_options: options,
})
}
+}
+impl HttpClient {
/// Login
///
/// Login is done on demand, so this is only required if you need
@@ -814,7 +887,7 @@ impl HttpClient {
}
async fn credentials(
- client: Client<HttpsConnector>,
+ client: Client<HttpsConnector<DnsResolver>>,
server: String,
port: u16,
username: Userid,
@@ -859,7 +932,7 @@ impl HttpClient {
}
async fn api_request(
- client: Client<HttpsConnector>,
+ client: Client<HttpsConnector<DnsResolver>>,
req: Request<Body>,
) -> Result<Value, Error> {
Self::api_response(
--
2.39.5
More information about the pbs-devel
mailing list