Some installer stuff, complete refactoring of Windows side of newly split tap driver. Seems to work. Now to see if the cleanup we did here gets rid of the zombie tap device issue on Windows.

This commit is contained in:
Adam Ierymenko 2014-04-08 12:00:21 -07:00
parent 0b8d6c7f4a
commit 5abfb11813
5 changed files with 230 additions and 1328 deletions

View File

@ -20,7 +20,7 @@
<ROW Property="CTRLS" Value="2"/> <ROW Property="CTRLS" Value="2"/>
<ROW Property="MSIFASTINSTALL" MultiBuildValue="DefaultBuild:2"/> <ROW Property="MSIFASTINSTALL" MultiBuildValue="DefaultBuild:2"/>
<ROW Property="Manufacturer" Value="ZeroTier Networks LLC"/> <ROW Property="Manufacturer" Value="ZeroTier Networks LLC"/>
<ROW Property="ProductCode" Value="1033:{58C56791-D77F-4B3D-A5BF-AB3C11DDE4CF} " Type="16"/> <ROW Property="ProductCode" Value="1033:{D74139EC-0303-454F-8812-2407A0ED13B3} " Type="16"/>
<ROW Property="ProductLanguage" Value="1033"/> <ROW Property="ProductLanguage" Value="1033"/>
<ROW Property="ProductName" Value="ZeroTier One"/> <ROW Property="ProductName" Value="ZeroTier One"/>
<ROW Property="ProductVersion" Value="0.8.0" Type="32"/> <ROW Property="ProductVersion" Value="0.8.0" Type="32"/>

File diff suppressed because it is too large Load Diff

View File

@ -25,51 +25,39 @@
* LLC. Start here: http://www.zerotier.com/ * LLC. Start here: http://www.zerotier.com/
*/ */
#ifndef ZT_ETHERNETTAP_HPP #ifndef ZT_WINDOWSETHERNETTAP_HPP
#define ZT_ETHERNETTAP_HPP #define ZT_WINDOWSETHERNETTAP_HPP
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <map>
#include <list>
#include <vector>
#include <set>
#include <string> #include <string>
#include <queue> #include <queue>
#include <stdexcept> #include <stdexcept>
#include "Constants.hpp" #include "Constants.hpp"
#include "InetAddress.hpp" #include "EthernetTap.hpp"
#include "MAC.hpp"
#include "Mutex.hpp" #include "Mutex.hpp"
#include "MulticastGroup.hpp"
#include "Thread.hpp" #include "Thread.hpp"
#include "Buffer.hpp"
#include "Array.hpp"
#ifdef __WINDOWS__
#include <WinSock2.h> #include <WinSock2.h>
#include <Windows.h> #include <Windows.h>
#endif
namespace ZeroTier { namespace ZeroTier {
class RuntimeEnvironment; class RuntimeEnvironment;
/** /**
* System ethernet tap device * Windows Ethernet tap device using bundled ztTap driver
*/ */
class EthernetTap class WindowsEthernetTap : public EthernetTap
{ {
public: public:
/** /**
* Construct a new TAP device * Open tap device, installing and creating one if it does not exist
*
* Handler arguments: arg,from,to,etherType,data
* *
* @param renv Runtime environment * @param renv Runtime environment
* @param tag A tag used to persist tap identity at the OS layer (e.g. nwid in hex for Windows or device name for *nix) * @param tag A tag (presently the hex network ID) used to identify persistent tap devices in the registry
* @param mac MAC address of device * @param mac MAC address of device
* @param mtu MTU of device * @param mtu MTU of device
* @param desc If non-NULL, a description (not used on all OSes) * @param desc If non-NULL, a description (not used on all OSes)
@ -77,7 +65,7 @@ public:
* @param arg First argument to handler function * @param arg First argument to handler function
* @throws std::runtime_error Unable to allocate device * @throws std::runtime_error Unable to allocate device
*/ */
EthernetTap( WindowsEthernetTap(
const RuntimeEnvironment *renv, const RuntimeEnvironment *renv,
const char *tag, const char *tag,
const MAC &mac, const MAC &mac,
@ -86,120 +74,18 @@ public:
void *arg) void *arg)
throw(std::runtime_error); throw(std::runtime_error);
/** virtual ~WindowsEthernetTap();
* Close tap and shut down thread
*
* This may block for a few seconds while thread exits.
*/
~EthernetTap();
/** virtual void setEnabled(bool en);
* Set the user display name for this connection virtual bool enabled() const;
* virtual void setDisplayName(const char *dn);
* This does nothing on platforms that don't have this concept. virtual bool addIP(const InetAddress &ip);
* virtual bool removeIP(const InetAddress &ip);
* @param dn User display name virtual std::set<InetAddress> ips() const;
*/ virtual void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len);
void setDisplayName(const char *dn); virtual std::string deviceName() const;
virtual std::string persistentId() const;
/** virtual bool updateMulticastGroups(std::set<MulticastGroup> &groups);
* @return MAC address of this interface
*/
inline const MAC &mac() const throw() { return _mac; }
/**
* @return MTU of this interface
*/
inline unsigned int mtu() const throw() { return _mtu; }
/**
* Add an IP to this interface
*
* @param ip IP and netmask (netmask stored in port field)
* @return True if IP added successfully
*/
bool addIP(const InetAddress &ip);
/**
* Remove an IP from this interface
*
* Link-local IP addresses may not be able to be removed, depending on platform and type.
*
* @param ip IP and netmask (netmask stored in port field)
* @return True if IP removed successfully
*/
bool removeIP(const InetAddress &ip);
/**
* @return All IP addresses (V4 and V6) assigned to this interface (including link-local)
*/
std::set<InetAddress> ips() const;
/**
* Set this tap's IP addresses to exactly this set of IPs
*
* New IPs are created, ones not in this list are removed.
*
* @param ips IP addresses with netmask in port field
*/
inline void setIps(const std::set<InetAddress> &allIps)
{
for(std::set<InetAddress>::iterator i(allIps.begin());i!=allIps.end();++i)
addIP(*i);
std::set<InetAddress> myIps(ips());
#ifdef __APPLE__
bool haveV6LinkLocal = false;
for(std::set<InetAddress>::iterator i(myIps.begin());i!=myIps.end();++i) {
if (i->isLinkLocal()) {
if (i->isV6())
haveV6LinkLocal = true;
} else if (!allIps.count(*i))
removeIP(*i);
}
if (!haveV6LinkLocal)
addIP(InetAddress::makeIpv6LinkLocal(_mac));
#else
for(std::set<InetAddress>::iterator i(myIps.begin());i!=myIps.end();++i) {
if ((!i->isLinkLocal())&&(!allIps.count(*i)))
removeIP(*i);
}
#endif
}
/**
* Put a frame, making it available to the OS for processing
*
* @param from MAC address from which frame originated
* @param to MAC address of destination (typically MAC of tap itself)
* @param etherType Ethernet protocol ID
* @param data Frame payload
* @param len Length of frame
*/
void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len);
/**
* @return OS-specific device or connection name
*/
std::string deviceName() const;
/**
* @return OS-internal persistent device ID or empty string if not applicable to this platform or not persistent
*/
std::string persistentId() const;
/**
* Fill or modify a set to contain multicast groups for this device
*
* This populates a set or, if already populated, modifies it to contain
* only multicast groups in which this device is interested.
*
* This should always include the blind wildcard MulticastGroup (MAC of
* ff:ff:ff:ff:ff:ff and 0 ADI field).
*
* @param groups Set to modify in place
* @return True if set was changed since last call
*/
bool updateMulticastGroups(std::set<MulticastGroup> &groups);
/** /**
* Thread main method; do not call elsewhere * Thread main method; do not call elsewhere
@ -210,10 +96,6 @@ public:
/** /**
* Remove persistent tap device by device name * Remove persistent tap device by device name
* *
* This has no effect on platforms that do not have persistent taps.
* On platforms like Windows with persistent devices the device is
* uninstalled.
*
* @param _r Runtime environment * @param _r Runtime environment
* @param pdev Device name as returned by persistentId() while tap is running * @param pdev Device name as returned by persistentId() while tap is running
* @return True if a device was deleted * @return True if a device was deleted
@ -223,10 +105,6 @@ public:
/** /**
* Clean persistent tap devices that are not in the supplied set * Clean persistent tap devices that are not in the supplied set
* *
* This has no effect on platforms that do not have persistent taps.
* On platforms like Windows with persistent devices the device is
* uninstalled.
*
* @param _r Runtime environment * @param _r Runtime environment
* @param exceptThese Devices to leave in place * @param exceptThese Devices to leave in place
* @param alsoRemoveUnassociatedDevices If true, remove devices not associated with any network as well * @param alsoRemoveUnassociatedDevices If true, remove devices not associated with any network as well
@ -235,37 +113,23 @@ public:
static int cleanPersistentTapDevices(const RuntimeEnvironment *_r,const std::set<std::string> &exceptThese,bool alsoRemoveUnassociatedDevices); static int cleanPersistentTapDevices(const RuntimeEnvironment *_r,const std::set<std::string> &exceptThese,bool alsoRemoveUnassociatedDevices);
private: private:
const MAC _mac;
const unsigned int _mtu;
const RuntimeEnvironment *_r; const RuntimeEnvironment *_r;
void (*_handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &); void (*_handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &);
void *_arg; void *_arg;
Thread _thread; Thread _thread;
#ifdef __UNIX_LIKE__
char _dev[16];
int _fd;
int _shutdownSignalPipe[2];
#endif
#ifdef __WINDOWS__
void _syncIpsWithRegistry(const std::set<InetAddress> &haveIps);
HANDLE _tap; HANDLE _tap;
OVERLAPPED _tapOvlRead,_tapOvlWrite; OVERLAPPED _tapOvlRead,_tapOvlWrite;
char _tapReadBuf[ZT_IF_MTU + 32]; char _tapReadBuf[ZT_IF_MTU + 32];
HANDLE _injectSemaphore; HANDLE _injectSemaphore;
GUID _deviceGuid; GUID _deviceGuid;
std::string _myDeviceInstanceId; // NetCfgInstanceId, a GUID std::string _netCfgInstanceId; // NetCfgInstanceId, a GUID
std::string _myDeviceInstanceIdPath; // DeviceInstanceID, another kind of "instance ID" std::string _deviceInstanceId; // DeviceInstanceID, another kind of "instance ID"
std::queue< std::pair< Array<char,ZT_IF_MTU + 32>,unsigned int > > _injectPending; std::queue< std::pair< Array<char,ZT_IF_MTU + 32>,unsigned int > > _injectPending;
Mutex _injectPending_m; Mutex _injectPending_m;
volatile bool _run; volatile bool _run;
volatile bool _initialized; volatile bool _initialized;
#endif volatile bool _enabled;
}; };
} // namespace ZeroTier } // namespace ZeroTier

View File

@ -25,7 +25,6 @@
<ClCompile Include="..\..\node\C25519.cpp" /> <ClCompile Include="..\..\node\C25519.cpp" />
<ClCompile Include="..\..\node\CertificateOfMembership.cpp" /> <ClCompile Include="..\..\node\CertificateOfMembership.cpp" />
<ClCompile Include="..\..\node\Defaults.cpp" /> <ClCompile Include="..\..\node\Defaults.cpp" />
<ClCompile Include="..\..\node\EthernetTap.cpp" />
<ClCompile Include="..\..\node\HttpClient.cpp" /> <ClCompile Include="..\..\node\HttpClient.cpp" />
<ClCompile Include="..\..\node\Identity.cpp" /> <ClCompile Include="..\..\node\Identity.cpp" />
<ClCompile Include="..\..\node\InetAddress.cpp" /> <ClCompile Include="..\..\node\InetAddress.cpp" />
@ -52,6 +51,7 @@
<ClCompile Include="..\..\node\Topology.cpp" /> <ClCompile Include="..\..\node\Topology.cpp" />
<ClCompile Include="..\..\node\UdpSocket.cpp" /> <ClCompile Include="..\..\node\UdpSocket.cpp" />
<ClCompile Include="..\..\node\Utils.cpp" /> <ClCompile Include="..\..\node\Utils.cpp" />
<ClCompile Include="..\..\node\WindowsEthernetTap.cpp" />
<ClCompile Include="ServiceBase.cpp" /> <ClCompile Include="ServiceBase.cpp" />
<ClCompile Include="ServiceInstaller.cpp" /> <ClCompile Include="ServiceInstaller.cpp" />
<ClCompile Include="ZeroTierOneService.cpp" /> <ClCompile Include="ZeroTierOneService.cpp" />
@ -107,6 +107,7 @@
<ClInclude Include="..\..\node\Topology.hpp" /> <ClInclude Include="..\..\node\Topology.hpp" />
<ClInclude Include="..\..\node\UdpSocket.hpp" /> <ClInclude Include="..\..\node\UdpSocket.hpp" />
<ClInclude Include="..\..\node\Utils.hpp" /> <ClInclude Include="..\..\node\Utils.hpp" />
<ClInclude Include="..\..\node\WindowsEthernetTap.hpp" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="ServiceBase.h" /> <ClInclude Include="ServiceBase.h" />
<ClInclude Include="ServiceInstaller.h" /> <ClInclude Include="ServiceInstaller.h" />

View File

@ -30,9 +30,6 @@
<ClCompile Include="..\..\node\Defaults.cpp"> <ClCompile Include="..\..\node\Defaults.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\node\EthernetTap.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\node\HttpClient.cpp"> <ClCompile Include="..\..\node\HttpClient.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
@ -123,6 +120,9 @@
<ClCompile Include="..\..\node\TcpSocket.cpp"> <ClCompile Include="..\..\node\TcpSocket.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\node\WindowsEthernetTap.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\ext\lz4\lz4.h"> <ClInclude Include="..\..\ext\lz4\lz4.h">
@ -287,6 +287,9 @@
<ClInclude Include="..\..\node\TcpSocket.hpp"> <ClInclude Include="..\..\node\TcpSocket.hpp">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\node\WindowsEthernetTap.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="ZeroTierOne.rc"> <ResourceCompile Include="ZeroTierOne.rc">