summaryrefslogtreecommitdiffstats
path: root/xbmc/network/DNSNameCache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/network/DNSNameCache.cpp')
-rw-r--r--xbmc/network/DNSNameCache.cpp114
1 files changed, 114 insertions, 0 deletions
diff --git a/xbmc/network/DNSNameCache.cpp b/xbmc/network/DNSNameCache.cpp
new file mode 100644
index 0000000..af2ac1a
--- /dev/null
+++ b/xbmc/network/DNSNameCache.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "DNSNameCache.h"
+
+#include "threads/CriticalSection.h"
+#include "utils/StringUtils.h"
+#include "utils/log.h"
+
+#include <mutex>
+
+#if !defined(TARGET_WINDOWS) && defined(HAS_FILESYSTEM_SMB)
+#include "ServiceBroker.h"
+
+#include "platform/posix/filesystem/SMBWSDiscovery.h"
+#endif
+
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <netinet/in.h>
+
+CDNSNameCache g_DNSCache;
+
+CCriticalSection CDNSNameCache::m_critical;
+
+CDNSNameCache::CDNSNameCache(void) = default;
+
+CDNSNameCache::~CDNSNameCache(void) = default;
+
+bool CDNSNameCache::Lookup(const std::string& strHostName, std::string& strIpAddress)
+{
+ if (strHostName.empty() && strIpAddress.empty())
+ return false;
+
+ // first see if this is already an ip address
+ unsigned long address = inet_addr(strHostName.c_str());
+ strIpAddress.clear();
+
+ if (address != INADDR_NONE)
+ {
+ strIpAddress = StringUtils::Format("{}.{}.{}.{}", (address & 0xFF), (address & 0xFF00) >> 8,
+ (address & 0xFF0000) >> 16, (address & 0xFF000000) >> 24);
+ return true;
+ }
+
+ // check if there's a custom entry or if it's already cached
+ if(g_DNSCache.GetCached(strHostName, strIpAddress))
+ return true;
+
+ // perform dns lookup
+ struct hostent *host = gethostbyname(strHostName.c_str());
+ if (host && host->h_addr_list[0])
+ {
+ strIpAddress = StringUtils::Format("{}.{}.{}.{}", (unsigned char)host->h_addr_list[0][0],
+ (unsigned char)host->h_addr_list[0][1],
+ (unsigned char)host->h_addr_list[0][2],
+ (unsigned char)host->h_addr_list[0][3]);
+ g_DNSCache.Add(strHostName, strIpAddress);
+ return true;
+ }
+
+ CLog::Log(LOGERROR, "Unable to lookup host: '{}'", strHostName);
+ return false;
+}
+
+bool CDNSNameCache::GetCached(const std::string& strHostName, std::string& strIpAddress)
+{
+ {
+ std::unique_lock<CCriticalSection> lock(m_critical);
+
+ // loop through all DNSname entries and see if strHostName is cached
+ for (const auto& DNSname : g_DNSCache.m_vecDNSNames)
+ {
+ if (DNSname.m_strHostName == strHostName)
+ {
+ strIpAddress = DNSname.m_strIpAddress;
+ return true;
+ }
+ }
+ }
+
+#if !defined(TARGET_WINDOWS) && defined(HAS_FILESYSTEM_SMB)
+ if (WSDiscovery::CWSDiscoveryPosix::IsInitialized())
+ {
+ WSDiscovery::CWSDiscoveryPosix& WSInstance =
+ dynamic_cast<WSDiscovery::CWSDiscoveryPosix&>(CServiceBroker::GetWSDiscovery());
+ if (WSInstance.GetCached(strHostName, strIpAddress))
+ return true;
+ }
+ else
+ CLog::Log(LOGDEBUG, LOGWSDISCOVERY,
+ "CDNSNameCache::GetCached: CWSDiscoveryPosix not initialized");
+#endif
+
+ // not cached
+ return false;
+}
+
+void CDNSNameCache::Add(const std::string& strHostName, const std::string& strIpAddress)
+{
+ CDNSName dnsName;
+
+ dnsName.m_strHostName = strHostName;
+ dnsName.m_strIpAddress = strIpAddress;
+
+ std::unique_lock<CCriticalSection> lock(m_critical);
+ g_DNSCache.m_vecDNSNames.push_back(dnsName);
+}
+