mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-25 08:27:39 +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
|
||||
#define ZT_CONSTANTS_HPP
|
||||
|
||||
/****************************************************************************/
|
||||
/* Core includes and OS/platform setup stuff */
|
||||
/****************************************************************************/
|
||||
|
||||
#include "../include/ZeroTierCore.h"
|
||||
#include "OS.hpp"
|
||||
|
||||
#if __has_include("version.h")
|
||||
#include "version.h"
|
||||
|
@ -29,165 +26,6 @@
|
|||
#define ZEROTIER_ONE_VERSION_BUILD 255
|
||||
#endif
|
||||
|
||||
//
|
||||
// This include file also auto-detects and canonicalizes some environment
|
||||
// information defines:
|
||||
//
|
||||
// __LINUX__
|
||||
// __APPLE__
|
||||
// __BSD__ (OSX also defines this)
|
||||
// __UNIX_LIKE__ (Linux, BSD, etc.)
|
||||
// __WINDOWS__
|
||||
//
|
||||
// Also makes sure __BYTE_ORDER is defined reasonably.
|
||||
//
|
||||
|
||||
// Hack: make sure __GCC__ is defined on old GCC compilers
|
||||
#ifndef __GCC__
|
||||
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
|
||||
#define __GCC__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux)
|
||||
#ifndef __LINUX__
|
||||
#define __LINUX__
|
||||
#endif
|
||||
#ifndef __UNIX_LIKE__
|
||||
#define __UNIX_LIKE__
|
||||
#endif
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <TargetConditionals.h>
|
||||
#ifndef __UNIX_LIKE__
|
||||
#define __UNIX_LIKE__
|
||||
#endif
|
||||
#ifndef __BSD__
|
||||
#define __BSD__
|
||||
#endif
|
||||
#include <machine/endian.h>
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
#ifndef __UNIX_LIKE__
|
||||
#define __UNIX_LIKE__
|
||||
#endif
|
||||
#ifndef __BSD__
|
||||
#define __BSD__
|
||||
#endif
|
||||
#include <sys/endian.h>
|
||||
#ifndef __BYTE_ORDER
|
||||
#define __BYTE_ORDER _BYTE_ORDER
|
||||
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
|
||||
#define __BIG_ENDIAN _BIG_ENDIAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#ifndef __WINDOWS__
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#pragma warning(disable : 4290)
|
||||
#pragma warning(disable : 4996)
|
||||
#pragma warning(disable : 4101)
|
||||
#undef __UNIX_LIKE__
|
||||
#undef __BSD__
|
||||
#include <WinSock2.h>
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef __NetBSD__
|
||||
#ifndef RTF_MULTICAST
|
||||
#define RTF_MULTICAST 0x20000000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Define ZT_NO_TYPE_PUNNING to disable reckless casts on anything other than x86 and x86_64.
|
||||
#if (!(defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(__X86__) || defined(_X86_) || defined(__I86__) || defined(__INTEL__) || defined(__386)))
|
||||
#ifndef ZT_NO_TYPE_PUNNING
|
||||
#define ZT_NO_TYPE_PUNNING
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Assume little endian if not defined on Mac and Windows as these don't run on any BE architectures.
|
||||
#if (defined(__APPLE__) || defined(__WINDOWS__)) && (!defined(__BYTE_ORDER))
|
||||
#undef __BYTE_ORDER
|
||||
#undef __LITTLE_ENDIAN
|
||||
#undef __BIG_ENDIAN
|
||||
#define __BIG_ENDIAN 4321
|
||||
#define __LITTLE_ENDIAN 1234
|
||||
#define __BYTE_ORDER 1234
|
||||
#endif
|
||||
#ifndef __BYTE_ORDER
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#define ZT_PATH_SEPARATOR '\\'
|
||||
#define ZT_PATH_SEPARATOR_S "\\"
|
||||
#define ZT_EOL_S "\r\n"
|
||||
#else
|
||||
#define ZT_PATH_SEPARATOR '/'
|
||||
#define ZT_PATH_SEPARATOR_S "/"
|
||||
#define ZT_EOL_S "\n"
|
||||
#endif
|
||||
|
||||
#if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__)
|
||||
// #define inline __attribute__((always_inline))
|
||||
#ifndef restrict
|
||||
#define restrict __restrict__
|
||||
#endif
|
||||
#ifndef likely
|
||||
#define likely(x) __builtin_expect((x),1)
|
||||
#endif
|
||||
#ifndef unlikely
|
||||
#define unlikely(x) __builtin_expect((x),0)
|
||||
#endif
|
||||
#else /* not GCC-like */
|
||||
#ifndef restrict
|
||||
#define restrict
|
||||
#endif
|
||||
#ifndef likely
|
||||
#define inline inline
|
||||
#define likely(x) (x)
|
||||
#endif
|
||||
#ifndef unlikely
|
||||
#define unlikely(x) (x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__WINDOWS__) && !defined(__GNUC__) && !defined (__clang__) && !defined(__INTEL_COMPILER)
|
||||
#define ZT_PACKED_STRUCT(D) __pragma(pack(push,1)) D __pragma(pack(pop))
|
||||
#else
|
||||
#define ZT_PACKED_STRUCT(D) D __attribute__((packed))
|
||||
#endif
|
||||
|
||||
#if __cplusplus > 199711L
|
||||
#ifndef __CPP11__
|
||||
#define __CPP11__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SOCKET
|
||||
#define ZT_SOCKET SOCKET
|
||||
#else
|
||||
#define ZT_SOCKET int
|
||||
#endif
|
||||
#ifdef INVALID_SOCKET
|
||||
#define ZT_INVALID_SOCKET INVALID_SOCKET
|
||||
#else
|
||||
#define ZT_INVALID_SOCKET -1
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/* Internal ZeroTier constants */
|
||||
/****************************************************************************/
|
||||
|
||||
/**
|
||||
* Length of a ZeroTier address in bytes
|
||||
*/
|
||||
|
@ -204,29 +42,15 @@
|
|||
#define ZT_ADDRESS_RESERVED_PREFIX 0xff
|
||||
|
||||
/**
|
||||
* Maximum DNS or URL name size for an Endpoint
|
||||
* Maximum DNS or URL name size for an Endpoint (set so that max marshaled endpoint size is 128 bytes)
|
||||
*/
|
||||
#define ZT_ENDPOINT_MAX_NAME_SIZE 256
|
||||
#define ZT_ENDPOINT_MAX_NAME_SIZE 124
|
||||
|
||||
/**
|
||||
* Size of an identity hash (SHA384)
|
||||
*/
|
||||
#define ZT_IDENTITY_HASH_SIZE 48
|
||||
|
||||
/**
|
||||
* Secure DNS name for ZeroTier's default root
|
||||
*
|
||||
* This resolves via GeoDNS to the (probably) nearest actual root server's locator.
|
||||
*/
|
||||
#define ZT_DEFAULT_ROOT_NAME "ztl-aj4zes4l6zumq64na6borruuvd6diw2koxrjcaatolcekt2gj5rrhric.ztl-6lhxeo7n3z7kzkgcqzj3ndliaq.zerotier.network"
|
||||
|
||||
/**
|
||||
* Default locator for default root
|
||||
*
|
||||
* This is used before the root has been successfully fetched, or if DNS is unavailable.
|
||||
*/
|
||||
#define ZT_DEFAULT_ROOT_LOCATOR "AAAAAW2OuYyfOkbxvzAAduZvqzPihUmmLuIGTRhDJzwsMAukXD8gvvAtutIlcju1mpu0sTU1cwlhruz1oWOs5HfM6wcnAluZrBSlFmoJowAEBLm0DVInCQS5tA1SAbsGKgJuoMgVAAAAAAAAAAAAACcJBioCbqDIFQAAAAAAAAAAAAABuwAAYDvTNB2snbn7TYom4PBTh/ohRgCnI2/A/nfKakGCb+2hGJTtxTCiGTzKZdbjd0vyKAKQLJxhj7RaoCo3XjPn8w9nDEmhdNCgCM/IITCJIzc9tEKFsSQnJY4VmB3dopBAfQAA"
|
||||
|
||||
/**
|
||||
* Default virtual network MTU (not physical)
|
||||
*/
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -489,6 +489,7 @@ struct InetAddress : public sockaddr_storage
|
|||
*/
|
||||
inline operator bool() const { return (ss_family != 0); }
|
||||
|
||||
// Marshal interface ///////////////////////////////////////////////////////
|
||||
static inline int marshalSizeMax() { return 19; }
|
||||
inline int marshal(uint8_t restrict data[19]) const
|
||||
{
|
||||
|
@ -547,6 +548,7 @@ struct InetAddress : public sockaddr_storage
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<unsigned int C>
|
||||
inline void serialize(Buffer<C> &b) const
|
||||
|
|
|
@ -22,8 +22,7 @@
|
|||
#include "Identity.hpp"
|
||||
|
||||
#define ZT_LOCATOR_MAX_ENDPOINTS 8
|
||||
|
||||
#define ZT_LOCATOR_MARSHAL_SIZE_MAX ((ZT_ENDPOINT_MARSHAL_SIZE_MAX * ZT_LOCATOR_MAX_ENDPOINTS) + 8 + 256 + ZT_SIGNATURE_BUFFER_SIZE)
|
||||
#define ZT_LOCATOR_MARSHAL_SIZE_MAX (8 + 2 + (ZT_ENDPOINT_MARSHAL_SIZE_MAX * ZT_LOCATOR_MAX_ENDPOINTS) + 2 + ZT_SIGNATURE_BUFFER_SIZE)
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -36,37 +35,12 @@ namespace ZeroTier {
|
|||
class Locator
|
||||
{
|
||||
public:
|
||||
inline Locator() : _ts(0),_at(nullptr),_signatureLength(0) {}
|
||||
inline ~Locator() { delete [] _at; }
|
||||
|
||||
inline Locator(const Locator &l) :
|
||||
_ts(l._ts),
|
||||
_id(l._id),
|
||||
_at((l._endpointCount > 0) ? new Endpoint[l._endpointCount] : nullptr),
|
||||
_endpointCount(l._endpointCount),
|
||||
_signatureLength(l._signatureLength)
|
||||
{
|
||||
for(unsigned int i=0;i<_endpointCount;++i)
|
||||
_at[i] = l._at[i];
|
||||
memcpy(_signature,l._signature,_signatureLength);
|
||||
}
|
||||
|
||||
inline Locator &operator=(const Locator &l)
|
||||
{
|
||||
_ts = l._ts;
|
||||
_id = l._id;
|
||||
delete [] _at;
|
||||
_at = (l._endpointCount > 0) ? new Endpoint[l._endpointCount] : nullptr;
|
||||
for(unsigned int i=0;i<l._endpointCount;++i)
|
||||
_at[i] = l._at[i];
|
||||
_endpointCount = l._endpointCount;
|
||||
_signatureLength = l._signatureLength;
|
||||
memcpy(_signature,l._signature,_signatureLength);
|
||||
return *this;
|
||||
}
|
||||
inline Locator() : _ts(0),_endpointCount(0),_signatureLength(0) {}
|
||||
|
||||
/**
|
||||
* @return Timestamp (a.k.a. revision number) set by Location signer
|
||||
*/
|
||||
inline int64_t timestamp() const { return _ts; }
|
||||
inline const Identity &id() const { return _id; }
|
||||
|
||||
/**
|
||||
* Create and sign a Locator
|
||||
|
@ -82,10 +56,6 @@ public:
|
|||
if ((endpointCount > ZT_LOCATOR_MAX_ENDPOINTS)||(!id.hasPrivate()))
|
||||
return false;
|
||||
_ts = ts;
|
||||
_id = id;
|
||||
if (_at)
|
||||
delete [] _at;
|
||||
_at = new Endpoint[endpointCount];
|
||||
for(unsigned int i=0;i<endpointCount;++i)
|
||||
_at[i] = at[i];
|
||||
_endpointCount = endpointCount;
|
||||
|
@ -103,19 +73,21 @@ public:
|
|||
/**
|
||||
* Verify this Locator's validity and signature
|
||||
*
|
||||
* @param id Identity corresponding to hash
|
||||
* @return True if valid and signature checks out
|
||||
*/
|
||||
inline bool verify() const
|
||||
inline bool verify(const Identity &id) const
|
||||
{
|
||||
if ((_ts == 0)||(_endpointCount > ZT_LOCATOR_MAX_ENDPOINTS)||(_signatureLength > ZT_SIGNATURE_BUFFER_SIZE))
|
||||
return false;
|
||||
uint8_t signData[ZT_LOCATOR_MARSHAL_SIZE_MAX];
|
||||
const unsigned int signLen = marshal(signData,true);
|
||||
return _id.verify(signData,signLen,_signature,_signatureLength);
|
||||
return id.verify(signData,signLen,_signature,_signatureLength);
|
||||
}
|
||||
|
||||
inline operator bool() const { return (_ts != 0); }
|
||||
|
||||
// Marshal interface ///////////////////////////////////////////////////////
|
||||
static inline int marshalSizeMax() { return ZT_LOCATOR_MARSHAL_SIZE_MAX; }
|
||||
inline int marshal(uint8_t restrict data[ZT_LOCATOR_MARSHAL_SIZE_MAX],const bool excludeSignature = false) const
|
||||
{
|
||||
|
@ -130,12 +102,9 @@ public:
|
|||
data[5] = (uint8_t)((uint64_t)_ts >> 16);
|
||||
data[6] = (uint8_t)((uint64_t)_ts >> 8);
|
||||
data[7] = (uint8_t)((uint64_t)_ts);
|
||||
int p = 8;
|
||||
|
||||
int p = _id.marshal(data + 8,false);
|
||||
if (p <= 0)
|
||||
return -1;
|
||||
p += 8;
|
||||
|
||||
data[p++] = (uint8_t)(_endpointCount >> 8);
|
||||
data[p++] = (uint8_t)_endpointCount;
|
||||
for(unsigned int i=0;i<_endpointCount;++i) {
|
||||
int tmp = _at[i].marshal(data + p);
|
||||
|
@ -155,7 +124,7 @@ public:
|
|||
}
|
||||
inline int unmarshal(const uint8_t *restrict data,const int len)
|
||||
{
|
||||
if (len <= 8)
|
||||
if (len <= (8 + 48))
|
||||
return -1;
|
||||
|
||||
uint64_t ts = ((uint64_t)data[0] << 56);
|
||||
|
@ -167,20 +136,16 @@ public:
|
|||
ts |= ((uint64_t)data[6] << 8);
|
||||
ts |= (uint64_t)data[7];
|
||||
_ts = (int64_t)ts;
|
||||
int p = 8;
|
||||
|
||||
int p = _id.unmarshal(data + 8,len - 8);
|
||||
if (p <= 0)
|
||||
return -1;
|
||||
p += 8;
|
||||
|
||||
if (p >= len)
|
||||
if ((p + 2) > len)
|
||||
return -1;
|
||||
unsigned int ec = (int)data[p++];
|
||||
ec <<= 8;
|
||||
ec |= data[p++];
|
||||
if (ec > ZT_LOCATOR_MAX_ENDPOINTS)
|
||||
return -1;
|
||||
if (_at)
|
||||
delete [] _at;
|
||||
_at = new Endpoint[ec];
|
||||
_endpointCount = ec;
|
||||
for(int i=0;i<ec;++i) {
|
||||
int tmp = _at[i].unmarshal(data + p,len - p);
|
||||
if (tmp < 0)
|
||||
|
@ -203,13 +168,13 @@ public:
|
|||
|
||||
return p;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private:
|
||||
int64_t _ts;
|
||||
Identity _id;
|
||||
Endpoint *_at;
|
||||
unsigned int _endpointCount;
|
||||
unsigned int _signatureLength;
|
||||
Endpoint _at[ZT_LOCATOR_MAX_ENDPOINTS];
|
||||
uint8_t _signature[ZT_SIGNATURE_BUFFER_SIZE];
|
||||
};
|
||||
|
||||
|
|
|
@ -28,24 +28,24 @@ namespace ZeroTier {
|
|||
class Mutex
|
||||
{
|
||||
public:
|
||||
inline Mutex() { pthread_mutex_init(&_mh,(const pthread_mutexattr_t *)0); }
|
||||
inline ~Mutex() { pthread_mutex_destroy(&_mh); }
|
||||
inline void lock() const { pthread_mutex_lock(&((const_cast <Mutex *> (this))->_mh)); }
|
||||
inline void unlock() const { pthread_mutex_unlock(&((const_cast <Mutex *> (this))->_mh)); }
|
||||
ZT_ALWAYS_INLINE Mutex() { pthread_mutex_init(&_mh,(const pthread_mutexattr_t *)0); }
|
||||
ZT_ALWAYS_INLINE ~Mutex() { pthread_mutex_destroy(&_mh); }
|
||||
ZT_ALWAYS_INLINE void lock() const { pthread_mutex_lock(&((const_cast <Mutex *> (this))->_mh)); }
|
||||
ZT_ALWAYS_INLINE void unlock() const { pthread_mutex_unlock(&((const_cast <Mutex *> (this))->_mh)); }
|
||||
|
||||
class Lock
|
||||
{
|
||||
public:
|
||||
inline Lock(Mutex &m) : _m(&m) { m.lock(); }
|
||||
inline Lock(const Mutex &m) : _m(const_cast<Mutex *>(&m)) { _m->lock(); }
|
||||
inline ~Lock() { _m->unlock(); }
|
||||
ZT_ALWAYS_INLINE Lock(Mutex &m) : _m(&m) { m.lock(); }
|
||||
ZT_ALWAYS_INLINE Lock(const Mutex &m) : _m(const_cast<Mutex *>(&m)) { _m->lock(); }
|
||||
ZT_ALWAYS_INLINE ~Lock() { _m->unlock(); }
|
||||
private:
|
||||
Mutex *const _m;
|
||||
};
|
||||
|
||||
private:
|
||||
inline Mutex(const Mutex &) {}
|
||||
const Mutex &operator=(const Mutex &) { return *this; }
|
||||
ZT_ALWAYS_INLINE Mutex(const Mutex &) {}
|
||||
ZT_ALWAYS_INLINE const Mutex &operator=(const Mutex &) { return *this; }
|
||||
|
||||
pthread_mutex_t _mh;
|
||||
};
|
||||
|
@ -65,26 +65,26 @@ namespace ZeroTier {
|
|||
class Mutex
|
||||
{
|
||||
public:
|
||||
inline Mutex() { InitializeCriticalSection(&_cs); }
|
||||
inline ~Mutex() { DeleteCriticalSection(&_cs); }
|
||||
inline void lock() { EnterCriticalSection(&_cs); }
|
||||
inline void unlock() { LeaveCriticalSection(&_cs); }
|
||||
inline void lock() const { (const_cast <Mutex *> (this))->lock(); }
|
||||
inline void unlock() const { (const_cast <Mutex *> (this))->unlock(); }
|
||||
ZT_ALWAYS_INLINE Mutex() { InitializeCriticalSection(&_cs); }
|
||||
ZT_ALWAYS_INLINE ~Mutex() { DeleteCriticalSection(&_cs); }
|
||||
ZT_ALWAYS_INLINE void lock() { EnterCriticalSection(&_cs); }
|
||||
ZT_ALWAYS_INLINE void unlock() { LeaveCriticalSection(&_cs); }
|
||||
ZT_ALWAYS_INLINE void lock() const { (const_cast <Mutex *> (this))->lock(); }
|
||||
ZT_ALWAYS_INLINE void unlock() const { (const_cast <Mutex *> (this))->unlock(); }
|
||||
|
||||
class Lock
|
||||
{
|
||||
public:
|
||||
inline Lock(Mutex &m) : _m(&m) { m.lock(); }
|
||||
inline Lock(const Mutex &m) : _m(const_cast<Mutex *>(&m)) { _m->lock(); }
|
||||
inline ~Lock() { _m->unlock(); }
|
||||
ZT_ALWAYS_INLINE Lock(Mutex &m) : _m(&m) { m.lock(); }
|
||||
ZT_ALWAYS_INLINE Lock(const Mutex &m) : _m(const_cast<Mutex *>(&m)) { _m->lock(); }
|
||||
ZT_ALWAYS_INLINE ~Lock() { _m->unlock(); }
|
||||
private:
|
||||
Mutex *const _m;
|
||||
};
|
||||
|
||||
private:
|
||||
inline Mutex(const Mutex &) {}
|
||||
const Mutex &operator=(const Mutex &) { return *this; }
|
||||
ZT_ALWAYS_INLINE Mutex(const Mutex &) {}
|
||||
ZT_ALWAYS_INLINE const Mutex &operator=(const Mutex &) { return *this; }
|
||||
|
||||
CRITICAL_SECTION _cs;
|
||||
};
|
||||
|
|
176
node/OS.hpp
Normal file
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>
|
||||
* <[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>
|
||||
|
|
|
@ -67,6 +67,14 @@ namespace Utils {
|
|||
|
||||
const char HEXCHARS[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
|
||||
|
||||
bool secureEq(const void *a,const void *b,unsigned int len)
|
||||
{
|
||||
uint8_t diff = 0;
|
||||
for(unsigned int i=0;i<len;++i)
|
||||
diff |= ( (reinterpret_cast<const uint8_t *>(a))[i] ^ (reinterpret_cast<const uint8_t *>(b))[i] );
|
||||
return (diff == 0);
|
||||
}
|
||||
|
||||
// Crazy hack to force memory to be securely zeroed in spite of the best efforts of optimizing compilers.
|
||||
static void _Utils_doBurn(volatile uint8_t *ptr,unsigned int len)
|
||||
{
|
||||
|
@ -462,6 +470,24 @@ uint64_t random()
|
|||
return result;
|
||||
}
|
||||
|
||||
bool scopy(char *dest,unsigned int len,const char *src)
|
||||
{
|
||||
if (!len)
|
||||
return false; // sanity check
|
||||
if (!src) {
|
||||
*dest = (char)0;
|
||||
return true;
|
||||
}
|
||||
char *const end = dest + len;
|
||||
while ((*dest++ = *src++)) {
|
||||
if (dest == end) {
|
||||
*(--dest) = (char)0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
|
104
node/Utils.hpp
104
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<len;++i)
|
||||
diff |= ( (reinterpret_cast<const uint8_t *>(a))[i] ^ (reinterpret_cast<const uint8_t *>(b))[i] );
|
||||
return (diff == 0);
|
||||
}
|
||||
bool secureEq(const void *a,const void *b,unsigned int len);
|
||||
|
||||
/**
|
||||
* Zero memory, ensuring to avoid any compiler optimizations or other things that may stop this.
|
||||
|
@ -148,7 +142,7 @@ void getSecureRandom(void *buf,unsigned int bytes);
|
|||
/**
|
||||
* Get a 64-bit unsigned secure random number
|
||||
*/
|
||||
static inline uint64_t getSecureRandom64()
|
||||
static ZT_ALWAYS_INLINE uint64_t getSecureRandom64()
|
||||
{
|
||||
uint64_t x;
|
||||
getSecureRandom(&x,sizeof(x));
|
||||
|
@ -158,7 +152,7 @@ static inline uint64_t getSecureRandom64()
|
|||
int b32e(const uint8_t *data,int length,char *result,int bufSize);
|
||||
int b32d(const char *encoded, uint8_t *result, int bufSize);
|
||||
|
||||
static inline unsigned int b64MaxEncodedSize(const unsigned int s) { return ((((s + 2) / 3) * 4) + 1); }
|
||||
static ZT_ALWAYS_INLINE unsigned int b64MaxEncodedSize(const unsigned int s) { return ((((s + 2) / 3) * 4) + 1); }
|
||||
unsigned int b64e(const uint8_t *in,unsigned int inlen,char *out,unsigned int outlen);
|
||||
unsigned int b64d(const char *in,uint8_t *out,unsigned int outlen);
|
||||
|
||||
|
@ -167,7 +161,7 @@ unsigned int b64d(const char *in,uint8_t *out,unsigned int outlen);
|
|||
*/
|
||||
uint64_t random();
|
||||
|
||||
static inline float normalize(float value, int64_t bigMin, int64_t bigMax, int32_t targetMin, int32_t targetMax)
|
||||
static ZT_ALWAYS_INLINE float normalize(float value, int64_t bigMin, int64_t bigMax, int32_t targetMin, int32_t targetMax)
|
||||
{
|
||||
int64_t bigSpan = bigMax - bigMin;
|
||||
int64_t smallSpan = targetMax - targetMin;
|
||||
|
@ -182,7 +176,7 @@ static inline float normalize(float value, int64_t bigMin, int64_t bigMax, int32
|
|||
* @param delim Delimiters
|
||||
* @param saveptr Pointer to a char * for temporary reentrant storage
|
||||
*/
|
||||
static inline char *stok(char *str,const char *delim,char **saveptr)
|
||||
static ZT_ALWAYS_INLINE char *stok(char *str,const char *delim,char **saveptr)
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
return strtok_s(str,delim,saveptr);
|
||||
|
@ -191,11 +185,11 @@ static inline char *stok(char *str,const char *delim,char **saveptr)
|
|||
#endif
|
||||
}
|
||||
|
||||
static inline unsigned int strToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,10); }
|
||||
static inline int strToInt(const char *s) { return (int)strtol(s,(char **)0,10); }
|
||||
static inline unsigned long strToULong(const char *s) { return strtoul(s,(char **)0,10); }
|
||||
static inline long strToLong(const char *s) { return strtol(s,(char **)0,10); }
|
||||
static inline unsigned long long strToU64(const char *s)
|
||||
static ZT_ALWAYS_INLINE unsigned int strToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,10); }
|
||||
static ZT_ALWAYS_INLINE int strToInt(const char *s) { return (int)strtol(s,(char **)0,10); }
|
||||
static ZT_ALWAYS_INLINE unsigned long strToULong(const char *s) { return strtoul(s,(char **)0,10); }
|
||||
static ZT_ALWAYS_INLINE long strToLong(const char *s) { return strtol(s,(char **)0,10); }
|
||||
static ZT_ALWAYS_INLINE unsigned long long strToU64(const char *s)
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
return (unsigned long long)_strtoui64(s,(char **)0,10);
|
||||
|
@ -203,7 +197,7 @@ static inline unsigned long long strToU64(const char *s)
|
|||
return strtoull(s,(char **)0,10);
|
||||
#endif
|
||||
}
|
||||
static inline long long strTo64(const char *s)
|
||||
static ZT_ALWAYS_INLINE long long strTo64(const char *s)
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
return (long long)_strtoi64(s,(char **)0,10);
|
||||
|
@ -211,11 +205,11 @@ static inline long long strTo64(const char *s)
|
|||
return strtoll(s,(char **)0,10);
|
||||
#endif
|
||||
}
|
||||
static inline unsigned int hexStrToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,16); }
|
||||
static inline int hexStrToInt(const char *s) { return (int)strtol(s,(char **)0,16); }
|
||||
static inline unsigned long hexStrToULong(const char *s) { return strtoul(s,(char **)0,16); }
|
||||
static inline long hexStrToLong(const char *s) { return strtol(s,(char **)0,16); }
|
||||
static inline unsigned long long hexStrToU64(const char *s)
|
||||
static ZT_ALWAYS_INLINE unsigned int hexStrToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,16); }
|
||||
static ZT_ALWAYS_INLINE int hexStrToInt(const char *s) { return (int)strtol(s,(char **)0,16); }
|
||||
static ZT_ALWAYS_INLINE unsigned long hexStrToULong(const char *s) { return strtoul(s,(char **)0,16); }
|
||||
static ZT_ALWAYS_INLINE long hexStrToLong(const char *s) { return strtol(s,(char **)0,16); }
|
||||
static ZT_ALWAYS_INLINE unsigned long long hexStrToU64(const char *s)
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
return (unsigned long long)_strtoui64(s,(char **)0,16);
|
||||
|
@ -223,7 +217,7 @@ static inline unsigned long long hexStrToU64(const char *s)
|
|||
return strtoull(s,(char **)0,16);
|
||||
#endif
|
||||
}
|
||||
static inline long long hexStrTo64(const char *s)
|
||||
static ZT_ALWAYS_INLINE long long hexStrTo64(const char *s)
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
return (long long)_strtoi64(s,(char **)0,16);
|
||||
|
@ -243,29 +237,13 @@ static inline long long hexStrTo64(const char *s)
|
|||
* @param src Source string (if NULL, dest will receive a zero-length string and true is returned)
|
||||
* @return True on success, false on overflow (buffer will still be 0-terminated)
|
||||
*/
|
||||
static inline bool scopy(char *dest,unsigned int len,const char *src)
|
||||
{
|
||||
if (!len)
|
||||
return false; // sanity check
|
||||
if (!src) {
|
||||
*dest = (char)0;
|
||||
return true;
|
||||
}
|
||||
char *const end = dest + len;
|
||||
while ((*dest++ = *src++)) {
|
||||
if (dest == end) {
|
||||
*(--dest) = (char)0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool scopy(char *dest,unsigned int len,const char *src);
|
||||
|
||||
#ifdef __GNUC__
|
||||
static inline unsigned int countBits(const uint8_t v) { return (unsigned int)__builtin_popcount((unsigned int)v); }
|
||||
static inline unsigned int countBits(const uint16_t v) { return (unsigned int)__builtin_popcount((unsigned int)v); }
|
||||
static inline unsigned int countBits(const uint32_t v) { return (unsigned int)__builtin_popcountl((unsigned long)v); }
|
||||
static inline unsigned int countBits(const uint64_t v) { return (unsigned int)__builtin_popcountll((unsigned long long)v); }
|
||||
static ZT_ALWAYS_INLINE unsigned int countBits(const uint8_t v) { return (unsigned int)__builtin_popcount((unsigned int)v); }
|
||||
static ZT_ALWAYS_INLINE unsigned int countBits(const uint16_t v) { return (unsigned int)__builtin_popcount((unsigned int)v); }
|
||||
static ZT_ALWAYS_INLINE unsigned int countBits(const uint32_t v) { return (unsigned int)__builtin_popcountl((unsigned long)v); }
|
||||
static ZT_ALWAYS_INLINE unsigned int countBits(const uint64_t v) { return (unsigned int)__builtin_popcountll((unsigned long long)v); }
|
||||
#else
|
||||
/**
|
||||
* Count the number of bits set in an integer
|
||||
|
@ -274,7 +252,7 @@ static inline unsigned int countBits(const uint64_t v) { return (unsigned int)__
|
|||
* @return Number of bits set in this integer (0-bits in integer)
|
||||
*/
|
||||
template<typename T>
|
||||
static inline unsigned int countBits(T v)
|
||||
static ZT_ALWAYS_INLINE unsigned int countBits(T v)
|
||||
{
|
||||
v = v - ((v >> 1) & (T)~(T)0/3);
|
||||
v = (v & (T)~(T)0/15*3) + ((v >> 2) & (T)~(T)0/15*3);
|
||||
|
@ -285,11 +263,11 @@ static inline unsigned int countBits(T v)
|
|||
|
||||
// Byte swappers for big/little endian conversion
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
static inline uint8_t hton(uint8_t n) { return n; }
|
||||
static inline int8_t hton(int8_t n) { return n; }
|
||||
static inline uint16_t hton(uint16_t n) { return htons(n); }
|
||||
static inline int16_t hton(int16_t n) { return (int16_t)Utils::hton((uint16_t)n); }
|
||||
static inline uint32_t hton(uint32_t n)
|
||||
static ZT_ALWAYS_INLINE uint8_t hton(uint8_t n) { return n; }
|
||||
static ZT_ALWAYS_INLINE int8_t hton(int8_t n) { return n; }
|
||||
static ZT_ALWAYS_INLINE uint16_t hton(uint16_t n) { return htons(n); }
|
||||
static ZT_ALWAYS_INLINE int16_t hton(int16_t n) { return (int16_t)Utils::hton((uint16_t)n); }
|
||||
static ZT_ALWAYS_INLINE uint32_t hton(uint32_t n)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
#if defined(__FreeBSD__)
|
||||
|
@ -301,8 +279,8 @@ static inline uint32_t hton(uint32_t n)
|
|||
return htonl(n);
|
||||
#endif
|
||||
}
|
||||
static inline int32_t hton(int32_t n) { return (int32_t)Utils::hton((uint32_t)n); }
|
||||
static inline uint64_t hton(uint64_t n)
|
||||
static ZT_ALWAYS_INLINE int32_t hton(int32_t n) { return (int32_t)Utils::hton((uint32_t)n); }
|
||||
static ZT_ALWAYS_INLINE uint64_t hton(uint64_t n)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
#if defined(__FreeBSD__)
|
||||
|
@ -323,18 +301,18 @@ static inline uint64_t hton(uint64_t n)
|
|||
);
|
||||
#endif
|
||||
}
|
||||
static inline int64_t hton(int64_t n) { return (int64_t)hton((uint64_t)n); }
|
||||
static ZT_ALWAYS_INLINE int64_t hton(int64_t n) { return (int64_t)hton((uint64_t)n); }
|
||||
#else
|
||||
template<typename T>
|
||||
static inline T hton(T n) { return n; }
|
||||
static ZT_ALWAYS_INLINE T hton(T n) { return n; }
|
||||
#endif
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
static inline uint8_t ntoh(uint8_t n) { return n; }
|
||||
static inline int8_t ntoh(int8_t n) { return n; }
|
||||
static inline uint16_t ntoh(uint16_t n) { return ntohs(n); }
|
||||
static inline int16_t ntoh(int16_t n) { return (int16_t)Utils::ntoh((uint16_t)n); }
|
||||
static inline uint32_t ntoh(uint32_t n)
|
||||
static ZT_ALWAYS_INLINE uint8_t ntoh(uint8_t n) { return n; }
|
||||
static ZT_ALWAYS_INLINE int8_t ntoh(int8_t n) { return n; }
|
||||
static ZT_ALWAYS_INLINE uint16_t ntoh(uint16_t n) { return ntohs(n); }
|
||||
static ZT_ALWAYS_INLINE int16_t ntoh(int16_t n) { return (int16_t)Utils::ntoh((uint16_t)n); }
|
||||
static ZT_ALWAYS_INLINE uint32_t ntoh(uint32_t n)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
#if defined(__FreeBSD__)
|
||||
|
@ -346,8 +324,8 @@ static inline uint32_t ntoh(uint32_t n)
|
|||
return ntohl(n);
|
||||
#endif
|
||||
}
|
||||
static inline int32_t ntoh(int32_t n) { return (int32_t)Utils::ntoh((uint32_t)n); }
|
||||
static inline uint64_t ntoh(uint64_t n)
|
||||
static ZT_ALWAYS_INLINE int32_t ntoh(int32_t n) { return (int32_t)Utils::ntoh((uint32_t)n); }
|
||||
static ZT_ALWAYS_INLINE uint64_t ntoh(uint64_t n)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
#if defined(__FreeBSD__)
|
||||
|
@ -368,10 +346,10 @@ static inline uint64_t ntoh(uint64_t n)
|
|||
);
|
||||
#endif
|
||||
}
|
||||
static inline int64_t ntoh(int64_t n) { return (int64_t)ntoh((uint64_t)n); }
|
||||
static ZT_ALWAYS_INLINE int64_t ntoh(int64_t n) { return (int64_t)ntoh((uint64_t)n); }
|
||||
#else
|
||||
template<typename T>
|
||||
static inline T ntoh(T n) { return n; }
|
||||
static ZT_ALWAYS_INLINE T ntoh(T n) { return n; }
|
||||
#endif
|
||||
|
||||
} // namespace Utils
|
||||
|
|
Loading…
Add table
Reference in a new issue