Răsfoiți Sursa

Code cleanup, Linux build fixes.

Adam Ierymenko 5 ani în urmă
părinte
comite
d18c33d6df
10 a modificat fișierele cu 142 adăugiri și 235 ștergeri
  1. 6 6
      core/AES.cpp
  2. 92 85
      core/AES.hpp
  3. 18 18
      core/Address.hpp
  4. 8 32
      core/Constants.hpp
  5. 0 50
      core/Dictionary.cpp
  6. 0 29
      core/Dictionary.hpp
  7. 10 4
      core/Endpoint.hpp
  8. 4 7
      osdep/LinuxNetLink.cpp
  9. 1 3
      osdep/LinuxNetLink.hpp
  10. 3 1
      serviceiocore/GoGlue.cpp

+ 6 - 6
core/AES.cpp

@@ -996,14 +996,14 @@ void AES::_initSW(const uint8_t key[32]) noexcept
 	rk[7] = readuint32_t(key + 28);
 	rk[7] = readuint32_t(key + 28);
 	for (int i = 0;;) {
 	for (int i = 0;;) {
 		uint32_t temp = rk[7];
 		uint32_t temp = rk[7];
-		rk[8] = rk[0] ^ (Te2[(temp >> 16U) & 0xff] & 0xff000000) ^ (Te3[(temp >> 8U) & 0xff] & 0x00ff0000) ^ (Te0[(temp) & 0xff] & 0x0000ff00) ^ (Te1[(temp >> 24U)] & 0x000000ff) ^ rcon[i];
+		rk[8] = rk[0] ^ (Te2[(temp >> 16U) & 0xffU] & 0xff000000U) ^ (Te3[(temp >> 8U) & 0xffU] & 0x00ff0000U) ^ (Te0[(temp) & 0xffU] & 0x0000ff00U) ^ (Te1[(temp >> 24U)] & 0x000000ffU) ^ rcon[i];
 		rk[9] = rk[1] ^ rk[8];
 		rk[9] = rk[1] ^ rk[8];
 		rk[10] = rk[2] ^ rk[9];
 		rk[10] = rk[2] ^ rk[9];
 		rk[11] = rk[3] ^ rk[10];
 		rk[11] = rk[3] ^ rk[10];
 		if (++i == 7)
 		if (++i == 7)
 			break;
 			break;
 		temp = rk[11];
 		temp = rk[11];
-		rk[12] = rk[4] ^ (Te2[(temp >> 24U)] & 0xff000000) ^ (Te3[(temp >> 16U) & 0xff] & 0x00ff0000) ^ (Te0[(temp >> 8U) & 0xff] & 0x0000ff00) ^ (Te1[(temp) & 0xff] & 0x000000ff);
+		rk[12] = rk[4] ^ (Te2[(temp >> 24U)] & 0xff000000U) ^ (Te3[(temp >> 16U) & 0xffU] & 0x00ff0000U) ^ (Te0[(temp >> 8U) & 0xffU] & 0x0000ff00U) ^ (Te1[(temp) & 0xffU] & 0x000000ffU);
 		rk[13] = rk[5] ^ rk[12];
 		rk[13] = rk[5] ^ rk[12];
 		rk[14] = rk[6] ^ rk[13];
 		rk[14] = rk[6] ^ rk[13];
 		rk[15] = rk[7] ^ rk[14];
 		rk[15] = rk[7] ^ rk[14];
@@ -1037,10 +1037,10 @@ void AES::_initSW(const uint8_t key[32]) noexcept
 	}
 	}
 	for (int i = 1; i < 14; ++i) {
 	for (int i = 1; i < 14; ++i) {
 		rk += 4;
 		rk += 4;
-		rk[0] = Td0[Te4[(rk[0] >> 24U)] & 0xff] ^ Td1[Te4[(rk[0] >> 16U) & 0xffU] & 0xff] ^ Td2[Te4[(rk[0] >> 8U) & 0xffU] & 0xffU] ^ Td3[Te4[(rk[0]) & 0xffU] & 0xffU];
-		rk[1] = Td0[Te4[(rk[1] >> 24U)] & 0xff] ^ Td1[Te4[(rk[1] >> 16U) & 0xffU] & 0xff] ^ Td2[Te4[(rk[1] >> 8U) & 0xffU] & 0xffU] ^ Td3[Te4[(rk[1]) & 0xffU] & 0xffU];
-		rk[2] = Td0[Te4[(rk[2] >> 24U)] & 0xff] ^ Td1[Te4[(rk[2] >> 16U) & 0xffU] & 0xff] ^ Td2[Te4[(rk[2] >> 8U) & 0xffU] & 0xffU] ^ Td3[Te4[(rk[2]) & 0xffU] & 0xffU];
-		rk[3] = Td0[Te4[(rk[3] >> 24U)] & 0xff] ^ Td1[Te4[(rk[3] >> 16U) & 0xffU] & 0xff] ^ Td2[Te4[(rk[3] >> 8U) & 0xffU] & 0xffU] ^ Td3[Te4[(rk[3]) & 0xffU] & 0xffU];
+		rk[0] = Td0[Te4[(rk[0] >> 24U)] & 0xffU] ^ Td1[Te4[(rk[0] >> 16U) & 0xffU] & 0xffU] ^ Td2[Te4[(rk[0] >> 8U) & 0xffU] & 0xffU] ^ Td3[Te4[(rk[0]) & 0xffU] & 0xffU];
+		rk[1] = Td0[Te4[(rk[1] >> 24U)] & 0xffU] ^ Td1[Te4[(rk[1] >> 16U) & 0xffU] & 0xffU] ^ Td2[Te4[(rk[1] >> 8U) & 0xffU] & 0xffU] ^ Td3[Te4[(rk[1]) & 0xffU] & 0xffU];
+		rk[2] = Td0[Te4[(rk[2] >> 24U)] & 0xffU] ^ Td1[Te4[(rk[2] >> 16U) & 0xffU] & 0xffU] ^ Td2[Te4[(rk[2] >> 8U) & 0xffU] & 0xffU] ^ Td3[Te4[(rk[2]) & 0xffU] & 0xffU];
+		rk[3] = Td0[Te4[(rk[3] >> 24U)] & 0xffU] ^ Td1[Te4[(rk[3] >> 16U) & 0xffU] & 0xffU] ^ Td2[Te4[(rk[3] >> 8U) & 0xffU] & 0xffU] ^ Td3[Te4[(rk[3]) & 0xffU] & 0xffU];
 	}
 	}
 }
 }
 
 

+ 92 - 85
core/AES.hpp

@@ -18,17 +18,9 @@
 #include "Utils.hpp"
 #include "Utils.hpp"
 #include "SHA512.hpp"
 #include "SHA512.hpp"
 
 
-#include <cstdint>
-#include <cstring>
-
-#ifndef ZT_AES_NO_ACCEL
-#ifdef ZT_ARCH_X64
-#include <xmmintrin.h>
-#include <emmintrin.h>
-#include <immintrin.h>
+#if !defined(ZT_AES_NO_ACCEL) && defined(ZT_ARCH_X64)
 #define ZT_AES_AESNI 1
 #define ZT_AES_AESNI 1
 #endif
 #endif
-#endif
 
 
 namespace ZeroTier {
 namespace ZeroTier {
 
 
@@ -56,7 +48,8 @@ public:
 	/**
 	/**
 	 * Create an un-initialized AES instance (must call init() before use)
 	 * Create an un-initialized AES instance (must call init() before use)
 	 */
 	 */
-	ZT_INLINE AES() noexcept {}
+	ZT_INLINE AES() noexcept
+	{}
 
 
 	/**
 	/**
 	 * Create an AES instance with the given key
 	 * Create an AES instance with the given key
@@ -70,7 +63,7 @@ public:
 
 
 	ZT_INLINE ~AES()
 	ZT_INLINE ~AES()
 	{
 	{
-		Utils::burn(&_k,sizeof(_k));
+		Utils::burn(&_k, sizeof(_k));
 	}
 	}
 
 
 	/**
 	/**
@@ -95,15 +88,15 @@ 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_INLINE void encrypt(const void *const in,void *const out) const noexcept
+	ZT_INLINE void encrypt(const void *const in, void *const out) const noexcept
 	{
 	{
 #ifdef ZT_AES_AESNI
 #ifdef ZT_AES_AESNI
 		if (likely(Utils::CPUID.aes)) {
 		if (likely(Utils::CPUID.aes)) {
-			_encrypt_aesni(in,out);
+			_encrypt_aesni(in, out);
 			return;
 			return;
 		}
 		}
 #endif
 #endif
-		_encryptSW(reinterpret_cast<const uint8_t *>(in),reinterpret_cast<uint8_t *>(out));
+		_encryptSW(reinterpret_cast<const uint8_t *>(in), reinterpret_cast<uint8_t *>(out));
 	}
 	}
 
 
 	/**
 	/**
@@ -112,18 +105,19 @@ 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_INLINE void decrypt(const void *const in,void *const out) const noexcept
+	ZT_INLINE void decrypt(const void *const in, void *const out) const noexcept
 	{
 	{
 #ifdef ZT_AES_AESNI
 #ifdef ZT_AES_AESNI
 		if (likely(Utils::CPUID.aes)) {
 		if (likely(Utils::CPUID.aes)) {
-			_decrypt_aesni(in,out);
+			_decrypt_aesni(in, out);
 			return;
 			return;
 		}
 		}
 #endif
 #endif
-		_decryptSW(reinterpret_cast<const uint8_t *>(in),reinterpret_cast<uint8_t *>(out));
+		_decryptSW(reinterpret_cast<const uint8_t *>(in), reinterpret_cast<uint8_t *>(out));
 	}
 	}
 
 
 	class GMACSIVEncryptor;
 	class GMACSIVEncryptor;
+
 	class GMACSIVDecryptor;
 	class GMACSIVDecryptor;
 
 
 	/**
 	/**
@@ -132,6 +126,7 @@ public:
 	class GMAC
 	class GMAC
 	{
 	{
 		friend class GMACSIVEncryptor;
 		friend class GMACSIVEncryptor;
+
 		friend class GMACSIVDecryptor;
 		friend class GMACSIVDecryptor;
 
 
 	public:
 	public:
@@ -140,7 +135,8 @@ public:
 		 *
 		 *
 		 * @param aes Keyed AES instance to use
 		 * @param aes Keyed AES instance to use
 		 */
 		 */
-		ZT_INLINE GMAC(const AES &aes) : _aes(aes) {}
+		ZT_INLINE GMAC(const AES &aes) : _aes(aes)
+		{}
 
 
 		/**
 		/**
 		 * Reset and initialize for a new GMAC calculation
 		 * Reset and initialize for a new GMAC calculation
@@ -176,7 +172,7 @@ public:
 		 * @param data Bytes to process
 		 * @param data Bytes to process
 		 * @param len Length of input
 		 * @param len Length of input
 		 */
 		 */
-		void update(const void *data,unsigned int len) noexcept;
+		void update(const void *data, unsigned int len) noexcept;
 
 
 		/**
 		/**
 		 * Process any remaining cached bytes and generate tag
 		 * Process any remaining cached bytes and generate tag
@@ -205,10 +201,12 @@ public:
 	class CTR
 	class CTR
 	{
 	{
 		friend class GMACSIVEncryptor;
 		friend class GMACSIVEncryptor;
+
 		friend class GMACSIVDecryptor;
 		friend class GMACSIVDecryptor;
 
 
 	public:
 	public:
-		ZT_INLINE CTR(const AES &aes) noexcept : _aes(aes) {}
+		ZT_INLINE CTR(const AES &aes) noexcept: _aes(aes)
+		{}
 
 
 		/**
 		/**
 		 * Initialize this CTR instance to encrypt a new stream
 		 * Initialize this CTR instance to encrypt a new stream
@@ -216,9 +214,9 @@ public:
 		 * @param iv Unique initialization vector and initial 32-bit counter (least significant 32 bits, big-endian)
 		 * @param iv Unique initialization vector and initial 32-bit counter (least significant 32 bits, big-endian)
 		 * @param output Buffer to which to store output (MUST be large enough for total bytes processed!)
 		 * @param output Buffer to which to store output (MUST be large enough for total bytes processed!)
 		 */
 		 */
-		ZT_INLINE void init(const uint8_t iv[16],void *const output) noexcept
+		ZT_INLINE void init(const uint8_t iv[16], void *const output) noexcept
 		{
 		{
-			Utils::copy<16>(_ctr,iv);
+			Utils::copy< 16 >(_ctr, iv);
 			_out = reinterpret_cast<uint8_t *>(output);
 			_out = reinterpret_cast<uint8_t *>(output);
 			_len = 0;
 			_len = 0;
 		}
 		}
@@ -230,9 +228,9 @@ public:
 		 * @param ic Initial counter (must be in big-endian byte order!)
 		 * @param ic Initial counter (must be in big-endian byte order!)
 		 * @param output Buffer to which to store output (MUST be large enough for total bytes processed!)
 		 * @param output Buffer to which to store output (MUST be large enough for total bytes processed!)
 		 */
 		 */
-		ZT_INLINE void init(const uint8_t iv[12],const uint32_t ic,void *const output) noexcept
+		ZT_INLINE void init(const uint8_t iv[12], const uint32_t ic, void *const output) noexcept
 		{
 		{
-			Utils::copy<12>(_ctr,iv);
+			Utils::copy< 12 >(_ctr, iv);
 			reinterpret_cast<uint32_t *>(_ctr)[3] = ic;
 			reinterpret_cast<uint32_t *>(_ctr)[3] = ic;
 			_out = reinterpret_cast<uint8_t *>(output);
 			_out = reinterpret_cast<uint8_t *>(output);
 			_len = 0;
 			_len = 0;
@@ -244,7 +242,7 @@ public:
 		 * @param input Input data
 		 * @param input Input data
 		 * @param len Length of input
 		 * @param len Length of input
 		 */
 		 */
-		void crypt(const void *input,unsigned int len) noexcept;
+		void crypt(const void *input, unsigned int len) noexcept;
 
 
 		/**
 		/**
 		 * Finish any remaining bytes if total bytes processed wasn't a multiple of 16
 		 * Finish any remaining bytes if total bytes processed wasn't a multiple of 16
@@ -280,9 +278,10 @@ public:
 		 * @param k0 First of two AES instances keyed with K0
 		 * @param k0 First of two AES instances keyed with K0
 		 * @param k1 Second of two AES instances keyed with K1
 		 * @param k1 Second of two AES instances keyed with K1
 		 */
 		 */
-		ZT_INLINE GMACSIVEncryptor(const AES &k0,const AES &k1) noexcept :
+		ZT_INLINE GMACSIVEncryptor(const AES &k0, const AES &k1) noexcept:
 			_gmac(k0),
 			_gmac(k0),
-			_ctr(k1) {}
+			_ctr(k1)
+		{}
 
 
 		/**
 		/**
 		 * Initialize AES-GMAC-SIV
 		 * Initialize AES-GMAC-SIV
@@ -290,7 +289,7 @@ public:
 		 * @param iv IV in network byte order (byte order in which it will appear on the wire)
 		 * @param iv IV in network byte order (byte order in which it will appear on the wire)
 		 * @param output Pointer to buffer to receive ciphertext, must be large enough for all to-be-processed data!
 		 * @param output Pointer to buffer to receive ciphertext, must be large enough for all to-be-processed data!
 		 */
 		 */
-		ZT_INLINE void init(const uint64_t iv,void *const output) noexcept
+		ZT_INLINE void init(const uint64_t iv, void *const output) noexcept
 		{
 		{
 			// Output buffer to receive the result of AES-CTR encryption.
 			// Output buffer to receive the result of AES-CTR encryption.
 			_output = output;
 			_output = output;
@@ -312,15 +311,15 @@ public:
 		 * @param aad Additional authenticated data
 		 * @param aad Additional authenticated data
 		 * @param len Length of AAD in bytes
 		 * @param len Length of AAD in bytes
 		 */
 		 */
-		ZT_INLINE void aad(const void *const aad,unsigned int len) noexcept
+		ZT_INLINE void aad(const void *const aad, unsigned int len) noexcept
 		{
 		{
 			// Feed ADD into GMAC first
 			// Feed ADD into GMAC first
-			_gmac.update(aad,len);
+			_gmac.update(aad, len);
 
 
 			// End of AAD is padded to a multiple of 16 bytes to ensure unique encoding.
 			// End of AAD is padded to a multiple of 16 bytes to ensure unique encoding.
 			len &= 0xfU;
 			len &= 0xfU;
 			if (len != 0)
 			if (len != 0)
-				_gmac.update(Utils::ZERO256,16 - len);
+				_gmac.update(Utils::ZERO256, 16 - len);
 		}
 		}
 
 
 		/**
 		/**
@@ -329,9 +328,9 @@ public:
 		 * @param input Plaintext chunk
 		 * @param input Plaintext chunk
 		 * @param len Length of plaintext chunk
 		 * @param len Length of plaintext chunk
 		 */
 		 */
-		ZT_INLINE void update1(const void *const input,const unsigned int len) noexcept
+		ZT_INLINE void update1(const void *const input, const unsigned int len) noexcept
 		{
 		{
-			_gmac.update(input,len);
+			_gmac.update(input, len);
 		}
 		}
 
 
 		/**
 		/**
@@ -350,7 +349,7 @@ public:
 			// packet and then recombined on receipt for legacy reasons (but with no
 			// packet and then recombined on receipt for legacy reasons (but with no
 			// cryptographic or performance impact).
 			// cryptographic or performance impact).
 			_tag[1] = tmp[0] ^ tmp[1];
 			_tag[1] = tmp[0] ^ tmp[1];
-			_ctr._aes.encrypt(_tag,_tag);
+			_ctr._aes.encrypt(_tag, _tag);
 
 
 			// Initialize CTR with 96-bit CTR nonce and 32-bit counter. The counter
 			// Initialize CTR with 96-bit CTR nonce and 32-bit counter. The counter
 			// incorporates 31 more bits of entropy which should raise our security margin
 			// incorporates 31 more bits of entropy which should raise our security margin
@@ -362,7 +361,7 @@ public:
 			// and so 2^31 should be considered the input limit.
 			// and so 2^31 should be considered the input limit.
 			tmp[0] = _tag[0];
 			tmp[0] = _tag[0];
 			tmp[1] = _tag[1] & ZT_CONST_TO_BE_UINT64(0xffffffff7fffffffULL);
 			tmp[1] = _tag[1] & ZT_CONST_TO_BE_UINT64(0xffffffff7fffffffULL);
-			_ctr.init(reinterpret_cast<const uint8_t *>(tmp),_output);
+			_ctr.init(reinterpret_cast<const uint8_t *>(tmp), _output);
 		}
 		}
 
 
 		/**
 		/**
@@ -374,9 +373,9 @@ public:
 		 * @param input Plaintext chunk
 		 * @param input Plaintext chunk
 		 * @param len Length of plaintext chunk
 		 * @param len Length of plaintext chunk
 		 */
 		 */
-		ZT_INLINE void update2(const void *const input,const unsigned int len) noexcept
+		ZT_INLINE void update2(const void *const input, const unsigned int len) noexcept
 		{
 		{
-			_ctr.crypt(input,len);
+			_ctr.crypt(input, len);
 		}
 		}
 
 
 		/**
 		/**
@@ -408,9 +407,10 @@ public:
 	class GMACSIVDecryptor
 	class GMACSIVDecryptor
 	{
 	{
 	public:
 	public:
-		ZT_INLINE GMACSIVDecryptor(const AES &k0,const AES &k1) noexcept :
+		ZT_INLINE GMACSIVDecryptor(const AES &k0, const AES &k1) noexcept:
 			_ctr(k1),
 			_ctr(k1),
-			_gmac(k0) {}
+			_gmac(k0)
+		{}
 
 
 		/**
 		/**
 		 * Initialize decryptor for a new message
 		 * Initialize decryptor for a new message
@@ -418,14 +418,14 @@ public:
 		 * @param tag 128-bit combined IV/MAC originally created by GMAC-SIV encryption
 		 * @param tag 128-bit combined IV/MAC originally created by GMAC-SIV encryption
 		 * @param output Buffer in which to write output plaintext (must be large enough!)
 		 * @param output Buffer in which to write output plaintext (must be large enough!)
 		 */
 		 */
-		ZT_INLINE void init(const uint64_t tag[2],void *const output) noexcept
+		ZT_INLINE void init(const uint64_t tag[2], void *const output) noexcept
 		{
 		{
 			uint64_t tmp[2];
 			uint64_t tmp[2];
 			tmp[0] = tag[0];
 			tmp[0] = tag[0];
 			tmp[1] = tag[1] & ZT_CONST_TO_BE_UINT64(0xffffffff7fffffffULL);
 			tmp[1] = tag[1] & ZT_CONST_TO_BE_UINT64(0xffffffff7fffffffULL);
-			_ctr.init(reinterpret_cast<const uint8_t *>(tmp),output);
+			_ctr.init(reinterpret_cast<const uint8_t *>(tmp), output);
 
 
-			_ctr._aes.decrypt(tag,_ivMac);
+			_ctr._aes.decrypt(tag, _ivMac);
 
 
 			tmp[0] = _ivMac[0];
 			tmp[0] = _ivMac[0];
 			tmp[1] = 0;
 			tmp[1] = 0;
@@ -441,12 +441,12 @@ public:
 		 * @param aad Additional authenticated data
 		 * @param aad Additional authenticated data
 		 * @param len Length of AAD in bytes
 		 * @param len Length of AAD in bytes
 		 */
 		 */
-		ZT_INLINE void aad(const void *const aad,unsigned int len) noexcept
+		ZT_INLINE void aad(const void *const aad, unsigned int len) noexcept
 		{
 		{
-			_gmac.update(aad,len);
+			_gmac.update(aad, len);
 			len &= 0xfU;
 			len &= 0xfU;
 			if (len != 0)
 			if (len != 0)
-				_gmac.update(Utils::ZERO256,16 - len);
+				_gmac.update(Utils::ZERO256, 16 - len);
 		}
 		}
 
 
 		/**
 		/**
@@ -457,9 +457,9 @@ public:
 		 * @param input Input ciphertext
 		 * @param input Input ciphertext
 		 * @param len Length of ciphertext
 		 * @param len Length of ciphertext
 		 */
 		 */
-		ZT_INLINE void update(const void *const input,const unsigned int len) noexcept
+		ZT_INLINE void update(const void *const input, const unsigned int len) noexcept
 		{
 		{
-			_ctr.crypt(input,len);
+			_ctr.crypt(input, len);
 			_decryptedLen += len;
 			_decryptedLen += len;
 		}
 		}
 
 
@@ -473,7 +473,7 @@ public:
 			_ctr.finish();
 			_ctr.finish();
 
 
 			uint64_t gmacTag[2];
 			uint64_t gmacTag[2];
-			_gmac.update(_output,_decryptedLen);
+			_gmac.update(_output, _decryptedLen);
 			_gmac.finish(reinterpret_cast<uint8_t *>(gmacTag));
 			_gmac.finish(reinterpret_cast<uint8_t *>(gmacTag));
 			return (gmacTag[0] ^ gmacTag[1]) == _ivMac[1];
 			return (gmacTag[0] ^ gmacTag[1]) == _ivMac[1];
 		}
 		}
@@ -500,18 +500,23 @@ private:
 	static const uint32_t rcon[10];
 	static const uint32_t rcon[10];
 
 
 	void _initSW(const uint8_t key[32]) noexcept;
 	void _initSW(const uint8_t key[32]) noexcept;
-	void _encryptSW(const uint8_t in[16],uint8_t out[16]) const noexcept;
-	void _decryptSW(const uint8_t in[16],uint8_t out[16]) const noexcept;
 
 
-	union {
+	void _encryptSW(const uint8_t in[16], uint8_t out[16]) const noexcept;
+
+	void _decryptSW(const uint8_t in[16], uint8_t out[16]) const noexcept;
+
+	union
+	{
 #ifdef ZT_AES_AESNI
 #ifdef ZT_AES_AESNI
-		struct {
+		struct
+		{
 			__m128i k[28];
 			__m128i k[28];
 			__m128i h[4]; // h, hh, hhh, hhhh
 			__m128i h[4]; // h, hh, hhh, hhhh
 		} ni;
 		} ni;
 #endif
 #endif
 
 
-		struct {
+		struct
+		{
 			uint64_t h[2];
 			uint64_t h[2];
 			uint32_t ek[60];
 			uint32_t ek[60];
 			uint32_t dk[60];
 			uint32_t dk[60];
@@ -519,47 +524,49 @@ private:
 	} _k;
 	} _k;
 
 
 #ifdef ZT_AES_AESNI
 #ifdef ZT_AES_AESNI
+
 	void _init_aesni(const uint8_t key[32]) noexcept;
 	void _init_aesni(const uint8_t key[32]) noexcept;
 
 
-	ZT_INLINE void _encrypt_aesni(const void *const in,void *const out) const noexcept
+	ZT_INLINE void _encrypt_aesni(const void *const in, void *const out) const noexcept
 	{
 	{
 		__m128i tmp = _mm_loadu_si128((const __m128i *)in);
 		__m128i tmp = _mm_loadu_si128((const __m128i *)in);
-		tmp = _mm_xor_si128(tmp,_k.ni.k[0]);
-		tmp = _mm_aesenc_si128(tmp,_k.ni.k[1]);
-		tmp = _mm_aesenc_si128(tmp,_k.ni.k[2]);
-		tmp = _mm_aesenc_si128(tmp,_k.ni.k[3]);
-		tmp = _mm_aesenc_si128(tmp,_k.ni.k[4]);
-		tmp = _mm_aesenc_si128(tmp,_k.ni.k[5]);
-		tmp = _mm_aesenc_si128(tmp,_k.ni.k[6]);
-		tmp = _mm_aesenc_si128(tmp,_k.ni.k[7]);
-		tmp = _mm_aesenc_si128(tmp,_k.ni.k[8]);
-		tmp = _mm_aesenc_si128(tmp,_k.ni.k[9]);
-		tmp = _mm_aesenc_si128(tmp,_k.ni.k[10]);
-		tmp = _mm_aesenc_si128(tmp,_k.ni.k[11]);
-		tmp = _mm_aesenc_si128(tmp,_k.ni.k[12]);
-		tmp = _mm_aesenc_si128(tmp,_k.ni.k[13]);
-		_mm_storeu_si128((__m128i *)out,_mm_aesenclast_si128(tmp,_k.ni.k[14]));
+		tmp = _mm_xor_si128(tmp, _k.ni.k[0]);
+		tmp = _mm_aesenc_si128(tmp, _k.ni.k[1]);
+		tmp = _mm_aesenc_si128(tmp, _k.ni.k[2]);
+		tmp = _mm_aesenc_si128(tmp, _k.ni.k[3]);
+		tmp = _mm_aesenc_si128(tmp, _k.ni.k[4]);
+		tmp = _mm_aesenc_si128(tmp, _k.ni.k[5]);
+		tmp = _mm_aesenc_si128(tmp, _k.ni.k[6]);
+		tmp = _mm_aesenc_si128(tmp, _k.ni.k[7]);
+		tmp = _mm_aesenc_si128(tmp, _k.ni.k[8]);
+		tmp = _mm_aesenc_si128(tmp, _k.ni.k[9]);
+		tmp = _mm_aesenc_si128(tmp, _k.ni.k[10]);
+		tmp = _mm_aesenc_si128(tmp, _k.ni.k[11]);
+		tmp = _mm_aesenc_si128(tmp, _k.ni.k[12]);
+		tmp = _mm_aesenc_si128(tmp, _k.ni.k[13]);
+		_mm_storeu_si128((__m128i *)out, _mm_aesenclast_si128(tmp, _k.ni.k[14]));
 	}
 	}
 
 
-	ZT_INLINE void _decrypt_aesni(const void *in,void *out) const noexcept
+	ZT_INLINE void _decrypt_aesni(const void *in, void *out) const noexcept
 	{
 	{
 		__m128i tmp = _mm_loadu_si128((const __m128i *)in);
 		__m128i tmp = _mm_loadu_si128((const __m128i *)in);
-		tmp = _mm_xor_si128(tmp,_k.ni.k[14]);
-		tmp = _mm_aesdec_si128(tmp,_k.ni.k[15]);
-		tmp = _mm_aesdec_si128(tmp,_k.ni.k[16]);
-		tmp = _mm_aesdec_si128(tmp,_k.ni.k[17]);
-		tmp = _mm_aesdec_si128(tmp,_k.ni.k[18]);
-		tmp = _mm_aesdec_si128(tmp,_k.ni.k[19]);
-		tmp = _mm_aesdec_si128(tmp,_k.ni.k[20]);
-		tmp = _mm_aesdec_si128(tmp,_k.ni.k[21]);
-		tmp = _mm_aesdec_si128(tmp,_k.ni.k[22]);
-		tmp = _mm_aesdec_si128(tmp,_k.ni.k[23]);
-		tmp = _mm_aesdec_si128(tmp,_k.ni.k[24]);
-		tmp = _mm_aesdec_si128(tmp,_k.ni.k[25]);
-		tmp = _mm_aesdec_si128(tmp,_k.ni.k[26]);
-		tmp = _mm_aesdec_si128(tmp,_k.ni.k[27]);
-		_mm_storeu_si128((__m128i *)out,_mm_aesdeclast_si128(tmp,_k.ni.k[0]));
+		tmp = _mm_xor_si128(tmp, _k.ni.k[14]);
+		tmp = _mm_aesdec_si128(tmp, _k.ni.k[15]);
+		tmp = _mm_aesdec_si128(tmp, _k.ni.k[16]);
+		tmp = _mm_aesdec_si128(tmp, _k.ni.k[17]);
+		tmp = _mm_aesdec_si128(tmp, _k.ni.k[18]);
+		tmp = _mm_aesdec_si128(tmp, _k.ni.k[19]);
+		tmp = _mm_aesdec_si128(tmp, _k.ni.k[20]);
+		tmp = _mm_aesdec_si128(tmp, _k.ni.k[21]);
+		tmp = _mm_aesdec_si128(tmp, _k.ni.k[22]);
+		tmp = _mm_aesdec_si128(tmp, _k.ni.k[23]);
+		tmp = _mm_aesdec_si128(tmp, _k.ni.k[24]);
+		tmp = _mm_aesdec_si128(tmp, _k.ni.k[25]);
+		tmp = _mm_aesdec_si128(tmp, _k.ni.k[26]);
+		tmp = _mm_aesdec_si128(tmp, _k.ni.k[27]);
+		_mm_storeu_si128((__m128i *)out, _mm_aesdeclast_si128(tmp, _k.ni.k[0]));
 	}
 	}
+
 #endif
 #endif
 };
 };
 
 

+ 18 - 18
core/Address.hpp

@@ -40,7 +40,7 @@ public:
 	{}
 	{}
 
 
 	explicit ZT_INLINE Address(const uint8_t b[5]) noexcept:
 	explicit ZT_INLINE Address(const uint8_t b[5]) noexcept:
-		_a(((uint64_t) b[0] << 32U) | ((uint64_t) b[1] << 24U) | ((uint64_t) b[2] << 16U) | ((uint64_t) b[3] << 8U) | (uint64_t) b[4])
+		_a(((uint64_t)b[0] << 32U) | ((uint64_t)b[1] << 24U) | ((uint64_t)b[2] << 16U) | ((uint64_t)b[3] << 8U) | (uint64_t)b[4])
 	{}
 	{}
 
 
 	ZT_INLINE Address &operator=(const uint64_t a) noexcept
 	ZT_INLINE Address &operator=(const uint64_t a) noexcept
@@ -55,7 +55,7 @@ public:
 	 */
 	 */
 	ZT_INLINE void setTo(const uint8_t b[5]) noexcept
 	ZT_INLINE void setTo(const uint8_t b[5]) noexcept
 	{
 	{
-		_a = ((uint64_t) b[0] << 32U) | ((uint64_t) b[1] << 24U) | ((uint64_t) b[2] << 16U) | ((uint64_t) b[3] << 8U) | (uint64_t) b[4];
+		_a = ((uint64_t)b[0] << 32U) | ((uint64_t)b[1] << 24U) | ((uint64_t)b[2] << 16U) | ((uint64_t)b[3] << 8U) | (uint64_t)b[4];
 	}
 	}
 
 
 	/**
 	/**
@@ -65,11 +65,11 @@ public:
 	ZT_INLINE void copyTo(uint8_t b[5]) const noexcept
 	ZT_INLINE void copyTo(uint8_t b[5]) const noexcept
 	{
 	{
 		const uint64_t a = _a;
 		const uint64_t a = _a;
-		b[0] = (uint8_t) (a >> 32U);
-		b[1] = (uint8_t) (a >> 24U);
-		b[2] = (uint8_t) (a >> 16U);
-		b[3] = (uint8_t) (a >> 8U);
-		b[4] = (uint8_t) a;
+		b[0] = (uint8_t)(a >> 32U);
+		b[1] = (uint8_t)(a >> 24U);
+		b[2] = (uint8_t)(a >> 16U);
+		b[3] = (uint8_t)(a >> 8U);
+		b[4] = (uint8_t)a;
 	}
 	}
 
 
 	/**
 	/**
@@ -92,16 +92,16 @@ public:
 	{
 	{
 		const uint64_t a = _a;
 		const uint64_t a = _a;
 		const unsigned int m = 0xf;
 		const unsigned int m = 0xf;
-		s[0] = Utils::HEXCHARS[(unsigned int) (a >> 36U) & m];
-		s[1] = Utils::HEXCHARS[(unsigned int) (a >> 32U) & m];
-		s[2] = Utils::HEXCHARS[(unsigned int) (a >> 28U) & m];
-		s[3] = Utils::HEXCHARS[(unsigned int) (a >> 24U) & m];
-		s[4] = Utils::HEXCHARS[(unsigned int) (a >> 20U) & m];
-		s[5] = Utils::HEXCHARS[(unsigned int) (a >> 16U) & m];
-		s[6] = Utils::HEXCHARS[(unsigned int) (a >> 12U) & m];
-		s[7] = Utils::HEXCHARS[(unsigned int) (a >> 8U) & m];
-		s[8] = Utils::HEXCHARS[(unsigned int) (a >> 4U) & m];
-		s[9] = Utils::HEXCHARS[(unsigned int) a & m];
+		s[0] = Utils::HEXCHARS[(unsigned int)(a >> 36U) & m];
+		s[1] = Utils::HEXCHARS[(unsigned int)(a >> 32U) & m];
+		s[2] = Utils::HEXCHARS[(unsigned int)(a >> 28U) & m];
+		s[3] = Utils::HEXCHARS[(unsigned int)(a >> 24U) & m];
+		s[4] = Utils::HEXCHARS[(unsigned int)(a >> 20U) & m];
+		s[5] = Utils::HEXCHARS[(unsigned int)(a >> 16U) & m];
+		s[6] = Utils::HEXCHARS[(unsigned int)(a >> 12U) & m];
+		s[7] = Utils::HEXCHARS[(unsigned int)(a >> 8U) & m];
+		s[8] = Utils::HEXCHARS[(unsigned int)(a >> 4U) & m];
+		s[9] = Utils::HEXCHARS[(unsigned int)a & m];
 		s[10] = 0;
 		s[10] = 0;
 		return s;
 		return s;
 	}
 	}
@@ -126,7 +126,7 @@ public:
 	{ return ((!_a) || ((_a >> 32U) == ZT_ADDRESS_RESERVED_PREFIX)); }
 	{ return ((!_a) || ((_a >> 32U) == ZT_ADDRESS_RESERVED_PREFIX)); }
 
 
 	ZT_INLINE unsigned long hashCode() const noexcept
 	ZT_INLINE unsigned long hashCode() const noexcept
-	{ return (unsigned long) _a; }
+	{ return (unsigned long)_a; }
 
 
 	ZT_INLINE operator bool() const noexcept
 	ZT_INLINE operator bool() const noexcept
 	{ return (_a != 0); }
 	{ return (_a != 0); }

+ 8 - 32
core/Constants.hpp

@@ -29,11 +29,11 @@
 /**
 /**
  * Version bit packed into four 16-bit fields in a 64-bit unsigned integer.
  * Version bit packed into four 16-bit fields in a 64-bit unsigned integer.
  */
  */
-#define ZT_VERSION_PACKED ( \
-	((uint64_t)ZEROTIER_VERSION_MAJOR << 48U) | \
-	((uint64_t)ZEROTIER_VERSION_MINOR << 32U) | \
+#define ZT_VERSION_PACKED (                      \
+	((uint64_t)ZEROTIER_VERSION_MAJOR    << 48U) | \
+	((uint64_t)ZEROTIER_VERSION_MINOR    << 32U) | \
 	((uint64_t)ZEROTIER_VERSION_REVISION << 16U) | \
 	((uint64_t)ZEROTIER_VERSION_REVISION << 16U) | \
-	(uint64_t)ZEROTIER_VERSION_BUILD )
+	((uint64_t)ZEROTIER_VERSION_BUILD)         )
 
 
 /**
 /**
  * Length of a ZeroTier address in bytes
  * Length of a ZeroTier address in bytes
@@ -91,7 +91,7 @@
 #define ZT_SYMMETRIC_KEY_TTL 1800000
 #define ZT_SYMMETRIC_KEY_TTL 1800000
 
 
 /**
 /**
- * Maximum number of messages over which a key should be considered usable.
+ * Maximum number of messages per symmetric key.
  */
  */
 #define ZT_SYMMETRIC_KEY_TTL_MESSAGES 2147483648
 #define ZT_SYMMETRIC_KEY_TTL_MESSAGES 2147483648
 
 
@@ -178,7 +178,7 @@
 #define ZT_PEER_PRIORITIZE_PATHS_INTERVAL 5000
 #define ZT_PEER_PRIORITIZE_PATHS_INTERVAL 5000
 
 
 /**
 /**
- * Number of previous endpoints to cache for root-less re-establishment
+ * Number of previous endpoints to cache in peer records.
  */
  */
 #define ZT_PEER_ENDPOINT_CACHE_SIZE 8
 #define ZT_PEER_ENDPOINT_CACHE_SIZE 8
 
 
@@ -201,11 +201,6 @@
  */
  */
 #define ZT_MAX_BRIDGE_ROUTES 16777216
 #define ZT_MAX_BRIDGE_ROUTES 16777216
 
 
-/**
- * If there is no known L2 bridging route, spam to up to this many active bridges
- */
-#define ZT_MAX_BRIDGE_SPAM 32
-
 /**
 /**
  * WHOIS rate limit (we allow these to be pretty fast)
  * WHOIS rate limit (we allow these to be pretty fast)
  */
  */
@@ -221,30 +216,11 @@
  */
  */
 #define ZT_PEER_PROBE_RESPONSE_RATE_LIMIT 5000
 #define ZT_PEER_PROBE_RESPONSE_RATE_LIMIT 5000
 
 
-/**
- * Don't do expensive identity validation more often than this
- *
- * IPv4 and IPv6 address prefixes are hashed down to 14-bit (0-16383) integers
- * using the first 24 bits for IPv4 or the first 48 bits for IPv6. These are
- * then rate limited to one identity validation per this often milliseconds.
- */
-#if (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64) || defined(_M_AMD64))
-// AMD64 machines can do anywhere from one every 50ms to one every 10ms. This provides plenty of margin.
-#define ZT_IDENTITY_VALIDATION_SOURCE_RATE_LIMIT 2000
-#else
-#if (defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(_X86_) || defined(__I86__))
-// 32-bit Intel machines usually average about one every 100ms
-#define ZT_IDENTITY_VALIDATION_SOURCE_RATE_LIMIT 5000
-#else
-// This provides a safe margin for ARM, MIPS, etc. that usually average one every 250-400ms
-#define ZT_IDENTITY_VALIDATION_SOURCE_RATE_LIMIT 10000
-#endif
-#endif
-
 /**
 /**
  * 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
  *
  *
- * This must be large enough to hold all signature types.
+ * This must be large enough to hold all signature types, which right now is
+ * Curve25519 EDDSA and NIST P-384 ECDSA.
  */
  */
 #define ZT_SIGNATURE_BUFFER_SIZE 96
 #define ZT_SIGNATURE_BUFFER_SIZE 96
 
 

+ 0 - 50
core/Dictionary.cpp

@@ -12,7 +12,6 @@
 /****/
 /****/
 
 
 #include "Dictionary.hpp"
 #include "Dictionary.hpp"
-#include "Identity.hpp"
 
 
 namespace ZeroTier {
 namespace ZeroTier {
 
 
@@ -124,55 +123,6 @@ char *Dictionary::getS(const char *k, char *v, const unsigned int cap) const
 	return v;
 	return v;
 }
 }
 
 
-bool Dictionary::sign(const Identity &signer)
-{
-	Vector<uint8_t> data;
-	encode(data, true);
-	uint8_t sig[ZT_SIGNATURE_BUFFER_SIZE];
-	const unsigned int siglen = signer.sign(data.data(), (unsigned int) data.size(), sig, ZT_SIGNATURE_BUFFER_SIZE);
-	if (siglen == 0)
-		return false;
-
-	uint8_t fp[ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE];
-	Address(signer.fingerprint().address).copyTo(fp);
-	Utils::copy<ZT_FINGERPRINT_HASH_SIZE>(fp + ZT_ADDRESS_LENGTH, signer.fingerprint().hash);
-
-	m_entries[s_signatureFingerprint].assign(fp, fp + ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE);
-	m_entries[s_signatureData].assign(sig, sig + siglen);
-
-	return true;
-}
-
-Fingerprint Dictionary::signer() const
-{
-	SortedMap<FCV<char, 8>, Vector<uint8_t> >::const_iterator sigfp(m_entries.find(s_signatureFingerprint));
-	Fingerprint fp;
-	if ((sigfp != m_entries.end()) && (sigfp->second.size() == (ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE))) {
-		fp.address = Address(sigfp->second.data());
-		Utils::copy<ZT_FINGERPRINT_HASH_SIZE>(fp.hash, sigfp->second.data() + ZT_ADDRESS_LENGTH);
-	}
-	return fp;
-}
-
-bool Dictionary::verify(const Identity &signer) const
-{
-	SortedMap< FCV<char, 8>, Vector<uint8_t> >::const_iterator sigfp(m_entries.find(s_signatureFingerprint));
-	if (
-		(sigfp == m_entries.end()) ||
-		(sigfp->second.size() != (ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE)) ||
-		(Address(sigfp->second.data()) != signer.address()) ||
-		(memcmp(sigfp->second.data() + ZT_ADDRESS_LENGTH,signer.fingerprint().hash,ZT_FINGERPRINT_HASH_SIZE) != 0))
-		return false;
-
-	SortedMap< FCV<char, 8>, Vector<uint8_t> >::const_iterator sig(m_entries.find(s_signatureData));
-	if ((sig == m_entries.end()) || (sig->second.empty()))
-		return false;
-
-	Vector<uint8_t> data;
-	encode(data, true);
-	return signer.verify(data.data(),(unsigned int)data.size(),sig->second.data(),(unsigned int)sig->second.size());
-}
-
 void Dictionary::clear()
 void Dictionary::clear()
 {
 {
 	m_entries.clear();
 	m_entries.clear();

+ 0 - 29
core/Dictionary.hpp

@@ -19,8 +19,6 @@
 #include "Address.hpp"
 #include "Address.hpp"
 #include "Buf.hpp"
 #include "Buf.hpp"
 #include "FCV.hpp"
 #include "FCV.hpp"
-#include "SHA512.hpp"
-#include "Fingerprint.hpp"
 #include "Containers.hpp"
 #include "Containers.hpp"
 
 
 namespace ZeroTier {
 namespace ZeroTier {
@@ -141,33 +139,6 @@ public:
 		return (obj.unmarshal(d.data(),(unsigned int)d.size()) > 0);
 		return (obj.unmarshal(d.data(),(unsigned int)d.size()) > 0);
 	}
 	}
 
 
-	/**
-	 * Sign this identity
-	 *
-	 * This adds two fields:
-	 *   "@Si" contains the fingerprint (address followed by hash) of the signer
-	 *   "@Ss" contains the signature
-	 *
-	 * @param signer Signing identity (must contain secret)
-	 * @return True if signature was successful
-	 */
-	bool sign(const Identity &signer);
-
-	/**
-	 * Get the signer's fingerprint for this dictionary or a NIL fingerprint if not signed.
-	 *
-	 * @return Signer
-	 */
-	Fingerprint signer() const;
-
-	/**
-	 * Verify this identity's signature
-	 *
-	 * @param signer
-	 * @return
-	 */
-	bool verify(const Identity &signer) const;
-
 	/**
 	/**
 	 * Erase all entries in dictionary
 	 * Erase all entries in dictionary
 	 */
 	 */

+ 10 - 4
core/Endpoint.hpp

@@ -52,7 +52,7 @@ public:
 	{ memoryZero(this); }
 	{ memoryZero(this); }
 
 
 	ZT_INLINE Endpoint(const ZT_Endpoint &ep) noexcept
 	ZT_INLINE Endpoint(const ZT_Endpoint &ep) noexcept
-	{ *this = ep; }
+	{ Utils::copy< sizeof(ZT_Endpoint) >((ZT_Endpoint *)this, &ep); }
 
 
 	/**
 	/**
 	 * Create an endpoint for a type that uses an IP
 	 * Create an endpoint for a type that uses an IP
@@ -64,7 +64,7 @@ public:
 	{
 	{
 		if (inaddr) {
 		if (inaddr) {
 			this->type = et;
 			this->type = et;
-			Utils::copy<sizeof(struct sockaddr_storage)>(&(this->value.ss), &(inaddr.as.ss));
+			Utils::copy< sizeof(struct sockaddr_storage) >(&(this->value.ss), &(inaddr.as.ss));
 		} else {
 		} else {
 			memoryZero(this);
 			memoryZero(this);
 		}
 		}
@@ -139,7 +139,7 @@ public:
 			case ZT_ENDPOINT_TYPE_IP_UDP:
 			case ZT_ENDPOINT_TYPE_IP_UDP:
 			case ZT_ENDPOINT_TYPE_IP_TCP:
 			case ZT_ENDPOINT_TYPE_IP_TCP:
 			case ZT_ENDPOINT_TYPE_IP_HTTP:
 			case ZT_ENDPOINT_TYPE_IP_HTTP:
-				switch(ep.type) {
+				switch (ep.type) {
 					case ZT_ENDPOINT_TYPE_IP:
 					case ZT_ENDPOINT_TYPE_IP:
 					case ZT_ENDPOINT_TYPE_IP_UDP:
 					case ZT_ENDPOINT_TYPE_IP_UDP:
 					case ZT_ENDPOINT_TYPE_IP_TCP:
 					case ZT_ENDPOINT_TYPE_IP_TCP:
@@ -200,7 +200,11 @@ public:
 
 
 	char *toString(char s[ZT_ENDPOINT_STRING_SIZE_MAX]) const noexcept;
 	char *toString(char s[ZT_ENDPOINT_STRING_SIZE_MAX]) const noexcept;
 
 
-	ZT_INLINE String toString() const { char tmp[ZT_ENDPOINT_STRING_SIZE_MAX]; return String(toString(tmp)); }
+	ZT_INLINE String toString() const
+	{
+		char tmp[ZT_ENDPOINT_STRING_SIZE_MAX];
+		return String(toString(tmp));
+	}
 
 
 	bool fromString(const char *s) noexcept;
 	bool fromString(const char *s) noexcept;
 
 
@@ -228,6 +232,8 @@ public:
 	{ return !(*this < ep); }
 	{ return !(*this < ep); }
 };
 };
 
 
+static_assert(sizeof(Endpoint) == sizeof(ZT_Endpoint), "size mismatch");
+
 } // namespace ZeroTier
 } // namespace ZeroTier
 
 
 #endif
 #endif

+ 4 - 7
osdep/LinuxNetLink.cpp

@@ -419,7 +419,7 @@ void LinuxNetLink::_linkDeleted(struct nlmsghdr *nlp)
 
 
 	{
 	{
 		Mutex::Lock l(_if_m);
 		Mutex::Lock l(_if_m);
-		if(_interfaces.contains(ifip->ifi_index)) {
+		if(_interfaces.find(ifip->ifi_index) != _interfaces.end()) {
 			_interfaces.erase(ifip->ifi_index);
 			_interfaces.erase(ifip->ifi_index);
 		}
 		}
 	}
 	}
@@ -1057,12 +1057,9 @@ int LinuxNetLink::_indexForInterface(const char *iface)
 {
 {
 	Mutex::Lock l(_if_m);
 	Mutex::Lock l(_if_m);
 	int interface_index = -1;
 	int interface_index = -1;
-	Hashtable<int, iface_entry>::Iterator iter(_interfaces);
-	int *k = NULL;
-	iface_entry *v = NULL;
-	while(iter.next(k,v)) {
-		if(strcmp(iface, v->ifacename) == 0) {
-			interface_index = v->index;
+	for(std::map<int, iface_entry>::iterator i(_interfaces.begin());i!=_interfaces.end();++i) {
+		if (strcmp(iface, i->second.ifacename) == 0) {
+			interface_index = i->second.index;
 			break;
 			break;
 		}
 		}
 	}
 	}

+ 1 - 3
osdep/LinuxNetLink.hpp

@@ -29,10 +29,8 @@
 #include "../core/InetAddress.hpp"
 #include "../core/InetAddress.hpp"
 #include "../core/MAC.hpp"
 #include "../core/MAC.hpp"
 #include "Thread.hpp"
 #include "Thread.hpp"
-#include "../core/Hashtable.hpp"
 #include "../core/Mutex.hpp"
 #include "../core/Mutex.hpp"
 
 
-
 namespace ZeroTier {
 namespace ZeroTier {
 
 
 struct route_entry {
 struct route_entry {
@@ -107,7 +105,7 @@ private:
         char mac_bin[6];
         char mac_bin[6];
         unsigned int mtu;
         unsigned int mtu;
     };
     };
-    Hashtable<int, iface_entry> _interfaces;
+    std::map<int, iface_entry> _interfaces;
     Mutex _if_m;
     Mutex _if_m;
 
 
     // socket communication vars;
     // socket communication vars;

+ 3 - 1
serviceiocore/GoGlue.cpp

@@ -32,7 +32,9 @@
 #include <ifaddrs.h>
 #include <ifaddrs.h>
 #include <net/if.h>
 #include <net/if.h>
 #include <netinet/in.h>
 #include <netinet/in.h>
+#if __has_include(<netinet/in6_var.h>)
 #include <netinet6/in6_var.h>
 #include <netinet6/in6_var.h>
+#endif
 #include <arpa/inet.h>
 #include <arpa/inet.h>
 #include <errno.h>
 #include <errno.h>
 #ifdef __LINUX__
 #ifdef __LINUX__
@@ -689,7 +691,7 @@ extern "C" void ZT_GoTap_setMtu(ZT_GoTap *tap,unsigned int mtu)
 
 
 extern "C" int ZT_isTemporaryV6Address(const char *ifname,const struct sockaddr_storage *a)
 extern "C" int ZT_isTemporaryV6Address(const char *ifname,const struct sockaddr_storage *a)
 {
 {
-#ifndef __WINDOWS__
+#ifdef IN6_IFF_TEMPORARY
 	static ZT_SOCKET s_tmpV6Socket = ZT_INVALID_SOCKET;
 	static ZT_SOCKET s_tmpV6Socket = ZT_INVALID_SOCKET;
 	static std::mutex s_lock;
 	static std::mutex s_lock;
 	std::lock_guard<std::mutex> l(s_lock);
 	std::lock_guard<std::mutex> l(s_lock);