From c8906c00608988235264929c9531689901b33f75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Berthaud-M=C3=BCller?= Date: Sun, 24 Apr 2022 15:40:00 +0200 Subject: [PATCH] upgrade trust-dns to 0.21 --- Cargo.lock | 13 ++++++------ Cargo.toml | 6 ++++-- src/dns/client.rs | 17 ++++++++++----- src/dns/dns_connector.rs | 2 +- src/models/rdata.rs | 45 +++++++++------------------------------- src/models/record.rs | 3 ++- 6 files changed, 36 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3cda004..9e1e1de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -408,9 +408,9 @@ checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" [[package]] name = "enum-as-inner" -version = "0.3.4" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "570d109b813e904becc80d8d5da38376818a143348413f7149f1340fe04754d4" +checksum = "21cdad81446a7f7dc43f6a77409efeb9733d2fa65553efef6018ef257c959b73" dependencies = [ "heck", "proc-macro2", @@ -911,6 +911,7 @@ dependencies = [ "diesel-derive-enum", "diesel_migrations", "figment", + "futures-util", "humantime", "rand", "rocket", @@ -1791,9 +1792,9 @@ dependencies = [ [[package]] name = "trust-dns-client" -version = "0.20.4" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b4ef9b9bde0559b78a4abb00339143750085f05e5a453efb7b8bef1061f09dc" +checksum = "a6d9ba1c6079f6f9b4664e482db1700bd53d2ee77b1c9752c1d7a66c0c8bda99" dependencies = [ "cfg-if", "data-encoding", @@ -1811,9 +1812,9 @@ dependencies = [ [[package]] name = "trust-dns-proto" -version = "0.20.4" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca94d4e9feb6a181c690c4040d7a24ef34018d8313ac5044a61d21222ae24e31" +checksum = "9c31f240f59877c3d4bb3b3ea0ec5a6a0cff07323580ff8c7a605cd7d08b255d" dependencies = [ "async-trait", "cfg-if", diff --git a/Cargo.toml b/Cargo.toml index d7c765a..a8bb330 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,8 +7,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -trust-dns-client = "0.20.1" -trust-dns-proto = "0.20.1" +trust-dns-client = { version = "0.21", features = ["dnssec"] } +trust-dns-proto = "0.21" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" rocket = { git = "https://github.com/SergioBenitez/Rocket", rev = "6bdd2f8", version = "0.5.0-rc.1", features = ["json"] } @@ -25,3 +25,5 @@ figment = { version = "0.10.6", features = ["toml", "env"] } clap = {version = "3", features = ["derive", "cargo"]} argon2 = {version = "0.4", default-features = false, features = ["alloc", "password-hash"] } rand = "0.8" +# From trust-dns-client +futures-util = { version = "0.3.5", default-features = false, features = ["std"] } diff --git a/src/dns/client.rs b/src/dns/client.rs index bf085ae..276fbda 100644 --- a/src/dns/client.rs +++ b/src/dns/client.rs @@ -1,10 +1,11 @@ use std::{future::Future, pin::Pin, task::{Context, Poll}}; +use futures_util::{ready, Stream, StreamExt}; use std::net::SocketAddr; use std::ops::{Deref, DerefMut}; use tokio::{net::TcpStream as TokioTcpStream, task}; use trust_dns_client::{client::AsyncClient, error::ClientError, op::DnsResponse, tcp::TcpClientStream}; -use trust_dns_proto::error::ProtoError; +use trust_dns_proto::error::{ProtoError, ProtoErrorKind}; use trust_dns_proto::iocompat::AsyncIoTokioAsStd; @@ -39,18 +40,24 @@ impl DnsClient { } // Reimplement this type here as ClientReponse in trust-dns crate have private fields +// https://github.com/bluejekyll/trust-dns/blob/v0.21.2/crates/client/src/client/async_client.rs#L621-L641 pub struct ClientResponse(pub(crate) R) where - R: Future> + Send + Unpin + 'static; + R: Stream> + Send + Unpin + 'static; impl Future for ClientResponse where - R: Future> + Send + Unpin + 'static, + R: Stream> + Send + Unpin + 'static, { type Output = Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - // This is from the future_utils crate, we simply reuse the reexport from Rocket - rocket::futures::FutureExt::poll_unpin(&mut self.0, cx).map_err(ClientError::from) + Poll::Ready( + match ready!(self.0.poll_next_unpin(cx)) { + Some(r) => r, + None => Err(ProtoError::from(ProtoErrorKind::Timeout)), + } + .map_err(ClientError::from), + ) } } diff --git a/src/dns/dns_connector.rs b/src/dns/dns_connector.rs index e27a9b1..211a1f5 100644 --- a/src/dns/dns_connector.rs +++ b/src/dns/dns_connector.rs @@ -86,7 +86,7 @@ impl RecordConnector for DnsConnectorClient { let answers = response.answers(); let mut records: Vec<_> = answers.to_vec().into_iter() - .filter(|record| !matches!(record.rdata(), RData::NULL { .. } | RData::DNSSEC(_))) + .filter(|record| record.data().is_some() && !matches!(record.data().unwrap(), RData::NULL { .. } | RData::DNSSEC(_))) .collect(); // AXFR response ends with SOA, we remove it so it is not doubled in the response. diff --git a/src/models/rdata.rs b/src/models/rdata.rs index f1600f0..7554319 100644 --- a/src/models/rdata.rs +++ b/src/models/rdata.rs @@ -1,4 +1,3 @@ -use std::fmt; use std::convert::TryFrom; use std::net::{Ipv6Addr, Ipv4Addr}; @@ -113,17 +112,22 @@ impl From for RData { dns::RData::CNAME(target) => RData::CNAME { target: SerdeName(target) }, - dns::RData::CAA(caa) => RData::CAA { - issuer_critical: caa.issuer_critical(), - value: format!("{}", CAAValue(caa.value())), - property_tag: caa.tag().as_str().to_string(), + dns::RData::CAA(caa) => { + let value_str = caa.value().to_string(); + + RData::CAA { + issuer_critical: caa.issuer_critical(), + // Remove first and last char (byte) because string is quoted (") (should be a safe operation) + value: value_str[1..(value_str.len())].into(), + property_tag: caa.tag().as_str().to_string(), + } }, dns::RData::MX(mx) => RData::MX { preference: mx.preference(), mail_exchanger: SerdeName(mx.exchange().clone()) }, dns::RData::NULL(null) => RData::NULL { - data: base64::encode(null.anything().map(|data| data.to_vec()).unwrap_or_default()) + data: base64::encode(null.anything()) }, dns::RData::NS(target) => RData::NS { target: SerdeName(target) @@ -251,32 +255,3 @@ impl TryFrom for dns::RData { }) } } - -struct CAAValue<'a>(&'a dns::caa::Value); - -// trust_dns Display implementation panics if no parameters (fixed in https://github.com/bluejekyll/trust-dns/pull/1631) -// Implementation based on caa::emit_value -// Also the quotes are strips to render in JSON -impl<'a> fmt::Display for CAAValue<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - match self.0 { - dns::caa::Value::Issuer(name, parameters) => { - - if let Some(name) = name { - write!(f, "{}", name)?; - } - - if name.is_none() && parameters.is_empty() { - write!(f, ";")?; - } - - for value in parameters { - write!(f, "; {}", value)?; - } - } - dns::caa::Value::Url(url) => write!(f, "{}", url)?, - dns::caa::Value::Unknown(v) => write!(f, "{:?}", v)?, - } - Ok(()) - } -} diff --git a/src/models/record.rs b/src/models/record.rs index 1027dae..3fe02a1 100644 --- a/src/models/record.rs +++ b/src/models/record.rs @@ -27,7 +27,8 @@ impl From for Record { name: SerdeName(record.name().clone()), dns_class: record.dns_class().into(), ttl: record.ttl(), - rdata: record.into_data().into(), + // Assume data exists, record with empty data should be filtered by caller + rdata: record.into_data().unwrap().into(), } } }