mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-01-29 15:43:52 +00:00
Safety upgrades to code
This commit is contained in:
parent
1977b9b764
commit
59ee0cfe88
@ -38,6 +38,7 @@ set(core_headers
|
||||
RingBuffer.hpp
|
||||
RuntimeEnvironment.hpp
|
||||
Salsa20.hpp
|
||||
ScopedPtr.hpp
|
||||
SelfAwareness.hpp
|
||||
SHA512.hpp
|
||||
SharedPtr.hpp
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "Revocation.hpp"
|
||||
#include "Switch.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "ScopedPtr.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
@ -37,10 +38,9 @@ static inline Credential::VerifyResult _credVerify(const RuntimeEnvironment *con
|
||||
return Credential::VERIFY_NEED_IDENTITY;
|
||||
}
|
||||
try {
|
||||
Buffer<(sizeof(CRED) + 64)> *const tmp = new Buffer<(sizeof(CRED) + 64)>();
|
||||
ScopedPtr< Buffer<(sizeof(CRED) + 64)> > tmp(new Buffer<(sizeof(CRED) + 64)>());
|
||||
credential.serialize(*tmp,true);
|
||||
const Credential::VerifyResult result = (id.verify(tmp->data(),tmp->size(),credential.signature(),credential.signatureLength()) ? Credential::VERIFY_OK : Credential::VERIFY_BAD_SIGNATURE);
|
||||
delete tmp;
|
||||
return result;
|
||||
} catch ( ... ) {}
|
||||
return Credential::VERIFY_BAD_SIGNATURE;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "Buffer.hpp"
|
||||
#include "SHA512.hpp"
|
||||
#include "Str.hpp"
|
||||
#include "ScopedPtr.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
@ -101,14 +102,12 @@ public:
|
||||
} else {
|
||||
_signedBy = signingId;
|
||||
}
|
||||
Buffer<65536> *tmp = new Buffer<65536>();
|
||||
try {
|
||||
ScopedPtr< Buffer<65536> > tmp(new Buffer<65536>());
|
||||
serialize(*tmp,true);
|
||||
_signatureLength = signingId.sign(tmp->data(),tmp->size(),_signature,ZT_SIGNATURE_BUFFER_SIZE);
|
||||
delete tmp;
|
||||
return (_signatureLength > 0);
|
||||
} catch ( ... ) {
|
||||
delete tmp;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -120,15 +119,12 @@ public:
|
||||
{
|
||||
if ((_signatureLength == 0)||(_signatureLength > sizeof(_signature)))
|
||||
return false;
|
||||
Buffer<65536> *tmp = nullptr;
|
||||
try {
|
||||
tmp = new Buffer<65536>();
|
||||
ScopedPtr< Buffer<65536> > tmp(new Buffer<65536>());
|
||||
serialize(*tmp,true);
|
||||
const bool ok = (_signedBy) ? _signedBy.verify(tmp->data(),tmp->size(),_signature,_signatureLength) : _id.verify(tmp->data(),tmp->size(),_signature,_signatureLength);
|
||||
delete tmp;
|
||||
return ok;
|
||||
} catch ( ... ) {
|
||||
if (tmp) delete tmp;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -150,7 +146,7 @@ public:
|
||||
uint8_t s384[48];
|
||||
char enc[256];
|
||||
|
||||
Buffer<65536> *const tmp = new Buffer<65536>();
|
||||
ScopedPtr< Buffer<65536> > tmp(new Buffer<65536>());
|
||||
serialize(*tmp,false);
|
||||
SHA384(s384,tmp->data(),tmp->size());
|
||||
ECC384ECDSASign(p384SigningKeyPrivate,s384,((uint8_t *)tmp->unsafeData()) + tmp->size());
|
||||
@ -172,7 +168,6 @@ public:
|
||||
++txtRecNo;
|
||||
}
|
||||
|
||||
delete tmp;
|
||||
return txtRecords;
|
||||
}
|
||||
|
||||
@ -192,7 +187,6 @@ public:
|
||||
inline bool decodeTxtRecords(I start,I end,const uint8_t p384SigningKeyPublic[ZT_ECC384_PUBLIC_KEY_SIZE])
|
||||
{
|
||||
uint8_t dec[256],s384[48];
|
||||
Buffer<65536> *tmp = nullptr;
|
||||
try {
|
||||
std::vector<Str> txtRecords;
|
||||
while (start != end) {
|
||||
@ -206,26 +200,22 @@ public:
|
||||
return false;
|
||||
std::sort(txtRecords.begin(),txtRecords.end());
|
||||
|
||||
tmp = new Buffer<65536>();
|
||||
ScopedPtr< Buffer<65536> > tmp(new Buffer<65536>());
|
||||
for(std::vector<Str>::const_iterator i(txtRecords.begin());i!=txtRecords.end();++i)
|
||||
tmp->append(dec,Utils::b64d(i->c_str() + 2,dec,sizeof(dec)));
|
||||
|
||||
if (tmp->size() <= ZT_ECC384_SIGNATURE_SIZE) {
|
||||
delete tmp;
|
||||
return false;
|
||||
}
|
||||
SHA384(s384,tmp->data(),tmp->size() - ZT_ECC384_SIGNATURE_SIZE);
|
||||
if (!ECC384ECDSAVerify(p384SigningKeyPublic,s384,((const uint8_t *)tmp->data()) + (tmp->size() - ZT_ECC384_SIGNATURE_SIZE))) {
|
||||
delete tmp;
|
||||
return false;
|
||||
}
|
||||
|
||||
deserialize(*tmp,0);
|
||||
delete tmp;
|
||||
|
||||
return verify();
|
||||
} catch ( ... ) {
|
||||
if (tmp) delete tmp;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "Node.hpp"
|
||||
#include "Peer.hpp"
|
||||
#include "Trace.hpp"
|
||||
#include "ScopedPtr.hpp"
|
||||
|
||||
#include <set>
|
||||
|
||||
@ -561,22 +562,20 @@ Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,void *u
|
||||
tmp[0] = nwid; tmp[1] = 0;
|
||||
|
||||
bool got = false;
|
||||
Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> *dict = new Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY>();
|
||||
ScopedPtr< Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> > dict(new Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY>());
|
||||
try {
|
||||
int n = RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp,dict->unsafeData(),ZT_NETWORKCONFIG_DICT_CAPACITY - 1);
|
||||
if (n > 1) {
|
||||
NetworkConfig *nconf = new NetworkConfig();
|
||||
try {
|
||||
ScopedPtr<NetworkConfig> nconf(new NetworkConfig());
|
||||
if (nconf->fromDictionary(*dict)) {
|
||||
this->setConfiguration(tPtr,*nconf,false);
|
||||
_lastConfigUpdate = 0; // still want to re-request an update since it's likely outdated
|
||||
got = true;
|
||||
}
|
||||
} catch ( ... ) {}
|
||||
delete nconf;
|
||||
}
|
||||
} catch ( ... ) {}
|
||||
delete dict;
|
||||
|
||||
if (!got)
|
||||
RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp,"\n",1);
|
||||
@ -856,7 +855,6 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add
|
||||
const unsigned int chunkLen = chunk.at<uint16_t>(ptr); ptr += 2;
|
||||
const void *chunkData = chunk.field(ptr,chunkLen); ptr += chunkLen;
|
||||
|
||||
NetworkConfig *nc = (NetworkConfig *)0;
|
||||
uint64_t configUpdateId;
|
||||
{
|
||||
Mutex::Lock l1(_config_l);
|
||||
@ -953,27 +951,16 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add
|
||||
if (c->haveBytes == totalLength) {
|
||||
c->data.unsafeData()[c->haveBytes] = (char)0; // ensure null terminated
|
||||
|
||||
nc = new NetworkConfig();
|
||||
ScopedPtr<NetworkConfig> nc(new NetworkConfig());
|
||||
try {
|
||||
if (!nc->fromDictionary(c->data)) {
|
||||
delete nc;
|
||||
nc = (NetworkConfig *)0;
|
||||
if (nc->fromDictionary(c->data)) {
|
||||
this->setConfiguration(tPtr,*nc,true);
|
||||
return configUpdateId;
|
||||
}
|
||||
} catch ( ... ) {
|
||||
delete nc;
|
||||
nc = (NetworkConfig *)0;
|
||||
}
|
||||
} catch ( ... ) {}
|
||||
}
|
||||
}
|
||||
|
||||
if (nc) {
|
||||
this->setConfiguration(tPtr,*nc,true);
|
||||
delete nc;
|
||||
return configUpdateId;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1007,15 +994,14 @@ int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToD
|
||||
_portError = RR->node->configureVirtualNetworkPort(tPtr,_id,&_uPtr,(oldPortInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp);
|
||||
|
||||
if (saveToDisk) {
|
||||
Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> *const d = new Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY>();
|
||||
try {
|
||||
ScopedPtr< Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> > d(new Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY>());
|
||||
if (nconf.toDictionary(*d,false)) {
|
||||
uint64_t tmp[2];
|
||||
tmp[0] = _id; tmp[1] = 0;
|
||||
RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp,d->data(),d->sizeBytes());
|
||||
}
|
||||
} catch ( ... ) {}
|
||||
delete d;
|
||||
}
|
||||
|
||||
return 2; // OK and configuration has changed
|
||||
@ -1120,7 +1106,7 @@ void Network::_requestConfiguration(void *tPtr)
|
||||
const uint16_t startPortRange = (uint16_t)((_id >> 40) & 0xffff);
|
||||
const uint16_t endPortRange = (uint16_t)((_id >> 24) & 0xffff);
|
||||
if (endPortRange >= startPortRange) {
|
||||
NetworkConfig *const nconf = new NetworkConfig();
|
||||
ScopedPtr<NetworkConfig> nconf(new NetworkConfig());
|
||||
|
||||
nconf->networkId = _id;
|
||||
nconf->timestamp = RR->node->now();
|
||||
@ -1182,7 +1168,6 @@ void Network::_requestConfiguration(void *tPtr)
|
||||
nconf->name[15] = (char)0;
|
||||
|
||||
this->setConfiguration(tPtr,*nconf,false);
|
||||
delete nconf;
|
||||
} else {
|
||||
this->setNotFound();
|
||||
}
|
||||
@ -1200,7 +1185,7 @@ void Network::_requestConfiguration(void *tPtr)
|
||||
char v4ascii[24];
|
||||
Utils::decimal(ipv4[0],v4ascii);
|
||||
|
||||
NetworkConfig *const nconf = new NetworkConfig();
|
||||
ScopedPtr<NetworkConfig> nconf(new NetworkConfig());
|
||||
|
||||
nconf->networkId = _id;
|
||||
nconf->timestamp = RR->node->now();
|
||||
@ -1241,32 +1226,31 @@ void Network::_requestConfiguration(void *tPtr)
|
||||
nconf->name[nn++] = (char)0;
|
||||
|
||||
this->setConfiguration(tPtr,*nconf,false);
|
||||
delete nconf;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const Address ctrl(controller());
|
||||
|
||||
Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> rmd;
|
||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,(uint64_t)ZT_NETWORKCONFIG_VERSION);
|
||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_VENDOR,(uint64_t)ZT_VENDOR_ZEROTIER);
|
||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION,(uint64_t)ZT_PROTO_VERSION);
|
||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,(uint64_t)ZEROTIER_ONE_VERSION_MAJOR);
|
||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION,(uint64_t)ZEROTIER_ONE_VERSION_MINOR);
|
||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION,(uint64_t)ZEROTIER_ONE_VERSION_REVISION);
|
||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_RULES,(uint64_t)ZT_MAX_NETWORK_RULES);
|
||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_CAPABILITIES,(uint64_t)ZT_MAX_NETWORK_CAPABILITIES);
|
||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_CAPABILITY_RULES,(uint64_t)ZT_MAX_CAPABILITY_RULES);
|
||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_TAGS,(uint64_t)ZT_MAX_NETWORK_TAGS);
|
||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS,(uint64_t)0);
|
||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV,(uint64_t)ZT_RULES_ENGINE_REVISION);
|
||||
ScopedPtr< Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> > rmd(new Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY>());
|
||||
rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,(uint64_t)ZT_NETWORKCONFIG_VERSION);
|
||||
rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_VENDOR,(uint64_t)ZT_VENDOR_ZEROTIER);
|
||||
rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION,(uint64_t)ZT_PROTO_VERSION);
|
||||
rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,(uint64_t)ZEROTIER_ONE_VERSION_MAJOR);
|
||||
rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION,(uint64_t)ZEROTIER_ONE_VERSION_MINOR);
|
||||
rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION,(uint64_t)ZEROTIER_ONE_VERSION_REVISION);
|
||||
rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_RULES,(uint64_t)ZT_MAX_NETWORK_RULES);
|
||||
rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_CAPABILITIES,(uint64_t)ZT_MAX_NETWORK_CAPABILITIES);
|
||||
rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_CAPABILITY_RULES,(uint64_t)ZT_MAX_CAPABILITY_RULES);
|
||||
rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_TAGS,(uint64_t)ZT_MAX_NETWORK_TAGS);
|
||||
rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS,(uint64_t)0);
|
||||
rmd->add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV,(uint64_t)ZT_RULES_ENGINE_REVISION);
|
||||
|
||||
RR->t->networkConfigRequestSent(tPtr,*this,ctrl);
|
||||
|
||||
if (ctrl == RR->identity.address()) {
|
||||
if (RR->localNetworkController) {
|
||||
RR->localNetworkController->request(_id,InetAddress(),0xffffffffffffffffULL,RR->identity,rmd);
|
||||
RR->localNetworkController->request(_id,InetAddress(),0xffffffffffffffffULL,RR->identity,*rmd);
|
||||
} else {
|
||||
this->setNotFound();
|
||||
}
|
||||
@ -1275,9 +1259,9 @@ void Network::_requestConfiguration(void *tPtr)
|
||||
|
||||
Packet outp(ctrl,RR->identity.address(),Packet::VERB_NETWORK_CONFIG_REQUEST);
|
||||
outp.append((uint64_t)_id);
|
||||
const unsigned int rmdSize = rmd.sizeBytes();
|
||||
const unsigned int rmdSize = rmd->sizeBytes();
|
||||
outp.append((uint16_t)rmdSize);
|
||||
outp.append((const void *)rmd.data(),rmdSize);
|
||||
outp.append((const void *)rmd->data(),rmdSize);
|
||||
if (_config) {
|
||||
outp.append((uint64_t)_config.revision);
|
||||
outp.append((uint64_t)_config.timestamp);
|
||||
@ -1373,7 +1357,7 @@ void Network::_announceMulticastGroups(void *tPtr,bool force)
|
||||
void Network::_announceMulticastGroupsTo(void *tPtr,const Address &peer,const std::vector<MulticastGroup> &allMulticastGroups)
|
||||
{
|
||||
// Assumes _myMulticastGroups_l and _memberships_l are locked
|
||||
Packet *const outp = new Packet(peer,RR->identity.address(),Packet::VERB_MULTICAST_LIKE);
|
||||
ScopedPtr<Packet> outp(new Packet(peer,RR->identity.address(),Packet::VERB_MULTICAST_LIKE));
|
||||
|
||||
for(std::vector<MulticastGroup>::const_iterator mg(allMulticastGroups.begin());mg!=allMulticastGroups.end();++mg) {
|
||||
if ((outp->size() + 24) >= ZT_PROTO_MAX_PACKET_LENGTH) {
|
||||
@ -1392,8 +1376,6 @@ void Network::_announceMulticastGroupsTo(void *tPtr,const Address &peer,const st
|
||||
outp->compress();
|
||||
RR->sw->send(tPtr,*outp,true);
|
||||
}
|
||||
|
||||
delete outp;
|
||||
}
|
||||
|
||||
std::vector<MulticastGroup> Network::_allMulticastGroups() const
|
||||
|
@ -16,99 +16,93 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "NetworkConfig.hpp"
|
||||
#include "ScopedPtr.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
bool NetworkConfig::toDictionary(Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d,bool includeLegacy) const
|
||||
{
|
||||
Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY> *tmp = new Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY>();
|
||||
ScopedPtr< Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY> > tmp(new Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY>());
|
||||
char tmp2[128];
|
||||
|
||||
try {
|
||||
d.clear();
|
||||
d.clear();
|
||||
|
||||
// Try to put the more human-readable fields first
|
||||
// Try to put the more human-readable fields first
|
||||
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_VERSION,(uint64_t)ZT_NETWORKCONFIG_VERSION)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID,this->networkId)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP,this->timestamp)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CREDENTIAL_TIME_MAX_DELTA,this->credentialTimeMaxDelta)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_REVISION,this->revision)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO,this->issuedTo.toString(tmp2))) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_TARGET,this->remoteTraceTarget.toString(tmp2))) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_LEVEL,(uint64_t)this->remoteTraceLevel)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_FLAGS,this->flags)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT,(uint64_t)this->multicastLimit)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TYPE,(uint64_t)this->type)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_NAME,this->name)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_MTU,(uint64_t)this->mtu)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_VERSION,(uint64_t)ZT_NETWORKCONFIG_VERSION)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID,this->networkId)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP,this->timestamp)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CREDENTIAL_TIME_MAX_DELTA,this->credentialTimeMaxDelta)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_REVISION,this->revision)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO,this->issuedTo.toString(tmp2))) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_TARGET,this->remoteTraceTarget.toString(tmp2))) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_LEVEL,(uint64_t)this->remoteTraceLevel)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_FLAGS,this->flags)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT,(uint64_t)this->multicastLimit)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TYPE,(uint64_t)this->type)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_NAME,this->name)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_MTU,(uint64_t)this->mtu)) return false;
|
||||
|
||||
// Then add binary blobs
|
||||
|
||||
if (this->com) {
|
||||
tmp->clear();
|
||||
this->com.serialize(*tmp);
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_COM,*tmp)) return false;
|
||||
}
|
||||
// Then add binary blobs
|
||||
|
||||
if (this->com) {
|
||||
tmp->clear();
|
||||
for(unsigned int i=0;i<this->capabilityCount;++i)
|
||||
this->capabilities[i].serialize(*tmp);
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES,*tmp)) return false;
|
||||
}
|
||||
this->com.serialize(*tmp);
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_COM,*tmp)) return false;
|
||||
}
|
||||
|
||||
tmp->clear();
|
||||
for(unsigned int i=0;i<this->capabilityCount;++i)
|
||||
this->capabilities[i].serialize(*tmp);
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES,*tmp)) return false;
|
||||
}
|
||||
|
||||
tmp->clear();
|
||||
for(unsigned int i=0;i<this->tagCount;++i)
|
||||
this->tags[i].serialize(*tmp);
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TAGS,*tmp)) return false;
|
||||
}
|
||||
|
||||
tmp->clear();
|
||||
for(unsigned int i=0;i<this->certificateOfOwnershipCount;++i)
|
||||
this->certificatesOfOwnership[i].serialize(*tmp);
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATES_OF_OWNERSHIP,*tmp)) return false;
|
||||
}
|
||||
|
||||
tmp->clear();
|
||||
for(unsigned int i=0;i<this->specialistCount;++i)
|
||||
tmp->append((uint64_t)this->specialists[i]);
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_SPECIALISTS,*tmp)) return false;
|
||||
}
|
||||
|
||||
tmp->clear();
|
||||
for(unsigned int i=0;i<this->routeCount;++i) {
|
||||
reinterpret_cast<const InetAddress *>(&(this->routes[i].target))->serialize(*tmp);
|
||||
reinterpret_cast<const InetAddress *>(&(this->routes[i].via))->serialize(*tmp);
|
||||
tmp->append((uint16_t)this->routes[i].flags);
|
||||
tmp->append((uint16_t)this->routes[i].metric);
|
||||
}
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ROUTES,*tmp)) return false;
|
||||
}
|
||||
|
||||
tmp->clear();
|
||||
for(unsigned int i=0;i<this->staticIpCount;++i)
|
||||
this->staticIps[i].serialize(*tmp);
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_STATIC_IPS,*tmp)) return false;
|
||||
}
|
||||
|
||||
if (this->ruleCount) {
|
||||
tmp->clear();
|
||||
for(unsigned int i=0;i<this->tagCount;++i)
|
||||
this->tags[i].serialize(*tmp);
|
||||
Capability::serializeRules(*tmp,rules,ruleCount);
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TAGS,*tmp)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_RULES,*tmp)) return false;
|
||||
}
|
||||
|
||||
tmp->clear();
|
||||
for(unsigned int i=0;i<this->certificateOfOwnershipCount;++i)
|
||||
this->certificatesOfOwnership[i].serialize(*tmp);
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATES_OF_OWNERSHIP,*tmp)) return false;
|
||||
}
|
||||
|
||||
tmp->clear();
|
||||
for(unsigned int i=0;i<this->specialistCount;++i)
|
||||
tmp->append((uint64_t)this->specialists[i]);
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_SPECIALISTS,*tmp)) return false;
|
||||
}
|
||||
|
||||
tmp->clear();
|
||||
for(unsigned int i=0;i<this->routeCount;++i) {
|
||||
reinterpret_cast<const InetAddress *>(&(this->routes[i].target))->serialize(*tmp);
|
||||
reinterpret_cast<const InetAddress *>(&(this->routes[i].via))->serialize(*tmp);
|
||||
tmp->append((uint16_t)this->routes[i].flags);
|
||||
tmp->append((uint16_t)this->routes[i].metric);
|
||||
}
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ROUTES,*tmp)) return false;
|
||||
}
|
||||
|
||||
tmp->clear();
|
||||
for(unsigned int i=0;i<this->staticIpCount;++i)
|
||||
this->staticIps[i].serialize(*tmp);
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_STATIC_IPS,*tmp)) return false;
|
||||
}
|
||||
|
||||
if (this->ruleCount) {
|
||||
tmp->clear();
|
||||
Capability::serializeRules(*tmp,rules,ruleCount);
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_RULES,*tmp)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
delete tmp;
|
||||
} catch ( ... ) {
|
||||
delete tmp;
|
||||
throw;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -117,25 +111,21 @@ bool NetworkConfig::toDictionary(Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d,b
|
||||
bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d)
|
||||
{
|
||||
static const NetworkConfig NIL_NC;
|
||||
Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY> *const tmp = new Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY>();
|
||||
ScopedPtr< Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY> > tmp(new Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY>());
|
||||
|
||||
try {
|
||||
*this = NIL_NC;
|
||||
|
||||
// Fields that are always present, new or old
|
||||
this->networkId = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID,0);
|
||||
if (!this->networkId) {
|
||||
delete tmp;
|
||||
if (!this->networkId)
|
||||
return false;
|
||||
}
|
||||
this->timestamp = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP,0);
|
||||
this->credentialTimeMaxDelta = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_CREDENTIAL_TIME_MAX_DELTA,0);
|
||||
this->revision = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_REVISION,0);
|
||||
this->issuedTo = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO,0);
|
||||
if (!this->issuedTo) {
|
||||
delete tmp;
|
||||
if (!this->issuedTo)
|
||||
return false;
|
||||
}
|
||||
this->remoteTraceTarget = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_TARGET);
|
||||
this->remoteTraceLevel = (Trace::Level)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_REMOTE_TRACE_LEVEL);
|
||||
this->multicastLimit = (unsigned int)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT,0);
|
||||
@ -148,7 +138,6 @@ bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACI
|
||||
this->mtu = ZT_MAX_MTU;
|
||||
|
||||
if (d.getUI(ZT_NETWORKCONFIG_DICT_KEY_VERSION,0) < 6) {
|
||||
delete tmp;
|
||||
return false;
|
||||
} else {
|
||||
// Otherwise we can use the new fields
|
||||
@ -228,10 +217,8 @@ bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACI
|
||||
}
|
||||
}
|
||||
|
||||
delete tmp;
|
||||
return true;
|
||||
} catch ( ... ) {
|
||||
delete tmp;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ namespace ZeroTier {
|
||||
#define ZT_NETWORKCONFIG_DICT_CAPACITY (1024 + (sizeof(ZT_VirtualNetworkRule) * ZT_MAX_NETWORK_RULES) + (sizeof(Capability) * ZT_MAX_NETWORK_CAPABILITIES) + (sizeof(Tag) * ZT_MAX_NETWORK_TAGS) + (sizeof(CertificateOfOwnership) * ZT_MAX_CERTIFICATES_OF_OWNERSHIP))
|
||||
|
||||
// Dictionary capacity needed for max size network meta-data
|
||||
#define ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY 2048
|
||||
#define ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY 8192
|
||||
|
||||
// Network config version
|
||||
#define ZT_NETWORKCONFIG_VERSION 7
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "SelfAwareness.hpp"
|
||||
#include "Network.hpp"
|
||||
#include "Trace.hpp"
|
||||
#include "ScopedPtr.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
@ -558,47 +559,41 @@ void Node::ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &de
|
||||
if (!n) return;
|
||||
n->setConfiguration((void *)0,nc,true);
|
||||
} else {
|
||||
Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> *dconf = new Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY>();
|
||||
try {
|
||||
if (nc.toDictionary(*dconf,sendLegacyFormatConfig)) {
|
||||
uint64_t configUpdateId = Utils::random();
|
||||
if (!configUpdateId) ++configUpdateId;
|
||||
ScopedPtr< Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> > dconf(new Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY>());
|
||||
if (nc.toDictionary(*dconf,sendLegacyFormatConfig)) {
|
||||
uint64_t configUpdateId = Utils::random();
|
||||
if (!configUpdateId) ++configUpdateId;
|
||||
|
||||
const unsigned int totalSize = dconf->sizeBytes();
|
||||
unsigned int chunkIndex = 0;
|
||||
while (chunkIndex < totalSize) {
|
||||
const unsigned int chunkLen = std::min(totalSize - chunkIndex,(unsigned int)(ZT_PROTO_MAX_PACKET_LENGTH - (ZT_PACKET_IDX_PAYLOAD + 256)));
|
||||
Packet outp(destination,RR->identity.address(),(requestPacketId) ? Packet::VERB_OK : Packet::VERB_NETWORK_CONFIG);
|
||||
if (requestPacketId) {
|
||||
outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
|
||||
outp.append(requestPacketId);
|
||||
}
|
||||
|
||||
const unsigned int sigStart = outp.size();
|
||||
outp.append(nwid);
|
||||
outp.append((uint16_t)chunkLen);
|
||||
outp.append((const void *)(dconf->data() + chunkIndex),chunkLen);
|
||||
|
||||
outp.append((uint8_t)0); // no flags
|
||||
outp.append((uint64_t)configUpdateId);
|
||||
outp.append((uint32_t)totalSize);
|
||||
outp.append((uint32_t)chunkIndex);
|
||||
|
||||
uint8_t sig[256];
|
||||
const unsigned int siglen = RR->identity.sign(reinterpret_cast<const uint8_t *>(outp.data()) + sigStart,outp.size() - sigStart,sig,sizeof(sig));
|
||||
outp.append((uint8_t)1);
|
||||
outp.append((uint16_t)siglen);
|
||||
outp.append(sig,siglen);
|
||||
|
||||
outp.compress();
|
||||
RR->sw->send((void *)0,outp,true);
|
||||
chunkIndex += chunkLen;
|
||||
const unsigned int totalSize = dconf->sizeBytes();
|
||||
unsigned int chunkIndex = 0;
|
||||
while (chunkIndex < totalSize) {
|
||||
const unsigned int chunkLen = std::min(totalSize - chunkIndex,(unsigned int)(ZT_PROTO_MAX_PACKET_LENGTH - (ZT_PACKET_IDX_PAYLOAD + 256)));
|
||||
Packet outp(destination,RR->identity.address(),(requestPacketId) ? Packet::VERB_OK : Packet::VERB_NETWORK_CONFIG);
|
||||
if (requestPacketId) {
|
||||
outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
|
||||
outp.append(requestPacketId);
|
||||
}
|
||||
|
||||
const unsigned int sigStart = outp.size();
|
||||
outp.append(nwid);
|
||||
outp.append((uint16_t)chunkLen);
|
||||
outp.append((const void *)(dconf->data() + chunkIndex),chunkLen);
|
||||
|
||||
outp.append((uint8_t)0); // no flags
|
||||
outp.append((uint64_t)configUpdateId);
|
||||
outp.append((uint32_t)totalSize);
|
||||
outp.append((uint32_t)chunkIndex);
|
||||
|
||||
uint8_t sig[256];
|
||||
const unsigned int siglen = RR->identity.sign(reinterpret_cast<const uint8_t *>(outp.data()) + sigStart,outp.size() - sigStart,sig,sizeof(sig));
|
||||
outp.append((uint8_t)1);
|
||||
outp.append((uint16_t)siglen);
|
||||
outp.append(sig,siglen);
|
||||
|
||||
outp.compress();
|
||||
RR->sw->send((void *)0,outp,true);
|
||||
chunkIndex += chunkLen;
|
||||
}
|
||||
delete dconf;
|
||||
} catch ( ... ) {
|
||||
delete dconf;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "InetAddress.hpp"
|
||||
#include "RingBuffer.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "ScopedPtr.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
@ -173,7 +174,7 @@ void Peer::received(
|
||||
if (pathsToPush.size() > 0) {
|
||||
std::vector<InetAddress>::const_iterator p(pathsToPush.begin());
|
||||
while (p != pathsToPush.end()) {
|
||||
Packet *const outp = new Packet(_id.address(),RR->identity.address(),Packet::VERB_PUSH_DIRECT_PATHS);
|
||||
ScopedPtr<Packet> outp(new Packet(_id.address(),RR->identity.address(),Packet::VERB_PUSH_DIRECT_PATHS));
|
||||
outp->addSize(2); // leave room for count
|
||||
unsigned int count = 0;
|
||||
while ((p != pathsToPush.end())&&((outp->size() + 24) < 1200)) {
|
||||
@ -205,7 +206,6 @@ void Peer::received(
|
||||
outp->armor(_key,true);
|
||||
path->send(RR,tPtr,outp->data(),outp->size(),now);
|
||||
}
|
||||
delete outp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
50
node/ScopedPtr.hpp
Normal file
50
node/ScopedPtr.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c)2019 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2023-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
#ifndef ZT_SCOPEDPTR_HPP
|
||||
#define ZT_SCOPEDPTR_HPP
|
||||
|
||||
#include "Constants.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
* Simple scoped pointer
|
||||
*
|
||||
* This is used in the core to avoid requiring C++11 and because auto_ptr is weird.
|
||||
*/
|
||||
template<typename T>
|
||||
class ScopedPtr
|
||||
{
|
||||
public:
|
||||
ZT_ALWAYS_INLINE ScopedPtr(T *const p) : _p(p) {}
|
||||
ZT_ALWAYS_INLINE ~ScopedPtr() { delete _p; }
|
||||
|
||||
ZT_ALWAYS_INLINE T *operator->() const { return _p; }
|
||||
ZT_ALWAYS_INLINE T &operator*() const { return *_p; }
|
||||
ZT_ALWAYS_INLINE operator bool() const { return (_p != (T *)0); }
|
||||
ZT_ALWAYS_INLINE T *ptr() const { return _p; }
|
||||
|
||||
ZT_ALWAYS_INLINE bool operator==(const ScopedPtr &p) const { return (_p == p._p); }
|
||||
ZT_ALWAYS_INLINE bool operator!=(const ScopedPtr &p) const { return (_p != p._p); }
|
||||
ZT_ALWAYS_INLINE bool operator==(T *const p) const { return (_p == p); }
|
||||
ZT_ALWAYS_INLINE bool operator!=(T *const p) const { return (_p != p); }
|
||||
|
||||
private:
|
||||
ZT_ALWAYS_INLINE ScopedPtr() {}
|
||||
T *const _p;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user