mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-26 17:03:43 +02:00
.
This commit is contained in:
parent
3b94ef99ae
commit
c1b2c7903c
10 changed files with 373 additions and 412 deletions
|
@ -14,11 +14,8 @@
|
||||||
#ifndef ZT_CONSTANTS_HPP
|
#ifndef ZT_CONSTANTS_HPP
|
||||||
#define ZT_CONSTANTS_HPP
|
#define ZT_CONSTANTS_HPP
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
/* Core includes and OS/platform setup stuff */
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
#include "../include/ZeroTierCore.h"
|
#include "../include/ZeroTierCore.h"
|
||||||
|
#include "OS.hpp"
|
||||||
|
|
||||||
#if __has_include("version.h")
|
#if __has_include("version.h")
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
@ -29,165 +26,6 @@
|
||||||
#define ZEROTIER_ONE_VERSION_BUILD 255
|
#define ZEROTIER_ONE_VERSION_BUILD 255
|
||||||
#endif
|
#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
|
* Length of a ZeroTier address in bytes
|
||||||
*/
|
*/
|
||||||
|
@ -204,29 +42,15 @@
|
||||||
#define ZT_ADDRESS_RESERVED_PREFIX 0xff
|
#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)
|
* Size of an identity hash (SHA384)
|
||||||
*/
|
*/
|
||||||
#define ZT_IDENTITY_HASH_SIZE 48
|
#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)
|
* Default virtual network MTU (not physical)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -62,7 +62,7 @@ public:
|
||||||
inline Type type() const { return _t; }
|
inline Type type() const { return _t; }
|
||||||
|
|
||||||
static inline int marshalSizeMax() { return ZT_ENDPOINT_MARSHAL_SIZE_MAX; }
|
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;
|
int p;
|
||||||
switch(_t) {
|
switch(_t) {
|
||||||
|
|
|
@ -246,87 +246,6 @@ public:
|
||||||
*/
|
*/
|
||||||
inline const Address &address() const { return _address; }
|
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)
|
* 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]); }
|
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:
|
private:
|
||||||
Address _address;
|
Address _address;
|
||||||
Type _type; // _type determines which fields in _priv and _pub are used
|
Type _type; // _type determines which fields in _priv and _pub are used
|
||||||
|
|
|
@ -489,6 +489,7 @@ struct InetAddress : public sockaddr_storage
|
||||||
*/
|
*/
|
||||||
inline operator bool() const { return (ss_family != 0); }
|
inline operator bool() const { return (ss_family != 0); }
|
||||||
|
|
||||||
|
// Marshal interface ///////////////////////////////////////////////////////
|
||||||
static inline int marshalSizeMax() { return 19; }
|
static inline int marshalSizeMax() { return 19; }
|
||||||
inline int marshal(uint8_t restrict data[19]) const
|
inline int marshal(uint8_t restrict data[19]) const
|
||||||
{
|
{
|
||||||
|
@ -547,6 +548,7 @@ struct InetAddress : public sockaddr_storage
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<unsigned int C>
|
template<unsigned int C>
|
||||||
inline void serialize(Buffer<C> &b) const
|
inline void serialize(Buffer<C> &b) const
|
||||||
|
|
|
@ -22,8 +22,7 @@
|
||||||
#include "Identity.hpp"
|
#include "Identity.hpp"
|
||||||
|
|
||||||
#define ZT_LOCATOR_MAX_ENDPOINTS 8
|
#define ZT_LOCATOR_MAX_ENDPOINTS 8
|
||||||
|
#define ZT_LOCATOR_MARSHAL_SIZE_MAX (8 + 2 + (ZT_ENDPOINT_MARSHAL_SIZE_MAX * ZT_LOCATOR_MAX_ENDPOINTS) + 2 + ZT_SIGNATURE_BUFFER_SIZE)
|
||||||
#define ZT_LOCATOR_MARSHAL_SIZE_MAX ((ZT_ENDPOINT_MARSHAL_SIZE_MAX * ZT_LOCATOR_MAX_ENDPOINTS) + 8 + 256 + ZT_SIGNATURE_BUFFER_SIZE)
|
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
|
@ -36,37 +35,12 @@ namespace ZeroTier {
|
||||||
class Locator
|
class Locator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline Locator() : _ts(0),_at(nullptr),_signatureLength(0) {}
|
inline Locator() : _ts(0),_endpointCount(0),_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Timestamp (a.k.a. revision number) set by Location signer
|
||||||
|
*/
|
||||||
inline int64_t timestamp() const { return _ts; }
|
inline int64_t timestamp() const { return _ts; }
|
||||||
inline const Identity &id() const { return _id; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and sign a Locator
|
* Create and sign a Locator
|
||||||
|
@ -82,10 +56,6 @@ public:
|
||||||
if ((endpointCount > ZT_LOCATOR_MAX_ENDPOINTS)||(!id.hasPrivate()))
|
if ((endpointCount > ZT_LOCATOR_MAX_ENDPOINTS)||(!id.hasPrivate()))
|
||||||
return false;
|
return false;
|
||||||
_ts = ts;
|
_ts = ts;
|
||||||
_id = id;
|
|
||||||
if (_at)
|
|
||||||
delete [] _at;
|
|
||||||
_at = new Endpoint[endpointCount];
|
|
||||||
for(unsigned int i=0;i<endpointCount;++i)
|
for(unsigned int i=0;i<endpointCount;++i)
|
||||||
_at[i] = at[i];
|
_at[i] = at[i];
|
||||||
_endpointCount = endpointCount;
|
_endpointCount = endpointCount;
|
||||||
|
@ -103,19 +73,21 @@ public:
|
||||||
/**
|
/**
|
||||||
* Verify this Locator's validity and signature
|
* Verify this Locator's validity and signature
|
||||||
*
|
*
|
||||||
|
* @param id Identity corresponding to hash
|
||||||
* @return True if valid and signature checks out
|
* @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))
|
if ((_ts == 0)||(_endpointCount > ZT_LOCATOR_MAX_ENDPOINTS)||(_signatureLength > ZT_SIGNATURE_BUFFER_SIZE))
|
||||||
return false;
|
return false;
|
||||||
uint8_t signData[ZT_LOCATOR_MARSHAL_SIZE_MAX];
|
uint8_t signData[ZT_LOCATOR_MARSHAL_SIZE_MAX];
|
||||||
const unsigned int signLen = marshal(signData,true);
|
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); }
|
inline operator bool() const { return (_ts != 0); }
|
||||||
|
|
||||||
|
// Marshal interface ///////////////////////////////////////////////////////
|
||||||
static inline int marshalSizeMax() { return ZT_LOCATOR_MARSHAL_SIZE_MAX; }
|
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
|
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[5] = (uint8_t)((uint64_t)_ts >> 16);
|
||||||
data[6] = (uint8_t)((uint64_t)_ts >> 8);
|
data[6] = (uint8_t)((uint64_t)_ts >> 8);
|
||||||
data[7] = (uint8_t)((uint64_t)_ts);
|
data[7] = (uint8_t)((uint64_t)_ts);
|
||||||
|
int p = 8;
|
||||||
|
|
||||||
int p = _id.marshal(data + 8,false);
|
data[p++] = (uint8_t)(_endpointCount >> 8);
|
||||||
if (p <= 0)
|
|
||||||
return -1;
|
|
||||||
p += 8;
|
|
||||||
|
|
||||||
data[p++] = (uint8_t)_endpointCount;
|
data[p++] = (uint8_t)_endpointCount;
|
||||||
for(unsigned int i=0;i<_endpointCount;++i) {
|
for(unsigned int i=0;i<_endpointCount;++i) {
|
||||||
int tmp = _at[i].marshal(data + p);
|
int tmp = _at[i].marshal(data + p);
|
||||||
|
@ -155,7 +124,7 @@ public:
|
||||||
}
|
}
|
||||||
inline int unmarshal(const uint8_t *restrict data,const int len)
|
inline int unmarshal(const uint8_t *restrict data,const int len)
|
||||||
{
|
{
|
||||||
if (len <= 8)
|
if (len <= (8 + 48))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
uint64_t ts = ((uint64_t)data[0] << 56);
|
uint64_t ts = ((uint64_t)data[0] << 56);
|
||||||
|
@ -167,20 +136,16 @@ public:
|
||||||
ts |= ((uint64_t)data[6] << 8);
|
ts |= ((uint64_t)data[6] << 8);
|
||||||
ts |= (uint64_t)data[7];
|
ts |= (uint64_t)data[7];
|
||||||
_ts = (int64_t)ts;
|
_ts = (int64_t)ts;
|
||||||
|
int p = 8;
|
||||||
|
|
||||||
int p = _id.unmarshal(data + 8,len - 8);
|
if ((p + 2) > len)
|
||||||
if (p <= 0)
|
|
||||||
return -1;
|
|
||||||
p += 8;
|
|
||||||
|
|
||||||
if (p >= len)
|
|
||||||
return -1;
|
return -1;
|
||||||
unsigned int ec = (int)data[p++];
|
unsigned int ec = (int)data[p++];
|
||||||
|
ec <<= 8;
|
||||||
|
ec |= data[p++];
|
||||||
if (ec > ZT_LOCATOR_MAX_ENDPOINTS)
|
if (ec > ZT_LOCATOR_MAX_ENDPOINTS)
|
||||||
return -1;
|
return -1;
|
||||||
if (_at)
|
_endpointCount = ec;
|
||||||
delete [] _at;
|
|
||||||
_at = new Endpoint[ec];
|
|
||||||
for(int i=0;i<ec;++i) {
|
for(int i=0;i<ec;++i) {
|
||||||
int tmp = _at[i].unmarshal(data + p,len - p);
|
int tmp = _at[i].unmarshal(data + p,len - p);
|
||||||
if (tmp < 0)
|
if (tmp < 0)
|
||||||
|
@ -203,13 +168,13 @@ public:
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int64_t _ts;
|
int64_t _ts;
|
||||||
Identity _id;
|
|
||||||
Endpoint *_at;
|
|
||||||
unsigned int _endpointCount;
|
unsigned int _endpointCount;
|
||||||
unsigned int _signatureLength;
|
unsigned int _signatureLength;
|
||||||
|
Endpoint _at[ZT_LOCATOR_MAX_ENDPOINTS];
|
||||||
uint8_t _signature[ZT_SIGNATURE_BUFFER_SIZE];
|
uint8_t _signature[ZT_SIGNATURE_BUFFER_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,24 +28,24 @@ namespace ZeroTier {
|
||||||
class Mutex
|
class Mutex
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline Mutex() { pthread_mutex_init(&_mh,(const pthread_mutexattr_t *)0); }
|
ZT_ALWAYS_INLINE Mutex() { pthread_mutex_init(&_mh,(const pthread_mutexattr_t *)0); }
|
||||||
inline ~Mutex() { pthread_mutex_destroy(&_mh); }
|
ZT_ALWAYS_INLINE ~Mutex() { pthread_mutex_destroy(&_mh); }
|
||||||
inline void lock() const { pthread_mutex_lock(&((const_cast <Mutex *> (this))->_mh)); }
|
ZT_ALWAYS_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 void unlock() const { pthread_mutex_unlock(&((const_cast <Mutex *> (this))->_mh)); }
|
||||||
|
|
||||||
class Lock
|
class Lock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline Lock(Mutex &m) : _m(&m) { m.lock(); }
|
ZT_ALWAYS_INLINE Lock(Mutex &m) : _m(&m) { m.lock(); }
|
||||||
inline Lock(const Mutex &m) : _m(const_cast<Mutex *>(&m)) { _m->lock(); }
|
ZT_ALWAYS_INLINE Lock(const Mutex &m) : _m(const_cast<Mutex *>(&m)) { _m->lock(); }
|
||||||
inline ~Lock() { _m->unlock(); }
|
ZT_ALWAYS_INLINE ~Lock() { _m->unlock(); }
|
||||||
private:
|
private:
|
||||||
Mutex *const _m;
|
Mutex *const _m;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline Mutex(const Mutex &) {}
|
ZT_ALWAYS_INLINE Mutex(const Mutex &) {}
|
||||||
const Mutex &operator=(const Mutex &) { return *this; }
|
ZT_ALWAYS_INLINE const Mutex &operator=(const Mutex &) { return *this; }
|
||||||
|
|
||||||
pthread_mutex_t _mh;
|
pthread_mutex_t _mh;
|
||||||
};
|
};
|
||||||
|
@ -65,26 +65,26 @@ namespace ZeroTier {
|
||||||
class Mutex
|
class Mutex
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline Mutex() { InitializeCriticalSection(&_cs); }
|
ZT_ALWAYS_INLINE Mutex() { InitializeCriticalSection(&_cs); }
|
||||||
inline ~Mutex() { DeleteCriticalSection(&_cs); }
|
ZT_ALWAYS_INLINE ~Mutex() { DeleteCriticalSection(&_cs); }
|
||||||
inline void lock() { EnterCriticalSection(&_cs); }
|
ZT_ALWAYS_INLINE void lock() { EnterCriticalSection(&_cs); }
|
||||||
inline void unlock() { LeaveCriticalSection(&_cs); }
|
ZT_ALWAYS_INLINE void unlock() { LeaveCriticalSection(&_cs); }
|
||||||
inline void lock() const { (const_cast <Mutex *> (this))->lock(); }
|
ZT_ALWAYS_INLINE void lock() const { (const_cast <Mutex *> (this))->lock(); }
|
||||||
inline void unlock() const { (const_cast <Mutex *> (this))->unlock(); }
|
ZT_ALWAYS_INLINE void unlock() const { (const_cast <Mutex *> (this))->unlock(); }
|
||||||
|
|
||||||
class Lock
|
class Lock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline Lock(Mutex &m) : _m(&m) { m.lock(); }
|
ZT_ALWAYS_INLINE Lock(Mutex &m) : _m(&m) { m.lock(); }
|
||||||
inline Lock(const Mutex &m) : _m(const_cast<Mutex *>(&m)) { _m->lock(); }
|
ZT_ALWAYS_INLINE Lock(const Mutex &m) : _m(const_cast<Mutex *>(&m)) { _m->lock(); }
|
||||||
inline ~Lock() { _m->unlock(); }
|
ZT_ALWAYS_INLINE ~Lock() { _m->unlock(); }
|
||||||
private:
|
private:
|
||||||
Mutex *const _m;
|
Mutex *const _m;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline Mutex(const Mutex &) {}
|
ZT_ALWAYS_INLINE Mutex(const Mutex &) {}
|
||||||
const Mutex &operator=(const Mutex &) { return *this; }
|
ZT_ALWAYS_INLINE const Mutex &operator=(const Mutex &) { return *this; }
|
||||||
|
|
||||||
CRITICAL_SECTION _cs;
|
CRITICAL_SECTION _cs;
|
||||||
};
|
};
|
||||||
|
|
176
node/OS.hpp
Normal file
176
node/OS.hpp
Normal 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
|
|
@ -422,10 +422,10 @@ public:
|
||||||
* <[1] software minor version>
|
* <[1] software minor version>
|
||||||
* <[2] software revision>
|
* <[2] software revision>
|
||||||
* <[8] timestamp for determining latency>
|
* <[8] timestamp for determining latency>
|
||||||
* <[...] binary serialized identity (see Identity)>
|
* <[...] binary serialized identity>
|
||||||
* <[...] physical destination address of packet>
|
* <[...] physical destination address of packet>
|
||||||
* [... begin encrypted region ...]
|
* [... begin encrypted region ...]
|
||||||
* <[2] 16-bit reserved field, always 0>
|
* <[2] 16-bit reserved (legacy) field, always 0>
|
||||||
* <[2] 16-bit length of locator>
|
* <[2] 16-bit length of locator>
|
||||||
* <[...] locator for this node>
|
* <[...] locator for this node>
|
||||||
* <[2] 16-bit length of meta-data dictionary>
|
* <[2] 16-bit length of meta-data dictionary>
|
||||||
|
@ -857,18 +857,6 @@ public:
|
||||||
*/
|
*/
|
||||||
VERB_USER_MESSAGE = 0x14,
|
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:
|
* Peer-to-peer propagated multicast packet:
|
||||||
* <[128] 1024-bit bloom filter>
|
* <[128] 1024-bit bloom filter>
|
||||||
|
|
|
@ -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' };
|
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.
|
// 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)
|
static void _Utils_doBurn(volatile uint8_t *ptr,unsigned int len)
|
||||||
{
|
{
|
||||||
|
@ -462,6 +470,24 @@ uint64_t random()
|
||||||
return result;
|
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 Utils
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
|
104
node/Utils.hpp
104
node/Utils.hpp
|
@ -44,13 +44,7 @@ const char HEXCHARS[16];
|
||||||
* @param len Length of strings
|
* @param len Length of strings
|
||||||
* @return True if strings are equal
|
* @return True if strings are equal
|
||||||
*/
|
*/
|
||||||
inline bool secureEq(const void *a,const void *b,unsigned int len)
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zero memory, ensuring to avoid any compiler optimizations or other things that may stop this.
|
* 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
|
* Get a 64-bit unsigned secure random number
|
||||||
*/
|
*/
|
||||||
static inline uint64_t getSecureRandom64()
|
static ZT_ALWAYS_INLINE uint64_t getSecureRandom64()
|
||||||
{
|
{
|
||||||
uint64_t x;
|
uint64_t x;
|
||||||
getSecureRandom(&x,sizeof(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 b32e(const uint8_t *data,int length,char *result,int bufSize);
|
||||||
int b32d(const char *encoded, uint8_t *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 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);
|
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();
|
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 bigSpan = bigMax - bigMin;
|
||||||
int64_t smallSpan = targetMax - targetMin;
|
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 delim Delimiters
|
||||||
* @param saveptr Pointer to a char * for temporary reentrant storage
|
* @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__
|
#ifdef __WINDOWS__
|
||||||
return strtok_s(str,delim,saveptr);
|
return strtok_s(str,delim,saveptr);
|
||||||
|
@ -191,11 +185,11 @@ static inline char *stok(char *str,const char *delim,char **saveptr)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int strToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,10); }
|
static ZT_ALWAYS_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 ZT_ALWAYS_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 ZT_ALWAYS_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 ZT_ALWAYS_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 long long strToU64(const char *s)
|
||||||
{
|
{
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
return (unsigned long long)_strtoui64(s,(char **)0,10);
|
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);
|
return strtoull(s,(char **)0,10);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
static inline long long strTo64(const char *s)
|
static ZT_ALWAYS_INLINE long long strTo64(const char *s)
|
||||||
{
|
{
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
return (long long)_strtoi64(s,(char **)0,10);
|
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);
|
return strtoll(s,(char **)0,10);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
static inline unsigned int hexStrToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,16); }
|
static ZT_ALWAYS_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 ZT_ALWAYS_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 ZT_ALWAYS_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 ZT_ALWAYS_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 long long hexStrToU64(const char *s)
|
||||||
{
|
{
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
return (unsigned long long)_strtoui64(s,(char **)0,16);
|
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);
|
return strtoull(s,(char **)0,16);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
static inline long long hexStrTo64(const char *s)
|
static ZT_ALWAYS_INLINE long long hexStrTo64(const char *s)
|
||||||
{
|
{
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
return (long long)_strtoi64(s,(char **)0,16);
|
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)
|
* @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)
|
* @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)
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
static inline unsigned int countBits(const uint8_t v) { return (unsigned int)__builtin_popcount((unsigned int)v); }
|
static ZT_ALWAYS_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 ZT_ALWAYS_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 ZT_ALWAYS_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 uint64_t v) { return (unsigned int)__builtin_popcountll((unsigned long long)v); }
|
||||||
#else
|
#else
|
||||||
/**
|
/**
|
||||||
* Count the number of bits set in an integer
|
* 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)
|
* @return Number of bits set in this integer (0-bits in integer)
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
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 - ((v >> 1) & (T)~(T)0/3);
|
||||||
v = (v & (T)~(T)0/15*3) + ((v >> 2) & (T)~(T)0/15*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
|
// Byte swappers for big/little endian conversion
|
||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
static inline uint8_t hton(uint8_t n) { return n; }
|
static ZT_ALWAYS_INLINE uint8_t hton(uint8_t n) { return n; }
|
||||||
static inline int8_t hton(int8_t n) { return n; }
|
static ZT_ALWAYS_INLINE int8_t hton(int8_t n) { return n; }
|
||||||
static inline uint16_t hton(uint16_t n) { return htons(n); }
|
static ZT_ALWAYS_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 ZT_ALWAYS_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 uint32_t hton(uint32_t n)
|
||||||
{
|
{
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#if defined(__FreeBSD__)
|
#if defined(__FreeBSD__)
|
||||||
|
@ -301,8 +279,8 @@ static inline uint32_t hton(uint32_t n)
|
||||||
return htonl(n);
|
return htonl(n);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
static inline int32_t hton(int32_t n) { return (int32_t)Utils::hton((uint32_t)n); }
|
static ZT_ALWAYS_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 uint64_t hton(uint64_t n)
|
||||||
{
|
{
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#if defined(__FreeBSD__)
|
#if defined(__FreeBSD__)
|
||||||
|
@ -323,18 +301,18 @@ static inline uint64_t hton(uint64_t n)
|
||||||
);
|
);
|
||||||
#endif
|
#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
|
#else
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static inline T hton(T n) { return n; }
|
static ZT_ALWAYS_INLINE T hton(T n) { return n; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
static inline uint8_t ntoh(uint8_t n) { return n; }
|
static ZT_ALWAYS_INLINE uint8_t ntoh(uint8_t n) { return n; }
|
||||||
static inline int8_t ntoh(int8_t n) { return n; }
|
static ZT_ALWAYS_INLINE int8_t ntoh(int8_t n) { return n; }
|
||||||
static inline uint16_t ntoh(uint16_t n) { return ntohs(n); }
|
static ZT_ALWAYS_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 ZT_ALWAYS_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 uint32_t ntoh(uint32_t n)
|
||||||
{
|
{
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#if defined(__FreeBSD__)
|
#if defined(__FreeBSD__)
|
||||||
|
@ -346,8 +324,8 @@ static inline uint32_t ntoh(uint32_t n)
|
||||||
return ntohl(n);
|
return ntohl(n);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
static inline int32_t ntoh(int32_t n) { return (int32_t)Utils::ntoh((uint32_t)n); }
|
static ZT_ALWAYS_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 uint64_t ntoh(uint64_t n)
|
||||||
{
|
{
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#if defined(__FreeBSD__)
|
#if defined(__FreeBSD__)
|
||||||
|
@ -368,10 +346,10 @@ static inline uint64_t ntoh(uint64_t n)
|
||||||
);
|
);
|
||||||
#endif
|
#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
|
#else
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static inline T ntoh(T n) { return n; }
|
static ZT_ALWAYS_INLINE T ntoh(T n) { return n; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
|
Loading…
Add table
Reference in a new issue