Browse Source

Work in progress on crypto stuff, refactoring to back out of use of structs for encode/decode as it is questionably portable.

Adam Ierymenko 5 years ago
parent
commit
2b0127c26d

+ 1 - 5
CMakeLists.txt

@@ -93,11 +93,7 @@ endif(WIN32)
 
 
 if (
 if (
 	CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64" OR
 	CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64" OR
-	CMAKE_SYSTEM_PROCESSOR MATCHES "amd64" OR
-	CMAKE_SYSTEM_PROCESSOR MATCHES "i386" OR
-	CMAKE_SYSTEM_PROCESSOR MATCHES "i486" OR
-	CMAKE_SYSTEM_PROCESSOR MATCHES "i586" OR
-	CMAKE_SYSTEM_PROCESSOR MATCHES "i686"
+	CMAKE_SYSTEM_PROCESSOR MATCHES "amd64"
 )
 )
 	message("++ Adding SSE and AES-NI flags for processor ${CMAKE_SYSTEM_PROCESSOR}")
 	message("++ Adding SSE and AES-NI flags for processor ${CMAKE_SYSTEM_PROCESSOR}")
 	add_compile_options(-maes -mrdrnd -mpclmul -msse -msse2 -mssse3)
 	add_compile_options(-maes -mrdrnd -mpclmul -msse -msse2 -mssse3)

+ 6 - 23
include/ZeroTierCore.h

@@ -29,25 +29,6 @@
 #include <sys/socket.h>
 #include <sys/socket.h>
 #endif
 #endif
 
 
-/* ZT_PACKED_STRUCT encloses structs whose contents should be bit-packed.
- * Nearly all compilers support this. These macros detect the compiler and
- * define it correctly for gcc/icc/clang or MSC. */
-#ifndef ZT_PACKED_STRUCT
-#if defined(__GCC__) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || defined(__INTEL_COMPILER) || defined(__clang__)
-#define ZT_PACKED_STRUCT(D) D __attribute__((packed))
-#define ZT_PACKED_STRUCT_START
-#define ZT_PACKED_STRUCT_END __attribute__((packed))
-#endif
-#ifdef _MSC_VER
-#define ZT_PACKED_STRUCT(D) __pragma(pack(push,1)) D __pragma(pack(pop))
-#define ZT_PACKED_STRUCT_START __pragma(pack(push,1))
-#define ZT_PACKED_STRUCT_END __pragma(pack(pop))
-#endif
-#endif
-#ifndef ZT_PACKED_STRUCT
-#error Missing a macro to define ZT_PACKED_STRUCT for your compiler.
-#endif
-
 #ifdef __cplusplus
 #ifdef __cplusplus
 #include <cstdint>
 #include <cstdint>
 extern "C" {
 extern "C" {
@@ -278,7 +259,6 @@ extern "C" {
 
 
 /* ----------------------------------------------------------------------------------------------------------------- */
 /* ----------------------------------------------------------------------------------------------------------------- */
 
 
-
 /**
 /**
  * Identity type codes
  * Identity type codes
  */
  */
@@ -297,7 +277,7 @@ typedef void ZT_Identity;
 /**
 /**
  * Full identity fingerprint with address and 384-bit hash of public key(s)
  * Full identity fingerprint with address and 384-bit hash of public key(s)
  */
  */
-ZT_PACKED_STRUCT(struct _ZT_Fingerprint
+typedef struct
 {
 {
 	/**
 	/**
 	 * Short address (only least significant 40 bits are used)
 	 * Short address (only least significant 40 bits are used)
@@ -308,8 +288,7 @@ ZT_PACKED_STRUCT(struct _ZT_Fingerprint
 	 * 384-bit hash of identity public key(s)
 	 * 384-bit hash of identity public key(s)
 	 */
 	 */
 	uint8_t hash[48];
 	uint8_t hash[48];
-});
-typedef struct _ZT_Fingerprint ZT_Fingerprint;
+} ZT_Fingerprint;
 
 
 /**
 /**
  * Credential type IDs
  * Credential type IDs
@@ -449,6 +428,8 @@ enum ZT_TraceCredentialRejectionReason
 	ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID = 4
 	ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID = 4
 };
 };
 
 
+#if 0
+
 /**
 /**
  * Physical path address from a trace event
  * Physical path address from a trace event
  *
  *
@@ -623,6 +604,8 @@ _ZT_TRACE_EVENT_STRUCT_END()
 #undef _ZT_TRACE_EVENT_STRUCT_START
 #undef _ZT_TRACE_EVENT_STRUCT_START
 #undef _ZT_TRACE_EVENT_STRUCT_END
 #undef _ZT_TRACE_EVENT_STRUCT_END
 
 
+#endif
+
 /****************************************************************************/
 /****************************************************************************/
 
 
 /**
 /**

+ 5 - 6
node/AES.hpp

@@ -23,10 +23,9 @@
 
 
 #ifndef ZT_AES_NO_ACCEL
 #ifndef ZT_AES_NO_ACCEL
 #ifdef ZT_ARCH_X64
 #ifdef ZT_ARCH_X64
+#include <xmmintrin.h>
 #include <emmintrin.h>
 #include <emmintrin.h>
-#include <smmintrin.h>
 #include <immintrin.h>
 #include <immintrin.h>
-#include <wmmintrin.h>
 #define ZT_AES_AESNI 1
 #define ZT_AES_AESNI 1
 #endif
 #endif
 #endif
 #endif
@@ -57,7 +56,7 @@ 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 // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
+	ZT_INLINE AES() noexcept
 	{
 	{
 		Utils::memoryLock(this,sizeof(AES));
 		Utils::memoryLock(this,sizeof(AES));
 	}
 	}
@@ -67,7 +66,7 @@ public:
 	 *
 	 *
 	 * @param key 256-bit key
 	 * @param key 256-bit key
 	 */
 	 */
-	explicit ZT_INLINE AES(const void *const key) noexcept // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
+	explicit ZT_INLINE AES(const void *const key) noexcept
 	{
 	{
 		Utils::memoryLock(this,sizeof(AES));
 		Utils::memoryLock(this,sizeof(AES));
 		this->init(key);
 		this->init(key);
@@ -264,7 +263,7 @@ 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 : // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
+		ZT_INLINE GMACSIVEncryptor(const AES &k0,const AES &k1) noexcept :
 			_gmac(k0),
 			_gmac(k0),
 			_ctr(k1) {}
 			_ctr(k1) {}
 
 
@@ -383,7 +382,7 @@ public:
 	class GMACSIVDecryptor
 	class GMACSIVDecryptor
 	{
 	{
 	public:
 	public:
-		ZT_INLINE GMACSIVDecryptor(const AES &k0,const AES &k1) noexcept : // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
+		ZT_INLINE GMACSIVDecryptor(const AES &k0,const AES &k1) noexcept :
 			_ctr(k1),
 			_ctr(k1),
 			_gmac(k0) {}
 			_gmac(k0) {}
 
 

+ 1 - 1
node/Address.hpp

@@ -107,7 +107,7 @@ public:
 
 
 	ZT_INLINE unsigned long hashCode() const noexcept { return (unsigned long)_a; }
 	ZT_INLINE unsigned long hashCode() const noexcept { return (unsigned long)_a; }
 
 
-	ZT_INLINE operator bool() const noexcept { return (_a != 0); } // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
+	ZT_INLINE operator bool() const noexcept { return (_a != 0); }
 
 
 	ZT_INLINE bool operator==(const Address &a) const noexcept { return _a == a._a; }
 	ZT_INLINE bool operator==(const Address &a) const noexcept { return _a == a._a; }
 	ZT_INLINE bool operator!=(const Address &a) const noexcept { return _a != a._a; }
 	ZT_INLINE bool operator!=(const Address &a) const noexcept { return _a != a._a; }

+ 1 - 0
node/CMakeLists.txt

@@ -32,6 +32,7 @@ set(core_headers
 	OS.hpp
 	OS.hpp
 	Path.hpp
 	Path.hpp
 	Peer.hpp
 	Peer.hpp
+	PeerList.hpp
 	Poly1305.hpp
 	Poly1305.hpp
 	Protocol.hpp
 	Protocol.hpp
 	RuntimeEnvironment.hpp
 	RuntimeEnvironment.hpp

+ 1 - 1
node/Capability.hpp

@@ -57,7 +57,7 @@ class Capability : public Credential
 public:
 public:
 	static constexpr ZT_CredentialType credentialType() noexcept { return ZT_CREDENTIAL_TYPE_CAPABILITY; }
 	static constexpr ZT_CredentialType credentialType() noexcept { return ZT_CREDENTIAL_TYPE_CAPABILITY; }
 
 
-	ZT_INLINE Capability() noexcept { memoryZero(this); } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
+	ZT_INLINE Capability() noexcept { memoryZero(this); }
 
 
 	/**
 	/**
 	 * @param id Capability ID
 	 * @param id Capability ID

+ 5 - 0
node/Constants.hpp

@@ -149,6 +149,11 @@
  */
  */
 #define ZT_PEER_HELLO_INTERVAL 120000LL
 #define ZT_PEER_HELLO_INTERVAL 120000LL
 
 
+/**
+ * Timeout for peers being alive
+ */
+#define ZT_PEER_ALIVE_TIMEOUT ((ZT_PEER_HELLO_INTERVAL * 2) + 5000)
+
 /**
 /**
  * Global timeout for peers in milliseconds
  * Global timeout for peers in milliseconds
  *
  *

+ 20 - 6
node/Containers.hpp

@@ -31,18 +31,19 @@
 namespace ZeroTier {
 namespace ZeroTier {
 
 
 #ifdef __CPP11__
 #ifdef __CPP11__
-struct _MapHasher
+
+struct intl_MapHasher
 {
 {
 	template<typename O>
 	template<typename O>
 	std::size_t operator()(const O &obj) const noexcept { return (std::size_t)obj.hashCode(); }
 	std::size_t operator()(const O &obj) const noexcept { return (std::size_t)obj.hashCode(); }
-	std::size_t operator()(const uint64_t i) const noexcept { return (std::size_t)Utils::hash64(i ^ Utils::s_mapNonce); }
-	std::size_t operator()(const int64_t i) const noexcept { return (std::size_t)Utils::hash64((uint64_t)i ^ Utils::s_mapNonce); }
-	std::size_t operator()(const uint32_t i) const noexcept { return (std::size_t)Utils::hash32(i ^ (uint32_t)Utils::s_mapNonce); }
-	std::size_t operator()(const int32_t i) const noexcept { return (std::size_t)Utils::hash32((uint32_t)i ^ (uint32_t)Utils::s_mapNonce); }
+	std::size_t operator()(const uint64_t i) const noexcept { return (std::size_t)Utils::hash64(i + Utils::s_mapNonce); }
+	std::size_t operator()(const int64_t i) const noexcept { return (std::size_t)Utils::hash64((uint64_t)i + Utils::s_mapNonce); }
+	std::size_t operator()(const uint32_t i) const noexcept { return (std::size_t)Utils::hash32(i + (uint32_t)Utils::s_mapNonce); }
+	std::size_t operator()(const int32_t i) const noexcept { return (std::size_t)Utils::hash32((uint32_t)i + (uint32_t)Utils::s_mapNonce); }
 };
 };
 
 
 template<typename K,typename V>
 template<typename K,typename V>
-class Map : public std::unordered_map< K,V,_MapHasher,std::equal_to<K>,Utils::Mallocator< std::pair<const K,V> > >
+class Map : public std::unordered_map< K,V,intl_MapHasher,std::equal_to<K>,Utils::Mallocator< std::pair<const K,V> > >
 {
 {
 public:
 public:
 	ZT_INLINE V *get(const K &key) noexcept
 	ZT_INLINE V *get(const K &key) noexcept
@@ -66,7 +67,14 @@ public:
 		this->emplace(key,value);
 		this->emplace(key,value);
 	}
 	}
 };
 };
+
+template<typename K,typename V>
+class MultiMap : public std::unordered_multimap< K,V,intl_MapHasher,std::equal_to<K>,Utils::Mallocator< std::pair<const K,V> > >
+{
+};
+
 #else
 #else
+
 template<typename K,typename V>
 template<typename K,typename V>
 class Map : public std::map< K,V,std::less<K>,Utils::Mallocator< std::pair<const K,V> > >
 class Map : public std::map< K,V,std::less<K>,Utils::Mallocator< std::pair<const K,V> > >
 {
 {
@@ -92,6 +100,12 @@ public:
 		(*this)[key] = value;
 		(*this)[key] = value;
 	}
 	}
 };
 };
+
+template<typename K,typename V>
+class MultiMap : public std::multimap< K,V,std::less<K>,Utils::Mallocator< std::pair<const K,V> > >
+{
+};
+
 #endif
 #endif
 
 
 template<typename K,typename V>
 template<typename K,typename V>

+ 0 - 4
node/Defragmenter.hpp

@@ -22,10 +22,6 @@
 #include "FCV.hpp"
 #include "FCV.hpp"
 #include "Containers.hpp"
 #include "Containers.hpp"
 
 
-#include <cstring>
-#include <cstdlib>
-#include <vector>
-
 namespace ZeroTier {
 namespace ZeroTier {
 
 
 /**
 /**

+ 0 - 4
node/Dictionary.cpp

@@ -19,10 +19,6 @@ Dictionary::Dictionary()
 {
 {
 }
 }
 
 
-Dictionary::~Dictionary()
-{
-}
-
 std::vector<uint8_t> &Dictionary::operator[](const char *k)
 std::vector<uint8_t> &Dictionary::operator[](const char *k)
 {
 {
 	return m_entries[s_toKey(k)];
 	return m_entries[s_toKey(k)];

+ 0 - 3
node/Dictionary.hpp

@@ -20,8 +20,6 @@
 #include "Buf.hpp"
 #include "Buf.hpp"
 #include "Containers.hpp"
 #include "Containers.hpp"
 
 
-#include <cstdint>
-
 namespace ZeroTier {
 namespace ZeroTier {
 
 
 /**
 /**
@@ -42,7 +40,6 @@ class Dictionary
 {
 {
 public:
 public:
 	Dictionary();
 	Dictionary();
-	~Dictionary();
 
 
 	/**
 	/**
 	 * Get a reference to a value
 	 * Get a reference to a value

+ 3 - 3
node/Expect.hpp

@@ -49,7 +49,7 @@ public:
 	 */
 	 */
 	ZT_INLINE void sending(const uint64_t packetId,const int64_t now) noexcept
 	ZT_INLINE void sending(const uint64_t packetId,const int64_t now) noexcept
 	{
 	{
-		_packetIdSent[Utils::hash64(packetId ^ Utils::s_mapNonce) % ZT_EXPECT_BUCKETS].store((uint32_t)(now / ZT_EXPECT_TTL));
+		m_packetIdSent[Utils::hash64(packetId ^ Utils::s_mapNonce) % ZT_EXPECT_BUCKETS].store((uint32_t)(now / ZT_EXPECT_TTL));
 	}
 	}
 
 
 	/**
 	/**
@@ -64,12 +64,12 @@ public:
 	 */
 	 */
 	ZT_INLINE bool expecting(const uint64_t inRePacketId,const int64_t now) noexcept
 	ZT_INLINE bool expecting(const uint64_t inRePacketId,const int64_t now) noexcept
 	{
 	{
-		return (((now / ZT_EXPECT_TTL) - (int64_t)_packetIdSent[(unsigned long)Utils::hash64(inRePacketId ^ Utils::s_mapNonce) % ZT_EXPECT_BUCKETS].exchange(0)) <= 1);
+		return (((now / ZT_EXPECT_TTL) - (int64_t)m_packetIdSent[(unsigned long)Utils::hash64(inRePacketId ^ Utils::s_mapNonce) % ZT_EXPECT_BUCKETS].exchange(0)) <= 1);
 	}
 	}
 
 
 private:
 private:
 	// Each bucket contains a timestamp in units of the max expect duration.
 	// Each bucket contains a timestamp in units of the max expect duration.
-	std::atomic<uint32_t> _packetIdSent[ZT_EXPECT_BUCKETS];
+	std::atomic<uint32_t> m_packetIdSent[ZT_EXPECT_BUCKETS];
 };
 };
 
 
 } // namespace ZeroTier
 } // namespace ZeroTier

+ 1 - 1
node/FCV.hpp

@@ -49,7 +49,7 @@ public:
 	/**
 	/**
 	 * @return True if this FCV is trivially copyable, which means its type is also.
 	 * @return True if this FCV is trivially copyable, which means its type is also.
 	 */
 	 */
-	static constexpr bool isTriviallyCopyable() noexcept { return isTriviallyCopyable(reinterpret_cast<const T *>(0)); }
+	static constexpr bool isTriviallyCopyable() noexcept { return ZeroTier::isTriviallyCopyable(reinterpret_cast<const T *>(nullptr)); }
 
 
 	ZT_INLINE FCV() noexcept : _s(0) {} // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
 	ZT_INLINE FCV() noexcept : _s(0) {} // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
 	ZT_INLINE FCV(const FCV &v) : _s(0) { *this = v; } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
 	ZT_INLINE FCV(const FCV &v) : _s(0) { *this = v; } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)

+ 13 - 13
node/Fingerprint.hpp

@@ -43,15 +43,15 @@ public:
 	 */
 	 */
 	ZT_INLINE Fingerprint() noexcept { memoryZero(this); } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
 	ZT_INLINE Fingerprint() noexcept { memoryZero(this); } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
 
 
-	ZT_INLINE Address address() const noexcept { return Address(_fp.address); }
-	ZT_INLINE const uint8_t *hash() const noexcept { return _fp.hash; }
-	ZT_INLINE ZT_Fingerprint *apiFingerprint() noexcept { return &_fp; }
-	ZT_INLINE const ZT_Fingerprint *apiFingerprint() const noexcept { return &_fp; }
+	ZT_INLINE Address address() const noexcept { return Address(m_cfp.address); }
+	ZT_INLINE const uint8_t *hash() const noexcept { return m_cfp.hash; }
+	ZT_INLINE ZT_Fingerprint *apiFingerprint() noexcept { return &m_cfp; }
+	ZT_INLINE const ZT_Fingerprint *apiFingerprint() const noexcept { return &m_cfp; }
 
 
 	/**
 	/**
 	 * @return True if hash is not all zero (missing/unspecified)
 	 * @return True if hash is not all zero (missing/unspecified)
 	 */
 	 */
-	ZT_INLINE bool haveHash() const noexcept { return (!Utils::allZero(_fp.hash,sizeof(_fp.hash))); }
+	ZT_INLINE bool haveHash() const noexcept { return (!Utils::allZero(m_cfp.hash, sizeof(m_cfp.hash))); }
 
 
 	/**
 	/**
 	 * Get a base32-encoded representation of this fingerprint
 	 * Get a base32-encoded representation of this fingerprint
@@ -62,7 +62,7 @@ public:
 	{
 	{
 		uint8_t tmp[48 + 5];
 		uint8_t tmp[48 + 5];
 		address().copyTo(tmp);
 		address().copyTo(tmp);
-		Utils::copy<48>(tmp + 5,_fp.hash);
+		Utils::copy<48>(tmp + 5, m_cfp.hash);
 		Utils::b32e(tmp,sizeof(tmp),s,ZT_FINGERPRINT_STRING_BUFFER_LENGTH);
 		Utils::b32e(tmp,sizeof(tmp),s,ZT_FINGERPRINT_STRING_BUFFER_LENGTH);
 		s[ZT_FINGERPRINT_STRING_BUFFER_LENGTH-1] = 0; // sanity check, ensure always zero terminated
 		s[ZT_FINGERPRINT_STRING_BUFFER_LENGTH-1] = 0; // sanity check, ensure always zero terminated
 	}
 	}
@@ -78,25 +78,25 @@ public:
 		uint8_t tmp[48 + 5];
 		uint8_t tmp[48 + 5];
 		if (Utils::b32d(s,tmp,sizeof(tmp)) != sizeof(tmp))
 		if (Utils::b32d(s,tmp,sizeof(tmp)) != sizeof(tmp))
 			return false;
 			return false;
-		_fp.address = Address(tmp).toInt();
-		Utils::copy<48>(_fp.hash,tmp + 5);
+		m_cfp.address = Address(tmp).toInt();
+		Utils::copy<48>(m_cfp.hash, tmp + 5);
 		return true;
 		return true;
 	}
 	}
 
 
 	ZT_INLINE void zero() noexcept { memoryZero(this); }
 	ZT_INLINE void zero() noexcept { memoryZero(this); }
-	ZT_INLINE unsigned long hashCode() const noexcept { return _fp.address; }
+	ZT_INLINE unsigned long hashCode() const noexcept { return m_cfp.address; }
 
 
-	ZT_INLINE operator bool() const noexcept { return (_fp.address != 0); } // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
+	ZT_INLINE operator bool() const noexcept { return (m_cfp.address != 0); } // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
 
 
-	ZT_INLINE bool operator==(const Fingerprint &h) const noexcept { return ((_fp.address == h._fp.address) && (memcmp(_fp.hash,h._fp.hash,ZT_FINGERPRINT_HASH_SIZE) == 0)); }
+	ZT_INLINE bool operator==(const Fingerprint &h) const noexcept { return ((m_cfp.address == h.m_cfp.address) && (memcmp(m_cfp.hash, h.m_cfp.hash, ZT_FINGERPRINT_HASH_SIZE) == 0)); }
 	ZT_INLINE bool operator!=(const Fingerprint &h) const noexcept { return !(*this == h); }
 	ZT_INLINE bool operator!=(const Fingerprint &h) const noexcept { return !(*this == h); }
-	ZT_INLINE bool operator<(const Fingerprint &h) const noexcept { return ((_fp.address < h._fp.address) || ((_fp.address == h._fp.address) && (memcmp(_fp.hash,h._fp.hash,ZT_FINGERPRINT_HASH_SIZE) < 0))); }
+	ZT_INLINE bool operator<(const Fingerprint &h) const noexcept { return ((m_cfp.address < h.m_cfp.address) || ((m_cfp.address == h.m_cfp.address) && (memcmp(m_cfp.hash, h.m_cfp.hash, ZT_FINGERPRINT_HASH_SIZE) < 0))); }
 	ZT_INLINE bool operator>(const Fingerprint &h) const noexcept { return (h < *this); }
 	ZT_INLINE bool operator>(const Fingerprint &h) const noexcept { return (h < *this); }
 	ZT_INLINE bool operator<=(const Fingerprint &h) const noexcept { return !(h < *this); }
 	ZT_INLINE bool operator<=(const Fingerprint &h) const noexcept { return !(h < *this); }
 	ZT_INLINE bool operator>=(const Fingerprint &h) const noexcept { return !(*this < h); }
 	ZT_INLINE bool operator>=(const Fingerprint &h) const noexcept { return !(*this < h); }
 
 
 private:
 private:
-	ZT_Fingerprint _fp;
+	ZT_Fingerprint m_cfp;
 };
 };
 
 
 static_assert(sizeof(Fingerprint) == sizeof(ZT_Fingerprint),"Fingerprint should be the same size as the underlying C ZT_Fingerprint");
 static_assert(sizeof(Fingerprint) == sizeof(ZT_Fingerprint),"Fingerprint should be the same size as the underlying C ZT_Fingerprint");

+ 102 - 102
node/Identity.cpp

@@ -176,8 +176,8 @@ const Identity Identity::NIL;
 
 
 bool Identity::generate(const Type t)
 bool Identity::generate(const Type t)
 {
 {
-	_type = t;
-	_hasPrivate = true;
+	m_type = t;
+	m_hasPrivate = true;
 
 
 	switch(t) {
 	switch(t) {
 		case C25519: {
 		case C25519: {
@@ -186,9 +186,9 @@ bool Identity::generate(const Type t)
 			uint8_t digest[64];
 			uint8_t digest[64];
 			char *const genmem = new char[ZT_V0_IDENTITY_GEN_MEMORY];
 			char *const genmem = new char[ZT_V0_IDENTITY_GEN_MEMORY];
 			do {
 			do {
-				C25519::generateSatisfying(identityV0ProofOfWorkCriteria(digest,genmem),_pub.c25519,_priv.c25519);
-				_address.setTo(digest + 59);
-			} while (_address.isReserved());
+				C25519::generateSatisfying(identityV0ProofOfWorkCriteria(digest,genmem), m_pub.c25519, m_priv.c25519);
+				m_address.setTo(digest + 59);
+			} while (m_address.isReserved());
 			delete[] genmem;
 			delete[] genmem;
 			_computeHash();
 			_computeHash();
 		} break;
 		} break;
@@ -201,21 +201,21 @@ bool Identity::generate(const Type t)
 				// Loop until we pass the PoW criteria. The nonce is only 8 bits, so generate
 				// Loop until we pass the PoW criteria. The nonce is only 8 bits, so generate
 				// some new key material every time it wraps. The ECC384 generator is slightly
 				// some new key material every time it wraps. The ECC384 generator is slightly
 				// faster so use that one.
 				// faster so use that one.
-				_pub.nonce = 0;
-				C25519::generateCombined(_pub.c25519,_priv.c25519);
-				ECC384GenerateKey(_pub.p384,_priv.p384);
+				m_pub.nonce = 0;
+				C25519::generateCombined(m_pub.c25519, m_priv.c25519);
+				ECC384GenerateKey(m_pub.p384, m_priv.p384);
 				for(;;) {
 				for(;;) {
-					if (identityV1ProofOfWorkCriteria(&_pub,sizeof(_pub),b))
+					if (identityV1ProofOfWorkCriteria(&m_pub, sizeof(m_pub), b))
 						break;
 						break;
-					if (++_pub.nonce == 0)
-						ECC384GenerateKey(_pub.p384,_priv.p384);
+					if (++m_pub.nonce == 0)
+						ECC384GenerateKey(m_pub.p384, m_priv.p384);
 				}
 				}
 
 
 				// If we passed PoW then check that the address is valid, otherwise loop
 				// If we passed PoW then check that the address is valid, otherwise loop
 				// back around and run the whole process again.
 				// back around and run the whole process again.
 				_computeHash();
 				_computeHash();
-				_address.setTo(_fp.hash());
-				if (!_address.isReserved())
+				m_address.setTo(m_fp.hash());
+				if (!m_address.isReserved())
 					break;
 					break;
 			}
 			}
 			free(b);
 			free(b);
@@ -231,24 +231,24 @@ bool Identity::generate(const Type t)
 bool Identity::locallyValidate() const noexcept
 bool Identity::locallyValidate() const noexcept
 {
 {
 	try {
 	try {
-		if ((!_address.isReserved()) && (_address)) {
-			switch (_type) {
+		if ((!m_address.isReserved()) && (m_address)) {
+			switch (m_type) {
 
 
 				case C25519: {
 				case C25519: {
 					uint8_t digest[64];
 					uint8_t digest[64];
 					char *genmem = new char[ZT_V0_IDENTITY_GEN_MEMORY];
 					char *genmem = new char[ZT_V0_IDENTITY_GEN_MEMORY];
-					identityV0ProofOfWorkFrankenhash(_pub.c25519,ZT_C25519_COMBINED_PUBLIC_KEY_SIZE,digest,genmem);
+					identityV0ProofOfWorkFrankenhash(m_pub.c25519, ZT_C25519_COMBINED_PUBLIC_KEY_SIZE, digest, genmem);
 					delete[] genmem;
 					delete[] genmem;
-					return ((_address == Address(digest + 59)) && (digest[0] < 17));
+					return ((m_address == Address(digest + 59)) && (digest[0] < 17));
 				}
 				}
 
 
 				case P384: {
 				case P384: {
-					if (_address != Address(_fp.hash()))
+					if (m_address != Address(m_fp.hash()))
 						return false;
 						return false;
 					uint64_t *const b = (uint64_t *)malloc(ZT_IDENTITY_V1_POW_MEMORY_SIZE * 8); // NOLINT(hicpp-use-auto,modernize-use-auto)
 					uint64_t *const b = (uint64_t *)malloc(ZT_IDENTITY_V1_POW_MEMORY_SIZE * 8); // NOLINT(hicpp-use-auto,modernize-use-auto)
 					if (!b)
 					if (!b)
 						return false;
 						return false;
-					const bool ok = identityV1ProofOfWorkCriteria(&_pub,sizeof(_pub),b);
+					const bool ok = identityV1ProofOfWorkCriteria(&m_pub, sizeof(m_pub), b);
 					free(b);
 					free(b);
 					return ok;
 					return ok;
 				}
 				}
@@ -261,15 +261,15 @@ bool Identity::locallyValidate() const noexcept
 
 
 void Identity::hashWithPrivate(uint8_t h[ZT_FINGERPRINT_HASH_SIZE]) const
 void Identity::hashWithPrivate(uint8_t h[ZT_FINGERPRINT_HASH_SIZE]) const
 {
 {
-	if (_hasPrivate) {
-		switch (_type) {
+	if (m_hasPrivate) {
+		switch (m_type) {
 
 
 			case C25519:
 			case C25519:
-				SHA384(h,_pub.c25519,ZT_C25519_COMBINED_PUBLIC_KEY_SIZE,_priv.c25519,ZT_C25519_COMBINED_PRIVATE_KEY_SIZE);
+				SHA384(h, m_pub.c25519, ZT_C25519_COMBINED_PUBLIC_KEY_SIZE, m_priv.c25519, ZT_C25519_COMBINED_PRIVATE_KEY_SIZE);
 				break;
 				break;
 
 
 			case P384:
 			case P384:
-				SHA384(h,&_pub,sizeof(_pub),&_priv,sizeof(_priv));
+				SHA384(h, &m_pub, sizeof(m_pub), &m_priv, sizeof(m_priv));
 				break;
 				break;
 
 
 		}
 		}
@@ -280,20 +280,20 @@ void Identity::hashWithPrivate(uint8_t h[ZT_FINGERPRINT_HASH_SIZE]) const
 
 
 unsigned int Identity::sign(const void *data,unsigned int len,void *sig,unsigned int siglen) const
 unsigned int Identity::sign(const void *data,unsigned int len,void *sig,unsigned int siglen) const
 {
 {
-	if (_hasPrivate) {
-		switch(_type) {
+	if (m_hasPrivate) {
+		switch(m_type) {
 
 
 			case C25519:
 			case C25519:
 				if (siglen >= ZT_C25519_SIGNATURE_LEN) {
 				if (siglen >= ZT_C25519_SIGNATURE_LEN) {
-					C25519::sign(_priv.c25519,_pub.c25519,data,len,sig);
+					C25519::sign(m_priv.c25519, m_pub.c25519, data, len, sig);
 					return ZT_C25519_SIGNATURE_LEN;
 					return ZT_C25519_SIGNATURE_LEN;
 				}
 				}
 
 
 			case P384:
 			case P384:
 				if (siglen >= ZT_ECC384_SIGNATURE_SIZE) {
 				if (siglen >= ZT_ECC384_SIGNATURE_SIZE) {
 					uint8_t h[48];
 					uint8_t h[48];
-					SHA384(h,data,len,&_pub,ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE); // include C25519 public key in hash
-					ECC384ECDSASign(_priv.p384,h,(uint8_t *)sig);
+					SHA384(h, data, len, &m_pub, ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE); // include C25519 public key in hash
+					ECC384ECDSASign(m_priv.p384, h, (uint8_t *)sig);
 					return ZT_ECC384_SIGNATURE_SIZE;
 					return ZT_ECC384_SIGNATURE_SIZE;
 				}
 				}
 
 
@@ -304,16 +304,16 @@ unsigned int Identity::sign(const void *data,unsigned int len,void *sig,unsigned
 
 
 bool Identity::verify(const void *data,unsigned int len,const void *sig,unsigned int siglen) const
 bool Identity::verify(const void *data,unsigned int len,const void *sig,unsigned int siglen) const
 {
 {
-	switch(_type) {
+	switch(m_type) {
 
 
 		case C25519:
 		case C25519:
-			return C25519::verify(_pub.c25519,data,len,sig,siglen);
+			return C25519::verify(m_pub.c25519, data, len, sig, siglen);
 
 
 		case P384:
 		case P384:
 			if (siglen == ZT_ECC384_SIGNATURE_SIZE) {
 			if (siglen == ZT_ECC384_SIGNATURE_SIZE) {
 				uint8_t h[48];
 				uint8_t h[48];
-				SHA384(h,data,len,&_pub,ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE);
-				return ECC384ECDSAVerify(_pub.p384,h,(const uint8_t *)sig);
+				SHA384(h, data, len, &m_pub, ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE);
+				return ECC384ECDSAVerify(m_pub.p384, h, (const uint8_t *)sig);
 			}
 			}
 			break;
 			break;
 
 
@@ -325,34 +325,34 @@ bool Identity::agree(const Identity &id,uint8_t key[ZT_SYMMETRIC_KEY_SIZE]) cons
 {
 {
 	uint8_t rawkey[128];
 	uint8_t rawkey[128];
 	uint8_t h[64];
 	uint8_t h[64];
-	if (_hasPrivate) {
-		if (_type == C25519) {
+	if (m_hasPrivate) {
+		if (m_type == C25519) {
 
 
-			if ((id._type == C25519)||(id._type == P384)) {
+			if ((id.m_type == C25519) || (id.m_type == P384)) {
 				// If we are a C25519 key we can agree with another C25519 key or with only the
 				// If we are a C25519 key we can agree with another C25519 key or with only the
 				// C25519 portion of a type 1 P-384 key.
 				// C25519 portion of a type 1 P-384 key.
-				C25519::agree(_priv.c25519,id._pub.c25519,rawkey);
+				C25519::agree(m_priv.c25519, id.m_pub.c25519, rawkey);
 				SHA512(h,rawkey,ZT_C25519_ECDH_SHARED_SECRET_SIZE);
 				SHA512(h,rawkey,ZT_C25519_ECDH_SHARED_SECRET_SIZE);
 				Utils::copy<ZT_SYMMETRIC_KEY_SIZE>(key,h);
 				Utils::copy<ZT_SYMMETRIC_KEY_SIZE>(key,h);
 				return true;
 				return true;
 			}
 			}
 
 
-		} else if (_type == P384) {
+		} else if (m_type == P384) {
 
 
-			if (id._type == P384) {
+			if (id.m_type == P384) {
 				// For another P384 identity we execute DH agreement with BOTH keys and then
 				// For another P384 identity we execute DH agreement with BOTH keys and then
 				// hash the results together. For those (cough FIPS cough) who only consider
 				// hash the results together. For those (cough FIPS cough) who only consider
 				// P384 to be kosher, the C25519 secret can be considered a "salt"
 				// P384 to be kosher, the C25519 secret can be considered a "salt"
 				// or something. For those who don't trust P384 this means the privacy of
 				// or something. For those who don't trust P384 this means the privacy of
 				// your traffic is also protected by C25519.
 				// your traffic is also protected by C25519.
-				C25519::agree(_priv.c25519,id._pub.c25519,rawkey);
-				ECC384ECDH(id._pub.p384,_priv.p384,rawkey + ZT_C25519_ECDH_SHARED_SECRET_SIZE);
+				C25519::agree(m_priv.c25519, id.m_pub.c25519, rawkey);
+				ECC384ECDH(id.m_pub.p384, m_priv.p384, rawkey + ZT_C25519_ECDH_SHARED_SECRET_SIZE);
 				SHA384(h,rawkey,ZT_C25519_ECDH_SHARED_SECRET_SIZE + ZT_ECC384_SHARED_SECRET_SIZE);
 				SHA384(h,rawkey,ZT_C25519_ECDH_SHARED_SECRET_SIZE + ZT_ECC384_SHARED_SECRET_SIZE);
 				Utils::copy<ZT_SYMMETRIC_KEY_SIZE>(key,h);
 				Utils::copy<ZT_SYMMETRIC_KEY_SIZE>(key,h);
 				return true;
 				return true;
-			} else if (id._type == C25519) {
+			} else if (id.m_type == C25519) {
 				// If the other identity is a C25519 identity we can agree using only that type.
 				// If the other identity is a C25519 identity we can agree using only that type.
-				C25519::agree(_priv.c25519,id._pub.c25519,rawkey);
+				C25519::agree(m_priv.c25519, id.m_pub.c25519, rawkey);
 				SHA512(h,rawkey,ZT_C25519_ECDH_SHARED_SECRET_SIZE);
 				SHA512(h,rawkey,ZT_C25519_ECDH_SHARED_SECRET_SIZE);
 				Utils::copy<ZT_SYMMETRIC_KEY_SIZE>(key,h);
 				Utils::copy<ZT_SYMMETRIC_KEY_SIZE>(key,h);
 				return true;
 				return true;
@@ -366,20 +366,20 @@ bool Identity::agree(const Identity &id,uint8_t key[ZT_SYMMETRIC_KEY_SIZE]) cons
 char *Identity::toString(bool includePrivate,char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]) const
 char *Identity::toString(bool includePrivate,char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]) const
 {
 {
 	char *p = buf;
 	char *p = buf;
-	_address.toString(p);
+	m_address.toString(p);
 	p += 10;
 	p += 10;
 	*(p++) = ':';
 	*(p++) = ':';
 
 
-	switch(_type) {
+	switch(m_type) {
 
 
 		case C25519: {
 		case C25519: {
 			*(p++) = '0';
 			*(p++) = '0';
 			*(p++) = ':';
 			*(p++) = ':';
-			Utils::hex(_pub.c25519,ZT_C25519_COMBINED_PUBLIC_KEY_SIZE,p);
+			Utils::hex(m_pub.c25519, ZT_C25519_COMBINED_PUBLIC_KEY_SIZE, p);
 			p += ZT_C25519_COMBINED_PUBLIC_KEY_SIZE * 2;
 			p += ZT_C25519_COMBINED_PUBLIC_KEY_SIZE * 2;
-			if ((_hasPrivate)&&(includePrivate)) {
+			if ((m_hasPrivate) && (includePrivate)) {
 				*(p++) = ':';
 				*(p++) = ':';
-				Utils::hex(_priv.c25519,ZT_C25519_COMBINED_PRIVATE_KEY_SIZE,p);
+				Utils::hex(m_priv.c25519, ZT_C25519_COMBINED_PRIVATE_KEY_SIZE, p);
 				p += ZT_C25519_COMBINED_PRIVATE_KEY_SIZE * 2;
 				p += ZT_C25519_COMBINED_PRIVATE_KEY_SIZE * 2;
 			}
 			}
 			*p = (char)0;
 			*p = (char)0;
@@ -389,12 +389,12 @@ char *Identity::toString(bool includePrivate,char buf[ZT_IDENTITY_STRING_BUFFER_
 		case P384: {
 		case P384: {
 			*(p++) = '1';
 			*(p++) = '1';
 			*(p++) = ':';
 			*(p++) = ':';
-			int el = Utils::b32e((const uint8_t *)(&_pub),sizeof(_pub),p,(int)(ZT_IDENTITY_STRING_BUFFER_LENGTH - (uintptr_t)(p - buf)));
+			int el = Utils::b32e((const uint8_t *)(&m_pub), sizeof(m_pub), p, (int)(ZT_IDENTITY_STRING_BUFFER_LENGTH - (uintptr_t)(p - buf)));
 			if (el <= 0) return nullptr;
 			if (el <= 0) return nullptr;
 			p += el;
 			p += el;
-			if ((_hasPrivate)&&(includePrivate)) {
+			if ((m_hasPrivate) && (includePrivate)) {
 				*(p++) = ':';
 				*(p++) = ':';
-				el = Utils::b32e((const uint8_t *)(&_priv),sizeof(_priv),p,(int)(ZT_IDENTITY_STRING_BUFFER_LENGTH - (uintptr_t)(p - buf)));
+				el = Utils::b32e((const uint8_t *)(&m_priv), sizeof(m_priv), p, (int)(ZT_IDENTITY_STRING_BUFFER_LENGTH - (uintptr_t)(p - buf)));
 				if (el <= 0) return nullptr;
 				if (el <= 0) return nullptr;
 				p += el;
 				p += el;
 			}
 			}
@@ -409,17 +409,17 @@ char *Identity::toString(bool includePrivate,char buf[ZT_IDENTITY_STRING_BUFFER_
 
 
 bool Identity::fromString(const char *str)
 bool Identity::fromString(const char *str)
 {
 {
-	_fp.zero();
-	_hasPrivate = false;
+	m_fp.zero();
+	m_hasPrivate = false;
 
 
 	if (!str) {
 	if (!str) {
-		_address.zero();
+		m_address.zero();
 		return false;
 		return false;
 	}
 	}
 
 
 	char tmp[ZT_IDENTITY_STRING_BUFFER_LENGTH];
 	char tmp[ZT_IDENTITY_STRING_BUFFER_LENGTH];
 	if (!Utils::scopy(tmp,sizeof(tmp),str)) {
 	if (!Utils::scopy(tmp,sizeof(tmp),str)) {
-		_address.zero();
+		m_address.zero();
 		return false;
 		return false;
 	}
 	}
 
 
@@ -429,37 +429,37 @@ bool Identity::fromString(const char *str)
 		switch(fno++) {
 		switch(fno++) {
 
 
 			case 0:
 			case 0:
-				_address = Address(Utils::hexStrToU64(f));
-				if (_address.isReserved()) {
-					_address.zero();
+				m_address = Address(Utils::hexStrToU64(f));
+				if (m_address.isReserved()) {
+					m_address.zero();
 					return false;
 					return false;
 				}
 				}
 				break;
 				break;
 
 
 			case 1:
 			case 1:
 				if ((f[0] == '0')&&(!f[1])) {
 				if ((f[0] == '0')&&(!f[1])) {
-					_type = C25519;
+					m_type = C25519;
 				} else if ((f[0] == '1')&&(!f[1])) {
 				} else if ((f[0] == '1')&&(!f[1])) {
-					_type = P384;
+					m_type = P384;
 				} else {
 				} else {
-					_address.zero();
+					m_address.zero();
 					return false;
 					return false;
 				}
 				}
 				break;
 				break;
 
 
 			case 2:
 			case 2:
-				switch(_type) {
+				switch(m_type) {
 
 
 					case C25519:
 					case C25519:
-						if (Utils::unhex(f,strlen(f),_pub.c25519,ZT_C25519_COMBINED_PUBLIC_KEY_SIZE) != ZT_C25519_COMBINED_PUBLIC_KEY_SIZE) {
-							_address.zero();
+						if (Utils::unhex(f, strlen(f), m_pub.c25519, ZT_C25519_COMBINED_PUBLIC_KEY_SIZE) != ZT_C25519_COMBINED_PUBLIC_KEY_SIZE) {
+							m_address.zero();
 							return false;
 							return false;
 						}
 						}
 						break;
 						break;
 
 
 					case P384:
 					case P384:
-						if (Utils::b32d(f,(uint8_t *)(&_pub),sizeof(_pub)) != sizeof(_pub)) {
-							_address.zero();
+						if (Utils::b32d(f, (uint8_t *)(&m_pub), sizeof(m_pub)) != sizeof(m_pub)) {
+							m_address.zero();
 							return false;
 							return false;
 						}
 						}
 						break;
 						break;
@@ -469,23 +469,23 @@ bool Identity::fromString(const char *str)
 
 
 			case 3:
 			case 3:
 				if (strlen(f) > 1) {
 				if (strlen(f) > 1) {
-					switch(_type) {
+					switch(m_type) {
 
 
 						case C25519:
 						case C25519:
-							if (Utils::unhex(f,strlen(f),_priv.c25519,ZT_C25519_COMBINED_PRIVATE_KEY_SIZE) != ZT_C25519_COMBINED_PRIVATE_KEY_SIZE) {
-								_address.zero();
+							if (Utils::unhex(f, strlen(f), m_priv.c25519, ZT_C25519_COMBINED_PRIVATE_KEY_SIZE) != ZT_C25519_COMBINED_PRIVATE_KEY_SIZE) {
+								m_address.zero();
 								return false;
 								return false;
 							} else {
 							} else {
-								_hasPrivate = true;
+								m_hasPrivate = true;
 							}
 							}
 							break;
 							break;
 
 
 						case P384:
 						case P384:
-							if (Utils::b32d(f,(uint8_t *)(&_priv),sizeof(_priv)) != sizeof(_priv)) {
-								_address.zero();
+							if (Utils::b32d(f, (uint8_t *)(&m_priv), sizeof(m_priv)) != sizeof(m_priv)) {
+								m_address.zero();
 								return false;
 								return false;
 							} else {
 							} else {
-								_hasPrivate = true;
+								m_hasPrivate = true;
 							}
 							}
 							break;
 							break;
 
 
@@ -497,13 +497,13 @@ bool Identity::fromString(const char *str)
 	}
 	}
 
 
 	if (fno < 3) {
 	if (fno < 3) {
-		_address.zero();
+		m_address.zero();
 		return false;
 		return false;
 	}
 	}
 
 
 	_computeHash();
 	_computeHash();
-	if ((_type == P384)&&(_address != Address(_fp.hash()))) {
-		_address.zero();
+	if ((m_type == P384) && (m_address != Address(m_fp.hash()))) {
+		m_address.zero();
 		return false;
 		return false;
 	}
 	}
 
 
@@ -512,14 +512,14 @@ bool Identity::fromString(const char *str)
 
 
 int Identity::marshal(uint8_t data[ZT_IDENTITY_MARSHAL_SIZE_MAX],const bool includePrivate) const noexcept
 int Identity::marshal(uint8_t data[ZT_IDENTITY_MARSHAL_SIZE_MAX],const bool includePrivate) const noexcept
 {
 {
-	_address.copyTo(data);
-	switch(_type) {
+	m_address.copyTo(data);
+	switch(m_type) {
 		case C25519:
 		case C25519:
 			data[ZT_ADDRESS_LENGTH] = (uint8_t)C25519;
 			data[ZT_ADDRESS_LENGTH] = (uint8_t)C25519;
-			Utils::copy<ZT_C25519_COMBINED_PUBLIC_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1,_pub.c25519);
-			if ((includePrivate)&&(_hasPrivate)) {
+			Utils::copy<ZT_C25519_COMBINED_PUBLIC_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1, m_pub.c25519);
+			if ((includePrivate)&&(m_hasPrivate)) {
 				data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE] = ZT_C25519_COMBINED_PRIVATE_KEY_SIZE;
 				data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE] = ZT_C25519_COMBINED_PRIVATE_KEY_SIZE;
-				Utils::copy<ZT_C25519_COMBINED_PRIVATE_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1,_priv.c25519);
+				Utils::copy<ZT_C25519_COMBINED_PRIVATE_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1, m_priv.c25519);
 				return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1 + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE;
 				return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1 + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE;
 			} else {
 			} else {
 				data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE] = 0;
 				data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE] = 0;
@@ -528,10 +528,10 @@ int Identity::marshal(uint8_t data[ZT_IDENTITY_MARSHAL_SIZE_MAX],const bool incl
 
 
 		case P384:
 		case P384:
 			data[ZT_ADDRESS_LENGTH] = (uint8_t)P384;
 			data[ZT_ADDRESS_LENGTH] = (uint8_t)P384;
-			Utils::copy<ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1,&_pub);
-			if ((includePrivate)&&(_hasPrivate)) {
+			Utils::copy<ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1,&m_pub);
+			if ((includePrivate)&&(m_hasPrivate)) {
 				data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE] = ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE;
 				data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE] = ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE;
-				Utils::copy<ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1,&_priv);
+				Utils::copy<ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1,&m_priv);
 				return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE;
 				return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE;
 			} else {
 			} else {
 				data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE] = 0;
 				data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE] = 0;
@@ -544,32 +544,32 @@ int Identity::marshal(uint8_t data[ZT_IDENTITY_MARSHAL_SIZE_MAX],const bool incl
 
 
 int Identity::unmarshal(const uint8_t *data,const int len) noexcept
 int Identity::unmarshal(const uint8_t *data,const int len) noexcept
 {
 {
-	_fp.zero();
-	_hasPrivate = false;
+	m_fp.zero();
+	m_hasPrivate = false;
 
 
 	if (len < (1 + ZT_ADDRESS_LENGTH))
 	if (len < (1 + ZT_ADDRESS_LENGTH))
 		return -1;
 		return -1;
-	_address.setTo(data);
+	m_address.setTo(data);
 
 
 	unsigned int privlen;
 	unsigned int privlen;
-	switch((_type = (Type)data[ZT_ADDRESS_LENGTH])) {
+	switch((m_type = (Type)data[ZT_ADDRESS_LENGTH])) {
 
 
 		case C25519:
 		case C25519:
 			if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1))
 			if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1))
 				return -1;
 				return -1;
 
 
-			Utils::copy<ZT_C25519_COMBINED_PUBLIC_KEY_SIZE>(_pub.c25519,data + ZT_ADDRESS_LENGTH + 1);
+			Utils::copy<ZT_C25519_COMBINED_PUBLIC_KEY_SIZE>(m_pub.c25519, data + ZT_ADDRESS_LENGTH + 1);
 			_computeHash();
 			_computeHash();
 
 
 			privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE];
 			privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE];
 			if (privlen == ZT_C25519_COMBINED_PRIVATE_KEY_SIZE) {
 			if (privlen == ZT_C25519_COMBINED_PRIVATE_KEY_SIZE) {
 				if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1 + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE))
 				if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1 + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE))
 					return -1;
 					return -1;
-				_hasPrivate = true;
-				Utils::copy<ZT_C25519_COMBINED_PRIVATE_KEY_SIZE>(_priv.c25519,data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1);
+				m_hasPrivate = true;
+				Utils::copy<ZT_C25519_COMBINED_PRIVATE_KEY_SIZE>(m_priv.c25519, data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1);
 				return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1 + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE;
 				return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1 + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE;
 			} else if (privlen == 0) {
 			} else if (privlen == 0) {
-				_hasPrivate = false;
+				m_hasPrivate = false;
 				return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1;
 				return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1;
 			}
 			}
 			break;
 			break;
@@ -578,20 +578,20 @@ int Identity::unmarshal(const uint8_t *data,const int len) noexcept
 			if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1))
 			if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1))
 				return -1;
 				return -1;
 
 
-			Utils::copy<ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE>(&_pub,data + ZT_ADDRESS_LENGTH + 1);
+			Utils::copy<ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE>(&m_pub, data + ZT_ADDRESS_LENGTH + 1);
 			_computeHash(); // this sets the address for P384
 			_computeHash(); // this sets the address for P384
-			if (_address != Address(_fp.hash())) // this sanity check is possible with V1 identities
+			if (m_address != Address(m_fp.hash())) // this sanity check is possible with V1 identities
 				return -1;
 				return -1;
 
 
 			privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE];
 			privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE];
 			if (privlen == ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE) {
 			if (privlen == ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE) {
 				if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE))
 				if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE))
 					return -1;
 					return -1;
-				_hasPrivate = true;
-				Utils::copy<ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE>(&_priv,data + ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1);
+				m_hasPrivate = true;
+				Utils::copy<ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE>(&m_priv, data + ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1);
 				return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE;
 				return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE;
 			} else if (privlen == 0) {
 			} else if (privlen == 0) {
-				_hasPrivate = false;
+				m_hasPrivate = false;
 				return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1;
 				return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1;
 			}
 			}
 			break;
 			break;
@@ -603,19 +603,19 @@ int Identity::unmarshal(const uint8_t *data,const int len) noexcept
 
 
 void Identity::_computeHash()
 void Identity::_computeHash()
 {
 {
-	switch(_type) {
+	switch(m_type) {
 		default:
 		default:
-			_fp.zero();
+			m_fp.zero();
 			break;
 			break;
 
 
 		case C25519:
 		case C25519:
-			_fp._fp.address = _address.toInt();
-			SHA384(_fp._fp.hash,_pub.c25519,ZT_C25519_COMBINED_PUBLIC_KEY_SIZE);
+			m_fp.m_cfp.address = m_address.toInt();
+			SHA384(m_fp.m_cfp.hash, m_pub.c25519, ZT_C25519_COMBINED_PUBLIC_KEY_SIZE);
 			break;
 			break;
 
 
 		case P384:
 		case P384:
-			SHA384(_fp._fp.hash,&_pub,sizeof(_pub));
-			_fp._fp.address = _address.toInt();
+			SHA384(m_fp.m_cfp.hash, &m_pub, sizeof(m_pub));
+			m_fp.m_cfp.address = m_address.toInt();
 			break;
 			break;
 	}
 	}
 }
 }

+ 17 - 15
node/Identity.hpp

@@ -22,6 +22,7 @@
 #include "ECC384.hpp"
 #include "ECC384.hpp"
 #include "TriviallyCopyable.hpp"
 #include "TriviallyCopyable.hpp"
 #include "Fingerprint.hpp"
 #include "Fingerprint.hpp"
+#include "Containers.hpp"
 
 
 #include <cstdio>
 #include <cstdio>
 #include <cstdlib>
 #include <cstdlib>
@@ -86,7 +87,7 @@ public:
 	ZT_INLINE ~Identity()
 	ZT_INLINE ~Identity()
 	{
 	{
 		Utils::memoryUnlock(this,sizeof(Identity));
 		Utils::memoryUnlock(this,sizeof(Identity));
-		Utils::burn(reinterpret_cast<void *>(&this->_priv),sizeof(this->_priv));
+		Utils::burn(reinterpret_cast<void *>(&this->m_priv), sizeof(this->m_priv));
 	}
 	}
 
 
 	/**
 	/**
@@ -97,7 +98,7 @@ public:
 	/**
 	/**
 	 * @return Identity type (undefined if identity is null or invalid)
 	 * @return Identity type (undefined if identity is null or invalid)
 	 */
 	 */
-	ZT_INLINE Type type() const noexcept { return _type; }
+	ZT_INLINE Type type() const noexcept { return m_type; }
 
 
 	/**
 	/**
 	 * Generate a new identity (address, key pair)
 	 * Generate a new identity (address, key pair)
@@ -123,7 +124,7 @@ public:
 	/**
 	/**
 	 * @return True if this identity contains a private key
 	 * @return True if this identity contains a private key
 	 */
 	 */
-	ZT_INLINE bool hasPrivate() const noexcept { return _hasPrivate; }
+	ZT_INLINE bool hasPrivate() const noexcept { return m_hasPrivate; }
 
 
 	/**
 	/**
 	 * Get a 384-bit hash of this identity's public key(s)
 	 * Get a 384-bit hash of this identity's public key(s)
@@ -137,7 +138,7 @@ public:
 	 *
 	 *
 	 * @return Hash of public key(s)
 	 * @return Hash of public key(s)
 	 */
 	 */
-	ZT_INLINE const Fingerprint &fingerprint() const noexcept { return _fp; }
+	ZT_INLINE const Fingerprint &fingerprint() const noexcept { return m_fp; }
 
 
 	/**
 	/**
 	 * Compute a hash of this identity's public and private keys.
 	 * Compute a hash of this identity's public and private keys.
@@ -187,7 +188,7 @@ public:
 	/**
 	/**
 	 * @return This identity's address
 	 * @return This identity's address
 	 */
 	 */
-	ZT_INLINE Address address() const noexcept { return _address; }
+	ZT_INLINE Address address() const noexcept { return m_address; }
 
 
 	/**
 	/**
 	 * Serialize to a more human-friendly string
 	 * Serialize to a more human-friendly string
@@ -197,6 +198,7 @@ public:
 	 * @return ASCII string representation of identity (pointer to buf)
 	 * @return ASCII string representation of identity (pointer to buf)
 	 */
 	 */
 	char *toString(bool includePrivate,char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]) const;
 	char *toString(bool includePrivate,char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]) const;
+	ZT_INLINE String toString(const bool includePrivate = false) const { char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]; toString(includePrivate); return String(buf); }
 
 
 	/**
 	/**
 	 * Deserialize a human-friendly string
 	 * Deserialize a human-friendly string
@@ -212,13 +214,13 @@ public:
 	/**
 	/**
 	 * @return True if this identity contains something
 	 * @return True if this identity contains something
 	 */
 	 */
-	explicit ZT_INLINE operator bool() const noexcept { return (_address); }
+	explicit ZT_INLINE operator bool() const noexcept { return (m_address); }
 
 
-	ZT_INLINE unsigned long hashCode() const noexcept { return _fp.hashCode(); }
+	ZT_INLINE unsigned long hashCode() const noexcept { return m_fp.hashCode(); }
 
 
-	ZT_INLINE bool operator==(const Identity &id) const noexcept { return (_fp == id._fp); }
+	ZT_INLINE bool operator==(const Identity &id) const noexcept { return (m_fp == id.m_fp); }
 	ZT_INLINE bool operator!=(const Identity &id) const noexcept { return !(*this == id); }
 	ZT_INLINE bool operator!=(const Identity &id) const noexcept { return !(*this == id); }
-	ZT_INLINE bool operator<(const Identity &id) const noexcept { return (_fp < id._fp); }
+	ZT_INLINE bool operator<(const Identity &id) const noexcept { return (m_fp < id.m_fp); }
 	ZT_INLINE bool operator>(const Identity &id) const noexcept { return (id < *this); }
 	ZT_INLINE bool operator>(const Identity &id) const noexcept { return (id < *this); }
 	ZT_INLINE bool operator<=(const Identity &id) const noexcept { return !(id < *this); }
 	ZT_INLINE bool operator<=(const Identity &id) const noexcept { return !(id < *this); }
 	ZT_INLINE bool operator>=(const Identity &id) const noexcept { return !(*this < id); }
 	ZT_INLINE bool operator>=(const Identity &id) const noexcept { return !(*this < id); }
@@ -230,19 +232,19 @@ public:
 private:
 private:
 	void _computeHash();
 	void _computeHash();
 
 
-	Address _address;
-	Fingerprint _fp;
+	Address m_address;
+	Fingerprint m_fp;
 	ZT_PACKED_STRUCT(struct { // do not re-order these fields
 	ZT_PACKED_STRUCT(struct { // do not re-order these fields
 		uint8_t c25519[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE];
 		uint8_t c25519[ZT_C25519_COMBINED_PRIVATE_KEY_SIZE];
 		uint8_t p384[ZT_ECC384_PRIVATE_KEY_SIZE];
 		uint8_t p384[ZT_ECC384_PRIVATE_KEY_SIZE];
-	}) _priv;
+	}) m_priv;
 	ZT_PACKED_STRUCT(struct { // do not re-order these fields
 	ZT_PACKED_STRUCT(struct { // do not re-order these fields
 		uint8_t nonce;                            // nonce for PoW generate/verify
 		uint8_t nonce;                            // nonce for PoW generate/verify
 		uint8_t c25519[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE]; // Curve25519 and Ed25519 public keys
 		uint8_t c25519[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE]; // Curve25519 and Ed25519 public keys
 		uint8_t p384[ZT_ECC384_PUBLIC_KEY_SIZE];  // NIST P-384 public key
 		uint8_t p384[ZT_ECC384_PUBLIC_KEY_SIZE];  // NIST P-384 public key
-	}) _pub;
-	Type _type; // _type determines which fields in _priv and _pub are used
-	bool _hasPrivate;
+	}) m_pub;
+	Type m_type; // _type determines which fields in _priv and _pub are used
+	bool m_hasPrivate;
 };
 };
 
 
 } // namespace ZeroTier
 } // namespace ZeroTier

+ 20 - 20
node/InetAddress.cpp

@@ -26,7 +26,7 @@ const InetAddress InetAddress::NIL;
 
 
 InetAddress::IpScope InetAddress::ipScope() const noexcept
 InetAddress::IpScope InetAddress::ipScope() const noexcept
 {
 {
-	switch(_data.ss_family) {
+	switch(m_sockaddr.ss_family) {
 
 
 		case AF_INET: {
 		case AF_INET: {
 			const uint32_t ip = Utils::ntoh((uint32_t)reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr);
 			const uint32_t ip = Utils::ntoh((uint32_t)reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr);
@@ -99,11 +99,11 @@ void InetAddress::set(const void *ipBytes,unsigned int ipLen,unsigned int port)
 	if (ipLen == 4) {
 	if (ipLen == 4) {
 		uint32_t ipb[1];
 		uint32_t ipb[1];
 		Utils::copy<4>(ipb,ipBytes);
 		Utils::copy<4>(ipb,ipBytes);
-		_data.ss_family = AF_INET;
+		m_sockaddr.ss_family = AF_INET;
 		reinterpret_cast<sockaddr_in *>(this)->sin_addr.s_addr = ipb[0];
 		reinterpret_cast<sockaddr_in *>(this)->sin_addr.s_addr = ipb[0];
 		reinterpret_cast<sockaddr_in *>(this)->sin_port = Utils::hton((uint16_t)port);
 		reinterpret_cast<sockaddr_in *>(this)->sin_port = Utils::hton((uint16_t)port);
 	} else if (ipLen == 16) {
 	} else if (ipLen == 16) {
-		_data.ss_family = AF_INET6;
+		m_sockaddr.ss_family = AF_INET6;
 		Utils::copy<16>(reinterpret_cast<sockaddr_in6 *>(this)->sin6_addr.s6_addr,ipBytes);
 		Utils::copy<16>(reinterpret_cast<sockaddr_in6 *>(this)->sin6_addr.s6_addr,ipBytes);
 		reinterpret_cast<sockaddr_in6 *>(this)->sin6_port = Utils::hton((uint16_t)port);
 		reinterpret_cast<sockaddr_in6 *>(this)->sin6_port = Utils::hton((uint16_t)port);
 	}
 	}
@@ -111,7 +111,7 @@ void InetAddress::set(const void *ipBytes,unsigned int ipLen,unsigned int port)
 
 
 bool InetAddress::isDefaultRoute() const noexcept
 bool InetAddress::isDefaultRoute() const noexcept
 {
 {
-	switch(_data.ss_family) {
+	switch(m_sockaddr.ss_family) {
 		case AF_INET:
 		case AF_INET:
 			return ( (reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr == 0) && (reinterpret_cast<const sockaddr_in *>(this)->sin_port == 0) );
 			return ( (reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr == 0) && (reinterpret_cast<const sockaddr_in *>(this)->sin_port == 0) );
 		case AF_INET6:
 		case AF_INET6:
@@ -139,7 +139,7 @@ char *InetAddress::toString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noex
 char *InetAddress::toIpString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noexcept
 char *InetAddress::toIpString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noexcept
 {
 {
 	buf[0] = (char)0;
 	buf[0] = (char)0;
-	switch(_data.ss_family) {
+	switch(m_sockaddr.ss_family) {
 		case AF_INET: {
 		case AF_INET: {
 #ifdef _WIN32
 #ifdef _WIN32
 			inet_ntop(AF_INET, (void*)&reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr, buf, INET_ADDRSTRLEN);
 			inet_ntop(AF_INET, (void*)&reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr, buf, INET_ADDRSTRLEN);
@@ -199,7 +199,7 @@ bool InetAddress::fromString(const char *ipSlashPort) noexcept
 InetAddress InetAddress::netmask() const noexcept
 InetAddress InetAddress::netmask() const noexcept
 {
 {
 	InetAddress r(*this);
 	InetAddress r(*this);
-	switch(r._data.ss_family) {
+	switch(r.m_sockaddr.ss_family) {
 		case AF_INET:
 		case AF_INET:
 			reinterpret_cast<sockaddr_in *>(&r)->sin_addr.s_addr = Utils::hton((uint32_t)(0xffffffffU << (32 - netmaskBits())));
 			reinterpret_cast<sockaddr_in *>(&r)->sin_addr.s_addr = Utils::hton((uint32_t)(0xffffffffU << (32 - netmaskBits())));
 			break;
 			break;
@@ -221,7 +221,7 @@ InetAddress InetAddress::netmask() const noexcept
 
 
 InetAddress InetAddress::broadcast() const noexcept
 InetAddress InetAddress::broadcast() const noexcept
 {
 {
-	if (_data.ss_family == AF_INET) {
+	if (m_sockaddr.ss_family == AF_INET) {
 		InetAddress r(*this);
 		InetAddress r(*this);
 		reinterpret_cast<sockaddr_in *>(&r)->sin_addr.s_addr |= Utils::hton((uint32_t)(0xffffffffU >> netmaskBits()));
 		reinterpret_cast<sockaddr_in *>(&r)->sin_addr.s_addr |= Utils::hton((uint32_t)(0xffffffffU >> netmaskBits()));
 		return r;
 		return r;
@@ -232,7 +232,7 @@ InetAddress InetAddress::broadcast() const noexcept
 InetAddress InetAddress::network() const noexcept
 InetAddress InetAddress::network() const noexcept
 {
 {
 	InetAddress r(*this);
 	InetAddress r(*this);
-	switch(r._data.ss_family) {
+	switch(r.m_sockaddr.ss_family) {
 		case AF_INET:
 		case AF_INET:
 			reinterpret_cast<sockaddr_in *>(&r)->sin_addr.s_addr &= Utils::hton((uint32_t)(0xffffffffU << (32 - netmaskBits())));
 			reinterpret_cast<sockaddr_in *>(&r)->sin_addr.s_addr &= Utils::hton((uint32_t)(0xffffffffU << (32 - netmaskBits())));
 			break;
 			break;
@@ -250,8 +250,8 @@ InetAddress InetAddress::network() const noexcept
 
 
 bool InetAddress::isEqualPrefix(const InetAddress &addr) const noexcept
 bool InetAddress::isEqualPrefix(const InetAddress &addr) const noexcept
 {
 {
-	if (addr._data.ss_family == _data.ss_family) {
-		switch(_data.ss_family) {
+	if (addr.m_sockaddr.ss_family == m_sockaddr.ss_family) {
+		switch(m_sockaddr.ss_family) {
 			case AF_INET6: {
 			case AF_INET6: {
 				const InetAddress mask(netmask());
 				const InetAddress mask(netmask());
 				InetAddress addr_mask(addr.netmask());
 				InetAddress addr_mask(addr.netmask());
@@ -272,8 +272,8 @@ bool InetAddress::isEqualPrefix(const InetAddress &addr) const noexcept
 
 
 bool InetAddress::containsAddress(const InetAddress &addr) const noexcept
 bool InetAddress::containsAddress(const InetAddress &addr) const noexcept
 {
 {
-	if (addr._data.ss_family == _data.ss_family) {
-		switch(_data.ss_family) {
+	if (addr.m_sockaddr.ss_family == m_sockaddr.ss_family) {
+		switch(m_sockaddr.ss_family) {
 			case AF_INET: {
 			case AF_INET: {
 				const unsigned int bits = netmaskBits();
 				const unsigned int bits = netmaskBits();
 				if (bits == 0)
 				if (bits == 0)
@@ -302,7 +302,7 @@ bool InetAddress::containsAddress(const InetAddress &addr) const noexcept
 void InetAddress::forTrace(ZT_TraceEventPathAddress &ta) const noexcept
 void InetAddress::forTrace(ZT_TraceEventPathAddress &ta) const noexcept
 {
 {
 	uint32_t tmp;
 	uint32_t tmp;
-	switch(_data.ss_family) {
+	switch(m_sockaddr.ss_family) {
 		default:
 		default:
 			Utils::zero<sizeof(ZT_TraceEventPathAddress)>(&ta);
 			Utils::zero<sizeof(ZT_TraceEventPathAddress)>(&ta);
 			break;
 			break;
@@ -327,7 +327,7 @@ void InetAddress::forTrace(ZT_TraceEventPathAddress &ta) const noexcept
 
 
 bool InetAddress::isNetwork() const noexcept
 bool InetAddress::isNetwork() const noexcept
 {
 {
-	switch(_data.ss_family) {
+	switch(m_sockaddr.ss_family) {
 		case AF_INET: {
 		case AF_INET: {
 			unsigned int bits = netmaskBits();
 			unsigned int bits = netmaskBits();
 			if (bits <= 0)
 			if (bits <= 0)
@@ -360,7 +360,7 @@ bool InetAddress::isNetwork() const noexcept
 int InetAddress::marshal(uint8_t data[ZT_INETADDRESS_MARSHAL_SIZE_MAX]) const noexcept
 int InetAddress::marshal(uint8_t data[ZT_INETADDRESS_MARSHAL_SIZE_MAX]) const noexcept
 {
 {
 	unsigned int port;
 	unsigned int port;
-	switch(_data.ss_family) {
+	switch(m_sockaddr.ss_family) {
 		case AF_INET:
 		case AF_INET:
 			port = Utils::ntoh((uint16_t)reinterpret_cast<const sockaddr_in *>(this)->sin_port);
 			port = Utils::ntoh((uint16_t)reinterpret_cast<const sockaddr_in *>(this)->sin_port);
 			data[0] = 4;
 			data[0] = 4;
@@ -421,8 +421,8 @@ int InetAddress::unmarshal(const uint8_t *restrict data,const int len) noexcept
 
 
 bool InetAddress::operator==(const InetAddress &a) const noexcept
 bool InetAddress::operator==(const InetAddress &a) const noexcept
 {
 {
-	if (_data.ss_family == a._data.ss_family) {
-		switch(_data.ss_family) {
+	if (m_sockaddr.ss_family == a.m_sockaddr.ss_family) {
+		switch(m_sockaddr.ss_family) {
 			case AF_INET:
 			case AF_INET:
 				return (
 				return (
 					(reinterpret_cast<const sockaddr_in *>(this)->sin_port == reinterpret_cast<const sockaddr_in *>(&a)->sin_port)&&
 					(reinterpret_cast<const sockaddr_in *>(this)->sin_port == reinterpret_cast<const sockaddr_in *>(&a)->sin_port)&&
@@ -442,10 +442,10 @@ bool InetAddress::operator==(const InetAddress &a) const noexcept
 
 
 bool InetAddress::operator<(const InetAddress &a) const noexcept
 bool InetAddress::operator<(const InetAddress &a) const noexcept
 {
 {
-	if (_data.ss_family < a._data.ss_family)
+	if (m_sockaddr.ss_family < a.m_sockaddr.ss_family)
 		return true;
 		return true;
-	else if (_data.ss_family == a._data.ss_family) {
-		switch(_data.ss_family) {
+	else if (m_sockaddr.ss_family == a.m_sockaddr.ss_family) {
+		switch(m_sockaddr.ss_family) {
 			case AF_INET:
 			case AF_INET:
 				if (reinterpret_cast<const sockaddr_in *>(this)->sin_port < reinterpret_cast<const sockaddr_in *>(&a)->sin_port)
 				if (reinterpret_cast<const sockaddr_in *>(this)->sin_port < reinterpret_cast<const sockaddr_in *>(&a)->sin_port)
 					return true;
 					return true;

+ 18 - 18
node/InetAddress.hpp

@@ -166,7 +166,7 @@ public:
 	/**
 	/**
 	 * @return Address family (ss_family in sockaddr_storage)
 	 * @return Address family (ss_family in sockaddr_storage)
 	 */
 	 */
-	ZT_INLINE uint8_t family() const noexcept { return _data.ss_family; }
+	ZT_INLINE uint8_t family() const noexcept { return m_sockaddr.ss_family; }
 
 
 	/**
 	/**
 	 * @return IP scope classification (e.g. loopback, link-local, private, global)
 	 * @return IP scope classification (e.g. loopback, link-local, private, global)
@@ -189,7 +189,7 @@ public:
 	 */
 	 */
 	ZT_INLINE void setPort(unsigned int port) noexcept
 	ZT_INLINE void setPort(unsigned int port) noexcept
 	{
 	{
-		switch(_data.ss_family) {
+		switch(m_sockaddr.ss_family) {
 			case AF_INET:
 			case AF_INET:
 				reinterpret_cast<sockaddr_in *>(this)->sin_port = Utils::hton((uint16_t)port);
 				reinterpret_cast<sockaddr_in *>(this)->sin_port = Utils::hton((uint16_t)port);
 				break;
 				break;
@@ -227,7 +227,7 @@ public:
 	 */
 	 */
 	ZT_INLINE unsigned int port() const noexcept
 	ZT_INLINE unsigned int port() const noexcept
 	{
 	{
-		switch(_data.ss_family) {
+		switch(m_sockaddr.ss_family) {
 			case AF_INET:  return Utils::ntoh((uint16_t)(reinterpret_cast<const sockaddr_in *>(this)->sin_port));
 			case AF_INET:  return Utils::ntoh((uint16_t)(reinterpret_cast<const sockaddr_in *>(this)->sin_port));
 			case AF_INET6: return Utils::ntoh((uint16_t)(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_port));
 			case AF_INET6: return Utils::ntoh((uint16_t)(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_port));
 			default:       return 0;
 			default:       return 0;
@@ -251,7 +251,7 @@ public:
 	ZT_INLINE bool netmaskBitsValid() const noexcept
 	ZT_INLINE bool netmaskBitsValid() const noexcept
 	{
 	{
 		const unsigned int n = port();
 		const unsigned int n = port();
-		switch(_data.ss_family) {
+		switch(m_sockaddr.ss_family) {
 			case AF_INET: return (n <= 32);
 			case AF_INET: return (n <= 32);
 			case AF_INET6: return (n <= 128);
 			case AF_INET6: return (n <= 128);
 		}
 		}
@@ -323,7 +323,7 @@ public:
 	 */
 	 */
 	ZT_INLINE const void *rawIpData() const noexcept
 	ZT_INLINE const void *rawIpData() const noexcept
 	{
 	{
-		switch(_data.ss_family) {
+		switch(m_sockaddr.ss_family) {
 			case AF_INET: return (const void *)&(reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr);
 			case AF_INET: return (const void *)&(reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr);
 			case AF_INET6: return (const void *)(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr);
 			case AF_INET6: return (const void *)(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr);
 			default: return nullptr;
 			default: return nullptr;
@@ -336,7 +336,7 @@ public:
 	ZT_INLINE InetAddress ipOnly() const noexcept
 	ZT_INLINE InetAddress ipOnly() const noexcept
 	{
 	{
 		InetAddress r;
 		InetAddress r;
-		switch(_data.ss_family) {
+		switch(m_sockaddr.ss_family) {
 			case AF_INET:
 			case AF_INET:
 				reinterpret_cast<sockaddr_in *>(&r)->sin_family = AF_INET;
 				reinterpret_cast<sockaddr_in *>(&r)->sin_family = AF_INET;
 				reinterpret_cast<sockaddr_in *>(&r)->sin_addr.s_addr = reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr;
 				reinterpret_cast<sockaddr_in *>(&r)->sin_addr.s_addr = reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr;
@@ -357,8 +357,8 @@ public:
 	 */
 	 */
 	ZT_INLINE bool ipsEqual(const InetAddress &a) const noexcept
 	ZT_INLINE bool ipsEqual(const InetAddress &a) const noexcept
 	{
 	{
-		const uint8_t f = _data.ss_family;
-		if (f == a._data.ss_family) {
+		const uint8_t f = m_sockaddr.ss_family;
+		if (f == a.m_sockaddr.ss_family) {
 			if (f == AF_INET)
 			if (f == AF_INET)
 				return (reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr == reinterpret_cast<const sockaddr_in *>(&a)->sin_addr.s_addr);
 				return (reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr == reinterpret_cast<const sockaddr_in *>(&a)->sin_addr.s_addr);
 			if (f == AF_INET6)
 			if (f == AF_INET6)
@@ -378,8 +378,8 @@ public:
 	 */
 	 */
 	ZT_INLINE bool ipsEqual2(const InetAddress &a) const noexcept
 	ZT_INLINE bool ipsEqual2(const InetAddress &a) const noexcept
 	{
 	{
-		const uint8_t f = _data.ss_family;
-		if (f == a._data.ss_family) {
+		const uint8_t f = m_sockaddr.ss_family;
+		if (f == a.m_sockaddr.ss_family) {
 			if (f == AF_INET)
 			if (f == AF_INET)
 				return (reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr == reinterpret_cast<const sockaddr_in *>(&a)->sin_addr.s_addr);
 				return (reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr == reinterpret_cast<const sockaddr_in *>(&a)->sin_addr.s_addr);
 			if (f == AF_INET6)
 			if (f == AF_INET6)
@@ -391,16 +391,16 @@ public:
 
 
 	ZT_INLINE unsigned long hashCode() const noexcept
 	ZT_INLINE unsigned long hashCode() const noexcept
 	{
 	{
-		if (_data.ss_family == AF_INET) {
-			return (unsigned long)Utils::hash32(((uint32_t)reinterpret_cast<const sockaddr_in *>(&_data)->sin_addr.s_addr + (uint32_t)reinterpret_cast<const sockaddr_in *>(&_data)->sin_port) ^ (uint32_t)Utils::s_mapNonce);
-		} else if (_data.ss_family == AF_INET6) {
+		if (m_sockaddr.ss_family == AF_INET) {
+			return (unsigned long)Utils::hash32(((uint32_t)reinterpret_cast<const sockaddr_in *>(&m_sockaddr)->sin_addr.s_addr + (uint32_t)reinterpret_cast<const sockaddr_in *>(&m_sockaddr)->sin_port) ^ (uint32_t)Utils::s_mapNonce);
+		} else if (m_sockaddr.ss_family == AF_INET6) {
 			return (unsigned long)Utils::hash64(
 			return (unsigned long)Utils::hash64(
-				(Utils::loadAsIsEndian<uint64_t>(reinterpret_cast<const sockaddr_in6 *>(&_data)->sin6_addr.s6_addr) +
-				Utils::loadAsIsEndian<uint64_t>(reinterpret_cast<const sockaddr_in6 *>(&_data)->sin6_addr.s6_addr + 8) +
-				(uint64_t)reinterpret_cast<const sockaddr_in6 *>(&_data)->sin6_port) ^ Utils::s_mapNonce
+				(Utils::loadAsIsEndian<uint64_t>(reinterpret_cast<const sockaddr_in6 *>(&m_sockaddr)->sin6_addr.s6_addr) +
+				 Utils::loadAsIsEndian<uint64_t>(reinterpret_cast<const sockaddr_in6 *>(&m_sockaddr)->sin6_addr.s6_addr + 8) +
+				 (uint64_t)reinterpret_cast<const sockaddr_in6 *>(&m_sockaddr)->sin6_port) ^ Utils::s_mapNonce
 			);
 			);
 		}
 		}
-		return Utils::fnv1a32(&_data,sizeof(_data));
+		return Utils::fnv1a32(&m_sockaddr, sizeof(m_sockaddr));
 	}
 	}
 
 
 	/**
 	/**
@@ -493,7 +493,7 @@ public:
 	static InetAddress makeIpv66plane(uint64_t nwid,uint64_t zeroTierAddress) noexcept;
 	static InetAddress makeIpv66plane(uint64_t nwid,uint64_t zeroTierAddress) noexcept;
 
 
 private:
 private:
-	sockaddr_storage _data;
+	sockaddr_storage m_sockaddr;
 };
 };
 
 
 static_assert(sizeof(sockaddr_storage) == sizeof(InetAddress),"InetAddress sizing incorrect");
 static_assert(sizeof(sockaddr_storage) == sizeof(InetAddress),"InetAddress sizing incorrect");

+ 25 - 25
node/Locator.cpp

@@ -20,50 +20,50 @@ bool Locator::sign(const int64_t ts,const Identity &id) noexcept
 	uint8_t signData[ZT_LOCATOR_MARSHAL_SIZE_MAX];
 	uint8_t signData[ZT_LOCATOR_MARSHAL_SIZE_MAX];
 	if (!id.hasPrivate())
 	if (!id.hasPrivate())
 		return false;
 		return false;
-	_ts = ts;
-	if (_endpointCount > 0)
-		std::sort(_at,_at + _endpointCount);
+	m_ts = ts;
+	if (m_endpointCount > 0)
+		std::sort(m_at, m_at + m_endpointCount);
 	const unsigned int signLen = marshal(signData,true);
 	const unsigned int signLen = marshal(signData,true);
-	_signatureLength = id.sign(signData, signLen, _signature, sizeof(_signature));
-	return (_signatureLength > 0);
+	m_signatureLength = id.sign(signData, signLen, m_signature, sizeof(m_signature));
+	return (m_signatureLength > 0);
 }
 }
 
 
 bool Locator::verify(const Identity &id) const noexcept
 bool Locator::verify(const Identity &id) const noexcept
 {
 {
-	if ((_ts == 0)||(_endpointCount > ZT_LOCATOR_MAX_ENDPOINTS)||(_signatureLength > ZT_SIGNATURE_BUFFER_SIZE))
+	if ((m_ts == 0) || (m_endpointCount > ZT_LOCATOR_MAX_ENDPOINTS) || (m_signatureLength > ZT_SIGNATURE_BUFFER_SIZE))
 		return false;
 		return false;
 	uint8_t signData[ZT_LOCATOR_MARSHAL_SIZE_MAX];
 	uint8_t signData[ZT_LOCATOR_MARSHAL_SIZE_MAX];
 	const unsigned int signLen = marshal(signData,true);
 	const unsigned int signLen = marshal(signData,true);
-	return id.verify(signData,signLen,_signature,_signatureLength);
+	return id.verify(signData, signLen, m_signature, m_signatureLength);
 }
 }
 
 
 int Locator::marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX],const bool excludeSignature) const noexcept
 int Locator::marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX],const bool excludeSignature) const noexcept
 {
 {
-	if ((_endpointCount > ZT_LOCATOR_MAX_ENDPOINTS)||(_signatureLength > ZT_SIGNATURE_BUFFER_SIZE))
+	if ((m_endpointCount > ZT_LOCATOR_MAX_ENDPOINTS) || (m_signatureLength > ZT_SIGNATURE_BUFFER_SIZE))
 		return -1;
 		return -1;
 
 
 	data[0] = 0xff; // version byte, currently 0xff to never be the same as byte 0 of an identity for legacy compatibility reasons
 	data[0] = 0xff; // version byte, currently 0xff to never be the same as byte 0 of an identity for legacy compatibility reasons
-	Utils::storeBigEndian<int64_t>(data + 1,_ts);
+	Utils::storeBigEndian<int64_t>(data + 1, m_ts);
 	int p = 9;
 	int p = 9;
 
 
-	if (_ts > 0) {
-		Utils::storeBigEndian(data + p,(uint16_t)_endpointCount);
+	if (m_ts > 0) {
+		Utils::storeBigEndian(data + p,(uint16_t)m_endpointCount);
 		p += 2;
 		p += 2;
-		for (unsigned int i = 0; i < _endpointCount; ++i) {
-			int tmp = _at[i].marshal(data + p);
+		for (unsigned int i = 0;i < m_endpointCount;++i) {
+			int tmp = m_at[i].marshal(data + p);
 			if (tmp < 0)
 			if (tmp < 0)
 				return -1;
 				return -1;
 			p += tmp;
 			p += tmp;
 		}
 		}
 
 
 		if (!excludeSignature) {
 		if (!excludeSignature) {
-			Utils::storeBigEndian(data + p,(uint16_t)_signatureLength);
+			Utils::storeBigEndian(data + p,(uint16_t)m_signatureLength);
 			p += 2;
 			p += 2;
-			Utils::copy(data + p,_signature,_signatureLength);
-			p += (int)_signatureLength;
+			Utils::copy(data + p, m_signature, m_signatureLength);
+			p += (int)m_signatureLength;
 		}
 		}
 
 
-		Utils::storeBigEndian(data + p,_flags);
+		Utils::storeBigEndian(data + p, m_flags);
 		p += 2;
 		p += 2;
 	}
 	}
 
 
@@ -77,17 +77,17 @@ int Locator::unmarshal(const uint8_t *restrict data,const int len) noexcept
 
 
 	if (data[0] != 0xff)
 	if (data[0] != 0xff)
 		return -1;
 		return -1;
-	_ts = Utils::loadBigEndian<int64_t>(data + 1);
+	m_ts = Utils::loadBigEndian<int64_t>(data + 1);
 	int p = 9;
 	int p = 9;
 
 
-	if (_ts > 0) {
+	if (m_ts > 0) {
 		const unsigned int ec = Utils::loadBigEndian<uint16_t>(data + p);
 		const unsigned int ec = Utils::loadBigEndian<uint16_t>(data + p);
 		p += 2;
 		p += 2;
 		if (ec > ZT_LOCATOR_MAX_ENDPOINTS)
 		if (ec > ZT_LOCATOR_MAX_ENDPOINTS)
 			return -1;
 			return -1;
-		_endpointCount = ec;
+		m_endpointCount = ec;
 		for (unsigned int i = 0; i < ec; ++i) {
 		for (unsigned int i = 0; i < ec; ++i) {
-			int tmp = _at[i].unmarshal(data + p,len - p);
+			int tmp = m_at[i].unmarshal(data + p, len - p);
 			if (tmp < 0)
 			if (tmp < 0)
 				return -1;
 				return -1;
 			p += tmp;
 			p += tmp;
@@ -99,18 +99,18 @@ int Locator::unmarshal(const uint8_t *restrict data,const int len) noexcept
 		p += 2;
 		p += 2;
 		if (sl > ZT_SIGNATURE_BUFFER_SIZE)
 		if (sl > ZT_SIGNATURE_BUFFER_SIZE)
 			return -1;
 			return -1;
-		_signatureLength = sl;
+		m_signatureLength = sl;
 		if ((p + (int)sl) > len)
 		if ((p + (int)sl) > len)
 			return -1;
 			return -1;
-		Utils::copy(_signature,data + p,sl);
+		Utils::copy(m_signature, data + p, sl);
 		p += (int)sl;
 		p += (int)sl;
 
 
 		if ((p + 2) > len)
 		if ((p + 2) > len)
 			return -1;
 			return -1;
-		_flags = Utils::loadBigEndian<uint16_t>(data + p);
+		m_flags = Utils::loadBigEndian<uint16_t>(data + p);
 		p += 2;
 		p += 2;
 	} else {
 	} else {
-		_ts = 0;
+		m_ts = 0;
 	}
 	}
 
 
 	return p;
 	return p;

+ 15 - 15
node/Locator.hpp

@@ -47,32 +47,32 @@ public:
 	/**
 	/**
 	 * @return Timestamp (a.k.a. revision number) set by Location signer
 	 * @return Timestamp (a.k.a. revision number) set by Location signer
 	 */
 	 */
-	ZT_INLINE int64_t timestamp() const noexcept { return _ts; }
+	ZT_INLINE int64_t timestamp() const noexcept { return m_ts; }
 
 
 	/**
 	/**
 	 * @return True if locator is signed
 	 * @return True if locator is signed
 	 */
 	 */
-	ZT_INLINE bool isSigned() const noexcept { return (_signatureLength > 0); }
+	ZT_INLINE bool isSigned() const noexcept { return (m_signatureLength > 0); }
 
 
 	/**
 	/**
 	 * @return Length of signature in bytes or 0 if none
 	 * @return Length of signature in bytes or 0 if none
 	 */
 	 */
-	ZT_INLINE unsigned int signatureLength() const noexcept { return _signatureLength; }
+	ZT_INLINE unsigned int signatureLength() const noexcept { return m_signatureLength; }
 
 
 	/**
 	/**
 	 * @return Pointer to signature bytes
 	 * @return Pointer to signature bytes
 	 */
 	 */
-	ZT_INLINE const uint8_t *signature() const noexcept { return _signature; }
+	ZT_INLINE const uint8_t *signature() const noexcept { return m_signature; }
 
 
 	/**
 	/**
 	 * @return Number of endpoints in this locator
 	 * @return Number of endpoints in this locator
 	 */
 	 */
-	ZT_INLINE unsigned int endpointCount() const noexcept { return _endpointCount; }
+	ZT_INLINE unsigned int endpointCount() const noexcept { return m_endpointCount; }
 
 
 	/**
 	/**
 	 * @return Pointer to array of endpoints
 	 * @return Pointer to array of endpoints
 	 */
 	 */
-	ZT_INLINE const Endpoint *endpoints() const noexcept { return _at; }
+	ZT_INLINE const Endpoint *endpoints() const noexcept { return m_at; }
 
 
 	/**
 	/**
 	 * Add an endpoint to this locator
 	 * Add an endpoint to this locator
@@ -85,9 +85,9 @@ public:
 	 */
 	 */
 	ZT_INLINE bool add(const Endpoint &ep) noexcept
 	ZT_INLINE bool add(const Endpoint &ep) noexcept
 	{
 	{
-		if (_endpointCount >= ZT_LOCATOR_MAX_ENDPOINTS)
+		if (m_endpointCount >= ZT_LOCATOR_MAX_ENDPOINTS)
 			return false;
 			return false;
-		_at[_endpointCount++] = ep;
+		m_at[m_endpointCount++] = ep;
 		return true;
 		return true;
 	}
 	}
 
 
@@ -110,19 +110,19 @@ public:
 	 */
 	 */
 	bool verify(const Identity &id) const noexcept;
 	bool verify(const Identity &id) const noexcept;
 
 
-	explicit ZT_INLINE operator bool() const noexcept { return (_ts != 0); }
+	explicit ZT_INLINE operator bool() const noexcept { return (m_ts != 0); }
 
 
 	static constexpr int marshalSizeMax() noexcept { return ZT_LOCATOR_MARSHAL_SIZE_MAX; }
 	static constexpr int marshalSizeMax() noexcept { return ZT_LOCATOR_MARSHAL_SIZE_MAX; }
 	int marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX],bool excludeSignature = false) const noexcept;
 	int marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX],bool excludeSignature = false) const noexcept;
 	int unmarshal(const uint8_t *restrict data,int len) noexcept;
 	int unmarshal(const uint8_t *restrict data,int len) noexcept;
 
 
 private:
 private:
-	int64_t _ts;
-	unsigned int _endpointCount;
-	unsigned int _signatureLength;
-	Endpoint _at[ZT_LOCATOR_MAX_ENDPOINTS];
-	uint16_t _flags;
-	uint8_t _signature[ZT_SIGNATURE_BUFFER_SIZE];
+	int64_t m_ts;
+	unsigned int m_endpointCount;
+	unsigned int m_signatureLength;
+	Endpoint m_at[ZT_LOCATOR_MAX_ENDPOINTS];
+	uint16_t m_flags;
+	uint8_t m_signature[ZT_SIGNATURE_BUFFER_SIZE];
 };
 };
 
 
 } // namespace ZeroTier
 } // namespace ZeroTier

+ 39 - 39
node/MAC.hpp

@@ -31,26 +31,26 @@ namespace ZeroTier {
 class MAC : public TriviallyCopyable
 class MAC : public TriviallyCopyable
 {
 {
 public:
 public:
-	ZT_INLINE MAC() noexcept : _m(0ULL) {}
-	ZT_INLINE MAC(const uint8_t a,const uint8_t b,const uint8_t c,const uint8_t d,const uint8_t e,const uint8_t f) noexcept : _m((((uint64_t)a) << 40U) | (((uint64_t)b) << 32U) | (((uint64_t)c) << 24U) | (((uint64_t)d) << 16U) | (((uint64_t)e) << 8U) | ((uint64_t)f) ) {}
-	explicit ZT_INLINE MAC(const uint64_t m) noexcept : _m(m) {}
+	ZT_INLINE MAC() noexcept : m_mac(0ULL) {}
+	ZT_INLINE MAC(const uint8_t a,const uint8_t b,const uint8_t c,const uint8_t d,const uint8_t e,const uint8_t f) noexcept : m_mac((((uint64_t)a) << 40U) | (((uint64_t)b) << 32U) | (((uint64_t)c) << 24U) | (((uint64_t)d) << 16U) | (((uint64_t)e) << 8U) | ((uint64_t)f) ) {}
+	explicit ZT_INLINE MAC(const uint64_t m) noexcept : m_mac(m) {}
 	explicit ZT_INLINE MAC(const uint8_t b[6]) noexcept { setTo(b); } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
 	explicit ZT_INLINE MAC(const uint8_t b[6]) noexcept { setTo(b); } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
 	ZT_INLINE MAC(const Address &ztaddr,const uint64_t nwid) noexcept { fromAddress(ztaddr,nwid); } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
 	ZT_INLINE MAC(const Address &ztaddr,const uint64_t nwid) noexcept { fromAddress(ztaddr,nwid); } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
 
 
 	/**
 	/**
 	 * @return MAC in 64-bit integer
 	 * @return MAC in 64-bit integer
 	 */
 	 */
-	ZT_INLINE uint64_t toInt() const noexcept { return _m; }
+	ZT_INLINE uint64_t toInt() const noexcept { return m_mac; }
 
 
 	/**
 	/**
 	 * Set MAC to zero
 	 * Set MAC to zero
 	 */
 	 */
-	ZT_INLINE void zero() noexcept { _m = 0ULL; }
+	ZT_INLINE void zero() noexcept { m_mac = 0ULL; }
 
 
 	/**
 	/**
 	 * @return True if MAC is non-zero
 	 * @return True if MAC is non-zero
 	 */
 	 */
-	ZT_INLINE operator bool() const noexcept { return (_m != 0ULL); } // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
+	ZT_INLINE operator bool() const noexcept { return (m_mac != 0ULL); } // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
 
 
 	/**
 	/**
 	 * @param bits Raw MAC in big-endian byte order
 	 * @param bits Raw MAC in big-endian byte order
@@ -58,7 +58,7 @@ public:
 	 */
 	 */
 	ZT_INLINE void setTo(const uint8_t b[6]) noexcept
 	ZT_INLINE void setTo(const uint8_t b[6]) noexcept
 	{
 	{
-		_m = ((uint64_t)b[0] << 40U) | ((uint64_t)b[1] << 32U) | ((uint64_t)b[2] << 24U) | ((uint64_t)b[3] << 16U) | ((uint64_t)b[4] << 8U) | (uint64_t)b[5];
+		m_mac = ((uint64_t)b[0] << 40U) | ((uint64_t)b[1] << 32U) | ((uint64_t)b[2] << 24U) | ((uint64_t)b[3] << 16U) | ((uint64_t)b[4] << 8U) | (uint64_t)b[5];
 	}
 	}
 
 
 	/**
 	/**
@@ -67,23 +67,23 @@ public:
 	 */
 	 */
 	ZT_INLINE void copyTo(uint8_t b[6]) const noexcept
 	ZT_INLINE void copyTo(uint8_t b[6]) const noexcept
 	{
 	{
-		b[0] = (uint8_t)(_m >> 40U);
-		b[1] = (uint8_t)(_m >> 32U);
-		b[2] = (uint8_t)(_m >> 24U);
-		b[3] = (uint8_t)(_m >> 16U);
-		b[4] = (uint8_t)(_m >> 8U);
-		b[5] = (uint8_t)_m;
+		b[0] = (uint8_t)(m_mac >> 40U);
+		b[1] = (uint8_t)(m_mac >> 32U);
+		b[2] = (uint8_t)(m_mac >> 24U);
+		b[3] = (uint8_t)(m_mac >> 16U);
+		b[4] = (uint8_t)(m_mac >> 8U);
+		b[5] = (uint8_t)m_mac;
 	}
 	}
 
 
 	/**
 	/**
 	 * @return True if this is broadcast (all 0xff)
 	 * @return True if this is broadcast (all 0xff)
 	 */
 	 */
-	ZT_INLINE bool isBroadcast() const noexcept { return _m; }
+	ZT_INLINE bool isBroadcast() const noexcept { return m_mac; }
 
 
 	/**
 	/**
 	 * @return True if this is a multicast MAC
 	 * @return True if this is a multicast MAC
 	 */
 	 */
-	ZT_INLINE bool isMulticast() const noexcept { return ((_m & 0x010000000000ULL) != 0ULL); }
+	ZT_INLINE bool isMulticast() const noexcept { return ((m_mac & 0x010000000000ULL) != 0ULL); }
 
 
 	/**
 	/**
 	 * Set this MAC to a MAC derived from an address and a network ID
 	 * Set this MAC to a MAC derived from an address and a network ID
@@ -100,7 +100,7 @@ public:
 		m ^= ((nwid >> 24U) & 0xffU) << 16U;
 		m ^= ((nwid >> 24U) & 0xffU) << 16U;
 		m ^= ((nwid >> 32U) & 0xffU) << 8U;
 		m ^= ((nwid >> 32U) & 0xffU) << 8U;
 		m ^= (nwid >> 40U) & 0xffU;
 		m ^= (nwid >> 40U) & 0xffU;
-		_m = m;
+		m_mac = m;
 	}
 	}
 
 
 	/**
 	/**
@@ -112,7 +112,7 @@ public:
 	 */
 	 */
 	ZT_INLINE Address toAddress(uint64_t nwid) const noexcept
 	ZT_INLINE Address toAddress(uint64_t nwid) const noexcept
 	{
 	{
-		uint64_t a = _m & 0xffffffffffULL; // least significant 40 bits of MAC are formed from address
+		uint64_t a = m_mac & 0xffffffffffULL; // least significant 40 bits of MAC are formed from address
 		a ^= ((nwid >> 8U) & 0xffU) << 32U; // ... XORed with bits 8-48 of the nwid in little-endian byte order, so unmask it
 		a ^= ((nwid >> 8U) & 0xffU) << 32U; // ... XORed with bits 8-48 of the nwid in little-endian byte order, so unmask it
 		a ^= ((nwid >> 16U) & 0xffU) << 24U;
 		a ^= ((nwid >> 16U) & 0xffU) << 24U;
 		a ^= ((nwid >> 24U) & 0xffU) << 16U;
 		a ^= ((nwid >> 24U) & 0xffU) << 16U;
@@ -135,49 +135,49 @@ public:
 	 * @param i Value from 0 to 5 (inclusive)
 	 * @param i Value from 0 to 5 (inclusive)
 	 * @return Byte at said position (address interpreted in big-endian order)
 	 * @return Byte at said position (address interpreted in big-endian order)
 	 */
 	 */
-	ZT_INLINE uint8_t operator[](unsigned int i) const noexcept { return (uint8_t)(_m >> (40 - (i * 8))); }
+	ZT_INLINE uint8_t operator[](unsigned int i) const noexcept { return (uint8_t)(m_mac >> (40 - (i * 8))); }
 
 
 	/**
 	/**
 	 * @return 6, which is the number of bytes in a MAC, for container compliance
 	 * @return 6, which is the number of bytes in a MAC, for container compliance
 	 */
 	 */
 	ZT_INLINE unsigned int size() const noexcept { return 6; }
 	ZT_INLINE unsigned int size() const noexcept { return 6; }
 
 
-	ZT_INLINE unsigned long hashCode() const noexcept { return (unsigned long)Utils::hash64(_m); }
+	ZT_INLINE unsigned long hashCode() const noexcept { return (unsigned long)Utils::hash64(m_mac); }
 
 
 	ZT_INLINE char *toString(char buf[18]) const noexcept
 	ZT_INLINE char *toString(char buf[18]) const noexcept
 	{
 	{
-		buf[0] = Utils::HEXCHARS[(_m >> 44U) & 0xfU];
-		buf[1] = Utils::HEXCHARS[(_m >> 40U) & 0xfU];
+		buf[0] = Utils::HEXCHARS[(m_mac >> 44U) & 0xfU];
+		buf[1] = Utils::HEXCHARS[(m_mac >> 40U) & 0xfU];
 		buf[2] = ':';
 		buf[2] = ':';
-		buf[3] = Utils::HEXCHARS[(_m >> 36U) & 0xfU];
-		buf[4] = Utils::HEXCHARS[(_m >> 32U) & 0xfU];
+		buf[3] = Utils::HEXCHARS[(m_mac >> 36U) & 0xfU];
+		buf[4] = Utils::HEXCHARS[(m_mac >> 32U) & 0xfU];
 		buf[5] = ':';
 		buf[5] = ':';
-		buf[6] = Utils::HEXCHARS[(_m >> 28U) & 0xfU];
-		buf[7] = Utils::HEXCHARS[(_m >> 24U) & 0xfU];
+		buf[6] = Utils::HEXCHARS[(m_mac >> 28U) & 0xfU];
+		buf[7] = Utils::HEXCHARS[(m_mac >> 24U) & 0xfU];
 		buf[8] = ':';
 		buf[8] = ':';
-		buf[9] = Utils::HEXCHARS[(_m >> 20U) & 0xfU];
-		buf[10] = Utils::HEXCHARS[(_m >> 16U) & 0xfU];
+		buf[9] = Utils::HEXCHARS[(m_mac >> 20U) & 0xfU];
+		buf[10] = Utils::HEXCHARS[(m_mac >> 16U) & 0xfU];
 		buf[11] = ':';
 		buf[11] = ':';
-		buf[12] = Utils::HEXCHARS[(_m >> 12U) & 0xfU];
-		buf[13] = Utils::HEXCHARS[(_m >> 8U) & 0xfU];
+		buf[12] = Utils::HEXCHARS[(m_mac >> 12U) & 0xfU];
+		buf[13] = Utils::HEXCHARS[(m_mac >> 8U) & 0xfU];
 		buf[14] = ':';
 		buf[14] = ':';
-		buf[15] = Utils::HEXCHARS[(_m >> 4U) & 0xfU];
-		buf[16] = Utils::HEXCHARS[_m & 0xfU];
+		buf[15] = Utils::HEXCHARS[(m_mac >> 4U) & 0xfU];
+		buf[16] = Utils::HEXCHARS[m_mac & 0xfU];
 		buf[17] = (char)0;
 		buf[17] = (char)0;
 		return buf;
 		return buf;
 	}
 	}
 
 
-	ZT_INLINE MAC &operator=(const uint64_t m) noexcept { _m = m; return *this; }
+	ZT_INLINE MAC &operator=(const uint64_t m) noexcept { m_mac = m; return *this; }
 
 
-	ZT_INLINE bool operator==(const MAC &m) const noexcept { return (_m == m._m); }
-	ZT_INLINE bool operator!=(const MAC &m) const noexcept { return (_m != m._m); }
-	ZT_INLINE bool operator<(const MAC &m) const noexcept { return (_m < m._m); }
-	ZT_INLINE bool operator<=(const MAC &m) const noexcept { return (_m <= m._m); }
-	ZT_INLINE bool operator>(const MAC &m) const noexcept { return (_m > m._m); }
-	ZT_INLINE bool operator>=(const MAC &m) const noexcept { return (_m >= m._m); }
+	ZT_INLINE bool operator==(const MAC &m) const noexcept { return (m_mac == m.m_mac); }
+	ZT_INLINE bool operator!=(const MAC &m) const noexcept { return (m_mac != m.m_mac); }
+	ZT_INLINE bool operator<(const MAC &m) const noexcept { return (m_mac < m.m_mac); }
+	ZT_INLINE bool operator<=(const MAC &m) const noexcept { return (m_mac <= m.m_mac); }
+	ZT_INLINE bool operator>(const MAC &m) const noexcept { return (m_mac > m.m_mac); }
+	ZT_INLINE bool operator>=(const MAC &m) const noexcept { return (m_mac >= m.m_mac); }
 
 
 private:
 private:
-	uint64_t _m;
+	uint64_t m_mac;
 };
 };
 
 
 } // namespace ZeroTier
 } // namespace ZeroTier

+ 20 - 20
node/Membership.cpp

@@ -21,10 +21,10 @@
 namespace ZeroTier {
 namespace ZeroTier {
 
 
 Membership::Membership() :
 Membership::Membership() :
-	_comRevocationThreshold(0),
-	_lastPushedCredentials(0),
-	_comAgreementLocalTimestamp(0),
-	_comAgreementRemoteTimestamp(0)
+	m_comRevocationThreshold(0),
+	m_lastPushedCredentials(0),
+	m_comAgreementLocalTimestamp(0),
+	m_comAgreementRemoteTimestamp(0)
 {
 {
 }
 }
 
 
@@ -110,30 +110,30 @@ void Membership::pushCredentials(const RuntimeEnvironment *RR,void *tPtr,const i
 		}
 		}
 	}
 	}
 
 
-	_lastPushedCredentials = now;
+	m_lastPushedCredentials = now;
 }
 }
 
 
 void Membership::clean(const int64_t now,const NetworkConfig &nconf)
 void Membership::clean(const int64_t now,const NetworkConfig &nconf)
 {
 {
-	_cleanCredImpl<Tag>(nconf,_remoteTags);
-	_cleanCredImpl<Capability>(nconf,_remoteCaps);
-	_cleanCredImpl<CertificateOfOwnership>(nconf,_remoteCoos);
+	m_cleanCredImpl<Tag>(nconf, m_remoteTags);
+	m_cleanCredImpl<Capability>(nconf, m_remoteCaps);
+	m_cleanCredImpl<CertificateOfOwnership>(nconf, m_remoteCoos);
 }
 }
 
 
 Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const Identity &sourcePeerIdentity,const NetworkConfig &nconf,const CertificateOfMembership &com)
 Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const Identity &sourcePeerIdentity,const NetworkConfig &nconf,const CertificateOfMembership &com)
 {
 {
 	const int64_t newts = com.timestamp();
 	const int64_t newts = com.timestamp();
-	if (newts <= _comRevocationThreshold) {
+	if (newts <= m_comRevocationThreshold) {
 		RR->t->credentialRejected(tPtr,0xd9992121,com.networkId(),sourcePeerIdentity.address(),sourcePeerIdentity,com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
 		RR->t->credentialRejected(tPtr,0xd9992121,com.networkId(),sourcePeerIdentity.address(),sourcePeerIdentity,com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
 		return ADD_REJECTED;
 		return ADD_REJECTED;
 	}
 	}
 
 
-	const int64_t oldts = _com.timestamp();
+	const int64_t oldts = m_com.timestamp();
 	if (newts < oldts) {
 	if (newts < oldts) {
 		RR->t->credentialRejected(tPtr,0xd9928192,com.networkId(),sourcePeerIdentity.address(),sourcePeerIdentity,com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
 		RR->t->credentialRejected(tPtr,0xd9928192,com.networkId(),sourcePeerIdentity.address(),sourcePeerIdentity,com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
 		return ADD_REJECTED;
 		return ADD_REJECTED;
 	}
 	}
-	if ((newts == oldts)&&(_com == com))
+	if ((newts == oldts)&&(m_com == com))
 		return ADD_ACCEPTED_REDUNDANT;
 		return ADD_ACCEPTED_REDUNDANT;
 
 
 	switch(com.verify(RR,tPtr)) {
 	switch(com.verify(RR,tPtr)) {
@@ -141,7 +141,7 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
 			RR->t->credentialRejected(tPtr,0x0f198241,com.networkId(),sourcePeerIdentity.address(),sourcePeerIdentity,com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
 			RR->t->credentialRejected(tPtr,0x0f198241,com.networkId(),sourcePeerIdentity.address(),sourcePeerIdentity,com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
 			return Membership::ADD_REJECTED;
 			return Membership::ADD_REJECTED;
 		case Credential::VERIFY_OK:
 		case Credential::VERIFY_OK:
-			_com = com;
+			m_com = com;
 			return ADD_ACCEPTED_NEW;
 			return ADD_ACCEPTED_NEW;
 		case Credential::VERIFY_BAD_SIGNATURE:
 		case Credential::VERIFY_BAD_SIGNATURE:
 			RR->t->credentialRejected(tPtr,0xbaf0aaaa,com.networkId(),sourcePeerIdentity.address(),sourcePeerIdentity,com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_SIGNATURE_VERIFICATION_FAILED);
 			RR->t->credentialRejected(tPtr,0xbaf0aaaa,com.networkId(),sourcePeerIdentity.address(),sourcePeerIdentity,com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_SIGNATURE_VERIFICATION_FAILED);
@@ -191,9 +191,9 @@ static ZT_INLINE Membership::AddCredentialResult _addCredImpl(
 			return Membership::ADD_DEFERRED_FOR_WHOIS;
 			return Membership::ADD_DEFERRED_FOR_WHOIS;
 	}
 	}
 }
 }
-Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const Identity &sourcePeerIdentity,const NetworkConfig &nconf,const Tag &tag) { return _addCredImpl<Tag>(_remoteTags,_revocations,RR,tPtr,sourcePeerIdentity,nconf,tag); }
-Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const Identity &sourcePeerIdentity,const NetworkConfig &nconf,const Capability &cap) { return _addCredImpl<Capability>(_remoteCaps,_revocations,RR,tPtr,sourcePeerIdentity,nconf,cap); }
-Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const Identity &sourcePeerIdentity,const NetworkConfig &nconf,const CertificateOfOwnership &coo) { return _addCredImpl<CertificateOfOwnership>(_remoteCoos,_revocations,RR,tPtr,sourcePeerIdentity,nconf,coo); }
+Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const Identity &sourcePeerIdentity,const NetworkConfig &nconf,const Tag &tag) { return _addCredImpl<Tag>(m_remoteTags, m_revocations, RR, tPtr, sourcePeerIdentity, nconf, tag); }
+Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const Identity &sourcePeerIdentity,const NetworkConfig &nconf,const Capability &cap) { return _addCredImpl<Capability>(m_remoteCaps, m_revocations, RR, tPtr, sourcePeerIdentity, nconf, cap); }
+Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const Identity &sourcePeerIdentity,const NetworkConfig &nconf,const CertificateOfOwnership &coo) { return _addCredImpl<CertificateOfOwnership>(m_remoteCoos, m_revocations, RR, tPtr, sourcePeerIdentity, nconf, coo); }
 
 
 Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const Identity &sourcePeerIdentity,const NetworkConfig &nconf,const Revocation &rev)
 Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const Identity &sourcePeerIdentity,const NetworkConfig &nconf,const Revocation &rev)
 {
 {
@@ -206,18 +206,18 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
 			const ZT_CredentialType ct = rev.typeBeingRevoked();
 			const ZT_CredentialType ct = rev.typeBeingRevoked();
 			switch(ct) {
 			switch(ct) {
 				case ZT_CREDENTIAL_TYPE_COM:
 				case ZT_CREDENTIAL_TYPE_COM:
-					if (rev.threshold() > _comRevocationThreshold) {
-						_comRevocationThreshold = rev.threshold();
+					if (rev.threshold() > m_comRevocationThreshold) {
+						m_comRevocationThreshold = rev.threshold();
 						return ADD_ACCEPTED_NEW;
 						return ADD_ACCEPTED_NEW;
 					}
 					}
 					return ADD_ACCEPTED_REDUNDANT;
 					return ADD_ACCEPTED_REDUNDANT;
 				case ZT_CREDENTIAL_TYPE_CAPABILITY:
 				case ZT_CREDENTIAL_TYPE_CAPABILITY:
 				case ZT_CREDENTIAL_TYPE_TAG:
 				case ZT_CREDENTIAL_TYPE_TAG:
 				case ZT_CREDENTIAL_TYPE_COO:
 				case ZT_CREDENTIAL_TYPE_COO:
-					rt = &(_revocations[credentialKey(ct,rev.credentialId())]);
+					rt = &(m_revocations[credentialKey(ct, rev.credentialId())]);
 					if (*rt < rev.threshold()) {
 					if (*rt < rev.threshold()) {
 						*rt = rev.threshold();
 						*rt = rev.threshold();
-						_comRevocationThreshold = rev.threshold();
+						m_comRevocationThreshold = rev.threshold();
 						return ADD_ACCEPTED_NEW;
 						return ADD_ACCEPTED_NEW;
 					}
 					}
 					return ADD_ACCEPTED_REDUNDANT;
 					return ADD_ACCEPTED_REDUNDANT;
@@ -231,7 +231,7 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
 	}
 	}
 }
 }
 
 
-bool Membership::_isUnspoofableAddress(const NetworkConfig &nconf,const InetAddress &ip) const noexcept
+bool Membership::m_isUnspoofableAddress(const NetworkConfig &nconf, const InetAddress &ip) const noexcept
 {
 {
 	if ((ip.isV6())&&(nconf.ndpEmulation())) {
 	if ((ip.isV6())&&(nconf.ndpEmulation())) {
 		const InetAddress sixpl(InetAddress::makeIpv66plane(nconf.networkId,nconf.issuedTo.toInt()));
 		const InetAddress sixpl(InetAddress::makeIpv66plane(nconf.networkId,nconf.issuedTo.toInt()));

+ 35 - 35
node/Membership.hpp

@@ -64,7 +64,7 @@ public:
 	/**
 	/**
 	 * @return Time we last pushed credentials to this member
 	 * @return Time we last pushed credentials to this member
 	 */
 	 */
-	ZT_INLINE int64_t lastPushedCredentials() const noexcept { return _lastPushedCredentials; }
+	ZT_INLINE int64_t lastPushedCredentials() const noexcept { return m_lastPushedCredentials; }
 
 
 	/**
 	/**
 	 * Get a remote member's tag (if we have it)
 	 * Get a remote member's tag (if we have it)
@@ -75,8 +75,8 @@ public:
 	 */
 	 */
 	ZT_INLINE const Tag *getTag(const NetworkConfig &nconf,const uint32_t id) const noexcept
 	ZT_INLINE const Tag *getTag(const NetworkConfig &nconf,const uint32_t id) const noexcept
 	{
 	{
-		const Tag *const t = _remoteTags.get(id);
-		return (((t)&&(_isCredentialTimestampValid(nconf,*t))) ? t : (Tag *)0);
+		const Tag *const t = m_remoteTags.get(id);
+		return (((t)&&(m_isCredentialTimestampValid(nconf, *t))) ? t : (Tag *)0);
 	}
 	}
 
 
 	/**
 	/**
@@ -103,10 +103,10 @@ public:
 	template<typename T>
 	template<typename T>
 	ZT_INLINE bool peerOwnsAddress(const NetworkConfig &nconf,const T &r) const noexcept
 	ZT_INLINE bool peerOwnsAddress(const NetworkConfig &nconf,const T &r) const noexcept
 	{
 	{
-		if (_isUnspoofableAddress(nconf,r))
+		if (s_isUnspoofableAddress(nconf, r))
 			return true;
 			return true;
-		for(Map< uint32_t,CertificateOfOwnership >::const_iterator i(_remoteCoos.begin());i!=_remoteCoos.end();++i) {
-			if (_isCredentialTimestampValid(nconf,i->second)&&(i->second.owns(r)))
+		for(Map< uint32_t,CertificateOfOwnership >::const_iterator i(m_remoteCoos.begin());i != m_remoteCoos.end();++i) {
+			if (m_isCredentialTimestampValid(nconf, i->second) && (i->second.owns(r)))
 				return true;
 				return true;
 		}
 		}
 		return false;
 		return false;
@@ -119,9 +119,9 @@ public:
 	 */
 	 */
 	ZT_INLINE bool certificateOfMembershipAgress(const CertificateOfMembership &localCom,const Identity &remoteIdentity)
 	ZT_INLINE bool certificateOfMembershipAgress(const CertificateOfMembership &localCom,const Identity &remoteIdentity)
 	{
 	{
-		if ((_comAgreementLocalTimestamp == localCom.timestamp())&&(_comAgreementRemoteTimestamp == _com.timestamp()))
+		if ((m_comAgreementLocalTimestamp == localCom.timestamp()) && (m_comAgreementRemoteTimestamp == m_com.timestamp()))
 			return true;
 			return true;
-		if (_com.agreesWith(localCom)) {
+		if (m_com.agreesWith(localCom)) {
 			// SECURITY: newer network controllers embed the full fingerprint into the COM. If we are
 			// SECURITY: newer network controllers embed the full fingerprint into the COM. If we are
 			// joined to a network managed by one of these, our COM will contain one. If it's present
 			// joined to a network managed by one of these, our COM will contain one. If it's present
 			// we compare vs the other and require them to match. If our COM does not contain a full
 			// we compare vs the other and require them to match. If our COM does not contain a full
@@ -130,18 +130,18 @@ public:
 			// and in so doing indicates if it's new or old. However this will go away after a while
 			// and in so doing indicates if it's new or old. However this will go away after a while
 			// once we can be pretty sure there are no ancient controllers around.
 			// once we can be pretty sure there are no ancient controllers around.
 			if (localCom.issuedTo().haveHash()) {
 			if (localCom.issuedTo().haveHash()) {
-				if (localCom.issuedTo() != _com.issuedTo())
+				if (localCom.issuedTo() != m_com.issuedTo())
 					return false;
 					return false;
 			} else {
 			} else {
 				// LEGACY: support networks run by old controllers.
 				// LEGACY: support networks run by old controllers.
-				if (localCom.issuedTo().address() != _com.issuedTo().address())
+				if (localCom.issuedTo().address() != m_com.issuedTo().address())
 					return false;
 					return false;
 			}
 			}
 
 
 			// Remember that these two COMs agreed. If any are updated this is invalidated and a full
 			// Remember that these two COMs agreed. If any are updated this is invalidated and a full
 			// agreement check will be done again.
 			// agreement check will be done again.
-			_comAgreementLocalTimestamp = localCom.timestamp();
-			_comAgreementRemoteTimestamp = _com.timestamp();
+			m_comAgreementLocalTimestamp = localCom.timestamp();
+			m_comAgreementRemoteTimestamp = m_com.timestamp();
 
 
 			return true;
 			return true;
 		}
 		}
@@ -158,77 +158,77 @@ private:
 	// This returns true if a resource is an IPv6 NDP-emulated address. These embed the ZT
 	// This returns true if a resource is an IPv6 NDP-emulated address. These embed the ZT
 	// address of the peer and therefore cannot be spoofed, causing peerOwnsAddress() to
 	// address of the peer and therefore cannot be spoofed, causing peerOwnsAddress() to
 	// always return true for them. A certificate is not required for these.
 	// always return true for them. A certificate is not required for these.
-	ZT_INLINE bool _isUnspoofableAddress(const NetworkConfig &nconf,const MAC &m) const noexcept { return false; }
-	bool _isUnspoofableAddress(const NetworkConfig &nconf,const InetAddress &ip) const noexcept;
+	ZT_INLINE static bool s_isUnspoofableAddress(const NetworkConfig &nconf, const MAC &m) noexcept { return false; }
+	bool m_isUnspoofableAddress(const NetworkConfig &nconf, const InetAddress &ip) const noexcept;
 
 
 	// This compares the remote credential's timestamp to the timestamp in our network config
 	// This compares the remote credential's timestamp to the timestamp in our network config
 	// plus or minus the permitted maximum timestamp delta.
 	// plus or minus the permitted maximum timestamp delta.
 	template<typename C>
 	template<typename C>
-	ZT_INLINE bool _isCredentialTimestampValid(const NetworkConfig &nconf,const C &remoteCredential) const noexcept
+	ZT_INLINE bool m_isCredentialTimestampValid(const NetworkConfig &nconf, const C &remoteCredential) const noexcept
 	{
 	{
 		const int64_t ts = remoteCredential.timestamp();
 		const int64_t ts = remoteCredential.timestamp();
 		if (((ts >= nconf.timestamp) ? (ts - nconf.timestamp) : (nconf.timestamp - ts)) <= nconf.credentialTimeMaxDelta) {
 		if (((ts >= nconf.timestamp) ? (ts - nconf.timestamp) : (nconf.timestamp - ts)) <= nconf.credentialTimeMaxDelta) {
-			const int64_t *threshold = _revocations.get(credentialKey(C::credentialType(),remoteCredential.id()));
+			const int64_t *threshold = m_revocations.get(credentialKey(C::credentialType(), remoteCredential.id()));
 			return ((!threshold)||(ts > *threshold));
 			return ((!threshold)||(ts > *threshold));
 		}
 		}
 		return false;
 		return false;
 	}
 	}
 
 
 	template<typename C>
 	template<typename C>
-	ZT_INLINE void _cleanCredImpl(const NetworkConfig &nconf,Map<uint32_t,C> &remoteCreds)
+	ZT_INLINE void m_cleanCredImpl(const NetworkConfig &nconf, Map<uint32_t,C> &remoteCreds)
 	{
 	{
 		for(typename Map<uint32_t,C>::iterator i(remoteCreds.begin());i!=remoteCreds.end();) {
 		for(typename Map<uint32_t,C>::iterator i(remoteCreds.begin());i!=remoteCreds.end();) {
-			if (!_isCredentialTimestampValid(nconf,i->second))
+			if (!m_isCredentialTimestampValid(nconf, i->second))
 				remoteCreds.erase(i++);
 				remoteCreds.erase(i++);
 			else ++i;
 			else ++i;
 		}
 		}
 	}
 	}
 
 
 	// Revocation threshold for COM or 0 if none
 	// Revocation threshold for COM or 0 if none
-	int64_t _comRevocationThreshold;
+	int64_t m_comRevocationThreshold;
 
 
 	// Time we last pushed credentials
 	// Time we last pushed credentials
-	int64_t _lastPushedCredentials;
+	int64_t m_lastPushedCredentials;
 
 
 	// COM timestamps at which we last agreed-- used to memo-ize agreement and avoid having to recompute constantly.
 	// COM timestamps at which we last agreed-- used to memo-ize agreement and avoid having to recompute constantly.
-	int64_t _comAgreementLocalTimestamp,_comAgreementRemoteTimestamp;
+	int64_t m_comAgreementLocalTimestamp,m_comAgreementRemoteTimestamp;
 
 
 	// Remote member's latest network COM
 	// Remote member's latest network COM
-	CertificateOfMembership _com;
+	CertificateOfMembership m_com;
 
 
 	// Revocations by credentialKey()
 	// Revocations by credentialKey()
-	Map< uint64_t,int64_t > _revocations;
+	Map<uint64_t,int64_t> m_revocations;
 
 
 	// Remote credentials that we have received from this member (and that are valid)
 	// Remote credentials that we have received from this member (and that are valid)
-	Map< uint32_t,Tag > _remoteTags;
-	Map< uint32_t,Capability > _remoteCaps;
-	Map< uint32_t,CertificateOfOwnership > _remoteCoos;
+	Map<uint32_t,Tag> m_remoteTags;
+	Map<uint32_t,Capability> m_remoteCaps;
+	Map<uint32_t,CertificateOfOwnership> m_remoteCoos;
 
 
 public:
 public:
 	class CapabilityIterator
 	class CapabilityIterator
 	{
 	{
 	public:
 	public:
 		ZT_INLINE CapabilityIterator(Membership &m,const NetworkConfig &nconf) noexcept :
 		ZT_INLINE CapabilityIterator(Membership &m,const NetworkConfig &nconf) noexcept :
-			_hti(m._remoteCaps.begin()),
-			_m(m),
-			_nconf(nconf)
+			m_hti(m.m_remoteCaps.begin()),
+			m_parent(m),
+			m_nconf(nconf)
 		{
 		{
 		}
 		}
 
 
 		ZT_INLINE Capability *next() noexcept
 		ZT_INLINE Capability *next() noexcept
 		{
 		{
-			while (_hti != _m._remoteCaps.end()) {
-				Map< uint32_t,Capability >::iterator i(_hti++); // NOLINT(hicpp-use-auto,modernize-use-auto)
-				if (_m._isCredentialTimestampValid(_nconf,i->second))
+			while (m_hti != m_parent.m_remoteCaps.end()) {
+				Map< uint32_t,Capability >::iterator i(m_hti++); // NOLINT(hicpp-use-auto,modernize-use-auto)
+				if (m_parent.m_isCredentialTimestampValid(m_nconf, i->second))
 					return &(i->second);
 					return &(i->second);
 			}
 			}
 			return nullptr;
 			return nullptr;
 		}
 		}
 
 
 	private:
 	private:
-		Map< uint32_t,Capability >::iterator _hti;
-		Membership &_m;
-		const NetworkConfig &_nconf;
+		Map< uint32_t,Capability >::iterator m_hti;
+		Membership &m_parent;
+		const NetworkConfig &m_nconf;
 	};
 	};
 };
 };
 
 

+ 8 - 8
node/Meter.hpp

@@ -57,10 +57,10 @@ public:
 		// the log size and then if it's a new bucket setting it or otherwise adding
 		// the log size and then if it's a new bucket setting it or otherwise adding
 		// to it.
 		// to it.
 		const unsigned long bucket = ((unsigned long)(now / TUNIT)) % LSIZE;
 		const unsigned long bucket = ((unsigned long)(now / TUNIT)) % LSIZE;
-		if (_bucket.exchange(bucket) != bucket) {
-			_totalExclCounts.fetch_add(_counts[bucket].exchange(count));
+		if (m_bucket.exchange(bucket) != bucket) {
+			m_totalExclCounts.fetch_add(m_counts[bucket].exchange(count));
 		} else {
 		} else {
-			_counts[bucket].fetch_add(count);
+			m_counts[bucket].fetch_add(count);
 		}
 		}
 	}
 	}
 
 
@@ -75,15 +75,15 @@ public:
 	{
 	{
 		total = 0;
 		total = 0;
 		for(unsigned long i=0;i<LSIZE;++i)
 		for(unsigned long i=0;i<LSIZE;++i)
-			total += _counts[i].load();
+			total += m_counts[i].load();
 		rate = (double)total / (double)LSIZE;
 		rate = (double)total / (double)LSIZE;
-		total += _totalExclCounts.load();
+		total += m_totalExclCounts.load();
 	}
 	}
 
 
 private:
 private:
-	std::atomic<uint64_t> _counts[LSIZE];
-	std::atomic<uint64_t> _totalExclCounts;
-	std::atomic<unsigned long> _bucket;
+	std::atomic<uint64_t> m_counts[LSIZE];
+	std::atomic<uint64_t> m_totalExclCounts;
+	std::atomic<unsigned long> m_bucket;
 };
 };
 
 
 } // namespace ZeroTier
 } // namespace ZeroTier

+ 12 - 12
node/MulticastGroup.hpp

@@ -42,8 +42,8 @@ namespace ZeroTier {
 class MulticastGroup : public TriviallyCopyable
 class MulticastGroup : public TriviallyCopyable
 {
 {
 public:
 public:
-	ZT_INLINE MulticastGroup() noexcept : _mac(),_adi(0) {}
-	ZT_INLINE MulticastGroup(const MAC &m,uint32_t a) noexcept : _mac(m),_adi(a) {}
+	ZT_INLINE MulticastGroup() noexcept : m_mac(), m_adi(0) {}
+	ZT_INLINE MulticastGroup(const MAC &m,uint32_t a) noexcept : m_mac(m), m_adi(a) {}
 
 
 	/**
 	/**
 	 * Derive the multicast group used for address resolution (ARP/NDP) for an IP
 	 * Derive the multicast group used for address resolution (ARP/NDP) for an IP
@@ -73,32 +73,32 @@ public:
 	/**
 	/**
 	 * @return Ethernet MAC portion of multicast group
 	 * @return Ethernet MAC portion of multicast group
 	 */
 	 */
-	ZT_INLINE const MAC &mac() const noexcept { return _mac; }
+	ZT_INLINE const MAC &mac() const noexcept { return m_mac; }
 
 
 	/**
 	/**
 	 * @return Additional distinguishing information, which is normally zero except for IPv4 ARP where it's the IPv4 address
 	 * @return Additional distinguishing information, which is normally zero except for IPv4 ARP where it's the IPv4 address
 	 */
 	 */
-	ZT_INLINE uint32_t adi() const { return _adi; }
+	ZT_INLINE uint32_t adi() const { return m_adi; }
 
 
-	ZT_INLINE bool operator==(const MulticastGroup &g) const noexcept { return ((_mac == g._mac) && (_adi == g._adi)); }
-	ZT_INLINE bool operator!=(const MulticastGroup &g) const noexcept { return ((_mac != g._mac) || (_adi != g._adi)); }
+	ZT_INLINE bool operator==(const MulticastGroup &g) const noexcept { return ((m_mac == g.m_mac) && (m_adi == g.m_adi)); }
+	ZT_INLINE bool operator!=(const MulticastGroup &g) const noexcept { return ((m_mac != g.m_mac) || (m_adi != g.m_adi)); }
 	ZT_INLINE bool operator<(const MulticastGroup &g) const noexcept
 	ZT_INLINE bool operator<(const MulticastGroup &g) const noexcept
 	{
 	{
-		if (_mac < g._mac)
+		if (m_mac < g.m_mac)
 			return true;
 			return true;
-		else if (_mac == g._mac)
-			return (_adi < g._adi);
+		else if (m_mac == g.m_mac)
+			return (m_adi < g.m_adi);
 		return false;
 		return false;
 	}
 	}
 	ZT_INLINE bool operator>(const MulticastGroup &g) const noexcept { return (g < *this); }
 	ZT_INLINE bool operator>(const MulticastGroup &g) const noexcept { return (g < *this); }
 	ZT_INLINE bool operator<=(const MulticastGroup &g) const noexcept { return !(g < *this); }
 	ZT_INLINE bool operator<=(const MulticastGroup &g) const noexcept { return !(g < *this); }
 	ZT_INLINE bool operator>=(const MulticastGroup &g) const noexcept { return !(*this < g); }
 	ZT_INLINE bool operator>=(const MulticastGroup &g) const noexcept { return !(*this < g); }
 
 
-	ZT_INLINE unsigned long hashCode() const noexcept { return (_mac.hashCode() + (unsigned long)_adi); }
+	ZT_INLINE unsigned long hashCode() const noexcept { return (m_mac.hashCode() + (unsigned long)m_adi); }
 
 
 private:
 private:
-	MAC _mac;
-	uint32_t _adi;
+	MAC m_mac;
+	uint32_t m_adi;
 };
 };
 
 
 } // namespace ZeroTier
 } // namespace ZeroTier

+ 150 - 150
node/Network.cpp

@@ -535,20 +535,20 @@ const ZeroTier::MulticastGroup Network::BROADCAST(ZeroTier::MAC(0xffffffffffffUL
 
 
 Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,const Fingerprint &controllerFingerprint,void *uptr,const NetworkConfig *nconf) :
 Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,const Fingerprint &controllerFingerprint,void *uptr,const NetworkConfig *nconf) :
 	RR(renv),
 	RR(renv),
-	_uPtr(uptr),
-	_id(nwid),
-	_mac(renv->identity.address(),nwid),
-	_portInitialized(false),
-	_lastConfigUpdate(0),
-	_destroyed(false),
+	m_uPtr(uptr),
+	m_id(nwid),
+	m_mac(renv->identity.address(), nwid),
+	m_portInitialized(false),
+	m_lastConfigUpdate(0),
+	m_destroyed(false),
 	_netconfFailure(NETCONF_FAILURE_NONE)
 	_netconfFailure(NETCONF_FAILURE_NONE)
 {
 {
 	if (controllerFingerprint)
 	if (controllerFingerprint)
-		_controllerFingerprint = controllerFingerprint;
+		m_controllerFingerprint = controllerFingerprint;
 
 
 	if (nconf) {
 	if (nconf) {
 		this->setConfiguration(tPtr,*nconf,false);
 		this->setConfiguration(tPtr,*nconf,false);
-		_lastConfigUpdate = 0; // still want to re-request since it's likely outdated
+		m_lastConfigUpdate = 0; // still want to re-request since it's likely outdated
 	} else {
 	} else {
 		uint64_t tmp[2];
 		uint64_t tmp[2];
 		tmp[0] = nwid; tmp[1] = 0;
 		tmp[0] = nwid; tmp[1] = 0;
@@ -564,7 +564,7 @@ Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,const F
 						ScopedPtr<NetworkConfig> nconf2(new NetworkConfig());
 						ScopedPtr<NetworkConfig> nconf2(new NetworkConfig());
 						if (nconf2->fromDictionary(dict)) {
 						if (nconf2->fromDictionary(dict)) {
 							this->setConfiguration(tPtr,*nconf2,false);
 							this->setConfiguration(tPtr,*nconf2,false);
-							_lastConfigUpdate = 0; // still want to re-request an update since it's likely outdated
+							m_lastConfigUpdate = 0; // still want to re-request an update since it's likely outdated
 							got = true;
 							got = true;
 						}
 						}
 					} catch (...) {}
 					} catch (...) {}
@@ -576,29 +576,29 @@ Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,const F
 			RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp,"\n",1);
 			RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp,"\n",1);
 	}
 	}
 
 
-	if (!_portInitialized) {
+	if (!m_portInitialized) {
 		ZT_VirtualNetworkConfig ctmp;
 		ZT_VirtualNetworkConfig ctmp;
-		_externalConfig(&ctmp);
-		RR->node->configureVirtualNetworkPort(tPtr,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp);
-		_portInitialized = true;
+		m_externalConfig(&ctmp);
+		RR->node->configureVirtualNetworkPort(tPtr, m_id, &m_uPtr, ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP, &ctmp);
+		m_portInitialized = true;
 	}
 	}
 }
 }
 
 
 Network::~Network()
 Network::~Network()
 {
 {
-	_memberships_l.lock();
-	_config_l.lock();
-	_config_l.unlock();
-	_memberships_l.unlock();
+	m_memberships_l.lock();
+	m_config_l.lock();
+	m_config_l.unlock();
+	m_memberships_l.unlock();
 
 
 	ZT_VirtualNetworkConfig ctmp;
 	ZT_VirtualNetworkConfig ctmp;
-	_externalConfig(&ctmp);
+	m_externalConfig(&ctmp);
 
 
-	if (_destroyed) {
+	if (m_destroyed) {
 		// This is done in Node::leave() so we can pass tPtr properly
 		// This is done in Node::leave() so we can pass tPtr properly
 		//RR->node->configureVirtualNetworkPort((void *)0,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp);
 		//RR->node->configureVirtualNetworkPort((void *)0,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp);
 	} else {
 	} else {
-		RR->node->configureVirtualNetworkPort(nullptr,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN,&ctmp);
+		RR->node->configureVirtualNetworkPort(nullptr, m_id, &m_uPtr, ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN, &ctmp);
 	}
 	}
 }
 }
 
 
@@ -623,20 +623,20 @@ bool Network::filterOutgoingPacket(
 	unsigned int ccLength = 0;
 	unsigned int ccLength = 0;
 	bool ccWatch = false;
 	bool ccWatch = false;
 
 
-	Mutex::Lock l1(_memberships_l);
-	Mutex::Lock l2(_config_l);
+	Mutex::Lock l1(m_memberships_l);
+	Mutex::Lock l2(m_config_l);
 
 
-	Membership *const membership = (ztDest) ? _memberships.get(ztDest) : nullptr;
+	Membership *const membership = (ztDest) ? m_memberships.get(ztDest) : nullptr;
 
 
-	switch(_doZtFilter(RR,rrl,_config,membership,false,ztSource,ztFinalDest,macSource,macDest,frameData,frameLen,etherType,vlanId,_config.rules,_config.ruleCount,cc,ccLength,ccWatch,qosBucket)) {
+	switch(_doZtFilter(RR, rrl, m_config, membership, false, ztSource, ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, m_config.rules, m_config.ruleCount, cc, ccLength, ccWatch, qosBucket)) {
 
 
 		case DOZTFILTER_NO_MATCH: {
 		case DOZTFILTER_NO_MATCH: {
-			for(unsigned int c=0;c<_config.capabilityCount;++c) {
+			for(unsigned int c=0;c < m_config.capabilityCount;++c) {
 				ztFinalDest = ztDest; // sanity check, shouldn't be possible if there was no match
 				ztFinalDest = ztDest; // sanity check, shouldn't be possible if there was no match
 				Address cc2;
 				Address cc2;
 				unsigned int ccLength2 = 0;
 				unsigned int ccLength2 = 0;
 				bool ccWatch2 = false;
 				bool ccWatch2 = false;
-				switch (_doZtFilter(RR,crrl,_config,membership,false,ztSource,ztFinalDest,macSource,macDest,frameData,frameLen,etherType,vlanId,_config.capabilities[c].rules(),_config.capabilities[c].ruleCount(),cc2,ccLength2,ccWatch2,qosBucket)) {
+				switch (_doZtFilter(RR, crrl, m_config, membership, false, ztSource, ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, m_config.capabilities[c].rules(), m_config.capabilities[c].ruleCount(), cc2, ccLength2, ccWatch2, qosBucket)) {
 					case DOZTFILTER_NO_MATCH:
 					case DOZTFILTER_NO_MATCH:
 					case DOZTFILTER_DROP: // explicit DROP in a capability just terminates its evaluation and is an anti-pattern
 					case DOZTFILTER_DROP: // explicit DROP in a capability just terminates its evaluation and is an anti-pattern
 						break;
 						break;
@@ -670,7 +670,7 @@ bool Network::filterOutgoingPacket(
 		}	break;
 		}	break;
 
 
 		case DOZTFILTER_DROP:
 		case DOZTFILTER_DROP:
-			RR->t->networkFilter(tPtr,0xadea5a2a,_id,rrl.l,nullptr,0,0,ztSource,ztDest,macSource,macDest,(uint16_t)frameLen,frameData,(uint16_t)etherType,(uint16_t)vlanId,noTee,false,0);
+			RR->t->networkFilter(tPtr, 0xadea5a2a, m_id, rrl.l, nullptr, 0, 0, ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, 0);
 			return false;
 			return false;
 
 
 		case DOZTFILTER_REDIRECT: // interpreted as ACCEPT but ztFinalDest will have been changed in _doZtFilter()
 		case DOZTFILTER_REDIRECT: // interpreted as ACCEPT but ztFinalDest will have been changed in _doZtFilter()
@@ -719,10 +719,10 @@ bool Network::filterOutgoingPacket(
 	}
 	}
 
 
 	if (localCapabilityIndex >= 0) {
 	if (localCapabilityIndex >= 0) {
-		const Capability &cap = _config.capabilities[localCapabilityIndex];
-		RR->t->networkFilter(tPtr,0x56ff1a93,_id,rrl.l,crrl.l,cap.id(),cap.timestamp(),ztSource,ztDest,macSource,macDest,(uint16_t)frameLen,frameData,(uint16_t)etherType,(uint16_t)vlanId,noTee,false,accept);
+		const Capability &cap = m_config.capabilities[localCapabilityIndex];
+		RR->t->networkFilter(tPtr, 0x56ff1a93, m_id, rrl.l, crrl.l, cap.id(), cap.timestamp(), ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, accept);
 	} else {
 	} else {
-		RR->t->networkFilter(tPtr,0x112fbbab,_id,rrl.l,nullptr,0,0,ztSource,ztDest,macSource,macDest,(uint16_t)frameLen,frameData,(uint16_t)etherType,(uint16_t)vlanId,noTee,false,accept);
+		RR->t->networkFilter(tPtr, 0x112fbbab, m_id, rrl.l, nullptr, 0, 0, ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, accept);
 	}
 	}
 
 
 	return (accept != 0);
 	return (accept != 0);
@@ -749,21 +749,21 @@ int Network::filterIncomingPacket(
 
 
 	uint8_t qosBucket = 255; // For incoming packets this is a dummy value
 	uint8_t qosBucket = 255; // For incoming packets this is a dummy value
 
 
-	Mutex::Lock l1(_memberships_l);
-	Mutex::Lock l2(_config_l);
+	Mutex::Lock l1(m_memberships_l);
+	Mutex::Lock l2(m_config_l);
 
 
-	Membership &membership = _memberships[sourcePeer->address()];
+	Membership &membership = m_memberships[sourcePeer->address()];
 
 
-	switch (_doZtFilter(RR,rrl,_config,&membership,true,sourcePeer->address(),ztFinalDest,macSource,macDest,frameData,frameLen,etherType,vlanId,_config.rules,_config.ruleCount,cc,ccLength,ccWatch,qosBucket)) {
+	switch (_doZtFilter(RR, rrl, m_config, &membership, true, sourcePeer->address(), ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, m_config.rules, m_config.ruleCount, cc, ccLength, ccWatch, qosBucket)) {
 
 
 		case DOZTFILTER_NO_MATCH: {
 		case DOZTFILTER_NO_MATCH: {
-			Membership::CapabilityIterator mci(membership,_config);
+			Membership::CapabilityIterator mci(membership, m_config);
 			while ((c = mci.next())) {
 			while ((c = mci.next())) {
 				ztFinalDest = ztDest; // sanity check, should be unmodified if there was no match
 				ztFinalDest = ztDest; // sanity check, should be unmodified if there was no match
 				Address cc2;
 				Address cc2;
 				unsigned int ccLength2 = 0;
 				unsigned int ccLength2 = 0;
 				bool ccWatch2 = false;
 				bool ccWatch2 = false;
-				switch(_doZtFilter(RR,crrl,_config,&membership,true,sourcePeer->address(),ztFinalDest,macSource,macDest,frameData,frameLen,etherType,vlanId,c->rules(),c->ruleCount(),cc2,ccLength2,ccWatch2,qosBucket)) {
+				switch(_doZtFilter(RR, crrl, m_config, &membership, true, sourcePeer->address(), ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, c->rules(), c->ruleCount(), cc2, ccLength2, ccWatch2, qosBucket)) {
 					case DOZTFILTER_NO_MATCH:
 					case DOZTFILTER_NO_MATCH:
 					case DOZTFILTER_DROP: // explicit DROP in a capability just terminates its evaluation and is an anti-pattern
 					case DOZTFILTER_DROP: // explicit DROP in a capability just terminates its evaluation and is an anti-pattern
 						break;
 						break;
@@ -853,31 +853,31 @@ int Network::filterIncomingPacket(
 
 
 void Network::multicastSubscribe(void *tPtr,const MulticastGroup &mg)
 void Network::multicastSubscribe(void *tPtr,const MulticastGroup &mg)
 {
 {
-	Mutex::Lock l(_myMulticastGroups_l);
-	if (!std::binary_search(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg)) {
-		_myMulticastGroups.insert(std::upper_bound(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg),mg);
-		Mutex::Lock l2(_memberships_l);
-		_announceMulticastGroups(tPtr,true);
+	Mutex::Lock l(m_myMulticastGroups_l);
+	if (!std::binary_search(m_myMulticastGroups.begin(), m_myMulticastGroups.end(), mg)) {
+		m_myMulticastGroups.insert(std::upper_bound(m_myMulticastGroups.begin(), m_myMulticastGroups.end(), mg), mg);
+		Mutex::Lock l2(m_memberships_l);
+		m_announceMulticastGroups(tPtr, true);
 	}
 	}
 }
 }
 
 
 void Network::multicastUnsubscribe(const MulticastGroup &mg)
 void Network::multicastUnsubscribe(const MulticastGroup &mg)
 {
 {
-	Mutex::Lock l(_myMulticastGroups_l);
-	std::vector<MulticastGroup>::iterator i(std::lower_bound(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg));
-	if ( (i != _myMulticastGroups.end()) && (*i == mg) )
-		_myMulticastGroups.erase(i);
+	Mutex::Lock l(m_myMulticastGroups_l);
+	std::vector<MulticastGroup>::iterator i(std::lower_bound(m_myMulticastGroups.begin(), m_myMulticastGroups.end(), mg));
+	if ((i != m_myMulticastGroups.end()) && (*i == mg) )
+		m_myMulticastGroups.erase(i);
 }
 }
 
 
 uint64_t Network::handleConfigChunk(void *tPtr,uint64_t packetId,const SharedPtr<Peer> &source,const Buf &chunk,int ptr,int size)
 uint64_t Network::handleConfigChunk(void *tPtr,uint64_t packetId,const SharedPtr<Peer> &source,const Buf &chunk,int ptr,int size)
 {
 {
 	// If the controller's full fingerprint is known or was explicitly specified on join(),
 	// If the controller's full fingerprint is known or was explicitly specified on join(),
 	// require that the controller's identity match. Otherwise learn it.
 	// require that the controller's identity match. Otherwise learn it.
-	if (_controllerFingerprint) {
-		if (source->identity().fingerprint() != _controllerFingerprint)
+	if (m_controllerFingerprint) {
+		if (source->identity().fingerprint() != m_controllerFingerprint)
 			return 0;
 			return 0;
 	} else {
 	} else {
-		_controllerFingerprint = source->identity().fingerprint();
+		m_controllerFingerprint = source->identity().fingerprint();
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -1015,42 +1015,42 @@ uint64_t Network::handleConfigChunk(void *tPtr,uint64_t packetId,const SharedPtr
 
 
 int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToDisk)
 int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToDisk)
 {
 {
-	if (_destroyed)
+	if (m_destroyed)
 		return 0;
 		return 0;
 
 
 	// _lock is NOT locked when this is called
 	// _lock is NOT locked when this is called
 	try {
 	try {
-		if ((nconf.issuedTo != RR->identity.address())||(nconf.networkId != _id))
+		if ((nconf.issuedTo != RR->identity.address())||(nconf.networkId != m_id))
 			return 0; // invalid config that is not for us or not for this network
 			return 0; // invalid config that is not for us or not for this network
 		if ((!Utils::allZero(nconf.issuedToFingerprintHash,ZT_FINGERPRINT_HASH_SIZE)) && (memcmp(nconf.issuedToFingerprintHash,RR->identity.fingerprint().hash(),ZT_FINGERPRINT_HASH_SIZE) != 0))
 		if ((!Utils::allZero(nconf.issuedToFingerprintHash,ZT_FINGERPRINT_HASH_SIZE)) && (memcmp(nconf.issuedToFingerprintHash,RR->identity.fingerprint().hash(),ZT_FINGERPRINT_HASH_SIZE) != 0))
 			return 0; // full identity hash is present and does not match
 			return 0; // full identity hash is present and does not match
 
 
-		if (_config == nconf)
+		if (m_config == nconf)
 			return 1; // OK config, but duplicate of what we already have
 			return 1; // OK config, but duplicate of what we already have
 
 
 		ZT_VirtualNetworkConfig ctmp;
 		ZT_VirtualNetworkConfig ctmp;
 		bool oldPortInitialized;
 		bool oldPortInitialized;
 		{	// do things that require lock here, but unlock before calling callbacks
 		{	// do things that require lock here, but unlock before calling callbacks
-			Mutex::Lock l1(_config_l);
+			Mutex::Lock l1(m_config_l);
 
 
-			_config = nconf;
-			_lastConfigUpdate = RR->node->now();
+			m_config = nconf;
+			m_lastConfigUpdate = RR->node->now();
 			_netconfFailure = NETCONF_FAILURE_NONE;
 			_netconfFailure = NETCONF_FAILURE_NONE;
 
 
-			oldPortInitialized = _portInitialized;
-			_portInitialized = true;
+			oldPortInitialized = m_portInitialized;
+			m_portInitialized = true;
 
 
-			_externalConfig(&ctmp);
+			m_externalConfig(&ctmp);
 		}
 		}
 
 
-		RR->node->configureVirtualNetworkPort(tPtr,_id,&_uPtr,(oldPortInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp);
+		RR->node->configureVirtualNetworkPort(tPtr, m_id, &m_uPtr, (oldPortInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP, &ctmp);
 
 
 		if (saveToDisk) {
 		if (saveToDisk) {
 			try {
 			try {
 				Dictionary d;
 				Dictionary d;
 				if (nconf.toDictionary(d,false)) {
 				if (nconf.toDictionary(d,false)) {
 					uint64_t tmp[2];
 					uint64_t tmp[2];
-					tmp[0] = _id; tmp[1] = 0;
+					tmp[0] = m_id; tmp[1] = 0;
 					std::vector<uint8_t> d2;
 					std::vector<uint8_t> d2;
 					d.encode(d2);
 					d.encode(d2);
 					RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp,d2.data(),(unsigned int)d2.size());
 					RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp,d2.data(),(unsigned int)d2.size());
@@ -1065,22 +1065,22 @@ int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToD
 
 
 bool Network::gate(void *tPtr,const SharedPtr<Peer> &peer) noexcept
 bool Network::gate(void *tPtr,const SharedPtr<Peer> &peer) noexcept
 {
 {
-	Mutex::Lock lc(_config_l);
+	Mutex::Lock lc(m_config_l);
 
 
-	if (!_config)
+	if (!m_config)
 		return false;
 		return false;
-	if (_config.isPublic())
+	if (m_config.isPublic())
 		return true;
 		return true;
 
 
 	try {
 	try {
-		Mutex::Lock l(_memberships_l);
-		Membership *m = _memberships.get(peer->address());
+		Mutex::Lock l(m_memberships_l);
+		Membership *m = m_memberships.get(peer->address());
 		if (m) {
 		if (m) {
 			// SECURITY: this method in CertificateOfMembership does a full fingerprint check as well as
 			// SECURITY: this method in CertificateOfMembership does a full fingerprint check as well as
 			// checking certificate agreement. See Membership.hpp.
 			// checking certificate agreement. See Membership.hpp.
-			return m->certificateOfMembershipAgress(_config.com,peer->identity());
+			return m->certificateOfMembershipAgress(m_config.com, peer->identity());
 		} else {
 		} else {
-			m = &(_memberships[peer->address()]);
+			m = &(m_memberships[peer->address()]);
 			return false;
 			return false;
 		}
 		}
 	} catch ( ... ) {}
 	} catch ( ... ) {}
@@ -1090,20 +1090,20 @@ bool Network::gate(void *tPtr,const SharedPtr<Peer> &peer) noexcept
 
 
 void Network::doPeriodicTasks(void *tPtr,const int64_t now)
 void Network::doPeriodicTasks(void *tPtr,const int64_t now)
 {
 {
-	if (_destroyed)
+	if (m_destroyed)
 		return;
 		return;
 
 
-	if ((now - _lastConfigUpdate) >= ZT_NETWORK_AUTOCONF_DELAY)
-		_requestConfiguration(tPtr);
+	if ((now - m_lastConfigUpdate) >= ZT_NETWORK_AUTOCONF_DELAY)
+		m_requestConfiguration(tPtr);
 
 
 	{
 	{
-		Mutex::Lock l1(_memberships_l);
+		Mutex::Lock l1(m_memberships_l);
 
 
-		for(Map<Address,Membership>::iterator i(_memberships.begin());i!=_memberships.end();++i)
-			i->second.clean(now,_config);
+		for(Map<Address,Membership>::iterator i(m_memberships.begin());i != m_memberships.end();++i)
+			i->second.clean(now, m_config);
 
 
 		{
 		{
-			Mutex::Lock l2(_myMulticastGroups_l);
+			Mutex::Lock l2(m_myMulticastGroups_l);
 
 
 			// TODO
 			// TODO
 			/*
 			/*
@@ -1123,17 +1123,17 @@ void Network::doPeriodicTasks(void *tPtr,const int64_t now)
 
 
 void Network::learnBridgeRoute(const MAC &mac,const Address &addr)
 void Network::learnBridgeRoute(const MAC &mac,const Address &addr)
 {
 {
-	Mutex::Lock _l(_remoteBridgeRoutes_l);
-	_remoteBridgeRoutes[mac] = addr;
+	Mutex::Lock _l(m_remoteBridgeRoutes_l);
+	m_remoteBridgeRoutes[mac] = addr;
 
 
 	// Anti-DOS circuit breaker to prevent nodes from spamming us with absurd numbers of bridge routes
 	// Anti-DOS circuit breaker to prevent nodes from spamming us with absurd numbers of bridge routes
-	while (_remoteBridgeRoutes.size() > ZT_MAX_BRIDGE_ROUTES) {
+	while (m_remoteBridgeRoutes.size() > ZT_MAX_BRIDGE_ROUTES) {
 		Map< Address,unsigned long > counts;
 		Map< Address,unsigned long > counts;
 		Address maxAddr;
 		Address maxAddr;
 		unsigned long maxCount = 0;
 		unsigned long maxCount = 0;
 
 
 		// Find the address responsible for the most entries
 		// Find the address responsible for the most entries
-		for(Map<MAC,Address>::iterator i(_remoteBridgeRoutes.begin());i!=_remoteBridgeRoutes.end();++i) {
+		for(Map<MAC,Address>::iterator i(m_remoteBridgeRoutes.begin());i != m_remoteBridgeRoutes.end();++i) {
 			const unsigned long c = ++counts[i->second];
 			const unsigned long c = ++counts[i->second];
 			if (c > maxCount) {
 			if (c > maxCount) {
 				maxCount = c;
 				maxCount = c;
@@ -1142,9 +1142,9 @@ void Network::learnBridgeRoute(const MAC &mac,const Address &addr)
 		}
 		}
 
 
 		// Kill this address from our table, since it's most likely spamming us
 		// Kill this address from our table, since it's most likely spamming us
-		for(Map<MAC,Address>::iterator i(_remoteBridgeRoutes.begin());i!=_remoteBridgeRoutes.end();) {
+		for(Map<MAC,Address>::iterator i(m_remoteBridgeRoutes.begin());i != m_remoteBridgeRoutes.end();) {
 			if (i->second == maxAddr)
 			if (i->second == maxAddr)
-				_remoteBridgeRoutes.erase(i++);
+				m_remoteBridgeRoutes.erase(i++);
 			else ++i;
 			else ++i;
 		}
 		}
 	}
 	}
@@ -1152,37 +1152,37 @@ void Network::learnBridgeRoute(const MAC &mac,const Address &addr)
 
 
 Membership::AddCredentialResult Network::addCredential(void *tPtr,const Identity &sourcePeerIdentity,const CertificateOfMembership &com)
 Membership::AddCredentialResult Network::addCredential(void *tPtr,const Identity &sourcePeerIdentity,const CertificateOfMembership &com)
 {
 {
-	if (com.networkId() != _id)
+	if (com.networkId() != m_id)
 		return Membership::ADD_REJECTED;
 		return Membership::ADD_REJECTED;
-	Mutex::Lock _l(_memberships_l);
-	return _memberships[com.issuedTo().address()].addCredential(RR,tPtr,sourcePeerIdentity,_config,com);
+	Mutex::Lock _l(m_memberships_l);
+	return m_memberships[com.issuedTo().address()].addCredential(RR, tPtr, sourcePeerIdentity, m_config, com);
 }
 }
 
 
 Membership::AddCredentialResult Network::addCredential(void *tPtr,const Identity &sourcePeerIdentity,const Capability &cap)
 Membership::AddCredentialResult Network::addCredential(void *tPtr,const Identity &sourcePeerIdentity,const Capability &cap)
 {
 {
-	if (cap.networkId() != _id)
+	if (cap.networkId() != m_id)
 		return Membership::ADD_REJECTED;
 		return Membership::ADD_REJECTED;
-	Mutex::Lock _l(_memberships_l);
-	return _memberships[cap.issuedTo()].addCredential(RR,tPtr,sourcePeerIdentity,_config,cap);
+	Mutex::Lock _l(m_memberships_l);
+	return m_memberships[cap.issuedTo()].addCredential(RR, tPtr, sourcePeerIdentity, m_config, cap);
 }
 }
 
 
 Membership::AddCredentialResult Network::addCredential(void *tPtr,const Identity &sourcePeerIdentity,const Tag &tag)
 Membership::AddCredentialResult Network::addCredential(void *tPtr,const Identity &sourcePeerIdentity,const Tag &tag)
 {
 {
-	if (tag.networkId() != _id)
+	if (tag.networkId() != m_id)
 		return Membership::ADD_REJECTED;
 		return Membership::ADD_REJECTED;
-	Mutex::Lock _l(_memberships_l);
-	return _memberships[tag.issuedTo()].addCredential(RR,tPtr,sourcePeerIdentity,_config,tag);
+	Mutex::Lock _l(m_memberships_l);
+	return m_memberships[tag.issuedTo()].addCredential(RR, tPtr, sourcePeerIdentity, m_config, tag);
 }
 }
 
 
 Membership::AddCredentialResult Network::addCredential(void *tPtr,const Identity &sourcePeerIdentity,const Revocation &rev)
 Membership::AddCredentialResult Network::addCredential(void *tPtr,const Identity &sourcePeerIdentity,const Revocation &rev)
 {
 {
-	if (rev.networkId() != _id)
+	if (rev.networkId() != m_id)
 		return Membership::ADD_REJECTED;
 		return Membership::ADD_REJECTED;
 
 
-	Mutex::Lock l1(_memberships_l);
-	Membership &m = _memberships[rev.target()];
+	Mutex::Lock l1(m_memberships_l);
+	Membership &m = m_memberships[rev.target()];
 
 
-	const Membership::AddCredentialResult result = m.addCredential(RR,tPtr,sourcePeerIdentity,_config,rev);
+	const Membership::AddCredentialResult result = m.addCredential(RR, tPtr, sourcePeerIdentity, m_config, rev);
 
 
 	if ((result == Membership::ADD_ACCEPTED_NEW)&&(rev.fastPropagate())) {
 	if ((result == Membership::ADD_ACCEPTED_NEW)&&(rev.fastPropagate())) {
 		// TODO
 		// TODO
@@ -1210,50 +1210,50 @@ Membership::AddCredentialResult Network::addCredential(void *tPtr,const Identity
 
 
 Membership::AddCredentialResult Network::addCredential(void *tPtr,const Identity &sourcePeerIdentity,const CertificateOfOwnership &coo)
 Membership::AddCredentialResult Network::addCredential(void *tPtr,const Identity &sourcePeerIdentity,const CertificateOfOwnership &coo)
 {
 {
-	if (coo.networkId() != _id)
+	if (coo.networkId() != m_id)
 		return Membership::ADD_REJECTED;
 		return Membership::ADD_REJECTED;
-	Mutex::Lock _l(_memberships_l);
-	return _memberships[coo.issuedTo()].addCredential(RR,tPtr,sourcePeerIdentity,_config,coo);
+	Mutex::Lock _l(m_memberships_l);
+	return m_memberships[coo.issuedTo()].addCredential(RR, tPtr, sourcePeerIdentity, m_config, coo);
 }
 }
 
 
 void Network::pushCredentials(void *tPtr,const SharedPtr<Peer> &to,const int64_t now)
 void Network::pushCredentials(void *tPtr,const SharedPtr<Peer> &to,const int64_t now)
 {
 {
-	const int64_t tout = std::min(_config.credentialTimeMaxDelta,_config.com.timestampMaxDelta());
-	Mutex::Lock _l(_memberships_l);
-	Membership &m = _memberships[to->address()];
+	const int64_t tout = std::min(m_config.credentialTimeMaxDelta, m_config.com.timestampMaxDelta());
+	Mutex::Lock _l(m_memberships_l);
+	Membership &m = m_memberships[to->address()];
 	if (((now - m.lastPushedCredentials()) + 5000) >= tout) {
 	if (((now - m.lastPushedCredentials()) + 5000) >= tout) {
-		m.pushCredentials(RR,tPtr,now,to,_config);
+		m.pushCredentials(RR, tPtr, now, to, m_config);
 	}
 	}
 }
 }
 
 
 void Network::destroy()
 void Network::destroy()
 {
 {
-	_memberships_l.lock();
-	_config_l.lock();
-	_destroyed = true;
-	_config_l.unlock();
-	_memberships_l.unlock();
+	m_memberships_l.lock();
+	m_config_l.lock();
+	m_destroyed = true;
+	m_config_l.unlock();
+	m_memberships_l.unlock();
 }
 }
 
 
 void Network::externalConfig(ZT_VirtualNetworkConfig *ec) const
 void Network::externalConfig(ZT_VirtualNetworkConfig *ec) const
 {
 {
-	Mutex::Lock _l(_config_l);
-	_externalConfig(ec);
+	Mutex::Lock _l(m_config_l);
+	m_externalConfig(ec);
 }
 }
 
 
-void Network::_requestConfiguration(void *tPtr)
+void Network::m_requestConfiguration(void *tPtr)
 {
 {
-	if (_destroyed)
+	if (m_destroyed)
 		return;
 		return;
 
 
-	if ((_id >> 56U) == 0xff) {
-		if ((_id & 0xffffffU) == 0) {
-			const uint16_t startPortRange = (uint16_t)((_id >> 40U) & 0xffff);
-			const uint16_t endPortRange = (uint16_t)((_id >> 24U) & 0xffff);
+	if ((m_id >> 56U) == 0xff) {
+		if ((m_id & 0xffffffU) == 0) {
+			const uint16_t startPortRange = (uint16_t)((m_id >> 40U) & 0xffff);
+			const uint16_t endPortRange = (uint16_t)((m_id >> 24U) & 0xffff);
 			if (endPortRange >= startPortRange) {
 			if (endPortRange >= startPortRange) {
 				ScopedPtr<NetworkConfig> nconf(new NetworkConfig());
 				ScopedPtr<NetworkConfig> nconf(new NetworkConfig());
 
 
-				nconf->networkId = _id;
+				nconf->networkId = m_id;
 				nconf->timestamp = RR->node->now();
 				nconf->timestamp = RR->node->now();
 				nconf->credentialTimeMaxDelta = ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MAX_MAX_DELTA;
 				nconf->credentialTimeMaxDelta = ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MAX_MAX_DELTA;
 				nconf->revision = 1;
 				nconf->revision = 1;
@@ -1263,7 +1263,7 @@ void Network::_requestConfiguration(void *tPtr)
 				nconf->multicastLimit = 0;
 				nconf->multicastLimit = 0;
 				nconf->staticIpCount = 1;
 				nconf->staticIpCount = 1;
 				nconf->ruleCount = 14;
 				nconf->ruleCount = 14;
-				nconf->staticIps[0] = InetAddress::makeIpv66plane(_id,RR->identity.address().toInt());
+				nconf->staticIps[0] = InetAddress::makeIpv66plane(m_id, RR->identity.address().toInt());
 
 
 				// Drop everything but IPv6
 				// Drop everything but IPv6
 				nconf->rules[0].t = (uint8_t)ZT_NETWORK_RULE_MATCH_ETHERTYPE | 0x80U; // NOT
 				nconf->rules[0].t = (uint8_t)ZT_NETWORK_RULE_MATCH_ETHERTYPE | 0x80U; // NOT
@@ -1316,13 +1316,13 @@ void Network::_requestConfiguration(void *tPtr)
 			} else {
 			} else {
 				this->setNotFound();
 				this->setNotFound();
 			}
 			}
-		} else if ((_id & 0xffU) == 0x01) {
+		} else if ((m_id & 0xffU) == 0x01) {
 			// ffAAaaaaaaaaaa01 -- where AA is the IPv4 /8 to use and aaaaaaaaaa is the anchor node for multicast gather and replication
 			// ffAAaaaaaaaaaa01 -- where AA is the IPv4 /8 to use and aaaaaaaaaa is the anchor node for multicast gather and replication
 			const uint64_t myAddress = RR->identity.address().toInt();
 			const uint64_t myAddress = RR->identity.address().toInt();
-			const uint64_t networkHub = (_id >> 8U) & 0xffffffffffULL;
+			const uint64_t networkHub = (m_id >> 8U) & 0xffffffffffULL;
 
 
 			uint8_t ipv4[4];
 			uint8_t ipv4[4];
-			ipv4[0] = (uint8_t)(_id >> 48U);
+			ipv4[0] = (uint8_t)(m_id >> 48U);
 			ipv4[1] = (uint8_t)(myAddress >> 16U);
 			ipv4[1] = (uint8_t)(myAddress >> 16U);
 			ipv4[2] = (uint8_t)(myAddress >> 8U);
 			ipv4[2] = (uint8_t)(myAddress >> 8U);
 			ipv4[3] = (uint8_t)myAddress;
 			ipv4[3] = (uint8_t)myAddress;
@@ -1332,7 +1332,7 @@ void Network::_requestConfiguration(void *tPtr)
 
 
 			ScopedPtr<NetworkConfig> nconf(new NetworkConfig());
 			ScopedPtr<NetworkConfig> nconf(new NetworkConfig());
 
 
-			nconf->networkId = _id;
+			nconf->networkId = m_id;
 			nconf->timestamp = RR->node->now();
 			nconf->timestamp = RR->node->now();
 			nconf->credentialTimeMaxDelta = ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MAX_MAX_DELTA;
 			nconf->credentialTimeMaxDelta = ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MAX_MAX_DELTA;
 			nconf->revision = 1;
 			nconf->revision = 1;
@@ -1347,7 +1347,7 @@ void Network::_requestConfiguration(void *tPtr)
 			if (networkHub != 0)
 			if (networkHub != 0)
 				nconf->specialists[0] = networkHub;
 				nconf->specialists[0] = networkHub;
 
 
-			nconf->staticIps[0] = InetAddress::makeIpv66plane(_id,myAddress);
+			nconf->staticIps[0] = InetAddress::makeIpv66plane(m_id, myAddress);
 			nconf->staticIps[1].set(ipv4,4,8);
 			nconf->staticIps[1].set(ipv4,4,8);
 
 
 			nconf->rules[0].t = (uint8_t)ZT_NETWORK_RULE_ACTION_ACCEPT;
 			nconf->rules[0].t = (uint8_t)ZT_NETWORK_RULE_ACTION_ACCEPT;
@@ -1390,11 +1390,11 @@ void Network::_requestConfiguration(void *tPtr)
 	rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS,(uint64_t)0);
 	rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS,(uint64_t)0);
 	rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV,(uint64_t)ZT_RULES_ENGINE_REVISION);
 	rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV,(uint64_t)ZT_RULES_ENGINE_REVISION);
 
 
-	RR->t->networkConfigRequestSent(tPtr,0x335bb1a2,_id);
+	RR->t->networkConfigRequestSent(tPtr, 0x335bb1a2, m_id);
 
 
 	if (ctrl == RR->identity.address()) {
 	if (ctrl == RR->identity.address()) {
 		if (RR->localNetworkController) {
 		if (RR->localNetworkController) {
-			RR->localNetworkController->request(_id,InetAddress(),0xffffffffffffffffULL,RR->identity,rmd);
+			RR->localNetworkController->request(m_id, InetAddress(), 0xffffffffffffffffULL, RR->identity, rmd);
 		} else {
 		} else {
 			this->setNotFound();
 			this->setNotFound();
 		}
 		}
@@ -1420,7 +1420,7 @@ void Network::_requestConfiguration(void *tPtr)
 	*/
 	*/
 }
 }
 
 
-ZT_VirtualNetworkStatus Network::_status() const
+ZT_VirtualNetworkStatus Network::m_status() const
 {
 {
 	switch(_netconfFailure) {
 	switch(_netconfFailure) {
 		case NETCONF_FAILURE_ACCESS_DENIED:
 		case NETCONF_FAILURE_ACCESS_DENIED:
@@ -1428,36 +1428,36 @@ ZT_VirtualNetworkStatus Network::_status() const
 		case NETCONF_FAILURE_NOT_FOUND:
 		case NETCONF_FAILURE_NOT_FOUND:
 			return ZT_NETWORK_STATUS_NOT_FOUND;
 			return ZT_NETWORK_STATUS_NOT_FOUND;
 		case NETCONF_FAILURE_NONE:
 		case NETCONF_FAILURE_NONE:
-			return ((_config) ? ZT_NETWORK_STATUS_OK : ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION);
+			return ((m_config) ? ZT_NETWORK_STATUS_OK : ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION);
 		default:
 		default:
 			return ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION;
 			return ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION;
 	}
 	}
 }
 }
 
 
-void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const
+void Network::m_externalConfig(ZT_VirtualNetworkConfig *ec) const
 {
 {
 	// assumes _config_l is locked
 	// assumes _config_l is locked
-	ec->nwid = _id;
-	ec->mac = _mac.toInt();
-	if (_config)
-		Utils::scopy(ec->name,sizeof(ec->name),_config.name);
+	ec->nwid = m_id;
+	ec->mac = m_mac.toInt();
+	if (m_config)
+		Utils::scopy(ec->name, sizeof(ec->name), m_config.name);
 	else ec->name[0] = (char)0;
 	else ec->name[0] = (char)0;
-	ec->status = _status();
-	ec->type = (_config) ? (_config.isPrivate() ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC) : ZT_NETWORK_TYPE_PRIVATE;
-	ec->mtu = (_config) ? _config.mtu : ZT_DEFAULT_MTU;
+	ec->status = m_status();
+	ec->type = (m_config) ? (m_config.isPrivate() ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC) : ZT_NETWORK_TYPE_PRIVATE;
+	ec->mtu = (m_config) ? m_config.mtu : ZT_DEFAULT_MTU;
 	std::vector<Address> ab;
 	std::vector<Address> ab;
-	for(unsigned int i=0;i<_config.specialistCount;++i) {
-		if ((_config.specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE) != 0)
-			ab.push_back(Address(_config.specialists[i]));
+	for(unsigned int i=0;i < m_config.specialistCount;++i) {
+		if ((m_config.specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE) != 0)
+			ab.push_back(Address(m_config.specialists[i]));
 	}
 	}
 	ec->bridge = (std::find(ab.begin(),ab.end(),RR->identity.address()) != ab.end()) ? 1 : 0;
 	ec->bridge = (std::find(ab.begin(),ab.end(),RR->identity.address()) != ab.end()) ? 1 : 0;
-	ec->broadcastEnabled = (_config) ? (_config.enableBroadcast() ? 1 : 0) : 0;
-	ec->netconfRevision = (_config) ? (unsigned long)_config.revision : 0;
+	ec->broadcastEnabled = (m_config) ? (m_config.enableBroadcast() ? 1 : 0) : 0;
+	ec->netconfRevision = (m_config) ? (unsigned long)m_config.revision : 0;
 
 
 	ec->assignedAddressCount = 0;
 	ec->assignedAddressCount = 0;
 	for(unsigned int i=0;i<ZT_MAX_ZT_ASSIGNED_ADDRESSES;++i) {
 	for(unsigned int i=0;i<ZT_MAX_ZT_ASSIGNED_ADDRESSES;++i) {
-		if (i < _config.staticIpCount) {
-			Utils::copy<sizeof(struct sockaddr_storage)>(&(ec->assignedAddresses[i]),&(_config.staticIps[i]));
+		if (i < m_config.staticIpCount) {
+			Utils::copy<sizeof(struct sockaddr_storage)>(&(ec->assignedAddresses[i]),&(m_config.staticIps[i]));
 			++ec->assignedAddressCount;
 			++ec->assignedAddressCount;
 		} else {
 		} else {
 			Utils::zero<sizeof(struct sockaddr_storage)>(&(ec->assignedAddresses[i]));
 			Utils::zero<sizeof(struct sockaddr_storage)>(&(ec->assignedAddresses[i]));
@@ -1466,8 +1466,8 @@ void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const
 
 
 	ec->routeCount = 0;
 	ec->routeCount = 0;
 	for(unsigned int i=0;i<ZT_MAX_NETWORK_ROUTES;++i) {
 	for(unsigned int i=0;i<ZT_MAX_NETWORK_ROUTES;++i) {
-		if (i < _config.routeCount) {
-			Utils::copy<sizeof(ZT_VirtualNetworkRoute)>(&(ec->routes[i]),&(_config.routes[i]));
+		if (i < m_config.routeCount) {
+			Utils::copy<sizeof(ZT_VirtualNetworkRoute)>(&(ec->routes[i]),&(m_config.routes[i]));
 			++ec->routeCount;
 			++ec->routeCount;
 		} else {
 		} else {
 			Utils::zero<sizeof(ZT_VirtualNetworkRoute)>(&(ec->routes[i]));
 			Utils::zero<sizeof(ZT_VirtualNetworkRoute)>(&(ec->routes[i]));
@@ -1475,11 +1475,11 @@ void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const
 	}
 	}
 }
 }
 
 
-void Network::_announceMulticastGroups(void *tPtr,bool force)
+void Network::m_announceMulticastGroups(void *tPtr, bool force)
 {
 {
 	// Assumes _myMulticastGroups_l and _memberships_l are locked
 	// Assumes _myMulticastGroups_l and _memberships_l are locked
-	const std::vector<MulticastGroup> groups(_allMulticastGroups());
-	_announceMulticastGroupsTo(tPtr,controller(),groups);
+	const Vector<MulticastGroup> groups(m_allMulticastGroups());
+	m_announceMulticastGroupsTo(tPtr, controller(), groups);
 
 
 		// TODO
 		// TODO
 		/*
 		/*
@@ -1497,7 +1497,7 @@ void Network::_announceMulticastGroups(void *tPtr,bool force)
 
 
 }
 }
 
 
-void Network::_announceMulticastGroupsTo(void *tPtr,const Address &peer,const std::vector<MulticastGroup> &allMulticastGroups)
+void Network::m_announceMulticastGroupsTo(void *tPtr, const Address &peer, const Vector<MulticastGroup> &allMulticastGroups)
 {
 {
 #if 0
 #if 0
 	// Assumes _myMulticastGroups_l and _memberships_l are locked
 	// Assumes _myMulticastGroups_l and _memberships_l are locked
@@ -1523,15 +1523,15 @@ void Network::_announceMulticastGroupsTo(void *tPtr,const Address &peer,const st
 #endif
 #endif
 }
 }
 
 
-std::vector<MulticastGroup> Network::_allMulticastGroups() const
+Vector<MulticastGroup> Network::m_allMulticastGroups() const
 {
 {
 	// Assumes _myMulticastGroups_l is locked
 	// Assumes _myMulticastGroups_l is locked
-	std::vector<MulticastGroup> mgs;
-	mgs.reserve(_myMulticastGroups.size() + _multicastGroupsBehindMe.size() + 1);
-	mgs.insert(mgs.end(),_myMulticastGroups.begin(),_myMulticastGroups.end());
-	for(Map< MulticastGroup,uint64_t >::const_iterator i(_multicastGroupsBehindMe.begin());i!=_multicastGroupsBehindMe.end();++i)
+	Vector<MulticastGroup> mgs;
+	mgs.reserve(m_myMulticastGroups.size() + m_multicastGroupsBehindMe.size() + 1);
+	mgs.insert(mgs.end(), m_myMulticastGroups.begin(), m_myMulticastGroups.end());
+	for(Map<MulticastGroup,uint64_t>::const_iterator i(m_multicastGroupsBehindMe.begin());i != m_multicastGroupsBehindMe.end();++i)
 		mgs.push_back(i->first);
 		mgs.push_back(i->first);
-	if ((_config)&&(_config.enableBroadcast()))
+	if ((m_config) && (m_config.enableBroadcast()))
 		mgs.push_back(Network::BROADCAST);
 		mgs.push_back(Network::BROADCAST);
 	std::sort(mgs.begin(),mgs.end());
 	std::sort(mgs.begin(),mgs.end());
 	mgs.erase(std::unique(mgs.begin(),mgs.end()),mgs.end());
 	mgs.erase(std::unique(mgs.begin(),mgs.end()),mgs.end());

+ 40 - 50
node/Network.hpp

@@ -75,14 +75,14 @@ public:
 
 
 	~Network();
 	~Network();
 
 
-	ZT_INLINE uint64_t id() const noexcept { return _id; }
-	ZT_INLINE Address controller() const noexcept { return Address(_id >> 24U); }
-	ZT_INLINE bool multicastEnabled() const noexcept { return (_config.multicastLimit > 0); }
-	ZT_INLINE bool hasConfig() const noexcept { return (_config); }
-	ZT_INLINE uint64_t lastConfigUpdate() const noexcept { return _lastConfigUpdate; }
-	ZT_INLINE ZT_VirtualNetworkStatus status() const noexcept { return _status(); }
-	ZT_INLINE const NetworkConfig &config() const noexcept { return _config; }
-	ZT_INLINE const MAC &mac() const noexcept { return _mac; }
+	ZT_INLINE uint64_t id() const noexcept { return m_id; }
+	ZT_INLINE Address controller() const noexcept { return Address(m_id >> 24U); }
+	ZT_INLINE bool multicastEnabled() const noexcept { return (m_config.multicastLimit > 0); }
+	ZT_INLINE bool hasConfig() const noexcept { return (m_config); }
+	ZT_INLINE uint64_t lastConfigUpdate() const noexcept { return m_lastConfigUpdate; }
+	ZT_INLINE ZT_VirtualNetworkStatus status() const noexcept { return m_status(); }
+	ZT_INLINE const NetworkConfig &config() const noexcept { return m_config; }
+	ZT_INLINE const MAC &mac() const noexcept { return m_mac; }
 
 
 	/**
 	/**
 	 * Apply filters to an outgoing packet
 	 * Apply filters to an outgoing packet
@@ -156,11 +156,11 @@ public:
 	 */
 	 */
 	ZT_INLINE bool subscribedToMulticastGroup(const MulticastGroup &mg,const bool includeBridgedGroups) const
 	ZT_INLINE bool subscribedToMulticastGroup(const MulticastGroup &mg,const bool includeBridgedGroups) const
 	{
 	{
-		Mutex::Lock l(_myMulticastGroups_l);
-		if (std::binary_search(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg))
+		Mutex::Lock l(m_myMulticastGroups_l);
+		if (std::binary_search(m_myMulticastGroups.begin(), m_myMulticastGroups.end(), mg))
 			return true;
 			return true;
 		else if (includeBridgedGroups)
 		else if (includeBridgedGroups)
-			return (_multicastGroupsBehindMe.find(mg) != _multicastGroupsBehindMe.end());
+			return (m_multicastGroupsBehindMe.find(mg) != m_multicastGroupsBehindMe.end());
 		return false;
 		return false;
 	}
 	}
 
 
@@ -242,8 +242,8 @@ public:
 	 */
 	 */
 	ZT_INLINE Address findBridgeTo(const MAC &mac) const
 	ZT_INLINE Address findBridgeTo(const MAC &mac) const
 	{
 	{
-		Mutex::Lock _l(_remoteBridgeRoutes_l);
-		const Address *const br = _remoteBridgeRoutes.get(mac);
+		Mutex::Lock _l(m_remoteBridgeRoutes_l);
+		const Address *const br = m_remoteBridgeRoutes.get(mac);
 		return ((br) ? *br : Address());
 		return ((br) ? *br : Address());
 	}
 	}
 
 
@@ -264,8 +264,8 @@ public:
 	 */
 	 */
 	ZT_INLINE void learnBridgedMulticastGroup(void *tPtr,const MulticastGroup &mg,int64_t now)
 	ZT_INLINE void learnBridgedMulticastGroup(void *tPtr,const MulticastGroup &mg,int64_t now)
 	{
 	{
-		Mutex::Lock l(_myMulticastGroups_l);
-		_multicastGroupsBehindMe.set(mg,now);
+		Mutex::Lock l(m_myMulticastGroups_l);
+		m_multicastGroupsBehindMe.set(mg, now);
 	}
 	}
 
 
 	/**
 	/**
@@ -325,8 +325,8 @@ public:
 	template<typename F>
 	template<typename F>
 	ZT_INLINE void eachMember(F f)
 	ZT_INLINE void eachMember(F f)
 	{
 	{
-		Mutex::Lock ml(_memberships_l);
-		for(Map<Address,Membership>::iterator i(_memberships.begin());i!=_memberships.end();++i) { // NOLINT(modernize-loop-convert,hicpp-use-auto,modernize-use-auto)
+		Mutex::Lock ml(m_memberships_l);
+		for(Map<Address,Membership>::iterator i(m_memberships.begin());i != m_memberships.end();++i) { // NOLINT(modernize-loop-convert,hicpp-use-auto,modernize-use-auto)
 			if (!f(i->first,i->second))
 			if (!f(i->first,i->second))
 				break;
 				break;
 		}
 		}
@@ -335,40 +335,30 @@ public:
 	/**
 	/**
 	 * @return Externally usable pointer-to-pointer exported via the core API
 	 * @return Externally usable pointer-to-pointer exported via the core API
 	 */
 	 */
-	ZT_INLINE void **userPtr() noexcept { return &_uPtr; }
+	ZT_INLINE void **userPtr() noexcept { return &m_uPtr; }
 
 
 private:
 private:
-	void _requestConfiguration(void *tPtr);
-	ZT_VirtualNetworkStatus _status() const;
-	void _externalConfig(ZT_VirtualNetworkConfig *ec) const; // assumes _lock is locked
-	void _announceMulticastGroups(void *tPtr,bool force);
-	void _announceMulticastGroupsTo(void *tPtr,const Address &peer,const std::vector<MulticastGroup> &allMulticastGroups);
-	std::vector<MulticastGroup> _allMulticastGroups() const;
+	void m_requestConfiguration(void *tPtr);
+	ZT_VirtualNetworkStatus m_status() const;
+	void m_externalConfig(ZT_VirtualNetworkConfig *ec) const; // assumes _lock is locked
+	void m_announceMulticastGroups(void *tPtr, bool force);
+	void m_announceMulticastGroupsTo(void *tPtr, const Address &peer, const Vector<MulticastGroup> &allMulticastGroups);
+	Vector<MulticastGroup> m_allMulticastGroups() const;
 
 
 	const RuntimeEnvironment *const RR;
 	const RuntimeEnvironment *const RR;
-	void *_uPtr;
-	const uint64_t _id;
-	Fingerprint _controllerFingerprint;
-	MAC _mac; // local MAC address
-	bool _portInitialized;
+	void *m_uPtr;
+	const uint64_t m_id;
+	Fingerprint m_controllerFingerprint;
+	MAC m_mac; // local MAC address
+	bool m_portInitialized;
+	std::atomic<bool> m_destroyed;
 
 
-	std::vector< MulticastGroup > _myMulticastGroups; // multicast groups that we belong to (according to tap)
-	Map< MulticastGroup,uint64_t > _multicastGroupsBehindMe; // multicast groups that seem to be behind us and when we last saw them (if we are a bridge)
-	Map< MAC,Address > _remoteBridgeRoutes; // remote addresses where given MACs are reachable (for tracking devices behind remote bridges)
+	Vector<MulticastGroup> m_myMulticastGroups; // multicast groups that we belong to (according to tap)
+	Map<MulticastGroup,int64_t> m_multicastGroupsBehindMe; // multicast groups that seem to be behind us and when we last saw them (if we are a bridge)
+	Map<MAC,Address> m_remoteBridgeRoutes; // remote addresses where given MACs are reachable (for tracking devices behind remote bridges)
 
 
-	NetworkConfig _config;
-	std::atomic<int64_t> _lastConfigUpdate;
-
-	struct _IncomingConfigChunk
-	{
-		ZT_INLINE _IncomingConfigChunk() : touchCtr(0),updateId(0) {}
-		uint64_t touchCtr;
-		uint64_t updateId;
-		std::map< int,std::vector<uint8_t> > chunks;
-	};
-	_IncomingConfigChunk _incomingConfigChunks[ZT_NETWORK_MAX_INCOMING_UPDATES];
-
-	volatile bool _destroyed;
+	NetworkConfig m_config;
+	std::atomic<int64_t> m_lastConfigUpdate;
 
 
 	volatile enum {
 	volatile enum {
 		NETCONF_FAILURE_NONE,
 		NETCONF_FAILURE_NONE,
@@ -377,12 +367,12 @@ private:
 		NETCONF_FAILURE_INIT_FAILED
 		NETCONF_FAILURE_INIT_FAILED
 	} _netconfFailure;
 	} _netconfFailure;
 
 
-	Map<Address,Membership> _memberships;
+	Map<Address,Membership> m_memberships;
 
 
-	Mutex _myMulticastGroups_l;
-	Mutex _remoteBridgeRoutes_l;
-	Mutex _config_l;
-	Mutex _memberships_l;
+	Mutex m_myMulticastGroups_l;
+	Mutex m_remoteBridgeRoutes_l;
+	Mutex m_config_l;
+	Mutex m_memberships_l;
 
 
 	std::atomic<int> __refCount;
 	std::atomic<int> __refCount;
 };
 };

+ 5 - 9
node/Node.cpp

@@ -11,10 +11,6 @@
  */
  */
 /****/
 /****/
 
 
-#include <cstdlib>
-#include <cstring>
-#include <cstdint>
-
 #include "Constants.hpp"
 #include "Constants.hpp"
 #include "SharedPtr.hpp"
 #include "SharedPtr.hpp"
 #include "Node.hpp"
 #include "Node.hpp"
@@ -90,7 +86,7 @@ Node::Node(void *uPtr,void *tPtr,const struct ZT_Node_Callbacks *callbacks,int64
 {
 {
 	// Load this node's identity.
 	// Load this node's identity.
 	uint64_t idtmp[2]; idtmp[0] = 0; idtmp[1] = 0;
 	uint64_t idtmp[2]; idtmp[0] = 0; idtmp[1] = 0;
-	std::vector<uint8_t> data(stateObjectGet(tPtr,ZT_STATE_OBJECT_IDENTITY_SECRET,idtmp));
+	Vector<uint8_t> data(stateObjectGet(tPtr,ZT_STATE_OBJECT_IDENTITY_SECRET,idtmp));
 	bool haveIdentity = false;
 	bool haveIdentity = false;
 	if (!data.empty()) {
 	if (!data.empty()) {
 		data.push_back(0); // zero-terminate string
 		data.push_back(0); // zero-terminate string
@@ -528,12 +524,12 @@ void Node::setController(void *networkControllerInstance)
 
 
 // Methods used only within the core ----------------------------------------------------------------------------------
 // Methods used only within the core ----------------------------------------------------------------------------------
 
 
-std::vector<uint8_t> Node::stateObjectGet(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2])
+Vector<uint8_t> Node::stateObjectGet(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2])
 {
 {
-	std::vector<uint8_t> r;
+	Vector<uint8_t> r;
 	if (m_cb.stateGetFunction) {
 	if (m_cb.stateGetFunction) {
-		void *data = 0;
-		void (*freeFunc)(void *) = 0;
+		void *data = nullptr;
+		void (*freeFunc)(void *) = nullptr;
 		int l = m_cb.stateGetFunction(
 		int l = m_cb.stateGetFunction(
 			reinterpret_cast<ZT_Node *>(this),
 			reinterpret_cast<ZT_Node *>(this),
 			m_uPtr,
 			m_uPtr,

+ 1 - 13
node/Node.hpp

@@ -226,7 +226,7 @@ public:
 	 * @param id Object ID
 	 * @param id Object ID
 	 * @return Vector containing data or empty vector if not found or empty
 	 * @return Vector containing data or empty vector if not found or empty
 	 */
 	 */
-	std::vector<uint8_t> stateObjectGet(void *tPtr,ZT_StateObjectType type,const uint64_t id[2]);
+	Vector<uint8_t> stateObjectGet(void *tPtr,ZT_StateObjectType type,const uint64_t id[2]);
 
 
 	/**
 	/**
 	 * Store a state object
 	 * Store a state object
@@ -299,18 +299,6 @@ public:
 	 */
 	 */
 	ZT_INLINE bool natMustDie() const noexcept { return m_natMustDie; }
 	ZT_INLINE bool natMustDie() const noexcept { return m_natMustDie; }
 
 
-	/**
-	 * Wake peer by calling its alarm() method at or after a given time.
-	 *
-	 * @param peer Identity fingerprint of peer to wake
-	 * @param triggerTime Time alarm should go off
-	 */
-	ZT_INLINE void setPeerAlarm(const Fingerprint &peer,const int64_t triggerTime)
-	{
-		Mutex::Lock l(_peerAlarms_l);
-		_peerAlarms[peer] = triggerTime;
-	}
-
 	/**
 	/**
 	 * Check whether a local controller has authorized a member on a network
 	 * Check whether a local controller has authorized a member on a network
 	 *
 	 *

+ 3 - 0
node/OS.hpp

@@ -194,4 +194,7 @@ typedef unsigned uint128_t __attribute__((mode(TI)));
 #endif
 #endif
 #endif
 #endif
 
 
+// Macro to print very verbose tracing information to standard error.
+#define ZT_SPEW(f,...) fprintf(stderr,"%s(%d): " f ZT_EOL_S,__FILE__,__LINE__,__VA_ARGS__)
+
 #endif
 #endif

+ 2 - 8
node/Path.hpp

@@ -20,13 +20,7 @@
 #include "Utils.hpp"
 #include "Utils.hpp"
 #include "Mutex.hpp"
 #include "Mutex.hpp"
 #include "Meter.hpp"
 #include "Meter.hpp"
-
-#include <cstdint>
-#include <cstring>
-#include <cstdlib>
-#include <stdexcept>
-#include <algorithm>
-#include <set>
+#include "Containers.hpp"
 
 
 namespace ZeroTier {
 namespace ZeroTier {
 
 
@@ -151,7 +145,7 @@ private:
 	// These fields belong to Defragmenter but are kept in Path for performance
 	// These fields belong to Defragmenter but are kept in Path for performance
 	// as it's much faster this way than having Defragmenter maintain another
 	// as it's much faster this way than having Defragmenter maintain another
 	// mapping from paths to inbound message IDs.
 	// mapping from paths to inbound message IDs.
-	std::set<uint64_t> _inboundFragmentedMessages;
+	Set<uint64_t> _inboundFragmentedMessages;
 	Mutex _inboundFragmentedMessages_l;
 	Mutex _inboundFragmentedMessages_l;
 
 
 	std::atomic<int> __refCount;
 	std::atomic<int> __refCount;

+ 27 - 1
node/Peer.hpp

@@ -86,6 +86,32 @@ public:
 		return m_locator;
 		return m_locator;
 	}
 	}
 
 
+	/**
+	 * Set this peer's probe token
+	 *
+	 * This doesn't update the mapping in Topology. The caller must do
+	 * this, which is the HELLO handler in VL1.
+	 *
+	 * @param t New probe token
+	 * @return Old probe token
+	 */
+	ZT_INLINE uint32_t setProbeToken(const uint32_t t) const noexcept
+	{
+		RWMutex::Lock l(m_lock);
+		const uint32_t pt = m_probe;
+		m_probe = t;
+		return pt;
+	}
+
+	/**
+	 * @return This peer's probe token or 0 if unknown
+	 */
+	ZT_INLINE uint32_t probeToken() const noexcept
+	{
+		RWMutex::RLock l(m_lock);
+		return m_probe;
+	}
+
 	/**
 	/**
 	 * Log receipt of an authenticated packet
 	 * Log receipt of an authenticated packet
 	 *
 	 *
@@ -415,7 +441,7 @@ private:
 	List<p_TryQueueItem> m_tryQueue;
 	List<p_TryQueueItem> m_tryQueue;
 	List<p_TryQueueItem>::iterator m_tryQueuePtr; // loops over _tryQueue like a circular buffer
 	List<p_TryQueueItem>::iterator m_tryQueuePtr; // loops over _tryQueue like a circular buffer
 
 
-	// 32-bit probe or 0 if unknown.
+	// 32-bit probe token or 0 if unknown.
 	uint32_t m_probe;
 	uint32_t m_probe;
 
 
 	uint16_t m_vProto;
 	uint16_t m_vProto;

+ 114 - 0
node/PeerList.hpp

@@ -0,0 +1,114 @@
+/*
+ * Copyright (c)2013-2020 ZeroTier, Inc.
+ *
+ * Use of this software is governed by the Business Source License included
+ * in the LICENSE.TXT file in the project's root directory.
+ *
+ * Change Date: 2024-01-01
+ *
+ * On the date above, in accordance with the Business Source License, use
+ * of this software will be governed by version 2.0 of the Apache License.
+ */
+/****/
+
+#ifndef ZT_PEERLIST_HPP
+#define ZT_PEERLIST_HPP
+
+#include "Constants.hpp"
+#include "SharedPtr.hpp"
+#include "Peer.hpp"
+
+namespace ZeroTier {
+
+/**
+ * A list of peers
+ *
+ * This is a simple vector optimized for the case where there will almost always
+ * be zero or one element. In that case it doesn't allocate. If there's more than
+ * one element, it will grow to include all elements.
+ *
+ * It's used to return lookups in Topology where there will almost always be zero
+ * or one peers returned but where there technically (but very rarely) can be more.
+ */
+class PeerList
+{
+public:
+	ZT_INLINE PeerList() noexcept :
+		m_onePeer(),
+		m_peers(&m_onePeer),
+		m_peerCount(0)
+	{}
+
+	ZT_INLINE PeerList(const PeerList &pl)
+	{
+		const unsigned int pc = pl.m_peerCount;
+		if (likely(pc <= 1)) {
+			m_onePeer = pl.m_onePeer;
+			m_peers = &m_onePeer;
+		} else {
+			m_peers = new SharedPtr<Peer>[pc];
+			for (unsigned int i=0;i<pc;++i)
+				m_peers[i] = pl.m_peers[i];
+		}
+		m_peerCount = pc;
+	}
+
+	ZT_INLINE ~PeerList()
+	{
+		if (unlikely(m_peers != &m_onePeer))
+			delete [] m_peers;
+	}
+
+	ZT_INLINE PeerList &operator=(const PeerList &pl)
+	{
+		if (&pl != this) {
+			if (unlikely(m_peers != &m_onePeer))
+				delete [] m_peers;
+			if (likely(pl.m_peerCount <= 1)) {
+				m_onePeer = pl.m_onePeer;
+				m_peers = &m_onePeer;
+			} else {
+				m_onePeer.zero();
+				m_peers = new SharedPtr<Peer>[pl.m_peerCount];
+				for (unsigned int i = 0;i < pl.m_peerCount;++i)
+					m_peers[i] = pl.m_peers[i];
+			}
+			m_peerCount = pl.m_peerCount;
+		}
+		return *this;
+	}
+
+	/**
+	 * Resize the peer list to store a given number of members
+	 *
+	 * To populate the list, this must be called first followed by each member
+	 * being set with the [] operator. List content after this call is undefined
+	 * and may contain old data if the object is being re-used.
+	 *
+	 * @param s New size of list
+	 */
+	ZT_INLINE void resize(const unsigned int s)
+	{
+		if (unlikely(m_peers != &m_onePeer))
+			delete [] m_peers;
+		m_peerCount = s;
+		if (likely(s <= 1)) {
+			m_peers = &m_onePeer;
+		} else {
+			m_peers = new SharedPtr<Peer>[s];
+		}
+	}
+
+	ZT_INLINE SharedPtr<Peer> &operator[](const unsigned int i) noexcept { return m_peers[i]; }
+	ZT_INLINE const SharedPtr<Peer> &operator[](const unsigned int i) const noexcept { return m_peers[i]; }
+	ZT_INLINE unsigned int size() const noexcept { return m_peerCount; }
+
+private:
+	SharedPtr<Peer> m_onePeer;
+	SharedPtr<Peer> *m_peers;
+	unsigned int m_peerCount;
+};
+
+} // namespace ZeroTier
+
+#endif

+ 36 - 289
node/Protocol.hpp

@@ -251,14 +251,16 @@
 #define ZT_PROTO_HELLO_NODE_META_INSTANCE_ID      "i"
 #define ZT_PROTO_HELLO_NODE_META_INSTANCE_ID      "i"
 #define ZT_PROTO_HELLO_NODE_META_LOCATOR          "l"
 #define ZT_PROTO_HELLO_NODE_META_LOCATOR          "l"
 #define ZT_PROTO_HELLO_NODE_META_PROBE_TOKEN      "p"
 #define ZT_PROTO_HELLO_NODE_META_PROBE_TOKEN      "p"
-#define ZT_PROTO_HELLO_NODE_META_NEIGHBORS        "n"
 #define ZT_PROTO_HELLO_NODE_META_SOFTWARE_VENDOR  "s"
 #define ZT_PROTO_HELLO_NODE_META_SOFTWARE_VENDOR  "s"
 #define ZT_PROTO_HELLO_NODE_META_SOFTWARE_VERSION "v"
 #define ZT_PROTO_HELLO_NODE_META_SOFTWARE_VERSION "v"
 #define ZT_PROTO_HELLO_NODE_META_PHYSICAL_DEST    "d"
 #define ZT_PROTO_HELLO_NODE_META_PHYSICAL_DEST    "d"
 #define ZT_PROTO_HELLO_NODE_META_COMPLIANCE       "c"
 #define ZT_PROTO_HELLO_NODE_META_COMPLIANCE       "c"
-#define ZT_PROTO_HELOO_NODE_META_EPHEMERAL_C25519 "0"
-#define ZT_PROTO_HELOO_NODE_META_EPHEMERAL_P384   "1"
-#define ZT_PROTO_HELOO_NODE_META_EPHEMERAL_REMOTE "R"
+#define ZT_PROTO_HELLO_NODE_META_EPHEMERAL_C25519 "0"
+#define ZT_PROTO_HELLO_NODE_META_EPHEMERAL_P384   "1"
+#define ZT_PROTO_HELLO_NODE_META_EPHEMERAL_REMOTE "R"
+
+static_assert(ZT_PROTO_MAX_PACKET_LENGTH < ZT_BUF_MEM_SIZE,"maximum packet length won't fit in Buf");
+static_assert(ZT_PROTO_PACKET_ENCRYPTED_SECTION_START == (ZT_PROTO_MIN_PACKET_LENGTH-1),"encrypted packet section must start right before protocol verb at one less than minimum packet size");
 
 
 namespace ZeroTier {
 namespace ZeroTier {
 namespace Protocol {
 namespace Protocol {
@@ -356,7 +358,6 @@ enum Verb
 	 *
 	 *
 	 *   NAME - arbitrary short user-defined name for this node
 	 *   NAME - arbitrary short user-defined name for this node
 	 *   CONTACT - arbitrary short contact information string for this node
 	 *   CONTACT - arbitrary short contact information string for this node
-	 *   NEIGHBORS - addresses of node(s) to whom we'll relay (mesh-like routing)
 	 *   SOFTWARE_VENDOR - short name or description of vendor, such as a URL
 	 *   SOFTWARE_VENDOR - short name or description of vendor, such as a URL
 	 *   SOFTWARE_VERSION - major, minor, revision, and build (packed 64-bit int)
 	 *   SOFTWARE_VERSION - major, minor, revision, and build (packed 64-bit int)
 	 *   PHYSICAL_DEST - serialized Endpoint to which this message was sent
 	 *   PHYSICAL_DEST - serialized Endpoint to which this message was sent
@@ -425,21 +426,28 @@ enum Verb
 	/**
 	/**
 	 * Relay-mediated NAT traversal or firewall punching initiation:
 	 * Relay-mediated NAT traversal or firewall punching initiation:
 	 *   <[1] flags (unused, currently 0)>
 	 *   <[1] flags (unused, currently 0)>
-	 *   <[5] ZeroTier address of peer that might be found at this address>
+	 *   <[5] ZeroTier address of other peer>
+	 *   <[2] 16-bit number of endpoints where peer might be reached>
+	 *   <[...] endpoints to attempt>
+	 *
+	 * Legacy packet format for pre-2.x peers:
+	 *   <[1] flags (unused, currently 0)>
+	 *   <[5] ZeroTier address of other peer>
 	 *   <[2] 16-bit protocol address port>
 	 *   <[2] 16-bit protocol address port>
 	 *   <[1] protocol address length / type>
 	 *   <[1] protocol address length / type>
 	 *   <[...] protocol address (network byte order)>
 	 *   <[...] protocol address (network byte order)>
 	 *
 	 *
-	 * This is sent by a third party node to inform a node of where another
-	 * may be located. These are currently only allowed from roots.
+	 * When a root or other peer is relaying messages, it can periodically send
+	 * RENDEZVOUS to assist peers in establishing direct communication.
 	 *
 	 *
-	 * The protocol address format differs from the standard InetAddress
-	 * encoding for legacy reasons, but it's not hard to decode. The following
-	 * values are valid for the protocol address length (type) field:
+	 * Peers also directly exchange information via HELLO, so this serves as
+	 * a second way for peers to learn about their possible locations.
 	 *
 	 *
-	 *   4 - IPv4 IP address
-	 *   16 - IPv6 IP address
-	 *   255 - Endpoint object, unmarshaled in place (port ignored)
+	 * It also serves another function: temporal coordination of NAT traversal
+	 * attempts. Some NATs traverse better if both sides first send "firewall
+	 * opener" packets and then send real packets and if this exchange is
+	 * coordinated in time so that the packets effectively pass each other in
+	 * flight.
 	 *
 	 *
 	 * No OK or ERROR is generated.
 	 * No OK or ERROR is generated.
 	 */
 	 */
@@ -627,46 +635,7 @@ enum Verb
 	 */
 	 */
 	VERB_MULTICAST_GATHER = 0x0d,
 	VERB_MULTICAST_GATHER = 0x0d,
 
 
-	/** *** DEPRECATED ***
-	 * Multicast frame:
-	 *   <[8] 64-bit network ID>
-	 *   <[1] flags>
-	 *  [<[4] 32-bit implicit gather limit>]
-	 *  [<[6] source MAC>]
-	 *   <[6] destination MAC (multicast address)>
-	 *   <[4] 32-bit multicast ADI (multicast address extension)>
-	 *   <[2] 16-bit ethertype>
-	 *   <[...] ethernet payload>
-	 *
-	 * Flags:
-	 *   0x01 - Network certificate of membership attached (DEPRECATED)
-	 *   0x02 - Implicit gather limit field is present
-	 *   0x04 - Source MAC is specified -- otherwise it's computed from sender
-	 *   0x08 - Please replicate (sent to multicast replicators)
-	 *
-	 * OK and ERROR responses are optional. OK may be generated if there are
-	 * implicit gather results or if the recipient wants to send its own
-	 * updated certificate of network membership to the sender. ERROR may be
-	 * generated if a certificate is needed or if multicasts to this group
-	 * are no longer wanted (multicast unsubscribe).
-	 *
-	 * OK response payload:
-	 *   <[8] 64-bit network ID>
-	 *   <[6] MAC address of multicast group>
-	 *   <[4] 32-bit ADI for multicast group>
-	 *   <[1] flags>
-	 *  [<[...] network certificate of membership (DEPRECATED)>]
-	 *  [<[...] implicit gather results if flag 0x01 is set>]
-	 *
-	 * OK flags (same bits as request flags):
-	 *   0x01 - OK includes certificate of network membership (DEPRECATED)
-	 *   0x02 - OK includes implicit gather results
-	 *
-	 * ERROR response payload:
-	 *   <[8] 64-bit network ID>
-	 *   <[6] multicast group MAC>
-	 *   <[4] 32-bit multicast group ADI>
-	 */
+	// Deprecated multicast frame message type.
 	VERB_MULTICAST_FRAME_deprecated = 0x0e,
 	VERB_MULTICAST_FRAME_deprecated = 0x0e,
 
 
 	/**
 	/**
@@ -676,14 +645,19 @@ enum Verb
 	 *
 	 *
 	 * Path record format:
 	 * Path record format:
 	 *   <[1] 8-bit path flags>
 	 *   <[1] 8-bit path flags>
-	 *   <[2] length of extended path data or 0 for none>
-	 *   <[...] extended path data>
-	 *   <[1] address type>
-	 *   <[1] address record length in bytes>
-	 *   <[...] address>
-	 *
-	 * Path flags:
-	 *   0x01 - BFG1024 symmetric NAT-t requested
+	 *   <[2] length of endpoint record>
+	 *   <[...] endpoint>
+	 * 
+	 * The following fields are also included if the node is pre-2.x:
+	 *   <[1] address type (LEGACY)>
+	 *   <[1] address length in bytes (LEGACY)>
+	 *   <[...] address (LEGACY)>
+	 *
+	 * Path record flags:
+	 *   0x01 - reserved (legacy)
+	 *   0x02 - reserved (legacy)
+	 *   0x04 - Symmetric NAT detected at sender side
+	 *   0x08 - Request aggressive symmetric NAT traversal
 	 *
 	 *
 	 * OK and ERROR are not generated.
 	 * OK and ERROR are not generated.
 	 */
 	 */
@@ -704,19 +678,6 @@ enum Verb
 	 */
 	 */
 	VERB_USER_MESSAGE = 0x14,
 	VERB_USER_MESSAGE = 0x14,
 
 
-	/**
-	 * Encapsulate a ZeroTier packet for multicast distribution:
-	 *   [... begin signed portion ...]
-	 *   <[1] 8-bit flags>
-	 *   <[5] 40-bit ZeroTier address of sender>
-	 *   <[2] 16-bit length of inner payload>
-	 *   <[1] inner payload verb>
-	 *   <[...] inner payload data>
-	 *   [... end signed portion ...]
-	 *   <[2] 16-bit length of signature or 0 if un-signed>
-	 *  [<[...] optional signature of multicast>]
-	 *   <[...] address (min prefix) list>
-	 */
 	VERB_MULTICAST = 0x16,
 	VERB_MULTICAST = 0x16,
 
 
 	/**
 	/**
@@ -807,220 +768,6 @@ enum NetworkConfigFlag
 	NETWORK_CONFIG_FLAG_FAST_PROPAGATE = 0x01
 	NETWORK_CONFIG_FLAG_FAST_PROPAGATE = 0x01
 };
 };
 
 
-/****************************************************************************/
-
-/*
- * These are bit-packed structures for rapid parsing of packets or at least
- * the fixed size headers thereof. Not all packet types have these as some
- * are full of variable length fields are are more easily parsed through
- * incremental decoding.
- *
- * All fields larger than one byte are in big-endian byte order on the wire.
- */
-
-/**
- * Normal packet header
- *
- * @tparam PT Packet payload type (default: uint8_t[])
- */
-ZT_PACKED_STRUCT(struct Header
-{
-	uint64_t packetId;
-	uint8_t destination[5];
-	uint8_t source[5];
-	uint8_t flags;
-	uint64_t mac;
-	// --- begin encrypted envelope ---
-	uint8_t verb;
-});
-
-/**
- * Packet fragment header
- */
-ZT_PACKED_STRUCT(struct FragmentHeader
-{
-	uint64_t packetId;
-	uint8_t destination[5];
-	uint8_t fragmentIndicator; // always 0xff for fragments
-	uint8_t counts; // total: most significant four bits, number: least significant four bits
-	uint8_t hops; // top 5 bits unused and must be zero
-});
-
-ZT_PACKED_STRUCT(struct HELLO
-{
-	Header h;
-	uint8_t versionProtocol;
-	uint8_t versionMajor;
-	uint8_t versionMinor;
-	uint16_t versionRev;
-	uint64_t timestamp;
-});
-
-ZT_PACKED_STRUCT(struct RENDEZVOUS
-{
-	Header h;
-	uint8_t flags;
-	uint8_t peerAddress[5];
-	uint16_t port;
-	uint8_t addressLength;
-});
-
-ZT_PACKED_STRUCT(struct FRAME
-{
-	Header h;
-	uint64_t networkId;
-	uint16_t etherType;
-});
-
-ZT_PACKED_STRUCT(struct EXT_FRAME
-{
-	Header h;
-	uint64_t networkId;
-	uint8_t flags;
-});
-
-ZT_PACKED_STRUCT(struct PUSH_DIRECT_PATHS
-{
-	Header h;
-	uint16_t numPaths;
-});
-
-ZT_PACKED_STRUCT(struct MULTICAST_LIKE
-{
-	ZT_PACKED_STRUCT(struct Entry
-	{
-		uint64_t networkId;
-		uint8_t mac[6];
-		uint32_t adi;
-	});
-
-	Header h;
-});
-
-namespace OK {
-
-/**
- * OK response header
- *
- * @tparam PT OK payload type (default: uint8_t[])
- */
-ZT_PACKED_STRUCT(struct Header
-{
-	Protocol::Header h;
-	uint8_t inReVerb;
-	uint64_t inRePacketId;
-});
-
-ZT_PACKED_STRUCT(struct WHOIS
-{
-	OK::Header h;
-});
-
-ZT_PACKED_STRUCT(struct ECHO
-{
-	OK::Header h;
-});
-
-ZT_PACKED_STRUCT(struct HELLO
-{
-	OK::Header h;
-	uint64_t timestampEcho;
-	uint8_t versionProtocol;
-	uint8_t versionMajor;
-	uint8_t versionMinor;
-	uint16_t versionRev;
-});
-
-ZT_PACKED_STRUCT(struct EXT_FRAME
-{
-	OK::Header h;
-	uint64_t networkId;
-	uint8_t flags;
-	uint8_t destMac[6];
-	uint8_t sourceMac[6];
-	uint16_t etherType;
-});
-
-ZT_PACKED_STRUCT(struct NETWORK_CONFIG
-{
-	OK::Header h;
-	uint64_t networkId;
-	uint64_t configUpdateId;
-});
-
-} // namespace OK
-
-namespace ERROR {
-
-/**
- * Error header
- *
- * The error header comes after the packet header but before type-specific payloads.
- *
- * @tparam PT Error payload type (default: uint8_t[])
- */
-ZT_PACKED_STRUCT(struct Header
-{
-	Protocol::Header h;
-	int8_t inReVerb;
-	uint64_t inRePacketId;
-	uint8_t error;
-});
-
-ZT_PACKED_STRUCT(struct NEED_MEMBERSHIP_CERTIFICATE
-{
-	ERROR::Header h;
-	uint64_t networkId;
-});
-
-ZT_PACKED_STRUCT(struct UNSUPPORTED_OPERATION__NETWORK_CONFIG_REQUEST
-{
-	ERROR::Header h;
-	uint64_t networkId;
-});
-
-} // namespace ERROR
-
-/****************************************************************************/
-
-static_assert(sizeof(Protocol::Header) == ZT_PROTO_MIN_PACKET_LENGTH,"Protocol::Header struct packing error");
-static_assert(sizeof(Protocol::FragmentHeader) == ZT_PROTO_MIN_FRAGMENT_LENGTH,"Protocol::FragmentHeader struct packing error");
-static_assert(ZT_PROTO_MAX_PACKET_LENGTH < ZT_BUF_MEM_SIZE,"maximum packet length won't fit in Buf");
-static_assert(ZT_PROTO_PACKET_ENCRYPTED_SECTION_START == (ZT_PROTO_MIN_PACKET_LENGTH-1),"encrypted packet section must start right before protocol verb at one less than minimum packet size");
-
-/**
- * Convenience function to pull packet ID from a raw buffer
- *
- * @param pkt Packet to read first 8 bytes from
- * @param packetSize Packet's actual size in bytes
- * @return Packet ID or 0 if packet size is less than 8
- */
-static ZT_INLINE uint64_t packetId(const Buf &pkt,const unsigned int packetSize) noexcept { return (packetSize >= 8) ? Utils::loadBigEndian<uint64_t>(pkt.unsafeData) : 0ULL; }
-
-/**
- * @param Packet to extract hops from
- * @param packetSize Packet's actual size in bytes
- * @return 3-bit hops field embedded in packet flags field
- */
-static ZT_INLINE uint8_t packetHops(const Buf &pkt,const unsigned int packetSize) noexcept { return (packetSize >= ZT_PROTO_PACKET_FLAGS_INDEX) ? (pkt.unsafeData[ZT_PROTO_PACKET_FLAGS_INDEX] & ZT_PROTO_FLAG_FIELD_HOPS_MASK) : 0; }
-
-/**
- * @param Packet to extract cipher ID from
- * @param packetSize Packet's actual size in bytes
- * @return 3-bit cipher field embedded in packet flags field
- */
-static ZT_INLINE uint8_t packetCipher(const Buf &pkt,const unsigned int packetSize) noexcept { return (packetSize >= ZT_PROTO_PACKET_FLAGS_INDEX) ? ((pkt.unsafeData[ZT_PROTO_PACKET_FLAGS_INDEX] >> 3U) & 0x07U) : 0; }
-
-/**
- * @return 3-bit hops field embedded in packet flags field
- */
-static ZT_INLINE uint8_t packetHops(const Header &ph) noexcept { return (ph.flags & 0x07U); }
-
-/**
- * @return 3-bit cipher field embedded in packet flags field
- */
-static ZT_INLINE uint8_t packetCipher(const Header &ph) noexcept { return ((ph.flags >> 3U) & 0x07U); }
-
 /**
 /**
  * Deterministically mangle a 256-bit crypto key based on packet characteristics
  * Deterministically mangle a 256-bit crypto key based on packet characteristics
  *
  *

+ 1 - 1
node/RuntimeEnvironment.hpp

@@ -55,7 +55,7 @@ public:
 		secretIdentityStr[0] = (char)0;
 		secretIdentityStr[0] = (char)0;
 	}
 	}
 
 
-	ZT_INLINE ~RuntimeEnvironment()
+	ZT_INLINE ~RuntimeEnvironment() noexcept
 	{
 	{
 		Utils::burn(secretIdentityStr,sizeof(secretIdentityStr));
 		Utils::burn(secretIdentityStr,sizeof(secretIdentityStr));
 	}
 	}

+ 10 - 9
node/SelfAwareness.cpp

@@ -17,8 +17,7 @@
 #include "Topology.hpp"
 #include "Topology.hpp"
 #include "Peer.hpp"
 #include "Peer.hpp"
 #include "Trace.hpp"
 #include "Trace.hpp"
-
-#include <set>
+#include "Containers.hpp"
 
 
 // Entry timeout -- make it fairly long since this is just to prevent stale buildup
 // Entry timeout -- make it fairly long since this is just to prevent stale buildup
 #define ZT_SELFAWARENESS_ENTRY_TIMEOUT 300000
 #define ZT_SELFAWARENESS_ENTRY_TIMEOUT 300000
@@ -67,7 +66,7 @@ void SelfAwareness::iam(void *tPtr,const Identity &reporter,const int64_t receiv
 		// Erase all entries in this scope that were not reported from this remote address to prevent 'thrashing'
 		// Erase all entries in this scope that were not reported from this remote address to prevent 'thrashing'
 		// due to multiple reports of endpoint change.
 		// due to multiple reports of endpoint change.
 		// Don't use 'entry' after this since hash table gets modified.
 		// Don't use 'entry' after this since hash table gets modified.
-		for(Map<p_PhySurfaceKey,p_PhySurfaceEntry>::iterator i(m_phy.begin());i != m_phy.end();) { // NOLINT(modernize-loop-convert,modernize-use-auto,hicpp-use-auto)
+		for(Map<p_PhySurfaceKey,p_PhySurfaceEntry>::iterator i(m_phy.begin());i != m_phy.end();) {
 			if ((i->first.scope == scope)&&(i->first.reporterPhysicalAddress != reporterPhysicalAddress))
 			if ((i->first.scope == scope)&&(i->first.reporterPhysicalAddress != reporterPhysicalAddress))
 				m_phy.erase(i++);
 				m_phy.erase(i++);
 			else ++i;
 			else ++i;
@@ -89,27 +88,29 @@ void SelfAwareness::iam(void *tPtr,const Identity &reporter,const int64_t receiv
 void SelfAwareness::clean(int64_t now)
 void SelfAwareness::clean(int64_t now)
 {
 {
 	Mutex::Lock l(m_phy_l);
 	Mutex::Lock l(m_phy_l);
-	for(Map<p_PhySurfaceKey,p_PhySurfaceEntry>::iterator i(m_phy.begin());i != m_phy.end();) { // NOLINT(modernize-loop-convert,modernize-use-auto,hicpp-use-auto)
+	for(Map<p_PhySurfaceKey,p_PhySurfaceEntry>::iterator i(m_phy.begin());i != m_phy.end();) {
 		if ((now - i->second.ts) >= ZT_SELFAWARENESS_ENTRY_TIMEOUT)
 		if ((now - i->second.ts) >= ZT_SELFAWARENESS_ENTRY_TIMEOUT)
 			m_phy.erase(i++);
 			m_phy.erase(i++);
 		else ++i;
 		else ++i;
 	}
 	}
 }
 }
 
 
-SelfAwareness::ExternalAddressList SelfAwareness::externalAddresses(const int64_t now) const
+MultiMap<unsigned int,InetAddress> SelfAwareness::externalAddresses(const int64_t now) const
 {
 {
-	SelfAwareness::ExternalAddressList r;
-	Map<InetAddress,unsigned long> counts;
+	MultiMap<unsigned int,InetAddress> r;
 
 
+	// Count endpoints reporting each IP/port combo
+	Map<InetAddress,unsigned long> counts;
 	{
 	{
 		Mutex::Lock l(m_phy_l);
 		Mutex::Lock l(m_phy_l);
-		for(Map<p_PhySurfaceKey,p_PhySurfaceEntry>::const_iterator i(m_phy.begin());i != m_phy.end();++i) { // NOLINT(modernize-loop-convert,modernize-use-auto,hicpp-use-auto)
+		for(Map<p_PhySurfaceKey,p_PhySurfaceEntry>::const_iterator i(m_phy.begin());i != m_phy.end();++i) {
 			if ((now - i->second.ts) < ZT_SELFAWARENESS_ENTRY_TIMEOUT)
 			if ((now - i->second.ts) < ZT_SELFAWARENESS_ENTRY_TIMEOUT)
 				++counts[i->second.mySurface];
 				++counts[i->second.mySurface];
 		}
 		}
 	}
 	}
 
 
-	for(Map<InetAddress,unsigned long>::iterator i(counts.begin());i!=counts.end();++i) // NOLINT(modernize-loop-convert,modernize-use-auto,hicpp-use-auto)
+	// Invert to create a map from count to address
+	for(Map<InetAddress,unsigned long>::iterator i(counts.begin());i!=counts.end();++i)
 		r.insert(std::pair<unsigned long,InetAddress>(i->second,i->first));
 		r.insert(std::pair<unsigned long,InetAddress>(i->second,i->first));
 
 
 	return r;
 	return r;

+ 1 - 3
node/SelfAwareness.hpp

@@ -33,8 +33,6 @@ class RuntimeEnvironment;
 class SelfAwareness
 class SelfAwareness
 {
 {
 public:
 public:
-	typedef std::multimap< unsigned long,InetAddress,std::less<unsigned long>,Utils::Mallocator< std::pair<const unsigned long,InetAddress> > > ExternalAddressList;
-
 	explicit SelfAwareness(const RuntimeEnvironment *renv);
 	explicit SelfAwareness(const RuntimeEnvironment *renv);
 
 
 	/**
 	/**
@@ -62,7 +60,7 @@ public:
 	 * @param now Current time
 	 * @param now Current time
 	 * @return Map of count to IP/port representing how many endpoints reported each address
 	 * @return Map of count to IP/port representing how many endpoints reported each address
 	 */
 	 */
-	ExternalAddressList externalAddresses(int64_t now) const;
+	MultiMap<unsigned int,InetAddress> externalAddresses(int64_t now) const;
 
 
 private:
 private:
 	struct p_PhySurfaceKey
 	struct p_PhySurfaceKey

+ 25 - 1
node/SharedPtr.hpp

@@ -127,7 +127,31 @@ public:
 		if (m_ptr) {
 		if (m_ptr) {
 			if (--m_ptr->__refCount <= 0)
 			if (--m_ptr->__refCount <= 0)
 				delete m_ptr;
 				delete m_ptr;
-			m_ptr = (T *)0;
+			m_ptr = nullptr;
+		}
+	}
+
+	/**
+	 * Set pointer to NULL and delete object if reference count is only 1
+	 *
+	 * This can be called periodically to implement something like a weak
+	 * reference as it exists in other more managed languages like Java,
+	 * but with the caveat that it only works if there is only one remaining
+	 * SharedPtr to be treated as weak.
+	 *
+	 * @return True if object was in fact deleted or was already zero/NULL
+	 */
+	ZT_INLINE bool weakGC()
+	{
+		if (m_ptr) {
+			if (m_ptr->__refCount.compare_exchange_strong(1,0)) {
+				delete m_ptr;
+				m_ptr = nullptr;
+				return true;
+			}
+			return false;
+		} else {
+			return true;
 		}
 		}
 	}
 	}
 
 

+ 87 - 76
node/Topology.cpp

@@ -15,31 +15,12 @@
 
 
 namespace ZeroTier {
 namespace ZeroTier {
 
 
-const uint64_t Topology::s_pathHashSalt = Utils::getSecureRandomU64();
-
-// Sorts roots so as to put the lowest latency alive root first.
-struct _RootSortComparisonOperator
-{
-	ZT_INLINE _RootSortComparisonOperator(const int64_t now) : _now(now) {}
-	ZT_INLINE bool operator()(const SharedPtr<Peer> &a,const SharedPtr<Peer> &b)
-	{
-		const int64_t now = _now;
-		if (a->active(now)) {
-			if (b->active(now))
-				return (a->latency() < b->latency());
-			return true;
-		}
-		return a->lastReceive() < b->lastReceive();
-	}
-	const int64_t _now;
-};
-
 Topology::Topology(const RuntimeEnvironment *renv,void *tPtr) :
 Topology::Topology(const RuntimeEnvironment *renv,void *tPtr) :
 	RR(renv),
 	RR(renv),
 	m_numConfiguredPhysicalPaths(0)
 	m_numConfiguredPhysicalPaths(0)
 {
 {
 	uint64_t idtmp[2]; idtmp[0] = 0; idtmp[1] = 0;
 	uint64_t idtmp[2]; idtmp[0] = 0; idtmp[1] = 0;
-	std::vector<uint8_t> data(RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_ROOTS,idtmp));
+	Vector<uint8_t> data(RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_ROOTS,idtmp));
 	if (!data.empty()) {
 	if (!data.empty()) {
 		uint8_t *dptr = data.data();
 		uint8_t *dptr = data.data();
 		int drem = (int)data.size();
 		int drem = (int)data.size();
@@ -50,57 +31,66 @@ Topology::Topology(const RuntimeEnvironment *renv,void *tPtr) :
 				m_roots.insert(id);
 				m_roots.insert(id);
 				dptr += l;
 				dptr += l;
 				drem -= l;
 				drem -= l;
+				ZT_SPEW("recalled root %s",id.address().toString().c_str());
 			}
 			}
 		}
 		}
 	}
 	}
 
 
-	for(std::set<Identity>::const_iterator r(m_roots.begin());r != m_roots.end();++r) {
+	for(Set<Identity>::const_iterator r(m_roots.begin());r != m_roots.end();++r) {
 		SharedPtr<Peer> p;
 		SharedPtr<Peer> p;
-		m_loadCached(tPtr, r->address(), p);
+		m_loadCached(tPtr,r->address(),p);
 		if ((!p)||(p->identity() != *r)) {
 		if ((!p)||(p->identity() != *r)) {
 			p.set(new Peer(RR));
 			p.set(new Peer(RR));
 			p->init(*r);
 			p->init(*r);
 		}
 		}
 		m_rootPeers.push_back(p);
 		m_rootPeers.push_back(p);
 		m_peers[p->address()] = p;
 		m_peers[p->address()] = p;
-		m_peersByIncomingProbe[p->incomingProbe()] = p;
-		m_peersByIdentityHash[p->identity().fingerprint()] = p;
 	}
 	}
 }
 }
 
 
-Topology::~Topology()
-{
-}
-
 SharedPtr<Peer> Topology::add(void *tPtr,const SharedPtr<Peer> &peer)
 SharedPtr<Peer> Topology::add(void *tPtr,const SharedPtr<Peer> &peer)
 {
 {
 	RWMutex::Lock _l(m_peers_l);
 	RWMutex::Lock _l(m_peers_l);
-
 	SharedPtr<Peer> &hp = m_peers[peer->address()];
 	SharedPtr<Peer> &hp = m_peers[peer->address()];
 	if (hp)
 	if (hp)
 		return hp;
 		return hp;
-
-	m_loadCached(tPtr, peer->address(), hp);
-	if (hp) {
-		m_peersByIncomingProbe[peer->incomingProbe()] = hp;
-		m_peersByIdentityHash[peer->identity().fingerprint()] = hp;
+	m_loadCached(tPtr,peer->address(),hp);
+	if (hp)
 		return hp;
 		return hp;
-	}
-
 	hp = peer;
 	hp = peer;
-	m_peersByIncomingProbe[peer->incomingProbe()] = peer;
-	m_peersByIdentityHash[peer->identity().fingerprint()] = peer;
-
 	return peer;
 	return peer;
 }
 }
 
 
-void Topology::getAllPeers(std::vector< SharedPtr<Peer> > &allPeers) const
+PeerList Topology::peersByProbeToken(const uint32_t probeToken) const
 {
 {
-	RWMutex::RLock l(m_peers_l);
-	allPeers.clear();
-	allPeers.reserve(m_peers.size());
-	for(Map< Address,SharedPtr<Peer> >::const_iterator i(m_peers.begin());i != m_peers.end();++i)
-		allPeers.push_back(i->second);
+	Mutex::Lock l(m_peersByProbeToken_l);
+	std::pair< MultiMap< uint32_t,SharedPtr<Peer> >::const_iterator,MultiMap< uint32_t,SharedPtr<Peer> >::const_iterator > r(m_peersByProbeToken.equal_range(probeToken));
+	PeerList pl;
+	if (r.first == r.second)
+		return pl;
+	const unsigned int cnt = (unsigned int)std::distance(r.first,r.second);
+	pl.resize(cnt);
+	MultiMap< uint32_t,SharedPtr<Peer> >::const_iterator pi(r.first);
+	for(unsigned int i=0;i<cnt;++i) {
+		pl[i] = pi->second;
+		++pi;
+	}
+	return pl;
+}
+
+void Topology::updateProbeToken(const SharedPtr<Peer> &peer,const uint32_t oldToken,const uint32_t newToken)
+{
+	Mutex::Lock l(m_peersByProbeToken_l);
+	if (oldToken != 0) {
+		std::pair< MultiMap< uint32_t,SharedPtr<Peer> >::iterator,MultiMap< uint32_t,SharedPtr<Peer> >::iterator > r(m_peersByProbeToken.equal_range(oldToken));
+		for(MultiMap< uint32_t,SharedPtr<Peer> >::iterator i(r.first);i!=r.second;) {
+			if (i->second == peer)
+				m_peersByProbeToken.erase(i++);
+			else ++i;
+		}
+	}
+	if (newToken != 0)
+		m_peersByProbeToken.insert(std::pair< uint32_t,SharedPtr<Peer> >(newToken,peer));
 }
 }
 
 
 void Topology::setPhysicalPathConfiguration(const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig)
 void Topology::setPhysicalPathConfiguration(const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig)
@@ -137,11 +127,25 @@ void Topology::setPhysicalPathConfiguration(const struct sockaddr_storage *pathN
 	}
 	}
 }
 }
 
 
-void Topology::addRoot(void *tPtr,const Identity &id,const InetAddress &bootstrap)
+struct p_RootSortComparisonOperator
 {
 {
-	if (id == RR->identity) return; // sanity check
+	ZT_INLINE bool operator()(const SharedPtr<Peer> &a,const SharedPtr<Peer> &b) const noexcept
+	{
+		// Sort in inverse order of latency with lowest latency first (and -1 last).
+		const int bb = b->latency();
+		if (bb < 0)
+			return true;
+		return bb < a->latency();
+	}
+};
+
+void Topology::addRoot(void *const tPtr,const Identity &id,const InetAddress &bootstrap)
+{
+	if (id == RR->identity)
+		return;
+
 	RWMutex::Lock l1(m_peers_l);
 	RWMutex::Lock l1(m_peers_l);
-	std::pair< std::set<Identity>::iterator,bool > ir(m_roots.insert(id));
+	std::pair< Set<Identity>::iterator,bool > ir(m_roots.insert(id));
 	if (ir.second) {
 	if (ir.second) {
 		SharedPtr<Peer> &p = m_peers[id.address()];
 		SharedPtr<Peer> &p = m_peers[id.address()];
 		if (!p) {
 		if (!p) {
@@ -149,68 +153,56 @@ void Topology::addRoot(void *tPtr,const Identity &id,const InetAddress &bootstra
 			p->init(id);
 			p->init(id);
 			if (bootstrap)
 			if (bootstrap)
 				p->setBootstrap(Endpoint(bootstrap));
 				p->setBootstrap(Endpoint(bootstrap));
-			m_peersByIncomingProbe[p->incomingProbe()] = p;
-			m_peersByIdentityHash[p->identity().fingerprint()] = p;
 		}
 		}
 		m_rootPeers.push_back(p);
 		m_rootPeers.push_back(p);
-
-		uint8_t *const roots = (uint8_t *)malloc(ZT_IDENTITY_MARSHAL_SIZE_MAX * m_roots.size());
-		if (roots) {
-			int p = 0;
-			for(std::set<Identity>::const_iterator i(m_roots.begin());i != m_roots.end();++i) {
-				int pp = i->marshal(roots + p,false);
-				if (pp > 0)
-					p += pp;
-			}
-			uint64_t id[2];
-			id[0] = 0;
-			id[1] = 0;
-			RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_ROOTS,id,roots,(unsigned int)p);
-			free(roots);
-		}
+		std::sort(m_rootPeers.begin(),m_rootPeers.end(),p_RootSortComparisonOperator());
+		m_writeRootList(tPtr);
 	}
 	}
 }
 }
 
 
-bool Topology::removeRoot(const Identity &id)
+bool Topology::removeRoot(void *const tPtr,const Identity &id)
 {
 {
 	RWMutex::Lock l1(m_peers_l);
 	RWMutex::Lock l1(m_peers_l);
-	std::set<Identity>::iterator r(m_roots.find(id));
+	Set<Identity>::iterator r(m_roots.find(id));
 	if (r != m_roots.end()) {
 	if (r != m_roots.end()) {
-		for(std::vector< SharedPtr<Peer> >::iterator p(m_rootPeers.begin());p != m_rootPeers.end();++p) {
+		for(Vector< SharedPtr<Peer> >::iterator p(m_rootPeers.begin());p != m_rootPeers.end();++p) {
 			if ((*p)->identity() == id) {
 			if ((*p)->identity() == id) {
 				m_rootPeers.erase(p);
 				m_rootPeers.erase(p);
 				break;
 				break;
 			}
 			}
 		}
 		}
 		m_roots.erase(r);
 		m_roots.erase(r);
+		m_writeRootList(tPtr);
 		return true;
 		return true;
 	}
 	}
 	return false;
 	return false;
 }
 }
 
 
-void Topology::rankRoots(const int64_t now)
+void Topology::rankRoots()
 {
 {
 	RWMutex::Lock l1(m_peers_l);
 	RWMutex::Lock l1(m_peers_l);
-	std::sort(m_rootPeers.begin(), m_rootPeers.end(), _RootSortComparisonOperator(now));
+	std::sort(m_rootPeers.begin(),m_rootPeers.end(),p_RootSortComparisonOperator());
 }
 }
 
 
 void Topology::doPeriodicTasks(void *tPtr,const int64_t now)
 void Topology::doPeriodicTasks(void *tPtr,const int64_t now)
 {
 {
+	// Delete peers that haven't said anything in ZT_PEER_ALIVE_TIMEOUT.
 	{
 	{
 		RWMutex::Lock l1(m_peers_l);
 		RWMutex::Lock l1(m_peers_l);
 		for(Map< Address,SharedPtr<Peer> >::iterator i(m_peers.begin());i != m_peers.end();) {
 		for(Map< Address,SharedPtr<Peer> >::iterator i(m_peers.begin());i != m_peers.end();) {
-			if ( (!i->second->alive(now)) && (m_roots.count(i->second->identity()) == 0) ) {
+			if ( ((now - i->second->lastReceive()) > ZT_PEER_ALIVE_TIMEOUT) && (m_roots.count(i->second->identity()) == 0) ) {
+				updateProbeToken(i->second,i->second->probeToken(),0);
 				i->second->save(tPtr);
 				i->second->save(tPtr);
-				m_peersByIncomingProbe.erase(i->second->incomingProbe());
-				m_peersByIdentityHash.erase(i->second->identity().fingerprint());
 				m_peers.erase(i++);
 				m_peers.erase(i++);
 			} else ++i;
 			} else ++i;
 		}
 		}
 	}
 	}
+
+	// Delete paths that are no longer held by anyone else ("weak reference" type behavior).
 	{
 	{
 		RWMutex::Lock l1(m_paths_l);
 		RWMutex::Lock l1(m_paths_l);
 		for(Map< uint64_t,SharedPtr<Path> >::iterator i(m_paths.begin());i != m_paths.end();) {
 		for(Map< uint64_t,SharedPtr<Path> >::iterator i(m_paths.begin());i != m_paths.end();) {
-			if ((i->second.references() <= 1)&&(!i->second->alive(now)))
+			if (i->second.weakGC())
 				m_paths.erase(i++);
 				m_paths.erase(i++);
 			else ++i;
 			else ++i;
 		}
 		}
@@ -220,7 +212,7 @@ void Topology::doPeriodicTasks(void *tPtr,const int64_t now)
 void Topology::saveAll(void *tPtr)
 void Topology::saveAll(void *tPtr)
 {
 {
 	RWMutex::RLock l(m_peers_l);
 	RWMutex::RLock l(m_peers_l);
-	for(Map< Address,SharedPtr<Peer> >::iterator i(m_peers.begin());i != m_peers.end();++i)
+	for(Map< Address,SharedPtr<Peer> >::iterator i(m_peers.begin());i!=m_peers.end();++i)
 		i->second->save(tPtr);
 		i->second->save(tPtr);
 }
 }
 
 
@@ -230,7 +222,7 @@ void Topology::m_loadCached(void *tPtr, const Address &zta, SharedPtr<Peer> &pee
 		uint64_t id[2];
 		uint64_t id[2];
 		id[0] = zta.toInt();
 		id[0] = zta.toInt();
 		id[1] = 0;
 		id[1] = 0;
-		std::vector<uint8_t> data(RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_PEER,id));
+		Vector<uint8_t> data(RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_PEER,id));
 		if (data.size() > 8) {
 		if (data.size() > 8) {
 			const uint8_t *d = data.data();
 			const uint8_t *d = data.data();
 			int dl = (int)data.size();
 			int dl = (int)data.size();
@@ -253,4 +245,23 @@ void Topology::m_loadCached(void *tPtr, const Address &zta, SharedPtr<Peer> &pee
 	}
 	}
 }
 }
 
 
+void Topology::m_writeRootList(void *tPtr)
+{
+	// assumes m_peers_l is locked
+	uint8_t *const roots = (uint8_t *)malloc(ZT_IDENTITY_MARSHAL_SIZE_MAX * m_roots.size());
+	if (roots) { // sanity check
+		int p = 0;
+		for(Set<Identity>::const_iterator i(m_roots.begin());i != m_roots.end();++i) {
+			const int pp = i->marshal(roots + p,false);
+			if (pp > 0)
+				p += pp;
+		}
+		uint64_t id[2];
+		id[0] = 0;
+		id[1] = 0;
+		RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_ROOTS,id,roots,(unsigned int)p);
+		free(roots);
+	}
+}
+
 } // namespace ZeroTier
 } // namespace ZeroTier

+ 37 - 64
node/Topology.hpp

@@ -14,12 +14,6 @@
 #ifndef ZT_TOPOLOGY_HPP
 #ifndef ZT_TOPOLOGY_HPP
 #define ZT_TOPOLOGY_HPP
 #define ZT_TOPOLOGY_HPP
 
 
-#include <cstring>
-#include <vector>
-#include <algorithm>
-#include <utility>
-#include <set>
-
 #include "Constants.hpp"
 #include "Constants.hpp"
 #include "Address.hpp"
 #include "Address.hpp"
 #include "Identity.hpp"
 #include "Identity.hpp"
@@ -31,6 +25,7 @@
 #include "ScopedPtr.hpp"
 #include "ScopedPtr.hpp"
 #include "Fingerprint.hpp"
 #include "Fingerprint.hpp"
 #include "Containers.hpp"
 #include "Containers.hpp"
+#include "PeerList.hpp"
 
 
 namespace ZeroTier {
 namespace ZeroTier {
 
 
@@ -43,7 +38,6 @@ class Topology
 {
 {
 public:
 public:
 	Topology(const RuntimeEnvironment *renv,void *tPtr);
 	Topology(const RuntimeEnvironment *renv,void *tPtr);
-	~Topology();
 
 
 	/**
 	/**
 	 * Add peer to database
 	 * Add peer to database
@@ -89,34 +83,21 @@ public:
 	}
 	}
 
 
 	/**
 	/**
-	 * Get a peer by its 384-bit identity public key hash
+	 * Get peer(s) by 32-bit probe token
 	 *
 	 *
-	 * @param hash Identity hash
-	 * @return Peer or NULL if no peer is currently in memory for this hash (cache is not checked in this case)
+	 * @param probeToken Probe token
+	 * @return List of peers
 	 */
 	 */
-	ZT_INLINE SharedPtr<Peer> peerByHash(const Fingerprint &hash)
-	{
-		RWMutex::RLock _l(m_peers_l);
-		const SharedPtr<Peer> *const ap = m_peersByIdentityHash.get(hash);
-		if (ap)
-			return *ap;
-		return SharedPtr<Peer>();
-	}
+	PeerList peersByProbeToken(uint32_t probeToken) const;
 
 
 	/**
 	/**
-	 * Get a peer by its incoming short probe packet payload
+	 * Set or update the probe token associated with a peer
 	 *
 	 *
-	 * @param probe Short probe payload (in big-endian byte order)
-	 * @return Peer or NULL if no peer is currently in memory matching this probe (cache is not checked in this case)
+	 * @param peer Peer to update
+	 * @param oldToken Old probe token or 0 if none
+	 * @param newToken New probe token or 0 to erase old mapping but not set a new token
 	 */
 	 */
-	ZT_INLINE SharedPtr<Peer> peerByProbe(const uint64_t probe)
-	{
-		RWMutex::RLock _l(m_peers_l);
-		const SharedPtr<Peer> *const ap = m_peersByIncomingProbe.get(probe);
-		if (ap)
-			return *ap;
-		return SharedPtr<Peer>();
-	}
+	void updateProbeToken(const SharedPtr<Peer> &peer,uint32_t oldToken,uint32_t newToken);
 
 
 	/**
 	/**
 	 * Get a Path object for a given local and remote physical address, creating if needed
 	 * Get a Path object for a given local and remote physical address, creating if needed
@@ -163,7 +144,7 @@ public:
 	ZT_INLINE bool isRoot(const Identity &id) const
 	ZT_INLINE bool isRoot(const Identity &id) const
 	{
 	{
 		RWMutex::RLock l(m_peers_l);
 		RWMutex::RLock l(m_peers_l);
-		return (m_roots.count(id) > 0);
+		return (m_roots.find(id) != m_roots.end());
 	}
 	}
 
 
 	/**
 	/**
@@ -210,24 +191,17 @@ public:
 	}
 	}
 
 
 	/**
 	/**
-	 * Iterate through all paths in the system
-	 *
-	 * @tparam F Function to call for each path
-	 * @param f
+	 * @param allPeers vector to fill with all current peers
 	 */
 	 */
-	template<typename F>
-	ZT_INLINE void eachPath(F f) const
+	ZT_INLINE void getAllPeers(Vector< SharedPtr<Peer> > &allPeers) const
 	{
 	{
-		RWMutex::RLock l(m_paths_l);
-		for(Map< uint64_t,SharedPtr<Path> >::const_iterator i(m_paths.begin());i != m_paths.end();++i) // NOLINT(modernize-loop-convert,hicpp-use-auto,modernize-use-auto)
-			f(i->second);
+		RWMutex::RLock l(m_peers_l);
+		allPeers.clear();
+		allPeers.reserve(m_peers.size());
+		for(Map< Address,SharedPtr<Peer> >::const_iterator i(m_peers.begin());i != m_peers.end();++i)
+			allPeers.push_back(i->second);
 	}
 	}
 
 
-	/**
-	 * @param allPeers vector to fill with all current peers
-	 */
-	void getAllPeers(std::vector< SharedPtr<Peer> > &allPeers) const;
-
 	/**
 	/**
 	 * Get info about a path
 	 * Get info about a path
 	 *
 	 *
@@ -295,17 +269,18 @@ public:
 	/**
 	/**
 	 * Remove a root server's identity from the root server set
 	 * Remove a root server's identity from the root server set
 	 *
 	 *
+	 * @param tPtr Thread pointer
 	 * @param id Root server identity
 	 * @param id Root server identity
 	 * @return True if root found and removed, false if not found
 	 * @return True if root found and removed, false if not found
 	 */
 	 */
-	bool removeRoot(const Identity &id);
+	bool removeRoot(void *tPtr,const Identity &id);
 
 
 	/**
 	/**
 	 * Sort roots in asecnding order of apparent latency
 	 * Sort roots in asecnding order of apparent latency
 	 *
 	 *
 	 * @param now Current time
 	 * @param now Current time
 	 */
 	 */
-	void rankRoots(int64_t now);
+	void rankRoots();
 
 
 	/**
 	/**
 	 * Do periodic tasks such as database cleanup
 	 * Do periodic tasks such as database cleanup
@@ -318,47 +293,45 @@ public:
 	void saveAll(void *tPtr);
 	void saveAll(void *tPtr);
 
 
 private:
 private:
-	// Load cached peer and set 'peer' to it, if one is found.
 	void m_loadCached(void *tPtr, const Address &zta, SharedPtr<Peer> &peer);
 	void m_loadCached(void *tPtr, const Address &zta, SharedPtr<Peer> &peer);
-
-	// This is a secure random integer created at startup to salt the calculation of path hash map keys
-	static const uint64_t s_pathHashSalt;
+	void m_writeRootList(void *tPtr);
 
 
 	// This gets an integer key from an InetAddress for looking up paths.
 	// This gets an integer key from an InetAddress for looking up paths.
-	static ZT_INLINE uint64_t s_getPathKey(int64_t l, const InetAddress &r)
+	static ZT_INLINE uint64_t s_getPathKey(const int64_t l,const InetAddress &r)
 	{
 	{
 		if (r.family() == AF_INET) {
 		if (r.family() == AF_INET) {
-			return s_pathHashSalt + (uint64_t)(reinterpret_cast<const struct sockaddr_in *>(&r)->sin_addr.s_addr) + (uint64_t)Utils::ntoh(reinterpret_cast<const struct sockaddr_in *>(&r)->sin_port) + (uint64_t)l;
+			return ((uint64_t)(reinterpret_cast<const sockaddr_in *>(&r)->sin_addr.s_addr) << 24U) +
+			       ((uint64_t)reinterpret_cast<const sockaddr_in *>(&r)->sin_port << 8U) +
+						 (uint64_t)l;
 		} else if (r.family() == AF_INET6) {
 		} else if (r.family() == AF_INET6) {
 #ifdef ZT_NO_UNALIGNED_ACCESS
 #ifdef ZT_NO_UNALIGNED_ACCESS
-			uint64_t h = s_pathHashSalt;
-			for(int i=0;i<16;++i) {
-				h += (uint64_t)((reinterpret_cast<const struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr)[i]);
-				h += (h << 10U);
-				h ^= (h >> 6U);
-			}
+			uint64_t htmp[2];
+			Utils::copy<16>(htmp,reinterpret_cast<const sockaddr_in6 *>(&r)->sin6_addr.s6_addr);
+			const uint64_t h = htmp[0] ^ htmp[1];
 #else
 #else
-			uint64_t h = s_pathHashSalt + (reinterpret_cast<const uint64_t *>(reinterpret_cast<const struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr)[0] + reinterpret_cast<const uint64_t *>(reinterpret_cast<const struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr)[1]);
+			const uint64_t h = reinterpret_cast<const uint64_t *>(reinterpret_cast<const sockaddr_in6 *>(&r)->sin6_addr.s6_addr)[0] ^
+			                   reinterpret_cast<const uint64_t *>(reinterpret_cast<const sockaddr_in6 *>(&r)->sin6_addr.s6_addr)[1];
 #endif
 #endif
-			return h + (uint64_t)Utils::ntoh(reinterpret_cast<const struct sockaddr_in6 *>(&r)->sin6_port) + (uint64_t)l;
+			return h + (uint64_t)Utils::ntoh(reinterpret_cast<const struct sockaddr_in6 *>(&r)->sin6_port) ^ (uint64_t)l;
 		} else {
 		} else {
-			return Utils::fnv1a32(reinterpret_cast<const void *>(&r),sizeof(InetAddress)) + (uint64_t)l;
+			return (uint64_t)Utils::fnv1a32(reinterpret_cast<const void *>(&r),sizeof(InetAddress)) + (uint64_t)l;
 		}
 		}
 	}
 	}
 
 
 	const RuntimeEnvironment *const RR;
 	const RuntimeEnvironment *const RR;
 
 
-	RWMutex m_peers_l;
 	RWMutex m_paths_l;
 	RWMutex m_paths_l;
+	Mutex m_peersByProbeToken_l;
+	RWMutex m_peers_l;
 
 
 	std::pair< InetAddress,ZT_PhysicalPathConfiguration > m_physicalPathConfig[ZT_MAX_CONFIGURABLE_PATHS];
 	std::pair< InetAddress,ZT_PhysicalPathConfiguration > m_physicalPathConfig[ZT_MAX_CONFIGURABLE_PATHS];
 	unsigned int m_numConfiguredPhysicalPaths;
 	unsigned int m_numConfiguredPhysicalPaths;
 
 
 	Map< uint64_t,SharedPtr<Path> > m_paths;
 	Map< uint64_t,SharedPtr<Path> > m_paths;
 
 
+	MultiMap< uint32_t,SharedPtr<Peer> > m_peersByProbeToken;
+
 	Map< Address,SharedPtr<Peer> > m_peers;
 	Map< Address,SharedPtr<Peer> > m_peers;
-	Map< uint64_t,SharedPtr<Peer> > m_peersByIncomingProbe;
-	Map< Fingerprint,SharedPtr<Peer> > m_peersByIdentityHash;
 	Set< Identity > m_roots;
 	Set< Identity > m_roots;
 	Vector< SharedPtr<Peer> > m_rootPeers;
 	Vector< SharedPtr<Peer> > m_rootPeers;
 };
 };

+ 0 - 4
node/Trace.cpp

@@ -18,10 +18,6 @@
 #include "Path.hpp"
 #include "Path.hpp"
 #include "InetAddress.hpp"
 #include "InetAddress.hpp"
 
 
-#include <cstdio>
-#include <cstdlib>
-#include <cstdarg>
-
 // NOTE: packet IDs are always handled in network byte order, so no need to convert them.
 // NOTE: packet IDs are always handled in network byte order, so no need to convert them.
 
 
 namespace ZeroTier {
 namespace ZeroTier {

+ 1 - 5
node/Trace.hpp

@@ -20,11 +20,7 @@
 #include "InetAddress.hpp"
 #include "InetAddress.hpp"
 #include "Address.hpp"
 #include "Address.hpp"
 #include "MAC.hpp"
 #include "MAC.hpp"
-
-#include <cstdint>
-#include <cstring>
-#include <cstdlib>
-#include <vector>
+#include "Containers.hpp"
 
 
 #define ZT_TRACE_F_VL1           0x01U
 #define ZT_TRACE_F_VL1           0x01U
 #define ZT_TRACE_F_VL2           0x02U
 #define ZT_TRACE_F_VL2           0x02U

+ 0 - 3
node/TriviallyCopyable.hpp

@@ -17,9 +17,6 @@
 #include "Constants.hpp"
 #include "Constants.hpp"
 #include "Utils.hpp"
 #include "Utils.hpp"
 
 
-#include <cstring>
-#include <cstdlib>
-
 namespace ZeroTier {
 namespace ZeroTier {
 
 
 /**
 /**

+ 0 - 2
node/VL1.hpp

@@ -23,8 +23,6 @@
 #include "FCV.hpp"
 #include "FCV.hpp"
 #include "Containers.hpp"
 #include "Containers.hpp"
 
 
-#include <vector>
-
 namespace ZeroTier {
 namespace ZeroTier {
 
 
 class RuntimeEnvironment;
 class RuntimeEnvironment;

+ 1 - 0
node/VL2.hpp

@@ -20,6 +20,7 @@
 #include "Protocol.hpp"
 #include "Protocol.hpp"
 #include "Mutex.hpp"
 #include "Mutex.hpp"
 #include "FCV.hpp"
 #include "FCV.hpp"
+#include "Containers.hpp"
 
 
 namespace ZeroTier {
 namespace ZeroTier {