mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-05-31 22:40:48 +00:00
Fix deadlock-causing regression in Network.
This commit is contained in:
parent
1eeebba2f7
commit
9eaa3756f8
@ -886,11 +886,13 @@ uint64_t Network::handleConfigChunk(const Packet &chunk,unsigned int ptr)
|
|||||||
const unsigned int chunkLen = chunk.at<uint16_t>(ptr); ptr += 2;
|
const unsigned int chunkLen = chunk.at<uint16_t>(ptr); ptr += 2;
|
||||||
const void *chunkData = chunk.field(ptr,chunkLen); ptr += chunkLen;
|
const void *chunkData = chunk.field(ptr,chunkLen); ptr += chunkLen;
|
||||||
|
|
||||||
|
NetworkConfig *nc = (NetworkConfig *)0;
|
||||||
|
uint64_t configUpdateId;
|
||||||
|
{
|
||||||
Mutex::Lock _l(_lock);
|
Mutex::Lock _l(_lock);
|
||||||
|
|
||||||
_IncomingConfigChunk *c = (_IncomingConfigChunk *)0;
|
_IncomingConfigChunk *c = (_IncomingConfigChunk *)0;
|
||||||
uint64_t chunkId = 0;
|
uint64_t chunkId = 0;
|
||||||
uint64_t configUpdateId;
|
|
||||||
unsigned long totalLength,chunkIndex;
|
unsigned long totalLength,chunkIndex;
|
||||||
if (ptr < chunk.size()) {
|
if (ptr < chunk.size()) {
|
||||||
const bool fastPropagate = ((chunk[ptr++] & 0x01) != 0);
|
const bool fastPropagate = ((chunk[ptr++] & 0x01) != 0);
|
||||||
@ -989,15 +991,25 @@ uint64_t Network::handleConfigChunk(const Packet &chunk,unsigned int ptr)
|
|||||||
if (c->haveBytes == totalLength) {
|
if (c->haveBytes == totalLength) {
|
||||||
c->data.unsafeData()[c->haveBytes] = (char)0; // ensure null terminated
|
c->data.unsafeData()[c->haveBytes] = (char)0; // ensure null terminated
|
||||||
|
|
||||||
NetworkConfig *const nc = new NetworkConfig();
|
nc = new NetworkConfig();
|
||||||
try {
|
try {
|
||||||
if (nc->fromDictionary(c->data)) {
|
if (!nc->fromDictionary(c->data)) {
|
||||||
|
delete nc;
|
||||||
|
nc = (NetworkConfig *)0;
|
||||||
|
}
|
||||||
|
} catch ( ... ) {
|
||||||
|
delete nc;
|
||||||
|
nc = (NetworkConfig *)0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nc) {
|
||||||
this->_setConfiguration(*nc,true);
|
this->_setConfiguration(*nc,true);
|
||||||
delete nc;
|
delete nc;
|
||||||
return configUpdateId;
|
return configUpdateId;
|
||||||
}
|
} else {
|
||||||
} catch ( ... ) {}
|
return 0;
|
||||||
delete nc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1027,10 +1039,9 @@ void Network::requestConfiguration()
|
|||||||
NetworkConfig *nconf = new NetworkConfig();
|
NetworkConfig *nconf = new NetworkConfig();
|
||||||
try {
|
try {
|
||||||
switch(RR->localNetworkController->doNetworkConfigRequest(InetAddress(),RR->identity,RR->identity,_id,rmd,*nconf)) {
|
switch(RR->localNetworkController->doNetworkConfigRequest(InetAddress(),RR->identity,RR->identity,_id,rmd,*nconf)) {
|
||||||
case NetworkController::NETCONF_QUERY_OK: {
|
case NetworkController::NETCONF_QUERY_OK:
|
||||||
Mutex::Lock _l(_lock);
|
|
||||||
this->_setConfiguration(*nconf,true);
|
this->_setConfiguration(*nconf,true);
|
||||||
} break;
|
break;
|
||||||
case NetworkController::NETCONF_QUERY_OBJECT_NOT_FOUND:
|
case NetworkController::NETCONF_QUERY_OBJECT_NOT_FOUND:
|
||||||
this->setNotFound();
|
this->setNotFound();
|
||||||
break;
|
break;
|
||||||
@ -1238,7 +1249,7 @@ ZT_VirtualNetworkStatus Network::_status() const
|
|||||||
|
|
||||||
int Network::_setConfiguration(const NetworkConfig &nconf,bool saveToDisk)
|
int Network::_setConfiguration(const NetworkConfig &nconf,bool saveToDisk)
|
||||||
{
|
{
|
||||||
// assumes _lock is locked
|
// _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))
|
||||||
return 0;
|
return 0;
|
||||||
@ -1246,20 +1257,27 @@ int Network::_setConfiguration(const NetworkConfig &nconf,bool saveToDisk)
|
|||||||
return 1; // OK config, but duplicate of what we already have
|
return 1; // OK config, but duplicate of what we already have
|
||||||
|
|
||||||
ZT_VirtualNetworkConfig ctmp;
|
ZT_VirtualNetworkConfig ctmp;
|
||||||
|
bool oldPortInitialized;
|
||||||
|
{
|
||||||
|
Mutex::Lock _l(_lock);
|
||||||
_config = nconf;
|
_config = nconf;
|
||||||
_lastConfigUpdate = RR->node->now();
|
_lastConfigUpdate = RR->node->now();
|
||||||
_netconfFailure = NETCONF_FAILURE_NONE;
|
_netconfFailure = NETCONF_FAILURE_NONE;
|
||||||
_externalConfig(&ctmp);
|
oldPortInitialized = _portInitialized;
|
||||||
const bool oldPortInitialized = _portInitialized;
|
|
||||||
_portInitialized = true;
|
_portInitialized = true;
|
||||||
|
_externalConfig(&ctmp);
|
||||||
|
}
|
||||||
_portError = RR->node->configureVirtualNetworkPort(_id,&_uPtr,(oldPortInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp);
|
_portError = RR->node->configureVirtualNetworkPort(_id,&_uPtr,(oldPortInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp);
|
||||||
|
|
||||||
if (saveToDisk) {
|
if (saveToDisk) {
|
||||||
|
Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> *d = new Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY>();
|
||||||
|
try {
|
||||||
char n[64];
|
char n[64];
|
||||||
Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.conf",_id);
|
Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.conf",_id);
|
||||||
Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> d;
|
if (nconf.toDictionary(*d,false))
|
||||||
if (nconf.toDictionary(d,false))
|
RR->node->dataStorePut(n,(const void *)d->data(),d->sizeBytes(),true);
|
||||||
RR->node->dataStorePut(n,(const void *)d.data(),d.sizeBytes(),true);
|
} catch ( ... ) {}
|
||||||
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 2; // OK and configuration has changed
|
return 2; // OK and configuration has changed
|
||||||
|
Loading…
x
Reference in New Issue
Block a user