1use std::net::IpAddr;
17use std::sync::Arc;
18
19use crate::common::RecordSOA;
20use crate::error::*;
21use crate::common::{QType, DnsRdata};
22
23use super::query::QDns;
24use super::{QuerySetup, ResolveConfig};
25
26
27pub
40fn resolve_fqdn<C>(fqdn: C, custom_resolv: Option<Arc<ResolveConfig>>) -> CDnsResult<Vec<IpAddr>>
41where C: AsRef<str>
42{
43 let dns =
45 QDns
46 ::make_a_aaaa_request(custom_resolv, fqdn.as_ref(), QuerySetup::default())?;
47
48 let res = dns.query();
50
51 let mut iplist: Vec<IpAddr> = vec![];
53
54
55 let recs = res.get_result()?;
56
57 for dnsr in recs.into_iter()
58 {
59 for resp in dnsr.into_iter()
60 {
61 match resp.borrow_rdata()
62 {
63 DnsRdata::A(ip) =>
64 iplist.push(IpAddr::from(ip.ip)),
65 DnsRdata::AAAA( ip ) =>
66 iplist.push(IpAddr::from(ip.ip)),
67 _ => continue,
68 }
69 }
70 }
71
72 return Ok(iplist);
73}
74
75pub
89fn resolve_mx<C>(fqdn: C, custom_resolv: Option<Arc<ResolveConfig>>) -> CDnsResult<Vec<String>>
90where C: AsRef<str>
91{
92 let mut dns_req =
93 QDns::make_empty(custom_resolv, QuerySetup::default())?;
94
95 dns_req.add_request(QType::MX, fqdn.as_ref());
96
97 let res = dns_req.query();
99
100 let mut mxlist: Vec<(u16, String)> = Vec::new();
102
103 let recs = res.get_result()?;
104
105 for dnsr in recs.into_iter()
106 {
107 for resp in dnsr.into_iter()
108 {
109 match resp.borrow_rdata()
110 {
111 DnsRdata::MX(mx) =>
112 {
113 let idx = mxlist.binary_search_by_key(&mx.preference, |x| x.0).map_or_else(|v| v, |f| f);
117 mxlist.insert(idx, (mx.preference, mx.exchange));
118
119 },
139 _ => continue,
140 }
141 }
142 }
143
144 return Ok(mxlist.into_iter().map( |(_, ip)| ip).collect());
145}
146
147pub
160fn resolve_soa<C>(fqdn: C, custom_resolv: Option<Arc<ResolveConfig>>) -> CDnsResult<Vec<RecordSOA>>
161where C: AsRef<str>
162{
163 let mut dns_req =
164 QDns::make_empty(custom_resolv, QuerySetup::default())?;
165
166 dns_req.add_request(QType::SOA, fqdn.as_ref());
167
168 let res = dns_req.query();
170
171 let mut soa_list: Vec<RecordSOA> = Vec::new();
172
173 let recs = res.get_result()?;
174
175 for dnsr in recs.into_iter()
176 {
177 for resp in dnsr.into_iter()
178 {
179 match resp.borrow_rdata()
180 {
181 DnsRdata::SOA(soa) =>
182 soa_list.push(soa),
183 _ => continue,
184 }
185 }
186 }
187
188 return Ok(soa_list);
189}
190
191pub
192fn resolve_reverse<C>(fqdn: C, custom_resolv: Option<Arc<ResolveConfig>>) -> CDnsResult<Vec<String>>
193where C: AsRef<str>
194{
195 let mut dns_req =
196 QDns::make_empty(custom_resolv, QuerySetup::default())?;
197
198 dns_req.add_request(QType::PTR, fqdn.as_ref());
199
200 let res = dns_req.query();
202
203 let recs = res.get_result()?;
204
205 let mut ptr_list: Vec<String> = Vec::new();
206
207 for dnsr in recs.into_iter()
208 {
209 for resp in dnsr.into_iter()
210 {
211 match resp.borrow_rdata()
212 {
213 DnsRdata::PTR(ptr) =>
214 ptr_list.push(ptr.fqdn),
215 _ => continue,
216 }
217 }
218 }
219
220 return Ok(ptr_list);
221}
222
223#[cfg(test)]
224mod tests
225{
226 use crate::sync::request::{resolve_fqdn, resolve_mx};
227
228 #[test]
229 fn test_mx_resolve()
230 {
231 let mx_doms = resolve_mx("protonmail.com", None);
232
233 assert_eq!(mx_doms.is_err(), false);
234
235 let mx_doms = mx_doms.unwrap();
236
237 let mut index = 0;
238 for di in mx_doms
239 {
240 match index
241 {
242 0 => assert_eq!(di.as_str(), "mail.protonmail.ch"),
243 1 => assert_eq!(di.as_str(), "mailsec.protonmail.ch"),
244 _ => panic!("test is required to be modified")
245 }
246
247 index += 1;
248
249 println!("{}", di);
250 }
251
252 }
253
254
255 #[test]
256 fn test_a_aaaa_resolve()
257 {
258 let a_aaaa = resolve_fqdn("protonmail.com", None);
259
260 assert_eq!(a_aaaa.is_ok(), true);
261
262 let a_aaaa = a_aaaa.unwrap();
263
264 for di in a_aaaa
265 {
266 println!("{}", di);
267 }
268
269 }
270}