A bunch of warning removal, build fixes, and cleanup.

This commit is contained in:
Adam Ierymenko 2020-05-25 09:48:18 -07:00
parent 1f9717250c
commit 6051c973d3
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
32 changed files with 222 additions and 330 deletions

View file

@ -14,6 +14,7 @@
#include "MIMC52.hpp"
#include "SHA512.hpp"
#include "Utils.hpp"
#include "Salsa20.hpp"
// This gets defined on any architecture whose FPU is not capable of doing the mulmod52() FPU trick.
//#define ZT_MIMC52_NO_FPU
@ -98,60 +99,52 @@ ZT_INLINE uint64_t modpow52(uint64_t a,uint64_t e,const uint64_t p) noexcept
} // anonymous namespace
#define ZT_MIMC52_ROUND_CONSTANT_COUNT 1048576
uint64_t mimc52Delay(const void *const salt,const unsigned int saltSize,const unsigned long rounds)
{
uint64_t hash[6];
SHA384(hash,salt,saltSize);
uint64_t hash[8];
SHA512(hash,salt,saltSize);
#if __BYTE_ORDER == __LITTLE_ENDIAN
uint64_t p = s_mimc52Primes[hash[0] & 511U];
const uint64_t p = s_mimc52Primes[hash[0] & 511U];
uint64_t x = hash[1] % p;
#else
uint64_t p = s_mimc52Primes[Utils::swapBytes(hash[0]) & 511U];
const uint64_t p = s_mimc52Primes[Utils::swapBytes(hash[0]) & 511U];
uint64_t x = Utils::swapBytes(hash[1]) % p;
#endif
//Speck128<8> roundConstantGenerator(hash + 2);
const uint64_t e = ((p * 2) - 1) / 3;
const uint64_t m52 = 0xfffffffffffffULL;
const uint64_t rmin1 = rounds - 1;
const uint64_t sxx = hash[4];
#pragma unroll 16
for(unsigned long r=0;r<rounds;++r) {
uint64_t sx = sxx,sy = rmin1 - r;
//roundConstantGenerator.encryptXY(sx,sy);
x = (x - sy) & m52;
const uint32_t rminus1 = rounds - 1;
for(uint32_t r=0;r<rounds;++r) {
x = (x - (uint64_t)sy) & m52;
x = modpow52(x,e,p);
}
return x;
}
bool mimc52Verify(const void *const salt,const unsigned int saltSize,unsigned long rounds,const uint64_t proof)
bool mimc52Verify(const void *const salt,const unsigned int saltSize,const unsigned long rounds,const uint64_t proof)
{
uint64_t hash[6];
SHA384(hash,salt,saltSize);
#if __BYTE_ORDER == __LITTLE_ENDIAN
uint64_t p = s_mimc52Primes[hash[0] & 511U];
uint64_t x = hash[1] % p;
#else
uint64_t p = s_mimc52Primes[Utils::swapBytes(hash[0]) & 511U];
const uint64_t p = s_mimc52Primes[Utils::swapBytes(hash[0]) & 511U];
uint64_t x = Utils::swapBytes(hash[1]) % p;
#else
const uint64_t p = s_mimc52Primes[hash[0] & 511U];
uint64_t x = hash[1] % p;
#endif
//Speck128<8> roundConstantGenerator(hash + 2);
const uint64_t m52 = 0xfffffffffffffULL;
uint64_t y = proof & m52;
const uint64_t sxx = hash[4];
#if !defined(ZT_MIMC52_NO_FPU)
double ii,of,pp = (double)p;
#ifndef ZT_MIMC52_NO_FPU
double dy,ii,of,pp = (double)p;
uint64_t oi,one = 1;
#endif
#pragma unroll 16
for(unsigned long r=0;r<rounds;++r) {
uint64_t sx = sxx,sy = r;
//roundConstantGenerator.encryptXY(sx,sy);
#ifdef ZT_MIMC52_NO_FPU
#ifdef x64_cubemod
x64_cubemod(y,p);
@ -160,18 +153,19 @@ bool mimc52Verify(const void *const salt,const unsigned int saltSize,unsigned lo
#endif
#else
// mulmod52(mulmod52(y,y,p),y,p)
of = (double)y;
dy = (double)y;
of = dy;
oi = y;
ii = (of * of) / pp;
y *= oi;
y -= ((uint64_t)ii - one) * p;
//y %= p;
ii = ((double)y * of) / pp;
//y %= p; // does not seem to be necessary
ii = (dy * of) / pp;
y *= oi;
y -= ((uint64_t)ii - one) * p;
y %= p;
#endif
y = (y + sy) & m52;
y = (y + (uint64_t)sy) & m52;
}
return (y % p) == x;

View file

@ -29,7 +29,8 @@ Usage: zerotier [-options] <command> [command args]
Global Options:
-j Output raw JSON where applicable
-p <path> Use alternate base path
-t <path> Use secret auth token from this file
-t <path> Load secret auth token from a file
-T <token> Set secret auth token on command line
Commands:
help Show this help
@ -38,7 +39,7 @@ Commands:
status Show node status, identity, and config
peers List all VL1 peers
roots List root peers
addroot <path/URL to spec> Add root
addroot <path | URL> Add root from root spec file or URL
removeroot <address> Remove a peer from the root list
join <network ID> [fingerprint] Join a virtual network
leave <network ID> Leave a virtual network
@ -62,7 +63,7 @@ Commands:
validate <identity> Locally validate an identity
sign <identity> <file> Sign a file with an identity's key
verify <identity> <file> <sig> Verify a signature
makeroot <identity> <address> ... Make a root spec (see docs)
makeroot <identity> <address> [...] Make a root spec (see docs)
The 'service' command does not exit until the service receives a signal.
This is typically run from launchd (Mac), systemd or init (Linux), a Windows

View file

@ -102,6 +102,11 @@ func Identity(args []string) {
}
}
case "makeroot":
if len(args) >= 2 {
//id := readIdentity(args[1])
}
}
}
Help()

View file

@ -28,7 +28,7 @@ func Join(basePath, authToken string, args []string) {
os.Exit(1)
}
if len(args[0]) != 16 {
if len(args[0]) != zerotier.NetworkIDStringLength {
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
os.Exit(1)
}

View file

@ -17,6 +17,7 @@ import (
"fmt"
"os"
"strconv"
"zerotier/pkg/zerotier"
)
// Leave CLI command
@ -26,7 +27,7 @@ func Leave(basePath, authToken string, args []string) {
os.Exit(1)
}
if len(args[0]) != 16 {
if len(args[0]) != zerotier.NetworkIDStringLength {
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
os.Exit(1)
}

View file

@ -28,7 +28,7 @@ func Network(basePath, authToken string, args []string, jsonOutput bool) {
os.Exit(1)
}
if len(args[0]) != 16 {
if len(args[0]) != zerotier.NetworkIDStringLength {
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
os.Exit(1)
}

View file

@ -1,52 +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"
)
// SetRoot CLI command, used for addroot and removeroot.
func SetRoot(basePath, authToken string, args []string, root bool) {
if len(args) < 1 || len(args) > 2 {
Help()
os.Exit(1)
}
id := readIdentity(args[0])
if id == nil {
fmt.Printf("ERROR: invalid identity '%s' (tried literal or reading as file)\n",args[0])
os.Exit(1)
}
var bootstrap *zerotier.InetAddress
if len(args) == 2 {
bootstrap = zerotier.NewInetAddressFromString(args[1])
if bootstrap == nil || bootstrap.Nil() {
fmt.Printf("ERROR: invalid bootstrap address '%s'\n",args[1])
os.Exit(1)
}
}
var peer zerotier.PeerMutableFields
peer.Identity = id
peer.Bootstrap = bootstrap
peer.Root = &root
apiPost(basePath, authToken, "/peer/"+id.Address().String(), &peer, nil)
fmt.Printf("OK %s", id.String())
os.Exit(0)
}

View file

@ -74,13 +74,14 @@ func main() {
} else {
runtime.GOMAXPROCS(1)
}
debug.SetGCPercent(25)
debug.SetGCPercent(20)
globalOpts := flag.NewFlagSet("global", flag.ContinueOnError)
hflag := globalOpts.Bool("h", false, "") // support -h to be canonical with other Unix utilities
jflag := globalOpts.Bool("j", false, "")
pflag := globalOpts.String("p", "", "")
tflag := globalOpts.String("t", "", "")
tTflag := globalOpts.String("T", "", "")
err := globalOpts.Parse(os.Args[1:])
if err != nil {
cli.Help()
@ -98,11 +99,6 @@ func main() {
cmdArgs = args[1:]
}
if *hflag {
cli.Help()
os.Exit(0)
}
basePath := zerotier.PlatformDefaultHomePath
if len(*pflag) > 0 {
basePath = *pflag
@ -110,7 +106,14 @@ func main() {
var authToken string
if len(*tflag) > 0 {
authToken = *tflag
at, err := ioutil.ReadFile(*tflag)
if err != nil || len(at) == 0 {
fmt.Println("FATAL: unable to read API authorization token from file '" + *tflag + "'")
os.Exit(1)
}
authToken = strings.TrimSpace(string(at))
} else if len(*tTflag) > 0 {
authToken = strings.TrimSpace(*tTflag)
} else {
authToken = readAuthToken(basePath)
}
@ -125,38 +128,36 @@ func main() {
os.Exit(0)
case "service":
cli.Service(basePath, authToken, cmdArgs)
case "status":
case "status", "info":
authTokenRequired(authToken)
cli.Status(basePath, authToken, cmdArgs, *jflag)
case "peers", "listpeers":
case "peers", "listpeers", "lspeers":
authTokenRequired(authToken)
cli.Peers(basePath, authToken, cmdArgs, *jflag, false)
case "roots", "listroots":
case "roots", "listroots", "lsroots":
authTokenRequired(authToken)
cli.Peers(basePath, authToken, cmdArgs, *jflag, true)
case "addroot":
authTokenRequired(authToken)
cli.SetRoot(basePath, authToken, cmdArgs, true)
// TODO
case "removeroot":
authTokenRequired(authToken)
cli.SetRoot(basePath, authToken, cmdArgs, false)
case "identity":
cli.Identity(cmdArgs)
case "networks", "listnetworks":
authTokenRequired(authToken)
cli.Networks(basePath, authToken, cmdArgs, *jflag)
case "network":
authTokenRequired(authToken)
cli.Network(basePath, authToken, cmdArgs, *jflag)
// TODO
case "join":
authTokenRequired(authToken)
cli.Join(basePath, authToken, cmdArgs)
case "leave":
authTokenRequired(authToken)
cli.Leave(basePath, authToken, cmdArgs)
case "networks", "listnetworks":
authTokenRequired(authToken)
cli.Networks(basePath, authToken, cmdArgs, *jflag)
case "network":
authTokenRequired(authToken)
cli.Network(basePath, authToken, cmdArgs, *jflag)
case "set":
authTokenRequired(authToken)
cli.Set(basePath, authToken, cmdArgs)
case "identity":
cli.Identity(cmdArgs)
}
cli.Help()

View file

@ -20,6 +20,7 @@ import (
"bytes"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"runtime"
"strings"
@ -241,6 +242,31 @@ func (id *Identity) Verify(msg, sig []byte) bool {
return C.ZT_Identity_verify(id.cid, dataP, C.uint(len(msg)), unsafe.Pointer(&sig[0]), C.uint(len(sig))) != 0
}
// MakeRoot generates a root spec consisting of a serialized identity and a root locator.
func (id *Identity) MakeRoot(addresses []InetAddress) ([]byte, error) {
if len(addresses) == 0 {
return nil, errors.New("at least one static address must be specified for a root")
}
id.cIdentity()
if uintptr(id.cid) == 0 {
return nil, errors.New("error initializing ZT_Identity")
}
ss := make([]C.sockaddr_storage, len(addresses))
for i := range addresses {
if !makeSockaddrStorage(addresses[i].IP, addresses[i].Port, &ss[i]) {
return nil, errors.New("invalid address in address list")
}
}
var buf [8192]byte
rl := C.ZT_Identity_makeRootSpecification(id.cid, C.int64_t(TimeMs()), &ss[0], C.uint(len(ss)), &buf[0], 8192)
if rl <= 0 {
return nil, errors.New("unable to make root specification (does identity contain a secret key?)")
}
return buf[0:int(rl)], nil
}
// Equals performs a deep equality test between this and another identity
func (id *Identity) Equals(id2 *Identity) bool {
if id2 == nil {

View file

@ -24,9 +24,6 @@ import (
type LocalConfigPhysicalPathConfiguration struct {
// Blacklist flags this path as unusable for ZeroTier traffic
Blacklist bool
// TrustedPathID identifies a path for unencrypted/unauthenticated traffic
TrustedPathID uint64
}
// LocalConfigVirtualAddressConfiguration contains settings for virtual addresses
@ -35,14 +32,6 @@ type LocalConfigVirtualAddressConfiguration struct {
Try []InetAddress `json:"try,omitempty"`
}
// ExternalAddress is an externally visible address
type ExternalAddress struct {
InetAddress
// Permanent indicates that this address should be incorporated into this node's Locator
Permanent bool `json:"permanent"`
}
// LocalConfigSettings contains node settings
type LocalConfigSettings struct {
// PrimaryPort is the main UDP port and must be set.
@ -60,14 +49,14 @@ type LocalConfigSettings struct {
// LogSizeMax is the maximum size of the infoLog in kilobytes or 0 for no limit and -1 to disable logging
LogSizeMax int `json:"logSizeMax"`
// IP/port to bind for TCP access to control API (disabled if null)
// IP/port to bind for TCP access to control API (TCP API port disabled if null)
APITCPBindAddress *InetAddress `json:"apiTCPBindAddress,omitempty"`
// InterfacePrefixBlacklist are prefixes of physical network interface names that won't be used by ZeroTier (e.g. "lo" or "utun")
InterfacePrefixBlacklist []string `json:"interfacePrefixBlacklist,omitempty"`
// ExplicitAddresses are explicit IP/port addresses to advertise to other nodes, such as externally mapped ports on a router
ExplicitAddresses []ExternalAddress `json:"explicitAddresses,omitempty"`
ExplicitAddresses []InetAddress `json:"explicitAddresses,omitempty"`
}
// LocalConfig is the local.conf file and stores local settings for the node.
@ -97,22 +86,18 @@ func (lc *LocalConfig) Read(p string, saveDefaultsIfNotExist bool, isTotallyNewN
lc.Virtual = make(map[Address]LocalConfigVirtualAddressConfiguration)
lc.Network = make(map[NetworkID]NetworkLocalSettings)
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))]
lc.Settings.PortSearch = true
lc.Settings.PortMapping = true
lc.Settings.LogSizeMax = 128
if !isTotallyNewNode {
if !isTotallyNewNode && runtime.GOOS != "darwin" && runtime.GOOS != "windows" {
// If this doesn't look like a new node and it's not a desktop OS, go ahead
// and bind the local TCP API port so as not to break scripts.
lc.Settings.APITCPBindAddress = NewInetAddressFromString("127.0.0.1/9993")
}
switch runtime.GOOS {
case "windows":
lc.Settings.InterfacePrefixBlacklist = []string{"loopback"}

View file

@ -47,6 +47,9 @@ var nullLogger = log.New(ioutil.Discard, "", 0)
// Network status states
const (
NetworkIDStringLength = 16
AddressStringLength = 10
NetworkStatusRequestConfiguration int = C.ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION
NetworkStatusOK int = C.ZT_NETWORK_STATUS_OK
NetworkStatusAccessDenied int = C.ZT_NETWORK_STATUS_ACCESS_DENIED

View file

@ -261,7 +261,15 @@ public:
};
/**
* Encryptor for GMAC-SIV
* Encryptor for AES-GMAC-SIV.
*
* Encryption requires two passes. The first pass starts after init
* with aad (if any) followed by update1() and finish1(). Then the
* update2() and finish2() methods must be used over the same data
* (but NOT AAD) again.
*
* This supports encryption of a maximum of 2^31 bytes of data per
* call to init().
*/
class GMACSIVEncryptor
{
@ -294,12 +302,12 @@ public:
}
/**
* Process AAD (additional authenticated data) that is not being encrypted
* Process AAD (additional authenticated data) that is not being encrypted.
*
* This must be called prior to update1, finish1, etc. if there is AAD to include
* in the MAC that is not included in the plaintext.
* If such data exists this must be called before update1() and finish1().
*
* This currently only supports one chunk of AAD. Don't call multiple times per message.
* Note: current code only supports one single chunk of AAD. Don't call this
* multiple times per message.
*
* @param aad Additional authenticated data
* @param len Length of AAD in bytes
@ -336,15 +344,22 @@ public:
// Compute 128-bit GMAC tag.
_gmac.finish(reinterpret_cast<uint8_t *>(tmp));
// Truncate to 64 bits, concatenate after 64-bit message IV, and encrypt with AES.
// Shorten to 64 bits, concatenate with message IV, and encrypt with AES to
// yield the CTR IV and opaque IV/MAC blob. In ZeroTier's use of GMAC-SIV
// this get split into the packet ID (64 bits) and the MAC (64 bits) in each
// packet and then recombined on receipt for legacy reasons (but with no
// cryptographic or performance impact).
_tag[1] = tmp[0] ^ tmp[1];
_ctr._aes.encrypt(_tag,_tag);
// Get CTR IV and 32-bit counter. The most significant bit of the 32-bit counter
// is masked to zero so the counter will never overflow, but the remaining bits
// are taken from the encrypted tag as they can count as additional bits of
// entropy for the CTR IV. We don't technically count these in figuring our
// worst case scenario bound, but they could be argued to add a little margin.
// Initialize CTR with 96-bit CTR nonce and 32-bit counter. The counter
// incorporates 31 more bits of entropy which should raise our security margin
// a bit, but this is not included in the worst case analysis of GMAC-SIV.
// The most significant bit of the counter is masked to zero to allow up to
// 2^31 bytes to be encrypted before the counter loops. Some CTR implementations
// increment the whole big-endian 128-bit integer in which case this could be
// used for more than 2^31 bytes, but ours does not for performance reasons
// and so 2^31 should be considered the input limit.
tmp[0] = _tag[0];
tmp[1] = _tag[1] & ZT_CONST_TO_BE_UINT64(0xffffffff7fffffffULL);
_ctr.init(reinterpret_cast<const uint8_t *>(tmp),_output);
@ -386,7 +401,9 @@ public:
};
/**
* Decryptor for GMAC-SIV
* Decryptor for AES-GMAC-SIV.
*
* GMAC-SIV decryption is single-pass. AAD (if any) must be processed first.
*/
class GMACSIVDecryptor
{

View file

@ -32,7 +32,6 @@ set(core_headers
OS.hpp
Path.hpp
Peer.hpp
PeerList.hpp
Poly1305.hpp
Protocol.hpp
RuntimeEnvironment.hpp

View file

@ -37,7 +37,7 @@ namespace ZeroTier {
* compatibility.
*
* Use of the append functions is faster than building and then encoding a
* dictionary.
* dictionary for creating outbound packets.
*/
class Dictionary
{

View file

@ -19,23 +19,15 @@
#include <iterator>
#include <algorithm>
#include <memory>
#include <cstring>
#include <cstdlib>
namespace ZeroTier {
/**
* FCV is a Fixed Capacity Vector
*
* Attempts to resize, push, or access this vector beyond its capacity will
* silently fail. The [] operator is NOT bounds checked!
*
* This doesn't implement everything in std::vector, just what we need. It
* also adds a few special things for use in ZT core code.
*
* Note that an FCV will be TriviallyCopyable IF and only if its contained
* type is TriviallyCopyable. There's a const static checker for this.
*
* @tparam T Type to contain
* @tparam C Maximum capacity of vector
*/
@ -46,11 +38,11 @@ public:
typedef T * iterator;
typedef const T * const_iterator;
ZT_INLINE FCV() noexcept : _s(0) {} // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
ZT_INLINE FCV(const FCV &v) : _s(0) { *this = v; } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
ZT_INLINE FCV() noexcept : _s(0) {}
ZT_INLINE FCV(const FCV &v) : _s(0) { *this = v; }
template<typename I>
ZT_INLINE FCV(I i,I end) : // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
ZT_INLINE FCV(I i,I end) :
_s(0)
{
while (i != end) {
@ -63,7 +55,7 @@ public:
ZT_INLINE FCV &operator=(const FCV &v)
{
if (&v != this) {
if (likely(&v != this)) {
this->clear();
const unsigned int s = v._s;
_s = s;
@ -85,25 +77,7 @@ public:
}
/**
* Clear without calling destructors (same as unsafeResize(0))
*/
ZT_INLINE void unsafeClear() noexcept { _s = 0; }
/**
* This does a straight copy of one vector's data to another
*
* @tparam C2 Inferred capacity of other vector
* @param v Other vector to copy to this one
*/
template<unsigned int C2>
ZT_INLINE void unsafeAssign(const FCV<T,C2> &v) noexcept
{
_s = ((C2 > C)&&(v._s > C)) ? C : v._s;
Utils::copy(_m,v._m,_s * sizeof(T));
}
/**
* Move contents from this vector to another and clear this vector
* Move contents from this vector to another and clear this vector.
*
* @param v Target vector
*/
@ -114,18 +88,29 @@ public:
}
ZT_INLINE iterator begin() noexcept { return reinterpret_cast<T *>(_m); }
ZT_INLINE const_iterator begin() const noexcept { return reinterpret_cast<const T *>(_m); }
ZT_INLINE iterator end() noexcept { return reinterpret_cast<T *>(_m) + _s; }
ZT_INLINE const_iterator begin() const noexcept { return reinterpret_cast<const T *>(_m); }
ZT_INLINE const_iterator end() const noexcept { return reinterpret_cast<const T *>(_m) + _s; }
ZT_INLINE T &operator[](const unsigned int i) noexcept { return reinterpret_cast<T *>(_m)[i]; }
ZT_INLINE const T &operator[](const unsigned int i) const noexcept { return reinterpret_cast<T *>(_m)[i]; }
ZT_INLINE T &operator[](const unsigned int i)
{
if (likely(i < _s))
return reinterpret_cast<T *>(_m)[i];
throw std::out_of_range("i > capacity");
}
ZT_INLINE const T &operator[](const unsigned int i) const
{
if (likely(i < _s))
return reinterpret_cast<const T *>(_m)[i];
throw std::out_of_range("i > capacity");
}
static constexpr unsigned int capacity() noexcept { return C; }
ZT_INLINE unsigned int size() const noexcept { return _s; }
ZT_INLINE bool empty() const noexcept { return (_s == 0); }
ZT_INLINE T *data() noexcept { return reinterpret_cast<T *>(_m); }
ZT_INLINE const T *data() const noexcept { return reinterpret_cast<const T *>(_m); }
static constexpr unsigned int capacity() noexcept { return C; }
/**
* Push a value onto the back of this vector
@ -136,8 +121,9 @@ public:
*/
ZT_INLINE void push_back(const T &v)
{
if (_s < C)
if (likely(_s < C))
new (reinterpret_cast<T *>(_m) + _s++) T(v);
else throw std::out_of_range("capacity exceeded");
}
/**
@ -147,7 +133,7 @@ public:
*/
ZT_INLINE T &push()
{
if (_s < C) {
if (likely(_s < C)) {
return *(new(reinterpret_cast<T *>(_m) + _s++) T());
} else {
return *(reinterpret_cast<T *>(_m) + (C - 1));
@ -161,7 +147,7 @@ public:
*/
ZT_INLINE T &push(const T &v)
{
if (_s < C) {
if (likely(_s < C)) {
return *(new(reinterpret_cast<T *>(_m) + _s++) T(v));
} else {
T &tmp = *(reinterpret_cast<T *>(_m) + (C - 1));
@ -175,7 +161,7 @@ public:
*/
ZT_INLINE void pop_back()
{
if (_s != 0)
if (likely(_s != 0))
(reinterpret_cast<T *>(_m) + --_s)->~T();
}
@ -186,8 +172,8 @@ public:
*/
ZT_INLINE void resize(unsigned int ns)
{
if (ns > C)
ns = C;
if (unlikely(ns > C))
throw std::out_of_range("capacity exceeded");
unsigned int s = _s;
while (s < ns)
new(reinterpret_cast<T *>(_m) + s++) T();
@ -196,16 +182,6 @@ public:
_s = s;
}
/**
* Resize without calling any constructors or destructors on T
*
* This must only be called if T is a primitive type or is TriviallyCopyable and
* safe to initialize from undefined contents.
*
* @param ns New size (clipped to C if larger than capacity)
*/
ZT_INLINE void unsafeResize(const unsigned int ns) noexcept { _s = (ns > C) ? C : ns; }
/**
* This is a bounds checked auto-resizing variant of the [] operator
*
@ -267,8 +243,12 @@ public:
ZT_INLINE bool operator>=(const FCV &v) const noexcept { return !(*this < v); }
private:
unsigned int _s;
#ifdef _MSC_VER
uint8_t _m[sizeof(T) * C];
#else
__attribute__((aligned(16))) uint8_t _m[sizeof(T) * C];
#endif
unsigned int _s;
};
} // namespace ZeroTier

View file

@ -631,11 +631,13 @@ const ZT_Fingerprint *ZT_Identity_fingerprint(const ZT_Identity *id)
int ZT_Identity_makeRootSpecification(ZT_Identity *id,int64_t ts,struct sockaddr_storage *addrs,unsigned int addrcnt,void *rootSpecBuf,unsigned int rootSpecBufSize)
{
if ((!id)||(!addrs)||(!addrcnt)||(!rootSpecBuf))
return -1;
ZeroTier::Vector<ZeroTier::Endpoint> endpoints;
endpoints.reserve(addrcnt);
for(unsigned int i=0;i<addrcnt;++i)
endpoints.push_back(ZeroTier::Endpoint(ZeroTier::asInetAddress(addrs[i]));
return ZeroTier::Locator::makeRootSpecification(reinterpret_cast<const ZeroTier::Identity *>(id),endpoints,rootSpecBuf,rootSpecBufSize);
endpoints.push_back(ZeroTier::Endpoint(ZeroTier::asInetAddress(addrs[i])));
return ZeroTier::Locator::makeRootSpecification(*reinterpret_cast<const ZeroTier::Identity *>(id),ts,endpoints,rootSpecBuf,rootSpecBufSize);
}
ZT_SDK_API void ZT_Identity_delete(ZT_Identity *id)

View file

@ -261,9 +261,9 @@ public:
{
switch (as.ss.ss_family) {
case AF_INET:
return Utils::ntoh((uint16_t) as.sa_in.sin_port);
return Utils::ntoh((uint16_t)as.sa_in.sin_port);
case AF_INET6:
return Utils::ntoh((uint16_t) as.sa_in6.sin6_port);
return Utils::ntoh((uint16_t)as.sa_in6.sin6_port);
default:
return 0;
}

View file

@ -14,8 +14,6 @@
#ifndef ZT_MEMBERSHIP_HPP
#define ZT_MEMBERSHIP_HPP
#include <cstdint>
#include "Constants.hpp"
#include "Credential.hpp"
#include "Containers.hpp"

View file

@ -44,7 +44,7 @@ public:
* @param now Start time
*/
ZT_INLINE Meter() noexcept
{} // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init,hicpp-use-equals-default,modernize-use-equals-default)
{}
/**
* Add a measurement

View file

@ -14,13 +14,6 @@
#ifndef ZT_NETWORKCONFIG_HPP
#define ZT_NETWORKCONFIG_HPP
#include <cstdint>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <stdexcept>
#include <algorithm>
#include "Constants.hpp"
#include "InetAddress.hpp"
#include "MulticastGroup.hpp"
@ -34,6 +27,10 @@
#include "Utils.hpp"
#include "Trace.hpp"
#include "TriviallyCopyable.hpp"
#include "Containers.hpp"
#include <stdexcept>
#include <algorithm>
namespace ZeroTier {

View file

@ -14,8 +14,6 @@
#ifndef ZT_NETWORKCONFIGMASTER_HPP
#define ZT_NETWORKCONFIGMASTER_HPP
#include <cstdint>
#include "Constants.hpp"
#include "Dictionary.hpp"
#include "NetworkConfig.hpp"

View file

@ -341,12 +341,10 @@ ZT_ResultCode Node::multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,u
ZT_ResultCode Node::addRoot(void *tPtr,const void *rdef,unsigned int rdeflen)
{
std::pair<Identity,Locator> r(Locator::parseRootSpecification(rdef,rdeflen));
if (r.first) {
RR->topology->addRoot(tPtr,r.first,r.second);
return ZT_RESULT_OK;
}
if ((!rdef)||(rdeflen == 0))
return ZT_RESULT_ERROR_BAD_PARAMETER;
std::pair<Identity,Locator> r(Locator::parseRootSpecification(rdef,rdeflen));
return ((r.first)&&(RR->topology->addRoot(tPtr,r.first,r.second))) ? ZT_RESULT_OK : ZT_RESULT_ERROR_BAD_PARAMETER;
}
ZT_ResultCode Node::removeRoot(void *tPtr,const ZT_Fingerprint *fp)

View file

@ -130,7 +130,7 @@ public:
m_uPtr,
tPtr,
localSocket,
reinterpret_cast<const struct sockaddr_storage *>(&addr),
&addr.as.ss,
data,
len,
ttl) == 0);
@ -306,9 +306,9 @@ public:
bool localControllerHasAuthorized(int64_t now,uint64_t nwid,const Address &addr) const;
// Implementation of NetworkController::Sender interface
virtual void ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &destination,const NetworkConfig &nc,bool sendLegacyFormatConfig); // NOLINT(cppcoreguidelines-explicit-virtual-functions,hicpp-use-override,modernize-use-override)
virtual void ncSendRevocation(const Address &destination,const Revocation &rev); // NOLINT(cppcoreguidelines-explicit-virtual-functions,hicpp-use-override,modernize-use-override)
virtual void ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &destination,NetworkController::ErrorCode errorCode); // NOLINT(cppcoreguidelines-explicit-virtual-functions,hicpp-use-override,modernize-use-override)
virtual void ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &destination,const NetworkConfig &nc,bool sendLegacyFormatConfig);
virtual void ncSendRevocation(const Address &destination,const Revocation &rev);
virtual void ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &destination,NetworkController::ErrorCode errorCode);
private:
RuntimeEnvironment m_RR;

View file

@ -41,7 +41,7 @@ class Path
friend class Defragmenter;
public:
ZT_INLINE Path(const int64_t l,const InetAddress &r) noexcept : // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
ZT_INLINE Path(const int64_t l,const InetAddress &r) noexcept :
m_localSocket(l),
m_lastIn(0),
m_lastOut(0),

View file

@ -250,7 +250,7 @@
#define ZT_PROTO_PACKET_VERB_INDEX 27
#define ZT_PROTO_HELLO_NODE_META_INSTANCE_ID "i"
#define ZT_PROTO_HELLO_NODE_META_PREFERRED_SYMMETRIC "a"
#define ZT_PROTO_HELLO_NODE_META_PREFERRED_CIPHER_MODE "a"
#define ZT_PROTO_HELLO_NODE_META_LOCATOR "l"
#define ZT_PROTO_HELLO_NODE_META_SOFTWARE_VENDOR "s"
#define ZT_PROTO_HELLO_NODE_META_COMPLIANCE "c"
@ -340,7 +340,7 @@ enum Verb
* Dictionary fields (defines start with ZT_PROTO_HELLO_NODE_META_):
*
* INSTANCE_ID - a 64-bit unique value generated on each node start
* PREFERRED_SYMMETRIC - preferred symmetric encryption mode
* PREFERRED_CIPHER_MODE - preferred symmetric encryption mode
* LOCATOR - signed record enumerating this node's trusted contact points
* EPHEMERAL_PUBLIC - Ephemeral public key(s)
*
@ -419,10 +419,10 @@ enum Verb
/**
* Relay-mediated NAT traversal or firewall punching initiation:
* <[1] flags (unused, currently 0)>
* <[1] flags>
* <[5] ZeroTier address of other peer>
* <[2] 16-bit number of endpoints where peer might be reached>
* <[...] endpoints to attempt>
* [<[...] endpoints to attempt>]
*
* Legacy packet format for pre-2.x peers:
* <[1] flags (unused, currently 0)>

View file

@ -14,11 +14,6 @@
#ifndef ZT_REVOCATION_HPP
#define ZT_REVOCATION_HPP
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdint>
#include "Constants.hpp"
#include "Credential.hpp"
#include "Address.hpp"

View file

@ -14,11 +14,6 @@
#ifndef ZT_TAG_HPP
#define ZT_TAG_HPP
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "Constants.hpp"
#include "Credential.hpp"
#include "C25519.hpp"

View file

@ -71,14 +71,15 @@ struct p_RootSortComparisonOperator
}
};
void Topology::addRoot(void *const tPtr, const Identity &id, const Locator &loc)
bool Topology::addRoot(void *const tPtr, const Identity &id, const Locator &loc)
{
if (id == RR->identity)
return;
if ((id == RR->identity) || (!id) || (!loc) || (!loc.verify(id)) || (!id.locallyValidate()))
return false;
RWMutex::Lock l1(m_peers_l);
m_roots[id] = loc;
m_updateRootPeers(tPtr);
m_writeRootList(tPtr);
return true;
}
bool Topology::removeRoot(void *const tPtr, const Fingerprint &fp)

View file

@ -185,11 +185,15 @@ public:
/**
* Add or update a root server and its locator
*
* This also validates the identity and checks the locator signature,
* returning false if either of these is not valid.
*
* @param tPtr Thread pointer
* @param id Root identity
* @param loc Root locator
* @return True if identity and locator are valid and root was added / updated
*/
void addRoot(void *tPtr,const Identity &id,const Locator &loc);
bool addRoot(void *tPtr,const Identity &id,const Locator &loc);
/**
* Remove a root server's identity from the root server set

View file

@ -53,62 +53,6 @@ public:
Utils::zero<sizeof(T)>(&obj);
}
/**
* Copy a TriviallyCopyable object
*
* @tparam T Automatically inferred type of destination
* @param dest Destination TriviallyCopyable object
* @param src Source TriviallyCopyable object
*/
template<typename T>
static ZT_INLINE void memoryCopy(T *dest,const T *src) noexcept
{
mustBeTriviallyCopyable(dest);
Utils::copy<sizeof(T)>(dest,src);
}
/**
* Copy a TriviallyCopyable object
*
* @tparam T Automatically inferred type of destination
* @param dest Destination TriviallyCopyable object
* @param src Source TriviallyCopyable object
*/
template<typename T>
static ZT_INLINE void memoryCopy(T *dest,const T &src) noexcept
{
mustBeTriviallyCopyable(src);
Utils::copy<sizeof(T)>(dest,&src);
}
/**
* Copy a TriviallyCopyable object
*
* @tparam T Automatically inferred type of destination
* @param dest Destination TriviallyCopyable object
* @param src Source TriviallyCopyable object
*/
template<typename T>
static ZT_INLINE void memoryCopy(T &dest,const T *src) noexcept
{
mustBeTriviallyCopyable(dest);
Utils::copy<sizeof(T)>(&dest,src);
}
/**
* Copy a TriviallyCopyable object
*
* @tparam T Automatically inferred type of destination
* @param dest Destination TriviallyCopyable object
* @param src Source TriviallyCopyable object
*/
template<typename T>
static ZT_INLINE void memoryCopy(T &dest,const T &src) noexcept
{
mustBeTriviallyCopyable(dest);
Utils::copy<sizeof(T)>(&dest,&src);
}
private:
static ZT_INLINE void mustBeTriviallyCopyable(const TriviallyCopyable &) noexcept {}
static ZT_INLINE void mustBeTriviallyCopyable(const TriviallyCopyable *) noexcept {}