summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2022-05-04 14:32:19 +0200
committerDavid Lönnhager <david.l@mullvad.net>2022-05-04 14:32:19 +0200
commite130e04448327369be97929c28032dacd0a8e2ab (patch)
treee394aa9e70404ca8150e3fe9aa48ce14c3331552
parentb1316278017c43405a94789e647b0d38723f089d (diff)
parentbb4a8ba6b75643b1cab1f784c9e9f9a9068a7e7c (diff)
downloadmullvadvpn-e130e04448327369be97929c28032dacd0a8e2ab.tar.xz
mullvadvpn-e130e04448327369be97929c28032dacd0a8e2ab.zip
Merge branch 'move-dns-options'
-rw-r--r--mullvad-daemon/src/dns.rs55
-rw-r--r--mullvad-daemon/src/lib.rs62
-rw-r--r--mullvad-types/src/settings/dns.rs89
-rw-r--r--mullvad-types/src/settings/mod.rs89
4 files changed, 154 insertions, 141 deletions
diff --git a/mullvad-daemon/src/dns.rs b/mullvad-daemon/src/dns.rs
new file mode 100644
index 0000000000..e82c50200e
--- /dev/null
+++ b/mullvad-daemon/src/dns.rs
@@ -0,0 +1,55 @@
+use mullvad_types::settings::{DnsOptions, DnsState};
+use std::net::{IpAddr, Ipv4Addr};
+
+/// When we want to block certain contents with the help of DNS server side,
+/// we compute the resolver IP to use based on these constants. The last
+/// byte can be ORed together to combine multiple block lists.
+const DNS_BLOCKING_IP_BASE: Ipv4Addr = Ipv4Addr::new(100, 64, 0, 0);
+const DNS_AD_BLOCKING_IP_BIT: u8 = 1 << 0; // 0b00000001
+const DNS_TRACKER_BLOCKING_IP_BIT: u8 = 1 << 1; // 0b00000010
+const DNS_MALWARE_BLOCKING_IP_BIT: u8 = 1 << 2; // 0b00000100
+const DNS_ADULT_BLOCKING_IP_BIT: u8 = 1 << 3; // 0b00001000
+const DNS_GAMBLING_BLOCKING_IP_BIT: u8 = 1 << 4; // 0b00010000
+
+/// Return the resolvers as a vector of `IpAddr`s. Returns `None` when no special resolvers
+/// are requested and the tunnel default gateway should be used.
+pub fn addresses_from_options(options: &DnsOptions) -> Option<Vec<IpAddr>> {
+ match options.state {
+ DnsState::Default => {
+ // Check if we should use a custom blocking DNS resolver.
+ // And if so, compute the IP.
+ let mut last_byte: u8 = 0;
+
+ if options.default_options.block_ads {
+ last_byte |= DNS_AD_BLOCKING_IP_BIT;
+ }
+ if options.default_options.block_trackers {
+ last_byte |= DNS_TRACKER_BLOCKING_IP_BIT;
+ }
+ if options.default_options.block_malware {
+ last_byte |= DNS_MALWARE_BLOCKING_IP_BIT;
+ }
+ if options.default_options.block_adult_content {
+ last_byte |= DNS_ADULT_BLOCKING_IP_BIT;
+ }
+ if options.default_options.block_gambling {
+ last_byte |= DNS_GAMBLING_BLOCKING_IP_BIT;
+ }
+
+ if last_byte != 0 {
+ let mut dns_ip = DNS_BLOCKING_IP_BASE.octets();
+ dns_ip[dns_ip.len() - 1] |= last_byte;
+ Some(vec![IpAddr::V4(Ipv4Addr::from(dns_ip))])
+ } else {
+ None
+ }
+ }
+ DnsState::Custom => {
+ if options.custom_options.addresses.is_empty() {
+ None
+ } else {
+ Some(options.custom_options.addresses.clone())
+ }
+ }
+ }
+}
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs
index 3b75b7ceb2..eb674b5763 100644
--- a/mullvad-daemon/src/lib.rs
+++ b/mullvad-daemon/src/lib.rs
@@ -7,6 +7,7 @@ extern crate serde;
pub mod account_history;
mod api;
pub mod device;
+mod dns;
pub mod exception_logging;
#[cfg(target_os = "macos")]
pub mod exclusion_gid;
@@ -42,7 +43,7 @@ use mullvad_types::{
location::GeoIpLocation,
relay_constraints::{BridgeSettings, BridgeState, ObfuscationSettings, RelaySettingsUpdate},
relay_list::{Relay, RelayList},
- settings::{DnsOptions, DnsState, Settings},
+ settings::{DnsOptions, Settings},
states::{TargetState, TunnelState},
version::{AppVersion, AppVersionInfo},
wireguard::{PublicKey, RotationInterval},
@@ -57,7 +58,6 @@ use std::{collections::HashSet, ffi::OsString};
use std::{
marker::PhantomData,
mem,
- net::{IpAddr, Ipv4Addr},
path::PathBuf,
pin::Pin,
sync::{mpsc as sync_mpsc, Arc, Weak},
@@ -85,16 +85,6 @@ use tokio::io;
/// Delay between generating a new WireGuard key and reconnecting
const WG_RECONNECT_DELAY: Duration = Duration::from_secs(4 * 60);
-/// When we want to block certain contents with the help of DNS server side,
-/// we compute the resolver IP to use based on these constants. The last
-/// byte can be ORed together to combine multiple block lists.
-const DNS_BLOCKING_IP_BASE: Ipv4Addr = Ipv4Addr::new(100, 64, 0, 0);
-const DNS_AD_BLOCKING_IP_BIT: u8 = 1 << 0; // 0b00000001
-const DNS_TRACKER_BLOCKING_IP_BIT: u8 = 1 << 1; // 0b00000010
-const DNS_MALWARE_BLOCKING_IP_BIT: u8 = 1 << 2; // 0b00000100
-const DNS_ADULT_BLOCKING_IP_BIT: u8 = 1 << 3; // 0b00001000
-const DNS_GAMBLING_BLOCKING_IP_BIT: u8 = 1 << 4; // 0b00010000
-
pub type ResponseTx<T, E> = oneshot::Sender<Result<T, E>>;
#[derive(err_derive::Error, Debug)]
@@ -711,7 +701,7 @@ where
tunnel_state_machine::InitialTunnelState {
allow_lan: settings.allow_lan,
block_when_disconnected: settings.block_when_disconnected,
- dns_servers: Self::get_dns_resolvers(&settings.tunnel_options.dns_options),
+ dns_servers: dns::addresses_from_options(&settings.tunnel_options.dns_options),
allowed_endpoint: initial_api_endpoint,
reset_firewall: *target_state != TargetState::Secured,
#[cfg(windows)]
@@ -796,49 +786,6 @@ where
Ok(daemon)
}
- /// Get which special DNS resolvers to use. Returns `None` when no special resolvers
- /// are requested and the tunnel default gateway should be used.
- fn get_dns_resolvers(options: &DnsOptions) -> Option<Vec<IpAddr>> {
- match options.state {
- DnsState::Default => {
- // Check if we should use a custom blocking DNS resolver.
- // And if so, compute the IP.
- let mut last_byte: u8 = 0;
-
- if options.default_options.block_ads {
- last_byte |= DNS_AD_BLOCKING_IP_BIT;
- }
- if options.default_options.block_trackers {
- last_byte |= DNS_TRACKER_BLOCKING_IP_BIT;
- }
- if options.default_options.block_malware {
- last_byte |= DNS_MALWARE_BLOCKING_IP_BIT;
- }
- if options.default_options.block_adult_content {
- last_byte |= DNS_ADULT_BLOCKING_IP_BIT;
- }
- if options.default_options.block_gambling {
- last_byte |= DNS_GAMBLING_BLOCKING_IP_BIT;
- }
-
- if last_byte != 0 {
- let mut dns_ip = DNS_BLOCKING_IP_BASE.octets();
- dns_ip[dns_ip.len() - 1] |= last_byte;
- Some(vec![IpAddr::V4(Ipv4Addr::from(dns_ip))])
- } else {
- None
- }
- }
- DnsState::Custom => {
- if options.custom_options.addresses.is_empty() {
- None
- } else {
- Some(options.custom_options.addresses.clone())
- }
- }
- }
- }
-
/// Consume the `Daemon` and run the main event loop. Blocks until an error happens or a
/// shutdown event is received.
pub async fn run(mut self) -> Result<(), Error> {
@@ -2256,7 +2203,8 @@ where
Self::oneshot_send(tx, Ok(()), "set_dns_options response");
if settings_changed {
let settings = self.settings.to_settings();
- let resolvers = Self::get_dns_resolvers(&settings.tunnel_options.dns_options);
+ let resolvers =
+ dns::addresses_from_options(&settings.tunnel_options.dns_options);
self.event_listener.notify_settings(settings);
self.send_tunnel_command(TunnelCommand::Dns(resolvers));
}
diff --git a/mullvad-types/src/settings/dns.rs b/mullvad-types/src/settings/dns.rs
new file mode 100644
index 0000000000..f379fd286f
--- /dev/null
+++ b/mullvad-types/src/settings/dns.rs
@@ -0,0 +1,89 @@
+#[cfg(target_os = "android")]
+use jnix::{jni::objects::JObject, FromJava, IntoJava, JnixEnv};
+use serde::{Deserialize, Serialize};
+use std::net::IpAddr;
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
+#[serde(rename_all = "snake_case")]
+pub enum DnsState {
+ Default,
+ Custom,
+}
+
+impl Default for DnsState {
+ fn default() -> Self {
+ Self::Default
+ }
+}
+
+/// DNS config
+#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
+#[serde(default)]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
+pub struct DnsOptions {
+ #[cfg_attr(target_os = "android", jnix(map = "|state| state == DnsState::Custom"))]
+ pub state: DnsState,
+ #[cfg_attr(target_os = "android", jnix(skip))]
+ pub default_options: DefaultDnsOptions,
+ #[cfg_attr(target_os = "android", jnix(map = "|opts| opts.addresses"))]
+ pub custom_options: CustomDnsOptions,
+}
+
+#[cfg(target_os = "android")]
+#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
+#[cfg_attr(target_os = "android", derive(FromJava))]
+#[cfg_attr(
+ target_os = "android",
+ jnix(class_name = "net.mullvad.mullvadvpn.model.DnsOptions")
+)]
+pub struct AndroidDnsOptions {
+ pub custom: bool,
+ pub addresses: Vec<IpAddr>,
+}
+
+#[cfg(target_os = "android")]
+impl From<AndroidDnsOptions> for DnsOptions {
+ fn from(options: AndroidDnsOptions) -> Self {
+ Self {
+ state: if options.custom {
+ DnsState::Custom
+ } else {
+ DnsState::Default
+ },
+ default_options: DefaultDnsOptions::default(),
+ custom_options: CustomDnsOptions {
+ addresses: options.addresses,
+ },
+ }
+ }
+}
+
+#[cfg(target_os = "android")]
+impl<'env, 'sub_env> FromJava<'env, JObject<'sub_env>> for DnsOptions
+where
+ 'env: 'sub_env,
+{
+ const JNI_SIGNATURE: &'static str = "Lnet/mullvad/mullvadvpn/model/DnsOptions";
+
+ fn from_java(env: &JnixEnv<'env>, object: JObject<'sub_env>) -> Self {
+ AndroidDnsOptions::from_java(env, object).into()
+ }
+}
+
+/// Default DNS config
+#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
+#[serde(default)]
+pub struct DefaultDnsOptions {
+ pub block_ads: bool,
+ pub block_trackers: bool,
+ pub block_malware: bool,
+ pub block_adult_content: bool,
+ pub block_gambling: bool,
+}
+
+/// Custom DNS config
+#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
+pub struct CustomDnsOptions {
+ pub addresses: Vec<IpAddr>,
+}
diff --git a/mullvad-types/src/settings/mod.rs b/mullvad-types/src/settings/mod.rs
index 969eb8e4e5..7bfff42824 100644
--- a/mullvad-types/src/settings/mod.rs
+++ b/mullvad-types/src/settings/mod.rs
@@ -7,13 +7,14 @@ use crate::{
wireguard,
};
#[cfg(target_os = "android")]
-use jnix::{jni::objects::JObject, FromJava, IntoJava, JnixEnv};
+use jnix::IntoJava;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
-use std::net::IpAddr;
#[cfg(target_os = "windows")]
use std::{collections::HashSet, path::PathBuf};
use talpid_types::net::{self, openvpn, GenericTunnelOptions};
+mod dns;
+
/// The version used by the current version of the code. Should always be the
/// latest version that exists in `SettingsVersion`.
/// This should be bumped when a new version is introduced along with a migration
@@ -187,90 +188,10 @@ pub struct TunnelOptions {
pub dns_options: DnsOptions,
}
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
-#[serde(rename_all = "snake_case")]
-pub enum DnsState {
- Default,
- Custom,
-}
-
-impl Default for DnsState {
- fn default() -> Self {
- Self::Default
- }
-}
-
-/// DNS config
-#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
-#[serde(default)]
-#[cfg_attr(target_os = "android", derive(IntoJava))]
-#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
-pub struct DnsOptions {
- #[cfg_attr(target_os = "android", jnix(map = "|state| state == DnsState::Custom"))]
- pub state: DnsState,
- #[cfg_attr(target_os = "android", jnix(skip))]
- pub default_options: DefaultDnsOptions,
- #[cfg_attr(target_os = "android", jnix(map = "|opts| opts.addresses"))]
- pub custom_options: CustomDnsOptions,
-}
-
-#[cfg(target_os = "android")]
-#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
-#[cfg_attr(target_os = "android", derive(FromJava))]
-#[cfg_attr(
- target_os = "android",
- jnix(class_name = "net.mullvad.mullvadvpn.model.DnsOptions")
-)]
-pub struct AndroidDnsOptions {
- pub custom: bool,
- pub addresses: Vec<IpAddr>,
-}
-
-#[cfg(target_os = "android")]
-impl From<AndroidDnsOptions> for DnsOptions {
- fn from(options: AndroidDnsOptions) -> Self {
- Self {
- state: if options.custom {
- DnsState::Custom
- } else {
- DnsState::Default
- },
- default_options: DefaultDnsOptions::default(),
- custom_options: CustomDnsOptions {
- addresses: options.addresses,
- },
- }
- }
-}
+pub use dns::{CustomDnsOptions, DefaultDnsOptions, DnsOptions, DnsState};
#[cfg(target_os = "android")]
-impl<'env, 'sub_env> FromJava<'env, JObject<'sub_env>> for DnsOptions
-where
- 'env: 'sub_env,
-{
- const JNI_SIGNATURE: &'static str = "Lnet/mullvad/mullvadvpn/model/DnsOptions";
-
- fn from_java(env: &JnixEnv<'env>, object: JObject<'sub_env>) -> Self {
- AndroidDnsOptions::from_java(env, object).into()
- }
-}
-
-/// Default DNS config
-#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
-#[serde(default)]
-pub struct DefaultDnsOptions {
- pub block_ads: bool,
- pub block_trackers: bool,
- pub block_malware: bool,
- pub block_adult_content: bool,
- pub block_gambling: bool,
-}
-
-/// Custom DNS config
-#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
-pub struct CustomDnsOptions {
- pub addresses: Vec<IpAddr>,
-}
+pub use dns::AndroidDnsOptions;
impl Default for TunnelOptions {
fn default() -> Self {