diff options
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 |