Browse Source

A bunch of build fixes.

Adam Ierymenko 5 years ago
parent
commit
864e33cf2d

+ 4 - 6
go/native/GoGlue.cpp

@@ -42,8 +42,6 @@
 
 
 #include <thread>
 #include <thread>
 #include <mutex>
 #include <mutex>
-#include <map>
-#include <vector>
 #include <memory>
 #include <memory>
 #include <atomic>
 #include <atomic>
 
 
@@ -65,7 +63,7 @@ using namespace ZeroTier;
 
 
 struct ZT_GoNodeThread
 struct ZT_GoNodeThread
 {
 {
-	std::string ip;
+	String ip;
 	int port;
 	int port;
 	int af;
 	int af;
 	bool primary;
 	bool primary;
@@ -91,7 +89,7 @@ struct ZT_GoNode_Impl
 	std::thread backgroundTaskThread;
 	std::thread backgroundTaskThread;
 };
 };
 
 
-static const std::string defaultHomePath(OSUtils::platformDefaultHomePath());
+static const String defaultHomePath(OSUtils::platformDefaultHomePath());
 const char *const ZT_PLATFORM_DEFAULT_HOMEPATH = defaultHomePath.c_str();
 const char *const ZT_PLATFORM_DEFAULT_HOMEPATH = defaultHomePath.c_str();
 
 
 // These are implemented in Go code.
 // These are implemented in Go code.
@@ -182,7 +180,7 @@ static ZT_INLINE void doUdpSend(ZT_SOCKET sock,const struct sockaddr_storage *ad
 {
 {
 	switch(addr->ss_family) {
 	switch(addr->ss_family) {
 		case AF_INET:
 		case AF_INET:
-			if ((ipTTL > 0)&&(ipTTL < 255)) {
+			if (unlikely((ipTTL > 0)&&(ipTTL < 255))) {
 #ifdef __WINDOWS__
 #ifdef __WINDOWS__
 				DWORD tmp = (DWORD)ipTTL;
 				DWORD tmp = (DWORD)ipTTL;
 #else
 #else
@@ -215,7 +213,7 @@ static int ZT_GoNode_WirePacketSendFunction(
 	unsigned int len,
 	unsigned int len,
 	unsigned int ipTTL)
 	unsigned int ipTTL)
 {
 {
-	if (localSocket > 0) {
+	if (likely(localSocket > 0)) {
 		doUdpSend((ZT_SOCKET)localSocket,addr,data,len,ipTTL);
 		doUdpSend((ZT_SOCKET)localSocket,addr,data,len,ipTTL);
 	} else {
 	} else {
 		ZT_GoNode *const gn = reinterpret_cast<ZT_GoNode *>(uptr);
 		ZT_GoNode *const gn = reinterpret_cast<ZT_GoNode *>(uptr);

+ 5 - 6
go/pkg/zerotier/node.go

@@ -67,19 +67,18 @@ const (
 )
 )
 
 
 var (
 var (
-	// PlatformDefaultHomePath is the default location of ZeroTier's working path on this system
-	PlatformDefaultHomePath string = C.GoString(C.ZT_PLATFORM_DEFAULT_HOMEPATH)
-
-	cNodeRefs    [maxCNodeRefs]*Node
-	cNodeRefUsed [maxCNodeRefs]uint32
-
+	PlatformDefaultHomePath string
 	CoreVersionMajor    int
 	CoreVersionMajor    int
 	CoreVersionMinor    int
 	CoreVersionMinor    int
 	CoreVersionRevision int
 	CoreVersionRevision int
 	CoreVersionBuild    int
 	CoreVersionBuild    int
+
+	cNodeRefs    [maxCNodeRefs]*Node
+	cNodeRefUsed [maxCNodeRefs]uint32
 )
 )
 
 
 func init() {
 func init() {
+	PlatformDefaultHomePath = C.GoString(C.ZT_PLATFORM_DEFAULT_HOMEPATH);
 	var vMaj, vMin, vRev, vBuild C.int
 	var vMaj, vMin, vRev, vBuild C.int
 	C.ZT_version(&vMaj, &vMin, &vRev, &vBuild)
 	C.ZT_version(&vMaj, &vMin, &vRev, &vBuild)
 	CoreVersionMajor = int(vMaj)
 	CoreVersionMajor = int(vMaj)

+ 1 - 1
node/Address.hpp

@@ -32,7 +32,7 @@ class Address : public TriviallyCopyable
 {
 {
 public:
 public:
 	ZT_INLINE Address() noexcept : _a(0) {}
 	ZT_INLINE Address() noexcept : _a(0) {}
-	explicit ZT_INLINE Address(const uint64_t a) noexcept : _a(a) {}
+	ZT_INLINE Address(const uint64_t a) noexcept : _a(a) {}
 	explicit ZT_INLINE Address(const uint8_t b[5]) noexcept : _a(((uint64_t)b[0] << 32U) | ((uint64_t)b[1] << 24U) | ((uint64_t)b[2] << 16U) | ((uint64_t)b[3] << 8U) | (uint64_t)b[4]) {}
 	explicit ZT_INLINE Address(const uint8_t b[5]) noexcept : _a(((uint64_t)b[0] << 32U) | ((uint64_t)b[1] << 24U) | ((uint64_t)b[2] << 16U) | ((uint64_t)b[3] << 8U) | (uint64_t)b[4]) {}
 
 
 	ZT_INLINE Address &operator=(const uint64_t a) noexcept { _a = a; return *this; }
 	ZT_INLINE Address &operator=(const uint64_t a) noexcept { _a = a; return *this; }

+ 19 - 19
node/CertificateOfMembership.cpp

@@ -82,7 +82,7 @@ bool CertificateOfMembership::agreesWith(const CertificateOfMembership &other) c
 
 
 	// SECURITY: check for issued-to inequality is a sanity check. This should be impossible since elsewhere
 	// SECURITY: check for issued-to inequality is a sanity check. This should be impossible since elsewhere
 	// in the code COMs are checked to ensure that they do in fact belong to their issued-to identities.
 	// in the code COMs are checked to ensure that they do in fact belong to their issued-to identities.
-	return (other.m_networkId == m_networkId) && (m_networkId != 0) && (other.m_issuedTo.address() != m_issuedTo.address());
+	return (other.m_networkId == m_networkId) && (m_networkId != 0) && (other.m_issuedTo.address != m_issuedTo.address);
 }
 }
 
 
 bool CertificateOfMembership::sign(const Identity &with) noexcept
 bool CertificateOfMembership::sign(const Identity &with) noexcept
@@ -115,7 +115,7 @@ int CertificateOfMembership::marshal(uint8_t data[ZT_CERTIFICATEOFMEMBERSHIP_MAR
 	p += 8;
 	p += 8;
 	Utils::storeBigEndian<uint64_t>(data + p, 2);
 	Utils::storeBigEndian<uint64_t>(data + p, 2);
 	p += 8;
 	p += 8;
-	Utils::storeBigEndian<uint64_t>(data + p, m_issuedTo.address().toInt());
+	Utils::storeBigEndian<uint64_t>(data + p, m_issuedTo.address);
 	p += 8;
 	p += 8;
 	Utils::storeAsIsEndian<uint64_t>(data + p, 0xffffffffffffffffULL);
 	Utils::storeAsIsEndian<uint64_t>(data + p, 0xffffffffffffffffULL);
 	p += 8;
 	p += 8;
@@ -123,7 +123,7 @@ int CertificateOfMembership::marshal(uint8_t data[ZT_CERTIFICATEOFMEMBERSHIP_MAR
 	if (v2) {
 	if (v2) {
 		// V2 marshal format will have three tuples followed by the fingerprint hash.
 		// V2 marshal format will have three tuples followed by the fingerprint hash.
 		Utils::storeBigEndian<uint16_t>(data + 1, 3);
 		Utils::storeBigEndian<uint16_t>(data + 1, 3);
-		Utils::copy<48>(data + p, m_issuedTo.hash());
+		Utils::copy<ZT_FINGERPRINT_HASH_SIZE>(data + p, m_issuedTo.hash);
 		p += 48;
 		p += 48;
 	} else {
 	} else {
 		// V1 marshal format must shove everything into tuples, resulting in nine.
 		// V1 marshal format must shove everything into tuples, resulting in nine.
@@ -131,7 +131,7 @@ int CertificateOfMembership::marshal(uint8_t data[ZT_CERTIFICATEOFMEMBERSHIP_MAR
 		for (int k = 0;k < 6;++k) {
 		for (int k = 0;k < 6;++k) {
 			Utils::storeBigEndian<uint64_t>(data + p, (uint64_t) k + 3);
 			Utils::storeBigEndian<uint64_t>(data + p, (uint64_t) k + 3);
 			p += 8;
 			p += 8;
-			Utils::storeAsIsEndian<uint64_t>(data + p, Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash() + (k * 8)));
+			Utils::storeAsIsEndian<uint64_t>(data + p, Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash + (k * 8)));
 			p += 8;
 			p += 8;
 			Utils::storeAsIsEndian<uint64_t>(data + p, 0xffffffffffffffffULL);
 			Utils::storeAsIsEndian<uint64_t>(data + p, 0xffffffffffffffffULL);
 			p += 8;
 			p += 8;
@@ -185,27 +185,27 @@ int CertificateOfMembership::unmarshal(const uint8_t *data, int len) noexcept
 				m_networkId = value;
 				m_networkId = value;
 				break;
 				break;
 			case 2:
 			case 2:
-				m_issuedTo.apiFingerprint()->address = value;
+				m_issuedTo.address = value;
 				break;
 				break;
 
 
 				// V1 nodes will pack the hash into qualifier tuples.
 				// V1 nodes will pack the hash into qualifier tuples.
 			case 3:
 			case 3:
-				Utils::storeBigEndian<uint64_t>(m_issuedTo.apiFingerprint()->hash, value);
+				Utils::storeBigEndian<uint64_t>(m_issuedTo.hash, value);
 				break;
 				break;
 			case 4:
 			case 4:
-				Utils::storeBigEndian<uint64_t>(m_issuedTo.apiFingerprint()->hash + 8, value);
+				Utils::storeBigEndian<uint64_t>(m_issuedTo.hash + 8, value);
 				break;
 				break;
 			case 5:
 			case 5:
-				Utils::storeBigEndian<uint64_t>(m_issuedTo.apiFingerprint()->hash + 16, value);
+				Utils::storeBigEndian<uint64_t>(m_issuedTo.hash + 16, value);
 				break;
 				break;
 			case 6:
 			case 6:
-				Utils::storeBigEndian<uint64_t>(m_issuedTo.apiFingerprint()->hash + 24, value);
+				Utils::storeBigEndian<uint64_t>(m_issuedTo.hash + 24, value);
 				break;
 				break;
 			case 7:
 			case 7:
-				Utils::storeBigEndian<uint64_t>(m_issuedTo.apiFingerprint()->hash + 32, value);
+				Utils::storeBigEndian<uint64_t>(m_issuedTo.hash + 32, value);
 				break;
 				break;
 			case 8:
 			case 8:
-				Utils::storeBigEndian<uint64_t>(m_issuedTo.apiFingerprint()->hash + 40, value);
+				Utils::storeBigEndian<uint64_t>(m_issuedTo.hash + 40, value);
 				break;
 				break;
 
 
 			default:
 			default:
@@ -227,7 +227,7 @@ int CertificateOfMembership::unmarshal(const uint8_t *data, int len) noexcept
 	} else if (data[0] == 2) {
 	} else if (data[0] == 2) {
 		if ((p + 48) > len)
 		if ((p + 48) > len)
 			return -1;
 			return -1;
-		Utils::copy<48>(m_issuedTo.apiFingerprint()->hash, data + p);
+		Utils::copy<48>(m_issuedTo.hash, data + p);
 		p += 48;
 		p += 48;
 		if ((p + 2) > len)
 		if ((p + 2) > len)
 			return -1;
 			return -1;
@@ -259,7 +259,7 @@ unsigned int CertificateOfMembership::m_fillSigningBuf(uint64_t *buf) const noex
 	buf[4] = Utils::hton(m_networkId);
 	buf[4] = Utils::hton(m_networkId);
 	buf[5] = 0;
 	buf[5] = 0;
 	buf[6] = ZT_CONST_TO_BE_UINT64(2);
 	buf[6] = ZT_CONST_TO_BE_UINT64(2);
-	buf[7] = Utils::hton(m_issuedTo.address().toInt());
+	buf[7] = Utils::hton(m_issuedTo.address);
 	buf[8] = informational;
 	buf[8] = informational;
 
 
 	unsigned int p = 9;
 	unsigned int p = 9;
@@ -268,22 +268,22 @@ unsigned int CertificateOfMembership::m_fillSigningBuf(uint64_t *buf) const noex
 	// embeded as a series of informational tuples.
 	// embeded as a series of informational tuples.
 	if (m_issuedTo.haveHash()) {
 	if (m_issuedTo.haveHash()) {
 		buf[p++] = ZT_CONST_TO_BE_UINT64(3);
 		buf[p++] = ZT_CONST_TO_BE_UINT64(3);
-		buf[p++] = Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash());
+		buf[p++] = Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash);
 		buf[p++] = informational;
 		buf[p++] = informational;
 		buf[p++] = ZT_CONST_TO_BE_UINT64(4);
 		buf[p++] = ZT_CONST_TO_BE_UINT64(4);
-		buf[p++] = Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash() + 8);
+		buf[p++] = Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash + 8);
 		buf[p++] = informational;
 		buf[p++] = informational;
 		buf[p++] = ZT_CONST_TO_BE_UINT64(5);
 		buf[p++] = ZT_CONST_TO_BE_UINT64(5);
-		buf[p++] = Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash() + 16);
+		buf[p++] = Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash + 16);
 		buf[p++] = informational;
 		buf[p++] = informational;
 		buf[p++] = ZT_CONST_TO_BE_UINT64(6);
 		buf[p++] = ZT_CONST_TO_BE_UINT64(6);
-		buf[p++] = Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash() + 24);
+		buf[p++] = Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash + 24);
 		buf[p++] = informational;
 		buf[p++] = informational;
 		buf[p++] = ZT_CONST_TO_BE_UINT64(7);
 		buf[p++] = ZT_CONST_TO_BE_UINT64(7);
-		buf[p++] = Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash() + 32);
+		buf[p++] = Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash + 32);
 		buf[p++] = informational;
 		buf[p++] = informational;
 		buf[p++] = ZT_CONST_TO_BE_UINT64(8);
 		buf[p++] = ZT_CONST_TO_BE_UINT64(8);
-		buf[p++] = Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash() + 40);
+		buf[p++] = Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash + 40);
 		buf[p++] = informational;
 		buf[p++] = informational;
 	}
 	}
 
 

+ 6 - 6
node/Dictionary.cpp

@@ -110,7 +110,7 @@ uint64_t Dictionary::getUI(const char *k, uint64_t dfl) const
 char *Dictionary::getS(const char *k, char *v, const unsigned int cap) const
 char *Dictionary::getS(const char *k, char *v, const unsigned int cap) const
 {
 {
 	if (cap == 0) // sanity check
 	if (cap == 0) // sanity check
-		return;
+		return v;
 	const Vector<uint8_t> &e = (*this)[k];
 	const Vector<uint8_t> &e = (*this)[k];
 	unsigned int i = 0;
 	unsigned int i = 0;
 	const unsigned int last = cap - 1;
 	const unsigned int last = cap - 1;
@@ -134,8 +134,8 @@ bool Dictionary::sign(const Identity &signer)
 		return false;
 		return false;
 
 
 	uint8_t fp[ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE];
 	uint8_t fp[ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE];
-	signer.fingerprint().address().copyTo(fp);
-	Utils::copy<ZT_FINGERPRINT_HASH_SIZE>(fp + ZT_ADDRESS_LENGTH, signer.fingerprint().hash());
+	Address(signer.fingerprint().address).copyTo(fp);
+	Utils::copy<ZT_FINGERPRINT_HASH_SIZE>(fp + ZT_ADDRESS_LENGTH, signer.fingerprint().hash);
 
 
 	m_entries[s_signatureFingerprint].assign(fp, fp + ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE);
 	m_entries[s_signatureFingerprint].assign(fp, fp + ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE);
 	m_entries[s_signatureData].assign(sig, sig + siglen);
 	m_entries[s_signatureData].assign(sig, sig + siglen);
@@ -148,8 +148,8 @@ Fingerprint Dictionary::signer() const
 	SortedMap<FCV<char, 8>, Vector<uint8_t> >::const_iterator sigfp(m_entries.find(s_signatureFingerprint));
 	SortedMap<FCV<char, 8>, Vector<uint8_t> >::const_iterator sigfp(m_entries.find(s_signatureFingerprint));
 	Fingerprint fp;
 	Fingerprint fp;
 	if ((sigfp != m_entries.end()) && (sigfp->second.size() == (ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE))) {
 	if ((sigfp != m_entries.end()) && (sigfp->second.size() == (ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE))) {
-		fp.apiFingerprint()->address = Address(sigfp->second.data()).toInt();
-		Utils::copy<ZT_FINGERPRINT_HASH_SIZE>(fp.apiFingerprint()->hash, sigfp->second.data() + ZT_ADDRESS_LENGTH);
+		fp.address = Address(sigfp->second.data());
+		Utils::copy<ZT_FINGERPRINT_HASH_SIZE>(fp.hash, sigfp->second.data() + ZT_ADDRESS_LENGTH);
 	}
 	}
 	return fp;
 	return fp;
 }
 }
@@ -161,7 +161,7 @@ bool Dictionary::verify(const Identity &signer) const
 		(sigfp == m_entries.end()) ||
 		(sigfp == m_entries.end()) ||
 		(sigfp->second.size() != (ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE)) ||
 		(sigfp->second.size() != (ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE)) ||
 		(Address(sigfp->second.data()) != signer.address()) ||
 		(Address(sigfp->second.data()) != signer.address()) ||
-		(memcmp(sigfp->second.data() + ZT_ADDRESS_LENGTH,signer.fingerprint().hash(),ZT_FINGERPRINT_HASH_SIZE) != 0))
+		(memcmp(sigfp->second.data() + ZT_ADDRESS_LENGTH,signer.fingerprint().hash,ZT_FINGERPRINT_HASH_SIZE) != 0))
 		return false;
 		return false;
 
 
 	SortedMap< FCV<char, 8>, Vector<uint8_t> >::const_iterator sig(m_entries.find(s_signatureData));
 	SortedMap< FCV<char, 8>, Vector<uint8_t> >::const_iterator sig(m_entries.find(s_signatureData));

+ 2 - 2
node/Identity.cpp

@@ -528,10 +528,10 @@ void Identity::m_computeHash()
 			m_fp.zero();
 			m_fp.zero();
 			break;
 			break;
 		case C25519:
 		case C25519:
-			SHA384(m_fp.m_cfp.hash, m_pub, ZT_C25519_COMBINED_PUBLIC_KEY_SIZE);
+			SHA384(m_fp.hash, m_pub, ZT_C25519_COMBINED_PUBLIC_KEY_SIZE);
 			break;
 			break;
 		case P384:
 		case P384:
-			SHA384(m_fp.m_cfp.hash, m_pub, sizeof(m_pub));
+			SHA384(m_fp.hash, m_pub, ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE);
 			break;
 			break;
 	}
 	}
 }
 }

+ 1 - 1
node/Identity.hpp

@@ -127,7 +127,7 @@ public:
 	/**
 	/**
 	 * @return This identity's address
 	 * @return This identity's address
 	 */
 	 */
-	ZT_INLINE Address address() const noexcept { return Address(m_fp.m_cfp.address); }
+	ZT_INLINE Address address() const noexcept { return Address(m_fp.address); }
 
 
 	/**
 	/**
 	 * @return Full fingerprint of this identity (address plus SHA384 of keys)
 	 * @return Full fingerprint of this identity (address plus SHA384 of keys)

+ 1 - 0
node/Locator.hpp

@@ -36,6 +36,7 @@ namespace ZeroTier {
 class Locator
 class Locator
 {
 {
 	friend class SharedPtr<Locator>;
 	friend class SharedPtr<Locator>;
+	friend class SharedPtr<const Locator>;
 
 
 public:
 public:
 	ZT_INLINE Locator() noexcept :
 	ZT_INLINE Locator() noexcept :

+ 1 - 1
node/Network.cpp

@@ -1155,7 +1155,7 @@ Membership::AddCredentialResult Network::addCredential(void *tPtr,const Identity
 	if (com.networkId() != m_id)
 	if (com.networkId() != m_id)
 		return Membership::ADD_REJECTED;
 		return Membership::ADD_REJECTED;
 	Mutex::Lock _l(m_memberships_l);
 	Mutex::Lock _l(m_memberships_l);
-	return m_memberships[com.issuedTo().address()].addCredential(RR, tPtr, sourcePeerIdentity, m_config, com);
+	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)

+ 1 - 1
node/Node.cpp

@@ -287,7 +287,7 @@ ZT_ResultCode Node::join(uint64_t nwid, const ZT_Fingerprint *controllerFingerpr
 {
 {
 	Fingerprint fp;
 	Fingerprint fp;
 	if (controllerFingerprint)
 	if (controllerFingerprint)
-		Utils::copy<sizeof(ZT_Fingerprint)>(fp.apiFingerprint(), controllerFingerprint);
+		fp = *controllerFingerprint;
 
 
 	RWMutex::Lock l(m_networks_l);
 	RWMutex::Lock l(m_networks_l);
 	SharedPtr<Network> &nw = m_networks[nwid];
 	SharedPtr<Network> &nw = m_networks[nwid];

+ 16 - 16
node/SharedPtr.hpp

@@ -31,23 +31,23 @@ class SharedPtr : public TriviallyCopyable
 {
 {
 public:
 public:
 	ZT_INLINE SharedPtr() noexcept : m_ptr((T *)0) {}
 	ZT_INLINE SharedPtr() noexcept : m_ptr((T *)0) {}
-	explicit ZT_INLINE SharedPtr(T *obj) noexcept : m_ptr(obj) { ++obj->__refCount; }
+	explicit ZT_INLINE SharedPtr(T *obj) noexcept : m_ptr(obj) { if (likely(obj != nullptr)) ++*const_cast<std::atomic<int> *>(&(obj->__refCount)); }
 	ZT_INLINE SharedPtr(const SharedPtr &sp) noexcept : m_ptr(sp._getAndInc()) {}
 	ZT_INLINE SharedPtr(const SharedPtr &sp) noexcept : m_ptr(sp._getAndInc()) {}
 
 
 	ZT_INLINE ~SharedPtr()
 	ZT_INLINE ~SharedPtr()
 	{
 	{
-		if (m_ptr) {
-			if (--m_ptr->__refCount <= 0)
+		if (likely(m_ptr != nullptr)) {
+			if (unlikely(--*const_cast<std::atomic<int> *>(&(m_ptr->__refCount)) <= 0))
 				delete m_ptr;
 				delete m_ptr;
 		}
 		}
 	}
 	}
 
 
 	ZT_INLINE SharedPtr &operator=(const SharedPtr &sp)
 	ZT_INLINE SharedPtr &operator=(const SharedPtr &sp)
 	{
 	{
-		if (m_ptr != sp.m_ptr) {
+		if (likely(m_ptr != sp.m_ptr)) {
 			T *p = sp._getAndInc();
 			T *p = sp._getAndInc();
-			if (m_ptr) {
-				if (--m_ptr->__refCount <= 0)
+			if (likely(m_ptr != nullptr)) {
+				if (unlikely(--*const_cast<std::atomic<int> *>(&(m_ptr->__refCount)) <= 0))
 					delete m_ptr;
 					delete m_ptr;
 			}
 			}
 			m_ptr = p;
 			m_ptr = p;
@@ -66,7 +66,7 @@ public:
 	ZT_INLINE void set(T *ptr) noexcept
 	ZT_INLINE void set(T *ptr) noexcept
 	{
 	{
 		zero();
 		zero();
-		++ptr->__refCount;
+		++*const_cast<std::atomic<int> *>(&(ptr->__refCount));
 		m_ptr = ptr;
 		m_ptr = ptr;
 	}
 	}
 
 
@@ -101,8 +101,8 @@ public:
 	 */
 	 */
 	ZT_INLINE void move(SharedPtr &from)
 	ZT_INLINE void move(SharedPtr &from)
 	{
 	{
-		if (m_ptr) {
-			if (--m_ptr->__refCount <= 0)
+		if (likely(m_ptr != nullptr)) {
+			if (--*const_cast<std::atomic<int> *>(&(m_ptr->__refCount)) <= 0)
 				delete m_ptr;
 				delete m_ptr;
 		}
 		}
 		m_ptr = from.m_ptr;
 		m_ptr = from.m_ptr;
@@ -124,8 +124,8 @@ public:
 	 */
 	 */
 	ZT_INLINE void zero()
 	ZT_INLINE void zero()
 	{
 	{
-		if (m_ptr) {
-			if (--m_ptr->__refCount <= 0)
+		if (likely(m_ptr != nullptr)) {
+			if (unlikely(--*const_cast<std::atomic<int> *>(&(m_ptr->__refCount)) <= 0))
 				delete m_ptr;
 				delete m_ptr;
 			m_ptr = nullptr;
 			m_ptr = nullptr;
 		}
 		}
@@ -139,13 +139,13 @@ public:
 	 * but with the caveat that it only works if there is only one remaining
 	 * but with the caveat that it only works if there is only one remaining
 	 * SharedPtr to be treated as weak.
 	 * SharedPtr to be treated as weak.
 	 *
 	 *
-	 * @return True if object was in fact deleted or was already zero/NULL
+	 * @return True if object was in fact deleted OR this pointer was already NULL
 	 */
 	 */
 	ZT_INLINE bool weakGC()
 	ZT_INLINE bool weakGC()
 	{
 	{
-		if (m_ptr) {
+		if (likely(m_ptr != nullptr)) {
 			int one = 1;
 			int one = 1;
-			if (m_ptr->__refCount.compare_exchange_strong(one,(int)0)) {
+			if (const_cast<std::atomic<int> *>(&(m_ptr->__refCount))->compare_exchange_strong(one,(int)0)) {
 				delete m_ptr;
 				delete m_ptr;
 				m_ptr = nullptr;
 				m_ptr = nullptr;
 				return true;
 				return true;
@@ -161,7 +161,7 @@ public:
 	 */
 	 */
 	ZT_INLINE int references() noexcept
 	ZT_INLINE int references() noexcept
 	{
 	{
-		if (m_ptr)
+		if (likely(m_ptr != nullptr))
 			return m_ptr->__refCount;
 			return m_ptr->__refCount;
 		return 0;
 		return 0;
 	}
 	}
@@ -177,7 +177,7 @@ private:
 	ZT_INLINE T *_getAndInc() const noexcept
 	ZT_INLINE T *_getAndInc() const noexcept
 	{
 	{
 		if (m_ptr)
 		if (m_ptr)
-			++m_ptr->__refCount;
+			++*const_cast<std::atomic<int> *>(&(m_ptr->__refCount));
 		return m_ptr;
 		return m_ptr;
 	}
 	}
 	T *m_ptr;
 	T *m_ptr;

+ 6 - 6
node/Trace.cpp

@@ -78,13 +78,13 @@ void Trace::_tryingNewPath(
 	FCV<uint8_t,4096> buf;
 	FCV<uint8_t,4096> buf;
 	Dictionary::append(buf,ZT_TRACE_FIELD_TYPE,ZT_TRACE_VL1_TRYING_NEW_PATH);
 	Dictionary::append(buf,ZT_TRACE_FIELD_TYPE,ZT_TRACE_VL1_TRYING_NEW_PATH);
 	Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
 	Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
-	Dictionary::append(buf,ZT_TRACE_FIELD_IDENTITY_FINGERPRINT_HASH,trying.fingerprint().hash(),ZT_FINGERPRINT_HASH_SIZE);
+	Dictionary::append(buf,ZT_TRACE_FIELD_IDENTITY_FINGERPRINT_HASH,trying.fingerprint().hash,ZT_FINGERPRINT_HASH_SIZE);
 	if (triggerAddress)
 	if (triggerAddress)
 		Dictionary::appendObject(buf,ZT_TRACE_FIELD_TRIGGER_FROM_ENDPOINT,Endpoint(triggerAddress));
 		Dictionary::appendObject(buf,ZT_TRACE_FIELD_TRIGGER_FROM_ENDPOINT,Endpoint(triggerAddress));
 	Dictionary::appendPacketId(buf,ZT_TRACE_FIELD_TRIGGER_FROM_PACKET_ID,triggeringPacketId);
 	Dictionary::appendPacketId(buf,ZT_TRACE_FIELD_TRIGGER_FROM_PACKET_ID,triggeringPacketId);
 	Dictionary::append(buf,ZT_TRACE_FIELD_TRIGGER_FROM_PACKET_VERB,triggeringPacketVerb);
 	Dictionary::append(buf,ZT_TRACE_FIELD_TRIGGER_FROM_PACKET_VERB,triggeringPacketVerb);
 	if (triggeringPeer)
 	if (triggeringPeer)
-		Dictionary::append(buf,ZT_TRACE_FIELD_TRIGGER_FROM_PEER_FINGERPRINT_HASH,triggeringPeer.fingerprint().hash(),ZT_FINGERPRINT_HASH_SIZE);
+		Dictionary::append(buf,ZT_TRACE_FIELD_TRIGGER_FROM_PEER_FINGERPRINT_HASH,triggeringPeer.fingerprint().hash,ZT_FINGERPRINT_HASH_SIZE);
 	buf.push_back(0);
 	buf.push_back(0);
 	RR->node->postEvent(tPtr,ZT_EVENT_TRACE,buf.data());
 	RR->node->postEvent(tPtr,ZT_EVENT_TRACE,buf.data());
 }
 }
@@ -101,7 +101,7 @@ void Trace::_learnedNewPath(
 	Dictionary::append(buf,ZT_TRACE_FIELD_TYPE,ZT_TRACE_VL1_LEARNED_NEW_PATH);
 	Dictionary::append(buf,ZT_TRACE_FIELD_TYPE,ZT_TRACE_VL1_LEARNED_NEW_PATH);
 	Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
 	Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
 	Dictionary::appendPacketId(buf,ZT_TRACE_FIELD_PACKET_ID,packetId);
 	Dictionary::appendPacketId(buf,ZT_TRACE_FIELD_PACKET_ID,packetId);
-	Dictionary::append(buf,ZT_TRACE_FIELD_IDENTITY_FINGERPRINT_HASH,peerIdentity.fingerprint().hash(),ZT_FINGERPRINT_HASH_SIZE);
+	Dictionary::append(buf,ZT_TRACE_FIELD_IDENTITY_FINGERPRINT_HASH,peerIdentity.fingerprint().hash,ZT_FINGERPRINT_HASH_SIZE);
 	if (physicalAddress)
 	if (physicalAddress)
 		Dictionary::appendObject(buf,ZT_TRACE_FIELD_ENDPOINT,Endpoint(physicalAddress));
 		Dictionary::appendObject(buf,ZT_TRACE_FIELD_ENDPOINT,Endpoint(physicalAddress));
 	if (replaced)
 	if (replaced)
@@ -126,7 +126,7 @@ void Trace::_incomingPacketDropped(
 	Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
 	Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
 	Dictionary::appendPacketId(buf,ZT_TRACE_FIELD_PACKET_ID,packetId);
 	Dictionary::appendPacketId(buf,ZT_TRACE_FIELD_PACKET_ID,packetId);
 	Dictionary::append(buf,ZT_TRACE_FIELD_NETWORK_ID,networkId);
 	Dictionary::append(buf,ZT_TRACE_FIELD_NETWORK_ID,networkId);
-	Dictionary::append(buf,ZT_TRACE_FIELD_IDENTITY_FINGERPRINT_HASH,peerIdentity.fingerprint().hash(),ZT_FINGERPRINT_HASH_SIZE);
+	Dictionary::append(buf,ZT_TRACE_FIELD_IDENTITY_FINGERPRINT_HASH,peerIdentity.fingerprint().hash,ZT_FINGERPRINT_HASH_SIZE);
 	if (physicalAddress)
 	if (physicalAddress)
 		Dictionary::append(buf,ZT_TRACE_FIELD_ENDPOINT,Endpoint(physicalAddress));
 		Dictionary::append(buf,ZT_TRACE_FIELD_ENDPOINT,Endpoint(physicalAddress));
 	Dictionary::append(buf,ZT_TRACE_FIELD_PACKET_HOPS,hops);
 	Dictionary::append(buf,ZT_TRACE_FIELD_PACKET_HOPS,hops);
@@ -181,7 +181,7 @@ void Trace::_incomingNetworkFrameDropped(
 	Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
 	Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
 	Dictionary::append(buf,ZT_TRACE_FIELD_SOURCE_MAC,sourceMac.toInt());
 	Dictionary::append(buf,ZT_TRACE_FIELD_SOURCE_MAC,sourceMac.toInt());
 	Dictionary::append(buf,ZT_TRACE_FIELD_DEST_MAC,destMac.toInt());
 	Dictionary::append(buf,ZT_TRACE_FIELD_DEST_MAC,destMac.toInt());
-	Dictionary::append(buf,ZT_TRACE_FIELD_IDENTITY_FINGERPRINT_HASH,peerIdentity.fingerprint().hash(),ZT_FINGERPRINT_HASH_SIZE);
+	Dictionary::append(buf,ZT_TRACE_FIELD_IDENTITY_FINGERPRINT_HASH,peerIdentity.fingerprint().hash,ZT_FINGERPRINT_HASH_SIZE);
 	if (physicalAddress)
 	if (physicalAddress)
 		Dictionary::appendObject(buf,ZT_TRACE_FIELD_ENDPOINT,Endpoint(physicalAddress));
 		Dictionary::appendObject(buf,ZT_TRACE_FIELD_ENDPOINT,Endpoint(physicalAddress));
 	Dictionary::append(buf,ZT_TRACE_FIELD_PACKET_HOPS,hops);
 	Dictionary::append(buf,ZT_TRACE_FIELD_PACKET_HOPS,hops);
@@ -268,7 +268,7 @@ void Trace::_credentialRejected(
 	Dictionary::append(buf,ZT_TRACE_FIELD_TYPE,ZT_TRACE_VL2_NETWORK_FILTER);
 	Dictionary::append(buf,ZT_TRACE_FIELD_TYPE,ZT_TRACE_VL2_NETWORK_FILTER);
 	Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
 	Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
 	Dictionary::append(buf,ZT_TRACE_FIELD_NETWORK_ID,networkId);
 	Dictionary::append(buf,ZT_TRACE_FIELD_NETWORK_ID,networkId);
-	Dictionary::append(buf,ZT_TRACE_FIELD_IDENTITY_FINGERPRINT_HASH,identity.fingerprint().hash(),ZT_FINGERPRINT_HASH_SIZE);
+	Dictionary::append(buf,ZT_TRACE_FIELD_IDENTITY_FINGERPRINT_HASH,identity.fingerprint().hash,ZT_FINGERPRINT_HASH_SIZE);
 	Dictionary::append(buf,ZT_TRACE_FIELD_CREDENTIAL_ID,credentialId);
 	Dictionary::append(buf,ZT_TRACE_FIELD_CREDENTIAL_ID,credentialId);
 	Dictionary::append(buf,ZT_TRACE_FIELD_CREDENTIAL_TIMESTAMP,credentialTimestamp);
 	Dictionary::append(buf,ZT_TRACE_FIELD_CREDENTIAL_TIMESTAMP,credentialTimestamp);
 	Dictionary::append(buf,ZT_TRACE_FIELD_CREDENTIAL_TYPE,credentialType);
 	Dictionary::append(buf,ZT_TRACE_FIELD_CREDENTIAL_TYPE,credentialType);

+ 31 - 29
osdep/OSUtils.cpp

@@ -13,6 +13,7 @@
 
 
 #include "../node/Constants.hpp"
 #include "../node/Constants.hpp"
 #include "../node/Utils.hpp"
 #include "../node/Utils.hpp"
+#include "../node/Containers.hpp"
 #include "OSUtils.hpp"
 #include "OSUtils.hpp"
 
 
 #ifdef __WINDOWS__
 #ifdef __WINDOWS__
@@ -24,6 +25,9 @@
 #include <fcntl.h>
 #include <fcntl.h>
 #endif
 #endif
 
 
+#include <algorithm>
+#include <utility>
+
 #ifdef __GCC__
 #ifdef __GCC__
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 #endif
 #endif
@@ -80,17 +84,17 @@ bool OSUtils::redirectUnixOutputs(const char *stdoutPath,const char *stderrPath)
 }
 }
 #endif // __UNIX_LIKE__
 #endif // __UNIX_LIKE__
 
 
-std::vector<std::string> OSUtils::listDirectory(const char *path,bool includeDirectories)
+Vector<String> OSUtils::listDirectory(const char *path,bool includeDirectories)
 {
 {
-	std::vector<std::string> r;
+	Vector<String> r;
 
 
 #ifdef __WINDOWS__
 #ifdef __WINDOWS__
 	HANDLE hFind;
 	HANDLE hFind;
 	WIN32_FIND_DATAA ffd;
 	WIN32_FIND_DATAA ffd;
-	if ((hFind = FindFirstFileA((std::string(path) + "\\*").c_str(),&ffd)) != INVALID_HANDLE_VALUE) {
+	if ((hFind = FindFirstFileA((String(path) + "\\*").c_str(),&ffd)) != INVALID_HANDLE_VALUE) {
 		do {
 		do {
 			if ( (strcmp(ffd.cFileName,".")) && (strcmp(ffd.cFileName,"..")) && (((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)||(((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)&&(includeDirectories))) )
 			if ( (strcmp(ffd.cFileName,".")) && (strcmp(ffd.cFileName,"..")) && (((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)||(((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)&&(includeDirectories))) )
-				r.push_back(std::string(ffd.cFileName));
+				r.push_back(String(ffd.cFileName));
 		} while (FindNextFileA(hFind,&ffd));
 		} while (FindNextFileA(hFind,&ffd));
 		FindClose(hFind);
 		FindClose(hFind);
 	}
 	}
@@ -106,7 +110,7 @@ std::vector<std::string> OSUtils::listDirectory(const char *path,bool includeDir
 			break;
 			break;
 		if (dptr) {
 		if (dptr) {
 			if ((strcmp(dptr->d_name,".") != 0)&&(strcmp(dptr->d_name,"..") != 0)&&((dptr->d_type != DT_DIR)||(includeDirectories)))
 			if ((strcmp(dptr->d_name,".") != 0)&&(strcmp(dptr->d_name,"..") != 0)&&((dptr->d_type != DT_DIR)||(includeDirectories)))
-				r.push_back(std::string(dptr->d_name));
+				r.push_back(String(dptr->d_name));
 		} else break;
 		} else break;
 	}
 	}
 	closedir(d);
 	closedir(d);
@@ -120,14 +124,14 @@ bool OSUtils::rmDashRf(const char *path)
 #ifdef __WINDOWS__
 #ifdef __WINDOWS__
 	HANDLE hFind;
 	HANDLE hFind;
 	WIN32_FIND_DATAA ffd;
 	WIN32_FIND_DATAA ffd;
-	if ((hFind = FindFirstFileA((std::string(path) + "\\*").c_str(),&ffd)) != INVALID_HANDLE_VALUE) {
+	if ((hFind = FindFirstFileA((String(path) + "\\*").c_str(),&ffd)) != INVALID_HANDLE_VALUE) {
 		do {
 		do {
 			if ((strcmp(ffd.cFileName,".") != 0)&&(strcmp(ffd.cFileName,"..") != 0)) {
 			if ((strcmp(ffd.cFileName,".") != 0)&&(strcmp(ffd.cFileName,"..") != 0)) {
 				if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
 				if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
-					if (DeleteFileA((std::string(path) + ZT_PATH_SEPARATOR_S + ffd.cFileName).c_str()) == FALSE)
+					if (DeleteFileA((String(path) + ZT_PATH_SEPARATOR_S + ffd.cFileName).c_str()) == FALSE)
 						return false;
 						return false;
 				} else {
 				} else {
-					if (!rmDashRf((std::string(path) + ZT_PATH_SEPARATOR_S + ffd.cFileName).c_str()))
+					if (!rmDashRf((String(path) + ZT_PATH_SEPARATOR_S + ffd.cFileName).c_str()))
 						return false;
 						return false;
 				}
 				}
 			}
 			}
@@ -148,7 +152,7 @@ bool OSUtils::rmDashRf(const char *path)
 		if (!dptr)
 		if (!dptr)
 			break;
 			break;
 		if ((strcmp(dptr->d_name,".") != 0)&&(strcmp(dptr->d_name,"..") != 0)&&(strlen(dptr->d_name) > 0)) {
 		if ((strcmp(dptr->d_name,".") != 0)&&(strcmp(dptr->d_name,"..") != 0)&&(strlen(dptr->d_name) > 0)) {
-			std::string p(path);
+			String p(path);
 			p.push_back(ZT_PATH_SEPARATOR);
 			p.push_back(ZT_PATH_SEPARATOR);
 			p.append(dptr->d_name);
 			p.append(dptr->d_name);
 			if (unlink(p.c_str()) != 0) { // unlink first will remove symlinks instead of recursing them
 			if (unlink(p.c_str()) != 0) { // unlink first will remove symlinks instead of recursing them
@@ -175,7 +179,7 @@ void OSUtils::lockDownFile(const char *path,bool isDir)
 		startupInfo.cb = sizeof(startupInfo);
 		startupInfo.cb = sizeof(startupInfo);
 		memset(&startupInfo,0,sizeof(STARTUPINFOA));
 		memset(&startupInfo,0,sizeof(STARTUPINFOA));
 		memset(&processInfo,0,sizeof(PROCESS_INFORMATION));
 		memset(&processInfo,0,sizeof(PROCESS_INFORMATION));
-		if (CreateProcessA(NULL,(LPSTR)(std::string("C:\\Windows\\System32\\icacls.exe \"") + path + "\" /inheritance:d /Q").c_str(),NULL,NULL,FALSE,CREATE_NO_WINDOW,NULL,NULL,&startupInfo,&processInfo)) {
+		if (CreateProcessA(NULL,(LPSTR)(String("C:\\Windows\\System32\\icacls.exe \"") + path + "\" /inheritance:d /Q").c_str(),NULL,NULL,FALSE,CREATE_NO_WINDOW,NULL,NULL,&startupInfo,&processInfo)) {
 			WaitForSingleObject(processInfo.hProcess,INFINITE);
 			WaitForSingleObject(processInfo.hProcess,INFINITE);
 			CloseHandle(processInfo.hProcess);
 			CloseHandle(processInfo.hProcess);
 			CloseHandle(processInfo.hThread);
 			CloseHandle(processInfo.hThread);
@@ -184,7 +188,7 @@ void OSUtils::lockDownFile(const char *path,bool isDir)
 		startupInfo.cb = sizeof(startupInfo);
 		startupInfo.cb = sizeof(startupInfo);
 		memset(&startupInfo,0,sizeof(STARTUPINFOA));
 		memset(&startupInfo,0,sizeof(STARTUPINFOA));
 		memset(&processInfo,0,sizeof(PROCESS_INFORMATION));
 		memset(&processInfo,0,sizeof(PROCESS_INFORMATION));
-		if (CreateProcessA(NULL,(LPSTR)(std::string("C:\\Windows\\System32\\icacls.exe \"") + path + "\" /remove *S-1-5-32-545 /Q").c_str(),NULL,NULL,FALSE,CREATE_NO_WINDOW,NULL,NULL,&startupInfo,&processInfo)) {
+		if (CreateProcessA(NULL,(LPSTR)(String("C:\\Windows\\System32\\icacls.exe \"") + path + "\" /remove *S-1-5-32-545 /Q").c_str(),NULL,NULL,FALSE,CREATE_NO_WINDOW,NULL,NULL,&startupInfo,&processInfo)) {
 			WaitForSingleObject(processInfo.hProcess,INFINITE);
 			WaitForSingleObject(processInfo.hProcess,INFINITE);
 			CloseHandle(processInfo.hProcess);
 			CloseHandle(processInfo.hProcess);
 			CloseHandle(processInfo.hThread);
 			CloseHandle(processInfo.hThread);
@@ -204,7 +208,7 @@ bool OSUtils::fileExists(const char *path,bool followLinks)
 	return (stat(path,&s) == 0);
 	return (stat(path,&s) == 0);
 }
 }
 
 
-bool OSUtils::readFile(const char *path,std::string &buf)
+bool OSUtils::readFile(const char *path,String &buf)
 {
 {
 	char tmp[16384];
 	char tmp[16384];
 	FILE *f = fopen(path,"rb");
 	FILE *f = fopen(path,"rb");
@@ -236,10 +240,10 @@ bool OSUtils::writeFile(const char *path,const void *buf,unsigned int len)
 	return false;
 	return false;
 }
 }
 
 
-std::vector<std::string> OSUtils::split(const char *s,const char *const sep,const char *esc,const char *quot)
+Vector<String> OSUtils::split(const char *s,const char *const sep,const char *esc,const char *quot)
 {
 {
-	std::vector<std::string> fields;
-	std::string buf;
+	Vector<String> fields;
+	String buf;
 
 
 	if (!esc)
 	if (!esc)
 		esc = "";
 		esc = "";
@@ -280,7 +284,7 @@ std::vector<std::string> OSUtils::split(const char *s,const char *const sep,cons
 	return fields;
 	return fields;
 }
 }
 
 
-std::string OSUtils::platformDefaultHomePath()
+ZeroTier::String OSUtils::platformDefaultHomePath()
 {
 {
 #ifdef __QNAP__
 #ifdef __QNAP__
 	char *cmd = "/sbin/getcfg zerotier Install_Path -f /etc/config/qpkg.conf";
 	char *cmd = "/sbin/getcfg zerotier Install_Path -f /etc/config/qpkg.conf";
@@ -295,7 +299,7 @@ std::string OSUtils::platformDefaultHomePath()
         printf("Command not found or exited with error status\n");
         printf("Command not found or exited with error status\n");
         return NULL;
         return NULL;
     }
     }
-    std::string homeDir = std::string(buf);
+    String homeDir = String(buf);
     homeDir.erase(std::remove(homeDir.begin(), homeDir.end(), '\n'), homeDir.end());
     homeDir.erase(std::remove(homeDir.begin(), homeDir.end(), '\n'), homeDir.end());
     return homeDir;
     return homeDir;
 #endif
 #endif
@@ -303,15 +307,13 @@ std::string OSUtils::platformDefaultHomePath()
     // Check for user-defined environment variable before using defaults
     // Check for user-defined environment variable before using defaults
 #ifdef __WINDOWS__
 #ifdef __WINDOWS__
 	DWORD bufferSize = 65535;
 	DWORD bufferSize = 65535;
-	std::string userDefinedPath;
+	ZeroTier::String userDefinedPath;
 	bufferSize = GetEnvironmentVariable("ZEROTIER_HOME", &userDefinedPath[0], bufferSize);
 	bufferSize = GetEnvironmentVariable("ZEROTIER_HOME", &userDefinedPath[0], bufferSize);
-	if (bufferSize) {
+	if (bufferSize)
 		return userDefinedPath;
 		return userDefinedPath;
-	}
 #else
 #else
-	if(const char* userDefinedPath = getenv("ZEROTIER_HOME")) {
-		return std::string(userDefinedPath);
-	}
+	if(const char* userDefinedPath = getenv("ZEROTIER_HOME"))
+		return String(userDefinedPath);
 #endif
 #endif
 
 
 	// Finally, resort to using default paths if no user-defined path was provided
 	// Finally, resort to using default paths if no user-defined path was provided
@@ -319,15 +321,15 @@ std::string OSUtils::platformDefaultHomePath()
 
 
 #ifdef __APPLE__
 #ifdef __APPLE__
 	// /Library/... on Apple
 	// /Library/... on Apple
-	return std::string("/Library/Application Support/ZeroTier");
+	return ZeroTier::String("/Library/Application Support/ZeroTier");
 #else
 #else
 
 
 #ifdef __BSD__
 #ifdef __BSD__
 	// BSD likes /var/db instead of /var/lib
 	// BSD likes /var/db instead of /var/lib
-	return std::string("/var/db/zerotier");
+	return ZeroTier::String("/var/db/zerotier");
 #else
 #else
 	// Use /var/lib for Linux and other *nix
 	// Use /var/lib for Linux and other *nix
-	return std::string("/var/lib/zerotier");
+	return ZeroTier::String("/var/lib/zerotier");
 #endif
 #endif
 
 
 #endif
 #endif
@@ -338,11 +340,11 @@ std::string OSUtils::platformDefaultHomePath()
 	// Look up app data folder on Windows, e.g. C:\ProgramData\...
 	// Look up app data folder on Windows, e.g. C:\ProgramData\...
 	char buf[16384];
 	char buf[16384];
 	if (SUCCEEDED(SHGetFolderPathA(NULL,CSIDL_COMMON_APPDATA,NULL,0,buf)))
 	if (SUCCEEDED(SHGetFolderPathA(NULL,CSIDL_COMMON_APPDATA,NULL,0,buf)))
-		return (std::string(buf) + "\\ZeroTier");
-	else return std::string("C:\\ZeroTier");
+		return (ZeroTier::String(buf) + "\\ZeroTier");
+	else return ZeroTier::String("C:\\ZeroTier");
 #else
 #else
 
 
-	return (std::string(ZT_PATH_SEPARATOR_S) + "ZeroTier"); // UNKNOWN PLATFORM
+	return (ZeroTier::String(ZT_PATH_SEPARATOR_S) + "ZeroTier"); // UNKNOWN PLATFORM
 
 
 #endif
 #endif
 
 

+ 8 - 16
osdep/OSUtils.hpp

@@ -15,16 +15,10 @@
 #define ZT_OSUTILS_HPP
 #define ZT_OSUTILS_HPP
 
 
 #include "../node/Constants.hpp"
 #include "../node/Constants.hpp"
+#include "../node/Containers.hpp"
 
 
-#include <cstdio>
-#include <cstdlib>
-#include <cstdint>
-#include <cstring>
-#include <cstdarg>
-#include <ctime>
-#include <stdexcept>
-#include <vector>
-#include <map>
+#include <stdarg.h>
+#include <time.h>
 
 
 #ifndef __WINDOWS__
 #ifndef __WINDOWS__
 #include <sys/time.h> // NOLINT(modernize-deprecated-headers)
 #include <sys/time.h> // NOLINT(modernize-deprecated-headers)
@@ -97,7 +91,6 @@ public:
 		return (unlink(path) == 0);
 		return (unlink(path) == 0);
 #endif
 #endif
 	}
 	}
-	static ZT_INLINE bool rm(const std::string &path) { return rm(path.c_str()); }
 
 
 	static ZT_INLINE bool mkdir(const char *path)
 	static ZT_INLINE bool mkdir(const char *path)
 	{
 	{
@@ -111,7 +104,6 @@ public:
 		return true;
 		return true;
 #endif
 #endif
 	}
 	}
-	static ZT_INLINE bool mkdir(const std::string &path) { return OSUtils::mkdir(path.c_str()); }
 
 
 	static ZT_INLINE bool rename(const char *o,const char *n)
 	static ZT_INLINE bool rename(const char *o,const char *n)
 	{
 	{
@@ -130,7 +122,7 @@ public:
 	 * @param includeDirectories If true, include directories as well as files
 	 * @param includeDirectories If true, include directories as well as files
 	 * @return Names of files in directory (without path prepended)
 	 * @return Names of files in directory (without path prepended)
 	 */
 	 */
-	static std::vector<std::string> listDirectory(const char *path,bool includeDirectories = false);
+	static ZeroTier::Vector<ZeroTier::String> listDirectory(const char *path,bool includeDirectories = false);
 
 
 	/**
 	/**
 	 * Delete a directory and all its files and subdirectories recursively
 	 * Delete a directory and all its files and subdirectories recursively
@@ -205,7 +197,7 @@ public:
 	 * @param buf Buffer to fill
 	 * @param buf Buffer to fill
 	 * @return True if open and read successful
 	 * @return True if open and read successful
 	 */
 	 */
-	static bool readFile(const char *path,std::string &buf);
+	static bool readFile(const char *path,ZeroTier::String &buf);
 
 
 	/**
 	/**
 	 * Write a block of data to disk, replacing any current file contents
 	 * Write a block of data to disk, replacing any current file contents
@@ -226,7 +218,7 @@ public:
 	 * @param quot Zero or more quote characters
 	 * @param quot Zero or more quote characters
 	 * @return Vector of tokens
 	 * @return Vector of tokens
 	 */
 	 */
-	static std::vector<std::string> split(const char *s,const char *sep,const char *esc,const char *quot);
+	static ZeroTier::Vector<ZeroTier::String> split(const char *s,const char *sep,const char *esc,const char *quot);
 
 
 	/**
 	/**
 	 * Write a block of data to disk, replacing any current file contents
 	 * Write a block of data to disk, replacing any current file contents
@@ -235,12 +227,12 @@ public:
 	 * @param s Data to write
 	 * @param s Data to write
 	 * @return True if entire file was successfully written
 	 * @return True if entire file was successfully written
 	 */
 	 */
-	static ZT_INLINE bool writeFile(const char *path,const std::string &s) { return writeFile(path,s.data(),(unsigned int)s.length()); }
+	static ZT_INLINE bool writeFile(const char *path,const ZeroTier::String &s) { return writeFile(path,s.data(),(unsigned int)s.length()); }
 
 
 	/**
 	/**
 	 * @return Platform default ZeroTier One home path
 	 * @return Platform default ZeroTier One home path
 	 */
 	 */
-	static std::string platformDefaultHomePath();
+	static ZeroTier::String platformDefaultHomePath();
 
 
 #ifndef OMIT_JSON_SUPPORT
 #ifndef OMIT_JSON_SUPPORT
 	static nlohmann::json jsonParse(const std::string &buf);
 	static nlohmann::json jsonParse(const std::string &buf);