use super::is_ip;
use crate::message_status::InternalMessageStatus;
use trust_dns_resolver::Resolver;
pub fn get_mx_records_for_email(
internal_message_status: &mut InternalMessageStatus,
resolver: &Resolver,
) {
for recipient in &mut internal_message_status.recipients {
let mx_records = get_mx_records_for_domain(&*recipient.domain, resolver);
recipient.mx_servers = Some(mx_records);
debug!(
"DEBUG: got mx servers for {}: {:?}",
recipient.email_addr,
recipient.mx_servers.as_ref().unwrap()
);
}
}
fn get_mx_records_for_domain(domain: &str, resolver: &Resolver) -> Vec<String> {
use std::cmp::Ordering;
let response = match resolver.mx_lookup(domain) {
Ok(res) => res,
Err(_) => {
return vec![domain.to_owned()];
}
};
let mut records: Vec<(u16, String)> = response
.iter()
.map(|mx| (mx.preference(), mx.exchange().to_string()))
.collect();
if records.is_empty() {
return vec![domain.to_owned()];
}
records.sort_by(|a, b| a.0.cmp(&b.0));
records.sort_by(|a, b| {
let a_is_ip = is_ip(&*(a.1));
let b_is_ip = is_ip(&*(b.1));
match (a_is_ip, b_is_ip) {
(true, false) => Ordering::Less,
(false, true) => Ordering::Greater,
_ => Ordering::Equal,
}
});
records
.into_iter()
.map(|(_, exch)| exch.trim_end_matches(|c| c == '.').to_owned())
.collect()
}