summaryrefslogtreecommitdiff
path: root/src/packet/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/packet/mod.rs (renamed from packet/src/lib.rs)62
1 files changed, 18 insertions, 44 deletions
diff --git a/packet/src/lib.rs b/src/packet/mod.rs
index c7a8eb9..0b7cb7b 100644
--- a/packet/src/lib.rs
+++ b/src/packet/mod.rs
@@ -1,16 +1,19 @@
use std::net::IpAddr;
-use self::{header::DnsHeader, question::DnsQuestion, record::DnsRecord, query::QueryType};
+use self::{
+ buffer::PacketBuffer, header::DnsHeader, query::QueryType, question::DnsQuestion,
+ record::DnsRecord,
+};
type Error = Box<dyn std::error::Error>;
pub type Result<T> = std::result::Result<T, Error>;
-mod buffer;
-mod header;
-mod query;
-mod question;
-mod record;
-mod result;
+pub mod buffer;
+pub mod header;
+pub mod query;
+pub mod question;
+pub mod record;
+pub mod result;
#[derive(Clone, Debug)]
pub struct Packet {
@@ -21,12 +24,6 @@ pub struct Packet {
pub resources: Vec<DnsRecord>,
}
-pub use buffer::PacketBuffer;
-pub use result::ResultCode;
-
-pub use query::QueryType as PacketType;
-pub use question::DnsQuestion as PacketQuestion;
-
impl Packet {
pub fn new() -> Self {
Self {
@@ -88,9 +85,6 @@ impl Packet {
Ok(())
}
- /// It's useful to be able to pick a random A record from a packet. When we
- /// get multiple IP's for a single name, it doesn't matter which one we
- /// choose, so in those cases we can now pick one at random.
pub fn get_random_a(&self) -> Option<IpAddr> {
self.answers
.iter()
@@ -102,55 +96,35 @@ impl Packet {
.next()
}
- /// A helper function which returns an iterator over all name servers in
- /// the authorities section, represented as (domain, host) tuples
fn get_ns<'a>(&'a self, qname: &'a str) -> impl Iterator<Item = (&'a str, &'a str)> {
self.authorities
.iter()
- // In practice, these are always NS records in well formed packages.
- // Convert the NS records to a tuple which has only the data we need
- // to make it easy to work with.
.filter_map(|record| match record {
DnsRecord::NS { domain, host, .. } => Some((domain.as_str(), host.as_str())),
_ => None,
})
- // Discard servers which aren't authoritative to our query
.filter(move |(domain, _)| qname.ends_with(*domain))
}
- /// We'll use the fact that name servers often bundle the corresponding
- /// A records when replying to an NS query to implement a function that
- /// returns the actual IP for an NS record if possible.
pub fn get_resolved_ns(&self, qname: &str) -> Option<IpAddr> {
- // Get an iterator over the nameservers in the authorities section
self.get_ns(qname)
- // Now we need to look for a matching A record in the additional
- // section. Since we just want the first valid record, we can just
- // build a stream of matching records.
.flat_map(|(_, host)| {
self.resources
.iter()
- // Filter for A records where the domain match the host
- // of the NS record that we are currently processing
.filter_map(move |record| match record {
- DnsRecord::A { domain, addr, .. } if domain == host => Some(IpAddr::V4(*addr)),
- DnsRecord::AAAA { domain, addr, .. } if domain == host => Some(IpAddr::V6(*addr)),
+ DnsRecord::A { domain, addr, .. } if domain == host => {
+ Some(IpAddr::V4(*addr))
+ }
+ DnsRecord::AAAA { domain, addr, .. } if domain == host => {
+ Some(IpAddr::V6(*addr))
+ }
_ => None,
})
})
- // Finally, pick the first valid entry
.next()
}
- /// However, not all name servers are as that nice. In certain cases there won't
- /// be any A records in the additional section, and we'll have to perform *another*
- /// lookup in the midst. For this, we introduce a method for returning the host
- /// name of an appropriate name server.
pub fn get_unresolved_ns<'a>(&'a self, qname: &'a str) -> Option<&'a str> {
- // Get an iterator over the nameservers in the authorities section
- self.get_ns(qname)
- .map(|(_, host)| host)
- // Finally, pick the first valid entry
- .next()
+ self.get_ns(qname).map(|(_, host)| host).next()
}
-} \ No newline at end of file
+}