Bunch of build fixes, some docs

This commit is contained in:
Adam Ierymenko 2020-01-20 10:40:31 -08:00
parent dab968ed96
commit 03190c5a55
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
23 changed files with 131 additions and 121 deletions

View file

@ -1,6 +1,30 @@
ZeroTier Release Notes
======
# Version 2.0.0
### This is a major milestone release with numerous changes. It's technically backward compatibile with older nodes but we highly recommend upgrading as soon as possible. We will not force upgrade however as this is a major release and contains changes that may require updates to some configurations, such as CLI changes that may required updates to scripts.
* Migrated from GNU make to cmake for easier cross platform builds and simplified build files.
* Service management code for desktop, laptop, and server ZeroTier service is now written in Go. Core and packet handling (performance critical) code remains in C++.
* Reworked CLI for improved ease of use, more readable and detailed display output, and added new root management commands.
* "Moon" and "planet" terminology and associated commands are now gone in favor of fully decentralized roots.
* Service now has a fully multithreaded UDP I/O path written in C++ for superior scaling on large systems.
* Entirely new P2P based multicast propagation algorithm for improved multi-data-center and global scale multicast propagation and improved multicast discovery. Some backward compatibility is included with pre-2.0 but upgrading of all nodes is recommended if you depend on multicast for anything but ARP, NDP, and occasional service advertisements.
* ZeroTier now implements ephemeral keys with continuos re-keying for forward secrecy! (FINALLY!)
* Separated root into its own highly optimized code base.
* Changed default primary ZeroTier port to 893 (for new nodes) to exploit friendlier NAT behavior on ports numbered under 1024. Added some more aggressive NAT-t techniques that work with this and can often traverse symmetric NATs.
* Added stubs for future support for alternative transports including HTTP/HTTPS, WebRTC, Web Sockets, and "naked" Ethernet (on LAN).
* Improved packet assemble/decode performance by moving to a lock-free bounds-checking scheme for buffers and a shared memory buffer pool.
* Added support for a new identity type with NIST P-384 curves for future FIPS compliance. Curve25519 is still the default.
* AES encryption is now the default for communicating with 2.0+ nodes. AES uses a GMAC-based "SIV" mode for improved resilience against nonce reuse, but constructed in a way that could be FIPS certified.
* Compression is now only enabled for control packets as most data these days is encrypted or already compressed. This improves performance in almost all cases.
* Minor API changes (for those who use the core directly) to support faster buffer handling, reduced memory copying, exposure of identity functions and full node identity, and improved state object load/store semantics.
---
# Older version release notes
# 2019-08-30 -- Version 1.4.6
* Update default root list to latest

View file

@ -11,19 +11,11 @@
*/
/****/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifndef _WIN32
#include <sys/time.h>
#endif
#include <sys/types.h>
#include <cstdint>
#include <cstdio>
#include <ctime>
#include <cstring>
#include <algorithm>
#include <utility>
#include <stdexcept>
#include <map>
#include <thread>
@ -36,8 +28,6 @@
#include "../node/Dictionary.hpp"
#include "../node/MAC.hpp"
#include "../include/ZeroTierOne.h"
#include "EmbeddedNetworkController.hpp"
#include "LFDB.hpp"
#include "FileDB.hpp"

View file

@ -34,7 +34,7 @@ func Status(basePath, authToken string, args []string, jsonOutput bool) {
}
fmt.Printf("%.10x: %s %s\n", uint64(status.Address), online, status.Version)
fmt.Printf("\tidentity:\t%s\n", status.Identity.String())
fmt.Printf("\tports:\t%d %d %d\n", status.Config.Settings.PrimaryPort, status.Config.Settings.SecondaryPort, status.Config.Settings.TertiaryPort)
fmt.Printf("\tports:\tprimary: %d secondary: %d\n", status.Config.Settings.PrimaryPort, status.Config.Settings.SecondaryPort)
fmt.Printf("\tport search:\t%s\n", enabledDisabled(status.Config.Settings.PortSearch))
fmt.Printf("\tport mapping (uPnP/NAT-PMP):\t%s\n", enabledDisabled(status.Config.Settings.PortMapping))
fmt.Printf("\tmultipath mode:\t%d\n", status.Config.Settings.MuiltipathMode)

View file

@ -98,11 +98,11 @@ const char *ZT_PLATFORM_DEFAULT_HOMEPATH = defaultHomePath.c_str();
/****************************************************************************/
/* These functions are implemented in Go in pkg/ztnode/node-callbacks.go */
extern "C" int goPathCheckFunc(void *,uint64_t,int,const void *,int);
/* These functions are implemented in Go in pkg/zerotier/node.go */
extern "C" int goPathCheckFunc(void *,const ZT_Identity *,int,const void *,int);
extern "C" int goPathLookupFunc(void *,uint64_t,int,const ZT_Identity *,int *,uint8_t [16],int *);
extern "C" void goStateObjectPutFunc(void *,int,const uint64_t [2],const void *,int);
extern "C" int goStateObjectGetFunc(void *,int,const uint64_t [2],void *,unsigned int);
extern "C" int goStateObjectGetFunc(void *,int,const uint64_t [2],void **);
extern "C" void goVirtualNetworkConfigFunc(void *,ZT_GoTap *,uint64_t,int,const ZT_VirtualNetworkConfig *);
extern "C" void goZtEvent(void *,int,const void *);
extern "C" void goHandleTapAddedMulticastGroup(void *,ZT_GoTap *,uint64_t,uint64_t,uint32_t);
@ -170,15 +170,15 @@ static int ZT_GoNode_StateGetFunction(
void *tptr,
enum ZT_StateObjectType objType,
const uint64_t id[2],
void *buf,
unsigned int buflen)
void **data,
void (**freeFunc)(void *))
{
*freeFunc = free;
return goStateObjectGetFunc(
reinterpret_cast<ZT_GoNode *>(uptr)->goUserPtr,
(int)objType,
id,
buf,
buflen);
data);
}
static ZT_ALWAYS_INLINE void doUdpSend(ZT_SOCKET sock,const struct sockaddr_storage *addr,const void *data,const unsigned int len,const unsigned int ipTTL)
@ -240,6 +240,7 @@ static int ZT_GoNode_PathCheckFunction(
void *uptr,
void *tptr,
uint64_t ztAddress,
const ZT_Identity *id,
int64_t localSocket,
const struct sockaddr_storage *sa)
{
@ -247,14 +248,14 @@ static int ZT_GoNode_PathCheckFunction(
case AF_INET:
return goPathCheckFunc(
reinterpret_cast<ZT_GoNode *>(uptr)->goUserPtr,
ztAddress,
id,
AF_INET,
&(reinterpret_cast<const struct sockaddr_in *>(sa)->sin_addr.s_addr),
Utils::ntoh((uint16_t)reinterpret_cast<const struct sockaddr_in *>(sa)->sin_port));
case AF_INET6:
return goPathCheckFunc(
reinterpret_cast<ZT_GoNode *>(uptr)->goUserPtr,
ztAddress,
id,
AF_INET6,
reinterpret_cast<const struct sockaddr_in6 *>(sa)->sin6_addr.s6_addr,
Utils::ntoh((uint16_t)reinterpret_cast<const struct sockaddr_in6 *>(sa)->sin6_port));

View file

@ -573,7 +573,7 @@ func (n *Node) multicastUnsubscribe(nwid uint64, mg *MulticastGroup) {
C.ZT_Node_multicastUnsubscribe(unsafe.Pointer(n.zn), C.uint64_t(nwid), C.uint64_t(mg.MAC), C.ulong(mg.ADI))
}
func (n *Node) pathCheck(ztAddress Address, af int, ip net.IP, port int) bool {
func (n *Node) pathCheck(ip net.IP) bool {
n.localConfigLock.RLock()
defer n.localConfigLock.RUnlock()
for cidr, phy := range n.localConfig.Physical {
@ -661,17 +661,17 @@ func (n *Node) handleTrace(traceMessage string) {
}
}
func (n *Node) handleUserMessage(originAddress, messageTypeID uint64, data []byte) {
func (n *Node) handleUserMessage(origin *Identity, messageTypeID uint64, data []byte) {
}
//////////////////////////////////////////////////////////////////////////////
// These are callbacks called by the core and GoGlue stuff to talk to the
// service. These launch gorountines to do their work where possible to
// service. These launch goroutines to do their work where possible to
// avoid blocking anything in the core.
//export goPathCheckFunc
func goPathCheckFunc(gn unsafe.Pointer, ztAddress C.uint64_t, af C.int, ip unsafe.Pointer, port C.int) C.int {
func goPathCheckFunc(gn, _ unsafe.Pointer, af C.int, ip unsafe.Pointer, _ C.int) C.int {
nodesByUserPtrLock.RLock()
node := nodesByUserPtr[uintptr(gn)]
nodesByUserPtrLock.RUnlock()
@ -683,14 +683,14 @@ func goPathCheckFunc(gn unsafe.Pointer, ztAddress C.uint64_t, af C.int, ip unsaf
} else {
return 0
}
if node != nil && len(nip) > 0 && node.pathCheck(Address(ztAddress), int(af), nip, int(port)) {
if node != nil && len(nip) > 0 && node.pathCheck(nip) {
return 1
}
return 0
}
//export goPathLookupFunc
func goPathLookupFunc(gn unsafe.Pointer, ztAddress C.uint64_t, desiredFamily int, identity, familyP, ipP, portP unsafe.Pointer) C.int {
func goPathLookupFunc(gn unsafe.Pointer, _ C.uint64_t, _ int, identity, familyP, ipP, portP unsafe.Pointer) C.int {
nodesByUserPtrLock.RLock()
node := nodesByUserPtr[uintptr(gn)]
nodesByUserPtrLock.RUnlock()
@ -741,18 +741,21 @@ func goStateObjectPutFunc(gn unsafe.Pointer, objType C.int, id, data unsafe.Poin
}
//export goStateObjectGetFunc
func goStateObjectGetFunc(gn unsafe.Pointer, objType C.int, id, data unsafe.Pointer, bufSize C.uint) C.int {
func goStateObjectGetFunc(gn unsafe.Pointer, objType C.int, id, dataP unsafe.Pointer) C.int {
nodesByUserPtrLock.RLock()
node := nodesByUserPtr[uintptr(gn)]
nodesByUserPtrLock.RUnlock()
if node == nil {
return -1
}
*((*uintptr)(dataP)) = 0
tmp, found := node.stateObjectGet(int(objType), *((*[2]uint64)(id)))
if found && len(tmp) < int(bufSize) {
if len(tmp) > 0 {
C.memcpy(data, unsafe.Pointer(&(tmp[0])), C.ulong(len(tmp)))
if found && len(tmp) > 0 {
cData := C.malloc(C.ulong(len(tmp)))
if uintptr(cData) == 0 {
return -1
}
*((*uintptr)(dataP)) = uintptr(cData)
return C.int(len(tmp))
}
return -1
@ -835,7 +838,10 @@ func goZtEvent(gn unsafe.Pointer, eventType C.int, data unsafe.Pointer) {
node.handleTrace(C.GoString((*C.char)(data)))
case C.ZT_EVENT_USER_MESSAGE:
um := (*C.ZT_UserMessage)(data)
node.handleUserMessage(uint64(um.origin), uint64(um.typeId), C.GoBytes(um.data, C.int(um.length)))
id, err := newIdentityFromCIdentity(unsafe.Pointer(um.id))
if err != nil {
node.handleUserMessage(id, uint64(um.typeId), C.GoBytes(um.data, C.int(um.length)))
}
}
}()
}

View file

@ -435,13 +435,16 @@ typedef void ZT_Identity;
* levels of authentication or access control that are required. Any node
* in the world can send you a user message! (Unless your network is air
* gapped.)
*
* Pointers to id and data might not remain valid after the event is
* received.
*/
typedef struct
{
/**
* ZeroTier address of sender (least significant 40 bits)
* Identity of sender
*/
uint64_t origin;
const ZT_Identity *id;
/**
* User message type ID
@ -449,7 +452,7 @@ typedef struct
uint64_t typeId;
/**
* User message data (not including type ID)
* User message data
*/
const void *data;

View file

@ -2,6 +2,7 @@ cmake_minimum_required (VERSION 2.8)
project(zt_core)
set(core_headers
../include/ZeroTierCore.h
Address.hpp
AtomicCounter.hpp
Buf.hpp

View file

@ -25,7 +25,6 @@
#include "Utils.hpp"
#include "Buffer.hpp"
#include "Identity.hpp"
#include "../include/ZeroTierOne.h"
namespace ZeroTier {

View file

@ -32,15 +32,15 @@ static inline Credential::VerifyResult _credVerify(const RuntimeEnvironment *con
const uint64_t networkId = credential.networkId();
if ((!signedBy)||(signedBy != Network::controllerFor(networkId)))
return Credential::VERIFY_BAD_SIGNATURE;
const Identity id(RR->topology->getIdentity(tPtr,signedBy));
if (!id) {
const SharedPtr<Peer> peer(RR->topology->get(tPtr,signedBy));
if (!peer) {
RR->sw->requestWhois(tPtr,RR->node->now(),signedBy);
return Credential::VERIFY_NEED_IDENTITY;
}
try {
ScopedPtr< Buffer<(sizeof(CRED) + 64)> > tmp(new Buffer<(sizeof(CRED) + 64)>());
credential.serialize(*tmp,true);
const Credential::VerifyResult result = (id.verify(tmp->data(),tmp->size(),credential.signature(),credential.signatureLength()) ? Credential::VERIFY_OK : Credential::VERIFY_BAD_SIGNATURE);
const Credential::VerifyResult result = (peer->identity().verify(tmp->data(),tmp->size(),credential.signature(),credential.signatureLength()) ? Credential::VERIFY_OK : Credential::VERIFY_BAD_SIGNATURE);
return result;
} catch ( ... ) {}
return Credential::VERIFY_BAD_SIGNATURE;
@ -55,8 +55,8 @@ Credential::VerifyResult Credential::_verify(const RuntimeEnvironment *const RR,
if ((!credential._signedBy)||(credential._signedBy != Network::controllerFor(credential.networkId()))||(credential._qualifierCount > ZT_NETWORK_COM_MAX_QUALIFIERS))
return Credential::VERIFY_BAD_SIGNATURE;
const Identity id(RR->topology->getIdentity(tPtr,credential._signedBy));
if (!id) {
const SharedPtr<Peer> peer(RR->topology->get(tPtr,credential._signedBy));
if (!peer) {
RR->sw->requestWhois(tPtr,RR->node->now(),credential._signedBy);
return Credential::VERIFY_NEED_IDENTITY;
}
@ -69,7 +69,7 @@ Credential::VerifyResult Credential::_verify(const RuntimeEnvironment *const RR,
buf[ptr++] = Utils::hton(credential._qualifiers[i].maxDelta);
}
return (id.verify(buf,ptr * sizeof(uint64_t),credential._signature,credential._signatureLength) ? Credential::VERIFY_OK : Credential::VERIFY_BAD_SIGNATURE);
return (peer->identity().verify(buf,ptr * sizeof(uint64_t),credential._signature,credential._signatureLength) ? Credential::VERIFY_OK : Credential::VERIFY_BAD_SIGNATURE);
}
Credential::VerifyResult Credential::_verify(const RuntimeEnvironment *RR,void *tPtr,const Capability &credential) const
@ -93,9 +93,9 @@ Credential::VerifyResult Credential::_verify(const RuntimeEnvironment *RR,void *
return Credential::VERIFY_BAD_SIGNATURE; // otherwise if we have another entry it must be from the previous holder in the chain
}
const Identity id(RR->topology->getIdentity(tPtr,credential._custody[c].from));
if (id) {
if (!id.verify(tmp.data(),tmp.size(),credential._custody[c].signature,credential._custody[c].signatureLength))
const SharedPtr<Peer> peer(RR->topology->get(tPtr,credential._custody[c].from));
if (peer) {
if (!peer->identity().verify(tmp.data(),tmp.size(),credential._custody[c].signature,credential._custody[c].signatureLength))
return Credential::VERIFY_BAD_SIGNATURE;
} else {
RR->sw->requestWhois(tPtr,RR->node->now(),credential._custody[c].from);

View file

@ -19,7 +19,7 @@ bool Endpoint::operator==(const Endpoint &ep) const
{
if (_t == ep._t) {
switch(_t) {
case INETADDR: return (*sockaddr() == *ep.sockaddr());
case INETADDR: return (inetAddr() == ep.inetAddr());
case DNSNAME: return ((_v.dns.port == ep._v.dns.port)&&(strcmp(_v.dns.name,ep._v.dns.name) == 0));
case ZEROTIER: return ((_v.zt.a == ep._v.zt.a)&&(memcmp(_v.zt.idh,ep._v.zt.idh,sizeof(_v.zt.idh)) == 0));
case URL: return (strcmp(_v.url,ep._v.url) == 0);
@ -37,7 +37,7 @@ bool Endpoint::operator<(const Endpoint &ep) const
} else if (_t == ep._t) {
int ncmp;
switch(_t) {
case INETADDR: return (*sockaddr() < *ep.sockaddr());
case INETADDR: return (inetAddr() < ep.inetAddr());
case DNSNAME:
ncmp = strcmp(_v.dns.name,ep._v.dns.name);
return ((ncmp < 0) ? true : (ncmp == 0)&&(_v.dns.port < ep._v.dns.port));

View file

@ -11,8 +11,6 @@
*/
/****/
#include "../include/ZeroTierOne.h"
#include "Constants.hpp"
#include "RuntimeEnvironment.hpp"
#include "IncomingPacket.hpp"
@ -75,7 +73,7 @@ ZT_ALWAYS_INLINE bool _doHELLO(IncomingPacket &pkt,const RuntimeEnvironment *con
return true;
}
SharedPtr<Peer> peer(RR->topology->get(id.address()));
SharedPtr<Peer> peer(RR->topology->get(tPtr,id.address()));
if (peer) {
// We already have an identity with this address -- check for collisions
if (!alreadyAuthenticated) {
@ -131,7 +129,11 @@ ZT_ALWAYS_INLINE bool _doHELLO(IncomingPacket &pkt,const RuntimeEnvironment *con
}
// Check packet integrity and MAC (this is faster than locallyValidate() so do it first to filter out total crap)
SharedPtr<Peer> newPeer(new Peer(RR,RR->identity,id));
SharedPtr<Peer> newPeer(new Peer(RR));
if (!newPeer->init(RR->identity,id)) {
RR->t->incomingPacketDroppedHELLO(tPtr,path,pid,fromAddress,"error initializing peer");
return true;
}
if (!pkt.dearmor(newPeer->key())) {
RR->t->incomingPacketMessageAuthenticationFailure(tPtr,path,pid,fromAddress,pkt.hops(),"invalid MAC");
return true;
@ -143,7 +145,7 @@ ZT_ALWAYS_INLINE bool _doHELLO(IncomingPacket &pkt,const RuntimeEnvironment *con
return true;
}
peer = RR->topology->add(newPeer);
peer = RR->topology->add(tPtr,newPeer);
// Continue at // VALID
}
@ -283,8 +285,11 @@ ZT_ALWAYS_INLINE bool _doOK(IncomingPacket &pkt,const RuntimeEnvironment *const
try {
Identity id;
p += id.deserialize(pkt,p);
if (id)
RR->sw->doAnythingWaitingForPeer(tPtr,RR->topology->add(SharedPtr<Peer>(new Peer(RR,RR->identity,id))));
if (id) {
SharedPtr<Peer> ptmp(RR->topology->add(tPtr,SharedPtr<Peer>(new Peer(RR))));
ptmp->init(RR->identity,id);
RR->sw->doAnythingWaitingForPeer(tPtr,ptmp);
}
} catch ( ... ) {
break;
}
@ -325,9 +330,9 @@ ZT_ALWAYS_INLINE bool _doWHOIS(IncomingPacket &pkt,const RuntimeEnvironment *con
const Address addr(pkt.field(ptr,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
ptr += ZT_ADDRESS_LENGTH;
const Identity id(RR->topology->getIdentity(tPtr,addr));
if (id) {
id.serialize(outp,false);
const SharedPtr<Peer> ptmp(RR->topology->get(tPtr,addr));
if (ptmp) {
ptmp->identity().serialize(outp,false);
++count;
} else {
// Request unknown WHOIS from upstream from us (if we have one)
@ -350,7 +355,7 @@ ZT_ALWAYS_INLINE bool _doRENDEZVOUS(IncomingPacket &pkt,const RuntimeEnvironment
if (RR->topology->isRoot(peer->identity())) {
uint16_t junk = (uint16_t)Utils::random();
const Address with(pkt.field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
const SharedPtr<Peer> rendezvousWith(RR->topology->get(with));
const SharedPtr<Peer> rendezvousWith(RR->topology->get(tPtr,with));
if (rendezvousWith) {
const unsigned int port = pkt.at<uint16_t>(ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT);
const unsigned int addrlen = pkt[ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN];
@ -712,7 +717,7 @@ ZT_ALWAYS_INLINE bool _doUSER_MESSAGE(IncomingPacket &pkt,const RuntimeEnvironme
{
if (likely(pkt.size() >= (ZT_PACKET_IDX_PAYLOAD + 8))) {
ZT_UserMessage um;
um.origin = peer->address().toInt();
um.id = (const ZT_Identity *)(&(peer->identity()));
um.typeId = pkt.at<uint64_t>(ZT_PACKET_IDX_PAYLOAD);
um.data = reinterpret_cast<const void *>(reinterpret_cast<const uint8_t *>(pkt.data()) + ZT_PACKET_IDX_PAYLOAD + 8);
um.length = pkt.size() - (ZT_PACKET_IDX_PAYLOAD + 8);
@ -749,7 +754,7 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,void *tPtr)
return _doHELLO(*this,RR,tPtr,false,_path);
}
const SharedPtr<Peer> peer(RR->topology->get(sourceAddress));
const SharedPtr<Peer> peer(RR->topology->get(tPtr,sourceAddress));
if (peer) {
if (!trusted) {
if (!dearmor(peer->key())) {

View file

@ -18,8 +18,6 @@
#include <cstring>
#include <cstdint>
#include "../include/ZeroTierOne.h"
#include "Constants.hpp"
#include "Utils.hpp"
#include "MAC.hpp"

View file

@ -16,8 +16,6 @@
#include <cstdint>
#include "../include/ZeroTierOne.h"
#include "Constants.hpp"
#include "Credential.hpp"
#include "Hashtable.hpp"

View file

@ -563,16 +563,19 @@ Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,void *u
bool got = false;
ScopedPtr< Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> > dict(new Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY>());
try {
int n = RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp,dict->unsafeData(),ZT_NETWORKCONFIG_DICT_CAPACITY - 1);
if (n > 1) {
try {
ScopedPtr<NetworkConfig> nconf2(new NetworkConfig());
if (nconf2->fromDictionary(*dict)) {
this->setConfiguration(tPtr,*nconf2,false);
_lastConfigUpdate = 0; // still want to re-request an update since it's likely outdated
got = true;
}
} catch ( ... ) {}
std::vector<uint8_t> nconfData(RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp));
if (nconfData.size() > 2) {
nconfData.push_back(0);
if (dict->load((const char *)nconfData.data())) {
try {
ScopedPtr<NetworkConfig> nconf2(new NetworkConfig());
if (nconf2->fromDictionary(*dict)) {
this->setConfiguration(tPtr,*nconf2,false);
_lastConfigUpdate = 0; // still want to re-request an update since it's likely outdated
got = true;
}
} catch (...) {}
}
}
} catch ( ... ) {}
@ -894,10 +897,10 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add
}
// If it's not a duplicate, check chunk signature
const Identity controllerId(RR->topology->getIdentity(tPtr,controller()));
if (!controllerId) // we should always have the controller identity by now, otherwise how would we have queried it the first time?
const SharedPtr<Peer> controllerPeer(RR->topology->get(tPtr,controller()));
if (!controllerPeer)
return 0;
if (!controllerId.verify(chunk.field(start,ptr - start),ptr - start,sig,ZT_C25519_SIGNATURE_LEN))
if (!controllerPeer->identity().verify(chunk.field(start,ptr - start),ptr - start,sig,ZT_C25519_SIGNATURE_LEN))
return 0;
// New properly verified chunks can be flooded "virally" through the network
@ -1010,7 +1013,6 @@ int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToD
bool Network::gate(void *tPtr,const SharedPtr<Peer> &peer)
{
const int64_t now = RR->node->now();
Mutex::Lock l(_memberships_l);
try {
if (_config) {
@ -1037,8 +1039,8 @@ void Network::doPeriodicTasks(void *tPtr,const int64_t now)
Mutex::Lock l1(_memberships_l);
{
Address *a = (Address *)0;
Membership *m = (Membership *)0;
Address *a = nullptr;
Membership *m = nullptr;
Hashtable<Address,Membership>::Iterator i(_memberships);
while (i.next(a,m))
m->clean(now,_config);
@ -1074,8 +1076,8 @@ void Network::learnBridgeRoute(const MAC &mac,const Address &addr)
Address maxAddr;
unsigned long maxCount = 0;
MAC *m = (MAC *)0;
Address *a = (Address *)0;
MAC *m = nullptr;
Address *a = nullptr;
// Find the address responsible for the most entries
{
@ -1365,12 +1367,11 @@ void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const
void Network::_announceMulticastGroups(void *tPtr,bool force)
{
// Assumes _myMulticastGroups_l and _memberships_l are locked
const int64_t now = RR->node->now();
const std::vector<MulticastGroup> groups(_allMulticastGroups());
_announceMulticastGroupsTo(tPtr,controller(),groups);
{
Address *a = (Address *)0;
Membership *m = (Membership *)0;
Address *a = nullptr;
Membership *m = nullptr;
Hashtable<Address,Membership>::Iterator i(_memberships);
while (i.next(a,m)) {
// TODO

View file

@ -15,9 +15,6 @@
#define ZT_NETWORK_HPP
#include <cstdint>
#include "../include/ZeroTierOne.h"
#include <string>
#include <map>
#include <vector>

View file

@ -22,8 +22,6 @@
#include <stdexcept>
#include <algorithm>
#include "../include/ZeroTierOne.h"
#include "Constants.hpp"
#include "Buffer.hpp"
#include "InetAddress.hpp"

View file

@ -22,9 +22,6 @@
#include <vector>
#include "Constants.hpp"
#include "../include/ZeroTierOne.h"
#include "RuntimeEnvironment.hpp"
#include "InetAddress.hpp"
#include "Mutex.hpp"

View file

@ -49,6 +49,8 @@ Peer::Peer(const RuntimeEnvironment *renv) :
bool Peer::init(const Identity &myIdentity,const Identity &peerIdentity)
{
if (_id == peerIdentity)
return true;
_id = peerIdentity;
_vProto = 0;
_vMajor = 0;

View file

@ -20,7 +20,6 @@
#include <cstdint>
#include "Constants.hpp"
#include "../include/ZeroTierOne.h"
#include "Credential.hpp"
#include "Address.hpp"
#include "C25519.hpp"

View file

@ -18,8 +18,6 @@
#include <utility>
#include <stdexcept>
#include "../include/ZeroTierOne.h"
#include "Constants.hpp"
#include "RuntimeEnvironment.hpp"
#include "Switch.hpp"
@ -57,7 +55,7 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
if (destination != RR->identity.address()) {
if (fragment.hops() < ZT_RELAY_MAX_HOPS) {
fragment.incrementHops();
SharedPtr<Peer> relayTo = RR->topology->get(destination);
SharedPtr<Peer> relayTo = RR->topology->get(tPtr,destination);
if ((!relayTo)||(!relayTo->sendDirect(tPtr,fragment.data(),fragment.size(),now))) {
relayTo = RR->topology->root();
if (relayTo)
@ -125,7 +123,7 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
Packet packet(data,len);
if (packet.hops() < ZT_RELAY_MAX_HOPS) {
packet.incrementHops();
SharedPtr<Peer> relayTo = RR->topology->get(destination);
SharedPtr<Peer> relayTo = RR->topology->get(tPtr,destination);
if ((!relayTo)||(!relayTo->sendDirect(tPtr,packet.data(),packet.size(),now))) {
relayTo = RR->topology->root();
if ((relayTo)&&(relayTo->address() != source))
@ -364,7 +362,7 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
// Destination is another ZeroTier peer on the same network --------------
Address toZT(to.toAddress(network->id())); // since in-network MACs are derived from addresses and network IDs, we can reverse this
SharedPtr<Peer> toPeer(RR->topology->get(toZT));
SharedPtr<Peer> toPeer(RR->topology->get(tPtr,toZT));
if (!network->filterOutgoingPacket(tPtr,false,RR->identity.address(),toZT,from,to,(const uint8_t *)data,len,etherType,vlanId,qosBucket)) {
RR->t->outgoingNetworkFrameDropped(tPtr,network,from,to,etherType,vlanId,len,"filter blocked");
@ -463,7 +461,7 @@ void Switch::send(void *tPtr,Packet &packet,bool encrypt)
}
_txQueue.push_back(TXQueueEntry(dest,RR->node->now(),packet,encrypt));
}
if (!RR->topology->get(dest))
if (!RR->topology->get(tPtr,dest))
requestWhois(tPtr,RR->node->now(),dest);
}
}
@ -540,7 +538,7 @@ unsigned long Switch::doTimerTasks(void *tPtr,int64_t now)
} else if ((now - txi->creationTime) > ZT_TRANSMIT_QUEUE_TIMEOUT) {
_txQueue.erase(txi++);
} else {
if (!RR->topology->get(txi->dest))
if (!RR->topology->get(tPtr,txi->dest))
needWhois.push_back(txi->dest);
++txi;
}
@ -557,7 +555,7 @@ unsigned long Switch::doTimerTasks(void *tPtr,int64_t now)
rq->timestamp = 0;
} else {
const Address src(rq->frag0.source());
if (!RR->topology->get(src))
if (!RR->topology->get(tPtr,src))
requestWhois(tPtr,now,src);
}
}
@ -580,7 +578,7 @@ unsigned long Switch::doTimerTasks(void *tPtr,int64_t now)
bool Switch::_trySend(void *tPtr,Packet &packet,bool encrypt)
{
const int64_t now = RR->node->now();
const SharedPtr<Peer> peer(RR->topology->get(packet.destination()));
const SharedPtr<Peer> peer(RR->topology->get(tPtr,packet.destination()));
SharedPtr<Path> viaPath;
if (peer) {
viaPath = peer->path(now);

View file

@ -14,17 +14,13 @@
#ifndef ZT_TOPOLOGY_HPP
#define ZT_TOPOLOGY_HPP
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <utility>
#include <set>
#include "Constants.hpp"
#include "../include/ZeroTierOne.h"
#include "Address.hpp"
#include "Identity.hpp"
#include "Peer.hpp"
@ -157,8 +153,8 @@ public:
{
RWMutex::RLock l(_peers_l);
Hashtable< Address,SharedPtr<Peer> >::Iterator i(const_cast<Topology *>(this)->_peers);
Address *a = (Address *)0;
SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
Address *a = nullptr;
SharedPtr<Peer> *p = nullptr;
while (i.next(a,p)) {
f(*((const SharedPtr<Peer> *)p));
}
@ -189,8 +185,8 @@ public:
try {
Hashtable< Address,SharedPtr<Peer> >::Iterator i(const_cast<Topology *>(this)->_peers);
Address *a = (Address *)0;
SharedPtr<Peer> *p = (SharedPtr<Peer> *)0;
Address *a = nullptr;
SharedPtr<Peer> *p = nullptr;
while (i.next(a,p)) {
f(*((const SharedPtr<Peer> *)p),std::binary_search(rootPeerPtrs,rootPeerPtrsEnd,(uintptr_t)p->ptr()));
}
@ -210,10 +206,10 @@ public:
{
RWMutex::RLock l(_paths_l);
Hashtable< Path::HashKey,SharedPtr<Path> >::Iterator i(const_cast<Topology *>(this)->_paths);
Path::HashKey *k = (Path::HashKey *)0;
SharedPtr<Path> *p = (SharedPtr<Path> *)0;
Path::HashKey *k = nullptr;
SharedPtr<Path> *p = nullptr;
while (i.next(k,p)) {
f(*((const SharedPtr<Peer> *)p));
f(*((const SharedPtr<Path> *)p));
}
}

View file

@ -19,8 +19,6 @@
#include <cstring>
#include <cstdlib>
#include "../include/ZeroTierOne.h"
#include "Constants.hpp"
#include "SharedPtr.hpp"
#include "Packet.hpp"

View file

@ -11,11 +11,10 @@
*/
/****/
#include "../node/Constants.hpp"
#include "NeighborDiscovery.hpp"
#include "OSUtils.hpp"
#include "../include/ZeroTierOne.h"
#include <assert.h>
namespace ZeroTier {