Pass tptr on leave.

This commit is contained in:
Adam Ierymenko 2017-04-11 08:47:02 -07:00
parent 6fabaae736
commit 88a4a3b1ba
3 changed files with 29 additions and 11 deletions

View file

@ -729,7 +729,8 @@ Network::~Network()
char n[128]; char n[128];
if (_destroyed) { 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); Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.conf",_id);
RR->node->dataStoreDelete((void *)0,n); RR->node->dataStoreDelete((void *)0,n);
} else { } 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) 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; const unsigned int start = ptr;
ptr += 8; // skip network ID, which is already obviously known 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) int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToDisk)
{ {
if (_destroyed)
return 0;
// _lock is NOT locked when this is called // _lock is NOT locked when this is called
try { try {
if ((nconf.issuedTo != RR->identity.address())||(nconf.networkId != _id)) 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) void Network::requestConfiguration(void *tPtr)
{ {
if (_destroyed)
return;
/* ZeroTier addresses can't begin with 0xff, so this is used to mark controllerless /* 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 * network IDs. Controllerless network IDs only support unicast IPv6 using the 6plane
* addressing scheme and have the following format: 0xffSSSSEEEE000000 where SSSS * addressing scheme and have the following format: 0xffSSSSEEEE000000 where SSSS

View file

@ -344,9 +344,8 @@ public:
/** /**
* Destroy this network * Destroy this network
* *
* This causes the network to disable itself, destroy its tap device, and on * This sets the network to completely remove itself on delete. This also prevents the
* delete to delete all trace of itself on disk and remove any persistent tap * call of the normal port shutdown event on delete.
* device instances. Call this when a network is being removed from the system.
*/ */
void destroy(); void destroy();
@ -364,7 +363,7 @@ public:
/** /**
* @return Externally usable pointer-to-pointer exported via the core API * @return Externally usable pointer-to-pointer exported via the core API
*/ */
inline void **userPtr() throw() { return &_uPtr; } inline void **userPtr() { return &_uPtr; }
private: private:
ZT_VirtualNetworkStatus _status() const; ZT_VirtualNetworkStatus _status() const;

View file

@ -305,26 +305,35 @@ ZT_ResultCode Node::join(uint64_t nwid,void *uptr,void *tptr)
{ {
Mutex::Lock _l(_networks_m); Mutex::Lock _l(_networks_m);
SharedPtr<Network> nw = _network(nwid); SharedPtr<Network> nw = _network(nwid);
if(!nw) if(!nw) {
_networks.push_back(std::pair< uint64_t,SharedPtr<Network> >(nwid,SharedPtr<Network>(new Network(RR,tptr,nwid,uptr)))); const std::pair< uint64_t,SharedPtr<Network> > nn(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<> _networks.insert(std::upper_bound(_networks.begin(),_networks.end(),nn),nn);
}
return ZT_RESULT_OK; return ZT_RESULT_OK;
} }
ZT_ResultCode Node::leave(uint64_t nwid,void **uptr,void *tptr) ZT_ResultCode Node::leave(uint64_t nwid,void **uptr,void *tptr)
{ {
ZT_VirtualNetworkConfig ctmp;
std::vector< std::pair< uint64_t,SharedPtr<Network> > > newn; std::vector< std::pair< uint64_t,SharedPtr<Network> > > newn;
void **nUserPtr = (void **)0;
Mutex::Lock _l(_networks_m); Mutex::Lock _l(_networks_m);
for(std::vector< std::pair< uint64_t,SharedPtr<Network> > >::const_iterator n(_networks.begin());n!=_networks.end();++n) { 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); newn.push_back(*n);
else { } else {
if (uptr) if (uptr)
*uptr = n->second->userPtr(); *uptr = *n->second->userPtr();
n->second->destroy(); n->second->destroy();
nUserPtr = n->second->userPtr();
} }
} }
_networks.swap(newn); _networks.swap(newn);
if (nUserPtr)
RR->node->configureVirtualNetworkPort(tptr,nwid,nUserPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp);
return ZT_RESULT_OK; return ZT_RESULT_OK;
} }