Skip to content

Commit

Permalink
Merge branch 'linux-systemd-resolve-check-contents'
Browse files Browse the repository at this point in the history
  • Loading branch information
pinkisemils committed Jan 7, 2021
2 parents 3d276db + e63ce42 commit 79ba258
Showing 1 changed file with 42 additions and 12 deletions.
54 changes: 42 additions & 12 deletions talpid-core/src/dns/linux/systemd_resolved.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use dbus::{
};
use lazy_static::lazy_static;
use libc::{AF_INET, AF_INET6};
use std::{fs, net::IpAddr, path::Path, sync::Arc, time::Duration};
use std::{fs, io, net::IpAddr, path::Path, sync::Arc, time::Duration};
use talpid_types::ErrorExt as _;

pub type Result<T> = std::result::Result<T, Error>;
Expand All @@ -17,6 +17,12 @@ pub enum Error {
#[error(display = "Failed to initialize a connection to D-Bus")]
ConnectDBus(#[error(source)] dbus::Error),

#[error(display = "Failed to read /etc/resolv.conf: _0")]
ReadResolvConfError(#[error(source)] io::Error),

#[error(display = "/etc/resolv.conf contents do not match systemd-resolved resolv.conf")]
ResolvConfDiffers,

#[error(display = "/etc/resolv.conf is not a symlink to Systemd resolved")]
NotSymlinkedToResolvConf,

Expand Down Expand Up @@ -92,20 +98,44 @@ impl SystemdResolved {
}

fn ensure_resolv_conf_is_resolved_symlink() -> Result<()> {
let link_target =
fs::read_link(RESOLV_CONF_PATH).map_err(|_| Error::NotSymlinkedToResolvConf)?;

// if /etc/resolv.conf is not symlinked to the stub resolve.conf file , managing DNS
// through systemd-resolved will not ensure that our resolver is given priority - sometimes
// this will mean adding 1 and 2 seconds of latency to DNS queries, other times our
// resolver won't be considered at all. In this case, it's better to fall back to cruder
// management methods.
if Self::path_is_resolvconf_stub(&link_target)
|| Self::resolv_conf_is_static_stub(&link_target)?
match fs::read_link(RESOLV_CONF_PATH) {
Ok(link_target) => {
// if /etc/resolv.conf is not symlinked to the stub resolve.conf file , managing DNS
// through systemd-resolved will not ensure that our resolver is given priority -
// sometimes this will mean adding 1 and 2 seconds of latency to DNS
// queries, other times our resolver won't be considered at all. In
// this case, it's better to fall back to cruder management methods.
if Self::path_is_resolvconf_stub(&link_target)
|| Self::resolv_conf_is_static_stub(&link_target)?
|| Self::ensure_resolvconf_contents().is_ok()
{
Ok(())
} else {
Err(Error::NotSymlinkedToResolvConf)
}
}
// etc/resolv.conf is not a symlink
Err(err) if err.kind() == io::ErrorKind::InvalidInput => {
Self::ensure_resolvconf_contents()
}
Err(err) => {
log::trace!("Failed to read /etc/resolv.conf symlink - {}", err);
Err(Error::NotSymlinkedToResolvConf)
}
}
}

fn ensure_resolvconf_contents() -> Result<()> {
let resolv_conf =
fs::read_to_string(RESOLV_CONF_PATH).map_err(Error::ReadResolvConfError)?;
if RESOLVED_STUB_PATHS
.iter()
.filter_map(|path| fs::read_to_string(path).ok())
.any(|link_contents| link_contents == resolv_conf)
{
Ok(())
} else {
Err(Error::NotSymlinkedToResolvConf)
Err(Error::ResolvConfDiffers)
}
}

Expand Down

0 comments on commit 79ba258

Please sign in to comment.