Safety upgrades to code

This commit is contained in:
Adam Ierymenko 2019-08-28 10:34:32 -07:00
parent 1977b9b764
commit 59ee0cfe88
No known key found for this signature in database
GPG Key ID: C8877CF2D7A5D7F3
9 changed files with 196 additions and 191 deletions

View File

@ -38,6 +38,7 @@ set(core_headers
RingBuffer.hpp
RuntimeEnvironment.hpp
Salsa20.hpp
ScopedPtr.hpp
SelfAwareness.hpp
SHA512.hpp
SharedPtr.hpp

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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
View 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