From 59da359b06fd9309a91ddf42f67ada8bfa5b55f4 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 24 Jan 2020 23:36:08 -0800 Subject: [PATCH] More porting to new Buf system. --- node/CMakeLists.txt | 3 + node/CertificateOfMembership.cpp | 139 +++++++++++++++ node/CertificateOfMembership.hpp | 152 ++--------------- node/CertificateOfOwnership.cpp | 118 +++++++++++++ node/CertificateOfOwnership.hpp | 107 +----------- node/Dictionary.cpp | 224 ++++++++++++++++++++++++ node/Dictionary.hpp | 285 +++---------------------------- node/Identity.hpp | 103 ----------- node/InetAddress.hpp | 57 ------- node/MAC.hpp | 5 +- node/Membership.cpp | 1 - node/MulticastGroup.hpp | 2 +- node/NetworkConfig.cpp | 41 ++++- node/NetworkConfig.hpp | 63 ++----- node/Node.cpp | 3 +- node/Peer.hpp | 5 +- node/Revocation.hpp | 1 - node/Switch.cpp | 1 - node/Switch.hpp | 2 +- node/Tag.hpp | 1 - node/Utils.cpp | 28 +-- node/Utils.hpp | 13 +- 22 files changed, 607 insertions(+), 747 deletions(-) create mode 100644 node/CertificateOfMembership.cpp create mode 100644 node/CertificateOfOwnership.cpp create mode 100644 node/Dictionary.cpp diff --git a/node/CMakeLists.txt b/node/CMakeLists.txt index d2e4c9e45..8e13b2436 100644 --- a/node/CMakeLists.txt +++ b/node/CMakeLists.txt @@ -51,7 +51,10 @@ set(core_src Buf.cpp C25519.cpp Capability.cpp + CertificateOfMembership.cpp + CertificateOfOwnership.cpp Credential.cpp + Dictionary.cpp ECC384.cpp Endpoint.cpp Identity.cpp diff --git a/node/CertificateOfMembership.cpp b/node/CertificateOfMembership.cpp new file mode 100644 index 000000000..ae82ef03b --- /dev/null +++ b/node/CertificateOfMembership.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c)2013-2020 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: 2024-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. + */ +/****/ + +#include "CertificateOfMembership.hpp" + +namespace ZeroTier { + +CertificateOfMembership::CertificateOfMembership(uint64_t timestamp,uint64_t timestampMaxDelta,uint64_t nwid,const Address &issuedTo) +{ + _qualifiers[0].id = COM_RESERVED_ID_TIMESTAMP; + _qualifiers[0].value = timestamp; + _qualifiers[0].maxDelta = timestampMaxDelta; + _qualifiers[1].id = COM_RESERVED_ID_NETWORK_ID; + _qualifiers[1].value = nwid; + _qualifiers[1].maxDelta = 0; + _qualifiers[2].id = COM_RESERVED_ID_ISSUED_TO; + _qualifiers[2].value = issuedTo.toInt(); + _qualifiers[2].maxDelta = 0xffffffffffffffffULL; + _qualifierCount = 3; + _signatureLength = 0; +} + +void CertificateOfMembership::setQualifier(uint64_t id,uint64_t value,uint64_t maxDelta) +{ + _signedBy.zero(); + for(unsigned int i=0;i<_qualifierCount;++i) { + if (_qualifiers[i].id == id) { + _qualifiers[i].value = value; + _qualifiers[i].maxDelta = maxDelta; + return; + } + } + if (_qualifierCount < ZT_NETWORK_COM_MAX_QUALIFIERS) { + _qualifiers[_qualifierCount].id = id; + _qualifiers[_qualifierCount].value = value; + _qualifiers[_qualifierCount].maxDelta = maxDelta; + ++_qualifierCount; + std::sort(&(_qualifiers[0]),&(_qualifiers[_qualifierCount])); + } +} + +bool CertificateOfMembership::sign(const Identity &with) +{ + uint64_t buf[ZT_NETWORK_COM_MAX_QUALIFIERS * 3]; + unsigned int ptr = 0; + for(unsigned int i=0;i<_qualifierCount;++i) { + buf[ptr++] = Utils::hton(_qualifiers[i].id); + buf[ptr++] = Utils::hton(_qualifiers[i].value); + buf[ptr++] = Utils::hton(_qualifiers[i].maxDelta); + } + + try { + _signatureLength = with.sign(buf,ptr * sizeof(uint64_t),_signature,sizeof(_signature)); + _signedBy = with.address(); + return true; + } catch ( ... ) { + _signedBy.zero(); + return false; + } +} + +int CertificateOfMembership::marshal(uint8_t data[ZT_CERTIFICATEOFMEMBERSHIP_MARSHAL_SIZE_MAX]) const +{ + data[0] = 1; + Utils::storeBigEndian(data + 1,(uint16_t)_qualifierCount); + int p = 3; + for(unsigned int i=0;i<_qualifierCount;++i) { + Utils::storeBigEndian(data + p,_qualifiers[i].id); p += 8; + Utils::storeBigEndian(data + p,_qualifiers[i].value); p += 8; + Utils::storeBigEndian(data + p,_qualifiers[i].maxDelta); p += 8; + } + _signedBy.copyTo(data + p); p += ZT_ADDRESS_LENGTH; + if ((_signedBy)&&(_signatureLength == 96)) { + // UGLY: Ed25519 signatures in ZT are 96 bytes (64 + 32 bytes of hash). + // P-384 signatures are also 96 bytes, praise the horned one. That means + // we don't need to include a length. If we ever do we will need a new + // serialized object version, but only for those with length != 96. + memcpy(data + p,_signature,96); p += 96; + } + return p; +} + +int CertificateOfMembership::unmarshal(const uint8_t *data,int len) +{ + if ((len < 3)||(data[0] != 1)) + return -1; + unsigned int numq = Utils::loadBigEndian(data + 1); + if (numq > ZT_NETWORK_COM_MAX_QUALIFIERS) + return -1; + _qualifierCount = numq; + int p = 3; + for(unsigned int i=0;i len) + return -1; + _qualifiers[i].id = Utils::loadBigEndian(data + p); p += 8; + _qualifiers[i].value = Utils::loadBigEndian(data + p); p += 8; + _qualifiers[i].maxDelta = Utils::loadBigEndian(data + p); p += 8; + } + if ((p + ZT_ADDRESS_LENGTH) > len) + return -1; + _signedBy.setTo(data + p); p += ZT_ADDRESS_LENGTH; + if (_signedBy) { + if ((p + 96) > len) + return -1; + _signatureLength = 96; + memcpy(_signature,data + p,96); + p += 96; + } + return p; +} + +bool CertificateOfMembership::operator==(const CertificateOfMembership &c) const +{ + if (_signedBy != c._signedBy) + return false; + if (_qualifierCount != c._qualifierCount) + return false; + if (_signatureLength != c._signatureLength) + return false; + for(unsigned int i=0;i<_qualifierCount;++i) { + const _Qualifier &a = _qualifiers[i]; + const _Qualifier &b = c._qualifiers[i]; + if ((a.id != b.id)||(a.value != b.value)||(a.maxDelta != b.maxDelta)) + return false; + } + return (memcmp(_signature,c._signature,_signatureLength) == 0); +} + +} // namespace ZeroTier diff --git a/node/CertificateOfMembership.hpp b/node/CertificateOfMembership.hpp index 0afc88496..2e2b59a36 100644 --- a/node/CertificateOfMembership.hpp +++ b/node/CertificateOfMembership.hpp @@ -23,7 +23,6 @@ #include "Constants.hpp" #include "Credential.hpp" -#include "Buffer.hpp" #include "Address.hpp" #include "C25519.hpp" #include "Identity.hpp" @@ -34,6 +33,8 @@ */ #define ZT_NETWORK_COM_MAX_QUALIFIERS 8 +#define ZT_CERTIFICATEOFMEMBERSHIP_MARSHAL_SIZE_MAX (1 + 2 + (24 * ZT_NETWORK_COM_MAX_QUALIFIERS) + 5 + ZT_SIGNATURE_BUFFER_SIZE) + namespace ZeroTier { class RuntimeEnvironment; @@ -113,29 +114,7 @@ public: * @param nwid Network ID * @param issuedTo Certificate recipient */ - ZT_ALWAYS_INLINE CertificateOfMembership(uint64_t timestamp,uint64_t timestampMaxDelta,uint64_t nwid,const Address &issuedTo) - { - _qualifiers[0].id = COM_RESERVED_ID_TIMESTAMP; - _qualifiers[0].value = timestamp; - _qualifiers[0].maxDelta = timestampMaxDelta; - _qualifiers[1].id = COM_RESERVED_ID_NETWORK_ID; - _qualifiers[1].value = nwid; - _qualifiers[1].maxDelta = 0; - _qualifiers[2].id = COM_RESERVED_ID_ISSUED_TO; - _qualifiers[2].value = issuedTo.toInt(); - _qualifiers[2].maxDelta = 0xffffffffffffffffULL; - _qualifierCount = 3; - _signatureLength = 0; - } - - /** - * Create from binary-serialized COM in buffer - * - * @param b Buffer to deserialize from - * @param startAt Position to start in buffer - */ - template - ZT_ALWAYS_INLINE CertificateOfMembership(const Buffer &b,unsigned int startAt = 0) { deserialize(b,startAt); } + CertificateOfMembership(uint64_t timestamp,uint64_t timestampMaxDelta,uint64_t nwid,const Address &issuedTo); /** * @return True if there's something here @@ -192,24 +171,7 @@ public: * @param value Qualifier value * @param maxDelta Qualifier maximum allowed difference (absolute value of difference) */ - ZT_ALWAYS_INLINE void setQualifier(uint64_t id,uint64_t value,uint64_t maxDelta) - { - _signedBy.zero(); - for(unsigned int i=0;i<_qualifierCount;++i) { - if (_qualifiers[i].id == id) { - _qualifiers[i].value = value; - _qualifiers[i].maxDelta = maxDelta; - return; - } - } - if (_qualifierCount < ZT_NETWORK_COM_MAX_QUALIFIERS) { - _qualifiers[_qualifierCount].id = id; - _qualifiers[_qualifierCount].value = value; - _qualifiers[_qualifierCount].maxDelta = maxDelta; - ++_qualifierCount; - std::sort(&(_qualifiers[0]),&(_qualifiers[_qualifierCount])); - } - } + void setQualifier(uint64_t id,uint64_t value,uint64_t maxDelta); ZT_ALWAYS_INLINE void setQualifier(ReservedId id,uint64_t value,uint64_t maxDelta) { setQualifier((uint64_t)id,value,maxDelta); } @@ -268,25 +230,7 @@ public: * @param with Identity to sign with, must include private key * @return True if signature was successful */ - ZT_ALWAYS_INLINE bool sign(const Identity &with) - { - uint64_t buf[ZT_NETWORK_COM_MAX_QUALIFIERS * 3]; - unsigned int ptr = 0; - for(unsigned int i=0;i<_qualifierCount;++i) { - buf[ptr++] = Utils::hton(_qualifiers[i].id); - buf[ptr++] = Utils::hton(_qualifiers[i].value); - buf[ptr++] = Utils::hton(_qualifiers[i].maxDelta); - } - - try { - _signatureLength = with.sign(buf,ptr * sizeof(uint64_t),_signature,sizeof(_signature)); - _signedBy = with.address(); - return true; - } catch ( ... ) { - _signedBy.zero(); - return false; - } - } + bool sign(const Identity &with); /** * Verify this COM and its signature @@ -301,95 +245,21 @@ public: */ ZT_ALWAYS_INLINE const Address &signedBy() const { return _signedBy; } - template - inline void serialize(Buffer &b) const - { - b.append((uint8_t)1); - b.append((uint16_t)_qualifierCount); - for(unsigned int i=0;i<_qualifierCount;++i) { - b.append(_qualifiers[i].id); - b.append(_qualifiers[i].value); - b.append(_qualifiers[i].maxDelta); - } - _signedBy.appendTo(b); - if ((_signedBy)&&(_signatureLength == 96)) { - // UGLY: Ed25519 signatures in ZT are 96 bytes (64 + 32 bytes of hash). - // P-384 signatures are also 96 bytes, praise the horned one. That means - // we don't need to include a length. If we ever do we will need a new - // serialized object version, but only for those with length != 96. - b.append(_signature,96); - } - } + static ZT_ALWAYS_INLINE int marshalSizeMax() { return ZT_CERTIFICATEOFMEMBERSHIP_MARSHAL_SIZE_MAX; } + int marshal(uint8_t data[ZT_CERTIFICATEOFMEMBERSHIP_MARSHAL_SIZE_MAX]) const; + int unmarshal(const uint8_t *data,int len); - template - inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) - { - unsigned int p = startAt; - - _signedBy.zero(); - _qualifierCount = 0; - _signatureLength = 0; - - if (b[p++] != 1) - throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE; - - unsigned int numq = b.template at(p); p += sizeof(uint16_t); - uint64_t lastId = 0; - for(unsigned int i=0;i(p); - if (qid < lastId) - throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_BAD_ENCODING; - else lastId = qid; - if (_qualifierCount < ZT_NETWORK_COM_MAX_QUALIFIERS) { - _qualifiers[_qualifierCount].id = qid; - _qualifiers[_qualifierCount].value = b.template at(p + 8); - _qualifiers[_qualifierCount].maxDelta = b.template at(p + 16); - p += 24; - ++_qualifierCount; - } else { - throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW; - } - } - - _signedBy.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); - p += ZT_ADDRESS_LENGTH; - - if (_signedBy) { - // See "UGLY" comment in serialize()... - _signatureLength = 96; - memcpy(_signature,b.field(p,96),96); - p += 96; - } - - return (p - startAt); - } - - ZT_ALWAYS_INLINE bool operator==(const CertificateOfMembership &c) const - { - if (_signedBy != c._signedBy) - return false; - if (_qualifierCount != c._qualifierCount) - return false; - if (_signatureLength != c._signatureLength) - return false; - for(unsigned int i=0;i<_qualifierCount;++i) { - const _Qualifier &a = _qualifiers[i]; - const _Qualifier &b = c._qualifiers[i]; - if ((a.id != b.id)||(a.value != b.value)||(a.maxDelta != b.maxDelta)) - return false; - } - return (memcmp(_signature,c._signature,_signatureLength) == 0); - } + bool operator==(const CertificateOfMembership &c) const; ZT_ALWAYS_INLINE bool operator!=(const CertificateOfMembership &c) const { return (!(*this == c)); } private: struct _Qualifier { - _Qualifier() : id(0),value(0),maxDelta(0) {} + ZT_ALWAYS_INLINE _Qualifier() : id(0),value(0),maxDelta(0) {} uint64_t id; uint64_t value; uint64_t maxDelta; - inline bool operator<(const _Qualifier &q) const { return (id < q.id); } // sort order + ZT_ALWAYS_INLINE bool operator<(const _Qualifier &q) const { return (id < q.id); } // sort order }; Address _signedBy; diff --git a/node/CertificateOfOwnership.cpp b/node/CertificateOfOwnership.cpp new file mode 100644 index 000000000..d4aa5bc0d --- /dev/null +++ b/node/CertificateOfOwnership.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c)2013-2020 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: 2024-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. + */ +/****/ + +#include "CertificateOfOwnership.hpp" + +namespace ZeroTier { + +void CertificateOfOwnership::addThing(const InetAddress &ip) +{ + if (_thingCount >= ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS) return; + if (ip.ss_family == AF_INET) { + _thingTypes[_thingCount] = THING_IPV4_ADDRESS; + memcpy(_thingValues[_thingCount],&(reinterpret_cast(&ip)->sin_addr.s_addr),4); + ++_thingCount; + } else if (ip.ss_family == AF_INET6) { + _thingTypes[_thingCount] = THING_IPV6_ADDRESS; + memcpy(_thingValues[_thingCount],reinterpret_cast(&ip)->sin6_addr.s6_addr,16); + ++_thingCount; + } +} + +void CertificateOfOwnership::addThing(const MAC &mac) +{ + if (_thingCount >= ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS) return; + _thingTypes[_thingCount] = THING_MAC_ADDRESS; + mac.copyTo(_thingValues[_thingCount],6); + ++_thingCount; +} + +bool CertificateOfOwnership::sign(const Identity &signer) +{ + uint8_t buf[ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_SIZE_MAX + 16]; + if (signer.hasPrivate()) { + _signedBy = signer.address(); + _signatureLength = signer.sign(buf,(unsigned int)marshal(buf,true),_signature,sizeof(_signature)); + return true; + } + return false; +} + +int CertificateOfOwnership::marshal(uint8_t data[ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_SIZE_MAX],bool forSign) const +{ + int p = 0; + if (forSign) { + for(int k=0;k<16;++k) + data[p++] = 0x7f; + } + Utils::storeBigEndian(data + p,_networkId); + Utils::storeBigEndian(data + p + 8,(uint64_t)_ts); + Utils::storeBigEndian(data + p + 16,_flags); + Utils::storeBigEndian(data + p + 24,_id); + Utils::storeBigEndian(data + p + 28,(uint16_t)_thingCount); + p += 30; + for(unsigned int i=0,j=_thingCount;i(data + p,(uint16_t)_signatureLength); p += 2; + memcpy(data + p,_signature,_signatureLength); p += (int)_signatureLength; + } + data[p++] = 0; + data[p++] = 0; + if (forSign) { + for(int k=0;k<16;++k) + data[p++] = 0x7f; + } + return p; +} + +int CertificateOfOwnership::unmarshal(const uint8_t *data,int len) +{ + if (len < 30) + return -1; + + _networkId = Utils::loadBigEndian(data); + _ts = (int64_t)Utils::loadBigEndian(data + 8); + _flags = Utils::loadBigEndian(data + 16); + _id = Utils::loadBigEndian(data + 24); + _thingCount = Utils::loadBigEndian(data + 28); + if (_thingCount > ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS) + return -1; + int p = 30; + + for(unsigned int i=0,j=_thingCount;i len) + return -1; + _thingTypes[i] = data[p++]; + memcpy(_thingValues[i],data + p,ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE); + p += ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE; + } + + if ((p + ZT_ADDRESS_LENGTH + ZT_ADDRESS_LENGTH + 1 + 2) > len) + return -1; + _issuedTo.setTo(data + p); p += ZT_ADDRESS_LENGTH; + _signedBy.setTo(data + p); p += ZT_ADDRESS_LENGTH + 1; + + p += 2 + Utils::loadBigEndian(data + p); + if (p > len) + return -1; + return p; +} + +} // namespace ZeroTier diff --git a/node/CertificateOfOwnership.hpp b/node/CertificateOfOwnership.hpp index 1ea0fdee4..1c55a9ae2 100644 --- a/node/CertificateOfOwnership.hpp +++ b/node/CertificateOfOwnership.hpp @@ -24,7 +24,6 @@ #include "C25519.hpp" #include "Address.hpp" #include "Identity.hpp" -#include "Buffer.hpp" #include "InetAddress.hpp" #include "MAC.hpp" @@ -34,6 +33,8 @@ // Maximum size of a thing's value field in bytes #define ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE 16 +#define ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_SIZE_MAX (8 + 8 + 8 + 4 + 2 + ((1 + ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE) * ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS) + 5 + 5 + 1 + 2 + ZT_SIGNATURE_BUFFER_SIZE + 2) + namespace ZeroTier { class RuntimeEnvironment; @@ -98,112 +99,20 @@ public: return this->_owns(THING_MAC_ADDRESS,tmp,6); } - ZT_ALWAYS_INLINE void addThing(const InetAddress &ip) - { - if (_thingCount >= ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS) return; - if (ip.ss_family == AF_INET) { - _thingTypes[_thingCount] = THING_IPV4_ADDRESS; - memcpy(_thingValues[_thingCount],&(reinterpret_cast(&ip)->sin_addr.s_addr),4); - ++_thingCount; - } else if (ip.ss_family == AF_INET6) { - _thingTypes[_thingCount] = THING_IPV6_ADDRESS; - memcpy(_thingValues[_thingCount],reinterpret_cast(&ip)->sin6_addr.s6_addr,16); - ++_thingCount; - } - } - - ZT_ALWAYS_INLINE void addThing(const MAC &mac) - { - if (_thingCount >= ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS) return; - _thingTypes[_thingCount] = THING_MAC_ADDRESS; - mac.copyTo(_thingValues[_thingCount],6); - ++_thingCount; - } + void addThing(const InetAddress &ip); + void addThing(const MAC &mac); /** * @param signer Signing identity, must have private key * @return True if signature was successful */ - ZT_ALWAYS_INLINE bool sign(const Identity &signer) - { - if (signer.hasPrivate()) { - Buffer tmp; - _signedBy = signer.address(); - this->serialize(tmp,true); - _signatureLength = signer.sign(tmp.data(),tmp.size(),_signature,sizeof(_signature)); - return true; - } - return false; - } + bool sign(const Identity &signer); ZT_ALWAYS_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); } - template - inline void serialize(Buffer &b,const bool forSign = false) const - { - if (forSign) b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL); - - b.append(_networkId); - b.append(_ts); - b.append(_flags); - b.append(_id); - b.append((uint16_t)_thingCount); - for(unsigned int i=0,j=_thingCount;i - inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) - { - unsigned int p = startAt; - - *this = CertificateOfOwnership(); - - _networkId = b.template at(p); p += 8; - _ts = b.template at(p); p += 8; - _flags = b.template at(p); p += 8; - _id = b.template at(p); p += 4; - _thingCount = b.template at(p); p += 2; - for(unsigned int i=0,j=_thingCount;i(p); - if (_signatureLength > sizeof(_signature)) - throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN; - p += 2; - memcpy(_signature,b.field(p,_signatureLength),_signatureLength); p += _signatureLength; - } else { - p += 2 + b.template at(p); - } - - p += 2 + b.template at(p); - if (p > b.size()) - throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW; - - return (p - startAt); - } + static ZT_ALWAYS_INLINE int marshalSizeMax() { return ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_SIZE_MAX; } + int marshal(uint8_t data[ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_SIZE_MAX],bool forSign = false) const; + int unmarshal(const uint8_t *data,int len); // Provides natural sort order by ID ZT_ALWAYS_INLINE bool operator<(const CertificateOfOwnership &coo) const { return (_id < coo._id); } diff --git a/node/Dictionary.cpp b/node/Dictionary.cpp new file mode 100644 index 000000000..61a3d1725 --- /dev/null +++ b/node/Dictionary.cpp @@ -0,0 +1,224 @@ +/* + * Copyright (c)2013-2020 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: 2024-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. + */ +/****/ + +#include "Dictionary.hpp" + +namespace ZeroTier { + +Dictionary::Dictionary(const char *s,unsigned int len) +{ + for(unsigned int i=0;i 0) { + _d[j++] = (char)10; + if (j == ZT_DICTIONARY_MAX_CAPACITY) { + _d[i] = (char)0; + return false; + } + } + + const char *p = key; + while (*p) { + _d[j++] = *(p++); + if (j == ZT_DICTIONARY_MAX_CAPACITY) { + _d[i] = (char)0; + return false; + } + } + + _d[j++] = '='; + if (j == ZT_DICTIONARY_MAX_CAPACITY) { + _d[i] = (char)0; + return false; + } + + p = value; + int k = 0; + while ( ((vlen < 0)&&(*p)) || (k < vlen) ) { + switch(*p) { + case 0: + case 13: + case 10: + case '\\': + case '=': + _d[j++] = '\\'; + if (j == ZT_DICTIONARY_MAX_CAPACITY) { + _d[i] = (char)0; + return false; + } + switch(*p) { + case 0: _d[j++] = '0'; break; + case 13: _d[j++] = 'r'; break; + case 10: _d[j++] = 'n'; break; + case '\\': _d[j++] = '\\'; break; + case '=': _d[j++] = 'e'; break; + } + if (j == ZT_DICTIONARY_MAX_CAPACITY) { + _d[i] = (char)0; + return false; + } + break; + default: + _d[j++] = *p; + if (j == ZT_DICTIONARY_MAX_CAPACITY) { + _d[i] = (char)0; + return false; + } + break; + } + ++p; + ++k; + } + + _d[j] = (char)0; + + return true; + } + } + return false; +} + +bool Dictionary::add(const char *key,bool value) +{ + return this->add(key,(value) ? "1" : "0",1); +} + +bool Dictionary::add(const char *key,uint64_t value) +{ + char tmp[32]; + return this->add(key,Utils::hex(value,tmp),-1); +} + +bool Dictionary::add(const char *key,int64_t value) +{ + char tmp[32]; + if (value >= 0) { + return this->add(key,Utils::hex((uint64_t)value,tmp),-1); + } else { + tmp[0] = '-'; + return this->add(key,Utils::hex((uint64_t)(value * -1),tmp+1),-1); + } +} + +bool Dictionary::add(const char *key,const Address &a) +{ + char tmp[32]; + return this->add(key,Utils::hex(a.toInt(),tmp),-1); +} + +} // namespace ZeroTier diff --git a/node/Dictionary.hpp b/node/Dictionary.hpp index 35df3d0f1..546eb2510 100644 --- a/node/Dictionary.hpp +++ b/node/Dictionary.hpp @@ -16,11 +16,13 @@ #include "Constants.hpp" #include "Utils.hpp" -#include "Buffer.hpp" #include "Address.hpp" +#include "Buf.hpp" #include +#define ZT_DICTIONARY_MAX_CAPACITY 65536 + namespace ZeroTier { /** @@ -45,32 +47,14 @@ namespace ZeroTier { * * @tparam C Dictionary max capacity in bytes */ -template class Dictionary { public: - inline Dictionary() { memset(_d,0,sizeof(_d)); } - inline Dictionary(const char *s) { this->load(s); } - inline Dictionary(const char *s,unsigned int len) - { - for(unsigned int i=0;iload(s); } + Dictionary(const char *s,unsigned int len); - inline Dictionary &operator=(const Dictionary &d) - { - memcpy(_d,d._d,C); - return *this; - } - - inline operator bool() const { return (_d[0] != 0); } + ZT_ALWAYS_INLINE operator bool() const { return (_d[0] != 0); } /** * Load a dictionary from a C-string @@ -78,35 +62,12 @@ public: * @param s Dictionary in string form * @return False if 's' was longer than our capacity */ - inline bool load(const char *s) - { - for(unsigned int i=0;i - inline bool get(const char *key,Buffer &dest) const - { - const int r = this->get(key,const_cast(reinterpret_cast(dest.data())),BC); - if (r >= 0) { - dest.setSize((unsigned int)r); - return true; - } else { - dest.clear(); - return false; - } - } + int get(const char *key,char *dest,unsigned int destlen) const; /** * Get a boolean value @@ -236,7 +100,7 @@ public: * @param dfl Default value if not found in dictionary * @return Boolean value of key or 'dfl' if not found */ - inline bool getB(const char *key,bool dfl = false) const + ZT_ALWAYS_INLINE bool getB(const char *key,bool dfl = false) const { char tmp[4]; if (this->get(key,tmp,sizeof(tmp)) >= 0) @@ -251,7 +115,7 @@ public: * @param dfl Default value or 0 if unspecified * @return Decoded hex UInt value or 'dfl' if not found */ - inline uint64_t getUI(const char *key,uint64_t dfl = 0) const + ZT_ALWAYS_INLINE uint64_t getUI(const char *key,uint64_t dfl = 0) const { char tmp[128]; if (this->get(key,tmp,sizeof(tmp)) >= 1) @@ -266,7 +130,7 @@ public: * @param dfl Default value or 0 if unspecified * @return Decoded hex UInt value or 'dfl' if not found */ - inline int64_t getI(const char *key,int64_t dfl = 0) const + ZT_ALWAYS_INLINE int64_t getI(const char *key,int64_t dfl = 0) const { char tmp[128]; if (this->get(key,tmp,sizeof(tmp)) >= 1) @@ -288,137 +152,33 @@ public: * @param vlen Length of value in bytes or -1 to treat value[] as a C-string and look for terminating 0 * @return True if there was enough room to add this key=value pair */ - inline bool add(const char *key,const char *value,int vlen = -1) - { - for(unsigned int i=0;i 0) { - _d[j++] = (char)10; - if (j == C) { - _d[i] = (char)0; - return false; - } - } - - const char *p = key; - while (*p) { - _d[j++] = *(p++); - if (j == C) { - _d[i] = (char)0; - return false; - } - } - - _d[j++] = '='; - if (j == C) { - _d[i] = (char)0; - return false; - } - - p = value; - int k = 0; - while ( ((vlen < 0)&&(*p)) || (k < vlen) ) { - switch(*p) { - case 0: - case 13: - case 10: - case '\\': - case '=': - _d[j++] = '\\'; - if (j == C) { - _d[i] = (char)0; - return false; - } - switch(*p) { - case 0: _d[j++] = '0'; break; - case 13: _d[j++] = 'r'; break; - case 10: _d[j++] = 'n'; break; - case '\\': _d[j++] = '\\'; break; - case '=': _d[j++] = 'e'; break; - } - if (j == C) { - _d[i] = (char)0; - return false; - } - break; - default: - _d[j++] = *p; - if (j == C) { - _d[i] = (char)0; - return false; - } - break; - } - ++p; - ++k; - } - - _d[j] = (char)0; - - return true; - } - } - return false; - } + bool add(const char *key,const char *value,int vlen = -1); /** * Add a boolean as a '1' or a '0' */ - inline bool add(const char *key,bool value) - { - return this->add(key,(value) ? "1" : "0",1); - } + bool add(const char *key,bool value); /** * Add a 64-bit integer (unsigned) as a hex value */ - inline bool add(const char *key,uint64_t value) - { - char tmp[32]; - return this->add(key,Utils::hex(value,tmp),-1); - } + bool add(const char *key,uint64_t value); /** * Add a 64-bit integer (unsigned) as a hex value */ - inline bool add(const char *key,int64_t value) - { - char tmp[32]; - if (value >= 0) { - return this->add(key,Utils::hex((uint64_t)value,tmp),-1); - } else { - tmp[0] = '-'; - return this->add(key,Utils::hex((uint64_t)(value * -1),tmp+1),-1); - } - } + bool add(const char *key,int64_t value); /** * Add a 64-bit integer (unsigned) as a hex value */ - inline bool add(const char *key,const Address &a) - { - char tmp[32]; - return this->add(key,Utils::hex(a.toInt(),tmp),-1); - } - - /** - * Add a binary buffer's contents as a value - * - * @tparam BC Buffer capacity (usually inferred) - */ - template - inline bool add(const char *key,const Buffer &value) - { - return this->add(key,(const char *)value.data(),(int)value.size()); - } + bool add(const char *key,const Address &a); /** * @param key Key to check * @return True if key is present */ - inline bool contains(const char *key) const + ZT_ALWAYS_INLINE bool contains(const char *key) const { char tmp[2]; return (this->get(key,tmp,2) >= 0); @@ -427,13 +187,12 @@ public: /** * @return Value of C template parameter */ - inline unsigned int capacity() const { return C; } + ZT_ALWAYS_INLINE unsigned int capacity() const { return sizeof(_d); } - inline const char *data() const { return _d; } - inline char *unsafeData() { return _d; } + ZT_ALWAYS_INLINE const char *data() const { return _d; } private: - char _d[C]; + char _d[ZT_DICTIONARY_MAX_CAPACITY]; }; } // namespace ZeroTier diff --git a/node/Identity.hpp b/node/Identity.hpp index 65aa1deb0..d98d9fa04 100644 --- a/node/Identity.hpp +++ b/node/Identity.hpp @@ -21,7 +21,6 @@ #include "Utils.hpp" #include "Address.hpp" #include "C25519.hpp" -#include "Buffer.hpp" #include "SHA512.hpp" #include "ECC384.hpp" @@ -158,108 +157,6 @@ public: */ ZT_ALWAYS_INLINE const Address &address() const { return _address; } - /** - * Serialize this identity (binary) - * - * @param b Destination buffer to append to - * @param includePrivate If true, include private key component (if present) (default: false) - */ - template - inline void serialize(Buffer &b,bool includePrivate = false) const - { - _address.appendTo(b); - switch(_type) { - - case C25519: - b.append((uint8_t)C25519); - b.append(_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN); - if ((_hasPrivate)&&(includePrivate)) { - b.append((uint8_t)ZT_C25519_PRIVATE_KEY_LEN); - b.append(_priv.c25519,ZT_C25519_PRIVATE_KEY_LEN); - } else { - b.append((uint8_t)0); - } - break; - - case P384: - b.append((uint8_t)P384); - b.append(&_pub,ZT_C25519_PUBLIC_KEY_LEN + ZT_ECC384_PUBLIC_KEY_SIZE + ZT_C25519_SIGNATURE_LEN + ZT_ECC384_SIGNATURE_SIZE); - if ((_hasPrivate)&&(includePrivate)) { - b.append((uint8_t)(ZT_C25519_PRIVATE_KEY_LEN + ZT_ECC384_PRIVATE_KEY_SIZE)); - b.append(_priv.c25519,ZT_C25519_PRIVATE_KEY_LEN); - b.append(_priv.p384,ZT_ECC384_PRIVATE_KEY_SIZE); - } else { - b.append((uint8_t)0); - } - b.append((uint8_t)0); // size of additional fields (should have included such a thing in v0!) - break; - - } - } - - /** - * Deserialize a binary serialized identity - * - * If an exception is thrown, the Identity object is left in an undefined - * state and should not be used. - * - * @param b Buffer containing serialized data - * @param startAt Index within buffer of serialized data (default: 0) - * @return Length of serialized data read from buffer - */ - template - inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) - { - _hasPrivate = false; - unsigned int p = startAt; - unsigned int pkl; - - _address.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); - p += ZT_ADDRESS_LENGTH; - - switch((_type = (Type)b[p++])) { - - case C25519: - memcpy(_pub.c25519,b.field(p,ZT_C25519_PUBLIC_KEY_LEN),ZT_C25519_PUBLIC_KEY_LEN); - p += ZT_C25519_PUBLIC_KEY_LEN; - pkl = (unsigned int)b[p++]; - if (pkl) { - if (pkl != ZT_C25519_PRIVATE_KEY_LEN) - throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN; - _hasPrivate = true; - memcpy(_priv.c25519,b.field(p,ZT_C25519_PRIVATE_KEY_LEN),ZT_C25519_PRIVATE_KEY_LEN); - p += ZT_C25519_PRIVATE_KEY_LEN; - } else { - _hasPrivate = false; - } - break; - - case P384: - memcpy(&_pub,b.field(p,ZT_C25519_PUBLIC_KEY_LEN + ZT_ECC384_PUBLIC_KEY_SIZE + ZT_C25519_SIGNATURE_LEN + ZT_ECC384_SIGNATURE_SIZE),ZT_C25519_PUBLIC_KEY_LEN + ZT_ECC384_PUBLIC_KEY_SIZE + ZT_C25519_SIGNATURE_LEN + ZT_ECC384_SIGNATURE_SIZE); - p += ZT_C25519_PUBLIC_KEY_LEN + ZT_ECC384_PUBLIC_KEY_SIZE + ZT_C25519_SIGNATURE_LEN + ZT_ECC384_SIGNATURE_SIZE; - pkl = (unsigned int)b[p++]; - if (pkl) { - if (pkl != (ZT_C25519_PRIVATE_KEY_LEN + ZT_ECC384_PRIVATE_KEY_SIZE)) - throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN; - _hasPrivate = true; - memcpy(_priv.c25519,b.field(p,ZT_C25519_PRIVATE_KEY_LEN),ZT_C25519_PRIVATE_KEY_LEN); - p += ZT_C25519_PRIVATE_KEY_LEN; - memcpy(_priv.p384,b.field(p,ZT_ECC384_PRIVATE_KEY_SIZE),ZT_ECC384_PRIVATE_KEY_SIZE); - p += ZT_ECC384_PRIVATE_KEY_SIZE; - } else { - _hasPrivate = false; - } - p += b.template at(p) + 2; - break; - - default: - throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE; - - } - - return (p - startAt); - } - /** * Serialize to a more human-friendly string * diff --git a/node/InetAddress.hpp b/node/InetAddress.hpp index 0cbe18953..09ca63e7d 100644 --- a/node/InetAddress.hpp +++ b/node/InetAddress.hpp @@ -21,7 +21,6 @@ #include "Constants.hpp" #include "Utils.hpp" #include "MAC.hpp" -#include "Buffer.hpp" namespace ZeroTier { @@ -498,62 +497,6 @@ public: int marshal(uint8_t data[19]) const; int unmarshal(const uint8_t *restrict data,const int len); - template - inline void serialize(Buffer &b) const - { - // This is used in the protocol and must be the same as describe in places - // like VERB_HELLO in Packet.hpp. - switch(ss_family) { - case AF_INET: - b.append((uint8_t)0x04); - b.append(&(reinterpret_cast(this)->sin_addr.s_addr),4); - b.append((uint16_t)port()); // just in case sin_port != uint16_t - return; - case AF_INET6: - b.append((uint8_t)0x06); - b.append(reinterpret_cast(this)->sin6_addr.s6_addr,16); - b.append((uint16_t)port()); // just in case sin_port != uint16_t - return; - default: - b.append((uint8_t)0); - return; - } - } - - template - inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) - { - memset(this,0,sizeof(InetAddress)); - unsigned int p = startAt; - switch(b[p++]) { - case 0: - return 1; - case 0x01: - // TODO: Ethernet address (but accept for forward compatibility) - return 7; - case 0x02: - // TODO: Bluetooth address (but accept for forward compatibility) - return 7; - case 0x03: - // TODO: Other address types (but accept for forward compatibility) - // These could be extended/optional things like AF_UNIX, LTE Direct, shared memory, etc. - return (unsigned int)(b.template at(p) + 3); // other addresses begin with 16-bit non-inclusive length - case 0x04: - ss_family = AF_INET; - memcpy(&(reinterpret_cast(this)->sin_addr.s_addr),b.field(p,4),4); p += 4; - reinterpret_cast(this)->sin_port = Utils::hton(b.template at(p)); p += 2; - break; - case 0x06: - ss_family = AF_INET6; - memcpy(reinterpret_cast(this)->sin6_addr.s6_addr,b.field(p,16),16); p += 16; - reinterpret_cast(this)->sin_port = Utils::hton(b.template at(p)); p += 2; - break; - default: - throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_BAD_ENCODING; - } - return (p - startAt); - } - bool operator==(const InetAddress &a) const; bool operator<(const InetAddress &a) const; ZT_ALWAYS_INLINE bool operator!=(const InetAddress &a) const { return !(*this == a); } diff --git a/node/MAC.hpp b/node/MAC.hpp index 7d969af5f..7c52e4997 100644 --- a/node/MAC.hpp +++ b/node/MAC.hpp @@ -21,7 +21,6 @@ #include "Constants.hpp" #include "Utils.hpp" #include "Address.hpp" -#include "Buffer.hpp" namespace ZeroTier { @@ -39,9 +38,9 @@ public: ((((uint64_t)d) & 0xffULL) << 16U) | ((((uint64_t)e) & 0xffULL) << 8U) | (((uint64_t)f) & 0xffULL) ) {} - ZT_ALWAYS_INLINE MAC(const uint8_t b[6]) { setTo(b); } + explicit ZT_ALWAYS_INLINE MAC(const uint8_t b[6]) { setTo(b); } ZT_ALWAYS_INLINE MAC(const Address &ztaddr,uint64_t nwid) { fromAddress(ztaddr,nwid); } - ZT_ALWAYS_INLINE MAC(const uint64_t m) : _m(m & 0xffffffffffffULL) {} + explicit ZT_ALWAYS_INLINE MAC(const uint64_t m) : _m(m & 0xffffffffffffULL) {} /** * @return MAC in 64-bit integer diff --git a/node/Membership.cpp b/node/Membership.cpp index afe51b2b7..f2b47e4a7 100644 --- a/node/Membership.cpp +++ b/node/Membership.cpp @@ -18,7 +18,6 @@ #include "Peer.hpp" #include "Topology.hpp" #include "Switch.hpp" -#include "Packet.hpp" #include "Node.hpp" namespace ZeroTier { diff --git a/node/MulticastGroup.hpp b/node/MulticastGroup.hpp index 4bb01276a..80317b487 100644 --- a/node/MulticastGroup.hpp +++ b/node/MulticastGroup.hpp @@ -63,7 +63,7 @@ public: // multicast address directly from the IP address, and it gives us // 24 bits of uniqueness. Collisions aren't likely to be common enough // to care about. - const unsigned char *a = (const unsigned char *)ip.rawIpData(); + const uint8_t *a = (const uint8_t *)ip.rawIpData(); return MulticastGroup(MAC(0x33,0x33,0xff,a[13],a[14],a[15]),0); } return MulticastGroup(); diff --git a/node/NetworkConfig.cpp b/node/NetworkConfig.cpp index a7b4ee814..f408fc99e 100644 --- a/node/NetworkConfig.cpp +++ b/node/NetworkConfig.cpp @@ -20,7 +20,28 @@ namespace ZeroTier { -bool NetworkConfig::toDictionary(Dictionary &d,bool includeLegacy) const +NetworkConfig::NetworkConfig() : + networkId(0), + timestamp(0), + credentialTimeMaxDelta(0), + revision(0), + issuedTo(), + flags(0), + mtu(0), + multicastLimit(0), + specialistCount(0), + routeCount(0), + staticIpCount(0), + ruleCount(0), + capabilityCount(0), + tagCount(0), + certificateOfOwnershipCount(0), + type(ZT_NETWORK_TYPE_PRIVATE) +{ + name[0] = 0; +} + +bool NetworkConfig::toDictionary(Dictionary &d,bool includeLegacy) const { ScopedPtr< Buffer > tmp(new Buffer()); char tmp2[128]; @@ -105,7 +126,7 @@ bool NetworkConfig::toDictionary(Dictionary &d,b return true; } -bool NetworkConfig::fromDictionary(const Dictionary &d) +bool NetworkConfig::fromDictionary(const Dictionary &d) { static const NetworkConfig NIL_NC; ScopedPtr< Buffer > tmp(new Buffer()); @@ -218,4 +239,20 @@ bool NetworkConfig::fromDictionary(const Dictionary #include #include - #include #include #include #include "Constants.hpp" -#include "Buffer.hpp" #include "InetAddress.hpp" #include "MulticastGroup.hpp" #include "Address.hpp" @@ -168,26 +166,7 @@ namespace ZeroTier { */ struct NetworkConfig { - inline NetworkConfig() : - networkId(0), - timestamp(0), - credentialTimeMaxDelta(0), - revision(0), - issuedTo(), - flags(0), - mtu(0), - multicastLimit(0), - specialistCount(0), - routeCount(0), - staticIpCount(0), - ruleCount(0), - capabilityCount(0), - tagCount(0), - certificateOfOwnershipCount(0), - type(ZT_NETWORK_TYPE_PRIVATE) - { - name[0] = 0; - } + NetworkConfig(); /** * Write this network config to a dictionary for transport @@ -196,7 +175,7 @@ struct NetworkConfig * @param includeLegacy If true, include legacy fields for old node versions * @return True if dictionary was successfully created, false if e.g. overflow */ - bool toDictionary(Dictionary &d,bool includeLegacy) const; + bool toDictionary(Dictionary &d,bool includeLegacy) const; /** * Read this network config from a dictionary @@ -204,33 +183,33 @@ struct NetworkConfig * @param d Dictionary (non-const since it might be modified during parse, should not be used after call) * @return True if dictionary was valid and network config successfully initialized */ - bool fromDictionary(const Dictionary &d); + bool fromDictionary(const Dictionary &d); /** * @return True if broadcast (ff:ff:ff:ff:ff:ff) address should work on this network */ - inline bool enableBroadcast() const { return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_BROADCAST) != 0); } + ZT_ALWAYS_INLINE bool enableBroadcast() const { return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_BROADCAST) != 0); } /** * @return True if IPv6 NDP emulation should be allowed for certain "magic" IPv6 address patterns */ - inline bool ndpEmulation() const { return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION) != 0); } + ZT_ALWAYS_INLINE bool ndpEmulation() const { return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION) != 0); } /** * @return Network type is public (no access control) */ - inline bool isPublic() const { return (this->type == ZT_NETWORK_TYPE_PUBLIC); } + ZT_ALWAYS_INLINE bool isPublic() const { return (this->type == ZT_NETWORK_TYPE_PUBLIC); } /** * @return Network type is private (certificate access control) */ - inline bool isPrivate() const { return (this->type == ZT_NETWORK_TYPE_PRIVATE); } + ZT_ALWAYS_INLINE bool isPrivate() const { return (this->type == ZT_NETWORK_TYPE_PRIVATE); } /** * @param fromPeer Peer attempting to bridge other Ethernet peers onto network * @return True if this network allows bridging */ - inline bool permitsBridging(const Address &fromPeer) const + ZT_ALWAYS_INLINE bool permitsBridging(const Address &fromPeer) const { for(unsigned int i=0;i @@ -103,9 +104,9 @@ public: unsigned int hops, uint64_t packetId, unsigned int payloadLength, - Packet::Verb verb, + Protocol::Verb verb, uint64_t inRePacketId, - Packet::Verb inReVerb, + Protocol::Verb inReVerb, uint64_t networkId); /** diff --git a/node/Revocation.hpp b/node/Revocation.hpp index d269b866a..132922c40 100644 --- a/node/Revocation.hpp +++ b/node/Revocation.hpp @@ -24,7 +24,6 @@ #include "Address.hpp" #include "C25519.hpp" #include "Utils.hpp" -#include "Buffer.hpp" #include "Identity.hpp" /** diff --git a/node/Switch.cpp b/node/Switch.cpp index 49917fa48..fc9fbfbb6 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -22,7 +22,6 @@ #include "InetAddress.hpp" #include "Peer.hpp" #include "SelfAwareness.hpp" -#include "Packet.hpp" #include "Trace.hpp" namespace ZeroTier { diff --git a/node/Switch.hpp b/node/Switch.hpp index fca6fac23..fdce19555 100644 --- a/node/Switch.hpp +++ b/node/Switch.hpp @@ -22,7 +22,6 @@ #include "Constants.hpp" #include "Mutex.hpp" #include "MAC.hpp" -#include "Packet.hpp" #include "Utils.hpp" #include "InetAddress.hpp" #include "Topology.hpp" @@ -30,6 +29,7 @@ #include "SharedPtr.hpp" #include "IncomingPacket.hpp" #include "Hashtable.hpp" +#include "Protocol.hpp" namespace ZeroTier { diff --git a/node/Tag.hpp b/node/Tag.hpp index eb5c9e242..731b55525 100644 --- a/node/Tag.hpp +++ b/node/Tag.hpp @@ -24,7 +24,6 @@ #include "C25519.hpp" #include "Address.hpp" #include "Identity.hpp" -#include "Buffer.hpp" namespace ZeroTier { diff --git a/node/Utils.cpp b/node/Utils.cpp index e0638c19b..691441953 100644 --- a/node/Utils.cpp +++ b/node/Utils.cpp @@ -15,7 +15,10 @@ #include #include -#include "Constants.hpp" +#include "Utils.hpp" +#include "Mutex.hpp" +#include "AES.hpp" +#include "SHA512.hpp" #ifdef __UNIX_LIKE__ #include @@ -27,11 +30,6 @@ #include #endif -#include "Utils.hpp" -#include "Mutex.hpp" -#include "AES.hpp" -#include "SHA512.hpp" - namespace ZeroTier { namespace Utils { @@ -166,13 +164,13 @@ void getSecureRandom(void *buf,unsigned int bytes) static Mutex globalLock; static bool initialized = false; static uint64_t randomState[8]; - static uint8_t randomBuf[65536]; - static unsigned long randomPtr = sizeof(randomBuf); + static uint64_t randomBuf[8192]; + static unsigned int randomPtr = 65536; Mutex::Lock gl(globalLock); for(unsigned int i=0;i= sizeof(randomBuf)) { + if (randomPtr >= 65536) { randomPtr = 0; if (!initialized) { @@ -225,18 +223,22 @@ void getSecureRandom(void *buf,unsigned int bytes) #endif } + ++randomState[0]; SHA512(randomState,randomState,sizeof(randomState)); AES aes(reinterpret_cast(randomState)); - uint64_t ctr[2]; + uint64_t ctr[2],tmp[2]; ctr[0] = randomState[6]; ctr[1] = randomState[7]; - for(unsigned long i=0;i(ctr),randomBuf + i); + aes.encrypt(reinterpret_cast(ctr),reinterpret_cast(tmp)); + randomBuf[k] ^= tmp[0]; + randomBuf[k+1] ^= tmp[1]; + k += 2; } } - reinterpret_cast(buf)[i] = randomBuf[randomPtr++]; + reinterpret_cast(buf)[i] = reinterpret_cast(randomBuf)[randomPtr++]; } } diff --git a/node/Utils.hpp b/node/Utils.hpp index ea2ed519f..2853d852c 100644 --- a/node/Utils.hpp +++ b/node/Utils.hpp @@ -19,6 +19,11 @@ #include #include #include +#include +#include +#include + +#include "Constants.hpp" #if (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64)) #include @@ -26,12 +31,6 @@ #include #endif -#include -#include -#include - -#include "Constants.hpp" - namespace ZeroTier { namespace Utils { @@ -87,7 +86,7 @@ char *decimal(unsigned long n,char s[24]); * @return Pointer to s containing hex string with trailing zero byte */ template -static inline char *hex(I x,char *s) +static ZT_ALWAYS_INLINE char *hex(I x,char *s) { char *const r = s; for(unsigned int i=0,b=(sizeof(x)*8);i