diff options
-rw-r--r-- | node/Network.cpp | 12 | ||||
-rw-r--r-- | node/Network.hpp | 7 | ||||
-rw-r--r-- | node/Node.cpp | 21 |
3 files changed, 29 insertions, 11 deletions
diff --git a/node/Network.cpp b/node/Network.cpp index 3c607b28..b7f25f7f 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -729,7 +729,8 @@ Network::~Network() char n[128]; if (_destroyed) { - RR->node->configureVirtualNetworkPort((void *)0,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp); + // This is done in Node::leave() so we can pass tPtr + //RR->node->configureVirtualNetworkPort((void *)0,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp); Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.conf",_id); RR->node->dataStoreDelete((void *)0,n); } else { @@ -993,6 +994,9 @@ void Network::multicastUnsubscribe(const MulticastGroup &mg) uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Address &source,const Buffer<ZT_PROTO_MAX_PACKET_LENGTH> &chunk,unsigned int ptr) { + if (_destroyed) + return 0; + const unsigned int start = ptr; ptr += 8; // skip network ID, which is already obviously known @@ -1140,6 +1144,9 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToDisk) { + if (_destroyed) + return 0; + // _lock is NOT locked when this is called try { if ((nconf.issuedTo != RR->identity.address())||(nconf.networkId != _id)) @@ -1190,6 +1197,9 @@ int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToD void Network::requestConfiguration(void *tPtr) { + if (_destroyed) + return; + /* ZeroTier addresses can't begin with 0xff, so this is used to mark controllerless * network IDs. Controllerless network IDs only support unicast IPv6 using the 6plane * addressing scheme and have the following format: 0xffSSSSEEEE000000 where SSSS diff --git a/node/Network.hpp b/node/Network.hpp index fccc267a..faef0fed 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -344,9 +344,8 @@ public: /** * Destroy this network * - * This causes the network to disable itself, destroy its tap device, and on - * delete to delete all trace of itself on disk and remove any persistent tap - * device instances. Call this when a network is being removed from the system. + * This sets the network to completely remove itself on delete. This also prevents the + * call of the normal port shutdown event on delete. */ void destroy(); @@ -364,7 +363,7 @@ public: /** * @return Externally usable pointer-to-pointer exported via the core API */ - inline void **userPtr() throw() { return &_uPtr; } + inline void **userPtr() { return &_uPtr; } private: ZT_VirtualNetworkStatus _status() const; diff --git a/node/Node.cpp b/node/Node.cpp index e7dc637f..9844b09e 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -305,26 +305,35 @@ ZT_ResultCode Node::join(uint64_t nwid,void *uptr,void *tptr) { Mutex::Lock _l(_networks_m); SharedPtr<Network> nw = _network(nwid); - if(!nw) - _networks.push_back(std::pair< uint64_t,SharedPtr<Network> >(nwid,SharedPtr<Network>(new Network(RR,tptr,nwid,uptr)))); - std::sort(_networks.begin(),_networks.end()); // will sort by nwid since it's the first in a pair<> + if(!nw) { + const std::pair< uint64_t,SharedPtr<Network> > nn(nwid,SharedPtr<Network>(new Network(RR,tptr,nwid,uptr))); + _networks.insert(std::upper_bound(_networks.begin(),_networks.end(),nn),nn); + } return ZT_RESULT_OK; } ZT_ResultCode Node::leave(uint64_t nwid,void **uptr,void *tptr) { + ZT_VirtualNetworkConfig ctmp; std::vector< std::pair< uint64_t,SharedPtr<Network> > > newn; + void **nUserPtr = (void **)0; Mutex::Lock _l(_networks_m); + for(std::vector< std::pair< uint64_t,SharedPtr<Network> > >::const_iterator n(_networks.begin());n!=_networks.end();++n) { - if (n->first != nwid) + if (n->first != nwid) { newn.push_back(*n); - else { + } else { if (uptr) - *uptr = n->second->userPtr(); + *uptr = *n->second->userPtr(); n->second->destroy(); + nUserPtr = n->second->userPtr(); } } _networks.swap(newn); + + if (nUserPtr) + RR->node->configureVirtualNetworkPort(tptr,nwid,nUserPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp); + return ZT_RESULT_OK; } |