A bunch of build fixes.

This commit is contained in:
Adam Ierymenko 2020-05-29 07:06:00 -07:00
parent b9bf6d1242
commit 864e33cf2d
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
14 changed files with 102 additions and 110 deletions

View file

@ -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);

View file

@ -67,19 +67,18 @@ const (
) )
var ( var (
// PlatformDefaultHomePath is the default location of ZeroTier's working path on this system PlatformDefaultHomePath string
PlatformDefaultHomePath string = C.GoString(C.ZT_PLATFORM_DEFAULT_HOMEPATH)
cNodeRefs [maxCNodeRefs]*Node
cNodeRefUsed [maxCNodeRefs]uint32
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)

View file

@ -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; }

View file

@ -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;
} }

View file

@ -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); Address(signer.fingerprint().address).copyTo(fp);
Utils::copy<ZT_FINGERPRINT_HASH_SIZE>(fp + ZT_ADDRESS_LENGTH, signer.fingerprint().hash()); 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(); fp.address = Address(sigfp->second.data());
Utils::copy<ZT_FINGERPRINT_HASH_SIZE>(fp.apiFingerprint()->hash, sigfp->second.data() + ZT_ADDRESS_LENGTH); 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));

View file

@ -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;
} }
} }

View file

@ -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)

View file

@ -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 :

View file

@ -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)

View file

@ -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];

View file

@ -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 (likely(m_ptr != nullptr)) {
if (--m_ptr->__refCount <= 0) 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 (likely(m_ptr != nullptr)) {
if (--m_ptr->__refCount <= 0) 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 (likely(m_ptr != nullptr)) {
if (--m_ptr->__refCount <= 0) 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 (likely(m_ptr != nullptr)) {
if (--m_ptr->__refCount <= 0) 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;

View file

@ -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);

View file

@ -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; Vector<String> fields;
std::string buf; 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")) { if(const char* userDefinedPath = getenv("ZEROTIER_HOME"))
return std::string(userDefinedPath); 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"); return (ZeroTier::String(buf) + "\\ZeroTier");
else return std::string("C:\\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

View file

@ -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 <stdarg.h>
#include <cstdlib> #include <time.h>
#include <cstdint>
#include <cstring>
#include <cstdarg>
#include <ctime>
#include <stdexcept>
#include <vector>
#include <map>
#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);