summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--windows/windns/src/windns/configmanager.cpp53
-rw-r--r--windows/windns/src/windns/configmanager.h46
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);
};