summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2021-01-08 14:53:31 +0100
committerDavid Lönnhager <david.l@mullvad.net>2021-01-08 14:53:31 +0100
commit63835d9ab54688c00aa8c87ebd628bfa91c16385 (patch)
tree831784de081a1d7f3c0cd56e8c84f2cfaf02c7d4
parent44929b7bc51428985f7f0508d65abee43b0ee1d3 (diff)
parent49391a28ff00ae8efd452be664ca66d134517f2a (diff)
downloadmullvadvpn-63835d9ab54688c00aa8c87ebd628bfa91c16385.tar.xz
mullvadvpn-63835d9ab54688c00aa8c87ebd628bfa91c16385.zip
Merge branch 'netbios-fallback'
-rw-r--r--CHANGELOG.md3
-rw-r--r--README.md6
-rw-r--r--talpid-core/src/dns/windows/mod.rs56
3 files changed, 47 insertions, 18 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b72ba378c4..ac7303ff09 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -37,6 +37,9 @@ Line wrap the file at 100 chars. Th
#### Linux
- Fix missing app window icon in Xfce.
+#### Windows
+- Resolve single-label hostnames correctly.
+
### Security
#### Linux
- Prevent the private tunnel IPv6 address from being detectable on a local network when using
diff --git a/README.md b/README.md
index ed265bc210..ed6714ef4b 100644
--- a/README.md
+++ b/README.md
@@ -369,6 +369,12 @@ echo "org.gradle.jvmargs=-Xmx4608M" >> ~/.gradle/gradle.properties
* `TALPID_FORCE_USERSPACE_WIREGUARD` - Forces the daemon to use the userspace implementation of
WireGuard on Linux.
+* `TALPID_DNS_CACHE_POLICY` - On Windows, this changes how DNS is configured:
+ * `1`: The default. This sets a global list of DNS servers that `dnscache` will use instead of
+ the servers specified on each interface.
+ * `0`: Only set DNS servers on the tunnel interface. This will misbehave if local custom DNS
+ servers are used.
+
## Building and running the desktop Electron GUI app
diff --git a/talpid-core/src/dns/windows/mod.rs b/talpid-core/src/dns/windows/mod.rs
index 66a361e9be..17165c2364 100644
--- a/talpid-core/src/dns/windows/mod.rs
+++ b/talpid-core/src/dns/windows/mod.rs
@@ -1,7 +1,10 @@
use crate::logging::windows::{log_sink, LogSink};
+use lazy_static::lazy_static;
use log::{error, trace, warn};
-use std::{ffi::OsString, io, iter, mem, net::IpAddr, os::windows::ffi::OsStrExt, path::Path, ptr};
+use std::{
+ env, ffi::OsString, io, iter, mem, net::IpAddr, os::windows::ffi::OsStrExt, path::Path, ptr,
+};
use talpid_types::ErrorExt;
use widestring::WideCString;
use winapi::um::{
@@ -21,6 +24,13 @@ use self::system_state::SystemStateWriter;
const DNS_STATE_FILENAME: &'static str = "dns-state-backup";
const DNS_CACHE_POLICY_GUID: &str = "{d57d2750-f971-408e-8e55-cfddb37e60ae}";
+lazy_static! {
+ /// Specifies whether to override per-interface DNS resolvers with a global DNS policy.
+ static ref GLOBAL_DNS_CACHE_POLICY: bool = env::var("TALPID_DNS_CACHE_POLICY")
+ .map(|v| v != "0")
+ .unwrap_or(true);
+}
+
/// Errors that can happen when configuring DNS on Windows.
#[derive(err_derive::Error, Debug)]
pub enum Error {
@@ -49,15 +59,6 @@ impl super::DnsMonitorT for DnsMonitor {
fn new(cache_dir: impl AsRef<Path>) -> Result<Self, Error> {
unsafe { WinDns_Initialize(Some(log_sink), b"WinDns\0".as_ptr()).into_result()? };
- if is_minimum_windows10() {
- if let Err(error) = reset_dns_cache_policy() {
- error!(
- "{}",
- error.display_chain_with_msg("Failed to reset DNS cache policy")
- );
- }
- }
-
let backup_writer = SystemStateWriter::new(
cache_dir
.as_ref()
@@ -65,7 +66,11 @@ impl super::DnsMonitorT for DnsMonitor {
.into_boxed_path(),
);
let _ = backup_writer.remove_backup();
- Ok(DnsMonitor {})
+
+ let mut monitor = DnsMonitor {};
+ monitor.reset()?;
+
+ Ok(monitor)
}
fn set(&mut self, interface: &str, servers: &[IpAddr]) -> Result<(), Error> {
@@ -103,7 +108,7 @@ impl super::DnsMonitorT for DnsMonitor {
.into_result()
}?;
- if is_minimum_windows10() {
+ if *GLOBAL_DNS_CACHE_POLICY && is_minimum_windows10() {
if let Err(error) = set_dns_cache_policy(servers) {
error!("{}", error.display_chain());
warn!("DNS resolution may be slowed down");
@@ -114,7 +119,7 @@ impl super::DnsMonitorT for DnsMonitor {
}
fn reset(&mut self) -> Result<(), Error> {
- if is_minimum_windows10() {
+ if *GLOBAL_DNS_CACHE_POLICY && is_minimum_windows10() {
reset_dns_cache_policy()
} else {
Ok(())
@@ -128,7 +133,7 @@ fn ip_to_widestring(ip: &IpAddr) -> WideCString {
impl Drop for DnsMonitor {
fn drop(&mut self) {
- if is_minimum_windows10() {
+ if *GLOBAL_DNS_CACHE_POLICY && is_minimum_windows10() {
if let Err(error) = reset_dns_cache_policy() {
warn!(
"{}",
@@ -160,8 +165,13 @@ fn set_dns_cache_policy(servers: &[IpAddr]) -> Result<(), Error> {
}
fn set_dns_cache_policy_inner(transaction: &Transaction, servers: &[IpAddr]) -> Result<(), Error> {
- let dns_cache_parameters = RegKey::predef(HKEY_LOCAL_MACHINE)
- .open_subkey(r#"SYSTEM\CurrentControlSet\Services\DnsCache\Parameters"#)?;
+ let (dns_cache_parameters, _) = RegKey::predef(HKEY_LOCAL_MACHINE).create_subkey_transacted(
+ r#"SYSTEM\CurrentControlSet\Services\DnsCache\Parameters"#,
+ transaction,
+ )?;
+
+ // Fall back on LLMNR and NetBIOS if DNS resolution fails
+ dns_cache_parameters.set_value("DnsSecureNameQueryFallback", &1u32)?;
let policy_path = Path::new("DnsPolicyConfig").join(DNS_CACHE_POLICY_GUID);
let (policy_config, _) =
@@ -186,8 +196,18 @@ fn set_dns_cache_policy_inner(transaction: &Transaction, servers: &[IpAddr]) ->
}
fn reset_dns_cache_policy() -> Result<(), Error> {
- let dns_cache_parameters = RegKey::predef(HKEY_LOCAL_MACHINE)
- .open_subkey(r#"SYSTEM\CurrentControlSet\Services\DnsCache\Parameters"#)?;
+ let (dns_cache_parameters, _) = RegKey::predef(HKEY_LOCAL_MACHINE)
+ .create_subkey(r#"SYSTEM\CurrentControlSet\Services\DnsCache\Parameters"#)?;
+ match dns_cache_parameters.delete_value("DnsSecureNameQueryFallback") {
+ Ok(()) => Ok(()),
+ Err(error) => {
+ if error.kind() == io::ErrorKind::NotFound {
+ Ok(())
+ } else {
+ Err(Error::UpdateDnsCachePolicy(error))
+ }
+ }
+ }?;
let policy_path = Path::new("DnsPolicyConfig").join(DNS_CACHE_POLICY_GUID);
match dns_cache_parameters.delete_subkey_all(policy_path) {
Ok(()) => Ok(()),