diff --git a/node/Constants.hpp b/node/Constants.hpp index 730937ab3..04748c066 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -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 -#endif - -#ifdef __APPLE__ -#include -#ifndef __UNIX_LIKE__ -#define __UNIX_LIKE__ -#endif -#ifndef __BSD__ -#define __BSD__ -#endif -#include -#endif - -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -#ifndef __UNIX_LIKE__ -#define __UNIX_LIKE__ -#endif -#ifndef __BSD__ -#define __BSD__ -#endif -#include -#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 -#include -#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 -#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) */ diff --git a/node/Endpoint.hpp b/node/Endpoint.hpp index 56ad148d3..bb167e2f6 100644 --- a/node/Endpoint.hpp +++ b/node/Endpoint.hpp @@ -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) { diff --git a/node/Identity.hpp b/node/Identity.hpp index 8fa905b60..cc8b5d71f 100644 --- a/node/Identity.hpp +++ b/node/Identity.hpp @@ -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 diff --git a/node/InetAddress.hpp b/node/InetAddress.hpp index 8330c7844..f6dc56f17 100644 --- a/node/InetAddress.hpp +++ b/node/InetAddress.hpp @@ -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 inline void serialize(Buffer &b) const diff --git a/node/Locator.hpp b/node/Locator.hpp index 676ff3f01..fef06b55c 100644 --- a/node/Locator.hpp +++ b/node/Locator.hpp @@ -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 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 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 (this))->_mh)); } - inline void unlock() const { pthread_mutex_unlock(&((const_cast (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 (this))->_mh)); } + ZT_ALWAYS_INLINE void unlock() const { pthread_mutex_unlock(&((const_cast (this))->_mh)); } class Lock { public: - inline Lock(Mutex &m) : _m(&m) { m.lock(); } - inline Lock(const Mutex &m) : _m(const_cast(&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(&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 (this))->lock(); } - inline void unlock() const { (const_cast (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 (this))->lock(); } + ZT_ALWAYS_INLINE void unlock() const { (const_cast (this))->unlock(); } class Lock { public: - inline Lock(Mutex &m) : _m(&m) { m.lock(); } - inline Lock(const Mutex &m) : _m(const_cast(&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(&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; }; diff --git a/node/OS.hpp b/node/OS.hpp new file mode 100644 index 000000000..025c59d19 --- /dev/null +++ b/node/OS.hpp @@ -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 +#endif + +#ifdef __APPLE__ +#include +#ifndef __UNIX_LIKE__ +#define __UNIX_LIKE__ +#endif +#ifndef __BSD__ +#define __BSD__ +#endif +#include +#endif + +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +#ifndef __UNIX_LIKE__ +#define __UNIX_LIKE__ +#endif +#ifndef __BSD__ +#define __BSD__ +#endif +#include +#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 +#include +#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 +#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 diff --git a/node/Packet.hpp b/node/Packet.hpp index c5301d7a8..e7a22746c 100644 --- a/node/Packet.hpp +++ b/node/Packet.hpp @@ -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> diff --git a/node/Utils.cpp b/node/Utils.cpp index a68e04bae..736526cc8 100644 --- a/node/Utils.cpp +++ b/node/Utils.cpp @@ -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(a))[i] ^ (reinterpret_cast(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 diff --git a/node/Utils.hpp b/node/Utils.hpp index be98f28dd..47f4b1051 100644 --- a/node/Utils.hpp +++ b/node/Utils.hpp @@ -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(a))[i] ^ (reinterpret_cast(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 -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 -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 -static inline T ntoh(T n) { return n; } +static ZT_ALWAYS_INLINE T ntoh(T n) { return n; } #endif } // namespace Utils