diff options
| author | Odd Stranne <odd@mullvad.net> | 2019-09-03 22:55:20 +0200 |
|---|---|---|
| committer | Odd Stranne <odd@mullvad.net> | 2019-09-05 10:19:07 +0200 |
| commit | e2ef1227283c252ec5a7190ed9b4bd278405fa9b (patch) | |
| tree | cbfaaf2b21f06b36c09d659d924b05b2bd89ba0a | |
| parent | eb6802418f9c82a2093d0c7027159ef85ab40654 (diff) | |
| download | mullvadvpn-e2ef1227283c252ec5a7190ed9b4bd278405fa9b.tar.xz mullvadvpn-e2ef1227283c252ec5a7190ed9b4bd278405fa9b.zip | |
Remove monitoring logic in DNS code
38 files changed, 89 insertions, 2194 deletions
diff --git a/windows/windns/extras.sln b/windows/windns/extras.sln index 36b98f06c1..ca9347638e 100644 --- a/windows/windns/extras.sln +++ b/windows/windns/extras.sln @@ -15,11 +15,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "windns", "src\windns\windns EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcommon", "..\windows-libraries\src\libcommon\libcommon.vcxproj", "{B52E2D10-A94A-4605-914A-2DCEF6A757EF}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "verifier", "src\extras\verifier\verifier.vcxproj", "{1A035E4B-3C83-4AD0-AB13-D19FB5FC9428}" - ProjectSection(ProjectDependencies) = postProject - {B52E2D10-A94A-4605-914A-2DCEF6A757EF} = {B52E2D10-A94A-4605-914A-2DCEF6A757EF} - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -52,14 +47,6 @@ Global {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Release|x64.Build.0 = Release|x64 {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Release|x86.ActiveCfg = Release|Win32 {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Release|x86.Build.0 = Release|Win32 - {1A035E4B-3C83-4AD0-AB13-D19FB5FC9428}.Debug|x64.ActiveCfg = Debug|x64 - {1A035E4B-3C83-4AD0-AB13-D19FB5FC9428}.Debug|x64.Build.0 = Debug|x64 - {1A035E4B-3C83-4AD0-AB13-D19FB5FC9428}.Debug|x86.ActiveCfg = Debug|Win32 - {1A035E4B-3C83-4AD0-AB13-D19FB5FC9428}.Debug|x86.Build.0 = Debug|Win32 - {1A035E4B-3C83-4AD0-AB13-D19FB5FC9428}.Release|x64.ActiveCfg = Release|x64 - {1A035E4B-3C83-4AD0-AB13-D19FB5FC9428}.Release|x64.Build.0 = Release|x64 - {1A035E4B-3C83-4AD0-AB13-D19FB5FC9428}.Release|x86.ActiveCfg = Release|Win32 - {1A035E4B-3C83-4AD0-AB13-D19FB5FC9428}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/windows/windns/src/extras/loader/loader.cpp b/windows/windns/src/extras/loader/loader.cpp index 5c6603c3dd..b20b4336b0 100644 --- a/windows/windns/src/extras/loader/loader.cpp +++ b/windows/windns/src/extras/loader/loader.cpp @@ -27,86 +27,12 @@ void WINDNS_API LogSink(WinDnsLogCategory category, const char *message, const c } } -void WINDNS_API RecoverySink(const void *recoveryData, uint32_t dataLength, void *context) -{ - std::wcout << L"Updated recovery data was delivered to WINDNS client code" << std::endl; - - auto f = CreateFileW(L"windns_recovery", GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, nullptr); - - if (INVALID_HANDLE_VALUE == f) - { - std::wcout << L"Failed to create recovery file" << std::endl; - return; - } - - if (FALSE == WriteFile(f, recoveryData, dataLength, nullptr, nullptr)) - { - std::wcout << L"Failed to update recovery file" << std::endl; - } - - CloseHandle(f); -} - -void Recover() -{ - auto f = CreateFileW(L"windns_recovery", GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); - - if (INVALID_HANDLE_VALUE == f) - { - std::wcout << L"Failed to open recovery file" << std::endl; - return; - } - - std::vector<uint8_t> data; - - data.resize(GetFileSize(f, nullptr)); - - if (FALSE == ReadFile(f, &data[0], static_cast<DWORD>(data.size()), nullptr, nullptr)) - { - std::wcout << L"Failed to read in recovery data" << std::endl; - CloseHandle(f); - - return; - } - - std::wcout << L"WinDns_Recover: " << std::boolalpha << - WinDns_Recover(&data[0], static_cast<uint32_t>(data.size())) << std::endl; -} - -bool Ask(const std::wstring &question) -{ - std::wcout << question.c_str() << L" Y/N: "; - - auto answer = _getwch(); - - std::wcout << std::endl; - - if ('y' == answer || 'Y' == answer) - { - return true; - } - - return false; -} - -void WaitInput(const std::wstring &message) -{ - std::wcout << message.c_str() << std::endl; - _getwch(); -} - int main() { common::trace::Trace::RegisterSink(new common::trace::ConsoleTraceSink); std::wcout << L"WinDns_Initialize: " << std::boolalpha << WinDns_Initialize(LogSink, nullptr) << std::endl; - if (Ask(L"Perform recovery?")) - { - Recover(); - return 0; - } - const wchar_t *servers[] = { L"8.8.8.8", @@ -119,28 +45,10 @@ int main() L"2001:4860:4860::8844" }; - auto status = WinDns_Set(servers, _countof(servers), v6Servers, _countof(v6Servers), RecoverySink, nullptr); - - std::wcout << L"WinDns_Set: " << std::boolalpha << status << std::endl; - - WaitInput(L"Press a key to abort DNS monitoring + enforcing..."); - - if (Ask(L"Perform WinDns_Reset() before next WinDns_Set()?")) - { - std::wcout << L"WinDns_Reset: " << std::boolalpha << WinDns_Reset() << std::endl; - } - - status = WinDns_Set(servers, _countof(servers), v6Servers, _countof(v6Servers), RecoverySink, nullptr); + auto status = WinDns_Set(L"Wi-Fi", servers, _countof(servers), v6Servers, _countof(v6Servers)); std::wcout << L"WinDns_Set: " << std::boolalpha << status << std::endl; - WaitInput(L"Press a key to abort DNS monitoring + enforcing..."); - - if (Ask(L"Perform WinDns_Reset() before WinDns_Deinitialize()?")) - { - std::wcout << L"WinDns_Reset: " << std::boolalpha << WinDns_Reset() << std::endl; - } - std::wcout << L"WinDns_Deinitialize: " << std::boolalpha << WinDns_Deinitialize() << std::endl; return 0; diff --git a/windows/windns/src/extras/verifier/stdafx.cpp b/windows/windns/src/extras/verifier/stdafx.cpp Binary files differdeleted file mode 100644 index 41d5cbabaa..0000000000 --- a/windows/windns/src/extras/verifier/stdafx.cpp +++ /dev/null diff --git a/windows/windns/src/extras/verifier/stdafx.h b/windows/windns/src/extras/verifier/stdafx.h Binary files differdeleted file mode 100644 index 94d4ed877d..0000000000 --- a/windows/windns/src/extras/verifier/stdafx.h +++ /dev/null diff --git a/windows/windns/src/extras/verifier/targetver.h b/windows/windns/src/extras/verifier/targetver.h Binary files differdeleted file mode 100644 index 567cd346ef..0000000000 --- a/windows/windns/src/extras/verifier/targetver.h +++ /dev/null diff --git a/windows/windns/src/extras/verifier/verifier.cpp b/windows/windns/src/extras/verifier/verifier.cpp deleted file mode 100644 index c7404a7060..0000000000 --- a/windows/windns/src/extras/verifier/verifier.cpp +++ /dev/null @@ -1,163 +0,0 @@ -#include "stdafx.h" - -#include <libcommon/registry/registry.h> - -#include <vector> -#include <string> -#include <iostream> -#include <algorithm> - -// Use source files directly from windns. -#include "../../windns/interfacesnap.h" -#include "../../windns/registrypaths.h" -#include "../../windns/types.h" - -struct InterfaceData -{ - InterfaceData(const std::wstring &_interfaceGuid, InterfaceSnap _snap) - : interfaceGuid(_interfaceGuid) - , snap(_snap) - { - } - - std::wstring interfaceGuid; - InterfaceSnap snap; -}; - -std::vector<std::wstring> DiscoverInterfaces(Protocol protocol) -{ - auto regKey = common::registry::Registry::OpenKey(HKEY_LOCAL_MACHINE, RegistryPaths::InterfaceRoot(protocol)); - - std::vector<std::wstring> interfaces; - - interfaces.reserve(20); - - regKey->enumerateSubKeys([&interfaces](const std::wstring &keyName) - { - interfaces.push_back(keyName); - return true; - }); - - return interfaces; -} - -std::vector<InterfaceData> CreateInterfaceRecords(Protocol protocol, const std::vector<std::wstring> &interfaces) -{ - std::vector<InterfaceData> records; - - records.reserve(interfaces.size()); - - for (const auto &iface : interfaces) - { - records.emplace_back(iface, InterfaceSnap(protocol, iface)); - } - - return records; -} - -void CreateSnapshots(std::vector<InterfaceData> &v4, std::vector<InterfaceData> &v6) -{ - v4 = CreateInterfaceRecords(Protocol::IPv4, DiscoverInterfaces(Protocol::IPv4)); - v6 = CreateInterfaceRecords(Protocol::IPv6, DiscoverInterfaces(Protocol::IPv6)); -} - -void VerifyProtocolSnapshots(const std::vector<InterfaceData> &first, const std::vector<InterfaceData> &second) -{ - for (const auto &firstRecord : first) - { - const auto interfaceGuid = firstRecord.interfaceGuid; - - auto secondRecord = std::find_if(second.begin(), second.end(), [&interfaceGuid](const InterfaceData &candidate) - { - return interfaceGuid == candidate.interfaceGuid; - }); - - if (second.end() == secondRecord) - { - std::wcout << L"Interface " << interfaceGuid << L" has been removed from the system" << std::endl; - continue; - } - - const auto serversBefore = firstRecord.snap.nameServers(); - const auto serversAfter = secondRecord->snap.nameServers(); - - if (serversBefore == serversAfter) - { - continue; - } - - std::wcout << L"Interface " << interfaceGuid << L" has been updated" << std::endl; - std::wcout << L"before:" << std::endl; - - for (const auto &server : serversBefore) - { - std::wcout << L" " << server << std::endl; - } - - std::wcout << L"after:" << std::endl; - - for (const auto &server : serversAfter) - { - std::wcout << L" " << server << std::endl; - } - } -} - -void VerifySnapshots(const std::vector<InterfaceData> &v4, const std::vector<InterfaceData> &v6) -{ - std::vector<InterfaceData> updatedV4, updatedV6; - - CreateSnapshots(updatedV4, updatedV6); - - VerifyProtocolSnapshots(v4, updatedV4); - VerifyProtocolSnapshots(v6, updatedV6); -} - -int main() -{ - std::vector<InterfaceData> v4records, v6records; - - for (;;) - { - std::wcout << L"(T)ake interface settings snapshot" << std::endl - << L"(C)ompare current settings to snapshot" << std::endl - << L"(Q)uit" << std::endl; - - std::wcout << L"?: "; - - auto answer = _getwch(); - - std::wcout << std::endl; - - // - // Branch on selected command. - // - - if ('t' == towlower(answer)) - { - CreateSnapshots(v4records, v6records); - - std::wcout << L"Created new snapshot" << std::endl; - - continue; - } - - if ('c' == towlower(answer)) - { - VerifySnapshots(v4records, v6records); - - std::wcout << L"Comparison completed" << std::endl; - - continue; - } - - if ('q' == towlower(answer)) - { - break; - } - - std::wcout << L"Unrecognized option" << std::endl; - } - - return 0; -} diff --git a/windows/windns/src/extras/verifier/verifier.vcxproj b/windows/windns/src/extras/verifier/verifier.vcxproj deleted file mode 100644 index f0342db79c..0000000000 --- a/windows/windns/src/extras/verifier/verifier.vcxproj +++ /dev/null @@ -1,190 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\..\windns\interfacesnap.cpp" /> - <ClCompile Include="..\..\windns\registrypaths.cpp" /> - <ClCompile Include="stdafx.cpp" /> - <ClCompile Include="verifier.cpp" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="stdafx.h" /> - <ClInclude Include="targetver.h" /> - </ItemGroup> - <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> - <ProjectGuid>{1A035E4B-3C83-4AD0-AB13-D19FB5FC9428}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>verifier</RootNamespace> - <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - <OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir> - <IntDir>$(SolutionDir)bin\temp\$(Platform)-$(Configuration)\$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - <OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir> - <IntDir>$(SolutionDir)bin\temp\$(Platform)-$(Configuration)\$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir> - <IntDir>$(SolutionDir)bin\temp\$(Platform)-$(Configuration)\$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - <OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir> - <IntDir>$(SolutionDir)bin\temp\$(Platform)-$(Configuration)\$(ProjectName)\</IntDir> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>Create</PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <Optimization>Disabled</Optimization> - <SDLCheck>true</SDLCheck> - <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ConformanceMode>true</ConformanceMode> - <AdditionalIncludeDirectories>$(ProjectDir)../../../../windows-libraries/src/</AdditionalIncludeDirectories> - <LanguageStandard>stdcpplatest</LanguageStandard> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>libcommon.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>Create</PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <Optimization>Disabled</Optimization> - <SDLCheck>true</SDLCheck> - <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ConformanceMode>true</ConformanceMode> - <AdditionalIncludeDirectories>$(ProjectDir)../../../../windows-libraries/src/</AdditionalIncludeDirectories> - <LanguageStandard>stdcpplatest</LanguageStandard> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>libcommon.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>Create</PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <SDLCheck>true</SDLCheck> - <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ConformanceMode>true</ConformanceMode> - <AdditionalIncludeDirectories>$(ProjectDir)../../../../windows-libraries/src/</AdditionalIncludeDirectories> - <LanguageStandard>stdcpplatest</LanguageStandard> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>libcommon.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>Create</PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <SDLCheck>true</SDLCheck> - <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ConformanceMode>true</ConformanceMode> - <AdditionalIncludeDirectories>$(ProjectDir)../../../../windows-libraries/src/</AdditionalIncludeDirectories> - <LanguageStandard>stdcpplatest</LanguageStandard> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>libcommon.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories> - </Link> - </ItemDefinitionGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/windows/windns/src/extras/verifier/verifier.vcxproj.filters b/windows/windns/src/extras/verifier/verifier.vcxproj.filters deleted file mode 100644 index f5d6b7adfc..0000000000 --- a/windows/windns/src/extras/verifier/verifier.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <ClCompile Include="stdafx.cpp" /> - <ClCompile Include="verifier.cpp" /> - <ClCompile Include="..\..\windns\interfacesnap.cpp"> - <Filter>borrowed</Filter> - </ClCompile> - <ClCompile Include="..\..\windns\registrypaths.cpp"> - <Filter>borrowed</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ClInclude Include="stdafx.h" /> - <ClInclude Include="targetver.h" /> - </ItemGroup> - <ItemGroup> - <Filter Include="borrowed"> - <UniqueIdentifier>{2950faf7-32b2-4f62-9470-974c71724d40}</UniqueIdentifier> - </Filter> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/windows/windns/src/windns/clientsinkinfo.h b/windows/windns/src/windns/clientsinkinfo.h deleted file mode 100644 index 39f602eeac..0000000000 --- a/windows/windns/src/windns/clientsinkinfo.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "windns.h" - -struct LogSinkInfo -{ - WinDnsLogSink sink; - void *context; -}; - -struct RecoverySinkInfo -{ - WinDnsRecoverySink sink; - void *context; -}; diff --git a/windows/windns/src/windns/dnsagent.cpp b/windows/windns/src/windns/dnsagent.cpp deleted file mode 100644 index 04bdcdb47d..0000000000 --- a/windows/windns/src/windns/dnsagent.cpp +++ /dev/null @@ -1,481 +0,0 @@ -#include "stdafx.h" -#include "dnsagent.h" -#include "registrypaths.h" -#include "netsh.h" -#include "confineoperation.h" -#include <libcommon/trace/xtrace.h> -#include <libcommon/error.h> -#include <libcommon/string.h> -#include <process.h> -#include <algorithm> - -DnsAgent::DnsAgent(Protocol protocol, INameServerSource *nameServerSource, IRecoverySink *recoverySink, ILogSink *logSink) - : m_protocol(protocol) - , m_nameServerSource(nameServerSource) - , m_recoverySink(recoverySink) - , m_logSink(logSink) - , m_thread(nullptr) - , m_shutdownEvent(nullptr) -{ - constructNameServerUpdateEvent(); - - try - { - constructRootMonitor(); - - if (false == startTrackingInterfaces(discoverInterfaces())) - { - throw std::runtime_error("Could not complete initial settings update on interfaces"); - } - - updateRecoveryData(); - - constructThread(); - } - catch (...) - { - if (nullptr != m_shutdownEvent) - { - CloseHandle(m_shutdownEvent); - } - - m_nameServerSource->unsubscribe(m_serverSourceEvent); - CloseHandle(m_serverSourceEvent); - - throw; - } - -} - -DnsAgent::~DnsAgent() -{ - SetEvent(m_shutdownEvent); - WaitForSingleObject(m_thread, INFINITE); - - CloseHandle(m_shutdownEvent); - CloseHandle(m_thread); - - m_nameServerSource->unsubscribe(m_serverSourceEvent); - CloseHandle(m_serverSourceEvent); -} - -void DnsAgent::constructNameServerUpdateEvent() -{ - m_serverSourceEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr); - - THROW_GLE_IF(nullptr, m_serverSourceEvent, "Create name server subscription event"); - - m_nameServerSource->subscribe(m_serverSourceEvent); -} - -void DnsAgent::constructRootMonitor() -{ - m_rootMonitor = common::registry::Registry::MonitorKey(HKEY_LOCAL_MACHINE, - RegistryPaths::InterfaceRoot(m_protocol), { common::registry::RegistryEventFlag::SubkeyChange }); -} - -void DnsAgent::constructThread() -{ - m_shutdownEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr); - - THROW_GLE_IF(nullptr, m_shutdownEvent, "Create shutdown event"); - - auto rawThreadHandle = _beginthreadex(nullptr, 0, &DnsAgent::ThreadEntry, this, 0, nullptr); - - if (0 == rawThreadHandle) - { - throw std::runtime_error("Could not create monitoring thread"); - } - - m_thread = reinterpret_cast<HANDLE>(rawThreadHandle); -} - -//static -unsigned __stdcall DnsAgent::ThreadEntry(void *parameters) -{ - try - { - reinterpret_cast<DnsAgent *>(parameters)->thread(); - } - catch (std::exception &err) - { - const char *what = err.what(); - - reinterpret_cast<DnsAgent *>(parameters)->m_logSink->error - ( - "Critical error in monitoring thread", &what, 1 - ); - } - catch (...) - { - reinterpret_cast<DnsAgent *>(parameters)->m_logSink->error - ( - "Unspecified critical error in monitoring thread" - ); - } - - return 0; -} - -void DnsAgent::thread() -{ - for (;;) - { - std::vector<HANDLE> waitHandles; - - // - // Reserve enough space in the array to hold: - // - // Shutdown event handle - // Name servers source update event - // Monitor handle for interfaces root key - // Monitor handles for all interfaces - // - waitHandles.reserve(3 + m_trackedInterfaces.size()); - - const size_t shutdownEventIndex = 0; - const size_t serverSourceEventIndex = 1; - const size_t rootKeyEventIndex = 2; - const size_t firstInterfaceIndex = 3; - - waitHandles.push_back(m_shutdownEvent); - waitHandles.push_back(m_serverSourceEvent); - waitHandles.push_back(m_rootMonitor->queueSingleEvent()); - - for (auto &interfaceData : m_trackedInterfaces) - { - waitHandles.push_back(interfaceData.monitor->queueSingleEvent()); - } - - // - // Wait for one or more events to become signalled. - // - - const auto status = WaitForMultipleObjects(static_cast<DWORD>(waitHandles.size()), &waitHandles[0], FALSE, INFINITE); - - if (WAIT_FAILED == status) - { - const auto error = common::error::FormatWindowsErrorPlain(GetLastError()); - const auto message = std::string("Failed to wait on events. Restarting wait in 1 minute. Error: ").append(error); - - m_logSink->error(message.c_str()); - - if (WAIT_OBJECT_0 == WaitForSingleObject(m_shutdownEvent, 1000 * 60)) - { - break; - } - - continue; - } - - const size_t firstSignalledIndex = status - WAIT_OBJECT_0; - - if (firstSignalledIndex == shutdownEventIndex) - { - break; - } - - if (firstSignalledIndex >= firstInterfaceIndex) - { - XTRACE(L"Interface event is signalled"); - - const auto result = processInterfaceEvent(&waitHandles[firstInterfaceIndex], - firstSignalledIndex - firstInterfaceIndex); - - if (ProcessingResult::TrackingUpdated == result) - { - updateRecoveryData(); - } - - continue; - } - - // - // We can't easily tell which events have been signalled. - // - - const auto interfaceResult = processInterfaceEvent(&waitHandles[firstInterfaceIndex], 0); - auto rootResult = ProcessingResult::Nop; - - if (WAIT_OBJECT_0 == WaitForSingleObject(waitHandles[rootKeyEventIndex], 0)) - { - XTRACE(L"Interfaces root key event is signalled"); - - rootResult = processRootKeyEvent(); - } - - if (ProcessingResult::TrackingUpdated == interfaceResult - || ProcessingResult::TrackingUpdated == rootResult) - { - updateRecoveryData(); - } - - if (WAIT_OBJECT_0 == WaitForSingleObject(waitHandles[serverSourceEventIndex], 0)) - { - XTRACE(L"Server source update event is signalled"); - ResetEvent(m_serverSourceEvent); - - processServerSourceEvent(); - } - } - - XTRACE(L"Thread is exiting"); -} - -void DnsAgent::processServerSourceEvent() -{ - // - // Check actual interface settings to determine which interfaces - // need to have their settings overridden. - // - // Do NOT update 'preservedSettings' on the tracking entries because - // it would overwrite legitimate settings with the previously enforced settings. - // - - std::vector<std::wstring> interfaces; - interfaces.reserve(m_trackedInterfaces.size()); - - std::transform(m_trackedInterfaces.begin(), m_trackedInterfaces.end(), std::back_inserter(interfaces), [](const InterfaceData &interfaceData) - { - return interfaceData.interfaceGuid; - }); - - const auto enforcedServers = m_nameServerSource->getNameServers(m_protocol); - - for (const auto &iface : interfaces) - { - const auto literalOperation = std::wstring(L"Verifying settings on interface ").append(iface); - - XTRACE(literalOperation); - - ConfineOperation(common::string::ToAnsi(literalOperation).c_str(), m_logSink, [&]() - { - InterfaceSnap snap(m_protocol, iface); - - if (snap.needsOverriding(enforcedServers)) - { - setNameServers(iface, enforcedServers); - } - }); - } -} - -DnsAgent::ProcessingResult DnsAgent::processRootKeyEvent() -{ - ProcessingResult result = ProcessingResult::Nop; - - std::vector<std::wstring> oldInterfaces; - oldInterfaces.reserve(m_trackedInterfaces.size()); - - std::transform(m_trackedInterfaces.begin(), m_trackedInterfaces.end(), std::back_inserter(oldInterfaces), [](const InterfaceData &interfaceData) - { - return interfaceData.interfaceGuid; - }); - - auto currentInterfaces = discoverInterfaces(); - - std::sort(oldInterfaces.begin(), oldInterfaces.end()); - std::sort(currentInterfaces.begin(), currentInterfaces.end()); - - // - // Stop tracking interfaces that have been removed. - // - - std::vector<std::wstring> removedInterfaces; - - std::set_difference(oldInterfaces.begin(), oldInterfaces.end(), currentInterfaces.begin(), currentInterfaces.end(), - std::back_inserter(removedInterfaces)); - - if (false == removedInterfaces.empty()) - { - result = ProcessingResult::TrackingUpdated; - stopTrackingInterfaces(removedInterfaces); - } - - // - // Start tracking new interfaces. - // - - std::vector<std::wstring> newInterfaces; - - std::set_difference(currentInterfaces.begin(), currentInterfaces.end(), oldInterfaces.begin(), oldInterfaces.end(), - std::back_inserter(newInterfaces)); - - if (false == newInterfaces.empty()) - { - result = ProcessingResult::TrackingUpdated; - startTrackingInterfaces(newInterfaces); - } - - return result; -} - -DnsAgent::ProcessingResult DnsAgent::processInterfaceEvent(const HANDLE *interfaceEvents, size_t startIndex) -{ - ProcessingResult result = ProcessingResult::Nop; - - // - // 'interfaceEvents' runs in parallel with 'm_trackedInterfaces'. - // - - const auto enforcedNameServers = m_nameServerSource->getNameServers(m_protocol); - - for (size_t i = startIndex; i < m_trackedInterfaces.size(); ++i) - { - if (WAIT_TIMEOUT == WaitForSingleObject(interfaceEvents[i], 0)) - { - continue; - } - - auto &iface = m_trackedInterfaces[i]; - - const auto literalOperation = std::wstring(L"Processing event for interface ").append(iface.interfaceGuid); - - XTRACE(literalOperation); - - ConfineOperation(common::string::ToAnsi(literalOperation).c_str(), m_logSink, [&]() - { - InterfaceSnap updatedSnap(m_protocol, iface.interfaceGuid); - - if ((iface.preservedSettings.internalInterface() && updatedSnap.internalInterface()) - || updatedSnap.nameServers() == enforcedNameServers) - { - return; - } - - const auto shouldOverride = updatedSnap.needsOverriding(enforcedNameServers); - - result = ProcessingResult::TrackingUpdated; - iface.preservedSettings = std::move(updatedSnap); - - if (shouldOverride) - { - setNameServers(iface.interfaceGuid, enforcedNameServers); - } - }); - } - - return result; -} - -std::vector<std::wstring> DnsAgent::discoverInterfaces() -{ - auto regKey = common::registry::Registry::OpenKey(HKEY_LOCAL_MACHINE, RegistryPaths::InterfaceRoot(m_protocol)); - - std::vector<std::wstring> interfaces; - - interfaces.reserve(20); - - regKey->enumerateSubKeys([&interfaces](const std::wstring &keyName) - { - interfaces.push_back(keyName); - return true; - }); - - return interfaces; -} - -void DnsAgent::setNameServers(const std::wstring &interfaceGuid, const std::vector<std::wstring> &enforcedServers) -{ - XTRACE(L"Overriding name servers for interface ", interfaceGuid); - - uint32_t interfaceIndex = 0; - - try - { - interfaceIndex = NetSh::ConvertInterfaceGuidToIndex(interfaceGuid); - } - catch (...) - { - // - // The interface cannot be linked to a virtual or physical adapter. - // - - XTRACE(L"Ignoring floating interface ", interfaceGuid); - return; - } - - if (Protocol::IPv4 == m_protocol) - { - NetSh::Instance().SetIpv4StaticDns(interfaceIndex, enforcedServers); - } - else - { - NetSh::Instance().SetIpv6StaticDns(interfaceIndex, enforcedServers); - } -} - -bool DnsAgent::startTrackingInterfaces(const std::vector<std::wstring> &interfaces) -{ - const auto enforcedServers = m_nameServerSource->getNameServers(m_protocol); - - bool successful = true; - - for (const auto &iface : interfaces) - { - const auto literalOperation = std::wstring(L"Start tracking interface ").append(iface); - - XTRACE(literalOperation); - - successful &= ConfineOperation(common::string::ToAnsi(literalOperation).c_str(), m_logSink, [&]() - { - InterfaceSnap snap(m_protocol, iface); - - const auto shouldOverride = snap.needsOverriding(enforcedServers); - - // - // Create a tracking record. - // - - m_trackedInterfaces.emplace_back(iface, std::move(snap), - std::make_unique<InterfaceMonitor>(m_protocol, iface)); - - // - // Override configured name servers, as necessary. - // - - if (shouldOverride) - { - setNameServers(iface, enforcedServers); - } - }); - } - - return successful; -} - -void DnsAgent::stopTrackingInterfaces(const std::vector<std::wstring> &interfaces) -{ - for (const auto &interfaceGuid : interfaces) - { - auto iter = std::find_if(m_trackedInterfaces.begin(), m_trackedInterfaces.end(), [&interfaceGuid](const InterfaceData &candidate) - { - return candidate.interfaceGuid == interfaceGuid; - }); - - if (m_trackedInterfaces.end() == iter) - { - m_logSink->error("Request to stop tracking non-tracked interface, ignoring."); - - continue; - } - - XTRACE(L"Cancel tracking of interface ", interfaceGuid); - - m_trackedInterfaces.erase(iter); - } -} - -void DnsAgent::updateRecoveryData() -{ - std::vector<InterfaceSnap> snaps; - - snaps.reserve(m_trackedInterfaces.size()); - - std::transform(m_trackedInterfaces.begin(), m_trackedInterfaces.end(), std::back_inserter(snaps), [](const InterfaceData &interfaceData) - { - return interfaceData.preservedSettings; - }); - - m_recoverySink->preserveSnaps(m_protocol, snaps); -} diff --git a/windows/windns/src/windns/dnsagent.h b/windows/windns/src/windns/dnsagent.h deleted file mode 100644 index a45cf75f00..0000000000 --- a/windows/windns/src/windns/dnsagent.h +++ /dev/null @@ -1,83 +0,0 @@ -#pragma once - -#include "interfacesnap.h" -#include "interfacemonitor.h" -#include "types.h" -#include "inameserversource.h" -#include "irecoverysink.h" -#include "ilogsink.h" -#include <libcommon/registry/registry.h> -#include <string> -#include <vector> -#include <memory> -#include <windows.h> - -// -// DnsAgent: -// Monitor interfaces and enforce name server settings. -// -class DnsAgent -{ -public: - - DnsAgent(Protocol protocol, INameServerSource *nameServerSource, IRecoverySink *recoverySink, ILogSink *logSink); - ~DnsAgent(); - -private: - - Protocol m_protocol; - INameServerSource *m_nameServerSource; - IRecoverySink *m_recoverySink; - ILogSink *m_logSink; - - // - // InterfaceData: - // Tracking entry for a network interface. - // - struct InterfaceData - { - InterfaceData(const std::wstring &interfaceGuid_, const InterfaceSnap &snap_, std::unique_ptr<InterfaceMonitor> &&monitor_) - : interfaceGuid(interfaceGuid_), preservedSettings(snap_), monitor(std::move(monitor_)) - { - } - - std::wstring interfaceGuid; - InterfaceSnap preservedSettings; - std::unique_ptr<InterfaceMonitor> monitor; - }; - - std::vector<InterfaceData> m_trackedInterfaces; - - std::unique_ptr<common::registry::RegistryMonitor> m_rootMonitor; - - HANDLE m_serverSourceEvent; - HANDLE m_thread; - HANDLE m_shutdownEvent; - - void constructNameServerUpdateEvent(); - void constructRootMonitor(); - void constructThread(); - - static unsigned __stdcall ThreadEntry(void *); - void thread(); - - void processServerSourceEvent(); - - enum class ProcessingResult - { - TrackingUpdated, - Nop - }; - - ProcessingResult processRootKeyEvent(); - ProcessingResult processInterfaceEvent(const HANDLE *interfaceEvents, size_t startIndex); - - std::vector<std::wstring> discoverInterfaces(); - - void setNameServers(const std::wstring &interfaceGuid, const std::vector<std::wstring> &enforcedServers); - - bool startTrackingInterfaces(const std::vector<std::wstring> &interfaces); - void stopTrackingInterfaces(const std::vector<std::wstring> &interfaces); - - void updateRecoveryData(); -}; diff --git a/windows/windns/src/windns/ilogsink.h b/windows/windns/src/windns/ilogsink.h index dec1584ca3..0d39b172b2 100644 --- a/windows/windns/src/windns/ilogsink.h +++ b/windows/windns/src/windns/ilogsink.h @@ -1,7 +1,14 @@ #pragma once +#include "windns.h" #include <cstdint> +struct LogSinkInfo +{ + WinDnsLogSink sink; + void* context; +}; + struct ILogSink { virtual ~ILogSink() = 0 diff --git a/windows/windns/src/windns/inameserversource.h b/windows/windns/src/windns/inameserversource.h deleted file mode 100644 index f97209ce7d..0000000000 --- a/windows/windns/src/windns/inameserversource.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "types.h" -#include <vector> -#include <string> - -// -// Provide the array of name servers that we enforce on all adapters. -// -struct INameServerSource -{ - virtual ~INameServerSource() = 0 - { - } - - virtual std::vector<std::wstring> getNameServers(Protocol protocol) const = 0; - - // - // Get notified if the servers array is updated. - // - virtual void subscribe(HANDLE eventHandle) = 0; - virtual void unsubscribe(HANDLE eventHandle) = 0; -}; diff --git a/windows/windns/src/windns/interfacemonitor.cpp b/windows/windns/src/windns/interfacemonitor.cpp deleted file mode 100644 index 322bb69e57..0000000000 --- a/windows/windns/src/windns/interfacemonitor.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "stdafx.h" -#include "interfacemonitor.h" -#include "registrypaths.h" - -using namespace common::registry; - -InterfaceMonitor::InterfaceMonitor(Protocol protocol, const std::wstring &interfaceGuid) - : m_protocol(protocol) - , m_interfaceGuid(interfaceGuid) -{ - const auto interfacePath = RegistryPaths::InterfaceKey(interfaceGuid, protocol); - - m_monitor = Registry::MonitorKey(HKEY_LOCAL_MACHINE, interfacePath, { RegistryEventFlag::ValueChange }); -} - -HANDLE InterfaceMonitor::queueSingleEvent() -{ - return m_monitor->queueSingleEvent(); -} - -const std::wstring &InterfaceMonitor::interfaceGuid() const -{ - return m_interfaceGuid; -} diff --git a/windows/windns/src/windns/interfacemonitor.h b/windows/windns/src/windns/interfacemonitor.h deleted file mode 100644 index f40c88dab6..0000000000 --- a/windows/windns/src/windns/interfacemonitor.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "types.h" -#include <libcommon/registry/registry.h> -#include <string> -#include <memory> -#include <windows.h> - -class InterfaceMonitor -{ -public: - - explicit InterfaceMonitor(Protocol protocol, const std::wstring &interfaceGuid); - - // - // The event becomes signalled if: - // 1. A value change occurs. - // 2. The monitored interface's registry key is deleted. - // - HANDLE queueSingleEvent(); - - const std::wstring &interfaceGuid() const; - -private: - - Protocol m_protocol; - std::wstring m_interfaceGuid; - - std::unique_ptr<common::registry::RegistryMonitor> m_monitor; -}; diff --git a/windows/windns/src/windns/interfacesnap.cpp b/windows/windns/src/windns/interfacesnap.cpp deleted file mode 100644 index 1840776ed3..0000000000 --- a/windows/windns/src/windns/interfacesnap.cpp +++ /dev/null @@ -1,149 +0,0 @@ -#include "stdafx.h" -#include "interfacesnap.h" -#include "registrypaths.h" -#include <libcommon/registry/registry.h> -#include <libcommon/string.h> -#include <cstdint> - -using namespace common::registry; - -namespace -{ - -enum class NameServerType -{ - Static, - Dhcp -}; - -std::vector<std::wstring> GetNameServers(const std::wstring &interfaceGuid, - Protocol protocol, NameServerType nameServerType) -{ - const auto interfacePath = RegistryPaths::InterfaceKey(interfaceGuid, protocol); - - const auto regKey = Registry::OpenKey(HKEY_LOCAL_MACHINE, interfacePath); - - std::wstring nameservers; - - try - { - // - // This particular value is a string array packed into a string data type. - // REG_MULTI_SZ would have been the correct type to use, but there - // are probably historical reasons for the value type currently being used. - // - nameservers = regKey->readString(NameServerType::Static == nameServerType ? L"NameServer" : L"DhcpNameServer"); - } - catch (...) - { - } - - if (nameservers.empty()) - { - return std::vector<std::wstring>(); - } - - return common::string::Tokenize(nameservers, L","); -} - -bool GetDhcpEnabled(const std::wstring &interfaceGuid, Protocol protocol) -{ - const auto interfacePath = RegistryPaths::InterfaceKey(interfaceGuid, protocol); - - const auto regKey = Registry::OpenKey(HKEY_LOCAL_MACHINE, interfacePath); - - bool enabled = false; - - try - { - const auto flag = regKey->readUint32(L"EnableDHCP"); - - enabled = (1 == flag); - } - catch (...) - { - } - - return enabled; -} - -} // anonymous namespace - -InterfaceSnap::InterfaceSnap(Protocol protocol, const std::wstring &interfaceGuid) - : m_protocol(protocol) - , m_interfaceGuid(interfaceGuid) -{ - m_configuredForDhcp = GetDhcpEnabled(m_interfaceGuid, m_protocol); - - // Static name servers are configured by the user. - m_staticNameServers = GetNameServers(m_interfaceGuid, m_protocol, NameServerType::Static); - - // DHCP name servers are the servers most recently supplied by DHCP. - // An adapter can be configured for DHCP and static name servers at the same time. - // Static name servers always have precedence. - //m_dhcpNameServers = GetNameServers(m_interfaceGuid, m_protocol, NameServerType::Dhcp); -} - -InterfaceSnap::InterfaceSnap(common::serialization::Deserializer &deserializer) -{ - common::serialization::Deserializer &d = deserializer; - - d >> (uint8_t &)m_protocol; - - if (m_protocol != Protocol::IPv4 - && m_protocol != Protocol::IPv6) - { - throw std::runtime_error("Serialized data for 'InterfaceSnap' instance is invalid (protocol)"); - } - - d >> m_interfaceGuid; - d >> (uint8_t &)m_configuredForDhcp; - d >> m_staticNameServers; -} - -void InterfaceSnap::serialize(common::serialization::Serializer &serializer) const -{ - common::serialization::Serializer &s = serializer; - - s << (uint8_t &)m_protocol; - s << m_interfaceGuid; - s << (uint8_t &)m_configuredForDhcp; - s << m_staticNameServers; -} - -bool InterfaceSnap::needsOverriding(const std::vector<std::wstring> &enforcedServers) const -{ - if (internalInterface()) - { - return false; - } - - // - // The interface has static DNS, or - // The interface has DNS provided by the DHCP server, or - // The interface *will get* DNS provided to it by the DHCP server - // - - // - // It's not enough that m_staticNameServers has the same elements. - // The order defines primary and secondary name server and has to match. - // - - return m_staticNameServers != enforcedServers; -} - -const std::wstring &InterfaceSnap::interfaceGuid() const -{ - return m_interfaceGuid; -} - -const std::vector<std::wstring> &InterfaceSnap::nameServers() const -{ - return m_staticNameServers; -} - -bool InterfaceSnap::internalInterface() const -{ - return false == m_configuredForDhcp - && m_staticNameServers.empty(); -} diff --git a/windows/windns/src/windns/interfacesnap.h b/windows/windns/src/windns/interfacesnap.h deleted file mode 100644 index 5159f581eb..0000000000 --- a/windows/windns/src/windns/interfacesnap.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "types.h" -#include <libcommon/serialization/serializer.h> -#include <libcommon/serialization/deserializer.h> -#include <string> -#include <vector> - -class InterfaceSnap -{ -public: - - explicit InterfaceSnap(Protocol protocol, const std::wstring &interfaceGuid); - - explicit InterfaceSnap(common::serialization::Deserializer &deserializer); - void serialize(common::serialization::Serializer &serializer) const; - - bool needsOverriding(const std::vector<std::wstring> &enforcedServers) const; - - const std::wstring &interfaceGuid() const; - - const std::vector<std::wstring> &nameServers() const; - - bool internalInterface() const; - -private: - - Protocol m_protocol; - std::wstring m_interfaceGuid; - - bool m_configuredForDhcp; - std::vector<std::wstring> m_staticNameServers; -}; diff --git a/windows/windns/src/windns/irecoverysink.h b/windows/windns/src/windns/irecoverysink.h deleted file mode 100644 index 8251625053..0000000000 --- a/windows/windns/src/windns/irecoverysink.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "types.h" -#include "interfacesnap.h" -#include <vector> - -struct IRecoverySink -{ - virtual ~IRecoverySink() = 0 - { - } - - virtual void preserveSnaps(Protocol protocol, const std::vector<InterfaceSnap> &snaps) = 0; -}; diff --git a/windows/windns/src/windns/logsink.h b/windows/windns/src/windns/logsink.h index 396320a0a8..236c8e3242 100644 --- a/windows/windns/src/windns/logsink.h +++ b/windows/windns/src/windns/logsink.h @@ -1,6 +1,5 @@ #pragma once -#include "clientsinkinfo.h" #include "ilogsink.h" #include <mutex> diff --git a/windows/windns/src/windns/nameserversource.cpp b/windows/windns/src/windns/nameserversource.cpp deleted file mode 100644 index b574266efb..0000000000 --- a/windows/windns/src/windns/nameserversource.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "stdafx.h" -#include "nameserversource.h" - -NameServerSource::NameServerSource(const std::vector<std::wstring> &ipv4NameServers, - const std::vector<std::wstring> &ipv6NameServers) - : m_ipv4NameServers(ipv4NameServers) - , m_ipv6NameServers(ipv6NameServers) -{ -} - -void NameServerSource::setNameServers(Protocol protocol, const std::vector<std::wstring> &nameServers) -{ - { - std::scoped_lock<std::mutex> lock(m_nameServersMutex); - - if (Protocol::IPv4 == protocol) - { - m_ipv4NameServers = nameServers; - } - else - { - m_ipv6NameServers = nameServers; - } - } - - // - // Notify all subscribers. - // - - std::scoped_lock<std::mutex> lock(m_subscriptionMutex); - - for (HANDLE eventHandle : m_subscriptions) - { - SetEvent(eventHandle); - } -} - -std::vector<std::wstring> NameServerSource::getNameServers(Protocol protocol) const -{ - std::vector<std::wstring> copy; - - std::scoped_lock<std::mutex> lock(m_nameServersMutex); - - if (Protocol::IPv4 == protocol) - { - copy = m_ipv4NameServers; - } - else - { - copy = m_ipv6NameServers; - } - - return copy; -} - -void NameServerSource::subscribe(HANDLE eventHandle) -{ - ResetEvent(eventHandle); - - std::scoped_lock<std::mutex> lock(m_subscriptionMutex); - - m_subscriptions.push_back(eventHandle); -} - -void NameServerSource::unsubscribe(HANDLE eventHandle) -{ - std::scoped_lock<std::mutex> lock(m_subscriptionMutex); - - auto it = std::find(m_subscriptions.begin(), m_subscriptions.end(), eventHandle); - - if (m_subscriptions.end() == it) - { - return; - } - - m_subscriptions.erase(it); -} diff --git a/windows/windns/src/windns/nameserversource.h b/windows/windns/src/windns/nameserversource.h deleted file mode 100644 index 7d46fcf264..0000000000 --- a/windows/windns/src/windns/nameserversource.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "inameserversource.h" -#include <mutex> - -class NameServerSource : public INameServerSource -{ -public: - - NameServerSource(const std::vector<std::wstring> &ipv4NameServers, - const std::vector<std::wstring> &ipv6NameServers); - - void setNameServers(Protocol protocol, const std::vector<std::wstring> &nameServers); - - std::vector<std::wstring> getNameServers(Protocol protocol) const override; - - void subscribe(HANDLE eventHandle) override; - void unsubscribe(HANDLE eventHandle) override; - -private: - - mutable std::mutex m_nameServersMutex; - - std::vector<std::wstring> m_ipv4NameServers; - std::vector<std::wstring> m_ipv6NameServers; - - std::mutex m_subscriptionMutex; - std::list<HANDLE> m_subscriptions; -}; diff --git a/windows/windns/src/windns/netsh.cpp b/windows/windns/src/windns/netsh.cpp index 1b703bcd66..3214c72abe 100644 --- a/windows/windns/src/windns/netsh.cpp +++ b/windows/windns/src/windns/netsh.cpp @@ -11,8 +11,6 @@ namespace { -NetSh *g_Instance = nullptr; - std::vector<std::string> BlockToRows(const std::string &textBlock) { // @@ -62,34 +60,14 @@ __declspec(noreturn) void ThrowWithDetails(std::string &&error, common::Applicat } // anonymous namespace -//static -void NetSh::Construct(ILogSink *logSink) -{ - if (nullptr != g_Instance) - { - throw std::runtime_error("NetSh is already constructed"); - } - - if (nullptr == logSink) - { - throw std::runtime_error("Invalid logger sink"); - } - - g_Instance = new NetSh(logSink); -} - -//static -NetSh &NetSh::Instance() +NetSh::NetSh(std::shared_ptr<ILogSink> logSink) + : m_logSink(logSink) { - if (nullptr == g_Instance) - { - throw std::runtime_error("NetSh is being referenced prior to being constructed"); - } - - return *g_Instance; + const auto system32 = common::fs::GetKnownFolderPath(FOLDERID_System, 0, nullptr); + m_netShPath = std::experimental::filesystem::path(system32).append(L"netsh.exe"); } -void NetSh::SetIpv4StaticDns(uint32_t interfaceIndex, +void NetSh::setIpv4StaticDns(uint32_t interfaceIndex, const std::vector<std::wstring> &nameServers, uint32_t timeout) { // @@ -117,7 +95,7 @@ void NetSh::SetIpv4StaticDns(uint32_t interfaceIndex, auto netsh = common::ApplicationRunner::StartWithoutConsole(m_netShPath, ss.str()); - ValidateShellOut(*netsh, timeout); + validateShellOut(*netsh, timeout); } // @@ -138,11 +116,11 @@ void NetSh::SetIpv4StaticDns(uint32_t interfaceIndex, auto netsh = common::ApplicationRunner::StartWithoutConsole(m_netShPath, ss.str()); - ValidateShellOut(*netsh, timeout); + validateShellOut(*netsh, timeout); } } -void NetSh::SetIpv4DhcpDns(uint32_t interfaceIndex, uint32_t timeout) +void NetSh::setIpv4DhcpDns(uint32_t interfaceIndex, uint32_t timeout) { // // netsh interface ipv4 set dnsservers name="Ethernet 2" source=dhcp @@ -158,10 +136,10 @@ void NetSh::SetIpv4DhcpDns(uint32_t interfaceIndex, uint32_t timeout) auto netsh = common::ApplicationRunner::StartWithoutConsole(m_netShPath, ss.str()); - ValidateShellOut(*netsh, timeout); + validateShellOut(*netsh, timeout); } -void NetSh::SetIpv6StaticDns(uint32_t interfaceIndex, +void NetSh::setIpv6StaticDns(uint32_t interfaceIndex, const std::vector<std::wstring> &nameServers, uint32_t timeout) { // @@ -189,7 +167,7 @@ void NetSh::SetIpv6StaticDns(uint32_t interfaceIndex, auto netsh = common::ApplicationRunner::StartWithoutConsole(m_netShPath, ss.str()); - ValidateShellOut(*netsh, timeout); + validateShellOut(*netsh, timeout); } // @@ -210,11 +188,11 @@ void NetSh::SetIpv6StaticDns(uint32_t interfaceIndex, auto netsh = common::ApplicationRunner::StartWithoutConsole(m_netShPath, ss.str()); - ValidateShellOut(*netsh, timeout); + validateShellOut(*netsh, timeout); } } -void NetSh::SetIpv6DhcpDns(uint32_t interfaceIndex, uint32_t timeout) +void NetSh::setIpv6DhcpDns(uint32_t interfaceIndex, uint32_t timeout) { // // netsh interface ipv6 set dnsservers name="Ethernet 2" source=dhcp @@ -230,35 +208,10 @@ void NetSh::SetIpv6DhcpDns(uint32_t interfaceIndex, uint32_t timeout) auto netsh = common::ApplicationRunner::StartWithoutConsole(m_netShPath, ss.str()); - ValidateShellOut(*netsh, timeout); -} - -//static -uint32_t NetSh::ConvertInterfaceGuidToIndex(const std::wstring &interfaceGuid) -{ - auto rawGuid = common::Guid::FromString(interfaceGuid); - - NET_LUID luid; - NET_IFINDEX index; - - if (NO_ERROR != ConvertInterfaceGuidToLuid(&rawGuid, &luid) - || NO_ERROR != ConvertInterfaceLuidToIndex(&luid, &index)) - { - throw std::runtime_error("Invalid interface GUID"); - } - - return index; -} - -NetSh::NetSh(ILogSink *logSink) - : m_logSink(logSink) -{ - const auto system32 = common::fs::GetKnownFolderPath(FOLDERID_System, 0, nullptr); - - m_netShPath = std::experimental::filesystem::path(system32).append(L"netsh.exe"); + validateShellOut(*netsh, timeout); } -void NetSh::ValidateShellOut(common::ApplicationRunner &netsh, uint32_t timeout) +void NetSh::validateShellOut(common::ApplicationRunner &netsh, uint32_t timeout) { const uint32_t actualTimeout = (0 == timeout ? 10000 : timeout); diff --git a/windows/windns/src/windns/netsh.h b/windows/windns/src/windns/netsh.h index f47408c9e2..d80c55529c 100644 --- a/windows/windns/src/windns/netsh.h +++ b/windows/windns/src/windns/netsh.h @@ -6,35 +6,30 @@ #include <vector> #include <cstdint> #include <stdexcept> +#include <memory> class NetSh { public: - static void Construct(ILogSink *logSink); + NetSh(std::shared_ptr<ILogSink> logSink); - static NetSh &Instance(); - - void SetIpv4StaticDns(uint32_t interfaceIndex, + void setIpv4StaticDns(uint32_t interfaceIndex, const std::vector<std::wstring> &nameServers, uint32_t timeout = 0); - void SetIpv4DhcpDns(uint32_t interfaceIndex, uint32_t timeout = 0); + void setIpv4DhcpDns(uint32_t interfaceIndex, uint32_t timeout = 0); - void SetIpv6StaticDns(uint32_t interfaceIndex, + void setIpv6StaticDns(uint32_t interfaceIndex, const std::vector<std::wstring> &nameServers, uint32_t timeout = 0); - void SetIpv6DhcpDns(uint32_t interfaceIndex, uint32_t timeout = 0); - - static uint32_t ConvertInterfaceGuidToIndex(const std::wstring &interfaceGuid); + void setIpv6DhcpDns(uint32_t interfaceIndex, uint32_t timeout = 0); private: - ILogSink *m_logSink; + std::shared_ptr<ILogSink> m_logSink; std::wstring m_netShPath; - NetSh(ILogSink *logSink); - - void ValidateShellOut(common::ApplicationRunner &netsh, uint32_t timeout); + void validateShellOut(common::ApplicationRunner &netsh, uint32_t timeout); }; class NetShError : public std::exception diff --git a/windows/windns/src/windns/recoveryformatter.cpp b/windows/windns/src/windns/recoveryformatter.cpp deleted file mode 100644 index e6ed3d75fd..0000000000 --- a/windows/windns/src/windns/recoveryformatter.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "stdafx.h" -#include <libcommon/serialization/serializer.h> -#include <libcommon/serialization/deserializer.h> -#include "recoveryformatter.h" -#include <stdexcept> - -namespace -{ - -uint32_t RF_MAGIC = 0x21534E44; // stores as 'DNS!' -uint32_t RF_VERSION = 0x01; - -} // anonymous namespace - -//static -std::vector<uint8_t> RecoveryFormatter::Pack(const std::vector<InterfaceSnap> &v4Snaps, - const std::vector<InterfaceSnap> &v6Snaps) -{ - common::serialization::Serializer s; - - // - // Format of binary blob - // - // u32 tag - // u32 version - // u32 number of ipv4 snaps - // [] ipv4 snaps - // u32 number of ipv6 snaps - // [] ipv6 snaps - // - - s << RF_MAGIC; - s << RF_VERSION; - - s << static_cast<uint32_t>(v4Snaps.size()); - - for (const auto &snap : v4Snaps) - { - snap.serialize(s); - } - - s << static_cast<uint32_t>(v6Snaps.size()); - - for (const auto &snap : v6Snaps) - { - snap.serialize(s); - } - - return s.blob(); -} - -//static -RecoveryFormatter::Unpacked RecoveryFormatter::Unpack(const uint8_t *data, uint32_t dataSize) -{ - common::serialization::Deserializer d(data, dataSize); - - if (RF_MAGIC != d.decode<uint32_t>() - || RF_VERSION != d.decode<uint32_t>()) - { - throw std::runtime_error("Invalid header in recovery data"); - } - - Unpacked unpacked; - - auto numV4Snaps = d.decode<uint32_t>(); - - for (; 0 != numV4Snaps; --numV4Snaps) - { - // Invoke deserializing ctor on InterfaceSnap. - unpacked.v4Snaps.emplace_back(d); - } - - auto numV6Snaps = d.decode<uint32_t>(); - - for (; 0 != numV6Snaps; --numV6Snaps) - { - // Invoke deserializing ctor on InterfaceSnap. - unpacked.v6Snaps.emplace_back(d); - } - - return unpacked; -} - -//static -RecoveryFormatter::Unpacked RecoveryFormatter::Unpack(const std::vector<uint8_t> &data) -{ - return RecoveryFormatter::Unpack(&data[0], static_cast<uint32_t>(data.size())); -} diff --git a/windows/windns/src/windns/recoveryformatter.h b/windows/windns/src/windns/recoveryformatter.h deleted file mode 100644 index c3d715cd9e..0000000000 --- a/windows/windns/src/windns/recoveryformatter.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "interfacesnap.h" -#include <vector> -#include <cstdint> - -class RecoveryFormatter -{ -public: - - RecoveryFormatter() = delete; - - static std::vector<uint8_t> Pack(const std::vector<InterfaceSnap> &v4Snaps, - const std::vector<InterfaceSnap> &v6Snaps); - - struct Unpacked - { - std::vector<InterfaceSnap> v4Snaps; - std::vector<InterfaceSnap> v6Snaps; - }; - - static Unpacked Unpack(const uint8_t *data, uint32_t dataSize); - static Unpacked Unpack(const std::vector<uint8_t> &data); -}; diff --git a/windows/windns/src/windns/recoverylogic.cpp b/windows/windns/src/windns/recoverylogic.cpp deleted file mode 100644 index 70fe0b8a91..0000000000 --- a/windows/windns/src/windns/recoverylogic.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include "stdafx.h" -#include "recoverylogic.h" -#include "netsh.h" -#include "confineoperation.h" -#include <libcommon/trace/xtrace.h> -#include <stdexcept> - -//static -void RecoveryLogic::RestoreInterfaces(const RecoveryFormatter::Unpacked &data, - ILogSink *logSink, uint32_t timeout) -{ - if (nullptr == logSink) - { - throw std::runtime_error("Invalid logger sink"); - } - - bool success = true; - - for (const auto &snap : data.v4Snaps) - { - const auto status = ConfineOperation("Reset interface DNS settings", logSink, [&snap, &timeout]() - { - if (snap.internalInterface()) - { - // - // This is an interface used for internal communication. - // We haven't changed any settings on it and therefore should not restore it. - // - return; - } - - XTRACE(L"Resetting name server configuration for interface ", snap.interfaceGuid()); - - uint32_t interfaceIndex = 0; - - try - { - interfaceIndex = NetSh::ConvertInterfaceGuidToIndex(snap.interfaceGuid()); - } - catch (...) - { - // - // The interface cannot be linked to a virtual or physical adapter. - // It's either floating or has been removed. - // - - XTRACE(L"Ignoring floating/invalid interface ", snap.interfaceGuid()); - return; - } - - if (snap.nameServers().empty()) - { - NetSh::Instance().SetIpv4DhcpDns(interfaceIndex, timeout); - } - else - { - NetSh::Instance().SetIpv4StaticDns(interfaceIndex, snap.nameServers(), timeout); - } - }); - - if (false == status) - { - success = false; - } - } - - for (const auto &snap : data.v6Snaps) - { - const auto status = ConfineOperation("Reset interface DNS settings", logSink, [&snap, &timeout]() - { - if (snap.internalInterface()) - { - // - // This is an interface used for internal communication. - // We haven't changed any settings on it and therefore should not restore it. - // - return; - } - - XTRACE(L"Resetting name server configuration for interface ", snap.interfaceGuid()); - - uint32_t interfaceIndex = 0; - - try - { - interfaceIndex = NetSh::ConvertInterfaceGuidToIndex(snap.interfaceGuid()); - } - catch (...) - { - // - // The interface cannot be linked to a virtual or physical adapter. - // It's either floating or has been removed. - // - - XTRACE(L"Ignoring floating/invalid interface ", snap.interfaceGuid()); - return; - } - - if (snap.nameServers().empty()) - { - NetSh::Instance().SetIpv6DhcpDns(interfaceIndex, timeout); - } - else - { - NetSh::Instance().SetIpv6StaticDns(interfaceIndex, snap.nameServers(), timeout); - } - }); - - if (false == status) - { - success = false; - } - } - - if (false == success) - { - throw std::runtime_error("Could not reset DNS settings for one of more interfaces"); - } -} diff --git a/windows/windns/src/windns/recoverylogic.h b/windows/windns/src/windns/recoverylogic.h deleted file mode 100644 index 5937b0635c..0000000000 --- a/windows/windns/src/windns/recoverylogic.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "recoveryformatter.h" -#include "ilogsink.h" - -class RecoveryLogic -{ -public: - - RecoveryLogic() = delete; - - static void RestoreInterfaces(const RecoveryFormatter::Unpacked &data, - ILogSink *logSink, uint32_t timeout = 0); -}; diff --git a/windows/windns/src/windns/recoverysink.cpp b/windows/windns/src/windns/recoverysink.cpp deleted file mode 100644 index 55a6620c7d..0000000000 --- a/windows/windns/src/windns/recoverysink.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "stdafx.h" -#include "recoverysink.h" -#include "recoveryformatter.h" -#include <stdexcept> - -RecoverySink::RecoverySink(const RecoverySinkInfo &target) - : m_target(target) -{ -} - -void RecoverySink::setTarget(const RecoverySinkInfo &target) -{ - std::scoped_lock<std::mutex> lock(m_targetMutex); - - m_target = target; -} - -void RecoverySink::preserveSnaps(Protocol protocol, const std::vector<InterfaceSnap> &snaps) -{ - std::scoped_lock<std::mutex> dataLock(m_dataMutex); - - switch (protocol) - { - case Protocol::IPv4: - { - m_v4Snaps = snaps; - break; - } - case Protocol::IPv6: - { - m_v6Snaps = snaps; - break; - } - default: - { - throw std::runtime_error("Missing case handler"); - } - } - - m_recoveryData = RecoveryFormatter::Pack(m_v4Snaps, m_v6Snaps); - - std::scoped_lock<std::mutex> lock(m_targetMutex); - - m_target.sink(&m_recoveryData[0], static_cast<uint32_t>(m_recoveryData.size()), m_target.context); -} - -std::vector<uint8_t> RecoverySink::recoveryData() const -{ - std::vector<uint8_t> copy; - - { - std::scoped_lock<std::mutex> dataLock(m_dataMutex); - - copy = m_recoveryData; - } - - return copy; -} diff --git a/windows/windns/src/windns/recoverysink.h b/windows/windns/src/windns/recoverysink.h deleted file mode 100644 index b685ccd12e..0000000000 --- a/windows/windns/src/windns/recoverysink.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "irecoverysink.h" -#include "clientsinkinfo.h" -#include <vector> -#include <cstdint> -#include <mutex> - -class RecoverySink : public IRecoverySink -{ -public: - - RecoverySink(const RecoverySinkInfo &target); - - void setTarget(const RecoverySinkInfo &target); - - void preserveSnaps(Protocol protocol, const std::vector<InterfaceSnap> &snaps) override; - - std::vector<uint8_t> recoveryData() const; - -private: - - std::mutex m_targetMutex; - RecoverySinkInfo m_target; - - mutable std::mutex m_dataMutex; - std::vector<InterfaceSnap> m_v4Snaps; - std::vector<InterfaceSnap> m_v6Snaps; - std::vector<uint8_t> m_recoveryData; -}; diff --git a/windows/windns/src/windns/registrypaths.cpp b/windows/windns/src/windns/registrypaths.cpp deleted file mode 100644 index 65117ee4fe..0000000000 --- a/windows/windns/src/windns/registrypaths.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "stdafx.h" -#include "registrypaths.h" - -//static -std::wstring RegistryPaths::InterfaceRoot(Protocol protocol) -{ - return - std::wstring(L"SYSTEM\\CurrentControlSet\\Services\\") - .append(Protocol::IPv4 == protocol ? L"Tcpip" : L"Tcpip6") - .append(L"\\Parameters\\Interfaces"); -} - -//static -std::wstring RegistryPaths::InterfaceKey(const std::wstring &interfaceGuid, Protocol protocol) -{ - return - InterfaceRoot(protocol) - .append(L"\\") - .append(interfaceGuid); -} diff --git a/windows/windns/src/windns/registrypaths.h b/windows/windns/src/windns/registrypaths.h deleted file mode 100644 index 34e8022649..0000000000 --- a/windows/windns/src/windns/registrypaths.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "types.h" -#include <string> - -class RegistryPaths -{ -public: - - RegistryPaths() = delete; - - static std::wstring InterfaceRoot(Protocol protocol); - static std::wstring InterfaceKey(const std::wstring &interfaceGuid, Protocol protocol); -}; diff --git a/windows/windns/src/windns/types.h b/windows/windns/src/windns/types.h deleted file mode 100644 index 4782621cd2..0000000000 --- a/windows/windns/src/windns/types.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include <cstdint> - -enum class Protocol : uint8_t -{ - IPv4, - IPv6 -}; diff --git a/windows/windns/src/windns/windns.cpp b/windows/windns/src/windns/windns.cpp index e082f0826e..268751eb8b 100644 --- a/windows/windns/src/windns/windns.cpp +++ b/windows/windns/src/windns/windns.cpp @@ -1,21 +1,19 @@ #include "stdafx.h" +#include <libcommon/string.h> #include "windns.h" -#include "windnscontext.h" -#include "clientsinkinfo.h" #include "confineoperation.h" -#include "recoveryformatter.h" -#include "recoverylogic.h" #include "netsh.h" #include "logsink.h" #include <memory> #include <vector> #include <string> +#include <iphlpapi.h> namespace { -LogSink *g_LogSink = nullptr; -WinDnsContext *g_Context = nullptr; +std::shared_ptr<LogSink> g_LogSink; +std::shared_ptr<NetSh> g_NetSh; std::vector<std::wstring> MakeStringArray(const wchar_t **strings, uint32_t numStrings) { @@ -37,6 +35,33 @@ void ForwardError(const char *message, const char **details, uint32_t numDetails } } +uint32_t ConvertInterfaceAliasToIndex(const std::wstring &interfaceAlias) +{ + NET_LUID luid; + + if (NO_ERROR != ConvertInterfaceAliasToLuid(interfaceAlias.c_str(), &luid)) + { + const auto err = std::wstring(L"Could not resolve LUID of interface: \"") + .append(interfaceAlias).append(L"\""); + + throw std::runtime_error(common::string::ToAnsi(err).c_str()); + } + + NET_IFINDEX index; + + if (NO_ERROR != ConvertInterfaceLuidToIndex(&luid, &index)) + { + std::wstringstream ss; + + ss << L"Could not resolve index of interface: \"" << interfaceAlias << L"\"" + << L"with LUID: 0x" << std::hex << luid.Value; + + throw std::runtime_error(common::string::ToAnsi(ss.str()).c_str()); + } + + return static_cast<uint32_t>(index); +} + } // anonymous namespace WINDNS_LINKAGE @@ -47,24 +72,24 @@ WinDns_Initialize( void *logContext ) { - if (nullptr != g_Context) + if (g_LogSink) { return false; } return ConfineOperation("Initialize", ForwardError, [&]() { - if (nullptr == g_LogSink) + g_LogSink = std::make_shared<LogSink>(LogSinkInfo{ logSink, logContext }); + + try { - g_LogSink = new LogSink(LogSinkInfo{ logSink, logContext }); - NetSh::Construct(g_LogSink); + g_NetSh = std::make_shared<NetSh>(g_LogSink); } - else + catch (...) { - g_LogSink->setTarget(LogSinkInfo{ logSink, logContext }); + g_LogSink.reset(); + throw; } - - g_Context = new WinDnsContext(g_LogSink); }); } @@ -74,17 +99,8 @@ WINDNS_API WinDns_Deinitialize( ) { - if (nullptr == g_Context) - { - return true; - } - - delete g_Context; - g_Context = nullptr; - - // Maintain a single instance forever and invoke setTarget() on it. - //delete g_LogSink; - //g_LogSink = nullptr; + g_NetSh.reset(); + g_LogSink.reset(); return true; } @@ -93,60 +109,25 @@ WINDNS_LINKAGE bool WINDNS_API WinDns_Set( + const wchar_t *interfaceAlias, const wchar_t **ipv4Servers, uint32_t numIpv4Servers, const wchar_t **ipv6Servers, - uint32_t numIpv6Servers, - WinDnsRecoverySink recoverySink, - void *recoveryContext + uint32_t numIpv6Servers ) { - if (nullptr == g_Context - || nullptr == ipv4Servers - || 0 == numIpv4Servers - || nullptr == recoverySink) + return ConfineOperation("Apply DNS settings", ForwardError, [&]() { - return false; - } + const auto interfaceIndex = ConvertInterfaceAliasToIndex(interfaceAlias); - return ConfineOperation("Enforce DNS settings", ForwardError, [&]() - { - g_Context->set(MakeStringArray(ipv4Servers, numIpv4Servers), MakeStringArray(ipv6Servers, \ - numIpv6Servers), RecoverySinkInfo{ recoverySink, recoveryContext }); - }); -} - -WINDNS_LINKAGE -bool -WINDNS_API -WinDns_Reset( -) -{ - if (nullptr == g_Context) - { - return true; - } - - return ConfineOperation("Reset DNS settings", ForwardError, []() - { - g_Context->reset(); - }); -} - -WINDNS_LINKAGE -bool -WINDNS_API -WinDns_Recover( - const void *recoveryData, - uint32_t dataLength -) -{ - return ConfineOperation("Recover DNS settings", ForwardError, [&]() - { - auto unpacked = RecoveryFormatter::Unpack(reinterpret_cast<const uint8_t *>(recoveryData), dataLength); - - static const uint32_t TIMEOUT_TEN_SECONDS = 1000 * 10; + if (nullptr != ipv4Servers && 0 != numIpv4Servers) + { + g_NetSh->setIpv4StaticDns(interfaceIndex, MakeStringArray(ipv4Servers, numIpv4Servers)); + } - RecoveryLogic::RestoreInterfaces(unpacked, g_LogSink, TIMEOUT_TEN_SECONDS); + if (nullptr != ipv6Servers && 0 != numIpv6Servers) + { + g_NetSh->setIpv6StaticDns(interfaceIndex, MakeStringArray(ipv6Servers, numIpv6Servers)); + } }); } diff --git a/windows/windns/src/windns/windns.h b/windows/windns/src/windns/windns.h index a7ebfd8f95..2ecd046f5b 100644 --- a/windows/windns/src/windns/windns.h +++ b/windows/windns/src/windns/windns.h @@ -26,17 +26,11 @@ enum WinDnsLogCategory typedef void (WINDNS_API *WinDnsLogSink)(WinDnsLogCategory category, const char *message, const char **details, uint32_t numDetails, void *context); -typedef void (WINDNS_API *WinDnsRecoverySink)(const void *recoveryData, uint32_t dataLength, void *context); - // // WinDns_Initialize: // // Call this function once at startup, to acquire resources etc. -// -// The OPTIONAL error callback is remembered and used to report exceptions that -// occur as a direct or indirect result of calling into WINDNS. -// -// (Recall that the monitoring provided by WINDNS is threaded.) +// The error callback is OPTIONAL. // extern "C" WINDNS_LINKAGE @@ -62,56 +56,16 @@ WinDns_Deinitialize( // // WinDns_Set: // -// Configure which DNS servers should be used and start enforcing these settings. -// -// The 'recoverySink' will receive periodic callbacks with updated recovery data -// until you call WinDns_Reset. -// -// You should persist the recovery data in preparation for an eventual recovery. +// Configure DNS servers on given adapter. // extern "C" WINDNS_LINKAGE bool WINDNS_API WinDns_Set( + const wchar_t *interfaceAlias, const wchar_t **ipv4Servers, uint32_t numIpv4Servers, const wchar_t **ipv6Servers, - uint32_t numIpv6Servers, - WinDnsRecoverySink recoverySink, - void *recoveryContext -); - -// -// Windns_Reset: -// -// Revert server settings to what they were before calling WinDns_Set. -// -// (Also taking into account external changes to DNS settings that have occurred -// during the period of enforcing specific settings.) -// -// It's safe to discard persisted recovery data once WinDns_Reset returns 'true'. -// -extern "C" -WINDNS_LINKAGE -bool -WINDNS_API -WinDns_Reset( -); - -// -// WinDns_Recover: -// -// Recover adapter configurations from a previously persisted state. -// -// This is useful if the machine has been abruptly powered off and -// WINDNS did not get a chance to restore settings. -// -extern "C" -WINDNS_LINKAGE -bool -WINDNS_API -WinDns_Recover( - const void *recoveryData, - uint32_t dataLength + uint32_t numIpv6Servers ); diff --git a/windows/windns/src/windns/windns.vcxproj b/windows/windns/src/windns/windns.vcxproj index bf84c01690..9edfb96ea3 100644 --- a/windows/windns/src/windns/windns.vcxproj +++ b/windows/windns/src/windns/windns.vcxproj @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> @@ -175,40 +175,19 @@ </Link> </ItemDefinitionGroup> <ItemGroup> - <ClInclude Include="clientsinkinfo.h" /> <ClInclude Include="confineoperation.h" /> <ClInclude Include="logsink.h" /> <ClInclude Include="ilogsink.h" /> - <ClInclude Include="inameserversource.h" /> - <ClInclude Include="interfacemonitor.h" /> - <ClInclude Include="interfacesnap.h" /> - <ClInclude Include="irecoverysink.h" /> - <ClInclude Include="dnsagent.h" /> - <ClInclude Include="nameserversource.h" /> <ClInclude Include="netsh.h" /> - <ClInclude Include="recoveryformatter.h" /> - <ClInclude Include="recoverylogic.h" /> - <ClInclude Include="recoverysink.h" /> - <ClInclude Include="registrypaths.h" /> <ClInclude Include="stdafx.h" /> <ClInclude Include="targetver.h" /> - <ClInclude Include="types.h" /> <ClInclude Include="windns.h" /> - <ClInclude Include="windnscontext.h" /> </ItemGroup> <ItemGroup> <ClCompile Include="confineoperation.cpp" /> <ClCompile Include="dllmain.cpp" /> <ClCompile Include="logsink.cpp" /> - <ClCompile Include="interfacemonitor.cpp" /> - <ClCompile Include="interfacesnap.cpp" /> - <ClCompile Include="dnsagent.cpp" /> - <ClCompile Include="nameserversource.cpp" /> <ClCompile Include="netsh.cpp" /> - <ClCompile Include="recoveryformatter.cpp" /> - <ClCompile Include="recoverylogic.cpp" /> - <ClCompile Include="recoverysink.cpp" /> - <ClCompile Include="registrypaths.cpp" /> <ClCompile Include="stdafx.cpp"> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> @@ -216,7 +195,6 @@ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> </ClCompile> <ClCompile Include="windns.cpp" /> - <ClCompile Include="windnscontext.cpp" /> </ItemGroup> <ItemGroup> <ResourceCompile Include="windns.rc" /> diff --git a/windows/windns/src/windns/windns.vcxproj.filters b/windows/windns/src/windns/windns.vcxproj.filters index 3c846bb6ba..e71bf3e814 100644 --- a/windows/windns/src/windns/windns.vcxproj.filters +++ b/windows/windns/src/windns/windns.vcxproj.filters @@ -4,40 +4,18 @@ <ClInclude Include="stdafx.h" /> <ClInclude Include="targetver.h" /> <ClInclude Include="windns.h" /> - <ClInclude Include="windnscontext.h" /> - <ClInclude Include="clientsinkinfo.h" /> <ClInclude Include="netsh.h" /> <ClInclude Include="confineoperation.h" /> - <ClInclude Include="interfacesnap.h" /> - <ClInclude Include="interfacemonitor.h" /> - <ClInclude Include="registrypaths.h" /> - <ClInclude Include="types.h" /> - <ClInclude Include="inameserversource.h" /> - <ClInclude Include="irecoverysink.h" /> - <ClInclude Include="dnsagent.h" /> - <ClInclude Include="recoverysink.h" /> - <ClInclude Include="recoveryformatter.h" /> - <ClInclude Include="nameserversource.h" /> <ClInclude Include="ilogsink.h" /> <ClInclude Include="logsink.h" /> - <ClInclude Include="recoverylogic.h" /> </ItemGroup> <ItemGroup> <ClCompile Include="dllmain.cpp" /> <ClCompile Include="stdafx.cpp" /> <ClCompile Include="windns.cpp" /> - <ClCompile Include="windnscontext.cpp" /> <ClCompile Include="netsh.cpp" /> <ClCompile Include="confineoperation.cpp" /> - <ClCompile Include="interfacesnap.cpp" /> - <ClCompile Include="interfacemonitor.cpp" /> - <ClCompile Include="registrypaths.cpp" /> - <ClCompile Include="dnsagent.cpp" /> - <ClCompile Include="recoverysink.cpp" /> - <ClCompile Include="recoveryformatter.cpp" /> - <ClCompile Include="nameserversource.cpp" /> <ClCompile Include="logsink.cpp" /> - <ClCompile Include="recoverylogic.cpp" /> </ItemGroup> <ItemGroup> <ResourceCompile Include="windns.rc" /> diff --git a/windows/windns/src/windns/windnscontext.cpp b/windows/windns/src/windns/windnscontext.cpp deleted file mode 100644 index d9d7913c67..0000000000 --- a/windows/windns/src/windns/windnscontext.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "stdafx.h" -#include "windnscontext.h" -#include "confineoperation.h" -#include "recoveryformatter.h" -#include "recoverylogic.h" -#include <functional> - -using namespace common; - -WinDnsContext::WinDnsContext(ILogSink *logSink) - : m_logSink(logSink) -{ - if (nullptr == logSink) - { - throw std::runtime_error("Invalid logger sink"); - } -} - -WinDnsContext::~WinDnsContext() -{ - ConfineOperation("Reset DNS settings", m_logSink, [this]() - { - this->reset(); - }); -} - -void WinDnsContext::set(const std::vector<std::wstring> &ipv4NameServers, - const std::vector<std::wstring> &ipv6NameServers, const RecoverySinkInfo &recoverySinkInfo) -{ - // - // The 'sink' and 'source' instances must be kept alive for the lifetime of the agents. - // - - if (!m_recoverySink) - { - m_recoverySink = std::make_unique<RecoverySink>(recoverySinkInfo); - } - else - { - m_recoverySink->setTarget(recoverySinkInfo); - } - - // Clearing DNS agents if the new server lists are empty, as they aren't needed. - if (ipv4NameServers.empty()) - { - m_ipv4Agent.reset(); - } - if (ipv6NameServers.empty()) - { - m_ipv6Agent.reset(); - } - - if (!m_nameServerSource) - { - m_nameServerSource = std::make_unique<NameServerSource>(ipv4NameServers, ipv6NameServers); - } - else - { - m_nameServerSource->setNameServers(Protocol::IPv4, ipv4NameServers); - m_nameServerSource->setNameServers(Protocol::IPv6, ipv6NameServers); - } - - // - // Instantiate agents unless they're already set up or the relevant server lists are empty - // - if (!m_ipv4Agent && !ipv4NameServers.empty()) - { - m_ipv4Agent = std::make_unique<DnsAgent>(Protocol::IPv4, m_nameServerSource.get(), m_recoverySink.get(), m_logSink); - } - - - if (!m_ipv6Agent && !ipv6NameServers.empty()) - { - m_ipv6Agent = std::make_unique<DnsAgent>(Protocol::IPv6, m_nameServerSource.get(), m_recoverySink.get(), m_logSink); - } -} - -void WinDnsContext::reset() -{ - if (!m_ipv4Agent && !m_ipv6Agent) - { - return; - } - - // - // Destructing the agents will abort all monitoring + enforcing. - // - - if (m_ipv4Agent) - { - m_ipv4Agent.reset(nullptr); - } - - if (m_ipv6Agent) - { - m_ipv6Agent.reset(nullptr); - } - - auto recoveryData = RecoveryFormatter::Unpack(m_recoverySink->recoveryData()); - - RecoveryLogic::RestoreInterfaces(recoveryData, m_logSink); -} diff --git a/windows/windns/src/windns/windnscontext.h b/windows/windns/src/windns/windnscontext.h deleted file mode 100644 index c64ab96f31..0000000000 --- a/windows/windns/src/windns/windnscontext.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "windns.h" -#include "clientsinkinfo.h" -#include "ilogsink.h" -#include "recoverysink.h" -#include "nameserversource.h" -#include "dnsagent.h" -#include <vector> -#include <string> -#include <memory> - -class WinDnsContext -{ -public: - - WinDnsContext(ILogSink *logSink); - ~WinDnsContext(); - - void set(const std::vector<std::wstring> &ipv4NameServers, const std::vector<std::wstring> &ipv6NameServers, - const RecoverySinkInfo &recoverySinkInfo); - - void reset(); - -private: - - ILogSink *m_logSink; - - std::unique_ptr<RecoverySink> m_recoverySink; - std::unique_ptr<NameServerSource> m_nameServerSource; - - std::unique_ptr<DnsAgent> m_ipv4Agent; - std::unique_ptr<DnsAgent> m_ipv6Agent; -}; |
