This commit is contained in:
Adam Ierymenko 2020-01-02 19:04:36 -05:00
parent 3b94ef99ae
commit c1b2c7903c
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
10 changed files with 373 additions and 412 deletions

View file

@ -14,11 +14,8 @@
#ifndef ZT_CONSTANTS_HPP
#define ZT_CONSTANTS_HPP
/****************************************************************************/
/* Core includes and OS/platform setup stuff */
/****************************************************************************/
#include "../include/ZeroTierCore.h"
#include "OS.hpp"
#if __has_include("version.h")
#include "version.h"
@ -29,165 +26,6 @@
#define ZEROTIER_ONE_VERSION_BUILD 255
#endif
//
// This include file also auto-detects and canonicalizes some environment
// information defines:
//
// __LINUX__
// __APPLE__
// __BSD__ (OSX also defines this)
// __UNIX_LIKE__ (Linux, BSD, etc.)
// __WINDOWS__
//
// Also makes sure __BYTE_ORDER is defined reasonably.
//
// Hack: make sure __GCC__ is defined on old GCC compilers
#ifndef __GCC__
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
#define __GCC__
#endif
#endif
#if defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux)
#ifndef __LINUX__
#define __LINUX__
#endif
#ifndef __UNIX_LIKE__
#define __UNIX_LIKE__
#endif
#include <endian.h>
#endif
#ifdef __APPLE__
#include <TargetConditionals.h>
#ifndef __UNIX_LIKE__
#define __UNIX_LIKE__
#endif
#ifndef __BSD__
#define __BSD__
#endif
#include <machine/endian.h>
#endif
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
#ifndef __UNIX_LIKE__
#define __UNIX_LIKE__
#endif
#ifndef __BSD__
#define __BSD__
#endif
#include <sys/endian.h>
#ifndef __BYTE_ORDER
#define __BYTE_ORDER _BYTE_ORDER
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
#endif
#endif
#if defined(_WIN32) || defined(_WIN64)
#ifndef __WINDOWS__
#define __WINDOWS__
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#pragma warning(disable : 4290)
#pragma warning(disable : 4996)
#pragma warning(disable : 4101)
#undef __UNIX_LIKE__
#undef __BSD__
#include <WinSock2.h>
#include <Windows.h>
#endif
#ifdef __NetBSD__
#ifndef RTF_MULTICAST
#define RTF_MULTICAST 0x20000000
#endif
#endif
// Define ZT_NO_TYPE_PUNNING to disable reckless casts on anything other than x86 and x86_64.
#if (!(defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(__X86__) || defined(_X86_) || defined(__I86__) || defined(__INTEL__) || defined(__386)))
#ifndef ZT_NO_TYPE_PUNNING
#define ZT_NO_TYPE_PUNNING
#endif
#endif
// Assume little endian if not defined on Mac and Windows as these don't run on any BE architectures.
#if (defined(__APPLE__) || defined(__WINDOWS__)) && (!defined(__BYTE_ORDER))
#undef __BYTE_ORDER
#undef __LITTLE_ENDIAN
#undef __BIG_ENDIAN
#define __BIG_ENDIAN 4321
#define __LITTLE_ENDIAN 1234
#define __BYTE_ORDER 1234
#endif
#ifndef __BYTE_ORDER
#include <endian.h>
#endif
#ifdef __WINDOWS__
#define ZT_PATH_SEPARATOR '\\'
#define ZT_PATH_SEPARATOR_S "\\"
#define ZT_EOL_S "\r\n"
#else
#define ZT_PATH_SEPARATOR '/'
#define ZT_PATH_SEPARATOR_S "/"
#define ZT_EOL_S "\n"
#endif
#if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__)
// #define inline __attribute__((always_inline))
#ifndef restrict
#define restrict __restrict__
#endif
#ifndef likely
#define likely(x) __builtin_expect((x),1)
#endif
#ifndef unlikely
#define unlikely(x) __builtin_expect((x),0)
#endif
#else /* not GCC-like */
#ifndef restrict
#define restrict
#endif
#ifndef likely
#define inline inline
#define likely(x) (x)
#endif
#ifndef unlikely
#define unlikely(x) (x)
#endif
#endif
#if defined(__WINDOWS__) && !defined(__GNUC__) && !defined (__clang__) && !defined(__INTEL_COMPILER)
#define ZT_PACKED_STRUCT(D) __pragma(pack(push,1)) D __pragma(pack(pop))
#else
#define ZT_PACKED_STRUCT(D) D __attribute__((packed))
#endif
#if __cplusplus > 199711L
#ifndef __CPP11__
#define __CPP11__
#endif
#endif
#ifdef SOCKET
#define ZT_SOCKET SOCKET
#else
#define ZT_SOCKET int
#endif
#ifdef INVALID_SOCKET
#define ZT_INVALID_SOCKET INVALID_SOCKET
#else
#define ZT_INVALID_SOCKET -1
#endif
/****************************************************************************/
/* Internal ZeroTier constants */
/****************************************************************************/
/**
* Length of a ZeroTier address in bytes
*/
@ -204,29 +42,15 @@
#define ZT_ADDRESS_RESERVED_PREFIX 0xff
/**
* Maximum DNS or URL name size for an Endpoint
* Maximum DNS or URL name size for an Endpoint (set so that max marshaled endpoint size is 128 bytes)
*/
#define ZT_ENDPOINT_MAX_NAME_SIZE 256
#define ZT_ENDPOINT_MAX_NAME_SIZE 124
/**
* Size of an identity hash (SHA384)
*/
#define ZT_IDENTITY_HASH_SIZE 48
/**
* Secure DNS name for ZeroTier's default root
*
* This resolves via GeoDNS to the (probably) nearest actual root server's locator.
*/
#define ZT_DEFAULT_ROOT_NAME "ztl-aj4zes4l6zumq64na6borruuvd6diw2koxrjcaatolcekt2gj5rrhric.ztl-6lhxeo7n3z7kzkgcqzj3ndliaq.zerotier.network"
/**
* Default locator for default root
*
* This is used before the root has been successfully fetched, or if DNS is unavailable.
*/
#define ZT_DEFAULT_ROOT_LOCATOR "AAAAAW2OuYyfOkbxvzAAduZvqzPihUmmLuIGTRhDJzwsMAukXD8gvvAtutIlcju1mpu0sTU1cwlhruz1oWOs5HfM6wcnAluZrBSlFmoJowAEBLm0DVInCQS5tA1SAbsGKgJuoMgVAAAAAAAAAAAAACcJBioCbqDIFQAAAAAAAAAAAAABuwAAYDvTNB2snbn7TYom4PBTh/ohRgCnI2/A/nfKakGCb+2hGJTtxTCiGTzKZdbjd0vyKAKQLJxhj7RaoCo3XjPn8w9nDEmhdNCgCM/IITCJIzc9tEKFsSQnJY4VmB3dopBAfQAA"
/**
* Default virtual network MTU (not physical)
*/

View file

@ -62,7 +62,7 @@ public:
inline Type type() const { return _t; }
static inline int marshalSizeMax() { return ZT_ENDPOINT_MARSHAL_SIZE_MAX; }
inline int marshal(uint8_t data[ZT_ENDPOINT_MARSHAL_SIZE_MAX])
inline int marshal(uint8_t data[ZT_ENDPOINT_MARSHAL_SIZE_MAX]) const
{
int p;
switch(_t) {

View file

@ -246,87 +246,6 @@ public:
*/
inline const Address &address() const { return _address; }
static inline int marshalSizeMax() { return ZT_IDENTITY_MARSHAL_SIZE_MAX; }
inline int marshal(uint8_t restrict data[ZT_IDENTITY_MARSHAL_SIZE_MAX],const bool includePrivate = false) const
{
_address.copyTo(data,ZT_ADDRESS_LENGTH);
switch(_type) {
case C25519:
data[ZT_ADDRESS_LENGTH] = (uint8_t)C25519;
memcpy(data + ZT_ADDRESS_LENGTH + 1,_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN);
if ((includePrivate)&&(_hasPrivate)) {
data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN] = ZT_C25519_PRIVATE_KEY_LEN;
memcpy(data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1,_priv.c25519,ZT_C25519_PRIVATE_KEY_LEN);
return (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1 + ZT_C25519_PRIVATE_KEY_LEN);
}
data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN] = 0;
return (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1);
case P384:
data[ZT_ADDRESS_LENGTH] = (uint8_t)P384;
memcpy(data + ZT_ADDRESS_LENGTH + 1,&_pub,ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE);
if ((includePrivate)&&(_hasPrivate)) {
data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE] = ZT_C25519_PRIVATE_KEY_LEN + ZT_ECC384_PRIVATE_KEY_SIZE;
memcpy(data + ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1,&_priv,ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE);
data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE] = 0;
return (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE + 1);
}
data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE] = 0;
data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1] = 0;
return (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 2);
}
return -1;
}
inline int unmarshal(const uint8_t *restrict data,const int len)
{
if (len < (ZT_ADDRESS_LENGTH + 1))
return -1;
unsigned int privlen;
switch((_type = (Type)data[ZT_ADDRESS_LENGTH])) {
case C25519:
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1))
return -1;
memcpy(_pub.c25519,data + ZT_ADDRESS_LENGTH + 1,ZT_C25519_PUBLIC_KEY_LEN);
privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN];
if (privlen == ZT_C25519_PRIVATE_KEY_LEN) {
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1 + ZT_C25519_PRIVATE_KEY_LEN))
return -1;
_hasPrivate = true;
memcpy(_priv.c25519,data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1,ZT_C25519_PRIVATE_KEY_LEN);
return (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1 + ZT_C25519_PRIVATE_KEY_LEN);
} else if (privlen == 0) {
_hasPrivate = false;
return (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1);
}
break;
case P384:
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 2))
return -1;
memcpy(&_pub,data + ZT_ADDRESS_LENGTH + 1,ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE);
privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE];
if (privlen == ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE) {
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE + 1))
return -1;
_hasPrivate = true;
memcpy(&_priv,data + ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1,ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE);
privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE];
if (len < (privlen + (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE + 1)))
return -1;
return (privlen + (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE + 1));
} else if (privlen == 0) {
_hasPrivate = false;
return (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 2);
}
break;
}
return -1;
}
/**
* Serialize this identity (binary)
*
@ -489,6 +408,89 @@ public:
inline unsigned long hashCode() const { return ((unsigned long)_address.toInt() + (unsigned long)_pub.c25519[0] + (unsigned long)_pub.c25519[1] + (unsigned long)_pub.c25519[2]); }
// Marshal interface ///////////////////////////////////////////////////////
static inline int marshalSizeMax() { return ZT_IDENTITY_MARSHAL_SIZE_MAX; }
inline int marshal(uint8_t restrict data[ZT_IDENTITY_MARSHAL_SIZE_MAX],const bool includePrivate = false) const
{
_address.copyTo(data,ZT_ADDRESS_LENGTH);
switch(_type) {
case C25519:
data[ZT_ADDRESS_LENGTH] = (uint8_t)C25519;
memcpy(data + ZT_ADDRESS_LENGTH + 1,_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN);
if ((includePrivate)&&(_hasPrivate)) {
data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN] = ZT_C25519_PRIVATE_KEY_LEN;
memcpy(data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1,_priv.c25519,ZT_C25519_PRIVATE_KEY_LEN);
return (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1 + ZT_C25519_PRIVATE_KEY_LEN);
}
data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN] = 0;
return (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1);
case P384:
data[ZT_ADDRESS_LENGTH] = (uint8_t)P384;
memcpy(data + ZT_ADDRESS_LENGTH + 1,&_pub,ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE);
if ((includePrivate)&&(_hasPrivate)) {
data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE] = ZT_C25519_PRIVATE_KEY_LEN + ZT_ECC384_PRIVATE_KEY_SIZE;
memcpy(data + ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1,&_priv,ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE);
data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE] = 0;
return (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE + 1);
}
data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE] = 0;
data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1] = 0;
return (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 2);
}
return -1;
}
inline int unmarshal(const uint8_t *restrict data,const int len)
{
if (len < (ZT_ADDRESS_LENGTH + 1))
return -1;
unsigned int privlen;
switch((_type = (Type)data[ZT_ADDRESS_LENGTH])) {
case C25519:
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1))
return -1;
memcpy(_pub.c25519,data + ZT_ADDRESS_LENGTH + 1,ZT_C25519_PUBLIC_KEY_LEN);
privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN];
if (privlen == ZT_C25519_PRIVATE_KEY_LEN) {
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1 + ZT_C25519_PRIVATE_KEY_LEN))
return -1;
_hasPrivate = true;
memcpy(_priv.c25519,data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1,ZT_C25519_PRIVATE_KEY_LEN);
return (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1 + ZT_C25519_PRIVATE_KEY_LEN);
} else if (privlen == 0) {
_hasPrivate = false;
return (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1);
}
break;
case P384:
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 2))
return -1;
memcpy(&_pub,data + ZT_ADDRESS_LENGTH + 1,ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE);
privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE];
if (privlen == ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE) {
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE + 1))
return -1;
_hasPrivate = true;
memcpy(&_priv,data + ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1,ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE);
privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE];
if (len < (privlen + (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE + 1)))
return -1;
return (privlen + (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE + 1));
} else if (privlen == 0) {
_hasPrivate = false;
return (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 2);
}
break;
}
return -1;
}
////////////////////////////////////////////////////////////////////////////
private:
Address _address;
Type _type; // _type determines which fields in _priv and _pub are used

View file

@ -489,6 +489,7 @@ struct InetAddress : public sockaddr_storage
*/
inline operator bool() const { return (ss_family != 0); }
// Marshal interface ///////////////////////////////////////////////////////
static inline int marshalSizeMax() { return 19; }
inline int marshal(uint8_t restrict data[19]) const
{
@ -547,6 +548,7 @@ struct InetAddress : public sockaddr_storage
return -1;
}
}
////////////////////////////////////////////////////////////////////////////
template<unsigned int C>
inline void serialize(Buffer<C> &b) const

View file

@ -22,8 +22,7 @@
#include "Identity.hpp"
#define ZT_LOCATOR_MAX_ENDPOINTS 8
#define ZT_LOCATOR_MARSHAL_SIZE_MAX ((ZT_ENDPOINT_MARSHAL_SIZE_MAX * ZT_LOCATOR_MAX_ENDPOINTS) + 8 + 256 + ZT_SIGNATURE_BUFFER_SIZE)
#define ZT_LOCATOR_MARSHAL_SIZE_MAX (8 + 2 + (ZT_ENDPOINT_MARSHAL_SIZE_MAX * ZT_LOCATOR_MAX_ENDPOINTS) + 2 + ZT_SIGNATURE_BUFFER_SIZE)
namespace ZeroTier {
@ -36,37 +35,12 @@ namespace ZeroTier {
class Locator
{
public:
inline Locator() : _ts(0),_at(nullptr),_signatureLength(0) {}
inline ~Locator() { delete [] _at; }
inline Locator(const Locator &l) :
_ts(l._ts),
_id(l._id),
_at((l._endpointCount > 0) ? new Endpoint[l._endpointCount] : nullptr),
_endpointCount(l._endpointCount),
_signatureLength(l._signatureLength)
{
for(unsigned int i=0;i<_endpointCount;++i)
_at[i] = l._at[i];
memcpy(_signature,l._signature,_signatureLength);
}
inline Locator &operator=(const Locator &l)
{
_ts = l._ts;
_id = l._id;
delete [] _at;
_at = (l._endpointCount > 0) ? new Endpoint[l._endpointCount] : nullptr;
for(unsigned int i=0;i<l._endpointCount;++i)
_at[i] = l._at[i];
_endpointCount = l._endpointCount;
_signatureLength = l._signatureLength;
memcpy(_signature,l._signature,_signatureLength);
return *this;
}
inline Locator() : _ts(0),_endpointCount(0),_signatureLength(0) {}
/**
* @return Timestamp (a.k.a. revision number) set by Location signer
*/
inline int64_t timestamp() const { return _ts; }
inline const Identity &id() const { return _id; }
/**
* Create and sign a Locator
@ -82,10 +56,6 @@ public:
if ((endpointCount > ZT_LOCATOR_MAX_ENDPOINTS)||(!id.hasPrivate()))
return false;
_ts = ts;
_id = id;
if (_at)
delete [] _at;
_at = new Endpoint[endpointCount];
for(unsigned int i=0;i<endpointCount;++i)
_at[i] = at[i];
_endpointCount = endpointCount;
@ -103,19 +73,21 @@ public:
/**
* Verify this Locator's validity and signature
*
* @param id Identity corresponding to hash
* @return True if valid and signature checks out
*/
inline bool verify() const
inline bool verify(const Identity &id) const
{
if ((_ts == 0)||(_endpointCount > ZT_LOCATOR_MAX_ENDPOINTS)||(_signatureLength > ZT_SIGNATURE_BUFFER_SIZE))
return false;
uint8_t signData[ZT_LOCATOR_MARSHAL_SIZE_MAX];
const unsigned int signLen = marshal(signData,true);
return _id.verify(signData,signLen,_signature,_signatureLength);
return id.verify(signData,signLen,_signature,_signatureLength);
}
inline operator bool() const { return (_ts != 0); }
// Marshal interface ///////////////////////////////////////////////////////
static inline int marshalSizeMax() { return ZT_LOCATOR_MARSHAL_SIZE_MAX; }
inline int marshal(uint8_t restrict data[ZT_LOCATOR_MARSHAL_SIZE_MAX],const bool excludeSignature = false) const
{
@ -130,12 +102,9 @@ public:
data[5] = (uint8_t)((uint64_t)_ts >> 16);
data[6] = (uint8_t)((uint64_t)_ts >> 8);
data[7] = (uint8_t)((uint64_t)_ts);
int p = 8;
int p = _id.marshal(data + 8,false);
if (p <= 0)
return -1;
p += 8;
data[p++] = (uint8_t)(_endpointCount >> 8);
data[p++] = (uint8_t)_endpointCount;
for(unsigned int i=0;i<_endpointCount;++i) {
int tmp = _at[i].marshal(data + p);
@ -155,7 +124,7 @@ public:
}
inline int unmarshal(const uint8_t *restrict data,const int len)
{
if (len <= 8)
if (len <= (8 + 48))
return -1;
uint64_t ts = ((uint64_t)data[0] << 56);
@ -167,20 +136,16 @@ public:
ts |= ((uint64_t)data[6] << 8);
ts |= (uint64_t)data[7];
_ts = (int64_t)ts;
int p = 8;
int p = _id.unmarshal(data + 8,len - 8);
if (p <= 0)
return -1;
p += 8;
if (p >= len)
if ((p + 2) > len)
return -1;
unsigned int ec = (int)data[p++];
ec <<= 8;
ec |= data[p++];
if (ec > ZT_LOCATOR_MAX_ENDPOINTS)
return -1;
if (_at)
delete [] _at;
_at = new Endpoint[ec];
_endpointCount = ec;
for(int i=0;i<ec;++i) {
int tmp = _at[i].unmarshal(data + p,len - p);
if (tmp < 0)
@ -203,13 +168,13 @@ public:
return p;
}
////////////////////////////////////////////////////////////////////////////
private:
int64_t _ts;
Identity _id;
Endpoint *_at;
unsigned int _endpointCount;
unsigned int _signatureLength;
Endpoint _at[ZT_LOCATOR_MAX_ENDPOINTS];
uint8_t _signature[ZT_SIGNATURE_BUFFER_SIZE];
};

View file

@ -28,24 +28,24 @@ namespace ZeroTier {
class Mutex
{
public:
inline Mutex() { pthread_mutex_init(&_mh,(const pthread_mutexattr_t *)0); }
inline ~Mutex() { pthread_mutex_destroy(&_mh); }
inline void lock() const { pthread_mutex_lock(&((const_cast <Mutex *> (this))->_mh)); }
inline void unlock() const { pthread_mutex_unlock(&((const_cast <Mutex *> (this))->_mh)); }
ZT_ALWAYS_INLINE Mutex() { pthread_mutex_init(&_mh,(const pthread_mutexattr_t *)0); }
ZT_ALWAYS_INLINE ~Mutex() { pthread_mutex_destroy(&_mh); }
ZT_ALWAYS_INLINE void lock() const { pthread_mutex_lock(&((const_cast <Mutex *> (this))->_mh)); }
ZT_ALWAYS_INLINE void unlock() const { pthread_mutex_unlock(&((const_cast <Mutex *> (this))->_mh)); }
class Lock
{
public:
inline Lock(Mutex &m) : _m(&m) { m.lock(); }
inline Lock(const Mutex &m) : _m(const_cast<Mutex *>(&m)) { _m->lock(); }
inline ~Lock() { _m->unlock(); }
ZT_ALWAYS_INLINE Lock(Mutex &m) : _m(&m) { m.lock(); }
ZT_ALWAYS_INLINE Lock(const Mutex &m) : _m(const_cast<Mutex *>(&m)) { _m->lock(); }
ZT_ALWAYS_INLINE ~Lock() { _m->unlock(); }
private:
Mutex *const _m;
};
private:
inline Mutex(const Mutex &) {}
const Mutex &operator=(const Mutex &) { return *this; }
ZT_ALWAYS_INLINE Mutex(const Mutex &) {}
ZT_ALWAYS_INLINE const Mutex &operator=(const Mutex &) { return *this; }
pthread_mutex_t _mh;
};
@ -65,26 +65,26 @@ namespace ZeroTier {
class Mutex
{
public:
inline Mutex() { InitializeCriticalSection(&_cs); }
inline ~Mutex() { DeleteCriticalSection(&_cs); }
inline void lock() { EnterCriticalSection(&_cs); }
inline void unlock() { LeaveCriticalSection(&_cs); }
inline void lock() const { (const_cast <Mutex *> (this))->lock(); }
inline void unlock() const { (const_cast <Mutex *> (this))->unlock(); }
ZT_ALWAYS_INLINE Mutex() { InitializeCriticalSection(&_cs); }
ZT_ALWAYS_INLINE ~Mutex() { DeleteCriticalSection(&_cs); }
ZT_ALWAYS_INLINE void lock() { EnterCriticalSection(&_cs); }
ZT_ALWAYS_INLINE void unlock() { LeaveCriticalSection(&_cs); }
ZT_ALWAYS_INLINE void lock() const { (const_cast <Mutex *> (this))->lock(); }
ZT_ALWAYS_INLINE void unlock() const { (const_cast <Mutex *> (this))->unlock(); }
class Lock
{
public:
inline Lock(Mutex &m) : _m(&m) { m.lock(); }
inline Lock(const Mutex &m) : _m(const_cast<Mutex *>(&m)) { _m->lock(); }
inline ~Lock() { _m->unlock(); }
ZT_ALWAYS_INLINE Lock(Mutex &m) : _m(&m) { m.lock(); }
ZT_ALWAYS_INLINE Lock(const Mutex &m) : _m(const_cast<Mutex *>(&m)) { _m->lock(); }
ZT_ALWAYS_INLINE ~Lock() { _m->unlock(); }
private:
Mutex *const _m;
};
private:
inline Mutex(const Mutex &) {}
const Mutex &operator=(const Mutex &) { return *this; }
ZT_ALWAYS_INLINE Mutex(const Mutex &) {}
ZT_ALWAYS_INLINE const Mutex &operator=(const Mutex &) { return *this; }
CRITICAL_SECTION _cs;
};

176
node/OS.hpp Normal file
View file

@ -0,0 +1,176 @@
/*
* Copyright (c)2019 ZeroTier, Inc.
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file in the project's root directory.
*
* Change Date: 2023-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2.0 of the Apache License.
*/
/****/
#ifndef ZT_OS_HPP
#define ZT_OS_HPP
//
// This include file also auto-detects and canonicalizes some environment
// information defines:
//
// __LINUX__
// __APPLE__
// __BSD__ (OSX also defines this)
// __UNIX_LIKE__ (Linux, BSD, etc.)
// __WINDOWS__
//
// Also makes sure __BYTE_ORDER is defined reasonably.
//
// Hack: make sure __GCC__ is defined on old GCC compilers
#ifndef __GCC__
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
#define __GCC__
#endif
#endif
#if defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux)
#ifndef __LINUX__
#define __LINUX__
#endif
#ifndef __UNIX_LIKE__
#define __UNIX_LIKE__
#endif
#include <endian.h>
#endif
#ifdef __APPLE__
#include <TargetConditionals.h>
#ifndef __UNIX_LIKE__
#define __UNIX_LIKE__
#endif
#ifndef __BSD__
#define __BSD__
#endif
#include <machine/endian.h>
#endif
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
#ifndef __UNIX_LIKE__
#define __UNIX_LIKE__
#endif
#ifndef __BSD__
#define __BSD__
#endif
#include <sys/endian.h>
#ifndef __BYTE_ORDER
#define __BYTE_ORDER _BYTE_ORDER
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
#endif
#endif
#if defined(_WIN32) || defined(_WIN64)
#ifndef __WINDOWS__
#define __WINDOWS__
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#pragma warning(disable : 4290)
#pragma warning(disable : 4996)
#pragma warning(disable : 4101)
#undef __UNIX_LIKE__
#undef __BSD__
#include <WinSock2.h>
#include <Windows.h>
#endif
#ifdef __NetBSD__
#ifndef RTF_MULTICAST
#define RTF_MULTICAST 0x20000000
#endif
#endif
// Define ZT_NO_TYPE_PUNNING to disable reckless casts on anything other than x86 and x86_64.
#if (!(defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(__X86__) || defined(_X86_) || defined(__I86__) || defined(__INTEL__) || defined(__386)))
#ifndef ZT_NO_TYPE_PUNNING
#define ZT_NO_TYPE_PUNNING
#endif
#endif
// Assume little endian if not defined on Mac and Windows as these don't run on any BE architectures.
#if (defined(__APPLE__) || defined(__WINDOWS__)) && (!defined(__BYTE_ORDER))
#undef __BYTE_ORDER
#undef __LITTLE_ENDIAN
#undef __BIG_ENDIAN
#define __BIG_ENDIAN 4321
#define __LITTLE_ENDIAN 1234
#define __BYTE_ORDER 1234
#endif
#ifndef __BYTE_ORDER
#include <endian.h>
#endif
#ifdef __WINDOWS__
#define ZT_PATH_SEPARATOR '\\'
#define ZT_PATH_SEPARATOR_S "\\"
#define ZT_EOL_S "\r\n"
#else
#define ZT_PATH_SEPARATOR '/'
#define ZT_PATH_SEPARATOR_S "/"
#define ZT_EOL_S "\n"
#endif
#if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__)
#define ZT_ALWAYS_INLINE __attribute__((always_inline))
#ifndef restrict
#define restrict __restrict__
#endif
#ifndef likely
#define likely(x) __builtin_expect((x),1)
#endif
#ifndef unlikely
#define unlikely(x) __builtin_expect((x),0)
#endif
#else /* not GCC-like */
#ifndef restrict
#define restrict
#endif
#ifndef likely
#define inline inline
#define likely(x) (x)
#endif
#ifndef unlikely
#define unlikely(x) (x)
#endif
#endif
#if defined(__WINDOWS__) && !defined(__GNUC__) && !defined (__clang__) && !defined(__INTEL_COMPILER)
#define ZT_PACKED_STRUCT(D) __pragma(pack(push,1)) D __pragma(pack(pop))
#else
#define ZT_PACKED_STRUCT(D) D __attribute__((packed))
#endif
#if __cplusplus > 199711L
#ifndef __CPP11__
#define __CPP11__
#endif
#endif
#ifdef SOCKET
#define ZT_SOCKET SOCKET
#else
#define ZT_SOCKET int
#endif
#ifdef INVALID_SOCKET
#define ZT_INVALID_SOCKET INVALID_SOCKET
#else
#define ZT_INVALID_SOCKET -1
#endif
#ifndef ZT_ALWAYS_INLINE
#define ZT_ALWAYS_INLINE inline
#endif
#endif

View file

@ -422,10 +422,10 @@ public:
* <[1] software minor version>
* <[2] software revision>
* <[8] timestamp for determining latency>
* <[...] binary serialized identity (see Identity)>
* <[...] binary serialized identity>
* <[...] physical destination address of packet>
* [... begin encrypted region ...]
* <[2] 16-bit reserved field, always 0>
* <[2] 16-bit reserved (legacy) field, always 0>
* <[2] 16-bit length of locator>
* <[...] locator for this node>
* <[2] 16-bit length of meta-data dictionary>
@ -857,18 +857,6 @@ public:
*/
VERB_USER_MESSAGE = 0x14,
/**
* A trace for remote debugging or diagnostics:
* <[...] null-terminated dictionary containing trace information>
* [<[...] additional null-terminated dictionaries>]
*
* This message contains a remote trace event. Remote trace events can
* be sent to observers configured at the network level for those that
* pertain directly to activity on a network, or to global observers if
* locally configured.
*/
VERB_REMOTE_TRACE = 0x15,
/**
* Peer-to-peer propagated multicast packet:
* <[128] 1024-bit bloom filter>

View file

@ -67,6 +67,14 @@ namespace Utils {
const char HEXCHARS[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
bool secureEq(const void *a,const void *b,unsigned int len)
{
uint8_t diff = 0;
for(unsigned int i=0;i<len;++i)
diff |= ( (reinterpret_cast<const uint8_t *>(a))[i] ^ (reinterpret_cast<const uint8_t *>(b))[i] );
return (diff == 0);
}
// Crazy hack to force memory to be securely zeroed in spite of the best efforts of optimizing compilers.
static void _Utils_doBurn(volatile uint8_t *ptr,unsigned int len)
{
@ -462,6 +470,24 @@ uint64_t random()
return result;
}
bool scopy(char *dest,unsigned int len,const char *src)
{
if (!len)
return false; // sanity check
if (!src) {
*dest = (char)0;
return true;
}
char *const end = dest + len;
while ((*dest++ = *src++)) {
if (dest == end) {
*(--dest) = (char)0;
return false;
}
}
return true;
}
} // namespace Utils
} // namespace ZeroTier

View file

@ -44,13 +44,7 @@ const char HEXCHARS[16];
* @param len Length of strings
* @return True if strings are equal
*/
inline bool secureEq(const void *a,const void *b,unsigned int len)
{
uint8_t diff = 0;
for(unsigned int i=0;i<len;++i)
diff |= ( (reinterpret_cast<const uint8_t *>(a))[i] ^ (reinterpret_cast<const uint8_t *>(b))[i] );
return (diff == 0);
}
bool secureEq(const void *a,const void *b,unsigned int len);
/**
* Zero memory, ensuring to avoid any compiler optimizations or other things that may stop this.
@ -148,7 +142,7 @@ void getSecureRandom(void *buf,unsigned int bytes);
/**
* Get a 64-bit unsigned secure random number
*/
static inline uint64_t getSecureRandom64()
static ZT_ALWAYS_INLINE uint64_t getSecureRandom64()
{
uint64_t x;
getSecureRandom(&x,sizeof(x));
@ -158,7 +152,7 @@ static inline uint64_t getSecureRandom64()
int b32e(const uint8_t *data,int length,char *result,int bufSize);
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 ZT_ALWAYS_INLINE unsigned int b64MaxEncodedSize(const unsigned int s) { return ((((s + 2) / 3) * 4) + 1); }
unsigned int b64e(const uint8_t *in,unsigned int inlen,char *out,unsigned int outlen);
unsigned int b64d(const char *in,uint8_t *out,unsigned int outlen);
@ -167,7 +161,7 @@ unsigned int b64d(const char *in,uint8_t *out,unsigned int outlen);
*/
uint64_t random();
static inline float normalize(float value, int64_t bigMin, int64_t bigMax, int32_t targetMin, int32_t targetMax)
static ZT_ALWAYS_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;
@ -182,7 +176,7 @@ static inline float normalize(float value, int64_t bigMin, int64_t bigMax, int32
* @param delim Delimiters
* @param saveptr Pointer to a char * for temporary reentrant storage
*/
static inline char *stok(char *str,const char *delim,char **saveptr)
static ZT_ALWAYS_INLINE char *stok(char *str,const char *delim,char **saveptr)
{
#ifdef __WINDOWS__
return strtok_s(str,delim,saveptr);
@ -191,11 +185,11 @@ static inline char *stok(char *str,const char *delim,char **saveptr)
#endif
}
static inline unsigned int strToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,10); }
static inline int strToInt(const char *s) { return (int)strtol(s,(char **)0,10); }
static inline unsigned long strToULong(const char *s) { return strtoul(s,(char **)0,10); }
static inline long strToLong(const char *s) { return strtol(s,(char **)0,10); }
static inline unsigned long long strToU64(const char *s)
static ZT_ALWAYS_INLINE unsigned int strToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,10); }
static ZT_ALWAYS_INLINE int strToInt(const char *s) { return (int)strtol(s,(char **)0,10); }
static ZT_ALWAYS_INLINE unsigned long strToULong(const char *s) { return strtoul(s,(char **)0,10); }
static ZT_ALWAYS_INLINE long strToLong(const char *s) { return strtol(s,(char **)0,10); }
static ZT_ALWAYS_INLINE unsigned long long strToU64(const char *s)
{
#ifdef __WINDOWS__
return (unsigned long long)_strtoui64(s,(char **)0,10);
@ -203,7 +197,7 @@ static inline unsigned long long strToU64(const char *s)
return strtoull(s,(char **)0,10);
#endif
}
static inline long long strTo64(const char *s)
static ZT_ALWAYS_INLINE long long strTo64(const char *s)
{
#ifdef __WINDOWS__
return (long long)_strtoi64(s,(char **)0,10);
@ -211,11 +205,11 @@ static inline long long strTo64(const char *s)
return strtoll(s,(char **)0,10);
#endif
}
static inline unsigned int hexStrToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,16); }
static inline int hexStrToInt(const char *s) { return (int)strtol(s,(char **)0,16); }
static inline unsigned long hexStrToULong(const char *s) { return strtoul(s,(char **)0,16); }
static inline long hexStrToLong(const char *s) { return strtol(s,(char **)0,16); }
static inline unsigned long long hexStrToU64(const char *s)
static ZT_ALWAYS_INLINE unsigned int hexStrToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,16); }
static ZT_ALWAYS_INLINE int hexStrToInt(const char *s) { return (int)strtol(s,(char **)0,16); }
static ZT_ALWAYS_INLINE unsigned long hexStrToULong(const char *s) { return strtoul(s,(char **)0,16); }
static ZT_ALWAYS_INLINE long hexStrToLong(const char *s) { return strtol(s,(char **)0,16); }
static ZT_ALWAYS_INLINE unsigned long long hexStrToU64(const char *s)
{
#ifdef __WINDOWS__
return (unsigned long long)_strtoui64(s,(char **)0,16);
@ -223,7 +217,7 @@ static inline unsigned long long hexStrToU64(const char *s)
return strtoull(s,(char **)0,16);
#endif
}
static inline long long hexStrTo64(const char *s)
static ZT_ALWAYS_INLINE long long hexStrTo64(const char *s)
{
#ifdef __WINDOWS__
return (long long)_strtoi64(s,(char **)0,16);
@ -243,29 +237,13 @@ static inline long long hexStrTo64(const char *s)
* @param src Source string (if NULL, dest will receive a zero-length string and true is returned)
* @return True on success, false on overflow (buffer will still be 0-terminated)
*/
static inline bool scopy(char *dest,unsigned int len,const char *src)
{
if (!len)
return false; // sanity check
if (!src) {
*dest = (char)0;
return true;
}
char *const end = dest + len;
while ((*dest++ = *src++)) {
if (dest == end) {
*(--dest) = (char)0;
return false;
}
}
return true;
}
bool scopy(char *dest,unsigned int len,const char *src);
#ifdef __GNUC__
static inline unsigned int countBits(const uint8_t v) { return (unsigned int)__builtin_popcount((unsigned int)v); }
static inline unsigned int countBits(const uint16_t v) { return (unsigned int)__builtin_popcount((unsigned int)v); }
static inline unsigned int countBits(const uint32_t v) { return (unsigned int)__builtin_popcountl((unsigned long)v); }
static inline unsigned int countBits(const uint64_t v) { return (unsigned int)__builtin_popcountll((unsigned long long)v); }
static ZT_ALWAYS_INLINE unsigned int countBits(const uint8_t v) { return (unsigned int)__builtin_popcount((unsigned int)v); }
static ZT_ALWAYS_INLINE unsigned int countBits(const uint16_t v) { return (unsigned int)__builtin_popcount((unsigned int)v); }
static ZT_ALWAYS_INLINE unsigned int countBits(const uint32_t v) { return (unsigned int)__builtin_popcountl((unsigned long)v); }
static ZT_ALWAYS_INLINE unsigned int countBits(const uint64_t v) { return (unsigned int)__builtin_popcountll((unsigned long long)v); }
#else
/**
* Count the number of bits set in an integer
@ -274,7 +252,7 @@ static inline unsigned int countBits(const uint64_t v) { return (unsigned int)__
* @return Number of bits set in this integer (0-bits in integer)
*/
template<typename T>
static inline unsigned int countBits(T v)
static ZT_ALWAYS_INLINE unsigned int countBits(T v)
{
v = v - ((v >> 1) & (T)~(T)0/3);
v = (v & (T)~(T)0/15*3) + ((v >> 2) & (T)~(T)0/15*3);
@ -285,11 +263,11 @@ static inline unsigned int countBits(T v)
// 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); }
static inline int16_t hton(int16_t n) { return (int16_t)Utils::hton((uint16_t)n); }
static inline uint32_t hton(uint32_t n)
static ZT_ALWAYS_INLINE uint8_t hton(uint8_t n) { return n; }
static ZT_ALWAYS_INLINE int8_t hton(int8_t n) { return n; }
static ZT_ALWAYS_INLINE uint16_t hton(uint16_t n) { return htons(n); }
static ZT_ALWAYS_INLINE int16_t hton(int16_t n) { return (int16_t)Utils::hton((uint16_t)n); }
static ZT_ALWAYS_INLINE uint32_t hton(uint32_t n)
{
#if defined(__GNUC__)
#if defined(__FreeBSD__)
@ -301,8 +279,8 @@ static inline uint32_t hton(uint32_t n)
return htonl(n);
#endif
}
static inline int32_t hton(int32_t n) { return (int32_t)Utils::hton((uint32_t)n); }
static inline uint64_t hton(uint64_t n)
static ZT_ALWAYS_INLINE int32_t hton(int32_t n) { return (int32_t)Utils::hton((uint32_t)n); }
static ZT_ALWAYS_INLINE uint64_t hton(uint64_t n)
{
#if defined(__GNUC__)
#if defined(__FreeBSD__)
@ -323,18 +301,18 @@ static inline uint64_t hton(uint64_t n)
);
#endif
}
static inline int64_t hton(int64_t n) { return (int64_t)hton((uint64_t)n); }
static ZT_ALWAYS_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; }
static ZT_ALWAYS_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); }
static inline int16_t ntoh(int16_t n) { return (int16_t)Utils::ntoh((uint16_t)n); }
static inline uint32_t ntoh(uint32_t n)
static ZT_ALWAYS_INLINE uint8_t ntoh(uint8_t n) { return n; }
static ZT_ALWAYS_INLINE int8_t ntoh(int8_t n) { return n; }
static ZT_ALWAYS_INLINE uint16_t ntoh(uint16_t n) { return ntohs(n); }
static ZT_ALWAYS_INLINE int16_t ntoh(int16_t n) { return (int16_t)Utils::ntoh((uint16_t)n); }
static ZT_ALWAYS_INLINE uint32_t ntoh(uint32_t n)
{
#if defined(__GNUC__)
#if defined(__FreeBSD__)
@ -346,8 +324,8 @@ static inline uint32_t ntoh(uint32_t n)
return ntohl(n);
#endif
}
static inline int32_t ntoh(int32_t n) { return (int32_t)Utils::ntoh((uint32_t)n); }
static inline uint64_t ntoh(uint64_t n)
static ZT_ALWAYS_INLINE int32_t ntoh(int32_t n) { return (int32_t)Utils::ntoh((uint32_t)n); }
static ZT_ALWAYS_INLINE uint64_t ntoh(uint64_t n)
{
#if defined(__GNUC__)
#if defined(__FreeBSD__)
@ -368,10 +346,10 @@ static inline uint64_t ntoh(uint64_t n)
);
#endif
}
static inline int64_t ntoh(int64_t n) { return (int64_t)ntoh((uint64_t)n); }
static ZT_ALWAYS_INLINE int64_t ntoh(int64_t n) { return (int64_t)ntoh((uint64_t)n); }
#else
template<typename T>
static inline T ntoh(T n) { return n; }
static ZT_ALWAYS_INLINE T ntoh(T n) { return n; }
#endif
} // namespace Utils