diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-04-15 13:09:20 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-04-15 13:09:20 -0700 |
commit | 1c9ca73065975b137deb6770b4624886942c2605 (patch) | |
tree | 68877dfbf02796160ae53f3d2e591564afb9a252 /node | |
parent | 508519b62a9a7eae47c1000d56c85c645dae0b55 (diff) | |
download | infinitytier-1c9ca73065975b137deb6770b4624886942c2605.tar.gz infinitytier-1c9ca73065975b137deb6770b4624886942c2605.zip |
Fix some deadlock issues, move awareness of broadcast subscription into core, other bug fixes.
Diffstat (limited to 'node')
-rw-r--r-- | node/Network.cpp | 48 | ||||
-rw-r--r-- | node/Network.hpp | 20 | ||||
-rw-r--r-- | node/Node.cpp | 63 | ||||
-rw-r--r-- | node/Node.hpp | 6 | ||||
-rw-r--r-- | node/Switch.cpp | 8 |
5 files changed, 76 insertions, 69 deletions
diff --git a/node/Network.cpp b/node/Network.cpp index ba0ee984..7fa17ef1 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -47,6 +47,7 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid) : _id(nwid), _mac(renv->identity.address(),nwid), _enabled(true), + _portInitialized(false), _lastConfigUpdate(0), _destroyed(false), _netconfFailure(NETCONF_FAILURE_NONE), @@ -84,7 +85,6 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid) : const char *e = p + mcdb.length(); if (!memcmp("ZTMCD0",p,6)) { p += 6; - Mutex::Lock _l(_lock); while (p != e) { CertificateOfMembership com; com.deserialize2(p,e); @@ -97,9 +97,12 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid) : } catch ( ... ) {} // ignore invalid MCDB, we'll re-learn from peers } - ZT1_VirtualNetworkConfig ctmp; - _externalConfig(&ctmp); - _portError = RR->node->configureVirtualNetworkPort(_id,ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp); + if (!_portInitialized) { + ZT1_VirtualNetworkConfig ctmp; + _externalConfig(&ctmp); + _portError = RR->node->configureVirtualNetworkPort(_id,ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp); + _portInitialized = true; + } } Network::~Network() @@ -145,6 +148,8 @@ std::vector<MulticastGroup> Network::allMulticastGroups() const if (!std::binary_search(mgs.begin(),oldend,i->first)) mgs.push_back(i->first); } + if ((_config)&&(_config->enableBroadcast())) + mgs.push_back(Network::BROADCAST); std::sort(mgs.begin(),mgs.end()); return mgs; } @@ -161,11 +166,13 @@ bool Network::subscribedToMulticastGroup(const MulticastGroup &mg,bool includeBr void Network::multicastSubscribe(const MulticastGroup &mg) { - Mutex::Lock _l(_lock); - if (std::binary_search(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg)) - return; - _myMulticastGroups.push_back(mg); - std::sort(_myMulticastGroups.begin(),_myMulticastGroups.end()); + { + Mutex::Lock _l(_lock); + if (std::binary_search(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg)) + return; + _myMulticastGroups.push_back(mg); + std::sort(_myMulticastGroups.begin(),_myMulticastGroups.end()); + } _announceMulticastGroups(); } @@ -183,19 +190,22 @@ void Network::multicastUnsubscribe(const MulticastGroup &mg) bool Network::applyConfiguration(const SharedPtr<NetworkConfig> &conf) { - Mutex::Lock _l(_lock); - if (_destroyed) + if (_destroyed) // sanity check return false; try { if ((conf->networkId() == _id)&&(conf->issuedTo() == RR->identity.address())) { - _config = conf; - _lastConfigUpdate = RR->node->now(); - _netconfFailure = NETCONF_FAILURE_NONE; - ZT1_VirtualNetworkConfig ctmp; - _externalConfig(&ctmp); - _portError = RR->node->configureVirtualNetworkPort(_id,ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE,&ctmp); - + bool portInitialized; + { + Mutex::Lock _l(_lock); + _config = conf; + _lastConfigUpdate = RR->node->now(); + _netconfFailure = NETCONF_FAILURE_NONE; + _externalConfig(&ctmp); + portInitialized = _portInitialized; + _portInitialized = true; + } + _portError = RR->node->configureVirtualNetworkPort(_id,(portInitialized) ? ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp); return true; } else { TRACE("ignored invalid configuration for network %.16llx (configuration contains mismatched network ID or issued-to address)",(unsigned long long)_id); @@ -462,7 +472,7 @@ ZT1_VirtualNetworkStatus Network::_status() const case NETCONF_FAILURE_NOT_FOUND: return ZT1_NETWORK_STATUS_NOT_FOUND; case NETCONF_FAILURE_NONE: - return ((_lastConfigUpdate > 0) ? ZT1_NETWORK_STATUS_OK : ZT1_NETWORK_STATUS_REQUESTING_CONFIGURATION); + return ((_config) ? ZT1_NETWORK_STATUS_OK : ZT1_NETWORK_STATUS_REQUESTING_CONFIGURATION); default: return ZT1_NETWORK_STATUS_PORT_ERROR; } diff --git a/node/Network.hpp b/node/Network.hpp index 08d9e527..213b44c5 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -65,6 +65,16 @@ class Network : NonCopyable public: /** + * Broadcast multicast group: ff:ff:ff:ff:ff:ff / 0 + */ + static const MulticastGroup BROADCAST; + + /** + * Construct a new network + * + * Note that init() should be called immediately after the network is + * constructed to actually configure the port. + * * @param renv Runtime environment * @param nwid Network ID */ @@ -73,11 +83,6 @@ public: ~Network(); /** - * Broadcast multicast group: ff:ff:ff:ff:ff:ff / 0 - */ - static const MulticastGroup BROADCAST; - - /** * @return Network ID */ inline uint64_t id() const throw() { return _id; } @@ -348,7 +353,8 @@ private: const RuntimeEnvironment *RR; uint64_t _id; MAC _mac; // local MAC address - bool _enabled; + volatile bool _enabled; + volatile bool _portInitialized; std::vector< MulticastGroup > _myMulticastGroups; // multicast groups that we belong to including those behind us (updated periodically) std::map< MulticastGroup,uint64_t > _multicastGroupsBehindMe; // multicast groups bridged to us and when we last saw activity on each @@ -370,7 +376,7 @@ private: NETCONF_FAILURE_NOT_FOUND, NETCONF_FAILURE_INIT_FAILED } _netconfFailure; - int _portError; // return value from port config callback + volatile int _portError; // return value from port config callback Mutex _lock; diff --git a/node/Node.cpp b/node/Node.cpp index 6cdfc650..c6ae54bd 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -152,16 +152,10 @@ ZT1_ResultCode Node::processWirePacket( unsigned int linkDesperation, const void *packetData, unsigned int packetLength, - uint64_t *nextBackgroundTaskDeadline) + volatile uint64_t *nextBackgroundTaskDeadline) { - if (now >= *nextBackgroundTaskDeadline) { - ZT1_ResultCode rc = processBackgroundTasks(now,nextBackgroundTaskDeadline); - if (rc != ZT1_RESULT_OK) - return rc; - } else _now = now; - + _now = now; RR->sw->onRemotePacket(*(reinterpret_cast<const InetAddress *>(remoteAddress)),linkDesperation,packetData,packetLength); - return ZT1_RESULT_OK; } @@ -174,20 +168,14 @@ ZT1_ResultCode Node::processVirtualNetworkFrame( unsigned int vlanId, const void *frameData, unsigned int frameLength, - uint64_t *nextBackgroundTaskDeadline) + volatile uint64_t *nextBackgroundTaskDeadline) { - if (now >= *nextBackgroundTaskDeadline) { - ZT1_ResultCode rc = processBackgroundTasks(now,nextBackgroundTaskDeadline); - if (rc != ZT1_RESULT_OK) - return rc; - } else _now = now; - - SharedPtr<Network> nw(network(nwid)); - if (nw) + _now = now; + SharedPtr<Network> nw(this->network(nwid)); + if (nw) { RR->sw->onLocalEthernet(nw,MAC(sourceMac),MAC(destMac),etherType,vlanId,frameData,frameLength); - else return ZT1_RESULT_ERROR_NETWORK_NOT_FOUND; - - return ZT1_RESULT_OK; + return ZT1_RESULT_OK; + } else return ZT1_RESULT_ERROR_NETWORK_NOT_FOUND; } class _PingPeersThatNeedPing @@ -217,7 +205,7 @@ private: std::vector<Address> _supernodes; }; -ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,uint64_t *nextBackgroundTaskDeadline) +ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline) { _now = now; Mutex::Lock bl(_backgroundTasksLock); @@ -260,6 +248,7 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,uint64_t *nextBackgroun *(reinterpret_cast<uint32_t *>(beacon)) = RR->prng->next32(); *(reinterpret_cast<uint32_t *>(beacon + 4)) = RR->prng->next32(); RR->identity.address().copyTo(beacon + 8,5); + RR->antiRec->logOutgoingZT(beacon,13); putPacket(ZT_DEFAULTS.v4Broadcast,beacon,13,0); } } @@ -292,9 +281,9 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,uint64_t *nextBackgroun ZT1_ResultCode Node::join(uint64_t nwid) { Mutex::Lock _l(_networks_m); - SharedPtr<Network> &nw = _networks[nwid]; - if (!nw) - nw = SharedPtr<Network>(new Network(RR,nwid)); + SharedPtr<Network> &nwe = _networks[nwid]; + if (!nwe) + nwe = SharedPtr<Network>(new Network(RR,nwid)); return ZT1_RESULT_OK; } @@ -311,20 +300,20 @@ ZT1_ResultCode Node::leave(uint64_t nwid) ZT1_ResultCode Node::multicastSubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi) { - Mutex::Lock _l(_networks_m); - std::map< uint64_t,SharedPtr<Network> >::iterator nw(_networks.find(nwid)); - if (nw != _networks.end()) - nw->second->multicastSubscribe(MulticastGroup(MAC(multicastGroup),(uint32_t)(multicastAdi & 0xffffffff))); - return ZT1_RESULT_OK; + SharedPtr<Network> nw(this->network(nwid)); + if (nw) { + nw->multicastSubscribe(MulticastGroup(MAC(multicastGroup),(uint32_t)(multicastAdi & 0xffffffff))); + return ZT1_RESULT_OK; + } else return ZT1_RESULT_ERROR_NETWORK_NOT_FOUND; } ZT1_ResultCode Node::multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi) { - Mutex::Lock _l(_networks_m); - std::map< uint64_t,SharedPtr<Network> >::iterator nw(_networks.find(nwid)); - if (nw != _networks.end()) - nw->second->multicastUnsubscribe(MulticastGroup(MAC(multicastGroup),(uint32_t)(multicastAdi & 0xffffffff))); - return ZT1_RESULT_OK; + SharedPtr<Network> nw(this->network(nwid)); + if (nw) { + nw->multicastUnsubscribe(MulticastGroup(MAC(multicastGroup),(uint32_t)(multicastAdi & 0xffffffff))); + return ZT1_RESULT_OK; + } else return ZT1_RESULT_ERROR_NETWORK_NOT_FOUND; } uint64_t Node::address() const @@ -531,7 +520,7 @@ enum ZT1_ResultCode ZT1_Node_processWirePacket( unsigned int linkDesperation, const void *packetData, unsigned int packetLength, - uint64_t *nextBackgroundTaskDeadline) + volatile uint64_t *nextBackgroundTaskDeadline) { try { return reinterpret_cast<ZeroTier::Node *>(node)->processWirePacket(now,remoteAddress,linkDesperation,packetData,packetLength,nextBackgroundTaskDeadline); @@ -553,7 +542,7 @@ enum ZT1_ResultCode ZT1_Node_processVirtualNetworkFrame( unsigned int vlanId, const void *frameData, unsigned int frameLength, - uint64_t *nextBackgroundTaskDeadline) + volatile uint64_t *nextBackgroundTaskDeadline) { try { return reinterpret_cast<ZeroTier::Node *>(node)->processVirtualNetworkFrame(now,nwid,sourceMac,destMac,etherType,vlanId,frameData,frameLength,nextBackgroundTaskDeadline); @@ -564,7 +553,7 @@ enum ZT1_ResultCode ZT1_Node_processVirtualNetworkFrame( } } -enum ZT1_ResultCode ZT1_Node_processBackgroundTasks(ZT1_Node *node,uint64_t now,uint64_t *nextBackgroundTaskDeadline) +enum ZT1_ResultCode ZT1_Node_processBackgroundTasks(ZT1_Node *node,uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline) { try { return reinterpret_cast<ZeroTier::Node *>(node)->processBackgroundTasks(now,nextBackgroundTaskDeadline); diff --git a/node/Node.hpp b/node/Node.hpp index cd8914e6..429e5171 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -83,7 +83,7 @@ public: unsigned int linkDesperation, const void *packetData, unsigned int packetLength, - uint64_t *nextBackgroundTaskDeadline); + volatile uint64_t *nextBackgroundTaskDeadline); ZT1_ResultCode processVirtualNetworkFrame( uint64_t now, uint64_t nwid, @@ -93,8 +93,8 @@ public: unsigned int vlanId, const void *frameData, unsigned int frameLength, - uint64_t *nextBackgroundTaskDeadline); - ZT1_ResultCode processBackgroundTasks(uint64_t now,uint64_t *nextBackgroundTaskDeadline); + volatile uint64_t *nextBackgroundTaskDeadline); + ZT1_ResultCode processBackgroundTasks(uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline); ZT1_ResultCode join(uint64_t nwid); ZT1_ResultCode leave(uint64_t nwid); ZT1_ResultCode multicastSubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi); diff --git a/node/Switch.cpp b/node/Switch.cpp index 3710158d..6bc044c0 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -153,7 +153,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c return; } - //TRACE("%.16llx: MULTICAST %s -> %s %s %u",network->id(),from.toString().c_str(),mg.toString().c_str(),etherTypeName(etherType),len); + TRACE("%.16llx: MULTICAST %s -> %s %s %u",network->id(),from.toString().c_str(),mg.toString().c_str(),etherTypeName(etherType),len); RR->mc->send( ((!nconf->isPublic())&&(nconf->com())) ? &(nconf->com()) : (const CertificateOfMembership *)0, @@ -171,7 +171,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c } if (to[0] == MAC::firstOctetForNetwork(network->id())) { - // Destination is another ZeroTier peer + // Destination is another ZeroTier peer on the same network Address toZT(to.toAddress(network->id())); if (network->isAllowed(toZT)) { @@ -203,8 +203,10 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c outp.compress(); send(outp,true); } + + TRACE("%.16llx: UNICAST: %s -> %s etherType==%s(%.4x) vlanId==%u len==%u fromBridged==%d",network->id(),from.toString().c_str(),to.toString().c_str(),etherTypeName(etherType),etherType,vlanId,len,(int)fromBridged); } else { - TRACE("%.16llx: UNICAST: %s -> %s %s dropped, destination not a member of private network",network->id(),from.toString().c_str(),to.toString().c_str(),etherTypeName(etherType)); + TRACE("%.16llx: UNICAST: %s -> %s etherType==%s dropped, destination not a member of private network",network->id(),from.toString().c_str(),to.toString().c_str(),etherTypeName(etherType)); } return; |