diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2018-03-26 11:41:39 -0300 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2018-04-11 06:35:07 -0300 |
| commit | 2b1f5f82d690a945d53ec009821e51ead825d92e (patch) | |
| tree | ca858105bfecdd2b332cb009668fd355dd8305ef /mullvad-rpc/src | |
| parent | 17c306705a16914c2b1476d2ae86790271f628e3 (diff) | |
| download | mullvadvpn-2b1f5f82d690a945d53ec009821e51ead825d92e.tar.xz mullvadvpn-2b1f5f82d690a945d53ec009821e51ead825d92e.zip | |
Implement timeout for DNS resolution
Diffstat (limited to 'mullvad-rpc/src')
| -rw-r--r-- | mullvad-rpc/src/cached_dns_resolver.rs | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/mullvad-rpc/src/cached_dns_resolver.rs b/mullvad-rpc/src/cached_dns_resolver.rs index 3acfad378c..f667214499 100644 --- a/mullvad-rpc/src/cached_dns_resolver.rs +++ b/mullvad-rpc/src/cached_dns_resolver.rs @@ -2,21 +2,35 @@ use std::fs::File; use std::io::{self, Read, Write}; use std::net::{IpAddr, ToSocketAddrs}; use std::path::{Path, PathBuf}; +use std::sync::mpsc; +use std::thread; use std::time::{Duration, SystemTime, UNIX_EPOCH}; +static DNS_TIMEOUT: Duration = Duration::from_secs(2); static MAX_CACHE_AGE: Duration = Duration::from_secs(3600); static EXPIRED_CACHE_TIMESTAMP: SystemTime = UNIX_EPOCH; pub trait DnsResolver { - fn resolve(&self, host: &str) -> io::Result<IpAddr>; + fn resolve(&mut self, host: &str) -> io::Result<IpAddr>; } pub struct SystemDnsResolver; -impl DnsResolver for SystemDnsResolver { - fn resolve(&self, host: &str) -> io::Result<IpAddr> { +impl SystemDnsResolver { + fn resolve_in_background_thread(host: &str) -> mpsc::Receiver<io::Result<IpAddr>> { + let host = host.to_owned(); + let (tx, rx) = mpsc::channel(); + + thread::spawn(move || { + let _ = tx.send(Self::resolve_hostname(&host)); + }); + + rx + } + + fn resolve_hostname(host: &str) -> io::Result<IpAddr> { (host, 0) .to_socket_addrs()? .next() @@ -27,6 +41,20 @@ impl DnsResolver for SystemDnsResolver { } } +impl DnsResolver for SystemDnsResolver { + fn resolve(&mut self, host: &str) -> io::Result<IpAddr> { + Self::resolve_in_background_thread(host) + .recv_timeout(DNS_TIMEOUT) + .map_err(|_| { + io::Error::new( + io::ErrorKind::Other, + "Timeout while performing DNS resolution", + ) + }) + .and_then(|result| result) + } +} + pub struct CachedDnsResolver<R: DnsResolver = SystemDnsResolver> { hostname: String, dns_resolver: R, @@ -317,7 +345,7 @@ mod tests { } impl DnsResolver for MockDnsResolver { - fn resolve(&self, host: &str) -> io::Result<IpAddr> { + fn resolve(&mut self, host: &str) -> io::Result<IpAddr> { self.called.store(true, Ordering::Release); self.address.ok_or_else(|| { |
