summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2022-07-13 20:20:22 +0200
committerDavid Lönnhager <david.l@mullvad.net>2022-08-10 14:19:23 +0200
commitd7223f3ae2bfefb267317a8fe7e7c51524f63f94 (patch)
tree4f648d2e8633be970528f54ba38e50dd6841cb15
parent97c55dc556ce9fca5039035070f3fb2af77c8801 (diff)
downloadmullvadvpn-d7223f3ae2bfefb267317a8fe7e7c51524f63f94.tar.xz
mullvadvpn-d7223f3ae2bfefb267317a8fe7e7c51524f63f94.zip
Give up if DNS flush takes too long
-rw-r--r--talpid-core/src/dns/windows/dnsapi.rs23
1 files changed, 22 insertions, 1 deletions
diff --git a/talpid-core/src/dns/windows/dnsapi.rs b/talpid-core/src/dns/windows/dnsapi.rs
index 1c6b2c4fbc..4a0cf636e5 100644
--- a/talpid-core/src/dns/windows/dnsapi.rs
+++ b/talpid-core/src/dns/windows/dnsapi.rs
@@ -1,5 +1,5 @@
use once_cell::sync::OnceCell;
-use std::{io, ptr};
+use std::{io, ptr, sync::mpsc, time::Duration};
use winapi::{
shared::minwindef::{BOOL, FALSE},
um::libloaderapi::{FreeLibrary, GetProcAddress, LoadLibraryExW, LOAD_LIBRARY_SEARCH_SYSTEM32},
@@ -8,6 +8,7 @@ use winapi::{
type FlushResolverCacheFn = unsafe extern "stdcall" fn() -> BOOL;
static FLUSH_RESOLVER_CACHE: OnceCell<FlushResolverCacheFn> = OnceCell::new();
+static FLUSH_TIMEOUT: Duration = Duration::from_secs(5);
/// Errors that can happen when configuring DNS on Windows.
#[derive(err_derive::Error, Debug)]
@@ -24,9 +25,29 @@ pub enum Error {
/// Failed to flush the DNS cache.
#[error(display = "Call to flush DNS cache failed")]
FlushCache,
+
+ /// Flushing the DNS cache timed out.
+ #[error(display = "Timeout while flushing DNS cache")]
+ Timeout,
}
pub fn flush_resolver_cache() -> Result<(), Error> {
+ let (tx, rx) = mpsc::channel();
+
+ std::thread::spawn(move || {
+ if tx.send(flush_resolver_cache_inner()).is_err() {
+ log::warn!("Flushing DNS cache completed (delayed)");
+ }
+ });
+
+ match rx.recv_timeout(FLUSH_TIMEOUT) {
+ Ok(result) => result,
+ // TODO: Can this be a cancelled safely?
+ Err(_timeout_err) => Err(Error::Timeout),
+ }
+}
+
+fn flush_resolver_cache_inner() -> Result<(), Error> {
let flush_cache = FLUSH_RESOLVER_CACHE.get_or_try_init(|| {
let handle = unsafe {
LoadLibraryExW(