mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-25 08:27:39 +02:00
Big core refactor to create a CallContext to carry several annoying state variables through the call chain. Also remove some warnings.
This commit is contained in:
parent
0f4d18c4ed
commit
89e9eb755e
65 changed files with 1572 additions and 1494 deletions
|
@ -82,6 +82,7 @@ if(NOT PACKAGE_STATIC)
|
|||
-Wno-deprecated
|
||||
-Wno-unused-function
|
||||
-Wno-format
|
||||
-Wno-attributes
|
||||
$<$<CONFIG:DEBUG>:-g>
|
||||
$<$<CONFIG:DEBUG>:-O0>
|
||||
$<$<CONFIG:RELEASE>:-O3>
|
||||
|
@ -125,6 +126,7 @@ if(NOT PACKAGE_STATIC)
|
|||
-Wall
|
||||
-Wno-deprecated
|
||||
-Wno-unused-function
|
||||
-Wno-attributes
|
||||
-mmacosx-version-min=${MACOS_VERSION_MIN}
|
||||
$<$<CONFIG:DEBUG>:-g>
|
||||
$<$<CONFIG:DEBUG>:-O0>
|
||||
|
@ -157,6 +159,7 @@ if(NOT PACKAGE_STATIC)
|
|||
-Wno-deprecated
|
||||
-Wno-unused-function
|
||||
-Wno-format
|
||||
-Wno-attributes
|
||||
$<$<CONFIG:DEBUG>:-g>
|
||||
$<$<CONFIG:DEBUG>:-O0>
|
||||
$<$<CONFIG:RELEASE>:-O3>
|
||||
|
|
61
core/Buf.cpp
61
core/Buf.cpp
|
@ -12,15 +12,12 @@
|
|||
/****/
|
||||
|
||||
#include "Buf.hpp"
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#define sched_yield() Sleep(0)
|
||||
#endif
|
||||
#include "Spinlock.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
static std::atomic<uintptr_t> s_pool(0);
|
||||
static std::atomic<long> s_allocated(0);
|
||||
static std::atomic< uintptr_t > s_pool(0);
|
||||
static std::atomic< long > s_allocated(0);
|
||||
|
||||
// uintptr_max can never be a valid pointer, so use it to indicate that s_pool is locked (very short duration spinlock)
|
||||
#define ZT_ATOMIC_PTR_LOCKED (~((uintptr_t)0))
|
||||
|
@ -29,45 +26,44 @@ void *Buf::operator new(std::size_t sz)
|
|||
{
|
||||
uintptr_t bb;
|
||||
for (;;) {
|
||||
bb = s_pool.exchange(ZT_ATOMIC_PTR_LOCKED);
|
||||
if (bb != ZT_ATOMIC_PTR_LOCKED)
|
||||
bb = s_pool.exchange(ZT_ATOMIC_PTR_LOCKED, std::memory_order_acquire);
|
||||
if (likely(bb != ZT_ATOMIC_PTR_LOCKED))
|
||||
break;
|
||||
sched_yield();
|
||||
Spinlock::pause();
|
||||
}
|
||||
|
||||
Buf *b;
|
||||
if (bb) {
|
||||
s_pool.store(((Buf *) bb)->__nextInPool);
|
||||
b = (Buf *) bb;
|
||||
s_pool.store(((Buf *)bb)->__nextInPool.load(std::memory_order_relaxed), std::memory_order_release);
|
||||
b = (Buf *)bb;
|
||||
} else {
|
||||
s_pool.store(0);
|
||||
b = (Buf *) malloc(sz);
|
||||
s_pool.store(0, std::memory_order_release);
|
||||
b = (Buf *)malloc(sz);
|
||||
if (!b)
|
||||
throw Utils::BadAllocException;
|
||||
++s_allocated;
|
||||
s_allocated.fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
b->__refCount.store(0);
|
||||
return (void *) b;
|
||||
b->__refCount.store(0, std::memory_order_relaxed);
|
||||
return (void *)b;
|
||||
}
|
||||
|
||||
void Buf::operator delete(void *ptr)
|
||||
{
|
||||
if (ptr) {
|
||||
if (s_allocated.load() > ZT_BUF_MAX_POOL_SIZE) {
|
||||
--s_allocated;
|
||||
if (s_allocated.load(std::memory_order_relaxed) > ZT_BUF_MAX_POOL_SIZE) {
|
||||
free(ptr);
|
||||
} else {
|
||||
uintptr_t bb;
|
||||
for (;;) {
|
||||
bb = s_pool.exchange(ZT_ATOMIC_PTR_LOCKED);
|
||||
if (bb != ZT_ATOMIC_PTR_LOCKED)
|
||||
bb = s_pool.exchange(ZT_ATOMIC_PTR_LOCKED, std::memory_order_acquire);
|
||||
if (likely(bb != ZT_ATOMIC_PTR_LOCKED))
|
||||
break;
|
||||
sched_yield();
|
||||
Spinlock::pause();
|
||||
}
|
||||
|
||||
((Buf *) ptr)->__nextInPool.store(bb);
|
||||
s_pool.store((uintptr_t) ptr);
|
||||
((Buf *)ptr)->__nextInPool.store(bb, std::memory_order_relaxed);
|
||||
s_pool.store((uintptr_t)ptr, std::memory_order_release);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,24 +72,23 @@ void Buf::freePool() noexcept
|
|||
{
|
||||
uintptr_t bb;
|
||||
for (;;) {
|
||||
bb = s_pool.exchange(ZT_ATOMIC_PTR_LOCKED);
|
||||
if (bb != ZT_ATOMIC_PTR_LOCKED)
|
||||
bb = s_pool.exchange(ZT_ATOMIC_PTR_LOCKED, std::memory_order_acquire);
|
||||
if (likely(bb != ZT_ATOMIC_PTR_LOCKED))
|
||||
break;
|
||||
sched_yield();
|
||||
Spinlock::pause();
|
||||
}
|
||||
s_pool.store(0);
|
||||
|
||||
s_pool.store(0, std::memory_order_release);
|
||||
|
||||
while (bb != 0) {
|
||||
const uintptr_t next = ((Buf *) bb)->__nextInPool;
|
||||
--s_allocated;
|
||||
free((void *) bb);
|
||||
const uintptr_t next = ((Buf *)bb)->__nextInPool.load(std::memory_order_relaxed);
|
||||
s_allocated.fetch_sub(1, std::memory_order_relaxed);
|
||||
free((void *)bb);
|
||||
bb = next;
|
||||
}
|
||||
}
|
||||
|
||||
long Buf::poolAllocated() noexcept
|
||||
{
|
||||
return s_allocated.load();
|
||||
}
|
||||
{ return s_allocated.load(std::memory_order_relaxed); }
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
|
64
core/Buf.hpp
64
core/Buf.hpp
|
@ -286,7 +286,7 @@ public:
|
|||
/**
|
||||
* Set all memory to zero
|
||||
*/
|
||||
ZT_INLINE void clear() noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void clear() noexcept
|
||||
{
|
||||
Utils::zero< ZT_BUF_MEM_SIZE >(unsafeData);
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ public:
|
|||
* @param ii Index value-result parameter (incremented by 1)
|
||||
* @return Byte (undefined on overflow)
|
||||
*/
|
||||
ZT_INLINE uint8_t rI8(int &ii) const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE uint8_t rI8(int &ii) const noexcept
|
||||
{
|
||||
const int s = ii++;
|
||||
return unsafeData[(unsigned int)s & ZT_BUF_MEM_MASK];
|
||||
|
@ -309,7 +309,7 @@ public:
|
|||
* @param ii Index value-result parameter (incremented by 2)
|
||||
* @return Integer (undefined on overflow)
|
||||
*/
|
||||
ZT_INLINE uint16_t rI16(int &ii) const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE uint16_t rI16(int &ii) const noexcept
|
||||
{
|
||||
const unsigned int s = (unsigned int)ii & ZT_BUF_MEM_MASK;
|
||||
ii += 2;
|
||||
|
@ -328,7 +328,7 @@ public:
|
|||
* @param ii Index value-result parameter (incremented by 4)
|
||||
* @return Integer (undefined on overflow)
|
||||
*/
|
||||
ZT_INLINE uint32_t rI32(int &ii) const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE uint32_t rI32(int &ii) const noexcept
|
||||
{
|
||||
const unsigned int s = (unsigned int)ii & ZT_BUF_MEM_MASK;
|
||||
ii += 4;
|
||||
|
@ -349,7 +349,7 @@ public:
|
|||
* @param ii Index value-result parameter (incremented by 8)
|
||||
* @return Integer (undefined on overflow)
|
||||
*/
|
||||
ZT_INLINE uint64_t rI64(int &ii) const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE uint64_t rI64(int &ii) const noexcept
|
||||
{
|
||||
const unsigned int s = (unsigned int)ii & ZT_BUF_MEM_MASK;
|
||||
ii += 8;
|
||||
|
@ -384,7 +384,7 @@ public:
|
|||
* @return Bytes read or a negative value on unmarshal error (passed from object) or overflow
|
||||
*/
|
||||
template< typename T >
|
||||
ZT_INLINE int rO(int &ii, T &obj) const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE int rO(int &ii, T &obj) const noexcept
|
||||
{
|
||||
if (likely(ii < ZT_BUF_MEM_SIZE)) {
|
||||
int ms = obj.unmarshal(unsafeData + ii, ZT_BUF_MEM_SIZE - ii);
|
||||
|
@ -406,7 +406,7 @@ public:
|
|||
* @param bufSize Capacity of buffer in bytes
|
||||
* @return Pointer to buf or NULL on overflow or error
|
||||
*/
|
||||
ZT_INLINE char *rS(int &ii, char *const buf, const unsigned int bufSize) const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE char *rS(int &ii, char *const buf, const unsigned int bufSize) const noexcept
|
||||
{
|
||||
const char *const s = (const char *)(unsafeData + ii);
|
||||
const int sii = ii;
|
||||
|
@ -435,7 +435,7 @@ public:
|
|||
* @param ii Index value-result parameter (incremented by length of string)
|
||||
* @return Pointer to null-terminated C-style string or NULL on overflow or error
|
||||
*/
|
||||
ZT_INLINE const char *rSnc(int &ii) const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE const char *rSnc(int &ii) const noexcept
|
||||
{
|
||||
const char *const s = (const char *)(unsafeData + ii);
|
||||
while (ii < ZT_BUF_MEM_SIZE) {
|
||||
|
@ -456,7 +456,7 @@ public:
|
|||
* @param len Length of buffer
|
||||
* @return Pointer to data or NULL on overflow or error
|
||||
*/
|
||||
ZT_INLINE uint8_t *rB(int &ii, void *const bytes, const unsigned int len) const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE uint8_t *rB(int &ii, void *const bytes, const unsigned int len) const noexcept
|
||||
{
|
||||
if (likely(((ii += (int)len) <= ZT_BUF_MEM_SIZE))) {
|
||||
Utils::copy(bytes, unsafeData + ii, len);
|
||||
|
@ -478,7 +478,7 @@ public:
|
|||
* @param len Length of data field to obtain a pointer to
|
||||
* @return Pointer to field or NULL on overflow
|
||||
*/
|
||||
ZT_INLINE const uint8_t *rBnc(int &ii, unsigned int len) const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE const uint8_t *rBnc(int &ii, unsigned int len) const noexcept
|
||||
{
|
||||
const uint8_t *const b = unsafeData + ii;
|
||||
return ((ii += (int)len) <= ZT_BUF_MEM_SIZE) ? b : nullptr;
|
||||
|
@ -491,7 +491,7 @@ public:
|
|||
* @return Value
|
||||
*/
|
||||
template< unsigned int I >
|
||||
ZT_INLINE uint8_t lI8() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE uint8_t lI8() const noexcept
|
||||
{
|
||||
static_assert(I < ZT_BUF_MEM_SIZE, "overflow");
|
||||
return unsafeData[I];
|
||||
|
@ -504,7 +504,7 @@ public:
|
|||
* @return Value
|
||||
*/
|
||||
template< unsigned int I >
|
||||
ZT_INLINE uint8_t lI16() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE uint8_t lI16() const noexcept
|
||||
{
|
||||
static_assert((I + 1) < ZT_BUF_MEM_SIZE, "overflow");
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
|
@ -523,7 +523,7 @@ public:
|
|||
* @return Value
|
||||
*/
|
||||
template< unsigned int I >
|
||||
ZT_INLINE uint8_t lI32() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE uint8_t lI32() const noexcept
|
||||
{
|
||||
static_assert((I + 3) < ZT_BUF_MEM_SIZE, "overflow");
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
|
@ -544,7 +544,7 @@ public:
|
|||
* @return Value
|
||||
*/
|
||||
template< unsigned int I >
|
||||
ZT_INLINE uint8_t lI64() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE uint8_t lI64() const noexcept
|
||||
{
|
||||
static_assert((I + 7) < ZT_BUF_MEM_SIZE, "overflow");
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
|
@ -569,7 +569,7 @@ public:
|
|||
* will not necessarily result in a 'true' return from readOverflow(). It does
|
||||
* however subject 'ii' to soft bounds masking like the gI??() methods.
|
||||
*/
|
||||
ZT_INLINE uint8_t lI8(const int ii) const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE uint8_t lI8(const int ii) const noexcept
|
||||
{
|
||||
return unsafeData[(unsigned int)ii & ZT_BUF_MEM_MASK];
|
||||
}
|
||||
|
@ -581,7 +581,7 @@ public:
|
|||
* will not necessarily result in a 'true' return from readOverflow(). It does
|
||||
* however subject 'ii' to soft bounds masking like the gI??() methods.
|
||||
*/
|
||||
ZT_INLINE uint16_t lI16(const int ii) const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE uint16_t lI16(const int ii) const noexcept
|
||||
{
|
||||
const unsigned int s = (unsigned int)ii & ZT_BUF_MEM_MASK;
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
|
@ -600,7 +600,7 @@ public:
|
|||
* will not necessarily result in a 'true' return from readOverflow(). It does
|
||||
* however subject 'ii' to soft bounds masking like the gI??() methods.
|
||||
*/
|
||||
ZT_INLINE uint32_t lI32(const int ii) const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE uint32_t lI32(const int ii) const noexcept
|
||||
{
|
||||
const unsigned int s = (unsigned int)ii & ZT_BUF_MEM_MASK;
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
|
@ -621,7 +621,7 @@ public:
|
|||
* will not necessarily result in a 'true' return from readOverflow(). It does
|
||||
* however subject 'ii' to soft bounds masking like the gI??() methods.
|
||||
*/
|
||||
ZT_INLINE uint8_t lI64(const int ii) const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE uint8_t lI64(const int ii) const noexcept
|
||||
{
|
||||
const unsigned int s = (unsigned int)ii & ZT_BUF_MEM_MASK;
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
|
@ -645,7 +645,7 @@ public:
|
|||
* @param ii Index value-result parameter (incremented by 1)
|
||||
* @param n Byte
|
||||
*/
|
||||
ZT_INLINE void wI8(int &ii, const uint8_t n) noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void wI8(int &ii, const uint8_t n) noexcept
|
||||
{
|
||||
const int s = ii++;
|
||||
unsafeData[(unsigned int)s & ZT_BUF_MEM_MASK] = n;
|
||||
|
@ -657,7 +657,7 @@ public:
|
|||
* @param ii Index value-result parameter (incremented by 2)
|
||||
* @param n Integer
|
||||
*/
|
||||
ZT_INLINE void wI16(int &ii, const uint16_t n) noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void wI16(int &ii, const uint16_t n) noexcept
|
||||
{
|
||||
const unsigned int s = ((unsigned int)ii) & ZT_BUF_MEM_MASK;
|
||||
ii += 2;
|
||||
|
@ -675,7 +675,7 @@ public:
|
|||
* @param ii Index value-result parameter (incremented by 4)
|
||||
* @param n Integer
|
||||
*/
|
||||
ZT_INLINE void wI32(int &ii, const uint32_t n) noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void wI32(int &ii, const uint32_t n) noexcept
|
||||
{
|
||||
const unsigned int s = ((unsigned int)ii) & ZT_BUF_MEM_MASK;
|
||||
ii += 4;
|
||||
|
@ -695,7 +695,7 @@ public:
|
|||
* @param ii Index value-result parameter (incremented by 8)
|
||||
* @param n Integer
|
||||
*/
|
||||
ZT_INLINE void wI64(int &ii, const uint64_t n) noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void wI64(int &ii, const uint64_t n) noexcept
|
||||
{
|
||||
const unsigned int s = ((unsigned int)ii) & ZT_BUF_MEM_MASK;
|
||||
ii += 8;
|
||||
|
@ -721,7 +721,7 @@ public:
|
|||
* @param t Object to write
|
||||
*/
|
||||
template< typename T >
|
||||
ZT_INLINE void wO(int &ii, T &t) noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void wO(int &ii, T &t) noexcept
|
||||
{
|
||||
const int s = ii;
|
||||
if (likely((s + T::marshalSizeMax()) <= ZT_BUF_MEM_SIZE)) {
|
||||
|
@ -739,7 +739,7 @@ public:
|
|||
* @param ii Index value-result parameter (incremented by length of string)
|
||||
* @param s String to write (writes an empty string if this is NULL)
|
||||
*/
|
||||
ZT_INLINE void wS(int &ii, const char *s) noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void wS(int &ii, const char *s) noexcept
|
||||
{
|
||||
if (s) {
|
||||
char c;
|
||||
|
@ -759,7 +759,7 @@ public:
|
|||
* @param bytes Bytes to write
|
||||
* @param len Size of data in bytes
|
||||
*/
|
||||
ZT_INLINE void wB(int &ii, const void *const bytes, const unsigned int len) noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void wB(int &ii, const void *const bytes, const unsigned int len) noexcept
|
||||
{
|
||||
const int s = ii;
|
||||
if (likely((ii += (int)len) <= ZT_BUF_MEM_SIZE))
|
||||
|
@ -772,7 +772,7 @@ public:
|
|||
* @param ii Index value-result parameter (incremented by len)
|
||||
* @param len Number of zero bytes to write
|
||||
*/
|
||||
ZT_INLINE void wZ(int &ii, const unsigned int len) noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void wZ(int &ii, const unsigned int len) noexcept
|
||||
{
|
||||
const int s = ii;
|
||||
if (likely((ii += (int)len) <= ZT_BUF_MEM_SIZE))
|
||||
|
@ -785,7 +785,7 @@ public:
|
|||
* @param ii Index value-result parameter (incremented by len)
|
||||
* @param len Number of random bytes to write
|
||||
*/
|
||||
ZT_INLINE void wR(int &ii, const unsigned int len) noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void wR(int &ii, const unsigned int len) noexcept
|
||||
{
|
||||
const int s = ii;
|
||||
if (likely((ii += (int)len) <= ZT_BUF_MEM_SIZE))
|
||||
|
@ -795,7 +795,7 @@ public:
|
|||
/**
|
||||
* Store a byte without advancing the index
|
||||
*/
|
||||
ZT_INLINE void sI8(const int ii, const uint8_t n) noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void sI8(const int ii, const uint8_t n) noexcept
|
||||
{
|
||||
unsafeData[(unsigned int)ii & ZT_BUF_MEM_MASK] = n;
|
||||
}
|
||||
|
@ -803,7 +803,7 @@ public:
|
|||
/**
|
||||
* Store an integer without advancing the index
|
||||
*/
|
||||
ZT_INLINE void sI16(const int ii, const uint16_t n) noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void sI16(const int ii, const uint16_t n) noexcept
|
||||
{
|
||||
const unsigned int s = ((unsigned int)ii) & ZT_BUF_MEM_MASK;
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
|
@ -817,7 +817,7 @@ public:
|
|||
/**
|
||||
* Store an integer without advancing the index
|
||||
*/
|
||||
ZT_INLINE void sI32(const int ii, const uint32_t n) noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void sI32(const int ii, const uint32_t n) noexcept
|
||||
{
|
||||
const unsigned int s = ((unsigned int)ii) & ZT_BUF_MEM_MASK;
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
|
@ -833,7 +833,7 @@ public:
|
|||
/**
|
||||
* Store an integer without advancing the index
|
||||
*/
|
||||
ZT_INLINE void sI64(const int ii, const uint64_t n) noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void sI64(const int ii, const uint64_t n) noexcept
|
||||
{
|
||||
const unsigned int s = ((unsigned int)ii) & ZT_BUF_MEM_MASK;
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
|
@ -853,7 +853,7 @@ public:
|
|||
/**
|
||||
* @return Capacity of this buffer (usable size of data.bytes)
|
||||
*/
|
||||
static constexpr unsigned int capacity() noexcept
|
||||
ZT_MAYBE_UNUSED static constexpr unsigned int capacity() noexcept
|
||||
{ return ZT_BUF_MEM_SIZE; }
|
||||
|
||||
private:
|
||||
|
|
336
core/CAPI.cpp
336
core/CAPI.cpp
|
@ -19,6 +19,7 @@
|
|||
#include "InetAddress.hpp"
|
||||
#include "VL1.hpp"
|
||||
#include "VL2.hpp"
|
||||
#include "CallContext.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
@ -30,7 +31,7 @@ extern "C" {
|
|||
#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()
|
||||
ZT_MAYBE_UNUSED 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
|
||||
|
@ -44,7 +45,7 @@ void *ZT_getBuffer()
|
|||
}
|
||||
}
|
||||
|
||||
void ZT_freeBuffer(void *b)
|
||||
ZT_MAYBE_UNUSED void ZT_freeBuffer(void *b)
|
||||
{
|
||||
if (b)
|
||||
delete ZT_PTRTOBUF(b);
|
||||
|
@ -55,13 +56,13 @@ struct p_queryResultBase
|
|||
void (*freeFunction)(const void *);
|
||||
};
|
||||
|
||||
void ZT_freeQueryResult(const void *qr)
|
||||
ZT_MAYBE_UNUSED 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)
|
||||
ZT_MAYBE_UNUSED void ZT_version(int *major, int *minor, int *revision, int *build)
|
||||
{
|
||||
if (major)
|
||||
*major = ZEROTIER_VERSION_MAJOR;
|
||||
|
@ -75,11 +76,18 @@ void ZT_version(int *major, int *minor, int *revision, int *build)
|
|||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
enum ZT_ResultCode ZT_Node_new(ZT_Node **node, void *uptr, void *tptr, const struct ZT_Node_Callbacks *callbacks, int64_t now)
|
||||
ZT_MAYBE_UNUSED enum ZT_ResultCode ZT_Node_new(
|
||||
ZT_Node **node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
void *uptr,
|
||||
const struct ZT_Node_Callbacks *callbacks)
|
||||
{
|
||||
*node = nullptr;
|
||||
try {
|
||||
*node = reinterpret_cast<ZT_Node *>(new ZeroTier::Node(uptr, tptr, callbacks, now));
|
||||
ZeroTier::CallContext cc(clock, ticks, tptr);
|
||||
*node = reinterpret_cast<ZT_Node *>(new ZeroTier::Node(uptr, callbacks, cc));
|
||||
return ZT_RESULT_OK;
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -90,18 +98,24 @@ enum ZT_ResultCode ZT_Node_new(ZT_Node **node, void *uptr, void *tptr, const str
|
|||
}
|
||||
}
|
||||
|
||||
void ZT_Node_delete(ZT_Node *node, void *tPtr)
|
||||
ZT_MAYBE_UNUSED void ZT_Node_delete(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr)
|
||||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->shutdown(tPtr);
|
||||
ZeroTier::CallContext cc(clock, ticks, tptr);
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->shutdown(cc);
|
||||
delete (reinterpret_cast<ZeroTier::Node *>(node));
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_processWirePacket(
|
||||
ZT_MAYBE_UNUSED enum ZT_ResultCode ZT_Node_processWirePacket(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
int64_t now,
|
||||
int64_t localSocket,
|
||||
const ZT_InetAddress *remoteAddress,
|
||||
const void *packetData,
|
||||
|
@ -110,8 +124,9 @@ enum ZT_ResultCode ZT_Node_processWirePacket(
|
|||
volatile int64_t *nextBackgroundTaskDeadline)
|
||||
{
|
||||
try {
|
||||
ZeroTier::CallContext cc(clock, ticks, tptr);
|
||||
ZeroTier::SharedPtr< ZeroTier::Buf > buf((isZtBuffer) ? ZT_PTRTOBUF(packetData) : new ZeroTier::Buf(packetData, packetLength & ZT_BUF_MEM_MASK));
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->RR->vl1->onRemotePacket(tptr, localSocket, *ZeroTier::asInetAddress(remoteAddress), buf, packetLength);
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->RR->vl1->onRemotePacket(cc, localSocket, *ZeroTier::asInetAddress(remoteAddress), buf, packetLength);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
|
@ -121,10 +136,11 @@ enum ZT_ResultCode ZT_Node_processWirePacket(
|
|||
return ZT_RESULT_OK;
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
|
||||
ZT_MAYBE_UNUSED enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
int64_t now,
|
||||
uint64_t nwid,
|
||||
uint64_t sourceMac,
|
||||
uint64_t destMac,
|
||||
|
@ -136,10 +152,11 @@ enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
|
|||
volatile int64_t *nextBackgroundTaskDeadline)
|
||||
{
|
||||
try {
|
||||
ZeroTier::CallContext cc(clock, ticks, tptr);
|
||||
ZeroTier::SharedPtr< ZeroTier::Network > network(reinterpret_cast<ZeroTier::Node *>(node)->RR->networks->get(nwid));
|
||||
if (likely(network)) {
|
||||
ZeroTier::SharedPtr< ZeroTier::Buf > buf((isZtBuffer) ? ZT_PTRTOBUF(frameData) : new ZeroTier::Buf(frameData, frameLength & ZT_BUF_MEM_MASK));
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->RR->vl2->onLocalEthernet(tptr, network, ZeroTier::MAC(sourceMac), ZeroTier::MAC(destMac), etherType, vlanId, buf, frameLength);
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->RR->vl2->onLocalEthernet(cc, network, ZeroTier::MAC(sourceMac), ZeroTier::MAC(destMac), etherType, vlanId, buf, frameLength);
|
||||
return ZT_RESULT_OK;
|
||||
} else {
|
||||
return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
|
||||
|
@ -151,10 +168,16 @@ enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
|
|||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node, void *tptr, int64_t now, volatile int64_t *nextBackgroundTaskDeadline)
|
||||
ZT_MAYBE_UNUSED enum ZT_ResultCode ZT_Node_processBackgroundTasks(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
volatile int64_t *nextBackgroundTaskDeadline)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->processBackgroundTasks(tptr, now, nextBackgroundTaskDeadline);
|
||||
ZeroTier::CallContext cc(clock, ticks, tptr);
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->processBackgroundTasks(cc, nextBackgroundTaskDeadline);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
|
@ -162,10 +185,18 @@ enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node, void *tptr, int
|
|||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_join(ZT_Node *node, uint64_t nwid, const ZT_Fingerprint *controllerFingerprint, void *uptr, void *tptr)
|
||||
ZT_MAYBE_UNUSED enum ZT_ResultCode ZT_Node_join(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
void *uptr,
|
||||
uint64_t nwid,
|
||||
const ZT_Fingerprint *controllerFingerprint)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->join(nwid, controllerFingerprint, uptr, tptr);
|
||||
ZeroTier::CallContext cc(clock, ticks, tptr);
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->join(nwid, controllerFingerprint, uptr, cc);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
|
@ -173,10 +204,17 @@ enum ZT_ResultCode ZT_Node_join(ZT_Node *node, uint64_t nwid, const ZT_Fingerpri
|
|||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_leave(ZT_Node *node, uint64_t nwid, void **uptr, void *tptr)
|
||||
ZT_MAYBE_UNUSED enum ZT_ResultCode ZT_Node_leave(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
void **uptr,
|
||||
uint64_t nwid)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->leave(nwid, uptr, tptr);
|
||||
ZeroTier::CallContext cc(clock, ticks, tptr);
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->leave(nwid, uptr, cc);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
|
@ -184,10 +222,18 @@ enum ZT_ResultCode ZT_Node_leave(ZT_Node *node, uint64_t nwid, void **uptr, void
|
|||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_multicastSubscribe(ZT_Node *node, void *tptr, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi)
|
||||
ZT_MAYBE_UNUSED enum ZT_ResultCode ZT_Node_multicastSubscribe(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
uint64_t nwid,
|
||||
uint64_t multicastGroup,
|
||||
unsigned long multicastAdi)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->multicastSubscribe(tptr, nwid, multicastGroup, multicastAdi);
|
||||
ZeroTier::CallContext cc(clock, ticks, tptr);
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->multicastSubscribe(cc, nwid, multicastGroup, multicastAdi);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
|
@ -195,10 +241,18 @@ enum ZT_ResultCode ZT_Node_multicastSubscribe(ZT_Node *node, void *tptr, uint64_
|
|||
}
|
||||
}
|
||||
|
||||
enum ZT_ResultCode ZT_Node_multicastUnsubscribe(ZT_Node *node, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi)
|
||||
ZT_MAYBE_UNUSED enum ZT_ResultCode ZT_Node_multicastUnsubscribe(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
uint64_t nwid,
|
||||
uint64_t multicastGroup,
|
||||
unsigned long multicastAdi)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->multicastUnsubscribe(nwid, multicastGroup, multicastAdi);
|
||||
ZeroTier::CallContext cc(clock, ticks, tptr);
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->multicastUnsubscribe(cc, nwid, multicastGroup, multicastAdi);
|
||||
} catch (std::bad_alloc &exc) {
|
||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch (...) {
|
||||
|
@ -206,29 +260,44 @@ enum ZT_ResultCode ZT_Node_multicastUnsubscribe(ZT_Node *node, uint64_t nwid, ui
|
|||
}
|
||||
}
|
||||
|
||||
uint64_t ZT_Node_address(ZT_Node *node)
|
||||
ZT_MAYBE_UNUSED uint64_t ZT_Node_address(ZT_Node *node)
|
||||
{ return reinterpret_cast<ZeroTier::Node *>(node)->RR->identity.address().toInt(); }
|
||||
|
||||
const ZT_Identity *ZT_Node_identity(ZT_Node *node)
|
||||
ZT_MAYBE_UNUSED 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)
|
||||
ZT_MAYBE_UNUSED void ZT_Node_status(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
ZT_NodeStatus *status)
|
||||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->status(status);
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
ZT_PeerList *ZT_Node_peers(ZT_Node *node)
|
||||
ZT_MAYBE_UNUSED ZT_PeerList *ZT_Node_peers(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->peers();
|
||||
ZeroTier::CallContext cc(clock, ticks, tptr);
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->peers(cc);
|
||||
} catch (...) {
|
||||
return (ZT_PeerList *)0;
|
||||
}
|
||||
}
|
||||
|
||||
ZT_VirtualNetworkConfig *ZT_Node_networkConfig(ZT_Node *node, uint64_t nwid)
|
||||
ZT_MAYBE_UNUSED ZT_VirtualNetworkConfig *ZT_Node_networkConfig(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
uint64_t nwid)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->networkConfig(nwid);
|
||||
|
@ -237,7 +306,7 @@ ZT_VirtualNetworkConfig *ZT_Node_networkConfig(ZT_Node *node, uint64_t nwid)
|
|||
}
|
||||
}
|
||||
|
||||
ZT_VirtualNetworkList *ZT_Node_networks(ZT_Node *node)
|
||||
ZT_MAYBE_UNUSED ZT_VirtualNetworkList *ZT_Node_networks(ZT_Node *node)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->networks();
|
||||
|
@ -246,49 +315,67 @@ ZT_VirtualNetworkList *ZT_Node_networks(ZT_Node *node)
|
|||
}
|
||||
}
|
||||
|
||||
int ZT_Node_tryPeer(
|
||||
ZT_MAYBE_UNUSED void ZT_Node_setNetworkUserPtr(
|
||||
ZT_Node *node,
|
||||
void *tptr,
|
||||
const ZT_Fingerprint *fp,
|
||||
const ZT_Endpoint *endpoint,
|
||||
int retries)
|
||||
uint64_t nwid,
|
||||
void *ptr)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->tryPeer(tptr, fp, endpoint, retries);
|
||||
} catch (...) {
|
||||
return 0;
|
||||
}
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->setNetworkUserPtr(nwid, ptr);
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
enum ZT_CertificateError ZT_Node_addCertificate(
|
||||
ZT_MAYBE_UNUSED void ZT_Node_setInterfaceAddresses(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
const ZT_InterfaceAddress *addrs,
|
||||
unsigned int addrCount)
|
||||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->setInterfaceAddresses(addrs, addrCount);
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
ZT_MAYBE_UNUSED enum ZT_CertificateError ZT_Node_addCertificate(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
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);
|
||||
ZeroTier::CallContext cc(clock, ticks, tptr);
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->addCertificate(cc, localTrust, cert, certData, certSize);
|
||||
} catch (...) {
|
||||
return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
}
|
||||
|
||||
ZT_SDK_API enum ZT_ResultCode ZT_Node_deleteCertificate(
|
||||
ZT_MAYBE_UNUSED enum ZT_ResultCode ZT_Node_deleteCertificate(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
const void *serialNo)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->deleteCertificate(tptr, serialNo);
|
||||
ZeroTier::CallContext cc(clock, ticks, tptr);
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->deleteCertificate(cc, serialNo);
|
||||
} catch (...) {
|
||||
return ZT_RESULT_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
ZT_SDK_API ZT_CertificateList *ZT_Node_listCertificates(ZT_Node *node)
|
||||
ZT_MAYBE_UNUSED ZT_CertificateList *ZT_Node_listCertificates(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr)
|
||||
{
|
||||
try {
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->listCertificates();
|
||||
|
@ -297,42 +384,27 @@ ZT_SDK_API ZT_CertificateList *ZT_Node_listCertificates(ZT_Node *node)
|
|||
}
|
||||
}
|
||||
|
||||
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_MAYBE_UNUSED int ZT_Node_sendUserMessage(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
const ZT_Identity *id)
|
||||
uint64_t dest,
|
||||
uint64_t typeId,
|
||||
const void *data,
|
||||
unsigned int len)
|
||||
{
|
||||
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);
|
||||
ZeroTier::CallContext cc(clock, ticks, tptr);
|
||||
return reinterpret_cast<ZeroTier::Node *>(node)->sendUserMessage(cc, dest, typeId, data, len);
|
||||
} catch (...) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ZT_Node_setController(ZT_Node *node, void *networkControllerInstance)
|
||||
ZT_MAYBE_UNUSED void ZT_Node_setController(
|
||||
ZT_Node *node,
|
||||
void *networkControllerInstance)
|
||||
{
|
||||
try {
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->setController(networkControllerInstance);
|
||||
|
@ -341,20 +413,20 @@ void ZT_Node_setController(ZT_Node *node, void *networkControllerInstance)
|
|||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
ZT_Locator *ZT_Locator_create(
|
||||
int64_t ts,
|
||||
ZT_MAYBE_UNUSED ZT_Locator *ZT_Locator_create(
|
||||
int64_t rev,
|
||||
const ZT_Endpoint *endpoints,
|
||||
const ZT_EndpointAttributes *endpointAttributes, // TODO: not used yet
|
||||
const ZT_EndpointAttributes *endpointAttributes,
|
||||
unsigned int endpointCount,
|
||||
const ZT_Identity *signer)
|
||||
{
|
||||
try {
|
||||
if ((ts <= 0) || (!endpoints) || (endpointCount == 0) || (!signer))
|
||||
if ((!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))) {
|
||||
if (!loc->sign(rev, *reinterpret_cast< const ZeroTier::Identity * >(signer))) {
|
||||
delete loc;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -364,7 +436,7 @@ ZT_Locator *ZT_Locator_create(
|
|||
}
|
||||
}
|
||||
|
||||
ZT_Locator *ZT_Locator_fromString(const char *str)
|
||||
ZT_MAYBE_UNUSED ZT_Locator *ZT_Locator_fromString(const char *str)
|
||||
{
|
||||
try {
|
||||
if (!str)
|
||||
|
@ -380,7 +452,7 @@ ZT_Locator *ZT_Locator_fromString(const char *str)
|
|||
}
|
||||
}
|
||||
|
||||
ZT_Locator *ZT_Locator_unmarshal(
|
||||
ZT_MAYBE_UNUSED ZT_Locator *ZT_Locator_unmarshal(
|
||||
const void *data,
|
||||
unsigned int len)
|
||||
{
|
||||
|
@ -398,14 +470,14 @@ ZT_Locator *ZT_Locator_unmarshal(
|
|||
}
|
||||
}
|
||||
|
||||
int ZT_Locator_marshal(const ZT_Locator *loc, void *buf, unsigned int bufSize)
|
||||
ZT_MAYBE_UNUSED 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), false);
|
||||
}
|
||||
|
||||
char *ZT_Locator_toString(
|
||||
ZT_MAYBE_UNUSED char *ZT_Locator_toString(
|
||||
const ZT_Locator *loc,
|
||||
char *buf,
|
||||
int capacity)
|
||||
|
@ -415,26 +487,24 @@ char *ZT_Locator_toString(
|
|||
return reinterpret_cast<const ZeroTier::Locator *>(loc)->toString(buf);
|
||||
}
|
||||
|
||||
const ZT_Fingerprint *ZT_Locator_fingerprint(const ZT_Locator *loc)
|
||||
ZT_MAYBE_UNUSED 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)
|
||||
ZT_MAYBE_UNUSED int64_t ZT_Locator_revision(const ZT_Locator *loc)
|
||||
{
|
||||
if (!loc)
|
||||
return 0;
|
||||
return reinterpret_cast<const ZeroTier::Locator *>(loc)->timestamp();
|
||||
return reinterpret_cast<const ZeroTier::Locator *>(loc)->revision();
|
||||
}
|
||||
|
||||
unsigned int ZT_Locator_endpointCount(const ZT_Locator *loc)
|
||||
{
|
||||
return (loc) ? (unsigned int) (reinterpret_cast<const ZeroTier::Locator *>(loc)->endpoints().size()) : 0;
|
||||
}
|
||||
ZT_MAYBE_UNUSED 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)
|
||||
ZT_MAYBE_UNUSED const ZT_Endpoint *ZT_Locator_endpoint(const ZT_Locator *loc, const unsigned int ep)
|
||||
{
|
||||
if (!loc)
|
||||
return nullptr;
|
||||
|
@ -443,14 +513,14 @@ const ZT_Endpoint *ZT_Locator_endpoint(const ZT_Locator *loc, const unsigned int
|
|||
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)
|
||||
ZT_MAYBE_UNUSED 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(const ZT_Locator *loc)
|
||||
ZT_MAYBE_UNUSED void ZT_Locator_delete(const ZT_Locator *loc)
|
||||
{
|
||||
if (loc)
|
||||
delete reinterpret_cast<const ZeroTier::Locator *>(loc);
|
||||
|
@ -458,7 +528,7 @@ void ZT_Locator_delete(const ZT_Locator *loc)
|
|||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
ZT_Identity *ZT_Identity_new(enum ZT_IdentityType type)
|
||||
ZT_MAYBE_UNUSED ZT_Identity *ZT_Identity_new(enum ZT_IdentityType type)
|
||||
{
|
||||
if ((type != ZT_IDENTITY_TYPE_C25519) && (type != ZT_IDENTITY_TYPE_P384))
|
||||
return nullptr;
|
||||
|
@ -471,7 +541,7 @@ ZT_Identity *ZT_Identity_new(enum ZT_IdentityType type)
|
|||
}
|
||||
}
|
||||
|
||||
ZT_Identity *ZT_Identity_clone(const ZT_Identity *id)
|
||||
ZT_MAYBE_UNUSED ZT_Identity *ZT_Identity_clone(const ZT_Identity *id)
|
||||
{
|
||||
if (id) {
|
||||
try {
|
||||
|
@ -483,7 +553,7 @@ ZT_Identity *ZT_Identity_clone(const ZT_Identity *id)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
ZT_Identity *ZT_Identity_fromString(const char *idStr)
|
||||
ZT_MAYBE_UNUSED ZT_Identity *ZT_Identity_fromString(const char *idStr)
|
||||
{
|
||||
if (!idStr)
|
||||
return nullptr;
|
||||
|
@ -499,14 +569,14 @@ ZT_Identity *ZT_Identity_fromString(const char *idStr)
|
|||
}
|
||||
}
|
||||
|
||||
int ZT_Identity_validate(const ZT_Identity *id)
|
||||
ZT_MAYBE_UNUSED 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)
|
||||
ZT_MAYBE_UNUSED unsigned int ZT_Identity_sign(const ZT_Identity *id, const void *data, unsigned int len, void *signature, unsigned int signatureBufferLength)
|
||||
{
|
||||
if (!id)
|
||||
return 0;
|
||||
|
@ -515,21 +585,21 @@ unsigned int ZT_Identity_sign(const ZT_Identity *id, const void *data, unsigned
|
|||
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)
|
||||
ZT_MAYBE_UNUSED 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)
|
||||
ZT_MAYBE_UNUSED 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)
|
||||
ZT_MAYBE_UNUSED 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;
|
||||
|
@ -537,28 +607,28 @@ char *ZT_Identity_toString(const ZT_Identity *id, char *buf, int capacity, int i
|
|||
return buf;
|
||||
}
|
||||
|
||||
int ZT_Identity_hasPrivate(const ZT_Identity *id)
|
||||
ZT_MAYBE_UNUSED 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)
|
||||
ZT_MAYBE_UNUSED 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)
|
||||
ZT_MAYBE_UNUSED const ZT_Fingerprint *ZT_Identity_fingerprint(const ZT_Identity *id)
|
||||
{
|
||||
if (!id)
|
||||
return nullptr;
|
||||
return &(reinterpret_cast<const ZeroTier::Identity *>(id)->fingerprint());
|
||||
}
|
||||
|
||||
int ZT_Identity_compare(const ZT_Identity *a, const ZT_Identity *b)
|
||||
ZT_MAYBE_UNUSED int ZT_Identity_compare(const ZT_Identity *a, const ZT_Identity *b)
|
||||
{
|
||||
if (a) {
|
||||
if (b) {
|
||||
|
@ -579,7 +649,7 @@ int ZT_Identity_compare(const ZT_Identity *a, const ZT_Identity *b)
|
|||
}
|
||||
}
|
||||
|
||||
void ZT_Identity_delete(const ZT_Identity *id)
|
||||
ZT_MAYBE_UNUSED void ZT_Identity_delete(const ZT_Identity *id)
|
||||
{
|
||||
if (id)
|
||||
delete reinterpret_cast<const ZeroTier::Identity *>(id);
|
||||
|
@ -587,7 +657,7 @@ void ZT_Identity_delete(const ZT_Identity *id)
|
|||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
int ZT_Certificate_newSubjectUniqueId(
|
||||
ZT_MAYBE_UNUSED int ZT_Certificate_newSubjectUniqueId(
|
||||
enum ZT_CertificateUniqueIdType type,
|
||||
void *uniqueId,
|
||||
int *uniqueIdSize,
|
||||
|
@ -610,7 +680,7 @@ int ZT_Certificate_newSubjectUniqueId(
|
|||
}
|
||||
}
|
||||
|
||||
int ZT_Certificate_newCSR(
|
||||
ZT_MAYBE_UNUSED int ZT_Certificate_newCSR(
|
||||
const ZT_Certificate_Subject *subject,
|
||||
const void *uniqueId,
|
||||
int uniqueIdSize,
|
||||
|
@ -633,7 +703,7 @@ int ZT_Certificate_newCSR(
|
|||
}
|
||||
}
|
||||
|
||||
int ZT_Certificate_sign(
|
||||
ZT_MAYBE_UNUSED int ZT_Certificate_sign(
|
||||
const ZT_Certificate *cert,
|
||||
const ZT_Identity *signer,
|
||||
void *signedCert,
|
||||
|
@ -658,7 +728,7 @@ int ZT_Certificate_sign(
|
|||
}
|
||||
}
|
||||
|
||||
enum ZT_CertificateError ZT_Certificate_decode(
|
||||
ZT_MAYBE_UNUSED enum ZT_CertificateError ZT_Certificate_decode(
|
||||
const ZT_Certificate **decodedCert,
|
||||
const void *cert,
|
||||
int certSize,
|
||||
|
@ -687,7 +757,7 @@ enum ZT_CertificateError ZT_Certificate_decode(
|
|||
}
|
||||
}
|
||||
|
||||
int ZT_Certificate_encode(
|
||||
ZT_MAYBE_UNUSED int ZT_Certificate_encode(
|
||||
const ZT_Certificate *cert,
|
||||
void *encoded,
|
||||
int *encodedSize)
|
||||
|
@ -707,7 +777,7 @@ int ZT_Certificate_encode(
|
|||
}
|
||||
}
|
||||
|
||||
enum ZT_CertificateError ZT_Certificate_verify(
|
||||
ZT_MAYBE_UNUSED enum ZT_CertificateError ZT_Certificate_verify(
|
||||
const ZT_Certificate *cert,
|
||||
int64_t clock)
|
||||
{
|
||||
|
@ -720,7 +790,7 @@ enum ZT_CertificateError ZT_Certificate_verify(
|
|||
}
|
||||
}
|
||||
|
||||
const ZT_Certificate *ZT_Certificate_clone(const ZT_Certificate *cert)
|
||||
ZT_MAYBE_UNUSED const ZT_Certificate *ZT_Certificate_clone(const ZT_Certificate *cert)
|
||||
{
|
||||
try {
|
||||
if (!cert)
|
||||
|
@ -731,7 +801,7 @@ const ZT_Certificate *ZT_Certificate_clone(const ZT_Certificate *cert)
|
|||
}
|
||||
}
|
||||
|
||||
void ZT_Certificate_delete(const ZT_Certificate *cert)
|
||||
ZT_MAYBE_UNUSED void ZT_Certificate_delete(const ZT_Certificate *cert)
|
||||
{
|
||||
try {
|
||||
if (cert)
|
||||
|
@ -741,7 +811,7 @@ void ZT_Certificate_delete(const ZT_Certificate *cert)
|
|||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
char *ZT_Endpoint_toString(
|
||||
ZT_MAYBE_UNUSED char *ZT_Endpoint_toString(
|
||||
const ZT_Endpoint *ep,
|
||||
char *buf,
|
||||
int capacity)
|
||||
|
@ -751,7 +821,7 @@ char *ZT_Endpoint_toString(
|
|||
return reinterpret_cast<const ZeroTier::Endpoint *>(ep)->toString(buf);
|
||||
}
|
||||
|
||||
int ZT_Endpoint_fromString(
|
||||
ZT_MAYBE_UNUSED int ZT_Endpoint_fromString(
|
||||
ZT_Endpoint *ep,
|
||||
const char *str)
|
||||
{
|
||||
|
@ -760,7 +830,7 @@ int ZT_Endpoint_fromString(
|
|||
return reinterpret_cast<ZeroTier::Endpoint *>(ep)->fromString(str) ? ZT_RESULT_OK : ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
int ZT_Endpoint_fromBytes(
|
||||
ZT_MAYBE_UNUSED int ZT_Endpoint_fromBytes(
|
||||
ZT_Endpoint *ep,
|
||||
const void *bytes,
|
||||
unsigned int len)
|
||||
|
@ -772,14 +842,14 @@ int ZT_Endpoint_fromBytes(
|
|||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
char *ZT_Fingerprint_toString(const ZT_Fingerprint *fp, char *buf, int capacity)
|
||||
ZT_MAYBE_UNUSED char *ZT_Fingerprint_toString(const ZT_Fingerprint *fp, char *buf, int capacity)
|
||||
{
|
||||
if (capacity < ZT_FINGERPRINT_STRING_SIZE_MAX)
|
||||
return nullptr;
|
||||
return reinterpret_cast<const ZeroTier::Fingerprint *>(fp)->toString(buf);
|
||||
}
|
||||
|
||||
int ZT_Fingerprint_fromString(ZT_Fingerprint *fp, const char *s)
|
||||
ZT_MAYBE_UNUSED int ZT_Fingerprint_fromString(ZT_Fingerprint *fp, const char *s)
|
||||
{
|
||||
if ((!fp)||(!s))
|
||||
return 0;
|
||||
|
@ -793,13 +863,13 @@ int ZT_Fingerprint_fromString(ZT_Fingerprint *fp, const char *s)
|
|||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
void ZT_InetAddress_clear(ZT_InetAddress *ia)
|
||||
ZT_MAYBE_UNUSED void ZT_InetAddress_clear(ZT_InetAddress *ia)
|
||||
{
|
||||
if (likely(ia != nullptr))
|
||||
ZeroTier::Utils::zero<sizeof(ZT_InetAddress)>(ia);
|
||||
}
|
||||
|
||||
char *ZT_InetAddress_toString(const ZT_InetAddress *ia, char *buf, unsigned int cap)
|
||||
ZT_MAYBE_UNUSED char *ZT_InetAddress_toString(const ZT_InetAddress *ia, char *buf, unsigned int cap)
|
||||
{
|
||||
if (likely((cap > 0)&&(buf != nullptr))) {
|
||||
if (likely((ia != nullptr)&&(cap >= ZT_INETADDRESS_STRING_SIZE_MAX))) {
|
||||
|
@ -811,7 +881,7 @@ char *ZT_InetAddress_toString(const ZT_InetAddress *ia, char *buf, unsigned int
|
|||
return buf;
|
||||
}
|
||||
|
||||
int ZT_InetAddress_fromString(ZT_InetAddress *ia, const char *str)
|
||||
ZT_MAYBE_UNUSED int ZT_InetAddress_fromString(ZT_InetAddress *ia, const char *str)
|
||||
{
|
||||
if (likely((ia != nullptr)&&(str != nullptr))) {
|
||||
return (int)reinterpret_cast<ZeroTier::InetAddress *>(ia)->fromString(str);
|
||||
|
@ -819,53 +889,53 @@ int ZT_InetAddress_fromString(ZT_InetAddress *ia, const char *str)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void ZT_InetAddress_set(ZT_InetAddress *ia, const void *saddr)
|
||||
ZT_MAYBE_UNUSED void ZT_InetAddress_set(ZT_InetAddress *ia, const void *saddr)
|
||||
{
|
||||
if (likely(ia != nullptr))
|
||||
(*reinterpret_cast<ZeroTier::InetAddress *>(ia)) = reinterpret_cast<const struct sockaddr *>(saddr);
|
||||
}
|
||||
|
||||
void ZT_InetAddress_setIpBytes(ZT_InetAddress *ia, const void *ipBytes, unsigned int ipLen, unsigned int port)
|
||||
ZT_MAYBE_UNUSED void ZT_InetAddress_setIpBytes(ZT_InetAddress *ia, const void *ipBytes, unsigned int ipLen, unsigned int port)
|
||||
{
|
||||
if (likely(ia != nullptr))
|
||||
reinterpret_cast<ZeroTier::InetAddress *>(ia)->set(ipBytes, ipLen, port);
|
||||
}
|
||||
|
||||
void ZT_InetAddress_setPort(ZT_InetAddress *ia, unsigned int port)
|
||||
ZT_MAYBE_UNUSED void ZT_InetAddress_setPort(ZT_InetAddress *ia, unsigned int port)
|
||||
{
|
||||
if (likely(ia != nullptr))
|
||||
reinterpret_cast<ZeroTier::InetAddress *>(ia)->setPort(port);
|
||||
}
|
||||
|
||||
unsigned int ZT_InetAddress_port(const ZT_InetAddress *ia)
|
||||
ZT_MAYBE_UNUSED unsigned int ZT_InetAddress_port(const ZT_InetAddress *ia)
|
||||
{
|
||||
if (likely(ia != nullptr))
|
||||
return reinterpret_cast<const ZeroTier::InetAddress *>(ia)->port();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ZT_InetAddress_isNil(const ZT_InetAddress *ia)
|
||||
ZT_MAYBE_UNUSED int ZT_InetAddress_isNil(const ZT_InetAddress *ia)
|
||||
{
|
||||
if (!ia)
|
||||
return 0;
|
||||
return (int)((bool)(*reinterpret_cast<const ZeroTier::InetAddress *>(ia)));
|
||||
}
|
||||
|
||||
int ZT_InetAddress_isV4(const ZT_InetAddress *ia)
|
||||
ZT_MAYBE_UNUSED int ZT_InetAddress_isV4(const ZT_InetAddress *ia)
|
||||
{
|
||||
if (!ia)
|
||||
return 0;
|
||||
return (int)(reinterpret_cast<const ZeroTier::InetAddress *>(ia))->isV4();
|
||||
}
|
||||
|
||||
int ZT_InetAddress_isV6(const ZT_InetAddress *ia)
|
||||
ZT_MAYBE_UNUSED int ZT_InetAddress_isV6(const ZT_InetAddress *ia)
|
||||
{
|
||||
if (!ia)
|
||||
return 0;
|
||||
return (int)(reinterpret_cast<const ZeroTier::InetAddress *>(ia))->isV6();
|
||||
}
|
||||
|
||||
unsigned int ZT_InetAddress_ipBytes(const ZT_InetAddress *ia, void *buf)
|
||||
ZT_MAYBE_UNUSED unsigned int ZT_InetAddress_ipBytes(const ZT_InetAddress *ia, void *buf)
|
||||
{
|
||||
if (ia) {
|
||||
switch(reinterpret_cast<const ZeroTier::InetAddress *>(ia)->as.sa.sa_family) {
|
||||
|
@ -880,14 +950,14 @@ unsigned int ZT_InetAddress_ipBytes(const ZT_InetAddress *ia, void *buf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
enum ZT_InetAddress_IpScope ZT_InetAddress_ipScope(const ZT_InetAddress *ia)
|
||||
ZT_MAYBE_UNUSED enum ZT_InetAddress_IpScope ZT_InetAddress_ipScope(const ZT_InetAddress *ia)
|
||||
{
|
||||
if (likely(ia != nullptr))
|
||||
return reinterpret_cast<const ZeroTier::InetAddress *>(ia)->ipScope();
|
||||
return ZT_IP_SCOPE_NONE;
|
||||
}
|
||||
|
||||
int ZT_InetAddress_compare(const ZT_InetAddress *a, const ZT_InetAddress *b)
|
||||
ZT_MAYBE_UNUSED int ZT_InetAddress_compare(const ZT_InetAddress *a, const ZT_InetAddress *b)
|
||||
{
|
||||
if (a) {
|
||||
if (b) {
|
||||
|
@ -910,7 +980,7 @@ int ZT_InetAddress_compare(const ZT_InetAddress *a, const ZT_InetAddress *b)
|
|||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
int ZT_Dictionary_parse(const void *const dict, const unsigned int len, void *const arg, void (*f)(void *, const char *, unsigned int, const void *, unsigned int))
|
||||
ZT_MAYBE_UNUSED int ZT_Dictionary_parse(const void *const dict, const unsigned int len, void *const arg, void (*f)(void *, const char *, unsigned int, const void *, unsigned int))
|
||||
{
|
||||
ZeroTier::Dictionary d;
|
||||
if (d.decode(dict, len)) {
|
||||
|
@ -924,7 +994,7 @@ int ZT_Dictionary_parse(const void *const dict, const unsigned int len, void *co
|
|||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
uint64_t ZT_random()
|
||||
ZT_MAYBE_UNUSED uint64_t ZT_random()
|
||||
{ return ZeroTier::Utils::random(); }
|
||||
|
||||
} // extern "C"
|
||||
|
|
|
@ -11,6 +11,7 @@ set(core_headers
|
|||
Address.hpp
|
||||
Buf.hpp
|
||||
C25519.hpp
|
||||
CallContext.hpp
|
||||
CapabilityCredential.hpp
|
||||
Certificate.hpp
|
||||
Defaults.hpp
|
||||
|
|
63
core/CallContext.hpp
Normal file
63
core/CallContext.hpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c)2013-2021 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: 2026-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
#ifndef ZT_CALLCONTEXT_HPP
|
||||
#define ZT_CALLCONTEXT_HPP
|
||||
|
||||
#include "Constants.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
* A per-API-call equivalent to the runtime
|
||||
*
|
||||
* This captures several things that are passed into API calls and follow
|
||||
* the call chain. Some such as tPtr may be supplied to callbacks.
|
||||
*/
|
||||
class CallContext
|
||||
{
|
||||
public:
|
||||
ZT_INLINE CallContext(const int64_t c, const int64_t t, void *const p) :
|
||||
clock(c),
|
||||
ticks(t),
|
||||
tPtr(p)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Real world time in milliseconds since Unix epoch or -1 if unknown.
|
||||
*
|
||||
* This is used for things like checking certificate expiration. If it's
|
||||
* not known then the value may be inferred from peers/roots or some
|
||||
* features may be disabled.
|
||||
*/
|
||||
const int64_t clock;
|
||||
|
||||
/**
|
||||
* Monotonic process or system clock in milliseconds since an arbitrary point.
|
||||
*
|
||||
* This is never -1 or undefined and is used for most timings.
|
||||
*/
|
||||
const int64_t ticks;
|
||||
|
||||
/**
|
||||
* An arbitrary pointer users pass into calls that follows the call chain
|
||||
*
|
||||
* By passing this back to callbacks state can be kept by the caller using
|
||||
* a mechanism that is faster (on most platforms) than thread-local storage.
|
||||
*/
|
||||
void *const tPtr;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
|
@ -38,7 +38,7 @@ int CapabilityCredential::marshal(uint8_t data[ZT_CAPABILITY_MARSHAL_SIZE_MAX],
|
|||
|
||||
Utils::storeBigEndian<uint64_t>(data + p, m_nwid);
|
||||
p += 8;
|
||||
Utils::storeBigEndian<uint64_t>(data + p, (uint64_t) m_ts);
|
||||
Utils::storeBigEndian<uint64_t>(data + p, (uint64_t) m_timestamp);
|
||||
p += 8;
|
||||
Utils::storeBigEndian<uint32_t>(data + p, m_id);
|
||||
p += 4;
|
||||
|
@ -84,7 +84,7 @@ int CapabilityCredential::unmarshal(const uint8_t *data, int len) noexcept
|
|||
return -1;
|
||||
|
||||
m_nwid = Utils::loadBigEndian<uint64_t>(data);
|
||||
m_ts = (int64_t) Utils::loadBigEndian<uint64_t>(data + 8);
|
||||
m_timestamp = (int64_t) Utils::loadBigEndian<uint64_t>(data + 8);
|
||||
m_id = Utils::loadBigEndian<uint32_t>(data + 16);
|
||||
|
||||
const unsigned int rc = Utils::loadBigEndian<uint16_t>(data + 20);
|
||||
|
|
|
@ -51,21 +51,23 @@ class CapabilityCredential : public Credential
|
|||
friend class Credential;
|
||||
|
||||
public:
|
||||
static constexpr ZT_CredentialType credentialType() noexcept { return ZT_CREDENTIAL_TYPE_CAPABILITY; }
|
||||
static constexpr ZT_CredentialType credentialType() noexcept
|
||||
{ return ZT_CREDENTIAL_TYPE_CAPABILITY; }
|
||||
|
||||
ZT_INLINE CapabilityCredential() noexcept { memoryZero(this); }
|
||||
ZT_INLINE CapabilityCredential() noexcept
|
||||
{ memoryZero(this); }
|
||||
|
||||
/**
|
||||
* @param id Capability ID
|
||||
* @param nwid Network ID
|
||||
* @param ts Timestamp (at controller)
|
||||
* @param timestamp Timestamp (at controller)
|
||||
* @param mccl Maximum custody chain length (1 to create non-transferable capability)
|
||||
* @param rules Network flow rules for this capability
|
||||
* @param ruleCount Number of flow rules
|
||||
*/
|
||||
ZT_INLINE CapabilityCredential(const uint32_t id, const uint64_t nwid, const int64_t ts, const ZT_VirtualNetworkRule *const rules, const unsigned int ruleCount) noexcept : // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
ZT_INLINE CapabilityCredential(const uint32_t id, const uint64_t nwid, const int64_t timestamp, const ZT_VirtualNetworkRule *const rules, const unsigned int ruleCount) noexcept: // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
m_nwid(nwid),
|
||||
m_ts(ts),
|
||||
m_timestamp(timestamp),
|
||||
m_id(id),
|
||||
m_ruleCount((ruleCount < ZT_MAX_CAPABILITY_RULES) ? ruleCount : ZT_MAX_CAPABILITY_RULES),
|
||||
m_signatureLength(0)
|
||||
|
@ -77,20 +79,38 @@ public:
|
|||
/**
|
||||
* @return Rules -- see ruleCount() for size of array
|
||||
*/
|
||||
ZT_INLINE const ZT_VirtualNetworkRule *rules() const noexcept { return m_rules; }
|
||||
ZT_INLINE const ZT_VirtualNetworkRule *rules() const noexcept
|
||||
{ return m_rules; }
|
||||
|
||||
/**
|
||||
* @return Number of rules in rules()
|
||||
*/
|
||||
ZT_INLINE unsigned int ruleCount() const noexcept { return m_ruleCount; }
|
||||
ZT_INLINE unsigned int ruleCount() const noexcept
|
||||
{ return m_ruleCount; }
|
||||
|
||||
ZT_INLINE uint32_t id() const noexcept { return m_id; }
|
||||
ZT_INLINE uint64_t networkId() const noexcept { return m_nwid; }
|
||||
ZT_INLINE int64_t timestamp() const noexcept { return m_ts; }
|
||||
ZT_INLINE const Address &issuedTo() const noexcept { return m_issuedTo; }
|
||||
ZT_INLINE const Address &signer() const noexcept { return m_signedBy; }
|
||||
ZT_INLINE const uint8_t *signature() const noexcept { return m_signature; }
|
||||
ZT_INLINE unsigned int signatureLength() const noexcept { return m_signatureLength; }
|
||||
ZT_INLINE uint32_t id() const noexcept
|
||||
{ return m_id; }
|
||||
|
||||
ZT_INLINE uint64_t networkId() const noexcept
|
||||
{ return m_nwid; }
|
||||
|
||||
ZT_INLINE int64_t timestamp() const noexcept
|
||||
{ return m_timestamp; }
|
||||
|
||||
ZT_INLINE int64_t revision() const noexcept
|
||||
{ return m_timestamp; }
|
||||
|
||||
ZT_INLINE const Address &issuedTo() const noexcept
|
||||
{ return m_issuedTo; }
|
||||
|
||||
ZT_INLINE const Address &signer() const noexcept
|
||||
{ return m_signedBy; }
|
||||
|
||||
ZT_INLINE const uint8_t *signature() const noexcept
|
||||
{ return m_signature; }
|
||||
|
||||
ZT_INLINE unsigned int signatureLength() const noexcept
|
||||
{ return m_signatureLength; }
|
||||
|
||||
/**
|
||||
* Sign this capability and add signature to its chain of custody
|
||||
|
@ -105,18 +125,22 @@ public:
|
|||
* @param to Recipient of this signature
|
||||
* @return True if signature successful and chain of custody appended
|
||||
*/
|
||||
bool sign(const Identity &from,const Address &to) noexcept;
|
||||
bool sign(const Identity &from, const Address &to) noexcept;
|
||||
|
||||
/**
|
||||
* Verify this capability's chain of custody and signatures
|
||||
*
|
||||
* @param RR Runtime environment to provide for peer lookup, etc.
|
||||
*/
|
||||
ZT_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const noexcept { return s_verify(RR, tPtr, *this); }
|
||||
ZT_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR, CallContext &cc) const noexcept
|
||||
{ return s_verify(RR, cc, *this); }
|
||||
|
||||
static constexpr int marshalSizeMax() noexcept { return ZT_CAPABILITY_MARSHAL_SIZE_MAX; }
|
||||
int marshal(uint8_t data[ZT_CAPABILITY_MARSHAL_SIZE_MAX],bool forSign = false) const noexcept;
|
||||
int unmarshal(const uint8_t *data,int len) noexcept;
|
||||
static constexpr int marshalSizeMax() noexcept
|
||||
{ return ZT_CAPABILITY_MARSHAL_SIZE_MAX; }
|
||||
|
||||
int marshal(uint8_t data[ZT_CAPABILITY_MARSHAL_SIZE_MAX], bool forSign = false) const noexcept;
|
||||
|
||||
int unmarshal(const uint8_t *data, int len) noexcept;
|
||||
|
||||
/**
|
||||
* Marshal a set of virtual network rules
|
||||
|
@ -126,7 +150,7 @@ public:
|
|||
* @param ruleCount Number of rules
|
||||
* @return Number of bytes written or -1 on error
|
||||
*/
|
||||
static int marshalVirtualNetworkRules(uint8_t *data,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount) noexcept;
|
||||
static int marshalVirtualNetworkRules(uint8_t *data, const ZT_VirtualNetworkRule *rules, unsigned int ruleCount) noexcept;
|
||||
|
||||
/**
|
||||
* Unmarshal a set of virtual network rules
|
||||
|
@ -138,17 +162,21 @@ public:
|
|||
* @param maxRuleCount Capacity of rules buffer
|
||||
* @return Number of bytes unmarshaled or -1 on error
|
||||
*/
|
||||
static int unmarshalVirtualNetworkRules(const uint8_t *data,int len,ZT_VirtualNetworkRule *rules,unsigned int &ruleCount,unsigned int maxRuleCount) noexcept;
|
||||
static int unmarshalVirtualNetworkRules(const uint8_t *data, int len, ZT_VirtualNetworkRule *rules, unsigned int &ruleCount, unsigned int maxRuleCount) noexcept;
|
||||
|
||||
// Provides natural sort order by ID
|
||||
ZT_INLINE bool operator<(const CapabilityCredential &c) const noexcept { return (m_id < c.m_id); }
|
||||
ZT_INLINE bool operator<(const CapabilityCredential &c) const noexcept
|
||||
{ return (m_id < c.m_id); }
|
||||
|
||||
ZT_INLINE bool operator==(const CapabilityCredential &c) const noexcept { return (memcmp(this, &c, sizeof(CapabilityCredential)) == 0); }
|
||||
ZT_INLINE bool operator!=(const CapabilityCredential &c) const noexcept { return (memcmp(this, &c, sizeof(CapabilityCredential)) != 0); }
|
||||
ZT_INLINE bool operator==(const CapabilityCredential &c) const noexcept
|
||||
{ return (memcmp(this, &c, sizeof(CapabilityCredential)) == 0); }
|
||||
|
||||
ZT_INLINE bool operator!=(const CapabilityCredential &c) const noexcept
|
||||
{ return (memcmp(this, &c, sizeof(CapabilityCredential)) != 0); }
|
||||
|
||||
private:
|
||||
uint64_t m_nwid;
|
||||
int64_t m_ts;
|
||||
int64_t m_timestamp;
|
||||
uint32_t m_id;
|
||||
unsigned int m_ruleCount;
|
||||
ZT_VirtualNetworkRule m_rules[ZT_MAX_CAPABILITY_RULES];
|
||||
|
|
|
@ -167,7 +167,7 @@ void Certificate::addSubjectCertificate(const uint8_t serialNo[ZT_SHA384_DIGEST_
|
|||
|
||||
// Enlarge array of uint8_t pointers, set new pointer to local copy of serial, and set
|
||||
// certificates to point to potentially reallocated array.
|
||||
m_subjectCertificates.push_back(m_serials.front().bytes());
|
||||
m_subjectCertificates.push_back(reinterpret_cast<const uint8_t *>(m_serials.front().data));
|
||||
this->subject.certificates = m_subjectCertificates.data();
|
||||
this->subject.certificateCount = (unsigned int)m_subjectCertificates.size();
|
||||
}
|
||||
|
@ -187,6 +187,7 @@ void Certificate::addSubjectUpdateUrl(const char *url)
|
|||
this->subject.updateURLCount = (unsigned int)m_updateUrls.size();
|
||||
}
|
||||
|
||||
/*
|
||||
void Certificate::setExtendedAttributes(const Dictionary &x)
|
||||
{
|
||||
m_extendedAttributes.clear();
|
||||
|
@ -194,6 +195,7 @@ void Certificate::setExtendedAttributes(const Dictionary &x)
|
|||
this->extendedAttributes = m_extendedAttributes.data();
|
||||
this->extendedAttributesSize = (unsigned int)m_extendedAttributes.size();
|
||||
}
|
||||
*/
|
||||
|
||||
bool Certificate::setSubjectUniqueId(const uint8_t uniqueId[ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_SIZE], const uint8_t uniqueIdPrivate[ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_PRIVATE_SIZE])
|
||||
{
|
||||
|
|
|
@ -110,7 +110,7 @@ public:
|
|||
*
|
||||
* @param x Extended attributes (set by issuer)
|
||||
*/
|
||||
void setExtendedAttributes(const Dictionary &x);
|
||||
//void setExtendedAttributes(const Dictionary &x);
|
||||
|
||||
/**
|
||||
* Set the unique ID of this certificate's subject
|
||||
|
|
|
@ -102,9 +102,9 @@
|
|||
#define ZT_NETWORK_HOUSEKEEPING_PERIOD 30000
|
||||
|
||||
/**
|
||||
* How often to rank roots
|
||||
* Period between calls to update() in TrustStore
|
||||
*/
|
||||
#define ZT_ROOT_RANK_PERIOD 5000
|
||||
#define ZT_TRUSTSTORE_UPDATE_PERIOD 300000
|
||||
|
||||
/**
|
||||
* Delay between WHOIS retries in ms
|
||||
|
|
|
@ -27,9 +27,11 @@
|
|||
#include <algorithm>
|
||||
|
||||
#ifdef __CPP11__
|
||||
|
||||
#include <atomic>
|
||||
#include <unordered_map>
|
||||
#include <forward_list>
|
||||
|
||||
#endif
|
||||
|
||||
namespace ZeroTier {
|
||||
|
@ -43,14 +45,15 @@ public:
|
|||
{}
|
||||
|
||||
template< typename I >
|
||||
ZT_INLINE Vector(I begin,I end) :
|
||||
ZT_INLINE Vector(I begin, I end) :
|
||||
std::vector< V >(begin, end)
|
||||
{}
|
||||
};
|
||||
|
||||
template< typename V >
|
||||
class List : public std::list< V >
|
||||
{};
|
||||
{
|
||||
};
|
||||
|
||||
#ifdef __CPP11__
|
||||
|
||||
|
@ -78,11 +81,13 @@ struct intl_MapHasher
|
|||
|
||||
template< typename K, typename V >
|
||||
class Map : public std::unordered_map< K, V, intl_MapHasher >
|
||||
{};
|
||||
{
|
||||
};
|
||||
|
||||
template< typename K, typename V >
|
||||
class MultiMap : public std::unordered_multimap< K, V, intl_MapHasher, std::equal_to< K > >
|
||||
{};
|
||||
{
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
|
@ -98,13 +103,15 @@ class MultiMap : public std::multimap< K, V >
|
|||
|
||||
template< typename K, typename V >
|
||||
class SortedMap : public std::map< K, V >
|
||||
{};
|
||||
{
|
||||
};
|
||||
|
||||
#ifdef __CPP11__
|
||||
|
||||
template< typename V >
|
||||
class ForwardList : public std::forward_list< V >
|
||||
{};
|
||||
{
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
|
@ -116,7 +123,8 @@ class ForwardList : public std::list< V >
|
|||
|
||||
template< typename V >
|
||||
class Set : public std::set< V, std::less< V > >
|
||||
{};
|
||||
{
|
||||
};
|
||||
|
||||
typedef std::string String;
|
||||
|
||||
|
@ -130,11 +138,17 @@ struct H384
|
|||
ZT_INLINE H384() noexcept
|
||||
{ Utils::zero< sizeof(data) >(data); }
|
||||
|
||||
ZT_INLINE H384(const H384 &b) noexcept
|
||||
{ Utils::copy< 48 >(data, b.data); }
|
||||
|
||||
explicit ZT_INLINE H384(const void *const d) noexcept
|
||||
{ Utils::copy< 48 >(data, d); }
|
||||
|
||||
ZT_INLINE const uint8_t *bytes() const noexcept
|
||||
{ return reinterpret_cast<const uint8_t *>(data); }
|
||||
ZT_INLINE H384 &operator=(const H384 &b) noexcept
|
||||
{
|
||||
Utils::copy< 48 >(data, b.data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ZT_INLINE unsigned long hashCode() const noexcept
|
||||
{ return (unsigned long)data[0]; }
|
||||
|
@ -151,12 +165,12 @@ struct H384
|
|||
ZT_INLINE bool operator<(const H384 &b) const noexcept
|
||||
{ return std::lexicographical_compare(data, data + 6, b.data, b.data + 6); }
|
||||
|
||||
ZT_INLINE bool operator>(const H384 &b) const noexcept
|
||||
{ return (b < *this); }
|
||||
|
||||
ZT_INLINE bool operator<=(const H384 &b) const noexcept
|
||||
{ return !(b < *this); }
|
||||
|
||||
ZT_INLINE bool operator>(const H384 &b) const noexcept
|
||||
{ return (b < *this); }
|
||||
|
||||
ZT_INLINE bool operator>=(const H384 &b) const noexcept
|
||||
{ return !(*this < b); }
|
||||
};
|
||||
|
@ -164,7 +178,7 @@ struct H384
|
|||
static_assert(sizeof(H384) == 48, "H384 contains unnecessary padding");
|
||||
|
||||
/**
|
||||
* A byte array
|
||||
* A fixed size byte array
|
||||
*
|
||||
* @tparam S Size in bytes
|
||||
*/
|
||||
|
@ -172,6 +186,53 @@ template< unsigned long S >
|
|||
struct Blob
|
||||
{
|
||||
uint8_t data[S];
|
||||
|
||||
ZT_INLINE Blob() noexcept
|
||||
{ Utils::zero< S >(data); }
|
||||
|
||||
ZT_INLINE Blob(const Blob &b) noexcept
|
||||
{ Utils::copy< S >(data, b.data); }
|
||||
|
||||
explicit ZT_INLINE Blob(const void *const d) noexcept
|
||||
{ Utils::copy< S >(data, d); }
|
||||
|
||||
explicit ZT_INLINE Blob(const void *const d, const unsigned int l) noexcept
|
||||
{
|
||||
Utils::copy(data, d, l);
|
||||
if (l < S) {
|
||||
Utils::zero(data + l, S - l);
|
||||
}
|
||||
}
|
||||
|
||||
ZT_INLINE Blob &operator=(const Blob &b) noexcept
|
||||
{
|
||||
Utils::copy< S >(data, b.data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ZT_INLINE unsigned long hashCode() const noexcept
|
||||
{ return Utils::fnv1a32(data, (unsigned int)S); }
|
||||
|
||||
ZT_INLINE operator bool() const noexcept
|
||||
{ return Utils::allZero(data, (unsigned int)S); }
|
||||
|
||||
ZT_INLINE bool operator==(const Blob &b) const noexcept
|
||||
{ return (memcmp(data, b.data, S) == 0); }
|
||||
|
||||
ZT_INLINE bool operator!=(const Blob &b) const noexcept
|
||||
{ return (memcmp(data, b.data, S) != 0); }
|
||||
|
||||
ZT_INLINE bool operator<(const Blob &b) const noexcept
|
||||
{ return (memcmp(data, b.data, S) < 0); }
|
||||
|
||||
ZT_INLINE bool operator<=(const Blob &b) const noexcept
|
||||
{ return (memcmp(data, b.data, S) <= 0); }
|
||||
|
||||
ZT_INLINE bool operator>(const Blob &b) const noexcept
|
||||
{ return (memcmp(data, b.data, S) > 0); }
|
||||
|
||||
ZT_INLINE bool operator>=(const Blob &b) const noexcept
|
||||
{ return (memcmp(data, b.data, S) >= 0); }
|
||||
};
|
||||
|
||||
} // ZeroTier
|
||||
|
|
|
@ -42,43 +42,50 @@
|
|||
|
||||
namespace ZeroTier {
|
||||
|
||||
template<typename CRED>
|
||||
static ZT_INLINE Credential::VerifyResult p_credVerify(const RuntimeEnvironment *RR,void *tPtr,CRED credential)
|
||||
template< typename CRED >
|
||||
static ZT_INLINE Credential::VerifyResult p_credVerify(const RuntimeEnvironment *RR, CallContext &cc, CRED credential)
|
||||
{
|
||||
uint8_t tmp[ZT_BUF_MEM_SIZE + 16];
|
||||
|
||||
const Address signedBy(credential.signer());
|
||||
const uint64_t networkId = credential.networkId();
|
||||
if ((!signedBy)||(signedBy != Network::controllerFor(networkId)))
|
||||
if ((!signedBy) || (signedBy != Network::controllerFor(networkId)))
|
||||
return Credential::VERIFY_BAD_SIGNATURE;
|
||||
|
||||
const SharedPtr<Peer> peer(RR->topology->peer(tPtr,signedBy));
|
||||
const SharedPtr< Peer > peer(RR->topology->peer(cc, signedBy));
|
||||
if (!peer)
|
||||
return Credential::VERIFY_NEED_IDENTITY;
|
||||
|
||||
try {
|
||||
int l = credential.marshal(tmp,true);
|
||||
int l = credential.marshal(tmp, true);
|
||||
if (l <= 0)
|
||||
return Credential::VERIFY_BAD_SIGNATURE;
|
||||
return (peer->identity().verify(tmp,(unsigned int)l,credential.signature(),credential.signatureLength()) ? Credential::VERIFY_OK : Credential::VERIFY_BAD_SIGNATURE);
|
||||
} catch ( ... ) {}
|
||||
return (peer->identity().verify(tmp, (unsigned int)l, credential.signature(), credential.signatureLength()) ? Credential::VERIFY_OK : Credential::VERIFY_BAD_SIGNATURE);
|
||||
} catch (...) {}
|
||||
|
||||
return Credential::VERIFY_BAD_SIGNATURE;
|
||||
}
|
||||
|
||||
Credential::VerifyResult Credential::s_verify(const RuntimeEnvironment *RR, void *tPtr, const RevocationCredential &credential) { return p_credVerify(RR, tPtr, credential); }
|
||||
Credential::VerifyResult Credential::s_verify(const RuntimeEnvironment *RR, void *tPtr, const TagCredential &credential) { return p_credVerify(RR, tPtr, credential); }
|
||||
Credential::VerifyResult Credential::s_verify(const RuntimeEnvironment *RR, void *tPtr, const CapabilityCredential &credential) { return p_credVerify(RR, tPtr, credential); }
|
||||
Credential::VerifyResult Credential::s_verify(const RuntimeEnvironment *RR, void *tPtr, const OwnershipCredential &credential) { return p_credVerify(RR, tPtr, credential); }
|
||||
Credential::VerifyResult Credential::s_verify(const RuntimeEnvironment *RR, CallContext &cc, const RevocationCredential &credential)
|
||||
{ return p_credVerify(RR, cc, credential); }
|
||||
|
||||
Credential::VerifyResult Credential::s_verify(const RuntimeEnvironment *RR, void *tPtr, const MembershipCredential &credential)
|
||||
Credential::VerifyResult Credential::s_verify(const RuntimeEnvironment *RR, CallContext &cc, const TagCredential &credential)
|
||||
{ return p_credVerify(RR, cc, credential); }
|
||||
|
||||
Credential::VerifyResult Credential::s_verify(const RuntimeEnvironment *RR, CallContext &cc, const CapabilityCredential &credential)
|
||||
{ return p_credVerify(RR, cc, credential); }
|
||||
|
||||
Credential::VerifyResult Credential::s_verify(const RuntimeEnvironment *RR, CallContext &cc, const OwnershipCredential &credential)
|
||||
{ return p_credVerify(RR, cc, credential); }
|
||||
|
||||
Credential::VerifyResult Credential::s_verify(const RuntimeEnvironment *RR, CallContext &cc, const MembershipCredential &credential)
|
||||
{
|
||||
// Sanity check network ID.
|
||||
if ((!credential.m_signedBy) || (credential.m_signedBy != Network::controllerFor(credential.m_networkId)))
|
||||
return Credential::VERIFY_BAD_SIGNATURE;
|
||||
|
||||
// If we don't know the peer, get its identity. This shouldn't happen here but should be handled.
|
||||
const SharedPtr<Peer> peer(RR->topology->peer(tPtr,credential.m_signedBy));
|
||||
const SharedPtr< Peer > peer(RR->topology->peer(cc, credential.m_signedBy));
|
||||
if (!peer)
|
||||
return Credential::VERIFY_NEED_IDENTITY;
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "Constants.hpp"
|
||||
#include "TriviallyCopyable.hpp"
|
||||
#include "CallContext.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
@ -52,11 +53,11 @@ public:
|
|||
};
|
||||
|
||||
protected:
|
||||
static VerifyResult s_verify(const RuntimeEnvironment *RR, void *tPtr, const MembershipCredential &credential);
|
||||
static VerifyResult s_verify(const RuntimeEnvironment *RR, void *tPtr, const RevocationCredential &credential);
|
||||
static VerifyResult s_verify(const RuntimeEnvironment *RR, void *tPtr, const TagCredential &credential);
|
||||
static VerifyResult s_verify(const RuntimeEnvironment *RR, void *tPtr, const OwnershipCredential &credential);
|
||||
static VerifyResult s_verify(const RuntimeEnvironment *RR, void *tPtr, const CapabilityCredential &credential);
|
||||
static VerifyResult s_verify(const RuntimeEnvironment *RR, CallContext &cc, const MembershipCredential &credential);
|
||||
static VerifyResult s_verify(const RuntimeEnvironment *RR, CallContext &cc, const RevocationCredential &credential);
|
||||
static VerifyResult s_verify(const RuntimeEnvironment *RR, CallContext &cc, const TagCredential &credential);
|
||||
static VerifyResult s_verify(const RuntimeEnvironment *RR, CallContext &cc, const OwnershipCredential &credential);
|
||||
static VerifyResult s_verify(const RuntimeEnvironment *RR, CallContext &cc, const CapabilityCredential &credential);
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
|
|
@ -50,7 +50,7 @@ template<
|
|||
unsigned int MFP = ZT_MAX_INCOMING_FRAGMENTS_PER_PATH,
|
||||
unsigned int GCS = (ZT_MAX_PACKET_FRAGMENTS * 2),
|
||||
unsigned int GCT = (ZT_MAX_PACKET_FRAGMENTS * 4),
|
||||
typename P = SharedPtr <Path> >
|
||||
typename P = SharedPtr< Path > >
|
||||
class Defragmenter
|
||||
{
|
||||
public:
|
||||
|
@ -136,19 +136,19 @@ public:
|
|||
* @param fragmentDataSize Length of data in fragment's data.bytes (fragment's data.fields type is ignored)
|
||||
* @param fragmentNo Number of fragment (0..totalFragmentsExpected, non-inclusive)
|
||||
* @param totalFragmentsExpected Total number of expected fragments in this message or 0 to use cached value
|
||||
* @param now Current time
|
||||
* @param ts Current time
|
||||
* @param via If non-NULL this is the path on which this message fragment was received
|
||||
* @return Result code
|
||||
*/
|
||||
ZT_INLINE ResultCode assemble(
|
||||
const uint64_t messageId,
|
||||
FCV <Buf::Slice, MF> &message,
|
||||
SharedPtr <Buf> &fragment,
|
||||
FCV< Buf::Slice, MF > &message,
|
||||
SharedPtr< Buf > &fragment,
|
||||
const unsigned int fragmentDataIndex,
|
||||
const unsigned int fragmentDataSize,
|
||||
const unsigned int fragmentNo,
|
||||
const unsigned int totalFragmentsExpected,
|
||||
const int64_t now,
|
||||
const int64_t ts,
|
||||
const P &via)
|
||||
{
|
||||
// Sanity checks for malformed fragments or invalid input parameters.
|
||||
|
@ -210,7 +210,7 @@ public:
|
|||
return ERR_DUPLICATE_FRAGMENT;
|
||||
|
||||
// Update last-activity timestamp for this entry, delaying GC.
|
||||
e->lastUsed = now;
|
||||
e->lastUsed = ts;
|
||||
|
||||
// Learn total fragments expected if a value is given. Otherwise the cached
|
||||
// value gets used. This is to support the implementation of fragmentation
|
||||
|
@ -344,11 +344,11 @@ private:
|
|||
unsigned int totalFragmentsExpected;
|
||||
unsigned int fragmentsReceived;
|
||||
P via;
|
||||
FCV <Buf::Slice, MF> message;
|
||||
FCV< Buf::Slice, MF > message;
|
||||
Mutex lock;
|
||||
};
|
||||
|
||||
Map <uint64_t, Defragmenter< MF, MFP, GCS, GCT, P >::p_E> m_messages;
|
||||
Map< uint64_t, Defragmenter< MF, MFP, GCS, GCT, P >::p_E > m_messages;
|
||||
RWMutex m_messages_l;
|
||||
};
|
||||
|
||||
|
|
|
@ -15,24 +15,24 @@
|
|||
|
||||
namespace ZeroTier {
|
||||
|
||||
Vector< uint8_t > &Dictionary::operator[](const char *const k)
|
||||
ZT_MAYBE_UNUSED Vector< uint8_t > &Dictionary::operator[](const char *const k)
|
||||
{ return m_entries[k]; }
|
||||
|
||||
const Vector< uint8_t > &Dictionary::operator[](const char *const k) const
|
||||
ZT_MAYBE_UNUSED const Vector< uint8_t > &Dictionary::operator[](const char *const k) const
|
||||
{
|
||||
static const Vector< uint8_t > s_emptyEntry;
|
||||
const SortedMap< String, Vector< uint8_t > >::const_iterator e(m_entries.find(k));
|
||||
return (e == m_entries.end()) ? s_emptyEntry : e->second;
|
||||
}
|
||||
|
||||
void Dictionary::add(const char *k, const Address &v)
|
||||
ZT_MAYBE_UNUSED void Dictionary::add(const char *k, const Address &v)
|
||||
{
|
||||
char tmp[ZT_ADDRESS_STRING_SIZE_MAX];
|
||||
v.toString(tmp);
|
||||
add(k, tmp);
|
||||
}
|
||||
|
||||
void Dictionary::add(const char *k, const char *v)
|
||||
ZT_MAYBE_UNUSED void Dictionary::add(const char *k, const char *v)
|
||||
{
|
||||
Vector< uint8_t > &e = (*this)[k];
|
||||
e.clear();
|
||||
|
@ -42,7 +42,7 @@ void Dictionary::add(const char *k, const char *v)
|
|||
}
|
||||
}
|
||||
|
||||
void Dictionary::add(const char *k, const void *data, unsigned int len)
|
||||
ZT_MAYBE_UNUSED void Dictionary::add(const char *k, const void *data, unsigned int len)
|
||||
{
|
||||
Vector< uint8_t > &e = (*this)[k];
|
||||
if (likely(len != 0)) {
|
||||
|
@ -52,7 +52,7 @@ void Dictionary::add(const char *k, const void *data, unsigned int len)
|
|||
}
|
||||
}
|
||||
|
||||
uint64_t Dictionary::getUI(const char *k, uint64_t dfl) const
|
||||
ZT_MAYBE_UNUSED uint64_t Dictionary::getUI(const char *k, uint64_t dfl) const
|
||||
{
|
||||
char tmp[32];
|
||||
getS(k, tmp, sizeof(tmp));
|
||||
|
@ -61,7 +61,7 @@ uint64_t Dictionary::getUI(const char *k, uint64_t dfl) const
|
|||
return dfl;
|
||||
}
|
||||
|
||||
char *Dictionary::getS(const char *k, char *v, const unsigned int cap) const
|
||||
ZT_MAYBE_UNUSED char *Dictionary::getS(const char *k, char *v, const unsigned int cap) const
|
||||
{
|
||||
if (cap == 0) // sanity check
|
||||
return v;
|
||||
|
@ -84,10 +84,10 @@ char *Dictionary::getS(const char *k, char *v, const unsigned int cap) const
|
|||
return v;
|
||||
}
|
||||
|
||||
void Dictionary::clear()
|
||||
ZT_MAYBE_UNUSED void Dictionary::clear()
|
||||
{ m_entries.clear(); }
|
||||
|
||||
void Dictionary::encode(Vector< uint8_t > &out) const
|
||||
ZT_MAYBE_UNUSED void Dictionary::encode(Vector< uint8_t > &out) const
|
||||
{
|
||||
out.clear();
|
||||
for (SortedMap< String, Vector< uint8_t > >::const_iterator ti(m_entries.begin()); ti != m_entries.end(); ++ti) {
|
||||
|
@ -98,7 +98,7 @@ void Dictionary::encode(Vector< uint8_t > &out) const
|
|||
}
|
||||
}
|
||||
|
||||
bool Dictionary::decode(const void *data, unsigned int len)
|
||||
ZT_MAYBE_UNUSED bool Dictionary::decode(const void *data, unsigned int len)
|
||||
{
|
||||
clear();
|
||||
String k;
|
||||
|
@ -151,7 +151,7 @@ bool Dictionary::decode(const void *data, unsigned int len)
|
|||
return true;
|
||||
}
|
||||
|
||||
char *Dictionary::arraySubscript(char *buf, unsigned int bufSize, const char *name, const unsigned long sub) noexcept
|
||||
ZT_MAYBE_UNUSED char *Dictionary::arraySubscript(char *buf, unsigned int bufSize, const char *name, const unsigned long sub) noexcept
|
||||
{
|
||||
if (bufSize < 17) { // sanity check
|
||||
buf[0] = 0;
|
||||
|
|
|
@ -81,7 +81,7 @@ public:
|
|||
* @param k Key to look up
|
||||
* @return Reference to value
|
||||
*/
|
||||
Vector< uint8_t > &operator[](const char *k);
|
||||
ZT_MAYBE_UNUSED Vector< uint8_t > &operator[](const char *k);
|
||||
|
||||
/**
|
||||
* Get a const reference to a value
|
||||
|
@ -89,18 +89,18 @@ public:
|
|||
* @param k Key to look up
|
||||
* @return Reference to value or to empty vector if not found
|
||||
*/
|
||||
const Vector< uint8_t > &operator[](const char *k) const;
|
||||
ZT_MAYBE_UNUSED const Vector< uint8_t > &operator[](const char *k) const;
|
||||
|
||||
/**
|
||||
* @return Start of key->value pairs
|
||||
*/
|
||||
ZT_INLINE const_iterator begin() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE const_iterator begin() const noexcept
|
||||
{ return m_entries.begin(); }
|
||||
|
||||
/**
|
||||
* @return End of key->value pairs
|
||||
*/
|
||||
ZT_INLINE const_iterator end() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE const_iterator end() const noexcept
|
||||
{ return m_entries.end(); }
|
||||
|
||||
/**
|
||||
|
@ -109,7 +109,7 @@ public:
|
|||
* @param k Key to set
|
||||
* @param v Integer to set, will be cast to uint64_t and stored as hex
|
||||
*/
|
||||
ZT_INLINE void add(const char *const k, const uint64_t v)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void add(const char *const k, const uint64_t v)
|
||||
{
|
||||
char buf[24];
|
||||
add(k, Utils::hex((uint64_t)(v), buf));
|
||||
|
@ -121,7 +121,7 @@ public:
|
|||
* @param k Key to set
|
||||
* @param v Integer to set, will be cast to uint64_t and stored as hex
|
||||
*/
|
||||
ZT_INLINE void add(const char *const k, const int64_t v)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void add(const char *const k, const int64_t v)
|
||||
{
|
||||
char buf[24];
|
||||
add(k, Utils::hex((uint64_t)(v), buf));
|
||||
|
@ -130,17 +130,17 @@ public:
|
|||
/**
|
||||
* Add an address in 10-digit hex string format
|
||||
*/
|
||||
void add(const char *k, const Address &v);
|
||||
ZT_MAYBE_UNUSED void add(const char *k, const Address &v);
|
||||
|
||||
/**
|
||||
* Add a C string as a value
|
||||
*/
|
||||
void add(const char *k, const char *v);
|
||||
ZT_MAYBE_UNUSED void add(const char *k, const char *v);
|
||||
|
||||
/**
|
||||
* Add a binary blob as a value
|
||||
*/
|
||||
void add(const char *k, const void *data, unsigned int len);
|
||||
ZT_MAYBE_UNUSED void add(const char *k, const void *data, unsigned int len);
|
||||
|
||||
/**
|
||||
* Get an integer
|
||||
|
@ -149,7 +149,7 @@ public:
|
|||
* @param dfl Default value (default: 0)
|
||||
* @return Value of key or default if not found
|
||||
*/
|
||||
uint64_t getUI(const char *k, uint64_t dfl = 0) const;
|
||||
ZT_MAYBE_UNUSED uint64_t getUI(const char *k, uint64_t dfl = 0) const;
|
||||
|
||||
/**
|
||||
* Get a C string
|
||||
|
@ -161,7 +161,7 @@ public:
|
|||
* @param v Buffer to hold string
|
||||
* @param cap Maximum size of string (including terminating null)
|
||||
*/
|
||||
char *getS(const char *k, char *v, unsigned int cap) const;
|
||||
ZT_MAYBE_UNUSED char *getS(const char *k, char *v, unsigned int cap) const;
|
||||
|
||||
/**
|
||||
* Get an object supporting the marshal/unmarshal interface pattern
|
||||
|
@ -172,7 +172,7 @@ public:
|
|||
* @return True if unmarshal was successful
|
||||
*/
|
||||
template< typename T >
|
||||
ZT_INLINE bool getO(const char *k, T &obj) const
|
||||
ZT_MAYBE_UNUSED ZT_INLINE bool getO(const char *k, T &obj) const
|
||||
{
|
||||
const Vector< uint8_t > &d = (*this)[k];
|
||||
if (d.empty())
|
||||
|
@ -189,7 +189,7 @@ public:
|
|||
* @return True if successful
|
||||
*/
|
||||
template< typename T >
|
||||
ZT_INLINE bool addO(const char *k, T &obj)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE bool addO(const char *k, T &obj)
|
||||
{
|
||||
Vector< uint8_t > &d = (*this)[k];
|
||||
d.resize(T::marshalSizeMax());
|
||||
|
@ -205,18 +205,18 @@ public:
|
|||
/**
|
||||
* Erase all entries in dictionary
|
||||
*/
|
||||
void clear();
|
||||
ZT_MAYBE_UNUSED void clear();
|
||||
|
||||
/**
|
||||
* @return Number of entries
|
||||
*/
|
||||
ZT_INLINE unsigned int size() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE unsigned int size() const noexcept
|
||||
{ return (unsigned int)m_entries.size(); }
|
||||
|
||||
/**
|
||||
* @return True if dictionary is not empty
|
||||
*/
|
||||
ZT_INLINE bool empty() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE bool empty() const noexcept
|
||||
{ return m_entries.empty(); }
|
||||
|
||||
/**
|
||||
|
@ -224,7 +224,7 @@ public:
|
|||
*
|
||||
* @param out String encoded dictionary
|
||||
*/
|
||||
void encode(Vector< uint8_t > &out) const;
|
||||
ZT_MAYBE_UNUSED void encode(Vector< uint8_t > &out) const;
|
||||
|
||||
/**
|
||||
* Decode a string encoded dictionary
|
||||
|
@ -236,7 +236,7 @@ public:
|
|||
* @param len Length of data
|
||||
* @return True if dictionary was formatted correctly and valid, false on error
|
||||
*/
|
||||
bool decode(const void *data, unsigned int len);
|
||||
ZT_MAYBE_UNUSED bool decode(const void *data, unsigned int len);
|
||||
|
||||
/**
|
||||
* Append a key=value pair to a buffer (vector or FCV)
|
||||
|
@ -246,7 +246,7 @@ public:
|
|||
* @param v Value
|
||||
*/
|
||||
template< typename V >
|
||||
ZT_INLINE static void append(V &out, const char *const k, const bool v)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE static void append(V &out, const char *const k, const bool v)
|
||||
{
|
||||
s_appendKey(out, k);
|
||||
out.push_back((uint8_t)(v ? '1' : '0'));
|
||||
|
@ -261,7 +261,7 @@ public:
|
|||
* @param v Value
|
||||
*/
|
||||
template< typename V >
|
||||
ZT_INLINE static void append(V &out, const char *const k, const Address v)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE static void append(V &out, const char *const k, const Address v)
|
||||
{
|
||||
s_appendKey(out, k);
|
||||
const uint64_t a = v.toInt();
|
||||
|
@ -287,7 +287,7 @@ public:
|
|||
* @param v Value
|
||||
*/
|
||||
template< typename V >
|
||||
ZT_INLINE static void append(V &out, const char *const k, const uint64_t v)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE static void append(V &out, const char *const k, const uint64_t v)
|
||||
{
|
||||
s_appendKey(out, k);
|
||||
char buf[17];
|
||||
|
@ -299,31 +299,31 @@ public:
|
|||
}
|
||||
|
||||
template< typename V >
|
||||
ZT_INLINE static void append(V &out, const char *const k, const int64_t v)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE static void append(V &out, const char *const k, const int64_t v)
|
||||
{ append(out, k, (uint64_t)v); }
|
||||
|
||||
template< typename V >
|
||||
ZT_INLINE static void append(V &out, const char *const k, const uint32_t v)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE static void append(V &out, const char *const k, const uint32_t v)
|
||||
{ append(out, k, (uint64_t)v); }
|
||||
|
||||
template< typename V >
|
||||
ZT_INLINE static void append(V &out, const char *const k, const int32_t v)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE static void append(V &out, const char *const k, const int32_t v)
|
||||
{ append(out, k, (uint64_t)v); }
|
||||
|
||||
template< typename V >
|
||||
ZT_INLINE static void append(V &out, const char *const k, const uint16_t v)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE static void append(V &out, const char *const k, const uint16_t v)
|
||||
{ append(out, k, (uint64_t)v); }
|
||||
|
||||
template< typename V >
|
||||
ZT_INLINE static void append(V &out, const char *const k, const int16_t v)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE static void append(V &out, const char *const k, const int16_t v)
|
||||
{ append(out, k, (uint64_t)v); }
|
||||
|
||||
template< typename V >
|
||||
ZT_INLINE static void append(V &out, const char *const k, const uint8_t v)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE static void append(V &out, const char *const k, const uint8_t v)
|
||||
{ append(out, k, (uint64_t)v); }
|
||||
|
||||
template< typename V >
|
||||
ZT_INLINE static void append(V &out, const char *const k, const int8_t v)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE static void append(V &out, const char *const k, const int8_t v)
|
||||
{ append(out, k, (uint64_t)v); }
|
||||
|
||||
/**
|
||||
|
@ -334,7 +334,7 @@ public:
|
|||
* @param v Value
|
||||
*/
|
||||
template< typename V >
|
||||
ZT_INLINE static void append(V &out, const char *const k, const char *v)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE static void append(V &out, const char *const k, const char *v)
|
||||
{
|
||||
if ((v) && (*v)) {
|
||||
s_appendKey(out, k);
|
||||
|
@ -353,7 +353,7 @@ public:
|
|||
* @param vlen Value length in bytes
|
||||
*/
|
||||
template< typename V >
|
||||
ZT_INLINE static void append(V &out, const char *const k, const void *const v, const unsigned int vlen)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE static void append(V &out, const char *const k, const void *const v, const unsigned int vlen)
|
||||
{
|
||||
s_appendKey(out, k);
|
||||
for (unsigned int i = 0; i < vlen; ++i)
|
||||
|
@ -369,7 +369,7 @@ public:
|
|||
* @param pid Packet ID
|
||||
*/
|
||||
template< typename V >
|
||||
static ZT_INLINE void appendPacketId(V &out, const char *const k, const uint64_t pid)
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE void appendPacketId(V &out, const char *const k, const uint64_t pid)
|
||||
{ append(out, k, &pid, 8); }
|
||||
|
||||
/**
|
||||
|
@ -381,7 +381,7 @@ public:
|
|||
* @return Bytes appended or negative on error (return value of marshal())
|
||||
*/
|
||||
template< typename V, typename T >
|
||||
static ZT_INLINE int appendObject(V &out, const char *const k, const T &v)
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE int appendObject(V &out, const char *const k, const T &v)
|
||||
{
|
||||
uint8_t tmp[2048]; // large enough for any current object
|
||||
if (T::marshalSizeMax() > sizeof(tmp))
|
||||
|
@ -400,7 +400,7 @@ public:
|
|||
* @param sub Subscript index
|
||||
* @return Pointer to 'buf'
|
||||
*/
|
||||
static char *arraySubscript(char *buf, unsigned int bufSize, const char *name, const unsigned long sub) noexcept;
|
||||
ZT_MAYBE_UNUSED static char *arraySubscript(char *buf, unsigned int bufSize, const char *name, const unsigned long sub) noexcept;
|
||||
|
||||
private:
|
||||
template< typename V >
|
||||
|
|
|
@ -68,7 +68,7 @@ public:
|
|||
|
||||
private:
|
||||
// Each bucket contains a timestamp in units of the max expect duration.
|
||||
std::atomic<uint32_t> m_packetIdSent[ZT_EXPECT_BUCKETS];
|
||||
std::atomic< uint32_t > m_packetIdSent[ZT_EXPECT_BUCKETS];
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
|
60
core/FCV.hpp
60
core/FCV.hpp
|
@ -81,7 +81,7 @@ public:
|
|||
/**
|
||||
* Clear this vector, destroying all content objects
|
||||
*/
|
||||
ZT_INLINE void clear()
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void clear()
|
||||
{
|
||||
const unsigned int s = _s;
|
||||
_s = 0;
|
||||
|
@ -94,51 +94,51 @@ public:
|
|||
*
|
||||
* @param v Target vector
|
||||
*/
|
||||
ZT_INLINE void unsafeMoveTo(FCV &v) noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void unsafeMoveTo(FCV &v) noexcept
|
||||
{
|
||||
Utils::copy(v._m, _m, (v._s = _s) * sizeof(T));
|
||||
_s = 0;
|
||||
}
|
||||
|
||||
ZT_INLINE iterator begin() noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE iterator begin() noexcept
|
||||
{ return reinterpret_cast<T *>(_m); }
|
||||
|
||||
ZT_INLINE iterator end() noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE iterator end() noexcept
|
||||
{ return reinterpret_cast<T *>(_m) + _s; }
|
||||
|
||||
ZT_INLINE const_iterator begin() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE const_iterator begin() const noexcept
|
||||
{ return reinterpret_cast<const T *>(_m); }
|
||||
|
||||
ZT_INLINE const_iterator end() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE const_iterator end() const noexcept
|
||||
{ return reinterpret_cast<const T *>(_m) + _s; }
|
||||
|
||||
ZT_INLINE T &operator[](const unsigned int i)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE T &operator[](const unsigned int i)
|
||||
{
|
||||
if (likely(i < _s))
|
||||
return reinterpret_cast<T *>(_m)[i];
|
||||
throw Utils::OutOfRangeException;
|
||||
}
|
||||
|
||||
ZT_INLINE const T &operator[](const unsigned int i) const
|
||||
ZT_MAYBE_UNUSED ZT_INLINE const T &operator[](const unsigned int i) const
|
||||
{
|
||||
if (likely(i < _s))
|
||||
return reinterpret_cast<const T *>(_m)[i];
|
||||
throw Utils::OutOfRangeException;
|
||||
}
|
||||
|
||||
static constexpr unsigned int capacity() noexcept
|
||||
ZT_MAYBE_UNUSED static constexpr unsigned int capacity() noexcept
|
||||
{ return C; }
|
||||
|
||||
ZT_INLINE unsigned int size() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE unsigned int size() const noexcept
|
||||
{ return _s; }
|
||||
|
||||
ZT_INLINE bool empty() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE bool empty() const noexcept
|
||||
{ return (_s == 0); }
|
||||
|
||||
ZT_INLINE T *data() noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE T *data() noexcept
|
||||
{ return reinterpret_cast<T *>(_m); }
|
||||
|
||||
ZT_INLINE const T *data() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE const T *data() const noexcept
|
||||
{ return reinterpret_cast<const T *>(_m); }
|
||||
|
||||
/**
|
||||
|
@ -148,7 +148,7 @@ public:
|
|||
*
|
||||
* @param v Value to push
|
||||
*/
|
||||
ZT_INLINE void push_back(const T &v)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void push_back(const T &v)
|
||||
{
|
||||
if (likely(_s < C))
|
||||
new(reinterpret_cast<T *>(_m) + _s++) T(v);
|
||||
|
@ -160,7 +160,7 @@ public:
|
|||
*
|
||||
* @return Reference to new item
|
||||
*/
|
||||
ZT_INLINE T &push()
|
||||
ZT_MAYBE_UNUSED ZT_INLINE T &push()
|
||||
{
|
||||
if (likely(_s < C)) {
|
||||
return *(new(reinterpret_cast<T *>(_m) + _s++) T());
|
||||
|
@ -174,7 +174,7 @@ public:
|
|||
*
|
||||
* @return Reference to new item
|
||||
*/
|
||||
ZT_INLINE T &push(const T &v)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE T &push(const T &v)
|
||||
{
|
||||
if (likely(_s < C)) {
|
||||
return *(new(reinterpret_cast<T *>(_m) + _s++) T(v));
|
||||
|
@ -188,7 +188,7 @@ public:
|
|||
/**
|
||||
* Remove the last element if this vector is not empty
|
||||
*/
|
||||
ZT_INLINE void pop_back()
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void pop_back()
|
||||
{
|
||||
if (likely(_s != 0))
|
||||
(reinterpret_cast<T *>(_m) + --_s)->~T();
|
||||
|
@ -199,7 +199,7 @@ public:
|
|||
*
|
||||
* @param ns New size (clipped to C if larger than capacity)
|
||||
*/
|
||||
ZT_INLINE void resize(unsigned int ns)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void resize(unsigned int ns)
|
||||
{
|
||||
if (unlikely(ns > C))
|
||||
throw Utils::OutOfRangeException;
|
||||
|
@ -216,7 +216,7 @@ public:
|
|||
*
|
||||
* @param ns New size
|
||||
*/
|
||||
ZT_INLINE void unsafeSetSize(unsigned int ns)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void unsafeSetSize(unsigned int ns)
|
||||
{ _s = ns; }
|
||||
|
||||
/**
|
||||
|
@ -228,7 +228,7 @@ public:
|
|||
* @param i Index to obtain as a reference, resizing if needed
|
||||
* @return Reference to value at this index
|
||||
*/
|
||||
ZT_INLINE T &at(unsigned int i)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE T &at(unsigned int i)
|
||||
{
|
||||
if (i >= _s) {
|
||||
if (unlikely(i >= C))
|
||||
|
@ -250,7 +250,7 @@ public:
|
|||
* @param end Ending iterator (must be greater than start)
|
||||
*/
|
||||
template< typename X >
|
||||
ZT_INLINE void assign(X start, const X &end)
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void assign(X start, const X &end)
|
||||
{
|
||||
const int l = std::min((int)std::distance(start, end), (int)C);
|
||||
if (l > 0) {
|
||||
|
@ -262,7 +262,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
ZT_INLINE bool operator==(const FCV &v) const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE bool operator==(const FCV &v) const noexcept
|
||||
{
|
||||
if (_s == v._s) {
|
||||
for (unsigned int i = 0; i < _s; ++i) {
|
||||
|
@ -274,20 +274,20 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
ZT_INLINE bool operator!=(const FCV &v) const noexcept
|
||||
{ return (!(*this == v)); }
|
||||
ZT_MAYBE_UNUSED ZT_INLINE bool operator!=(const FCV &v) const noexcept
|
||||
{ return *this != v; }
|
||||
|
||||
ZT_INLINE bool operator<(const FCV &v) const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE bool operator<(const FCV &v) const noexcept
|
||||
{ return std::lexicographical_compare(begin(), end(), v.begin(), v.end()); }
|
||||
|
||||
ZT_INLINE bool operator>(const FCV &v) const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE bool operator>(const FCV &v) const noexcept
|
||||
{ return (v < *this); }
|
||||
|
||||
ZT_INLINE bool operator<=(const FCV &v) const noexcept
|
||||
{ return !(v < *this); }
|
||||
ZT_MAYBE_UNUSED ZT_INLINE bool operator<=(const FCV &v) const noexcept
|
||||
{ return v >= *this; }
|
||||
|
||||
ZT_INLINE bool operator>=(const FCV &v) const noexcept
|
||||
{ return !(*this < v); }
|
||||
ZT_MAYBE_UNUSED ZT_INLINE bool operator>=(const FCV &v) const noexcept
|
||||
{ return *this >= v; }
|
||||
|
||||
private:
|
||||
#ifdef _MSC_VER
|
||||
|
|
|
@ -92,24 +92,6 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for equality with best possible specificity.
|
||||
*
|
||||
* If both fingerprints have a hash, that is compared. Otherwise just the
|
||||
* addresses are compared.
|
||||
*
|
||||
* @param fp Fingerprint to test
|
||||
*/
|
||||
ZT_INLINE bool bestSpecificityEquals(const ZT_Fingerprint &fp) const noexcept
|
||||
{
|
||||
if (address == fp.address) {
|
||||
if (Utils::allZero(fp.hash, ZT_FINGERPRINT_HASH_SIZE) || Utils::allZero(hash, ZT_FINGERPRINT_HASH_SIZE))
|
||||
return true;
|
||||
return (memcmp(hash, fp.hash, ZT_FINGERPRINT_HASH_SIZE) == 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ZT_INLINE void zero() noexcept
|
||||
{ memoryZero(this); }
|
||||
|
||||
|
|
|
@ -15,12 +15,10 @@
|
|||
#include "Identity.hpp"
|
||||
#include "SHA512.hpp"
|
||||
#include "Salsa20.hpp"
|
||||
#include "Poly1305.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "Endpoint.hpp"
|
||||
#include "MIMC52.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
|
@ -31,7 +29,7 @@ namespace {
|
|||
// This is the memory-intensive hash function used to compute v0 identities from v0 public keys.
|
||||
#define ZT_V0_IDENTITY_GEN_MEMORY 2097152
|
||||
|
||||
void identityV0ProofOfWorkFrankenhash(const void *const publicKey, unsigned int publicKeyBytes, void *const digest, void *const genmem) noexcept
|
||||
void identityV0ProofOfWorkFrankenhash(const void *const restrict publicKey, unsigned int publicKeyBytes, void *const restrict digest, void *const restrict genmem) noexcept
|
||||
{
|
||||
// Digest publicKey[] to obtain initial digest
|
||||
SHA512(digest, publicKey, publicKeyBytes);
|
||||
|
@ -68,7 +66,7 @@ void identityV0ProofOfWorkFrankenhash(const void *const publicKey, unsigned int
|
|||
|
||||
struct identityV0ProofOfWorkCriteria
|
||||
{
|
||||
ZT_INLINE identityV0ProofOfWorkCriteria(unsigned char *sb, char *gm) noexcept: digest(sb), genmem(gm)
|
||||
ZT_INLINE identityV0ProofOfWorkCriteria(unsigned char *restrict sb, char *restrict gm) noexcept: digest(sb), genmem(gm)
|
||||
{}
|
||||
|
||||
ZT_INLINE bool operator()(const uint8_t pub[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE]) const noexcept
|
||||
|
|
|
@ -27,7 +27,7 @@ const InetAddress InetAddress::LO4((const void *) ("\x7f\x00\x00\x01"), 4, 0);
|
|||
const InetAddress InetAddress::LO6((const void *) ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"), 16, 0);
|
||||
const InetAddress InetAddress::NIL;
|
||||
|
||||
InetAddress::IpScope InetAddress::ipScope() const noexcept
|
||||
ZT_MAYBE_UNUSED InetAddress::IpScope InetAddress::ipScope() const noexcept
|
||||
{
|
||||
switch (as.ss.ss_family) {
|
||||
|
||||
|
@ -40,17 +40,17 @@ InetAddress::IpScope InetAddress::ipScope() const noexcept
|
|||
return ZT_IP_SCOPE_PSEUDOPRIVATE; // 6.0.0.0/8 (US Army)
|
||||
case 0x0a:
|
||||
return ZT_IP_SCOPE_PRIVATE; // 10.0.0.0/8
|
||||
case 0x0b: //return IP_SCOPE_PSEUDOPRIVATE; // 11.0.0.0/8 (US DoD)
|
||||
case 0x15: //return IP_SCOPE_PSEUDOPRIVATE; // 21.0.0.0/8 (US DDN-RVN)
|
||||
case 0x16: //return IP_SCOPE_PSEUDOPRIVATE; // 22.0.0.0/8 (US DISA)
|
||||
case 0x19: //return IP_SCOPE_PSEUDOPRIVATE; // 25.0.0.0/8 (UK Ministry of Defense)
|
||||
case 0x1a: //return IP_SCOPE_PSEUDOPRIVATE; // 26.0.0.0/8 (US DISA)
|
||||
case 0x1c: //return IP_SCOPE_PSEUDOPRIVATE; // 28.0.0.0/8 (US DSI-North)
|
||||
case 0x1d: //return IP_SCOPE_PSEUDOPRIVATE; // 29.0.0.0/8 (US DISA)
|
||||
case 0x1e: //return IP_SCOPE_PSEUDOPRIVATE; // 30.0.0.0/8 (US DISA)
|
||||
case 0x33: //return IP_SCOPE_PSEUDOPRIVATE; // 51.0.0.0/8 (UK Department of Social Security)
|
||||
case 0x37: //return IP_SCOPE_PSEUDOPRIVATE; // 55.0.0.0/8 (US DoD)
|
||||
case 0x38: // 56.0.0.0/8 (US Postal Service)
|
||||
case 0x0b: //return IP_SCOPE_PSEUDOPRIVATE; // 11.0.0.0/8 (US DoD)
|
||||
case 0x15: //return IP_SCOPE_PSEUDOPRIVATE; // 21.0.0.0/8 (US DDN-RVN)
|
||||
case 0x16: //return IP_SCOPE_PSEUDOPRIVATE; // 22.0.0.0/8 (US DISA)
|
||||
case 0x19: //return IP_SCOPE_PSEUDOPRIVATE; // 25.0.0.0/8 (UK Ministry of Defense)
|
||||
case 0x1a: //return IP_SCOPE_PSEUDOPRIVATE; // 26.0.0.0/8 (US DISA)
|
||||
case 0x1c: //return IP_SCOPE_PSEUDOPRIVATE; // 28.0.0.0/8 (US DSI-North)
|
||||
case 0x1d: //return IP_SCOPE_PSEUDOPRIVATE; // 29.0.0.0/8 (US DISA)
|
||||
case 0x1e: //return IP_SCOPE_PSEUDOPRIVATE; // 30.0.0.0/8 (US DISA)
|
||||
case 0x33: //return IP_SCOPE_PSEUDOPRIVATE; // 51.0.0.0/8 (UK Department of Social Security)
|
||||
case 0x37: //return IP_SCOPE_PSEUDOPRIVATE; // 55.0.0.0/8 (US DoD)
|
||||
case 0x38: // 56.0.0.0/8 (US Postal Service)
|
||||
return ZT_IP_SCOPE_PSEUDOPRIVATE;
|
||||
case 0x64:
|
||||
if ((ip & 0xffc00000) == 0x64400000) return ZT_IP_SCOPE_PRIVATE; // 100.64.0.0/10
|
||||
|
@ -112,7 +112,7 @@ InetAddress::IpScope InetAddress::ipScope() const noexcept
|
|||
return ZT_IP_SCOPE_NONE;
|
||||
}
|
||||
|
||||
void InetAddress::set(const void *ipBytes, unsigned int ipLen, unsigned int port) noexcept
|
||||
ZT_MAYBE_UNUSED void InetAddress::set(const void *ipBytes, unsigned int ipLen, unsigned int port) noexcept
|
||||
{
|
||||
memoryZero(this);
|
||||
if (ipLen == 4) {
|
||||
|
@ -126,7 +126,7 @@ void InetAddress::set(const void *ipBytes, unsigned int ipLen, unsigned int port
|
|||
}
|
||||
}
|
||||
|
||||
bool InetAddress::isDefaultRoute() const noexcept
|
||||
ZT_MAYBE_UNUSED bool InetAddress::isDefaultRoute() const noexcept
|
||||
{
|
||||
switch (as.ss.ss_family) {
|
||||
case AF_INET:
|
||||
|
@ -145,7 +145,7 @@ bool InetAddress::isDefaultRoute() const noexcept
|
|||
}
|
||||
}
|
||||
|
||||
char *InetAddress::toString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noexcept
|
||||
ZT_MAYBE_UNUSED char *InetAddress::toString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noexcept
|
||||
{
|
||||
char *p = toIpString(buf);
|
||||
if (*p) {
|
||||
|
@ -156,7 +156,7 @@ char *InetAddress::toString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noex
|
|||
return buf;
|
||||
}
|
||||
|
||||
char *InetAddress::toIpString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noexcept
|
||||
ZT_MAYBE_UNUSED char *InetAddress::toIpString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noexcept
|
||||
{
|
||||
buf[0] = (char) 0;
|
||||
switch (as.ss.ss_family) {
|
||||
|
@ -170,7 +170,7 @@ char *InetAddress::toIpString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const no
|
|||
return buf;
|
||||
}
|
||||
|
||||
bool InetAddress::fromString(const char *ipSlashPort) noexcept
|
||||
ZT_MAYBE_UNUSED bool InetAddress::fromString(const char *ipSlashPort) noexcept
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
|
@ -205,7 +205,7 @@ bool InetAddress::fromString(const char *ipSlashPort) noexcept
|
|||
return false;
|
||||
}
|
||||
|
||||
InetAddress InetAddress::netmask() const noexcept
|
||||
ZT_MAYBE_UNUSED InetAddress InetAddress::netmask() const noexcept
|
||||
{
|
||||
InetAddress r(*this);
|
||||
switch (r.as.ss.ss_family) {
|
||||
|
@ -229,7 +229,7 @@ InetAddress InetAddress::netmask() const noexcept
|
|||
return r;
|
||||
}
|
||||
|
||||
InetAddress InetAddress::broadcast() const noexcept
|
||||
ZT_MAYBE_UNUSED InetAddress InetAddress::broadcast() const noexcept
|
||||
{
|
||||
if (as.ss.ss_family == AF_INET) {
|
||||
InetAddress r(*this);
|
||||
|
@ -239,7 +239,7 @@ InetAddress InetAddress::broadcast() const noexcept
|
|||
return InetAddress();
|
||||
}
|
||||
|
||||
InetAddress InetAddress::network() const noexcept
|
||||
ZT_MAYBE_UNUSED InetAddress InetAddress::network() const noexcept
|
||||
{
|
||||
InetAddress r(*this);
|
||||
switch (r.as.ss.ss_family) {
|
||||
|
@ -259,7 +259,7 @@ InetAddress InetAddress::network() const noexcept
|
|||
return r;
|
||||
}
|
||||
|
||||
bool InetAddress::isEqualPrefix(const InetAddress &addr) const noexcept
|
||||
ZT_MAYBE_UNUSED bool InetAddress::isEqualPrefix(const InetAddress &addr) const noexcept
|
||||
{
|
||||
if (addr.as.ss.ss_family == as.ss.ss_family) {
|
||||
switch (as.ss.ss_family) {
|
||||
|
@ -281,7 +281,7 @@ bool InetAddress::isEqualPrefix(const InetAddress &addr) const noexcept
|
|||
return false;
|
||||
}
|
||||
|
||||
bool InetAddress::containsAddress(const InetAddress &addr) const noexcept
|
||||
ZT_MAYBE_UNUSED bool InetAddress::containsAddress(const InetAddress &addr) const noexcept
|
||||
{
|
||||
if (addr.as.ss.ss_family == as.ss.ss_family) {
|
||||
switch (as.ss.ss_family) {
|
||||
|
@ -310,7 +310,7 @@ bool InetAddress::containsAddress(const InetAddress &addr) const noexcept
|
|||
return false;
|
||||
}
|
||||
|
||||
bool InetAddress::isNetwork() const noexcept
|
||||
ZT_MAYBE_UNUSED bool InetAddress::isNetwork() const noexcept
|
||||
{
|
||||
switch (as.ss.ss_family) {
|
||||
case AF_INET: {
|
||||
|
@ -342,7 +342,7 @@ bool InetAddress::isNetwork() const noexcept
|
|||
return false;
|
||||
}
|
||||
|
||||
int InetAddress::marshal(uint8_t data[ZT_INETADDRESS_MARSHAL_SIZE_MAX]) const noexcept
|
||||
ZT_MAYBE_UNUSED int InetAddress::marshal(uint8_t data[ZT_INETADDRESS_MARSHAL_SIZE_MAX]) const noexcept
|
||||
{
|
||||
unsigned int port;
|
||||
switch (as.ss.ss_family) {
|
||||
|
@ -369,7 +369,7 @@ int InetAddress::marshal(uint8_t data[ZT_INETADDRESS_MARSHAL_SIZE_MAX]) const no
|
|||
}
|
||||
}
|
||||
|
||||
int InetAddress::unmarshal(const uint8_t *restrict data, const int len) noexcept
|
||||
ZT_MAYBE_UNUSED int InetAddress::unmarshal(const uint8_t *restrict data, const int len) noexcept
|
||||
{
|
||||
memoryZero(this);
|
||||
if (unlikely(len <= 0))
|
||||
|
@ -396,7 +396,7 @@ int InetAddress::unmarshal(const uint8_t *restrict data, const int len) noexcept
|
|||
}
|
||||
}
|
||||
|
||||
InetAddress InetAddress::makeIpv6LinkLocal(const MAC &mac) noexcept
|
||||
ZT_MAYBE_UNUSED InetAddress InetAddress::makeIpv6LinkLocal(const MAC &mac) noexcept
|
||||
{
|
||||
InetAddress r;
|
||||
r.as.sa_in6.sin6_family = AF_INET6;
|
||||
|
@ -420,7 +420,7 @@ InetAddress InetAddress::makeIpv6LinkLocal(const MAC &mac) noexcept
|
|||
return r;
|
||||
}
|
||||
|
||||
InetAddress InetAddress::makeIpv6rfc4193(uint64_t nwid, uint64_t zeroTierAddress) noexcept
|
||||
ZT_MAYBE_UNUSED InetAddress InetAddress::makeIpv6rfc4193(uint64_t nwid, uint64_t zeroTierAddress) noexcept
|
||||
{
|
||||
InetAddress r;
|
||||
r.as.sa_in6.sin6_family = AF_INET6;
|
||||
|
@ -444,7 +444,7 @@ InetAddress InetAddress::makeIpv6rfc4193(uint64_t nwid, uint64_t zeroTierAddress
|
|||
return r;
|
||||
}
|
||||
|
||||
InetAddress InetAddress::makeIpv66plane(uint64_t nwid, uint64_t zeroTierAddress) noexcept
|
||||
ZT_MAYBE_UNUSED InetAddress InetAddress::makeIpv66plane(uint64_t nwid, uint64_t zeroTierAddress) noexcept
|
||||
{
|
||||
nwid ^= (nwid >> 32U);
|
||||
InetAddress r;
|
||||
|
@ -465,8 +465,8 @@ InetAddress InetAddress::makeIpv66plane(uint64_t nwid, uint64_t zeroTierAddress)
|
|||
}
|
||||
|
||||
extern "C" {
|
||||
extern const int ZT_AF_INET = (int)AF_INET;
|
||||
extern const int ZT_AF_INET6 = (int)AF_INET6;
|
||||
ZT_MAYBE_UNUSED extern const int ZT_AF_INET = (int)AF_INET;
|
||||
ZT_MAYBE_UNUSED extern const int ZT_AF_INET6 = (int)AF_INET6;
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
|
|
@ -60,13 +60,6 @@ public:
|
|||
*/
|
||||
typedef ZT_InetAddress_IpScope IpScope;
|
||||
|
||||
// Hasher for unordered sets and maps in C++11
|
||||
struct Hasher
|
||||
{
|
||||
ZT_INLINE std::size_t operator()(const InetAddress &a) const noexcept
|
||||
{ return (std::size_t)a.hashCode(); }
|
||||
};
|
||||
|
||||
ZT_INLINE InetAddress() noexcept
|
||||
{ memoryZero(this); }
|
||||
|
||||
|
@ -169,19 +162,13 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
ZT_INLINE void clear() noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void clear() noexcept
|
||||
{ memoryZero(this); }
|
||||
|
||||
/**
|
||||
* @return Address family (ss_family in sockaddr_storage)
|
||||
*/
|
||||
ZT_INLINE uint8_t family() const noexcept
|
||||
{ return as.ss.ss_family; }
|
||||
|
||||
/**
|
||||
* @return IP scope classification (e.g. loopback, link-local, private, global)
|
||||
*/
|
||||
IpScope ipScope() const noexcept;
|
||||
ZT_MAYBE_UNUSED IpScope ipScope() const noexcept;
|
||||
|
||||
/**
|
||||
* Set from a raw IP and port number
|
||||
|
@ -190,14 +177,14 @@ public:
|
|||
* @param ipLen Length of IP address: 4 or 16
|
||||
* @param port Port number or 0 for none
|
||||
*/
|
||||
void set(const void *ipBytes, unsigned int ipLen, unsigned int port) noexcept;
|
||||
ZT_MAYBE_UNUSED void set(const void *ipBytes, unsigned int ipLen, unsigned int port) noexcept;
|
||||
|
||||
/**
|
||||
* Set the port component
|
||||
*
|
||||
* @param port Port, 0 to 65535
|
||||
*/
|
||||
ZT_INLINE void setPort(unsigned int port) noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void setPort(unsigned int port) noexcept
|
||||
{
|
||||
switch (as.ss.ss_family) {
|
||||
case AF_INET:
|
||||
|
@ -212,14 +199,14 @@ public:
|
|||
/**
|
||||
* @return True if this network/netmask route describes a default route (e.g. 0.0.0.0/0)
|
||||
*/
|
||||
bool isDefaultRoute() const noexcept;
|
||||
ZT_MAYBE_UNUSED bool isDefaultRoute() const noexcept;
|
||||
|
||||
/**
|
||||
* @return ASCII IP/port format representation
|
||||
*/
|
||||
char *toString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noexcept;
|
||||
ZT_MAYBE_UNUSED char *toString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noexcept;
|
||||
|
||||
ZT_INLINE String toString() const
|
||||
ZT_MAYBE_UNUSED ZT_INLINE String toString() const
|
||||
{
|
||||
char buf[ZT_INETADDRESS_STRING_SIZE_MAX];
|
||||
toString(buf);
|
||||
|
@ -229,9 +216,9 @@ public:
|
|||
/**
|
||||
* @return IP portion only, in ASCII string format
|
||||
*/
|
||||
char *toIpString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noexcept;
|
||||
ZT_MAYBE_UNUSED char *toIpString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noexcept;
|
||||
|
||||
ZT_INLINE String toIpString() const
|
||||
ZT_MAYBE_UNUSED ZT_INLINE String toIpString() const
|
||||
{
|
||||
char buf[ZT_INETADDRESS_STRING_SIZE_MAX];
|
||||
toIpString(buf);
|
||||
|
@ -242,12 +229,12 @@ public:
|
|||
* @param ipSlashPort IP/port (port is optional, will be 0 if not included)
|
||||
* @return True if address appeared to be valid
|
||||
*/
|
||||
bool fromString(const char *ipSlashPort) noexcept;
|
||||
ZT_MAYBE_UNUSED bool fromString(const char *ipSlashPort) noexcept;
|
||||
|
||||
/**
|
||||
* @return Port or 0 if no port component defined
|
||||
*/
|
||||
ZT_INLINE unsigned int port() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE unsigned int port() const noexcept
|
||||
{
|
||||
switch (as.ss.ss_family) {
|
||||
case AF_INET:
|
||||
|
@ -268,13 +255,13 @@ public:
|
|||
*
|
||||
* @return Netmask bits
|
||||
*/
|
||||
ZT_INLINE unsigned int netmaskBits() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE unsigned int netmaskBits() const noexcept
|
||||
{ return port(); }
|
||||
|
||||
/**
|
||||
* @return True if netmask bits is valid for the address type
|
||||
*/
|
||||
ZT_INLINE bool netmaskBitsValid() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE bool netmaskBitsValid() const noexcept
|
||||
{
|
||||
const unsigned int n = port();
|
||||
switch (as.ss.ss_family) {
|
||||
|
@ -294,7 +281,7 @@ public:
|
|||
*
|
||||
* @return Gateway metric
|
||||
*/
|
||||
ZT_INLINE unsigned int metric() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE unsigned int metric() const noexcept
|
||||
{ return port(); }
|
||||
|
||||
/**
|
||||
|
@ -302,7 +289,7 @@ public:
|
|||
*
|
||||
* @return Netmask such as 255.255.255.0 if this address is /24 (port field will be unchanged)
|
||||
*/
|
||||
InetAddress netmask() const noexcept;
|
||||
ZT_MAYBE_UNUSED InetAddress netmask() const noexcept;
|
||||
|
||||
/**
|
||||
* Constructs a broadcast address from a network/netmask address
|
||||
|
@ -312,14 +299,14 @@ public:
|
|||
*
|
||||
* @return Broadcast address (only IP portion is meaningful)
|
||||
*/
|
||||
InetAddress broadcast() const noexcept;
|
||||
ZT_MAYBE_UNUSED InetAddress broadcast() const noexcept;
|
||||
|
||||
/**
|
||||
* Return the network -- a.k.a. the IP ANDed with the netmask
|
||||
*
|
||||
* @return Network e.g. 10.0.1.0/24 from 10.0.1.200/24
|
||||
*/
|
||||
InetAddress network() const noexcept;
|
||||
ZT_MAYBE_UNUSED InetAddress network() const noexcept;
|
||||
|
||||
/**
|
||||
* Test whether this IPv6 prefix matches the prefix of a given IPv6 address
|
||||
|
@ -327,7 +314,7 @@ public:
|
|||
* @param addr Address to check
|
||||
* @return True if this IPv6 prefix matches the prefix of a given IPv6 address
|
||||
*/
|
||||
bool isEqualPrefix(const InetAddress &addr) const noexcept;
|
||||
ZT_MAYBE_UNUSED bool isEqualPrefix(const InetAddress &addr) const noexcept;
|
||||
|
||||
/**
|
||||
* Test whether this IP/netmask contains this address
|
||||
|
@ -335,24 +322,24 @@ public:
|
|||
* @param addr Address to check
|
||||
* @return True if this IP/netmask (route) contains this address
|
||||
*/
|
||||
bool containsAddress(const InetAddress &addr) const noexcept;
|
||||
ZT_MAYBE_UNUSED bool containsAddress(const InetAddress &addr) const noexcept;
|
||||
|
||||
/**
|
||||
* @return True if this is an IPv4 address
|
||||
*/
|
||||
ZT_INLINE bool isV4() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE bool isV4() const noexcept
|
||||
{ return (as.ss.ss_family == AF_INET); }
|
||||
|
||||
/**
|
||||
* @return True if this is an IPv6 address
|
||||
*/
|
||||
ZT_INLINE bool isV6() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE bool isV6() const noexcept
|
||||
{ return (as.ss.ss_family == AF_INET6); }
|
||||
|
||||
/**
|
||||
* @return pointer to raw address bytes or NULL if not available
|
||||
*/
|
||||
ZT_INLINE const void *rawIpData() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE const void *rawIpData() const noexcept
|
||||
{
|
||||
switch (as.ss.ss_family) {
|
||||
case AF_INET:
|
||||
|
@ -367,7 +354,7 @@ public:
|
|||
/**
|
||||
* @return InetAddress containing only the IP portion of this address and a zero port, or NULL if not IPv4 or IPv6
|
||||
*/
|
||||
ZT_INLINE InetAddress ipOnly() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE InetAddress ipOnly() const noexcept
|
||||
{
|
||||
InetAddress r;
|
||||
switch (as.ss.ss_family) {
|
||||
|
@ -389,7 +376,7 @@ public:
|
|||
* @param a InetAddress to compare again
|
||||
* @return True if only IP portions are equal (false for non-IP or null addresses)
|
||||
*/
|
||||
ZT_INLINE bool ipsEqual(const InetAddress &a) const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE bool ipsEqual(const InetAddress &a) const noexcept
|
||||
{
|
||||
const uint8_t f = as.ss.ss_family;
|
||||
if (f == a.as.ss.ss_family) {
|
||||
|
@ -410,7 +397,7 @@ public:
|
|||
* @param a InetAddress to compare again
|
||||
* @return True if only IP portions are equal (false for non-IP or null addresses)
|
||||
*/
|
||||
ZT_INLINE bool ipsEqual2(const InetAddress &a) const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE bool ipsEqual2(const InetAddress &a) const noexcept
|
||||
{
|
||||
const uint8_t f = as.ss.ss_family;
|
||||
if (f == a.as.ss.ss_family) {
|
||||
|
@ -423,7 +410,7 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
ZT_INLINE unsigned long hashCode() const noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE unsigned long hashCode() const noexcept
|
||||
{
|
||||
if (as.ss.ss_family == AF_INET) {
|
||||
return (unsigned long)Utils::hash32(((uint32_t)as.sa_in.sin_addr.s_addr + (uint32_t)as.sa_in.sin_port) ^ (uint32_t)Utils::s_mapNonce);
|
||||
|
@ -445,20 +432,20 @@ public:
|
|||
*
|
||||
* @return True if everything after netmask bits is zero
|
||||
*/
|
||||
bool isNetwork() const noexcept;
|
||||
ZT_MAYBE_UNUSED bool isNetwork() const noexcept;
|
||||
|
||||
/**
|
||||
* @return True if address family is non-zero
|
||||
*/
|
||||
explicit ZT_INLINE operator bool() const noexcept
|
||||
ZT_MAYBE_UNUSED explicit ZT_INLINE operator bool() const noexcept
|
||||
{ return (as.ss.ss_family != 0); }
|
||||
|
||||
static constexpr int marshalSizeMax() noexcept
|
||||
ZT_MAYBE_UNUSED static constexpr int marshalSizeMax() noexcept
|
||||
{ return ZT_INETADDRESS_MARSHAL_SIZE_MAX; }
|
||||
|
||||
int marshal(uint8_t data[ZT_INETADDRESS_MARSHAL_SIZE_MAX]) const noexcept;
|
||||
ZT_MAYBE_UNUSED int marshal(uint8_t data[ZT_INETADDRESS_MARSHAL_SIZE_MAX]) const noexcept;
|
||||
|
||||
int unmarshal(const uint8_t *restrict data, int len) noexcept;
|
||||
ZT_MAYBE_UNUSED int unmarshal(const uint8_t *restrict data, int len) noexcept;
|
||||
|
||||
ZT_INLINE bool operator==(const InetAddress &a) const noexcept
|
||||
{
|
||||
|
@ -512,7 +499,7 @@ public:
|
|||
* @param mac MAC address seed
|
||||
* @return IPv6 link-local address
|
||||
*/
|
||||
static InetAddress makeIpv6LinkLocal(const MAC &mac) noexcept;
|
||||
ZT_MAYBE_UNUSED static InetAddress makeIpv6LinkLocal(const MAC &mac) noexcept;
|
||||
|
||||
/**
|
||||
* Compute private IPv6 unicast address from network ID and ZeroTier address
|
||||
|
@ -574,64 +561,64 @@ public:
|
|||
} as;
|
||||
};
|
||||
|
||||
static ZT_INLINE InetAddress *asInetAddress(sockaddr_in *const p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE InetAddress *asInetAddress(sockaddr_in *const p) noexcept
|
||||
{ return reinterpret_cast<InetAddress *>(p); }
|
||||
|
||||
static ZT_INLINE InetAddress *asInetAddress(sockaddr_in6 *const p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE InetAddress *asInetAddress(sockaddr_in6 *const p) noexcept
|
||||
{ return reinterpret_cast<InetAddress *>(p); }
|
||||
|
||||
static ZT_INLINE InetAddress *asInetAddress(sockaddr *const p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE InetAddress *asInetAddress(sockaddr *const p) noexcept
|
||||
{ return reinterpret_cast<InetAddress *>(p); }
|
||||
|
||||
static ZT_INLINE InetAddress *asInetAddress(sockaddr_storage *const p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE InetAddress *asInetAddress(sockaddr_storage *const p) noexcept
|
||||
{ return reinterpret_cast<InetAddress *>(p); }
|
||||
|
||||
static ZT_INLINE InetAddress *asInetAddress(ZT_InetAddress *const p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE InetAddress *asInetAddress(ZT_InetAddress *const p) noexcept
|
||||
{ return reinterpret_cast<InetAddress *>(p); }
|
||||
|
||||
static ZT_INLINE const InetAddress *asInetAddress(const sockaddr_in *const p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE const InetAddress *asInetAddress(const sockaddr_in *const p) noexcept
|
||||
{ return reinterpret_cast<const InetAddress *>(p); }
|
||||
|
||||
static ZT_INLINE const InetAddress *asInetAddress(const sockaddr_in6 *const p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE const InetAddress *asInetAddress(const sockaddr_in6 *const p) noexcept
|
||||
{ return reinterpret_cast<const InetAddress *>(p); }
|
||||
|
||||
static ZT_INLINE const InetAddress *asInetAddress(const sockaddr *const p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE const InetAddress *asInetAddress(const sockaddr *const p) noexcept
|
||||
{ return reinterpret_cast<const InetAddress *>(p); }
|
||||
|
||||
static ZT_INLINE const InetAddress *asInetAddress(const sockaddr_storage *const p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE const InetAddress *asInetAddress(const sockaddr_storage *const p) noexcept
|
||||
{ return reinterpret_cast<const InetAddress *>(p); }
|
||||
|
||||
static ZT_INLINE const InetAddress *asInetAddress(const ZT_InetAddress *const p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE const InetAddress *asInetAddress(const ZT_InetAddress *const p) noexcept
|
||||
{ return reinterpret_cast<const InetAddress *>(p); }
|
||||
|
||||
static ZT_INLINE InetAddress &asInetAddress(sockaddr_in &p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE InetAddress &asInetAddress(sockaddr_in &p) noexcept
|
||||
{ return *reinterpret_cast<InetAddress *>(&p); }
|
||||
|
||||
static ZT_INLINE InetAddress &asInetAddress(sockaddr_in6 &p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE InetAddress &asInetAddress(sockaddr_in6 &p) noexcept
|
||||
{ return *reinterpret_cast<InetAddress *>(&p); }
|
||||
|
||||
static ZT_INLINE InetAddress &asInetAddress(sockaddr &p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE InetAddress &asInetAddress(sockaddr &p) noexcept
|
||||
{ return *reinterpret_cast<InetAddress *>(&p); }
|
||||
|
||||
static ZT_INLINE InetAddress &asInetAddress(sockaddr_storage &p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE InetAddress &asInetAddress(sockaddr_storage &p) noexcept
|
||||
{ return *reinterpret_cast<InetAddress *>(&p); }
|
||||
|
||||
static ZT_INLINE InetAddress &asInetAddress(ZT_InetAddress &p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE InetAddress &asInetAddress(ZT_InetAddress &p) noexcept
|
||||
{ return *reinterpret_cast<InetAddress *>(&p); }
|
||||
|
||||
static ZT_INLINE const InetAddress &asInetAddress(const sockaddr_in &p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE const InetAddress &asInetAddress(const sockaddr_in &p) noexcept
|
||||
{ return *reinterpret_cast<const InetAddress *>(&p); }
|
||||
|
||||
static ZT_INLINE const InetAddress &asInetAddress(const sockaddr_in6 &p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE const InetAddress &asInetAddress(const sockaddr_in6 &p) noexcept
|
||||
{ return *reinterpret_cast<const InetAddress *>(&p); }
|
||||
|
||||
static ZT_INLINE const InetAddress &asInetAddress(const sockaddr &p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE const InetAddress &asInetAddress(const sockaddr &p) noexcept
|
||||
{ return *reinterpret_cast<const InetAddress *>(&p); }
|
||||
|
||||
static ZT_INLINE const InetAddress &asInetAddress(const sockaddr_storage &p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE const InetAddress &asInetAddress(const sockaddr_storage &p) noexcept
|
||||
{ return *reinterpret_cast<const InetAddress *>(&p); }
|
||||
|
||||
static ZT_INLINE const InetAddress &asInetAddress(const ZT_InetAddress &p) noexcept
|
||||
ZT_MAYBE_UNUSED static ZT_INLINE const InetAddress &asInetAddress(const ZT_InetAddress &p) noexcept
|
||||
{ return *reinterpret_cast<const InetAddress *>(&p); }
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
|
|
@ -24,7 +24,7 @@ Locator::Locator(const char *const str) noexcept :
|
|||
__refCount(0)
|
||||
{
|
||||
if (!fromString(str)) {
|
||||
m_ts = 0;
|
||||
m_revision = 0;
|
||||
m_signer.zero();
|
||||
m_endpoints.clear();
|
||||
m_signature.clear();
|
||||
|
@ -46,9 +46,9 @@ bool Locator::add(const Endpoint &ep, const SharedPtr< const EndpointAttributes
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Locator::sign(const int64_t ts, const Identity &id) noexcept
|
||||
bool Locator::sign(const int64_t rev, const Identity &id) noexcept
|
||||
{
|
||||
m_ts = ts;
|
||||
m_revision = rev;
|
||||
m_signer = id.fingerprint();
|
||||
|
||||
m_sortEndpoints();
|
||||
|
@ -67,7 +67,7 @@ bool Locator::sign(const int64_t ts, const Identity &id) noexcept
|
|||
bool Locator::verify(const Identity &id) const noexcept
|
||||
{
|
||||
try {
|
||||
if ((m_ts > 0) && (m_signer == id.fingerprint())) {
|
||||
if ((m_revision > 0) && (m_signer == id.fingerprint())) {
|
||||
uint8_t signdata[ZT_LOCATOR_MARSHAL_SIZE_MAX];
|
||||
const unsigned int signlen = marshal(signdata, true);
|
||||
return id.verify(signdata, signlen, m_signature.data(), m_signature.size());
|
||||
|
@ -101,7 +101,7 @@ bool Locator::fromString(const char *s) noexcept
|
|||
|
||||
int Locator::marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX], const bool excludeSignature) const noexcept
|
||||
{
|
||||
Utils::storeBigEndian<uint64_t>(data, (uint64_t) m_ts);
|
||||
Utils::storeBigEndian<uint64_t>(data, (uint64_t) m_revision);
|
||||
int p = 8;
|
||||
|
||||
int l = m_signer.marshal(data + p);
|
||||
|
@ -143,7 +143,7 @@ int Locator::unmarshal(const uint8_t *data, const int len) noexcept
|
|||
{
|
||||
if (unlikely(len < 8))
|
||||
return -1;
|
||||
m_ts = (int64_t)Utils::loadBigEndian<uint64_t>(data);
|
||||
m_revision = (int64_t)Utils::loadBigEndian<uint64_t>(data);
|
||||
int p = 8;
|
||||
|
||||
int l = m_signer.unmarshal(data + p, len - p);
|
||||
|
|
|
@ -106,13 +106,13 @@ public:
|
|||
};
|
||||
|
||||
ZT_INLINE Locator() noexcept:
|
||||
m_ts(0)
|
||||
m_revision(0)
|
||||
{}
|
||||
|
||||
explicit Locator(const char *const str) noexcept;
|
||||
|
||||
ZT_INLINE Locator(const Locator &loc) noexcept:
|
||||
m_ts(loc.m_ts),
|
||||
m_revision(loc.m_revision),
|
||||
m_signer(loc.m_signer),
|
||||
m_endpoints(loc.m_endpoints),
|
||||
m_signature(loc.m_signature),
|
||||
|
@ -122,8 +122,8 @@ public:
|
|||
/**
|
||||
* @return Timestamp (a.k.a. revision number) set by Location signer
|
||||
*/
|
||||
ZT_INLINE int64_t timestamp() const noexcept
|
||||
{ return m_ts; }
|
||||
ZT_INLINE int64_t revision() const noexcept
|
||||
{ return m_revision; }
|
||||
|
||||
/**
|
||||
* @return Fingerprint of identity that signed this locator
|
||||
|
@ -164,7 +164,7 @@ public:
|
|||
* @param id Identity that includes private key
|
||||
* @return True if signature successful
|
||||
*/
|
||||
bool sign(int64_t ts, const Identity &id) noexcept;
|
||||
bool sign(int64_t rev, const Identity &id) noexcept;
|
||||
|
||||
/**
|
||||
* Verify this Locator's validity and signature
|
||||
|
@ -197,7 +197,7 @@ public:
|
|||
bool fromString(const char *s) noexcept;
|
||||
|
||||
explicit ZT_INLINE operator bool() const noexcept
|
||||
{ return m_ts > 0; }
|
||||
{ return m_revision > 0; }
|
||||
|
||||
static constexpr int marshalSizeMax() noexcept
|
||||
{ return ZT_LOCATOR_MARSHAL_SIZE_MAX; }
|
||||
|
@ -207,7 +207,7 @@ public:
|
|||
ZT_INLINE bool operator==(const Locator &l) const noexcept
|
||||
{
|
||||
const unsigned long es = (unsigned long)m_endpoints.size();
|
||||
if ((m_ts == l.m_ts) && (m_signer == l.m_signer) && (es == (unsigned long)l.m_endpoints.size()) && (m_signature == l.m_signature)) {
|
||||
if ((m_revision == l.m_revision) && (m_signer == l.m_signer) && (es == (unsigned long)l.m_endpoints.size()) && (m_signature == l.m_signature)) {
|
||||
for(unsigned long i=0;i<es;++i) {
|
||||
if (m_endpoints[i].first != l.m_endpoints[i].first)
|
||||
return false;
|
||||
|
@ -229,7 +229,7 @@ public:
|
|||
private:
|
||||
void m_sortEndpoints() noexcept;
|
||||
|
||||
int64_t m_ts;
|
||||
int64_t m_revision;
|
||||
Fingerprint m_signer;
|
||||
Vector< std::pair< Endpoint, SharedPtr< const EndpointAttributes > > > m_endpoints;
|
||||
FCV< uint8_t, ZT_SIGNATURE_BUFFER_SIZE > m_signature;
|
||||
|
|
|
@ -28,7 +28,7 @@ Member::Member() :
|
|||
{
|
||||
}
|
||||
|
||||
void Member::pushCredentials(const RuntimeEnvironment *RR, void *tPtr, const int64_t now, const SharedPtr< Peer > &to, const NetworkConfig &nconf)
|
||||
void Member::pushCredentials(const RuntimeEnvironment *RR, CallContext &cc, const SharedPtr< Peer > &to, const NetworkConfig &nconf)
|
||||
{
|
||||
if (!nconf.com) // sanity check
|
||||
return;
|
||||
|
@ -112,7 +112,7 @@ void Member::pushCredentials(const RuntimeEnvironment *RR, void *tPtr, const int
|
|||
}
|
||||
#endif
|
||||
|
||||
m_lastPushedCredentials = now;
|
||||
m_lastPushedCredentials = cc.ticks;
|
||||
}
|
||||
|
||||
void Member::clean(const NetworkConfig &nconf)
|
||||
|
@ -122,31 +122,31 @@ void Member::clean(const NetworkConfig &nconf)
|
|||
m_cleanCredImpl< OwnershipCredential >(nconf, m_remoteCoos);
|
||||
}
|
||||
|
||||
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, void *tPtr, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const MembershipCredential &com)
|
||||
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const MembershipCredential &com)
|
||||
{
|
||||
const int64_t newts = com.timestamp();
|
||||
if (newts <= m_comRevocationThreshold) {
|
||||
RR->t->credentialRejected(tPtr, 0xd9992121, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
|
||||
RR->t->credentialRejected(cc, 0xd9992121, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
|
||||
return ADD_REJECTED;
|
||||
}
|
||||
|
||||
const int64_t oldts = m_com.timestamp();
|
||||
if (newts < oldts) {
|
||||
RR->t->credentialRejected(tPtr, 0xd9928192, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
|
||||
RR->t->credentialRejected(cc, 0xd9928192, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
|
||||
return ADD_REJECTED;
|
||||
}
|
||||
if ((newts == oldts) && (m_com == com))
|
||||
return ADD_ACCEPTED_REDUNDANT;
|
||||
|
||||
switch (com.verify(RR, tPtr)) {
|
||||
switch (com.verify(RR, cc)) {
|
||||
default:
|
||||
RR->t->credentialRejected(tPtr, 0x0f198241, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
|
||||
RR->t->credentialRejected(cc, 0x0f198241, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
|
||||
return Member::ADD_REJECTED;
|
||||
case Credential::VERIFY_OK:
|
||||
m_com = com;
|
||||
return ADD_ACCEPTED_NEW;
|
||||
case Credential::VERIFY_BAD_SIGNATURE:
|
||||
RR->t->credentialRejected(tPtr, 0xbaf0aaaa, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_SIGNATURE_VERIFICATION_FAILED);
|
||||
RR->t->credentialRejected(cc, 0xbaf0aaaa, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_SIGNATURE_VERIFICATION_FAILED);
|
||||
return ADD_REJECTED;
|
||||
case Credential::VERIFY_NEED_IDENTITY:
|
||||
return ADD_DEFERRED_FOR_WHOIS;
|
||||
|
@ -159,15 +159,15 @@ static ZT_INLINE Member::AddCredentialResult _addCredImpl(
|
|||
Map< uint32_t, C > &remoteCreds,
|
||||
const Map< uint64_t, int64_t > &revocations,
|
||||
const RuntimeEnvironment *const RR,
|
||||
void *const tPtr,
|
||||
CallContext &cc,
|
||||
const Identity &sourcePeerIdentity,
|
||||
const NetworkConfig &nconf,
|
||||
const C &cred)
|
||||
{
|
||||
typename Map< uint32_t, C >::const_iterator rc(remoteCreds.find(cred.id()));
|
||||
if (rc != remoteCreds.end()) {
|
||||
if (rc->second.timestamp() > cred.timestamp()) {
|
||||
RR->t->credentialRejected(tPtr, 0x40000001, nconf.networkId, sourcePeerIdentity, cred.id(), cred.timestamp(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
|
||||
if (rc->second.revision() > cred.revision()) {
|
||||
RR->t->credentialRejected(cc, 0x40000001, nconf.networkId, sourcePeerIdentity, cred.id(), cred.revision(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
|
||||
return Member::ADD_REJECTED;
|
||||
}
|
||||
if (rc->second == cred)
|
||||
|
@ -175,14 +175,14 @@ static ZT_INLINE Member::AddCredentialResult _addCredImpl(
|
|||
}
|
||||
|
||||
typename Map< uint64_t, int64_t >::const_iterator rt(revocations.find(Member::credentialKey(C::credentialType(), cred.id())));
|
||||
if ((rt != revocations.end()) && (rt->second >= cred.timestamp())) {
|
||||
RR->t->credentialRejected(tPtr, 0x24248124, nconf.networkId, sourcePeerIdentity, cred.id(), cred.timestamp(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
|
||||
if ((rt != revocations.end()) && (rt->second >= cred.revision())) {
|
||||
RR->t->credentialRejected(cc, 0x24248124, nconf.networkId, sourcePeerIdentity, cred.id(), cred.revision(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
|
||||
return Member::ADD_REJECTED;
|
||||
}
|
||||
|
||||
switch (cred.verify(RR, tPtr)) {
|
||||
switch (cred.verify(RR, cc)) {
|
||||
default:
|
||||
RR->t->credentialRejected(tPtr, 0x01feba012, nconf.networkId, sourcePeerIdentity, cred.id(), cred.timestamp(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
|
||||
RR->t->credentialRejected(cc, 0x01feba012, nconf.networkId, sourcePeerIdentity, cred.id(), cred.revision(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
|
||||
return Member::ADD_REJECTED;
|
||||
case 0:
|
||||
if (rc == remoteCreds.end())
|
||||
|
@ -193,21 +193,21 @@ static ZT_INLINE Member::AddCredentialResult _addCredImpl(
|
|||
}
|
||||
}
|
||||
|
||||
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, void *tPtr, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const TagCredential &tag)
|
||||
{ return _addCredImpl< TagCredential >(m_remoteTags, m_revocations, RR, tPtr, sourcePeerIdentity, nconf, tag); }
|
||||
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const TagCredential &tag)
|
||||
{ return _addCredImpl< TagCredential >(m_remoteTags, m_revocations, RR, cc, sourcePeerIdentity, nconf, tag); }
|
||||
|
||||
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, void *tPtr, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const CapabilityCredential &cap)
|
||||
{ return _addCredImpl< CapabilityCredential >(m_remoteCaps, m_revocations, RR, tPtr, sourcePeerIdentity, nconf, cap); }
|
||||
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const CapabilityCredential &cap)
|
||||
{ return _addCredImpl< CapabilityCredential >(m_remoteCaps, m_revocations, RR, cc, sourcePeerIdentity, nconf, cap); }
|
||||
|
||||
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, void *tPtr, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const OwnershipCredential &coo)
|
||||
{ return _addCredImpl< OwnershipCredential >(m_remoteCoos, m_revocations, RR, tPtr, sourcePeerIdentity, nconf, coo); }
|
||||
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const OwnershipCredential &coo)
|
||||
{ return _addCredImpl< OwnershipCredential >(m_remoteCoos, m_revocations, RR, cc, sourcePeerIdentity, nconf, coo); }
|
||||
|
||||
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, void *tPtr, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const RevocationCredential &rev)
|
||||
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const RevocationCredential &rev)
|
||||
{
|
||||
int64_t *rt;
|
||||
switch (rev.verify(RR, tPtr)) {
|
||||
switch (rev.verify(RR, cc)) {
|
||||
default:
|
||||
RR->t->credentialRejected(tPtr, 0x938fffff, nconf.networkId, sourcePeerIdentity, rev.id(), 0, ZT_CREDENTIAL_TYPE_REVOCATION, ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
|
||||
RR->t->credentialRejected(cc, 0x938fffff, nconf.networkId, sourcePeerIdentity, rev.id(), 0, ZT_CREDENTIAL_TYPE_REVOCATION, ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
|
||||
return ADD_REJECTED;
|
||||
case 0: {
|
||||
const ZT_CredentialType ct = rev.typeBeingRevoked();
|
||||
|
@ -229,7 +229,7 @@ Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR,
|
|||
}
|
||||
return ADD_ACCEPTED_REDUNDANT;
|
||||
default:
|
||||
RR->t->credentialRejected(tPtr, 0x0bbbb1a4, nconf.networkId, sourcePeerIdentity, rev.id(), 0, ZT_CREDENTIAL_TYPE_REVOCATION, ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
|
||||
RR->t->credentialRejected(cc, 0x0bbbb1a4, nconf.networkId, sourcePeerIdentity, rev.id(), 0, ZT_CREDENTIAL_TYPE_REVOCATION, ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
|
||||
return ADD_REJECTED;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
namespace ZeroTier {
|
||||
|
||||
class RuntimeEnvironment;
|
||||
|
||||
class Network;
|
||||
|
||||
/**
|
||||
|
@ -51,18 +52,16 @@ public:
|
|||
/**
|
||||
* Send COM and other credentials to this peer
|
||||
*
|
||||
* @param RR Runtime environment
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param now Current time
|
||||
* @param to Peer identity
|
||||
* @param nconf My network config
|
||||
*/
|
||||
void pushCredentials(const RuntimeEnvironment *RR,void *tPtr,int64_t now,const SharedPtr<Peer> &to,const NetworkConfig &nconf);
|
||||
void pushCredentials(const RuntimeEnvironment *RR, CallContext &cc, const SharedPtr< Peer > &to, const NetworkConfig &nconf);
|
||||
|
||||
/**
|
||||
* @return Time we last pushed credentials to this member
|
||||
*/
|
||||
ZT_INLINE int64_t lastPushedCredentials() const noexcept { return m_lastPushedCredentials; }
|
||||
ZT_INLINE int64_t lastPushedCredentials() const noexcept
|
||||
{ return m_lastPushedCredentials; }
|
||||
|
||||
/**
|
||||
* Get a remote member's tag (if we have it)
|
||||
|
@ -74,7 +73,7 @@ public:
|
|||
ZT_INLINE const TagCredential *getTag(const NetworkConfig &nconf, const uint32_t id) const noexcept
|
||||
{
|
||||
Map< uint32_t, TagCredential >::const_iterator t(m_remoteTags.find(id));
|
||||
return (((t != m_remoteTags.end())&&(m_isCredentialTimestampValid(nconf, t->second))) ? &(t->second) : (TagCredential *)0);
|
||||
return (((t != m_remoteTags.end()) && (m_isCredentialTimestampValid(nconf, t->second))) ? &(t->second) : (TagCredential *)0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,7 +86,8 @@ public:
|
|||
/**
|
||||
* Generates a key for internal use in indexing credentials by type and credential ID
|
||||
*/
|
||||
static ZT_INLINE uint64_t credentialKey(const ZT_CredentialType &t,const uint32_t i) noexcept { return (((uint64_t)t << 32U) | (uint64_t)i); }
|
||||
static ZT_INLINE uint64_t credentialKey(const ZT_CredentialType &t, const uint32_t i) noexcept
|
||||
{ return (((uint64_t)t << 32U) | (uint64_t)i); }
|
||||
|
||||
/**
|
||||
* Check whether the peer represented by this Membership owns a given address
|
||||
|
@ -97,12 +97,12 @@ public:
|
|||
* @param r Resource to check
|
||||
* @return True if this peer has a certificate of ownership for the given resource
|
||||
*/
|
||||
template<typename T>
|
||||
template< typename T >
|
||||
ZT_INLINE bool peerOwnsAddress(const NetworkConfig &nconf, const T &r) const noexcept
|
||||
{
|
||||
if (m_isUnspoofableAddress(nconf, r))
|
||||
return true;
|
||||
for(Map< uint32_t,OwnershipCredential >::const_iterator i(m_remoteCoos.begin()); i != m_remoteCoos.end(); ++i) {
|
||||
for (Map< uint32_t, OwnershipCredential >::const_iterator i(m_remoteCoos.begin()); i != m_remoteCoos.end(); ++i) {
|
||||
if (m_isCredentialTimestampValid(nconf, i->second) && (i->second.owns(r)))
|
||||
return true;
|
||||
}
|
||||
|
@ -145,36 +145,38 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const Identity &sourcePeerIdentity,const NetworkConfig &nconf,const MembershipCredential &com);
|
||||
AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const Identity &sourcePeerIdentity,const NetworkConfig &nconf,const TagCredential &tag);
|
||||
AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const Identity &sourcePeerIdentity,const NetworkConfig &nconf,const CapabilityCredential &cap);
|
||||
AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const Identity &sourcePeerIdentity,const NetworkConfig &nconf,const OwnershipCredential &coo);
|
||||
AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const Identity &sourcePeerIdentity,const NetworkConfig &nconf,const RevocationCredential &rev);
|
||||
AddCredentialResult addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const MembershipCredential &com);
|
||||
AddCredentialResult addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const TagCredential &tag);
|
||||
AddCredentialResult addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const CapabilityCredential &cap);
|
||||
AddCredentialResult addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const OwnershipCredential &coo);
|
||||
AddCredentialResult addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const RevocationCredential &rev);
|
||||
|
||||
private:
|
||||
// This returns true if a resource is an IPv6 NDP-emulated address. These embed the ZT
|
||||
// address of the peer and therefore cannot be spoofed, causing peerOwnsAddress() to
|
||||
// always return true for them. A certificate is not required for these.
|
||||
ZT_INLINE bool m_isUnspoofableAddress(const NetworkConfig &nconf, const MAC &m) const noexcept { return false; }
|
||||
ZT_INLINE bool m_isUnspoofableAddress(const NetworkConfig &nconf, const MAC &m) const noexcept
|
||||
{ return false; }
|
||||
|
||||
bool m_isUnspoofableAddress(const NetworkConfig &nconf, const InetAddress &ip) const noexcept;
|
||||
|
||||
// This compares the remote credential's timestamp to the timestamp in our network config
|
||||
// plus or minus the permitted maximum timestamp delta.
|
||||
template<typename C>
|
||||
template< typename C >
|
||||
ZT_INLINE bool m_isCredentialTimestampValid(const NetworkConfig &nconf, const C &remoteCredential) const noexcept
|
||||
{
|
||||
const int64_t ts = remoteCredential.timestamp();
|
||||
const int64_t ts = remoteCredential.revision();
|
||||
if (((ts >= nconf.timestamp) ? (ts - nconf.timestamp) : (nconf.timestamp - ts)) <= nconf.credentialTimeMaxDelta) {
|
||||
Map< uint64_t, int64_t >::const_iterator threshold(m_revocations.find(credentialKey(C::credentialType(), remoteCredential.id())));
|
||||
return ((threshold == m_revocations.end())||(ts > threshold->second));
|
||||
return ((threshold == m_revocations.end()) || (ts > threshold->second));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
ZT_INLINE void m_cleanCredImpl(const NetworkConfig &nconf, Map<uint32_t,C> &remoteCreds)
|
||||
template< typename C >
|
||||
ZT_INLINE void m_cleanCredImpl(const NetworkConfig &nconf, Map< uint32_t, C > &remoteCreds)
|
||||
{
|
||||
for(typename Map<uint32_t,C>::iterator i(remoteCreds.begin());i!=remoteCreds.end();) {
|
||||
for (typename Map< uint32_t, C >::iterator i(remoteCreds.begin()); i != remoteCreds.end();) {
|
||||
if (!m_isCredentialTimestampValid(nconf, i->second))
|
||||
remoteCreds.erase(i++);
|
||||
else ++i;
|
||||
|
@ -188,24 +190,24 @@ private:
|
|||
int64_t m_lastPushedCredentials;
|
||||
|
||||
// COM timestamps at which we last agreed-- used to memo-ize agreement and avoid having to recompute constantly.
|
||||
int64_t m_comAgreementLocalTimestamp,m_comAgreementRemoteTimestamp;
|
||||
int64_t m_comAgreementLocalTimestamp, m_comAgreementRemoteTimestamp;
|
||||
|
||||
// Remote member's latest network COM
|
||||
MembershipCredential m_com;
|
||||
|
||||
// Revocations by credentialKey()
|
||||
Map<uint64_t,int64_t> m_revocations;
|
||||
Map< uint64_t, int64_t > m_revocations;
|
||||
|
||||
// Remote credentials that we have received from this member (and that are valid)
|
||||
Map<uint32_t,TagCredential> m_remoteTags;
|
||||
Map<uint32_t,CapabilityCredential> m_remoteCaps;
|
||||
Map<uint32_t,OwnershipCredential> m_remoteCoos;
|
||||
Map< uint32_t, TagCredential > m_remoteTags;
|
||||
Map< uint32_t, CapabilityCredential > m_remoteCaps;
|
||||
Map< uint32_t, OwnershipCredential > m_remoteCoos;
|
||||
|
||||
public:
|
||||
class CapabilityIterator
|
||||
{
|
||||
public:
|
||||
ZT_INLINE CapabilityIterator(Member &m, const NetworkConfig &nconf) noexcept :
|
||||
ZT_INLINE CapabilityIterator(Member &m, const NetworkConfig &nconf) noexcept:
|
||||
m_hti(m.m_remoteCaps.begin()),
|
||||
m_parent(m),
|
||||
m_nconf(nconf)
|
||||
|
@ -215,7 +217,7 @@ public:
|
|||
ZT_INLINE CapabilityCredential *next() noexcept
|
||||
{
|
||||
while (m_hti != m_parent.m_remoteCaps.end()) {
|
||||
Map< uint32_t,CapabilityCredential >::iterator i(m_hti++);
|
||||
Map< uint32_t, CapabilityCredential >::iterator i(m_hti++);
|
||||
if (m_parent.m_isCredentialTimestampValid(m_nconf, i->second))
|
||||
return &(i->second);
|
||||
}
|
||||
|
@ -223,7 +225,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
Map< uint32_t,CapabilityCredential >::iterator m_hti;
|
||||
Map< uint32_t, CapabilityCredential >::iterator m_hti;
|
||||
Member &m_parent;
|
||||
const NetworkConfig &m_nconf;
|
||||
};
|
||||
|
|
|
@ -133,6 +133,9 @@ public:
|
|||
*/
|
||||
ZT_INLINE int64_t timestamp() const noexcept { return m_timestamp; }
|
||||
|
||||
ZT_INLINE int64_t revision() const noexcept
|
||||
{ return m_timestamp; }
|
||||
|
||||
/**
|
||||
* @return Maximum allowed difference between timestamps
|
||||
*/
|
||||
|
@ -177,7 +180,7 @@ public:
|
|||
* @param RR Runtime environment for looking up peers
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
*/
|
||||
ZT_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return s_verify(RR, tPtr, *this); }
|
||||
ZT_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR, CallContext &cc) const { return s_verify(RR, cc, *this); }
|
||||
|
||||
// NOTE: right now we use v1 serialization format which works with both ZeroTier 1.x and 2.x. V2 format
|
||||
// will be switched on once 1.x is pretty much dead and out of support.
|
||||
|
|
|
@ -43,28 +43,25 @@ public:
|
|||
*
|
||||
* @param now Start time
|
||||
*/
|
||||
ZT_INLINE Meter() noexcept :
|
||||
m_counts(),
|
||||
m_totalExclCounts(0),
|
||||
m_bucket(0)
|
||||
ZT_INLINE Meter() noexcept
|
||||
{}
|
||||
|
||||
/**
|
||||
* Add a measurement
|
||||
*
|
||||
* @param now Current time
|
||||
* @param ts Timestamp for measurement
|
||||
* @param count Count of items (usually bytes)
|
||||
*/
|
||||
ZT_INLINE void log(const int64_t now, uint64_t count) noexcept
|
||||
ZT_INLINE void log(const int64_t ts, const uint64_t count) noexcept
|
||||
{
|
||||
// We log by choosing a log bucket based on the current time in units modulo
|
||||
// the log size and then if it's a new bucket setting it or otherwise adding
|
||||
// to it.
|
||||
const unsigned long bucket = ((unsigned long)(now / TUNIT)) % LSIZE;
|
||||
if (m_bucket.exchange(bucket) != bucket) {
|
||||
m_totalExclCounts.fetch_add(m_counts[bucket].exchange(count));
|
||||
const unsigned long bucket = ((unsigned long)(ts / TUNIT)) % LSIZE;
|
||||
if (m_bucket.exchange(bucket, std::memory_order_relaxed) != bucket) {
|
||||
m_totalExclCounts.fetch_add(m_counts[bucket].exchange(count, std::memory_order_relaxed), std::memory_order_relaxed);
|
||||
} else {
|
||||
m_counts[bucket].fetch_add(count);
|
||||
m_counts[bucket].fetch_add(count, std::memory_order_relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,9 +76,9 @@ public:
|
|||
{
|
||||
total = 0;
|
||||
for (unsigned long i = 0;i < LSIZE;++i)
|
||||
total += m_counts[i].load();
|
||||
total += m_counts[i].load(std::memory_order_relaxed);
|
||||
rate = (double) total / (double) LSIZE;
|
||||
total += m_totalExclCounts.load();
|
||||
total += m_totalExclCounts.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -538,7 +538,7 @@ _doZtFilterResult _doZtFilter(
|
|||
|
||||
const ZeroTier::MulticastGroup Network::BROADCAST(ZeroTier::MAC(0xffffffffffffULL), 0);
|
||||
|
||||
Network::Network(const RuntimeEnvironment *renv, void *tPtr, uint64_t nwid, const Fingerprint &controllerFingerprint, void *uptr, const NetworkConfig *nconf) :
|
||||
Network::Network(const RuntimeEnvironment *renv, CallContext &cc, uint64_t nwid, const Fingerprint &controllerFingerprint, void *uptr, const NetworkConfig *nconf) :
|
||||
RR(renv),
|
||||
m_uPtr(uptr),
|
||||
m_id(nwid),
|
||||
|
@ -552,7 +552,7 @@ Network::Network(const RuntimeEnvironment *renv, void *tPtr, uint64_t nwid, cons
|
|||
m_controllerFingerprint = controllerFingerprint;
|
||||
|
||||
if (nconf) {
|
||||
this->setConfiguration(tPtr, *nconf, false);
|
||||
this->setConfiguration(cc, *nconf, false);
|
||||
m_lastConfigUpdate = 0; // still want to re-request since it's likely outdated
|
||||
} else {
|
||||
uint64_t tmp[2];
|
||||
|
@ -562,14 +562,14 @@ Network::Network(const RuntimeEnvironment *renv, void *tPtr, uint64_t nwid, cons
|
|||
bool got = false;
|
||||
try {
|
||||
Dictionary dict;
|
||||
Vector< uint8_t > nconfData(RR->store->get(tPtr, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, 1));
|
||||
Vector< uint8_t > nconfData(RR->store->get(cc, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, 1));
|
||||
if (nconfData.size() > 2) {
|
||||
nconfData.push_back(0);
|
||||
if (dict.decode(nconfData.data(), (unsigned int)nconfData.size())) {
|
||||
try {
|
||||
ScopedPtr< NetworkConfig > nconf2(new NetworkConfig());
|
||||
if (nconf2->fromDictionary(dict)) {
|
||||
this->setConfiguration(tPtr, *nconf2, false);
|
||||
this->setConfiguration(cc, *nconf2, false);
|
||||
m_lastConfigUpdate = 0; // still want to re-request an update since it's likely outdated
|
||||
got = true;
|
||||
}
|
||||
|
@ -579,13 +579,13 @@ Network::Network(const RuntimeEnvironment *renv, void *tPtr, uint64_t nwid, cons
|
|||
} catch (...) {}
|
||||
|
||||
if (!got)
|
||||
RR->store->put(tPtr, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, 1, "\n", 1);
|
||||
RR->store->put(cc, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, 1, "\n", 1);
|
||||
}
|
||||
|
||||
if (!m_portInitialized) {
|
||||
ZT_VirtualNetworkConfig ctmp;
|
||||
m_externalConfig(&ctmp);
|
||||
RR->node->configureVirtualNetworkPort(tPtr, m_id, &m_uPtr, ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP, &ctmp);
|
||||
RR->cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, cc.tPtr, m_id, &m_uPtr, ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP, &ctmp);
|
||||
m_portInitialized = true;
|
||||
}
|
||||
}
|
||||
|
@ -604,12 +604,12 @@ Network::~Network()
|
|||
// This is done in Node::leave() so we can pass tPtr properly
|
||||
//RR->node->configureVirtualNetworkPort((void *)0,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp);
|
||||
} else {
|
||||
RR->node->configureVirtualNetworkPort(nullptr, m_id, &m_uPtr, ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN, &ctmp);
|
||||
RR->cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, nullptr, m_id, &m_uPtr, ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN, &ctmp);
|
||||
}
|
||||
}
|
||||
|
||||
bool Network::filterOutgoingPacket(
|
||||
void *tPtr,
|
||||
CallContext &cc,
|
||||
const bool noTee,
|
||||
const Address &ztSource,
|
||||
const Address &ztDest,
|
||||
|
@ -625,7 +625,7 @@ bool Network::filterOutgoingPacket(
|
|||
Address ztFinalDest(ztDest);
|
||||
int localCapabilityIndex = -1;
|
||||
int accept = 0;
|
||||
Address cc;
|
||||
Address ccNodeAddress;
|
||||
unsigned int ccLength = 0;
|
||||
bool ccWatch = false;
|
||||
|
||||
|
@ -640,7 +640,7 @@ bool Network::filterOutgoingPacket(
|
|||
membership = nullptr;
|
||||
}
|
||||
|
||||
switch (_doZtFilter(RR, rrl, m_config, membership, false, ztSource, ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, m_config.rules, m_config.ruleCount, cc, ccLength, ccWatch, qosBucket)) {
|
||||
switch (_doZtFilter(RR, rrl, m_config, membership, false, ztSource, ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, m_config.rules, m_config.ruleCount, ccNodeAddress, ccLength, ccWatch, qosBucket)) {
|
||||
|
||||
case DOZTFILTER_NO_MATCH: {
|
||||
for (unsigned int c = 0; c < m_config.capabilityCount; ++c) {
|
||||
|
@ -683,7 +683,7 @@ bool Network::filterOutgoingPacket(
|
|||
break;
|
||||
|
||||
case DOZTFILTER_DROP:
|
||||
RR->t->networkFilter(tPtr, 0xadea5a2a, m_id, rrl.l, nullptr, 0, 0, ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, 0);
|
||||
RR->t->networkFilter(cc, 0xadea5a2a, m_id, rrl.l, nullptr, 0, 0, ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, 0);
|
||||
return false;
|
||||
|
||||
case DOZTFILTER_REDIRECT: // interpreted as ACCEPT but ztFinalDest will have been changed in _doZtFilter()
|
||||
|
@ -697,7 +697,7 @@ bool Network::filterOutgoingPacket(
|
|||
}
|
||||
|
||||
if (accept != 0) {
|
||||
if ((!noTee) && (cc)) {
|
||||
if ((!noTee) && (ccNodeAddress)) {
|
||||
// TODO
|
||||
/*
|
||||
Packet outp(cc,RR->identity.address(),Packet::VERB_EXT_FRAME);
|
||||
|
@ -733,16 +733,16 @@ bool Network::filterOutgoingPacket(
|
|||
|
||||
if (localCapabilityIndex >= 0) {
|
||||
const CapabilityCredential &cap = m_config.capabilities[localCapabilityIndex];
|
||||
RR->t->networkFilter(tPtr, 0x56ff1a93, m_id, rrl.l, crrl.l, cap.id(), cap.timestamp(), ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, accept);
|
||||
RR->t->networkFilter(cc, 0x56ff1a93, m_id, rrl.l, crrl.l, cap.id(), cap.timestamp(), ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, accept);
|
||||
} else {
|
||||
RR->t->networkFilter(tPtr, 0x112fbbab, m_id, rrl.l, nullptr, 0, 0, ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, accept);
|
||||
RR->t->networkFilter(cc, 0x112fbbab, m_id, rrl.l, nullptr, 0, 0, ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, accept);
|
||||
}
|
||||
|
||||
return (accept != 0);
|
||||
}
|
||||
|
||||
int Network::filterIncomingPacket(
|
||||
void *tPtr,
|
||||
CallContext &cc,
|
||||
const SharedPtr< Peer > &sourcePeer,
|
||||
const Address &ztDest,
|
||||
const MAC &macSource,
|
||||
|
@ -755,7 +755,7 @@ int Network::filterIncomingPacket(
|
|||
Address ztFinalDest(ztDest);
|
||||
Trace::RuleResultLog rrl, crrl;
|
||||
int accept = 0;
|
||||
Address cc;
|
||||
Address ccNodeAddress;
|
||||
unsigned int ccLength = 0;
|
||||
bool ccWatch = false;
|
||||
const CapabilityCredential *c = nullptr;
|
||||
|
@ -767,7 +767,7 @@ int Network::filterIncomingPacket(
|
|||
|
||||
Member &membership = m_memberships[sourcePeer->address()];
|
||||
|
||||
switch (_doZtFilter(RR, rrl, m_config, &membership, true, sourcePeer->address(), ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, m_config.rules, m_config.ruleCount, cc, ccLength, ccWatch, qosBucket)) {
|
||||
switch (_doZtFilter(RR, rrl, m_config, &membership, true, sourcePeer->address(), ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, m_config.rules, m_config.ruleCount, ccNodeAddress, ccLength, ccWatch, qosBucket)) {
|
||||
|
||||
case DOZTFILTER_NO_MATCH: {
|
||||
Member::CapabilityIterator mci(membership, m_config);
|
||||
|
@ -825,7 +825,7 @@ int Network::filterIncomingPacket(
|
|||
}
|
||||
|
||||
if (accept) {
|
||||
if (cc) {
|
||||
if (ccNodeAddress) {
|
||||
// TODO
|
||||
/*
|
||||
Packet outp(cc,RR->identity.address(),Packet::VERB_EXT_FRAME);
|
||||
|
@ -865,13 +865,13 @@ int Network::filterIncomingPacket(
|
|||
return accept;
|
||||
}
|
||||
|
||||
void Network::multicastSubscribe(void *tPtr, const MulticastGroup &mg)
|
||||
void Network::multicastSubscribe(CallContext &cc, const MulticastGroup &mg)
|
||||
{
|
||||
Mutex::Lock l(m_myMulticastGroups_l);
|
||||
if (!std::binary_search(m_myMulticastGroups.begin(), m_myMulticastGroups.end(), mg)) {
|
||||
m_myMulticastGroups.insert(std::upper_bound(m_myMulticastGroups.begin(), m_myMulticastGroups.end(), mg), mg);
|
||||
Mutex::Lock l2(m_memberships_l);
|
||||
m_announceMulticastGroups(tPtr, true);
|
||||
m_announceMulticastGroups(cc.tPtr, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -883,7 +883,7 @@ void Network::multicastUnsubscribe(const MulticastGroup &mg)
|
|||
m_myMulticastGroups.erase(i);
|
||||
}
|
||||
|
||||
uint64_t Network::handleConfigChunk(void *tPtr, uint64_t packetId, const SharedPtr< Peer > &source, const Buf &chunk, int ptr, int size)
|
||||
uint64_t Network::handleConfigChunk(CallContext &cc, uint64_t packetId, const SharedPtr< Peer > &source, const Buf &chunk, int ptr, int size)
|
||||
{
|
||||
// If the controller's full fingerprint is known or was explicitly specified on join(),
|
||||
// require that the controller's identity match. Otherwise learn it.
|
||||
|
@ -1027,7 +1027,7 @@ uint64_t Network::handleConfigChunk(void *tPtr, uint64_t packetId, const SharedP
|
|||
#endif
|
||||
}
|
||||
|
||||
int Network::setConfiguration(void *tPtr, const NetworkConfig &nconf, bool saveToDisk)
|
||||
int Network::setConfiguration(CallContext &cc, const NetworkConfig &nconf, bool saveToDisk)
|
||||
{
|
||||
if (m_destroyed)
|
||||
return 0;
|
||||
|
@ -1048,7 +1048,7 @@ int Network::setConfiguration(void *tPtr, const NetworkConfig &nconf, bool saveT
|
|||
Mutex::Lock l1(m_config_l);
|
||||
|
||||
m_config = nconf;
|
||||
m_lastConfigUpdate = RR->node->now();
|
||||
m_lastConfigUpdate = cc.ticks;
|
||||
_netconfFailure = NETCONF_FAILURE_NONE;
|
||||
|
||||
oldPortInitialized = m_portInitialized;
|
||||
|
@ -1057,7 +1057,7 @@ int Network::setConfiguration(void *tPtr, const NetworkConfig &nconf, bool saveT
|
|||
m_externalConfig(&ctmp);
|
||||
}
|
||||
|
||||
RR->node->configureVirtualNetworkPort(tPtr, m_id, &m_uPtr, (oldPortInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP, &ctmp);
|
||||
RR->cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, cc.tPtr, nconf.networkId, &m_uPtr, (oldPortInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP, &ctmp);
|
||||
|
||||
if (saveToDisk) {
|
||||
try {
|
||||
|
@ -1068,7 +1068,7 @@ int Network::setConfiguration(void *tPtr, const NetworkConfig &nconf, bool saveT
|
|||
tmp[1] = 0;
|
||||
Vector< uint8_t > d2;
|
||||
d.encode(d2);
|
||||
RR->store->put(tPtr, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, 1, d2.data(), (unsigned int)d2.size());
|
||||
RR->store->put(cc, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, 1, d2.data(), (unsigned int)d2.size());
|
||||
}
|
||||
} catch (...) {}
|
||||
}
|
||||
|
@ -1095,13 +1095,13 @@ bool Network::gate(void *tPtr, const SharedPtr< Peer > &peer) noexcept
|
|||
return false;
|
||||
}
|
||||
|
||||
void Network::doPeriodicTasks(void *tPtr, const int64_t now)
|
||||
void Network::doPeriodicTasks(CallContext &cc)
|
||||
{
|
||||
if (m_destroyed)
|
||||
return;
|
||||
|
||||
if ((now - m_lastConfigUpdate) >= ZT_NETWORK_AUTOCONF_DELAY)
|
||||
m_requestConfiguration(tPtr);
|
||||
if ((cc.ticks - m_lastConfigUpdate) >= ZT_NETWORK_AUTOCONF_DELAY)
|
||||
m_requestConfiguration(cc);
|
||||
|
||||
{
|
||||
Mutex::Lock l1(m_memberships_l);
|
||||
|
@ -1157,31 +1157,31 @@ void Network::learnBridgeRoute(const MAC &mac, const Address &addr)
|
|||
}
|
||||
}
|
||||
|
||||
Member::AddCredentialResult Network::addCredential(void *tPtr, const Identity &sourcePeerIdentity, const MembershipCredential &com)
|
||||
Member::AddCredentialResult Network::addCredential(CallContext &cc, const Identity &sourcePeerIdentity, const MembershipCredential &com)
|
||||
{
|
||||
if (com.networkId() != m_id)
|
||||
return Member::ADD_REJECTED;
|
||||
Mutex::Lock _l(m_memberships_l);
|
||||
return m_memberships[com.issuedTo().address].addCredential(RR, tPtr, sourcePeerIdentity, m_config, com);
|
||||
return m_memberships[com.issuedTo().address].addCredential(RR, cc, sourcePeerIdentity, m_config, com);
|
||||
}
|
||||
|
||||
Member::AddCredentialResult Network::addCredential(void *tPtr, const Identity &sourcePeerIdentity, const CapabilityCredential &cap)
|
||||
Member::AddCredentialResult Network::addCredential(CallContext &cc, const Identity &sourcePeerIdentity, const CapabilityCredential &cap)
|
||||
{
|
||||
if (cap.networkId() != m_id)
|
||||
return Member::ADD_REJECTED;
|
||||
Mutex::Lock _l(m_memberships_l);
|
||||
return m_memberships[cap.issuedTo()].addCredential(RR, tPtr, sourcePeerIdentity, m_config, cap);
|
||||
return m_memberships[cap.issuedTo()].addCredential(RR, cc, sourcePeerIdentity, m_config, cap);
|
||||
}
|
||||
|
||||
Member::AddCredentialResult Network::addCredential(void *tPtr, const Identity &sourcePeerIdentity, const TagCredential &tag)
|
||||
Member::AddCredentialResult Network::addCredential(CallContext &cc, const Identity &sourcePeerIdentity, const TagCredential &tag)
|
||||
{
|
||||
if (tag.networkId() != m_id)
|
||||
return Member::ADD_REJECTED;
|
||||
Mutex::Lock _l(m_memberships_l);
|
||||
return m_memberships[tag.issuedTo()].addCredential(RR, tPtr, sourcePeerIdentity, m_config, tag);
|
||||
return m_memberships[tag.issuedTo()].addCredential(RR, cc, sourcePeerIdentity, m_config, tag);
|
||||
}
|
||||
|
||||
Member::AddCredentialResult Network::addCredential(void *tPtr, const Identity &sourcePeerIdentity, const RevocationCredential &rev)
|
||||
Member::AddCredentialResult Network::addCredential(CallContext &cc, const Identity &sourcePeerIdentity, const RevocationCredential &rev)
|
||||
{
|
||||
if (rev.networkId() != m_id)
|
||||
return Member::ADD_REJECTED;
|
||||
|
@ -1189,7 +1189,7 @@ Member::AddCredentialResult Network::addCredential(void *tPtr, const Identity &s
|
|||
Mutex::Lock l1(m_memberships_l);
|
||||
Member &m = m_memberships[rev.target()];
|
||||
|
||||
const Member::AddCredentialResult result = m.addCredential(RR, tPtr, sourcePeerIdentity, m_config, rev);
|
||||
const Member::AddCredentialResult result = m.addCredential(RR, cc, sourcePeerIdentity, m_config, rev);
|
||||
|
||||
if ((result == Member::ADD_ACCEPTED_NEW) && (rev.fastPropagate())) {
|
||||
// TODO
|
||||
|
@ -1215,22 +1215,21 @@ Member::AddCredentialResult Network::addCredential(void *tPtr, const Identity &s
|
|||
return result;
|
||||
}
|
||||
|
||||
Member::AddCredentialResult Network::addCredential(void *tPtr, const Identity &sourcePeerIdentity, const OwnershipCredential &coo)
|
||||
Member::AddCredentialResult Network::addCredential(CallContext &cc, const Identity &sourcePeerIdentity, const OwnershipCredential &coo)
|
||||
{
|
||||
if (coo.networkId() != m_id)
|
||||
return Member::ADD_REJECTED;
|
||||
Mutex::Lock _l(m_memberships_l);
|
||||
return m_memberships[coo.issuedTo()].addCredential(RR, tPtr, sourcePeerIdentity, m_config, coo);
|
||||
return m_memberships[coo.issuedTo()].addCredential(RR, cc, sourcePeerIdentity, m_config, coo);
|
||||
}
|
||||
|
||||
void Network::pushCredentials(void *tPtr, const SharedPtr< Peer > &to, const int64_t now)
|
||||
void Network::pushCredentials(CallContext &cc, const SharedPtr< Peer > &to)
|
||||
{
|
||||
const int64_t tout = std::min(m_config.credentialTimeMaxDelta, m_config.com.timestampMaxDelta());
|
||||
Mutex::Lock _l(m_memberships_l);
|
||||
Member &m = m_memberships[to->address()];
|
||||
if (((now - m.lastPushedCredentials()) + 5000) >= tout) {
|
||||
m.pushCredentials(RR, tPtr, now, to, m_config);
|
||||
}
|
||||
if (((cc.ticks - m.lastPushedCredentials()) + 5000) >= tout)
|
||||
m.pushCredentials(RR, cc, to, m_config);
|
||||
}
|
||||
|
||||
void Network::destroy()
|
||||
|
@ -1248,7 +1247,7 @@ void Network::externalConfig(ZT_VirtualNetworkConfig *ec) const
|
|||
m_externalConfig(ec);
|
||||
}
|
||||
|
||||
void Network::m_requestConfiguration(void *tPtr)
|
||||
void Network::m_requestConfiguration(CallContext &cc)
|
||||
{
|
||||
if (m_destroyed)
|
||||
return;
|
||||
|
@ -1261,7 +1260,7 @@ void Network::m_requestConfiguration(void *tPtr)
|
|||
ScopedPtr< NetworkConfig > nconf(new NetworkConfig());
|
||||
|
||||
nconf->networkId = m_id;
|
||||
nconf->timestamp = RR->node->now();
|
||||
nconf->timestamp = (cc.clock < 0) ? cc.ticks : cc.clock;
|
||||
nconf->credentialTimeMaxDelta = ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MAX_MAX_DELTA;
|
||||
nconf->revision = 1;
|
||||
nconf->issuedTo = RR->identity.address();
|
||||
|
@ -1319,7 +1318,7 @@ void Network::m_requestConfiguration(void *tPtr)
|
|||
Utils::hex((uint16_t)endPortRange, nconf->name + 11);
|
||||
nconf->name[15] = (char)0;
|
||||
|
||||
this->setConfiguration(tPtr, *nconf, false);
|
||||
this->setConfiguration(cc, *nconf, false);
|
||||
} else {
|
||||
this->setNotFound();
|
||||
}
|
||||
|
@ -1340,7 +1339,7 @@ void Network::m_requestConfiguration(void *tPtr)
|
|||
ScopedPtr< NetworkConfig > nconf(new NetworkConfig());
|
||||
|
||||
nconf->networkId = m_id;
|
||||
nconf->timestamp = RR->node->now();
|
||||
nconf->timestamp = (cc.clock < 0) ? cc.ticks : cc.clock;
|
||||
nconf->credentialTimeMaxDelta = ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MAX_MAX_DELTA;
|
||||
nconf->revision = 1;
|
||||
nconf->issuedTo = RR->identity.address();
|
||||
|
@ -1377,7 +1376,7 @@ void Network::m_requestConfiguration(void *tPtr)
|
|||
nconf->name[nn++] = '0';
|
||||
nconf->name[nn] = (char)0;
|
||||
|
||||
this->setConfiguration(tPtr, *nconf, false);
|
||||
this->setConfiguration(cc, *nconf, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1397,7 +1396,7 @@ void Network::m_requestConfiguration(void *tPtr)
|
|||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS, (uint64_t)0);
|
||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV, (uint64_t)ZT_RULES_ENGINE_REVISION);
|
||||
|
||||
RR->t->networkConfigRequestSent(tPtr, 0x335bb1a2, m_id);
|
||||
RR->t->networkConfigRequestSent(cc, 0x335bb1a2, m_id);
|
||||
|
||||
if (ctrl == RR->identity.address()) {
|
||||
if (RR->localNetworkController) {
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "NetworkConfig.hpp"
|
||||
#include "MembershipCredential.hpp"
|
||||
#include "Containers.hpp"
|
||||
#include "CallContext.hpp"
|
||||
|
||||
#define ZT_NETWORK_MAX_INCOMING_UPDATES 3
|
||||
|
||||
|
@ -60,14 +61,18 @@ public:
|
|||
* Note that init() should be called immediately after the network is
|
||||
* constructed to actually configure the port.
|
||||
*
|
||||
* @param renv Runtime environment
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param nwid Network ID
|
||||
* @param controllerFingerprint Initial controller fingerprint if non-NULL
|
||||
* @param uptr Arbitrary pointer used by externally-facing API (for user use)
|
||||
* @param nconf Network config, if known
|
||||
*/
|
||||
Network(const RuntimeEnvironment *renv, void *tPtr, uint64_t nwid, const Fingerprint &controllerFingerprint, void *uptr, const NetworkConfig *nconf);
|
||||
Network(
|
||||
const RuntimeEnvironment *renv,
|
||||
CallContext &cc,
|
||||
uint64_t nwid,
|
||||
const Fingerprint &controllerFingerprint,
|
||||
void *uptr,
|
||||
const NetworkConfig *nconf);
|
||||
|
||||
~Network();
|
||||
|
||||
|
@ -103,7 +108,6 @@ public:
|
|||
* such as TEE may be taken, and credentials may be pushed, so this is not
|
||||
* side-effect-free. It's basically step one in sending something over VL2.
|
||||
*
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param noTee If true, do not TEE anything anywhere (for two-pass filtering as done with multicast and bridging)
|
||||
* @param ztSource Source ZeroTier address
|
||||
* @param ztDest Destination ZeroTier address
|
||||
|
@ -116,7 +120,7 @@ public:
|
|||
* @return True if packet should be sent, false if dropped or redirected
|
||||
*/
|
||||
bool filterOutgoingPacket(
|
||||
void *tPtr,
|
||||
CallContext &cc,
|
||||
bool noTee,
|
||||
const Address &ztSource,
|
||||
const Address &ztDest,
|
||||
|
@ -136,7 +140,6 @@ public:
|
|||
* a match certain actions may be taken such as sending a copy of the packet
|
||||
* to a TEE or REDIRECT target.
|
||||
*
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param sourcePeer Source Peer
|
||||
* @param ztDest Destination ZeroTier address
|
||||
* @param macSource Ethernet layer source address
|
||||
|
@ -148,7 +151,7 @@ public:
|
|||
* @return 0 == drop, 1 == accept, 2 == accept even if bridged
|
||||
*/
|
||||
int filterIncomingPacket(
|
||||
void *tPtr,
|
||||
CallContext &cc,
|
||||
const SharedPtr< Peer > &sourcePeer,
|
||||
const Address &ztDest,
|
||||
const MAC &macSource,
|
||||
|
@ -158,30 +161,12 @@ public:
|
|||
unsigned int etherType,
|
||||
unsigned int vlanId);
|
||||
|
||||
/**
|
||||
* Check whether we are subscribed to a multicast group
|
||||
*
|
||||
* @param mg Multicast group
|
||||
* @param includeBridgedGroups If true, also check groups we've learned via bridging
|
||||
* @return True if this network endpoint / peer is a member
|
||||
*/
|
||||
ZT_INLINE bool subscribedToMulticastGroup(const MulticastGroup &mg, const bool includeBridgedGroups) const
|
||||
{
|
||||
Mutex::Lock l(m_myMulticastGroups_l);
|
||||
if (std::binary_search(m_myMulticastGroups.begin(), m_myMulticastGroups.end(), mg))
|
||||
return true;
|
||||
else if (includeBridgedGroups)
|
||||
return (m_multicastGroupsBehindMe.find(mg) != m_multicastGroupsBehindMe.end());
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to a multicast group
|
||||
*
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param mg New multicast group
|
||||
*/
|
||||
void multicastSubscribe(void *tPtr, const MulticastGroup &mg);
|
||||
void multicastSubscribe(CallContext &cc, const MulticastGroup &mg);
|
||||
|
||||
/**
|
||||
* Unsubscribe from a multicast group
|
||||
|
@ -198,7 +183,6 @@ public:
|
|||
* bit of packet parsing code that also verifies chunks and replicates
|
||||
* them (via rumor mill flooding) if their fast propagate flag is set.
|
||||
*
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param packetId Packet ID or 0 if none (e.g. via cluster path)
|
||||
* @param source Peer that actually sent this chunk (probably controller)
|
||||
* @param chunk Buffer containing chunk
|
||||
|
@ -206,7 +190,13 @@ public:
|
|||
* @param size Size of data in chunk buffer (total, not relative to ptr)
|
||||
* @return Update ID if update was fully assembled and accepted or 0 otherwise
|
||||
*/
|
||||
uint64_t handleConfigChunk(void *tPtr, uint64_t packetId, const SharedPtr< Peer > &source, const Buf &chunk, int ptr, int size);
|
||||
uint64_t handleConfigChunk(
|
||||
CallContext &cc,
|
||||
uint64_t packetId,
|
||||
const SharedPtr< Peer > &source,
|
||||
const Buf &chunk,
|
||||
int ptr,
|
||||
int size);
|
||||
|
||||
/**
|
||||
* Set network configuration
|
||||
|
@ -215,12 +205,14 @@ public:
|
|||
* and fully assembled, but it can also be called on Node startup when
|
||||
* cached configurations are re-read from the data store.
|
||||
*
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param nconf Network configuration
|
||||
* @param saveToDisk Save to disk? Used during loading, should usually be true otherwise.
|
||||
* @return 0 == bad, 1 == accepted but duplicate/unchanged, 2 == accepted and new
|
||||
*/
|
||||
int setConfiguration(void *tPtr, const NetworkConfig &nconf, bool saveToDisk);
|
||||
int setConfiguration(
|
||||
CallContext &cc,
|
||||
const NetworkConfig &nconf,
|
||||
bool saveToDisk);
|
||||
|
||||
/**
|
||||
* Set netconf failure to 'access denied' -- called in IncomingPacket when controller reports this
|
||||
|
@ -245,7 +237,7 @@ public:
|
|||
/**
|
||||
* Do periodic cleanup and housekeeping tasks
|
||||
*/
|
||||
void doPeriodicTasks(void *tPtr, int64_t now);
|
||||
void doPeriodicTasks(CallContext &cc);
|
||||
|
||||
/**
|
||||
* Find the node on this network that has this MAC behind it (if any)
|
||||
|
@ -275,7 +267,7 @@ public:
|
|||
* @param mg Multicast group
|
||||
* @param now Current time
|
||||
*/
|
||||
ZT_INLINE void learnBridgedMulticastGroup(void *tPtr, const MulticastGroup &mg, int64_t now)
|
||||
ZT_INLINE void learnBridgedMulticastGroup(const MulticastGroup &mg, int64_t now)
|
||||
{
|
||||
Mutex::Lock l(m_myMulticastGroups_l);
|
||||
m_multicastGroupsBehindMe[mg] = now;
|
||||
|
@ -284,36 +276,34 @@ public:
|
|||
/**
|
||||
* Validate a credential and learn it if it passes certificate and other checks
|
||||
*/
|
||||
Member::AddCredentialResult addCredential(void *tPtr, const Identity &sourcePeerIdentity, const MembershipCredential &com);
|
||||
Member::AddCredentialResult addCredential(CallContext &cc, const Identity &sourcePeerIdentity, const MembershipCredential &com);
|
||||
|
||||
/**
|
||||
* Validate a credential and learn it if it passes certificate and other checks
|
||||
*/
|
||||
Member::AddCredentialResult addCredential(void *tPtr, const Identity &sourcePeerIdentity, const CapabilityCredential &cap);
|
||||
Member::AddCredentialResult addCredential(CallContext &cc, const Identity &sourcePeerIdentity, const CapabilityCredential &cap);
|
||||
|
||||
/**
|
||||
* Validate a credential and learn it if it passes certificate and other checks
|
||||
*/
|
||||
Member::AddCredentialResult addCredential(void *tPtr, const Identity &sourcePeerIdentity, const TagCredential &tag);
|
||||
Member::AddCredentialResult addCredential(CallContext &cc, const Identity &sourcePeerIdentity, const TagCredential &tag);
|
||||
|
||||
/**
|
||||
* Validate a credential and learn it if it passes certificate and other checks
|
||||
*/
|
||||
Member::AddCredentialResult addCredential(void *tPtr, const Identity &sourcePeerIdentity, const RevocationCredential &rev);
|
||||
Member::AddCredentialResult addCredential(CallContext &cc, const Identity &sourcePeerIdentity, const RevocationCredential &rev);
|
||||
|
||||
/**
|
||||
* Validate a credential and learn it if it passes certificate and other checks
|
||||
*/
|
||||
Member::AddCredentialResult addCredential(void *tPtr, const Identity &sourcePeerIdentity, const OwnershipCredential &coo);
|
||||
Member::AddCredentialResult addCredential(CallContext &cc, const Identity &sourcePeerIdentity, const OwnershipCredential &coo);
|
||||
|
||||
/**
|
||||
* Push credentials to a peer if timeouts indicate that we should do so
|
||||
*
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param to Destination peer
|
||||
* @param now Current time
|
||||
*/
|
||||
void pushCredentials(void *tPtr, const SharedPtr< Peer > &to, int64_t now);
|
||||
void pushCredentials(CallContext &cc, const SharedPtr< Peer > &to);
|
||||
|
||||
/**
|
||||
* Destroy this network
|
||||
|
@ -352,7 +342,7 @@ public:
|
|||
{ return &m_uPtr; }
|
||||
|
||||
private:
|
||||
void m_requestConfiguration(void *tPtr);
|
||||
void m_requestConfiguration(CallContext &cc);
|
||||
|
||||
ZT_VirtualNetworkStatus m_status() const;
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
* @param nc Network configuration to send
|
||||
* @param sendLegacyFormatConfig If true, send an old-format network config
|
||||
*/
|
||||
virtual void ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &destination,const NetworkConfig &nc,bool sendLegacyFormatConfig) = 0;
|
||||
virtual void ncSendConfig(void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address &destination, const NetworkConfig &nc, bool sendLegacyFormatConfig) = 0;
|
||||
|
||||
/**
|
||||
* Send revocation to a node
|
||||
|
@ -62,7 +62,7 @@ public:
|
|||
* @param destination Destination node address
|
||||
* @param rev Revocation to send
|
||||
*/
|
||||
virtual void ncSendRevocation(const Address &destination,const RevocationCredential &rev) = 0;
|
||||
virtual void ncSendRevocation(void *tPtr, int64_t clock, int64_t ticks, const Address &destination, const RevocationCredential &rev) = 0;
|
||||
|
||||
/**
|
||||
* Send a network configuration request error
|
||||
|
@ -72,7 +72,7 @@ public:
|
|||
* @param destination Destination peer Address
|
||||
* @param errorCode Error code
|
||||
*/
|
||||
virtual void ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &destination,NetworkController::ErrorCode errorCode) = 0;
|
||||
virtual void ncSendError(void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address &destination, NetworkController::ErrorCode errorCode) = 0;
|
||||
};
|
||||
|
||||
NetworkController() {}
|
||||
|
@ -84,7 +84,7 @@ public:
|
|||
* @param signingId Identity for signing of network configurations, certs, etc.
|
||||
* @param sender Sender implementation for sending replies or config pushes
|
||||
*/
|
||||
virtual void init(const Identity &signingId,Sender *sender) = 0;
|
||||
virtual void init(const Identity &signingId, Sender *sender) = 0;
|
||||
|
||||
/**
|
||||
* Handle a network configuration request
|
||||
|
|
186
core/Node.cpp
186
core/Node.cpp
|
@ -35,13 +35,13 @@ namespace {
|
|||
|
||||
struct _NodeObjects
|
||||
{
|
||||
ZT_INLINE _NodeObjects(RuntimeEnvironment *const RR, Node *const n, void *const tPtr, const int64_t now) :
|
||||
ZT_INLINE _NodeObjects(RuntimeEnvironment *const RR, CallContext &cc) :
|
||||
networks(),
|
||||
t(RR),
|
||||
expect(),
|
||||
vl2(RR),
|
||||
vl1(RR),
|
||||
topology(RR, tPtr, now),
|
||||
topology(RR, cc),
|
||||
sa(RR),
|
||||
ts()
|
||||
{
|
||||
|
@ -69,9 +69,8 @@ struct _NodeObjects
|
|||
|
||||
Node::Node(
|
||||
void *uPtr,
|
||||
void *tPtr,
|
||||
const struct ZT_Node_Callbacks *callbacks,
|
||||
int64_t now) :
|
||||
CallContext &cc) :
|
||||
m_RR(this),
|
||||
RR(&m_RR),
|
||||
m_store(&m_RR),
|
||||
|
@ -79,8 +78,7 @@ Node::Node(
|
|||
m_lastPeerPulse(0),
|
||||
m_lastHousekeepingRun(0),
|
||||
m_lastNetworkHousekeepingRun(0),
|
||||
m_lastRootRank(0),
|
||||
m_now(now),
|
||||
m_lastTrustStoreUpdate(0),
|
||||
m_online(false)
|
||||
{
|
||||
ZT_SPEW("Node starting up!");
|
||||
|
@ -89,7 +87,7 @@ Node::Node(
|
|||
m_RR.uPtr = uPtr;
|
||||
m_RR.store = &m_store;
|
||||
|
||||
Vector< uint8_t > data(m_store.get(tPtr, ZT_STATE_OBJECT_IDENTITY_SECRET, Utils::ZERO256, 0));
|
||||
Vector< uint8_t > data(m_store.get(cc, ZT_STATE_OBJECT_IDENTITY_SECRET, Utils::ZERO256, 0));
|
||||
bool haveIdentity = false;
|
||||
if (!data.empty()) {
|
||||
data.push_back(0); // zero-terminate string
|
||||
|
@ -105,13 +103,13 @@ Node::Node(
|
|||
m_RR.identity.generate(Identity::C25519);
|
||||
m_RR.identity.toString(false, m_RR.publicIdentityStr);
|
||||
m_RR.identity.toString(true, m_RR.secretIdentityStr);
|
||||
m_store.put(tPtr, ZT_STATE_OBJECT_IDENTITY_SECRET, Utils::ZERO256, 0, m_RR.secretIdentityStr, (unsigned int)strlen(m_RR.secretIdentityStr));
|
||||
m_store.put(tPtr, ZT_STATE_OBJECT_IDENTITY_PUBLIC, Utils::ZERO256, 0, m_RR.publicIdentityStr, (unsigned int)strlen(m_RR.publicIdentityStr));
|
||||
m_store.put(cc, ZT_STATE_OBJECT_IDENTITY_SECRET, Utils::ZERO256, 0, m_RR.secretIdentityStr, (unsigned int)strlen(m_RR.secretIdentityStr));
|
||||
m_store.put(cc, ZT_STATE_OBJECT_IDENTITY_PUBLIC, Utils::ZERO256, 0, m_RR.publicIdentityStr, (unsigned int)strlen(m_RR.publicIdentityStr));
|
||||
ZT_SPEW("no pre-existing identity found, created %s", RR->identity.toString().c_str());
|
||||
} else {
|
||||
data = m_store.get(tPtr, ZT_STATE_OBJECT_IDENTITY_PUBLIC, Utils::ZERO256, 0);
|
||||
data = m_store.get(cc, ZT_STATE_OBJECT_IDENTITY_PUBLIC, Utils::ZERO256, 0);
|
||||
if ((data.empty()) || (memcmp(data.data(), m_RR.publicIdentityStr, strlen(m_RR.publicIdentityStr)) != 0))
|
||||
m_store.put(tPtr, ZT_STATE_OBJECT_IDENTITY_PUBLIC, Utils::ZERO256, 0, m_RR.publicIdentityStr, (unsigned int)strlen(m_RR.publicIdentityStr));
|
||||
m_store.put(cc, ZT_STATE_OBJECT_IDENTITY_PUBLIC, Utils::ZERO256, 0, m_RR.publicIdentityStr, (unsigned int)strlen(m_RR.publicIdentityStr));
|
||||
}
|
||||
|
||||
uint8_t localSecretCipherKey[ZT_FINGERPRINT_HASH_SIZE];
|
||||
|
@ -133,10 +131,10 @@ Node::Node(
|
|||
}
|
||||
}
|
||||
|
||||
m_objects = new _NodeObjects(&m_RR, this, tPtr, now);
|
||||
m_objects = new _NodeObjects(&m_RR, cc);
|
||||
|
||||
ZT_SPEW("node initialized!");
|
||||
postEvent(tPtr, ZT_EVENT_UP);
|
||||
postEvent(cc.tPtr, ZT_EVENT_UP);
|
||||
}
|
||||
|
||||
Node::~Node()
|
||||
|
@ -157,28 +155,59 @@ Node::~Node()
|
|||
Buf::freePool();
|
||||
}
|
||||
|
||||
void Node::shutdown(void *tPtr)
|
||||
void Node::shutdown(CallContext &cc)
|
||||
{
|
||||
m_allNetworks_l.lock();
|
||||
RR->networks->clear();
|
||||
m_allNetworks.clear();
|
||||
m_allNetworks_l.unlock();
|
||||
postEvent(tPtr, ZT_EVENT_DOWN);
|
||||
|
||||
postEvent(cc.tPtr, ZT_EVENT_DOWN);
|
||||
|
||||
if (RR->topology)
|
||||
RR->topology->saveAll(tPtr);
|
||||
RR->topology->saveAll(cc);
|
||||
}
|
||||
|
||||
ZT_ResultCode Node::processBackgroundTasks(
|
||||
void *tPtr,
|
||||
int64_t now,
|
||||
CallContext &cc,
|
||||
volatile int64_t *nextBackgroundTaskDeadline)
|
||||
{
|
||||
m_now = now;
|
||||
Mutex::Lock bl(m_backgroundTasksLock);
|
||||
|
||||
try {
|
||||
if ((now - m_lastPeerPulse) >= ZT_PEER_PULSE_INTERVAL) {
|
||||
m_lastPeerPulse = now;
|
||||
// Updating the trust store means checking certificates and certificate chains
|
||||
// against the current time, etc., and also resynchronizing roots as specified by
|
||||
// certificates. This also happens on demand when the trust store is changed.
|
||||
if ((cc.ticks - m_lastTrustStoreUpdate) >= ZT_TRUSTSTORE_UPDATE_PERIOD) {
|
||||
m_lastTrustStoreUpdate = cc.ticks;
|
||||
if (RR->ts->update(cc.ticks, nullptr))
|
||||
RR->topology->trustStoreChanged(cc);
|
||||
}
|
||||
|
||||
// Networks perform housekeeping here such as refreshing configs.
|
||||
if ((cc.ticks - m_lastNetworkHousekeepingRun) >= ZT_NETWORK_HOUSEKEEPING_PERIOD) {
|
||||
m_lastNetworkHousekeepingRun = cc.ticks;
|
||||
ZT_SPEW("running networking housekeeping...");
|
||||
Mutex::Lock l(m_allNetworks_l);
|
||||
for (Vector< SharedPtr< Network > >::const_iterator n(m_allNetworks.begin()); n != m_allNetworks.end(); ++n)
|
||||
(*n)->doPeriodicTasks(cc);
|
||||
}
|
||||
|
||||
// Perform general housekeeping for other objects in the system.
|
||||
if ((cc.ticks - m_lastHousekeepingRun) >= ZT_HOUSEKEEPING_PERIOD) {
|
||||
m_lastHousekeepingRun = cc.ticks;
|
||||
ZT_SPEW("running housekeeping...");
|
||||
|
||||
RR->topology->doPeriodicTasks(cc);
|
||||
RR->sa->clean(cc);
|
||||
}
|
||||
|
||||
// Peers have a "pulse" method that does things like keepalive and path housekeeping.
|
||||
// This happens last because keepalives are only necessary if nothing has been sent
|
||||
// in a while, and some of the above actions may cause peers to send things which may
|
||||
// reduce the need for keepalives. Root ranking also happens here.
|
||||
if ((cc.ticks - m_lastPeerPulse) >= ZT_PEER_PULSE_INTERVAL) {
|
||||
m_lastPeerPulse = cc.ticks;
|
||||
ZT_SPEW("running pulse() on each peer...");
|
||||
try {
|
||||
Vector< SharedPtr< Peer > > allPeers, rootPeers;
|
||||
|
@ -187,41 +216,21 @@ ZT_ResultCode Node::processBackgroundTasks(
|
|||
bool online = false;
|
||||
for (Vector< SharedPtr< Peer > >::iterator p(allPeers.begin()); p != allPeers.end(); ++p) {
|
||||
const bool isRoot = std::find(rootPeers.begin(), rootPeers.end(), *p) != rootPeers.end();
|
||||
(*p)->pulse(tPtr, now, isRoot);
|
||||
online |= ((isRoot || rootPeers.empty()) && (*p)->directlyConnected(now));
|
||||
(*p)->pulse(cc, isRoot);
|
||||
online |= ((isRoot || rootPeers.empty()) && (*p)->directlyConnected(cc));
|
||||
}
|
||||
|
||||
if (m_online.exchange(online) != online)
|
||||
postEvent(tPtr, online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE);
|
||||
postEvent(cc.tPtr, online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE);
|
||||
|
||||
ZT_SPEW("ranking roots...");
|
||||
RR->topology->rankRoots(cc);
|
||||
} catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((now - m_lastNetworkHousekeepingRun) >= ZT_NETWORK_HOUSEKEEPING_PERIOD) {
|
||||
m_lastHousekeepingRun = now;
|
||||
ZT_SPEW("running networking housekeeping...");
|
||||
Mutex::Lock l(m_allNetworks_l);
|
||||
for (Vector< SharedPtr< Network > >::const_iterator i(m_allNetworks.begin()); i != m_allNetworks.end(); ++i) {
|
||||
(*i)->doPeriodicTasks(tPtr, now);
|
||||
}
|
||||
}
|
||||
|
||||
if ((now - m_lastHousekeepingRun) >= ZT_HOUSEKEEPING_PERIOD) {
|
||||
m_lastHousekeepingRun = now;
|
||||
ZT_SPEW("running housekeeping...");
|
||||
|
||||
RR->topology->doPeriodicTasks(tPtr, now);
|
||||
RR->sa->clean(now);
|
||||
}
|
||||
|
||||
if ((now - m_lastRootRank) >= ZT_ROOT_RANK_PERIOD) {
|
||||
m_lastRootRank = now;
|
||||
ZT_SPEW("ranking roots...");
|
||||
RR->topology->rankRoots(now);
|
||||
}
|
||||
|
||||
*nextBackgroundTaskDeadline = now + ZT_TIMER_TASK_INTERVAL;
|
||||
*nextBackgroundTaskDeadline = cc.ticks + ZT_TIMER_TASK_INTERVAL;
|
||||
} catch (...) {
|
||||
return ZT_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
|
@ -233,7 +242,7 @@ ZT_ResultCode Node::join(
|
|||
uint64_t nwid,
|
||||
const ZT_Fingerprint *controllerFingerprint,
|
||||
void *uptr,
|
||||
void *tptr)
|
||||
CallContext &cc)
|
||||
{
|
||||
Mutex::Lock l(m_allNetworks_l);
|
||||
|
||||
|
@ -249,7 +258,7 @@ ZT_ResultCode Node::join(
|
|||
if ((*n)->id() == nwid)
|
||||
return ZT_RESULT_OK;
|
||||
}
|
||||
SharedPtr< Network > network(new Network(RR, tptr, nwid, fp, uptr, nullptr));
|
||||
SharedPtr< Network > network(new Network(RR, cc, nwid, fp, uptr, nullptr));
|
||||
m_allNetworks.push_back(network);
|
||||
RR->networks->set(nwid, network);
|
||||
|
||||
|
@ -259,7 +268,7 @@ ZT_ResultCode Node::join(
|
|||
ZT_ResultCode Node::leave(
|
||||
uint64_t nwid,
|
||||
void **uptr,
|
||||
void *tptr)
|
||||
CallContext &cc)
|
||||
{
|
||||
Mutex::Lock l(m_allNetworks_l);
|
||||
|
||||
|
@ -279,21 +288,22 @@ ZT_ResultCode Node::leave(
|
|||
uint64_t tmp[2];
|
||||
tmp[0] = nwid;
|
||||
tmp[1] = 0;
|
||||
m_store.erase(tptr, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, 1);
|
||||
m_store.erase(cc, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, 1);
|
||||
|
||||
if (network) {
|
||||
if (uptr)
|
||||
*uptr = *network->userPtr();
|
||||
network->externalConfig(&ctmp);
|
||||
RR->node->configureVirtualNetworkPort(tptr, nwid, uptr, ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY, &ctmp);
|
||||
RR->cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(this), RR->uPtr, cc.tPtr, nwid, network->userPtr(), ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY, &ctmp);
|
||||
network->destroy();
|
||||
return ZT_RESULT_OK;
|
||||
} else {
|
||||
return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
|
||||
}
|
||||
return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
|
||||
}
|
||||
|
||||
ZT_ResultCode Node::multicastSubscribe(
|
||||
void *tPtr,
|
||||
CallContext &cc,
|
||||
uint64_t nwid,
|
||||
uint64_t multicastGroup,
|
||||
unsigned long multicastAdi)
|
||||
|
@ -301,7 +311,7 @@ ZT_ResultCode Node::multicastSubscribe(
|
|||
ZT_SPEW("multicast subscribe to %s:%lu", MAC(multicastGroup).toString().c_str(), multicastAdi);
|
||||
const SharedPtr< Network > nw(RR->networks->get(nwid));
|
||||
if (nw) {
|
||||
nw->multicastSubscribe(tPtr, MulticastGroup(MAC(multicastGroup), (uint32_t)(multicastAdi & 0xffffffff)));
|
||||
nw->multicastSubscribe(cc, MulticastGroup(MAC(multicastGroup), (uint32_t)(multicastAdi & 0xffffffff)));
|
||||
return ZT_RESULT_OK;
|
||||
} else {
|
||||
return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
|
||||
|
@ -309,6 +319,7 @@ ZT_ResultCode Node::multicastSubscribe(
|
|||
}
|
||||
|
||||
ZT_ResultCode Node::multicastUnsubscribe(
|
||||
CallContext &cc,
|
||||
uint64_t nwid,
|
||||
uint64_t multicastGroup,
|
||||
unsigned long multicastAdi)
|
||||
|
@ -353,7 +364,7 @@ struct p_sortPeerPtrsByAddress
|
|||
{ return (a->address() < b->address()); }
|
||||
};
|
||||
|
||||
ZT_PeerList *Node::peers() const
|
||||
ZT_PeerList *Node::peers(CallContext &cc) const
|
||||
{
|
||||
p_ZT_PeerListPrivate *pl = nullptr;
|
||||
try {
|
||||
|
@ -364,7 +375,6 @@ ZT_PeerList *Node::peers() const
|
|||
RR->topology->allPeers(peers, rootPeers);
|
||||
std::sort(peers.begin(), peers.end(), p_sortPeerPtrsByAddress());
|
||||
std::sort(rootPeers.begin(), rootPeers.end());
|
||||
int64_t now = m_now;
|
||||
|
||||
for (Vector< SharedPtr< Peer > >::iterator pi(peers.begin()); pi != peers.end(); ++pi) {
|
||||
pl->p_peers.push_back(ZT_Peer());
|
||||
|
@ -405,7 +415,7 @@ ZT_PeerList *Node::peers() const
|
|||
Utils::copy< sizeof(struct sockaddr_storage) >(&(apip.endpoint.value.ss), &(ztp->address().as.ss));
|
||||
apip.lastSend = ztp->lastOut();
|
||||
apip.lastReceive = ztp->lastIn();
|
||||
apip.alive = ztp->alive(now) ? 1 : 0;
|
||||
apip.alive = ztp->alive(cc) ? 1 : 0;
|
||||
apip.preferred = (i == 0) ? 1 : 0;
|
||||
}
|
||||
p.paths = apiPaths.data();
|
||||
|
@ -499,40 +509,8 @@ void Node::setInterfaceAddresses(
|
|||
}
|
||||
}
|
||||
|
||||
ZT_ResultCode Node::addPeer(
|
||||
void *tptr,
|
||||
const ZT_Identity *identity)
|
||||
{
|
||||
if (!identity)
|
||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
SharedPtr< Peer > peer(RR->topology->peer(tptr, reinterpret_cast<const Identity *>(identity)->address()));
|
||||
if (!peer) {
|
||||
peer.set(new Peer(RR));
|
||||
peer->init(*reinterpret_cast<const Identity *>(identity));
|
||||
peer = RR->topology->add(tptr, peer);
|
||||
}
|
||||
return (peer->identity() == *reinterpret_cast<const Identity *>(identity)) ? ZT_RESULT_OK : ZT_RESULT_ERROR_COLLIDING_OBJECT;
|
||||
}
|
||||
|
||||
int Node::tryPeer(
|
||||
void *tptr,
|
||||
const ZT_Fingerprint *fp,
|
||||
const ZT_Endpoint *endpoint,
|
||||
int retries)
|
||||
{
|
||||
if ((!fp) || (!endpoint))
|
||||
return 0;
|
||||
const SharedPtr< Peer > peer(RR->topology->peer(tptr, fp->address, true));
|
||||
if ((peer) && (peer->identity().fingerprint().bestSpecificityEquals(*fp))) {
|
||||
peer->contact(tptr, m_now, Endpoint(*endpoint), std::min(retries, 1));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZT_CertificateError Node::addCertificate(
|
||||
void *tptr,
|
||||
int64_t now,
|
||||
CallContext &cc,
|
||||
unsigned int localTrust,
|
||||
const ZT_Certificate *cert,
|
||||
const void *certData,
|
||||
|
@ -548,13 +526,13 @@ ZT_CertificateError Node::addCertificate(
|
|||
return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
RR->ts->add(c, localTrust);
|
||||
RR->ts->update(now, nullptr);
|
||||
RR->ts->update(cc.clock, nullptr);
|
||||
SharedPtr< TrustStore::Entry > ent(RR->ts->get(c.getSerialNo()));
|
||||
return (ent) ? ent->error() : ZT_CERTIFICATE_ERROR_INVALID_FORMAT; // should never be null, but if so it means invalid
|
||||
}
|
||||
|
||||
ZT_ResultCode Node::deleteCertificate(
|
||||
void *tptr,
|
||||
CallContext &cc,
|
||||
const void *serialNo)
|
||||
{
|
||||
if (!serialNo)
|
||||
|
@ -605,11 +583,11 @@ ZT_CertificateList *Node::listCertificates()
|
|||
}
|
||||
|
||||
int Node::sendUserMessage(
|
||||
void *tptr,
|
||||
CallContext &cc,
|
||||
uint64_t dest,
|
||||
uint64_t typeId,
|
||||
const void *data,
|
||||
unsigned int len)
|
||||
uint64_t /*typeId*/,
|
||||
const void */*data*/,
|
||||
unsigned int /*len*/)
|
||||
{
|
||||
try {
|
||||
if (RR->identity.address().toInt() != dest) {
|
||||
|
@ -679,13 +657,14 @@ bool Node::externalPathLookup(void *tPtr, const Identity &id, int family, InetAd
|
|||
|
||||
// Implementation of NetworkController::Sender ------------------------------------------------------------------------
|
||||
|
||||
void Node::ncSendConfig(uint64_t nwid, uint64_t requestPacketId, const Address &destination, const NetworkConfig &nc, bool sendLegacyFormatConfig)
|
||||
void Node::ncSendConfig(void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address &destination, const NetworkConfig &nc, bool sendLegacyFormatConfig)
|
||||
{
|
||||
if (destination == RR->identity.address()) {
|
||||
SharedPtr< Network > n(RR->networks->get(nwid));
|
||||
if (!n)
|
||||
return;
|
||||
n->setConfiguration((void *)0, nc, true);
|
||||
CallContext cc(clock, ticks, tPtr);
|
||||
n->setConfiguration(cc, nc, true);
|
||||
} else {
|
||||
Dictionary dconf;
|
||||
if (nc.toDictionary(dconf)) {
|
||||
|
@ -731,13 +710,14 @@ void Node::ncSendConfig(uint64_t nwid, uint64_t requestPacketId, const Address &
|
|||
}
|
||||
}
|
||||
|
||||
void Node::ncSendRevocation(const Address &destination, const RevocationCredential &rev)
|
||||
void Node::ncSendRevocation(void *tPtr, int64_t clock, int64_t ticks, const Address &destination, const RevocationCredential &rev)
|
||||
{
|
||||
if (destination == RR->identity.address()) {
|
||||
SharedPtr< Network > n(RR->networks->get(rev.networkId()));
|
||||
if (!n)
|
||||
return;
|
||||
n->addCredential(nullptr, RR->identity, rev);
|
||||
CallContext cc(clock, ticks, tPtr);
|
||||
n->addCredential(cc, RR->identity, rev);
|
||||
} else {
|
||||
// TODO
|
||||
/*
|
||||
|
@ -753,7 +733,7 @@ void Node::ncSendRevocation(const Address &destination, const RevocationCredenti
|
|||
}
|
||||
}
|
||||
|
||||
void Node::ncSendError(uint64_t nwid, uint64_t requestPacketId, const Address &destination, NetworkController::ErrorCode errorCode)
|
||||
void Node::ncSendError(void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address &destination, NetworkController::ErrorCode errorCode)
|
||||
{
|
||||
if (destination == RR->identity.address()) {
|
||||
SharedPtr< Network > n(RR->networks->get(nwid));
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "Buf.hpp"
|
||||
#include "Containers.hpp"
|
||||
#include "Store.hpp"
|
||||
#include "CallContext.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -43,37 +44,35 @@ public:
|
|||
void operator delete(void* p) { _mm_free(p); }
|
||||
#endif
|
||||
|
||||
Node(void *uPtr, void *tPtr, const struct ZT_Node_Callbacks *callbacks, int64_t now);
|
||||
Node(void *uPtr, const struct ZT_Node_Callbacks *callbacks, CallContext &cc);
|
||||
|
||||
virtual ~Node();
|
||||
|
||||
void shutdown(void *tPtr);
|
||||
|
||||
// Public API Functions ---------------------------------------------------------------------------------------------
|
||||
void shutdown(CallContext &cc);
|
||||
|
||||
ZT_ResultCode processBackgroundTasks(
|
||||
void *tPtr,
|
||||
int64_t now,
|
||||
CallContext &cc,
|
||||
volatile int64_t *nextBackgroundTaskDeadline);
|
||||
|
||||
ZT_ResultCode join(
|
||||
uint64_t nwid,
|
||||
const ZT_Fingerprint *controllerFingerprint,
|
||||
void *uptr,
|
||||
void *tptr);
|
||||
CallContext &cc);
|
||||
|
||||
ZT_ResultCode leave(
|
||||
uint64_t nwid,
|
||||
void **uptr,
|
||||
void *tptr);
|
||||
CallContext &cc);
|
||||
|
||||
ZT_ResultCode multicastSubscribe(
|
||||
void *tPtr,
|
||||
CallContext &cc,
|
||||
uint64_t nwid,
|
||||
uint64_t multicastGroup,
|
||||
unsigned long multicastAdi);
|
||||
|
||||
ZT_ResultCode multicastUnsubscribe(
|
||||
CallContext &cc,
|
||||
uint64_t nwid,
|
||||
uint64_t multicastGroup,
|
||||
unsigned long multicastAdi);
|
||||
|
@ -81,7 +80,8 @@ public:
|
|||
void status(
|
||||
ZT_NodeStatus *status) const;
|
||||
|
||||
ZT_PeerList *peers() const;
|
||||
ZT_PeerList *peers(
|
||||
CallContext &cc) const;
|
||||
|
||||
ZT_VirtualNetworkConfig *networkConfig(
|
||||
uint64_t nwid) const;
|
||||
|
@ -96,32 +96,21 @@ public:
|
|||
const ZT_InterfaceAddress *addrs,
|
||||
unsigned int addrCount);
|
||||
|
||||
ZT_ResultCode addPeer(
|
||||
void *tptr,
|
||||
const ZT_Identity *identity);
|
||||
|
||||
int tryPeer(
|
||||
void *tptr,
|
||||
const ZT_Fingerprint *fp,
|
||||
const ZT_Endpoint *endpoint,
|
||||
int retries);
|
||||
|
||||
ZT_CertificateError addCertificate(
|
||||
void *tptr,
|
||||
int64_t now,
|
||||
CallContext &cc,
|
||||
unsigned int localTrust,
|
||||
const ZT_Certificate *cert,
|
||||
const void *certData,
|
||||
unsigned int certSize);
|
||||
|
||||
ZT_ResultCode deleteCertificate(
|
||||
void *tptr,
|
||||
CallContext &cc,
|
||||
const void *serialNo);
|
||||
|
||||
ZT_CertificateList *listCertificates();
|
||||
|
||||
int sendUserMessage(
|
||||
void *tptr,
|
||||
CallContext &cc,
|
||||
uint64_t dest,
|
||||
uint64_t typeId,
|
||||
const void *data,
|
||||
|
@ -130,23 +119,6 @@ public:
|
|||
void setController(
|
||||
void *networkControllerInstance);
|
||||
|
||||
// Internal functions -----------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @return Most recent time value supplied to core via API
|
||||
*/
|
||||
ZT_INLINE int64_t now() const noexcept
|
||||
{ return m_now; }
|
||||
|
||||
/**
|
||||
* @return Known local interface addresses for this node
|
||||
*/
|
||||
ZT_INLINE Vector< ZT_InterfaceAddress > localInterfaceAddresses() const
|
||||
{
|
||||
Mutex::Lock _l(m_localInterfaceAddresses_m);
|
||||
return m_localInterfaceAddresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post an event via external callback
|
||||
*
|
||||
|
@ -158,18 +130,6 @@ public:
|
|||
ZT_INLINE void postEvent(void *tPtr, ZT_Event ev, const void *md = nullptr, const unsigned int mdSize = 0) noexcept
|
||||
{ RR->cb.eventCallback(reinterpret_cast<ZT_Node *>(this), RR->uPtr, tPtr, ev, md, mdSize); }
|
||||
|
||||
/**
|
||||
* Post network port configuration via external callback
|
||||
*
|
||||
* @param tPtr Thread pointer
|
||||
* @param nwid Network ID
|
||||
* @param nuptr Network-associated user pointer
|
||||
* @param op Config operation or event type
|
||||
* @param nc Network config info
|
||||
*/
|
||||
ZT_INLINE void configureVirtualNetworkPort(void *tPtr, uint64_t nwid, void **nuptr, ZT_VirtualNetworkConfigOperation op, const ZT_VirtualNetworkConfig *nc) noexcept
|
||||
{ RR->cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(this), RR->uPtr, tPtr, nwid, nuptr, op, nc); }
|
||||
|
||||
/**
|
||||
* Check whether a path should be used for ZeroTier traffic
|
||||
*
|
||||
|
@ -201,9 +161,9 @@ public:
|
|||
{ return m_RR.identity; }
|
||||
|
||||
// Implementation of NetworkController::Sender interface
|
||||
virtual void ncSendConfig(uint64_t nwid, uint64_t requestPacketId, const Address &destination, const NetworkConfig &nc, bool sendLegacyFormatConfig);
|
||||
virtual void ncSendRevocation(const Address &destination, const RevocationCredential &rev);
|
||||
virtual void ncSendError(uint64_t nwid, uint64_t requestPacketId, const Address &destination, NetworkController::ErrorCode errorCode);
|
||||
virtual void ncSendConfig(void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address &destination, const NetworkConfig &nc, bool sendLegacyFormatConfig);
|
||||
virtual void ncSendRevocation(void *tPtr, int64_t clock, int64_t ticks, const Address &destination, const RevocationCredential &rev);
|
||||
virtual void ncSendError(void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address &destination, NetworkController::ErrorCode errorCode);
|
||||
|
||||
private:
|
||||
RuntimeEnvironment m_RR;
|
||||
|
@ -234,10 +194,7 @@ private:
|
|||
int64_t m_lastPeerPulse;
|
||||
int64_t m_lastHousekeepingRun;
|
||||
int64_t m_lastNetworkHousekeepingRun;
|
||||
int64_t m_lastRootRank;
|
||||
|
||||
// This is the most recent value for time passed in via any of the core API methods.
|
||||
std::atomic< int64_t > m_now;
|
||||
int64_t m_lastTrustStoreUpdate;
|
||||
|
||||
// True if at least one root appears reachable.
|
||||
std::atomic< bool > m_online;
|
||||
|
|
13
core/OS.hpp
13
core/OS.hpp
|
@ -161,11 +161,22 @@
|
|||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus > 199711L
|
||||
#if __cplusplus >= 199711L
|
||||
|
||||
#include <atomic>
|
||||
#ifndef __CPP11__
|
||||
#define __CPP11__ 1
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
#define ZT_MAYBE_UNUSED [[maybe_unused]]
|
||||
#ifndef __CPP17__
|
||||
#define __CPP17__ 1
|
||||
#endif
|
||||
#else
|
||||
#define ZT_MAYBE_UNUSED
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(ZT_ARCH_X64) || defined(__aarch64__)
|
||||
|
|
|
@ -19,11 +19,11 @@ void OwnershipCredential::addThing(const InetAddress &ip)
|
|||
{
|
||||
if (m_thingCount >= ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS)
|
||||
return;
|
||||
if (ip.family() == AF_INET) {
|
||||
if (ip.as.sa.sa_family == AF_INET) {
|
||||
m_thingTypes[m_thingCount] = THING_IPV4_ADDRESS;
|
||||
Utils::copy<4>(m_thingValues[m_thingCount], &(reinterpret_cast<const struct sockaddr_in *>(&ip)->sin_addr.s_addr));
|
||||
++m_thingCount;
|
||||
} else if (ip.family() == AF_INET6) {
|
||||
} else if (ip.as.sa.sa_family == AF_INET6) {
|
||||
m_thingTypes[m_thingCount] = THING_IPV6_ADDRESS;
|
||||
Utils::copy<16>(m_thingValues[m_thingCount], reinterpret_cast<const struct sockaddr_in6 *>(&ip)->sin6_addr.s6_addr);
|
||||
++m_thingCount;
|
||||
|
|
|
@ -45,7 +45,8 @@ class OwnershipCredential : public Credential
|
|||
friend class Credential;
|
||||
|
||||
public:
|
||||
static constexpr ZT_CredentialType credentialType() noexcept { return ZT_CREDENTIAL_TYPE_COO; }
|
||||
static constexpr ZT_CredentialType credentialType() noexcept
|
||||
{ return ZT_CREDENTIAL_TYPE_COO; }
|
||||
|
||||
enum Thing
|
||||
{
|
||||
|
@ -55,7 +56,8 @@ public:
|
|||
THING_IPV6_ADDRESS = 3
|
||||
};
|
||||
|
||||
ZT_INLINE OwnershipCredential() noexcept { memoryZero(this); }
|
||||
ZT_INLINE OwnershipCredential() noexcept
|
||||
{ memoryZero(this); }
|
||||
|
||||
ZT_INLINE OwnershipCredential(const uint64_t nwid, const int64_t ts, const Address &issuedTo, const uint32_t id) noexcept
|
||||
{
|
||||
|
@ -66,32 +68,53 @@ public:
|
|||
m_issuedTo = issuedTo;
|
||||
}
|
||||
|
||||
ZT_INLINE uint64_t networkId() const noexcept { return m_networkId; }
|
||||
ZT_INLINE int64_t timestamp() const noexcept { return m_ts; }
|
||||
ZT_INLINE uint32_t id() const noexcept { return m_id; }
|
||||
ZT_INLINE const Address &issuedTo() const noexcept { return m_issuedTo; }
|
||||
ZT_INLINE const Address &signer() const noexcept { return m_signedBy; }
|
||||
ZT_INLINE const uint8_t *signature() const noexcept { return m_signature; }
|
||||
ZT_INLINE unsigned int signatureLength() const noexcept { return m_signatureLength; }
|
||||
ZT_INLINE uint64_t networkId() const noexcept
|
||||
{ return m_networkId; }
|
||||
|
||||
ZT_INLINE unsigned int thingCount() const noexcept { return (unsigned int)m_thingCount; }
|
||||
ZT_INLINE Thing thingType(const unsigned int i) const noexcept { return (Thing)m_thingTypes[i]; }
|
||||
ZT_INLINE const uint8_t *thingValue(const unsigned int i) const noexcept { return m_thingValues[i]; }
|
||||
ZT_INLINE int64_t timestamp() const noexcept
|
||||
{ return m_ts; }
|
||||
|
||||
ZT_INLINE int64_t revision() const noexcept
|
||||
{ return m_ts; }
|
||||
|
||||
ZT_INLINE uint32_t id() const noexcept
|
||||
{ return m_id; }
|
||||
|
||||
ZT_INLINE const Address &issuedTo() const noexcept
|
||||
{ return m_issuedTo; }
|
||||
|
||||
ZT_INLINE const Address &signer() const noexcept
|
||||
{ return m_signedBy; }
|
||||
|
||||
ZT_INLINE const uint8_t *signature() const noexcept
|
||||
{ return m_signature; }
|
||||
|
||||
ZT_INLINE unsigned int signatureLength() const noexcept
|
||||
{ return m_signatureLength; }
|
||||
|
||||
ZT_INLINE unsigned int thingCount() const noexcept
|
||||
{ return (unsigned int)m_thingCount; }
|
||||
|
||||
ZT_INLINE Thing thingType(const unsigned int i) const noexcept
|
||||
{ return (Thing)m_thingTypes[i]; }
|
||||
|
||||
ZT_INLINE const uint8_t *thingValue(const unsigned int i) const noexcept
|
||||
{ return m_thingValues[i]; }
|
||||
|
||||
ZT_INLINE bool owns(const InetAddress &ip) const noexcept
|
||||
{
|
||||
if (ip.family() == AF_INET)
|
||||
return this->_owns(THING_IPV4_ADDRESS,&(reinterpret_cast<const struct sockaddr_in *>(&ip)->sin_addr.s_addr),4);
|
||||
if (ip.family() == AF_INET6)
|
||||
return this->_owns(THING_IPV6_ADDRESS,reinterpret_cast<const struct sockaddr_in6 *>(&ip)->sin6_addr.s6_addr,16);
|
||||
return false;
|
||||
if (ip.as.sa.sa_family == AF_INET)
|
||||
return this->_owns(THING_IPV4_ADDRESS, &(reinterpret_cast<const struct sockaddr_in *>(&ip)->sin_addr.s_addr), 4);
|
||||
else if (ip.as.sa.sa_family == AF_INET6)
|
||||
return this->_owns(THING_IPV6_ADDRESS, reinterpret_cast<const struct sockaddr_in6 *>(&ip)->sin6_addr.s6_addr, 16);
|
||||
else return false;
|
||||
}
|
||||
|
||||
ZT_INLINE bool owns(const MAC &mac) const noexcept
|
||||
{
|
||||
uint8_t tmp[6];
|
||||
mac.copyTo(tmp);
|
||||
return this->_owns(THING_MAC_ADDRESS,tmp,6);
|
||||
return this->_owns(THING_MAC_ADDRESS, tmp, 6);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -127,22 +150,30 @@ public:
|
|||
* @param tPtr That pointer we pass around
|
||||
* @return Credential verification result: OK, bad signature, or identity needed
|
||||
*/
|
||||
ZT_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return s_verify(RR, tPtr, *this); }
|
||||
ZT_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR, CallContext &cc) const
|
||||
{ return s_verify(RR, cc, *this); }
|
||||
|
||||
static constexpr int marshalSizeMax() noexcept { return ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_SIZE_MAX; }
|
||||
int marshal(uint8_t data[ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_SIZE_MAX],bool forSign = false) const noexcept;
|
||||
int unmarshal(const uint8_t *data,int len) noexcept;
|
||||
static constexpr int marshalSizeMax() noexcept
|
||||
{ return ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_SIZE_MAX; }
|
||||
|
||||
int marshal(uint8_t data[ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_SIZE_MAX], bool forSign = false) const noexcept;
|
||||
|
||||
int unmarshal(const uint8_t *data, int len) noexcept;
|
||||
|
||||
// Provides natural sort order by ID
|
||||
ZT_INLINE bool operator<(const OwnershipCredential &coo) const noexcept { return (m_id < coo.m_id); }
|
||||
ZT_INLINE bool operator<(const OwnershipCredential &coo) const noexcept
|
||||
{ return (m_id < coo.m_id); }
|
||||
|
||||
ZT_INLINE bool operator==(const OwnershipCredential &coo) const noexcept { return (memcmp(this, &coo, sizeof(OwnershipCredential)) == 0); }
|
||||
ZT_INLINE bool operator!=(const OwnershipCredential &coo) const noexcept { return (memcmp(this, &coo, sizeof(OwnershipCredential)) != 0); }
|
||||
ZT_INLINE bool operator==(const OwnershipCredential &coo) const noexcept
|
||||
{ return (memcmp(this, &coo, sizeof(OwnershipCredential)) == 0); }
|
||||
|
||||
ZT_INLINE bool operator!=(const OwnershipCredential &coo) const noexcept
|
||||
{ return (memcmp(this, &coo, sizeof(OwnershipCredential)) != 0); }
|
||||
|
||||
private:
|
||||
ZT_INLINE bool _owns(const Thing &t,const void *v,unsigned int l) const noexcept
|
||||
ZT_INLINE bool _owns(const Thing &t, const void *v, unsigned int l) const noexcept
|
||||
{
|
||||
for(unsigned int i=0,j=m_thingCount;i < j;++i) {
|
||||
for (unsigned int i = 0, j = m_thingCount; i < j; ++i) {
|
||||
if (m_thingTypes[i] == (uint8_t)t) {
|
||||
unsigned int k = 0;
|
||||
while (k < l) {
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
|
||||
namespace ZeroTier {
|
||||
|
||||
bool Path::send(const RuntimeEnvironment *const RR, void *const tPtr, const void *const data, const unsigned int len, const int64_t now) noexcept
|
||||
bool Path::send(const RuntimeEnvironment *const RR, CallContext &cc, const void *const data, const unsigned int len) noexcept
|
||||
{
|
||||
if (likely(RR->cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, tPtr, m_localSocket, reinterpret_cast<const ZT_InetAddress *>(&m_addr), data, len, 0) == 0)) {
|
||||
m_lastOut = now;
|
||||
m_outMeter.log(now, len);
|
||||
if (likely(RR->cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, cc.tPtr, m_localSocket, reinterpret_cast<const ZT_InetAddress *>(&m_addr), data, len, 0) == 0)) {
|
||||
m_lastOut = cc.ticks;
|
||||
m_outMeter.log(cc.ticks, len);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "Mutex.hpp"
|
||||
#include "Meter.hpp"
|
||||
#include "Containers.hpp"
|
||||
#include "CallContext.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -140,14 +141,11 @@ public:
|
|||
/**
|
||||
* Send a packet via this path (last out time is also updated)
|
||||
*
|
||||
* @param RR Runtime environment
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param data Packet data
|
||||
* @param len Packet length
|
||||
* @param now Current time
|
||||
* @return True if transport reported success
|
||||
*/
|
||||
bool send(const RuntimeEnvironment *RR, void *tPtr, const void *data, unsigned int len, int64_t now) noexcept;
|
||||
bool send(const RuntimeEnvironment *RR, CallContext &cc, const void *data, unsigned int len) noexcept;
|
||||
|
||||
/**
|
||||
* Explicitly update last sent time
|
||||
|
@ -155,10 +153,10 @@ public:
|
|||
* @param now Time of send
|
||||
* @param bytes Bytes sent
|
||||
*/
|
||||
ZT_INLINE void sent(const int64_t now, const unsigned int bytes) noexcept
|
||||
ZT_INLINE void sent(const CallContext &cc, const unsigned int bytes) noexcept
|
||||
{
|
||||
m_lastOut.store(now);
|
||||
m_outMeter.log(now, bytes);
|
||||
m_lastOut.store(cc.ticks, std::memory_order_relaxed);
|
||||
m_outMeter.log(cc.ticks, bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -167,10 +165,10 @@ public:
|
|||
* @param now Time of receive
|
||||
* @param bytes Bytes received
|
||||
*/
|
||||
ZT_INLINE void received(const int64_t now, const unsigned int bytes) noexcept
|
||||
ZT_INLINE void received(const CallContext &cc, const unsigned int bytes) noexcept
|
||||
{
|
||||
m_lastIn.store(now);
|
||||
m_inMeter.log(now, bytes);
|
||||
m_lastIn.store(cc.ticks, std::memory_order_relaxed);
|
||||
m_inMeter.log(cc.ticks, bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -199,8 +197,8 @@ public:
|
|||
*
|
||||
* @param now Current time
|
||||
*/
|
||||
ZT_INLINE bool alive(const int64_t now) const noexcept
|
||||
{ return ((now - m_lastIn.load()) < ZT_PATH_ALIVE_TIMEOUT); }
|
||||
ZT_INLINE bool alive(const CallContext &cc) const noexcept
|
||||
{ return ((cc.ticks - m_lastIn.load()) < ZT_PATH_ALIVE_TIMEOUT); }
|
||||
|
||||
/**
|
||||
* @return Physical address
|
||||
|
|
177
core/Peer.cpp
177
core/Peer.cpp
|
@ -45,7 +45,7 @@ Peer::Peer(const RuntimeEnvironment *renv) :
|
|||
Peer::~Peer()
|
||||
{ Utils::burn(m_helloMacKey, sizeof(m_helloMacKey)); }
|
||||
|
||||
bool Peer::init(const Identity &peerIdentity)
|
||||
bool Peer::init(CallContext &cc, const Identity &peerIdentity)
|
||||
{
|
||||
RWMutex::Lock l(m_lock);
|
||||
|
||||
|
@ -56,7 +56,7 @@ bool Peer::init(const Identity &peerIdentity)
|
|||
uint8_t k[ZT_SYMMETRIC_KEY_SIZE];
|
||||
if (!RR->identity.agree(peerIdentity, k))
|
||||
return false;
|
||||
m_identityKey.set(new SymmetricKey(RR->node->now(), k));
|
||||
m_identityKey.set(new SymmetricKey(cc.ticks, k));
|
||||
Utils::burn(k, sizeof(k));
|
||||
|
||||
m_deriveSecondaryIdentityKeys();
|
||||
|
@ -65,7 +65,7 @@ bool Peer::init(const Identity &peerIdentity)
|
|||
}
|
||||
|
||||
void Peer::received(
|
||||
void *tPtr,
|
||||
CallContext &cc,
|
||||
const SharedPtr< Path > &path,
|
||||
const unsigned int hops,
|
||||
const uint64_t packetId,
|
||||
|
@ -73,10 +73,8 @@ void Peer::received(
|
|||
const Protocol::Verb verb,
|
||||
const Protocol::Verb inReVerb)
|
||||
{
|
||||
const int64_t now = RR->node->now();
|
||||
|
||||
m_lastReceive = now;
|
||||
m_inMeter.log(now, payloadLength);
|
||||
m_lastReceive = cc.ticks;
|
||||
m_inMeter.log(cc.ticks, payloadLength);
|
||||
|
||||
if (hops == 0) {
|
||||
RWMutex::RMaybeWLock l(m_lock);
|
||||
|
@ -89,7 +87,7 @@ void Peer::received(
|
|||
}
|
||||
|
||||
// If we made it here, we don't already know this path.
|
||||
if (RR->node->shouldUsePathForZeroTierTraffic(tPtr, m_id, path->localSocket(), path->address())) {
|
||||
if (RR->node->shouldUsePathForZeroTierTraffic(cc.tPtr, m_id, path->localSocket(), path->address())) {
|
||||
// SECURITY: note that if we've made it here we expected this OK, see Expect.hpp.
|
||||
// There is replay protection in effect for OK responses.
|
||||
if (verb == Protocol::VERB_OK) {
|
||||
|
@ -101,7 +99,7 @@ void Peer::received(
|
|||
if (m_alivePathCount == ZT_MAX_PEER_NETWORK_PATHS) {
|
||||
int64_t lastReceiveTimeMax = 0;
|
||||
for (unsigned int i = 0; i < m_alivePathCount; ++i) {
|
||||
if ((m_paths[i]->address().family() == path->address().family()) &&
|
||||
if ((m_paths[i]->address().as.sa.sa_family == path->address().as.sa.sa_family) &&
|
||||
(m_paths[i]->localSocket() == path->localSocket()) && // TODO: should be localInterface when multipath is integrated
|
||||
(m_paths[i]->address().ipsEqual2(path->address()))) {
|
||||
// Replace older path if everything is the same except the port number, since NAT/firewall reboots
|
||||
|
@ -123,7 +121,7 @@ void Peer::received(
|
|||
m_paths[newPathIdx] = path;
|
||||
|
||||
// Re-prioritize paths to include the new one.
|
||||
m_prioritizePaths(now);
|
||||
m_prioritizePaths(cc);
|
||||
|
||||
// Add or update entry in the endpoint cache. If this endpoint
|
||||
// is already present, its timesSeen count is incremented. Otherwise
|
||||
|
@ -133,35 +131,35 @@ void Peer::received(
|
|||
for (unsigned int i = 0;; ++i) {
|
||||
if (i == (ZT_PEER_ENDPOINT_CACHE_SIZE - 1)) {
|
||||
m_endpointCache[i].target = thisEndpoint;
|
||||
m_endpointCache[i].lastSeen = now;
|
||||
m_endpointCache[i].lastSeen = cc.ticks;
|
||||
break;
|
||||
} else if (m_endpointCache[i].target == thisEndpoint) {
|
||||
m_endpointCache[i].lastSeen = now;
|
||||
m_endpointCache[i].lastSeen = cc.ticks;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RR->t->learnedNewPath(tPtr, 0x582fabdd, packetId, m_id, path->address(), old);
|
||||
RR->t->learnedNewPath(cc, 0x582fabdd, packetId, m_id, path->address(), old);
|
||||
} else {
|
||||
path->sent(now, hello(tPtr, path->localSocket(), path->address(), now));
|
||||
RR->t->tryingNewPath(tPtr, 0xb7747ddd, m_id, path->address(), path->address(), packetId, (uint8_t)verb, m_id);
|
||||
path->sent(cc, hello(cc, path->localSocket(), path->address()));
|
||||
RR->t->tryingNewPath(cc, 0xb7747ddd, m_id, path->address(), path->address(), packetId, (uint8_t)verb, m_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Peer::send(void *tPtr, int64_t now, const void *data, unsigned int len) noexcept
|
||||
void Peer::send(CallContext &cc, const void *data, unsigned int len) noexcept
|
||||
{
|
||||
SharedPtr< Path > via(this->path(now));
|
||||
SharedPtr< Path > via(this->path(cc));
|
||||
if (via) {
|
||||
via->send(RR, tPtr, data, len, now);
|
||||
via->send(RR, cc, data, len);
|
||||
} else {
|
||||
const SharedPtr< Peer > root(RR->topology->root());
|
||||
if ((root) && (root.ptr() != this)) {
|
||||
via = root->path(now);
|
||||
via = root->path(cc);
|
||||
if (via) {
|
||||
via->send(RR, tPtr, data, len, now);
|
||||
root->relayed(now, len);
|
||||
via->send(RR, cc, data, len);
|
||||
root->relayed(cc, len);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
@ -169,10 +167,10 @@ void Peer::send(void *tPtr, int64_t now, const void *data, unsigned int len) noe
|
|||
return;
|
||||
}
|
||||
}
|
||||
sent(now, len);
|
||||
sent(cc, len);
|
||||
}
|
||||
|
||||
unsigned int Peer::hello(void *tPtr, int64_t localSocket, const InetAddress &atAddress, const int64_t now)
|
||||
unsigned int Peer::hello(CallContext &cc, int64_t localSocket, const InetAddress &atAddress)
|
||||
{
|
||||
Buf outp;
|
||||
|
||||
|
@ -183,7 +181,7 @@ unsigned int Peer::hello(void *tPtr, int64_t localSocket, const InetAddress &atA
|
|||
outp.wI8(ii, ZEROTIER_VERSION_MAJOR);
|
||||
outp.wI8(ii, ZEROTIER_VERSION_MINOR);
|
||||
outp.wI16(ii, ZEROTIER_VERSION_REVISION);
|
||||
outp.wI64(ii, (uint64_t)now);
|
||||
outp.wI64(ii, (uint64_t)cc.clock);
|
||||
outp.wO(ii, RR->identity);
|
||||
outp.wO(ii, atAddress);
|
||||
|
||||
|
@ -226,10 +224,10 @@ unsigned int Peer::hello(void *tPtr, int64_t localSocket, const InetAddress &atA
|
|||
p1305.finish(polyMac);
|
||||
Utils::storeMachineEndian< uint64_t >(outp.unsafeData + ZT_PROTO_PACKET_MAC_INDEX, polyMac[0]);
|
||||
|
||||
return (likely(RR->cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, tPtr, localSocket, reinterpret_cast<const ZT_InetAddress *>(&atAddress), outp.unsafeData, ii, 0) == 0)) ? ii : 0;
|
||||
return (likely(RR->cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, cc.tPtr, localSocket, reinterpret_cast<const ZT_InetAddress *>(&atAddress), outp.unsafeData, ii, 0) == 0)) ? ii : 0;
|
||||
}
|
||||
|
||||
void Peer::pulse(void *const tPtr, const int64_t now, const bool isRoot)
|
||||
void Peer::pulse(CallContext &cc, const bool isRoot)
|
||||
{
|
||||
RWMutex::Lock l(m_lock);
|
||||
|
||||
|
@ -237,15 +235,15 @@ void Peer::pulse(void *const tPtr, const int64_t now, const bool isRoot)
|
|||
// to be sent. The latter happens every ZT_PEER_HELLO_INTERVAL or if a new
|
||||
// ephemeral key pair is generated.
|
||||
bool needHello = false;
|
||||
if ((m_vProto >= 11) && (((now - m_ephemeralPairTimestamp) >= (ZT_SYMMETRIC_KEY_TTL / 2)) || ((m_ephemeralKeys[0]) && (m_ephemeralKeys[0]->odometer() >= (ZT_SYMMETRIC_KEY_TTL_MESSAGES / 2))))) {
|
||||
if ((m_vProto >= 11) && (((cc.ticks - m_ephemeralPairTimestamp) >= (ZT_SYMMETRIC_KEY_TTL / 2)) || ((m_ephemeralKeys[0]) && (m_ephemeralKeys[0]->odometer() >= (ZT_SYMMETRIC_KEY_TTL_MESSAGES / 2))))) {
|
||||
m_ephemeralPair.generate();
|
||||
needHello = true;
|
||||
} else if ((now - m_lastSentHello) >= ZT_PEER_HELLO_INTERVAL) {
|
||||
} else if ((cc.ticks - m_lastSentHello) >= ZT_PEER_HELLO_INTERVAL) {
|
||||
needHello = true;
|
||||
}
|
||||
|
||||
// Prioritize paths and more importantly for here forget dead ones.
|
||||
m_prioritizePaths(now);
|
||||
m_prioritizePaths(cc);
|
||||
|
||||
if (m_tryQueue.empty()) {
|
||||
if (m_alivePathCount == 0) {
|
||||
|
@ -256,12 +254,12 @@ void Peer::pulse(void *const tPtr, const int64_t now, const bool isRoot)
|
|||
if (m_locator) {
|
||||
for (Vector< std::pair<Endpoint, SharedPtr< const Locator::EndpointAttributes > > >::const_iterator ep(m_locator->endpoints().begin()); ep != m_locator->endpoints().end(); ++ep) {
|
||||
if (ep->first.type == ZT_ENDPOINT_TYPE_IP_UDP) {
|
||||
if (RR->node->shouldUsePathForZeroTierTraffic(tPtr, m_id, -1, ep->first.ip())) {
|
||||
if (RR->node->shouldUsePathForZeroTierTraffic(cc.tPtr, m_id, -1, ep->first.ip())) {
|
||||
int64_t < = m_lastTried[ep->first];
|
||||
if ((now - lt) > ZT_PATH_MIN_TRY_INTERVAL) {
|
||||
lt = now;
|
||||
RR->t->tryingNewPath(tPtr, 0x84b22322, m_id, ep->first.ip(), InetAddress::NIL, 0, 0, Identity::NIL);
|
||||
sent(now, m_sendProbe(tPtr, -1, ep->first.ip(), nullptr, 0, now));
|
||||
if ((cc.ticks - lt) > ZT_PATH_MIN_TRY_INTERVAL) {
|
||||
lt = cc.ticks;
|
||||
RR->t->tryingNewPath(cc, 0x84b22322, m_id, ep->first.ip(), InetAddress::NIL, 0, 0, Identity::NIL);
|
||||
sent(cc, m_sendProbe(cc, -1, ep->first.ip(), nullptr, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -270,25 +268,25 @@ void Peer::pulse(void *const tPtr, const int64_t now, const bool isRoot)
|
|||
|
||||
for (unsigned int i = 0; i < ZT_PEER_ENDPOINT_CACHE_SIZE; ++i) {
|
||||
if ((m_endpointCache[i].lastSeen > 0) && (m_endpointCache[i].target.type == ZT_ENDPOINT_TYPE_IP_UDP)) {
|
||||
if (RR->node->shouldUsePathForZeroTierTraffic(tPtr, m_id, -1, m_endpointCache[i].target.ip())) {
|
||||
if (RR->node->shouldUsePathForZeroTierTraffic(cc.tPtr, m_id, -1, m_endpointCache[i].target.ip())) {
|
||||
int64_t < = m_lastTried[m_endpointCache[i].target];
|
||||
if ((now - lt) > ZT_PATH_MIN_TRY_INTERVAL) {
|
||||
lt = now;
|
||||
RR->t->tryingNewPath(tPtr, 0x84b22343, m_id, m_endpointCache[i].target.ip(), InetAddress::NIL, 0, 0, Identity::NIL);
|
||||
sent(now, m_sendProbe(tPtr, -1, m_endpointCache[i].target.ip(), nullptr, 0, now));
|
||||
if ((cc.ticks - lt) > ZT_PATH_MIN_TRY_INTERVAL) {
|
||||
lt = cc.ticks;
|
||||
RR->t->tryingNewPath(cc, 0x84b22343, m_id, m_endpointCache[i].target.ip(), InetAddress::NIL, 0, 0, Identity::NIL);
|
||||
sent(cc, m_sendProbe(cc, -1, m_endpointCache[i].target.ip(), nullptr, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InetAddress addr;
|
||||
if (RR->node->externalPathLookup(tPtr, m_id, -1, addr)) {
|
||||
if ((addr) && RR->node->shouldUsePathForZeroTierTraffic(tPtr, m_id, -1, addr)) {
|
||||
if (RR->node->externalPathLookup(cc.tPtr, m_id, -1, addr)) {
|
||||
if ((addr) && RR->node->shouldUsePathForZeroTierTraffic(cc.tPtr, m_id, -1, addr)) {
|
||||
int64_t < = m_lastTried[Endpoint(addr)];
|
||||
if ((now - lt) > ZT_PATH_MIN_TRY_INTERVAL) {
|
||||
lt = now;
|
||||
RR->t->tryingNewPath(tPtr, 0x84a10000, m_id, addr, InetAddress::NIL, 0, 0, Identity::NIL);
|
||||
sent(now, m_sendProbe(tPtr, -1, addr, nullptr, 0, now));
|
||||
if ((cc.ticks - lt) > ZT_PATH_MIN_TRY_INTERVAL) {
|
||||
lt = cc.ticks;
|
||||
RR->t->tryingNewPath(cc, 0x84a10000, m_id, addr, InetAddress::NIL, 0, 0, Identity::NIL);
|
||||
sent(cc, m_sendProbe(cc, -1, addr, nullptr, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -318,7 +316,7 @@ void Peer::pulse(void *const tPtr, const int64_t now, const bool isRoot)
|
|||
// If iteration is less than zero, try to contact the original address.
|
||||
// It may be set to a larger negative value to try multiple times such
|
||||
// as e.g. -3 to try 3 times.
|
||||
sent(now, m_sendProbe(tPtr, -1, qi.target.ip(), nullptr, 0, now));
|
||||
sent(cc, m_sendProbe(cc, -1, qi.target.ip(), nullptr, 0));
|
||||
++qi.iteration;
|
||||
goto requeue_item;
|
||||
|
||||
|
@ -340,7 +338,7 @@ void Peer::pulse(void *const tPtr, const int64_t now, const bool isRoot)
|
|||
ports[pn++] = p;
|
||||
}
|
||||
if (pn > 0)
|
||||
sent(now, m_sendProbe(tPtr, -1, qi.target.ip(), ports, pn, now));
|
||||
sent(cc, m_sendProbe(cc, -1, qi.target.ip(), ports, pn));
|
||||
if (qi.iteration < 1023)
|
||||
goto requeue_item;
|
||||
|
||||
|
@ -354,7 +352,7 @@ void Peer::pulse(void *const tPtr, const int64_t now, const bool isRoot)
|
|||
if (p > 65535)
|
||||
p -= 64512; // wrap back to 1024
|
||||
tmp.setPort(p);
|
||||
sent(now, m_sendProbe(tPtr, -1, tmp, nullptr, 0, now));
|
||||
sent(cc, m_sendProbe(cc, -1, tmp, nullptr, 0));
|
||||
if (qi.iteration < ZT_NAT_T_PORT_SCAN_MAX)
|
||||
goto requeue_item;
|
||||
|
||||
|
@ -385,13 +383,13 @@ void Peer::pulse(void *const tPtr, const int64_t now, const bool isRoot)
|
|||
for (unsigned int i = 0; i < m_alivePathCount; ++i) {
|
||||
if (needHello) {
|
||||
needHello = false;
|
||||
const unsigned int bytes = hello(tPtr, m_paths[i]->localSocket(), m_paths[i]->address(), now);
|
||||
m_paths[i]->sent(now, bytes);
|
||||
sent(now, bytes);
|
||||
m_lastSentHello = now;
|
||||
} else if ((now - m_paths[i]->lastOut()) >= ZT_PATH_KEEPALIVE_PERIOD) {
|
||||
m_paths[i]->send(RR, tPtr, reinterpret_cast<uint8_t *>(&randomJunk) + (i & 7U), 1, now);
|
||||
sent(now, 1);
|
||||
const unsigned int bytes = hello(cc, m_paths[i]->localSocket(), m_paths[i]->address());
|
||||
m_paths[i]->sent(cc, bytes);
|
||||
sent(cc, bytes);
|
||||
m_lastSentHello = cc.ticks;
|
||||
} else if ((cc.ticks - m_paths[i]->lastOut()) >= ZT_PATH_KEEPALIVE_PERIOD) {
|
||||
m_paths[i]->send(RR, cc, reinterpret_cast<uint8_t *>(&randomJunk) + (i & 7U), 1);
|
||||
sent(cc, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -399,34 +397,35 @@ void Peer::pulse(void *const tPtr, const int64_t now, const bool isRoot)
|
|||
if (needHello) {
|
||||
const SharedPtr< Peer > root(RR->topology->root());
|
||||
if (root) {
|
||||
const SharedPtr< Path > via(root->path(now));
|
||||
const SharedPtr< Path > via(root->path(cc));
|
||||
if (via) {
|
||||
const unsigned int bytes = hello(tPtr, via->localSocket(), via->address(), now);
|
||||
via->sent(now, bytes);
|
||||
root->relayed(now, bytes);
|
||||
sent(now, bytes);
|
||||
m_lastSentHello = now;
|
||||
const unsigned int bytes = hello(cc, via->localSocket(), via->address());
|
||||
via->sent(cc, bytes);
|
||||
root->relayed(cc, bytes);
|
||||
sent(cc, bytes);
|
||||
m_lastSentHello = cc.ticks;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean m_lastTried
|
||||
for (Map< Endpoint, int64_t >::iterator i(m_lastTried.begin()); i != m_lastTried.end();) {
|
||||
if ((now - i->second) > (ZT_PATH_MIN_TRY_INTERVAL * 4))
|
||||
if ((cc.ticks - i->second) > (ZT_PATH_MIN_TRY_INTERVAL * 4))
|
||||
m_lastTried.erase(i++);
|
||||
else ++i;
|
||||
}
|
||||
}
|
||||
|
||||
void Peer::contact(void *tPtr, const int64_t now, const Endpoint &ep, int tries)
|
||||
void Peer::contact(CallContext &cc, const Endpoint &ep, int tries)
|
||||
{
|
||||
static uint8_t foo = 0;
|
||||
RWMutex::Lock l(m_lock);
|
||||
|
||||
// See if there's already a path to this endpoint and if so ignore it.
|
||||
if (ep.isInetAddr()) {
|
||||
if ((now - m_lastPrioritizedPaths) > ZT_PEER_PRIORITIZE_PATHS_INTERVAL)
|
||||
m_prioritizePaths(now);
|
||||
if ((cc.ticks - m_lastPrioritizedPaths) > ZT_PEER_PRIORITIZE_PATHS_INTERVAL) {
|
||||
m_prioritizePaths(cc);
|
||||
}
|
||||
for (unsigned int i = 0; i < m_alivePathCount; ++i) {
|
||||
if (m_paths[i]->address().ipsEqual(ep.ip()))
|
||||
return;
|
||||
|
@ -435,15 +434,15 @@ void Peer::contact(void *tPtr, const int64_t now, const Endpoint &ep, int tries)
|
|||
|
||||
// Check underlying path attempt rate limit.
|
||||
int64_t < = m_lastTried[ep];
|
||||
if ((now - lt) < ZT_PATH_MIN_TRY_INTERVAL)
|
||||
if ((cc.ticks - lt) < ZT_PATH_MIN_TRY_INTERVAL)
|
||||
return;
|
||||
lt = now;
|
||||
lt = cc.ticks;
|
||||
|
||||
// For IPv4 addresses we send a tiny packet with a low TTL, which helps to
|
||||
// traverse some NAT types. It has no effect otherwise.
|
||||
if (ep.isInetAddr() && ep.ip().isV4()) {
|
||||
++foo;
|
||||
RR->cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, tPtr, -1, reinterpret_cast<const ZT_InetAddress *>(&ep.ip()), &foo, 1, 2);
|
||||
RR->cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, cc.tPtr, -1, reinterpret_cast<const ZT_InetAddress *>(&ep.ip()), &foo, 1, 2);
|
||||
}
|
||||
|
||||
// Make sure address is not already in the try queue. If so just update it.
|
||||
|
@ -458,15 +457,15 @@ void Peer::contact(void *tPtr, const int64_t now, const Endpoint &ep, int tries)
|
|||
m_tryQueue.push_back(p_TryQueueItem(ep, -tries));
|
||||
}
|
||||
|
||||
void Peer::resetWithinScope(void *tPtr, InetAddress::IpScope scope, int inetAddressFamily, int64_t now)
|
||||
void Peer::resetWithinScope(CallContext &cc, InetAddress::IpScope scope, int inetAddressFamily)
|
||||
{
|
||||
RWMutex::Lock l(m_lock);
|
||||
unsigned int pc = 0;
|
||||
for (unsigned int i = 0; i < m_alivePathCount; ++i) {
|
||||
if ((m_paths[i]) && ((m_paths[i]->address().family() == inetAddressFamily) && (m_paths[i]->address().ipScope() == scope))) {
|
||||
const unsigned int bytes = m_sendProbe(tPtr, m_paths[i]->localSocket(), m_paths[i]->address(), nullptr, 0, now);
|
||||
m_paths[i]->sent(now, bytes);
|
||||
sent(now, bytes);
|
||||
if ((m_paths[i]) && (((int)m_paths[i]->address().as.sa.sa_family == inetAddressFamily) && (m_paths[i]->address().ipScope() == scope))) {
|
||||
const unsigned int bytes = m_sendProbe(cc, m_paths[i]->localSocket(), m_paths[i]->address(), nullptr, 0);
|
||||
m_paths[i]->sent(cc, bytes);
|
||||
sent(cc, bytes);
|
||||
} else if (pc != i) {
|
||||
m_paths[pc++] = m_paths[i];
|
||||
}
|
||||
|
@ -476,11 +475,11 @@ void Peer::resetWithinScope(void *tPtr, InetAddress::IpScope scope, int inetAddr
|
|||
m_paths[pc++].zero();
|
||||
}
|
||||
|
||||
bool Peer::directlyConnected(int64_t now)
|
||||
bool Peer::directlyConnected(CallContext &cc)
|
||||
{
|
||||
if ((now - m_lastPrioritizedPaths) > ZT_PEER_PRIORITIZE_PATHS_INTERVAL) {
|
||||
if ((cc.ticks - m_lastPrioritizedPaths) > ZT_PEER_PRIORITIZE_PATHS_INTERVAL) {
|
||||
RWMutex::Lock l(m_lock);
|
||||
m_prioritizePaths(now);
|
||||
m_prioritizePaths(cc);
|
||||
return m_alivePathCount > 0;
|
||||
} else {
|
||||
RWMutex::RLock l(m_lock);
|
||||
|
@ -496,19 +495,19 @@ void Peer::getAllPaths(Vector< SharedPtr< Path > > &paths)
|
|||
paths.assign(m_paths, m_paths + m_alivePathCount);
|
||||
}
|
||||
|
||||
void Peer::save(void *tPtr) const
|
||||
void Peer::save(CallContext &cc) const
|
||||
{
|
||||
uint8_t buf[8 + ZT_PEER_MARSHAL_SIZE_MAX];
|
||||
|
||||
// Prefix each saved peer with the current timestamp.
|
||||
Utils::storeBigEndian< uint64_t >(buf, (uint64_t)RR->node->now());
|
||||
Utils::storeBigEndian< uint64_t >(buf, (uint64_t)cc.clock);
|
||||
|
||||
const int len = marshal(buf + 8);
|
||||
if (len > 0) {
|
||||
uint64_t id[2];
|
||||
id[0] = m_id.address().toInt();
|
||||
id[1] = 0;
|
||||
RR->store->put(tPtr, ZT_STATE_OBJECT_PEER, id, 1, buf, (unsigned int)len + 8);
|
||||
RR->store->put(cc, ZT_STATE_OBJECT_PEER, id, 1, buf, (unsigned int)len + 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -579,7 +578,7 @@ int Peer::marshal(uint8_t data[ZT_PEER_MARSHAL_SIZE_MAX]) const noexcept
|
|||
return p;
|
||||
}
|
||||
|
||||
int Peer::unmarshal(const uint8_t *restrict data, const int len) noexcept
|
||||
int Peer::unmarshal(const int64_t ticks, const uint8_t *restrict data, const int len) noexcept
|
||||
{
|
||||
RWMutex::Lock l(m_lock);
|
||||
|
||||
|
@ -596,7 +595,7 @@ int Peer::unmarshal(const uint8_t *restrict data, const int len) noexcept
|
|||
RR->localSecretCipher.decrypt(data + 1 + ZT_ADDRESS_LENGTH, k);
|
||||
RR->localSecretCipher.decrypt(data + 1 + ZT_ADDRESS_LENGTH + 16, k + 16);
|
||||
RR->localSecretCipher.decrypt(data + 1 + ZT_ADDRESS_LENGTH + 32, k + 32);
|
||||
m_identityKey.set(new SymmetricKey(RR->node->now(), k));
|
||||
m_identityKey.set(new SymmetricKey(ticks, k));
|
||||
Utils::burn(k, sizeof(k));
|
||||
}
|
||||
|
||||
|
@ -611,7 +610,7 @@ int Peer::unmarshal(const uint8_t *restrict data, const int len) noexcept
|
|||
uint8_t k[ZT_SYMMETRIC_KEY_SIZE];
|
||||
if (!RR->identity.agree(m_id, k))
|
||||
return -1;
|
||||
m_identityKey.set(new SymmetricKey(RR->node->now(), k));
|
||||
m_identityKey.set(new SymmetricKey(ticks, k));
|
||||
Utils::burn(k, sizeof(k));
|
||||
}
|
||||
|
||||
|
@ -673,10 +672,10 @@ struct _PathPriorityComparisonOperator
|
|||
}
|
||||
};
|
||||
|
||||
void Peer::m_prioritizePaths(int64_t now)
|
||||
void Peer::m_prioritizePaths(CallContext &cc)
|
||||
{
|
||||
// assumes _lock is locked for writing
|
||||
m_lastPrioritizedPaths = now;
|
||||
m_lastPrioritizedPaths = cc.ticks;
|
||||
|
||||
if (m_alivePathCount > 0) {
|
||||
// Sort paths in descending order of priority.
|
||||
|
@ -684,7 +683,7 @@ void Peer::m_prioritizePaths(int64_t now)
|
|||
|
||||
// Let go of paths that have expired.
|
||||
for (unsigned int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
|
||||
if ((!m_paths[i]) || (!m_paths[i]->alive(now))) {
|
||||
if ((!m_paths[i]) || (!m_paths[i]->alive(cc))) {
|
||||
m_alivePathCount = i;
|
||||
for (; i < ZT_MAX_PEER_NETWORK_PATHS; ++i)
|
||||
m_paths[i].zero();
|
||||
|
@ -694,7 +693,7 @@ void Peer::m_prioritizePaths(int64_t now)
|
|||
}
|
||||
}
|
||||
|
||||
unsigned int Peer::m_sendProbe(void *tPtr, int64_t localSocket, const InetAddress &atAddress, const uint16_t *ports, const unsigned int numPorts, int64_t now)
|
||||
unsigned int Peer::m_sendProbe(CallContext &cc, int64_t localSocket, const InetAddress &atAddress, const uint16_t *ports, const unsigned int numPorts)
|
||||
{
|
||||
// Assumes m_lock is locked
|
||||
const SharedPtr< SymmetricKey > k(m_key());
|
||||
|
@ -709,17 +708,17 @@ unsigned int Peer::m_sendProbe(void *tPtr, int64_t localSocket, const InetAddres
|
|||
|
||||
Protocol::armor(p, ZT_PROTO_MIN_PACKET_LENGTH, k, cipher());
|
||||
|
||||
RR->expect->sending(packetId, now);
|
||||
RR->expect->sending(packetId, cc.ticks);
|
||||
|
||||
if (numPorts > 0) {
|
||||
InetAddress tmp(atAddress);
|
||||
for (unsigned int i = 0; i < numPorts; ++i) {
|
||||
tmp.setPort(ports[i]);
|
||||
RR->cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, tPtr, -1, reinterpret_cast<const ZT_InetAddress *>(&tmp), p, ZT_PROTO_MIN_PACKET_LENGTH, 0);
|
||||
RR->cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, cc.tPtr, -1, reinterpret_cast<const ZT_InetAddress *>(&tmp), p, ZT_PROTO_MIN_PACKET_LENGTH, 0);
|
||||
}
|
||||
return ZT_PROTO_MIN_PACKET_LENGTH * numPorts;
|
||||
} else {
|
||||
RR->cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, tPtr, -1, reinterpret_cast<const ZT_InetAddress *>(&atAddress), p, ZT_PROTO_MIN_PACKET_LENGTH, 0);
|
||||
RR->cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, cc.tPtr, -1, reinterpret_cast<const ZT_InetAddress *>(&atAddress), p, ZT_PROTO_MIN_PACKET_LENGTH, 0);
|
||||
return ZT_PROTO_MIN_PACKET_LENGTH;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ public:
|
|||
* @param peerIdentity The peer's identity
|
||||
* @return True if initialization was succcesful
|
||||
*/
|
||||
bool init(const Identity &peerIdentity);
|
||||
bool init(CallContext &cc, const Identity &peerIdentity);
|
||||
|
||||
/**
|
||||
* @return This peer's ZT address (short for identity().address())
|
||||
|
@ -113,7 +113,7 @@ public:
|
|||
ZT_INLINE SharedPtr< const Locator > setLocator(const SharedPtr< const Locator > &loc, bool verify) noexcept
|
||||
{
|
||||
RWMutex::Lock l(m_lock);
|
||||
if ((loc) && ((!m_locator) || (m_locator->timestamp() < loc->timestamp()))) {
|
||||
if ((loc) && ((!m_locator) || (m_locator->revision() < loc->revision()))) {
|
||||
if ((!verify) || loc->verify(m_id))
|
||||
m_locator = loc;
|
||||
}
|
||||
|
@ -126,7 +126,6 @@ public:
|
|||
* This is called by the decode pipe when a packet is proven to be authentic
|
||||
* and appears to be valid.
|
||||
*
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param path Path over which packet was received
|
||||
* @param hops ZeroTier (not IP) hops
|
||||
* @param packetId Packet ID
|
||||
|
@ -134,7 +133,7 @@ public:
|
|||
* @param inReVerb In-reply verb for OK or ERROR verbs
|
||||
*/
|
||||
void received(
|
||||
void *tPtr,
|
||||
CallContext &cc,
|
||||
const SharedPtr< Path > &path,
|
||||
unsigned int hops,
|
||||
uint64_t packetId,
|
||||
|
@ -145,38 +144,36 @@ public:
|
|||
/**
|
||||
* Log sent data
|
||||
*
|
||||
* @param now Current time
|
||||
* @param bytes Number of bytes written
|
||||
*/
|
||||
ZT_INLINE void sent(const int64_t now, const unsigned int bytes) noexcept
|
||||
ZT_INLINE void sent(CallContext &cc, const unsigned int bytes) noexcept
|
||||
{
|
||||
m_lastSend = now;
|
||||
m_outMeter.log(now, bytes);
|
||||
m_lastSend = cc.ticks;
|
||||
m_outMeter.log(cc.ticks, bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when traffic destined for a different peer is sent to this one
|
||||
*
|
||||
* @param now Current time
|
||||
* @param bytes Number of bytes relayed
|
||||
*/
|
||||
ZT_INLINE void relayed(const int64_t now, const unsigned int bytes) noexcept
|
||||
{ m_relayedMeter.log(now, bytes); }
|
||||
ZT_INLINE void relayed(CallContext &cc, const unsigned int bytes) noexcept
|
||||
{ m_relayedMeter.log(cc.ticks, bytes); }
|
||||
|
||||
/**
|
||||
* Get the current best direct path or NULL if none
|
||||
*
|
||||
* @return Current best path or NULL if there is no direct path
|
||||
*/
|
||||
ZT_INLINE SharedPtr< Path > path(const int64_t now) noexcept
|
||||
ZT_INLINE SharedPtr< Path > path(CallContext &cc) noexcept
|
||||
{
|
||||
if (likely((now - m_lastPrioritizedPaths) < ZT_PEER_PRIORITIZE_PATHS_INTERVAL)) {
|
||||
if (likely((cc.ticks - m_lastPrioritizedPaths) < ZT_PEER_PRIORITIZE_PATHS_INTERVAL)) {
|
||||
RWMutex::RLock l(m_lock);
|
||||
if (m_alivePathCount > 0)
|
||||
return m_paths[0];
|
||||
} else {
|
||||
RWMutex::Lock l(m_lock);
|
||||
m_prioritizePaths(now);
|
||||
m_prioritizePaths(cc);
|
||||
if (m_alivePathCount > 0)
|
||||
return m_paths[0];
|
||||
}
|
||||
|
@ -186,16 +183,14 @@ public:
|
|||
/**
|
||||
* Send data to this peer over a specific path only
|
||||
*
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param now Current time
|
||||
* @param data Data to send
|
||||
* @param len Length in bytes
|
||||
* @param via Path over which to send data (may or may not be an already-learned path for this peer)
|
||||
*/
|
||||
ZT_INLINE void send(void *tPtr, int64_t now, const void *data, unsigned int len, const SharedPtr< Path > &via) noexcept
|
||||
ZT_INLINE void send(CallContext &cc, const void *data, unsigned int len, const SharedPtr< Path > &via) noexcept
|
||||
{
|
||||
via->send(RR, tPtr, data, len, now);
|
||||
sent(now, len);
|
||||
via->send(RR, cc, data, len);
|
||||
sent(cc, len);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -204,42 +199,34 @@ public:
|
|||
* If there is a working direct path it will be used. Otherwise the data will be
|
||||
* sent via a root server.
|
||||
*
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param now Current time
|
||||
* @param data Data to send
|
||||
* @param len Length in bytes
|
||||
*/
|
||||
void send(void *tPtr, int64_t now, const void *data, unsigned int len) noexcept;
|
||||
void send(CallContext &cc, const void *data, unsigned int len) noexcept;
|
||||
|
||||
/**
|
||||
* Send a HELLO to this peer at a specified physical address.
|
||||
*
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param localSocket Local source socket
|
||||
* @param atAddress Destination address
|
||||
* @param now Current time
|
||||
* @return Number of bytes sent
|
||||
*/
|
||||
unsigned int hello(void *tPtr, int64_t localSocket, const InetAddress &atAddress, int64_t now);
|
||||
unsigned int hello(CallContext &cc, int64_t localSocket, const InetAddress &atAddress);
|
||||
|
||||
/**
|
||||
* Ping this peer if needed and/or perform other periodic tasks.
|
||||
*
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param now Current time
|
||||
* @param isRoot True if this peer is a root
|
||||
*/
|
||||
void pulse(void *tPtr, int64_t now, bool isRoot);
|
||||
void pulse(CallContext &cc, bool isRoot);
|
||||
|
||||
/**
|
||||
* Attempt to contact this peer at a given endpoint.
|
||||
*
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param now Current time
|
||||
* @param ep Endpoint to attempt to contact
|
||||
* @param tries Number of times to try (default: 1)
|
||||
*/
|
||||
void contact(void *tPtr, int64_t now, const Endpoint &ep, int tries = 1);
|
||||
void contact(CallContext &cc, const Endpoint &ep, int tries = 1);
|
||||
|
||||
/**
|
||||
* Reset paths within a given IP scope and address family
|
||||
|
@ -249,12 +236,10 @@ public:
|
|||
* to our external IP or another system change that might invalidate
|
||||
* many or all current paths.
|
||||
*
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param scope IP scope
|
||||
* @param inetAddressFamily Family e.g. AF_INET
|
||||
* @param now Current time
|
||||
*/
|
||||
void resetWithinScope(void *tPtr, InetAddress::IpScope scope, int inetAddressFamily, int64_t now);
|
||||
void resetWithinScope(CallContext &cc, InetAddress::IpScope scope, int inetAddressFamily);
|
||||
|
||||
/**
|
||||
* @return Time of last receive of anything, whether direct or relayed
|
||||
|
@ -372,7 +357,7 @@ public:
|
|||
/**
|
||||
* @return True if there is at least one alive direct path
|
||||
*/
|
||||
bool directlyConnected(int64_t now);
|
||||
bool directlyConnected(CallContext &cc);
|
||||
|
||||
/**
|
||||
* Get all paths
|
||||
|
@ -384,7 +369,7 @@ public:
|
|||
/**
|
||||
* Save the latest version of this peer to the data store
|
||||
*/
|
||||
void save(void *tPtr) const;
|
||||
void save(CallContext &cc) const;
|
||||
|
||||
// NOTE: peer marshal/unmarshal only saves/restores the identity, locator, most
|
||||
// recent bootstrap address, and version information.
|
||||
|
@ -393,15 +378,15 @@ public:
|
|||
|
||||
int marshal(uint8_t data[ZT_PEER_MARSHAL_SIZE_MAX]) const noexcept;
|
||||
|
||||
int unmarshal(const uint8_t *restrict data, int len) noexcept;
|
||||
int unmarshal(int64_t ticks, const uint8_t *restrict data, int len) noexcept;
|
||||
|
||||
/**
|
||||
* Rate limit gate for inbound WHOIS requests
|
||||
*/
|
||||
ZT_INLINE bool rateGateInboundWhoisRequest(const int64_t now) noexcept
|
||||
ZT_INLINE bool rateGateInboundWhoisRequest(CallContext &cc) noexcept
|
||||
{
|
||||
if ((now - m_lastWhoisRequestReceived) >= ZT_PEER_WHOIS_RATE_LIMIT) {
|
||||
m_lastWhoisRequestReceived = now;
|
||||
if ((cc.ticks - m_lastWhoisRequestReceived) >= ZT_PEER_WHOIS_RATE_LIMIT) {
|
||||
m_lastWhoisRequestReceived = cc.ticks;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -410,10 +395,10 @@ public:
|
|||
/**
|
||||
* Rate limit gate for inbound ECHO requests
|
||||
*/
|
||||
ZT_INLINE bool rateGateEchoRequest(const int64_t now) noexcept
|
||||
ZT_INLINE bool rateGateEchoRequest(CallContext &cc) noexcept
|
||||
{
|
||||
if ((now - m_lastEchoRequestReceived) >= ZT_PEER_GENERAL_RATE_LIMIT) {
|
||||
m_lastEchoRequestReceived = now;
|
||||
if ((cc.ticks - m_lastEchoRequestReceived) >= ZT_PEER_GENERAL_RATE_LIMIT) {
|
||||
m_lastEchoRequestReceived = cc.ticks;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -422,10 +407,10 @@ public:
|
|||
/**
|
||||
* Rate limit gate for inbound probes
|
||||
*/
|
||||
ZT_INLINE bool rateGateProbeRequest(const int64_t now) noexcept
|
||||
ZT_INLINE bool rateGateProbeRequest(CallContext &cc) noexcept
|
||||
{
|
||||
if ((now - m_lastProbeReceived) > ZT_PEER_PROBE_RESPONSE_RATE_LIMIT) {
|
||||
m_lastProbeReceived = now;
|
||||
if ((cc.ticks - m_lastProbeReceived) > ZT_PEER_PROBE_RESPONSE_RATE_LIMIT) {
|
||||
m_lastProbeReceived = cc.ticks;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -447,10 +432,8 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
void m_prioritizePaths(int64_t now);
|
||||
|
||||
unsigned int m_sendProbe(void *tPtr, int64_t localSocket, const InetAddress &atAddress, const uint16_t *ports, unsigned int numPorts, int64_t now);
|
||||
|
||||
void m_prioritizePaths(CallContext &cc);
|
||||
unsigned int m_sendProbe(CallContext &cc, int64_t localSocket, const InetAddress &atAddress, const uint16_t *ports, unsigned int numPorts);
|
||||
void m_deriveSecondaryIdentityKeys() noexcept;
|
||||
|
||||
ZT_INLINE SharedPtr< SymmetricKey > m_key() noexcept
|
||||
|
|
|
@ -110,8 +110,8 @@ public:
|
|||
* @param RR Runtime environment to provide for peer lookup, etc.
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
*/
|
||||
ZT_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR, void *tPtr) const noexcept
|
||||
{ return s_verify(RR, tPtr, *this); }
|
||||
ZT_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR, CallContext &cc) const noexcept
|
||||
{ return s_verify(RR, cc, *this); }
|
||||
|
||||
static constexpr int marshalSizeMax() noexcept
|
||||
{ return ZT_REVOCATION_MARSHAL_SIZE_MAX; }
|
||||
|
|
|
@ -39,19 +39,26 @@ class Salsa20 : public TriviallyCopyable
|
|||
{
|
||||
public:
|
||||
#ifdef ZT_SALSA20_SSE
|
||||
static constexpr bool accelerated() noexcept { return true; }
|
||||
|
||||
static constexpr bool accelerated() noexcept
|
||||
{ return true; }
|
||||
|
||||
#else
|
||||
static constexpr bool accelerated() noexcept { return false; }
|
||||
#endif
|
||||
|
||||
ZT_INLINE Salsa20() noexcept {}
|
||||
ZT_INLINE ~Salsa20() noexcept { Utils::burn(&_state,sizeof(_state)); }
|
||||
ZT_INLINE Salsa20() noexcept
|
||||
{}
|
||||
|
||||
ZT_INLINE ~Salsa20() noexcept
|
||||
{ Utils::burn(&_state, sizeof(_state)); }
|
||||
|
||||
/**
|
||||
* @param key 256-bit (32 byte) key
|
||||
* @param iv 64-bit initialization vector
|
||||
*/
|
||||
ZT_INLINE Salsa20(const void *key,const void *iv) noexcept { init(key,iv); }
|
||||
ZT_INLINE Salsa20(const void *key, const void *iv) noexcept
|
||||
{ init(key, iv); }
|
||||
|
||||
/**
|
||||
* Initialize cipher
|
||||
|
@ -59,7 +66,7 @@ public:
|
|||
* @param key Key bits
|
||||
* @param iv 64-bit initialization vector
|
||||
*/
|
||||
void init(const void *key,const void *iv) noexcept;
|
||||
void init(const void *key, const void *iv) noexcept;
|
||||
|
||||
/**
|
||||
* Encrypt/decrypt data using Salsa20/12
|
||||
|
@ -68,7 +75,7 @@ public:
|
|||
* @param out Output buffer
|
||||
* @param bytes Length of data
|
||||
*/
|
||||
void crypt12(const void *in,void *out,unsigned int bytes) noexcept;
|
||||
void crypt12(const void *in, void *out, unsigned int bytes) noexcept;
|
||||
|
||||
/**
|
||||
* Encrypt/decrypt data using Salsa20/20
|
||||
|
@ -77,10 +84,11 @@ public:
|
|||
* @param out Output buffer
|
||||
* @param bytes Length of data
|
||||
*/
|
||||
void crypt20(const void *in,void *out,unsigned int bytes) noexcept;
|
||||
void crypt20(const void *in, void *out, unsigned int bytes) noexcept;
|
||||
|
||||
private:
|
||||
union {
|
||||
union
|
||||
{
|
||||
#ifdef ZT_SALSA20_SSE
|
||||
__m128i v[4];
|
||||
#endif // ZT_SALSA20_SSE
|
||||
|
|
|
@ -84,6 +84,6 @@ namespace std {
|
|||
template< typename T >
|
||||
ZT_INLINE void swap(ZeroTier::ScopedPtr< T > &a, ZeroTier::ScopedPtr< T > &b) noexcept
|
||||
{ a.swap(b); }
|
||||
}
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,32 +24,12 @@
|
|||
|
||||
namespace ZeroTier {
|
||||
|
||||
class _ResetWithinScope
|
||||
{
|
||||
public:
|
||||
ZT_INLINE _ResetWithinScope(void *tPtr, int64_t now, int inetAddressFamily, InetAddress::IpScope scope) :
|
||||
_now(now),
|
||||
_tPtr(tPtr),
|
||||
_family(inetAddressFamily),
|
||||
_scope(scope)
|
||||
{}
|
||||
|
||||
ZT_INLINE void operator()(const SharedPtr< Peer > &p)
|
||||
{ p->resetWithinScope(_tPtr, _scope, _family, _now); }
|
||||
|
||||
private:
|
||||
int64_t _now;
|
||||
void *_tPtr;
|
||||
int _family;
|
||||
InetAddress::IpScope _scope;
|
||||
};
|
||||
|
||||
SelfAwareness::SelfAwareness(const RuntimeEnvironment *renv) :
|
||||
RR(renv)
|
||||
{
|
||||
}
|
||||
|
||||
void SelfAwareness::iam(void *tPtr, const Identity &reporter, const int64_t receivedOnLocalSocket, const InetAddress &reporterPhysicalAddress, const InetAddress &myPhysicalAddress, bool trusted, int64_t now)
|
||||
void SelfAwareness::iam(CallContext &cc, const Identity &reporter, const int64_t receivedOnLocalSocket, const InetAddress &reporterPhysicalAddress, const InetAddress &myPhysicalAddress, bool trusted)
|
||||
{
|
||||
const InetAddress::IpScope scope = myPhysicalAddress.ipScope();
|
||||
|
||||
|
@ -59,10 +39,10 @@ void SelfAwareness::iam(void *tPtr, const Identity &reporter, const int64_t rece
|
|||
Mutex::Lock l(m_phy_l);
|
||||
p_PhySurfaceEntry &entry = m_phy[p_PhySurfaceKey(reporter.address(), receivedOnLocalSocket, reporterPhysicalAddress, scope)];
|
||||
|
||||
if ((trusted) && ((now - entry.ts) < ZT_SELFAWARENESS_ENTRY_TIMEOUT) && (!entry.mySurface.ipsEqual(myPhysicalAddress))) {
|
||||
if ((trusted) && ((cc.ticks - entry.timestampTicks) < ZT_SELFAWARENESS_ENTRY_TIMEOUT) && (!entry.mySurface.ipsEqual(myPhysicalAddress))) {
|
||||
// Changes to external surface reported by trusted peers causes path reset in this scope
|
||||
entry.mySurface = myPhysicalAddress;
|
||||
entry.ts = now;
|
||||
entry.timestampTicks = cc.ticks;
|
||||
entry.trusted = trusted;
|
||||
|
||||
// Erase all entries in this scope that were not reported from this remote address to prevent 'thrashing'
|
||||
|
@ -78,28 +58,28 @@ void SelfAwareness::iam(void *tPtr, const Identity &reporter, const int64_t rece
|
|||
Vector< SharedPtr< Peer > > peers, rootPeers;
|
||||
RR->topology->allPeers(peers, rootPeers);
|
||||
for(Vector< SharedPtr< Peer > >::const_iterator p(peers.begin());p!=peers.end();++p)
|
||||
(*p)->resetWithinScope(tPtr, (InetAddress::IpScope)scope, myPhysicalAddress.family(), now);
|
||||
(*p)->resetWithinScope(cc, (InetAddress::IpScope)scope, myPhysicalAddress.as.sa.sa_family);
|
||||
|
||||
RR->t->resettingPathsInScope(tPtr, 0x9afff100, reporter, reporterPhysicalAddress, entry.mySurface, myPhysicalAddress, scope);
|
||||
RR->t->resettingPathsInScope(cc, 0x9afff100, reporter, reporterPhysicalAddress, entry.mySurface, myPhysicalAddress, scope);
|
||||
} else {
|
||||
// Otherwise just update DB to use to determine external surface info
|
||||
entry.mySurface = myPhysicalAddress;
|
||||
entry.ts = now;
|
||||
entry.timestampTicks = cc.ticks;
|
||||
entry.trusted = trusted;
|
||||
}
|
||||
}
|
||||
|
||||
void SelfAwareness::clean(int64_t now)
|
||||
void SelfAwareness::clean(CallContext &cc)
|
||||
{
|
||||
Mutex::Lock l(m_phy_l);
|
||||
for (Map< p_PhySurfaceKey, p_PhySurfaceEntry >::iterator i(m_phy.begin()); i != m_phy.end();) {
|
||||
if ((now - i->second.ts) >= ZT_SELFAWARENESS_ENTRY_TIMEOUT)
|
||||
if ((cc.ticks - i->second.timestampTicks) >= ZT_SELFAWARENESS_ENTRY_TIMEOUT)
|
||||
m_phy.erase(i++);
|
||||
else ++i;
|
||||
}
|
||||
}
|
||||
|
||||
MultiMap< unsigned int, InetAddress > SelfAwareness::externalAddresses(const int64_t now) const
|
||||
MultiMap< unsigned int, InetAddress > SelfAwareness::externalAddresses(CallContext &cc) const
|
||||
{
|
||||
MultiMap< unsigned int, InetAddress > r;
|
||||
|
||||
|
@ -108,7 +88,7 @@ MultiMap< unsigned int, InetAddress > SelfAwareness::externalAddresses(const int
|
|||
{
|
||||
Mutex::Lock l(m_phy_l);
|
||||
for (Map< p_PhySurfaceKey, p_PhySurfaceEntry >::const_iterator i(m_phy.begin()); i != m_phy.end(); ++i) {
|
||||
if ((now - i->second.ts) < ZT_SELFAWARENESS_ENTRY_TIMEOUT)
|
||||
if ((cc.ticks - i->second.timestampTicks) < ZT_SELFAWARENESS_ENTRY_TIMEOUT)
|
||||
++counts[i->second.mySurface];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "Containers.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "CallContext.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -44,24 +45,20 @@ public:
|
|||
* @param reporterPhysicalAddress Physical address that reporting peer seems to have
|
||||
* @param myPhysicalAddress Physical address that peer says we have
|
||||
* @param trusted True if this peer is trusted as an authority to inform us of external address changes
|
||||
* @param now Current time
|
||||
*/
|
||||
void iam(void *tPtr, const Identity &reporter, int64_t receivedOnLocalSocket, const InetAddress &reporterPhysicalAddress, const InetAddress &myPhysicalAddress, bool trusted, int64_t now);
|
||||
void iam(CallContext &cc, const Identity &reporter, int64_t receivedOnLocalSocket, const InetAddress &reporterPhysicalAddress, const InetAddress &myPhysicalAddress, bool trusted);
|
||||
|
||||
/**
|
||||
* Clean up database periodically
|
||||
*
|
||||
* @param now Current time
|
||||
*/
|
||||
void clean(int64_t now);
|
||||
void clean(CallContext &cc);
|
||||
|
||||
/**
|
||||
* Get external address consensus, which is the statistical "mode" of external addresses.
|
||||
*
|
||||
* @param now Current time
|
||||
* @return Map of count to IP/port representing how many endpoints reported each address
|
||||
*/
|
||||
MultiMap< unsigned int, InetAddress > externalAddresses(int64_t now) const;
|
||||
MultiMap< unsigned int, InetAddress > externalAddresses(CallContext &cc) const;
|
||||
|
||||
private:
|
||||
struct p_PhySurfaceKey
|
||||
|
@ -108,13 +105,13 @@ private:
|
|||
struct p_PhySurfaceEntry
|
||||
{
|
||||
InetAddress mySurface;
|
||||
int64_t ts;
|
||||
int64_t timestampTicks;
|
||||
bool trusted;
|
||||
|
||||
ZT_INLINE p_PhySurfaceEntry() noexcept: mySurface(), ts(0), trusted(false)
|
||||
ZT_INLINE p_PhySurfaceEntry() noexcept: mySurface(), timestampTicks(0), trusted(false)
|
||||
{}
|
||||
|
||||
ZT_INLINE p_PhySurfaceEntry(const InetAddress &a, const int64_t t) noexcept: mySurface(a), ts(t), trusted(false)
|
||||
ZT_INLINE p_PhySurfaceEntry(const InetAddress &a, const int64_t t) noexcept: mySurface(a), timestampTicks(t), trusted(false)
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ public:
|
|||
{}
|
||||
|
||||
explicit ZT_INLINE SharedPtr(T *obj) noexcept: m_ptr(obj)
|
||||
{ if (likely(obj != nullptr)) const_cast<std::atomic< int > *>(&(obj->__refCount))->fetch_add(1, std::memory_order_relaxed); }
|
||||
{ if (likely(obj != nullptr)) const_cast<std::atomic< int > *>(&(obj->__refCount))->fetch_add(1, std::memory_order_acquire); }
|
||||
|
||||
ZT_INLINE SharedPtr(const SharedPtr &sp) noexcept: m_ptr(sp._getAndInc())
|
||||
{}
|
||||
|
@ -54,7 +54,7 @@ public:
|
|||
ZT_INLINE void set(T *ptr) noexcept
|
||||
{
|
||||
_release();
|
||||
const_cast<std::atomic< int > *>(&((m_ptr = ptr)->__refCount))->fetch_add(1, std::memory_order_relaxed);
|
||||
const_cast<std::atomic< int > *>(&((m_ptr = ptr)->__refCount))->fetch_add(1, std::memory_order_acquire);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,7 +122,7 @@ public:
|
|||
{
|
||||
if (likely(m_ptr != nullptr)) {
|
||||
int one = 1;
|
||||
if (const_cast<std::atomic< int > *>(&(m_ptr->__refCount))->compare_exchange_strong(one, (int)0)) {
|
||||
if (const_cast<std::atomic< int > *>(&(m_ptr->__refCount))->compare_exchange_strong(one, (int)0, std::memory_order_acq_rel)) {
|
||||
delete m_ptr;
|
||||
m_ptr = nullptr;
|
||||
return true;
|
||||
|
@ -145,14 +145,6 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast this SharedPtr<> to one that holds a const instance of the type
|
||||
*
|
||||
* @return "this" casted in place to hold "const T"
|
||||
*/
|
||||
ZT_INLINE const SharedPtr<const T> &constify() const noexcept
|
||||
{ return reinterpret_cast< const SharedPtr<const T> >(*this); }
|
||||
|
||||
ZT_INLINE unsigned long hashCode() const noexcept
|
||||
{ return (unsigned long)Utils::hash64((uint64_t)((uintptr_t)m_ptr)); }
|
||||
|
||||
|
@ -178,13 +170,13 @@ private:
|
|||
ZT_INLINE T *_getAndInc() const noexcept
|
||||
{
|
||||
if (likely(m_ptr != nullptr))
|
||||
const_cast<std::atomic< int > *>(&(m_ptr->__refCount))->fetch_add(1, std::memory_order_relaxed);
|
||||
const_cast<std::atomic< int > *>(&(m_ptr->__refCount))->fetch_add(1, std::memory_order_acquire);
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
ZT_INLINE void _release() const noexcept
|
||||
{
|
||||
if (unlikely((m_ptr != nullptr)&&(const_cast<std::atomic< int > *>(&(m_ptr->__refCount))->fetch_sub(1, std::memory_order_relaxed) <= 1)))
|
||||
if (unlikely((m_ptr != nullptr)&&(const_cast<std::atomic< int > *>(&(m_ptr->__refCount))->fetch_sub(1, std::memory_order_release) <= 1)))
|
||||
delete m_ptr;
|
||||
}
|
||||
|
||||
|
@ -197,9 +189,13 @@ private:
|
|||
namespace std {
|
||||
|
||||
template< typename T >
|
||||
ZT_INLINE void swap(ZeroTier::SharedPtr< T > &a, ZeroTier::SharedPtr< T > &b) noexcept
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void swap(ZeroTier::SharedPtr< T > &a, ZeroTier::SharedPtr< T > &b) noexcept
|
||||
{ a.swap(b); }
|
||||
|
||||
template< typename T >
|
||||
ZT_MAYBE_UNUSED ZT_INLINE void move(ZeroTier::SharedPtr< T > &a, ZeroTier::SharedPtr< T > &b) noexcept
|
||||
{ a.move(b); }
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "Constants.hpp"
|
||||
#include "Containers.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "CallContext.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -32,18 +33,17 @@ public:
|
|||
/**
|
||||
* Get a state object
|
||||
*
|
||||
* @param tPtr Thread pointer to pass through
|
||||
* @param type Object type
|
||||
* @param id Object ID
|
||||
* @param idSize Size of object ID in qwords
|
||||
* @return Data or empty vector if not found
|
||||
*/
|
||||
ZT_INLINE Vector< uint8_t > get(void *tPtr, ZT_StateObjectType type, const uint64_t *id, unsigned int idSize) const
|
||||
ZT_INLINE Vector< uint8_t > get(CallContext &cc, ZT_StateObjectType type, const uint64_t *id, unsigned int idSize) const
|
||||
{
|
||||
Vector< uint8_t > dv;
|
||||
void *data = nullptr;
|
||||
void (*freeFunc)(void *) = nullptr;
|
||||
const int r = RR->cb.stateGetFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, tPtr, type, id, idSize, &data, &freeFunc);
|
||||
const int r = RR->cb.stateGetFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, cc.tPtr, type, id, idSize, &data, &freeFunc);
|
||||
if (r > 0)
|
||||
dv.assign(reinterpret_cast<const uint8_t *>(data), reinterpret_cast<const uint8_t *>(data) + r);
|
||||
if ((data) && (freeFunc))
|
||||
|
@ -54,26 +54,24 @@ public:
|
|||
/**
|
||||
* Store a state object
|
||||
*
|
||||
* @param tPtr Thread pointer to pass through
|
||||
* @param type Object type
|
||||
* @param id Object ID
|
||||
* @param idSize Size of object ID in qwords
|
||||
* @param data Data to store
|
||||
* @param len Length of data
|
||||
*/
|
||||
ZT_INLINE void put(void *const tPtr, ZT_StateObjectType type, const uint64_t *const id, const unsigned int idSize, const void *const data, const unsigned int len) noexcept
|
||||
{ RR->cb.statePutFunction(reinterpret_cast<ZT_Node *>(this), RR->uPtr, tPtr, type, id, idSize, data, (int)len); }
|
||||
ZT_INLINE void put(CallContext &cc, ZT_StateObjectType type, const uint64_t *const id, const unsigned int idSize, const void *const data, const unsigned int len) noexcept
|
||||
{ RR->cb.statePutFunction(reinterpret_cast<ZT_Node *>(this), RR->uPtr, cc.tPtr, type, id, idSize, data, (int)len); }
|
||||
|
||||
/**
|
||||
* Erase a state object from the object store
|
||||
*
|
||||
* @param tPtr Thread pointer to pass through
|
||||
* @param type Object type
|
||||
* @param id Object ID
|
||||
* @param idSize Size of object ID in qwords
|
||||
*/
|
||||
ZT_INLINE void erase(void *const tPtr, ZT_StateObjectType type, const uint64_t *const id, const unsigned int idSize) noexcept
|
||||
{ RR->cb.statePutFunction(reinterpret_cast<ZT_Node *>(this), RR->uPtr, tPtr, type, id, idSize, nullptr, -1); }
|
||||
ZT_INLINE void erase(CallContext &cc, ZT_StateObjectType type, const uint64_t *const id, const unsigned int idSize) noexcept
|
||||
{ RR->cb.statePutFunction(reinterpret_cast<ZT_Node *>(this), RR->uPtr, cc.tPtr, type, id, idSize, nullptr, -1); }
|
||||
|
||||
private:
|
||||
const RuntimeEnvironment *RR;
|
||||
|
|
|
@ -84,6 +84,9 @@ public:
|
|||
ZT_INLINE int64_t timestamp() const noexcept
|
||||
{ return m_ts; }
|
||||
|
||||
ZT_INLINE int64_t revision() const noexcept
|
||||
{ return m_ts; }
|
||||
|
||||
ZT_INLINE const Address &issuedTo() const noexcept
|
||||
{ return m_issuedTo; }
|
||||
|
||||
|
@ -110,8 +113,8 @@ public:
|
|||
* @param RR Runtime environment to allow identity lookup for signedBy
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
*/
|
||||
ZT_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR, void *tPtr) const noexcept
|
||||
{ return s_verify(RR, tPtr, *this); }
|
||||
ZT_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR, CallContext &cc) const noexcept
|
||||
{ return s_verify(RR, cc, *this); }
|
||||
|
||||
static constexpr int marshalSizeMax() noexcept
|
||||
{ return ZT_TAG_MARSHAL_SIZE_MAX; }
|
||||
|
|
|
@ -13,20 +13,22 @@
|
|||
|
||||
#include "Topology.hpp"
|
||||
#include "Defaults.hpp"
|
||||
#include "TrustStore.hpp"
|
||||
#include "Locator.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
Topology::Topology(const RuntimeEnvironment *renv, void *tPtr, const int64_t now) :
|
||||
Topology::Topology(const RuntimeEnvironment *renv, CallContext &cc) :
|
||||
RR(renv)
|
||||
{}
|
||||
|
||||
SharedPtr< Peer > Topology::add(void *tPtr, const SharedPtr< Peer > &peer)
|
||||
SharedPtr< Peer > Topology::add(CallContext &cc, const SharedPtr< Peer > &peer)
|
||||
{
|
||||
RWMutex::Lock _l(m_peers_l);
|
||||
SharedPtr< Peer > &hp = m_peers[peer->address()];
|
||||
if (hp)
|
||||
return hp;
|
||||
m_loadCached(tPtr, peer->address(), hp);
|
||||
m_loadCached(cc, peer->address(), hp);
|
||||
if (hp)
|
||||
return hp;
|
||||
hp = peer;
|
||||
|
@ -48,13 +50,13 @@ void Topology::allPeers(Vector< SharedPtr< Peer > > &allPeers, Vector< SharedPtr
|
|||
}
|
||||
}
|
||||
|
||||
void Topology::doPeriodicTasks(void *tPtr, const int64_t now)
|
||||
void Topology::doPeriodicTasks(CallContext &cc)
|
||||
{
|
||||
// Get a list of root peer pointer addresses for filtering during peer cleanup.
|
||||
Vector< uintptr_t > rootLookup;
|
||||
{
|
||||
Mutex::Lock l(m_roots_l);
|
||||
m_rankRoots(now);
|
||||
m_rankRoots();
|
||||
rootLookup.reserve(m_roots.size());
|
||||
for (Vector< SharedPtr< Peer > >::const_iterator r(m_roots.begin()); r != m_roots.end(); ++r)
|
||||
rootLookup.push_back((uintptr_t)r->ptr());
|
||||
|
@ -69,7 +71,7 @@ void Topology::doPeriodicTasks(void *tPtr, const int64_t now)
|
|||
RWMutex::RLock l1(m_peers_l);
|
||||
for (Map< Address, SharedPtr< Peer > >::iterator i(m_peers.begin()); i != m_peers.end(); ++i) {
|
||||
// TODO: also delete if the peer has not exchanged meaningful communication in a while, such as a network frame or non-trivial control packet.
|
||||
if (((now - i->second->lastReceive()) > ZT_PEER_ALIVE_TIMEOUT) && (std::find(rootLookup.begin(), rootLookup.end(), (uintptr_t)(i->second.ptr())) == rootLookup.end()))
|
||||
if (((cc.ticks - i->second->lastReceive()) > ZT_PEER_ALIVE_TIMEOUT) && (std::find(rootLookup.begin(), rootLookup.end(), (uintptr_t)(i->second.ptr())) == rootLookup.end()))
|
||||
toDelete.push_back(i->first);
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +88,7 @@ void Topology::doPeriodicTasks(void *tPtr, const int64_t now)
|
|||
}
|
||||
}
|
||||
if (toSave)
|
||||
toSave->save(tPtr);
|
||||
toSave->save(cc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,11 +119,37 @@ void Topology::doPeriodicTasks(void *tPtr, const int64_t now)
|
|||
}
|
||||
}
|
||||
|
||||
void Topology::saveAll(void *tPtr)
|
||||
void Topology::trustStoreChanged(CallContext &cc)
|
||||
{
|
||||
Map< Identity, SharedPtr< const Locator > > roots(RR->ts->roots());
|
||||
|
||||
Vector< SharedPtr< Peer > > newRootList;
|
||||
newRootList.reserve(roots.size());
|
||||
|
||||
for (Map< Identity, SharedPtr< const Locator > >::const_iterator r(roots.begin()); r != roots.end(); ++r) {
|
||||
SharedPtr< Peer > root(this->peer(cc, r->first.address(), true));
|
||||
if (!root) {
|
||||
root.set(new Peer(RR));
|
||||
root->init(cc, r->first);
|
||||
root = this->add(cc, root);
|
||||
}
|
||||
newRootList.push_back(root);
|
||||
if (r->second)
|
||||
root->setLocator(r->second, true);
|
||||
}
|
||||
|
||||
{
|
||||
Mutex::Lock l(m_roots_l);
|
||||
m_roots.swap(newRootList);
|
||||
m_rankRoots();
|
||||
}
|
||||
}
|
||||
|
||||
void Topology::saveAll(CallContext &cc)
|
||||
{
|
||||
RWMutex::RLock l(m_peers_l);
|
||||
for (Map< Address, SharedPtr< Peer > >::iterator i(m_peers.begin()); i != m_peers.end(); ++i)
|
||||
i->second->save(tPtr);
|
||||
i->second->save(cc);
|
||||
}
|
||||
|
||||
struct p_RootRankingComparisonOperator
|
||||
|
@ -147,7 +175,7 @@ struct p_RootRankingComparisonOperator
|
|||
}
|
||||
};
|
||||
|
||||
void Topology::m_rankRoots(const int64_t now)
|
||||
void Topology::m_rankRoots()
|
||||
{
|
||||
// assumes m_roots is locked
|
||||
if (unlikely(m_roots.empty())) {
|
||||
|
@ -162,7 +190,7 @@ void Topology::m_rankRoots(const int64_t now)
|
|||
}
|
||||
}
|
||||
|
||||
void Topology::m_loadCached(void *tPtr, const Address &zta, SharedPtr< Peer > &peer)
|
||||
void Topology::m_loadCached(CallContext &cc, const Address &zta, SharedPtr< Peer > &peer)
|
||||
{
|
||||
// does not require any locks to be held
|
||||
|
||||
|
@ -170,19 +198,19 @@ void Topology::m_loadCached(void *tPtr, const Address &zta, SharedPtr< Peer > &p
|
|||
uint64_t id[2];
|
||||
id[0] = zta.toInt();
|
||||
id[1] = 0;
|
||||
Vector< uint8_t > data(RR->store->get(tPtr, ZT_STATE_OBJECT_PEER, id, 1));
|
||||
Vector< uint8_t > data(RR->store->get(cc, ZT_STATE_OBJECT_PEER, id, 1));
|
||||
if (data.size() > 8) {
|
||||
const uint8_t *d = data.data();
|
||||
int dl = (int)data.size();
|
||||
|
||||
const int64_t ts = (int64_t)Utils::loadBigEndian< uint64_t >(d);
|
||||
Peer *const p = new Peer(RR);
|
||||
int n = p->unmarshal(d + 8, dl - 8);
|
||||
int n = p->unmarshal(cc.ticks, d + 8, dl - 8);
|
||||
if (n < 0) {
|
||||
delete p;
|
||||
return;
|
||||
}
|
||||
if ((RR->node->now() - ts) < ZT_PEER_GLOBAL_TIMEOUT) {
|
||||
if ((cc.ticks - ts) < ZT_PEER_GLOBAL_TIMEOUT) {
|
||||
// TODO: handle many peers, same address (?)
|
||||
peer.set(p);
|
||||
return;
|
||||
|
@ -193,10 +221,10 @@ void Topology::m_loadCached(void *tPtr, const Address &zta, SharedPtr< Peer > &p
|
|||
}
|
||||
}
|
||||
|
||||
SharedPtr< Peer > Topology::m_peerFromCached(void *tPtr, const Address &zta)
|
||||
SharedPtr< Peer > Topology::m_peerFromCached(CallContext &cc, const Address &zta)
|
||||
{
|
||||
SharedPtr< Peer > p;
|
||||
m_loadCached(tPtr, zta, p);
|
||||
m_loadCached(cc, zta, p);
|
||||
if (p) {
|
||||
RWMutex::Lock l(m_peers_l);
|
||||
SharedPtr< Peer > &hp = m_peers[zta];
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "Certificate.hpp"
|
||||
#include "Containers.hpp"
|
||||
#include "Spinlock.hpp"
|
||||
#include "CallContext.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -39,7 +40,7 @@ class RuntimeEnvironment;
|
|||
class Topology
|
||||
{
|
||||
public:
|
||||
Topology(const RuntimeEnvironment *renv, void *tPtr, int64_t now);
|
||||
Topology(const RuntimeEnvironment *renv, CallContext &cc);
|
||||
|
||||
/**
|
||||
* Add peer to database
|
||||
|
@ -47,21 +48,19 @@ public:
|
|||
* This will not replace existing peers. In that case the existing peer
|
||||
* record is returned.
|
||||
*
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param peer Peer to add
|
||||
* @return New or existing peer (should replace 'peer')
|
||||
*/
|
||||
SharedPtr< Peer > add(void *tPtr, const SharedPtr< Peer > &peer);
|
||||
SharedPtr< Peer > add(CallContext &cc, const SharedPtr< Peer > &peer);
|
||||
|
||||
/**
|
||||
* Get a peer from its address
|
||||
*
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param zta ZeroTier address of peer
|
||||
* @param loadFromCached If false do not load from cache if not in memory (default: true)
|
||||
* @return Peer or NULL if not found
|
||||
*/
|
||||
ZT_INLINE SharedPtr< Peer > peer(void *tPtr, const Address &zta, const bool loadFromCached = true)
|
||||
ZT_INLINE SharedPtr< Peer > peer(CallContext &cc, const Address &zta, const bool loadFromCached = true)
|
||||
{
|
||||
{
|
||||
RWMutex::RLock l(m_peers_l);
|
||||
|
@ -70,7 +69,7 @@ public:
|
|||
return ap->second;
|
||||
}
|
||||
if (loadFromCached)
|
||||
return m_peerFromCached(tPtr, zta);
|
||||
return m_peerFromCached(cc, zta);
|
||||
return SharedPtr< Peer >();
|
||||
}
|
||||
|
||||
|
@ -125,34 +124,34 @@ public:
|
|||
|
||||
/**
|
||||
* Do periodic tasks such as database cleanup, cert cleanup, root ranking, etc.
|
||||
*
|
||||
* @param tPtr Thread pointer
|
||||
* @param now Current time
|
||||
*/
|
||||
void doPeriodicTasks(void *tPtr, int64_t now);
|
||||
void doPeriodicTasks(CallContext &cc);
|
||||
|
||||
/**
|
||||
* Rank root servers in descending order of quality
|
||||
*
|
||||
* @param now Current time
|
||||
*/
|
||||
ZT_INLINE void rankRoots(int64_t now)
|
||||
ZT_INLINE void rankRoots(CallContext &cc)
|
||||
{
|
||||
Mutex::Lock l(m_roots_l);
|
||||
m_rankRoots(now);
|
||||
m_rankRoots();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all currently known peers to data store
|
||||
*
|
||||
* @param tPtr Thread pointer
|
||||
* Perform internal updates based on changes in the trust store
|
||||
*/
|
||||
void saveAll(void *tPtr);
|
||||
void trustStoreChanged(CallContext &cc);
|
||||
|
||||
/**
|
||||
* Save all currently known peers to data store
|
||||
*/
|
||||
void saveAll(CallContext &cc);
|
||||
|
||||
private:
|
||||
void m_rankRoots(int64_t now);
|
||||
void m_loadCached(void *tPtr, const Address &zta, SharedPtr< Peer > &peer);
|
||||
SharedPtr< Peer > m_peerFromCached(void *tPtr, const Address &zta);
|
||||
void m_rankRoots();
|
||||
void m_loadCached(CallContext &cc, const Address &zta, SharedPtr< Peer > &peer);
|
||||
SharedPtr< Peer > m_peerFromCached(CallContext &cc, const Address &zta);
|
||||
SharedPtr< Path > m_newPath(int64_t l, const InetAddress &r, const Path::Key &k);
|
||||
|
||||
const RuntimeEnvironment *const RR;
|
||||
|
|
130
core/Trace.cpp
130
core/Trace.cpp
|
@ -29,7 +29,7 @@ Trace::Trace(const RuntimeEnvironment *renv) :
|
|||
}
|
||||
|
||||
void Trace::unexpectedError(
|
||||
void *tPtr,
|
||||
CallContext &cc,
|
||||
uint32_t codeLocation,
|
||||
const char *message,
|
||||
...)
|
||||
|
@ -39,17 +39,17 @@ void Trace::unexpectedError(
|
|||
Dictionary::append(buf, ZT_TRACE_FIELD_CODE_LOCATION, codeLocation);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_MESSAGE, message);
|
||||
buf.push_back(0);
|
||||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
RR->node->postEvent(cc.tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
}
|
||||
|
||||
void Trace::_resettingPathsInScope(
|
||||
void *const tPtr,
|
||||
const uint32_t codeLocation,
|
||||
void Trace::m_resettingPathsInScope(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
const Identity &reporter,
|
||||
const InetAddress &from,
|
||||
const InetAddress &oldExternal,
|
||||
const InetAddress &newExternal,
|
||||
const InetAddress::IpScope scope)
|
||||
ZT_InetAddress_IpScope scope)
|
||||
{
|
||||
FCV< uint8_t, 4096 > buf;
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL1_RESETTING_PATHS_IN_SCOPE);
|
||||
|
@ -67,14 +67,14 @@ void Trace::_resettingPathsInScope(
|
|||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
}
|
||||
|
||||
void Trace::_tryingNewPath(
|
||||
void *const tPtr,
|
||||
const uint32_t codeLocation,
|
||||
void Trace::m_tryingNewPath(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
const Identity &trying,
|
||||
const InetAddress &physicalAddress,
|
||||
const InetAddress &triggerAddress,
|
||||
const uint64_t triggeringPacketId,
|
||||
const uint8_t triggeringPacketVerb,
|
||||
uint64_t triggeringPacketId,
|
||||
uint8_t triggeringPacketVerb,
|
||||
const Identity &triggeringPeer)
|
||||
{
|
||||
if ((trying)&&(physicalAddress)) {
|
||||
|
@ -94,10 +94,10 @@ void Trace::_tryingNewPath(
|
|||
}
|
||||
}
|
||||
|
||||
void Trace::_learnedNewPath(
|
||||
void *const tPtr,
|
||||
const uint32_t codeLocation,
|
||||
const uint64_t packetId,
|
||||
void Trace::m_learnedNewPath(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
uint64_t packetId,
|
||||
const Identity &peerIdentity,
|
||||
const InetAddress &physicalAddress,
|
||||
const InetAddress &replaced)
|
||||
|
@ -117,16 +117,16 @@ void Trace::_learnedNewPath(
|
|||
}
|
||||
}
|
||||
|
||||
void Trace::_incomingPacketDropped(
|
||||
void *const tPtr,
|
||||
const uint32_t codeLocation,
|
||||
const uint64_t packetId,
|
||||
const uint64_t networkId,
|
||||
void Trace::m_incomingPacketDropped(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
uint64_t packetId,
|
||||
uint64_t networkId,
|
||||
const Identity &peerIdentity,
|
||||
const InetAddress &physicalAddress,
|
||||
const uint8_t hops,
|
||||
const uint8_t verb,
|
||||
const ZT_TracePacketDropReason reason)
|
||||
uint8_t hops,
|
||||
uint8_t verb,
|
||||
ZT_TracePacketDropReason reason)
|
||||
{
|
||||
FCV< uint8_t, 4096 > buf;
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL1_INCOMING_PACKET_DROPPED);
|
||||
|
@ -144,16 +144,16 @@ void Trace::_incomingPacketDropped(
|
|||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
}
|
||||
|
||||
void Trace::_outgoingNetworkFrameDropped(
|
||||
void *const tPtr,
|
||||
const uint32_t codeLocation,
|
||||
const uint64_t networkId,
|
||||
void Trace::m_outgoingNetworkFrameDropped(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
uint64_t networkId,
|
||||
const MAC &sourceMac,
|
||||
const MAC &destMac,
|
||||
const uint16_t etherType,
|
||||
const uint16_t frameLength,
|
||||
uint16_t etherType,
|
||||
uint16_t frameLength,
|
||||
const uint8_t *frameData,
|
||||
const ZT_TraceFrameDropReason reason)
|
||||
ZT_TraceFrameDropReason reason)
|
||||
{
|
||||
FCV< uint8_t, 4096 > buf;
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL1_INCOMING_PACKET_DROPPED);
|
||||
|
@ -170,21 +170,21 @@ void Trace::_outgoingNetworkFrameDropped(
|
|||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
}
|
||||
|
||||
void Trace::_incomingNetworkFrameDropped(
|
||||
void *const tPtr,
|
||||
const uint32_t codeLocation,
|
||||
const uint64_t networkId,
|
||||
void Trace::m_incomingNetworkFrameDropped(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
uint64_t networkId,
|
||||
const MAC &sourceMac,
|
||||
const MAC &destMac,
|
||||
const uint16_t etherType,
|
||||
const Identity &peerIdentity,
|
||||
const InetAddress &physicalAddress,
|
||||
const uint8_t hops,
|
||||
const uint16_t frameLength,
|
||||
uint8_t hops,
|
||||
uint16_t frameLength,
|
||||
const uint8_t *frameData,
|
||||
const uint8_t verb,
|
||||
const bool credentialRequestSent,
|
||||
const ZT_TraceFrameDropReason reason)
|
||||
uint8_t verb,
|
||||
bool credentialRequestSent,
|
||||
ZT_TraceFrameDropReason reason)
|
||||
{
|
||||
FCV< uint8_t, 4096 > buf;
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL2_INCOMING_FRAME_DROPPED);
|
||||
|
@ -207,10 +207,10 @@ void Trace::_incomingNetworkFrameDropped(
|
|||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
}
|
||||
|
||||
void Trace::_networkConfigRequestSent(
|
||||
void *const tPtr,
|
||||
const uint32_t codeLocation,
|
||||
const uint64_t networkId)
|
||||
void Trace::m_networkConfigRequestSent(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
uint64_t networkId)
|
||||
{
|
||||
FCV< uint8_t, 4096 > buf;
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL2_NETWORK_CONFIG_REQUESTED);
|
||||
|
@ -220,25 +220,25 @@ void Trace::_networkConfigRequestSent(
|
|||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
}
|
||||
|
||||
void Trace::_networkFilter(
|
||||
void *const tPtr,
|
||||
const uint32_t codeLocation,
|
||||
const uint64_t networkId,
|
||||
const uint8_t primaryRuleSetLog[512],
|
||||
const uint8_t matchingCapabilityRuleSetLog[512],
|
||||
const uint32_t matchingCapabilityId,
|
||||
const int64_t matchingCapabilityTimestamp,
|
||||
void Trace::m_networkFilter(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
uint64_t networkId,
|
||||
const uint8_t *primaryRuleSetLog,
|
||||
const uint8_t *matchingCapabilityRuleSetLog,
|
||||
uint32_t matchingCapabilityId,
|
||||
int64_t matchingCapabilityTimestamp,
|
||||
const Address &source,
|
||||
const Address &dest,
|
||||
const MAC &sourceMac,
|
||||
const MAC &destMac,
|
||||
const uint16_t frameLength,
|
||||
uint16_t frameLength,
|
||||
const uint8_t *frameData,
|
||||
const uint16_t etherType,
|
||||
const uint16_t vlanId,
|
||||
const bool noTee,
|
||||
const bool inbound,
|
||||
const int accept)
|
||||
uint16_t etherType,
|
||||
uint16_t vlanId,
|
||||
bool noTee,
|
||||
bool inbound,
|
||||
int accept)
|
||||
{
|
||||
FCV< uint8_t, 4096 > buf;
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL2_NETWORK_FILTER);
|
||||
|
@ -266,15 +266,15 @@ void Trace::_networkFilter(
|
|||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
}
|
||||
|
||||
void Trace::_credentialRejected(
|
||||
void *const tPtr,
|
||||
const uint32_t codeLocation,
|
||||
const uint64_t networkId,
|
||||
void Trace::m_credentialRejected(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
uint64_t networkId,
|
||||
const Identity &identity,
|
||||
const uint32_t credentialId,
|
||||
const int64_t credentialTimestamp,
|
||||
const uint8_t credentialType,
|
||||
const ZT_TraceCredentialRejectionReason reason)
|
||||
uint32_t credentialId,
|
||||
int64_t credentialTimestamp,
|
||||
uint8_t credentialType,
|
||||
ZT_TraceCredentialRejectionReason reason)
|
||||
{
|
||||
FCV< uint8_t, 4096 > buf;
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL2_NETWORK_CREDENTIAL_REJECTED);
|
||||
|
|
103
core/Trace.hpp
103
core/Trace.hpp
|
@ -22,6 +22,7 @@
|
|||
#include "MAC.hpp"
|
||||
#include "Containers.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "CallContext.hpp"
|
||||
|
||||
#define ZT_TRACE_F_VL1 0x01U
|
||||
#define ZT_TRACE_F_VL2 0x02U
|
||||
|
@ -31,25 +32,15 @@
|
|||
namespace ZeroTier {
|
||||
|
||||
class RuntimeEnvironment;
|
||||
|
||||
class Identity;
|
||||
|
||||
class Peer;
|
||||
|
||||
class Path;
|
||||
|
||||
class Network;
|
||||
|
||||
class MembershipCredential;
|
||||
|
||||
class OwnershipCredential;
|
||||
|
||||
class RevocationCredential;
|
||||
|
||||
class TagCredential;
|
||||
|
||||
class CapabilityCredential;
|
||||
|
||||
struct NetworkConfig;
|
||||
|
||||
/**
|
||||
|
@ -73,31 +64,25 @@ public:
|
|||
uint8_t l[ZT_MAX_NETWORK_RULES / 2]; // ZT_MAX_NETWORK_RULES 4-bit fields
|
||||
|
||||
ZT_INLINE void log(const unsigned int rn, const uint8_t thisRuleMatches, const uint8_t thisSetMatches) noexcept
|
||||
{
|
||||
l[rn >> 1U] |= (((thisRuleMatches + 1U) << 2U) | (thisSetMatches + 1U)) << ((rn & 1U) << 2U);
|
||||
}
|
||||
{ l[rn >> 1U] |= (((thisRuleMatches + 1U) << 2U) | (thisSetMatches + 1U)) << ((rn & 1U) << 2U); }
|
||||
|
||||
ZT_INLINE void logSkipped(const unsigned int rn, const uint8_t thisSetMatches) noexcept
|
||||
{
|
||||
l[rn >> 1U] |= (thisSetMatches + 1U) << ((rn & 1U) << 2U);
|
||||
}
|
||||
{ l[rn >> 1U] |= (thisSetMatches + 1U) << ((rn & 1U) << 2U); }
|
||||
|
||||
ZT_INLINE void clear() noexcept
|
||||
{
|
||||
memoryZero(this);
|
||||
}
|
||||
{ memoryZero(this); }
|
||||
};
|
||||
|
||||
explicit Trace(const RuntimeEnvironment *renv);
|
||||
|
||||
void unexpectedError(
|
||||
void *tPtr,
|
||||
CallContext &cc,
|
||||
uint32_t codeLocation,
|
||||
const char *message,
|
||||
...);
|
||||
|
||||
ZT_INLINE void resettingPathsInScope(
|
||||
void *const tPtr,
|
||||
CallContext &cc,
|
||||
const uint32_t codeLocation,
|
||||
const Identity &reporter,
|
||||
const InetAddress &from,
|
||||
|
@ -105,12 +90,12 @@ public:
|
|||
const InetAddress &newExternal,
|
||||
const InetAddress::IpScope scope)
|
||||
{
|
||||
if ((m_traceFlags & ZT_TRACE_F_VL1) != 0)
|
||||
_resettingPathsInScope(tPtr, codeLocation, reporter, from, oldExternal, newExternal, scope);
|
||||
if (unlikely((m_traceFlags & ZT_TRACE_F_VL1) != 0))
|
||||
m_resettingPathsInScope(cc.tPtr, codeLocation, reporter, from, oldExternal, newExternal, scope);
|
||||
}
|
||||
|
||||
ZT_INLINE void tryingNewPath(
|
||||
void *const tPtr,
|
||||
CallContext &cc,
|
||||
const uint32_t codeLocation,
|
||||
const Identity &trying,
|
||||
const InetAddress &physicalAddress,
|
||||
|
@ -119,24 +104,24 @@ public:
|
|||
uint8_t triggeringPacketVerb,
|
||||
const Identity &triggeringPeer)
|
||||
{
|
||||
if ((m_traceFlags & ZT_TRACE_F_VL1) != 0)
|
||||
_tryingNewPath(tPtr, codeLocation, trying, physicalAddress, triggerAddress, triggeringPacketId, triggeringPacketVerb, triggeringPeer);
|
||||
if (unlikely((m_traceFlags & ZT_TRACE_F_VL1) != 0))
|
||||
m_tryingNewPath(cc.tPtr, codeLocation, trying, physicalAddress, triggerAddress, triggeringPacketId, triggeringPacketVerb, triggeringPeer);
|
||||
}
|
||||
|
||||
ZT_INLINE void learnedNewPath(
|
||||
void *const tPtr,
|
||||
CallContext &cc,
|
||||
const uint32_t codeLocation,
|
||||
uint64_t packetId,
|
||||
const Identity &peerIdentity,
|
||||
const InetAddress &physicalAddress,
|
||||
const InetAddress &replaced)
|
||||
{
|
||||
if ((m_traceFlags & ZT_TRACE_F_VL1) != 0)
|
||||
_learnedNewPath(tPtr, codeLocation, packetId, peerIdentity, physicalAddress, replaced);
|
||||
if (unlikely((m_traceFlags & ZT_TRACE_F_VL1) != 0))
|
||||
m_learnedNewPath(cc.tPtr, codeLocation, packetId, peerIdentity, physicalAddress, replaced);
|
||||
}
|
||||
|
||||
ZT_INLINE void incomingPacketDropped(
|
||||
void *const tPtr,
|
||||
CallContext &cc,
|
||||
const uint32_t codeLocation,
|
||||
uint64_t packetId,
|
||||
uint64_t networkId,
|
||||
|
@ -146,12 +131,12 @@ public:
|
|||
uint8_t verb,
|
||||
const ZT_TracePacketDropReason reason)
|
||||
{
|
||||
if ((m_traceFlags & ZT_TRACE_F_VL1) != 0)
|
||||
_incomingPacketDropped(tPtr, codeLocation, packetId, networkId, peerIdentity, physicalAddress, hops, verb, reason);
|
||||
if (unlikely((m_traceFlags & ZT_TRACE_F_VL1) != 0))
|
||||
m_incomingPacketDropped(cc.tPtr, codeLocation, packetId, networkId, peerIdentity, physicalAddress, hops, verb, reason);
|
||||
}
|
||||
|
||||
ZT_INLINE void outgoingNetworkFrameDropped(
|
||||
void *const tPtr,
|
||||
CallContext &cc,
|
||||
const uint32_t codeLocation,
|
||||
uint64_t networkId,
|
||||
const MAC &sourceMac,
|
||||
|
@ -161,12 +146,12 @@ public:
|
|||
const uint8_t *frameData,
|
||||
ZT_TraceFrameDropReason reason)
|
||||
{
|
||||
if ((m_traceFlags & ZT_TRACE_F_VL2) != 0)
|
||||
_outgoingNetworkFrameDropped(tPtr, codeLocation, networkId, sourceMac, destMac, etherType, frameLength, frameData, reason);
|
||||
if (unlikely((m_traceFlags & ZT_TRACE_F_VL2) != 0))
|
||||
m_outgoingNetworkFrameDropped(cc.tPtr, codeLocation, networkId, sourceMac, destMac, etherType, frameLength, frameData, reason);
|
||||
}
|
||||
|
||||
ZT_INLINE void incomingNetworkFrameDropped(
|
||||
void *const tPtr,
|
||||
CallContext &cc,
|
||||
const uint32_t codeLocation,
|
||||
uint64_t networkId,
|
||||
const MAC &sourceMac,
|
||||
|
@ -181,21 +166,21 @@ public:
|
|||
bool credentialRequestSent,
|
||||
ZT_TraceFrameDropReason reason)
|
||||
{
|
||||
if ((m_traceFlags & ZT_TRACE_F_VL2) != 0)
|
||||
_incomingNetworkFrameDropped(tPtr, codeLocation, networkId, sourceMac, destMac, etherType, peerIdentity, physicalAddress, hops, frameLength, frameData, verb, credentialRequestSent, reason);
|
||||
if (unlikely((m_traceFlags & ZT_TRACE_F_VL2) != 0))
|
||||
m_incomingNetworkFrameDropped(cc.tPtr, codeLocation, networkId, sourceMac, destMac, etherType, peerIdentity, physicalAddress, hops, frameLength, frameData, verb, credentialRequestSent, reason);
|
||||
}
|
||||
|
||||
ZT_INLINE void networkConfigRequestSent(
|
||||
void *const tPtr,
|
||||
CallContext &cc,
|
||||
const uint32_t codeLocation,
|
||||
uint64_t networkId)
|
||||
{
|
||||
if ((m_traceFlags & ZT_TRACE_F_VL2) != 0)
|
||||
_networkConfigRequestSent(tPtr, codeLocation, networkId);
|
||||
if (unlikely((m_traceFlags & ZT_TRACE_F_VL2) != 0))
|
||||
m_networkConfigRequestSent(cc.tPtr, codeLocation, networkId);
|
||||
}
|
||||
|
||||
ZT_INLINE void networkFilter(
|
||||
void *const tPtr,
|
||||
CallContext &cc,
|
||||
const uint32_t codeLocation,
|
||||
uint64_t networkId,
|
||||
const uint8_t primaryRuleSetLog[512],
|
||||
|
@ -214,9 +199,9 @@ public:
|
|||
bool inbound,
|
||||
int accept)
|
||||
{
|
||||
if ((m_traceFlags & ZT_TRACE_F_VL2_FILTER) != 0) {
|
||||
_networkFilter(
|
||||
tPtr,
|
||||
if (unlikely((m_traceFlags & ZT_TRACE_F_VL2_FILTER) != 0)) {
|
||||
m_networkFilter(
|
||||
cc.tPtr,
|
||||
codeLocation,
|
||||
networkId,
|
||||
primaryRuleSetLog,
|
||||
|
@ -238,7 +223,7 @@ public:
|
|||
}
|
||||
|
||||
ZT_INLINE void credentialRejected(
|
||||
void *const tPtr,
|
||||
CallContext &cc,
|
||||
const uint32_t codeLocation,
|
||||
uint64_t networkId,
|
||||
const Identity &identity,
|
||||
|
@ -247,12 +232,12 @@ public:
|
|||
uint8_t credentialType,
|
||||
ZT_TraceCredentialRejectionReason reason)
|
||||
{
|
||||
if ((m_traceFlags & ZT_TRACE_F_VL2) != 0)
|
||||
_credentialRejected(tPtr, codeLocation, networkId, identity, credentialId, credentialTimestamp, credentialType, reason);
|
||||
if (unlikely((m_traceFlags & ZT_TRACE_F_VL2) != 0))
|
||||
m_credentialRejected(cc.tPtr, codeLocation, networkId, identity, credentialId, credentialTimestamp, credentialType, reason);
|
||||
}
|
||||
|
||||
private:
|
||||
void _resettingPathsInScope(
|
||||
void m_resettingPathsInScope(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
const Identity &reporter,
|
||||
|
@ -261,7 +246,7 @@ private:
|
|||
const InetAddress &newExternal,
|
||||
InetAddress::IpScope scope);
|
||||
|
||||
void _tryingNewPath(
|
||||
void m_tryingNewPath(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
const Identity &trying,
|
||||
|
@ -271,7 +256,7 @@ private:
|
|||
uint8_t triggeringPacketVerb,
|
||||
const Identity &triggeringPeer);
|
||||
|
||||
void _learnedNewPath(
|
||||
void m_learnedNewPath(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
uint64_t packetId,
|
||||
|
@ -279,7 +264,7 @@ private:
|
|||
const InetAddress &physicalAddress,
|
||||
const InetAddress &replaced);
|
||||
|
||||
void _incomingPacketDropped(
|
||||
void m_incomingPacketDropped(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
uint64_t packetId,
|
||||
|
@ -290,7 +275,7 @@ private:
|
|||
uint8_t verb,
|
||||
ZT_TracePacketDropReason reason);
|
||||
|
||||
void _outgoingNetworkFrameDropped(
|
||||
void m_outgoingNetworkFrameDropped(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
uint64_t networkId,
|
||||
|
@ -301,7 +286,7 @@ private:
|
|||
const uint8_t *frameData,
|
||||
ZT_TraceFrameDropReason reason);
|
||||
|
||||
void _incomingNetworkFrameDropped(
|
||||
void m_incomingNetworkFrameDropped(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
uint64_t networkId,
|
||||
|
@ -317,17 +302,17 @@ private:
|
|||
bool credentialRequestSent,
|
||||
ZT_TraceFrameDropReason reason);
|
||||
|
||||
void _networkConfigRequestSent(
|
||||
void m_networkConfigRequestSent(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
uint64_t networkId);
|
||||
|
||||
void _networkFilter(
|
||||
void m_networkFilter(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
uint64_t networkId,
|
||||
const uint8_t primaryRuleSetLog[512],
|
||||
const uint8_t matchingCapabilityRuleSetLog[512],
|
||||
const uint8_t *primaryRuleSetLog,
|
||||
const uint8_t *matchingCapabilityRuleSetLog,
|
||||
uint32_t matchingCapabilityId,
|
||||
int64_t matchingCapabilityTimestamp,
|
||||
const Address &source,
|
||||
|
@ -342,7 +327,7 @@ private:
|
|||
bool inbound,
|
||||
int accept);
|
||||
|
||||
void _credentialRejected(
|
||||
void m_credentialRejected(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
uint64_t networkId,
|
||||
|
|
|
@ -41,7 +41,7 @@ Map< Identity, SharedPtr< const Locator > > TrustStore::roots()
|
|||
if (likely((id != nullptr) && (*id))) { // sanity check
|
||||
SharedPtr< const Locator > &existingLoc = r[*id];
|
||||
const Locator *const loc = reinterpret_cast<const Locator *>((*c)->certificate().subject.identities[j].locator);
|
||||
if ((loc != nullptr) && ((!existingLoc) || (existingLoc->timestamp() < loc->timestamp())))
|
||||
if ((loc != nullptr) && ((!existingLoc) || (existingLoc->revision() < loc->revision())))
|
||||
existingLoc.set(new Locator(*loc));
|
||||
}
|
||||
}
|
||||
|
@ -63,17 +63,6 @@ Vector< SharedPtr< TrustStore::Entry > > TrustStore::all(const bool includeRejec
|
|||
return r;
|
||||
}
|
||||
|
||||
Vector< SharedPtr< TrustStore::Entry > > TrustStore::rejects() const
|
||||
{
|
||||
RWMutex::RLock l(m_lock);
|
||||
Vector< SharedPtr< Entry > > r;
|
||||
for (Map< H384, SharedPtr< Entry > >::const_iterator c(m_bySerial.begin()); c != m_bySerial.end(); ++c) {
|
||||
if (c->second->error() != ZT_CERTIFICATE_ERROR_NONE)
|
||||
r.push_back(c->second);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void TrustStore::add(const Certificate &cert, const unsigned int localTrust)
|
||||
{
|
||||
RWMutex::Lock l(m_lock);
|
||||
|
@ -105,7 +94,7 @@ static bool p_validatePath(const Map< H384, Vector< SharedPtr< TrustStore::Entry
|
|||
return false;
|
||||
}
|
||||
|
||||
void TrustStore::update(const int64_t clock, Vector< SharedPtr< Entry > > *const purge)
|
||||
bool TrustStore::update(const int64_t clock, Vector< SharedPtr< Entry > > *const purge)
|
||||
{
|
||||
RWMutex::Lock l(m_lock);
|
||||
|
||||
|
@ -113,15 +102,21 @@ void TrustStore::update(const int64_t clock, Vector< SharedPtr< Entry > > *const
|
|||
// signature check here since that's done when they're taken out of the add queue.
|
||||
bool errorStateModified = false;
|
||||
for (Map< H384, SharedPtr< Entry > >::const_iterator c(m_bySerial.begin()); c != m_bySerial.end(); ++c) {
|
||||
const ZT_CertificateError err = c->second->m_certificate.verify(clock, false);
|
||||
errorStateModified |= (c->second->m_error.exchange((int)err, std::memory_order_relaxed) != (int)err);
|
||||
const ZT_CertificateError err = c->second->error();
|
||||
if ((err != ZT_CERTIFICATE_ERROR_HAVE_NEWER_CERT) && (err != ZT_CERTIFICATE_ERROR_INVALID_CHAIN)) {
|
||||
const ZT_CertificateError newErr = c->second->m_certificate.verify(clock, false);
|
||||
if (newErr != err) {
|
||||
c->second->m_error.store((int)newErr, std::memory_order_relaxed);
|
||||
errorStateModified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no certificate error statuses changed and there are no new certificates to
|
||||
// add, there is nothing to do and we don't need to do more expensive path validation
|
||||
// and structure rebuilding.
|
||||
if ((!errorStateModified) && (m_addQueue.empty()) && (m_deleteQueue.empty()))
|
||||
return;
|
||||
return false;
|
||||
|
||||
// Add new certificates to m_bySerial, which is the master certificate set. They still
|
||||
// have yet to have their full certificate chains validated. Full signature checking is
|
||||
|
@ -164,8 +159,8 @@ void TrustStore::update(const int64_t clock, Vector< SharedPtr< Entry > > *const
|
|||
for (Map< H384, SharedPtr< Entry > >::const_iterator c(m_bySerial.begin()); c != m_bySerial.end();) {
|
||||
if (c->second->error() == ZT_CERTIFICATE_ERROR_NONE) {
|
||||
const unsigned int uniqueIdSize = c->second->m_certificate.subject.uniqueIdSize;
|
||||
if ((uniqueIdSize > 0) && (uniqueIdSize <= 1024)) { // 1024 is a sanity check value, actual unique IDs are <100 bytes
|
||||
SharedPtr< Entry > ¤t = m_bySubjectUniqueId[Vector< uint8_t >(c->second->m_certificate.subject.uniqueId, c->second->m_certificate.subject.uniqueId + uniqueIdSize)];
|
||||
if ((uniqueIdSize > 0) && (uniqueIdSize <= ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_SIZE)) {
|
||||
SharedPtr< Entry > ¤t = m_bySubjectUniqueId[Blob< ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_SIZE >(c->second->m_certificate.subject.uniqueId, uniqueIdSize)];
|
||||
if (current) {
|
||||
exitLoop = false;
|
||||
if (c->second->m_certificate.subject.timestamp > current->m_certificate.subject.timestamp) {
|
||||
|
@ -222,6 +217,8 @@ void TrustStore::update(const int64_t clock, Vector< SharedPtr< Entry > > *const
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Vector< uint8_t > TrustStore::save() const
|
||||
|
|
|
@ -124,13 +124,6 @@ public:
|
|||
*/
|
||||
Vector< SharedPtr< Entry > > all(bool includeRejectedCertificates) const;
|
||||
|
||||
/**
|
||||
* Get a copy of the current rejected certificate set.
|
||||
*
|
||||
* @return Rejected certificates
|
||||
*/
|
||||
Vector< SharedPtr< Entry > > rejects() const;
|
||||
|
||||
/**
|
||||
* Add a certificate
|
||||
*
|
||||
|
@ -161,8 +154,9 @@ public:
|
|||
*
|
||||
* @param clock Current time in milliseconds since epoch, or -1 to not check times on this pass
|
||||
* @param purge If non-NULL, purge rejected certificates and return them in this vector (vector should be empty)
|
||||
* @return True if there were changes
|
||||
*/
|
||||
void update(int64_t clock, Vector< SharedPtr< Entry > > *purge);
|
||||
bool update(int64_t clock, Vector< SharedPtr< Entry > > *purge);
|
||||
|
||||
/**
|
||||
* Create a compressed binary version of certificates and their local trust
|
||||
|
@ -184,7 +178,7 @@ public:
|
|||
|
||||
private:
|
||||
Map< H384, SharedPtr< Entry > > m_bySerial; // all certificates
|
||||
Map< Vector< uint8_t >, SharedPtr< Entry > > m_bySubjectUniqueId; // non-rejected certificates only
|
||||
Map< Blob< ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_SIZE >, SharedPtr< Entry > > m_bySubjectUniqueId; // non-rejected certificates only
|
||||
Map< Fingerprint, Vector< SharedPtr< Entry > > > m_bySubjectIdentity; // non-rejected certificates only
|
||||
ForwardList< SharedPtr< Entry > > m_addQueue;
|
||||
ForwardList< H384 > m_deleteQueue;
|
||||
|
|
|
@ -529,7 +529,7 @@ bool scopy(char *const dest, const unsigned int len, const char *const src) noex
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t fnv1a32(const void *const data, const unsigned int len) noexcept
|
||||
uint32_t fnv1a32(const void *const restrict data, const unsigned int len) noexcept
|
||||
{
|
||||
uint32_t h = 0x811c9dc5;
|
||||
const uint32_t p = 0x01000193;
|
||||
|
|
|
@ -546,7 +546,7 @@ static ZT_INLINE I ntoh(const I n) noexcept
|
|||
* @return Loaded raw integer
|
||||
*/
|
||||
template< typename I >
|
||||
static ZT_INLINE I loadMachineEndian(const void *const p) noexcept
|
||||
static ZT_INLINE I loadMachineEndian(const void *const restrict p) noexcept
|
||||
{
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
I tmp;
|
||||
|
@ -566,7 +566,7 @@ static ZT_INLINE I loadMachineEndian(const void *const p) noexcept
|
|||
* @param i Integer to store
|
||||
*/
|
||||
template< typename I >
|
||||
static ZT_INLINE void storeMachineEndian(void *const p, const I i) noexcept
|
||||
static ZT_INLINE void storeMachineEndian(void *const restrict p, const I i) noexcept
|
||||
{
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
for(unsigned int k=0;k<sizeof(I);++k)
|
||||
|
@ -584,7 +584,7 @@ static ZT_INLINE void storeMachineEndian(void *const p, const I i) noexcept
|
|||
* @return Decoded integer
|
||||
*/
|
||||
template< typename I >
|
||||
static ZT_INLINE I loadBigEndian(const void *const p) noexcept
|
||||
static ZT_INLINE I loadBigEndian(const void *const restrict p) noexcept
|
||||
{
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
return _load_be_bysize<I,sizeof(I)>::l(reinterpret_cast<const uint8_t *>(p));
|
||||
|
@ -601,7 +601,7 @@ static ZT_INLINE I loadBigEndian(const void *const p) noexcept
|
|||
* #param i Integer to write
|
||||
*/
|
||||
template< typename I >
|
||||
static ZT_INLINE void storeBigEndian(void *const p, I i) noexcept
|
||||
static ZT_INLINE void storeBigEndian(void *const restrict p, I i) noexcept
|
||||
{
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
storeMachineEndian(p,hton(i));
|
||||
|
@ -618,7 +618,7 @@ static ZT_INLINE void storeBigEndian(void *const p, I i) noexcept
|
|||
* @return Decoded integer
|
||||
*/
|
||||
template< typename I >
|
||||
static ZT_INLINE I loadLittleEndian(const void *const p) noexcept
|
||||
static ZT_INLINE I loadLittleEndian(const void *const restrict p) noexcept
|
||||
{
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN || defined(ZT_NO_UNALIGNED_ACCESS)
|
||||
return _load_le_bysize<I,sizeof(I)>::l(reinterpret_cast<const uint8_t *>(p));
|
||||
|
@ -635,7 +635,7 @@ static ZT_INLINE I loadLittleEndian(const void *const p) noexcept
|
|||
* #param i Integer to write
|
||||
*/
|
||||
template< typename I >
|
||||
static ZT_INLINE void storeLittleEndian(void *const p, const I i) noexcept
|
||||
static ZT_INLINE void storeLittleEndian(void *const restrict p, const I i) noexcept
|
||||
{
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
storeMachineEndian(p,_swap_bytes_bysize<I,sizeof(I)>::s(i));
|
||||
|
@ -723,7 +723,7 @@ static ZT_INLINE void zero(void *dest, unsigned long len) noexcept
|
|||
* @param len Length of data
|
||||
* @return FNV1a checksum
|
||||
*/
|
||||
uint32_t fnv1a32(const void *data, unsigned int len) noexcept;
|
||||
uint32_t fnv1a32(const void *restrict data, unsigned int len) noexcept;
|
||||
|
||||
/**
|
||||
* Mix bits in a 64-bit integer (non-cryptographic, for hash tables)
|
||||
|
|
144
core/VL1.cpp
144
core/VL1.cpp
|
@ -99,13 +99,12 @@ VL1::VL1(const RuntimeEnvironment *renv) :
|
|||
RR(renv)
|
||||
{}
|
||||
|
||||
void VL1::onRemotePacket(void *const tPtr, const int64_t localSocket, const InetAddress &fromAddr, SharedPtr< Buf > &data, const unsigned int len) noexcept
|
||||
void VL1::onRemotePacket(CallContext &cc, const int64_t localSocket, const InetAddress &fromAddr, SharedPtr< Buf > &data, const unsigned int len) noexcept
|
||||
{
|
||||
const SharedPtr< Path > path(RR->topology->path(localSocket, fromAddr));
|
||||
const int64_t now = RR->node->now();
|
||||
|
||||
ZT_SPEW("%u bytes from %s (local socket %lld)", len, fromAddr.toString().c_str(), localSocket);
|
||||
path->received(now, len);
|
||||
path->received(cc, len);
|
||||
|
||||
// NOTE: likely/unlikely are used here to highlight the most common code path
|
||||
// for valid data packets. This may allow the compiler to generate very slightly
|
||||
|
@ -121,7 +120,7 @@ void VL1::onRemotePacket(void *const tPtr, const int64_t localSocket, const Inet
|
|||
static_assert((ZT_PROTO_PACKET_DESTINATION_INDEX + ZT_ADDRESS_LENGTH) < ZT_PROTO_MIN_FRAGMENT_LENGTH, "overflow");
|
||||
const Address destination(data->unsafeData + ZT_PROTO_PACKET_DESTINATION_INDEX);
|
||||
if (destination != RR->identity.address()) {
|
||||
m_relay(tPtr, path, destination, data, len);
|
||||
m_relay(cc, path, destination, data, len);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -145,7 +144,7 @@ void VL1::onRemotePacket(void *const tPtr, const int64_t localSocket, const Inet
|
|||
len - ZT_PROTO_PACKET_FRAGMENT_PAYLOAD_START_AT,
|
||||
fragmentNo,
|
||||
totalFragments,
|
||||
now,
|
||||
cc.ticks,
|
||||
path)) {
|
||||
case Defragmenter< ZT_MAX_PACKET_FRAGMENTS >::COMPLETE:
|
||||
break;
|
||||
|
@ -171,7 +170,7 @@ void VL1::onRemotePacket(void *const tPtr, const int64_t localSocket, const Inet
|
|||
len,
|
||||
0, // always the zero'eth fragment
|
||||
0, // this is specified in fragments, not in the head
|
||||
now,
|
||||
cc.ticks,
|
||||
path)) {
|
||||
case Defragmenter< ZT_MAX_PACKET_FRAGMENTS >::COMPLETE:
|
||||
break;
|
||||
|
@ -214,9 +213,9 @@ void VL1::onRemotePacket(void *const tPtr, const int64_t localSocket, const Inet
|
|||
ZT_SPEW("discarding packet %.16llx from %s(%s): assembled packet size: %d", packetId, source.toString().c_str(), fromAddr.toString().c_str(), pktSize);
|
||||
return;
|
||||
}
|
||||
const SharedPtr< Peer > peer(m_HELLO(tPtr, path, *pkt, pktSize));
|
||||
const SharedPtr< Peer > peer(m_HELLO(cc, path, *pkt, pktSize));
|
||||
if (likely(peer))
|
||||
peer->received(tPtr, path, hops, packetId, pktSize - ZT_PROTO_PACKET_PAYLOAD_START, Protocol::VERB_HELLO, Protocol::VERB_NOP);
|
||||
peer->received(cc, path, hops, packetId, pktSize - ZT_PROTO_PACKET_PAYLOAD_START, Protocol::VERB_HELLO, Protocol::VERB_NOP);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -225,7 +224,7 @@ void VL1::onRemotePacket(void *const tPtr, const int64_t localSocket, const Inet
|
|||
// secrecy status.
|
||||
unsigned int auth = 0;
|
||||
|
||||
SharedPtr< Peer > peer(RR->topology->peer(tPtr, source));
|
||||
SharedPtr< Peer > peer(RR->topology->peer(cc, source));
|
||||
if (likely(peer)) {
|
||||
switch (cipher) {
|
||||
|
||||
|
@ -245,7 +244,7 @@ void VL1::onRemotePacket(void *const tPtr, const int64_t localSocket, const Inet
|
|||
static_assert((ZT_PROTO_PACKET_MAC_INDEX + 8) < ZT_PROTO_MIN_PACKET_LENGTH, "overflow");
|
||||
if (unlikely(Utils::loadMachineEndian< uint64_t >(hdr + ZT_PROTO_PACKET_MAC_INDEX) != mac[0])) {
|
||||
ZT_SPEW("discarding packet %.16llx from %s(%s): packet MAC failed (none/poly1305)", packetId, source.toString().c_str(), fromAddr.toString().c_str());
|
||||
RR->t->incomingPacketDropped(tPtr, 0xcc89c812, packetId, 0, peer->identity(), path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
RR->t->incomingPacketDropped(cc, 0xcc89c812, packetId, 0, peer->identity(), path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -269,7 +268,7 @@ void VL1::onRemotePacket(void *const tPtr, const int64_t localSocket, const Inet
|
|||
static_assert((ZT_PROTO_PACKET_MAC_INDEX + 8) < ZT_PROTO_MIN_PACKET_LENGTH, "overflow");
|
||||
if (unlikely(Utils::loadMachineEndian< uint64_t >(hdr + ZT_PROTO_PACKET_MAC_INDEX) != mac[0])) {
|
||||
ZT_SPEW("discarding packet %.16llx from %s(%s): packet MAC failed (salsa/poly1305)", packetId, source.toString().c_str(), fromAddr.toString().c_str());
|
||||
RR->t->incomingPacketDropped(tPtr, 0xcc89c812, packetId, 0, peer->identity(), path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
RR->t->incomingPacketDropped(cc, 0xcc89c812, packetId, 0, peer->identity(), path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -288,7 +287,7 @@ void VL1::onRemotePacket(void *const tPtr, const int64_t localSocket, const Inet
|
|||
break;
|
||||
|
||||
default:
|
||||
RR->t->incomingPacketDropped(tPtr, 0x5b001099, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
|
||||
RR->t->incomingPacketDropped(cc, 0x5b001099, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -327,7 +326,7 @@ void VL1::onRemotePacket(void *const tPtr, const int64_t localSocket, const Inet
|
|||
ZT_SPEW("decompressed packet: %d -> %d", pktSize, ZT_PROTO_PACKET_PAYLOAD_START + uncompressedLen);
|
||||
pktSize = ZT_PROTO_PACKET_PAYLOAD_START + uncompressedLen;
|
||||
} else {
|
||||
RR->t->incomingPacketDropped(tPtr, 0xee9e4392, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, verb, ZT_TRACE_PACKET_DROP_REASON_INVALID_COMPRESSED_DATA);
|
||||
RR->t->incomingPacketDropped(cc, 0xee9e4392, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, verb, ZT_TRACE_PACKET_DROP_REASON_INVALID_COMPRESSED_DATA);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -345,66 +344,66 @@ void VL1::onRemotePacket(void *const tPtr, const int64_t localSocket, const Inet
|
|||
case Protocol::VERB_NOP:
|
||||
break;
|
||||
case Protocol::VERB_HELLO:
|
||||
ok = (bool)(m_HELLO(tPtr, path, *pkt, pktSize));
|
||||
ok = (bool)(m_HELLO(cc, path, *pkt, pktSize));
|
||||
break;
|
||||
case Protocol::VERB_ERROR:
|
||||
ok = m_ERROR(tPtr, packetId, auth, path, peer, *pkt, pktSize, inReVerb);
|
||||
ok = m_ERROR(cc, packetId, auth, path, peer, *pkt, pktSize, inReVerb);
|
||||
break;
|
||||
case Protocol::VERB_OK:
|
||||
ok = m_OK(tPtr, packetId, auth, path, peer, *pkt, pktSize, inReVerb);
|
||||
ok = m_OK(cc, packetId, auth, path, peer, *pkt, pktSize, inReVerb);
|
||||
break;
|
||||
case Protocol::VERB_WHOIS:
|
||||
ok = m_WHOIS(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||
ok = m_WHOIS(cc, packetId, auth, path, peer, *pkt, pktSize);
|
||||
break;
|
||||
case Protocol::VERB_RENDEZVOUS:
|
||||
ok = m_RENDEZVOUS(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||
ok = m_RENDEZVOUS(cc, packetId, auth, path, peer, *pkt, pktSize);
|
||||
break;
|
||||
case Protocol::VERB_FRAME:
|
||||
ok = RR->vl2->m_FRAME(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||
ok = RR->vl2->m_FRAME(cc, packetId, auth, path, peer, *pkt, pktSize);
|
||||
break;
|
||||
case Protocol::VERB_EXT_FRAME:
|
||||
ok = RR->vl2->m_EXT_FRAME(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||
ok = RR->vl2->m_EXT_FRAME(cc, packetId, auth, path, peer, *pkt, pktSize);
|
||||
break;
|
||||
case Protocol::VERB_ECHO:
|
||||
ok = m_ECHO(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||
ok = m_ECHO(cc, packetId, auth, path, peer, *pkt, pktSize);
|
||||
break;
|
||||
case Protocol::VERB_MULTICAST_LIKE:
|
||||
ok = RR->vl2->m_MULTICAST_LIKE(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||
ok = RR->vl2->m_MULTICAST_LIKE(cc, packetId, auth, path, peer, *pkt, pktSize);
|
||||
break;
|
||||
case Protocol::VERB_NETWORK_CREDENTIALS:
|
||||
ok = RR->vl2->m_NETWORK_CREDENTIALS(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||
ok = RR->vl2->m_NETWORK_CREDENTIALS(cc, packetId, auth, path, peer, *pkt, pktSize);
|
||||
break;
|
||||
case Protocol::VERB_NETWORK_CONFIG_REQUEST:
|
||||
ok = RR->vl2->m_NETWORK_CONFIG_REQUEST(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||
ok = RR->vl2->m_NETWORK_CONFIG_REQUEST(cc, packetId, auth, path, peer, *pkt, pktSize);
|
||||
break;
|
||||
case Protocol::VERB_NETWORK_CONFIG:
|
||||
ok = RR->vl2->m_NETWORK_CONFIG(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||
ok = RR->vl2->m_NETWORK_CONFIG(cc, packetId, auth, path, peer, *pkt, pktSize);
|
||||
break;
|
||||
case Protocol::VERB_MULTICAST_GATHER:
|
||||
ok = RR->vl2->m_MULTICAST_GATHER(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||
ok = RR->vl2->m_MULTICAST_GATHER(cc, packetId, auth, path, peer, *pkt, pktSize);
|
||||
break;
|
||||
case Protocol::VERB_MULTICAST_FRAME_deprecated:
|
||||
ok = RR->vl2->m_MULTICAST_FRAME_deprecated(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||
ok = RR->vl2->m_MULTICAST_FRAME_deprecated(cc, packetId, auth, path, peer, *pkt, pktSize);
|
||||
break;
|
||||
case Protocol::VERB_PUSH_DIRECT_PATHS:
|
||||
ok = m_PUSH_DIRECT_PATHS(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||
ok = m_PUSH_DIRECT_PATHS(cc, packetId, auth, path, peer, *pkt, pktSize);
|
||||
break;
|
||||
case Protocol::VERB_USER_MESSAGE:
|
||||
ok = m_USER_MESSAGE(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||
ok = m_USER_MESSAGE(cc, packetId, auth, path, peer, *pkt, pktSize);
|
||||
break;
|
||||
case Protocol::VERB_MULTICAST:
|
||||
ok = RR->vl2->m_MULTICAST(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||
ok = RR->vl2->m_MULTICAST(cc, packetId, auth, path, peer, *pkt, pktSize);
|
||||
break;
|
||||
case Protocol::VERB_ENCAP:
|
||||
ok = m_ENCAP(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||
ok = m_ENCAP(cc, packetId, auth, path, peer, *pkt, pktSize);
|
||||
break;
|
||||
|
||||
default:
|
||||
RR->t->incomingPacketDropped(tPtr, 0xeeeeeff0, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, verb, ZT_TRACE_PACKET_DROP_REASON_UNRECOGNIZED_VERB);
|
||||
RR->t->incomingPacketDropped(cc, 0xeeeeeff0, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, verb, ZT_TRACE_PACKET_DROP_REASON_UNRECOGNIZED_VERB);
|
||||
break;
|
||||
}
|
||||
if (likely(ok))
|
||||
peer->received(tPtr, path, hops, packetId, pktSize - ZT_PROTO_PACKET_PAYLOAD_START, verb, inReVerb);
|
||||
peer->received(cc, path, hops, packetId, pktSize - ZT_PROTO_PACKET_PAYLOAD_START, verb, inReVerb);
|
||||
} else {
|
||||
// If decryption and authentication were not successful, try to look up identities.
|
||||
// This is rate limited by virtue of the retry rate limit timer.
|
||||
|
@ -419,27 +418,27 @@ void VL1::onRemotePacket(void *const tPtr, const int64_t localSocket, const Inet
|
|||
const unsigned int wpidx = wq.waitingPacketCount++ % ZT_VL1_MAX_WHOIS_WAITING_PACKETS;
|
||||
wq.waitingPacketSize[wpidx] = (unsigned int)pktSize;
|
||||
wq.waitingPacket[wpidx] = pkt;
|
||||
sendPending = (now - wq.lastRetry) >= ZT_WHOIS_RETRY_DELAY;
|
||||
sendPending = (cc.ticks - wq.lastRetry) >= ZT_WHOIS_RETRY_DELAY;
|
||||
}
|
||||
if (sendPending)
|
||||
m_sendPendingWhois(tPtr, now);
|
||||
m_sendPendingWhois(cc);
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
RR->t->unexpectedError(tPtr, 0xea1b6dea, "unexpected exception in onRemotePacket() parsing packet from %s", path->address().toString().c_str());
|
||||
RR->t->unexpectedError(cc, 0xea1b6dea, "unexpected exception in onRemotePacket() parsing packet from %s", path->address().toString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void VL1::m_relay(void *tPtr, const SharedPtr< Path > &path, Address destination, SharedPtr< Buf > &pkt, int pktSize)
|
||||
void VL1::m_relay(CallContext &cc, const SharedPtr< Path > &path, Address destination, SharedPtr< Buf > &pkt, int pktSize)
|
||||
{
|
||||
}
|
||||
|
||||
void VL1::m_sendPendingWhois(void *tPtr, int64_t now)
|
||||
void VL1::m_sendPendingWhois(CallContext &cc)
|
||||
{
|
||||
const SharedPtr< Peer > root(RR->topology->root());
|
||||
if (unlikely(!root))
|
||||
return;
|
||||
const SharedPtr< Path > rootPath(root->path(now));
|
||||
const SharedPtr< Path > rootPath(root->path(cc));
|
||||
if (unlikely(!rootPath))
|
||||
return;
|
||||
|
||||
|
@ -447,8 +446,8 @@ void VL1::m_sendPendingWhois(void *tPtr, int64_t now)
|
|||
{
|
||||
Mutex::Lock wl(m_whoisQueue_l);
|
||||
for (Map< Address, p_WhoisQueueItem >::iterator wi(m_whoisQueue.begin()); wi != m_whoisQueue.end(); ++wi) {
|
||||
if ((now - wi->second.lastRetry) >= ZT_WHOIS_RETRY_DELAY) {
|
||||
wi->second.lastRetry = now;
|
||||
if ((cc.ticks - wi->second.lastRetry) >= ZT_WHOIS_RETRY_DELAY) {
|
||||
wi->second.lastRetry = cc.ticks;
|
||||
++wi->second.retries;
|
||||
toSend.push_back(wi->first);
|
||||
}
|
||||
|
@ -468,13 +467,13 @@ void VL1::m_sendPendingWhois(void *tPtr, int64_t now)
|
|||
p += ZT_ADDRESS_LENGTH;
|
||||
}
|
||||
Protocol::armor(outp, p, key, root->cipher());
|
||||
RR->expect->sending(packetId, now);
|
||||
root->send(tPtr, now, outp, p, rootPath);
|
||||
RR->expect->sending(packetId, cc.ticks);
|
||||
root->send(cc, outp, p, rootPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SharedPtr< Peer > VL1::m_HELLO(void *tPtr, const SharedPtr< Path > &path, Buf &pkt, int packetSize)
|
||||
SharedPtr< Peer > VL1::m_HELLO(CallContext &cc, const SharedPtr< Path > &path, Buf &pkt, int packetSize)
|
||||
{
|
||||
const uint64_t packetId = Utils::loadMachineEndian< uint64_t >(pkt.unsafeData + ZT_PROTO_PACKET_ID_INDEX);
|
||||
const uint64_t mac = Utils::loadMachineEndian< uint64_t >(pkt.unsafeData + ZT_PROTO_PACKET_MAC_INDEX);
|
||||
|
@ -482,7 +481,7 @@ SharedPtr< Peer > VL1::m_HELLO(void *tPtr, const SharedPtr< Path > &path, Buf &p
|
|||
|
||||
const uint8_t protoVersion = pkt.lI8< ZT_PROTO_PACKET_PAYLOAD_START >();
|
||||
if (unlikely(protoVersion < ZT_PROTO_VERSION_MIN)) {
|
||||
RR->t->incomingPacketDropped(tPtr, 0x907a9891, packetId, 0, Identity::NIL, path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_PEER_TOO_OLD);
|
||||
RR->t->incomingPacketDropped(cc, 0x907a9891, packetId, 0, Identity::NIL, path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_PEER_TOO_OLD);
|
||||
return SharedPtr< Peer >();
|
||||
}
|
||||
const unsigned int versionMajor = pkt.lI8< ZT_PROTO_PACKET_PAYLOAD_START + 1 >();
|
||||
|
@ -495,19 +494,19 @@ SharedPtr< Peer > VL1::m_HELLO(void *tPtr, const SharedPtr< Path > &path, Buf &p
|
|||
// Get identity and verify that it matches the sending address in the packet.
|
||||
Identity id;
|
||||
if (unlikely(pkt.rO(ii, id) < 0)) {
|
||||
RR->t->incomingPacketDropped(tPtr, 0x707a9810, packetId, 0, Identity::NIL, path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
|
||||
RR->t->incomingPacketDropped(cc, 0x707a9810, packetId, 0, Identity::NIL, path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
|
||||
return SharedPtr< Peer >();
|
||||
}
|
||||
if (unlikely(id.address() != Address(pkt.unsafeData + ZT_PROTO_PACKET_SOURCE_INDEX))) {
|
||||
RR->t->incomingPacketDropped(tPtr, 0x707a9010, packetId, 0, Identity::NIL, path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
RR->t->incomingPacketDropped(cc, 0x707a9010, packetId, 0, Identity::NIL, path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
return SharedPtr< Peer >();
|
||||
}
|
||||
|
||||
// Get the peer that matches this identity, or learn a new one if we don't know it.
|
||||
SharedPtr< Peer > peer(RR->topology->peer(tPtr, id.address(), true));
|
||||
SharedPtr< Peer > peer(RR->topology->peer(cc, id.address(), true));
|
||||
if (peer) {
|
||||
if (unlikely(peer->identity() != id)) {
|
||||
RR->t->incomingPacketDropped(tPtr, 0x707a9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
RR->t->incomingPacketDropped(cc, 0x707a9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
return SharedPtr< Peer >();
|
||||
}
|
||||
if (unlikely(peer->deduplicateIncomingPacket(packetId))) {
|
||||
|
@ -516,15 +515,15 @@ SharedPtr< Peer > VL1::m_HELLO(void *tPtr, const SharedPtr< Path > &path, Buf &p
|
|||
}
|
||||
} else {
|
||||
if (unlikely(!id.locallyValidate())) {
|
||||
RR->t->incomingPacketDropped(tPtr, 0x707a9892, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
|
||||
RR->t->incomingPacketDropped(cc, 0x707a9892, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
|
||||
return SharedPtr< Peer >();
|
||||
}
|
||||
peer.set(new Peer(RR));
|
||||
if (unlikely(!peer->init(id))) {
|
||||
RR->t->incomingPacketDropped(tPtr, 0x707a9893, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_UNSPECIFIED);
|
||||
if (unlikely(!peer->init(cc, id))) {
|
||||
RR->t->incomingPacketDropped(cc, 0x707a9893, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_UNSPECIFIED);
|
||||
return SharedPtr< Peer >();
|
||||
}
|
||||
peer = RR->topology->add(tPtr, peer);
|
||||
peer = RR->topology->add(cc, peer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -537,7 +536,7 @@ SharedPtr< Peer > VL1::m_HELLO(void *tPtr, const SharedPtr< Path > &path, Buf &p
|
|||
// field is ignored, and eventually it'll be undefined.
|
||||
uint8_t hmac[ZT_HMACSHA384_LEN];
|
||||
if (unlikely(packetSize < ZT_HMACSHA384_LEN)) {
|
||||
RR->t->incomingPacketDropped(tPtr, 0xab9c9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
RR->t->incomingPacketDropped(cc, 0xab9c9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
return SharedPtr< Peer >();
|
||||
}
|
||||
packetSize -= ZT_HMACSHA384_LEN;
|
||||
|
@ -545,7 +544,7 @@ SharedPtr< Peer > VL1::m_HELLO(void *tPtr, const SharedPtr< Path > &path, Buf &p
|
|||
Utils::storeMachineEndian< uint64_t >(pkt.unsafeData + ZT_PROTO_PACKET_MAC_INDEX, 0); // set MAC field to 0
|
||||
HMACSHA384(peer->identityHelloHmacKey(), pkt.unsafeData, packetSize, hmac);
|
||||
if (unlikely(!Utils::secureEq(hmac, pkt.unsafeData + packetSize, ZT_HMACSHA384_LEN))) {
|
||||
RR->t->incomingPacketDropped(tPtr, 0x707a9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
RR->t->incomingPacketDropped(cc, 0x707a9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
return SharedPtr< Peer >();
|
||||
}
|
||||
} else {
|
||||
|
@ -560,11 +559,11 @@ SharedPtr< Peer > VL1::m_HELLO(void *tPtr, const SharedPtr< Path > &path, Buf &p
|
|||
uint64_t polyMac[2];
|
||||
poly1305.finish(polyMac);
|
||||
if (unlikely(mac != polyMac[0])) {
|
||||
RR->t->incomingPacketDropped(tPtr, 0x11bfff82, packetId, 0, id, path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
RR->t->incomingPacketDropped(cc, 0x11bfff82, packetId, 0, id, path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
return SharedPtr< Peer >();
|
||||
}
|
||||
} else {
|
||||
RR->t->incomingPacketDropped(tPtr, 0x11bfff81, packetId, 0, id, path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
RR->t->incomingPacketDropped(cc, 0x11bfff81, packetId, 0, id, path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
return SharedPtr< Peer >();
|
||||
}
|
||||
}
|
||||
|
@ -575,7 +574,7 @@ SharedPtr< Peer > VL1::m_HELLO(void *tPtr, const SharedPtr< Path > &path, Buf &p
|
|||
|
||||
InetAddress sentTo;
|
||||
if (unlikely(pkt.rO(ii, sentTo) < 0)) {
|
||||
RR->t->incomingPacketDropped(tPtr, 0x707a9811, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
|
||||
RR->t->incomingPacketDropped(cc, 0x707a9811, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
|
||||
return SharedPtr< Peer >();
|
||||
}
|
||||
|
||||
|
@ -595,12 +594,12 @@ SharedPtr< Peer > VL1::m_HELLO(void *tPtr, const SharedPtr< Path > &path, Buf &p
|
|||
ii += 2; // skip reserved field
|
||||
const unsigned int dictSize = pkt.rI16(ii);
|
||||
if (unlikely((ii + dictSize) > packetSize)) {
|
||||
RR->t->incomingPacketDropped(tPtr, 0x707a9815, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
|
||||
RR->t->incomingPacketDropped(cc, 0x707a9815, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
|
||||
return peer;
|
||||
}
|
||||
Dictionary md;
|
||||
if (!md.decode(pkt.unsafeData + ii, dictSize)) {
|
||||
RR->t->incomingPacketDropped(tPtr, 0x707a9816, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
|
||||
RR->t->incomingPacketDropped(cc, 0x707a9816, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
|
||||
return peer;
|
||||
}
|
||||
|
||||
|
@ -635,11 +634,11 @@ SharedPtr< Peer > VL1::m_HELLO(void *tPtr, const SharedPtr< Path > &path, Buf &p
|
|||
}
|
||||
|
||||
peer->setRemoteVersion(protoVersion, versionMajor, versionMinor, versionRev);
|
||||
peer->send(tPtr, RR->node->now(), pkt.unsafeData, ii, path);
|
||||
peer->send(cc, pkt.unsafeData, ii, path);
|
||||
return peer;
|
||||
}
|
||||
|
||||
bool VL1::m_ERROR(void *tPtr, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize, Protocol::Verb &inReVerb)
|
||||
bool VL1::m_ERROR(CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize, Protocol::Verb &inReVerb)
|
||||
{
|
||||
#if 0
|
||||
if (packetSize < (int)sizeof(Protocol::ERROR::Header)) {
|
||||
|
@ -686,20 +685,19 @@ bool VL1::m_ERROR(void *tPtr, const uint64_t packetId, const unsigned int auth,
|
|||
#endif
|
||||
}
|
||||
|
||||
bool VL1::m_OK(void *tPtr, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize, Protocol::Verb &inReVerb)
|
||||
bool VL1::m_OK(CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize, Protocol::Verb &inReVerb)
|
||||
{
|
||||
int ii = ZT_PROTO_PACKET_PAYLOAD_START + 13;
|
||||
|
||||
inReVerb = (Protocol::Verb)pkt.rI8(ii);
|
||||
const uint64_t inRePacketId = pkt.rI64(ii);
|
||||
if (unlikely(Buf::readOverflow(ii, packetSize))) {
|
||||
RR->t->incomingPacketDropped(tPtr, 0x4c1f1ff7, packetId, 0, identityFromPeerPtr(peer), path->address(), 0, Protocol::VERB_OK, ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET);
|
||||
RR->t->incomingPacketDropped(cc, 0x4c1f1ff7, packetId, 0, identityFromPeerPtr(peer), path->address(), 0, Protocol::VERB_OK, ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET);
|
||||
return false;
|
||||
}
|
||||
|
||||
const int64_t now = RR->node->now();
|
||||
if (unlikely(!RR->expect->expecting(inRePacketId, now))) {
|
||||
RR->t->incomingPacketDropped(tPtr, 0x4c1f1ff8, packetId, 0, identityFromPeerPtr(peer), path->address(), 0, Protocol::VERB_OK, ZT_TRACE_PACKET_DROP_REASON_REPLY_NOT_EXPECTED);
|
||||
if (unlikely(!RR->expect->expecting(inRePacketId, cc.ticks))) {
|
||||
RR->t->incomingPacketDropped(cc, 0x4c1f1ff8, packetId, 0, identityFromPeerPtr(peer), path->address(), 0, Protocol::VERB_OK, ZT_TRACE_PACKET_DROP_REASON_REPLY_NOT_EXPECTED);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -724,7 +722,7 @@ bool VL1::m_OK(void *tPtr, const uint64_t packetId, const unsigned int auth, con
|
|||
return true;
|
||||
}
|
||||
|
||||
bool VL1::m_WHOIS(void *tPtr, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
bool VL1::m_WHOIS(CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
{
|
||||
#if 0
|
||||
if (packetSize < (int)sizeof(Protocol::OK::Header)) {
|
||||
|
@ -778,7 +776,7 @@ bool VL1::m_WHOIS(void *tPtr, const uint64_t packetId, const unsigned int auth,
|
|||
#endif
|
||||
}
|
||||
|
||||
bool VL1::m_RENDEZVOUS(void *tPtr, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
bool VL1::m_RENDEZVOUS(CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
{
|
||||
#if 0
|
||||
if (RR->topology->isRoot(peer->identity())) {
|
||||
|
@ -826,7 +824,7 @@ bool VL1::m_RENDEZVOUS(void *tPtr, const uint64_t packetId, const unsigned int a
|
|||
#endif
|
||||
}
|
||||
|
||||
bool VL1::m_ECHO(void *tPtr, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
bool VL1::m_ECHO(CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
{
|
||||
#if 0
|
||||
const uint64_t packetId = Protocol::packetId(pkt,packetSize);
|
||||
|
@ -864,7 +862,7 @@ bool VL1::m_ECHO(void *tPtr, const uint64_t packetId, const unsigned int auth, c
|
|||
#endif
|
||||
}
|
||||
|
||||
bool VL1::m_PUSH_DIRECT_PATHS(void *tPtr, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
bool VL1::m_PUSH_DIRECT_PATHS(CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
{
|
||||
#if 0
|
||||
if (packetSize < (int)sizeof(Protocol::PUSH_DIRECT_PATHS)) {
|
||||
|
@ -955,13 +953,13 @@ bool VL1::m_PUSH_DIRECT_PATHS(void *tPtr, const uint64_t packetId, const unsigne
|
|||
#endif
|
||||
}
|
||||
|
||||
bool VL1::m_USER_MESSAGE(void *tPtr, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
bool VL1::m_USER_MESSAGE(CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
{
|
||||
// TODO
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VL1::m_ENCAP(void *tPtr, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
bool VL1::m_ENCAP(CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
{
|
||||
// TODO: not implemented yet
|
||||
return true;
|
||||
|
|
26
core/VL1.hpp
26
core/VL1.hpp
|
@ -22,6 +22,7 @@
|
|||
#include "Mutex.hpp"
|
||||
#include "FCV.hpp"
|
||||
#include "Containers.hpp"
|
||||
#include "CallContext.hpp"
|
||||
|
||||
#define ZT_VL1_MAX_WHOIS_WAITING_PACKETS 32
|
||||
|
||||
|
@ -56,38 +57,37 @@ public:
|
|||
* contents should not be used after this call. Make a copy if the
|
||||
* data might still be needed.
|
||||
*
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param localSocket Local I/O socket as supplied by external code
|
||||
* @param fromAddr Internet IP address of origin
|
||||
* @param data Packet data
|
||||
* @param len Packet length
|
||||
*/
|
||||
void onRemotePacket(void *tPtr, int64_t localSocket, const InetAddress &fromAddr, SharedPtr< Buf > &data, unsigned int len) noexcept;
|
||||
void onRemotePacket(CallContext &cc, int64_t localSocket, const InetAddress &fromAddr, SharedPtr< Buf > &data, unsigned int len) noexcept;
|
||||
|
||||
private:
|
||||
const RuntimeEnvironment *RR;
|
||||
|
||||
void m_relay(void *tPtr, const SharedPtr< Path > &path, Address destination, SharedPtr< Buf > &pkt, int pktSize);
|
||||
void m_relay(CallContext &cc, const SharedPtr< Path > &path, Address destination, SharedPtr< Buf > &pkt, int pktSize);
|
||||
|
||||
void m_sendPendingWhois(void *tPtr, int64_t now);
|
||||
void m_sendPendingWhois(CallContext &cc);
|
||||
|
||||
SharedPtr< Peer > m_HELLO(void *tPtr, const SharedPtr< Path > &path, Buf &pkt, int packetSize);
|
||||
SharedPtr< Peer > m_HELLO(CallContext &cc, const SharedPtr< Path > &path, Buf &pkt, int packetSize);
|
||||
|
||||
bool m_ERROR(void *tPtr, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize, Protocol::Verb &inReVerb);
|
||||
bool m_ERROR(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize, Protocol::Verb &inReVerb);
|
||||
|
||||
bool m_OK(void *tPtr, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize, Protocol::Verb &inReVerb);
|
||||
bool m_OK(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize, Protocol::Verb &inReVerb);
|
||||
|
||||
bool m_WHOIS(void *tPtr, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
bool m_WHOIS(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
|
||||
bool m_RENDEZVOUS(void *tPtr, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
bool m_RENDEZVOUS(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
|
||||
bool m_ECHO(void *tPtr, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
bool m_ECHO(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
|
||||
bool m_PUSH_DIRECT_PATHS(void *tPtr, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
bool m_PUSH_DIRECT_PATHS(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
|
||||
bool m_USER_MESSAGE(void *tPtr, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
bool m_USER_MESSAGE(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
|
||||
bool m_ENCAP(void *tPtr, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
bool m_ENCAP(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
|
||||
// Defragmentation engine for handling inbound packets with more than one fragment.
|
||||
Defragmenter< ZT_MAX_PACKET_FRAGMENTS > m_inputPacketAssembler;
|
||||
|
|
20
core/VL2.cpp
20
core/VL2.cpp
|
@ -26,43 +26,43 @@ VL2::VL2(const RuntimeEnvironment *renv)
|
|||
{
|
||||
}
|
||||
|
||||
void VL2::onLocalEthernet(void *const tPtr, const SharedPtr< Network > &network, const MAC &from, const MAC &to, const unsigned int etherType, unsigned int vlanId, SharedPtr< Buf > &data, unsigned int len)
|
||||
void VL2::onLocalEthernet(CallContext &cc, const SharedPtr< Network > &network, const MAC &from, const MAC &to, const unsigned int etherType, unsigned int vlanId, SharedPtr< Buf > &data, unsigned int len)
|
||||
{
|
||||
}
|
||||
|
||||
bool VL2::m_FRAME(void *tPtr, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
bool VL2::m_FRAME(CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
{
|
||||
}
|
||||
|
||||
bool VL2::m_EXT_FRAME(void *tPtr, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
bool VL2::m_EXT_FRAME(CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
{
|
||||
}
|
||||
|
||||
bool VL2::m_MULTICAST_LIKE(void *tPtr, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
bool VL2::m_MULTICAST_LIKE(CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
{
|
||||
}
|
||||
|
||||
bool VL2::m_NETWORK_CREDENTIALS(void *tPtr, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
bool VL2::m_NETWORK_CREDENTIALS(CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
{
|
||||
}
|
||||
|
||||
bool VL2::m_NETWORK_CONFIG_REQUEST(void *tPtr, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
bool VL2::m_NETWORK_CONFIG_REQUEST(CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
{
|
||||
}
|
||||
|
||||
bool VL2::m_NETWORK_CONFIG(void *tPtr, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
bool VL2::m_NETWORK_CONFIG(CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
{
|
||||
}
|
||||
|
||||
bool VL2::m_MULTICAST_GATHER(void *tPtr, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
bool VL2::m_MULTICAST_GATHER(CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
{
|
||||
}
|
||||
|
||||
bool VL2::m_MULTICAST_FRAME_deprecated(void *tPtr, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
bool VL2::m_MULTICAST_FRAME_deprecated(CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
{
|
||||
}
|
||||
|
||||
bool VL2::m_MULTICAST(void *tPtr, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
bool VL2::m_MULTICAST(CallContext &cc, const uint64_t packetId, const unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
22
core/VL2.hpp
22
core/VL2.hpp
|
@ -21,6 +21,7 @@
|
|||
#include "Mutex.hpp"
|
||||
#include "FCV.hpp"
|
||||
#include "Containers.hpp"
|
||||
#include "CallContext.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -46,7 +47,6 @@ public:
|
|||
/**
|
||||
* Called when a packet comes from a local Ethernet tap
|
||||
*
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param network Which network's TAP did this packet come from?
|
||||
* @param from Originating MAC address
|
||||
* @param to Destination MAC address
|
||||
|
@ -55,26 +55,26 @@ public:
|
|||
* @param data Ethernet payload
|
||||
* @param len Frame length
|
||||
*/
|
||||
void onLocalEthernet(void *tPtr, const SharedPtr< Network > &network, const MAC &from, const MAC &to, unsigned int etherType, unsigned int vlanId, SharedPtr< Buf > &data, unsigned int len);
|
||||
void onLocalEthernet(CallContext &cc, const SharedPtr< Network > &network, const MAC &from, const MAC &to, unsigned int etherType, unsigned int vlanId, SharedPtr< Buf > &data, unsigned int len);
|
||||
|
||||
protected:
|
||||
bool m_FRAME(void *tPtr, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
bool m_FRAME(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
|
||||
bool m_EXT_FRAME(void *tPtr, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
bool m_EXT_FRAME(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
|
||||
bool m_MULTICAST_LIKE(void *tPtr, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
bool m_MULTICAST_LIKE(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
|
||||
bool m_NETWORK_CREDENTIALS(void *tPtr, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
bool m_NETWORK_CREDENTIALS(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
|
||||
bool m_NETWORK_CONFIG_REQUEST(void *tPtr, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
bool m_NETWORK_CONFIG_REQUEST(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
|
||||
bool m_NETWORK_CONFIG(void *tPtr, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
bool m_NETWORK_CONFIG(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
|
||||
bool m_MULTICAST_GATHER(void *tPtr, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
bool m_MULTICAST_GATHER(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
|
||||
bool m_MULTICAST_FRAME_deprecated(void *tPtr, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
bool m_MULTICAST_FRAME_deprecated(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
|
||||
bool m_MULTICAST(void *tPtr, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
bool m_MULTICAST(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
|
||||
|
||||
private:
|
||||
};
|
||||
|
|
172
core/zerotier.h
172
core/zerotier.h
|
@ -1750,18 +1750,10 @@ enum ZT_StateObjectType
|
|||
* List of certificates, their local trust, and locally added roots
|
||||
*
|
||||
* Object ID: (none)
|
||||
* Canonical path: <HOME>/trust
|
||||
* Canonical path: <HOME>/truststore
|
||||
* Persistence: required if root settings should persist
|
||||
*/
|
||||
ZT_STATE_OBJECT_TRUST_STORE = 7,
|
||||
|
||||
/**
|
||||
* Certificate
|
||||
*
|
||||
* Object ID: [6]serial (384-bit serial packed into 6 uint64_t's)
|
||||
* Canonical path: <HOME>/certs.d/<serial> (96-digit hex serial)
|
||||
*/
|
||||
ZT_STATE_OBJECT_CERT = 8
|
||||
ZT_STATE_OBJECT_TRUST_STORE = 7
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -2028,7 +2020,7 @@ struct ZT_Node_Callbacks
|
|||
*
|
||||
* @return Pointer to I/O buffer
|
||||
*/
|
||||
ZT_SDK_API void *ZT_getBuffer();
|
||||
ZT_SDK_API [[maybe_unused]] void *ZT_getBuffer();
|
||||
|
||||
/**
|
||||
* Free an unused buffer obtained via getBuffer
|
||||
|
@ -2059,37 +2051,32 @@ ZT_SDK_API void ZT_freeQueryResult(const void *qr);
|
|||
*
|
||||
* @param node Result: pointer is set to new node instance on success
|
||||
* @param uptr User pointer to pass to functions/callbacks
|
||||
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
|
||||
* @param callbacks Callback function configuration
|
||||
* @param now Current clock in milliseconds
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
ZT_SDK_API enum ZT_ResultCode ZT_Node_new(
|
||||
ZT_Node **node,
|
||||
void *uptr,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
const struct ZT_Node_Callbacks *callbacks,
|
||||
int64_t now);
|
||||
void *uptr,
|
||||
const struct ZT_Node_Callbacks *callbacks);
|
||||
|
||||
/**
|
||||
* Delete a node and free all resources it consumes
|
||||
*
|
||||
* If you are using multiple threads, all other threads must be shut down
|
||||
* first. This can crash if processXXX() methods are in progress.
|
||||
*
|
||||
* @param node Node to delete
|
||||
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
|
||||
*/
|
||||
ZT_SDK_API void ZT_Node_delete(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr);
|
||||
|
||||
/**
|
||||
* Process a packet received from the physical wire
|
||||
*
|
||||
* @param node Node instance
|
||||
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
|
||||
* @param now Current clock in milliseconds
|
||||
* @param localSocket Local socket (you can use 0 if only one local socket is bound and ignore this)
|
||||
* @param remoteAddress Origin of packet
|
||||
* @param packetData Packet data
|
||||
|
@ -2100,8 +2087,9 @@ ZT_SDK_API void ZT_Node_delete(
|
|||
*/
|
||||
ZT_SDK_API enum ZT_ResultCode ZT_Node_processWirePacket(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
int64_t now,
|
||||
int64_t localSocket,
|
||||
const ZT_InetAddress *remoteAddress,
|
||||
const void *packetData,
|
||||
|
@ -2112,9 +2100,6 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_processWirePacket(
|
|||
/**
|
||||
* Process a frame from a virtual network port (tap)
|
||||
*
|
||||
* @param node Node instance
|
||||
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
|
||||
* @param now Current clock in milliseconds
|
||||
* @param nwid ZeroTier 64-bit virtual network ID
|
||||
* @param sourceMac Source MAC address (least significant 48 bits)
|
||||
* @param destMac Destination MAC address (least significant 48 bits)
|
||||
|
@ -2128,8 +2113,9 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_processWirePacket(
|
|||
*/
|
||||
ZT_SDK_API enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
int64_t now,
|
||||
uint64_t nwid,
|
||||
uint64_t sourceMac,
|
||||
uint64_t destMac,
|
||||
|
@ -2143,16 +2129,15 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
|
|||
/**
|
||||
* Perform periodic background operations
|
||||
*
|
||||
* @param node Node instance
|
||||
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
|
||||
* @param now Current clock in milliseconds
|
||||
* @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks()
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
ZT_SDK_API enum ZT_ResultCode ZT_Node_processBackgroundTasks(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
int64_t now,
|
||||
volatile int64_t *nextBackgroundTaskDeadline);
|
||||
|
||||
/**
|
||||
|
@ -2164,19 +2149,18 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_processBackgroundTasks(
|
|||
* If we are already a member of the network, nothing is done and OK is
|
||||
* returned.
|
||||
*
|
||||
* @param node Node instance
|
||||
* @param nwid 64-bit ZeroTier network ID
|
||||
* @param fingerprintHash If non-NULL this is the full fingerprint of the controller
|
||||
* @param uptr An arbitrary pointer to associate with this network (default: NULL)
|
||||
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
ZT_SDK_API enum ZT_ResultCode ZT_Node_join(
|
||||
ZT_Node *node,
|
||||
uint64_t nwid,
|
||||
const ZT_Fingerprint *controllerFingerprint,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
void *uptr,
|
||||
void *tptr);
|
||||
uint64_t nwid,
|
||||
const ZT_Fingerprint *controllerFingerprint);
|
||||
|
||||
/**
|
||||
* Leave a network
|
||||
|
@ -2188,17 +2172,15 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_join(
|
|||
* The uptr parameter is optional and is NULL by default. If it is not NULL,
|
||||
* the pointer it points to is set to this network's uptr on success.
|
||||
*
|
||||
* @param node Node instance
|
||||
* @param nwid 64-bit network ID
|
||||
* @param uptr Target pointer is set to uptr (if not NULL)
|
||||
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
|
||||
* @return OK (0) or error code if a fatal error condition has occurred
|
||||
*/
|
||||
ZT_SDK_API enum ZT_ResultCode ZT_Node_leave(
|
||||
ZT_Node *node,
|
||||
uint64_t nwid,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
void **uptr,
|
||||
void *tptr);
|
||||
uint64_t nwid);
|
||||
|
||||
/**
|
||||
* Subscribe to an Ethernet multicast group
|
||||
|
@ -2219,8 +2201,6 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_leave(
|
|||
*
|
||||
* This does not generate an update call to networkConfigCallback().
|
||||
*
|
||||
* @param node Node instance
|
||||
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
|
||||
* @param nwid 64-bit network ID
|
||||
* @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
|
||||
* @param multicastAdi Multicast ADI (least significant 32 bits only, use 0 if not needed)
|
||||
|
@ -2228,6 +2208,8 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_leave(
|
|||
*/
|
||||
ZT_SDK_API enum ZT_ResultCode ZT_Node_multicastSubscribe(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
uint64_t nwid,
|
||||
uint64_t multicastGroup,
|
||||
|
@ -2241,7 +2223,6 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_multicastSubscribe(
|
|||
*
|
||||
* This does not generate an update call to networkConfigCallback().
|
||||
*
|
||||
* @param node Node instance
|
||||
* @param nwid 64-bit network ID
|
||||
* @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
|
||||
* @param multicastAdi Multicast ADI (least significant 32 bits only, use 0 if not needed)
|
||||
|
@ -2249,6 +2230,9 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_multicastSubscribe(
|
|||
*/
|
||||
ZT_SDK_API enum ZT_ResultCode ZT_Node_multicastUnsubscribe(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
uint64_t nwid,
|
||||
uint64_t multicastGroup,
|
||||
unsigned long multicastAdi);
|
||||
|
@ -2256,10 +2240,10 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_multicastUnsubscribe(
|
|||
/**
|
||||
* Get this node's 40-bit ZeroTier address
|
||||
*
|
||||
* @param node Node instance
|
||||
* @return ZeroTier address (least significant 40 bits of 64-bit int)
|
||||
*/
|
||||
ZT_SDK_API uint64_t ZT_Node_address(ZT_Node *node);
|
||||
ZT_SDK_API uint64_t ZT_Node_address(
|
||||
ZT_Node *node);
|
||||
|
||||
/**
|
||||
* Get this node's identity
|
||||
|
@ -2267,19 +2251,21 @@ ZT_SDK_API uint64_t ZT_Node_address(ZT_Node *node);
|
|||
* The identity pointer returned by this function need not and should not be
|
||||
* freed with ZT_Identity_delete(). It's valid until the node is deleted.
|
||||
*
|
||||
* @param node Node instance
|
||||
* @return Identity
|
||||
*/
|
||||
ZT_SDK_API const ZT_Identity *ZT_Node_identity(ZT_Node *node);
|
||||
ZT_SDK_API const ZT_Identity *ZT_Node_identity(
|
||||
ZT_Node *node);
|
||||
|
||||
/**
|
||||
* Get the status of this node
|
||||
*
|
||||
* @param node Node instance
|
||||
* @param status Buffer to fill with current node status
|
||||
*/
|
||||
ZT_SDK_API void ZT_Node_status(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
ZT_NodeStatus *status);
|
||||
|
||||
/**
|
||||
|
@ -2288,10 +2274,13 @@ ZT_SDK_API void ZT_Node_status(
|
|||
* The pointer returned here must be freed with freeQueryResult()
|
||||
* when you are done with it.
|
||||
*
|
||||
* @param node Node instance
|
||||
* @return List of known peers or NULL on failure
|
||||
*/
|
||||
ZT_SDK_API ZT_PeerList *ZT_Node_peers(ZT_Node *node);
|
||||
ZT_SDK_API ZT_PeerList *ZT_Node_peers(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr);
|
||||
|
||||
/**
|
||||
* Get the status of a virtual network
|
||||
|
@ -2299,12 +2288,14 @@ ZT_SDK_API ZT_PeerList *ZT_Node_peers(ZT_Node *node);
|
|||
* The pointer returned here must be freed with freeQueryResult()
|
||||
* when you are done with it.
|
||||
*
|
||||
* @param node Node instance
|
||||
* @param nwid 64-bit network ID
|
||||
* @return Network configuration or NULL if we are not a member of this network
|
||||
*/
|
||||
ZT_SDK_API ZT_VirtualNetworkConfig *ZT_Node_networkConfig(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
uint64_t nwid);
|
||||
|
||||
/**
|
||||
|
@ -2313,7 +2304,8 @@ ZT_SDK_API ZT_VirtualNetworkConfig *ZT_Node_networkConfig(
|
|||
* @param node Node instance
|
||||
* @return List of networks or NULL on failure
|
||||
*/
|
||||
ZT_SDK_API ZT_VirtualNetworkList *ZT_Node_networks(ZT_Node *node);
|
||||
ZT_SDK_API ZT_VirtualNetworkList *ZT_Node_networks(
|
||||
ZT_Node *node);
|
||||
|
||||
/**
|
||||
* Set the network-associated user-defined pointer for a given network
|
||||
|
@ -2338,61 +2330,18 @@ ZT_SDK_API void ZT_Node_setNetworkUserPtr(
|
|||
*/
|
||||
ZT_SDK_API void ZT_Node_setInterfaceAddresses(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
const ZT_InterfaceAddress *addrs,
|
||||
unsigned int addrCount);
|
||||
|
||||
/**
|
||||
* Add a peer directly by supplying its identity
|
||||
*
|
||||
* This does not authorize the peer on a network (only the network's
|
||||
* controller can do that) or otherwise give it special privileges. It
|
||||
* also doesn't guarantee it will be contacted. It just adds it to the
|
||||
* internal peer data set if it is not already present.
|
||||
*
|
||||
* @param node Node instance
|
||||
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
|
||||
* @param id Identity of peer to add
|
||||
* @return OK (0) or error code
|
||||
*/
|
||||
ZT_SDK_API enum ZT_ResultCode ZT_Node_addPeer(
|
||||
ZT_Node *node,
|
||||
void *tptr,
|
||||
const ZT_Identity *id);
|
||||
|
||||
/**
|
||||
* Attempt to contact a peer at an explicit endpoint address.
|
||||
*
|
||||
* If the fingerprint structure's hash is all zeroes, the peer is
|
||||
* looked up only by address.
|
||||
*
|
||||
* This can only fail if the peer was not found.
|
||||
*
|
||||
* Note that this can immediately (before this returns) result in
|
||||
* calls to the send packet functions supplied to the core.
|
||||
*
|
||||
* @param node Node instance
|
||||
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
|
||||
* @param fp Fingerprint (or only address)
|
||||
* @param endpoint Endpoint
|
||||
* @param retries If greater than zero, try this many times
|
||||
* @return Boolean: non-zero on success, zero if peer was not found
|
||||
*/
|
||||
ZT_SDK_API int ZT_Node_tryPeer(
|
||||
ZT_Node *node,
|
||||
void *tptr,
|
||||
const ZT_Fingerprint *fp,
|
||||
const ZT_Endpoint *endpoint,
|
||||
int retries);
|
||||
|
||||
/**
|
||||
* Add a certificate to this node's certificate store
|
||||
*
|
||||
* This supports adding of certificates as expanded ZT_Certificate structures
|
||||
* or as raw data. If 'cert' is NULL then certData/certSize must be set.
|
||||
*
|
||||
* @param node Node instance
|
||||
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
|
||||
* @param now Current time
|
||||
* @param localTrust Local trust flags (ORed together)
|
||||
* @param cert Certificate object, or set to NULL if certData and certSize are to be used
|
||||
* @param certData Certificate binary data if 'cert' is NULL, NULL otherwise
|
||||
|
@ -2401,8 +2350,9 @@ ZT_SDK_API int ZT_Node_tryPeer(
|
|||
*/
|
||||
ZT_SDK_API enum ZT_CertificateError ZT_Node_addCertificate(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
int64_t now,
|
||||
unsigned int localTrust,
|
||||
const ZT_Certificate *cert,
|
||||
const void *certData,
|
||||
|
@ -2421,6 +2371,8 @@ ZT_SDK_API enum ZT_CertificateError ZT_Node_addCertificate(
|
|||
*/
|
||||
ZT_SDK_API enum ZT_ResultCode ZT_Node_deleteCertificate(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
const void *serialNo);
|
||||
|
||||
|
@ -2430,7 +2382,11 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_deleteCertificate(
|
|||
* @param node Node instance
|
||||
* @return List of certificates or NULL on error
|
||||
*/
|
||||
ZT_SDK_API ZT_CertificateList *ZT_Node_listCertificates(ZT_Node *node);
|
||||
ZT_SDK_API ZT_CertificateList *ZT_Node_listCertificates(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr);
|
||||
|
||||
/**
|
||||
* Send a VERB_USER_MESSAGE to another ZeroTier node
|
||||
|
@ -2448,6 +2404,8 @@ ZT_SDK_API ZT_CertificateList *ZT_Node_listCertificates(ZT_Node *node);
|
|||
*/
|
||||
ZT_SDK_API int ZT_Node_sendUserMessage(
|
||||
ZT_Node *node,
|
||||
int64_t clock,
|
||||
int64_t ticks,
|
||||
void *tptr,
|
||||
uint64_t dest,
|
||||
uint64_t typeId,
|
||||
|
@ -2665,7 +2623,7 @@ ZT_SDK_API int ZT_Endpoint_fromBytes(
|
|||
* Note that attributes must be either NULL to use defaults for all or there
|
||||
* must be an attributes object for each endpoint.
|
||||
*
|
||||
* @param ts Locator timestamp
|
||||
* @param rev Locator timestamp
|
||||
* @param endpoints List of endpoints to store in locator
|
||||
* @param endpointAttributes Array of ZT_EndpointAttributes objects or NULL to use defaults
|
||||
* @param endpointCount Number of endpoints (maximum: 8)
|
||||
|
@ -2673,7 +2631,7 @@ ZT_SDK_API int ZT_Endpoint_fromBytes(
|
|||
* @return Locator or NULL on error (too many endpoints or identity does not have private key)
|
||||
*/
|
||||
ZT_SDK_API ZT_Locator *ZT_Locator_create(
|
||||
int64_t ts,
|
||||
int64_t rev,
|
||||
const ZT_Endpoint *endpoints,
|
||||
const ZT_EndpointAttributes *endpointAttributes,
|
||||
unsigned int endpointCount,
|
||||
|
@ -2735,12 +2693,12 @@ ZT_SDK_API char *ZT_Locator_toString(
|
|||
ZT_SDK_API const ZT_Fingerprint *ZT_Locator_fingerprint(const ZT_Locator *loc);
|
||||
|
||||
/**
|
||||
* Get a locator's timestamp
|
||||
* Get a locator's revision
|
||||
*
|
||||
* @param loc Locator to query
|
||||
* @return Locator timestamp in milliseconds since epoch
|
||||
* @return Locator revision
|
||||
*/
|
||||
ZT_SDK_API int64_t ZT_Locator_timestamp(const ZT_Locator *loc);
|
||||
ZT_SDK_API int64_t ZT_Locator_revision(const ZT_Locator *loc);
|
||||
|
||||
/**
|
||||
* Get the number of endpoints in this locator
|
||||
|
|
|
@ -27,13 +27,13 @@ pub struct Locator {
|
|||
impl Locator {
|
||||
/// Create and sign a new locator.
|
||||
/// The signer must include its secret key.
|
||||
pub fn new(signer: &Identity, timestamp: i64, endpoints: &Vec<Endpoint>) -> Result<Locator, ResultCode> {
|
||||
pub fn new(signer: &Identity, revision: i64, endpoints: &Vec<Endpoint>) -> Result<Locator, ResultCode> {
|
||||
let mut capi_endpoints: Vec<ztcore::ZT_Endpoint> = Vec::new();
|
||||
capi_endpoints.reserve(endpoints.len());
|
||||
for ep in endpoints.iter() {
|
||||
capi_endpoints.push(ep.capi);
|
||||
}
|
||||
let loc = unsafe { ztcore::ZT_Locator_create(timestamp, capi_endpoints.as_ptr(), null(), capi_endpoints.len() as c_uint, signer.capi) };
|
||||
let loc = unsafe { ztcore::ZT_Locator_create(revision, capi_endpoints.as_ptr(), null(), capi_endpoints.len() as c_uint, signer.capi) };
|
||||
if loc.is_null() {
|
||||
Err(ResultCode::ErrorBadParameter)
|
||||
} else {
|
||||
|
@ -65,9 +65,9 @@ impl Locator {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn timestamp(&self) -> i64 {
|
||||
pub fn revision(&self) -> i64 {
|
||||
unsafe {
|
||||
ztcore::ZT_Locator_timestamp(self.capi) as i64
|
||||
ztcore::ZT_Locator_revision(self.capi) as i64
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,14 @@ pub enum StateObjectType {
|
|||
Peer = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_PEER as isize,
|
||||
NetworkConfig = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_NETWORK_CONFIG as isize,
|
||||
TrustStore = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_TRUST_STORE as isize,
|
||||
Certificate = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_CERT as isize,
|
||||
}
|
||||
|
||||
impl StateObjectType {
|
||||
/// True if this state object should be protected.
|
||||
#[inline(always)]
|
||||
pub fn is_secret(&self) -> bool {
|
||||
*self == StateObjectType::IdentitySecret || *self == StateObjectType::TrustStore
|
||||
}
|
||||
}
|
||||
|
||||
/// The status of a ZeroTier node.
|
||||
|
|
|
@ -35,7 +35,6 @@ pub(crate) struct Store {
|
|||
peers_path: Box<Path>,
|
||||
controller_path: Box<Path>,
|
||||
networks_path: Box<Path>,
|
||||
certs_path: Box<Path>,
|
||||
auth_token_path: Mutex<Box<Path>>,
|
||||
auth_token: Mutex<String>,
|
||||
}
|
||||
|
@ -69,7 +68,6 @@ impl Store {
|
|||
peers_path: bp.join("peers.d").into_boxed_path(),
|
||||
controller_path: bp.join("controller.d").into_boxed_path(),
|
||||
networks_path: bp.join("networks.d").into_boxed_path(),
|
||||
certs_path: bp.join("certs.d").into_boxed_path(),
|
||||
auth_token_path: Mutex::new(auth_token_path_override.map_or_else(|| {
|
||||
bp.join(AUTHTOKEN_SECRET).into_boxed_path()
|
||||
}, |auth_token_path_override| {
|
||||
|
@ -85,32 +83,16 @@ impl Store {
|
|||
let _ = std::fs::create_dir_all(&s.peers_path);
|
||||
let _ = std::fs::create_dir_all(&s.controller_path);
|
||||
let _ = std::fs::create_dir_all(&s.networks_path);
|
||||
let _ = std::fs::create_dir_all(&s.certs_path);
|
||||
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
fn make_obj_path_internal(&self, obj_type: &StateObjectType, obj_id: &[u64]) -> Option<PathBuf> {
|
||||
match obj_type {
|
||||
StateObjectType::IdentityPublic => {
|
||||
Some(self.base_path.join("identity.public"))
|
||||
},
|
||||
StateObjectType::IdentitySecret => {
|
||||
Some(self.base_path.join("identity.secret"))
|
||||
},
|
||||
StateObjectType::Certificate => {
|
||||
if obj_id.len() < 6 {
|
||||
None
|
||||
} else {
|
||||
Some(self.certs_path.join(format!("{:0>16x}{:0>16x}{:0>16x}{:0>16x}{:0>16x}{:0>16x}.cert", obj_id[0], obj_id[1], obj_id[2], obj_id[3], obj_id[4], obj_id[5])))
|
||||
}
|
||||
},
|
||||
StateObjectType::TrustStore => {
|
||||
Some(self.base_path.join("trust"))
|
||||
},
|
||||
StateObjectType::Locator => {
|
||||
Some(self.base_path.join("locator"))
|
||||
},
|
||||
StateObjectType::IdentityPublic => Some(self.base_path.join("identity.public")),
|
||||
StateObjectType::IdentitySecret => Some(self.base_path.join("identity.secret")),
|
||||
StateObjectType::TrustStore => Some(self.base_path.join("truststore")),
|
||||
StateObjectType::Locator => Some(self.base_path.join("locator")),
|
||||
StateObjectType::NetworkConfig => {
|
||||
if obj_id.len() < 1 {
|
||||
None
|
||||
|
@ -306,7 +288,7 @@ impl Store {
|
|||
let obj_path = obj_path.unwrap();
|
||||
std::fs::OpenOptions::new().write(true).truncate(true).create(true).open(&obj_path)?.write_all(obj_data)?;
|
||||
|
||||
if obj_type.eq(&StateObjectType::IdentitySecret) || obj_type.eq(&StateObjectType::TrustStore) {
|
||||
if obj_type.is_secret() {
|
||||
lock_down_file(obj_path.to_str().unwrap());
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue