diff options
| -rw-r--r-- | windows/windns/src/windns/configmanager.cpp | 53 | ||||
| -rw-r--r-- | windows/windns/src/windns/configmanager.h | 46 |
2 files changed, 82 insertions, 17 deletions
diff --git a/windows/windns/src/windns/configmanager.cpp b/windows/windns/src/windns/configmanager.cpp index 5efb48d2d0..4ebdfcfbae 100644 --- a/windows/windns/src/windns/configmanager.cpp +++ b/windows/windns/src/windns/configmanager.cpp @@ -34,30 +34,55 @@ const std::vector<std::wstring> &ConfigManager::getServers() const return m_servers; } -bool ConfigManager::updateConfig(DnsConfig &&config) +ConfigManager::UpdateType ConfigManager::updateConfig(const DnsConfig &previous, const DnsConfig &target) { - XTRACE(L"Interface configuration update for interface =", config.interfaceIndex()); - - if (false == validUpdate(config)) + XTRACE(L"Interface configuration update for interface =", target.interfaceIndex()); + + // + // There are a few cases we need to deal with: + // + // 1/ An interface being offline and coming online. + // 2/ An external application changing the interface settings. + // 3/ Us changing the interface settings. + // a. On an interface the ConfigManager hasn't seen before. + // b. On an interface the ConfigManager already knows about. + // + + const auto configIndex = target.configIndex(); + auto iter = m_configs.find(configIndex); + + if (internalUpdate(target)) { - XTRACE(L"Ignoring interface configuration update"); - return false; - } + XTRACE(L"Update event was initiated by WINDNS"); - auto iter = m_configs.find(config.id()); + // + // If we haven't seen this config id before, it means the 'previous' instance + // is the original configuration on the system, and as such must be recorded. + // + if (m_configs.end() == iter) + { + XTRACE(L"Creating new interface configuration entry"); + m_configs.insert(std::make_pair(configIndex, previous)); + } + + return UpdateType::WinDnsEnforced; + } + // + // The update was not initiated by us so store the updated configuration. + // if (m_configs.end() == iter) { XTRACE(L"Creating new interface configuration entry"); - m_configs.insert(std::make_pair(config.id(), std::move(config))); + m_configs.insert(std::make_pair(configIndex, target)); } else { XTRACE(L"Updating interface configuration entry"); - iter->second = std::move(config); + iter->second = target; } - return true; + return UpdateType::External; } bool ConfigManager::processConfigs(std::function<bool(const DnsConfig &)> configSink) @@ -73,14 +98,14 @@ bool ConfigManager::processConfigs(std::function<bool(const DnsConfig &)> config return true; } -bool ConfigManager::validUpdate(const DnsConfig &config) +bool ConfigManager::internalUpdate(const DnsConfig &config) { auto updatedServers = config.servers(); if (nullptr == updatedServers) { - return true; + return false; } - return false == std::equal(m_servers.begin(), m_servers.end(), updatedServers->begin(), updatedServers->end()); + return std::equal(m_servers.begin(), m_servers.end(), updatedServers->begin(), updatedServers->end()); } diff --git a/windows/windns/src/windns/configmanager.h b/windows/windns/src/windns/configmanager.h index 3760319bbb..1344e23857 100644 --- a/windows/windns/src/windns/configmanager.h +++ b/windows/windns/src/windns/configmanager.h @@ -8,6 +8,16 @@ #include <memory> #include <functional> +// +// The ConfigManager is engineered to track the "real" DNS configuration for an adapter. +// +// The situation is somewhat complicated, because a given system may have several adapters, which +// in turn may have several configurations? +// +// Every update for every configuration is recorded, bar the ones that correspond to us +// overriding the DNS settings. +// + class ConfigManager { public: @@ -43,23 +53,53 @@ public: std::shared_ptr<ITraceSink> traceSink = std::make_shared<NullTraceSink>() ); + // + // The ConfigManager is shared between threads. + // Locking is managed externally for reasons of efficiency. + // void lock(); void unlock(); + // + // Notify the ConfigManager that servers used when overriding DNS settings have changed. + // void updateServers(const std::vector<std::wstring> &servers); + + // + // Get the current set of servers used for overriding DNS settings. + // const std::vector<std::wstring> &getServers() const; - bool updateConfig(DnsConfig &&config); + // + // Notify the ConfigManager that a live configuration has been updated. + // + enum class UpdateType + { + WinDnsEnforced, + External + }; + + UpdateType updateConfig(const DnsConfig &previous, const DnsConfig &target); + // + // Enumerate recorded configs. + // bool processConfigs(std::function<bool(const DnsConfig &)> configSink); private: std::mutex m_mutex; std::vector<std::wstring> m_servers; - std::map<std::wstring, DnsConfig> m_configs; + + // + // Organize configs based on their system assigned index. + // + std::map<uint32_t, DnsConfig> m_configs; std::shared_ptr<ITraceSink> m_traceSink; - bool validUpdate(const DnsConfig &config); + // + // Tests, by looking at the servers, whether this is an update initied by WINDNS. + // + bool internalUpdate(const DnsConfig &config); }; |
