Compare commits

...
20 Commits
Author SHA1 Message Date
Adam Ierymenko b6248c7cb7 VERSION 0.4.4: multicast cleanup, Windows port work
In addition to a lot of Windows port work that isn't finished yet (and doesn't
affect the *nix platforms at all), this version contains quite a bit of multicast
cleanup and code simplification.

I also pulled rate limits for now, as it seems to be causing problems. More testing
on the testnet is going to be needed.
2013-08-23 10:54:45 -04:00
Adam Ierymenko f6e7be102a Decided to abandon the winpcap direction for Windows tap... re-evaluating using OpenVPN tap driver in some form for now. 2013-08-23 09:50:51 -04:00
Adam Ierymenko c8213a3f58 Commit of a draft of the pcap-based strategy for a Windows tap. This may, in the end, not work, since winpcap may not support immediate capture and also because some software flags winpcap as malware. Like I said, trying to do anything interesting with Windows is PAIN. 2013-08-22 22:33:32 -04:00
Adam Ierymenko d19516b40a Add winpcap development libraries and includes. 2013-08-22 16:42:17 -04:00
Adam Ierymenko ca5334509c Tap now creates Microsoft Loopback Adapter instances and tags them with a special ID... work in progress. 2013-08-22 14:30:55 -04:00
Adam Ierymenko a0a9d52213 Bug fix in multicast changes. 2013-08-21 14:51:32 -04:00
Adam Ierymenko 2efc9b31bd Huge convoluted logic de-tangling in multicast propagation, supernodes now do random propagation for more efficient coverage with less bias in sparse graph cases. 2013-08-21 11:45:06 -04:00
Adam Ierymenko 1d9977b8b9 A bit of code comment cleanup. 2013-08-21 10:19:34 -04:00
Adam Ierymenko edad580c32 Some work on Windows tap. 2013-08-21 10:18:05 -04:00
Adam Ierymenko 2536352e5d Make that an arbitrary tag to identify persistent taps... 2013-08-21 08:13:48 -04:00
Adam Ierymenko dbb509a302 Add an interface description to EthernetTap, mostly for Windows. 2013-08-19 17:44:46 -04:00
Adam Ierymenko 3daf73710a Add devcon 32-bit and 64-bit Windoze binaries. 2013-08-19 17:20:27 -04:00
Adam Ierymenko d372cd1b17 Clean up... 2013-08-19 15:39:11 -04:00
Adam Ierymenko ee7e826f0c On second thought... argh. 2013-08-16 16:37:01 -04:00
Adam Ierymenko d7bd3e37cb Add a fork of tap-windows from OpenVPN, will be customized. 2013-08-15 15:52:52 -04:00
Adam Ierymenko b23748aa5a Create devel project for Windows tap work. (Might be temporary.) 2013-08-15 15:51:03 -04:00
Adam Ierymenko 8584515a50 A few test build changes. 2013-08-14 13:30:27 -04:00
Adam Ierymenko 08fe84d707 Windows builds, self test runs in Debug mode! 2013-08-14 13:23:25 -04:00
Adam Ierymenko 150a53eb17 Self test almost builds, now need skeleton EthernetTap implementation for Windows. 2013-08-14 11:19:21 -04:00
Adam Ierymenko 1f9a7e26ba Move .vcxproj files to vsprojects\ subfolder and use Visual Studio's ability to add existing files to create per-tool solutions. Create self test solution to test basic functionality on Windows. 2013-08-14 10:29:20 -04:00
25 changed files with 1112 additions and 825 deletions

No files matched your search

+8 -4
View File
@@ -6,9 +6,13 @@ zerotier-*
*.dSYM
mac-tap/tuntap/src/tap/tap
mac-tap/tuntap/tap.kext
/ZeroTierOne.vcxproj.user
/ipch
/ZeroTierOne.sdf
/ZeroTierOne.v11.suo
/ZeroTierOne.opensdf
/Debug_32
/vsprojects/SelfTest/Debug
/vsprojects/SelfTest/Release
/Debug
/Release
*.log
*.opensdf
*.user
+45 -5
View File
@@ -1,18 +1,58 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZeroTierOne", "ZeroTierOne.vcxproj", "{0D4AE49A-FCE5-404F-8041-7FFC4DAF83F4}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SelfTest", "vsprojects\SelfTest\SelfTest.vcxproj", "{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
Vista Debug|Win32 = Vista Debug|Win32
Vista Debug|x64 = Vista Debug|x64
Vista Release|Win32 = Vista Release|Win32
Vista Release|x64 = Vista Release|x64
Win7 Debug|Win32 = Win7 Debug|Win32
Win7 Debug|x64 = Win7 Debug|x64
Win7 Release|Win32 = Win7 Release|Win32
Win7 Release|x64 = Win7 Release|x64
Win8 Debug|Win32 = Win8 Debug|Win32
Win8 Debug|x64 = Win8 Debug|x64
Win8 Release|Win32 = Win8 Release|Win32
Win8 Release|x64 = Win8 Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0D4AE49A-FCE5-404F-8041-7FFC4DAF83F4}.Debug|Win32.ActiveCfg = Debug_32|Win32
{0D4AE49A-FCE5-404F-8041-7FFC4DAF83F4}.Debug|Win32.Build.0 = Debug_32|Win32
{0D4AE49A-FCE5-404F-8041-7FFC4DAF83F4}.Release|Win32.ActiveCfg = Debug_32|Win32
{0D4AE49A-FCE5-404F-8041-7FFC4DAF83F4}.Release|Win32.Build.0 = Debug_32|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Debug|Win32.ActiveCfg = Release|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Debug|Win32.Build.0 = Release|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Debug|x64.ActiveCfg = Debug|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Release|Win32.ActiveCfg = Release|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Release|Win32.Build.0 = Release|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Release|x64.ActiveCfg = Release|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Debug|Win32.ActiveCfg = Debug|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Debug|Win32.Build.0 = Debug|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Debug|Win32.Deploy.0 = Debug|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Debug|x64.ActiveCfg = Debug|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Release|Win32.ActiveCfg = Release|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Release|Win32.Build.0 = Release|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Release|Win32.Deploy.0 = Release|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Release|x64.ActiveCfg = Release|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Debug|Win32.ActiveCfg = Debug|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Debug|Win32.Build.0 = Debug|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Debug|Win32.Deploy.0 = Debug|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Debug|x64.ActiveCfg = Debug|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Release|Win32.ActiveCfg = Release|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Release|Win32.Build.0 = Release|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Release|Win32.Deploy.0 = Release|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Release|x64.ActiveCfg = Release|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Debug|Win32.ActiveCfg = Debug|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Debug|Win32.Build.0 = Debug|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Debug|Win32.Deploy.0 = Debug|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Debug|x64.ActiveCfg = Debug|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Release|Win32.ActiveCfg = Release|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Release|Win32.Build.0 = Release|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Release|Win32.Deploy.0 = Release|Win32
{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Release|x64.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
-200
View File
@@ -1,200 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug_32|Win32">
<Configuration>Debug_32</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0D4AE49A-FCE5-404F-8041-7FFC4DAF83F4}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_32|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug_32|Win32'">
<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_32|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_32|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;__WINDOWS__;_WINDOWS;_USRDLL;ZEROTIERONE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<AdditionalIncludeDirectories>ext\bin\libcrypto\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>ext\bin\libcrypto\win32-vs2012\libeay32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="ext\kissdb\kissdb.c" />
<ClCompile Include="ext\lz4\lz4.c" />
<ClCompile Include="ext\lz4\lz4hc.c" />
<ClCompile Include="node\Defaults.cpp" />
<ClCompile Include="node\Demarc.cpp" />
<ClCompile Include="node\EllipticCurveKeyPair.cpp" />
<ClCompile Include="node\EthernetTap.cpp" />
<ClCompile Include="node\Filter.cpp" />
<ClCompile Include="node\HMAC.cpp" />
<ClCompile Include="node\Identity.cpp" />
<ClCompile Include="node\InetAddress.cpp" />
<ClCompile Include="node\Logger.cpp" />
<ClCompile Include="node\Network.cpp" />
<ClCompile Include="node\Node.cpp" />
<ClCompile Include="node\NodeConfig.cpp" />
<ClCompile Include="node\Packet.cpp" />
<ClCompile Include="node\PacketDecoder.cpp" />
<ClCompile Include="node\Peer.cpp" />
<ClCompile Include="node\Salsa20.cpp" />
<ClCompile Include="node\Service.cpp" />
<ClCompile Include="node\Switch.cpp" />
<ClCompile Include="node\SysEnv.cpp" />
<ClCompile Include="node\Topology.cpp" />
<ClCompile Include="node\UdpSocket.cpp" />
<ClCompile Include="node\Utils.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="ext\bin\libcrypto\include\openssl\aes.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\asn1.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\asn1t.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\asn1_mac.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\bio.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\blowfish.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\bn.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\buffer.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\camellia.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\cast.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\cmac.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\cms.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\comp.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\conf.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\conf_api.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\crypto.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\des.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\des_old.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\dh.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\dsa.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\dso.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\dtls1.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\ebcdic.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\ec.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\ecdh.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\ecdsa.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\engine.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\err.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\evp.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\e_os2.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\hmac.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\idea.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\krb5_asn.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\kssl.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\lhash.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\md4.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\md5.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\mdc2.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\modes.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\objects.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\obj_mac.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\ocsp.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\opensslconf.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\opensslv.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\ossl_typ.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\pem.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\pem2.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\pkcs12.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\pkcs7.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\pqueue.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\rand.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\rc2.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\rc4.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\ripemd.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\rsa.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\safestack.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\seed.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\sha.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\srp.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\srtp.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\ssl.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\ssl2.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\ssl23.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\ssl3.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\stack.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\symhacks.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\tls1.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\ts.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\txt_db.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\ui.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\ui_compat.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\whrlpool.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\x509.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\x509v3.h" />
<ClInclude Include="ext\bin\libcrypto\include\openssl\x509_vfy.h" />
<ClInclude Include="ext\kissdb\kissdb.h" />
<ClInclude Include="ext\lz4\lz4.h" />
<ClInclude Include="ext\lz4\lz4hc.h" />
<ClInclude Include="node\Address.hpp" />
<ClInclude Include="node\Array.hpp" />
<ClInclude Include="node\AtomicCounter.hpp" />
<ClInclude Include="node\BloomFilter.hpp" />
<ClInclude Include="node\Buffer.hpp" />
<ClInclude Include="node\CMWC4096.hpp" />
<ClInclude Include="node\Condition.hpp" />
<ClInclude Include="node\Constants.hpp" />
<ClInclude Include="node\Defaults.hpp" />
<ClInclude Include="node\Demarc.hpp" />
<ClInclude Include="node\Dictionary.hpp" />
<ClInclude Include="node\EllipticCurveKey.hpp" />
<ClInclude Include="node\EllipticCurveKeyPair.hpp" />
<ClInclude Include="node\EthernetTap.hpp" />
<ClInclude Include="node\Filter.hpp" />
<ClInclude Include="node\HMAC.hpp" />
<ClInclude Include="node\Identity.hpp" />
<ClInclude Include="node\InetAddress.hpp" />
<ClInclude Include="node\Logger.hpp" />
<ClInclude Include="node\MAC.hpp" />
<ClInclude Include="node\Multicaster.hpp" />
<ClInclude Include="node\MulticastGroup.hpp" />
<ClInclude Include="node\Mutex.hpp" />
<ClInclude Include="node\Network.hpp" />
<ClInclude Include="node\Node.hpp" />
<ClInclude Include="node\NodeConfig.hpp" />
<ClInclude Include="node\NonCopyable.hpp" />
<ClInclude Include="node\Packet.hpp" />
<ClInclude Include="node\PacketDecoder.hpp" />
<ClInclude Include="node\Peer.hpp" />
<ClInclude Include="node\Range.hpp" />
<ClInclude Include="node\RateLimiter.hpp" />
<ClInclude Include="node\RuntimeEnvironment.hpp" />
<ClInclude Include="node\Salsa20.hpp" />
<ClInclude Include="node\Service.hpp" />
<ClInclude Include="node\SharedPtr.hpp" />
<ClInclude Include="node\Switch.hpp" />
<ClInclude Include="node\SysEnv.hpp" />
<ClInclude Include="node\Thread.hpp" />
<ClInclude Include="node\Topology.hpp" />
<ClInclude Include="node\UdpSocket.hpp" />
<ClInclude Include="node\Utils.hpp" />
<ClInclude Include="version.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
-459
View File
@@ -1,459 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="ext\kissdb\kissdb.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ext\lz4\lz4.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ext\lz4\lz4hc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\Defaults.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\Demarc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\EllipticCurveKeyPair.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\EthernetTap.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\Filter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\HMAC.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\Identity.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\InetAddress.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\Logger.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\Network.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\Node.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\NodeConfig.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\Packet.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\PacketDecoder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\Peer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\Salsa20.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\Service.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\Switch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\SysEnv.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\Topology.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\UdpSocket.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="node\Utils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="version.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\aes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\asn1.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\asn1t.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\asn1_mac.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\bio.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\blowfish.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\bn.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\buffer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\camellia.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\cast.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\cmac.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\cms.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\comp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\conf.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\conf_api.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\crypto.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\des.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\des_old.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\dh.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\dsa.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\dso.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\dtls1.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\ebcdic.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\ec.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\ecdh.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\ecdsa.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\engine.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\err.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\evp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\e_os2.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\hmac.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\idea.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\krb5_asn.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\kssl.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\lhash.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\md4.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\md5.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\mdc2.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\modes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\objects.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\obj_mac.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\ocsp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\opensslconf.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\opensslv.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\ossl_typ.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\pem.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\pem2.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\pkcs12.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\pkcs7.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\pqueue.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\rand.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\rc2.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\rc4.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\ripemd.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\rsa.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\safestack.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\seed.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\sha.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\srp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\srtp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\ssl.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\ssl2.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\ssl23.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\ssl3.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\stack.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\symhacks.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\tls1.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\ts.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\txt_db.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\ui.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\ui_compat.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\whrlpool.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\x509.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\x509v3.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\bin\libcrypto\include\openssl\x509_vfy.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\kissdb\kissdb.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\lz4\lz4.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ext\lz4\lz4hc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Address.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Array.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\AtomicCounter.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\BloomFilter.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Buffer.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\CMWC4096.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Condition.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Constants.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Defaults.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Demarc.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Dictionary.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\EllipticCurveKey.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\EllipticCurveKeyPair.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\EthernetTap.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Filter.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\HMAC.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Identity.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\InetAddress.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Logger.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\MAC.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Multicaster.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\MulticastGroup.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Mutex.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Network.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Node.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\NodeConfig.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\NonCopyable.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Packet.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\PacketDecoder.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Peer.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Range.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\RateLimiter.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\RuntimeEnvironment.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Salsa20.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Service.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\SharedPtr.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Switch.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\SysEnv.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Thread.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Topology.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\UdpSocket.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="node\Utils.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
+7
View File
@@ -0,0 +1,7 @@
This is the Microsoft "devcon" utility, which as far as I know is
fair game to redistribute. It's packaged with OpenVPN and several
other things and also distributed in source code form as an example
program by Microsoft.
It's used to automatically install the Microsoft Loopback Adapter
or remove it when no longer needed.
Binary file not shown.
Binary file not shown.
+12 -1
View File
@@ -47,10 +47,21 @@ int KISSDB_open(
uint64_t *httmp;
uint64_t *hash_tables_rea;
#ifdef _WIN32
db->f = (FILE *)0;
fopen_s(&db->f,path,((mode == KISSDB_OPEN_MODE_RWREPLACE) ? "w+b" : (((mode == KISSDB_OPEN_MODE_RDWR)||(mode == KISSDB_OPEN_MODE_RWCREAT)) ? "r+b" : "rb")));
#else
db->f = fopen(path,((mode == KISSDB_OPEN_MODE_RWREPLACE) ? "w+b" : (((mode == KISSDB_OPEN_MODE_RDWR)||(mode == KISSDB_OPEN_MODE_RWCREAT)) ? "r+b" : "rb")));
#endif
if (!db->f) {
if (mode == KISSDB_OPEN_MODE_RWCREAT)
if (mode == KISSDB_OPEN_MODE_RWCREAT) {
#ifdef _WIN32
db->f = (FILE *)0;
fopen_s(&db->f,path,"w+b");
#else
db->f = fopen(path,"w+b");
#endif
}
if (!db->f)
return KISSDB_ERROR_IO;
}
+1
View File
@@ -71,6 +71,7 @@
#define NOMINMAX
#pragma warning(disable : 4290)
#pragma warning(disable : 4996)
#pragma warning(disable : 4101)
#undef __UNIX_LIKE__
#define ZT_PATH_SEPARATOR '\\'
#define ZT_PATH_SEPARATOR_S "\\"
+2 -2
View File
@@ -44,8 +44,8 @@
namespace ZeroTier {
const Demarc::Port Demarc::ANY_PORT;
const Demarc::Port Demarc::NULL_PORT;
const Demarc::Port Demarc::ANY_PORT = (Port)0xffffffffffffffffULL;
const Demarc::Port Demarc::NULL_PORT = (Port)0;
Demarc::Demarc(const RuntimeEnvironment *renv) :
_r(renv)
+2 -2
View File
@@ -64,12 +64,12 @@ public:
/**
* Port identifier used to refer to any port
*/
static const Port ANY_PORT = (Port)0xffffffffffffffffULL;
static const Port ANY_PORT;
/**
* Port identifier used to refer to null port / port not found
*/
static const Port NULL_PORT = (Port)0;
static const Port NULL_PORT;
Demarc(const RuntimeEnvironment *renv);
~Demarc();
+373 -1
View File
@@ -27,6 +27,8 @@
#include <string>
#include <map>
#include <set>
#include <algorithm>
#include "Constants.hpp"
#include "EthernetTap.hpp"
@@ -146,6 +148,7 @@ static Mutex __tapCreateLock;
#ifdef __LINUX__
EthernetTap::EthernetTap(
const RuntimeEnvironment *renv,
const char *tag,
const MAC &mac,
unsigned int mtu,
void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &),
@@ -246,6 +249,7 @@ EthernetTap::EthernetTap(
#ifdef __APPLE__
EthernetTap::EthernetTap(
const RuntimeEnvironment *renv,
const char *tag,
const MAC &mac,
unsigned int mtu,
void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &),
@@ -675,6 +679,374 @@ void EthernetTap::threadMain()
#ifdef __WINDOWS__
// TODO
#include <queue>
#include <WinSock2.h>
#include <Windows.h>
#include <iphlpapi.h>
#include <ws2ipdef.h>
#include <WS2tcpip.h>
#include <tchar.h>
#include <winreg.h>
namespace ZeroTier {
/* Background thread that handles I/O to/from all running
* EthernetTap instances using WinPcap -- this must be
* managed from a single thread because of the need to
* "reboot" npf every time a new interface is added. */
class _WinEthernetTapPcapIOThread
{
public:
_WinEthernetTapPcapIOThread()
{
scManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (scManager == NULL)
fprintf(stderr,"ZeroTier One: WARNING: unable to OpenSCManager(), tap will have issues with new devices!\r\n");
updateSem = CreateSemaphore(NULL,0,1,NULL); // binary
run = true;
needReload = false;
thread = Thread::start(this);
}
~_WinEthernetTapPcapIOThread()
{
run = false;
needReload = false;
ReleaseSemaphore(updateSem,1,NULL);
Thread::join(thread);
CloseHandle(updateSem);
if (scManager != NULL)
CloseServiceHandle(scManager);
}
void threadMain()
throw()
{
HANDLE *objects = new HANDLE[1];
objects[0] = updateSem;
DWORD numObjects = 1;
for(;;) {
if (!run) {
delete [] objects;
return;
}
printf("waiting on: %d\r\n",(int)numObjects);
WaitForMultipleObjects(numObjects,objects,FALSE,INFINITE);
{
Mutex::Lock _l(taps_m);
for(std::list<EthernetTap *>::iterator tapptr(taps.begin());tapptr!=taps.end();++tapptr) {
EthernetTap *tap = *tapptr;
if (tap->_pcap) {
{
Mutex::Lock _l2(tap->_injectPending_m);
while (!tap->_injectPending.empty()) {
pcap_sendpacket(tap->_pcap,(const u_char *)(tap->_injectPending.front().first.data),tap->_injectPending.front().second);
tap->_injectPending.pop();
}
}
printf("dispatch: %s\r\n",tap->_myDeviceInstanceId.c_str());
pcap_dispatch(tap->_pcap,-1,&EthernetTap::_pcapHandler,(u_char *)tap);
}
}
if (needReload) {
// Close all taps and restart WinPcap driver to scan for possible new
// interfaces... yuck. This is done because WinPcap does not support
// hot plug, so if we've added a new loopback adapter it won't show
// up without this full system refresh.
needReload = false;
for(std::list<EthernetTap *>::iterator tapptr(taps.begin());tapptr!=taps.end();++tapptr) {
if ((*tapptr)->_pcap) {
pcap_close((*tapptr)->_pcap);
(*tapptr)->_pcap = (pcap_t *)0;
}
}
if (scManager != NULL) {
Thread::sleep(250);
SC_HANDLE npfService = OpenServiceA(scManager,"npf",SERVICE_ALL_ACCESS);
if (npfService != NULL) {
SERVICE_STATUS sstatus;
memset(&sstatus,0,sizeof(SERVICE_STATUS));
ControlService(npfService,SERVICE_CONTROL_STOP,&sstatus);
printf("service restart\r\n");
CloseServiceHandle(npfService);
}
Thread::sleep(250);
}
delete [] objects;
objects = new HANDLE[taps.size() + 1];
objects[0] = updateSem;
numObjects = 1;
pcap_if_t *alldevs;
char pcaperrbuf[PCAP_ERRBUF_SIZE+1];
if (pcap_findalldevs(&alldevs,pcaperrbuf) != -1) {
for(std::list<EthernetTap *>::iterator tapptr(taps.begin());tapptr!=taps.end();++tapptr) {
EthernetTap *tap = *tapptr;
pcap_if_t *mydev = (pcap_if_t *)0;
for(mydev=alldevs;(mydev);mydev=mydev->next) {
if (strstr(mydev->name,tap->_myDeviceInstanceId.c_str()))
break;
}
if (mydev) {
tap->_pcap = pcap_open_live(mydev->name,65535,1,0,pcaperrbuf);
pcap_setnonblock(tap->_pcap,1,pcaperrbuf);
if (tap->_pcap) {
printf("pcap opened: %s\r\n",mydev->name);
objects[numObjects++] = pcap_getevent(tap->_pcap);
}
} else {
tap->_pcap = (pcap_t *)0;
}
}
pcap_freealldevs(alldevs);
}
}
}
if (!run) {
delete [] objects;
return;
}
}
}
inline void addTap(EthernetTap *t)
{
Mutex::Lock _l(taps_m);
taps.push_back(t);
needReload = true;
ReleaseSemaphore(updateSem,1,NULL);
}
inline void removeTap(EthernetTap *t)
{
Mutex::Lock _l(taps_m);
for(std::list<EthernetTap *>::iterator tapptr(taps.begin());tapptr!=taps.end();++tapptr) {
if (*tapptr == t) {
taps.erase(tapptr);
break;
}
}
needReload = true;
ReleaseSemaphore(updateSem,1,NULL);
}
std::list<EthernetTap *> taps;
Mutex taps_m;
SC_HANDLE scManager;
HANDLE updateSem;
volatile bool run;
volatile bool needReload;
Thread thread;
};
static _WinEthernetTapPcapIOThread _pcapIoThread;
static Mutex _systemTapInitLock;
EthernetTap::EthernetTap(
const RuntimeEnvironment *renv,
const char *tag,
const MAC &mac,
unsigned int mtu,
void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &),
void *arg)
throw(std::runtime_error) :
_mac(mac),
_mtu(mtu),
_r(renv),
_handler(handler),
_arg(arg),
_pcap((pcap_t *)0)
{
char subkeyName[1024];
char subkeyClass[1024];
char data[1024];
Mutex::Lock _l(_systemTapInitLock); // only do one at a time, process-wide
HKEY nwAdapters;
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",0,KEY_READ|KEY_WRITE,&nwAdapters) != ERROR_SUCCESS)
throw std::runtime_error("unable to open registry key for network adapter enumeration");
std::set<std::string> existingDeviceInstances;
// Enumerate all Microsoft Loopback Adapter instances and look for one
// that matches our tag.
for(DWORD subkeyIndex=0;subkeyIndex!=-1;) {
DWORD type;
DWORD dataLen;
DWORD subkeyNameLen = sizeof(subkeyName);
DWORD subkeyClassLen = sizeof(subkeyClass);
FILETIME lastWriteTime;
switch (RegEnumKeyExA(nwAdapters,subkeyIndex++,subkeyName,&subkeyNameLen,(DWORD *)0,subkeyClass,&subkeyClassLen,&lastWriteTime)) {
case ERROR_NO_MORE_ITEMS: subkeyIndex = -1; break;
case ERROR_SUCCESS:
type = 0;
dataLen = sizeof(data);
if (RegGetValueA(nwAdapters,subkeyName,"ComponentId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
data[dataLen] = '\0';
if (!strcmpi(data,"*msloop")) {
std::string instanceId;
type = 0;
dataLen = sizeof(data);
if (RegGetValueA(nwAdapters,subkeyName,"NetCfgInstanceId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
instanceId.assign(data,dataLen);
existingDeviceInstances.insert(instanceId);
}
if ((_myDeviceInstanceId.length() == 0)&&(instanceId.length() != 0)) {
type = 0;
dataLen = sizeof(data);
if (RegGetValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
data[dataLen] = '\0';
if (!strcmp(data,tag)) {
type = 0;
dataLen = sizeof(data);
if (RegGetValueA(nwAdapters,subkeyName,"NetCfgInstanceId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
_myDeviceInstanceId = instanceId;
subkeyIndex = -1; // break outer loop
}
}
}
}
}
}
break;
}
}
// If there is no device, try to create one
if (_myDeviceInstanceId.length() == 0) {
// Execute devcon to install an instance of the Microsoft Loopback Adapter
#ifdef _WIN64
const char *devcon = "\\devcon64.exe";
#else
BOOL f64 = FALSE;
const char *devcon = ((IsWow64Process(GetCurrentProcess(),&f64) == TRUE) ? "\\devcon64.exe" : "\\devcon32.exe");
#endif
char windir[4096];
windir[0] = '\0';
GetWindowsDirectoryA(windir,sizeof(windir));
STARTUPINFOA startupInfo;
startupInfo.cb = sizeof(startupInfo);
PROCESS_INFORMATION processInfo;
memset(&startupInfo,0,sizeof(STARTUPINFOA));
memset(&processInfo,0,sizeof(PROCESS_INFORMATION));
if (!CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" install " + windir + "\\inf\\netloop.inf *msloop").c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) {
RegCloseKey(nwAdapters);
throw std::runtime_error(std::string("unable to find or execute devcon at ")+devcon);
}
WaitForSingleObject(processInfo.hProcess,INFINITE);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
// Scan for that new instance by looking for adapters of type
// *msloop that we did not already see on the first scan.
for(DWORD subkeyIndex=0;subkeyIndex!=-1;) {
DWORD type;
DWORD dataLen;
DWORD subkeyNameLen = sizeof(subkeyName);
DWORD subkeyClassLen = sizeof(subkeyClass);
FILETIME lastWriteTime;
switch (RegEnumKeyExA(nwAdapters,subkeyIndex++,subkeyName,&subkeyNameLen,(DWORD *)0,subkeyClass,&subkeyClassLen,&lastWriteTime)) {
case ERROR_NO_MORE_ITEMS: subkeyIndex = -1; break;
case ERROR_SUCCESS:
type = 0;
dataLen = sizeof(data);
if (RegGetValueA(nwAdapters,subkeyName,"ComponentId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
data[dataLen] = '\0';
if (!strcmpi(data,"*msloop")) {
type = 0;
dataLen = sizeof(data);
if (RegGetValueA(nwAdapters,subkeyName,"NetCfgInstanceId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
if (existingDeviceInstances.count(std::string(data,dataLen)) == 0) {
RegSetKeyValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",REG_SZ,tag,strlen(tag)+1);
_myDeviceInstanceId.assign(data,dataLen);
subkeyIndex = -1; // break outer loop
}
}
}
}
break;
}
}
}
RegCloseKey(nwAdapters);
if (_myDeviceInstanceId.length() == 0)
throw std::runtime_error("unable to create new loopback adapter for tap");
// pcap is opened and managed by the pcap I/O thread
_pcapIoThread.addTap(this);
}
EthernetTap::~EthernetTap()
{
_pcapIoThread.removeTap(this);
if (_pcap)
pcap_close(_pcap);
}
void EthernetTap::whack()
{
}
bool EthernetTap::addIP(const InetAddress &ip)
{
return false;
}
bool EthernetTap::removeIP(const InetAddress &ip)
{
return false;
}
void EthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
{
if (len > (ZT_IF_MTU))
return;
{
Mutex::Lock _l(_injectPending_m);
_injectPending.push( std::pair<Array<char,ZT_IF_MTU + 32>,unsigned int>(Array<char,ZT_IF_MTU + 32>(),len + 14) );
char *d = _injectPending.back().first.data;
memcpy(d,to.data,6);
memcpy(d + 6,from.data,6);
*((uint16_t *)(d + 12)) = Utils::hton(etherType);
memcpy(d + 14,data,len);
}
ReleaseSemaphore(_pcapIoThread.updateSem,1,NULL);
}
std::string EthernetTap::deviceName() const
{
return _myDeviceInstanceId;
}
bool EthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
{
// TODO
return false;
}
void EthernetTap::_pcapHandler(u_char *user,const struct pcap_pkthdr *pkt_header,const u_char *pkt_data)
{
printf("got packet: %d\r\n",(int)pkt_header->len);
if (pkt_header->len > 14)
((EthernetTap *)user)->_handler(((EthernetTap *)user)->_arg,MAC(pkt_data + 6),MAC(pkt_data),Utils::ntoh(*((const uint16_t *)(pkt_data + 12))),Buffer<4096>(pkt_data + 14,pkt_header->len - 14));
}
} // namespace ZeroTier
#endif // __WINDOWS__
+31 -1
View File
@@ -30,12 +30,15 @@
#include <stdio.h>
#include <stdlib.h>
#include <map>
#include <list>
#include <vector>
#include <set>
#include <string>
#include <queue>
#include <stdexcept>
#include "Constants.hpp"
#include "InetAddress.hpp"
#include "MAC.hpp"
@@ -43,16 +46,30 @@
#include "MulticastGroup.hpp"
#include "Thread.hpp"
#include "Buffer.hpp"
#include "Array.hpp"
#ifdef __WINDOWS__
#include <pcap/pcap.h>
#include <pcap/bpf.h>
#include <Win32-Extensions.h>
#endif
namespace ZeroTier {
class RuntimeEnvironment;
#ifdef __WINDOWS__
class _WinEthernetTapPcapIOThread;
#endif
/**
* System ethernet tap device
*/
class EthernetTap
{
#ifdef __WINDOWS__
friend class _WinEthernetTapPcapIOThread;
#endif
public:
/**
* Construct a new TAP device
@@ -60,14 +77,17 @@ public:
* Handler arguments: arg,from,to,etherType,data
*
* @param renv Runtime environment
* @param tag A tag used to identify persistent taps at the OS layer (e.g. nwid in hex)
* @param mac MAC address of device
* @param mtu MTU of device
* @param desc If non-NULL, a description (not used on all OSes)
* @param handler Handler function to be called when data is received from the tap
* @param arg First argument to handler function
* @throws std::runtime_error Unable to allocate device
*/
EthernetTap(
const RuntimeEnvironment *renv,
const char *tag,
const MAC &mac,
unsigned int mtu,
void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &),
@@ -169,18 +189,19 @@ public:
*/
bool updateMulticastGroups(std::set<MulticastGroup> &groups);
#ifdef __UNIX_LIKE__
/**
* Thread main method; do not call elsewhere
*/
void threadMain()
throw();
#endif
private:
const MAC _mac;
const unsigned int _mtu;
const RuntimeEnvironment *_r;
Thread _thread;
std::set<InetAddress> _ips;
Mutex _ips_m;
@@ -189,10 +210,19 @@ private:
void *_arg;
#ifdef __UNIX_LIKE__
Thread _thread;
char _dev[16];
int _fd;
int _shutdownSignalPipe[2];
#endif
#ifdef __WINDOWS__
pcap_t *_pcap;
std::string _myDeviceInstanceId;
std::queue< std::pair< Array<char,ZT_IF_MTU + 32>,unsigned int > > _injectPending;
Mutex _injectPending_m;
static void _pcapHandler(u_char *user,const struct pcap_pkthdr *pkt_header,const u_char *pkt_data);
#endif
};
} // namespace ZeroTier
+80 -28
View File
@@ -206,8 +206,9 @@ public:
}
/**
* Choose peers to send a propagating multicast to
* Choose peers for multicast propagation via random selection
*
* @param prng Random source
* @param topology Topology object or mock thereof
* @param nwid Network ID
* @param mg Multicast group
@@ -222,7 +223,68 @@ public:
* @tparam P Type of peers, which is SharedPtr<Peer> in running code or a mock in simulation (mock must behave like a pointer type)
*/
template<typename T,typename P>
inline unsigned int pickNextPropagationPeers(
inline unsigned int pickRandomPropagationPeers(
CMWC4096 &prng,
T &topology,
uint64_t nwid,
const MulticastGroup &mg,
const Address &originalSubmitter,
const Address &upstream,
MulticastBloomFilter &bf,
unsigned int max,
P *peers,
uint64_t now)
{
unsigned int chosen = 0;
Mutex::Lock _l(_multicastMemberships_m);
std::map< MulticastChannel,std::vector<MulticastMembership> >::iterator mm(_multicastMemberships.find(MulticastChannel(nwid,mg)));
if ((mm != _multicastMemberships.end())&&(!mm->second.empty())) {
for(unsigned int stries=0;((stries<ZT_MULTICAST_PICK_MAX_SAMPLE_SIZE)&&(chosen < max));++stries) {
MulticastMembership &m = mm->second[prng.next32() % mm->second.size()];
unsigned int sum = m.first.sum();
if (
((now - m.second) < ZT_MULTICAST_LIKE_EXPIRE)&& /* LIKE is not expired */
(!bf.contains(sum))&& /* Not in propagation bloom */
(m.first != originalSubmitter)&& /* Not the original submitter */
(m.first != upstream) ) { /* Not where the frame came from */
P peer(topology.getPeer(m.first));
if (peer) {
unsigned int chk = 0;
while (chk < chosen) {
if (peers[chk] == peer)
break;
++chk;
}
if (chk == chosen) { /* not already picked */
peers[chosen++] = peer;
bf.set(sum);
}
}
}
}
}
return chosen;
}
/**
* Choose peers for multicast propagation via implicit social switching
*
* @param prng Random source
* @param topology Topology object or mock thereof
* @param nwid Network ID
* @param mg Multicast group
* @param originalSubmitter Original submitter of multicast message to network
* @param upstream Address from which message originated, or null (0) address if none
* @param bf Bloom filter, updated in place with sums of addresses in chosen peers and/or decay
* @param max Maximum number of peers to pick
* @param peers Array of objects of type P to fill with up to [max] peers
* @param now Current timestamp
* @return Number of peers actually stored in peers array
* @tparam T Type of topology, which is Topology in running code or a mock in simulation
* @tparam P Type of peers, which is SharedPtr<Peer> in running code or a mock in simulation (mock must behave like a pointer type)
*/
template<typename T,typename P>
inline unsigned int pickSocialPropagationPeers(
CMWC4096 &prng,
T &topology,
uint64_t nwid,
@@ -236,49 +298,39 @@ public:
{
typename std::set< P,_PeerPropagationPrioritySortOrder<P> > toConsider;
// Pick up to ZT_MULTICAST_PICK_MAX_SAMPLE_SIZE peers that have
// subscribed to this channel and that are not in bloom filter.
// Pick randomly from subscribers, but place into a set that is
// sorted in descending order of time of most recent unicast
// frame transfer. (Implicit social ordering.) Also ignore original
// submitter and upstream, since we know these have seen this
// message.
/* Pick up to ZT_MULTICAST_PICK_MAX_SAMPLE_SIZE peers that meet
* our minimal criteria for this multicast group and place them
* into a set that is sorted in descending order of time of most
* recent unicast frame transfer (implicit social ordering). */
{
Mutex::Lock _l(_multicastMemberships_m);
std::map< MulticastChannel,std::vector<MulticastMembership> >::iterator mm(_multicastMemberships.find(MulticastChannel(nwid,mg)));
if ((mm != _multicastMemberships.end())&&(!mm->second.empty())) {
for(unsigned int stries=0;stries<ZT_MULTICAST_PICK_MAX_SAMPLE_SIZE;++stries) {
MulticastMembership &m = mm->second[prng.next32() % mm->second.size()];
if (((now - m.second) < ZT_MULTICAST_LIKE_EXPIRE)&&(!bf.contains(m.first.sum()))&&(m.first != originalSubmitter)&&(m.first != upstream)) {
if (
((now - m.second) < ZT_MULTICAST_LIKE_EXPIRE)&& /* LIKE is not expired */
(!bf.contains(m.first.sum()))&& /* Not in propagation bloom */
(m.first != originalSubmitter)&& /* Not the original submitter */
(m.first != upstream) ) { /* Not where the frame came from */
P peer(topology.getPeer(m.first));
if (peer)
toConsider.insert(peer);
toConsider.insert(peer); /* Consider propagating to this peer */
}
}
}
}
// The first peers in toConsider will be the 'best'
/* The first peers in toConsider will be the "best" */
unsigned int chosen = 0;
for(typename std::set< P,_PeerPropagationPrioritySortOrder<P> >::iterator i(toConsider.begin());((i!=toConsider.end())&&(chosen < max));++i)
bf.set((peers[chosen++] = *i)->address().sum());
// Add a supernode if there are fewer than the desired
// number of recipients. Note that we do not use the bloom
// filter to track visits to supernodes, intentionally
// allowing multicasts to ping pong between supernodes.
// Supernodes propagate even messages they've already seen,
// while regular nodes do not. Thus this ping-ponging will
// cause the supernodes to pick new starting points for
// peer to peer graph traversal multiple times. It's a
// simple, stateless way to increase supernode-driven
// propagation of a multicast in the event that peer to
// peer connectivity for its group is sparse.
if (chosen < max) {
Address avoid[2];
avoid[0] = originalSubmitter;
avoid[1] = upstream;
P peer = topology.getBestSupernode(avoid,2,true);
/* Tack on a supernode if we have no next hops */
if (!chosen) {
Address exclude[1];
exclude[0] = originalSubmitter; // if it came from a supernode, don't boomerang
P peer = topology.getBestSupernode(exclude,1,true);
if (peer)
peers[chosen++] = peer;
}
+4 -1
View File
@@ -139,6 +139,9 @@ Network::~Network()
SharedPtr<Network> Network::newInstance(const RuntimeEnvironment *renv,uint64_t id)
throw(std::runtime_error)
{
char tag[32];
sprintf(tag,"%.16llx",(unsigned long long)id);
// We construct Network via a static method to ensure that it is immediately
// wrapped in a SharedPtr<>. Otherwise if there is traffic on the Ethernet
// tap device, a SharedPtr<> wrap can occur in the Ethernet frame handler
@@ -150,7 +153,7 @@ SharedPtr<Network> Network::newInstance(const RuntimeEnvironment *renv,uint64_t
nw->_rlLimit.bytesPerSecond = ZT_MULTICAST_DEFAULT_BYTES_PER_SECOND;
nw->_rlLimit.maxBalance = ZT_MULTICAST_DEFAULT_RATE_MAX_BALANCE;
nw->_rlLimit.minBalance = ZT_MULTICAST_DEFAULT_RATE_MIN_BALANCE;
nw->_tap = new EthernetTap(renv,renv->identity.address().toMAC(),ZT_IF_MTU,&_CBhandleTapData,nw.ptr());
nw->_tap = new EthernetTap(renv,tag,renv->identity.address().toMAC(),ZT_IF_MTU,&_CBhandleTapData,nw.ptr());
nw->_id = id;
nw->_lastConfigUpdate = 0;
nw->_destroyOnDelete = false;
+1 -1
View File
@@ -351,7 +351,7 @@ Node::ReasonForTermination Node::run()
// Make sure networks.d exists
#ifdef __WINDOWS__
CreateDirectory((_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d").c_str(),NULL);
CreateDirectoryA((_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d").c_str(),NULL);
#else
mkdir((_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d").c_str(),0700);
#endif
+119 -113
View File
@@ -105,7 +105,7 @@ bool PacketDecoder::tryDecode(const RuntimeEnvironment *_r)
TRACE("NOP from %s(%s)",source().toString().c_str(),_remoteAddress.toString().c_str());
return true;
case Packet::VERB_HELLO:
return _doHELLO(_r); // encrypted HELLO is technically allowed, but kind of pointless... :)
return _doHELLO(_r);
case Packet::VERB_ERROR:
return _doERROR(_r,peer);
case Packet::VERB_OK:
@@ -238,29 +238,16 @@ bool PacketDecoder::_doHELLO(const RuntimeEnvironment *_r)
uint64_t timestamp = at<uint64_t>(ZT_PROTO_VERB_HELLO_IDX_TIMESTAMP);
Identity id(*this,ZT_PROTO_VERB_HELLO_IDX_IDENTITY);
// Create a new candidate peer that we might decide to add to our
// database. We create it now since we want its keys to send replies
// even in the error case, and the code for keying is in Peer.
SharedPtr<Peer> candidate(new Peer(_r->identity,id));
candidate->setPathAddress(_remoteAddress,false);
// The initial sniff test... is the identity valid, and is it
// the sender's identity?
// Initial sniff test for valid addressing and that this is indeed the
// submitter's identity.
if ((id.address().isReserved())||(id.address() != source())) {
#ifdef ZT_TRACE
if (id.address().isReserved()) {
TRACE("rejected HELLO from %s(%s): identity has reserved address",source().toString().c_str(),_remoteAddress.toString().c_str());
TRACE("dropped HELLO from %s(%s): identity has reserved address",source().toString().c_str(),_remoteAddress.toString().c_str());
} else {
TRACE("rejected HELLO from %s(%s): identity is not for sender of packet (HELLO is a self-announcement)",source().toString().c_str(),_remoteAddress.toString().c_str());
TRACE("dropped HELLO from %s(%s): identity is not for sender of packet (HELLO is a self-announcement)",source().toString().c_str(),_remoteAddress.toString().c_str());
}
#endif
Packet outp(source(),_r->identity.address(),Packet::VERB_ERROR);
outp.append((unsigned char)Packet::VERB_HELLO);
outp.append(packetId());
outp.append((unsigned char)((id.address().isReserved()) ? Packet::ERROR_IDENTITY_INVALID : Packet::ERROR_INVALID_REQUEST));
outp.encrypt(candidate->cryptKey());
outp.hmacSet(candidate->macKey());
_r->demarc->send(_localPort,_remoteAddress,outp.data(),outp.size(),-1);
return true;
}
@@ -281,9 +268,9 @@ bool PacketDecoder::_doHELLO(const RuntimeEnvironment *_r)
return true;
}
// Otherwise we call addPeer() and set up a callback to handle the verdict.
// Topology evaluates the peer in the background, possibly doing the entire
// expensive analysis before determining whether to add it to the database.
SharedPtr<Peer> candidate(new Peer(_r->identity,id));
candidate->setPathAddress(_remoteAddress,false);
_CBaddPeerFromHello_Data *arg = new _CBaddPeerFromHello_Data;
arg->renv = _r;
arg->source = source();
@@ -319,16 +306,15 @@ bool PacketDecoder::_doOK(const RuntimeEnvironment *_r,const SharedPtr<Peer> &pe
if (_r->topology->isSupernode(source())) {
// Right now, only supernodes are queried for WHOIS so we only
// accept OK(WHOIS) from supernodes. Otherwise peers could
// potentially cache-poison. A more elegant but memory-intensive
// solution would be to remember packet IDs of WHOIS requests.
// potentially cache-poison.
_r->topology->addPeer(SharedPtr<Peer>(new Peer(_r->identity,Identity(*this,ZT_PROTO_VERB_WHOIS__OK__IDX_IDENTITY))),&PacketDecoder::_CBaddPeerFromWhois,const_cast<void *>((const void *)_r));
}
} break;
case Packet::VERB_NETWORK_CONFIG_REQUEST: {
SharedPtr<Network> nw(_r->nc->network(at<uint64_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_NETWORK_ID)));
if ((nw)&&(nw->controller() == source())) {
// Only accept OK(NETWORK_CONFIG_REQUEST) from masters for
// networks we have.
// OK(NETWORK_CONFIG_REQUEST) is only accepted from a network's
// controller.
unsigned int dictlen = at<uint16_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT_LEN);
std::string dict((const char *)field(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT,dictlen),dictlen);
if (dict.length()) {
@@ -396,8 +382,7 @@ bool PacketDecoder::_doRENDEZVOUS(const RuntimeEnvironment *_r,const SharedPtr<P
* packet, but it's still maybe something we want to not allow just
* anyone to order due to possible DDOS or network forensic implications.
* So if we diversify relays, we'll need some way of deciding whether the
* sender is someone we should trust with a RENDEZVOUS hint. Or maybe
* we just need rate limiting to prevent DDOS and amplification attacks.
* sender is someone we should trust with a RENDEZVOUS hint.
*/
if (_r->topology->isSupernode(source())) {
Address with(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
@@ -469,10 +454,7 @@ bool PacketDecoder::_doMULTICAST_LIKE(const RuntimeEnvironment *_r,const SharedP
//TRACE("peer %s likes multicast group %s:%.8lx on network %llu",source().toString().c_str(),mac.toString().c_str(),(unsigned long)adi,nwid);
_r->multicaster->likesMulticastGroup(nwid,MulticastGroup(mac,adi),source(),now);
++numAccepted;
} else {
ptr += 10;
TRACE("ignored MULTICAST_LIKE from %s(%s): network %.16llx unknown, or sender is not a member of network",source().toString().c_str(),_remoteAddress.toString().c_str(),(unsigned long long)nwid);
}
} else ptr += 10;
}
Packet outp(source(),_r->identity.address(),Packet::VERB_OK);
@@ -496,6 +478,24 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared
SharedPtr<Network> network(_r->nc->network(at<uint64_t>(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_NETWORK_ID)));
if ((network)&&(network->isAllowed(source()))) {
Address originalSubmitterAddress(field(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SUBMITTER_ADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
if (originalSubmitterAddress.isReserved()) {
TRACE("dropped MULTICAST_FRAME from original submitter %s, received from %s(%s): invalid original submitter address",originalSubmitterAddress.toString().c_str(),source().toString().c_str(),_remoteAddress.toString().c_str());
return true;
}
if (originalSubmitterAddress == _r->identity.address()) {
TRACE("dropped MULTICAST_FRAME from original submitter %s, received from %s(%s): boomerang!",originalSubmitterAddress.toString().c_str(),source().toString().c_str(),_remoteAddress.toString().c_str());
return true;
}
SharedPtr<Peer> originalSubmitter(_r->topology->getPeer(originalSubmitterAddress));
if (!originalSubmitter) {
TRACE("requesting WHOIS on original multicast frame submitter %s",originalSubmitterAddress.toString().c_str());
_r->sw->requestWhois(originalSubmitterAddress);
_step = DECODE_WAITING_FOR_MULTICAST_FRAME_ORIGINAL_SENDER_LOOKUP;
return false; // try again if/when we get OK(WHOIS)
}
MAC fromMac(field(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SOURCE_MAC,6));
MulticastGroup mg(MAC(field(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DESTINATION_MAC,6)),at<uint32_t>(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ADI));
unsigned int hops = (*this)[ZT_PROTO_VERB_MULTICAST_FRAME_IDX_HOP_COUNT];
@@ -504,94 +504,100 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared
unsigned int signaturelen = at<uint16_t>(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SIGNATURE_LENGTH);
unsigned char *dataAndSignature = field(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PAYLOAD,datalen + signaturelen);
if (!Multicaster::verifyMulticastPacket(originalSubmitter->identity(),network->id(),fromMac,mg,etherType,dataAndSignature,datalen,dataAndSignature + datalen,signaturelen)) {
LOG("dropped MULTICAST_FRAME from original submitter %s, received from %s(%s): FAILED SIGNATURE CHECK (spoofed original submitter?)",originalSubmitterAddress.toString().c_str(),source().toString().c_str(),_remoteAddress.toString().c_str());
return true;
}
if (++hops >= ZT_MULTICAST_PROPAGATION_DEPTH) {
TRACE("dropped MULTICAST_FRAME from original submitter %s, received from %s(%s): max depth reached",originalSubmitterAddress.toString().c_str(),source().toString().c_str(),_remoteAddress.toString().c_str());
return true;
}
uint64_t mccrc = Multicaster::computeMulticastDedupCrc(network->id(),fromMac,mg,etherType,dataAndSignature,datalen);
uint64_t now = Utils::now();
bool isDuplicate = _r->multicaster->checkDuplicate(mccrc,now);
if (originalSubmitterAddress == _r->identity.address()) {
// Technically should not happen, since the original submitter is
// excluded from consideration as a propagation recipient.
TRACE("dropped boomerang MULTICAST_FRAME received from %s(%s)",source().toString().c_str(),_remoteAddress.toString().c_str());
} else if ((!isDuplicate)||(_r->topology->amSupernode())) {
//
// If I am a supernode, I will repeatedly propagate duplicates. That's
// because supernodes are used to bridge sparse multicast groups. Non-
// supernodes will ignore duplicates completely.
//
// TODO: supernodes should keep a local bloom filter too and OR it with
// the bloom from the packet in order to pick different recipients each
// time a multicast returns to them for repropagation.
//
if (!isDuplicate) {
//if (network->multicastRateGate(originalSubmitterAddress,datalen)) {
network->tap().put(fromMac,mg.mac(),etherType,dataAndSignature,datalen);
//} else {
// TRACE("dropped MULTICAST_FRAME from original submitter %s, received from %s(%s): sender rate limit exceeded",originalSubmitterAddress.toString().c_str(),source().toString().c_str(),_remoteAddress.toString().c_str());
// return true;
//}
SharedPtr<Peer> originalSubmitter(_r->topology->getPeer(originalSubmitterAddress));
if (!originalSubmitter) {
TRACE("requesting WHOIS on original multicast frame submitter %s",originalSubmitterAddress.toString().c_str());
_r->sw->requestWhois(originalSubmitterAddress);
_step = DECODE_WAITING_FOR_MULTICAST_FRAME_ORIGINAL_SENDER_LOOKUP;
return false; // try again if/when we get OK(WHOIS)
} else if (Multicaster::verifyMulticastPacket(originalSubmitter->identity(),network->id(),fromMac,mg,etherType,dataAndSignature,datalen,dataAndSignature + datalen,signaturelen)) {
// In checking the multicast rate, we don't re-check if this is
// a duplicate. That's because if isDuplicate is true it means
// we're a supernode and it's a second pass relay.
if ((isDuplicate)||(network->multicastRateGate(originalSubmitter->address(),datalen))) {
_r->multicaster->addToDedupHistory(mccrc,now);
// Even if we are a supernode, we still don't repeatedly inject
// duplicates into our own tap.
if (!isDuplicate)
network->tap().put(fromMac,mg.mac(),etherType,dataAndSignature,datalen);
if (++hops < ZT_MULTICAST_PROPAGATION_DEPTH) {
Address upstream(source()); // save this since we mangle it
Multicaster::MulticastBloomFilter bloom(field(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_BLOOM_FILTER,ZT_PROTO_VERB_MULTICAST_FRAME_BLOOM_FILTER_SIZE_BYTES));
SharedPtr<Peer> propPeers[ZT_MULTICAST_PROPAGATION_BREADTH];
unsigned int np = _r->multicaster->pickNextPropagationPeers(
*(_r->prng),
*(_r->topology),
network->id(),
mg,
originalSubmitterAddress,
upstream,
bloom,
ZT_MULTICAST_PROPAGATION_BREADTH,
propPeers,
now);
// In a bit of a hack, we re-use this packet to repeat it
// to our multicast propagation recipients. Afterwords we
// return true just to be sure this is the end of this
// packet's life cycle, since it is now mangled.
setSource(_r->identity.address());
(*this)[ZT_PROTO_VERB_MULTICAST_FRAME_IDX_HOP_COUNT] = hops;
memcpy(field(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_BLOOM_FILTER,ZT_PROTO_VERB_MULTICAST_FRAME_BLOOM_FILTER_SIZE_BYTES),bloom.data(),ZT_PROTO_VERB_MULTICAST_FRAME_BLOOM_FILTER_SIZE_BYTES);
compress();
for(unsigned int i=0;i<np;++i) {
//TRACE("propagating multicast from original node %s: %s -> %s",originalSubmitterAddress.toString().c_str(),upstream.toString().c_str(),propPeers[i]->address().toString().c_str());
// Re-use this packet to re-send multicast frame to everyone
// downstream from us.
newInitializationVector();
setDestination(propPeers[i]->address());
_r->sw->send(*this,true);
}
// Return here just to be safe, since this packet's state is no
// longer valid.
return true;
} else {
//TRACE("terminating MULTICAST_FRAME propagation from %s(%s): max depth reached",source().toString().c_str(),_remoteAddress.toString().c_str());
}
} else {
LOG("dropped MULTICAST_FRAME from original sender %s: rate limit overrun",originalSubmitter->address().toString().c_str());
}
} else {
TRACE("rejected MULTICAST_FRAME forwarded by %s(%s): failed signature check (falsely claims origin %s)",source().toString().c_str(),_remoteAddress.toString().c_str(),originalSubmitterAddress.toString().c_str());
}
} else {
TRACE("dropped duplicate MULTICAST_FRAME from %s(%s)",source().toString().c_str(),_remoteAddress.toString().c_str());
/* It's important that we do this *after* rate limit checking,
* otherwise supernodes could be used to execute a flood by
* first bouncing a multicast off a supernode and then flooding
* it with retransmits. */
_r->multicaster->addToDedupHistory(mccrc,now);
}
Address upstream(source()); // save this since we might mangle it below
Multicaster::MulticastBloomFilter bloom(field(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_BLOOM_FILTER,ZT_PROTO_VERB_MULTICAST_FRAME_BLOOM_FILTER_SIZE_BYTES));
SharedPtr<Peer> propPeers[ZT_MULTICAST_PROPAGATION_BREADTH];
unsigned int np = 0;
if (_r->topology->amSupernode()) {
/* Supernodes behave differently here from ordinary nodes, as their
* role in the network is to bridge gaps between unconnected islands
* in a multicast propagation graph. Instead of using the ordinary
* multicast peer picker, supernodes propagate to random unvisited
* peers. They will also repeatedly propagate duplicate multicasts to
* new peers, while regular nodes simply discard them. This allows
* such gaps to be bridged more than once by ping-ponging off the
* same supernode -- a simple way to implement this without requiring
* that supernodes maintain a lot of state at the cost of a small
* amount of bandwidth. */
np = _r->multicaster->pickRandomPropagationPeers(
*(_r->prng),
*(_r->topology),
network->id(),
mg,
originalSubmitterAddress,
upstream,
bloom,
ZT_MULTICAST_PROPAGATION_BREADTH,
propPeers,
now);
} else if (isDuplicate) {
TRACE("dropped MULTICAST_FRAME from original submitter %s, received from %s(%s): duplicate",originalSubmitterAddress.toString().c_str(),source().toString().c_str(),_remoteAddress.toString().c_str());
return true;
} else {
/* Regular peers only propagate non-duplicate packets, and do so
* according to ordinary propagation priority rules. */
np = _r->multicaster->pickSocialPropagationPeers(
*(_r->prng),
*(_r->topology),
network->id(),
mg,
originalSubmitterAddress,
upstream,
bloom,
ZT_MULTICAST_PROPAGATION_BREADTH,
propPeers,
now);
}
/* Re-use *this* packet to repeat it to our propagation
* recipients, which invalidates its current contents and
* state. */
if (np) {
setSource(_r->identity.address());
(*this)[ZT_PROTO_VERB_MULTICAST_FRAME_IDX_HOP_COUNT] = hops;
memcpy(field(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_BLOOM_FILTER,ZT_PROTO_VERB_MULTICAST_FRAME_BLOOM_FILTER_SIZE_BYTES),bloom.data(),ZT_PROTO_VERB_MULTICAST_FRAME_BLOOM_FILTER_SIZE_BYTES);
compress();
for(unsigned int i=0;i<np;++i) {
newInitializationVector();
setDestination(propPeers[i]->address());
_r->sw->send(*this,true);
}
}
/* Just to be safe, return true here to terminate processing as we
* have thoroughly destroyed our state by doing the above. */
return true;
} else {
TRACE("dropped MULTICAST_FRAME from %s(%s): network %.16llx unknown or sender not allowed",source().toString().c_str(),_remoteAddress.toString().c_str(),(unsigned long long)network->id());
}
+1 -1
View File
@@ -108,7 +108,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
Multicaster::MulticastBloomFilter bloom;
SharedPtr<Peer> propPeers[ZT_MULTICAST_PROPAGATION_BREADTH];
unsigned int np = _r->multicaster->pickNextPropagationPeers(
unsigned int np = _r->multicaster->pickSocialPropagationPeers(
*(_r->prng),
*(_r->topology),
network->id(),
+3 -3
View File
@@ -220,11 +220,11 @@ std::map<std::string,bool> Utils::listDirectory(const char *path)
#ifdef __WINDOWS__
HANDLE hFind;
WIN32_FIND_DATA ffd;
if ((hFind = FindFirstFile((std::string(path) + "\\*").c_str(),&ffd)) != INVALID_HANDLE_VALUE) {
WIN32_FIND_DATAA ffd;
if ((hFind = FindFirstFileA((std::string(path) + "\\*").c_str(),&ffd)) != INVALID_HANDLE_VALUE) {
do {
r[std::string(ffd.cFileName)] = ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
} while (FindNextFile(hFind,&ffd));
} while (FindNextFileA(hFind,&ffd));
FindClose(hFind);
}
#else
+2 -1
View File
@@ -75,7 +75,7 @@ public:
throw()
{
#ifdef __WINDOWS__
return (DeleteFile(path) != FALSE);
return (DeleteFileA(path) != FALSE);
#else
return (unlink(path) == 0);
#endif
@@ -118,6 +118,7 @@ public:
* @return Number of characters actually written
*/
static unsigned int unhex(const char *hex,void *buf,unsigned int len);
static inline unsigned int unhex(const std::string &hex,void *buf,unsigned int len) { return unhex(hex.c_str(),buf,len); }
/**
* @param buf Buffer to fill
Loaded 20 of 25 files, more files were not shown because too many files have changed in this diff. Show more