mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-09-06 14:52:54 +02:00
A bunch of warning removal, build fixes, and cleanup.
This commit is contained in:
parent
1f9717250c
commit
6051c973d3
32 changed files with 222 additions and 330 deletions
|
@ -14,6 +14,7 @@
|
||||||
#include "MIMC52.hpp"
|
#include "MIMC52.hpp"
|
||||||
#include "SHA512.hpp"
|
#include "SHA512.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
|
#include "Salsa20.hpp"
|
||||||
|
|
||||||
// This gets defined on any architecture whose FPU is not capable of doing the mulmod52() FPU trick.
|
// This gets defined on any architecture whose FPU is not capable of doing the mulmod52() FPU trick.
|
||||||
//#define ZT_MIMC52_NO_FPU
|
//#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
|
} // 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 mimc52Delay(const void *const salt,const unsigned int saltSize,const unsigned long rounds)
|
||||||
{
|
{
|
||||||
uint64_t hash[6];
|
uint64_t hash[8];
|
||||||
SHA384(hash,salt,saltSize);
|
SHA512(hash,salt,saltSize);
|
||||||
|
|
||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
#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;
|
uint64_t x = hash[1] % p;
|
||||||
#else
|
#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;
|
uint64_t x = Utils::swapBytes(hash[1]) % p;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Speck128<8> roundConstantGenerator(hash + 2);
|
|
||||||
const uint64_t e = ((p * 2) - 1) / 3;
|
const uint64_t e = ((p * 2) - 1) / 3;
|
||||||
const uint64_t m52 = 0xfffffffffffffULL;
|
const uint64_t m52 = 0xfffffffffffffULL;
|
||||||
const uint64_t rmin1 = rounds - 1;
|
const uint32_t rminus1 = rounds - 1;
|
||||||
const uint64_t sxx = hash[4];
|
for(uint32_t r=0;r<rounds;++r) {
|
||||||
#pragma unroll 16
|
x = (x - (uint64_t)sy) & m52;
|
||||||
for(unsigned long r=0;r<rounds;++r) {
|
|
||||||
uint64_t sx = sxx,sy = rmin1 - r;
|
|
||||||
//roundConstantGenerator.encryptXY(sx,sy);
|
|
||||||
x = (x - sy) & m52;
|
|
||||||
x = modpow52(x,e,p);
|
x = modpow52(x,e,p);
|
||||||
}
|
}
|
||||||
|
|
||||||
return x;
|
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];
|
uint64_t hash[6];
|
||||||
SHA384(hash,salt,saltSize);
|
SHA384(hash,salt,saltSize);
|
||||||
|
|
||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
uint64_t p = s_mimc52Primes[hash[0] & 511U];
|
const uint64_t p = s_mimc52Primes[Utils::swapBytes(hash[0]) & 511U];
|
||||||
uint64_t x = hash[1] % p;
|
|
||||||
#else
|
|
||||||
uint64_t p = s_mimc52Primes[Utils::swapBytes(hash[0]) & 511U];
|
|
||||||
uint64_t x = Utils::swapBytes(hash[1]) % p;
|
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
|
#endif
|
||||||
|
|
||||||
//Speck128<8> roundConstantGenerator(hash + 2);
|
|
||||||
const uint64_t m52 = 0xfffffffffffffULL;
|
const uint64_t m52 = 0xfffffffffffffULL;
|
||||||
uint64_t y = proof & m52;
|
uint64_t y = proof & m52;
|
||||||
const uint64_t sxx = hash[4];
|
#ifndef ZT_MIMC52_NO_FPU
|
||||||
#if !defined(ZT_MIMC52_NO_FPU)
|
double dy,ii,of,pp = (double)p;
|
||||||
double ii,of,pp = (double)p;
|
|
||||||
uint64_t oi,one = 1;
|
uint64_t oi,one = 1;
|
||||||
#endif
|
#endif
|
||||||
#pragma unroll 16
|
|
||||||
for(unsigned long r=0;r<rounds;++r) {
|
for(unsigned long r=0;r<rounds;++r) {
|
||||||
uint64_t sx = sxx,sy = r;
|
|
||||||
//roundConstantGenerator.encryptXY(sx,sy);
|
|
||||||
#ifdef ZT_MIMC52_NO_FPU
|
#ifdef ZT_MIMC52_NO_FPU
|
||||||
#ifdef x64_cubemod
|
#ifdef x64_cubemod
|
||||||
x64_cubemod(y,p);
|
x64_cubemod(y,p);
|
||||||
|
@ -160,18 +153,19 @@ bool mimc52Verify(const void *const salt,const unsigned int saltSize,unsigned lo
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
// mulmod52(mulmod52(y,y,p),y,p)
|
// mulmod52(mulmod52(y,y,p),y,p)
|
||||||
of = (double)y;
|
dy = (double)y;
|
||||||
|
of = dy;
|
||||||
oi = y;
|
oi = y;
|
||||||
ii = (of * of) / pp;
|
ii = (of * of) / pp;
|
||||||
y *= oi;
|
y *= oi;
|
||||||
y -= ((uint64_t)ii - one) * p;
|
y -= ((uint64_t)ii - one) * p;
|
||||||
//y %= p;
|
//y %= p; // does not seem to be necessary
|
||||||
ii = ((double)y * of) / pp;
|
ii = (dy * of) / pp;
|
||||||
y *= oi;
|
y *= oi;
|
||||||
y -= ((uint64_t)ii - one) * p;
|
y -= ((uint64_t)ii - one) * p;
|
||||||
y %= p;
|
y %= p;
|
||||||
#endif
|
#endif
|
||||||
y = (y + sy) & m52;
|
y = (y + (uint64_t)sy) & m52;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (y % p) == x;
|
return (y % p) == x;
|
||||||
|
|
|
@ -27,42 +27,43 @@ Licensed under the ZeroTier BSL (see LICENSE.txt)
|
||||||
Usage: zerotier [-options] <command> [command args]
|
Usage: zerotier [-options] <command> [command args]
|
||||||
|
|
||||||
Global Options:
|
Global Options:
|
||||||
-j Output raw JSON where applicable
|
-j Output raw JSON where applicable
|
||||||
-p <path> Use alternate base path
|
-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:
|
Commands:
|
||||||
help Show this help
|
help Show this help
|
||||||
version Print version
|
version Print version
|
||||||
service Start as service
|
service Start as service
|
||||||
status Show node status, identity, and config
|
status Show node status, identity, and config
|
||||||
peers List all VL1 peers
|
peers List all VL1 peers
|
||||||
roots List root 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
|
removeroot <address> Remove a peer from the root list
|
||||||
join <network ID> [fingerprint] Join a virtual network
|
join <network ID> [fingerprint] Join a virtual network
|
||||||
leave <network ID> Leave a virtual network
|
leave <network ID> Leave a virtual network
|
||||||
networks List VL2 virtual networks
|
networks List VL2 virtual networks
|
||||||
network <network ID> Show verbose network info
|
network <network ID> Show verbose network info
|
||||||
set <network ID> [option] [value] Get or set a network config option
|
set <network ID> [option] [value] Get or set a network config option
|
||||||
manageips <boolean> Is IP management allowed?
|
manageips <boolean> Is IP management allowed?
|
||||||
manageroutes <boolean> Is route management allowed?
|
manageroutes <boolean> Is route management allowed?
|
||||||
globalips <boolean> Allow assignment of global IPs?
|
globalips <boolean> Allow assignment of global IPs?
|
||||||
globalroutes <boolean> Can global IP space routes be set?
|
globalroutes <boolean> Can global IP space routes be set?
|
||||||
defaultroute <boolean> Can default route be overridden?
|
defaultroute <boolean> Can default route be overridden?
|
||||||
set [option] [value] Get or set a service config option
|
set [option] [value] Get or set a service config option
|
||||||
port <port> Primary P2P port
|
port <port> Primary P2P port
|
||||||
secondaryport <port/0> Secondary P2P port (0 to disable)
|
secondaryport <port/0> Secondary P2P port (0 to disable)
|
||||||
blacklist cidr <IP/bits> <boolean> Toggle physical path blacklisting
|
blacklist cidr <IP/bits> <boolean> Toggle physical path blacklisting
|
||||||
blacklist if <prefix> <boolean> Toggle interface prefix blacklisting
|
blacklist if <prefix> <boolean> Toggle interface prefix blacklisting
|
||||||
portmap <boolean> Toggle use of uPnP or NAT-PMP
|
portmap <boolean> Toggle use of uPnP or NAT-PMP
|
||||||
identity <command> [args] Identity management commands
|
identity <command> [args] Identity management commands
|
||||||
new [c25519|p384] Create identity pair (default: c25519)
|
new [c25519|p384] Create identity pair (default: c25519)
|
||||||
getpublic <identity> Extract only public part of identity
|
getpublic <identity> Extract only public part of identity
|
||||||
validate <identity> Locally validate an identity
|
validate <identity> Locally validate an identity
|
||||||
sign <identity> <file> Sign a file with an identity's key
|
sign <identity> <file> Sign a file with an identity's key
|
||||||
verify <identity> <file> <sig> Verify a signature
|
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.
|
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
|
This is typically run from launchd (Mac), systemd or init (Linux), a Windows
|
||||||
|
|
|
@ -102,6 +102,11 @@ func Identity(args []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "makeroot":
|
||||||
|
if len(args) >= 2 {
|
||||||
|
//id := readIdentity(args[1])
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Help()
|
Help()
|
||||||
|
|
|
@ -28,7 +28,7 @@ func Join(basePath, authToken string, args []string) {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args[0]) != 16 {
|
if len(args[0]) != zerotier.NetworkIDStringLength {
|
||||||
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
|
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"zerotier/pkg/zerotier"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Leave CLI command
|
// Leave CLI command
|
||||||
|
@ -26,7 +27,7 @@ func Leave(basePath, authToken string, args []string) {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args[0]) != 16 {
|
if len(args[0]) != zerotier.NetworkIDStringLength {
|
||||||
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
|
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ func Network(basePath, authToken string, args []string, jsonOutput bool) {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args[0]) != 16 {
|
if len(args[0]) != zerotier.NetworkIDStringLength {
|
||||||
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
|
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
|
@ -74,13 +74,14 @@ func main() {
|
||||||
} else {
|
} else {
|
||||||
runtime.GOMAXPROCS(1)
|
runtime.GOMAXPROCS(1)
|
||||||
}
|
}
|
||||||
debug.SetGCPercent(25)
|
debug.SetGCPercent(20)
|
||||||
|
|
||||||
globalOpts := flag.NewFlagSet("global", flag.ContinueOnError)
|
globalOpts := flag.NewFlagSet("global", flag.ContinueOnError)
|
||||||
hflag := globalOpts.Bool("h", false, "") // support -h to be canonical with other Unix utilities
|
hflag := globalOpts.Bool("h", false, "") // support -h to be canonical with other Unix utilities
|
||||||
jflag := globalOpts.Bool("j", false, "")
|
jflag := globalOpts.Bool("j", false, "")
|
||||||
pflag := globalOpts.String("p", "", "")
|
pflag := globalOpts.String("p", "", "")
|
||||||
tflag := globalOpts.String("t", "", "")
|
tflag := globalOpts.String("t", "", "")
|
||||||
|
tTflag := globalOpts.String("T", "", "")
|
||||||
err := globalOpts.Parse(os.Args[1:])
|
err := globalOpts.Parse(os.Args[1:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cli.Help()
|
cli.Help()
|
||||||
|
@ -98,11 +99,6 @@ func main() {
|
||||||
cmdArgs = args[1:]
|
cmdArgs = args[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
if *hflag {
|
|
||||||
cli.Help()
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
basePath := zerotier.PlatformDefaultHomePath
|
basePath := zerotier.PlatformDefaultHomePath
|
||||||
if len(*pflag) > 0 {
|
if len(*pflag) > 0 {
|
||||||
basePath = *pflag
|
basePath = *pflag
|
||||||
|
@ -110,7 +106,14 @@ func main() {
|
||||||
|
|
||||||
var authToken string
|
var authToken string
|
||||||
if len(*tflag) > 0 {
|
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 {
|
} else {
|
||||||
authToken = readAuthToken(basePath)
|
authToken = readAuthToken(basePath)
|
||||||
}
|
}
|
||||||
|
@ -125,38 +128,36 @@ func main() {
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
case "service":
|
case "service":
|
||||||
cli.Service(basePath, authToken, cmdArgs)
|
cli.Service(basePath, authToken, cmdArgs)
|
||||||
case "status":
|
case "status", "info":
|
||||||
authTokenRequired(authToken)
|
authTokenRequired(authToken)
|
||||||
cli.Status(basePath, authToken, cmdArgs, *jflag)
|
cli.Status(basePath, authToken, cmdArgs, *jflag)
|
||||||
case "peers", "listpeers":
|
case "peers", "listpeers", "lspeers":
|
||||||
authTokenRequired(authToken)
|
authTokenRequired(authToken)
|
||||||
cli.Peers(basePath, authToken, cmdArgs, *jflag, false)
|
cli.Peers(basePath, authToken, cmdArgs, *jflag, false)
|
||||||
case "roots", "listroots":
|
case "roots", "listroots", "lsroots":
|
||||||
authTokenRequired(authToken)
|
authTokenRequired(authToken)
|
||||||
cli.Peers(basePath, authToken, cmdArgs, *jflag, true)
|
cli.Peers(basePath, authToken, cmdArgs, *jflag, true)
|
||||||
case "addroot":
|
case "addroot":
|
||||||
authTokenRequired(authToken)
|
// TODO
|
||||||
cli.SetRoot(basePath, authToken, cmdArgs, true)
|
|
||||||
case "removeroot":
|
case "removeroot":
|
||||||
authTokenRequired(authToken)
|
// TODO
|
||||||
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)
|
|
||||||
case "join":
|
case "join":
|
||||||
authTokenRequired(authToken)
|
authTokenRequired(authToken)
|
||||||
cli.Join(basePath, authToken, cmdArgs)
|
cli.Join(basePath, authToken, cmdArgs)
|
||||||
case "leave":
|
case "leave":
|
||||||
authTokenRequired(authToken)
|
authTokenRequired(authToken)
|
||||||
cli.Leave(basePath, authToken, cmdArgs)
|
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":
|
case "set":
|
||||||
authTokenRequired(authToken)
|
authTokenRequired(authToken)
|
||||||
cli.Set(basePath, authToken, cmdArgs)
|
cli.Set(basePath, authToken, cmdArgs)
|
||||||
|
case "identity":
|
||||||
|
cli.Identity(cmdArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
cli.Help()
|
cli.Help()
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"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
|
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
|
// Equals performs a deep equality test between this and another identity
|
||||||
func (id *Identity) Equals(id2 *Identity) bool {
|
func (id *Identity) Equals(id2 *Identity) bool {
|
||||||
if id2 == nil {
|
if id2 == nil {
|
||||||
|
|
|
@ -24,9 +24,6 @@ import (
|
||||||
type LocalConfigPhysicalPathConfiguration struct {
|
type LocalConfigPhysicalPathConfiguration struct {
|
||||||
// Blacklist flags this path as unusable for ZeroTier traffic
|
// Blacklist flags this path as unusable for ZeroTier traffic
|
||||||
Blacklist bool
|
Blacklist bool
|
||||||
|
|
||||||
// TrustedPathID identifies a path for unencrypted/unauthenticated traffic
|
|
||||||
TrustedPathID uint64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LocalConfigVirtualAddressConfiguration contains settings for virtual addresses
|
// LocalConfigVirtualAddressConfiguration contains settings for virtual addresses
|
||||||
|
@ -35,14 +32,6 @@ type LocalConfigVirtualAddressConfiguration struct {
|
||||||
Try []InetAddress `json:"try,omitempty"`
|
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
|
// LocalConfigSettings contains node settings
|
||||||
type LocalConfigSettings struct {
|
type LocalConfigSettings struct {
|
||||||
// PrimaryPort is the main UDP port and must be set.
|
// 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 is the maximum size of the infoLog in kilobytes or 0 for no limit and -1 to disable logging
|
||||||
LogSizeMax int `json:"logSizeMax"`
|
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"`
|
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 are prefixes of physical network interface names that won't be used by ZeroTier (e.g. "lo" or "utun")
|
||||||
InterfacePrefixBlacklist []string `json:"interfacePrefixBlacklist,omitempty"`
|
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 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.
|
// 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.Virtual = make(map[Address]LocalConfigVirtualAddressConfiguration)
|
||||||
lc.Network = make(map[NetworkID]NetworkLocalSettings)
|
lc.Network = make(map[NetworkID]NetworkLocalSettings)
|
||||||
|
|
||||||
if isTotallyNewNode {
|
lc.Settings.PrimaryPort = 9993
|
||||||
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.SecondaryPort = unassignedPrivilegedPorts[randomUInt()%uint(len(unassignedPrivilegedPorts))]
|
||||||
lc.Settings.PortSearch = true
|
lc.Settings.PortSearch = true
|
||||||
lc.Settings.PortMapping = true
|
lc.Settings.PortMapping = true
|
||||||
lc.Settings.LogSizeMax = 128
|
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")
|
lc.Settings.APITCPBindAddress = NewInetAddressFromString("127.0.0.1/9993")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "windows":
|
case "windows":
|
||||||
lc.Settings.InterfacePrefixBlacklist = []string{"loopback"}
|
lc.Settings.InterfacePrefixBlacklist = []string{"loopback"}
|
||||||
|
|
|
@ -47,6 +47,9 @@ var nullLogger = log.New(ioutil.Discard, "", 0)
|
||||||
|
|
||||||
// Network status states
|
// Network status states
|
||||||
const (
|
const (
|
||||||
|
NetworkIDStringLength = 16
|
||||||
|
AddressStringLength = 10
|
||||||
|
|
||||||
NetworkStatusRequestConfiguration int = C.ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION
|
NetworkStatusRequestConfiguration int = C.ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION
|
||||||
NetworkStatusOK int = C.ZT_NETWORK_STATUS_OK
|
NetworkStatusOK int = C.ZT_NETWORK_STATUS_OK
|
||||||
NetworkStatusAccessDenied int = C.ZT_NETWORK_STATUS_ACCESS_DENIED
|
NetworkStatusAccessDenied int = C.ZT_NETWORK_STATUS_ACCESS_DENIED
|
||||||
|
|
41
node/AES.hpp
41
node/AES.hpp
|
@ -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
|
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
|
* If such data exists this must be called before update1() and finish1().
|
||||||
* in the MAC that is not included in the plaintext.
|
|
||||||
*
|
*
|
||||||
* 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 aad Additional authenticated data
|
||||||
* @param len Length of AAD in bytes
|
* @param len Length of AAD in bytes
|
||||||
|
@ -336,15 +344,22 @@ public:
|
||||||
// Compute 128-bit GMAC tag.
|
// Compute 128-bit GMAC tag.
|
||||||
_gmac.finish(reinterpret_cast<uint8_t *>(tmp));
|
_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];
|
_tag[1] = tmp[0] ^ tmp[1];
|
||||||
_ctr._aes.encrypt(_tag,_tag);
|
_ctr._aes.encrypt(_tag,_tag);
|
||||||
|
|
||||||
// Get CTR IV and 32-bit counter. The most significant bit of the 32-bit counter
|
// Initialize CTR with 96-bit CTR nonce and 32-bit counter. The counter
|
||||||
// is masked to zero so the counter will never overflow, but the remaining bits
|
// incorporates 31 more bits of entropy which should raise our security margin
|
||||||
// are taken from the encrypted tag as they can count as additional bits of
|
// a bit, but this is not included in the worst case analysis of GMAC-SIV.
|
||||||
// entropy for the CTR IV. We don't technically count these in figuring our
|
// The most significant bit of the counter is masked to zero to allow up to
|
||||||
// worst case scenario bound, but they could be argued to add a little margin.
|
// 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[0] = _tag[0];
|
||||||
tmp[1] = _tag[1] & ZT_CONST_TO_BE_UINT64(0xffffffff7fffffffULL);
|
tmp[1] = _tag[1] & ZT_CONST_TO_BE_UINT64(0xffffffff7fffffffULL);
|
||||||
_ctr.init(reinterpret_cast<const uint8_t *>(tmp),_output);
|
_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
|
class GMACSIVDecryptor
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,7 +32,6 @@ set(core_headers
|
||||||
OS.hpp
|
OS.hpp
|
||||||
Path.hpp
|
Path.hpp
|
||||||
Peer.hpp
|
Peer.hpp
|
||||||
PeerList.hpp
|
|
||||||
Poly1305.hpp
|
Poly1305.hpp
|
||||||
Protocol.hpp
|
Protocol.hpp
|
||||||
RuntimeEnvironment.hpp
|
RuntimeEnvironment.hpp
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace ZeroTier {
|
||||||
* compatibility.
|
* compatibility.
|
||||||
*
|
*
|
||||||
* Use of the append functions is faster than building and then encoding a
|
* Use of the append functions is faster than building and then encoding a
|
||||||
* dictionary.
|
* dictionary for creating outbound packets.
|
||||||
*/
|
*/
|
||||||
class Dictionary
|
class Dictionary
|
||||||
{
|
{
|
||||||
|
|
84
node/FCV.hpp
84
node/FCV.hpp
|
@ -19,23 +19,15 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <cstring>
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FCV is a Fixed Capacity Vector
|
* 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
|
* 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.
|
* 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 T Type to contain
|
||||||
* @tparam C Maximum capacity of vector
|
* @tparam C Maximum capacity of vector
|
||||||
*/
|
*/
|
||||||
|
@ -46,11 +38,11 @@ public:
|
||||||
typedef T * iterator;
|
typedef T * iterator;
|
||||||
typedef const T * const_iterator;
|
typedef const T * const_iterator;
|
||||||
|
|
||||||
ZT_INLINE FCV() noexcept : _s(0) {} // 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; } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
ZT_INLINE FCV(const FCV &v) : _s(0) { *this = v; }
|
||||||
|
|
||||||
template<typename I>
|
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)
|
_s(0)
|
||||||
{
|
{
|
||||||
while (i != end) {
|
while (i != end) {
|
||||||
|
@ -63,7 +55,7 @@ public:
|
||||||
|
|
||||||
ZT_INLINE FCV &operator=(const FCV &v)
|
ZT_INLINE FCV &operator=(const FCV &v)
|
||||||
{
|
{
|
||||||
if (&v != this) {
|
if (likely(&v != this)) {
|
||||||
this->clear();
|
this->clear();
|
||||||
const unsigned int s = v._s;
|
const unsigned int s = v._s;
|
||||||
_s = s;
|
_s = s;
|
||||||
|
@ -85,25 +77,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear without calling destructors (same as unsafeResize(0))
|
* Move contents from this vector to another and clear this vector.
|
||||||
*/
|
|
||||||
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
|
|
||||||
*
|
*
|
||||||
* @param v Target vector
|
* @param v Target vector
|
||||||
*/
|
*/
|
||||||
|
@ -114,18 +88,29 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
ZT_INLINE iterator begin() noexcept { return reinterpret_cast<T *>(_m); }
|
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 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 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 T &operator[](const unsigned int i)
|
||||||
ZT_INLINE const T &operator[](const unsigned int i) const noexcept { return reinterpret_cast<T *>(_m)[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 unsigned int size() const noexcept { return _s; }
|
||||||
ZT_INLINE bool empty() const noexcept { return (_s == 0); }
|
ZT_INLINE bool empty() const noexcept { return (_s == 0); }
|
||||||
|
|
||||||
ZT_INLINE T *data() noexcept { return reinterpret_cast<T *>(_m); }
|
ZT_INLINE T *data() noexcept { return reinterpret_cast<T *>(_m); }
|
||||||
ZT_INLINE const T *data() const noexcept { return reinterpret_cast<const 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
|
* Push a value onto the back of this vector
|
||||||
|
@ -136,8 +121,9 @@ public:
|
||||||
*/
|
*/
|
||||||
ZT_INLINE void push_back(const T &v)
|
ZT_INLINE void push_back(const T &v)
|
||||||
{
|
{
|
||||||
if (_s < C)
|
if (likely(_s < C))
|
||||||
new (reinterpret_cast<T *>(_m) + _s++) T(v);
|
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()
|
ZT_INLINE T &push()
|
||||||
{
|
{
|
||||||
if (_s < C) {
|
if (likely(_s < C)) {
|
||||||
return *(new(reinterpret_cast<T *>(_m) + _s++) T());
|
return *(new(reinterpret_cast<T *>(_m) + _s++) T());
|
||||||
} else {
|
} else {
|
||||||
return *(reinterpret_cast<T *>(_m) + (C - 1));
|
return *(reinterpret_cast<T *>(_m) + (C - 1));
|
||||||
|
@ -161,7 +147,7 @@ public:
|
||||||
*/
|
*/
|
||||||
ZT_INLINE T &push(const T &v)
|
ZT_INLINE T &push(const T &v)
|
||||||
{
|
{
|
||||||
if (_s < C) {
|
if (likely(_s < C)) {
|
||||||
return *(new(reinterpret_cast<T *>(_m) + _s++) T(v));
|
return *(new(reinterpret_cast<T *>(_m) + _s++) T(v));
|
||||||
} else {
|
} else {
|
||||||
T &tmp = *(reinterpret_cast<T *>(_m) + (C - 1));
|
T &tmp = *(reinterpret_cast<T *>(_m) + (C - 1));
|
||||||
|
@ -175,7 +161,7 @@ public:
|
||||||
*/
|
*/
|
||||||
ZT_INLINE void pop_back()
|
ZT_INLINE void pop_back()
|
||||||
{
|
{
|
||||||
if (_s != 0)
|
if (likely(_s != 0))
|
||||||
(reinterpret_cast<T *>(_m) + --_s)->~T();
|
(reinterpret_cast<T *>(_m) + --_s)->~T();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,8 +172,8 @@ public:
|
||||||
*/
|
*/
|
||||||
ZT_INLINE void resize(unsigned int ns)
|
ZT_INLINE void resize(unsigned int ns)
|
||||||
{
|
{
|
||||||
if (ns > C)
|
if (unlikely(ns > C))
|
||||||
ns = C;
|
throw std::out_of_range("capacity exceeded");
|
||||||
unsigned int s = _s;
|
unsigned int s = _s;
|
||||||
while (s < ns)
|
while (s < ns)
|
||||||
new(reinterpret_cast<T *>(_m) + s++) T();
|
new(reinterpret_cast<T *>(_m) + s++) T();
|
||||||
|
@ -196,16 +182,6 @@ public:
|
||||||
_s = s;
|
_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
|
* 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); }
|
ZT_INLINE bool operator>=(const FCV &v) const noexcept { return !(*this < v); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int _s;
|
#ifdef _MSC_VER
|
||||||
uint8_t _m[sizeof(T) * C];
|
uint8_t _m[sizeof(T) * C];
|
||||||
|
#else
|
||||||
|
__attribute__((aligned(16))) uint8_t _m[sizeof(T) * C];
|
||||||
|
#endif
|
||||||
|
unsigned int _s;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
|
|
@ -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)
|
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;
|
ZeroTier::Vector<ZeroTier::Endpoint> endpoints;
|
||||||
endpoints.reserve(addrcnt);
|
endpoints.reserve(addrcnt);
|
||||||
for(unsigned int i=0;i<addrcnt;++i)
|
for(unsigned int i=0;i<addrcnt;++i)
|
||||||
endpoints.push_back(ZeroTier::Endpoint(ZeroTier::asInetAddress(addrs[i]));
|
endpoints.push_back(ZeroTier::Endpoint(ZeroTier::asInetAddress(addrs[i])));
|
||||||
return ZeroTier::Locator::makeRootSpecification(reinterpret_cast<const ZeroTier::Identity *>(id),endpoints,rootSpecBuf,rootSpecBufSize);
|
return ZeroTier::Locator::makeRootSpecification(*reinterpret_cast<const ZeroTier::Identity *>(id),ts,endpoints,rootSpecBuf,rootSpecBufSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZT_SDK_API void ZT_Identity_delete(ZT_Identity *id)
|
ZT_SDK_API void ZT_Identity_delete(ZT_Identity *id)
|
||||||
|
|
|
@ -261,9 +261,9 @@ public:
|
||||||
{
|
{
|
||||||
switch (as.ss.ss_family) {
|
switch (as.ss.ss_family) {
|
||||||
case AF_INET:
|
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:
|
case AF_INET6:
|
||||||
return Utils::ntoh((uint16_t) as.sa_in6.sin6_port);
|
return Utils::ntoh((uint16_t)as.sa_in6.sin6_port);
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
#ifndef ZT_MEMBERSHIP_HPP
|
#ifndef ZT_MEMBERSHIP_HPP
|
||||||
#define ZT_MEMBERSHIP_HPP
|
#define ZT_MEMBERSHIP_HPP
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#include "Constants.hpp"
|
#include "Constants.hpp"
|
||||||
#include "Credential.hpp"
|
#include "Credential.hpp"
|
||||||
#include "Containers.hpp"
|
#include "Containers.hpp"
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
* @param now Start time
|
* @param now Start time
|
||||||
*/
|
*/
|
||||||
ZT_INLINE Meter() noexcept
|
ZT_INLINE Meter() noexcept
|
||||||
{} // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init,hicpp-use-equals-default,modernize-use-equals-default)
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a measurement
|
* Add a measurement
|
||||||
|
|
|
@ -14,13 +14,6 @@
|
||||||
#ifndef ZT_NETWORKCONFIG_HPP
|
#ifndef ZT_NETWORKCONFIG_HPP
|
||||||
#define ZT_NETWORKCONFIG_HPP
|
#define ZT_NETWORKCONFIG_HPP
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstring>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <vector>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include "Constants.hpp"
|
#include "Constants.hpp"
|
||||||
#include "InetAddress.hpp"
|
#include "InetAddress.hpp"
|
||||||
#include "MulticastGroup.hpp"
|
#include "MulticastGroup.hpp"
|
||||||
|
@ -34,6 +27,10 @@
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
#include "Trace.hpp"
|
#include "Trace.hpp"
|
||||||
#include "TriviallyCopyable.hpp"
|
#include "TriviallyCopyable.hpp"
|
||||||
|
#include "Containers.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
#ifndef ZT_NETWORKCONFIGMASTER_HPP
|
#ifndef ZT_NETWORKCONFIGMASTER_HPP
|
||||||
#define ZT_NETWORKCONFIGMASTER_HPP
|
#define ZT_NETWORKCONFIGMASTER_HPP
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#include "Constants.hpp"
|
#include "Constants.hpp"
|
||||||
#include "Dictionary.hpp"
|
#include "Dictionary.hpp"
|
||||||
#include "NetworkConfig.hpp"
|
#include "NetworkConfig.hpp"
|
||||||
|
|
|
@ -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)
|
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));
|
std::pair<Identity,Locator> r(Locator::parseRootSpecification(rdef,rdeflen));
|
||||||
if (r.first) {
|
return ((r.first)&&(RR->topology->addRoot(tPtr,r.first,r.second))) ? ZT_RESULT_OK : ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||||
RR->topology->addRoot(tPtr,r.first,r.second);
|
|
||||||
return ZT_RESULT_OK;
|
|
||||||
}
|
|
||||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ZT_ResultCode Node::removeRoot(void *tPtr,const ZT_Fingerprint *fp)
|
ZT_ResultCode Node::removeRoot(void *tPtr,const ZT_Fingerprint *fp)
|
||||||
|
|
|
@ -130,7 +130,7 @@ public:
|
||||||
m_uPtr,
|
m_uPtr,
|
||||||
tPtr,
|
tPtr,
|
||||||
localSocket,
|
localSocket,
|
||||||
reinterpret_cast<const struct sockaddr_storage *>(&addr),
|
&addr.as.ss,
|
||||||
data,
|
data,
|
||||||
len,
|
len,
|
||||||
ttl) == 0);
|
ttl) == 0);
|
||||||
|
@ -306,9 +306,9 @@ public:
|
||||||
bool localControllerHasAuthorized(int64_t now,uint64_t nwid,const Address &addr) const;
|
bool localControllerHasAuthorized(int64_t now,uint64_t nwid,const Address &addr) const;
|
||||||
|
|
||||||
// Implementation of NetworkController::Sender interface
|
// 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 ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &destination,const NetworkConfig &nc,bool sendLegacyFormatConfig);
|
||||||
virtual void ncSendRevocation(const Address &destination,const Revocation &rev); // NOLINT(cppcoreguidelines-explicit-virtual-functions,hicpp-use-override,modernize-use-override)
|
virtual void ncSendRevocation(const Address &destination,const Revocation &rev);
|
||||||
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 ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &destination,NetworkController::ErrorCode errorCode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RuntimeEnvironment m_RR;
|
RuntimeEnvironment m_RR;
|
||||||
|
|
|
@ -41,7 +41,7 @@ class Path
|
||||||
friend class Defragmenter;
|
friend class Defragmenter;
|
||||||
|
|
||||||
public:
|
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_localSocket(l),
|
||||||
m_lastIn(0),
|
m_lastIn(0),
|
||||||
m_lastOut(0),
|
m_lastOut(0),
|
||||||
|
|
|
@ -327,10 +327,10 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether a key is ephemeral
|
* Check whether a key is ephemeral
|
||||||
*
|
*
|
||||||
* This is used to check whether a packet is received with forward secrecy enabled
|
* This is used to check whether a packet is received with forward secrecy enabled
|
||||||
* or not.
|
* or not.
|
||||||
*
|
*
|
||||||
* @param k Key to check
|
* @param k Key to check
|
||||||
* @return True if this key is ephemeral, false if it's the long-lived identity key
|
* @return True if this key is ephemeral, false if it's the long-lived identity key
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -250,7 +250,7 @@
|
||||||
#define ZT_PROTO_PACKET_VERB_INDEX 27
|
#define ZT_PROTO_PACKET_VERB_INDEX 27
|
||||||
|
|
||||||
#define ZT_PROTO_HELLO_NODE_META_INSTANCE_ID "i"
|
#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_LOCATOR "l"
|
||||||
#define ZT_PROTO_HELLO_NODE_META_SOFTWARE_VENDOR "s"
|
#define ZT_PROTO_HELLO_NODE_META_SOFTWARE_VENDOR "s"
|
||||||
#define ZT_PROTO_HELLO_NODE_META_COMPLIANCE "c"
|
#define ZT_PROTO_HELLO_NODE_META_COMPLIANCE "c"
|
||||||
|
@ -340,7 +340,7 @@ enum Verb
|
||||||
* Dictionary fields (defines start with ZT_PROTO_HELLO_NODE_META_):
|
* Dictionary fields (defines start with ZT_PROTO_HELLO_NODE_META_):
|
||||||
*
|
*
|
||||||
* INSTANCE_ID - a 64-bit unique value generated on each node start
|
* 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
|
* LOCATOR - signed record enumerating this node's trusted contact points
|
||||||
* EPHEMERAL_PUBLIC - Ephemeral public key(s)
|
* EPHEMERAL_PUBLIC - Ephemeral public key(s)
|
||||||
*
|
*
|
||||||
|
@ -419,10 +419,10 @@ enum Verb
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Relay-mediated NAT traversal or firewall punching initiation:
|
* Relay-mediated NAT traversal or firewall punching initiation:
|
||||||
* <[1] flags (unused, currently 0)>
|
* <[1] flags>
|
||||||
* <[5] ZeroTier address of other peer>
|
* <[5] ZeroTier address of other peer>
|
||||||
* <[2] 16-bit number of endpoints where peer might be reached>
|
* <[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:
|
* Legacy packet format for pre-2.x peers:
|
||||||
* <[1] flags (unused, currently 0)>
|
* <[1] flags (unused, currently 0)>
|
||||||
|
|
|
@ -14,11 +14,6 @@
|
||||||
#ifndef ZT_REVOCATION_HPP
|
#ifndef ZT_REVOCATION_HPP
|
||||||
#define ZT_REVOCATION_HPP
|
#define ZT_REVOCATION_HPP
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#include "Constants.hpp"
|
#include "Constants.hpp"
|
||||||
#include "Credential.hpp"
|
#include "Credential.hpp"
|
||||||
#include "Address.hpp"
|
#include "Address.hpp"
|
||||||
|
|
|
@ -14,11 +14,6 @@
|
||||||
#ifndef ZT_TAG_HPP
|
#ifndef ZT_TAG_HPP
|
||||||
#define ZT_TAG_HPP
|
#define ZT_TAG_HPP
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include "Constants.hpp"
|
#include "Constants.hpp"
|
||||||
#include "Credential.hpp"
|
#include "Credential.hpp"
|
||||||
#include "C25519.hpp"
|
#include "C25519.hpp"
|
||||||
|
|
|
@ -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)
|
if ((id == RR->identity) || (!id) || (!loc) || (!loc.verify(id)) || (!id.locallyValidate()))
|
||||||
return;
|
return false;
|
||||||
RWMutex::Lock l1(m_peers_l);
|
RWMutex::Lock l1(m_peers_l);
|
||||||
m_roots[id] = loc;
|
m_roots[id] = loc;
|
||||||
m_updateRootPeers(tPtr);
|
m_updateRootPeers(tPtr);
|
||||||
m_writeRootList(tPtr);
|
m_writeRootList(tPtr);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Topology::removeRoot(void *const tPtr, const Fingerprint &fp)
|
bool Topology::removeRoot(void *const tPtr, const Fingerprint &fp)
|
||||||
|
|
|
@ -185,11 +185,15 @@ public:
|
||||||
/**
|
/**
|
||||||
* Add or update a root server and its locator
|
* 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 tPtr Thread pointer
|
||||||
* @param id Root identity
|
* @param id Root identity
|
||||||
* @param loc Root locator
|
* @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
|
* Remove a root server's identity from the root server set
|
||||||
|
|
|
@ -53,62 +53,6 @@ public:
|
||||||
Utils::zero<sizeof(T)>(&obj);
|
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:
|
private:
|
||||||
static ZT_INLINE void mustBeTriviallyCopyable(const TriviallyCopyable &) noexcept {}
|
static ZT_INLINE void mustBeTriviallyCopyable(const TriviallyCopyable &) noexcept {}
|
||||||
static ZT_INLINE void mustBeTriviallyCopyable(const TriviallyCopyable *) noexcept {}
|
static ZT_INLINE void mustBeTriviallyCopyable(const TriviallyCopyable *) noexcept {}
|
||||||
|
|
Loading…
Add table
Reference in a new issue