diff options
author | Adam Ierymenko <adam.ierymenko@zerotier.com> | 2014-04-08 12:00:21 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@zerotier.com> | 2014-04-08 12:00:21 -0700 |
commit | 5abfb11813d0db9a85903712db2b3389c7c34d6e (patch) | |
tree | 8bd6c240dd69f519a22147d54f308fefabe0f67c /node/WindowsEthernetTap.hpp | |
parent | 0b8d6c7f4a9c7753e5da255bd213ef8fde59bb1e (diff) | |
download | infinitytier-5abfb11813d0db9a85903712db2b3389c7c34d6e.tar.gz infinitytier-5abfb11813d0db9a85903712db2b3389c7c34d6e.zip |
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.
Diffstat (limited to 'node/WindowsEthernetTap.hpp')
-rw-r--r-- | node/WindowsEthernetTap.hpp | 180 |
1 files changed, 22 insertions, 158 deletions
diff --git a/node/WindowsEthernetTap.hpp b/node/WindowsEthernetTap.hpp index f58dc748..4d9d7c90 100644 --- a/node/WindowsEthernetTap.hpp +++ b/node/WindowsEthernetTap.hpp @@ -25,51 +25,39 @@ * LLC. Start here: http://www.zerotier.com/ */ -#ifndef ZT_ETHERNETTAP_HPP -#define ZT_ETHERNETTAP_HPP +#ifndef ZT_WINDOWSETHERNETTAP_HPP +#define ZT_WINDOWSETHERNETTAP_HPP #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" +#include "EthernetTap.hpp" #include "Mutex.hpp" -#include "MulticastGroup.hpp" #include "Thread.hpp" -#include "Buffer.hpp" -#include "Array.hpp" -#ifdef __WINDOWS__ #include <WinSock2.h> #include <Windows.h> -#endif namespace ZeroTier { class RuntimeEnvironment; /** - * System ethernet tap device + * Windows Ethernet tap device using bundled ztTap driver */ -class EthernetTap +class WindowsEthernetTap : public EthernetTap { public: /** - * Construct a new TAP device - * - * Handler arguments: arg,from,to,etherType,data + * Open tap device, installing and creating one if it does not exist * * @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 mtu MTU of device * @param desc If non-NULL, a description (not used on all OSes) @@ -77,7 +65,7 @@ public: * @param arg First argument to handler function * @throws std::runtime_error Unable to allocate device */ - EthernetTap( + WindowsEthernetTap( const RuntimeEnvironment *renv, const char *tag, const MAC &mac, @@ -86,120 +74,18 @@ public: void *arg) throw(std::runtime_error); - /** - * Close tap and shut down thread - * - * This may block for a few seconds while thread exits. - */ - ~EthernetTap(); - - /** - * Set the user display name for this connection - * - * This does nothing on platforms that don't have this concept. - * - * @param dn User display name - */ - void setDisplayName(const char *dn); - - /** - * @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 - } + virtual ~WindowsEthernetTap(); - /** - * 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); + virtual void setEnabled(bool en); + virtual bool enabled() const; + virtual void setDisplayName(const char *dn); + virtual bool addIP(const InetAddress &ip); + virtual bool removeIP(const InetAddress &ip); + virtual std::set<InetAddress> ips() const; + virtual void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len); + virtual std::string deviceName() const; + virtual std::string persistentId() const; + virtual bool updateMulticastGroups(std::set<MulticastGroup> &groups); /** * Thread main method; do not call elsewhere @@ -210,10 +96,6 @@ public: /** * 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 pdev Device name as returned by persistentId() while tap is running * @return True if a device was deleted @@ -223,10 +105,6 @@ public: /** * 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 exceptThese Devices to leave in place * @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); private: - const MAC _mac; - const unsigned int _mtu; - const RuntimeEnvironment *_r; - void (*_handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &); void *_arg; - 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; OVERLAPPED _tapOvlRead,_tapOvlWrite; char _tapReadBuf[ZT_IF_MTU + 32]; HANDLE _injectSemaphore; GUID _deviceGuid; - std::string _myDeviceInstanceId; // NetCfgInstanceId, a GUID - std::string _myDeviceInstanceIdPath; // DeviceInstanceID, another kind of "instance ID" + std::string _netCfgInstanceId; // NetCfgInstanceId, a GUID + std::string _deviceInstanceId; // DeviceInstanceID, another kind of "instance ID" std::queue< std::pair< Array<char,ZT_IF_MTU + 32>,unsigned int > > _injectPending; Mutex _injectPending_m; volatile bool _run; volatile bool _initialized; -#endif + volatile bool _enabled; }; } // namespace ZeroTier |