From 03190c5a55312cbf3f36ae202cb5a40705ca2eb5 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 20 Jan 2020 10:40:31 -0800 Subject: [PATCH] Bunch of build fixes, some docs --- RELEASE-NOTES.md | 24 +++++++++++++ controller/EmbeddedNetworkController.cpp | 18 +++------- go/cmd/zerotier/cli/status.go | 2 +- go/native/GoGlue.cpp | 19 ++++++----- go/pkg/zerotier/node.go | 28 +++++++++------ include/ZeroTierCore.h | 9 +++-- node/CMakeLists.txt | 1 + node/Capability.hpp | 1 - node/Credential.cpp | 18 +++++----- node/Endpoint.cpp | 4 +-- node/IncomingPacket.cpp | 31 ++++++++++------- node/InetAddress.hpp | 2 -- node/Membership.hpp | 2 -- node/Network.cpp | 43 ++++++++++++------------ node/Network.hpp | 3 -- node/NetworkConfig.hpp | 2 -- node/Node.hpp | 3 -- node/Peer.cpp | 2 ++ node/Revocation.hpp | 1 - node/Switch.cpp | 16 ++++----- node/Topology.hpp | 18 ++++------ node/Trace.hpp | 2 -- osdep/NeighborDiscovery.cpp | 3 +- 23 files changed, 131 insertions(+), 121 deletions(-) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 2f3777b42..61a48d077 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -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 diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp index b1f8358eb..26d43f04f 100644 --- a/controller/EmbeddedNetworkController.cpp +++ b/controller/EmbeddedNetworkController.cpp @@ -11,19 +11,11 @@ */ /****/ -#include -#include -#include -#include -#include - -#ifndef _WIN32 -#include -#endif -#include - +#include +#include +#include +#include #include -#include #include #include #include @@ -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" diff --git a/go/cmd/zerotier/cli/status.go b/go/cmd/zerotier/cli/status.go index b5685a463..2fe62f0d9 100644 --- a/go/cmd/zerotier/cli/status.go +++ b/go/cmd/zerotier/cli/status.go @@ -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) diff --git a/go/native/GoGlue.cpp b/go/native/GoGlue.cpp index 75ec4895d..3c34c6a80 100644 --- a/go/native/GoGlue.cpp +++ b/go/native/GoGlue.cpp @@ -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(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(uptr)->goUserPtr, - ztAddress, + id, AF_INET, &(reinterpret_cast(sa)->sin_addr.s_addr), Utils::ntoh((uint16_t)reinterpret_cast(sa)->sin_port)); case AF_INET6: return goPathCheckFunc( reinterpret_cast(uptr)->goUserPtr, - ztAddress, + id, AF_INET6, reinterpret_cast(sa)->sin6_addr.s6_addr, Utils::ntoh((uint16_t)reinterpret_cast(sa)->sin6_port)); diff --git a/go/pkg/zerotier/node.go b/go/pkg/zerotier/node.go index dad2bc94b..22b38bd1d 100644 --- a/go/pkg/zerotier/node.go +++ b/go/pkg/zerotier/node.go @@ -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))) + } } }() } diff --git a/include/ZeroTierCore.h b/include/ZeroTierCore.h index 52daac43b..e107ab7fa 100644 --- a/include/ZeroTierCore.h +++ b/include/ZeroTierCore.h @@ -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; diff --git a/node/CMakeLists.txt b/node/CMakeLists.txt index 0ea2a85cd..a5043b8fe 100644 --- a/node/CMakeLists.txt +++ b/node/CMakeLists.txt @@ -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 diff --git a/node/Capability.hpp b/node/Capability.hpp index 263c42257..0a6a3ee8b 100644 --- a/node/Capability.hpp +++ b/node/Capability.hpp @@ -25,7 +25,6 @@ #include "Utils.hpp" #include "Buffer.hpp" #include "Identity.hpp" -#include "../include/ZeroTierOne.h" namespace ZeroTier { diff --git a/node/Credential.cpp b/node/Credential.cpp index 103fa187c..1e87076fd 100644 --- a/node/Credential.cpp +++ b/node/Credential.cpp @@ -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(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(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(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); diff --git a/node/Endpoint.cpp b/node/Endpoint.cpp index be12eb2bb..64321b771 100644 --- a/node/Endpoint.cpp +++ b/node/Endpoint.cpp @@ -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)); diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 9d00dd2e1..e3968d260 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -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(RR->topology->get(id.address())); + SharedPtr 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 newPeer(new Peer(RR,RR->identity,id)); + SharedPtr 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(new Peer(RR,RR->identity,id)))); + if (id) { + SharedPtr ptmp(RR->topology->add(tPtr,SharedPtr(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 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 rendezvousWith(RR->topology->get(with)); + const SharedPtr rendezvousWith(RR->topology->get(tPtr,with)); if (rendezvousWith) { const unsigned int port = pkt.at(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(ZT_PACKET_IDX_PAYLOAD); um.data = reinterpret_cast(reinterpret_cast(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(RR->topology->get(sourceAddress)); + const SharedPtr peer(RR->topology->get(tPtr,sourceAddress)); if (peer) { if (!trusted) { if (!dearmor(peer->key())) { diff --git a/node/InetAddress.hpp b/node/InetAddress.hpp index b27b32cc6..25cbd5f2d 100644 --- a/node/InetAddress.hpp +++ b/node/InetAddress.hpp @@ -18,8 +18,6 @@ #include #include -#include "../include/ZeroTierOne.h" - #include "Constants.hpp" #include "Utils.hpp" #include "MAC.hpp" diff --git a/node/Membership.hpp b/node/Membership.hpp index 04840d245..587657e21 100644 --- a/node/Membership.hpp +++ b/node/Membership.hpp @@ -16,8 +16,6 @@ #include -#include "../include/ZeroTierOne.h" - #include "Constants.hpp" #include "Credential.hpp" #include "Hashtable.hpp" diff --git a/node/Network.cpp b/node/Network.cpp index b7c2fcc27..3d458f0d2 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -563,16 +563,19 @@ Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,void *u bool got = false; ScopedPtr< Dictionary > dict(new Dictionary()); 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 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 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 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 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) { - 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::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 groups(_allMulticastGroups()); _announceMulticastGroupsTo(tPtr,controller(),groups); { - Address *a = (Address *)0; - Membership *m = (Membership *)0; + Address *a = nullptr; + Membership *m = nullptr; Hashtable::Iterator i(_memberships); while (i.next(a,m)) { // TODO diff --git a/node/Network.hpp b/node/Network.hpp index 83e7c99a6..295826966 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -15,9 +15,6 @@ #define ZT_NETWORK_HPP #include - -#include "../include/ZeroTierOne.h" - #include #include #include diff --git a/node/NetworkConfig.hpp b/node/NetworkConfig.hpp index f62d99b01..2ab2d6d7e 100644 --- a/node/NetworkConfig.hpp +++ b/node/NetworkConfig.hpp @@ -22,8 +22,6 @@ #include #include -#include "../include/ZeroTierOne.h" - #include "Constants.hpp" #include "Buffer.hpp" #include "InetAddress.hpp" diff --git a/node/Node.hpp b/node/Node.hpp index a24a3633c..074255ff1 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -22,9 +22,6 @@ #include #include "Constants.hpp" - -#include "../include/ZeroTierOne.h" - #include "RuntimeEnvironment.hpp" #include "InetAddress.hpp" #include "Mutex.hpp" diff --git a/node/Peer.cpp b/node/Peer.cpp index 20e3bed7d..8fb2b064a 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -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; diff --git a/node/Revocation.hpp b/node/Revocation.hpp index 1e05fc785..3c6e50613 100644 --- a/node/Revocation.hpp +++ b/node/Revocation.hpp @@ -20,7 +20,6 @@ #include #include "Constants.hpp" -#include "../include/ZeroTierOne.h" #include "Credential.hpp" #include "Address.hpp" #include "C25519.hpp" diff --git a/node/Switch.cpp b/node/Switch.cpp index 10de40277..358d06b15 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -18,8 +18,6 @@ #include #include -#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 relayTo = RR->topology->get(destination); + SharedPtr 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 relayTo = RR->topology->get(destination); + SharedPtr 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,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 toPeer(RR->topology->get(toZT)); + SharedPtr 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(RR->topology->get(packet.destination())); + const SharedPtr peer(RR->topology->get(tPtr,packet.destination())); SharedPtr viaPath; if (peer) { viaPath = peer->path(now); diff --git a/node/Topology.hpp b/node/Topology.hpp index f30bc10dd..70ffe8519 100644 --- a/node/Topology.hpp +++ b/node/Topology.hpp @@ -14,17 +14,13 @@ #ifndef ZT_TOPOLOGY_HPP #define ZT_TOPOLOGY_HPP -#include #include - #include #include #include #include #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 >::Iterator i(const_cast(this)->_peers); - Address *a = (Address *)0; - SharedPtr *p = (SharedPtr *)0; + Address *a = nullptr; + SharedPtr *p = nullptr; while (i.next(a,p)) { f(*((const SharedPtr *)p)); } @@ -189,8 +185,8 @@ public: try { Hashtable< Address,SharedPtr >::Iterator i(const_cast(this)->_peers); - Address *a = (Address *)0; - SharedPtr *p = (SharedPtr *)0; + Address *a = nullptr; + SharedPtr *p = nullptr; while (i.next(a,p)) { f(*((const SharedPtr *)p),std::binary_search(rootPeerPtrs,rootPeerPtrsEnd,(uintptr_t)p->ptr())); } @@ -210,10 +206,10 @@ public: { RWMutex::RLock l(_paths_l); Hashtable< Path::HashKey,SharedPtr >::Iterator i(const_cast(this)->_paths); - Path::HashKey *k = (Path::HashKey *)0; - SharedPtr *p = (SharedPtr *)0; + Path::HashKey *k = nullptr; + SharedPtr *p = nullptr; while (i.next(k,p)) { - f(*((const SharedPtr *)p)); + f(*((const SharedPtr *)p)); } } diff --git a/node/Trace.hpp b/node/Trace.hpp index 5d9825195..3a00eeec4 100644 --- a/node/Trace.hpp +++ b/node/Trace.hpp @@ -19,8 +19,6 @@ #include #include -#include "../include/ZeroTierOne.h" - #include "Constants.hpp" #include "SharedPtr.hpp" #include "Packet.hpp" diff --git a/osdep/NeighborDiscovery.cpp b/osdep/NeighborDiscovery.cpp index b00484f72..8f229642e 100644 --- a/osdep/NeighborDiscovery.cpp +++ b/osdep/NeighborDiscovery.cpp @@ -11,11 +11,10 @@ */ /****/ +#include "../node/Constants.hpp" #include "NeighborDiscovery.hpp" #include "OSUtils.hpp" -#include "../include/ZeroTierOne.h" - #include namespace ZeroTier {