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
use std::ffi::NulError;
use std::io;
use std::net::AddrParseError;

use crate::dns::{DnsRequest, DnsResponse};
use crate::dns::packet::parse::ResponseParseError;

// TODO(teawithsand): TCP resolver
// TODO(teawithsand): UDP resolver
// TODO(teawithsand): Libc(aka OS) resolver

#[derive(Debug, From)]
pub enum DnsResolverError {
    IOError(io::Error),
    ParseError(ResponseParseError),

    /// domain string which contains null byte(`0x00`) may cause problems with some resolvers
    NulError(NulError),
    AddrParseError(AddrParseError),
    UnknownError,

    /// Given resolver does not support any type of query required to satisfy requirements of given function
    NotSupported,

    #[cfg(feature = "doh")]
    HyperHttpError(hyper::http::Error),

    #[cfg(feature = "doh")]
    HyperError(hyper::Error),
}

/// DnsResolver is trait which represents asynchronous DNS resolver - thing able to process dns requests and
/// return responses.
///
///
#[async_trait]
pub trait DnsResolver {
    /// send_request performs single DNS request using given resolver and parses response.
    ///
    /// # Notes
    /// If request for given query kind is not supported `DnsResolverError::NotSupported` is returned.
    /// For instance given resolver uses libc and can resolve only Ipv4 addresses.
    async fn send_request(&self, req: &DnsRequest<'_>) -> Result<DnsResponse<'static>, DnsResolverError>;
}