fix: Implement missing "implicit MX" rule

Implements "implicit MX" as described by
https://datatracker.ietf.org/doc/html/rfc5321#section-5.1

Fixes: #126
Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
This commit is contained in:
Jagoda Ślązak
2026-08-18 12:21:28 +02:00
committed by missytake
parent 6121d46234
commit 4131fd0823
+18 -10
View File
@@ -59,26 +59,34 @@ impl TransportHandler {
allow_invalid_cert = true; allow_invalid_cert = true;
} }
let query = format!("{mx_domain}."); let query = format!("{mx_domain}.");
let mx_records = dns_resolver.mx_lookup(query).await.map_err(|e| {
if e.is_no_records_found() {
format!("512 No MX records for {mx_domain}")
} else if e.is_nx_domain() {
format!("512 Domain {mx_domain} does not exist")
} else {
format!("421 DNS resolution failed for {mx_domain}")
}
})?;
match dns_resolver.mx_lookup(query).await {
Ok(mx_records) => {
let mut hosts: Vec<(u16, String)> = mx_records let mut hosts: Vec<(u16, String)> = mx_records
.iter() .iter()
.map(|mx| { .map(|mx| {
let host = mx.exchange().to_string().trim_end_matches('.').to_string(); let host =
mx.exchange().to_string().trim_end_matches('.').to_string();
(mx.preference(), host) (mx.preference(), host)
}) })
.collect(); .collect();
hosts.sort(); hosts.sort();
hosts hosts
} }
Err(e) => {
if e.is_no_records_found() {
// "implicit MX" as described by section 5.1 of RFC5321
// https://datatracker.ietf.org/doc/html/rfc5321#section-5.1
log::debug!("No MX record found, using implicit MX: {mx_domain}");
vec![(0, mx_domain)]
} else if e.is_nx_domain() {
return Err(format!("512 Domain {mx_domain} does not exist"));
} else {
return Err(format!("421 DNS resolution failed for {mx_domain}"));
}
}
}
}
}; };
let tls_config = match skip_tls { let tls_config = match skip_tls {