mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2024-12-19 13:07:55 +00:00
More work in progress
This commit is contained in:
parent
573d3eea87
commit
8f5f7f1baa
@ -239,7 +239,7 @@ public:
|
||||
class CapabilityIterator
|
||||
{
|
||||
public:
|
||||
CapabilityIterator(Membership &m,const NetworkConfig &nconf) :
|
||||
inline CapabilityIterator(Membership &m,const NetworkConfig &nconf) :
|
||||
_hti(m._remoteCaps),
|
||||
_k((uint32_t *)0),
|
||||
_c((Capability *)0),
|
||||
|
@ -161,8 +161,8 @@ public:
|
||||
private:
|
||||
struct Key
|
||||
{
|
||||
Key() : nwid(0),mg() {}
|
||||
Key(uint64_t n,const MulticastGroup &g) : nwid(n),mg(g) {}
|
||||
inline Key() : nwid(0),mg() {}
|
||||
inline Key(uint64_t n,const MulticastGroup &g) : nwid(n),mg(g) {}
|
||||
|
||||
uint64_t nwid;
|
||||
MulticastGroup mg;
|
||||
@ -174,8 +174,8 @@ private:
|
||||
|
||||
struct MulticastGroupMember
|
||||
{
|
||||
MulticastGroupMember() {}
|
||||
MulticastGroupMember(const Address &a,uint64_t ts) : address(a),timestamp(ts) {}
|
||||
inline MulticastGroupMember() {}
|
||||
inline MulticastGroupMember(const Address &a,uint64_t ts) : address(a),timestamp(ts) {}
|
||||
|
||||
inline bool operator<(const MulticastGroupMember &a) const { return (address < a.address); }
|
||||
inline bool operator==(const MulticastGroupMember &a) const { return (address == a.address); }
|
||||
@ -190,7 +190,7 @@ private:
|
||||
|
||||
struct MulticastGroupStatus
|
||||
{
|
||||
MulticastGroupStatus() : lastExplicitGather(0) {}
|
||||
inline MulticastGroupStatus() : lastExplicitGather(0) {}
|
||||
|
||||
uint64_t lastExplicitGather;
|
||||
std::list<OutboundMulticast> txQueue; // pending outbound multicasts
|
||||
|
@ -194,7 +194,7 @@ ZT_ResultCode Node::processVirtualNetworkFrame(
|
||||
// those that need pinging.
|
||||
struct _PingPeersThatNeedPing
|
||||
{
|
||||
_PingPeersThatNeedPing(const RuntimeEnvironment *renv,void *tPtr,Hashtable< Address,std::vector<InetAddress> > &alwaysContact,int64_t now) :
|
||||
inline _PingPeersThatNeedPing(const RuntimeEnvironment *renv,void *tPtr,Hashtable< Address,std::vector<InetAddress> > &alwaysContact,int64_t now) :
|
||||
RR(renv),
|
||||
_tPtr(tPtr),
|
||||
_alwaysContact(alwaysContact),
|
||||
@ -284,7 +284,7 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64
|
||||
|
||||
// (1) Get peers we should remain connected to and (2) get networks that need config.
|
||||
Hashtable< Address,std::vector<InetAddress> > alwaysContact;
|
||||
RR->topology->getUpstreamsToContact(alwaysContact);
|
||||
RR->topology->getAlwaysContact(alwaysContact);
|
||||
std::vector< std::pair< SharedPtr<Network>,bool > > networkConfigNeeded;
|
||||
{
|
||||
Mutex::Lock l(_networks_m);
|
||||
|
@ -58,7 +58,7 @@ class Revocation : public Credential
|
||||
public:
|
||||
static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_REVOCATION; }
|
||||
|
||||
Revocation() :
|
||||
inline Revocation() :
|
||||
_id(0),
|
||||
_credentialId(0),
|
||||
_networkId(0),
|
||||
@ -80,7 +80,7 @@ public:
|
||||
* @param tgt Target node whose credential(s) are being revoked
|
||||
* @param ct Credential type being revoked
|
||||
*/
|
||||
Revocation(const uint32_t i,const uint64_t nwid,const uint32_t cid,const uint64_t thr,const uint64_t fl,const Address &tgt,const Credential::Type ct) :
|
||||
inline Revocation(const uint32_t i,const uint64_t nwid,const uint32_t cid,const uint64_t thr,const uint64_t fl,const Address &tgt,const Credential::Type ct) :
|
||||
_id(i),
|
||||
_credentialId(cid),
|
||||
_networkId(nwid),
|
||||
|
34
node/Str.hpp
34
node/Str.hpp
@ -37,16 +37,22 @@
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
* A short non-allocating replacement for std::string
|
||||
*/
|
||||
class Str
|
||||
{
|
||||
public:
|
||||
Str() { _l = 0; _s[0] = 0; }
|
||||
Str(const Str &s)
|
||||
typedef char * iterator;
|
||||
typedef const char * const_iterator;
|
||||
|
||||
inline Str() { _l = 0; _s[0] = 0; }
|
||||
inline Str(const Str &s)
|
||||
{
|
||||
_l = s._l;
|
||||
memcpy(_s,s._s,_l+1);
|
||||
}
|
||||
Str(const char *s)
|
||||
inline Str(const char *s)
|
||||
{
|
||||
_l = 0;
|
||||
_s[0] = 0;
|
||||
@ -75,7 +81,11 @@ public:
|
||||
|
||||
inline void clear() { _l = 0; _s[0] = 0; }
|
||||
inline const char *c_str() const { return _s; }
|
||||
inline unsigned int length() const { return _l; }
|
||||
inline unsigned int length() const { return (unsigned int)_l; }
|
||||
inline iterator begin() { return (iterator)_s; }
|
||||
inline iterator end() { return (iterator)(_s + (unsigned long)_l); }
|
||||
inline const_iterator begin() const { return (const_iterator)_s; }
|
||||
inline const_iterator end() const { return (const_iterator)(_s + (unsigned long)_l); }
|
||||
|
||||
inline Str &operator<<(const char *s)
|
||||
{
|
||||
@ -83,8 +93,8 @@ public:
|
||||
unsigned long l = _l;
|
||||
while (*s) {
|
||||
if (unlikely(l >= ZT_STR_CAPACITY)) {
|
||||
_s[l] = 0;
|
||||
_l = (uint8_t)l;
|
||||
_s[ZT_STR_CAPACITY] = 0;
|
||||
_l = ZT_STR_CAPACITY;
|
||||
throw ZT_EXCEPTION_OUT_OF_BOUNDS;
|
||||
}
|
||||
_s[l++] = *s;
|
||||
@ -97,14 +107,12 @@ public:
|
||||
inline Str &operator<<(const Str &s) { return ((*this) << s._s); }
|
||||
inline Str &operator<<(const char c)
|
||||
{
|
||||
if (likely(c != 0)) {
|
||||
if (unlikely(_l >= ZT_STR_CAPACITY)) {
|
||||
_s[_l] = 0;
|
||||
throw ZT_EXCEPTION_OUT_OF_BOUNDS;
|
||||
}
|
||||
_s[_l++] = c;
|
||||
_s[_l] = 0;
|
||||
if (unlikely(_l >= ZT_STR_CAPACITY)) {
|
||||
_s[ZT_STR_CAPACITY] = 0;
|
||||
throw ZT_EXCEPTION_OUT_OF_BOUNDS;
|
||||
}
|
||||
_s[(unsigned long)(_l++)] = c;
|
||||
_s[(unsigned long)_l] = 0;
|
||||
}
|
||||
inline Str &operator<<(const unsigned long n)
|
||||
{
|
||||
|
@ -95,13 +95,9 @@ public:
|
||||
{
|
||||
if (zta == RR->identity.address())
|
||||
return SharedPtr<Peer>();
|
||||
{
|
||||
Mutex::Lock _l(_peers_m);
|
||||
const SharedPtr<Peer> *const ap = _peers.get(zta);
|
||||
if (ap)
|
||||
return *ap;
|
||||
}
|
||||
return SharedPtr<Peer>();
|
||||
Mutex::Lock _l(_peers_m);
|
||||
const SharedPtr<Peer> *const ap = _peers.get(zta);
|
||||
return ((ap) ? *ap : SharedPtr<Peer>());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,7 +117,7 @@ public:
|
||||
}
|
||||
return Identity();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a peer only if it is presently in memory (no disk cache)
|
||||
*
|
||||
@ -157,38 +153,29 @@ public:
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current best upstream peer
|
||||
*
|
||||
* @return Upstream or NULL if none available
|
||||
*/
|
||||
inline SharedPtr<Peer> getUpstreamPeer() const
|
||||
{
|
||||
// TODO
|
||||
return SharedPtr<Peer>();
|
||||
}
|
||||
|
||||
inline bool isUpstream(const Identity &id) const
|
||||
{
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
inline ZT_PeerRole role(const Address &ztaddr) const
|
||||
{
|
||||
// TODO
|
||||
return ZT_PEER_ROLE_LEAF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets upstreams to contact and their stable endpoints (if known)
|
||||
*
|
||||
* @param eps Hash table to fill with addresses and their stable endpoints
|
||||
*/
|
||||
inline void getUpstreamsToContact(Hashtable< Address,std::vector<InetAddress> > &eps) const
|
||||
inline void getAlwaysContact(Hashtable< Address,std::vector<InetAddress> > &eps) const
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Vector of active upstream addresses (including roots)
|
||||
*/
|
||||
inline std::vector<Address> upstreamAddresses() const
|
||||
{
|
||||
// TODO
|
||||
|
164
node/Utils.cpp
164
node/Utils.cpp
@ -85,6 +85,71 @@ char *Utils::decimal(unsigned long n,char s[24])
|
||||
return s;
|
||||
}
|
||||
|
||||
unsigned int Utils::unhex(const char *h,void *buf,unsigned int buflen)
|
||||
{
|
||||
unsigned int l = 0;
|
||||
while (l < buflen) {
|
||||
uint8_t hc = *(reinterpret_cast<const uint8_t *>(h++));
|
||||
if (!hc) break;
|
||||
|
||||
uint8_t c = 0;
|
||||
if ((hc >= 48)&&(hc <= 57)) // 0..9
|
||||
c = hc - 48;
|
||||
else if ((hc >= 97)&&(hc <= 102)) // a..f
|
||||
c = hc - 87;
|
||||
else if ((hc >= 65)&&(hc <= 70)) // A..F
|
||||
c = hc - 55;
|
||||
|
||||
hc = *(reinterpret_cast<const uint8_t *>(h++));
|
||||
if (!hc) break;
|
||||
|
||||
c <<= 4;
|
||||
if ((hc >= 48)&&(hc <= 57))
|
||||
c |= hc - 48;
|
||||
else if ((hc >= 97)&&(hc <= 102))
|
||||
c |= hc - 87;
|
||||
else if ((hc >= 65)&&(hc <= 70))
|
||||
c |= hc - 55;
|
||||
|
||||
reinterpret_cast<uint8_t *>(buf)[l++] = c;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
unsigned int Utils::unhex(const char *h,unsigned int hlen,void *buf,unsigned int buflen)
|
||||
{
|
||||
unsigned int l = 0;
|
||||
const char *hend = h + hlen;
|
||||
while (l < buflen) {
|
||||
if (h == hend) break;
|
||||
uint8_t hc = *(reinterpret_cast<const uint8_t *>(h++));
|
||||
if (!hc) break;
|
||||
|
||||
uint8_t c = 0;
|
||||
if ((hc >= 48)&&(hc <= 57))
|
||||
c = hc - 48;
|
||||
else if ((hc >= 97)&&(hc <= 102))
|
||||
c = hc - 87;
|
||||
else if ((hc >= 65)&&(hc <= 70))
|
||||
c = hc - 55;
|
||||
|
||||
if (h == hend) break;
|
||||
hc = *(reinterpret_cast<const uint8_t *>(h++));
|
||||
if (!hc) break;
|
||||
|
||||
c <<= 4;
|
||||
if ((hc >= 48)&&(hc <= 57))
|
||||
c |= hc - 48;
|
||||
else if ((hc >= 97)&&(hc <= 102))
|
||||
c |= hc - 87;
|
||||
else if ((hc >= 65)&&(hc <= 70))
|
||||
c |= hc - 55;
|
||||
|
||||
reinterpret_cast<uint8_t *>(buf)[l++] = c;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
void Utils::getSecureRandom(void *buf,unsigned int bytes)
|
||||
{
|
||||
static Mutex globalLock;
|
||||
@ -105,8 +170,12 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
|
||||
if (!s20Initialized) {
|
||||
s20Initialized = true;
|
||||
uint64_t s20Key[4];
|
||||
s20Key[0] = (uint64_t)time(0); // system clock
|
||||
s20Key[0] = (uint64_t)time(nullptr);
|
||||
#ifdef __WINDOWS__
|
||||
s20Key[1] = (uint64_t)buf; // address of buf
|
||||
#else
|
||||
s20Key[1] = (uint64_t)getpid();
|
||||
#endif
|
||||
s20Key[2] = (uint64_t)s20Key; // address of s20Key[]
|
||||
s20Key[3] = (uint64_t)&s20; // address of s20
|
||||
s20.init(s20Key,s20Key);
|
||||
@ -171,6 +240,42 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
|
||||
#endif // __WINDOWS__ or not
|
||||
}
|
||||
|
||||
int Utils::b32e(const uint8_t *data,int length,char *result,int bufSize)
|
||||
{
|
||||
if (length < 0 || length > (1 << 28)) {
|
||||
result[0] = (char)0;
|
||||
return -1;
|
||||
}
|
||||
int count = 0;
|
||||
if (length > 0) {
|
||||
int buffer = data[0];
|
||||
int next = 1;
|
||||
int bitsLeft = 8;
|
||||
while (count < bufSize && (bitsLeft > 0 || next < length)) {
|
||||
if (bitsLeft < 5) {
|
||||
if (next < length) {
|
||||
buffer <<= 8;
|
||||
buffer |= data[next++] & 0xFF;
|
||||
bitsLeft += 8;
|
||||
} else {
|
||||
int pad = 5 - bitsLeft;
|
||||
buffer <<= pad;
|
||||
bitsLeft += pad;
|
||||
}
|
||||
}
|
||||
int index = 0x1F & (buffer >> (bitsLeft - 5));
|
||||
bitsLeft -= 5;
|
||||
result[count++] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"[index];
|
||||
}
|
||||
}
|
||||
if (count < bufSize) {
|
||||
result[count] = (char)0;
|
||||
return count;
|
||||
}
|
||||
result[0] = (char)0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Utils::b32d(const char *encoded,uint8_t *result,int bufSize)
|
||||
{
|
||||
int buffer = 0;
|
||||
@ -211,42 +316,6 @@ int Utils::b32d(const char *encoded,uint8_t *result,int bufSize)
|
||||
return count;
|
||||
}
|
||||
|
||||
int Utils::b32e(const uint8_t *data,int length,char *result,int bufSize)
|
||||
{
|
||||
if (length < 0 || length > (1 << 28)) {
|
||||
result[0] = (char)0;
|
||||
return -1;
|
||||
}
|
||||
int count = 0;
|
||||
if (length > 0) {
|
||||
int buffer = data[0];
|
||||
int next = 1;
|
||||
int bitsLeft = 8;
|
||||
while (count < bufSize && (bitsLeft > 0 || next < length)) {
|
||||
if (bitsLeft < 5) {
|
||||
if (next < length) {
|
||||
buffer <<= 8;
|
||||
buffer |= data[next++] & 0xFF;
|
||||
bitsLeft += 8;
|
||||
} else {
|
||||
int pad = 5 - bitsLeft;
|
||||
buffer <<= pad;
|
||||
bitsLeft += pad;
|
||||
}
|
||||
}
|
||||
int index = 0x1F & (buffer >> (bitsLeft - 5));
|
||||
bitsLeft -= 5;
|
||||
result[count++] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"[index];
|
||||
}
|
||||
}
|
||||
if (count < bufSize) {
|
||||
result[count] = (char)0;
|
||||
return count;
|
||||
}
|
||||
result[0] = (char)0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int Utils::b64e(const uint8_t *in,unsigned int inlen,char *out,unsigned int outlen)
|
||||
{
|
||||
static const char base64en[64] = { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' };
|
||||
@ -326,4 +395,25 @@ unsigned int Utils::b64d(const char *in,unsigned char *out,unsigned int outlen)
|
||||
return j;
|
||||
}
|
||||
|
||||
#define ROL64(x,k) (((x) << (k)) | ((x) >> (64 - (k))))
|
||||
uint64_t Utils::random()
|
||||
{
|
||||
// https://en.wikipedia.org/wiki/Xorshift#xoshiro256**
|
||||
static Mutex l;
|
||||
static uint64_t s[4] = { Utils::getSecureRandom64(),Utils::getSecureRandom64(),Utils::getSecureRandom64(),Utils::getSecureRandom64() };
|
||||
|
||||
l.lock();
|
||||
const uint64_t result = ROL64(s[1] * 5,7) * 9;
|
||||
const uint64_t t = s[1] << 17;
|
||||
s[2] ^= s[0];
|
||||
s[3] ^= s[1];
|
||||
s[1] ^= s[2];
|
||||
s[0] ^= s[3];
|
||||
s[2] ^= t;
|
||||
s[3] = ROL64(s[3],45);
|
||||
l.unlock();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
145
node/Utils.hpp
145
node/Utils.hpp
@ -48,6 +48,11 @@ namespace ZeroTier {
|
||||
class Utils
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Hexadecimal characters 0-f
|
||||
*/
|
||||
static const char HEXCHARS[16];
|
||||
|
||||
/**
|
||||
* Perform a time-invariant binary comparison
|
||||
*
|
||||
@ -65,7 +70,7 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Securely zero memory, avoiding compiler optimizations and such
|
||||
* Zero memory, ensuring to avoid any compiler optimizations or other things that may stop this.
|
||||
*/
|
||||
static void burn(void *ptr,unsigned int len);
|
||||
|
||||
@ -158,78 +163,8 @@ public:
|
||||
return save;
|
||||
}
|
||||
|
||||
static inline unsigned int unhex(const char *h,void *buf,unsigned int buflen)
|
||||
{
|
||||
unsigned int l = 0;
|
||||
while (l < buflen) {
|
||||
uint8_t hc = *(reinterpret_cast<const uint8_t *>(h++));
|
||||
if (!hc) break;
|
||||
|
||||
uint8_t c = 0;
|
||||
if ((hc >= 48)&&(hc <= 57)) // 0..9
|
||||
c = hc - 48;
|
||||
else if ((hc >= 97)&&(hc <= 102)) // a..f
|
||||
c = hc - 87;
|
||||
else if ((hc >= 65)&&(hc <= 70)) // A..F
|
||||
c = hc - 55;
|
||||
|
||||
hc = *(reinterpret_cast<const uint8_t *>(h++));
|
||||
if (!hc) break;
|
||||
|
||||
c <<= 4;
|
||||
if ((hc >= 48)&&(hc <= 57))
|
||||
c |= hc - 48;
|
||||
else if ((hc >= 97)&&(hc <= 102))
|
||||
c |= hc - 87;
|
||||
else if ((hc >= 65)&&(hc <= 70))
|
||||
c |= hc - 55;
|
||||
|
||||
reinterpret_cast<uint8_t *>(buf)[l++] = c;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
static inline unsigned int unhex(const char *h,unsigned int hlen,void *buf,unsigned int buflen)
|
||||
{
|
||||
unsigned int l = 0;
|
||||
const char *hend = h + hlen;
|
||||
while (l < buflen) {
|
||||
if (h == hend) break;
|
||||
uint8_t hc = *(reinterpret_cast<const uint8_t *>(h++));
|
||||
if (!hc) break;
|
||||
|
||||
uint8_t c = 0;
|
||||
if ((hc >= 48)&&(hc <= 57))
|
||||
c = hc - 48;
|
||||
else if ((hc >= 97)&&(hc <= 102))
|
||||
c = hc - 87;
|
||||
else if ((hc >= 65)&&(hc <= 70))
|
||||
c = hc - 55;
|
||||
|
||||
if (h == hend) break;
|
||||
hc = *(reinterpret_cast<const uint8_t *>(h++));
|
||||
if (!hc) break;
|
||||
|
||||
c <<= 4;
|
||||
if ((hc >= 48)&&(hc <= 57))
|
||||
c |= hc - 48;
|
||||
else if ((hc >= 97)&&(hc <= 102))
|
||||
c |= hc - 87;
|
||||
else if ((hc >= 65)&&(hc <= 70))
|
||||
c |= hc - 55;
|
||||
|
||||
reinterpret_cast<uint8_t *>(buf)[l++] = c;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
static inline float normalize(float value, int64_t bigMin, int64_t bigMax, int32_t targetMin, int32_t targetMax)
|
||||
{
|
||||
int64_t bigSpan = bigMax - bigMin;
|
||||
int64_t smallSpan = targetMax - targetMin;
|
||||
float valueScaled = (value - (float)bigMin) / (float)bigSpan;
|
||||
return (float)targetMin + valueScaled * (float)smallSpan;
|
||||
}
|
||||
static unsigned int unhex(const char *h,void *buf,unsigned int buflen);
|
||||
static unsigned int unhex(const char *h,unsigned int hlen,void *buf,unsigned int buflen);
|
||||
|
||||
/**
|
||||
* Generate secure random bytes
|
||||
@ -242,13 +177,36 @@ public:
|
||||
*/
|
||||
static void getSecureRandom(void *buf,unsigned int bytes);
|
||||
|
||||
static int b32d(const char *encoded, uint8_t *result, int bufSize);
|
||||
/**
|
||||
* Get a 64-bit unsigned secure random number
|
||||
*/
|
||||
static inline uint64_t getSecureRandom64()
|
||||
{
|
||||
uint64_t x;
|
||||
getSecureRandom(&x,sizeof(x));
|
||||
return x;
|
||||
}
|
||||
|
||||
static int b32e(const uint8_t *data,int length,char *result,int bufSize);
|
||||
static int b32d(const char *encoded, uint8_t *result, int bufSize);
|
||||
|
||||
static inline unsigned int b64MaxEncodedSize(const unsigned int s) { return ((((s + 2) / 3) * 4) + 1); }
|
||||
static unsigned int b64e(const uint8_t *in,unsigned int inlen,char *out,unsigned int outlen);
|
||||
static unsigned int b64d(const char *in,uint8_t *out,unsigned int outlen);
|
||||
|
||||
/**
|
||||
* Get a non-cryptographic random integer
|
||||
*/
|
||||
static uint64_t random();
|
||||
|
||||
static inline float normalize(float value, int64_t bigMin, int64_t bigMax, int32_t targetMin, int32_t targetMax)
|
||||
{
|
||||
int64_t bigSpan = bigMax - bigMin;
|
||||
int64_t smallSpan = targetMax - targetMin;
|
||||
float valueScaled = (value - (float)bigMin) / (float)bigSpan;
|
||||
return (float)targetMin + valueScaled * (float)smallSpan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tokenize a string (alias for strtok_r or strtok_s depending on platform)
|
||||
*
|
||||
@ -350,23 +308,8 @@ public:
|
||||
return (T)(v * ((~((T)0))/((T)255))) >> ((sizeof(T) - 1) * 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a memory buffer is all-zero
|
||||
*
|
||||
* @param p Memory to scan
|
||||
* @param len Length of memory
|
||||
* @return True if memory is all zero
|
||||
*/
|
||||
static inline bool isZero(const void *p,unsigned int len)
|
||||
{
|
||||
for(unsigned int i=0;i<len;++i) {
|
||||
if (((const unsigned char *)p)[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Byte swappers for big/little endian conversion
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
static inline uint8_t hton(uint8_t n) { return n; }
|
||||
static inline int8_t hton(int8_t n) { return n; }
|
||||
static inline uint16_t hton(uint16_t n) { return htons(n); }
|
||||
@ -375,7 +318,6 @@ public:
|
||||
static inline int32_t hton(int32_t n) { return (int32_t)htonl((uint32_t)n); }
|
||||
static inline uint64_t hton(uint64_t n)
|
||||
{
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#if defined(__GNUC__)
|
||||
#if defined(__FreeBSD__)
|
||||
return bswap64(n);
|
||||
@ -393,13 +335,15 @@ public:
|
||||
((n & 0x00FF000000000000ULL) >> 40) |
|
||||
((n & 0xFF00000000000000ULL) >> 56)
|
||||
);
|
||||
#endif
|
||||
#else
|
||||
return n;
|
||||
#endif
|
||||
}
|
||||
static inline int64_t hton(int64_t n) { return (int64_t)hton((uint64_t)n); }
|
||||
#else
|
||||
template<typename T>
|
||||
static inline T hton(T n) { return n; }
|
||||
#endif
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
static inline uint8_t ntoh(uint8_t n) { return n; }
|
||||
static inline int8_t ntoh(int8_t n) { return n; }
|
||||
static inline uint16_t ntoh(uint16_t n) { return ntohs(n); }
|
||||
@ -408,7 +352,6 @@ public:
|
||||
static inline int32_t ntoh(int32_t n) { return (int32_t)ntohl((uint32_t)n); }
|
||||
static inline uint64_t ntoh(uint64_t n)
|
||||
{
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#if defined(__GNUC__)
|
||||
#if defined(__FreeBSD__)
|
||||
return bswap64(n);
|
||||
@ -426,17 +369,13 @@ public:
|
||||
((n & 0x00FF000000000000ULL) >> 40) |
|
||||
((n & 0xFF00000000000000ULL) >> 56)
|
||||
);
|
||||
#endif
|
||||
#else
|
||||
return n;
|
||||
#endif
|
||||
}
|
||||
static inline int64_t ntoh(int64_t n) { return (int64_t)ntoh((uint64_t)n); }
|
||||
|
||||
/**
|
||||
* Hexadecimal characters 0-f
|
||||
*/
|
||||
static const char HEXCHARS[16];
|
||||
#else
|
||||
template<typename T>
|
||||
static inline T ntoh(T n) { return n; }
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
Loading…
Reference in New Issue
Block a user