DEV Community

Adam.S
Adam.S

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

3 3

Lookup TXT Records using Rust & trust-dns-resolver

This is the third 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::TxtLookup};
fn main() {
// Construct a new Resolver with default configuration options
let resolver = Resolver::new(ResolverConfig::default(), ResolverOpts::default()).unwrap();
// Lookup the IP addresses associated with a name.
// The final dot forces this to be an FQDN, otherwise the search rules as specified
// in `ResolverOpts` will take effect. FQDN's are generally cheaper queries.
let txt_response = resolver.txt_lookup("gmail.com.");
display_txt(&txt_response);
}
fn display_txt(txt_response: &ResolveResult<TxtLookup>) {
match txt_response {
Err(_) => println!("No TXT Records."),
Ok(txt_response) => {
let mut i = 1;
for record in txt_response.iter() {
println!("TXT Record {}:", i);
println!("{}", record.to_string());
println!("");
i = i + 1;
}
}
}
}
view raw txt.rs hosted with ❤ by GitHub
cargo run
Enter fullscreen mode Exit fullscreen mode

This outputs the following

TXT Record 1:
globalsign-smime-dv=CDYX+XFHUw2wml6/Gb8+59BsH31KzUr6c1l2BPvqKX8=

TXT Record 2:
v=spf1 redirect=_spf.google.com

Enter fullscreen mode Exit fullscreen mode

Explaining the code

Documentation for the TXT RData can be found here

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

Like the previous examples we create a resolver which will do the work of doing the DNS lookups.

Next we use the resolver to call txt_lookup() and store the result into txt_response.

txt_response will contain either a TxtLookup or an Err. For this reason we need to handle these two cases. As before I am passing a reference to the display_txt() function.

Within display_txt I use match to handle my two cases.

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

In the case of TxtLookup, I will need to do some more processing.
I simply make an iter() out of txt_response and loop over it and call to_string() on each record in the iter().

I went down a rabbit hole for a while because I incorrectly thought I had to call txt_data() which returns a Box<[u8], a smart pointer.

I hope you find this interesting and useful.

P.S: I might revisit this when I look at using regular expressions.

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

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay