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

@ -27,42 +27,43 @@ Licensed under the ZeroTier BSL (see LICENSE.txt)
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
-j Output raw JSON where applicable
-p <path> Use alternate base path
-t <path> Load secret auth token from a file
-T <token> Set secret auth token on command line
Commands:
help Show this help
version Print version
service Start as service
status Show node status, identity, and config
peers List all VL1 peers
roots List root peers
addroot <path/URL to spec> Add root
removeroot <address> Remove a peer from the root list
join <network ID> [fingerprint] Join a virtual network
leave <network ID> Leave a virtual network
networks List VL2 virtual networks
network <network ID> Show verbose network info
set <network ID> [option] [value] Get or set a network config option
manageips <boolean> Is IP management allowed?
manageroutes <boolean> Is route management allowed?
globalips <boolean> Allow assignment of global IPs?
globalroutes <boolean> Can global IP space routes be set?
defaultroute <boolean> Can default route be overridden?
set [option] [value] Get or set a service config option
port <port> Primary P2P port
secondaryport <port/0> Secondary P2P port (0 to disable)
blacklist cidr <IP/bits> <boolean> Toggle physical path blacklisting
blacklist if <prefix> <boolean> Toggle interface prefix blacklisting
portmap <boolean> Toggle use of uPnP or NAT-PMP
identity <command> [args] Identity management commands
new [c25519|p384] Create identity pair (default: c25519)
getpublic <identity> Extract only public part of identity
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)
help Show this help
version Print version
service Start as service
status Show node status, identity, and config
peers List all VL1 peers
roots List root peers
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
networks List VL2 virtual networks
network <network ID> Show verbose network info
set <network ID> [option] [value] Get or set a network config option
manageips <boolean> Is IP management allowed?
manageroutes <boolean> Is route management allowed?
globalips <boolean> Allow assignment of global IPs?
globalroutes <boolean> Can global IP space routes be set?
defaultroute <boolean> Can default route be overridden?
set [option] [value] Get or set a service config option
port <port> Primary P2P port
secondaryport <port/0> Secondary P2P port (0 to disable)
blacklist cidr <IP/bits> <boolean> Toggle physical path blacklisting
blacklist if <prefix> <boolean> Toggle interface prefix blacklisting
portmap <boolean> Toggle use of uPnP or NAT-PMP
identity <command> [args] Identity management commands
new [c25519|p384] Create identity pair (default: c25519)
getpublic <identity> Extract only public part of identity
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)
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.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)
{
if ((!rdef)||(rdeflen == 0))
return ZT_RESULT_ERROR_BAD_PARAMETER;
std::pair<Identity,Locator> r(Locator::parseRootSpecification(rdef,rdeflen));
if (r.first) {
RR->topology->addRoot(tPtr,r.first,r.second);
return ZT_RESULT_OK;
}
return ZT_RESULT_ERROR_BAD_PARAMETER;
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

@ -327,10 +327,10 @@ public:
/**
* Check whether a key is ephemeral
*
*
* This is used to check whether a packet is received with forward secrecy enabled
* or not.
*
*
* @param k Key to check
* @return True if this key is ephemeral, false if it's the long-lived identity key
*/

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 {}