summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--windns/src/windns/configmanager.cpp86
-rw-r--r--windns/src/windns/configmanager.h65
2 files changed, 151 insertions, 0 deletions
diff --git a/windns/src/windns/configmanager.cpp b/windns/src/windns/configmanager.cpp
new file mode 100644
index 0000000000..5efb48d2d0
--- /dev/null
+++ b/windns/src/windns/configmanager.cpp
@@ -0,0 +1,86 @@
+#include "stdafx.h"
+#include "configmanager.h"
+#include <utility>
+#include <algorithm>
+
+ConfigManager::ConfigManager
+(
+ const std::vector<std::wstring> &servers,
+ std::shared_ptr<ITraceSink> traceSink
+)
+ : m_servers(servers)
+ , m_traceSink(traceSink)
+{
+}
+
+void ConfigManager::lock()
+{
+ m_mutex.lock();
+}
+
+void ConfigManager::unlock()
+{
+ m_mutex.unlock();
+}
+
+void ConfigManager::updateServers(const std::vector<std::wstring> &servers)
+{
+ XTRACE(L"Updating DNS server list");
+ m_servers = servers;
+}
+
+const std::vector<std::wstring> &ConfigManager::getServers() const
+{
+ return m_servers;
+}
+
+bool ConfigManager::updateConfig(DnsConfig &&config)
+{
+ XTRACE(L"Interface configuration update for interface =", config.interfaceIndex());
+
+ if (false == validUpdate(config))
+ {
+ XTRACE(L"Ignoring interface configuration update");
+ return false;
+ }
+
+ auto iter = m_configs.find(config.id());
+
+ if (m_configs.end() == iter)
+ {
+ XTRACE(L"Creating new interface configuration entry");
+ m_configs.insert(std::make_pair(config.id(), std::move(config)));
+ }
+ else
+ {
+ XTRACE(L"Updating interface configuration entry");
+ iter->second = std::move(config);
+ }
+
+ return true;
+}
+
+bool ConfigManager::processConfigs(std::function<bool(const DnsConfig &)> configSink)
+{
+ for (auto it = m_configs.begin(); it != m_configs.end(); ++it)
+ {
+ if (false == configSink(it->second))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ConfigManager::validUpdate(const DnsConfig &config)
+{
+ auto updatedServers = config.servers();
+
+ if (nullptr == updatedServers)
+ {
+ return true;
+ }
+
+ return false == std::equal(m_servers.begin(), m_servers.end(), updatedServers->begin(), updatedServers->end());
+}
diff --git a/windns/src/windns/configmanager.h b/windns/src/windns/configmanager.h
new file mode 100644
index 0000000000..3760319bbb
--- /dev/null
+++ b/windns/src/windns/configmanager.h
@@ -0,0 +1,65 @@
+#pragma once
+
+#include "dnsconfig.h"
+#include "itracesink.h"
+#include <map>
+#include <string>
+#include <mutex>
+#include <memory>
+#include <functional>
+
+class ConfigManager
+{
+public:
+
+ struct Mutex
+ {
+ Mutex(const Mutex &) = delete;
+ Mutex &operator=(const Mutex &) = delete;
+ Mutex(Mutex &&) = delete;
+ Mutex &operator=(Mutex &&) = delete;
+
+ Mutex(ConfigManager &manager)
+ : m_manager(manager)
+ {
+ m_manager.lock();
+ }
+
+ ~Mutex()
+ {
+ m_manager.unlock();
+ }
+
+ ConfigManager &m_manager;
+ };
+
+ //
+ // "servers" specifies the set of servers used when overriding settings.
+ // This enables filtering out the corresponding event.
+ //
+ ConfigManager
+ (
+ const std::vector<std::wstring> &servers,
+ std::shared_ptr<ITraceSink> traceSink = std::make_shared<NullTraceSink>()
+ );
+
+ void lock();
+ void unlock();
+
+ void updateServers(const std::vector<std::wstring> &servers);
+ const std::vector<std::wstring> &getServers() const;
+
+ bool updateConfig(DnsConfig &&config);
+
+ 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;
+
+ std::shared_ptr<ITraceSink> m_traceSink;
+
+ bool validUpdate(const DnsConfig &config);
+};