From b0b4ba9784452a4b141f2ce5b41c291465232d5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Wed, 9 Nov 2022 15:58:11 +0000 Subject: [PATCH] mdns: replace dns-parse with trust-dns-proto --- protocols/mdns/Cargo.toml | 2 +- protocols/mdns/src/behaviour/iface/dns.rs | 8 +-- protocols/mdns/src/behaviour/iface/query.rs | 59 +++++++++++---------- protocols/mdns/src/lib.rs | 4 ++ 4 files changed, 40 insertions(+), 33 deletions(-) diff --git a/protocols/mdns/Cargo.toml b/protocols/mdns/Cargo.toml index 5729043514ec..504f312d7f99 100644 --- a/protocols/mdns/Cargo.toml +++ b/protocols/mdns/Cargo.toml @@ -12,7 +12,6 @@ categories = ["network-programming", "asynchronous"] [dependencies] data-encoding = "2.3.2" -dns-parser = "0.8.0" futures = "0.3.13" if-watch = "2.0.0" libp2p-core = { version = "0.38.0", path = "../../core" } @@ -25,6 +24,7 @@ void = "1.0.2" async-io = { version = "1.3.1", optional = true } tokio = { version = "1.19", default-features = false, features = ["net", "time"], optional = true} +trust-dns-proto = { version = "0.22.0", features = ["mdns"] } [features] tokio = ["dep:tokio"] diff --git a/protocols/mdns/src/behaviour/iface/dns.rs b/protocols/mdns/src/behaviour/iface/dns.rs index 4590e1e266e8..1f0825727a23 100644 --- a/protocols/mdns/src/behaviour/iface/dns.rs +++ b/protocols/mdns/src/behaviour/iface/dns.rs @@ -395,14 +395,14 @@ impl error::Error for MdnsResponseError {} #[cfg(test)] mod tests { use super::*; - use dns_parser::Packet; use libp2p_core::identity; use std::time::Duration; + use trust_dns_proto::op::Message; #[test] fn build_query_correct() { let query = build_query(); - assert!(Packet::parse(&query).is_ok()); + assert!(Message::from_vec(&query).is_ok()); } #[test] @@ -417,14 +417,14 @@ mod tests { Duration::from_secs(60), ); for packet in packets { - assert!(Packet::parse(&packet).is_ok()); + assert!(Message::from_vec(&packet).is_ok()); } } #[test] fn build_service_discovery_response_correct() { let query = build_service_discovery_response(0x1234, Duration::from_secs(120)); - assert!(Packet::parse(&query).is_ok()); + assert!(Message::from_vec(&query).is_ok()); } #[test] diff --git a/protocols/mdns/src/behaviour/iface/query.rs b/protocols/mdns/src/behaviour/iface/query.rs index 70e38016849a..4b9852d2b385 100644 --- a/protocols/mdns/src/behaviour/iface/query.rs +++ b/protocols/mdns/src/behaviour/iface/query.rs @@ -19,8 +19,7 @@ // DEALINGS IN THE SOFTWARE. use super::dns; -use crate::{META_QUERY_SERVICE, SERVICE_NAME}; -use dns_parser::{Packet, RData}; +use crate::{META_QUERY_SERVICE_FQDN, SERVICE_NAME_FQDN}; use libp2p_core::{ address_translation, multiaddr::{Multiaddr, Protocol}, @@ -28,6 +27,10 @@ use libp2p_core::{ }; use std::time::Instant; use std::{convert::TryFrom, fmt, net::SocketAddr, str, time::Duration}; +use trust_dns_proto::{ + op::Message, + rr::{Name, RData}, +}; /// A valid mDNS packet received by the service. #[derive(Debug)] @@ -44,33 +47,33 @@ impl MdnsPacket { pub fn new_from_bytes( buf: &[u8], from: SocketAddr, - ) -> Result, dns_parser::Error> { - let packet = Packet::parse(buf)?; + ) -> Result, trust_dns_proto::error::ProtoError> { + let packet = Message::from_vec(buf)?; - if !packet.header.query { - return Ok(Some(MdnsPacket::Response(MdnsResponse::new(packet, from)))); + if packet.query().is_none() { + return Ok(Some(MdnsPacket::Response(MdnsResponse::new(&packet, from)))); } if packet - .questions + .queries() .iter() - .any(|q| q.qname.to_string().as_bytes() == SERVICE_NAME) + .any(|q| q.name().to_utf8() == SERVICE_NAME_FQDN) { return Ok(Some(MdnsPacket::Query(MdnsQuery { from, - query_id: packet.header.id, + query_id: packet.header().id(), }))); } if packet - .questions + .queries() .iter() - .any(|q| q.qname.to_string().as_bytes() == META_QUERY_SERVICE) + .any(|q| q.name().to_utf8() == META_QUERY_SERVICE_FQDN) { // TODO: what if multiple questions, one with SERVICE_NAME and one with META_QUERY_SERVICE? return Ok(Some(MdnsPacket::ServiceDiscovery(MdnsServiceDiscovery { from, - query_id: packet.header.id, + query_id: packet.header().id(), }))); } @@ -144,21 +147,21 @@ pub struct MdnsResponse { impl MdnsResponse { /// Creates a new `MdnsResponse` based on the provided `Packet`. - pub fn new(packet: Packet<'_>, from: SocketAddr) -> MdnsResponse { + pub fn new(packet: &Message, from: SocketAddr) -> MdnsResponse { let peers = packet - .answers + .answers() .iter() .filter_map(|record| { - if record.name.to_string().as_bytes() != SERVICE_NAME { + if record.name().to_string() != SERVICE_NAME_FQDN { return None; } - let record_value = match record.data { - RData::PTR(record) => record.0.to_string(), + let record_value = match record.data() { + Some(RData::PTR(record)) => record, _ => return None, }; - MdnsPeer::new(&packet, record_value, record.ttl) + MdnsPeer::new(packet, record_value, record.ttl()) }) .collect(); @@ -225,17 +228,17 @@ pub struct MdnsPeer { impl MdnsPeer { /// Creates a new `MdnsPeer` based on the provided `Packet`. - pub fn new(packet: &Packet<'_>, record_value: String, ttl: u32) -> Option { + pub fn new(packet: &Message, record_value: &Name, ttl: u32) -> Option { let mut my_peer_id: Option = None; let addrs = packet - .additional + .additionals() .iter() .filter_map(|add_record| { - if add_record.name.to_string() != record_value { + if add_record.name() != record_value { return None; } - if let RData::TXT(ref txt) = add_record.data { + if let Some(RData::TXT(ref txt)) = add_record.data() { Some(txt) } else { None @@ -337,16 +340,16 @@ mod tests { ); for bytes in packets { - let packet = Packet::parse(&bytes).expect("unable to parse packet"); + let packet = Message::from_vec(&bytes).expect("unable to parse packet"); let record_value = packet - .answers + .answers() .iter() .filter_map(|record| { - if record.name.to_string().as_bytes() != SERVICE_NAME { + if record.name().to_utf8() != SERVICE_NAME_FQDN { return None; } - let record_value = match record.data { - RData::PTR(record) => record.0.to_string(), + let record_value = match record.data() { + Some(RData::PTR(record)) => record, _ => return None, }; Some(record_value) @@ -354,7 +357,7 @@ mod tests { .next() .expect("empty record value"); - let peer = MdnsPeer::new(&packet, record_value, ttl).expect("fail to create peer"); + let peer = MdnsPeer::new(&packet, &record_value, ttl).expect("fail to create peer"); assert_eq!(peer.peer_id, peer_id); } } diff --git a/protocols/mdns/src/lib.rs b/protocols/mdns/src/lib.rs index 298f48ea9754..368582ecb7b5 100644 --- a/protocols/mdns/src/lib.rs +++ b/protocols/mdns/src/lib.rs @@ -49,8 +49,12 @@ pub use crate::behaviour::TokioMdns; /// The DNS service name for all libp2p peers used to query for addresses. const SERVICE_NAME: &[u8] = b"_p2p._udp.local"; +/// `SERVICE_NAME` as a Fully Qualified Domain Name. +const SERVICE_NAME_FQDN: &str = "_p2p._udp.local."; /// The meta query for looking up the `SERVICE_NAME`. const META_QUERY_SERVICE: &[u8] = b"_services._dns-sd._udp.local"; +/// `META_QUERY_SERVICE` as a Fully Qualified Domain Name. +const META_QUERY_SERVICE_FQDN: &str = "_services._dns-sd._udp.local."; pub const IPV4_MDNS_MULTICAST_ADDRESS: Ipv4Addr = Ipv4Addr::new(224, 0, 0, 251); pub const IPV6_MDNS_MULTICAST_ADDRESS: Ipv6Addr = Ipv6Addr::new(0xFF02, 0, 0, 0, 0, 0, 0, 0xFB);