فهرست منبع

Cleanup, warning removal, cppcheck informed cleanup.

Adam Ierymenko 6 سال پیش
والد
کامیت
d7a31088ba

+ 1 - 1
controller/DBMirrorSet.cpp

@@ -49,7 +49,7 @@ DBMirrorSet::DBMirrorSet(DB::ChangeListener *listener) :
 			}
 			}
 
 
 			for(auto db=dbs.begin();db!=dbs.end();++db) {
 			for(auto db=dbs.begin();db!=dbs.end();++db) {
-				(*db)->each([this,&dbs,&db](uint64_t networkId,const nlohmann::json &network,uint64_t memberId,const nlohmann::json &member) {
+				(*db)->each([&dbs,&db](uint64_t networkId,const nlohmann::json &network,uint64_t memberId,const nlohmann::json &member) {
 					try {
 					try {
 						if (network.is_object()) {
 						if (network.is_object()) {
 							if (memberId == 0) {
 							if (memberId == 0) {

+ 7 - 7
controller/EmbeddedNetworkController.cpp

@@ -42,8 +42,14 @@
 #include <thread>
 #include <thread>
 #include <memory>
 #include <memory>
 
 
+#include "../node/Constants.hpp"
+#include "../node/Node.hpp"
+#include "../node/CertificateOfMembership.hpp"
+#include "../node/NetworkConfig.hpp"
+#include "../node/Dictionary.hpp"
+#include "../node/MAC.hpp"
+
 #include "../include/ZeroTierOne.h"
 #include "../include/ZeroTierOne.h"
-#include "../version.h"
 
 
 #include "EmbeddedNetworkController.hpp"
 #include "EmbeddedNetworkController.hpp"
 #include "LFDB.hpp"
 #include "LFDB.hpp"
@@ -52,12 +58,6 @@
 #include "PostgreSQL.hpp"
 #include "PostgreSQL.hpp"
 #endif
 #endif
 
 
-#include "../node/Node.hpp"
-#include "../node/CertificateOfMembership.hpp"
-#include "../node/NetworkConfig.hpp"
-#include "../node/Dictionary.hpp"
-#include "../node/MAC.hpp"
-
 using json = nlohmann::json;
 using json = nlohmann::json;
 
 
 // API version reported via JSON control plane
 // API version reported via JSON control plane

+ 19 - 18
node/AES.hpp

@@ -124,8 +124,8 @@ private:
 		} sw;
 		} sw;
 	} _k;
 	} _k;
 
 
-#ifdef ZT_AES_AESNI
-	static inline __m128i _init256_1(__m128i a,__m128i b)
+#ifdef ZT_AES_AESNI /********************************************************/
+	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);
@@ -138,7 +138,7 @@ private:
 		x = _mm_xor_si128(x,b);
 		x = _mm_xor_si128(x,b);
 		return x;
 		return x;
 	}
 	}
-	static inline __m128i _init256_2(__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);
@@ -154,23 +154,25 @@ private:
 	}
 	}
 	inline void _init_aesni(const uint8_t key[32])
 	inline void _init_aesni(const uint8_t key[32])
 	{
 	{
+		/* Init AES itself */
 		__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);
 		_k.ni.k[1] = t2 = _mm_loadu_si128((const __m128i *)(key+16));
 		_k.ni.k[1] = t2 = _mm_loadu_si128((const __m128i *)(key+16));
-		_k.ni.k[2] = t1 = _init256_1(t1,_mm_aeskeygenassist_si128(t2,0x01));
-		_k.ni.k[3] = t2 = _init256_2(t1,t2);
-		_k.ni.k[4] = t1 = _init256_1(t1,_mm_aeskeygenassist_si128(t2,0x02));
-		_k.ni.k[5] = t2 = _init256_2(t1,t2);
-		_k.ni.k[6] = t1 = _init256_1(t1,_mm_aeskeygenassist_si128(t2,0x04));
-		_k.ni.k[7] = t2 = _init256_2(t1,t2);
-		_k.ni.k[8] = t1 = _init256_1(t1,_mm_aeskeygenassist_si128(t2,0x08));
-		_k.ni.k[9] = t2 = _init256_2(t1,t2);
-		_k.ni.k[10] = t1 = _init256_1(t1,_mm_aeskeygenassist_si128(t2,0x10));
-		_k.ni.k[11] = t2 = _init256_2(t1,t2);
-		_k.ni.k[12] = t1 = _init256_1(t1,_mm_aeskeygenassist_si128(t2,0x20));
-		_k.ni.k[13] = t2 = _init256_2(t1,t2);
-		_k.ni.k[14] = _init256_1(t1,_mm_aeskeygenassist_si128(t2,0x40));
+		_k.ni.k[2] = t1 = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x01));
+		_k.ni.k[3] = t2 = _init256_2_aesni(t1,t2);
+		_k.ni.k[4] = t1 = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x02));
+		_k.ni.k[5] = t2 = _init256_2_aesni(t1,t2);
+		_k.ni.k[6] = t1 = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x04));
+		_k.ni.k[7] = t2 = _init256_2_aesni(t1,t2);
+		_k.ni.k[8] = t1 = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x08));
+		_k.ni.k[9] = t2 = _init256_2_aesni(t1,t2);
+		_k.ni.k[10] = t1 = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x10));
+		_k.ni.k[11] = t2 = _init256_2_aesni(t1,t2);
+		_k.ni.k[12] = t1 = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x20));
+		_k.ni.k[13] = t2 = _init256_2_aesni(t1,t2);
+		_k.ni.k[14] = _init256_1_aesni(t1,_mm_aeskeygenassist_si128(t2,0x40));
 
 
+		/* Init GCM / GHASH */
 		__m128i h = _mm_xor_si128(_mm_setzero_si128(),_k.ni.k[0]);
 		__m128i h = _mm_xor_si128(_mm_setzero_si128(),_k.ni.k[0]);
 		h = _mm_aesenc_si128(h,_k.ni.k[1]);
 		h = _mm_aesenc_si128(h,_k.ni.k[1]);
 		h = _mm_aesenc_si128(h,_k.ni.k[2]);
 		h = _mm_aesenc_si128(h,_k.ni.k[2]);
@@ -357,7 +359,6 @@ private:
 		return x;
 		return x;
 	}
 	}
 	static inline void _htoun64_aesni(void *network,const uint64_t host) { *((uint64_t *)network) = Utils::hton(host); }
 	static inline void _htoun64_aesni(void *network,const uint64_t host) { *((uint64_t *)network) = Utils::hton(host); }
-	static inline void _htoun32_aesni(void *network,const uint64_t host) { *((uint32_t *)network) = Utils::hton(host); }
 
 
 	inline __m128i _create_j_aesni(const uint8_t *iv) const
 	inline __m128i _create_j_aesni(const uint8_t *iv) const
 	{
 	{
@@ -731,7 +732,7 @@ private:
 		y = _icv_tailer_aesni(y,alen,len);
 		y = _icv_tailer_aesni(y,alen,len);
 		_icv_crypt_aesni(y,j,icv,icvsize);
 		_icv_crypt_aesni(y,j,icv,icvsize);
 	}
 	}
-#endif
+#endif /* ZT_AES_AESNI ******************************************************/
 };
 };
 
 
 } // namespace ZeroTier
 } // namespace ZeroTier

+ 4 - 4
node/Address.hpp

@@ -46,15 +46,15 @@ namespace ZeroTier {
 class Address
 class Address
 {
 {
 public:
 public:
-	Address() : _a(0) {}
-	Address(const Address &a) : _a(a._a) {}
-	Address(uint64_t a) : _a(a & 0xffffffffffULL) {}
+	inline Address() : _a(0) {}
+	inline Address(const Address &a) : _a(a._a) {}
+	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
 	 */
 	 */
-	Address(const void *bits,unsigned int len) { setTo(bits,len); }
+	inline Address(const void *bits,unsigned int len) { setTo(bits,len); }
 
 
 	inline Address &operator=(const Address &a) { _a = a._a; return *this; }
 	inline Address &operator=(const Address &a) { _a = a._a; return *this; }
 	inline Address &operator=(const uint64_t a) { _a = (a & 0xffffffffffULL); return *this; }
 	inline Address &operator=(const uint64_t a) { _a = (a & 0xffffffffffULL); return *this; }

+ 2 - 2
node/AtomicCounter.hpp

@@ -41,7 +41,7 @@ namespace ZeroTier {
 class AtomicCounter
 class AtomicCounter
 {
 {
 public:
 public:
-	AtomicCounter() { _v = 0; }
+	inline AtomicCounter() { _v = 0; }
 
 
 	inline int load() const
 	inline int load() const
 	{
 	{
@@ -71,7 +71,7 @@ public:
 	}
 	}
 
 
 private:
 private:
-	AtomicCounter(const AtomicCounter &) {}
+	inline AtomicCounter(const AtomicCounter &) {}
 	const AtomicCounter &operator=(const AtomicCounter &) { return *this; }
 	const AtomicCounter &operator=(const AtomicCounter &) { return *this; }
 
 
 #ifdef __GNUC__
 #ifdef __GNUC__

+ 4 - 4
node/Buffer.hpp

@@ -87,12 +87,12 @@ public:
 	inline const_reverse_iterator rbegin() const { return const_reverse_iterator(begin()); }
 	inline const_reverse_iterator rbegin() const { return const_reverse_iterator(begin()); }
 	inline const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
 	inline const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
 
 
-	Buffer() :
+	inline Buffer() :
 		_l(0)
 		_l(0)
 	{
 	{
 	}
 	}
 
 
-	Buffer(unsigned int l)
+	inline Buffer(const unsigned int l)
 	{
 	{
 		if (l > C)
 		if (l > C)
 			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
 			throw ZT_EXCEPTION_OUT_OF_BOUNDS;
@@ -100,12 +100,12 @@ public:
 	}
 	}
 
 
 	template<unsigned int C2>
 	template<unsigned int C2>
-	Buffer(const Buffer<C2> &b)
+	inline Buffer(const Buffer<C2> &b)
 	{
 	{
 		*this = b;
 		*this = b;
 	}
 	}
 
 
-	Buffer(const void *b,unsigned int l)
+	inline Buffer(const void *b,unsigned int l)
 	{
 	{
 		copyFrom(b,l);
 		copyFrom(b,l);
 	}
 	}

+ 25 - 79
node/C25519.cpp

@@ -392,63 +392,36 @@ static inline void fcontract(u8 *output, limb *input_limbs) {
   s32 input[10];
   s32 input[10];
   s32 mask;
   s32 mask;
 
 
-  /* |input_limbs[i]| < 2^26, so it's valid to convert to an s32. */
   for (i = 0; i < 10; i++) {
   for (i = 0; i < 10; i++) {
     input[i] = input_limbs[i];
     input[i] = input_limbs[i];
   }
   }
-
   for (j = 0; j < 2; ++j) {
   for (j = 0; j < 2; ++j) {
     for (i = 0; i < 9; ++i) {
     for (i = 0; i < 9; ++i) {
       if ((i & 1) == 1) {
       if ((i & 1) == 1) {
-        /* This calculation is a time-invariant way to make input[i]
-         * non-negative by borrowing from the next-larger limb. */
-        const s32 mask = input[i] >> 31;
-        const s32 carry = -((input[i] & mask) >> 25);
+        const s32 mm = input[i] >> 31;
+        const s32 carry = -((input[i] & mm) >> 25);
         input[i] = input[i] + (carry << 25);
         input[i] = input[i] + (carry << 25);
         input[i+1] = input[i+1] - carry;
         input[i+1] = input[i+1] - carry;
       } else {
       } else {
-        const s32 mask = input[i] >> 31;
-        const s32 carry = -((input[i] & mask) >> 26);
+        const s32 mm = input[i] >> 31;
+        const s32 carry = -((input[i] & mm) >> 26);
         input[i] = input[i] + (carry << 26);
         input[i] = input[i] + (carry << 26);
         input[i+1] = input[i+1] - carry;
         input[i+1] = input[i+1] - carry;
       }
       }
     }
     }
-
-    /* There's no greater limb for input[9] to borrow from, but we can multiply
-     * by 19 and borrow from input[0], which is valid mod 2^255-19. */
     {
     {
-      const s32 mask = input[9] >> 31;
-      const s32 carry = -((input[9] & mask) >> 25);
+      const s32 mm = input[9] >> 31;
+      const s32 carry = -((input[9] & mm) >> 25);
       input[9] = input[9] + (carry << 25);
       input[9] = input[9] + (carry << 25);
       input[0] = input[0] - (carry * 19);
       input[0] = input[0] - (carry * 19);
     }
     }
-
-    /* After the first iteration, input[1..9] are non-negative and fit within
-     * 25 or 26 bits, depending on position. However, input[0] may be
-     * negative. */
   }
   }
-
-  /* The first borrow-propagation pass above ended with every limb
-     except (possibly) input[0] non-negative.
-
-     If input[0] was negative after the first pass, then it was because of a
-     carry from input[9]. On entry, input[9] < 2^26 so the carry was, at most,
-     one, since (2**26-1) >> 25 = 1. Thus input[0] >= -19.
-
-     In the second pass, each limb is decreased by at most one. Thus the second
-     borrow-propagation pass could only have wrapped around to decrease
-     input[0] again if the first pass left input[0] negative *and* input[1]
-     through input[9] were all zero.  In that case, input[1] is now 2^25 - 1,
-     and this last borrow-propagation step will leave input[1] non-negative. */
   {
   {
-    const s32 mask = input[0] >> 31;
-    const s32 carry = -((input[0] & mask) >> 26);
+    const s32 mm = input[0] >> 31;
+    const s32 carry = -((input[0] & mm) >> 26);
     input[0] = input[0] + (carry << 26);
     input[0] = input[0] + (carry << 26);
     input[1] = input[1] - carry;
     input[1] = input[1] - carry;
   }
   }
-
-  /* All input[i] are now non-negative. However, there might be values between
-   * 2^25 and 2^26 in a limb which is, nominally, 25 bits wide. */
   for (j = 0; j < 2; j++) {
   for (j = 0; j < 2; j++) {
     for (i = 0; i < 9; i++) {
     for (i = 0; i < 9; i++) {
       if ((i & 1) == 1) {
       if ((i & 1) == 1) {
@@ -461,24 +434,12 @@ static inline void fcontract(u8 *output, limb *input_limbs) {
         input[i+1] += carry;
         input[i+1] += carry;
       }
       }
     }
     }
-
     {
     {
       const s32 carry = input[9] >> 25;
       const s32 carry = input[9] >> 25;
       input[9] &= 0x1ffffff;
       input[9] &= 0x1ffffff;
       input[0] += 19*carry;
       input[0] += 19*carry;
     }
     }
   }
   }
-
-  /* If the first carry-chain pass, just above, ended up with a carry from
-   * input[9], and that caused input[0] to be out-of-bounds, then input[0] was
-   * < 2^26 + 2*19, because the carry was, at most, two.
-   *
-   * If the second pass carried from input[9] again then input[0] is < 2*19 and
-   * the input[9] -> input[0] carry didn't push input[0] out of bounds. */
-
-  /* It still remains the case that input might be between 2^255-19 and 2^255.
-   * In this case, input[1..9] must take their maximum value and input[0] must
-   * be >= (2^255-19) & 0x3ffffff, which is 0x3ffffed. */
   mask = s32_gte(input[0], 0x3ffffed);
   mask = s32_gte(input[0], 0x3ffffed);
   for (i = 1; i < 10; i++) {
   for (i = 1; i < 10; i++) {
     if ((i & 1) == 1) {
     if ((i & 1) == 1) {
@@ -487,11 +448,7 @@ static inline void fcontract(u8 *output, limb *input_limbs) {
       mask &= s32_eq(input[i], 0x3ffffff);
       mask &= s32_eq(input[i], 0x3ffffff);
     }
     }
   }
   }
-
-  /* mask is either 0xffffffff (if input >= 2^255-19) and zero otherwise. Thus
-   * this conditionally subtracts 2^255-19. */
   input[0] -= mask & 0x3ffffed;
   input[0] -= mask & 0x3ffffed;
-
   for (i = 1; i < 10; i++) {
   for (i = 1; i < 10; i++) {
     if ((i & 1) == 1) {
     if ((i & 1) == 1) {
       input[i] -= mask & 0x1ffffff;
       input[i] -= mask & 0x1ffffff;
@@ -834,12 +791,10 @@ static inline crypto_uint32 times38(crypto_uint32 a)
 
 
 static inline void reduce_add_sub(fe25519 *r)
 static inline void reduce_add_sub(fe25519 *r)
 {
 {
-	crypto_uint32 t;
 	int i,rep;
 	int i,rep;
-
 	for(rep=0;rep<4;rep++)
 	for(rep=0;rep<4;rep++)
 	{
 	{
-		t = r->v[31] >> 7;
+		crypto_uint32 t = r->v[31] >> 7;
 		r->v[31] &= 127;
 		r->v[31] &= 127;
 		t = times19(t);
 		t = times19(t);
 		r->v[0] += t;
 		r->v[0] += t;
@@ -854,12 +809,10 @@ static inline void reduce_add_sub(fe25519 *r)
 
 
 static inline void reduce_mul(fe25519 *r)
 static inline void reduce_mul(fe25519 *r)
 {
 {
-	crypto_uint32 t;
 	int i,rep;
 	int i,rep;
-
 	for(rep=0;rep<2;rep++)
 	for(rep=0;rep<2;rep++)
 	{
 	{
-		t = r->v[31] >> 7;
+		crypto_uint32 t = r->v[31] >> 7;
 		r->v[31] &= 127;
 		r->v[31] &= 127;
 		t = times19(t);
 		t = times19(t);
 		r->v[0] += t;
 		r->v[0] += t;
@@ -876,17 +829,17 @@ static inline void reduce_mul(fe25519 *r)
 static inline void fe25519_freeze(fe25519 *r)
 static inline void fe25519_freeze(fe25519 *r)
 {
 {
 	int i;
 	int i;
-	crypto_uint32 m = equal(r->v[31],127);
+	crypto_uint32 mm = equal(r->v[31],127);
 	for(i=30;i>0;i--)
 	for(i=30;i>0;i--)
-		m &= equal(r->v[i],255);
-	m &= ge(r->v[0],237);
+		mm &= equal(r->v[i],255);
+	mm &= ge(r->v[0],237);
 
 
-	m = -m;
+	mm = -mm;
 
 
-	r->v[31] -= m&127;
+	r->v[31] -= mm&127;
 	for(i=30;i>0;i--)
 	for(i=30;i>0;i--)
-		r->v[i] -= m&255;
-	r->v[0] -= m&237;
+		r->v[i] -= mm&255;
+	r->v[0] -= mm&237;
 }
 }
 
 
 static inline void fe25519_unpack(fe25519 *r, const unsigned char x[32])
 static inline void fe25519_unpack(fe25519 *r, const unsigned char x[32])
@@ -1157,9 +1110,7 @@ static inline void barrett_reduce(sc25519 *r, const crypto_uint32 x[64])
 	crypto_uint32 *q3 = q2 + 33;
 	crypto_uint32 *q3 = q2 + 33;
 	crypto_uint32 r1[33];
 	crypto_uint32 r1[33];
 	crypto_uint32 r2[33];
 	crypto_uint32 r2[33];
-	crypto_uint32 carry;
 	crypto_uint32 pb = 0;
 	crypto_uint32 pb = 0;
-	crypto_uint32 b;
 
 
 	for (i = 0;i < 66;++i) q2[i] = 0;
 	for (i = 0;i < 66;++i) q2[i] = 0;
 	for (i = 0;i < 33;++i) r2[i] = 0;
 	for (i = 0;i < 33;++i) r2[i] = 0;
@@ -1167,10 +1118,8 @@ static inline void barrett_reduce(sc25519 *r, const crypto_uint32 x[64])
 	for(i=0;i<33;i++)
 	for(i=0;i<33;i++)
 		for(j=0;j<33;j++)
 		for(j=0;j<33;j++)
 			if(i+j >= 31) q2[i+j] += mu[i]*x[j+31];
 			if(i+j >= 31) q2[i+j] += mu[i]*x[j+31];
-	carry = q2[31] >> 8;
-	q2[32] += carry;
-	carry = q2[32] >> 8;
-	q2[33] += carry;
+	q2[32] += (q2[31] >> 8);
+	q2[33] += (q2[32] >> 8);
 
 
 	for(i=0;i<33;i++)r1[i] = x[i];
 	for(i=0;i<33;i++)r1[i] = x[i];
 	for(i=0;i<32;i++)
 	for(i=0;i<32;i++)
@@ -1179,15 +1128,14 @@ static inline void barrett_reduce(sc25519 *r, const crypto_uint32 x[64])
 
 
 	for(i=0;i<32;i++)
 	for(i=0;i<32;i++)
 	{
 	{
-		carry = r2[i] >> 8;
-		r2[i+1] += carry;
+		r2[i+1] += (r2[i] >> 8);
 		r2[i] &= 0xff;
 		r2[i] &= 0xff;
 	}
 	}
 
 
 	for(i=0;i<32;i++)
 	for(i=0;i<32;i++)
 	{
 	{
 		pb += r2[i];
 		pb += r2[i];
-		b = lt(r1[i],pb);
+		crypto_uint32 b = lt(r1[i],pb);
 		r->v[i] = r1[i]-pb+(b<<8);
 		r->v[i] = r1[i]-pb+(b<<8);
 		pb = b;
 		pb = b;
 	}
 	}
@@ -1225,12 +1173,11 @@ static inline void sc25519_to32bytes(unsigned char r[32], const sc25519 *x)
 
 
 static inline void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y)
 static inline void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y)
 {
 {
-	int i, carry;
+	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];
 	for(i=0;i<31;i++)
 	for(i=0;i<31;i++)
 	{
 	{
-		carry = r->v[i] >> 8;
-		r->v[i+1] += carry;
+		r->v[i+1] += (r->v[i] >> 8);
 		r->v[i] &= 0xff;
 		r->v[i] &= 0xff;
 	}
 	}
 	reduce_add_sub(r);
 	reduce_add_sub(r);
@@ -1238,7 +1185,7 @@ static inline void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y)
 
 
 static inline void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
 static inline void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
 {
 {
-	int i,j,carry;
+	int i,j;
 	crypto_uint32 t[64];
 	crypto_uint32 t[64];
 	for(i=0;i<64;i++)t[i] = 0;
 	for(i=0;i<64;i++)t[i] = 0;
 
 
@@ -1248,8 +1195,7 @@ static inline void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
 
 
 	for(i=0;i<63;i++)
 	for(i=0;i<63;i++)
 	{
 	{
-		carry = t[i] >> 8;
-		t[i+1] += carry;
+		t[i+1] += (t[i] >> 8);
 		t[i] &= 0xff;
 		t[i] &= 0xff;
 	}
 	}
 
 

+ 2 - 2
node/Capability.hpp

@@ -72,7 +72,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; }
 
 
-	Capability() :
+	inline Capability() :
 		_nwid(0),
 		_nwid(0),
 		_ts(0),
 		_ts(0),
 		_id(0),
 		_id(0),
@@ -91,7 +91,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
 	 */
 	 */
-	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),

+ 3 - 3
node/CertificateOfMembership.hpp

@@ -112,7 +112,7 @@ public:
 	/**
 	/**
 	 * Create an empty certificate of membership
 	 * Create an empty certificate of membership
 	 */
 	 */
-	CertificateOfMembership() :
+	inline CertificateOfMembership() :
 		_qualifierCount(0),
 		_qualifierCount(0),
 		_signatureLength(0) {}
 		_signatureLength(0) {}
 
 
@@ -124,7 +124,7 @@ public:
 	 * @param nwid Network ID
 	 * @param nwid Network ID
 	 * @param issuedTo Certificate recipient
 	 * @param issuedTo Certificate recipient
 	 */
 	 */
-	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;
@@ -146,7 +146,7 @@ public:
 	 * @param startAt Position to start in buffer
 	 * @param startAt Position to start in buffer
 	 */
 	 */
 	template<unsigned int C>
 	template<unsigned int C>
-	CertificateOfMembership(const Buffer<C> &b,unsigned int startAt = 0)
+	inline CertificateOfMembership(const Buffer<C> &b,unsigned int startAt = 0)
 	{
 	{
 		deserialize(b,startAt);
 		deserialize(b,startAt);
 	}
 	}

+ 2 - 2
node/CertificateOfOwnership.hpp

@@ -67,12 +67,12 @@ public:
 		THING_IPV6_ADDRESS = 3
 		THING_IPV6_ADDRESS = 3
 	};
 	};
 
 
-	CertificateOfOwnership()
+	inline CertificateOfOwnership()
 	{
 	{
 		memset(reinterpret_cast<void *>(this),0,sizeof(CertificateOfOwnership));
 		memset(reinterpret_cast<void *>(this),0,sizeof(CertificateOfOwnership));
 	}
 	}
 
 
-	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;

+ 16 - 5
node/Constants.hpp

@@ -29,6 +29,22 @@
 
 
 #include "../include/ZeroTierOne.h"
 #include "../include/ZeroTierOne.h"
 
 
+#if __has_include("../version.h")
+#include "../version.h"
+#else /* dummy values for use inside IDEs, etc. */
+#define ZEROTIER_ONE_VERSION_MAJOR 255
+#define ZEROTIER_ONE_VERSION_MINOR 255
+#define ZEROTIER_ONE_VERSION_REVISION 255
+#define ZEROTIER_ONE_VERSION_BUILD 255
+#endif
+
+#ifndef ZT_BUILD_ARCHITECTURE
+#define ZT_BUILD_ARCHITECTURE 0
+#endif
+#ifndef ZT_BUILD_PLATFORM
+#define ZT_BUILD_PLATFORM 0
+#endif
+
 //
 //
 // This include file also auto-detects and canonicalizes some environment
 // This include file also auto-detects and canonicalizes some environment
 // information defines:
 // information defines:
@@ -603,11 +619,6 @@
  */
  */
 #define ZT_TRUST_EXPIRATION 600000
 #define ZT_TRUST_EXPIRATION 600000
 
 
-/**
- * Enable support for older network configurations from older (pre-1.1.6) controllers
- */
-#define ZT_SUPPORT_OLD_STYLE_NETCONF 1
-
 /**
 /**
  * Size of a buffer to store either a C25519 or an ECC P-384 signature
  * Size of a buffer to store either a C25519 or an ECC P-384 signature
  */
  */

+ 4 - 4
node/Dictionary.hpp

@@ -62,9 +62,9 @@ template<unsigned int C>
 class Dictionary
 class Dictionary
 {
 {
 public:
 public:
-	Dictionary() { memset(_d,0,sizeof(_d)); }
-	Dictionary(const char *s) { this->load(s); }
-	Dictionary(const char *s,unsigned int len)
+	inline Dictionary() { memset(_d,0,sizeof(_d)); }
+	inline Dictionary(const char *s) { this->load(s); }
+	inline Dictionary(const char *s,unsigned int len)
 	{
 	{
 		for(unsigned int i=0;i<C;++i) {
 		for(unsigned int i=0;i<C;++i) {
 			if ((s)&&(i < len)) {
 			if ((s)&&(i < len)) {
@@ -75,7 +75,7 @@ public:
 		}
 		}
 		_d[C - 1] = (char)0;
 		_d[C - 1] = (char)0;
 	}
 	}
-	Dictionary(const Dictionary &d) { memcpy(_d,d._d,C); }
+	inline Dictionary(const Dictionary &d) { memcpy(_d,d._d,C); }
 
 
 	inline Dictionary &operator=(const Dictionary &d)
 	inline Dictionary &operator=(const Dictionary &d)
 	{
 	{

+ 7 - 7
node/Hashtable.hpp

@@ -49,9 +49,9 @@ class Hashtable
 private:
 private:
 	struct _Bucket
 	struct _Bucket
 	{
 	{
-		_Bucket(const K &k,const V &v) : k(k),v(v) {}
-		_Bucket(const K &k) : k(k),v() {}
-		_Bucket(const _Bucket &b) : k(b.k),v(b.v) {}
+		inline _Bucket(const K &k,const V &v) : k(k),v(v) {}
+		inline _Bucket(const K &k) : k(k),v() {}
+		inline _Bucket(const _Bucket &b) : k(b.k),v(b.v) {}
 		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; }
 		K k;
 		K k;
 		V v;
 		V v;
@@ -72,7 +72,7 @@ public:
 		/**
 		/**
 		 * @param ht Hash table to iterate over
 		 * @param ht Hash table to iterate over
 		 */
 		 */
-		Iterator(Hashtable &ht) :
+		inline Iterator(Hashtable &ht) :
 			_idx(0),
 			_idx(0),
 			_ht(&ht),
 			_ht(&ht),
 			_b(ht._t[0])
 			_b(ht._t[0])
@@ -110,7 +110,7 @@ public:
 	/**
 	/**
 	 * @param bc Initial capacity in buckets (default: 64, must be nonzero)
 	 * @param bc Initial capacity in buckets (default: 64, must be nonzero)
 	 */
 	 */
-	Hashtable(unsigned long bc = 64) :
+	inline Hashtable(unsigned long bc = 64) :
 		_t(reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * bc))),
 		_t(reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * bc))),
 		_bc(bc),
 		_bc(bc),
 		_s(0)
 		_s(0)
@@ -121,7 +121,7 @@ public:
 			_t[i] = (_Bucket *)0;
 			_t[i] = (_Bucket *)0;
 	}
 	}
 
 
-	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)
@@ -141,7 +141,7 @@ public:
 		}
 		}
 	}
 	}
 
 
-	~Hashtable()
+	inline ~Hashtable()
 	{
 	{
 		this->clear();
 		this->clear();
 		::free(_t);
 		::free(_t);

+ 5 - 5
node/Identity.hpp

@@ -64,19 +64,19 @@ public:
 		P384 = ZT_CRYPTO_ALG_P384      // Type 1 -- NIST P-384 ECDH and ECDSA (2.0+ only)
 		P384 = ZT_CRYPTO_ALG_P384      // Type 1 -- NIST P-384 ECDH and ECDSA (2.0+ only)
 	};
 	};
 
 
-	Identity() { memset(reinterpret_cast<void *>(this),0,sizeof(Identity)); }
-	Identity(const Identity &id) { memcpy(reinterpret_cast<void *>(this),&id,sizeof(Identity)); }
+	inline Identity() { memset(reinterpret_cast<void *>(this),0,sizeof(Identity)); }
+	inline Identity(const Identity &id) { memcpy(reinterpret_cast<void *>(this),&id,sizeof(Identity)); }
 
 
-	Identity(const char *str)
+	inline Identity(const char *str)
 	{
 	{
 		if (!fromString(str))
 		if (!fromString(str))
 			throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE;
 			throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE;
 	}
 	}
 
 
 	template<unsigned int C>
 	template<unsigned int C>
-	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); }
 
 
-	~Identity() { Utils::burn(reinterpret_cast<void *>(this),sizeof(Identity)); }
+	inline ~Identity() { Utils::burn(reinterpret_cast<void *>(this),sizeof(Identity)); }
 
 
 	inline void zero() { Utils::burn(reinterpret_cast<void *>(this),sizeof(Identity)); }
 	inline void zero() { Utils::burn(reinterpret_cast<void *>(this),sizeof(Identity)); }
 
 

+ 0 - 1
node/IncomingPacket.cpp

@@ -30,7 +30,6 @@
 
 
 #include <list>
 #include <list>
 
 
-#include "../version.h"
 #include "../include/ZeroTierOne.h"
 #include "../include/ZeroTierOne.h"
 
 
 #include "Constants.hpp"
 #include "Constants.hpp"

+ 2 - 2
node/IncomingPacket.hpp

@@ -62,7 +62,7 @@ class Network;
 class IncomingPacket : public Packet
 class IncomingPacket : public Packet
 {
 {
 public:
 public:
-	IncomingPacket() :
+	inline IncomingPacket() :
 		Packet(),
 		Packet(),
 		_receiveTime(0)
 		_receiveTime(0)
 	{
 	{
@@ -77,7 +77,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
 	 */
 	 */
-	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)

+ 14 - 14
node/InetAddress.hpp

@@ -90,20 +90,20 @@ struct InetAddress : public sockaddr_storage
 		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(); }
 	};
 	};
 
 
-	InetAddress() { memset(this,0,sizeof(InetAddress)); }
-	InetAddress(const InetAddress &a) { memcpy(this,&a,sizeof(InetAddress)); }
-	InetAddress(const InetAddress *a) { memcpy(this,a,sizeof(InetAddress)); }
-	InetAddress(const struct sockaddr_storage &ss) { *this = ss; }
-	InetAddress(const struct sockaddr_storage *ss) { *this = ss; }
-	InetAddress(const struct sockaddr &sa) { *this = sa; }
-	InetAddress(const struct sockaddr *sa) { *this = sa; }
-	InetAddress(const struct sockaddr_in &sa) { *this = sa; }
-	InetAddress(const struct sockaddr_in *sa) { *this = sa; }
-	InetAddress(const struct sockaddr_in6 &sa) { *this = sa; }
-	InetAddress(const struct sockaddr_in6 *sa) { *this = sa; }
-	InetAddress(const void *ipBytes,unsigned int ipLen,unsigned int port) { this->set(ipBytes,ipLen,port); }
-	InetAddress(const uint32_t ipv4,unsigned int port) { this->set(&ipv4,4,port); }
-	InetAddress(const char *ipSlashPort) { this->fromString(ipSlashPort); }
+	inline InetAddress() { memset(this,0,sizeof(InetAddress)); }
+	inline InetAddress(const InetAddress &a) { memcpy(this,&a,sizeof(InetAddress)); }
+	inline InetAddress(const InetAddress *a) { memcpy(this,a,sizeof(InetAddress)); }
+	inline InetAddress(const struct sockaddr_storage &ss) { *this = ss; }
+	inline InetAddress(const struct sockaddr_storage *ss) { *this = ss; }
+	inline InetAddress(const struct sockaddr &sa) { *this = sa; }
+	inline InetAddress(const struct sockaddr *sa) { *this = sa; }
+	inline InetAddress(const struct sockaddr_in &sa) { *this = sa; }
+	inline InetAddress(const struct sockaddr_in *sa) { *this = sa; }
+	inline InetAddress(const struct sockaddr_in6 &sa) { *this = sa; }
+	inline InetAddress(const struct sockaddr_in6 *sa) { *this = sa; }
+	inline InetAddress(const void *ipBytes,unsigned int ipLen,unsigned int port) { this->set(ipBytes,ipLen,port); }
+	inline InetAddress(const uint32_t ipv4,unsigned int port) { this->set(&ipv4,4,port); }
+	inline InetAddress(const char *ipSlashPort) { this->fromString(ipSlashPort); }
 
 
 	inline InetAddress &operator=(const InetAddress &a)
 	inline InetAddress &operator=(const InetAddress &a)
 	{
 	{

+ 77 - 6
node/Locator.hpp

@@ -46,30 +46,51 @@ namespace ZeroTier {
 /**
 /**
  * Signed information about a node's location on the network
  * Signed information about a node's location on the network
  * 
  * 
- * A locator can be stored in DNS as a series of TXT records with a DNS name
- * that includes a public key that can be used to validate the locator's
- * signature. That way DNS records can't be spoofed even if no DNSSEC or
- * anything else is present to secure DNS.
+ * A locator is a signed record that contains information about where a node
+ * may be found. It can contain static physical addresses or virtual ZeroTier
+ * addresses of nodes that can forward to the target node. Locator records
+ * can be stored in signed DNS TXT record sets, in LF by roots, in caches,
+ * etc. Version 2.x nodes can sign their own locators. Roots can create
+ * signed locators using their own signature for version 1.x nodes. Locators
+ * signed by the node whose location they describe always take precedence
+ * over locators signed by other nodes.
  */
  */
 class Locator
 class Locator
 {
 {
 public:
 public:
-	Locator() : _signatureLength(0) {}
+	inline Locator() : _signatureLength(0) {}
+
+	inline const Identity &id() const { return _id; }
+	inline const Identity &signer() const { return ((_signedBy) ? _signedBy : _id); }
 
 
 	inline const std::vector<InetAddress> &phy() const { return _physical; }
 	inline const std::vector<InetAddress> &phy() const { return _physical; }
 	inline const std::vector<Identity> &virt() const { return _virtual; }
 	inline const std::vector<Identity> &virt() const { return _virtual; }
 
 
+	/**
+	 * Add a physical address to this locator (call before finish() to build a new Locator)
+	 */
 	inline void add(const InetAddress &ip)
 	inline void add(const InetAddress &ip)
 	{
 	{
 		if (_physical.size() < ZT_LOCATOR_MAX_PHYSICAL_ADDRESSES)
 		if (_physical.size() < ZT_LOCATOR_MAX_PHYSICAL_ADDRESSES)
 			_physical.push_back(ip);
 			_physical.push_back(ip);
 	}
 	}
+
+	/**
+	 * Add a forwarding ZeroTier node to this locator (call before finish() to build a new Locator)
+	 */
 	inline void add(const Identity &zt)
 	inline void add(const Identity &zt)
 	{
 	{
 		if (_virtual.size() < ZT_LOCATOR_MAX_VIRTUAL_ADDRESSES)
 		if (_virtual.size() < ZT_LOCATOR_MAX_VIRTUAL_ADDRESSES)
 			_virtual.push_back(zt);
 			_virtual.push_back(zt);
 	}
 	}
 
 
+	/**
+	 * Method to be called after add() is called for each address or forwarding node
+	 * 
+	 * This sets timestamp and ID information and sorts and deduplicates target
+	 * lists but does not sign the locator. The sign() method should be used after
+	 * finish().
+	 */
 	inline void finish(const Identity &id,const int64_t ts)
 	inline void finish(const Identity &id,const int64_t ts)
 	{
 	{
 		_ts = ts;
 		_ts = ts;
@@ -80,6 +101,9 @@ public:
 		_virtual.erase(std::unique(_virtual.begin(),_virtual.end()),_virtual.end());
 		_virtual.erase(std::unique(_virtual.begin(),_virtual.end()),_virtual.end());
 	}
 	}
 
 
+	/**
+	 * Sign this locator (must be called after finish())
+	 */
 	inline bool sign(const Identity &signingId)
 	inline bool sign(const Identity &signingId)
 	{
 	{
 		if (!signingId.hasPrivate())
 		if (!signingId.hasPrivate())
@@ -101,6 +125,9 @@ public:
 		}
 		}
 	}
 	}
 
 
+	/**
+	 * Verify this locator's signature against its embedded signing identity
+	 */
 	inline bool verify() const
 	inline bool verify() const
 	{
 	{
 		if ((_signatureLength == 0)||(_signatureLength > sizeof(_signature)))
 		if ((_signatureLength == 0)||(_signatureLength > sizeof(_signature)))
@@ -118,6 +145,18 @@ public:
 		}
 		}
 	}
 	}
 
 
+	/**
+	 * 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 p384SigningKeyPublic[ZT_ECC384_PUBLIC_KEY_SIZE],const uint8_t p384SigningKeyPrivate[ZT_ECC384_PUBLIC_KEY_SIZE])
 	inline std::vector<Str> makeTxtRecords(const uint8_t p384SigningKeyPublic[ZT_ECC384_PUBLIC_KEY_SIZE],const uint8_t p384SigningKeyPrivate[ZT_ECC384_PUBLIC_KEY_SIZE])
 	{
 	{
 		uint8_t s384[48],dnsSig[ZT_ECC384_SIGNATURE_SIZE];
 		uint8_t s384[48],dnsSig[ZT_ECC384_SIGNATURE_SIZE];
@@ -144,6 +183,19 @@ public:
 		return txtRecords;
 		return txtRecords;
 	}
 	}
 
 
+	/**
+	 * Decode TXT records
+	 * 
+	 * The supplied TXT records must be sorted in ascending natural sort order prior
+	 * to calling this method. The iterators supplied must be read iterators that
+	 * point to string objects supporting the c_str() method, which can be Str or
+	 * std::string.
+	 * 
+	 * 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.
+	 */
 	template<typename I>
 	template<typename I>
 	inline bool decodeTxtRecords(I start,I end,const uint8_t p384SigningKeyPublic[ZT_ECC384_PUBLIC_KEY_SIZE])
 	inline bool decodeTxtRecords(I start,I end,const uint8_t p384SigningKeyPublic[ZT_ECC384_PUBLIC_KEY_SIZE])
 	{
 	{
@@ -215,7 +267,7 @@ public:
 		_ts = (int64_t)b.template at<uint64_t>(p); p += 8;
 		_ts = (int64_t)b.template at<uint64_t>(p); p += 8;
 		p += _id.deserialize(b,p);
 		p += _id.deserialize(b,p);
 		const unsigned int signerCount = b[p++];
 		const unsigned int signerCount = b[p++];
-		if (signerCount > 1)
+		if (signerCount > 1) /* only one third party signer is currently supported */
 			throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW;
 			throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW;
 		if (signerCount == 1) {
 		if (signerCount == 1) {
 			p += _signedBy.deserialize(b,p);
 			p += _signedBy.deserialize(b,p);
@@ -242,6 +294,25 @@ public:
 		return (p - startAt);
 		return (p - startAt);
 	}
 	}
 
 
+	inline operator bool() const { return (_id); }
+
+	inline bool operator==(const Locator &l) const { return ((_ts == l._ts)&&(_id == l._id)&&(_signedBy == l._signedBy)&&(_physical == l._physical)&&(_virtual == l._virtual)&&(_signatureLength == l._signatureLength)&&(memcmp(_signature,l._signature,_signatureLength) == 0)); }
+	inline bool operator!=(const Locator &l) const { return (!(*this == l)); }
+	inline bool operator<(const Locator &l) const
+	{
+		if (_id < l._id) return true;
+		if (_ts < l._ts) return true;
+		if (_signedBy < l._signedBy) return true;
+		if (_physical < l._physical) return true;
+		if (_virtual < l._virtual) return true;
+		return false;
+	}
+	inline bool operator>(const Locator &l) const { return (l < *this); }
+	inline bool operator<=(const Locator &l) const { return (!(l < *this)); }
+	inline bool operator>=(const Locator &l) const { return (!(*this < l)); }
+
+	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;

+ 6 - 6
node/MAC.hpp

@@ -44,19 +44,19 @@ namespace ZeroTier {
 class MAC
 class MAC
 {
 {
 public:
 public:
-	MAC() : _m(0ULL) {}
-	MAC(const MAC &m) : _m(m._m) {}
+	inline MAC() : _m(0ULL) {}
+	inline MAC(const MAC &m) : _m(m._m) {}
 
 
-	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) ) {}
-	MAC(const void *bits,unsigned int len) { setTo(bits,len); }
-	MAC(const Address &ztaddr,uint64_t nwid) { fromAddress(ztaddr,nwid); }
-	MAC(const uint64_t m) : _m(m & 0xffffffffffffULL) {}
+	inline MAC(const void *bits,unsigned int len) { setTo(bits,len); }
+	inline MAC(const Address &ztaddr,uint64_t nwid) { fromAddress(ztaddr,nwid); }
+	inline MAC(const uint64_t m) : _m(m & 0xffffffffffffULL) {}
 
 
 	/**
 	/**
 	 * @return MAC in 64-bit integer
 	 * @return MAC in 64-bit integer

+ 2 - 2
node/MulticastGroup.hpp

@@ -53,13 +53,13 @@ namespace ZeroTier {
 class MulticastGroup
 class MulticastGroup
 {
 {
 public:
 public:
-	MulticastGroup() :
+	inline MulticastGroup() :
 		_mac(),
 		_mac(),
 		_adi(0)
 		_adi(0)
 	{
 	{
 	}
 	}
 
 
-	MulticastGroup(const MAC &m,uint32_t a) :
+	inline MulticastGroup(const MAC &m,uint32_t a) :
 		_mac(m),
 		_mac(m),
 		_adi(a)
 		_adi(a)
 	{
 	{

+ 17 - 31
node/Mutex.hpp

@@ -43,7 +43,7 @@ namespace ZeroTier {
 class Mutex
 class Mutex
 {
 {
 public:
 public:
-	Mutex() :
+	inline Mutex() :
 		nextTicket(0),
 		nextTicket(0),
 		nowServing(0)
 		nowServing(0)
 	{
 	{
@@ -69,29 +69,15 @@ public:
 	class Lock
 	class Lock
 	{
 	{
 	public:
 	public:
-		Lock(Mutex &m) :
-			_m(&m)
-		{
-			m.lock();
-		}
-
-		Lock(const Mutex &m) :
-			_m(const_cast<Mutex *>(&m))
-		{
-			_m->lock();
-		}
-
-		~Lock()
-		{
-			_m->unlock();
-		}
-
+		inline Lock(Mutex &m) : _m(&m) { m.lock(); }
+		inline Lock(const Mutex &m) : _m(const_cast<Mutex *>(&m)) { _m->lock(); }
+		inline ~Lock() { _m->unlock(); }
 	private:
 	private:
 		Mutex *const _m;
 		Mutex *const _m;
 	};
 	};
 
 
 private:
 private:
-	Mutex(const Mutex &) {}
+	inline Mutex(const Mutex &) {}
 	const Mutex &operator=(const Mutex &) { return *this; }
 	const Mutex &operator=(const Mutex &) { return *this; }
 
 
 	uint16_t nextTicket;
 	uint16_t nextTicket;
@@ -104,12 +90,12 @@ private:
 class Mutex
 class Mutex
 {
 {
 public:
 public:
-	Mutex()
+	inline Mutex()
 	{
 	{
 		pthread_mutex_init(&_mh,(const pthread_mutexattr_t *)0);
 		pthread_mutex_init(&_mh,(const pthread_mutexattr_t *)0);
 	}
 	}
 
 
-	~Mutex()
+	inline ~Mutex()
 	{
 	{
 		pthread_mutex_destroy(&_mh);
 		pthread_mutex_destroy(&_mh);
 	}
 	}
@@ -127,19 +113,19 @@ public:
 	class Lock
 	class Lock
 	{
 	{
 	public:
 	public:
-		Lock(Mutex &m) :
+		inline Lock(Mutex &m) :
 			_m(&m)
 			_m(&m)
 		{
 		{
 			m.lock();
 			m.lock();
 		}
 		}
 
 
-		Lock(const Mutex &m) :
+		inline Lock(const Mutex &m) :
 			_m(const_cast<Mutex *>(&m))
 			_m(const_cast<Mutex *>(&m))
 		{
 		{
 			_m->lock();
 			_m->lock();
 		}
 		}
 
 
-		~Lock()
+		inline ~Lock()
 		{
 		{
 			_m->unlock();
 			_m->unlock();
 		}
 		}
@@ -149,7 +135,7 @@ public:
 	};
 	};
 
 
 private:
 private:
-	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;
@@ -172,12 +158,12 @@ namespace ZeroTier {
 class Mutex
 class Mutex
 {
 {
 public:
 public:
-	Mutex()
+	inline Mutex()
 	{
 	{
 		InitializeCriticalSection(&_cs);
 		InitializeCriticalSection(&_cs);
 	}
 	}
 
 
-	~Mutex()
+	inline ~Mutex()
 	{
 	{
 		DeleteCriticalSection(&_cs);
 		DeleteCriticalSection(&_cs);
 	}
 	}
@@ -205,19 +191,19 @@ public:
 	class Lock
 	class Lock
 	{
 	{
 	public:
 	public:
-		Lock(Mutex &m) :
+		inline Lock(Mutex &m) :
 			_m(&m)
 			_m(&m)
 		{
 		{
 			m.lock();
 			m.lock();
 		}
 		}
 
 
-		Lock(const Mutex &m) :
+		inline Lock(const Mutex &m) :
 			_m(const_cast<Mutex *>(&m))
 			_m(const_cast<Mutex *>(&m))
 		{
 		{
 			_m->lock();
 			_m->lock();
 		}
 		}
 
 
-		~Lock()
+		inline ~Lock()
 		{
 		{
 			_m->unlock();
 			_m->unlock();
 		}
 		}
@@ -227,7 +213,7 @@ public:
 	};
 	};
 
 
 private:
 private:
-	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;

+ 0 - 1
node/Network.cpp

@@ -32,7 +32,6 @@
 #include "../include/ZeroTierDebug.h"
 #include "../include/ZeroTierDebug.h"
 
 
 #include "Constants.hpp"
 #include "Constants.hpp"
-#include "../version.h"
 #include "Network.hpp"
 #include "Network.hpp"
 #include "RuntimeEnvironment.hpp"
 #include "RuntimeEnvironment.hpp"
 #include "MAC.hpp"
 #include "MAC.hpp"

+ 1 - 133
node/NetworkConfig.cpp

@@ -56,77 +56,6 @@ bool NetworkConfig::toDictionary(Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d,b
 		if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_NAME,this->name)) return false;
 		if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_NAME,this->name)) return false;
 		if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_MTU,(uint64_t)this->mtu)) return false;
 		if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_MTU,(uint64_t)this->mtu)) return false;
 
 
-#ifdef ZT_SUPPORT_OLD_STYLE_NETCONF
-		if (includeLegacy) {
-			if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ENABLE_BROADCAST_OLD,this->enableBroadcast())) return false;
-			if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_PRIVATE_OLD,this->isPrivate())) return false;
-
-			std::string v4s;
-			for(unsigned int i=0;i<staticIpCount;++i) {
-				if (this->staticIps[i].ss_family == AF_INET) {
-					if (v4s.length() > 0)
-						v4s.push_back(',');
-					char buf[64];
-					v4s.append(this->staticIps[i].toString(buf));
-				}
-			}
-			if (v4s.length() > 0) {
-				if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_IPV4_STATIC_OLD,v4s.c_str())) return false;
-			}
-			std::string v6s;
-			for(unsigned int i=0;i<staticIpCount;++i) {
-				if (this->staticIps[i].ss_family == AF_INET6) {
-					if (v6s.length() > 0)
-						v6s.push_back(',');
-					char buf[64];
-					v6s.append(this->staticIps[i].toString(buf));
-				}
-			}
-			if (v6s.length() > 0) {
-				if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_IPV6_STATIC_OLD,v6s.c_str())) return false;
-			}
-
-			std::string ets;
-			unsigned int et = 0;
-			ZT_VirtualNetworkRuleType lastrt = ZT_NETWORK_RULE_ACTION_ACCEPT;
-			for(unsigned int i=0;i<ruleCount;++i) {
-				ZT_VirtualNetworkRuleType rt = (ZT_VirtualNetworkRuleType)(rules[i].t & 0x7f);
-				if (rt == ZT_NETWORK_RULE_MATCH_ETHERTYPE) {
-					et = rules[i].v.etherType;
-				} else if (rt == ZT_NETWORK_RULE_ACTION_ACCEPT) {
-					if (((int)lastrt < 32)||(lastrt == ZT_NETWORK_RULE_MATCH_ETHERTYPE)) {
-						if (ets.length() > 0)
-							ets.push_back(',');
-						char tmp2[16];
-						ets.append(Utils::hex((uint16_t)et,tmp2));
-					}
-					et = 0;
-				}
-				lastrt = rt;
-			}
-			if (ets.length() > 0) {
-				if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ALLOWED_ETHERNET_TYPES_OLD,ets.c_str())) return false;
-			}
-
-			if (this->com) {
-				if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATE_OF_MEMBERSHIP_OLD,this->com.toString().c_str())) return false;
-			}
-
-			std::string ab;
-			for(unsigned int i=0;i<this->specialistCount;++i) {
-				if ((this->specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE) != 0) {
-					if (ab.length() > 0)
-						ab.push_back(',');
-					char tmp2[16];
-					ab.append(Address(this->specialists[i]).toString(tmp2));
-				}
-			}
-			if (ab.length() > 0) {
-				if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ACTIVE_BRIDGES_OLD,ab.c_str())) return false;
-			}
-		}
-#endif // ZT_SUPPORT_OLD_STYLE_NETCONF
-
 		// Then add binary blobs
 		// Then add binary blobs
 
 
 		if (this->com) {
 		if (this->com) {
@@ -201,7 +130,7 @@ bool NetworkConfig::toDictionary(Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d,b
 bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d)
 bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d)
 {
 {
 	static const NetworkConfig NIL_NC;
 	static const NetworkConfig NIL_NC;
-	Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY> *tmp = new Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY>();
+	Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY> *const tmp = new Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY>();
 
 
 	try {
 	try {
 		*this = NIL_NC;
 		*this = NIL_NC;
@@ -232,65 +161,8 @@ bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACI
 			this->mtu = ZT_MAX_MTU;
 			this->mtu = ZT_MAX_MTU;
 
 
 		if (d.getUI(ZT_NETWORKCONFIG_DICT_KEY_VERSION,0) < 6) {
 		if (d.getUI(ZT_NETWORKCONFIG_DICT_KEY_VERSION,0) < 6) {
-	#ifdef ZT_SUPPORT_OLD_STYLE_NETCONF
-			char tmp2[1024];
-
-			// Decode legacy fields if version is old
-			if (d.getB(ZT_NETWORKCONFIG_DICT_KEY_ENABLE_BROADCAST_OLD))
-				this->flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_BROADCAST;
-			this->flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION; // always enable for old-style netconf
-			this->type = (d.getB(ZT_NETWORKCONFIG_DICT_KEY_PRIVATE_OLD,true)) ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC;
-
-			if (d.get(ZT_NETWORKCONFIG_DICT_KEY_IPV4_STATIC_OLD,tmp2,sizeof(tmp2)) > 0) {
-				char *saveptr = (char *)0;
-				for(char *f=Utils::stok(tmp2,",",&saveptr);(f);f=Utils::stok((char *)0,",",&saveptr)) {
-					if (this->staticIpCount >= ZT_MAX_ZT_ASSIGNED_ADDRESSES) break;
-					InetAddress ip(f);
-					if (!ip.isNetwork())
-						this->staticIps[this->staticIpCount++] = ip;
-				}
-			}
-			if (d.get(ZT_NETWORKCONFIG_DICT_KEY_IPV6_STATIC_OLD,tmp2,sizeof(tmp2)) > 0) {
-				char *saveptr = (char *)0;
-				for(char *f=Utils::stok(tmp2,",",&saveptr);(f);f=Utils::stok((char *)0,",",&saveptr)) {
-					if (this->staticIpCount >= ZT_MAX_ZT_ASSIGNED_ADDRESSES) break;
-					InetAddress ip(f);
-					if (!ip.isNetwork())
-						this->staticIps[this->staticIpCount++] = ip;
-				}
-			}
-
-			if (d.get(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATE_OF_MEMBERSHIP_OLD,tmp2,sizeof(tmp2)) > 0) {
-				this->com.fromString(tmp2);
-			}
-
-			if (d.get(ZT_NETWORKCONFIG_DICT_KEY_ALLOWED_ETHERNET_TYPES_OLD,tmp2,sizeof(tmp2)) > 0) {
-				char *saveptr = (char *)0;
-				for(char *f=Utils::stok(tmp2,",",&saveptr);(f);f=Utils::stok((char *)0,",",&saveptr)) {
-					unsigned int et = Utils::hexStrToUInt(f) & 0xffff;
-					if ((this->ruleCount + 2) > ZT_MAX_NETWORK_RULES) break;
-					if (et > 0) {
-						this->rules[this->ruleCount].t = (uint8_t)ZT_NETWORK_RULE_MATCH_ETHERTYPE;
-						this->rules[this->ruleCount].v.etherType = (uint16_t)et;
-						++this->ruleCount;
-					}
-					this->rules[this->ruleCount++].t = (uint8_t)ZT_NETWORK_RULE_ACTION_ACCEPT;
-				}
-			} else {
-				this->rules[0].t = ZT_NETWORK_RULE_ACTION_ACCEPT;
-				this->ruleCount = 1;
-			}
-
-			if (d.get(ZT_NETWORKCONFIG_DICT_KEY_ACTIVE_BRIDGES_OLD,tmp2,sizeof(tmp2)) > 0) {
-				char *saveptr = (char *)0;
-				for(char *f=Utils::stok(tmp2,",",&saveptr);(f);f=Utils::stok((char *)0,",",&saveptr)) {
-					this->addSpecialist(Address(Utils::hexStrToU64(f)),ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE);
-				}
-			}
-	#else
 			delete tmp;
 			delete tmp;
 			return false;
 			return false;
-	#endif // ZT_SUPPORT_OLD_STYLE_NETCONF
 		} else {
 		} else {
 			// Otherwise we can use the new fields
 			// Otherwise we can use the new fields
 			this->flags = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_FLAGS,0);
 			this->flags = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_FLAGS,0);
@@ -369,10 +241,6 @@ bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACI
 			}
 			}
 		}
 		}
 
 
-		//printf("~~~\n%s\n~~~\n",d.data());
-		//dump();
-		//printf("~~~\n");
-
 		delete tmp;
 		delete tmp;
 		return true;
 		return true;
 	} catch ( ... ) {
 	} catch ( ... ) {

+ 1 - 1
node/NetworkConfig.hpp

@@ -216,7 +216,7 @@ namespace ZeroTier {
 class NetworkConfig
 class NetworkConfig
 {
 {
 public:
 public:
-	NetworkConfig() :
+	inline NetworkConfig() :
 		networkId(0),
 		networkId(0),
 		timestamp(0),
 		timestamp(0),
 		credentialTimeMaxDelta(0),
 		credentialTimeMaxDelta(0),

+ 0 - 7
node/Node.cpp

@@ -30,8 +30,6 @@
 #include <string.h>
 #include <string.h>
 #include <stdint.h>
 #include <stdint.h>
 
 
-#include "../version.h"
-
 #include "Constants.hpp"
 #include "Constants.hpp"
 #include "SharedPtr.hpp"
 #include "SharedPtr.hpp"
 #include "Node.hpp"
 #include "Node.hpp"
@@ -573,10 +571,6 @@ bool Node::shouldUsePathForZeroTierTraffic(void *tPtr,const Address &ztaddr,cons
 {
 {
 	if (!Path::isAddressValidForPath(remoteAddress))
 	if (!Path::isAddressValidForPath(remoteAddress))
 		return false;
 		return false;
-
-	if (RR->topology->isProhibitedEndpoint(ztaddr,remoteAddress))
-		return false;
-
 	{
 	{
 		Mutex::Lock _l(_networks_m);
 		Mutex::Lock _l(_networks_m);
 		Hashtable< uint64_t,SharedPtr<Network> >::Iterator i(_networks);
 		Hashtable< uint64_t,SharedPtr<Network> >::Iterator i(_networks);
@@ -591,7 +585,6 @@ bool Node::shouldUsePathForZeroTierTraffic(void *tPtr,const Address &ztaddr,cons
 			}
 			}
 		}
 		}
 	}
 	}
-
 	return ( (_cb.pathCheckFunction) ? (_cb.pathCheckFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ztaddr.toInt(),localSocket,reinterpret_cast<const struct sockaddr_storage *>(&remoteAddress)) != 0) : true);
 	return ( (_cb.pathCheckFunction) ? (_cb.pathCheckFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ztaddr.toInt(),localSocket,reinterpret_cast<const struct sockaddr_storage *>(&remoteAddress)) != 0) : true);
 }
 }
 
 

+ 1 - 1
node/OutboundMulticast.hpp

@@ -56,7 +56,7 @@ public:
 	 *
 	 *
 	 * It must be initialized with init().
 	 * It must be initialized with init().
 	 */
 	 */
-	OutboundMulticast() {}
+	inline OutboundMulticast() {}
 
 
 	/**
 	/**
 	 * Initialize outbound multicast
 	 * Initialize outbound multicast

+ 14 - 11
node/Packet.hpp

@@ -70,16 +70,19 @@
  * 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
- * 11 - 1.6.0 ... CURRENT
+ * 11 - 2.0.0 ... CURRENT
  *    + Peer-to-peer multicast replication (optional)
  *    + Peer-to-peer multicast replication (optional)
  *    + Old planet/moon stuff is DEAD!
  *    + Old planet/moon stuff is DEAD!
+ *    + AES256-GCM encryption is now the default
+ *    + NIST P-384 type identities now supported (25519 still default)
+ *    + Min proto version is now 8 (1.1.17 and newer)
  */
  */
 #define ZT_PROTO_VERSION 11
 #define ZT_PROTO_VERSION 11
 
 
 /**
 /**
  * Minimum supported protocol version
  * Minimum supported protocol version
  */
  */
-#define ZT_PROTO_VERSION_MIN 4
+#define ZT_PROTO_VERSION_MIN 8
 
 
 /**
 /**
  * Maximum hop count allowed by packet structure (3 bits, 0-7)
  * Maximum hop count allowed by packet structure (3 bits, 0-7)
@@ -406,18 +409,18 @@ public:
 	class Fragment : public Buffer<ZT_PROTO_MAX_PACKET_LENGTH>
 	class Fragment : public Buffer<ZT_PROTO_MAX_PACKET_LENGTH>
 	{
 	{
 	public:
 	public:
-		Fragment() :
+		inline Fragment() :
 			Buffer<ZT_PROTO_MAX_PACKET_LENGTH>()
 			Buffer<ZT_PROTO_MAX_PACKET_LENGTH>()
 		{
 		{
 		}
 		}
 
 
 		template<unsigned int C2>
 		template<unsigned int C2>
-		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)
 		{
 		{
 		}
 		}
 
 
-		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)
 		{
 		{
 		}
 		}
@@ -431,7 +434,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)
 		 */
 		 */
-		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);
 		}
 		}
@@ -1003,12 +1006,12 @@ public:
 	};
 	};
 
 
 	template<unsigned int C2>
 	template<unsigned int C2>
-	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)
 	{
 	{
 	}
 	}
 
 
-	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)
 	{
 	{
 	}
 	}
@@ -1020,7 +1023,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.
 	 */
 	 */
-	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)
 	{
 	{
 		Utils::getSecureRandom(field(ZT_PACKET_IDX_IV,8),8);
 		Utils::getSecureRandom(field(ZT_PACKET_IDX_IV,8),8);
@@ -1036,7 +1039,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
 	 */
 	 */
-	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)
 	{
 	{
 		Utils::getSecureRandom(field(ZT_PACKET_IDX_IV,8),8);
 		Utils::getSecureRandom(field(ZT_PACKET_IDX_IV,8),8);
@@ -1050,7 +1053,7 @@ public:
 	 * @param source Source ZT address
 	 * @param source Source ZT address
 	 * @param v Verb
 	 * @param v Verb
 	 */
 	 */
-	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)
 	{
 	{
 		Utils::getSecureRandom(field(ZT_PACKET_IDX_IV,8),8);
 		Utils::getSecureRandom(field(ZT_PACKET_IDX_IV,8),8);

+ 4 - 4
node/Path.hpp

@@ -68,9 +68,9 @@ public:
 	class HashKey
 	class HashKey
 	{
 	{
 	public:
 	public:
-		HashKey() {}
+		inline HashKey() {}
 
 
-		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;
@@ -94,7 +94,7 @@ public:
 		uint64_t _k[3];
 		uint64_t _k[3];
 	};
 	};
 
 
-	Path() :
+	inline Path() :
 		_lastOut(0),
 		_lastOut(0),
 		_lastIn(0),
 		_lastIn(0),
 		_lastTrustEstablishedPacketReceived(0),
 		_lastTrustEstablishedPacketReceived(0),
@@ -127,7 +127,7 @@ public:
 		memset(_addrString, 0, sizeof(_addrString));
 		memset(_addrString, 0, sizeof(_addrString));
 	}
 	}
 
 
-	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),
 		_lastTrustEstablishedPacketReceived(0),
 		_lastTrustEstablishedPacketReceived(0),

+ 0 - 1
node/Peer.cpp

@@ -24,7 +24,6 @@
  * of your own application.
  * of your own application.
  */
  */
 
 
-#include "../version.h"
 #include "Constants.hpp"
 #include "Constants.hpp"
 #include "Peer.hpp"
 #include "Peer.hpp"
 #include "Node.hpp"
 #include "Node.hpp"

+ 2 - 2
node/Peer.hpp

@@ -57,10 +57,10 @@ class Peer
 	friend class SharedPtr<Peer>;
 	friend class SharedPtr<Peer>;
 
 
 private:
 private:
-	Peer() {} // disabled to prevent bugs -- should not be constructed uninitialized
+	inline Peer() {} // disabled to prevent bugs -- should not be constructed uninitialized
 
 
 public:
 public:
-	~Peer() { Utils::burn(_key,sizeof(_key)); }
+	inline ~Peer() { Utils::burn(_key,sizeof(_key)); }
 
 
 	/**
 	/**
 	 * Construct a new peer
 	 * Construct a new peer

+ 8 - 11
node/Poly1305.cpp

@@ -25,7 +25,7 @@ typedef struct poly1305_context {
   unsigned char opaque[136];
   unsigned char opaque[136];
 } poly1305_context;
 } poly1305_context;
 
 
-#if (defined(_MSC_VER) || defined(__GNUC__)) && (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64))
+#if (defined(_MSC_VER) || defined(__GNUC__) || defined(__clang)) && (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64))
 
 
 //////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 // 128-bit implementation for MSC and GCC from Poly1305-donna
 // 128-bit implementation for MSC and GCC from Poly1305-donna
@@ -136,7 +136,6 @@ static inline void poly1305_blocks(poly1305_state_internal_t *st, const unsigned
   unsigned long long r0,r1,r2;
   unsigned long long r0,r1,r2;
   unsigned long long s1,s2;
   unsigned long long s1,s2;
   unsigned long long h0,h1,h2;
   unsigned long long h0,h1,h2;
-  unsigned long long c;
   uint128_t d0,d1,d2,d;
   uint128_t d0,d1,d2,d;
 
 
   r0 = st->r[0];
   r0 = st->r[0];
@@ -167,7 +166,7 @@ static inline void poly1305_blocks(poly1305_state_internal_t *st, const unsigned
     MUL(d2, h0, r2); MUL(d, h1, r1); ADD(d2, d); MUL(d, h2, r0); ADD(d2, d);
     MUL(d2, h0, r2); MUL(d, h1, r1); ADD(d2, d); MUL(d, h2, r0); ADD(d2, d);
 
 
     /* (partial) h %= p */
     /* (partial) h %= p */
-                  c = SHR(d0, 44); h0 = LO(d0) & 0xfffffffffff;
+    unsigned long long c = SHR(d0, 44); h0 = LO(d0) & 0xfffffffffff;
     ADDLO(d1, c); c = SHR(d1, 44); h1 = LO(d1) & 0xfffffffffff;
     ADDLO(d1, c); c = SHR(d1, 44); h1 = LO(d1) & 0xfffffffffff;
     ADDLO(d2, c); c = SHR(d2, 42); h2 = LO(d2) & 0x3ffffffffff;
     ADDLO(d2, c); c = SHR(d2, 42); h2 = LO(d2) & 0x3ffffffffff;
     h0  += c * 5; c = (h0 >> 44);  h0 =    h0  & 0xfffffffffff;
     h0  += c * 5; c = (h0 >> 44);  h0 =    h0  & 0xfffffffffff;
@@ -324,8 +323,6 @@ poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t by
   unsigned long r0,r1,r2,r3,r4;
   unsigned long r0,r1,r2,r3,r4;
   unsigned long s1,s2,s3,s4;
   unsigned long s1,s2,s3,s4;
   unsigned long h0,h1,h2,h3,h4;
   unsigned long h0,h1,h2,h3,h4;
-  unsigned long long d0,d1,d2,d3,d4;
-  unsigned long c;
 
 
   r0 = st->r[0];
   r0 = st->r[0];
   r1 = st->r[1];
   r1 = st->r[1];
@@ -353,14 +350,14 @@ poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t by
     h4 += (U8TO32(m+12) >> 8) | hibit;
     h4 += (U8TO32(m+12) >> 8) | hibit;
 
 
     /* h *= r */
     /* h *= r */
-    d0 = ((unsigned long long)h0 * r0) + ((unsigned long long)h1 * s4) + ((unsigned long long)h2 * s3) + ((unsigned long long)h3 * s2) + ((unsigned long long)h4 * s1);
-    d1 = ((unsigned long long)h0 * r1) + ((unsigned long long)h1 * r0) + ((unsigned long long)h2 * s4) + ((unsigned long long)h3 * s3) + ((unsigned long long)h4 * s2);
-    d2 = ((unsigned long long)h0 * r2) + ((unsigned long long)h1 * r1) + ((unsigned long long)h2 * r0) + ((unsigned long long)h3 * s4) + ((unsigned long long)h4 * s3);
-    d3 = ((unsigned long long)h0 * r3) + ((unsigned long long)h1 * r2) + ((unsigned long long)h2 * r1) + ((unsigned long long)h3 * r0) + ((unsigned long long)h4 * s4);
-    d4 = ((unsigned long long)h0 * r4) + ((unsigned long long)h1 * r3) + ((unsigned long long)h2 * r2) + ((unsigned long long)h3 * r1) + ((unsigned long long)h4 * r0);
+    unsigned long long d0 = ((unsigned long long)h0 * r0) + ((unsigned long long)h1 * s4) + ((unsigned long long)h2 * s3) + ((unsigned long long)h3 * s2) + ((unsigned long long)h4 * s1);
+    unsigned long long d1 = ((unsigned long long)h0 * r1) + ((unsigned long long)h1 * r0) + ((unsigned long long)h2 * s4) + ((unsigned long long)h3 * s3) + ((unsigned long long)h4 * s2);
+    unsigned long long d2 = ((unsigned long long)h0 * r2) + ((unsigned long long)h1 * r1) + ((unsigned long long)h2 * r0) + ((unsigned long long)h3 * s4) + ((unsigned long long)h4 * s3);
+    unsigned long long d3 = ((unsigned long long)h0 * r3) + ((unsigned long long)h1 * r2) + ((unsigned long long)h2 * r1) + ((unsigned long long)h3 * r0) + ((unsigned long long)h4 * s4);
+    unsigned long long d4 = ((unsigned long long)h0 * r4) + ((unsigned long long)h1 * r3) + ((unsigned long long)h2 * r2) + ((unsigned long long)h3 * r1) + ((unsigned long long)h4 * r0);
 
 
     /* (partial) h %= p */
     /* (partial) h %= p */
-                  c = (unsigned long)(d0 >> 26); h0 = (unsigned long)d0 & 0x3ffffff;
+    unsigned long c = (unsigned long)(d0 >> 26); h0 = (unsigned long)d0 & 0x3ffffff;
     d1 += c;      c = (unsigned long)(d1 >> 26); h1 = (unsigned long)d1 & 0x3ffffff;
     d1 += c;      c = (unsigned long)(d1 >> 26); h1 = (unsigned long)d1 & 0x3ffffff;
     d2 += c;      c = (unsigned long)(d2 >> 26); h2 = (unsigned long)d2 & 0x3ffffff;
     d2 += c;      c = (unsigned long)(d2 >> 26); h2 = (unsigned long)d2 & 0x3ffffff;
     d3 += c;      c = (unsigned long)(d3 >> 26); h3 = (unsigned long)d3 & 0x3ffffff;
     d3 += c;      c = (unsigned long)(d3 >> 26); h3 = (unsigned long)d3 & 0x3ffffff;

+ 3 - 6
node/Salsa20.hpp

@@ -31,8 +31,8 @@ namespace ZeroTier {
 class Salsa20
 class Salsa20
 {
 {
 public:
 public:
-	Salsa20() {}
-	~Salsa20() { Utils::burn(&_state,sizeof(_state)); }
+	inline Salsa20() {}
+	inline ~Salsa20() { Utils::burn(&_state,sizeof(_state)); }
 
 
 	/**
 	/**
 	 * XOR d with s
 	 * XOR d with s
@@ -114,10 +114,7 @@ public:
 	 * @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
 	 */
 	 */
-	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

+ 0 - 1
node/Switch.cpp

@@ -31,7 +31,6 @@
 #include <utility>
 #include <utility>
 #include <stdexcept>
 #include <stdexcept>
 
 
-#include "../version.h"
 #include "../include/ZeroTierOne.h"
 #include "../include/ZeroTierOne.h"
 
 
 #include "Constants.hpp"
 #include "Constants.hpp"

+ 2 - 2
node/Tag.hpp

@@ -65,7 +65,7 @@ class Tag : public Credential
 public:
 public:
 	static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_TAG; }
 	static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_TAG; }
 
 
-	Tag() :
+	inline Tag() :
 		_id(0),
 		_id(0),
 		_value(0),
 		_value(0),
 		_networkId(0),
 		_networkId(0),
@@ -81,7 +81,7 @@ public:
 	 * @param id Tag ID
 	 * @param id Tag ID
 	 * @param value Tag value
 	 * @param value Tag value
 	 */
 	 */
-	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),

+ 0 - 203
node/Topology.cpp

@@ -1,203 +0,0 @@
-/*
- * ZeroTier One - Network Virtualization Everywhere
- * Copyright (C) 2011-2019  ZeroTier, Inc.  https://www.zerotier.com/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * --
- *
- * You can be released from the requirements of the license by purchasing
- * a commercial license. Buying such a license is mandatory as soon as you
- * develop commercial closed-source software that incorporates or links
- * directly against ZeroTier software without disclosing the source code
- * of your own application.
- */
-
-#include "Constants.hpp"
-#include "Topology.hpp"
-#include "RuntimeEnvironment.hpp"
-#include "Node.hpp"
-#include "Network.hpp"
-#include "NetworkConfig.hpp"
-#include "Buffer.hpp"
-#include "Switch.hpp"
-
-namespace ZeroTier {
-
-Topology::Topology(const RuntimeEnvironment *renv,void *tPtr) :
-	RR(renv),
-	_numConfiguredPhysicalPaths(0)
-{
-}
-
-Topology::~Topology()
-{
-	Hashtable< Address,SharedPtr<Peer> >::Iterator i(_peers);
-	Address *a = (Address *)0;
-	SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
-	while (i.next(a,p))
-		_savePeer((void *)0,*p);
-}
-
-SharedPtr<Peer> Topology::addPeer(void *tPtr,const SharedPtr<Peer> &peer)
-{
-	SharedPtr<Peer> np;
-	{
-		Mutex::Lock _l(_peers_m);
-		SharedPtr<Peer> &hp = _peers[peer->address()];
-		if (!hp)
-			hp = peer;
-		np = hp;
-	}
-	return np;
-}
-
-SharedPtr<Peer> Topology::getPeer(void *tPtr,const Address &zta)
-{
-	if (zta == RR->identity.address())
-		return SharedPtr<Peer>();
-
-	{
-		Mutex::Lock _l(_peers_m);
-		const SharedPtr<Peer> *const ap = _peers.get(zta);
-		if (ap)
-			return *ap;
-	}
-
-	try {
-		Buffer<ZT_PEER_MAX_SERIALIZED_STATE_SIZE> buf;
-		uint64_t idbuf[2]; idbuf[0] = zta.toInt(); idbuf[1] = 0;
-		int len = RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_PEER,idbuf,buf.unsafeData(),ZT_PEER_MAX_SERIALIZED_STATE_SIZE);
-		if (len > 0) {
-			buf.setSize(len);
-			Mutex::Lock _l(_peers_m);
-			SharedPtr<Peer> &ap = _peers[zta];
-			if (ap)
-				return ap;
-			ap = Peer::deserializeFromCache(RR->node->now(),tPtr,buf,RR);
-			if (!ap) {
-				_peers.erase(zta);
-			}
-			return SharedPtr<Peer>();
-		}
-	} catch ( ... ) {} // ignore invalid identities or other strange failures
-
-	return SharedPtr<Peer>();
-}
-
-Identity Topology::getIdentity(void *tPtr,const Address &zta)
-{
-	if (zta == RR->identity.address()) {
-		return RR->identity;
-	} else {
-		Mutex::Lock _l(_peers_m);
-		const SharedPtr<Peer> *const ap = _peers.get(zta);
-		if (ap)
-			return (*ap)->identity();
-	}
-	return Identity();
-}
-
-SharedPtr<Peer> Topology::getUpstreamPeer()
-{
-	return SharedPtr<Peer>();
-}
-
-bool Topology::isUpstream(const Identity &id) const
-{
-	return false;
-}
-
-ZT_PeerRole Topology::role(const Address &ztaddr) const
-{
-	return ZT_PEER_ROLE_LEAF;
-}
-
-bool Topology::isProhibitedEndpoint(const Address &ztaddr,const InetAddress &ipaddr) const
-{
-	return false;
-}
-
-void Topology::doPeriodicTasks(void *tPtr,int64_t now)
-{
-	{
-		Mutex::Lock _l1(_peers_m);
-		Hashtable< Address,SharedPtr<Peer> >::Iterator i(_peers);
-		Address *a = (Address *)0;
-		SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
-		while (i.next(a,p)) {
-			if (!(*p)->isAlive(now)) {
-				_savePeer(tPtr,*p);
-				_peers.erase(*a);
-			}
-		}
-	}
-
-	{
-		Mutex::Lock _l(_paths_m);
-		Hashtable< Path::HashKey,SharedPtr<Path> >::Iterator i(_paths);
-		Path::HashKey *k = (Path::HashKey *)0;
-		SharedPtr<Path> *p = (SharedPtr<Path> *)0;
-		while (i.next(k,p)) {
-			if (p->references() <= 1)
-				_paths.erase(*k);
-		}
-	}
-}
-
-void Topology::setPhysicalPathConfiguration(const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig)
-{
-	if (!pathNetwork) {
-		_numConfiguredPhysicalPaths = 0;
-	} else {
-		std::map<InetAddress,ZT_PhysicalPathConfiguration> cpaths;
-		for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i)
-			cpaths[_physicalPathConfig[i].first] = _physicalPathConfig[i].second;
-
-		if (pathConfig) {
-			ZT_PhysicalPathConfiguration pc(*pathConfig);
-
-			if (pc.mtu <= 0)
-				pc.mtu = ZT_DEFAULT_PHYSMTU;
-			else if (pc.mtu < ZT_MIN_PHYSMTU)
-				pc.mtu = ZT_MIN_PHYSMTU;
-			else if (pc.mtu > ZT_MAX_PHYSMTU)
-				pc.mtu = ZT_MAX_PHYSMTU;
-
-			cpaths[*(reinterpret_cast<const InetAddress *>(pathNetwork))] = pc;
-		} else {
-			cpaths.erase(*(reinterpret_cast<const InetAddress *>(pathNetwork)));
-		}
-
-		unsigned int cnt = 0;
-		for(std::map<InetAddress,ZT_PhysicalPathConfiguration>::const_iterator i(cpaths.begin());((i!=cpaths.end())&&(cnt<ZT_MAX_CONFIGURABLE_PATHS));++i) {
-			_physicalPathConfig[cnt].first = i->first;
-			_physicalPathConfig[cnt].second = i->second;
-			++cnt;
-		}
-		_numConfiguredPhysicalPaths = cnt;
-	}
-}
-
-void Topology::_savePeer(void *tPtr,const SharedPtr<Peer> &peer)
-{
-	try {
-		Buffer<ZT_PEER_MAX_SERIALIZED_STATE_SIZE> buf;
-		peer->serializeForCache(buf);
-		uint64_t tmpid[2]; tmpid[0] = peer->address().toInt(); tmpid[1] = 0;
-		RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_PEER,tmpid,buf.data(),buf.size());
-	} catch ( ... ) {} // sanity check, discard invalid entries
-}
-
-} // namespace ZeroTier

+ 112 - 47
node/Topology.hpp

@@ -56,8 +56,10 @@ class RuntimeEnvironment;
 class Topology
 class Topology
 {
 {
 public:
 public:
-	Topology(const RuntimeEnvironment *renv,void *tPtr);
-	~Topology();
+	inline Topology(const RuntimeEnvironment *renv,void *tPtr) :
+		RR(renv),
+		_numConfiguredPhysicalPaths(0) {}
+	inline ~Topology() {}
 
 
 	/**
 	/**
 	 * Add a peer to database
 	 * Add a peer to database
@@ -69,7 +71,18 @@ 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')
 	 */
 	 */
-	SharedPtr<Peer> addPeer(void *tPtr,const SharedPtr<Peer> &peer);
+	inline SharedPtr<Peer> addPeer(void *tPtr,const SharedPtr<Peer> &peer)
+	{
+		SharedPtr<Peer> np;
+		{
+			Mutex::Lock _l(_peers_m);
+			SharedPtr<Peer> &hp = _peers[peer->address()];
+			if (!hp)
+				hp = peer;
+			np = hp;
+		}
+		return np;
+	}
 
 
 	/**
 	/**
 	 * Get a peer from its address
 	 * Get a peer from its address
@@ -78,15 +91,37 @@ 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
 	 */
 	 */
-	SharedPtr<Peer> getPeer(void *tPtr,const Address &zta);
+	inline SharedPtr<Peer> getPeer(void *tPtr,const Address &zta) const
+	{
+		if (zta == RR->identity.address())
+			return SharedPtr<Peer>();
+		{
+			Mutex::Lock _l(_peers_m);
+			const SharedPtr<Peer> *const ap = _peers.get(zta);
+			if (ap)
+				return *ap;
+		}
+		return SharedPtr<Peer>();
+	}
 
 
 	/**
 	/**
 	 * @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 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
 	 */
 	 */
-	Identity getIdentity(void *tPtr,const Address &zta);
-
+	inline Identity getIdentity(void *tPtr,const Address &zta)
+	{
+		if (zta == RR->identity.address()) {
+			return RR->identity;
+		} else {
+			Mutex::Lock _l(_peers_m);
+			const SharedPtr<Peer> *const ap = _peers.get(zta);
+			if (ap)
+				return (*ap)->identity();
+		}
+		return Identity();
+	}
+	
 	/**
 	/**
 	 * Get a peer only if it is presently in memory (no disk cache)
 	 * Get a peer only if it is presently in memory (no disk cache)
 	 *
 	 *
@@ -127,35 +162,20 @@ public:
 	 *
 	 *
 	 * @return Upstream or NULL if none available
 	 * @return Upstream or NULL if none available
 	 */
 	 */
-	SharedPtr<Peer> getUpstreamPeer();
-
-	/**
-	 * @param id Identity to check
-	 * @return True if this is a root server or a network preferred relay from one of our networks
-	 */
-	bool isUpstream(const Identity &id) const;
-
-	/**
-	 * @param ztaddr ZeroTier address
-	 * @return Peer role for this device
-	 */
-	ZT_PeerRole role(const Address &ztaddr) const;
+	inline SharedPtr<Peer> getUpstreamPeer() const
+	{
+		return SharedPtr<Peer>();
+	}
 
 
-	/**
-	 * Check for prohibited endpoints
-	 *
-	 * Right now this returns true if the designated ZT address is a root and if
-	 * the IP (IP only, not port) does not equal any of the IPs defined in the
-	 * current World. This is an extra little security feature in case root keys
-	 * get appropriated or something.
-	 *
-	 * Otherwise it returns false.
-	 *
-	 * @param ztaddr ZeroTier address
-	 * @param ipaddr IP address
-	 * @return True if this ZT/IP pair should not be allowed to be used
-	 */
-	bool isProhibitedEndpoint(const Address &ztaddr,const InetAddress &ipaddr) const;
+	inline bool isUpstream(const Identity &id) const
+	{
+		return false;
+	}
+	
+	inline ZT_PeerRole role(const Address &ztaddr) const
+	{
+		return ZT_PEER_ROLE_LEAF;
+	}
 
 
 	/**
 	/**
 	 * Gets upstreams to contact and their stable endpoints (if known)
 	 * Gets upstreams to contact and their stable endpoints (if known)
@@ -175,10 +195,30 @@ public:
 		return std::vector<Address>();
 		return std::vector<Address>();
 	}
 	}
 
 
-	/**
-	 * Clean and flush database
-	 */
-	void doPeriodicTasks(void *tPtr,int64_t now);
+	inline void doPeriodicTasks(void *tPtr,int64_t now)
+	{
+		{
+			Mutex::Lock _l1(_peers_m);
+			Hashtable< Address,SharedPtr<Peer> >::Iterator i(_peers);
+			Address *a = (Address *)0;
+			SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
+			while (i.next(a,p)) {
+				if (!(*p)->isAlive(now)) {
+					_peers.erase(*a);
+				}
+			}
+		}
+		{
+			Mutex::Lock _l(_paths_m);
+			Hashtable< Path::HashKey,SharedPtr<Path> >::Iterator i(_paths);
+			Path::HashKey *k = (Path::HashKey *)0;
+			SharedPtr<Path> *p = (SharedPtr<Path> *)0;
+			while (i.next(k,p)) {
+				if (p->references() <= 1)
+					_paths.erase(*k);
+			}
+		}
+	}
 
 
 	/**
 	/**
 	 * @param now Current time
 	 * @param now Current time
@@ -218,7 +258,7 @@ public:
 	}
 	}
 
 
 	/**
 	/**
-	 * @return All currently active peers by address (unsorted)
+	 * @return All peers by address (unsorted)
 	 */
 	 */
 	inline std::vector< std::pair< Address,SharedPtr<Peer> > > allPeers() const
 	inline std::vector< std::pair< Address,SharedPtr<Peer> > > allPeers() const
 	{
 	{
@@ -294,21 +334,46 @@ public:
 	/**
 	/**
 	 * Set or clear physical path configuration (called via Node::setPhysicalPathConfiguration)
 	 * Set or clear physical path configuration (called via Node::setPhysicalPathConfiguration)
 	 */
 	 */
-	void setPhysicalPathConfiguration(const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig);
+	inline void setPhysicalPathConfiguration(const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig)
+	{
+		if (!pathNetwork) {
+			_numConfiguredPhysicalPaths = 0;
+		} else {
+			std::map<InetAddress,ZT_PhysicalPathConfiguration> cpaths;
+			for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i)
+				cpaths[_physicalPathConfig[i].first] = _physicalPathConfig[i].second;
+	
+			if (pathConfig) {
+				ZT_PhysicalPathConfiguration pc(*pathConfig);
+	
+				if (pc.mtu <= 0)
+					pc.mtu = ZT_DEFAULT_PHYSMTU;
+				else if (pc.mtu < ZT_MIN_PHYSMTU)
+					pc.mtu = ZT_MIN_PHYSMTU;
+				else if (pc.mtu > ZT_MAX_PHYSMTU)
+					pc.mtu = ZT_MAX_PHYSMTU;
+	
+				cpaths[*(reinterpret_cast<const InetAddress *>(pathNetwork))] = pc;
+			} else {
+				cpaths.erase(*(reinterpret_cast<const InetAddress *>(pathNetwork)));
+			}
+	
+			unsigned int cnt = 0;
+			for(std::map<InetAddress,ZT_PhysicalPathConfiguration>::const_iterator i(cpaths.begin());((i!=cpaths.end())&&(cnt<ZT_MAX_CONFIGURABLE_PATHS));++i) {
+				_physicalPathConfig[cnt].first = i->first;
+				_physicalPathConfig[cnt].second = i->second;
+				++cnt;
+			}
+			_numConfiguredPhysicalPaths = cnt;
+		}
+	}
 
 
 private:
 private:
-	Identity _getIdentity(void *tPtr,const Address &zta);
-	void _memoizeUpstreams(void *tPtr);
-	void _savePeer(void *tPtr,const SharedPtr<Peer> &peer);
-
 	const RuntimeEnvironment *const RR;
 	const RuntimeEnvironment *const RR;
-
 	std::pair<InetAddress,ZT_PhysicalPathConfiguration> _physicalPathConfig[ZT_MAX_CONFIGURABLE_PATHS];
 	std::pair<InetAddress,ZT_PhysicalPathConfiguration> _physicalPathConfig[ZT_MAX_CONFIGURABLE_PATHS];
 	unsigned int _numConfiguredPhysicalPaths;
 	unsigned int _numConfiguredPhysicalPaths;
-
 	Hashtable< Address,SharedPtr<Peer> > _peers;
 	Hashtable< Address,SharedPtr<Peer> > _peers;
 	Mutex _peers_m;
 	Mutex _peers_m;
-
 	Hashtable< Path::HashKey,SharedPtr<Path> > _paths;
 	Hashtable< Path::HashKey,SharedPtr<Path> > _paths;
 	Mutex _paths_m;
 	Mutex _paths_m;
 };
 };

+ 2 - 2
node/Trace.hpp

@@ -89,7 +89,7 @@ public:
 	class RuleResultLog
 	class RuleResultLog
 	{
 	{
 	public:
 	public:
-		RuleResultLog() {}
+		inline RuleResultLog() {}
 
 
 		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)
 		{
 		{
@@ -112,7 +112,7 @@ public:
 		uint8_t _l[ZT_MAX_NETWORK_RULES / 2];
 		uint8_t _l[ZT_MAX_NETWORK_RULES / 2];
 	};
 	};
 
 
-	Trace(const RuntimeEnvironment *renv) :
+	inline Trace(const RuntimeEnvironment *renv) :
 		RR(renv),
 		RR(renv),
 		_byNet(8)
 		_byNet(8)
 	{
 	{

+ 8 - 20
node/Utils.hpp

@@ -338,28 +338,16 @@ public:
 	/**
 	/**
 	 * Count the number of bits set in an integer
 	 * Count the number of bits set in an integer
 	 *
 	 *
-	 * @param v 32-bit integer
-	 * @return Number of bits set in this integer (0-32)
+	 * @param v Unsigned integer
+	 * @return Number of bits set in this integer (0-bits in integer)
 	 */
 	 */
-	static inline uint32_t countBits(uint32_t v)
+	template<typename T>
+	static inline uint64_t countBits(T v)
 	{
 	{
-		v = v - ((v >> 1) & (uint32_t)0x55555555);
-		v = (v & (uint32_t)0x33333333) + ((v >> 2) & (uint32_t)0x33333333);
-		return ((((v + (v >> 4)) & (uint32_t)0xF0F0F0F) * (uint32_t)0x1010101) >> 24);
-	}
-
-	/**
-	 * Count the number of bits set in an integer
-	 *
-	 * @param v 64-bit integer
-	 * @return Number of bits set in this integer (0-64)
-	 */
-	static inline uint64_t countBits(uint64_t v)
-	{
-		v = v - ((v >> 1) & (uint64_t)~(uint64_t)0/3);
-		v = (v & (uint64_t)~(uint64_t)0/15*3) + ((v >> 2) & (uint64_t)~(uint64_t)0/15*3);
-		v = (v + (v >> 4)) & (uint64_t)~(uint64_t)0/255*15;
-		return (uint64_t)(v * ((uint64_t)~(uint64_t)0/255)) >> 56;
+		v = v - ((v >> 1) & (T)~(T)0/3);
+		v = (v & (T)~(T)0/15*3) + ((v >> 2) & (T)~(T)0/15*3);
+		v = (v + (v >> 4)) & (T)~(T)0/255*15;
+		return (T)(v * ((~((T)0))/((T)255))) >> ((sizeof(T) - 1) * 8);
 	}
 	}
 
 
 	/**
 	/**

+ 0 - 1
objects.mk

@@ -24,7 +24,6 @@ CORE_OBJS=\
 	node/SHA512.o \
 	node/SHA512.o \
 	node/Switch.o \
 	node/Switch.o \
 	node/Tag.o \
 	node/Tag.o \
-	node/Topology.o \
 	node/Trace.o \
 	node/Trace.o \
 	node/Utils.o
 	node/Utils.o
 
 

+ 21 - 0
selftest.cpp

@@ -696,6 +696,27 @@ static int testOther()
 	char buf2[4096];
 	char buf2[4096];
 	char buf3[1024];
 	char buf3[1024];
 
 
+	std::cout << "[other] Testing bit count... "; std::cout.flush();
+	uint32_t i32 = 0;
+	uint64_t i64 = 0;
+	for(int i=0;i<=32;++i) {
+		if ((int)Utils::countBits(i32) != i) {
+			std::cout << "FAIL!" << std::endl;
+			return -1;
+		}
+		i32 <<= 1;
+		i32 |= 1;
+	}
+	for(int i=0;i<=64;++i) {
+		if ((int)Utils::countBits(i64) != i) {
+			std::cout << "FAIL!" << std::endl;
+			return -1;
+		}
+		i64 <<= 1;
+		i64 |= 1;
+	}
+	std::cout << "PASS" << std::endl;
+
 	std::cout << "[other] Testing hex/unhex... "; std::cout.flush();
 	std::cout << "[other] Testing hex/unhex... "; std::cout.flush();
 	Utils::getSecureRandom(buf,(unsigned int)sizeof(buf));
 	Utils::getSecureRandom(buf,(unsigned int)sizeof(buf));
 	Utils::hex(buf,(unsigned int)sizeof(buf),buf2);
 	Utils::hex(buf,(unsigned int)sizeof(buf),buf2);

+ 0 - 1
service/OneService.cpp

@@ -38,7 +38,6 @@
 #include <mutex>
 #include <mutex>
 #include <condition_variable>
 #include <condition_variable>
 
 
-#include "../version.h"
 #include "../include/ZeroTierOne.h"
 #include "../include/ZeroTierOne.h"
 
 
 #include "../node/Constants.hpp"
 #include "../node/Constants.hpp"

+ 0 - 1
service/SoftwareUpdater.cpp

@@ -30,7 +30,6 @@
 #include <stdint.h>
 #include <stdint.h>
 
 
 #include "../node/Constants.hpp"
 #include "../node/Constants.hpp"
-#include "../version.h"
 
 
 #ifdef __WINDOWS__
 #ifdef __WINDOWS__
 #include <WinSock2.h>
 #include <WinSock2.h>

+ 0 - 7
version.h.in

@@ -51,11 +51,4 @@
  */
  */
 #define ZEROTIER_ONE_VERSION_BUILD @ZEROTIER_ONE_VERSION_BUILD@
 #define ZEROTIER_ONE_VERSION_BUILD @ZEROTIER_ONE_VERSION_BUILD@
 
 
-#ifndef ZT_BUILD_ARCHITECTURE
-#define ZT_BUILD_ARCHITECTURE 0
-#endif
-#ifndef ZT_BUILD_PLATFORM
-#define ZT_BUILD_PLATFORM 0
-#endif
-
 #endif
 #endif