diff options
Diffstat (limited to 'node/Network.hpp')
| -rw-r--r-- | node/Network.hpp | 163 |
1 files changed, 126 insertions, 37 deletions
diff --git a/node/Network.hpp b/node/Network.hpp index f41e7502..af51e368 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -53,6 +53,7 @@ #include "BandwidthAccount.hpp" #include "NetworkConfig.hpp" #include "CertificateOfMembership.hpp" +#include "Thread.hpp" namespace ZeroTier { @@ -91,6 +92,9 @@ private: * If there is no saved state, a dummy .conf is created on disk to remember * this network across restarts. * + * This can be a time consuming operation on some platforms (cough Windows + * cough). + * * @param renv Runtime environment * @param id Network ID * @return Reference counted pointer to new network @@ -109,10 +113,12 @@ public: */ enum Status { + NETWORK_INITIALIZING, NETWORK_WAITING_FOR_FIRST_AUTOCONF, NETWORK_OK, NETWORK_ACCESS_DENIED, - NETWORK_NOT_FOUND + NETWORK_NOT_FOUND, + NETWORK_INITIALIZATION_FAILED }; /** @@ -128,11 +134,6 @@ public: inline uint64_t id() const throw() { return _id; } /** - * @return Ethernet tap - */ - inline EthernetTap &tap() throw() { return *_tap; } - - /** * @return Address of network's controlling node */ inline Address controller() throw() { return Address(_id >> 24); } @@ -155,7 +156,10 @@ public: inline bool updateMulticastGroups() { Mutex::Lock _l(_lock); - return _tap->updateMulticastGroups(_multicastGroups); + EthernetTap *t = _tap; + if (t) + return _tap->updateMulticastGroups(_multicastGroups); + return false; } /** @@ -173,10 +177,34 @@ public: * This is called by PacketDecoder when an update comes over the wire, or * internally when an old config is reloaded from disk. * + * This also cancels any netconf failure flags. + * + * The network can't accept configuration when in INITIALIZATION state, + * and so in that state this will just return false. + * * @param conf Configuration in key/value dictionary form * @param saveToDisk IF true (default), write config to disk + * @return True if configuration was accepted + */ + bool setConfiguration(const Dictionary &conf,bool saveToDisk = true); + + /** + * Set netconf failure to 'access denied'. */ - void setConfiguration(const Dictionary &conf,bool saveToDisk = true); + inline void setAccessDenied() + { + Mutex::Lock _l(_lock); + _netconfFailure = NETCONF_FAILURE_ACCESS_DENIED; + } + + /** + * Set netconf failure to 'not found'. + */ + inline void setNotFound() + { + Mutex::Lock _l(_lock); + _netconfFailure = NETCONF_FAILURE_NOT_FOUND; + } /** * Causes this network to request an updated configuration from its master node now @@ -223,16 +251,6 @@ public: */ inline uint64_t lastConfigUpdate() const throw() { return _lastConfigUpdate; } - /** - * Force this network's status to a particular state based on config reply - */ - inline void forceStatusTo(const Status s) - throw() - { - Mutex::Lock _l(_lock); - _status = s; - } - /** * @return Status of this network */ @@ -240,17 +258,20 @@ public: throw() { Mutex::Lock _l(_lock); - return _status; - } - - /** - * @return True if this network is in "OK" status and can accept traffic from us - */ - inline bool isUp() const - throw() - { - Mutex::Lock _l(_lock); - return ((_config)&&(_status == NETWORK_OK)&&(_ready)); + if (_tap) { + switch(_netconfFailure) { + case NETCONF_FAILURE_ACCESS_DENIED: + return NETWORK_ACCESS_DENIED; + case NETCONF_FAILURE_NOT_FOUND: + return NETWORK_NOT_FOUND; + case NETCONF_FAILURE_NONE: + if (_lastConfigUpdate > 0) + return NETWORK_OK; + else return NETWORK_WAITING_FOR_FIRST_AUTOCONF; + } + } else if (_netconfFailure == NETCONF_FAILURE_INIT_FAILED) + return NETWORK_INITIALIZATION_FAILED; + else return NETWORK_INITIALIZING; } /** @@ -307,6 +328,73 @@ public: return _config; } + /** + * Thread main method; do not call elsewhere + */ + void threadMain() + throw(); + + /** + * Inject a frame into tap (if it's created) + * + * @param from Origin MAC + * @param to Destination MC + * @param etherType Ethernet frame type + * @param data Frame data + * @param len Frame length + */ + inline void tapPut(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) + { + EthernetTap *t = _tap; + if (t) + t->put(from,to,etherType,data,len); + } + + /** + * Inject a frame into tap with local MAC as destination MAC (if it's created) + * + * @param from Origin MAC + * @param etherType Ethernet frame type + * @param data Frame data + * @param len Frame length + */ + inline void tapPut(const MAC &from,unsigned int etherType,const void *data,unsigned int len) + { + EthernetTap *t = _tap; + if (t) + t->put(from,t->mac(),etherType,data,len); + } + + /** + * @return Tap device name or empty string if still initializing + */ + inline std::string tapDeviceName() const + { + EthernetTap *t = _tap; + if (t) + return t->deviceName(); + else return std::string(); + } + + /** + * @return Ethernet MAC address for this network's local interface + */ + inline const MAC &mac() const + { + return _mac; + } + + /** + * @return Set of currently assigned IP addresses + */ + inline std::set<InetAddress> ips() const + { + EthernetTap *t = _tap; + if (t) + return t->ips(); + return std::set<InetAddress>(); + } + private: static void _CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned int etherType,const Buffer<4096> &data); @@ -315,22 +403,23 @@ private: void _dumpMulticastCerts(); uint64_t _id; - + MAC _mac; const RuntimeEnvironment *_r; - - EthernetTap *_tap; + EthernetTap *volatile _tap; std::set<MulticastGroup> _multicastGroups; - std::map< std::pair<Address,MulticastGroup>,BandwidthAccount > _multicastRateAccounts; std::map<Address,CertificateOfMembership> _membershipCertificates; std::map<Address,uint64_t> _lastPushedMembershipCertificate; SharedPtr<NetworkConfig> _config; - volatile uint64_t _lastConfigUpdate; - volatile Status _status; volatile bool _destroyOnDelete; - volatile bool _ready; - + volatile enum { + NETCONF_FAILURE_NONE, + NETCONF_FAILURE_ACCESS_DENIED, + NETCONF_FAILURE_NOT_FOUND, + NETCONF_FAILURE_INIT_FAILED + } _netconfFailure; + Thread _setupThread; Mutex _lock; AtomicCounter __refCount; |
