Some optimization and raw memory access cleanup.

This commit is contained in:
Adam Ierymenko 2020-03-27 07:40:14 -07:00
parent 3f32cffc40
commit 1f2e94a51d
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
34 changed files with 1012 additions and 738 deletions

View file

@ -165,7 +165,7 @@ public:
r.e = 0;
break;
}
memcpy(r.b->unsafeData + r.e,s->b->unsafeData + s->s,l);
Utils::copy(r.b->unsafeData + r.e,s->b->unsafeData + s->s,l);
s->b.zero(); // let go of buffer in vector as soon as possible
r.e += l;
}
@ -182,14 +182,24 @@ public:
/**
* Create a new buffer and copy data into it
*/
ZT_INLINE Buf(const void *const data,const unsigned int len) noexcept : __nextInPool(0),__refCount(0) { memcpy(unsafeData,data,len); }
ZT_INLINE Buf(const void *const data,const unsigned int len) noexcept :
__nextInPool(0),
__refCount(0)
{
Utils::copy(unsafeData,data,len);
}
ZT_INLINE Buf(const Buf &b2) noexcept : __nextInPool(0),__refCount(0) { memcpy(unsafeData,b2.unsafeData,ZT_BUF_MEM_SIZE); }
ZT_INLINE Buf(const Buf &b2) noexcept :
__nextInPool(0),
__refCount(0)
{
Utils::copy<ZT_BUF_MEM_SIZE>(unsafeData,b2.unsafeData);
}
ZT_INLINE Buf &operator=(const Buf &b2) noexcept
{
if (this != &b2)
memcpy(unsafeData,b2.unsafeData,ZT_BUF_MEM_SIZE);
Utils::copy<ZT_BUF_MEM_SIZE>(unsafeData,b2.unsafeData);
return *this;
}
@ -219,12 +229,18 @@ public:
/**
* Set all memory to zero
*/
ZT_INLINE void clear() noexcept { memset(unsafeData,0,ZT_BUF_MEM_SIZE); }
ZT_INLINE void clear() noexcept
{
Utils::zero<ZT_BUF_MEM_SIZE>(unsafeData);
}
/**
* Zero security critical data using Utils::burn() to ensure it's never optimized out.
*/
ZT_INLINE void burn() noexcept { Utils::burn(unsafeData,ZT_BUF_MEM_SIZE); }
ZT_INLINE void burn() noexcept
{
Utils::burn(unsafeData,ZT_BUF_MEM_SIZE);
}
/**
* Read a byte
@ -347,7 +363,7 @@ public:
const int sii = ii;
while (ii < ZT_BUF_MEM_SIZE) {
if (unsafeData[ii++] == 0) {
memcpy(buf,s,ii - sii);
Utils::copy(buf,s,ii - sii);
return buf;
}
}
@ -391,7 +407,7 @@ public:
ZT_INLINE uint8_t *rB(int &ii,void *const bytes,const unsigned int len) const noexcept
{
if ((ii += (int)len) <= ZT_BUF_MEM_SIZE) {
memcpy(bytes,unsafeData + ii,len);
Utils::copy(bytes,unsafeData + ii,len);
return reinterpret_cast<uint8_t *>(bytes);
}
return nullptr;
@ -617,7 +633,7 @@ public:
{
const int s = ii;
if ((ii += (int)len) <= ZT_BUF_MEM_SIZE)
memcpy(unsafeData + s,bytes,len);
Utils::copy(unsafeData + s,bytes,len);
}
/**

File diff suppressed because it is too large Load diff

View file

@ -110,7 +110,7 @@ int Capability::unmarshal(const uint8_t *data,int len) noexcept
_custody[i].signatureLength = sl;
if ((sl > sizeof(_custody[i].signature))||((p + (int)sl) > len))
return -1;
memcpy(_custody[i].signature,data + p,sl); p += (int)sl;
Utils::copy(_custody[i].signature,data + p,sl); p += (int)sl;
}
if ((p + 2) > len)
@ -281,18 +281,18 @@ int Capability::unmarshalVirtualNetworkRules(const uint8_t *const data,const int
case ZT_NETWORK_RULE_MATCH_MAC_SOURCE:
case ZT_NETWORK_RULE_MATCH_MAC_DEST:
if ((p + 6) > len) return -1;
memcpy(rules[ruleCount].v.mac,data + p,6); p += 6;
Utils::copy<6>(rules[ruleCount].v.mac,data + p); p += 6;
break;
case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE:
case ZT_NETWORK_RULE_MATCH_IPV4_DEST:
if ((p + 5) > len) return -1;
memcpy(&(rules[ruleCount].v.ipv4.ip),data + p,4); p += 4;
Utils::copy<4>(&(rules[ruleCount].v.ipv4.ip),data + p); p += 4;
rules[ruleCount].v.ipv4.mask = data[p++];
break;
case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE:
case ZT_NETWORK_RULE_MATCH_IPV6_DEST:
if ((p + 17) > len) return -1;
memcpy(rules[ruleCount].v.ipv6.ip,data + p,16); p += 16;
Utils::copy<16>(rules[ruleCount].v.ipv6.ip,data + p); p += 16;
rules[ruleCount].v.ipv6.mask = data[p++];
break;
case ZT_NETWORK_RULE_MATCH_IP_TOS:

View file

@ -82,7 +82,7 @@ public:
_ruleCount((ruleCount < ZT_MAX_CAPABILITY_RULES) ? ruleCount : ZT_MAX_CAPABILITY_RULES)
{
if (_ruleCount > 0)
memcpy(_rules,rules,sizeof(ZT_VirtualNetworkRule) * _ruleCount);
Utils::copy(_rules,rules,sizeof(ZT_VirtualNetworkRule) * _ruleCount);
}
/**

View file

@ -57,7 +57,7 @@ bool CertificateOfMembership::agreesWith(const CertificateOfMembership &other) c
}
}
// them <> us
// them <> us (we need a second pass in case they have qualifiers we don't or vice versa)
for(FCV<_Qualifier,ZT_CERTIFICATEOFMEMBERSHIP_MAX_ADDITIONAL_QUALIFIERS>::const_iterator i(other._additionalQualifiers.begin());i != other._additionalQualifiers.end();++i) {
if (i->delta != 0xffffffffffffffffULL) {
const uint64_t *v2 = nullptr;
@ -113,7 +113,7 @@ int CertificateOfMembership::marshal(uint8_t data[ZT_CERTIFICATEOFMEMBERSHIP_MAR
if (v2) {
// V2 marshal format will have three tuples followed by the fingerprint hash.
Utils::storeBigEndian<uint16_t>(data + 1,3);
memcpy(data + p,_issuedTo.hash(),48);
Utils::copy<48>(data + p,_issuedTo.hash());
p += 48;
} else {
// V1 marshal format must shove everything into tuples, resulting in nine.
@ -130,11 +130,11 @@ int CertificateOfMembership::marshal(uint8_t data[ZT_CERTIFICATEOFMEMBERSHIP_MAR
if (v2) {
// V2 marshal format prefixes signatures with a 16-bit length to support future signature types.
Utils::storeBigEndian<uint16_t>(data + p,(uint16_t)_signatureLength); p += 2;
memcpy(data + p,_signature,_signatureLength);
Utils::copy(data + p,_signature,_signatureLength);
p += (int)_signatureLength;
} else {
// V1 only supports 96-byte signature fields.
memcpy(data + p,_signature,96);
Utils::copy<96>(data + p,_signature);
p += 96;
}
@ -204,19 +204,19 @@ int CertificateOfMembership::unmarshal(const uint8_t *data,int len) noexcept
if ((p + 96) > len)
return -1;
_signatureLength = 96;
memcpy(_signature,data + p,96);
Utils::copy<96>(_signature,data + p);
return p + 96;
} else if (data[0] == 2) {
if ((p + 48) > len)
return -1;
memcpy(_issuedTo.apiFingerprint()->hash,data + p,48);
Utils::copy<48>(_issuedTo.apiFingerprint()->hash,data + p);
p += 48;
if ((p + 2) > len)
return -1;
_signatureLength = Utils::loadBigEndian<uint16_t>(data + p);
if ((_signatureLength > (unsigned int)sizeof(_signature))||((p + (int)_signatureLength) > len))
return -1;
memcpy(_signature,data + p,_signatureLength);
Utils::copy(_signature,data + p,_signatureLength);
return p + (int)_signatureLength;
}

View file

@ -17,21 +17,23 @@ namespace ZeroTier {
void CertificateOfOwnership::addThing(const InetAddress &ip)
{
if (_thingCount >= ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS) return;
if (_thingCount >= ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS)
return;
if (ip.family() == AF_INET) {
_thingTypes[_thingCount] = THING_IPV4_ADDRESS;
memcpy(_thingValues[_thingCount],&(reinterpret_cast<const struct sockaddr_in *>(&ip)->sin_addr.s_addr),4);
Utils::copy<4>(_thingValues[_thingCount],&(reinterpret_cast<const struct sockaddr_in *>(&ip)->sin_addr.s_addr));
++_thingCount;
} else if (ip.family() == AF_INET6) {
_thingTypes[_thingCount] = THING_IPV6_ADDRESS;
memcpy(_thingValues[_thingCount],reinterpret_cast<const struct sockaddr_in6 *>(&ip)->sin6_addr.s6_addr,16);
Utils::copy<16>(_thingValues[_thingCount],reinterpret_cast<const struct sockaddr_in6 *>(&ip)->sin6_addr.s6_addr);
++_thingCount;
}
}
void CertificateOfOwnership::addThing(const MAC &mac)
{
if (_thingCount >= ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS) return;
if (_thingCount >= ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS)
return;
_thingTypes[_thingCount] = THING_MAC_ADDRESS;
mac.copyTo(_thingValues[_thingCount]);
++_thingCount;
@ -63,7 +65,7 @@ int CertificateOfOwnership::marshal(uint8_t data[ZT_CERTIFICATEOFOWNERSHIP_MARSH
p += 30;
for(unsigned int i=0,j=_thingCount;i<j;++i) {
data[p++] = _thingTypes[i];
memcpy(data + p,_thingValues[i],ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE);
Utils::copy<ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE>(data + p,_thingValues[i]);
p += ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE;
}
_issuedTo.copyTo(data + p); p += ZT_ADDRESS_LENGTH;
@ -71,7 +73,7 @@ int CertificateOfOwnership::marshal(uint8_t data[ZT_CERTIFICATEOFOWNERSHIP_MARSH
if (!forSign) {
data[p++] = 1;
Utils::storeBigEndian<uint16_t>(data + p,(uint16_t)_signatureLength); p += 2;
memcpy(data + p,_signature,_signatureLength); p += (int)_signatureLength;
Utils::copy(data + p,_signature,_signatureLength); p += (int)_signatureLength;
}
data[p++] = 0;
data[p++] = 0;
@ -100,7 +102,7 @@ int CertificateOfOwnership::unmarshal(const uint8_t *data,int len) noexcept
if ((p + 1 + ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE) > len)
return -1;
_thingTypes[i] = data[p++];
memcpy(_thingValues[i],data + p,ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE);
Utils::copy<ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE>(_thingValues[i],data + p);
p += ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE;
}

View file

@ -64,7 +64,7 @@ public:
ZT_INLINE CertificateOfOwnership(const uint64_t nwid,const int64_t ts,const Address &issuedTo,const uint32_t id) noexcept
{
memset(reinterpret_cast<void *>(this),0,sizeof(CertificateOfOwnership));
memoryZero(this);
_networkId = nwid;
_ts = ts;
_id = id;

View file

@ -263,7 +263,7 @@ public:
e->via.zero();
}
// Slices are TriviallyCopyable and so may be memcpy'd from e->message to
// Slices are TriviallyCopyable and so may be raw copied from e->message to
// the result parameter. This is fast.
e->message.unsafeMoveTo(message);
e->lastUsed = -1; // mark as "done" and force GC to collect

View file

@ -134,7 +134,7 @@ uint64_t Dictionary::getUI(const char *k,uint64_t dfl) const
if (!e.empty()) {
if (e.back() != 0) {
const unsigned long sl = e.size();
memcpy(tmp,e.data(),(sl > 17) ? 17 : sl);
Utils::copy(tmp,e.data(),(sl > 17) ? 17 : sl);
tmp[17] = 0;
return Utils::unhex((const char *)tmp);
}

View file

@ -82,7 +82,7 @@ int Endpoint::marshal(uint8_t data[ZT_ENDPOINT_MARSHAL_SIZE_MAX]) const noexcept
data[9] = (uint8_t)(_v.zt.address >> 16U);
data[10] = (uint8_t)(_v.zt.address >> 8U);
data[11] = (uint8_t)_v.zt.address;
memcpy(data + 12,_v.zt.hash,ZT_IDENTITY_HASH_SIZE);
Utils::copy<ZT_IDENTITY_HASH_SIZE>(data + 12,_v.zt.hash);
return ZT_IDENTITY_HASH_SIZE + 12;
case TYPE_DNSNAME:
p = 7;
@ -147,7 +147,7 @@ int Endpoint::unmarshal(const uint8_t *restrict data,const int len) noexcept
_v.zt.address |= ((uint64_t)data[9]) << 16U;
_v.zt.address |= ((uint64_t)data[10]) << 8U;
_v.zt.address |= (uint64_t)data[11];
memcpy(_v.zt.hash,data + 12,ZT_IDENTITY_HASH_SIZE);
Utils::copy<ZT_IDENTITY_HASH_SIZE>(_v.zt.hash,data + 12);
return 60;
case TYPE_DNSNAME:
if (len < 10)

View file

@ -76,7 +76,7 @@ public:
_t(TYPE_ZEROTIER)
{
_v.zt.address = zt.toInt();
memcpy(_v.zt.hash,identityHash,ZT_IDENTITY_HASH_SIZE);
Utils::copy<ZT_IDENTITY_HASH_SIZE>(_v.zt.hash,identityHash);
}
explicit ZT_INLINE Endpoint(const char *name,const int port) noexcept :

View file

@ -87,11 +87,6 @@ public:
/**
* This does a straight copy of one vector's data to another
*
* If the other vector is larger than this one's capacity the data is
* silently truncated. This is unsafe in that it does not call any
* constructors or destructors and copies data with memcpy, so it can
* only be used with primitive types or TriviallyCopyable objects.
*
* @tparam C2 Inferred capacity of other vector
* @param v Other vector to copy to this one
*/
@ -99,20 +94,17 @@ public:
ZT_INLINE void unsafeAssign(const FCV<T,C2> &v) noexcept
{
_s = ((C2 > C)&&(v._s > C)) ? C : v._s;
memcpy(_m,v._m,_s * sizeof(T));
Utils::copy(_m,v._m,_s * sizeof(T));
}
/**
* Move contents from this vector to another and clear this vector
*
* This uses a straight memcpy and so is only safe for primitive types or
* types that are TriviallyCopyable.
*
* @param v Target vector
*/
ZT_INLINE void unsafeMoveTo(FCV &v) noexcept
{
memcpy(v._m,_m,(v._s = _s) * sizeof(T));
Utils::copy(v._m,_m,(v._s = _s) * sizeof(T));
_s = 0;
}

View file

@ -62,7 +62,7 @@ public:
{
uint8_t tmp[48 + 5];
address().copyTo(tmp);
memcpy(tmp + 5,_fp.hash,48);
Utils::copy<48>(tmp + 5,_fp.hash);
Utils::b32e(tmp,sizeof(tmp),s,ZT_FINGERPRINT_STRING_BUFFER_LENGTH);
s[ZT_FINGERPRINT_STRING_BUFFER_LENGTH-1] = 0; // sanity check, ensure always zero terminated
}
@ -79,7 +79,7 @@ public:
if (Utils::b32d(s,tmp,sizeof(tmp)) != sizeof(tmp))
return false;
_fp.address = Address(tmp).toInt();
memcpy(_fp.hash,tmp + 5,48);
Utils::copy<48>(_fp.hash,tmp + 5);
return true;
}

View file

@ -15,6 +15,7 @@
#define ZT_HASHTABLE_HPP
#include "Constants.hpp"
#include "Utils.hpp"
#include <cstdlib>
#include <cstring>
@ -95,14 +96,14 @@ public:
/**
* @param bc Initial capacity in buckets (default: 32, must be nonzero)
*/
explicit ZT_INLINE Hashtable(unsigned long bc = 32) :
explicit ZT_INLINE Hashtable(unsigned int bc = 32) :
_t(reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * bc))),
_bc(bc),
_s(0)
{
if (!_t)
throw std::bad_alloc();
memset(_t,0,sizeof(_Bucket *) * bc);
Utils::zero(_t,sizeof(uintptr_t) * bc);
}
ZT_INLINE Hashtable(const Hashtable<K,V> &ht) :

View file

@ -40,7 +40,7 @@ void identityV0ProofOfWorkFrankenhash(const void *const publicKey,unsigned int p
// Initialize genmem[] using Salsa20 in a CBC-like configuration since
// ordinary Salsa20 is randomly seek-able. This is good for a cipher
// but is not what we want for sequential memory-hardness.
memset(genmem,0,ZT_V0_IDENTITY_GEN_MEMORY);
Utils::zero<ZT_V0_IDENTITY_GEN_MEMORY>(genmem);
Salsa20 s20(digest,(char *)digest + 32);
s20.crypt20((char *)genmem,(char *)genmem,64);
for(unsigned long i=64;i<ZT_V0_IDENTITY_GEN_MEMORY;i+=64) {
@ -261,7 +261,7 @@ void Identity::hashWithPrivate(uint8_t h[ZT_IDENTITY_HASH_SIZE]) const
}
return;
}
memset(h,0,48);
Utils::zero<48>(h);
}
unsigned int Identity::sign(const void *data,unsigned int len,void *sig,unsigned int siglen) const
@ -319,7 +319,7 @@ bool Identity::agree(const Identity &id,uint8_t key[ZT_PEER_SECRET_KEY_LENGTH])
// C25519 portion of a type 1 P-384 key.
C25519::agree(_priv.c25519,id._pub.c25519,rawkey);
SHA512(h,rawkey,ZT_C25519_SHARED_KEY_LEN);
memcpy(key,h,ZT_PEER_SECRET_KEY_LENGTH);
Utils::copy<ZT_PEER_SECRET_KEY_LENGTH>(key,h);
return true;
}
@ -334,13 +334,13 @@ bool Identity::agree(const Identity &id,uint8_t key[ZT_PEER_SECRET_KEY_LENGTH])
C25519::agree(_priv.c25519,id._pub.c25519,rawkey);
ECC384ECDH(id._pub.p384,_priv.p384,rawkey + ZT_C25519_SHARED_KEY_LEN);
SHA384(h,rawkey,ZT_C25519_SHARED_KEY_LEN + ZT_ECC384_SHARED_SECRET_SIZE);
memcpy(key,h,ZT_PEER_SECRET_KEY_LENGTH);
Utils::copy<ZT_PEER_SECRET_KEY_LENGTH>(key,h);
return true;
} else if (id._type == C25519) {
// If the other identity is a C25519 identity we can agree using only that type.
C25519::agree(_priv.c25519,id._pub.c25519,rawkey);
SHA512(h,rawkey,ZT_C25519_SHARED_KEY_LEN);
memcpy(key,h,ZT_PEER_SECRET_KEY_LENGTH);
Utils::copy<ZT_PEER_SECRET_KEY_LENGTH>(key,h);
return true;
}
@ -502,10 +502,10 @@ int Identity::marshal(uint8_t data[ZT_IDENTITY_MARSHAL_SIZE_MAX],const bool incl
switch(_type) {
case C25519:
data[ZT_ADDRESS_LENGTH] = (uint8_t)C25519;
memcpy(data + ZT_ADDRESS_LENGTH + 1,_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN);
Utils::copy<ZT_C25519_PUBLIC_KEY_LEN>(data + ZT_ADDRESS_LENGTH + 1,_pub.c25519);
if ((includePrivate)&&(_hasPrivate)) {
data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN] = ZT_C25519_PRIVATE_KEY_LEN;
memcpy(data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1,_priv.c25519,ZT_C25519_PRIVATE_KEY_LEN);
Utils::copy<ZT_C25519_PRIVATE_KEY_LEN>(data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1,_priv.c25519);
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1 + ZT_C25519_PRIVATE_KEY_LEN;
} else {
data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN] = 0;
@ -514,10 +514,10 @@ int Identity::marshal(uint8_t data[ZT_IDENTITY_MARSHAL_SIZE_MAX],const bool incl
case P384:
data[ZT_ADDRESS_LENGTH] = (uint8_t)P384;
memcpy(data + ZT_ADDRESS_LENGTH + 1,&_pub,ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE);
Utils::copy<ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1,&_pub);
if ((includePrivate)&&(_hasPrivate)) {
data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE] = ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE;
memcpy(data + ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1,&_priv,ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE);
Utils::copy<ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1,&_priv);
return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE;
} else {
data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE] = 0;
@ -544,7 +544,7 @@ int Identity::unmarshal(const uint8_t *data,const int len) noexcept
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1))
return -1;
memcpy(_pub.c25519,data + ZT_ADDRESS_LENGTH + 1,ZT_C25519_PUBLIC_KEY_LEN);
Utils::copy<ZT_C25519_PUBLIC_KEY_LEN>(_pub.c25519,data + ZT_ADDRESS_LENGTH + 1);
_computeHash();
privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN];
@ -552,7 +552,7 @@ int Identity::unmarshal(const uint8_t *data,const int len) noexcept
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1 + ZT_C25519_PRIVATE_KEY_LEN))
return -1;
_hasPrivate = true;
memcpy(_priv.c25519,data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1,ZT_C25519_PRIVATE_KEY_LEN);
Utils::copy<ZT_C25519_PRIVATE_KEY_LEN>(_priv.c25519,data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1);
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1 + ZT_C25519_PRIVATE_KEY_LEN;
} else if (privlen == 0) {
_hasPrivate = false;
@ -564,7 +564,7 @@ int Identity::unmarshal(const uint8_t *data,const int len) noexcept
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1))
return -1;
memcpy(&_pub,data + ZT_ADDRESS_LENGTH + 1,ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE);
Utils::copy<ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE>(&_pub,data + ZT_ADDRESS_LENGTH + 1);
_computeHash(); // this sets the address for P384
if (_address != Address(_fp.hash())) // this sanity check is possible with V1 identities
return -1;
@ -574,7 +574,7 @@ int Identity::unmarshal(const uint8_t *data,const int len) noexcept
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE))
return -1;
_hasPrivate = true;
memcpy(&_priv,data + ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1,ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE);
Utils::copy<ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE>(&_priv,data + ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1);
return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE;
} else if (privlen == 0) {
_hasPrivate = false;

View file

@ -96,16 +96,16 @@ InetAddress::IpScope InetAddress::ipScope() const noexcept
void InetAddress::set(const void *ipBytes,unsigned int ipLen,unsigned int port) noexcept
{
memset(this,0,sizeof(InetAddress));
memoryZero(this);
if (ipLen == 4) {
uint32_t ipb[1];
memcpy(ipb,ipBytes,4);
Utils::copy<4>(ipb,ipBytes);
_data.ss_family = AF_INET;
reinterpret_cast<struct sockaddr_in *>(this)->sin_addr.s_addr = ipb[0];
reinterpret_cast<struct sockaddr_in *>(this)->sin_port = Utils::hton((uint16_t)port);
} else if (ipLen == 16) {
_data.ss_family = AF_INET6;
memcpy(reinterpret_cast<struct sockaddr_in6 *>(this)->sin6_addr.s6_addr,ipBytes,16);
Utils::copy<16>(reinterpret_cast<struct sockaddr_in6 *>(this)->sin6_addr.s6_addr,ipBytes);
reinterpret_cast<struct sockaddr_in6 *>(this)->sin6_port = Utils::hton((uint16_t)port);
}
}
@ -164,7 +164,7 @@ bool InetAddress::fromString(const char *ipSlashPort) noexcept
{
char buf[64];
memset(this,0,sizeof(InetAddress));
memoryZero(this);
if (!*ipSlashPort)
return true;
@ -214,7 +214,7 @@ InetAddress InetAddress::netmask() const noexcept
nm[0] = 0;
nm[1] = 0;
}
memcpy(reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr,nm,16);
Utils::copy<16>(reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr,nm);
} break;
}
return r;
@ -240,10 +240,10 @@ InetAddress InetAddress::network() const noexcept
case AF_INET6: {
uint64_t nm[2];
const unsigned int bits = netmaskBits();
memcpy(nm,reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr,16);
Utils::copy<16>(nm,reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr);
nm[0] &= Utils::hton((uint64_t)((bits >= 64) ? 0xffffffffffffffffULL : (0xffffffffffffffffULL << (64 - bits))));
nm[1] &= Utils::hton((uint64_t)((bits <= 64) ? 0ULL : (0xffffffffffffffffULL << (128 - bits))));
memcpy(reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr,nm,16);
Utils::copy<16>(reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr,nm);
} break;
}
return r;
@ -324,7 +324,7 @@ void InetAddress::forTrace(ZT_TraceEventPathAddress &ta) const noexcept
uint32_t tmp;
switch(_data.ss_family) {
default:
memset(&ta,0,sizeof(ZT_TraceEventPathAddress));
Utils::zero<sizeof(ZT_TraceEventPathAddress)>(&ta);
break;
case AF_INET:
ta.type = ZT_TRACE_EVENT_PATH_TYPE_INETADDR_V4;
@ -333,13 +333,13 @@ void InetAddress::forTrace(ZT_TraceEventPathAddress &ta) const noexcept
ta.address[1] = reinterpret_cast<const uint8_t *>(&tmp)[1];
ta.address[2] = reinterpret_cast<const uint8_t *>(&tmp)[2];
ta.address[3] = reinterpret_cast<const uint8_t *>(&tmp)[3];
memset(ta.address + 4,0,sizeof(ta.address) - 4);
Utils::zero<sizeof(ta.address) - 4>(ta.address + 4);
ta.port = reinterpret_cast<const struct sockaddr_in *>(this)->sin_port;
break;
case AF_INET6:
ta.type = ZT_TRACE_EVENT_PATH_TYPE_INETADDR_V6;
memcpy(ta.address,reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr,16);
memset(ta.address + 16,0,sizeof(ta.address) - 16);
Utils::copy<16>(ta.address,reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr);
Utils::zero<sizeof(ta.address) - 16>(ta.address + 16);
ta.port = reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_port;
break;
}
@ -415,7 +415,7 @@ int InetAddress::unmarshal(const uint8_t *restrict data,const int len) noexcept
case 4:
if (len < 7)
return -1;
memset(reinterpret_cast<void *>(this),0,sizeof(InetAddress));
memoryZero(this);
reinterpret_cast<sockaddr_in *>(this)->sin_family = AF_INET;
reinterpret_cast<uint8_t *>(&(reinterpret_cast<sockaddr_in *>(this)->sin_addr.s_addr))[0] = data[1];
reinterpret_cast<uint8_t *>(&(reinterpret_cast<sockaddr_in *>(this)->sin_addr.s_addr))[1] = data[2];
@ -427,7 +427,7 @@ int InetAddress::unmarshal(const uint8_t *restrict data,const int len) noexcept
case 6:
if (len < 19)
return -1;
memset(reinterpret_cast<void *>(this),0,sizeof(InetAddress));
memoryZero(this);
reinterpret_cast<sockaddr_in6 *>(this)->sin6_family = AF_INET6;
for(int i=0;i<16;i++)
(reinterpret_cast<sockaddr_in6 *>(this)->sin6_addr.s6_addr)[i] = data[i+1];

View file

@ -43,9 +43,9 @@ private:
template<typename SA>
ZT_INLINE void copySockaddrToThis(const SA *sa) noexcept
{
memcpy(reinterpret_cast<void *>(this),sa,sizeof(SA));
Utils::copy<sizeof(SA)>(reinterpret_cast<void *>(this),sa);
if (sizeof(SA) < sizeof(InetAddress))
memset(reinterpret_cast<uint8_t *>(this) + sizeof(SA),0,sizeof(InetAddress) - sizeof(SA));
Utils::zero<sizeof(InetAddress) - sizeof(SA)>(reinterpret_cast<uint8_t *>(this) + sizeof(SA));
}
public:
@ -100,8 +100,11 @@ public:
ZT_INLINE InetAddress(const uint32_t ipv4,unsigned int port) noexcept { this->set(&ipv4,4,port); }
explicit ZT_INLINE InetAddress(const char *ipSlashPort) noexcept { this->fromString(ipSlashPort); }
ZT_INLINE void clear() noexcept { memoryZero(this); }
ZT_INLINE InetAddress &operator=(const InetAddress &a) noexcept
{
memoryCopy(this,a);
return *this;
}
ZT_INLINE InetAddress &operator=(const sockaddr_storage &ss) noexcept
{
memoryCopyUnsafe(this,&ss);
@ -123,7 +126,7 @@ public:
{
if (sa)
copySockaddrToThis(sa);
else memset(reinterpret_cast<void *>(this),0,sizeof(InetAddress));
else memoryZero(this);
return *this;
}
ZT_INLINE InetAddress &operator=(const sockaddr_in6 &sa) noexcept
@ -135,7 +138,7 @@ public:
{
if (sa)
copySockaddrToThis(sa);
else memset(reinterpret_cast<void *>(this),0,sizeof(InetAddress));
else memoryZero(this);
return *this;
}
ZT_INLINE InetAddress &operator=(const sockaddr &sa) noexcept
@ -144,7 +147,7 @@ public:
copySockaddrToThis(reinterpret_cast<const sockaddr_in *>(&sa));
else if (sa.sa_family == AF_INET6)
copySockaddrToThis(reinterpret_cast<const sockaddr_in6 *>(&sa));
else memset(reinterpret_cast<void *>(this),0,sizeof(InetAddress));
else memoryZero(this);
return *this;
}
ZT_INLINE InetAddress &operator=(const sockaddr *sa) noexcept
@ -161,6 +164,8 @@ public:
return *this;
}
ZT_INLINE void clear() noexcept { memoryZero(this); }
/**
* @return Address family (ss_family in sockaddr_storage)
*/
@ -339,7 +344,7 @@ public:
break;
case AF_INET6:
reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_family = AF_INET;
memcpy(reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr,reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr,16);
Utils::copy<16>(reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr,reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr);
break;
}
return r;

View file

@ -37,6 +37,7 @@
// original LZ4 license.
#include "LZ4.hpp"
#include "Utils.hpp"
#include <cstring>
#include <cstdlib>
@ -113,7 +114,6 @@ union LZ4_streamDecode_u {
#define ALLOCATOR(n,s) calloc(n,s)
#define FREEMEM free
#define MEM_INIT memset
typedef uint8_t BYTE;
typedef uint16_t U16;
@ -142,26 +142,26 @@ FORCE_INLINE U32 LZ4_read32(const void* ptr) { return ((const unalign*)ptr)->u32
FORCE_INLINE reg_t LZ4_read_ARCH(const void* ptr) { return ((const unalign*)ptr)->uArch; }
FORCE_INLINE void LZ4_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; }
FORCE_INLINE void LZ4_write32(void* memPtr, U32 value) { ((unalign*)memPtr)->u32 = value; }
#else /* safe and portable access through memcpy() */
#else /* safe and portable */
FORCE_INLINE U16 LZ4_read16(const void* memPtr)
{
U16 val; memcpy(&val, memPtr, sizeof(val)); return val;
U16 val; Utils::copy(&val, memPtr, sizeof(val)); return val;
}
FORCE_INLINE U32 LZ4_read32(const void* memPtr)
{
U32 val; memcpy(&val, memPtr, sizeof(val)); return val;
U32 val; Utils::copy(&val, memPtr, sizeof(val)); return val;
}
FORCE_INLINE reg_t LZ4_read_ARCH(const void* memPtr)
{
reg_t val; memcpy(&val, memPtr, sizeof(val)); return val;
reg_t val; Utils::copy(&val, memPtr, sizeof(val)); return val;
}
FORCE_INLINE void LZ4_write16(void* memPtr, U16 value)
{
memcpy(memPtr, &value, sizeof(value));
Utils::copy(memPtr, &value, sizeof(value));
}
FORCE_INLINE void LZ4_write32(void* memPtr, U32 value)
{
memcpy(memPtr, &value, sizeof(value));
Utils::copy(memPtr, &value, sizeof(value));
}
#endif /* LZ4_FORCE_MEMORY_ACCESS */
@ -188,7 +188,7 @@ FORCE_INLINE void LZ4_writeLE16(void* memPtr, U16 value)
FORCE_INLINE void LZ4_copy8(void* dst, const void* src)
{
memcpy(dst,src,8);
Utils::copy<8>(dst,src);
}
FORCE_INLINE void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd)
@ -555,7 +555,7 @@ FORCE_INLINE int LZ4_compress_generic(
} else {
*op++ = (BYTE)(lastRun<<ML_BITS);
}
memcpy(op, anchor, lastRun);
Utils::copy(op, anchor, lastRun);
op += lastRun;
}
@ -584,7 +584,7 @@ ZT_INLINE int LZ4_compress_fast_extState(void* state,const char* source,char* de
FORCE_INLINE void LZ4_resetStream (LZ4_stream_t* LZ4_stream)
{
MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t));
Utils::zero<sizeof(LZ4_stream_t)>(LZ4_stream);
}
FORCE_INLINE int LZ4_decompress_generic(
@ -655,7 +655,7 @@ FORCE_INLINE int LZ4_decompress_generic(
if ((!endOnInput) && (cpy != oend)) goto _output_error; /* Error : block decoding must stop exactly there */
if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error; /* Error : input must be consumed */
}
memcpy(op, ip, length);
Utils::copy(op, ip, length);
ip += length;
op += length;
break; /* Necessarily EOF, due to parsing restrictions */
@ -694,14 +694,14 @@ FORCE_INLINE int LZ4_decompress_generic(
/* match encompass external dictionary and current block */
size_t const copySize = (size_t)(lowPrefix-match);
size_t const restSize = length - copySize;
memcpy(op, dictEnd - copySize, copySize);
Utils::copy(op, dictEnd - copySize, copySize);
op += copySize;
if (restSize > (size_t)(op-lowPrefix)) { /* overlap copy */
BYTE* const endOfMatch = op + restSize;
const BYTE* copyFrom = lowPrefix;
while (op < endOfMatch) *op++ = *copyFrom++;
} else {
memcpy(op, lowPrefix, restSize);
Utils::copy(op, lowPrefix, restSize);
op += restSize;
} }
continue;
@ -716,7 +716,7 @@ FORCE_INLINE int LZ4_decompress_generic(
op[2] = match[2];
op[3] = match[3];
match += dec32table[offset];
memcpy(op+4, match, 4);
Utils::copy<4>(op+4, match);
match -= dec64;
} else { LZ4_copy8(op, match); match+=8; }
op += 8;

View file

@ -59,7 +59,7 @@ int Locator::marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX],const bool exclud
if (!excludeSignature) {
Utils::storeBigEndian(data + p,(uint16_t)_signatureLength);
p += 2;
memcpy(data + p,_signature,_signatureLength);
Utils::copy(data + p,_signature,_signatureLength);
p += (int)_signatureLength;
}
@ -102,7 +102,7 @@ int Locator::unmarshal(const uint8_t *restrict data,const int len) noexcept
_signatureLength = sl;
if ((p + (int)sl) > len)
return -1;
memcpy(_signature,data + p,sl);
Utils::copy(_signature,data + p,sl);
p += (int)sl;
if ((p + 2) > len)

View file

@ -1458,20 +1458,20 @@ void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const
ec->assignedAddressCount = 0;
for(unsigned int i=0;i<ZT_MAX_ZT_ASSIGNED_ADDRESSES;++i) {
if (i < _config.staticIpCount) {
memcpy(&(ec->assignedAddresses[i]),&(_config.staticIps[i]),sizeof(struct sockaddr_storage));
Utils::copy<sizeof(struct sockaddr_storage)>(&(ec->assignedAddresses[i]),&(_config.staticIps[i]));
++ec->assignedAddressCount;
} else {
memset(&(ec->assignedAddresses[i]),0,sizeof(struct sockaddr_storage));
Utils::zero<sizeof(struct sockaddr_storage)>(&(ec->assignedAddresses[i]));
}
}
ec->routeCount = 0;
for(unsigned int i=0;i<ZT_MAX_NETWORK_ROUTES;++i) {
if (i < _config.routeCount) {
memcpy(&(ec->routes[i]),&(_config.routes[i]),sizeof(ZT_VirtualNetworkRoute));
Utils::copy<sizeof(ZT_VirtualNetworkRoute)>(&(ec->routes[i]),&(_config.routes[i]));
++ec->routeCount;
} else {
memset(&(ec->routes[i]),0,sizeof(ZT_VirtualNetworkRoute));
Utils::zero<sizeof(ZT_VirtualNetworkRoute)>(&(ec->routes[i]));
}
}
}

View file

@ -123,9 +123,9 @@ bool NetworkConfig::fromDictionary(const Dictionary &d)
this->issuedTo = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO,0);
const std::vector<uint8_t> *blob = &(d[ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO_IDENTITY_HASH]);
if (blob->size() == ZT_IDENTITY_HASH_SIZE) {
memcpy(this->issuedToFingerprintHash,blob->data(),ZT_IDENTITY_HASH_SIZE);
Utils::copy<ZT_IDENTITY_HASH_SIZE>(this->issuedToFingerprintHash,blob->data());
} else {
memset(this->issuedToFingerprintHash,0,ZT_IDENTITY_HASH_SIZE);
Utils::zero<ZT_IDENTITY_HASH_SIZE>(this->issuedToFingerprintHash);
}
if (!this->issuedTo)
return false;

View file

@ -157,9 +157,6 @@ namespace ZeroTier {
/**
* Network configuration received from network controller nodes
*
* This is a memcpy()'able structure and is safe (in a crash sense) to modify
* without locks.
*/
struct NetworkConfig : TriviallyCopyable
{

View file

@ -493,7 +493,7 @@ ZT_PeerList *Node::peers() const
identities[pl->peerCount] = (*pi)->identity(); // need to make a copy in case peer gets deleted
p->identity = &identities[pl->peerCount];
p->fingerprint.address = p->address;
memcpy(p->fingerprint.hash,(*pi)->identity().fingerprint().hash(),ZT_IDENTITY_HASH_SIZE);
Utils::copy<ZT_IDENTITY_HASH_SIZE>(p->fingerprint.hash,(*pi)->identity().fingerprint().hash());
if ((*pi)->remoteVersionKnown()) {
p->versionMajor = (int)(*pi)->remoteVersionMajor();
p->versionMinor = (int)(*pi)->remoteVersionMinor();
@ -507,13 +507,13 @@ ZT_PeerList *Node::peers() const
if (p->latency >= 0xffff)
p->latency = -1;
p->root = RR->topology->isRoot((*pi)->identity()) ? 1 : 0;
memcpy(&p->bootstrap,&((*pi)->bootstrap()),sizeof(sockaddr_storage));
Utils::copy<sizeof(sockaddr_storage)>(&p->bootstrap,&((*pi)->bootstrap()));
std::vector< SharedPtr<Path> > paths;
(*pi)->getAllPaths(paths);
p->pathCount = 0;
for(std::vector< SharedPtr<Path> >::iterator path(paths.begin());path!=paths.end();++path) {
memcpy(&(p->paths[p->pathCount].address),&((*path)->address()),sizeof(struct sockaddr_storage));
Utils::copy<sizeof(sockaddr_storage)>(&(p->paths[p->pathCount].address),&((*path)->address()));
p->paths[p->pathCount].lastSend = (*path)->lastOut();
p->paths[p->pathCount].lastReceive = (*path)->lastIn();
p->paths[p->pathCount].trustedPathId = RR->topology->getOutboundPathTrust((*path)->address());

View file

@ -33,8 +33,8 @@ std::atomic<uint64_t> _s_packetIdCtr((uint64_t)time(nullptr) << 32U);
uint64_t createProbe(const Identity &sender,const Identity &recipient,const uint8_t key[ZT_PEER_SECRET_KEY_LENGTH]) noexcept
{
uint8_t tmp[ZT_IDENTITY_HASH_SIZE + ZT_IDENTITY_HASH_SIZE];
memcpy(tmp,sender.fingerprint().hash(),ZT_IDENTITY_HASH_SIZE);
memcpy(tmp + ZT_IDENTITY_HASH_SIZE,recipient.fingerprint().hash(),ZT_IDENTITY_HASH_SIZE);
Utils::copy<ZT_IDENTITY_HASH_SIZE>(tmp,sender.fingerprint().hash());
Utils::copy<ZT_IDENTITY_HASH_SIZE>(tmp + ZT_IDENTITY_HASH_SIZE,recipient.fingerprint().hash());
uint64_t hash[6];
SHA384(hash,tmp,sizeof(tmp),key,ZT_PEER_SECRET_KEY_LENGTH);
return hash[0];
@ -93,7 +93,7 @@ int compress(SharedPtr<Buf> &pkt,int packetSize) noexcept
const int uncompressedLen = packetSize - ZT_PROTO_PACKET_PAYLOAD_START;
const int compressedLen = LZ4_compress_fast(reinterpret_cast<const char *>(pkt->unsafeData + ZT_PROTO_PACKET_PAYLOAD_START),reinterpret_cast<char *>(pkt2->unsafeData + ZT_PROTO_PACKET_PAYLOAD_START),uncompressedLen,ZT_BUF_MEM_SIZE - ZT_PROTO_PACKET_PAYLOAD_START);
if ((compressedLen > 0)&&(compressedLen < uncompressedLen)) {
memcpy(pkt2->unsafeData,pkt->unsafeData,ZT_PROTO_PACKET_PAYLOAD_START);
Utils::copy<ZT_PROTO_PACKET_PAYLOAD_START>(pkt2->unsafeData,pkt->unsafeData);
pkt.swap(pkt2);
pkt->as<Protocol::Header>().verb |= ZT_PROTO_VERB_FLAG_COMPRESSED;
return compressedLen + ZT_PROTO_PACKET_PAYLOAD_START;

View file

@ -46,7 +46,7 @@ int Revocation::marshal(uint8_t data[ZT_REVOCATION_MARSHAL_SIZE_MAX],bool forSig
if (!forSign) {
data[p++] = 1;
Utils::storeBigEndian<uint16_t>(data + p,(uint16_t)_signatureLength);
memcpy(data + p,_signature,_signatureLength);
Utils::copy(data + p,_signature,_signatureLength);
p += (int)_signatureLength;
}
data[p++] = 0;
@ -77,7 +77,7 @@ int Revocation::unmarshal(const uint8_t *restrict data,const int len) noexcept
int p = 54 + (int)_signatureLength;
if ((_signatureLength > ZT_SIGNATURE_BUFFER_SIZE)||(p > len))
return -1;
memcpy(_signature,data + 54,_signatureLength);
Utils::copy(_signature,data + 54,_signatureLength);
if ((p + 2) > len)
return -1;
p += 2 + Utils::loadBigEndian<uint16_t>(data + p);

View file

@ -265,7 +265,7 @@ void KBKDFHMACSHA384(const uint8_t key[32],const char label,const char context,c
kbkdfMsg[11] = 1;
kbkdfMsg[12] = 0; // key length: 256 bits as big-endian 32-bit value
HMACSHA384(key,&kbkdfMsg,sizeof(kbkdfMsg),kbuf);
memcpy(out,kbuf,32);
Utils::copy<32>(out,kbuf);
}
} // namespace ZeroTier

View file

@ -25,10 +25,6 @@ namespace ZeroTier {
* This is an introspective shared pointer. Classes that need to be reference
* counted must list this as a 'friend' and must have a private instance of
* atomic<int> called __refCount.
*
* This is technically TriviallyCopyable but extreme care must be taken if
* one wishes to handle it in this manner. A memcpy must be followed by a
* memset of the source to 0 so as to achieve 'move' semantics.
*/
template<typename T>
class SharedPtr : public TriviallyCopyable

View file

@ -42,7 +42,7 @@ int Tag::marshal(uint8_t data[ZT_TAG_MARSHAL_SIZE_MAX],bool forSign) const noexc
if (!forSign) {
data[p++] = 1;
Utils::storeBigEndian<uint16_t>(data + p,(uint16_t)_signatureLength); p += 2;
memcpy(data + p,_signature,_signatureLength);
Utils::copy(data + p,_signature,_signatureLength);
p += (int)_signatureLength;
}
data[p++] = 0;
@ -69,7 +69,7 @@ int Tag::unmarshal(const uint8_t *data,int len) noexcept
int p = 37 + (int)_signatureLength;
if ((_signatureLength > ZT_SIGNATURE_BUFFER_SIZE)||(p > len))
return -1;
memcpy(_signature,data + p,_signatureLength);
Utils::copy(_signature,data + p,_signatureLength);
if ((p + 2) > len)
return -1;
p += 2 + Utils::loadBigEndian<uint16_t>(data + p);

View file

@ -338,19 +338,19 @@ extern "C" const char *ZTT_general()
ZT_T_PRINTF("FAILED (loadAsIsEndian)" ZT_EOL_S);
return "Utils::loadAsIsEndian() broken";
}
memset(t,0,sizeof(t));
Utils::zero<sizeof(t)>(t);
Utils::storeAsIsEndian<uint64_t>(t,0x0807060504030201ULL);
if (t[0] != 1) {
ZT_T_PRINTF("FAILED (storeAsIsEndian)" ZT_EOL_S);
return "Utils::storeAsIsEndian() broken";
}
memset(t,0,sizeof(t));
Utils::zero<sizeof(t)>(t);
Utils::storeAsIsEndian<uint32_t>(t,0x04030201);
if (t[0] != 1) {
ZT_T_PRINTF("FAILED (storeAsIsEndian)" ZT_EOL_S);
return "Utils::storeAsIsEndian() broken";
}
memset(t,0,sizeof(t));
Utils::zero<sizeof(t)>(t);
Utils::storeAsIsEndian<uint16_t>(t,0x0201);
if (t[0] != 1) {
ZT_T_PRINTF("FAILED (storeAsIsEndian)" ZT_EOL_S);
@ -369,19 +369,19 @@ extern "C" const char *ZTT_general()
ZT_T_PRINTF("FAILED (loadAsIsEndian)" ZT_EOL_S);
return "Utils::loadAsIsEndian() broken";
}
memset(t,0,sizeof(t));
Utils::zero<sizeof(t)>(t);
Utils::storeAsIsEndian<uint64_t>(t,0x0807060504030201ULL);
if (t[0] != 8) {
ZT_T_PRINTF("FAILED (storeAsIsEndian)" ZT_EOL_S);
return "Utils::storeAsIsEndian() broken";
}
memset(t,0,sizeof(t));
Utils::zero<sizeof(t)>(t);
Utils::storeAsIsEndian<uint32_t>(t,0x04030201);
if (t[0] != 4) {
ZT_T_PRINTF("FAILED (storeAsIsEndian)" ZT_EOL_S);
return "Utils::storeAsIsEndian() broken";
}
memset(t,0,sizeof(t));
Utils::zero<sizeof(t)>(t);
Utils::storeAsIsEndian<uint16_t>(t,0x0201);
if (t[0] != 2) {
ZT_T_PRINTF("FAILED (storeAsIsEndian)" ZT_EOL_S);
@ -831,14 +831,14 @@ extern "C" const char *ZTT_crypto()
ZT_T_PRINTF("[crypto] Testing Salsa20... ");
Salsa20 s20;
s20.init(SALSA20_TV0_KEY,SALSA20_TV0_IV);
memset(ks,0,sizeof(ks));
Utils::zero<sizeof(ks)>(ks);
s20.crypt20(ks,ks,sizeof(ks));
if (memcmp(ks,SALSA20_TV0_KS,64) != 0) {
ZT_T_PRINTF("FAILED (Salsa20 test vector)" ZT_EOL_S);
return "Salsa20 test vector failed";
}
s20.init(SALSA12_TV0_KEY,SALSA12_TV0_IV);
memset(ks,0,sizeof(ks));
Utils::zero<sizeof(ks)>(ks);
s20.crypt12(ks,ks,sizeof(ks));
if (memcmp(ks,SALSA12_TV0_KS,64) != 0) {
ZT_T_PRINTF("FAILED (Salsa12 test vector)" ZT_EOL_S);
@ -994,8 +994,8 @@ extern "C" const char *ZTT_benchmarkCrypto()
{
try {
uint8_t tmp[16384],tag[16];
memset(tmp,0,sizeof(tmp));
memset(tag,0,sizeof(tag));
Utils::zero<sizeof(tmp)>(tmp);
Utils::zero<sizeof(tag)>(tag);
{
ZT_T_PRINTF("[crypto] Benchmarking SHA384... ");
@ -1094,7 +1094,7 @@ extern "C" const char *ZTT_benchmarkCrypto()
{
uint8_t sig[ZT_C25519_SIGNATURE_LEN];
memset(sig,0,sizeof(sig));
Utils::zero<sizeof(sig)>(sig);
ZT_T_PRINTF("[crypto] Benchmarking Ed25519 signature... ");
int64_t start = now();
for(int i=0;i<150;++i) {
@ -1169,7 +1169,7 @@ extern "C" const char *ZTT_benchmarkCrypto()
for(long i=0;i<10;++i)
foo = (uint8_t)id.locallyValidate();
end = now();
ZT_T_PRINTF("%.4f ms/validation" ZT_EOL_S,(double)(end - start) / 10.0);
ZT_T_PRINTF(" %.4f ms/validation" ZT_EOL_S,(double)(end - start) / 10.0);
ZT_T_PRINTF("[crypto] Benchmarking V1 Identity generation...");
start = now();
for(long i=0;i<10;++i) {

View file

@ -74,7 +74,7 @@ void Trace::unexpectedError(
ev.evSize = ZT_CONST_TO_BE_UINT16(sizeof(ev));
ev.evType = ZT_CONST_TO_BE_UINT16(ZT_TRACE_UNEXPECTED_ERROR);
ev.codeLocation = codeLocation;
memset(ev.message,0,sizeof(ev.message));
Utils::zero<sizeof(ev.message)>(ev.message);
va_start(ap,message);
vsnprintf(ev.message,sizeof(ev.message),message,ap);
va_end(ap);
@ -116,12 +116,12 @@ void Trace::_tryingNewPath(
ev.evSize = ZT_CONST_TO_BE_UINT16(sizeof(ev));
ev.evType = ZT_CONST_TO_BE_UINT16(ZT_TRACE_VL1_TRYING_NEW_PATH);
ev.codeLocation = Utils::hton(codeLocation);
memcpy(&ev.peer,trying.fingerprint().apiFingerprint(),sizeof(ev.peer));
Utils::copy<sizeof(ev.peer)>(&ev.peer,trying.fingerprint().apiFingerprint());
physicalAddress.forTrace(ev.physicalAddress);
triggerAddress.forTrace(ev.triggerAddress);
ev.triggeringPacketId = triggeringPacketId;
ev.triggeringPacketVerb = triggeringPacketVerb;
memcpy(&ev.triggeringPeer,triggeringPeer.fingerprint().apiFingerprint(),sizeof(ev.triggeringPeer));
Utils::copy<sizeof(ev.triggeringPeer)>(&ev.triggeringPeer,triggeringPeer.fingerprint().apiFingerprint());
ev.reason = (uint8_t)reason;
RR->node->postEvent(tPtr,ZT_EVENT_TRACE,&ev);
}
@ -139,7 +139,7 @@ void Trace::_learnedNewPath(
ev.evType = ZT_CONST_TO_BE_UINT16(ZT_TRACE_VL1_LEARNED_NEW_PATH);
ev.codeLocation = Utils::hton(codeLocation);
ev.packetId = packetId; // packet IDs are kept in big-endian
memcpy(&ev.peer,peerIdentity.fingerprint().apiFingerprint(),sizeof(ev.peer));
Utils::copy<sizeof(ev.peer)>(&ev.peer,peerIdentity.fingerprint().apiFingerprint());
physicalAddress.forTrace(ev.physicalAddress);
replaced.forTrace(ev.replaced);
@ -163,7 +163,7 @@ void Trace::_incomingPacketDropped(
ev.codeLocation = Utils::hton(codeLocation);
ev.packetId = packetId; // packet IDs are kept in big-endian
ev.networkId = Utils::hton(networkId);
memcpy(&ev.peer,peerIdentity.fingerprint().apiFingerprint(),sizeof(ev.peer));
Utils::copy<sizeof(ev.peer)>(&ev.peer,peerIdentity.fingerprint().apiFingerprint());
physicalAddress.forTrace(ev.physicalAddress);
ev.hops = hops;
ev.verb = verb;
@ -196,8 +196,8 @@ void Trace::_outgoingNetworkFrameDropped(
unsigned int l = frameLength;
if (l > sizeof(ev.frameHead))
l = sizeof(ev.frameHead);
memcpy(ev.frameHead,frameData,l);
memset(ev.frameHead + l,0,sizeof(ev.frameHead) - l);
Utils::copy(ev.frameHead,frameData,l);
Utils::copy(ev.frameHead + l,0,sizeof(ev.frameHead) - l);
}
ev.reason = (uint8_t)reason;
@ -226,7 +226,7 @@ void Trace::_incomingNetworkFrameDropped(
ev.networkId = Utils::hton(networkId);
ev.sourceMac = Utils::hton(sourceMac.toInt());
ev.destMac = Utils::hton(destMac.toInt());
memcpy(&ev.sender,peerIdentity.fingerprint().apiFingerprint(),sizeof(ev.sender));
Utils::copy<sizeof(ev.sender)>(&ev.sender,peerIdentity.fingerprint().apiFingerprint());
physicalAddress.forTrace(ev.physicalAddress);
ev.hops = hops;
ev.frameLength = Utils::hton(frameLength);
@ -234,8 +234,8 @@ void Trace::_incomingNetworkFrameDropped(
unsigned int l = frameLength;
if (l > sizeof(ev.frameHead))
l = sizeof(ev.frameHead);
memcpy(ev.frameHead,frameData,l);
memset(ev.frameHead + l,0,sizeof(ev.frameHead) - l);
Utils::copy(ev.frameHead,frameData,l);
Utils::copy(ev.frameHead + l,0,sizeof(ev.frameHead) - l);
}
ev.verb = verb;
ev.credentialRequestSent = (uint8_t)credentialRequestSent;
@ -282,10 +282,10 @@ void Trace::_networkFilter(
ev.evType = ZT_CONST_TO_BE_UINT16(ZT_TRACE_VL2_NETWORK_FILTER);
ev.codeLocation = Utils::hton(codeLocation);
ev.networkId = Utils::hton(networkId);
memcpy(ev.primaryRuleSetLog,primaryRuleSetLog,sizeof(ev.primaryRuleSetLog));
Utils::copy<sizeof(ev.primaryRuleSetLog)>(ev.primaryRuleSetLog,primaryRuleSetLog);
if (matchingCapabilityRuleSetLog)
memcpy(ev.matchingCapabilityRuleSetLog,matchingCapabilityRuleSetLog,sizeof(ev.matchingCapabilityRuleSetLog));
else memset(ev.matchingCapabilityRuleSetLog,0,sizeof(ev.matchingCapabilityRuleSetLog));
Utils::copy<sizeof(ev.matchingCapabilityRuleSetLog)>(ev.matchingCapabilityRuleSetLog,matchingCapabilityRuleSetLog);
else Utils::zero<sizeof(ev.matchingCapabilityRuleSetLog)>(ev.matchingCapabilityRuleSetLog);
ev.matchingCapabilityId = Utils::hton(matchingCapabilityId);
ev.matchingCapabilityTimestamp = Utils::hton(matchingCapabilityTimestamp);
ev.source = Utils::hton(source.toInt());
@ -297,8 +297,8 @@ void Trace::_networkFilter(
unsigned int l = frameLength;
if (l > sizeof(ev.frameHead))
l = sizeof(ev.frameHead);
memcpy(ev.frameHead,frameData,l);
memset(ev.frameHead + l,0,sizeof(ev.frameHead) - l);
Utils::copy(ev.frameHead,frameData,l);
Utils::copy(ev.frameHead + l,0,sizeof(ev.frameHead) - l);
}
ev.etherType = Utils::hton(etherType);
ev.vlanId = Utils::hton(vlanId);
@ -325,10 +325,10 @@ void Trace::_credentialRejected(
ev.codeLocation = Utils::hton(codeLocation);
ev.networkId = Utils::hton(networkId);
if (identity) {
memcpy(&ev.peer,identity.fingerprint().apiFingerprint(),sizeof(ev.peer));
Utils::copy<sizeof(ev.peer)>(&ev.peer,identity.fingerprint().apiFingerprint());
} else {
ev.peer.address = address.toInt();
memset(ev.peer.hash,0,sizeof(ev.peer.hash));
Utils::zero<sizeof(ev.peer.hash)>(ev.peer.hash);
}
ev.credentialId = Utils::hton(credentialId);
ev.credentialTimestamp = Utils::hton(credentialTimestamp);

View file

@ -70,7 +70,7 @@ public:
}
ZT_INLINE void clear()
{
memset(l,0,sizeof(l));
Utils::zero<sizeof(l)>(l);
}
};
@ -82,7 +82,7 @@ public:
template<unsigned int C>
struct Str
{
ZT_INLINE Str() { memset(s,0,sizeof(s)); }
ZT_INLINE Str() { Utils::zero<sizeof(s)>(s); }
constexpr static unsigned int capacity() { return C; }
char s[C];
};

View file

@ -23,7 +23,7 @@
namespace ZeroTier {
/**
* Classes inheriting from this base class are safe to abuse in C-like ways: memcpy, memset, etc.
* Classes inheriting from this base class are safe to abuse in C-like ways.
*
* It also includes some static methods to do this conveniently.
*/
@ -65,7 +65,7 @@ ZT_PACKED_STRUCT(struct TriviallyCopyable
static ZT_INLINE void memoryZero(T *obj) noexcept
{
TriviallyCopyable *const tmp = obj;
memset(tmp,0,sizeof(T));
Utils::zero<sizeof(T)>(tmp);
}
/**
@ -78,7 +78,7 @@ ZT_PACKED_STRUCT(struct TriviallyCopyable
static ZT_INLINE void memoryZero(T &obj) noexcept
{
TriviallyCopyable *const tmp = &obj;
memset(tmp,0,sizeof(T));
Utils::zero<sizeof(T)>(tmp);
}
/**
@ -92,7 +92,7 @@ ZT_PACKED_STRUCT(struct TriviallyCopyable
static ZT_INLINE void memoryCopyUnsafe(T *dest,const void *src) noexcept
{
TriviallyCopyable *const tmp = dest;
memcpy(tmp,src,sizeof(T));
Utils::copy<sizeof(T)>(tmp,src);
}
/**
@ -106,7 +106,7 @@ ZT_PACKED_STRUCT(struct TriviallyCopyable
static ZT_INLINE void memoryCopyUnsafe(T &dest,const void *src) noexcept
{
TriviallyCopyable *const tmp = &dest;
memcpy(tmp,src,sizeof(T));
Utils::copy<sizeof(T)>(tmp,src);
}
/**
@ -120,7 +120,7 @@ ZT_PACKED_STRUCT(struct TriviallyCopyable
static ZT_INLINE void memoryCopy(T *dest,const T *src) noexcept
{
TriviallyCopyable *const tmp = dest;
memcpy(tmp,src,sizeof(T));
Utils::copy<sizeof(T)>(tmp,src);
}
/**
@ -134,7 +134,7 @@ ZT_PACKED_STRUCT(struct TriviallyCopyable
static ZT_INLINE void memoryCopy(T *dest,const T &src) noexcept
{
TriviallyCopyable *const tmp = dest;
memcpy(tmp,&src,sizeof(T));
Utils::copy<sizeof(T)>(tmp,&src);
}
/**
@ -148,7 +148,7 @@ ZT_PACKED_STRUCT(struct TriviallyCopyable
static ZT_INLINE void memoryCopy(T &dest,const T *src) noexcept
{
TriviallyCopyable *const tmp = &dest;
memcpy(tmp,src,sizeof(T));
Utils::copy<sizeof(T)>(tmp,src);
}
/**
@ -162,7 +162,7 @@ ZT_PACKED_STRUCT(struct TriviallyCopyable
static ZT_INLINE void memoryCopy(T &dest,const T &src) noexcept
{
TriviallyCopyable *const tmp = &dest;
memcpy(tmp,&src,sizeof(T));
Utils::copy<sizeof(T)>(tmp,&src);
}
});

View file

@ -16,6 +16,12 @@
#include "Constants.hpp"
#ifdef ZT_ARCH_X64
#include <xmmintrin.h>
#include <emmintrin.h>
#include <immintrin.h>
#endif
namespace ZeroTier {
namespace Utils {
@ -577,6 +583,260 @@ static ZT_INLINE void storeLittleEndian(void *const p,const I i) noexcept
#endif
}
template<unsigned int L>
static ZT_INLINE void copy(void *dest,const void *src) noexcept;
template<>
ZT_INLINE void copy<64>(void *const dest,const void *const src) noexcept
{
#ifdef ZT_ARCH_X64
__m128i a = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src));
__m128i b = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src) + 1);
__m128i c = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src) + 2);
__m128i d = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src) + 3);
_mm_storeu_si128(reinterpret_cast<__m128i *>(dest),a);
_mm_storeu_si128(reinterpret_cast<__m128i *>(dest) + 1,b);
_mm_storeu_si128(reinterpret_cast<__m128i *>(dest) + 2,c);
_mm_storeu_si128(reinterpret_cast<__m128i *>(dest) + 3,d);
#else
uint64_t a = reinterpret_cast<const uint64_t *>(src)[0];
uint64_t b = reinterpret_cast<const uint64_t *>(src)[1];
uint64_t c = reinterpret_cast<const uint64_t *>(src)[2];
uint64_t d = reinterpret_cast<const uint64_t *>(src)[3];
uint64_t e = reinterpret_cast<const uint64_t *>(src)[4];
uint64_t f = reinterpret_cast<const uint64_t *>(src)[5];
uint64_t g = reinterpret_cast<const uint64_t *>(src)[6];
uint64_t h = reinterpret_cast<const uint64_t *>(src)[7];
reinterpret_cast<uint64_t *>(dest)[0] = a;
reinterpret_cast<uint64_t *>(dest)[1] = b;
reinterpret_cast<uint64_t *>(dest)[2] = c;
reinterpret_cast<uint64_t *>(dest)[3] = d;
reinterpret_cast<uint64_t *>(dest)[4] = e;
reinterpret_cast<uint64_t *>(dest)[5] = f;
reinterpret_cast<uint64_t *>(dest)[6] = g;
reinterpret_cast<uint64_t *>(dest)[7] = h;
#endif
}
template<>
ZT_INLINE void copy<32>(void *const dest,const void *const src) noexcept
{
#ifdef ZT_ARCH_X64
__m128i a = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src));
__m128i b = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src) + 1);
_mm_storeu_si128(reinterpret_cast<__m128i *>(dest),a);
_mm_storeu_si128(reinterpret_cast<__m128i *>(dest) + 1,b);
#else
uint64_t a = reinterpret_cast<const uint64_t *>(src)[0];
uint64_t b = reinterpret_cast<const uint64_t *>(src)[1];
uint64_t c = reinterpret_cast<const uint64_t *>(src)[2];
uint64_t d = reinterpret_cast<const uint64_t *>(src)[3];
reinterpret_cast<uint64_t *>(dest)[0] = a;
reinterpret_cast<uint64_t *>(dest)[1] = b;
reinterpret_cast<uint64_t *>(dest)[2] = c;
reinterpret_cast<uint64_t *>(dest)[3] = d;
#endif
}
template<>
ZT_INLINE void copy<16>(void *const dest,const void *const src) noexcept
{
#ifdef ZT_ARCH_X64
_mm_storeu_si128(reinterpret_cast<__m128i *>(dest),_mm_loadu_si128(reinterpret_cast<const __m128i *>(src)));
#else
uint64_t a = reinterpret_cast<const uint64_t *>(src)[0];
uint64_t b = reinterpret_cast<const uint64_t *>(src)[1];
reinterpret_cast<uint64_t *>(dest)[0] = a;
reinterpret_cast<uint64_t *>(dest)[1] = b;
#endif
}
template<>
ZT_INLINE void copy<8>(void *const dest,const void *const src) noexcept
{
*reinterpret_cast<uint64_t *>(dest) = *reinterpret_cast<const uint64_t *>(src);
}
template<>
ZT_INLINE void copy<4>(void *const dest,const void *const src) noexcept
{
*reinterpret_cast<uint32_t *>(dest) = *reinterpret_cast<const uint32_t *>(src);
}
template<>
ZT_INLINE void copy<2>(void *const dest,const void *const src) noexcept
{
*reinterpret_cast<uint16_t *>(dest) = *reinterpret_cast<const uint16_t *>(src);
}
template<>
ZT_INLINE void copy<1>(void *const dest,const void *const src) noexcept
{
*reinterpret_cast<uint8_t *>(dest) = *reinterpret_cast<const uint8_t *>(src);
}
template<>
ZT_INLINE void copy<0>(void *const dest,const void *const src) noexcept
{
}
template<unsigned int L>
static ZT_INLINE void copy(void *const dest,const void *const src) noexcept
{
#ifdef ZT_NO_UNALIGNED_ACCESS
if ((((uintptr_t)dest | (uintptr_t)src) & 7U) != 0) {
memcpy(dest,src,L);
return;
}
#endif
uint8_t *d = reinterpret_cast<uint8_t *>(dest);
const uint8_t *s = reinterpret_cast<const uint8_t *>(src);
for(unsigned int i=0;i<(L / 64U);++i) {
copy<64>(d,s);
d += 64;
s += 64;
}
if ((L & 63U) >= 32U) {
copy<32>(d,s);
d += 32;
s += 32;
}
if ((L & 31U) >= 16U) {
copy<16>(d,s);
d += 16;
s += 16;
}
if ((L & 15U) >= 8U) {
copy<8>(d,s);
d += 8;
s += 8;
}
if ((L & 7U) >= 4U) {
copy<4>(d,s);
d += 4;
s += 4;
}
if ((L & 3U) >= 2U) {
copy<2>(d,s);
d += 2;
s += 2;
}
if ((L & 1U) != 0U) {
copy<1>(d,s);
}
}
static ZT_INLINE void copy(void *const dest,const void *const src,const unsigned int len) noexcept
{
memcpy(dest,src,len);
}
template<unsigned int L>
static ZT_INLINE void zero(void *dest) noexcept;
template<>
ZT_INLINE void zero<64>(void *const dest) noexcept
{
#ifdef ZT_ARCH_X64
const __m128i z = _mm_setzero_si128();
_mm_storeu_si128(reinterpret_cast<__m128i *>(dest),z);
_mm_storeu_si128(reinterpret_cast<__m128i *>(dest) + 1,z);
_mm_storeu_si128(reinterpret_cast<__m128i *>(dest) + 2,z);
_mm_storeu_si128(reinterpret_cast<__m128i *>(dest) + 3,z);
#else
const uint64_t z = 0;
reinterpret_cast<uint64_t *>(dest)[0] = z;
reinterpret_cast<uint64_t *>(dest)[1] = z;
reinterpret_cast<uint64_t *>(dest)[2] = z;
reinterpret_cast<uint64_t *>(dest)[3] = z;
reinterpret_cast<uint64_t *>(dest)[4] = z;
reinterpret_cast<uint64_t *>(dest)[5] = z;
reinterpret_cast<uint64_t *>(dest)[6] = z;
reinterpret_cast<uint64_t *>(dest)[7] = z;
#endif
}
template<>
ZT_INLINE void zero<32>(void *const dest) noexcept
{
#ifdef ZT_ARCH_X64
const __m128i z = _mm_setzero_si128();
_mm_storeu_si128(reinterpret_cast<__m128i *>(dest),z);
_mm_storeu_si128(reinterpret_cast<__m128i *>(dest) + 1,z);
#else
const uint64_t z = 0;
reinterpret_cast<uint64_t *>(dest)[0] = z;
reinterpret_cast<uint64_t *>(dest)[1] = z;
reinterpret_cast<uint64_t *>(dest)[2] = z;
reinterpret_cast<uint64_t *>(dest)[3] = z;
#endif
}
template<>
ZT_INLINE void zero<16>(void *const dest) noexcept
{
const uint64_t z = 0;
reinterpret_cast<uint64_t *>(dest)[0] = z;
reinterpret_cast<uint64_t *>(dest)[1] = z;
}
template<>
ZT_INLINE void zero<8>(void *const dest) noexcept
{
*reinterpret_cast<uint64_t *>(dest) = 0;
}
template<>
ZT_INLINE void zero<4>(void *const dest) noexcept
{
*reinterpret_cast<uint32_t *>(dest) = 0;
}
template<>
ZT_INLINE void zero<2>(void *const dest) noexcept
{
*reinterpret_cast<uint16_t *>(dest) = 0;
}
template<>
ZT_INLINE void zero<1>(void *const dest) noexcept
{
*reinterpret_cast<uint8_t *>(dest) = 0;
}
template<>
ZT_INLINE void zero<0>(void *const dest) noexcept
{
}
template<unsigned int L>
static ZT_INLINE void zero(void *const dest) noexcept
{
#ifdef ZT_NO_UNALIGNED_ACCESS
if ((((uintptr_t)dest | (uintptr_t)src) & 7U) != 0) {
memset(dest,0,L);
return;
}
#endif
uint8_t *d = reinterpret_cast<uint8_t *>(dest);
for(unsigned int i=0;i<(L / 64U);++i) {
zero<64>(d);
d += 64;
}
if ((L & 63U) >= 32U) {
zero<32>(d);
d += 32;
}
if ((L & 31U) >= 16U) {
zero<16>(d);
d += 16;
}
if ((L & 15U) >= 8U) {
zero<8>(d);
d += 8;
}
if ((L & 7U) >= 4U) {
zero<4>(d);
d += 4;
}
if ((L & 3U) >= 2U) {
zero<2>(d);
d += 2;
}
if ((L & 1U) != 0U) {
zero<1>(d);
}
}
static ZT_INLINE void zero(void *const dest,const unsigned int len) noexcept
{
memset(dest,0,len);
}
} // namespace Utils
} // namespace ZeroTier

View file

@ -275,7 +275,7 @@ void VL1::onRemotePacket(void *const tPtr,const int64_t localSocket,const InetAd
// Simultaneously decrypt and assemble packet into a contiguous buffer.
// Since we moved data around above all slices will have sizes that are
// multiples of 64.
memcpy(pkt.b->unsafeData,ph,sizeof(Protocol::Header));
Utils::copy<sizeof(Protocol::Header)>(pkt.b->unsafeData,ph);
pkt.e = sizeof(Protocol::Header);
for(FCV<Buf::Slice,ZT_MAX_PACKET_FRAGMENTS>::iterator s(pktv.begin());s!=pktv.end();++s) {
const unsigned int sliceSize = s->e - s->s;
@ -508,7 +508,7 @@ bool VL1::_HELLO(void *tPtr,const SharedPtr<Path> &path,SharedPtr<Peer> &peer,Bu
uint8_t key[ZT_PEER_SECRET_KEY_LENGTH];
if ((peer) && (id == peer->identity())) {
memcpy(key,peer->key(),ZT_PEER_SECRET_KEY_LENGTH);
Utils::copy<ZT_PEER_SECRET_KEY_LENGTH>(key,peer->key());
} else {
peer.zero();
if (!RR->identity.agree(id,key)) {