Skip to content

Commit

Permalink
feat: always use preloaded DNS results
Browse files Browse the repository at this point in the history
Otherwise if DNS server returns incorrect results,
we may never try preloaded DNS results.
For example, we may get our first results
from a captive portal.

To test, add `127.0.0.1 example.org`
and try to create an account.
Without this change we only try 127.0.0.1 and fail.
With this change preloaded DNS results are tried as well.
  • Loading branch information
link2xt committed Aug 25, 2024
1 parent 36e5e96 commit 137ee93
Showing 1 changed file with 11 additions and 17 deletions.
28 changes: 11 additions & 17 deletions src/net/dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ pub(crate) async fn update_connect_timestamp(
Ok(())
}

/// Preloaded DNS results that can be used in case of DNS server failures.
///
/// See <https://support.delta.chat/t/no-dns-resolution-result/2778> and
/// <https://github.com/deltachat/deltachat-core-rust/issues/4920> for reasons.
static DNS_PRELOAD: Lazy<HashMap<&'static str, Vec<IpAddr>>> = Lazy::new(|| {
HashMap::from([
(
Expand Down Expand Up @@ -501,21 +505,6 @@ static DNS_PRELOAD: Lazy<HashMap<&'static str, Vec<IpAddr>>> = Lazy::new(|| {
])
});

/// Load hardcoded cache if everything else fails.
///
/// See <https://support.delta.chat/t/no-dns-resolution-result/2778> and
/// <https://github.com/deltachat/deltachat-core-rust/issues/4920> for reasons.
///
/// In the future we may pre-resolve all provider database addresses
/// and build them in.
fn load_hardcoded_cache(hostname: &str, port: u16) -> Vec<SocketAddr> {
if let Some(ips) = DNS_PRELOAD.get(hostname) {
ips.iter().map(|ip| SocketAddr::new(*ip, port)).collect()
} else {
Vec::new()
}
}

async fn lookup_cache(
context: &Context,
host: &str,
Expand Down Expand Up @@ -631,8 +620,13 @@ pub(crate) async fn lookup_host_with_cache(
}
}

if resolved_addrs.is_empty() {
return Ok(load_hardcoded_cache(hostname, port));
if let Some(ips) = DNS_PRELOAD.get(hostname) {
for ip in ips {
let addr = SocketAddr::new(*ip, port);
if !resolved_addrs.contains(&addr) {
resolved_addrs.push(addr);
}
}
}
}

Expand Down

0 comments on commit 137ee93

Please sign in to comment.