Build fixes.

This commit is contained in:
Adam Ierymenko 2020-05-18 09:44:23 -07:00
parent 996589894d
commit d537428421
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
20 changed files with 575 additions and 436 deletions

View file

@ -57,8 +57,8 @@ else(WIN32)
-Wall -Wall
-Wno-deprecated -Wno-deprecated
-Wno-unused-function -Wno-unused-function
-mmacosx-version-min=10.9 -mmacosx-version-min=10.12
$<$<CONFIG:Debug>:-g> $<$<CONFIG:DEBUG>:-g>
$<$<CONFIG:DEBUG>:-O0> $<$<CONFIG:DEBUG>:-O0>
$<$<CONFIG:RELEASE>:-Ofast> $<$<CONFIG:RELEASE>:-Ofast>
$<$<CONFIG:RELEASE>:-ffast-math> $<$<CONFIG:RELEASE>:-ffast-math>
@ -79,7 +79,7 @@ else(WIN32)
-Wno-deprecated -Wno-deprecated
-Wno-unused-function -Wno-unused-function
-Wno-format -Wno-format
$<$<CONFIG:Debug>:-g> $<$<CONFIG:DEBUG>:-g>
$<$<CONFIG:DEBUG>:-O0> $<$<CONFIG:DEBUG>:-O0>
$<$<CONFIG:RELEASE>:-O3> $<$<CONFIG:RELEASE>:-O3>
$<$<CONFIG:RELEASE>:-ffast-math> $<$<CONFIG:RELEASE>:-ffast-math>

View file

@ -14,9 +14,6 @@
#include "MIMC52.hpp" #include "MIMC52.hpp"
#include "SHA512.hpp" #include "SHA512.hpp"
#include "Utils.hpp" #include "Utils.hpp"
#include "Speck128.hpp"
#include <cstdio>
// This gets defined on any architecture whose FPU is not capable of doing the mulmod52() FPU trick. // This gets defined on any architecture whose FPU is not capable of doing the mulmod52() FPU trick.
//#define ZT_MIMC52_NO_FPU //#define ZT_MIMC52_NO_FPU
@ -114,7 +111,7 @@ uint64_t mimc52Delay(const void *const salt,const unsigned int saltSize,const un
uint64_t x = Utils::swapBytes(hash[1]) % p; uint64_t x = Utils::swapBytes(hash[1]) % p;
#endif #endif
Speck128<8> roundConstantGenerator(hash + 2); //Speck128<8> roundConstantGenerator(hash + 2);
const uint64_t e = ((p * 2) - 1) / 3; const uint64_t e = ((p * 2) - 1) / 3;
const uint64_t m52 = 0xfffffffffffffULL; const uint64_t m52 = 0xfffffffffffffULL;
const uint64_t rmin1 = rounds - 1; const uint64_t rmin1 = rounds - 1;
@ -122,7 +119,7 @@ uint64_t mimc52Delay(const void *const salt,const unsigned int saltSize,const un
#pragma unroll 16 #pragma unroll 16
for(unsigned long r=0;r<rounds;++r) { for(unsigned long r=0;r<rounds;++r) {
uint64_t sx = sxx,sy = rmin1 - r; uint64_t sx = sxx,sy = rmin1 - r;
roundConstantGenerator.encryptXY(sx,sy); //roundConstantGenerator.encryptXY(sx,sy);
x = (x - sy) & m52; x = (x - sy) & m52;
x = modpow52(x,e,p); x = modpow52(x,e,p);
} }
@ -143,7 +140,7 @@ bool mimc52Verify(const void *const salt,const unsigned int saltSize,unsigned lo
uint64_t x = Utils::swapBytes(hash[1]) % p; uint64_t x = Utils::swapBytes(hash[1]) % p;
#endif #endif
Speck128<8> roundConstantGenerator(hash + 2); //Speck128<8> roundConstantGenerator(hash + 2);
const uint64_t m52 = 0xfffffffffffffULL; const uint64_t m52 = 0xfffffffffffffULL;
uint64_t y = proof & m52; uint64_t y = proof & m52;
const uint64_t sxx = hash[4]; const uint64_t sxx = hash[4];
@ -154,7 +151,7 @@ bool mimc52Verify(const void *const salt,const unsigned int saltSize,unsigned lo
#pragma unroll 16 #pragma unroll 16
for(unsigned long r=0;r<rounds;++r) { for(unsigned long r=0;r<rounds;++r) {
uint64_t sx = sxx,sy = r; uint64_t sx = sxx,sy = r;
roundConstantGenerator.encryptXY(sx,sy); //roundConstantGenerator.encryptXY(sx,sy);
#ifdef ZT_MIMC52_NO_FPU #ifdef ZT_MIMC52_NO_FPU
#ifdef x64_cubemod #ifdef x64_cubemod
x64_cubemod(y,p); x64_cubemod(y,p);

View file

@ -137,6 +137,8 @@ public:
template<typename V> template<typename V>
class Vector : public std::vector< V,Utils::Mallocator<V> > class Vector : public std::vector< V,Utils::Mallocator<V> >
{ {
public:
ZT_INLINE Vector() {}
}; };
template<typename V> template<typename V>

View file

@ -96,7 +96,8 @@ public:
ERR_OUT_OF_MEMORY ERR_OUT_OF_MEMORY
}; };
ZT_INLINE Defragmenter() {} // NOLINT(hicpp-use-equals-default,modernize-use-equals-default) ZT_INLINE Defragmenter()
{} // NOLINT(hicpp-use-equals-default,modernize-use-equals-default)
/** /**
* Process a fragment of a multi-part message * Process a fragment of a multi-part message
@ -298,7 +299,8 @@ private:
id(0), id(0),
lastUsed(0), lastUsed(0),
totalFragmentsExpected(0), totalFragmentsExpected(0),
fragmentsReceived(0) {} fragmentsReceived(0)
{}
ZT_INLINE p_E(const p_E &e) noexcept: ZT_INLINE p_E(const p_E &e) noexcept:
id(e.id), id(e.id),
@ -307,7 +309,8 @@ private:
fragmentsReceived(e.fragmentsReceived), fragmentsReceived(e.fragmentsReceived),
via(e.via), via(e.via),
message(e.message), message(e.message),
lock() {} lock()
{}
ZT_INLINE ~p_E() ZT_INLINE ~p_E()
{ {

View file

@ -16,7 +16,6 @@
#include "SHA512.hpp" #include "SHA512.hpp"
#include "Salsa20.hpp" #include "Salsa20.hpp"
#include "Utils.hpp" #include "Utils.hpp"
#include "AES.hpp"
#include <algorithm> #include <algorithm>
@ -26,6 +25,7 @@ namespace {
// This is the memory-intensive hash function used to compute v0 identities from v0 public keys. // This is the memory-intensive hash function used to compute v0 identities from v0 public keys.
#define ZT_V0_IDENTITY_GEN_MEMORY 2097152 #define ZT_V0_IDENTITY_GEN_MEMORY 2097152
void identityV0ProofOfWorkFrankenhash(const void *const publicKey, unsigned int publicKeyBytes, void *const digest, void *const genmem) noexcept void identityV0ProofOfWorkFrankenhash(const void *const publicKey, unsigned int publicKeyBytes, void *const digest, void *const genmem) noexcept
{ {
// Digest publicKey[] to obtain initial digest // Digest publicKey[] to obtain initial digest
@ -60,68 +60,67 @@ void identityV0ProofOfWorkFrankenhash(const void *const publicKey,unsigned int p
s20.crypt20(digest, digest, 64); s20.crypt20(digest, digest, 64);
} }
} }
struct identityV0ProofOfWorkCriteria struct identityV0ProofOfWorkCriteria
{ {
ZT_INLINE identityV0ProofOfWorkCriteria(unsigned char *sb,char *gm) noexcept : digest(sb),genmem(gm) {} ZT_INLINE identityV0ProofOfWorkCriteria(unsigned char *sb, char *gm) noexcept: digest(sb), genmem(gm)
{}
ZT_INLINE bool operator()(const uint8_t pub[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE]) const noexcept ZT_INLINE bool operator()(const uint8_t pub[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE]) const noexcept
{ {
identityV0ProofOfWorkFrankenhash(pub, ZT_C25519_COMBINED_PUBLIC_KEY_SIZE, digest, genmem); identityV0ProofOfWorkFrankenhash(pub, ZT_C25519_COMBINED_PUBLIC_KEY_SIZE, digest, genmem);
return (digest[0] < 17); return (digest[0] < 17);
} }
unsigned char *digest; unsigned char *digest;
char *genmem; char *genmem;
}; };
#define ZT_IDENTITY_V1_POW_MEMORY_SIZE 131072
// This is a simpler memory-intensive hash function for V1 identity generation. // This is a simpler memory-intensive hash function for V1 identity generation.
// It's not quite as heavy as the V0 frankenhash, is a little more orderly in // It's not quite as heavy as the V0 frankenhash, is a little more orderly in
// its design, but remains relatively resistant to GPU acceleration due to memory // its design, but remains relatively resistant to GPU acceleration due to memory
// requirements for efficient computation. // requirements for efficient computation.
#define ZT_IDENTITY_V1_POW_MEMORY_SIZE 262144
#define ZT_IDENTITY_V1_POW_MEMORY_SIZE_U64 32768
bool identityV1ProofOfWorkCriteria(const void *in, const unsigned int len) bool identityV1ProofOfWorkCriteria(const void *in, const unsigned int len)
{ {
uint64_t b[ZT_IDENTITY_V1_POW_MEMORY_SIZE_U64]; uint64_t b[ZT_IDENTITY_V1_POW_MEMORY_SIZE / 8];
SHA512(b,in,len); SHA384(b, in, len);
AES c(b); Utils::zero<ZT_IDENTITY_V1_POW_MEMORY_SIZE - 48>(b + 6);
for(unsigned int i=8;i<ZT_IDENTITY_V1_POW_MEMORY_SIZE_U64;i+=8) { Salsa20(b,b + 4).crypt12(b,b,ZT_IDENTITY_V1_POW_MEMORY_SIZE);
SHA512(b + i,b + (i - 8),64);
if (unlikely((b[i] % 31ULL) == (b[i - 1] >> 59U)))
c.encrypt(b + i,b + i);
}
#if __BYTE_ORDER == __BIG_ENDIAN #if __BYTE_ORDER == __BIG_ENDIAN
for(unsigned int i=0;i<ZT_IDENTITY_V1_POW_MEMORY_SIZE_U64;i+=4) { for (unsigned int i=0;i<(ZT_IDENTITY_V1_POW_MEMORY_SIZE / 8);) {
const unsigned int i1 = i + 1;
const unsigned int i2 = i + 2;
const unsigned int i3 = i + 3;
b[i] = Utils::swapBytes(b[i]); b[i] = Utils::swapBytes(b[i]);
b[i + 1] = Utils::swapBytes(b[i + 1]); i += 4;
b[i + 2] = Utils::swapBytes(b[i + 2]); b[i1] = Utils::swapBytes(b[i1]);
b[i + 3] = Utils::swapBytes(b[i + 3]); b[i2] = Utils::swapBytes(b[i2]);
} b[i3] = Utils::swapBytes(b[i3]);
#endif }
std::sort(b,b + ZT_IDENTITY_V1_POW_MEMORY_SIZE_U64); #endif
#if __BYTE_ORDER == __BIG_ENDIAN
for(unsigned int i=0;i<ZT_IDENTITY_V1_POW_MEMORY_SIZE_U64;i+=4) { std::sort(b,b + (ZT_IDENTITY_V1_POW_MEMORY_SIZE / 8));
b[i] = Utils::swapBytes(b[i]);
b[i + 1] = Utils::swapBytes(b[i + 1]); #if __BYTE_ORDER == __BIG_ENDIAN
b[i + 2] = Utils::swapBytes(b[i + 2]); for (unsigned int i=0;i<(ZT_IDENTITY_V1_POW_MEMORY_SIZE / 8);) {
b[i + 3] = Utils::swapBytes(b[i + 3]); const unsigned int i1 = i + 1;
const unsigned int i2 = i + 2;
const unsigned int i3 = i + 3;
b[i] = Utils::swapBytes(b[i]);
i += 4;
b[i1] = Utils::swapBytes(b[i1]);
b[i2] = Utils::swapBytes(b[i2]);
b[i3] = Utils::swapBytes(b[i3]);
} }
#endif #endif
// Hash resulting sorted array to get final result for PoW criteria test.
// We also include the original input after so that cryptographically this
// is exactly like SHA384(in). This should make any FIPS types happy as
// this means the identity hash is SHA384 and not some weird construction.
SHA384(b, b, ZT_IDENTITY_V1_POW_MEMORY_SIZE, in, len); SHA384(b, b, ZT_IDENTITY_V1_POW_MEMORY_SIZE, in, len);
// PoW passes if sum of first two 64-bit integers (treated as little-endian) mod 180 is 0. return (b[0] % 1093U) == 0;
// This value was picked to yield about 1-2s total on typical desktop and server cores in 2020.
#if __BYTE_ORDER == __BIG_ENDIAN
const uint64_t finalHash = Utils::swapBytes(b[0]) + Utils::swapBytes(b[1]);
#else
const uint64_t finalHash = b[0] + b[1];
#endif
return (finalHash % 180U) == 0;
} }
} // anonymous namespace } // anonymous namespace

View file

@ -31,9 +31,12 @@ InetAddress::IpScope InetAddress::ipScope() const noexcept
case AF_INET: { case AF_INET: {
const uint32_t ip = Utils::ntoh((uint32_t)as.sa_in.sin_addr.s_addr); const uint32_t ip = Utils::ntoh((uint32_t)as.sa_in.sin_addr.s_addr);
switch (ip >> 24U) { switch (ip >> 24U) {
case 0x00: return IP_SCOPE_NONE; // 0.0.0.0/8 (reserved, never used) case 0x00:
case 0x06: return IP_SCOPE_PSEUDOPRIVATE; // 6.0.0.0/8 (US Army) return IP_SCOPE_NONE; // 0.0.0.0/8 (reserved, never used)
case 0x0a: return IP_SCOPE_PRIVATE; // 10.0.0.0/8 case 0x06:
return IP_SCOPE_PSEUDOPRIVATE; // 6.0.0.0/8 (US Army)
case 0x0a:
return IP_SCOPE_PRIVATE; // 10.0.0.0/8
case 0x0b: //return IP_SCOPE_PSEUDOPRIVATE; // 11.0.0.0/8 (US DoD) case 0x0b: //return IP_SCOPE_PSEUDOPRIVATE; // 11.0.0.0/8 (US DoD)
case 0x15: //return IP_SCOPE_PSEUDOPRIVATE; // 21.0.0.0/8 (US DDN-RVN) case 0x15: //return IP_SCOPE_PSEUDOPRIVATE; // 21.0.0.0/8 (US DDN-RVN)
case 0x16: //return IP_SCOPE_PSEUDOPRIVATE; // 22.0.0.0/8 (US DISA) case 0x16: //return IP_SCOPE_PSEUDOPRIVATE; // 22.0.0.0/8 (US DISA)
@ -44,11 +47,13 @@ InetAddress::IpScope InetAddress::ipScope() const noexcept
case 0x1e: //return IP_SCOPE_PSEUDOPRIVATE; // 30.0.0.0/8 (US DISA) case 0x1e: //return IP_SCOPE_PSEUDOPRIVATE; // 30.0.0.0/8 (US DISA)
case 0x33: //return IP_SCOPE_PSEUDOPRIVATE; // 51.0.0.0/8 (UK Department of Social Security) case 0x33: //return IP_SCOPE_PSEUDOPRIVATE; // 51.0.0.0/8 (UK Department of Social Security)
case 0x37: //return IP_SCOPE_PSEUDOPRIVATE; // 55.0.0.0/8 (US DoD) case 0x37: //return IP_SCOPE_PSEUDOPRIVATE; // 55.0.0.0/8 (US DoD)
case 0x38: return IP_SCOPE_PSEUDOPRIVATE; // 56.0.0.0/8 (US Postal Service) case 0x38:
return IP_SCOPE_PSEUDOPRIVATE; // 56.0.0.0/8 (US Postal Service)
case 0x64: case 0x64:
if ((ip & 0xffc00000) == 0x64400000) return IP_SCOPE_PRIVATE; // 100.64.0.0/10 if ((ip & 0xffc00000) == 0x64400000) return IP_SCOPE_PRIVATE; // 100.64.0.0/10
break; break;
case 0x7f: return IP_SCOPE_LOOPBACK; // 127.0.0.0/8 case 0x7f:
return IP_SCOPE_LOOPBACK; // 127.0.0.0/8
case 0xa9: case 0xa9:
if ((ip & 0xffff0000) == 0xa9fe0000) return IP_SCOPE_LINK_LOCAL; // 169.254.0.0/16 if ((ip & 0xffff0000) == 0xa9fe0000) return IP_SCOPE_LINK_LOCAL; // 169.254.0.0/16
break; break;
@ -58,11 +63,14 @@ InetAddress::IpScope InetAddress::ipScope() const noexcept
case 0xc0: case 0xc0:
if ((ip & 0xffff0000) == 0xc0a80000) return IP_SCOPE_PRIVATE; // 192.168.0.0/16 if ((ip & 0xffff0000) == 0xc0a80000) return IP_SCOPE_PRIVATE; // 192.168.0.0/16
break; break;
case 0xff: return IP_SCOPE_NONE; // 255.0.0.0/8 (broadcast, or unused/unusable) case 0xff:
return IP_SCOPE_NONE; // 255.0.0.0/8 (broadcast, or unused/unusable)
} }
switch (ip >> 28U) { switch (ip >> 28U) {
case 0xe: return IP_SCOPE_MULTICAST; // 224.0.0.0/4 case 0xe:
case 0xf: return IP_SCOPE_PSEUDOPRIVATE; // 240.0.0.0/4 ("reserved," usually unusable) return IP_SCOPE_MULTICAST; // 224.0.0.0/4
case 0xf:
return IP_SCOPE_PSEUDOPRIVATE; // 240.0.0.0/4 ("reserved," usually unusable)
} }
return IP_SCOPE_GLOBAL; return IP_SCOPE_GLOBAL;
} }
@ -141,8 +149,12 @@ char *InetAddress::toIpString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const no
{ {
buf[0] = (char) 0; buf[0] = (char) 0;
switch (as.ss.ss_family) { switch (as.ss.ss_family) {
case AF_INET: inet_ntop(AF_INET,&as.sa_in.sin_addr.s_addr,buf,INET_ADDRSTRLEN); break; case AF_INET:
case AF_INET6: inet_ntop(AF_INET6,as.sa_in6.sin6_addr.s6_addr,buf,INET6_ADDRSTRLEN); break; inet_ntop(AF_INET, &as.sa_in.sin_addr.s_addr, buf, INET_ADDRSTRLEN);
break;
case AF_INET6:
inet_ntop(AF_INET6, as.sa_in6.sin6_addr.s6_addr, buf, INET6_ADDRSTRLEN);
break;
} }
return buf; return buf;
} }
@ -200,7 +212,8 @@ InetAddress InetAddress::netmask() const noexcept
nm[1] = 0; nm[1] = 0;
} }
Utils::copy<16>(r.as.sa_in6.sin6_addr.s6_addr, nm); Utils::copy<16>(r.as.sa_in6.sin6_addr.s6_addr, nm);
} break; }
break;
} }
return r; return r;
} }
@ -229,7 +242,8 @@ InetAddress InetAddress::network() const noexcept
nm[0] &= Utils::hton((uint64_t) ((bits >= 64) ? 0xffffffffffffffffULL : (0xffffffffffffffffULL << (64 - bits)))); nm[0] &= Utils::hton((uint64_t) ((bits >= 64) ? 0xffffffffffffffffULL : (0xffffffffffffffffULL << (64 - bits))));
nm[1] &= Utils::hton((uint64_t) ((bits <= 64) ? 0ULL : (0xffffffffffffffffULL << (128 - bits)))); nm[1] &= Utils::hton((uint64_t) ((bits <= 64) ? 0ULL : (0xffffffffffffffffULL << (128 - bits))));
Utils::copy<16>(r.as.sa_in6.sin6_addr.s6_addr, nm); Utils::copy<16>(r.as.sa_in6.sin6_addr.s6_addr, nm);
} break; }
break;
} }
return r; return r;
} }

View file

@ -71,28 +71,54 @@ public:
}; };
// Hasher for unordered sets and maps in C++11 // Hasher for unordered sets and maps in C++11
struct Hasher { ZT_INLINE std::size_t operator()(const InetAddress &a) const noexcept { return (std::size_t)a.hashCode(); } }; struct Hasher
{
ZT_INLINE std::size_t operator()(const InetAddress &a) const noexcept
{ return (std::size_t) a.hashCode(); }
};
ZT_INLINE InetAddress() noexcept { memoryZero(this); } ZT_INLINE InetAddress() noexcept
{ memoryZero(this); }
explicit ZT_INLINE InetAddress(const sockaddr_storage &ss) noexcept { *this = ss; } explicit ZT_INLINE InetAddress(const sockaddr_storage &ss) noexcept
explicit ZT_INLINE InetAddress(const sockaddr_storage *const ss) noexcept { *this = ss; } { *this = ss; }
explicit ZT_INLINE InetAddress(const sockaddr &sa) noexcept { *this = sa; }
explicit ZT_INLINE InetAddress(const sockaddr *const sa) noexcept { *this = sa; }
explicit ZT_INLINE InetAddress(const sockaddr_in &sa) noexcept { *this = sa; }
explicit ZT_INLINE InetAddress(const sockaddr_in *const sa) noexcept { *this = sa; }
explicit ZT_INLINE InetAddress(const sockaddr_in6 &sa) noexcept { *this = sa; }
explicit ZT_INLINE InetAddress(const sockaddr_in6 *const sa) noexcept { *this = sa; }
ZT_INLINE InetAddress(const void *const ipBytes,const unsigned int ipLen,const unsigned int port) noexcept { this->set(ipBytes,ipLen,port); } explicit ZT_INLINE InetAddress(const sockaddr_storage *const ss) noexcept
ZT_INLINE InetAddress(const uint32_t ipv4,const unsigned int port) noexcept { this->set(&ipv4,4,port); } { *this = ss; }
explicit ZT_INLINE InetAddress(const char *const ipSlashPort) noexcept { this->fromString(ipSlashPort); }
explicit ZT_INLINE InetAddress(const sockaddr &sa) noexcept
{ *this = sa; }
explicit ZT_INLINE InetAddress(const sockaddr *const sa) noexcept
{ *this = sa; }
explicit ZT_INLINE InetAddress(const sockaddr_in &sa) noexcept
{ *this = sa; }
explicit ZT_INLINE InetAddress(const sockaddr_in *const sa) noexcept
{ *this = sa; }
explicit ZT_INLINE InetAddress(const sockaddr_in6 &sa) noexcept
{ *this = sa; }
explicit ZT_INLINE InetAddress(const sockaddr_in6 *const sa) noexcept
{ *this = sa; }
ZT_INLINE InetAddress(const void *const ipBytes, const unsigned int ipLen, const unsigned int port) noexcept
{ this->set(ipBytes, ipLen, port); }
ZT_INLINE InetAddress(const uint32_t ipv4, const unsigned int port) noexcept
{ this->set(&ipv4, 4, port); }
explicit ZT_INLINE InetAddress(const char *const ipSlashPort) noexcept
{ this->fromString(ipSlashPort); }
ZT_INLINE InetAddress &operator=(const sockaddr_storage &ss) noexcept ZT_INLINE InetAddress &operator=(const sockaddr_storage &ss) noexcept
{ {
as.ss = ss; as.ss = ss;
return *this; return *this;
} }
ZT_INLINE InetAddress &operator=(const sockaddr_storage *ss) noexcept ZT_INLINE InetAddress &operator=(const sockaddr_storage *ss) noexcept
{ {
if (ss) if (ss)
@ -100,11 +126,13 @@ public:
else memoryZero(this); else memoryZero(this);
return *this; return *this;
} }
ZT_INLINE InetAddress &operator=(const sockaddr_in &sa) noexcept ZT_INLINE InetAddress &operator=(const sockaddr_in &sa) noexcept
{ {
as.sa_in = sa; as.sa_in = sa;
return *this; return *this;
} }
ZT_INLINE InetAddress &operator=(const sockaddr_in *sa) noexcept ZT_INLINE InetAddress &operator=(const sockaddr_in *sa) noexcept
{ {
if (sa) if (sa)
@ -112,11 +140,13 @@ public:
else memoryZero(this); else memoryZero(this);
return *this; return *this;
} }
ZT_INLINE InetAddress &operator=(const sockaddr_in6 &sa) noexcept ZT_INLINE InetAddress &operator=(const sockaddr_in6 &sa) noexcept
{ {
as.sa_in6 = sa; as.sa_in6 = sa;
return *this; return *this;
} }
ZT_INLINE InetAddress &operator=(const sockaddr_in6 *sa) noexcept ZT_INLINE InetAddress &operator=(const sockaddr_in6 *sa) noexcept
{ {
if (sa) if (sa)
@ -124,6 +154,7 @@ public:
else memoryZero(this); else memoryZero(this);
return *this; return *this;
} }
ZT_INLINE InetAddress &operator=(const sockaddr &sa) noexcept ZT_INLINE InetAddress &operator=(const sockaddr &sa) noexcept
{ {
if (sa.sa_family == AF_INET) if (sa.sa_family == AF_INET)
@ -133,6 +164,7 @@ public:
else memoryZero(this); else memoryZero(this);
return *this; return *this;
} }
ZT_INLINE InetAddress &operator=(const sockaddr *sa) noexcept ZT_INLINE InetAddress &operator=(const sockaddr *sa) noexcept
{ {
if (sa) { if (sa) {
@ -147,12 +179,14 @@ public:
return *this; return *this;
} }
ZT_INLINE void clear() noexcept { memoryZero(this); } ZT_INLINE void clear() noexcept
{ memoryZero(this); }
/** /**
* @return Address family (ss_family in sockaddr_storage) * @return Address family (ss_family in sockaddr_storage)
*/ */
ZT_INLINE uint8_t family() const noexcept { return as.ss.ss_family; } ZT_INLINE uint8_t family() const noexcept
{ return as.ss.ss_family; }
/** /**
* @return IP scope classification (e.g. loopback, link-local, private, global) * @return IP scope classification (e.g. loopback, link-local, private, global)
@ -176,8 +210,12 @@ public:
ZT_INLINE void setPort(unsigned int port) noexcept ZT_INLINE void setPort(unsigned int port) noexcept
{ {
switch (as.ss.ss_family) { switch (as.ss.ss_family) {
case AF_INET: as.sa_in.sin_port = Utils::hton((uint16_t)port); break; case AF_INET:
case AF_INET6: as.sa_in6.sin6_port = Utils::hton((uint16_t)port); break; as.sa_in.sin_port = Utils::hton((uint16_t) port);
break;
case AF_INET6:
as.sa_in6.sin6_port = Utils::hton((uint16_t) port);
break;
} }
} }
@ -190,13 +228,25 @@ public:
* @return ASCII IP/port format representation * @return ASCII IP/port format representation
*/ */
char *toString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noexcept; char *toString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noexcept;
ZT_INLINE String toString() const { char buf[ZT_INETADDRESS_STRING_SIZE_MAX]; toString(buf); return String(buf); }
ZT_INLINE String toString() const
{
char buf[ZT_INETADDRESS_STRING_SIZE_MAX];
toString(buf);
return String(buf);
}
/** /**
* @return IP portion only, in ASCII string format * @return IP portion only, in ASCII string format
*/ */
char *toIpString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noexcept; char *toIpString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noexcept;
ZT_INLINE String toIpString() const { char buf[ZT_INETADDRESS_STRING_SIZE_MAX]; toIpString(buf); return String(buf); }
ZT_INLINE String toIpString() const
{
char buf[ZT_INETADDRESS_STRING_SIZE_MAX];
toIpString(buf);
return String(buf);
}
/** /**
* @param ipSlashPort IP/port (port is optional, will be 0 if not included) * @param ipSlashPort IP/port (port is optional, will be 0 if not included)
@ -210,9 +260,12 @@ public:
ZT_INLINE unsigned int port() const noexcept ZT_INLINE unsigned int port() const noexcept
{ {
switch (as.ss.ss_family) { switch (as.ss.ss_family) {
case AF_INET: return Utils::ntoh((uint16_t)as.sa_in.sin_port); case AF_INET:
case AF_INET6: return Utils::ntoh((uint16_t)as.sa_in6.sin6_port); return Utils::ntoh((uint16_t) as.sa_in.sin_port);
default: return 0; case AF_INET6:
return Utils::ntoh((uint16_t) as.sa_in6.sin6_port);
default:
return 0;
} }
} }
@ -225,7 +278,8 @@ public:
* *
* @return Netmask bits * @return Netmask bits
*/ */
ZT_INLINE unsigned int netmaskBits() const noexcept { return port(); } ZT_INLINE unsigned int netmaskBits() const noexcept
{ return port(); }
/** /**
* @return True if netmask bits is valid for the address type * @return True if netmask bits is valid for the address type
@ -234,8 +288,10 @@ public:
{ {
const unsigned int n = port(); const unsigned int n = port();
switch (as.ss.ss_family) { switch (as.ss.ss_family) {
case AF_INET: return (n <= 32); case AF_INET:
case AF_INET6: return (n <= 128); return (n <= 32);
case AF_INET6:
return (n <= 128);
} }
return false; return false;
} }
@ -248,7 +304,8 @@ public:
* *
* @return Gateway metric * @return Gateway metric
*/ */
ZT_INLINE unsigned int metric() const noexcept { return port(); } ZT_INLINE unsigned int metric() const noexcept
{ return port(); }
/** /**
* Construct a full netmask as an InetAddress * Construct a full netmask as an InetAddress
@ -293,12 +350,14 @@ public:
/** /**
* @return True if this is an IPv4 address * @return True if this is an IPv4 address
*/ */
ZT_INLINE bool isV4() const noexcept { return (as.ss.ss_family == AF_INET); } ZT_INLINE bool isV4() const noexcept
{ return (as.ss.ss_family == AF_INET); }
/** /**
* @return True if this is an IPv6 address * @return True if this is an IPv6 address
*/ */
ZT_INLINE bool isV6() const noexcept { return (as.ss.ss_family == AF_INET6); } ZT_INLINE bool isV6() const noexcept
{ return (as.ss.ss_family == AF_INET6); }
/** /**
* @return pointer to raw address bytes or NULL if not available * @return pointer to raw address bytes or NULL if not available
@ -306,9 +365,12 @@ public:
ZT_INLINE const void *rawIpData() const noexcept ZT_INLINE const void *rawIpData() const noexcept
{ {
switch (as.ss.ss_family) { switch (as.ss.ss_family) {
case AF_INET: return reinterpret_cast<const void *>(&(as.sa_in.sin_addr.s_addr)); case AF_INET:
case AF_INET6: return reinterpret_cast<const void *>(as.sa_in6.sin6_addr.s6_addr); return reinterpret_cast<const void *>(&(as.sa_in.sin_addr.s_addr));
default: return nullptr; case AF_INET6:
return reinterpret_cast<const void *>(as.sa_in6.sin6_addr.s6_addr);
default:
return nullptr;
} }
} }
@ -398,10 +460,14 @@ public:
/** /**
* @return True if address family is non-zero * @return True if address family is non-zero
*/ */
explicit ZT_INLINE operator bool() const noexcept { return (as.ss.ss_family != 0); } explicit ZT_INLINE operator bool() const noexcept
{ return (as.ss.ss_family != 0); }
static constexpr int marshalSizeMax() noexcept
{ return ZT_INETADDRESS_MARSHAL_SIZE_MAX; }
static constexpr int marshalSizeMax() noexcept { return ZT_INETADDRESS_MARSHAL_SIZE_MAX; }
int marshal(uint8_t data[ZT_INETADDRESS_MARSHAL_SIZE_MAX]) const noexcept; int marshal(uint8_t data[ZT_INETADDRESS_MARSHAL_SIZE_MAX]) const noexcept;
int unmarshal(const uint8_t *restrict data, int len) noexcept; int unmarshal(const uint8_t *restrict data, int len) noexcept;
ZT_INLINE bool operator==(const InetAddress &a) const noexcept ZT_INLINE bool operator==(const InetAddress &a) const noexcept
@ -415,6 +481,7 @@ public:
} }
return false; return false;
} }
ZT_INLINE bool operator<(const InetAddress &a) const noexcept ZT_INLINE bool operator<(const InetAddress &a) const noexcept
{ {
if (as.ss.ss_family == a.as.ss.ss_family) { if (as.ss.ss_family == a.as.ss.ss_family) {
@ -436,10 +503,18 @@ public:
} }
return as.ss.ss_family < a.as.ss.ss_family; return as.ss.ss_family < a.as.ss.ss_family;
} }
ZT_INLINE bool operator!=(const InetAddress &a) const noexcept { return !(*this == a); }
ZT_INLINE bool operator>(const InetAddress &a) const noexcept { return (a < *this); } ZT_INLINE bool operator!=(const InetAddress &a) const noexcept
ZT_INLINE bool operator<=(const InetAddress &a) const noexcept { return !(a < *this); } { return !(*this == a); }
ZT_INLINE bool operator>=(const InetAddress &a) const noexcept { return !(*this < a); }
ZT_INLINE bool operator>(const InetAddress &a) const noexcept
{ return (a < *this); }
ZT_INLINE bool operator<=(const InetAddress &a) const noexcept
{ return !(a < *this); }
ZT_INLINE bool operator>=(const InetAddress &a) const noexcept
{ return !(*this < a); }
/** /**
* Compute an IPv6 link-local address * Compute an IPv6 link-local address
@ -500,7 +575,8 @@ public:
/** /**
* Union allowing this to be accessed as a sockaddr of any supported type. * Union allowing this to be accessed as a sockaddr of any supported type.
*/ */
union { union
{
sockaddr_storage ss; sockaddr_storage ss;
sockaddr sa; sockaddr sa;
sockaddr_in sa_in; sockaddr_in sa_in;
@ -508,22 +584,53 @@ public:
} as; } as;
}; };
static ZT_INLINE InetAddress *asInetAddress(sockaddr_in *const p) noexcept { return reinterpret_cast<InetAddress *>(p); } static ZT_INLINE InetAddress *asInetAddress(sockaddr_in *const p) noexcept
static ZT_INLINE InetAddress *asInetAddress(sockaddr_in6 *const p) noexcept { return reinterpret_cast<InetAddress *>(p); } { return reinterpret_cast<InetAddress *>(p); }
static ZT_INLINE InetAddress *asInetAddress(sockaddr *const p) noexcept { return reinterpret_cast<InetAddress *>(p); }
static ZT_INLINE InetAddress *asInetAddress(sockaddr_storage *const p) noexcept { return reinterpret_cast<InetAddress *>(p); } static ZT_INLINE InetAddress *asInetAddress(sockaddr_in6 *const p) noexcept
static ZT_INLINE const InetAddress *asInetAddress(const sockaddr_in *const p) noexcept { return reinterpret_cast<const InetAddress *>(p); } { return reinterpret_cast<InetAddress *>(p); }
static ZT_INLINE const InetAddress *asInetAddress(const sockaddr_in6 *const p) noexcept { return reinterpret_cast<const InetAddress *>(p); }
static ZT_INLINE const InetAddress *asInetAddress(const sockaddr *const p) noexcept { return reinterpret_cast<const InetAddress *>(p); } static ZT_INLINE InetAddress *asInetAddress(sockaddr *const p) noexcept
static ZT_INLINE const InetAddress *asInetAddress(const sockaddr_storage *const p) noexcept { return reinterpret_cast<const InetAddress *>(p); } { return reinterpret_cast<InetAddress *>(p); }
static ZT_INLINE InetAddress &asInetAddress(sockaddr_in &p) noexcept { return *reinterpret_cast<InetAddress *>(&p); }
static ZT_INLINE InetAddress &asInetAddress(sockaddr_in6 &p) noexcept { return *reinterpret_cast<InetAddress *>(&p); } static ZT_INLINE InetAddress *asInetAddress(sockaddr_storage *const p) noexcept
static ZT_INLINE InetAddress &asInetAddress(sockaddr &p) noexcept { return *reinterpret_cast<InetAddress *>(&p); } { return reinterpret_cast<InetAddress *>(p); }
static ZT_INLINE InetAddress &asInetAddress(sockaddr_storage &p) noexcept { return *reinterpret_cast<InetAddress *>(&p); }
static ZT_INLINE const InetAddress &asInetAddress(const sockaddr_in &p) noexcept { return *reinterpret_cast<const InetAddress *>(&p); } static ZT_INLINE const InetAddress *asInetAddress(const sockaddr_in *const p) noexcept
static ZT_INLINE const InetAddress &asInetAddress(const sockaddr_in6 &p) noexcept { return *reinterpret_cast<const InetAddress *>(&p); } { return reinterpret_cast<const InetAddress *>(p); }
static ZT_INLINE const InetAddress &asInetAddress(const sockaddr &p) noexcept { return *reinterpret_cast<const InetAddress *>(&p); }
static ZT_INLINE const InetAddress &asInetAddress(const sockaddr_storage &p) noexcept { return *reinterpret_cast<const InetAddress *>(&p); } static ZT_INLINE const InetAddress *asInetAddress(const sockaddr_in6 *const p) noexcept
{ return reinterpret_cast<const InetAddress *>(p); }
static ZT_INLINE const InetAddress *asInetAddress(const sockaddr *const p) noexcept
{ return reinterpret_cast<const InetAddress *>(p); }
static ZT_INLINE const InetAddress *asInetAddress(const sockaddr_storage *const p) noexcept
{ return reinterpret_cast<const InetAddress *>(p); }
static ZT_INLINE InetAddress &asInetAddress(sockaddr_in &p) noexcept
{ return *reinterpret_cast<InetAddress *>(&p); }
static ZT_INLINE InetAddress &asInetAddress(sockaddr_in6 &p) noexcept
{ return *reinterpret_cast<InetAddress *>(&p); }
static ZT_INLINE InetAddress &asInetAddress(sockaddr &p) noexcept
{ return *reinterpret_cast<InetAddress *>(&p); }
static ZT_INLINE InetAddress &asInetAddress(sockaddr_storage &p) noexcept
{ return *reinterpret_cast<InetAddress *>(&p); }
static ZT_INLINE const InetAddress &asInetAddress(const sockaddr_in &p) noexcept
{ return *reinterpret_cast<const InetAddress *>(&p); }
static ZT_INLINE const InetAddress &asInetAddress(const sockaddr_in6 &p) noexcept
{ return *reinterpret_cast<const InetAddress *>(&p); }
static ZT_INLINE const InetAddress &asInetAddress(const sockaddr &p) noexcept
{ return *reinterpret_cast<const InetAddress *>(&p); }
static ZT_INLINE const InetAddress &asInetAddress(const sockaddr_storage &p) noexcept
{ return *reinterpret_cast<const InetAddress *>(&p); }
} // namespace ZeroTier } // namespace ZeroTier

View file

@ -52,7 +52,7 @@ public:
/** /**
* @return True if locator is signed * @return True if locator is signed
*/ */
ZT_INLINE bool isSigned() const noexcept { return (m_signatureLength > 0); } ZT_INLINE bool isSigned() const noexcept { return m_signatureLength > 0; }
/** /**
* @return Length of signature in bytes or 0 if none * @return Length of signature in bytes or 0 if none
@ -110,7 +110,7 @@ public:
*/ */
bool verify(const Identity &id) const noexcept; bool verify(const Identity &id) const noexcept;
explicit ZT_INLINE operator bool() const noexcept { return (m_ts != 0); } explicit ZT_INLINE operator bool() const noexcept { return m_ts != 0; }
static constexpr int marshalSizeMax() noexcept { return ZT_LOCATOR_MARSHAL_SIZE_MAX; } static constexpr int marshalSizeMax() noexcept { return ZT_LOCATOR_MARSHAL_SIZE_MAX; }
int marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX],bool excludeSignature = false) const noexcept; int marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX],bool excludeSignature = false) const noexcept;

View file

@ -33,6 +33,7 @@ void Membership::pushCredentials(const RuntimeEnvironment *RR,void *tPtr,const i
if (!nconf.com) // sanity check if (!nconf.com) // sanity check
return; return;
#if 0
SharedPtr<Buf> outp(new Buf()); SharedPtr<Buf> outp(new Buf());
Protocol::Header &ph = outp->as<Protocol::Header>(); // NOLINT(hicpp-use-auto,modernize-use-auto) Protocol::Header &ph = outp->as<Protocol::Header>(); // NOLINT(hicpp-use-auto,modernize-use-auto)
@ -109,6 +110,7 @@ void Membership::pushCredentials(const RuntimeEnvironment *RR,void *tPtr,const i
// TODO // TODO
} }
} }
#endif
m_lastPushedCredentials = now; m_lastPushedCredentials = now;
} }

View file

@ -103,7 +103,7 @@ public:
template<typename T> template<typename T>
ZT_INLINE bool peerOwnsAddress(const NetworkConfig &nconf,const T &r) const noexcept ZT_INLINE bool peerOwnsAddress(const NetworkConfig &nconf,const T &r) const noexcept
{ {
if (s_isUnspoofableAddress(nconf, r)) if (m_isUnspoofableAddress(nconf, r))
return true; return true;
for(Map< uint32_t,CertificateOfOwnership >::const_iterator i(m_remoteCoos.begin());i != m_remoteCoos.end();++i) { for(Map< uint32_t,CertificateOfOwnership >::const_iterator i(m_remoteCoos.begin());i != m_remoteCoos.end();++i) {
if (m_isCredentialTimestampValid(nconf, i->second) && (i->second.owns(r))) if (m_isCredentialTimestampValid(nconf, i->second) && (i->second.owns(r)))
@ -158,7 +158,7 @@ private:
// This returns true if a resource is an IPv6 NDP-emulated address. These embed the ZT // This returns true if a resource is an IPv6 NDP-emulated address. These embed the ZT
// address of the peer and therefore cannot be spoofed, causing peerOwnsAddress() to // address of the peer and therefore cannot be spoofed, causing peerOwnsAddress() to
// always return true for them. A certificate is not required for these. // always return true for them. A certificate is not required for these.
ZT_INLINE static bool s_isUnspoofableAddress(const NetworkConfig &nconf, const MAC &m) noexcept { return false; } constexpr bool m_isUnspoofableAddress(const NetworkConfig &nconf, const MAC &m) const noexcept { return false; }
bool m_isUnspoofableAddress(const NetworkConfig &nconf, const InetAddress &ip) const noexcept; bool m_isUnspoofableAddress(const NetworkConfig &nconf, const InetAddress &ip) const noexcept;
// This compares the remote credential's timestamp to the timestamp in our network config // This compares the remote credential's timestamp to the timestamp in our network config

View file

@ -43,7 +43,8 @@ public:
* *
* @param now Start time * @param now Start time
*/ */
ZT_INLINE Meter() noexcept {} // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init,hicpp-use-equals-default,modernize-use-equals-default) ZT_INLINE Meter() noexcept
{} // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init,hicpp-use-equals-default,modernize-use-equals-default)
/** /**
* Add a measurement * Add a measurement

View file

@ -539,8 +539,8 @@ Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,const F
m_id(nwid), m_id(nwid),
m_mac(renv->identity.address(), nwid), m_mac(renv->identity.address(), nwid),
m_portInitialized(false), m_portInitialized(false),
m_lastConfigUpdate(0),
m_destroyed(false), m_destroyed(false),
m_lastConfigUpdate(0),
_netconfFailure(NETCONF_FAILURE_NONE) _netconfFailure(NETCONF_FAILURE_NONE)
{ {
if (controllerFingerprint) if (controllerFingerprint)
@ -556,7 +556,7 @@ Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,const F
bool got = false; bool got = false;
try { try {
Dictionary dict; Dictionary dict;
std::vector<uint8_t> nconfData(RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp)); Vector<uint8_t> nconfData(RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp));
if (nconfData.size() > 2) { if (nconfData.size() > 2) {
nconfData.push_back(0); nconfData.push_back(0);
if (dict.decode(nconfData.data(),(unsigned int)nconfData.size())) { if (dict.decode(nconfData.data(),(unsigned int)nconfData.size())) {
@ -864,7 +864,7 @@ void Network::multicastSubscribe(void *tPtr,const MulticastGroup &mg)
void Network::multicastUnsubscribe(const MulticastGroup &mg) void Network::multicastUnsubscribe(const MulticastGroup &mg)
{ {
Mutex::Lock l(m_myMulticastGroups_l); Mutex::Lock l(m_myMulticastGroups_l);
std::vector<MulticastGroup>::iterator i(std::lower_bound(m_myMulticastGroups.begin(), m_myMulticastGroups.end(), mg)); Vector<MulticastGroup>::iterator i(std::lower_bound(m_myMulticastGroups.begin(), m_myMulticastGroups.end(), mg));
if ((i != m_myMulticastGroups.end()) && (*i == mg) ) if ((i != m_myMulticastGroups.end()) && (*i == mg) )
m_myMulticastGroups.erase(i); m_myMulticastGroups.erase(i);
} }
@ -984,7 +984,7 @@ uint64_t Network::handleConfigChunk(void *tPtr,uint64_t packetId,const SharedPtr
c->chunks[chunkIndex].assign(chunkData,chunkData + chunkLen); c->chunks[chunkIndex].assign(chunkData,chunkData + chunkLen);
int haveLength = 0; int haveLength = 0;
for(std::map< int,std::vector<uint8_t> >::const_iterator ch(c->chunks.begin());ch!=c->chunks.end();++ch) for(std::map< int,Vector<uint8_t> >::const_iterator ch(c->chunks.begin());ch!=c->chunks.end();++ch)
haveLength += (int)ch->second.size(); haveLength += (int)ch->second.size();
if (haveLength > ZT_MAX_NETWORK_CONFIG_BYTES) { if (haveLength > ZT_MAX_NETWORK_CONFIG_BYTES) {
c->touchCtr = 0; c->touchCtr = 0;
@ -994,8 +994,8 @@ uint64_t Network::handleConfigChunk(void *tPtr,uint64_t packetId,const SharedPtr
} }
if (haveLength == totalLength) { if (haveLength == totalLength) {
std::vector<uint8_t> assembledConfig; Vector<uint8_t> assembledConfig;
for(std::map< int,std::vector<uint8_t> >::const_iterator ch(c->chunks.begin());ch!=c->chunks.end();++ch) for(std::map< int,Vector<uint8_t> >::const_iterator ch(c->chunks.begin());ch!=c->chunks.end();++ch)
assembledConfig.insert(assembledConfig.end(),ch->second.begin(),ch->second.end()); assembledConfig.insert(assembledConfig.end(),ch->second.begin(),ch->second.end());
Dictionary dict; Dictionary dict;
@ -1048,10 +1048,10 @@ int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToD
if (saveToDisk) { if (saveToDisk) {
try { try {
Dictionary d; Dictionary d;
if (nconf.toDictionary(d,false)) { if (nconf.toDictionary(d)) {
uint64_t tmp[2]; uint64_t tmp[2];
tmp[0] = m_id; tmp[1] = 0; tmp[0] = m_id; tmp[1] = 0;
std::vector<uint8_t> d2; Vector<uint8_t> d2;
d.encode(d2); d.encode(d2);
RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp,d2.data(),(unsigned int)d2.size()); RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp,d2.data(),(unsigned int)d2.size());
} }
@ -1445,7 +1445,7 @@ void Network::m_externalConfig(ZT_VirtualNetworkConfig *ec) const
ec->status = m_status(); ec->status = m_status();
ec->type = (m_config) ? (m_config.isPrivate() ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC) : ZT_NETWORK_TYPE_PRIVATE; ec->type = (m_config) ? (m_config.isPrivate() ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC) : ZT_NETWORK_TYPE_PRIVATE;
ec->mtu = (m_config) ? m_config.mtu : ZT_DEFAULT_MTU; ec->mtu = (m_config) ? m_config.mtu : ZT_DEFAULT_MTU;
std::vector<Address> ab; Vector<Address> ab;
for(unsigned int i=0;i < m_config.specialistCount;++i) { for(unsigned int i=0;i < m_config.specialistCount;++i) {
if ((m_config.specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE) != 0) if ((m_config.specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE) != 0)
ab.push_back(Address(m_config.specialists[i])); ab.push_back(Address(m_config.specialists[i]));
@ -1503,7 +1503,7 @@ void Network::m_announceMulticastGroupsTo(void *tPtr, const Address &peer, const
// Assumes _myMulticastGroups_l and _memberships_l are locked // Assumes _myMulticastGroups_l and _memberships_l are locked
ScopedPtr<Packet> outp(new Packet(peer,RR->identity.address(),Packet::VERB_MULTICAST_LIKE)); ScopedPtr<Packet> outp(new Packet(peer,RR->identity.address(),Packet::VERB_MULTICAST_LIKE));
for(std::vector<MulticastGroup>::const_iterator mg(allMulticastGroups.begin());mg!=allMulticastGroups.end();++mg) { for(Vector<MulticastGroup>::const_iterator mg(allMulticastGroups.begin());mg!=allMulticastGroups.end();++mg) {
if ((outp->size() + 24) >= ZT_PROTO_MAX_PACKET_LENGTH) { if ((outp->size() + 24) >= ZT_PROTO_MAX_PACKET_LENGTH) {
outp->compress(); outp->compress();
RR->sw->send(tPtr,*outp,true); RR->sw->send(tPtr,*outp,true);
@ -1529,7 +1529,7 @@ Vector<MulticastGroup> Network::m_allMulticastGroups() const
Vector<MulticastGroup> mgs; Vector<MulticastGroup> mgs;
mgs.reserve(m_myMulticastGroups.size() + m_multicastGroupsBehindMe.size() + 1); mgs.reserve(m_myMulticastGroups.size() + m_multicastGroupsBehindMe.size() + 1);
mgs.insert(mgs.end(), m_myMulticastGroups.begin(), m_myMulticastGroups.end()); mgs.insert(mgs.end(), m_myMulticastGroups.begin(), m_myMulticastGroups.end());
for(Map<MulticastGroup,uint64_t>::const_iterator i(m_multicastGroupsBehindMe.begin());i != m_multicastGroupsBehindMe.end();++i) for(Map<MulticastGroup,int64_t>::const_iterator i(m_multicastGroupsBehindMe.begin());i != m_multicastGroupsBehindMe.end();++i)
mgs.push_back(i->first); mgs.push_back(i->first);
if ((m_config) && (m_config.enableBroadcast())) if ((m_config) && (m_config.enableBroadcast()))
mgs.push_back(Network::BROADCAST); mgs.push_back(Network::BROADCAST);

View file

@ -31,13 +31,7 @@ namespace ZeroTier {
namespace { namespace {
/** // Structure containing all the core objects for a ZeroTier node to reduce memory allocations.
* All core objects of a ZeroTier node.
*
* This is just a box that allows us to allocate all core objects
* and data structures at once for a bit of memory saves and improved
* cache adjacency.
*/
struct _NodeObjects struct _NodeObjects
{ {
ZT_INLINE _NodeObjects(RuntimeEnvironment *const RR,void *const tPtr) : ZT_INLINE _NodeObjects(RuntimeEnvironment *const RR,void *const tPtr) :
@ -195,7 +189,7 @@ struct _processBackgroundTasks_eachPeer
Node *const parent; Node *const parent;
void *const tPtr; void *const tPtr;
bool online; bool online;
std::vector< SharedPtr<Peer> > rootsNotOnline; Vector< SharedPtr<Peer> > rootsNotOnline;
ZT_INLINE void operator()(const SharedPtr<Peer> &peer,const bool isRoot) noexcept ZT_INLINE void operator()(const SharedPtr<Peer> &peer,const bool isRoot) noexcept
{ {
peer->pulse(tPtr,now,isRoot); peer->pulse(tPtr,now,isRoot);
@ -226,7 +220,7 @@ ZT_ResultCode Node::processBackgroundTasks(void *tPtr,int64_t now,volatile int64
postEvent(tPtr, m_online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE); postEvent(tPtr, m_online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE);
} }
RR->topology->rankRoots(now); RR->topology->rankRoots();
if (pf.online) { if (pf.online) {
// If we have at least one online root, request whois for roots not online. // If we have at least one online root, request whois for roots not online.
@ -234,7 +228,7 @@ ZT_ResultCode Node::processBackgroundTasks(void *tPtr,int64_t now,volatile int64
// IP addresses. It will also auto-discover IPs for roots that were not added // IP addresses. It will also auto-discover IPs for roots that were not added
// with an initial bootstrap address. // with an initial bootstrap address.
// TODO // TODO
//for (std::vector<Address>::const_iterator r(pf.rootsNotOnline.begin()); r != pf.rootsNotOnline.end(); ++r) //for (Vector<Address>::const_iterator r(pf.rootsNotOnline.begin()); r != pf.rootsNotOnline.end(); ++r)
// RR->sw->requestWhois(tPtr,now,*r); // RR->sw->requestWhois(tPtr,now,*r);
} }
} catch ( ... ) { } catch ( ... ) {
@ -360,7 +354,7 @@ ZT_ResultCode Node::removeRoot(void *tPtr,const ZT_Identity *identity)
{ {
if (!identity) if (!identity)
return ZT_RESULT_ERROR_BAD_PARAMETER; return ZT_RESULT_ERROR_BAD_PARAMETER;
RR->topology->removeRoot(*reinterpret_cast<const Identity *>(identity)); RR->topology->removeRoot(tPtr, *reinterpret_cast<const Identity *>(identity));
return ZT_RESULT_OK; return ZT_RESULT_OK;
} }
@ -380,7 +374,7 @@ void Node::status(ZT_NodeStatus *status) const
ZT_PeerList *Node::peers() const ZT_PeerList *Node::peers() const
{ {
std::vector< SharedPtr<Peer> > peers; Vector< SharedPtr<Peer> > peers;
RR->topology->getAllPeers(peers); RR->topology->getAllPeers(peers);
std::sort(peers.begin(),peers.end(),_sortPeerPtrsByAddress()); std::sort(peers.begin(),peers.end(),_sortPeerPtrsByAddress());
@ -393,7 +387,7 @@ ZT_PeerList *Node::peers() const
const int64_t now = m_now; const int64_t now = m_now;
pl->peerCount = 0; pl->peerCount = 0;
for(std::vector< SharedPtr<Peer> >::iterator pi(peers.begin());pi!=peers.end();++pi) { // NOLINT(modernize-use-auto,modernize-loop-convert,hicpp-use-auto) for(Vector< SharedPtr<Peer> >::iterator pi(peers.begin());pi!=peers.end();++pi) { // NOLINT(modernize-use-auto,modernize-loop-convert,hicpp-use-auto)
ZT_Peer *const p = &(pl->peers[pl->peerCount]); ZT_Peer *const p = &(pl->peers[pl->peerCount]);
p->address = (*pi)->address().toInt(); p->address = (*pi)->address().toInt();
@ -420,14 +414,15 @@ ZT_PeerList *Node::peers() const
Utils::copy<sizeof(sockaddr_storage)>(&(p->bootstrap[p->bootstrapAddressCount++]),&(*i)); Utils::copy<sizeof(sockaddr_storage)>(&(p->bootstrap[p->bootstrapAddressCount++]),&(*i));
} }
std::vector< SharedPtr<Path> > paths; Vector< SharedPtr<Path> > paths;
(*pi)->getAllPaths(paths); (*pi)->getAllPaths(paths);
p->pathCount = 0; p->pathCount = 0;
for(std::vector< SharedPtr<Path> >::iterator path(paths.begin());path!=paths.end();++path) { // NOLINT(modernize-use-auto,modernize-loop-convert,hicpp-use-auto) for(Vector< SharedPtr<Path> >::iterator path(paths.begin());path!=paths.end();++path) { // NOLINT(modernize-use-auto,modernize-loop-convert,hicpp-use-auto)
Utils::copy<sizeof(sockaddr_storage)>(&(p->paths[p->pathCount].address),&((*path)->address())); Utils::copy<sizeof(sockaddr_storage)>(&(p->paths[p->pathCount].address),&((*path)->address()));
p->paths[p->pathCount].lastSend = (*path)->lastOut(); p->paths[p->pathCount].lastSend = (*path)->lastOut();
p->paths[p->pathCount].lastReceive = (*path)->lastIn(); p->paths[p->pathCount].lastReceive = (*path)->lastIn();
p->paths[p->pathCount].trustedPathId = RR->topology->getOutboundPathTrust((*path)->address()); // TODO
//p->paths[p->pathCount].trustedPathId = RR->topology->getOutboundPathTrust((*path)->address());
p->paths[p->pathCount].alive = (*path)->alive(now) ? 1 : 0; p->paths[p->pathCount].alive = (*path)->alive(now) ? 1 : 0;
p->paths[p->pathCount].preferred = (p->pathCount == 0) ? 1 : 0; p->paths[p->pathCount].preferred = (p->pathCount == 0) ? 1 : 0;
++p->pathCount; ++p->pathCount;
@ -613,15 +608,17 @@ void Node::ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &de
if (destination == RR->identity.address()) { if (destination == RR->identity.address()) {
SharedPtr<Network> n(network(nwid)); SharedPtr<Network> n(network(nwid));
if (!n) return; if (!n)
return;
n->setConfiguration((void *)0,nc,true); n->setConfiguration((void *)0,nc,true);
} else { } else {
Dictionary dconf; Dictionary dconf;
if (nc.toDictionary(dconf,sendLegacyFormatConfig)) { if (nc.toDictionary(dconf)) {
uint64_t configUpdateId = Utils::random(); uint64_t configUpdateId = Utils::random();
if (!configUpdateId) ++configUpdateId; if (!configUpdateId)
++configUpdateId;
std::vector<uint8_t> ddata; Vector<uint8_t> ddata;
dconf.encode(ddata); dconf.encode(ddata);
// TODO // TODO
/* /*

View file

@ -164,11 +164,10 @@ void Peer::send(void *tPtr,int64_t now,const void *data,unsigned int len) noexce
sent(now,len); sent(now,len);
} }
unsigned int Peer::hello(void *tPtr,int64_t localSocket,const InetAddress &atAddress,int64_t now) unsigned int Peer::hello(void *tPtr,int64_t localSocket,const InetAddress &atAddress,const int64_t now)
{ {
Buf outp; Buf outp;
const int64_t now = RR->node->now();
const uint64_t packetId = m_identityKey->nextMessage(RR->identity.address(),m_id.address()); const uint64_t packetId = m_identityKey->nextMessage(RR->identity.address(),m_id.address());
int ii = Protocol::newPacket(outp,packetId,m_id.address(),RR->identity.address(),Protocol::VERB_HELLO); int ii = Protocol::newPacket(outp,packetId,m_id.address(),RR->identity.address(),Protocol::VERB_HELLO);

View file

@ -32,6 +32,13 @@ public:
void update(const void *data,unsigned int len) noexcept; void update(const void *data,unsigned int len) noexcept;
void finish(void *auth) noexcept; void finish(void *auth) noexcept;
static ZT_INLINE void compute(void *const auth, const void *const data, const unsigned int len, const void *const key) noexcept
{
Poly1305 p(key);
p.update(data,len);
p.finish(auth);
}
private: private:
struct { struct {
size_t aligner; size_t aligner;

View file

@ -31,9 +31,11 @@ public:
_now(now), _now(now),
_tPtr(tPtr), _tPtr(tPtr),
_family(inetAddressFamily), _family(inetAddressFamily),
_scope(scope) {} _scope(scope)
{}
ZT_INLINE void operator()(const SharedPtr<Peer> &p) { p->resetWithinScope(_tPtr,_scope,_family,_now); } ZT_INLINE void operator()(const SharedPtr<Peer> &p)
{ p->resetWithinScope(_tPtr, _scope, _family, _now); }
private: private:
int64_t _now; int64_t _now;

View file

@ -144,7 +144,8 @@ public:
ZT_INLINE bool weakGC() ZT_INLINE bool weakGC()
{ {
if (m_ptr) { if (m_ptr) {
if (m_ptr->__refCount.compare_exchange_strong(1,0)) { int one = 1;
if (m_ptr->__refCount.compare_exchange_strong(one,(int)0)) {
delete m_ptr; delete m_ptr;
m_ptr = nullptr; m_ptr = nullptr;
return true; return true;

View file

@ -413,7 +413,7 @@ extern "C" const char *ZTT_general()
return "FCV object life cycle test failed (2)"; return "FCV object life cycle test failed (2)";
} }
test.clear(); test.clear();
if (cnt != (long)test.size()) { if (cnt != (long)test2.size()) {
ZT_T_PRINTF("FAILED (expected 512 objects, got %lu (3))" ZT_EOL_S,cnt); ZT_T_PRINTF("FAILED (expected 512 objects, got %lu (3))" ZT_EOL_S,cnt);
return "FCV object life cycle test failed (3)"; return "FCV object life cycle test failed (3)";
} }
@ -515,7 +515,7 @@ extern "C" const char *ZTT_general()
FCV<Buf::Slice,ZT_MAX_PACKET_FRAGMENTS> message; FCV<Buf::Slice,ZT_MAX_PACKET_FRAGMENTS> message;
FCV<Buf::Slice,ZT_MAX_PACKET_FRAGMENTS> ref; FCV<Buf::Slice,ZT_MAX_PACKET_FRAGMENTS> ref;
int frags = 1 + (int)(Utils::random() % 16); int frags = 1 + (int)(Utils::random() % ZT_MAX_PACKET_FRAGMENTS);
int skip = ((k & 3) == 1) ? -1 : (int)(Utils::random() % frags); int skip = ((k & 3) == 1) ? -1 : (int)(Utils::random() % frags);
bool complete = false; bool complete = false;
message.resize(frags); message.resize(frags);
@ -803,12 +803,12 @@ extern "C" const char *ZTT_crypto()
{ {
uint8_t tag[16]; uint8_t tag[16];
ZT_T_PRINTF("[crypto] Testing Poly1305... "); ZT_T_PRINTF("[crypto] Testing Poly1305... ");
poly1305(tag,POLY1305_TV0_INPUT,sizeof(POLY1305_TV0_INPUT),POLY1305_TV0_KEY); Poly1305::compute(tag,POLY1305_TV0_INPUT,sizeof(POLY1305_TV0_INPUT),POLY1305_TV0_KEY);
if (memcmp(tag,POLY1305_TV0_TAG,16) != 0) { if (memcmp(tag,POLY1305_TV0_TAG,16) != 0) {
ZT_T_PRINTF("FAILED (test vector 0)" ZT_EOL_S); ZT_T_PRINTF("FAILED (test vector 0)" ZT_EOL_S);
return "poly1305 test vector 0 failed"; return "poly1305 test vector 0 failed";
} }
poly1305(tag,POLY1305_TV1_INPUT,sizeof(POLY1305_TV1_INPUT),POLY1305_TV1_KEY); Poly1305::compute(tag,POLY1305_TV1_INPUT,sizeof(POLY1305_TV1_INPUT),POLY1305_TV1_KEY);
if (memcmp(tag,POLY1305_TV1_TAG,16) != 0) { if (memcmp(tag,POLY1305_TV1_TAG,16) != 0) {
ZT_T_PRINTF("FAILED (test vector 1)" ZT_EOL_S); ZT_T_PRINTF("FAILED (test vector 1)" ZT_EOL_S);
return "poly1305 test vector 1 failed"; return "poly1305 test vector 1 failed";
@ -1014,7 +1014,7 @@ extern "C" const char *ZTT_benchmarkCrypto()
ZT_T_PRINTF("[crypto] Benchmarking Poly1305... "); ZT_T_PRINTF("[crypto] Benchmarking Poly1305... ");
int64_t start = now(); int64_t start = now();
for(long i=0;i<150000;++i) for(long i=0;i<150000;++i)
poly1305(tag,tmp,sizeof(tmp),tag); Poly1305::compute(tag,tmp,sizeof(tmp),tag);
int64_t end = now(); int64_t end = now();
foo = tag[0]; // prevent optimization foo = tag[0]; // prevent optimization
ZT_T_PRINTF("%.4f MiB/sec" ZT_EOL_S,((16384.0 * 150000.0) / 1048576.0) / ((double)(end - start) / 1000.0)); ZT_T_PRINTF("%.4f MiB/sec" ZT_EOL_S,((16384.0 * 150000.0) / 1048576.0) / ((double)(end - start) / 1000.0));

View file

@ -51,6 +51,11 @@ namespace Utils {
#define ZT_CONST_TO_BE_UINT64(x) ((uint64_t)(x)) #define ZT_CONST_TO_BE_UINT64(x) ((uint64_t)(x))
#endif #endif
#define ZT_ROR64(x, r) (((x) >> (r)) | ((x) << (64 - (r))))
#define ZT_ROL64(x, r) (((x) << (r)) | ((x) >> (64 - (r))))
#define ZT_ROR32(x, r) (((x) >> (r)) | ((x) << (32 - (r))))
#define ZT_ROL32(x, r) (((x) << (r)) | ((x) >> (32 - (r))))
#ifdef ZT_ARCH_X64 #ifdef ZT_ARCH_X64
struct CPUIDRegisters struct CPUIDRegisters
{ {
@ -759,6 +764,9 @@ struct Mallocator
ZT_INLINE size_type max_size() const noexcept { return std::numeric_limits<size_t>::max() / sizeof(T); } ZT_INLINE size_type max_size() const noexcept { return std::numeric_limits<size_t>::max() / sizeof(T); }
ZT_INLINE void construct(pointer p,const T& val) { new((void *)p) T(val); } ZT_INLINE void construct(pointer p,const T& val) { new((void *)p) T(val); }
ZT_INLINE void destroy(pointer p) { p->~T(); } ZT_INLINE void destroy(pointer p) { p->~T(); }
constexpr bool operator==(const Mallocator &) const noexcept { return true; }
constexpr bool operator!=(const Mallocator &) const noexcept { return false; }
}; };
} // namespace Utils } // namespace Utils