1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use std::str::FromStr;
use trust_dns_client::client::{Client, SyncClient};
use trust_dns_client::op::DnsResponse;
use trust_dns_client::rr::{DNSClass, Name, RecordType};
use trust_dns_client::udp::UdpClientConnection;
use crate::error::DigsError;
#[derive(Debug, Clone, Copy)]
pub enum RTypes {
A,
AAAA,
CNAME,
MX,
NS,
SOA,
TXT,
}
impl FromStr for RTypes {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"A" => Ok(Self::A),
"AAAA" => Ok(Self::AAAA),
"CNAME" => Ok(Self::CNAME),
"MX" => Ok(Self::MX),
"NS" => Ok(Self::NS),
"SOA" => Ok(Self::SOA),
"TXT" => Ok(Self::TXT),
_ => Err("no match"),
}
}
}
const fn get_rtype(rtype: RTypes) -> RecordType {
match rtype {
RTypes::A => RecordType::A,
RTypes::AAAA => RecordType::AAAA,
RTypes::CNAME => RecordType::CNAME,
RTypes::MX => RecordType::MX,
RTypes::NS => RecordType::NS,
RTypes::SOA => RecordType::SOA,
RTypes::TXT => RecordType::TXT,
}
}
fn get_address(nameserver: &str) -> Result<std::net::SocketAddr, DigsError> {
let address = format!("{}:53", nameserver).parse::<std::net::SocketAddr>();
match address {
Ok(addr) => Ok(addr),
Err(_) => Err(DigsError::InvalidIpAddress(nameserver.to_string())),
}
}
pub fn query(domain: &str, rtype: RTypes, nameserver: &str) -> Result<DnsResponse, DigsError> {
let address = get_address(nameserver)?;
let conn = UdpClientConnection::new(address)?;
let client = SyncClient::new(conn);
let rtype = get_rtype(rtype);
let name = Name::from_str(&format!("{}.", domain))?;
let response = client.query(&name, DNSClass::IN, rtype);
match response {
Ok(resp) => Ok(resp),
Err(err) => Err(DigsError::ForeignError(err)),
}
}