mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-06 20:43:44 +02:00
Move C API into its own source file, and fix some build flags to mirror fix in 1.6.0 to run on old Atom processors.
This commit is contained in:
parent
bc8aa6c359
commit
8f746f5099
13 changed files with 760 additions and 715 deletions
|
@ -219,10 +219,13 @@ if(NOT PACKAGE_STATIC)
|
|||
if (
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "amd64" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64"
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "X86_64" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "x64" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "X64"
|
||||
)
|
||||
message("++ Adding flags for processor ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
add_compile_options(-maes -mrdrnd -mpclmul -msse -msse2 -mssse3 -msse4 -msse4.1 -msse4.2)
|
||||
add_compile_options(-maes -mrdrnd -mpclmul -msse -msse2)
|
||||
endif()
|
||||
|
||||
if (
|
||||
|
|
|
@ -158,6 +158,8 @@ private:
|
|||
uint64_t _a;
|
||||
};
|
||||
|
||||
static_assert(sizeof(Address) == sizeof(uint64_t),"Address has unnecessary extra padding");
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
||||
|
|
|
@ -112,6 +112,9 @@ struct UniqueID
|
|||
{ return (memcmp(data, b.data, 16) >= 0); }
|
||||
};
|
||||
|
||||
static_assert(sizeof(SHA384Hash) == 48,"SHA384Hash contains unnecessary padding");
|
||||
static_assert(sizeof(UniqueID) == 16,"UniqueID contains unnecessary padding");
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
||||
|
|
704
core/CAPI.cpp
Normal file
704
core/CAPI.cpp
Normal file
|
@ -0,0 +1,704 @@
|
|||
/*
|
||||
* Copyright (c)2013-2020 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: 2025-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.
|
||||
*/
|
||||
/****/
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "Locator.hpp"
|
||||
#include "Certificate.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
// These macros make the idiom of passing buffers to outside code via the API work properly even
|
||||
// if the first address of Buf does not overlap with its data field, since the C++ standard does
|
||||
// not absolutely guarantee this.
|
||||
#define _ZT_PTRTOBUF(p) ((ZeroTier::Buf *)( ((uintptr_t)(p)) - ((uintptr_t)&(((ZeroTier::Buf *)0)->unsafeData[0])) ))
|
||||
#define _ZT_BUFTOPTR(b) ((void *)(&((b)->unsafeData[0])))
|
||||
|
||||
void *ZT_getBuffer()
|
||||
{
|
||||
// When external code requests a Buf, grab one from the pool (or freshly allocated)
|
||||
// and return it with its reference count left at zero. It's the responsibility of
|
||||
// external code to bring it back via freeBuffer() or one of the processX() calls.
|
||||
// When this occurs it's either sent back to the pool with Buf's delete operator or
|
||||
// wrapped in a SharedPtr<> to be passed into the core.
|
||||
try {
|
||||
return _ZT_BUFTOPTR(new ZeroTier::Buf());
|
||||
} catch (...) {
|
||||
return nullptr; // can only happen on out of memory condition
|
||||
}
|
||||
}
|
||||
|
||||
void ZT_freeBuffer(void *b)
|
||||
{
|
||||
if (b)
|
||||
delete _ZT_PTRTOBUF(b);
|
||||
}
|
||||
|
||||
struct p_queryResultBase
|
||||
{
|
||||
void (*freeFunction)(const void *);
|
||||
};
|
||||
|
||||
void ZT_freeQueryResult(const void *qr)
|
||||
{
|
||||
if ((qr) && (reinterpret_cast<const p_queryResultBase *>(qr)->freeFunction))
|
||||
reinterpret_cast<const p_queryResultBase *>(qr)->freeFunction(qr);
|
||||
}
|
||||
|
||||
void ZT_version(int *major, int *minor, int *revision, int *build)
|
||||
{
|
||||
if (major)
|
||||
*major = ZEROTIER_VERSION_MAJOR;
|
||||
if (minor)
|
||||
*minor = ZEROTIER_VERSION_MINOR;
|
||||
if (revision)
|
||||
*revision = ZEROTIER_VERSION_REVISION;
|
||||
if (build)
|
||||
*build = ZEROTIER_VERSION_BUILD;
|
||||
}
|
||||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
enum ZT_ResultCode ZT_Node_new(ZT_Node **node, void *uptr, void *tptr, const struct ZT_Node_Callbacks *callbacks, int64_t now)
|
||||
{
|
||||
*node = (ZT_Node *)0;
|
||||
try {
|
||||
*node = reinterpret_cast<ZT_Node *>(new ZeroTier::Node(uptr, tptr, callbacks, now));
|
||||
return ZT_RESULT_OK;
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (std::runtime_error &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
void ZT_Node_delete(ZT_Node *node, void *tPtr)
|
||||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->shutdown(tPtr);
|
||||
delete (reinterpret_cast<ZeroTier::Node *>(node));
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_processWirePacket(
|
||||
ZT_Node *node,
|
||||
void *tptr,
|
||||
int64_t now,
|
||||
int64_t localSocket,
|
||||
const struct sockaddr_storage *remoteAddress,
|
||||
const void *packetData,
|
||||
unsigned int packetLength,
|
||||
int isZtBuffer,
|
||||
volatile int64_t *nextBackgroundTaskDeadline)
|
||||
{
|
||||
try {
|
||||
ZeroTier::SharedPtr< ZeroTier::Buf > buf((isZtBuffer) ? _ZT_PTRTOBUF(packetData) : new ZeroTier::Buf(packetData, packetLength & ZT_BUF_MEM_MASK));
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->processWirePacket(tptr, now, localSocket, remoteAddress, buf, packetLength, nextBackgroundTaskDeadline);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
// "OK" since invalid packets are simply dropped, but the system is still up.
|
||||
// We should never make it here, but if we did that would be the interpretation.
|
||||
return ZT_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
|
||||
ZT_Node *node,
|
||||
void *tptr,
|
||||
int64_t now,
|
||||
uint64_t nwid,
|
||||
uint64_t sourceMac,
|
||||
uint64_t destMac,
|
||||
unsigned int etherType,
|
||||
unsigned int vlanId,
|
||||
const void *frameData,
|
||||
unsigned int frameLength,
|
||||
int isZtBuffer,
|
||||
volatile int64_t *nextBackgroundTaskDeadline)
|
||||
{
|
||||
try {
|
||||
ZeroTier::SharedPtr< ZeroTier::Buf > buf((isZtBuffer) ? _ZT_PTRTOBUF(frameData) : new ZeroTier::Buf(frameData, frameLength & ZT_BUF_MEM_MASK));
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->processVirtualNetworkFrame(tptr, now, nwid, sourceMac, destMac, etherType, vlanId, buf, frameLength, nextBackgroundTaskDeadline);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node, void *tptr, int64_t now, volatile int64_t *nextBackgroundTaskDeadline)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->processBackgroundTasks(tptr, now, nextBackgroundTaskDeadline);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_join(ZT_Node *node, uint64_t nwid, const ZT_Fingerprint *controllerFingerprint, void *uptr, void *tptr)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->join(nwid, controllerFingerprint, uptr, tptr);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_leave(ZT_Node *node, uint64_t nwid, void **uptr, void *tptr)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->leave(nwid, uptr, tptr);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_multicastSubscribe(ZT_Node *node, void *tptr, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->multicastSubscribe(tptr, nwid, multicastGroup, multicastAdi);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_multicastUnsubscribe(ZT_Node *node, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->multicastUnsubscribe(nwid, multicastGroup, multicastAdi);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t ZT_Node_address(ZT_Node *node)
|
||||
{
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->address();
|
||||
}
|
||||
|
||||
const ZT_Identity *ZT_Node_identity(ZT_Node *node)
|
||||
{
|
||||
return (const ZT_Identity *)(&(reinterpret_cast<ZeroTier::Node *>(node)->identity()));
|
||||
}
|
||||
|
||||
void ZT_Node_status(ZT_Node *node, ZT_NodeStatus *status)
|
||||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->status(status);
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
ZT_PeerList *ZT_Node_peers(ZT_Node *node)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->peers();
|
||||
} catch (...) {
|
||||
return (ZT_PeerList *)0;
|
||||
}
|
||||
}
|
||||
|
||||
ZT_VirtualNetworkConfig *ZT_Node_networkConfig(ZT_Node *node, uint64_t nwid)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->networkConfig(nwid);
|
||||
} catch (...) {
|
||||
return (ZT_VirtualNetworkConfig *)0;
|
||||
}
|
||||
}
|
||||
|
||||
ZT_VirtualNetworkList *ZT_Node_networks(ZT_Node *node)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->networks();
|
||||
} catch (...) {
|
||||
return (ZT_VirtualNetworkList *)0;
|
||||
}
|
||||
}
|
||||
|
||||
int ZT_Node_tryPeer(
|
||||
ZT_Node *node,
|
||||
void *tptr,
|
||||
const ZT_Fingerprint *fp,
|
||||
const ZT_Endpoint *endpoint,
|
||||
int retries)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->tryPeer(tptr, fp, endpoint, retries);
|
||||
} catch (...) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_CertificateError ZT_Node_addCertificate(
|
||||
ZT_Node *node,
|
||||
void *tptr,
|
||||
int64_t now,
|
||||
unsigned int localTrust,
|
||||
const ZT_Certificate *cert,
|
||||
const void *certData,
|
||||
unsigned int certSize)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->addCertificate(tptr, now, localTrust, cert, certData, certSize);
|
||||
} catch (...) {
|
||||
return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
}
|
||||
|
||||
ZT_SDK_API enum ZT_ResultCode ZT_Node_deleteCertificate(
|
||||
ZT_Node *node,
|
||||
void *tptr,
|
||||
const void *serialNo)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->deleteCertificate(tptr, serialNo);
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
ZT_SDK_API ZT_CertificateList *ZT_Node_listCertificates(ZT_Node *node)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->listCertificates();
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ZT_Node_setNetworkUserPtr(ZT_Node *node, uint64_t nwid, void *ptr)
|
||||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->setNetworkUserPtr(nwid, ptr);
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
void ZT_Node_setInterfaceAddresses(ZT_Node *node, const ZT_InterfaceAddress *addrs, unsigned int addrCount)
|
||||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->setInterfaceAddresses(addrs, addrCount);
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_addPeer(
|
||||
ZT_Node *node,
|
||||
void *tptr,
|
||||
const ZT_Identity *id)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->addPeer(tptr, id);
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
int ZT_Node_sendUserMessage(ZT_Node *node, void *tptr, uint64_t dest, uint64_t typeId, const void *data, unsigned int len)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->sendUserMessage(tptr, dest, typeId, data, len);
|
||||
} catch (...) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ZT_Node_setController(ZT_Node *node, void *networkControllerInstance)
|
||||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->setController(networkControllerInstance);
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
ZT_Locator *ZT_Locator_create(
|
||||
int64_t ts,
|
||||
const ZT_Endpoint *endpoints,
|
||||
const ZT_EndpointAttributes *endpointAttributes, // TODO: not used yet
|
||||
unsigned int endpointCount,
|
||||
const ZT_Identity *signer)
|
||||
{
|
||||
try {
|
||||
if ((ts <= 0) || (!endpoints) || (endpointCount == 0) || (!signer))
|
||||
return nullptr;
|
||||
ZeroTier::Locator *loc = new ZeroTier::Locator();
|
||||
for (unsigned int i = 0;i < endpointCount;++i)
|
||||
loc->add(reinterpret_cast< const ZeroTier::Endpoint * >(endpoints)[i], ZeroTier::Locator::EndpointAttributes::DEFAULT);
|
||||
if (!loc->sign(ts, *reinterpret_cast< const ZeroTier::Identity * >(signer))) {
|
||||
delete loc;
|
||||
return nullptr;
|
||||
}
|
||||
return reinterpret_cast<ZT_Locator *>(loc);
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ZT_Locator *ZT_Locator_fromString(const char *str)
|
||||
{
|
||||
try {
|
||||
if (!str)
|
||||
return nullptr;
|
||||
ZeroTier::Locator *loc = new ZeroTier::Locator();
|
||||
if (!loc->fromString(str)) {
|
||||
delete loc;
|
||||
return nullptr;
|
||||
}
|
||||
return reinterpret_cast<ZT_Locator *>(loc);
|
||||
} catch ( ... ) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ZT_Locator *ZT_Locator_unmarshal(
|
||||
const void *data,
|
||||
unsigned int len)
|
||||
{
|
||||
try {
|
||||
if ((!data) || (len == 0))
|
||||
return nullptr;
|
||||
ZeroTier::Locator *loc = new ZeroTier::Locator();
|
||||
if (loc->unmarshal(reinterpret_cast<const uint8_t *>(data), (int) len) <= 0) {
|
||||
delete loc;
|
||||
return nullptr;
|
||||
}
|
||||
return reinterpret_cast<ZT_Locator *>(loc);
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int ZT_Locator_marshal(const ZT_Locator *loc, void *buf, unsigned int bufSize)
|
||||
{
|
||||
if ((!loc) || (bufSize < ZT_LOCATOR_MARSHAL_SIZE_MAX))
|
||||
return -1;
|
||||
return reinterpret_cast<const ZeroTier::Locator *>(loc)->marshal(reinterpret_cast<uint8_t *>(buf), (int) bufSize);
|
||||
}
|
||||
|
||||
char *ZT_Locator_toString(
|
||||
const ZT_Locator *loc,
|
||||
char *buf,
|
||||
int capacity)
|
||||
{
|
||||
if ((!loc) || (capacity < ZT_LOCATOR_STRING_SIZE_MAX))
|
||||
return nullptr;
|
||||
return reinterpret_cast<const ZeroTier::Locator *>(loc)->toString(buf);
|
||||
}
|
||||
|
||||
const ZT_Fingerprint *ZT_Locator_fingerprint(const ZT_Locator *loc)
|
||||
{
|
||||
if (!loc)
|
||||
return nullptr;
|
||||
return (ZT_Fingerprint *) (&(reinterpret_cast<const ZeroTier::Locator *>(loc)->signer()));
|
||||
}
|
||||
|
||||
int64_t ZT_Locator_timestamp(const ZT_Locator *loc)
|
||||
{
|
||||
if (!loc)
|
||||
return 0;
|
||||
return reinterpret_cast<const ZeroTier::Locator *>(loc)->timestamp();
|
||||
}
|
||||
|
||||
unsigned int ZT_Locator_endpointCount(const ZT_Locator *loc)
|
||||
{
|
||||
return (loc) ? (unsigned int) (reinterpret_cast<const ZeroTier::Locator *>(loc)->endpoints().size()) : 0;
|
||||
}
|
||||
|
||||
const ZT_Endpoint *ZT_Locator_endpoint(const ZT_Locator *loc, const unsigned int ep)
|
||||
{
|
||||
if (!loc)
|
||||
return nullptr;
|
||||
if (ep >= (unsigned int) (reinterpret_cast<const ZeroTier::Locator *>(loc)->endpoints().size()))
|
||||
return nullptr;
|
||||
return reinterpret_cast<const ZT_Endpoint *>(&(reinterpret_cast<const ZeroTier::Locator *>(loc)->endpoints()[ep]));
|
||||
}
|
||||
|
||||
int ZT_Locator_verify(const ZT_Locator *loc, const ZT_Identity *signer)
|
||||
{
|
||||
if ((!loc) || (!signer))
|
||||
return 0;
|
||||
return reinterpret_cast<const ZeroTier::Locator *>(loc)->verify(*reinterpret_cast<const ZeroTier::Identity *>(signer)) ? 1 : 0;
|
||||
}
|
||||
|
||||
void ZT_Locator_delete(ZT_Locator *loc)
|
||||
{
|
||||
if (loc)
|
||||
delete reinterpret_cast<ZeroTier::Locator *>(loc);
|
||||
}
|
||||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
ZT_Identity *ZT_Identity_new(enum ZT_IdentityType type)
|
||||
{
|
||||
if ((type != ZT_IDENTITY_TYPE_C25519) && (type != ZT_IDENTITY_TYPE_P384))
|
||||
return nullptr;
|
||||
try {
|
||||
ZeroTier::Identity *const id = new ZeroTier::Identity();
|
||||
id->generate((ZeroTier::Identity::Type)type);
|
||||
return reinterpret_cast<ZT_Identity *>(id);
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ZT_Identity *ZT_Identity_fromString(const char *idStr)
|
||||
{
|
||||
if (!idStr)
|
||||
return nullptr;
|
||||
try {
|
||||
ZeroTier::Identity *const id = new ZeroTier::Identity();
|
||||
if (!id->fromString(idStr)) {
|
||||
delete id;
|
||||
return nullptr;
|
||||
}
|
||||
return reinterpret_cast<ZT_Identity *>(id);
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int ZT_Identity_validate(const ZT_Identity *id)
|
||||
{
|
||||
if (!id)
|
||||
return 0;
|
||||
return reinterpret_cast<const ZeroTier::Identity *>(id)->locallyValidate() ? 1 : 0;
|
||||
}
|
||||
|
||||
unsigned int ZT_Identity_sign(const ZT_Identity *id, const void *data, unsigned int len, void *signature, unsigned int signatureBufferLength)
|
||||
{
|
||||
if (!id)
|
||||
return 0;
|
||||
if (signatureBufferLength < ZT_SIGNATURE_BUFFER_SIZE)
|
||||
return 0;
|
||||
return reinterpret_cast<const ZeroTier::Identity *>(id)->sign(data, len, signature, signatureBufferLength);
|
||||
}
|
||||
|
||||
int ZT_Identity_verify(const ZT_Identity *id, const void *data, unsigned int len, const void *signature, unsigned int sigLen)
|
||||
{
|
||||
if ((!id) || (!signature) || (!sigLen))
|
||||
return 0;
|
||||
return reinterpret_cast<const ZeroTier::Identity *>(id)->verify(data, len, signature, sigLen) ? 1 : 0;
|
||||
}
|
||||
|
||||
enum ZT_IdentityType ZT_Identity_type(const ZT_Identity *id)
|
||||
{
|
||||
if (!id)
|
||||
return (ZT_IdentityType)0;
|
||||
return (enum ZT_IdentityType)reinterpret_cast<const ZeroTier::Identity *>(id)->type();
|
||||
}
|
||||
|
||||
char *ZT_Identity_toString(const ZT_Identity *id, char *buf, int capacity, int includePrivate)
|
||||
{
|
||||
if ((!id) || (!buf) || (capacity < ZT_IDENTITY_STRING_BUFFER_LENGTH))
|
||||
return nullptr;
|
||||
reinterpret_cast<const ZeroTier::Identity *>(id)->toString(includePrivate != 0, buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int ZT_Identity_hasPrivate(const ZT_Identity *id)
|
||||
{
|
||||
if (!id)
|
||||
return 0;
|
||||
return reinterpret_cast<const ZeroTier::Identity *>(id)->hasPrivate() ? 1 : 0;
|
||||
}
|
||||
|
||||
uint64_t ZT_Identity_address(const ZT_Identity *id)
|
||||
{
|
||||
if (!id)
|
||||
return 0;
|
||||
return reinterpret_cast<const ZeroTier::Identity *>(id)->address();
|
||||
}
|
||||
|
||||
const ZT_Fingerprint *ZT_Identity_fingerprint(const ZT_Identity *id)
|
||||
{
|
||||
if (!id)
|
||||
return nullptr;
|
||||
return &(reinterpret_cast<const ZeroTier::Identity *>(id)->fingerprint());
|
||||
}
|
||||
|
||||
void ZT_Identity_delete(ZT_Identity *id)
|
||||
{
|
||||
if (id)
|
||||
delete reinterpret_cast<ZeroTier::Identity *>(id);
|
||||
}
|
||||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
int ZT_Certificate_newSubjectUniqueId(
|
||||
enum ZT_CertificateUniqueIdType type,
|
||||
void *uniqueId,
|
||||
int *uniqueIdSize,
|
||||
void *uniqueIdPrivate,
|
||||
int *uniqueIdPrivateSize)
|
||||
{
|
||||
try {
|
||||
switch (type) {
|
||||
case ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384:
|
||||
if ((*uniqueIdSize < ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_SIZE) || (*uniqueIdPrivateSize < ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_PRIVATE_SIZE))
|
||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
*uniqueIdSize = ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_SIZE;
|
||||
*uniqueIdPrivateSize = ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_PRIVATE_SIZE;
|
||||
ZeroTier::Certificate::createSubjectUniqueId(reinterpret_cast<uint8_t *>(uniqueId), reinterpret_cast<uint8_t *>(uniqueIdPrivate));
|
||||
return ZT_RESULT_OK;
|
||||
}
|
||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
int ZT_Certificate_newCSR(
|
||||
const ZT_Certificate_Subject *subject,
|
||||
const void *uniqueId,
|
||||
int uniqueIdSize,
|
||||
const void *uniqueIdPrivate,
|
||||
int uniqueIdPrivateSize,
|
||||
void *csr,
|
||||
int *csrSize)
|
||||
{
|
||||
try {
|
||||
if (!subject)
|
||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
const ZeroTier::Vector< uint8_t > csrV(ZeroTier::Certificate::createCSR(*subject, uniqueId, uniqueIdSize, uniqueIdPrivate, uniqueIdPrivateSize));
|
||||
if ((int)csrV.size() > *csrSize)
|
||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
ZeroTier::Utils::copy(csr, csrV.data(), (unsigned int)csrV.size());
|
||||
*csrSize = (int)csrV.size();
|
||||
return ZT_RESULT_OK;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
int ZT_Certificate_sign(
|
||||
const ZT_Certificate *cert,
|
||||
const ZT_Identity *signer,
|
||||
void *signedCert,
|
||||
int *signedCertSize)
|
||||
{
|
||||
try {
|
||||
if (!cert)
|
||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
ZeroTier::Certificate c(*cert);
|
||||
if (!c.sign(*reinterpret_cast<const ZeroTier::Identity *>(signer)))
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
|
||||
const ZeroTier::Vector< uint8_t > enc(c.encode());
|
||||
if ((int)enc.size() > *signedCertSize)
|
||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
ZeroTier::Utils::copy(signedCert, enc.data(), (unsigned int)enc.size());
|
||||
*signedCertSize = (int)enc.size();
|
||||
|
||||
return ZT_RESULT_OK;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_CertificateError ZT_Certificate_decode(
|
||||
const ZT_Certificate **decodedCert,
|
||||
const void *cert,
|
||||
int certSize,
|
||||
int verify)
|
||||
{
|
||||
try {
|
||||
if ((!decodedCert) || (!cert) || (certSize <= 0))
|
||||
return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
|
||||
*decodedCert = nullptr;
|
||||
ZeroTier::Certificate *const c = new ZeroTier::Certificate();
|
||||
if (!c->decode(cert, certSize)) {
|
||||
delete c;
|
||||
return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
if (verify) {
|
||||
const ZT_CertificateError err = c->verify();
|
||||
if (err != ZT_CERTIFICATE_ERROR_NONE) {
|
||||
delete c;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
*decodedCert = c;
|
||||
return ZT_CERTIFICATE_ERROR_NONE;
|
||||
} catch (...) {
|
||||
return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
}
|
||||
|
||||
int ZT_Certificate_encode(
|
||||
const ZT_Certificate *cert,
|
||||
void *encoded,
|
||||
int *encodedSize)
|
||||
{
|
||||
try {
|
||||
if ((!cert) || (!encoded) || (!encodedSize))
|
||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
ZeroTier::Certificate c(*cert);
|
||||
ZeroTier::Vector< uint8_t > enc(c.encode());
|
||||
if ((int)enc.size() > *encodedSize)
|
||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
ZeroTier::Utils::copy(encoded, enc.data(), (unsigned int)enc.size());
|
||||
*encodedSize = (int)enc.size();
|
||||
return ZT_RESULT_OK;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_CertificateError ZT_Certificate_verify(const ZT_Certificate *cert)
|
||||
{
|
||||
try {
|
||||
if (!cert)
|
||||
return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
|
||||
return ZeroTier::Certificate(*cert).verify();
|
||||
} catch (...) {
|
||||
return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
}
|
||||
|
||||
const ZT_Certificate *ZT_Certificate_clone(const ZT_Certificate *cert)
|
||||
{
|
||||
try {
|
||||
if (!cert)
|
||||
return nullptr;
|
||||
return (const ZT_Certificate *)(new ZeroTier::Certificate(*cert));
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ZT_Certificate_delete(const ZT_Certificate *cert)
|
||||
{
|
||||
try {
|
||||
if (cert)
|
||||
delete (const ZeroTier::Certificate *)(cert);
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
} // extern "C"
|
|
@ -63,6 +63,7 @@ set(core_src
|
|||
AES.cpp
|
||||
Buf.cpp
|
||||
C25519.cpp
|
||||
CAPI.cpp
|
||||
CapabilityCredential.cpp
|
||||
Certificate.cpp
|
||||
Defaults.cpp
|
||||
|
|
|
@ -663,157 +663,3 @@ void Certificate::m_encodeSubject(const ZT_Certificate_Subject &s, Dictionary &d
|
|||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
extern "C" {
|
||||
|
||||
int ZT_Certificate_newSubjectUniqueId(
|
||||
enum ZT_CertificateUniqueIdType type,
|
||||
void *uniqueId,
|
||||
int *uniqueIdSize,
|
||||
void *uniqueIdPrivate,
|
||||
int *uniqueIdPrivateSize)
|
||||
{
|
||||
try {
|
||||
switch (type) {
|
||||
case ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384:
|
||||
if ((*uniqueIdSize < ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_SIZE) || (*uniqueIdPrivateSize < ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_PRIVATE_SIZE))
|
||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
*uniqueIdSize = ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_SIZE;
|
||||
*uniqueIdPrivateSize = ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_PRIVATE_SIZE;
|
||||
ZeroTier::Certificate::createSubjectUniqueId(reinterpret_cast<uint8_t *>(uniqueId), reinterpret_cast<uint8_t *>(uniqueIdPrivate));
|
||||
return ZT_RESULT_OK;
|
||||
}
|
||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
int ZT_Certificate_newCSR(
|
||||
const ZT_Certificate_Subject *subject,
|
||||
const void *uniqueId,
|
||||
int uniqueIdSize,
|
||||
const void *uniqueIdPrivate,
|
||||
int uniqueIdPrivateSize,
|
||||
void *csr,
|
||||
int *csrSize)
|
||||
{
|
||||
try {
|
||||
if (!subject)
|
||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
const ZeroTier::Vector< uint8_t > csrV(ZeroTier::Certificate::createCSR(*subject, uniqueId, uniqueIdSize, uniqueIdPrivate, uniqueIdPrivateSize));
|
||||
if ((int)csrV.size() > *csrSize)
|
||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
ZeroTier::Utils::copy(csr, csrV.data(), (unsigned int)csrV.size());
|
||||
*csrSize = (int)csrV.size();
|
||||
return ZT_RESULT_OK;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
int ZT_Certificate_sign(
|
||||
const ZT_Certificate *cert,
|
||||
const ZT_Identity *signer,
|
||||
void *signedCert,
|
||||
int *signedCertSize)
|
||||
{
|
||||
try {
|
||||
if (!cert)
|
||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
ZeroTier::Certificate c(*cert);
|
||||
if (!c.sign(*reinterpret_cast<const ZeroTier::Identity *>(signer)))
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
|
||||
const ZeroTier::Vector< uint8_t > enc(c.encode());
|
||||
if ((int)enc.size() > *signedCertSize)
|
||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
ZeroTier::Utils::copy(signedCert, enc.data(), (unsigned int)enc.size());
|
||||
*signedCertSize = (int)enc.size();
|
||||
|
||||
return ZT_RESULT_OK;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_CertificateError ZT_Certificate_decode(
|
||||
const ZT_Certificate **decodedCert,
|
||||
const void *cert,
|
||||
int certSize,
|
||||
int verify)
|
||||
{
|
||||
try {
|
||||
if ((!decodedCert) || (!cert) || (certSize <= 0))
|
||||
return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
|
||||
*decodedCert = nullptr;
|
||||
ZeroTier::Certificate *const c = new ZeroTier::Certificate();
|
||||
if (!c->decode(cert, certSize)) {
|
||||
delete c;
|
||||
return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
if (verify) {
|
||||
const ZT_CertificateError err = c->verify();
|
||||
if (err != ZT_CERTIFICATE_ERROR_NONE) {
|
||||
delete c;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
*decodedCert = c;
|
||||
return ZT_CERTIFICATE_ERROR_NONE;
|
||||
} catch (...) {
|
||||
return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
}
|
||||
|
||||
int ZT_Certificate_encode(
|
||||
const ZT_Certificate *cert,
|
||||
void *encoded,
|
||||
int *encodedSize)
|
||||
{
|
||||
try {
|
||||
if ((!cert) || (!encoded) || (!encodedSize))
|
||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
ZeroTier::Certificate c(*cert);
|
||||
ZeroTier::Vector< uint8_t > enc(c.encode());
|
||||
if ((int)enc.size() > *encodedSize)
|
||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
ZeroTier::Utils::copy(encoded, enc.data(), (unsigned int)enc.size());
|
||||
*encodedSize = (int)enc.size();
|
||||
return ZT_RESULT_OK;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_CertificateError ZT_Certificate_verify(const ZT_Certificate *cert)
|
||||
{
|
||||
try {
|
||||
if (!cert)
|
||||
return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
|
||||
return ZeroTier::Certificate(*cert).verify();
|
||||
} catch (...) {
|
||||
return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
}
|
||||
|
||||
const ZT_Certificate *ZT_Certificate_clone(const ZT_Certificate *cert)
|
||||
{
|
||||
try {
|
||||
if (!cert)
|
||||
return nullptr;
|
||||
return (const ZT_Certificate *)(new ZeroTier::Certificate(*cert));
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ZT_Certificate_delete(const ZT_Certificate *cert)
|
||||
{
|
||||
try {
|
||||
if (cert)
|
||||
delete (const ZeroTier::Certificate *)(cert);
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -542,101 +542,3 @@ void Identity::m_computeHash()
|
|||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
extern "C" {
|
||||
|
||||
ZT_Identity *ZT_Identity_new(enum ZT_IdentityType type)
|
||||
{
|
||||
if ((type != ZT_IDENTITY_TYPE_C25519) && (type != ZT_IDENTITY_TYPE_P384))
|
||||
return nullptr;
|
||||
try {
|
||||
ZeroTier::Identity *const id = new ZeroTier::Identity();
|
||||
id->generate((ZeroTier::Identity::Type)type);
|
||||
return reinterpret_cast<ZT_Identity *>(id);
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ZT_Identity *ZT_Identity_fromString(const char *idStr)
|
||||
{
|
||||
if (!idStr)
|
||||
return nullptr;
|
||||
try {
|
||||
ZeroTier::Identity *const id = new ZeroTier::Identity();
|
||||
if (!id->fromString(idStr)) {
|
||||
delete id;
|
||||
return nullptr;
|
||||
}
|
||||
return reinterpret_cast<ZT_Identity *>(id);
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int ZT_Identity_validate(const ZT_Identity *id)
|
||||
{
|
||||
if (!id)
|
||||
return 0;
|
||||
return reinterpret_cast<const ZeroTier::Identity *>(id)->locallyValidate() ? 1 : 0;
|
||||
}
|
||||
|
||||
unsigned int ZT_Identity_sign(const ZT_Identity *id, const void *data, unsigned int len, void *signature, unsigned int signatureBufferLength)
|
||||
{
|
||||
if (!id)
|
||||
return 0;
|
||||
if (signatureBufferLength < ZT_SIGNATURE_BUFFER_SIZE)
|
||||
return 0;
|
||||
return reinterpret_cast<const ZeroTier::Identity *>(id)->sign(data, len, signature, signatureBufferLength);
|
||||
}
|
||||
|
||||
int ZT_Identity_verify(const ZT_Identity *id, const void *data, unsigned int len, const void *signature, unsigned int sigLen)
|
||||
{
|
||||
if ((!id) || (!signature) || (!sigLen))
|
||||
return 0;
|
||||
return reinterpret_cast<const ZeroTier::Identity *>(id)->verify(data, len, signature, sigLen) ? 1 : 0;
|
||||
}
|
||||
|
||||
enum ZT_IdentityType ZT_Identity_type(const ZT_Identity *id)
|
||||
{
|
||||
if (!id)
|
||||
return (ZT_IdentityType)0;
|
||||
return (enum ZT_IdentityType)reinterpret_cast<const ZeroTier::Identity *>(id)->type();
|
||||
}
|
||||
|
||||
char *ZT_Identity_toString(const ZT_Identity *id, char *buf, int capacity, int includePrivate)
|
||||
{
|
||||
if ((!id) || (!buf) || (capacity < ZT_IDENTITY_STRING_BUFFER_LENGTH))
|
||||
return nullptr;
|
||||
reinterpret_cast<const ZeroTier::Identity *>(id)->toString(includePrivate != 0, buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int ZT_Identity_hasPrivate(const ZT_Identity *id)
|
||||
{
|
||||
if (!id)
|
||||
return 0;
|
||||
return reinterpret_cast<const ZeroTier::Identity *>(id)->hasPrivate() ? 1 : 0;
|
||||
}
|
||||
|
||||
uint64_t ZT_Identity_address(const ZT_Identity *id)
|
||||
{
|
||||
if (!id)
|
||||
return 0;
|
||||
return reinterpret_cast<const ZeroTier::Identity *>(id)->address();
|
||||
}
|
||||
|
||||
const ZT_Fingerprint *ZT_Identity_fingerprint(const ZT_Identity *id)
|
||||
{
|
||||
if (!id)
|
||||
return nullptr;
|
||||
return &(reinterpret_cast<const ZeroTier::Identity *>(id)->fingerprint());
|
||||
}
|
||||
|
||||
ZT_SDK_API void ZT_Identity_delete(ZT_Identity *id)
|
||||
{
|
||||
if (id)
|
||||
delete reinterpret_cast<ZeroTier::Identity *>(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
119
core/Locator.cpp
119
core/Locator.cpp
|
@ -204,122 +204,3 @@ void Locator::m_sortEndpoints() noexcept
|
|||
{ std::sort(m_endpoints.begin(), m_endpoints.end(), p_SortByEndpoint()); }
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
extern "C" {
|
||||
|
||||
ZT_Locator *ZT_Locator_create(
|
||||
int64_t ts,
|
||||
const ZT_Endpoint *endpoints,
|
||||
const ZT_EndpointAttributes *endpointAttributes, // TODO: not used yet
|
||||
unsigned int endpointCount,
|
||||
const ZT_Identity *signer)
|
||||
{
|
||||
try {
|
||||
if ((ts <= 0) || (!endpoints) || (endpointCount == 0) || (!signer))
|
||||
return nullptr;
|
||||
ZeroTier::Locator *loc = new ZeroTier::Locator();
|
||||
for (unsigned int i = 0;i < endpointCount;++i)
|
||||
loc->add(reinterpret_cast< const ZeroTier::Endpoint * >(endpoints)[i], ZeroTier::Locator::EndpointAttributes::DEFAULT);
|
||||
if (!loc->sign(ts, *reinterpret_cast< const ZeroTier::Identity * >(signer))) {
|
||||
delete loc;
|
||||
return nullptr;
|
||||
}
|
||||
return reinterpret_cast<ZT_Locator *>(loc);
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ZT_Locator *ZT_Locator_fromString(const char *str)
|
||||
{
|
||||
try {
|
||||
if (!str)
|
||||
return nullptr;
|
||||
ZeroTier::Locator *loc = new ZeroTier::Locator();
|
||||
if (!loc->fromString(str)) {
|
||||
delete loc;
|
||||
return nullptr;
|
||||
}
|
||||
return reinterpret_cast<ZT_Locator *>(loc);
|
||||
} catch ( ... ) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ZT_Locator *ZT_Locator_unmarshal(
|
||||
const void *data,
|
||||
unsigned int len)
|
||||
{
|
||||
try {
|
||||
if ((!data) || (len == 0))
|
||||
return nullptr;
|
||||
ZeroTier::Locator *loc = new ZeroTier::Locator();
|
||||
if (loc->unmarshal(reinterpret_cast<const uint8_t *>(data), (int) len) <= 0) {
|
||||
delete loc;
|
||||
return nullptr;
|
||||
}
|
||||
return reinterpret_cast<ZT_Locator *>(loc);
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int ZT_Locator_marshal(const ZT_Locator *loc, void *buf, unsigned int bufSize)
|
||||
{
|
||||
if ((!loc) || (bufSize < ZT_LOCATOR_MARSHAL_SIZE_MAX))
|
||||
return -1;
|
||||
return reinterpret_cast<const ZeroTier::Locator *>(loc)->marshal(reinterpret_cast<uint8_t *>(buf), (int) bufSize);
|
||||
}
|
||||
|
||||
char *ZT_Locator_toString(
|
||||
const ZT_Locator *loc,
|
||||
char *buf,
|
||||
int capacity)
|
||||
{
|
||||
if ((!loc) || (capacity < ZT_LOCATOR_STRING_SIZE_MAX))
|
||||
return nullptr;
|
||||
return reinterpret_cast<const ZeroTier::Locator *>(loc)->toString(buf);
|
||||
}
|
||||
|
||||
const ZT_Fingerprint *ZT_Locator_fingerprint(const ZT_Locator *loc)
|
||||
{
|
||||
if (!loc)
|
||||
return nullptr;
|
||||
return (ZT_Fingerprint *) (&(reinterpret_cast<const ZeroTier::Locator *>(loc)->signer()));
|
||||
}
|
||||
|
||||
int64_t ZT_Locator_timestamp(const ZT_Locator *loc)
|
||||
{
|
||||
if (!loc)
|
||||
return 0;
|
||||
return reinterpret_cast<const ZeroTier::Locator *>(loc)->timestamp();
|
||||
}
|
||||
|
||||
unsigned int ZT_Locator_endpointCount(const ZT_Locator *loc)
|
||||
{
|
||||
return (loc) ? (unsigned int) (reinterpret_cast<const ZeroTier::Locator *>(loc)->endpoints().size()) : 0;
|
||||
}
|
||||
|
||||
const ZT_Endpoint *ZT_Locator_endpoint(const ZT_Locator *loc, const unsigned int ep)
|
||||
{
|
||||
if (!loc)
|
||||
return nullptr;
|
||||
if (ep >= (unsigned int) (reinterpret_cast<const ZeroTier::Locator *>(loc)->endpoints().size()))
|
||||
return nullptr;
|
||||
return reinterpret_cast<const ZT_Endpoint *>(&(reinterpret_cast<const ZeroTier::Locator *>(loc)->endpoints()[ep]));
|
||||
}
|
||||
|
||||
int ZT_Locator_verify(const ZT_Locator *loc, const ZT_Identity *signer)
|
||||
{
|
||||
if ((!loc) || (!signer))
|
||||
return 0;
|
||||
return reinterpret_cast<const ZeroTier::Locator *>(loc)->verify(*reinterpret_cast<const ZeroTier::Identity *>(signer)) ? 1 : 0;
|
||||
}
|
||||
|
||||
void ZT_Locator_delete(ZT_Locator *loc)
|
||||
{
|
||||
if (loc)
|
||||
delete reinterpret_cast<ZeroTier::Locator *>(loc);
|
||||
}
|
||||
|
||||
} // C API functions
|
||||
|
|
|
@ -264,6 +264,8 @@ private:
|
|||
uint64_t m_mac;
|
||||
};
|
||||
|
||||
static_assert(sizeof(MAC) == sizeof(uint64_t),"MAC contains unnecessary padding");
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
||||
|
|
317
core/Node.cpp
317
core/Node.cpp
|
@ -840,320 +840,3 @@ void Node::ncSendError(uint64_t nwid, uint64_t requestPacketId, const Address &d
|
|||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
// C API --------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern "C" {
|
||||
|
||||
// These macros make the idiom of passing buffers to outside code via the API work properly even
|
||||
// if the first address of Buf does not overlap with its data field, since the C++ standard does
|
||||
// not absolutely guarantee this.
|
||||
#define _ZT_PTRTOBUF(p) ((ZeroTier::Buf *)( ((uintptr_t)(p)) - ((uintptr_t)&(((ZeroTier::Buf *)0)->unsafeData[0])) ))
|
||||
#define _ZT_BUFTOPTR(b) ((void *)(&((b)->unsafeData[0])))
|
||||
|
||||
void *ZT_getBuffer()
|
||||
{
|
||||
// When external code requests a Buf, grab one from the pool (or freshly allocated)
|
||||
// and return it with its reference count left at zero. It's the responsibility of
|
||||
// external code to bring it back via freeBuffer() or one of the processX() calls.
|
||||
// When this occurs it's either sent back to the pool with Buf's delete operator or
|
||||
// wrapped in a SharedPtr<> to be passed into the core.
|
||||
try {
|
||||
return _ZT_BUFTOPTR(new ZeroTier::Buf());
|
||||
} catch (...) {
|
||||
return nullptr; // can only happen on out of memory condition
|
||||
}
|
||||
}
|
||||
|
||||
void ZT_freeBuffer(void *b)
|
||||
{
|
||||
if (b)
|
||||
delete _ZT_PTRTOBUF(b);
|
||||
}
|
||||
|
||||
struct p_queryResultBase
|
||||
{
|
||||
void (*freeFunction)(const void *);
|
||||
};
|
||||
|
||||
void ZT_freeQueryResult(const void *qr)
|
||||
{
|
||||
if ((qr) && (reinterpret_cast<const p_queryResultBase *>(qr)->freeFunction))
|
||||
reinterpret_cast<const p_queryResultBase *>(qr)->freeFunction(qr);
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_new(ZT_Node **node, void *uptr, void *tptr, const struct ZT_Node_Callbacks *callbacks, int64_t now)
|
||||
{
|
||||
*node = (ZT_Node *)0;
|
||||
try {
|
||||
*node = reinterpret_cast<ZT_Node *>(new ZeroTier::Node(uptr, tptr, callbacks, now));
|
||||
return ZT_RESULT_OK;
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (std::runtime_error &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
void ZT_Node_delete(ZT_Node *node, void *tPtr)
|
||||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->shutdown(tPtr);
|
||||
delete (reinterpret_cast<ZeroTier::Node *>(node));
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_processWirePacket(
|
||||
ZT_Node *node,
|
||||
void *tptr,
|
||||
int64_t now,
|
||||
int64_t localSocket,
|
||||
const struct sockaddr_storage *remoteAddress,
|
||||
const void *packetData,
|
||||
unsigned int packetLength,
|
||||
int isZtBuffer,
|
||||
volatile int64_t *nextBackgroundTaskDeadline)
|
||||
{
|
||||
try {
|
||||
ZeroTier::SharedPtr< ZeroTier::Buf > buf((isZtBuffer) ? _ZT_PTRTOBUF(packetData) : new ZeroTier::Buf(packetData, packetLength & ZT_BUF_MEM_MASK));
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->processWirePacket(tptr, now, localSocket, remoteAddress, buf, packetLength, nextBackgroundTaskDeadline);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
// "OK" since invalid packets are simply dropped, but the system is still up.
|
||||
// We should never make it here, but if we did that would be the interpretation.
|
||||
return ZT_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
|
||||
ZT_Node *node,
|
||||
void *tptr,
|
||||
int64_t now,
|
||||
uint64_t nwid,
|
||||
uint64_t sourceMac,
|
||||
uint64_t destMac,
|
||||
unsigned int etherType,
|
||||
unsigned int vlanId,
|
||||
const void *frameData,
|
||||
unsigned int frameLength,
|
||||
int isZtBuffer,
|
||||
volatile int64_t *nextBackgroundTaskDeadline)
|
||||
{
|
||||
try {
|
||||
ZeroTier::SharedPtr< ZeroTier::Buf > buf((isZtBuffer) ? _ZT_PTRTOBUF(frameData) : new ZeroTier::Buf(frameData, frameLength & ZT_BUF_MEM_MASK));
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->processVirtualNetworkFrame(tptr, now, nwid, sourceMac, destMac, etherType, vlanId, buf, frameLength, nextBackgroundTaskDeadline);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node, void *tptr, int64_t now, volatile int64_t *nextBackgroundTaskDeadline)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->processBackgroundTasks(tptr, now, nextBackgroundTaskDeadline);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_join(ZT_Node *node, uint64_t nwid, const ZT_Fingerprint *controllerFingerprint, void *uptr, void *tptr)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->join(nwid, controllerFingerprint, uptr, tptr);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_leave(ZT_Node *node, uint64_t nwid, void **uptr, void *tptr)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->leave(nwid, uptr, tptr);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_multicastSubscribe(ZT_Node *node, void *tptr, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->multicastSubscribe(tptr, nwid, multicastGroup, multicastAdi);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_multicastUnsubscribe(ZT_Node *node, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->multicastUnsubscribe(nwid, multicastGroup, multicastAdi);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t ZT_Node_address(ZT_Node *node)
|
||||
{
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->address();
|
||||
}
|
||||
|
||||
const ZT_Identity *ZT_Node_identity(ZT_Node *node)
|
||||
{
|
||||
return (const ZT_Identity *)(&(reinterpret_cast<ZeroTier::Node *>(node)->identity()));
|
||||
}
|
||||
|
||||
void ZT_Node_status(ZT_Node *node, ZT_NodeStatus *status)
|
||||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->status(status);
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
ZT_PeerList *ZT_Node_peers(ZT_Node *node)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->peers();
|
||||
} catch (...) {
|
||||
return (ZT_PeerList *)0;
|
||||
}
|
||||
}
|
||||
|
||||
ZT_VirtualNetworkConfig *ZT_Node_networkConfig(ZT_Node *node, uint64_t nwid)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->networkConfig(nwid);
|
||||
} catch (...) {
|
||||
return (ZT_VirtualNetworkConfig *)0;
|
||||
}
|
||||
}
|
||||
|
||||
ZT_VirtualNetworkList *ZT_Node_networks(ZT_Node *node)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->networks();
|
||||
} catch (...) {
|
||||
return (ZT_VirtualNetworkList *)0;
|
||||
}
|
||||
}
|
||||
|
||||
int ZT_Node_tryPeer(
|
||||
ZT_Node *node,
|
||||
void *tptr,
|
||||
const ZT_Fingerprint *fp,
|
||||
const ZT_Endpoint *endpoint,
|
||||
int retries)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->tryPeer(tptr, fp, endpoint, retries);
|
||||
} catch (...) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
enum ZT_CertificateError ZT_Node_addCertificate(
|
||||
ZT_Node *node,
|
||||
void *tptr,
|
||||
int64_t now,
|
||||
unsigned int localTrust,
|
||||
const ZT_Certificate *cert,
|
||||
const void *certData,
|
||||
unsigned int certSize)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->addCertificate(tptr, now, localTrust, cert, certData, certSize);
|
||||
} catch (...) {
|
||||
return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
}
|
||||
|
||||
ZT_SDK_API enum ZT_ResultCode ZT_Node_deleteCertificate(
|
||||
ZT_Node *node,
|
||||
void *tptr,
|
||||
const void *serialNo)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->deleteCertificate(tptr, serialNo);
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
ZT_SDK_API ZT_CertificateList *ZT_Node_listCertificates(ZT_Node *node)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->listCertificates();
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ZT_Node_setNetworkUserPtr(ZT_Node *node, uint64_t nwid, void *ptr)
|
||||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->setNetworkUserPtr(nwid, ptr);
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
void ZT_Node_setInterfaceAddresses(ZT_Node *node, const ZT_InterfaceAddress *addrs, unsigned int addrCount)
|
||||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->setInterfaceAddresses(addrs, addrCount);
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_addPeer(
|
||||
ZT_Node *node,
|
||||
void *tptr,
|
||||
const ZT_Identity *id)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->addPeer(tptr, id);
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
int ZT_Node_sendUserMessage(ZT_Node *node, void *tptr, uint64_t dest, uint64_t typeId, const void *data, unsigned int len)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->sendUserMessage(tptr, dest, typeId, data, len);
|
||||
} catch (...) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ZT_Node_setController(ZT_Node *node, void *networkControllerInstance)
|
||||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->setController(networkControllerInstance);
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
void ZT_version(int *major, int *minor, int *revision, int *build)
|
||||
{
|
||||
if (major)
|
||||
*major = ZEROTIER_VERSION_MAJOR;
|
||||
if (minor)
|
||||
*minor = ZEROTIER_VERSION_MINOR;
|
||||
if (revision)
|
||||
*revision = ZEROTIER_VERSION_REVISION;
|
||||
if (build)
|
||||
*build = ZEROTIER_VERSION_BUILD;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
25
core/OS.hpp
25
core/OS.hpp
|
@ -115,14 +115,6 @@
|
|||
#include <mmintrin.h>
|
||||
#endif
|
||||
|
||||
#if (defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(ZT_ARCH_ARM_HAS_NEON))
|
||||
#ifndef ZT_ARCH_ARM_HAS_NEON
|
||||
#define ZT_ARCH_ARM_HAS_NEON 1
|
||||
#endif
|
||||
#include <arm_neon.h>
|
||||
/*#include <arm_acle.h>*/
|
||||
#endif
|
||||
|
||||
#if defined(ZT_ARCH_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)
|
||||
#define ZT_ARCH_X86 1
|
||||
#endif
|
||||
|
@ -133,6 +125,20 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(ZT_ARCH_ARM_HAS_NEON))
|
||||
#if (defined(__APPLE__) && !defined(__LP64__)) || (defined(__ANDROID__) && defined(__arm__))
|
||||
#ifdef ZT_ARCH_ARM_HAS_NEON
|
||||
#undef ZT_ARCH_ARM_HAS_NEON
|
||||
#endif
|
||||
#else
|
||||
#ifndef ZT_ARCH_ARM_HAS_NEON
|
||||
#define ZT_ARCH_ARM_HAS_NEON 1
|
||||
#endif
|
||||
#include <arm_neon.h>
|
||||
/*#include <arm_acle.h>*/
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__SIZEOF_INT128__) || ((defined(ZT_ARCH_X64) || defined(__aarch64__)) && defined(__GNUC__))
|
||||
#ifdef __SIZEOF_INT128__
|
||||
#define ZT_HAVE_UINT128 1
|
||||
|
@ -216,10 +222,9 @@ typedef unsigned uint128_t __attribute__((mode(TI)));
|
|||
#endif
|
||||
#endif
|
||||
|
||||
// Macro to print very verbose tracing information to standard error.
|
||||
#define ZT_VA_ARGS(...) , ##__VA_ARGS__
|
||||
#define ZT_DEBUG_SPEW
|
||||
#ifdef ZT_DEBUG_SPEW
|
||||
#define ZT_VA_ARGS(...) , ##__VA_ARGS__
|
||||
#define ZT_SPEW(f,...) fprintf(stderr,"%s:%d(%s): " f ZT_EOL_S,__FILE__,__LINE__,__FUNCTION__ ZT_VA_ARGS(__VA_ARGS__))
|
||||
#else
|
||||
#define ZT_SPEW(f,...)
|
||||
|
|
|
@ -194,7 +194,6 @@ private:
|
|||
SharedPtr< const Certificate > certificate;
|
||||
unsigned int localTrust;
|
||||
};
|
||||
|
||||
Map< SHA384Hash, p_CertEntry > m_certs;
|
||||
Map< SHA384Hash, p_CertEntry > m_certsBySubjectUniqueID;
|
||||
Map< Fingerprint, Map< SharedPtr< const Certificate >, unsigned int > > m_certsBySubjectIdentity;
|
||||
|
|
|
@ -38,9 +38,21 @@ namespace ZeroTier {
|
|||
|
||||
namespace Utils {
|
||||
|
||||
#ifdef ZT_ARCH_ARM_HAS_NEON
|
||||
#ifdef ZT_ARCH_ARM_HAS_NEON /****************************************************************************************/
|
||||
ARMCapabilities::ARMCapabilities() noexcept
|
||||
{
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
this->aes = true;
|
||||
this->crc32 = true;
|
||||
this->pmull = true;
|
||||
this->sha1 = true;
|
||||
this->sha2 = true;
|
||||
|
||||
#else
|
||||
|
||||
#ifdef __LINUX__
|
||||
#ifdef HWCAP2_AES
|
||||
if (sizeof(void *) == 4) {
|
||||
const long hwcaps2 = getauxval(AT_HWCAP2);
|
||||
|
@ -60,13 +72,16 @@ ARMCapabilities::ARMCapabilities() noexcept
|
|||
#ifdef HWCAP2_AES
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
const ARMCapabilities ARMCAP;
|
||||
#endif
|
||||
|
||||
#ifdef ZT_ARCH_X64
|
||||
#endif /*************************************************************************************************************/
|
||||
|
||||
#ifdef ZT_ARCH_X64 /*************************************************************************************************/
|
||||
CPUIDRegisters::CPUIDRegisters() noexcept
|
||||
{
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
|
@ -113,7 +128,7 @@ CPUIDRegisters::CPUIDRegisters() noexcept
|
|||
}
|
||||
|
||||
const CPUIDRegisters CPUID;
|
||||
#endif
|
||||
#endif /*************************************************************************************************************/
|
||||
|
||||
const std::bad_alloc BadAllocException;
|
||||
const std::out_of_range OutOfRangeException("access out of range");
|
||||
|
@ -131,19 +146,18 @@ bool secureEq(const void *a, const void *b, unsigned int len) noexcept
|
|||
|
||||
void burn(volatile void *ptr, unsigned int len)
|
||||
{
|
||||
static volatile uintptr_t foo = 0;
|
||||
Utils::zero((void *)ptr, len);
|
||||
// This line is present to force the compiler not to optimize out the memory
|
||||
// zeroing operation above, as burn() is used to erase secrets and other
|
||||
// sensitive data.
|
||||
if ((reinterpret_cast<volatile uint8_t *>(ptr)[0] | reinterpret_cast<volatile uint8_t *>(ptr)[len-1]) != 0)
|
||||
burn(ptr, len);
|
||||
// Force compiler not to optimize this function out by taking a volatile
|
||||
// parameter and also updating a volatile variable.
|
||||
foo += (uintptr_t)len ^ (uintptr_t)reinterpret_cast<volatile uint8_t *>(ptr)[0];
|
||||
}
|
||||
|
||||
static unsigned long _Utils_itoa(unsigned long n, char *s)
|
||||
static unsigned long s_decimalRecursive(unsigned long n, char *s)
|
||||
{
|
||||
if (n == 0)
|
||||
return 0;
|
||||
unsigned long pos = _Utils_itoa(n / 10, s);
|
||||
unsigned long pos = s_decimalRecursive(n / 10, s);
|
||||
if (pos >= 22) // sanity check,should be impossible
|
||||
pos = 22;
|
||||
s[pos] = (char)('0' + (n % 10));
|
||||
|
@ -157,7 +171,7 @@ char *decimal(unsigned long n, char s[24]) noexcept
|
|||
s[1] = (char)0;
|
||||
return s;
|
||||
}
|
||||
s[_Utils_itoa(n, s)] = (char)0;
|
||||
s[s_decimalRecursive(n, s)] = (char)0;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -353,7 +367,7 @@ void getSecureRandom(void *const buf, unsigned int bytes) noexcept
|
|||
|
||||
uint64_t getSecureRandomU64() noexcept
|
||||
{
|
||||
uint64_t tmp = 0;
|
||||
uint64_t tmp;
|
||||
getSecureRandom(&tmp, sizeof(tmp));
|
||||
return tmp;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue