mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-07 13:03:45 +02:00
A bunch more build fixes.
This commit is contained in:
parent
1a2378a3d4
commit
55b0555aa0
14 changed files with 207 additions and 191 deletions
|
@ -7,13 +7,16 @@ else()
|
||||||
cmake_policy(VERSION 3.15)
|
cmake_policy(VERSION 3.15)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
set(default_build_type "Release")
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(CMAKE_SYSTEM_VERSION "7" CACHE STRING INTERNAL FORCE)
|
set(CMAKE_SYSTEM_VERSION "7" CACHE STRING INTERNAL FORCE)
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X Deployment Version")
|
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X Deployment Version")
|
||||||
|
|
||||||
set(ZEROTIER_ONE_VERSION_MAJOR 2 CACHE INTERNAL "")
|
set(ZEROTIER_ONE_VERSION_MAJOR 1 CACHE INTERNAL "")
|
||||||
set(ZEROTIER_ONE_VERSION_MINOR 0 CACHE INTERNAL "")
|
set(ZEROTIER_ONE_VERSION_MINOR 9 CACHE INTERNAL "")
|
||||||
set(ZEROTIER_ONE_VERSION_REVISION 0 CACHE INTERNAL "")
|
set(ZEROTIER_ONE_VERSION_REVISION 0 CACHE INTERNAL "")
|
||||||
set(ZEROTIER_ONE_VERSION_BUILD 0 CACHE INTERNAL "")
|
set(ZEROTIER_ONE_VERSION_BUILD 0 CACHE INTERNAL "")
|
||||||
|
|
||||||
|
@ -22,11 +25,6 @@ configure_file(
|
||||||
${CMAKE_BINARY_DIR}/version.h
|
${CMAKE_BINARY_DIR}/version.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(default_build_type "Release")
|
|
||||||
#if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
|
||||||
# set(default_build_type "Debug")
|
|
||||||
#endif()
|
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
|
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
|
||||||
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Choose the type of build." FORCE)
|
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Choose the type of build." FORCE)
|
||||||
|
@ -54,7 +52,6 @@ if(WIN32)
|
||||||
add_definitions(-DNOMINMAX)
|
add_definitions(-DNOMINMAX)
|
||||||
else(WIN32)
|
else(WIN32)
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
|
|
||||||
message("++ Setting MacOS Compiler Flags ${CMAKE_BUILD_TYPE}")
|
message("++ Setting MacOS Compiler Flags ${CMAKE_BUILD_TYPE}")
|
||||||
add_compile_options(
|
add_compile_options(
|
||||||
-Wall
|
-Wall
|
||||||
|
@ -74,9 +71,7 @@ else(WIN32)
|
||||||
-mmacosx-version-min=10.9
|
-mmacosx-version-min=10.9
|
||||||
$<$<CONFIG:RELEASE>:-flto>
|
$<$<CONFIG:RELEASE>:-flto>
|
||||||
)
|
)
|
||||||
|
|
||||||
else(APPLE)
|
else(APPLE)
|
||||||
|
|
||||||
message("++ Setting Linux/BSD/Posix Compiler Flags (${CMAKE_BUILD_TYPE})")
|
message("++ Setting Linux/BSD/Posix Compiler Flags (${CMAKE_BUILD_TYPE})")
|
||||||
add_compile_options(
|
add_compile_options(
|
||||||
-Wall
|
-Wall
|
||||||
|
@ -90,7 +85,6 @@ else(WIN32)
|
||||||
$<$<CONFIG:RELWITHDEBINFO>:-fPIE>
|
$<$<CONFIG:RELWITHDEBINFO>:-fPIE>
|
||||||
$<$<CONFIG:RELWITHDEBINFO>:-g>
|
$<$<CONFIG:RELWITHDEBINFO>:-g>
|
||||||
)
|
)
|
||||||
|
|
||||||
endif(APPLE)
|
endif(APPLE)
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
|
@ -103,19 +97,7 @@ if (
|
||||||
CMAKE_SYSTEM_PROCESSOR MATCHES "i686"
|
CMAKE_SYSTEM_PROCESSOR MATCHES "i686"
|
||||||
)
|
)
|
||||||
message("++ Adding SSE and AES-NI flags for processor ${CMAKE_SYSTEM_PROCESSOR}")
|
message("++ Adding SSE and AES-NI flags for processor ${CMAKE_SYSTEM_PROCESSOR}")
|
||||||
add_compile_options(
|
add_compile_options(-maes -mrdrnd -mpclmul -msse -msse2)
|
||||||
-maes
|
|
||||||
-mrdrnd
|
|
||||||
-mpclmul
|
|
||||||
-msse
|
|
||||||
-msse2
|
|
||||||
-msse3
|
|
||||||
-msse4.1
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(ZT_TRACE)
|
|
||||||
add_definitions(-DZT_TRACE)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(node)
|
add_subdirectory(node)
|
||||||
|
|
|
@ -404,7 +404,7 @@ public:
|
||||||
*/
|
*/
|
||||||
ZT_ALWAYS_INLINE const uint8_t *rBnc(int &ii,unsigned int len) const noexcept
|
ZT_ALWAYS_INLINE const uint8_t *rBnc(int &ii,unsigned int len) const noexcept
|
||||||
{
|
{
|
||||||
const uint8_t *const b = b + ii;
|
const uint8_t *const b = unsafeData + ii;
|
||||||
return ((ii += (int)len) <= ZT_BUF_MEM_SIZE) ? b : nullptr;
|
return ((ii += (int)len) <= ZT_BUF_MEM_SIZE) ? b : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1054,7 +1054,7 @@ ZT_ALWAYS_INLINE crypto_uint32 lt(crypto_uint32 a,crypto_uint32 b) /* 16-bit inp
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
oid reduce_add_sub(sc25519 *r)
|
void reduce_add_sub(sc25519 *r)
|
||||||
{
|
{
|
||||||
crypto_uint32 pb = 0;
|
crypto_uint32 pb = 0;
|
||||||
crypto_uint32 b;
|
crypto_uint32 b;
|
||||||
|
|
|
@ -41,7 +41,6 @@ set(core_headers
|
||||||
SHA512.hpp
|
SHA512.hpp
|
||||||
SharedPtr.hpp
|
SharedPtr.hpp
|
||||||
Tag.hpp
|
Tag.hpp
|
||||||
Tests.h
|
|
||||||
Topology.hpp
|
Topology.hpp
|
||||||
Trace.hpp
|
Trace.hpp
|
||||||
TriviallyCopyable.hpp
|
TriviallyCopyable.hpp
|
||||||
|
@ -78,7 +77,6 @@ set(core_src
|
||||||
SelfAwareness.cpp
|
SelfAwareness.cpp
|
||||||
SHA512.cpp
|
SHA512.cpp
|
||||||
Tag.cpp
|
Tag.cpp
|
||||||
Tests.cpp
|
|
||||||
Topology.cpp
|
Topology.cpp
|
||||||
Trace.cpp
|
Trace.cpp
|
||||||
Utils.cpp
|
Utils.cpp
|
||||||
|
@ -89,3 +87,7 @@ set(core_src
|
||||||
add_library(${PROJECT_NAME} STATIC ${core_src} ${core_headers})
|
add_library(${PROJECT_NAME} STATIC ${core_src} ${core_headers})
|
||||||
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_11)
|
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_11)
|
||||||
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_BINARY_DIR})
|
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_BINARY_DIR})
|
||||||
|
|
||||||
|
add_executable(zt_core_tests Tests.h Tests.cpp)
|
||||||
|
target_compile_definitions(zt_core_tests PRIVATE ZT_ENABLE_TESTS=1 ZT_STANDALONE_TESTS=1)
|
||||||
|
target_link_libraries(zt_core_tests zt_core)
|
||||||
|
|
|
@ -53,10 +53,8 @@ static ZT_ALWAYS_INLINE Credential::VerifyResult _credVerify(const RuntimeEnviro
|
||||||
return Credential::VERIFY_BAD_SIGNATURE;
|
return Credential::VERIFY_BAD_SIGNATURE;
|
||||||
|
|
||||||
const SharedPtr<Peer> peer(RR->topology->peer(tPtr,signedBy));
|
const SharedPtr<Peer> peer(RR->topology->peer(tPtr,signedBy));
|
||||||
if (!peer) {
|
if (!peer)
|
||||||
RR->sw->requestWhois(tPtr,RR->node->now(),signedBy);
|
|
||||||
return Credential::VERIFY_NEED_IDENTITY;
|
return Credential::VERIFY_NEED_IDENTITY;
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int l = credential.marshal(tmp,true);
|
int l = credential.marshal(tmp,true);
|
||||||
|
@ -78,10 +76,8 @@ Credential::VerifyResult Credential::_verify(const RuntimeEnvironment *const RR,
|
||||||
return Credential::VERIFY_BAD_SIGNATURE;
|
return Credential::VERIFY_BAD_SIGNATURE;
|
||||||
|
|
||||||
const SharedPtr<Peer> peer(RR->topology->peer(tPtr,credential._signedBy));
|
const SharedPtr<Peer> peer(RR->topology->peer(tPtr,credential._signedBy));
|
||||||
if (!peer) {
|
if (!peer)
|
||||||
RR->sw->requestWhois(tPtr,RR->node->now(),credential._signedBy);
|
|
||||||
return Credential::VERIFY_NEED_IDENTITY;
|
return Credential::VERIFY_NEED_IDENTITY;
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t buf[ZT_NETWORK_COM_MAX_QUALIFIERS * 3];
|
uint64_t buf[ZT_NETWORK_COM_MAX_QUALIFIERS * 3];
|
||||||
unsigned int ptr = 0;
|
unsigned int ptr = 0;
|
||||||
|
@ -123,7 +119,6 @@ Credential::VerifyResult Credential::_verify(const RuntimeEnvironment *RR,void *
|
||||||
if (!peer->identity().verify(tmp,(unsigned int)l,credential._custody[c].signature,credential._custody[c].signatureLength))
|
if (!peer->identity().verify(tmp,(unsigned int)l,credential._custody[c].signature,credential._custody[c].signatureLength))
|
||||||
return Credential::VERIFY_BAD_SIGNATURE;
|
return Credential::VERIFY_BAD_SIGNATURE;
|
||||||
} else {
|
} else {
|
||||||
RR->sw->requestWhois(tPtr,RR->node->now(),credential._custody[c].from);
|
|
||||||
return Credential::VERIFY_NEED_IDENTITY;
|
return Credential::VERIFY_NEED_IDENTITY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
Membership::Membership() :
|
Membership::Membership() :
|
||||||
_lastUpdatedMulticast(0),
|
|
||||||
_comRevocationThreshold(0),
|
_comRevocationThreshold(0),
|
||||||
_lastPushedCredentials(0),
|
_lastPushedCredentials(0),
|
||||||
_revocations(4),
|
_revocations(4),
|
||||||
|
|
|
@ -167,9 +167,6 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last time we pushed MULTICAST_LIKE(s)
|
|
||||||
int64_t _lastUpdatedMulticast;
|
|
||||||
|
|
||||||
// Revocation threshold for COM or 0 if none
|
// Revocation threshold for COM or 0 if none
|
||||||
int64_t _comRevocationThreshold;
|
int64_t _comRevocationThreshold;
|
||||||
|
|
||||||
|
|
141
node/Node.cpp
141
node/Node.cpp
|
@ -28,16 +28,54 @@
|
||||||
#include "ScopedPtr.hpp"
|
#include "ScopedPtr.hpp"
|
||||||
#include "Locator.hpp"
|
#include "Locator.hpp"
|
||||||
#include "Protocol.hpp"
|
#include "Protocol.hpp"
|
||||||
|
#include "Expect.hpp"
|
||||||
|
#include "VL1.hpp"
|
||||||
|
#include "VL2.hpp"
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct _NodeObjects
|
||||||
|
{
|
||||||
|
ZT_ALWAYS_INLINE _NodeObjects(RuntimeEnvironment *const RR,void *const tPtr) :
|
||||||
|
t(RR),
|
||||||
|
expect(),
|
||||||
|
vl2(RR),
|
||||||
|
vl1(RR),
|
||||||
|
sa(RR),
|
||||||
|
topology(RR,tPtr)
|
||||||
|
{
|
||||||
|
RR->t = &t;
|
||||||
|
RR->expect = &expect;
|
||||||
|
RR->vl2 = &vl2;
|
||||||
|
RR->vl1 = &vl1;
|
||||||
|
RR->sa = &sa;
|
||||||
|
RR->topology = &topology;
|
||||||
|
}
|
||||||
|
Trace t;
|
||||||
|
Expect expect;
|
||||||
|
VL2 vl2;
|
||||||
|
VL1 vl1;
|
||||||
|
SelfAwareness sa;
|
||||||
|
Topology topology;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _sortPeerPtrsByAddress
|
||||||
|
{
|
||||||
|
ZT_ALWAYS_INLINE bool operator()(const SharedPtr<Peer> &a,const SharedPtr<Peer> &b) const { return (a->address() < b->address()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
Node::Node(void *uPtr,void *tPtr,const struct ZT_Node_Callbacks *callbacks,int64_t now) :
|
Node::Node(void *uPtr,void *tPtr,const struct ZT_Node_Callbacks *callbacks,int64_t now) :
|
||||||
_RR(this),
|
_RR(this),
|
||||||
|
_objects(nullptr),
|
||||||
RR(&_RR),
|
RR(&_RR),
|
||||||
_cb(*callbacks),
|
_cb(*callbacks),
|
||||||
_uPtr(uPtr),
|
_uPtr(uPtr),
|
||||||
_networks(),
|
_networks(),
|
||||||
_networksMask(63),
|
_networksMask(15),
|
||||||
_now(now),
|
_now(now),
|
||||||
_lastPing(0),
|
_lastPing(0),
|
||||||
_lastHousekeepingRun(0),
|
_lastHousekeepingRun(0),
|
||||||
|
@ -46,7 +84,7 @@ Node::Node(void *uPtr,void *tPtr,const struct ZT_Node_Callbacks *callbacks,int64
|
||||||
_natMustDie(true),
|
_natMustDie(true),
|
||||||
_online(false)
|
_online(false)
|
||||||
{
|
{
|
||||||
_networks.resize(64); // _networksMask + 1, must be power of two
|
_networks.resize(16); // _networksMask + 1, must be power of two
|
||||||
|
|
||||||
uint64_t idtmp[2]; idtmp[0] = 0; idtmp[1] = 0;
|
uint64_t idtmp[2]; idtmp[0] = 0; idtmp[1] = 0;
|
||||||
std::vector<uint8_t> data(stateObjectGet(tPtr,ZT_STATE_OBJECT_IDENTITY_SECRET,idtmp));
|
std::vector<uint8_t> data(stateObjectGet(tPtr,ZT_STATE_OBJECT_IDENTITY_SECRET,idtmp));
|
||||||
|
@ -74,30 +112,9 @@ Node::Node(void *uPtr,void *tPtr,const struct ZT_Node_Callbacks *callbacks,int64
|
||||||
stateObjectPut(tPtr,ZT_STATE_OBJECT_IDENTITY_PUBLIC,idtmp,RR->publicIdentityStr,(unsigned int)strlen(RR->publicIdentityStr));
|
stateObjectPut(tPtr,ZT_STATE_OBJECT_IDENTITY_PUBLIC,idtmp,RR->publicIdentityStr,(unsigned int)strlen(RR->publicIdentityStr));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
// This constructs all the components of the ZeroTier core within a single contiguous memory container,
|
||||||
char *m = nullptr;
|
// which reduces memory fragmentation and may improve cache locality.
|
||||||
try {
|
_objects = new _NodeObjects(RR,tPtr);
|
||||||
m = reinterpret_cast<char *>(malloc(16 + sizeof(Trace) + sizeof(Switch) + sizeof(Topology) + sizeof(SelfAwareness)));
|
|
||||||
if (!m)
|
|
||||||
throw std::bad_alloc();
|
|
||||||
RR->rtmem = m;
|
|
||||||
while (((uintptr_t)m & 0xfU) != 0) ++m;
|
|
||||||
RR->t = new (m) Trace(RR);
|
|
||||||
m += sizeof(Trace);
|
|
||||||
RR->sw = new (m) Switch(RR);
|
|
||||||
m += sizeof(Switch);
|
|
||||||
RR->topology = new (m) Topology(RR,RR->identity,tPtr);
|
|
||||||
m += sizeof(Topology);
|
|
||||||
RR->sa = new (m) SelfAwareness(RR);
|
|
||||||
} catch ( ... ) {
|
|
||||||
if (RR->sa) RR->sa->~SelfAwareness();
|
|
||||||
if (RR->topology) RR->topology->~Topology();
|
|
||||||
if (RR->sw) RR->sw->~Switch();
|
|
||||||
if (RR->t) RR->t->~Trace();
|
|
||||||
if (m) ::free(m);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
postEvent(tPtr, ZT_EVENT_UP);
|
postEvent(tPtr, ZT_EVENT_UP);
|
||||||
}
|
}
|
||||||
|
@ -112,13 +129,12 @@ Node::~Node()
|
||||||
networks.swap(_networks);
|
networks.swap(_networks);
|
||||||
}
|
}
|
||||||
networks.clear();
|
networks.clear();
|
||||||
|
|
||||||
_networks_m.lock();
|
_networks_m.lock();
|
||||||
_networks_m.unlock();
|
_networks_m.unlock();
|
||||||
|
|
||||||
if (RR->sa) RR->sa->~SelfAwareness();
|
if (_objects)
|
||||||
if (RR->topology) RR->topology->~Topology();
|
delete (_NodeObjects *)_objects;
|
||||||
if (RR->t) RR->t->~Trace();
|
|
||||||
free(RR->rtmem);
|
|
||||||
|
|
||||||
// Let go of cached Buf objects. If other nodes happen to be running in this
|
// Let go of cached Buf objects. If other nodes happen to be running in this
|
||||||
// same process space new Bufs will be allocated as needed, but this is almost
|
// same process space new Bufs will be allocated as needed, but this is almost
|
||||||
|
@ -129,11 +145,12 @@ Node::~Node()
|
||||||
|
|
||||||
void Node::shutdown(void *tPtr)
|
void Node::shutdown(void *tPtr)
|
||||||
{
|
{
|
||||||
RR->topology->saveAll(tPtr);
|
if (RR->topology)
|
||||||
|
RR->topology->saveAll(tPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZT_ResultCode Node::processWirePacket(
|
ZT_ResultCode Node::processWirePacket(
|
||||||
void *tptr,
|
void *tPtr,
|
||||||
int64_t now,
|
int64_t now,
|
||||||
int64_t localSocket,
|
int64_t localSocket,
|
||||||
const struct sockaddr_storage *remoteAddress,
|
const struct sockaddr_storage *remoteAddress,
|
||||||
|
@ -142,12 +159,16 @@ ZT_ResultCode Node::processWirePacket(
|
||||||
volatile int64_t *nextBackgroundTaskDeadline)
|
volatile int64_t *nextBackgroundTaskDeadline)
|
||||||
{
|
{
|
||||||
_now = now;
|
_now = now;
|
||||||
//RR->sw->onRemotePacket(tptr,localSocket,*(reinterpret_cast<const InetAddress *>(remoteAddress)),packetData,packetLength);
|
// TODO: add buffer life cycle methods
|
||||||
|
SharedPtr<Buf> tmp(new Buf());
|
||||||
|
packetLength &= ZT_BUF_MEM_MASK;
|
||||||
|
memcpy(tmp->unsafeData,packetData,packetLength);
|
||||||
|
RR->vl1->onRemotePacket(tPtr,localSocket,(remoteAddress) ? InetAddress::NIL : *asInetAddress(remoteAddress),tmp,packetLength);
|
||||||
return ZT_RESULT_OK;
|
return ZT_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZT_ResultCode Node::processVirtualNetworkFrame(
|
ZT_ResultCode Node::processVirtualNetworkFrame(
|
||||||
void *tptr,
|
void *tPtr,
|
||||||
int64_t now,
|
int64_t now,
|
||||||
uint64_t nwid,
|
uint64_t nwid,
|
||||||
uint64_t sourceMac,
|
uint64_t sourceMac,
|
||||||
|
@ -389,11 +410,11 @@ ZT_ResultCode Node::leave(uint64_t nwid,void **uptr,void *tptr)
|
||||||
return ZT_RESULT_OK;
|
return ZT_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZT_ResultCode Node::multicastSubscribe(void *tptr,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi)
|
ZT_ResultCode Node::multicastSubscribe(void *tPtr,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi)
|
||||||
{
|
{
|
||||||
SharedPtr<Network> nw(this->network(nwid));
|
SharedPtr<Network> nw(this->network(nwid));
|
||||||
if (nw) {
|
if (nw) {
|
||||||
nw->multicastSubscribe(tptr,MulticastGroup(MAC(multicastGroup),(uint32_t)(multicastAdi & 0xffffffff)));
|
nw->multicastSubscribe(tPtr,MulticastGroup(MAC(multicastGroup),(uint32_t)(multicastAdi & 0xffffffff)));
|
||||||
return ZT_RESULT_OK;
|
return ZT_RESULT_OK;
|
||||||
} else return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
|
} else return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
@ -407,18 +428,18 @@ ZT_ResultCode Node::multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,u
|
||||||
} else return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
|
} else return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZT_ResultCode Node::addRoot(void *tptr,const ZT_Identity *identity,const sockaddr_storage *bootstrap)
|
ZT_ResultCode Node::addRoot(void *tPtr,const ZT_Identity *identity,const sockaddr_storage *bootstrap)
|
||||||
{
|
{
|
||||||
if (!identity)
|
if (!identity)
|
||||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||||
InetAddress a;
|
InetAddress a;
|
||||||
if (bootstrap)
|
if (bootstrap)
|
||||||
a = bootstrap;
|
a = bootstrap;
|
||||||
RR->topology->addRoot(tptr,*reinterpret_cast<const Identity *>(identity),a);
|
RR->topology->addRoot(tPtr,*reinterpret_cast<const Identity *>(identity),a);
|
||||||
return ZT_RESULT_OK;
|
return ZT_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZT_ResultCode Node::removeRoot(void *tptr,const ZT_Identity *identity)
|
ZT_ResultCode Node::removeRoot(void *tPtr,const ZT_Identity *identity)
|
||||||
{
|
{
|
||||||
if (!identity)
|
if (!identity)
|
||||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||||
|
@ -440,8 +461,6 @@ void Node::status(ZT_NodeStatus *status) const
|
||||||
status->online = _online ? 1 : 0;
|
status->online = _online ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _sortPeerPtrsByAddress { inline bool operator()(const SharedPtr<Peer> &a,const SharedPtr<Peer> &b) const { return (a->address() < b->address()); } };
|
|
||||||
|
|
||||||
ZT_PeerList *Node::peers() const
|
ZT_PeerList *Node::peers() const
|
||||||
{
|
{
|
||||||
std::vector< SharedPtr<Peer> > peers;
|
std::vector< SharedPtr<Peer> > peers;
|
||||||
|
@ -463,7 +482,7 @@ ZT_PeerList *Node::peers() const
|
||||||
p->address = (*pi)->address().toInt();
|
p->address = (*pi)->address().toInt();
|
||||||
identities[pl->peerCount] = (*pi)->identity(); // need to make a copy in case peer gets deleted
|
identities[pl->peerCount] = (*pi)->identity(); // need to make a copy in case peer gets deleted
|
||||||
p->identity = &identities[pl->peerCount];
|
p->identity = &identities[pl->peerCount];
|
||||||
memcpy(p->identityHash,(*pi)->identity().hash(),sizeof(p->identityHash));
|
memcpy(p->identityHash,(*pi)->identity().hash().data(),ZT_IDENTITY_HASH_SIZE);
|
||||||
if ((*pi)->remoteVersionKnown()) {
|
if ((*pi)->remoteVersionKnown()) {
|
||||||
p->versionMajor = (int)(*pi)->remoteVersionMajor();
|
p->versionMajor = (int)(*pi)->remoteVersionMajor();
|
||||||
p->versionMinor = (int)(*pi)->remoteVersionMinor();
|
p->versionMinor = (int)(*pi)->remoteVersionMinor();
|
||||||
|
@ -568,11 +587,14 @@ int Node::sendUserMessage(void *tptr,uint64_t dest,uint64_t typeId,const void *d
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (RR->identity.address().toInt() != dest) {
|
if (RR->identity.address().toInt() != dest) {
|
||||||
|
// TODO
|
||||||
|
/*
|
||||||
Packet outp(Address(dest),RR->identity.address(),Packet::VERB_USER_MESSAGE);
|
Packet outp(Address(dest),RR->identity.address(),Packet::VERB_USER_MESSAGE);
|
||||||
outp.append(typeId);
|
outp.append(typeId);
|
||||||
outp.append(data,len);
|
outp.append(data,len);
|
||||||
outp.compress();
|
outp.compress();
|
||||||
RR->sw->send(tptr,outp,true);
|
RR->sw->send(tptr,outp,true);
|
||||||
|
*/
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} catch ( ... ) {}
|
} catch ( ... ) {}
|
||||||
|
@ -586,9 +608,7 @@ void Node::setController(void *networkControllerInstance)
|
||||||
RR->localNetworkController->init(RR->identity,this);
|
RR->localNetworkController->init(RR->identity,this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************/
|
// Methods used only within the core ----------------------------------------------------------------------------------
|
||||||
/* Node methods used only within node/ */
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
std::vector<uint8_t> Node::stateObjectGet(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2])
|
std::vector<uint8_t> Node::stateObjectGet(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2])
|
||||||
{
|
{
|
||||||
|
@ -671,6 +691,8 @@ bool Node::localControllerHasAuthorized(const int64_t now,const uint64_t nwid,co
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implementation of NetworkController::Sender ------------------------------------------------------------------------
|
||||||
|
|
||||||
void Node::ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &destination,const NetworkConfig &nc,bool sendLegacyFormatConfig)
|
void Node::ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &destination,const NetworkConfig &nc,bool sendLegacyFormatConfig)
|
||||||
{
|
{
|
||||||
_localControllerAuthorizations_m.lock();
|
_localControllerAuthorizations_m.lock();
|
||||||
|
@ -682,12 +704,15 @@ void Node::ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &de
|
||||||
if (!n) return;
|
if (!n) return;
|
||||||
n->setConfiguration((void *)0,nc,true);
|
n->setConfiguration((void *)0,nc,true);
|
||||||
} else {
|
} else {
|
||||||
ScopedPtr< Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> > dconf(new Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY>());
|
Dictionary dconf;
|
||||||
if (nc.toDictionary(*dconf,sendLegacyFormatConfig)) {
|
if (nc.toDictionary(dconf,sendLegacyFormatConfig)) {
|
||||||
uint64_t configUpdateId = Utils::random();
|
uint64_t configUpdateId = Utils::random();
|
||||||
if (!configUpdateId) ++configUpdateId;
|
if (!configUpdateId) ++configUpdateId;
|
||||||
|
|
||||||
const unsigned int totalSize = dconf->sizeBytes();
|
std::vector<uint8_t> ddata;
|
||||||
|
dconf.encode(ddata);
|
||||||
|
// TODO
|
||||||
|
/*
|
||||||
unsigned int chunkIndex = 0;
|
unsigned int chunkIndex = 0;
|
||||||
while (chunkIndex < totalSize) {
|
while (chunkIndex < totalSize) {
|
||||||
const unsigned int chunkLen = std::min(totalSize - chunkIndex,(unsigned int)(ZT_PROTO_MAX_PACKET_LENGTH - (ZT_PACKET_IDX_PAYLOAD + 256)));
|
const unsigned int chunkLen = std::min(totalSize - chunkIndex,(unsigned int)(ZT_PROTO_MAX_PACKET_LENGTH - (ZT_PACKET_IDX_PAYLOAD + 256)));
|
||||||
|
@ -717,6 +742,7 @@ void Node::ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &de
|
||||||
RR->sw->send((void *)0,outp,true);
|
RR->sw->send((void *)0,outp,true);
|
||||||
chunkIndex += chunkLen;
|
chunkIndex += chunkLen;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -728,6 +754,8 @@ void Node::ncSendRevocation(const Address &destination,const Revocation &rev)
|
||||||
if (!n) return;
|
if (!n) return;
|
||||||
n->addCredential((void *)0,RR->identity,rev);
|
n->addCredential((void *)0,RR->identity,rev);
|
||||||
} else {
|
} else {
|
||||||
|
// TODO
|
||||||
|
/*
|
||||||
Packet outp(destination,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS);
|
Packet outp(destination,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS);
|
||||||
outp.append((uint8_t)0x00);
|
outp.append((uint8_t)0x00);
|
||||||
outp.append((uint16_t)0);
|
outp.append((uint16_t)0);
|
||||||
|
@ -736,6 +764,7 @@ void Node::ncSendRevocation(const Address &destination,const Revocation &rev)
|
||||||
rev.serialize(outp);
|
rev.serialize(outp);
|
||||||
outp.append((uint16_t)0);
|
outp.append((uint16_t)0);
|
||||||
RR->sw->send((void *)0,outp,true);
|
RR->sw->send((void *)0,outp,true);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -756,6 +785,8 @@ void Node::ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &des
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
} else if (requestPacketId) {
|
} else if (requestPacketId) {
|
||||||
|
// TODO
|
||||||
|
/*
|
||||||
Packet outp(destination,RR->identity.address(),Packet::VERB_ERROR);
|
Packet outp(destination,RR->identity.address(),Packet::VERB_ERROR);
|
||||||
outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
|
outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
|
||||||
outp.append(requestPacketId);
|
outp.append(requestPacketId);
|
||||||
|
@ -771,14 +802,13 @@ void Node::ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &des
|
||||||
}
|
}
|
||||||
outp.append(nwid);
|
outp.append(nwid);
|
||||||
RR->sw->send((void *)0,outp,true);
|
RR->sw->send((void *)0,outp,true);
|
||||||
|
*/
|
||||||
} // else we can't send an ERROR() in response to nothing, so discard
|
} // else we can't send an ERROR() in response to nothing, so discard
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
|
||||||
/****************************************************************************/
|
// C API exports
|
||||||
/* CAPI bindings */
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
@ -1015,9 +1045,12 @@ enum ZT_ResultCode ZT_Node_setPhysicalPathConfiguration(ZT_Node *node,const stru
|
||||||
|
|
||||||
void ZT_version(int *major,int *minor,int *revision)
|
void ZT_version(int *major,int *minor,int *revision)
|
||||||
{
|
{
|
||||||
if (major) *major = ZEROTIER_ONE_VERSION_MAJOR;
|
if (major)
|
||||||
if (minor) *minor = ZEROTIER_ONE_VERSION_MINOR;
|
*major = ZEROTIER_ONE_VERSION_MAJOR;
|
||||||
if (revision) *revision = ZEROTIER_ONE_VERSION_REVISION;
|
if (minor)
|
||||||
|
*minor = ZEROTIER_ONE_VERSION_MINOR;
|
||||||
|
if (revision)
|
||||||
|
*revision = ZEROTIER_ONE_VERSION_REVISION;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
|
@ -68,7 +68,7 @@ public:
|
||||||
// Public API Functions ---------------------------------------------------------------------------------------------
|
// Public API Functions ---------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
ZT_ResultCode processWirePacket(
|
ZT_ResultCode processWirePacket(
|
||||||
void *tptr,
|
void *tPtr,
|
||||||
int64_t now,
|
int64_t now,
|
||||||
int64_t localSocket,
|
int64_t localSocket,
|
||||||
const struct sockaddr_storage *remoteAddress,
|
const struct sockaddr_storage *remoteAddress,
|
||||||
|
@ -76,7 +76,7 @@ public:
|
||||||
unsigned int packetLength,
|
unsigned int packetLength,
|
||||||
volatile int64_t *nextBackgroundTaskDeadline);
|
volatile int64_t *nextBackgroundTaskDeadline);
|
||||||
ZT_ResultCode processVirtualNetworkFrame(
|
ZT_ResultCode processVirtualNetworkFrame(
|
||||||
void *tptr,
|
void *tPtr,
|
||||||
int64_t now,
|
int64_t now,
|
||||||
uint64_t nwid,
|
uint64_t nwid,
|
||||||
uint64_t sourceMac,
|
uint64_t sourceMac,
|
||||||
|
@ -89,10 +89,10 @@ public:
|
||||||
ZT_ResultCode processBackgroundTasks(void *tPtr, int64_t now, volatile int64_t *nextBackgroundTaskDeadline);
|
ZT_ResultCode processBackgroundTasks(void *tPtr, int64_t now, volatile int64_t *nextBackgroundTaskDeadline);
|
||||||
ZT_ResultCode join(uint64_t nwid,void *uptr,void *tptr);
|
ZT_ResultCode join(uint64_t nwid,void *uptr,void *tptr);
|
||||||
ZT_ResultCode leave(uint64_t nwid,void **uptr,void *tptr);
|
ZT_ResultCode leave(uint64_t nwid,void **uptr,void *tptr);
|
||||||
ZT_ResultCode multicastSubscribe(void *tptr,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);
|
ZT_ResultCode multicastSubscribe(void *tPtr,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);
|
||||||
ZT_ResultCode multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);
|
ZT_ResultCode multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);
|
||||||
ZT_ResultCode addRoot(void *tptr,const ZT_Identity *identity,const sockaddr_storage *bootstrap);
|
ZT_ResultCode addRoot(void *tPtr,const ZT_Identity *identity,const sockaddr_storage *bootstrap);
|
||||||
ZT_ResultCode removeRoot(void *tptr,const ZT_Identity *identity);
|
ZT_ResultCode removeRoot(void *tPtr,const ZT_Identity *identity);
|
||||||
uint64_t address() const;
|
uint64_t address() const;
|
||||||
void status(ZT_NodeStatus *status) const;
|
void status(ZT_NodeStatus *status) const;
|
||||||
ZT_PeerList *peers() const;
|
ZT_PeerList *peers() const;
|
||||||
|
@ -331,6 +331,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RuntimeEnvironment _RR;
|
RuntimeEnvironment _RR;
|
||||||
|
void *_objects;
|
||||||
RuntimeEnvironment *RR;
|
RuntimeEnvironment *RR;
|
||||||
ZT_Node_Callbacks _cb;
|
ZT_Node_Callbacks _cb;
|
||||||
void *_uPtr; // _uptr (lower case) is reserved in Visual Studio :P
|
void *_uPtr; // _uptr (lower case) is reserved in Visual Studio :P
|
||||||
|
|
|
@ -594,4 +594,15 @@ extern "C" const char *ZTT_benchmarkCrypto()
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ZT_STANDALONE_TESTS
|
||||||
|
int main(int argc,char **argv)
|
||||||
|
{
|
||||||
|
bool ok = true;
|
||||||
|
ok &= ZTT_general() == nullptr;
|
||||||
|
ZT_T_PRINTF(ZT_EOL_S);
|
||||||
|
ok &= ZTT_crypto() == nullptr;
|
||||||
|
return ok ? 0 : 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // ZT_ENABLE_TESTS
|
#endif // ZT_ENABLE_TESTS
|
||||||
|
|
|
@ -37,8 +37,6 @@
|
||||||
#ifndef ZT_TESTS_HPP
|
#ifndef ZT_TESTS_HPP
|
||||||
#define ZT_TESTS_HPP
|
#define ZT_TESTS_HPP
|
||||||
|
|
||||||
#define ZT_ENABLE_TESTS
|
|
||||||
|
|
||||||
#ifdef ZT_ENABLE_TESTS
|
#ifdef ZT_ENABLE_TESTS
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -34,9 +34,8 @@ struct _RootSortComparisonOperator
|
||||||
const int64_t _now;
|
const int64_t _now;
|
||||||
};
|
};
|
||||||
|
|
||||||
Topology::Topology(const RuntimeEnvironment *renv,const Identity &myId,void *tPtr) :
|
Topology::Topology(const RuntimeEnvironment *renv,void *tPtr) :
|
||||||
RR(renv),
|
RR(renv),
|
||||||
_myIdentity(myId),
|
|
||||||
_numConfiguredPhysicalPaths(0),
|
_numConfiguredPhysicalPaths(0),
|
||||||
_peers(256),
|
_peers(256),
|
||||||
_peersByIncomingProbe(256),
|
_peersByIncomingProbe(256),
|
||||||
|
@ -147,7 +146,7 @@ void Topology::setPhysicalPathConfiguration(const struct sockaddr_storage *pathN
|
||||||
|
|
||||||
void Topology::addRoot(void *tPtr,const Identity &id,const InetAddress &bootstrap)
|
void Topology::addRoot(void *tPtr,const Identity &id,const InetAddress &bootstrap)
|
||||||
{
|
{
|
||||||
if (id == _myIdentity) return; // sanity check
|
if (id == RR->identity) return; // sanity check
|
||||||
RWMutex::Lock l1(_peers_l);
|
RWMutex::Lock l1(_peers_l);
|
||||||
std::pair< std::set<Identity>::iterator,bool > ir(_roots.insert(id));
|
std::pair< std::set<Identity>::iterator,bool > ir(_roots.insert(id));
|
||||||
if (ir.second) {
|
if (ir.second) {
|
||||||
|
|
|
@ -42,7 +42,7 @@ class RuntimeEnvironment;
|
||||||
class Topology
|
class Topology
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Topology(const RuntimeEnvironment *renv,const Identity &myId,void *tPtr);
|
Topology(const RuntimeEnvironment *renv,void *tPtr);
|
||||||
~Topology();
|
~Topology();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -355,7 +355,6 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
const RuntimeEnvironment *const RR;
|
const RuntimeEnvironment *const RR;
|
||||||
const Identity _myIdentity;
|
|
||||||
|
|
||||||
RWMutex _peers_l;
|
RWMutex _peers_l;
|
||||||
RWMutex _paths_l;
|
RWMutex _paths_l;
|
||||||
|
|
172
node/Utils.hpp
172
node/Utils.hpp
|
@ -288,92 +288,6 @@ static ZT_ALWAYS_INLINE unsigned long hashString(const void *restrict key,const
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Decode a big-endian value from a byte stream
|
|
||||||
*
|
|
||||||
* @tparam I Type to decode (should be unsigned e.g. uint32_t or uint64_t)
|
|
||||||
* @param p Byte stream, must be at least sizeof(I) in size
|
|
||||||
* @return Decoded integer
|
|
||||||
*/
|
|
||||||
template<typename I>
|
|
||||||
static ZT_ALWAYS_INLINE I loadBigEndian(const void *const p) noexcept
|
|
||||||
{
|
|
||||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
|
||||||
I x = (I)0;
|
|
||||||
for(unsigned int k=0;k<sizeof(I);++k) {
|
|
||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
||||||
reinterpret_cast<uint8_t *>(&x)[k] = reinterpret_cast<const uint8_t *>(p)[(sizeof(I)-1)-k];
|
|
||||||
#else
|
|
||||||
reinterpret_cast<uint8_t *>(&x)[k] = reinterpret_cast<const uint8_t *>(p)[k];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return x;
|
|
||||||
#else
|
|
||||||
return ntoh(*reinterpret_cast<const I *>(p));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save an integer in big-endian format
|
|
||||||
*
|
|
||||||
* @tparam I Integer type to store (usually inferred)
|
|
||||||
* @param p Byte stream to write (must be at least sizeof(I))
|
|
||||||
* #param i Integer to write
|
|
||||||
*/
|
|
||||||
template<typename I>
|
|
||||||
static ZT_ALWAYS_INLINE void storeBigEndian(void *const p,const I i) noexcept
|
|
||||||
{
|
|
||||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
|
||||||
for(unsigned int k=0;k<sizeof(I);++k) {
|
|
||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
||||||
reinterpret_cast<uint8_t *>(p)[k] = reinterpret_cast<const uint8_t *>(&i)[(sizeof(I)-1)-k];
|
|
||||||
#else
|
|
||||||
reinterpret_cast<uint8_t *>(p)[k] = reinterpret_cast<const uint8_t *>(&i)[k];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
*reinterpret_cast<I *>(p) = hton(i);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy bits from memory into an integer type without modifying their order
|
|
||||||
*
|
|
||||||
* @tparam I Type to load
|
|
||||||
* @param p Byte stream, must be at least sizeof(I) in size
|
|
||||||
* @return Loaded raw integer
|
|
||||||
*/
|
|
||||||
template<typename I>
|
|
||||||
static ZT_ALWAYS_INLINE I loadAsIsEndian(const void *const p) noexcept
|
|
||||||
{
|
|
||||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
|
||||||
I x = (I)0;
|
|
||||||
for(unsigned int k=0;k<sizeof(I);++k)
|
|
||||||
reinterpret_cast<uint8_t *>(&x)[k] = reinterpret_cast<const uint8_t *>(p)[k];
|
|
||||||
return x;
|
|
||||||
#else
|
|
||||||
return *reinterpret_cast<const I *>(p);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy bits from memory into an integer type without modifying their order
|
|
||||||
*
|
|
||||||
* @tparam I Type to store
|
|
||||||
* @param p Byte array (must be at least sizeof(I))
|
|
||||||
* @param i Integer to store
|
|
||||||
*/
|
|
||||||
template<typename I>
|
|
||||||
static ZT_ALWAYS_INLINE void storeAsIsEndian(void *const p,const I i) noexcept
|
|
||||||
{
|
|
||||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
|
||||||
for(unsigned int k=0;k<sizeof(I);++k)
|
|
||||||
reinterpret_cast<uint8_t *>(p)[k] = reinterpret_cast<const uint8_t *>(&i)[k];
|
|
||||||
#else
|
|
||||||
*reinterpret_cast<I *>(p) = i;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
static ZT_ALWAYS_INLINE unsigned int countBits(const uint8_t v) noexcept { return (unsigned int)__builtin_popcount((unsigned int)v); }
|
static ZT_ALWAYS_INLINE unsigned int countBits(const uint8_t v) noexcept { return (unsigned int)__builtin_popcount((unsigned int)v); }
|
||||||
static ZT_ALWAYS_INLINE unsigned int countBits(const uint16_t v) noexcept { return (unsigned int)__builtin_popcount((unsigned int)v); }
|
static ZT_ALWAYS_INLINE unsigned int countBits(const uint16_t v) noexcept { return (unsigned int)__builtin_popcount((unsigned int)v); }
|
||||||
|
@ -502,6 +416,92 @@ template<typename T>
|
||||||
static ZT_ALWAYS_INLINE T ntoh(T n) noexcept { return n; }
|
static ZT_ALWAYS_INLINE T ntoh(T n) noexcept { return n; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode a big-endian value from a byte stream
|
||||||
|
*
|
||||||
|
* @tparam I Type to decode (should be unsigned e.g. uint32_t or uint64_t)
|
||||||
|
* @param p Byte stream, must be at least sizeof(I) in size
|
||||||
|
* @return Decoded integer
|
||||||
|
*/
|
||||||
|
template<typename I>
|
||||||
|
static ZT_ALWAYS_INLINE I loadBigEndian(const void *const p) noexcept
|
||||||
|
{
|
||||||
|
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||||
|
I x = (I)0;
|
||||||
|
for(unsigned int k=0;k<sizeof(I);++k) {
|
||||||
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
|
reinterpret_cast<uint8_t *>(&x)[k] = reinterpret_cast<const uint8_t *>(p)[(sizeof(I)-1)-k];
|
||||||
|
#else
|
||||||
|
reinterpret_cast<uint8_t *>(&x)[k] = reinterpret_cast<const uint8_t *>(p)[k];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
#else
|
||||||
|
return ntoh(*reinterpret_cast<const I *>(p));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save an integer in big-endian format
|
||||||
|
*
|
||||||
|
* @tparam I Integer type to store (usually inferred)
|
||||||
|
* @param p Byte stream to write (must be at least sizeof(I))
|
||||||
|
* #param i Integer to write
|
||||||
|
*/
|
||||||
|
template<typename I>
|
||||||
|
static ZT_ALWAYS_INLINE void storeBigEndian(void *const p,const I i) noexcept
|
||||||
|
{
|
||||||
|
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||||
|
for(unsigned int k=0;k<sizeof(I);++k) {
|
||||||
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
|
reinterpret_cast<uint8_t *>(p)[k] = reinterpret_cast<const uint8_t *>(&i)[(sizeof(I)-1)-k];
|
||||||
|
#else
|
||||||
|
reinterpret_cast<uint8_t *>(p)[k] = reinterpret_cast<const uint8_t *>(&i)[k];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
*reinterpret_cast<I *>(p) = hton(i);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy bits from memory into an integer type without modifying their order
|
||||||
|
*
|
||||||
|
* @tparam I Type to load
|
||||||
|
* @param p Byte stream, must be at least sizeof(I) in size
|
||||||
|
* @return Loaded raw integer
|
||||||
|
*/
|
||||||
|
template<typename I>
|
||||||
|
static ZT_ALWAYS_INLINE I loadAsIsEndian(const void *const p) noexcept
|
||||||
|
{
|
||||||
|
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||||
|
I x = (I)0;
|
||||||
|
for(unsigned int k=0;k<sizeof(I);++k)
|
||||||
|
reinterpret_cast<uint8_t *>(&x)[k] = reinterpret_cast<const uint8_t *>(p)[k];
|
||||||
|
return x;
|
||||||
|
#else
|
||||||
|
return *reinterpret_cast<const I *>(p);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy bits from memory into an integer type without modifying their order
|
||||||
|
*
|
||||||
|
* @tparam I Type to store
|
||||||
|
* @param p Byte array (must be at least sizeof(I))
|
||||||
|
* @param i Integer to store
|
||||||
|
*/
|
||||||
|
template<typename I>
|
||||||
|
static ZT_ALWAYS_INLINE void storeAsIsEndian(void *const p,const I i) noexcept
|
||||||
|
{
|
||||||
|
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||||
|
for(unsigned int k=0;k<sizeof(I);++k)
|
||||||
|
reinterpret_cast<uint8_t *>(p)[k] = reinterpret_cast<const uint8_t *>(&i)[k];
|
||||||
|
#else
|
||||||
|
*reinterpret_cast<I *>(p) = i;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
|
Loading…
Add table
Reference in a new issue