zero_trust_rps/common/
dns.rs

1use std::net::{SocketAddr, ToSocketAddrs};
2
3#[derive(thiserror::Error, Debug)]
4pub enum DomainResolveError {
5    #[error("Io error: {}", .0)]
6    IoError(#[from] std::io::Error),
7    #[error("Failed to resolve domain.")]
8    #[allow(unused)]
9    NoIpsFound,
10}
11
12#[allow(unused)]
13pub async fn resolve_to_ips(
14    domain: &str,
15    port: u16,
16) -> Result<Box<[SocketAddr]>, DomainResolveError> {
17    let addrs = (domain, port).to_socket_addrs()?;
18
19    let (ipv4s, ipv6s) = addrs.into_iter().partition::<Vec<_>, _>(|ip| ip.is_ipv4());
20
21    let ips_count = ipv4s.len() + ipv6s.len();
22
23    if ips_count == 0 {
24        return Err(DomainResolveError::NoIpsFound);
25    }
26
27    let mut left = ipv6s.into_iter();
28    let mut right = ipv4s.into_iter();
29
30    let mut interlaced = Vec::with_capacity(ips_count);
31    for (l, r) in (&mut left).zip(&mut right) {
32        interlaced.push(l);
33        interlaced.push(r);
34    }
35    interlaced.extend(left);
36    interlaced.extend(right);
37
38    Ok(interlaced.into_boxed_slice())
39}