Clang-format changes.

This commit is contained in:
Adam Ierymenko 2021-05-18 12:43:13 -04:00
parent 68c64d530b
commit 0290446000
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
96 changed files with 4974 additions and 5613 deletions

View file

@ -32,38 +32,47 @@ namespace ZeroTier {
namespace {
#define s_bmul32(N, x, y, rh, rl) \
uint32_t x0t_##N = (x)&0x11111111U; \
uint32_t x1t_##N = (x)&0x22222222U; \
uint32_t x2t_##N = (x)&0x44444444U; \
uint32_t x3t_##N = (x)&0x88888888U; \
uint32_t y0t_##N = (y)&0x11111111U; \
uint32_t y1t_##N = (y)&0x22222222U; \
uint32_t y2t_##N = (y)&0x44444444U; \
uint32_t y3t_##N = (y)&0x88888888U; \
uint64_t z0t_##N = (((uint64_t)x0t_##N * y0t_##N) ^ ((uint64_t)x1t_##N * y3t_##N) ^ ((uint64_t)x2t_##N * y2t_##N) ^ ((uint64_t)x3t_##N * y1t_##N)) & 0x1111111111111111ULL; \
uint64_t z1t_##N = (((uint64_t)x0t_##N * y1t_##N) ^ ((uint64_t)x1t_##N * y0t_##N) ^ ((uint64_t)x2t_##N * y3t_##N) ^ ((uint64_t)x3t_##N * y2t_##N)) & 0x2222222222222222ULL; \
uint64_t z2t_##N = (((uint64_t)x0t_##N * y2t_##N) ^ ((uint64_t)x1t_##N * y1t_##N) ^ ((uint64_t)x2t_##N * y0t_##N) ^ ((uint64_t)x3t_##N * y3t_##N)) & 0x4444444444444444ULL; \
z0t_##N |= z1t_##N; \
z2t_##N |= z0t_##N; \
uint64_t zt_##N = z2t_##N | ((((uint64_t)x0t_##N * y3t_##N) ^ ((uint64_t)x1t_##N * y2t_##N) ^ ((uint64_t)x2t_##N * y1t_##N) ^ ((uint64_t)x3t_##N * y0t_##N)) & 0x8888888888888888ULL); \
(rh) = (uint32_t)(zt_##N >> 32U); \
#define s_bmul32(N, x, y, rh, rl) \
uint32_t x0t_##N = (x)&0x11111111U; \
uint32_t x1t_##N = (x)&0x22222222U; \
uint32_t x2t_##N = (x)&0x44444444U; \
uint32_t x3t_##N = (x)&0x88888888U; \
uint32_t y0t_##N = (y)&0x11111111U; \
uint32_t y1t_##N = (y)&0x22222222U; \
uint32_t y2t_##N = (y)&0x44444444U; \
uint32_t y3t_##N = (y)&0x88888888U; \
uint64_t z0t_##N = (((uint64_t)x0t_##N * y0t_##N) ^ ((uint64_t)x1t_##N * y3t_##N) ^ ((uint64_t)x2t_##N * y2t_##N) \
^ ((uint64_t)x3t_##N * y1t_##N)) \
& 0x1111111111111111ULL; \
uint64_t z1t_##N = (((uint64_t)x0t_##N * y1t_##N) ^ ((uint64_t)x1t_##N * y0t_##N) ^ ((uint64_t)x2t_##N * y3t_##N) \
^ ((uint64_t)x3t_##N * y2t_##N)) \
& 0x2222222222222222ULL; \
uint64_t z2t_##N = (((uint64_t)x0t_##N * y2t_##N) ^ ((uint64_t)x1t_##N * y1t_##N) ^ ((uint64_t)x2t_##N * y0t_##N) \
^ ((uint64_t)x3t_##N * y3t_##N)) \
& 0x4444444444444444ULL; \
z0t_##N |= z1t_##N; \
z2t_##N |= z0t_##N; \
uint64_t zt_##N = z2t_##N \
| ((((uint64_t)x0t_##N * y3t_##N) ^ ((uint64_t)x1t_##N * y2t_##N) \
^ ((uint64_t)x2t_##N * y1t_##N) ^ ((uint64_t)x3t_##N * y0t_##N)) \
& 0x8888888888888888ULL); \
(rh) = (uint32_t)(zt_##N >> 32U); \
(rl) = (uint32_t)zt_##N;
void s_gfmul(const uint64_t hh, const uint64_t hl, uint64_t& y0, uint64_t& y1) noexcept
void s_gfmul(const uint64_t hh, const uint64_t hl, uint64_t &y0, uint64_t &y1) noexcept
{
uint32_t hhh = (uint32_t)(hh >> 32U);
uint32_t hhl = (uint32_t)hh;
uint32_t hlh = (uint32_t)(hl >> 32U);
uint32_t hll = (uint32_t)hl;
uint32_t hhXlh = hhh ^ hlh;
uint32_t hhXll = hhl ^ hll;
uint64_t yl = Utils::ntoh(y0);
uint64_t yh = Utils::ntoh(y1);
uint32_t cilh = (uint32_t)(yh >> 32U);
uint32_t cill = (uint32_t)yh;
uint32_t cihh = (uint32_t)(yl >> 32U);
uint32_t cihl = (uint32_t)yl;
uint32_t hhh = (uint32_t)(hh >> 32U);
uint32_t hhl = (uint32_t)hh;
uint32_t hlh = (uint32_t)(hl >> 32U);
uint32_t hll = (uint32_t)hl;
uint32_t hhXlh = hhh ^ hlh;
uint32_t hhXll = hhl ^ hll;
uint64_t yl = Utils::ntoh(y0);
uint64_t yh = Utils::ntoh(y1);
uint32_t cilh = (uint32_t)(yh >> 32U);
uint32_t cill = (uint32_t)yh;
uint32_t cihh = (uint32_t)(yl >> 32U);
uint32_t cihl = (uint32_t)yl;
uint32_t cihXlh = cihh ^ cilh;
uint32_t cihXll = cihl ^ cill;
uint32_t aah, aal, abh, abl, ach, acl;
@ -98,9 +107,9 @@ void s_gfmul(const uint64_t hh, const uint64_t hl, uint64_t& y0, uint64_t& y1) n
uint64_t zhl = (((uint64_t)abh << 32U) | abl) ^ (((uint64_t)cah << 32U) | cal);
uint64_t zlh = (((uint64_t)bah << 32U) | bal) ^ (((uint64_t)cbh << 32U) | cbl);
uint64_t zll = ((uint64_t)bbh << 32U) | bbl;
zhh = zhh << 1U | zhl >> 63U;
zhl = zhl << 1U | zlh >> 63U;
zlh = zlh << 1U | zll >> 63U;
zhh = zhh << 1U | zhl >> 63U;
zhl = zhl << 1U | zlh >> 63U;
zlh = zlh << 1U | zll >> 63U;
zll <<= 1U;
zlh ^= (zll << 63U) ^ (zll << 62U) ^ (zll << 57U);
zhh ^= zlh ^ (zlh >> 1U) ^ (zlh >> 2U) ^ (zlh >> 7U);
@ -111,9 +120,9 @@ void s_gfmul(const uint64_t hh, const uint64_t hl, uint64_t& y0, uint64_t& y1) n
} // anonymous namespace
void AES::GMAC::update(const void* const data, unsigned int len) noexcept
void AES::GMAC::update(const void *const data, unsigned int len) noexcept
{
const uint8_t* in = reinterpret_cast<const uint8_t*>(data);
const uint8_t *in = reinterpret_cast<const uint8_t *>(data);
_len += len;
#ifdef ZT_AES_AESNI
@ -132,12 +141,12 @@ void AES::GMAC::update(const void* const data, unsigned int len) noexcept
const uint64_t h0 = _aes.p_k.sw.h[0];
const uint64_t h1 = _aes.p_k.sw.h[1];
uint64_t y0 = _y[0];
uint64_t y1 = _y[1];
uint64_t y0 = _y[0];
uint64_t y1 = _y[1];
if (_rp) {
for (;;) {
if (! len)
if (!len)
return;
--len;
_r[_rp++] = *(in++);
@ -184,8 +193,8 @@ void AES::GMAC::finish(uint8_t tag[16]) noexcept
const uint64_t h0 = _aes.p_k.sw.h[0];
const uint64_t h1 = _aes.p_k.sw.h[1];
uint64_t y0 = _y[0];
uint64_t y1 = _y[1];
uint64_t y0 = _y[0];
uint64_t y1 = _y[1];
if (_rp) {
while (_rp < 16)
@ -201,9 +210,9 @@ void AES::GMAC::finish(uint8_t tag[16]) noexcept
uint64_t iv2[2];
Utils::copy<12>(iv2, _iv);
#if __BYTE_ORDER == __BIG_ENDIAN
reinterpret_cast<uint32_t*>(iv2)[3] = 0x00000001;
reinterpret_cast<uint32_t *>(iv2)[3] = 0x00000001;
#else
reinterpret_cast<uint32_t*>(iv2)[3] = 0x01000000;
reinterpret_cast<uint32_t *>(iv2)[3] = 0x01000000;
#endif
_aes.encrypt(iv2, iv2);
@ -213,10 +222,10 @@ void AES::GMAC::finish(uint8_t tag[16]) noexcept
// AES-CTR ------------------------------------------------------------------------------------------------------------
void AES::CTR::crypt(const void* const input, unsigned int len) noexcept
void AES::CTR::crypt(const void *const input, unsigned int len) noexcept
{
const uint8_t* in = reinterpret_cast<const uint8_t*>(input);
uint8_t* out = _out;
const uint8_t *in = reinterpret_cast<const uint8_t *>(input);
uint8_t *out = _out;
#ifdef ZT_AES_AESNI
if (likely(Utils::CPUID.aes)) {
@ -233,23 +242,23 @@ void AES::CTR::crypt(const void* const input, unsigned int len) noexcept
#endif // ZT_AES_NEON
uint64_t keyStream[2];
uint32_t ctr = Utils::ntoh(reinterpret_cast<uint32_t*>(_ctr)[3]);
uint32_t ctr = Utils::ntoh(reinterpret_cast<uint32_t *>(_ctr)[3]);
unsigned int totalLen = _len;
if ((totalLen & 15U)) {
for (;;) {
if (! len) {
if (!len) {
_len = (totalLen + len);
return;
}
--len;
out[totalLen++] = *(in++);
if (! (totalLen & 15U)) {
_aes.p_encryptSW(reinterpret_cast<const uint8_t*>(_ctr), reinterpret_cast<uint8_t*>(keyStream));
reinterpret_cast<uint32_t*>(_ctr)[3] = Utils::hton(++ctr);
uint8_t* outblk = out + (totalLen - 16);
if (!(totalLen & 15U)) {
_aes.p_encryptSW(reinterpret_cast<const uint8_t *>(_ctr), reinterpret_cast<uint8_t *>(keyStream));
reinterpret_cast<uint32_t *>(_ctr)[3] = Utils::hton(++ctr);
uint8_t *outblk = out + (totalLen - 16);
for (int i = 0; i < 16; ++i)
outblk[i] ^= reinterpret_cast<uint8_t*>(keyStream)[i];
outblk[i] ^= reinterpret_cast<uint8_t *>(keyStream)[i];
break;
}
}
@ -259,14 +268,14 @@ void AES::CTR::crypt(const void* const input, unsigned int len) noexcept
_len = (totalLen + len);
if (likely(len >= 16)) {
const uint32_t* const restrict rk = _aes.p_k.sw.ek;
const uint32_t ctr0rk0 = Utils::ntoh(reinterpret_cast<const uint32_t*>(_ctr)[0]) ^ rk[0];
const uint32_t ctr1rk1 = Utils::ntoh(reinterpret_cast<const uint32_t*>(_ctr)[1]) ^ rk[1];
const uint32_t ctr2rk2 = Utils::ntoh(reinterpret_cast<const uint32_t*>(_ctr)[2]) ^ rk[2];
const uint32_t m8 = 0x000000ff;
const uint32_t m8_8 = 0x0000ff00;
const uint32_t m8_16 = 0x00ff0000;
const uint32_t m8_24 = 0xff000000;
const uint32_t *const restrict rk = _aes.p_k.sw.ek;
const uint32_t ctr0rk0 = Utils::ntoh(reinterpret_cast<const uint32_t *>(_ctr)[0]) ^ rk[0];
const uint32_t ctr1rk1 = Utils::ntoh(reinterpret_cast<const uint32_t *>(_ctr)[1]) ^ rk[1];
const uint32_t ctr2rk2 = Utils::ntoh(reinterpret_cast<const uint32_t *>(_ctr)[2]) ^ rk[2];
const uint32_t m8 = 0x000000ff;
const uint32_t m8_8 = 0x0000ff00;
const uint32_t m8_16 = 0x00ff0000;
const uint32_t m8_24 = 0xff000000;
if (likely((((uintptr_t)out & 7U) == 0U) && (((uintptr_t)in & 7U) == 0U))) {
do {
uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
@ -275,8 +284,8 @@ void AES::CTR::crypt(const void* const input, unsigned int len) noexcept
s2 = ctr2rk2;
s3 = ctr++ ^ rk[3];
const uint64_t in0 = *reinterpret_cast<const uint64_t*>(in);
const uint64_t in1 = *reinterpret_cast<const uint64_t*>(in + 8);
const uint64_t in0 = *reinterpret_cast<const uint64_t *>(in);
const uint64_t in1 = *reinterpret_cast<const uint64_t *>(in + 8);
in += 16;
t0 = Te0[s0 >> 24U] ^ Te1_r((s1 >> 16U) & m8) ^ Te2_r((s2 >> 8U) & m8) ^ Te3_r(s3 & m8) ^ rk[4];
@ -331,13 +340,17 @@ void AES::CTR::crypt(const void* const input, unsigned int len) noexcept
t1 = Te0[s1 >> 24U] ^ Te1_r((s2 >> 16U) & m8) ^ Te2_r((s3 >> 8U) & m8) ^ Te3_r(s0 & m8) ^ rk[53];
t2 = Te0[s2 >> 24U] ^ Te1_r((s3 >> 16U) & m8) ^ Te2_r((s0 >> 8U) & m8) ^ Te3_r(s1 & m8) ^ rk[54];
t3 = Te0[s3 >> 24U] ^ Te1_r((s0 >> 16U) & m8) ^ Te2_r((s1 >> 8U) & m8) ^ Te3_r(s2 & m8) ^ rk[55];
s0 = (Te2_r(t0 >> 24U) & m8_24) ^ (Te3_r((t1 >> 16U) & m8) & m8_16) ^ (Te0[(t2 >> 8U) & m8] & m8_8) ^ (Te1_r(t3 & m8) & m8) ^ rk[56];
s1 = (Te2_r(t1 >> 24U) & m8_24) ^ (Te3_r((t2 >> 16U) & m8) & m8_16) ^ (Te0[(t3 >> 8U) & m8] & m8_8) ^ (Te1_r(t0 & m8) & m8) ^ rk[57];
s2 = (Te2_r(t2 >> 24U) & m8_24) ^ (Te3_r((t3 >> 16U) & m8) & m8_16) ^ (Te0[(t0 >> 8U) & m8] & m8_8) ^ (Te1_r(t1 & m8) & m8) ^ rk[58];
s3 = (Te2_r(t3 >> 24U) & m8_24) ^ (Te3_r((t0 >> 16U) & m8) & m8_16) ^ (Te0[(t1 >> 8U) & m8] & m8_8) ^ (Te1_r(t2 & m8) & m8) ^ rk[59];
s0 = (Te2_r(t0 >> 24U) & m8_24) ^ (Te3_r((t1 >> 16U) & m8) & m8_16) ^ (Te0[(t2 >> 8U) & m8] & m8_8)
^ (Te1_r(t3 & m8) & m8) ^ rk[56];
s1 = (Te2_r(t1 >> 24U) & m8_24) ^ (Te3_r((t2 >> 16U) & m8) & m8_16) ^ (Te0[(t3 >> 8U) & m8] & m8_8)
^ (Te1_r(t0 & m8) & m8) ^ rk[57];
s2 = (Te2_r(t2 >> 24U) & m8_24) ^ (Te3_r((t3 >> 16U) & m8) & m8_16) ^ (Te0[(t0 >> 8U) & m8] & m8_8)
^ (Te1_r(t1 & m8) & m8) ^ rk[58];
s3 = (Te2_r(t3 >> 24U) & m8_24) ^ (Te3_r((t0 >> 16U) & m8) & m8_16) ^ (Te0[(t1 >> 8U) & m8] & m8_8)
^ (Te1_r(t2 & m8) & m8) ^ rk[59];
*reinterpret_cast<uint64_t*>(out) = in0 ^ Utils::hton(((uint64_t)s0 << 32U) | (uint64_t)s1);
*reinterpret_cast<uint64_t*>(out + 8) = in1 ^ Utils::hton(((uint64_t)s2 << 32U) | (uint64_t)s3);
*reinterpret_cast<uint64_t *>(out) = in0 ^ Utils::hton(((uint64_t)s0 << 32U) | (uint64_t)s1);
*reinterpret_cast<uint64_t *>(out + 8) = in1 ^ Utils::hton(((uint64_t)s2 << 32U) | (uint64_t)s3);
out += 16;
} while ((len -= 16) >= 16);
}
@ -401,21 +414,25 @@ void AES::CTR::crypt(const void* const input, unsigned int len) noexcept
t1 = Te0[s1 >> 24U] ^ Te1_r((s2 >> 16U) & m8) ^ Te2_r((s3 >> 8U) & m8) ^ Te3_r(s0 & m8) ^ rk[53];
t2 = Te0[s2 >> 24U] ^ Te1_r((s3 >> 16U) & m8) ^ Te2_r((s0 >> 8U) & m8) ^ Te3_r(s1 & m8) ^ rk[54];
t3 = Te0[s3 >> 24U] ^ Te1_r((s0 >> 16U) & m8) ^ Te2_r((s1 >> 8U) & m8) ^ Te3_r(s2 & m8) ^ rk[55];
s0 = (Te2_r(t0 >> 24U) & m8_24) ^ (Te3_r((t1 >> 16U) & m8) & m8_16) ^ (Te0[(t2 >> 8U) & m8] & m8_8) ^ (Te1_r(t3 & m8) & m8) ^ rk[56];
s1 = (Te2_r(t1 >> 24U) & m8_24) ^ (Te3_r((t2 >> 16U) & m8) & m8_16) ^ (Te0[(t3 >> 8U) & m8] & m8_8) ^ (Te1_r(t0 & m8) & m8) ^ rk[57];
s2 = (Te2_r(t2 >> 24U) & m8_24) ^ (Te3_r((t3 >> 16U) & m8) & m8_16) ^ (Te0[(t0 >> 8U) & m8] & m8_8) ^ (Te1_r(t1 & m8) & m8) ^ rk[58];
s3 = (Te2_r(t3 >> 24U) & m8_24) ^ (Te3_r((t0 >> 16U) & m8) & m8_16) ^ (Te0[(t1 >> 8U) & m8] & m8_8) ^ (Te1_r(t2 & m8) & m8) ^ rk[59];
s0 = (Te2_r(t0 >> 24U) & m8_24) ^ (Te3_r((t1 >> 16U) & m8) & m8_16) ^ (Te0[(t2 >> 8U) & m8] & m8_8)
^ (Te1_r(t3 & m8) & m8) ^ rk[56];
s1 = (Te2_r(t1 >> 24U) & m8_24) ^ (Te3_r((t2 >> 16U) & m8) & m8_16) ^ (Te0[(t3 >> 8U) & m8] & m8_8)
^ (Te1_r(t0 & m8) & m8) ^ rk[57];
s2 = (Te2_r(t2 >> 24U) & m8_24) ^ (Te3_r((t3 >> 16U) & m8) & m8_16) ^ (Te0[(t0 >> 8U) & m8] & m8_8)
^ (Te1_r(t1 & m8) & m8) ^ rk[58];
s3 = (Te2_r(t3 >> 24U) & m8_24) ^ (Te3_r((t0 >> 16U) & m8) & m8_16) ^ (Te0[(t1 >> 8U) & m8] & m8_8)
^ (Te1_r(t2 & m8) & m8) ^ rk[59];
out[0] = in[0] ^ (uint8_t)(s0 >> 24U);
out[1] = in[1] ^ (uint8_t)(s0 >> 16U);
out[2] = in[2] ^ (uint8_t)(s0 >> 8U);
out[3] = in[3] ^ (uint8_t)s0;
out[4] = in[4] ^ (uint8_t)(s1 >> 24U);
out[5] = in[5] ^ (uint8_t)(s1 >> 16U);
out[6] = in[6] ^ (uint8_t)(s1 >> 8U);
out[7] = in[7] ^ (uint8_t)s1;
out[8] = in[8] ^ (uint8_t)(s2 >> 24U);
out[9] = in[9] ^ (uint8_t)(s2 >> 16U);
out[0] = in[0] ^ (uint8_t)(s0 >> 24U);
out[1] = in[1] ^ (uint8_t)(s0 >> 16U);
out[2] = in[2] ^ (uint8_t)(s0 >> 8U);
out[3] = in[3] ^ (uint8_t)s0;
out[4] = in[4] ^ (uint8_t)(s1 >> 24U);
out[5] = in[5] ^ (uint8_t)(s1 >> 16U);
out[6] = in[6] ^ (uint8_t)(s1 >> 8U);
out[7] = in[7] ^ (uint8_t)s1;
out[8] = in[8] ^ (uint8_t)(s2 >> 24U);
out[9] = in[9] ^ (uint8_t)(s2 >> 16U);
out[10] = in[10] ^ (uint8_t)(s2 >> 8U);
out[11] = in[11] ^ (uint8_t)s2;
out[12] = in[12] ^ (uint8_t)(s3 >> 24U);
@ -426,7 +443,7 @@ void AES::CTR::crypt(const void* const input, unsigned int len) noexcept
in += 16;
} while ((len -= 16) >= 16);
}
reinterpret_cast<uint32_t*>(_ctr)[3] = Utils::hton(ctr);
reinterpret_cast<uint32_t *>(_ctr)[3] = Utils::hton(ctr);
}
// Any remaining input is placed in _out. This will be picked up and crypted
@ -451,67 +468,122 @@ void AES::CTR::finish() noexcept
// Software AES and AES key expansion ---------------------------------------------------------------------------------
const uint32_t AES::Te0[256] = { 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5, 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883, 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4, 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12, 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a };
const uint32_t AES::Te4[256] = { 0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b, 0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5, 0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b, 0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676,
0xcacacaca, 0x82828282, 0xc9c9c9c9, 0x7d7d7d7d, 0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0, 0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2, 0xafafafaf, 0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0,
0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626, 0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc, 0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1, 0x71717171, 0xd8d8d8d8, 0x31313131, 0x15151515,
0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3, 0x18181818, 0x96969696, 0x05050505, 0x9a9a9a9a, 0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2, 0xebebebeb, 0x27272727, 0xb2b2b2b2, 0x75757575,
0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a, 0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0, 0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3, 0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484,
0x53535353, 0xd1d1d1d1, 0x00000000, 0xedededed, 0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b, 0x6a6a6a6a, 0xcbcbcbcb, 0xbebebebe, 0x39393939, 0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf,
0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa, 0xfbfbfbfb, 0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585, 0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f, 0x50505050, 0x3c3c3c3c, 0x9f9f9f9f, 0xa8a8a8a8,
0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f, 0x92929292, 0x9d9d9d9d, 0x38383838, 0xf5f5f5f5, 0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121, 0x10101010, 0xffffffff, 0xf3f3f3f3, 0xd2d2d2d2,
0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec, 0x5f5f5f5f, 0x97979797, 0x44444444, 0x17171717, 0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d, 0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373,
0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc, 0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888, 0x46464646, 0xeeeeeeee, 0xb8b8b8b8, 0x14141414, 0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb,
0xe0e0e0e0, 0x32323232, 0x3a3a3a3a, 0x0a0a0a0a, 0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c, 0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac, 0x62626262, 0x91919191, 0x95959595, 0xe4e4e4e4, 0x79797979,
0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d, 0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9, 0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea, 0x65656565, 0x7a7a7a7a, 0xaeaeaeae, 0x08080808,
0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e, 0x1c1c1c1c, 0xa6a6a6a6, 0xb4b4b4b4, 0xc6c6c6c6, 0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f, 0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b, 0x8a8a8a8a,
0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666, 0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e, 0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9, 0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e,
0xe1e1e1e1, 0xf8f8f8f8, 0x98989898, 0x11111111, 0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494, 0x9b9b9b9b, 0x1e1e1e1e, 0x87878787, 0xe9e9e9e9, 0xcececece, 0x55555555, 0x28282828, 0xdfdfdfdf,
0x8c8c8c8c, 0xa1a1a1a1, 0x89898989, 0x0d0d0d0d, 0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868, 0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f, 0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616 };
const uint32_t AES::Td0[256] = { 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a, 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0, 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742 };
const uint8_t AES::Td4[256] = { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
const uint32_t AES::rcon[15] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, 0x6c000000, 0xd8000000, 0xab000000, 0x4d000000, 0x9a000000 };
const uint32_t AES::Te0[256] = {
0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, 0x60303050,
0x02010103, 0xce6767a9, 0x562b2b7d, 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, 0x8fcaca45, 0x1f82829d,
0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, 0x41adadec, 0xb3d4d467, 0x5fa2a2fd,
0x45afafea, 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 0xe2717193,
0xabd8d873, 0x62313153, 0x2a15153f, 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1,
0x0a05050f, 0x2f9a9ab5, 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, 0xcdebeb26, 0x4e272769, 0x7fb2b2cd,
0xea75759f, 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497, 0xa65353f5,
0xb9d1d168, 0x00000000, 0xc1eded2c, 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, 0xd46a6abe, 0x8dcbcb46,
0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5,
0xedfbfb16, 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, 0x3f9292ad,
0x219d9dbc, 0x70383848, 0xf1f5f504, 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a,
0xfdf3f30e, 0xbfd2d26d, 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, 0xbe5f5fe1, 0x359797a2, 0x884444cc,
0x2e171739, 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883, 0x8c4646ca,
0xc7eeee29, 0x6bb8b8d3, 0x2814143c, 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, 0xdbe0e03b, 0x64323256,
0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4, 0x9fc2c25d, 0xbdd3d36e, 0x43acacef,
0xc46262a6, 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b, 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, 0xca6565af,
0xf47a7a8e, 0x47aeaee9, 0x10080818, 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1,
0x73b4b4c7, 0x97c6c651, 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86,
0x0f8a8a85, 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9, 0xd9e1e138,
0xebf8f813, 0x2b9898b3, 0x22111133, 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, 0x2d9b9bb6, 0x3c1e1e22,
0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a, 0x038c8c8f, 0x59a1a1f8, 0x09898980,
0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
};
const uint32_t AES::Te4[256] = {
0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b, 0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5, 0x30303030,
0x01010101, 0x67676767, 0x2b2b2b2b, 0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676, 0xcacacaca, 0x82828282,
0xc9c9c9c9, 0x7d7d7d7d, 0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0, 0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2,
0xafafafaf, 0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0, 0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626,
0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc, 0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1, 0x71717171,
0xd8d8d8d8, 0x31313131, 0x15151515, 0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3, 0x18181818, 0x96969696,
0x05050505, 0x9a9a9a9a, 0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2, 0xebebebeb, 0x27272727, 0xb2b2b2b2,
0x75757575, 0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a, 0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0,
0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3, 0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484, 0x53535353,
0xd1d1d1d1, 0x00000000, 0xedededed, 0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b, 0x6a6a6a6a, 0xcbcbcbcb,
0xbebebebe, 0x39393939, 0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf, 0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa,
0xfbfbfbfb, 0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585, 0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f,
0x50505050, 0x3c3c3c3c, 0x9f9f9f9f, 0xa8a8a8a8, 0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f, 0x92929292,
0x9d9d9d9d, 0x38383838, 0xf5f5f5f5, 0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121, 0x10101010, 0xffffffff,
0xf3f3f3f3, 0xd2d2d2d2, 0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec, 0x5f5f5f5f, 0x97979797, 0x44444444,
0x17171717, 0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d, 0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373,
0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc, 0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888, 0x46464646,
0xeeeeeeee, 0xb8b8b8b8, 0x14141414, 0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb, 0xe0e0e0e0, 0x32323232,
0x3a3a3a3a, 0x0a0a0a0a, 0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c, 0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac,
0x62626262, 0x91919191, 0x95959595, 0xe4e4e4e4, 0x79797979, 0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d,
0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9, 0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea, 0x65656565,
0x7a7a7a7a, 0xaeaeaeae, 0x08080808, 0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e, 0x1c1c1c1c, 0xa6a6a6a6,
0xb4b4b4b4, 0xc6c6c6c6, 0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f, 0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b,
0x8a8a8a8a, 0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666, 0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e,
0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9, 0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e, 0xe1e1e1e1,
0xf8f8f8f8, 0x98989898, 0x11111111, 0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494, 0x9b9b9b9b, 0x1e1e1e1e,
0x87878787, 0xe9e9e9e9, 0xcececece, 0x55555555, 0x28282828, 0xdfdfdfdf, 0x8c8c8c8c, 0xa1a1a1a1, 0x89898989,
0x0d0d0d0d, 0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868, 0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f,
0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616
};
const uint32_t AES::Td0[256] = {
0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, 0x2030fa55,
0xad766df6, 0x88cc7691, 0xf5024c25, 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, 0xdeb15a49, 0x25ba1b67,
0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, 0x038f5fe7, 0x15929c95, 0xbf6d7aeb,
0x955259da, 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844, 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, 0xb16477e0,
0xbb6bae84, 0xfe81a01c, 0xf9082b94, 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2,
0xe31f8f57, 0x6655ab2a, 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, 0x302887f2, 0x23bfa5b2, 0x02036aba,
0xed16825c, 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051, 0x3e218af9,
0x96dd063d, 0xdd3e05ae, 0x4de6bd46, 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, 0x1998fb24, 0xd6bde997,
0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb, 0xa17c0a47, 0x7c420fe9, 0xf8841ec9,
0x00000000, 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f,
0x61dc20a2, 0x5a774b69, 0x1c121a16, 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad,
0x2db6a8b9, 0x141ea9c8, 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, 0xf701269f, 0x5c72f5bc, 0x44663bc5,
0x5bfb7e34, 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0, 0x2bb3166c,
0xa970b999, 0x119448fa, 0x47e96422, 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, 0x87494ec7, 0xd938d1c1,
0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b,
0x547e4662, 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5, 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, 0xe6956e65,
0xaaffe67e, 0x21bccf08, 0xef15e8e6, 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331,
0xc6a59430, 0x35a266c0, 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, 0xf104984a, 0x41ecdaf7, 0x7fcd500e,
0x1791f62f, 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713, 0x9ad7618c,
0x37a10c7a, 0x59f8148e, 0xeb133c89, 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, 0x9cd2df59, 0x55f2733f,
0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86, 0xcaaff381, 0xb968c43e, 0x3824342c,
0xc2a3405f, 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
};
const uint8_t AES::Td4[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39,
0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2,
0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76,
0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc,
0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d,
0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c,
0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f,
0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62,
0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd,
0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60,
0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d,
0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6,
0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};
const uint32_t AES::rcon[15] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000,
0x6c000000, 0xd8000000, 0xab000000, 0x4d000000, 0x9a000000 };
void AES::p_initSW(const uint8_t* key) noexcept
void AES::p_initSW(const uint8_t *key) noexcept
{
uint32_t* rk = p_k.sw.ek;
uint32_t *rk = p_k.sw.ek;
rk[0] = Utils::loadBigEndian<uint32_t>(key);
rk[1] = Utils::loadBigEndian<uint32_t>(key + 4);
@ -523,21 +595,23 @@ void AES::p_initSW(const uint8_t* key) noexcept
rk[7] = Utils::loadBigEndian<uint32_t>(key + 28);
for (int i = 0;;) {
uint32_t temp = rk[7];
rk[8] = rk[0] ^ (Te2_r((temp >> 16U) & 0xffU) & 0xff000000U) ^ (Te3_r((temp >> 8U) & 0xffU) & 0x00ff0000U) ^ (Te0[(temp)&0xffU] & 0x0000ff00U) ^ (Te1_r(temp >> 24U) & 0x000000ffU) ^ rcon[i];
rk[9] = rk[1] ^ rk[8];
rk[8] = rk[0] ^ (Te2_r((temp >> 16U) & 0xffU) & 0xff000000U) ^ (Te3_r((temp >> 8U) & 0xffU) & 0x00ff0000U)
^ (Te0[(temp)&0xffU] & 0x0000ff00U) ^ (Te1_r(temp >> 24U) & 0x000000ffU) ^ rcon[i];
rk[9] = rk[1] ^ rk[8];
rk[10] = rk[2] ^ rk[9];
rk[11] = rk[3] ^ rk[10];
if (++i == 7)
break;
temp = rk[11];
rk[12] = rk[4] ^ (Te2_r(temp >> 24U) & 0xff000000U) ^ (Te3_r((temp >> 16U) & 0xffU) & 0x00ff0000U) ^ (Te0[(temp >> 8U) & 0xffU] & 0x0000ff00U) ^ (Te1_r((temp)&0xffU) & 0x000000ffU);
temp = rk[11];
rk[12] = rk[4] ^ (Te2_r(temp >> 24U) & 0xff000000U) ^ (Te3_r((temp >> 16U) & 0xffU) & 0x00ff0000U)
^ (Te0[(temp >> 8U) & 0xffU] & 0x0000ff00U) ^ (Te1_r((temp)&0xffU) & 0x000000ffU);
rk[13] = rk[5] ^ rk[12];
rk[14] = rk[6] ^ rk[13];
rk[15] = rk[7] ^ rk[14];
rk += 8;
}
p_encryptSW((const uint8_t*)Utils::ZERO256, (uint8_t*)p_k.sw.h);
p_encryptSW((const uint8_t *)Utils::ZERO256, (uint8_t *)p_k.sw.h);
p_k.sw.h[0] = Utils::ntoh(p_k.sw.h[0]);
p_k.sw.h[1] = Utils::ntoh(p_k.sw.h[1]);
@ -547,38 +621,42 @@ void AES::p_initSW(const uint8_t* key) noexcept
for (int i = 0, j = 56; i < j; i += 4, j -= 4) {
uint32_t temp = rk[i];
rk[i] = rk[j];
rk[j] = temp;
temp = rk[i + 1];
rk[i + 1] = rk[j + 1];
rk[j + 1] = temp;
temp = rk[i + 2];
rk[i + 2] = rk[j + 2];
rk[j + 2] = temp;
temp = rk[i + 3];
rk[i + 3] = rk[j + 3];
rk[j + 3] = temp;
rk[i] = rk[j];
rk[j] = temp;
temp = rk[i + 1];
rk[i + 1] = rk[j + 1];
rk[j + 1] = temp;
temp = rk[i + 2];
rk[i + 2] = rk[j + 2];
rk[j + 2] = temp;
temp = rk[i + 3];
rk[i + 3] = rk[j + 3];
rk[j + 3] = temp;
}
for (int i = 1; i < 14; ++i) {
rk += 4;
rk[0] = Td0[Te4[(rk[0] >> 24U)] & 0xffU] ^ Td1_r(Te4[(rk[0] >> 16U) & 0xffU] & 0xffU) ^ Td2_r(Te4[(rk[0] >> 8U) & 0xffU] & 0xffU) ^ Td3_r(Te4[(rk[0]) & 0xffU] & 0xffU);
rk[1] = Td0[Te4[(rk[1] >> 24U)] & 0xffU] ^ Td1_r(Te4[(rk[1] >> 16U) & 0xffU] & 0xffU) ^ Td2_r(Te4[(rk[1] >> 8U) & 0xffU] & 0xffU) ^ Td3_r(Te4[(rk[1]) & 0xffU] & 0xffU);
rk[2] = Td0[Te4[(rk[2] >> 24U)] & 0xffU] ^ Td1_r(Te4[(rk[2] >> 16U) & 0xffU] & 0xffU) ^ Td2_r(Te4[(rk[2] >> 8U) & 0xffU] & 0xffU) ^ Td3_r(Te4[(rk[2]) & 0xffU] & 0xffU);
rk[3] = Td0[Te4[(rk[3] >> 24U)] & 0xffU] ^ Td1_r(Te4[(rk[3] >> 16U) & 0xffU] & 0xffU) ^ Td2_r(Te4[(rk[3] >> 8U) & 0xffU] & 0xffU) ^ Td3_r(Te4[(rk[3]) & 0xffU] & 0xffU);
rk[0] = Td0[Te4[(rk[0] >> 24U)] & 0xffU] ^ Td1_r(Te4[(rk[0] >> 16U) & 0xffU] & 0xffU)
^ Td2_r(Te4[(rk[0] >> 8U) & 0xffU] & 0xffU) ^ Td3_r(Te4[(rk[0]) & 0xffU] & 0xffU);
rk[1] = Td0[Te4[(rk[1] >> 24U)] & 0xffU] ^ Td1_r(Te4[(rk[1] >> 16U) & 0xffU] & 0xffU)
^ Td2_r(Te4[(rk[1] >> 8U) & 0xffU] & 0xffU) ^ Td3_r(Te4[(rk[1]) & 0xffU] & 0xffU);
rk[2] = Td0[Te4[(rk[2] >> 24U)] & 0xffU] ^ Td1_r(Te4[(rk[2] >> 16U) & 0xffU] & 0xffU)
^ Td2_r(Te4[(rk[2] >> 8U) & 0xffU] & 0xffU) ^ Td3_r(Te4[(rk[2]) & 0xffU] & 0xffU);
rk[3] = Td0[Te4[(rk[3] >> 24U)] & 0xffU] ^ Td1_r(Te4[(rk[3] >> 16U) & 0xffU] & 0xffU)
^ Td2_r(Te4[(rk[3] >> 8U) & 0xffU] & 0xffU) ^ Td3_r(Te4[(rk[3]) & 0xffU] & 0xffU);
}
}
void AES::p_encryptSW(const uint8_t* in, uint8_t* out) const noexcept
void AES::p_encryptSW(const uint8_t *in, uint8_t *out) const noexcept
{
const uint32_t* const restrict rk = p_k.sw.ek;
const uint32_t m8 = 0x000000ff;
const uint32_t m8_8 = 0x0000ff00;
const uint32_t m8_16 = 0x00ff0000;
const uint32_t m8_24 = 0xff000000;
uint32_t s0 = Utils::loadBigEndian<uint32_t>(in) ^ rk[0];
uint32_t s1 = Utils::loadBigEndian<uint32_t>(in + 4) ^ rk[1];
uint32_t s2 = Utils::loadBigEndian<uint32_t>(in + 8) ^ rk[2];
uint32_t s3 = Utils::loadBigEndian<uint32_t>(in + 12) ^ rk[3];
const uint32_t *const restrict rk = p_k.sw.ek;
const uint32_t m8 = 0x000000ff;
const uint32_t m8_8 = 0x0000ff00;
const uint32_t m8_16 = 0x00ff0000;
const uint32_t m8_24 = 0xff000000;
uint32_t s0 = Utils::loadBigEndian<uint32_t>(in) ^ rk[0];
uint32_t s1 = Utils::loadBigEndian<uint32_t>(in + 4) ^ rk[1];
uint32_t s2 = Utils::loadBigEndian<uint32_t>(in + 8) ^ rk[2];
uint32_t s3 = Utils::loadBigEndian<uint32_t>(in + 12) ^ rk[3];
uint32_t t0, t1, t2, t3;
t0 = Te0[s0 >> 24U] ^ Te1_r((s1 >> 16U) & m8) ^ Te2_r((s2 >> 8U) & m8) ^ Te3_r(s3 & m8) ^ rk[4];
@ -633,10 +711,14 @@ void AES::p_encryptSW(const uint8_t* in, uint8_t* out) const noexcept
t1 = Te0[s1 >> 24U] ^ Te1_r((s2 >> 16U) & m8) ^ Te2_r((s3 >> 8U) & m8) ^ Te3_r(s0 & m8) ^ rk[53];
t2 = Te0[s2 >> 24U] ^ Te1_r((s3 >> 16U) & m8) ^ Te2_r((s0 >> 8U) & m8) ^ Te3_r(s1 & m8) ^ rk[54];
t3 = Te0[s3 >> 24U] ^ Te1_r((s0 >> 16U) & m8) ^ Te2_r((s1 >> 8U) & m8) ^ Te3_r(s2 & m8) ^ rk[55];
s0 = (Te2_r(t0 >> 24U) & m8_24) ^ (Te3_r((t1 >> 16U) & m8) & m8_16) ^ (Te0[(t2 >> 8U) & m8] & m8_8) ^ (Te1_r(t3 & m8) & m8) ^ rk[56];
s1 = (Te2_r(t1 >> 24U) & m8_24) ^ (Te3_r((t2 >> 16U) & m8) & m8_16) ^ (Te0[(t3 >> 8U) & m8] & m8_8) ^ (Te1_r(t0 & m8) & m8) ^ rk[57];
s2 = (Te2_r(t2 >> 24U) & m8_24) ^ (Te3_r((t3 >> 16U) & m8) & m8_16) ^ (Te0[(t0 >> 8U) & m8] & m8_8) ^ (Te1_r(t1 & m8) & m8) ^ rk[58];
s3 = (Te2_r(t3 >> 24U) & m8_24) ^ (Te3_r((t0 >> 16U) & m8) & m8_16) ^ (Te0[(t1 >> 8U) & m8] & m8_8) ^ (Te1_r(t2 & m8) & m8) ^ rk[59];
s0 = (Te2_r(t0 >> 24U) & m8_24) ^ (Te3_r((t1 >> 16U) & m8) & m8_16) ^ (Te0[(t2 >> 8U) & m8] & m8_8)
^ (Te1_r(t3 & m8) & m8) ^ rk[56];
s1 = (Te2_r(t1 >> 24U) & m8_24) ^ (Te3_r((t2 >> 16U) & m8) & m8_16) ^ (Te0[(t3 >> 8U) & m8] & m8_8)
^ (Te1_r(t0 & m8) & m8) ^ rk[57];
s2 = (Te2_r(t2 >> 24U) & m8_24) ^ (Te3_r((t3 >> 16U) & m8) & m8_16) ^ (Te0[(t0 >> 8U) & m8] & m8_8)
^ (Te1_r(t1 & m8) & m8) ^ rk[58];
s3 = (Te2_r(t3 >> 24U) & m8_24) ^ (Te3_r((t0 >> 16U) & m8) & m8_16) ^ (Te0[(t1 >> 8U) & m8] & m8_8)
^ (Te1_r(t2 & m8) & m8) ^ rk[59];
Utils::storeBigEndian<uint32_t>(out, s0);
Utils::storeBigEndian<uint32_t>(out + 4, s1);
@ -644,14 +726,14 @@ void AES::p_encryptSW(const uint8_t* in, uint8_t* out) const noexcept
Utils::storeBigEndian<uint32_t>(out + 12, s3);
}
void AES::p_decryptSW(const uint8_t* in, uint8_t* out) const noexcept
void AES::p_decryptSW(const uint8_t *in, uint8_t *out) const noexcept
{
const uint32_t* restrict rk = p_k.sw.dk;
const uint32_t m8 = 0x000000ff;
uint32_t s0 = Utils::loadBigEndian<uint32_t>(in) ^ rk[0];
uint32_t s1 = Utils::loadBigEndian<uint32_t>(in + 4) ^ rk[1];
uint32_t s2 = Utils::loadBigEndian<uint32_t>(in + 8) ^ rk[2];
uint32_t s3 = Utils::loadBigEndian<uint32_t>(in + 12) ^ rk[3];
const uint32_t *restrict rk = p_k.sw.dk;
const uint32_t m8 = 0x000000ff;
uint32_t s0 = Utils::loadBigEndian<uint32_t>(in) ^ rk[0];
uint32_t s1 = Utils::loadBigEndian<uint32_t>(in + 4) ^ rk[1];
uint32_t s2 = Utils::loadBigEndian<uint32_t>(in + 8) ^ rk[2];
uint32_t s3 = Utils::loadBigEndian<uint32_t>(in + 12) ^ rk[3];
uint32_t t0, t1, t2, t3;
t0 = Td0[s0 >> 24U] ^ Td1_r((s3 >> 16U) & m8) ^ Td2_r((s2 >> 8U) & m8) ^ Td3_r(s1 & m8) ^ rk[4];
@ -706,10 +788,14 @@ void AES::p_decryptSW(const uint8_t* in, uint8_t* out) const noexcept
t1 = Td0[s1 >> 24U] ^ Td1_r((s0 >> 16U) & m8) ^ Td2_r((s3 >> 8U) & m8) ^ Td3_r(s2 & m8) ^ rk[53];
t2 = Td0[s2 >> 24U] ^ Td1_r((s1 >> 16U) & m8) ^ Td2_r((s0 >> 8U) & m8) ^ Td3_r(s3 & m8) ^ rk[54];
t3 = Td0[s3 >> 24U] ^ Td1_r((s2 >> 16U) & m8) ^ Td2_r((s1 >> 8U) & m8) ^ Td3_r(s0 & m8) ^ rk[55];
s0 = (Td4[t0 >> 24U] << 24U) ^ (Td4[(t3 >> 16U) & m8] << 16U) ^ (Td4[(t2 >> 8U) & m8] << 8U) ^ (Td4[(t1)&m8]) ^ rk[56];
s1 = (Td4[t1 >> 24U] << 24U) ^ (Td4[(t0 >> 16U) & m8] << 16U) ^ (Td4[(t3 >> 8U) & m8] << 8U) ^ (Td4[(t2)&m8]) ^ rk[57];
s2 = (Td4[t2 >> 24U] << 24U) ^ (Td4[(t1 >> 16U) & m8] << 16U) ^ (Td4[(t0 >> 8U) & m8] << 8U) ^ (Td4[(t3)&m8]) ^ rk[58];
s3 = (Td4[t3 >> 24U] << 24U) ^ (Td4[(t2 >> 16U) & m8] << 16U) ^ (Td4[(t1 >> 8U) & m8] << 8U) ^ (Td4[(t0)&m8]) ^ rk[59];
s0 = (Td4[t0 >> 24U] << 24U) ^ (Td4[(t3 >> 16U) & m8] << 16U) ^ (Td4[(t2 >> 8U) & m8] << 8U) ^ (Td4[(t1)&m8])
^ rk[56];
s1 = (Td4[t1 >> 24U] << 24U) ^ (Td4[(t0 >> 16U) & m8] << 16U) ^ (Td4[(t3 >> 8U) & m8] << 8U) ^ (Td4[(t2)&m8])
^ rk[57];
s2 = (Td4[t2 >> 24U] << 24U) ^ (Td4[(t1 >> 16U) & m8] << 16U) ^ (Td4[(t0 >> 8U) & m8] << 8U) ^ (Td4[(t3)&m8])
^ rk[58];
s3 = (Td4[t3 >> 24U] << 24U) ^ (Td4[(t2 >> 16U) & m8] << 16U) ^ (Td4[(t1 >> 8U) & m8] << 8U) ^ (Td4[(t0)&m8])
^ rk[59];
Utils::storeBigEndian<uint32_t>(out, s0);
Utils::storeBigEndian<uint32_t>(out + 4, s1);

View file

@ -21,10 +21,10 @@
// Uncomment to disable all hardware acceleration (usually for testing)
//#define ZT_AES_NO_ACCEL
#if ! defined(ZT_AES_NO_ACCEL) && defined(ZT_ARCH_X64)
#if !defined(ZT_AES_NO_ACCEL) && defined(ZT_ARCH_X64)
#define ZT_AES_AESNI 1
#endif
#if ! defined(ZT_AES_NO_ACCEL) && defined(ZT_ARCH_ARM_HAS_NEON)
#if !defined(ZT_AES_NO_ACCEL) && defined(ZT_ARCH_ARM_HAS_NEON)
#define ZT_AES_NEON 1
#endif
@ -62,45 +62,37 @@ class AES {
/**
* Create an un-initialized AES instance (must call init() before use)
*/
ZT_INLINE AES() noexcept
{
}
ZT_INLINE AES() noexcept {}
/**
* Create an AES instance with the given key
*
* @param key 256-bit key
*/
explicit ZT_INLINE AES(const void* const key) noexcept
{
this->init(key);
}
explicit ZT_INLINE AES(const void *const key) noexcept { this->init(key); }
ZT_INLINE ~AES()
{
Utils::burn(&p_k, sizeof(p_k));
}
ZT_INLINE ~AES() { Utils::burn(&p_k, sizeof(p_k)); }
/**
* Set (or re-set) this AES256 cipher's key
*
* @param key 256-bit / 32-byte key
*/
ZT_INLINE void init(const void* const key) noexcept
ZT_INLINE void init(const void *const key) noexcept
{
#ifdef ZT_AES_AESNI
if (likely(Utils::CPUID.aes)) {
p_init_aesni(reinterpret_cast<const uint8_t*>(key));
p_init_aesni(reinterpret_cast<const uint8_t *>(key));
return;
}
#endif
#ifdef ZT_AES_NEON
if (Utils::ARMCAP.aes) {
p_init_armneon_crypto(reinterpret_cast<const uint8_t*>(key));
p_init_armneon_crypto(reinterpret_cast<const uint8_t *>(key));
return;
}
#endif
p_initSW(reinterpret_cast<const uint8_t*>(key));
p_initSW(reinterpret_cast<const uint8_t *>(key));
}
/**
@ -109,7 +101,7 @@ class AES {
* @param in Input block
* @param out Output block (can be same as input)
*/
ZT_INLINE void encrypt(const void* const in, void* const out) const noexcept
ZT_INLINE void encrypt(const void *const in, void *const out) const noexcept
{
#ifdef ZT_AES_AESNI
if (likely(Utils::CPUID.aes)) {
@ -123,7 +115,7 @@ class AES {
return;
}
#endif
p_encryptSW(reinterpret_cast<const uint8_t*>(in), reinterpret_cast<uint8_t*>(out));
p_encryptSW(reinterpret_cast<const uint8_t *>(in), reinterpret_cast<uint8_t *>(out));
}
/**
@ -132,7 +124,7 @@ class AES {
* @param in Input block
* @param out Output block (can be same as input)
*/
ZT_INLINE void decrypt(const void* const in, void* const out) const noexcept
ZT_INLINE void decrypt(const void *const in, void *const out) const noexcept
{
#ifdef ZT_AES_AESNI
if (likely(Utils::CPUID.aes)) {
@ -146,7 +138,7 @@ class AES {
return;
}
#endif
p_decryptSW(reinterpret_cast<const uint8_t*>(in), reinterpret_cast<uint8_t*>(out));
p_decryptSW(reinterpret_cast<const uint8_t *>(in), reinterpret_cast<uint8_t *>(out));
}
class GMACSIVEncryptor;
@ -181,9 +173,7 @@ class AES {
*
* @param aes Keyed AES instance to use
*/
ZT_INLINE GMAC(const AES& aes) : _aes(aes)
{
}
ZT_INLINE GMAC(const AES &aes) : _aes(aes) {}
/**
* Reset and initialize for a new GMAC calculation
@ -192,16 +182,16 @@ class AES {
*/
ZT_INLINE void init(const uint8_t iv[12]) noexcept
{
_rp = 0;
_rp = 0;
_len = 0;
// We fill the least significant 32 bits in the _iv field with 1 since in GCM mode
// this would hold the counter, but we're not doing GCM just GMAC. That means the
// counter always stays just 1.
#ifdef ZT_AES_AESNI // also implies an x64 processor
*reinterpret_cast<uint64_t*>(_iv) = *reinterpret_cast<const uint64_t*>(iv);
*reinterpret_cast<uint32_t*>(_iv + 8) = *reinterpret_cast<const uint64_t*>(iv + 8);
*reinterpret_cast<uint32_t*>(_iv + 12) = 0x01000000; // 0x00000001 in big-endian byte order
*reinterpret_cast<uint64_t *>(_iv) = *reinterpret_cast<const uint64_t *>(iv);
*reinterpret_cast<uint32_t *>(_iv + 8) = *reinterpret_cast<const uint64_t *>(iv + 8);
*reinterpret_cast<uint32_t *>(_iv + 12) = 0x01000000; // 0x00000001 in big-endian byte order
#else
Utils::copy<12>(_iv, iv);
_iv[12] = 0;
@ -220,7 +210,7 @@ class AES {
* @param data Bytes to process
* @param len Length of input
*/
void update(const void* data, unsigned int len) noexcept;
void update(const void *data, unsigned int len) noexcept;
/**
* Process any remaining cached bytes and generate tag
@ -233,14 +223,14 @@ class AES {
private:
#ifdef ZT_AES_AESNI
void p_aesNIUpdate(const uint8_t* in, unsigned int len) noexcept;
void p_aesNIUpdate(const uint8_t *in, unsigned int len) noexcept;
void p_aesNIFinish(uint8_t tag[16]) noexcept;
#endif
#ifdef ZT_AES_NEON
void p_armUpdate(const uint8_t* in, unsigned int len) noexcept;
void p_armUpdate(const uint8_t *in, unsigned int len) noexcept;
void p_armFinish(uint8_t tag[16]) noexcept;
#endif
const AES& _aes;
const AES &_aes;
unsigned int _rp;
unsigned int _len;
uint8_t _r[16]; // remainder
@ -260,9 +250,7 @@ class AES {
friend class GMACSIVDecryptor;
public:
ZT_INLINE CTR(const AES& aes) noexcept : _aes(aes)
{
}
ZT_INLINE CTR(const AES &aes) noexcept : _aes(aes) {}
/**
* Initialize this CTR instance to encrypt a new stream
@ -270,10 +258,10 @@ class AES {
* @param iv Unique initialization vector and initial 32-bit counter (least significant 32 bits, big-endian)
* @param output Buffer to which to store output (MUST be large enough for total bytes processed!)
*/
ZT_INLINE void init(const uint8_t iv[16], void* const output) noexcept
ZT_INLINE void init(const uint8_t iv[16], void *const output) noexcept
{
Utils::copy<16>(_ctr, iv);
_out = reinterpret_cast<uint8_t*>(output);
_out = reinterpret_cast<uint8_t *>(output);
_len = 0;
}
@ -284,12 +272,12 @@ class AES {
* @param ic Initial counter (must be in big-endian byte order!)
* @param output Buffer to which to store output (MUST be large enough for total bytes processed!)
*/
ZT_INLINE void init(const uint8_t iv[12], const uint32_t ic, void* const output) noexcept
ZT_INLINE void init(const uint8_t iv[12], const uint32_t ic, void *const output) noexcept
{
Utils::copy<12>(_ctr, iv);
reinterpret_cast<uint32_t*>(_ctr)[3] = ic;
_out = reinterpret_cast<uint8_t*>(output);
_len = 0;
reinterpret_cast<uint32_t *>(_ctr)[3] = ic;
_out = reinterpret_cast<uint8_t *>(output);
_len = 0;
}
/**
@ -298,7 +286,7 @@ class AES {
* @param input Input data
* @param len Length of input
*/
void crypt(const void* input, unsigned int len) noexcept;
void crypt(const void *input, unsigned int len) noexcept;
/**
* Finish any remaining bytes if total bytes processed wasn't a multiple of 16
@ -309,14 +297,14 @@ class AES {
private:
#ifdef ZT_AES_AESNI
void p_aesNICrypt(const uint8_t* in, uint8_t* out, unsigned int len) noexcept;
void p_aesNICrypt(const uint8_t *in, uint8_t *out, unsigned int len) noexcept;
#endif
#ifdef ZT_AES_NEON
void p_armCrypt(const uint8_t* in, uint8_t* out, unsigned int len) noexcept;
void p_armCrypt(const uint8_t *in, uint8_t *out, unsigned int len) noexcept;
#endif
const AES& _aes;
const AES &_aes;
uint64_t _ctr[2];
uint8_t* _out;
uint8_t *_out;
unsigned int _len;
};
@ -339,11 +327,7 @@ class AES {
* @param k0 First of two AES instances keyed with K0
* @param k1 Second of two AES instances keyed with K1
*/
ZT_INLINE GMACSIVEncryptor(const AES& k0, const AES& k1) noexcept
: _gmac(k0)
, _ctr(k1)
{
}
ZT_INLINE GMACSIVEncryptor(const AES &k0, const AES &k1) noexcept : _gmac(k0), _ctr(k1) {}
/**
* Initialize AES-GMAC-SIV
@ -351,7 +335,7 @@ class AES {
* @param iv IV in network byte order (byte order in which it will appear on the wire)
* @param output Pointer to buffer to receive ciphertext, must be large enough for all to-be-processed data!
*/
ZT_INLINE void init(const uint64_t iv, void* const output) noexcept
ZT_INLINE void init(const uint64_t iv, void *const output) noexcept
{
// Output buffer to receive the result of AES-CTR encryption.
_output = output;
@ -359,7 +343,7 @@ class AES {
// Initialize GMAC with 64-bit IV (and remaining 32 bits padded to zero).
_tag[0] = iv;
_tag[1] = 0;
_gmac.init(reinterpret_cast<const uint8_t*>(_tag));
_gmac.init(reinterpret_cast<const uint8_t *>(_tag));
}
/**
@ -372,7 +356,7 @@ class AES {
* @param aad Additional authenticated data
* @param len Length of AAD in bytes
*/
ZT_INLINE void aad(const void* const aad, unsigned int len) noexcept
ZT_INLINE void aad(const void *const aad, unsigned int len) noexcept
{
// Feed ADD into GMAC first
_gmac.update(aad, len);
@ -389,10 +373,7 @@ class AES {
* @param input Plaintext chunk
* @param len Length of plaintext chunk
*/
ZT_INLINE void update1(const void* const input, const unsigned int len) noexcept
{
_gmac.update(input, len);
}
ZT_INLINE void update1(const void *const input, const unsigned int len) noexcept { _gmac.update(input, len); }
/**
* Finish first pass, compute CTR IV, initialize second pass.
@ -401,7 +382,7 @@ class AES {
{
// Compute 128-bit GMAC tag.
uint64_t tmp[2];
_gmac.finish(reinterpret_cast<uint8_t*>(tmp));
_gmac.finish(reinterpret_cast<uint8_t *>(tmp));
// Shorten to 64 bits, concatenate with message IV, and encrypt with AES to
// yield the CTR IV and opaque IV/MAC blob. In ZeroTier's use of GMAC-SIV
@ -421,7 +402,7 @@ class AES {
// and so 2^31 should be considered the input limit.
tmp[0] = _tag[0];
tmp[1] = _tag[1] & ZT_CONST_TO_BE_UINT64(0xffffffff7fffffffULL);
_ctr.init(reinterpret_cast<const uint8_t*>(tmp), _output);
_ctr.init(reinterpret_cast<const uint8_t *>(tmp), _output);
}
/**
@ -434,10 +415,7 @@ class AES {
* @param input Plaintext chunk
* @param len Length of plaintext chunk
*/
ZT_INLINE void update2(const void* const input, const unsigned int len) noexcept
{
_ctr.crypt(input, len);
}
ZT_INLINE void update2(const void *const input, const unsigned int len) noexcept { _ctr.crypt(input, len); }
/**
* Finish second pass and return a pointer to the opaque 128-bit IV+MAC block
@ -447,14 +425,14 @@ class AES {
*
* @return Pointer to 128-bit opaque IV+MAC (packed into two 64-bit integers)
*/
ZT_INLINE const uint64_t* finish2()
ZT_INLINE const uint64_t *finish2()
{
_ctr.finish();
return _tag;
}
private:
void* _output;
void *_output;
uint64_t _tag[2];
AES::GMAC _gmac;
AES::CTR _ctr;
@ -467,11 +445,7 @@ class AES {
*/
class GMACSIVDecryptor {
public:
ZT_INLINE GMACSIVDecryptor(const AES& k0, const AES& k1) noexcept
: _ctr(k1)
, _gmac(k0)
{
}
ZT_INLINE GMACSIVDecryptor(const AES &k0, const AES &k1) noexcept : _ctr(k1), _gmac(k0) {}
/**
* Initialize decryptor for a new message
@ -479,20 +453,20 @@ class AES {
* @param tag 128-bit combined IV/MAC originally created by GMAC-SIV encryption
* @param output Buffer in which to write output plaintext (must be large enough!)
*/
ZT_INLINE void init(const uint64_t tag[2], void* const output) noexcept
ZT_INLINE void init(const uint64_t tag[2], void *const output) noexcept
{
uint64_t tmp[2];
tmp[0] = tag[0];
tmp[1] = tag[1] & ZT_CONST_TO_BE_UINT64(0xffffffff7fffffffULL);
_ctr.init(reinterpret_cast<const uint8_t*>(tmp), output);
_ctr.init(reinterpret_cast<const uint8_t *>(tmp), output);
_ctr._aes.decrypt(tag, _ivMac);
tmp[0] = _ivMac[0];
tmp[1] = 0;
_gmac.init(reinterpret_cast<const uint8_t*>(tmp));
_gmac.init(reinterpret_cast<const uint8_t *>(tmp));
_output = output;
_output = output;
_decryptedLen = 0;
}
@ -502,7 +476,7 @@ class AES {
* @param aad Additional authenticated data
* @param len Length of AAD in bytes
*/
ZT_INLINE void aad(const void* const aad, unsigned int len) noexcept
ZT_INLINE void aad(const void *const aad, unsigned int len) noexcept
{
_gmac.update(aad, len);
len &= 0xfU;
@ -518,7 +492,7 @@ class AES {
* @param input Input ciphertext
* @param len Length of ciphertext
*/
ZT_INLINE void update(const void* const input, const unsigned int len) noexcept
ZT_INLINE void update(const void *const input, const unsigned int len) noexcept
{
_ctr.crypt(input, len);
_decryptedLen += len;
@ -535,7 +509,7 @@ class AES {
uint64_t gmacTag[2];
_gmac.update(_output, _decryptedLen);
_gmac.finish(reinterpret_cast<uint8_t*>(gmacTag));
_gmac.finish(reinterpret_cast<uint8_t *>(gmacTag));
return (gmacTag[0] ^ gmacTag[1]) == _ivMac[1];
}
@ -543,7 +517,7 @@ class AES {
uint64_t _ivMac[2];
AES::CTR _ctr;
AES::GMAC _gmac;
void* _output;
void *_output;
unsigned int _decryptedLen;
};
@ -554,9 +528,9 @@ class AES {
static const uint8_t Td4[256];
static const uint32_t rcon[15];
void p_initSW(const uint8_t* key) noexcept;
void p_encryptSW(const uint8_t* in, uint8_t* out) const noexcept;
void p_decryptSW(const uint8_t* in, uint8_t* out) const noexcept;
void p_initSW(const uint8_t *key) noexcept;
void p_encryptSW(const uint8_t *in, uint8_t *out) const noexcept;
void p_decryptSW(const uint8_t *in, uint8_t *out) const noexcept;
union {
#ifdef ZT_AES_AESNI
@ -584,15 +558,15 @@ class AES {
} p_k;
#ifdef ZT_AES_AESNI
void p_init_aesni(const uint8_t* key) noexcept;
void p_encrypt_aesni(const void* in, void* out) const noexcept;
void p_decrypt_aesni(const void* in, void* out) const noexcept;
void p_init_aesni(const uint8_t *key) noexcept;
void p_encrypt_aesni(const void *in, void *out) const noexcept;
void p_decrypt_aesni(const void *in, void *out) const noexcept;
#endif
#ifdef ZT_AES_NEON
void p_init_armneon_crypto(const uint8_t* key) noexcept;
void p_encrypt_armneon_crypto(const void* in, void* out) const noexcept;
void p_decrypt_armneon_crypto(const void* in, void* out) const noexcept;
void p_init_armneon_crypto(const uint8_t *key) noexcept;
void p_encrypt_armneon_crypto(const void *in, void *out) const noexcept;
void p_decrypt_armneon_crypto(const void *in, void *out) const noexcept;
#endif
};

View file

@ -35,22 +35,27 @@ __attribute__((__target__("ssse3,sse4,sse4.1,sse4.2,pclmul")))
__m128i
p_gmacPCLMUL128(const __m128i h, __m128i y) noexcept
{
y = _mm_shuffle_epi8(y, s_sseSwapBytes);
y = _mm_shuffle_epi8(y, s_sseSwapBytes);
__m128i t1 = _mm_clmulepi64_si128(h, y, 0x00);
__m128i t2 = _mm_clmulepi64_si128(h, y, 0x01);
__m128i t3 = _mm_clmulepi64_si128(h, y, 0x10);
__m128i t4 = _mm_clmulepi64_si128(h, y, 0x11);
t2 = _mm_xor_si128(t2, t3);
t3 = _mm_slli_si128(t2, 8);
t2 = _mm_srli_si128(t2, 8);
t1 = _mm_xor_si128(t1, t3);
t4 = _mm_xor_si128(t4, t2);
t2 = _mm_xor_si128(t2, t3);
t3 = _mm_slli_si128(t2, 8);
t2 = _mm_srli_si128(t2, 8);
t1 = _mm_xor_si128(t1, t3);
t4 = _mm_xor_si128(t4, t2);
__m128i t5 = _mm_srli_epi32(t1, 31);
t1 = _mm_or_si128(_mm_slli_epi32(t1, 1), _mm_slli_si128(t5, 4));
t4 = _mm_or_si128(_mm_or_si128(_mm_slli_epi32(t4, 1), _mm_slli_si128(_mm_srli_epi32(t4, 31), 4)), _mm_srli_si128(t5, 12));
t1 = _mm_or_si128(_mm_slli_epi32(t1, 1), _mm_slli_si128(t5, 4));
t4 = _mm_or_si128(
_mm_or_si128(_mm_slli_epi32(t4, 1), _mm_slli_si128(_mm_srli_epi32(t4, 31), 4)), _mm_srli_si128(t5, 12));
t5 = _mm_xor_si128(_mm_xor_si128(_mm_slli_epi32(t1, 31), _mm_slli_epi32(t1, 30)), _mm_slli_epi32(t1, 25));
t1 = _mm_xor_si128(t1, _mm_slli_si128(t5, 12));
t4 = _mm_xor_si128(_mm_xor_si128(_mm_xor_si128(_mm_xor_si128(_mm_xor_si128(t4, _mm_srli_si128(t5, 4)), t1), _mm_srli_epi32(t1, 2)), _mm_srli_epi32(t1, 7)), _mm_srli_epi32(t1, 1));
t4 = _mm_xor_si128(
_mm_xor_si128(
_mm_xor_si128(_mm_xor_si128(_mm_xor_si128(t4, _mm_srli_si128(t5, 4)), t1), _mm_srli_epi32(t1, 2)),
_mm_srli_epi32(t1, 7)),
_mm_srli_epi32(t1, 1));
return _mm_shuffle_epi8(t4, s_sseSwapBytes);
}
@ -59,7 +64,7 @@ p_gmacPCLMUL128(const __m128i h, __m128i y) noexcept
* The performance gain can be significant but regular SSE is already so
* fast it's highly unlikely to be a rate limiting factor except on massive
* servers and network infrastructure stuff. */
#if ! defined(__WINDOWS__) && ((__GNUC__ >= 8) || (__clang_major__ >= 7))
#if !defined(__WINDOWS__) && ((__GNUC__ >= 8) || (__clang_major__ >= 7))
#define ZT_AES_VAES512 1
@ -68,24 +73,26 @@ __attribute__((__target__("sse4,aes,avx,avx2,vaes,avx512f,avx512bw")))
#endif
void p_aesCtrInnerVAES512(unsigned int &len, const uint64_t c0, uint64_t &c1, const uint8_t *&in, uint8_t *&out, const __m128i *const k) noexcept
{
const __m512i kk0 = _mm512_broadcast_i32x4(k[0]);
const __m512i kk1 = _mm512_broadcast_i32x4(k[1]);
const __m512i kk2 = _mm512_broadcast_i32x4(k[2]);
const __m512i kk3 = _mm512_broadcast_i32x4(k[3]);
const __m512i kk4 = _mm512_broadcast_i32x4(k[4]);
const __m512i kk5 = _mm512_broadcast_i32x4(k[5]);
const __m512i kk6 = _mm512_broadcast_i32x4(k[6]);
const __m512i kk7 = _mm512_broadcast_i32x4(k[7]);
const __m512i kk8 = _mm512_broadcast_i32x4(k[8]);
const __m512i kk9 = _mm512_broadcast_i32x4(k[9]);
const __m512i kk0 = _mm512_broadcast_i32x4(k[0]);
const __m512i kk1 = _mm512_broadcast_i32x4(k[1]);
const __m512i kk2 = _mm512_broadcast_i32x4(k[2]);
const __m512i kk3 = _mm512_broadcast_i32x4(k[3]);
const __m512i kk4 = _mm512_broadcast_i32x4(k[4]);
const __m512i kk5 = _mm512_broadcast_i32x4(k[5]);
const __m512i kk6 = _mm512_broadcast_i32x4(k[6]);
const __m512i kk7 = _mm512_broadcast_i32x4(k[7]);
const __m512i kk8 = _mm512_broadcast_i32x4(k[8]);
const __m512i kk9 = _mm512_broadcast_i32x4(k[9]);
const __m512i kk10 = _mm512_broadcast_i32x4(k[10]);
const __m512i kk11 = _mm512_broadcast_i32x4(k[11]);
const __m512i kk12 = _mm512_broadcast_i32x4(k[12]);
const __m512i kk13 = _mm512_broadcast_i32x4(k[13]);
const __m512i kk14 = _mm512_broadcast_i32x4(k[14]);
do {
__m512i p0 = _mm512_loadu_si512(reinterpret_cast<const __m512i*>(in));
__m512i d0 = _mm512_set_epi64((long long)Utils::hton(c1 + 3ULL), (long long)c0, (long long)Utils::hton(c1 + 2ULL), (long long)c0, (long long)Utils::hton(c1 + 1ULL), (long long)c0, (long long)Utils::hton(c1), (long long)c0);
__m512i p0 = _mm512_loadu_si512(reinterpret_cast<const __m512i *>(in));
__m512i d0 = _mm512_set_epi64(
(long long)Utils::hton(c1 + 3ULL), (long long)c0, (long long)Utils::hton(c1 + 2ULL), (long long)c0,
(long long)Utils::hton(c1 + 1ULL), (long long)c0, (long long)Utils::hton(c1), (long long)c0);
c1 += 4;
in += 64;
len -= 64;
@ -104,7 +111,7 @@ void p_aesCtrInnerVAES512(unsigned int &len, const uint64_t c0, uint64_t &c1, co
d0 = _mm512_aesenc_epi128(d0, kk12);
d0 = _mm512_aesenc_epi128(d0, kk13);
d0 = _mm512_aesenclast_epi128(d0, kk14);
_mm512_storeu_si512(reinterpret_cast<__m512i*>(out), _mm512_xor_si512(p0, d0));
_mm512_storeu_si512(reinterpret_cast<__m512i *>(out), _mm512_xor_si512(p0, d0));
out += 64;
} while (likely(len >= 64));
}
@ -116,26 +123,28 @@ __attribute__((__target__("sse4,aes,avx,avx2,vaes")))
#endif
void p_aesCtrInnerVAES256(unsigned int &len, const uint64_t c0, uint64_t &c1, const uint8_t *&in, uint8_t *&out, const __m128i *const k) noexcept
{
const __m256i kk0 = _mm256_broadcastsi128_si256(k[0]);
const __m256i kk1 = _mm256_broadcastsi128_si256(k[1]);
const __m256i kk2 = _mm256_broadcastsi128_si256(k[2]);
const __m256i kk3 = _mm256_broadcastsi128_si256(k[3]);
const __m256i kk4 = _mm256_broadcastsi128_si256(k[4]);
const __m256i kk5 = _mm256_broadcastsi128_si256(k[5]);
const __m256i kk6 = _mm256_broadcastsi128_si256(k[6]);
const __m256i kk7 = _mm256_broadcastsi128_si256(k[7]);
const __m256i kk8 = _mm256_broadcastsi128_si256(k[8]);
const __m256i kk9 = _mm256_broadcastsi128_si256(k[9]);
const __m256i kk0 = _mm256_broadcastsi128_si256(k[0]);
const __m256i kk1 = _mm256_broadcastsi128_si256(k[1]);
const __m256i kk2 = _mm256_broadcastsi128_si256(k[2]);
const __m256i kk3 = _mm256_broadcastsi128_si256(k[3]);
const __m256i kk4 = _mm256_broadcastsi128_si256(k[4]);
const __m256i kk5 = _mm256_broadcastsi128_si256(k[5]);
const __m256i kk6 = _mm256_broadcastsi128_si256(k[6]);
const __m256i kk7 = _mm256_broadcastsi128_si256(k[7]);
const __m256i kk8 = _mm256_broadcastsi128_si256(k[8]);
const __m256i kk9 = _mm256_broadcastsi128_si256(k[9]);
const __m256i kk10 = _mm256_broadcastsi128_si256(k[10]);
const __m256i kk11 = _mm256_broadcastsi128_si256(k[11]);
const __m256i kk12 = _mm256_broadcastsi128_si256(k[12]);
const __m256i kk13 = _mm256_broadcastsi128_si256(k[13]);
const __m256i kk14 = _mm256_broadcastsi128_si256(k[14]);
do {
__m256i p0 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(in));
__m256i p1 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(in + 32));
__m256i d0 = _mm256_set_epi64x((long long)Utils::hton(c1 + 1ULL), (long long)c0, (long long)Utils::hton(c1), (long long)c0);
__m256i d1 = _mm256_set_epi64x((long long)Utils::hton(c1 + 3ULL), (long long)c0, (long long)Utils::hton(c1 + 2ULL), (long long)c0);
__m256i p0 = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(in));
__m256i p1 = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(in + 32));
__m256i d0 = _mm256_set_epi64x(
(long long)Utils::hton(c1 + 1ULL), (long long)c0, (long long)Utils::hton(c1), (long long)c0);
__m256i d1 = _mm256_set_epi64x(
(long long)Utils::hton(c1 + 3ULL), (long long)c0, (long long)Utils::hton(c1 + 2ULL), (long long)c0);
c1 += 4;
in += 64;
len -= 64;
@ -169,8 +178,8 @@ void p_aesCtrInnerVAES256(unsigned int &len, const uint64_t c0, uint64_t &c1, co
d1 = _mm256_aesenc_epi128(d1, kk13);
d0 = _mm256_aesenclast_epi128(d0, kk14);
d1 = _mm256_aesenclast_epi128(d1, kk14);
_mm256_storeu_si256(reinterpret_cast<__m256i*>(out), _mm256_xor_si256(d0, p0));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(out + 32), _mm256_xor_si256(d1, p1));
_mm256_storeu_si256(reinterpret_cast<__m256i *>(out), _mm256_xor_si256(d0, p0));
_mm256_storeu_si256(reinterpret_cast<__m256i *>(out + 32), _mm256_xor_si256(d1, p1));
out += 64;
} while (likely(len >= 64));
}
@ -221,66 +230,80 @@ __attribute__((__target__("ssse3,sse4,sse4.1,sse4.2,pclmul")))
#endif
void AES::GMAC::p_aesNIUpdate(const uint8_t *in, unsigned int len) noexcept
{
__m128i y = _mm_loadu_si128(reinterpret_cast<const __m128i*>(_y));
__m128i y = _mm_loadu_si128(reinterpret_cast<const __m128i *>(_y));
// Handle anything left over from a previous run that wasn't a multiple of 16 bytes.
if (_rp) {
for (;;) {
if (! len)
if (!len)
return;
--len;
_r[_rp++] = *(in++);
if (_rp == 16) {
y = p_gmacPCLMUL128(_aes.p_k.ni.h[0], _mm_xor_si128(y, _mm_loadu_si128(reinterpret_cast<__m128i*>(_r))));
y = p_gmacPCLMUL128(
_aes.p_k.ni.h[0], _mm_xor_si128(y, _mm_loadu_si128(reinterpret_cast<__m128i *>(_r))));
break;
}
}
}
if (likely(len >= 64)) {
const __m128i sb = s_sseSwapBytes;
const __m128i h = _aes.p_k.ni.h[0];
const __m128i hh = _aes.p_k.ni.h[1];
const __m128i hhh = _aes.p_k.ni.h[2];
const __m128i hhhh = _aes.p_k.ni.h[3];
const __m128i h2 = _aes.p_k.ni.h2[0];
const __m128i hh2 = _aes.p_k.ni.h2[1];
const __m128i hhh2 = _aes.p_k.ni.h2[2];
const __m128i hhhh2 = _aes.p_k.ni.h2[3];
const uint8_t* const end64 = in + (len & ~((unsigned int)63));
const __m128i sb = s_sseSwapBytes;
const __m128i h = _aes.p_k.ni.h[0];
const __m128i hh = _aes.p_k.ni.h[1];
const __m128i hhh = _aes.p_k.ni.h[2];
const __m128i hhhh = _aes.p_k.ni.h[3];
const __m128i h2 = _aes.p_k.ni.h2[0];
const __m128i hh2 = _aes.p_k.ni.h2[1];
const __m128i hhh2 = _aes.p_k.ni.h2[2];
const __m128i hhhh2 = _aes.p_k.ni.h2[3];
const uint8_t *const end64 = in + (len & ~((unsigned int)63));
len &= 63U;
do {
__m128i d1 = _mm_shuffle_epi8(_mm_xor_si128(y, _mm_loadu_si128(reinterpret_cast<const __m128i*>(in))), sb);
__m128i d2 = _mm_shuffle_epi8(_mm_loadu_si128(reinterpret_cast<const __m128i*>(in + 16)), sb);
__m128i d3 = _mm_shuffle_epi8(_mm_loadu_si128(reinterpret_cast<const __m128i*>(in + 32)), sb);
__m128i d4 = _mm_shuffle_epi8(_mm_loadu_si128(reinterpret_cast<const __m128i*>(in + 48)), sb);
__m128i d1 = _mm_shuffle_epi8(_mm_xor_si128(y, _mm_loadu_si128(reinterpret_cast<const __m128i *>(in))), sb);
__m128i d2 = _mm_shuffle_epi8(_mm_loadu_si128(reinterpret_cast<const __m128i *>(in + 16)), sb);
__m128i d3 = _mm_shuffle_epi8(_mm_loadu_si128(reinterpret_cast<const __m128i *>(in + 32)), sb);
__m128i d4 = _mm_shuffle_epi8(_mm_loadu_si128(reinterpret_cast<const __m128i *>(in + 48)), sb);
in += 64;
__m128i a = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(hhhh, d1, 0x00), _mm_clmulepi64_si128(hhh, d2, 0x00)), _mm_xor_si128(_mm_clmulepi64_si128(hh, d3, 0x00), _mm_clmulepi64_si128(h, d4, 0x00)));
__m128i b = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(hhhh, d1, 0x11), _mm_clmulepi64_si128(hhh, d2, 0x11)), _mm_xor_si128(_mm_clmulepi64_si128(hh, d3, 0x11), _mm_clmulepi64_si128(h, d4, 0x11)));
__m128i a = _mm_xor_si128(
_mm_xor_si128(_mm_clmulepi64_si128(hhhh, d1, 0x00), _mm_clmulepi64_si128(hhh, d2, 0x00)),
_mm_xor_si128(_mm_clmulepi64_si128(hh, d3, 0x00), _mm_clmulepi64_si128(h, d4, 0x00)));
__m128i b = _mm_xor_si128(
_mm_xor_si128(_mm_clmulepi64_si128(hhhh, d1, 0x11), _mm_clmulepi64_si128(hhh, d2, 0x11)),
_mm_xor_si128(_mm_clmulepi64_si128(hh, d3, 0x11), _mm_clmulepi64_si128(h, d4, 0x11)));
__m128i c = _mm_xor_si128(
_mm_xor_si128(
_mm_xor_si128(_mm_clmulepi64_si128(hhhh2, _mm_xor_si128(_mm_shuffle_epi32(d1, 78), d1), 0x00), _mm_clmulepi64_si128(hhh2, _mm_xor_si128(_mm_shuffle_epi32(d2, 78), d2), 0x00)),
_mm_xor_si128(_mm_clmulepi64_si128(hh2, _mm_xor_si128(_mm_shuffle_epi32(d3, 78), d3), 0x00), _mm_clmulepi64_si128(h2, _mm_xor_si128(_mm_shuffle_epi32(d4, 78), d4), 0x00))),
_mm_xor_si128(
_mm_clmulepi64_si128(hhhh2, _mm_xor_si128(_mm_shuffle_epi32(d1, 78), d1), 0x00),
_mm_clmulepi64_si128(hhh2, _mm_xor_si128(_mm_shuffle_epi32(d2, 78), d2), 0x00)),
_mm_xor_si128(
_mm_clmulepi64_si128(hh2, _mm_xor_si128(_mm_shuffle_epi32(d3, 78), d3), 0x00),
_mm_clmulepi64_si128(h2, _mm_xor_si128(_mm_shuffle_epi32(d4, 78), d4), 0x00))),
_mm_xor_si128(a, b));
a = _mm_xor_si128(_mm_slli_si128(c, 8), a);
b = _mm_xor_si128(_mm_srli_si128(c, 8), b);
c = _mm_srli_epi32(a, 31);
a = _mm_or_si128(_mm_slli_epi32(a, 1), _mm_slli_si128(c, 4));
b = _mm_or_si128(_mm_or_si128(_mm_slli_epi32(b, 1), _mm_slli_si128(_mm_srli_epi32(b, 31), 4)), _mm_srli_si128(c, 12));
b = _mm_or_si128(
_mm_or_si128(_mm_slli_epi32(b, 1), _mm_slli_si128(_mm_srli_epi32(b, 31), 4)), _mm_srli_si128(c, 12));
c = _mm_xor_si128(_mm_slli_epi32(a, 31), _mm_xor_si128(_mm_slli_epi32(a, 30), _mm_slli_epi32(a, 25)));
a = _mm_xor_si128(a, _mm_slli_si128(c, 12));
b = _mm_xor_si128(b, _mm_xor_si128(a, _mm_xor_si128(_mm_xor_si128(_mm_srli_epi32(a, 1), _mm_srli_si128(c, 4)), _mm_xor_si128(_mm_srli_epi32(a, 2), _mm_srli_epi32(a, 7)))));
b = _mm_xor_si128(
b, _mm_xor_si128(
a, _mm_xor_si128(
_mm_xor_si128(_mm_srli_epi32(a, 1), _mm_srli_si128(c, 4)),
_mm_xor_si128(_mm_srli_epi32(a, 2), _mm_srli_epi32(a, 7)))));
y = _mm_shuffle_epi8(b, sb);
} while (likely(in != end64));
}
while (len >= 16) {
y = p_gmacPCLMUL128(_aes.p_k.ni.h[0], _mm_xor_si128(y, _mm_loadu_si128(reinterpret_cast<const __m128i*>(in))));
y = p_gmacPCLMUL128(_aes.p_k.ni.h[0], _mm_xor_si128(y, _mm_loadu_si128(reinterpret_cast<const __m128i *>(in))));
in += 16;
len -= 16;
}
_mm_storeu_si128(reinterpret_cast<__m128i*>(_y), y);
_mm_storeu_si128(reinterpret_cast<__m128i *>(_y), y);
// Any overflow is cached for a later run or finish().
for (unsigned int i = 0; i < len; ++i)
@ -293,72 +316,72 @@ __attribute__((__target__("ssse3,sse4,sse4.1,sse4.2,pclmul,aes")))
#endif
void AES::GMAC::p_aesNIFinish(uint8_t tag[16]) noexcept
{
__m128i y = _mm_loadu_si128(reinterpret_cast<const __m128i*>(_y));
__m128i y = _mm_loadu_si128(reinterpret_cast<const __m128i *>(_y));
// Handle any remaining bytes, padding the last block with zeroes.
if (_rp) {
while (_rp < 16)
_r[_rp++] = 0;
y = p_gmacPCLMUL128(_aes.p_k.ni.h[0], _mm_xor_si128(y, _mm_loadu_si128(reinterpret_cast<__m128i*>(_r))));
y = p_gmacPCLMUL128(_aes.p_k.ni.h[0], _mm_xor_si128(y, _mm_loadu_si128(reinterpret_cast<__m128i *>(_r))));
}
// Interleave encryption of IV with the final GHASH of y XOR (length * 8).
// Then XOR these together to get the final tag.
const __m128i* const k = _aes.p_k.ni.k;
const __m128i h = _aes.p_k.ni.h[0];
y = _mm_xor_si128(y, _mm_set_epi64x(0LL, (long long)Utils::hton((uint64_t)_len << 3U)));
y = _mm_shuffle_epi8(y, s_sseSwapBytes);
__m128i encIV = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(_iv)), k[0]);
__m128i t1 = _mm_clmulepi64_si128(h, y, 0x00);
__m128i t2 = _mm_clmulepi64_si128(h, y, 0x01);
__m128i t3 = _mm_clmulepi64_si128(h, y, 0x10);
__m128i t4 = _mm_clmulepi64_si128(h, y, 0x11);
encIV = _mm_aesenc_si128(encIV, k[1]);
t2 = _mm_xor_si128(t2, t3);
t3 = _mm_slli_si128(t2, 8);
encIV = _mm_aesenc_si128(encIV, k[2]);
t2 = _mm_srli_si128(t2, 8);
t1 = _mm_xor_si128(t1, t3);
encIV = _mm_aesenc_si128(encIV, k[3]);
t4 = _mm_xor_si128(t4, t2);
__m128i t5 = _mm_srli_epi32(t1, 31);
t1 = _mm_slli_epi32(t1, 1);
__m128i t6 = _mm_srli_epi32(t4, 31);
encIV = _mm_aesenc_si128(encIV, k[4]);
t4 = _mm_slli_epi32(t4, 1);
t3 = _mm_srli_si128(t5, 12);
encIV = _mm_aesenc_si128(encIV, k[5]);
t6 = _mm_slli_si128(t6, 4);
t5 = _mm_slli_si128(t5, 4);
encIV = _mm_aesenc_si128(encIV, k[6]);
t1 = _mm_or_si128(t1, t5);
t4 = _mm_or_si128(t4, t6);
encIV = _mm_aesenc_si128(encIV, k[7]);
t4 = _mm_or_si128(t4, t3);
t5 = _mm_slli_epi32(t1, 31);
encIV = _mm_aesenc_si128(encIV, k[8]);
t6 = _mm_slli_epi32(t1, 30);
t3 = _mm_slli_epi32(t1, 25);
encIV = _mm_aesenc_si128(encIV, k[9]);
t5 = _mm_xor_si128(t5, t6);
t5 = _mm_xor_si128(t5, t3);
encIV = _mm_aesenc_si128(encIV, k[10]);
t6 = _mm_srli_si128(t5, 4);
t4 = _mm_xor_si128(t4, t6);
encIV = _mm_aesenc_si128(encIV, k[11]);
t5 = _mm_slli_si128(t5, 12);
t1 = _mm_xor_si128(t1, t5);
t4 = _mm_xor_si128(t4, t1);
t5 = _mm_srli_epi32(t1, 1);
encIV = _mm_aesenc_si128(encIV, k[12]);
t2 = _mm_srli_epi32(t1, 2);
t3 = _mm_srli_epi32(t1, 7);
encIV = _mm_aesenc_si128(encIV, k[13]);
t4 = _mm_xor_si128(t4, t2);
t4 = _mm_xor_si128(t4, t3);
encIV = _mm_aesenclast_si128(encIV, k[14]);
t4 = _mm_xor_si128(t4, t5);
_mm_storeu_si128(reinterpret_cast<__m128i*>(tag), _mm_xor_si128(_mm_shuffle_epi8(t4, s_sseSwapBytes), encIV));
const __m128i *const k = _aes.p_k.ni.k;
const __m128i h = _aes.p_k.ni.h[0];
y = _mm_xor_si128(y, _mm_set_epi64x(0LL, (long long)Utils::hton((uint64_t)_len << 3U)));
y = _mm_shuffle_epi8(y, s_sseSwapBytes);
__m128i encIV = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i *>(_iv)), k[0]);
__m128i t1 = _mm_clmulepi64_si128(h, y, 0x00);
__m128i t2 = _mm_clmulepi64_si128(h, y, 0x01);
__m128i t3 = _mm_clmulepi64_si128(h, y, 0x10);
__m128i t4 = _mm_clmulepi64_si128(h, y, 0x11);
encIV = _mm_aesenc_si128(encIV, k[1]);
t2 = _mm_xor_si128(t2, t3);
t3 = _mm_slli_si128(t2, 8);
encIV = _mm_aesenc_si128(encIV, k[2]);
t2 = _mm_srli_si128(t2, 8);
t1 = _mm_xor_si128(t1, t3);
encIV = _mm_aesenc_si128(encIV, k[3]);
t4 = _mm_xor_si128(t4, t2);
__m128i t5 = _mm_srli_epi32(t1, 31);
t1 = _mm_slli_epi32(t1, 1);
__m128i t6 = _mm_srli_epi32(t4, 31);
encIV = _mm_aesenc_si128(encIV, k[4]);
t4 = _mm_slli_epi32(t4, 1);
t3 = _mm_srli_si128(t5, 12);
encIV = _mm_aesenc_si128(encIV, k[5]);
t6 = _mm_slli_si128(t6, 4);
t5 = _mm_slli_si128(t5, 4);
encIV = _mm_aesenc_si128(encIV, k[6]);
t1 = _mm_or_si128(t1, t5);
t4 = _mm_or_si128(t4, t6);
encIV = _mm_aesenc_si128(encIV, k[7]);
t4 = _mm_or_si128(t4, t3);
t5 = _mm_slli_epi32(t1, 31);
encIV = _mm_aesenc_si128(encIV, k[8]);
t6 = _mm_slli_epi32(t1, 30);
t3 = _mm_slli_epi32(t1, 25);
encIV = _mm_aesenc_si128(encIV, k[9]);
t5 = _mm_xor_si128(t5, t6);
t5 = _mm_xor_si128(t5, t3);
encIV = _mm_aesenc_si128(encIV, k[10]);
t6 = _mm_srli_si128(t5, 4);
t4 = _mm_xor_si128(t4, t6);
encIV = _mm_aesenc_si128(encIV, k[11]);
t5 = _mm_slli_si128(t5, 12);
t1 = _mm_xor_si128(t1, t5);
t4 = _mm_xor_si128(t4, t1);
t5 = _mm_srli_epi32(t1, 1);
encIV = _mm_aesenc_si128(encIV, k[12]);
t2 = _mm_srli_epi32(t1, 2);
t3 = _mm_srli_epi32(t1, 7);
encIV = _mm_aesenc_si128(encIV, k[13]);
t4 = _mm_xor_si128(t4, t2);
t4 = _mm_xor_si128(t4, t3);
encIV = _mm_aesenclast_si128(encIV, k[14]);
t4 = _mm_xor_si128(t4, t5);
_mm_storeu_si128(reinterpret_cast<__m128i *>(tag), _mm_xor_si128(_mm_shuffle_epi8(t4, s_sseSwapBytes), encIV));
}
#ifdef __GNUC__
@ -367,55 +390,55 @@ __attribute__((__target__("ssse3,sse4,sse4.1,sse4.2,aes")))
void AES::CTR::p_aesNICrypt(const uint8_t *in, uint8_t *out, unsigned int len) noexcept
{
const __m128i dd = _mm_set_epi64x(0, (long long)_ctr[0]);
uint64_t c1 = Utils::ntoh(_ctr[1]);
uint64_t c1 = Utils::ntoh(_ctr[1]);
const __m128i* const k = _aes.p_k.ni.k;
const __m128i k0 = k[0];
const __m128i k1 = k[1];
const __m128i k2 = k[2];
const __m128i k3 = k[3];
const __m128i k4 = k[4];
const __m128i k5 = k[5];
const __m128i k6 = k[6];
const __m128i k7 = k[7];
const __m128i k8 = k[8];
const __m128i k9 = k[9];
const __m128i k10 = k[10];
const __m128i k11 = k[11];
const __m128i k12 = k[12];
const __m128i k13 = k[13];
const __m128i k14 = k[14];
const __m128i *const k = _aes.p_k.ni.k;
const __m128i k0 = k[0];
const __m128i k1 = k[1];
const __m128i k2 = k[2];
const __m128i k3 = k[3];
const __m128i k4 = k[4];
const __m128i k5 = k[5];
const __m128i k6 = k[6];
const __m128i k7 = k[7];
const __m128i k8 = k[8];
const __m128i k9 = k[9];
const __m128i k10 = k[10];
const __m128i k11 = k[11];
const __m128i k12 = k[12];
const __m128i k13 = k[13];
const __m128i k14 = k[14];
// Complete any unfinished blocks from previous calls to crypt().
unsigned int totalLen = _len;
if ((totalLen & 15U)) {
for (;;) {
if (unlikely(! len)) {
if (unlikely(!len)) {
_ctr[1] = Utils::hton(c1);
_len = totalLen;
_len = totalLen;
return;
}
--len;
out[totalLen++] = *(in++);
if (! (totalLen & 15U)) {
__m128i d0 = _mm_insert_epi64(dd, (long long)Utils::hton(c1++), 1);
d0 = _mm_xor_si128(d0, k0);
d0 = _mm_aesenc_si128(d0, k1);
d0 = _mm_aesenc_si128(d0, k2);
d0 = _mm_aesenc_si128(d0, k3);
d0 = _mm_aesenc_si128(d0, k4);
d0 = _mm_aesenc_si128(d0, k5);
d0 = _mm_aesenc_si128(d0, k6);
d0 = _mm_aesenc_si128(d0, k7);
d0 = _mm_aesenc_si128(d0, k8);
d0 = _mm_aesenc_si128(d0, k9);
d0 = _mm_aesenc_si128(d0, k10);
__m128i* const outblk = reinterpret_cast<__m128i*>(out + (totalLen - 16));
d0 = _mm_aesenc_si128(d0, k11);
const __m128i p0 = _mm_loadu_si128(outblk);
d0 = _mm_aesenc_si128(d0, k12);
d0 = _mm_aesenc_si128(d0, k13);
d0 = _mm_aesenclast_si128(d0, k14);
if (!(totalLen & 15U)) {
__m128i d0 = _mm_insert_epi64(dd, (long long)Utils::hton(c1++), 1);
d0 = _mm_xor_si128(d0, k0);
d0 = _mm_aesenc_si128(d0, k1);
d0 = _mm_aesenc_si128(d0, k2);
d0 = _mm_aesenc_si128(d0, k3);
d0 = _mm_aesenc_si128(d0, k4);
d0 = _mm_aesenc_si128(d0, k5);
d0 = _mm_aesenc_si128(d0, k6);
d0 = _mm_aesenc_si128(d0, k7);
d0 = _mm_aesenc_si128(d0, k8);
d0 = _mm_aesenc_si128(d0, k9);
d0 = _mm_aesenc_si128(d0, k10);
__m128i *const outblk = reinterpret_cast<__m128i *>(out + (totalLen - 16));
d0 = _mm_aesenc_si128(d0, k11);
const __m128i p0 = _mm_loadu_si128(outblk);
d0 = _mm_aesenc_si128(d0, k12);
d0 = _mm_aesenc_si128(d0, k13);
d0 = _mm_aesenclast_si128(d0, k14);
_mm_storeu_si128(outblk, _mm_xor_si128(p0, d0));
break;
}
@ -438,14 +461,14 @@ void AES::CTR::p_aesNICrypt(const uint8_t *in, uint8_t *out, unsigned int len) n
}
#endif
#if ! defined(ZT_AES_VAES512) && defined(ZT_AES_VAES256)
#if !defined(ZT_AES_VAES512) && defined(ZT_AES_VAES256)
if (Utils::CPUID.vaes && (len >= 256)) {
p_aesCtrInnerVAES256(len, _ctr[0], c1, in, out, k);
goto skip_conventional_aesni_64;
}
#endif
const uint8_t* const eof64 = in + (len & ~((unsigned int)63));
const uint8_t *const eof64 = in + (len & ~((unsigned int)63));
len &= 63;
__m128i d0, d1, d2, d3;
do {
@ -453,10 +476,10 @@ void AES::CTR::p_aesNICrypt(const uint8_t *in, uint8_t *out, unsigned int len) n
const uint64_t c11 = Utils::hton(c1 + 1ULL);
const uint64_t c12 = Utils::hton(c1 + 2ULL);
const uint64_t c13 = Utils::hton(c1 + 3ULL);
d0 = _mm_insert_epi64(dd, (long long)c10, 1);
d1 = _mm_insert_epi64(dd, (long long)c11, 1);
d2 = _mm_insert_epi64(dd, (long long)c12, 1);
d3 = _mm_insert_epi64(dd, (long long)c13, 1);
d0 = _mm_insert_epi64(dd, (long long)c10, 1);
d1 = _mm_insert_epi64(dd, (long long)c11, 1);
d2 = _mm_insert_epi64(dd, (long long)c12, 1);
d3 = _mm_insert_epi64(dd, (long long)c13, 1);
c1 += 4;
d0 = _mm_xor_si128(d0, k0);
d1 = _mm_xor_si128(d1, k0);
@ -514,15 +537,18 @@ void AES::CTR::p_aesNICrypt(const uint8_t *in, uint8_t *out, unsigned int len) n
d1 = _mm_aesenc_si128(d1, k13);
d2 = _mm_aesenc_si128(d2, k13);
d3 = _mm_aesenc_si128(d3, k13);
d0 = _mm_xor_si128(_mm_aesenclast_si128(d0, k14), _mm_loadu_si128(reinterpret_cast<const __m128i*>(in)));
d1 = _mm_xor_si128(_mm_aesenclast_si128(d1, k14), _mm_loadu_si128(reinterpret_cast<const __m128i*>(in + 16)));
d2 = _mm_xor_si128(_mm_aesenclast_si128(d2, k14), _mm_loadu_si128(reinterpret_cast<const __m128i*>(in + 32)));
d3 = _mm_xor_si128(_mm_aesenclast_si128(d3, k14), _mm_loadu_si128(reinterpret_cast<const __m128i*>(in + 48)));
d0 = _mm_xor_si128(_mm_aesenclast_si128(d0, k14), _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)));
d1 = _mm_xor_si128(
_mm_aesenclast_si128(d1, k14), _mm_loadu_si128(reinterpret_cast<const __m128i *>(in + 16)));
d2 = _mm_xor_si128(
_mm_aesenclast_si128(d2, k14), _mm_loadu_si128(reinterpret_cast<const __m128i *>(in + 32)));
d3 = _mm_xor_si128(
_mm_aesenclast_si128(d3, k14), _mm_loadu_si128(reinterpret_cast<const __m128i *>(in + 48)));
in += 64;
_mm_storeu_si128(reinterpret_cast<__m128i*>(out), d0);
_mm_storeu_si128(reinterpret_cast<__m128i*>(out + 16), d1);
_mm_storeu_si128(reinterpret_cast<__m128i*>(out + 32), d2);
_mm_storeu_si128(reinterpret_cast<__m128i*>(out + 48), d3);
_mm_storeu_si128(reinterpret_cast<__m128i *>(out), d0);
_mm_storeu_si128(reinterpret_cast<__m128i *>(out + 16), d1);
_mm_storeu_si128(reinterpret_cast<__m128i *>(out + 32), d2);
_mm_storeu_si128(reinterpret_cast<__m128i *>(out + 48), d3);
out += 64;
} while (likely(in != eof64));
}
@ -530,21 +556,23 @@ void AES::CTR::p_aesNICrypt(const uint8_t *in, uint8_t *out, unsigned int len) n
skip_conventional_aesni_64:
while (len >= 16) {
__m128i d0 = _mm_insert_epi64(dd, (long long)Utils::hton(c1++), 1);
d0 = _mm_xor_si128(d0, k0);
d0 = _mm_aesenc_si128(d0, k1);
d0 = _mm_aesenc_si128(d0, k2);
d0 = _mm_aesenc_si128(d0, k3);
d0 = _mm_aesenc_si128(d0, k4);
d0 = _mm_aesenc_si128(d0, k5);
d0 = _mm_aesenc_si128(d0, k6);
d0 = _mm_aesenc_si128(d0, k7);
d0 = _mm_aesenc_si128(d0, k8);
d0 = _mm_aesenc_si128(d0, k9);
d0 = _mm_aesenc_si128(d0, k10);
d0 = _mm_aesenc_si128(d0, k11);
d0 = _mm_aesenc_si128(d0, k12);
d0 = _mm_aesenc_si128(d0, k13);
_mm_storeu_si128(reinterpret_cast<__m128i*>(out), _mm_xor_si128(_mm_aesenclast_si128(d0, k14), _mm_loadu_si128(reinterpret_cast<const __m128i*>(in))));
d0 = _mm_xor_si128(d0, k0);
d0 = _mm_aesenc_si128(d0, k1);
d0 = _mm_aesenc_si128(d0, k2);
d0 = _mm_aesenc_si128(d0, k3);
d0 = _mm_aesenc_si128(d0, k4);
d0 = _mm_aesenc_si128(d0, k5);
d0 = _mm_aesenc_si128(d0, k6);
d0 = _mm_aesenc_si128(d0, k7);
d0 = _mm_aesenc_si128(d0, k8);
d0 = _mm_aesenc_si128(d0, k9);
d0 = _mm_aesenc_si128(d0, k10);
d0 = _mm_aesenc_si128(d0, k11);
d0 = _mm_aesenc_si128(d0, k12);
d0 = _mm_aesenc_si128(d0, k13);
_mm_storeu_si128(
reinterpret_cast<__m128i *>(out),
_mm_xor_si128(_mm_aesenclast_si128(d0, k14), _mm_loadu_si128(reinterpret_cast<const __m128i *>(in))));
in += 16;
len -= 16;
out += 16;
@ -565,8 +593,8 @@ __attribute__((__target__("ssse3,sse4,sse4.1,sse4.2,aes,pclmul")))
void AES::p_init_aesni(const uint8_t *key) noexcept
{
__m128i t1, t2, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13;
p_k.ni.k[0] = t1 = _mm_loadu_si128((const __m128i*)key);
p_k.ni.k[1] = k1 = t2 = _mm_loadu_si128((const __m128i*)(key + 16));
p_k.ni.k[0] = t1 = _mm_loadu_si128((const __m128i *)key);
p_k.ni.k[1] = k1 = t2 = _mm_loadu_si128((const __m128i *)(key + 16));
p_k.ni.k[2] = k2 = t1 = p_init256_1_aesni(t1, _mm_aeskeygenassist_si128(t2, 0x01));
p_k.ni.k[3] = k3 = t2 = p_init256_2_aesni(t1, t2);
p_k.ni.k[4] = k4 = t1 = p_init256_1_aesni(t1, _mm_aeskeygenassist_si128(t2, 0x02));
@ -579,48 +607,48 @@ void AES::p_init_aesni(const uint8_t *key) noexcept
p_k.ni.k[11] = k11 = t2 = p_init256_2_aesni(t1, t2);
p_k.ni.k[12] = k12 = t1 = p_init256_1_aesni(t1, _mm_aeskeygenassist_si128(t2, 0x20));
p_k.ni.k[13] = k13 = t2 = p_init256_2_aesni(t1, t2);
p_k.ni.k[14] = p_init256_1_aesni(t1, _mm_aeskeygenassist_si128(t2, 0x40));
p_k.ni.k[15] = _mm_aesimc_si128(k13);
p_k.ni.k[16] = _mm_aesimc_si128(k12);
p_k.ni.k[17] = _mm_aesimc_si128(k11);
p_k.ni.k[18] = _mm_aesimc_si128(k10);
p_k.ni.k[19] = _mm_aesimc_si128(k9);
p_k.ni.k[20] = _mm_aesimc_si128(k8);
p_k.ni.k[21] = _mm_aesimc_si128(k7);
p_k.ni.k[22] = _mm_aesimc_si128(k6);
p_k.ni.k[23] = _mm_aesimc_si128(k5);
p_k.ni.k[24] = _mm_aesimc_si128(k4);
p_k.ni.k[25] = _mm_aesimc_si128(k3);
p_k.ni.k[26] = _mm_aesimc_si128(k2);
p_k.ni.k[27] = _mm_aesimc_si128(k1);
p_k.ni.k[14] = p_init256_1_aesni(t1, _mm_aeskeygenassist_si128(t2, 0x40));
p_k.ni.k[15] = _mm_aesimc_si128(k13);
p_k.ni.k[16] = _mm_aesimc_si128(k12);
p_k.ni.k[17] = _mm_aesimc_si128(k11);
p_k.ni.k[18] = _mm_aesimc_si128(k10);
p_k.ni.k[19] = _mm_aesimc_si128(k9);
p_k.ni.k[20] = _mm_aesimc_si128(k8);
p_k.ni.k[21] = _mm_aesimc_si128(k7);
p_k.ni.k[22] = _mm_aesimc_si128(k6);
p_k.ni.k[23] = _mm_aesimc_si128(k5);
p_k.ni.k[24] = _mm_aesimc_si128(k4);
p_k.ni.k[25] = _mm_aesimc_si128(k3);
p_k.ni.k[26] = _mm_aesimc_si128(k2);
p_k.ni.k[27] = _mm_aesimc_si128(k1);
__m128i h = p_k.ni.k[0]; // _mm_xor_si128(_mm_setzero_si128(),_k.ni.k[0]);
h = _mm_aesenc_si128(h, k1);
h = _mm_aesenc_si128(h, k2);
h = _mm_aesenc_si128(h, k3);
h = _mm_aesenc_si128(h, k4);
h = _mm_aesenc_si128(h, k5);
h = _mm_aesenc_si128(h, k6);
h = _mm_aesenc_si128(h, k7);
h = _mm_aesenc_si128(h, k8);
h = _mm_aesenc_si128(h, k9);
h = _mm_aesenc_si128(h, k10);
h = _mm_aesenc_si128(h, k11);
h = _mm_aesenc_si128(h, k12);
h = _mm_aesenc_si128(h, k13);
h = _mm_aesenclast_si128(h, p_k.ni.k[14]);
__m128i h = p_k.ni.k[0]; // _mm_xor_si128(_mm_setzero_si128(),_k.ni.k[0]);
h = _mm_aesenc_si128(h, k1);
h = _mm_aesenc_si128(h, k2);
h = _mm_aesenc_si128(h, k3);
h = _mm_aesenc_si128(h, k4);
h = _mm_aesenc_si128(h, k5);
h = _mm_aesenc_si128(h, k6);
h = _mm_aesenc_si128(h, k7);
h = _mm_aesenc_si128(h, k8);
h = _mm_aesenc_si128(h, k9);
h = _mm_aesenc_si128(h, k10);
h = _mm_aesenc_si128(h, k11);
h = _mm_aesenc_si128(h, k12);
h = _mm_aesenc_si128(h, k13);
h = _mm_aesenclast_si128(h, p_k.ni.k[14]);
__m128i hswap = _mm_shuffle_epi8(h, s_sseSwapBytes);
__m128i hh = p_gmacPCLMUL128(hswap, h);
__m128i hhh = p_gmacPCLMUL128(hswap, hh);
__m128i hhhh = p_gmacPCLMUL128(hswap, hhh);
p_k.ni.h[0] = hswap;
__m128i hh = p_gmacPCLMUL128(hswap, h);
__m128i hhh = p_gmacPCLMUL128(hswap, hh);
__m128i hhhh = p_gmacPCLMUL128(hswap, hhh);
p_k.ni.h[0] = hswap;
p_k.ni.h[1] = hh = _mm_shuffle_epi8(hh, s_sseSwapBytes);
p_k.ni.h[2] = hhh = _mm_shuffle_epi8(hhh, s_sseSwapBytes);
p_k.ni.h[3] = hhhh = _mm_shuffle_epi8(hhhh, s_sseSwapBytes);
p_k.ni.h2[0] = _mm_xor_si128(_mm_shuffle_epi32(hswap, 78), hswap);
p_k.ni.h2[1] = _mm_xor_si128(_mm_shuffle_epi32(hh, 78), hh);
p_k.ni.h2[2] = _mm_xor_si128(_mm_shuffle_epi32(hhh, 78), hhh);
p_k.ni.h2[3] = _mm_xor_si128(_mm_shuffle_epi32(hhhh, 78), hhhh);
p_k.ni.h2[0] = _mm_xor_si128(_mm_shuffle_epi32(hswap, 78), hswap);
p_k.ni.h2[1] = _mm_xor_si128(_mm_shuffle_epi32(hh, 78), hh);
p_k.ni.h2[2] = _mm_xor_si128(_mm_shuffle_epi32(hhh, 78), hhh);
p_k.ni.h2[3] = _mm_xor_si128(_mm_shuffle_epi32(hhhh, 78), hhhh);
}
#ifdef __GNUC__
@ -628,22 +656,22 @@ __attribute__((__target__("ssse3,sse4,sse4.1,sse4.2,aes,pclmul")))
#endif
void AES::p_encrypt_aesni(const void *const in, void *const out) const noexcept
{
__m128i tmp = _mm_loadu_si128((const __m128i*)in);
tmp = _mm_xor_si128(tmp, p_k.ni.k[0]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[1]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[2]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[3]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[4]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[5]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[6]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[7]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[8]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[9]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[10]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[11]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[12]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[13]);
_mm_storeu_si128((__m128i*)out, _mm_aesenclast_si128(tmp, p_k.ni.k[14]));
__m128i tmp = _mm_loadu_si128((const __m128i *)in);
tmp = _mm_xor_si128(tmp, p_k.ni.k[0]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[1]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[2]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[3]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[4]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[5]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[6]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[7]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[8]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[9]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[10]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[11]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[12]);
tmp = _mm_aesenc_si128(tmp, p_k.ni.k[13]);
_mm_storeu_si128((__m128i *)out, _mm_aesenclast_si128(tmp, p_k.ni.k[14]));
}
#ifdef __GNUC__
@ -651,22 +679,22 @@ __attribute__((__target__("ssse3,sse4,sse4.1,sse4.2,aes,pclmul")))
#endif
void AES::p_decrypt_aesni(const void *in, void *out) const noexcept
{
__m128i tmp = _mm_loadu_si128((const __m128i*)in);
tmp = _mm_xor_si128(tmp, p_k.ni.k[14]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[15]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[16]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[17]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[18]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[19]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[20]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[21]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[22]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[23]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[24]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[25]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[26]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[27]);
_mm_storeu_si128((__m128i*)out, _mm_aesdeclast_si128(tmp, p_k.ni.k[0]));
__m128i tmp = _mm_loadu_si128((const __m128i *)in);
tmp = _mm_xor_si128(tmp, p_k.ni.k[14]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[15]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[16]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[17]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[18]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[19]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[20]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[21]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[22]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[23]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[24]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[25]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[26]);
tmp = _mm_aesdec_si128(tmp, p_k.ni.k[27]);
_mm_storeu_si128((__m128i *)out, _mm_aesdeclast_si128(tmp, p_k.ni.k[0]));
}
} // namespace ZeroTier

View file

@ -25,12 +25,12 @@ namespace {
ZT_INLINE uint8x16_t s_clmul_armneon_crypto(uint8x16_t h, uint8x16_t y, const uint8_t b[16]) noexcept
{
uint8x16_t r0, r1, t0, t1;
r0 = vld1q_u8(b);
r0 = vld1q_u8(b);
const uint8x16_t z = veorq_u8(h, h);
y = veorq_u8(r0, y);
y = vrbitq_u8(y);
y = veorq_u8(r0, y);
y = vrbitq_u8(y);
const uint8x16_t p = vreinterpretq_u8_u64(vdupq_n_u64(0x0000000000000087));
t0 = vextq_u8(y, y, 8);
t0 = vextq_u8(y, y, 8);
__asm__ __volatile__("pmull %0.1q, %1.1d, %2.1d \n\t" : "=w"(r0) : "w"(h), "w"(y));
__asm__ __volatile__("pmull2 %0.1q, %1.2d, %2.2d \n\t" : "=w"(r1) : "w"(h), "w"(y));
__asm__ __volatile__("pmull %0.1q, %1.1d, %2.1d \n\t" : "=w"(t1) : "w"(h), "w"(t0));
@ -51,14 +51,14 @@ ZT_INLINE uint8x16_t s_clmul_armneon_crypto(uint8x16_t h, uint8x16_t y, const ui
} // anonymous namespace
void AES::GMAC::p_armUpdate(const uint8_t* in, unsigned int len) noexcept
void AES::GMAC::p_armUpdate(const uint8_t *in, unsigned int len) noexcept
{
uint8x16_t y = vld1q_u8(reinterpret_cast<const uint8_t*>(_y));
uint8x16_t y = vld1q_u8(reinterpret_cast<const uint8_t *>(_y));
const uint8x16_t h = _aes.p_k.neon.h;
if (_rp) {
for (;;) {
if (! len)
if (!len)
return;
--len;
_r[_rp++] = *(in++);
@ -75,7 +75,7 @@ void AES::GMAC::p_armUpdate(const uint8_t* in, unsigned int len) noexcept
len -= 16;
}
vst1q_u8(reinterpret_cast<uint8_t*>(_y), y);
vst1q_u8(reinterpret_cast<uint8_t *>(_y), y);
for (unsigned int i = 0; i < len; ++i)
_r[i] = in[i];
@ -85,7 +85,7 @@ void AES::GMAC::p_armUpdate(const uint8_t* in, unsigned int len) noexcept
void AES::GMAC::p_armFinish(uint8_t tag[16]) noexcept
{
uint64_t tmp[2];
uint8x16_t y = vld1q_u8(reinterpret_cast<const uint8_t*>(_y));
uint8x16_t y = vld1q_u8(reinterpret_cast<const uint8_t *>(_y));
const uint8x16_t h = _aes.p_k.neon.h;
if (_rp) {
@ -96,36 +96,36 @@ void AES::GMAC::p_armFinish(uint8_t tag[16]) noexcept
tmp[0] = Utils::hton((uint64_t)_len << 3U);
tmp[1] = 0;
y = s_clmul_armneon_crypto(h, y, reinterpret_cast<const uint8_t*>(tmp));
y = s_clmul_armneon_crypto(h, y, reinterpret_cast<const uint8_t *>(tmp));
Utils::copy<12>(tmp, _iv);
#if __BYTE_ORDER == __BIG_ENDIAN
reinterpret_cast<uint32_t*>(tmp)[3] = 0x00000001;
reinterpret_cast<uint32_t *>(tmp)[3] = 0x00000001;
#else
reinterpret_cast<uint32_t*>(tmp)[3] = 0x01000000;
reinterpret_cast<uint32_t *>(tmp)[3] = 0x01000000;
#endif
_aes.encrypt(tmp, tmp);
uint8x16_t yy = y;
Utils::storeMachineEndian<uint64_t>(tag, tmp[0] ^ reinterpret_cast<const uint64_t*>(&yy)[0]);
Utils::storeMachineEndian<uint64_t>(tag + 8, tmp[1] ^ reinterpret_cast<const uint64_t*>(&yy)[1]);
Utils::storeMachineEndian<uint64_t>(tag, tmp[0] ^ reinterpret_cast<const uint64_t *>(&yy)[0]);
Utils::storeMachineEndian<uint64_t>(tag + 8, tmp[1] ^ reinterpret_cast<const uint64_t *>(&yy)[1]);
}
void AES::CTR::p_armCrypt(const uint8_t* in, uint8_t* out, unsigned int len) noexcept
void AES::CTR::p_armCrypt(const uint8_t *in, uint8_t *out, unsigned int len) noexcept
{
uint8x16_t dd = vrev32q_u8(vld1q_u8(reinterpret_cast<uint8_t*>(_ctr)));
uint8x16_t dd = vrev32q_u8(vld1q_u8(reinterpret_cast<uint8_t *>(_ctr)));
const uint32x4_t one = { 0, 0, 0, 1 };
uint8x16_t k0 = _aes.p_k.neon.ek[0];
uint8x16_t k1 = _aes.p_k.neon.ek[1];
uint8x16_t k2 = _aes.p_k.neon.ek[2];
uint8x16_t k3 = _aes.p_k.neon.ek[3];
uint8x16_t k4 = _aes.p_k.neon.ek[4];
uint8x16_t k5 = _aes.p_k.neon.ek[5];
uint8x16_t k6 = _aes.p_k.neon.ek[6];
uint8x16_t k7 = _aes.p_k.neon.ek[7];
uint8x16_t k8 = _aes.p_k.neon.ek[8];
uint8x16_t k9 = _aes.p_k.neon.ek[9];
uint8x16_t k0 = _aes.p_k.neon.ek[0];
uint8x16_t k1 = _aes.p_k.neon.ek[1];
uint8x16_t k2 = _aes.p_k.neon.ek[2];
uint8x16_t k3 = _aes.p_k.neon.ek[3];
uint8x16_t k4 = _aes.p_k.neon.ek[4];
uint8x16_t k5 = _aes.p_k.neon.ek[5];
uint8x16_t k6 = _aes.p_k.neon.ek[6];
uint8x16_t k7 = _aes.p_k.neon.ek[7];
uint8x16_t k8 = _aes.p_k.neon.ek[8];
uint8x16_t k9 = _aes.p_k.neon.ek[9];
uint8x16_t k10 = _aes.p_k.neon.ek[10];
uint8x16_t k11 = _aes.p_k.neon.ek[11];
uint8x16_t k12 = _aes.p_k.neon.ek[12];
@ -135,31 +135,31 @@ void AES::CTR::p_armCrypt(const uint8_t* in, uint8_t* out, unsigned int len) noe
unsigned int totalLen = _len;
if ((totalLen & 15U) != 0) {
for (;;) {
if (unlikely(! len)) {
vst1q_u8(reinterpret_cast<uint8_t*>(_ctr), vrev32q_u8(dd));
if (unlikely(!len)) {
vst1q_u8(reinterpret_cast<uint8_t *>(_ctr), vrev32q_u8(dd));
_len = totalLen;
return;
}
--len;
out[totalLen++] = *(in++);
if ((totalLen & 15U) == 0) {
uint8_t* const otmp = out + (totalLen - 16);
uint8x16_t d0 = vrev32q_u8(dd);
uint8x16_t pt = vld1q_u8(otmp);
d0 = vaesmcq_u8(vaeseq_u8(d0, k0));
d0 = vaesmcq_u8(vaeseq_u8(d0, k1));
d0 = vaesmcq_u8(vaeseq_u8(d0, k2));
d0 = vaesmcq_u8(vaeseq_u8(d0, k3));
d0 = vaesmcq_u8(vaeseq_u8(d0, k4));
d0 = vaesmcq_u8(vaeseq_u8(d0, k5));
d0 = vaesmcq_u8(vaeseq_u8(d0, k6));
d0 = vaesmcq_u8(vaeseq_u8(d0, k7));
d0 = vaesmcq_u8(vaeseq_u8(d0, k8));
d0 = vaesmcq_u8(vaeseq_u8(d0, k9));
d0 = vaesmcq_u8(vaeseq_u8(d0, k10));
d0 = vaesmcq_u8(vaeseq_u8(d0, k11));
d0 = vaesmcq_u8(vaeseq_u8(d0, k12));
d0 = veorq_u8(vaeseq_u8(d0, k13), k14);
uint8_t *const otmp = out + (totalLen - 16);
uint8x16_t d0 = vrev32q_u8(dd);
uint8x16_t pt = vld1q_u8(otmp);
d0 = vaesmcq_u8(vaeseq_u8(d0, k0));
d0 = vaesmcq_u8(vaeseq_u8(d0, k1));
d0 = vaesmcq_u8(vaeseq_u8(d0, k2));
d0 = vaesmcq_u8(vaeseq_u8(d0, k3));
d0 = vaesmcq_u8(vaeseq_u8(d0, k4));
d0 = vaesmcq_u8(vaeseq_u8(d0, k5));
d0 = vaesmcq_u8(vaeseq_u8(d0, k6));
d0 = vaesmcq_u8(vaeseq_u8(d0, k7));
d0 = vaesmcq_u8(vaeseq_u8(d0, k8));
d0 = vaesmcq_u8(vaeseq_u8(d0, k9));
d0 = vaesmcq_u8(vaeseq_u8(d0, k10));
d0 = vaesmcq_u8(vaeseq_u8(d0, k11));
d0 = vaesmcq_u8(vaeseq_u8(d0, k12));
d0 = veorq_u8(vaeseq_u8(d0, k13), k14);
vst1q_u8(otmp, veorq_u8(pt, d0));
dd = (uint8x16_t)vaddq_u32((uint32x4_t)dd, one);
break;
@ -172,15 +172,15 @@ void AES::CTR::p_armCrypt(const uint8_t* in, uint8_t* out, unsigned int len) noe
if (likely(len >= 64)) {
const uint32x4_t four = vshlq_n_u32(one, 2);
uint8x16_t dd1 = (uint8x16_t)vaddq_u32((uint32x4_t)dd, one);
uint8x16_t dd2 = (uint8x16_t)vaddq_u32((uint32x4_t)dd1, one);
uint8x16_t dd3 = (uint8x16_t)vaddq_u32((uint32x4_t)dd2, one);
uint8x16_t dd1 = (uint8x16_t)vaddq_u32((uint32x4_t)dd, one);
uint8x16_t dd2 = (uint8x16_t)vaddq_u32((uint32x4_t)dd1, one);
uint8x16_t dd3 = (uint8x16_t)vaddq_u32((uint32x4_t)dd2, one);
for (;;) {
len -= 64;
uint8x16_t d0 = vrev32q_u8(dd);
uint8x16_t d1 = vrev32q_u8(dd1);
uint8x16_t d2 = vrev32q_u8(dd2);
uint8x16_t d3 = vrev32q_u8(dd3);
uint8x16_t d0 = vrev32q_u8(dd);
uint8x16_t d1 = vrev32q_u8(dd1);
uint8x16_t d2 = vrev32q_u8(dd2);
uint8x16_t d3 = vrev32q_u8(dd3);
uint8x16_t pt0 = vld1q_u8(in);
uint8x16_t pt1 = vld1q_u8(in + 16);
uint8x16_t pt2 = vld1q_u8(in + 32);
@ -295,39 +295,53 @@ void AES::CTR::p_armCrypt(const uint8_t* in, uint8_t* out, unsigned int len) noe
for (unsigned int i = 0; i < len; ++i)
out[i] = in[i];
vst1q_u8(reinterpret_cast<uint8_t*>(_ctr), vrev32q_u8(dd));
vst1q_u8(reinterpret_cast<uint8_t *>(_ctr), vrev32q_u8(dd));
}
#define ZT_INIT_ARMNEON_CRYPTO_SUBWORD(w) ((uint32_t)s_sbox[w & 0xffU] + ((uint32_t)s_sbox[(w >> 8U) & 0xffU] << 8U) + ((uint32_t)s_sbox[(w >> 16U) & 0xffU] << 16U) + ((uint32_t)s_sbox[(w >> 24U) & 0xffU] << 24U))
#define ZT_INIT_ARMNEON_CRYPTO_SUBWORD(w) \
((uint32_t)s_sbox[w & 0xffU] + ((uint32_t)s_sbox[(w >> 8U) & 0xffU] << 8U) \
+ ((uint32_t)s_sbox[(w >> 16U) & 0xffU] << 16U) + ((uint32_t)s_sbox[(w >> 24U) & 0xffU] << 24U))
#define ZT_INIT_ARMNEON_CRYPTO_ROTWORD(w) (((w) << 8U) | ((w) >> 24U))
#define ZT_INIT_ARMNEON_CRYPTO_NK 8
#define ZT_INIT_ARMNEON_CRYPTO_NB 4
#define ZT_INIT_ARMNEON_CRYPTO_NR 14
void AES::p_init_armneon_crypto(const uint8_t* key) noexcept
void AES::p_init_armneon_crypto(const uint8_t *key) noexcept
{
static const uint8_t s_sbox[256] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
static const uint8_t s_sbox[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82,
0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26,
0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96,
0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb,
0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,
0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff,
0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32,
0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6,
0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e,
0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,
0xb0, 0x54, 0xbb, 0x16
};
uint64_t h[2];
uint32_t* const w = reinterpret_cast<uint32_t*>(p_k.neon.ek);
uint32_t *const w = reinterpret_cast<uint32_t *>(p_k.neon.ek);
for (unsigned int i = 0; i < ZT_INIT_ARMNEON_CRYPTO_NK; ++i) {
const unsigned int j = i * 4;
w[i] = ((uint32_t)key[j] << 24U) | ((uint32_t)key[j + 1] << 16U) | ((uint32_t)key[j + 2] << 8U) | (uint32_t)key[j + 3];
w[i] = ((uint32_t)key[j] << 24U) | ((uint32_t)key[j + 1] << 16U) | ((uint32_t)key[j + 2] << 8U)
| (uint32_t)key[j + 3];
}
for (unsigned int i = ZT_INIT_ARMNEON_CRYPTO_NK; i < (ZT_INIT_ARMNEON_CRYPTO_NB * (ZT_INIT_ARMNEON_CRYPTO_NR + 1)); ++i) {
uint32_t t = w[i - 1];
for (unsigned int i = ZT_INIT_ARMNEON_CRYPTO_NK; i < (ZT_INIT_ARMNEON_CRYPTO_NB * (ZT_INIT_ARMNEON_CRYPTO_NR + 1));
++i) {
uint32_t t = w[i - 1];
const unsigned int imod = i & (ZT_INIT_ARMNEON_CRYPTO_NK - 1);
if (imod == 0) {
t = ZT_INIT_ARMNEON_CRYPTO_SUBWORD(ZT_INIT_ARMNEON_CRYPTO_ROTWORD(t)) ^ rcon[(i - 1) / ZT_INIT_ARMNEON_CRYPTO_NK];
t = ZT_INIT_ARMNEON_CRYPTO_SUBWORD(ZT_INIT_ARMNEON_CRYPTO_ROTWORD(t))
^ rcon[(i - 1) / ZT_INIT_ARMNEON_CRYPTO_NK];
}
else if (imod == 4) {
t = ZT_INIT_ARMNEON_CRYPTO_SUBWORD(t);
@ -345,49 +359,49 @@ void AES::p_init_armneon_crypto(const uint8_t* key) noexcept
p_encrypt_armneon_crypto(Utils::ZERO256, h);
Utils::copy<16>(&(p_k.neon.h), h);
p_k.neon.h = vrbitq_u8(p_k.neon.h);
p_k.neon.h = vrbitq_u8(p_k.neon.h);
p_k.sw.h[0] = Utils::ntoh(h[0]);
p_k.sw.h[1] = Utils::ntoh(h[1]);
}
void AES::p_encrypt_armneon_crypto(const void* const in, void* const out) const noexcept
void AES::p_encrypt_armneon_crypto(const void *const in, void *const out) const noexcept
{
uint8x16_t tmp = vld1q_u8(reinterpret_cast<const uint8_t*>(in));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[0]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[1]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[2]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[3]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[4]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[5]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[6]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[7]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[8]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[9]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[10]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[11]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[12]));
tmp = veorq_u8(vaeseq_u8(tmp, p_k.neon.ek[13]), p_k.neon.ek[14]);
vst1q_u8(reinterpret_cast<uint8_t*>(out), tmp);
uint8x16_t tmp = vld1q_u8(reinterpret_cast<const uint8_t *>(in));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[0]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[1]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[2]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[3]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[4]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[5]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[6]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[7]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[8]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[9]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[10]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[11]));
tmp = vaesmcq_u8(vaeseq_u8(tmp, p_k.neon.ek[12]));
tmp = veorq_u8(vaeseq_u8(tmp, p_k.neon.ek[13]), p_k.neon.ek[14]);
vst1q_u8(reinterpret_cast<uint8_t *>(out), tmp);
}
void AES::p_decrypt_armneon_crypto(const void* const in, void* const out) const noexcept
void AES::p_decrypt_armneon_crypto(const void *const in, void *const out) const noexcept
{
uint8x16_t tmp = vld1q_u8(reinterpret_cast<const uint8_t*>(in));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[0]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[1]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[2]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[3]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[4]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[5]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[6]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[7]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[8]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[9]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[10]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[11]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[12]));
tmp = veorq_u8(vaesdq_u8(tmp, p_k.neon.dk[13]), p_k.neon.dk[14]);
vst1q_u8(reinterpret_cast<uint8_t*>(out), tmp);
uint8x16_t tmp = vld1q_u8(reinterpret_cast<const uint8_t *>(in));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[0]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[1]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[2]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[3]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[4]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[5]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[6]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[7]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[8]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[9]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[10]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[11]));
tmp = vaesimcq_u8(vaesdq_u8(tmp, p_k.neon.dk[12]));
tmp = veorq_u8(vaesdq_u8(tmp, p_k.neon.dk[13]), p_k.neon.dk[14]);
vst1q_u8(reinterpret_cast<uint8_t *>(out), tmp);
}
} // namespace ZeroTier

View file

@ -30,19 +30,18 @@ namespace ZeroTier {
*/
class Address : public TriviallyCopyable {
public:
ZT_INLINE Address() noexcept : _a(0)
ZT_INLINE Address() noexcept : _a(0) {}
ZT_INLINE Address(const uint64_t a) noexcept : _a(a) {}
explicit ZT_INLINE Address(const uint8_t b[5]) noexcept
: _a(
((uint64_t)b[0] << 32U) | ((uint64_t)b[1] << 24U) | ((uint64_t)b[2] << 16U) | ((uint64_t)b[3] << 8U)
| (uint64_t)b[4])
{
}
ZT_INLINE Address(const uint64_t a) noexcept : _a(a)
{
}
explicit ZT_INLINE Address(const uint8_t b[5]) noexcept : _a(((uint64_t)b[0] << 32U) | ((uint64_t)b[1] << 24U) | ((uint64_t)b[2] << 16U) | ((uint64_t)b[3] << 8U) | (uint64_t)b[4])
{
}
ZT_INLINE Address& operator=(const uint64_t a) noexcept
ZT_INLINE Address &operator=(const uint64_t a) noexcept
{
_a = a;
return *this;
@ -54,7 +53,8 @@ class Address : public TriviallyCopyable {
*/
ZT_INLINE void setTo(const uint8_t b[5]) noexcept
{
_a = ((uint64_t)b[0] << 32U) | ((uint64_t)b[1] << 24U) | ((uint64_t)b[2] << 16U) | ((uint64_t)b[3] << 8U) | (uint64_t)b[4];
_a = ((uint64_t)b[0] << 32U) | ((uint64_t)b[1] << 24U) | ((uint64_t)b[2] << 16U) | ((uint64_t)b[3] << 8U)
| (uint64_t)b[4];
}
/**
@ -64,48 +64,42 @@ class Address : public TriviallyCopyable {
ZT_INLINE void copyTo(uint8_t b[5]) const noexcept
{
const uint64_t a = _a;
b[0] = (uint8_t)(a >> 32U);
b[1] = (uint8_t)(a >> 24U);
b[2] = (uint8_t)(a >> 16U);
b[3] = (uint8_t)(a >> 8U);
b[4] = (uint8_t)a;
b[0] = (uint8_t)(a >> 32U);
b[1] = (uint8_t)(a >> 24U);
b[2] = (uint8_t)(a >> 16U);
b[3] = (uint8_t)(a >> 8U);
b[4] = (uint8_t)a;
}
/**
* @return Integer containing address (0 to 2^40)
*/
ZT_INLINE uint64_t toInt() const noexcept
{
return _a;
}
ZT_INLINE uint64_t toInt() const noexcept { return _a; }
/**
* Set address to zero/NIL
*/
ZT_INLINE void zero() noexcept
{
_a = 0;
}
ZT_INLINE void zero() noexcept { _a = 0; }
/**
* @param s String with at least 11 characters of space available (10 + terminating NULL)
* @return Hexadecimal string
*/
ZT_INLINE char* toString(char s[ZT_ADDRESS_STRING_SIZE_MAX]) const noexcept
ZT_INLINE char *toString(char s[ZT_ADDRESS_STRING_SIZE_MAX]) const noexcept
{
const uint64_t a = _a;
const uint64_t a = _a;
const unsigned int m = 0xf;
s[0] = Utils::HEXCHARS[(unsigned int)(a >> 36U) & m];
s[1] = Utils::HEXCHARS[(unsigned int)(a >> 32U) & m];
s[2] = Utils::HEXCHARS[(unsigned int)(a >> 28U) & m];
s[3] = Utils::HEXCHARS[(unsigned int)(a >> 24U) & m];
s[4] = Utils::HEXCHARS[(unsigned int)(a >> 20U) & m];
s[5] = Utils::HEXCHARS[(unsigned int)(a >> 16U) & m];
s[6] = Utils::HEXCHARS[(unsigned int)(a >> 12U) & m];
s[7] = Utils::HEXCHARS[(unsigned int)(a >> 8U) & m];
s[8] = Utils::HEXCHARS[(unsigned int)(a >> 4U) & m];
s[9] = Utils::HEXCHARS[(unsigned int)a & m];
s[10] = 0;
s[0] = Utils::HEXCHARS[(unsigned int)(a >> 36U) & m];
s[1] = Utils::HEXCHARS[(unsigned int)(a >> 32U) & m];
s[2] = Utils::HEXCHARS[(unsigned int)(a >> 28U) & m];
s[3] = Utils::HEXCHARS[(unsigned int)(a >> 24U) & m];
s[4] = Utils::HEXCHARS[(unsigned int)(a >> 20U) & m];
s[5] = Utils::HEXCHARS[(unsigned int)(a >> 16U) & m];
s[6] = Utils::HEXCHARS[(unsigned int)(a >> 12U) & m];
s[7] = Utils::HEXCHARS[(unsigned int)(a >> 8U) & m];
s[8] = Utils::HEXCHARS[(unsigned int)(a >> 4U) & m];
s[9] = Utils::HEXCHARS[(unsigned int)a & m];
s[10] = 0;
return s;
}
@ -125,85 +119,37 @@ class Address : public TriviallyCopyable {
*
* @return True if address is reserved and may not be used
*/
ZT_INLINE bool isReserved() const noexcept
{
return ((! _a) || ((_a >> 32U) == ZT_ADDRESS_RESERVED_PREFIX));
}
ZT_INLINE bool isReserved() const noexcept { return ((!_a) || ((_a >> 32U) == ZT_ADDRESS_RESERVED_PREFIX)); }
ZT_INLINE unsigned long hashCode() const noexcept
{
return (unsigned long)_a;
}
ZT_INLINE unsigned long hashCode() const noexcept { return (unsigned long)_a; }
ZT_INLINE operator bool() const noexcept
{
return (_a != 0);
}
ZT_INLINE operator bool() const noexcept { return (_a != 0); }
ZT_INLINE operator uint64_t() const noexcept
{
return _a;
}
ZT_INLINE operator uint64_t() const noexcept { return _a; }
ZT_INLINE bool operator==(const Address& a) const noexcept
{
return _a == a._a;
}
ZT_INLINE bool operator==(const Address &a) const noexcept { return _a == a._a; }
ZT_INLINE bool operator!=(const Address& a) const noexcept
{
return _a != a._a;
}
ZT_INLINE bool operator!=(const Address &a) const noexcept { return _a != a._a; }
ZT_INLINE bool operator>(const Address& a) const noexcept
{
return _a > a._a;
}
ZT_INLINE bool operator>(const Address &a) const noexcept { return _a > a._a; }
ZT_INLINE bool operator<(const Address& a) const noexcept
{
return _a < a._a;
}
ZT_INLINE bool operator<(const Address &a) const noexcept { return _a < a._a; }
ZT_INLINE bool operator>=(const Address& a) const noexcept
{
return _a >= a._a;
}
ZT_INLINE bool operator>=(const Address &a) const noexcept { return _a >= a._a; }
ZT_INLINE bool operator<=(const Address& a) const noexcept
{
return _a <= a._a;
}
ZT_INLINE bool operator<=(const Address &a) const noexcept { return _a <= a._a; }
ZT_INLINE bool operator==(const uint64_t a) const noexcept
{
return _a == a;
}
ZT_INLINE bool operator==(const uint64_t a) const noexcept { return _a == a; }
ZT_INLINE bool operator!=(const uint64_t a) const noexcept
{
return _a != a;
}
ZT_INLINE bool operator!=(const uint64_t a) const noexcept { return _a != a; }
ZT_INLINE bool operator>(const uint64_t a) const noexcept
{
return _a > a;
}
ZT_INLINE bool operator>(const uint64_t a) const noexcept { return _a > a; }
ZT_INLINE bool operator<(const uint64_t a) const noexcept
{
return _a < a;
}
ZT_INLINE bool operator<(const uint64_t a) const noexcept { return _a < a; }
ZT_INLINE bool operator>=(const uint64_t a) const noexcept
{
return _a >= a;
}
ZT_INLINE bool operator>=(const uint64_t a) const noexcept { return _a >= a; }
ZT_INLINE bool operator<=(const uint64_t a) const noexcept
{
return _a <= a;
}
ZT_INLINE bool operator<=(const uint64_t a) const noexcept { return _a <= a; }
private:
uint64_t _a;

View file

@ -23,36 +23,36 @@ static std::atomic<long> s_allocated(0);
// uintptr_max can never be a valid pointer, so use it to indicate that s_pool is locked (very short duration spinlock)
#define ZT_ATOMIC_PTR_LOCKED (~((uintptr_t)0))
void* Buf::operator new(std::size_t sz)
void *Buf::operator new(std::size_t sz)
{
uintptr_t bb;
for (;;) {
bb = s_pool.exchange(ZT_ATOMIC_PTR_LOCKED, std::memory_order_acquire);
if (likely(bb != ZT_ATOMIC_PTR_LOCKED)) {
Buf* b;
Buf *b;
if (likely(bb != 0)) {
b = reinterpret_cast<Buf*>(bb);
b = reinterpret_cast<Buf *>(bb);
s_pool.store(b->__nextInPool, std::memory_order_release);
}
else {
s_pool.store(0, std::memory_order_release);
b = reinterpret_cast<Buf*>(malloc(sz));
if (! b)
b = reinterpret_cast<Buf *>(malloc(sz));
if (!b)
throw Utils::BadAllocException;
s_allocated.fetch_add(1, std::memory_order_relaxed);
}
b->__refCount.store(0, std::memory_order_relaxed);
return reinterpret_cast<void*>(b);
return reinterpret_cast<void *>(b);
}
Spinlock::pause();
}
}
void Buf::operator delete(void* ptr)
void Buf::operator delete(void *ptr)
{
if (likely(ptr != nullptr)) {
if (s_allocated.load(std::memory_order_relaxed) > ZT_BUF_MAX_POOL_SIZE) {
@ -64,7 +64,7 @@ void Buf::operator delete(void* ptr)
for (;;) {
bb = s_pool.exchange(ZT_ATOMIC_PTR_LOCKED, std::memory_order_acquire);
if (likely(bb != ZT_ATOMIC_PTR_LOCKED)) {
reinterpret_cast<Buf*>(ptr)->__nextInPool = bb;
reinterpret_cast<Buf *>(ptr)->__nextInPool = bb;
s_pool.store(reinterpret_cast<uintptr_t>(ptr), std::memory_order_release);
return;
}
@ -84,9 +84,9 @@ void Buf::freePool() noexcept
s_pool.store(0, std::memory_order_release);
while (bb != 0) {
const uintptr_t next = reinterpret_cast<Buf*>(bb)->__nextInPool;
const uintptr_t next = reinterpret_cast<Buf *>(bb)->__nextInPool;
s_allocated.fetch_sub(1, std::memory_order_relaxed);
free(reinterpret_cast<void*>(bb));
free(reinterpret_cast<void *>(bb));
bb = next;
}
@ -97,9 +97,6 @@ void Buf::freePool() noexcept
}
}
long Buf::poolAllocated() noexcept
{
return s_allocated.load(std::memory_order_relaxed);
}
long Buf::poolAllocated() noexcept { return s_allocated.load(std::memory_order_relaxed); }
} // namespace ZeroTier

View file

@ -82,9 +82,9 @@ class Buf {
public:
// New and delete operators that allocate Buf instances from a shared lock-free memory pool.
static void* operator new(std::size_t sz);
static void *operator new(std::size_t sz);
static void operator delete(void* ptr);
static void operator delete(void *ptr);
/**
* Raw data held in buffer
@ -113,29 +113,18 @@ class Buf {
* Slice is almost exactly like the built-in slice data structure in Go
*/
struct Slice : TriviallyCopyable {
ZT_INLINE Slice(const SharedPtr<Buf>& b_, const unsigned int s_, const unsigned int e_) noexcept
ZT_INLINE Slice(const SharedPtr<Buf> &b_, const unsigned int s_, const unsigned int e_) noexcept
: b(b_)
, s(s_)
, e(e_)
{
}
ZT_INLINE Slice() noexcept
: b()
, s(0)
, e(0)
{
}
ZT_INLINE Slice() noexcept : b(), s(0), e(0) {}
ZT_INLINE operator bool() const noexcept
{
return (b);
}
ZT_INLINE operator bool() const noexcept { return (b); }
ZT_INLINE unsigned int size() const noexcept
{
return (e - s);
}
ZT_INLINE unsigned int size() const noexcept { return (e - s); }
ZT_INLINE void zero() noexcept
{
@ -165,9 +154,7 @@ class Buf {
*/
class PacketVector : public ZeroTier::FCV<Slice, ZT_MAX_PACKET_FRAGMENTS> {
public:
ZT_INLINE PacketVector() : ZeroTier::FCV<Slice, ZT_MAX_PACKET_FRAGMENTS>()
{
}
ZT_INLINE PacketVector() : ZeroTier::FCV<Slice, ZT_MAX_PACKET_FRAGMENTS>() {}
ZT_INLINE unsigned int totalSize() const noexcept
{
@ -183,12 +170,12 @@ class Buf {
* @param b Destination buffer
* @return Size of data in destination or -1 on error
*/
ZT_INLINE int mergeCopy(Buf& b) const noexcept
ZT_INLINE int mergeCopy(Buf &b) const noexcept
{
unsigned int size = 0;
for (PacketVector::const_iterator s(begin()); s != end(); ++s) {
const unsigned int start = s->s;
const unsigned int rem = s->e - start;
const unsigned int rem = s->e - start;
if (likely((size + rem) <= ZT_BUF_MEM_SIZE)) {
Utils::copy(b.unsafeData + size, s->b->unsafeData + start, rem);
size += rem;
@ -211,12 +198,13 @@ class Buf {
* @tparam F Type of copyFunction (typically inferred)
* @return Size of data in destination or -1 on error
*/
template <typename F> ZT_INLINE int mergeMap(Buf& b, const unsigned int simpleCopyBefore, F copyFunction) const noexcept
template <typename F>
ZT_INLINE int mergeMap(Buf &b, const unsigned int simpleCopyBefore, F copyFunction) const noexcept
{
unsigned int size = 0;
for (PacketVector::const_iterator s(begin()); s != end(); ++s) {
unsigned int start = s->s;
unsigned int rem = s->e - start;
unsigned int rem = s->e - start;
if (likely((size + rem) <= ZT_BUF_MEM_SIZE)) {
if (size < simpleCopyBefore) {
unsigned int sc = simpleCopyBefore - size;
@ -243,28 +231,22 @@ class Buf {
/**
* Create a new uninitialized buffer with undefined contents (use clear() to zero if needed)
*/
ZT_INLINE Buf() noexcept
: __nextInPool(0)
, __refCount(0)
{
}
ZT_INLINE Buf() noexcept : __nextInPool(0), __refCount(0) {}
/**
* Create a new buffer and copy data into it
*/
ZT_INLINE Buf(const void* const data, const unsigned int len) noexcept : __refCount(0)
ZT_INLINE Buf(const void *const data, const unsigned int len) noexcept : __refCount(0)
{
Utils::copy(unsafeData, data, len);
}
ZT_INLINE Buf(const Buf& b2) noexcept
: __nextInPool(0)
, __refCount(0)
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
ZT_INLINE Buf &operator=(const Buf &b2) noexcept
{
if (this != &b2)
Utils::copy<ZT_BUF_MEM_SIZE>(unsafeData, b2.unsafeData);
@ -280,10 +262,7 @@ class Buf {
* @param ii Iterator to check
* @return True if iterator has read past the size of the buffer
*/
static ZT_INLINE bool writeOverflow(const int& ii) noexcept
{
return ((ii - ZT_BUF_MEM_SIZE) > 0);
}
static ZT_INLINE bool writeOverflow(const int &ii) noexcept { return ((ii - ZT_BUF_MEM_SIZE) > 0); }
/**
* Check for overflow beyond the size of the data that should be in the buffer
@ -295,7 +274,7 @@ class Buf {
* @param size Size of data that should be in buffer
* @return True if iterator has read past the size of the data
*/
static ZT_INLINE bool readOverflow(const int& ii, const unsigned int size) noexcept
static ZT_INLINE bool readOverflow(const int &ii, const unsigned int size) noexcept
{
return ((ii - (int)size) > 0);
}
@ -303,10 +282,7 @@ class Buf {
/**
* Set all memory to zero
*/
ZT_INLINE void clear() noexcept
{
Utils::zero<ZT_BUF_MEM_SIZE>(unsafeData);
}
ZT_INLINE void clear() noexcept { Utils::zero<ZT_BUF_MEM_SIZE>(unsafeData); }
/**
* Read a byte
@ -314,7 +290,7 @@ class Buf {
* @param ii Index value-result parameter (incremented by 1)
* @return Byte (undefined on overflow)
*/
ZT_INLINE uint8_t rI8(int& ii) const noexcept
ZT_INLINE uint8_t rI8(int &ii) const noexcept
{
const int s = ii++;
return unsafeData[(unsigned int)s & ZT_BUF_MEM_MASK];
@ -326,14 +302,14 @@ class Buf {
* @param ii Index value-result parameter (incremented by 2)
* @return Integer (undefined on overflow)
*/
ZT_INLINE uint16_t rI16(int& ii) const noexcept
ZT_INLINE uint16_t rI16(int &ii) const noexcept
{
const unsigned int s = (unsigned int)ii & ZT_BUF_MEM_MASK;
ii += 2;
#ifdef ZT_NO_UNALIGNED_ACCESS
return (((uint16_t)unsafeData[s] << 8U) | (uint16_t)unsafeData[s + 1]);
#else
return Utils::ntoh(*reinterpret_cast<const uint16_t*>(unsafeData + s));
return Utils::ntoh(*reinterpret_cast<const uint16_t *>(unsafeData + s));
#endif
}
@ -343,14 +319,16 @@ class Buf {
* @param ii Index value-result parameter (incremented by 4)
* @return Integer (undefined on overflow)
*/
ZT_INLINE uint32_t rI32(int& ii) const noexcept
ZT_INLINE uint32_t rI32(int &ii) const noexcept
{
const unsigned int s = (unsigned int)ii & ZT_BUF_MEM_MASK;
ii += 4;
#ifdef ZT_NO_UNALIGNED_ACCESS
return (((uint32_t)unsafeData[s] << 24U) | ((uint32_t)unsafeData[s + 1] << 16U) | ((uint32_t)unsafeData[s + 2] << 8U) | (uint32_t)unsafeData[s + 3]);
return (
((uint32_t)unsafeData[s] << 24U) | ((uint32_t)unsafeData[s + 1] << 16U)
| ((uint32_t)unsafeData[s + 2] << 8U) | (uint32_t)unsafeData[s + 3]);
#else
return Utils::ntoh(*reinterpret_cast<const uint32_t*>(unsafeData + s));
return Utils::ntoh(*reinterpret_cast<const uint32_t *>(unsafeData + s));
#endif
}
@ -360,16 +338,18 @@ class Buf {
* @param ii Index value-result parameter (incremented by 8)
* @return Integer (undefined on overflow)
*/
ZT_INLINE uint64_t rI64(int& ii) const noexcept
ZT_INLINE uint64_t rI64(int &ii) const noexcept
{
const unsigned int s = (unsigned int)ii & ZT_BUF_MEM_MASK;
ii += 8;
#ifdef ZT_NO_UNALIGNED_ACCESS
return (
((uint64_t)unsafeData[s] << 56U) | ((uint64_t)unsafeData[s + 1] << 48U) | ((uint64_t)unsafeData[s + 2] << 40U) | ((uint64_t)unsafeData[s + 3] << 32U) | ((uint64_t)unsafeData[s + 4] << 24U) | ((uint64_t)unsafeData[s + 5] << 16U)
((uint64_t)unsafeData[s] << 56U) | ((uint64_t)unsafeData[s + 1] << 48U)
| ((uint64_t)unsafeData[s + 2] << 40U) | ((uint64_t)unsafeData[s + 3] << 32U)
| ((uint64_t)unsafeData[s + 4] << 24U) | ((uint64_t)unsafeData[s + 5] << 16U)
| ((uint64_t)unsafeData[s + 6] << 8U) | (uint64_t)unsafeData[s + 7]);
#else
return Utils::ntoh(*reinterpret_cast<const uint64_t*>(unsafeData + s));
return Utils::ntoh(*reinterpret_cast<const uint64_t *>(unsafeData + s));
#endif
}
@ -388,7 +368,7 @@ class Buf {
* @param obj Object to read
* @return Bytes read or a negative value on unmarshal error (passed from object) or overflow
*/
template <typename T> ZT_INLINE int rO(int& ii, T& obj) const noexcept
template <typename T> ZT_INLINE int rO(int &ii, T &obj) const noexcept
{
if (likely(ii < ZT_BUF_MEM_SIZE)) {
int ms = obj.unmarshal(unsafeData + ii, ZT_BUF_MEM_SIZE - ii);
@ -410,10 +390,10 @@ class Buf {
* @param bufSize Capacity of buffer in bytes
* @return Pointer to buf or NULL on overflow or error
*/
ZT_INLINE char* rS(int& ii, char* const buf, const unsigned int bufSize) const noexcept
ZT_INLINE char *rS(int &ii, char *const buf, const unsigned int bufSize) const noexcept
{
const char* const s = (const char*)(unsafeData + ii);
const int sii = ii;
const char *const s = (const char *)(unsafeData + ii);
const int sii = ii;
while (ii < ZT_BUF_MEM_SIZE) {
if (unsafeData[ii++] == 0) {
const int l = ii - sii;
@ -439,9 +419,9 @@ class Buf {
* @param ii Index value-result parameter (incremented by length of string)
* @return Pointer to null-terminated C-style string or NULL on overflow or error
*/
ZT_INLINE const char* rSnc(int& ii) const noexcept
ZT_INLINE const char *rSnc(int &ii) const noexcept
{
const char* const s = (const char*)(unsafeData + ii);
const char *const s = (const char *)(unsafeData + ii);
while (ii < ZT_BUF_MEM_SIZE) {
if (unsafeData[ii++] == 0)
return s;
@ -460,11 +440,11 @@ class Buf {
* @param len Length of buffer
* @return Pointer to data or NULL on overflow or error
*/
ZT_INLINE uint8_t* rB(int& ii, void* const bytes, const unsigned int len) const noexcept
ZT_INLINE uint8_t *rB(int &ii, void *const bytes, const unsigned int len) const noexcept
{
if (likely(((ii += (int)len) <= ZT_BUF_MEM_SIZE))) {
Utils::copy(bytes, unsafeData + ii, len);
return reinterpret_cast<uint8_t*>(bytes);
return reinterpret_cast<uint8_t *>(bytes);
}
return nullptr;
}
@ -482,9 +462,9 @@ class Buf {
* @param len Length of data field to obtain a pointer to
* @return Pointer to field or NULL on overflow
*/
ZT_INLINE const uint8_t* rBnc(int& ii, unsigned int len) const noexcept
ZT_INLINE const uint8_t *rBnc(int &ii, unsigned int len) const noexcept
{
const uint8_t* const b = unsafeData + ii;
const uint8_t *const b = unsafeData + ii;
return ((ii += (int)len) <= ZT_BUF_MEM_SIZE) ? b : nullptr;
}
@ -512,7 +492,7 @@ class Buf {
#ifdef ZT_NO_UNALIGNED_ACCESS
return (((uint16_t)unsafeData[I] << 8U) | (uint16_t)unsafeData[I + 1]);
#else
return Utils::ntoh(*reinterpret_cast<const uint16_t*>(unsafeData + I));
return Utils::ntoh(*reinterpret_cast<const uint16_t *>(unsafeData + I));
#endif
}
@ -526,9 +506,11 @@ class Buf {
{
static_assert((I + 3) < ZT_BUF_MEM_SIZE, "overflow");
#ifdef ZT_NO_UNALIGNED_ACCESS
return (((uint32_t)unsafeData[I] << 24U) | ((uint32_t)unsafeData[I + 1] << 16U) | ((uint32_t)unsafeData[I + 2] << 8U) | (uint32_t)unsafeData[I + 3]);
return (
((uint32_t)unsafeData[I] << 24U) | ((uint32_t)unsafeData[I + 1] << 16U)
| ((uint32_t)unsafeData[I + 2] << 8U) | (uint32_t)unsafeData[I + 3]);
#else
return Utils::ntoh(*reinterpret_cast<const uint32_t*>(unsafeData + I));
return Utils::ntoh(*reinterpret_cast<const uint32_t *>(unsafeData + I));
#endif
}
@ -543,10 +525,12 @@ class Buf {
static_assert((I + 7) < ZT_BUF_MEM_SIZE, "overflow");
#ifdef ZT_NO_UNALIGNED_ACCESS
return (
((uint64_t)unsafeData[I] << 56U) | ((uint64_t)unsafeData[I + 1] << 48U) | ((uint64_t)unsafeData[I + 2] << 40U) | ((uint64_t)unsafeData[I + 3] << 32U) | ((uint64_t)unsafeData[I + 4] << 24U) | ((uint64_t)unsafeData[I + 5] << 16U)
((uint64_t)unsafeData[I] << 56U) | ((uint64_t)unsafeData[I + 1] << 48U)
| ((uint64_t)unsafeData[I + 2] << 40U) | ((uint64_t)unsafeData[I + 3] << 32U)
| ((uint64_t)unsafeData[I + 4] << 24U) | ((uint64_t)unsafeData[I + 5] << 16U)
| ((uint64_t)unsafeData[I + 6] << 8U) | (uint64_t)unsafeData[I + 7]);
#else
return Utils::ntoh(*reinterpret_cast<const uint64_t*>(unsafeData + I));
return Utils::ntoh(*reinterpret_cast<const uint64_t *>(unsafeData + I));
#endif
}
@ -557,10 +541,7 @@ class Buf {
* will not necessarily result in a 'true' return from readOverflow(). It does
* however subject 'ii' to soft bounds masking like the gI??() methods.
*/
ZT_INLINE uint8_t lI8(const int ii) const noexcept
{
return unsafeData[(unsigned int)ii & ZT_BUF_MEM_MASK];
}
ZT_INLINE uint8_t lI8(const int ii) const noexcept { return unsafeData[(unsigned int)ii & ZT_BUF_MEM_MASK]; }
/**
* Load a value at an index without advancing the index
@ -575,7 +556,7 @@ class Buf {
#ifdef ZT_NO_UNALIGNED_ACCESS
return (((uint16_t)unsafeData[s] << 8U) | (uint16_t)unsafeData[s + 1]);
#else
return Utils::ntoh(*reinterpret_cast<const uint16_t*>(unsafeData + s));
return Utils::ntoh(*reinterpret_cast<const uint16_t *>(unsafeData + s));
#endif
}
@ -590,9 +571,11 @@ class Buf {
{
const unsigned int s = (unsigned int)ii & ZT_BUF_MEM_MASK;
#ifdef ZT_NO_UNALIGNED_ACCESS
return (((uint32_t)unsafeData[s] << 24U) | ((uint32_t)unsafeData[s + 1] << 16U) | ((uint32_t)unsafeData[s + 2] << 8U) | (uint32_t)unsafeData[s + 3]);
return (
((uint32_t)unsafeData[s] << 24U) | ((uint32_t)unsafeData[s + 1] << 16U)
| ((uint32_t)unsafeData[s + 2] << 8U) | (uint32_t)unsafeData[s + 3]);
#else
return Utils::ntoh(*reinterpret_cast<const uint32_t*>(unsafeData + s));
return Utils::ntoh(*reinterpret_cast<const uint32_t *>(unsafeData + s));
#endif
}
@ -608,10 +591,12 @@ class Buf {
const unsigned int s = (unsigned int)ii & ZT_BUF_MEM_MASK;
#ifdef ZT_NO_UNALIGNED_ACCESS
return (
((uint64_t)unsafeData[s] << 56U) | ((uint64_t)unsafeData[s + 1] << 48U) | ((uint64_t)unsafeData[s + 2] << 40U) | ((uint64_t)unsafeData[s + 3] << 32U) | ((uint64_t)unsafeData[s + 4] << 24U) | ((uint64_t)unsafeData[s + 5] << 16U)
((uint64_t)unsafeData[s] << 56U) | ((uint64_t)unsafeData[s + 1] << 48U)
| ((uint64_t)unsafeData[s + 2] << 40U) | ((uint64_t)unsafeData[s + 3] << 32U)
| ((uint64_t)unsafeData[s + 4] << 24U) | ((uint64_t)unsafeData[s + 5] << 16U)
| ((uint64_t)unsafeData[s + 6] << 8U) | (uint64_t)unsafeData[s + 7]);
#else
return Utils::ntoh(*reinterpret_cast<const uint64_t*>(unsafeData + s));
return Utils::ntoh(*reinterpret_cast<const uint64_t *>(unsafeData + s));
#endif
}
@ -621,9 +606,9 @@ class Buf {
* @param ii Index value-result parameter (incremented by 1)
* @param n Byte
*/
ZT_INLINE void wI8(int& ii, const uint8_t n) noexcept
ZT_INLINE void wI8(int &ii, const uint8_t n) noexcept
{
const int s = ii++;
const int s = ii++;
unsafeData[(unsigned int)s & ZT_BUF_MEM_MASK] = n;
}
@ -633,15 +618,15 @@ class Buf {
* @param ii Index value-result parameter (incremented by 2)
* @param n Integer
*/
ZT_INLINE void wI16(int& ii, const uint16_t n) noexcept
ZT_INLINE void wI16(int &ii, const uint16_t n) noexcept
{
const unsigned int s = ((unsigned int)ii) & ZT_BUF_MEM_MASK;
ii += 2;
#ifdef ZT_NO_UNALIGNED_ACCESS
unsafeData[s] = (uint8_t)(n >> 8U);
unsafeData[s] = (uint8_t)(n >> 8U);
unsafeData[s + 1] = (uint8_t)n;
#else
*reinterpret_cast<uint16_t*>(unsafeData + s) = Utils::hton(n);
*reinterpret_cast<uint16_t *>(unsafeData + s) = Utils::hton(n);
#endif
}
@ -651,17 +636,17 @@ class Buf {
* @param ii Index value-result parameter (incremented by 4)
* @param n Integer
*/
ZT_INLINE void wI32(int& ii, const uint32_t n) noexcept
ZT_INLINE void wI32(int &ii, const uint32_t n) noexcept
{
const unsigned int s = ((unsigned int)ii) & ZT_BUF_MEM_MASK;
ii += 4;
#ifdef ZT_NO_UNALIGNED_ACCESS
unsafeData[s] = (uint8_t)(n >> 24U);
unsafeData[s] = (uint8_t)(n >> 24U);
unsafeData[s + 1] = (uint8_t)(n >> 16U);
unsafeData[s + 2] = (uint8_t)(n >> 8U);
unsafeData[s + 3] = (uint8_t)n;
#else
*reinterpret_cast<uint32_t*>(unsafeData + s) = Utils::hton(n);
*reinterpret_cast<uint32_t *>(unsafeData + s) = Utils::hton(n);
#endif
}
@ -671,12 +656,12 @@ class Buf {
* @param ii Index value-result parameter (incremented by 8)
* @param n Integer
*/
ZT_INLINE void wI64(int& ii, const uint64_t n) noexcept
ZT_INLINE void wI64(int &ii, const uint64_t n) noexcept
{
const unsigned int s = ((unsigned int)ii) & ZT_BUF_MEM_MASK;
ii += 8;
#ifdef ZT_NO_UNALIGNED_ACCESS
unsafeData[s] = (uint8_t)(n >> 56U);
unsafeData[s] = (uint8_t)(n >> 56U);
unsafeData[s + 1] = (uint8_t)(n >> 48U);
unsafeData[s + 2] = (uint8_t)(n >> 40U);
unsafeData[s + 3] = (uint8_t)(n >> 32U);
@ -685,7 +670,7 @@ class Buf {
unsafeData[s + 6] = (uint8_t)(n >> 8U);
unsafeData[s + 7] = (uint8_t)n;
#else
*reinterpret_cast<uint64_t*>(unsafeData + s) = Utils::hton(n);
*reinterpret_cast<uint64_t *>(unsafeData + s) = Utils::hton(n);
#endif
}
@ -696,7 +681,7 @@ class Buf {
* @param ii Index value-result parameter (incremented by size of object)
* @param t Object to write
*/
template <typename T> ZT_INLINE void wO(int& ii, T& t) noexcept
template <typename T> ZT_INLINE void wO(int &ii, T &t) noexcept
{
const int s = ii;
if (likely((s + T::marshalSizeMax()) <= ZT_BUF_MEM_SIZE)) {
@ -715,7 +700,7 @@ class Buf {
* @param ii Index value-result parameter (incremented by length of string)
* @param s String to write (writes an empty string if this is NULL)
*/
ZT_INLINE void wS(int& ii, const char* s) noexcept
ZT_INLINE void wS(int &ii, const char *s) noexcept
{
if (s) {
char c;
@ -736,7 +721,7 @@ class Buf {
* @param bytes Bytes to write
* @param len Size of data in bytes
*/
ZT_INLINE void wB(int& ii, const void* const bytes, const unsigned int len) noexcept
ZT_INLINE void wB(int &ii, const void *const bytes, const unsigned int len) noexcept
{
const int s = ii;
if (likely((ii += (int)len) <= ZT_BUF_MEM_SIZE))
@ -749,7 +734,7 @@ class Buf {
* @param ii Index value-result parameter (incremented by len)
* @param len Number of zero bytes to write
*/
ZT_INLINE void wZ(int& ii, const unsigned int len) noexcept
ZT_INLINE void wZ(int &ii, const unsigned int len) noexcept
{
const int s = ii;
if (likely((ii += (int)len) <= ZT_BUF_MEM_SIZE))
@ -762,7 +747,7 @@ class Buf {
* @param ii Index value-result parameter (incremented by len)
* @param len Number of random bytes to write
*/
ZT_INLINE void wR(int& ii, const unsigned int len) noexcept
ZT_INLINE void wR(int &ii, const unsigned int len) noexcept
{
const int s = ii;
if (likely((ii += (int)len) <= ZT_BUF_MEM_SIZE))
@ -772,10 +757,7 @@ class Buf {
/**
* Store a byte without advancing the index
*/
ZT_INLINE void sI8(const int ii, const uint8_t n) noexcept
{
unsafeData[(unsigned int)ii & ZT_BUF_MEM_MASK] = n;
}
ZT_INLINE void sI8(const int ii, const uint8_t n) noexcept { unsafeData[(unsigned int)ii & ZT_BUF_MEM_MASK] = n; }
/**
* Store an integer without advancing the index
@ -784,10 +766,10 @@ class Buf {
{
const unsigned int s = ((unsigned int)ii) & ZT_BUF_MEM_MASK;
#ifdef ZT_NO_UNALIGNED_ACCESS
unsafeData[s] = (uint8_t)(n >> 8U);
unsafeData[s] = (uint8_t)(n >> 8U);
unsafeData[s + 1] = (uint8_t)n;
#else
*reinterpret_cast<uint16_t*>(unsafeData + s) = Utils::hton(n);
*reinterpret_cast<uint16_t *>(unsafeData + s) = Utils::hton(n);
#endif
}
@ -798,12 +780,12 @@ class Buf {
{
const unsigned int s = ((unsigned int)ii) & ZT_BUF_MEM_MASK;
#ifdef ZT_NO_UNALIGNED_ACCESS
unsafeData[s] = (uint8_t)(n >> 24U);
unsafeData[s] = (uint8_t)(n >> 24U);
unsafeData[s + 1] = (uint8_t)(n >> 16U);
unsafeData[s + 2] = (uint8_t)(n >> 8U);
unsafeData[s + 3] = (uint8_t)n;
#else
*reinterpret_cast<uint32_t*>(unsafeData + s) = Utils::hton(n);
*reinterpret_cast<uint32_t *>(unsafeData + s) = Utils::hton(n);
#endif
}
@ -814,7 +796,7 @@ class Buf {
{
const unsigned int s = ((unsigned int)ii) & ZT_BUF_MEM_MASK;
#ifdef ZT_NO_UNALIGNED_ACCESS
unsafeData[s] = (uint8_t)(n >> 56U);
unsafeData[s] = (uint8_t)(n >> 56U);
unsafeData[s + 1] = (uint8_t)(n >> 48U);
unsafeData[s + 2] = (uint8_t)(n >> 40U);
unsafeData[s + 3] = (uint8_t)(n >> 32U);
@ -823,17 +805,14 @@ class Buf {
unsafeData[s + 6] = (uint8_t)(n >> 8U);
unsafeData[s + 7] = (uint8_t)n;
#else
*reinterpret_cast<uint64_t*>(unsafeData + s) = Utils::hton(n);
*reinterpret_cast<uint64_t *>(unsafeData + s) = Utils::hton(n);
#endif
}
/**
* @return Capacity of this buffer (usable size of data.bytes)
*/
static constexpr unsigned int capacity() noexcept
{
return ZT_BUF_MEM_SIZE;
}
static constexpr unsigned int capacity() noexcept { return ZT_BUF_MEM_SIZE; }
private:
volatile uintptr_t __nextInPool;

View file

@ -27,7 +27,6 @@ namespace {
// --------------------------------------------------------------------------------------------------------------------
#define crypto_uint32 uint32_t
#define crypto_hash_sha512_BYTES 64
typedef uint8_t u8;
typedef int32_t s32;
@ -168,7 +167,7 @@ ZT_INLINE limb div_by_2_25(const limb v)
return (v + roundoff) >> 25;
}
void freduce_coefficients(limb *output)
ZT_INLINE void freduce_coefficients(limb *output)
{
output[10] = 0;
for (int i = 0; i < 10; i += 2) {
@ -183,11 +182,9 @@ void freduce_coefficients(limb *output)
output[0] += output[10] << 1;
output[0] += output[10];
output[10] = 0;
{
limb over = div_by_2_26(output[0]);
output[0] -= over << 26;
output[1] += over;
}
limb over = div_by_2_26(output[0]);
output[0] -= over << 26;
output[1] += over;
}
ZT_INLINE void fmul(limb *output, const limb *in, const limb *in2)
@ -591,11 +588,11 @@ ZT_INLINE void crypto_scalarmult_base(unsigned char *q, const unsigned char *n)
// Ed25519 ref from: http://bench.cr.yp.to/supercop.html
typedef struct {
crypto_uint32 v[32];
uint32_t v[32];
} fe25519;
typedef struct {
crypto_uint32 v[32];
uint32_t v[32];
} sc25519;
typedef struct {
@ -618,15 +615,15 @@ typedef struct {
void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y);
ZT_INLINE crypto_uint32 equal(crypto_uint32 a, crypto_uint32 b)
ZT_INLINE uint32_t equal(uint32_t a, uint32_t b)
{
crypto_uint32 x = a ^ b;
uint32_t x = a ^ b;
x -= 1;
x >>= 31;
return x;
}
ZT_INLINE crypto_uint32 ge(crypto_uint32 a, crypto_uint32 b)
ZT_INLINE uint32_t ge(uint32_t a, uint32_t b)
{
unsigned int x = a;
x -= (unsigned int)b;
@ -635,13 +632,13 @@ ZT_INLINE crypto_uint32 ge(crypto_uint32 a, crypto_uint32 b)
return x;
}
ZT_INLINE crypto_uint32 times19(crypto_uint32 a) { return (a << 4) + (a << 1) + a; }
ZT_INLINE crypto_uint32 times38(crypto_uint32 a) { return (a << 5) + (a << 2) + (a << 1); }
ZT_INLINE uint32_t times19(uint32_t a) { return (a << 4) + (a << 1) + a; }
ZT_INLINE uint32_t times38(uint32_t a) { return (a << 5) + (a << 2) + (a << 1); }
void reduce_add_sub(fe25519 *r)
{
for (int rep = 0; rep < 4; rep++) {
crypto_uint32 t = r->v[31] >> 7;
uint32_t t = r->v[31] >> 7;
r->v[31] &= 127;
t = times19(t);
r->v[0] += t;
@ -656,7 +653,7 @@ void reduce_add_sub(fe25519 *r)
ZT_INLINE void reduce_mul(fe25519 *r)
{
for (int rep = 0; rep < 2; rep++) {
crypto_uint32 t = r->v[31] >> 7;
uint32_t t = r->v[31] >> 7;
r->v[31] &= 127;
t = times19(t);
r->v[0] += t;
@ -670,7 +667,7 @@ ZT_INLINE void reduce_mul(fe25519 *r)
void fe25519_freeze(fe25519 *r)
{
crypto_uint32 mm = equal(r->v[31], 127);
uint32_t mm = equal(r->v[31], 127);
for (int i = 30; i > 0; i--)
mm &= equal(r->v[i], 255);
mm &= ge(r->v[0], 237);
@ -711,8 +708,8 @@ ZT_INLINE int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y)
ZT_INLINE void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b)
{
crypto_uint32 mask = b;
mask = -mask;
uint32_t mask = b;
mask = -mask;
for (int i = 0; i < 32; i++)
r->v[i] ^= mask & (x->v[i] ^ r->v[i]);
}
@ -755,7 +752,7 @@ ZT_INLINE void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y)
void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y)
{
crypto_uint32 t[32];
uint32_t t[32];
t[0] = x->v[0] + 0x1da;
t[31] = x->v[31] + 0xfe;
for (int i = 1; i < 31; i++)
@ -767,7 +764,7 @@ void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y)
void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y)
{
crypto_uint32 t[63];
uint32_t t[63];
for (int i = 0; i < 63; i++)
t[i] = 0;
for (int i = 0; i < 32; i++) {
@ -891,14 +888,15 @@ ZT_INLINE void fe25519_pow2523(fe25519 *r, const fe25519 *x)
fe25519_mul(r, &t, x);
}
const crypto_uint32 m[32] = { 0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7,
0xA2, 0xDE, 0xF9, 0xDE, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 };
const crypto_uint32 mu[33] = { 0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63,
0x08, 0x5D, 0x21, 0x06, 0x21, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F };
const uint32_t m[32] = {
0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
};
const uint32_t mu[33] = { 0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63,
0x08, 0x5D, 0x21, 0x06, 0x21, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F };
ZT_INLINE crypto_uint32 lt(crypto_uint32 a, crypto_uint32 b) /* 16-bit inputs */
ZT_INLINE uint32_t lt(uint32_t a, uint32_t b) /* 16-bit inputs */
{
unsigned int x = a;
x -= (unsigned int)b; /* 0..65535: no; 4294901761..4294967295: yes */
@ -908,9 +906,9 @@ ZT_INLINE crypto_uint32 lt(crypto_uint32 a, crypto_uint32 b) /* 16-bit inputs */
void reduce_add_sub(sc25519 *r)
{
crypto_uint32 pb = 0;
crypto_uint32 b;
crypto_uint32 mask;
uint32_t pb = 0;
uint32_t b;
uint32_t mask;
int i;
unsigned char t[32];
@ -925,15 +923,15 @@ void reduce_add_sub(sc25519 *r)
r->v[i] ^= mask & (r->v[i] ^ t[i]);
}
void barrett_reduce(sc25519 *r, const crypto_uint32 x[64])
void barrett_reduce(sc25519 *r, const uint32_t x[64])
{
/* See HAC, Alg. 14.42 */
int i, j;
crypto_uint32 q2[66];
crypto_uint32 *q3 = q2 + 33;
crypto_uint32 r1[33];
crypto_uint32 r2[33];
crypto_uint32 pb = 0;
uint32_t q2[66];
uint32_t *q3 = q2 + 33;
uint32_t r1[33];
uint32_t r2[33];
uint32_t pb = 0;
Utils::zero<sizeof(q2)>(q2);
// for (i = 0;i < 66;++i) q2[i] = 0;
@ -961,9 +959,9 @@ void barrett_reduce(sc25519 *r, const crypto_uint32 x[64])
for (i = 0; i < 32; i++) {
pb += r2[i];
crypto_uint32 b = lt(r1[i], pb);
r->v[i] = r1[i] - pb + (b << 8);
pb = b;
uint32_t b = lt(r1[i], pb);
r->v[i] = r1[i] - pb + (b << 8);
pb = b;
}
reduce_add_sub(r);
@ -973,7 +971,7 @@ void barrett_reduce(sc25519 *r, const crypto_uint32 x[64])
ZT_INLINE void sc25519_from32bytes(sc25519 *r, const unsigned char x[32])
{
int i;
crypto_uint32 t[64];
uint32_t t[64];
for (i = 0; i < 32; i++)
t[i] = x[i];
for (i = 32; i < 64; ++i)
@ -984,7 +982,7 @@ ZT_INLINE void sc25519_from32bytes(sc25519 *r, const unsigned char x[32])
ZT_INLINE void sc25519_from64bytes(sc25519 *r, const unsigned char x[64])
{
int i;
crypto_uint32 t[64];
uint32_t t[64];
for (i = 0; i < 64; i++)
t[i] = x[i];
barrett_reduce(r, t);
@ -1012,7 +1010,7 @@ ZT_INLINE void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y)
ZT_INLINE void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
{
int i, j;
crypto_uint32 t[64];
uint32_t t[64];
for (i = 0; i < 64; i++)
t[i] = 0;
@ -1077,16 +1075,16 @@ ZT_INLINE void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, con
r[126] = ((s1->v[31] >> 4) & 3) ^ (((s2->v[31] >> 4) & 3) << 2);
}
static const fe25519 ge25519_ecd = { { 0xA3, 0x78, 0x59, 0x13, 0xCA, 0x4D, 0xEB, 0x75, 0xAB, 0xD8, 0x41,
static const fe25519 ge25519_ecd = { { 0xA3, 0x78, 0x59, 0x13, 0xCA, 0x4D, 0xEB, 0x75, 0xAB, 0xD8, 0x41,
0x41, 0x4D, 0x0A, 0x70, 0x00, 0x98, 0xE8, 0x79, 0x77, 0x79, 0x40,
0xC7, 0x8C, 0x73, 0xFE, 0x6F, 0x2B, 0xEE, 0x6C, 0x03, 0x52 } };
static const fe25519 ge25519_ec2d = { { 0x59, 0xF1, 0xB2, 0x26, 0x94, 0x9B, 0xD6, 0xEB, 0x56, 0xB1, 0x83,
static const fe25519 ge25519_ec2d = { { 0x59, 0xF1, 0xB2, 0x26, 0x94, 0x9B, 0xD6, 0xEB, 0x56, 0xB1, 0x83,
0x82, 0x9A, 0x14, 0xE0, 0x00, 0x30, 0xD1, 0xF3, 0xEE, 0xF2, 0x80,
0x8E, 0x19, 0xE7, 0xFC, 0xDF, 0x56, 0xDC, 0xD9, 0x06, 0x24 } };
static const fe25519 ge25519_sqrtm1 = { { 0xB0, 0xA0, 0x0E, 0x4A, 0x27, 0x1B, 0xEE, 0xC4, 0x78, 0xE4, 0x2F,
0xAD, 0x06, 0x18, 0x43, 0x2F, 0xA7, 0xD7, 0xFB, 0x3D, 0x99, 0x00,
0x4D, 0x2B, 0x0B, 0xDF, 0xC1, 0x4F, 0x80, 0x24, 0x83, 0x2B } };
static const ge25519 ge25519_base = {
static const ge25519 ge25519_base = {
{ { 0x1A, 0xD5, 0x25, 0x8F, 0x60, 0x2D, 0x56, 0xC9, 0xB2, 0xA7, 0x25, 0x95, 0x60, 0xC7, 0x2C, 0x69,
0x5C, 0xDC, 0xD6, 0xFD, 0x31, 0xE2, 0xA4, 0xC0, 0xFE, 0x53, 0x6E, 0xCD, 0xD3, 0x36, 0x69, 0x21 } },
{ { 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
@ -1094,7 +1092,8 @@ static const ge25519 ge25519_base = {
{ { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0xA3, 0xDD, 0xB7, 0xA5, 0xB3, 0x8A, 0xDE, 0x6D, 0xF5, 0x52, 0x51, 0x77, 0x80, 0x9F, 0xF0, 0x20,
0x7D, 0xE3, 0xAB, 0x64, 0x8E, 0x4E, 0xEA, 0x66, 0x65, 0x76, 0x8B, 0xD7, 0x0F, 0x5F, 0x87, 0x67 } } };
0x7D, 0xE3, 0xAB, 0x64, 0x8E, 0x4E, 0xEA, 0x66, 0x65, 0x76, 0x8B, 0xD7, 0x0F, 0x5F, 0x87, 0x67 } }
};
static const ge25519_aff ge25519_base_multiples_affine[425] = {
{ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
@ -2886,7 +2885,7 @@ ZT_INLINE void cmov_aff(ge25519_aff *r, const ge25519_aff *p, unsigned char b)
ZT_INLINE unsigned char equal(signed char b, signed char c)
{
unsigned char ub = b, uc = c, x = ub ^ uc;
crypto_uint32 y = x;
uint32_t y = x;
y -= 1;
y >>= 31;
return (unsigned char)y;

View file

@ -40,12 +40,14 @@ class C25519 {
/**
* Generate a set of two 25519 keys: a C25519 ECDH key pair and an Ed25519 EDDSA key pair.
*/
static void generateCombined(uint8_t pub[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE], uint8_t priv[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE]);
static void generateCombined(
uint8_t pub[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE], uint8_t priv[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE]);
/**
* Generate a C25519 ECDH key pair only.
*/
static void generateC25519(uint8_t pub[ZT_C25519_ECDH_PUBLIC_KEY_SIZE], uint8_t priv[ZT_C25519_ECDH_PRIVATE_KEY_SIZE]);
static void
generateC25519(uint8_t pub[ZT_C25519_ECDH_PUBLIC_KEY_SIZE], uint8_t priv[ZT_C25519_ECDH_PRIVATE_KEY_SIZE]);
/**
* Generate a key pair satisfying a condition
@ -60,15 +62,17 @@ class C25519 {
* @return Key pair where cond(kp) returns true
* @tparam F Type of 'cond'
*/
template <typename F> static ZT_INLINE void generateSatisfying(F cond, uint8_t pub[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE], uint8_t priv[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE])
template <typename F>
static ZT_INLINE void generateSatisfying(
F cond, uint8_t pub[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE], uint8_t priv[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE])
{
Utils::getSecureRandom(priv, ZT_C25519_COMBINED_PRIVATE_KEY_SIZE);
s_calcPubED(pub, priv); // do Ed25519 key -- bytes 32-63 of pub and priv
do {
++(((uint64_t*)priv)[1]);
--(((uint64_t*)priv)[2]);
++(((uint64_t *)priv)[1]);
--(((uint64_t *)priv)[2]);
s_calcPubDH(pub, priv); // keep regenerating bytes 0-31 until satisfied
} while (! cond(pub));
} while (!cond(pub));
}
/**
@ -81,7 +85,9 @@ class C25519 {
* @param their Their public key
* @param rawkey Buffer to receive raw (not hashed) agreed upon key
*/
static void agree(const uint8_t mine[ZT_C25519_ECDH_PRIVATE_KEY_SIZE], const uint8_t their[ZT_C25519_ECDH_PUBLIC_KEY_SIZE], uint8_t rawkey[ZT_C25519_ECDH_SHARED_SECRET_SIZE]);
static void agree(
const uint8_t mine[ZT_C25519_ECDH_PRIVATE_KEY_SIZE], const uint8_t their[ZT_C25519_ECDH_PUBLIC_KEY_SIZE],
uint8_t rawkey[ZT_C25519_ECDH_SHARED_SECRET_SIZE]);
/**
* Sign a message with a sender's key pair
@ -100,7 +106,9 @@ class C25519 {
* @param len Length of message in bytes
* @param signature Buffer to fill with signature -- MUST be 96 bytes in length
*/
static void sign(const uint8_t myPrivate[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE], const uint8_t myPublic[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE], const void* msg, unsigned int len, void* signature);
static void sign(
const uint8_t myPrivate[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE],
const uint8_t myPublic[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE], const void *msg, unsigned int len, void *signature);
/**
* Verify a message's signature
@ -112,16 +120,18 @@ class C25519 {
* @param siglen Length of signature in bytes
* @return True if signature is valid and the message is authentic and unmodified
*/
static bool verify(const uint8_t their[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE], const void* msg, unsigned int len, const void* signature, unsigned int siglen);
static bool verify(
const uint8_t their[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE], const void *msg, unsigned int len,
const void *signature, unsigned int siglen);
private:
// derive first 32 bytes of kp.pub from first 32 bytes of kp.priv
// this is the ECDH key
static void s_calcPubDH(uint8_t* pub, const uint8_t* priv);
static void s_calcPubDH(uint8_t *pub, const uint8_t *priv);
// derive 2nd 32 bytes of kp.pub from 2nd 32 bytes of kp.priv
// this is the Ed25519 sign/verify key
static void s_calcPubED(uint8_t* pub, const uint8_t* priv);
static void s_calcPubED(uint8_t *pub, const uint8_t *priv);
};
} // namespace ZeroTier

File diff suppressed because it is too large Load diff

View file

@ -27,9 +27,7 @@ namespace ZeroTier {
*/
class CallContext {
public:
ZT_INLINE CallContext(const int64_t c, const int64_t t, void* const p) : clock(c), ticks(t), tPtr(p)
{
}
ZT_INLINE CallContext(const int64_t c, const int64_t t, void *const p) : clock(c), ticks(t), tPtr(p) {}
/**
* Real world time in milliseconds since Unix epoch or -1 if unknown.
@ -53,7 +51,7 @@ class CallContext {
* By passing this back to callbacks state can be kept by the caller using
* a mechanism that is faster (on most platforms) than thread-local storage.
*/
void* const tPtr;
void *const tPtr;
};
} // namespace ZeroTier

View file

@ -19,7 +19,9 @@
namespace ZeroTier {
CapabilityCredential::CapabilityCredential(const uint32_t id, const uint64_t nwid, const int64_t timestamp, const ZT_VirtualNetworkRule* const rules, const unsigned int ruleCount) noexcept
CapabilityCredential::CapabilityCredential(
const uint32_t id, const uint64_t nwid, const int64_t timestamp, const ZT_VirtualNetworkRule *const rules,
const unsigned int ruleCount) noexcept
: m_nwid(nwid)
, m_timestamp(timestamp)
, m_id(id)
@ -32,11 +34,11 @@ CapabilityCredential::CapabilityCredential(const uint32_t id, const uint64_t nwi
Utils::zero<sizeof(m_signature)>(m_signature);
}
bool CapabilityCredential::sign(const Identity& from, const Address& to) noexcept
bool CapabilityCredential::sign(const Identity &from, const Address &to) noexcept
{
uint8_t buf[ZT_CAPABILITY_MARSHAL_SIZE_MAX + 16];
m_issuedTo = to;
m_signedBy = from.address();
m_issuedTo = to;
m_signedBy = from.address();
m_signatureLength = from.sign(buf, (unsigned int)marshal(buf, true), m_signature, sizeof(m_signature));
return m_signatureLength > 0;
}
@ -63,7 +65,7 @@ int CapabilityCredential::marshal(uint8_t data[ZT_CAPABILITY_MARSHAL_SIZE_MAX],
// chain length. This is deprecated so set the max chain length to one.
data[p++] = (uint8_t)1;
if (! forSign) {
if (!forSign) {
m_issuedTo.copyTo(data + p);
m_signedBy.copyTo(data + p + ZT_ADDRESS_LENGTH);
p += ZT_ADDRESS_LENGTH + ZT_ADDRESS_LENGTH;
@ -89,14 +91,14 @@ int CapabilityCredential::marshal(uint8_t data[ZT_CAPABILITY_MARSHAL_SIZE_MAX],
return p;
}
int CapabilityCredential::unmarshal(const uint8_t* data, int len) noexcept
int CapabilityCredential::unmarshal(const uint8_t *data, int len) noexcept
{
if (len < 22)
return -1;
m_nwid = Utils::loadBigEndian<uint64_t>(data);
m_nwid = Utils::loadBigEndian<uint64_t>(data);
m_timestamp = (int64_t)Utils::loadBigEndian<uint64_t>(data + 8);
m_id = Utils::loadBigEndian<uint32_t>(data + 16);
m_id = Utils::loadBigEndian<uint32_t>(data + 16);
const unsigned int rc = Utils::loadBigEndian<uint16_t>(data + 20);
if (rc > ZT_MAX_CAPABILITY_RULES)
@ -120,7 +122,7 @@ int CapabilityCredential::unmarshal(const uint8_t* data, int len) noexcept
const Address to(data + p);
p += ZT_ADDRESS_LENGTH;
if (! to)
if (!to)
break;
m_issuedTo = to;
@ -149,15 +151,14 @@ int CapabilityCredential::unmarshal(const uint8_t* data, int len) noexcept
return p;
}
int CapabilityCredential::marshalVirtualNetworkRules(uint8_t* data, const ZT_VirtualNetworkRule* const rules, const unsigned int ruleCount) noexcept
int CapabilityCredential::marshalVirtualNetworkRules(
uint8_t *data, const ZT_VirtualNetworkRule *const rules, const unsigned int ruleCount) noexcept
{
int p = 0;
for (unsigned int i = 0; i < ruleCount; ++i) {
data[p++] = rules[i].t;
switch ((ZT_VirtualNetworkRuleType)(rules[i].t & 0x3fU)) {
default:
data[p++] = 0;
break;
default: data[p++] = 0; break;
case ZT_NETWORK_RULE_ACTION_TEE:
case ZT_NETWORK_RULE_ACTION_WATCH:
case ZT_NETWORK_RULE_ACTION_REDIRECT:
@ -197,10 +198,10 @@ int CapabilityCredential::marshalVirtualNetworkRules(uint8_t* data, const ZT_Vir
case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE:
case ZT_NETWORK_RULE_MATCH_IPV4_DEST:
data[p++] = 5;
data[p++] = reinterpret_cast<const uint8_t*>(&(rules[i].v.ipv4.ip))[0];
data[p++] = reinterpret_cast<const uint8_t*>(&(rules[i].v.ipv4.ip))[1];
data[p++] = reinterpret_cast<const uint8_t*>(&(rules[i].v.ipv4.ip))[2];
data[p++] = reinterpret_cast<const uint8_t*>(&(rules[i].v.ipv4.ip))[3];
data[p++] = reinterpret_cast<const uint8_t *>(&(rules[i].v.ipv4.ip))[0];
data[p++] = reinterpret_cast<const uint8_t *>(&(rules[i].v.ipv4.ip))[1];
data[p++] = reinterpret_cast<const uint8_t *>(&(rules[i].v.ipv4.ip))[2];
data[p++] = reinterpret_cast<const uint8_t *>(&(rules[i].v.ipv4.ip))[3];
data[p++] = rules[i].v.ipv4.mask;
break;
case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE:
@ -273,7 +274,8 @@ int CapabilityCredential::marshalVirtualNetworkRules(uint8_t* data, const ZT_Vir
data[p++] = 19;
Utils::storeBigEndian<uint64_t>(data + p, rules[i].v.intRange.start);
p += 8;
Utils::storeBigEndian<uint64_t>(data + p, rules[i].v.intRange.start + (uint64_t)rules[i].v.intRange.end);
Utils::storeBigEndian<uint64_t>(
data + p, rules[i].v.intRange.start + (uint64_t)rules[i].v.intRange.end);
p += 8;
Utils::storeBigEndian<uint16_t>(data + p, rules[i].v.intRange.idx);
p += 2;
@ -284,9 +286,11 @@ int CapabilityCredential::marshalVirtualNetworkRules(uint8_t* data, const ZT_Vir
return p;
}
int CapabilityCredential::unmarshalVirtualNetworkRules(const uint8_t* const data, const int len, ZT_VirtualNetworkRule* const rules, unsigned int& ruleCount, const unsigned int maxRuleCount) noexcept
int CapabilityCredential::unmarshalVirtualNetworkRules(
const uint8_t *const data, const int len, ZT_VirtualNetworkRule *const rules, unsigned int &ruleCount,
const unsigned int maxRuleCount) noexcept
{
int p = 0;
int p = 0;
unsigned int rc = 0;
while (rc < maxRuleCount) {
if (p >= len)
@ -296,8 +300,7 @@ int CapabilityCredential::unmarshalVirtualNetworkRules(const uint8_t* const data
if ((p + fieldLen) > len)
return -1;
switch ((ZT_VirtualNetworkRuleType)(rules[ruleCount].t & 0x3fU)) {
default:
break;
default: break;
case ZT_NETWORK_RULE_ACTION_TEE:
case ZT_NETWORK_RULE_ACTION_WATCH:
case ZT_NETWORK_RULE_ACTION_REDIRECT:
@ -359,7 +362,7 @@ int CapabilityCredential::unmarshalVirtualNetworkRules(const uint8_t* const data
case ZT_NETWORK_RULE_MATCH_IP_TOS:
if ((p + 3) > len)
return -1;
rules[ruleCount].v.ipTos.mask = data[p++];
rules[ruleCount].v.ipTos.mask = data[p++];
rules[ruleCount].v.ipTos.value[0] = data[p++];
rules[ruleCount].v.ipTos.value[1] = data[p++];
break;
@ -377,8 +380,8 @@ int CapabilityCredential::unmarshalVirtualNetworkRules(const uint8_t* const data
case ZT_NETWORK_RULE_MATCH_ICMP:
if ((p + 3) > len)
return -1;
rules[ruleCount].v.icmp.type = data[p++];
rules[ruleCount].v.icmp.code = data[p++];
rules[ruleCount].v.icmp.type = data[p++];
rules[ruleCount].v.icmp.code = data[p++];
rules[ruleCount].v.icmp.flags = data[p++];
break;
case ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE:
@ -429,7 +432,8 @@ int CapabilityCredential::unmarshalVirtualNetworkRules(const uint8_t* const data
return -1;
rules[ruleCount].v.intRange.start = Utils::loadBigEndian<uint64_t>(data + p);
p += 8;
rules[ruleCount].v.intRange.end = (uint32_t)(Utils::loadBigEndian<uint64_t>(data + p) - rules[ruleCount].v.intRange.start);
rules[ruleCount].v.intRange.end =
(uint32_t)(Utils::loadBigEndian<uint64_t>(data + p) - rules[ruleCount].v.intRange.start);
p += 8;
rules[ruleCount].v.intRange.idx = Utils::loadBigEndian<uint16_t>(data + p);
p += 2;

View file

@ -22,7 +22,9 @@
#include "Utils.hpp"
#define ZT_VIRTUALNETWORKRULE_MARSHAL_SIZE_MAX 21
#define ZT_CAPABILITY_MARSHAL_SIZE_MAX (8 + 8 + 4 + 1 + 2 + (ZT_VIRTUALNETWORKRULE_MARSHAL_SIZE_MAX * ZT_MAX_CAPABILITY_RULES) + 2 + (5 + 5 + 1 + 2 + ZT_SIGNATURE_BUFFER_SIZE))
#define ZT_CAPABILITY_MARSHAL_SIZE_MAX \
(8 + 8 + 4 + 1 + 2 + (ZT_VIRTUALNETWORKRULE_MARSHAL_SIZE_MAX * ZT_MAX_CAPABILITY_RULES) + 2 \
+ (5 + 5 + 1 + 2 + ZT_SIGNATURE_BUFFER_SIZE))
namespace ZeroTier {
@ -50,15 +52,9 @@ class CapabilityCredential : public Credential {
friend class Credential;
public:
static constexpr ZT_CredentialType credentialType() noexcept
{
return ZT_CREDENTIAL_TYPE_CAPABILITY;
}
static constexpr ZT_CredentialType credentialType() noexcept { return ZT_CREDENTIAL_TYPE_CAPABILITY; }
ZT_INLINE CapabilityCredential() noexcept
{
memoryZero(this);
}
ZT_INLINE CapabilityCredential() noexcept { memoryZero(this); }
/**
* @param id Capability ID
@ -68,63 +64,35 @@ class CapabilityCredential : public Credential {
* @param rules Network flow rules for this capability
* @param ruleCount Number of flow rules
*/
CapabilityCredential(const uint32_t id, const uint64_t nwid, const int64_t timestamp, const ZT_VirtualNetworkRule* const rules, const unsigned int ruleCount) noexcept;
CapabilityCredential(
const uint32_t id, const uint64_t nwid, const int64_t timestamp, const ZT_VirtualNetworkRule *const rules,
const unsigned int ruleCount) noexcept;
/**
* @return Rules -- see ruleCount() for size of array
*/
ZT_INLINE const ZT_VirtualNetworkRule* rules() const noexcept
{
return m_rules;
}
ZT_INLINE const ZT_VirtualNetworkRule *rules() const noexcept { return m_rules; }
/**
* @return Number of rules in rules()
*/
ZT_INLINE unsigned int ruleCount() const noexcept
{
return m_ruleCount;
}
ZT_INLINE unsigned int ruleCount() const noexcept { return m_ruleCount; }
ZT_INLINE uint32_t id() const noexcept
{
return m_id;
}
ZT_INLINE uint32_t id() const noexcept { return m_id; }
ZT_INLINE uint64_t networkId() const noexcept
{
return m_nwid;
}
ZT_INLINE uint64_t networkId() const noexcept { return m_nwid; }
ZT_INLINE int64_t timestamp() const noexcept
{
return m_timestamp;
}
ZT_INLINE int64_t timestamp() const noexcept { return m_timestamp; }
ZT_INLINE int64_t revision() const noexcept
{
return m_timestamp;
}
ZT_INLINE int64_t revision() const noexcept { return m_timestamp; }
ZT_INLINE const Address& issuedTo() const noexcept
{
return m_issuedTo;
}
ZT_INLINE const Address &issuedTo() const noexcept { return m_issuedTo; }
ZT_INLINE const Address& signer() const noexcept
{
return m_signedBy;
}
ZT_INLINE const Address &signer() const noexcept { return m_signedBy; }
ZT_INLINE const uint8_t* signature() const noexcept
{
return m_signature;
}
ZT_INLINE const uint8_t *signature() const noexcept { return m_signature; }
ZT_INLINE unsigned int signatureLength() const noexcept
{
return m_signatureLength;
}
ZT_INLINE unsigned int signatureLength() const noexcept { return m_signatureLength; }
/**
* Sign this capability and add signature to its chain of custody
@ -139,25 +107,22 @@ class CapabilityCredential : public Credential {
* @param to Recipient of this signature
* @return True if signature successful and chain of custody appended
*/
bool sign(const Identity& from, const Address& to) noexcept;
bool sign(const Identity &from, const Address &to) noexcept;
/**
* Verify this capability's chain of custody and signatures
*
* @param RR Runtime environment to provide for peer lookup, etc.
*/
ZT_INLINE Credential::VerifyResult verify(const Context& ctx, const CallContext& cc) const noexcept
ZT_INLINE Credential::VerifyResult verify(const Context &ctx, const CallContext &cc) const noexcept
{
return s_verify(ctx, cc, *this);
}
static constexpr int marshalSizeMax() noexcept
{
return ZT_CAPABILITY_MARSHAL_SIZE_MAX;
}
static constexpr int marshalSizeMax() noexcept { return ZT_CAPABILITY_MARSHAL_SIZE_MAX; }
int marshal(uint8_t data[ZT_CAPABILITY_MARSHAL_SIZE_MAX], bool forSign = false) const noexcept;
int unmarshal(const uint8_t* data, int len) noexcept;
int unmarshal(const uint8_t *data, int len) noexcept;
/**
* Marshal a set of virtual network rules
@ -167,7 +132,8 @@ class CapabilityCredential : public Credential {
* @param ruleCount Number of rules
* @return Number of bytes written or -1 on error
*/
static int marshalVirtualNetworkRules(uint8_t* data, const ZT_VirtualNetworkRule* rules, unsigned int ruleCount) noexcept;
static int
marshalVirtualNetworkRules(uint8_t *data, const ZT_VirtualNetworkRule *rules, unsigned int ruleCount) noexcept;
/**
* Unmarshal a set of virtual network rules
@ -179,20 +145,19 @@ class CapabilityCredential : public Credential {
* @param maxRuleCount Capacity of rules buffer
* @return Number of bytes unmarshaled or -1 on error
*/
static int unmarshalVirtualNetworkRules(const uint8_t* data, int len, ZT_VirtualNetworkRule* rules, unsigned int& ruleCount, unsigned int maxRuleCount) noexcept;
static int unmarshalVirtualNetworkRules(
const uint8_t *data, int len, ZT_VirtualNetworkRule *rules, unsigned int &ruleCount,
unsigned int maxRuleCount) noexcept;
// Provides natural sort order by ID
ZT_INLINE bool operator<(const CapabilityCredential& c) const noexcept
{
return (m_id < c.m_id);
}
ZT_INLINE bool operator<(const CapabilityCredential &c) const noexcept { return (m_id < c.m_id); }
ZT_INLINE bool operator==(const CapabilityCredential& c) const noexcept
ZT_INLINE bool operator==(const CapabilityCredential &c) const noexcept
{
return (memcmp(this, &c, sizeof(CapabilityCredential)) == 0);
}
ZT_INLINE bool operator!=(const CapabilityCredential& c) const noexcept
ZT_INLINE bool operator!=(const CapabilityCredential &c) const noexcept
{
return (memcmp(this, &c, sizeof(CapabilityCredential)) != 0);
}

View file

@ -345,12 +345,15 @@ bool Certificate::sign(
default: return false;
case ZT_CERTIFICATE_PUBLIC_KEY_ALGORITHM_ECDSA_NIST_P_384:
if (issuerPrivateKeySize == (1 + ZT_ECC384_PUBLIC_KEY_SIZE + ZT_ECC384_PRIVATE_KEY_SIZE)) {
if ((!issuer)||((this->publicKeySize == (ZT_ECC384_PUBLIC_KEY_SIZE + 1))&&(memcmp(issuerPrivateKey, this->publicKey, ZT_ECC384_PUBLIC_KEY_SIZE + 1) == 0))) {
if ((!issuer)
|| ((this->publicKeySize == (ZT_ECC384_PUBLIC_KEY_SIZE + 1))
&& (memcmp(issuerPrivateKey, this->publicKey, ZT_ECC384_PUBLIC_KEY_SIZE + 1) == 0))) {
// If public key and issuer public key match, this is a self-signed certificate.
// This can also be specified by signing with issuer set to NULL.
Utils::fill<sizeof(this->issuer), 0xff>(this->issuer);
this->issuerPublicKeySize = 0;
} else {
}
else {
// Otherwise set the issuer and issuer public key.
Utils::copy<sizeof(this->issuer)>(this->issuer, issuer);
Utils::copy<1 + ZT_ECC384_PUBLIC_KEY_SIZE>(

View file

@ -46,17 +46,17 @@ namespace ZeroTier {
class Certificate : public ZT_Certificate {
public:
Certificate() noexcept;
explicit Certificate(const ZT_Certificate& apiCert);
Certificate(const Certificate& cert);
explicit Certificate(const ZT_Certificate &apiCert);
Certificate(const Certificate &cert);
~Certificate();
Certificate& operator=(const ZT_Certificate& cert);
Certificate &operator=(const ZT_Certificate &cert);
ZT_INLINE Certificate& operator=(const Certificate& cert) noexcept
ZT_INLINE Certificate &operator=(const Certificate &cert) noexcept
{
if (likely(&cert != this)) {
const ZT_Certificate* const sup = &cert;
*this = *sup;
const ZT_Certificate *const sup = &cert;
*this = *sup;
}
return *this;
}
@ -64,17 +64,14 @@ class Certificate : public ZT_Certificate {
/**
* @return Serial number in a H384 object
*/
ZT_INLINE H384 getSerialNo() const noexcept
{
return H384(this->serialNo);
}
ZT_INLINE H384 getSerialNo() const noexcept { return H384(this->serialNo); }
/**
* @return True if this is a self-signed certificate
*/
ZT_INLINE bool isSelfSigned() const noexcept
{
for(unsigned int i=0;i<ZT_CERTIFICATE_HASH_SIZE;++i) {
for (unsigned int i = 0; i < ZT_CERTIFICATE_HASH_SIZE; ++i) {
if (this->issuer[i] != 0xff)
return false;
}
@ -87,7 +84,7 @@ class Certificate : public ZT_Certificate {
* @param id Identity
* @return Pointer to C struct
*/
ZT_Certificate_Identity* addSubjectIdentity(const Identity& id);
ZT_Certificate_Identity *addSubjectIdentity(const Identity &id);
/**
* Add a subject node/identity with a locator
@ -96,7 +93,7 @@ class Certificate : public ZT_Certificate {
* @param loc Locator signed by identity (signature is NOT checked here)
* @return Pointer to C struct
*/
ZT_Certificate_Identity* addSubjectIdentity(const Identity& id, const Locator& loc);
ZT_Certificate_Identity *addSubjectIdentity(const Identity &id, const Locator &loc);
/**
* Add a subject network
@ -105,14 +102,14 @@ class Certificate : public ZT_Certificate {
* @param controller Network controller's full fingerprint
* @return Pointer to C struct
*/
ZT_Certificate_Network* addSubjectNetwork(uint64_t id, const ZT_Fingerprint& controller);
ZT_Certificate_Network *addSubjectNetwork(uint64_t id, const ZT_Fingerprint &controller);
/**
* Add an update URL to the updateUrls list
*
* @param url Update URL
*/
void addSubjectUpdateUrl(const char* url);
void addSubjectUpdateUrl(const char *url);
/**
* Sign subject with unique ID private key and set.
@ -124,7 +121,7 @@ class Certificate : public ZT_Certificate {
* @param uniqueIdPrivateSize Size of private key
* @return True on success
*/
ZT_INLINE bool setSubjectUniqueId(const void* uniqueIdPrivate, unsigned int uniqueIdPrivateSize)
ZT_INLINE bool setSubjectUniqueId(const void *uniqueIdPrivate, unsigned int uniqueIdPrivateSize)
{
return m_setSubjectUniqueId(this->subject, uniqueIdPrivate, uniqueIdPrivateSize);
}
@ -147,7 +144,7 @@ class Certificate : public ZT_Certificate {
* @param len Length of marshalled certificate
* @return True if input is valid and was unmarshalled (signature is NOT checked)
*/
bool decode(const void* data, unsigned int len);
bool decode(const void *data, unsigned int len);
/**
* Sign this certificate.
@ -156,7 +153,9 @@ class Certificate : public ZT_Certificate {
*
* @return True on success
*/
bool sign(const uint8_t issuer[ZT_CERTIFICATE_HASH_SIZE], const void* issuerPrivateKey, unsigned int issuerPrivateKeySize);
bool sign(
const uint8_t issuer[ZT_CERTIFICATE_HASH_SIZE], const void *issuerPrivateKey,
unsigned int issuerPrivateKeySize);
/**
* Verify self-contained signatures and validity of certificate structure
@ -178,7 +177,8 @@ class Certificate : public ZT_Certificate {
*/
ZT_INLINE bool verifyTimeWindow(int64_t clock) const noexcept
{
return ((clock >= this->validity[0]) && (clock <= this->validity[1]) && (this->validity[0] <= this->validity[1]));
return (
(clock >= this->validity[0]) && (clock <= this->validity[1]) && (this->validity[0] <= this->validity[1]));
}
/**
@ -191,7 +191,9 @@ class Certificate : public ZT_Certificate {
* @param privateKeySize Result parameter: set to size of private key
* @return True on success
*/
static bool newKeyPair(const ZT_CertificatePublicKeyAlgorithm type, uint8_t publicKey[ZT_CERTIFICATE_MAX_PUBLIC_KEY_SIZE], int* const publicKeySize, uint8_t privateKey[ZT_CERTIFICATE_MAX_PRIVATE_KEY_SIZE], int* const privateKeySize);
static bool newKeyPair(
const ZT_CertificatePublicKeyAlgorithm type, uint8_t publicKey[ZT_CERTIFICATE_MAX_PUBLIC_KEY_SIZE],
int *const publicKeySize, uint8_t privateKey[ZT_CERTIFICATE_MAX_PRIVATE_KEY_SIZE], int *const privateKeySize);
/**
* Create a CSR that encodes the subject of this certificate
@ -203,47 +205,50 @@ class Certificate : public ZT_Certificate {
* @param uniqueIdPrivateSize Size of unique ID private key
* @return Encoded subject (without any unique ID fields) or empty vector on error
*/
static Vector<uint8_t> createCSR(const ZT_Certificate_Subject& s, const void* certificatePrivateKey, unsigned int certificatePrivateKeySize, const void* uniqueIdPrivate, unsigned int uniqueIdPrivateSize);
static Vector<uint8_t> createCSR(
const ZT_Certificate_Subject &s, const void *certificatePrivateKey, unsigned int certificatePrivateKeySize,
const void *uniqueIdPrivate, unsigned int uniqueIdPrivateSize);
ZT_INLINE unsigned long hashCode() const noexcept
{
return (unsigned long)Utils::loadMachineEndian<uint32_t>(this->serialNo);
}
ZT_INLINE bool operator==(const ZT_Certificate& c) const noexcept
ZT_INLINE bool operator==(const ZT_Certificate &c) const noexcept
{
return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) == 0;
}
ZT_INLINE bool operator!=(const ZT_Certificate& c) const noexcept
ZT_INLINE bool operator!=(const ZT_Certificate &c) const noexcept
{
return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) != 0;
}
ZT_INLINE bool operator<(const ZT_Certificate& c) const noexcept
ZT_INLINE bool operator<(const ZT_Certificate &c) const noexcept
{
return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) < 0;
}
ZT_INLINE bool operator<=(const ZT_Certificate& c) const noexcept
ZT_INLINE bool operator<=(const ZT_Certificate &c) const noexcept
{
return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) <= 0;
}
ZT_INLINE bool operator>(const ZT_Certificate& c) const noexcept
ZT_INLINE bool operator>(const ZT_Certificate &c) const noexcept
{
return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) > 0;
}
ZT_INLINE bool operator>=(const ZT_Certificate& c) const noexcept
ZT_INLINE bool operator>=(const ZT_Certificate &c) const noexcept
{
return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) >= 0;
}
private:
void m_clear();
static bool m_setSubjectUniqueId(ZT_Certificate_Subject& s, const void* uniqueIdPrivate, unsigned int uniqueIdPrivateSize);
static void m_encodeSubject(const ZT_Certificate_Subject& s, Dictionary& d, bool omitUniqueIdProofSignature);
static bool
m_setSubjectUniqueId(ZT_Certificate_Subject &s, const void *uniqueIdPrivate, unsigned int uniqueIdPrivateSize);
static void m_encodeSubject(const ZT_Certificate_Subject &s, Dictionary &d, bool omitUniqueIdProofSignature);
// These hold any identity or locator objects that are owned by and should
// be deleted with this certificate. Lists are used so the pointers never
@ -255,7 +260,7 @@ class Certificate : public ZT_Certificate {
// These are stored in a vector because the memory needs to be contiguous.
Vector<ZT_Certificate_Identity> m_subjectIdentities;
Vector<ZT_Certificate_Network> m_subjectNetworks;
Vector<const char*> m_updateUrls;
Vector<const char *> m_updateUrls;
Vector<uint8_t> m_extendedAttributes;
};

View file

@ -38,13 +38,9 @@ namespace ZeroTier {
template <typename V> class Vector : public std::vector<V> {
public:
ZT_INLINE Vector() : std::vector<V>()
{
}
ZT_INLINE Vector() : std::vector<V>() {}
template <typename I> ZT_INLINE Vector(I begin, I end) : std::vector<V>(begin, end)
{
}
template <typename I> ZT_INLINE Vector(I begin, I end) : std::vector<V>(begin, end) {}
};
template <typename V> class List : public std::list<V> {
@ -53,12 +49,9 @@ template <typename V> class List : public std::list<V> {
#ifdef __CPP11__
struct intl_MapHasher {
template <typename O> std::size_t operator()(const O& obj) const noexcept
{
return (std::size_t)obj.hashCode();
}
template <typename O> std::size_t operator()(const O &obj) const noexcept { return (std::size_t)obj.hashCode(); }
std::size_t operator()(const Vector<uint8_t>& bytes) const noexcept
std::size_t operator()(const Vector<uint8_t> &bytes) const noexcept
{
return (std::size_t)Utils::fnv1a32(bytes.data(), (unsigned int)bytes.size());
}
@ -87,7 +80,8 @@ struct intl_MapHasher {
template <typename K, typename V> class Map : public std::unordered_map<K, V, intl_MapHasher> {
};
template <typename K, typename V> class MultiMap : public std::unordered_multimap<K, V, intl_MapHasher, std::equal_to<K> > {
template <typename K, typename V>
class MultiMap : public std::unordered_multimap<K, V, intl_MapHasher, std::equal_to<K>> {
};
#else
@ -115,7 +109,7 @@ template <typename V> class ForwardList : public std::list<V> {
#endif
template <typename V> class Set : public std::set<V, std::less<V> > {
template <typename V> class Set : public std::set<V, std::less<V>> {
};
typedef std::string String;
@ -126,66 +120,45 @@ typedef std::string String;
struct H384 {
uint64_t data[6];
ZT_INLINE H384() noexcept
{
Utils::zero<sizeof(data)>(data);
}
ZT_INLINE H384() noexcept { Utils::zero<sizeof(data)>(data); }
ZT_INLINE H384(const H384& b) noexcept
{
Utils::copy<48>(data, b.data);
}
ZT_INLINE H384(const H384 &b) noexcept { Utils::copy<48>(data, b.data); }
explicit ZT_INLINE H384(const void* const d) noexcept
{
Utils::copy<48>(data, d);
}
explicit ZT_INLINE H384(const void *const d) noexcept { Utils::copy<48>(data, d); }
ZT_INLINE H384& operator=(const H384& b) noexcept
ZT_INLINE H384 &operator=(const H384 &b) noexcept
{
Utils::copy<48>(data, b.data);
return *this;
}
ZT_INLINE unsigned long hashCode() const noexcept
{
return (unsigned long)data[0];
}
ZT_INLINE unsigned long hashCode() const noexcept { return (unsigned long)data[0]; }
ZT_INLINE operator bool() const noexcept
{
return ((data[0] != 0) && (data[1] != 0) && (data[2] != 0) && (data[3] != 0) && (data[4] != 0) && (data[5] != 0));
return (
(data[0] != 0) && (data[1] != 0) && (data[2] != 0) && (data[3] != 0) && (data[4] != 0) && (data[5] != 0));
}
ZT_INLINE bool operator==(const H384& b) const noexcept
ZT_INLINE bool operator==(const H384 &b) const noexcept
{
return ((data[0] == b.data[0]) && (data[1] == b.data[1]) && (data[2] == b.data[2]) && (data[3] == b.data[3]) && (data[4] == b.data[4]) && (data[5] == b.data[5]));
return (
(data[0] == b.data[0]) && (data[1] == b.data[1]) && (data[2] == b.data[2]) && (data[3] == b.data[3])
&& (data[4] == b.data[4]) && (data[5] == b.data[5]));
}
ZT_INLINE bool operator!=(const H384& b) const noexcept
{
return ! (*this == b);
}
ZT_INLINE bool operator!=(const H384 &b) const noexcept { return !(*this == b); }
ZT_INLINE bool operator<(const H384& b) const noexcept
ZT_INLINE bool operator<(const H384 &b) const noexcept
{
return std::lexicographical_compare(data, data + 6, b.data, b.data + 6);
}
ZT_INLINE bool operator<=(const H384& b) const noexcept
{
return ! (b < *this);
}
ZT_INLINE bool operator<=(const H384 &b) const noexcept { return !(b < *this); }
ZT_INLINE bool operator>(const H384& b) const noexcept
{
return (b < *this);
}
ZT_INLINE bool operator>(const H384 &b) const noexcept { return (b < *this); }
ZT_INLINE bool operator>=(const H384& b) const noexcept
{
return ! (*this < b);
}
ZT_INLINE bool operator>=(const H384 &b) const noexcept { return !(*this < b); }
};
static_assert(sizeof(H384) == 48, "H384 contains unnecessary padding");
@ -198,22 +171,13 @@ static_assert(sizeof(H384) == 48, "H384 contains unnecessary padding");
template <unsigned long S> struct Blob {
uint8_t data[S];
ZT_INLINE Blob() noexcept
{
Utils::zero<S>(data);
}
ZT_INLINE Blob() noexcept { Utils::zero<S>(data); }
ZT_INLINE Blob(const Blob& b) noexcept
{
Utils::copy<S>(data, b.data);
}
ZT_INLINE Blob(const Blob &b) noexcept { Utils::copy<S>(data, b.data); }
explicit ZT_INLINE Blob(const void* const d) noexcept
{
Utils::copy<S>(data, d);
}
explicit ZT_INLINE Blob(const void *const d) noexcept { Utils::copy<S>(data, d); }
explicit ZT_INLINE Blob(const void* const d, const unsigned int l) noexcept
explicit ZT_INLINE Blob(const void *const d, const unsigned int l) noexcept
{
Utils::copy(data, d, (l > (unsigned int)S) ? (unsigned int)S : l);
if (l < S) {
@ -221,51 +185,27 @@ template <unsigned long S> struct Blob {
}
}
ZT_INLINE Blob& operator=(const Blob& b) noexcept
ZT_INLINE Blob &operator=(const Blob &b) noexcept
{
Utils::copy<S>(data, b.data);
return *this;
}
ZT_INLINE unsigned long hashCode() const noexcept
{
return Utils::fnv1a32(data, (unsigned int)S);
}
ZT_INLINE unsigned long hashCode() const noexcept { return Utils::fnv1a32(data, (unsigned int)S); }
ZT_INLINE operator bool() const noexcept
{
return Utils::allZero(data, (unsigned int)S);
}
ZT_INLINE operator bool() const noexcept { return Utils::allZero(data, (unsigned int)S); }
ZT_INLINE bool operator==(const Blob& b) const noexcept
{
return (memcmp(data, b.data, S) == 0);
}
ZT_INLINE bool operator==(const Blob &b) const noexcept { return (memcmp(data, b.data, S) == 0); }
ZT_INLINE bool operator!=(const Blob& b) const noexcept
{
return (memcmp(data, b.data, S) != 0);
}
ZT_INLINE bool operator!=(const Blob &b) const noexcept { return (memcmp(data, b.data, S) != 0); }
ZT_INLINE bool operator<(const Blob& b) const noexcept
{
return (memcmp(data, b.data, S) < 0);
}
ZT_INLINE bool operator<(const Blob &b) const noexcept { return (memcmp(data, b.data, S) < 0); }
ZT_INLINE bool operator<=(const Blob& b) const noexcept
{
return (memcmp(data, b.data, S) <= 0);
}
ZT_INLINE bool operator<=(const Blob &b) const noexcept { return (memcmp(data, b.data, S) <= 0); }
ZT_INLINE bool operator>(const Blob& b) const noexcept
{
return (memcmp(data, b.data, S) > 0);
}
ZT_INLINE bool operator>(const Blob &b) const noexcept { return (memcmp(data, b.data, S) > 0); }
ZT_INLINE bool operator>=(const Blob& b) const noexcept
{
return (memcmp(data, b.data, S) >= 0);
}
ZT_INLINE bool operator>=(const Blob &b) const noexcept { return (memcmp(data, b.data, S) >= 0); }
};
} // namespace ZeroTier

View file

@ -40,7 +40,7 @@ class Network;
*/
class Context {
public:
ZT_INLINE Context(Node* const n) noexcept
ZT_INLINE Context(Node *const n) noexcept
: instanceId(Utils::getSecureRandomU64())
, node(n)
, uPtr(nullptr)
@ -59,35 +59,32 @@ class Context {
secretIdentityStr[0] = 0;
}
ZT_INLINE ~Context() noexcept
{
Utils::burn(secretIdentityStr, sizeof(secretIdentityStr));
}
ZT_INLINE ~Context() noexcept { Utils::burn(secretIdentityStr, sizeof(secretIdentityStr)); }
// Unique ID generated on startup
const uint64_t instanceId;
// Node instance that owns this RuntimeEnvironment
Node* const restrict node;
Node *const restrict node;
// Callbacks specified by caller who created node
ZT_Node_Callbacks cb;
// User pointer specified by external code via API
void* restrict uPtr;
void *restrict uPtr;
// This is set externally to an instance of this base class
NetworkController* restrict localNetworkController;
NetworkController *restrict localNetworkController;
Store* restrict store;
TinyMap<SharedPtr<Network> >* restrict networks;
Trace* restrict t;
Expect* restrict expect;
VL2* restrict vl2;
VL1* restrict vl1;
Topology* restrict topology;
SelfAwareness* restrict sa;
TrustStore* restrict ts;
Store *restrict store;
TinyMap<SharedPtr<Network>> *restrict networks;
Trace *restrict t;
Expect *restrict expect;
VL2 *restrict vl2;
VL1 *restrict vl1;
Topology *restrict topology;
SelfAwareness *restrict sa;
TrustStore *restrict ts;
// This node's identity and string representations thereof
Identity identity;

View file

@ -43,24 +43,28 @@
namespace ZeroTier {
template <typename CRED> static ZT_INLINE Credential::VerifyResult p_credVerify(const Context& ctx, const CallContext& cc, CRED credential)
template <typename CRED>
static ZT_INLINE Credential::VerifyResult p_credVerify(const Context &ctx, const CallContext &cc, CRED credential)
{
uint8_t tmp[ZT_BUF_MEM_SIZE + 16];
const Address signedBy(credential.signer());
const uint64_t networkId = credential.networkId();
if ((! signedBy) || (signedBy != Network::controllerFor(networkId)))
if ((!signedBy) || (signedBy != Network::controllerFor(networkId)))
return Credential::VERIFY_BAD_SIGNATURE;
const SharedPtr<Peer> peer(ctx.topology->peer(cc, signedBy));
if (! peer)
if (!peer)
return Credential::VERIFY_NEED_IDENTITY;
try {
int l = credential.marshal(tmp, true);
if (l <= 0)
return Credential::VERIFY_BAD_SIGNATURE;
return (peer->identity().verify(tmp, (unsigned int)l, credential.signature(), credential.signatureLength()) ? Credential::VERIFY_OK : Credential::VERIFY_BAD_SIGNATURE);
return (
peer->identity().verify(tmp, (unsigned int)l, credential.signature(), credential.signatureLength())
? Credential::VERIFY_OK
: Credential::VERIFY_BAD_SIGNATURE);
}
catch (...) {
}
@ -68,41 +72,48 @@ template <typename CRED> static ZT_INLINE Credential::VerifyResult p_credVerify(
return Credential::VERIFY_BAD_SIGNATURE;
}
Credential::VerifyResult Credential::s_verify(const Context& ctx, const CallContext& cc, const RevocationCredential& credential)
Credential::VerifyResult
Credential::s_verify(const Context &ctx, const CallContext &cc, const RevocationCredential &credential)
{
return p_credVerify(ctx, cc, credential);
}
Credential::VerifyResult Credential::s_verify(const Context& ctx, const CallContext& cc, const TagCredential& credential)
Credential::VerifyResult
Credential::s_verify(const Context &ctx, const CallContext &cc, const TagCredential &credential)
{
return p_credVerify(ctx, cc, credential);
}
Credential::VerifyResult Credential::s_verify(const Context& ctx, const CallContext& cc, const CapabilityCredential& credential)
Credential::VerifyResult
Credential::s_verify(const Context &ctx, const CallContext &cc, const CapabilityCredential &credential)
{
return p_credVerify(ctx, cc, credential);
}
Credential::VerifyResult Credential::s_verify(const Context& ctx, const CallContext& cc, const OwnershipCredential& credential)
Credential::VerifyResult
Credential::s_verify(const Context &ctx, const CallContext &cc, const OwnershipCredential &credential)
{
return p_credVerify(ctx, cc, credential);
}
Credential::VerifyResult Credential::s_verify(const Context& ctx, const CallContext& cc, const MembershipCredential& credential)
Credential::VerifyResult
Credential::s_verify(const Context &ctx, const CallContext &cc, const MembershipCredential &credential)
{
// Sanity check network ID.
if ((! credential.m_signedBy) || (credential.m_signedBy != Network::controllerFor(credential.m_networkId)))
if ((!credential.m_signedBy) || (credential.m_signedBy != Network::controllerFor(credential.m_networkId)))
return Credential::VERIFY_BAD_SIGNATURE;
// If we don't know the peer, get its identity. This shouldn't happen here but should be handled.
const SharedPtr<Peer> peer(ctx.topology->peer(cc, credential.m_signedBy));
if (! peer)
if (!peer)
return Credential::VERIFY_NEED_IDENTITY;
// Now verify the controller's signature.
uint64_t buf[ZT_MEMBERSHIP_CREDENTIAL_MARSHAL_SIZE_MAX / 8];
const unsigned int bufSize = credential.m_fillSigningBuf(buf);
return peer->identity().verify(buf, bufSize, credential.m_signature, credential.m_signatureLength) ? Credential::VERIFY_OK : Credential::VERIFY_BAD_SIGNATURE;
return peer->identity().verify(buf, bufSize, credential.m_signature, credential.m_signatureLength)
? Credential::VERIFY_OK
: Credential::VERIFY_BAD_SIGNATURE;
}
} // namespace ZeroTier

View file

@ -43,11 +43,11 @@ class Credential : public TriviallyCopyable {
enum VerifyResult { VERIFY_OK = 0, VERIFY_BAD_SIGNATURE = 1, VERIFY_NEED_IDENTITY = 2 };
protected:
static VerifyResult s_verify(const Context& ctx, const CallContext& cc, const MembershipCredential& credential);
static VerifyResult s_verify(const Context& ctx, const CallContext& cc, const RevocationCredential& credential);
static VerifyResult s_verify(const Context& ctx, const CallContext& cc, const TagCredential& credential);
static VerifyResult s_verify(const Context& ctx, const CallContext& cc, const OwnershipCredential& credential);
static VerifyResult s_verify(const Context& ctx, const CallContext& cc, const CapabilityCredential& credential);
static VerifyResult s_verify(const Context &ctx, const CallContext &cc, const MembershipCredential &credential);
static VerifyResult s_verify(const Context &ctx, const CallContext &cc, const RevocationCredential &credential);
static VerifyResult s_verify(const Context &ctx, const CallContext &cc, const TagCredential &credential);
static VerifyResult s_verify(const Context &ctx, const CallContext &cc, const OwnershipCredential &credential);
static VerifyResult s_verify(const Context &ctx, const CallContext &cc, const CapabilityCredential &credential);
};
} // namespace ZeroTier

View file

@ -16,7 +16,7 @@
namespace ZeroTier {
namespace Defaults {
const uint8_t* CERTIFICATE[DEFAULT_CERTIFICATE_COUNT] = {};
const uint8_t *CERTIFICATE[DEFAULT_CERTIFICATE_COUNT] = {};
unsigned int CERTIFICATE_SIZE[DEFAULT_CERTIFICATE_COUNT] = {};

View file

@ -21,7 +21,7 @@ namespace Defaults {
#define DEFAULT_CERTIFICATE_COUNT 0
extern const uint8_t* CERTIFICATE[DEFAULT_CERTIFICATE_COUNT];
extern const uint8_t *CERTIFICATE[DEFAULT_CERTIFICATE_COUNT];
extern unsigned int CERTIFICATE_SIZE[DEFAULT_CERTIFICATE_COUNT];
} // namespace Defaults

View file

@ -46,7 +46,10 @@ namespace ZeroTier {
* @tparam GCT Garbage collection trigger threshold, usually 2X GCS (default: ZT_MAX_PACKET_FRAGMENTS * 4)
* @tparam P Type for pointer to a path object (default: SharedPtr<Path>)
*/
template <unsigned int MF = ZT_MAX_PACKET_FRAGMENTS, unsigned int MFP = ZT_MAX_INCOMING_FRAGMENTS_PER_PATH, unsigned int GCS = (ZT_MAX_PACKET_FRAGMENTS * 2), unsigned int GCT = (ZT_MAX_PACKET_FRAGMENTS * 4), typename P = SharedPtr<Path> >
template <
unsigned int MF = ZT_MAX_PACKET_FRAGMENTS, unsigned int MFP = ZT_MAX_INCOMING_FRAGMENTS_PER_PATH,
unsigned int GCS = (ZT_MAX_PACKET_FRAGMENTS * 2), unsigned int GCT = (ZT_MAX_PACKET_FRAGMENTS * 4),
typename P = SharedPtr<Path>>
class Defragmenter {
public:
/**
@ -90,9 +93,7 @@ class Defragmenter {
ERR_OUT_OF_MEMORY
};
ZT_INLINE Defragmenter()
{
}
ZT_INLINE Defragmenter() {}
/**
* Process a fragment of a multi-part message
@ -136,15 +137,9 @@ class Defragmenter {
* @return Result code
*/
ZT_INLINE ResultCode assemble(
const uint64_t messageId,
FCV<Buf::Slice, MF>& message,
SharedPtr<Buf>& fragment,
const unsigned int fragmentDataIndex,
const unsigned int fragmentDataSize,
const unsigned int fragmentNo,
const unsigned int totalFragmentsExpected,
const int64_t ts,
const P& via)
const uint64_t messageId, FCV<Buf::Slice, MF> &message, SharedPtr<Buf> &fragment,
const unsigned int fragmentDataIndex, const unsigned int fragmentDataSize, const unsigned int fragmentNo,
const unsigned int totalFragmentsExpected, const int64_t ts, const P &via)
{
// Sanity checks for malformed fragments or invalid input parameters.
if ((fragmentNo >= totalFragmentsExpected) || (totalFragmentsExpected > MF) || (totalFragmentsExpected == 0))
@ -162,7 +157,7 @@ class Defragmenter {
// under the target size. This tries to minimize the amount of time the write
// lock is held since many threads can hold the read lock but all threads must
// wait if someone holds the write lock.
std::vector<std::pair<int64_t, uint64_t> > messagesByLastUsedTime;
std::vector<std::pair<int64_t, uint64_t>> messagesByLastUsedTime;
messagesByLastUsedTime.reserve(m_messages.size());
for (typename Map<uint64_t, p_E>::const_iterator i(m_messages.begin()); i != m_messages.end(); ++i)
@ -179,7 +174,7 @@ class Defragmenter {
}
// Get or create message fragment.
Defragmenter<MF, MFP, GCS, GCT, P>::p_E* e;
Defragmenter<MF, MFP, GCS, GCT, P>::p_E *e;
{
typename Map<uint64_t, Defragmenter<MF, MFP, GCS, GCT, P>::p_E>::iterator ee(m_messages.find(messageId));
if (ee == m_messages.end()) {
@ -218,8 +213,8 @@ class Defragmenter {
// If there is a path associated with this fragment make sure we've registered
// ourselves as in flight, check the limit, and abort if exceeded.
if ((via) && (! e->via)) {
e->via = via;
if ((via) && (!e->via)) {
e->via = via;
bool tooManyPerPath = false;
via->m_inboundFragmentedMessages_l.lock();
try {
@ -245,7 +240,7 @@ class Defragmenter {
// data would just mean the transfer is corrupt and would be detected
// later e.g. by packet MAC check. Other use cases of this code like
// network configs check each fragment so this basically can't happen.
Buf::Slice& s = e->message.at(fragmentNo);
Buf::Slice &s = e->message.at(fragmentNo);
if (s.b)
return ERR_DUPLICATE_FRAGMENT;
@ -299,15 +294,9 @@ class Defragmenter {
private:
// p_E is an entry in the message queue.
struct p_E {
ZT_INLINE p_E() noexcept
: id(0)
, lastUsed(0)
, totalFragmentsExpected(0)
, fragmentsReceived(0)
{
}
ZT_INLINE p_E() noexcept : id(0), lastUsed(0), totalFragmentsExpected(0), fragmentsReceived(0) {}
ZT_INLINE p_E(const p_E& e) noexcept
ZT_INLINE p_E(const p_E &e) noexcept
: id(e.id)
, lastUsed(e.lastUsed)
, totalFragmentsExpected(e.totalFragmentsExpected)
@ -327,15 +316,15 @@ class Defragmenter {
}
}
ZT_INLINE p_E& operator=(const p_E& e)
ZT_INLINE p_E &operator=(const p_E &e)
{
if (this != &e) {
id = e.id;
lastUsed = e.lastUsed;
id = e.id;
lastUsed = e.lastUsed;
totalFragmentsExpected = e.totalFragmentsExpected;
fragmentsReceived = e.fragmentsReceived;
via = e.via;
message = e.message;
fragmentsReceived = e.fragmentsReceived;
via = e.via;
message = e.message;
}
return *this;
}

View file

@ -15,28 +15,25 @@
namespace ZeroTier {
Vector<uint8_t>& Dictionary::operator[](const char* const k)
{
return m_entries[k];
}
Vector<uint8_t> &Dictionary::operator[](const char *const k) { return m_entries[k]; }
const Vector<uint8_t>& Dictionary::operator[](const char* const k) const
const Vector<uint8_t> &Dictionary::operator[](const char *const k) const
{
static const Vector<uint8_t> s_emptyEntry;
const SortedMap<String, Vector<uint8_t> >::const_iterator e(m_entries.find(k));
const SortedMap<String, Vector<uint8_t>>::const_iterator e(m_entries.find(k));
return (e == m_entries.end()) ? s_emptyEntry : e->second;
}
void Dictionary::add(const char* k, const Address& v)
void Dictionary::add(const char *k, const Address &v)
{
char tmp[ZT_ADDRESS_STRING_SIZE_MAX];
v.toString(tmp);
add(k, tmp);
}
void Dictionary::add(const char* k, const char* v)
void Dictionary::add(const char *k, const char *v)
{
Vector<uint8_t>& e = (*this)[k];
Vector<uint8_t> &e = (*this)[k];
e.clear();
if (v) {
while (*v)
@ -44,18 +41,18 @@ void Dictionary::add(const char* k, const char* v)
}
}
void Dictionary::add(const char* k, const void* data, unsigned int len)
void Dictionary::add(const char *k, const void *data, unsigned int len)
{
Vector<uint8_t>& e = (*this)[k];
Vector<uint8_t> &e = (*this)[k];
if (likely(len != 0)) {
e.assign((const uint8_t*)data, (const uint8_t*)data + len);
e.assign((const uint8_t *)data, (const uint8_t *)data + len);
}
else {
e.clear();
}
}
uint64_t Dictionary::getUI(const char* k, uint64_t dfl) const
uint64_t Dictionary::getUI(const char *k, uint64_t dfl) const
{
char tmp[32];
getS(k, tmp, sizeof(tmp));
@ -64,12 +61,12 @@ uint64_t Dictionary::getUI(const char* k, uint64_t dfl) const
return dfl;
}
char* Dictionary::getS(const char* k, char* v, const unsigned int cap) const
char *Dictionary::getS(const char *k, char *v, const unsigned int cap) const
{
if (cap == 0) // sanity check
return v;
const Vector<uint8_t>& e = (*this)[k];
const Vector<uint8_t> &e = (*this)[k];
if (e.empty()) {
v[0] = 0;
return v;
@ -87,15 +84,12 @@ char* Dictionary::getS(const char* k, char* v, const unsigned int cap) const
return v;
}
void Dictionary::clear()
{
m_entries.clear();
}
void Dictionary::clear() { m_entries.clear(); }
void Dictionary::encode(Vector<uint8_t>& out) const
void Dictionary::encode(Vector<uint8_t> &out) const
{
out.clear();
for (SortedMap<String, Vector<uint8_t> >::const_iterator ti(m_entries.begin()); ti != m_entries.end(); ++ti) {
for (SortedMap<String, Vector<uint8_t>>::const_iterator ti(m_entries.begin()); ti != m_entries.end(); ++ti) {
s_appendKey(out, ti->first.data());
for (Vector<uint8_t>::const_iterator i(ti->second.begin()); i != ti->second.end(); ++i)
s_appendValueByte(out, *i);
@ -103,34 +97,24 @@ void Dictionary::encode(Vector<uint8_t>& out) const
}
}
bool Dictionary::decode(const void* data, unsigned int len)
bool Dictionary::decode(const void *data, unsigned int len)
{
clear();
String k;
Vector<uint8_t>* v = nullptr;
bool escape = false;
Vector<uint8_t> *v = nullptr;
bool escape = false;
for (unsigned int di = 0; di < len; ++di) {
const uint8_t c = reinterpret_cast<const uint8_t*>(data)[di];
const uint8_t c = reinterpret_cast<const uint8_t *>(data)[di];
if (c) {
if (v) {
if (escape) {
escape = false;
switch (c) {
case 48:
v->push_back(0);
break;
case 101:
v->push_back(61);
break;
case 110:
v->push_back(10);
break;
case 114:
v->push_back(13);
break;
default:
v->push_back(c);
break;
case 48: v->push_back(0); break;
case 101: v->push_back(61); break;
case 110: v->push_back(10); break;
case 114: v->push_back(13); break;
default: v->push_back(c); break;
}
}
else {
@ -162,7 +146,7 @@ bool Dictionary::decode(const void* data, unsigned int len)
return true;
}
char* Dictionary::arraySubscript(char* buf, unsigned int bufSize, const char* name, const unsigned long sub) noexcept
char *Dictionary::arraySubscript(char *buf, unsigned int bufSize, const char *name, const unsigned long sub) noexcept
{
if (bufSize < 17) { // sanity check
buf[0] = 0;

View file

@ -39,15 +39,11 @@ class Identity;
*/
class Dictionary {
public:
typedef SortedMap<String, Vector<uint8_t> >::const_iterator const_iterator;
typedef SortedMap<String, Vector<uint8_t>>::const_iterator const_iterator;
ZT_INLINE Dictionary()
{
}
ZT_INLINE Dictionary() {}
ZT_INLINE ~Dictionary()
{
}
ZT_INLINE ~Dictionary() {}
/*
ZT_INLINE void dump() const
@ -82,7 +78,7 @@ class Dictionary {
* @param k Key to look up
* @return Reference to value
*/
Vector<uint8_t>& operator[](const char* k);
Vector<uint8_t> &operator[](const char *k);
/**
* Get a const reference to a value
@ -90,23 +86,17 @@ class Dictionary {
* @param k Key to look up
* @return Reference to value or to empty vector if not found
*/
const Vector<uint8_t>& operator[](const char* k) const;
const Vector<uint8_t> &operator[](const char *k) const;
/**
* @return Start of key->value pairs
*/
ZT_INLINE const_iterator begin() const noexcept
{
return m_entries.begin();
}
ZT_INLINE const_iterator begin() const noexcept { return m_entries.begin(); }
/**
* @return End of key->value pairs
*/
ZT_INLINE const_iterator end() const noexcept
{
return m_entries.end();
}
ZT_INLINE const_iterator end() const noexcept { return m_entries.end(); }
/**
* Add an integer as a hexadecimal string value
@ -114,7 +104,7 @@ class Dictionary {
* @param k Key to set
* @param v Integer to set, will be cast to uint64_t and stored as hex
*/
ZT_INLINE void add(const char* const k, const uint64_t v)
ZT_INLINE void add(const char *const k, const uint64_t v)
{
char buf[24];
add(k, Utils::hex((uint64_t)(v), buf));
@ -126,7 +116,7 @@ class Dictionary {
* @param k Key to set
* @param v Integer to set, will be cast to uint64_t and stored as hex
*/
ZT_INLINE void add(const char* const k, const int64_t v)
ZT_INLINE void add(const char *const k, const int64_t v)
{
char buf[24];
add(k, Utils::hex((uint64_t)(v), buf));
@ -135,17 +125,17 @@ class Dictionary {
/**
* Add an address in 10-digit hex string format
*/
void add(const char* k, const Address& v);
void add(const char *k, const Address &v);
/**
* Add a C string as a value
*/
void add(const char* k, const char* v);
void add(const char *k, const char *v);
/**
* Add a binary blob as a value
*/
void add(const char* k, const void* data, unsigned int len);
void add(const char *k, const void *data, unsigned int len);
/**
* Get an integer
@ -154,7 +144,7 @@ class Dictionary {
* @param dfl Default value (default: 0)
* @return Value of key or default if not found
*/
uint64_t getUI(const char* k, uint64_t dfl = 0) const;
uint64_t getUI(const char *k, uint64_t dfl = 0) const;
/**
* Get a C string
@ -166,7 +156,7 @@ class Dictionary {
* @param v Buffer to hold string
* @param cap Maximum size of string (including terminating null)
*/
char* getS(const char* k, char* v, unsigned int cap) const;
char *getS(const char *k, char *v, unsigned int cap) const;
/**
* Get an object supporting the marshal/unmarshal interface pattern
@ -176,9 +166,9 @@ class Dictionary {
* @param obj Object to unmarshal() into
* @return True if unmarshal was successful
*/
template <typename T> ZT_INLINE bool getO(const char* k, T& obj) const
template <typename T> ZT_INLINE bool getO(const char *k, T &obj) const
{
const Vector<uint8_t>& d = (*this)[k];
const Vector<uint8_t> &d = (*this)[k];
if (d.empty())
return false;
return (obj.unmarshal(d.data(), (unsigned int)d.size()) > 0);
@ -192,9 +182,9 @@ class Dictionary {
* @param obj Object to marshal() into vector
* @return True if successful
*/
template <typename T> ZT_INLINE bool addO(const char* k, T& obj)
template <typename T> ZT_INLINE bool addO(const char *k, T &obj)
{
Vector<uint8_t>& d = (*this)[k];
Vector<uint8_t> &d = (*this)[k];
d.resize(T::marshalSizeMax());
const int l = obj.marshal(d.data());
if (l > 0) {
@ -213,25 +203,19 @@ class Dictionary {
/**
* @return Number of entries
*/
ZT_INLINE unsigned int size() const noexcept
{
return (unsigned int)m_entries.size();
}
ZT_INLINE unsigned int size() const noexcept { return (unsigned int)m_entries.size(); }
/**
* @return True if dictionary is not empty
*/
ZT_INLINE bool empty() const noexcept
{
return m_entries.empty();
}
ZT_INLINE bool empty() const noexcept { return m_entries.empty(); }
/**
* Encode to a string in the supplied vector
*
* @param out String encoded dictionary
*/
void encode(Vector<uint8_t>& out) const;
void encode(Vector<uint8_t> &out) const;
/**
* Decode a string encoded dictionary
@ -243,7 +227,7 @@ class Dictionary {
* @param len Length of data
* @return True if dictionary was formatted correctly and valid, false on error
*/
bool decode(const void* data, unsigned int len);
bool decode(const void *data, unsigned int len);
/**
* Append a key=value pair to a buffer (vector or FCV)
@ -252,7 +236,7 @@ class Dictionary {
* @param k Key (must be <= 8 characters)
* @param v Value
*/
template <typename V> ZT_INLINE static void append(V& out, const char* const k, const bool v)
template <typename V> ZT_INLINE static void append(V &out, const char *const k, const bool v)
{
s_appendKey(out, k);
out.push_back((uint8_t)(v ? '1' : '0'));
@ -266,7 +250,7 @@ class Dictionary {
* @param k Key (must be <= 8 characters)
* @param v Value
*/
template <typename V> ZT_INLINE static void append(V& out, const char* const k, const Address v)
template <typename V> ZT_INLINE static void append(V &out, const char *const k, const Address v)
{
s_appendKey(out, k);
const uint64_t a = v.toInt();
@ -291,7 +275,7 @@ class Dictionary {
* @param k Key (must be <= 8 characters)
* @param v Value
*/
template <typename V> ZT_INLINE static void append(V& out, const char* const k, const uint64_t v)
template <typename V> ZT_INLINE static void append(V &out, const char *const k, const uint64_t v)
{
s_appendKey(out, k);
char buf[17];
@ -302,37 +286,37 @@ class Dictionary {
out.push_back((uint8_t)'\n');
}
template <typename V> ZT_INLINE static void append(V& out, const char* const k, const int64_t v)
template <typename V> ZT_INLINE static void append(V &out, const char *const k, const int64_t v)
{
append(out, k, (uint64_t)v);
}
template <typename V> ZT_INLINE static void append(V& out, const char* const k, const uint32_t v)
template <typename V> ZT_INLINE static void append(V &out, const char *const k, const uint32_t v)
{
append(out, k, (uint64_t)v);
}
template <typename V> ZT_INLINE static void append(V& out, const char* const k, const int32_t v)
template <typename V> ZT_INLINE static void append(V &out, const char *const k, const int32_t v)
{
append(out, k, (uint64_t)v);
}
template <typename V> ZT_INLINE static void append(V& out, const char* const k, const uint16_t v)
template <typename V> ZT_INLINE static void append(V &out, const char *const k, const uint16_t v)
{
append(out, k, (uint64_t)v);
}
template <typename V> ZT_INLINE static void append(V& out, const char* const k, const int16_t v)
template <typename V> ZT_INLINE static void append(V &out, const char *const k, const int16_t v)
{
append(out, k, (uint64_t)v);
}
template <typename V> ZT_INLINE static void append(V& out, const char* const k, const uint8_t v)
template <typename V> ZT_INLINE static void append(V &out, const char *const k, const uint8_t v)
{
append(out, k, (uint64_t)v);
}
template <typename V> ZT_INLINE static void append(V& out, const char* const k, const int8_t v)
template <typename V> ZT_INLINE static void append(V &out, const char *const k, const int8_t v)
{
append(out, k, (uint64_t)v);
}
@ -344,7 +328,7 @@ class Dictionary {
* @param k Key (must be <= 8 characters)
* @param v Value
*/
template <typename V> ZT_INLINE static void append(V& out, const char* const k, const char* v)
template <typename V> ZT_INLINE static void append(V &out, const char *const k, const char *v)
{
if ((v) && (*v)) {
s_appendKey(out, k);
@ -362,11 +346,12 @@ class Dictionary {
* @param v Value
* @param vlen Value length in bytes
*/
template <typename V> ZT_INLINE static void append(V& out, const char* const k, const void* const v, const unsigned int vlen)
template <typename V>
ZT_INLINE static void append(V &out, const char *const k, const void *const v, const unsigned int vlen)
{
s_appendKey(out, k);
for (unsigned int i = 0; i < vlen; ++i)
s_appendValueByte(out, reinterpret_cast<const uint8_t*>(v)[i]);
s_appendValueByte(out, reinterpret_cast<const uint8_t *>(v)[i]);
out.push_back((uint8_t)'\n');
}
@ -377,7 +362,7 @@ class Dictionary {
* @param k Key (must be <= 8 characters)
* @param pid Packet ID
*/
template <typename V> static ZT_INLINE void appendPacketId(V& out, const char* const k, const uint64_t pid)
template <typename V> static ZT_INLINE void appendPacketId(V &out, const char *const k, const uint64_t pid)
{
append(out, k, &pid, 8);
}
@ -390,7 +375,7 @@ class Dictionary {
* @param v Marshal-able object
* @return Bytes appended or negative on error (return value of marshal())
*/
template <typename V, typename T> static ZT_INLINE int appendObject(V& out, const char* const k, const T& v)
template <typename V, typename T> static ZT_INLINE int appendObject(V &out, const char *const k, const T &v)
{
uint8_t tmp[2048]; // large enough for any current object
if (T::marshalSizeMax() > sizeof(tmp))
@ -409,10 +394,10 @@ class Dictionary {
* @param sub Subscript index
* @return Pointer to 'buf'
*/
static char* arraySubscript(char* buf, unsigned int bufSize, const char* name, const unsigned long sub) noexcept;
static char *arraySubscript(char *buf, unsigned int bufSize, const char *name, const unsigned long sub) noexcept;
private:
template <typename V> ZT_INLINE static void s_appendValueByte(V& out, const uint8_t c)
template <typename V> ZT_INLINE static void s_appendValueByte(V &out, const uint8_t c)
{
switch (c) {
case 0:
@ -435,13 +420,11 @@ class Dictionary {
out.push_back(92);
out.push_back(92);
break;
default:
out.push_back(c);
break;
default: out.push_back(c); break;
}
}
template <typename V> ZT_INLINE static void s_appendKey(V& out, const char* k)
template <typename V> ZT_INLINE static void s_appendKey(V &out, const char *k)
{
for (;;) {
const char c = *(k++);
@ -455,7 +438,7 @@ class Dictionary {
// Dictionary maps need to be sorted so that they always encode in the same order
// to yield blobs that can be hashed and signed reproducibly. Other than for areas
// where dictionaries are signed and verified the order doesn't matter.
SortedMap<String, Vector<uint8_t> > m_entries;
SortedMap<String, Vector<uint8_t>> m_entries;
};
} // namespace ZeroTier

View file

@ -77,7 +77,9 @@ void ECC384GenerateKey(uint8_t pub[ZT_ECC384_PUBLIC_KEY_SIZE], uint8_t priv[ZT_E
* @param hash 48-byte hash
* @param sig Buffer to receive signature
*/
void ECC384ECDSASign(const uint8_t priv[ZT_ECC384_PRIVATE_KEY_SIZE], const uint8_t hash[ZT_ECC384_SIGNATURE_HASH_SIZE], uint8_t sig[ZT_ECC384_SIGNATURE_SIZE]);
void ECC384ECDSASign(
const uint8_t priv[ZT_ECC384_PRIVATE_KEY_SIZE], const uint8_t hash[ZT_ECC384_SIGNATURE_HASH_SIZE],
uint8_t sig[ZT_ECC384_SIGNATURE_SIZE]);
/**
* Verify a signature
@ -87,7 +89,9 @@ void ECC384ECDSASign(const uint8_t priv[ZT_ECC384_PRIVATE_KEY_SIZE], const uint8
* @param sig Signature to check
* @return True if signature is valid
*/
bool ECC384ECDSAVerify(const uint8_t pub[ZT_ECC384_PUBLIC_KEY_SIZE], const uint8_t hash[ZT_ECC384_SIGNATURE_HASH_SIZE], const uint8_t sig[ZT_ECC384_SIGNATURE_SIZE]);
bool ECC384ECDSAVerify(
const uint8_t pub[ZT_ECC384_PUBLIC_KEY_SIZE], const uint8_t hash[ZT_ECC384_SIGNATURE_HASH_SIZE],
const uint8_t sig[ZT_ECC384_SIGNATURE_SIZE]);
/**
* Perform ECDH key agreement
@ -99,7 +103,9 @@ bool ECC384ECDSAVerify(const uint8_t pub[ZT_ECC384_PUBLIC_KEY_SIZE], const uint8
* @param ourPriv Local private key
* @param secret Buffer to receive 48-byte secret
*/
bool ECC384ECDH(const uint8_t theirPub[ZT_ECC384_PUBLIC_KEY_SIZE], const uint8_t ourPriv[ZT_ECC384_PRIVATE_KEY_SIZE], uint8_t secret[ZT_ECC384_SHARED_SECRET_SIZE]);
bool ECC384ECDH(
const uint8_t theirPub[ZT_ECC384_PUBLIC_KEY_SIZE], const uint8_t ourPriv[ZT_ECC384_PRIVATE_KEY_SIZE],
uint8_t secret[ZT_ECC384_SHARED_SECRET_SIZE]);
} // namespace ZeroTier

View file

@ -20,52 +20,34 @@ namespace ZeroTier {
static ZT_INLINE char s_endpointTypeChar(const ZT_EndpointType t)
{
switch (t) {
default:
return '0';
case ZT_ENDPOINT_TYPE_ZEROTIER:
return 'z';
case ZT_ENDPOINT_TYPE_ETHERNET:
return 'e';
case ZT_ENDPOINT_TYPE_WIFI_DIRECT:
return 'd';
case ZT_ENDPOINT_TYPE_BLUETOOTH:
return 'b';
case ZT_ENDPOINT_TYPE_IP:
return 'i';
case ZT_ENDPOINT_TYPE_IP_UDP:
return 'u';
case ZT_ENDPOINT_TYPE_IP_TCP:
return 't';
case ZT_ENDPOINT_TYPE_IP_TCP_WS:
return 'w';
default: return '0';
case ZT_ENDPOINT_TYPE_ZEROTIER: return 'z';
case ZT_ENDPOINT_TYPE_ETHERNET: return 'e';
case ZT_ENDPOINT_TYPE_WIFI_DIRECT: return 'd';
case ZT_ENDPOINT_TYPE_BLUETOOTH: return 'b';
case ZT_ENDPOINT_TYPE_IP: return 'i';
case ZT_ENDPOINT_TYPE_IP_UDP: return 'u';
case ZT_ENDPOINT_TYPE_IP_TCP: return 't';
case ZT_ENDPOINT_TYPE_IP_TCP_WS: return 'w';
}
}
static ZT_INLINE ZT_EndpointType s_charEndpointType(const char c)
{
switch (c) {
default:
return ZT_ENDPOINT_TYPE_NIL;
case 'z':
return ZT_ENDPOINT_TYPE_ZEROTIER;
case 'e':
return ZT_ENDPOINT_TYPE_ETHERNET;
case 'd':
return ZT_ENDPOINT_TYPE_WIFI_DIRECT;
case 'b':
return ZT_ENDPOINT_TYPE_BLUETOOTH;
case 'i':
return ZT_ENDPOINT_TYPE_IP;
case 'u':
return ZT_ENDPOINT_TYPE_IP_UDP;
case 't':
return ZT_ENDPOINT_TYPE_IP_TCP;
case 'w':
return ZT_ENDPOINT_TYPE_IP_TCP_WS;
default: return ZT_ENDPOINT_TYPE_NIL;
case 'z': return ZT_ENDPOINT_TYPE_ZEROTIER;
case 'e': return ZT_ENDPOINT_TYPE_ETHERNET;
case 'd': return ZT_ENDPOINT_TYPE_WIFI_DIRECT;
case 'b': return ZT_ENDPOINT_TYPE_BLUETOOTH;
case 'i': return ZT_ENDPOINT_TYPE_IP;
case 'u': return ZT_ENDPOINT_TYPE_IP_UDP;
case 't': return ZT_ENDPOINT_TYPE_IP_TCP;
case 'w': return ZT_ENDPOINT_TYPE_IP_TCP_WS;
}
}
char* Endpoint::toString(char s[ZT_ENDPOINT_STRING_SIZE_MAX]) const noexcept
char *Endpoint::toString(char s[ZT_ENDPOINT_STRING_SIZE_MAX]) const noexcept
{
static_assert(ZT_ENDPOINT_STRING_SIZE_MAX > (ZT_INETADDRESS_STRING_SIZE_MAX + 4), "overflow");
static_assert(ZT_ENDPOINT_STRING_SIZE_MAX > (ZT_FINGERPRINT_STRING_SIZE_MAX + 4), "overflow");
@ -97,10 +79,10 @@ char* Endpoint::toString(char s[ZT_ENDPOINT_STRING_SIZE_MAX]) const noexcept
return s;
}
bool Endpoint::fromString(const char* s) noexcept
bool Endpoint::fromString(const char *s) noexcept
{
memoryZero(this);
if ((! s) || (! *s)) {
if ((!s) || (!*s)) {
// Empty strings are considered NIL endpoints.
return true;
}
@ -108,16 +90,15 @@ bool Endpoint::fromString(const char* s) noexcept
// type/ADDRESS is a fully qualified endpoint.
this->type = s_charEndpointType(s[0]);
switch (this->type) {
case ZT_ENDPOINT_TYPE_NIL:
break;
case ZT_ENDPOINT_TYPE_NIL: break;
case ZT_ENDPOINT_TYPE_ZEROTIER:
if (! s[2])
if (!s[2])
return false;
break;
case ZT_ENDPOINT_TYPE_ETHERNET:
case ZT_ENDPOINT_TYPE_WIFI_DIRECT:
case ZT_ENDPOINT_TYPE_BLUETOOTH: {
if (! s[2])
if (!s[2])
return false;
MAC tmpmac;
tmpmac.fromString(s + 2);
@ -127,9 +108,9 @@ bool Endpoint::fromString(const char* s) noexcept
case ZT_ENDPOINT_TYPE_IP_UDP:
case ZT_ENDPOINT_TYPE_IP_TCP:
case ZT_ENDPOINT_TYPE_IP_TCP_WS: {
if (! s[2])
if (!s[2])
return false;
if (! asInetAddress(this->value.ss).fromString(s + 2))
if (!asInetAddress(this->value.ss).fromString(s + 2))
return false;
} break;
}
@ -176,7 +157,7 @@ int Endpoint::marshal(uint8_t data[ZT_ENDPOINT_MARSHAL_SIZE_MAX]) const noexcept
}
}
int Endpoint::unmarshal(const uint8_t* restrict data, int len) noexcept
int Endpoint::unmarshal(const uint8_t *restrict data, int len) noexcept
{
memoryZero(this);
if (unlikely(len <= 0))
@ -189,19 +170,15 @@ int Endpoint::unmarshal(const uint8_t* restrict data, int len) noexcept
if (data[0] < 16) {
switch (data[0]) {
case 0:
return 1;
case 0: return 1;
case 4:
case 6:
this->type = ZT_ENDPOINT_TYPE_IP_UDP;
return asInetAddress(this->value.ss).unmarshal(data, len);
case 6: this->type = ZT_ENDPOINT_TYPE_IP_UDP; return asInetAddress(this->value.ss).unmarshal(data, len);
}
return -1;
}
switch ((this->type = (ZT_EndpointType)(data[0] - 16))) {
case ZT_ENDPOINT_TYPE_NIL:
return 1;
case ZT_ENDPOINT_TYPE_NIL: return 1;
case ZT_ENDPOINT_TYPE_ZEROTIER:
if (len >= (1 + ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE)) {
@ -225,11 +202,9 @@ int Endpoint::unmarshal(const uint8_t* restrict data, int len) noexcept
case ZT_ENDPOINT_TYPE_IP:
case ZT_ENDPOINT_TYPE_IP_UDP:
case ZT_ENDPOINT_TYPE_IP_TCP:
case ZT_ENDPOINT_TYPE_IP_TCP_WS:
return asInetAddress(this->value.ss).unmarshal(data + 1, len - 1);
case ZT_ENDPOINT_TYPE_IP_TCP_WS: return asInetAddress(this->value.ss).unmarshal(data + 1, len - 1);
default:
break;
default: break;
}
// Unrecognized types can still be passed over in a valid stream if they are
@ -242,45 +217,37 @@ int Endpoint::unmarshal(const uint8_t* restrict data, int len) noexcept
return (unrecLen > len) ? -1 : unrecLen;
}
bool Endpoint::operator==(const Endpoint& ep) const noexcept
bool Endpoint::operator==(const Endpoint &ep) const noexcept
{
if (this->type == ep.type) {
switch (this->type) {
case ZT_ENDPOINT_TYPE_ZEROTIER:
return zt() == ep.zt();
case ZT_ENDPOINT_TYPE_ZEROTIER: return zt() == ep.zt();
case ZT_ENDPOINT_TYPE_ETHERNET:
case ZT_ENDPOINT_TYPE_WIFI_DIRECT:
case ZT_ENDPOINT_TYPE_BLUETOOTH:
return this->value.mac == ep.value.mac;
case ZT_ENDPOINT_TYPE_BLUETOOTH: return this->value.mac == ep.value.mac;
case ZT_ENDPOINT_TYPE_IP:
case ZT_ENDPOINT_TYPE_IP_UDP:
case ZT_ENDPOINT_TYPE_IP_TCP:
case ZT_ENDPOINT_TYPE_IP_TCP_WS:
return ip() == ep.ip();
default:
return true;
case ZT_ENDPOINT_TYPE_IP_TCP_WS: return ip() == ep.ip();
default: return true;
}
}
return false;
}
bool Endpoint::operator<(const Endpoint& ep) const noexcept
bool Endpoint::operator<(const Endpoint &ep) const noexcept
{
if (this->type == ep.type) {
switch (this->type) {
case ZT_ENDPOINT_TYPE_ZEROTIER:
return zt() < ep.zt();
case ZT_ENDPOINT_TYPE_ZEROTIER: return zt() < ep.zt();
case ZT_ENDPOINT_TYPE_ETHERNET:
case ZT_ENDPOINT_TYPE_WIFI_DIRECT:
case ZT_ENDPOINT_TYPE_BLUETOOTH:
return this->value.mac < ep.value.mac;
case ZT_ENDPOINT_TYPE_BLUETOOTH: return this->value.mac < ep.value.mac;
case ZT_ENDPOINT_TYPE_IP:
case ZT_ENDPOINT_TYPE_IP_UDP:
case ZT_ENDPOINT_TYPE_IP_TCP:
case ZT_ENDPOINT_TYPE_IP_TCP_WS:
return ip() < ep.ip();
default:
return true;
case ZT_ENDPOINT_TYPE_IP_TCP_WS: return ip() < ep.ip();
default: return true;
}
}
return (int)this->type < (int)ep.type;

View file

@ -27,11 +27,16 @@
namespace ZeroTier {
static_assert((ZT_ENDPOINT_MARSHAL_SIZE_MAX - 1) > ZT_INETADDRESS_MARSHAL_SIZE_MAX, "ZT_ENDPOINT_MARSHAL_SIZE_MAX not large enough");
static_assert((ZT_ENDPOINT_MARSHAL_SIZE_MAX - 1) > sizeof(ZT_Fingerprint), "ZT_ENDPOINT_MARSHAL_SIZE_MAX not large enough");
static_assert((ZT_ENDPOINT_MARSHAL_SIZE_MAX - 1) > sizeof(InetAddress), "ZT_ENDPOINT_MARSHAL_SIZE_MAX not large enough");
static_assert(
(ZT_ENDPOINT_MARSHAL_SIZE_MAX - 1) > ZT_INETADDRESS_MARSHAL_SIZE_MAX,
"ZT_ENDPOINT_MARSHAL_SIZE_MAX not large enough");
static_assert(
(ZT_ENDPOINT_MARSHAL_SIZE_MAX - 1) > sizeof(ZT_Fingerprint), "ZT_ENDPOINT_MARSHAL_SIZE_MAX not large enough");
static_assert(
(ZT_ENDPOINT_MARSHAL_SIZE_MAX - 1) > sizeof(InetAddress), "ZT_ENDPOINT_MARSHAL_SIZE_MAX not large enough");
static_assert((ZT_ENDPOINT_MARSHAL_SIZE_MAX - 1) > sizeof(MAC), "ZT_ENDPOINT_MARSHAL_SIZE_MAX not large enough");
static_assert((ZT_ENDPOINT_MARSHAL_SIZE_MAX - 1) > sizeof(Fingerprint), "ZT_ENDPOINT_MARSHAL_SIZE_MAX not large enough");
static_assert(
(ZT_ENDPOINT_MARSHAL_SIZE_MAX - 1) > sizeof(Fingerprint), "ZT_ENDPOINT_MARSHAL_SIZE_MAX not large enough");
/**
* Endpoint variant specifying some form of network endpoint.
@ -49,15 +54,9 @@ class Endpoint
/**
* Create a NIL/empty endpoint
*/
ZT_INLINE Endpoint() noexcept
{
memoryZero(this);
}
ZT_INLINE Endpoint() noexcept { memoryZero(this); }
ZT_INLINE Endpoint(const ZT_Endpoint& ep) noexcept
{
Utils::copy<sizeof(ZT_Endpoint)>((ZT_Endpoint*)this, &ep);
}
ZT_INLINE Endpoint(const ZT_Endpoint &ep) noexcept { Utils::copy<sizeof(ZT_Endpoint)>((ZT_Endpoint *)this, &ep); }
/**
* Create an endpoint for a type that uses an IP
@ -65,7 +64,7 @@ class Endpoint
* @param a IP/port
* @param et Endpoint type (default: IP_UDP)
*/
ZT_INLINE Endpoint(const InetAddress& inaddr, const ZT_EndpointType et = ZT_ENDPOINT_TYPE_IP_UDP) noexcept
ZT_INLINE Endpoint(const InetAddress &inaddr, const ZT_EndpointType et = ZT_ENDPOINT_TYPE_IP_UDP) noexcept
{
if (inaddr) {
this->type = et;
@ -81,10 +80,10 @@ class Endpoint
*
* @param zt_ ZeroTier identity fingerprint
*/
ZT_INLINE Endpoint(const Fingerprint& zt_) noexcept
ZT_INLINE Endpoint(const Fingerprint &zt_) noexcept
{
if (zt_) {
this->type = ZT_ENDPOINT_TYPE_ZEROTIER;
this->type = ZT_ENDPOINT_TYPE_ZEROTIER;
this->value.fp = zt_;
}
else {
@ -98,10 +97,10 @@ class Endpoint
* @param eth_ Ethernet address
* @param et Endpoint type (default: ETHERNET)
*/
ZT_INLINE Endpoint(const MAC& eth_, const ZT_EndpointType et = ZT_ENDPOINT_TYPE_ETHERNET) noexcept
ZT_INLINE Endpoint(const MAC &eth_, const ZT_EndpointType et = ZT_ENDPOINT_TYPE_ETHERNET) noexcept
{
if (eth_) {
this->type = et;
this->type = et;
this->value.mac = eth_.toInt();
}
else {
@ -112,10 +111,7 @@ class Endpoint
/**
* @return True if endpoint type isn't NIL
*/
ZT_INLINE operator bool() const noexcept
{
return this->type != ZT_ENDPOINT_TYPE_NIL;
}
ZT_INLINE operator bool() const noexcept { return this->type != ZT_ENDPOINT_TYPE_NIL; }
/**
* @return True if this endpoint type has an InetAddress address type and thus ip() is valid
@ -126,10 +122,8 @@ class Endpoint
case ZT_ENDPOINT_TYPE_IP:
case ZT_ENDPOINT_TYPE_IP_UDP:
case ZT_ENDPOINT_TYPE_IP_TCP:
case ZT_ENDPOINT_TYPE_IP_TCP_WS:
return true;
default:
return false;
case ZT_ENDPOINT_TYPE_IP_TCP_WS: return true;
default: return false;
}
}
@ -142,7 +136,7 @@ class Endpoint
* @param ep Endpoint to check
* @return True if endpoints seem to refer to the same address/host
*/
ZT_INLINE bool isSameAddress(const Endpoint& ep) const noexcept
ZT_INLINE bool isSameAddress(const Endpoint &ep) const noexcept
{
switch (this->type) {
case ZT_ENDPOINT_TYPE_IP:
@ -153,14 +147,11 @@ class Endpoint
case ZT_ENDPOINT_TYPE_IP:
case ZT_ENDPOINT_TYPE_IP_UDP:
case ZT_ENDPOINT_TYPE_IP_TCP:
case ZT_ENDPOINT_TYPE_IP_TCP_WS:
return ip().ipsEqual(ep.ip());
default:
break;
case ZT_ENDPOINT_TYPE_IP_TCP_WS: return ip().ipsEqual(ep.ip());
default: break;
}
break;
default:
break;
default: break;
}
return (*this) == ep;
}
@ -170,51 +161,38 @@ class Endpoint
*
* @return InetAddress instance
*/
ZT_INLINE const InetAddress& ip() const noexcept
{
return asInetAddress(this->value.ss);
}
ZT_INLINE const InetAddress &ip() const noexcept { return asInetAddress(this->value.ss); }
/**
* Get MAC if this is an Ethernet, WiFi direct, or Bluetooth type (undefined otherwise)
*
* @return Ethernet MAC
*/
ZT_INLINE MAC eth() const noexcept
{
return MAC(this->value.mac);
}
ZT_INLINE MAC eth() const noexcept { return MAC(this->value.mac); }
/**
* Get fingerprint if this is a ZeroTier endpoint type (undefined otherwise)
*
* @return ZeroTier fingerprint
*/
ZT_INLINE Fingerprint zt() const noexcept
{
return Fingerprint(this->value.fp);
}
ZT_INLINE Fingerprint zt() const noexcept { return Fingerprint(this->value.fp); }
ZT_INLINE unsigned long hashCode() const noexcept
{
switch (this->type) {
default:
return 1;
case ZT_ENDPOINT_TYPE_ZEROTIER:
return (unsigned long)this->value.fp.address;
default: return 1;
case ZT_ENDPOINT_TYPE_ZEROTIER: return (unsigned long)this->value.fp.address;
case ZT_ENDPOINT_TYPE_ETHERNET:
case ZT_ENDPOINT_TYPE_WIFI_DIRECT:
case ZT_ENDPOINT_TYPE_BLUETOOTH:
return (unsigned long)Utils::hash64(this->value.mac);
case ZT_ENDPOINT_TYPE_BLUETOOTH: return (unsigned long)Utils::hash64(this->value.mac);
case ZT_ENDPOINT_TYPE_IP:
case ZT_ENDPOINT_TYPE_IP_UDP:
case ZT_ENDPOINT_TYPE_IP_TCP:
case ZT_ENDPOINT_TYPE_IP_TCP_WS:
return ip().hashCode();
case ZT_ENDPOINT_TYPE_IP_TCP_WS: return ip().hashCode();
}
}
char* toString(char s[ZT_ENDPOINT_STRING_SIZE_MAX]) const noexcept;
char *toString(char s[ZT_ENDPOINT_STRING_SIZE_MAX]) const noexcept;
ZT_INLINE String toString() const
{
@ -222,40 +200,25 @@ class Endpoint
return String(toString(tmp));
}
bool fromString(const char* s) noexcept;
bool fromString(const char *s) noexcept;
static constexpr int marshalSizeMax() noexcept
{
return ZT_ENDPOINT_MARSHAL_SIZE_MAX;
}
static constexpr int marshalSizeMax() noexcept { return ZT_ENDPOINT_MARSHAL_SIZE_MAX; }
int marshal(uint8_t data[ZT_ENDPOINT_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;
bool operator==(const Endpoint& ep) const noexcept;
bool operator==(const Endpoint &ep) const noexcept;
ZT_INLINE bool operator!=(const Endpoint& ep) const noexcept
{
return ! ((*this) == ep);
}
ZT_INLINE bool operator!=(const Endpoint &ep) const noexcept { return !((*this) == ep); }
bool operator<(const Endpoint& ep) const noexcept;
bool operator<(const Endpoint &ep) const noexcept;
ZT_INLINE bool operator>(const Endpoint& ep) const noexcept
{
return (ep < *this);
}
ZT_INLINE bool operator>(const Endpoint &ep) const noexcept { return (ep < *this); }
ZT_INLINE bool operator<=(const Endpoint& ep) const noexcept
{
return ! (ep < *this);
}
ZT_INLINE bool operator<=(const Endpoint &ep) const noexcept { return !(ep < *this); }
ZT_INLINE bool operator>=(const Endpoint& ep) const noexcept
{
return ! (*this < ep);
}
ZT_INLINE bool operator>=(const Endpoint &ep) const noexcept { return !(*this < ep); }
};
static_assert(sizeof(Endpoint) == sizeof(ZT_Endpoint), "size mismatch");

View file

@ -38,9 +38,7 @@ namespace ZeroTier {
*/
class Expect {
public:
ZT_INLINE Expect() : m_packetIdSent()
{
}
ZT_INLINE Expect() : m_packetIdSent() {}
/**
* Called by other code when something is sending a packet that could potentially receive an OK response
@ -50,7 +48,8 @@ class Expect {
*/
ZT_INLINE void sending(const uint64_t packetId, const int64_t now) noexcept
{
m_packetIdSent[Utils::hash64(packetId ^ Utils::s_mapNonce) % ZT_EXPECT_BUCKETS] = (uint32_t)(now / ZT_EXPECT_TTL);
m_packetIdSent[Utils::hash64(packetId ^ Utils::s_mapNonce) % ZT_EXPECT_BUCKETS] =
(uint32_t)(now / ZT_EXPECT_TTL);
}
/**
@ -66,7 +65,12 @@ class Expect {
*/
ZT_INLINE bool expecting(const uint64_t inRePacketId, const int64_t now) noexcept
{
return (((now / ZT_EXPECT_TTL) - (int64_t)m_packetIdSent[(unsigned long)Utils::hash64(inRePacketId ^ Utils::s_mapNonce) % ZT_EXPECT_BUCKETS].exchange(0)) <= 1);
return (
((now / ZT_EXPECT_TTL)
- (int64_t)
m_packetIdSent[(unsigned long)Utils::hash64(inRePacketId ^ Utils::s_mapNonce) % ZT_EXPECT_BUCKETS]
.exchange(0))
<= 1);
}
private:

View file

@ -35,23 +35,18 @@ namespace ZeroTier {
*/
template <typename T, unsigned int C> class FCV {
public:
typedef T* iterator;
typedef const T* const_iterator;
typedef T *iterator;
typedef const T *const_iterator;
ZT_INLINE FCV() noexcept : _s(0)
{
}
ZT_INLINE FCV() noexcept : _s(0) {}
ZT_INLINE FCV(const FCV& v) : _s(0)
{
*this = v;
}
ZT_INLINE FCV(const FCV &v) : _s(0) { *this = v; }
ZT_INLINE FCV(const T* const contents, const unsigned int len) : _s(len)
ZT_INLINE FCV(const T *const contents, const unsigned int len) : _s(len)
{
const unsigned int l = std::min(len, C);
for (unsigned int i = 0; i < l; ++i)
new (reinterpret_cast<T*>(_m) + i) T(contents[i]);
new (reinterpret_cast<T *>(_m) + i) T(contents[i]);
}
template <typename I> ZT_INLINE FCV(I i, I end) : _s(0)
@ -62,19 +57,16 @@ template <typename T, unsigned int C> class FCV {
}
}
ZT_INLINE ~FCV()
{
this->clear();
}
ZT_INLINE ~FCV() { this->clear(); }
ZT_INLINE FCV& operator=(const FCV& v)
ZT_INLINE FCV &operator=(const FCV &v)
{
if (likely(&v != this)) {
this->clear();
const unsigned int s = v._s;
_s = s;
_s = s;
for (unsigned int i = 0; i < s; ++i)
new (reinterpret_cast<T*>(_m) + i) T(*(reinterpret_cast<const T*>(v._m) + i));
new (reinterpret_cast<T *>(_m) + i) T(*(reinterpret_cast<const T *>(v._m) + i));
}
return *this;
}
@ -85,9 +77,9 @@ template <typename T, unsigned int C> class FCV {
ZT_INLINE void clear()
{
const unsigned int s = _s;
_s = 0;
_s = 0;
for (unsigned int i = 0; i < s; ++i)
(reinterpret_cast<T*>(_m) + i)->~T();
(reinterpret_cast<T *>(_m) + i)->~T();
}
/**
@ -95,70 +87,43 @@ template <typename T, unsigned int C> class FCV {
*
* @param v Target vector
*/
ZT_INLINE void unsafeMoveTo(FCV& v) noexcept
ZT_INLINE void unsafeMoveTo(FCV &v) noexcept
{
Utils::copy(v._m, _m, (v._s = _s) * sizeof(T));
_s = 0;
}
ZT_INLINE iterator begin() noexcept
{
return reinterpret_cast<T*>(_m);
}
ZT_INLINE iterator begin() noexcept { return reinterpret_cast<T *>(_m); }
ZT_INLINE iterator end() noexcept
{
return reinterpret_cast<T*>(_m) + _s;
}
ZT_INLINE iterator end() noexcept { return reinterpret_cast<T *>(_m) + _s; }
ZT_INLINE const_iterator begin() const noexcept
{
return reinterpret_cast<const T*>(_m);
}
ZT_INLINE const_iterator begin() const noexcept { return reinterpret_cast<const T *>(_m); }
ZT_INLINE const_iterator end() const noexcept
{
return reinterpret_cast<const T*>(_m) + _s;
}
ZT_INLINE const_iterator end() const noexcept { return reinterpret_cast<const T *>(_m) + _s; }
ZT_INLINE T& operator[](const unsigned int i)
ZT_INLINE T &operator[](const unsigned int i)
{
if (likely(i < _s))
return reinterpret_cast<T*>(_m)[i];
return reinterpret_cast<T *>(_m)[i];
throw Utils::OutOfRangeException;
}
ZT_INLINE const T& operator[](const unsigned int i) const
ZT_INLINE const T &operator[](const unsigned int i) const
{
if (likely(i < _s))
return reinterpret_cast<const T*>(_m)[i];
return reinterpret_cast<const T *>(_m)[i];
throw Utils::OutOfRangeException;
}
static constexpr unsigned int capacity() noexcept
{
return C;
}
static constexpr unsigned int capacity() noexcept { return C; }
ZT_INLINE unsigned int size() const noexcept
{
return _s;
}
ZT_INLINE unsigned int size() const noexcept { return _s; }
ZT_INLINE bool empty() const noexcept
{
return (_s == 0);
}
ZT_INLINE bool empty() const noexcept { return (_s == 0); }
ZT_INLINE T* data() noexcept
{
return reinterpret_cast<T*>(_m);
}
ZT_INLINE T *data() noexcept { return reinterpret_cast<T *>(_m); }
ZT_INLINE const T* data() const noexcept
{
return reinterpret_cast<const T*>(_m);
}
ZT_INLINE const T *data() const noexcept { return reinterpret_cast<const T *>(_m); }
/**
* Push a value onto the back of this vector
@ -167,10 +132,10 @@ template <typename T, unsigned int C> class FCV {
*
* @param v Value to push
*/
ZT_INLINE void push_back(const T& v)
ZT_INLINE void push_back(const T &v)
{
if (likely(_s < C))
new (reinterpret_cast<T*>(_m) + _s++) T(v);
new (reinterpret_cast<T *>(_m) + _s++) T(v);
else
throw Utils::OutOfRangeException;
}
@ -180,13 +145,13 @@ template <typename T, unsigned int C> class FCV {
*
* @return Reference to new item
*/
ZT_INLINE T& push()
ZT_INLINE T &push()
{
if (likely(_s < C)) {
return *(new (reinterpret_cast<T*>(_m) + _s++) T());
return *(new (reinterpret_cast<T *>(_m) + _s++) T());
}
else {
return *(reinterpret_cast<T*>(_m) + (C - 1));
return *(reinterpret_cast<T *>(_m) + (C - 1));
}
}
@ -195,14 +160,14 @@ template <typename T, unsigned int C> class FCV {
*
* @return Reference to new item
*/
ZT_INLINE T& push(const T& v)
ZT_INLINE T &push(const T &v)
{
if (likely(_s < C)) {
return *(new (reinterpret_cast<T*>(_m) + _s++) T(v));
return *(new (reinterpret_cast<T *>(_m) + _s++) T(v));
}
else {
T& tmp = *(reinterpret_cast<T*>(_m) + (C - 1));
tmp = v;
T &tmp = *(reinterpret_cast<T *>(_m) + (C - 1));
tmp = v;
return tmp;
}
}
@ -213,7 +178,7 @@ template <typename T, unsigned int C> class FCV {
ZT_INLINE void pop_back()
{
if (likely(_s != 0))
(reinterpret_cast<T*>(_m) + --_s)->~T();
(reinterpret_cast<T *>(_m) + --_s)->~T();
}
/**
@ -227,9 +192,9 @@ template <typename T, unsigned int C> class FCV {
throw Utils::OutOfRangeException;
unsigned int s = _s;
while (s < ns)
new (reinterpret_cast<T*>(_m) + s++) T();
new (reinterpret_cast<T *>(_m) + s++) T();
while (s > ns)
(reinterpret_cast<T*>(_m) + --s)->~T();
(reinterpret_cast<T *>(_m) + --s)->~T();
_s = s;
}
@ -238,10 +203,7 @@ template <typename T, unsigned int C> class FCV {
*
* @param ns New size
*/
ZT_INLINE void unsafeSetSize(unsigned int ns)
{
_s = ns;
}
ZT_INLINE void unsafeSetSize(unsigned int ns) { _s = ns; }
/**
* This is a bounds checked auto-resizing variant of the [] operator
@ -252,16 +214,16 @@ template <typename T, unsigned int C> class FCV {
* @param i Index to obtain as a reference, resizing if needed
* @return Reference to value at this index
*/
ZT_INLINE T& at(unsigned int i)
ZT_INLINE T &at(unsigned int i)
{
if (i >= _s) {
if (unlikely(i >= C))
i = C - 1;
do {
new (reinterpret_cast<T*>(_m) + _s++) T();
new (reinterpret_cast<T *>(_m) + _s++) T();
} while (i >= _s);
}
return *(reinterpret_cast<T*>(_m) + i);
return *(reinterpret_cast<T *>(_m) + i);
}
/**
@ -273,24 +235,24 @@ template <typename T, unsigned int C> class FCV {
* @param start Starting iterator
* @param end Ending iterator (must be greater than start)
*/
template <typename X> ZT_INLINE void assign(X start, const X& end)
template <typename X> ZT_INLINE void assign(X start, const X &end)
{
const int l = std::min((int)std::distance(start, end), (int)C);
if (l > 0) {
this->resize((unsigned int)l);
for (int i = 0; i < l; ++i)
reinterpret_cast<T*>(_m)[i] = *(start++);
reinterpret_cast<T *>(_m)[i] = *(start++);
}
else {
this->clear();
}
}
ZT_INLINE bool operator==(const FCV& v) const noexcept
ZT_INLINE bool operator==(const FCV &v) const noexcept
{
if (_s == v._s) {
for (unsigned int i = 0; i < _s; ++i) {
if (! (*(reinterpret_cast<const T*>(_m) + i) == *(reinterpret_cast<const T*>(v._m) + i)))
if (!(*(reinterpret_cast<const T *>(_m) + i) == *(reinterpret_cast<const T *>(v._m) + i)))
return false;
}
return true;
@ -298,30 +260,18 @@ template <typename T, unsigned int C> class FCV {
return false;
}
ZT_INLINE bool operator!=(const FCV& v) const noexcept
{
return *this != v;
}
ZT_INLINE bool operator!=(const FCV &v) const noexcept { return *this != v; }
ZT_INLINE bool operator<(const FCV& v) const noexcept
ZT_INLINE bool operator<(const FCV &v) const noexcept
{
return std::lexicographical_compare(begin(), end(), v.begin(), v.end());
}
ZT_INLINE bool operator>(const FCV& v) const noexcept
{
return (v < *this);
}
ZT_INLINE bool operator>(const FCV &v) const noexcept { return (v < *this); }
ZT_INLINE bool operator<=(const FCV& v) const noexcept
{
return v >= *this;
}
ZT_INLINE bool operator<=(const FCV &v) const noexcept { return v >= *this; }
ZT_INLINE bool operator>=(const FCV& v) const noexcept
{
return *this >= v;
}
ZT_INLINE bool operator>=(const FCV &v) const noexcept { return *this >= v; }
private:
#ifdef _MSC_VER

View file

@ -34,35 +34,28 @@ class Fingerprint
: public ZT_Fingerprint
, public TriviallyCopyable {
public:
ZT_INLINE Fingerprint() noexcept
{
memoryZero(this);
}
ZT_INLINE Fingerprint() noexcept { memoryZero(this); }
ZT_INLINE Fingerprint(const ZT_Fingerprint& fp) noexcept
{
Utils::copy<sizeof(ZT_Fingerprint)>(this, &fp);
}
ZT_INLINE Fingerprint(const ZT_Fingerprint &fp) noexcept { Utils::copy<sizeof(ZT_Fingerprint)>(this, &fp); }
/**
* @return True if hash is not all zero (missing/unspecified)
*/
ZT_INLINE bool haveHash() const noexcept
{
return (! Utils::allZero(this->hash, ZT_FINGERPRINT_HASH_SIZE));
}
ZT_INLINE bool haveHash() const noexcept { return (!Utils::allZero(this->hash, ZT_FINGERPRINT_HASH_SIZE)); }
/**
* Get a base32-encoded representation of this fingerprint
*
* @param s Base32 string
*/
ZT_INLINE char* toString(char s[ZT_FINGERPRINT_STRING_SIZE_MAX]) const noexcept
ZT_INLINE char *toString(char s[ZT_FINGERPRINT_STRING_SIZE_MAX]) const noexcept
{
Address(this->address).toString(s);
if (haveHash()) {
s[ZT_ADDRESS_LENGTH_HEX] = '-';
Utils::b32e(this->hash, ZT_FINGERPRINT_HASH_SIZE, s + (ZT_ADDRESS_LENGTH_HEX + 1), ZT_FINGERPRINT_STRING_SIZE_MAX - (ZT_ADDRESS_LENGTH_HEX + 1));
Utils::b32e(
this->hash, ZT_FINGERPRINT_HASH_SIZE, s + (ZT_ADDRESS_LENGTH_HEX + 1),
ZT_FINGERPRINT_STRING_SIZE_MAX - (ZT_ADDRESS_LENGTH_HEX + 1));
}
return s;
}
@ -79,9 +72,9 @@ class Fingerprint
* @param s String to decode
* @return True if string appears to be valid and of the proper length (no other checking is done)
*/
ZT_INLINE bool fromString(const char* const s) noexcept
ZT_INLINE bool fromString(const char *const s) noexcept
{
if (! s)
if (!s)
return false;
const int l = (int)strlen(s);
if (l < ZT_ADDRESS_LENGTH_HEX)
@ -89,9 +82,10 @@ class Fingerprint
char a[ZT_ADDRESS_LENGTH_HEX + 1];
Utils::copy<ZT_ADDRESS_LENGTH_HEX>(a, s);
a[ZT_ADDRESS_LENGTH_HEX] = 0;
this->address = Utils::hexStrToU64(a) & ZT_ADDRESS_MASK;
this->address = Utils::hexStrToU64(a) & ZT_ADDRESS_MASK;
if (l > (ZT_ADDRESS_LENGTH_HEX + 1)) {
if (Utils::b32d(s + (ZT_ADDRESS_LENGTH_HEX + 1), this->hash, ZT_FINGERPRINT_HASH_SIZE) != ZT_FINGERPRINT_HASH_SIZE)
if (Utils::b32d(s + (ZT_ADDRESS_LENGTH_HEX + 1), this->hash, ZT_FINGERPRINT_HASH_SIZE)
!= ZT_FINGERPRINT_HASH_SIZE)
return false;
}
else {
@ -100,25 +94,13 @@ class Fingerprint
return true;
}
ZT_INLINE void zero() noexcept
{
memoryZero(this);
}
ZT_INLINE void zero() noexcept { memoryZero(this); }
ZT_INLINE unsigned long hashCode() const noexcept
{
return (unsigned long)this->address;
}
ZT_INLINE unsigned long hashCode() const noexcept { return (unsigned long)this->address; }
ZT_INLINE operator bool() const noexcept
{
return this->address != 0;
}
ZT_INLINE operator bool() const noexcept { return this->address != 0; }
static constexpr int marshalSizeMax() noexcept
{
return ZT_FINGERPRINT_MARSHAL_SIZE;
}
static constexpr int marshalSizeMax() noexcept { return ZT_FINGERPRINT_MARSHAL_SIZE; }
ZT_INLINE int marshal(uint8_t data[ZT_FINGERPRINT_MARSHAL_SIZE]) const noexcept
{
@ -127,7 +109,7 @@ class Fingerprint
return ZT_FINGERPRINT_MARSHAL_SIZE;
}
ZT_INLINE int unmarshal(const uint8_t* const data, int len) noexcept
ZT_INLINE int unmarshal(const uint8_t *const data, int len) noexcept
{
if (unlikely(len < ZT_FINGERPRINT_MARSHAL_SIZE))
return -1;
@ -136,35 +118,31 @@ class Fingerprint
return ZT_FINGERPRINT_MARSHAL_SIZE;
}
ZT_INLINE bool operator==(const ZT_Fingerprint& h) const noexcept
ZT_INLINE bool operator==(const ZT_Fingerprint &h) const noexcept
{
return ((this->address == h.address) && (memcmp(this->hash, h.hash, ZT_FINGERPRINT_HASH_SIZE) == 0));
}
ZT_INLINE bool operator!=(const ZT_Fingerprint& h) const noexcept
ZT_INLINE bool operator!=(const ZT_Fingerprint &h) const noexcept { return !(*this == h); }
ZT_INLINE bool operator<(const ZT_Fingerprint &h) const noexcept
{
return ! (*this == h);
return (
(this->address < h.address)
|| ((this->address == h.address) && (memcmp(this->hash, h.hash, ZT_FINGERPRINT_HASH_SIZE) < 0)));
}
ZT_INLINE bool operator<(const ZT_Fingerprint& h) const noexcept
ZT_INLINE bool operator>(const ZT_Fingerprint &h) const noexcept
{
return ((this->address < h.address) || ((this->address == h.address) && (memcmp(this->hash, h.hash, ZT_FINGERPRINT_HASH_SIZE) < 0)));
return (*reinterpret_cast<const Fingerprint *>(&h) < *this);
}
ZT_INLINE bool operator>(const ZT_Fingerprint& h) const noexcept
ZT_INLINE bool operator<=(const ZT_Fingerprint &h) const noexcept
{
return (*reinterpret_cast<const Fingerprint*>(&h) < *this);
return !(*reinterpret_cast<const Fingerprint *>(&h) < *this);
}
ZT_INLINE bool operator<=(const ZT_Fingerprint& h) const noexcept
{
return ! (*reinterpret_cast<const Fingerprint*>(&h) < *this);
}
ZT_INLINE bool operator>=(const ZT_Fingerprint& h) const noexcept
{
return ! (*this < h);
}
ZT_INLINE bool operator>=(const ZT_Fingerprint &h) const noexcept { return !(*this < h); }
};
static_assert(sizeof(Fingerprint) == sizeof(ZT_Fingerprint), "size mismatch");

View file

@ -30,7 +30,9 @@ namespace {
// This is the memory-intensive hash function used to compute v0 identities from v0 public keys.
#define ZT_V0_IDENTITY_GEN_MEMORY 2097152
void identityV0ProofOfWorkFrankenhash(const void* const restrict c25519CombinedPublicKey, void* const restrict digest, void* const restrict genmem) noexcept
void identityV0ProofOfWorkFrankenhash(
const void *const restrict c25519CombinedPublicKey, void *const restrict digest,
void *const restrict genmem) noexcept
{
// Digest publicKey[] to obtain initial digest
SHA512(digest, c25519CombinedPublicKey, ZT_C25519_COMBINED_PUBLIC_KEY_SIZE);
@ -39,35 +41,35 @@ void identityV0ProofOfWorkFrankenhash(const void* const restrict c25519CombinedP
// ordinary Salsa20 is randomly seek-able. This is good for a cipher
// but is not what we want for sequential memory-hardness.
Utils::zero<ZT_V0_IDENTITY_GEN_MEMORY>(genmem);
Salsa20 s20(digest, (char*)digest + 32);
s20.crypt20((char*)genmem, (char*)genmem, 64);
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) {
unsigned long k = i - 64;
*((uint64_t*)((char*)genmem + i)) = *((uint64_t*)((char*)genmem + k));
*((uint64_t*)((char*)genmem + i + 8)) = *((uint64_t*)((char*)genmem + k + 8));
*((uint64_t*)((char*)genmem + i + 16)) = *((uint64_t*)((char*)genmem + k + 16));
*((uint64_t*)((char*)genmem + i + 24)) = *((uint64_t*)((char*)genmem + k + 24));
*((uint64_t*)((char*)genmem + i + 32)) = *((uint64_t*)((char*)genmem + k + 32));
*((uint64_t*)((char*)genmem + i + 40)) = *((uint64_t*)((char*)genmem + k + 40));
*((uint64_t*)((char*)genmem + i + 48)) = *((uint64_t*)((char*)genmem + k + 48));
*((uint64_t*)((char*)genmem + i + 56)) = *((uint64_t*)((char*)genmem + k + 56));
s20.crypt20((char*)genmem + i, (char*)genmem + i, 64);
unsigned long k = i - 64;
*((uint64_t *)((char *)genmem + i)) = *((uint64_t *)((char *)genmem + k));
*((uint64_t *)((char *)genmem + i + 8)) = *((uint64_t *)((char *)genmem + k + 8));
*((uint64_t *)((char *)genmem + i + 16)) = *((uint64_t *)((char *)genmem + k + 16));
*((uint64_t *)((char *)genmem + i + 24)) = *((uint64_t *)((char *)genmem + k + 24));
*((uint64_t *)((char *)genmem + i + 32)) = *((uint64_t *)((char *)genmem + k + 32));
*((uint64_t *)((char *)genmem + i + 40)) = *((uint64_t *)((char *)genmem + k + 40));
*((uint64_t *)((char *)genmem + i + 48)) = *((uint64_t *)((char *)genmem + k + 48));
*((uint64_t *)((char *)genmem + i + 56)) = *((uint64_t *)((char *)genmem + k + 56));
s20.crypt20((char *)genmem + i, (char *)genmem + i, 64);
}
// Render final digest using genmem as a lookup table
for (unsigned long i = 0; i < (ZT_V0_IDENTITY_GEN_MEMORY / sizeof(uint64_t));) {
unsigned long idx1 = (unsigned long)(Utils::ntoh(((uint64_t*)genmem)[i++]) % (64 / sizeof(uint64_t)));
unsigned long idx2 = (unsigned long)(Utils::ntoh(((uint64_t*)genmem)[i++]) % (ZT_V0_IDENTITY_GEN_MEMORY / sizeof(uint64_t)));
uint64_t tmp = ((uint64_t*)genmem)[idx2];
((uint64_t*)genmem)[idx2] = ((uint64_t*)digest)[idx1];
((uint64_t*)digest)[idx1] = tmp;
unsigned long idx1 = (unsigned long)(Utils::ntoh(((uint64_t *)genmem)[i++]) % (64 / sizeof(uint64_t)));
unsigned long idx2 =
(unsigned long)(Utils::ntoh(((uint64_t *)genmem)[i++]) % (ZT_V0_IDENTITY_GEN_MEMORY / sizeof(uint64_t)));
uint64_t tmp = ((uint64_t *)genmem)[idx2];
((uint64_t *)genmem)[idx2] = ((uint64_t *)digest)[idx1];
((uint64_t *)digest)[idx1] = tmp;
s20.crypt20(digest, digest, 64);
}
}
struct identityV0ProofOfWorkCriteria
{
ZT_INLINE identityV0ProofOfWorkCriteria(unsigned char* restrict sb, char* restrict gm) noexcept
struct identityV0ProofOfWorkCriteria {
ZT_INLINE identityV0ProofOfWorkCriteria(unsigned char *restrict sb, char *restrict gm) noexcept
: digest(sb)
, genmem(gm)
{
@ -79,8 +81,8 @@ struct identityV0ProofOfWorkCriteria
return (digest[0] < 17);
}
unsigned char* restrict digest;
char* restrict genmem;
unsigned char *restrict digest;
char *restrict genmem;
};
void v1ChallengeFromPub(const uint8_t pub[ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE], uint64_t challenge[4])
@ -108,7 +110,7 @@ const Identity Identity::NIL;
bool Identity::generate(const Type t)
{
m_type = t;
m_type = t;
m_hasPrivate = true;
switch (t) {
@ -116,7 +118,7 @@ bool Identity::generate(const Type t)
// Generate C25519/Ed25519 key pair whose hash satisfies a "hashcash" criterion and generate the
// address from the last 40 bits of this hash. This is different from the fingerprint hash for V0.
uint8_t digest[64];
char* const genmem = new char[ZT_V0_IDENTITY_GEN_MEMORY];
char *const genmem = new char[ZT_V0_IDENTITY_GEN_MEMORY];
Address address;
do {
C25519::generateSatisfying(identityV0ProofOfWorkCriteria(digest, genmem), m_pub, m_priv);
@ -130,11 +132,13 @@ bool Identity::generate(const Type t)
case P384:
for (;;) {
C25519::generateCombined(m_pub + 7, m_priv);
ECC384GenerateKey(m_pub + 7 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE, m_priv + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE);
ECC384GenerateKey(
m_pub + 7 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE, m_priv + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE);
uint64_t challenge[4];
v1ChallengeFromPub(m_pub, challenge);
const uint64_t proof = MIMC52::delay(reinterpret_cast<const uint8_t*>(challenge), ZT_IDENTITY_TYPE1_MIMC52_ROUNDS);
const uint64_t proof =
MIMC52::delay(reinterpret_cast<const uint8_t *>(challenge), ZT_IDENTITY_TYPE1_MIMC52_ROUNDS);
m_pub[0] = (uint8_t)(proof >> 48U);
m_pub[1] = (uint8_t)(proof >> 40U);
m_pub[2] = (uint8_t)(proof >> 32U);
@ -145,15 +149,14 @@ bool Identity::generate(const Type t)
m_computeHash();
const Address addr(m_fp.hash);
if (! addr.isReserved()) {
if (!addr.isReserved()) {
m_fp.address = addr;
break;
}
}
break;
default:
return false;
default: return false;
}
return true;
@ -162,12 +165,12 @@ bool Identity::generate(const Type t)
bool Identity::locallyValidate() const noexcept
{
try {
if ((m_fp) && ((! Address(m_fp.address).isReserved()))) {
if ((m_fp) && ((!Address(m_fp.address).isReserved()))) {
switch (m_type) {
case C25519: {
uint8_t digest[64];
char* const genmem = (char*)malloc(ZT_V0_IDENTITY_GEN_MEMORY);
if (! genmem)
char *const genmem = (char *)malloc(ZT_V0_IDENTITY_GEN_MEMORY);
if (!genmem)
return false;
identityV0ProofOfWorkFrankenhash(m_pub, digest, genmem);
free(genmem);
@ -179,9 +182,10 @@ bool Identity::locallyValidate() const noexcept
uint64_t challenge[4];
v1ChallengeFromPub(m_pub, challenge);
return MIMC52::verify(
reinterpret_cast<const uint8_t*>(challenge),
ZT_IDENTITY_TYPE1_MIMC52_ROUNDS,
((uint64_t)m_pub[0] << 48U) | ((uint64_t)m_pub[1] << 40U) | ((uint64_t)m_pub[2] << 32U) | ((uint64_t)m_pub[3] << 24U) | ((uint64_t)m_pub[4] << 16U) | ((uint64_t)m_pub[5] << 8U) | (uint64_t)m_pub[6]);
reinterpret_cast<const uint8_t *>(challenge), ZT_IDENTITY_TYPE1_MIMC52_ROUNDS,
((uint64_t)m_pub[0] << 48U) | ((uint64_t)m_pub[1] << 40U) | ((uint64_t)m_pub[2] << 32U)
| ((uint64_t)m_pub[3] << 24U) | ((uint64_t)m_pub[4] << 16U) | ((uint64_t)m_pub[5] << 8U)
| (uint64_t)m_pub[6]);
}
return false;
}
@ -200,15 +204,13 @@ void Identity::hashWithPrivate(uint8_t h[ZT_FINGERPRINT_HASH_SIZE]) const
SHA384(h, m_pub, ZT_C25519_COMBINED_PUBLIC_KEY_SIZE, m_priv, ZT_C25519_COMBINED_PRIVATE_KEY_SIZE);
return;
case P384:
SHA384(h, m_pub, sizeof(m_pub), m_priv, sizeof(m_priv));
return;
case P384: SHA384(h, m_pub, sizeof(m_pub), m_priv, sizeof(m_priv)); return;
}
}
Utils::zero<ZT_FINGERPRINT_HASH_SIZE>(h);
}
unsigned int Identity::sign(const void* data, unsigned int len, void* sig, unsigned int siglen) const
unsigned int Identity::sign(const void *data, unsigned int len, void *sig, unsigned int siglen) const
{
if (m_hasPrivate) {
switch (m_type) {
@ -224,7 +226,7 @@ unsigned int Identity::sign(const void* data, unsigned int len, void* sig, unsig
static_assert(ZT_ECC384_SIGNATURE_HASH_SIZE == ZT_SHA384_DIGEST_SIZE, "weird!");
uint8_t h[ZT_ECC384_SIGNATURE_HASH_SIZE];
SHA384(h, data, len, m_pub, ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE);
ECC384ECDSASign(m_priv + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE, h, (uint8_t*)sig);
ECC384ECDSASign(m_priv + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE, h, (uint8_t *)sig);
return ZT_ECC384_SIGNATURE_SIZE;
}
break;
@ -233,24 +235,23 @@ unsigned int Identity::sign(const void* data, unsigned int len, void* sig, unsig
return 0;
}
bool Identity::verify(const void* data, unsigned int len, const void* sig, unsigned int siglen) const
bool Identity::verify(const void *data, unsigned int len, const void *sig, unsigned int siglen) const
{
switch (m_type) {
case C25519:
return C25519::verify(m_pub, data, len, sig, siglen);
case C25519: return C25519::verify(m_pub, data, len, sig, siglen);
case P384:
if (siglen == ZT_ECC384_SIGNATURE_SIZE) {
uint8_t h[ZT_ECC384_SIGNATURE_HASH_SIZE];
SHA384(h, data, len, m_pub, ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE);
return ECC384ECDSAVerify(m_pub + 7 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE, h, (const uint8_t*)sig);
return ECC384ECDSAVerify(m_pub + 7 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE, h, (const uint8_t *)sig);
}
break;
}
return false;
}
bool Identity::agree(const Identity& id, uint8_t key[ZT_SYMMETRIC_KEY_SIZE]) const
bool Identity::agree(const Identity &id, uint8_t key[ZT_SYMMETRIC_KEY_SIZE]) const
{
uint8_t rawkey[128], h[64];
if (m_hasPrivate) {
@ -269,7 +270,9 @@ bool Identity::agree(const Identity& id, uint8_t key[ZT_SYMMETRIC_KEY_SIZE]) con
// or something. For those who don't trust P384 this means the privacy of
// your traffic is also protected by C25519.
C25519::agree(m_priv, id.m_pub, rawkey);
ECC384ECDH(id.m_pub + 7 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE, m_priv + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE, rawkey + ZT_C25519_ECDH_SHARED_SECRET_SIZE);
ECC384ECDH(
id.m_pub + 7 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE, m_priv + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE,
rawkey + ZT_C25519_ECDH_SHARED_SECRET_SIZE);
SHA384(key, rawkey, ZT_C25519_ECDH_SHARED_SECRET_SIZE + ZT_ECC384_SHARED_SECRET_SIZE);
return true;
}
@ -277,9 +280,9 @@ bool Identity::agree(const Identity& id, uint8_t key[ZT_SYMMETRIC_KEY_SIZE]) con
return false;
}
char* Identity::toString(bool includePrivate, char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]) const
char *Identity::toString(bool includePrivate, char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]) const
{
char* p = buf;
char *p = buf;
Address(m_fp.address).toString(p);
p += 10;
*(p++) = ':';
@ -301,13 +304,15 @@ char* Identity::toString(bool includePrivate, char buf[ZT_IDENTITY_STRING_BUFFER
case P384: {
*(p++) = '1';
*(p++) = ':';
int el = Utils::b32e(m_pub, sizeof(m_pub), p, (int)(ZT_IDENTITY_STRING_BUFFER_LENGTH - (uintptr_t)(p - buf)));
int el =
Utils::b32e(m_pub, sizeof(m_pub), p, (int)(ZT_IDENTITY_STRING_BUFFER_LENGTH - (uintptr_t)(p - buf)));
if (el <= 0)
return nullptr;
p += el;
if ((m_hasPrivate) && (includePrivate)) {
*(p++) = ':';
el = Utils::b32e(m_priv, sizeof(m_priv), p, (int)(ZT_IDENTITY_STRING_BUFFER_LENGTH - (uintptr_t)(p - buf)));
el = Utils::b32e(
m_priv, sizeof(m_priv), p, (int)(ZT_IDENTITY_STRING_BUFFER_LENGTH - (uintptr_t)(p - buf)));
if (el <= 0)
return nullptr;
p += el;
@ -315,23 +320,22 @@ char* Identity::toString(bool includePrivate, char buf[ZT_IDENTITY_STRING_BUFFER
*p = (char)0;
return buf;
}
default:
buf[0] = 0;
default: buf[0] = 0;
}
return nullptr;
}
bool Identity::fromString(const char* str)
bool Identity::fromString(const char *str)
{
char tmp[ZT_IDENTITY_STRING_BUFFER_LENGTH];
memoryZero(this);
if ((! str) || (! Utils::scopy(tmp, sizeof(tmp), str)))
if ((!str) || (!Utils::scopy(tmp, sizeof(tmp), str)))
return false;
int fno = 0;
char* saveptr = nullptr;
for (char* f = Utils::stok(tmp, ":", &saveptr); ((f) && (fno < 4)); f = Utils::stok(nullptr, ":", &saveptr)) {
int fno = 0;
char *saveptr = nullptr;
for (char *f = Utils::stok(tmp, ":", &saveptr); ((f) && (fno < 4)); f = Utils::stok(nullptr, ":", &saveptr)) {
switch (fno++) {
case 0:
m_fp.address = Utils::hexStrToU64(f) & ZT_ADDRESS_MASK;
@ -340,10 +344,10 @@ bool Identity::fromString(const char* str)
break;
case 1:
if ((f[0] == '0') && (! f[1])) {
if ((f[0] == '0') && (!f[1])) {
m_type = C25519;
}
else if ((f[0] == '1') && (! f[1])) {
else if ((f[0] == '1') && (!f[1])) {
m_type = P384;
}
else {
@ -354,7 +358,8 @@ bool Identity::fromString(const char* str)
case 2:
switch (m_type) {
case C25519:
if (Utils::unhex(f, strlen(f), m_pub, ZT_C25519_COMBINED_PUBLIC_KEY_SIZE) != ZT_C25519_COMBINED_PUBLIC_KEY_SIZE)
if (Utils::unhex(f, strlen(f), m_pub, ZT_C25519_COMBINED_PUBLIC_KEY_SIZE)
!= ZT_C25519_COMBINED_PUBLIC_KEY_SIZE)
return false;
break;
@ -369,7 +374,8 @@ bool Identity::fromString(const char* str)
if (strlen(f) > 1) {
switch (m_type) {
case C25519:
if (Utils::unhex(f, strlen(f), m_priv, ZT_C25519_COMBINED_PRIVATE_KEY_SIZE) != ZT_C25519_COMBINED_PRIVATE_KEY_SIZE) {
if (Utils::unhex(f, strlen(f), m_priv, ZT_C25519_COMBINED_PRIVATE_KEY_SIZE)
!= ZT_C25519_COMBINED_PRIVATE_KEY_SIZE) {
return false;
}
else {
@ -395,7 +401,7 @@ bool Identity::fromString(const char* str)
return false;
m_computeHash();
return ! ((m_type == P384) && (Address(m_fp.hash) != m_fp.address));
return !((m_type == P384) && (Address(m_fp.hash) != m_fp.address));
}
int Identity::marshal(uint8_t data[ZT_IDENTITY_MARSHAL_SIZE_MAX], const bool includePrivate) const noexcept
@ -407,8 +413,10 @@ int Identity::marshal(uint8_t data[ZT_IDENTITY_MARSHAL_SIZE_MAX], const bool inc
Utils::copy<ZT_C25519_COMBINED_PUBLIC_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1, m_pub);
if ((includePrivate) && (m_hasPrivate)) {
data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE] = ZT_C25519_COMBINED_PRIVATE_KEY_SIZE;
Utils::copy<ZT_C25519_COMBINED_PRIVATE_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1, m_priv);
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1 + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE;
Utils::copy<ZT_C25519_COMBINED_PRIVATE_KEY_SIZE>(
data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1, m_priv);
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1
+ ZT_C25519_COMBINED_PRIVATE_KEY_SIZE;
}
data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE] = 0;
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1;
@ -417,9 +425,12 @@ int Identity::marshal(uint8_t data[ZT_IDENTITY_MARSHAL_SIZE_MAX], const bool inc
data[ZT_ADDRESS_LENGTH] = (uint8_t)P384;
Utils::copy<ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1, m_pub);
if ((includePrivate) && (m_hasPrivate)) {
data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE] = 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, m_priv);
return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE;
data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE] =
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, m_priv);
return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1
+ ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE;
}
data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE] = 0;
return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1;
@ -427,7 +438,7 @@ int Identity::marshal(uint8_t data[ZT_IDENTITY_MARSHAL_SIZE_MAX], const bool inc
return -1;
}
int Identity::unmarshal(const uint8_t* data, const int len) noexcept
int Identity::unmarshal(const uint8_t *data, const int len) noexcept
{
memoryZero(this);
@ -446,11 +457,15 @@ int Identity::unmarshal(const uint8_t* data, const int len) noexcept
privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE];
if (privlen == ZT_C25519_COMBINED_PRIVATE_KEY_SIZE) {
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1 + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE))
if (len
< (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1
+ ZT_C25519_COMBINED_PRIVATE_KEY_SIZE))
return -1;
m_hasPrivate = true;
Utils::copy<ZT_C25519_COMBINED_PRIVATE_KEY_SIZE>(m_priv, data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1);
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1 + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE;
Utils::copy<ZT_C25519_COMBINED_PRIVATE_KEY_SIZE>(
m_priv, data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1);
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1
+ ZT_C25519_COMBINED_PRIVATE_KEY_SIZE;
}
else if (privlen == 0) {
m_hasPrivate = false;
@ -473,11 +488,15 @@ int Identity::unmarshal(const uint8_t* data, const int len) noexcept
return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1;
}
else if (privlen == ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE) {
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE))
if (len
< (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1
+ ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE))
return -1;
m_hasPrivate = true;
Utils::copy<ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE>(&m_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;
Utils::copy<ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE>(
&m_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;
}
break;
}
@ -488,17 +507,11 @@ int Identity::unmarshal(const uint8_t* data, const int len) noexcept
void Identity::m_computeHash()
{
switch (m_type) {
default:
m_fp.zero();
break;
default: m_fp.zero(); break;
case C25519:
SHA384(m_fp.hash, m_pub, ZT_C25519_COMBINED_PUBLIC_KEY_SIZE);
break;
case C25519: SHA384(m_fp.hash, m_pub, ZT_C25519_COMBINED_PUBLIC_KEY_SIZE); break;
case P384:
SHA384(m_fp.hash, m_pub, ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE);
break;
case P384: SHA384(m_fp.hash, m_pub, ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE); break;
}
}

View file

@ -27,8 +27,9 @@
#define ZT_IDENTITY_STRING_BUFFER_LENGTH 1024
#define ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE (7 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + ZT_ECC384_PUBLIC_KEY_SIZE)
#define ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE (ZT_C25519_COMBINED_PRIVATE_KEY_SIZE + ZT_ECC384_PRIVATE_KEY_SIZE)
#define ZT_IDENTITY_MARSHAL_SIZE_MAX (ZT_ADDRESS_LENGTH + 4 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE)
#define ZT_IDENTITY_TYPE1_MIMC52_ROUNDS 262144
#define ZT_IDENTITY_MARSHAL_SIZE_MAX \
(ZT_ADDRESS_LENGTH + 4 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE)
#define ZT_IDENTITY_TYPE1_MIMC52_ROUNDS 262144
namespace ZeroTier {
@ -51,7 +52,7 @@ class Identity : public TriviallyCopyable {
*/
enum Type {
C25519 = ZT_IDENTITY_TYPE_C25519, // Type 0 -- Curve25519 and Ed25519 (1.x and 2.x, default)
P384 = ZT_IDENTITY_TYPE_P384 // Type 1 -- NIST P-384 with linked Curve25519/Ed25519 secondaries (2.x+)
P384 = ZT_IDENTITY_TYPE_P384 // Type 1 -- NIST P-384 with linked Curve25519/Ed25519 secondaries (2.x+)
};
/**
@ -59,15 +60,9 @@ class Identity : public TriviallyCopyable {
*/
static const Identity NIL;
ZT_INLINE Identity() noexcept
{
memoryZero(this);
}
ZT_INLINE Identity() noexcept { memoryZero(this); }
ZT_INLINE Identity(const Identity& id) noexcept
{
Utils::copy<sizeof(Identity)>(this, &id);
}
ZT_INLINE Identity(const Identity &id) noexcept { Utils::copy<sizeof(Identity)>(this, &id); }
/**
* Construct identity from string
@ -77,17 +72,11 @@ class Identity : public TriviallyCopyable {
*
* @param str Identity in canonical string format
*/
explicit ZT_INLINE Identity(const char* str)
{
fromString(str);
}
explicit ZT_INLINE Identity(const char *str) { fromString(str); }
ZT_INLINE ~Identity()
{
Utils::burn(reinterpret_cast<void*>(&this->m_priv), sizeof(this->m_priv));
}
ZT_INLINE ~Identity() { Utils::burn(reinterpret_cast<void *>(&this->m_priv), sizeof(this->m_priv)); }
ZT_INLINE Identity& operator=(const Identity& id) noexcept
ZT_INLINE Identity &operator=(const Identity &id) noexcept
{
if (likely(this != &id))
Utils::copy<sizeof(Identity)>(this, &id);
@ -97,18 +86,12 @@ class Identity : public TriviallyCopyable {
/**
* Set identity to NIL value (all zero)
*/
ZT_INLINE void zero() noexcept
{
memoryZero(this);
}
ZT_INLINE void zero() noexcept { memoryZero(this); }
/**
* @return Identity type (undefined if identity is null or invalid)
*/
ZT_INLINE Type type() const noexcept
{
return m_type;
}
ZT_INLINE Type type() const noexcept { return m_type; }
/**
* Generate a new identity (address, key pair)
@ -134,26 +117,17 @@ class Identity : public TriviallyCopyable {
/**
* @return True if this identity contains a private key
*/
ZT_INLINE bool hasPrivate() const noexcept
{
return m_hasPrivate;
}
ZT_INLINE bool hasPrivate() const noexcept { return m_hasPrivate; }
/**
* @return This identity's address
*/
ZT_INLINE Address address() const noexcept
{
return Address(m_fp.address);
}
ZT_INLINE Address address() const noexcept { return Address(m_fp.address); }
/**
* @return Full fingerprint of this identity (address plus SHA384 of keys)
*/
ZT_INLINE const Fingerprint& fingerprint() const noexcept
{
return m_fp;
}
ZT_INLINE const Fingerprint &fingerprint() const noexcept { return m_fp; }
/**
* Compute a hash of this identity's public and private keys.
@ -176,7 +150,7 @@ class Identity : public TriviallyCopyable {
* @param siglen Length of buffer
* @return Number of bytes actually written to sig or 0 on error
*/
unsigned int sign(const void* data, unsigned int len, void* sig, unsigned int siglen) const;
unsigned int sign(const void *data, unsigned int len, void *sig, unsigned int siglen) const;
/**
* Verify a message signature against this identity
@ -187,7 +161,7 @@ class Identity : public TriviallyCopyable {
* @param siglen Length of signature in bytes
* @return True if signature validates and data integrity checks
*/
bool verify(const void* data, unsigned int len, const void* sig, unsigned int siglen) const;
bool verify(const void *data, unsigned int len, const void *sig, unsigned int siglen) const;
/**
* Shortcut method to perform key agreement with another identity
@ -198,7 +172,7 @@ class Identity : public TriviallyCopyable {
* @param key Result parameter to fill with key bytes
* @return Was agreement successful?
*/
bool agree(const Identity& id, uint8_t key[ZT_SYMMETRIC_KEY_SIZE]) const;
bool agree(const Identity &id, uint8_t key[ZT_SYMMETRIC_KEY_SIZE]) const;
/**
* Serialize to a more human-friendly string
@ -207,7 +181,7 @@ class Identity : public TriviallyCopyable {
* @param buf Buffer to store string
* @return ASCII string representation of identity (pointer to buf)
*/
char* toString(bool includePrivate, char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]) const;
char *toString(bool includePrivate, char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]) const;
ZT_INLINE String toString(const bool includePrivate = false) const
{
@ -225,7 +199,7 @@ class Identity : public TriviallyCopyable {
* @param str String to deserialize
* @return True if deserialization appears successful
*/
bool fromString(const char* str);
bool fromString(const char *str);
/**
* Erase any private key in this identity object
@ -239,53 +213,26 @@ class Identity : public TriviallyCopyable {
/**
* @return True if this identity contains something
*/
explicit ZT_INLINE operator bool() const noexcept
{
return (m_fp);
}
explicit ZT_INLINE operator bool() const noexcept { return (m_fp); }
ZT_INLINE unsigned long hashCode() const noexcept
{
return m_fp.hashCode();
}
ZT_INLINE unsigned long hashCode() const noexcept { return m_fp.hashCode(); }
ZT_INLINE bool operator==(const Identity& id) const noexcept
{
return (m_fp == id.m_fp);
}
ZT_INLINE bool operator==(const Identity &id) const noexcept { return (m_fp == id.m_fp); }
ZT_INLINE bool operator!=(const Identity& id) const noexcept
{
return ! (*this == id);
}
ZT_INLINE bool operator!=(const Identity &id) const noexcept { return !(*this == id); }
ZT_INLINE bool operator<(const Identity& id) const noexcept
{
return (m_fp < id.m_fp);
}
ZT_INLINE bool operator<(const Identity &id) const noexcept { return (m_fp < id.m_fp); }
ZT_INLINE bool operator>(const Identity& id) const noexcept
{
return (id < *this);
}
ZT_INLINE bool operator>(const Identity &id) const noexcept { return (id < *this); }
ZT_INLINE bool operator<=(const Identity& id) const noexcept
{
return ! (id < *this);
}
ZT_INLINE bool operator<=(const Identity &id) const noexcept { return !(id < *this); }
ZT_INLINE bool operator>=(const Identity& id) const noexcept
{
return ! (*this < id);
}
ZT_INLINE bool operator>=(const Identity &id) const noexcept { return !(*this < id); }
static constexpr int marshalSizeMax() noexcept
{
return ZT_IDENTITY_MARSHAL_SIZE_MAX;
}
static constexpr int marshalSizeMax() noexcept { return ZT_IDENTITY_MARSHAL_SIZE_MAX; }
int marshal(uint8_t data[ZT_IDENTITY_MARSHAL_SIZE_MAX], bool includePrivate = false) const noexcept;
int unmarshal(const uint8_t* data, int len) noexcept;
int unmarshal(const uint8_t *data, int len) noexcept;
private:
void m_computeHash();

View file

@ -59,73 +59,40 @@ struct InetAddress : public TriviallyCopyable {
*/
typedef ZT_InetAddress_IpScope IpScope;
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 { *this = ss; }
explicit ZT_INLINE InetAddress(const sockaddr_storage* const ss) noexcept
{
*this = ss;
}
explicit ZT_INLINE InetAddress(const sockaddr_storage *const ss) noexcept { *this = ss; }
explicit ZT_INLINE InetAddress(const sockaddr& sa) noexcept
{
*this = sa;
}
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 *const sa) noexcept { *this = sa; }
explicit ZT_INLINE InetAddress(const sockaddr_in& 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_in *const sa) noexcept { *this = sa; }
explicit ZT_INLINE InetAddress(const sockaddr_in6& 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;
}
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
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);
}
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);
}
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;
return *this;
}
ZT_INLINE InetAddress& operator=(const sockaddr_storage* ss) noexcept
ZT_INLINE InetAddress &operator=(const sockaddr_storage *ss) noexcept
{
if (ss)
as.ss = *ss;
@ -134,14 +101,14 @@ struct InetAddress : public TriviallyCopyable {
return *this;
}
ZT_INLINE InetAddress& operator=(const sockaddr_in& sa) noexcept
ZT_INLINE InetAddress &operator=(const sockaddr_in &sa) noexcept
{
memoryZero(this);
as.sa_in = sa;
return *this;
}
ZT_INLINE InetAddress& operator=(const sockaddr_in* sa) noexcept
ZT_INLINE InetAddress &operator=(const sockaddr_in *sa) noexcept
{
memoryZero(this);
if (sa)
@ -149,14 +116,14 @@ struct InetAddress : public TriviallyCopyable {
return *this;
}
ZT_INLINE InetAddress& operator=(const sockaddr_in6& sa) noexcept
ZT_INLINE InetAddress &operator=(const sockaddr_in6 &sa) noexcept
{
memoryZero(this);
as.sa_in6 = sa;
return *this;
}
ZT_INLINE InetAddress& operator=(const sockaddr_in6* sa) noexcept
ZT_INLINE InetAddress &operator=(const sockaddr_in6 *sa) noexcept
{
memoryZero(this);
if (sa)
@ -164,32 +131,29 @@ struct InetAddress : public TriviallyCopyable {
return *this;
}
ZT_INLINE InetAddress& operator=(const sockaddr& sa) noexcept
ZT_INLINE InetAddress &operator=(const sockaddr &sa) noexcept
{
memoryZero(this);
if (sa.sa_family == AF_INET)
as.sa_in = *reinterpret_cast<const sockaddr_in*>(&sa);
as.sa_in = *reinterpret_cast<const sockaddr_in *>(&sa);
else if (sa.sa_family == AF_INET6)
as.sa_in6 = *reinterpret_cast<const sockaddr_in6*>(&sa);
as.sa_in6 = *reinterpret_cast<const sockaddr_in6 *>(&sa);
return *this;
}
ZT_INLINE InetAddress& operator=(const sockaddr* sa) noexcept
ZT_INLINE InetAddress &operator=(const sockaddr *sa) noexcept
{
memoryZero(this);
if (sa) {
if (sa->sa_family == AF_INET)
as.sa_in = *reinterpret_cast<const sockaddr_in*>(sa);
as.sa_in = *reinterpret_cast<const sockaddr_in *>(sa);
else if (sa->sa_family == AF_INET6)
as.sa_in6 = *reinterpret_cast<const sockaddr_in6*>(sa);
as.sa_in6 = *reinterpret_cast<const sockaddr_in6 *>(sa);
}
return *this;
}
ZT_INLINE void clear() noexcept
{
memoryZero(this);
}
ZT_INLINE void clear() noexcept { memoryZero(this); }
/**
* @return IP scope classification (e.g. loopback, link-local, private, global)
@ -203,7 +167,7 @@ struct InetAddress : public TriviallyCopyable {
* @param ipLen Length of IP address: 4 or 16
* @param port Port number or 0 for none
*/
void set(const void* ipBytes, unsigned int ipLen, unsigned int port) noexcept;
void set(const void *ipBytes, unsigned int ipLen, unsigned int port) noexcept;
/**
* Set the port component
@ -213,12 +177,8 @@ struct InetAddress : public TriviallyCopyable {
ZT_INLINE void setPort(unsigned int port) noexcept
{
switch (as.ss.ss_family) {
case AF_INET:
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;
case AF_INET: 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;
}
}
@ -230,7 +190,7 @@ struct InetAddress : public TriviallyCopyable {
/**
* @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
{
@ -242,7 +202,7 @@ struct InetAddress : public TriviallyCopyable {
/**
* @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
{
@ -255,7 +215,7 @@ struct InetAddress : public TriviallyCopyable {
* @param ipSlashPort IP/port (port is optional, will be 0 if not included)
* @return True if address appeared to be valid
*/
bool fromString(const char* ipSlashPort) noexcept;
bool fromString(const char *ipSlashPort) noexcept;
/**
* @return Port or 0 if no port component defined
@ -263,12 +223,9 @@ struct InetAddress : public TriviallyCopyable {
ZT_INLINE unsigned int port() const noexcept
{
switch (as.ss.ss_family) {
case AF_INET:
return Utils::ntoh((uint16_t)as.sa_in.sin_port);
case AF_INET6:
return Utils::ntoh((uint16_t)as.sa_in6.sin6_port);
default:
return 0;
case AF_INET: return Utils::ntoh((uint16_t)as.sa_in.sin_port);
case AF_INET6: return Utils::ntoh((uint16_t)as.sa_in6.sin6_port);
default: return 0;
}
}
@ -281,10 +238,7 @@ struct InetAddress : public TriviallyCopyable {
*
* @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
@ -293,10 +247,8 @@ struct InetAddress : public TriviallyCopyable {
{
const unsigned int n = port();
switch (as.ss.ss_family) {
case AF_INET:
return (n <= 32);
case AF_INET6:
return (n <= 128);
case AF_INET: return (n <= 32);
case AF_INET6: return (n <= 128);
}
return false;
}
@ -309,10 +261,7 @@ struct InetAddress : public TriviallyCopyable {
*
* @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
@ -344,7 +293,7 @@ struct InetAddress : public TriviallyCopyable {
* @param addr Address to check
* @return True if this IPv6 prefix matches the prefix of a given IPv6 address
*/
bool isEqualPrefix(const InetAddress& addr) const noexcept;
bool isEqualPrefix(const InetAddress &addr) const noexcept;
/**
* Test whether this IP/netmask contains this address
@ -352,36 +301,27 @@ struct InetAddress : public TriviallyCopyable {
* @param addr Address to check
* @return True if this IP/netmask (route) contains this address
*/
bool containsAddress(const InetAddress& addr) const noexcept;
bool containsAddress(const InetAddress &addr) const noexcept;
/**
* @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
*/
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
*/
ZT_INLINE const void* rawIpData() const noexcept
ZT_INLINE const void *rawIpData() const noexcept
{
switch (as.ss.ss_family) {
case AF_INET:
return reinterpret_cast<const void*>(&(as.sa_in.sin_addr.s_addr));
case AF_INET6:
return reinterpret_cast<const void*>(as.sa_in6.sin6_addr.s6_addr);
default:
return nullptr;
case AF_INET: return reinterpret_cast<const void *>(&(as.sa_in.sin_addr.s_addr));
case AF_INET6: return reinterpret_cast<const void *>(as.sa_in6.sin6_addr.s6_addr);
default: return nullptr;
}
}
@ -393,7 +333,7 @@ struct InetAddress : public TriviallyCopyable {
InetAddress r;
switch (as.ss.ss_family) {
case AF_INET:
r.as.sa_in.sin_family = AF_INET;
r.as.sa_in.sin_family = AF_INET;
r.as.sa_in.sin_addr.s_addr = as.sa_in.sin_addr.s_addr;
break;
case AF_INET6:
@ -410,7 +350,7 @@ struct InetAddress : public TriviallyCopyable {
* @param a InetAddress to compare again
* @return True if only IP portions are equal (false for non-IP or null addresses)
*/
ZT_INLINE bool ipsEqual(const InetAddress& a) const noexcept
ZT_INLINE bool ipsEqual(const InetAddress &a) const noexcept
{
const uint8_t f = as.ss.ss_family;
if (f == a.as.ss.ss_family) {
@ -431,7 +371,7 @@ struct InetAddress : public TriviallyCopyable {
* @param a InetAddress to compare again
* @return True if only IP portions are equal (false for non-IP or null addresses)
*/
ZT_INLINE bool ipsEqual2(const InetAddress& a) const noexcept
ZT_INLINE bool ipsEqual2(const InetAddress &a) const noexcept
{
const uint8_t f = as.ss.ss_family;
if (f == a.as.ss.ss_family) {
@ -447,10 +387,14 @@ struct InetAddress : public TriviallyCopyable {
ZT_INLINE unsigned long hashCode() const noexcept
{
if (as.ss.ss_family == AF_INET) {
return (unsigned long)Utils::hash32(((uint32_t)as.sa_in.sin_addr.s_addr + (uint32_t)as.sa_in.sin_port) ^ (uint32_t)Utils::s_mapNonce);
return (unsigned long)Utils::hash32(
((uint32_t)as.sa_in.sin_addr.s_addr + (uint32_t)as.sa_in.sin_port) ^ (uint32_t)Utils::s_mapNonce);
}
else if (as.ss.ss_family == AF_INET6) {
return (unsigned long)Utils::hash64((Utils::loadMachineEndian<uint64_t>(as.sa_in6.sin6_addr.s6_addr) + Utils::loadMachineEndian<uint64_t>(as.sa_in6.sin6_addr.s6_addr + 8) + (uint64_t)as.sa_in6.sin6_port) ^ Utils::s_mapNonce);
return (unsigned long)Utils::hash64(
(Utils::loadMachineEndian<uint64_t>(as.sa_in6.sin6_addr.s6_addr)
+ Utils::loadMachineEndian<uint64_t>(as.sa_in6.sin6_addr.s6_addr + 8) + (uint64_t)as.sa_in6.sin6_port)
^ Utils::s_mapNonce);
}
return Utils::fnv1a32(this, sizeof(InetAddress));
}
@ -468,40 +412,39 @@ struct InetAddress : public TriviallyCopyable {
/**
* @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 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
{
if (as.ss.ss_family == a.as.ss.ss_family) {
if (as.ss.ss_family == AF_INET)
return ((as.sa_in.sin_port == a.as.sa_in.sin_port) && (as.sa_in.sin_addr.s_addr == a.as.sa_in.sin_addr.s_addr));
return (
(as.sa_in.sin_port == a.as.sa_in.sin_port)
&& (as.sa_in.sin_addr.s_addr == a.as.sa_in.sin_addr.s_addr));
if (as.ss.ss_family == AF_INET6)
return ((as.sa_in6.sin6_port == a.as.sa_in6.sin6_port) && (memcmp(as.sa_in6.sin6_addr.s6_addr, a.as.sa_in6.sin6_addr.s6_addr, 16) == 0));
return (
(as.sa_in6.sin6_port == a.as.sa_in6.sin6_port)
&& (memcmp(as.sa_in6.sin6_addr.s6_addr, a.as.sa_in6.sin6_addr.s6_addr, 16) == 0));
return memcmp(this, &a, sizeof(InetAddress)) == 0;
}
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 == AF_INET) {
const uint16_t p0 = Utils::ntoh((uint16_t)as.sa_in.sin_port);
const uint16_t p1 = Utils::ntoh((uint16_t)a.as.sa_in.sin_port);
if (p0 == p1)
return Utils::ntoh((uint32_t)as.sa_in.sin_addr.s_addr) < Utils::ntoh((uint32_t)a.as.sa_in.sin_addr.s_addr);
return Utils::ntoh((uint32_t)as.sa_in.sin_addr.s_addr)
< Utils::ntoh((uint32_t)a.as.sa_in.sin_addr.s_addr);
return p0 < p1;
}
if (as.ss.ss_family == AF_INET6) {
@ -516,25 +459,13 @@ struct InetAddress : public TriviallyCopyable {
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 !(*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 ! (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);
}
ZT_INLINE bool operator>=(const InetAddress &a) const noexcept { return !(*this < a); }
/**
* Compute an IPv6 link-local address
@ -542,7 +473,7 @@ struct InetAddress : public TriviallyCopyable {
* @param mac MAC address seed
* @return IPv6 link-local address
*/
static InetAddress makeIpv6LinkLocal(const MAC& mac) noexcept;
static InetAddress makeIpv6LinkLocal(const MAC &mac) noexcept;
/**
* Compute private IPv6 unicast address from network ID and ZeroTier address
@ -603,104 +534,89 @@ struct InetAddress : public TriviallyCopyable {
} as;
};
static ZT_INLINE InetAddress* asInetAddress(sockaddr_in* const p) noexcept
static ZT_INLINE InetAddress *asInetAddress(sockaddr_in *const p) noexcept
{
return reinterpret_cast<InetAddress*>(p);
return reinterpret_cast<InetAddress *>(p);
}
static ZT_INLINE InetAddress* asInetAddress(sockaddr_in6* 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
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);
return reinterpret_cast<InetAddress *>(p);
}
static ZT_INLINE InetAddress* asInetAddress(sockaddr_storage* const p) noexcept
static ZT_INLINE InetAddress *asInetAddress(ZT_InetAddress *const p) noexcept
{
return reinterpret_cast<InetAddress*>(p);
return reinterpret_cast<InetAddress *>(p);
}
static ZT_INLINE InetAddress* asInetAddress(ZT_InetAddress* const p) noexcept
static ZT_INLINE const InetAddress *asInetAddress(const sockaddr_in *const p) noexcept
{
return reinterpret_cast<InetAddress*>(p);
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 *const p) noexcept
{
return reinterpret_cast<const InetAddress*>(p);
return reinterpret_cast<const InetAddress *>(p);
}
static ZT_INLINE const InetAddress* asInetAddress(const sockaddr_in6* const p) noexcept
static ZT_INLINE const InetAddress *asInetAddress(const sockaddr *const p) noexcept
{
return reinterpret_cast<const InetAddress*>(p);
return reinterpret_cast<const InetAddress *>(p);
}
static ZT_INLINE const InetAddress* asInetAddress(const 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<const InetAddress *>(p);
}
static ZT_INLINE const InetAddress* asInetAddress(const sockaddr_storage* const p) noexcept
static ZT_INLINE const InetAddress *asInetAddress(const ZT_InetAddress *const p) noexcept
{
return reinterpret_cast<const InetAddress*>(p);
return reinterpret_cast<const InetAddress *>(p);
}
static ZT_INLINE const InetAddress* asInetAddress(const ZT_InetAddress* const p) noexcept
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<const InetAddress*>(p);
return *reinterpret_cast<InetAddress *>(&p);
}
static ZT_INLINE InetAddress& asInetAddress(sockaddr_in& p) noexcept
static ZT_INLINE InetAddress &asInetAddress(ZT_InetAddress &p) noexcept { return *reinterpret_cast<InetAddress *>(&p); }
static ZT_INLINE const InetAddress &asInetAddress(const sockaddr_in &p) noexcept
{
return *reinterpret_cast<InetAddress*>(&p);
return *reinterpret_cast<const InetAddress *>(&p);
}
static ZT_INLINE InetAddress& asInetAddress(sockaddr_in6& p) noexcept
static ZT_INLINE const InetAddress &asInetAddress(const sockaddr_in6 &p) noexcept
{
return *reinterpret_cast<InetAddress*>(&p);
return *reinterpret_cast<const InetAddress *>(&p);
}
static ZT_INLINE InetAddress& asInetAddress(sockaddr& p) noexcept
static ZT_INLINE const InetAddress &asInetAddress(const sockaddr &p) noexcept
{
return *reinterpret_cast<InetAddress*>(&p);
return *reinterpret_cast<const InetAddress *>(&p);
}
static ZT_INLINE InetAddress& asInetAddress(sockaddr_storage& p) noexcept
static ZT_INLINE const InetAddress &asInetAddress(const sockaddr_storage &p) noexcept
{
return *reinterpret_cast<InetAddress*>(&p);
return *reinterpret_cast<const InetAddress *>(&p);
}
static ZT_INLINE InetAddress& asInetAddress(ZT_InetAddress& p) noexcept
static ZT_INLINE const InetAddress &asInetAddress(const ZT_InetAddress &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);
}
static ZT_INLINE const InetAddress& asInetAddress(const ZT_InetAddress& p) noexcept
{
return *reinterpret_cast<const InetAddress*>(&p);
return *reinterpret_cast<const InetAddress *>(&p);
}
} // namespace ZeroTier

View file

@ -64,7 +64,7 @@ namespace {
typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */
FORCE_INLINE void LZ4_resetStream(LZ4_stream_t* streamPtr);
FORCE_INLINE void LZ4_resetStream(LZ4_stream_t *streamPtr);
#define LZ4_HASHLOG (LZ4_MEMORY_USAGE - 2)
#define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */
@ -73,15 +73,15 @@ typedef struct {
uint32_t hashTable[LZ4_HASH_SIZE_U32];
uint32_t currentOffset;
uint32_t initCheck;
const uint8_t* dictionary;
uint8_t* bufferStart; /* obsolete, used for slideInputBuffer */
const uint8_t *dictionary;
uint8_t *bufferStart; /* obsolete, used for slideInputBuffer */
uint32_t dictSize;
} LZ4_stream_t_internal;
typedef struct {
const uint8_t* externalDict;
const uint8_t *externalDict;
size_t extDictSize;
const uint8_t* prefixEnd;
const uint8_t *prefixEnd;
size_t prefixSize;
} LZ4_streamDecode_t_internal;
@ -129,30 +129,15 @@ typedef uintptr_t reg_t;
#endif
#if defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS == 2)
FORCE_INLINE U16 LZ4_read16(const void* memPtr)
{
return *(const U16*)memPtr;
}
FORCE_INLINE U16 LZ4_read16(const void *memPtr) { return *(const U16 *)memPtr; }
FORCE_INLINE U32 LZ4_read32(const void* memPtr)
{
return *(const U32*)memPtr;
}
FORCE_INLINE U32 LZ4_read32(const void *memPtr) { return *(const U32 *)memPtr; }
FORCE_INLINE reg_t LZ4_read_ARCH(const void* memPtr)
{
return *(const reg_t*)memPtr;
}
FORCE_INLINE reg_t LZ4_read_ARCH(const void *memPtr) { return *(const reg_t *)memPtr; }
FORCE_INLINE void LZ4_write16(void* memPtr, U16 value)
{
*(U16*)memPtr = value;
}
FORCE_INLINE void LZ4_write16(void *memPtr, U16 value) { *(U16 *)memPtr = value; }
FORCE_INLINE void LZ4_write32(void* memPtr, U32 value)
{
*(U32*)memPtr = value;
}
FORCE_INLINE void LZ4_write32(void *memPtr, U32 value) { *(U32 *)memPtr = value; }
#elif defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS == 1)
typedef union {
@ -160,88 +145,64 @@ typedef union {
U32 u32;
reg_t uArch;
} __attribute__((packed)) unalign;
FORCE_INLINE U16 LZ4_read16(const void* ptr)
{
return ((const unalign*)ptr)->u16;
}
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;
}
FORCE_INLINE U16 LZ4_read16(const void *ptr) { return ((const unalign *)ptr)->u16; }
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 */
FORCE_INLINE U16 LZ4_read16(const void* memPtr)
FORCE_INLINE U16 LZ4_read16(const void *memPtr)
{
U16 val;
Utils::copy(&val, memPtr, sizeof(val));
return val;
}
FORCE_INLINE U32 LZ4_read32(const void* memPtr)
FORCE_INLINE U32 LZ4_read32(const void *memPtr)
{
U32 val;
Utils::copy(&val, memPtr, sizeof(val));
return val;
}
FORCE_INLINE reg_t LZ4_read_ARCH(const void* memPtr)
FORCE_INLINE reg_t LZ4_read_ARCH(const void *memPtr)
{
reg_t val;
Utils::copy(&val, memPtr, sizeof(val));
return val;
}
FORCE_INLINE void LZ4_write16(void* memPtr, U16 value)
{
Utils::copy(memPtr, &value, sizeof(value));
}
FORCE_INLINE void LZ4_write32(void* memPtr, U32 value)
{
Utils::copy(memPtr, &value, sizeof(value));
}
FORCE_INLINE void LZ4_write16(void *memPtr, U16 value) { Utils::copy(memPtr, &value, sizeof(value)); }
FORCE_INLINE void LZ4_write32(void *memPtr, U32 value) { Utils::copy(memPtr, &value, sizeof(value)); }
#endif /* LZ4_FORCE_MEMORY_ACCESS */
FORCE_INLINE U16 LZ4_readLE16(const void* memPtr)
FORCE_INLINE U16 LZ4_readLE16(const void *memPtr)
{
if (LZ4_isLittleEndian()) {
return LZ4_read16(memPtr);
}
else {
const BYTE* p = (const BYTE*)memPtr;
const BYTE *p = (const BYTE *)memPtr;
return (U16)((U16)p[0] + (p[1] << 8));
}
}
FORCE_INLINE void LZ4_writeLE16(void* memPtr, U16 value)
FORCE_INLINE void LZ4_writeLE16(void *memPtr, U16 value)
{
if (LZ4_isLittleEndian()) {
LZ4_write16(memPtr, value);
}
else {
BYTE* p = (BYTE*)memPtr;
p[0] = (BYTE)value;
p[1] = (BYTE)(value >> 8);
BYTE *p = (BYTE *)memPtr;
p[0] = (BYTE)value;
p[1] = (BYTE)(value >> 8);
}
}
FORCE_INLINE void LZ4_copy8(void* dst, const void* src)
{
Utils::copy<8>(dst, src);
}
FORCE_INLINE void LZ4_copy8(void *dst, const void *src) { Utils::copy<8>(dst, src); }
FORCE_INLINE void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd)
FORCE_INLINE void LZ4_wildCopy(void *dstPtr, const void *srcPtr, void *dstEnd)
{
BYTE* d = (BYTE*)dstPtr;
const BYTE* s = (const BYTE*)srcPtr;
BYTE* const e = (BYTE*)dstEnd;
BYTE *d = (BYTE *)dstPtr;
const BYTE *s = (const BYTE *)srcPtr;
BYTE *const e = (BYTE *)dstEnd;
do {
LZ4_copy8(d, s);
d += 8;
@ -275,69 +236,71 @@ FORCE_INLINE unsigned LZ4_NbCommonBytes(reg_t val)
{
if (LZ4_isLittleEndian()) {
if (sizeof(val) == 8) {
#if defined(_MSC_VER) && defined(_WIN64) && ! defined(LZ4_FORCE_SW_BITCOUNT)
#if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT)
unsigned long r = 0;
_BitScanForward64(&r, (U64)val);
return (int)(r >> 3);
#elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 3))) && ! defined(LZ4_FORCE_SW_BITCOUNT)
#elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
return (__builtin_ctzll((U64)val) >> 3);
#else
static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7,
7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5,
3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5,
3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
#endif
}
else /* 32 bits */ {
#if defined(_MSC_VER) && ! defined(LZ4_FORCE_SW_BITCOUNT)
#if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
unsigned long r;
_BitScanForward(&r, (U32)val);
return (int)(r >> 3);
#elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 3))) && ! defined(LZ4_FORCE_SW_BITCOUNT)
#elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
return (__builtin_ctz((U32)val) >> 3);
#else
static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1,
3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
#endif
}
}
else /* Big Endian CPU */ {
if (sizeof(val) == 8) {
#if defined(_MSC_VER) && defined(_WIN64) && ! defined(LZ4_FORCE_SW_BITCOUNT)
#if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT)
unsigned long r = 0;
_BitScanReverse64(&r, val);
return (unsigned)(r >> 3);
#elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 3))) && ! defined(LZ4_FORCE_SW_BITCOUNT)
#elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
return (__builtin_clzll((U64)val) >> 3);
#else
unsigned r;
if (! (val >> 32)) {
if (!(val >> 32)) {
r = 4;
}
else {
r = 0;
val >>= 32;
}
if (! (val >> 16)) {
if (!(val >> 16)) {
r += 2;
val >>= 8;
}
else {
val >>= 24;
}
r += (! val);
r += (!val);
return r;
#endif
}
else /* 32 bits */ {
#if defined(_MSC_VER) && ! defined(LZ4_FORCE_SW_BITCOUNT)
#if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
unsigned long r = 0;
_BitScanReverse(&r, (unsigned long)val);
return (unsigned)(r >> 3);
#elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 3))) && ! defined(LZ4_FORCE_SW_BITCOUNT)
#elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
return (__builtin_clz((U32)val) >> 3);
#else
unsigned r;
if (! (val >> 16)) {
if (!(val >> 16)) {
r = 2;
val >>= 8;
}
@ -345,7 +308,7 @@ FORCE_INLINE unsigned LZ4_NbCommonBytes(reg_t val)
r = 0;
val >>= 24;
}
r += (! val);
r += (!val);
return r;
#endif
}
@ -353,13 +316,13 @@ FORCE_INLINE unsigned LZ4_NbCommonBytes(reg_t val)
}
#define STEPSIZE sizeof(reg_t)
FORCE_INLINE unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit)
FORCE_INLINE unsigned LZ4_count(const BYTE *pIn, const BYTE *pMatch, const BYTE *pInLimit)
{
const BYTE* const pStart = pIn;
const BYTE *const pStart = pIn;
while (likely(pIn < pInLimit - (STEPSIZE - 1))) {
reg_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn);
if (! diff) {
if (!diff) {
pIn += STEPSIZE;
pMatch += STEPSIZE;
continue;
@ -381,7 +344,7 @@ FORCE_INLINE unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE*
return (unsigned)(pIn - pStart);
}
static const int LZ4_64Klimit = ((64 KB) + (MFLIMIT - 1));
static const int LZ4_64Klimit = ((64 KB) + (MFLIMIT - 1));
static const U32 LZ4_skipTrigger = 6; /* Increase this value ==> compression run slower on incompressible data */
typedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive;
@ -393,10 +356,7 @@ typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive;
typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive;
typedef enum { full = 0, partial = 1 } earlyEnd_directive;
FORCE_INLINE int LZ4_compressBound(int isize)
{
return LZ4_COMPRESSBOUND(isize);
}
FORCE_INLINE int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); }
FORCE_INLINE U32 LZ4_hash4(U32 sequence, tableType_t const tableType)
{
@ -410,95 +370,89 @@ FORCE_INLINE U32 LZ4_hash5(U64 sequence, tableType_t const tableType)
{
static const U64 prime5bytes = 889523592379ULL;
static const U64 prime8bytes = 11400714785074694791ULL;
const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG + 1 : LZ4_HASHLOG;
const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG + 1 : LZ4_HASHLOG;
if (LZ4_isLittleEndian())
return (U32)(((sequence << 24) * prime5bytes) >> (64 - hashLog));
else
return (U32)(((sequence >> 24) * prime8bytes) >> (64 - hashLog));
}
FORCE_INLINE U32 LZ4_hashPosition(const void* const p, tableType_t const tableType)
FORCE_INLINE U32 LZ4_hashPosition(const void *const p, tableType_t const tableType)
{
if ((sizeof(reg_t) == 8) && (tableType != byU16))
return LZ4_hash5(LZ4_read_ARCH(p), tableType);
return LZ4_hash4(LZ4_read32(p), tableType);
}
FORCE_INLINE void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t const tableType, const BYTE* srcBase)
FORCE_INLINE void
LZ4_putPositionOnHash(const BYTE *p, U32 h, void *tableBase, tableType_t const tableType, const BYTE *srcBase)
{
switch (tableType) {
case byPtr: {
const BYTE** hashTable = (const BYTE**)tableBase;
hashTable[h] = p;
const BYTE **hashTable = (const BYTE **)tableBase;
hashTable[h] = p;
return;
}
case byU32: {
U32* hashTable = (U32*)tableBase;
hashTable[h] = (U32)(p - srcBase);
U32 *hashTable = (U32 *)tableBase;
hashTable[h] = (U32)(p - srcBase);
return;
}
case byU16: {
U16* hashTable = (U16*)tableBase;
hashTable[h] = (U16)(p - srcBase);
U16 *hashTable = (U16 *)tableBase;
hashTable[h] = (U16)(p - srcBase);
return;
}
}
}
FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase)
FORCE_INLINE void LZ4_putPosition(const BYTE *p, void *tableBase, tableType_t tableType, const BYTE *srcBase)
{
U32 const h = LZ4_hashPosition(p, tableType);
LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase);
}
FORCE_INLINE const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase)
FORCE_INLINE const BYTE *LZ4_getPositionOnHash(U32 h, void *tableBase, tableType_t tableType, const BYTE *srcBase)
{
if (tableType == byPtr) {
const BYTE** hashTable = (const BYTE**)tableBase;
const BYTE **hashTable = (const BYTE **)tableBase;
return hashTable[h];
}
if (tableType == byU32) {
const U32* const hashTable = (U32*)tableBase;
const U32 *const hashTable = (U32 *)tableBase;
return hashTable[h] + srcBase;
}
{
const U16* const hashTable = (U16*)tableBase;
const U16 *const hashTable = (U16 *)tableBase;
return hashTable[h] + srcBase;
} /* default, to ensure a return */
}
FORCE_INLINE const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase)
FORCE_INLINE const BYTE *LZ4_getPosition(const BYTE *p, void *tableBase, tableType_t tableType, const BYTE *srcBase)
{
U32 const h = LZ4_hashPosition(p, tableType);
return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase);
}
FORCE_INLINE int LZ4_compress_generic(
LZ4_stream_t_internal* const cctx,
const char* const source,
char* const dest,
const int inputSize,
const int maxOutputSize,
const limitedOutput_directive outputLimited,
const tableType_t tableType,
const dict_directive dict,
const dictIssue_directive dictIssue,
const U32 acceleration)
LZ4_stream_t_internal *const cctx, const char *const source, char *const dest, const int inputSize,
const int maxOutputSize, const limitedOutput_directive outputLimited, const tableType_t tableType,
const dict_directive dict, const dictIssue_directive dictIssue, const U32 acceleration)
{
const BYTE* ip = (const BYTE*)source;
const BYTE* base;
const BYTE* lowLimit;
const BYTE* const lowRefLimit = ip - cctx->dictSize;
const BYTE* const dictionary = cctx->dictionary;
const BYTE* const dictEnd = dictionary + cctx->dictSize;
const ptrdiff_t dictDelta = dictEnd - (const BYTE*)source;
const BYTE* anchor = (const BYTE*)source;
const BYTE* const iend = ip + inputSize;
const BYTE* const mflimit = iend - MFLIMIT;
const BYTE* const matchlimit = iend - LASTLITERALS;
const BYTE *ip = (const BYTE *)source;
const BYTE *base;
const BYTE *lowLimit;
const BYTE *const lowRefLimit = ip - cctx->dictSize;
const BYTE *const dictionary = cctx->dictionary;
const BYTE *const dictEnd = dictionary + cctx->dictSize;
const ptrdiff_t dictDelta = dictEnd - (const BYTE *)source;
const BYTE *anchor = (const BYTE *)source;
const BYTE *const iend = ip + inputSize;
const BYTE *const mflimit = iend - MFLIMIT;
const BYTE *const matchlimit = iend - LASTLITERALS;
BYTE* op = (BYTE*)dest;
BYTE* const olimit = op + maxOutputSize;
BYTE *op = (BYTE *)dest;
BYTE *const olimit = op + maxOutputSize;
U32 forwardH;
@ -508,16 +462,16 @@ FORCE_INLINE int LZ4_compress_generic(
switch (dict) {
case noDict:
default:
base = (const BYTE*)source;
lowLimit = (const BYTE*)source;
base = (const BYTE *)source;
lowLimit = (const BYTE *)source;
break;
case withPrefix64k:
base = (const BYTE*)source - cctx->currentOffset;
lowLimit = (const BYTE*)source - cctx->dictSize;
base = (const BYTE *)source - cctx->currentOffset;
lowLimit = (const BYTE *)source - cctx->dictSize;
break;
case usingExtDict:
base = (const BYTE*)source - cctx->currentOffset;
lowLimit = (const BYTE*)source;
base = (const BYTE *)source - cctx->currentOffset;
lowLimit = (const BYTE *)source;
break;
}
if ((tableType == byU16) && (inputSize >= LZ4_64Klimit))
@ -533,17 +487,17 @@ FORCE_INLINE int LZ4_compress_generic(
/* Main Loop */
for (;;) {
ptrdiff_t refDelta = 0;
const BYTE* match;
BYTE* token;
const BYTE *match;
BYTE *token;
/* Find a match */
{
const BYTE* forwardIp = ip;
unsigned step = 1;
const BYTE *forwardIp = ip;
unsigned step = 1;
unsigned searchMatchNb = acceleration << LZ4_skipTrigger;
do {
U32 const h = forwardH;
ip = forwardIp;
ip = forwardIp;
forwardIp += step;
step = (searchMatchNb++ >> LZ4_skipTrigger);
@ -552,19 +506,21 @@ FORCE_INLINE int LZ4_compress_generic(
match = LZ4_getPositionOnHash(h, cctx->hashTable, tableType, base);
if (dict == usingExtDict) {
if (match < (const BYTE*)source) {
if (match < (const BYTE *)source) {
refDelta = dictDelta;
lowLimit = dictionary;
}
else {
refDelta = 0;
lowLimit = (const BYTE*)source;
lowLimit = (const BYTE *)source;
}
}
forwardH = LZ4_hashPosition(forwardIp, tableType);
LZ4_putPositionOnHash(ip, h, cctx->hashTable, tableType, base);
} while (((dictIssue == dictSmall) ? (match < lowRefLimit) : 0) || ((tableType == byU16) ? 0 : (match + MAX_DISTANCE < ip)) || (LZ4_read32(match + refDelta) != LZ4_read32(ip)));
} while (((dictIssue == dictSmall) ? (match < lowRefLimit) : 0)
|| ((tableType == byU16) ? 0 : (match + MAX_DISTANCE < ip))
|| (LZ4_read32(match + refDelta) != LZ4_read32(ip)));
}
/* Catch up */
@ -576,13 +532,13 @@ FORCE_INLINE int LZ4_compress_generic(
/* Encode Literals */
{
unsigned const litLength = (unsigned)(ip - anchor);
token = op++;
token = op++;
if ((outputLimited) && /* Check output buffer overflow */
(unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength / 255) > olimit)))
return 0;
if (litLength >= RUN_MASK) {
int len = (int)litLength - RUN_MASK;
*token = (RUN_MASK << ML_BITS);
*token = (RUN_MASK << ML_BITS);
for (; len >= 255; len -= 255)
*op++ = 255;
*op++ = (BYTE)len;
@ -605,7 +561,7 @@ FORCE_INLINE int LZ4_compress_generic(
unsigned matchCode;
if ((dict == usingExtDict) && (lowLimit == dictionary)) {
const BYTE* limit;
const BYTE *limit;
match += refDelta;
limit = ip + (dictEnd - match);
if (limit > matchlimit)
@ -613,7 +569,7 @@ FORCE_INLINE int LZ4_compress_generic(
matchCode = LZ4_count(ip + MINMATCH, match + MINMATCH, limit);
ip += MINMATCH + matchCode;
if (ip == limit) {
unsigned const more = LZ4_count(ip, (const BYTE*)source, matchlimit);
unsigned const more = LZ4_count(ip, (const BYTE *)source, matchlimit);
matchCode += more;
ip += more;
}
@ -651,18 +607,19 @@ FORCE_INLINE int LZ4_compress_generic(
/* Test next position */
match = LZ4_getPosition(ip, cctx->hashTable, tableType, base);
if (dict == usingExtDict) {
if (match < (const BYTE*)source) {
if (match < (const BYTE *)source) {
refDelta = dictDelta;
lowLimit = dictionary;
}
else {
refDelta = 0;
lowLimit = (const BYTE*)source;
lowLimit = (const BYTE *)source;
}
}
LZ4_putPosition(ip, cctx->hashTable, tableType, base);
if (((dictIssue == dictSmall) ? (match >= lowRefLimit) : 1) && (match + MAX_DISTANCE >= ip) && (LZ4_read32(match + refDelta) == LZ4_read32(ip))) {
token = op++;
if (((dictIssue == dictSmall) ? (match >= lowRefLimit) : 1) && (match + MAX_DISTANCE >= ip)
&& (LZ4_read32(match + refDelta) == LZ4_read32(ip))) {
token = op++;
*token = 0;
goto _next_match;
}
@ -676,11 +633,11 @@ _last_literals:
{
size_t const lastRun = (size_t)(iend - anchor);
if ((outputLimited) && /* Check output buffer overflow */
((op - (BYTE*)dest) + lastRun + 1 + ((lastRun + 255 - RUN_MASK) / 255) > (U32)maxOutputSize))
((op - (BYTE *)dest) + lastRun + 1 + ((lastRun + 255 - RUN_MASK) / 255) > (U32)maxOutputSize))
return 0;
if (lastRun >= RUN_MASK) {
size_t accumulator = lastRun - RUN_MASK;
*op++ = RUN_MASK << ML_BITS;
*op++ = RUN_MASK << ML_BITS;
for (; accumulator >= 255; accumulator -= 255)
*op++ = 255;
*op++ = (BYTE)accumulator;
@ -693,64 +650,66 @@ _last_literals:
}
/* End */
return (int)(((char*)op) - dest);
return (int)(((char *)op) - dest);
}
ZT_INLINE int LZ4_compress_fast_extState(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
ZT_INLINE int LZ4_compress_fast_extState(
void *state, const char *source, char *dest, int inputSize, int maxOutputSize, int acceleration)
{
LZ4_stream_t_internal* ctx = &((LZ4_stream_t*)state)->internal_donotuse;
LZ4_resetStream((LZ4_stream_t*)state);
LZ4_stream_t_internal *ctx = &((LZ4_stream_t *)state)->internal_donotuse;
LZ4_resetStream((LZ4_stream_t *)state);
// if (acceleration < 1) acceleration = ACCELERATION_DEFAULT;
if (maxOutputSize >= LZ4_compressBound(inputSize)) {
if (inputSize < LZ4_64Klimit)
return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue, acceleration);
return LZ4_compress_generic(
ctx, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue, acceleration);
else
return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, (sizeof(void*) == 8) ? byU32 : byPtr, noDict, noDictIssue, acceleration);
return LZ4_compress_generic(
ctx, source, dest, inputSize, 0, notLimited, (sizeof(void *) == 8) ? byU32 : byPtr, noDict, noDictIssue,
acceleration);
}
else {
if (inputSize < LZ4_64Klimit)
return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration);
return LZ4_compress_generic(
ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration);
else
return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, (sizeof(void*) == 8) ? byU32 : byPtr, noDict, noDictIssue, acceleration);
return LZ4_compress_generic(
ctx, source, dest, inputSize, maxOutputSize, limitedOutput, (sizeof(void *) == 8) ? byU32 : byPtr,
noDict, noDictIssue, acceleration);
}
}
FORCE_INLINE void LZ4_resetStream(LZ4_stream_t* LZ4_stream)
{
Utils::zero<sizeof(LZ4_stream_t)>(LZ4_stream);
}
FORCE_INLINE void LZ4_resetStream(LZ4_stream_t *LZ4_stream) { Utils::zero<sizeof(LZ4_stream_t)>(LZ4_stream); }
FORCE_INLINE int LZ4_decompress_generic(
const char* const source,
char* const dest,
int inputSize,
const char *const source, char *const dest, int inputSize,
int outputSize, /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */
int endOnInput, /* endOnOutputSize, endOnInputSize */
int partialDecoding, /* full, partial */
int targetOutputSize, /* only used if partialDecoding==partial */
int dict, /* noDict, withPrefix64k, usingExtDict */
const BYTE* const lowPrefix, /* == dest when no prefix */
const BYTE* const dictStart, /* only if dict==usingExtDict */
const BYTE *const lowPrefix, /* == dest when no prefix */
const BYTE *const dictStart, /* only if dict==usingExtDict */
const size_t dictSize /* note : = 0 if noDict */
)
{
/* Local Variables */
const BYTE* ip = (const BYTE*)source;
const BYTE* const iend = ip + inputSize;
const BYTE *ip = (const BYTE *)source;
const BYTE *const iend = ip + inputSize;
BYTE* op = (BYTE*)dest;
BYTE* const oend = op + outputSize;
BYTE* cpy;
BYTE* oexit = op + targetOutputSize;
const BYTE* const lowLimit = lowPrefix - dictSize;
BYTE *op = (BYTE *)dest;
BYTE *const oend = op + outputSize;
BYTE *cpy;
BYTE *oexit = op + targetOutputSize;
const BYTE *const lowLimit = lowPrefix - dictSize;
const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize;
const BYTE *const dictEnd = (const BYTE *)dictStart + dictSize;
const unsigned dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 };
const int dec64table[] = { 0, 0, 0, -1, 0, 1, 2, 3 };
const int dec64table[] = { 0, 0, 0, -1, 0, 1, 2, 3 };
const int safeDecode = (endOnInput == endOnInputSize);
const int safeDecode = (endOnInput == endOnInputSize);
const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB)));
/* Special cases */
@ -758,13 +717,13 @@ FORCE_INLINE int LZ4_decompress_generic(
oexit = oend - MFLIMIT; /* targetOutputSize too high => decode everything */
if ((endOnInput) && (unlikely(outputSize == 0)))
return ((inputSize == 1) && (*ip == 0)) ? 0 : -1; /* Empty output buffer */
if ((! endOnInput) && (unlikely(outputSize == 0)))
if ((!endOnInput) && (unlikely(outputSize == 0)))
return (*ip == 0 ? 1 : -1);
/* Main Loop : decode sequences */
while (1) {
size_t length;
const BYTE* match;
const BYTE *match;
size_t offset;
/* get literal length */
@ -783,7 +742,9 @@ FORCE_INLINE int LZ4_decompress_generic(
/* copy literals */
cpy = op + length;
if (((endOnInput) && ((cpy > (partialDecoding ? oexit : oend - MFLIMIT)) || (ip + length > iend - (2 + 1 + LASTLITERALS)))) || ((! endOnInput) && (cpy > oend - WILDCOPYLENGTH))) {
if (((endOnInput)
&& ((cpy > (partialDecoding ? oexit : oend - MFLIMIT)) || (ip + length > iend - (2 + 1 + LASTLITERALS))))
|| ((!endOnInput) && (cpy > oend - WILDCOPYLENGTH))) {
if (partialDecoding) {
if (cpy > oend)
goto _output_error; /* Error : write attempt beyond end of output buffer */
@ -791,7 +752,7 @@ FORCE_INLINE int LZ4_decompress_generic(
goto _output_error; /* Error : read attempt beyond end of input buffer */
}
else {
if ((! endOnInput) && (cpy != oend))
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 */
@ -845,8 +806,8 @@ FORCE_INLINE int LZ4_decompress_generic(
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;
BYTE *const endOfMatch = op + restSize;
const BYTE *copyFrom = lowPrefix;
while (op < endOfMatch)
*op++ = *copyFrom++;
}
@ -862,10 +823,10 @@ FORCE_INLINE int LZ4_decompress_generic(
cpy = op + length;
if (unlikely(offset < 8)) {
const int dec64 = dec64table[offset];
op[0] = match[0];
op[1] = match[1];
op[2] = match[2];
op[3] = match[3];
op[0] = match[0];
op[1] = match[1];
op[2] = match[2];
op[3] = match[3];
match += dec32table[offset];
Utils::copy<4>(op + 4, match);
match -= dec64;
@ -877,7 +838,7 @@ FORCE_INLINE int LZ4_decompress_generic(
op += 8;
if (unlikely(cpy > oend - 12)) {
BYTE* const oCopyLimit = oend - (WILDCOPYLENGTH - 1);
BYTE *const oCopyLimit = oend - (WILDCOPYLENGTH - 1);
if (cpy > oend - LASTLITERALS)
goto _output_error; /* Error : last LASTLITERALS bytes must be literals (uncompressed) */
if (op < oCopyLimit) {
@ -898,24 +859,24 @@ FORCE_INLINE int LZ4_decompress_generic(
/* end of decoding */
if (endOnInput)
return (int)(((char*)op) - dest); /* Nb of output bytes decoded */
return (int)(((char *)op) - dest); /* Nb of output bytes decoded */
else
return (int)(((const char*)ip) - source); /* Nb of input bytes read */
return (int)(((const char *)ip) - source); /* Nb of input bytes read */
/* Overflow error detected */
_output_error:
return (int)(-(((const char*)ip) - source)) - 1;
return (int)(-(((const char *)ip) - source)) - 1;
}
} // anonymous namespace
int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) noexcept
int LZ4_compress_fast(const char *source, char *dest, int inputSize, int maxOutputSize, int acceleration) noexcept
{
#if (HEAPMODE)
void* ctxPtr = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */
void *ctxPtr = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */
#else
LZ4_stream_t ctx;
void* const ctxPtr = &ctx;
void *const ctxPtr = &ctx;
#endif
int const result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration);
@ -926,9 +887,10 @@ int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutp
return result;
}
int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxDecompressedSize) noexcept
int LZ4_decompress_safe(const char *source, char *dest, int compressedSize, int maxDecompressedSize) noexcept
{
return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endOnInputSize, full, 0, noDict, (BYTE*)dest, NULL, 0);
return LZ4_decompress_generic(
source, dest, compressedSize, maxDecompressedSize, endOnInputSize, full, 0, noDict, (BYTE *)dest, NULL, 0);
}
} // namespace ZeroTier

View file

@ -21,8 +21,8 @@ namespace ZeroTier {
#define LZ4_MAX_INPUT_SIZE 0x7E000000
#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize) / 255) + 16)
int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration = 1) noexcept;
int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxDecompressedSize) noexcept;
int LZ4_compress_fast(const char *source, char *dest, int inputSize, int maxOutputSize, int acceleration = 1) noexcept;
int LZ4_decompress_safe(const char *source, char *dest, int compressedSize, int maxDecompressedSize) noexcept;
} // namespace ZeroTier

View file

@ -19,11 +19,12 @@
namespace ZeroTier {
const SharedPtr<const Locator::EndpointAttributes> Locator::EndpointAttributes::DEFAULT(new Locator::EndpointAttributes());
const SharedPtr<const Locator::EndpointAttributes>
Locator::EndpointAttributes::DEFAULT(new Locator::EndpointAttributes());
Locator::Locator(const char* const str) noexcept : __refCount(0)
Locator::Locator(const char *const str) noexcept : __refCount(0)
{
if (! fromString(str)) {
if (!fromString(str)) {
m_revision = 0;
m_signer.zero();
m_endpoints.clear();
@ -31,25 +32,27 @@ Locator::Locator(const char* const str) noexcept : __refCount(0)
}
}
bool Locator::add(const Endpoint& ep, const SharedPtr<const EndpointAttributes>& a)
bool Locator::add(const Endpoint &ep, const SharedPtr<const EndpointAttributes> &a)
{
for (Vector<std::pair<Endpoint, SharedPtr<const EndpointAttributes> > >::iterator i(m_endpoints.begin()); i != m_endpoints.end(); ++i) {
for (Vector<std::pair<Endpoint, SharedPtr<const EndpointAttributes>>>::iterator i(m_endpoints.begin());
i != m_endpoints.end(); ++i) {
if (i->first == ep) {
i->second = ((a) && (a->data[0] != 0)) ? a : EndpointAttributes::DEFAULT;
return true;
}
}
if (m_endpoints.size() < ZT_LOCATOR_MAX_ENDPOINTS) {
m_endpoints.push_back(std::pair<Endpoint, SharedPtr<const EndpointAttributes> >(ep, ((a) && (a->data[0] != 0)) ? a : EndpointAttributes::DEFAULT));
m_endpoints.push_back(std::pair<Endpoint, SharedPtr<const EndpointAttributes>>(
ep, ((a) && (a->data[0] != 0)) ? a : EndpointAttributes::DEFAULT));
return true;
}
return false;
}
bool Locator::sign(const int64_t rev, const Identity& id) noexcept
bool Locator::sign(const int64_t rev, const Identity &id) noexcept
{
m_revision = rev;
m_signer = id.address();
m_signer = id.address();
m_sortEndpoints();
@ -64,7 +67,7 @@ bool Locator::sign(const int64_t rev, const Identity& id) noexcept
return true;
}
bool Locator::verify(const Identity& id) const noexcept
bool Locator::verify(const Identity &id) const noexcept
{
try {
if ((m_revision > 0) && (m_signer == id.address())) {
@ -78,19 +81,23 @@ bool Locator::verify(const Identity& id) const noexcept
return false;
}
char* Locator::toString(char s[ZT_LOCATOR_STRING_SIZE_MAX]) const noexcept
char *Locator::toString(char s[ZT_LOCATOR_STRING_SIZE_MAX]) const noexcept
{
static_assert(ZT_LOCATOR_STRING_SIZE_MAX > ((((ZT_LOCATOR_MARSHAL_SIZE_MAX / 5) + 1) * 8) + ZT_ADDRESS_LENGTH_HEX + 1), "overflow");
static_assert(
ZT_LOCATOR_STRING_SIZE_MAX > ((((ZT_LOCATOR_MARSHAL_SIZE_MAX / 5) + 1) * 8) + ZT_ADDRESS_LENGTH_HEX + 1),
"overflow");
uint8_t bin[ZT_LOCATOR_MARSHAL_SIZE_MAX];
m_signer.toString(s);
s[ZT_ADDRESS_LENGTH_HEX] = '@';
Utils::b32e(bin, marshal(bin, false), s + (ZT_ADDRESS_LENGTH_HEX + 1), ZT_LOCATOR_STRING_SIZE_MAX - (ZT_ADDRESS_LENGTH_HEX + 1));
Utils::b32e(
bin, marshal(bin, false), s + (ZT_ADDRESS_LENGTH_HEX + 1),
ZT_LOCATOR_STRING_SIZE_MAX - (ZT_ADDRESS_LENGTH_HEX + 1));
return s;
}
bool Locator::fromString(const char* s) noexcept
bool Locator::fromString(const char *s) noexcept
{
if (! s)
if (!s)
return false;
if (strlen(s) < (ZT_ADDRESS_LENGTH_HEX + 1))
return false;
@ -109,7 +116,8 @@ int Locator::marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX], const bool exclu
Utils::storeBigEndian<uint16_t>(data + p, (uint16_t)m_endpoints.size());
p += 2;
for (Vector<std::pair<Endpoint, SharedPtr<const EndpointAttributes> > >::const_iterator e(m_endpoints.begin()); e != m_endpoints.end(); ++e) {
for (Vector<std::pair<Endpoint, SharedPtr<const EndpointAttributes>>>::const_iterator e(m_endpoints.begin());
e != m_endpoints.end(); ++e) {
int l = e->first.marshal(data + p);
if (l <= 0)
return -1;
@ -128,7 +136,7 @@ int Locator::marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX], const bool exclu
Utils::storeMachineEndian<uint16_t>(data + p, 0); // length of meta-data, currently always 0
p += 2;
if (! excludeSignature) {
if (!excludeSignature) {
Utils::storeBigEndian<uint16_t>(data + p, (uint16_t)m_signature.size());
p += 2;
Utils::copy(data + p, m_signature.data(), m_signature.size());
@ -138,7 +146,7 @@ int Locator::marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX], const bool exclu
return p;
}
int Locator::unmarshal(const uint8_t* data, const int len) noexcept
int Locator::unmarshal(const uint8_t *data, const int len) noexcept
{
if (unlikely(len < (8 + ZT_ADDRESS_LENGTH)))
return -1;
@ -169,7 +177,7 @@ int Locator::unmarshal(const uint8_t* data, const int len) noexcept
}
else {
m_endpoints[i].second.set(new EndpointAttributes());
Utils::copy(const_cast<uint8_t*>(m_endpoints[i].second->data), data + p, (unsigned int)l);
Utils::copy(const_cast<uint8_t *>(m_endpoints[i].second->data), data + p, (unsigned int)l);
p += l;
}
}
@ -198,15 +206,14 @@ int Locator::unmarshal(const uint8_t* data, const int len) noexcept
struct p_SortByEndpoint {
// There can't be more than one of the same endpoint, so only need to sort
// by endpoint.
ZT_INLINE bool operator()(const std::pair<Endpoint, SharedPtr<const Locator::EndpointAttributes> >& a, const std::pair<Endpoint, SharedPtr<const Locator::EndpointAttributes> >& b) const noexcept
ZT_INLINE bool operator()(
const std::pair<Endpoint, SharedPtr<const Locator::EndpointAttributes>> &a,
const std::pair<Endpoint, SharedPtr<const Locator::EndpointAttributes>> &b) const noexcept
{
return a.first < b.first;
}
};
void Locator::m_sortEndpoints() noexcept
{
std::sort(m_endpoints.begin(), m_endpoints.end(), p_SortByEndpoint());
}
void Locator::m_sortEndpoints() noexcept { std::sort(m_endpoints.begin(), m_endpoints.end(), p_SortByEndpoint()); }
} // namespace ZeroTier

View file

@ -35,7 +35,10 @@
*/
#define ZT_LOCATOR_MAX_ENDPOINTS 16
#define ZT_LOCATOR_MARSHAL_SIZE_MAX (8 + ZT_ADDRESS_LENGTH + 2 + (ZT_LOCATOR_MAX_ENDPOINTS * (ZT_ENDPOINT_MARSHAL_SIZE_MAX + ZT_LOCATOR_MAX_ENDPOINT_ATTRIBUTES_SIZE)) + 2 + 2 + ZT_SIGNATURE_BUFFER_SIZE)
#define ZT_LOCATOR_MARSHAL_SIZE_MAX \
(8 + ZT_ADDRESS_LENGTH + 2 \
+ (ZT_LOCATOR_MAX_ENDPOINTS * (ZT_ENDPOINT_MARSHAL_SIZE_MAX + ZT_LOCATOR_MAX_ENDPOINT_ATTRIBUTES_SIZE)) + 2 + 2 \
+ ZT_SIGNATURE_BUFFER_SIZE)
/**
* Maximum size of a string format Locator (this is way larger than needed)
@ -78,50 +81,33 @@ class Locator {
*/
uint8_t data[ZT_LOCATOR_MAX_ENDPOINT_ATTRIBUTES_SIZE];
ZT_INLINE EndpointAttributes() noexcept
{
Utils::zero<ZT_LOCATOR_MAX_ENDPOINT_ATTRIBUTES_SIZE>(data);
}
ZT_INLINE EndpointAttributes() noexcept { Utils::zero<ZT_LOCATOR_MAX_ENDPOINT_ATTRIBUTES_SIZE>(data); }
ZT_INLINE bool operator==(const EndpointAttributes& a) const noexcept
ZT_INLINE bool operator==(const EndpointAttributes &a) const noexcept
{
return ((data[0] == a.data[0]) && (memcmp(data, a.data, data[0]) == 0));
}
ZT_INLINE bool operator<(const EndpointAttributes& a) const noexcept
ZT_INLINE bool operator<(const EndpointAttributes &a) const noexcept
{
return ((data[0] < a.data[0]) || ((data[0] == a.data[0]) && (memcmp(data, a.data, data[0]) < 0)));
}
ZT_INLINE bool operator!=(const EndpointAttributes& a) const noexcept
{
return ! (*this == a);
}
ZT_INLINE bool operator!=(const EndpointAttributes &a) const noexcept { return !(*this == a); }
ZT_INLINE bool operator>(const EndpointAttributes& a) const noexcept
{
return (a < *this);
}
ZT_INLINE bool operator>(const EndpointAttributes &a) const noexcept { return (a < *this); }
ZT_INLINE bool operator<=(const EndpointAttributes& a) const noexcept
{
return ! (a < *this);
}
ZT_INLINE bool operator<=(const EndpointAttributes &a) const noexcept { return !(a < *this); }
ZT_INLINE bool operator>=(const EndpointAttributes& a) const noexcept
{
return ! (*this < a);
}
ZT_INLINE bool operator>=(const EndpointAttributes &a) const noexcept { return !(*this < a); }
private:
std::atomic<int> __refCount;
};
ZT_INLINE Locator() noexcept : m_revision(0)
{
}
ZT_INLINE Locator() noexcept : m_revision(0) {}
ZT_INLINE Locator(const Locator& l) noexcept
ZT_INLINE Locator(const Locator &l) noexcept
: m_revision(l.m_revision)
, m_signer(l.m_signer)
, m_endpoints(l.m_endpoints)
@ -130,28 +116,22 @@ class Locator {
{
}
explicit Locator(const char* const str) noexcept;
explicit Locator(const char *const str) noexcept;
/**
* @return Timestamp (a.k.a. revision number) set by Location signer
*/
ZT_INLINE int64_t revision() const noexcept
{
return m_revision;
}
ZT_INLINE int64_t revision() const noexcept { return m_revision; }
/**
* @return ZeroTier address of signer
*/
ZT_INLINE Address signer() const noexcept
{
return m_signer;
}
ZT_INLINE Address signer() const noexcept { return m_signer; }
/**
* @return Endpoints specified in locator
*/
ZT_INLINE const Vector<std::pair<Endpoint, SharedPtr<const EndpointAttributes> > >& endpoints() const noexcept
ZT_INLINE const Vector<std::pair<Endpoint, SharedPtr<const EndpointAttributes>>> &endpoints() const noexcept
{
return m_endpoints;
}
@ -159,10 +139,7 @@ class Locator {
/**
* @return Signature data
*/
ZT_INLINE const FCV<uint8_t, ZT_SIGNATURE_BUFFER_SIZE>& signature() const noexcept
{
return m_signature;
}
ZT_INLINE const FCV<uint8_t, ZT_SIGNATURE_BUFFER_SIZE> &signature() const noexcept { return m_signature; }
/**
* Add an endpoint to this locator
@ -174,7 +151,7 @@ class Locator {
* @param a Endpoint attributes or NULL to use default
* @return True if endpoint was added (or already present), false if locator is full
*/
bool add(const Endpoint& ep, const SharedPtr<const EndpointAttributes>& a);
bool add(const Endpoint &ep, const SharedPtr<const EndpointAttributes> &a);
/**
* Sign this locator
@ -185,7 +162,7 @@ class Locator {
* @param id Identity that includes private key
* @return True if signature successful
*/
bool sign(int64_t rev, const Identity& id) noexcept;
bool sign(int64_t rev, const Identity &id) noexcept;
/**
* Verify this Locator's validity and signature
@ -193,7 +170,7 @@ class Locator {
* @param id Identity corresponding to hash
* @return True if valid and signature checks out
*/
bool verify(const Identity& id) const noexcept;
bool verify(const Identity &id) const noexcept;
/**
* Convert this locator to a string
@ -201,7 +178,7 @@ class Locator {
* @param s String buffer
* @return Pointer to buffer
*/
char* toString(char s[ZT_LOCATOR_STRING_SIZE_MAX]) const noexcept;
char *toString(char s[ZT_LOCATOR_STRING_SIZE_MAX]) const noexcept;
ZT_INLINE String toString() const
{
@ -215,34 +192,29 @@ class Locator {
* @param s Locator from toString()
* @return True if format was valid
*/
bool fromString(const char* s) noexcept;
bool fromString(const char *s) noexcept;
explicit ZT_INLINE operator bool() const noexcept
{
return m_revision > 0;
}
explicit ZT_INLINE operator bool() const noexcept { return m_revision > 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 unmarshal(const uint8_t* data, int len) noexcept;
int unmarshal(const uint8_t *data, int len) noexcept;
ZT_INLINE bool operator==(const Locator& l) const noexcept
ZT_INLINE bool operator==(const Locator &l) const noexcept
{
const unsigned long es = (unsigned long)m_endpoints.size();
if ((m_revision == l.m_revision) && (m_signer == l.m_signer) && (es == (unsigned long)l.m_endpoints.size()) && (m_signature == l.m_signature)) {
if ((m_revision == l.m_revision) && (m_signer == l.m_signer) && (es == (unsigned long)l.m_endpoints.size())
&& (m_signature == l.m_signature)) {
for (unsigned long i = 0; i < es; ++i) {
if (m_endpoints[i].first != l.m_endpoints[i].first)
return false;
if (! m_endpoints[i].second) {
if (!m_endpoints[i].second) {
if (l.m_endpoints[i].second)
return false;
}
else {
if ((! l.m_endpoints[i].second) || (*(m_endpoints[i].second) != *(l.m_endpoints[i].second)))
if ((!l.m_endpoints[i].second) || (*(m_endpoints[i].second) != *(l.m_endpoints[i].second)))
return false;
}
}
@ -251,17 +223,14 @@ class Locator {
return false;
}
ZT_INLINE bool operator!=(const Locator& l) const noexcept
{
return ! (*this == l);
}
ZT_INLINE bool operator!=(const Locator &l) const noexcept { return !(*this == l); }
private:
void m_sortEndpoints() noexcept;
int64_t m_revision;
Address m_signer;
Vector<std::pair<Endpoint, SharedPtr<const EndpointAttributes> > > m_endpoints;
Vector<std::pair<Endpoint, SharedPtr<const EndpointAttributes>>> m_endpoints;
FCV<uint8_t, ZT_SIGNATURE_BUFFER_SIZE> m_signature;
std::atomic<int> __refCount;
};

View file

@ -27,44 +27,31 @@ namespace ZeroTier {
*/
class MAC : public TriviallyCopyable {
public:
ZT_INLINE MAC() noexcept : m_mac(0ULL)
ZT_INLINE MAC() noexcept : m_mac(0ULL) {}
ZT_INLINE
MAC(const uint8_t a, const uint8_t b, const uint8_t c, const uint8_t d, const uint8_t e, const uint8_t f) noexcept
: m_mac(
(((uint64_t)a) << 40U) | (((uint64_t)b) << 32U) | (((uint64_t)c) << 24U) | (((uint64_t)d) << 16U)
| (((uint64_t)e) << 8U) | ((uint64_t)f))
{
}
ZT_INLINE MAC(const uint8_t a, const uint8_t b, const uint8_t c, const uint8_t d, const uint8_t e, const uint8_t f) noexcept
: m_mac((((uint64_t)a) << 40U) | (((uint64_t)b) << 32U) | (((uint64_t)c) << 24U) | (((uint64_t)d) << 16U) | (((uint64_t)e) << 8U) | ((uint64_t)f))
{
}
explicit ZT_INLINE MAC(const uint64_t m) noexcept : m_mac(m) {}
explicit ZT_INLINE MAC(const uint64_t m) noexcept : m_mac(m)
{
}
explicit ZT_INLINE MAC(const uint8_t b[6]) noexcept { setTo(b); }
explicit ZT_INLINE MAC(const uint8_t b[6]) noexcept
{
setTo(b);
}
ZT_INLINE MAC(const Address& ztaddr, const uint64_t nwid) noexcept
{
fromAddress(ztaddr, nwid);
}
ZT_INLINE MAC(const Address &ztaddr, const uint64_t nwid) noexcept { fromAddress(ztaddr, nwid); }
/**
* @return MAC in 64-bit integer
*/
ZT_INLINE uint64_t toInt() const noexcept
{
return m_mac;
}
ZT_INLINE uint64_t toInt() const noexcept { return m_mac; }
/**
* Set MAC to zero
*/
ZT_INLINE void zero() noexcept
{
m_mac = 0ULL;
}
ZT_INLINE void zero() noexcept { m_mac = 0ULL; }
/**
* @param bits Raw MAC in big-endian byte order
@ -72,7 +59,8 @@ class MAC : public TriviallyCopyable {
*/
ZT_INLINE void setTo(const uint8_t b[6]) noexcept
{
m_mac = ((uint64_t)b[0] << 40U) | ((uint64_t)b[1] << 32U) | ((uint64_t)b[2] << 24U) | ((uint64_t)b[3] << 16U) | ((uint64_t)b[4] << 8U) | (uint64_t)b[5];
m_mac = ((uint64_t)b[0] << 40U) | ((uint64_t)b[1] << 32U) | ((uint64_t)b[2] << 24U) | ((uint64_t)b[3] << 16U)
| ((uint64_t)b[4] << 8U) | (uint64_t)b[5];
}
/**
@ -92,18 +80,12 @@ class MAC : public TriviallyCopyable {
/**
* @return True if this is broadcast (all 0xff)
*/
ZT_INLINE bool isBroadcast() const noexcept
{
return m_mac;
}
ZT_INLINE bool isBroadcast() const noexcept { return m_mac; }
/**
* @return True if this is a multicast MAC
*/
ZT_INLINE bool isMulticast() const noexcept
{
return ((m_mac & 0x010000000000ULL) != 0ULL);
}
ZT_INLINE bool isMulticast() const noexcept { return ((m_mac & 0x010000000000ULL) != 0ULL); }
/**
* Set this MAC to a MAC derived from an address and a network ID
@ -111,7 +93,7 @@ class MAC : public TriviallyCopyable {
* @param ztaddr ZeroTier address
* @param nwid 64-bit network ID
*/
ZT_INLINE void fromAddress(const Address& ztaddr, uint64_t nwid) noexcept
ZT_INLINE void fromAddress(const Address &ztaddr, uint64_t nwid) noexcept
{
uint64_t m = ((uint64_t)firstOctetForNetwork(nwid)) << 40U;
m |= ztaddr.toInt(); // a is 40 bits
@ -133,7 +115,8 @@ class MAC : public TriviallyCopyable {
ZT_INLINE Address toAddress(uint64_t nwid) const noexcept
{
uint64_t a = m_mac & 0xffffffffffULL; // least significant 40 bits of MAC are formed from address
a ^= ((nwid >> 8U) & 0xffU) << 32U; // ... XORed with bits 8-48 of the nwid in little-endian byte order, so unmask it
a ^= ((nwid >> 8U) & 0xffU)
<< 32U; // ... XORed with bits 8-48 of the nwid in little-endian byte order, so unmask it
a ^= ((nwid >> 16U) & 0xffU) << 24U;
a ^= ((nwid >> 24U) & 0xffU) << 16U;
a ^= ((nwid >> 32U) & 0xffU) << 8U;
@ -147,9 +130,10 @@ class MAC : public TriviallyCopyable {
*/
static ZT_INLINE unsigned char firstOctetForNetwork(uint64_t nwid) noexcept
{
const uint8_t a = ((uint8_t)(nwid & 0xfeU) | 0x02U); // locally administered, not multicast, from LSB of network ID
return ((a == 0x52) ? 0x32 : a); // blacklist 0x52 since it's used by KVM, libvirt, and other popular
// virtualization engines... seems de-facto standard on Linux
const uint8_t a =
((uint8_t)(nwid & 0xfeU) | 0x02U); // locally administered, not multicast, from LSB of network ID
return ((a == 0x52) ? 0x32 : a); // blacklist 0x52 since it's used by KVM, libvirt, and other popular
// virtualization engines... seems de-facto standard on Linux
}
/**
@ -164,25 +148,13 @@ class MAC : public TriviallyCopyable {
/**
* @return 6, which is the number of bytes in a MAC, for container compliance
*/
ZT_INLINE unsigned int size() const noexcept
{
return 6;
}
ZT_INLINE unsigned int size() const noexcept { return 6; }
ZT_INLINE unsigned long hashCode() const noexcept
{
return (unsigned long)Utils::hash64(m_mac);
}
ZT_INLINE unsigned long hashCode() const noexcept { return (unsigned long)Utils::hash64(m_mac); }
ZT_INLINE operator bool() const noexcept
{
return (m_mac != 0ULL);
}
ZT_INLINE operator bool() const noexcept { return (m_mac != 0ULL); }
ZT_INLINE operator uint64_t() const noexcept
{
return m_mac;
}
ZT_INLINE operator uint64_t() const noexcept { return m_mac; }
/**
* Convert this MAC to a standard format colon-separated hex string
@ -190,18 +162,18 @@ class MAC : public TriviallyCopyable {
* @param buf Buffer to store string
* @return Pointer to buf
*/
ZT_INLINE char* toString(char buf[18]) const noexcept
ZT_INLINE char *toString(char buf[18]) const noexcept
{
buf[0] = Utils::HEXCHARS[(m_mac >> 44U) & 0xfU];
buf[1] = Utils::HEXCHARS[(m_mac >> 40U) & 0xfU];
buf[2] = ':';
buf[3] = Utils::HEXCHARS[(m_mac >> 36U) & 0xfU];
buf[4] = Utils::HEXCHARS[(m_mac >> 32U) & 0xfU];
buf[5] = ':';
buf[6] = Utils::HEXCHARS[(m_mac >> 28U) & 0xfU];
buf[7] = Utils::HEXCHARS[(m_mac >> 24U) & 0xfU];
buf[8] = ':';
buf[9] = Utils::HEXCHARS[(m_mac >> 20U) & 0xfU];
buf[0] = Utils::HEXCHARS[(m_mac >> 44U) & 0xfU];
buf[1] = Utils::HEXCHARS[(m_mac >> 40U) & 0xfU];
buf[2] = ':';
buf[3] = Utils::HEXCHARS[(m_mac >> 36U) & 0xfU];
buf[4] = Utils::HEXCHARS[(m_mac >> 32U) & 0xfU];
buf[5] = ':';
buf[6] = Utils::HEXCHARS[(m_mac >> 28U) & 0xfU];
buf[7] = Utils::HEXCHARS[(m_mac >> 24U) & 0xfU];
buf[8] = ':';
buf[9] = Utils::HEXCHARS[(m_mac >> 20U) & 0xfU];
buf[10] = Utils::HEXCHARS[(m_mac >> 16U) & 0xfU];
buf[11] = ':';
buf[12] = Utils::HEXCHARS[(m_mac >> 12U) & 0xfU];
@ -224,7 +196,7 @@ class MAC : public TriviallyCopyable {
*
* @param s String to parse
*/
ZT_INLINE void fromString(const char* s) noexcept
ZT_INLINE void fromString(const char *s) noexcept
{
m_mac = 0;
if (s) {
@ -245,71 +217,35 @@ class MAC : public TriviallyCopyable {
}
}
ZT_INLINE MAC& operator=(const uint64_t m) noexcept
ZT_INLINE MAC &operator=(const uint64_t m) noexcept
{
m_mac = m;
return *this;
}
ZT_INLINE bool operator==(const MAC& m) const noexcept
{
return (m_mac == m.m_mac);
}
ZT_INLINE bool operator==(const MAC &m) const noexcept { return (m_mac == m.m_mac); }
ZT_INLINE bool operator!=(const MAC& m) const noexcept
{
return (m_mac != m.m_mac);
}
ZT_INLINE bool operator!=(const MAC &m) const noexcept { return (m_mac != m.m_mac); }
ZT_INLINE bool operator<(const MAC& m) const noexcept
{
return (m_mac < m.m_mac);
}
ZT_INLINE bool operator<(const MAC &m) const noexcept { return (m_mac < m.m_mac); }
ZT_INLINE bool operator<=(const MAC& m) const noexcept
{
return (m_mac <= m.m_mac);
}
ZT_INLINE bool operator<=(const MAC &m) const noexcept { return (m_mac <= m.m_mac); }
ZT_INLINE bool operator>(const MAC& m) const noexcept
{
return (m_mac > m.m_mac);
}
ZT_INLINE bool operator>(const MAC &m) const noexcept { return (m_mac > m.m_mac); }
ZT_INLINE bool operator>=(const MAC& m) const noexcept
{
return (m_mac >= m.m_mac);
}
ZT_INLINE bool operator>=(const MAC &m) const noexcept { return (m_mac >= m.m_mac); }
ZT_INLINE bool operator==(const uint64_t m) const noexcept
{
return (m_mac == m);
}
ZT_INLINE bool operator==(const uint64_t m) const noexcept { return (m_mac == m); }
ZT_INLINE bool operator!=(const uint64_t m) const noexcept
{
return (m_mac != m);
}
ZT_INLINE bool operator!=(const uint64_t m) const noexcept { return (m_mac != m); }
ZT_INLINE bool operator<(const uint64_t m) const noexcept
{
return (m_mac < m);
}
ZT_INLINE bool operator<(const uint64_t m) const noexcept { return (m_mac < m); }
ZT_INLINE bool operator<=(const uint64_t m) const noexcept
{
return (m_mac <= m);
}
ZT_INLINE bool operator<=(const uint64_t m) const noexcept { return (m_mac <= m); }
ZT_INLINE bool operator>(const uint64_t m) const noexcept
{
return (m_mac > m);
}
ZT_INLINE bool operator>(const uint64_t m) const noexcept { return (m_mac > m); }
ZT_INLINE bool operator>=(const uint64_t m) const noexcept
{
return (m_mac >= m);
}
ZT_INLINE bool operator>=(const uint64_t m) const noexcept { return (m_mac >= m); }
private:
uint64_t m_mac;

View file

@ -21,60 +21,120 @@ namespace {
// Largest 1024 primes of form 6k + 5 and less than 2^52. Only the least significant 32
// bits need to be here, as the most significant bits are all 1.
const uint32_t ZT_MIMC52_PRIMES[1024] = {
4294895267, 4294895477, 4294895513, 4294895519, 4294895543, 4294895567, 4294895657, 4294895711, 4294895777, 4294895861, 4294895909, 4294895921, 4294895969, 4294896011, 4294896149, 4294896227, 4294896401, 4294896473, 4294896527,
4294896563, 4294896653, 4294896731, 4294896863, 4294896899, 4294896983, 4294897037, 4294897103, 4294897331, 4294897349, 4294897451, 4294897571, 4294897661, 4294897703, 4294897757, 4294897793, 4294897811, 4294897817, 4294897829,
4294897877, 4294897919, 4294897991, 4294898027, 4294898129, 4294898153, 4294898231, 4294898273, 4294898279, 4294898291, 4294898363, 4294898369, 4294898417, 4294898423, 4294898453, 4294898489, 4294898573, 4294898579, 4294898639,
4294898693, 4294898747, 4294898759, 4294898867, 4294898879, 4294898909, 4294898921, 4294898933, 4294899011, 4294899041, 4294899047, 4294899203, 4294899221, 4294899227, 4294899287, 4294899341, 4294899431, 4294899509, 4294899533,
4294899539, 4294899551, 4294899629, 4294899791, 4294899809, 4294899971, 4294900001, 4294900007, 4294900013, 4294900307, 4294900331, 4294900427, 4294900469, 4294900481, 4294900541, 4294900583, 4294900781, 4294900853, 4294900931,
4294900991, 4294901033, 4294901087, 4294901159, 4294901267, 4294901393, 4294901411, 4294901489, 4294901657, 4294902011, 4294902071, 4294902101, 4294902107, 4294902353, 4294902377, 4294902599, 4294902647, 4294902743, 4294902869,
4294902977, 4294903067, 4294903103, 4294903259, 4294903289, 4294903397, 4294903421, 4294903493, 4294903577, 4294903631, 4294903637, 4294903733, 4294903799, 4294903823, 4294904003, 4294904033, 4294904081, 4294904129, 4294904279,
4294904297, 4294904303, 4294904333, 4294904351, 4294904381, 4294904453, 4294904519, 4294904561, 4294904639, 4294904657, 4294904747, 4294904807, 4294904843, 4294905089, 4294905149, 4294905293, 4294905299, 4294905311, 4294905443,
4294905479, 4294905539, 4294905623, 4294905641, 4294905671, 4294905707, 4294905887, 4294905977, 4294906091, 4294906103, 4294906139, 4294906157, 4294906223, 4294906259, 4294906487, 4294906493, 4294906523, 4294906547, 4294906553,
4294906571, 4294906577, 4294906589, 4294906703, 4294906733, 4294906763, 4294906841, 4294906859, 4294906937, 4294907057, 4294907063, 4294907141, 4294907231, 4294907249, 4294907261, 4294907267, 4294907387, 4294907417, 4294907567,
4294907603, 4294907699, 4294907789, 4294907849, 4294907873, 4294907879, 4294908023, 4294908071, 4294908119, 4294908209, 4294908227, 4294908329, 4294908491, 4294908503, 4294908569, 4294908653, 4294908713, 4294908719, 4294908791,
4294908839, 4294908869, 4294908989, 4294909031, 4294909067, 4294909109, 4294909253, 4294909529, 4294909589, 4294909643, 4294909739, 4294909799, 4294909811, 4294909853, 4294910003, 4294910039, 4294910189, 4294910201, 4294910219,
4294910273, 4294910333, 4294910369, 4294910393, 4294910471, 4294910549, 4294910651, 4294910669, 4294910681, 4294910711, 4294910753, 4294910801, 4294910981, 4294911053, 4294911143, 4294911227, 4294911239, 4294911359, 4294911383,
4294911407, 4294911521, 4294911551, 4294911611, 4294911641, 4294911689, 4294911719, 4294911869, 4294912109, 4294912133, 4294912151, 4294912187, 4294912223, 4294912331, 4294912439, 4294912607, 4294912703, 4294912859, 4294912871,
4294912907, 4294912961, 4294913003, 4294913111, 4294913309, 4294913333, 4294913357, 4294913399, 4294913411, 4294913459, 4294913501, 4294913531, 4294913591, 4294913609, 4294913663, 4294913783, 4294913819, 4294913903, 4294914137,
4294914413, 4294914473, 4294914497, 4294914527, 4294914551, 4294914593, 4294914611, 4294914659, 4294914671, 4294914743, 4294914863, 4294914917, 4294915061, 4294915103, 4294915139, 4294915217, 4294915223, 4294915253, 4294915283,
4294915373, 4294915433, 4294915607, 4294916069, 4294916213, 4294916267, 4294916303, 4294916393, 4294916441, 4294916477, 4294916507, 4294916573, 4294916633, 4294916687, 4294916783, 4294916837, 4294916897, 4294916921, 4294917029,
4294917047, 4294917101, 4294917203, 4294917287, 4294917299, 4294917389, 4294917437, 4294917527, 4294917557, 4294917611, 4294917617, 4294917689, 4294917821, 4294917857, 4294917917, 4294917941, 4294918169, 4294918187, 4294918307,
4294918409, 4294918433, 4294918481, 4294918703, 4294918709, 4294918733, 4294918799, 4294918871, 4294919009, 4294919249, 4294919279, 4294919291, 4294919363, 4294919381, 4294919441, 4294919447, 4294919549, 4294919579, 4294919633,
4294919657, 4294919669, 4294919693, 4294919711, 4294920029, 4294920059, 4294920089, 4294920197, 4294920239, 4294920257, 4294920263, 4294920269, 4294920341, 4294920353, 4294920407, 4294920503, 4294920599, 4294920647, 4294920743,
4294920803, 4294920809, 4294920881, 4294920899, 4294920983, 4294921043, 4294921139, 4294921151, 4294921181, 4294921229, 4294921289, 4294921331, 4294921343, 4294921391, 4294921469, 4294921709, 4294921721, 4294921823, 4294921847,
4294921889, 4294922057, 4294922171, 4294922201, 4294922237, 4294922309, 4294922399, 4294922447, 4294922507, 4294922513, 4294922549, 4294922609, 4294922663, 4294922861, 4294922933, 4294923101, 4294923191, 4294923209, 4294923221,
4294923251, 4294923263, 4294923359, 4294923371, 4294923377, 4294923461, 4294923521, 4294923953, 4294924001, 4294924091, 4294924121, 4294924319, 4294924397, 4294924571, 4294924583, 4294924751, 4294924817, 4294924823, 4294924847,
4294924877, 4294925003, 4294925027, 4294925117, 4294925237, 4294925243, 4294925297, 4294925369, 4294925627, 4294925639, 4294925729, 4294925747, 4294925873, 4294925891, 4294925933, 4294926047, 4294926059, 4294926209, 4294926221,
4294926233, 4294926257, 4294926329, 4294926371, 4294926401, 4294926413, 4294926437, 4294926563, 4294926569, 4294926917, 4294926923, 4294926947, 4294926971, 4294927067, 4294927073, 4294927151, 4294927349, 4294927367, 4294927403,
4294927481, 4294927523, 4294927553, 4294927589, 4294927649, 4294927673, 4294927727, 4294927739, 4294927763, 4294927889, 4294928183, 4294928207, 4294928249, 4294928327, 4294928351, 4294928399, 4294928483, 4294928489, 4294928543,
4294928597, 4294928951, 4294928963, 4294928981, 4294929017, 4294929059, 4294929161, 4294929197, 4294929233, 4294929269, 4294929311, 4294929323, 4294929341, 4294929383, 4294929401, 4294929497, 4294929509, 4294929581, 4294929707,
4294929743, 4294930043, 4294930121, 4294930193, 4294930223, 4294930349, 4294930403, 4294930571, 4294930613, 4294930721, 4294930751, 4294930877, 4294930931, 4294930961, 4294930967, 4294930973, 4294931021, 4294931051, 4294931057,
4294931063, 4294931219, 4294931273, 4294931339, 4294931423, 4294931441, 4294931453, 4294931567, 4294931639, 4294931717, 4294931897, 4294931969, 4294932023, 4294932053, 4294932239, 4294932299, 4294932443, 4294932671, 4294932677,
4294932731, 4294932743, 4294932767, 4294932773, 4294932779, 4294932881, 4294932899, 4294932929, 4294933067, 4294933277, 4294933307, 4294933343, 4294933451, 4294933523, 4294933763, 4294933793, 4294933829, 4294933847, 4294933871,
4294933997, 4294934033, 4294934111, 4294934207, 4294934243, 4294934267, 4294934279, 4294934291, 4294934327, 4294934363, 4294934423, 4294934489, 4294934561, 4294934867, 4294934921, 4294934969, 4294935137, 4294935239, 4294935299,
4294935431, 4294935539, 4294935629, 4294935701, 4294935791, 4294935797, 4294935803, 4294935959, 4294936001, 4294936007, 4294936037, 4294936079, 4294936127, 4294936163, 4294936247, 4294936307, 4294936331, 4294936409, 4294936451,
4294936601, 4294936607, 4294936619, 4294936667, 4294936709, 4294936733, 4294936751, 4294936763, 4294936829, 4294936937, 4294936997, 4294937027, 4294937051, 4294937093, 4294937177, 4294937213, 4294937291, 4294937381, 4294937417,
4294937429, 4294937681, 4294937693, 4294937753, 4294937771, 4294937813, 4294937837, 4294937891, 4294937969, 4294938071, 4294938101, 4294938323, 4294938371, 4294938401, 4294938467, 4294938473, 4294938521, 4294938599, 4294938731,
4294938779, 4294938833, 4294938899, 4294938977, 4294938983, 4294939067, 4294939127, 4294939223, 4294939277, 4294939331, 4294939337, 4294939391, 4294939457, 4294939559, 4294939673, 4294939691, 4294939901, 4294939991, 4294940087,
4294940093, 4294940189, 4294940213, 4294940417, 4294940657, 4294940699, 4294940753, 4294940801, 4294940873, 4294940951, 4294941047, 4294941143, 4294941161, 4294941227, 4294941281, 4294941377, 4294941509, 4294941551, 4294941701,
4294941731, 4294941767, 4294941911, 4294941923, 4294942043, 4294942139, 4294942313, 4294942343, 4294942373, 4294942427, 4294942529, 4294942601, 4294942649, 4294942673, 4294942679, 4294942733, 4294942769, 4294942811, 4294942961,
4294943129, 4294943141, 4294943219, 4294943369, 4294943423, 4294943471, 4294943651, 4294943687, 4294943717, 4294943729, 4294943747, 4294943759, 4294943813, 4294943819, 4294943891, 4294944077, 4294944191, 4294944233, 4294944239,
4294944353, 4294944389, 4294944581, 4294944623, 4294944629, 4294944659, 4294944821, 4294945031, 4294945157, 4294945211, 4294945229, 4294945301, 4294945337, 4294945343, 4294945511, 4294945547, 4294945667, 4294945709, 4294945757,
4294945841, 4294945991, 4294946033, 4294946099, 4294946153, 4294946477, 4294946687, 4294946747, 4294946957, 4294946993, 4294947023, 4294947131, 4294947167, 4294947287, 4294947311, 4294947413, 4294947581, 4294947599, 4294947671,
4294947851, 4294947959, 4294948067, 4294948073, 4294948193, 4294948259, 4294948421, 4294948451, 4294948613, 4294948673, 4294948883, 4294949027, 4294949057, 4294949069, 4294949519, 4294949531, 4294949603, 4294949609, 4294949627,
4294949693, 4294949729, 4294949741, 4294949807, 4294949921, 4294949939, 4294949981, 4294949993, 4294950083, 4294950173, 4294950197, 4294950251, 4294950287, 4294950317, 4294950323, 4294950329, 4294950581, 4294950593, 4294950617,
4294950629, 4294950713, 4294950929, 4294951151, 4294951163, 4294951169, 4294951379, 4294951583, 4294951613, 4294951853, 4294951907, 4294951913, 4294951937, 4294951961, 4294952063, 4294952183, 4294952393, 4294952543, 4294952549,
4294952597, 4294952627, 4294952687, 4294952723, 4294952729, 4294952789, 4294952819, 4294952873, 4294952891, 4294952903, 4294952969, 4294952999, 4294953023, 4294953107, 4294953173, 4294953281, 4294953341, 4294953431, 4294953599,
4294953689, 4294953719, 4294953827, 4294953887, 4294953977, 4294954073, 4294954079, 4294954157, 4294954217, 4294954283, 4294954607, 4294954667, 4294954859, 4294954901, 4294954973, 4294955081, 4294955237, 4294955273, 4294955327,
4294955441, 4294955507, 4294955591, 4294955789, 4294955831, 4294955837, 4294955927, 4294955963, 4294955969, 4294955987, 4294956041, 4294956047, 4294956197, 4294956323, 4294956359, 4294956551, 4294956593, 4294956623, 4294956629,
4294956641, 4294956719, 4294956761, 4294956767, 4294956797, 4294956821, 4294956833, 4294957037, 4294957079, 4294957103, 4294957181, 4294957349, 4294957379, 4294957433, 4294957463, 4294957511, 4294957577, 4294957727, 4294957859,
4294957877, 4294958039, 4294958153, 4294958309, 4294958417, 4294958441, 4294958693, 4294958717, 4294958753, 4294958903, 4294958909, 4294959017, 4294959071, 4294959107, 4294959161, 4294959257, 4294959299, 4294959329, 4294959431,
4294959593, 4294959599, 4294959659, 4294959893, 4294959917, 4294959983, 4294960001, 4294960031, 4294960061, 4294960079, 4294960097, 4294960271, 4294960283, 4294960349, 4294960367, 4294960421, 4294960529, 4294960541, 4294960583,
4294960613, 4294960673, 4294960691, 4294960697, 4294960787, 4294960919, 4294961003, 4294961039, 4294961153, 4294961159, 4294961171, 4294961321, 4294961411, 4294961471, 4294961507, 4294961537, 4294961669, 4294961717, 4294961741,
4294961873, 4294962059, 4294962137, 4294962167, 4294962263, 4294962281, 4294962311, 4294962341, 4294962413, 4294962521, 4294962563, 4294962761, 4294962893, 4294963103, 4294963163, 4294963223, 4294963313, 4294963349, 4294963427,
4294963547, 4294963559, 4294963721, 4294963799, 4294963817, 4294963901, 4294963919, 4294964021, 4294964279, 4294964297, 4294964363, 4294964387, 4294964411, 4294964567, 4294964603, 4294964687, 4294964777, 4294965041, 4294965071,
4294965119, 4294965221, 4294965251, 4294965287, 4294965413, 4294965569, 4294965647, 4294965671, 4294965689, 4294965779, 4294965839, 4294965893, 4294966091, 4294966109, 4294966127, 4294966157, 4294966187, 4294966199, 4294966211,
4294966403, 4294966457, 4294966499, 4294966541, 4294966637, 4294966661, 4294966739, 4294966823, 4294966883, 4294966901, 4294966961, 4294967027, 4294967087, 4294967099, 4294967123, 4294967153, 4294967249
4294895267, 4294895477, 4294895513, 4294895519, 4294895543, 4294895567, 4294895657, 4294895711, 4294895777,
4294895861, 4294895909, 4294895921, 4294895969, 4294896011, 4294896149, 4294896227, 4294896401, 4294896473,
4294896527, 4294896563, 4294896653, 4294896731, 4294896863, 4294896899, 4294896983, 4294897037, 4294897103,
4294897331, 4294897349, 4294897451, 4294897571, 4294897661, 4294897703, 4294897757, 4294897793, 4294897811,
4294897817, 4294897829, 4294897877, 4294897919, 4294897991, 4294898027, 4294898129, 4294898153, 4294898231,
4294898273, 4294898279, 4294898291, 4294898363, 4294898369, 4294898417, 4294898423, 4294898453, 4294898489,
4294898573, 4294898579, 4294898639, 4294898693, 4294898747, 4294898759, 4294898867, 4294898879, 4294898909,
4294898921, 4294898933, 4294899011, 4294899041, 4294899047, 4294899203, 4294899221, 4294899227, 4294899287,
4294899341, 4294899431, 4294899509, 4294899533, 4294899539, 4294899551, 4294899629, 4294899791, 4294899809,
4294899971, 4294900001, 4294900007, 4294900013, 4294900307, 4294900331, 4294900427, 4294900469, 4294900481,
4294900541, 4294900583, 4294900781, 4294900853, 4294900931, 4294900991, 4294901033, 4294901087, 4294901159,
4294901267, 4294901393, 4294901411, 4294901489, 4294901657, 4294902011, 4294902071, 4294902101, 4294902107,
4294902353, 4294902377, 4294902599, 4294902647, 4294902743, 4294902869, 4294902977, 4294903067, 4294903103,
4294903259, 4294903289, 4294903397, 4294903421, 4294903493, 4294903577, 4294903631, 4294903637, 4294903733,
4294903799, 4294903823, 4294904003, 4294904033, 4294904081, 4294904129, 4294904279, 4294904297, 4294904303,
4294904333, 4294904351, 4294904381, 4294904453, 4294904519, 4294904561, 4294904639, 4294904657, 4294904747,
4294904807, 4294904843, 4294905089, 4294905149, 4294905293, 4294905299, 4294905311, 4294905443, 4294905479,
4294905539, 4294905623, 4294905641, 4294905671, 4294905707, 4294905887, 4294905977, 4294906091, 4294906103,
4294906139, 4294906157, 4294906223, 4294906259, 4294906487, 4294906493, 4294906523, 4294906547, 4294906553,
4294906571, 4294906577, 4294906589, 4294906703, 4294906733, 4294906763, 4294906841, 4294906859, 4294906937,
4294907057, 4294907063, 4294907141, 4294907231, 4294907249, 4294907261, 4294907267, 4294907387, 4294907417,
4294907567, 4294907603, 4294907699, 4294907789, 4294907849, 4294907873, 4294907879, 4294908023, 4294908071,
4294908119, 4294908209, 4294908227, 4294908329, 4294908491, 4294908503, 4294908569, 4294908653, 4294908713,
4294908719, 4294908791, 4294908839, 4294908869, 4294908989, 4294909031, 4294909067, 4294909109, 4294909253,
4294909529, 4294909589, 4294909643, 4294909739, 4294909799, 4294909811, 4294909853, 4294910003, 4294910039,
4294910189, 4294910201, 4294910219, 4294910273, 4294910333, 4294910369, 4294910393, 4294910471, 4294910549,
4294910651, 4294910669, 4294910681, 4294910711, 4294910753, 4294910801, 4294910981, 4294911053, 4294911143,
4294911227, 4294911239, 4294911359, 4294911383, 4294911407, 4294911521, 4294911551, 4294911611, 4294911641,
4294911689, 4294911719, 4294911869, 4294912109, 4294912133, 4294912151, 4294912187, 4294912223, 4294912331,
4294912439, 4294912607, 4294912703, 4294912859, 4294912871, 4294912907, 4294912961, 4294913003, 4294913111,
4294913309, 4294913333, 4294913357, 4294913399, 4294913411, 4294913459, 4294913501, 4294913531, 4294913591,
4294913609, 4294913663, 4294913783, 4294913819, 4294913903, 4294914137, 4294914413, 4294914473, 4294914497,
4294914527, 4294914551, 4294914593, 4294914611, 4294914659, 4294914671, 4294914743, 4294914863, 4294914917,
4294915061, 4294915103, 4294915139, 4294915217, 4294915223, 4294915253, 4294915283, 4294915373, 4294915433,
4294915607, 4294916069, 4294916213, 4294916267, 4294916303, 4294916393, 4294916441, 4294916477, 4294916507,
4294916573, 4294916633, 4294916687, 4294916783, 4294916837, 4294916897, 4294916921, 4294917029, 4294917047,
4294917101, 4294917203, 4294917287, 4294917299, 4294917389, 4294917437, 4294917527, 4294917557, 4294917611,
4294917617, 4294917689, 4294917821, 4294917857, 4294917917, 4294917941, 4294918169, 4294918187, 4294918307,
4294918409, 4294918433, 4294918481, 4294918703, 4294918709, 4294918733, 4294918799, 4294918871, 4294919009,
4294919249, 4294919279, 4294919291, 4294919363, 4294919381, 4294919441, 4294919447, 4294919549, 4294919579,
4294919633, 4294919657, 4294919669, 4294919693, 4294919711, 4294920029, 4294920059, 4294920089, 4294920197,
4294920239, 4294920257, 4294920263, 4294920269, 4294920341, 4294920353, 4294920407, 4294920503, 4294920599,
4294920647, 4294920743, 4294920803, 4294920809, 4294920881, 4294920899, 4294920983, 4294921043, 4294921139,
4294921151, 4294921181, 4294921229, 4294921289, 4294921331, 4294921343, 4294921391, 4294921469, 4294921709,
4294921721, 4294921823, 4294921847, 4294921889, 4294922057, 4294922171, 4294922201, 4294922237, 4294922309,
4294922399, 4294922447, 4294922507, 4294922513, 4294922549, 4294922609, 4294922663, 4294922861, 4294922933,
4294923101, 4294923191, 4294923209, 4294923221, 4294923251, 4294923263, 4294923359, 4294923371, 4294923377,
4294923461, 4294923521, 4294923953, 4294924001, 4294924091, 4294924121, 4294924319, 4294924397, 4294924571,
4294924583, 4294924751, 4294924817, 4294924823, 4294924847, 4294924877, 4294925003, 4294925027, 4294925117,
4294925237, 4294925243, 4294925297, 4294925369, 4294925627, 4294925639, 4294925729, 4294925747, 4294925873,
4294925891, 4294925933, 4294926047, 4294926059, 4294926209, 4294926221, 4294926233, 4294926257, 4294926329,
4294926371, 4294926401, 4294926413, 4294926437, 4294926563, 4294926569, 4294926917, 4294926923, 4294926947,
4294926971, 4294927067, 4294927073, 4294927151, 4294927349, 4294927367, 4294927403, 4294927481, 4294927523,
4294927553, 4294927589, 4294927649, 4294927673, 4294927727, 4294927739, 4294927763, 4294927889, 4294928183,
4294928207, 4294928249, 4294928327, 4294928351, 4294928399, 4294928483, 4294928489, 4294928543, 4294928597,
4294928951, 4294928963, 4294928981, 4294929017, 4294929059, 4294929161, 4294929197, 4294929233, 4294929269,
4294929311, 4294929323, 4294929341, 4294929383, 4294929401, 4294929497, 4294929509, 4294929581, 4294929707,
4294929743, 4294930043, 4294930121, 4294930193, 4294930223, 4294930349, 4294930403, 4294930571, 4294930613,
4294930721, 4294930751, 4294930877, 4294930931, 4294930961, 4294930967, 4294930973, 4294931021, 4294931051,
4294931057, 4294931063, 4294931219, 4294931273, 4294931339, 4294931423, 4294931441, 4294931453, 4294931567,
4294931639, 4294931717, 4294931897, 4294931969, 4294932023, 4294932053, 4294932239, 4294932299, 4294932443,
4294932671, 4294932677, 4294932731, 4294932743, 4294932767, 4294932773, 4294932779, 4294932881, 4294932899,
4294932929, 4294933067, 4294933277, 4294933307, 4294933343, 4294933451, 4294933523, 4294933763, 4294933793,
4294933829, 4294933847, 4294933871, 4294933997, 4294934033, 4294934111, 4294934207, 4294934243, 4294934267,
4294934279, 4294934291, 4294934327, 4294934363, 4294934423, 4294934489, 4294934561, 4294934867, 4294934921,
4294934969, 4294935137, 4294935239, 4294935299, 4294935431, 4294935539, 4294935629, 4294935701, 4294935791,
4294935797, 4294935803, 4294935959, 4294936001, 4294936007, 4294936037, 4294936079, 4294936127, 4294936163,
4294936247, 4294936307, 4294936331, 4294936409, 4294936451, 4294936601, 4294936607, 4294936619, 4294936667,
4294936709, 4294936733, 4294936751, 4294936763, 4294936829, 4294936937, 4294936997, 4294937027, 4294937051,
4294937093, 4294937177, 4294937213, 4294937291, 4294937381, 4294937417, 4294937429, 4294937681, 4294937693,
4294937753, 4294937771, 4294937813, 4294937837, 4294937891, 4294937969, 4294938071, 4294938101, 4294938323,
4294938371, 4294938401, 4294938467, 4294938473, 4294938521, 4294938599, 4294938731, 4294938779, 4294938833,
4294938899, 4294938977, 4294938983, 4294939067, 4294939127, 4294939223, 4294939277, 4294939331, 4294939337,
4294939391, 4294939457, 4294939559, 4294939673, 4294939691, 4294939901, 4294939991, 4294940087, 4294940093,
4294940189, 4294940213, 4294940417, 4294940657, 4294940699, 4294940753, 4294940801, 4294940873, 4294940951,
4294941047, 4294941143, 4294941161, 4294941227, 4294941281, 4294941377, 4294941509, 4294941551, 4294941701,
4294941731, 4294941767, 4294941911, 4294941923, 4294942043, 4294942139, 4294942313, 4294942343, 4294942373,
4294942427, 4294942529, 4294942601, 4294942649, 4294942673, 4294942679, 4294942733, 4294942769, 4294942811,
4294942961, 4294943129, 4294943141, 4294943219, 4294943369, 4294943423, 4294943471, 4294943651, 4294943687,
4294943717, 4294943729, 4294943747, 4294943759, 4294943813, 4294943819, 4294943891, 4294944077, 4294944191,
4294944233, 4294944239, 4294944353, 4294944389, 4294944581, 4294944623, 4294944629, 4294944659, 4294944821,
4294945031, 4294945157, 4294945211, 4294945229, 4294945301, 4294945337, 4294945343, 4294945511, 4294945547,
4294945667, 4294945709, 4294945757, 4294945841, 4294945991, 4294946033, 4294946099, 4294946153, 4294946477,
4294946687, 4294946747, 4294946957, 4294946993, 4294947023, 4294947131, 4294947167, 4294947287, 4294947311,
4294947413, 4294947581, 4294947599, 4294947671, 4294947851, 4294947959, 4294948067, 4294948073, 4294948193,
4294948259, 4294948421, 4294948451, 4294948613, 4294948673, 4294948883, 4294949027, 4294949057, 4294949069,
4294949519, 4294949531, 4294949603, 4294949609, 4294949627, 4294949693, 4294949729, 4294949741, 4294949807,
4294949921, 4294949939, 4294949981, 4294949993, 4294950083, 4294950173, 4294950197, 4294950251, 4294950287,
4294950317, 4294950323, 4294950329, 4294950581, 4294950593, 4294950617, 4294950629, 4294950713, 4294950929,
4294951151, 4294951163, 4294951169, 4294951379, 4294951583, 4294951613, 4294951853, 4294951907, 4294951913,
4294951937, 4294951961, 4294952063, 4294952183, 4294952393, 4294952543, 4294952549, 4294952597, 4294952627,
4294952687, 4294952723, 4294952729, 4294952789, 4294952819, 4294952873, 4294952891, 4294952903, 4294952969,
4294952999, 4294953023, 4294953107, 4294953173, 4294953281, 4294953341, 4294953431, 4294953599, 4294953689,
4294953719, 4294953827, 4294953887, 4294953977, 4294954073, 4294954079, 4294954157, 4294954217, 4294954283,
4294954607, 4294954667, 4294954859, 4294954901, 4294954973, 4294955081, 4294955237, 4294955273, 4294955327,
4294955441, 4294955507, 4294955591, 4294955789, 4294955831, 4294955837, 4294955927, 4294955963, 4294955969,
4294955987, 4294956041, 4294956047, 4294956197, 4294956323, 4294956359, 4294956551, 4294956593, 4294956623,
4294956629, 4294956641, 4294956719, 4294956761, 4294956767, 4294956797, 4294956821, 4294956833, 4294957037,
4294957079, 4294957103, 4294957181, 4294957349, 4294957379, 4294957433, 4294957463, 4294957511, 4294957577,
4294957727, 4294957859, 4294957877, 4294958039, 4294958153, 4294958309, 4294958417, 4294958441, 4294958693,
4294958717, 4294958753, 4294958903, 4294958909, 4294959017, 4294959071, 4294959107, 4294959161, 4294959257,
4294959299, 4294959329, 4294959431, 4294959593, 4294959599, 4294959659, 4294959893, 4294959917, 4294959983,
4294960001, 4294960031, 4294960061, 4294960079, 4294960097, 4294960271, 4294960283, 4294960349, 4294960367,
4294960421, 4294960529, 4294960541, 4294960583, 4294960613, 4294960673, 4294960691, 4294960697, 4294960787,
4294960919, 4294961003, 4294961039, 4294961153, 4294961159, 4294961171, 4294961321, 4294961411, 4294961471,
4294961507, 4294961537, 4294961669, 4294961717, 4294961741, 4294961873, 4294962059, 4294962137, 4294962167,
4294962263, 4294962281, 4294962311, 4294962341, 4294962413, 4294962521, 4294962563, 4294962761, 4294962893,
4294963103, 4294963163, 4294963223, 4294963313, 4294963349, 4294963427, 4294963547, 4294963559, 4294963721,
4294963799, 4294963817, 4294963901, 4294963919, 4294964021, 4294964279, 4294964297, 4294964363, 4294964387,
4294964411, 4294964567, 4294964603, 4294964687, 4294964777, 4294965041, 4294965071, 4294965119, 4294965221,
4294965251, 4294965287, 4294965413, 4294965569, 4294965647, 4294965671, 4294965689, 4294965779, 4294965839,
4294965893, 4294966091, 4294966109, 4294966127, 4294966157, 4294966187, 4294966199, 4294966211, 4294966403,
4294966457, 4294966499, 4294966541, 4294966637, 4294966661, 4294966739, 4294966823, 4294966883, 4294966901,
4294966961, 4294967027, 4294967087, 4294967099, 4294967123, 4294967153, 4294967249
};
#ifdef ZT_NO_IEEE_DOUBLE
@ -158,10 +218,10 @@ uint64_t delay(const uint8_t challenge[32], const unsigned long rounds)
uint64_t k[34];
fillK(k, challenge);
const uint64_t p = 0x000fffff00000000ULL | (uint64_t)ZT_MIMC52_PRIMES[((unsigned long)k[32]) & 1023];
const uint64_t e = ((p * 2ULL) - 1ULL) / 3ULL;
const uint64_t p = 0x000fffff00000000ULL | (uint64_t)ZT_MIMC52_PRIMES[((unsigned long)k[32]) & 1023];
const uint64_t e = ((p * 2ULL) - 1ULL) / 3ULL;
const uint64_t m52 = 0xfffffffffffffULL;
const double pf = (double)p;
const double pf = (double)p;
uint64_t x = k[33] % p;
for (unsigned long r = 0, kn = rounds; r < rounds; ++r) {
@ -177,14 +237,14 @@ bool verify(const uint8_t challenge[32], const unsigned long rounds, uint64_t pr
uint64_t k[34];
fillK(k, challenge);
const uint64_t p = 0x000fffff00000000ULL | (uint64_t)ZT_MIMC52_PRIMES[((unsigned long)k[32]) & 1023];
const uint64_t p = 0x000fffff00000000ULL | (uint64_t)ZT_MIMC52_PRIMES[((unsigned long)k[32]) & 1023];
const uint64_t m52 = 0xfffffffffffffULL;
const double pf = (double)p;
const double pf = (double)p;
for (unsigned long r = 0; r < rounds; ++r) {
const uint64_t kk = k[r & 31];
proof = mulmod52(mulmod52(proof, proof, p, pf), proof, p, pf); // y = y ^ 3
proof = (proof + kk) & m52;
proof = mulmod52(mulmod52(proof, proof, p, pf), proof, p, pf); // y = y ^ 3
proof = (proof + kk) & m52;
}
return ((proof % p) == (k[33] % p));

View file

@ -21,13 +21,18 @@
namespace ZeroTier {
Member::Member() : m_comRevocationThreshold(0), m_lastPushedCredentials(0), m_comAgreementLocalTimestamp(0), m_comAgreementRemoteTimestamp(0)
Member::Member()
: m_comRevocationThreshold(0)
, m_lastPushedCredentials(0)
, m_comAgreementLocalTimestamp(0)
, m_comAgreementRemoteTimestamp(0)
{
}
void Member::pushCredentials(const Context& ctx, const CallContext& cc, const SharedPtr<Peer>& to, const NetworkConfig& nconf)
void Member::pushCredentials(
const Context &ctx, const CallContext &cc, const SharedPtr<Peer> &to, const NetworkConfig &nconf)
{
if (! nconf.com) // sanity check
if (!nconf.com) // sanity check
return;
#if 0
@ -112,24 +117,30 @@ void Member::pushCredentials(const Context& ctx, const CallContext& cc, const Sh
m_lastPushedCredentials = cc.ticks;
}
void Member::clean(const NetworkConfig& nconf)
void Member::clean(const NetworkConfig &nconf)
{
m_cleanCredImpl<TagCredential>(nconf, m_remoteTags);
m_cleanCredImpl<CapabilityCredential>(nconf, m_remoteCaps);
m_cleanCredImpl<OwnershipCredential>(nconf, m_remoteCoos);
}
Member::AddCredentialResult Member::addCredential(const Context& ctx, const CallContext& cc, const Identity& sourcePeerIdentity, const NetworkConfig& nconf, const MembershipCredential& com)
Member::AddCredentialResult Member::addCredential(
const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf,
const MembershipCredential &com)
{
const int64_t newts = com.timestamp();
if (newts <= m_comRevocationThreshold) {
ctx.t->credentialRejected(cc, 0xd9992121, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
ctx.t->credentialRejected(
cc, 0xd9992121, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM,
ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
return ADD_REJECTED;
}
const int64_t oldts = m_com.timestamp();
if (newts < oldts) {
ctx.t->credentialRejected(cc, 0xd9928192, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
ctx.t->credentialRejected(
cc, 0xd9928192, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM,
ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
return ADD_REJECTED;
}
if ((newts == oldts) && (m_com == com))
@ -137,74 +148,92 @@ Member::AddCredentialResult Member::addCredential(const Context& ctx, const Call
switch (com.verify(ctx, cc)) {
default:
ctx.t->credentialRejected(cc, 0x0f198241, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
ctx.t->credentialRejected(
cc, 0x0f198241, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM,
ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
return Member::ADD_REJECTED;
case Credential::VERIFY_OK:
m_com = com;
return ADD_ACCEPTED_NEW;
case Credential::VERIFY_OK: m_com = com; return ADD_ACCEPTED_NEW;
case Credential::VERIFY_BAD_SIGNATURE:
ctx.t->credentialRejected(cc, 0xbaf0aaaa, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_SIGNATURE_VERIFICATION_FAILED);
ctx.t->credentialRejected(
cc, 0xbaf0aaaa, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM,
ZT_TRACE_CREDENTIAL_REJECTION_REASON_SIGNATURE_VERIFICATION_FAILED);
return ADD_REJECTED;
case Credential::VERIFY_NEED_IDENTITY:
return ADD_DEFERRED_FOR_WHOIS;
case Credential::VERIFY_NEED_IDENTITY: return ADD_DEFERRED_FOR_WHOIS;
}
}
// 3/5 of the credential types have identical addCredential() code
template <typename C>
static ZT_INLINE Member::AddCredentialResult
_addCredImpl(Map<uint32_t, C>& remoteCreds, const Map<uint64_t, int64_t>& revocations, const Context& ctx, const CallContext& cc, const Identity& sourcePeerIdentity, const NetworkConfig& nconf, const C& cred)
static ZT_INLINE Member::AddCredentialResult _addCredImpl(
Map<uint32_t, C> &remoteCreds, const Map<uint64_t, int64_t> &revocations, const Context &ctx, const CallContext &cc,
const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const C &cred)
{
typename Map<uint32_t, C>::const_iterator rc(remoteCreds.find(cred.id()));
if (rc != remoteCreds.end()) {
if (rc->second.revision() > cred.revision()) {
ctx.t->credentialRejected(cc, 0x40000001, nconf.networkId, sourcePeerIdentity, cred.id(), cred.revision(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
ctx.t->credentialRejected(
cc, 0x40000001, nconf.networkId, sourcePeerIdentity, cred.id(), cred.revision(), C::credentialType(),
ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
return Member::ADD_REJECTED;
}
if (rc->second == cred)
return Member::ADD_ACCEPTED_REDUNDANT;
}
typename Map<uint64_t, int64_t>::const_iterator rt(revocations.find(Member::credentialKey(C::credentialType(), cred.id())));
typename Map<uint64_t, int64_t>::const_iterator rt(
revocations.find(Member::credentialKey(C::credentialType(), cred.id())));
if ((rt != revocations.end()) && (rt->second >= cred.revision())) {
ctx.t->credentialRejected(cc, 0x24248124, nconf.networkId, sourcePeerIdentity, cred.id(), cred.revision(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
ctx.t->credentialRejected(
cc, 0x24248124, nconf.networkId, sourcePeerIdentity, cred.id(), cred.revision(), C::credentialType(),
ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
return Member::ADD_REJECTED;
}
switch (cred.verify(ctx, cc)) {
default:
ctx.t->credentialRejected(cc, 0x01feba012, nconf.networkId, sourcePeerIdentity, cred.id(), cred.revision(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
ctx.t->credentialRejected(
cc, 0x01feba012, nconf.networkId, sourcePeerIdentity, cred.id(), cred.revision(), C::credentialType(),
ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
return Member::ADD_REJECTED;
case 0:
if (rc == remoteCreds.end())
remoteCreds[cred.id()] = cred;
return Member::ADD_ACCEPTED_NEW;
case 1:
return Member::ADD_DEFERRED_FOR_WHOIS;
case 1: return Member::ADD_DEFERRED_FOR_WHOIS;
}
}
Member::AddCredentialResult Member::addCredential(const Context& ctx, const CallContext& cc, const Identity& sourcePeerIdentity, const NetworkConfig& nconf, const TagCredential& tag)
Member::AddCredentialResult Member::addCredential(
const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf,
const TagCredential &tag)
{
return _addCredImpl<TagCredential>(m_remoteTags, m_revocations, ctx, cc, sourcePeerIdentity, nconf, tag);
}
Member::AddCredentialResult Member::addCredential(const Context& ctx, const CallContext& cc, const Identity& sourcePeerIdentity, const NetworkConfig& nconf, const CapabilityCredential& cap)
Member::AddCredentialResult Member::addCredential(
const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf,
const CapabilityCredential &cap)
{
return _addCredImpl<CapabilityCredential>(m_remoteCaps, m_revocations, ctx, cc, sourcePeerIdentity, nconf, cap);
}
Member::AddCredentialResult Member::addCredential(const Context& ctx, const CallContext& cc, const Identity& sourcePeerIdentity, const NetworkConfig& nconf, const OwnershipCredential& coo)
Member::AddCredentialResult Member::addCredential(
const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf,
const OwnershipCredential &coo)
{
return _addCredImpl<OwnershipCredential>(m_remoteCoos, m_revocations, ctx, cc, sourcePeerIdentity, nconf, coo);
}
Member::AddCredentialResult Member::addCredential(const Context& ctx, const CallContext& cc, const Identity& sourcePeerIdentity, const NetworkConfig& nconf, const RevocationCredential& rev)
Member::AddCredentialResult Member::addCredential(
const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf,
const RevocationCredential &rev)
{
int64_t* rt;
int64_t *rt;
switch (rev.verify(ctx, cc)) {
default:
ctx.t->credentialRejected(cc, 0x938ff009, nconf.networkId, sourcePeerIdentity, rev.id(), 0, ZT_CREDENTIAL_TYPE_REVOCATION, ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
ctx.t->credentialRejected(
cc, 0x938ff009, nconf.networkId, sourcePeerIdentity, rev.id(), 0, ZT_CREDENTIAL_TYPE_REVOCATION,
ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
return ADD_REJECTED;
case 0: {
const ZT_CredentialType ct = rev.typeBeingRevoked();
@ -220,24 +249,28 @@ Member::AddCredentialResult Member::addCredential(const Context& ctx, const Call
case ZT_CREDENTIAL_TYPE_COO:
rt = &(m_revocations[credentialKey(ct, rev.credentialId())]);
if (*rt < rev.threshold()) {
*rt = rev.threshold();
*rt = rev.threshold();
m_comRevocationThreshold = rev.threshold();
return ADD_ACCEPTED_NEW;
}
return ADD_ACCEPTED_REDUNDANT;
default:
ctx.t->credentialRejected(cc, 0x0bbbb1a4, nconf.networkId, sourcePeerIdentity, rev.id(), 0, ZT_CREDENTIAL_TYPE_REVOCATION, ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
ctx.t->credentialRejected(
cc, 0x0bbbb1a4, nconf.networkId, sourcePeerIdentity, rev.id(), 0, ZT_CREDENTIAL_TYPE_REVOCATION,
ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
return ADD_REJECTED;
}
}
case 1:
return ADD_DEFERRED_FOR_WHOIS;
case 1: return ADD_DEFERRED_FOR_WHOIS;
}
}
bool Member::m_isUnspoofableAddress(const NetworkConfig& nconf, const InetAddress& ip) const noexcept
bool Member::m_isUnspoofableAddress(const NetworkConfig &nconf, const InetAddress &ip) const noexcept
{
return (ip.isV6() && nconf.ndpEmulation() && ((ip == InetAddress::makeIpv66plane(nconf.networkId, m_com.issuedTo().address)) || (ip == InetAddress::makeIpv6rfc4193(nconf.networkId, m_com.issuedTo().address))));
return (
ip.isV6() && nconf.ndpEmulation()
&& ((ip == InetAddress::makeIpv66plane(nconf.networkId, m_com.issuedTo().address))
|| (ip == InetAddress::makeIpv6rfc4193(nconf.networkId, m_com.issuedTo().address))));
}
} // namespace ZeroTier

View file

@ -48,15 +48,13 @@ class Member {
* @param to Peer identity
* @param nconf My network config
*/
void pushCredentials(const Context& ctx, const CallContext& cc, const SharedPtr<Peer>& to, const NetworkConfig& nconf);
void
pushCredentials(const Context &ctx, const CallContext &cc, const SharedPtr<Peer> &to, const NetworkConfig &nconf);
/**
* @return Time we last pushed credentials to this member
*/
ZT_INLINE int64_t lastPushedCredentials() const noexcept
{
return m_lastPushedCredentials;
}
ZT_INLINE int64_t lastPushedCredentials() const noexcept { return m_lastPushedCredentials; }
/**
* Get a remote member's tag (if we have it)
@ -65,10 +63,12 @@ class Member {
* @param id Tag ID
* @return Pointer to tag or NULL if not found
*/
ZT_INLINE const TagCredential* getTag(const NetworkConfig& nconf, const uint32_t id) const noexcept
ZT_INLINE const TagCredential *getTag(const NetworkConfig &nconf, const uint32_t id) const noexcept
{
Map<uint32_t, TagCredential>::const_iterator t(m_remoteTags.find(id));
return (((t != m_remoteTags.end()) && (m_isCredentialTimestampValid(nconf, t->second))) ? &(t->second) : (TagCredential*)0);
return (
((t != m_remoteTags.end()) && (m_isCredentialTimestampValid(nconf, t->second))) ? &(t->second)
: (TagCredential *)0);
}
/**
@ -76,12 +76,12 @@ class Member {
*
* @param nconf Current network configuration
*/
void clean(const NetworkConfig& nconf);
void clean(const NetworkConfig &nconf);
/**
* Generates a key for internal use in indexing credentials by type and credential ID
*/
static ZT_INLINE uint64_t credentialKey(const ZT_CredentialType& t, const uint32_t i) noexcept
static ZT_INLINE uint64_t credentialKey(const ZT_CredentialType &t, const uint32_t i) noexcept
{
return (((uint64_t)t << 32U) | (uint64_t)i);
}
@ -94,7 +94,7 @@ class Member {
* @param r Resource to check
* @return True if this peer has a certificate of ownership for the given resource
*/
template <typename T> ZT_INLINE bool peerOwnsAddress(const NetworkConfig& nconf, const T& r) const noexcept
template <typename T> ZT_INLINE bool peerOwnsAddress(const NetworkConfig &nconf, const T &r) const noexcept
{
if (m_isUnspoofableAddress(nconf, r))
return true;
@ -110,9 +110,10 @@ class Member {
*
* @param localCom
*/
ZT_INLINE bool certificateOfMembershipAgress(const MembershipCredential& localCom, const Identity& remoteIdentity)
ZT_INLINE bool certificateOfMembershipAgress(const MembershipCredential &localCom, const Identity &remoteIdentity)
{
if ((m_comAgreementLocalTimestamp == localCom.timestamp()) && (m_comAgreementRemoteTimestamp == m_com.timestamp()))
if ((m_comAgreementLocalTimestamp == localCom.timestamp())
&& (m_comAgreementRemoteTimestamp == m_com.timestamp()))
return true;
if (m_com.agreesWith(localCom)) {
// SECURITY: newer network controllers embed the full fingerprint into the COM. If we are
@ -134,7 +135,7 @@ class Member {
// Remember that these two COMs agreed. If any are updated this is invalidated and a full
// agreement check will be done again.
m_comAgreementLocalTimestamp = localCom.timestamp();
m_comAgreementLocalTimestamp = localCom.timestamp();
m_comAgreementRemoteTimestamp = m_com.timestamp();
return true;
@ -142,39 +143,49 @@ class Member {
return false;
}
AddCredentialResult addCredential(const Context& ctx, const CallContext& cc, const Identity& sourcePeerIdentity, const NetworkConfig& nconf, const MembershipCredential& com);
AddCredentialResult addCredential(const Context& ctx, const CallContext& cc, const Identity& sourcePeerIdentity, const NetworkConfig& nconf, const TagCredential& tag);
AddCredentialResult addCredential(const Context& ctx, const CallContext& cc, const Identity& sourcePeerIdentity, const NetworkConfig& nconf, const CapabilityCredential& cap);
AddCredentialResult addCredential(const Context& ctx, const CallContext& cc, const Identity& sourcePeerIdentity, const NetworkConfig& nconf, const OwnershipCredential& coo);
AddCredentialResult addCredential(const Context& ctx, const CallContext& cc, const Identity& sourcePeerIdentity, const NetworkConfig& nconf, const RevocationCredential& rev);
AddCredentialResult addCredential(
const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf,
const MembershipCredential &com);
AddCredentialResult addCredential(
const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf,
const TagCredential &tag);
AddCredentialResult addCredential(
const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf,
const CapabilityCredential &cap);
AddCredentialResult addCredential(
const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf,
const OwnershipCredential &coo);
AddCredentialResult addCredential(
const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf,
const RevocationCredential &rev);
private:
// 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
// always return true for them. A certificate is not required for these.
ZT_INLINE bool m_isUnspoofableAddress(const NetworkConfig& nconf, const MAC& m) const noexcept
{
return false;
}
ZT_INLINE 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
// plus or minus the permitted maximum timestamp delta.
template <typename C> ZT_INLINE bool m_isCredentialTimestampValid(const NetworkConfig& nconf, const C& remoteCredential) const noexcept
template <typename C>
ZT_INLINE bool m_isCredentialTimestampValid(const NetworkConfig &nconf, const C &remoteCredential) const noexcept
{
const int64_t ts = remoteCredential.revision();
if (((ts >= nconf.timestamp) ? (ts - nconf.timestamp) : (nconf.timestamp - ts)) <= nconf.credentialTimeMaxDelta) {
Map<uint64_t, int64_t>::const_iterator threshold(m_revocations.find(credentialKey(C::credentialType(), remoteCredential.id())));
if (((ts >= nconf.timestamp) ? (ts - nconf.timestamp) : (nconf.timestamp - ts))
<= nconf.credentialTimeMaxDelta) {
Map<uint64_t, int64_t>::const_iterator threshold(
m_revocations.find(credentialKey(C::credentialType(), remoteCredential.id())));
return ((threshold == m_revocations.end()) || (ts > threshold->second));
}
return false;
}
template <typename C> ZT_INLINE void m_cleanCredImpl(const NetworkConfig& nconf, Map<uint32_t, C>& remoteCreds)
template <typename C> ZT_INLINE void m_cleanCredImpl(const NetworkConfig &nconf, Map<uint32_t, C> &remoteCreds)
{
for (typename Map<uint32_t, C>::iterator i(remoteCreds.begin()); i != remoteCreds.end();) {
if (! m_isCredentialTimestampValid(nconf, i->second))
if (!m_isCredentialTimestampValid(nconf, i->second))
remoteCreds.erase(i++);
else
++i;
@ -204,14 +215,14 @@ class Member {
public:
class CapabilityIterator {
public:
ZT_INLINE CapabilityIterator(Member& m, const NetworkConfig& nconf) noexcept
ZT_INLINE CapabilityIterator(Member &m, const NetworkConfig &nconf) noexcept
: m_hti(m.m_remoteCaps.begin())
, m_parent(m)
, m_nconf(nconf)
{
}
ZT_INLINE CapabilityCredential* next() noexcept
ZT_INLINE CapabilityCredential *next() noexcept
{
while (m_hti != m_parent.m_remoteCaps.end()) {
Map<uint32_t, CapabilityCredential>::iterator i(m_hti++);
@ -223,8 +234,8 @@ class Member {
private:
Map<uint32_t, CapabilityCredential>::iterator m_hti;
Member& m_parent;
const NetworkConfig& m_nconf;
Member &m_parent;
const NetworkConfig &m_nconf;
};
};

View file

@ -16,12 +16,10 @@
namespace ZeroTier {
MembershipCredential::MembershipCredential(
const int64_t timestamp,
const int64_t timestampMaxDelta,
const uint64_t nwid,
const Identity& issuedTo) noexcept
const int64_t timestamp, const int64_t timestampMaxDelta, const uint64_t nwid,
const Identity &issuedTo) noexcept
: // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
m_timestamp(timestamp)
m_timestamp(timestamp)
, m_timestampMaxDelta(timestampMaxDelta)
, m_networkId(nwid)
, m_issuedTo(issuedTo.fingerprint())
@ -29,7 +27,7 @@ MembershipCredential::MembershipCredential(
{
}
bool MembershipCredential::agreesWith(const MembershipCredential& other) const noexcept
bool MembershipCredential::agreesWith(const MembershipCredential &other) const noexcept
{
// NOTE: we always do explicit absolute value with an if() since llabs() can have overflow
// conditions that could introduce a vulnerability.
@ -44,16 +42,20 @@ bool MembershipCredential::agreesWith(const MembershipCredential& other) const n
}
// us <> them
for (FCV<p_Qualifier, ZT_MEMBERSHIP_CREDENTIAL_MAX_ADDITIONAL_QUALIFIERS>::const_iterator i(m_additionalQualifiers.begin()); i != m_additionalQualifiers.end(); ++i) {
for (FCV<p_Qualifier, ZT_MEMBERSHIP_CREDENTIAL_MAX_ADDITIONAL_QUALIFIERS>::const_iterator i(
m_additionalQualifiers.begin());
i != m_additionalQualifiers.end(); ++i) {
if (i->delta != 0xffffffffffffffffULL) {
const uint64_t* v2 = nullptr;
for (FCV<p_Qualifier, ZT_MEMBERSHIP_CREDENTIAL_MAX_ADDITIONAL_QUALIFIERS>::const_iterator j(other.m_additionalQualifiers.begin()); j != other.m_additionalQualifiers.end(); ++i) {
const uint64_t *v2 = nullptr;
for (FCV<p_Qualifier, ZT_MEMBERSHIP_CREDENTIAL_MAX_ADDITIONAL_QUALIFIERS>::const_iterator j(
other.m_additionalQualifiers.begin());
j != other.m_additionalQualifiers.end(); ++i) {
if (j->id == i->id) {
v2 = &(j->value);
break;
}
}
if (! v2)
if (!v2)
return false;
if (*v2 > i->value) {
if ((*v2 - i->value) > i->delta)
@ -67,16 +69,20 @@ bool MembershipCredential::agreesWith(const MembershipCredential& other) const n
}
// them <> us (we need a second pass in case they have qualifiers we don't or vice versa)
for (FCV<p_Qualifier, ZT_MEMBERSHIP_CREDENTIAL_MAX_ADDITIONAL_QUALIFIERS>::const_iterator i(other.m_additionalQualifiers.begin()); i != other.m_additionalQualifiers.end(); ++i) {
for (FCV<p_Qualifier, ZT_MEMBERSHIP_CREDENTIAL_MAX_ADDITIONAL_QUALIFIERS>::const_iterator i(
other.m_additionalQualifiers.begin());
i != other.m_additionalQualifiers.end(); ++i) {
if (i->delta != 0xffffffffffffffffULL) {
const uint64_t* v2 = nullptr;
for (FCV<p_Qualifier, ZT_MEMBERSHIP_CREDENTIAL_MAX_ADDITIONAL_QUALIFIERS>::const_iterator j(m_additionalQualifiers.begin()); j != m_additionalQualifiers.end(); ++i) {
const uint64_t *v2 = nullptr;
for (FCV<p_Qualifier, ZT_MEMBERSHIP_CREDENTIAL_MAX_ADDITIONAL_QUALIFIERS>::const_iterator j(
m_additionalQualifiers.begin());
j != m_additionalQualifiers.end(); ++i) {
if (j->id == i->id) {
v2 = &(j->value);
break;
}
}
if (! v2)
if (!v2)
return false;
if (*v2 > i->value) {
if ((*v2 - i->value) > i->delta)
@ -94,12 +100,12 @@ bool MembershipCredential::agreesWith(const MembershipCredential& other) const n
return (other.m_networkId == m_networkId) && (m_networkId != 0) && (other.m_issuedTo.address != m_issuedTo.address);
}
bool MembershipCredential::sign(const Identity& with) noexcept
bool MembershipCredential::sign(const Identity &with) noexcept
{
m_signedBy = with.address();
uint64_t buf[ZT_MEMBERSHIP_CREDENTIAL_MARSHAL_SIZE_MAX / 8];
const unsigned int bufSize = m_fillSigningBuf(buf);
m_signatureLength = with.sign(buf, bufSize, m_signature, sizeof(m_signature));
m_signatureLength = with.sign(buf, bufSize, m_signature, sizeof(m_signature));
return m_signatureLength > 0;
}
@ -132,7 +138,8 @@ int MembershipCredential::marshal(uint8_t data[ZT_MEMBERSHIP_CREDENTIAL_MARSHAL_
Utils::storeBigEndian<uint16_t>(data + 1, 9);
for (int k = 0; k < 6; ++k) {
Utils::storeBigEndian<uint64_t>(data + p, (uint64_t)k + 3);
Utils::storeMachineEndian<uint64_t>(data + p + 8, Utils::loadMachineEndian<uint64_t>(m_issuedTo.hash + (k * 8)));
Utils::storeMachineEndian<uint64_t>(
data + p + 8, Utils::loadMachineEndian<uint64_t>(m_issuedTo.hash + (k * 8)));
Utils::storeMachineEndian<uint64_t>(data + p + 16, 0xffffffffffffffffULL);
p += 24;
}
@ -157,7 +164,7 @@ int MembershipCredential::marshal(uint8_t data[ZT_MEMBERSHIP_CREDENTIAL_MARSHAL_
return p;
}
int MembershipCredential::unmarshal(const uint8_t* data, int len) noexcept
int MembershipCredential::unmarshal(const uint8_t *data, int len) noexcept
{
if (len < (1 + 2 + 72))
return -1;
@ -179,35 +186,21 @@ int MembershipCredential::unmarshal(const uint8_t* data, int len) noexcept
p += 8; // NOLINT(hicpp-use-auto,modernize-use-auto)
switch (id) {
case 0:
m_timestamp = (int64_t)value;
m_timestamp = (int64_t)value;
m_timestampMaxDelta = (int64_t)delta;
break;
case 1:
m_networkId = value;
break;
case 1: m_networkId = value; break;
case 2:
m_issuedTo.address = value;
break;
// V1 nodes will pack the hash into qualifier tuples.
case 3:
Utils::storeBigEndian<uint64_t>(m_issuedTo.hash, value);
break;
case 4:
Utils::storeBigEndian<uint64_t>(m_issuedTo.hash + 8, value);
break;
case 5:
Utils::storeBigEndian<uint64_t>(m_issuedTo.hash + 16, value);
break;
case 6:
Utils::storeBigEndian<uint64_t>(m_issuedTo.hash + 24, value);
break;
case 7:
Utils::storeBigEndian<uint64_t>(m_issuedTo.hash + 32, value);
break;
case 8:
Utils::storeBigEndian<uint64_t>(m_issuedTo.hash + 40, value);
break;
case 3: Utils::storeBigEndian<uint64_t>(m_issuedTo.hash, value); break;
case 4: Utils::storeBigEndian<uint64_t>(m_issuedTo.hash + 8, value); break;
case 5: Utils::storeBigEndian<uint64_t>(m_issuedTo.hash + 16, value); break;
case 6: Utils::storeBigEndian<uint64_t>(m_issuedTo.hash + 24, value); break;
case 7: Utils::storeBigEndian<uint64_t>(m_issuedTo.hash + 32, value); break;
case 8: Utils::storeBigEndian<uint64_t>(m_issuedTo.hash + 40, value); break;
default:
if (m_additionalQualifiers.size() >= ZT_MEMBERSHIP_CREDENTIAL_MAX_ADDITIONAL_QUALIFIERS)
@ -243,7 +236,7 @@ int MembershipCredential::unmarshal(const uint8_t* data, int len) noexcept
return -1;
}
unsigned int MembershipCredential::m_fillSigningBuf(uint64_t* buf) const noexcept
unsigned int MembershipCredential::m_fillSigningBuf(uint64_t *buf) const noexcept
{
const uint64_t informational = 0xffffffffffffffffULL;
@ -289,7 +282,9 @@ unsigned int MembershipCredential::m_fillSigningBuf(uint64_t* buf) const noexcep
buf[p++] = informational;
}
for (FCV<p_Qualifier, ZT_MEMBERSHIP_CREDENTIAL_MAX_ADDITIONAL_QUALIFIERS>::const_iterator i(m_additionalQualifiers.begin()); i != m_additionalQualifiers.end(); ++i) { // NOLINT(modernize-loop-convert)
for (FCV<p_Qualifier, ZT_MEMBERSHIP_CREDENTIAL_MAX_ADDITIONAL_QUALIFIERS>::const_iterator i(
m_additionalQualifiers.begin());
i != m_additionalQualifiers.end(); ++i) { // NOLINT(modernize-loop-convert)
buf[p++] = Utils::hton(i->id);
buf[p++] = Utils::hton(i->value);
buf[p++] = Utils::hton(i->delta);

View file

@ -30,7 +30,8 @@
#define ZT_MEMBERSHIP_CREDENTIAL_MAX_ADDITIONAL_QUALIFIERS 8
// version + qualifier count + three required qualifiers + additional qualifiers +
#define ZT_MEMBERSHIP_CREDENTIAL_MARSHAL_SIZE_MAX (1 + 2 + (3 * 3 * 8) + (ZT_MEMBERSHIP_CREDENTIAL_MAX_ADDITIONAL_QUALIFIERS * 3 * 8) + 144 + 5 + 2 + 96)
#define ZT_MEMBERSHIP_CREDENTIAL_MARSHAL_SIZE_MAX \
(1 + 2 + (3 * 3 * 8) + (ZT_MEMBERSHIP_CREDENTIAL_MAX_ADDITIONAL_QUALIFIERS * 3 * 8) + 144 + 5 + 2 + 96)
namespace ZeroTier {
@ -100,18 +101,12 @@ class MembershipCredential : public Credential {
friend class Credential;
public:
static constexpr ZT_CredentialType credentialType() noexcept
{
return ZT_CREDENTIAL_TYPE_COM;
}
static constexpr ZT_CredentialType credentialType() noexcept { return ZT_CREDENTIAL_TYPE_COM; }
/**
* Create an empty certificate of membership
*/
ZT_INLINE MembershipCredential() noexcept
{
memoryZero(this);
}
ZT_INLINE MembershipCredential() noexcept { memoryZero(this); }
/**
* Create from required fields common to all networks
@ -121,60 +116,40 @@ class MembershipCredential : public Credential {
* @param nwid Network ID
* @param issuedTo Certificate recipient
*/
MembershipCredential(int64_t timestamp, int64_t timestampMaxDelta, uint64_t nwid, const Identity& issuedTo) noexcept;
MembershipCredential(
int64_t timestamp, int64_t timestampMaxDelta, uint64_t nwid, const Identity &issuedTo) noexcept;
/**
* @return True if there's something here
*/
ZT_INLINE operator bool() const noexcept
{
return (m_networkId != 0);
}
ZT_INLINE operator bool() const noexcept { return (m_networkId != 0); }
/**
* @return Credential ID, always 0 for COMs
*/
ZT_INLINE uint32_t id() const noexcept
{
return 0;
}
ZT_INLINE uint32_t id() const noexcept { return 0; }
/**
* @return Timestamp for this cert and maximum delta for timestamp
*/
ZT_INLINE int64_t timestamp() const noexcept
{
return m_timestamp;
}
ZT_INLINE int64_t timestamp() const noexcept { return m_timestamp; }
ZT_INLINE int64_t revision() const noexcept
{
return m_timestamp;
}
ZT_INLINE int64_t revision() const noexcept { return m_timestamp; }
/**
* @return Maximum allowed difference between timestamps
*/
ZT_INLINE int64_t timestampMaxDelta() const noexcept
{
return m_timestampMaxDelta;
}
ZT_INLINE int64_t timestampMaxDelta() const noexcept { return m_timestampMaxDelta; }
/**
* @return Fingerprint of identity to which this cert was issued
*/
ZT_INLINE const Fingerprint& issuedTo() const noexcept
{
return m_issuedTo;
}
ZT_INLINE const Fingerprint &issuedTo() const noexcept { return m_issuedTo; }
/**
* @return Network ID for which this cert was issued
*/
ZT_INLINE uint64_t networkId() const noexcept
{
return m_networkId;
}
ZT_INLINE uint64_t networkId() const noexcept { return m_networkId; }
/**
* Compare two certificates for parameter agreement
@ -189,7 +164,7 @@ class MembershipCredential : public Credential {
* @param other Cert to compare with
* @return True if certs agree and 'other' may be communicated with
*/
bool agreesWith(const MembershipCredential& other) const noexcept;
bool agreesWith(const MembershipCredential &other) const noexcept;
/**
* Sign this certificate
@ -197,7 +172,7 @@ class MembershipCredential : public Credential {
* @param with Identity to sign with, must include private key
* @return True if signature was successful
*/
bool sign(const Identity& with) noexcept;
bool sign(const Identity &with) noexcept;
/**
* Verify this COM and its signature
@ -205,29 +180,21 @@ class MembershipCredential : public Credential {
* @param RR Runtime environment for looking up peers
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
*/
ZT_INLINE Credential::VerifyResult verify(const Context& ctx, const CallContext& cc) const
ZT_INLINE Credential::VerifyResult verify(const Context &ctx, const CallContext &cc) const
{
return s_verify(ctx, cc, *this);
}
static constexpr int marshalSizeMax() noexcept
{
return ZT_MEMBERSHIP_CREDENTIAL_MARSHAL_SIZE_MAX;
}
static constexpr int marshalSizeMax() noexcept { return ZT_MEMBERSHIP_CREDENTIAL_MARSHAL_SIZE_MAX; }
int marshal(uint8_t data[ZT_MEMBERSHIP_CREDENTIAL_MARSHAL_SIZE_MAX], bool v2 = false) const noexcept;
int unmarshal(const uint8_t* data, int len) noexcept;
int unmarshal(const uint8_t *data, int len) noexcept;
private:
unsigned int m_fillSigningBuf(uint64_t* buf) const noexcept;
unsigned int m_fillSigningBuf(uint64_t *buf) const noexcept;
struct p_Qualifier {
ZT_INLINE p_Qualifier() noexcept
: id(0)
, value(0)
, delta(0)
{
}
ZT_INLINE p_Qualifier() noexcept : id(0), value(0), delta(0) {}
ZT_INLINE p_Qualifier(const uint64_t id_, const uint64_t value_, const uint64_t delta_) noexcept
: id(id_)
@ -239,10 +206,7 @@ class MembershipCredential : public Credential {
uint64_t id;
uint64_t value;
uint64_t delta;
ZT_INLINE bool operator<(const p_Qualifier& q) const noexcept
{
return (id < q.id);
} // sort order
ZT_INLINE bool operator<(const p_Qualifier &q) const noexcept { return (id < q.id); } // sort order
};
FCV<p_Qualifier, ZT_MEMBERSHIP_CREDENTIAL_MAX_ADDITIONAL_QUALIFIERS> m_additionalQualifiers;

View file

@ -41,9 +41,7 @@ template <int64_t TUNIT = 1000, unsigned long LSIZE = 10> class Meter {
*
* @param now Start time
*/
ZT_INLINE Meter() noexcept
{
}
ZT_INLINE Meter() noexcept {}
/**
* Add a measurement
@ -58,7 +56,8 @@ template <int64_t TUNIT = 1000, unsigned long LSIZE = 10> class Meter {
// to it.
const unsigned long bucket = ((unsigned long)(ts / TUNIT)) % LSIZE;
if (unlikely(m_bucket.exchange(bucket, std::memory_order_relaxed) != bucket)) {
m_totalExclCounts.fetch_add(m_counts[bucket].exchange(count, std::memory_order_relaxed), std::memory_order_relaxed);
m_totalExclCounts.fetch_add(
m_counts[bucket].exchange(count, std::memory_order_relaxed), std::memory_order_relaxed);
}
else {
m_counts[bucket].fetch_add(count, std::memory_order_relaxed);
@ -72,7 +71,7 @@ template <int64_t TUNIT = 1000, unsigned long LSIZE = 10> class Meter {
* @param rate Result parameter: rate in count/TUNIT
* @param total Total count for life of object
*/
ZT_INLINE void rate(double& rate, uint64_t& total) const noexcept
ZT_INLINE void rate(double &rate, uint64_t &total) const noexcept
{
total = 0;
for (unsigned long i = 0; i < LSIZE; ++i)

View file

@ -39,17 +39,9 @@ namespace ZeroTier {
*/
class MulticastGroup : public TriviallyCopyable {
public:
ZT_INLINE MulticastGroup() noexcept
: m_mac()
, m_adi(0)
{
}
ZT_INLINE MulticastGroup() noexcept : m_mac(), m_adi(0) {}
ZT_INLINE MulticastGroup(const MAC& m, uint32_t a) noexcept
: m_mac(m)
, m_adi(a)
{
}
ZT_INLINE MulticastGroup(const MAC &m, uint32_t a) noexcept : m_mac(m), m_adi(a) {}
/**
* Derive the multicast group used for address resolution (ARP/NDP) for an IP
@ -57,21 +49,22 @@ class MulticastGroup : public TriviallyCopyable {
* @param ip IP address (port field is ignored)
* @return Multicast group for ARP/NDP
*/
static ZT_INLINE MulticastGroup deriveMulticastGroupForAddressResolution(const InetAddress& ip) noexcept
static ZT_INLINE MulticastGroup deriveMulticastGroupForAddressResolution(const InetAddress &ip) noexcept
{
if (ip.isV4()) {
// IPv4 wants broadcast MACs, so we shove the V4 address itself into
// the Multicast Group ADI field. Making V4 ARP work is basically why
// ADI was added, as well as handling other things that want mindless
// Ethernet broadcast to all.
return MulticastGroup(MAC(0xffffffffffffULL), Utils::ntoh(*((const uint32_t*)ip.rawIpData())));
return MulticastGroup(MAC(0xffffffffffffULL), Utils::ntoh(*((const uint32_t *)ip.rawIpData())));
}
else if (ip.isV6()) {
// IPv6 is better designed in this respect. We can compute the IPv6
// multicast address directly from the IP address, and it gives us
// 24 bits of uniqueness. Collisions aren't likely to be common enough
// to care about.
const uint8_t* const a = reinterpret_cast<const uint8_t*>(ip.rawIpData()); // NOLINT(hicpp-use-auto,modernize-use-auto)
const uint8_t *const a =
reinterpret_cast<const uint8_t *>(ip.rawIpData()); // NOLINT(hicpp-use-auto,modernize-use-auto)
return MulticastGroup(MAC(0x33, 0x33, 0xff, a[13], a[14], a[15]), 0);
}
return MulticastGroup(); // NOLINT(modernize-return-braced-init-list)
@ -80,31 +73,25 @@ class MulticastGroup : public TriviallyCopyable {
/**
* @return Ethernet MAC portion of multicast group
*/
ZT_INLINE const MAC& mac() const noexcept
{
return m_mac;
}
ZT_INLINE const MAC &mac() const noexcept { return m_mac; }
/**
* @return Additional distinguishing information, which is normally zero except for IPv4 ARP where it's the IPv4
* address
*/
ZT_INLINE uint32_t adi() const
{
return m_adi;
}
ZT_INLINE uint32_t adi() const { return m_adi; }
ZT_INLINE bool operator==(const MulticastGroup& g) const noexcept
ZT_INLINE bool operator==(const MulticastGroup &g) const noexcept
{
return ((m_mac == g.m_mac) && (m_adi == g.m_adi));
}
ZT_INLINE bool operator!=(const MulticastGroup& g) const noexcept
ZT_INLINE bool operator!=(const MulticastGroup &g) const noexcept
{
return ((m_mac != g.m_mac) || (m_adi != g.m_adi));
}
ZT_INLINE bool operator<(const MulticastGroup& g) const noexcept
ZT_INLINE bool operator<(const MulticastGroup &g) const noexcept
{
if (m_mac < g.m_mac)
return true;
@ -113,25 +100,13 @@ class MulticastGroup : public TriviallyCopyable {
return false;
}
ZT_INLINE bool operator>(const MulticastGroup& g) const noexcept
{
return (g < *this);
}
ZT_INLINE bool operator>(const MulticastGroup &g) const noexcept { return (g < *this); }
ZT_INLINE bool operator<=(const MulticastGroup& g) const noexcept
{
return ! (g < *this);
}
ZT_INLINE bool operator<=(const MulticastGroup &g) const noexcept { return !(g < *this); }
ZT_INLINE bool operator>=(const MulticastGroup& g) const noexcept
{
return ! (*this < g);
}
ZT_INLINE bool operator>=(const MulticastGroup &g) const noexcept { return !(*this < g); }
ZT_INLINE unsigned long hashCode() const noexcept
{
return (m_mac.hashCode() + (unsigned long)m_adi);
}
ZT_INLINE unsigned long hashCode() const noexcept { return (m_mac.hashCode() + (unsigned long)m_adi); }
private:
MAC m_mac;

View file

@ -39,63 +39,29 @@ namespace ZeroTier {
class Mutex {
public:
#ifdef ZT_USE_PTHREADS
ZT_INLINE Mutex() noexcept
{
pthread_mutex_init(&_mh, nullptr);
}
ZT_INLINE ~Mutex() noexcept
{
pthread_mutex_destroy(&_mh);
}
ZT_INLINE void lock() const noexcept
{
pthread_mutex_lock(&((const_cast<Mutex*>(this))->_mh));
}
ZT_INLINE void unlock() const noexcept
{
pthread_mutex_unlock(&((const_cast<Mutex*>(this))->_mh));
}
ZT_INLINE Mutex() noexcept { pthread_mutex_init(&_mh, nullptr); }
ZT_INLINE ~Mutex() noexcept { pthread_mutex_destroy(&_mh); }
ZT_INLINE void lock() const noexcept { pthread_mutex_lock(&((const_cast<Mutex *>(this))->_mh)); }
ZT_INLINE void unlock() const noexcept { pthread_mutex_unlock(&((const_cast<Mutex *>(this))->_mh)); }
#else
ZT_INLINE Mutex() noexcept : _m()
{
}
ZT_INLINE void lock() const noexcept
{
const_cast<Mutex*>(this)->_m.lock();
}
ZT_INLINE void unlock() const noexcept
{
const_cast<Mutex*>(this)->_m.unlock();
}
ZT_INLINE Mutex() noexcept : _m() {}
ZT_INLINE void lock() const noexcept { const_cast<Mutex *>(this)->_m.lock(); }
ZT_INLINE void unlock() const noexcept { const_cast<Mutex *>(this)->_m.unlock(); }
#endif
class Lock {
public:
explicit ZT_INLINE Lock(Mutex& m) noexcept : _m(&m)
{
m.lock();
}
explicit ZT_INLINE Lock(const Mutex& m) noexcept : _m(const_cast<Mutex*>(&m))
{
_m->lock();
}
ZT_INLINE ~Lock()
{
_m->unlock();
}
explicit ZT_INLINE Lock(Mutex &m) noexcept : _m(&m) { m.lock(); }
explicit ZT_INLINE Lock(const Mutex &m) noexcept : _m(const_cast<Mutex *>(&m)) { _m->lock(); }
ZT_INLINE ~Lock() { _m->unlock(); }
private:
Mutex* const _m;
Mutex *const _m;
};
private:
ZT_INLINE Mutex(const Mutex&) noexcept
{
}
ZT_INLINE const Mutex& operator=(const Mutex&) noexcept
{
return *this;
}
ZT_INLINE Mutex(const Mutex &) noexcept {}
ZT_INLINE const Mutex &operator=(const Mutex &) noexcept { return *this; }
#ifdef ZT_USE_PTHREADS
pthread_mutex_t _mh;
@ -110,50 +76,18 @@ class Mutex {
class RWMutex {
public:
#ifdef ZT_USE_PTHREADS
ZT_INLINE RWMutex() noexcept
{
pthread_rwlock_init(&_mh, nullptr);
}
ZT_INLINE ~RWMutex() noexcept
{
pthread_rwlock_destroy(&_mh);
}
ZT_INLINE void lock() const noexcept
{
pthread_rwlock_wrlock(&((const_cast<RWMutex*>(this))->_mh));
}
ZT_INLINE void rlock() const noexcept
{
pthread_rwlock_rdlock(&((const_cast<RWMutex*>(this))->_mh));
}
ZT_INLINE void unlock() const noexcept
{
pthread_rwlock_unlock(&((const_cast<RWMutex*>(this))->_mh));
}
ZT_INLINE void runlock() const noexcept
{
pthread_rwlock_unlock(&((const_cast<RWMutex*>(this))->_mh));
}
ZT_INLINE RWMutex() noexcept { pthread_rwlock_init(&_mh, nullptr); }
ZT_INLINE ~RWMutex() noexcept { pthread_rwlock_destroy(&_mh); }
ZT_INLINE void lock() const noexcept { pthread_rwlock_wrlock(&((const_cast<RWMutex *>(this))->_mh)); }
ZT_INLINE void rlock() const noexcept { pthread_rwlock_rdlock(&((const_cast<RWMutex *>(this))->_mh)); }
ZT_INLINE void unlock() const noexcept { pthread_rwlock_unlock(&((const_cast<RWMutex *>(this))->_mh)); }
ZT_INLINE void runlock() const noexcept { pthread_rwlock_unlock(&((const_cast<RWMutex *>(this))->_mh)); }
#else
ZT_INLINE RWMutex() noexcept : _m()
{
}
ZT_INLINE void lock() const noexcept
{
const_cast<RWMutex*>(this)->_m.lock();
}
ZT_INLINE void rlock() const noexcept
{
const_cast<RWMutex*>(this)->_m.lock_shared();
}
ZT_INLINE void unlock() const noexcept
{
const_cast<RWMutex*>(this)->_m.unlock();
}
ZT_INLINE void runlock() const noexcept
{
const_cast<RWMutex*>(this)->_m.unlock_shared();
}
ZT_INLINE RWMutex() noexcept : _m() {}
ZT_INLINE void lock() const noexcept { const_cast<RWMutex *>(this)->_m.lock(); }
ZT_INLINE void rlock() const noexcept { const_cast<RWMutex *>(this)->_m.lock_shared(); }
ZT_INLINE void unlock() const noexcept { const_cast<RWMutex *>(this)->_m.unlock(); }
ZT_INLINE void runlock() const noexcept { const_cast<RWMutex *>(this)->_m.unlock_shared(); }
#endif
/**
@ -161,21 +95,12 @@ class RWMutex {
*/
class RLock {
public:
explicit ZT_INLINE RLock(RWMutex& m) noexcept : _m(&m)
{
m.rlock();
}
explicit ZT_INLINE RLock(const RWMutex& m) noexcept : _m(const_cast<RWMutex*>(&m))
{
_m->rlock();
}
ZT_INLINE ~RLock()
{
_m->runlock();
}
explicit ZT_INLINE RLock(RWMutex &m) noexcept : _m(&m) { m.rlock(); }
explicit ZT_INLINE RLock(const RWMutex &m) noexcept : _m(const_cast<RWMutex *>(&m)) { _m->rlock(); }
ZT_INLINE ~RLock() { _m->runlock(); }
private:
RWMutex* const _m;
RWMutex *const _m;
};
/**
@ -183,21 +108,12 @@ class RWMutex {
*/
class Lock {
public:
explicit ZT_INLINE Lock(RWMutex& m) noexcept : _m(&m)
{
m.lock();
}
explicit ZT_INLINE Lock(const RWMutex& m) noexcept : _m(const_cast<RWMutex*>(&m))
{
_m->lock();
}
ZT_INLINE ~Lock()
{
_m->unlock();
}
explicit ZT_INLINE Lock(RWMutex &m) noexcept : _m(&m) { m.lock(); }
explicit ZT_INLINE Lock(const RWMutex &m) noexcept : _m(const_cast<RWMutex *>(&m)) { _m->lock(); }
ZT_INLINE ~Lock() { _m->unlock(); }
private:
RWMutex* const _m;
RWMutex *const _m;
};
/**
@ -211,21 +127,14 @@ class RWMutex {
*/
class RMaybeWLock {
public:
explicit ZT_INLINE RMaybeWLock(RWMutex& m) noexcept
: _m(&m)
, _w(false)
{
m.rlock();
}
explicit ZT_INLINE RMaybeWLock(const RWMutex& m) noexcept
: _m(const_cast<RWMutex*>(&m))
, _w(false)
explicit ZT_INLINE RMaybeWLock(RWMutex &m) noexcept : _m(&m), _w(false) { m.rlock(); }
explicit ZT_INLINE RMaybeWLock(const RWMutex &m) noexcept : _m(const_cast<RWMutex *>(&m)), _w(false)
{
_m->rlock();
}
ZT_INLINE void writing() noexcept
{
if (! _w) {
if (!_w) {
_w = true;
_m->runlock();
_m->lock();
@ -239,10 +148,7 @@ class RWMutex {
_m->rlock();
}
}
ZT_INLINE bool isWriting() const noexcept
{
return _w;
}
ZT_INLINE bool isWriting() const noexcept { return _w; }
ZT_INLINE ~RMaybeWLock()
{
if (_w)
@ -252,18 +158,13 @@ class RWMutex {
}
private:
RWMutex* const _m;
RWMutex *const _m;
bool _w;
};
private:
ZT_INLINE RWMutex(const RWMutex&) noexcept
{
}
ZT_INLINE const RWMutex& operator=(const RWMutex&) noexcept
{
return *this;
}
ZT_INLINE RWMutex(const RWMutex &) noexcept {}
ZT_INLINE const RWMutex &operator=(const RWMutex &) noexcept { return *this; }
#ifdef ZT_USE_PTHREADS
pthread_rwlock_t _mh;

File diff suppressed because it is too large Load diff

View file

@ -51,10 +51,7 @@ class Network {
/**
* Compute primary controller device ID from network ID
*/
static ZT_INLINE Address controllerFor(uint64_t nwid) noexcept
{
return Address(nwid >> 24U);
}
static ZT_INLINE Address controllerFor(uint64_t nwid) noexcept { return Address(nwid >> 24U); }
/**
* Construct a new network
@ -67,49 +64,27 @@ class Network {
* @param uptr Arbitrary pointer used by externally-facing API (for user use)
* @param nconf Network config, if known
*/
Network(const Context& ctx, const CallContext& cc, uint64_t nwid, const Fingerprint& controllerFingerprint, void* uptr, const NetworkConfig* nconf);
Network(
const Context &ctx, const CallContext &cc, uint64_t nwid, const Fingerprint &controllerFingerprint, void *uptr,
const NetworkConfig *nconf);
~Network();
ZT_INLINE uint64_t id() const noexcept
{
return m_id;
}
ZT_INLINE uint64_t id() const noexcept { return m_id; }
ZT_INLINE Address controller() const noexcept
{
return Address(m_id >> 24U);
}
ZT_INLINE Address controller() const noexcept { return Address(m_id >> 24U); }
ZT_INLINE bool multicastEnabled() const noexcept
{
return (m_config.multicastLimit > 0);
}
ZT_INLINE bool multicastEnabled() const noexcept { return (m_config.multicastLimit > 0); }
ZT_INLINE bool hasConfig() const noexcept
{
return (m_config);
}
ZT_INLINE bool hasConfig() const noexcept { return (m_config); }
ZT_INLINE uint64_t lastConfigUpdate() const noexcept
{
return m_lastConfigUpdate;
}
ZT_INLINE uint64_t lastConfigUpdate() const noexcept { return m_lastConfigUpdate; }
ZT_INLINE ZT_VirtualNetworkStatus status() const noexcept
{
return m_status();
}
ZT_INLINE ZT_VirtualNetworkStatus status() const noexcept { return m_status(); }
ZT_INLINE const NetworkConfig& config() const noexcept
{
return m_config;
}
ZT_INLINE const NetworkConfig &config() const noexcept { return m_config; }
ZT_INLINE const MAC& mac() const noexcept
{
return m_mac;
}
ZT_INLINE const MAC &mac() const noexcept { return m_mac; }
/**
* Apply filters to an outgoing packet
@ -131,17 +106,9 @@ class Network {
* @return True if packet should be sent, false if dropped or redirected
*/
bool filterOutgoingPacket(
const CallContext& cc,
bool noTee,
const Address& ztSource,
const Address& ztDest,
const MAC& macSource,
const MAC& macDest,
const uint8_t* frameData,
unsigned int frameLen,
unsigned int etherType,
unsigned int vlanId,
uint8_t& qosBucket);
const CallContext &cc, bool noTee, const Address &ztSource, const Address &ztDest, const MAC &macSource,
const MAC &macDest, const uint8_t *frameData, unsigned int frameLen, unsigned int etherType,
unsigned int vlanId, uint8_t &qosBucket);
/**
* Apply filters to an incoming packet
@ -162,14 +129,8 @@ class Network {
* @return 0 == drop, 1 == accept, 2 == accept even if bridged
*/
int filterIncomingPacket(
const CallContext& cc,
const SharedPtr<Peer>& sourcePeer,
const Address& ztDest,
const MAC& macSource,
const MAC& macDest,
const uint8_t* frameData,
unsigned int frameLen,
unsigned int etherType,
const CallContext &cc, const SharedPtr<Peer> &sourcePeer, const Address &ztDest, const MAC &macSource,
const MAC &macDest, const uint8_t *frameData, unsigned int frameLen, unsigned int etherType,
unsigned int vlanId);
/**
@ -177,14 +138,14 @@ class Network {
*
* @param mg New multicast group
*/
void multicastSubscribe(const CallContext& cc, const MulticastGroup& mg);
void multicastSubscribe(const CallContext &cc, const MulticastGroup &mg);
/**
* Unsubscribe from a multicast group
*
* @param mg Multicast group
*/
void multicastUnsubscribe(const MulticastGroup& mg);
void multicastUnsubscribe(const MulticastGroup &mg);
/**
* Parse, verify, and handle an inbound network config chunk
@ -201,7 +162,8 @@ class Network {
* @param size Size of data in chunk buffer (total, not relative to ptr)
* @return Update ID if update was fully assembled and accepted or 0 otherwise
*/
uint64_t handleConfigChunk(const CallContext& cc, uint64_t packetId, const SharedPtr<Peer>& source, const Buf& chunk, int ptr, int size);
uint64_t handleConfigChunk(
const CallContext &cc, uint64_t packetId, const SharedPtr<Peer> &source, const Buf &chunk, int ptr, int size);
/**
* Set network configuration
@ -214,23 +176,17 @@ class Network {
* @param saveToDisk Save to disk? Used during loading, should usually be true otherwise.
* @return 0 == bad, 1 == accepted but duplicate/unchanged, 2 == accepted and new
*/
int setConfiguration(const CallContext& cc, const NetworkConfig& nconf, bool saveToDisk);
int setConfiguration(const CallContext &cc, const NetworkConfig &nconf, bool saveToDisk);
/**
* Set netconf failure to 'access denied' -- called in IncomingPacket when controller reports this
*/
ZT_INLINE void setAccessDenied() noexcept
{
_netconfFailure = NETCONF_FAILURE_ACCESS_DENIED;
}
ZT_INLINE void setAccessDenied() noexcept { _netconfFailure = NETCONF_FAILURE_ACCESS_DENIED; }
/**
* Set netconf failure to 'not found' -- called by IncomingPacket when controller reports this
*/
ZT_INLINE void setNotFound() noexcept
{
_netconfFailure = NETCONF_FAILURE_NOT_FOUND;
}
ZT_INLINE void setNotFound() noexcept { _netconfFailure = NETCONF_FAILURE_NOT_FOUND; }
/**
* Determine whether this peer is permitted to communicate on this network
@ -238,12 +194,12 @@ class Network {
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param peer Peer to check
*/
bool gate(void* tPtr, const SharedPtr<Peer>& peer) noexcept;
bool gate(void *tPtr, const SharedPtr<Peer> &peer) noexcept;
/**
* Do periodic cleanup and housekeeping tasks
*/
void doPeriodicTasks(const CallContext& cc);
void doPeriodicTasks(const CallContext &cc);
/**
* Find the node on this network that has this MAC behind it (if any)
@ -251,7 +207,7 @@ class Network {
* @param mac MAC address
* @return ZeroTier address of bridge to this MAC
*/
ZT_INLINE Address findBridgeTo(const MAC& mac) const
ZT_INLINE Address findBridgeTo(const MAC &mac) const
{
Mutex::Lock _l(m_remoteBridgeRoutes_l);
Map<MAC, Address>::const_iterator br(m_remoteBridgeRoutes.find(mac));
@ -264,7 +220,7 @@ class Network {
* @param mac MAC address of destination
* @param addr Bridge this MAC is reachable behind
*/
void learnBridgeRoute(const MAC& mac, const Address& addr);
void learnBridgeRoute(const MAC &mac, const Address &addr);
/**
* Learn a multicast group that is bridged to our tap device
@ -273,7 +229,7 @@ class Network {
* @param mg Multicast group
* @param now Current time
*/
ZT_INLINE void learnBridgedMulticastGroup(const MulticastGroup& mg, int64_t now)
ZT_INLINE void learnBridgedMulticastGroup(const MulticastGroup &mg, int64_t now)
{
Mutex::Lock l(m_myMulticastGroups_l);
m_multicastGroupsBehindMe[mg] = now;
@ -282,34 +238,39 @@ class Network {
/**
* Validate a credential and learn it if it passes certificate and other checks
*/
Member::AddCredentialResult addCredential(const CallContext& cc, const Identity& sourcePeerIdentity, const MembershipCredential& com);
Member::AddCredentialResult
addCredential(const CallContext &cc, const Identity &sourcePeerIdentity, const MembershipCredential &com);
/**
* Validate a credential and learn it if it passes certificate and other checks
*/
Member::AddCredentialResult addCredential(const CallContext& cc, const Identity& sourcePeerIdentity, const CapabilityCredential& cap);
Member::AddCredentialResult
addCredential(const CallContext &cc, const Identity &sourcePeerIdentity, const CapabilityCredential &cap);
/**
* Validate a credential and learn it if it passes certificate and other checks
*/
Member::AddCredentialResult addCredential(const CallContext& cc, const Identity& sourcePeerIdentity, const TagCredential& tag);
Member::AddCredentialResult
addCredential(const CallContext &cc, const Identity &sourcePeerIdentity, const TagCredential &tag);
/**
* Validate a credential and learn it if it passes certificate and other checks
*/
Member::AddCredentialResult addCredential(const CallContext& cc, const Identity& sourcePeerIdentity, const RevocationCredential& rev);
Member::AddCredentialResult
addCredential(const CallContext &cc, const Identity &sourcePeerIdentity, const RevocationCredential &rev);
/**
* Validate a credential and learn it if it passes certificate and other checks
*/
Member::AddCredentialResult addCredential(const CallContext& cc, const Identity& sourcePeerIdentity, const OwnershipCredential& coo);
Member::AddCredentialResult
addCredential(const CallContext &cc, const Identity &sourcePeerIdentity, const OwnershipCredential &coo);
/**
* Push credentials to a peer if timeouts indicate that we should do so
*
* @param to Destination peer
*/
void pushCredentials(const CallContext& cc, const SharedPtr<Peer>& to);
void pushCredentials(const CallContext &cc, const SharedPtr<Peer> &to);
/**
* Destroy this network
@ -324,7 +285,7 @@ class Network {
*
* @param ec Buffer to fill with externally-visible network configuration
*/
void externalConfig(ZT_VirtualNetworkConfig* ec) const;
void externalConfig(ZT_VirtualNetworkConfig *ec) const;
/**
* Iterate through memberships
@ -334,8 +295,9 @@ class Network {
template <typename F> ZT_INLINE void eachMember(F f)
{
Mutex::Lock ml(m_memberships_l);
for (Map<Address, Member>::iterator i(m_memberships.begin()); i != m_memberships.end(); ++i) { // NOLINT(modernize-loop-convert,hicpp-use-auto,modernize-use-auto)
if (! f(i->first, i->second))
for (Map<Address, Member>::iterator i(m_memberships.begin()); i != m_memberships.end();
++i) { // NOLINT(modernize-loop-convert,hicpp-use-auto,modernize-use-auto)
if (!f(i->first, i->second))
break;
}
}
@ -343,21 +305,18 @@ class Network {
/**
* @return Externally usable pointer-to-pointer exported via the core API
*/
ZT_INLINE void** userPtr() noexcept
{
return &m_uPtr;
}
ZT_INLINE void **userPtr() noexcept { return &m_uPtr; }
private:
void m_requestConfiguration(const CallContext& cc);
void m_requestConfiguration(const CallContext &cc);
ZT_VirtualNetworkStatus m_status() const;
void m_externalConfig(ZT_VirtualNetworkConfig* ec) const; // assumes _lock is locked
void m_announceMulticastGroups(void* tPtr, bool force);
void m_announceMulticastGroupsTo(void* tPtr, const Address& peer, const Vector<MulticastGroup>& allMulticastGroups);
void m_externalConfig(ZT_VirtualNetworkConfig *ec) const; // assumes _lock is locked
void m_announceMulticastGroups(void *tPtr, bool force);
void m_announceMulticastGroupsTo(void *tPtr, const Address &peer, const Vector<MulticastGroup> &allMulticastGroups);
Vector<MulticastGroup> m_allMulticastGroups() const;
const Context& m_ctx;
void* m_uPtr;
const Context &m_ctx;
void *m_uPtr;
const uint64_t m_id;
Fingerprint m_controllerFingerprint;
MAC m_mac; // local MAC address
@ -367,13 +326,18 @@ class Network {
Vector<MulticastGroup> m_myMulticastGroups; // multicast groups that we belong to (according to tap)
Map<MulticastGroup, int64_t> m_multicastGroupsBehindMe; // multicast groups that seem to be behind us and when we
// last saw them (if we are a bridge)
Map<MAC, Address> m_remoteBridgeRoutes; // remote addresses where given MACs are reachable (for tracking devices
// behind remote bridges)
Map<MAC, Address> m_remoteBridgeRoutes; // remote addresses where given MACs are reachable (for tracking devices
// behind remote bridges)
NetworkConfig m_config;
std::atomic<int64_t> m_lastConfigUpdate;
volatile enum { NETCONF_FAILURE_NONE, NETCONF_FAILURE_ACCESS_DENIED, NETCONF_FAILURE_NOT_FOUND, NETCONF_FAILURE_INIT_FAILED } _netconfFailure;
volatile enum {
NETCONF_FAILURE_NONE,
NETCONF_FAILURE_ACCESS_DENIED,
NETCONF_FAILURE_NOT_FOUND,
NETCONF_FAILURE_INIT_FAILED
} _netconfFailure;
Map<Address, Member> m_memberships;

View file

@ -21,7 +21,7 @@
namespace ZeroTier {
bool NetworkConfig::toDictionary(Dictionary& d) const
bool NetworkConfig::toDictionary(Dictionary &d) const
{
uint8_t tmp[ZT_BUF_MEM_SIZE];
try {
@ -31,8 +31,9 @@ bool NetworkConfig::toDictionary(Dictionary& d) const
d.add(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP, this->timestamp);
d.add(ZT_NETWORKCONFIG_DICT_KEY_CREDENTIAL_TIME_MAX_DELTA, this->credentialTimeMaxDelta);
d.add(ZT_NETWORKCONFIG_DICT_KEY_REVISION, this->revision);
d.add(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO, this->issuedTo.toString((char*)tmp));
d.add(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO_IDENTITY_HASH, this->issuedToFingerprintHash, ZT_FINGERPRINT_HASH_SIZE);
d.add(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO, this->issuedTo.toString((char *)tmp));
d.add(
ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO_IDENTITY_HASH, this->issuedToFingerprintHash, ZT_FINGERPRINT_HASH_SIZE);
d.add(ZT_NETWORKCONFIG_DICT_KEY_FLAGS, this->flags);
d.add(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT, (uint64_t)this->multicastLimit);
d.add(ZT_NETWORKCONFIG_DICT_KEY_TYPE, (uint64_t)this->type);
@ -43,7 +44,7 @@ bool NetworkConfig::toDictionary(Dictionary& d) const
d.add(ZT_NETWORKCONFIG_DICT_KEY_COM, tmp, this->com.marshal(tmp));
}
Vector<uint8_t>* blob = &(d[ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES]);
Vector<uint8_t> *blob = &(d[ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES]);
for (unsigned int i = 0; i < this->capabilityCount; ++i) {
int l = this->capabilities[i].marshal(tmp);
if (l < 0)
@ -108,29 +109,29 @@ bool NetworkConfig::toDictionary(Dictionary& d) const
return false;
}
bool NetworkConfig::fromDictionary(const Dictionary& d)
bool NetworkConfig::fromDictionary(const Dictionary &d)
{
static const NetworkConfig NIL_NC;
try {
*this = NIL_NC;
this->networkId = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID, 0);
if (! this->networkId)
if (!this->networkId)
return false;
this->timestamp = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP, 0);
if (this->timestamp <= 0)
return false;
this->credentialTimeMaxDelta = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_CREDENTIAL_TIME_MAX_DELTA, 0);
this->revision = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_REVISION, 0);
this->issuedTo = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO, 0);
const Vector<uint8_t>* blob = &(d[ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO_IDENTITY_HASH]);
this->revision = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_REVISION, 0);
this->issuedTo = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO, 0);
const Vector<uint8_t> *blob = &(d[ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO_IDENTITY_HASH]);
if (blob->size() == ZT_FINGERPRINT_HASH_SIZE) {
Utils::copy<ZT_FINGERPRINT_HASH_SIZE>(this->issuedToFingerprintHash, blob->data());
}
else {
Utils::zero<ZT_FINGERPRINT_HASH_SIZE>(this->issuedToFingerprintHash);
}
if (! this->issuedTo)
if (!this->issuedTo)
return false;
this->multicastLimit = (unsigned int)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT, 0);
d.getS(ZT_NETWORKCONFIG_DICT_KEY_NAME, this->name, sizeof(this->name));
@ -145,16 +146,17 @@ bool NetworkConfig::fromDictionary(const Dictionary& d)
}
else {
this->flags = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_FLAGS, 0);
this->type = (ZT_VirtualNetworkType)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_TYPE, (uint64_t)ZT_NETWORK_TYPE_PRIVATE);
this->type =
(ZT_VirtualNetworkType)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_TYPE, (uint64_t)ZT_NETWORK_TYPE_PRIVATE);
blob = &(d[ZT_NETWORKCONFIG_DICT_KEY_COM]);
if (! blob->empty()) {
if (!blob->empty()) {
if (this->com.unmarshal(blob->data(), (int)(blob->size()) < 0))
return false;
}
blob = &(d[ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES]);
if (! blob->empty()) {
if (!blob->empty()) {
try {
unsigned int p = 0;
while (p < blob->size()) {
@ -173,7 +175,7 @@ bool NetworkConfig::fromDictionary(const Dictionary& d)
}
blob = &(d[ZT_NETWORKCONFIG_DICT_KEY_TAGS]);
if (! blob->empty()) {
if (!blob->empty()) {
try {
unsigned int p = 0;
while (p < blob->size()) {
@ -192,7 +194,7 @@ bool NetworkConfig::fromDictionary(const Dictionary& d)
}
blob = &(d[ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATES_OF_OWNERSHIP]);
if (! blob->empty()) {
if (!blob->empty()) {
try {
unsigned int p = 0;
while (p < blob->size()) {
@ -207,11 +209,13 @@ bool NetworkConfig::fromDictionary(const Dictionary& d)
}
catch (...) {
}
std::sort(&(this->certificatesOfOwnership[0]), &(this->certificatesOfOwnership[this->certificateOfOwnershipCount]));
std::sort(
&(this->certificatesOfOwnership[0]),
&(this->certificatesOfOwnership[this->certificateOfOwnershipCount]));
}
blob = &(d[ZT_NETWORKCONFIG_DICT_KEY_SPECIALISTS]);
if (! blob->empty()) {
if (!blob->empty()) {
unsigned int p = 0;
while (((p + 8) <= blob->size()) && (specialistCount < ZT_MAX_NETWORK_SPECIALISTS)) {
this->specialists[this->specialistCount++] = Utils::loadBigEndian<uint64_t>(blob->data() + p);
@ -220,16 +224,18 @@ bool NetworkConfig::fromDictionary(const Dictionary& d)
}
blob = &(d[ZT_NETWORKCONFIG_DICT_KEY_ROUTES]);
if (! blob->empty()) {
if (!blob->empty()) {
unsigned int p = 0;
while ((p < blob->size()) && (routeCount < ZT_MAX_NETWORK_ROUTES)) {
int l = asInetAddress(this->routes[this->routeCount].target).unmarshal(blob->data(), (int)(blob->size() - p));
int l = asInetAddress(this->routes[this->routeCount].target)
.unmarshal(blob->data(), (int)(blob->size() - p));
if (l < 0)
return false;
p += l;
if (p >= blob->size())
return false;
l = asInetAddress(this->routes[this->routeCount].via).unmarshal(blob->data(), (int)(blob->size() - p));
l = asInetAddress(this->routes[this->routeCount].via)
.unmarshal(blob->data(), (int)(blob->size() - p));
if (l < 0)
return false;
p += l;
@ -244,7 +250,7 @@ bool NetworkConfig::fromDictionary(const Dictionary& d)
}
blob = &(d[ZT_NETWORKCONFIG_DICT_KEY_STATIC_IPS]);
if (! blob->empty()) {
if (!blob->empty()) {
unsigned int p = 0;
while ((p < blob->size()) && (staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)) {
int l = this->staticIps[this->staticIpCount].unmarshal(blob->data() + p, (int)(blob->size() - p));
@ -256,9 +262,11 @@ bool NetworkConfig::fromDictionary(const Dictionary& d)
}
blob = &(d[ZT_NETWORKCONFIG_DICT_KEY_RULES]);
if (! blob->empty()) {
if (!blob->empty()) {
this->ruleCount = 0;
if (CapabilityCredential::unmarshalVirtualNetworkRules(blob->data(), (int)blob->size(), this->rules, this->ruleCount, ZT_MAX_NETWORK_RULES) < 0)
if (CapabilityCredential::unmarshalVirtualNetworkRules(
blob->data(), (int)blob->size(), this->rules, this->ruleCount, ZT_MAX_NETWORK_RULES)
< 0)
return false;
}
}
@ -270,7 +278,7 @@ bool NetworkConfig::fromDictionary(const Dictionary& d)
return false;
}
bool NetworkConfig::addSpecialist(const Address& a, const uint64_t f) noexcept
bool NetworkConfig::addSpecialist(const Address &a, const uint64_t f) noexcept
{
const uint64_t aint = a.toInt();
for (unsigned int i = 0; i < specialistCount; ++i) {

View file

@ -156,7 +156,7 @@ struct NetworkConfig : TriviallyCopyable {
* @param d Dictionary
* @return True if dictionary was successfully created, false if e.g. overflow
*/
bool toDictionary(Dictionary& d) const;
bool toDictionary(Dictionary &d) const;
/**
* Read this network config from a dictionary
@ -164,7 +164,7 @@ struct NetworkConfig : TriviallyCopyable {
* @param d Dictionary (non-const since it might be modified during parse, should not be used after call)
* @return True if dictionary was valid and network config successfully initialized
*/
bool fromDictionary(const Dictionary& d);
bool fromDictionary(const Dictionary &d);
/**
* @return True if broadcast (ff:ff:ff:ff:ff:ff) address should work on this network
@ -185,27 +185,22 @@ struct NetworkConfig : TriviallyCopyable {
/**
* @return Network type is public (no access control)
*/
ZT_INLINE bool isPublic() const noexcept
{
return (this->type == ZT_NETWORK_TYPE_PUBLIC);
}
ZT_INLINE bool isPublic() const noexcept { return (this->type == ZT_NETWORK_TYPE_PUBLIC); }
/**
* @return Network type is private (certificate access control)
*/
ZT_INLINE bool isPrivate() const noexcept
{
return (this->type == ZT_NETWORK_TYPE_PRIVATE);
}
ZT_INLINE bool isPrivate() const noexcept { return (this->type == ZT_NETWORK_TYPE_PRIVATE); }
/**
* @param fromPeer Peer attempting to bridge other Ethernet peers onto network
* @return True if this network allows bridging
*/
ZT_INLINE bool permitsBridging(const Address& fromPeer) const noexcept
ZT_INLINE bool permitsBridging(const Address &fromPeer) const noexcept
{
for (unsigned int i = 0; i < specialistCount; ++i) {
if ((fromPeer.toInt() == (specialists[i] & ZT_ADDRESS_MASK)) && ((specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE) != 0))
if ((fromPeer.toInt() == (specialists[i] & ZT_ADDRESS_MASK))
&& ((specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE) != 0))
return true;
}
return false;
@ -215,15 +210,12 @@ struct NetworkConfig : TriviallyCopyable {
{
return (networkId != 0);
} // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
ZT_INLINE bool operator==(const NetworkConfig& nc) const noexcept
ZT_INLINE bool operator==(const NetworkConfig &nc) const noexcept
{
return (memcmp(this, &nc, sizeof(NetworkConfig)) == 0);
}
ZT_INLINE bool operator!=(const NetworkConfig& nc) const noexcept
{
return (! (*this == nc));
}
ZT_INLINE bool operator!=(const NetworkConfig &nc) const noexcept { return (!(*this == nc)); }
/**
* Add a specialist or mask flags if already present
@ -235,9 +227,9 @@ struct NetworkConfig : TriviallyCopyable {
* @param f Flags (OR of specialist role/type flags)
* @return True if successfully masked or added
*/
bool addSpecialist(const Address& a, uint64_t f) noexcept;
bool addSpecialist(const Address &a, uint64_t f) noexcept;
ZT_INLINE const CapabilityCredential* capability(const uint32_t id) const
ZT_INLINE const CapabilityCredential *capability(const uint32_t id) const
{
for (unsigned int i = 0; i < capabilityCount; ++i) {
if (capabilities[i].id() == id)
@ -246,7 +238,7 @@ struct NetworkConfig : TriviallyCopyable {
return nullptr;
}
ZT_INLINE const TagCredential* tag(const uint32_t id) const
ZT_INLINE const TagCredential *tag(const uint32_t id) const
{
for (unsigned int i = 0; i < tagCount; ++i) {
if (tags[i].id() == id)

View file

@ -30,7 +30,12 @@ struct InetAddress;
*/
class NetworkController {
public:
enum ErrorCode { NC_ERROR_NONE = 0, NC_ERROR_OBJECT_NOT_FOUND = 1, NC_ERROR_ACCESS_DENIED = 2, NC_ERROR_INTERNAL_SERVER_ERROR = 3 };
enum ErrorCode {
NC_ERROR_NONE = 0,
NC_ERROR_OBJECT_NOT_FOUND = 1,
NC_ERROR_ACCESS_DENIED = 2,
NC_ERROR_INTERNAL_SERVER_ERROR = 3
};
/**
* Interface for sender used to send pushes and replies
@ -47,7 +52,9 @@ class NetworkController {
* @param nc Network configuration to send
* @param sendLegacyFormatConfig If true, send an old-format network config
*/
virtual void ncSendConfig(void* tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address& destination, const NetworkConfig& nc, bool sendLegacyFormatConfig) = 0;
virtual void ncSendConfig(
void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId,
const Address &destination, const NetworkConfig &nc, bool sendLegacyFormatConfig) = 0;
/**
* Send revocation to a node
@ -55,7 +62,8 @@ class NetworkController {
* @param destination Destination node address
* @param rev Revocation to send
*/
virtual void ncSendRevocation(void* tPtr, int64_t clock, int64_t ticks, const Address& destination, const RevocationCredential& rev) = 0;
virtual void ncSendRevocation(
void *tPtr, int64_t clock, int64_t ticks, const Address &destination, const RevocationCredential &rev) = 0;
/**
* Send a network configuration request error
@ -65,15 +73,13 @@ class NetworkController {
* @param destination Destination peer Address
* @param errorCode Error code
*/
virtual void ncSendError(void* tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address& destination, NetworkController::ErrorCode errorCode) = 0;
virtual void ncSendError(
void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId,
const Address &destination, NetworkController::ErrorCode errorCode) = 0;
};
NetworkController()
{
}
virtual ~NetworkController()
{
}
NetworkController() {}
virtual ~NetworkController() {}
/**
* Called when this is added to a Node to initialize and supply info
@ -81,7 +87,7 @@ class NetworkController {
* @param signingId Identity for signing of network configurations, certs, etc.
* @param sender Sender implementation for sending replies or config pushes
*/
virtual void init(const Identity& signingId, Sender* sender) = 0;
virtual void init(const Identity &signingId, Sender *sender) = 0;
/**
* Handle a network configuration request
@ -93,7 +99,9 @@ class NetworkController {
* @param metaData Meta-data bundled with request (if any)
* @return Returns NETCONF_QUERY_OK if result 'nc' is valid, or an error code on error
*/
virtual void request(uint64_t nwid, const InetAddress& fromAddr, uint64_t requestPacketId, const Identity& identity, const Dictionary& metaData) = 0;
virtual void request(
uint64_t nwid, const InetAddress &fromAddr, uint64_t requestPacketId, const Identity &identity,
const Dictionary &metaData) = 0;
};
} // namespace ZeroTier

View file

@ -35,19 +35,27 @@ namespace ZeroTier {
namespace {
struct _NodeObjects {
ZT_INLINE _NodeObjects(Context& ctx, const CallContext& cc) : networks(), t(ctx), expect(), vl2(ctx), vl1(ctx), topology(ctx, cc), sa(ctx), ts()
ZT_INLINE _NodeObjects(Context &ctx, const CallContext &cc)
: networks()
, t(ctx)
, expect()
, vl2(ctx)
, vl1(ctx)
, topology(ctx, cc)
, sa(ctx)
, ts()
{
ctx.networks = &networks;
ctx.t = &t;
ctx.expect = &expect;
ctx.vl2 = &vl2;
ctx.vl1 = &vl1;
ctx.t = &t;
ctx.expect = &expect;
ctx.vl2 = &vl2;
ctx.vl1 = &vl1;
ctx.topology = &topology;
ctx.sa = &sa;
ctx.ts = &ts;
ctx.sa = &sa;
ctx.ts = &ts;
}
TinyMap<SharedPtr<Network> > networks;
TinyMap<SharedPtr<Network>> networks;
Trace t;
Expect expect;
VL2 vl2;
@ -59,7 +67,7 @@ struct _NodeObjects {
} // anonymous namespace
Node::Node(void* uPtr, const struct ZT_Node_Callbacks* callbacks, const CallContext& cc)
Node::Node(void *uPtr, const struct ZT_Node_Callbacks *callbacks, const CallContext &cc)
: m_ctx(this)
, m_store(m_ctx)
, m_objects(nullptr)
@ -72,14 +80,14 @@ Node::Node(void* uPtr, const struct ZT_Node_Callbacks* callbacks, const CallCont
ZT_SPEW("Node starting up!");
Utils::copy<sizeof(ZT_Node_Callbacks)>(&m_ctx.cb, callbacks);
m_ctx.uPtr = uPtr;
m_ctx.uPtr = uPtr;
m_ctx.store = &m_store;
Vector<uint8_t> data(m_store.get(cc, ZT_STATE_OBJECT_IDENTITY_SECRET, Utils::ZERO256, 0));
bool haveIdentity = false;
if (! data.empty()) {
if (!data.empty()) {
data.push_back(0); // zero-terminate string
if (m_ctx.identity.fromString((const char*)data.data())) {
if (m_ctx.identity.fromString((const char *)data.data())) {
m_ctx.identity.toString(false, m_ctx.publicIdentityStr);
m_ctx.identity.toString(true, m_ctx.secretIdentityStr);
haveIdentity = true;
@ -87,18 +95,24 @@ Node::Node(void* uPtr, const struct ZT_Node_Callbacks* callbacks, const CallCont
}
}
if (! haveIdentity) {
if (!haveIdentity) {
m_ctx.identity.generate(Identity::C25519);
m_ctx.identity.toString(false, m_ctx.publicIdentityStr);
m_ctx.identity.toString(true, m_ctx.secretIdentityStr);
m_store.put(cc, ZT_STATE_OBJECT_IDENTITY_SECRET, Utils::ZERO256, 0, m_ctx.secretIdentityStr, (unsigned int)strlen(m_ctx.secretIdentityStr));
m_store.put(cc, ZT_STATE_OBJECT_IDENTITY_PUBLIC, Utils::ZERO256, 0, m_ctx.publicIdentityStr, (unsigned int)strlen(m_ctx.publicIdentityStr));
m_store.put(
cc, ZT_STATE_OBJECT_IDENTITY_SECRET, Utils::ZERO256, 0, m_ctx.secretIdentityStr,
(unsigned int)strlen(m_ctx.secretIdentityStr));
m_store.put(
cc, ZT_STATE_OBJECT_IDENTITY_PUBLIC, Utils::ZERO256, 0, m_ctx.publicIdentityStr,
(unsigned int)strlen(m_ctx.publicIdentityStr));
ZT_SPEW("no pre-existing identity found, created %s", m_ctx.identity.toString().c_str());
}
else {
data = m_store.get(cc, ZT_STATE_OBJECT_IDENTITY_PUBLIC, Utils::ZERO256, 0);
if ((data.empty()) || (memcmp(data.data(), m_ctx.publicIdentityStr, strlen(m_ctx.publicIdentityStr)) != 0))
m_store.put(cc, ZT_STATE_OBJECT_IDENTITY_PUBLIC, Utils::ZERO256, 0, m_ctx.publicIdentityStr, (unsigned int)strlen(m_ctx.publicIdentityStr));
m_store.put(
cc, ZT_STATE_OBJECT_IDENTITY_PUBLIC, Utils::ZERO256, 0, m_ctx.publicIdentityStr,
(unsigned int)strlen(m_ctx.publicIdentityStr));
}
uint8_t localSecretCipherKey[ZT_FINGERPRINT_HASH_SIZE];
@ -110,11 +124,11 @@ Node::Node(void* uPtr, const struct ZT_Node_Callbacks* callbacks, const CallCont
for (unsigned int i = 0; i < 1023; ++i)
m_ctx.randomPrivilegedPortOrder[i] = (uint16_t)(i + 1);
for (unsigned int i = 0; i < 512; ++i) {
uint64_t rn = Utils::random();
uint64_t rn = Utils::random();
const unsigned int a = (unsigned int)rn % 1023;
const unsigned int b = (unsigned int)(rn >> 32U) % 1023;
if (a != b) {
const uint16_t tmp = m_ctx.randomPrivilegedPortOrder[a];
const uint16_t tmp = m_ctx.randomPrivilegedPortOrder[a];
m_ctx.randomPrivilegedPortOrder[a] = m_ctx.randomPrivilegedPortOrder[b];
m_ctx.randomPrivilegedPortOrder[b] = tmp;
}
@ -135,7 +149,7 @@ Node::~Node()
m_allNetworks.clear();
m_allNetworks_l.unlock();
delete reinterpret_cast<_NodeObjects*>(m_objects);
delete reinterpret_cast<_NodeObjects *>(m_objects);
// Let go of cached Buf objects. If other nodes happen to be running in this
// same process space new Bufs will be allocated as needed, but this is almost
@ -144,7 +158,7 @@ Node::~Node()
Buf::freePool();
}
void Node::shutdown(const CallContext& cc)
void Node::shutdown(const CallContext &cc)
{
m_allNetworks_l.lock();
m_ctx.networks->clear();
@ -157,7 +171,7 @@ void Node::shutdown(const CallContext& cc)
m_ctx.topology->saveAll(cc);
}
ZT_ResultCode Node::processBackgroundTasks(const CallContext& cc, volatile int64_t* nextBackgroundTaskDeadline)
ZT_ResultCode Node::processBackgroundTasks(const CallContext &cc, volatile int64_t *nextBackgroundTaskDeadline)
{
Mutex::Lock bl(m_backgroundTasksLock);
@ -176,7 +190,7 @@ ZT_ResultCode Node::processBackgroundTasks(const CallContext& cc, volatile int64
m_lastNetworkHousekeepingRun = cc.ticks;
ZT_SPEW("running networking housekeeping...");
Mutex::Lock l(m_allNetworks_l);
for (Vector<SharedPtr<Network> >::const_iterator n(m_allNetworks.begin()); n != m_allNetworks.end(); ++n)
for (Vector<SharedPtr<Network>>::const_iterator n(m_allNetworks.begin()); n != m_allNetworks.end(); ++n)
(*n)->doPeriodicTasks(cc);
}
@ -196,15 +210,17 @@ ZT_ResultCode Node::processBackgroundTasks(const CallContext& cc, volatile int64
m_lastPeerPulse = cc.ticks;
ZT_SPEW("running pulse() on each peer...");
try {
Vector<SharedPtr<Peer> > allPeers, rootPeers;
Vector<SharedPtr<Peer>> allPeers, rootPeers;
m_ctx.topology->allPeers(allPeers, rootPeers);
std::sort(rootPeers.begin(), rootPeers.end());
bool online = false;
for (Vector<SharedPtr<Peer> >::iterator p(allPeers.begin()); p != allPeers.end(); ++p) {
for (Vector<SharedPtr<Peer>>::iterator p(allPeers.begin()); p != allPeers.end(); ++p) {
(*p)->pulse(m_ctx, cc);
if (! online) {
online = ((std::binary_search(rootPeers.begin(), rootPeers.end(), *p) || rootPeers.empty()) && (*p)->directlyConnected());
if (!online) {
online =
((std::binary_search(rootPeers.begin(), rootPeers.end(), *p) || rootPeers.empty())
&& (*p)->directlyConnected());
}
}
@ -228,7 +244,7 @@ ZT_ResultCode Node::processBackgroundTasks(const CallContext& cc, volatile int64
return ZT_RESULT_OK;
}
ZT_ResultCode Node::join(uint64_t nwid, const ZT_Fingerprint* controllerFingerprint, void* uptr, const CallContext& cc)
ZT_ResultCode Node::join(uint64_t nwid, const ZT_Fingerprint *controllerFingerprint, void *uptr, const CallContext &cc)
{
Mutex::Lock l(m_allNetworks_l);
@ -241,7 +257,7 @@ ZT_ResultCode Node::join(uint64_t nwid, const ZT_Fingerprint* controllerFingerpr
ZT_SPEW("joining network %.16llx", nwid);
}
for (Vector<SharedPtr<Network> >::iterator n(m_allNetworks.begin()); n != m_allNetworks.end(); ++n) {
for (Vector<SharedPtr<Network>>::iterator n(m_allNetworks.begin()); n != m_allNetworks.end(); ++n) {
if ((*n)->id() == nwid)
return ZT_RESULT_OK;
}
@ -252,7 +268,7 @@ ZT_ResultCode Node::join(uint64_t nwid, const ZT_Fingerprint* controllerFingerpr
return ZT_RESULT_OK;
}
ZT_ResultCode Node::leave(uint64_t nwid, void** uptr, const CallContext& cc)
ZT_ResultCode Node::leave(uint64_t nwid, void **uptr, const CallContext &cc)
{
Mutex::Lock l(m_allNetworks_l);
@ -261,7 +277,7 @@ ZT_ResultCode Node::leave(uint64_t nwid, void** uptr, const CallContext& cc)
SharedPtr<Network> network;
m_ctx.networks->erase(nwid);
for (Vector<SharedPtr<Network> >::iterator n(m_allNetworks.begin()); n != m_allNetworks.end(); ++n) {
for (Vector<SharedPtr<Network>>::iterator n(m_allNetworks.begin()); n != m_allNetworks.end(); ++n) {
if ((*n)->id() == nwid) {
network.move(*n);
m_allNetworks.erase(n);
@ -278,7 +294,9 @@ ZT_ResultCode Node::leave(uint64_t nwid, void** uptr, const CallContext& cc)
if (uptr)
*uptr = *network->userPtr();
network->externalConfig(&ctmp);
m_ctx.cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node*>(this), m_ctx.uPtr, cc.tPtr, nwid, network->userPtr(), ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY, &ctmp);
m_ctx.cb.virtualNetworkConfigFunction(
reinterpret_cast<ZT_Node *>(this), m_ctx.uPtr, cc.tPtr, nwid, network->userPtr(),
ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY, &ctmp);
network->destroy();
return ZT_RESULT_OK;
}
@ -287,7 +305,8 @@ ZT_ResultCode Node::leave(uint64_t nwid, void** uptr, const CallContext& cc)
}
}
ZT_ResultCode Node::multicastSubscribe(const CallContext& cc, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi)
ZT_ResultCode
Node::multicastSubscribe(const CallContext &cc, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi)
{
ZT_SPEW("multicast subscribe to %s:%lu", MAC(multicastGroup).toString().c_str(), multicastAdi);
const SharedPtr<Network> nw(m_ctx.networks->get(nwid));
@ -300,7 +319,8 @@ ZT_ResultCode Node::multicastSubscribe(const CallContext& cc, uint64_t nwid, uin
}
}
ZT_ResultCode Node::multicastUnsubscribe(const CallContext& cc, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi)
ZT_ResultCode
Node::multicastUnsubscribe(const CallContext &cc, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi)
{
ZT_SPEW("multicast unsubscribe from %s:%lu", MAC(multicastGroup).toString().c_str(), multicastAdi);
const SharedPtr<Network> nw(m_ctx.networks->get(nwid));
@ -313,114 +333,114 @@ ZT_ResultCode Node::multicastUnsubscribe(const CallContext& cc, uint64_t nwid, u
}
}
void Node::status(ZT_NodeStatus* status) const
void Node::status(ZT_NodeStatus *status) const
{
status->address = m_ctx.identity.address().toInt();
status->identity = reinterpret_cast<const ZT_Identity*>(&m_ctx.identity);
status->address = m_ctx.identity.address().toInt();
status->identity = reinterpret_cast<const ZT_Identity *>(&m_ctx.identity);
status->publicIdentity = m_ctx.publicIdentityStr;
status->secretIdentity = m_ctx.secretIdentityStr;
status->online = m_online ? 1 : 0;
status->online = m_online ? 1 : 0;
}
struct p_ZT_PeerListPrivate : public ZT_PeerList {
// Actual containers for the memory, hidden from external users.
Vector<ZT_Peer> p_peers;
ForwardList<Vector<ZT_Path> > p_paths;
ForwardList<Vector<ZT_Path>> p_paths;
ForwardList<Identity> p_identities;
ForwardList<Blob<ZT_LOCATOR_MARSHAL_SIZE_MAX> > p_locators;
ForwardList<Blob<ZT_LOCATOR_MARSHAL_SIZE_MAX>> p_locators;
};
static void p_peerListFreeFunction(const void* pl)
static void p_peerListFreeFunction(const void *pl)
{
if (pl)
delete reinterpret_cast<p_ZT_PeerListPrivate*>(const_cast<void*>(pl));
delete reinterpret_cast<p_ZT_PeerListPrivate *>(const_cast<void *>(pl));
}
struct p_sortPeerPtrsByAddress {
ZT_INLINE bool operator()(const SharedPtr<Peer>& a, const SharedPtr<Peer>& b) const noexcept
ZT_INLINE bool operator()(const SharedPtr<Peer> &a, const SharedPtr<Peer> &b) const noexcept
{
return (a->address() < b->address());
}
};
ZT_PeerList* Node::peers(const CallContext& cc) const
ZT_PeerList *Node::peers(const CallContext &cc) const
{
p_ZT_PeerListPrivate* pl = nullptr;
p_ZT_PeerListPrivate *pl = nullptr;
try {
pl = new p_ZT_PeerListPrivate;
pl = new p_ZT_PeerListPrivate;
pl->freeFunction = p_peerListFreeFunction;
Vector<SharedPtr<Peer> > peers, rootPeers;
Vector<SharedPtr<Peer>> peers, rootPeers;
m_ctx.topology->allPeers(peers, rootPeers);
std::sort(peers.begin(), peers.end(), p_sortPeerPtrsByAddress());
std::sort(rootPeers.begin(), rootPeers.end());
for (Vector<SharedPtr<Peer> >::iterator pi(peers.begin()); pi != peers.end(); ++pi) {
for (Vector<SharedPtr<Peer>>::iterator pi(peers.begin()); pi != peers.end(); ++pi) {
pl->p_peers.push_back(ZT_Peer());
ZT_Peer& p = pl->p_peers.back();
Peer& pp = **pi;
ZT_Peer &p = pl->p_peers.back();
Peer &pp = **pi;
p.address = pp.address();
pl->p_identities.push_front(pp.identity());
p.identity = reinterpret_cast<const ZT_Identity*>(&(pl->p_identities.front()));
p.identity = reinterpret_cast<const ZT_Identity *>(&(pl->p_identities.front()));
p.fingerprint = &(pl->p_identities.front().fingerprint());
uint16_t vProto, vMajor, vMinor, vRevision;
if (pp.remoteVersion(vProto, vMajor, vMinor, vRevision)) {
p.versionMajor = (int)vMajor;
p.versionMinor = (int)vMinor;
p.versionRev = (int)vRevision;
p.versionRev = (int)vRevision;
p.versionProto = (int)vProto;
}
else {
p.versionMajor = -1;
p.versionMinor = -1;
p.versionRev = -1;
p.versionRev = -1;
p.versionProto = -1;
}
p.latency = pp.latency();
p.root = std::binary_search(rootPeers.begin(), rootPeers.end(), *pi) ? 1 : 0;
p.root = std::binary_search(rootPeers.begin(), rootPeers.end(), *pi) ? 1 : 0;
p.networks = nullptr;
p.networks = nullptr;
p.networkCount = 0; // TODO: networks this peer belongs to
Vector<SharedPtr<Path> > ztPaths;
Vector<SharedPtr<Path>> ztPaths;
pp.getAllPaths(ztPaths);
if (ztPaths.empty()) {
pl->p_paths.push_front(Vector<ZT_Path>());
std::vector<ZT_Path>& apiPaths = pl->p_paths.front();
std::vector<ZT_Path> &apiPaths = pl->p_paths.front();
apiPaths.resize(ztPaths.size());
for (unsigned long i = 0; i < (unsigned long)ztPaths.size(); ++i) {
SharedPtr<Path>& ztp = ztPaths[i];
ZT_Path& apip = apiPaths[i];
apip.endpoint.type = ZT_ENDPOINT_TYPE_IP_UDP;
SharedPtr<Path> &ztp = ztPaths[i];
ZT_Path &apip = apiPaths[i];
apip.endpoint.type = ZT_ENDPOINT_TYPE_IP_UDP;
Utils::copy<sizeof(struct sockaddr_storage)>(&(apip.endpoint.value.ss), &(ztp->address().as.ss));
apip.lastSend = ztp->lastOut();
apip.lastSend = ztp->lastOut();
apip.lastReceive = ztp->lastIn();
apip.alive = ztp->alive(cc) ? 1 : 0;
apip.preferred = (i == 0) ? 1 : 0;
apip.alive = ztp->alive(cc) ? 1 : 0;
apip.preferred = (i == 0) ? 1 : 0;
}
p.paths = apiPaths.data();
p.paths = apiPaths.data();
p.pathCount = (unsigned int)apiPaths.size();
}
else {
p.paths = nullptr;
p.paths = nullptr;
p.pathCount = 0;
}
const SharedPtr<const Locator> loc(pp.locator());
if (loc) {
pl->p_locators.push_front(Blob<ZT_LOCATOR_MARSHAL_SIZE_MAX>());
Blob<ZT_LOCATOR_MARSHAL_SIZE_MAX>& lb = pl->p_locators.front();
Blob<ZT_LOCATOR_MARSHAL_SIZE_MAX> &lb = pl->p_locators.front();
Utils::zero<ZT_LOCATOR_MARSHAL_SIZE_MAX>(lb.data);
const int ls = loc->marshal(lb.data);
if (ls > 0) {
p.locatorSize = (unsigned int)ls;
p.locator = lb.data;
p.locator = lb.data;
}
}
}
pl->peers = pl->p_peers.data();
pl->peers = pl->p_peers.data();
pl->peerCount = (unsigned long)pl->p_peers.size();
return pl;
@ -431,11 +451,11 @@ ZT_PeerList* Node::peers(const CallContext& cc) const
}
}
ZT_VirtualNetworkConfig* Node::networkConfig(uint64_t nwid) const
ZT_VirtualNetworkConfig *Node::networkConfig(uint64_t nwid) const
{
const SharedPtr<Network> nw(m_ctx.networks->get(nwid));
if (nw) {
ZT_VirtualNetworkConfig* const nc = (ZT_VirtualNetworkConfig*)::malloc(sizeof(ZT_VirtualNetworkConfig));
ZT_VirtualNetworkConfig *const nc = (ZT_VirtualNetworkConfig *)::malloc(sizeof(ZT_VirtualNetworkConfig));
nw->externalConfig(nc);
return nc;
}
@ -444,25 +464,26 @@ ZT_VirtualNetworkConfig* Node::networkConfig(uint64_t nwid) const
}
}
ZT_VirtualNetworkList* Node::networks() const
ZT_VirtualNetworkList *Node::networks() const
{
Mutex::Lock l(m_allNetworks_l);
char* const buf = (char*)::malloc(sizeof(ZT_VirtualNetworkList) + (sizeof(ZT_VirtualNetworkConfig) * m_allNetworks.size()));
if (! buf)
char *const buf =
(char *)::malloc(sizeof(ZT_VirtualNetworkList) + (sizeof(ZT_VirtualNetworkConfig) * m_allNetworks.size()));
if (!buf)
return nullptr;
ZT_VirtualNetworkList* nl = (ZT_VirtualNetworkList*)buf;
nl->freeFunction = reinterpret_cast<void (*)(const void*)>(free);
nl->networks = (ZT_VirtualNetworkConfig*)(buf + sizeof(ZT_VirtualNetworkList));
ZT_VirtualNetworkList *nl = (ZT_VirtualNetworkList *)buf;
nl->freeFunction = reinterpret_cast<void (*)(const void *)>(free);
nl->networks = (ZT_VirtualNetworkConfig *)(buf + sizeof(ZT_VirtualNetworkList));
nl->networkCount = 0;
for (Vector<SharedPtr<Network> >::const_iterator i(m_allNetworks.begin()); i != m_allNetworks.end(); ++i)
for (Vector<SharedPtr<Network>>::const_iterator i(m_allNetworks.begin()); i != m_allNetworks.end(); ++i)
(*i)->externalConfig(&(nl->networks[nl->networkCount++]));
return nl;
}
void Node::setNetworkUserPtr(uint64_t nwid, void* ptr)
void Node::setNetworkUserPtr(uint64_t nwid, void *ptr)
{
SharedPtr<Network> nw(m_ctx.networks->get(nwid));
if (nw) {
@ -472,44 +493,48 @@ void Node::setNetworkUserPtr(uint64_t nwid, void* ptr)
}
}
void Node::setInterfaceAddresses(const ZT_InterfaceAddress* addrs, unsigned int addrCount)
void Node::setInterfaceAddresses(const ZT_InterfaceAddress *addrs, unsigned int addrCount)
{
Mutex::Lock _l(m_localInterfaceAddresses_m);
m_localInterfaceAddresses.clear();
for (unsigned int i = 0; i < addrCount; ++i) {
bool dupe = false;
for (unsigned int j = 0; j < i; ++j) {
if (*(reinterpret_cast<const InetAddress*>(&addrs[j].address)) == *(reinterpret_cast<const InetAddress*>(&addrs[i].address))) {
if (*(reinterpret_cast<const InetAddress *>(&addrs[j].address))
== *(reinterpret_cast<const InetAddress *>(&addrs[i].address))) {
dupe = true;
break;
}
}
if (! dupe)
if (!dupe)
m_localInterfaceAddresses.push_back(addrs[i]);
}
}
ZT_CertificateError Node::addCertificate(const CallContext& cc, unsigned int localTrust, const ZT_Certificate* cert, const void* certData, unsigned int certSize)
ZT_CertificateError Node::addCertificate(
const CallContext &cc, unsigned int localTrust, const ZT_Certificate *cert, const void *certData,
unsigned int certSize)
{
Certificate c;
if (cert) {
c = *cert;
}
else {
if ((! certData) || (! certSize))
if ((!certData) || (!certSize))
return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
if (! c.decode(certData, certSize))
if (!c.decode(certData, certSize))
return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
}
m_ctx.ts->add(c, localTrust);
m_ctx.ts->update(cc.clock, nullptr);
SharedPtr<TrustStore::Entry> ent(m_ctx.ts->get(c.getSerialNo()));
return (ent) ? ent->error() : ZT_CERTIFICATE_ERROR_INVALID_FORMAT; // should never be null, but if so it means invalid
return (ent) ? ent->error()
: ZT_CERTIFICATE_ERROR_INVALID_FORMAT; // should never be null, but if so it means invalid
}
ZT_ResultCode Node::deleteCertificate(const CallContext& cc, const void* serialNo)
ZT_ResultCode Node::deleteCertificate(const CallContext &cc, const void *serialNo)
{
if (! serialNo)
if (!serialNo)
return ZT_RESULT_ERROR_BAD_PARAMETER;
m_ctx.ts->erase(H384(serialNo));
m_ctx.ts->update(-1, nullptr);
@ -517,45 +542,51 @@ ZT_ResultCode Node::deleteCertificate(const CallContext& cc, const void* serialN
}
struct p_certificateListInternal {
Vector<SharedPtr<TrustStore::Entry> > entries;
Vector<const ZT_Certificate*> c;
Vector<SharedPtr<TrustStore::Entry>> entries;
Vector<const ZT_Certificate *> c;
Vector<unsigned int> t;
};
static void p_freeCertificateList(const void* cl)
static void p_freeCertificateList(const void *cl)
{
if (cl) {
reinterpret_cast<const p_certificateListInternal*>(reinterpret_cast<const uint8_t*>(cl) + sizeof(ZT_CertificateList))->~p_certificateListInternal();
free(const_cast<void*>(cl));
reinterpret_cast<const p_certificateListInternal *>(
reinterpret_cast<const uint8_t *>(cl) + sizeof(ZT_CertificateList))
->~p_certificateListInternal();
free(const_cast<void *>(cl));
}
}
ZT_CertificateList* Node::listCertificates()
ZT_CertificateList *Node::listCertificates()
{
ZT_CertificateList* const cl = (ZT_CertificateList*)malloc(sizeof(ZT_CertificateList) + sizeof(p_certificateListInternal));
if (! cl)
ZT_CertificateList *const cl =
(ZT_CertificateList *)malloc(sizeof(ZT_CertificateList) + sizeof(p_certificateListInternal));
if (!cl)
return nullptr;
p_certificateListInternal* const clint = reinterpret_cast<p_certificateListInternal*>(reinterpret_cast<uint8_t*>(cl) + sizeof(ZT_CertificateList));
p_certificateListInternal *const clint =
reinterpret_cast<p_certificateListInternal *>(reinterpret_cast<uint8_t *>(cl) + sizeof(ZT_CertificateList));
new (clint) p_certificateListInternal;
clint->entries = m_ctx.ts->all(false);
clint->c.reserve(clint->entries.size());
clint->t.reserve(clint->entries.size());
for (Vector<SharedPtr<TrustStore::Entry> >::const_iterator i(clint->entries.begin()); i != clint->entries.end(); ++i) {
for (Vector<SharedPtr<TrustStore::Entry>>::const_iterator i(clint->entries.begin()); i != clint->entries.end();
++i) {
clint->c.push_back(&((*i)->certificate()));
clint->t.push_back((*i)->localTrust());
}
cl->freeFunction = p_freeCertificateList;
cl->certs = clint->c.data();
cl->localTrust = clint->t.data();
cl->certCount = (unsigned long)clint->c.size();
cl->certs = clint->c.data();
cl->localTrust = clint->t.data();
cl->certCount = (unsigned long)clint->c.size();
return cl;
}
int Node::sendUserMessage(const CallContext& cc, uint64_t dest, uint64_t /*typeId*/, const void* /*data*/, unsigned int /*len*/)
int Node::sendUserMessage(
const CallContext &cc, uint64_t dest, uint64_t /*typeId*/, const void * /*data*/, unsigned int /*len*/)
{
try {
if (m_ctx.identity.address().toInt() != dest) {
@ -575,18 +606,18 @@ int Node::sendUserMessage(const CallContext& cc, uint64_t dest, uint64_t /*typeI
return 0;
}
void Node::setController(void* networkControllerInstance)
void Node::setController(void *networkControllerInstance)
{
m_ctx.localNetworkController = reinterpret_cast<NetworkController*>(networkControllerInstance);
m_ctx.localNetworkController = reinterpret_cast<NetworkController *>(networkControllerInstance);
if (networkControllerInstance)
m_ctx.localNetworkController->init(m_ctx.identity, this);
}
bool Node::filterPotentialPath(void* tPtr, const Identity& id, int64_t localSocket, const InetAddress& remoteAddress)
bool Node::filterPotentialPath(void *tPtr, const Identity &id, int64_t localSocket, const InetAddress &remoteAddress)
{
{
Mutex::Lock l(m_allNetworks_l);
for (Vector<SharedPtr<Network> >::iterator i(m_allNetworks.begin()); i != m_allNetworks.end(); ++i) {
for (Vector<SharedPtr<Network>>::iterator i(m_allNetworks.begin()); i != m_allNetworks.end(); ++i) {
for (unsigned int k = 0, j = (*i)->config().staticIpCount; k < j; ++k) {
if ((*i)->config().staticIps[k].containsAddress(remoteAddress))
return false;
@ -595,27 +626,37 @@ bool Node::filterPotentialPath(void* tPtr, const Identity& id, int64_t localSock
}
if (m_ctx.cb.pathCheckFunction) {
return (m_ctx.cb.pathCheckFunction(reinterpret_cast<ZT_Node*>(this), m_ctx.uPtr, tPtr, id.address().toInt(), (const ZT_Identity*)&id, localSocket, reinterpret_cast<const ZT_InetAddress*>(&remoteAddress)) != 0);
return (
m_ctx.cb.pathCheckFunction(
reinterpret_cast<ZT_Node *>(this), m_ctx.uPtr, tPtr, id.address().toInt(), (const ZT_Identity *)&id,
localSocket, reinterpret_cast<const ZT_InetAddress *>(&remoteAddress))
!= 0);
}
return true;
}
bool Node::externalPathLookup(void* tPtr, const Identity& id, int family, InetAddress& addr)
bool Node::externalPathLookup(void *tPtr, const Identity &id, int family, InetAddress &addr)
{
if (m_ctx.cb.pathLookupFunction) {
return (m_ctx.cb.pathLookupFunction(reinterpret_cast<ZT_Node*>(this), m_ctx.uPtr, tPtr, id.address().toInt(), reinterpret_cast<const ZT_Identity*>(&id), family, reinterpret_cast<ZT_InetAddress*>(&addr)) == ZT_RESULT_OK);
return (
m_ctx.cb.pathLookupFunction(
reinterpret_cast<ZT_Node *>(this), m_ctx.uPtr, tPtr, id.address().toInt(),
reinterpret_cast<const ZT_Identity *>(&id), family, reinterpret_cast<ZT_InetAddress *>(&addr))
== ZT_RESULT_OK);
}
return false;
}
// Implementation of NetworkController::Sender ------------------------------------------------------------------------
void Node::ncSendConfig(void* tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address& destination, const NetworkConfig& nc, bool sendLegacyFormatConfig)
void Node::ncSendConfig(
void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address &destination,
const NetworkConfig &nc, bool sendLegacyFormatConfig)
{
if (destination == m_ctx.identity.address()) {
SharedPtr<Network> n(m_ctx.networks->get(nwid));
if (! n)
if (!n)
return;
CallContext cc(clock, ticks, tPtr);
n->setConfiguration(cc, nc, true);
@ -624,7 +665,7 @@ void Node::ncSendConfig(void* tPtr, int64_t clock, int64_t ticks, uint64_t nwid,
Dictionary dconf;
if (nc.toDictionary(dconf)) {
uint64_t configUpdateId = Utils::random();
if (! configUpdateId)
if (!configUpdateId)
++configUpdateId;
Vector<uint8_t> ddata;
@ -663,11 +704,12 @@ void Node::ncSendConfig(void* tPtr, int64_t clock, int64_t ticks, uint64_t nwid,
}
}
void Node::ncSendRevocation(void* tPtr, int64_t clock, int64_t ticks, const Address& destination, const RevocationCredential& rev)
void Node::ncSendRevocation(
void *tPtr, int64_t clock, int64_t ticks, const Address &destination, const RevocationCredential &rev)
{
if (destination == m_ctx.identity.address()) {
SharedPtr<Network> n(m_ctx.networks->get(rev.networkId()));
if (! n)
if (!n)
return;
CallContext cc(clock, ticks, tPtr);
n->addCredential(cc, m_ctx.identity, rev);
@ -687,23 +729,20 @@ void Node::ncSendRevocation(void* tPtr, int64_t clock, int64_t ticks, const Addr
}
}
void Node::ncSendError(void* tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address& destination, NetworkController::ErrorCode errorCode)
void Node::ncSendError(
void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address &destination,
NetworkController::ErrorCode errorCode)
{
if (destination == m_ctx.identity.address()) {
SharedPtr<Network> n(m_ctx.networks->get(nwid));
if (! n)
if (!n)
return;
switch (errorCode) {
case NetworkController::NC_ERROR_OBJECT_NOT_FOUND:
case NetworkController::NC_ERROR_INTERNAL_SERVER_ERROR:
n->setNotFound();
break;
case NetworkController::NC_ERROR_ACCESS_DENIED:
n->setAccessDenied();
break;
case NetworkController::NC_ERROR_INTERNAL_SERVER_ERROR: n->setNotFound(); break;
case NetworkController::NC_ERROR_ACCESS_DENIED: n->setAccessDenied(); break;
default:
break;
default: break;
}
}
else if (requestPacketId) {

View file

@ -39,53 +39,51 @@ class Node : public NetworkController::Sender {
public:
// Get rid of alignment warnings on 32-bit Windows
#ifdef __WINDOWS__
void* operator new(size_t i)
{
return _mm_malloc(i, 16);
}
void operator delete(void* p)
{
_mm_free(p);
}
void *operator new(size_t i) { return _mm_malloc(i, 16); }
void operator delete(void *p) { _mm_free(p); }
#endif
Node(void* uPtr, const struct ZT_Node_Callbacks* callbacks, const CallContext& cc);
Node(void *uPtr, const struct ZT_Node_Callbacks *callbacks, const CallContext &cc);
virtual ~Node();
void shutdown(const CallContext& cc);
void shutdown(const CallContext &cc);
ZT_ResultCode processBackgroundTasks(const CallContext& cc, volatile int64_t* nextBackgroundTaskDeadline);
ZT_ResultCode processBackgroundTasks(const CallContext &cc, volatile int64_t *nextBackgroundTaskDeadline);
ZT_ResultCode join(uint64_t nwid, const ZT_Fingerprint* controllerFingerprint, void* uptr, const CallContext& cc);
ZT_ResultCode join(uint64_t nwid, const ZT_Fingerprint *controllerFingerprint, void *uptr, const CallContext &cc);
ZT_ResultCode leave(uint64_t nwid, void** uptr, const CallContext& cc);
ZT_ResultCode leave(uint64_t nwid, void **uptr, const CallContext &cc);
ZT_ResultCode multicastSubscribe(const CallContext& cc, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi);
ZT_ResultCode
multicastSubscribe(const CallContext &cc, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi);
ZT_ResultCode multicastUnsubscribe(const CallContext& cc, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi);
ZT_ResultCode
multicastUnsubscribe(const CallContext &cc, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi);
void status(ZT_NodeStatus* status) const;
void status(ZT_NodeStatus *status) const;
ZT_PeerList* peers(const CallContext& cc) const;
ZT_PeerList *peers(const CallContext &cc) const;
ZT_VirtualNetworkConfig* networkConfig(uint64_t nwid) const;
ZT_VirtualNetworkConfig *networkConfig(uint64_t nwid) const;
ZT_VirtualNetworkList* networks() const;
ZT_VirtualNetworkList *networks() const;
void setNetworkUserPtr(uint64_t nwid, void* ptr);
void setNetworkUserPtr(uint64_t nwid, void *ptr);
void setInterfaceAddresses(const ZT_InterfaceAddress* addrs, unsigned int addrCount);
void setInterfaceAddresses(const ZT_InterfaceAddress *addrs, unsigned int addrCount);
ZT_CertificateError addCertificate(const CallContext& cc, unsigned int localTrust, const ZT_Certificate* cert, const void* certData, unsigned int certSize);
ZT_CertificateError addCertificate(
const CallContext &cc, unsigned int localTrust, const ZT_Certificate *cert, const void *certData,
unsigned int certSize);
ZT_ResultCode deleteCertificate(const CallContext& cc, const void* serialNo);
ZT_ResultCode deleteCertificate(const CallContext &cc, const void *serialNo);
ZT_CertificateList* listCertificates();
ZT_CertificateList *listCertificates();
int sendUserMessage(const CallContext& cc, uint64_t dest, uint64_t typeId, const void* data, unsigned int len);
int sendUserMessage(const CallContext &cc, uint64_t dest, uint64_t typeId, const void *data, unsigned int len);
void setController(void* networkControllerInstance);
void setController(void *networkControllerInstance);
/**
* Post an event via external callback
@ -95,9 +93,10 @@ class Node : public NetworkController::Sender {
* @param md Event data or NULL if none
* @param mdSize Size of event data
*/
ZT_INLINE void postEvent(void* const tPtr, const ZT_Event ev, const void* const md = nullptr, const unsigned int mdSize = 0) noexcept
ZT_INLINE void postEvent(
void *const tPtr, const ZT_Event ev, const void *const md = nullptr, const unsigned int mdSize = 0) noexcept
{
m_ctx.cb.eventCallback(reinterpret_cast<ZT_Node*>(this), m_ctx.uPtr, tPtr, ev, md, mdSize);
m_ctx.cb.eventCallback(reinterpret_cast<ZT_Node *>(this), m_ctx.uPtr, tPtr, ev, md, mdSize);
}
/**
@ -111,7 +110,7 @@ class Node : public NetworkController::Sender {
* @param remoteAddress Remote address
* @return True if path should be used
*/
bool filterPotentialPath(void* tPtr, const Identity& id, int64_t localSocket, const InetAddress& remoteAddress);
bool filterPotentialPath(void *tPtr, const Identity &id, int64_t localSocket, const InetAddress &remoteAddress);
/**
* Query callback for a physical address for a peer
@ -122,22 +121,21 @@ class Node : public NetworkController::Sender {
* @param addr Buffer to store address (result paramter)
* @return True if addr was filled with something
*/
bool externalPathLookup(void* tPtr, const Identity& id, int family, InetAddress& addr);
bool externalPathLookup(void *tPtr, const Identity &id, int family, InetAddress &addr);
ZT_INLINE const Identity& identity() const noexcept
{
return m_ctx.identity;
}
ZT_INLINE const Identity &identity() const noexcept { return m_ctx.identity; }
ZT_INLINE const Context& context() const noexcept
{
return m_ctx;
}
ZT_INLINE const Context &context() const noexcept { return m_ctx; }
// Implementation of NetworkController::Sender interface
virtual void ncSendConfig(void* tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address& destination, const NetworkConfig& nc, bool sendLegacyFormatConfig);
virtual void ncSendRevocation(void* tPtr, int64_t clock, int64_t ticks, const Address& destination, const RevocationCredential& rev);
virtual void ncSendError(void* tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address& destination, NetworkController::ErrorCode errorCode);
virtual void ncSendConfig(
void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address &destination,
const NetworkConfig &nc, bool sendLegacyFormatConfig);
virtual void ncSendRevocation(
void *tPtr, int64_t clock, int64_t ticks, const Address &destination, const RevocationCredential &rev);
virtual void ncSendError(
void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address &destination,
NetworkController::ErrorCode errorCode);
private:
Context m_ctx;
@ -146,10 +144,10 @@ class Node : public NetworkController::Sender {
Store m_store;
// Pointer to a struct defined in Node that holds instances of core objects.
void* m_objects;
void *m_objects;
// This stores networks for rapid iteration, while RR->networks is the primary lookup.
Vector<SharedPtr<Network> > m_allNetworks;
Vector<SharedPtr<Network>> m_allNetworks;
Mutex m_allNetworks_l;
// These are local interface addresses that have been configured via the API

View file

@ -17,7 +17,9 @@
/* Uncomment this to force a whole lot of debug output. */
#define ZT_DEBUG_SPEW
#if ! defined(__GNUC__) && (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || defined(__INTEL_COMPILER) || defined(__clang__))
#if !defined(__GNUC__) \
&& (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) \
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || defined(__INTEL_COMPILER) || defined(__clang__))
#define __GNUC__ 3
#endif
@ -70,25 +72,28 @@
#include <stdlib.h>
#include <string.h>
#if (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64))
#if ( \
defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) \
|| defined(__AMD64__) || defined(_M_X64))
#define ZT_ARCH_X64 1
#include <emmintrin.h>
#include <immintrin.h>
#include <xmmintrin.h>
#endif
#if defined(ZT_ARCH_X64) || defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(__X86__) || defined(_X86_) || defined(__I86__) \
|| defined(__INTEL__) || defined(__386)
#if defined(ZT_ARCH_X64) || defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) \
|| defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(__X86__) || defined(_X86_) \
|| defined(__I86__) || defined(__INTEL__) || defined(__386)
#define ZT_ARCH_X86 1
#endif
#if ! defined(ZT_ARCH_X86)
#if !defined(ZT_ARCH_X86)
#ifndef ZT_NO_UNALIGNED_ACCESS
#define ZT_NO_UNALIGNED_ACCESS 1
#endif
#endif
#if defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(ZT_ARCH_ARM_HAS_NEON)
#if (defined(__APPLE__) && ! defined(__LP64__)) || (defined(__ANDROID__) && defined(__arm__))
#if (defined(__APPLE__) && !defined(__LP64__)) || (defined(__ANDROID__) && defined(__arm__))
#ifdef ZT_ARCH_ARM_HAS_NEON
#undef ZT_ARCH_ARM_HAS_NEON
#endif
@ -209,9 +214,9 @@
* if a shim for <atomic> were included. */
#ifndef __CPP11__
#error TODO: to build on pre-c++11 compilers we will need to make a subset of std::atomic for integers
#define nullptr (0)
#define nullptr (0)
#define constexpr ZT_INLINE
#define noexcept throw()
#define noexcept throw()
#define explicit
#endif
#endif
@ -250,17 +255,17 @@ typedef unsigned uint128_t __attribute__((mode(TI)));
#endif
#endif
#if ! defined(__BYTE_ORDER) && defined(__BYTE_ORDER__)
#if !defined(__BYTE_ORDER) && defined(__BYTE_ORDER__)
#define __BYTE_ORDER __BYTE_ORDER__
#define __LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
#define __BIG_ENDIAN __ORDER_BIG_ENDIAN__
#endif
#if ! defined(__BYTE_ORDER) && defined(BYTE_ORDER)
#if !defined(__BYTE_ORDER) && defined(BYTE_ORDER)
#define __BYTE_ORDER BYTE_ORDER
#define __LITTLE_ENDIAN LITTLE_ENDIAN
#define __BIG_ENDIAN BIG_ENDIAN
#endif
#if ! defined(__BYTE_ORDER) && defined(_BYTE_ORDER)
#if !defined(__BYTE_ORDER) && defined(_BYTE_ORDER)
#define __BYTE_ORDER _BYTE_ORDER
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
@ -269,7 +274,8 @@ typedef unsigned uint128_t __attribute__((mode(TI)));
#define ZT_VA_ARGS(...) , ##__VA_ARGS__
#ifdef ZT_DEBUG_SPEW
#define ZT_SPEW(f, ...) fprintf(stderr, "%s:%d(%s): " f ZT_EOL_S, __FILE__, __LINE__, __FUNCTION__ ZT_VA_ARGS(__VA_ARGS__))
#define ZT_SPEW(f, ...) \
fprintf(stderr, "%s:%d(%s): " f ZT_EOL_S, __FILE__, __LINE__, __FUNCTION__ ZT_VA_ARGS(__VA_ARGS__))
#else
#define ZT_SPEW(f, ...)
#endif

View file

@ -15,23 +15,25 @@
namespace ZeroTier {
void OwnershipCredential::addThing(const InetAddress& ip)
void OwnershipCredential::addThing(const InetAddress &ip)
{
if (m_thingCount >= ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS)
return;
if (ip.as.sa.sa_family == AF_INET) {
m_thingTypes[m_thingCount] = THING_IPV4_ADDRESS;
Utils::copy<4>(m_thingValues[m_thingCount], &(reinterpret_cast<const struct sockaddr_in*>(&ip)->sin_addr.s_addr));
Utils::copy<4>(
m_thingValues[m_thingCount], &(reinterpret_cast<const struct sockaddr_in *>(&ip)->sin_addr.s_addr));
++m_thingCount;
}
else if (ip.as.sa.sa_family == AF_INET6) {
m_thingTypes[m_thingCount] = THING_IPV6_ADDRESS;
Utils::copy<16>(m_thingValues[m_thingCount], reinterpret_cast<const struct sockaddr_in6*>(&ip)->sin6_addr.s6_addr);
Utils::copy<16>(
m_thingValues[m_thingCount], reinterpret_cast<const struct sockaddr_in6 *>(&ip)->sin6_addr.s6_addr);
++m_thingCount;
}
}
void OwnershipCredential::addThing(const MAC& mac)
void OwnershipCredential::addThing(const MAC &mac)
{
if (m_thingCount >= ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS)
return;
@ -40,11 +42,11 @@ void OwnershipCredential::addThing(const MAC& mac)
++m_thingCount;
}
bool OwnershipCredential::sign(const Identity& signer)
bool OwnershipCredential::sign(const Identity &signer)
{
uint8_t buf[ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_SIZE_MAX + 16];
if (signer.hasPrivate()) {
m_signedBy = signer.address();
m_signedBy = signer.address();
m_signatureLength = signer.sign(buf, (unsigned int)marshal(buf, true), m_signature, sizeof(m_signature));
return true;
}
@ -73,7 +75,7 @@ int OwnershipCredential::marshal(uint8_t data[ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_
p += ZT_ADDRESS_LENGTH;
m_signedBy.copyTo(data + p);
p += ZT_ADDRESS_LENGTH;
if (! forSign) {
if (!forSign) {
data[p++] = 1;
Utils::storeBigEndian<uint16_t>(data + p, (uint16_t)m_signatureLength);
p += 2;
@ -89,15 +91,15 @@ int OwnershipCredential::marshal(uint8_t data[ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_
return p;
}
int OwnershipCredential::unmarshal(const uint8_t* data, int len) noexcept
int OwnershipCredential::unmarshal(const uint8_t *data, int len) noexcept
{
if (len < 30)
return -1;
m_networkId = Utils::loadBigEndian<uint64_t>(data);
m_ts = (int64_t)Utils::loadBigEndian<uint64_t>(data + 8);
m_flags = Utils::loadBigEndian<uint64_t>(data + 16);
m_id = Utils::loadBigEndian<uint32_t>(data + 24);
m_networkId = Utils::loadBigEndian<uint64_t>(data);
m_ts = (int64_t)Utils::loadBigEndian<uint64_t>(data + 8);
m_flags = Utils::loadBigEndian<uint64_t>(data + 16);
m_id = Utils::loadBigEndian<uint32_t>(data + 24);
m_thingCount = Utils::loadBigEndian<uint16_t>(data + 28);
if (m_thingCount > ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS)
return -1;

View file

@ -28,7 +28,9 @@
// Maximum size of a thing's value field in bytes
#define ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE 16
#define ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_SIZE_MAX (8 + 8 + 8 + 4 + 2 + ((1 + ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE) * ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS) + 5 + 5 + 1 + 2 + ZT_SIGNATURE_BUFFER_SIZE + 2)
#define ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_SIZE_MAX \
(8 + 8 + 8 + 4 + 2 + ((1 + ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE) * ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS) \
+ 5 + 5 + 1 + 2 + ZT_SIGNATURE_BUFFER_SIZE + 2)
namespace ZeroTier {
@ -44,94 +46,57 @@ class OwnershipCredential : public Credential {
friend class Credential;
public:
static constexpr ZT_CredentialType credentialType() noexcept
{
return ZT_CREDENTIAL_TYPE_COO;
}
static constexpr ZT_CredentialType credentialType() noexcept { return ZT_CREDENTIAL_TYPE_COO; }
enum Thing { THING_NULL = 0, THING_MAC_ADDRESS = 1, THING_IPV4_ADDRESS = 2, THING_IPV6_ADDRESS = 3 };
ZT_INLINE OwnershipCredential() noexcept
{
memoryZero(this);
}
ZT_INLINE OwnershipCredential() noexcept { memoryZero(this); }
ZT_INLINE
OwnershipCredential(const uint64_t nwid, const int64_t ts, const Address& issuedTo, const uint32_t id) noexcept
OwnershipCredential(const uint64_t nwid, const int64_t ts, const Address &issuedTo, const uint32_t id) noexcept
{
memoryZero(this);
m_networkId = nwid;
m_ts = ts;
m_id = id;
m_issuedTo = issuedTo;
m_ts = ts;
m_id = id;
m_issuedTo = issuedTo;
}
ZT_INLINE uint64_t networkId() const noexcept
{
return m_networkId;
}
ZT_INLINE uint64_t networkId() const noexcept { return m_networkId; }
ZT_INLINE int64_t timestamp() const noexcept
{
return m_ts;
}
ZT_INLINE int64_t timestamp() const noexcept { return m_ts; }
ZT_INLINE int64_t revision() const noexcept
{
return m_ts;
}
ZT_INLINE int64_t revision() const noexcept { return m_ts; }
ZT_INLINE uint32_t id() const noexcept
{
return m_id;
}
ZT_INLINE uint32_t id() const noexcept { return m_id; }
ZT_INLINE const Address& issuedTo() const noexcept
{
return m_issuedTo;
}
ZT_INLINE const Address &issuedTo() const noexcept { return m_issuedTo; }
ZT_INLINE const Address& signer() const noexcept
{
return m_signedBy;
}
ZT_INLINE const Address &signer() const noexcept { return m_signedBy; }
ZT_INLINE const uint8_t* signature() const noexcept
{
return m_signature;
}
ZT_INLINE const uint8_t *signature() const noexcept { return m_signature; }
ZT_INLINE unsigned int signatureLength() const noexcept
{
return m_signatureLength;
}
ZT_INLINE unsigned int signatureLength() const noexcept { return m_signatureLength; }
ZT_INLINE unsigned int thingCount() const noexcept
{
return (unsigned int)m_thingCount;
}
ZT_INLINE unsigned int thingCount() const noexcept { return (unsigned int)m_thingCount; }
ZT_INLINE Thing thingType(const unsigned int i) const noexcept
{
return (Thing)m_thingTypes[i];
}
ZT_INLINE Thing thingType(const unsigned int i) const noexcept { return (Thing)m_thingTypes[i]; }
ZT_INLINE const uint8_t* thingValue(const unsigned int i) const noexcept
{
return m_thingValues[i];
}
ZT_INLINE const uint8_t *thingValue(const unsigned int i) const noexcept { return m_thingValues[i]; }
ZT_INLINE bool owns(const InetAddress& ip) const noexcept
ZT_INLINE bool owns(const InetAddress &ip) const noexcept
{
if (ip.as.sa.sa_family == AF_INET)
return this->_owns(THING_IPV4_ADDRESS, &(reinterpret_cast<const struct sockaddr_in*>(&ip)->sin_addr.s_addr), 4);
return this->_owns(
THING_IPV4_ADDRESS, &(reinterpret_cast<const struct sockaddr_in *>(&ip)->sin_addr.s_addr), 4);
else if (ip.as.sa.sa_family == AF_INET6)
return this->_owns(THING_IPV6_ADDRESS, reinterpret_cast<const struct sockaddr_in6*>(&ip)->sin6_addr.s6_addr, 16);
return this->_owns(
THING_IPV6_ADDRESS, reinterpret_cast<const struct sockaddr_in6 *>(&ip)->sin6_addr.s6_addr, 16);
else
return false;
}
ZT_INLINE bool owns(const MAC& mac) const noexcept
ZT_INLINE bool owns(const MAC &mac) const noexcept
{
uint8_t tmp[6];
mac.copyTo(tmp);
@ -143,7 +108,7 @@ class OwnershipCredential : public Credential {
*
* @param ip IPv4 or IPv6 address
*/
void addThing(const InetAddress& ip);
void addThing(const InetAddress &ip);
/**
* Add an Ethernet MAC address
@ -154,7 +119,7 @@ class OwnershipCredential : public Credential {
*
* @param mac 48-bit MAC address
*/
void addThing(const MAC& mac);
void addThing(const MAC &mac);
/**
* Sign this certificate
@ -162,50 +127,44 @@ class OwnershipCredential : public Credential {
* @param signer Signing identity, must have private key
* @return True if signature was successful
*/
bool sign(const Identity& signer);
bool sign(const Identity &signer);
/**
* Verify certificate signature
*
* @return Credential verification result: OK, bad signature, or identity needed
*/
ZT_INLINE Credential::VerifyResult verify(const Context& ctx, const CallContext& cc) const
ZT_INLINE Credential::VerifyResult verify(const Context &ctx, const CallContext &cc) const
{
return s_verify(ctx, cc, *this);
}
static constexpr int marshalSizeMax() noexcept
{
return ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_SIZE_MAX;
}
static constexpr int marshalSizeMax() noexcept { return ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_SIZE_MAX; }
int marshal(uint8_t data[ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_SIZE_MAX], bool forSign = false) const noexcept;
int unmarshal(const uint8_t* data, int len) noexcept;
int unmarshal(const uint8_t *data, int len) noexcept;
// Provides natural sort order by ID
ZT_INLINE bool operator<(const OwnershipCredential& coo) const noexcept
{
return (m_id < coo.m_id);
}
ZT_INLINE bool operator<(const OwnershipCredential &coo) const noexcept { return (m_id < coo.m_id); }
ZT_INLINE bool operator==(const OwnershipCredential& coo) const noexcept
ZT_INLINE bool operator==(const OwnershipCredential &coo) const noexcept
{
return (memcmp(this, &coo, sizeof(OwnershipCredential)) == 0);
}
ZT_INLINE bool operator!=(const OwnershipCredential& coo) const noexcept
ZT_INLINE bool operator!=(const OwnershipCredential &coo) const noexcept
{
return (memcmp(this, &coo, sizeof(OwnershipCredential)) != 0);
}
private:
ZT_INLINE bool _owns(const Thing& t, const void* v, unsigned int l) const noexcept
ZT_INLINE bool _owns(const Thing &t, const void *v, unsigned int l) const noexcept
{
for (unsigned int i = 0, j = m_thingCount; i < j; ++i) {
if (m_thingTypes[i] == (uint8_t)t) {
unsigned int k = 0;
while (k < l) {
if (reinterpret_cast<const uint8_t*>(v)[k] != m_thingValues[i][k])
if (reinterpret_cast<const uint8_t *>(v)[k] != m_thingValues[i][k])
break;
++k;
}

View file

@ -18,9 +18,13 @@
namespace ZeroTier {
bool Path::send(const Context& ctx, const CallContext& cc, const void* const data, const unsigned int len) noexcept
bool Path::send(const Context &ctx, const CallContext &cc, const void *const data, const unsigned int len) noexcept
{
if (likely(ctx.cb.wirePacketSendFunction(reinterpret_cast<ZT_Node*>(ctx.node), ctx.uPtr, cc.tPtr, m_localSocket, reinterpret_cast<const ZT_InetAddress*>(&m_addr), data, len, 0) == 0)) {
if (likely(
ctx.cb.wirePacketSendFunction(
reinterpret_cast<ZT_Node *>(ctx.node), ctx.uPtr, cc.tPtr, m_localSocket,
reinterpret_cast<const ZT_InetAddress *>(&m_addr), data, len, 0)
== 0)) {
m_lastOut = cc.ticks;
m_outMeter.log(cc.ticks, len);
return true;

View file

@ -36,7 +36,8 @@ class Path {
friend class SharedPtr<Path>;
// Allow defragmenter to access fragment-in-flight info stored in Path for performance reasons.
template <unsigned int MF, unsigned int MFP, unsigned int GCT, unsigned int GCS, typename P> friend class Defragmenter;
template <unsigned int MF, unsigned int MFP, unsigned int GCT, unsigned int GCS, typename P>
friend class Defragmenter;
public:
/**
@ -44,53 +45,48 @@ class Path {
*/
class Key {
public:
ZT_INLINE Key() noexcept
{
}
ZT_INLINE Key() noexcept {}
ZT_INLINE Key(const InetAddress& ip) noexcept
ZT_INLINE Key(const InetAddress &ip) noexcept
{
const unsigned int family = ip.as.sa.sa_family;
if (family == AF_INET) {
const uint16_t p = (uint16_t)ip.as.sa_in.sin_port;
m_hashCode = Utils::hash64((((uint64_t)ip.as.sa_in.sin_addr.s_addr) << 16U) ^ ((uint64_t)p) ^ Utils::s_mapNonce);
m_hashCode =
Utils::hash64((((uint64_t)ip.as.sa_in.sin_addr.s_addr) << 16U) ^ ((uint64_t)p) ^ Utils::s_mapNonce);
m_ipv6Net64 = 0; // 0 for IPv4, never 0 for IPv6
m_port = p;
m_port = p;
}
else {
if (likely(family == AF_INET6)) {
const uint64_t a = Utils::loadMachineEndian<uint64_t>(reinterpret_cast<const uint8_t*>(ip.as.sa_in6.sin6_addr.s6_addr));
const uint64_t b = Utils::loadMachineEndian<uint64_t>(reinterpret_cast<const uint8_t*>(ip.as.sa_in6.sin6_addr.s6_addr) + 8);
const uint64_t a = Utils::loadMachineEndian<uint64_t>(
reinterpret_cast<const uint8_t *>(ip.as.sa_in6.sin6_addr.s6_addr));
const uint64_t b = Utils::loadMachineEndian<uint64_t>(
reinterpret_cast<const uint8_t *>(ip.as.sa_in6.sin6_addr.s6_addr) + 8);
const uint16_t p = ip.as.sa_in6.sin6_port;
m_hashCode = Utils::hash64(a ^ b ^ ((uint64_t)p) ^ Utils::s_mapNonce);
m_ipv6Net64 = a; // IPv6 /64
m_port = p;
m_hashCode = Utils::hash64(a ^ b ^ ((uint64_t)p) ^ Utils::s_mapNonce);
m_ipv6Net64 = a; // IPv6 /64
m_port = p;
}
else {
// This is not reachable since InetAddress can only be AF_INET or AF_INET6, but implement something.
m_hashCode = Utils::fnv1a32(&ip, sizeof(InetAddress));
m_hashCode = Utils::fnv1a32(&ip, sizeof(InetAddress));
m_ipv6Net64 = 0;
m_port = (uint16_t)family;
m_port = (uint16_t)family;
}
}
}
ZT_INLINE unsigned long hashCode() const noexcept
{
return (unsigned long)m_hashCode;
}
ZT_INLINE unsigned long hashCode() const noexcept { return (unsigned long)m_hashCode; }
ZT_INLINE bool operator==(const Key& k) const noexcept
ZT_INLINE bool operator==(const Key &k) const noexcept
{
return (m_hashCode == k.m_hashCode) && (m_ipv6Net64 == k.m_ipv6Net64) && (m_port == k.m_port);
}
ZT_INLINE bool operator!=(const Key& k) const noexcept
{
return (! (*this == k));
}
ZT_INLINE bool operator!=(const Key &k) const noexcept { return (!(*this == k)); }
ZT_INLINE bool operator<(const Key& k) const noexcept
ZT_INLINE bool operator<(const Key &k) const noexcept
{
if (m_hashCode < k.m_hashCode) {
return true;
@ -106,20 +102,11 @@ class Path {
return false;
}
ZT_INLINE bool operator>(const Key& k) const noexcept
{
return (k < *this);
}
ZT_INLINE bool operator>(const Key &k) const noexcept { return (k < *this); }
ZT_INLINE bool operator<=(const Key& k) const noexcept
{
return ! (k < *this);
}
ZT_INLINE bool operator<=(const Key &k) const noexcept { return !(k < *this); }
ZT_INLINE bool operator>=(const Key& k) const noexcept
{
return ! (*this < k);
}
ZT_INLINE bool operator>=(const Key &k) const noexcept { return !(*this < k); }
private:
uint64_t m_hashCode;
@ -127,7 +114,7 @@ class Path {
uint16_t m_port;
};
ZT_INLINE Path(const int64_t l, const InetAddress& r) noexcept
ZT_INLINE Path(const int64_t l, const InetAddress &r) noexcept
: m_localSocket(l)
, m_lastIn(0)
, m_lastOut(0)
@ -143,7 +130,7 @@ class Path {
* @param len Packet length
* @return True if transport reported success
*/
bool send(const Context& ctx, const CallContext& cc, const void* data, unsigned int len) noexcept;
bool send(const Context &ctx, const CallContext &cc, const void *data, unsigned int len) noexcept;
/**
* Explicitly update last sent time
@ -151,7 +138,7 @@ class Path {
* @param now Time of send
* @param bytes Bytes sent
*/
ZT_INLINE void sent(const CallContext& cc, const unsigned int bytes) noexcept
ZT_INLINE void sent(const CallContext &cc, const unsigned int bytes) noexcept
{
m_lastOut.store(cc.ticks, std::memory_order_relaxed);
m_outMeter.log(cc.ticks, bytes);
@ -163,7 +150,7 @@ class Path {
* @param now Time of receive
* @param bytes Bytes received
*/
ZT_INLINE void received(const CallContext& cc, const unsigned int bytes) noexcept
ZT_INLINE void received(const CallContext &cc, const unsigned int bytes) noexcept
{
m_lastIn.store(cc.ticks, std::memory_order_relaxed);
m_inMeter.log(cc.ticks, bytes);
@ -188,17 +175,14 @@ class Path {
/**
* @return Latency in milliseconds or -1 if unknown
*/
ZT_INLINE int latency() const noexcept
{
return m_latency.load(std::memory_order_relaxed);
}
ZT_INLINE int latency() const noexcept { return m_latency.load(std::memory_order_relaxed); }
/**
* Check path aliveness
*
* @param now Current time
*/
ZT_INLINE bool alive(const CallContext& cc) const noexcept
ZT_INLINE bool alive(const CallContext &cc) const noexcept
{
return ((cc.ticks - m_lastIn.load(std::memory_order_relaxed)) < ZT_PATH_ALIVE_TIMEOUT);
}
@ -206,34 +190,22 @@ class Path {
/**
* @return Physical address
*/
ZT_INLINE const InetAddress& address() const noexcept
{
return m_addr;
}
ZT_INLINE const InetAddress &address() const noexcept { return m_addr; }
/**
* @return Local socket as specified by external code
*/
ZT_INLINE int64_t localSocket() const noexcept
{
return m_localSocket;
}
ZT_INLINE int64_t localSocket() const noexcept { return m_localSocket; }
/**
* @return Last time we received anything
*/
ZT_INLINE int64_t lastIn() const noexcept
{
return m_lastIn.load(std::memory_order_relaxed);
}
ZT_INLINE int64_t lastIn() const noexcept { return m_lastIn.load(std::memory_order_relaxed); }
/**
* @return Last time we sent something
*/
ZT_INLINE int64_t lastOut() const noexcept
{
return m_lastOut.load(std::memory_order_relaxed);
}
ZT_INLINE int64_t lastOut() const noexcept { return m_lastOut.load(std::memory_order_relaxed); }
private:
const int64_t m_localSocket;

View file

@ -46,19 +46,16 @@ Peer::Peer()
{
}
Peer::~Peer()
{
Utils::burn(m_helloMacKey, sizeof(m_helloMacKey));
}
Peer::~Peer() { Utils::burn(m_helloMacKey, sizeof(m_helloMacKey)); }
bool Peer::init(const Context& ctx, const CallContext& cc, const Identity& peerIdentity)
bool Peer::init(const Context &ctx, const CallContext &cc, const Identity &peerIdentity)
{
RWMutex::Lock l(m_lock);
m_id = peerIdentity;
uint8_t k[ZT_SYMMETRIC_KEY_SIZE];
if (unlikely(! ctx.identity.agree(peerIdentity, k)))
if (unlikely(!ctx.identity.agree(peerIdentity, k)))
return false;
m_identityKey.init(cc.ticks, k);
Utils::burn(k, sizeof(k));
@ -68,7 +65,10 @@ bool Peer::init(const Context& ctx, const CallContext& cc, const Identity& peerI
return true;
}
void Peer::received(const Context& ctx, const CallContext& cc, const SharedPtr<Path>& path, const unsigned int hops, const uint64_t packetId, const unsigned int payloadLength, const Protocol::Verb verb, const Protocol::Verb /*inReVerb*/)
void Peer::received(
const Context &ctx, const CallContext &cc, const SharedPtr<Path> &path, const unsigned int hops,
const uint64_t packetId, const unsigned int payloadLength, const Protocol::Verb verb,
const Protocol::Verb /*inReVerb*/)
{
m_lastReceive.store(cc.ticks, std::memory_order_relaxed);
m_inMeter.log(cc.ticks, payloadLength);
@ -110,7 +110,7 @@ void Peer::received(const Context& ctx, const CallContext& cc, const SharedPtr<P
// Save a reference to the current path in case we replace it. This
// should technically never happen, but this ensures safety if it does.
const SharedPtr<Path> currentBest(reinterpret_cast<Path*>(m_bestPath.load(std::memory_order_acquire)));
const SharedPtr<Path> currentBest(reinterpret_cast<Path *>(m_bestPath.load(std::memory_order_acquire)));
SharedPtr<Path> old;
old.move(m_paths[newPathIdx]);
@ -118,23 +118,25 @@ void Peer::received(const Context& ctx, const CallContext& cc, const SharedPtr<P
m_prioritizePaths(cc);
ctx.t->learnedNewPath(cc, 0x582fabdd, packetId, m_id, path->address(), (old) ? old->address() : InetAddress());
ctx.t->learnedNewPath(
cc, 0x582fabdd, packetId, m_id, path->address(), (old) ? old->address() : InetAddress());
}
else {
int64_t& lt = m_lastTried[Endpoint(path->address())];
int64_t &lt = m_lastTried[Endpoint(path->address())];
if ((cc.ticks - lt) < ZT_PATH_MIN_TRY_INTERVAL) {
lt = cc.ticks;
path->sent(cc, m_hello(ctx, cc, path->localSocket(), path->address(), false));
ctx.t->tryingNewPath(cc, 0xb7747ddd, m_id, path->address(), path->address(), packetId, (uint8_t)verb, m_id);
ctx.t->tryingNewPath(
cc, 0xb7747ddd, m_id, path->address(), path->address(), packetId, (uint8_t)verb, m_id);
}
}
}
}
}
void Peer::send(const Context& ctx, const CallContext& cc, const void* data, unsigned int len) noexcept
void Peer::send(const Context &ctx, const CallContext &cc, const void *data, unsigned int len) noexcept
{
SharedPtr<Path> via(reinterpret_cast<Path*>(m_bestPath.load(std::memory_order_acquire)));
SharedPtr<Path> via(reinterpret_cast<Path *>(m_bestPath.load(std::memory_order_acquire)));
if (likely(via)) {
if (likely(via->send(ctx, cc, data, len)))
this->sent(cc, len);
@ -153,18 +155,21 @@ void Peer::send(const Context& ctx, const CallContext& cc, const void* data, uns
}
}
void Peer::pulse(const Context& ctx, const CallContext& cc)
void Peer::pulse(const Context &ctx, const CallContext &cc)
{
RWMutex::Lock l(m_lock);
// Grab current key (this is never NULL).
SymmetricKey* const key = reinterpret_cast<SymmetricKey*>(m_key.load(std::memory_order_relaxed));
SymmetricKey *const key = reinterpret_cast<SymmetricKey *>(m_key.load(std::memory_order_relaxed));
// Determine if we need a new ephemeral key pair and if a new HELLO needs
// to be sent. The latter happens every ZT_PEER_HELLO_INTERVAL or if a new
// ephemeral key pair is generated.
bool needHello =
(((m_vProto >= 20) && (m_keyRenegotiationNeeded || (key == &m_identityKey) || ((cc.ticks - key->timestamp()) >= (ZT_SYMMETRIC_KEY_TTL / 2)) || (key->odometer() > (ZT_SYMMETRIC_KEY_TTL_MESSAGES / 2))))
(((m_vProto >= 20)
&& (m_keyRenegotiationNeeded || (key == &m_identityKey)
|| ((cc.ticks - key->timestamp()) >= (ZT_SYMMETRIC_KEY_TTL / 2))
|| (key->odometer() > (ZT_SYMMETRIC_KEY_TTL_MESSAGES / 2))))
|| ((cc.ticks - m_lastSentHello) >= ZT_PEER_HELLO_INTERVAL));
// Prioritize paths and more importantly for here forget dead ones.
@ -177,13 +182,16 @@ void Peer::pulse(const Context& ctx, const CallContext& cc)
// callback (if one was supplied).
if (m_locator) {
for (Vector<std::pair<Endpoint, SharedPtr<const Locator::EndpointAttributes> > >::const_iterator ep(m_locator->endpoints().begin()); ep != m_locator->endpoints().end(); ++ep) {
for (Vector<std::pair<Endpoint, SharedPtr<const Locator::EndpointAttributes>>>::const_iterator ep(
m_locator->endpoints().begin());
ep != m_locator->endpoints().end(); ++ep) {
if (ep->first.type == ZT_ENDPOINT_TYPE_IP_UDP) {
if (ctx.node->filterPotentialPath(cc.tPtr, m_id, -1, ep->first.ip())) {
int64_t& lt = m_lastTried[ep->first];
int64_t &lt = m_lastTried[ep->first];
if ((cc.ticks - lt) > ZT_PATH_MIN_TRY_INTERVAL) {
lt = cc.ticks;
ctx.t->tryingNewPath(cc, 0x84b22322, m_id, ep->first.ip(), InetAddress::NIL, 0, 0, Identity::NIL);
ctx.t->tryingNewPath(
cc, 0x84b22322, m_id, ep->first.ip(), InetAddress::NIL, 0, 0, Identity::NIL);
sent(cc, m_sendProbe(ctx, cc, -1, ep->first.ip(), nullptr, 0));
}
}
@ -194,7 +202,7 @@ void Peer::pulse(const Context& ctx, const CallContext& cc)
InetAddress addr;
if (ctx.node->externalPathLookup(cc.tPtr, m_id, -1, addr)) {
if ((addr) && ctx.node->filterPotentialPath(cc.tPtr, m_id, -1, addr)) {
int64_t& lt = m_lastTried[Endpoint(addr)];
int64_t &lt = m_lastTried[Endpoint(addr)];
if ((cc.ticks - lt) > ZT_PATH_MIN_TRY_INTERVAL) {
lt = cc.ticks;
ctx.t->tryingNewPath(cc, 0x84a10000, m_id, addr, InetAddress::NIL, 0, 0, Identity::NIL);
@ -207,7 +215,7 @@ void Peer::pulse(const Context& ctx, const CallContext& cc)
else {
unsigned int attempts = 0;
for (;;) {
p_TryQueueItem& qi = m_tryQueue.front();
p_TryQueueItem &qi = m_tryQueue.front();
if (qi.target.isInetAddr()) {
// Skip entry if it overlaps with any currently active IP.
@ -290,11 +298,12 @@ void Peer::pulse(const Context& ctx, const CallContext& cc)
for (unsigned int i = 0; i < m_alivePathCount; ++i) {
if (needHello) {
needHello = false;
const unsigned int bytes = m_hello(ctx, cc, m_paths[i]->localSocket(), m_paths[i]->address(), m_keyRenegotiationNeeded);
const unsigned int bytes =
m_hello(ctx, cc, m_paths[i]->localSocket(), m_paths[i]->address(), m_keyRenegotiationNeeded);
if (bytes) {
m_paths[i]->sent(cc, bytes);
sent(cc, bytes);
m_lastSentHello = cc.ticks;
m_lastSentHello = cc.ticks;
m_keyRenegotiationNeeded = false;
}
}
@ -311,12 +320,13 @@ void Peer::pulse(const Context& ctx, const CallContext& cc)
if (root) {
const SharedPtr<Path> via(root->path(cc));
if (via) {
const unsigned int bytes = m_hello(ctx, cc, via->localSocket(), via->address(), m_keyRenegotiationNeeded);
const unsigned int bytes =
m_hello(ctx, cc, via->localSocket(), via->address(), m_keyRenegotiationNeeded);
if (bytes) {
via->sent(cc, bytes);
root->relayed(cc, bytes);
sent(cc, bytes);
m_lastSentHello = cc.ticks;
m_lastSentHello = cc.ticks;
m_keyRenegotiationNeeded = false;
}
}
@ -332,7 +342,7 @@ void Peer::pulse(const Context& ctx, const CallContext& cc)
}
}
void Peer::contact(const Context& ctx, const CallContext& cc, const Endpoint& ep, int tries)
void Peer::contact(const Context &ctx, const CallContext &cc, const Endpoint &ep, int tries)
{
RWMutex::Lock l(m_lock);
@ -345,7 +355,7 @@ void Peer::contact(const Context& ctx, const CallContext& cc, const Endpoint& ep
}
// Check underlying path attempt rate limit.
int64_t& lt = m_lastTried[ep];
int64_t &lt = m_lastTried[ep];
if ((cc.ticks - lt) < ZT_PATH_MIN_TRY_INTERVAL)
return;
lt = cc.ticks;
@ -353,14 +363,16 @@ void Peer::contact(const Context& ctx, const CallContext& cc, const Endpoint& ep
// For IPv4 addresses we send a tiny packet with a low TTL, which helps to
// traverse some NAT types. It has no effect otherwise.
if (ep.isInetAddr() && ep.ip().isV4()) {
ctx.cb.wirePacketSendFunction(reinterpret_cast<ZT_Node*>(ctx.node), ctx.uPtr, cc.tPtr, -1, reinterpret_cast<const ZT_InetAddress*>(&ep.ip()), &s_arbitraryByte, 1, 2);
ctx.cb.wirePacketSendFunction(
reinterpret_cast<ZT_Node *>(ctx.node), ctx.uPtr, cc.tPtr, -1,
reinterpret_cast<const ZT_InetAddress *>(&ep.ip()), &s_arbitraryByte, 1, 2);
++s_arbitraryByte;
}
// Make sure address is not already in the try queue. If so just update it.
for (List<p_TryQueueItem>::iterator i(m_tryQueue.begin()); i != m_tryQueue.end(); ++i) {
if (i->target.isSameAddress(ep)) {
i->target = ep;
i->target = ep;
i->iteration = -tries;
return;
}
@ -369,13 +381,17 @@ void Peer::contact(const Context& ctx, const CallContext& cc, const Endpoint& ep
m_tryQueue.push_back(p_TryQueueItem(ep, -tries));
}
void Peer::resetWithinScope(const Context& ctx, const CallContext& cc, InetAddress::IpScope scope, int inetAddressFamily)
void Peer::resetWithinScope(
const Context &ctx, const CallContext &cc, InetAddress::IpScope scope, int inetAddressFamily)
{
RWMutex::Lock l(m_lock);
unsigned int pc = 0;
for (unsigned int i = 0; i < m_alivePathCount; ++i) {
if ((m_paths[i]) && (((int)m_paths[i]->address().as.sa.sa_family == inetAddressFamily) && (m_paths[i]->address().ipScope() == scope))) {
const unsigned int bytes = m_sendProbe(ctx, cc, m_paths[i]->localSocket(), m_paths[i]->address(), nullptr, 0);
if ((m_paths[i])
&& (((int)m_paths[i]->address().as.sa.sa_family == inetAddressFamily)
&& (m_paths[i]->address().ipScope() == scope))) {
const unsigned int bytes =
m_sendProbe(ctx, cc, m_paths[i]->localSocket(), m_paths[i]->address(), nullptr, 0);
m_paths[i]->sent(cc, bytes);
sent(cc, bytes);
}
@ -388,7 +404,7 @@ void Peer::resetWithinScope(const Context& ctx, const CallContext& cc, InetAddre
m_paths[pc++].zero();
}
void Peer::save(const Context& ctx, const CallContext& cc) const
void Peer::save(const Context &ctx, const CallContext &cc) const
{
uint8_t buf[8 + ZT_PEER_MARSHAL_SIZE_MAX];
@ -404,7 +420,7 @@ void Peer::save(const Context& ctx, const CallContext& cc) const
}
}
int Peer::marshal(const Context& ctx, uint8_t data[ZT_PEER_MARSHAL_SIZE_MAX]) const noexcept
int Peer::marshal(const Context &ctx, uint8_t data[ZT_PEER_MARSHAL_SIZE_MAX]) const noexcept
{
RWMutex::RLock l(m_lock);
@ -430,7 +446,7 @@ int Peer::marshal(const Context& ctx, uint8_t data[ZT_PEER_MARSHAL_SIZE_MAX]) co
if (m_locator) {
data[p++] = 1;
s = m_locator->marshal(data + p);
s = m_locator->marshal(data + p);
if (s <= 0)
return s;
p += s;
@ -454,7 +470,7 @@ int Peer::marshal(const Context& ctx, uint8_t data[ZT_PEER_MARSHAL_SIZE_MAX]) co
return p;
}
int Peer::unmarshal(const Context& ctx, const int64_t ticks, const uint8_t* restrict data, const int len) noexcept
int Peer::unmarshal(const Context &ctx, const int64_t ticks, const uint8_t *restrict data, const int len) noexcept
{
RWMutex::Lock l(m_lock);
@ -463,14 +479,16 @@ int Peer::unmarshal(const Context& ctx, const int64_t ticks, const uint8_t* rest
for (unsigned int i = 0; i < ZT_PEER_EPHEMERAL_KEY_BUFFER_SIZE; ++i) {
m_ephemeralKeysSent[i].creationTime = -1;
m_ephemeralSessions[i].established = false;
m_ephemeralSessions[i].established = false;
}
m_key.store((uintptr_t)&m_identityKey, std::memory_order_relaxed);
bool identityKeyRestored = false;
if (Address(data + 1) == ctx.identity.address()) {
uint8_t k[ZT_SYMMETRIC_KEY_SIZE];
static_assert(ZT_SYMMETRIC_KEY_SIZE == 48, "marshal() and unmarshal() must be revisited if ZT_SYMMETRIC_KEY_SIZE is changed");
static_assert(
ZT_SYMMETRIC_KEY_SIZE == 48,
"marshal() and unmarshal() must be revisited if ZT_SYMMETRIC_KEY_SIZE is changed");
ctx.localSecretCipher.decrypt(data + 1 + ZT_ADDRESS_LENGTH, k);
ctx.localSecretCipher.decrypt(data + 1 + ZT_ADDRESS_LENGTH + 16, k + 16);
ctx.localSecretCipher.decrypt(data + 1 + ZT_ADDRESS_LENGTH + 32, k + 32);
@ -486,9 +504,9 @@ int Peer::unmarshal(const Context& ctx, const int64_t ticks, const uint8_t* rest
return s;
p += s;
if (! identityKeyRestored) {
if (!identityKeyRestored) {
uint8_t k[ZT_SYMMETRIC_KEY_SIZE];
if (! ctx.identity.agree(m_id, k))
if (!ctx.identity.agree(m_id, k))
return -1;
m_identityKey.init(ticks, k);
Utils::burn(k, sizeof(k));
@ -502,8 +520,8 @@ int Peer::unmarshal(const Context& ctx, const int64_t ticks, const uint8_t* rest
}
else if (data[p] == 1) {
++p;
Locator* const loc = new Locator();
s = loc->unmarshal(data + p, len - p);
Locator *const loc = new Locator();
s = loc->unmarshal(data + p, len - p);
m_locator.set(loc);
if (s < 0)
return s;
@ -531,7 +549,7 @@ int Peer::unmarshal(const Context& ctx, const int64_t ticks, const uint8_t* rest
}
struct _PathPriorityComparisonOperator {
ZT_INLINE bool operator()(const SharedPtr<Path>& a, const SharedPtr<Path>& b) const noexcept
ZT_INLINE bool operator()(const SharedPtr<Path> &a, const SharedPtr<Path> &b) const noexcept
{
if (a) {
if (b)
@ -545,12 +563,12 @@ struct _PathPriorityComparisonOperator {
}
};
void Peer::m_prioritizePaths(const CallContext& cc)
void Peer::m_prioritizePaths(const CallContext &cc)
{
// assumes m_lock is locked
// Need to hold the current best just in case we drop it before changing the atomic.
const SharedPtr<Path> oldBest(reinterpret_cast<Path*>(m_bestPath.load(std::memory_order_acquire)));
const SharedPtr<Path> oldBest(reinterpret_cast<Path *>(m_bestPath.load(std::memory_order_acquire)));
// Clean and reprioritize paths.
if (m_alivePathCount != 0) {
@ -573,7 +591,9 @@ void Peer::m_prioritizePaths(const CallContext& cc)
m_bestPath.store((m_alivePathCount != 0) ? (uintptr_t)m_paths[0].ptr() : (uintptr_t)0, std::memory_order_release);
}
unsigned int Peer::m_sendProbe(const Context& ctx, const CallContext& cc, int64_t localSocket, const InetAddress& atAddress, const uint16_t* ports, const unsigned int numPorts)
unsigned int Peer::m_sendProbe(
const Context &ctx, const CallContext &cc, int64_t localSocket, const InetAddress &atAddress, const uint16_t *ports,
const unsigned int numPorts)
{
// Assumes m_lock is locked
@ -582,11 +602,12 @@ unsigned int Peer::m_sendProbe(const Context& ctx, const CallContext& cc, int64_
// some future attacker compromises it.
uint8_t p[ZT_PROTO_MIN_PACKET_LENGTH];
Utils::storeMachineEndian<uint64_t>(p + ZT_PROTO_PACKET_ID_INDEX, m_identityKey.nextMessage(ctx.identity.address(), m_id.address()));
Utils::storeMachineEndian<uint64_t>(
p + ZT_PROTO_PACKET_ID_INDEX, m_identityKey.nextMessage(ctx.identity.address(), m_id.address()));
m_id.address().copyTo(p + ZT_PROTO_PACKET_DESTINATION_INDEX);
ctx.identity.address().copyTo(p + ZT_PROTO_PACKET_SOURCE_INDEX);
p[ZT_PROTO_PACKET_FLAGS_INDEX] = 0;
p[ZT_PROTO_PACKET_VERB_INDEX] = Protocol::VERB_NOP;
p[ZT_PROTO_PACKET_VERB_INDEX] = Protocol::VERB_NOP;
ctx.expect->sending(Protocol::armor(p, ZT_PROTO_MIN_PACKET_LENGTH, m_identityKey, cipher()), cc.ticks);
@ -594,12 +615,16 @@ unsigned int Peer::m_sendProbe(const Context& ctx, const CallContext& cc, int64_
InetAddress tmp(atAddress);
for (unsigned int i = 0; i < numPorts; ++i) {
tmp.setPort(ports[i]);
ctx.cb.wirePacketSendFunction(reinterpret_cast<ZT_Node*>(ctx.node), ctx.uPtr, cc.tPtr, -1, reinterpret_cast<const ZT_InetAddress*>(&tmp), p, ZT_PROTO_MIN_PACKET_LENGTH, 0);
ctx.cb.wirePacketSendFunction(
reinterpret_cast<ZT_Node *>(ctx.node), ctx.uPtr, cc.tPtr, -1,
reinterpret_cast<const ZT_InetAddress *>(&tmp), p, ZT_PROTO_MIN_PACKET_LENGTH, 0);
}
return ZT_PROTO_MIN_PACKET_LENGTH * numPorts;
}
else {
ctx.cb.wirePacketSendFunction(reinterpret_cast<ZT_Node*>(ctx.node), ctx.uPtr, cc.tPtr, -1, reinterpret_cast<const ZT_InetAddress*>(&atAddress), p, ZT_PROTO_MIN_PACKET_LENGTH, 0);
ctx.cb.wirePacketSendFunction(
reinterpret_cast<ZT_Node *>(ctx.node), ctx.uPtr, cc.tPtr, -1,
reinterpret_cast<const ZT_InetAddress *>(&atAddress), p, ZT_PROTO_MIN_PACKET_LENGTH, 0);
return ZT_PROTO_MIN_PACKET_LENGTH;
}
}
@ -618,7 +643,9 @@ void Peer::m_deriveSecondaryIdentityKeys() noexcept
KBKDFHMACSHA384(m_identityKey.key(), ZT_KBKDF_LABEL_PACKET_HMAC, 0, 0, m_helloMacKey);
}
unsigned int Peer::m_hello(const Context& ctx, const CallContext& cc, int64_t localSocket, const InetAddress& atAddress, const bool forceNewKey)
unsigned int Peer::m_hello(
const Context &ctx, const CallContext &cc, int64_t localSocket, const InetAddress &atAddress,
const bool forceNewKey)
{
// assumes m_lock is at least locked for reading
@ -633,30 +660,30 @@ unsigned int Peer::m_hello(const Context& ctx, const CallContext& cc, int64_t lo
* here is also needed to satisfy some FIPS/NIST type requirements. */
// Pick or generate an ephemeral key to send with this HELLO.
p_EphemeralPrivate* ephemeral;
p_EphemeralPrivate *ephemeral;
{
p_EphemeralPrivate* earliest = m_ephemeralKeysSent;
p_EphemeralPrivate* latest = nullptr;
p_EphemeralPrivate *earliest = m_ephemeralKeysSent;
p_EphemeralPrivate *latest = nullptr;
int64_t earliestEphemeralPrivate = 9223372036854775807LL;
int64_t latestEphemeralPrivate = 0;
int64_t latestEphemeralPrivate = 0;
for (unsigned int k = 0; k < ZT_PEER_EPHEMERAL_KEY_BUFFER_SIZE; ++k) {
const int64_t ct = m_ephemeralKeysSent[k].creationTime;
if (ct <= earliestEphemeralPrivate) {
earliestEphemeralPrivate = ct;
earliest = m_ephemeralKeysSent + k;
earliest = m_ephemeralKeysSent + k;
}
else if (ct >= latestEphemeralPrivate) { // creationTime will be -1 if not initialized
latestEphemeralPrivate = ct;
latest = m_ephemeralKeysSent + k;
latest = m_ephemeralKeysSent + k;
}
}
if ((latest != nullptr) && (! forceNewKey) && ((cc.ticks - latest->creationTime) < (ZT_SYMMETRIC_KEY_TTL / 2))) {
if ((latest != nullptr) && (!forceNewKey) && ((cc.ticks - latest->creationTime) < (ZT_SYMMETRIC_KEY_TTL / 2))) {
ephemeral = latest;
}
else {
earliest->creationTime = cc.ticks;
earliest->pub.type = ZT_PROTO_EPHEMERAL_KEY_TYPE_C25519_P384;
earliest->pub.type = ZT_PROTO_EPHEMERAL_KEY_TYPE_C25519_P384;
C25519::generateC25519(earliest->pub.c25519Public, earliest->c25519Private);
ECC384GenerateKey(earliest->pub.p384Public, earliest->p384Private);
SHA384(earliest->sha384OfPublic, &earliest->pub, sizeof(earliest->pub));
@ -683,7 +710,7 @@ unsigned int Peer::m_hello(const Context& ctx, const CallContext& cc, int64_t lo
// LEGACY: the six reserved bytes after the IV exist for legacy compatibility with v1.x nodes.
// Once those are dead they'll become just reserved bytes for future use as flags etc.
outp.wI32(ii, 0); // reserved bytes
void* const legacyMoonCountStart = outp.unsafeData + ii;
void *const legacyMoonCountStart = outp.unsafeData + ii;
outp.wI16(ii, 0);
const uint64_t legacySalsaIv = packetId & ZT_CONST_TO_BE_UINT64(0xfffffffffffffff8ULL);
Salsa20(m_identityKey.key(), &legacySalsaIv).crypt12(legacyMoonCountStart, legacyMoonCountStart, 2);
@ -705,7 +732,7 @@ unsigned int Peer::m_hello(const Context& ctx, const CallContext& cc, int64_t lo
// particular this means that the public keys exchanged for ephemeral keying
// are concealed from any observer.
AES::CTR ctr(m_helloCipher);
void* const cryptSection = outp.unsafeData + ii;
void *const cryptSection = outp.unsafeData + ii;
ctr.init(outp.unsafeData + ivStart, 0, cryptSection);
ctr.crypt(cryptSection, ii - cryptSectionStart);
ctr.finish();
@ -719,12 +746,19 @@ unsigned int Peer::m_hello(const Context& ctx, const CallContext& cc, int64_t lo
Protocol::salsa2012DeriveKey(m_identityKey.key(), perPacketKey, outp, ii);
Salsa20(perPacketKey, &packetId).crypt12(Utils::ZERO256, polyKey, sizeof(polyKey));
Poly1305 p1305(polyKey);
p1305.update(outp.unsafeData + ZT_PROTO_PACKET_ENCRYPTED_SECTION_START, ii - ZT_PROTO_PACKET_ENCRYPTED_SECTION_START);
p1305.update(
outp.unsafeData + ZT_PROTO_PACKET_ENCRYPTED_SECTION_START, ii - ZT_PROTO_PACKET_ENCRYPTED_SECTION_START);
uint64_t polyMac[2];
p1305.finish(polyMac);
Utils::storeMachineEndian<uint64_t>(outp.unsafeData + ZT_PROTO_PACKET_MAC_INDEX, polyMac[0]);
return (likely(ctx.cb.wirePacketSendFunction(reinterpret_cast<ZT_Node*>(ctx.node), ctx.uPtr, cc.tPtr, localSocket, reinterpret_cast<const ZT_InetAddress*>(&atAddress), outp.unsafeData, ii, 0) == 0)) ? (unsigned int)ii : 0U;
return (likely(
ctx.cb.wirePacketSendFunction(
reinterpret_cast<ZT_Node *>(ctx.node), ctx.uPtr, cc.tPtr, localSocket,
reinterpret_cast<const ZT_InetAddress *>(&atAddress), outp.unsafeData, ii, 0)
== 0))
? (unsigned int)ii
: 0U;
}
} // namespace ZeroTier

View file

@ -31,7 +31,9 @@
#include "SymmetricKey.hpp"
#include "Utils.hpp"
#define ZT_PEER_MARSHAL_SIZE_MAX (1 + ZT_ADDRESS_LENGTH + ZT_SYMMETRIC_KEY_SIZE + ZT_IDENTITY_MARSHAL_SIZE_MAX + 1 + ZT_LOCATOR_MARSHAL_SIZE_MAX + (2 * 4) + 2)
#define ZT_PEER_MARSHAL_SIZE_MAX \
(1 + ZT_ADDRESS_LENGTH + ZT_SYMMETRIC_KEY_SIZE + ZT_IDENTITY_MARSHAL_SIZE_MAX + 1 + ZT_LOCATOR_MARSHAL_SIZE_MAX \
+ (2 * 4) + 2)
#define ZT_PEER_DEDUP_BUFFER_SIZE 1024
#define ZT_PEER_DEDUP_BUFFER_MASK 1023U
@ -66,23 +68,17 @@ class Peer {
* @param peerIdentity The peer's identity
* @return True if initialization was succcesful
*/
bool init(const Context& ctx, const CallContext& cc, const Identity& peerIdentity);
bool init(const Context &ctx, const CallContext &cc, const Identity &peerIdentity);
/**
* @return This peer's ZT address (short for identity().address())
*/
ZT_INLINE Address address() const noexcept
{
return m_id.address();
}
ZT_INLINE Address address() const noexcept { return m_id.address(); }
/**
* @return This peer's identity
*/
ZT_INLINE const Identity& identity() const noexcept
{
return m_id;
}
ZT_INLINE const Identity &identity() const noexcept { return m_id; }
/**
* @return Current locator or NULL if no locator is known
@ -103,11 +99,11 @@ class Peer {
* @param verify If true, verify locator's signature and structure
* @return New locator or previous if it was not replaced.
*/
ZT_INLINE SharedPtr<const Locator> setLocator(const SharedPtr<const Locator>& loc, const bool verify) noexcept
ZT_INLINE SharedPtr<const Locator> setLocator(const SharedPtr<const Locator> &loc, const bool verify) noexcept
{
RWMutex::Lock l(m_lock);
if ((loc) && ((! m_locator) || (m_locator->revision() < loc->revision()))) {
if ((! verify) || loc->verify(m_id))
if ((loc) && ((!m_locator) || (m_locator->revision() < loc->revision()))) {
if ((!verify) || loc->verify(m_id))
m_locator = loc;
}
return m_locator;
@ -125,14 +121,16 @@ class Peer {
* @param verb Packet verb
* @param inReVerb In-reply verb for OK or ERROR verbs
*/
void received(const Context& ctx, const CallContext& cc, const SharedPtr<Path>& path, unsigned int hops, uint64_t packetId, unsigned int payloadLength, Protocol::Verb verb, Protocol::Verb inReVerb);
void received(
const Context &ctx, const CallContext &cc, const SharedPtr<Path> &path, unsigned int hops, uint64_t packetId,
unsigned int payloadLength, Protocol::Verb verb, Protocol::Verb inReVerb);
/**
* Log sent data
*
* @param bytes Number of bytes written
*/
ZT_INLINE void sent(const CallContext& cc, const unsigned int bytes) noexcept
ZT_INLINE void sent(const CallContext &cc, const unsigned int bytes) noexcept
{
m_lastSend.store(cc.ticks, std::memory_order_relaxed);
m_outMeter.log(cc.ticks, bytes);
@ -143,7 +141,7 @@ class Peer {
*
* @param bytes Number of bytes relayed
*/
ZT_INLINE void relayed(const CallContext& cc, const unsigned int bytes) noexcept
ZT_INLINE void relayed(const CallContext &cc, const unsigned int bytes) noexcept
{
m_relayedMeter.log(cc.ticks, bytes);
}
@ -153,9 +151,9 @@ class Peer {
*
* @return Current best path or NULL if there is no direct path
*/
ZT_INLINE SharedPtr<Path> path(const CallContext& cc) noexcept
ZT_INLINE SharedPtr<Path> path(const CallContext &cc) noexcept
{
return SharedPtr<Path>(reinterpret_cast<Path*>(m_bestPath.load(std::memory_order_acquire)));
return SharedPtr<Path>(reinterpret_cast<Path *>(m_bestPath.load(std::memory_order_acquire)));
}
/**
@ -165,7 +163,9 @@ class Peer {
* @param len Length in bytes
* @param via Path over which to send data (may or may not be an already-learned path for this peer)
*/
ZT_INLINE void send(const Context& ctx, const CallContext& cc, const void* data, unsigned int len, const SharedPtr<Path>& via) noexcept
ZT_INLINE void send(
const Context &ctx, const CallContext &cc, const void *data, unsigned int len,
const SharedPtr<Path> &via) noexcept
{
via->send(ctx, cc, data, len);
sent(cc, len);
@ -180,12 +180,12 @@ class Peer {
* @param data Data to send
* @param len Length in bytes
*/
void send(const Context& ctx, const CallContext& cc, const void* data, unsigned int len) noexcept;
void send(const Context &ctx, const CallContext &cc, const void *data, unsigned int len) noexcept;
/**
* Do ping, probes, re-keying, and keepalive with this peer, as needed.
*/
void pulse(const Context& ctx, const CallContext& cc);
void pulse(const Context &ctx, const CallContext &cc);
/**
* Attempt to contact this peer at a given endpoint.
@ -196,7 +196,7 @@ class Peer {
* @param ep Endpoint to attempt to contact
* @param tries Number of times to try (default: 1)
*/
void contact(const Context& ctx, const CallContext& cc, const Endpoint& ep, int tries = 1);
void contact(const Context &ctx, const CallContext &cc, const Endpoint &ep, int tries = 1);
/**
* Reset paths within a given IP scope and address family
@ -209,15 +209,12 @@ class Peer {
* @param scope IP scope
* @param inetAddressFamily Family e.g. AF_INET
*/
void resetWithinScope(const Context& ctx, const CallContext& cc, InetAddress::IpScope scope, int inetAddressFamily);
void resetWithinScope(const Context &ctx, const CallContext &cc, InetAddress::IpScope scope, int inetAddressFamily);
/**
* @return Time of last receive of anything, whether direct or relayed
*/
ZT_INLINE int64_t lastReceive() const noexcept
{
return m_lastReceive.load(std::memory_order_relaxed);
}
ZT_INLINE int64_t lastReceive() const noexcept { return m_lastReceive.load(std::memory_order_relaxed); }
/**
* @return Average latency of all direct paths or -1 if no direct paths or unknown
@ -250,41 +247,29 @@ class Peer {
/**
* @return The permanent shared key for this peer computed by simple identity agreement
*/
ZT_INLINE SymmetricKey& identityKey() noexcept
{
return m_identityKey;
}
ZT_INLINE SymmetricKey &identityKey() noexcept { return m_identityKey; }
/**
* @return AES instance for HELLO dictionary / encrypted section encryption/decryption
*/
ZT_INLINE const AES& identityHelloDictionaryEncryptionCipher() const noexcept
{
return m_helloCipher;
}
ZT_INLINE const AES &identityHelloDictionaryEncryptionCipher() const noexcept { return m_helloCipher; }
/**
* @return Key for HMAC on HELLOs
*/
ZT_INLINE const uint8_t* identityHelloHmacKey() const noexcept
{
return m_helloMacKey;
}
ZT_INLINE const uint8_t *identityHelloHmacKey() const noexcept { return m_helloMacKey; }
/**
* @return Raw identity key bytes
*/
ZT_INLINE const uint8_t* rawIdentityKey() const noexcept
{
return m_identityKey.key();
}
ZT_INLINE const uint8_t *rawIdentityKey() const noexcept { return m_identityKey.key(); }
/**
* @return Current best key: either the latest ephemeral or the identity key
*/
ZT_INLINE SymmetricKey& key() noexcept
ZT_INLINE SymmetricKey &key() noexcept
{
return *reinterpret_cast<SymmetricKey*>(m_key.load(std::memory_order_relaxed));
return *reinterpret_cast<SymmetricKey *>(m_key.load(std::memory_order_relaxed));
}
/**
@ -298,14 +283,15 @@ class Peer {
* @param notYetTried All keys known (long lived or session) other than alreadyTried
* @return Number of pointers written to notYetTried[]
*/
ZT_INLINE int getOtherKeys(const SymmetricKey* const alreadyTried, SymmetricKey* notYetTried[ZT_PEER_EPHEMERAL_KEY_COUNT_MAX]) noexcept
ZT_INLINE int getOtherKeys(
const SymmetricKey *const alreadyTried, SymmetricKey *notYetTried[ZT_PEER_EPHEMERAL_KEY_COUNT_MAX]) noexcept
{
RWMutex::RLock l(m_lock);
int cnt = 0;
if (alreadyTried != &m_identityKey)
notYetTried[cnt++] = &m_identityKey;
for (unsigned int k = 0; k < ZT_PEER_EPHEMERAL_KEY_BUFFER_SIZE; ++k) {
SymmetricKey* const kk = &m_ephemeralSessions[k].key;
SymmetricKey *const kk = &m_ephemeralSessions[k].key;
if (m_ephemeralSessions[k].established && (alreadyTried != kk))
notYetTried[cnt++] = kk;
}
@ -334,12 +320,13 @@ class Peer {
* @param vmin Minor version
* @param vrev Revision
*/
ZT_INLINE void setRemoteVersion(unsigned int vproto, unsigned int vmaj, unsigned int vmin, unsigned int vrev) noexcept
ZT_INLINE void
setRemoteVersion(unsigned int vproto, unsigned int vmaj, unsigned int vmin, unsigned int vrev) noexcept
{
RWMutex::Lock l(m_lock);
m_vProto = (uint16_t)vproto;
m_vMajor = (uint16_t)vmaj;
m_vMinor = (uint16_t)vmin;
m_vProto = (uint16_t)vproto;
m_vMajor = (uint16_t)vmaj;
m_vMinor = (uint16_t)vmin;
m_vRevision = (uint16_t)vrev;
}
@ -355,7 +342,7 @@ class Peer {
* @param vRevision Set to revision
* @return True if remote version is known
*/
ZT_INLINE bool remoteVersion(uint16_t& vProto, uint16_t& vMajor, uint16_t& vMinor, uint16_t& vRevision)
ZT_INLINE bool remoteVersion(uint16_t &vProto, uint16_t &vMajor, uint16_t &vMinor, uint16_t &vRevision)
{
RWMutex::RLock l(m_lock);
return (((vProto = m_vProto) | (vMajor = m_vMajor) | (vMinor = m_vMinor) | (vRevision = m_vRevision)) != 0);
@ -375,7 +362,7 @@ class Peer {
*
* @param paths Vector of paths with the first path being the current preferred path
*/
ZT_INLINE void getAllPaths(Vector<SharedPtr<Path> >& paths) const
ZT_INLINE void getAllPaths(Vector<SharedPtr<Path>> &paths) const
{
RWMutex::RLock l(m_lock);
paths.assign(m_paths, m_paths + m_alivePathCount);
@ -384,20 +371,17 @@ class Peer {
/**
* Save the latest version of this peer to the data store
*/
void save(const Context& ctx, const CallContext& cc) const;
void save(const Context &ctx, const CallContext &cc) const;
static constexpr int marshalSizeMax() noexcept
{
return ZT_PEER_MARSHAL_SIZE_MAX;
}
static constexpr int marshalSizeMax() noexcept { return ZT_PEER_MARSHAL_SIZE_MAX; }
int marshal(const Context& ctx, uint8_t data[ZT_PEER_MARSHAL_SIZE_MAX]) const noexcept;
int unmarshal(const Context& ctx, int64_t ticks, const uint8_t* restrict data, int len) noexcept;
int marshal(const Context &ctx, uint8_t data[ZT_PEER_MARSHAL_SIZE_MAX]) const noexcept;
int unmarshal(const Context &ctx, int64_t ticks, const uint8_t *restrict data, int len) noexcept;
/**
* Rate limit gate for inbound WHOIS requests
*/
ZT_INLINE bool rateGateInboundWhoisRequest(CallContext& cc) noexcept
ZT_INLINE bool rateGateInboundWhoisRequest(CallContext &cc) noexcept
{
if ((cc.ticks - m_lastWhoisRequestReceived.load(std::memory_order_relaxed)) >= ZT_PEER_WHOIS_RATE_LIMIT) {
m_lastWhoisRequestReceived.store(cc.ticks, std::memory_order_relaxed);
@ -409,7 +393,7 @@ class Peer {
/**
* Rate limit gate for inbound ECHO requests
*/
ZT_INLINE bool rateGateEchoRequest(CallContext& cc) noexcept
ZT_INLINE bool rateGateEchoRequest(CallContext &cc) noexcept
{
if ((cc.ticks - m_lastEchoRequestReceived.load(std::memory_order_relaxed)) >= ZT_PEER_GENERAL_RATE_LIMIT) {
m_lastEchoRequestReceived.store(cc.ticks, std::memory_order_relaxed);
@ -421,7 +405,7 @@ class Peer {
/**
* Rate limit gate for inbound probes
*/
ZT_INLINE bool rateGateProbeRequest(CallContext& cc) noexcept
ZT_INLINE bool rateGateProbeRequest(CallContext &cc) noexcept
{
if ((cc.ticks - m_lastProbeReceived.load(std::memory_order_relaxed)) > ZT_PEER_PROBE_RESPONSE_RATE_LIMIT) {
m_lastProbeReceived.store(cc.ticks, std::memory_order_relaxed);
@ -441,7 +425,9 @@ class Peer {
*/
ZT_INLINE bool deduplicateIncomingPacket(const uint64_t packetId) noexcept
{
return m_dedup[Utils::hash32((uint32_t)packetId) & ZT_PEER_DEDUP_BUFFER_MASK].exchange(packetId, std::memory_order_relaxed) == packetId;
return m_dedup[Utils::hash32((uint32_t)packetId) & ZT_PEER_DEDUP_BUFFER_MASK].exchange(
packetId, std::memory_order_relaxed)
== packetId;
}
private:
@ -451,17 +437,14 @@ class Peer {
uint8_t p384Public[ZT_ECC384_PUBLIC_KEY_SIZE];
};
static_assert(sizeof(p_EphemeralPublic) == (1 + ZT_C25519_ECDH_PUBLIC_KEY_SIZE + ZT_ECC384_PUBLIC_KEY_SIZE), "p_EphemeralPublic has extra padding");
static_assert(
sizeof(p_EphemeralPublic) == (1 + ZT_C25519_ECDH_PUBLIC_KEY_SIZE + ZT_ECC384_PUBLIC_KEY_SIZE),
"p_EphemeralPublic has extra padding");
struct p_EphemeralPrivate {
ZT_INLINE p_EphemeralPrivate() noexcept : creationTime(-1)
{
}
ZT_INLINE p_EphemeralPrivate() noexcept : creationTime(-1) {}
ZT_INLINE ~p_EphemeralPrivate()
{
Utils::burn(this, sizeof(p_EphemeralPublic));
}
ZT_INLINE ~p_EphemeralPrivate() { Utils::burn(this, sizeof(p_EphemeralPublic)); }
int64_t creationTime;
uint64_t sha384OfPublic[6];
@ -471,19 +454,20 @@ class Peer {
};
struct p_EphemeralSession {
ZT_INLINE p_EphemeralSession() noexcept : established(false)
{
}
ZT_INLINE p_EphemeralSession() noexcept : established(false) {}
uint64_t sha384OfPeerPublic[6];
SymmetricKey key;
bool established;
};
void m_prioritizePaths(const CallContext& cc);
unsigned int m_sendProbe(const Context& ctx, const CallContext& cc, int64_t localSocket, const InetAddress& atAddress, const uint16_t* ports, unsigned int numPorts);
void m_prioritizePaths(const CallContext &cc);
unsigned int m_sendProbe(
const Context &ctx, const CallContext &cc, int64_t localSocket, const InetAddress &atAddress,
const uint16_t *ports, unsigned int numPorts);
void m_deriveSecondaryIdentityKeys() noexcept;
unsigned int m_hello(const Context& ctx, const CallContext& cc, int64_t localSocket, const InetAddress& atAddress, bool forceNewKey);
unsigned int m_hello(
const Context &ctx, const CallContext &cc, int64_t localSocket, const InetAddress &atAddress, bool forceNewKey);
// Guards all fields except those otherwise indicated (and atomics of course).
RWMutex m_lock;
@ -552,13 +536,9 @@ class Peer {
std::atomic<int> __refCount;
struct p_TryQueueItem {
ZT_INLINE p_TryQueueItem() : target(), iteration(0)
{
}
ZT_INLINE p_TryQueueItem() : target(), iteration(0) {}
ZT_INLINE p_TryQueueItem(const Endpoint& t, int iter) : target(t), iteration(iter)
{
}
ZT_INLINE p_TryQueueItem(const Endpoint &t, int iter) : target(t), iteration(iter) {}
Endpoint target;
int iteration;

View file

@ -48,9 +48,9 @@ typedef struct poly1305_state_internal_t {
unsigned char final;
} poly1305_state_internal_t;
ZT_INLINE void poly1305_init(poly1305_context* ctx, const unsigned char key[32])
ZT_INLINE void poly1305_init(poly1305_context *ctx, const unsigned char key[32])
{
poly1305_state_internal_t* st = (poly1305_state_internal_t*)ctx;
poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
unsigned long long t0, t1;
/* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
@ -71,10 +71,10 @@ ZT_INLINE void poly1305_init(poly1305_context* ctx, const unsigned char key[32])
st->pad[1] = U8TO64(&key[24]);
st->leftover = 0;
st->final = 0;
st->final = 0;
}
void poly1305_blocks(poly1305_state_internal_t* st, const unsigned char* m, size_t bytes)
void poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes)
{
const unsigned long long hibit = (st->final) ? 0 : ((unsigned long long)1 << 40); /* 1 << 128 */
unsigned long long r0, r1, r2;
@ -123,15 +123,15 @@ void poly1305_blocks(poly1305_state_internal_t* st, const unsigned char* m, size
/* (partial) h %= p */
unsigned long long c = SHR(d0, 44);
h0 = LO(d0) & 0xfffffffffff;
h0 = LO(d0) & 0xfffffffffff;
ADDLO(d1, c);
c = SHR(d1, 44);
c = SHR(d1, 44);
h1 = LO(d1) & 0xfffffffffff;
ADDLO(d2, c);
c = SHR(d2, 42);
c = SHR(d2, 42);
h2 = LO(d2) & 0x3ffffffffff;
h0 += c * 5;
c = (h0 >> 44);
c = (h0 >> 44);
h0 = h0 & 0xfffffffffff;
h1 += c;
@ -144,16 +144,16 @@ void poly1305_blocks(poly1305_state_internal_t* st, const unsigned char* m, size
st->h[2] = h2;
}
ZT_INLINE void poly1305_finish(poly1305_context* ctx, unsigned char mac[16])
ZT_INLINE void poly1305_finish(poly1305_context *ctx, unsigned char mac[16])
{
poly1305_state_internal_t* st = (poly1305_state_internal_t*)ctx;
poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
unsigned long long h0, h1, h2, c;
unsigned long long g0, g1, g2;
unsigned long long t0, t1;
/* process the remaining block */
if (st->leftover) {
size_t i = st->leftover;
size_t i = st->leftover;
st->buffer[i] = 1;
for (i = i + 1; i < poly1305_block_size; i++)
st->buffer[i] = 0;
@ -187,10 +187,10 @@ ZT_INLINE void poly1305_finish(poly1305_context* ctx, unsigned char mac[16])
/* compute h + -p */
g0 = h0 + 5;
c = (g0 >> 44);
c = (g0 >> 44);
g0 &= 0xfffffffffff;
g1 = h1 + c;
c = (g1 >> 44);
c = (g1 >> 44);
g1 &= 0xfffffffffff;
g2 = h2 + c - ((unsigned long long)1 << 42);
@ -199,7 +199,7 @@ ZT_INLINE void poly1305_finish(poly1305_context* ctx, unsigned char mac[16])
g0 &= c;
g1 &= c;
g2 &= c;
c = ~c;
c = ~c;
h0 = (h0 & c) | g0;
h1 = (h1 & c) | g1;
h2 = (h2 & c) | g2;
@ -225,12 +225,12 @@ ZT_INLINE void poly1305_finish(poly1305_context* ctx, unsigned char mac[16])
U64TO8(&mac[8], h1);
/* zero out the state */
st->h[0] = 0;
st->h[1] = 0;
st->h[2] = 0;
st->r[0] = 0;
st->r[1] = 0;
st->r[2] = 0;
st->h[0] = 0;
st->h[1] = 0;
st->h[2] = 0;
st->r[0] = 0;
st->r[1] = 0;
st->r[2] = 0;
st->pad[0] = 0;
st->pad[1] = 0;
}
@ -248,9 +248,9 @@ typedef struct poly1305_state_internal_t {
unsigned char final;
} poly1305_state_internal_t;
ZT_INLINE void poly1305_init(poly1305_context* ctx, const unsigned char key[32])
ZT_INLINE void poly1305_init(poly1305_context *ctx, const unsigned char key[32])
{
poly1305_state_internal_t* st = (poly1305_state_internal_t*)ctx;
poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
/* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
st->r[0] = (U8TO32(&key[0])) & 0x3ffffff;
@ -273,10 +273,10 @@ ZT_INLINE void poly1305_init(poly1305_context* ctx, const unsigned char key[32])
st->pad[3] = U8TO32(&key[28]);
st->leftover = 0;
st->final = 0;
st->final = 0;
}
void poly1305_blocks(poly1305_state_internal_t* st, const unsigned char* m, size_t bytes)
void poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes)
{
const unsigned long hibit = (st->final) ? 0 : (1 << 24); /* 1 << 128 */
unsigned long r0, r1, r2, r3, r4;
@ -309,29 +309,39 @@ void poly1305_blocks(poly1305_state_internal_t* st, const unsigned char* m, size
h4 += (U8TO32(m + 12) >> 8) | hibit;
/* h *= r */
unsigned long long d0 = ((unsigned long long)h0 * r0) + ((unsigned long long)h1 * s4) + ((unsigned long long)h2 * s3) + ((unsigned long long)h3 * s2) + ((unsigned long long)h4 * s1);
unsigned long long d1 = ((unsigned long long)h0 * r1) + ((unsigned long long)h1 * r0) + ((unsigned long long)h2 * s4) + ((unsigned long long)h3 * s3) + ((unsigned long long)h4 * s2);
unsigned long long d2 = ((unsigned long long)h0 * r2) + ((unsigned long long)h1 * r1) + ((unsigned long long)h2 * r0) + ((unsigned long long)h3 * s4) + ((unsigned long long)h4 * s3);
unsigned long long d3 = ((unsigned long long)h0 * r3) + ((unsigned long long)h1 * r2) + ((unsigned long long)h2 * r1) + ((unsigned long long)h3 * r0) + ((unsigned long long)h4 * s4);
unsigned long long d4 = ((unsigned long long)h0 * r4) + ((unsigned long long)h1 * r3) + ((unsigned long long)h2 * r2) + ((unsigned long long)h3 * r1) + ((unsigned long long)h4 * r0);
unsigned long long d0 = ((unsigned long long)h0 * r0) + ((unsigned long long)h1 * s4)
+ ((unsigned long long)h2 * s3) + ((unsigned long long)h3 * s2)
+ ((unsigned long long)h4 * s1);
unsigned long long d1 = ((unsigned long long)h0 * r1) + ((unsigned long long)h1 * r0)
+ ((unsigned long long)h2 * s4) + ((unsigned long long)h3 * s3)
+ ((unsigned long long)h4 * s2);
unsigned long long d2 = ((unsigned long long)h0 * r2) + ((unsigned long long)h1 * r1)
+ ((unsigned long long)h2 * r0) + ((unsigned long long)h3 * s4)
+ ((unsigned long long)h4 * s3);
unsigned long long d3 = ((unsigned long long)h0 * r3) + ((unsigned long long)h1 * r2)
+ ((unsigned long long)h2 * r1) + ((unsigned long long)h3 * r0)
+ ((unsigned long long)h4 * s4);
unsigned long long d4 = ((unsigned long long)h0 * r4) + ((unsigned long long)h1 * r3)
+ ((unsigned long long)h2 * r2) + ((unsigned long long)h3 * r1)
+ ((unsigned long long)h4 * r0);
/* (partial) h %= p */
unsigned long c = (unsigned long)(d0 >> 26);
h0 = (unsigned long)d0 & 0x3ffffff;
h0 = (unsigned long)d0 & 0x3ffffff;
d1 += c;
c = (unsigned long)(d1 >> 26);
c = (unsigned long)(d1 >> 26);
h1 = (unsigned long)d1 & 0x3ffffff;
d2 += c;
c = (unsigned long)(d2 >> 26);
c = (unsigned long)(d2 >> 26);
h2 = (unsigned long)d2 & 0x3ffffff;
d3 += c;
c = (unsigned long)(d3 >> 26);
c = (unsigned long)(d3 >> 26);
h3 = (unsigned long)d3 & 0x3ffffff;
d4 += c;
c = (unsigned long)(d4 >> 26);
c = (unsigned long)(d4 >> 26);
h4 = (unsigned long)d4 & 0x3ffffff;
h0 += c * 5;
c = (h0 >> 26);
c = (h0 >> 26);
h0 = h0 & 0x3ffffff;
h1 += c;
@ -346,9 +356,9 @@ void poly1305_blocks(poly1305_state_internal_t* st, const unsigned char* m, size
st->h[4] = h4;
}
ZT_INLINE void poly1305_finish(poly1305_context* ctx, unsigned char mac[16])
ZT_INLINE void poly1305_finish(poly1305_context *ctx, unsigned char mac[16])
{
poly1305_state_internal_t* st = (poly1305_state_internal_t*)ctx;
poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
unsigned long h0, h1, h2, h3, h4, c;
unsigned long g0, g1, g2, g3, g4;
unsigned long long f;
@ -356,7 +366,7 @@ ZT_INLINE void poly1305_finish(poly1305_context* ctx, unsigned char mac[16])
/* process the remaining block */
if (st->leftover) {
size_t i = st->leftover;
size_t i = st->leftover;
st->buffer[i++] = 1;
for (; i < poly1305_block_size; i++)
st->buffer[i] = 0;
@ -371,34 +381,34 @@ ZT_INLINE void poly1305_finish(poly1305_context* ctx, unsigned char mac[16])
h3 = st->h[3];
h4 = st->h[4];
c = h1 >> 26;
c = h1 >> 26;
h1 = h1 & 0x3ffffff;
h2 += c;
c = h2 >> 26;
c = h2 >> 26;
h2 = h2 & 0x3ffffff;
h3 += c;
c = h3 >> 26;
c = h3 >> 26;
h3 = h3 & 0x3ffffff;
h4 += c;
c = h4 >> 26;
c = h4 >> 26;
h4 = h4 & 0x3ffffff;
h0 += c * 5;
c = h0 >> 26;
c = h0 >> 26;
h0 = h0 & 0x3ffffff;
h1 += c;
/* compute h + -p */
g0 = h0 + 5;
c = g0 >> 26;
c = g0 >> 26;
g0 &= 0x3ffffff;
g1 = h1 + c;
c = g1 >> 26;
c = g1 >> 26;
g1 &= 0x3ffffff;
g2 = h2 + c;
c = g2 >> 26;
c = g2 >> 26;
g2 &= 0x3ffffff;
g3 = h3 + c;
c = g3 >> 26;
c = g3 >> 26;
g3 &= 0x3ffffff;
g4 = h4 + c - (1 << 26);
@ -410,11 +420,11 @@ ZT_INLINE void poly1305_finish(poly1305_context* ctx, unsigned char mac[16])
g3 &= mask;
g4 &= mask;
mask = ~mask;
h0 = (h0 & mask) | g0;
h1 = (h1 & mask) | g1;
h2 = (h2 & mask) | g2;
h3 = (h3 & mask) | g3;
h4 = (h4 & mask) | g4;
h0 = (h0 & mask) | g0;
h1 = (h1 & mask) | g1;
h2 = (h2 & mask) | g2;
h3 = (h3 & mask) | g3;
h4 = (h4 & mask) | g4;
/* h = h % (2^128) */
h0 = ((h0) | (h1 << 26)) & 0xffffffff;
@ -423,13 +433,13 @@ ZT_INLINE void poly1305_finish(poly1305_context* ctx, unsigned char mac[16])
h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff;
/* mac = (h + pad) % (2^128) */
f = (unsigned long long)h0 + st->pad[0];
f = (unsigned long long)h0 + st->pad[0];
h0 = (unsigned long)f;
f = (unsigned long long)h1 + st->pad[1] + (f >> 32);
f = (unsigned long long)h1 + st->pad[1] + (f >> 32);
h1 = (unsigned long)f;
f = (unsigned long long)h2 + st->pad[2] + (f >> 32);
f = (unsigned long long)h2 + st->pad[2] + (f >> 32);
h2 = (unsigned long)f;
f = (unsigned long long)h3 + st->pad[3] + (f >> 32);
f = (unsigned long long)h3 + st->pad[3] + (f >> 32);
h3 = (unsigned long)f;
U32TO8(mac + 0, h0);
@ -438,16 +448,16 @@ ZT_INLINE void poly1305_finish(poly1305_context* ctx, unsigned char mac[16])
U32TO8(mac + 12, h3);
/* zero out the state */
st->h[0] = 0;
st->h[1] = 0;
st->h[2] = 0;
st->h[3] = 0;
st->h[4] = 0;
st->r[0] = 0;
st->r[1] = 0;
st->r[2] = 0;
st->r[3] = 0;
st->r[4] = 0;
st->h[0] = 0;
st->h[1] = 0;
st->h[2] = 0;
st->h[3] = 0;
st->h[4] = 0;
st->r[0] = 0;
st->r[1] = 0;
st->r[2] = 0;
st->r[3] = 0;
st->r[4] = 0;
st->pad[0] = 0;
st->pad[1] = 0;
st->pad[2] = 0;
@ -456,9 +466,9 @@ ZT_INLINE void poly1305_finish(poly1305_context* ctx, unsigned char mac[16])
#endif // uint128_t or portable version?
ZT_INLINE void poly1305_update(poly1305_context* ctx, const unsigned char* m, size_t bytes) noexcept
ZT_INLINE void poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes) noexcept
{
poly1305_state_internal_t* st = (poly1305_state_internal_t*)ctx;
poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
size_t i;
/* handle leftover */
@ -495,20 +505,21 @@ ZT_INLINE void poly1305_update(poly1305_context* ctx, const unsigned char* m, si
} // anonymous namespace
void Poly1305::init(const void* key) noexcept
void Poly1305::init(const void *key) noexcept
{
static_assert(sizeof(ctx) >= sizeof(poly1305_context), "buffer in class smaller than required structure size");
poly1305_init(reinterpret_cast<poly1305_context*>(&ctx), reinterpret_cast<const unsigned char*>(key));
poly1305_init(reinterpret_cast<poly1305_context *>(&ctx), reinterpret_cast<const unsigned char *>(key));
}
void Poly1305::update(const void* data, unsigned int len) noexcept
void Poly1305::update(const void *data, unsigned int len) noexcept
{
poly1305_update(reinterpret_cast<poly1305_context*>(&ctx), reinterpret_cast<const unsigned char*>(data), (size_t)len);
poly1305_update(
reinterpret_cast<poly1305_context *>(&ctx), reinterpret_cast<const unsigned char *>(data), (size_t)len);
}
void Poly1305::finish(void* auth) noexcept
void Poly1305::finish(void *auth) noexcept
{
poly1305_finish(reinterpret_cast<poly1305_context*>(&ctx), reinterpret_cast<unsigned char*>(auth));
poly1305_finish(reinterpret_cast<poly1305_context *>(&ctx), reinterpret_cast<unsigned char *>(auth));
}
} // namespace ZeroTier

View file

@ -26,20 +26,16 @@ namespace ZeroTier {
*/
class Poly1305 {
public:
ZT_INLINE Poly1305()
{
}
ZT_INLINE Poly1305() {}
ZT_INLINE Poly1305(const void* key)
{
this->init(key);
}
ZT_INLINE Poly1305(const void *key) { this->init(key); }
void init(const void* key) noexcept;
void update(const void* data, unsigned int len) noexcept;
void finish(void* auth) noexcept;
void init(const void *key) noexcept;
void update(const void *data, unsigned int len) 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
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);

View file

@ -253,7 +253,9 @@
#define ZT_PROTO_HELLO_NODE_META_EPHEMERAL_ACK "E"
static_assert(ZT_PROTO_MAX_PACKET_LENGTH < ZT_BUF_MEM_SIZE, "maximum packet length won't fit in Buf");
static_assert(ZT_PROTO_PACKET_ENCRYPTED_SECTION_START == (ZT_PROTO_MIN_PACKET_LENGTH - 1), "encrypted packet section must start right before protocol verb at one less than minimum packet size");
static_assert(
ZT_PROTO_PACKET_ENCRYPTED_SECTION_START == (ZT_PROTO_MIN_PACKET_LENGTH - 1),
"encrypted packet section must start right before protocol verb at one less than minimum packet size");
namespace ZeroTier {
namespace Protocol {
@ -684,49 +686,29 @@ enum Verb {
#ifdef ZT_DEBUG_SPEW
static ZT_INLINE const char* verbName(const Verb v) noexcept
static ZT_INLINE const char *verbName(const Verb v) noexcept
{
switch (v) {
case VERB_NOP:
return "NOP";
case VERB_HELLO:
return "HELLO";
case VERB_ERROR:
return "ERROR";
case VERB_OK:
return "OK";
case VERB_WHOIS:
return "WHOIS";
case VERB_RENDEZVOUS:
return "RENDEZVOUS";
case VERB_FRAME:
return "FRAME";
case VERB_EXT_FRAME:
return "EXT_FRAME";
case VERB_ECHO:
return "ECHO";
case VERB_MULTICAST_LIKE:
return "MULTICAST_LIKE";
case VERB_NETWORK_CREDENTIALS:
return "NETWORK_CREDENTIALS";
case VERB_NETWORK_CONFIG_REQUEST:
return "NETWORK_CONFIG_REQUEST";
case VERB_NETWORK_CONFIG:
return "NETWORK_CONFIG";
case VERB_MULTICAST_GATHER:
return "MULTICAST_GATHER";
case VERB_MULTICAST_FRAME_deprecated:
return "MULTICAST_FRAME_deprecated";
case VERB_PUSH_DIRECT_PATHS:
return "PUSH_DIRECT_PATHS";
case VERB_USER_MESSAGE:
return "USER_MESSAGE";
case VERB_MULTICAST:
return "MULTICAST";
case VERB_ENCAP:
return "ENCAP";
default:
return "(unknown)";
case VERB_NOP: return "NOP";
case VERB_HELLO: return "HELLO";
case VERB_ERROR: return "ERROR";
case VERB_OK: return "OK";
case VERB_WHOIS: return "WHOIS";
case VERB_RENDEZVOUS: return "RENDEZVOUS";
case VERB_FRAME: return "FRAME";
case VERB_EXT_FRAME: return "EXT_FRAME";
case VERB_ECHO: return "ECHO";
case VERB_MULTICAST_LIKE: return "MULTICAST_LIKE";
case VERB_NETWORK_CREDENTIALS: return "NETWORK_CREDENTIALS";
case VERB_NETWORK_CONFIG_REQUEST: return "NETWORK_CONFIG_REQUEST";
case VERB_NETWORK_CONFIG: return "NETWORK_CONFIG";
case VERB_MULTICAST_GATHER: return "MULTICAST_GATHER";
case VERB_MULTICAST_FRAME_deprecated: return "MULTICAST_FRAME_deprecated";
case VERB_PUSH_DIRECT_PATHS: return "PUSH_DIRECT_PATHS";
case VERB_USER_MESSAGE: return "USER_MESSAGE";
case VERB_MULTICAST: return "MULTICAST";
case VERB_ENCAP: return "ENCAP";
default: return "(unknown)";
}
}
@ -765,13 +747,13 @@ enum ErrorCode {
* by a special tee or redirect type flow rule.
*/
enum ExtFrameSubtype {
EXT_FRAME_SUBTYPE_NORMAL = 0x0,
EXT_FRAME_SUBTYPE_TEE_OUTBOUND = 0x1,
EXT_FRAME_SUBTYPE_NORMAL = 0x0,
EXT_FRAME_SUBTYPE_TEE_OUTBOUND = 0x1,
EXT_FRAME_SUBTYPE_REDIRECT_OUTBOUND = 0x2,
EXT_FRAME_SUBTYPE_WATCH_OUTBOUND = 0x3,
EXT_FRAME_SUBTYPE_TEE_INBOUND = 0x4,
EXT_FRAME_SUBTYPE_REDIRECT_INBOUND = 0x5,
EXT_FRAME_SUBTYPE_WATCH_INBOUND = 0x6
EXT_FRAME_SUBTYPE_WATCH_OUTBOUND = 0x3,
EXT_FRAME_SUBTYPE_TEE_INBOUND = 0x4,
EXT_FRAME_SUBTYPE_REDIRECT_INBOUND = 0x5,
EXT_FRAME_SUBTYPE_WATCH_INBOUND = 0x6
};
/**
@ -811,7 +793,8 @@ enum NetworkConfigFlag {
* @param in Input key (32 bytes)
* @param out Output buffer (32 bytes)
*/
static ZT_INLINE void salsa2012DeriveKey(const uint8_t* const in, uint8_t* const out, const Buf& packet, const unsigned int packetSize) noexcept
static ZT_INLINE void salsa2012DeriveKey(
const uint8_t *const in, uint8_t *const out, const Buf &packet, const unsigned int packetSize) noexcept
{
// IV and source/destination addresses. Using the addresses divides the
// key space into two halves-- A->B and B->A (since order will change).
@ -819,9 +802,12 @@ static ZT_INLINE void salsa2012DeriveKey(const uint8_t* const in, uint8_t* const
for (int i = 0; i < 18; ++i)
out[i] = in[i] ^ packet.unsafeData[i];
#else
*reinterpret_cast<uint64_t*>(out) = *reinterpret_cast<const uint64_t*>(in) ^ *reinterpret_cast<const uint64_t*>(packet.unsafeData);
*reinterpret_cast<uint64_t*>(out + 8) = *reinterpret_cast<const uint64_t*>(in + 8) ^ *reinterpret_cast<const uint64_t*>(packet.unsafeData + 8);
*reinterpret_cast<uint16_t*>(out + 16) = *reinterpret_cast<const uint16_t*>(in + 16) ^ *reinterpret_cast<const uint16_t*>(packet.unsafeData + 16);
*reinterpret_cast<uint64_t *>(out) =
*reinterpret_cast<const uint64_t *>(in) ^ *reinterpret_cast<const uint64_t *>(packet.unsafeData);
*reinterpret_cast<uint64_t *>(out + 8) =
*reinterpret_cast<const uint64_t *>(in + 8) ^ *reinterpret_cast<const uint64_t *>(packet.unsafeData + 8);
*reinterpret_cast<uint16_t *>(out + 16) =
*reinterpret_cast<const uint16_t *>(in + 16) ^ *reinterpret_cast<const uint16_t *>(packet.unsafeData + 16);
#endif
// Flags, but with hop count masked off. Hop count is altered by forwarding
@ -837,10 +823,10 @@ static ZT_INLINE void salsa2012DeriveKey(const uint8_t* const in, uint8_t* const
for (int i = 21; i < 32; ++i)
out[i] = in[i];
#else
out[21] = in[21];
out[22] = in[22];
out[23] = in[23];
*reinterpret_cast<uint64_t*>(out + 24) = *reinterpret_cast<const uint64_t*>(in + 24);
out[21] = in[21];
out[22] = in[22];
out[23] = in[23];
*reinterpret_cast<uint64_t *>(out + 24) = *reinterpret_cast<const uint64_t *>(in + 24);
#endif
}
@ -854,7 +840,8 @@ static ZT_INLINE void salsa2012DeriveKey(const uint8_t* const in, uint8_t* const
* @param verb Protocol verb
* @return Index of packet start
*/
static ZT_INLINE int newPacket(uint8_t pkt[28], const uint64_t packetId, const Address destination, const Address source, const Verb verb) noexcept
static ZT_INLINE int newPacket(
uint8_t pkt[28], const uint64_t packetId, const Address destination, const Address source, const Verb verb) noexcept
{
Utils::storeMachineEndian<uint64_t>(pkt + ZT_PROTO_PACKET_ID_INDEX, packetId);
destination.copyTo(pkt + ZT_PROTO_PACKET_DESTINATION_INDEX);
@ -865,7 +852,8 @@ static ZT_INLINE int newPacket(uint8_t pkt[28], const uint64_t packetId, const A
return ZT_PROTO_PACKET_VERB_INDEX + 1;
}
static ZT_INLINE int newPacket(Buf& pkt, const uint64_t packetId, const Address destination, const Address source, const Verb verb) noexcept
static ZT_INLINE int
newPacket(Buf &pkt, const uint64_t packetId, const Address destination, const Address source, const Verb verb) noexcept
{
return newPacket(pkt.unsafeData, packetId, destination, source, verb);
}
@ -879,7 +867,8 @@ static ZT_INLINE int newPacket(Buf& pkt, const uint64_t packetId, const Address
* @param cipherSuite Cipher suite to use for AEAD encryption or just MAC
* @return Packet ID of packet (which may change!)
*/
static ZT_INLINE uint64_t armor(uint8_t* const pkt, const int packetSize, const SymmetricKey& key, const uint8_t cipherSuite) noexcept
static ZT_INLINE uint64_t
armor(uint8_t *const pkt, const int packetSize, const SymmetricKey &key, const uint8_t cipherSuite) noexcept
{
// TODO
#if 0
@ -937,7 +926,7 @@ static ZT_INLINE uint64_t armor(uint8_t* const pkt, const int packetSize, const
* @param packetSize Total size of packet in bytes (including headers)
* @return New size of packet after compression or original size of compression wasn't helpful
*/
static ZT_INLINE int compress(Buf& pkt, int packetSize) noexcept
static ZT_INLINE int compress(Buf &pkt, int packetSize) noexcept
{
// TODO
return packetSize;

View file

@ -15,11 +15,11 @@
namespace ZeroTier {
bool RevocationCredential::sign(const Identity& signer) noexcept
bool RevocationCredential::sign(const Identity &signer) noexcept
{
uint8_t buf[ZT_REVOCATION_MARSHAL_SIZE_MAX + 32];
if (signer.hasPrivate()) {
m_signedBy = signer.address();
m_signedBy = signer.address();
m_signatureLength = signer.sign(buf, (unsigned int)marshal(buf, true), m_signature, sizeof(m_signature));
return true;
}
@ -46,7 +46,7 @@ int RevocationCredential::marshal(uint8_t data[ZT_REVOCATION_MARSHAL_SIZE_MAX],
m_signedBy.copyTo(data + p);
p += ZT_ADDRESS_LENGTH;
data[p++] = (uint8_t)m_type;
if (! forSign) {
if (!forSign) {
data[p++] = 1;
Utils::storeBigEndian<uint16_t>(data + p, (uint16_t)m_signatureLength);
Utils::copy(data + p, m_signature, m_signatureLength);
@ -61,23 +61,23 @@ int RevocationCredential::marshal(uint8_t data[ZT_REVOCATION_MARSHAL_SIZE_MAX],
return p;
}
int RevocationCredential::unmarshal(const uint8_t* restrict data, const int len) noexcept
int RevocationCredential::unmarshal(const uint8_t *restrict data, const int len) noexcept
{
if (len < 54)
return -1;
// 4 bytes reserved
m_id = Utils::loadBigEndian<uint32_t>(data + 4);
m_id = Utils::loadBigEndian<uint32_t>(data + 4);
m_networkId = Utils::loadBigEndian<uint64_t>(data + 8);
// 4 bytes reserved
m_credentialId = Utils::loadBigEndian<uint32_t>(data + 20);
m_threshold = (int64_t)Utils::loadBigEndian<uint64_t>(data + 24);
m_flags = Utils::loadBigEndian<uint64_t>(data + 32);
m_threshold = (int64_t)Utils::loadBigEndian<uint64_t>(data + 24);
m_flags = Utils::loadBigEndian<uint64_t>(data + 32);
m_target.setTo(data + 40);
m_signedBy.setTo(data + 45);
m_type = (ZT_CredentialType)data[50];
// 1 byte reserved
m_signatureLength = Utils::loadBigEndian<uint16_t>(data + 52);
int p = 54 + (int)m_signatureLength;
int p = 54 + (int)m_signatureLength;
if ((m_signatureLength > ZT_SIGNATURE_BUFFER_SIZE) || (p > len))
return -1;
Utils::copy(m_signature, data + 54, m_signatureLength);

View file

@ -39,15 +39,9 @@ class RevocationCredential : public Credential {
friend class Credential;
public:
static constexpr ZT_CredentialType credentialType() noexcept
{
return ZT_CREDENTIAL_TYPE_REVOCATION;
}
static constexpr ZT_CredentialType credentialType() noexcept { return ZT_CREDENTIAL_TYPE_REVOCATION; }
ZT_INLINE RevocationCredential() noexcept
{
memoryZero(this);
}
ZT_INLINE RevocationCredential() noexcept { memoryZero(this); }
/**
* @param i ID (arbitrary for revocations, currently random)
@ -59,15 +53,11 @@ class RevocationCredential : public Credential {
* @param ct Credential type being revoked
*/
ZT_INLINE RevocationCredential(
const uint32_t i,
const uint64_t nwid,
const uint32_t cid,
const uint64_t thr,
const uint64_t fl,
const Address& tgt,
const uint32_t i, const uint64_t nwid, const uint32_t cid, const uint64_t thr, const uint64_t fl,
const Address &tgt,
const ZT_CredentialType ct) noexcept
: // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
m_id(i)
m_id(i)
, m_credentialId(cid)
, m_networkId(nwid)
, m_threshold(thr)
@ -79,61 +69,31 @@ class RevocationCredential : public Credential {
{
}
ZT_INLINE uint32_t id() const noexcept
{
return m_id;
}
ZT_INLINE uint32_t id() const noexcept { return m_id; }
ZT_INLINE uint32_t credentialId() const noexcept
{
return m_credentialId;
}
ZT_INLINE uint32_t credentialId() const noexcept { return m_credentialId; }
ZT_INLINE uint64_t networkId() const noexcept
{
return m_networkId;
}
ZT_INLINE uint64_t networkId() const noexcept { return m_networkId; }
ZT_INLINE int64_t threshold() const noexcept
{
return m_threshold;
}
ZT_INLINE int64_t threshold() const noexcept { return m_threshold; }
ZT_INLINE const Address& target() const noexcept
{
return m_target;
}
ZT_INLINE const Address &target() const noexcept { return m_target; }
ZT_INLINE const Address& signer() const noexcept
{
return m_signedBy;
}
ZT_INLINE const Address &signer() const noexcept { return m_signedBy; }
ZT_INLINE ZT_CredentialType typeBeingRevoked() const noexcept
{
return m_type;
}
ZT_INLINE ZT_CredentialType typeBeingRevoked() const noexcept { return m_type; }
ZT_INLINE const uint8_t* signature() const noexcept
{
return m_signature;
}
ZT_INLINE const uint8_t *signature() const noexcept { return m_signature; }
ZT_INLINE unsigned int signatureLength() const noexcept
{
return m_signatureLength;
}
ZT_INLINE unsigned int signatureLength() const noexcept { return m_signatureLength; }
ZT_INLINE bool fastPropagate() const noexcept
{
return ((m_flags & ZT_REVOCATION_FLAG_FAST_PROPAGATE) != 0);
}
ZT_INLINE bool fastPropagate() const noexcept { return ((m_flags & ZT_REVOCATION_FLAG_FAST_PROPAGATE) != 0); }
/**
* @param signer Signing identity, must have private key
* @return True if signature was successful
*/
bool sign(const Identity& signer) noexcept;
bool sign(const Identity &signer) noexcept;
/**
* Verify this revocation's signature
@ -141,18 +101,15 @@ class RevocationCredential : public Credential {
* @param RR Runtime environment to provide for peer lookup, etc.
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
*/
ZT_INLINE Credential::VerifyResult verify(const Context& ctx, const CallContext& cc) const noexcept
ZT_INLINE Credential::VerifyResult verify(const Context &ctx, const CallContext &cc) const noexcept
{
return s_verify(ctx, cc, *this);
}
static constexpr int marshalSizeMax() noexcept
{
return ZT_REVOCATION_MARSHAL_SIZE_MAX;
}
static constexpr int marshalSizeMax() noexcept { return ZT_REVOCATION_MARSHAL_SIZE_MAX; }
int marshal(uint8_t data[ZT_REVOCATION_MARSHAL_SIZE_MAX], bool forSign = false) const noexcept;
int unmarshal(const uint8_t* restrict data, int len) noexcept;
int unmarshal(const uint8_t *restrict data, int len) noexcept;
private:
uint32_t m_id;

View file

@ -16,15 +16,24 @@ struct sha512_state {
uint8_t buf[128];
};
static const uint64_t K[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL };
static const uint64_t K[80] = {
0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL,
0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL,
0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL,
0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL,
0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL,
0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
};
#define STORE64H(x, y) Utils::storeBigEndian<uint64_t>(y, x)
#define LOAD64H(x, y) x = Utils::loadBigEndian<uint64_t>(y)
@ -39,7 +48,7 @@ static const uint64_t K[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0x
#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
static ZT_INLINE void sha512_compress(sha512_state* const md, uint8_t* const buf)
static ZT_INLINE void sha512_compress(sha512_state *const md, uint8_t *const buf)
{
uint64_t S[8], W[80], t0, t1;
int i;
@ -51,10 +60,10 @@ static ZT_INLINE void sha512_compress(sha512_state* const md, uint8_t* const buf
for (i = 16; i < 80; i++)
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
#define RND(a, b, c, d, e, f, g, h, i) \
t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
t1 = Sigma0(a) + Maj(a, b, c); \
d += t0; \
#define RND(a, b, c, d, e, f, g, h, i) \
t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
t1 = Sigma0(a) + Maj(a, b, c); \
d += t0; \
h = t0 + t1;
for (i = 0; i < 80; i += 8) {
@ -72,10 +81,10 @@ static ZT_INLINE void sha512_compress(sha512_state* const md, uint8_t* const buf
md->state[i] = md->state[i] + S[i];
}
static ZT_INLINE void sha384_init(sha512_state* const md)
static ZT_INLINE void sha384_init(sha512_state *const md)
{
md->curlen = 0;
md->length = 0;
md->curlen = 0;
md->length = 0;
md->state[0] = 0xcbbb9d5dc1059ed8ULL;
md->state[1] = 0x629a292a367cd507ULL;
md->state[2] = 0x9159015a3070dd17ULL;
@ -86,10 +95,10 @@ static ZT_INLINE void sha384_init(sha512_state* const md)
md->state[7] = 0x47b5481dbefa4fa4ULL;
}
static ZT_INLINE void sha512_init(sha512_state* const md)
static ZT_INLINE void sha512_init(sha512_state *const md)
{
md->curlen = 0;
md->length = 0;
md->curlen = 0;
md->length = 0;
md->state[0] = 0x6a09e667f3bcc908ULL;
md->state[1] = 0xbb67ae8584caa73bULL;
md->state[2] = 0x3c6ef372fe94f82bULL;
@ -100,11 +109,11 @@ static ZT_INLINE void sha512_init(sha512_state* const md)
md->state[7] = 0x5be0cd19137e2179ULL;
}
static void sha512_process(sha512_state* const md, const uint8_t* in, unsigned long inlen)
static void sha512_process(sha512_state *const md, const uint8_t *in, unsigned long inlen)
{
while (inlen > 0) {
if (md->curlen == 0 && inlen >= 128) {
sha512_compress(md, (uint8_t*)in);
sha512_compress(md, (uint8_t *)in);
md->length += 128 * 8;
in += 128;
inlen -= 128;
@ -124,7 +133,7 @@ static void sha512_process(sha512_state* const md, const uint8_t* in, unsigned l
}
}
static ZT_INLINE void sha512_done(sha512_state* const md, uint8_t* out)
static ZT_INLINE void sha512_done(sha512_state *const md, uint8_t *out)
{
int i;
@ -153,38 +162,38 @@ static ZT_INLINE void sha512_done(sha512_state* const md, uint8_t* out)
} // anonymous namespace
void SHA512(void* digest, const void* data, unsigned int len)
void SHA512(void *digest, const void *data, unsigned int len)
{
sha512_state state;
sha512_init(&state);
sha512_process(&state, (uint8_t*)data, (unsigned long)len);
sha512_done(&state, (uint8_t*)digest);
sha512_process(&state, (uint8_t *)data, (unsigned long)len);
sha512_done(&state, (uint8_t *)digest);
}
void SHA384(void* digest, const void* data, unsigned int len)
void SHA384(void *digest, const void *data, unsigned int len)
{
uint8_t tmp[64];
sha512_state state;
sha384_init(&state);
sha512_process(&state, (uint8_t*)data, (unsigned long)len);
sha512_process(&state, (uint8_t *)data, (unsigned long)len);
sha512_done(&state, tmp);
Utils::copy<48>(digest, tmp);
}
void SHA384(void* digest, const void* data0, unsigned int len0, const void* data1, unsigned int len1)
void SHA384(void *digest, const void *data0, unsigned int len0, const void *data1, unsigned int len1)
{
uint8_t tmp[64];
sha512_state state;
sha384_init(&state);
sha512_process(&state, (uint8_t*)data0, (unsigned long)len0);
sha512_process(&state, (uint8_t*)data1, (unsigned long)len1);
sha512_process(&state, (uint8_t *)data0, (unsigned long)len0);
sha512_process(&state, (uint8_t *)data1, (unsigned long)len1);
sha512_done(&state, tmp);
Utils::copy<48>(digest, tmp);
}
#endif // !ZT_HAVE_NATIVE_SHA512
void HMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE], const void* msg, const unsigned int msglen, uint8_t mac[48])
void HMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE], const void *msg, const unsigned int msglen, uint8_t mac[48])
{
uint64_t kInPadded[16]; // input padded key
uint64_t outer[22]; // output padded key | H(input padded key | msg)
@ -197,47 +206,49 @@ void HMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE], const void* msg, const
const uint64_t k5 = Utils::loadMachineEndian<uint64_t>(key + 40);
const uint64_t ipad = 0x3636363636363636ULL;
kInPadded[0] = k0 ^ ipad;
kInPadded[1] = k1 ^ ipad;
kInPadded[2] = k2 ^ ipad;
kInPadded[3] = k3 ^ ipad;
kInPadded[4] = k4 ^ ipad;
kInPadded[5] = k5 ^ ipad;
kInPadded[6] = ipad;
kInPadded[7] = ipad;
kInPadded[8] = ipad;
kInPadded[9] = ipad;
kInPadded[10] = ipad;
kInPadded[11] = ipad;
kInPadded[12] = ipad;
kInPadded[13] = ipad;
kInPadded[14] = ipad;
kInPadded[15] = ipad;
kInPadded[0] = k0 ^ ipad;
kInPadded[1] = k1 ^ ipad;
kInPadded[2] = k2 ^ ipad;
kInPadded[3] = k3 ^ ipad;
kInPadded[4] = k4 ^ ipad;
kInPadded[5] = k5 ^ ipad;
kInPadded[6] = ipad;
kInPadded[7] = ipad;
kInPadded[8] = ipad;
kInPadded[9] = ipad;
kInPadded[10] = ipad;
kInPadded[11] = ipad;
kInPadded[12] = ipad;
kInPadded[13] = ipad;
kInPadded[14] = ipad;
kInPadded[15] = ipad;
const uint64_t opad = 0x5c5c5c5c5c5c5c5cULL;
outer[0] = k0 ^ opad;
outer[1] = k1 ^ opad;
outer[2] = k2 ^ opad;
outer[3] = k3 ^ opad;
outer[4] = k4 ^ opad;
outer[5] = k5 ^ opad;
outer[6] = opad;
outer[7] = opad;
outer[8] = opad;
outer[9] = opad;
outer[10] = opad;
outer[11] = opad;
outer[12] = opad;
outer[13] = opad;
outer[14] = opad;
outer[15] = opad;
outer[0] = k0 ^ opad;
outer[1] = k1 ^ opad;
outer[2] = k2 ^ opad;
outer[3] = k3 ^ opad;
outer[4] = k4 ^ opad;
outer[5] = k5 ^ opad;
outer[6] = opad;
outer[7] = opad;
outer[8] = opad;
outer[9] = opad;
outer[10] = opad;
outer[11] = opad;
outer[12] = opad;
outer[13] = opad;
outer[14] = opad;
outer[15] = opad;
// H(output padded key | H(input padded key | msg))
SHA384(reinterpret_cast<uint8_t*>(outer) + 128, kInPadded, 128, msg, msglen);
SHA384(reinterpret_cast<uint8_t *>(outer) + 128, kInPadded, 128, msg, msglen);
SHA384(mac, outer, 176);
}
void KBKDFHMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE], const char label, const char context, const uint32_t iter, uint8_t out[ZT_SYMMETRIC_KEY_SIZE])
void KBKDFHMACSHA384(
const uint8_t key[ZT_SYMMETRIC_KEY_SIZE], const char label, const char context, const uint32_t iter,
uint8_t out[ZT_SYMMETRIC_KEY_SIZE])
{
uint8_t kbkdfMsg[13];
@ -251,7 +262,7 @@ void KBKDFHMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE], const char label,
kbkdfMsg[8] = (uint8_t)context;
// Output key length: 384 bits (as 32-bit big-endian value)
kbkdfMsg[9] = 0;
kbkdfMsg[9] = 0;
kbkdfMsg[10] = 0;
kbkdfMsg[11] = 0x01;
kbkdfMsg[12] = 0x80;

View file

@ -32,34 +32,34 @@ namespace ZeroTier {
// SHA384 and SHA512 are actually in the standard libraries on MacOS and iOS
#ifdef __APPLE__
#define ZT_HAVE_NATIVE_SHA512 1
static ZT_INLINE void SHA512(void* digest, const void* data, unsigned int len)
static ZT_INLINE void SHA512(void *digest, const void *data, unsigned int len)
{
CC_SHA512_CTX ctx;
CC_SHA512_Init(&ctx);
CC_SHA512_Update(&ctx, data, len);
CC_SHA512_Final(reinterpret_cast<unsigned char*>(digest), &ctx);
CC_SHA512_Final(reinterpret_cast<unsigned char *>(digest), &ctx);
}
static ZT_INLINE void SHA384(void* digest, const void* data, unsigned int len)
static ZT_INLINE void SHA384(void *digest, const void *data, unsigned int len)
{
CC_SHA512_CTX ctx;
CC_SHA384_Init(&ctx);
CC_SHA384_Update(&ctx, data, len);
CC_SHA384_Final(reinterpret_cast<unsigned char*>(digest), &ctx);
CC_SHA384_Final(reinterpret_cast<unsigned char *>(digest), &ctx);
}
static ZT_INLINE void SHA384(void* digest, const void* data0, unsigned int len0, const void* data1, unsigned int len1)
static ZT_INLINE void SHA384(void *digest, const void *data0, unsigned int len0, const void *data1, unsigned int len1)
{
CC_SHA512_CTX ctx;
CC_SHA384_Init(&ctx);
CC_SHA384_Update(&ctx, data0, len0);
CC_SHA384_Update(&ctx, data1, len1);
CC_SHA384_Final(reinterpret_cast<unsigned char*>(digest), &ctx);
CC_SHA384_Final(reinterpret_cast<unsigned char *>(digest), &ctx);
}
#endif
#ifndef ZT_HAVE_NATIVE_SHA512
void SHA512(void* digest, const void* data, unsigned int len);
void SHA384(void* digest, const void* data, unsigned int len);
void SHA384(void* digest, const void* data0, unsigned int len0, const void* data1, unsigned int len1);
void SHA512(void *digest, const void *data, unsigned int len);
void SHA384(void *digest, const void *data, unsigned int len);
void SHA384(void *digest, const void *data0, unsigned int len0, const void *data1, unsigned int len1);
#endif
/**
@ -70,7 +70,7 @@ void SHA384(void* digest, const void* data0, unsigned int len0, const void* data
* @param msglen Length of message
* @param mac Buffer to fill with result
*/
void HMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE], const void* msg, unsigned int msglen, uint8_t mac[48]);
void HMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE], const void *msg, unsigned int msglen, uint8_t mac[48]);
/**
* Compute KBKDF (key-based key derivation function) using HMAC-SHA-384 as a PRF
@ -81,7 +81,9 @@ void HMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE], const void* msg, unsig
* @param iter Key iteration for generation of multiple keys for the same label/context
* @param out Output to receive derived key
*/
void KBKDFHMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE], char label, char context, uint32_t iter, uint8_t out[ZT_SYMMETRIC_KEY_SIZE]);
void KBKDFHMACSHA384(
const uint8_t key[ZT_SYMMETRIC_KEY_SIZE], char label, char context, uint32_t iter,
uint8_t out[ZT_SYMMETRIC_KEY_SIZE]);
} // namespace ZeroTier

View file

@ -19,8 +19,9 @@
#if __BYTE_ORDER == __LITTLE_ENDIAN
#ifdef ZT_NO_UNALIGNED_ACCESS
// Slower version that does not use type punning
#define U8TO32_LITTLE(p) (((uint32_t)(p)[0]) | ((uint32_t)(p)[1] << 8) | ((uint32_t)(p)[2] << 16) | ((uint32_t)(p)[3] << 24))
static ZT_INLINE void U32TO8_LITTLE(uint8_t* const c, const uint32_t v)
#define U8TO32_LITTLE(p) \
(((uint32_t)(p)[0]) | ((uint32_t)(p)[1] << 8) | ((uint32_t)(p)[2] << 16) | ((uint32_t)(p)[3] << 24))
static ZT_INLINE void U32TO8_LITTLE(uint8_t *const c, const uint32_t v)
{
c[0] = (uint8_t)v;
c[1] = (uint8_t)(v >> 8);
@ -29,18 +30,19 @@ static ZT_INLINE void U32TO8_LITTLE(uint8_t* const c, const uint32_t v)
}
#else
// Fast version that just does 32-bit load/store
#define U8TO32_LITTLE(p) (*((const uint32_t*)((const void*)(p))))
#define U32TO8_LITTLE(c, v) *((uint32_t*)((void*)(c))) = (v)
#define U8TO32_LITTLE(p) (*((const uint32_t *)((const void *)(p))))
#define U32TO8_LITTLE(c, v) *((uint32_t *)((void *)(c))) = (v)
#endif // ZT_NO_UNALIGNED_ACCESS
#else // __BYTE_ORDER == __BIG_ENDIAN (we don't support anything else... does MIDDLE_ENDIAN even still exist?)
#ifdef __GNUC__
// Use GNUC builtin bswap macros on big-endian machines if available
#define U8TO32_LITTLE(p) __builtin_bswap32(*((const uint32_t*)((const void*)(p))))
#define U32TO8_LITTLE(c, v) *((uint32_t*)((void*)(c))) = __builtin_bswap32((v))
#define U8TO32_LITTLE(p) __builtin_bswap32(*((const uint32_t *)((const void *)(p))))
#define U32TO8_LITTLE(c, v) *((uint32_t *)((void *)(c))) = __builtin_bswap32((v))
#else // no __GNUC__
// Otherwise do it the slow, manual way on BE machines
#define U8TO32_LITTLE(p) (((uint32_t)(p)[0]) | ((uint32_t)(p)[1] << 8) | ((uint32_t)(p)[2] << 16) | ((uint32_t)(p)[3] << 24))
static ZT_INLINE void U32TO8_LITTLE(uint8_t* const c, const uint32_t v)
#define U8TO32_LITTLE(p) \
(((uint32_t)(p)[0]) | ((uint32_t)(p)[1] << 8) | ((uint32_t)(p)[2] << 16) | ((uint32_t)(p)[3] << 24))
static ZT_INLINE void U32TO8_LITTLE(uint8_t *const c, const uint32_t v)
{
c[0] = (uint8_t)v;
c[1] = (uint8_t)(v >> 8);
@ -66,45 +68,45 @@ static const _s20sseconsts s_S20SSECONSTANTS;
namespace ZeroTier {
void Salsa20::init(const void* key, const void* iv) noexcept
void Salsa20::init(const void *key, const void *iv) noexcept
{
#ifdef ZT_SALSA20_SSE
const uint32_t* const k = (const uint32_t*)key;
_state.i[0] = 0x61707865;
_state.i[1] = 0x3320646e;
_state.i[2] = 0x79622d32;
_state.i[3] = 0x6b206574;
_state.i[4] = k[3];
_state.i[5] = 0;
_state.i[6] = k[7];
_state.i[7] = k[2];
_state.i[8] = 0;
_state.i[9] = k[6];
_state.i[10] = k[1];
_state.i[11] = ((const uint32_t*)iv)[1];
_state.i[12] = k[5];
_state.i[13] = k[0];
_state.i[14] = ((const uint32_t*)iv)[0];
_state.i[15] = k[4];
const uint32_t *const k = (const uint32_t *)key;
_state.i[0] = 0x61707865;
_state.i[1] = 0x3320646e;
_state.i[2] = 0x79622d32;
_state.i[3] = 0x6b206574;
_state.i[4] = k[3];
_state.i[5] = 0;
_state.i[6] = k[7];
_state.i[7] = k[2];
_state.i[8] = 0;
_state.i[9] = k[6];
_state.i[10] = k[1];
_state.i[11] = ((const uint32_t *)iv)[1];
_state.i[12] = k[5];
_state.i[13] = k[0];
_state.i[14] = ((const uint32_t *)iv)[0];
_state.i[15] = k[4];
#else
const char* const constants = "expand 32-byte k";
const uint8_t* const k = (const uint8_t*)key;
_state.i[0] = U8TO32_LITTLE(constants + 0);
_state.i[1] = U8TO32_LITTLE(k + 0);
_state.i[2] = U8TO32_LITTLE(k + 4);
_state.i[3] = U8TO32_LITTLE(k + 8);
_state.i[4] = U8TO32_LITTLE(k + 12);
_state.i[5] = U8TO32_LITTLE(constants + 4);
_state.i[6] = U8TO32_LITTLE(((const uint8_t*)iv) + 0);
_state.i[7] = U8TO32_LITTLE(((const uint8_t*)iv) + 4);
_state.i[8] = 0;
_state.i[9] = 0;
_state.i[10] = U8TO32_LITTLE(constants + 8);
_state.i[11] = U8TO32_LITTLE(k + 16);
_state.i[12] = U8TO32_LITTLE(k + 20);
_state.i[13] = U8TO32_LITTLE(k + 24);
_state.i[14] = U8TO32_LITTLE(k + 28);
_state.i[15] = U8TO32_LITTLE(constants + 12);
const char *const constants = "expand 32-byte k";
const uint8_t *const k = (const uint8_t *)key;
_state.i[0] = U8TO32_LITTLE(constants + 0);
_state.i[1] = U8TO32_LITTLE(k + 0);
_state.i[2] = U8TO32_LITTLE(k + 4);
_state.i[3] = U8TO32_LITTLE(k + 8);
_state.i[4] = U8TO32_LITTLE(k + 12);
_state.i[5] = U8TO32_LITTLE(constants + 4);
_state.i[6] = U8TO32_LITTLE(((const uint8_t *)iv) + 0);
_state.i[7] = U8TO32_LITTLE(((const uint8_t *)iv) + 4);
_state.i[8] = 0;
_state.i[9] = 0;
_state.i[10] = U8TO32_LITTLE(constants + 8);
_state.i[11] = U8TO32_LITTLE(k + 16);
_state.i[12] = U8TO32_LITTLE(k + 20);
_state.i[13] = U8TO32_LITTLE(k + 24);
_state.i[14] = U8TO32_LITTLE(k + 28);
_state.i[15] = U8TO32_LITTLE(constants + 12);
#endif
}
@ -115,35 +117,36 @@ union p_SalsaState {
uint32_t i[16];
};
template <unsigned int R> static ZT_INLINE void p_salsaCrypt(p_SalsaState* const state, const uint8_t* m, uint8_t* c, unsigned int bytes) noexcept
template <unsigned int R>
static ZT_INLINE void p_salsaCrypt(p_SalsaState *const state, const uint8_t *m, uint8_t *c, unsigned int bytes) noexcept
{
if (unlikely(bytes == 0))
return;
uint8_t tmp[64];
uint8_t* ctarget = c;
uint8_t *ctarget = c;
#ifdef ZT_SALSA20_SSE
__m128i X0 = state->v[0];
__m128i X1 = state->v[1];
__m128i X2 = state->v[2];
__m128i X3 = state->v[3];
__m128i X0 = state->v[0];
__m128i X1 = state->v[1];
__m128i X2 = state->v[2];
__m128i X3 = state->v[3];
const __m128i maskLo32 = s_S20SSECONSTANTS.maskLo32;
const __m128i maskHi32 = s_S20SSECONSTANTS.maskHi32;
const __m128i add1 = _mm_set_epi32(0, 0, 0, 1);
const __m128i add1 = _mm_set_epi32(0, 0, 0, 1);
#else
uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
j0 = state->i[0];
j1 = state->i[1];
j2 = state->i[2];
j3 = state->i[3];
j4 = state->i[4];
j5 = state->i[5];
j6 = state->i[6];
j7 = state->i[7];
j8 = state->i[8];
j9 = state->i[9];
j0 = state->i[0];
j1 = state->i[1];
j2 = state->i[2];
j3 = state->i[3];
j4 = state->i[4];
j5 = state->i[5];
j6 = state->i[6];
j7 = state->i[7];
j8 = state->i[8];
j9 = state->i[9];
j10 = state->i[10];
j11 = state->i[11];
j12 = state->i[12];
@ -156,9 +159,9 @@ template <unsigned int R> static ZT_INLINE void p_salsaCrypt(p_SalsaState* const
if (unlikely(bytes < 64)) {
for (unsigned int i = 0; i < bytes; ++i)
tmp[i] = m[i];
m = tmp;
m = tmp;
ctarget = c;
c = tmp;
c = tmp;
}
#ifdef ZT_SALSA20_SSE
@ -169,24 +172,24 @@ template <unsigned int R> static ZT_INLINE void p_salsaCrypt(p_SalsaState* const
__m128i T;
for (unsigned int rr = 0; rr < (R / 2); ++rr) {
T = _mm_add_epi32(X0, X3);
T = _mm_add_epi32(X0, X3);
X1 = _mm_xor_si128(_mm_xor_si128(X1, _mm_slli_epi32(T, 7)), _mm_srli_epi32(T, 25));
T = _mm_add_epi32(X1, X0);
T = _mm_add_epi32(X1, X0);
X2 = _mm_xor_si128(_mm_xor_si128(X2, _mm_slli_epi32(T, 9)), _mm_srli_epi32(T, 23));
T = _mm_add_epi32(X2, X1);
T = _mm_add_epi32(X2, X1);
X3 = _mm_xor_si128(_mm_xor_si128(X3, _mm_slli_epi32(T, 13)), _mm_srli_epi32(T, 19));
T = _mm_add_epi32(X3, X2);
T = _mm_add_epi32(X3, X2);
X0 = _mm_xor_si128(_mm_xor_si128(X0, _mm_slli_epi32(T, 18)), _mm_srli_epi32(T, 14));
X1 = _mm_shuffle_epi32(X1, 0x93);
X2 = _mm_shuffle_epi32(X2, 0x4E);
X3 = _mm_shuffle_epi32(X3, 0x39);
T = _mm_add_epi32(X0, X1);
T = _mm_add_epi32(X0, X1);
X3 = _mm_xor_si128(_mm_xor_si128(X3, _mm_slli_epi32(T, 7)), _mm_srli_epi32(T, 25));
T = _mm_add_epi32(X3, X0);
T = _mm_add_epi32(X3, X0);
X2 = _mm_xor_si128(_mm_xor_si128(X2, _mm_slli_epi32(T, 9)), _mm_srli_epi32(T, 23));
T = _mm_add_epi32(X2, X3);
T = _mm_add_epi32(X2, X3);
X1 = _mm_xor_si128(_mm_xor_si128(X1, _mm_slli_epi32(T, 13)), _mm_srli_epi32(T, 19));
T = _mm_add_epi32(X1, X2);
T = _mm_add_epi32(X1, X2);
X0 = _mm_xor_si128(_mm_xor_si128(X0, _mm_slli_epi32(T, 18)), _mm_srli_epi32(T, 14));
X1 = _mm_shuffle_epi32(X1, 0x39);
X2 = _mm_shuffle_epi32(X2, 0x4E);
@ -202,13 +205,21 @@ template <unsigned int R> static ZT_INLINE void p_salsaCrypt(p_SalsaState* const
__m128i k20 = _mm_or_si128(_mm_and_si128(X2, maskLo32), _mm_and_si128(X1, maskHi32));
__m128i k13 = _mm_or_si128(_mm_slli_epi64(X1, 32), _mm_srli_epi64(X0, 32));
__m128i k31 = _mm_or_si128(_mm_and_si128(X3, maskLo32), _mm_and_si128(X2, maskHi32));
k02 = _mm_shuffle_epi32(k02, _MM_SHUFFLE(0, 1, 2, 3));
k13 = _mm_shuffle_epi32(k13, _MM_SHUFFLE(0, 1, 2, 3));
k02 = _mm_shuffle_epi32(k02, _MM_SHUFFLE(0, 1, 2, 3));
k13 = _mm_shuffle_epi32(k13, _MM_SHUFFLE(0, 1, 2, 3));
_mm_storeu_si128(reinterpret_cast<__m128i*>(c), _mm_xor_si128(_mm_unpackhi_epi64(k02, k20), _mm_loadu_si128(reinterpret_cast<const __m128i*>(m))));
_mm_storeu_si128(reinterpret_cast<__m128i*>(c) + 1, _mm_xor_si128(_mm_unpackhi_epi64(k13, k31), _mm_loadu_si128(reinterpret_cast<const __m128i*>(m) + 1)));
_mm_storeu_si128(reinterpret_cast<__m128i*>(c) + 2, _mm_xor_si128(_mm_unpacklo_epi64(k20, k02), _mm_loadu_si128(reinterpret_cast<const __m128i*>(m) + 2)));
_mm_storeu_si128(reinterpret_cast<__m128i*>(c) + 3, _mm_xor_si128(_mm_unpacklo_epi64(k31, k13), _mm_loadu_si128(reinterpret_cast<const __m128i*>(m) + 3)));
_mm_storeu_si128(
reinterpret_cast<__m128i *>(c),
_mm_xor_si128(_mm_unpackhi_epi64(k02, k20), _mm_loadu_si128(reinterpret_cast<const __m128i *>(m))));
_mm_storeu_si128(
reinterpret_cast<__m128i *>(c) + 1,
_mm_xor_si128(_mm_unpackhi_epi64(k13, k31), _mm_loadu_si128(reinterpret_cast<const __m128i *>(m) + 1)));
_mm_storeu_si128(
reinterpret_cast<__m128i *>(c) + 2,
_mm_xor_si128(_mm_unpacklo_epi64(k20, k02), _mm_loadu_si128(reinterpret_cast<const __m128i *>(m) + 2)));
_mm_storeu_si128(
reinterpret_cast<__m128i *>(c) + 3,
_mm_xor_si128(_mm_unpacklo_epi64(k31, k13), _mm_loadu_si128(reinterpret_cast<const __m128i *>(m) + 3)));
X0 = X0s;
X1 = X1s;
@ -217,16 +228,16 @@ template <unsigned int R> static ZT_INLINE void p_salsaCrypt(p_SalsaState* const
#else
x0 = j0;
x1 = j1;
x2 = j2;
x3 = j3;
x4 = j4;
x5 = j5;
x6 = j6;
x7 = j7;
x8 = j8;
x9 = j9;
x0 = j0;
x1 = j1;
x2 = j2;
x3 = j3;
x4 = j4;
x5 = j5;
x6 = j6;
x7 = j7;
x8 = j8;
x9 = j9;
x10 = j10;
x11 = j11;
x12 = j12;
@ -235,33 +246,33 @@ template <unsigned int R> static ZT_INLINE void p_salsaCrypt(p_SalsaState* const
x15 = j15;
for (unsigned int rr = 0; rr < (R / 2); ++rr) {
x4 = XOR(x4, ROTATE(PLUS(x0, x12), 7));
x8 = XOR(x8, ROTATE(PLUS(x4, x0), 9));
x4 = XOR(x4, ROTATE(PLUS(x0, x12), 7));
x8 = XOR(x8, ROTATE(PLUS(x4, x0), 9));
x12 = XOR(x12, ROTATE(PLUS(x8, x4), 13));
x0 = XOR(x0, ROTATE(PLUS(x12, x8), 18));
x9 = XOR(x9, ROTATE(PLUS(x5, x1), 7));
x0 = XOR(x0, ROTATE(PLUS(x12, x8), 18));
x9 = XOR(x9, ROTATE(PLUS(x5, x1), 7));
x13 = XOR(x13, ROTATE(PLUS(x9, x5), 9));
x1 = XOR(x1, ROTATE(PLUS(x13, x9), 13));
x5 = XOR(x5, ROTATE(PLUS(x1, x13), 18));
x1 = XOR(x1, ROTATE(PLUS(x13, x9), 13));
x5 = XOR(x5, ROTATE(PLUS(x1, x13), 18));
x14 = XOR(x14, ROTATE(PLUS(x10, x6), 7));
x2 = XOR(x2, ROTATE(PLUS(x14, x10), 9));
x6 = XOR(x6, ROTATE(PLUS(x2, x14), 13));
x2 = XOR(x2, ROTATE(PLUS(x14, x10), 9));
x6 = XOR(x6, ROTATE(PLUS(x2, x14), 13));
x10 = XOR(x10, ROTATE(PLUS(x6, x2), 18));
x3 = XOR(x3, ROTATE(PLUS(x15, x11), 7));
x7 = XOR(x7, ROTATE(PLUS(x3, x15), 9));
x3 = XOR(x3, ROTATE(PLUS(x15, x11), 7));
x7 = XOR(x7, ROTATE(PLUS(x3, x15), 9));
x11 = XOR(x11, ROTATE(PLUS(x7, x3), 13));
x15 = XOR(x15, ROTATE(PLUS(x11, x7), 18));
x1 = XOR(x1, ROTATE(PLUS(x0, x3), 7));
x2 = XOR(x2, ROTATE(PLUS(x1, x0), 9));
x3 = XOR(x3, ROTATE(PLUS(x2, x1), 13));
x0 = XOR(x0, ROTATE(PLUS(x3, x2), 18));
x6 = XOR(x6, ROTATE(PLUS(x5, x4), 7));
x7 = XOR(x7, ROTATE(PLUS(x6, x5), 9));
x4 = XOR(x4, ROTATE(PLUS(x7, x6), 13));
x5 = XOR(x5, ROTATE(PLUS(x4, x7), 18));
x1 = XOR(x1, ROTATE(PLUS(x0, x3), 7));
x2 = XOR(x2, ROTATE(PLUS(x1, x0), 9));
x3 = XOR(x3, ROTATE(PLUS(x2, x1), 13));
x0 = XOR(x0, ROTATE(PLUS(x3, x2), 18));
x6 = XOR(x6, ROTATE(PLUS(x5, x4), 7));
x7 = XOR(x7, ROTATE(PLUS(x6, x5), 9));
x4 = XOR(x4, ROTATE(PLUS(x7, x6), 13));
x5 = XOR(x5, ROTATE(PLUS(x4, x7), 18));
x11 = XOR(x11, ROTATE(PLUS(x10, x9), 7));
x8 = XOR(x8, ROTATE(PLUS(x11, x10), 9));
x9 = XOR(x9, ROTATE(PLUS(x8, x11), 13));
x8 = XOR(x8, ROTATE(PLUS(x11, x10), 9));
x9 = XOR(x9, ROTATE(PLUS(x8, x11), 13));
x10 = XOR(x10, ROTATE(PLUS(x9, x8), 18));
x12 = XOR(x12, ROTATE(PLUS(x15, x14), 7));
x13 = XOR(x13, ROTATE(PLUS(x12, x15), 9));
@ -269,16 +280,16 @@ template <unsigned int R> static ZT_INLINE void p_salsaCrypt(p_SalsaState* const
x15 = XOR(x15, ROTATE(PLUS(x14, x13), 18));
}
x0 = PLUS(x0, j0);
x1 = PLUS(x1, j1);
x2 = PLUS(x2, j2);
x3 = PLUS(x3, j3);
x4 = PLUS(x4, j4);
x5 = PLUS(x5, j5);
x6 = PLUS(x6, j6);
x7 = PLUS(x7, j7);
x8 = PLUS(x8, j8);
x9 = PLUS(x9, j9);
x0 = PLUS(x0, j0);
x1 = PLUS(x1, j1);
x2 = PLUS(x2, j2);
x3 = PLUS(x3, j3);
x4 = PLUS(x4, j4);
x5 = PLUS(x5, j5);
x6 = PLUS(x6, j6);
x7 = PLUS(x7, j7);
x8 = PLUS(x8, j8);
x9 = PLUS(x9, j9);
x10 = PLUS(x10, j10);
x11 = PLUS(x11, j11);
x12 = PLUS(x12, j12);
@ -327,14 +338,18 @@ template <unsigned int R> static ZT_INLINE void p_salsaCrypt(p_SalsaState* const
}
}
void Salsa20::crypt12(const void* in, void* out, unsigned int bytes) noexcept
void Salsa20::crypt12(const void *in, void *out, unsigned int bytes) noexcept
{
p_salsaCrypt<12>(reinterpret_cast<p_SalsaState*>(&_state), reinterpret_cast<const uint8_t*>(in), reinterpret_cast<uint8_t*>(out), bytes);
p_salsaCrypt<12>(
reinterpret_cast<p_SalsaState *>(&_state), reinterpret_cast<const uint8_t *>(in),
reinterpret_cast<uint8_t *>(out), bytes);
}
void Salsa20::crypt20(const void* in, void* out, unsigned int bytes) noexcept
void Salsa20::crypt20(const void *in, void *out, unsigned int bytes) noexcept
{
p_salsaCrypt<20>(reinterpret_cast<p_SalsaState*>(&_state), reinterpret_cast<const uint8_t*>(in), reinterpret_cast<uint8_t*>(out), bytes);
p_salsaCrypt<20>(
reinterpret_cast<p_SalsaState *>(&_state), reinterpret_cast<const uint8_t *>(in),
reinterpret_cast<uint8_t *>(out), bytes);
}
} // namespace ZeroTier

View file

@ -39,35 +39,21 @@ class Salsa20 : public TriviallyCopyable {
public:
#ifdef ZT_SALSA20_SSE
static constexpr bool accelerated() noexcept
{
return true;
}
static constexpr bool accelerated() noexcept { return true; }
#else
static constexpr bool accelerated() noexcept
{
return false;
}
static constexpr bool accelerated() noexcept { return false; }
#endif
ZT_INLINE Salsa20() noexcept
{
}
ZT_INLINE Salsa20() noexcept {}
ZT_INLINE ~Salsa20() noexcept
{
Utils::burn(&_state, sizeof(_state));
}
ZT_INLINE ~Salsa20() noexcept { Utils::burn(&_state, sizeof(_state)); }
/**
* @param key 256-bit (32 byte) key
* @param iv 64-bit initialization vector
*/
ZT_INLINE Salsa20(const void* key, const void* iv) noexcept
{
init(key, iv);
}
ZT_INLINE Salsa20(const void *key, const void *iv) noexcept { init(key, iv); }
/**
* Initialize cipher
@ -75,7 +61,7 @@ class Salsa20 : public TriviallyCopyable {
* @param key Key bits
* @param iv 64-bit initialization vector
*/
void init(const void* key, const void* iv) noexcept;
void init(const void *key, const void *iv) noexcept;
/**
* Encrypt/decrypt data using Salsa20/12
@ -84,7 +70,7 @@ class Salsa20 : public TriviallyCopyable {
* @param out Output buffer
* @param bytes Length of data
*/
void crypt12(const void* in, void* out, unsigned int bytes) noexcept;
void crypt12(const void *in, void *out, unsigned int bytes) noexcept;
/**
* Encrypt/decrypt data using Salsa20/20
@ -93,7 +79,7 @@ class Salsa20 : public TriviallyCopyable {
* @param out Output buffer
* @param bytes Length of data
*/
void crypt20(const void* in, void* out, unsigned int bytes) noexcept;
void crypt20(const void *in, void *out, unsigned int bytes) noexcept;
private:
union {

View file

@ -26,86 +26,47 @@ namespace ZeroTier {
*/
template <typename T> class ScopedPtr : public TriviallyCopyable {
public:
explicit ZT_INLINE ScopedPtr(T* const p) noexcept : m_ptr(p)
explicit ZT_INLINE ScopedPtr(T *const p) noexcept : m_ptr(p) {}
ZT_INLINE ~ScopedPtr() { delete m_ptr; }
ZT_INLINE T *operator->() const noexcept { return m_ptr; }
ZT_INLINE T &operator*() const noexcept { return *m_ptr; }
ZT_INLINE T *ptr() const noexcept { return m_ptr; }
ZT_INLINE void swap(const ScopedPtr &p) noexcept
{
T *const tmp = m_ptr;
m_ptr = p.m_ptr;
p.m_ptr = tmp;
}
ZT_INLINE ~ScopedPtr()
{
delete m_ptr;
}
explicit ZT_INLINE operator bool() const noexcept { return (m_ptr != (T *)0); }
ZT_INLINE T* operator->() const noexcept
{
return m_ptr;
}
ZT_INLINE bool operator==(const ScopedPtr &p) const noexcept { return (m_ptr == p.m_ptr); }
ZT_INLINE T& operator*() const noexcept
{
return *m_ptr;
}
ZT_INLINE bool operator!=(const ScopedPtr &p) const noexcept { return (m_ptr != p.m_ptr); }
ZT_INLINE T* ptr() const noexcept
{
return m_ptr;
}
ZT_INLINE bool operator==(T *const p) const noexcept { return (m_ptr == p); }
ZT_INLINE void swap(const ScopedPtr& p) noexcept
{
T* const tmp = m_ptr;
m_ptr = p.m_ptr;
p.m_ptr = tmp;
}
explicit ZT_INLINE operator bool() const noexcept
{
return (m_ptr != (T*)0);
}
ZT_INLINE bool operator==(const ScopedPtr& p) const noexcept
{
return (m_ptr == p.m_ptr);
}
ZT_INLINE bool operator!=(const ScopedPtr& p) const noexcept
{
return (m_ptr != p.m_ptr);
}
ZT_INLINE bool operator==(T* const p) const noexcept
{
return (m_ptr == p);
}
ZT_INLINE bool operator!=(T* const p) const noexcept
{
return (m_ptr != p);
}
ZT_INLINE bool operator!=(T *const p) const noexcept { return (m_ptr != p); }
private:
ZT_INLINE ScopedPtr() noexcept
{
}
ZT_INLINE ScopedPtr() noexcept {}
ZT_INLINE ScopedPtr(const ScopedPtr& p) noexcept : m_ptr(nullptr)
{
}
ZT_INLINE ScopedPtr(const ScopedPtr &p) noexcept : m_ptr(nullptr) {}
ZT_INLINE ScopedPtr& operator=(const ScopedPtr& p) noexcept
{
return *this;
}
ZT_INLINE ScopedPtr &operator=(const ScopedPtr &p) noexcept { return *this; }
T* const m_ptr;
T *const m_ptr;
};
} // namespace ZeroTier
namespace std {
template <typename T> ZT_INLINE void swap(ZeroTier::ScopedPtr<T>& a, ZeroTier::ScopedPtr<T>& b) noexcept
{
a.swap(b);
}
template <typename T> ZT_INLINE void swap(ZeroTier::ScopedPtr<T> &a, ZeroTier::ScopedPtr<T> &b) noexcept { a.swap(b); }
} // namespace std
#endif

View file

@ -25,25 +25,28 @@
namespace ZeroTier {
SelfAwareness::SelfAwareness(const Context& ctx) : m_ctx(ctx)
{
}
SelfAwareness::SelfAwareness(const Context &ctx) : m_ctx(ctx) {}
void SelfAwareness::iam(const CallContext& cc, const Identity& reporter, const int64_t receivedOnLocalSocket, const InetAddress& reporterPhysicalAddress, const InetAddress& myPhysicalAddress, bool trusted)
void SelfAwareness::iam(
const CallContext &cc, const Identity &reporter, const int64_t receivedOnLocalSocket,
const InetAddress &reporterPhysicalAddress, const InetAddress &myPhysicalAddress, bool trusted)
{
const InetAddress::IpScope scope = myPhysicalAddress.ipScope();
if ((scope != reporterPhysicalAddress.ipScope()) || (scope == ZT_IP_SCOPE_NONE) || (scope == ZT_IP_SCOPE_LOOPBACK) || (scope == ZT_IP_SCOPE_MULTICAST))
if ((scope != reporterPhysicalAddress.ipScope()) || (scope == ZT_IP_SCOPE_NONE) || (scope == ZT_IP_SCOPE_LOOPBACK)
|| (scope == ZT_IP_SCOPE_MULTICAST))
return;
Mutex::Lock l(m_phy_l);
p_PhySurfaceEntry& entry = m_phy[p_PhySurfaceKey(reporter.address(), receivedOnLocalSocket, reporterPhysicalAddress, scope)];
p_PhySurfaceEntry &entry =
m_phy[p_PhySurfaceKey(reporter.address(), receivedOnLocalSocket, reporterPhysicalAddress, scope)];
if ((trusted) && ((cc.ticks - entry.timestampTicks) < ZT_SELFAWARENESS_ENTRY_TIMEOUT) && (! entry.mySurface.ipsEqual(myPhysicalAddress))) {
if ((trusted) && ((cc.ticks - entry.timestampTicks) < ZT_SELFAWARENESS_ENTRY_TIMEOUT)
&& (!entry.mySurface.ipsEqual(myPhysicalAddress))) {
// Changes to external surface reported by trusted peers causes path reset in this scope
entry.mySurface = myPhysicalAddress;
entry.mySurface = myPhysicalAddress;
entry.timestampTicks = cc.ticks;
entry.trusted = trusted;
entry.trusted = trusted;
// Erase all entries in this scope that were not reported from this remote address to prevent 'thrashing'
// due to multiple reports of endpoint change.
@ -56,22 +59,23 @@ void SelfAwareness::iam(const CallContext& cc, const Identity& reporter, const i
}
// Reset all paths within this scope and address family
Vector<SharedPtr<Peer> > peers, rootPeers;
Vector<SharedPtr<Peer>> peers, rootPeers;
m_ctx.topology->allPeers(peers, rootPeers);
for (Vector<SharedPtr<Peer> >::const_iterator p(peers.begin()); p != peers.end(); ++p)
for (Vector<SharedPtr<Peer>>::const_iterator p(peers.begin()); p != peers.end(); ++p)
(*p)->resetWithinScope(m_ctx, cc, (InetAddress::IpScope)scope, myPhysicalAddress.as.sa.sa_family);
m_ctx.t->resettingPathsInScope(cc, 0x9afff100, reporter, reporterPhysicalAddress, entry.mySurface, myPhysicalAddress, scope);
m_ctx.t->resettingPathsInScope(
cc, 0x9afff100, reporter, reporterPhysicalAddress, entry.mySurface, myPhysicalAddress, scope);
}
else {
// Otherwise just update DB to use to determine external surface info
entry.mySurface = myPhysicalAddress;
entry.mySurface = myPhysicalAddress;
entry.timestampTicks = cc.ticks;
entry.trusted = trusted;
entry.trusted = trusted;
}
}
void SelfAwareness::clean(const CallContext& cc)
void SelfAwareness::clean(const CallContext &cc)
{
Mutex::Lock l(m_phy_l);
for (Map<p_PhySurfaceKey, p_PhySurfaceEntry>::iterator i(m_phy.begin()); i != m_phy.end();) {
@ -82,7 +86,7 @@ void SelfAwareness::clean(const CallContext& cc)
}
}
MultiMap<unsigned int, InetAddress> SelfAwareness::externalAddresses(CallContext& cc) const
MultiMap<unsigned int, InetAddress> SelfAwareness::externalAddresses(CallContext &cc) const
{
MultiMap<unsigned int, InetAddress> r;

View file

@ -33,7 +33,7 @@ class Context;
*/
class SelfAwareness {
public:
explicit SelfAwareness(const Context& ctx);
explicit SelfAwareness(const Context &ctx);
/**
* Called when a remote peer informs us of our external network address
@ -44,19 +44,21 @@ class SelfAwareness {
* @param myPhysicalAddress Physical address that peer says we have
* @param trusted True if this peer is trusted as an authority to inform us of external address changes
*/
void iam(const CallContext& cc, const Identity& reporter, int64_t receivedOnLocalSocket, const InetAddress& reporterPhysicalAddress, const InetAddress& myPhysicalAddress, bool trusted);
void
iam(const CallContext &cc, const Identity &reporter, int64_t receivedOnLocalSocket,
const InetAddress &reporterPhysicalAddress, const InetAddress &myPhysicalAddress, bool trusted);
/**
* Clean up database periodically
*/
void clean(const CallContext& cc);
void clean(const CallContext &cc);
/**
* Get external address consensus, which is the statistical "mode" of external addresses.
*
* @return Map of count to IP/port representing how many endpoints reported each address
*/
MultiMap<unsigned int, InetAddress> externalAddresses(CallContext& cc) const;
MultiMap<unsigned int, InetAddress> externalAddresses(CallContext &cc) const;
private:
struct p_PhySurfaceKey {
@ -65,12 +67,10 @@ class SelfAwareness {
InetAddress reporterPhysicalAddress;
InetAddress::IpScope scope;
ZT_INLINE p_PhySurfaceKey() noexcept
{
}
ZT_INLINE p_PhySurfaceKey() noexcept {}
ZT_INLINE
p_PhySurfaceKey(const Address& r, const int64_t rol, const InetAddress& ra, InetAddress::IpScope s) noexcept
p_PhySurfaceKey(const Address &r, const int64_t rol, const InetAddress &ra, InetAddress::IpScope s) noexcept
: reporter(r)
, receivedOnLocalSocket(rol)
, reporterPhysicalAddress(ra)
@ -83,17 +83,16 @@ class SelfAwareness {
return ((unsigned long)reporter.toInt() + (unsigned long)receivedOnLocalSocket + (unsigned long)scope);
}
ZT_INLINE bool operator==(const p_PhySurfaceKey& k) const noexcept
ZT_INLINE bool operator==(const p_PhySurfaceKey &k) const noexcept
{
return ((reporter == k.reporter) && (receivedOnLocalSocket == k.receivedOnLocalSocket) && (reporterPhysicalAddress == k.reporterPhysicalAddress) && (scope == k.scope));
return (
(reporter == k.reporter) && (receivedOnLocalSocket == k.receivedOnLocalSocket)
&& (reporterPhysicalAddress == k.reporterPhysicalAddress) && (scope == k.scope));
}
ZT_INLINE bool operator!=(const p_PhySurfaceKey& k) const noexcept
{
return (! (*this == k));
}
ZT_INLINE bool operator!=(const p_PhySurfaceKey &k) const noexcept { return (!(*this == k)); }
ZT_INLINE bool operator<(const p_PhySurfaceKey& k) const noexcept
ZT_INLINE bool operator<(const p_PhySurfaceKey &k) const noexcept
{
if (reporter < k.reporter) {
return true;
@ -120,14 +119,9 @@ class SelfAwareness {
int64_t timestampTicks;
bool trusted;
ZT_INLINE p_PhySurfaceEntry() noexcept
: mySurface()
, timestampTicks(0)
, trusted(false)
{
}
ZT_INLINE p_PhySurfaceEntry() noexcept : mySurface(), timestampTicks(0), trusted(false) {}
ZT_INLINE p_PhySurfaceEntry(const InetAddress& a, const int64_t t) noexcept
ZT_INLINE p_PhySurfaceEntry(const InetAddress &a, const int64_t t) noexcept
: mySurface(a)
, timestampTicks(t)
, trusted(false)
@ -135,7 +129,7 @@ class SelfAwareness {
}
};
const Context& m_ctx;
const Context &m_ctx;
Map<p_PhySurfaceKey, p_PhySurfaceEntry> m_phy;
Mutex m_phy_l;
};

View file

@ -27,40 +27,33 @@ namespace ZeroTier {
*/
template <typename T> class SharedPtr : public TriviallyCopyable {
public:
ZT_INLINE SharedPtr() noexcept : m_ptr(nullptr)
{
}
ZT_INLINE SharedPtr() noexcept : m_ptr(nullptr) {}
explicit ZT_INLINE SharedPtr(T* obj) noexcept : m_ptr(obj)
explicit ZT_INLINE SharedPtr(T *obj) noexcept : m_ptr(obj)
{
if (likely(obj != nullptr))
const_cast<std::atomic<int>*>(&(obj->__refCount))->fetch_add(1, std::memory_order_acquire);
const_cast<std::atomic<int> *>(&(obj->__refCount))->fetch_add(1, std::memory_order_acquire);
}
ZT_INLINE SharedPtr(const SharedPtr& sp) noexcept : m_ptr(sp.m_acquire())
{
}
ZT_INLINE SharedPtr(const SharedPtr &sp) noexcept : m_ptr(sp.m_acquire()) {}
ZT_INLINE ~SharedPtr()
{
m_release();
}
ZT_INLINE ~SharedPtr() { m_release(); }
ZT_INLINE SharedPtr& operator=(const SharedPtr& sp)
ZT_INLINE SharedPtr &operator=(const SharedPtr &sp)
{
if (likely(m_ptr != sp.m_ptr)) {
T* const p = sp.m_acquire();
T *const p = sp.m_acquire();
m_release();
m_ptr = p;
}
return *this;
}
ZT_INLINE void set(T* ptr) noexcept
ZT_INLINE void set(T *ptr) noexcept
{
m_release();
m_ptr = ptr;
const_cast<std::atomic<int>*>(&(ptr->__refCount))->fetch_add(1, std::memory_order_acquire);
const_cast<std::atomic<int> *>(&(ptr->__refCount))->fetch_add(1, std::memory_order_acquire);
}
/**
@ -71,11 +64,11 @@ template <typename T> class SharedPtr : public TriviallyCopyable {
*
* @param with Pointer to swap with
*/
ZT_INLINE void swap(SharedPtr& with) noexcept
ZT_INLINE void swap(SharedPtr &with) noexcept
{
T* const tmp = m_ptr;
m_ptr = with.m_ptr;
with.m_ptr = tmp;
T *const tmp = m_ptr;
m_ptr = with.m_ptr;
with.m_ptr = tmp;
}
/**
@ -87,35 +80,23 @@ template <typename T> class SharedPtr : public TriviallyCopyable {
*
* @param from Source pointer; will be changed to NULL
*/
ZT_INLINE void move(SharedPtr& from)
ZT_INLINE void move(SharedPtr &from)
{
m_release();
m_ptr = from.m_ptr;
m_ptr = from.m_ptr;
from.m_ptr = nullptr;
}
ZT_INLINE operator bool() const noexcept
{
return (m_ptr != nullptr);
}
ZT_INLINE operator bool() const noexcept { return (m_ptr != nullptr); }
ZT_INLINE T& operator*() const noexcept
{
return *m_ptr;
}
ZT_INLINE T &operator*() const noexcept { return *m_ptr; }
ZT_INLINE T* operator->() const noexcept
{
return m_ptr;
}
ZT_INLINE T *operator->() const noexcept { return m_ptr; }
/**
* @return Raw pointer to held object
*/
ZT_INLINE T* ptr() const noexcept
{
return m_ptr;
}
ZT_INLINE T *ptr() const noexcept { return m_ptr; }
/**
* Set this pointer to NULL
@ -136,13 +117,13 @@ template <typename T> class SharedPtr : public TriviallyCopyable {
*
* @return Pointer or NULL if more than one reference
*/
ZT_INLINE T* weakGC()
ZT_INLINE T *weakGC()
{
if (likely(m_ptr != nullptr)) {
int one = 1;
if (const_cast<std::atomic<int>*>(&(m_ptr->__refCount))->compare_exchange_strong(one, (int)0)) {
T* const ptr = m_ptr;
m_ptr = nullptr;
if (const_cast<std::atomic<int> *>(&(m_ptr->__refCount))->compare_exchange_strong(one, (int)0)) {
T *const ptr = m_ptr;
m_ptr = nullptr;
return ptr;
}
else {
@ -159,53 +140,48 @@ template <typename T> class SharedPtr : public TriviallyCopyable {
return (unsigned long)((uintptr_t)m_ptr + (uintptr_t)Utils::hash32((uint32_t)m_ptr));
}
ZT_INLINE bool operator==(const SharedPtr& sp) const noexcept
ZT_INLINE bool operator==(const SharedPtr &sp) const noexcept { return (m_ptr == sp.m_ptr); }
ZT_INLINE bool operator!=(const SharedPtr &sp) const noexcept { return (m_ptr != sp.m_ptr); }
ZT_INLINE bool operator>(const SharedPtr &sp) const noexcept
{
return (m_ptr == sp.m_ptr);
return (reinterpret_cast<const uint8_t *>(m_ptr) > reinterpret_cast<const uint8_t *>(sp.m_ptr));
}
ZT_INLINE bool operator!=(const SharedPtr& sp) const noexcept
ZT_INLINE bool operator<(const SharedPtr &sp) const noexcept
{
return (m_ptr != sp.m_ptr);
return (reinterpret_cast<const uint8_t *>(m_ptr) < reinterpret_cast<const uint8_t *>(sp.m_ptr));
}
ZT_INLINE bool operator>(const SharedPtr& sp) const noexcept
ZT_INLINE bool operator>=(const SharedPtr &sp) const noexcept
{
return (reinterpret_cast<const uint8_t*>(m_ptr) > reinterpret_cast<const uint8_t*>(sp.m_ptr));
return (reinterpret_cast<const uint8_t *>(m_ptr) >= reinterpret_cast<const uint8_t *>(sp.m_ptr));
}
ZT_INLINE bool operator<(const SharedPtr& sp) const noexcept
ZT_INLINE bool operator<=(const SharedPtr &sp) const noexcept
{
return (reinterpret_cast<const uint8_t*>(m_ptr) < reinterpret_cast<const uint8_t*>(sp.m_ptr));
}
ZT_INLINE bool operator>=(const SharedPtr& sp) const noexcept
{
return (reinterpret_cast<const uint8_t*>(m_ptr) >= reinterpret_cast<const uint8_t*>(sp.m_ptr));
}
ZT_INLINE bool operator<=(const SharedPtr& sp) const noexcept
{
return (reinterpret_cast<const uint8_t*>(m_ptr) <= reinterpret_cast<const uint8_t*>(sp.m_ptr));
return (reinterpret_cast<const uint8_t *>(m_ptr) <= reinterpret_cast<const uint8_t *>(sp.m_ptr));
}
private:
ZT_INLINE T* m_acquire() const noexcept
ZT_INLINE T *m_acquire() const noexcept
{
if (likely(m_ptr != nullptr))
const_cast<std::atomic<int>*>(&(m_ptr->__refCount))->fetch_add(1, std::memory_order_acquire);
const_cast<std::atomic<int> *>(&(m_ptr->__refCount))->fetch_add(1, std::memory_order_acquire);
return m_ptr;
}
ZT_INLINE void m_release() const noexcept
{
if (likely(m_ptr != nullptr)) {
if (unlikely(const_cast<std::atomic<int>*>(&(m_ptr->__refCount))->fetch_sub(1, std::memory_order_release) <= 1))
if (unlikely(
const_cast<std::atomic<int> *>(&(m_ptr->__refCount))->fetch_sub(1, std::memory_order_release) <= 1))
delete m_ptr;
}
}
T* m_ptr;
T *m_ptr;
};
} // namespace ZeroTier
@ -213,12 +189,12 @@ template <typename T> class SharedPtr : public TriviallyCopyable {
// Augment std::swap to speed up some operations with SharedPtr.
namespace std {
template <typename T> ZT_MAYBE_UNUSED ZT_INLINE void swap(ZeroTier::SharedPtr<T>& a, ZeroTier::SharedPtr<T>& b) noexcept
template <typename T> ZT_MAYBE_UNUSED ZT_INLINE void swap(ZeroTier::SharedPtr<T> &a, ZeroTier::SharedPtr<T> &b) noexcept
{
a.swap(b);
}
template <typename T> ZT_MAYBE_UNUSED ZT_INLINE void move(ZeroTier::SharedPtr<T>& a, ZeroTier::SharedPtr<T>& b) noexcept
template <typename T> ZT_MAYBE_UNUSED ZT_INLINE void move(ZeroTier::SharedPtr<T> &a, ZeroTier::SharedPtr<T> &b) noexcept
{
a.move(b);
}

View file

@ -49,9 +49,7 @@ class Spinlock {
#endif
}
ZT_INLINE Spinlock() noexcept : m_locked(false)
{
}
ZT_INLINE Spinlock() noexcept : m_locked(false) {}
ZT_INLINE void lock() noexcept
{
@ -62,19 +60,11 @@ class Spinlock {
}
}
ZT_INLINE void unlock() noexcept
{
m_locked.clear(std::memory_order_release);
}
ZT_INLINE void unlock() noexcept { m_locked.clear(std::memory_order_release); }
private:
ZT_INLINE Spinlock(const Spinlock&) noexcept
{
}
ZT_INLINE const Spinlock& operator=(const Spinlock&) noexcept
{
return *this;
}
ZT_INLINE Spinlock(const Spinlock &) noexcept {}
ZT_INLINE const Spinlock &operator=(const Spinlock &) noexcept { return *this; }
std::atomic_flag m_locked;
};

View file

@ -26,9 +26,7 @@ namespace ZeroTier {
*/
class Store {
public:
ZT_INLINE Store(const Context& ctx) : m_ctx(ctx)
{
}
ZT_INLINE Store(const Context &ctx) : m_ctx(ctx) {}
/**
* Get a state object
@ -38,14 +36,16 @@ class Store {
* @param idSize Size of object ID in qwords
* @return Data or empty vector if not found
*/
ZT_INLINE Vector<uint8_t> get(const CallContext& cc, ZT_StateObjectType type, const uint64_t* const id, unsigned int idSize) const
ZT_INLINE Vector<uint8_t>
get(const CallContext &cc, ZT_StateObjectType type, const uint64_t *const id, unsigned int idSize) const
{
Vector<uint8_t> dv;
void* data = nullptr;
void (*freeFunc)(void*) = nullptr;
const int r = m_ctx.cb.stateGetFunction(reinterpret_cast<ZT_Node*>(m_ctx.node), m_ctx.uPtr, cc.tPtr, type, id, idSize, &data, &freeFunc);
void *data = nullptr;
void (*freeFunc)(void *) = nullptr;
const int r = m_ctx.cb.stateGetFunction(
reinterpret_cast<ZT_Node *>(m_ctx.node), m_ctx.uPtr, cc.tPtr, type, id, idSize, &data, &freeFunc);
if (r > 0)
dv.assign(reinterpret_cast<const uint8_t*>(data), reinterpret_cast<const uint8_t*>(data) + r);
dv.assign(reinterpret_cast<const uint8_t *>(data), reinterpret_cast<const uint8_t *>(data) + r);
if ((data) && (freeFunc))
freeFunc(data);
return dv;
@ -60,9 +60,12 @@ class Store {
* @param data Data to store
* @param len Length of data
*/
ZT_INLINE void put(const CallContext& cc, ZT_StateObjectType type, const uint64_t* const id, const unsigned int idSize, const void* const data, const unsigned int len) noexcept
ZT_INLINE void
put(const CallContext &cc, ZT_StateObjectType type, const uint64_t *const id, const unsigned int idSize,
const void *const data, const unsigned int len) noexcept
{
m_ctx.cb.statePutFunction(reinterpret_cast<ZT_Node*>(this), m_ctx.uPtr, cc.tPtr, type, id, idSize, data, (int)len);
m_ctx.cb.statePutFunction(
reinterpret_cast<ZT_Node *>(this), m_ctx.uPtr, cc.tPtr, type, id, idSize, data, (int)len);
}
/**
@ -72,13 +75,15 @@ class Store {
* @param id Object ID
* @param idSize Size of object ID in qwords
*/
ZT_INLINE void erase(const CallContext& cc, ZT_StateObjectType type, const uint64_t* const id, const unsigned int idSize) noexcept
ZT_INLINE void
erase(const CallContext &cc, ZT_StateObjectType type, const uint64_t *const id, const unsigned int idSize) noexcept
{
m_ctx.cb.statePutFunction(reinterpret_cast<ZT_Node*>(this), m_ctx.uPtr, cc.tPtr, type, id, idSize, nullptr, -1);
m_ctx.cb.statePutFunction(
reinterpret_cast<ZT_Node *>(this), m_ctx.uPtr, cc.tPtr, type, id, idSize, nullptr, -1);
}
private:
const Context& m_ctx;
const Context &m_ctx;
};
} // namespace ZeroTier

View file

@ -29,9 +29,7 @@ class SymmetricKey {
/**
* Construct an uninitialized key (init() must be called)
*/
ZT_INLINE SymmetricKey() : m_secret(), m_ts(-1), m_initialNonce(0), m_cipher(), m_nonce(0)
{
}
ZT_INLINE SymmetricKey() : m_secret(), m_ts(-1), m_initialNonce(0), m_cipher(), m_nonce(0) {}
/**
* Construct a new symmetric key
@ -42,7 +40,7 @@ class SymmetricKey {
* @param ts Key timestamp
* @param key Key (must be 48 bytes / 384 bits)
*/
ZT_INLINE SymmetricKey(const int64_t ts, const void* const key) noexcept
ZT_INLINE SymmetricKey(const int64_t ts, const void *const key) noexcept
: m_secret(key)
, m_ts(ts)
, m_initialNonce(Utils::getSecureRandomU64() >> 1U)
@ -51,7 +49,7 @@ class SymmetricKey {
{
}
ZT_INLINE SymmetricKey(const SymmetricKey& k) noexcept
ZT_INLINE SymmetricKey(const SymmetricKey &k) noexcept
: m_secret(k.m_secret)
, m_ts(k.m_ts)
, m_initialNonce(k.m_initialNonce)
@ -60,15 +58,12 @@ class SymmetricKey {
{
}
ZT_INLINE ~SymmetricKey() noexcept
{
Utils::burn(m_secret.data, ZT_SYMMETRIC_KEY_SIZE);
}
ZT_INLINE ~SymmetricKey() noexcept { Utils::burn(m_secret.data, ZT_SYMMETRIC_KEY_SIZE); }
ZT_INLINE SymmetricKey& operator=(const SymmetricKey& k) noexcept
ZT_INLINE SymmetricKey &operator=(const SymmetricKey &k) noexcept
{
m_secret = k.m_secret;
m_ts = k.m_ts;
m_secret = k.m_secret;
m_ts = k.m_ts;
m_initialNonce = k.m_initialNonce;
m_cipher.init(k.m_secret.data);
m_nonce.store(k.m_nonce.load(std::memory_order_relaxed), std::memory_order_relaxed);
@ -81,10 +76,10 @@ class SymmetricKey {
* @param ts Key timestamp
* @param key Key (must be 48 bytes / 384 bits)
*/
ZT_INLINE void init(const int64_t ts, const void* const key) noexcept
ZT_INLINE void init(const int64_t ts, const void *const key) noexcept
{
Utils::copy<ZT_SYMMETRIC_KEY_SIZE>(m_secret.data, key);
m_ts = ts;
m_ts = ts;
m_initialNonce = Utils::getSecureRandomU64() >> 1U;
m_cipher.init(key);
m_nonce.store(m_initialNonce, std::memory_order_relaxed);
@ -110,34 +105,22 @@ class SymmetricKey {
*
* @return Number of times nextMessage() has been called since object creation
*/
ZT_INLINE uint64_t odometer() const noexcept
{
return m_nonce.load(std::memory_order_relaxed) - m_initialNonce;
}
ZT_INLINE uint64_t odometer() const noexcept { return m_nonce.load(std::memory_order_relaxed) - m_initialNonce; }
/**
* @return Key creation timestamp or -1 if this is a long-lived key
*/
ZT_INLINE int64_t timestamp() const noexcept
{
return m_ts;
}
ZT_INLINE int64_t timestamp() const noexcept { return m_ts; }
/**
* @return 48-byte / 384-bit secret key
*/
ZT_INLINE const uint8_t* key() const noexcept
{
return m_secret.data;
}
ZT_INLINE const uint8_t *key() const noexcept { return m_secret.data; }
/**
* @return AES cipher (already initialized with secret key)
*/
ZT_INLINE const AES& aes() const noexcept
{
return m_cipher;
}
ZT_INLINE const AES &aes() const noexcept { return m_cipher; }
private:
Blob<ZT_SYMMETRIC_KEY_SIZE> m_secret;

View file

@ -15,11 +15,11 @@
namespace ZeroTier {
bool TagCredential::sign(const Identity& signer) noexcept
bool TagCredential::sign(const Identity &signer) noexcept
{
uint8_t buf[ZT_TAG_MARSHAL_SIZE_MAX];
if (signer.hasPrivate()) {
m_signedBy = signer.address();
m_signedBy = signer.address();
m_signatureLength = signer.sign(buf, (unsigned int)marshal(buf, true), m_signature, sizeof(m_signature));
return true;
}
@ -42,7 +42,7 @@ int TagCredential::marshal(uint8_t data[ZT_TAG_MARSHAL_SIZE_MAX], bool forSign)
p += ZT_ADDRESS_LENGTH;
m_signedBy.copyTo(data + p);
p += ZT_ADDRESS_LENGTH;
if (! forSign) {
if (!forSign) {
data[p++] = 1;
Utils::storeBigEndian<uint16_t>(data + p, (uint16_t)m_signatureLength);
p += 2;
@ -58,19 +58,19 @@ int TagCredential::marshal(uint8_t data[ZT_TAG_MARSHAL_SIZE_MAX], bool forSign)
return p;
}
int TagCredential::unmarshal(const uint8_t* data, int len) noexcept
int TagCredential::unmarshal(const uint8_t *data, int len) noexcept
{
if (len < 37)
return -1;
m_networkId = Utils::loadBigEndian<uint64_t>(data);
m_ts = (int64_t)Utils::loadBigEndian<uint64_t>(data + 8);
m_id = Utils::loadBigEndian<uint32_t>(data + 16);
m_value = Utils::loadBigEndian<uint32_t>(data + 20);
m_ts = (int64_t)Utils::loadBigEndian<uint64_t>(data + 8);
m_id = Utils::loadBigEndian<uint32_t>(data + 16);
m_value = Utils::loadBigEndian<uint32_t>(data + 20);
m_issuedTo.setTo(data + 24);
m_signedBy.setTo(data + 29);
// 1 byte reserved
m_signatureLength = Utils::loadBigEndian<uint16_t>(data + 35);
int p = 37 + (int)m_signatureLength;
int p = 37 + (int)m_signatureLength;
if ((m_signatureLength > ZT_SIGNATURE_BUFFER_SIZE) || (p > len))
return -1;
Utils::copy(m_signature, data + p, m_signatureLength);

View file

@ -47,15 +47,9 @@ class TagCredential : public Credential {
friend class Credential;
public:
static constexpr ZT_CredentialType credentialType() noexcept
{
return ZT_CREDENTIAL_TYPE_TAG;
}
static constexpr ZT_CredentialType credentialType() noexcept { return ZT_CREDENTIAL_TYPE_TAG; }
ZT_INLINE TagCredential() noexcept
{
memoryZero(this);
}
ZT_INLINE TagCredential() noexcept { memoryZero(this); }
/**
* @param nwid Network ID
@ -64,7 +58,9 @@ class TagCredential : public Credential {
* @param id Tag ID
* @param value Tag value
*/
ZT_INLINE TagCredential(const uint64_t nwid, const int64_t ts, const Address& issuedTo, const uint32_t id, const uint32_t value) noexcept
ZT_INLINE TagCredential(
const uint64_t nwid, const int64_t ts, const Address &issuedTo, const uint32_t id,
const uint32_t value) noexcept
: m_id(id)
, m_value(value)
, m_networkId(nwid)
@ -75,50 +71,23 @@ class TagCredential : public Credential {
{
}
ZT_INLINE uint32_t id() const noexcept
{
return m_id;
}
ZT_INLINE uint32_t id() const noexcept { return m_id; }
ZT_INLINE const uint32_t& value() const noexcept
{
return m_value;
}
ZT_INLINE const uint32_t &value() const noexcept { return m_value; }
ZT_INLINE uint64_t networkId() const noexcept
{
return m_networkId;
}
ZT_INLINE uint64_t networkId() const noexcept { return m_networkId; }
ZT_INLINE int64_t timestamp() const noexcept
{
return m_ts;
}
ZT_INLINE int64_t timestamp() const noexcept { return m_ts; }
ZT_INLINE int64_t revision() const noexcept
{
return m_ts;
}
ZT_INLINE int64_t revision() const noexcept { return m_ts; }
ZT_INLINE const Address& issuedTo() const noexcept
{
return m_issuedTo;
}
ZT_INLINE const Address &issuedTo() const noexcept { return m_issuedTo; }
ZT_INLINE const Address& signer() const noexcept
{
return m_signedBy;
}
ZT_INLINE const Address &signer() const noexcept { return m_signedBy; }
ZT_INLINE const uint8_t* signature() const noexcept
{
return m_signature;
}
ZT_INLINE const uint8_t *signature() const noexcept { return m_signature; }
ZT_INLINE unsigned int signatureLength() const noexcept
{
return m_signatureLength;
}
ZT_INLINE unsigned int signatureLength() const noexcept { return m_signatureLength; }
/**
* Sign this tag
@ -126,7 +95,7 @@ class TagCredential : public Credential {
* @param signer Signing identity, must have private key
* @return True if signature was successful
*/
bool sign(const Identity& signer) noexcept;
bool sign(const Identity &signer) noexcept;
/**
* Check this tag's signature
@ -134,82 +103,61 @@ class TagCredential : public Credential {
* @param RR Runtime environment to allow identity lookup for signedBy
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
*/
ZT_INLINE Credential::VerifyResult verify(const Context& ctx, const CallContext& cc) const noexcept
ZT_INLINE Credential::VerifyResult verify(const Context &ctx, const CallContext &cc) const noexcept
{
return s_verify(ctx, cc, *this);
}
static constexpr int marshalSizeMax() noexcept
{
return ZT_TAG_MARSHAL_SIZE_MAX;
}
static constexpr int marshalSizeMax() noexcept { return ZT_TAG_MARSHAL_SIZE_MAX; }
int marshal(uint8_t data[ZT_TAG_MARSHAL_SIZE_MAX], bool forSign = false) const noexcept;
int unmarshal(const uint8_t* data, int len) noexcept;
int unmarshal(const uint8_t *data, int len) noexcept;
// Provides natural sort order by ID
ZT_INLINE bool operator<(const TagCredential& t) const noexcept
{
return (m_id < t.m_id);
}
ZT_INLINE bool operator<(const TagCredential &t) const noexcept { return (m_id < t.m_id); }
ZT_INLINE bool operator==(const TagCredential& t) const noexcept
ZT_INLINE bool operator==(const TagCredential &t) const noexcept
{
return (memcmp(this, &t, sizeof(TagCredential)) == 0);
}
ZT_INLINE bool operator!=(const TagCredential& t) const noexcept
ZT_INLINE bool operator!=(const TagCredential &t) const noexcept
{
return (memcmp(this, &t, sizeof(TagCredential)) != 0);
}
// For searching sorted arrays or lists of Tags by ID
struct IdComparePredicate {
ZT_INLINE bool operator()(const TagCredential& a, const TagCredential& b) const noexcept
ZT_INLINE bool operator()(const TagCredential &a, const TagCredential &b) const noexcept
{
return (a.id() < b.id());
}
ZT_INLINE bool operator()(const uint32_t a, const TagCredential& b) const noexcept
{
return (a < b.id());
}
ZT_INLINE bool operator()(const uint32_t a, const TagCredential &b) const noexcept { return (a < b.id()); }
ZT_INLINE bool operator()(const TagCredential& a, const uint32_t b) const noexcept
{
return (a.id() < b);
}
ZT_INLINE bool operator()(const TagCredential &a, const uint32_t b) const noexcept { return (a.id() < b); }
ZT_INLINE bool operator()(const TagCredential* a, const TagCredential* b) const noexcept
ZT_INLINE bool operator()(const TagCredential *a, const TagCredential *b) const noexcept
{
return (a->id() < b->id());
}
ZT_INLINE bool operator()(const TagCredential* a, const TagCredential& b) const noexcept
ZT_INLINE bool operator()(const TagCredential *a, const TagCredential &b) const noexcept
{
return (a->id() < b.id());
}
ZT_INLINE bool operator()(const TagCredential& a, const TagCredential* b) const noexcept
ZT_INLINE bool operator()(const TagCredential &a, const TagCredential *b) const noexcept
{
return (a.id() < b->id());
}
ZT_INLINE bool operator()(const uint32_t a, const TagCredential* b) const noexcept
{
return (a < b->id());
}
ZT_INLINE bool operator()(const uint32_t a, const TagCredential *b) const noexcept { return (a < b->id()); }
ZT_INLINE bool operator()(const TagCredential* a, const uint32_t b) const noexcept
{
return (a->id() < b);
}
ZT_INLINE bool operator()(const TagCredential *a, const uint32_t b) const noexcept { return (a->id() < b); }
ZT_INLINE bool operator()(const uint32_t a, const uint32_t b) const noexcept
{
return (a < b);
}
ZT_INLINE bool operator()(const uint32_t a, const uint32_t b) const noexcept { return (a < b); }
};
private:

View file

@ -2378,7 +2378,8 @@ extern "C" const char *ZTT_crypto()
ZT_CERTIFICATE_PUBLIC_KEY_ALGORITHM_ECDSA_NIST_P_384, cert->publicKey, (int *)&cert->publicKeySize,
certPrivateKey, &certPrivateKeySize);
auto csr = Certificate::createCSR(cert->subject, certPrivateKey, certPrivateKeySize, uniqueIdPrivate, uniqueIdPrivateKeySize);
auto csr = Certificate::createCSR(
cert->subject, certPrivateKey, certPrivateKeySize, uniqueIdPrivate, uniqueIdPrivateKeySize);
if (csr.empty()) {
ZT_T_PRINTF("FAILED (create CSR failed)" ZT_EOL_S);
return "Create CSR";

View file

@ -57,7 +57,7 @@ extern "C" {
/**
* Test platform, compiler behavior, utility functions, and core classes
*/
const char* ZTT_general();
const char *ZTT_general();
/**
* Test crypto using test vectors and simple scenarios
@ -65,12 +65,12 @@ const char* ZTT_general();
* This is not an absolutely exhaustive test, just a sanity check to make sure
* crypto routines are basically working.
*/
const char* ZTT_crypto();
const char *ZTT_crypto();
/**
* Run benchmarks of cryptographic routines and common constructions
*/
const char* ZTT_benchmarkCrypto();
const char *ZTT_benchmarkCrypto();
#ifdef __cplusplus
}

View file

@ -38,17 +38,12 @@ namespace ZeroTier {
*/
template <typename V> class TinyMap {
private:
typedef Vector<std::pair<uint64_t, V> > EV;
typedef Vector<std::pair<uint64_t, V>> EV;
public:
ZT_INLINE TinyMap()
{
}
ZT_INLINE TinyMap() {}
ZT_INLINE ~TinyMap()
{
this->clear();
}
ZT_INLINE ~TinyMap() { this->clear(); }
ZT_INLINE void clear()
{
@ -57,7 +52,7 @@ template <typename V> class TinyMap {
const uintptr_t vptr = m_buckets[i].exchange(ZT_TINYMAP_LOCKED_POINTER, std::memory_order_acquire);
if (likely(vptr != ZT_TINYMAP_LOCKED_POINTER)) {
if (vptr != 0)
delete reinterpret_cast<EV*>(vptr);
delete reinterpret_cast<EV *>(vptr);
m_buckets[i].store(0, std::memory_order_release);
break;
}
@ -71,12 +66,13 @@ template <typename V> class TinyMap {
ZT_INLINE V get(const uint64_t key) noexcept
{
V tmp;
std::atomic<uintptr_t>& bucket = m_buckets[(key ^ (key >> 32)) & ZT_TINYMAP_BUCKETS_MASK];
std::atomic<uintptr_t> &bucket = m_buckets[(key ^ (key >> 32)) & ZT_TINYMAP_BUCKETS_MASK];
for (;;) {
const uintptr_t vptr = bucket.exchange(ZT_TINYMAP_LOCKED_POINTER, std::memory_order_acquire);
if (likely(vptr != ZT_TINYMAP_LOCKED_POINTER)) {
if (likely(vptr != 0)) {
for (typename EV::const_iterator n(reinterpret_cast<const EV*>(vptr)->begin()); n != reinterpret_cast<const EV*>(vptr)->end(); ++n) {
for (typename EV::const_iterator n(reinterpret_cast<const EV *>(vptr)->begin());
n != reinterpret_cast<const EV *>(vptr)->end(); ++n) {
if (likely(n->first == key)) {
tmp = n->second;
break;
@ -92,9 +88,9 @@ template <typename V> class TinyMap {
}
}
ZT_INLINE void set(const uint64_t key, const V& value)
ZT_INLINE void set(const uint64_t key, const V &value)
{
std::atomic<uintptr_t>& bucket = m_buckets[(key ^ (key >> 32)) & ZT_TINYMAP_BUCKETS_MASK];
std::atomic<uintptr_t> &bucket = m_buckets[(key ^ (key >> 32)) & ZT_TINYMAP_BUCKETS_MASK];
for (;;) {
uintptr_t vptr = bucket.exchange(ZT_TINYMAP_LOCKED_POINTER, std::memory_order_acquire);
if (likely(vptr != ZT_TINYMAP_LOCKED_POINTER)) {
@ -102,7 +98,8 @@ template <typename V> class TinyMap {
vptr = reinterpret_cast<uintptr_t>(new EV());
}
else {
for (typename EV::iterator n(reinterpret_cast<EV*>(vptr)->begin()); n != reinterpret_cast<EV*>(vptr)->end(); ++n) {
for (typename EV::iterator n(reinterpret_cast<EV *>(vptr)->begin());
n != reinterpret_cast<EV *>(vptr)->end(); ++n) {
if (n->first == key) {
n->second = value;
bucket.store(vptr, std::memory_order_release);
@ -110,7 +107,7 @@ template <typename V> class TinyMap {
}
}
}
reinterpret_cast<EV*>(vptr)->push_back(std::pair<uint64_t, V>(key, value));
reinterpret_cast<EV *>(vptr)->push_back(std::pair<uint64_t, V>(key, value));
bucket.store(vptr, std::memory_order_release);
return;
}
@ -122,19 +119,20 @@ template <typename V> class TinyMap {
ZT_INLINE void erase(const uint64_t key)
{
std::atomic<uintptr_t>& bucket = m_buckets[(key ^ (key >> 32)) & ZT_TINYMAP_BUCKETS_MASK];
std::atomic<uintptr_t> &bucket = m_buckets[(key ^ (key >> 32)) & ZT_TINYMAP_BUCKETS_MASK];
for (;;) {
uintptr_t vptr = bucket.exchange(ZT_TINYMAP_LOCKED_POINTER, std::memory_order_acquire);
if (likely(vptr != ZT_TINYMAP_LOCKED_POINTER)) {
if (likely(vptr != 0)) {
for (typename EV::iterator n(reinterpret_cast<EV*>(vptr)->begin()); n != reinterpret_cast<EV*>(vptr)->end(); ++n) {
for (typename EV::iterator n(reinterpret_cast<EV *>(vptr)->begin());
n != reinterpret_cast<EV *>(vptr)->end(); ++n) {
if (n->first == key) {
reinterpret_cast<EV*>(vptr)->erase(n);
reinterpret_cast<EV *>(vptr)->erase(n);
break;
}
}
if (reinterpret_cast<EV*>(vptr)->empty()) {
delete reinterpret_cast<EV*>(vptr);
if (reinterpret_cast<EV *>(vptr)->empty()) {
delete reinterpret_cast<EV *>(vptr);
vptr = 0;
}
}

View file

@ -19,14 +19,12 @@
namespace ZeroTier {
Topology::Topology(const Context& ctx, const CallContext& cc) : m_ctx(ctx)
{
}
Topology::Topology(const Context &ctx, const CallContext &cc) : m_ctx(ctx) {}
SharedPtr<Peer> Topology::add(const CallContext& cc, const SharedPtr<Peer>& peer)
SharedPtr<Peer> Topology::add(const CallContext &cc, const SharedPtr<Peer> &peer)
{
RWMutex::Lock _l(m_peers_l);
SharedPtr<Peer>& hp = m_peers[peer->address()];
SharedPtr<Peer> &hp = m_peers[peer->address()];
if (hp)
return hp;
m_loadCached(cc, peer->address(), hp);
@ -36,13 +34,13 @@ SharedPtr<Peer> Topology::add(const CallContext& cc, const SharedPtr<Peer>& peer
return peer;
}
void Topology::allPeers(Vector<SharedPtr<Peer> >& allPeers, Vector<SharedPtr<Peer> >& rootPeers) const
void Topology::allPeers(Vector<SharedPtr<Peer>> &allPeers, Vector<SharedPtr<Peer>> &rootPeers) const
{
allPeers.clear();
{
RWMutex::RLock l(m_peers_l);
allPeers.reserve(m_peers.size());
for (Map<Address, SharedPtr<Peer> >::const_iterator i(m_peers.begin()); i != m_peers.end(); ++i)
for (Map<Address, SharedPtr<Peer>>::const_iterator i(m_peers.begin()); i != m_peers.end(); ++i)
allPeers.push_back(i->second);
}
{
@ -51,7 +49,7 @@ void Topology::allPeers(Vector<SharedPtr<Peer> >& allPeers, Vector<SharedPtr<Pee
}
}
void Topology::doPeriodicTasks(const CallContext& cc)
void Topology::doPeriodicTasks(const CallContext &cc)
{
// Get a list of root peer pointer addresses for filtering during peer cleanup.
Vector<uintptr_t> rootLookup;
@ -59,7 +57,7 @@ void Topology::doPeriodicTasks(const CallContext& cc)
Mutex::Lock l(m_roots_l);
m_rankRoots();
rootLookup.reserve(m_roots.size());
for (Vector<SharedPtr<Peer> >::const_iterator r(m_roots.begin()); r != m_roots.end(); ++r)
for (Vector<SharedPtr<Peer>>::const_iterator r(m_roots.begin()); r != m_roots.end(); ++r)
rootLookup.push_back((uintptr_t)r->ptr());
}
std::sort(rootLookup.begin(), rootLookup.end());
@ -71,20 +69,22 @@ void Topology::doPeriodicTasks(const CallContext& cc)
Vector<Address> toDelete;
{
RWMutex::RLock l1(m_peers_l);
for (Map<Address, SharedPtr<Peer> >::iterator i(m_peers.begin()); i != m_peers.end(); ++i) {
for (Map<Address, SharedPtr<Peer>>::iterator i(m_peers.begin()); i != m_peers.end(); ++i) {
// TODO: also delete if the peer has not exchanged meaningful communication in a while, such as a
// network frame or non-trivial control packet.
if (((cc.ticks - i->second->lastReceive()) > ZT_PEER_ALIVE_TIMEOUT) && (! std::binary_search(rootLookup.begin(), rootLookup.end(), reinterpret_cast<uintptr_t>(i->second.ptr()))))
if (((cc.ticks - i->second->lastReceive()) > ZT_PEER_ALIVE_TIMEOUT)
&& (!std::binary_search(
rootLookup.begin(), rootLookup.end(), reinterpret_cast<uintptr_t>(i->second.ptr()))))
toDelete.push_back(i->first);
}
}
if (! toDelete.empty()) {
if (!toDelete.empty()) {
ZT_SPEW("garbage collecting %u offline or stale peer objects", (unsigned int)toDelete.size());
for (Vector<Address>::iterator i(toDelete.begin()); i != toDelete.end(); ++i) {
SharedPtr<Peer> toSave;
{
RWMutex::Lock l1(m_peers_l);
const Map<Address, SharedPtr<Peer> >::iterator p(m_peers.find(*i));
const Map<Address, SharedPtr<Peer>>::iterator p(m_peers.find(*i));
if (p != m_peers.end()) {
p->second.swap(toSave);
m_peers.erase(p);
@ -97,11 +97,11 @@ void Topology::doPeriodicTasks(const CallContext& cc)
}
{
Vector<Path*> toDelete;
Vector<Path *> toDelete;
{
RWMutex::Lock l1(m_paths_l);
for (Map<Path::Key, SharedPtr<Path> >::iterator i(m_paths.begin()); i != m_paths.end();) {
Path* const d = i->second.weakGC();
for (Map<Path::Key, SharedPtr<Path>>::iterator i(m_paths.begin()); i != m_paths.end();) {
Path *const d = i->second.weakGC();
if (likely(d == nullptr)) {
++i;
}
@ -116,24 +116,24 @@ void Topology::doPeriodicTasks(const CallContext& cc)
}
}
}
if (! toDelete.empty()) {
for (Vector<Path*>::iterator i(toDelete.begin()); i != toDelete.end(); ++i)
if (!toDelete.empty()) {
for (Vector<Path *>::iterator i(toDelete.begin()); i != toDelete.end(); ++i)
delete *i;
ZT_SPEW("garbage collected %u orphaned paths", (unsigned int)toDelete.size());
}
}
}
void Topology::trustStoreChanged(const CallContext& cc)
void Topology::trustStoreChanged(const CallContext &cc)
{
Map<Identity, SharedPtr<const Locator> > roots(m_ctx.ts->roots());
Map<Identity, SharedPtr<const Locator>> roots(m_ctx.ts->roots());
Vector<SharedPtr<Peer> > newRootList;
Vector<SharedPtr<Peer>> newRootList;
newRootList.reserve(roots.size());
for (Map<Identity, SharedPtr<const Locator> >::const_iterator r(roots.begin()); r != roots.end(); ++r) {
for (Map<Identity, SharedPtr<const Locator>>::const_iterator r(roots.begin()); r != roots.end(); ++r) {
SharedPtr<Peer> root(this->peer(cc, r->first.address(), true));
if (! root) {
if (!root) {
root.set(new Peer());
if (root->init(m_ctx, cc, r->first)) {
root = this->add(cc, root);
@ -156,15 +156,15 @@ void Topology::trustStoreChanged(const CallContext& cc)
}
}
void Topology::saveAll(const CallContext& cc)
void Topology::saveAll(const CallContext &cc)
{
RWMutex::RLock l(m_peers_l);
for (Map<Address, SharedPtr<Peer> >::iterator i(m_peers.begin()); i != m_peers.end(); ++i)
for (Map<Address, SharedPtr<Peer>>::iterator i(m_peers.begin()); i != m_peers.end(); ++i)
i->second->save(m_ctx, cc);
}
struct p_RootRankingComparisonOperator {
ZT_INLINE bool operator()(const SharedPtr<Peer>& a, const SharedPtr<Peer>& b) const noexcept
ZT_INLINE bool operator()(const SharedPtr<Peer> &a, const SharedPtr<Peer> &b) const noexcept
{
// Sort roots first in order of which root has spoken most recently, but
// only at a resolution of ZT_PATH_KEEPALIVE_PERIOD/2 units of time. This
@ -202,7 +202,7 @@ void Topology::m_rankRoots()
}
}
void Topology::m_loadCached(const CallContext& cc, const Address& zta, SharedPtr<Peer>& peer)
void Topology::m_loadCached(const CallContext &cc, const Address &zta, SharedPtr<Peer> &peer)
{
// does not require any locks to be held
@ -212,12 +212,12 @@ void Topology::m_loadCached(const CallContext& cc, const Address& zta, SharedPtr
id[1] = 0;
Vector<uint8_t> data(m_ctx.store->get(cc, ZT_STATE_OBJECT_PEER, id, 1));
if (data.size() > 8) {
const uint8_t* d = data.data();
int dl = (int)data.size();
const uint8_t *d = data.data();
int dl = (int)data.size();
const int64_t ts = (int64_t)Utils::loadBigEndian<uint64_t>(d);
Peer* const p = new Peer();
int n = p->unmarshal(m_ctx, cc.ticks, d + 8, dl - 8);
Peer *const p = new Peer();
int n = p->unmarshal(m_ctx, cc.ticks, d + 8, dl - 8);
if (n < 0) {
delete p;
return;
@ -234,13 +234,13 @@ void Topology::m_loadCached(const CallContext& cc, const Address& zta, SharedPtr
}
}
SharedPtr<Peer> Topology::m_peerFromCached(const CallContext& cc, const Address& zta)
SharedPtr<Peer> Topology::m_peerFromCached(const CallContext &cc, const Address &zta)
{
SharedPtr<Peer> p;
m_loadCached(cc, zta, p);
if (p) {
RWMutex::Lock l(m_peers_l);
SharedPtr<Peer>& hp = m_peers[zta];
SharedPtr<Peer> &hp = m_peers[zta];
if (hp)
return hp;
hp = p;
@ -248,11 +248,11 @@ SharedPtr<Peer> Topology::m_peerFromCached(const CallContext& cc, const Address&
return p;
}
SharedPtr<Path> Topology::m_newPath(const int64_t l, const InetAddress& r, const Path::Key& k)
SharedPtr<Path> Topology::m_newPath(const int64_t l, const InetAddress &r, const Path::Key &k)
{
SharedPtr<Path> p(new Path(l, r));
RWMutex::Lock lck(m_paths_l);
SharedPtr<Path>& p2 = m_paths[k];
SharedPtr<Path> &p2 = m_paths[k];
if (p2)
return p2;
p2 = p;

View file

@ -39,7 +39,7 @@ class Context;
*/
class Topology {
public:
Topology(const Context& ctx, const CallContext& cc);
Topology(const Context &ctx, const CallContext &cc);
/**
* Add peer to database
@ -50,7 +50,7 @@ class Topology {
* @param peer Peer to add
* @return New or existing peer
*/
SharedPtr<Peer> add(const CallContext& cc, const SharedPtr<Peer>& peer);
SharedPtr<Peer> add(const CallContext &cc, const SharedPtr<Peer> &peer);
/**
* Get a peer from its address
@ -59,11 +59,11 @@ class Topology {
* @param loadFromCached If false do not load from cache if not in memory (default: true)
* @return Peer or NULL if not found
*/
ZT_INLINE SharedPtr<Peer> peer(const CallContext& cc, const Address& zta, const bool loadFromCached = true)
ZT_INLINE SharedPtr<Peer> peer(const CallContext &cc, const Address &zta, const bool loadFromCached = true)
{
{
RWMutex::RLock l(m_peers_l);
Map<Address, SharedPtr<Peer> >::const_iterator ap(m_peers.find(zta));
Map<Address, SharedPtr<Peer>>::const_iterator ap(m_peers.find(zta));
if (likely(ap != m_peers.end()))
return ap->second;
}
@ -79,12 +79,12 @@ class Topology {
* @param r Remote address
* @return Pointer to canonicalized Path object or NULL on error
*/
ZT_INLINE SharedPtr<Path> path(const int64_t l, const InetAddress& r)
ZT_INLINE SharedPtr<Path> path(const int64_t l, const InetAddress &r)
{
const Path::Key k(r);
{
RWMutex::RLock lck(m_paths_l);
Map<Path::Key, SharedPtr<Path> >::const_iterator p(m_paths.find(k));
Map<Path::Key, SharedPtr<Path>>::const_iterator p(m_paths.find(k));
if (likely(p != m_paths.end()))
return p->second;
}
@ -109,7 +109,7 @@ class Topology {
*
* @param root Set to best root or nullptr if none
*/
ZT_INLINE void root(SharedPtr<Peer>& root)
ZT_INLINE void root(SharedPtr<Peer> &root)
{
l_bestRoot.lock(); // spinlock
root = m_bestRoot;
@ -120,17 +120,17 @@ class Topology {
* @param allPeers Vector to fill with all current peers
* @param rootPeers Vector to fill with peers that are roots
*/
void allPeers(Vector<SharedPtr<Peer> >& allPeers, Vector<SharedPtr<Peer> >& rootPeers) const;
void allPeers(Vector<SharedPtr<Peer>> &allPeers, Vector<SharedPtr<Peer>> &rootPeers) const;
/**
* Do periodic tasks such as database cleanup, cert cleanup, root ranking, etc.
*/
void doPeriodicTasks(const CallContext& cc);
void doPeriodicTasks(const CallContext &cc);
/**
* Rank root servers in descending order of quality
*/
ZT_INLINE void rankRoots(const CallContext& cc)
ZT_INLINE void rankRoots(const CallContext &cc)
{
Mutex::Lock l(m_roots_l);
m_rankRoots();
@ -139,24 +139,24 @@ class Topology {
/**
* Perform internal updates based on changes in the trust store
*/
void trustStoreChanged(const CallContext& cc);
void trustStoreChanged(const CallContext &cc);
/**
* Save all currently known peers to data store
*/
void saveAll(const CallContext& cc);
void saveAll(const CallContext &cc);
private:
void m_rankRoots();
void m_loadCached(const CallContext& cc, const Address& zta, SharedPtr<Peer>& peer);
SharedPtr<Peer> m_peerFromCached(const CallContext& cc, const Address& zta);
SharedPtr<Path> m_newPath(int64_t l, const InetAddress& r, const Path::Key& k);
void m_loadCached(const CallContext &cc, const Address &zta, SharedPtr<Peer> &peer);
SharedPtr<Peer> m_peerFromCached(const CallContext &cc, const Address &zta);
SharedPtr<Path> m_newPath(int64_t l, const InetAddress &r, const Path::Key &k);
const Context& m_ctx;
const Context &m_ctx;
Vector<SharedPtr<Peer> > m_roots;
Map<Address, SharedPtr<Peer> > m_peers;
Map<Path::Key, SharedPtr<Path> > m_paths;
Vector<SharedPtr<Peer>> m_roots;
Map<Address, SharedPtr<Peer>> m_peers;
Map<Path::Key, SharedPtr<Path>> m_paths;
RWMutex m_peers_l; // m_peers
RWMutex m_paths_l; // m_paths

View file

@ -23,11 +23,9 @@
namespace ZeroTier {
Trace::Trace(const Context& ctx) : m_ctx(ctx), m_traceFlags(0)
{
}
Trace::Trace(const Context &ctx) : m_ctx(ctx), m_traceFlags(0) {}
void Trace::unexpectedError(const CallContext& cc, uint32_t codeLocation, const char* message, ...)
void Trace::unexpectedError(const CallContext &cc, uint32_t codeLocation, const char *message, ...)
{
FCV<uint8_t, 4096> buf;
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_UNEXPECTED_ERROR);
@ -37,7 +35,9 @@ void Trace::unexpectedError(const CallContext& cc, uint32_t codeLocation, const
m_ctx.node->postEvent(cc.tPtr, ZT_EVENT_TRACE, buf.data());
}
void Trace::m_resettingPathsInScope(void* tPtr, uint32_t codeLocation, const Identity& reporter, const InetAddress& from, const InetAddress& oldExternal, const InetAddress& newExternal, ZT_InetAddress_IpScope scope)
void Trace::m_resettingPathsInScope(
void *tPtr, uint32_t codeLocation, const Identity &reporter, const InetAddress &from,
const InetAddress &oldExternal, const InetAddress &newExternal, ZT_InetAddress_IpScope scope)
{
FCV<uint8_t, 4096> buf;
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL1_RESETTING_PATHS_IN_SCOPE);
@ -56,14 +56,9 @@ void Trace::m_resettingPathsInScope(void* tPtr, uint32_t codeLocation, const Ide
}
void Trace::m_tryingNewPath(
void* tPtr,
uint32_t codeLocation,
const Identity& trying,
const InetAddress& physicalAddress,
const InetAddress& triggerAddress,
uint64_t triggeringPacketId,
uint8_t triggeringPacketVerb,
const Identity& triggeringPeer)
void *tPtr, uint32_t codeLocation, const Identity &trying, const InetAddress &physicalAddress,
const InetAddress &triggerAddress, uint64_t triggeringPacketId, uint8_t triggeringPacketVerb,
const Identity &triggeringPeer)
{
if ((trying) && (physicalAddress)) {
FCV<uint8_t, 4096> buf;
@ -82,7 +77,9 @@ void Trace::m_tryingNewPath(
}
}
void Trace::m_learnedNewPath(void* tPtr, uint32_t codeLocation, uint64_t packetId, const Identity& peerIdentity, const InetAddress& physicalAddress, const InetAddress& replaced)
void Trace::m_learnedNewPath(
void *tPtr, uint32_t codeLocation, uint64_t packetId, const Identity &peerIdentity,
const InetAddress &physicalAddress, const InetAddress &replaced)
{
if (peerIdentity) {
FCV<uint8_t, 4096> buf;
@ -99,7 +96,9 @@ void Trace::m_learnedNewPath(void* tPtr, uint32_t codeLocation, uint64_t packetI
}
}
void Trace::m_incomingPacketDropped(void* tPtr, uint32_t codeLocation, uint64_t packetId, uint64_t networkId, const Identity& peerIdentity, const InetAddress& physicalAddress, uint8_t hops, uint8_t verb, ZT_TracePacketDropReason reason)
void Trace::m_incomingPacketDropped(
void *tPtr, uint32_t codeLocation, uint64_t packetId, uint64_t networkId, const Identity &peerIdentity,
const InetAddress &physicalAddress, uint8_t hops, uint8_t verb, ZT_TracePacketDropReason reason)
{
FCV<uint8_t, 4096> buf;
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL1_INCOMING_PACKET_DROPPED);
@ -117,7 +116,9 @@ void Trace::m_incomingPacketDropped(void* tPtr, uint32_t codeLocation, uint64_t
m_ctx.node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
}
void Trace::m_outgoingNetworkFrameDropped(void* tPtr, uint32_t codeLocation, uint64_t networkId, const MAC& sourceMac, const MAC& destMac, uint16_t etherType, uint16_t frameLength, const uint8_t* frameData, ZT_TraceFrameDropReason reason)
void Trace::m_outgoingNetworkFrameDropped(
void *tPtr, uint32_t codeLocation, uint64_t networkId, const MAC &sourceMac, const MAC &destMac, uint16_t etherType,
uint16_t frameLength, const uint8_t *frameData, ZT_TraceFrameDropReason reason)
{
FCV<uint8_t, 4096> buf;
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL1_INCOMING_PACKET_DROPPED);
@ -128,26 +129,17 @@ void Trace::m_outgoingNetworkFrameDropped(void* tPtr, uint32_t codeLocation, uin
Dictionary::append(buf, ZT_TRACE_FIELD_ETHERTYPE, etherType);
Dictionary::append(buf, ZT_TRACE_FIELD_FRAME_LENGTH, frameLength);
if (frameData)
Dictionary::append(buf, ZT_TRACE_FIELD_FRAME_DATA, frameData, std::min((unsigned int)64, (unsigned int)frameLength));
Dictionary::append(
buf, ZT_TRACE_FIELD_FRAME_DATA, frameData, std::min((unsigned int)64, (unsigned int)frameLength));
Dictionary::append(buf, ZT_TRACE_FIELD_REASON, reason);
buf.push_back(0);
m_ctx.node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
}
void Trace::m_incomingNetworkFrameDropped(
void* tPtr,
uint32_t codeLocation,
uint64_t networkId,
const MAC& sourceMac,
const MAC& destMac,
const uint16_t etherType,
const Identity& peerIdentity,
const InetAddress& physicalAddress,
uint8_t hops,
uint16_t frameLength,
const uint8_t* frameData,
uint8_t verb,
bool credentialRequestSent,
void *tPtr, uint32_t codeLocation, uint64_t networkId, const MAC &sourceMac, const MAC &destMac,
const uint16_t etherType, const Identity &peerIdentity, const InetAddress &physicalAddress, uint8_t hops,
uint16_t frameLength, const uint8_t *frameData, uint8_t verb, bool credentialRequestSent,
ZT_TraceFrameDropReason reason)
{
FCV<uint8_t, 4096> buf;
@ -164,14 +156,15 @@ void Trace::m_incomingNetworkFrameDropped(
Dictionary::append(buf, ZT_TRACE_FIELD_PACKET_VERB, verb);
Dictionary::append(buf, ZT_TRACE_FIELD_FRAME_LENGTH, frameLength);
if (frameData)
Dictionary::append(buf, ZT_TRACE_FIELD_FRAME_DATA, frameData, std::min((unsigned int)64, (unsigned int)frameLength));
Dictionary::append(
buf, ZT_TRACE_FIELD_FRAME_DATA, frameData, std::min((unsigned int)64, (unsigned int)frameLength));
Dictionary::append(buf, ZT_TRACE_FIELD_FLAG_CREDENTIAL_REQUEST_SENT, credentialRequestSent);
Dictionary::append(buf, ZT_TRACE_FIELD_REASON, reason);
buf.push_back(0);
m_ctx.node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
}
void Trace::m_networkConfigRequestSent(void* tPtr, uint32_t codeLocation, uint64_t networkId)
void Trace::m_networkConfigRequestSent(void *tPtr, uint32_t codeLocation, uint64_t networkId)
{
FCV<uint8_t, 4096> buf;
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL2_NETWORK_CONFIG_REQUESTED);
@ -182,32 +175,18 @@ void Trace::m_networkConfigRequestSent(void* tPtr, uint32_t codeLocation, uint64
}
void Trace::m_networkFilter(
void* tPtr,
uint32_t codeLocation,
uint64_t networkId,
const uint8_t* primaryRuleSetLog,
const uint8_t* matchingCapabilityRuleSetLog,
uint32_t matchingCapabilityId,
int64_t matchingCapabilityTimestamp,
const Address& source,
const Address& dest,
const MAC& sourceMac,
const MAC& destMac,
uint16_t frameLength,
const uint8_t* frameData,
uint16_t etherType,
uint16_t vlanId,
bool noTee,
bool inbound,
int accept)
void *tPtr, uint32_t codeLocation, uint64_t networkId, const uint8_t *primaryRuleSetLog,
const uint8_t *matchingCapabilityRuleSetLog, uint32_t matchingCapabilityId, int64_t matchingCapabilityTimestamp,
const Address &source, const Address &dest, const MAC &sourceMac, const MAC &destMac, uint16_t frameLength,
const uint8_t *frameData, uint16_t etherType, uint16_t vlanId, bool noTee, bool inbound, int accept)
{
FCV<uint8_t, 4096> buf;
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL2_NETWORK_FILTER);
Dictionary::append(buf, ZT_TRACE_FIELD_CODE_LOCATION, codeLocation);
Dictionary::append(buf, ZT_TRACE_FIELD_NETWORK_ID, networkId);
if ((primaryRuleSetLog) && (! Utils::allZero(primaryRuleSetLog, 512)))
if ((primaryRuleSetLog) && (!Utils::allZero(primaryRuleSetLog, 512)))
Dictionary::append(buf, ZT_TRACE_FIELD_PRIMARY_RULE_SET_LOG, primaryRuleSetLog, 512);
if ((matchingCapabilityRuleSetLog) && (! Utils::allZero(matchingCapabilityRuleSetLog, 512)))
if ((matchingCapabilityRuleSetLog) && (!Utils::allZero(matchingCapabilityRuleSetLog, 512)))
Dictionary::append(buf, ZT_TRACE_FIELD_MATCHING_CAPABILITY_RULE_SET_LOG, matchingCapabilityRuleSetLog, 512);
Dictionary::append(buf, ZT_TRACE_FIELD_MATCHING_CAPABILITY_ID, matchingCapabilityId);
Dictionary::append(buf, ZT_TRACE_FIELD_MATCHING_CAPABILITY_TIMESTAMP, matchingCapabilityTimestamp);
@ -217,7 +196,8 @@ void Trace::m_networkFilter(
Dictionary::append(buf, ZT_TRACE_FIELD_DEST_MAC, destMac.toInt());
Dictionary::append(buf, ZT_TRACE_FIELD_FRAME_LENGTH, frameLength);
if (frameData)
Dictionary::append(buf, ZT_TRACE_FIELD_FRAME_DATA, frameData, std::min((unsigned int)64, (unsigned int)frameLength));
Dictionary::append(
buf, ZT_TRACE_FIELD_FRAME_DATA, frameData, std::min((unsigned int)64, (unsigned int)frameLength));
Dictionary::append(buf, ZT_TRACE_FIELD_ETHERTYPE, etherType);
Dictionary::append(buf, ZT_TRACE_FIELD_VLAN_ID, vlanId);
Dictionary::append(buf, ZT_TRACE_FIELD_RULE_FLAG_NOTEE, noTee);
@ -227,7 +207,9 @@ void Trace::m_networkFilter(
m_ctx.node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
}
void Trace::m_credentialRejected(void* tPtr, uint32_t codeLocation, uint64_t networkId, const Identity& identity, uint32_t credentialId, int64_t credentialTimestamp, uint8_t credentialType, ZT_TraceCredentialRejectionReason reason)
void Trace::m_credentialRejected(
void *tPtr, uint32_t codeLocation, uint64_t networkId, const Identity &identity, uint32_t credentialId,
int64_t credentialTimestamp, uint8_t credentialType, ZT_TraceCredentialRejectionReason reason)
{
FCV<uint8_t, 4096> buf;
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL2_NETWORK_CREDENTIAL_REJECTED);

View file

@ -71,209 +71,144 @@ class Trace {
l[rn >> 1U] |= (thisSetMatches + 1U) << ((rn & 1U) << 2U);
}
ZT_INLINE void clear() noexcept
{
memoryZero(this);
}
ZT_INLINE void clear() noexcept { memoryZero(this); }
};
explicit Trace(const Context& ctx);
explicit Trace(const Context &ctx);
void unexpectedError(const CallContext& cc, uint32_t codeLocation, const char* message, ...);
void unexpectedError(const CallContext &cc, uint32_t codeLocation, const char *message, ...);
ZT_INLINE void
resettingPathsInScope(const CallContext& cc, const uint32_t codeLocation, const Identity& reporter, const InetAddress& from, const InetAddress& oldExternal, const InetAddress& newExternal, const InetAddress::IpScope scope)
ZT_INLINE void resettingPathsInScope(
const CallContext &cc, const uint32_t codeLocation, const Identity &reporter, const InetAddress &from,
const InetAddress &oldExternal, const InetAddress &newExternal, const InetAddress::IpScope scope)
{
if (unlikely((m_traceFlags & ZT_TRACE_F_VL1) != 0))
m_resettingPathsInScope(cc.tPtr, codeLocation, reporter, from, oldExternal, newExternal, scope);
}
ZT_INLINE void tryingNewPath(
const CallContext& cc,
const uint32_t codeLocation,
const Identity& trying,
const InetAddress& physicalAddress,
const InetAddress& triggerAddress,
uint64_t triggeringPacketId,
uint8_t triggeringPacketVerb,
const Identity& triggeringPeer)
const CallContext &cc, const uint32_t codeLocation, const Identity &trying, const InetAddress &physicalAddress,
const InetAddress &triggerAddress, uint64_t triggeringPacketId, uint8_t triggeringPacketVerb,
const Identity &triggeringPeer)
{
if (unlikely((m_traceFlags & ZT_TRACE_F_VL1) != 0))
m_tryingNewPath(cc.tPtr, codeLocation, trying, physicalAddress, triggerAddress, triggeringPacketId, triggeringPacketVerb, triggeringPeer);
m_tryingNewPath(
cc.tPtr, codeLocation, trying, physicalAddress, triggerAddress, triggeringPacketId,
triggeringPacketVerb, triggeringPeer);
}
ZT_INLINE void learnedNewPath(const CallContext& cc, const uint32_t codeLocation, uint64_t packetId, const Identity& peerIdentity, const InetAddress& physicalAddress, const InetAddress& replaced)
ZT_INLINE void learnedNewPath(
const CallContext &cc, const uint32_t codeLocation, uint64_t packetId, const Identity &peerIdentity,
const InetAddress &physicalAddress, const InetAddress &replaced)
{
if (unlikely((m_traceFlags & ZT_TRACE_F_VL1) != 0))
m_learnedNewPath(cc.tPtr, codeLocation, packetId, peerIdentity, physicalAddress, replaced);
}
ZT_INLINE void incomingPacketDropped(
const CallContext& cc,
const uint32_t codeLocation,
uint64_t packetId,
uint64_t networkId,
const Identity& peerIdentity,
const InetAddress& physicalAddress,
uint8_t hops,
uint8_t verb,
const CallContext &cc, const uint32_t codeLocation, uint64_t packetId, uint64_t networkId,
const Identity &peerIdentity, const InetAddress &physicalAddress, uint8_t hops, uint8_t verb,
const ZT_TracePacketDropReason reason)
{
if (unlikely((m_traceFlags & ZT_TRACE_F_VL1) != 0))
m_incomingPacketDropped(cc.tPtr, codeLocation, packetId, networkId, peerIdentity, physicalAddress, hops, verb, reason);
m_incomingPacketDropped(
cc.tPtr, codeLocation, packetId, networkId, peerIdentity, physicalAddress, hops, verb, reason);
}
ZT_INLINE void outgoingNetworkFrameDropped(
const CallContext& cc,
const uint32_t codeLocation,
uint64_t networkId,
const MAC& sourceMac,
const MAC& destMac,
uint16_t etherType,
uint16_t frameLength,
const uint8_t* frameData,
const CallContext &cc, const uint32_t codeLocation, uint64_t networkId, const MAC &sourceMac,
const MAC &destMac, uint16_t etherType, uint16_t frameLength, const uint8_t *frameData,
ZT_TraceFrameDropReason reason)
{
if (unlikely((m_traceFlags & ZT_TRACE_F_VL2) != 0))
m_outgoingNetworkFrameDropped(cc.tPtr, codeLocation, networkId, sourceMac, destMac, etherType, frameLength, frameData, reason);
m_outgoingNetworkFrameDropped(
cc.tPtr, codeLocation, networkId, sourceMac, destMac, etherType, frameLength, frameData, reason);
}
ZT_INLINE void incomingNetworkFrameDropped(
const CallContext& cc,
const uint32_t codeLocation,
uint64_t networkId,
const MAC& sourceMac,
const MAC& destMac,
const uint16_t etherType,
const Identity& peerIdentity,
const InetAddress& physicalAddress,
uint8_t hops,
uint16_t frameLength,
const uint8_t* frameData,
uint8_t verb,
bool credentialRequestSent,
const CallContext &cc, const uint32_t codeLocation, uint64_t networkId, const MAC &sourceMac,
const MAC &destMac, const uint16_t etherType, const Identity &peerIdentity, const InetAddress &physicalAddress,
uint8_t hops, uint16_t frameLength, const uint8_t *frameData, uint8_t verb, bool credentialRequestSent,
ZT_TraceFrameDropReason reason)
{
if (unlikely((m_traceFlags & ZT_TRACE_F_VL2) != 0))
m_incomingNetworkFrameDropped(cc.tPtr, codeLocation, networkId, sourceMac, destMac, etherType, peerIdentity, physicalAddress, hops, frameLength, frameData, verb, credentialRequestSent, reason);
m_incomingNetworkFrameDropped(
cc.tPtr, codeLocation, networkId, sourceMac, destMac, etherType, peerIdentity, physicalAddress, hops,
frameLength, frameData, verb, credentialRequestSent, reason);
}
ZT_INLINE void networkConfigRequestSent(const CallContext& cc, const uint32_t codeLocation, uint64_t networkId)
ZT_INLINE void networkConfigRequestSent(const CallContext &cc, const uint32_t codeLocation, uint64_t networkId)
{
if (unlikely((m_traceFlags & ZT_TRACE_F_VL2) != 0))
m_networkConfigRequestSent(cc.tPtr, codeLocation, networkId);
}
ZT_INLINE void networkFilter(
const CallContext& cc,
const uint32_t codeLocation,
uint64_t networkId,
const uint8_t primaryRuleSetLog[512],
const uint8_t matchingCapabilityRuleSetLog[512],
uint32_t matchingCapabilityId,
int64_t matchingCapabilityTimestamp,
const Address& source,
const Address& dest,
const MAC& sourceMac,
const MAC& destMac,
uint16_t frameLength,
const uint8_t* frameData,
uint16_t etherType,
uint16_t vlanId,
bool noTee,
bool inbound,
int accept)
const CallContext &cc, const uint32_t codeLocation, uint64_t networkId, const uint8_t primaryRuleSetLog[512],
const uint8_t matchingCapabilityRuleSetLog[512], uint32_t matchingCapabilityId,
int64_t matchingCapabilityTimestamp, const Address &source, const Address &dest, const MAC &sourceMac,
const MAC &destMac, uint16_t frameLength, const uint8_t *frameData, uint16_t etherType, uint16_t vlanId,
bool noTee, bool inbound, int accept)
{
if (unlikely((m_traceFlags & ZT_TRACE_F_VL2_FILTER) != 0)) {
m_networkFilter(
cc.tPtr,
codeLocation,
networkId,
primaryRuleSetLog,
matchingCapabilityRuleSetLog,
matchingCapabilityId,
matchingCapabilityTimestamp,
source,
dest,
sourceMac,
destMac,
frameLength,
frameData,
etherType,
vlanId,
noTee,
inbound,
accept);
cc.tPtr, codeLocation, networkId, primaryRuleSetLog, matchingCapabilityRuleSetLog, matchingCapabilityId,
matchingCapabilityTimestamp, source, dest, sourceMac, destMac, frameLength, frameData, etherType,
vlanId, noTee, inbound, accept);
}
}
ZT_INLINE void
credentialRejected(const CallContext& cc, const uint32_t codeLocation, uint64_t networkId, const Identity& identity, uint32_t credentialId, int64_t credentialTimestamp, uint8_t credentialType, ZT_TraceCredentialRejectionReason reason)
ZT_INLINE void credentialRejected(
const CallContext &cc, const uint32_t codeLocation, uint64_t networkId, const Identity &identity,
uint32_t credentialId, int64_t credentialTimestamp, uint8_t credentialType,
ZT_TraceCredentialRejectionReason reason)
{
if (unlikely((m_traceFlags & ZT_TRACE_F_VL2) != 0))
m_credentialRejected(cc.tPtr, codeLocation, networkId, identity, credentialId, credentialTimestamp, credentialType, reason);
m_credentialRejected(
cc.tPtr, codeLocation, networkId, identity, credentialId, credentialTimestamp, credentialType, reason);
}
private:
void m_resettingPathsInScope(void* tPtr, uint32_t codeLocation, const Identity& reporter, const InetAddress& from, const InetAddress& oldExternal, const InetAddress& newExternal, InetAddress::IpScope scope);
void m_resettingPathsInScope(
void *tPtr, uint32_t codeLocation, const Identity &reporter, const InetAddress &from,
const InetAddress &oldExternal, const InetAddress &newExternal, InetAddress::IpScope scope);
void m_tryingNewPath(
void* tPtr,
uint32_t codeLocation,
const Identity& trying,
const InetAddress& physicalAddress,
const InetAddress& triggerAddress,
uint64_t triggeringPacketId,
uint8_t triggeringPacketVerb,
const Identity& triggeringPeer);
void *tPtr, uint32_t codeLocation, const Identity &trying, const InetAddress &physicalAddress,
const InetAddress &triggerAddress, uint64_t triggeringPacketId, uint8_t triggeringPacketVerb,
const Identity &triggeringPeer);
void m_learnedNewPath(void* tPtr, uint32_t codeLocation, uint64_t packetId, const Identity& peerIdentity, const InetAddress& physicalAddress, const InetAddress& replaced);
void m_learnedNewPath(
void *tPtr, uint32_t codeLocation, uint64_t packetId, const Identity &peerIdentity,
const InetAddress &physicalAddress, const InetAddress &replaced);
void m_incomingPacketDropped(void* tPtr, uint32_t codeLocation, uint64_t packetId, uint64_t networkId, const Identity& peerIdentity, const InetAddress& physicalAddress, uint8_t hops, uint8_t verb, ZT_TracePacketDropReason reason);
void m_incomingPacketDropped(
void *tPtr, uint32_t codeLocation, uint64_t packetId, uint64_t networkId, const Identity &peerIdentity,
const InetAddress &physicalAddress, uint8_t hops, uint8_t verb, ZT_TracePacketDropReason reason);
void m_outgoingNetworkFrameDropped(void* tPtr, uint32_t codeLocation, uint64_t networkId, const MAC& sourceMac, const MAC& destMac, uint16_t etherType, uint16_t frameLength, const uint8_t* frameData, ZT_TraceFrameDropReason reason);
void m_outgoingNetworkFrameDropped(
void *tPtr, uint32_t codeLocation, uint64_t networkId, const MAC &sourceMac, const MAC &destMac,
uint16_t etherType, uint16_t frameLength, const uint8_t *frameData, ZT_TraceFrameDropReason reason);
void m_incomingNetworkFrameDropped(
void* tPtr,
uint32_t codeLocation,
uint64_t networkId,
const MAC& sourceMac,
const MAC& destMac,
const uint16_t etherType,
const Identity& peerIdentity,
const InetAddress& physicalAddress,
uint8_t hops,
uint16_t frameLength,
const uint8_t* frameData,
uint8_t verb,
bool credentialRequestSent,
void *tPtr, uint32_t codeLocation, uint64_t networkId, const MAC &sourceMac, const MAC &destMac,
const uint16_t etherType, const Identity &peerIdentity, const InetAddress &physicalAddress, uint8_t hops,
uint16_t frameLength, const uint8_t *frameData, uint8_t verb, bool credentialRequestSent,
ZT_TraceFrameDropReason reason);
void m_networkConfigRequestSent(void* tPtr, uint32_t codeLocation, uint64_t networkId);
void m_networkConfigRequestSent(void *tPtr, uint32_t codeLocation, uint64_t networkId);
void m_networkFilter(
void* tPtr,
uint32_t codeLocation,
uint64_t networkId,
const uint8_t* primaryRuleSetLog,
const uint8_t* matchingCapabilityRuleSetLog,
uint32_t matchingCapabilityId,
int64_t matchingCapabilityTimestamp,
const Address& source,
const Address& dest,
const MAC& sourceMac,
const MAC& destMac,
uint16_t frameLength,
const uint8_t* frameData,
uint16_t etherType,
uint16_t vlanId,
bool noTee,
bool inbound,
int accept);
void *tPtr, uint32_t codeLocation, uint64_t networkId, const uint8_t *primaryRuleSetLog,
const uint8_t *matchingCapabilityRuleSetLog, uint32_t matchingCapabilityId, int64_t matchingCapabilityTimestamp,
const Address &source, const Address &dest, const MAC &sourceMac, const MAC &destMac, uint16_t frameLength,
const uint8_t *frameData, uint16_t etherType, uint16_t vlanId, bool noTee, bool inbound, int accept);
void m_credentialRejected(void* tPtr, uint32_t codeLocation, uint64_t networkId, const Identity& identity, uint32_t credentialId, int64_t credentialTimestamp, uint8_t credentialType, ZT_TraceCredentialRejectionReason reason);
void m_credentialRejected(
void *tPtr, uint32_t codeLocation, uint64_t networkId, const Identity &identity, uint32_t credentialId,
int64_t credentialTimestamp, uint8_t credentialType, ZT_TraceCredentialRejectionReason reason);
const Context& m_ctx;
const Context &m_ctx;
volatile unsigned int m_traceFlags; // faster than atomic, but may not "instantly" change... should be okay
};

View file

@ -32,7 +32,7 @@ struct TriviallyCopyable {
* @tparam T Automatically inferred type of object
* @param obj Any TriviallyCopyable object
*/
template <typename T> static ZT_INLINE void memoryZero(T* obj) noexcept
template <typename T> static ZT_INLINE void memoryZero(T *obj) noexcept
{
mustBeTriviallyCopyable(obj);
Utils::zero<sizeof(T)>(obj);
@ -44,19 +44,15 @@ struct TriviallyCopyable {
* @tparam T Automatically inferred type of object
* @param obj Any TriviallyCopyable object
*/
template <typename T> static ZT_INLINE void memoryZero(T& obj) noexcept
template <typename T> static ZT_INLINE void memoryZero(T &obj) noexcept
{
mustBeTriviallyCopyable(obj);
Utils::zero<sizeof(T)>(&obj);
}
private:
static ZT_INLINE void mustBeTriviallyCopyable(const TriviallyCopyable&) noexcept
{
}
static ZT_INLINE void mustBeTriviallyCopyable(const TriviallyCopyable*) noexcept
{
}
static ZT_INLINE void mustBeTriviallyCopyable(const TriviallyCopyable &) noexcept {}
static ZT_INLINE void mustBeTriviallyCopyable(const TriviallyCopyable *) noexcept {}
};
} // namespace ZeroTier

View file

@ -17,41 +17,41 @@
namespace ZeroTier {
TrustStore::TrustStore()
{
}
TrustStore::TrustStore() {}
TrustStore::~TrustStore()
{
}
TrustStore::~TrustStore() {}
SharedPtr<TrustStore::Entry> TrustStore::get(const H384& serial) const
SharedPtr<TrustStore::Entry> TrustStore::get(const H384 &serial) const
{
RWMutex::RLock l(m_lock);
Map<H384, SharedPtr<Entry> >::const_iterator c(m_bySerial.find(serial));
Map<H384, SharedPtr<Entry>>::const_iterator c(m_bySerial.find(serial));
return (c != m_bySerial.end()) ? c->second : SharedPtr<TrustStore::Entry>();
}
Map<Identity, SharedPtr<const Locator> > TrustStore::roots()
Map<Identity, SharedPtr<const Locator>> TrustStore::roots()
{
RWMutex::RLock l(m_lock);
Map<Identity, SharedPtr<const Locator> > r;
Map<Identity, SharedPtr<const Locator>> r;
// Iterate using m_bySubjectIdentity to only scan certificates with subject identities.
// This map also does not contian error or deprecated certificates.
for (Map<Fingerprint, Vector<SharedPtr<Entry> > >::const_iterator cv(m_bySubjectIdentity.begin()); cv != m_bySubjectIdentity.end(); ++cv) {
for (Vector<SharedPtr<Entry> >::const_iterator c(cv->second.begin()); c != cv->second.end(); ++c) {
for (Map<Fingerprint, Vector<SharedPtr<Entry>>>::const_iterator cv(m_bySubjectIdentity.begin());
cv != m_bySubjectIdentity.end(); ++cv) {
for (Vector<SharedPtr<Entry>>::const_iterator c(cv->second.begin()); c != cv->second.end(); ++c) {
// A root set cert must be marked for this use and authorized to influence this node's config.
if ((((*c)->m_certificate.usageFlags & ZT_CERTIFICATE_USAGE_ZEROTIER_ROOT_SET) != 0) && (((*c)->m_localTrust & ZT_CERTIFICATE_LOCAL_TRUST_FLAG_CONFIG) != 0)) {
if ((((*c)->m_certificate.usageFlags & ZT_CERTIFICATE_USAGE_ZEROTIER_ROOT_SET) != 0)
&& (((*c)->m_localTrust & ZT_CERTIFICATE_LOCAL_TRUST_FLAG_CONFIG) != 0)) {
// Add all identities to the root set, and for each entry in the set make sure we have the latest
// locator if there's more than one cert with one.
for (unsigned int j = 0; j < (*c)->certificate().subject.identityCount; ++j) {
const Identity* const id = reinterpret_cast<const Identity*>((*c)->certificate().subject.identities[j].identity);
const Identity *const id =
reinterpret_cast<const Identity *>((*c)->certificate().subject.identities[j].identity);
if ((id) && (*id)) { // sanity check
SharedPtr<const Locator>& existingLoc = r[*id];
const Locator* const loc = reinterpret_cast<const Locator*>((*c)->certificate().subject.identities[j].locator);
SharedPtr<const Locator> &existingLoc = r[*id];
const Locator *const loc =
reinterpret_cast<const Locator *>((*c)->certificate().subject.identities[j].locator);
if (loc) {
if ((! existingLoc) || (existingLoc->revision() < loc->revision()))
if ((!existingLoc) || (existingLoc->revision() < loc->revision()))
existingLoc.set(new Locator(*loc));
}
}
@ -62,43 +62,43 @@ Map<Identity, SharedPtr<const Locator> > TrustStore::roots()
return r;
}
Vector<SharedPtr<TrustStore::Entry> > TrustStore::all(const bool includeRejectedCertificates) const
Vector<SharedPtr<TrustStore::Entry>> TrustStore::all(const bool includeRejectedCertificates) const
{
RWMutex::RLock l(m_lock);
Vector<SharedPtr<Entry> > r;
Vector<SharedPtr<Entry>> r;
r.reserve(m_bySerial.size());
for (Map<H384, SharedPtr<Entry> >::const_iterator c(m_bySerial.begin()); c != m_bySerial.end(); ++c) {
for (Map<H384, SharedPtr<Entry>>::const_iterator c(m_bySerial.begin()); c != m_bySerial.end(); ++c) {
if ((includeRejectedCertificates) || (c->second->error() == ZT_CERTIFICATE_ERROR_NONE))
r.push_back(c->second);
}
return r;
}
void TrustStore::add(const Certificate& cert, const unsigned int localTrust)
void TrustStore::add(const Certificate &cert, const unsigned int localTrust)
{
RWMutex::Lock l(m_lock);
m_addQueue.push_front(SharedPtr<Entry>(new Entry(this->m_lock, cert, localTrust)));
}
void TrustStore::erase(const H384& serial)
void TrustStore::erase(const H384 &serial)
{
RWMutex::Lock l(m_lock);
m_deleteQueue.push_front(serial);
}
bool TrustStore::update(const int64_t clock, Vector<SharedPtr<Entry> >* const purge)
bool TrustStore::update(const int64_t clock, Vector<SharedPtr<Entry>> *const purge)
{
RWMutex::Lock l(m_lock);
// Check for certificate time validity status changes. If any of these occur then
// full re-validation is required.
bool errorStateModified = false;
for (Map<H384, SharedPtr<Entry> >::const_iterator c(m_bySerial.begin()); c != m_bySerial.end(); ++c) {
for (Map<H384, SharedPtr<Entry>>::const_iterator c(m_bySerial.begin()); c != m_bySerial.end(); ++c) {
const bool timeValid = c->second->m_certificate.verifyTimeWindow(clock);
switch (c->second->m_error) {
case ZT_CERTIFICATE_ERROR_NONE:
case ZT_CERTIFICATE_ERROR_INVALID_CHAIN:
if (! timeValid) {
if (!timeValid) {
c->second->m_error = ZT_CERTIFICATE_ERROR_OUT_OF_VALID_TIME_WINDOW;
errorStateModified = true;
}
@ -109,46 +109,45 @@ bool TrustStore::update(const int64_t clock, Vector<SharedPtr<Entry> >* const pu
errorStateModified = true;
}
break;
default:
break;
default: break;
}
}
// If there were not any such changes and if the add and delete queues are empty,
// there is nothing more to be done.
if ((! errorStateModified) && (m_addQueue.empty()) && (m_deleteQueue.empty()))
if ((!errorStateModified) && (m_addQueue.empty()) && (m_deleteQueue.empty()))
return false;
// Add new certificates to m_bySerial, which is the master certificate set. They still
// have yet to have their full certificate chains validated. Full signature checking is
// performed here.
while (! m_addQueue.empty()) {
SharedPtr<Entry>& qi = m_addQueue.front();
qi->m_error = qi->m_certificate.verify(clock, true);
while (!m_addQueue.empty()) {
SharedPtr<Entry> &qi = m_addQueue.front();
qi->m_error = qi->m_certificate.verify(clock, true);
m_bySerial[H384(qi->m_certificate.serialNo)].move(qi);
m_addQueue.pop_front();
}
// Delete any certificates enqueued to be deleted.
while (! m_deleteQueue.empty()) {
while (!m_deleteQueue.empty()) {
m_bySerial.erase(m_deleteQueue.front());
m_deleteQueue.pop_front();
}
// Reset flags for deprecation and a cert being on a trust path, which are
// recomputed when chain and subjects are checked below.
for (Map<H384, SharedPtr<Entry> >::const_iterator c(m_bySerial.begin()); c != m_bySerial.end(); ++c) {
for (Map<H384, SharedPtr<Entry>>::const_iterator c(m_bySerial.begin()); c != m_bySerial.end(); ++c) {
if (c->second->m_error == ZT_CERTIFICATE_ERROR_NONE) {
c->second->m_subjectDeprecated = false;
c->second->m_onTrustPath = false;
c->second->m_onTrustPath = false;
}
}
// Validate certificate trust paths.
{
Vector<Entry*> visited;
Vector<Entry *> visited;
visited.reserve(8);
for (Map<H384, SharedPtr<Entry> >::iterator c(m_bySerial.begin()); c != m_bySerial.end(); ++c) {
for (Map<H384, SharedPtr<Entry>>::iterator c(m_bySerial.begin()); c != m_bySerial.end(); ++c) {
if (c->second->m_error == ZT_CERTIFICATE_ERROR_NONE) {
if (c->second->m_certificate.isSelfSigned()) {
// If this is a self-signed certificate it's only valid if it's trusted as a CA.
@ -157,34 +156,44 @@ bool TrustStore::update(const int64_t clock, Vector<SharedPtr<Entry> >* const pu
}
}
else {
if ((! c->second->m_onTrustPath) && ((c->second->m_localTrust & ZT_CERTIFICATE_LOCAL_TRUST_FLAG_ROOT_CA) == 0)) {
if ((!c->second->m_onTrustPath)
&& ((c->second->m_localTrust & ZT_CERTIFICATE_LOCAL_TRUST_FLAG_ROOT_CA) == 0)) {
// Trace the path of each certificate all the way back to a trusted CA.
unsigned int pathLength = 0;
Map<H384, SharedPtr<Entry> >::const_iterator current(c);
Map<H384, SharedPtr<Entry>>::const_iterator current(c);
visited.clear();
for (;;) {
if (pathLength <= current->second->m_certificate.maxPathLength) {
// Check if this cert isn't a CA or already part of a valid trust path. If so then step upward
// toward CA.
if (((current->second->m_localTrust & ZT_CERTIFICATE_LOCAL_TRUST_FLAG_ROOT_CA) == 0) && (! current->second->m_onTrustPath)) {
// If the issuer (parent) certificiate is (1) valid, (2) not already visited (to prevent
// loops), and (3) has a public key that matches this cert's issuer public key (sanity
// check), proceed up the certificate graph toward a potential CA.
// Check if this cert isn't a CA or already part of a valid trust path. If so then step
// upward toward CA.
if (((current->second->m_localTrust & ZT_CERTIFICATE_LOCAL_TRUST_FLAG_ROOT_CA) == 0)
&& (!current->second->m_onTrustPath)) {
// If the issuer (parent) certificiate is (1) valid, (2) not already visited (to
// prevent loops), and (3) has a public key that matches this cert's issuer public
// key (sanity check), proceed up the certificate graph toward a potential CA.
visited.push_back(current->second.ptr());
const Map<H384, SharedPtr<Entry> >::const_iterator prevChild(current);
const Map<H384, SharedPtr<Entry>>::const_iterator prevChild(current);
current = m_bySerial.find(H384(current->second->m_certificate.issuer));
if ((current != m_bySerial.end()) && (std::find(visited.begin(), visited.end(), current->second.ptr()) == visited.end()) && (current->second->m_error == ZT_CERTIFICATE_ERROR_NONE)
&& (current->second->m_certificate.publicKeySize == prevChild->second->m_certificate.issuerPublicKeySize)
&& (memcmp(current->second->m_certificate.publicKey, prevChild->second->m_certificate.issuerPublicKey, current->second->m_certificate.publicKeySize) == 0)) {
if ((current != m_bySerial.end())
&& (std::find(visited.begin(), visited.end(), current->second.ptr())
== visited.end())
&& (current->second->m_error == ZT_CERTIFICATE_ERROR_NONE)
&& (current->second->m_certificate.publicKeySize
== prevChild->second->m_certificate.issuerPublicKeySize)
&& (memcmp(
current->second->m_certificate.publicKey,
prevChild->second->m_certificate.issuerPublicKey,
current->second->m_certificate.publicKeySize)
== 0)) {
++pathLength;
continue;
}
}
else {
// If we've traced this to a root CA, flag its parents as also being on a trust path. Then
// break the loop without setting an error. We don't flag the current cert as being on a
// trust path since no other certificates depend on it.
for (Vector<Entry*>::const_iterator v(visited.begin()); v != visited.end(); ++v) {
// If we've traced this to a root CA, flag its parents as also being on a trust
// path. Then break the loop without setting an error. We don't flag the current
// cert as being on a trust path since no other certificates depend on it.
for (Vector<Entry *>::const_iterator v(visited.begin()); v != visited.end(); ++v) {
if (*v != c->second.ptr())
(*v)->m_onTrustPath = true;
}
@ -207,25 +216,29 @@ bool TrustStore::update(const int64_t clock, Vector<SharedPtr<Entry> >* const pu
// certificates for the same subject as deprecated. A deprecated certificate is not invalid
// but will be purged if it is also not part of a trust path. Error certificates are ignored.
m_bySubjectUniqueId.clear();
for (Map<H384, SharedPtr<Entry> >::const_iterator c(m_bySerial.begin()); c != m_bySerial.end();) {
for (Map<H384, SharedPtr<Entry>>::const_iterator c(m_bySerial.begin()); c != m_bySerial.end();) {
if (c->second->m_error == ZT_CERTIFICATE_ERROR_NONE) {
const unsigned int uniqueIdSize = c->second->m_certificate.subject.uniqueIdSize;
if ((uniqueIdSize > 0) && (uniqueIdSize <= ZT_CERTIFICATE_MAX_PUBLIC_KEY_SIZE)) {
SharedPtr<Entry>& entry = m_bySubjectUniqueId[Blob<ZT_CERTIFICATE_MAX_PUBLIC_KEY_SIZE>(c->second->m_certificate.subject.uniqueId, uniqueIdSize)];
SharedPtr<Entry> &entry = m_bySubjectUniqueId[Blob<ZT_CERTIFICATE_MAX_PUBLIC_KEY_SIZE>(
c->second->m_certificate.subject.uniqueId, uniqueIdSize)];
if (entry) {
// If there's already an entry, see if there's a newer certificate for this subject.
if (c->second->m_certificate.subject.timestamp > entry->m_certificate.subject.timestamp) {
entry->m_subjectDeprecated = true;
entry = c->second;
entry = c->second;
}
else if (c->second->m_certificate.subject.timestamp < entry->m_certificate.subject.timestamp) {
c->second->m_subjectDeprecated = true;
}
else {
// Equal timestamps should never happen, but handle it anyway by comparing serials.
if (memcmp(c->second->m_certificate.serialNo, entry->m_certificate.serialNo, ZT_CERTIFICATE_HASH_SIZE) > 0) {
if (memcmp(
c->second->m_certificate.serialNo, entry->m_certificate.serialNo,
ZT_CERTIFICATE_HASH_SIZE)
> 0) {
entry->m_subjectDeprecated = true;
entry = c->second;
entry = c->second;
}
else {
c->second->m_subjectDeprecated = true;
@ -242,10 +255,11 @@ bool TrustStore::update(const int64_t clock, Vector<SharedPtr<Entry> >* const pu
// Populate mapping of identities to certificates whose subjects reference them, ignoring
// error or deprecated certificates.
m_bySubjectIdentity.clear();
for (Map<H384, SharedPtr<Entry> >::const_iterator c(m_bySerial.begin()); c != m_bySerial.end(); ++c) {
if ((c->second->m_error == ZT_CERTIFICATE_ERROR_NONE) && (! c->second->m_subjectDeprecated)) {
for (Map<H384, SharedPtr<Entry>>::const_iterator c(m_bySerial.begin()); c != m_bySerial.end(); ++c) {
if ((c->second->m_error == ZT_CERTIFICATE_ERROR_NONE) && (!c->second->m_subjectDeprecated)) {
for (unsigned int i = 0; i < c->second->m_certificate.subject.identityCount; ++i) {
const Identity* const id = reinterpret_cast<const Identity*>(c->second->m_certificate.subject.identities[i].identity);
const Identity *const id =
reinterpret_cast<const Identity *>(c->second->m_certificate.subject.identities[i].identity);
if ((id) && (*id)) // sanity check
m_bySubjectIdentity[id->fingerprint()].push_back(c->second);
}
@ -254,8 +268,9 @@ bool TrustStore::update(const int64_t clock, Vector<SharedPtr<Entry> >* const pu
// If purge is set, erase and return error and deprecated certs (that are not on a trust path).
if (purge) {
for (Map<H384, SharedPtr<Entry> >::const_iterator c(m_bySerial.begin()); c != m_bySerial.end();) {
if ((c->second->error() != ZT_CERTIFICATE_ERROR_NONE) || ((c->second->m_subjectDeprecated) && (! c->second->m_onTrustPath))) {
for (Map<H384, SharedPtr<Entry>>::const_iterator c(m_bySerial.begin()); c != m_bySerial.end();) {
if ((c->second->error() != ZT_CERTIFICATE_ERROR_NONE)
|| ((c->second->m_subjectDeprecated) && (!c->second->m_onTrustPath))) {
purge->push_back(c->second);
m_bySerial.erase(c++);
}
@ -283,7 +298,7 @@ Vector<uint8_t> TrustStore::save() const
b.push_back(0);
// <size[2]> <certificate[...]> <trust[2]> tuples terminated by a 0 size.
for (Map<H384, SharedPtr<Entry> >::const_iterator c(m_bySerial.begin()); c != m_bySerial.end(); ++c) {
for (Map<H384, SharedPtr<Entry>>::const_iterator c(m_bySerial.begin()); c != m_bySerial.end(); ++c) {
const Vector<uint8_t> cdata(c->second->certificate().encode());
const unsigned long size = (uint32_t)cdata.size();
if ((size > 0) && (size <= 0xffff)) {
@ -299,7 +314,9 @@ Vector<uint8_t> TrustStore::save() const
b.push_back(0);
comp.resize((unsigned long)LZ4_COMPRESSBOUND(b.size()) + 8);
compSize = LZ4_compress_fast(reinterpret_cast<const char*>(b.data()), reinterpret_cast<char*>(comp.data() + 8), (int)b.size(), (int)(comp.size() - 8));
compSize = LZ4_compress_fast(
reinterpret_cast<const char *>(b.data()), reinterpret_cast<char *>(comp.data() + 8), (int)b.size(),
(int)(comp.size() - 8));
if (unlikely(compSize <= 0)) // shouldn't be possible
return Vector<uint8_t>();
@ -315,7 +332,7 @@ Vector<uint8_t> TrustStore::save() const
return comp;
}
int TrustStore::load(const Vector<uint8_t>& data)
int TrustStore::load(const Vector<uint8_t> &data)
{
if (data.size() < 8)
return -1;
@ -327,12 +344,15 @@ int TrustStore::load(const Vector<uint8_t>& data)
Vector<uint8_t> uncomp;
uncomp.resize(uncompSize);
if (LZ4_decompress_safe(reinterpret_cast<const char*>(data.data() + 8), reinterpret_cast<char*>(uncomp.data()), (int)(data.size() - 8), (int)uncompSize) != (int)uncompSize)
if (LZ4_decompress_safe(
reinterpret_cast<const char *>(data.data() + 8), reinterpret_cast<char *>(uncomp.data()),
(int)(data.size() - 8), (int)uncompSize)
!= (int)uncompSize)
return -1;
const uint8_t* b = uncomp.data();
const uint8_t *b = uncomp.data();
if (Utils::fnv1a32(b, (unsigned int)uncompSize) != Utils::loadBigEndian<uint32_t>(data.data() + 4))
return -1;
const uint8_t* const eof = b + uncompSize;
const uint8_t *const eof = b + uncompSize;
if (*(b++) != 0) // unrecognized version
return -1;

View file

@ -57,10 +57,7 @@ class TrustStore {
/**
* @return Reference to held certificate
*/
ZT_INLINE const Certificate& certificate() const noexcept
{
return m_certificate;
}
ZT_INLINE const Certificate &certificate() const noexcept { return m_certificate; }
/**
* Get the local trust for this certificate
@ -98,12 +95,9 @@ class TrustStore {
}
private:
Entry& operator=(const Entry&)
{
return *this;
}
Entry &operator=(const Entry &) { return *this; }
ZT_INLINE Entry(RWMutex& l, const Certificate& cert, const unsigned int lt) noexcept
ZT_INLINE Entry(RWMutex &l, const Certificate &cert, const unsigned int lt) noexcept
: __refCount(0)
, m_lock(l)
, m_certificate(cert)
@ -116,7 +110,7 @@ class TrustStore {
std::atomic<int> __refCount;
RWMutex& m_lock;
RWMutex &m_lock;
const Certificate m_certificate;
unsigned int m_localTrust;
ZT_CertificateError m_error;
@ -137,7 +131,7 @@ class TrustStore {
* @param serial SHA384 hash of certificate
* @return Entry or empty/nil if not found
*/
SharedPtr<Entry> get(const H384& serial) const;
SharedPtr<Entry> get(const H384 &serial) const;
/**
* Get roots specified by root set certificates in the local store.
@ -148,13 +142,13 @@ class TrustStore {
*
* @return Roots and the latest locator specified for each (if any)
*/
Map<Identity, SharedPtr<const Locator> > roots();
Map<Identity, SharedPtr<const Locator>> roots();
/**
* @param includeRejectedCertificates If true, also include certificates with error codes
* @return All certificates in asecending sort order by serial
*/
Vector<SharedPtr<Entry> > all(bool includeRejectedCertificates) const;
Vector<SharedPtr<Entry>> all(bool includeRejectedCertificates) const;
/**
* Add a certificate
@ -168,7 +162,7 @@ class TrustStore {
*
* @param cert Certificate to add
*/
void add(const Certificate& cert, unsigned int localTrust);
void add(const Certificate &cert, unsigned int localTrust);
/**
* Queue a certificate to be deleted
@ -177,7 +171,7 @@ class TrustStore {
*
* @param serial Serial of certificate to delete
*/
void erase(const H384& serial);
void erase(const H384 &serial);
/**
* Validate all certificates and their certificate chains
@ -188,7 +182,7 @@ class TrustStore {
* @param purge If non-NULL, purge rejected certificates and return them in this vector (vector should be empty)
* @return True if there were changes
*/
bool update(int64_t clock, Vector<SharedPtr<Entry> >* purge);
bool update(int64_t clock, Vector<SharedPtr<Entry>> *purge);
/**
* Create a compressed binary version of certificates and their local trust
@ -206,13 +200,14 @@ class TrustStore {
* @param data Data to decode
* @return Number of certificates or -1 if input is invalid
*/
int load(const Vector<uint8_t>& data);
int load(const Vector<uint8_t> &data);
private:
Map<H384, SharedPtr<Entry> > m_bySerial; // all certificates
Map<Blob<ZT_CERTIFICATE_MAX_PUBLIC_KEY_SIZE>, SharedPtr<Entry> > m_bySubjectUniqueId; // non-rejected certificates only
Map<Fingerprint, Vector<SharedPtr<Entry> > > m_bySubjectIdentity; // non-rejected certificates only
ForwardList<SharedPtr<Entry> > m_addQueue;
Map<H384, SharedPtr<Entry>> m_bySerial; // all certificates
Map<Blob<ZT_CERTIFICATE_MAX_PUBLIC_KEY_SIZE>, SharedPtr<Entry>>
m_bySubjectUniqueId; // non-rejected certificates only
Map<Fingerprint, Vector<SharedPtr<Entry>>> m_bySubjectIdentity; // non-rejected certificates only
ForwardList<SharedPtr<Entry>> m_addQueue;
ForwardList<H384> m_deleteQueue;
RWMutex m_lock;
};

View file

@ -76,32 +76,32 @@ ARMCapabilities::ARMCapabilities() noexcept
{
#ifdef __APPLE__
this->aes = true;
this->aes = true;
this->crc32 = true;
this->pmull = true;
this->sha1 = true;
this->sha2 = true;
this->sha1 = true;
this->sha2 = true;
#else
#ifdef __LINUX__
#ifdef HWCAP2_AES
if (sizeof(void*) == 4) {
if (sizeof(void *) == 4) {
const long hwcaps2 = getauxval(AT_HWCAP2);
this->aes = (hwcaps2 & HWCAP2_AES) != 0;
this->crc32 = (hwcaps2 & HWCAP2_CRC32) != 0;
this->pmull = (hwcaps2 & HWCAP2_PMULL) != 0;
this->sha1 = (hwcaps2 & HWCAP2_SHA1) != 0;
this->sha2 = (hwcaps2 & HWCAP2_SHA2) != 0;
this->aes = (hwcaps2 & HWCAP2_AES) != 0;
this->crc32 = (hwcaps2 & HWCAP2_CRC32) != 0;
this->pmull = (hwcaps2 & HWCAP2_PMULL) != 0;
this->sha1 = (hwcaps2 & HWCAP2_SHA1) != 0;
this->sha2 = (hwcaps2 & HWCAP2_SHA2) != 0;
}
else {
#endif
const long hwcaps = getauxval(AT_HWCAP);
this->aes = (hwcaps & HWCAP_AES) != 0;
this->crc32 = (hwcaps & HWCAP_CRC32) != 0;
this->pmull = (hwcaps & HWCAP_PMULL) != 0;
this->sha1 = (hwcaps & HWCAP_SHA1) != 0;
this->sha2 = (hwcaps & HWCAP_SHA2) != 0;
this->aes = (hwcaps & HWCAP_AES) != 0;
this->crc32 = (hwcaps & HWCAP_CRC32) != 0;
this->pmull = (hwcaps & HWCAP_PMULL) != 0;
this->sha1 = (hwcaps & HWCAP_SHA1) != 0;
this->sha2 = (hwcaps & HWCAP_SHA2) != 0;
#ifdef HWCAP2_AES
}
#endif
@ -130,8 +130,8 @@ CPUIDRegisters::CPUIDRegisters() noexcept
#endif
rdrand = ((ecx & (1U << 30U)) != 0);
aes = (((ecx & (1U << 25U)) != 0) && ((ecx & (1U << 19U)) != 0) && ((ecx & (1U << 1U)) != 0));
avx = ((ecx & (1U << 25U)) != 0);
aes = (((ecx & (1U << 25U)) != 0) && ((ecx & (1U << 19U)) != 0) && ((ecx & (1U << 1U)) != 0));
avx = ((ecx & (1U << 25U)) != 0);
#ifdef __WINDOWS__
__cpuid(regs, 7);
@ -143,12 +143,12 @@ CPUIDRegisters::CPUIDRegisters() noexcept
__asm__ __volatile__("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(7), "c"(0));
#endif
vaes = aes && avx && ((ecx & (1U << 9U)) != 0);
vaes = aes && avx && ((ecx & (1U << 9U)) != 0);
vpclmulqdq = aes && avx && ((ecx & (1U << 10U)) != 0);
avx2 = avx && ((ebx & (1U << 5U)) != 0);
avx512f = avx && ((ebx & (1U << 16U)) != 0);
sha = ((ebx & (1U << 29U)) != 0);
fsrm = ((edx & (1U << 4U)) != 0);
avx2 = avx && ((ebx & (1U << 5U)) != 0);
avx512f = avx && ((ebx & (1U << 16U)) != 0);
sha = ((ebx & (1U << 29U)) != 0);
fsrm = ((edx & (1U << 4U)) != 0);
}
const CPUIDRegisters CPUID;
@ -157,27 +157,27 @@ const CPUIDRegisters CPUID;
const std::bad_alloc BadAllocException;
const std::out_of_range OutOfRangeException("access out of range");
const uint64_t ZERO256[4] = { 0, 0, 0, 0 };
const char HEXCHARS[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
const char HEXCHARS[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
const uint64_t s_mapNonce = getSecureRandomU64();
bool secureEq(const void* const a, const void* const b, const unsigned int len) noexcept
bool secureEq(const void *const a, const void *const b, const unsigned int len) noexcept
{
uint8_t diff = 0;
for (unsigned int i = 0; i < len; ++i)
diff |= ((reinterpret_cast<const uint8_t*>(a))[i] ^ (reinterpret_cast<const uint8_t*>(b))[i]);
diff |= ((reinterpret_cast<const uint8_t *>(a))[i] ^ (reinterpret_cast<const uint8_t *>(b))[i]);
return (diff == 0);
}
void burn(volatile void* const ptr, const unsigned int len)
void burn(volatile void *const ptr, const unsigned int len)
{
static volatile uintptr_t foo = 0;
Utils::zero((void*)ptr, len);
Utils::zero((void *)ptr, len);
// Force compiler not to optimize this function out by taking a volatile
// parameter and also updating a volatile variable.
foo += (uintptr_t)len ^ (uintptr_t) reinterpret_cast<volatile uint8_t*>(ptr)[0];
foo += (uintptr_t)len ^ (uintptr_t) reinterpret_cast<volatile uint8_t *>(ptr)[0];
}
static unsigned long s_decimalRecursive(unsigned long n, char* s)
static unsigned long s_decimalRecursive(unsigned long n, char *s)
{
if (n == 0)
return 0;
@ -188,7 +188,7 @@ static unsigned long s_decimalRecursive(unsigned long n, char* s)
return pos + 1;
}
char* decimal(unsigned long n, char s[24]) noexcept
char *decimal(unsigned long n, char s[24]) noexcept
{
if (n == 0) {
s[0] = '0';
@ -199,17 +199,17 @@ char* decimal(unsigned long n, char s[24]) noexcept
return s;
}
char* hex(uint64_t i, char buf[17]) noexcept
char *hex(uint64_t i, char buf[17]) noexcept
{
if (i != 0) {
char* p = nullptr;
char *p = nullptr;
for (int b = 60; b >= 0; b -= 4) {
const unsigned int nyb = (unsigned int)(i >> (unsigned int)b) & 0xfU;
if (p) {
*(p++) = HEXCHARS[nyb];
}
else if (nyb != 0) {
p = buf;
p = buf;
*(p++) = HEXCHARS[nyb];
}
}
@ -223,14 +223,14 @@ char* hex(uint64_t i, char buf[17]) noexcept
}
}
uint64_t unhex(const char* s) noexcept
uint64_t unhex(const char *s) noexcept
{
uint64_t n = 0;
if (s) {
int k = 0;
while (k < 16) {
char hc = *(s++);
if (! hc)
if (!hc)
break;
uint8_t c = 0;
@ -249,27 +249,27 @@ uint64_t unhex(const char* s) noexcept
return n;
}
char* hex(const void* d, unsigned int l, char* s) noexcept
char *hex(const void *d, unsigned int l, char *s) noexcept
{
char* const save = s;
char *const save = s;
for (unsigned int i = 0; i < l; ++i) {
const unsigned int b = reinterpret_cast<const uint8_t*>(d)[i];
*(s++) = HEXCHARS[b >> 4U];
*(s++) = HEXCHARS[b & 0xfU];
const unsigned int b = reinterpret_cast<const uint8_t *>(d)[i];
*(s++) = HEXCHARS[b >> 4U];
*(s++) = HEXCHARS[b & 0xfU];
}
*s = (char)0;
return save;
}
unsigned int unhex(const char* h, unsigned int hlen, void* buf, unsigned int buflen) noexcept
unsigned int unhex(const char *h, unsigned int hlen, void *buf, unsigned int buflen) noexcept
{
unsigned int l = 0;
const char* hend = h + hlen;
unsigned int l = 0;
const char *hend = h + hlen;
while (l < buflen) {
if (h == hend)
break;
uint8_t hc = *(reinterpret_cast<const uint8_t*>(h++));
if (! hc)
uint8_t hc = *(reinterpret_cast<const uint8_t *>(h++));
if (!hc)
break;
uint8_t c = 0;
@ -282,8 +282,8 @@ unsigned int unhex(const char* h, unsigned int hlen, void* buf, unsigned int buf
if (h == hend)
break;
hc = *(reinterpret_cast<const uint8_t*>(h++));
if (! hc)
hc = *(reinterpret_cast<const uint8_t *>(h++));
if (!hc)
break;
c <<= 4U;
@ -294,7 +294,7 @@ unsigned int unhex(const char* h, unsigned int hlen, void* buf, unsigned int buf
else if ((hc >= 65) && (hc <= 70))
c |= hc - 55;
reinterpret_cast<uint8_t*>(buf)[l++] = c;
reinterpret_cast<uint8_t *>(buf)[l++] = c;
}
return l;
}
@ -302,7 +302,7 @@ unsigned int unhex(const char* h, unsigned int hlen, void* buf, unsigned int buf
#define ZT_GETSECURERANDOM_STATE_SIZE 64
#define ZT_GETSECURERANDOM_ITERATIONS_PER_GENERATOR 1048576
void getSecureRandom(void* const buf, unsigned int bytes) noexcept
void getSecureRandom(void *const buf, unsigned int bytes) noexcept
{
static Mutex globalLock;
static bool initialized = false;
@ -320,16 +320,16 @@ void getSecureRandom(void* const buf, unsigned int bytes) noexcept
if (unlikely(randomByteCounter >= ZT_GETSECURERANDOM_ITERATIONS_PER_GENERATOR)) {
randomByteCounter = 0;
if (unlikely(! initialized)) {
if (unlikely(!initialized)) {
initialized = true;
Utils::zero<sizeof(randomState)>(randomState);
#ifdef __WINDOWS__
HCRYPTPROV cryptProvider = NULL;
if (! CryptAcquireContextA(&cryptProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
if (!CryptAcquireContextA(&cryptProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
fprintf(stderr, "FATAL: Utils::getSecureRandom() unable to obtain WinCrypt context!\r\n");
exit(1);
}
if (! CryptGenRandom(cryptProvider, (DWORD)sizeof(randomState), (BYTE*)randomState)) {
if (!CryptGenRandom(cryptProvider, (DWORD)sizeof(randomState), (BYTE *)randomState)) {
fprintf(stderr, "FATAL: Utils::getSecureRandom() CryptGenRandom failed!\r\n");
exit(1);
}
@ -355,7 +355,7 @@ void getSecureRandom(void* const buf, unsigned int bytes) noexcept
if (CPUID.rdrand) {
uint64_t tmp = 0;
for (unsigned long i = 0; i < ZT_GETSECURERANDOM_STATE_SIZE; ++i) {
_rdrand64_step((unsigned long long*)&tmp);
_rdrand64_step((unsigned long long *)&tmp);
randomState[i] ^= tmp;
}
}
@ -373,8 +373,8 @@ void getSecureRandom(void* const buf, unsigned int bytes) noexcept
// Generate random bytes using AES and bytes 32-48 of randomState as an in-place
// AES-CTR counter. Counter can be machine endian; we don't care about portability
// for a random generator.
uint64_t* const ctr = randomState + 4;
uint8_t* out = reinterpret_cast<uint8_t*>(buf);
uint64_t *const ctr = randomState + 4;
uint8_t *out = reinterpret_cast<uint8_t *>(buf);
while (bytes >= 16) {
++*ctr;
@ -400,7 +400,7 @@ uint64_t getSecureRandomU64() noexcept
return tmp;
}
int b32e(const uint8_t* data, int length, char* result, int bufSize) noexcept
int b32e(const uint8_t *data, int length, char *result, int bufSize) noexcept
{
if (length < 0 || length > (1 << 28U)) {
result[0] = (char)0;
@ -408,8 +408,8 @@ int b32e(const uint8_t* data, int length, char* result, int bufSize) noexcept
}
int count = 0;
if (length > 0) {
int buffer = data[0];
int next = 1;
int buffer = data[0];
int next = 1;
int bitsLeft = 8;
while (count < bufSize && (bitsLeft > 0 || next < length)) {
if (bitsLeft < 5) {
@ -437,12 +437,12 @@ int b32e(const uint8_t* data, int length, char* result, int bufSize) noexcept
return -1;
}
int b32d(const char* encoded, uint8_t* result, int bufSize) noexcept
int b32d(const char *encoded, uint8_t *result, int bufSize) noexcept
{
int buffer = 0;
int buffer = 0;
int bitsLeft = 0;
int count = 0;
for (const uint8_t* ptr = (const uint8_t*)encoded; count < bufSize && *ptr; ++ptr) {
int count = 0;
for (const uint8_t *ptr = (const uint8_t *)encoded; count < bufSize && *ptr; ++ptr) {
uint8_t ch = *ptr;
if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == '-' || ch == '.') {
continue;
@ -489,19 +489,19 @@ uint64_t random() noexcept
static volatile uint64_t s_s3 = getSecureRandomU64();
// https://en.wikipedia.org/wiki/Xorshift#xoshiro256**
uint64_t s0 = s_s0;
uint64_t s1 = s_s1;
uint64_t s2 = s_s2;
uint64_t s3 = s_s3;
const uint64_t s1x5 = s1 * 5ULL;
uint64_t s0 = s_s0;
uint64_t s1 = s_s1;
uint64_t s2 = s_s2;
uint64_t s3 = s_s3;
const uint64_t s1x5 = s1 * 5ULL;
const uint64_t result = ((s1x5 << 7U) | (s1x5 >> 57U)) * 9ULL;
const uint64_t t = s1 << 17U;
const uint64_t t = s1 << 17U;
s2 ^= s0;
s3 ^= s1;
s1 ^= s2;
s0 ^= s3;
s2 ^= t;
s3 = ((s3 << 45U) | (s3 >> 19U));
s3 = ((s3 << 45U) | (s3 >> 19U));
s_s0 = s0;
s_s1 = s1;
s_s2 = s2;
@ -510,7 +510,7 @@ uint64_t random() noexcept
return result;
}
bool scopy(char* const dest, const unsigned int len, const char* const src) noexcept
bool scopy(char *const dest, const unsigned int len, const char *const src) noexcept
{
if (unlikely((len == 0) || (dest == nullptr))) {
return false;
@ -532,12 +532,12 @@ bool scopy(char* const dest, const unsigned int len, const char* const src) noex
}
}
uint32_t fnv1a32(const void* const restrict data, const unsigned int len) noexcept
uint32_t fnv1a32(const void *const restrict data, const unsigned int len) noexcept
{
uint32_t h = 0x811c9dc5;
uint32_t h = 0x811c9dc5;
const uint32_t p = 0x01000193;
for (unsigned int i = 0; i < len; ++i)
h = (h ^ (uint32_t) reinterpret_cast<const uint8_t*>(data)[i]) * p;
h = (h ^ (uint32_t) reinterpret_cast<const uint8_t *>(data)[i]) * p;
return h;
}

View file

@ -36,9 +36,11 @@ namespace Utils {
// Macros to convert endian-ness at compile time for constants.
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define ZT_CONST_TO_BE_UINT16(x) ((uint16_t)((uint16_t)((uint16_t)(x) << 8U) | (uint16_t)((uint16_t)(x) >> 8U)))
#define ZT_CONST_TO_BE_UINT64(x) \
((((uint64_t)(x)&0x00000000000000ffULL) << 56U) | (((uint64_t)(x)&0x000000000000ff00ULL) << 40U) | (((uint64_t)(x)&0x0000000000ff0000ULL) << 24U) | (((uint64_t)(x)&0x00000000ff000000ULL) << 8U) \
| (((uint64_t)(x)&0x000000ff00000000ULL) >> 8U) | (((uint64_t)(x)&0x0000ff0000000000ULL) >> 24U) | (((uint64_t)(x)&0x00ff000000000000ULL) >> 40U) | (((uint64_t)(x)&0xff00000000000000ULL) >> 56U))
#define ZT_CONST_TO_BE_UINT64(x) \
((((uint64_t)(x)&0x00000000000000ffULL) << 56U) | (((uint64_t)(x)&0x000000000000ff00ULL) << 40U) \
| (((uint64_t)(x)&0x0000000000ff0000ULL) << 24U) | (((uint64_t)(x)&0x00000000ff000000ULL) << 8U) \
| (((uint64_t)(x)&0x000000ff00000000ULL) >> 8U) | (((uint64_t)(x)&0x0000ff0000000000ULL) >> 24U) \
| (((uint64_t)(x)&0x00ff000000000000ULL) >> 40U) | (((uint64_t)(x)&0xff00000000000000ULL) >> 56U))
#else
#define ZT_CONST_TO_BE_UINT16(x) ((uint16_t)(x))
#define ZT_CONST_TO_BE_UINT64(x) ((uint64_t)(x))
@ -91,7 +93,7 @@ extern const uint64_t s_mapNonce;
* @param len Length of strings
* @return True if strings are equal
*/
bool secureEq(const void* a, const void* b, unsigned int len) noexcept;
bool secureEq(const void *a, const void *b, unsigned int len) noexcept;
/**
* Be absolutely sure to zero memory
@ -102,14 +104,14 @@ bool secureEq(const void* a, const void* b, unsigned int len) noexcept;
* @param ptr Memory to zero
* @param len Length of memory in bytes
*/
void burn(volatile void* ptr, unsigned int len);
void burn(volatile void *ptr, unsigned int len);
/**
* @param n Number to convert
* @param s Buffer, at least 24 bytes in size
* @return String containing 'n' in base 10 form
*/
char* decimal(unsigned long n, char s[24]) noexcept;
char *decimal(unsigned long n, char s[24]) noexcept;
/**
* Convert an unsigned integer into hex
@ -118,7 +120,7 @@ char* decimal(unsigned long n, char s[24]) noexcept;
* @param s Buffer to receive hex, must be at least (2*sizeof(i))+1 in size or overflow will occur.
* @return Pointer to s containing hex string with trailing zero byte
*/
char* hex(uint64_t i, char buf[17]) noexcept;
char *hex(uint64_t i, char buf[17]) noexcept;
/**
* Decode an unsigned integer in hex format
@ -126,7 +128,7 @@ char* hex(uint64_t i, char buf[17]) noexcept;
* @param s String to decode, non-hex chars are ignored
* @return Unsigned integer
*/
uint64_t unhex(const char* s) noexcept;
uint64_t unhex(const char *s) noexcept;
/**
* Convert a byte array into hex
@ -136,7 +138,7 @@ uint64_t unhex(const char* s) noexcept;
* @param s String buffer, must be at least (l*2)+1 in size or overflow will occur
* @return Pointer to filled string buffer
*/
char* hex(const void* d, unsigned int l, char* s) noexcept;
char *hex(const void *d, unsigned int l, char *s) noexcept;
/**
* Decode a hex string
@ -147,7 +149,7 @@ char* hex(const void* d, unsigned int l, char* s) noexcept;
* @param buflen Length of output buffer
* @return Number of written bytes
*/
unsigned int unhex(const char* h, unsigned int hlen, void* buf, unsigned int buflen) noexcept;
unsigned int unhex(const char *h, unsigned int hlen, void *buf, unsigned int buflen) noexcept;
/**
* Generate secure random bytes
@ -158,7 +160,7 @@ unsigned int unhex(const char* h, unsigned int hlen, void* buf, unsigned int buf
* @param buf Buffer to fill
* @param bytes Number of random bytes to generate
*/
void getSecureRandom(void* buf, unsigned int bytes) noexcept;
void getSecureRandom(void *buf, unsigned int bytes) noexcept;
/**
* @return Secure random 64-bit integer
@ -174,7 +176,7 @@ uint64_t getSecureRandomU64() noexcept;
* @param bufSize Size of result buffer
* @return Number of bytes written
*/
int b32e(const uint8_t* data, int length, char* result, int bufSize) noexcept;
int b32e(const uint8_t *data, int length, char *result, int bufSize) noexcept;
/**
* Decode base32 string
@ -184,7 +186,7 @@ int b32e(const uint8_t* data, int length, char* result, int bufSize) noexcept;
* @param bufSize Size of result buffer
* @return Number of bytes written or -1 on error
*/
int b32d(const char* encoded, uint8_t* result, int bufSize) noexcept;
int b32d(const char *encoded, uint8_t *result, int bufSize) noexcept;
/**
* Get a non-cryptographic random integer.
@ -206,15 +208,15 @@ uint64_t random() noexcept;
* @param src Source string (if NULL, dest will receive a zero-length string and true is returned)
* @return True on success, false on overflow (buffer will still be 0-terminated)
*/
bool scopy(char* dest, unsigned int len, const char* src) noexcept;
bool scopy(char *dest, unsigned int len, const char *src) noexcept;
/**
* Check if a buffer's contents are all zero
*/
static ZT_INLINE bool allZero(const void* const b, const unsigned int l) noexcept
static ZT_INLINE bool allZero(const void *const b, const unsigned int l) noexcept
{
for (unsigned int i = 0; i < l; ++i) {
if (reinterpret_cast<const uint8_t*>(b)[i] != 0)
if (reinterpret_cast<const uint8_t *>(b)[i] != 0)
return false;
}
return true;
@ -228,7 +230,7 @@ static ZT_INLINE bool allZero(const void* const b, const unsigned int l) noexcep
* @param saveptr Pointer to pointer where function can save state
* @return Next token or NULL if none
*/
static ZT_INLINE char* stok(char* str, const char* delim, char** saveptr) noexcept
static ZT_INLINE char *stok(char *str, const char *delim, char **saveptr) noexcept
{
#ifdef __WINDOWS__
return strtok_s(str, delim, saveptr);
@ -237,12 +239,9 @@ static ZT_INLINE char* stok(char* str, const char* delim, char** saveptr) noexce
#endif
}
static ZT_INLINE unsigned int strToUInt(const char* s) noexcept
{
return (unsigned int)strtoul(s, nullptr, 10);
}
static ZT_INLINE unsigned int strToUInt(const char *s) noexcept { return (unsigned int)strtoul(s, nullptr, 10); }
static ZT_INLINE unsigned long long hexStrToU64(const char* s) noexcept
static ZT_INLINE unsigned long long hexStrToU64(const char *s) noexcept
{
#ifdef __WINDOWS__
return (unsigned long long)_strtoui64(s, nullptr, 16);
@ -300,7 +299,8 @@ static ZT_INLINE uint64_t swapBytes(const uint64_t n) noexcept
return (uint64_t)_byteswap_uint64((unsigned __int64)n);
#else
return (
((n & 0x00000000000000ffULL) << 56) | ((n & 0x000000000000ff00ULL) << 40) | ((n & 0x0000000000ff0000ULL) << 24) | ((n & 0x00000000ff000000ULL) << 8) | ((n & 0x000000ff00000000ULL) >> 8) | ((n & 0x0000ff0000000000ULL) >> 24)
((n & 0x00000000000000ffULL) << 56) | ((n & 0x000000000000ff00ULL) << 40) | ((n & 0x0000000000ff0000ULL) << 24)
| ((n & 0x00000000ff000000ULL) << 8) | ((n & 0x000000ff00000000ULL) >> 8) | ((n & 0x0000ff0000000000ULL) >> 24)
| ((n & 0x00ff000000000000ULL) >> 40) | ((n & 0xff00000000000000ULL) >> 56));
#endif
#endif
@ -350,49 +350,34 @@ template <typename I, unsigned int S> class _swap_bytes_bysize;
template <typename I> class _swap_bytes_bysize<I, 1> {
public:
static ZT_INLINE I s(const I n) noexcept
{
return n;
}
static ZT_INLINE I s(const I n) noexcept { return n; }
};
template <typename I> class _swap_bytes_bysize<I, 2> {
public:
static ZT_INLINE I s(const I n) noexcept
{
return (I)swapBytes((uint16_t)n);
}
static ZT_INLINE I s(const I n) noexcept { return (I)swapBytes((uint16_t)n); }
};
template <typename I> class _swap_bytes_bysize<I, 4> {
public:
static ZT_INLINE I s(const I n) noexcept
{
return (I)swapBytes((uint32_t)n);
}
static ZT_INLINE I s(const I n) noexcept { return (I)swapBytes((uint32_t)n); }
};
template <typename I> class _swap_bytes_bysize<I, 8> {
public:
static ZT_INLINE I s(const I n) noexcept
{
return (I)swapBytes((uint64_t)n);
}
static ZT_INLINE I s(const I n) noexcept { return (I)swapBytes((uint64_t)n); }
};
template <typename I, unsigned int S> class _load_be_bysize;
template <typename I> class _load_be_bysize<I, 1> {
public:
static ZT_INLINE I l(const uint8_t* const p) noexcept
{
return p[0];
}
static ZT_INLINE I l(const uint8_t *const p) noexcept { return p[0]; }
};
template <typename I> class _load_be_bysize<I, 2> {
public:
static ZT_INLINE I l(const uint8_t* const p) noexcept
static ZT_INLINE I l(const uint8_t *const p) noexcept
{
return (I)(((unsigned int)p[0] << 8U) | (unsigned int)p[1]);
}
@ -400,7 +385,7 @@ template <typename I> class _load_be_bysize<I, 2> {
template <typename I> class _load_be_bysize<I, 4> {
public:
static ZT_INLINE I l(const uint8_t* const p) noexcept
static ZT_INLINE I l(const uint8_t *const p) noexcept
{
return (I)(((uint32_t)p[0] << 24U) | ((uint32_t)p[1] << 16U) | ((uint32_t)p[2] << 8U) | (uint32_t)p[3]);
}
@ -408,9 +393,10 @@ template <typename I> class _load_be_bysize<I, 4> {
template <typename I> class _load_be_bysize<I, 8> {
public:
static ZT_INLINE I l(const uint8_t* const p) noexcept
static ZT_INLINE I l(const uint8_t *const p) noexcept
{
return (I)(((uint64_t)p[0] << 56U) | ((uint64_t)p[1] << 48U) | ((uint64_t)p[2] << 40U) | ((uint64_t)p[3] << 32U) | ((uint64_t)p[4] << 24U) | ((uint64_t)p[5] << 16U) | ((uint64_t)p[6] << 8U) | (uint64_t)p[7]);
return (
I)(((uint64_t)p[0] << 56U) | ((uint64_t)p[1] << 48U) | ((uint64_t)p[2] << 40U) | ((uint64_t)p[3] << 32U) | ((uint64_t)p[4] << 24U) | ((uint64_t)p[5] << 16U) | ((uint64_t)p[6] << 8U) | (uint64_t)p[7]);
}
};
@ -418,15 +404,12 @@ template <typename I, unsigned int S> class _load_le_bysize;
template <typename I> class _load_le_bysize<I, 1> {
public:
static ZT_INLINE I l(const uint8_t* const p) noexcept
{
return p[0];
}
static ZT_INLINE I l(const uint8_t *const p) noexcept { return p[0]; }
};
template <typename I> class _load_le_bysize<I, 2> {
public:
static ZT_INLINE I l(const uint8_t* const p) noexcept
static ZT_INLINE I l(const uint8_t *const p) noexcept
{
return (I)((unsigned int)p[0] | ((unsigned int)p[1] << 8U));
}
@ -434,7 +417,7 @@ template <typename I> class _load_le_bysize<I, 2> {
template <typename I> class _load_le_bysize<I, 4> {
public:
static ZT_INLINE I l(const uint8_t* const p) noexcept
static ZT_INLINE I l(const uint8_t *const p) noexcept
{
return (I)((uint32_t)p[0] | ((uint32_t)p[1] << 8U) | ((uint32_t)p[2] << 16U) | ((uint32_t)p[3] << 24U));
}
@ -442,9 +425,10 @@ template <typename I> class _load_le_bysize<I, 4> {
template <typename I> class _load_le_bysize<I, 8> {
public:
static ZT_INLINE I l(const uint8_t* const p) noexcept
static ZT_INLINE I l(const uint8_t *const p) noexcept
{
return (I)((uint64_t)p[0] | ((uint64_t)p[1] << 8U) | ((uint64_t)p[2] << 16U) | ((uint64_t)p[3] << 24U) | ((uint64_t)p[4] << 32U) | ((uint64_t)p[5] << 40U) | ((uint64_t)p[6] << 48U) | ((uint64_t)p[7]) << 56U);
return (
I)((uint64_t)p[0] | ((uint64_t)p[1] << 8U) | ((uint64_t)p[2] << 16U) | ((uint64_t)p[3] << 24U) | ((uint64_t)p[4] << 32U) | ((uint64_t)p[5] << 40U) | ((uint64_t)p[6] << 48U) | ((uint64_t)p[7]) << 56U);
}
};
@ -487,15 +471,15 @@ template <typename I> static ZT_INLINE I ntoh(const I n) noexcept
* @param p Byte stream, must be at least sizeof(I) in size
* @return Loaded raw integer
*/
template <typename I> static ZT_INLINE I loadMachineEndian(const void* const restrict p) noexcept
template <typename I> static ZT_INLINE I loadMachineEndian(const void *const restrict p) noexcept
{
#ifdef ZT_NO_UNALIGNED_ACCESS
I tmp;
for (int i = 0; i < (int)sizeof(I); ++i)
reinterpret_cast<uint8_t*>(&tmp)[i] = reinterpret_cast<const uint8_t*>(p)[i];
reinterpret_cast<uint8_t *>(&tmp)[i] = reinterpret_cast<const uint8_t *>(p)[i];
return tmp;
#else
return *reinterpret_cast<const I*>(p);
return *reinterpret_cast<const I *>(p);
#endif
}
@ -506,13 +490,13 @@ template <typename I> static ZT_INLINE I loadMachineEndian(const void* const res
* @param p Byte array (must be at least sizeof(I))
* @param i Integer to store
*/
template <typename I> static ZT_INLINE void storeMachineEndian(void* const restrict p, const I i) noexcept
template <typename I> static ZT_INLINE void storeMachineEndian(void *const restrict p, const I i) noexcept
{
#ifdef ZT_NO_UNALIGNED_ACCESS
for (unsigned int k = 0; k < sizeof(I); ++k)
reinterpret_cast<uint8_t*>(p)[k] = reinterpret_cast<const uint8_t*>(&i)[k];
reinterpret_cast<uint8_t *>(p)[k] = reinterpret_cast<const uint8_t *>(&i)[k];
#else
*reinterpret_cast<I*>(p) = i;
*reinterpret_cast<I *>(p) = i;
#endif
}
@ -523,12 +507,12 @@ template <typename I> static ZT_INLINE void storeMachineEndian(void* const restr
* @param p Byte stream, must be at least sizeof(I) in size
* @return Decoded integer
*/
template <typename I> static ZT_INLINE I loadBigEndian(const void* const restrict p) noexcept
template <typename I> static ZT_INLINE I loadBigEndian(const void *const restrict p) noexcept
{
#ifdef ZT_NO_UNALIGNED_ACCESS
return _load_be_bysize<I, sizeof(I)>::l(reinterpret_cast<const uint8_t*>(p));
return _load_be_bysize<I, sizeof(I)>::l(reinterpret_cast<const uint8_t *>(p));
#else
return ntoh(*reinterpret_cast<const I*>(p));
return ntoh(*reinterpret_cast<const I *>(p));
#endif
}
@ -539,12 +523,12 @@ template <typename I> static ZT_INLINE I loadBigEndian(const void* const restric
* @param p Byte stream to write (must be at least sizeof(I))
* #param i Integer to write
*/
template <typename I> static ZT_INLINE void storeBigEndian(void* const restrict p, I i) noexcept
template <typename I> static ZT_INLINE void storeBigEndian(void *const restrict p, I i) noexcept
{
#ifdef ZT_NO_UNALIGNED_ACCESS
storeMachineEndian(p, hton(i));
#else
*reinterpret_cast<I*>(p) = hton(i);
*reinterpret_cast<I *>(p) = hton(i);
#endif
}
@ -555,12 +539,12 @@ template <typename I> static ZT_INLINE void storeBigEndian(void* const restrict
* @param p Byte stream, must be at least sizeof(I) in size
* @return Decoded integer
*/
template <typename I> static ZT_INLINE I loadLittleEndian(const void* const restrict p) noexcept
template <typename I> static ZT_INLINE I loadLittleEndian(const void *const restrict p) noexcept
{
#if __BYTE_ORDER == __BIG_ENDIAN || defined(ZT_NO_UNALIGNED_ACCESS)
return _load_le_bysize<I, sizeof(I)>::l(reinterpret_cast<const uint8_t*>(p));
return _load_le_bysize<I, sizeof(I)>::l(reinterpret_cast<const uint8_t *>(p));
#else
return *reinterpret_cast<const I*>(p);
return *reinterpret_cast<const I *>(p);
#endif
}
@ -571,7 +555,7 @@ template <typename I> static ZT_INLINE I loadLittleEndian(const void* const rest
* @param p Byte stream to write (must be at least sizeof(I))
* #param i Integer to write
*/
template <typename I> static ZT_INLINE void storeLittleEndian(void* const restrict p, const I i) noexcept
template <typename I> static ZT_INLINE void storeLittleEndian(void *const restrict p, const I i) noexcept
{
#if __BYTE_ORDER == __BIG_ENDIAN
storeMachineEndian(p, _swap_bytes_bysize<I, sizeof(I)>::s(i));
@ -579,7 +563,7 @@ template <typename I> static ZT_INLINE void storeLittleEndian(void* const restri
#ifdef ZT_NO_UNALIGNED_ACCESS
storeMachineEndian(p, i);
#else
*reinterpret_cast<I*>(p) = i;
*reinterpret_cast<I *>(p) = i;
#endif
#endif
}
@ -591,7 +575,7 @@ template <typename I> static ZT_INLINE void storeLittleEndian(void* const restri
* @param dest Destination memory
* @param src Source memory
*/
template <unsigned long L> static ZT_INLINE void copy(void* dest, const void* src) noexcept
template <unsigned long L> static ZT_INLINE void copy(void *dest, const void *src) noexcept
{
#if defined(ZT_ARCH_X64) && defined(__GNUC__)
uintptr_t l = L;
@ -608,7 +592,7 @@ template <unsigned long L> static ZT_INLINE void copy(void* dest, const void* sr
* @param src Source memory
* @param len Bytes to copy
*/
static ZT_INLINE void copy(void* dest, const void* src, unsigned long len) noexcept
static ZT_INLINE void copy(void *dest, const void *src, unsigned long len) noexcept
{
#if defined(ZT_ARCH_X64) && defined(__GNUC__)
__asm__ __volatile__("cld ; rep movsb" : "+c"(len), "+S"(src), "+D"(dest)::"memory");
@ -623,7 +607,7 @@ static ZT_INLINE void copy(void* dest, const void* src, unsigned long len) noexc
* @tparam L Size in bytes
* @param dest Memory to zero
*/
template <unsigned long L> static ZT_INLINE void zero(void* dest) noexcept
template <unsigned long L> static ZT_INLINE void zero(void *dest) noexcept
{
#if defined(ZT_ARCH_X64) && defined(__GNUC__)
uintptr_t l = L;
@ -639,7 +623,7 @@ template <unsigned long L> static ZT_INLINE void zero(void* dest) noexcept
* @param dest Memory to zero
* @param len Size in bytes
*/
static ZT_INLINE void zero(void* dest, unsigned long len) noexcept
static ZT_INLINE void zero(void *dest, unsigned long len) noexcept
{
#if defined(ZT_ARCH_X64) && defined(__GNUC__)
__asm__ __volatile__("cld ; rep stosb" : "+c"(len), "+D"(dest) : "a"(0) : "memory");
@ -654,7 +638,7 @@ static ZT_INLINE void zero(void* dest, unsigned long len) noexcept
* @tparam L Size in bytes
* @param dest Memory to zero
*/
template <unsigned long L, uint8_t B> static ZT_INLINE void fill(void* dest) noexcept
template <unsigned long L, uint8_t B> static ZT_INLINE void fill(void *dest) noexcept
{
#if defined(ZT_ARCH_X64) && defined(__GNUC__)
uintptr_t l = L;
@ -670,7 +654,7 @@ template <unsigned long L, uint8_t B> static ZT_INLINE void fill(void* dest) noe
* @param dest Memory to zero
* @param len Size in bytes
*/
template <uint8_t B> static ZT_INLINE void fill(void* dest, unsigned long len) noexcept
template <uint8_t B> static ZT_INLINE void fill(void *dest, unsigned long len) noexcept
{
#if defined(ZT_ARCH_X64) && defined(__GNUC__)
__asm__ __volatile__("cld ; rep stosb" : "+c"(len), "+D"(dest) : "a"(B) : "memory");
@ -688,7 +672,7 @@ template <uint8_t B> static ZT_INLINE void fill(void* dest, unsigned long len) n
* @param len Length of data
* @return FNV1a checksum
*/
uint32_t fnv1a32(const void* restrict data, unsigned int len) noexcept;
uint32_t fnv1a32(const void *restrict data, unsigned int len) noexcept;
/**
* Mix bits in a 64-bit integer (non-cryptographic, for hash tables)

View file

@ -31,31 +31,31 @@ namespace ZeroTier {
namespace {
ZT_INLINE const Identity& identityFromPeerPtr(const SharedPtr<Peer>& p)
{
return (p) ? p->identity() : Identity::NIL;
}
ZT_INLINE const Identity &identityFromPeerPtr(const SharedPtr<Peer> &p) { return (p) ? p->identity() : Identity::NIL; }
struct p_SalsaPolyCopyFunction {
Salsa20 s20;
Poly1305 poly1305;
unsigned int hdrRemaining;
ZT_INLINE p_SalsaPolyCopyFunction(const void* salsaKey, const void* salsaIv) : s20(salsaKey, salsaIv), poly1305(), hdrRemaining(ZT_PROTO_PACKET_ENCRYPTED_SECTION_START)
ZT_INLINE p_SalsaPolyCopyFunction(const void *salsaKey, const void *salsaIv)
: s20(salsaKey, salsaIv)
, poly1305()
, hdrRemaining(ZT_PROTO_PACKET_ENCRYPTED_SECTION_START)
{
uint8_t macKey[ZT_POLY1305_KEY_SIZE];
s20.crypt12(Utils::ZERO256, macKey, ZT_POLY1305_KEY_SIZE);
poly1305.init(macKey);
}
ZT_INLINE void operator()(void* dest, const void* src, unsigned int len) noexcept
ZT_INLINE void operator()(void *dest, const void *src, unsigned int len) noexcept
{
if (hdrRemaining != 0) {
unsigned int hdrBytes = (len > hdrRemaining) ? hdrRemaining : len;
Utils::copy(dest, src, hdrBytes);
hdrRemaining -= hdrBytes;
dest = reinterpret_cast<uint8_t*>(dest) + hdrBytes;
src = reinterpret_cast<const uint8_t*>(src) + hdrBytes;
dest = reinterpret_cast<uint8_t *>(dest) + hdrBytes;
src = reinterpret_cast<const uint8_t *>(src) + hdrBytes;
len -= hdrBytes;
}
poly1305.update(src, len);
@ -67,21 +67,23 @@ struct p_PolyCopyFunction {
Poly1305 poly1305;
unsigned int hdrRemaining;
ZT_INLINE p_PolyCopyFunction(const void* salsaKey, const void* salsaIv) : poly1305(), hdrRemaining(ZT_PROTO_PACKET_ENCRYPTED_SECTION_START)
ZT_INLINE p_PolyCopyFunction(const void *salsaKey, const void *salsaIv)
: poly1305()
, hdrRemaining(ZT_PROTO_PACKET_ENCRYPTED_SECTION_START)
{
uint8_t macKey[ZT_POLY1305_KEY_SIZE];
Salsa20(salsaKey, salsaIv).crypt12(Utils::ZERO256, macKey, ZT_POLY1305_KEY_SIZE);
poly1305.init(macKey);
}
ZT_INLINE void operator()(void* dest, const void* src, unsigned int len) noexcept
ZT_INLINE void operator()(void *dest, const void *src, unsigned int len) noexcept
{
if (hdrRemaining != 0) {
unsigned int hdrBytes = (len > hdrRemaining) ? hdrRemaining : len;
Utils::copy(dest, src, hdrBytes);
hdrRemaining -= hdrBytes;
dest = reinterpret_cast<uint8_t*>(dest) + hdrBytes;
src = reinterpret_cast<const uint8_t*>(src) + hdrBytes;
dest = reinterpret_cast<uint8_t *>(dest) + hdrBytes;
src = reinterpret_cast<const uint8_t *>(src) + hdrBytes;
len -= hdrBytes;
}
poly1305.update(src, len);
@ -91,11 +93,11 @@ struct p_PolyCopyFunction {
} // anonymous namespace
VL1::VL1(const Context& ctx) : m_ctx(ctx)
{
}
VL1::VL1(const Context &ctx) : m_ctx(ctx) {}
void VL1::onRemotePacket(CallContext& cc, const int64_t localSocket, const InetAddress& fromAddr, SharedPtr<Buf>& data, const unsigned int len) noexcept
void VL1::onRemotePacket(
CallContext &cc, const int64_t localSocket, const InetAddress &fromAddr, SharedPtr<Buf> &data,
const unsigned int len) noexcept
{
const SharedPtr<Path> path(m_ctx.topology->path(localSocket, fromAddr));
@ -113,7 +115,8 @@ void VL1::onRemotePacket(CallContext& cc, const int64_t localSocket, const InetA
static_assert((ZT_PROTO_PACKET_ID_INDEX + sizeof(uint64_t)) < ZT_PROTO_MIN_FRAGMENT_LENGTH, "overflow");
const uint64_t packetId = Utils::loadMachineEndian<uint64_t>(data->unsafeData + ZT_PROTO_PACKET_ID_INDEX);
static_assert((ZT_PROTO_PACKET_DESTINATION_INDEX + ZT_ADDRESS_LENGTH) < ZT_PROTO_MIN_FRAGMENT_LENGTH, "overflow");
static_assert(
(ZT_PROTO_PACKET_DESTINATION_INDEX + ZT_ADDRESS_LENGTH) < ZT_PROTO_MIN_FRAGMENT_LENGTH, "overflow");
const Address destination(data->unsafeData + ZT_PROTO_PACKET_DESTINATION_INDEX);
if (destination != m_ctx.identity.address()) {
m_relay(cc, path, destination, data, len);
@ -131,10 +134,11 @@ void VL1::onRemotePacket(CallContext& cc, const int64_t localSocket, const InetA
// This looks like a fragment (excluding the head) of a larger packet.
static_assert(ZT_PROTO_PACKET_FRAGMENT_COUNTS < ZT_PROTO_MIN_FRAGMENT_LENGTH, "overflow");
const unsigned int totalFragments = (data->unsafeData[ZT_PROTO_PACKET_FRAGMENT_COUNTS] >> 4U) & 0x0fU;
const unsigned int fragmentNo = data->unsafeData[ZT_PROTO_PACKET_FRAGMENT_COUNTS] & 0x0fU;
switch (m_inputPacketAssembler.assemble(packetId, pktv, data, ZT_PROTO_PACKET_FRAGMENT_PAYLOAD_START_AT, len - ZT_PROTO_PACKET_FRAGMENT_PAYLOAD_START_AT, fragmentNo, totalFragments, cc.ticks, path)) {
case Defragmenter<ZT_MAX_PACKET_FRAGMENTS>::COMPLETE:
break;
const unsigned int fragmentNo = data->unsafeData[ZT_PROTO_PACKET_FRAGMENT_COUNTS] & 0x0fU;
switch (m_inputPacketAssembler.assemble(
packetId, pktv, data, ZT_PROTO_PACKET_FRAGMENT_PAYLOAD_START_AT,
len - ZT_PROTO_PACKET_FRAGMENT_PAYLOAD_START_AT, fragmentNo, totalFragments, cc.ticks, path)) {
case Defragmenter<ZT_MAX_PACKET_FRAGMENTS>::COMPLETE: break;
default:
// case Defragmenter<ZT_MAX_PACKET_FRAGMENTS>::OK:
// case Defragmenter<ZT_MAX_PACKET_FRAGMENTS>::ERR_DUPLICATE_FRAGMENT:
@ -151,17 +155,13 @@ void VL1::onRemotePacket(CallContext& cc, const int64_t localSocket, const InetA
if ((data->unsafeData[ZT_PROTO_PACKET_FLAGS_INDEX] & ZT_PROTO_FLAG_FRAGMENTED) != 0) {
// This is the head of a series of fragments that we may or may not already have.
switch (m_inputPacketAssembler.assemble(
packetId,
pktv,
data,
packetId, pktv, data,
0, // fragment index is 0 since this is the head
len,
0, // always the zero'eth fragment
0, // this is specified in fragments, not in the head
cc.ticks,
path)) {
case Defragmenter<ZT_MAX_PACKET_FRAGMENTS>::COMPLETE:
break;
cc.ticks, path)) {
case Defragmenter<ZT_MAX_PACKET_FRAGMENTS>::COMPLETE: break;
default:
// case Defragmenter<ZT_MAX_PACKET_FRAGMENTS>::OK:
// case Defragmenter<ZT_MAX_PACKET_FRAGMENTS>::ERR_DUPLICATE_FRAGMENT:
@ -184,27 +184,33 @@ void VL1::onRemotePacket(CallContext& cc, const int64_t localSocket, const InetA
// If we made it this far without returning, a packet is fully assembled and ready to process.
// ----------------------------------------------------------------------------------------------------------------
const uint8_t* const hdr = pktv[0].b->unsafeData + pktv[0].s;
const uint8_t *const hdr = pktv[0].b->unsafeData + pktv[0].s;
static_assert((ZT_PROTO_PACKET_SOURCE_INDEX + ZT_ADDRESS_LENGTH) < ZT_PROTO_MIN_PACKET_LENGTH, "overflow");
const Address source(hdr + ZT_PROTO_PACKET_SOURCE_INDEX);
static_assert(ZT_PROTO_PACKET_FLAGS_INDEX < ZT_PROTO_MIN_PACKET_LENGTH, "overflow");
const uint8_t hops = hdr[ZT_PROTO_PACKET_FLAGS_INDEX] & ZT_PROTO_FLAG_FIELD_HOPS_MASK;
const uint8_t hops = hdr[ZT_PROTO_PACKET_FLAGS_INDEX] & ZT_PROTO_FLAG_FIELD_HOPS_MASK;
const uint8_t cipher = (hdr[ZT_PROTO_PACKET_FLAGS_INDEX] >> 3U) & 3U;
SharedPtr<Buf> pkt(new Buf());
int pktSize = 0;
static_assert(ZT_PROTO_PACKET_VERB_INDEX < ZT_PROTO_MIN_PACKET_LENGTH, "overflow");
if (unlikely(((cipher == ZT_PROTO_CIPHER_POLY1305_NONE) || (cipher == ZT_PROTO_CIPHER_NONE)) && ((hdr[ZT_PROTO_PACKET_VERB_INDEX] & ZT_PROTO_VERB_MASK) == Protocol::VERB_HELLO))) {
if (unlikely(
((cipher == ZT_PROTO_CIPHER_POLY1305_NONE) || (cipher == ZT_PROTO_CIPHER_NONE))
&& ((hdr[ZT_PROTO_PACKET_VERB_INDEX] & ZT_PROTO_VERB_MASK) == Protocol::VERB_HELLO))) {
// Handle unencrypted HELLO packets.
pktSize = pktv.mergeCopy(*pkt);
if (unlikely(pktSize < ZT_PROTO_MIN_PACKET_LENGTH)) {
ZT_SPEW("discarding packet %.16llx from %s(%s): assembled packet size: %d", packetId, source.toString().c_str(), fromAddr.toString().c_str(), pktSize);
ZT_SPEW(
"discarding packet %.16llx from %s(%s): assembled packet size: %d", packetId,
source.toString().c_str(), fromAddr.toString().c_str(), pktSize);
return;
}
const SharedPtr<Peer> peer(m_HELLO(cc, path, *pkt, pktSize));
if (likely(peer))
peer->received(m_ctx, cc, path, hops, packetId, pktSize - ZT_PROTO_PACKET_PAYLOAD_START, Protocol::VERB_HELLO, Protocol::VERB_NOP);
peer->received(
m_ctx, cc, path, hops, packetId, pktSize - ZT_PROTO_PACKET_PAYLOAD_START, Protocol::VERB_HELLO,
Protocol::VERB_NOP);
return;
}
@ -221,9 +227,11 @@ void VL1::onRemotePacket(CallContext& cc, const int64_t localSocket, const InetA
Protocol::salsa2012DeriveKey(peer->rawIdentityKey(), perPacketKey, *pktv[0].b, pktv.totalSize());
p_PolyCopyFunction s20cf(perPacketKey, &packetId);
pktSize = pktv.mergeMap<p_PolyCopyFunction&>(*pkt, ZT_PROTO_PACKET_ENCRYPTED_SECTION_START, s20cf);
pktSize = pktv.mergeMap<p_PolyCopyFunction &>(*pkt, ZT_PROTO_PACKET_ENCRYPTED_SECTION_START, s20cf);
if (unlikely(pktSize < ZT_PROTO_MIN_PACKET_LENGTH)) {
ZT_SPEW("discarding packet %.16llx from %s(%s): assembled packet size: %d", packetId, source.toString().c_str(), fromAddr.toString().c_str(), pktSize);
ZT_SPEW(
"discarding packet %.16llx from %s(%s): assembled packet size: %d", packetId,
source.toString().c_str(), fromAddr.toString().c_str(), pktSize);
return;
}
@ -231,8 +239,12 @@ void VL1::onRemotePacket(CallContext& cc, const int64_t localSocket, const InetA
s20cf.poly1305.finish(mac);
static_assert((ZT_PROTO_PACKET_MAC_INDEX + 8) < ZT_PROTO_MIN_PACKET_LENGTH, "overflow");
if (unlikely(Utils::loadMachineEndian<uint64_t>(hdr + ZT_PROTO_PACKET_MAC_INDEX) != mac[0])) {
ZT_SPEW("discarding packet %.16llx from %s(%s): packet MAC failed (none/poly1305)", packetId, source.toString().c_str(), fromAddr.toString().c_str());
m_ctx.t->incomingPacketDropped(cc, 0xcc89c812, packetId, 0, peer->identity(), path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
ZT_SPEW(
"discarding packet %.16llx from %s(%s): packet MAC failed (none/poly1305)", packetId,
source.toString().c_str(), fromAddr.toString().c_str());
m_ctx.t->incomingPacketDropped(
cc, 0xcc89c812, packetId, 0, peer->identity(), path->address(), hops, Protocol::VERB_NOP,
ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
return;
}
@ -244,9 +256,12 @@ void VL1::onRemotePacket(CallContext& cc, const int64_t localSocket, const InetA
Protocol::salsa2012DeriveKey(peer->rawIdentityKey(), perPacketKey, *pktv[0].b, pktv.totalSize());
p_SalsaPolyCopyFunction s20cf(perPacketKey, &packetId);
pktSize = pktv.mergeMap<p_SalsaPolyCopyFunction&>(*pkt, ZT_PROTO_PACKET_ENCRYPTED_SECTION_START, s20cf);
pktSize =
pktv.mergeMap<p_SalsaPolyCopyFunction &>(*pkt, ZT_PROTO_PACKET_ENCRYPTED_SECTION_START, s20cf);
if (unlikely(pktSize < ZT_PROTO_MIN_PACKET_LENGTH)) {
ZT_SPEW("discarding packet %.16llx from %s(%s): assembled packet size: %d", packetId, source.toString().c_str(), fromAddr.toString().c_str(), pktSize);
ZT_SPEW(
"discarding packet %.16llx from %s(%s): assembled packet size: %d", packetId,
source.toString().c_str(), fromAddr.toString().c_str(), pktSize);
return;
}
@ -254,8 +269,12 @@ void VL1::onRemotePacket(CallContext& cc, const int64_t localSocket, const InetA
s20cf.poly1305.finish(mac);
static_assert((ZT_PROTO_PACKET_MAC_INDEX + 8) < ZT_PROTO_MIN_PACKET_LENGTH, "overflow");
if (unlikely(Utils::loadMachineEndian<uint64_t>(hdr + ZT_PROTO_PACKET_MAC_INDEX) != mac[0])) {
ZT_SPEW("discarding packet %.16llx from %s(%s): packet MAC failed (salsa/poly1305)", packetId, source.toString().c_str(), fromAddr.toString().c_str());
m_ctx.t->incomingPacketDropped(cc, 0xcc89c812, packetId, 0, peer->identity(), path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
ZT_SPEW(
"discarding packet %.16llx from %s(%s): packet MAC failed (salsa/poly1305)", packetId,
source.toString().c_str(), fromAddr.toString().c_str());
m_ctx.t->incomingPacketDropped(
cc, 0xcc89c812, packetId, 0, peer->identity(), path->address(), hops, Protocol::VERB_NOP,
ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
return;
}
@ -271,7 +290,9 @@ void VL1::onRemotePacket(CallContext& cc, const int64_t localSocket, const InetA
} break;
default:
m_ctx.t->incomingPacketDropped(cc, 0x5b001099, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
m_ctx.t->incomingPacketDropped(
cc, 0x5b001099, packetId, 0, identityFromPeerPtr(peer), path->address(), hops,
Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
return;
}
}
@ -283,21 +304,20 @@ void VL1::onRemotePacket(CallContext& cc, const int64_t localSocket, const InetA
ZT_SPEW(
"discarding packet %.16llx from %s(%s): assembled packet size %d is smaller than minimum packet "
"length",
packetId,
source.toString().c_str(),
fromAddr.toString().c_str(),
pktSize);
packetId, source.toString().c_str(), fromAddr.toString().c_str(), pktSize);
return;
}
// TODO: should take instance ID into account here once that is fully implemented.
if (unlikely(peer->deduplicateIncomingPacket(packetId))) {
ZT_SPEW("discarding packet %.16llx from %s(%s): duplicate!", packetId, source.toString().c_str(), fromAddr.toString().c_str());
ZT_SPEW(
"discarding packet %.16llx from %s(%s): duplicate!", packetId, source.toString().c_str(),
fromAddr.toString().c_str());
return;
}
static_assert(ZT_PROTO_PACKET_VERB_INDEX < ZT_PROTO_MIN_PACKET_LENGTH, "overflow");
const uint8_t verbFlags = pkt->unsafeData[ZT_PROTO_PACKET_VERB_INDEX];
const uint8_t verbFlags = pkt->unsafeData[ZT_PROTO_PACKET_VERB_INDEX];
const Protocol::Verb verb = (Protocol::Verb)(verbFlags & ZT_PROTO_VERB_MASK);
// Decompress packet payload if compressed. For additional safety decompression is
@ -307,22 +327,27 @@ void VL1::onRemotePacket(CallContext& cc, const int64_t localSocket, const InetA
SharedPtr<Buf> dec(new Buf());
Utils::copy<ZT_PROTO_PACKET_PAYLOAD_START>(dec->unsafeData, pkt->unsafeData);
const int uncompressedLen = LZ4_decompress_safe(
reinterpret_cast<const char*>(pkt->unsafeData + ZT_PROTO_PACKET_PAYLOAD_START),
reinterpret_cast<char*>(dec->unsafeData + ZT_PROTO_PACKET_PAYLOAD_START),
pktSize - ZT_PROTO_PACKET_PAYLOAD_START,
ZT_BUF_MEM_SIZE - ZT_PROTO_PACKET_PAYLOAD_START);
if (likely((uncompressedLen >= 0) && (uncompressedLen <= (ZT_BUF_MEM_SIZE - ZT_PROTO_PACKET_PAYLOAD_START)))) {
reinterpret_cast<const char *>(pkt->unsafeData + ZT_PROTO_PACKET_PAYLOAD_START),
reinterpret_cast<char *>(dec->unsafeData + ZT_PROTO_PACKET_PAYLOAD_START),
pktSize - ZT_PROTO_PACKET_PAYLOAD_START, ZT_BUF_MEM_SIZE - ZT_PROTO_PACKET_PAYLOAD_START);
if (likely(
(uncompressedLen >= 0)
&& (uncompressedLen <= (ZT_BUF_MEM_SIZE - ZT_PROTO_PACKET_PAYLOAD_START)))) {
pkt.swap(dec);
ZT_SPEW("decompressed packet: %d -> %d", pktSize, ZT_PROTO_PACKET_PAYLOAD_START + uncompressedLen);
pktSize = ZT_PROTO_PACKET_PAYLOAD_START + uncompressedLen;
}
else {
m_ctx.t->incomingPacketDropped(cc, 0xee9e4392, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, verb, ZT_TRACE_PACKET_DROP_REASON_INVALID_COMPRESSED_DATA);
m_ctx.t->incomingPacketDropped(
cc, 0xee9e4392, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, verb,
ZT_TRACE_PACKET_DROP_REASON_INVALID_COMPRESSED_DATA);
return;
}
}
ZT_SPEW("%s from %s(%s) (%d bytes)", Protocol::verbName(verb), source.toString().c_str(), fromAddr.toString().c_str(), pktSize);
ZT_SPEW(
"%s from %s(%s) (%d bytes)", Protocol::verbName(verb), source.toString().c_str(),
fromAddr.toString().c_str(), pktSize);
// NOTE: HELLO is normally sent in the clear (in terms of our usual AEAD modes) and is handled
// above. We will try to process it here, but if so it'll still get re-authenticated via HELLO's
@ -330,34 +355,21 @@ void VL1::onRemotePacket(CallContext& cc, const int64_t localSocket, const InetA
// but not invalid.
Protocol::Verb inReVerb = Protocol::VERB_NOP;
bool ok = true;
bool ok = true;
switch (verb) {
case Protocol::VERB_NOP:
break;
case Protocol::VERB_HELLO:
ok = (bool)(m_HELLO(cc, path, *pkt, pktSize));
break;
case Protocol::VERB_ERROR:
ok = m_ERROR(cc, packetId, auth, path, peer, *pkt, pktSize, inReVerb);
break;
case Protocol::VERB_OK:
ok = m_OK(cc, packetId, auth, path, peer, *pkt, pktSize, inReVerb);
break;
case Protocol::VERB_WHOIS:
ok = m_WHOIS(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_RENDEZVOUS:
ok = m_RENDEZVOUS(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_NOP: break;
case Protocol::VERB_HELLO: ok = (bool)(m_HELLO(cc, path, *pkt, pktSize)); break;
case Protocol::VERB_ERROR: ok = m_ERROR(cc, packetId, auth, path, peer, *pkt, pktSize, inReVerb); break;
case Protocol::VERB_OK: ok = m_OK(cc, packetId, auth, path, peer, *pkt, pktSize, inReVerb); break;
case Protocol::VERB_WHOIS: ok = m_WHOIS(cc, packetId, auth, path, peer, *pkt, pktSize); break;
case Protocol::VERB_RENDEZVOUS: ok = m_RENDEZVOUS(cc, packetId, auth, path, peer, *pkt, pktSize); break;
case Protocol::VERB_FRAME:
ok = m_ctx.vl2->m_FRAME(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_EXT_FRAME:
ok = m_ctx.vl2->m_EXT_FRAME(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_ECHO:
ok = m_ECHO(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_ECHO: ok = m_ECHO(cc, packetId, auth, path, peer, *pkt, pktSize); break;
case Protocol::VERB_MULTICAST_LIKE:
ok = m_ctx.vl2->m_MULTICAST_LIKE(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
@ -385,16 +397,17 @@ void VL1::onRemotePacket(CallContext& cc, const int64_t localSocket, const InetA
case Protocol::VERB_MULTICAST:
ok = m_ctx.vl2->m_MULTICAST(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_ENCAP:
ok = m_ENCAP(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_ENCAP: ok = m_ENCAP(cc, packetId, auth, path, peer, *pkt, pktSize); break;
default:
m_ctx.t->incomingPacketDropped(cc, 0xeeeeeff0, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, verb, ZT_TRACE_PACKET_DROP_REASON_UNRECOGNIZED_VERB);
m_ctx.t->incomingPacketDropped(
cc, 0xeeeeeff0, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, verb,
ZT_TRACE_PACKET_DROP_REASON_UNRECOGNIZED_VERB);
break;
}
if (likely(ok))
peer->received(m_ctx, cc, path, hops, packetId, pktSize - ZT_PROTO_PACKET_PAYLOAD_START, verb, inReVerb);
peer->received(
m_ctx, cc, path, hops, packetId, pktSize - ZT_PROTO_PACKET_PAYLOAD_START, verb, inReVerb);
}
else {
// If decryption and authentication were not successful, try to look up identities.
@ -406,11 +419,11 @@ void VL1::onRemotePacket(CallContext& cc, const int64_t localSocket, const InetA
bool sendPending;
{
Mutex::Lock wl(m_whoisQueue_l);
p_WhoisQueueItem& wq = m_whoisQueue[source];
const unsigned int wpidx = wq.waitingPacketCount++ % ZT_VL1_MAX_WHOIS_WAITING_PACKETS;
p_WhoisQueueItem &wq = m_whoisQueue[source];
const unsigned int wpidx = wq.waitingPacketCount++ % ZT_VL1_MAX_WHOIS_WAITING_PACKETS;
wq.waitingPacketSize[wpidx] = (unsigned int)pktSize;
wq.waitingPacket[wpidx] = pkt;
sendPending = (cc.ticks - wq.lastRetry) >= ZT_WHOIS_RETRY_DELAY;
wq.waitingPacket[wpidx] = pkt;
sendPending = (cc.ticks - wq.lastRetry) >= ZT_WHOIS_RETRY_DELAY;
}
if (sendPending)
m_sendPendingWhois(cc);
@ -418,21 +431,23 @@ void VL1::onRemotePacket(CallContext& cc, const int64_t localSocket, const InetA
}
}
catch (...) {
m_ctx.t->unexpectedError(cc, 0xea1b6dea, "unexpected exception in onRemotePacket() parsing packet from %s", path->address().toString().c_str());
m_ctx.t->unexpectedError(
cc, 0xea1b6dea, "unexpected exception in onRemotePacket() parsing packet from %s",
path->address().toString().c_str());
}
}
void VL1::m_relay(CallContext& cc, const SharedPtr<Path>& path, Address destination, SharedPtr<Buf>& pkt, int pktSize)
void VL1::m_relay(CallContext &cc, const SharedPtr<Path> &path, Address destination, SharedPtr<Buf> &pkt, int pktSize)
{
}
void VL1::m_sendPendingWhois(CallContext& cc)
void VL1::m_sendPendingWhois(CallContext &cc)
{
const SharedPtr<Peer> root(m_ctx.topology->root());
if (unlikely(! root))
if (unlikely(!root))
return;
const SharedPtr<Path> rootPath(root->path(cc));
if (unlikely(! rootPath))
if (unlikely(!rootPath))
return;
Vector<Address> toSend;
@ -447,13 +462,14 @@ void VL1::m_sendPendingWhois(CallContext& cc)
}
}
if (! toSend.empty()) {
SymmetricKey& key = root->key();
if (!toSend.empty()) {
SymmetricKey &key = root->key();
uint8_t outp[ZT_DEFAULT_UDP_MTU - ZT_PROTO_MIN_PACKET_LENGTH];
Vector<Address>::iterator a(toSend.begin());
while (a != toSend.end()) {
const uint64_t packetId = key.nextMessage(m_ctx.identity.address(), root->address());
int p = Protocol::newPacket(outp, packetId, root->address(), m_ctx.identity.address(), Protocol::VERB_WHOIS);
int p =
Protocol::newPacket(outp, packetId, root->address(), m_ctx.identity.address(), Protocol::VERB_WHOIS);
while ((a != toSend.end()) && (p < (sizeof(outp) - ZT_ADDRESS_LENGTH))) {
a->copyTo(outp + p);
++a;
@ -465,32 +481,38 @@ void VL1::m_sendPendingWhois(CallContext& cc)
}
}
SharedPtr<Peer> VL1::m_HELLO(CallContext& cc, const SharedPtr<Path>& path, Buf& pkt, int packetSize)
SharedPtr<Peer> VL1::m_HELLO(CallContext &cc, const SharedPtr<Path> &path, Buf &pkt, int packetSize)
{
const uint64_t packetId = Utils::loadMachineEndian<uint64_t>(pkt.unsafeData + ZT_PROTO_PACKET_ID_INDEX);
const uint64_t mac = Utils::loadMachineEndian<uint64_t>(pkt.unsafeData + ZT_PROTO_PACKET_MAC_INDEX);
const uint8_t hops = pkt.unsafeData[ZT_PROTO_PACKET_FLAGS_INDEX] & ZT_PROTO_FLAG_FIELD_HOPS_MASK;
const uint64_t mac = Utils::loadMachineEndian<uint64_t>(pkt.unsafeData + ZT_PROTO_PACKET_MAC_INDEX);
const uint8_t hops = pkt.unsafeData[ZT_PROTO_PACKET_FLAGS_INDEX] & ZT_PROTO_FLAG_FIELD_HOPS_MASK;
const uint8_t protoVersion = pkt.lI8<ZT_PROTO_PACKET_PAYLOAD_START>();
if (unlikely(protoVersion < ZT_PROTO_VERSION_MIN)) {
m_ctx.t->incomingPacketDropped(cc, 0x907a9891, packetId, 0, Identity::NIL, path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_PEER_TOO_OLD);
m_ctx.t->incomingPacketDropped(
cc, 0x907a9891, packetId, 0, Identity::NIL, path->address(), hops, Protocol::VERB_HELLO,
ZT_TRACE_PACKET_DROP_REASON_PEER_TOO_OLD);
return SharedPtr<Peer>();
}
const unsigned int versionMajor = pkt.lI8<ZT_PROTO_PACKET_PAYLOAD_START + 1>();
const unsigned int versionMinor = pkt.lI8<ZT_PROTO_PACKET_PAYLOAD_START + 2>();
const unsigned int versionRev = pkt.lI16<ZT_PROTO_PACKET_PAYLOAD_START + 3>();
const uint64_t timestamp = pkt.lI64<ZT_PROTO_PACKET_PAYLOAD_START + 5>();
const unsigned int versionRev = pkt.lI16<ZT_PROTO_PACKET_PAYLOAD_START + 3>();
const uint64_t timestamp = pkt.lI64<ZT_PROTO_PACKET_PAYLOAD_START + 5>();
int ii = ZT_PROTO_PACKET_PAYLOAD_START + 13;
// Get identity and verify that it matches the sending address in the packet.
Identity id;
if (unlikely(pkt.rO(ii, id) < 0)) {
m_ctx.t->incomingPacketDropped(cc, 0x707a9810, packetId, 0, Identity::NIL, path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
m_ctx.t->incomingPacketDropped(
cc, 0x707a9810, packetId, 0, Identity::NIL, path->address(), hops, Protocol::VERB_HELLO,
ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
return SharedPtr<Peer>();
}
if (unlikely(id.address() != Address(pkt.unsafeData + ZT_PROTO_PACKET_SOURCE_INDEX))) {
m_ctx.t->incomingPacketDropped(cc, 0x707a9010, packetId, 0, Identity::NIL, path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
m_ctx.t->incomingPacketDropped(
cc, 0x707a9010, packetId, 0, Identity::NIL, path->address(), hops, Protocol::VERB_HELLO,
ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
return SharedPtr<Peer>();
}
@ -498,22 +520,30 @@ SharedPtr<Peer> VL1::m_HELLO(CallContext& cc, const SharedPtr<Path>& path, Buf&
SharedPtr<Peer> peer(m_ctx.topology->peer(cc, id.address(), true));
if (peer) {
if (unlikely(peer->identity() != id)) {
m_ctx.t->incomingPacketDropped(cc, 0x707a9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
m_ctx.t->incomingPacketDropped(
cc, 0x707a9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO,
ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
return SharedPtr<Peer>();
}
if (unlikely(peer->deduplicateIncomingPacket(packetId))) {
ZT_SPEW("discarding packet %.16llx from %s(%s): duplicate!", packetId, id.address().toString().c_str(), path->address().toString().c_str());
ZT_SPEW(
"discarding packet %.16llx from %s(%s): duplicate!", packetId, id.address().toString().c_str(),
path->address().toString().c_str());
return SharedPtr<Peer>();
}
}
else {
if (unlikely(! id.locallyValidate())) {
m_ctx.t->incomingPacketDropped(cc, 0x707a9892, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
if (unlikely(!id.locallyValidate())) {
m_ctx.t->incomingPacketDropped(
cc, 0x707a9892, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO,
ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
return SharedPtr<Peer>();
}
peer.set(new Peer());
if (unlikely(! peer->init(m_ctx, cc, id))) {
m_ctx.t->incomingPacketDropped(cc, 0x707a9893, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_UNSPECIFIED);
if (unlikely(!peer->init(m_ctx, cc, id))) {
m_ctx.t->incomingPacketDropped(
cc, 0x707a9893, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO,
ZT_TRACE_PACKET_DROP_REASON_UNSPECIFIED);
return SharedPtr<Peer>();
}
peer = m_ctx.topology->add(cc, peer);
@ -529,15 +559,19 @@ SharedPtr<Peer> VL1::m_HELLO(CallContext& cc, const SharedPtr<Path>& path, Buf&
// field is ignored, and eventually it'll be undefined.
uint8_t hmac[ZT_HMACSHA384_LEN];
if (unlikely(packetSize < ZT_HMACSHA384_LEN)) {
m_ctx.t->incomingPacketDropped(cc, 0xab9c9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
m_ctx.t->incomingPacketDropped(
cc, 0xab9c9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO,
ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
return SharedPtr<Peer>();
}
packetSize -= ZT_HMACSHA384_LEN;
pkt.unsafeData[ZT_PROTO_PACKET_FLAGS_INDEX] &= ~ZT_PROTO_FLAG_FIELD_HOPS_MASK; // mask hops to 0
Utils::storeMachineEndian<uint64_t>(pkt.unsafeData + ZT_PROTO_PACKET_MAC_INDEX, 0); // set MAC field to 0
HMACSHA384(peer->identityHelloHmacKey(), pkt.unsafeData, packetSize, hmac);
if (unlikely(! Utils::secureEq(hmac, pkt.unsafeData + packetSize, ZT_HMACSHA384_LEN))) {
m_ctx.t->incomingPacketDropped(cc, 0x707a9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
if (unlikely(!Utils::secureEq(hmac, pkt.unsafeData + packetSize, ZT_HMACSHA384_LEN))) {
m_ctx.t->incomingPacketDropped(
cc, 0x707a9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO,
ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
return SharedPtr<Peer>();
}
}
@ -549,16 +583,22 @@ SharedPtr<Peer> VL1::m_HELLO(CallContext& cc, const SharedPtr<Path>& path, Buf&
uint8_t macKey[ZT_POLY1305_KEY_SIZE];
Salsa20(perPacketKey, &packetId).crypt12(Utils::ZERO256, macKey, ZT_POLY1305_KEY_SIZE);
Poly1305 poly1305(macKey);
poly1305.update(pkt.unsafeData + ZT_PROTO_PACKET_ENCRYPTED_SECTION_START, packetSize - ZT_PROTO_PACKET_ENCRYPTED_SECTION_START);
poly1305.update(
pkt.unsafeData + ZT_PROTO_PACKET_ENCRYPTED_SECTION_START,
packetSize - ZT_PROTO_PACKET_ENCRYPTED_SECTION_START);
uint64_t polyMac[2];
poly1305.finish(polyMac);
if (unlikely(mac != polyMac[0])) {
m_ctx.t->incomingPacketDropped(cc, 0x11bfff82, packetId, 0, id, path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
m_ctx.t->incomingPacketDropped(
cc, 0x11bfff82, packetId, 0, id, path->address(), hops, Protocol::VERB_NOP,
ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
return SharedPtr<Peer>();
}
}
else {
m_ctx.t->incomingPacketDropped(cc, 0x11bfff81, packetId, 0, id, path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
m_ctx.t->incomingPacketDropped(
cc, 0x11bfff81, packetId, 0, id, path->address(), hops, Protocol::VERB_NOP,
ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
return SharedPtr<Peer>();
}
}
@ -569,18 +609,20 @@ SharedPtr<Peer> VL1::m_HELLO(CallContext& cc, const SharedPtr<Path>& path, Buf&
InetAddress sentTo;
if (unlikely(pkt.rO(ii, sentTo) < 0)) {
m_ctx.t->incomingPacketDropped(cc, 0x707a9811, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
m_ctx.t->incomingPacketDropped(
cc, 0x707a9811, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO,
ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
return SharedPtr<Peer>();
}
SymmetricKey& key = peer->key();
SymmetricKey &key = peer->key();
if (protoVersion >= 11) {
// V2.x and newer supports an encrypted section and has a new OK format.
ii += 4; // skip reserved field
if (likely((ii + 12) < packetSize)) {
AES::CTR ctr(peer->identityHelloDictionaryEncryptionCipher());
const uint8_t* const ctrNonce = pkt.unsafeData + ii;
const uint8_t *const ctrNonce = pkt.unsafeData + ii;
ii += 12;
ctr.init(ctrNonce, 0, pkt.unsafeData + ii);
ctr.crypt(pkt.unsafeData + ii, packetSize - ii);
@ -589,22 +631,28 @@ SharedPtr<Peer> VL1::m_HELLO(CallContext& cc, const SharedPtr<Path>& path, Buf&
ii += 2; // skip reserved field
const unsigned int dictSize = pkt.rI16(ii);
if (unlikely((ii + dictSize) > packetSize)) {
m_ctx.t->incomingPacketDropped(cc, 0x707a9815, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
m_ctx.t->incomingPacketDropped(
cc, 0x707a9815, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO,
ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
return peer;
}
Dictionary md;
if (! md.decode(pkt.unsafeData + ii, dictSize)) {
m_ctx.t->incomingPacketDropped(cc, 0x707a9816, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
if (!md.decode(pkt.unsafeData + ii, dictSize)) {
m_ctx.t->incomingPacketDropped(
cc, 0x707a9816, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO,
ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
return peer;
}
if (! md.empty()) {
if (!md.empty()) {
// TODO
}
}
}
Protocol::newPacket(pkt, key.nextMessage(m_ctx.identity.address(), peer->address()), peer->address(), m_ctx.identity.address(), Protocol::VERB_OK);
Protocol::newPacket(
pkt, key.nextMessage(m_ctx.identity.address(), peer->address()), peer->address(), m_ctx.identity.address(),
Protocol::VERB_OK);
ii = ZT_PROTO_PACKET_PAYLOAD_START;
pkt.wI8(ii, Protocol::VERB_HELLO);
pkt.wI64(ii, packetId);
@ -633,7 +681,9 @@ SharedPtr<Peer> VL1::m_HELLO(CallContext& cc, const SharedPtr<Path>& path, Buf&
return peer;
}
bool VL1::m_ERROR(CallContext& cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path>& path, const SharedPtr<Peer>& peer, Buf& pkt, int packetSize, Protocol::Verb& inReVerb)
bool VL1::m_ERROR(
CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path> &path,
const SharedPtr<Peer> &peer, Buf &pkt, int packetSize, Protocol::Verb &inReVerb)
{
#if 0
if (packetSize < (int)sizeof(Protocol::ERROR::Header)) {
@ -680,42 +730,48 @@ bool VL1::m_ERROR(CallContext& cc, const uint64_t packetId, const unsigned int a
#endif
}
bool VL1::m_OK(CallContext& cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path>& path, const SharedPtr<Peer>& peer, Buf& pkt, int packetSize, Protocol::Verb& inReVerb)
bool VL1::m_OK(
CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path> &path,
const SharedPtr<Peer> &peer, Buf &pkt, int packetSize, Protocol::Verb &inReVerb)
{
int ii = ZT_PROTO_PACKET_PAYLOAD_START + 13;
inReVerb = (Protocol::Verb)pkt.rI8(ii);
inReVerb = (Protocol::Verb)pkt.rI8(ii);
const uint64_t inRePacketId = pkt.rI64(ii);
if (unlikely(Buf::readOverflow(ii, packetSize))) {
m_ctx.t->incomingPacketDropped(cc, 0x4c1f1ff7, packetId, 0, identityFromPeerPtr(peer), path->address(), 0, Protocol::VERB_OK, ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET);
m_ctx.t->incomingPacketDropped(
cc, 0x4c1f1ff7, packetId, 0, identityFromPeerPtr(peer), path->address(), 0, Protocol::VERB_OK,
ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET);
return false;
}
if (unlikely(! m_ctx.expect->expecting(inRePacketId, cc.ticks))) {
m_ctx.t->incomingPacketDropped(cc, 0x4c1f1ff8, packetId, 0, identityFromPeerPtr(peer), path->address(), 0, Protocol::VERB_OK, ZT_TRACE_PACKET_DROP_REASON_REPLY_NOT_EXPECTED);
if (unlikely(!m_ctx.expect->expecting(inRePacketId, cc.ticks))) {
m_ctx.t->incomingPacketDropped(
cc, 0x4c1f1ff8, packetId, 0, identityFromPeerPtr(peer), path->address(), 0, Protocol::VERB_OK,
ZT_TRACE_PACKET_DROP_REASON_REPLY_NOT_EXPECTED);
return false;
}
ZT_SPEW("got OK in-re %s (packet ID %.16llx) from %s(%s)", Protocol::verbName(inReVerb), inRePacketId, peer->address().toString().c_str(), path->address().toString().c_str());
ZT_SPEW(
"got OK in-re %s (packet ID %.16llx) from %s(%s)", Protocol::verbName(inReVerb), inRePacketId,
peer->address().toString().c_str(), path->address().toString().c_str());
switch (inReVerb) {
case Protocol::VERB_HELLO:
break;
case Protocol::VERB_HELLO: break;
case Protocol::VERB_WHOIS:
break;
case Protocol::VERB_WHOIS: break;
case Protocol::VERB_NETWORK_CONFIG_REQUEST:
break;
case Protocol::VERB_NETWORK_CONFIG_REQUEST: break;
case Protocol::VERB_MULTICAST_GATHER:
break;
case Protocol::VERB_MULTICAST_GATHER: break;
}
return true;
}
bool VL1::m_WHOIS(CallContext& cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path>& path, const SharedPtr<Peer>& peer, Buf& pkt, int packetSize)
bool VL1::m_WHOIS(
CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path> &path,
const SharedPtr<Peer> &peer, Buf &pkt, int packetSize)
{
#if 0
if (packetSize < (int)sizeof(Protocol::OK::Header)) {
@ -769,7 +825,9 @@ bool VL1::m_WHOIS(CallContext& cc, const uint64_t packetId, const unsigned int a
#endif
}
bool VL1::m_RENDEZVOUS(CallContext& cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path>& path, const SharedPtr<Peer>& peer, Buf& pkt, int packetSize)
bool VL1::m_RENDEZVOUS(
CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path> &path,
const SharedPtr<Peer> &peer, Buf &pkt, int packetSize)
{
#if 0
if (RR->topology->isRoot(peer->identity())) {
@ -817,7 +875,9 @@ bool VL1::m_RENDEZVOUS(CallContext& cc, const uint64_t packetId, const unsigned
#endif
}
bool VL1::m_ECHO(CallContext& cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path>& path, const SharedPtr<Peer>& peer, Buf& pkt, int packetSize)
bool VL1::m_ECHO(
CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path> &path,
const SharedPtr<Peer> &peer, Buf &pkt, int packetSize)
{
#if 0
const uint64_t packetId = Protocol::packetId(pkt,packetSize);
@ -855,7 +915,9 @@ bool VL1::m_ECHO(CallContext& cc, const uint64_t packetId, const unsigned int au
#endif
}
bool VL1::m_PUSH_DIRECT_PATHS(CallContext& cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path>& path, const SharedPtr<Peer>& peer, Buf& pkt, int packetSize)
bool VL1::m_PUSH_DIRECT_PATHS(
CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path> &path,
const SharedPtr<Peer> &peer, Buf &pkt, int packetSize)
{
#if 0
if (packetSize < (int)sizeof(Protocol::PUSH_DIRECT_PATHS)) {
@ -946,13 +1008,17 @@ bool VL1::m_PUSH_DIRECT_PATHS(CallContext& cc, const uint64_t packetId, const un
#endif
}
bool VL1::m_USER_MESSAGE(CallContext& cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path>& path, const SharedPtr<Peer>& peer, Buf& pkt, int packetSize)
bool VL1::m_USER_MESSAGE(
CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path> &path,
const SharedPtr<Peer> &peer, Buf &pkt, int packetSize)
{
// TODO
return true;
}
bool VL1::m_ENCAP(CallContext& cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path>& path, const SharedPtr<Peer>& peer, Buf& pkt, int packetSize)
bool VL1::m_ENCAP(
CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path> &path,
const SharedPtr<Peer> &peer, Buf &pkt, int packetSize)
{
// TODO: not implemented yet
return true;

View file

@ -45,7 +45,7 @@ class VL2;
*/
class VL1 {
public:
explicit VL1(const Context& ctx);
explicit VL1(const Context &ctx);
/**
* Called when a packet is received from the real network
@ -61,31 +61,47 @@ class VL1 {
* @param data Packet data
* @param len Packet length
*/
void onRemotePacket(CallContext& cc, int64_t localSocket, const InetAddress& fromAddr, SharedPtr<Buf>& data, unsigned int len) noexcept;
void onRemotePacket(
CallContext &cc, int64_t localSocket, const InetAddress &fromAddr, SharedPtr<Buf> &data,
unsigned int len) noexcept;
private:
void m_relay(CallContext& cc, const SharedPtr<Path>& path, Address destination, SharedPtr<Buf>& pkt, int pktSize);
void m_sendPendingWhois(CallContext& cc);
SharedPtr<Peer> m_HELLO(CallContext& cc, const SharedPtr<Path>& path, Buf& pkt, int packetSize);
bool m_ERROR(CallContext& cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path>& path, const SharedPtr<Peer>& peer, Buf& pkt, int packetSize, Protocol::Verb& inReVerb);
bool m_OK(CallContext& cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path>& path, const SharedPtr<Peer>& peer, Buf& pkt, int packetSize, Protocol::Verb& inReVerb);
bool m_WHOIS(CallContext& cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path>& path, const SharedPtr<Peer>& peer, Buf& pkt, int packetSize);
bool m_RENDEZVOUS(CallContext& cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path>& path, const SharedPtr<Peer>& peer, Buf& pkt, int packetSize);
bool m_ECHO(CallContext& cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path>& path, const SharedPtr<Peer>& peer, Buf& pkt, int packetSize);
bool m_PUSH_DIRECT_PATHS(CallContext& cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path>& path, const SharedPtr<Peer>& peer, Buf& pkt, int packetSize);
bool m_USER_MESSAGE(CallContext& cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path>& path, const SharedPtr<Peer>& peer, Buf& pkt, int packetSize);
bool m_ENCAP(CallContext& cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path>& path, const SharedPtr<Peer>& peer, Buf& pkt, int packetSize);
void m_relay(CallContext &cc, const SharedPtr<Path> &path, Address destination, SharedPtr<Buf> &pkt, int pktSize);
void m_sendPendingWhois(CallContext &cc);
SharedPtr<Peer> m_HELLO(CallContext &cc, const SharedPtr<Path> &path, Buf &pkt, int packetSize);
bool m_ERROR(
CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path> &path, const SharedPtr<Peer> &peer,
Buf &pkt, int packetSize, Protocol::Verb &inReVerb);
bool m_OK(
CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path> &path, const SharedPtr<Peer> &peer,
Buf &pkt, int packetSize, Protocol::Verb &inReVerb);
bool m_WHOIS(
CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path> &path, const SharedPtr<Peer> &peer,
Buf &pkt, int packetSize);
bool m_RENDEZVOUS(
CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path> &path, const SharedPtr<Peer> &peer,
Buf &pkt, int packetSize);
bool m_ECHO(
CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path> &path, const SharedPtr<Peer> &peer,
Buf &pkt, int packetSize);
bool m_PUSH_DIRECT_PATHS(
CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path> &path, const SharedPtr<Peer> &peer,
Buf &pkt, int packetSize);
bool m_USER_MESSAGE(
CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path> &path, const SharedPtr<Peer> &peer,
Buf &pkt, int packetSize);
bool m_ENCAP(
CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path> &path, const SharedPtr<Peer> &peer,
Buf &pkt, int packetSize);
const Context& m_ctx;
const Context &m_ctx;
// Defragmentation engine for handling inbound packets with more than one fragment.
Defragmenter<ZT_MAX_PACKET_FRAGMENTS> m_inputPacketAssembler;
// Queue of outbound WHOIS reqeusts and packets waiting on them.
struct p_WhoisQueueItem {
ZT_INLINE p_WhoisQueueItem() : lastRetry(0), retries(0), waitingPacketCount(0)
{
}
ZT_INLINE p_WhoisQueueItem() : lastRetry(0), retries(0), waitingPacketCount(0) {}
int64_t lastRetry;
unsigned int retries;

View file

@ -23,47 +23,65 @@
namespace ZeroTier {
VL2::VL2(const Context& ctx) : m_ctx(ctx)
VL2::VL2(const Context &ctx) : m_ctx(ctx) {}
void VL2::onLocalEthernet(
CallContext &cc, const SharedPtr<Network> &network, const MAC &from, const MAC &to, const unsigned int etherType,
unsigned int vlanId, SharedPtr<Buf> &data, unsigned int len)
{
}
void VL2::onLocalEthernet(CallContext& cc, const SharedPtr<Network>& network, const MAC& from, const MAC& to, const unsigned int etherType, unsigned int vlanId, SharedPtr<Buf>& data, unsigned int len)
bool VL2::m_FRAME(
CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path> &path,
SharedPtr<Peer> &peer, Buf &pkt, int packetSize)
{
}
bool VL2::m_FRAME(CallContext& cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path>& path, SharedPtr<Peer>& peer, Buf& pkt, int packetSize)
bool VL2::m_EXT_FRAME(
CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path> &path,
SharedPtr<Peer> &peer, Buf &pkt, int packetSize)
{
}
bool VL2::m_EXT_FRAME(CallContext& cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path>& path, SharedPtr<Peer>& peer, Buf& pkt, int packetSize)
bool VL2::m_MULTICAST_LIKE(
CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path> &path,
SharedPtr<Peer> &peer, Buf &pkt, int packetSize)
{
}
bool VL2::m_MULTICAST_LIKE(CallContext& cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path>& path, SharedPtr<Peer>& peer, Buf& pkt, int packetSize)
bool VL2::m_NETWORK_CREDENTIALS(
CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path> &path,
SharedPtr<Peer> &peer, Buf &pkt, int packetSize)
{
}
bool VL2::m_NETWORK_CREDENTIALS(CallContext& cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path>& path, SharedPtr<Peer>& peer, Buf& pkt, int packetSize)
bool VL2::m_NETWORK_CONFIG_REQUEST(
CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path> &path,
SharedPtr<Peer> &peer, Buf &pkt, int packetSize)
{
}
bool VL2::m_NETWORK_CONFIG_REQUEST(CallContext& cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path>& path, SharedPtr<Peer>& peer, Buf& pkt, int packetSize)
bool VL2::m_NETWORK_CONFIG(
CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path> &path,
SharedPtr<Peer> &peer, Buf &pkt, int packetSize)
{
}
bool VL2::m_NETWORK_CONFIG(CallContext& cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path>& path, SharedPtr<Peer>& peer, Buf& pkt, int packetSize)
bool VL2::m_MULTICAST_GATHER(
CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path> &path,
SharedPtr<Peer> &peer, Buf &pkt, int packetSize)
{
}
bool VL2::m_MULTICAST_GATHER(CallContext& cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path>& path, SharedPtr<Peer>& peer, Buf& pkt, int packetSize)
bool VL2::m_MULTICAST_FRAME_deprecated(
CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path> &path,
SharedPtr<Peer> &peer, Buf &pkt, int packetSize)
{
}
bool VL2::m_MULTICAST_FRAME_deprecated(CallContext& cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path>& path, SharedPtr<Peer>& peer, Buf& pkt, int packetSize)
{
}
bool VL2::m_MULTICAST(CallContext& cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path>& path, SharedPtr<Peer>& peer, Buf& pkt, int packetSize)
bool VL2::m_MULTICAST(
CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr<Path> &path,
SharedPtr<Peer> &peer, Buf &pkt, int packetSize)
{
}

View file

@ -36,7 +36,7 @@ class VL2 {
friend class VL1;
public:
explicit VL2(const Context& ctx);
explicit VL2(const Context &ctx);
/**
* Called when a packet comes from a local Ethernet tap
@ -49,21 +49,41 @@ class VL2 {
* @param data Ethernet payload
* @param len Frame length
*/
void onLocalEthernet(CallContext& cc, const SharedPtr<Network>& network, const MAC& from, const MAC& to, unsigned int etherType, unsigned int vlanId, SharedPtr<Buf>& data, unsigned int len);
void onLocalEthernet(
CallContext &cc, const SharedPtr<Network> &network, const MAC &from, const MAC &to, unsigned int etherType,
unsigned int vlanId, SharedPtr<Buf> &data, unsigned int len);
protected:
bool m_FRAME(CallContext& cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path>& path, SharedPtr<Peer>& peer, Buf& pkt, int packetSize);
bool m_EXT_FRAME(CallContext& cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path>& path, SharedPtr<Peer>& peer, Buf& pkt, int packetSize);
bool m_MULTICAST_LIKE(CallContext& cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path>& path, SharedPtr<Peer>& peer, Buf& pkt, int packetSize);
bool m_NETWORK_CREDENTIALS(CallContext& cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path>& path, SharedPtr<Peer>& peer, Buf& pkt, int packetSize);
bool m_NETWORK_CONFIG_REQUEST(CallContext& cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path>& path, SharedPtr<Peer>& peer, Buf& pkt, int packetSize);
bool m_NETWORK_CONFIG(CallContext& cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path>& path, SharedPtr<Peer>& peer, Buf& pkt, int packetSize);
bool m_MULTICAST_GATHER(CallContext& cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path>& path, SharedPtr<Peer>& peer, Buf& pkt, int packetSize);
bool m_MULTICAST_FRAME_deprecated(CallContext& cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path>& path, SharedPtr<Peer>& peer, Buf& pkt, int packetSize);
bool m_MULTICAST(CallContext& cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path>& path, SharedPtr<Peer>& peer, Buf& pkt, int packetSize);
bool m_FRAME(
CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path> &path, SharedPtr<Peer> &peer,
Buf &pkt, int packetSize);
bool m_EXT_FRAME(
CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path> &path, SharedPtr<Peer> &peer,
Buf &pkt, int packetSize);
bool m_MULTICAST_LIKE(
CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path> &path, SharedPtr<Peer> &peer,
Buf &pkt, int packetSize);
bool m_NETWORK_CREDENTIALS(
CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path> &path, SharedPtr<Peer> &peer,
Buf &pkt, int packetSize);
bool m_NETWORK_CONFIG_REQUEST(
CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path> &path, SharedPtr<Peer> &peer,
Buf &pkt, int packetSize);
bool m_NETWORK_CONFIG(
CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path> &path, SharedPtr<Peer> &peer,
Buf &pkt, int packetSize);
bool m_MULTICAST_GATHER(
CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path> &path, SharedPtr<Peer> &peer,
Buf &pkt, int packetSize);
bool m_MULTICAST_FRAME_deprecated(
CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path> &path, SharedPtr<Peer> &peer,
Buf &pkt, int packetSize);
bool m_MULTICAST(
CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr<Path> &path, SharedPtr<Peer> &peer,
Buf &pkt, int packetSize);
private:
const Context& m_ctx;
const Context &m_ctx;
};
} // namespace ZeroTier

View file

@ -17,17 +17,17 @@
/**
* Major version
*/
#define ZEROTIER_VERSION_MAJOR @ZEROTIER_VERSION_MAJOR@
#define ZEROTIER_VERSION_MAJOR @ZEROTIER_VERSION_MAJOR @
/**
* Minor version
*/
#define ZEROTIER_VERSION_MINOR @ZEROTIER_VERSION_MINOR@
#define ZEROTIER_VERSION_MINOR @ZEROTIER_VERSION_MINOR @
/**
* Revision
*/
#define ZEROTIER_VERSION_REVISION @ZEROTIER_VERSION_REVISION@
#define ZEROTIER_VERSION_REVISION @ZEROTIER_VERSION_REVISION @
/**
* Build version
@ -36,6 +36,6 @@
* to force a minor update without an actual version number change. It's
* not part of the actual release version number.
*/
#define ZEROTIER_VERSION_BUILD @ZEROTIER_VERSION_BUILD@
#define ZEROTIER_VERSION_BUILD @ZEROTIER_VERSION_BUILD @
#endif

File diff suppressed because it is too large Load diff