diff options
| author | Odd Stranne <odd@mullvad.net> | 2019-12-03 10:07:20 +0100 |
|---|---|---|
| committer | Odd Stranne <odd@mullvad.net> | 2019-12-04 13:07:57 +0100 |
| commit | 877f34593b857e3f1d81d9acce003e2ededbda1d (patch) | |
| tree | 6b0f78b1c6e9b0b0dc437434a37bd8fd8af969e6 /windows/libshared/src | |
| parent | 80ce050ad2eee528ded8d5c1d2211534fe7485ae (diff) | |
| download | mullvadvpn-877f34593b857e3f1d81d9acce003e2ededbda1d.tar.xz mullvadvpn-877f34593b857e3f1d81d9acce003e2ededbda1d.zip | |
Update shared logging in C++
Diffstat (limited to 'windows/libshared/src')
| -rw-r--r-- | windows/libshared/src/libshared/libshared.vcxproj | 202 | ||||
| -rw-r--r-- | windows/libshared/src/libshared/libshared.vcxproj.filters | 45 | ||||
| -rw-r--r-- | windows/libshared/src/libshared/logging/logsink.h | 27 | ||||
| -rw-r--r-- | windows/libshared/src/libshared/logging/logsinkadapter.cpp | 49 | ||||
| -rw-r--r-- | windows/libshared/src/libshared/logging/logsinkadapter.h | 24 | ||||
| -rw-r--r-- | windows/libshared/src/libshared/logging/stdoutlogger.cpp | 33 | ||||
| -rw-r--r-- | windows/libshared/src/libshared/logging/stdoutlogger.h | 10 | ||||
| -rw-r--r-- | windows/libshared/src/libshared/logging/unwind.cpp | 21 | ||||
| -rw-r--r-- | windows/libshared/src/libshared/logging/unwind.h | 11 | ||||
| -rw-r--r-- | windows/libshared/src/libshared/network/interfaceutils.cpp | 177 | ||||
| -rw-r--r-- | windows/libshared/src/libshared/network/interfaceutils.h | 79 | ||||
| -rw-r--r-- | windows/libshared/src/libshared/stdafx.cpp | 8 | ||||
| -rw-r--r-- | windows/libshared/src/libshared/stdafx.h | 15 | ||||
| -rw-r--r-- | windows/libshared/src/libshared/targetver.h | 12 |
14 files changed, 713 insertions, 0 deletions
diff --git a/windows/libshared/src/libshared/libshared.vcxproj b/windows/libshared/src/libshared/libshared.vcxproj new file mode 100644 index 0000000000..88a2ac5140 --- /dev/null +++ b/windows/libshared/src/libshared/libshared.vcxproj @@ -0,0 +1,202 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="16.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> + <PropertyGroup Label="Globals"> + <VCProjectVersion>16.0</VCProjectVersion> + <ProjectGuid>{EE69EA4A-CF71-4B88-866B-957F60C4CE0D}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>libshared</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>libshared</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</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>Use</PrecompiledHeader> + <WarningLevel>Level4</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../../../windows-libraries/src/</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <LanguageStandard>stdcpplatest</LanguageStandard> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>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> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <WarningLevel>Level4</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../../../windows-libraries/src/</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <LanguageStandard>stdcpplatest</LanguageStandard> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>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> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <WarningLevel>Level4</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../../../windows-libraries/src/</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <LanguageStandard>stdcpplatest</LanguageStandard> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>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> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <WarningLevel>Level4</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../../../windows-libraries/src/</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <LanguageStandard>stdcpplatest</LanguageStandard> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories> + <AdditionalDependencies>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> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="network\interfaceutils.h" /> + <ClInclude Include="logging\logsink.h" /> + <ClInclude Include="logging\logsinkadapter.h" /> + <ClInclude Include="logging\stdoutlogger.h" /> + <ClInclude Include="logging\unwind.h" /> + <ClInclude Include="stdafx.h" /> + <ClInclude Include="targetver.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="network\interfaceutils.cpp" /> + <ClCompile Include="logging\logsinkadapter.cpp" /> + <ClCompile Include="logging\stdoutlogger.cpp" /> + <ClCompile Include="logging\unwind.cpp" /> + <ClCompile Include="stdafx.cpp"> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> + </ClCompile> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/windows/libshared/src/libshared/libshared.vcxproj.filters b/windows/libshared/src/libshared/libshared.vcxproj.filters new file mode 100644 index 0000000000..ef4f0330d2 --- /dev/null +++ b/windows/libshared/src/libshared/libshared.vcxproj.filters @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <ClInclude Include="stdafx.h" /> + <ClInclude Include="targetver.h" /> + <ClInclude Include="logging\logsink.h"> + <Filter>logging</Filter> + </ClInclude> + <ClInclude Include="logging\logsinkadapter.h"> + <Filter>logging</Filter> + </ClInclude> + <ClInclude Include="logging\stdoutlogger.h"> + <Filter>logging</Filter> + </ClInclude> + <ClInclude Include="logging\unwind.h"> + <Filter>logging</Filter> + </ClInclude> + <ClInclude Include="network\interfaceutils.h"> + <Filter>network</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="stdafx.cpp" /> + <ClCompile Include="logging\logsinkadapter.cpp"> + <Filter>logging</Filter> + </ClCompile> + <ClCompile Include="logging\stdoutlogger.cpp"> + <Filter>logging</Filter> + </ClCompile> + <ClCompile Include="logging\unwind.cpp"> + <Filter>logging</Filter> + </ClCompile> + <ClCompile Include="network\interfaceutils.cpp"> + <Filter>network</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <Filter Include="logging"> + <UniqueIdentifier>{8d3be7e9-117c-44d3-a799-0bc6e2712776}</UniqueIdentifier> + </Filter> + <Filter Include="network"> + <UniqueIdentifier>{c36884fc-7afc-42a8-b852-c0aafcfcc1c2}</UniqueIdentifier> + </Filter> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/windows/libshared/src/libshared/logging/logsink.h b/windows/libshared/src/libshared/logging/logsink.h new file mode 100644 index 0000000000..e24c69ac32 --- /dev/null +++ b/windows/libshared/src/libshared/logging/logsink.h @@ -0,0 +1,27 @@ +#pragma once + +// +// This file is shared between DLL modules to help define their public interface. +// It should always be C-compatible. +// + +enum MULLVAD_LOG_LEVEL +{ + MULLVAD_LOG_LEVEL_ERROR = 0, + MULLVAD_LOG_LEVEL_WARNING, + MULLVAD_LOG_LEVEL_INFO, + MULLVAD_LOG_LEVEL_DEBUG, + MULLVAD_LOG_LEVEL_TRACE +}; + +// +// The log sink is registered with a DLL during e.g. initialization. +// It may later be activated as a direct or indirect result of calling into the DLL. +// +// The parameters are: +// +// `MULLVAD_LOG_LEVEL` - Severity of the message. +// `const char *` - The message itself. +// `void *` - The sink context that was registered along with the sink. +// +typedef void (__stdcall *MullvadLogSink)(MULLVAD_LOG_LEVEL, const char *, void *); diff --git a/windows/libshared/src/libshared/logging/logsinkadapter.cpp b/windows/libshared/src/libshared/logging/logsinkadapter.cpp new file mode 100644 index 0000000000..f506aba096 --- /dev/null +++ b/windows/libshared/src/libshared/logging/logsinkadapter.cpp @@ -0,0 +1,49 @@ +#include "stdafx.h" +#include "logsinkadapter.h" + +namespace shared::logging +{ + +LogSinkAdapter::LogSinkAdapter(MullvadLogSink target, void *context) + : LogSink(MakeAdapter(target, context)) +{ +} + +//static +common::logging::LogTarget LogSinkAdapter::MakeAdapter(MullvadLogSink target, void *context) +{ + return [target, context](common::logging::LogLevel level, const char* msg) + { + if (nullptr == target) + { + return; + } + + // + // TODO: Replace manual mapping with ValueMapper once the updated + // ValueMapper reaches libcommon. + // + + const MULLVAD_LOG_LEVEL translatedLevel = [level]() + { + switch (level) + { + case common::logging::LogLevel::Warning: + return MULLVAD_LOG_LEVEL_WARNING; + case common::logging::LogLevel::Info: + return MULLVAD_LOG_LEVEL_INFO; + case common::logging::LogLevel::Trace: + return MULLVAD_LOG_LEVEL_TRACE; + case common::logging::LogLevel::Debug: + return MULLVAD_LOG_LEVEL_DEBUG; + case common::logging::LogLevel::Error: + default: + return MULLVAD_LOG_LEVEL_ERROR; + } + }(); + + target(translatedLevel, msg, context); + }; +} + +} diff --git a/windows/libshared/src/libshared/logging/logsinkadapter.h b/windows/libshared/src/libshared/logging/logsinkadapter.h new file mode 100644 index 0000000000..d077e29b4f --- /dev/null +++ b/windows/libshared/src/libshared/logging/logsinkadapter.h @@ -0,0 +1,24 @@ +#pragma once + +#include "logsink.h" +#include <libcommon/logging/logsink.h> + +namespace shared::logging +{ + +// +// Adapt common::logging::LogSink C++ world to +// MullvadLogSink C world. +// +class LogSinkAdapter : public common::logging::LogSink +{ +public: + + LogSinkAdapter(MullvadLogSink target, void *context); + +private: + + static common::logging::LogTarget MakeAdapter(MullvadLogSink target, void *context); +}; + +} diff --git a/windows/libshared/src/libshared/logging/stdoutlogger.cpp b/windows/libshared/src/libshared/logging/stdoutlogger.cpp new file mode 100644 index 0000000000..6a72009950 --- /dev/null +++ b/windows/libshared/src/libshared/logging/stdoutlogger.cpp @@ -0,0 +1,33 @@ +#include "stdafx.h" +#include "stdoutlogger.h" +#include <iostream> + +namespace shared::logging +{ + +void __stdcall StdoutLogger(MULLVAD_LOG_LEVEL level, const char *msg, void*) +{ + switch (level) + { + case MULLVAD_LOG_LEVEL_WARNING: + std::cout << "Warning: "; + break; + case MULLVAD_LOG_LEVEL_INFO: + std::cout << "Info: "; + break; + case MULLVAD_LOG_LEVEL_DEBUG: + std::cout << "Debug: "; + break; + case MULLVAD_LOG_LEVEL_TRACE: + std::cout << "Trace: "; + break; + case MULLVAD_LOG_LEVEL_ERROR: + default: + std::cout << "Error: "; + break; + } + + std::cout << msg << std::endl; +} + +} diff --git a/windows/libshared/src/libshared/logging/stdoutlogger.h b/windows/libshared/src/libshared/logging/stdoutlogger.h new file mode 100644 index 0000000000..d6cee1b58b --- /dev/null +++ b/windows/libshared/src/libshared/logging/stdoutlogger.h @@ -0,0 +1,10 @@ +#pragma once + +#include "logsink.h" + +namespace shared::logging +{ + +void __stdcall StdoutLogger(MULLVAD_LOG_LEVEL level, const char *msg, void *context); + +} diff --git a/windows/libshared/src/libshared/logging/unwind.cpp b/windows/libshared/src/libshared/logging/unwind.cpp new file mode 100644 index 0000000000..206ea81ce2 --- /dev/null +++ b/windows/libshared/src/libshared/logging/unwind.cpp @@ -0,0 +1,21 @@ +#include "stdafx.h" +#include "unwind.h" +#include "logsinkadapter.h" +#include <libcommon/error.h> + +namespace shared::logging +{ + +void UnwindAndLog(MullvadLogSink logSink, void *logSinkContext, const std::exception &err) +{ + if (nullptr == logSink) + { + return; + } + + auto logger = std::make_shared<LogSinkAdapter>(logSink, logSinkContext); + + common::error::UnwindException(err, logger); +} + +} diff --git a/windows/libshared/src/libshared/logging/unwind.h b/windows/libshared/src/libshared/logging/unwind.h new file mode 100644 index 0000000000..ab3c6c519d --- /dev/null +++ b/windows/libshared/src/libshared/logging/unwind.h @@ -0,0 +1,11 @@ +#pragma once + +#include "logsink.h" +#include <stdexcept> + +namespace shared::logging +{ + +void UnwindAndLog(MullvadLogSink logSink, void *logSinkContext, const std::exception &err); + +} diff --git a/windows/libshared/src/libshared/network/interfaceutils.cpp b/windows/libshared/src/libshared/network/interfaceutils.cpp new file mode 100644 index 0000000000..6d56ec82d2 --- /dev/null +++ b/windows/libshared/src/libshared/network/interfaceutils.cpp @@ -0,0 +1,177 @@ +#include "stdafx.h" +#include <sstream> +#include <algorithm> +#include "interfaceutils.h" +#include <libcommon/error.h> +#include <libcommon/string.h> + +namespace shared::network +{ + +InterfaceUtils::NetworkAdapter::NetworkAdapter( + const common::network::Nci &nci, + const std::shared_ptr<std::vector<uint8_t>> addressesBuffer, + const IP_ADAPTER_ADDRESSES &entry +) + : m_addressesBuffer(addressesBuffer) + , m_entry(entry) +{ + m_guid = common::string::ToWide(entry.AdapterName); + + try + { + // + // FIXME: + // Work around incorrect alias sometimes + // being returned on Windows 8. + // + // Steps to reproduce: + // 1. Install NDIS 6 TAP driver v9.00.00.21. + // 2. Update driver to v9.24.2.601. + // 3. Rename TAP adapter. + // + // GetAdaptersAddresses() returns a generic name + // for the *first* adapter instead of the correct + // one, whereas ConvertInterfaceAliasToLuid() and + // ConvertInterfaceLuidToAlias() yield correct values. + // + + IID guidObj = { 0 }; + if (S_OK != IIDFromString(&m_guid[0], &guidObj)) + { + throw std::runtime_error("IIDFromString() failed"); + } + + m_alias = nci.getConnectionName(guidObj); + } + catch (const std::exception &) + { + m_alias = entry.FriendlyName; + } + + m_name = entry.Description; +} + +//static +std::set<InterfaceUtils::NetworkAdapter> InterfaceUtils::GetAllAdapters(ULONG family, ULONG flags) +{ + ULONG bufferSize = 0; + + auto status = GetAdaptersAddresses(family, flags, nullptr, nullptr, &bufferSize); + + THROW_UNLESS(ERROR_BUFFER_OVERFLOW, status, "Probe for adapter listing buffer size"); + + // Memory is cheap, this avoids a looping construct. + bufferSize *= 2; + + auto buffer = std::make_shared<std::vector<uint8_t>>(bufferSize); + auto addresses = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(&(*buffer)[0]); + + status = GetAdaptersAddresses(family, flags, nullptr, addresses, &bufferSize); + + THROW_UNLESS(ERROR_SUCCESS, status, "Retrieve adapter listing"); + + std::set<NetworkAdapter> adapters; + + common::network::Nci nci; + + for (auto it = addresses; nullptr != it; it = it->Next) + { + adapters.emplace(NetworkAdapter(nci, buffer, *it)); + } + + return adapters; +} + +//static +void InterfaceUtils::AddDeviceIpAddresses(NET_LUID device, const std::vector<SOCKADDR_INET> &addresses) +{ + for (const auto &address : addresses) + { + MIB_UNICASTIPADDRESS_ROW row; + InitializeUnicastIpAddressEntry(&row); + + row.InterfaceLuid = device; + row.Address = address; + + THROW_UNLESS(NO_ERROR, CreateUnicastIpAddressEntry(&row), "Assign IP address on network interface"); + } +} + +//static +std::set<InterfaceUtils::NetworkAdapter> +InterfaceUtils::GetTapAdapters(const std::set<NetworkAdapter>& adapters) +{ + std::set<NetworkAdapter> tapAdapters; + + for (const auto& adapter : adapters) + { + static const wchar_t name[] = L"TAP-Windows Adapter V9"; + + // + // Compare partial name, because once you start having more TAP adapters + // they're named "TAP-Windows Adapter V9 #2" and so on. + // + + if (0 == adapter.name().compare(0, _countof(name) - 1, name)) + { + tapAdapters.insert(adapter); + } + } + + return tapAdapters; +} + +//static +std::wstring InterfaceUtils::GetTapInterfaceAlias() +{ + // + // Look for TAP adapter with alias "Mullvad". + // + + using shared::network::InterfaceUtils; + + auto adapters = InterfaceUtils::GetTapAdapters(InterfaceUtils::GetAllAdapters( + AF_INET, + GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST + )); + + auto findByAlias = [](const std::set<InterfaceUtils::NetworkAdapter>& adapters, const std::wstring& alias) + { + const auto it = std::find_if(adapters.begin(), adapters.end(), [&alias](const InterfaceUtils::NetworkAdapter& candidate) + { + return 0 == _wcsicmp(candidate.alias().c_str(), alias.c_str()); + }); + + return it != adapters.end(); + }; + + static const wchar_t baseAlias[] = L"Mullvad"; + + if (findByAlias(adapters, baseAlias)) + { + return baseAlias; + } + + // + // Look for TAP adapter with alias "Mullvad-1", "Mullvad-2", etc. + // + + for (auto i = 0; i < 10; ++i) + { + std::wstringstream ss; + + ss << baseAlias << L"-" << i; + + const auto alias = ss.str(); + + if (findByAlias(adapters, alias)) + { + return alias; + } + } + + throw std::runtime_error("Unable to find TAP adapter"); +} + +} diff --git a/windows/libshared/src/libshared/network/interfaceutils.h b/windows/libshared/src/libshared/network/interfaceutils.h new file mode 100644 index 0000000000..85a243d591 --- /dev/null +++ b/windows/libshared/src/libshared/network/interfaceutils.h @@ -0,0 +1,79 @@ +#pragma once + +#include <string> +#include <set> +#include <vector> +#include <memory> +#include <cstdint> + +// Secret include order to get most common networking structs/apis +// And avoiding compilation errors +#include <winsock2.h> +#include <windows.h> +#include <ws2def.h> +#include <ws2ipdef.h> +#include <iphlpapi.h> +#include <netioapi.h> +// end + +#include <libcommon/network/nci.h> + +namespace shared::network +{ + +class InterfaceUtils +{ + InterfaceUtils() = delete; + +public: + + class NetworkAdapter + { + + public: + + const std::wstring &guid() const { return m_guid; } + const std::wstring &name() const { return m_name; } + const std::wstring &alias() const { return m_alias; } + + bool operator<(const NetworkAdapter &rhs) const + { + return _wcsicmp(m_guid.c_str(), rhs.m_guid.c_str()) < 0; + } + + const IP_ADAPTER_ADDRESSES &raw() const + { + return m_entry; + } + + private: + + NetworkAdapter( + const common::network::Nci &nci, + const std::shared_ptr<std::vector<uint8_t>> addressesBuffer, + const IP_ADAPTER_ADDRESSES &entry + ); + + friend class InterfaceUtils; + + const IP_ADAPTER_ADDRESSES &m_entry; + std::shared_ptr<std::vector<uint8_t>> m_addressesBuffer; + + std::wstring m_guid; + std::wstring m_name; + std::wstring m_alias; + }; + + static std::set<NetworkAdapter> GetAllAdapters(ULONG family, ULONG flags); + + static void AddDeviceIpAddresses(NET_LUID device, const std::vector<SOCKADDR_INET> &addresses); + + static std::set<NetworkAdapter> GetTapAdapters(const std::set<NetworkAdapter> &adapters); + + // + // Determines alias of primary TAP adapter. + // + static std::wstring GetTapInterfaceAlias(); +}; + +} diff --git a/windows/libshared/src/libshared/stdafx.cpp b/windows/libshared/src/libshared/stdafx.cpp new file mode 100644 index 0000000000..c418cf5096 --- /dev/null +++ b/windows/libshared/src/libshared/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// shared.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/windows/libshared/src/libshared/stdafx.h b/windows/libshared/src/libshared/stdafx.h new file mode 100644 index 0000000000..59e4616a97 --- /dev/null +++ b/windows/libshared/src/libshared/stdafx.h @@ -0,0 +1,15 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include <windows.h> +#include <string> +#include <sstream> +#include <algorithm> diff --git a/windows/libshared/src/libshared/targetver.h b/windows/libshared/src/libshared/targetver.h new file mode 100644 index 0000000000..ae4a5c032c --- /dev/null +++ b/windows/libshared/src/libshared/targetver.h @@ -0,0 +1,12 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include <WinSDKVer.h> + +#define _WIN32_WINNT _WIN32_WINNT_WIN7 + +#include <SDKDDKVer.h> |
