diff options
Diffstat (limited to 'windows/windns/src/windns/windns.cpp')
| -rw-r--r-- | windows/windns/src/windns/windns.cpp | 321 |
1 files changed, 0 insertions, 321 deletions
diff --git a/windows/windns/src/windns/windns.cpp b/windows/windns/src/windns/windns.cpp deleted file mode 100644 index f7cc35f27f..0000000000 --- a/windows/windns/src/windns/windns.cpp +++ /dev/null @@ -1,321 +0,0 @@ -#include "stdafx.h" -#include <libcommon/guid.h> -#include <libcommon/string.h> -#include <libcommon/error.h> -#include <libshared/network/interfaceutils.h> -#include <libcommon/logging/ilogsink.h> -#include <libshared/logging/logsinkadapter.h> -#include "windns.h" -#include "confineoperation.h" -#include "netsh.h" -#include <memory> -#include <vector> -#include <string> -#include <sstream> -#include <ws2tcpip.h> -#include <ws2ipdef.h> -#include <winsock2.h> // magic order :-( -#include <iphlpapi.h> // if we don't do this then most of iphlpapi is not actually defined - -bool operator==(const IN_ADDR &lhs, const IN_ADDR &rhs) -{ - return 0 == memcmp(&lhs, &rhs, sizeof(IN_ADDR)); -} - -bool operator==(const IN6_ADDR &lhs, const IN6_ADDR &rhs) -{ - return 0 == memcmp(&lhs, &rhs, sizeof(IN6_ADDR)); -} - -namespace -{ - -std::shared_ptr<common::logging::ILogSink> g_LogSink; -std::shared_ptr<NetSh> g_NetSh; - -std::vector<std::wstring> MakeStringArray(const wchar_t **strings, uint32_t numStrings) -{ - std::vector<std::wstring> v; - - while (numStrings--) - { - v.emplace_back(*strings++); - } - - return v; -} - -uint32_t ConvertInterfaceLuidToIndex(const NET_LUID &luid) -{ - NET_IFINDEX index; - - if (NO_ERROR != ConvertInterfaceLuidToIndex(&luid, &index)) - { - std::wstringstream ss; - - ss << L"Could not resolve index of interface with LUID: 0x" - << std::hex << luid.Value; - - THROW_ERROR(common::string::ToAnsi(ss.str()).c_str()); - } - - return static_cast<uint32_t>(index); -} - -struct AdapterDnsAddresses -{ - std::vector<IN_ADDR> ipv4; - std::vector<IN6_ADDR> ipv6; -}; - -// -// The adapter structure that is returned has two fields for interface index. -// If IPv4 is enabled, 'IfIndex' will be set. Otherwise set to 0. -// If IPv6 is enabled, 'Ipv6IfIndex' will be set. Otherwise set to 0. -// If both IPv4 and IPv6 is enabled, then both fields will be set, and have the same value. -// -AdapterDnsAddresses GetAdapterDnsAddresses(const NET_LUID &adapterLuid) -{ - using shared::network::InterfaceUtils; - - const auto adapters = InterfaceUtils::GetAllAdapters( - AF_UNSPEC, - GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST - ); - - for (const auto adapter : adapters) - { - if (adapterLuid.Value != adapter.raw().Luid.Value) - { - continue; - } - - AdapterDnsAddresses out; - - for (auto server = adapter.raw().FirstDnsServerAddress; nullptr != server; server = server->Next) - { - if (AF_INET == server->Address.lpSockaddr->sa_family) - { - out.ipv4.push_back(((const SOCKADDR_IN*)server->Address.lpSockaddr)->sin_addr); - } - else if (AF_INET6 == server->Address.lpSockaddr->sa_family) - { - out.ipv6.push_back(((const SOCKADDR_IN6_LH*)server->Address.lpSockaddr)->sin6_addr); - } - } - - return out; - } - - std::stringstream ss; - ss << "Could not find interface with LUID: 0x" << std::hex << adapterLuid.Value; - THROW_ERROR(ss.str().c_str()); -} - -AdapterDnsAddresses ConvertAddresses( - const wchar_t **ipv4Servers, - uint32_t numIpv4Servers, - const wchar_t **ipv6Servers, - uint32_t numIpv6Servers -) -{ - AdapterDnsAddresses out; - - if (nullptr != ipv4Servers && 0 != numIpv4Servers) - { - for (uint32_t i = 0; i < numIpv4Servers; ++i) - { - IN_ADDR converted; - - if (1 != InetPtonW(AF_INET, ipv4Servers[i], &converted)) - { - THROW_ERROR("Failed to convert IPv4 address"); - } - - out.ipv4.push_back(converted); - } - } - - if (nullptr != ipv6Servers && 0 != numIpv6Servers) - { - for (uint32_t i = 0; i < numIpv6Servers; ++i) - { - IN6_ADDR converted; - - if (1 != InetPtonW(AF_INET6, ipv6Servers[i], &converted)) - { - THROW_ERROR("Failed to convert IPv6 address"); - } - - out.ipv6.push_back(converted); - } - } - - return out; -} - -bool Equal(const AdapterDnsAddresses &lhs, const AdapterDnsAddresses &rhs) -{ - return lhs.ipv4 == rhs.ipv4 - && lhs.ipv6 == rhs.ipv6; -} - -} // anonymous namespace - -WINDNS_LINKAGE -bool -WINDNS_API -WinDns_Initialize( - MullvadLogSink logSink, - void *logSinkContext -) -{ - if (g_LogSink) - { - return false; - } - - try - { - g_LogSink = std::make_shared<shared::logging::LogSinkAdapter>(logSink, logSinkContext); - - try - { - g_NetSh = std::make_shared<NetSh>(g_LogSink); - } - catch (...) - { - g_LogSink.reset(); - throw; - } - - return true; - } - catch (const std::exception &err) - { - if (nullptr != logSink) - { - const auto msg = std::string("Failed to initialize WinDns: ").append(err.what()); - logSink(MULLVAD_LOG_LEVEL_ERROR, msg.c_str(), logSinkContext); - } - - return false; - } - catch (...) - { - if (nullptr != logSink) - { - const std::string msg("Failed to initialize WinDns: Unspecified error"); - logSink(MULLVAD_LOG_LEVEL_ERROR, msg.c_str(), logSinkContext); - } - - return false; - } -} - -WINDNS_LINKAGE -bool -WINDNS_API -WinDns_Deinitialize( -) -{ - g_NetSh.reset(); - g_LogSink.reset(); - - return true; -} - -WINDNS_LINKAGE -bool -WINDNS_API -WinDns_Set( - const NET_LUID *interfaceLuid, - const wchar_t **ipv4Servers, - uint32_t numIpv4Servers, - const wchar_t **ipv6Servers, - uint32_t numIpv6Servers -) -{ - if (nullptr == g_LogSink) - { - return false; - } - - if (nullptr == interfaceLuid) - { - g_LogSink->error("Invalid argument: interfaceLuid"); - return false; - } - - // - // Check the settings on the adapter. - // If it already has the exact same settings we need, we're done. - // - try - { - const auto activeSettings = GetAdapterDnsAddresses(*interfaceLuid); - const auto wantedSetting = ConvertAddresses(ipv4Servers, numIpv4Servers, ipv6Servers, numIpv6Servers); - - if (Equal(activeSettings, wantedSetting)) - { - std::stringstream ss; - - ss << "DNS settings on adapter with LUID 0x" << std::hex << interfaceLuid->Value << " are up-to-date"; - - g_LogSink->info(ss.str().c_str()); - - return true; - } - } - catch (const std::exception &err) - { - std::stringstream ss; - - ss << "Failed to evaluate DNS settings on adapter with LUID 0x" - << std::hex << interfaceLuid->Value << ": " << err.what(); - - g_LogSink->info(ss.str().c_str()); - } - catch (...) - { - std::stringstream ss; - - ss << "Failed to evaluate DNS settings on adapter with LUID 0x" - << std::hex << interfaceLuid->Value << ": Unspecified failure"; - - g_LogSink->info(ss.str().c_str()); - } - - // - // Apply specified settings. - // - - std::stringstream operation; - operation << "Apply DNS settings on adapter with LUID 0x" - << std::hex << interfaceLuid->Value; - - return ConfineOperation(operation.str().c_str(), g_LogSink, [&]() - { - const auto interfaceIndex = ConvertInterfaceLuidToIndex(*interfaceLuid); - - if (nullptr != ipv4Servers && 0 != numIpv4Servers) - { - g_NetSh->setIpv4StaticDns(interfaceIndex, MakeStringArray(ipv4Servers, numIpv4Servers)); - } - else - { - // This is required to clear any current settings. - g_NetSh->setIpv4DhcpDns(interfaceIndex); - } - - if (nullptr != ipv6Servers && 0 != numIpv6Servers) - { - g_NetSh->setIpv6StaticDns(interfaceIndex, MakeStringArray(ipv6Servers, numIpv6Servers)); - } - else - { - // This is required to clear any current settings. - g_NetSh->setIpv6DhcpDns(interfaceIndex); - } - }); -} |
