A bunch of cleanup and refactoring toward 2.x

This commit is contained in:
Adam Ierymenko 2019-12-12 16:15:49 -08:00
parent 23d6a3aacd
commit 6267c67888
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
50 changed files with 1066 additions and 1130 deletions

View file

@ -25,7 +25,7 @@
namespace ZeroTier { namespace ZeroTier {
#ifdef ZT_NO_TYPE_PUNNING #ifdef ZT_NO_TYPE_PUNNING
static ZT_ALWAYS_INLINE uint32_t readuint32_t(const void *in) static inline uint32_t readuint32_t(const void *in)
{ {
uint32_t v = ((const uint8_t *)in)[0]; uint32_t v = ((const uint8_t *)in)[0];
v <<= 8; v <<= 8;
@ -36,7 +36,7 @@ static ZT_ALWAYS_INLINE uint32_t readuint32_t(const void *in)
v |= ((const uint8_t *)in)[3]; v |= ((const uint8_t *)in)[3];
return v; return v;
} }
static ZT_ALWAYS_INLINE void writeuint32_t(void *out,const uint32_t v) static inline void writeuint32_t(void *out,const uint32_t v)
{ {
((uint8_t *)out)[0] = (uint8_t)(v >> 24); ((uint8_t *)out)[0] = (uint8_t)(v >> 24);
((uint8_t *)out)[1] = (uint8_t)(v >> 16); ((uint8_t *)out)[1] = (uint8_t)(v >> 16);
@ -183,7 +183,7 @@ typedef unsigned __int128 uint128_t;
typedef unsigned uint128_t __attribute__((mode(TI))); typedef unsigned uint128_t __attribute__((mode(TI)));
#endif #endif
static ZT_ALWAYS_INLINE void s_bmul64(const uint64_t x,const uint64_t y,uint64_t &r_high,uint64_t &r_low) static inline void s_bmul64(const uint64_t x,const uint64_t y,uint64_t &r_high,uint64_t &r_low)
{ {
static uint128_t m1 = (uint128_t)0x2108421084210842ULL << 64 | 0x1084210842108421ULL; static uint128_t m1 = (uint128_t)0x2108421084210842ULL << 64 | 0x1084210842108421ULL;
static uint128_t m2 = (uint128_t)0x4210842108421084ULL << 64 | 0x2108421084210842ULL; static uint128_t m2 = (uint128_t)0x4210842108421084ULL << 64 | 0x2108421084210842ULL;
@ -214,7 +214,7 @@ static ZT_ALWAYS_INLINE void s_bmul64(const uint64_t x,const uint64_t y,uint64_t
r_low = (uint64_t)r; r_low = (uint64_t)r;
} }
static ZT_ALWAYS_INLINE void s_gfmul(const uint64_t h_high,const uint64_t h_low,uint64_t &y0, uint64_t &y1) static inline void s_gfmul(const uint64_t h_high,const uint64_t h_low,uint64_t &y0, uint64_t &y1)
{ {
uint64_t z2_low,z2_high,z0_low,z0_high,z1a_low,z1a_high; uint64_t z2_low,z2_high,z0_low,z0_high,z1a_low,z1a_high;
uint64_t y_high = Utils::ntoh(y0); uint64_t y_high = Utils::ntoh(y0);
@ -236,7 +236,7 @@ static ZT_ALWAYS_INLINE void s_gfmul(const uint64_t h_high,const uint64_t h_low,
#else #else
static ZT_ALWAYS_INLINE void s_bmul32(uint32_t x,uint32_t y,uint32_t &r_high,uint32_t &r_low) static inline void s_bmul32(uint32_t x,uint32_t y,uint32_t &r_high,uint32_t &r_low)
{ {
const uint32_t m1 = (uint32_t)0x11111111; const uint32_t m1 = (uint32_t)0x11111111;
const uint32_t m2 = (uint32_t)0x22222222; const uint32_t m2 = (uint32_t)0x22222222;
@ -263,7 +263,7 @@ static ZT_ALWAYS_INLINE void s_bmul32(uint32_t x,uint32_t y,uint32_t &r_high,uin
r_low = (uint32_t)z; r_low = (uint32_t)z;
} }
static ZT_ALWAYS_INLINE void s_gfmul(const uint64_t h_high,const uint64_t h_low,uint64_t &y0,uint64_t &y1) static inline void s_gfmul(const uint64_t h_high,const uint64_t h_low,uint64_t &y0,uint64_t &y1)
{ {
uint32_t h_high_h = (uint32_t)(h_high >> 32); uint32_t h_high_h = (uint32_t)(h_high >> 32);
uint32_t h_high_l = (uint32_t)h_high; uint32_t h_high_l = (uint32_t)h_high;

View file

@ -47,14 +47,14 @@ public:
*/ */
static const bool HW_ACCEL; static const bool HW_ACCEL;
ZT_ALWAYS_INLINE AES() {} inline AES() {}
ZT_ALWAYS_INLINE AES(const uint8_t key[32]) { this->init(key); } inline AES(const uint8_t key[32]) { this->init(key); }
ZT_ALWAYS_INLINE ~AES() { Utils::burn(&_k,sizeof(_k)); } inline ~AES() { Utils::burn(&_k,sizeof(_k)); }
/** /**
* Set (or re-set) this AES256 cipher's key * Set (or re-set) this AES256 cipher's key
*/ */
ZT_ALWAYS_INLINE void init(const uint8_t key[32]) inline void init(const uint8_t key[32])
{ {
#ifdef ZT_AES_AESNI #ifdef ZT_AES_AESNI
if (likely(HW_ACCEL)) { if (likely(HW_ACCEL)) {
@ -72,7 +72,7 @@ public:
* @param in Input block * @param in Input block
* @param out Output block (can be same as input) * @param out Output block (can be same as input)
*/ */
ZT_ALWAYS_INLINE void encrypt(const uint8_t in[16],uint8_t out[16]) const inline void encrypt(const uint8_t in[16],uint8_t out[16]) const
{ {
#ifdef ZT_AES_AESNI #ifdef ZT_AES_AESNI
if (likely(HW_ACCEL)) { if (likely(HW_ACCEL)) {
@ -92,7 +92,7 @@ public:
* @param len Length of input * @param len Length of input
* @param out 128-bit authorization tag from GMAC * @param out 128-bit authorization tag from GMAC
*/ */
ZT_ALWAYS_INLINE void gmac(const uint8_t iv[12],const void *in,const unsigned int len,uint8_t out[16]) const inline void gmac(const uint8_t iv[12],const void *in,const unsigned int len,uint8_t out[16]) const
{ {
#ifdef ZT_AES_AESNI #ifdef ZT_AES_AESNI
if (likely(HW_ACCEL)) { if (likely(HW_ACCEL)) {
@ -116,7 +116,7 @@ public:
* @param len Length of input * @param len Length of input
* @param out Output plaintext or ciphertext * @param out Output plaintext or ciphertext
*/ */
ZT_ALWAYS_INLINE void ctr(const uint8_t iv[16],const void *in,unsigned int len,void *out) const inline void ctr(const uint8_t iv[16],const void *in,unsigned int len,void *out) const
{ {
#ifdef ZT_AES_AESNI #ifdef ZT_AES_AESNI
if (likely(HW_ACCEL)) { if (likely(HW_ACCEL)) {
@ -187,7 +187,7 @@ public:
* @param out Output buffer to receive ciphertext * @param out Output buffer to receive ciphertext
* @param tag Output buffer to receive 64-bit authentication tag * @param tag Output buffer to receive 64-bit authentication tag
*/ */
static ZT_ALWAYS_INLINE void gmacSivEncrypt(const AES &k1,const AES &k2,const AES &k3,const AES &k4,const uint8_t iv[8],const uint8_t pc,const void *in,const unsigned int len,void *out,uint8_t tag[8]) static inline void gmacSivEncrypt(const AES &k1,const AES &k2,const AES &k3,const AES &k4,const uint8_t iv[8],const uint8_t pc,const void *in,const unsigned int len,void *out,uint8_t tag[8])
{ {
#ifdef __GNUC__ #ifdef __GNUC__
uint8_t __attribute__ ((aligned (16))) miv[12]; uint8_t __attribute__ ((aligned (16))) miv[12];
@ -246,7 +246,7 @@ public:
* @param tag Authentication tag supplied with message * @param tag Authentication tag supplied with message
* @return True if authentication tags match and message appears authentic * @return True if authentication tags match and message appears authentic
*/ */
static ZT_ALWAYS_INLINE bool gmacSivDecrypt(const AES &k1,const AES &k2,const AES &k3,const AES &k4,const uint8_t iv[8],const uint8_t pc,const void *in,const unsigned int len,void *out,const uint8_t tag[8]) static inline bool gmacSivDecrypt(const AES &k1,const AES &k2,const AES &k3,const AES &k4,const uint8_t iv[8],const uint8_t pc,const void *in,const unsigned int len,void *out,const uint8_t tag[8])
{ {
#ifdef __GNUC__ #ifdef __GNUC__
uint8_t __attribute__ ((aligned (16))) miv[12]; uint8_t __attribute__ ((aligned (16))) miv[12];
@ -307,7 +307,7 @@ public:
* @param k3 CTR IV keyed hash key * @param k3 CTR IV keyed hash key
* @param k4 AES-CTR key * @param k4 AES-CTR key
*/ */
static ZT_ALWAYS_INLINE void initGmacCtrKeys(const uint8_t masterKey[32],AES &k1,AES &k2,AES &k3,AES &k4) static inline void initGmacCtrKeys(const uint8_t masterKey[32],AES &k1,AES &k2,AES &k3,AES &k4)
{ {
uint8_t k[32]; uint8_t k[32];
KBKDFHMACSHA384(masterKey,ZT_PROTO_KBKDF_LABEL_KEY_USE_AES_GMAC_SIV_K1,0,0,k); KBKDFHMACSHA384(masterKey,ZT_PROTO_KBKDF_LABEL_KEY_USE_AES_GMAC_SIV_K1,0,0,k);
@ -435,7 +435,7 @@ private:
#endif /*********************************************************************/ #endif /*********************************************************************/
#ifdef ZT_AES_AESNI /********************************************************/ #ifdef ZT_AES_AESNI /********************************************************/
static ZT_ALWAYS_INLINE __m128i _init256_1_aesni(__m128i a,__m128i b) static inline __m128i _init256_1_aesni(__m128i a,__m128i b)
{ {
__m128i x,y; __m128i x,y;
b = _mm_shuffle_epi32(b,0xff); b = _mm_shuffle_epi32(b,0xff);
@ -448,7 +448,7 @@ private:
x = _mm_xor_si128(x,b); x = _mm_xor_si128(x,b);
return x; return x;
} }
static ZT_ALWAYS_INLINE __m128i _init256_2_aesni(__m128i a,__m128i b) static inline __m128i _init256_2_aesni(__m128i a,__m128i b)
{ {
__m128i x,y,z; __m128i x,y,z;
y = _mm_aeskeygenassist_si128(a,0x00); y = _mm_aeskeygenassist_si128(a,0x00);
@ -462,7 +462,7 @@ private:
x = _mm_xor_si128(x,z); x = _mm_xor_si128(x,z);
return x; return x;
} }
ZT_ALWAYS_INLINE void _init_aesni(const uint8_t key[32]) inline void _init_aesni(const uint8_t key[32])
{ {
__m128i t1,t2; __m128i t1,t2;
_k.ni.k[0] = t1 = _mm_loadu_si128((const __m128i *)key); _k.ni.k[0] = t1 = _mm_loadu_si128((const __m128i *)key);
@ -508,7 +508,7 @@ private:
_k.ni.hhhh = _mm_shuffle_epi8(hhhh,shuf); _k.ni.hhhh = _mm_shuffle_epi8(hhhh,shuf);
} }
ZT_ALWAYS_INLINE void _encrypt_aesni(const void *in,void *out) const inline void _encrypt_aesni(const void *in,void *out) const
{ {
__m128i tmp; __m128i tmp;
tmp = _mm_loadu_si128((const __m128i *)in); tmp = _mm_loadu_si128((const __m128i *)in);
@ -529,7 +529,7 @@ private:
_mm_storeu_si128((__m128i *)out,_mm_aesenclast_si128(tmp,_k.ni.k[14])); _mm_storeu_si128((__m128i *)out,_mm_aesenclast_si128(tmp,_k.ni.k[14]));
} }
static ZT_ALWAYS_INLINE __m128i _mult_block_aesni(__m128i shuf,__m128i h,__m128i y) static inline __m128i _mult_block_aesni(__m128i shuf,__m128i h,__m128i y)
{ {
y = _mm_shuffle_epi8(y,shuf); y = _mm_shuffle_epi8(y,shuf);
__m128i t1 = _mm_clmulepi64_si128(h,y,0x00); __m128i t1 = _mm_clmulepi64_si128(h,y,0x00);
@ -569,9 +569,9 @@ private:
t4 = _mm_xor_si128(t4,t5); t4 = _mm_xor_si128(t4,t5);
return _mm_shuffle_epi8(t4,shuf); return _mm_shuffle_epi8(t4,shuf);
} }
static ZT_ALWAYS_INLINE __m128i _ghash_aesni(__m128i shuf,__m128i h,__m128i y,__m128i x) { return _mult_block_aesni(shuf,h,_mm_xor_si128(y,x)); } static inline __m128i _ghash_aesni(__m128i shuf,__m128i h,__m128i y,__m128i x) { return _mult_block_aesni(shuf,h,_mm_xor_si128(y,x)); }
ZT_ALWAYS_INLINE void _gmac_aesni(const uint8_t iv[12],const uint8_t *in,const unsigned int len,uint8_t out[16]) const inline void _gmac_aesni(const uint8_t iv[12],const uint8_t *in,const unsigned int len,uint8_t out[16]) const
{ {
const __m128i *const ab = (const __m128i *)in; const __m128i *const ab = (const __m128i *)in;
const unsigned int blocks = len / 16; const unsigned int blocks = len / 16;

View file

@ -33,24 +33,24 @@ namespace ZeroTier {
class Address class Address
{ {
public: public:
ZT_ALWAYS_INLINE Address() : _a(0) {} inline Address() : _a(0) {}
ZT_ALWAYS_INLINE Address(const Address &a) : _a(a._a) {} inline Address(const Address &a) : _a(a._a) {}
ZT_ALWAYS_INLINE Address(uint64_t a) : _a(a & 0xffffffffffULL) {} inline Address(uint64_t a) : _a(a & 0xffffffffffULL) {}
/** /**
* @param bits Raw address -- 5 bytes, big-endian byte order * @param bits Raw address -- 5 bytes, big-endian byte order
* @param len Length of array * @param len Length of array
*/ */
ZT_ALWAYS_INLINE Address(const void *bits,unsigned int len) { setTo(bits,len); } inline Address(const void *bits,unsigned int len) { setTo(bits,len); }
ZT_ALWAYS_INLINE Address &operator=(const Address &a) { _a = a._a; return *this; } inline Address &operator=(const Address &a) { _a = a._a; return *this; }
ZT_ALWAYS_INLINE Address &operator=(const uint64_t a) { _a = (a & 0xffffffffffULL); return *this; } inline Address &operator=(const uint64_t a) { _a = (a & 0xffffffffffULL); return *this; }
/** /**
* @param bits Raw address -- 5 bytes, big-endian byte order * @param bits Raw address -- 5 bytes, big-endian byte order
* @param len Length of array * @param len Length of array
*/ */
ZT_ALWAYS_INLINE void setTo(const void *bits,const unsigned int len) inline void setTo(const void *bits,const unsigned int len)
{ {
if (len < ZT_ADDRESS_LENGTH) { if (len < ZT_ADDRESS_LENGTH) {
_a = 0; _a = 0;
@ -69,7 +69,7 @@ public:
* @param bits Buffer to hold 5-byte address in big-endian byte order * @param bits Buffer to hold 5-byte address in big-endian byte order
* @param len Length of array * @param len Length of array
*/ */
ZT_ALWAYS_INLINE void copyTo(void *const bits,const unsigned int len) const inline void copyTo(void *const bits,const unsigned int len) const
{ {
if (len < ZT_ADDRESS_LENGTH) if (len < ZT_ADDRESS_LENGTH)
return; return;
@ -87,7 +87,7 @@ public:
* @param b Buffer to append to * @param b Buffer to append to
*/ */
template<unsigned int C> template<unsigned int C>
ZT_ALWAYS_INLINE void appendTo(Buffer<C> &b) const inline void appendTo(Buffer<C> &b) const
{ {
unsigned char *p = (unsigned char *)b.appendField(ZT_ADDRESS_LENGTH); unsigned char *p = (unsigned char *)b.appendField(ZT_ADDRESS_LENGTH);
*(p++) = (unsigned char)((_a >> 32) & 0xff); *(p++) = (unsigned char)((_a >> 32) & 0xff);
@ -100,22 +100,22 @@ public:
/** /**
* @return Integer containing address (0 to 2^40) * @return Integer containing address (0 to 2^40)
*/ */
ZT_ALWAYS_INLINE uint64_t toInt() const { return _a; } inline uint64_t toInt() const { return _a; }
/** /**
* @return Hash code for use with Hashtable * @return Hash code for use with Hashtable
*/ */
ZT_ALWAYS_INLINE unsigned long hashCode() const { return (unsigned long)_a; } inline unsigned long hashCode() const { return (unsigned long)_a; }
/** /**
* @return Hexadecimal string * @return Hexadecimal string
*/ */
ZT_ALWAYS_INLINE char *toString(char buf[11]) const { return Utils::hex10(_a,buf); } inline char *toString(char buf[11]) const { return Utils::hex10(_a,buf); }
/** /**
* @return True if this address is not zero * @return True if this address is not zero
*/ */
ZT_ALWAYS_INLINE operator bool() const { return (_a != 0); } inline operator bool() const { return (_a != 0); }
/** /**
* Check if this address is reserved * Check if this address is reserved
@ -126,33 +126,33 @@ public:
* *
* @return True if address is reserved and may not be used * @return True if address is reserved and may not be used
*/ */
ZT_ALWAYS_INLINE bool isReserved() const { return ((!_a)||((_a >> 32) == ZT_ADDRESS_RESERVED_PREFIX)); } inline bool isReserved() const { return ((!_a)||((_a >> 32) == ZT_ADDRESS_RESERVED_PREFIX)); }
/** /**
* @param i Value from 0 to 4 (inclusive) * @param i Value from 0 to 4 (inclusive)
* @return Byte at said position (address interpreted in big-endian order) * @return Byte at said position (address interpreted in big-endian order)
*/ */
ZT_ALWAYS_INLINE uint8_t operator[](unsigned int i) const { return (uint8_t)(_a >> (32 - (i * 8))); } inline uint8_t operator[](unsigned int i) const { return (uint8_t)(_a >> (32 - (i * 8))); }
ZT_ALWAYS_INLINE operator unsigned int() const { return (unsigned int)_a; } inline operator unsigned int() const { return (unsigned int)_a; }
ZT_ALWAYS_INLINE operator unsigned long() const { return (unsigned long)_a; } inline operator unsigned long() const { return (unsigned long)_a; }
ZT_ALWAYS_INLINE operator unsigned long long() const { return (unsigned long long)_a; } inline operator unsigned long long() const { return (unsigned long long)_a; }
ZT_ALWAYS_INLINE void zero() { _a = 0; } inline void zero() { _a = 0; }
ZT_ALWAYS_INLINE bool operator==(const uint64_t &a) const { return (_a == (a & 0xffffffffffULL)); } inline bool operator==(const uint64_t &a) const { return (_a == (a & 0xffffffffffULL)); }
ZT_ALWAYS_INLINE bool operator!=(const uint64_t &a) const { return (_a != (a & 0xffffffffffULL)); } inline bool operator!=(const uint64_t &a) const { return (_a != (a & 0xffffffffffULL)); }
ZT_ALWAYS_INLINE bool operator>(const uint64_t &a) const { return (_a > (a & 0xffffffffffULL)); } inline bool operator>(const uint64_t &a) const { return (_a > (a & 0xffffffffffULL)); }
ZT_ALWAYS_INLINE bool operator<(const uint64_t &a) const { return (_a < (a & 0xffffffffffULL)); } inline bool operator<(const uint64_t &a) const { return (_a < (a & 0xffffffffffULL)); }
ZT_ALWAYS_INLINE bool operator>=(const uint64_t &a) const { return (_a >= (a & 0xffffffffffULL)); } inline bool operator>=(const uint64_t &a) const { return (_a >= (a & 0xffffffffffULL)); }
ZT_ALWAYS_INLINE bool operator<=(const uint64_t &a) const { return (_a <= (a & 0xffffffffffULL)); } inline bool operator<=(const uint64_t &a) const { return (_a <= (a & 0xffffffffffULL)); }
ZT_ALWAYS_INLINE bool operator==(const Address &a) const { return (_a == a._a); } inline bool operator==(const Address &a) const { return (_a == a._a); }
ZT_ALWAYS_INLINE bool operator!=(const Address &a) const { return (_a != a._a); } inline bool operator!=(const Address &a) const { return (_a != a._a); }
ZT_ALWAYS_INLINE bool operator>(const Address &a) const { return (_a > a._a); } inline bool operator>(const Address &a) const { return (_a > a._a); }
ZT_ALWAYS_INLINE bool operator<(const Address &a) const { return (_a < a._a); } inline bool operator<(const Address &a) const { return (_a < a._a); }
ZT_ALWAYS_INLINE bool operator>=(const Address &a) const { return (_a >= a._a); } inline bool operator>=(const Address &a) const { return (_a >= a._a); }
ZT_ALWAYS_INLINE bool operator<=(const Address &a) const { return (_a <= a._a); } inline bool operator<=(const Address &a) const { return (_a <= a._a); }
private: private:
uint64_t _a; uint64_t _a;

View file

@ -28,9 +28,9 @@ namespace ZeroTier {
class AtomicCounter class AtomicCounter
{ {
public: public:
ZT_ALWAYS_INLINE AtomicCounter() { _v = 0; } inline AtomicCounter() { _v = 0; }
ZT_ALWAYS_INLINE int load() const inline int load() const
{ {
#ifdef __GNUC__ #ifdef __GNUC__
return __sync_or_and_fetch(const_cast<int *>(&_v),0); return __sync_or_and_fetch(const_cast<int *>(&_v),0);
@ -39,7 +39,7 @@ public:
#endif #endif
} }
ZT_ALWAYS_INLINE int operator++() inline int operator++()
{ {
#ifdef __GNUC__ #ifdef __GNUC__
return __sync_add_and_fetch(&_v,1); return __sync_add_and_fetch(&_v,1);
@ -48,7 +48,7 @@ public:
#endif #endif
} }
ZT_ALWAYS_INLINE int operator--() inline int operator--()
{ {
#ifdef __GNUC__ #ifdef __GNUC__
return __sync_sub_and_fetch(&_v,1); return __sync_sub_and_fetch(&_v,1);
@ -58,8 +58,8 @@ public:
} }
private: private:
ZT_ALWAYS_INLINE AtomicCounter(const AtomicCounter &) {} inline AtomicCounter(const AtomicCounter &) {}
ZT_ALWAYS_INLINE const AtomicCounter &operator=(const AtomicCounter &) { return *this; } inline const AtomicCounter &operator=(const AtomicCounter &) { return *this; }
#ifdef __GNUC__ #ifdef __GNUC__
int _v; int _v;

View file

@ -41,7 +41,7 @@ typedef uint8_t u8;
typedef int32_t s32; typedef int32_t s32;
typedef int64_t limb; typedef int64_t limb;
static ZT_ALWAYS_INLINE void fsum(limb *output, const limb *in) { static inline void fsum(limb *output, const limb *in) {
unsigned i; unsigned i;
for (i = 0; i < 10; i += 2) { for (i = 0; i < 10; i += 2) {
output[0+i] = output[0+i] + in[0+i]; output[0+i] = output[0+i] + in[0+i];
@ -49,21 +49,21 @@ static ZT_ALWAYS_INLINE void fsum(limb *output, const limb *in) {
} }
} }
static ZT_ALWAYS_INLINE void fdifference(limb *output, const limb *in) { static inline void fdifference(limb *output, const limb *in) {
unsigned i; unsigned i;
for (i = 0; i < 10; ++i) { for (i = 0; i < 10; ++i) {
output[i] = in[i] - output[i]; output[i] = in[i] - output[i];
} }
} }
static ZT_ALWAYS_INLINE void fscalar_product(limb *output, const limb *in, const limb scalar) { static inline void fscalar_product(limb *output, const limb *in, const limb scalar) {
unsigned i; unsigned i;
for (i = 0; i < 10; ++i) { for (i = 0; i < 10; ++i) {
output[i] = in[i] * scalar; output[i] = in[i] * scalar;
} }
} }
static ZT_ALWAYS_INLINE void fproduct(limb *output, const limb *in2, const limb *in) { static inline void fproduct(limb *output, const limb *in2, const limb *in) {
output[0] = ((limb) ((s32) in2[0])) * ((s32) in[0]); output[0] = ((limb) ((s32) in2[0])) * ((s32) in[0]);
output[1] = ((limb) ((s32) in2[0])) * ((s32) in[1]) + output[1] = ((limb) ((s32) in2[0])) * ((s32) in[1]) +
((limb) ((s32) in2[1])) * ((s32) in[0]); ((limb) ((s32) in2[1])) * ((s32) in[0]);
@ -166,7 +166,7 @@ static ZT_ALWAYS_INLINE void fproduct(limb *output, const limb *in2, const limb
output[18] = 2 * ((limb) ((s32) in2[9])) * ((s32) in[9]); output[18] = 2 * ((limb) ((s32) in2[9])) * ((s32) in[9]);
} }
static ZT_ALWAYS_INLINE void freduce_degree(limb *output) { static inline void freduce_degree(limb *output) {
output[8] += output[18] << 4; output[8] += output[18] << 4;
output[8] += output[18] << 1; output[8] += output[18] << 1;
output[8] += output[18]; output[8] += output[18];
@ -200,7 +200,7 @@ static ZT_ALWAYS_INLINE void freduce_degree(limb *output) {
#error "This code only works on a two's complement system" #error "This code only works on a two's complement system"
#endif #endif
static ZT_ALWAYS_INLINE limb div_by_2_26(const limb v) static inline limb div_by_2_26(const limb v)
{ {
/* High word of v; no shift needed. */ /* High word of v; no shift needed. */
const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32); const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
@ -212,7 +212,7 @@ static ZT_ALWAYS_INLINE limb div_by_2_26(const limb v)
return (v + roundoff) >> 26; return (v + roundoff) >> 26;
} }
static ZT_ALWAYS_INLINE limb div_by_2_25(const limb v) static inline limb div_by_2_25(const limb v)
{ {
/* High word of v; no shift needed*/ /* High word of v; no shift needed*/
const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32); const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
@ -224,7 +224,7 @@ static ZT_ALWAYS_INLINE limb div_by_2_25(const limb v)
return (v + roundoff) >> 25; return (v + roundoff) >> 25;
} }
static ZT_ALWAYS_INLINE void freduce_coefficients(limb *output) { static inline void freduce_coefficients(limb *output) {
unsigned i; unsigned i;
output[10] = 0; output[10] = 0;
@ -277,7 +277,7 @@ static inline void fmul(limb *output, const limb *in, const limb *in2) {
memcpy(output, t, sizeof(limb) * 10); memcpy(output, t, sizeof(limb) * 10);
} }
static ZT_ALWAYS_INLINE void fsquare_inner(limb *output, const limb *in) { static inline void fsquare_inner(limb *output, const limb *in) {
output[0] = ((limb) ((s32) in[0])) * ((s32) in[0]); output[0] = ((limb) ((s32) in[0])) * ((s32) in[0]);
output[1] = 2 * ((limb) ((s32) in[0])) * ((s32) in[1]); output[1] = 2 * ((limb) ((s32) in[0])) * ((s32) in[1]);
output[2] = 2 * (((limb) ((s32) in[1])) * ((s32) in[1]) + output[2] = 2 * (((limb) ((s32) in[1])) * ((s32) in[1]) +
@ -347,7 +347,7 @@ static inline void fsquare(limb *output, const limb *in) {
memcpy(output, t, sizeof(limb) * 10); memcpy(output, t, sizeof(limb) * 10);
} }
static ZT_ALWAYS_INLINE void fexpand(limb *output, const u8 *input) { static inline void fexpand(limb *output, const u8 *input) {
#define F(n,start,shift,mask) \ #define F(n,start,shift,mask) \
output[n] = ((((limb) input[start + 0]) | \ output[n] = ((((limb) input[start + 0]) | \
((limb) input[start + 1]) << 8 | \ ((limb) input[start + 1]) << 8 | \
@ -370,7 +370,7 @@ static ZT_ALWAYS_INLINE void fexpand(limb *output, const u8 *input) {
#error "This code only works when >> does sign-extension on negative numbers" #error "This code only works when >> does sign-extension on negative numbers"
#endif #endif
static ZT_ALWAYS_INLINE s32 s32_eq(s32 a, s32 b) { static inline s32 s32_eq(s32 a, s32 b) {
a = ~(a ^ b); a = ~(a ^ b);
a &= a << 16; a &= a << 16;
a &= a << 8; a &= a << 8;
@ -380,7 +380,7 @@ static ZT_ALWAYS_INLINE s32 s32_eq(s32 a, s32 b) {
return a >> 31; return a >> 31;
} }
static ZT_ALWAYS_INLINE s32 s32_gte(s32 a, s32 b) { static inline s32 s32_gte(s32 a, s32 b) {
a -= b; a -= b;
/* a >= 0 iff a >= b. */ /* a >= 0 iff a >= b. */
return ~(a >> 31); return ~(a >> 31);
@ -560,7 +560,7 @@ static inline void fmonty(limb *x2, limb *z2, /* output 2Q */
/* |z2|i| < 2^26 */ /* |z2|i| < 2^26 */
} }
static ZT_ALWAYS_INLINE void swap_conditional(limb a[19], limb b[19], limb iswap) { static inline void swap_conditional(limb a[19], limb b[19], limb iswap) {
unsigned i; unsigned i;
const s32 swap = (s32) -iswap; const s32 swap = (s32) -iswap;
@ -701,7 +701,7 @@ static inline void crypto_scalarmult(u8 *mypublic, const u8 *secret, const u8 *b
} }
static const unsigned char base[32] = {9}; static const unsigned char base[32] = {9};
static ZT_ALWAYS_INLINE void crypto_scalarmult_base(unsigned char *q,const unsigned char *n) { crypto_scalarmult(q,n,base); } static inline void crypto_scalarmult_base(unsigned char *q,const unsigned char *n) { crypto_scalarmult(q,n,base); }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -759,7 +759,7 @@ typedef struct
static inline void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y); static inline void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y);
static ZT_ALWAYS_INLINE crypto_uint32 equal(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */ static inline crypto_uint32 equal(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
{ {
crypto_uint32 x = a ^ b; /* 0: yes; 1..65535: no */ crypto_uint32 x = a ^ b; /* 0: yes; 1..65535: no */
x -= 1; /* 4294967295: yes; 0..65534: no */ x -= 1; /* 4294967295: yes; 0..65534: no */
@ -767,7 +767,7 @@ static ZT_ALWAYS_INLINE crypto_uint32 equal(crypto_uint32 a,crypto_uint32 b) /*
return x; return x;
} }
static ZT_ALWAYS_INLINE crypto_uint32 ge(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */ static inline crypto_uint32 ge(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
{ {
unsigned int x = a; unsigned int x = a;
x -= (unsigned int) b; /* 0..65535: yes; 4294901761..4294967295: no */ x -= (unsigned int) b; /* 0..65535: yes; 4294901761..4294967295: no */
@ -776,10 +776,10 @@ static ZT_ALWAYS_INLINE crypto_uint32 ge(crypto_uint32 a,crypto_uint32 b) /* 16-
return x; return x;
} }
static ZT_ALWAYS_INLINE crypto_uint32 times19(crypto_uint32 a) { return (a << 4) + (a << 1) + a; } static inline crypto_uint32 times19(crypto_uint32 a) { return (a << 4) + (a << 1) + a; }
static ZT_ALWAYS_INLINE crypto_uint32 times38(crypto_uint32 a) { return (a << 5) + (a << 2) + (a << 1); } static inline crypto_uint32 times38(crypto_uint32 a) { return (a << 5) + (a << 2) + (a << 1); }
static ZT_ALWAYS_INLINE void reduce_add_sub(fe25519 *r) static inline void reduce_add_sub(fe25519 *r)
{ {
int i,rep; int i,rep;
for(rep=0;rep<4;rep++) for(rep=0;rep<4;rep++)
@ -797,7 +797,7 @@ static ZT_ALWAYS_INLINE void reduce_add_sub(fe25519 *r)
} }
} }
static ZT_ALWAYS_INLINE void reduce_mul(fe25519 *r) static inline void reduce_mul(fe25519 *r)
{ {
int i,rep; int i,rep;
for(rep=0;rep<2;rep++) for(rep=0;rep<2;rep++)
@ -815,7 +815,7 @@ static ZT_ALWAYS_INLINE void reduce_mul(fe25519 *r)
} }
} }
static ZT_ALWAYS_INLINE void fe25519_freeze(fe25519 *r) static inline void fe25519_freeze(fe25519 *r)
{ {
int i; int i;
crypto_uint32 mm = equal(r->v[31],127); crypto_uint32 mm = equal(r->v[31],127);
@ -831,14 +831,14 @@ static ZT_ALWAYS_INLINE void fe25519_freeze(fe25519 *r)
r->v[0] -= mm&237; r->v[0] -= mm&237;
} }
static ZT_ALWAYS_INLINE void fe25519_unpack(fe25519 *r, const unsigned char x[32]) static inline void fe25519_unpack(fe25519 *r, const unsigned char x[32])
{ {
int i; int i;
for(i=0;i<32;i++) r->v[i] = x[i]; for(i=0;i<32;i++) r->v[i] = x[i];
r->v[31] &= 127; r->v[31] &= 127;
} }
static ZT_ALWAYS_INLINE void fe25519_pack(unsigned char r[32], const fe25519 *x) static inline void fe25519_pack(unsigned char r[32], const fe25519 *x)
{ {
int i; int i;
fe25519 y = *x; fe25519 y = *x;
@ -859,7 +859,7 @@ static inline int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y)
return 1; return 1;
} }
static ZT_ALWAYS_INLINE void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b) static inline void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b)
{ {
int i; int i;
crypto_uint32 mask = b; crypto_uint32 mask = b;
@ -867,27 +867,27 @@ static ZT_ALWAYS_INLINE void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned
for(i=0;i<32;i++) r->v[i] ^= mask & (x->v[i] ^ r->v[i]); for(i=0;i<32;i++) r->v[i] ^= mask & (x->v[i] ^ r->v[i]);
} }
static ZT_ALWAYS_INLINE unsigned char fe25519_getparity(const fe25519 *x) static inline unsigned char fe25519_getparity(const fe25519 *x)
{ {
fe25519 t = *x; fe25519 t = *x;
fe25519_freeze(&t); fe25519_freeze(&t);
return t.v[0] & 1; return t.v[0] & 1;
} }
static ZT_ALWAYS_INLINE void fe25519_setone(fe25519 *r) static inline void fe25519_setone(fe25519 *r)
{ {
int i; int i;
r->v[0] = 1; r->v[0] = 1;
for(i=1;i<32;i++) r->v[i]=0; for(i=1;i<32;i++) r->v[i]=0;
} }
static ZT_ALWAYS_INLINE void fe25519_setzero(fe25519 *r) static inline void fe25519_setzero(fe25519 *r)
{ {
int i; int i;
for(i=0;i<32;i++) r->v[i]=0; for(i=0;i<32;i++) r->v[i]=0;
} }
static ZT_ALWAYS_INLINE void fe25519_neg(fe25519 *r, const fe25519 *x) static inline void fe25519_neg(fe25519 *r, const fe25519 *x)
{ {
fe25519 t; fe25519 t;
int i; int i;
@ -896,14 +896,14 @@ static ZT_ALWAYS_INLINE void fe25519_neg(fe25519 *r, const fe25519 *x)
fe25519_sub(r, r, &t); fe25519_sub(r, r, &t);
} }
static ZT_ALWAYS_INLINE void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y) static inline void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y)
{ {
int i; int i;
for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i]; for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];
reduce_add_sub(r); reduce_add_sub(r);
} }
static ZT_ALWAYS_INLINE void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y) static inline void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y)
{ {
int i; int i;
crypto_uint32 t[32]; crypto_uint32 t[32];
@ -914,7 +914,7 @@ static ZT_ALWAYS_INLINE void fe25519_sub(fe25519 *r, const fe25519 *x, const fe2
reduce_add_sub(r); reduce_add_sub(r);
} }
static ZT_ALWAYS_INLINE void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y) static inline void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y)
{ {
int i,j; int i,j;
crypto_uint32 t[63]; crypto_uint32 t[63];
@ -931,7 +931,7 @@ static ZT_ALWAYS_INLINE void fe25519_mul(fe25519 *r, const fe25519 *x, const fe2
reduce_mul(r); reduce_mul(r);
} }
static ZT_ALWAYS_INLINE void fe25519_square(fe25519 *r, const fe25519 *x) { fe25519_mul(r, x, x); } static inline void fe25519_square(fe25519 *r, const fe25519 *x) { fe25519_mul(r, x, x); }
static inline void fe25519_invert(fe25519 *r, const fe25519 *x) static inline void fe25519_invert(fe25519 *r, const fe25519 *x)
{ {
@ -1057,7 +1057,7 @@ static inline void fe25519_pow2523(fe25519 *r, const fe25519 *x)
static 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}; static 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};
static 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}; static 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};
static ZT_ALWAYS_INLINE crypto_uint32 lt(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */ static inline crypto_uint32 lt(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
{ {
unsigned int x = a; unsigned int x = a;
x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */ x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */
@ -1065,7 +1065,7 @@ static ZT_ALWAYS_INLINE crypto_uint32 lt(crypto_uint32 a,crypto_uint32 b) /* 16-
return x; return x;
} }
static ZT_ALWAYS_INLINE void reduce_add_sub(sc25519 *r) static inline void reduce_add_sub(sc25519 *r)
{ {
crypto_uint32 pb = 0; crypto_uint32 pb = 0;
crypto_uint32 b; crypto_uint32 b;
@ -1144,7 +1144,7 @@ static inline void sc25519_from64bytes(sc25519 *r, const unsigned char x[64])
barrett_reduce(r, t); barrett_reduce(r, t);
} }
static ZT_ALWAYS_INLINE void sc25519_to32bytes(unsigned char r[32], const sc25519 *x) static inline void sc25519_to32bytes(unsigned char r[32], const sc25519 *x)
{ {
int i; int i;
for(i=0;i<32;i++) r[i] = x->v[i]; for(i=0;i<32;i++) r[i] = x->v[i];
@ -1181,7 +1181,7 @@ static inline void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
barrett_reduce(r, t); barrett_reduce(r, t);
} }
static ZT_ALWAYS_INLINE void sc25519_window3(signed char r[85], const sc25519 *s) static inline void sc25519_window3(signed char r[85], const sc25519 *s)
{ {
char carry; char carry;
int i; int i;
@ -1218,7 +1218,7 @@ static ZT_ALWAYS_INLINE void sc25519_window3(signed char r[85], const sc25519 *s
r[84] += carry; r[84] += carry;
} }
static ZT_ALWAYS_INLINE void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2) static inline void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2)
{ {
int i; int i;
for(i=0;i<31;i++) for(i=0;i<31;i++)
@ -2107,21 +2107,21 @@ static const ge25519_aff ge25519_base_multiples_affine[425] = {
{{0x69, 0x3e, 0x47, 0x97, 0x2c, 0xaf, 0x52, 0x7c, 0x78, 0x83, 0xad, 0x1b, 0x39, 0x82, 0x2f, 0x02, 0x6f, 0x47, 0xdb, 0x2a, 0xb0, 0xe1, 0x91, 0x99, 0x55, 0xb8, 0x99, 0x3a, 0xa0, 0x44, 0x11, 0x51}}} {{0x69, 0x3e, 0x47, 0x97, 0x2c, 0xaf, 0x52, 0x7c, 0x78, 0x83, 0xad, 0x1b, 0x39, 0x82, 0x2f, 0x02, 0x6f, 0x47, 0xdb, 0x2a, 0xb0, 0xe1, 0x91, 0x99, 0x55, 0xb8, 0x99, 0x3a, 0xa0, 0x44, 0x11, 0x51}}}
}; };
static ZT_ALWAYS_INLINE void p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p) static inline void p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p)
{ {
fe25519_mul(&r->x, &p->x, &p->t); fe25519_mul(&r->x, &p->x, &p->t);
fe25519_mul(&r->y, &p->y, &p->z); fe25519_mul(&r->y, &p->y, &p->z);
fe25519_mul(&r->z, &p->z, &p->t); fe25519_mul(&r->z, &p->z, &p->t);
} }
static ZT_ALWAYS_INLINE void p1p1_to_p2_2(ge25519_p3 *r, const ge25519_p1p1 *p) static inline void p1p1_to_p2_2(ge25519_p3 *r, const ge25519_p1p1 *p)
{ {
fe25519_mul(&r->x, &p->x, &p->t); fe25519_mul(&r->x, &p->x, &p->t);
fe25519_mul(&r->y, &p->y, &p->z); fe25519_mul(&r->y, &p->y, &p->z);
fe25519_mul(&r->z, &p->z, &p->t); fe25519_mul(&r->z, &p->z, &p->t);
} }
static ZT_ALWAYS_INLINE void p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p) static inline void p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p)
{ {
p1p1_to_p2_2(r, p); p1p1_to_p2_2(r, p);
fe25519_mul(&r->t, &p->x, &p->y); fe25519_mul(&r->t, &p->x, &p->y);
@ -2190,13 +2190,13 @@ static inline void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p)
} }
/* Constant-time version of: if(b) r = p */ /* Constant-time version of: if(b) r = p */
static ZT_ALWAYS_INLINE void cmov_aff(ge25519_aff *r, const ge25519_aff *p, unsigned char b) static inline void cmov_aff(ge25519_aff *r, const ge25519_aff *p, unsigned char b)
{ {
fe25519_cmov(&r->x, &p->x, b); fe25519_cmov(&r->x, &p->x, b);
fe25519_cmov(&r->y, &p->y, b); fe25519_cmov(&r->y, &p->y, b);
} }
static ZT_ALWAYS_INLINE unsigned char equal(signed char b,signed char c) static inline unsigned char equal(signed char b,signed char c)
{ {
unsigned char ub = b; unsigned char ub = b;
unsigned char uc = c; unsigned char uc = c;
@ -2207,7 +2207,7 @@ static ZT_ALWAYS_INLINE unsigned char equal(signed char b,signed char c)
return (unsigned char)y; return (unsigned char)y;
} }
static ZT_ALWAYS_INLINE unsigned char negative(signed char b) static inline unsigned char negative(signed char b)
{ {
unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
x >>= 63; /* 1: yes; 0: no */ x >>= 63; /* 1: yes; 0: no */
@ -2356,7 +2356,7 @@ static inline void ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s)
} }
} }
static ZT_ALWAYS_INLINE void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen) static inline void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen)
{ {
unsigned long long i; unsigned long long i;

View file

@ -32,7 +32,7 @@ public:
/** /**
* Generate a C25519 elliptic curve key pair * Generate a C25519 elliptic curve key pair
*/ */
static ZT_ALWAYS_INLINE void generate(uint8_t pub[ZT_C25519_PUBLIC_KEY_LEN],uint8_t priv[ZT_C25519_PRIVATE_KEY_LEN]) static inline void generate(uint8_t pub[ZT_C25519_PUBLIC_KEY_LEN],uint8_t priv[ZT_C25519_PRIVATE_KEY_LEN])
{ {
Utils::getSecureRandom(priv,ZT_C25519_PRIVATE_KEY_LEN); Utils::getSecureRandom(priv,ZT_C25519_PRIVATE_KEY_LEN);
_calcPubDH(pub,priv); _calcPubDH(pub,priv);
@ -53,7 +53,7 @@ public:
* @tparam F Type of 'cond' * @tparam F Type of 'cond'
*/ */
template<typename F> template<typename F>
static ZT_ALWAYS_INLINE void generateSatisfying(F cond,uint8_t pub[ZT_C25519_PUBLIC_KEY_LEN],uint8_t priv[ZT_C25519_PRIVATE_KEY_LEN]) static inline void generateSatisfying(F cond,uint8_t pub[ZT_C25519_PUBLIC_KEY_LEN],uint8_t priv[ZT_C25519_PRIVATE_KEY_LEN])
{ {
Utils::getSecureRandom(priv,ZT_C25519_PRIVATE_KEY_LEN); Utils::getSecureRandom(priv,ZT_C25519_PRIVATE_KEY_LEN);
_calcPubED(pub,priv); // do Ed25519 key -- bytes 32-63 of pub and priv _calcPubED(pub,priv); // do Ed25519 key -- bytes 32-63 of pub and priv

View file

@ -61,7 +61,7 @@ class Capability : public Credential
public: public:
static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_CAPABILITY; } static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_CAPABILITY; }
ZT_ALWAYS_INLINE Capability() : inline Capability() :
_nwid(0), _nwid(0),
_ts(0), _ts(0),
_id(0), _id(0),
@ -80,7 +80,7 @@ public:
* @param rules Network flow rules for this capability * @param rules Network flow rules for this capability
* @param ruleCount Number of flow rules * @param ruleCount Number of flow rules
*/ */
ZT_ALWAYS_INLINE Capability(uint32_t id,uint64_t nwid,int64_t ts,unsigned int mccl,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount) : inline Capability(uint32_t id,uint64_t nwid,int64_t ts,unsigned int mccl,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount) :
_nwid(nwid), _nwid(nwid),
_ts(ts), _ts(ts),
_id(id), _id(id),
@ -94,32 +94,32 @@ public:
/** /**
* @return Rules -- see ruleCount() for size of array * @return Rules -- see ruleCount() for size of array
*/ */
ZT_ALWAYS_INLINE const ZT_VirtualNetworkRule *rules() const { return _rules; } inline const ZT_VirtualNetworkRule *rules() const { return _rules; }
/** /**
* @return Number of rules in rules() * @return Number of rules in rules()
*/ */
ZT_ALWAYS_INLINE unsigned int ruleCount() const { return _ruleCount; } inline unsigned int ruleCount() const { return _ruleCount; }
/** /**
* @return ID and evaluation order of this capability in network * @return ID and evaluation order of this capability in network
*/ */
ZT_ALWAYS_INLINE uint32_t id() const { return _id; } inline uint32_t id() const { return _id; }
/** /**
* @return Network ID for which this capability was issued * @return Network ID for which this capability was issued
*/ */
ZT_ALWAYS_INLINE uint64_t networkId() const { return _nwid; } inline uint64_t networkId() const { return _nwid; }
/** /**
* @return Timestamp * @return Timestamp
*/ */
ZT_ALWAYS_INLINE int64_t timestamp() const { return _ts; } inline int64_t timestamp() const { return _ts; }
/** /**
* @return Last 'to' address in chain of custody * @return Last 'to' address in chain of custody
*/ */
ZT_ALWAYS_INLINE Address issuedTo() const inline Address issuedTo() const
{ {
Address i2; Address i2;
for(unsigned int i=0;i<ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH;++i) { for(unsigned int i=0;i<ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH;++i) {
@ -165,7 +165,7 @@ public:
* *
* @param RR Runtime environment to provide for peer lookup, etc. * @param RR Runtime environment to provide for peer lookup, etc.
*/ */
ZT_ALWAYS_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); } inline Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); }
template<unsigned int C> template<unsigned int C>
static inline void serializeRules(Buffer<C> &b,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount) static inline void serializeRules(Buffer<C> &b,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount)
@ -460,10 +460,10 @@ public:
} }
// Provides natural sort order by ID // Provides natural sort order by ID
ZT_ALWAYS_INLINE bool operator<(const Capability &c) const { return (_id < c._id); } inline bool operator<(const Capability &c) const { return (_id < c._id); }
ZT_ALWAYS_INLINE bool operator==(const Capability &c) const { return (memcmp(this,&c,sizeof(Capability)) == 0); } inline bool operator==(const Capability &c) const { return (memcmp(this,&c,sizeof(Capability)) == 0); }
ZT_ALWAYS_INLINE bool operator!=(const Capability &c) const { return (memcmp(this,&c,sizeof(Capability)) != 0); } inline bool operator!=(const Capability &c) const { return (memcmp(this,&c,sizeof(Capability)) != 0); }
private: private:
uint64_t _nwid; uint64_t _nwid;

View file

@ -69,7 +69,7 @@ class CertificateOfMembership : public Credential
friend class Credential; friend class Credential;
public: public:
static ZT_ALWAYS_INLINE Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_COM; } static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_COM; }
/** /**
* Reserved qualifier IDs * Reserved qualifier IDs
@ -101,7 +101,7 @@ public:
/** /**
* Create an empty certificate of membership * Create an empty certificate of membership
*/ */
ZT_ALWAYS_INLINE CertificateOfMembership() : inline CertificateOfMembership() :
_qualifierCount(0), _qualifierCount(0),
_signatureLength(0) {} _signatureLength(0) {}
@ -113,7 +113,7 @@ public:
* @param nwid Network ID * @param nwid Network ID
* @param issuedTo Certificate recipient * @param issuedTo Certificate recipient
*/ */
ZT_ALWAYS_INLINE CertificateOfMembership(uint64_t timestamp,uint64_t timestampMaxDelta,uint64_t nwid,const Address &issuedTo) inline CertificateOfMembership(uint64_t timestamp,uint64_t timestampMaxDelta,uint64_t nwid,const Address &issuedTo)
{ {
_qualifiers[0].id = COM_RESERVED_ID_TIMESTAMP; _qualifiers[0].id = COM_RESERVED_ID_TIMESTAMP;
_qualifiers[0].value = timestamp; _qualifiers[0].value = timestamp;
@ -135,22 +135,22 @@ public:
* @param startAt Position to start in buffer * @param startAt Position to start in buffer
*/ */
template<unsigned int C> template<unsigned int C>
ZT_ALWAYS_INLINE CertificateOfMembership(const Buffer<C> &b,unsigned int startAt = 0) { deserialize(b,startAt); } inline CertificateOfMembership(const Buffer<C> &b,unsigned int startAt = 0) { deserialize(b,startAt); }
/** /**
* @return True if there's something here * @return True if there's something here
*/ */
ZT_ALWAYS_INLINE operator bool() const { return (_qualifierCount != 0); } inline operator bool() const { return (_qualifierCount != 0); }
/** /**
* @return Credential ID, always 0 for COMs * @return Credential ID, always 0 for COMs
*/ */
ZT_ALWAYS_INLINE uint32_t id() const { return 0; } inline uint32_t id() const { return 0; }
/** /**
* @return Timestamp for this cert and maximum delta for timestamp * @return Timestamp for this cert and maximum delta for timestamp
*/ */
ZT_ALWAYS_INLINE int64_t timestamp() const inline int64_t timestamp() const
{ {
for(unsigned int i=0;i<_qualifierCount;++i) { for(unsigned int i=0;i<_qualifierCount;++i) {
if (_qualifiers[i].id == COM_RESERVED_ID_TIMESTAMP) if (_qualifiers[i].id == COM_RESERVED_ID_TIMESTAMP)
@ -162,7 +162,7 @@ public:
/** /**
* @return Address to which this cert was issued * @return Address to which this cert was issued
*/ */
ZT_ALWAYS_INLINE Address issuedTo() const inline Address issuedTo() const
{ {
for(unsigned int i=0;i<_qualifierCount;++i) { for(unsigned int i=0;i<_qualifierCount;++i) {
if (_qualifiers[i].id == COM_RESERVED_ID_ISSUED_TO) if (_qualifiers[i].id == COM_RESERVED_ID_ISSUED_TO)
@ -174,7 +174,7 @@ public:
/** /**
* @return Network ID for which this cert was issued * @return Network ID for which this cert was issued
*/ */
ZT_ALWAYS_INLINE uint64_t networkId() const inline uint64_t networkId() const
{ {
for(unsigned int i=0;i<_qualifierCount;++i) { for(unsigned int i=0;i<_qualifierCount;++i) {
if (_qualifiers[i].id == COM_RESERVED_ID_NETWORK_ID) if (_qualifiers[i].id == COM_RESERVED_ID_NETWORK_ID)
@ -211,7 +211,7 @@ public:
} }
} }
ZT_ALWAYS_INLINE void setQualifier(ReservedId id,uint64_t value,uint64_t maxDelta) { setQualifier((uint64_t)id,value,maxDelta); } inline void setQualifier(ReservedId id,uint64_t value,uint64_t maxDelta) { setQualifier((uint64_t)id,value,maxDelta); }
/** /**
* Compare two certificates for parameter agreement * Compare two certificates for parameter agreement
@ -294,17 +294,17 @@ public:
* @param RR Runtime environment for looking up peers * @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 * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
*/ */
ZT_ALWAYS_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); } inline Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); }
/** /**
* @return True if signed * @return True if signed
*/ */
ZT_ALWAYS_INLINE bool isSigned() const { return (_signedBy); } inline bool isSigned() const { return (_signedBy); }
/** /**
* @return Address that signed this certificate or null address if none * @return Address that signed this certificate or null address if none
*/ */
ZT_ALWAYS_INLINE const Address &signedBy() const { return _signedBy; } inline const Address &signedBy() const { return _signedBy; }
template<unsigned int C> template<unsigned int C>
inline void serialize(Buffer<C> &b) const inline void serialize(Buffer<C> &b) const
@ -369,7 +369,7 @@ public:
return (p - startAt); return (p - startAt);
} }
ZT_ALWAYS_INLINE bool operator==(const CertificateOfMembership &c) const inline bool operator==(const CertificateOfMembership &c) const
{ {
if (_signedBy != c._signedBy) if (_signedBy != c._signedBy)
return false; return false;
@ -385,7 +385,7 @@ public:
} }
return (memcmp(_signature,c._signature,_signatureLength) == 0); return (memcmp(_signature,c._signature,_signatureLength) == 0);
} }
ZT_ALWAYS_INLINE bool operator!=(const CertificateOfMembership &c) const { return (!(*this == c)); } inline bool operator!=(const CertificateOfMembership &c) const { return (!(*this == c)); }
private: private:
struct _Qualifier struct _Qualifier

View file

@ -46,7 +46,7 @@ class CertificateOfOwnership : public Credential
friend class Credential; friend class Credential;
public: public:
static ZT_ALWAYS_INLINE Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_COO; } static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_COO; }
enum Thing enum Thing
{ {
@ -56,12 +56,12 @@ public:
THING_IPV6_ADDRESS = 3 THING_IPV6_ADDRESS = 3
}; };
ZT_ALWAYS_INLINE CertificateOfOwnership() inline CertificateOfOwnership()
{ {
memset(reinterpret_cast<void *>(this),0,sizeof(CertificateOfOwnership)); memset(reinterpret_cast<void *>(this),0,sizeof(CertificateOfOwnership));
} }
ZT_ALWAYS_INLINE CertificateOfOwnership(const uint64_t nwid,const int64_t ts,const Address &issuedTo,const uint32_t id) inline CertificateOfOwnership(const uint64_t nwid,const int64_t ts,const Address &issuedTo,const uint32_t id)
{ {
memset(reinterpret_cast<void *>(this),0,sizeof(CertificateOfOwnership)); memset(reinterpret_cast<void *>(this),0,sizeof(CertificateOfOwnership));
_networkId = nwid; _networkId = nwid;
@ -70,19 +70,19 @@ public:
_issuedTo = issuedTo; _issuedTo = issuedTo;
} }
ZT_ALWAYS_INLINE uint64_t networkId() const { return _networkId; } inline uint64_t networkId() const { return _networkId; }
ZT_ALWAYS_INLINE int64_t timestamp() const { return _ts; } inline int64_t timestamp() const { return _ts; }
ZT_ALWAYS_INLINE uint32_t id() const { return _id; } inline uint32_t id() const { return _id; }
ZT_ALWAYS_INLINE const Address &issuedTo() const { return _issuedTo; } inline const Address &issuedTo() const { return _issuedTo; }
ZT_ALWAYS_INLINE const Address &signer() const { return _signedBy; } inline const Address &signer() const { return _signedBy; }
ZT_ALWAYS_INLINE const uint8_t *signature() const { return _signature; } inline const uint8_t *signature() const { return _signature; }
ZT_ALWAYS_INLINE unsigned int signatureLength() const { return _signatureLength; } inline unsigned int signatureLength() const { return _signatureLength; }
ZT_ALWAYS_INLINE unsigned int thingCount() const { return (unsigned int)_thingCount; } inline unsigned int thingCount() const { return (unsigned int)_thingCount; }
ZT_ALWAYS_INLINE Thing thingType(const unsigned int i) const { return (Thing)_thingTypes[i]; } inline Thing thingType(const unsigned int i) const { return (Thing)_thingTypes[i]; }
ZT_ALWAYS_INLINE const uint8_t *thingValue(const unsigned int i) const { return _thingValues[i]; } inline const uint8_t *thingValue(const unsigned int i) const { return _thingValues[i]; }
ZT_ALWAYS_INLINE bool owns(const InetAddress &ip) const inline bool owns(const InetAddress &ip) const
{ {
if (ip.ss_family == AF_INET) if (ip.ss_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);
@ -91,7 +91,7 @@ public:
return false; return false;
} }
ZT_ALWAYS_INLINE bool owns(const MAC &mac) const inline bool owns(const MAC &mac) const
{ {
uint8_t tmp[6]; uint8_t tmp[6];
mac.copyTo(tmp,6); mac.copyTo(tmp,6);
@ -136,7 +136,7 @@ public:
return false; return false;
} }
ZT_ALWAYS_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); } inline Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); }
template<unsigned int C> template<unsigned int C>
inline void serialize(Buffer<C> &b,const bool forSign = false) const inline void serialize(Buffer<C> &b,const bool forSign = false) const
@ -206,10 +206,10 @@ public:
} }
// Provides natural sort order by ID // Provides natural sort order by ID
ZT_ALWAYS_INLINE bool operator<(const CertificateOfOwnership &coo) const { return (_id < coo._id); } inline bool operator<(const CertificateOfOwnership &coo) const { return (_id < coo._id); }
ZT_ALWAYS_INLINE bool operator==(const CertificateOfOwnership &coo) const { return (memcmp(this,&coo,sizeof(CertificateOfOwnership)) == 0); } inline bool operator==(const CertificateOfOwnership &coo) const { return (memcmp(this,&coo,sizeof(CertificateOfOwnership)) == 0); }
ZT_ALWAYS_INLINE bool operator!=(const CertificateOfOwnership &coo) const { return (memcmp(this,&coo,sizeof(CertificateOfOwnership)) != 0); } inline bool operator!=(const CertificateOfOwnership &coo) const { return (memcmp(this,&coo,sizeof(CertificateOfOwnership)) != 0); }
private: private:
inline bool _owns(const Thing &t,const void *v,unsigned int l) const inline bool _owns(const Thing &t,const void *v,unsigned int l) const

View file

@ -138,16 +138,22 @@
#endif #endif
#if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__) #if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__)
#define ZT_ALWAYS_INLINE inline __attribute__((always_inline)) // #define inline __attribute__((always_inline))
#ifndef restrict
#define restrict __restrict__
#endif
#ifndef likely #ifndef likely
#define likely(x) __builtin_expect((x),1) #define likely(x) __builtin_expect((x),1)
#endif #endif
#ifndef unlikely #ifndef unlikely
#define unlikely(x) __builtin_expect((x),0) #define unlikely(x) __builtin_expect((x),0)
#endif #endif
#else #else /* not GCC-like */
#ifndef restrict
#define restrict
#endif
#ifndef likely #ifndef likely
#define ZT_ALWAYS_INLINE inline #define inline inline
#define likely(x) (x) #define likely(x) (x)
#endif #endif
#ifndef unlikely #ifndef unlikely
@ -197,6 +203,16 @@
*/ */
#define ZT_ADDRESS_RESERVED_PREFIX 0xff #define ZT_ADDRESS_RESERVED_PREFIX 0xff
/**
* Maximum DNS or URL name size for an Endpoint
*/
#define ZT_ENDPOINT_MAX_NAME_SIZE 256
/**
* Size of an identity hash (SHA384)
*/
#define ZT_IDENTITY_HASH_SIZE 48
/** /**
* Secure DNS name for ZeroTier's default root * Secure DNS name for ZeroTier's default root
* *

View file

@ -26,7 +26,7 @@
namespace ZeroTier { namespace ZeroTier {
template<typename CRED> template<typename CRED>
static ZT_ALWAYS_INLINE Credential::VerifyResult _credVerify(const RuntimeEnvironment *const RR,void *tPtr,CRED credential) static inline Credential::VerifyResult _credVerify(const RuntimeEnvironment *const RR,void *tPtr,CRED credential)
{ {
const Address signedBy(credential.signer()); const Address signedBy(credential.signer());
const uint64_t networkId = credential.networkId(); const uint64_t networkId = credential.networkId();

View file

@ -49,9 +49,9 @@ template<unsigned int C>
class Dictionary class Dictionary
{ {
public: public:
ZT_ALWAYS_INLINE Dictionary() { memset(_d,0,sizeof(_d)); } inline Dictionary() { memset(_d,0,sizeof(_d)); }
ZT_ALWAYS_INLINE Dictionary(const char *s) { this->load(s); } inline Dictionary(const char *s) { this->load(s); }
ZT_ALWAYS_INLINE Dictionary(const char *s,unsigned int len) inline Dictionary(const char *s,unsigned int len)
{ {
for(unsigned int i=0;i<C;++i) { for(unsigned int i=0;i<C;++i) {
if ((s)&&(i < len)) { if ((s)&&(i < len)) {
@ -62,15 +62,15 @@ public:
} }
_d[C - 1] = (char)0; _d[C - 1] = (char)0;
} }
ZT_ALWAYS_INLINE Dictionary(const Dictionary &d) { memcpy(_d,d._d,C); } inline Dictionary(const Dictionary &d) { memcpy(_d,d._d,C); }
ZT_ALWAYS_INLINE Dictionary &operator=(const Dictionary &d) inline Dictionary &operator=(const Dictionary &d)
{ {
memcpy(_d,d._d,C); memcpy(_d,d._d,C);
return *this; return *this;
} }
ZT_ALWAYS_INLINE operator bool() const { return (_d[0] != 0); } inline operator bool() const { return (_d[0] != 0); }
/** /**
* Load a dictionary from a C-string * Load a dictionary from a C-string
@ -78,7 +78,7 @@ public:
* @param s Dictionary in string form * @param s Dictionary in string form
* @return False if 's' was longer than our capacity * @return False if 's' was longer than our capacity
*/ */
ZT_ALWAYS_INLINE bool load(const char *s) inline bool load(const char *s)
{ {
for(unsigned int i=0;i<C;++i) { for(unsigned int i=0;i<C;++i) {
if (s) { if (s) {
@ -94,12 +94,12 @@ public:
/** /**
* Delete all entries * Delete all entries
*/ */
ZT_ALWAYS_INLINE void clear() { memset(_d,0,sizeof(_d)); } inline void clear() { memset(_d,0,sizeof(_d)); }
/** /**
* @return Size of dictionary in bytes not including terminating NULL * @return Size of dictionary in bytes not including terminating NULL
*/ */
ZT_ALWAYS_INLINE unsigned int sizeBytes() const inline unsigned int sizeBytes() const
{ {
for(unsigned int i=0;i<C;++i) { for(unsigned int i=0;i<C;++i) {
if (!_d[i]) if (!_d[i])
@ -217,7 +217,7 @@ public:
* @tparam BC Buffer capacity (usually inferred) * @tparam BC Buffer capacity (usually inferred)
*/ */
template<unsigned int BC> template<unsigned int BC>
ZT_ALWAYS_INLINE bool get(const char *key,Buffer<BC> &dest) const inline bool get(const char *key,Buffer<BC> &dest) const
{ {
const int r = this->get(key,const_cast<char *>(reinterpret_cast<const char *>(dest.data())),BC); const int r = this->get(key,const_cast<char *>(reinterpret_cast<const char *>(dest.data())),BC);
if (r >= 0) { if (r >= 0) {
@ -236,7 +236,7 @@ public:
* @param dfl Default value if not found in dictionary * @param dfl Default value if not found in dictionary
* @return Boolean value of key or 'dfl' if not found * @return Boolean value of key or 'dfl' if not found
*/ */
ZT_ALWAYS_INLINE bool getB(const char *key,bool dfl = false) const inline bool getB(const char *key,bool dfl = false) const
{ {
char tmp[4]; char tmp[4];
if (this->get(key,tmp,sizeof(tmp)) >= 0) if (this->get(key,tmp,sizeof(tmp)) >= 0)
@ -251,7 +251,7 @@ public:
* @param dfl Default value or 0 if unspecified * @param dfl Default value or 0 if unspecified
* @return Decoded hex UInt value or 'dfl' if not found * @return Decoded hex UInt value or 'dfl' if not found
*/ */
ZT_ALWAYS_INLINE uint64_t getUI(const char *key,uint64_t dfl = 0) const inline uint64_t getUI(const char *key,uint64_t dfl = 0) const
{ {
char tmp[128]; char tmp[128];
if (this->get(key,tmp,sizeof(tmp)) >= 1) if (this->get(key,tmp,sizeof(tmp)) >= 1)
@ -266,7 +266,7 @@ public:
* @param dfl Default value or 0 if unspecified * @param dfl Default value or 0 if unspecified
* @return Decoded hex UInt value or 'dfl' if not found * @return Decoded hex UInt value or 'dfl' if not found
*/ */
ZT_ALWAYS_INLINE int64_t getI(const char *key,int64_t dfl = 0) const inline int64_t getI(const char *key,int64_t dfl = 0) const
{ {
char tmp[128]; char tmp[128];
if (this->get(key,tmp,sizeof(tmp)) >= 1) if (this->get(key,tmp,sizeof(tmp)) >= 1)
@ -366,7 +366,7 @@ public:
/** /**
* Add a boolean as a '1' or a '0' * Add a boolean as a '1' or a '0'
*/ */
ZT_ALWAYS_INLINE bool add(const char *key,bool value) inline bool add(const char *key,bool value)
{ {
return this->add(key,(value) ? "1" : "0",1); return this->add(key,(value) ? "1" : "0",1);
} }
@ -374,7 +374,7 @@ public:
/** /**
* Add a 64-bit integer (unsigned) as a hex value * Add a 64-bit integer (unsigned) as a hex value
*/ */
ZT_ALWAYS_INLINE bool add(const char *key,uint64_t value) inline bool add(const char *key,uint64_t value)
{ {
char tmp[32]; char tmp[32];
return this->add(key,Utils::hex(value,tmp),-1); return this->add(key,Utils::hex(value,tmp),-1);
@ -383,7 +383,7 @@ public:
/** /**
* Add a 64-bit integer (unsigned) as a hex value * Add a 64-bit integer (unsigned) as a hex value
*/ */
ZT_ALWAYS_INLINE bool add(const char *key,int64_t value) inline bool add(const char *key,int64_t value)
{ {
char tmp[32]; char tmp[32];
if (value >= 0) { if (value >= 0) {
@ -397,7 +397,7 @@ public:
/** /**
* Add a 64-bit integer (unsigned) as a hex value * Add a 64-bit integer (unsigned) as a hex value
*/ */
ZT_ALWAYS_INLINE bool add(const char *key,const Address &a) inline bool add(const char *key,const Address &a)
{ {
char tmp[32]; char tmp[32];
return this->add(key,Utils::hex(a.toInt(),tmp),-1); return this->add(key,Utils::hex(a.toInt(),tmp),-1);
@ -409,7 +409,7 @@ public:
* @tparam BC Buffer capacity (usually inferred) * @tparam BC Buffer capacity (usually inferred)
*/ */
template<unsigned int BC> template<unsigned int BC>
ZT_ALWAYS_INLINE bool add(const char *key,const Buffer<BC> &value) inline bool add(const char *key,const Buffer<BC> &value)
{ {
return this->add(key,(const char *)value.data(),(int)value.size()); return this->add(key,(const char *)value.data(),(int)value.size());
} }
@ -418,7 +418,7 @@ public:
* @param key Key to check * @param key Key to check
* @return True if key is present * @return True if key is present
*/ */
ZT_ALWAYS_INLINE bool contains(const char *key) const inline bool contains(const char *key) const
{ {
char tmp[2]; char tmp[2];
return (this->get(key,tmp,2) >= 0); return (this->get(key,tmp,2) >= 0);
@ -427,10 +427,10 @@ public:
/** /**
* @return Value of C template parameter * @return Value of C template parameter
*/ */
ZT_ALWAYS_INLINE unsigned int capacity() const { return C; } inline unsigned int capacity() const { return C; }
ZT_ALWAYS_INLINE const char *data() const { return _d; } inline const char *data() const { return _d; }
ZT_ALWAYS_INLINE char *unsafeData() { return _d; } inline char *unsafeData() { return _d; }
private: private:
char _d[C]; char _d[C];

View file

@ -61,13 +61,13 @@ static EccPoint curve_G = CONCAT(Curve_G_, ECC_CURVE);
static uint64_t curve_n[NUM_ECC_DIGITS] = CONCAT(Curve_N_, ECC_CURVE); static uint64_t curve_n[NUM_ECC_DIGITS] = CONCAT(Curve_N_, ECC_CURVE);
// Use ZeroTier's secure PRNG // Use ZeroTier's secure PRNG
static ZT_ALWAYS_INLINE int getRandomNumber(uint64_t *p_vli) static inline int getRandomNumber(uint64_t *p_vli)
{ {
Utils::getSecureRandom(p_vli,ECC_BYTES); Utils::getSecureRandom(p_vli,ECC_BYTES);
return 1; return 1;
} }
static ZT_ALWAYS_INLINE void vli_clear(uint64_t *p_vli) static inline void vli_clear(uint64_t *p_vli)
{ {
uint i; uint i;
for(i=0; i<NUM_ECC_DIGITS; ++i) for(i=0; i<NUM_ECC_DIGITS; ++i)
@ -77,7 +77,7 @@ static ZT_ALWAYS_INLINE void vli_clear(uint64_t *p_vli)
} }
/* Returns 1 if p_vli == 0, 0 otherwise. */ /* Returns 1 if p_vli == 0, 0 otherwise. */
static ZT_ALWAYS_INLINE int vli_isZero(uint64_t *p_vli) static inline int vli_isZero(uint64_t *p_vli)
{ {
uint i; uint i;
for(i = 0; i < NUM_ECC_DIGITS; ++i) for(i = 0; i < NUM_ECC_DIGITS; ++i)
@ -91,13 +91,13 @@ static ZT_ALWAYS_INLINE int vli_isZero(uint64_t *p_vli)
} }
/* Returns nonzero if bit p_bit of p_vli is set. */ /* Returns nonzero if bit p_bit of p_vli is set. */
static ZT_ALWAYS_INLINE uint64_t vli_testBit(uint64_t *p_vli, uint p_bit) static inline uint64_t vli_testBit(uint64_t *p_vli, uint p_bit)
{ {
return (p_vli[p_bit/64] & ((uint64_t)1 << (p_bit % 64))); return (p_vli[p_bit/64] & ((uint64_t)1 << (p_bit % 64)));
} }
/* Counts the number of 64-bit "digits" in p_vli. */ /* Counts the number of 64-bit "digits" in p_vli. */
static ZT_ALWAYS_INLINE uint vli_numDigits(uint64_t *p_vli) static inline uint vli_numDigits(uint64_t *p_vli)
{ {
int i; int i;
/* Search from the end until we find a non-zero digit. /* Search from the end until we find a non-zero digit.
@ -110,7 +110,7 @@ static ZT_ALWAYS_INLINE uint vli_numDigits(uint64_t *p_vli)
} }
/* Counts the number of bits required for p_vli. */ /* Counts the number of bits required for p_vli. */
static ZT_ALWAYS_INLINE uint vli_numBits(uint64_t *p_vli) static inline uint vli_numBits(uint64_t *p_vli)
{ {
uint i; uint i;
uint64_t l_digit; uint64_t l_digit;
@ -131,7 +131,7 @@ static ZT_ALWAYS_INLINE uint vli_numBits(uint64_t *p_vli)
} }
/* Sets p_dest = p_src. */ /* Sets p_dest = p_src. */
static ZT_ALWAYS_INLINE void vli_set(uint64_t *p_dest, uint64_t *p_src) static inline void vli_set(uint64_t *p_dest, uint64_t *p_src)
{ {
uint i; uint i;
for(i=0; i<NUM_ECC_DIGITS; ++i) for(i=0; i<NUM_ECC_DIGITS; ++i)
@ -141,7 +141,7 @@ static ZT_ALWAYS_INLINE void vli_set(uint64_t *p_dest, uint64_t *p_src)
} }
/* Returns sign of p_left - p_right. */ /* Returns sign of p_left - p_right. */
static ZT_ALWAYS_INLINE int vli_cmp(uint64_t *p_left, uint64_t *p_right) static inline int vli_cmp(uint64_t *p_left, uint64_t *p_right)
{ {
int i; int i;
for(i = NUM_ECC_DIGITS-1; i >= 0; --i) for(i = NUM_ECC_DIGITS-1; i >= 0; --i)
@ -376,7 +376,7 @@ static inline void vli_square(uint64_t *p_result, uint64_t *p_left)
/* Computes p_result = (p_left + p_right) % p_mod. /* Computes p_result = (p_left + p_right) % p_mod.
Assumes that p_left < p_mod and p_right < p_mod, p_result != p_mod. */ Assumes that p_left < p_mod and p_right < p_mod, p_result != p_mod. */
static ZT_ALWAYS_INLINE void vli_modAdd(uint64_t *p_result, uint64_t *p_left, uint64_t *p_right, uint64_t *p_mod) static inline void vli_modAdd(uint64_t *p_result, uint64_t *p_left, uint64_t *p_right, uint64_t *p_mod)
{ {
uint64_t l_carry = vli_add(p_result, p_left, p_right); uint64_t l_carry = vli_add(p_result, p_left, p_right);
if(l_carry || vli_cmp(p_result, p_mod) >= 0) if(l_carry || vli_cmp(p_result, p_mod) >= 0)
@ -387,7 +387,7 @@ static ZT_ALWAYS_INLINE void vli_modAdd(uint64_t *p_result, uint64_t *p_left, ui
/* Computes p_result = (p_left - p_right) % p_mod. /* Computes p_result = (p_left - p_right) % p_mod.
Assumes that p_left < p_mod and p_right < p_mod, p_result != p_mod. */ Assumes that p_left < p_mod and p_right < p_mod, p_result != p_mod. */
static ZT_ALWAYS_INLINE void vli_modSub(uint64_t *p_result, uint64_t *p_left, uint64_t *p_right, uint64_t *p_mod) static inline void vli_modSub(uint64_t *p_result, uint64_t *p_left, uint64_t *p_right, uint64_t *p_mod)
{ {
uint64_t l_borrow = vli_sub(p_result, p_left, p_right); uint64_t l_borrow = vli_sub(p_result, p_left, p_right);
if(l_borrow) if(l_borrow)
@ -465,7 +465,7 @@ static inline void vli_mmod_fast(uint64_t *p_result, uint64_t *p_product)
//#endif //#endif
/* Computes p_result = (p_left * p_right) % curve_p. */ /* Computes p_result = (p_left * p_right) % curve_p. */
static ZT_ALWAYS_INLINE void vli_modMult_fast(uint64_t *p_result, uint64_t *p_left, uint64_t *p_right) static inline void vli_modMult_fast(uint64_t *p_result, uint64_t *p_left, uint64_t *p_right)
{ {
uint64_t l_product[2 * NUM_ECC_DIGITS]; uint64_t l_product[2 * NUM_ECC_DIGITS];
vli_mult(l_product, p_left, p_right); vli_mult(l_product, p_left, p_right);
@ -473,7 +473,7 @@ static ZT_ALWAYS_INLINE void vli_modMult_fast(uint64_t *p_result, uint64_t *p_le
} }
/* Computes p_result = p_left^2 % curve_p. */ /* Computes p_result = p_left^2 % curve_p. */
static ZT_ALWAYS_INLINE void vli_modSquare_fast(uint64_t *p_result, uint64_t *p_left) static inline void vli_modSquare_fast(uint64_t *p_result, uint64_t *p_left)
{ {
uint64_t l_product[2 * NUM_ECC_DIGITS]; uint64_t l_product[2 * NUM_ECC_DIGITS];
vli_square(l_product, p_left); vli_square(l_product, p_left);
@ -577,7 +577,7 @@ static inline void vli_modInv(uint64_t *p_result, uint64_t *p_input, uint64_t *p
/* ------ Point operations ------ */ /* ------ Point operations ------ */
/* Returns 1 if p_point is the point at infinity, 0 otherwise. */ /* Returns 1 if p_point is the point at infinity, 0 otherwise. */
static ZT_ALWAYS_INLINE int EccPoint_isZero(EccPoint *p_point) static inline int EccPoint_isZero(EccPoint *p_point)
{ {
return (vli_isZero(p_point->x) && vli_isZero(p_point->y)); return (vli_isZero(p_point->x) && vli_isZero(p_point->y));
} }
@ -636,7 +636,7 @@ static inline void EccPoint_double_jacobian(uint64_t *X1, uint64_t *Y1, uint64_t
} }
/* Modify (x1, y1) => (x1 * z^2, y1 * z^3) */ /* Modify (x1, y1) => (x1 * z^2, y1 * z^3) */
static ZT_ALWAYS_INLINE void apply_z(uint64_t *X1, uint64_t *Y1, uint64_t *Z) static inline void apply_z(uint64_t *X1, uint64_t *Y1, uint64_t *Z)
{ {
uint64_t t1[NUM_ECC_DIGITS]; uint64_t t1[NUM_ECC_DIGITS];
@ -773,7 +773,7 @@ static inline void EccPoint_mult(EccPoint *p_result, EccPoint *p_point, uint64_t
vli_set(p_result->y, Ry[0]); vli_set(p_result->y, Ry[0]);
} }
static ZT_ALWAYS_INLINE void ecc_bytes2native(uint64_t p_native[NUM_ECC_DIGITS], const uint8_t p_bytes[ECC_BYTES]) static inline void ecc_bytes2native(uint64_t p_native[NUM_ECC_DIGITS], const uint8_t p_bytes[ECC_BYTES])
{ {
unsigned i; unsigned i;
for(i=0; i<NUM_ECC_DIGITS; ++i) for(i=0; i<NUM_ECC_DIGITS; ++i)
@ -784,7 +784,7 @@ static ZT_ALWAYS_INLINE void ecc_bytes2native(uint64_t p_native[NUM_ECC_DIGITS],
} }
} }
static ZT_ALWAYS_INLINE void ecc_native2bytes(uint8_t p_bytes[ECC_BYTES], const uint64_t p_native[NUM_ECC_DIGITS]) static inline void ecc_native2bytes(uint8_t p_bytes[ECC_BYTES], const uint64_t p_native[NUM_ECC_DIGITS])
{ {
unsigned i; unsigned i;
for(i=0; i<NUM_ECC_DIGITS; ++i) for(i=0; i<NUM_ECC_DIGITS; ++i)
@ -962,7 +962,7 @@ static inline void vli_modMult(uint64_t *p_result, uint64_t *p_left, uint64_t *p
vli_set(p_result, l_product); vli_set(p_result, l_product);
} }
static ZT_ALWAYS_INLINE uint umax(uint a, uint b) static inline uint umax(uint a, uint b)
{ {
return (a > b ? a : b); return (a > b ? a : b);
} }

181
node/Endpoint.hpp Normal file
View file

@ -0,0 +1,181 @@
/*
* Copyright (c)2019 ZeroTier, Inc.
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file in the project's root directory.
*
* Change Date: 2023-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2.0 of the Apache License.
*/
/****/
#ifndef ZT_ENDPOINT_HPP
#define ZT_ENDPOINT_HPP
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "Constants.hpp"
#include "InetAddress.hpp"
#include "Address.hpp"
#include "Utils.hpp"
#define ZT_ENDPOINT_MARSHAL_SIZE_MAX (ZT_ENDPOINT_MAX_NAME_SIZE+4)
namespace ZeroTier {
/**
* Endpoint variant specifying some form of network endpoint
*/
class Endpoint
{
public:
enum Type
{
NIL = 0, // NIL value
SOCKADDR = 1, // InetAddress
DNSNAME = 2, // DNS name and port that resolves to InetAddress
ZEROTIER = 3, // ZeroTier Address (for relaying and meshy behavior)
URL = 4 // URL for http/https/ws/etc. (not implemented yet)
};
inline Endpoint() { memset(reinterpret_cast<void *>(this),0,sizeof(Endpoint)); }
inline Endpoint(const InetAddress &sa) : _t(SOCKADDR) { _v.sa = sa; }
inline Endpoint(const Address &zt,const uint8_t identityHash[ZT_IDENTITY_HASH_SIZE]) : _t(ZEROTIER) { _v.zt.a = zt.toInt(); memcpy(_v.zt.idh,identityHash,ZT_IDENTITY_HASH_SIZE); }
inline Endpoint(const char *name,const int port) : _t(DNSNAME) { Utils::scopy(_v.dns.name,sizeof(_v.dns.name),name); _v.dns.port = port; }
inline Endpoint(const char *url) : _t(URL) { Utils::scopy(_v.url,sizeof(_v.url),url); }
inline const InetAddress *sockaddr() const { return (_t == SOCKADDR) ? reinterpret_cast<const InetAddress *>(&_v.sa) : nullptr; }
inline const char *dnsName() const { return (_t == DNSNAME) ? _v.dns.name : nullptr; }
inline const int dnsPort() const { return (_t == DNSNAME) ? _v.dns.port : -1; }
inline Address ztAddress() const { return (_t == ZEROTIER) ? Address(_v.zt.a) : Address(); }
inline const uint8_t *ztIdentityHash() const { return (_t == ZEROTIER) ? _v.zt.idh : nullptr; }
inline const char *url() const { return (_t == URL) ? _v.url : nullptr; }
inline Type type() const { return _t; }
inline unsigned int marshal(uint8_t data[ZT_ENDPOINT_MARSHAL_SIZE_MAX])
{
unsigned int p;
switch(_t) {
case SOCKADDR:
data[0] = (uint8_t)SOCKADDR;
return 1 + reinterpret_cast<const InetAddress *>(&_v.sa)->marshal(data+1);
case DNSNAME:
data[0] = (uint8_t)DNSNAME;
p = 1;
for (;;) {
if ((data[p] = (uint8_t)_v.dns.name[p-1]) == 0)
break;
++p;
if (p == (ZT_ENDPOINT_MAX_NAME_SIZE+1))
return 0;
}
data[p++] = (uint8_t)((_v.dns.port >> 8) & 0xff);
data[p++] = (uint8_t)(_v.dns.port & 0xff);
return p;
case ZEROTIER:
data[0] = (uint8_t)ZEROTIER;
data[1] = (uint8_t)((_v.zt.a >> 32) & 0xff);
data[2] = (uint8_t)((_v.zt.a >> 24) & 0xff);
data[3] = (uint8_t)((_v.zt.a >> 16) & 0xff);
data[4] = (uint8_t)((_v.zt.a >> 8) & 0xff);
data[5] = (uint8_t)(_v.zt.a & 0xff);
memcpy(data + 6,_v.zt.idh,ZT_IDENTITY_HASH_SIZE);
return (ZT_IDENTITY_HASH_SIZE + 6);
case URL:
data[0] = (uint8_t)URL;
p = 1;
for (;;) {
if ((data[p] = (uint8_t)_v.url[p-1]) == 0)
break;
++p;
if (p == (ZT_ENDPOINT_MAX_NAME_SIZE+1))
return 0;
}
return p;
default:
data[0] = (uint8_t)NIL;
return 1;
}
}
inline bool unmarshal(const uint8_t *restrict data,const unsigned int len)
{
if (len == 0)
return false;
unsigned int p;
switch((Type)data[0]) {
case NIL:
_t = NIL;
return true;
case SOCKADDR:
_t = SOCKADDR;
return reinterpret_cast<InetAddress *>(&_v.sa)->unmarshal(data+1,len-1);
case DNSNAME:
if (len < 4)
return false;
_t = DNSNAME;
p = 1;
for (;;) {
if ((_v.dns.name[p-1] = (char)data[p]) == 0)
break;
++p;
if ((p >= (ZT_ENDPOINT_MAX_NAME_SIZE+1))||(p >= (len-2)))
return;
}
_v.dns.port = ((int)data[p++]) << 8;
_v.dns.port |= (int)data[p++];
return true;
case ZEROTIER:
if (len != (ZT_IDENTITY_HASH_SIZE + 6))
return false;
_t = ZEROTIER;
_v.zt.a = ((uint64_t)data[1]) << 32;
_v.zt.a |= ((uint64_t)data[2]) << 24;
_v.zt.a |= ((uint64_t)data[3]) << 16;
_v.zt.a |= ((uint64_t)data[4]) << 8;
_v.zt.a |= (uint64_t)data[5];
memcpy(_v.zt.idh,data + 6,ZT_IDENTITY_HASH_SIZE);
return true;
case URL:
if (len < 2)
return false;
_t = URL;
p = 1;
for (;;) {
if ((_v.url[p-1] = (char)data[p]) == 0)
break;
++p;
if ((p >= (ZT_ENDPOINT_MAX_NAME_SIZE+1))||(p >= len))
return;
}
return true;
}
return false;
}
private:
Type _t;
union {
struct sockaddr_storage sa;
struct {
char name[ZT_ENDPOINT_MAX_NAME_SIZE];
int port;
} dns;
struct {
uint64_t a;
uint8_t idh[ZT_IDENTITY_HASH_SIZE];
} zt;
char url[ZT_ENDPOINT_MAX_NAME_SIZE];
} _v;
};
} // namespace ZeroTier
#endif

View file

@ -46,9 +46,9 @@ public:
C25519ECC384 = 1 C25519ECC384 = 1
}; };
ZT_ALWAYS_INLINE EphemeralKey() : _priv(nullptr),_type(NONE) {} inline EphemeralKey() : _priv(nullptr),_type(NONE) {}
ZT_ALWAYS_INLINE ~EphemeralKey() inline ~EphemeralKey()
{ {
if (_priv) { if (_priv) {
Utils::burn(_priv,ZT_EPHEMERAL_KEY_TYPE_1_PRIVATE_SIZE); Utils::burn(_priv,ZT_EPHEMERAL_KEY_TYPE_1_PRIVATE_SIZE);
@ -56,10 +56,10 @@ public:
} }
} }
ZT_ALWAYS_INLINE Type type() const { return (Type)_type; } inline Type type() const { return (Type)_type; }
ZT_ALWAYS_INLINE bool hasPrivate() const { return (_priv != nullptr); } inline bool hasPrivate() const { return (_priv != nullptr); }
ZT_ALWAYS_INLINE void generate() inline void generate()
{ {
if (!_priv) if (!_priv)
_priv = new uint8_t[ZT_EPHEMERAL_KEY_TYPE_1_PRIVATE_SIZE]; _priv = new uint8_t[ZT_EPHEMERAL_KEY_TYPE_1_PRIVATE_SIZE];
@ -68,7 +68,7 @@ public:
_type = C25519ECC384; _type = C25519ECC384;
} }
ZT_ALWAYS_INLINE bool agree(const EphemeralKey &theirs,uint8_t key[ZT_PEER_SECRET_KEY_LENGTH]) const inline bool agree(const EphemeralKey &theirs,uint8_t key[ZT_PEER_SECRET_KEY_LENGTH]) const
{ {
if ((_priv)&&(_type == 1)) { if ((_priv)&&(_type == 1)) {
uint8_t rawkey[128],h[48]; uint8_t rawkey[128],h[48];
@ -82,7 +82,7 @@ public:
} }
template<unsigned int C> template<unsigned int C>
ZT_ALWAYS_INLINE void serialize(Buffer<C> &b) const inline void serialize(Buffer<C> &b) const
{ {
b.append(_type); b.append(_type);
if (_type == C25519ECC384) if (_type == C25519ECC384)
@ -90,7 +90,7 @@ public:
} }
template<unsigned int C> template<unsigned int C>
ZT_ALWAYS_INLINE unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0) inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
{ {
unsigned int p = startAt; unsigned int p = startAt;
delete [] _priv; delete [] _priv;

View file

@ -33,10 +33,10 @@ class Hashtable
private: private:
struct _Bucket struct _Bucket
{ {
ZT_ALWAYS_INLINE _Bucket(const K &k,const V &v) : k(k),v(v) {} inline _Bucket(const K &k,const V &v) : k(k),v(v) {}
ZT_ALWAYS_INLINE _Bucket(const K &k) : k(k),v() {} inline _Bucket(const K &k) : k(k),v() {}
ZT_ALWAYS_INLINE _Bucket(const _Bucket &b) : k(b.k),v(b.v) {} inline _Bucket(const _Bucket &b) : k(b.k),v(b.v) {}
ZT_ALWAYS_INLINE _Bucket &operator=(const _Bucket &b) { k = b.k; v = b.v; return *this; } inline _Bucket &operator=(const _Bucket &b) { k = b.k; v = b.v; return *this; }
_Bucket *next; // must be set manually for each _Bucket _Bucket *next; // must be set manually for each _Bucket
const K k; const K k;
V v; V v;
@ -56,7 +56,7 @@ public:
/** /**
* @param ht Hash table to iterate over * @param ht Hash table to iterate over
*/ */
ZT_ALWAYS_INLINE Iterator(Hashtable &ht) : inline Iterator(Hashtable &ht) :
_idx(0), _idx(0),
_ht(&ht), _ht(&ht),
_b(ht._t[0]) _b(ht._t[0])
@ -68,7 +68,7 @@ public:
* @param vptr Pointer to set to point to next value * @param vptr Pointer to set to point to next value
* @return True if kptr and vptr are set, false if no more entries * @return True if kptr and vptr are set, false if no more entries
*/ */
ZT_ALWAYS_INLINE bool next(K *&kptr,V *&vptr) inline bool next(K *&kptr,V *&vptr)
{ {
for(;;) { for(;;) {
if (_b) { if (_b) {
@ -94,7 +94,7 @@ public:
/** /**
* @param bc Initial capacity in buckets (default: 32, must be nonzero) * @param bc Initial capacity in buckets (default: 32, must be nonzero)
*/ */
ZT_ALWAYS_INLINE Hashtable(unsigned long bc = 32) : inline Hashtable(unsigned long bc = 32) :
_t(reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * bc))), _t(reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * bc))),
_bc(bc), _bc(bc),
_s(0) _s(0)
@ -105,7 +105,7 @@ public:
_t[i] = (_Bucket *)0; _t[i] = (_Bucket *)0;
} }
ZT_ALWAYS_INLINE Hashtable(const Hashtable<K,V> &ht) : inline Hashtable(const Hashtable<K,V> &ht) :
_t(reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * ht._bc))), _t(reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * ht._bc))),
_bc(ht._bc), _bc(ht._bc),
_s(ht._s) _s(ht._s)
@ -125,13 +125,13 @@ public:
} }
} }
ZT_ALWAYS_INLINE ~Hashtable() inline ~Hashtable()
{ {
this->clear(); this->clear();
::free(_t); ::free(_t);
} }
ZT_ALWAYS_INLINE Hashtable &operator=(const Hashtable<K,V> &ht) inline Hashtable &operator=(const Hashtable<K,V> &ht)
{ {
this->clear(); this->clear();
if (ht._s) { if (ht._s) {
@ -149,7 +149,7 @@ public:
/** /**
* Erase all entries * Erase all entries
*/ */
ZT_ALWAYS_INLINE void clear() inline void clear()
{ {
if (_s) { if (_s) {
for(unsigned long i=0;i<_bc;++i) { for(unsigned long i=0;i<_bc;++i) {
@ -168,7 +168,7 @@ public:
/** /**
* @return Vector of all keys * @return Vector of all keys
*/ */
ZT_ALWAYS_INLINE typename std::vector<K> keys() const inline typename std::vector<K> keys() const
{ {
typename std::vector<K> k; typename std::vector<K> k;
if (_s) { if (_s) {
@ -191,7 +191,7 @@ public:
* @tparam Type of V (generally inferred) * @tparam Type of V (generally inferred)
*/ */
template<typename C> template<typename C>
ZT_ALWAYS_INLINE void appendKeys(C &v) const inline void appendKeys(C &v) const
{ {
if (_s) { if (_s) {
for(unsigned long i=0;i<_bc;++i) { for(unsigned long i=0;i<_bc;++i) {
@ -207,7 +207,7 @@ public:
/** /**
* @return Vector of all entries (pairs of K,V) * @return Vector of all entries (pairs of K,V)
*/ */
ZT_ALWAYS_INLINE typename std::vector< std::pair<K,V> > entries() const inline typename std::vector< std::pair<K,V> > entries() const
{ {
typename std::vector< std::pair<K,V> > k; typename std::vector< std::pair<K,V> > k;
if (_s) { if (_s) {
@ -227,7 +227,7 @@ public:
* @param k Key * @param k Key
* @return Pointer to value or NULL if not found * @return Pointer to value or NULL if not found
*/ */
ZT_ALWAYS_INLINE V *get(const K k) inline V *get(const K k)
{ {
_Bucket *b = _t[_hc(k) % _bc]; _Bucket *b = _t[_hc(k) % _bc];
while (b) { while (b) {
@ -237,14 +237,14 @@ public:
} }
return (V *)0; return (V *)0;
} }
ZT_ALWAYS_INLINE const V *get(const K k) const { return const_cast<Hashtable *>(this)->get(k); } inline const V *get(const K k) const { return const_cast<Hashtable *>(this)->get(k); }
/** /**
* @param k Key * @param k Key
* @param v Value to fill with result * @param v Value to fill with result
* @return True if value was found and set (if false, v is not modified) * @return True if value was found and set (if false, v is not modified)
*/ */
ZT_ALWAYS_INLINE bool get(const K &k,V &v) const inline bool get(const K &k,V &v) const
{ {
_Bucket *b = _t[_hc(k) % _bc]; _Bucket *b = _t[_hc(k) % _bc];
while (b) { while (b) {
@ -261,7 +261,7 @@ public:
* @param k Key to check * @param k Key to check
* @return True if key is present * @return True if key is present
*/ */
ZT_ALWAYS_INLINE bool contains(const K &k) const inline bool contains(const K &k) const
{ {
_Bucket *b = _t[_hc(k) % _bc]; _Bucket *b = _t[_hc(k) % _bc];
while (b) { while (b) {
@ -276,7 +276,7 @@ public:
* @param k Key * @param k Key
* @return True if value was present * @return True if value was present
*/ */
ZT_ALWAYS_INLINE bool erase(const K &k) inline bool erase(const K &k)
{ {
const unsigned long bidx = _hc(k) % _bc; const unsigned long bidx = _hc(k) % _bc;
_Bucket *lastb = (_Bucket *)0; _Bucket *lastb = (_Bucket *)0;
@ -301,7 +301,7 @@ public:
* @param v Value * @param v Value
* @return Reference to value in table * @return Reference to value in table
*/ */
ZT_ALWAYS_INLINE V &set(const K &k,const V &v) inline V &set(const K &k,const V &v)
{ {
const unsigned long h = _hc(k); const unsigned long h = _hc(k);
unsigned long bidx = h % _bc; unsigned long bidx = h % _bc;
@ -331,7 +331,7 @@ public:
* @param k Key * @param k Key
* @return Value, possibly newly created * @return Value, possibly newly created
*/ */
ZT_ALWAYS_INLINE V &operator[](const K k) inline V &operator[](const K k)
{ {
const unsigned long h = _hc(k); const unsigned long h = _hc(k);
unsigned long bidx = h % _bc; unsigned long bidx = h % _bc;
@ -358,25 +358,25 @@ public:
/** /**
* @return Number of entries * @return Number of entries
*/ */
ZT_ALWAYS_INLINE unsigned long size() const { return _s; } inline unsigned long size() const { return _s; }
/** /**
* @return True if table is empty * @return True if table is empty
*/ */
ZT_ALWAYS_INLINE bool empty() const { return (_s == 0); } inline bool empty() const { return (_s == 0); }
private: private:
template<typename O> template<typename O>
static ZT_ALWAYS_INLINE unsigned long _hc(const O &obj) { return (unsigned long)obj.hashCode(); } static inline unsigned long _hc(const O &obj) { return (unsigned long)obj.hashCode(); }
static ZT_ALWAYS_INLINE unsigned long _hc(const uint64_t i) { return (unsigned long)(i ^ (i >> 32)); } static inline unsigned long _hc(const uint64_t i) { return (unsigned long)(i ^ (i >> 32)); }
static ZT_ALWAYS_INLINE unsigned long _hc(const uint32_t i) { return ((unsigned long)i * (unsigned long)0x9e3779b1); } static inline unsigned long _hc(const uint32_t i) { return ((unsigned long)i * (unsigned long)0x9e3779b1); }
static ZT_ALWAYS_INLINE unsigned long _hc(const uint16_t i) { return ((unsigned long)i * (unsigned long)0x9e3779b1); } static inline unsigned long _hc(const uint16_t i) { return ((unsigned long)i * (unsigned long)0x9e3779b1); }
static ZT_ALWAYS_INLINE unsigned long _hc(const int i) { return ((unsigned long)i * (unsigned long)0x9e3379b1); } static inline unsigned long _hc(const int i) { return ((unsigned long)i * (unsigned long)0x9e3379b1); }
static ZT_ALWAYS_INLINE unsigned long _hc(void *p) { return ((unsigned long)((uintptr_t)p) * (unsigned long)0x9e3779b1); } static inline unsigned long _hc(void *p) { return ((unsigned long)((uintptr_t)p) * (unsigned long)0x9e3779b1); }
static ZT_ALWAYS_INLINE unsigned long _hc(const void *p) { return ((unsigned long)((uintptr_t)p) * (unsigned long)0x9e3779b1); } static inline unsigned long _hc(const void *p) { return ((unsigned long)((uintptr_t)p) * (unsigned long)0x9e3779b1); }
ZT_ALWAYS_INLINE void _grow() inline void _grow()
{ {
const unsigned long nc = _bc * 2; const unsigned long nc = _bc * 2;
_Bucket **nt = reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * nc)); _Bucket **nt = reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * nc));

View file

@ -51,8 +51,8 @@ public:
P384 = ZT_CRYPTO_ALG_P384 // Type 1 -- NIST P-384 with linked Curve25519/Ed25519 secondaries (2.x+) P384 = ZT_CRYPTO_ALG_P384 // Type 1 -- NIST P-384 with linked Curve25519/Ed25519 secondaries (2.x+)
}; };
ZT_ALWAYS_INLINE Identity() { memset(reinterpret_cast<void *>(this),0,sizeof(Identity)); } inline Identity() { memset(reinterpret_cast<void *>(this),0,sizeof(Identity)); }
ZT_ALWAYS_INLINE ~Identity() { Utils::burn(reinterpret_cast<void *>(&this->_priv),sizeof(this->_priv)); } inline ~Identity() { Utils::burn(reinterpret_cast<void *>(&this->_priv),sizeof(this->_priv)); }
/** /**
* Construct identity from string * Construct identity from string
@ -62,20 +62,20 @@ public:
* *
* @param str Identity in canonical string format * @param str Identity in canonical string format
*/ */
ZT_ALWAYS_INLINE Identity(const char *str) { fromString(str); } inline Identity(const char *str) { fromString(str); }
template<unsigned int C> template<unsigned int C>
ZT_ALWAYS_INLINE Identity(const Buffer<C> &b,unsigned int startAt = 0) { deserialize(b,startAt); } inline Identity(const Buffer<C> &b,unsigned int startAt = 0) { deserialize(b,startAt); }
/** /**
* Set identity to NIL value (all zero) * Set identity to NIL value (all zero)
*/ */
ZT_ALWAYS_INLINE void zero() { memset(reinterpret_cast<void *>(this),0,sizeof(Identity)); } inline void zero() { memset(reinterpret_cast<void *>(this),0,sizeof(Identity)); }
/** /**
* @return Identity type (undefined if identity is null or invalid) * @return Identity type (undefined if identity is null or invalid)
*/ */
ZT_ALWAYS_INLINE Type type() const { return _type; } inline Type type() const { return _type; }
/** /**
* Generate a new identity (address, key pair) * Generate a new identity (address, key pair)
@ -96,7 +96,7 @@ public:
/** /**
* @return True if this identity contains a private key * @return True if this identity contains a private key
*/ */
ZT_ALWAYS_INLINE bool hasPrivate() const { return _hasPrivate; } inline bool hasPrivate() const { return _hasPrivate; }
/** /**
* This generates a SHA384 hash of this identity's keys. * This generates a SHA384 hash of this identity's keys.
@ -104,7 +104,7 @@ public:
* @param h Buffer to receive SHA384 of public key(s) * @param h Buffer to receive SHA384 of public key(s)
* @param includePrivate If true, hash private key(s) as well * @param includePrivate If true, hash private key(s) as well
*/ */
ZT_ALWAYS_INLINE bool hash(uint8_t h[48],const bool includePrivate = false) const inline bool hash(uint8_t h[48],const bool includePrivate = false) const
{ {
switch(_type) { switch(_type) {
@ -136,7 +136,7 @@ public:
* @param siglen Length of buffer * @param siglen Length of buffer
* @return Number of bytes actually written to sig or 0 on error * @return Number of bytes actually written to sig or 0 on error
*/ */
ZT_ALWAYS_INLINE unsigned int sign(const void *data,unsigned int len,void *sig,unsigned int siglen) const inline unsigned int sign(const void *data,unsigned int len,void *sig,unsigned int siglen) const
{ {
if (_hasPrivate) { if (_hasPrivate) {
switch(_type) { switch(_type) {
@ -171,7 +171,7 @@ public:
* @param siglen Length of signature in bytes * @param siglen Length of signature in bytes
* @return True if signature validates and data integrity checks * @return True if signature validates and data integrity checks
*/ */
ZT_ALWAYS_INLINE bool verify(const void *data,unsigned int len,const void *sig,unsigned int siglen) const inline bool verify(const void *data,unsigned int len,const void *sig,unsigned int siglen) const
{ {
switch(_type) { switch(_type) {
@ -199,7 +199,7 @@ public:
* @param key Result parameter to fill with key bytes * @param key Result parameter to fill with key bytes
* @return Was agreement successful? * @return Was agreement successful?
*/ */
ZT_ALWAYS_INLINE bool agree(const Identity &id,uint8_t key[ZT_PEER_SECRET_KEY_LENGTH]) const inline bool agree(const Identity &id,uint8_t key[ZT_PEER_SECRET_KEY_LENGTH]) const
{ {
uint8_t rawkey[128]; uint8_t rawkey[128];
uint8_t h[64]; uint8_t h[64];
@ -239,7 +239,7 @@ public:
/** /**
* @return This identity's address * @return This identity's address
*/ */
ZT_ALWAYS_INLINE const Address &address() const { return _address; } inline const Address &address() const { return _address; }
/** /**
* Serialize this identity (binary) * Serialize this identity (binary)
@ -248,7 +248,7 @@ public:
* @param includePrivate If true, include private key component (if present) (default: false) * @param includePrivate If true, include private key component (if present) (default: false)
*/ */
template<unsigned int C> template<unsigned int C>
ZT_ALWAYS_INLINE void serialize(Buffer<C> &b,bool includePrivate = false) const inline void serialize(Buffer<C> &b,bool includePrivate = false) const
{ {
_address.appendTo(b); _address.appendTo(b);
switch(_type) { switch(_type) {
@ -291,7 +291,7 @@ public:
* @return Length of serialized data read from buffer * @return Length of serialized data read from buffer
*/ */
template<unsigned int C> template<unsigned int C>
ZT_ALWAYS_INLINE unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0) inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
{ {
_hasPrivate = false; _hasPrivate = false;
unsigned int p = startAt; unsigned int p = startAt;
@ -366,9 +366,9 @@ public:
/** /**
* @return True if this identity contains something * @return True if this identity contains something
*/ */
ZT_ALWAYS_INLINE operator bool() const { return (_address); } inline operator bool() const { return (_address); }
ZT_ALWAYS_INLINE bool operator==(const Identity &id) const inline bool operator==(const Identity &id) const
{ {
if ((_address == id._address)&&(_type == id._type)) { if ((_address == id._address)&&(_type == id._type)) {
switch(_type) { switch(_type) {
@ -379,7 +379,7 @@ public:
} }
return false; return false;
} }
ZT_ALWAYS_INLINE bool operator<(const Identity &id) const inline bool operator<(const Identity &id) const
{ {
if (_address < id._address) if (_address < id._address)
return true; return true;
@ -396,12 +396,12 @@ public:
} }
return false; return false;
} }
ZT_ALWAYS_INLINE bool operator!=(const Identity &id) const { return !(*this == id); } inline bool operator!=(const Identity &id) const { return !(*this == id); }
ZT_ALWAYS_INLINE bool operator>(const Identity &id) const { return (id < *this); } inline bool operator>(const Identity &id) const { return (id < *this); }
ZT_ALWAYS_INLINE bool operator<=(const Identity &id) const { return !(id < *this); } inline bool operator<=(const Identity &id) const { return !(id < *this); }
ZT_ALWAYS_INLINE bool operator>=(const Identity &id) const { return !(*this < id); } inline bool operator>=(const Identity &id) const { return !(*this < id); }
ZT_ALWAYS_INLINE unsigned long hashCode() const { return ((unsigned long)_address.toInt() + (unsigned long)_pub.c25519[0] + (unsigned long)_pub.c25519[1] + (unsigned long)_pub.c25519[2]); } inline unsigned long hashCode() const { return ((unsigned long)_address.toInt() + (unsigned long)_pub.c25519[0] + (unsigned long)_pub.c25519[1] + (unsigned long)_pub.c25519[2]); }
private: private:
Address _address; Address _address;

View file

@ -39,6 +39,8 @@ namespace ZeroTier {
namespace { namespace {
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Implementation of each protocol verb //
//////////////////////////////////////////////////////////////////////////////
static void _sendErrorNeedCredentials(IncomingPacket &pkt,const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer,const uint64_t nwid,const SharedPtr<Path> &path) static void _sendErrorNeedCredentials(IncomingPacket &pkt,const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer,const uint64_t nwid,const SharedPtr<Path> &path)
{ {
@ -51,7 +53,7 @@ static void _sendErrorNeedCredentials(IncomingPacket &pkt,const RuntimeEnvironme
path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now()); path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now());
} }
static ZT_ALWAYS_INLINE bool _doHELLO(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const bool alreadyAuthenticated,const SharedPtr<Path> &path) static inline bool _doHELLO(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const bool alreadyAuthenticated,const SharedPtr<Path> &path)
{ {
const int64_t now = RR->node->now(); const int64_t now = RR->node->now();
@ -180,15 +182,15 @@ static ZT_ALWAYS_INLINE bool _doHELLO(IncomingPacket &pkt,const RuntimeEnvironme
return true; return true;
} }
static ZT_ALWAYS_INLINE bool _doACK(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path) static inline bool _doACK(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path)
{ {
} }
static ZT_ALWAYS_INLINE bool _doQOS_MEASUREMENT(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path) static inline bool _doQOS_MEASUREMENT(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path)
{ {
} }
static ZT_ALWAYS_INLINE bool _doERROR(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path) static inline bool _doERROR(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path)
{ {
const Packet::Verb inReVerb = (Packet::Verb)pkt[ZT_PROTO_VERB_ERROR_IDX_IN_RE_VERB]; const Packet::Verb inReVerb = (Packet::Verb)pkt[ZT_PROTO_VERB_ERROR_IDX_IN_RE_VERB];
const uint64_t inRePacketId = pkt.at<uint64_t>(ZT_PROTO_VERB_ERROR_IDX_IN_RE_PACKET_ID); const uint64_t inRePacketId = pkt.at<uint64_t>(ZT_PROTO_VERB_ERROR_IDX_IN_RE_PACKET_ID);
@ -250,7 +252,7 @@ static ZT_ALWAYS_INLINE bool _doERROR(IncomingPacket &pkt,const RuntimeEnvironme
return true; return true;
} }
static ZT_ALWAYS_INLINE bool _doOK(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path) static inline bool _doOK(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path)
{ {
const Packet::Verb inReVerb = (Packet::Verb)pkt[ZT_PROTO_VERB_OK_IDX_IN_RE_VERB]; const Packet::Verb inReVerb = (Packet::Verb)pkt[ZT_PROTO_VERB_OK_IDX_IN_RE_VERB];
const uint64_t inRePacketId = pkt.at<uint64_t>(ZT_PROTO_VERB_OK_IDX_IN_RE_PACKET_ID); const uint64_t inRePacketId = pkt.at<uint64_t>(ZT_PROTO_VERB_OK_IDX_IN_RE_PACKET_ID);
@ -317,7 +319,7 @@ static ZT_ALWAYS_INLINE bool _doOK(IncomingPacket &pkt,const RuntimeEnvironment
return true; return true;
} }
static ZT_ALWAYS_INLINE bool _doWHOIS(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path) static inline bool _doWHOIS(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path)
{ {
if (!peer->rateGateInboundWhoisRequest(RR->node->now())) if (!peer->rateGateInboundWhoisRequest(RR->node->now()))
return true; return true;
@ -352,7 +354,7 @@ static ZT_ALWAYS_INLINE bool _doWHOIS(IncomingPacket &pkt,const RuntimeEnvironme
return true; return true;
} }
static ZT_ALWAYS_INLINE bool _doRENDEZVOUS(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path) static inline bool _doRENDEZVOUS(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path)
{ {
if (RR->topology->isRoot(peer->identity())) { if (RR->topology->isRoot(peer->identity())) {
const Address with(pkt.field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); const Address with(pkt.field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
@ -374,7 +376,7 @@ static ZT_ALWAYS_INLINE bool _doRENDEZVOUS(IncomingPacket &pkt,const RuntimeEnvi
return true; return true;
} }
static ZT_ALWAYS_INLINE bool _doFRAME(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path) static inline bool _doFRAME(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path)
{ {
const uint64_t nwid = pkt.at<uint64_t>(ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID); const uint64_t nwid = pkt.at<uint64_t>(ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID);
const SharedPtr<Network> network(RR->node->network(nwid)); const SharedPtr<Network> network(RR->node->network(nwid));
@ -397,7 +399,7 @@ static ZT_ALWAYS_INLINE bool _doFRAME(IncomingPacket &pkt,const RuntimeEnvironme
return true; return true;
} }
static ZT_ALWAYS_INLINE bool _doEXT_FRAME(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path) static inline bool _doEXT_FRAME(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path)
{ {
const uint64_t nwid = pkt.at<uint64_t>(ZT_PROTO_VERB_EXT_FRAME_IDX_NETWORK_ID); const uint64_t nwid = pkt.at<uint64_t>(ZT_PROTO_VERB_EXT_FRAME_IDX_NETWORK_ID);
const SharedPtr<Network> network(RR->node->network(nwid)); const SharedPtr<Network> network(RR->node->network(nwid));
@ -475,7 +477,7 @@ static ZT_ALWAYS_INLINE bool _doEXT_FRAME(IncomingPacket &pkt,const RuntimeEnvir
return true; return true;
} }
static ZT_ALWAYS_INLINE bool _doECHO(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path) static inline bool _doECHO(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path)
{ {
if (!peer->rateGateEchoRequest(RR->node->now())) if (!peer->rateGateEchoRequest(RR->node->now()))
return true; return true;
@ -494,7 +496,7 @@ static ZT_ALWAYS_INLINE bool _doECHO(IncomingPacket &pkt,const RuntimeEnvironmen
return true; return true;
} }
static ZT_ALWAYS_INLINE bool _doNETWORK_CREDENTIALS(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path) static inline bool _doNETWORK_CREDENTIALS(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path)
{ {
if (!peer->rateGateCredentialsReceived(RR->node->now())) if (!peer->rateGateCredentialsReceived(RR->node->now()))
return true; return true;
@ -576,7 +578,7 @@ static ZT_ALWAYS_INLINE bool _doNETWORK_CREDENTIALS(IncomingPacket &pkt,const Ru
return true; return true;
} }
static ZT_ALWAYS_INLINE bool _doNETWORK_CONFIG_REQUEST(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path) static inline bool _doNETWORK_CONFIG_REQUEST(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path)
{ {
const uint64_t nwid = pkt.at<uint64_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID); const uint64_t nwid = pkt.at<uint64_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID);
const unsigned int hopCount = pkt.hops(); const unsigned int hopCount = pkt.hops();
@ -602,7 +604,7 @@ static ZT_ALWAYS_INLINE bool _doNETWORK_CONFIG_REQUEST(IncomingPacket &pkt,const
return true; return true;
} }
static ZT_ALWAYS_INLINE bool _doNETWORK_CONFIG(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path) static inline bool _doNETWORK_CONFIG(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path)
{ {
const SharedPtr<Network> network(RR->node->network(pkt.at<uint64_t>(ZT_PACKET_IDX_PAYLOAD))); const SharedPtr<Network> network(RR->node->network(pkt.at<uint64_t>(ZT_PACKET_IDX_PAYLOAD)));
if (network) { if (network) {
@ -621,7 +623,7 @@ static ZT_ALWAYS_INLINE bool _doNETWORK_CONFIG(IncomingPacket &pkt,const Runtime
return true; return true;
} }
static ZT_ALWAYS_INLINE bool _doMULTICAST_GATHER(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path) static inline bool _doMULTICAST_GATHER(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path)
{ {
const uint64_t nwid = pkt.at<uint64_t>(ZT_PROTO_VERB_MULTICAST_GATHER_IDX_NETWORK_ID); const uint64_t nwid = pkt.at<uint64_t>(ZT_PROTO_VERB_MULTICAST_GATHER_IDX_NETWORK_ID);
const unsigned int flags = pkt[ZT_PROTO_VERB_MULTICAST_GATHER_IDX_FLAGS]; const unsigned int flags = pkt[ZT_PROTO_VERB_MULTICAST_GATHER_IDX_FLAGS];
@ -669,7 +671,7 @@ static ZT_ALWAYS_INLINE bool _doMULTICAST_GATHER(IncomingPacket &pkt,const Runti
return true; return true;
} }
static ZT_ALWAYS_INLINE bool _doPUSH_DIRECT_PATHS(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path) static inline bool _doPUSH_DIRECT_PATHS(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path)
{ {
const int64_t now = RR->node->now(); const int64_t now = RR->node->now();
@ -719,7 +721,7 @@ static ZT_ALWAYS_INLINE bool _doPUSH_DIRECT_PATHS(IncomingPacket &pkt,const Runt
return true; return true;
} }
static ZT_ALWAYS_INLINE bool _doUSER_MESSAGE(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path) static inline bool _doUSER_MESSAGE(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr<Peer> &peer,const SharedPtr<Path> &path)
{ {
if (likely(pkt.size() >= (ZT_PACKET_IDX_PAYLOAD + 8))) { if (likely(pkt.size() >= (ZT_PACKET_IDX_PAYLOAD + 8))) {
ZT_UserMessage um; ZT_UserMessage um;

View file

@ -46,7 +46,7 @@ class Network;
class IncomingPacket : public Packet class IncomingPacket : public Packet
{ {
public: public:
ZT_ALWAYS_INLINE IncomingPacket() : Packet(),_receiveTime(0),_path() {} inline IncomingPacket() : Packet(),_receiveTime(0),_path() {}
/** /**
* Create a new packet-in-decode * Create a new packet-in-decode
@ -57,7 +57,7 @@ public:
* @param now Current time * @param now Current time
* @throws std::out_of_range Range error processing packet * @throws std::out_of_range Range error processing packet
*/ */
ZT_ALWAYS_INLINE IncomingPacket(const void *data,unsigned int len,const SharedPtr<Path> &path,int64_t now) : inline IncomingPacket(const void *data,unsigned int len,const SharedPtr<Path> &path,int64_t now) :
Packet(data,len), Packet(data,len),
_receiveTime(now), _receiveTime(now),
_path(path) _path(path)
@ -73,7 +73,7 @@ public:
* @param now Current time * @param now Current time
* @throws std::out_of_range Range error processing packet * @throws std::out_of_range Range error processing packet
*/ */
ZT_ALWAYS_INLINE void init(const void *data,unsigned int len,const SharedPtr<Path> &path,int64_t now) inline void init(const void *data,unsigned int len,const SharedPtr<Path> &path,int64_t now)
{ {
copyFrom(data,len); copyFrom(data,len);
_receiveTime = now; _receiveTime = now;
@ -98,7 +98,7 @@ public:
/** /**
* @return Time of packet receipt / start of decode * @return Time of packet receipt / start of decode
*/ */
ZT_ALWAYS_INLINE uint64_t receiveTime() const { return _receiveTime; } inline uint64_t receiveTime() const { return _receiveTime; }
private: private:
uint64_t _receiveTime; uint64_t _receiveTime;

View file

@ -79,55 +79,55 @@ struct InetAddress : public sockaddr_storage
// but this is safe to put here. // but this is safe to put here.
struct Hasher struct Hasher
{ {
ZT_ALWAYS_INLINE std::size_t operator()(const InetAddress &a) const { return (std::size_t)a.hashCode(); } inline std::size_t operator()(const InetAddress &a) const { return (std::size_t)a.hashCode(); }
}; };
ZT_ALWAYS_INLINE InetAddress() { memset(this,0,sizeof(InetAddress)); } inline InetAddress() { memset(this,0,sizeof(InetAddress)); }
ZT_ALWAYS_INLINE InetAddress(const InetAddress &a) { memcpy(this,&a,sizeof(InetAddress)); } inline InetAddress(const InetAddress &a) { memcpy(this,&a,sizeof(InetAddress)); }
ZT_ALWAYS_INLINE InetAddress(const InetAddress *a) { memcpy(this,a,sizeof(InetAddress)); } inline InetAddress(const InetAddress *a) { memcpy(this,a,sizeof(InetAddress)); }
ZT_ALWAYS_INLINE InetAddress(const struct sockaddr_storage &ss) { *this = ss; } inline InetAddress(const struct sockaddr_storage &ss) { *this = ss; }
ZT_ALWAYS_INLINE InetAddress(const struct sockaddr_storage *ss) { *this = ss; } inline InetAddress(const struct sockaddr_storage *ss) { *this = ss; }
ZT_ALWAYS_INLINE InetAddress(const struct sockaddr &sa) { *this = sa; } inline InetAddress(const struct sockaddr &sa) { *this = sa; }
ZT_ALWAYS_INLINE InetAddress(const struct sockaddr *sa) { *this = sa; } inline InetAddress(const struct sockaddr *sa) { *this = sa; }
ZT_ALWAYS_INLINE InetAddress(const struct sockaddr_in &sa) { *this = sa; } inline InetAddress(const struct sockaddr_in &sa) { *this = sa; }
ZT_ALWAYS_INLINE InetAddress(const struct sockaddr_in *sa) { *this = sa; } inline InetAddress(const struct sockaddr_in *sa) { *this = sa; }
ZT_ALWAYS_INLINE InetAddress(const struct sockaddr_in6 &sa) { *this = sa; } inline InetAddress(const struct sockaddr_in6 &sa) { *this = sa; }
ZT_ALWAYS_INLINE InetAddress(const struct sockaddr_in6 *sa) { *this = sa; } inline InetAddress(const struct sockaddr_in6 *sa) { *this = sa; }
ZT_ALWAYS_INLINE InetAddress(const void *ipBytes,unsigned int ipLen,unsigned int port) { this->set(ipBytes,ipLen,port); } inline InetAddress(const void *ipBytes,unsigned int ipLen,unsigned int port) { this->set(ipBytes,ipLen,port); }
ZT_ALWAYS_INLINE InetAddress(const uint32_t ipv4,unsigned int port) { this->set(&ipv4,4,port); } inline InetAddress(const uint32_t ipv4,unsigned int port) { this->set(&ipv4,4,port); }
ZT_ALWAYS_INLINE InetAddress(const char *ipSlashPort) { this->fromString(ipSlashPort); } inline InetAddress(const char *ipSlashPort) { this->fromString(ipSlashPort); }
ZT_ALWAYS_INLINE void clear() { memset(this,0,sizeof(InetAddress)); } inline void clear() { memset(this,0,sizeof(InetAddress)); }
ZT_ALWAYS_INLINE InetAddress &operator=(const InetAddress &a) inline InetAddress &operator=(const InetAddress &a)
{ {
if (&a != this) if (&a != this)
memcpy(this,&a,sizeof(InetAddress)); memcpy(this,&a,sizeof(InetAddress));
return *this; return *this;
} }
ZT_ALWAYS_INLINE InetAddress &operator=(const InetAddress *a) inline InetAddress &operator=(const InetAddress *a)
{ {
if (a != this) if (a != this)
memcpy(this,a,sizeof(InetAddress)); memcpy(this,a,sizeof(InetAddress));
return *this; return *this;
} }
ZT_ALWAYS_INLINE InetAddress &operator=(const struct sockaddr_storage &ss) inline InetAddress &operator=(const struct sockaddr_storage &ss)
{ {
if (reinterpret_cast<const InetAddress *>(&ss) != this) if (reinterpret_cast<const InetAddress *>(&ss) != this)
memcpy(this,&ss,sizeof(InetAddress)); memcpy(this,&ss,sizeof(InetAddress));
return *this; return *this;
} }
ZT_ALWAYS_INLINE InetAddress &operator=(const struct sockaddr_storage *ss) inline InetAddress &operator=(const struct sockaddr_storage *ss)
{ {
if (reinterpret_cast<const InetAddress *>(ss) != this) if (reinterpret_cast<const InetAddress *>(ss) != this)
memcpy(this,ss,sizeof(InetAddress)); memcpy(this,ss,sizeof(InetAddress));
return *this; return *this;
} }
ZT_ALWAYS_INLINE InetAddress &operator=(const struct sockaddr_in &sa) inline InetAddress &operator=(const struct sockaddr_in &sa)
{ {
if (reinterpret_cast<const InetAddress *>(&sa) != this) { if (reinterpret_cast<const InetAddress *>(&sa) != this) {
memset(this,0,sizeof(InetAddress)); memset(this,0,sizeof(InetAddress));
@ -136,7 +136,7 @@ struct InetAddress : public sockaddr_storage
return *this; return *this;
} }
ZT_ALWAYS_INLINE InetAddress &operator=(const struct sockaddr_in *sa) inline InetAddress &operator=(const struct sockaddr_in *sa)
{ {
if (reinterpret_cast<const InetAddress *>(sa) != this) { if (reinterpret_cast<const InetAddress *>(sa) != this) {
memset(this,0,sizeof(InetAddress)); memset(this,0,sizeof(InetAddress));
@ -145,7 +145,7 @@ struct InetAddress : public sockaddr_storage
return *this; return *this;
} }
ZT_ALWAYS_INLINE InetAddress &operator=(const struct sockaddr_in6 &sa) inline InetAddress &operator=(const struct sockaddr_in6 &sa)
{ {
if (reinterpret_cast<const InetAddress *>(&sa) != this) { if (reinterpret_cast<const InetAddress *>(&sa) != this) {
memset(this,0,sizeof(InetAddress)); memset(this,0,sizeof(InetAddress));
@ -154,7 +154,7 @@ struct InetAddress : public sockaddr_storage
return *this; return *this;
} }
ZT_ALWAYS_INLINE InetAddress &operator=(const struct sockaddr_in6 *sa) inline InetAddress &operator=(const struct sockaddr_in6 *sa)
{ {
if (reinterpret_cast<const InetAddress *>(sa) != this) { if (reinterpret_cast<const InetAddress *>(sa) != this) {
memset(this,0,sizeof(InetAddress)); memset(this,0,sizeof(InetAddress));
@ -163,7 +163,7 @@ struct InetAddress : public sockaddr_storage
return *this; return *this;
} }
ZT_ALWAYS_INLINE InetAddress &operator=(const struct sockaddr &sa) inline InetAddress &operator=(const struct sockaddr &sa)
{ {
if (reinterpret_cast<const InetAddress *>(&sa) != this) { if (reinterpret_cast<const InetAddress *>(&sa) != this) {
memset(this,0,sizeof(InetAddress)); memset(this,0,sizeof(InetAddress));
@ -179,7 +179,7 @@ struct InetAddress : public sockaddr_storage
return *this; return *this;
} }
ZT_ALWAYS_INLINE InetAddress &operator=(const struct sockaddr *sa) inline InetAddress &operator=(const struct sockaddr *sa)
{ {
if (reinterpret_cast<const InetAddress *>(sa) != this) { if (reinterpret_cast<const InetAddress *>(sa) != this) {
memset(this,0,sizeof(InetAddress)); memset(this,0,sizeof(InetAddress));
@ -214,7 +214,7 @@ struct InetAddress : public sockaddr_storage
* *
* @param port Port, 0 to 65535 * @param port Port, 0 to 65535
*/ */
ZT_ALWAYS_INLINE void setPort(unsigned int port) inline void setPort(unsigned int port)
{ {
switch(ss_family) { switch(ss_family) {
case AF_INET: case AF_INET:
@ -229,7 +229,7 @@ struct InetAddress : public sockaddr_storage
/** /**
* @return True if this network/netmask route describes a default route (e.g. 0.0.0.0/0) * @return True if this network/netmask route describes a default route (e.g. 0.0.0.0/0)
*/ */
ZT_ALWAYS_INLINE bool isDefaultRoute() const inline bool isDefaultRoute() const
{ {
switch(ss_family) { switch(ss_family) {
case AF_INET: case AF_INET:
@ -264,7 +264,7 @@ struct InetAddress : public sockaddr_storage
/** /**
* @return Port or 0 if no port component defined * @return Port or 0 if no port component defined
*/ */
ZT_ALWAYS_INLINE unsigned int port() const inline unsigned int port() const
{ {
switch(ss_family) { switch(ss_family) {
case AF_INET: return Utils::ntoh((uint16_t)(reinterpret_cast<const struct sockaddr_in *>(this)->sin_port)); case AF_INET: return Utils::ntoh((uint16_t)(reinterpret_cast<const struct sockaddr_in *>(this)->sin_port));
@ -282,12 +282,12 @@ struct InetAddress : public sockaddr_storage
* *
* @return Netmask bits * @return Netmask bits
*/ */
ZT_ALWAYS_INLINE unsigned int netmaskBits() const { return port(); } inline unsigned int netmaskBits() const { return port(); }
/** /**
* @return True if netmask bits is valid for the address type * @return True if netmask bits is valid for the address type
*/ */
ZT_ALWAYS_INLINE bool netmaskBitsValid() const inline bool netmaskBitsValid() const
{ {
const unsigned int n = port(); const unsigned int n = port();
switch(ss_family) { switch(ss_family) {
@ -305,7 +305,7 @@ struct InetAddress : public sockaddr_storage
* *
* @return Gateway metric * @return Gateway metric
*/ */
ZT_ALWAYS_INLINE unsigned int metric() const { return port(); } inline unsigned int metric() const { return port(); }
/** /**
* Construct a full netmask as an InetAddress * Construct a full netmask as an InetAddress
@ -350,17 +350,17 @@ struct InetAddress : public sockaddr_storage
/** /**
* @return True if this is an IPv4 address * @return True if this is an IPv4 address
*/ */
ZT_ALWAYS_INLINE bool isV4() const { return (ss_family == AF_INET); } inline bool isV4() const { return (ss_family == AF_INET); }
/** /**
* @return True if this is an IPv6 address * @return True if this is an IPv6 address
*/ */
ZT_ALWAYS_INLINE bool isV6() const { return (ss_family == AF_INET6); } inline bool isV6() const { return (ss_family == AF_INET6); }
/** /**
* @return pointer to raw address bytes or NULL if not available * @return pointer to raw address bytes or NULL if not available
*/ */
ZT_ALWAYS_INLINE const void *rawIpData() const inline const void *rawIpData() const
{ {
switch(ss_family) { switch(ss_family) {
case AF_INET: return (const void *)&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr); case AF_INET: return (const void *)&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr);
@ -372,7 +372,7 @@ struct InetAddress : public sockaddr_storage
/** /**
* @return InetAddress containing only the IP portion of this address and a zero port, or NULL if not IPv4 or IPv6 * @return InetAddress containing only the IP portion of this address and a zero port, or NULL if not IPv4 or IPv6
*/ */
ZT_ALWAYS_INLINE InetAddress ipOnly() const inline InetAddress ipOnly() const
{ {
InetAddress r; InetAddress r;
switch(ss_family) { switch(ss_family) {
@ -394,7 +394,7 @@ struct InetAddress : public sockaddr_storage
* @param a InetAddress to compare again * @param a InetAddress to compare again
* @return True if only IP portions are equal (false for non-IP or null addresses) * @return True if only IP portions are equal (false for non-IP or null addresses)
*/ */
ZT_ALWAYS_INLINE bool ipsEqual(const InetAddress &a) const inline bool ipsEqual(const InetAddress &a) const
{ {
if (ss_family == a.ss_family) { if (ss_family == a.ss_family) {
if (ss_family == AF_INET) if (ss_family == AF_INET)
@ -414,7 +414,7 @@ struct InetAddress : public sockaddr_storage
* @param a InetAddress to compare again * @param a InetAddress to compare again
* @return True if only IP portions are equal (false for non-IP or null addresses) * @return True if only IP portions are equal (false for non-IP or null addresses)
*/ */
ZT_ALWAYS_INLINE bool ipsEqual2(const InetAddress &a) const inline bool ipsEqual2(const InetAddress &a) const
{ {
if (ss_family == a.ss_family) { if (ss_family == a.ss_family) {
if (ss_family == AF_INET) if (ss_family == AF_INET)
@ -426,7 +426,7 @@ struct InetAddress : public sockaddr_storage
return false; return false;
} }
ZT_ALWAYS_INLINE unsigned long hashCode() const inline unsigned long hashCode() const
{ {
if (ss_family == AF_INET) { if (ss_family == AF_INET) {
return ((unsigned long)reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr + (unsigned long)reinterpret_cast<const struct sockaddr_in *>(this)->sin_port); return ((unsigned long)reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr + (unsigned long)reinterpret_cast<const struct sockaddr_in *>(this)->sin_port);
@ -448,7 +448,7 @@ struct InetAddress : public sockaddr_storage
/** /**
* Set to null/zero * Set to null/zero
*/ */
ZT_ALWAYS_INLINE void zero() { memset(this,0,sizeof(InetAddress)); } inline void zero() { memset(this,0,sizeof(InetAddress)); }
/** /**
* Check whether this is a network/route rather than an IP assignment * Check whether this is a network/route rather than an IP assignment
@ -463,7 +463,7 @@ struct InetAddress : public sockaddr_storage
/** /**
* @return 14-bit (0-16383) hash of this IP's first 24 or 48 bits (for V4 or V6) for rate limiting code, or 0 if non-IP * @return 14-bit (0-16383) hash of this IP's first 24 or 48 bits (for V4 or V6) for rate limiting code, or 0 if non-IP
*/ */
ZT_ALWAYS_INLINE unsigned long rateGateHash() const inline unsigned long rateGateHash() const
{ {
unsigned long h = 0; unsigned long h = 0;
switch(ss_family) { switch(ss_family) {
@ -487,10 +487,69 @@ struct InetAddress : public sockaddr_storage
/** /**
* @return True if address family is non-zero * @return True if address family is non-zero
*/ */
ZT_ALWAYS_INLINE operator bool() const { return (ss_family != 0); } inline operator bool() const { return (ss_family != 0); }
inline unsigned int marshal(uint8_t restrict data[20]) const
{
switch(ss_family) {
case AF_INET:
const unsigned int port = Utils::ntoh((uint16_t)reinterpret_cast<const sockaddr_in *>(this)->sin_port);
data[0] = 4;
data[1] = reinterpret_cast<const uint8_t *>(&(reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr))[0];
data[2] = reinterpret_cast<const uint8_t *>(&(reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr))[1];
data[3] = reinterpret_cast<const uint8_t *>(&(reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr))[2];
data[4] = reinterpret_cast<const uint8_t *>(&(reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr))[3];
data[5] = (uint8_t)((port >> 8) & 0xff);
data[6] = (uint8_t)(port & 0xff);
return 7;
case AF_INET6:
const unsigned int port = Utils::ntoh((uint16_t)reinterpret_cast<const sockaddr_in6 *>(this)->sin6_port);
data[0] = 6;
for(int i=0;i<16;++i)
data[i+1] = reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr[i];
data[17] = (uint8_t)((port >> 8) & 0xff);
data[18] = (uint8_t)(port & 0xff);
return 19;
default:
data[0] = 0;
return 1;
}
}
inline bool unmarshal(const uint8_t *restrict data,const unsigned int len)
{
if (len) {
memset(this,0,sizeof(InetAddress));
switch(data[0]) {
case 0:
return true;
case 4:
if (len != 7)
return false;
reinterpret_cast<sockaddr_in *>(this)->sin_family = AF_INET;
reinterpret_cast<uint8_t *>(&(reinterpret_cast<sockaddr_in *>(this)->sin_addr.s_addr))[0] = data[1];
reinterpret_cast<uint8_t *>(&(reinterpret_cast<sockaddr_in *>(this)->sin_addr.s_addr))[1] = data[2];
reinterpret_cast<uint8_t *>(&(reinterpret_cast<sockaddr_in *>(this)->sin_addr.s_addr))[2] = data[3];
reinterpret_cast<uint8_t *>(&(reinterpret_cast<sockaddr_in *>(this)->sin_addr.s_addr))[3] = data[4];
reinterpret_cast<sockaddr_in *>(this)->sin_port = Utils::hton((((uint16_t)data[5]) << 8) | (uint16_t)data[6]);
return true;
case 6:
if (len != 19)
return false;
reinterpret_cast<sockaddr_in6 *>(this)->sin6_family = AF_INET6;
for(int i=0;i<16;i++)
(reinterpret_cast<sockaddr_in6 *>(this)->sin6_addr.s6_addr)[i] = data[i+1];
reinterpret_cast<sockaddr_in6 *>(this)->sin6_port = Utils::hton((((uint16_t)data[17]) << 8) | (uint16_t)data[18]);
return true;
default:
return false;
}
}
return false;
}
template<unsigned int C> template<unsigned int C>
ZT_ALWAYS_INLINE void serialize(Buffer<C> &b) const inline void serialize(Buffer<C> &b) const
{ {
// This is used in the protocol and must be the same as describe in places // This is used in the protocol and must be the same as describe in places
// like VERB_HELLO in Packet.hpp. // like VERB_HELLO in Packet.hpp.
@ -512,7 +571,7 @@ struct InetAddress : public sockaddr_storage
} }
template<unsigned int C> template<unsigned int C>
ZT_ALWAYS_INLINE unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0) inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
{ {
memset(this,0,sizeof(InetAddress)); memset(this,0,sizeof(InetAddress));
unsigned int p = startAt; unsigned int p = startAt;
@ -547,10 +606,10 @@ struct InetAddress : public sockaddr_storage
bool operator==(const InetAddress &a) const; bool operator==(const InetAddress &a) const;
bool operator<(const InetAddress &a) const; bool operator<(const InetAddress &a) const;
ZT_ALWAYS_INLINE bool operator!=(const InetAddress &a) const { return !(*this == a); } inline bool operator!=(const InetAddress &a) const { return !(*this == a); }
ZT_ALWAYS_INLINE bool operator>(const InetAddress &a) const { return (a < *this); } inline bool operator>(const InetAddress &a) const { return (a < *this); }
ZT_ALWAYS_INLINE bool operator<=(const InetAddress &a) const { return !(a < *this); } inline bool operator<=(const InetAddress &a) const { return !(a < *this); }
ZT_ALWAYS_INLINE bool operator>=(const InetAddress &a) const { return !(*this < a); } inline bool operator>=(const InetAddress &a) const { return !(*this < a); }
/** /**
* @param mac MAC address seed * @param mac MAC address seed

View file

@ -14,22 +14,15 @@
#ifndef ZT_LOCATOR_HPP #ifndef ZT_LOCATOR_HPP
#define ZT_LOCATOR_HPP #define ZT_LOCATOR_HPP
#include "Constants.hpp"
#include "Identity.hpp"
#include "InetAddress.hpp"
#include "Utils.hpp"
#include "Buffer.hpp"
#include "SHA512.hpp"
#include "Str.hpp"
#include "ScopedPtr.hpp"
#include "SharedPtr.hpp"
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
// These are absolute maximums -- real locators are never this big #include "Constants.hpp"
#define ZT_LOCATOR_MAX_PHYSICAL_ADDRESSES 64 #include "Endpoint.hpp"
#define ZT_LOCATOR_MAX_VIRTUAL_ADDRESSES 64
#define ZT_LOCATOR_MAX_ENDPOINTS 8
#define ZT_LOCATOR_MARSHAL_SIZE_MAX ((ZT_ENDPOINT_MARSHAL_SIZE_MAX * ZT_LOCATOR_MAX_ENDPOINTS) + 8 + 256 + ZT_SIGNATURE_BUFFER_SIZE)
namespace ZeroTier { namespace ZeroTier {
@ -44,342 +37,27 @@ namespace ZeroTier {
*/ */
class Locator class Locator
{ {
enum ObjectType
{
OBJECT_TYPE_ZEROTIER_NODE = 1
};
friend class SharedPtr<Locator>; friend class SharedPtr<Locator>;
public: public:
ZT_ALWAYS_INLINE Locator() : _ts(0),_signatureLength(0) {} inline Locator() : _ts(0),_signatureLength(0) {}
ZT_ALWAYS_INLINE int64_t timestamp() const { return _ts; } inline int64_t timestamp() const { return _ts; }
ZT_ALWAYS_INLINE const Identity &id() const { return _id; } inline const Identity &id() const { return _id; }
ZT_ALWAYS_INLINE const std::vector<InetAddress> &phy() const { return _physical; } inline operator bool() const { return (_ts != 0); }
ZT_ALWAYS_INLINE const std::vector<Identity> &virt() const { return _virtual; }
/** inline bool create(const int64_t ts,const Identity &id,const Endpoint *restrict at,const unsigned int endpointCount)
* Add a physical address to this locator (call before finish() to build a new Locator)
*/
ZT_ALWAYS_INLINE void add(const InetAddress &ip)
{ {
if (_physical.size() < ZT_LOCATOR_MAX_PHYSICAL_ADDRESSES)
_physical.push_back(ip);
} }
/**
* Add a forwarding ZeroTier node to this locator (call before finish() to build a new Locator)
*/
ZT_ALWAYS_INLINE void add(const Identity &zt)
{
if (_virtual.size() < ZT_LOCATOR_MAX_VIRTUAL_ADDRESSES)
_virtual.push_back(zt);
}
/**
* Method to be called after add() is called for each address or forwarding node
*
* @param id Identity that this locator describes (must contain private key)
* @param ts Current time
* @return True if completion and signature were successful
*/
ZT_ALWAYS_INLINE bool finish(const Identity &id,const int64_t ts)
{
_ts = ts;
_id = id;
std::sort(_physical.begin(),_physical.end());
_physical.erase(std::unique(_physical.begin(),_physical.end()),_physical.end());
std::sort(_virtual.begin(),_virtual.end());
_virtual.erase(std::unique(_virtual.begin(),_virtual.end()),_virtual.end());
try {
ScopedPtr< Buffer<65536> > tmp(new Buffer<65536>());
serialize(*tmp,true);
_signatureLength = id.sign(tmp->data(),tmp->size(),_signature,ZT_SIGNATURE_BUFFER_SIZE);
return (_signatureLength > 0);
} catch ( ... ) {
return false;
}
}
/**
* Verify this locator's signature against its embedded signing identity
*/
ZT_ALWAYS_INLINE bool verify() const
{
if ((_signatureLength == 0)||(_signatureLength > sizeof(_signature)))
return false;
try {
ScopedPtr< Buffer<65536> > tmp(new Buffer<65536>());
serialize(*tmp,true);
return _id.verify(tmp->data(),tmp->size(),_signature,_signatureLength);
} catch ( ... ) {
return false;
}
}
/**
* Make a DNS name contiaining a public key that can sign DNS entries
*
* This generates the initial fields of a DNS name that contains an
* encoded public key. Users may append any domain suffix to this name.
*
* @return First field(s) of DNS name
*/
static inline Str makeSecureDnsName(const uint8_t p384SigningKeyPublic[ZT_ECC384_PUBLIC_KEY_SIZE])
{
uint8_t tmp[ZT_ECC384_PUBLIC_KEY_SIZE+2];
memcpy(tmp,p384SigningKeyPublic,ZT_ECC384_PUBLIC_KEY_SIZE);
const uint16_t crc = Utils::crc16(tmp,ZT_ECC384_PUBLIC_KEY_SIZE);
tmp[ZT_ECC384_PUBLIC_KEY_SIZE-2] = (uint8_t)(crc >> 8);
tmp[ZT_ECC384_PUBLIC_KEY_SIZE-1] = (uint8_t)(crc);
Str name;
char b32[128];
Utils::b32e(tmp,35,b32,sizeof(b32));
name << "ztl-";
name << b32;
Utils::b32e(tmp + 35,(ZT_ECC384_PUBLIC_KEY_SIZE+2) - 35,b32,sizeof(b32));
name << ".ztl-";
name << b32;
return name;
}
/**
* This searches for an extracts a public key from a DNS name, if one is present.
*
* @return True if a key was found and successfully decoded
*/
static inline bool decodeSecureDnsName(const char *name,uint8_t p384SigningKeyPublic[ZT_ECC384_PUBLIC_KEY_SIZE])
{
uint8_t b32[128];
unsigned int b32ptr = 0;
char tmp[1024];
Utils::scopy(tmp,sizeof(tmp),name);
bool ok = false;
for(char *saveptr=(char *)0,*p=Utils::stok(tmp,".",&saveptr);p;p=Utils::stok((char *)0,".",&saveptr)) {
if (b32ptr >= sizeof(b32))
break;
if ((strlen(p) <= 4)||(memcmp(p,"ztl-",4) != 0))
continue;
int s = Utils::b32d(p + 4,b32 + b32ptr,sizeof(b32) - b32ptr);
if (s > 0) {
b32ptr += (unsigned int)s;
if (b32ptr > 2) {
const uint16_t crc = Utils::crc16(b32,b32ptr);
if ((b32[b32ptr-2] == (uint8_t)(crc >> 8))&&(b32[b32ptr-1] == (uint8_t)(crc & 0xff))) {
ok = true;
break;
}
}
} else break;
}
if (ok) {
if (b32ptr == (ZT_ECC384_PUBLIC_KEY_SIZE + 2)) {
memcpy(p384SigningKeyPublic,b32,ZT_ECC384_PUBLIC_KEY_SIZE);
return true;
}
}
return false;
}
/**
* Make DNS TXT records for this locator
*
* DNS TXT records are signed by an entirely separate key that is added along
* with DNS names to nodes to allow them to verify DNS results. It's separate
* from the locator's signature so that a single DNS record can point to more
* than one locator or be served by things like geo-aware DNS.
*
* Right now only NIST P-384 is supported for signing DNS records. NIST EDDSA
* is used here so that FIPS-only nodes can always use DNS to locate roots as
* FIPS-only nodes may be required to disable non-FIPS algorithms.
*/
inline std::vector<Str> makeTxtRecords(const uint8_t p384SigningKeyPrivate[ZT_ECC384_PUBLIC_KEY_SIZE])
{
uint8_t s384[48];
char enc[256];
ScopedPtr< Buffer<65536> > tmp(new Buffer<65536>());
serialize(*tmp,false);
SHA384(s384,tmp->data(),tmp->size());
const unsigned int sigLocation = tmp->size();
tmp->addSize(ZT_ECC384_SIGNATURE_SIZE);
ECC384ECDSASign(p384SigningKeyPrivate,s384,((uint8_t *)tmp->unsafeData()) + sigLocation);
// Blob must be broken into multiple TXT records that must remain sortable so they are prefixed by a hex value.
// 186-byte chunks yield 248-byte base64 chunks which leaves some margin below the limit of 255.
std::vector<Str> txtRecords;
unsigned int txtRecNo = 0;
for(unsigned int p=0;p<tmp->size();) {
unsigned int chunkSize = tmp->size() - p;
if (chunkSize > 186) chunkSize = 186;
Utils::b64e(((const uint8_t *)tmp->data()) + p,chunkSize,enc,sizeof(enc));
p += chunkSize;
txtRecords.push_back(Str());
txtRecords.back() << Utils::HEXCHARS[(txtRecNo >> 4) & 0xf] << Utils::HEXCHARS[txtRecNo & 0xf] << enc;
++txtRecNo;
}
return txtRecords;
}
/**
* Decode TXT records
*
* TXT records can be provided as an iterator over std::string, Str, or char *
* values, and TXT records can be provided in any order. Any oversize or empty
* entries will be ignored.
*
* This method checks the decoded locator's signature using the supplied DNS TXT
* record signing public key. False is returned if the TXT records are invalid,
* incomplete, or fail signature check. If true is returned this Locator object
* now contains the contents of the supplied TXT records.
*
* @return True if new Locator is valid
*/
template<typename I>
inline bool decodeTxtRecords(const Str &dnsName,I start,I end)
{
uint8_t dec[256],s384[48];
try {
std::vector<Str> txtRecords;
while (start != end) {
try {
if (start->length() > 2)
txtRecords.push_back(*start);
} catch ( ... ) {} // skip any records that trigger out of bounds exceptions
++start;
}
if (txtRecords.empty())
return false;
std::sort(txtRecords.begin(),txtRecords.end());
ScopedPtr< Buffer<65536> > tmp(new Buffer<65536>());
for(std::vector<Str>::const_iterator i(txtRecords.begin());i!=txtRecords.end();++i)
tmp->append(dec,Utils::b64d(i->c_str() + 2,dec,sizeof(dec)));
uint8_t p384SigningKeyPublic[ZT_ECC384_PUBLIC_KEY_SIZE];
if (decodeSecureDnsName(dnsName.c_str(),p384SigningKeyPublic)) {
if (tmp->size() <= ZT_ECC384_SIGNATURE_SIZE)
return false;
SHA384(s384,tmp->data(),tmp->size() - ZT_ECC384_SIGNATURE_SIZE);
if (!ECC384ECDSAVerify(p384SigningKeyPublic,s384,((const uint8_t *)tmp->data()) + (tmp->size() - ZT_ECC384_SIGNATURE_SIZE)))
return false;
}
deserialize(*tmp,0);
return verify();
} catch ( ... ) {
return false;
}
}
inline bool deserialize(const void *data,unsigned int len)
{
ScopedPtr< Buffer<65536> > tmp(new Buffer<65536>());
tmp->append(data,len);
try {
deserialize(*tmp,0);
return true;
} catch ( ... ) {
return false;
}
}
template<unsigned int C>
inline void serialize(Buffer<C> &b,const bool forSign = false) const
{
if (forSign) b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL);
b.append((uint8_t)0); // version/flags, currently 0
b.append((uint64_t)_ts);
_id.serialize(b,false);
b.append((uint8_t)_physical.size());
for(std::vector<InetAddress>::const_iterator i(_physical.begin());i!=_physical.end();++i)
i->serialize(b);
b.append((uint8_t)_virtual.size());
for(std::vector<Identity>::const_iterator i(_virtual.begin());i!=_virtual.end();++i)
i->serialize(b,false);
if (!forSign) {
b.append((uint16_t)_signatureLength);
b.append(_signature,_signatureLength);
}
b.append((uint16_t)0); // length of additional fields, currently 0
if (forSign) b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL);
}
template<unsigned int C>
inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
{
unsigned int p = startAt;
if (b[p++] != 0)
throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE;
_ts = (int64_t)b.template at<uint64_t>(p); p += 8;
p += _id.deserialize(b,p);
const unsigned int physicalCount = b[p++];
_physical.resize(physicalCount);
for(unsigned int i=0;i<physicalCount;++i)
p += _physical[i].deserialize(b,p);
const unsigned int virtualCount = b[p++];
_virtual.resize(virtualCount);
for(unsigned int i=0;i<virtualCount;++i)
p += _virtual[i].deserialize(b,p);
_signatureLength = b.template at<uint16_t>(p); p += 2;
if (_signatureLength > ZT_SIGNATURE_BUFFER_SIZE)
throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW;
memcpy(_signature,b.field(p,_signatureLength),_signatureLength);
p += _signatureLength;
p += b.template at<uint16_t>(p) + 2;
return (p - startAt);
}
ZT_ALWAYS_INLINE operator bool() const { return (_id); }
ZT_ALWAYS_INLINE bool addressesEqual(const Locator &l) const { return ((_physical == l._physical)&&(_virtual == l._virtual)); }
ZT_ALWAYS_INLINE bool operator==(const Locator &l) const
{
return (
(_ts == l._ts)&&
(_id == l._id)&&
(_physical == l._physical)&&
(_virtual == l._virtual)&&
(_signatureLength == l._signatureLength)&&
(memcmp(_signature,l._signature,_signatureLength) == 0));
}
ZT_ALWAYS_INLINE bool operator!=(const Locator &l) const { return (!(*this == l)); }
ZT_ALWAYS_INLINE bool operator<(const Locator &l) const
{
if (_ts < l._ts) return true; else if (_ts > l._ts) return false;
if (_id < l._id) return true; else if (_id > l._id) return false;
if (_physical < l._physical) return true; else if (_physical > l._physical) return false;
if (_virtual < l._virtual) return true; else if (_virtual > l._virtual) return false;
if (_signatureLength < l._signatureLength) return true;
return (_signatureLength == l._signatureLength) ? (memcmp(_signature,l._signature,_signatureLength) < 0) : false;
}
ZT_ALWAYS_INLINE bool operator>(const Locator &l) const { return (l < *this); }
ZT_ALWAYS_INLINE bool operator<=(const Locator &l) const { return (!(l < *this)); }
ZT_ALWAYS_INLINE bool operator>=(const Locator &l) const { return (!(*this < l)); }
ZT_ALWAYS_INLINE unsigned long hashCode() const { return (unsigned long)(_id.address().toInt() ^ (uint64_t)_ts); }
private: private:
int64_t _ts; int64_t _ts;
Identity _id; Identity _id;
std::vector<InetAddress> _physical; Endpoint *_at;
std::vector<Identity> _virtual; unsigned int _endpointCount;
unsigned int _signatureLength; unsigned int _signatureLength;
uint8_t _signature[ZT_SIGNATURE_BUFFER_SIZE]; uint8_t _signature[ZT_SIGNATURE_BUFFER_SIZE];
AtomicCounter __refCount;
}; };
} // namespace ZeroTier } // namespace ZeroTier

View file

@ -31,40 +31,40 @@ namespace ZeroTier {
class MAC class MAC
{ {
public: public:
ZT_ALWAYS_INLINE MAC() : _m(0ULL) {} inline MAC() : _m(0ULL) {}
ZT_ALWAYS_INLINE MAC(const MAC &m) : _m(m._m) {} inline MAC(const MAC &m) : _m(m._m) {}
ZT_ALWAYS_INLINE MAC(const unsigned char a,const unsigned char b,const unsigned char c,const unsigned char d,const unsigned char e,const unsigned char f) : inline MAC(const unsigned char a,const unsigned char b,const unsigned char c,const unsigned char d,const unsigned char e,const unsigned char f) :
_m( ((((uint64_t)a) & 0xffULL) << 40) | _m( ((((uint64_t)a) & 0xffULL) << 40) |
((((uint64_t)b) & 0xffULL) << 32) | ((((uint64_t)b) & 0xffULL) << 32) |
((((uint64_t)c) & 0xffULL) << 24) | ((((uint64_t)c) & 0xffULL) << 24) |
((((uint64_t)d) & 0xffULL) << 16) | ((((uint64_t)d) & 0xffULL) << 16) |
((((uint64_t)e) & 0xffULL) << 8) | ((((uint64_t)e) & 0xffULL) << 8) |
(((uint64_t)f) & 0xffULL) ) {} (((uint64_t)f) & 0xffULL) ) {}
ZT_ALWAYS_INLINE MAC(const void *bits,unsigned int len) { setTo(bits,len); } inline MAC(const void *bits,unsigned int len) { setTo(bits,len); }
ZT_ALWAYS_INLINE MAC(const Address &ztaddr,uint64_t nwid) { fromAddress(ztaddr,nwid); } inline MAC(const Address &ztaddr,uint64_t nwid) { fromAddress(ztaddr,nwid); }
ZT_ALWAYS_INLINE MAC(const uint64_t m) : _m(m & 0xffffffffffffULL) {} inline MAC(const uint64_t m) : _m(m & 0xffffffffffffULL) {}
/** /**
* @return MAC in 64-bit integer * @return MAC in 64-bit integer
*/ */
ZT_ALWAYS_INLINE uint64_t toInt() const { return _m; } inline uint64_t toInt() const { return _m; }
/** /**
* Set MAC to zero * Set MAC to zero
*/ */
ZT_ALWAYS_INLINE void zero() { _m = 0ULL; } inline void zero() { _m = 0ULL; }
/** /**
* @return True if MAC is non-zero * @return True if MAC is non-zero
*/ */
ZT_ALWAYS_INLINE operator bool() const { return (_m != 0ULL); } inline operator bool() const { return (_m != 0ULL); }
/** /**
* @param bits Raw MAC in big-endian byte order * @param bits Raw MAC in big-endian byte order
* @param len Length, must be >= 6 or result is zero * @param len Length, must be >= 6 or result is zero
*/ */
ZT_ALWAYS_INLINE void setTo(const void *bits,unsigned int len) inline void setTo(const void *bits,unsigned int len)
{ {
if (len < 6) { if (len < 6) {
_m = 0ULL; _m = 0ULL;
@ -83,7 +83,7 @@ public:
* @param buf Destination buffer for MAC in big-endian byte order * @param buf Destination buffer for MAC in big-endian byte order
* @param len Length of buffer, must be >= 6 or nothing is copied * @param len Length of buffer, must be >= 6 or nothing is copied
*/ */
ZT_ALWAYS_INLINE void copyTo(void *buf,unsigned int len) const inline void copyTo(void *buf,unsigned int len) const
{ {
if (len < 6) if (len < 6)
return; return;
@ -102,7 +102,7 @@ public:
* @param b Buffer to append to * @param b Buffer to append to
*/ */
template<unsigned int C> template<unsigned int C>
ZT_ALWAYS_INLINE void appendTo(Buffer<C> &b) const inline void appendTo(Buffer<C> &b) const
{ {
unsigned char *p = (unsigned char *)b.appendField(6); unsigned char *p = (unsigned char *)b.appendField(6);
*(p++) = (unsigned char)((_m >> 40) & 0xff); *(p++) = (unsigned char)((_m >> 40) & 0xff);
@ -116,17 +116,17 @@ public:
/** /**
* @return True if this is broadcast (all 0xff) * @return True if this is broadcast (all 0xff)
*/ */
ZT_ALWAYS_INLINE bool isBroadcast() const { return (_m == 0xffffffffffffULL); } inline bool isBroadcast() const { return (_m == 0xffffffffffffULL); }
/** /**
* @return True if this is a multicast MAC * @return True if this is a multicast MAC
*/ */
ZT_ALWAYS_INLINE bool isMulticast() const { return ((_m & 0x010000000000ULL) != 0ULL); } inline bool isMulticast() const { return ((_m & 0x010000000000ULL) != 0ULL); }
/** /**
* @param True if this is a locally-administered MAC * @param True if this is a locally-administered MAC
*/ */
ZT_ALWAYS_INLINE bool isLocallyAdministered() const { return ((_m & 0x020000000000ULL) != 0ULL); } inline bool isLocallyAdministered() const { return ((_m & 0x020000000000ULL) != 0ULL); }
/** /**
* Set this MAC to a MAC derived from an address and a network ID * Set this MAC to a MAC derived from an address and a network ID
@ -134,7 +134,7 @@ public:
* @param ztaddr ZeroTier address * @param ztaddr ZeroTier address
* @param nwid 64-bit network ID * @param nwid 64-bit network ID
*/ */
ZT_ALWAYS_INLINE void fromAddress(const Address &ztaddr,uint64_t nwid) inline void fromAddress(const Address &ztaddr,uint64_t nwid)
{ {
uint64_t m = ((uint64_t)firstOctetForNetwork(nwid)) << 40; uint64_t m = ((uint64_t)firstOctetForNetwork(nwid)) << 40;
m |= ztaddr.toInt(); // a is 40 bits m |= ztaddr.toInt(); // a is 40 bits
@ -153,7 +153,7 @@ public:
* *
* @param nwid Network ID * @param nwid Network ID
*/ */
ZT_ALWAYS_INLINE Address toAddress(uint64_t nwid) const inline Address toAddress(uint64_t nwid) const
{ {
uint64_t a = _m & 0xffffffffffULL; // least significant 40 bits of MAC are formed from address uint64_t a = _m & 0xffffffffffULL; // least significant 40 bits of MAC are formed from address
a ^= ((nwid >> 8) & 0xff) << 32; // ... XORed with bits 8-48 of the nwid in little-endian byte order, so unmask it a ^= ((nwid >> 8) & 0xff) << 32; // ... XORed with bits 8-48 of the nwid in little-endian byte order, so unmask it
@ -168,7 +168,7 @@ public:
* @param nwid Network ID * @param nwid Network ID
* @return First octet of MAC for this network * @return First octet of MAC for this network
*/ */
static ZT_ALWAYS_INLINE unsigned char firstOctetForNetwork(uint64_t nwid) static inline unsigned char firstOctetForNetwork(uint64_t nwid)
{ {
unsigned char a = ((unsigned char)(nwid & 0xfe) | 0x02); // locally administered, not multicast, from LSB of network ID unsigned char a = ((unsigned char)(nwid & 0xfe) | 0x02); // 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 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
@ -178,16 +178,16 @@ public:
* @param i Value from 0 to 5 (inclusive) * @param i Value from 0 to 5 (inclusive)
* @return Byte at said position (address interpreted in big-endian order) * @return Byte at said position (address interpreted in big-endian order)
*/ */
ZT_ALWAYS_INLINE uint8_t operator[](unsigned int i) const { return (uint8_t)(_m >> (40 - (i * 8))); } inline uint8_t operator[](unsigned int i) const { return (uint8_t)(_m >> (40 - (i * 8))); }
/** /**
* @return 6, which is the number of bytes in a MAC, for container compliance * @return 6, which is the number of bytes in a MAC, for container compliance
*/ */
ZT_ALWAYS_INLINE unsigned int size() const { return 6; } inline unsigned int size() const { return 6; }
ZT_ALWAYS_INLINE unsigned long hashCode() const { return (unsigned long)_m; } inline unsigned long hashCode() const { return (unsigned long)_m; }
ZT_ALWAYS_INLINE char *toString(char buf[18]) const inline char *toString(char buf[18]) const
{ {
buf[0] = Utils::HEXCHARS[(_m >> 44) & 0xf]; buf[0] = Utils::HEXCHARS[(_m >> 44) & 0xf];
buf[1] = Utils::HEXCHARS[(_m >> 40) & 0xf]; buf[1] = Utils::HEXCHARS[(_m >> 40) & 0xf];
@ -210,23 +210,23 @@ public:
return buf; return buf;
} }
ZT_ALWAYS_INLINE MAC &operator=(const MAC &m) inline MAC &operator=(const MAC &m)
{ {
_m = m._m; _m = m._m;
return *this; return *this;
} }
ZT_ALWAYS_INLINE MAC &operator=(const uint64_t m) inline MAC &operator=(const uint64_t m)
{ {
_m = m & 0xffffffffffffULL; _m = m & 0xffffffffffffULL;
return *this; return *this;
} }
ZT_ALWAYS_INLINE bool operator==(const MAC &m) const { return (_m == m._m); } inline bool operator==(const MAC &m) const { return (_m == m._m); }
ZT_ALWAYS_INLINE bool operator!=(const MAC &m) const { return (_m != m._m); } inline bool operator!=(const MAC &m) const { return (_m != m._m); }
ZT_ALWAYS_INLINE bool operator<(const MAC &m) const { return (_m < m._m); } inline bool operator<(const MAC &m) const { return (_m < m._m); }
ZT_ALWAYS_INLINE bool operator<=(const MAC &m) const { return (_m <= m._m); } inline bool operator<=(const MAC &m) const { return (_m <= m._m); }
ZT_ALWAYS_INLINE bool operator>(const MAC &m) const { return (_m > m._m); } inline bool operator>(const MAC &m) const { return (_m > m._m); }
ZT_ALWAYS_INLINE bool operator>=(const MAC &m) const { return (_m >= m._m); } inline bool operator>=(const MAC &m) const { return (_m >= m._m); }
private: private:
uint64_t _m; uint64_t _m;

View file

@ -67,7 +67,7 @@ public:
/** /**
* @return Time we last pushed credentials to this member * @return Time we last pushed credentials to this member
*/ */
ZT_ALWAYS_INLINE int64_t lastPushedCredentials() const { return _lastPushedCredentials; } inline int64_t lastPushedCredentials() const { return _lastPushedCredentials; }
/** /**
* Check whether we should push MULTICAST_LIKEs to this peer, and update last sent time if true * Check whether we should push MULTICAST_LIKEs to this peer, and update last sent time if true
@ -75,7 +75,7 @@ public:
* @param now Current time * @param now Current time
* @return True if we should update multicasts * @return True if we should update multicasts
*/ */
ZT_ALWAYS_INLINE bool multicastLikeGate(const int64_t now) inline bool multicastLikeGate(const int64_t now)
{ {
if ((now - _lastUpdatedMulticast) >= ZT_MULTICAST_ANNOUNCE_PERIOD) { if ((now - _lastUpdatedMulticast) >= ZT_MULTICAST_ANNOUNCE_PERIOD) {
_lastUpdatedMulticast = now; _lastUpdatedMulticast = now;
@ -90,7 +90,7 @@ public:
* @param nconf Our network config * @param nconf Our network config
* @return True if this peer is allowed on this network at all * @return True if this peer is allowed on this network at all
*/ */
ZT_ALWAYS_INLINE bool isAllowedOnNetwork(const NetworkConfig &nconf) const inline bool isAllowedOnNetwork(const NetworkConfig &nconf) const
{ {
if (nconf.isPublic()) return true; // public network if (nconf.isPublic()) return true; // public network
if (_com.timestamp() <= _comRevocationThreshold) return false; // COM has been revoked if (_com.timestamp() <= _comRevocationThreshold) return false; // COM has been revoked
@ -100,7 +100,7 @@ public:
/** /**
* @return True if this peer has sent us a valid certificate within ZT_PEER_ACTIVITY_TIMEOUT * @return True if this peer has sent us a valid certificate within ZT_PEER_ACTIVITY_TIMEOUT
*/ */
ZT_ALWAYS_INLINE bool recentlyAssociated(const int64_t now) const { return ((_com)&&((now - _com.timestamp()) < ZT_PEER_ACTIVITY_TIMEOUT)); } inline bool recentlyAssociated(const int64_t now) const { return ((_com)&&((now - _com.timestamp()) < ZT_PEER_ACTIVITY_TIMEOUT)); }
/** /**
* Check whether the peer represented by this Membership owns a given address * Check whether the peer represented by this Membership owns a given address
@ -160,22 +160,22 @@ public:
/** /**
* @return Bytes received so far * @return Bytes received so far
*/ */
ZT_ALWAYS_INLINE uint64_t receivedBytes() const { return _received; } inline uint64_t receivedBytes() const { return _received; }
/** /**
* @return Bytes sent so far * @return Bytes sent so far
*/ */
ZT_ALWAYS_INLINE uint64_t sentBytes() const { return _sent; } inline uint64_t sentBytes() const { return _sent; }
/** /**
* @param bytes Bytes received * @param bytes Bytes received
*/ */
ZT_ALWAYS_INLINE void logReceivedBytes(const unsigned int bytes) { _received = (uint64_t)bytes; } inline void logReceivedBytes(const unsigned int bytes) { _received = (uint64_t)bytes; }
/** /**
* @param bytes Bytes sent * @param bytes Bytes sent
*/ */
ZT_ALWAYS_INLINE void logSentBytes(const unsigned int bytes) { _sent = (uint64_t)bytes; } inline void logSentBytes(const unsigned int bytes) { _sent = (uint64_t)bytes; }
private: private:
// This returns true if a resource is an IPv6 NDP-emulated address. These embed the ZT // This returns true if a resource is an IPv6 NDP-emulated address. These embed the ZT
@ -275,7 +275,7 @@ public:
class CapabilityIterator class CapabilityIterator
{ {
public: public:
ZT_ALWAYS_INLINE CapabilityIterator(Membership &m,const NetworkConfig &nconf) : inline CapabilityIterator(Membership &m,const NetworkConfig &nconf) :
_hti(m._remoteCaps), _hti(m._remoteCaps),
_k((uint32_t *)0), _k((uint32_t *)0),
_c((Capability *)0), _c((Capability *)0),
@ -284,7 +284,7 @@ public:
{ {
} }
ZT_ALWAYS_INLINE Capability *next() inline Capability *next()
{ {
while (_hti.next(_k,_c)) { while (_hti.next(_k,_c)) {
if (_m._isCredentialTimestampValid(_nconf,*_c)) if (_m._isCredentialTimestampValid(_nconf,*_c))

View file

@ -29,7 +29,7 @@ namespace ZeroTier {
class Meter class Meter
{ {
public: public:
ZT_ALWAYS_INLINE Meter() inline Meter()
{ {
for(int i=0;i<ZT_METER_HISTORY_LENGTH;++i) for(int i=0;i<ZT_METER_HISTORY_LENGTH;++i)
_history[i] = 0.0; _history[i] = 0.0;
@ -38,7 +38,7 @@ public:
} }
template<typename I> template<typename I>
ZT_ALWAYS_INLINE void log(const int64_t now,I count) inline void log(const int64_t now,I count)
{ {
const int64_t since = now - _ts; const int64_t since = now - _ts;
if (since >= ZT_METER_HISTORY_TICK_DURATION) { if (since >= ZT_METER_HISTORY_TICK_DURATION) {
@ -50,7 +50,7 @@ public:
} }
} }
ZT_ALWAYS_INLINE double perSecond(const int64_t now) const inline double perSecond(const int64_t now) const
{ {
double r = 0.0,n = 0.0; double r = 0.0,n = 0.0;
const int64_t since = (now - _ts); const int64_t since = (now - _ts);

View file

@ -41,8 +41,8 @@ namespace ZeroTier {
class MulticastGroup class MulticastGroup
{ {
public: public:
ZT_ALWAYS_INLINE MulticastGroup() : _mac(),_adi(0) {} inline MulticastGroup() : _mac(),_adi(0) {}
ZT_ALWAYS_INLINE MulticastGroup(const MAC &m,uint32_t a) : _mac(m),_adi(a) {} inline MulticastGroup(const MAC &m,uint32_t a) : _mac(m),_adi(a) {}
/** /**
* Derive the multicast group used for address resolution (ARP/NDP) for an IP * Derive the multicast group used for address resolution (ARP/NDP) for an IP
@ -50,7 +50,7 @@ public:
* @param ip IP address (port field is ignored) * @param ip IP address (port field is ignored)
* @return Multicast group for ARP/NDP * @return Multicast group for ARP/NDP
*/ */
static ZT_ALWAYS_INLINE MulticastGroup deriveMulticastGroupForAddressResolution(const InetAddress &ip) static inline MulticastGroup deriveMulticastGroupForAddressResolution(const InetAddress &ip)
{ {
if (ip.isV4()) { if (ip.isV4()) {
// IPv4 wants broadcast MACs, so we shove the V4 address itself into // IPv4 wants broadcast MACs, so we shove the V4 address itself into
@ -72,17 +72,17 @@ public:
/** /**
* @return Ethernet MAC portion of multicast group * @return Ethernet MAC portion of multicast group
*/ */
ZT_ALWAYS_INLINE const MAC &mac() const { return _mac; } inline const MAC &mac() const { return _mac; }
/** /**
* @return Additional distinguishing information, which is normally zero except for IPv4 ARP where it's the IPv4 address * @return Additional distinguishing information, which is normally zero except for IPv4 ARP where it's the IPv4 address
*/ */
ZT_ALWAYS_INLINE uint32_t adi() const { return _adi; } inline uint32_t adi() const { return _adi; }
/** /**
* @return 32-bit non-cryptographic hash ID of this multicast group * @return 32-bit non-cryptographic hash ID of this multicast group
*/ */
ZT_ALWAYS_INLINE uint32_t id() const inline uint32_t id() const
{ {
uint64_t m = _mac.toInt(); uint64_t m = _mac.toInt();
uint32_t x1 = _adi; uint32_t x1 = _adi;
@ -100,9 +100,9 @@ public:
return (x1 ^ x2 ^ x3); return (x1 ^ x2 ^ x3);
} }
ZT_ALWAYS_INLINE bool operator==(const MulticastGroup &g) const { return ((_mac == g._mac)&&(_adi == g._adi)); } inline bool operator==(const MulticastGroup &g) const { return ((_mac == g._mac)&&(_adi == g._adi)); }
ZT_ALWAYS_INLINE bool operator!=(const MulticastGroup &g) const { return ((_mac != g._mac)||(_adi != g._adi)); } inline bool operator!=(const MulticastGroup &g) const { return ((_mac != g._mac)||(_adi != g._adi)); }
ZT_ALWAYS_INLINE bool operator<(const MulticastGroup &g) const inline bool operator<(const MulticastGroup &g) const
{ {
if (_mac < g._mac) if (_mac < g._mac)
return true; return true;
@ -110,11 +110,11 @@ public:
return (_adi < g._adi); return (_adi < g._adi);
return false; return false;
} }
ZT_ALWAYS_INLINE bool operator>(const MulticastGroup &g) const { return (g < *this); } inline bool operator>(const MulticastGroup &g) const { return (g < *this); }
ZT_ALWAYS_INLINE bool operator<=(const MulticastGroup &g) const { return !(g < *this); } inline bool operator<=(const MulticastGroup &g) const { return !(g < *this); }
ZT_ALWAYS_INLINE bool operator>=(const MulticastGroup &g) const { return !(*this < g); } inline bool operator>=(const MulticastGroup &g) const { return !(*this < g); }
ZT_ALWAYS_INLINE unsigned long hashCode() const { return (_mac.hashCode() ^ (unsigned long)_adi); } inline unsigned long hashCode() const { return (_mac.hashCode() ^ (unsigned long)_adi); }
private: private:
MAC _mac; MAC _mac;

View file

@ -28,23 +28,23 @@ namespace ZeroTier {
class Mutex class Mutex
{ {
public: public:
ZT_ALWAYS_INLINE Mutex() { pthread_mutex_init(&_mh,(const pthread_mutexattr_t *)0); } inline Mutex() { pthread_mutex_init(&_mh,(const pthread_mutexattr_t *)0); }
ZT_ALWAYS_INLINE ~Mutex() { pthread_mutex_destroy(&_mh); } inline ~Mutex() { pthread_mutex_destroy(&_mh); }
ZT_ALWAYS_INLINE void lock() const { pthread_mutex_lock(&((const_cast <Mutex *> (this))->_mh)); } inline void lock() const { pthread_mutex_lock(&((const_cast <Mutex *> (this))->_mh)); }
ZT_ALWAYS_INLINE void unlock() const { pthread_mutex_unlock(&((const_cast <Mutex *> (this))->_mh)); } inline void unlock() const { pthread_mutex_unlock(&((const_cast <Mutex *> (this))->_mh)); }
class Lock class Lock
{ {
public: public:
ZT_ALWAYS_INLINE Lock(Mutex &m) : _m(&m) { m.lock(); } inline Lock(Mutex &m) : _m(&m) { m.lock(); }
ZT_ALWAYS_INLINE Lock(const Mutex &m) : _m(const_cast<Mutex *>(&m)) { _m->lock(); } inline Lock(const Mutex &m) : _m(const_cast<Mutex *>(&m)) { _m->lock(); }
ZT_ALWAYS_INLINE ~Lock() { _m->unlock(); } inline ~Lock() { _m->unlock(); }
private: private:
Mutex *const _m; Mutex *const _m;
}; };
private: private:
ZT_ALWAYS_INLINE Mutex(const Mutex &) {} inline Mutex(const Mutex &) {}
const Mutex &operator=(const Mutex &) { return *this; } const Mutex &operator=(const Mutex &) { return *this; }
pthread_mutex_t _mh; pthread_mutex_t _mh;
@ -65,25 +65,25 @@ namespace ZeroTier {
class Mutex class Mutex
{ {
public: public:
ZT_ALWAYS_INLINE Mutex() { InitializeCriticalSection(&_cs); } inline Mutex() { InitializeCriticalSection(&_cs); }
ZT_ALWAYS_INLINE ~Mutex() { DeleteCriticalSection(&_cs); } inline ~Mutex() { DeleteCriticalSection(&_cs); }
ZT_ALWAYS_INLINE void lock() { EnterCriticalSection(&_cs); } inline void lock() { EnterCriticalSection(&_cs); }
ZT_ALWAYS_INLINE void unlock() { LeaveCriticalSection(&_cs); } inline void unlock() { LeaveCriticalSection(&_cs); }
ZT_ALWAYS_INLINE void lock() const { (const_cast <Mutex *> (this))->lock(); } inline void lock() const { (const_cast <Mutex *> (this))->lock(); }
ZT_ALWAYS_INLINE void unlock() const { (const_cast <Mutex *> (this))->unlock(); } inline void unlock() const { (const_cast <Mutex *> (this))->unlock(); }
class Lock class Lock
{ {
public: public:
ZT_ALWAYS_INLINE Lock(Mutex &m) : _m(&m) { m.lock(); } inline Lock(Mutex &m) : _m(&m) { m.lock(); }
ZT_ALWAYS_INLINE Lock(const Mutex &m) : _m(const_cast<Mutex *>(&m)) { _m->lock(); } inline Lock(const Mutex &m) : _m(const_cast<Mutex *>(&m)) { _m->lock(); }
ZT_ALWAYS_INLINE ~Lock() { _m->unlock(); } inline ~Lock() { _m->unlock(); }
private: private:
Mutex *const _m; Mutex *const _m;
}; };
private: private:
ZT_ALWAYS_INLINE Mutex(const Mutex &) {} inline Mutex(const Mutex &) {}
const Mutex &operator=(const Mutex &) { return *this; } const Mutex &operator=(const Mutex &) { return *this; }
CRITICAL_SECTION _cs; CRITICAL_SECTION _cs;

View file

@ -61,7 +61,7 @@ public:
/** /**
* Compute primary controller device ID from network ID * Compute primary controller device ID from network ID
*/ */
static ZT_ALWAYS_INLINE Address controllerFor(uint64_t nwid) { return Address(nwid >> 24); } static inline Address controllerFor(uint64_t nwid) { return Address(nwid >> 24); }
/** /**
* Construct a new network * Construct a new network
@ -79,14 +79,14 @@ public:
~Network(); ~Network();
ZT_ALWAYS_INLINE uint64_t id() const { return _id; } inline uint64_t id() const { return _id; }
ZT_ALWAYS_INLINE Address controller() const { return Address(_id >> 24); } inline Address controller() const { return Address(_id >> 24); }
ZT_ALWAYS_INLINE bool multicastEnabled() const { return (_config.multicastLimit > 0); } inline bool multicastEnabled() const { return (_config.multicastLimit > 0); }
ZT_ALWAYS_INLINE bool hasConfig() const { return (_config); } inline bool hasConfig() const { return (_config); }
ZT_ALWAYS_INLINE uint64_t lastConfigUpdate() const { return _lastConfigUpdate; } inline uint64_t lastConfigUpdate() const { return _lastConfigUpdate; }
ZT_ALWAYS_INLINE ZT_VirtualNetworkStatus status() const { return _status(); } inline ZT_VirtualNetworkStatus status() const { return _status(); }
ZT_ALWAYS_INLINE const NetworkConfig &config() const { return _config; } inline const NetworkConfig &config() const { return _config; }
ZT_ALWAYS_INLINE const MAC &mac() const { return _mac; } inline const MAC &mac() const { return _mac; }
/** /**
* Apply filters to an outgoing packet * Apply filters to an outgoing packet
@ -158,7 +158,7 @@ public:
* @param includeBridgedGroups If true, also check groups we've learned via bridging * @param includeBridgedGroups If true, also check groups we've learned via bridging
* @return True if this network endpoint / peer is a member * @return True if this network endpoint / peer is a member
*/ */
ZT_ALWAYS_INLINE bool subscribedToMulticastGroup(const MulticastGroup &mg,const bool includeBridgedGroups) const inline bool subscribedToMulticastGroup(const MulticastGroup &mg,const bool includeBridgedGroups) const
{ {
Mutex::Lock l(_myMulticastGroups_l); Mutex::Lock l(_myMulticastGroups_l);
if (std::binary_search(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg)) if (std::binary_search(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg))
@ -174,7 +174,7 @@ public:
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param mg New multicast group * @param mg New multicast group
*/ */
ZT_ALWAYS_INLINE void multicastSubscribe(void *tPtr,const MulticastGroup &mg) inline void multicastSubscribe(void *tPtr,const MulticastGroup &mg)
{ {
Mutex::Lock l(_myMulticastGroups_l); Mutex::Lock l(_myMulticastGroups_l);
if (!std::binary_search(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg)) { if (!std::binary_search(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg)) {
@ -189,7 +189,7 @@ public:
* *
* @param mg Multicast group * @param mg Multicast group
*/ */
ZT_ALWAYS_INLINE void multicastUnsubscribe(const MulticastGroup &mg) inline void multicastUnsubscribe(const MulticastGroup &mg)
{ {
Mutex::Lock l(_myMulticastGroups_l); Mutex::Lock l(_myMulticastGroups_l);
std::vector<MulticastGroup>::iterator i(std::lower_bound(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg)); std::vector<MulticastGroup>::iterator i(std::lower_bound(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg));
@ -230,12 +230,12 @@ public:
/** /**
* Set netconf failure to 'access denied' -- called in IncomingPacket when controller reports this * Set netconf failure to 'access denied' -- called in IncomingPacket when controller reports this
*/ */
ZT_ALWAYS_INLINE void setAccessDenied() { _netconfFailure = NETCONF_FAILURE_ACCESS_DENIED; } inline void setAccessDenied() { _netconfFailure = NETCONF_FAILURE_ACCESS_DENIED; }
/** /**
* Set netconf failure to 'not found' -- called by IncomingPacket when controller reports this * Set netconf failure to 'not found' -- called by IncomingPacket when controller reports this
*/ */
ZT_ALWAYS_INLINE void setNotFound() { _netconfFailure = NETCONF_FAILURE_NOT_FOUND; } inline void setNotFound() { _netconfFailure = NETCONF_FAILURE_NOT_FOUND; }
/** /**
* Determine whether this peer is permitted to communicate on this network * Determine whether this peer is permitted to communicate on this network
@ -256,7 +256,7 @@ public:
* @param mac MAC address * @param mac MAC address
* @return ZeroTier address of bridge to this MAC * @return ZeroTier address of bridge to this MAC
*/ */
ZT_ALWAYS_INLINE Address findBridgeTo(const MAC &mac) const inline Address findBridgeTo(const MAC &mac) const
{ {
Mutex::Lock _l(_remoteBridgeRoutes_l); Mutex::Lock _l(_remoteBridgeRoutes_l);
const Address *const br = _remoteBridgeRoutes.get(mac); const Address *const br = _remoteBridgeRoutes.get(mac);
@ -283,7 +283,7 @@ public:
* @param mg Multicast group * @param mg Multicast group
* @param now Current time * @param now Current time
*/ */
ZT_ALWAYS_INLINE void learnBridgedMulticastGroup(void *tPtr,const MulticastGroup &mg,int64_t now) inline void learnBridgedMulticastGroup(void *tPtr,const MulticastGroup &mg,int64_t now)
{ {
Mutex::Lock l(_myMulticastGroups_l); Mutex::Lock l(_myMulticastGroups_l);
_multicastGroupsBehindMe.set(mg,now); _multicastGroupsBehindMe.set(mg,now);
@ -292,7 +292,7 @@ public:
/** /**
* Validate a credential and learn it if it passes certificate and other checks * Validate a credential and learn it if it passes certificate and other checks
*/ */
ZT_ALWAYS_INLINE Membership::AddCredentialResult addCredential(void *tPtr,const CertificateOfMembership &com) inline Membership::AddCredentialResult addCredential(void *tPtr,const CertificateOfMembership &com)
{ {
if (com.networkId() != _id) if (com.networkId() != _id)
return Membership::ADD_REJECTED; return Membership::ADD_REJECTED;
@ -303,7 +303,7 @@ public:
/** /**
* Validate a credential and learn it if it passes certificate and other checks * Validate a credential and learn it if it passes certificate and other checks
*/ */
ZT_ALWAYS_INLINE Membership::AddCredentialResult addCredential(void *tPtr,const Capability &cap) inline Membership::AddCredentialResult addCredential(void *tPtr,const Capability &cap)
{ {
if (cap.networkId() != _id) if (cap.networkId() != _id)
return Membership::ADD_REJECTED; return Membership::ADD_REJECTED;
@ -314,7 +314,7 @@ public:
/** /**
* Validate a credential and learn it if it passes certificate and other checks * Validate a credential and learn it if it passes certificate and other checks
*/ */
ZT_ALWAYS_INLINE Membership::AddCredentialResult addCredential(void *tPtr,const Tag &tag) inline Membership::AddCredentialResult addCredential(void *tPtr,const Tag &tag)
{ {
if (tag.networkId() != _id) if (tag.networkId() != _id)
return Membership::ADD_REJECTED; return Membership::ADD_REJECTED;
@ -330,7 +330,7 @@ public:
/** /**
* Validate a credential and learn it if it passes certificate and other checks * Validate a credential and learn it if it passes certificate and other checks
*/ */
ZT_ALWAYS_INLINE Membership::AddCredentialResult addCredential(void *tPtr,const CertificateOfOwnership &coo) inline Membership::AddCredentialResult addCredential(void *tPtr,const CertificateOfOwnership &coo)
{ {
if (coo.networkId() != _id) if (coo.networkId() != _id)
return Membership::ADD_REJECTED; return Membership::ADD_REJECTED;
@ -345,7 +345,7 @@ public:
* @param to Destination peer address * @param to Destination peer address
* @param now Current time * @param now Current time
*/ */
ZT_ALWAYS_INLINE void pushCredentialsNow(void *tPtr,const Address &to,const int64_t now) inline void pushCredentialsNow(void *tPtr,const Address &to,const int64_t now)
{ {
Mutex::Lock _l(_memberships_l); Mutex::Lock _l(_memberships_l);
_memberships[to].pushCredentials(RR,tPtr,now,to,_config); _memberships[to].pushCredentials(RR,tPtr,now,to,_config);
@ -358,7 +358,7 @@ public:
* @param to Destination peer address * @param to Destination peer address
* @param now Current time * @param now Current time
*/ */
ZT_ALWAYS_INLINE void pushCredentialsIfNeeded(void *tPtr,const Address &to,const int64_t now) inline void pushCredentialsIfNeeded(void *tPtr,const Address &to,const int64_t now)
{ {
const int64_t tout = std::min(_config.credentialTimeMaxDelta,(int64_t)ZT_PEER_ACTIVITY_TIMEOUT); const int64_t tout = std::min(_config.credentialTimeMaxDelta,(int64_t)ZT_PEER_ACTIVITY_TIMEOUT);
Mutex::Lock _l(_memberships_l); Mutex::Lock _l(_memberships_l);
@ -373,7 +373,7 @@ public:
* This sets the network to completely remove itself on delete. This also prevents the * This sets the network to completely remove itself on delete. This also prevents the
* call of the normal port shutdown event on delete. * call of the normal port shutdown event on delete.
*/ */
ZT_ALWAYS_INLINE void destroy() inline void destroy()
{ {
_memberships_l.lock(); _memberships_l.lock();
_config_l.lock(); _config_l.lock();
@ -387,7 +387,7 @@ public:
* *
* @param ec Buffer to fill with externally-visible network configuration * @param ec Buffer to fill with externally-visible network configuration
*/ */
ZT_ALWAYS_INLINE void externalConfig(ZT_VirtualNetworkConfig *ec) const inline void externalConfig(ZT_VirtualNetworkConfig *ec) const
{ {
Mutex::Lock _l(_config_l); Mutex::Lock _l(_config_l);
_externalConfig(ec); _externalConfig(ec);
@ -399,7 +399,7 @@ public:
* @param f Function of (const Address,const Membership) * @param f Function of (const Address,const Membership)
*/ */
template<typename F> template<typename F>
ZT_ALWAYS_INLINE void eachMember(F f) inline void eachMember(F f)
{ {
Mutex::Lock ml(_memberships_l); Mutex::Lock ml(_memberships_l);
Hashtable<Address,Membership>::Iterator i(_memberships); Hashtable<Address,Membership>::Iterator i(_memberships);
@ -414,7 +414,7 @@ public:
/** /**
* @return Externally usable pointer-to-pointer exported via the core API * @return Externally usable pointer-to-pointer exported via the core API
*/ */
ZT_ALWAYS_INLINE void **userPtr() { return &_uPtr; } inline void **userPtr() { return &_uPtr; }
private: private:
void _requestConfiguration(void *tPtr); void _requestConfiguration(void *tPtr);
@ -440,7 +440,7 @@ private:
struct _IncomingConfigChunk struct _IncomingConfigChunk
{ {
ZT_ALWAYS_INLINE _IncomingConfigChunk() : ts(0),updateId(0),haveChunks(0),haveBytes(0),data() {} inline _IncomingConfigChunk() : ts(0),updateId(0),haveChunks(0),haveBytes(0),data() {}
uint64_t ts; uint64_t ts;
uint64_t updateId; uint64_t updateId;
uint64_t haveChunkIds[ZT_NETWORK_MAX_UPDATE_CHUNKS]; uint64_t haveChunkIds[ZT_NETWORK_MAX_UPDATE_CHUNKS];

View file

@ -177,7 +177,7 @@ namespace ZeroTier {
*/ */
struct NetworkConfig struct NetworkConfig
{ {
ZT_ALWAYS_INLINE NetworkConfig() : inline NetworkConfig() :
networkId(0), networkId(0),
timestamp(0), timestamp(0),
credentialTimeMaxDelta(0), credentialTimeMaxDelta(0),
@ -218,17 +218,17 @@ struct NetworkConfig
/** /**
* @return True if broadcast (ff:ff:ff:ff:ff:ff) address should work on this network * @return True if broadcast (ff:ff:ff:ff:ff:ff) address should work on this network
*/ */
ZT_ALWAYS_INLINE bool enableBroadcast() const { return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_BROADCAST) != 0); } inline bool enableBroadcast() const { return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_BROADCAST) != 0); }
/** /**
* @return True if IPv6 NDP emulation should be allowed for certain "magic" IPv6 address patterns * @return True if IPv6 NDP emulation should be allowed for certain "magic" IPv6 address patterns
*/ */
ZT_ALWAYS_INLINE bool ndpEmulation() const { return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION) != 0); } inline bool ndpEmulation() const { return ((this->flags & ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION) != 0); }
/** /**
* @return True if frames should not be compressed * @return True if frames should not be compressed
*/ */
ZT_ALWAYS_INLINE bool disableCompression() const inline bool disableCompression() const
{ {
#ifndef ZT_DISABLE_COMPRESSION #ifndef ZT_DISABLE_COMPRESSION
return ((this->flags & ZT_NETWORKCONFIG_FLAG_DISABLE_COMPRESSION) != 0); return ((this->flags & ZT_NETWORKCONFIG_FLAG_DISABLE_COMPRESSION) != 0);
@ -244,18 +244,18 @@ struct NetworkConfig
/** /**
* @return Network type is public (no access control) * @return Network type is public (no access control)
*/ */
ZT_ALWAYS_INLINE bool isPublic() const { return (this->type == ZT_NETWORK_TYPE_PUBLIC); } inline bool isPublic() const { return (this->type == ZT_NETWORK_TYPE_PUBLIC); }
/** /**
* @return Network type is private (certificate access control) * @return Network type is private (certificate access control)
*/ */
ZT_ALWAYS_INLINE bool isPrivate() const { return (this->type == ZT_NETWORK_TYPE_PRIVATE); } inline bool isPrivate() const { return (this->type == ZT_NETWORK_TYPE_PRIVATE); }
/** /**
* @param fromPeer Peer attempting to bridge other Ethernet peers onto network * @param fromPeer Peer attempting to bridge other Ethernet peers onto network
* @return True if this network allows bridging * @return True if this network allows bridging
*/ */
ZT_ALWAYS_INLINE bool permitsBridging(const Address &fromPeer) const inline bool permitsBridging(const Address &fromPeer) const
{ {
for(unsigned int i=0;i<specialistCount;++i) { for(unsigned int i=0;i<specialistCount;++i) {
if ((fromPeer == specialists[i])&&((specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE) != 0)) if ((fromPeer == specialists[i])&&((specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE) != 0))
@ -264,9 +264,9 @@ struct NetworkConfig
return false; return false;
} }
ZT_ALWAYS_INLINE operator bool() const { return (networkId != 0); } inline operator bool() const { return (networkId != 0); }
ZT_ALWAYS_INLINE bool operator==(const NetworkConfig &nc) const { return (memcmp(this,&nc,sizeof(NetworkConfig)) == 0); } inline bool operator==(const NetworkConfig &nc) const { return (memcmp(this,&nc,sizeof(NetworkConfig)) == 0); }
ZT_ALWAYS_INLINE bool operator!=(const NetworkConfig &nc) const { return (!(*this == nc)); } inline bool operator!=(const NetworkConfig &nc) const { return (!(*this == nc)); }
/** /**
* Add a specialist or mask flags if already present * Add a specialist or mask flags if already present
@ -278,7 +278,7 @@ struct NetworkConfig
* @param f Flags (OR of specialist role/type flags) * @param f Flags (OR of specialist role/type flags)
* @return True if successfully masked or added * @return True if successfully masked or added
*/ */
ZT_ALWAYS_INLINE bool addSpecialist(const Address &a,const uint64_t f) inline bool addSpecialist(const Address &a,const uint64_t f)
{ {
const uint64_t aint = a.toInt(); const uint64_t aint = a.toInt();
for(unsigned int i=0;i<specialistCount;++i) { for(unsigned int i=0;i<specialistCount;++i) {
@ -294,7 +294,7 @@ struct NetworkConfig
return false; return false;
} }
ZT_ALWAYS_INLINE const Capability *capability(const uint32_t id) const inline const Capability *capability(const uint32_t id) const
{ {
for(unsigned int i=0;i<capabilityCount;++i) { for(unsigned int i=0;i<capabilityCount;++i) {
if (capabilities[i].id() == id) if (capabilities[i].id() == id)
@ -303,7 +303,7 @@ struct NetworkConfig
return (Capability *)0; return (Capability *)0;
} }
ZT_ALWAYS_INLINE const Tag *tag(const uint32_t id) const inline const Tag *tag(const uint32_t id) const
{ {
for(unsigned int i=0;i<tagCount;++i) { for(unsigned int i=0;i<tagCount;++i) {
if (tags[i].id() == id) if (tags[i].id() == id)

View file

@ -188,7 +188,7 @@ struct _processBackgroundTasks_eachRootName
void *tPtr; void *tPtr;
bool updateAll; bool updateAll;
ZT_ALWAYS_INLINE bool operator()(const Str &dnsName,const Locator &loc) inline bool operator()(const Str &dnsName,const Locator &loc)
{ {
if ((strchr(dnsName.c_str(),'.'))&&((updateAll)||(!loc))) { if ((strchr(dnsName.c_str(),'.'))&&((updateAll)||(!loc))) {
_processBackgroundTasks_dnsResultAccumulator *dnsReq = new _processBackgroundTasks_dnsResultAccumulator(dnsName); _processBackgroundTasks_dnsResultAccumulator *dnsReq = new _processBackgroundTasks_dnsResultAccumulator(dnsName);
@ -205,7 +205,7 @@ struct _processBackgroundTasks_ping_eachRoot
void *tPtr; void *tPtr;
bool online; bool online;
ZT_ALWAYS_INLINE bool operator()(const SharedPtr<Peer> &peer,const std::vector<InetAddress> &addrs) inline bool operator()(const SharedPtr<Peer> &peer,const std::vector<InetAddress> &addrs)
{ {
unsigned int v4SendCount = 0,v6SendCount = 0; unsigned int v4SendCount = 0,v6SendCount = 0;
peer->ping(tPtr,now,v4SendCount,v6SendCount); peer->ping(tPtr,now,v4SendCount,v6SendCount);
@ -226,7 +226,7 @@ struct _processBackgroundTasks_ping_eachPeer
void *tPtr; void *tPtr;
Hashtable< void *,bool > *roots; Hashtable< void *,bool > *roots;
ZT_ALWAYS_INLINE bool operator()(const SharedPtr<Peer> &peer) inline bool operator()(const SharedPtr<Peer> &peer)
{ {
if (!roots->contains((void *)peer.ptr())) { if (!roots->contains((void *)peer.ptr())) {
unsigned int v4SendCount = 0,v6SendCount = 0; unsigned int v4SendCount = 0,v6SendCount = 0;

View file

@ -111,9 +111,9 @@ public:
// Internal functions ------------------------------------------------------ // Internal functions ------------------------------------------------------
ZT_ALWAYS_INLINE int64_t now() const { return _now; } inline int64_t now() const { return _now; }
ZT_ALWAYS_INLINE bool putPacket(void *tPtr,const int64_t localSocket,const InetAddress &addr,const void *data,unsigned int len,unsigned int ttl = 0) inline bool putPacket(void *tPtr,const int64_t localSocket,const InetAddress &addr,const void *data,unsigned int len,unsigned int ttl = 0)
{ {
return (_cb.wirePacketSendFunction( return (_cb.wirePacketSendFunction(
reinterpret_cast<ZT_Node *>(this), reinterpret_cast<ZT_Node *>(this),
@ -126,7 +126,7 @@ public:
ttl) == 0); ttl) == 0);
} }
ZT_ALWAYS_INLINE void putFrame(void *tPtr,uint64_t nwid,void **nuptr,const MAC &source,const MAC &dest,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) inline void putFrame(void *tPtr,uint64_t nwid,void **nuptr,const MAC &source,const MAC &dest,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
{ {
_cb.virtualNetworkFrameFunction( _cb.virtualNetworkFrameFunction(
reinterpret_cast<ZT_Node *>(this), reinterpret_cast<ZT_Node *>(this),
@ -142,7 +142,7 @@ public:
len); len);
} }
ZT_ALWAYS_INLINE SharedPtr<Network> network(uint64_t nwid) const inline SharedPtr<Network> network(uint64_t nwid) const
{ {
Mutex::Lock _l(_networks_m); Mutex::Lock _l(_networks_m);
const SharedPtr<Network> *n = _networks.get(nwid); const SharedPtr<Network> *n = _networks.get(nwid);
@ -151,13 +151,13 @@ public:
return SharedPtr<Network>(); return SharedPtr<Network>();
} }
ZT_ALWAYS_INLINE bool belongsToNetwork(uint64_t nwid) const inline bool belongsToNetwork(uint64_t nwid) const
{ {
Mutex::Lock _l(_networks_m); Mutex::Lock _l(_networks_m);
return _networks.contains(nwid); return _networks.contains(nwid);
} }
ZT_ALWAYS_INLINE std::vector< SharedPtr<Network> > allNetworks() const inline std::vector< SharedPtr<Network> > allNetworks() const
{ {
std::vector< SharedPtr<Network> > nw; std::vector< SharedPtr<Network> > nw;
Mutex::Lock _l(_networks_m); Mutex::Lock _l(_networks_m);
@ -169,7 +169,7 @@ public:
return nw; return nw;
} }
ZT_ALWAYS_INLINE std::vector<ZT_InterfaceAddress> directPaths() const inline std::vector<ZT_InterfaceAddress> directPaths() const
{ {
Mutex::Lock _l(_localInterfaceAddresses_m); Mutex::Lock _l(_localInterfaceAddresses_m);
return _localInterfaceAddresses; return _localInterfaceAddresses;
@ -178,16 +178,16 @@ public:
void setInterfaceAddresses(const ZT_InterfaceAddress *addrs,unsigned int addrCount); void setInterfaceAddresses(const ZT_InterfaceAddress *addrs,unsigned int addrCount);
SharedPtr< const Locator > locator(); SharedPtr< const Locator > locator();
ZT_ALWAYS_INLINE void postEvent(void *tPtr,ZT_Event ev,const void *md = (const void *)0) { _cb.eventCallback(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ev,md); } inline void postEvent(void *tPtr,ZT_Event ev,const void *md = (const void *)0) { _cb.eventCallback(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ev,md); }
ZT_ALWAYS_INLINE void configureVirtualNetworkPort(void *tPtr,uint64_t nwid,void **nuptr,ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nc) { _cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,nwid,nuptr,op,nc); } inline void configureVirtualNetworkPort(void *tPtr,uint64_t nwid,void **nuptr,ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nc) { _cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,nwid,nuptr,op,nc); }
ZT_ALWAYS_INLINE bool online() const { return _online; } inline bool online() const { return _online; }
ZT_ALWAYS_INLINE int stateObjectGet(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2],void *const data,const unsigned int maxlen) { return _cb.stateGetFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,type,id,data,maxlen); } inline int stateObjectGet(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2],void *const data,const unsigned int maxlen) { return _cb.stateGetFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,type,id,data,maxlen); }
ZT_ALWAYS_INLINE void stateObjectPut(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2],const void *const data,const unsigned int len) { _cb.statePutFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,type,id,data,(int)len); } inline void stateObjectPut(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2],const void *const data,const unsigned int len) { _cb.statePutFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,type,id,data,(int)len); }
ZT_ALWAYS_INLINE void stateObjectDelete(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2]) { _cb.statePutFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,type,id,(const void *)0,-1); } inline void stateObjectDelete(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2]) { _cb.statePutFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,type,id,(const void *)0,-1); }
bool shouldUsePathForZeroTierTraffic(void *tPtr,const Address &ztaddr,const int64_t localSocket,const InetAddress &remoteAddress); bool shouldUsePathForZeroTierTraffic(void *tPtr,const Address &ztaddr,const int64_t localSocket,const InetAddress &remoteAddress);
ZT_ALWAYS_INLINE bool externalPathLookup(void *tPtr,const Address &ztaddr,int family,InetAddress &addr) { return ( (_cb.pathLookupFunction) ? (_cb.pathLookupFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ztaddr.toInt(),family,reinterpret_cast<struct sockaddr_storage *>(&addr)) != 0) : false ); } inline bool externalPathLookup(void *tPtr,const Address &ztaddr,int family,InetAddress &addr) { return ( (_cb.pathLookupFunction) ? (_cb.pathLookupFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ztaddr.toInt(),family,reinterpret_cast<struct sockaddr_storage *>(&addr)) != 0) : false ); }
ZT_ResultCode setPhysicalPathConfiguration(const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig); ZT_ResultCode setPhysicalPathConfiguration(const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig);
ZT_ALWAYS_INLINE const Identity &identity() const { return _RR.identity; } inline const Identity &identity() const { return _RR.identity; }
/** /**
* Register that we are expecting a reply to a packet ID * Register that we are expecting a reply to a packet ID
@ -198,7 +198,7 @@ public:
* *
* @param packetId Packet ID to expect reply to * @param packetId Packet ID to expect reply to
*/ */
ZT_ALWAYS_INLINE void expectReplyTo(const uint64_t packetId) inline void expectReplyTo(const uint64_t packetId)
{ {
const unsigned long pid2 = (unsigned long)(packetId >> 32); const unsigned long pid2 = (unsigned long)(packetId >> 32);
const unsigned long bucket = (unsigned long)(pid2 & ZT_EXPECTING_REPLIES_BUCKET_MASK1); const unsigned long bucket = (unsigned long)(pid2 & ZT_EXPECTING_REPLIES_BUCKET_MASK1);
@ -215,7 +215,7 @@ public:
* @param packetId Packet ID to check * @param packetId Packet ID to check
* @return True if we're expecting a reply * @return True if we're expecting a reply
*/ */
ZT_ALWAYS_INLINE bool expectingReplyTo(const uint64_t packetId) const inline bool expectingReplyTo(const uint64_t packetId) const
{ {
const uint32_t pid2 = (uint32_t)(packetId >> 32); const uint32_t pid2 = (uint32_t)(packetId >> 32);
const unsigned long bucket = (unsigned long)(pid2 & ZT_EXPECTING_REPLIES_BUCKET_MASK1); const unsigned long bucket = (unsigned long)(pid2 & ZT_EXPECTING_REPLIES_BUCKET_MASK1);
@ -233,7 +233,7 @@ public:
* @param from Source address of packet * @param from Source address of packet
* @return True if within rate limits * @return True if within rate limits
*/ */
ZT_ALWAYS_INLINE bool rateGateIdentityVerification(const int64_t now,const InetAddress &from) inline bool rateGateIdentityVerification(const int64_t now,const InetAddress &from)
{ {
unsigned long iph = from.rateGateHash(); unsigned long iph = from.rateGateHash();
if ((now - _lastIdentityVerification[iph]) >= ZT_IDENTITY_VALIDATION_SOURCE_RATE_LIMIT) { if ((now - _lastIdentityVerification[iph]) >= ZT_IDENTITY_VALIDATION_SOURCE_RATE_LIMIT) {
@ -247,10 +247,10 @@ public:
virtual void ncSendRevocation(const Address &destination,const Revocation &rev); virtual void ncSendRevocation(const Address &destination,const Revocation &rev);
virtual void ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &destination,NetworkController::ErrorCode errorCode); virtual void ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &destination,NetworkController::ErrorCode errorCode);
ZT_ALWAYS_INLINE void setMultipathMode(uint8_t mode) { _multipathMode = mode; } inline void setMultipathMode(uint8_t mode) { _multipathMode = mode; }
ZT_ALWAYS_INLINE uint8_t getMultipathMode() { return _multipathMode; } inline uint8_t getMultipathMode() { return _multipathMode; }
ZT_ALWAYS_INLINE bool localControllerHasAuthorized(const int64_t now,const uint64_t nwid,const Address &addr) const inline bool localControllerHasAuthorized(const int64_t now,const uint64_t nwid,const Address &addr) const
{ {
_localControllerAuthorizations_m.lock(); _localControllerAuthorizations_m.lock();
const int64_t *const at = _localControllerAuthorizations.get(_LocalControllerAuth(nwid,addr)); const int64_t *const at = _localControllerAuthorizations.get(_LocalControllerAuth(nwid,addr));
@ -281,10 +281,10 @@ private:
struct _LocalControllerAuth struct _LocalControllerAuth
{ {
uint64_t nwid,address; uint64_t nwid,address;
ZT_ALWAYS_INLINE _LocalControllerAuth(const uint64_t nwid_,const Address &address_) : nwid(nwid_),address(address_.toInt()) {} inline _LocalControllerAuth(const uint64_t nwid_,const Address &address_) : nwid(nwid_),address(address_.toInt()) {}
ZT_ALWAYS_INLINE unsigned long hashCode() const { return (unsigned long)(nwid ^ address); } inline unsigned long hashCode() const { return (unsigned long)(nwid ^ address); }
ZT_ALWAYS_INLINE bool operator==(const _LocalControllerAuth &a) const { return ((a.nwid == nwid)&&(a.address == address)); } inline bool operator==(const _LocalControllerAuth &a) const { return ((a.nwid == nwid)&&(a.address == address)); }
ZT_ALWAYS_INLINE bool operator!=(const _LocalControllerAuth &a) const { return ((a.nwid != nwid)||(a.address != address)); } inline bool operator!=(const _LocalControllerAuth &a) const { return ((a.nwid != nwid)||(a.address != address)); }
}; };
Hashtable< _LocalControllerAuth,int64_t > _localControllerAuthorizations; Hashtable< _LocalControllerAuth,int64_t > _localControllerAuthorizations;
Hashtable< uint64_t,SharedPtr<Network> > _networks; Hashtable< uint64_t,SharedPtr<Network> > _networks;

View file

@ -53,7 +53,7 @@
* 8 - 1.1.17 ... 1.2.0 * 8 - 1.1.17 ... 1.2.0
* + Multipart network configurations for large network configs * + Multipart network configurations for large network configs
* + Tags and Capabilities * + Tags and Capabilities
* + ZT_ALWAYS_INLINE push of CertificateOfMembership deprecated * + inline push of CertificateOfMembership deprecated
* 9 - 1.2.0 ... 1.2.14 * 9 - 1.2.0 ... 1.2.14
* 10 - 1.4.0 ... 1.6.0 * 10 - 1.4.0 ... 1.6.0
* + Multipath capability and load balancing * + Multipath capability and load balancing
@ -305,14 +305,14 @@ public:
class Fragment : public Buffer<ZT_PROTO_MAX_PACKET_LENGTH> class Fragment : public Buffer<ZT_PROTO_MAX_PACKET_LENGTH>
{ {
public: public:
ZT_ALWAYS_INLINE Fragment() : inline Fragment() :
Buffer<ZT_PROTO_MAX_PACKET_LENGTH>() {} Buffer<ZT_PROTO_MAX_PACKET_LENGTH>() {}
template<unsigned int C2> template<unsigned int C2>
ZT_ALWAYS_INLINE Fragment(const Buffer<C2> &b) : inline Fragment(const Buffer<C2> &b) :
Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(b) {} Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(b) {}
ZT_ALWAYS_INLINE Fragment(const void *data,unsigned int len) : inline Fragment(const void *data,unsigned int len) :
Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(data,len) {} Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(data,len) {}
/** /**
@ -324,7 +324,7 @@ public:
* @param fragNo Which fragment (>= 1, since 0 is Packet with end chopped off) * @param fragNo Which fragment (>= 1, since 0 is Packet with end chopped off)
* @param fragTotal Total number of fragments (including 0) * @param fragTotal Total number of fragments (including 0)
*/ */
ZT_ALWAYS_INLINE Fragment(const Packet &p,unsigned int fragStart,unsigned int fragLen,unsigned int fragNo,unsigned int fragTotal) inline Fragment(const Packet &p,unsigned int fragStart,unsigned int fragLen,unsigned int fragNo,unsigned int fragTotal)
{ {
init(p,fragStart,fragLen,fragNo,fragTotal); init(p,fragStart,fragLen,fragNo,fragTotal);
} }
@ -338,7 +338,7 @@ public:
* @param fragNo Which fragment (>= 1, since 0 is Packet with end chopped off) * @param fragNo Which fragment (>= 1, since 0 is Packet with end chopped off)
* @param fragTotal Total number of fragments (including 0) * @param fragTotal Total number of fragments (including 0)
*/ */
ZT_ALWAYS_INLINE void init(const Packet &p,unsigned int fragStart,unsigned int fragLen,unsigned int fragNo,unsigned int fragTotal) inline void init(const Packet &p,unsigned int fragStart,unsigned int fragLen,unsigned int fragNo,unsigned int fragTotal)
{ {
if ((fragStart + fragLen) > p.size()) if ((fragStart + fragLen) > p.size())
throw ZT_EXCEPTION_OUT_OF_BOUNDS; throw ZT_EXCEPTION_OUT_OF_BOUNDS;
@ -359,37 +359,37 @@ public:
* *
* @return Destination ZT address * @return Destination ZT address
*/ */
ZT_ALWAYS_INLINE Address destination() const { return Address(field(ZT_PACKET_FRAGMENT_IDX_DEST,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); } inline Address destination() const { return Address(field(ZT_PACKET_FRAGMENT_IDX_DEST,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
/** /**
* @return True if fragment is of a valid length * @return True if fragment is of a valid length
*/ */
ZT_ALWAYS_INLINE bool lengthValid() const { return (size() >= ZT_PACKET_FRAGMENT_IDX_PAYLOAD); } inline bool lengthValid() const { return (size() >= ZT_PACKET_FRAGMENT_IDX_PAYLOAD); }
/** /**
* @return ID of packet this is a fragment of * @return ID of packet this is a fragment of
*/ */
ZT_ALWAYS_INLINE uint64_t packetId() const { return at<uint64_t>(ZT_PACKET_FRAGMENT_IDX_PACKET_ID); } inline uint64_t packetId() const { return at<uint64_t>(ZT_PACKET_FRAGMENT_IDX_PACKET_ID); }
/** /**
* @return Total number of fragments in packet * @return Total number of fragments in packet
*/ */
ZT_ALWAYS_INLINE unsigned int totalFragments() const { return (((unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO]) >> 4) & 0xf); } inline unsigned int totalFragments() const { return (((unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO]) >> 4) & 0xf); }
/** /**
* @return Fragment number of this fragment * @return Fragment number of this fragment
*/ */
ZT_ALWAYS_INLINE unsigned int fragmentNumber() const { return ((unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO]) & 0xf); } inline unsigned int fragmentNumber() const { return ((unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_NO]) & 0xf); }
/** /**
* @return Fragment ZT hop count * @return Fragment ZT hop count
*/ */
ZT_ALWAYS_INLINE unsigned int hops() const { return (unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_HOPS]); } inline unsigned int hops() const { return (unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_HOPS]); }
/** /**
* Increment this packet's hop count * Increment this packet's hop count
*/ */
ZT_ALWAYS_INLINE unsigned int incrementHops() inline unsigned int incrementHops()
{ {
return (unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_HOPS] = (((*this)[ZT_PACKET_FRAGMENT_IDX_HOPS]) + 1)); return (unsigned int)((*this)[ZT_PACKET_FRAGMENT_IDX_HOPS] = (((*this)[ZT_PACKET_FRAGMENT_IDX_HOPS]) + 1));
} }
@ -397,12 +397,12 @@ public:
/** /**
* @return Length of payload in bytes * @return Length of payload in bytes
*/ */
ZT_ALWAYS_INLINE unsigned int payloadLength() const { return ((size() > ZT_PACKET_FRAGMENT_IDX_PAYLOAD) ? (size() - ZT_PACKET_FRAGMENT_IDX_PAYLOAD) : 0); } inline unsigned int payloadLength() const { return ((size() > ZT_PACKET_FRAGMENT_IDX_PAYLOAD) ? (size() - ZT_PACKET_FRAGMENT_IDX_PAYLOAD) : 0); }
/** /**
* @return Raw packet payload * @return Raw packet payload
*/ */
ZT_ALWAYS_INLINE const unsigned char *payload() const { return field(ZT_PACKET_FRAGMENT_IDX_PAYLOAD,size() - ZT_PACKET_FRAGMENT_IDX_PAYLOAD); } inline const unsigned char *payload() const { return field(ZT_PACKET_FRAGMENT_IDX_PAYLOAD,size() - ZT_PACKET_FRAGMENT_IDX_PAYLOAD); }
}; };
/** /**
@ -970,12 +970,12 @@ public:
}; };
template<unsigned int C2> template<unsigned int C2>
ZT_ALWAYS_INLINE Packet(const Buffer<C2> &b) : inline Packet(const Buffer<C2> &b) :
Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(b) Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(b)
{ {
} }
ZT_ALWAYS_INLINE Packet(const void *data,unsigned int len) : inline Packet(const void *data,unsigned int len) :
Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(data,len) Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(data,len)
{ {
} }
@ -987,7 +987,7 @@ public:
* Use the header access methods (setDestination() and friends) to fill out * Use the header access methods (setDestination() and friends) to fill out
* the header. Payload should be appended; initial size is header size. * the header. Payload should be appended; initial size is header size.
*/ */
ZT_ALWAYS_INLINE Packet() : inline Packet() :
Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(ZT_PROTO_MIN_PACKET_LENGTH) Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(ZT_PROTO_MIN_PACKET_LENGTH)
{ {
setAt<uint64_t>(ZT_PACKET_IDX_IV,Packet::nextPacketId()); setAt<uint64_t>(ZT_PACKET_IDX_IV,Packet::nextPacketId());
@ -1003,7 +1003,7 @@ public:
* @param prototype Prototype packet * @param prototype Prototype packet
* @param dest Destination ZeroTier address for new packet * @param dest Destination ZeroTier address for new packet
*/ */
ZT_ALWAYS_INLINE Packet(const Packet &prototype,const Address &dest) : inline Packet(const Packet &prototype,const Address &dest) :
Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(prototype) Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(prototype)
{ {
setAt<uint64_t>(ZT_PACKET_IDX_IV,Packet::nextPacketId()); setAt<uint64_t>(ZT_PACKET_IDX_IV,Packet::nextPacketId());
@ -1017,7 +1017,7 @@ public:
* @param source Source ZT address * @param source Source ZT address
* @param v Verb * @param v Verb
*/ */
ZT_ALWAYS_INLINE Packet(const Address &dest,const Address &source,const Verb v) : inline Packet(const Address &dest,const Address &source,const Verb v) :
Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(ZT_PROTO_MIN_PACKET_LENGTH) Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(ZT_PROTO_MIN_PACKET_LENGTH)
{ {
setAt<uint64_t>(ZT_PACKET_IDX_IV,Packet::nextPacketId()); setAt<uint64_t>(ZT_PACKET_IDX_IV,Packet::nextPacketId());
@ -1034,7 +1034,7 @@ public:
* @param source Source ZT address * @param source Source ZT address
* @param v Verb * @param v Verb
*/ */
ZT_ALWAYS_INLINE void reset(const Address &dest,const Address &source,const Verb v) inline void reset(const Address &dest,const Address &source,const Verb v)
{ {
setSize(ZT_PROTO_MIN_PACKET_LENGTH); setSize(ZT_PROTO_MIN_PACKET_LENGTH);
setAt<uint64_t>(ZT_PACKET_IDX_IV,Packet::nextPacketId()); setAt<uint64_t>(ZT_PACKET_IDX_IV,Packet::nextPacketId());
@ -1051,52 +1051,52 @@ public:
* technically different but otherwise identical copies of the same * technically different but otherwise identical copies of the same
* packet. * packet.
*/ */
ZT_ALWAYS_INLINE void newInitializationVector() { setAt<uint64_t>(ZT_PACKET_IDX_IV,Packet::nextPacketId()); } inline void newInitializationVector() { setAt<uint64_t>(ZT_PACKET_IDX_IV,Packet::nextPacketId()); }
/** /**
* Set this packet's destination * Set this packet's destination
* *
* @param dest ZeroTier address of destination * @param dest ZeroTier address of destination
*/ */
ZT_ALWAYS_INLINE void setDestination(const Address &dest) { dest.copyTo(field(ZT_PACKET_IDX_DEST,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); } inline void setDestination(const Address &dest) { dest.copyTo(field(ZT_PACKET_IDX_DEST,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
/** /**
* Set this packet's source * Set this packet's source
* *
* @param source ZeroTier address of source * @param source ZeroTier address of source
*/ */
ZT_ALWAYS_INLINE void setSource(const Address &source) { source.copyTo(field(ZT_PACKET_IDX_SOURCE,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); } inline void setSource(const Address &source) { source.copyTo(field(ZT_PACKET_IDX_SOURCE,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
/** /**
* Get this packet's destination * Get this packet's destination
* *
* @return Destination ZT address * @return Destination ZT address
*/ */
ZT_ALWAYS_INLINE Address destination() const { return Address(field(ZT_PACKET_IDX_DEST,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); } inline Address destination() const { return Address(field(ZT_PACKET_IDX_DEST,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
/** /**
* Get this packet's source * Get this packet's source
* *
* @return Source ZT address * @return Source ZT address
*/ */
ZT_ALWAYS_INLINE Address source() const { return Address(field(ZT_PACKET_IDX_SOURCE,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); } inline Address source() const { return Address(field(ZT_PACKET_IDX_SOURCE,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); }
/** /**
* @return True if packet is of valid length * @return True if packet is of valid length
*/ */
ZT_ALWAYS_INLINE bool lengthValid() const { return (size() >= ZT_PROTO_MIN_PACKET_LENGTH); } inline bool lengthValid() const { return (size() >= ZT_PROTO_MIN_PACKET_LENGTH); }
/** /**
* @return True if packet is fragmented (expect fragments) * @return True if packet is fragmented (expect fragments)
*/ */
ZT_ALWAYS_INLINE bool fragmented() const { return (((unsigned char)(*this)[ZT_PACKET_IDX_FLAGS] & ZT_PROTO_FLAG_FRAGMENTED) != 0); } inline bool fragmented() const { return (((unsigned char)(*this)[ZT_PACKET_IDX_FLAGS] & ZT_PROTO_FLAG_FRAGMENTED) != 0); }
/** /**
* Set this packet's fragmented flag * Set this packet's fragmented flag
* *
* @param f Fragmented flag value * @param f Fragmented flag value
*/ */
ZT_ALWAYS_INLINE void setFragmented(bool f) inline void setFragmented(bool f)
{ {
if (f) if (f)
(*this)[ZT_PACKET_IDX_FLAGS] |= (char)ZT_PROTO_FLAG_FRAGMENTED; (*this)[ZT_PACKET_IDX_FLAGS] |= (char)ZT_PROTO_FLAG_FRAGMENTED;
@ -1106,17 +1106,17 @@ public:
/** /**
* @return True if compressed (result only valid if unencrypted) * @return True if compressed (result only valid if unencrypted)
*/ */
ZT_ALWAYS_INLINE bool compressed() const { return (((unsigned char)(*this)[ZT_PACKET_IDX_VERB] & ZT_PROTO_VERB_FLAG_COMPRESSED) != 0); } inline bool compressed() const { return (((unsigned char)(*this)[ZT_PACKET_IDX_VERB] & ZT_PROTO_VERB_FLAG_COMPRESSED) != 0); }
/** /**
* @return ZeroTier forwarding hops (0 to 7) * @return ZeroTier forwarding hops (0 to 7)
*/ */
ZT_ALWAYS_INLINE unsigned int hops() const { return ((unsigned int)(*this)[ZT_PACKET_IDX_FLAGS] & 0x07); } inline unsigned int hops() const { return ((unsigned int)(*this)[ZT_PACKET_IDX_FLAGS] & 0x07); }
/** /**
* Increment this packet's hop count * Increment this packet's hop count
*/ */
ZT_ALWAYS_INLINE unsigned char incrementHops() inline unsigned char incrementHops()
{ {
unsigned char &b = (*this)[ZT_PACKET_IDX_FLAGS]; unsigned char &b = (*this)[ZT_PACKET_IDX_FLAGS];
const unsigned char h = (b + 1) & 0x07; const unsigned char h = (b + 1) & 0x07;
@ -1127,7 +1127,7 @@ public:
/** /**
* @return Cipher suite selector: 0 - 7 (see #defines) * @return Cipher suite selector: 0 - 7 (see #defines)
*/ */
ZT_ALWAYS_INLINE unsigned int cipher() const inline unsigned int cipher() const
{ {
return (((unsigned int)(*this)[ZT_PACKET_IDX_FLAGS] & 0x38) >> 3); return (((unsigned int)(*this)[ZT_PACKET_IDX_FLAGS] & 0x38) >> 3);
} }
@ -1135,7 +1135,7 @@ public:
/** /**
* Set this packet's cipher suite * Set this packet's cipher suite
*/ */
ZT_ALWAYS_INLINE void setCipher(unsigned int c) inline void setCipher(unsigned int c)
{ {
unsigned char &b = (*this)[ZT_PACKET_IDX_FLAGS]; unsigned char &b = (*this)[ZT_PACKET_IDX_FLAGS];
b = (b & 0xc7) | (unsigned char)((c << 3) & 0x38); // bits: FFCCCHHH b = (b & 0xc7) | (unsigned char)((c << 3) & 0x38); // bits: FFCCCHHH
@ -1146,14 +1146,14 @@ public:
* *
* @return Trusted path ID (from MAC field) * @return Trusted path ID (from MAC field)
*/ */
ZT_ALWAYS_INLINE uint64_t trustedPathId() const { return at<uint64_t>(ZT_PACKET_IDX_MAC); } inline uint64_t trustedPathId() const { return at<uint64_t>(ZT_PACKET_IDX_MAC); }
/** /**
* Set this packet's trusted path ID and set the cipher spec to trusted path * Set this packet's trusted path ID and set the cipher spec to trusted path
* *
* @param tpid Trusted path ID * @param tpid Trusted path ID
*/ */
ZT_ALWAYS_INLINE void setTrusted(const uint64_t tpid) inline void setTrusted(const uint64_t tpid)
{ {
setCipher(ZT_PROTO_CIPHER_SUITE__NONE); setCipher(ZT_PROTO_CIPHER_SUITE__NONE);
setAt(ZT_PACKET_IDX_MAC,tpid); setAt(ZT_PACKET_IDX_MAC,tpid);
@ -1170,7 +1170,7 @@ public:
* *
* @return Packet ID * @return Packet ID
*/ */
ZT_ALWAYS_INLINE uint64_t packetId() const { return at<uint64_t>(ZT_PACKET_IDX_IV); } inline uint64_t packetId() const { return at<uint64_t>(ZT_PACKET_IDX_IV); }
/** /**
* Set packet verb * Set packet verb
@ -1180,22 +1180,22 @@ public:
* *
* @param v New packet verb * @param v New packet verb
*/ */
ZT_ALWAYS_INLINE void setVerb(Verb v) { (*this)[ZT_PACKET_IDX_VERB] = (char)v; } inline void setVerb(Verb v) { (*this)[ZT_PACKET_IDX_VERB] = (char)v; }
/** /**
* @return Packet verb (not including flag bits) * @return Packet verb (not including flag bits)
*/ */
ZT_ALWAYS_INLINE Verb verb() const { return (Verb)((*this)[ZT_PACKET_IDX_VERB] & 0x1f); } inline Verb verb() const { return (Verb)((*this)[ZT_PACKET_IDX_VERB] & 0x1f); }
/** /**
* @return Length of packet payload * @return Length of packet payload
*/ */
ZT_ALWAYS_INLINE unsigned int payloadLength() const { return ((size() < ZT_PROTO_MIN_PACKET_LENGTH) ? 0 : (size() - ZT_PROTO_MIN_PACKET_LENGTH)); } inline unsigned int payloadLength() const { return ((size() < ZT_PROTO_MIN_PACKET_LENGTH) ? 0 : (size() - ZT_PROTO_MIN_PACKET_LENGTH)); }
/** /**
* @return Raw packet payload * @return Raw packet payload
*/ */
ZT_ALWAYS_INLINE const unsigned char *payload() const { return field(ZT_PACKET_IDX_PAYLOAD,size() - ZT_PACKET_IDX_PAYLOAD); } inline const unsigned char *payload() const { return field(ZT_PACKET_IDX_PAYLOAD,size() - ZT_PACKET_IDX_PAYLOAD); }
/** /**
* Armor packet for transport * Armor packet for transport
@ -1255,7 +1255,7 @@ private:
* @param in Input key (32 bytes) * @param in Input key (32 bytes)
* @param out Output buffer (32 bytes) * @param out Output buffer (32 bytes)
*/ */
ZT_ALWAYS_INLINE void _salsa20MangleKey(const unsigned char *in,unsigned char *out) const inline void _salsa20MangleKey(const unsigned char *in,unsigned char *out) const
{ {
const unsigned char *d = (const unsigned char *)data(); const unsigned char *d = (const unsigned char *)data();

View file

@ -52,9 +52,9 @@ public:
class HashKey class HashKey
{ {
public: public:
ZT_ALWAYS_INLINE HashKey() {} inline HashKey() {}
ZT_ALWAYS_INLINE HashKey(const int64_t l,const InetAddress &r) inline HashKey(const int64_t l,const InetAddress &r)
{ {
if (r.ss_family == AF_INET) { if (r.ss_family == AF_INET) {
_k[0] = (uint64_t)reinterpret_cast<const struct sockaddr_in *>(&r)->sin_addr.s_addr; _k[0] = (uint64_t)reinterpret_cast<const struct sockaddr_in *>(&r)->sin_addr.s_addr;
@ -69,16 +69,16 @@ public:
} }
} }
ZT_ALWAYS_INLINE unsigned long hashCode() const { return (unsigned long)(_k[0] + _k[1] + _k[2]); } inline unsigned long hashCode() const { return (unsigned long)(_k[0] + _k[1] + _k[2]); }
ZT_ALWAYS_INLINE bool operator==(const HashKey &k) const { return ( (_k[0] == k._k[0]) && (_k[1] == k._k[1]) && (_k[2] == k._k[2]) ); } inline bool operator==(const HashKey &k) const { return ( (_k[0] == k._k[0]) && (_k[1] == k._k[1]) && (_k[2] == k._k[2]) ); }
ZT_ALWAYS_INLINE bool operator!=(const HashKey &k) const { return (!(*this == k)); } inline bool operator!=(const HashKey &k) const { return (!(*this == k)); }
private: private:
uint64_t _k[3]; uint64_t _k[3];
}; };
ZT_ALWAYS_INLINE Path() : inline Path() :
_lastOut(0), _lastOut(0),
_lastIn(0), _lastIn(0),
_lastPathQualityComputeTime(0), _lastPathQualityComputeTime(0),
@ -110,7 +110,7 @@ public:
memset(_addrString, 0, sizeof(_addrString)); memset(_addrString, 0, sizeof(_addrString));
} }
ZT_ALWAYS_INLINE Path(const int64_t localSocket,const InetAddress &addr) : inline Path(const int64_t localSocket,const InetAddress &addr) :
_lastOut(0), _lastOut(0),
_lastIn(0), _lastIn(0),
_lastPathQualityComputeTime(0), _lastPathQualityComputeTime(0),
@ -151,7 +151,7 @@ public:
* *
* @param t Time of receive * @param t Time of receive
*/ */
ZT_ALWAYS_INLINE void received(const uint64_t t) { _lastIn = t; } inline void received(const uint64_t t) { _lastIn = t; }
/** /**
* Send a packet via this path (last out time is also updated) * Send a packet via this path (last out time is also updated)
@ -170,14 +170,14 @@ public:
* *
* @param t Time of send * @param t Time of send
*/ */
ZT_ALWAYS_INLINE void sent(const int64_t t) { _lastOut = t; } inline void sent(const int64_t t) { _lastOut = t; }
/** /**
* Update path latency with a new measurement * Update path latency with a new measurement
* *
* @param l Measured latency * @param l Measured latency
*/ */
ZT_ALWAYS_INLINE void updateLatency(const unsigned int l, int64_t now) inline void updateLatency(const unsigned int l, int64_t now)
{ {
unsigned int pl = _latency; unsigned int pl = _latency;
if (pl < 0xffff) { if (pl < 0xffff) {
@ -192,22 +192,22 @@ public:
/** /**
* @return Local socket as specified by external code * @return Local socket as specified by external code
*/ */
ZT_ALWAYS_INLINE int64_t localSocket() const { return _localSocket; } inline int64_t localSocket() const { return _localSocket; }
/** /**
* @return Physical address * @return Physical address
*/ */
ZT_ALWAYS_INLINE const InetAddress &address() const { return _addr; } inline const InetAddress &address() const { return _addr; }
/** /**
* @return IP scope -- faster shortcut for address().ipScope() * @return IP scope -- faster shortcut for address().ipScope()
*/ */
ZT_ALWAYS_INLINE InetAddress::IpScope ipScope() const { return _ipScope; } inline InetAddress::IpScope ipScope() const { return _ipScope; }
/** /**
* @return Preference rank, higher == better * @return Preference rank, higher == better
*/ */
ZT_ALWAYS_INLINE unsigned int preferenceRank() const inline unsigned int preferenceRank() const
{ {
// This causes us to rank paths in order of IP scope rank (see InetAdddress.hpp) but // This causes us to rank paths in order of IP scope rank (see InetAdddress.hpp) but
// within each IP scope class to prefer IPv6 over IPv4. // within each IP scope class to prefer IPv6 over IPv4.
@ -223,7 +223,7 @@ public:
* @param a Address to check * @param a Address to check
* @return True if address is good for ZeroTier path use * @return True if address is good for ZeroTier path use
*/ */
static ZT_ALWAYS_INLINE bool isAddressValidForPath(const InetAddress &a) static inline bool isAddressValidForPath(const InetAddress &a)
{ {
if ((a.ss_family == AF_INET)||(a.ss_family == AF_INET6)) { if ((a.ss_family == AF_INET)||(a.ss_family == AF_INET6)) {
switch(a.ipScope()) { switch(a.ipScope()) {
@ -257,12 +257,12 @@ public:
/** /**
* @return Latency or 0xffff if unknown * @return Latency or 0xffff if unknown
*/ */
ZT_ALWAYS_INLINE unsigned int latency() const { return _latency; } inline unsigned int latency() const { return _latency; }
/** /**
* @return Path quality -- lower is better * @return Path quality -- lower is better
*/ */
ZT_ALWAYS_INLINE long quality(const int64_t now) const inline long quality(const int64_t now) const
{ {
const long l = (long)_latency; const long l = (long)_latency;
const long age = (long)std::min((long)(now - _lastIn),(long)(ZT_PEER_PING_PERIOD * 10)); // set an upper sanity limit to avoid overflow const long age = (long)std::min((long)(now - _lastIn),(long)(ZT_PEER_PING_PERIOD * 10)); // set an upper sanity limit to avoid overflow
@ -277,7 +277,7 @@ public:
* @param payloadLength Length of payload * @param payloadLength Length of payload
* @param verb Packet verb * @param verb Packet verb
*/ */
ZT_ALWAYS_INLINE void recordOutgoingPacket(int64_t now, int64_t packetId, uint16_t payloadLength, Packet::Verb verb) inline void recordOutgoingPacket(int64_t now, int64_t packetId, uint16_t payloadLength, Packet::Verb verb)
{ {
Mutex::Lock _l(_statistics_m); Mutex::Lock _l(_statistics_m);
if (verb != Packet::VERB_ACK && verb != Packet::VERB_QOS_MEASUREMENT) { if (verb != Packet::VERB_ACK && verb != Packet::VERB_QOS_MEASUREMENT) {
@ -300,7 +300,7 @@ public:
* @param payloadLength Length of payload * @param payloadLength Length of payload
* @param verb Packet verb * @param verb Packet verb
*/ */
ZT_ALWAYS_INLINE void recordIncomingPacket(int64_t now, int64_t packetId, uint16_t payloadLength, Packet::Verb verb) inline void recordIncomingPacket(int64_t now, int64_t packetId, uint16_t payloadLength, Packet::Verb verb)
{ {
Mutex::Lock _l(_statistics_m); Mutex::Lock _l(_statistics_m);
if (verb != Packet::VERB_ACK && verb != Packet::VERB_QOS_MEASUREMENT) { if (verb != Packet::VERB_ACK && verb != Packet::VERB_QOS_MEASUREMENT) {
@ -320,7 +320,7 @@ public:
* @param now Current time * @param now Current time
* @param ackedBytes Number of bytes acknowledged by other peer * @param ackedBytes Number of bytes acknowledged by other peer
*/ */
ZT_ALWAYS_INLINE void receivedAck(int64_t now, int32_t ackedBytes) inline void receivedAck(int64_t now, int32_t ackedBytes)
{ {
_expectingAckAsOf = 0; _expectingAckAsOf = 0;
_unackedBytes = (ackedBytes > _unackedBytes) ? 0 : _unackedBytes - ackedBytes; _unackedBytes = (ackedBytes > _unackedBytes) ? 0 : _unackedBytes - ackedBytes;
@ -598,17 +598,17 @@ public:
/** /**
* @return True if this path is alive (receiving data) * @return True if this path is alive (receiving data)
*/ */
ZT_ALWAYS_INLINE bool alive(const int64_t now) const { return ((now - _lastIn) < ((ZT_PEER_PING_PERIOD * 2) + 5000)); } inline bool alive(const int64_t now) const { return ((now - _lastIn) < ((ZT_PEER_PING_PERIOD * 2) + 5000)); }
/** /**
* @return Last time we sent something * @return Last time we sent something
*/ */
ZT_ALWAYS_INLINE int64_t lastOut() const { return _lastOut; } inline int64_t lastOut() const { return _lastOut; }
/** /**
* @return Last time we received anything * @return Last time we received anything
*/ */
ZT_ALWAYS_INLINE int64_t lastIn() const { return _lastIn; } inline int64_t lastIn() const { return _lastIn; }
private: private:
Mutex _statistics_m; Mutex _statistics_m;

View file

@ -60,12 +60,12 @@ public:
/** /**
* @return This peer's ZT address (short for identity().address()) * @return This peer's ZT address (short for identity().address())
*/ */
ZT_ALWAYS_INLINE const Address &address() const { return _id.address(); } inline const Address &address() const { return _id.address(); }
/** /**
* @return This peer's identity * @return This peer's identity
*/ */
ZT_ALWAYS_INLINE const Identity &identity() const { return _id; } inline const Identity &identity() const { return _id; }
/** /**
* Log receipt of an authenticated packet * Log receipt of an authenticated packet
@ -100,7 +100,7 @@ public:
* @param addr Remote address * @param addr Remote address
* @return True if we have an active path to this destination * @return True if we have an active path to this destination
*/ */
ZT_ALWAYS_INLINE bool hasActivePathTo(int64_t now,const InetAddress &addr) const inline bool hasActivePathTo(int64_t now,const InetAddress &addr) const
{ {
Mutex::Lock _l(_paths_m); Mutex::Lock _l(_paths_m);
for(unsigned int i=0;i<ZT_MAX_PEER_NETWORK_PATHS;++i) { for(unsigned int i=0;i<ZT_MAX_PEER_NETWORK_PATHS;++i) {
@ -122,7 +122,7 @@ public:
* @param force If true, send even if path is not alive * @param force If true, send even if path is not alive
* @return True if we actually sent something * @return True if we actually sent something
*/ */
ZT_ALWAYS_INLINE bool sendDirect(void *tPtr,const void *data,unsigned int len,int64_t now,bool force) inline bool sendDirect(void *tPtr,const void *data,unsigned int len,int64_t now,bool force)
{ {
SharedPtr<Path> bp(getAppropriatePath(now,force)); SharedPtr<Path> bp(getAppropriatePath(now,force));
if (bp) if (bp)
@ -262,7 +262,7 @@ public:
* @param now Current time * @param now Current time
* @return All known paths to this peer * @return All known paths to this peer
*/ */
ZT_ALWAYS_INLINE std::vector< SharedPtr<Path> > paths(const int64_t now) const inline std::vector< SharedPtr<Path> > paths(const int64_t now) const
{ {
std::vector< SharedPtr<Path> > pp; std::vector< SharedPtr<Path> > pp;
Mutex::Lock _l(_paths_m); Mutex::Lock _l(_paths_m);
@ -276,17 +276,17 @@ public:
/** /**
* @return Time of last receive of anything, whether direct or relayed * @return Time of last receive of anything, whether direct or relayed
*/ */
ZT_ALWAYS_INLINE int64_t lastReceive() const { return _lastReceive; } inline int64_t lastReceive() const { return _lastReceive; }
/** /**
* @return True if we've heard from this peer in less than ZT_PEER_ACTIVITY_TIMEOUT * @return True if we've heard from this peer in less than ZT_PEER_ACTIVITY_TIMEOUT
*/ */
ZT_ALWAYS_INLINE bool alive(const int64_t now) const { return ((now - _lastReceive) < ZT_PEER_ACTIVITY_TIMEOUT); } inline bool alive(const int64_t now) const { return ((now - _lastReceive) < ZT_PEER_ACTIVITY_TIMEOUT); }
/** /**
* @return Latency in milliseconds of best/aggregate path or 0xffff if unknown / no paths * @return Latency in milliseconds of best/aggregate path or 0xffff if unknown / no paths
*/ */
ZT_ALWAYS_INLINE unsigned int latency(const int64_t now) inline unsigned int latency(const int64_t now)
{ {
if (_canUseMultipath) { if (_canUseMultipath) {
return (int)computeAggregateLinkMeanLatency(); return (int)computeAggregateLinkMeanLatency();
@ -309,7 +309,7 @@ public:
* *
* @return Relay quality score computed from latency and other factors, lower is better * @return Relay quality score computed from latency and other factors, lower is better
*/ */
ZT_ALWAYS_INLINE unsigned int relayQuality(const int64_t now) inline unsigned int relayQuality(const int64_t now)
{ {
const uint64_t tsr = now - _lastReceive; const uint64_t tsr = now - _lastReceive;
if (tsr >= ZT_PEER_ACTIVITY_TIMEOUT) if (tsr >= ZT_PEER_ACTIVITY_TIMEOUT)
@ -323,7 +323,7 @@ public:
/** /**
* @return 256-bit secret symmetric encryption key * @return 256-bit secret symmetric encryption key
*/ */
ZT_ALWAYS_INLINE const unsigned char *key() const { return _key; } inline const unsigned char *key() const { return _key; }
/** /**
* Set the currently known remote version of this peer's client * Set the currently known remote version of this peer's client
@ -333,7 +333,7 @@ public:
* @param vmin Minor version * @param vmin Minor version
* @param vrev Revision * @param vrev Revision
*/ */
ZT_ALWAYS_INLINE void setRemoteVersion(unsigned int vproto,unsigned int vmaj,unsigned int vmin,unsigned int vrev) inline void setRemoteVersion(unsigned int vproto,unsigned int vmaj,unsigned int vmin,unsigned int vrev)
{ {
_vProto = (uint16_t)vproto; _vProto = (uint16_t)vproto;
_vMajor = (uint16_t)vmaj; _vMajor = (uint16_t)vmaj;
@ -341,11 +341,11 @@ public:
_vRevision = (uint16_t)vrev; _vRevision = (uint16_t)vrev;
} }
ZT_ALWAYS_INLINE unsigned int remoteVersionProtocol() const { return _vProto; } inline unsigned int remoteVersionProtocol() const { return _vProto; }
ZT_ALWAYS_INLINE unsigned int remoteVersionMajor() const { return _vMajor; } inline unsigned int remoteVersionMajor() const { return _vMajor; }
ZT_ALWAYS_INLINE unsigned int remoteVersionMinor() const { return _vMinor; } inline unsigned int remoteVersionMinor() const { return _vMinor; }
ZT_ALWAYS_INLINE unsigned int remoteVersionRevision() const { return _vRevision; } inline unsigned int remoteVersionRevision() const { return _vRevision; }
ZT_ALWAYS_INLINE bool remoteVersionKnown() const { return ((_vMajor > 0)||(_vMinor > 0)||(_vRevision > 0)); } inline bool remoteVersionKnown() const { return ((_vMajor > 0)||(_vMinor > 0)||(_vRevision > 0)); }
/** /**
* Periodically update known multipath activation constraints. This is done so that we know when and when * Periodically update known multipath activation constraints. This is done so that we know when and when
@ -360,28 +360,28 @@ public:
* or a VERB_QOS_MEASUREMENT packet at some point in the past. Until this flag is set, the local client * or a VERB_QOS_MEASUREMENT packet at some point in the past. Until this flag is set, the local client
* shall assume that multipath is not enabled and should only use classical Protocol 9 logic. * shall assume that multipath is not enabled and should only use classical Protocol 9 logic.
*/ */
ZT_ALWAYS_INLINE void inferRemoteMultipathEnabled() { _remotePeerMultipathEnabled = true; } inline void inferRemoteMultipathEnabled() { _remotePeerMultipathEnabled = true; }
/** /**
* @return Whether the local client supports and is configured to use multipath * @return Whether the local client supports and is configured to use multipath
*/ */
ZT_ALWAYS_INLINE bool localMultipathSupport() { return _localMultipathSupported; } inline bool localMultipathSupport() { return _localMultipathSupported; }
/** /**
* @return Whether the remote peer supports and is configured to use multipath * @return Whether the remote peer supports and is configured to use multipath
*/ */
ZT_ALWAYS_INLINE bool remoteMultipathSupport() { return _remoteMultipathSupported; } inline bool remoteMultipathSupport() { return _remoteMultipathSupported; }
/** /**
* @return Whether this client can use multipath to communicate with this peer. True if both peers are using * @return Whether this client can use multipath to communicate with this peer. True if both peers are using
* the correct protocol and if both peers have multipath enabled. False if otherwise. * the correct protocol and if both peers have multipath enabled. False if otherwise.
*/ */
ZT_ALWAYS_INLINE bool canUseMultipath() { return _canUseMultipath; } inline bool canUseMultipath() { return _canUseMultipath; }
/** /**
* Rate limit gate for VERB_PUSH_DIRECT_PATHS * Rate limit gate for VERB_PUSH_DIRECT_PATHS
*/ */
ZT_ALWAYS_INLINE bool rateGatePushDirectPaths(const int64_t now) inline bool rateGatePushDirectPaths(const int64_t now)
{ {
if ((now - _lastDirectPathPushReceive) <= ZT_PUSH_DIRECT_PATHS_CUTOFF_TIME) if ((now - _lastDirectPathPushReceive) <= ZT_PUSH_DIRECT_PATHS_CUTOFF_TIME)
++_directPathPushCutoffCount; ++_directPathPushCutoffCount;
@ -393,7 +393,7 @@ public:
/** /**
* Rate limit gate for VERB_NETWORK_CREDENTIALS * Rate limit gate for VERB_NETWORK_CREDENTIALS
*/ */
ZT_ALWAYS_INLINE bool rateGateCredentialsReceived(const int64_t now) inline bool rateGateCredentialsReceived(const int64_t now)
{ {
if ((now - _lastCredentialsReceived) <= ZT_PEER_CREDENTIALS_CUTOFF_TIME) if ((now - _lastCredentialsReceived) <= ZT_PEER_CREDENTIALS_CUTOFF_TIME)
++_credentialsCutoffCount; ++_credentialsCutoffCount;
@ -405,7 +405,7 @@ public:
/** /**
* Rate limit gate for sending of ERROR_NEED_MEMBERSHIP_CERTIFICATE * Rate limit gate for sending of ERROR_NEED_MEMBERSHIP_CERTIFICATE
*/ */
ZT_ALWAYS_INLINE bool rateGateRequestCredentials(const int64_t now) inline bool rateGateRequestCredentials(const int64_t now)
{ {
if ((now - _lastCredentialRequestSent) >= ZT_PEER_GENERAL_RATE_LIMIT) { if ((now - _lastCredentialRequestSent) >= ZT_PEER_GENERAL_RATE_LIMIT) {
_lastCredentialRequestSent = now; _lastCredentialRequestSent = now;
@ -417,7 +417,7 @@ public:
/** /**
* Rate limit gate for inbound WHOIS requests * Rate limit gate for inbound WHOIS requests
*/ */
ZT_ALWAYS_INLINE bool rateGateInboundWhoisRequest(const int64_t now) inline bool rateGateInboundWhoisRequest(const int64_t now)
{ {
if ((now - _lastWhoisRequestReceived) >= ZT_PEER_WHOIS_RATE_LIMIT) { if ((now - _lastWhoisRequestReceived) >= ZT_PEER_WHOIS_RATE_LIMIT) {
_lastWhoisRequestReceived = now; _lastWhoisRequestReceived = now;
@ -429,7 +429,7 @@ public:
/** /**
* Rate limit gate for inbound ECHO requests * Rate limit gate for inbound ECHO requests
*/ */
ZT_ALWAYS_INLINE bool rateGateEchoRequest(const int64_t now) inline bool rateGateEchoRequest(const int64_t now)
{ {
if ((now - _lastEchoRequestReceived) >= ZT_PEER_GENERAL_RATE_LIMIT) { if ((now - _lastEchoRequestReceived) >= ZT_PEER_GENERAL_RATE_LIMIT) {
_lastEchoRequestReceived = now; _lastEchoRequestReceived = now;
@ -441,7 +441,7 @@ public:
/** /**
* Rate limit gate for VERB_ACK * Rate limit gate for VERB_ACK
*/ */
ZT_ALWAYS_INLINE bool rateGateACK(const int64_t now) inline bool rateGateACK(const int64_t now)
{ {
if ((now - _lastACKWindowReset) >= ZT_PATH_QOS_ACK_CUTOFF_TIME) { if ((now - _lastACKWindowReset) >= ZT_PATH_QOS_ACK_CUTOFF_TIME) {
_lastACKWindowReset = now; _lastACKWindowReset = now;
@ -455,7 +455,7 @@ public:
/** /**
* Rate limit gate for VERB_QOS_MEASUREMENT * Rate limit gate for VERB_QOS_MEASUREMENT
*/ */
ZT_ALWAYS_INLINE bool rateGateQoS(const int64_t now) inline bool rateGateQoS(const int64_t now)
{ {
if ((now - _lastQoSWindowReset) >= ZT_PATH_QOS_ACK_CUTOFF_TIME) { if ((now - _lastQoSWindowReset) >= ZT_PATH_QOS_ACK_CUTOFF_TIME) {
_lastQoSWindowReset = now; _lastQoSWindowReset = now;
@ -469,7 +469,7 @@ public:
/** /**
* Rate limit gate for trying externally defined or static path * Rate limit gate for trying externally defined or static path
*/ */
ZT_ALWAYS_INLINE bool rateGateTryStaticPath(const int64_t now) inline bool rateGateTryStaticPath(const int64_t now)
{ {
if ((now - _lastTriedStaticPath) >= ZT_PEER_PING_PERIOD) { if ((now - _lastTriedStaticPath) >= ZT_PEER_PING_PERIOD) {
_lastTriedStaticPath = now; _lastTriedStaticPath = now;
@ -481,7 +481,7 @@ public:
/** /**
* @return Whether this peer is reachable via an aggregate link * @return Whether this peer is reachable via an aggregate link
*/ */
ZT_ALWAYS_INLINE bool hasAggregateLink() const inline bool hasAggregateLink() const
{ {
return _localMultipathSupported && _remoteMultipathSupported && _remotePeerMultipathEnabled; return _localMultipathSupported && _remoteMultipathSupported && _remotePeerMultipathEnabled;
} }
@ -544,7 +544,7 @@ private:
// Add a swap() for shared ptr's to peers to speed up peer sorts // Add a swap() for shared ptr's to peers to speed up peer sorts
namespace std { namespace std {
template<> template<>
ZT_ALWAYS_INLINE void swap(ZeroTier::SharedPtr<ZeroTier::Peer> &a,ZeroTier::SharedPtr<ZeroTier::Peer> &b) { a.swap(b); } inline void swap(ZeroTier::SharedPtr<ZeroTier::Peer> &a,ZeroTier::SharedPtr<ZeroTier::Peer> &b) { a.swap(b); }
} }
#endif #endif

View file

@ -74,7 +74,7 @@ typedef struct poly1305_state_internal_t {
} poly1305_state_internal_t; } poly1305_state_internal_t;
#if defined(ZT_NO_TYPE_PUNNING) || (__BYTE_ORDER != __LITTLE_ENDIAN) #if defined(ZT_NO_TYPE_PUNNING) || (__BYTE_ORDER != __LITTLE_ENDIAN)
static ZT_ALWAYS_INLINE unsigned long long U8TO64(const unsigned char *p) static inline unsigned long long U8TO64(const unsigned char *p)
{ {
return return
(((unsigned long long)(p[0] & 0xff) ) | (((unsigned long long)(p[0] & 0xff) ) |
@ -91,7 +91,7 @@ static ZT_ALWAYS_INLINE unsigned long long U8TO64(const unsigned char *p)
#endif #endif
#if defined(ZT_NO_TYPE_PUNNING) || (__BYTE_ORDER != __LITTLE_ENDIAN) #if defined(ZT_NO_TYPE_PUNNING) || (__BYTE_ORDER != __LITTLE_ENDIAN)
static ZT_ALWAYS_INLINE void U64TO8(unsigned char *p, unsigned long long v) static inline void U64TO8(unsigned char *p, unsigned long long v)
{ {
p[0] = (v ) & 0xff; p[0] = (v ) & 0xff;
p[1] = (v >> 8) & 0xff; p[1] = (v >> 8) & 0xff;
@ -106,7 +106,7 @@ static ZT_ALWAYS_INLINE void U64TO8(unsigned char *p, unsigned long long v)
#define U64TO8(p,v) ((*reinterpret_cast<unsigned long long *>(p)) = (v)) #define U64TO8(p,v) ((*reinterpret_cast<unsigned long long *>(p)) = (v))
#endif #endif
static ZT_ALWAYS_INLINE void poly1305_init(poly1305_context *ctx, const unsigned char key[32]) static 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; unsigned long long t0,t1;
@ -132,7 +132,7 @@ static ZT_ALWAYS_INLINE void poly1305_init(poly1305_context *ctx, const unsigned
st->final = 0; st->final = 0;
} }
static ZT_ALWAYS_INLINE void poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes) static inline 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 */ const unsigned long long hibit = (st->final) ? 0 : ((unsigned long long)1 << 40); /* 1 << 128 */
unsigned long long r0,r1,r2; unsigned long long r0,r1,r2;
@ -183,7 +183,7 @@ static ZT_ALWAYS_INLINE void poly1305_blocks(poly1305_state_internal_t *st, cons
st->h[2] = h2; st->h[2] = h2;
} }
static ZT_ALWAYS_INLINE void poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) static 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 h0,h1,h2,c;
@ -274,7 +274,7 @@ typedef struct poly1305_state_internal_t {
} poly1305_state_internal_t; } poly1305_state_internal_t;
/* interpret four 8 bit unsigned integers as a 32 bit unsigned integer in little endian */ /* interpret four 8 bit unsigned integers as a 32 bit unsigned integer in little endian */
static ZT_ALWAYS_INLINE unsigned long static inline unsigned long
U8TO32(const unsigned char *p) { U8TO32(const unsigned char *p) {
return return
(((unsigned long)(p[0] & 0xff) ) | (((unsigned long)(p[0] & 0xff) ) |
@ -284,7 +284,7 @@ U8TO32(const unsigned char *p) {
} }
/* store a 32 bit unsigned integer as four 8 bit unsigned integers in little endian */ /* store a 32 bit unsigned integer as four 8 bit unsigned integers in little endian */
static ZT_ALWAYS_INLINE void static inline void
U32TO8(unsigned char *p, unsigned long v) { U32TO8(unsigned char *p, unsigned long v) {
p[0] = (v ) & 0xff; p[0] = (v ) & 0xff;
p[1] = (v >> 8) & 0xff; p[1] = (v >> 8) & 0xff;
@ -292,7 +292,7 @@ U32TO8(unsigned char *p, unsigned long v) {
p[3] = (v >> 24) & 0xff; p[3] = (v >> 24) & 0xff;
} }
static ZT_ALWAYS_INLINE void static inline void
poly1305_init(poly1305_context *ctx, const unsigned char key[32]) { 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;
@ -320,7 +320,7 @@ poly1305_init(poly1305_context *ctx, const unsigned char key[32]) {
st->final = 0; st->final = 0;
} }
static ZT_ALWAYS_INLINE void static inline void
poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes) { 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 */ const unsigned long hibit = (st->final) ? 0 : (1 << 24); /* 1 << 128 */
unsigned long r0,r1,r2,r3,r4; unsigned long r0,r1,r2,r3,r4;
@ -379,7 +379,7 @@ poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t by
st->h[4] = h4; st->h[4] = h4;
} }
static ZT_ALWAYS_INLINE void static inline void
poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) { 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 h0,h1,h2,h3,h4,c;
@ -470,7 +470,7 @@ poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) {
#endif // MSC/GCC or not #endif // MSC/GCC or not
static ZT_ALWAYS_INLINE void poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes) { static inline void poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes) {
poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
size_t i; size_t i;

View file

@ -82,16 +82,16 @@ public:
{ {
} }
ZT_ALWAYS_INLINE uint32_t id() const { return _id; } inline uint32_t id() const { return _id; }
ZT_ALWAYS_INLINE uint32_t credentialId() const { return _credentialId; } inline uint32_t credentialId() const { return _credentialId; }
ZT_ALWAYS_INLINE uint64_t networkId() const { return _networkId; } inline uint64_t networkId() const { return _networkId; }
ZT_ALWAYS_INLINE int64_t threshold() const { return _threshold; } inline int64_t threshold() const { return _threshold; }
ZT_ALWAYS_INLINE const Address &target() const { return _target; } inline const Address &target() const { return _target; }
ZT_ALWAYS_INLINE const Address &signer() const { return _signedBy; } inline const Address &signer() const { return _signedBy; }
ZT_ALWAYS_INLINE Credential::Type type() const { return _type; } inline Credential::Type type() const { return _type; }
ZT_ALWAYS_INLINE const uint8_t *signature() const { return _signature; } inline const uint8_t *signature() const { return _signature; }
ZT_ALWAYS_INLINE unsigned int signatureLength() const { return _signatureLength; } inline unsigned int signatureLength() const { return _signatureLength; }
ZT_ALWAYS_INLINE bool fastPropagate() const { return ((_flags & ZT_REVOCATION_FLAG_FAST_PROPAGATE) != 0); } inline bool fastPropagate() const { return ((_flags & ZT_REVOCATION_FLAG_FAST_PROPAGATE) != 0); }
/** /**
* @param signer Signing identity, must have private key * @param signer Signing identity, must have private key

View file

@ -43,7 +43,7 @@ private:
bool wrap; bool wrap;
public: public:
ZT_ALWAYS_INLINE RingBuffer() : inline RingBuffer() :
begin(0), begin(0),
end(0), end(0),
wrap(false) wrap(false)
@ -54,7 +54,7 @@ public:
/** /**
* @return A pointer to the underlying buffer * @return A pointer to the underlying buffer
*/ */
ZT_ALWAYS_INLINE T *get_buf() inline T *get_buf()
{ {
return buf + begin; return buf + begin;
} }
@ -64,7 +64,7 @@ public:
* @param n Number of elements to copy in * @param n Number of elements to copy in
* @return Number of elements we copied in * @return Number of elements we copied in
*/ */
ZT_ALWAYS_INLINE size_t produce(size_t n) inline size_t produce(size_t n)
{ {
n = std::min(n, getFree()); n = std::min(n, getFree());
if (n == 0) { if (n == 0) {
@ -86,14 +86,14 @@ public:
* Fast erase, O(1). * Fast erase, O(1).
* Merely reset the buffer pointer, doesn't erase contents * Merely reset the buffer pointer, doesn't erase contents
*/ */
ZT_ALWAYS_INLINE void reset() { consume(count()); } inline void reset() { consume(count()); }
/** /**
* adjust buffer index pointer as if we copied data out * adjust buffer index pointer as if we copied data out
* @param n Number of elements we copied from the buffer * @param n Number of elements we copied from the buffer
* @return Number of elements actually available from the buffer * @return Number of elements actually available from the buffer
*/ */
ZT_ALWAYS_INLINE size_t consume(size_t n) inline size_t consume(size_t n)
{ {
n = std::min(n, count()); n = std::min(n, count());
if (n == 0) { if (n == 0) {
@ -115,7 +115,7 @@ public:
* @param data Buffer that is to be written to the ring * @param data Buffer that is to be written to the ring
* @param n Number of elements to write to the buffer * @param n Number of elements to write to the buffer
*/ */
ZT_ALWAYS_INLINE size_t write(const T * data, size_t n) inline size_t write(const T * data, size_t n)
{ {
n = std::min(n, getFree()); n = std::min(n, getFree());
if (n == 0) { if (n == 0) {
@ -140,7 +140,7 @@ public:
* *
* @param value A single value to be placed in the buffer * @param value A single value to be placed in the buffer
*/ */
ZT_ALWAYS_INLINE void push(const T value) inline void push(const T value)
{ {
if (count() == S) { if (count() == S) {
consume(1); consume(1);
@ -156,14 +156,14 @@ public:
/** /**
* @return The most recently pushed element on the buffer * @return The most recently pushed element on the buffer
*/ */
ZT_ALWAYS_INLINE T get_most_recent() { return *(buf + end); } inline T get_most_recent() { return *(buf + end); }
/** /**
* @param dest Destination buffer * @param dest Destination buffer
* @param n Size (in terms of number of elements) of the destination buffer * @param n Size (in terms of number of elements) of the destination buffer
* @return Number of elements read from the buffer * @return Number of elements read from the buffer
*/ */
ZT_ALWAYS_INLINE size_t read(T *dest,size_t n) inline size_t read(T *dest,size_t n)
{ {
n = std::min(n, count()); n = std::min(n, count());
if (n == 0) { if (n == 0) {
@ -188,7 +188,7 @@ public:
* *
* @return The number of elements in the buffer * @return The number of elements in the buffer
*/ */
ZT_ALWAYS_INLINE size_t count() inline size_t count()
{ {
if (end == begin) { if (end == begin) {
return wrap ? S : 0; return wrap ? S : 0;
@ -204,12 +204,12 @@ public:
/** /**
* @return The number of slots that are unused in the buffer * @return The number of slots that are unused in the buffer
*/ */
ZT_ALWAYS_INLINE size_t getFree() { return S - count(); } inline size_t getFree() { return S - count(); }
/** /**
* @return The arithmetic mean of the contents of the buffer * @return The arithmetic mean of the contents of the buffer
*/ */
ZT_ALWAYS_INLINE float mean() inline float mean()
{ {
size_t iterator = begin; size_t iterator = begin;
float subtotal = 0; float subtotal = 0;
@ -224,7 +224,7 @@ public:
/** /**
* @return The arithmetic mean of the most recent 'n' elements of the buffer * @return The arithmetic mean of the most recent 'n' elements of the buffer
*/ */
ZT_ALWAYS_INLINE float mean(size_t n) inline float mean(size_t n)
{ {
n = n < S ? n : S; n = n < S ? n : S;
size_t iterator = begin; size_t iterator = begin;
@ -240,12 +240,12 @@ public:
/** /**
* @return The sample standard deviation of element values * @return The sample standard deviation of element values
*/ */
ZT_ALWAYS_INLINE float stddev() { return sqrt(variance()); } inline float stddev() { return sqrt(variance()); }
/** /**
* @return The variance of element values * @return The variance of element values
*/ */
ZT_ALWAYS_INLINE float variance() inline float variance()
{ {
size_t iterator = begin; size_t iterator = begin;
float cached_mean = mean(); float cached_mean = mean();
@ -263,7 +263,7 @@ public:
/** /**
* @return The number of elements of zero value * @return The number of elements of zero value
*/ */
ZT_ALWAYS_INLINE size_t zeroCount() inline size_t zeroCount()
{ {
size_t iterator = begin; size_t iterator = begin;
size_t zeros = 0; size_t zeros = 0;
@ -281,7 +281,7 @@ public:
* @param value Value to match against in buffer * @param value Value to match against in buffer
* @return The number of values held in the ring buffer which match a given value * @return The number of values held in the ring buffer which match a given value
*/ */
ZT_ALWAYS_INLINE size_t countValue(T value) inline size_t countValue(T value)
{ {
size_t iterator = begin; size_t iterator = begin;
size_t cnt = 0; size_t cnt = 0;

View file

@ -36,7 +36,7 @@ class Trace;
class RuntimeEnvironment class RuntimeEnvironment
{ {
public: public:
ZT_ALWAYS_INLINE RuntimeEnvironment(Node *n) : inline RuntimeEnvironment(Node *n) :
node(n) node(n)
,localNetworkController((NetworkController *)0) ,localNetworkController((NetworkController *)0)
,rtmem((void *)0) ,rtmem((void *)0)
@ -48,7 +48,7 @@ public:
secretIdentityStr[0] = (char)0; secretIdentityStr[0] = (char)0;
} }
ZT_ALWAYS_INLINE ~RuntimeEnvironment() { Utils::burn(secretIdentityStr,sizeof(secretIdentityStr)); } inline ~RuntimeEnvironment() { Utils::burn(secretIdentityStr,sizeof(secretIdentityStr)); }
// Node instance that owns this RuntimeEnvironment // Node instance that owns this RuntimeEnvironment
Node *const node; Node *const node;

View file

@ -69,7 +69,7 @@ static const uint64_t K[80] = {
#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) #define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) #define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
static ZT_ALWAYS_INLINE void sha512_compress(sha512_state *const md,uint8_t *const buf) static inline void sha512_compress(sha512_state *const md,uint8_t *const buf)
{ {
uint64_t S[8], W[80], t0, t1; uint64_t S[8], W[80], t0, t1;
int i; int i;
@ -102,7 +102,7 @@ static ZT_ALWAYS_INLINE void sha512_compress(sha512_state *const md,uint8_t *con
md->state[i] = md->state[i] + S[i]; md->state[i] = md->state[i] + S[i];
} }
static ZT_ALWAYS_INLINE void sha384_init(sha512_state *const md) static inline void sha384_init(sha512_state *const md)
{ {
md->curlen = 0; md->curlen = 0;
md->length = 0; md->length = 0;
@ -116,7 +116,7 @@ static ZT_ALWAYS_INLINE void sha384_init(sha512_state *const md)
md->state[7] = 0x47b5481dbefa4fa4ULL; md->state[7] = 0x47b5481dbefa4fa4ULL;
} }
static ZT_ALWAYS_INLINE void sha512_init(sha512_state *const md) static inline void sha512_init(sha512_state *const md)
{ {
md->curlen = 0; md->curlen = 0;
md->length = 0; md->length = 0;
@ -130,7 +130,7 @@ static ZT_ALWAYS_INLINE void sha512_init(sha512_state *const md)
md->state[7] = 0x5be0cd19137e2179ULL; md->state[7] = 0x5be0cd19137e2179ULL;
} }
static ZT_ALWAYS_INLINE void sha512_process(sha512_state *const md,const uint8_t *in,unsigned long inlen) static inline void sha512_process(sha512_state *const md,const uint8_t *in,unsigned long inlen)
{ {
while (inlen > 0) { while (inlen > 0) {
if (md->curlen == 0 && inlen >= 128) { if (md->curlen == 0 && inlen >= 128) {
@ -153,7 +153,7 @@ static ZT_ALWAYS_INLINE void sha512_process(sha512_state *const md,const uint8_t
} }
} }
static ZT_ALWAYS_INLINE void sha512_done(sha512_state *const md,uint8_t *out) static inline void sha512_done(sha512_state *const md,uint8_t *out)
{ {
int i; int i;

View file

@ -42,21 +42,21 @@ namespace ZeroTier {
#ifdef __APPLE__ #ifdef __APPLE__
#define ZT_HAVE_NATIVE_SHA512 1 #define ZT_HAVE_NATIVE_SHA512 1
static ZT_ALWAYS_INLINE void SHA512(void *digest,const void *data,unsigned int len) static inline void SHA512(void *digest,const void *data,unsigned int len)
{ {
CC_SHA512_CTX ctx; CC_SHA512_CTX ctx;
CC_SHA512_Init(&ctx); CC_SHA512_Init(&ctx);
CC_SHA512_Update(&ctx,data,len); 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_ALWAYS_INLINE void SHA384(void *digest,const void *data,unsigned int len) static inline void SHA384(void *digest,const void *data,unsigned int len)
{ {
CC_SHA512_CTX ctx; CC_SHA512_CTX ctx;
CC_SHA384_Init(&ctx); CC_SHA384_Init(&ctx);
CC_SHA384_Update(&ctx,data,len); 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_ALWAYS_INLINE void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,unsigned int len1) static inline void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,unsigned int len1)
{ {
CC_SHA512_CTX ctx; CC_SHA512_CTX ctx;
CC_SHA384_Init(&ctx); CC_SHA384_Init(&ctx);
@ -69,21 +69,21 @@ static ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data0,unsigned int
#ifndef ZT_HAVE_NATIVE_SHA512 #ifndef ZT_HAVE_NATIVE_SHA512
#ifdef ZT_USE_LIBCRYPTO #ifdef ZT_USE_LIBCRYPTO
#define ZT_HAVE_NATIVE_SHA512 1 #define ZT_HAVE_NATIVE_SHA512 1
static ZT_ALWAYS_INLINE void SHA512(void *digest,const void *data,unsigned int len) static inline void SHA512(void *digest,const void *data,unsigned int len)
{ {
SHA512_CTX ctx; SHA512_CTX ctx;
SHA512_Init(&ctx); SHA512_Init(&ctx);
SHA512_Update(&ctx,data,len); SHA512_Update(&ctx,data,len);
SHA512_Final(reinterpret_cast<unsigned char *>(digest),&ctx); SHA512_Final(reinterpret_cast<unsigned char *>(digest),&ctx);
} }
static ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data,unsigned int len) static inline void SHA384(void *digest,const void *data,unsigned int len)
{ {
SHA512_CTX ctx; SHA512_CTX ctx;
SHA384_Init(&ctx); SHA384_Init(&ctx);
SHA384_Update(&ctx,data,len); SHA384_Update(&ctx,data,len);
SHA384_Final(reinterpret_cast<unsigned char *>(digest),&ctx); SHA384_Final(reinterpret_cast<unsigned char *>(digest),&ctx);
} }
static ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,unsigned int len1) static inline void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,unsigned int len1)
{ {
SHA512_CTX ctx; SHA512_CTX ctx;
SHA384_Init(&ctx); SHA384_Init(&ctx);

View file

@ -30,14 +30,14 @@ namespace ZeroTier {
class Salsa20 class Salsa20
{ {
public: public:
ZT_ALWAYS_INLINE Salsa20() {} inline Salsa20() {}
ZT_ALWAYS_INLINE ~Salsa20() { Utils::burn(&_state,sizeof(_state)); } inline ~Salsa20() { Utils::burn(&_state,sizeof(_state)); }
/** /**
* @param key 256-bit (32 byte) key * @param key 256-bit (32 byte) key
* @param iv 64-bit initialization vector * @param iv 64-bit initialization vector
*/ */
ZT_ALWAYS_INLINE Salsa20(const void *key,const void *iv) { init(key,iv); } inline Salsa20(const void *key,const void *iv) { init(key,iv); }
/** /**
* Initialize cipher * Initialize cipher

View file

@ -27,21 +27,21 @@ template<typename T>
class ScopedPtr class ScopedPtr
{ {
public: public:
ZT_ALWAYS_INLINE ScopedPtr(T *const p) : _p(p) {} inline ScopedPtr(T *const p) : _p(p) {}
ZT_ALWAYS_INLINE ~ScopedPtr() { delete _p; } inline ~ScopedPtr() { delete _p; }
ZT_ALWAYS_INLINE T *operator->() const { return _p; } inline T *operator->() const { return _p; }
ZT_ALWAYS_INLINE T &operator*() const { return *_p; } inline T &operator*() const { return *_p; }
ZT_ALWAYS_INLINE operator bool() const { return (_p != (T *)0); } inline operator bool() const { return (_p != (T *)0); }
ZT_ALWAYS_INLINE T *ptr() const { return _p; } inline T *ptr() const { return _p; }
ZT_ALWAYS_INLINE bool operator==(const ScopedPtr &p) const { return (_p == p._p); } inline bool operator==(const ScopedPtr &p) const { return (_p == p._p); }
ZT_ALWAYS_INLINE bool operator!=(const ScopedPtr &p) const { return (_p != p._p); } inline bool operator!=(const ScopedPtr &p) const { return (_p != p._p); }
ZT_ALWAYS_INLINE bool operator==(T *const p) const { return (_p == p); } inline bool operator==(T *const p) const { return (_p == p); }
ZT_ALWAYS_INLINE bool operator!=(T *const p) const { return (_p != p); } inline bool operator!=(T *const p) const { return (_p != p); }
private: private:
ZT_ALWAYS_INLINE ScopedPtr() {} inline ScopedPtr() {}
T *const _p; T *const _p;
}; };

View file

@ -36,13 +36,13 @@ namespace ZeroTier {
class _ResetWithinScope class _ResetWithinScope
{ {
public: public:
ZT_ALWAYS_INLINE _ResetWithinScope(void *tPtr,int64_t now,int inetAddressFamily,InetAddress::IpScope scope) : inline _ResetWithinScope(void *tPtr,int64_t now,int inetAddressFamily,InetAddress::IpScope scope) :
_now(now), _now(now),
_tPtr(tPtr), _tPtr(tPtr),
_family(inetAddressFamily), _family(inetAddressFamily),
_scope(scope) {} _scope(scope) {}
ZT_ALWAYS_INLINE bool operator()(const SharedPtr<Peer> &p) inline bool operator()(const SharedPtr<Peer> &p)
{ {
p->resetWithinScope(_tPtr,_scope,_family,_now); p->resetWithinScope(_tPtr,_scope,_family,_now);
return true; return true;

View file

@ -59,13 +59,13 @@ private:
InetAddress reporterPhysicalAddress; InetAddress reporterPhysicalAddress;
InetAddress::IpScope scope; InetAddress::IpScope scope;
ZT_ALWAYS_INLINE PhySurfaceKey() : reporter(),scope(InetAddress::IP_SCOPE_NONE) {} inline PhySurfaceKey() : reporter(),scope(InetAddress::IP_SCOPE_NONE) {}
ZT_ALWAYS_INLINE PhySurfaceKey(const Address &r,const int64_t rol,const InetAddress &ra,InetAddress::IpScope s) : reporter(r),receivedOnLocalSocket(rol),reporterPhysicalAddress(ra),scope(s) {} inline PhySurfaceKey(const Address &r,const int64_t rol,const InetAddress &ra,InetAddress::IpScope s) : reporter(r),receivedOnLocalSocket(rol),reporterPhysicalAddress(ra),scope(s) {}
ZT_ALWAYS_INLINE unsigned long hashCode() const { return ((unsigned long)reporter.toInt() + (unsigned long)scope); } inline unsigned long hashCode() const { return ((unsigned long)reporter.toInt() + (unsigned long)scope); }
ZT_ALWAYS_INLINE bool operator==(const PhySurfaceKey &k) const { return ((reporter == k.reporter)&&(receivedOnLocalSocket == k.receivedOnLocalSocket)&&(reporterPhysicalAddress == k.reporterPhysicalAddress)&&(scope == k.scope)); } inline bool operator==(const PhySurfaceKey &k) const { return ((reporter == k.reporter)&&(receivedOnLocalSocket == k.receivedOnLocalSocket)&&(reporterPhysicalAddress == k.reporterPhysicalAddress)&&(scope == k.scope)); }
ZT_ALWAYS_INLINE bool operator!=(const PhySurfaceKey &k) const { return (!(*this == k)); } inline bool operator!=(const PhySurfaceKey &k) const { return (!(*this == k)); }
}; };
struct PhySurfaceEntry struct PhySurfaceEntry
{ {
@ -73,8 +73,8 @@ private:
uint64_t ts; uint64_t ts;
bool trusted; bool trusted;
ZT_ALWAYS_INLINE PhySurfaceEntry() : mySurface(),ts(0),trusted(false) {} inline PhySurfaceEntry() : mySurface(),ts(0),trusted(false) {}
ZT_ALWAYS_INLINE PhySurfaceEntry(const InetAddress &a,const uint64_t t) : mySurface(a),ts(t),trusted(false) {} inline PhySurfaceEntry(const InetAddress &a,const uint64_t t) : mySurface(a),ts(t),trusted(false) {}
}; };
const RuntimeEnvironment *RR; const RuntimeEnvironment *RR;

View file

@ -30,11 +30,11 @@ template<typename T>
class SharedPtr class SharedPtr
{ {
public: public:
ZT_ALWAYS_INLINE SharedPtr() : _ptr((T *)0) {} inline SharedPtr() : _ptr((T *)0) {}
ZT_ALWAYS_INLINE SharedPtr(T *obj) : _ptr(obj) { ++obj->__refCount; } inline SharedPtr(T *obj) : _ptr(obj) { ++obj->__refCount; }
ZT_ALWAYS_INLINE SharedPtr(const SharedPtr &sp) : _ptr(sp._getAndInc()) {} inline SharedPtr(const SharedPtr &sp) : _ptr(sp._getAndInc()) {}
ZT_ALWAYS_INLINE ~SharedPtr() inline ~SharedPtr()
{ {
if (_ptr) { if (_ptr) {
if (--_ptr->__refCount <= 0) if (--_ptr->__refCount <= 0)
@ -42,7 +42,7 @@ public:
} }
} }
ZT_ALWAYS_INLINE SharedPtr &operator=(const SharedPtr &sp) inline SharedPtr &operator=(const SharedPtr &sp)
{ {
if (_ptr != sp._ptr) { if (_ptr != sp._ptr) {
T *p = sp._getAndInc(); T *p = sp._getAndInc();
@ -63,7 +63,7 @@ public:
* *
* @param ptr Naked pointer to assign * @param ptr Naked pointer to assign
*/ */
ZT_ALWAYS_INLINE void set(T *ptr) inline void set(T *ptr)
{ {
zero(); zero();
++ptr->__refCount; ++ptr->__refCount;
@ -75,26 +75,26 @@ public:
* *
* @param with Pointer to swap with * @param with Pointer to swap with
*/ */
ZT_ALWAYS_INLINE void swap(SharedPtr &with) inline void swap(SharedPtr &with)
{ {
T *tmp = _ptr; T *tmp = _ptr;
_ptr = with._ptr; _ptr = with._ptr;
with._ptr = tmp; with._ptr = tmp;
} }
ZT_ALWAYS_INLINE operator bool() const { return (_ptr != (T *)0); } inline operator bool() const { return (_ptr != (T *)0); }
ZT_ALWAYS_INLINE T &operator*() const { return *_ptr; } inline T &operator*() const { return *_ptr; }
ZT_ALWAYS_INLINE T *operator->() const { return _ptr; } inline T *operator->() const { return _ptr; }
/** /**
* @return Raw pointer to held object * @return Raw pointer to held object
*/ */
ZT_ALWAYS_INLINE T *ptr() const { return _ptr; } inline T *ptr() const { return _ptr; }
/** /**
* Set this pointer to NULL * Set this pointer to NULL
*/ */
ZT_ALWAYS_INLINE void zero() inline void zero()
{ {
if (_ptr) { if (_ptr) {
if (--_ptr->__refCount <= 0) if (--_ptr->__refCount <= 0)
@ -106,22 +106,22 @@ public:
/** /**
* @return Number of references according to this object's ref count or 0 if NULL * @return Number of references according to this object's ref count or 0 if NULL
*/ */
ZT_ALWAYS_INLINE int references() inline int references()
{ {
if (_ptr) if (_ptr)
return _ptr->__refCount.load(); return _ptr->__refCount.load();
return 0; return 0;
} }
ZT_ALWAYS_INLINE bool operator==(const SharedPtr &sp) const { return (_ptr == sp._ptr); } inline bool operator==(const SharedPtr &sp) const { return (_ptr == sp._ptr); }
ZT_ALWAYS_INLINE bool operator!=(const SharedPtr &sp) const { return (_ptr != sp._ptr); } inline bool operator!=(const SharedPtr &sp) const { return (_ptr != sp._ptr); }
ZT_ALWAYS_INLINE bool operator>(const SharedPtr &sp) const { return (_ptr > sp._ptr); } inline bool operator>(const SharedPtr &sp) const { return (_ptr > sp._ptr); }
ZT_ALWAYS_INLINE bool operator<(const SharedPtr &sp) const { return (_ptr < sp._ptr); } inline bool operator<(const SharedPtr &sp) const { return (_ptr < sp._ptr); }
ZT_ALWAYS_INLINE bool operator>=(const SharedPtr &sp) const { return (_ptr >= sp._ptr); } inline bool operator>=(const SharedPtr &sp) const { return (_ptr >= sp._ptr); }
ZT_ALWAYS_INLINE bool operator<=(const SharedPtr &sp) const { return (_ptr <= sp._ptr); } inline bool operator<=(const SharedPtr &sp) const { return (_ptr <= sp._ptr); }
private: private:
ZT_ALWAYS_INLINE T *_getAndInc() const inline T *_getAndInc() const
{ {
if (_ptr) if (_ptr)
++_ptr->__refCount; ++_ptr->__refCount;

View file

@ -35,36 +35,36 @@ public:
typedef char * iterator; typedef char * iterator;
typedef const char * const_iterator; typedef const char * const_iterator;
ZT_ALWAYS_INLINE Str() { _l = 0; _s[0] = 0; } inline Str() { _l = 0; _s[0] = 0; }
ZT_ALWAYS_INLINE Str(const Str &s) inline Str(const Str &s)
{ {
_l = s._l; _l = s._l;
memcpy(_s,s._s,_l+1); memcpy(_s,s._s,_l+1);
} }
ZT_ALWAYS_INLINE Str(const char *s) inline Str(const char *s)
{ {
_l = 0; _l = 0;
_s[0] = 0; _s[0] = 0;
(*this) << s; (*this) << s;
} }
ZT_ALWAYS_INLINE Str(const std::string &s) inline Str(const std::string &s)
{ {
*this = s; *this = s;
} }
ZT_ALWAYS_INLINE Str &operator=(const Str &s) inline Str &operator=(const Str &s)
{ {
_l = s._l; _l = s._l;
memcpy(_s,s._s,_l+1); memcpy(_s,s._s,_l+1);
return *this; return *this;
} }
ZT_ALWAYS_INLINE Str &operator=(const char *s) inline Str &operator=(const char *s)
{ {
_l = 0; _l = 0;
_s[0] = 0; _s[0] = 0;
return ((*this) << s); return ((*this) << s);
} }
ZT_ALWAYS_INLINE Str &operator=(const std::string &s) inline Str &operator=(const std::string &s)
{ {
if (s.length() > ZT_STR_CAPACITY) { if (s.length() > ZT_STR_CAPACITY) {
_l = 0; _l = 0;
@ -78,23 +78,23 @@ public:
return *this; return *this;
} }
ZT_ALWAYS_INLINE char operator[](const unsigned int i) const inline char operator[](const unsigned int i) const
{ {
if (unlikely(i >= (unsigned int)_l)) if (unlikely(i >= (unsigned int)_l))
throw ZT_EXCEPTION_OUT_OF_BOUNDS; throw ZT_EXCEPTION_OUT_OF_BOUNDS;
return _s[i]; return _s[i];
} }
ZT_ALWAYS_INLINE void clear() { _l = 0; _s[0] = 0; } inline void clear() { _l = 0; _s[0] = 0; }
ZT_ALWAYS_INLINE const char *c_str() const { return _s; } inline const char *c_str() const { return _s; }
ZT_ALWAYS_INLINE unsigned int length() const { return (unsigned int)_l; } inline unsigned int length() const { return (unsigned int)_l; }
ZT_ALWAYS_INLINE bool empty() const { return (_l == 0); } inline bool empty() const { return (_l == 0); }
ZT_ALWAYS_INLINE iterator begin() { return (iterator)_s; } inline iterator begin() { return (iterator)_s; }
ZT_ALWAYS_INLINE iterator end() { return (iterator)(_s + (unsigned long)_l); } inline iterator end() { return (iterator)(_s + (unsigned long)_l); }
ZT_ALWAYS_INLINE const_iterator begin() const { return (const_iterator)_s; } inline const_iterator begin() const { return (const_iterator)_s; }
ZT_ALWAYS_INLINE const_iterator end() const { return (const_iterator)(_s + (unsigned long)_l); } inline const_iterator end() const { return (const_iterator)(_s + (unsigned long)_l); }
ZT_ALWAYS_INLINE Str &operator<<(const char *s) inline Str &operator<<(const char *s)
{ {
if (likely(s != (const char *)0)) { if (likely(s != (const char *)0)) {
unsigned long l = _l; unsigned long l = _l;
@ -111,8 +111,8 @@ public:
} }
return *this; return *this;
} }
ZT_ALWAYS_INLINE Str &operator<<(const Str &s) { return ((*this) << s._s); } inline Str &operator<<(const Str &s) { return ((*this) << s._s); }
ZT_ALWAYS_INLINE Str &operator<<(const char c) inline Str &operator<<(const char c)
{ {
if (unlikely(_l >= ZT_STR_CAPACITY)) { if (unlikely(_l >= ZT_STR_CAPACITY)) {
_s[ZT_STR_CAPACITY] = 0; _s[ZT_STR_CAPACITY] = 0;
@ -122,35 +122,35 @@ public:
_s[(unsigned long)_l] = 0; _s[(unsigned long)_l] = 0;
return *this; return *this;
} }
ZT_ALWAYS_INLINE Str &operator<<(const unsigned long n) inline Str &operator<<(const unsigned long n)
{ {
char tmp[32]; char tmp[32];
Utils::decimal(n,tmp); Utils::decimal(n,tmp);
return ((*this) << tmp); return ((*this) << tmp);
} }
ZT_ALWAYS_INLINE Str &operator<<(const unsigned int n) inline Str &operator<<(const unsigned int n)
{ {
char tmp[32]; char tmp[32];
Utils::decimal((unsigned long)n,tmp); Utils::decimal((unsigned long)n,tmp);
return ((*this) << tmp); return ((*this) << tmp);
} }
ZT_ALWAYS_INLINE Str &operator<<(const Address &a) inline Str &operator<<(const Address &a)
{ {
char tmp[32]; char tmp[32];
return ((*this) << a.toString(tmp)); return ((*this) << a.toString(tmp));
} }
ZT_ALWAYS_INLINE Str &operator<<(const InetAddress &a) inline Str &operator<<(const InetAddress &a)
{ {
char tmp[128]; char tmp[128];
return ((*this) << a.toString(tmp)); return ((*this) << a.toString(tmp));
} }
ZT_ALWAYS_INLINE Str &operator<<(const MAC &a) inline Str &operator<<(const MAC &a)
{ {
char tmp[64]; char tmp[64];
return ((*this) << a.toString(tmp)); return ((*this) << a.toString(tmp));
} }
ZT_ALWAYS_INLINE Str &append(const char *s,const unsigned int max) inline Str &append(const char *s,const unsigned int max)
{ {
if (likely(s != (const char *)0)) { if (likely(s != (const char *)0)) {
unsigned long l = _l; unsigned long l = _l;
@ -171,23 +171,23 @@ public:
return *this; return *this;
} }
ZT_ALWAYS_INLINE operator bool() const { return (_l != 0); } inline operator bool() const { return (_l != 0); }
ZT_ALWAYS_INLINE bool operator==(const Str &s) const { return ((_l == s._l)&&(memcmp(_s,s._s,_l) == 0)); } inline bool operator==(const Str &s) const { return ((_l == s._l)&&(memcmp(_s,s._s,_l) == 0)); }
ZT_ALWAYS_INLINE bool operator!=(const Str &s) const { return ((_l != s._l)||(memcmp(_s,s._s,_l) != 0)); } inline bool operator!=(const Str &s) const { return ((_l != s._l)||(memcmp(_s,s._s,_l) != 0)); }
ZT_ALWAYS_INLINE bool operator<(const Str &s) const { return ( (_l < s._l) ? true : ((_l == s._l) ? (memcmp(_s,s._s,_l) < 0) : false) ); } inline bool operator<(const Str &s) const { return ( (_l < s._l) ? true : ((_l == s._l) ? (memcmp(_s,s._s,_l) < 0) : false) ); }
ZT_ALWAYS_INLINE bool operator>(const Str &s) const { return (s < *this); } inline bool operator>(const Str &s) const { return (s < *this); }
ZT_ALWAYS_INLINE bool operator<=(const Str &s) const { return !(s < *this); } inline bool operator<=(const Str &s) const { return !(s < *this); }
ZT_ALWAYS_INLINE bool operator>=(const Str &s) const { return !(*this < s); } inline bool operator>=(const Str &s) const { return !(*this < s); }
ZT_ALWAYS_INLINE bool operator==(const char *s) const { return (strcmp(_s,s) == 0); } inline bool operator==(const char *s) const { return (strcmp(_s,s) == 0); }
ZT_ALWAYS_INLINE bool operator!=(const char *s) const { return (strcmp(_s,s) != 0); } inline bool operator!=(const char *s) const { return (strcmp(_s,s) != 0); }
ZT_ALWAYS_INLINE bool operator<(const char *s) const { return (strcmp(_s,s) < 0); } inline bool operator<(const char *s) const { return (strcmp(_s,s) < 0); }
ZT_ALWAYS_INLINE bool operator>(const char *s) const { return (strcmp(_s,s) > 0); } inline bool operator>(const char *s) const { return (strcmp(_s,s) > 0); }
ZT_ALWAYS_INLINE bool operator<=(const char *s) const { return (strcmp(_s,s) <= 0); } inline bool operator<=(const char *s) const { return (strcmp(_s,s) <= 0); }
ZT_ALWAYS_INLINE bool operator>=(const char *s) const { return (strcmp(_s,s) >= 0); } inline bool operator>=(const char *s) const { return (strcmp(_s,s) >= 0); }
ZT_ALWAYS_INLINE unsigned long hashCode() const inline unsigned long hashCode() const
{ {
const char *p = _s; const char *p = _s;
unsigned long h = 0; unsigned long h = 0;

View file

@ -225,7 +225,7 @@ private:
AtomicCounter _rxQueuePtr; AtomicCounter _rxQueuePtr;
// Returns matching or next available RX queue entry // Returns matching or next available RX queue entry
ZT_ALWAYS_INLINE RXQueueEntry *_findRXQueueEntry(uint64_t packetId) inline RXQueueEntry *_findRXQueueEntry(uint64_t packetId)
{ {
const unsigned int current = static_cast<unsigned int>(_rxQueuePtr.load()); const unsigned int current = static_cast<unsigned int>(_rxQueuePtr.load());
for(unsigned int k=1;k<=ZT_RX_QUEUE_SIZE;++k) { for(unsigned int k=1;k<=ZT_RX_QUEUE_SIZE;++k) {
@ -238,7 +238,7 @@ private:
} }
// Returns current entry in rx queue ring buffer and increments ring pointer // Returns current entry in rx queue ring buffer and increments ring pointer
ZT_ALWAYS_INLINE RXQueueEntry *_nextRXQueueEntry() inline RXQueueEntry *_nextRXQueueEntry()
{ {
return &(_rxQueue[static_cast<unsigned int>((++_rxQueuePtr) - 1) % ZT_RX_QUEUE_SIZE]); return &(_rxQueue[static_cast<unsigned int>((++_rxQueuePtr) - 1) % ZT_RX_QUEUE_SIZE]);
} }
@ -276,9 +276,9 @@ private:
y = a2.toInt(); y = a2.toInt();
} }
} }
ZT_ALWAYS_INLINE unsigned long hashCode() const { return ((unsigned long)x ^ (unsigned long)y); } inline unsigned long hashCode() const { return ((unsigned long)x ^ (unsigned long)y); }
ZT_ALWAYS_INLINE bool operator==(const _LastUniteKey &k) const { return ((x == k.x)&&(y == k.y)); } inline bool operator==(const _LastUniteKey &k) const { return ((x == k.x)&&(y == k.y)); }
ZT_ALWAYS_INLINE bool operator!=(const _LastUniteKey &k) const { return ((x != k.x)||(y != k.y)); } inline bool operator!=(const _LastUniteKey &k) const { return ((x != k.x)||(y != k.y)); }
uint64_t x,y; uint64_t x,y;
}; };
Hashtable< _LastUniteKey,uint64_t > _lastUniteAttempt; // key is always sorted in ascending order, for set-like behavior Hashtable< _LastUniteKey,uint64_t > _lastUniteAttempt; // key is always sorted in ascending order, for set-like behavior

View file

@ -52,9 +52,9 @@ class Tag : public Credential
friend class Credential; friend class Credential;
public: public:
static ZT_ALWAYS_INLINE Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_TAG; } static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_TAG; }
ZT_ALWAYS_INLINE Tag() : inline Tag() :
_id(0), _id(0),
_value(0), _value(0),
_networkId(0), _networkId(0),
@ -70,7 +70,7 @@ public:
* @param id Tag ID * @param id Tag ID
* @param value Tag value * @param value Tag value
*/ */
ZT_ALWAYS_INLINE Tag(const uint64_t nwid,const int64_t ts,const Address &issuedTo,const uint32_t id,const uint32_t value) : inline Tag(const uint64_t nwid,const int64_t ts,const Address &issuedTo,const uint32_t id,const uint32_t value) :
_id(id), _id(id),
_value(value), _value(value),
_networkId(nwid), _networkId(nwid),
@ -81,14 +81,14 @@ public:
{ {
} }
ZT_ALWAYS_INLINE uint32_t id() const { return _id; } inline uint32_t id() const { return _id; }
ZT_ALWAYS_INLINE const uint32_t &value() const { return _value; } inline const uint32_t &value() const { return _value; }
ZT_ALWAYS_INLINE uint64_t networkId() const { return _networkId; } inline uint64_t networkId() const { return _networkId; }
ZT_ALWAYS_INLINE int64_t timestamp() const { return _ts; } inline int64_t timestamp() const { return _ts; }
ZT_ALWAYS_INLINE const Address &issuedTo() const { return _issuedTo; } inline const Address &issuedTo() const { return _issuedTo; }
ZT_ALWAYS_INLINE const Address &signer() const { return _signedBy; } inline const Address &signer() const { return _signedBy; }
ZT_ALWAYS_INLINE const uint8_t *signature() const { return _signature; } inline const uint8_t *signature() const { return _signature; }
ZT_ALWAYS_INLINE unsigned int signatureLength() const { return _signatureLength; } inline unsigned int signatureLength() const { return _signatureLength; }
/** /**
* Sign this tag * Sign this tag
@ -96,7 +96,7 @@ public:
* @param signer Signing identity, must have private key * @param signer Signing identity, must have private key
* @return True if signature was successful * @return True if signature was successful
*/ */
ZT_ALWAYS_INLINE bool sign(const Identity &signer) inline bool sign(const Identity &signer)
{ {
if (signer.hasPrivate()) { if (signer.hasPrivate()) {
Buffer<sizeof(Tag) + 64> tmp; Buffer<sizeof(Tag) + 64> tmp;
@ -114,7 +114,7 @@ public:
* @param RR Runtime environment to allow identity lookup for signedBy * @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 * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
*/ */
ZT_ALWAYS_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); } inline Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); }
template<unsigned int C> template<unsigned int C>
inline void serialize(Buffer<C> &b,const bool forSign = false) const inline void serialize(Buffer<C> &b,const bool forSign = false) const
@ -172,23 +172,23 @@ public:
} }
// Provides natural sort order by ID // Provides natural sort order by ID
ZT_ALWAYS_INLINE bool operator<(const Tag &t) const { return (_id < t._id); } inline bool operator<(const Tag &t) const { return (_id < t._id); }
ZT_ALWAYS_INLINE bool operator==(const Tag &t) const { return (memcmp(this,&t,sizeof(Tag)) == 0); } inline bool operator==(const Tag &t) const { return (memcmp(this,&t,sizeof(Tag)) == 0); }
ZT_ALWAYS_INLINE bool operator!=(const Tag &t) const { return (memcmp(this,&t,sizeof(Tag)) != 0); } inline bool operator!=(const Tag &t) const { return (memcmp(this,&t,sizeof(Tag)) != 0); }
// For searching sorted arrays or lists of Tags by ID // For searching sorted arrays or lists of Tags by ID
struct IdComparePredicate struct IdComparePredicate
{ {
ZT_ALWAYS_INLINE bool operator()(const Tag &a,const Tag &b) const { return (a.id() < b.id()); } inline bool operator()(const Tag &a,const Tag &b) const { return (a.id() < b.id()); }
ZT_ALWAYS_INLINE bool operator()(const uint32_t a,const Tag &b) const { return (a < b.id()); } inline bool operator()(const uint32_t a,const Tag &b) const { return (a < b.id()); }
ZT_ALWAYS_INLINE bool operator()(const Tag &a,const uint32_t b) const { return (a.id() < b); } inline bool operator()(const Tag &a,const uint32_t b) const { return (a.id() < b); }
ZT_ALWAYS_INLINE bool operator()(const Tag *a,const Tag *b) const { return (a->id() < b->id()); } inline bool operator()(const Tag *a,const Tag *b) const { return (a->id() < b->id()); }
ZT_ALWAYS_INLINE bool operator()(const Tag *a,const Tag &b) const { return (a->id() < b.id()); } inline bool operator()(const Tag *a,const Tag &b) const { return (a->id() < b.id()); }
ZT_ALWAYS_INLINE bool operator()(const Tag &a,const Tag *b) const { return (a.id() < b->id()); } inline bool operator()(const Tag &a,const Tag *b) const { return (a.id() < b->id()); }
ZT_ALWAYS_INLINE bool operator()(const uint32_t a,const Tag *b) const { return (a < b->id()); } inline bool operator()(const uint32_t a,const Tag *b) const { return (a < b->id()); }
ZT_ALWAYS_INLINE bool operator()(const Tag *a,const uint32_t b) const { return (a->id() < b); } inline bool operator()(const Tag *a,const uint32_t b) const { return (a->id() < b); }
ZT_ALWAYS_INLINE bool operator()(const uint32_t a,const uint32_t b) const { return (a < b); } inline bool operator()(const uint32_t a,const uint32_t b) const { return (a < b); }
}; };
private: private:

View file

@ -49,8 +49,8 @@ class Topology
private: private:
struct _RootRankingFunction struct _RootRankingFunction
{ {
ZT_ALWAYS_INLINE _RootRankingFunction() : bestRoot(),bestRootLatency(0xffff) {} inline _RootRankingFunction() : bestRoot(),bestRootLatency(0xffff) {}
ZT_ALWAYS_INLINE bool operator()(const SharedPtr<Peer> &peer,const std::vector<InetAddress> &phy) inline bool operator()(const SharedPtr<Peer> &peer,const std::vector<InetAddress> &phy)
{ {
const unsigned int lat = peer->latency(now); const unsigned int lat = peer->latency(now);
if ((!bestRoot)||((lat <= bestRootLatency)&&(peer->getAppropriatePath(now,false)))) { if ((!bestRoot)||((lat <= bestRootLatency)&&(peer->getAppropriatePath(now,false)))) {
@ -64,7 +64,7 @@ private:
unsigned int bestRootLatency; unsigned int bestRootLatency;
}; };
ZT_ALWAYS_INLINE void _updateRoots() inline void _updateRoots()
{ {
// assumes _roots_l is locked // assumes _roots_l is locked
_rootIdentities.clear(); _rootIdentities.clear();
@ -78,7 +78,7 @@ private:
} }
public: public:
ZT_ALWAYS_INLINE Topology(const RuntimeEnvironment *renv,const Identity &myId) : inline Topology(const RuntimeEnvironment *renv,const Identity &myId) :
RR(renv), RR(renv),
_myIdentity(myId), _myIdentity(myId),
_numConfiguredPhysicalPaths(0), _numConfiguredPhysicalPaths(0),
@ -87,7 +87,7 @@ public:
_roots(8), _roots(8),
_rootIdentities(8), _rootIdentities(8),
_lastUpdatedBestRoot(0) {} _lastUpdatedBestRoot(0) {}
ZT_ALWAYS_INLINE ~Topology() {} inline ~Topology() {}
/** /**
* Add a peer to database * Add a peer to database
@ -99,7 +99,7 @@ public:
* @param peer Peer to add * @param peer Peer to add
* @return New or existing peer (should replace 'peer') * @return New or existing peer (should replace 'peer')
*/ */
ZT_ALWAYS_INLINE SharedPtr<Peer> add(const SharedPtr<Peer> &peer) inline SharedPtr<Peer> add(const SharedPtr<Peer> &peer)
{ {
SharedPtr<Peer> np; SharedPtr<Peer> np;
{ {
@ -119,7 +119,7 @@ public:
* @param zta ZeroTier address of peer * @param zta ZeroTier address of peer
* @return Peer or NULL if not found * @return Peer or NULL if not found
*/ */
ZT_ALWAYS_INLINE SharedPtr<Peer> get(const Address &zta) inline SharedPtr<Peer> get(const Address &zta)
{ {
if (zta == _myIdentity.address()) if (zta == _myIdentity.address())
return SharedPtr<Peer>(); return SharedPtr<Peer>();
@ -135,7 +135,7 @@ public:
* @param zta ZeroTier address of peer * @param zta ZeroTier address of peer
* @return Identity or NULL identity if not found * @return Identity or NULL identity if not found
*/ */
ZT_ALWAYS_INLINE Identity getIdentity(void *tPtr,const Address &zta) inline Identity getIdentity(void *tPtr,const Address &zta)
{ {
if (zta == _myIdentity.address()) { if (zta == _myIdentity.address()) {
return _myIdentity; return _myIdentity;
@ -155,7 +155,7 @@ public:
* @param r Remote address * @param r Remote address
* @return Pointer to canonicalized Path object * @return Pointer to canonicalized Path object
*/ */
ZT_ALWAYS_INLINE SharedPtr<Path> getPath(const int64_t l,const InetAddress &r) inline SharedPtr<Path> getPath(const int64_t l,const InetAddress &r)
{ {
Mutex::Lock _l(_paths_l); Mutex::Lock _l(_paths_l);
SharedPtr<Path> &p = _paths[Path::HashKey(l,r)]; SharedPtr<Path> &p = _paths[Path::HashKey(l,r)];
@ -168,7 +168,7 @@ public:
* @param id Identity to check * @param id Identity to check
* @return True if this identity corresponds to a root * @return True if this identity corresponds to a root
*/ */
ZT_ALWAYS_INLINE bool isRoot(const Identity &id) const inline bool isRoot(const Identity &id) const
{ {
Mutex::Lock l(_roots_l); Mutex::Lock l(_roots_l);
return _rootIdentities.contains(id); return _rootIdentities.contains(id);
@ -177,7 +177,7 @@ public:
/** /**
* Do periodic tasks such as database cleanup * Do periodic tasks such as database cleanup
*/ */
ZT_ALWAYS_INLINE void doPeriodicTasks(int64_t now) inline void doPeriodicTasks(int64_t now)
{ {
{ {
Mutex::Lock _l1(_peers_l); Mutex::Lock _l1(_peers_l);
@ -231,7 +231,7 @@ public:
* @tparam F Function or function object type * @tparam F Function or function object type
*/ */
template<typename F> template<typename F>
ZT_ALWAYS_INLINE void eachPeer(F f) inline void eachPeer(F f)
{ {
Mutex::Lock l(_peers_l); Mutex::Lock l(_peers_l);
Hashtable< Address,SharedPtr<Peer> >::Iterator i(_peers); Hashtable< Address,SharedPtr<Peer> >::Iterator i(_peers);
@ -253,7 +253,7 @@ public:
* @tparam F function or function object type * @tparam F function or function object type
*/ */
template<typename F> template<typename F>
ZT_ALWAYS_INLINE void eachRoot(F f) inline void eachRoot(F f)
{ {
Mutex::Lock l(_roots_l); Mutex::Lock l(_roots_l);
Hashtable< Str,Locator >::Iterator i(_roots); Hashtable< Str,Locator >::Iterator i(_roots);
@ -306,7 +306,7 @@ public:
* @param f Function of (Str,Locator) * @param f Function of (Str,Locator)
*/ */
template<typename F> template<typename F>
ZT_ALWAYS_INLINE void eachRootName(F f) const inline void eachRootName(F f) const
{ {
Mutex::Lock l(_roots_l); Mutex::Lock l(_roots_l);
Str *k = (Str *)0; Str *k = (Str *)0;
@ -405,7 +405,7 @@ public:
* @param toAddr Destination address * @param toAddr Destination address
* @return Best current relay or NULL if none * @return Best current relay or NULL if none
*/ */
ZT_ALWAYS_INLINE SharedPtr<Peer> findRelayTo(const int64_t now,const Address &toAddr) inline SharedPtr<Peer> findRelayTo(const int64_t now,const Address &toAddr)
{ {
// TODO: in the future this will check 'mesh-like' relays and if enabled consult LF for other roots (for if this is a root) // TODO: in the future this will check 'mesh-like' relays and if enabled consult LF for other roots (for if this is a root)
return root(now); return root(now);
@ -414,7 +414,7 @@ public:
/** /**
* @param allPeers vector to fill with all current peers * @param allPeers vector to fill with all current peers
*/ */
ZT_ALWAYS_INLINE void getAllPeers(std::vector< SharedPtr<Peer> > &allPeers) const inline void getAllPeers(std::vector< SharedPtr<Peer> > &allPeers) const
{ {
Mutex::Lock l(_peers_l); Mutex::Lock l(_peers_l);
allPeers.clear(); allPeers.clear();
@ -436,7 +436,7 @@ public:
* @param mtu Variable set to MTU * @param mtu Variable set to MTU
* @param trustedPathId Variable set to trusted path ID * @param trustedPathId Variable set to trusted path ID
*/ */
ZT_ALWAYS_INLINE void getOutboundPathInfo(const InetAddress &physicalAddress,unsigned int &mtu,uint64_t &trustedPathId) inline void getOutboundPathInfo(const InetAddress &physicalAddress,unsigned int &mtu,uint64_t &trustedPathId)
{ {
for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i) { for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i) {
if (_physicalPathConfig[i].first.containsAddress(physicalAddress)) { if (_physicalPathConfig[i].first.containsAddress(physicalAddress)) {
@ -453,7 +453,7 @@ public:
* @param physicalAddress Physical endpoint address * @param physicalAddress Physical endpoint address
* @return MTU * @return MTU
*/ */
ZT_ALWAYS_INLINE unsigned int getOutboundPathMtu(const InetAddress &physicalAddress) inline unsigned int getOutboundPathMtu(const InetAddress &physicalAddress)
{ {
for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i) { for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i) {
if (_physicalPathConfig[i].first.containsAddress(physicalAddress)) if (_physicalPathConfig[i].first.containsAddress(physicalAddress))
@ -468,7 +468,7 @@ public:
* @param physicalAddress Physical address to which we are sending the packet * @param physicalAddress Physical address to which we are sending the packet
* @return Trusted path ID or 0 if none (0 is not a valid trusted path ID) * @return Trusted path ID or 0 if none (0 is not a valid trusted path ID)
*/ */
ZT_ALWAYS_INLINE uint64_t getOutboundPathTrust(const InetAddress &physicalAddress) inline uint64_t getOutboundPathTrust(const InetAddress &physicalAddress)
{ {
for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i) { for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i) {
if (_physicalPathConfig[i].first.containsAddress(physicalAddress)) if (_physicalPathConfig[i].first.containsAddress(physicalAddress))
@ -483,7 +483,7 @@ public:
* @param physicalAddress Originating physical address * @param physicalAddress Originating physical address
* @param trustedPathId Trusted path ID from packet (from MAC field) * @param trustedPathId Trusted path ID from packet (from MAC field)
*/ */
ZT_ALWAYS_INLINE bool shouldInboundPathBeTrusted(const InetAddress &physicalAddress,const uint64_t trustedPathId) inline bool shouldInboundPathBeTrusted(const InetAddress &physicalAddress,const uint64_t trustedPathId)
{ {
for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i) { for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i) {
if ((_physicalPathConfig[i].second.trustedPathId == trustedPathId)&&(_physicalPathConfig[i].first.containsAddress(physicalAddress))) if ((_physicalPathConfig[i].second.trustedPathId == trustedPathId)&&(_physicalPathConfig[i].first.containsAddress(physicalAddress)))

View file

@ -75,30 +75,30 @@ public:
class RuleResultLog class RuleResultLog
{ {
public: public:
ZT_ALWAYS_INLINE RuleResultLog() {} inline RuleResultLog() {}
ZT_ALWAYS_INLINE void log(const unsigned int rn,const uint8_t thisRuleMatches,const uint8_t thisSetMatches) inline void log(const unsigned int rn,const uint8_t thisRuleMatches,const uint8_t thisSetMatches)
{ {
_l[rn >> 1] |= ( ((thisRuleMatches + 1) << 2) | (thisSetMatches + 1) ) << ((rn & 1) << 2); _l[rn >> 1] |= ( ((thisRuleMatches + 1) << 2) | (thisSetMatches + 1) ) << ((rn & 1) << 2);
} }
ZT_ALWAYS_INLINE void logSkipped(const unsigned int rn,const uint8_t thisSetMatches) inline void logSkipped(const unsigned int rn,const uint8_t thisSetMatches)
{ {
_l[rn >> 1] |= (thisSetMatches + 1) << ((rn & 1) << 2); _l[rn >> 1] |= (thisSetMatches + 1) << ((rn & 1) << 2);
} }
ZT_ALWAYS_INLINE void clear() inline void clear()
{ {
memset(_l,0,sizeof(_l)); memset(_l,0,sizeof(_l));
} }
ZT_ALWAYS_INLINE const uint8_t *data() const { return _l; } inline const uint8_t *data() const { return _l; }
ZT_ALWAYS_INLINE unsigned int sizeBytes() const { return (ZT_MAX_NETWORK_RULES / 2); } inline unsigned int sizeBytes() const { return (ZT_MAX_NETWORK_RULES / 2); }
private: private:
uint8_t _l[ZT_MAX_NETWORK_RULES / 2]; uint8_t _l[ZT_MAX_NETWORK_RULES / 2];
}; };
ZT_ALWAYS_INLINE Trace(const RuntimeEnvironment *renv) : inline Trace(const RuntimeEnvironment *renv) :
RR(renv), RR(renv),
_byNet(8) {} _byNet(8) {}

View file

@ -44,7 +44,7 @@ const char HEXCHARS[16];
* @param len Length of strings * @param len Length of strings
* @return True if strings are equal * @return True if strings are equal
*/ */
ZT_ALWAYS_INLINE bool secureEq(const void *a,const void *b,unsigned int len) inline bool secureEq(const void *a,const void *b,unsigned int len)
{ {
uint8_t diff = 0; uint8_t diff = 0;
for(unsigned int i=0;i<len;++i) for(unsigned int i=0;i<len;++i)
@ -77,7 +77,7 @@ uint16_t crc16(const void *buf,unsigned int len);
* @return Pointer to s containing hex string with trailing zero byte * @return Pointer to s containing hex string with trailing zero byte
*/ */
template<typename I> template<typename I>
static ZT_ALWAYS_INLINE char *hex(I x,char *s) static inline char *hex(I x,char *s)
{ {
char *const r = s; char *const r = s;
for(unsigned int i=0,b=(sizeof(x)*8);i<sizeof(x);++i) { for(unsigned int i=0,b=(sizeof(x)*8);i<sizeof(x);++i) {
@ -95,7 +95,7 @@ static ZT_ALWAYS_INLINE char *hex(I x,char *s)
* @param s Buffer of size [11] to receive 10 hex characters * @param s Buffer of size [11] to receive 10 hex characters
* @return Pointer to buffer * @return Pointer to buffer
*/ */
static ZT_ALWAYS_INLINE char *hex10(uint64_t i,char s[11]) static inline char *hex10(uint64_t i,char s[11])
{ {
s[0] = HEXCHARS[(i >> 36) & 0xf]; s[0] = HEXCHARS[(i >> 36) & 0xf];
s[1] = HEXCHARS[(i >> 32) & 0xf]; s[1] = HEXCHARS[(i >> 32) & 0xf];
@ -119,7 +119,7 @@ static ZT_ALWAYS_INLINE char *hex10(uint64_t i,char s[11])
* @param s String buffer, must be at least (l*2)+1 in size or overflow will occur * @param s String buffer, must be at least (l*2)+1 in size or overflow will occur
* @return Pointer to filled string buffer * @return Pointer to filled string buffer
*/ */
static ZT_ALWAYS_INLINE char *hex(const void *d,unsigned int l,char *s) static inline char *hex(const void *d,unsigned int l,char *s)
{ {
char *const save = s; char *const save = s;
for(unsigned int i=0;i<l;++i) { for(unsigned int i=0;i<l;++i) {
@ -148,7 +148,7 @@ void getSecureRandom(void *buf,unsigned int bytes);
/** /**
* Get a 64-bit unsigned secure random number * Get a 64-bit unsigned secure random number
*/ */
static ZT_ALWAYS_INLINE uint64_t getSecureRandom64() static inline uint64_t getSecureRandom64()
{ {
uint64_t x; uint64_t x;
getSecureRandom(&x,sizeof(x)); getSecureRandom(&x,sizeof(x));
@ -158,7 +158,7 @@ static ZT_ALWAYS_INLINE uint64_t getSecureRandom64()
int b32e(const uint8_t *data,int length,char *result,int bufSize); int b32e(const uint8_t *data,int length,char *result,int bufSize);
int b32d(const char *encoded, uint8_t *result, int bufSize); int b32d(const char *encoded, uint8_t *result, int bufSize);
static ZT_ALWAYS_INLINE unsigned int b64MaxEncodedSize(const unsigned int s) { return ((((s + 2) / 3) * 4) + 1); } static inline unsigned int b64MaxEncodedSize(const unsigned int s) { return ((((s + 2) / 3) * 4) + 1); }
unsigned int b64e(const uint8_t *in,unsigned int inlen,char *out,unsigned int outlen); unsigned int b64e(const uint8_t *in,unsigned int inlen,char *out,unsigned int outlen);
unsigned int b64d(const char *in,uint8_t *out,unsigned int outlen); unsigned int b64d(const char *in,uint8_t *out,unsigned int outlen);
@ -167,7 +167,7 @@ unsigned int b64d(const char *in,uint8_t *out,unsigned int outlen);
*/ */
uint64_t random(); uint64_t random();
static ZT_ALWAYS_INLINE float normalize(float value, int64_t bigMin, int64_t bigMax, int32_t targetMin, int32_t targetMax) static inline float normalize(float value, int64_t bigMin, int64_t bigMax, int32_t targetMin, int32_t targetMax)
{ {
int64_t bigSpan = bigMax - bigMin; int64_t bigSpan = bigMax - bigMin;
int64_t smallSpan = targetMax - targetMin; int64_t smallSpan = targetMax - targetMin;
@ -182,7 +182,7 @@ static ZT_ALWAYS_INLINE float normalize(float value, int64_t bigMin, int64_t big
* @param delim Delimiters * @param delim Delimiters
* @param saveptr Pointer to a char * for temporary reentrant storage * @param saveptr Pointer to a char * for temporary reentrant storage
*/ */
static ZT_ALWAYS_INLINE char *stok(char *str,const char *delim,char **saveptr) static inline char *stok(char *str,const char *delim,char **saveptr)
{ {
#ifdef __WINDOWS__ #ifdef __WINDOWS__
return strtok_s(str,delim,saveptr); return strtok_s(str,delim,saveptr);
@ -191,11 +191,11 @@ static ZT_ALWAYS_INLINE char *stok(char *str,const char *delim,char **saveptr)
#endif #endif
} }
static ZT_ALWAYS_INLINE unsigned int strToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,10); } static inline unsigned int strToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,10); }
static ZT_ALWAYS_INLINE int strToInt(const char *s) { return (int)strtol(s,(char **)0,10); } static inline int strToInt(const char *s) { return (int)strtol(s,(char **)0,10); }
static ZT_ALWAYS_INLINE unsigned long strToULong(const char *s) { return strtoul(s,(char **)0,10); } static inline unsigned long strToULong(const char *s) { return strtoul(s,(char **)0,10); }
static ZT_ALWAYS_INLINE long strToLong(const char *s) { return strtol(s,(char **)0,10); } static inline long strToLong(const char *s) { return strtol(s,(char **)0,10); }
static ZT_ALWAYS_INLINE unsigned long long strToU64(const char *s) static inline unsigned long long strToU64(const char *s)
{ {
#ifdef __WINDOWS__ #ifdef __WINDOWS__
return (unsigned long long)_strtoui64(s,(char **)0,10); return (unsigned long long)_strtoui64(s,(char **)0,10);
@ -203,7 +203,7 @@ static ZT_ALWAYS_INLINE unsigned long long strToU64(const char *s)
return strtoull(s,(char **)0,10); return strtoull(s,(char **)0,10);
#endif #endif
} }
static ZT_ALWAYS_INLINE long long strTo64(const char *s) static inline long long strTo64(const char *s)
{ {
#ifdef __WINDOWS__ #ifdef __WINDOWS__
return (long long)_strtoi64(s,(char **)0,10); return (long long)_strtoi64(s,(char **)0,10);
@ -211,11 +211,11 @@ static ZT_ALWAYS_INLINE long long strTo64(const char *s)
return strtoll(s,(char **)0,10); return strtoll(s,(char **)0,10);
#endif #endif
} }
static ZT_ALWAYS_INLINE unsigned int hexStrToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,16); } static inline unsigned int hexStrToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,16); }
static ZT_ALWAYS_INLINE int hexStrToInt(const char *s) { return (int)strtol(s,(char **)0,16); } static inline int hexStrToInt(const char *s) { return (int)strtol(s,(char **)0,16); }
static ZT_ALWAYS_INLINE unsigned long hexStrToULong(const char *s) { return strtoul(s,(char **)0,16); } static inline unsigned long hexStrToULong(const char *s) { return strtoul(s,(char **)0,16); }
static ZT_ALWAYS_INLINE long hexStrToLong(const char *s) { return strtol(s,(char **)0,16); } static inline long hexStrToLong(const char *s) { return strtol(s,(char **)0,16); }
static ZT_ALWAYS_INLINE unsigned long long hexStrToU64(const char *s) static inline unsigned long long hexStrToU64(const char *s)
{ {
#ifdef __WINDOWS__ #ifdef __WINDOWS__
return (unsigned long long)_strtoui64(s,(char **)0,16); return (unsigned long long)_strtoui64(s,(char **)0,16);
@ -223,7 +223,7 @@ static ZT_ALWAYS_INLINE unsigned long long hexStrToU64(const char *s)
return strtoull(s,(char **)0,16); return strtoull(s,(char **)0,16);
#endif #endif
} }
static ZT_ALWAYS_INLINE long long hexStrTo64(const char *s) static inline long long hexStrTo64(const char *s)
{ {
#ifdef __WINDOWS__ #ifdef __WINDOWS__
return (long long)_strtoi64(s,(char **)0,16); return (long long)_strtoi64(s,(char **)0,16);
@ -243,7 +243,7 @@ static ZT_ALWAYS_INLINE long long hexStrTo64(const char *s)
* @param src Source string (if NULL, dest will receive a zero-length string and true is returned) * @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) * @return True on success, false on overflow (buffer will still be 0-terminated)
*/ */
static ZT_ALWAYS_INLINE bool scopy(char *dest,unsigned int len,const char *src) static inline bool scopy(char *dest,unsigned int len,const char *src)
{ {
if (!len) if (!len)
return false; // sanity check return false; // sanity check
@ -262,10 +262,10 @@ static ZT_ALWAYS_INLINE bool scopy(char *dest,unsigned int len,const char *src)
} }
#ifdef __GNUC__ #ifdef __GNUC__
static ZT_ALWAYS_INLINE unsigned int countBits(const uint8_t v) { return (unsigned int)__builtin_popcount((unsigned int)v); } static inline unsigned int countBits(const uint8_t v) { return (unsigned int)__builtin_popcount((unsigned int)v); }
static ZT_ALWAYS_INLINE unsigned int countBits(const uint16_t v) { return (unsigned int)__builtin_popcount((unsigned int)v); } static inline unsigned int countBits(const uint16_t v) { return (unsigned int)__builtin_popcount((unsigned int)v); }
static ZT_ALWAYS_INLINE unsigned int countBits(const uint32_t v) { return (unsigned int)__builtin_popcountl((unsigned long)v); } static inline unsigned int countBits(const uint32_t v) { return (unsigned int)__builtin_popcountl((unsigned long)v); }
static ZT_ALWAYS_INLINE unsigned int countBits(const uint64_t v) { return (unsigned int)__builtin_popcountll((unsigned long long)v); } static inline unsigned int countBits(const uint64_t v) { return (unsigned int)__builtin_popcountll((unsigned long long)v); }
#else #else
/** /**
* Count the number of bits set in an integer * Count the number of bits set in an integer
@ -274,7 +274,7 @@ static ZT_ALWAYS_INLINE unsigned int countBits(const uint64_t v) { return (unsig
* @return Number of bits set in this integer (0-bits in integer) * @return Number of bits set in this integer (0-bits in integer)
*/ */
template<typename T> template<typename T>
static ZT_ALWAYS_INLINE unsigned int countBits(T v) static inline unsigned int countBits(T v)
{ {
v = v - ((v >> 1) & (T)~(T)0/3); v = v - ((v >> 1) & (T)~(T)0/3);
v = (v & (T)~(T)0/15*3) + ((v >> 2) & (T)~(T)0/15*3); v = (v & (T)~(T)0/15*3) + ((v >> 2) & (T)~(T)0/15*3);
@ -285,11 +285,11 @@ static ZT_ALWAYS_INLINE unsigned int countBits(T v)
// Byte swappers for big/little endian conversion // Byte swappers for big/little endian conversion
#if __BYTE_ORDER == __LITTLE_ENDIAN #if __BYTE_ORDER == __LITTLE_ENDIAN
static ZT_ALWAYS_INLINE uint8_t hton(uint8_t n) { return n; } static inline uint8_t hton(uint8_t n) { return n; }
static ZT_ALWAYS_INLINE int8_t hton(int8_t n) { return n; } static inline int8_t hton(int8_t n) { return n; }
static ZT_ALWAYS_INLINE uint16_t hton(uint16_t n) { return htons(n); } static inline uint16_t hton(uint16_t n) { return htons(n); }
static ZT_ALWAYS_INLINE int16_t hton(int16_t n) { return (int16_t)Utils::hton((uint16_t)n); } static inline int16_t hton(int16_t n) { return (int16_t)Utils::hton((uint16_t)n); }
static ZT_ALWAYS_INLINE uint32_t hton(uint32_t n) static inline uint32_t hton(uint32_t n)
{ {
#if defined(__GNUC__) #if defined(__GNUC__)
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
@ -301,8 +301,8 @@ static ZT_ALWAYS_INLINE uint32_t hton(uint32_t n)
return htonl(n); return htonl(n);
#endif #endif
} }
static ZT_ALWAYS_INLINE int32_t hton(int32_t n) { return (int32_t)Utils::hton((uint32_t)n); } static inline int32_t hton(int32_t n) { return (int32_t)Utils::hton((uint32_t)n); }
static ZT_ALWAYS_INLINE uint64_t hton(uint64_t n) static inline uint64_t hton(uint64_t n)
{ {
#if defined(__GNUC__) #if defined(__GNUC__)
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
@ -323,18 +323,18 @@ static ZT_ALWAYS_INLINE uint64_t hton(uint64_t n)
); );
#endif #endif
} }
static ZT_ALWAYS_INLINE int64_t hton(int64_t n) { return (int64_t)hton((uint64_t)n); } static inline int64_t hton(int64_t n) { return (int64_t)hton((uint64_t)n); }
#else #else
template<typename T> template<typename T>
static ZT_ALWAYS_INLINE T hton(T n) { return n; } static inline T hton(T n) { return n; }
#endif #endif
#if __BYTE_ORDER == __LITTLE_ENDIAN #if __BYTE_ORDER == __LITTLE_ENDIAN
static ZT_ALWAYS_INLINE uint8_t ntoh(uint8_t n) { return n; } static inline uint8_t ntoh(uint8_t n) { return n; }
static ZT_ALWAYS_INLINE int8_t ntoh(int8_t n) { return n; } static inline int8_t ntoh(int8_t n) { return n; }
static ZT_ALWAYS_INLINE uint16_t ntoh(uint16_t n) { return ntohs(n); } static inline uint16_t ntoh(uint16_t n) { return ntohs(n); }
static ZT_ALWAYS_INLINE int16_t ntoh(int16_t n) { return (int16_t)Utils::ntoh((uint16_t)n); } static inline int16_t ntoh(int16_t n) { return (int16_t)Utils::ntoh((uint16_t)n); }
static ZT_ALWAYS_INLINE uint32_t ntoh(uint32_t n) static inline uint32_t ntoh(uint32_t n)
{ {
#if defined(__GNUC__) #if defined(__GNUC__)
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
@ -346,8 +346,8 @@ static ZT_ALWAYS_INLINE uint32_t ntoh(uint32_t n)
return ntohl(n); return ntohl(n);
#endif #endif
} }
static ZT_ALWAYS_INLINE int32_t ntoh(int32_t n) { return (int32_t)Utils::ntoh((uint32_t)n); } static inline int32_t ntoh(int32_t n) { return (int32_t)Utils::ntoh((uint32_t)n); }
static ZT_ALWAYS_INLINE uint64_t ntoh(uint64_t n) static inline uint64_t ntoh(uint64_t n)
{ {
#if defined(__GNUC__) #if defined(__GNUC__)
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
@ -368,10 +368,10 @@ static ZT_ALWAYS_INLINE uint64_t ntoh(uint64_t n)
); );
#endif #endif
} }
static ZT_ALWAYS_INLINE int64_t ntoh(int64_t n) { return (int64_t)ntoh((uint64_t)n); } static inline int64_t ntoh(int64_t n) { return (int64_t)ntoh((uint64_t)n); }
#else #else
template<typename T> template<typename T>
static ZT_ALWAYS_INLINE T ntoh(T n) { return n; } static inline T ntoh(T n) { return n; }
#endif #endif
} // namespace Utils } // namespace Utils