Moar build fixes, clock perf improvement.

This commit is contained in:
Adam Ierymenko 2020-03-23 16:12:45 -07:00
parent 2da096944d
commit 490b9c4d79
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
13 changed files with 87 additions and 92 deletions

View file

@ -27,7 +27,7 @@ A ZeroTier identity is comprised of one or more cryptographic public keys and a
#### Identity Types and Corresponding Algorithms
* **Type 0** (v1.x and v2.x): one Curve25519 key for elliptic curve Diffie-Hellman and one Ed25519 key for Ed25519 signatures, with the address and fingerprint computed from a hash of both.
* **Type 1** (v2.x only): Curve25519, Ed25519, and NIST P-384 public keys, with the latter being used for signatures (the Ed25519 key is still there but is presently unused) and with *both* keys being used for elliptic curve Diffie-Hellman key agreement. In key agreement the resulting raw secret keys are hashed together using SHA-384 to combine them and yield a single session key.
* **Type 1** (v2.x only): Curve25519, Ed25519, and NIST P-384 public keys, with the latter being used for signatures (the Ed25519 key is still there but is presently unused) and with *both* Curve25519 and NIST P-384 being used for elliptic curve Diffie-Hellman key agreement. In key agreement the resulting raw secret keys are hashed together using SHA-384 to combine them and yield a single session key.
Session keys resulting from identity key exchange and agreement are *long-lived keys* that remain static for the lifetime of a particular pair of identities. A different mechanism is used for ephemeral key negotiation.
@ -52,6 +52,8 @@ bzg7fc3sn46fzyxcxw2ev4c4m2u5fyisb3o4wz5hfmvexbzwk6et3fsglkdcn6nnjobxi3bq7hgxqox3
These are too large to type but not to copy/paste, store in databases, or use in scripts and APIs.
Once a device has joined a network, network controllers will remember and check its full identity or identity fingerprint (depending on implementation) rather than just the device's ZeroTier address.
## VL1 Wire Protocol
ZeroTier's wire protocol is packet based with packets having the following format:

View file

@ -0,0 +1,4 @@
package main
func main() {
}

View file

@ -37,7 +37,6 @@ Global Options:
Commands:
help Show this help
version Print version
selftest Run internal tests
service Start as service
status Show ZeroTier status and config
peers Show VL1 peers and link information

View file

@ -1,29 +0,0 @@
/*
* Copyright (c)2013-2020 ZeroTier, Inc.
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file in the project's root directory.
*
* Change Date: 2024-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.
*/
/****/
package cli
import (
"fmt"
"os"
"zerotier/pkg/zerotier"
)
func SelfTest() {
if !zerotier.SelfTest() {
fmt.Println("FAILED: at least one ZeroTier self-test reported failure.")
os.Exit(1)
}
os.Exit(0)
}

View file

@ -123,9 +123,6 @@ func main() {
case "version":
fmt.Printf("%d.%d.%d\n", zerotier.CoreVersionMajor, zerotier.CoreVersionMinor, zerotier.CoreVersionRevision)
os.Exit(0)
case "selftest":
cli.SelfTest()
os.Exit(0)
case "service":
cli.Service(basePath, authToken, cmdArgs)
case "status":

View file

@ -46,7 +46,7 @@ type Identity struct {
idtype int
publicKey []byte
privateKey []byte
cid unsafe.Pointer
cid unsafe.Pointer // ZT_Identity
}
func identityFinalizer(obj interface{}) {

View file

@ -45,10 +45,10 @@ type ExternalAddress struct {
// LocalConfigSettings contains node settings
type LocalConfigSettings struct {
// PrimaryPort is the main UDP port and must be set (defaults to 9993)
// PrimaryPort is the main UDP port and must be set.
PrimaryPort int `json:"primaryPort"`
// SecondaryPort is the secondary UDP port, set to 0 to disbale (picked at random by default)
// SecondaryPort is the secondary UDP port, set to 0 to disable (picked at random by default)
SecondaryPort int `json:"secondaryPort"`
// PortSearch causes ZeroTier to try other ports automatically if it can't bind to configured ports
@ -100,6 +100,10 @@ func (lc *LocalConfig) Read(p string, saveDefaultsIfNotExist bool, isTotallyNewN
if isTotallyNewNode {
lc.Settings.PrimaryPort = 793
} else {
// For legacy reasons we keep nodes that already existed prior to 2.0 (upgraded nodes)
// at 9993 by default if there is no existing primary port configured. This is for
// principle of least surprise since some admins may have special firewall rules for
// this port.
lc.Settings.PrimaryPort = 9993
}
lc.Settings.SecondaryPort = unassignedPrivilegedPorts[randomUInt()%uint(len(unassignedPrivilegedPorts))]

View file

@ -899,7 +899,7 @@ void AES::CTR::finish() noexcept
// Software AES and AES key expansion ---------------------------------------------------------------------------------
#ifdef ZT_NO_UNALIGNED_ACCESS
static inline uint32_t readuint32_t(const void *in)
static ZT_INLINE uint32_t readuint32_t(const void *in)
{
uint32_t v = ((const uint8_t *)in)[0];
v <<= 8;
@ -910,7 +910,7 @@ static inline uint32_t readuint32_t(const void *in)
v |= ((const uint8_t *)in)[3];
return v;
}
static inline void writeuint32_t(void *out,const uint32_t v)
static ZT_INLINE void writeuint32_t(void *out,const uint32_t v)
{
((uint8_t *)out)[0] = (uint8_t)(v >> 24);
((uint8_t *)out)[1] = (uint8_t)(v >> 16);

View file

@ -24,6 +24,8 @@ namespace ZeroTier {
/**
* A ZeroTier address
*
* This is merely a 40-bit short address packed into a uint64_t and wrapped with methods.
*/
class Address : public TriviallyCopyable
{

View file

@ -1,26 +0,0 @@
/*
* Copyright (c)2013-2020 ZeroTier, Inc.
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file in the project's root directory.
*
* Change Date: 2024-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_LZ4_HPP
#define ZT_LZ4_HPP
#include "Constants.hpp"
namespace ZeroTier {
int LZ4_compress_fast(const char *source,char *dest,int inputSize,int maxOutputSize,int acceleration = 1) noexcept;
int LZ4_decompress_safe(const char *source,char *dest,int compressedSize,int maxDecompressedSize) noexcept;
} // namespace ZeroTier
#endif

View file

@ -36,6 +36,13 @@ namespace ZeroTier {
namespace {
/**
* All core objects of a ZeroTier node.
*
* This is just a box that allows us to allocate all core objects
* and data structures at once for a bit of memory saves and improved
* cache adjacency.
*/
struct _NodeObjects
{
ZT_INLINE _NodeObjects(RuntimeEnvironment *const RR,void *const tPtr) :
@ -190,11 +197,17 @@ ZT_ResultCode Node::processVirtualNetworkFrame(
}
}
struct _processBackgroundTasks_ping_eachPeer
struct _processBackgroundTasks_eachPeer
{
int64_t now;
Node *parent;
void *tPtr;
ZT_INLINE _processBackgroundTasks_eachPeer(const int64_t now_,Node *const parent_,void *const tPtr_) :
now(now_),
parent(parent_),
tPtr(tPtr_),
online(false),
rootsNotOnline() {}
const int64_t now;
Node *const parent;
void *const tPtr;
bool online;
std::vector<Address> rootsNotOnline;
ZT_INLINE void operator()(const SharedPtr<Peer> &peer,const bool isRoot)
@ -209,22 +222,25 @@ struct _processBackgroundTasks_ping_eachPeer
}
}
};
static uint8_t keepAlivePayload = 0; // junk payload for keepalive packets
struct _processBackgroundTasks_path_keepalive
struct _processBackgroundTasks_eachPath
{
int64_t now;
RuntimeEnvironment *RR;
void *tPtr;
ZT_INLINE _processBackgroundTasks_eachPath(const int64_t now_,const RuntimeEnvironment *const RR_,void *const tPtr_) :
now(now_),
RR(RR_),
tPtr(tPtr_),
keepAlivePayload((uint8_t)now_) {}
const int64_t now;
const RuntimeEnvironment *const RR;
void *const tPtr;
uint8_t keepAlivePayload;
ZT_INLINE void operator()(const SharedPtr<Path> &path)
{
if ((now - path->lastOut()) >= ZT_PATH_KEEPALIVE_PERIOD) {
++keepAlivePayload;
path->send(RR,tPtr,&keepAlivePayload,1,now);
path->send(RR,tPtr,&keepAlivePayload,sizeof(keepAlivePayload),now);
}
}
};
ZT_ResultCode Node::processBackgroundTasks(void *tPtr, int64_t now, volatile int64_t *nextBackgroundTaskDeadline)
{
_now = now;
@ -233,12 +249,8 @@ ZT_ResultCode Node::processBackgroundTasks(void *tPtr, int64_t now, volatile int
if ((now - _lastPing) >= ZT_PEER_PING_PERIOD) {
_lastPing = now;
try {
_processBackgroundTasks_ping_eachPeer pf;
pf.now = now;
pf.parent = this;
pf.tPtr = tPtr;
pf.online = false;
RR->topology->eachPeerWithRoot<_processBackgroundTasks_ping_eachPeer &>(pf);
_processBackgroundTasks_eachPeer pf(now,this,tPtr);
RR->topology->eachPeerWithRoot<_processBackgroundTasks_eachPeer &>(pf);
if (pf.online != _online) {
_online = pf.online;
@ -300,11 +312,8 @@ ZT_ResultCode Node::processBackgroundTasks(void *tPtr, int64_t now, volatile int
if ((now - _lastPathKeepaliveCheck) >= ZT_PATH_KEEPALIVE_PERIOD) {
_lastPathKeepaliveCheck = now;
_processBackgroundTasks_path_keepalive pf;
pf.now = now;
pf.RR = RR;
pf.tPtr = tPtr;
RR->topology->eachPath<_processBackgroundTasks_path_keepalive &>(pf);
_processBackgroundTasks_eachPath pf(now,RR,tPtr);
RR->topology->eachPath<_processBackgroundTasks_eachPath &>(pf);
}
int64_t earliestAlarmAt = 0x7fffffffffffffffLL;

View file

@ -30,6 +30,16 @@
namespace ZeroTier {
#ifdef __APPLE__
static clock_serv_t _machGetRealtimeClock() noexcept
{
clock_serv_t c;
host_get_clock_service(mach_host_self(),CALENDAR_CLOCK,&c);
return c;
}
static clock_serv_t s_machRealtimeClock = _machGetRealtimeClock();
#endif
unsigned int OSUtils::ztsnprintf(char *buf,unsigned int len,const char *fmt,...)
{
va_list ap;

View file

@ -32,6 +32,12 @@
#include <unistd.h>
#endif
#ifdef __APPLE__
#include <mach/mach.h>
#include <mach/clock.h>
#include <mach/mach_time.h>
#endif
#ifndef OMIT_JSON_SUPPORT
#include "../ext/json/json.hpp"
#endif
@ -43,6 +49,11 @@ namespace ZeroTier {
*/
class OSUtils
{
private:
#ifdef __APPLE__
static clock_serv_t s_machRealtimeClock;
#endif
public:
/**
* Variant of snprintf that is portable and throws an exception
@ -161,14 +172,26 @@ public:
tmp.LowPart = ft.dwLowDateTime;
tmp.HighPart = ft.dwHighDateTime;
return (int64_t)( ((tmp.QuadPart - 116444736000000000LL) / 10000L) + st.wMilliseconds );
#else
#ifdef __LINUX__
timespec ts;
#ifdef CLOCK_REALTIME_COARSE
clock_gettime(CLOCK_REALTIME_COARSE,&ts);
#else
clock_gettime(CLOCK_REALTIME,&ts);
#endif
return ( (1000LL * (int64_t)ts.tv_sec) + ((int64_t)(ts.tv_nsec / 1000000)) );
#else
#ifdef __APPLE__
mach_timespec_t mts;
clock_get_time(s_machRealtimeClock,&mts);
return ( (1000LL * (int64_t)mts.tv_sec) + ((int64_t)(mts.tv_nsec / 1000000)) );
#else
timeval tv;
// #ifdef __LINUX__
// syscall(SYS_gettimeofday,&tv,0); /* fix for musl libc broken gettimeofday bug */
// #else
gettimeofday(&tv,(struct timezone *)0);
// #endif
return ( (1000LL * (int64_t)tv.tv_sec) + (int64_t)(tv.tv_usec / 1000) );
#endif
#endif
#endif
};