diff options
author | Himbeer <himbeer@disroot.org> | 2024-08-19 21:48:36 +0200 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2024-08-19 21:48:36 +0200 |
commit | aee8706bc84d98e96f7a30f1c3dbc1411f4d06a6 (patch) | |
tree | b31b9a1fc8d3a13aa9058c05d468ad827d384483 | |
parent | 4e2c8045137d8ba60422293d69d214f4b6bf3518 (diff) |
Fix forward lookups requiring linear-time checks against the hosts file
This should fix the resolver becoming unusably slow on low-end hardware
with long blocklists.
-rw-r--r-- | src/main.rs | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/src/main.rs b/src/main.rs index 6650dc4..fae9f94 100644 --- a/src/main.rs +++ b/src/main.rs @@ -138,7 +138,7 @@ fn read_hosts(cache: Arc<RwLock<HashMap<String, IpAddr>>>) -> Result<()> { let mut columns = split_input.split_whitespace(); let addr = columns.next().ok_or(Error::NoAddrColumn(line))?; for host in columns { - hosts.insert(host.to_string(), addr.parse()?); + hosts.insert(host.to_string() + ".", addr.parse()?); } } @@ -510,22 +510,28 @@ fn file_entry( hosts: Arc<RwLock<HashMap<String, IpAddr>>>, ) -> Option<(String, IpAddr)> { let hosts = hosts.read().unwrap(); - let (host, addr) = hosts.iter().find(|(host, addr)| { - if Name::from_str("in-addr.arpa.").unwrap().zone_of(hostname) && hostname.iter().len() <= 6 - { + let (host, addr) = if Name::from_str("in-addr.arpa.").unwrap().zone_of(hostname) + && hostname.iter().len() <= 6 + { + let (host, addr) = hosts.iter().find(|(_, addr)| { IpNet::new(**addr, 32).unwrap() == hostname.parse_arpa_name().expect("can't parse arpa name") - } else if Name::from_str("ip6.arpa.").unwrap().zone_of(hostname) - && hostname.iter().len() <= 34 - { + })?; + (host.clone(), *addr) + } else if Name::from_str("ip6.arpa.").unwrap().zone_of(hostname) && hostname.iter().len() <= 34 + { + let (host, addr) = hosts.iter().find(|(_, addr)| { IpNet::new(**addr, 128).unwrap() == hostname.parse_arpa_name().expect("can't parse arpa name") - } else { - (*host).clone() + "." == hostname.to_utf8() - } - })?; + })?; + (host.clone(), *addr) + } else { + let hostname_utf8 = hostname.to_utf8(); + let addr = hosts.get(&hostname_utf8)?; + (hostname_utf8, *addr) + }; - Some((host.clone(), *addr)) + Some((host, addr)) } fn is_file_known(hostname: &Name, hosts: Arc<RwLock<HashMap<String, IpAddr>>>) -> bool { |