use super::ResolveTargetError;
use dns_lookup::lookup_host;
use std::net::IpAddr;
#[cfg(doc)]
use super::{IcmpTarget, TcpTarget};
#[derive(PartialEq, Debug)]
pub enum ResolvePolicy {
Agnostic,
ResolveToIPv4,
ResolveToIPv6,
}
impl ResolvePolicy {
pub fn resolve(&self, fqhn: &str) -> Result<Vec<IpAddr>, ResolveTargetError> {
let mut addrs = lookup_host(fqhn)?;
addrs = match &self {
ResolvePolicy::Agnostic => addrs,
ResolvePolicy::ResolveToIPv4 => addrs.into_iter().filter(|ip| ip.is_ipv4()).collect(),
ResolvePolicy::ResolveToIPv6 => addrs.into_iter().filter(|ip| ip.is_ipv6()).collect(),
};
if addrs.is_empty() {
Err(ResolveTargetError::from("Given Policy filtered all resolved addresses"))
} else {
Ok(addrs)
}
}
}
#[cfg(test)]
mod tests {
use std::net::{Ipv4Addr, Ipv6Addr};
use super::*;
#[test]
fn resolver_policy_agnostic() {
let policy = ResolvePolicy::Agnostic;
let ipv4_localhost = String::from("127.0.0.1");
let res = policy.resolve(&ipv4_localhost).unwrap();
assert_eq!(res, vec![IpAddr::V4(Ipv4Addr::LOCALHOST)]);
let ipv6_localhost = String::from("::1");
let res = policy.resolve(&ipv6_localhost).unwrap();
assert_eq!(res, vec![IpAddr::V6(Ipv6Addr::LOCALHOST)]);
}
#[test]
fn resolver_policy_ipv4() {
let policy = ResolvePolicy::ResolveToIPv4;
let ipv4_localhost = String::from("127.0.0.1");
let res = policy.resolve(&ipv4_localhost).unwrap();
assert_eq!(res, vec![IpAddr::V4(Ipv4Addr::LOCALHOST)]);
let ipv6_localhost = String::from("::1");
assert_eq!(
format!("{}", policy.resolve(&ipv6_localhost).unwrap_err()),
"Given Policy filtered all resolved addresses"
);
}
#[test]
fn resolver_policy_ipv6() {
let policy = ResolvePolicy::ResolveToIPv6;
let ipv6_localhost = String::from("::1");
let res = policy.resolve(&ipv6_localhost).unwrap();
assert_eq!(res, vec![IpAddr::V6(Ipv6Addr::LOCALHOST)]);
let ipv4_localhost = String::from("127.0.0.1");
assert_eq!(
format!("{}", policy.resolve(&ipv4_localhost).unwrap_err()),
"Given Policy filtered all resolved addresses"
);
}
#[test]
fn resolver_policy_fail_to_resolve() {
let policy = ResolvePolicy::Agnostic;
let invalid_host = String::from("askjdakdsjhaksd.com");
assert_eq!(
format!("{}", policy.resolve(&invalid_host).unwrap_err()),
"IoError caused by: failed to lookup address information: Name or service not known"
);
}
}