zero_trust_rps/common/
dns.rs

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
use std::net::{SocketAddr, ToSocketAddrs};

#[derive(thiserror::Error, Debug)]
pub enum DomainResolveError {
    #[error("Io error: {}", .0)]
    IoError(#[from] std::io::Error),
    #[error("Failed to resolve domain.")]
    #[allow(unused)]
    NoIpsFound,
}

#[allow(unused)]
pub async fn resolve_to_ips(
    domain: &str,
    port: u16,
) -> Result<Box<[SocketAddr]>, DomainResolveError> {
    let addrs = (domain, port).to_socket_addrs()?;

    let (ipv4s, ipv6s) = addrs.into_iter().partition::<Vec<_>, _>(|ip| ip.is_ipv4());

    let ips_count = ipv4s.len() + ipv6s.len();

    if ips_count == 0 {
        return Err(DomainResolveError::NoIpsFound);
    }

    let mut left = ipv6s.into_iter();
    let mut right = ipv4s.into_iter();

    let mut interlaced = Vec::with_capacity(ips_count);
    for (l, r) in (&mut left).zip(&mut right) {
        interlaced.push(l);
        interlaced.push(r);
    }
    interlaced.extend(left);
    interlaced.extend(right);

    Ok(interlaced.into_boxed_slice())
}