DEV Community

Adam.S
Adam.S

Posted on • Edited on • Originally published at bas-man.dev

3 1

Lookup SOA Records using Rust & trust-dns-resolver

This is a second article on using the trust-dns-resolver crate

Warning: This code is not intended to be used in production. You should review and adjust to your own needs.

Getting Started

First we will need to create our development environment.

cargo new trust-dns-resolver && cd $_
Enter fullscreen mode Exit fullscreen mode

This will give us our standard rust directly structure. We need to add our crate to the Cargo.toml

-snip-
[dependencies]
trust-dns-resolver = "0.20.1"
Enter fullscreen mode Exit fullscreen mode

Next edit the src/main.rs as follows.

use trust_dns_resolver::error::ResolveResult;
use trust_dns_resolver::Resolver;
use trust_dns_resolver::{config::*, lookup::SoaLookup};
fn main() {
// Construct a new Resolver with default configuration options
let resolver = Resolver::new(ResolverConfig::default(), ResolverOpts::default()).unwrap();
let soa_response = resolver.soa_lookup("gmail.com.");
display_soa(&soa_response);
}
fn display_soa(soa_response: &ResolveResult<SoaLookup>) {
match soa_response {
Err(_) => println!("No SOA."),
Ok(soa_response) => {
let soa_iter = soa_response.iter();
for record in soa_iter {
println!("Admin: {}", record.rname());
let email = convert_rname_to_email_address(&record.rname().to_string());
println!("Admin Email: {}", email);
println!("Primary: {}", record.mname());
println!("Serial: {}", record.serial());
}
}
}
}
fn convert_rname_to_email_address(rname: &String) -> String {
//Solution found on StackOverFlow :)
let rname = rname.clone();
let mut email_address: String = String::new();
let mut splitter = rname.splitn(2, ".");
email_address.push_str(splitter.next().unwrap());
email_address.push_str("@");
email_address.push_str(splitter.next().unwrap());
// Remove remaining period (.)
email_address.pop();
email_address
}
view raw soa.rs hosted with ❤ by GitHub

Compile and run the code to make sure everything is ok.

cargo run
Enter fullscreen mode Exit fullscreen mode

This outputs the following

Admin: dns-admin.google.com.
Admin Email: dns-admin@google.com
Primary: ns1.google.com.
Serial: 364996005
Enter fullscreen mode Exit fullscreen mode

Explaining the code

Documentation for the SOA RData can be found here

Let's take a look at what we are doing here.

Like the first example we create a resolver which will do the work of doing the DNS lookups.

Next we use the resolver to call soa_lookup() and store the result into soa_response

soa_response will contain either and SoaLookup or an Err. For this reason we need to handle these two cases. I have changed things up a little this time and I am passing a reference to the display_soa() function. So I am allowing display_soa() to borrow the data. In doing this I am saving on memory and I am also promising that I am not going to mutate soa_response within this function. I will cheat a little and clone() some data later.

Within display_soa I again use match to handle my two cases.

In the case of Err. I do nothing and just report there were no records.

In the case of SoaLookup, I will need to do some more processing.

  • First lets make an iter() out of soa_response and loop over it.
  • In the loop we get the rname() or the administrative contact and the mname() or primary name server for this domain as well as serial() and access to a few more elements.

Line 26 is just a cobbled together function to redisplay rname() as a more valid email address which is what it really represents. If anyone can point in the direction of a better way to handle this it would greatly appreciated.

I hope you find this interesting and useful.

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more →

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more