diff options
| author | Odd Stranne <odd@mullvad.net> | 2018-10-08 10:27:38 +0200 |
|---|---|---|
| committer | Odd Stranne <odd@mullvad.net> | 2018-10-08 10:27:38 +0200 |
| commit | 17fbe2e88c9c8985016ff78e41ede3ea647cdce3 (patch) | |
| tree | 2765d131dda8993e6551a3e3550d55b173dfffe2 | |
| parent | f18fefd5e5fc3ac2fa66b5fa667be42e518d9013 (diff) | |
| parent | 702b16ada63113a8f9e2ee0f1a7d514f0a8803f3 (diff) | |
| download | mullvadvpn-17fbe2e88c9c8985016ff78e41ede3ea647cdce3.tar.xz mullvadvpn-17fbe2e88c9c8985016ff78e41ede3ea647cdce3.zip | |
Merge branch 'windns-improve-error-handling'
| -rw-r--r-- | windows/windns/src/windns/confineoperation.cpp | 18 | ||||
| -rw-r--r-- | windows/windns/src/windns/confineoperation.h | 8 | ||||
| -rw-r--r-- | windows/windns/src/windns/dnsagent.cpp | 127 | ||||
| -rw-r--r-- | windows/windns/src/windns/dnsagent.h | 1 | ||||
| -rw-r--r-- | windows/windns/src/windns/interfacesnap.cpp | 4 | ||||
| -rw-r--r-- | windows/windns/src/windns/interfacesnap.h | 2 | ||||
| -rw-r--r-- | windows/windns/src/windns/recoverylogic.cpp | 55 | ||||
| -rw-r--r-- | windows/windns/src/windns/windnscontext.cpp | 7 |
8 files changed, 139 insertions, 83 deletions
diff --git a/windows/windns/src/windns/confineoperation.cpp b/windows/windns/src/windns/confineoperation.cpp index 5c16de71bf..a43bbd0d2e 100644 --- a/windows/windns/src/windns/confineoperation.cpp +++ b/windows/windns/src/windns/confineoperation.cpp @@ -50,6 +50,24 @@ bool ConfineOperation } } +bool ConfineOperation +( + const char *literalOperation, + ILogSink *logSink, + std::function<void()> operation +) +{ + auto ForwardError = [logSink](const char *error, const char **details, uint32_t numDetails) + { + if (nullptr != logSink) + { + logSink->error(error, details, numDetails); + } + }; + + return ConfineOperation(literalOperation, ForwardError, operation); +} + std::vector<uint8_t> CreateRawStringArray(const std::vector<std::string> &arr) { // diff --git a/windows/windns/src/windns/confineoperation.h b/windows/windns/src/windns/confineoperation.h index 21fe7dd996..4c37058da2 100644 --- a/windows/windns/src/windns/confineoperation.h +++ b/windows/windns/src/windns/confineoperation.h @@ -1,5 +1,6 @@ #pragma once +#include "ilogsink.h" #include <functional> #include <vector> #include <string> @@ -12,6 +13,13 @@ bool ConfineOperation std::function<void()> operation ); +bool ConfineOperation +( + const char *literalOperation, + ILogSink *logSink, + std::function<void()> operation +); + // // The returned buffer looks like this: // diff --git a/windows/windns/src/windns/dnsagent.cpp b/windows/windns/src/windns/dnsagent.cpp index 6ff8ee9b39..e9b3a4246d 100644 --- a/windows/windns/src/windns/dnsagent.cpp +++ b/windows/windns/src/windns/dnsagent.cpp @@ -2,8 +2,10 @@ #include "dnsagent.h" #include "registrypaths.h" #include "netsh.h" +#include "confineoperation.h" #include <libcommon/trace/xtrace.h> #include <libcommon/error.h> +#include <libcommon/string.h> #include <process.h> #include <algorithm> @@ -214,15 +216,23 @@ void DnsAgent::processServerSourceEvent() return interfaceData.interfaceGuid; }); - const auto updatedSnaps = createSnaps(interfaces); const auto enforcedServers = m_nameServerSource->getNameServers(m_protocol); - for (const auto snap : updatedSnaps) + for (const auto &iface : interfaces) { - if (snap.needsOverriding(enforcedServers)) + const auto literalOperation = std::wstring(L"Verifying settings on interface ").append(iface); + + XTRACE(literalOperation); + + ConfineOperation(common::string::ToAnsi(literalOperation).c_str(), m_logSink, [&]() { - setNameServers(snap.interfaceGuid(), enforcedServers); - } + InterfaceSnap snap(m_protocol, iface); + + if (snap.needsOverriding(enforcedServers)) + { + setNameServers(iface, enforcedServers); + } + }); } } @@ -293,36 +303,32 @@ DnsAgent::ProcessingResult DnsAgent::processInterfaceEvent(const HANDLE *interfa continue; } - auto &interface = m_trackedInterfaces[i]; + auto &iface = m_trackedInterfaces[i]; + + const auto literalOperation = std::wstring(L"Processing event for interface ").append(iface.interfaceGuid); - XTRACE(L"Processing event for interface ", interface.interfaceGuid); + XTRACE(literalOperation); - try + ConfineOperation(common::string::ToAnsi(literalOperation).c_str(), m_logSink, [&]() { - InterfaceSnap updatedSnap(m_protocol, interface.interfaceGuid); + InterfaceSnap updatedSnap(m_protocol, iface.interfaceGuid); - if (updatedSnap.needsOverriding(enforcedNameServers)) + if ((iface.preservedSettings.internalInterface() && updatedSnap.internalInterface()) + || updatedSnap.nameServers() == enforcedNameServers) { - result = ProcessingResult::TrackingUpdated; - - interface.preservedSettings = std::move(updatedSnap); - setNameServers(interface.interfaceGuid, enforcedNameServers); + return; } - } - catch (std::exception &err) - { - const char *what = err.what(); - m_logSink->error("Could not fetch updated interface settings. Probably because the interface was removed.", &what, 1); + const auto shouldOverride = updatedSnap.needsOverriding(enforcedNameServers); - continue; - } - catch (...) - { - m_logSink->error("Could not fetch updated interface settings. Probably because the interface was removed."); + result = ProcessingResult::TrackingUpdated; + iface.preservedSettings = std::move(updatedSnap); - continue; - } + if (shouldOverride) + { + setNameServers(iface.interfaceGuid, enforcedNameServers); + } + }); } return result; @@ -345,63 +351,68 @@ std::vector<std::wstring> DnsAgent::discoverInterfaces() return interfaces; } -std::vector<InterfaceSnap> DnsAgent::createSnaps(const std::vector<std::wstring> &interfaces) +void DnsAgent::setNameServers(const std::wstring &interfaceGuid, const std::vector<std::wstring> &enforcedServers) { - std::vector<InterfaceSnap> snaps; + XTRACE(L"Overriding name servers for interface ", interfaceGuid); - snaps.reserve(interfaces.size()); + uint32_t interfaceIndex = 0; - for (const auto &interface : interfaces) + try { - snaps.emplace_back(m_protocol, interface); + interfaceIndex = NetSh::ConvertInterfaceGuidToIndex(interfaceGuid); } + catch (...) + { + // + // The interface cannot be linked to a virtual or physical adapter. + // - return snaps; -} - -void DnsAgent::setNameServers(const std::wstring &interfaceGuid, const std::vector<std::wstring> &enforcedServers) -{ - XTRACE(L"Overriding name servers for interface ", interfaceGuid); + XTRACE(L"Ignoring floating interface ", interfaceGuid); + return; + } if (Protocol::IPv4 == m_protocol) { - NetSh::Instance().SetIpv4StaticDns(NetSh::ConvertInterfaceGuidToIndex(interfaceGuid), enforcedServers); + NetSh::Instance().SetIpv4StaticDns(interfaceIndex, enforcedServers); } else { - NetSh::Instance().SetIpv6StaticDns(NetSh::ConvertInterfaceGuidToIndex(interfaceGuid), enforcedServers); + NetSh::Instance().SetIpv6StaticDns(interfaceIndex, enforcedServers); } } void DnsAgent::startTrackingInterfaces(const std::vector<std::wstring> &interfaces) { - const auto snaps = createSnaps(interfaces); - - // - // Override configured name servers on all interfaces, as necessary. - // - const auto enforcedServers = m_nameServerSource->getNameServers(m_protocol); - for (const auto &snap : snaps) + for (const auto &iface : interfaces) { - if (snap.needsOverriding(enforcedServers)) + const auto literalOperation = std::wstring(L"Start tracking interface ").append(iface); + + XTRACE(literalOperation); + + ConfineOperation(common::string::ToAnsi(literalOperation).c_str(), m_logSink, [&]() { - setNameServers(snap.interfaceGuid(), enforcedServers); - } - } + InterfaceSnap snap(m_protocol, iface); - // - // Create a tracking record for each interface. - // + const auto shouldOverride = snap.needsOverriding(enforcedServers); - for (const auto &snap : snaps) - { - const auto interfaceGuid = snap.interfaceGuid(); + // + // Create a tracking record. + // + + m_trackedInterfaces.emplace_back(iface, std::move(snap), + std::make_unique<InterfaceMonitor>(m_protocol, iface)); - XTRACE(L"Creating tracking entry for interface ", interfaceGuid); + // + // Override configured name servers, as necessary. + // - m_trackedInterfaces.emplace_back(interfaceGuid, snap, std::make_unique<InterfaceMonitor>(m_protocol, interfaceGuid)); + if (shouldOverride) + { + setNameServers(iface, enforcedServers); + } + }); } } diff --git a/windows/windns/src/windns/dnsagent.h b/windows/windns/src/windns/dnsagent.h index 48dd12c52d..db73257330 100644 --- a/windows/windns/src/windns/dnsagent.h +++ b/windows/windns/src/windns/dnsagent.h @@ -73,7 +73,6 @@ private: ProcessingResult processInterfaceEvent(const HANDLE *interfaceEvents, size_t startIndex); std::vector<std::wstring> discoverInterfaces(); - std::vector<InterfaceSnap> createSnaps(const std::vector<std::wstring> &interfaces); void setNameServers(const std::wstring &interfaceGuid, const std::vector<std::wstring> &enforcedServers); diff --git a/windows/windns/src/windns/interfacesnap.cpp b/windows/windns/src/windns/interfacesnap.cpp index 309296897f..1840776ed3 100644 --- a/windows/windns/src/windns/interfacesnap.cpp +++ b/windows/windns/src/windns/interfacesnap.cpp @@ -81,7 +81,7 @@ InterfaceSnap::InterfaceSnap(Protocol protocol, const std::wstring &interfaceGui // DHCP name servers are the servers most recently supplied by DHCP. // An adapter can be configured for DHCP and static name servers at the same time. // Static name servers always have precedence. - m_dhcpNameServers = GetNameServers(m_interfaceGuid, m_protocol, NameServerType::Dhcp); + //m_dhcpNameServers = GetNameServers(m_interfaceGuid, m_protocol, NameServerType::Dhcp); } InterfaceSnap::InterfaceSnap(common::serialization::Deserializer &deserializer) @@ -99,7 +99,6 @@ InterfaceSnap::InterfaceSnap(common::serialization::Deserializer &deserializer) d >> m_interfaceGuid; d >> (uint8_t &)m_configuredForDhcp; d >> m_staticNameServers; - d >> m_dhcpNameServers; } void InterfaceSnap::serialize(common::serialization::Serializer &serializer) const @@ -110,7 +109,6 @@ void InterfaceSnap::serialize(common::serialization::Serializer &serializer) con s << m_interfaceGuid; s << (uint8_t &)m_configuredForDhcp; s << m_staticNameServers; - s << m_dhcpNameServers; } bool InterfaceSnap::needsOverriding(const std::vector<std::wstring> &enforcedServers) const diff --git a/windows/windns/src/windns/interfacesnap.h b/windows/windns/src/windns/interfacesnap.h index 4d1156b615..5159f581eb 100644 --- a/windows/windns/src/windns/interfacesnap.h +++ b/windows/windns/src/windns/interfacesnap.h @@ -29,7 +29,5 @@ private: std::wstring m_interfaceGuid; bool m_configuredForDhcp; - std::vector<std::wstring> m_staticNameServers; - std::vector<std::wstring> m_dhcpNameServers; }; diff --git a/windows/windns/src/windns/recoverylogic.cpp b/windows/windns/src/windns/recoverylogic.cpp index 0c630a89b2..70fe0b8a91 100644 --- a/windows/windns/src/windns/recoverylogic.cpp +++ b/windows/windns/src/windns/recoverylogic.cpp @@ -14,16 +14,11 @@ void RecoveryLogic::RestoreInterfaces(const RecoveryFormatter::Unpacked &data, throw std::runtime_error("Invalid logger sink"); } - auto forwardError = [logSink](const char *msg, const char **details, uint32_t numDetails) - { - logSink->error(msg, details, numDetails); - }; - bool success = true; for (const auto &snap : data.v4Snaps) { - const auto status = ConfineOperation("Reset interface DNS settings", forwardError, [&snap, &timeout]() + const auto status = ConfineOperation("Reset interface DNS settings", logSink, [&snap, &timeout]() { if (snap.internalInterface()) { @@ -34,15 +29,32 @@ void RecoveryLogic::RestoreInterfaces(const RecoveryFormatter::Unpacked &data, return; } - XTRACE("Resetting name server configuration for interface ", snap.interfaceGuid()); + XTRACE(L"Resetting name server configuration for interface ", snap.interfaceGuid()); + + uint32_t interfaceIndex = 0; + + try + { + interfaceIndex = NetSh::ConvertInterfaceGuidToIndex(snap.interfaceGuid()); + } + catch (...) + { + // + // The interface cannot be linked to a virtual or physical adapter. + // It's either floating or has been removed. + // + + XTRACE(L"Ignoring floating/invalid interface ", snap.interfaceGuid()); + return; + } if (snap.nameServers().empty()) { - NetSh::Instance().SetIpv4DhcpDns(NetSh::ConvertInterfaceGuidToIndex(snap.interfaceGuid()), timeout); + NetSh::Instance().SetIpv4DhcpDns(interfaceIndex, timeout); } else { - NetSh::Instance().SetIpv4StaticDns(NetSh::ConvertInterfaceGuidToIndex(snap.interfaceGuid()), snap.nameServers(), timeout); + NetSh::Instance().SetIpv4StaticDns(interfaceIndex, snap.nameServers(), timeout); } }); @@ -54,7 +66,7 @@ void RecoveryLogic::RestoreInterfaces(const RecoveryFormatter::Unpacked &data, for (const auto &snap : data.v6Snaps) { - const auto status = ConfineOperation("Reset interface DNS settings", forwardError, [&snap, &timeout]() + const auto status = ConfineOperation("Reset interface DNS settings", logSink, [&snap, &timeout]() { if (snap.internalInterface()) { @@ -65,15 +77,32 @@ void RecoveryLogic::RestoreInterfaces(const RecoveryFormatter::Unpacked &data, return; } - XTRACE("Resetting name server configuration for interface ", snap.interfaceGuid()); + XTRACE(L"Resetting name server configuration for interface ", snap.interfaceGuid()); + + uint32_t interfaceIndex = 0; + + try + { + interfaceIndex = NetSh::ConvertInterfaceGuidToIndex(snap.interfaceGuid()); + } + catch (...) + { + // + // The interface cannot be linked to a virtual or physical adapter. + // It's either floating or has been removed. + // + + XTRACE(L"Ignoring floating/invalid interface ", snap.interfaceGuid()); + return; + } if (snap.nameServers().empty()) { - NetSh::Instance().SetIpv6DhcpDns(NetSh::ConvertInterfaceGuidToIndex(snap.interfaceGuid()), timeout); + NetSh::Instance().SetIpv6DhcpDns(interfaceIndex, timeout); } else { - NetSh::Instance().SetIpv6StaticDns(NetSh::ConvertInterfaceGuidToIndex(snap.interfaceGuid()), snap.nameServers(), timeout); + NetSh::Instance().SetIpv6StaticDns(interfaceIndex, snap.nameServers(), timeout); } }); diff --git a/windows/windns/src/windns/windnscontext.cpp b/windows/windns/src/windns/windnscontext.cpp index cf80c0e619..7c95358652 100644 --- a/windows/windns/src/windns/windnscontext.cpp +++ b/windows/windns/src/windns/windnscontext.cpp @@ -18,12 +18,7 @@ WinDnsContext::WinDnsContext(ILogSink *logSink) WinDnsContext::~WinDnsContext() { - auto forwardError = [this](const char *msg, const char **details, uint32_t numDetails) - { - m_logSink->error(msg, details, numDetails); - }; - - ConfineOperation("Reset DNS settings", forwardError, [this]() + ConfineOperation("Reset DNS settings", m_logSink, [this]() { this->reset(); }); |
