summaryrefslogtreecommitdiffhomepage
path: root/mullvad-rpc/src
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2018-03-26 11:41:39 -0300
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2018-04-11 06:35:07 -0300
commit2b1f5f82d690a945d53ec009821e51ead825d92e (patch)
treeca858105bfecdd2b332cb009668fd355dd8305ef /mullvad-rpc/src
parent17c306705a16914c2b1476d2ae86790271f628e3 (diff)
downloadmullvadvpn-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.rs36
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(|| {