From 0b2e5ed499aea0076caa2dc1d8784796e54da538 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 19 Oct 2015 15:11:43 -0700 Subject: Fix some broken logic in Path::reliable() --- node/Path.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'node/Path.hpp') diff --git a/node/Path.hpp b/node/Path.hpp index 6a69e071..6fa3c52e 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -114,7 +114,9 @@ public: */ inline bool reliable() const throw() { - return ( (_addr.ss_family == AF_INET6) || ((_ipScope != InetAddress::IP_SCOPE_GLOBAL)&&(_ipScope != InetAddress::IP_SCOPE_PSEUDOPRIVATE)) ); + if (_addr.ss_family == AF_INET) + return ((_ipScope != InetAddress::IP_SCOPE_GLOBAL)&&(_ipScope != InetAddress::IP_SCOPE_PSEUDOPRIVATE)); + return true; } /** -- cgit v1.2.3 From 16bc3e03982286232e1df2da17d8b2fc3c5a5c55 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 27 Oct 2015 15:00:16 -0700 Subject: Factor out RemotePath subclass of Path -- no longer needed, just cruft. --- include/ZeroTierOne.h | 3 +- node/Cluster.cpp | 1 + node/IncomingPacket.cpp | 5 +- node/Multicaster.cpp | 1 + node/Network.cpp | 1 + node/Node.cpp | 14 ++--- node/Node.hpp | 6 +- node/Path.cpp | 45 ++++++++++++++ node/Path.hpp | 117 +++++++++++++++++++++++++++++++++-- node/Peer.cpp | 32 +++++----- node/Peer.hpp | 24 ++++---- node/RemotePath.hpp | 161 ------------------------------------------------ node/SelfAwareness.cpp | 2 +- node/Switch.cpp | 2 +- objects.mk | 1 + service/OneService.cpp | 4 +- 16 files changed, 208 insertions(+), 211 deletions(-) create mode 100644 node/Path.cpp delete mode 100644 node/RemotePath.hpp (limited to 'node/Path.hpp') diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index 3457634b..01c8bcde 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -1356,11 +1356,10 @@ void ZT_Node_freeQueryResult(ZT_Node *node,void *qr); * reject bad, empty, and unusable addresses. * * @param addr Local interface address - * @param metric Local interface metric * @param trust How much do you trust the local network under this interface? * @return Boolean: non-zero if address was accepted and added */ -int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr,int metric, enum ZT_LocalInterfaceAddressTrust trust); +int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr,enum ZT_LocalInterfaceAddressTrust trust); /** * Clear local interface addresses diff --git a/node/Cluster.cpp b/node/Cluster.cpp index 73ff5846..07ca0ba1 100644 --- a/node/Cluster.cpp +++ b/node/Cluster.cpp @@ -48,6 +48,7 @@ #include "Topology.hpp" #include "Packet.hpp" #include "Switch.hpp" +#include "Node.hpp" namespace ZeroTier { diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 2514cd64..7015535a 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -44,6 +44,7 @@ #include "SHA512.hpp" #include "World.hpp" #include "Cluster.hpp" +#include "Node.hpp" namespace ZeroTier { @@ -888,7 +889,7 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha { try { const uint64_t now = RR->node->now(); - const RemotePath *currentBest = peer->getBestPath(now); + const Path *currentBest = peer->getBestPath(now); unsigned int count = at(ZT_PACKET_IDX_PAYLOAD); unsigned int ptr = ZT_PACKET_IDX_PAYLOAD + 2; @@ -1036,7 +1037,7 @@ bool IncomingPacket::_doCIRCUIT_TEST(const RuntimeEnvironment *RR,const SharedPt remainingHopsPtr += ZT_ADDRESS_LENGTH; SharedPtr nhp(RR->topology->getPeer(nextHop[h])); if (nhp) { - RemotePath *const rp = nhp->getBestPath(now); + Path *const rp = nhp->getBestPath(now); if (rp) nextHopBestPathAddress[h] = rp->address(); } diff --git a/node/Multicaster.cpp b/node/Multicaster.cpp index 6e6cd628..e43d7d88 100644 --- a/node/Multicaster.cpp +++ b/node/Multicaster.cpp @@ -37,6 +37,7 @@ #include "Peer.hpp" #include "C25519.hpp" #include "CertificateOfMembership.hpp" +#include "Node.hpp" namespace ZeroTier { diff --git a/node/Network.cpp b/node/Network.cpp index cd30e386..afbe1074 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -37,6 +37,7 @@ #include "Packet.hpp" #include "Buffer.hpp" #include "NetworkController.hpp" +#include "Node.hpp" #include "../version.h" diff --git a/node/Node.cpp b/node/Node.cpp index 87871e20..82cda66d 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -448,10 +448,10 @@ ZT_PeerList *Node::peers() const p->latency = pi->second->latency(); p->role = RR->topology->isRoot(pi->second->identity()) ? ZT_PEER_ROLE_ROOT : ZT_PEER_ROLE_LEAF; - std::vector paths(pi->second->paths()); - RemotePath *bestPath = pi->second->getBestPath(_now); + std::vector paths(pi->second->paths()); + Path *bestPath = pi->second->getBestPath(_now); p->pathCount = 0; - for(std::vector::iterator path(paths.begin());path!=paths.end();++path) { + for(std::vector::iterator path(paths.begin());path!=paths.end();++path) { memcpy(&(p->paths[p->pathCount].address),&(path->address()),sizeof(struct sockaddr_storage)); p->paths[p->pathCount].lastSend = path->lastSend(); p->paths[p->pathCount].lastReceive = path->lastReceived(); @@ -499,11 +499,11 @@ void Node::freeQueryResult(void *qr) ::free(qr); } -int Node::addLocalInterfaceAddress(const struct sockaddr_storage *addr,int metric,ZT_LocalInterfaceAddressTrust trust) +int Node::addLocalInterfaceAddress(const struct sockaddr_storage *addr,ZT_LocalInterfaceAddressTrust trust) { if (Path::isAddressValidForPath(*(reinterpret_cast(addr)))) { Mutex::Lock _l(_directPaths_m); - _directPaths.push_back(Path(*(reinterpret_cast(addr)),metric,(Path::Trust)trust)); + _directPaths.push_back(*(reinterpret_cast(addr))); std::sort(_directPaths.begin(),_directPaths.end()); _directPaths.erase(std::unique(_directPaths.begin(),_directPaths.end()),_directPaths.end()); return 1; @@ -900,10 +900,10 @@ void ZT_Node_freeQueryResult(ZT_Node *node,void *qr) } catch ( ... ) {} } -int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr,int metric, enum ZT_LocalInterfaceAddressTrust trust) +int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr,enum ZT_LocalInterfaceAddressTrust trust) { try { - return reinterpret_cast(node)->addLocalInterfaceAddress(addr,metric,trust); + return reinterpret_cast(node)->addLocalInterfaceAddress(addr,trust); } catch ( ... ) { return 0; } diff --git a/node/Node.hpp b/node/Node.hpp index 4094a79e..48c5ead8 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -105,7 +105,7 @@ public: ZT_VirtualNetworkConfig *networkConfig(uint64_t nwid) const; ZT_VirtualNetworkList *networks() const; void freeQueryResult(void *qr); - int addLocalInterfaceAddress(const struct sockaddr_storage *addr,int metric,ZT_LocalInterfaceAddressTrust trust); + int addLocalInterfaceAddress(const struct sockaddr_storage *addr,ZT_LocalInterfaceAddressTrust trust); void clearLocalInterfaceAddresses(); void setNetconfMaster(void *networkControllerInstance); ZT_ResultCode circuitTestBegin(ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *)); @@ -207,7 +207,7 @@ public: /** * @return Potential direct paths to me a.k.a. local interface addresses */ - inline std::vector directPaths() const + inline std::vector directPaths() const { Mutex::Lock _l(_directPaths_m); return _directPaths; @@ -285,7 +285,7 @@ private: std::vector< ZT_CircuitTest * > _circuitTests; Mutex _circuitTests_m; - std::vector _directPaths; + std::vector _directPaths; Mutex _directPaths_m; Mutex _backgroundTasksLock; diff --git a/node/Path.cpp b/node/Path.cpp new file mode 100644 index 00000000..e2475751 --- /dev/null +++ b/node/Path.cpp @@ -0,0 +1,45 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#include "Path.hpp" +#include "AntiRecursion.hpp" +#include "RuntimeEnvironment.hpp" +#include "Node.hpp" + +namespace ZeroTier { + +bool Path::send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) +{ + if (RR->node->putPacket(_localAddress,address(),data,len)) { + sent(now); + RR->antiRec->logOutgoingZT(data,len); + return true; + } + return false; +} + +} // namespace ZeroTier diff --git a/node/Path.hpp b/node/Path.hpp index 6fa3c52e..99f6590b 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -28,12 +28,19 @@ #ifndef ZT_PATH_HPP #define ZT_PATH_HPP +#include +#include + +#include +#include + #include "Constants.hpp" #include "InetAddress.hpp" -#include "Utils.hpp" namespace ZeroTier { +class RuntimeEnvironment; + /** * Base class for paths * @@ -67,19 +74,87 @@ public: }; Path() : + _lastSend(0), + _lastReceived(0), _addr(), + _localAddress(), _ipScope(InetAddress::IP_SCOPE_NONE), - _trust(TRUST_NORMAL) + _trust(TRUST_NORMAL), + _flags(0) { } - Path(const InetAddress &addr,int metric,Trust trust) : + Path(const InetAddress &localAddress,const InetAddress &addr,Trust trust) : + _lastSend(0), + _lastReceived(0), _addr(addr), + _localAddress(localAddress), _ipScope(addr.ipScope()), - _trust(trust) + _trust(trust), + _flags(0) + { + } + + /** + * Called when a packet is sent to this remote path + * + * This is called automatically by Path::send(). + * + * @param t Time of send + */ + inline void sent(uint64_t t) + throw() { + _lastSend = t; } + /** + * Called when a packet is received from this remote path + * + * @param t Time of receive + */ + inline void received(uint64_t t) + throw() + { + _lastReceived = t; + } + + /** + * @param now Current time + * @return True if this path appears active + */ + inline bool active(uint64_t now) const + throw() + { + return ((now - _lastReceived) < ZT_PEER_ACTIVITY_TIMEOUT); + } + + /** + * Send a packet via this path + * + * @param RR Runtime environment + * @param data Packet data + * @param len Packet length + * @param now Current time + * @return True if transport reported success + */ + bool send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now); + + /** + * @return Address of local side of this path or NULL if unspecified + */ + inline const InetAddress &localAddress() const throw() { return _localAddress; } + + /** + * @return Time of last send to this path + */ + inline uint64_t lastSend() const throw() { return _lastSend; } + + /** + * @return Time of last receive from this path + */ + inline uint64_t lastReceived() const throw() { return _lastReceived; } + /** * @return Physical address */ @@ -157,10 +232,42 @@ public: return false; } -protected: + template + inline void serialize(Buffer &b) const + { + b.append((uint8_t)0); // version + b.append((uint64_t)_lastSend); + b.append((uint64_t)_lastReceived); + _addr.serialize(b); + _localAddress.serialize(b); + b.append((uint8_t)_trust); + b.append((uint16_t)_flags); + } + + template + inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) + { + unsigned int p = startAt; + if (b[p++] != 0) + throw std::invalid_argument("invalid serialized Path"); + _lastSend = b.template at(p); p += 8; + _lastReceived = b.template at(p); p += 8; + p += _addr.deserialize(b,p); + p += _localAddress.deserialize(b,p); + _ipScope = _addr.ipScope(); + _trust = (Path::Trust)b[p++]; + _flags = b.template at(p); p += 2; + return (p - startAt); + } + +private: + uint64_t _lastSend; + uint64_t _lastReceived; InetAddress _addr; + InetAddress _localAddress; InetAddress::IpScope _ipScope; // memoize this since it's a computed value checked often Trust _trust; + uint16_t _flags; }; } // namespace ZeroTier diff --git a/node/Peer.cpp b/node/Peer.cpp index 009e2be5..ebdb6026 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -169,7 +169,7 @@ void Peer::received( if (!pathIsConfirmed) { if (verb == Packet::VERB_OK) { - RemotePath *slot = (RemotePath *)0; + Path *slot = (Path *)0; if (np < ZT_MAX_PEER_NETWORK_PATHS) { slot = &(_paths[np++]); } else { @@ -182,7 +182,7 @@ void Peer::received( } } if (slot) { - *slot = RemotePath(localAddr,remoteAddr); + *slot = Path(localAddr,remoteAddr,Path::TRUST_NORMAL); slot->received(now); _numPaths = np; pathIsConfirmed = true; @@ -240,7 +240,7 @@ void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &lo bool Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now,int inetAddressFamily) { - RemotePath *p = (RemotePath *)0; + Path *p = (Path *)0; Mutex::Lock _l(_lock); if (inetAddressFamily != 0) { @@ -268,7 +268,7 @@ bool Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now,int inet return false; } -void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_t now,bool force) +void Peer::pushDirectPaths(const RuntimeEnvironment *RR,Path *path,uint64_t now,bool force) { #ifdef ZT_ENABLE_CLUSTER // Cluster mode disables normal PUSH_DIRECT_PATHS in favor of cluster-based peer redirection @@ -281,7 +281,7 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_ if (((now - _lastDirectPathPushSent) >= ZT_DIRECT_PATH_PUSH_INTERVAL)||(force)) { _lastDirectPathPushSent = now; - std::vector dps(RR->node->directPaths()); + std::vector dps(RR->node->directPaths()); if (dps.empty()) return; @@ -291,13 +291,13 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_ for(std::vector::const_iterator p(dps.begin());p!=dps.end();++p) { if (ps.length() > 0) ps.push_back(','); - ps.append(p->address().toString()); + ps.append(p->toString()); } TRACE("pushing %u direct paths to %s: %s",(unsigned int)dps.size(),_id.address().toString().c_str(),ps.c_str()); } #endif - std::vector::const_iterator p(dps.begin()); + std::vector::const_iterator p(dps.begin()); while (p != dps.end()) { Packet outp(_id.address(),RR->identity.address(),Packet::VERB_PUSH_DIRECT_PATHS); outp.addSize(2); // leave room for count @@ -305,7 +305,7 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_ unsigned int count = 0; while ((p != dps.end())&&((outp.size() + 24) < ZT_PROTO_MAX_PACKET_LENGTH)) { uint8_t addressType = 4; - switch(p->address().ss_family) { + switch(p->ss_family) { case AF_INET: break; case AF_INET6: @@ -317,6 +317,7 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_ } uint8_t flags = 0; + /* TODO: path trust is not implemented yet switch(p->trust()) { default: break; @@ -327,13 +328,14 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_ flags |= (0x04 | 0x08); // no encryption, no authentication (redundant but go ahead and set both) break; } + */ outp.append(flags); outp.append((uint16_t)0); // no extensions outp.append(addressType); outp.append((uint8_t)((addressType == 4) ? 6 : 18)); - outp.append(p->address().rawIpData(),((addressType == 4) ? 4 : 16)); - outp.append((uint16_t)p->address().port()); + outp.append(p->rawIpData(),((addressType == 4) ? 4 : 16)); + outp.append((uint16_t)p->port()); ++count; ++p; @@ -506,7 +508,7 @@ struct _SortPathsByQuality { uint64_t _now; _SortPathsByQuality(const uint64_t now) : _now(now) {} - inline bool operator()(const RemotePath &a,const RemotePath &b) const + inline bool operator()(const Path &a,const Path &b) const { const uint64_t qa = ( ((uint64_t)a.active(_now) << 63) | @@ -526,7 +528,7 @@ void Peer::_sortPaths(const uint64_t now) std::sort(&(_paths[0]),&(_paths[_numPaths]),_SortPathsByQuality(now)); } -RemotePath *Peer::_getBestPath(const uint64_t now) +Path *Peer::_getBestPath(const uint64_t now) { // assumes _lock is locked if ((now - _lastPathSort) >= ZT_PEER_PATH_SORT_INTERVAL) @@ -538,10 +540,10 @@ RemotePath *Peer::_getBestPath(const uint64_t now) if (_paths[0].active(now)) return &(_paths[0]); } - return (RemotePath *)0; + return (Path *)0; } -RemotePath *Peer::_getBestPath(const uint64_t now,int inetAddressFamily) +Path *Peer::_getBestPath(const uint64_t now,int inetAddressFamily) { // assumes _lock is locked if ((now - _lastPathSort) >= ZT_PEER_PATH_SORT_INTERVAL) @@ -553,7 +555,7 @@ RemotePath *Peer::_getBestPath(const uint64_t now,int inetAddressFamily) } _sortPaths(now); } - return (RemotePath *)0; + return (Path *)0; } } // namespace ZeroTier diff --git a/node/Peer.hpp b/node/Peer.hpp index 04b541af..aa75b3f4 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -41,7 +41,7 @@ #include "RuntimeEnvironment.hpp" #include "CertificateOfMembership.hpp" -#include "RemotePath.hpp" +#include "Path.hpp" #include "Address.hpp" #include "Utils.hpp" #include "Identity.hpp" @@ -135,7 +135,7 @@ public: * @param now Current time * @return Best path or NULL if there are no active direct paths */ - inline RemotePath *getBestPath(uint64_t now) + inline Path *getBestPath(uint64_t now) { Mutex::Lock _l(_lock); return _getBestPath(now); @@ -150,14 +150,14 @@ public: * @param now Current time * @return Path used on success or NULL on failure */ - inline RemotePath *send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) + inline Path *send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) { - RemotePath *bestPath = getBestPath(now); + Path *bestPath = getBestPath(now); if (bestPath) { if (bestPath->send(RR,data,len,now)) return bestPath; } - return (RemotePath *)0; + return (Path *)0; } /** @@ -191,14 +191,14 @@ public: * @param now Current time * @param force If true, push regardless of rate limit */ - void pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_t now,bool force); + void pushDirectPaths(const RuntimeEnvironment *RR,Path *path,uint64_t now,bool force); /** * @return All known direct paths to this peer */ - inline std::vector paths() const + inline std::vector paths() const { - std::vector pp; + std::vector pp; Mutex::Lock _l(_lock); for(unsigned int p=0,np=_numPaths;p_paths[np->_numPaths++].deserialize(b,p); } else { // Skip any paths beyond max, but still read stream - RemotePath foo; + Path foo; p += foo.deserialize(b,p); } } @@ -557,8 +557,8 @@ public: private: void _sortPaths(const uint64_t now); - RemotePath *_getBestPath(const uint64_t now); - RemotePath *_getBestPath(const uint64_t now,int inetAddressFamily); + Path *_getBestPath(const uint64_t now); + Path *_getBestPath(const uint64_t now,int inetAddressFamily); unsigned char _key[ZT_PEER_SECRET_KEY_LENGTH]; // computed with key agreement, not serialized @@ -575,7 +575,7 @@ private: uint16_t _vMinor; uint16_t _vRevision; Identity _id; - RemotePath _paths[ZT_MAX_PEER_NETWORK_PATHS]; + Path _paths[ZT_MAX_PEER_NETWORK_PATHS]; unsigned int _numPaths; unsigned int _latency; diff --git a/node/RemotePath.hpp b/node/RemotePath.hpp deleted file mode 100644 index 8b37621a..00000000 --- a/node/RemotePath.hpp +++ /dev/null @@ -1,161 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2015 ZeroTier, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * ZeroTier may be used and distributed under the terms of the GPLv3, which - * are available at: http://www.gnu.org/licenses/gpl-3.0.html - * - * If you would like to embed ZeroTier into a commercial application or - * redistribute it in a modified binary form, please contact ZeroTier Networks - * LLC. Start here: http://www.zerotier.com/ - */ - -#ifndef ZT_REMOTEPATH_HPP -#define ZT_REMOTEPATH_HPP - -#include -#include - -#include -#include - -#include "Path.hpp" -#include "Node.hpp" -#include "AntiRecursion.hpp" -#include "RuntimeEnvironment.hpp" - -namespace ZeroTier { - -/** - * Path to a remote peer - * - * This extends Path to include status information about path activity. - */ -class RemotePath : public Path -{ -public: - RemotePath() : - Path(), - _lastSend(0), - _lastReceived(0), - _localAddress(), - _flags(0) {} - - RemotePath(const InetAddress &localAddress,const InetAddress &addr) : - Path(addr,0,TRUST_NORMAL), - _lastSend(0), - _lastReceived(0), - _localAddress(localAddress), - _flags(0) {} - - inline const InetAddress &localAddress() const throw() { return _localAddress; } - - inline uint64_t lastSend() const throw() { return _lastSend; } - inline uint64_t lastReceived() const throw() { return _lastReceived; } - - /** - * Called when a packet is sent to this remote path - * - * This is called automatically by RemotePath::send(). - * - * @param t Time of send - */ - inline void sent(uint64_t t) - throw() - { - _lastSend = t; - } - - /** - * Called when a packet is received from this remote path - * - * @param t Time of receive - */ - inline void received(uint64_t t) - throw() - { - _lastReceived = t; - } - - /** - * @param now Current time - * @return True if this path appears active - */ - inline bool active(uint64_t now) const - throw() - { - return ((now - _lastReceived) < ZT_PEER_ACTIVITY_TIMEOUT); - } - - /** - * Send a packet via this path - * - * @param RR Runtime environment - * @param data Packet data - * @param len Packet length - * @param now Current time - * @return True if transport reported success - */ - inline bool send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) - { - if (RR->node->putPacket(_localAddress,address(),data,len)) { - sent(now); - RR->antiRec->logOutgoingZT(data,len); - return true; - } - return false; - } - - template - inline void serialize(Buffer &b) const - { - b.append((uint8_t)1); // version - _addr.serialize(b); - b.append((uint8_t)_trust); - b.append((uint64_t)_lastSend); - b.append((uint64_t)_lastReceived); - _localAddress.serialize(b); - b.append((uint16_t)_flags); - } - - template - inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) - { - unsigned int p = startAt; - if (b[p++] != 1) - throw std::invalid_argument("invalid serialized RemotePath"); - p += _addr.deserialize(b,p); - _ipScope = _addr.ipScope(); - _trust = (Path::Trust)b[p++]; - _lastSend = b.template at(p); p += 8; - _lastReceived = b.template at(p); p += 8; - p += _localAddress.deserialize(b,p); - _flags = b.template at(p); p += 2; - return (p - startAt); - } - -protected: - uint64_t _lastSend; - uint64_t _lastReceived; - InetAddress _localAddress; - uint16_t _flags; -}; - -} // namespace ZeroTier - -#endif diff --git a/node/SelfAwareness.cpp b/node/SelfAwareness.cpp index 81d19369..b4841544 100644 --- a/node/SelfAwareness.cpp +++ b/node/SelfAwareness.cpp @@ -125,7 +125,7 @@ void SelfAwareness::iam(const Address &reporter,const InetAddress &reporterPhysi // they are still considered alive so that we will re-establish direct links. SharedPtr r(RR->topology->getBestRoot()); if (r) { - RemotePath *rp = r->getBestPath(now); + Path *rp = r->getBestPath(now); if (rp) { for(std::vector< SharedPtr >::const_iterator p(rset.peersReset.begin());p!=rset.peersReset.end();++p) { if ((*p)->alive(now)) { diff --git a/node/Switch.cpp b/node/Switch.cpp index 772eaf02..2f72f57a 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -736,7 +736,7 @@ bool Switch::_trySend(const Packet &packet,bool encrypt,uint64_t nwid) return false; // sanity check: unconfigured network? why are we trying to talk to it? } - RemotePath *viaPath = peer->getBestPath(now); + Path *viaPath = peer->getBestPath(now); SharedPtr relay; if (!viaPath) { // See if this network has a preferred relay (if packet has an associated network) diff --git a/objects.mk b/objects.mk index 6dd5ea30..540072d5 100644 --- a/objects.mk +++ b/objects.mk @@ -15,6 +15,7 @@ OBJS=\ node/Node.o \ node/OutboundMulticast.o \ node/Packet.o \ + node/Path.o \ node/Peer.o \ node/Poly1305.o \ node/Salsa20.o \ diff --git a/service/OneService.cpp b/service/OneService.cpp index 1765b5c4..4e3f24c7 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -731,7 +731,7 @@ public: #ifdef ZT_USE_MINIUPNPC std::vector upnpAddresses(_upnpClient->get()); for(std::vector::const_iterator ext(upnpAddresses.begin());ext!=upnpAddresses.end();++ext) - _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext)),0,ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); + _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext)),ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); #endif struct ifaddrs *ifatbl = (struct ifaddrs *)0; @@ -749,7 +749,7 @@ public: if (!isZT) { InetAddress ip(ifa->ifa_addr); ip.setPort(_port); - _node->addLocalInterfaceAddress(reinterpret_cast(&ip),0,ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); + _node->addLocalInterfaceAddress(reinterpret_cast(&ip),ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); } } ifa = ifa->ifa_next; -- cgit v1.2.3 From 51fcc753549e4f7c18efb889a841c4dd4fb9e6cf Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 27 Oct 2015 17:36:47 -0700 Subject: Some cleanup, and use getPeerNoCache() exclusively in Cluster. --- node/Cluster.cpp | 42 ++++++++++++++++++++++++++++++------------ node/Cluster.hpp | 3 ++- node/Path.hpp | 8 ++++++++ 3 files changed, 40 insertions(+), 13 deletions(-) (limited to 'node/Path.hpp') diff --git a/node/Cluster.cpp b/node/Cluster.cpp index 0535f9ee..9b034822 100644 --- a/node/Cluster.cpp +++ b/node/Cluster.cpp @@ -83,7 +83,8 @@ Cluster::Cluster( _id(id), _zeroTierPhysicalEndpoints(zeroTierPhysicalEndpoints), _members(new _Member[ZT_CLUSTER_MAX_MEMBERS]), - _peerAffinities(65536) + _peerAffinities(65536), + _lastCleanedPeerAffinities(0) { uint16_t stmp[ZT_SHA512_DIGEST_LEN / sizeof(uint16_t)]; @@ -247,11 +248,13 @@ void Cluster::handleIncomingStateMessage(const void *msg,unsigned int len) } break; case STATE_MESSAGE_COM: { + /* not currently used so not decoded yet CertificateOfMembership com; ptr += com.deserialize(dmsg,ptr); if (com) { TRACE("[%u] COM for %s on %.16llu rev %llu",(unsigned int)fromMemberId,com.issuedTo().toString().c_str(),com.networkId(),com.revision()); } + */ } break; case STATE_MESSAGE_PROXY_UNITE: { @@ -262,12 +265,13 @@ void Cluster::handleIncomingStateMessage(const void *msg,unsigned int len) for(unsigned int i=0;i localPeer(RR->topology->getPeer(localPeerAddress)); + const uint64_t now = RR->node->now(); + SharedPtr localPeer(RR->topology->getPeerNoCache(localPeerAddress,now)); if ((localPeer)&&(numRemotePeerPaths > 0)) { InetAddress bestLocalV4,bestLocalV6; - localPeer->getBestActiveAddresses(RR->node->now(),bestLocalV4,bestLocalV6); + localPeer->getBestActiveAddresses(now,bestLocalV4,bestLocalV6); InetAddress bestRemoteV4,bestRemoteV6; for(unsigned int i=0;i buf; + Buffer<1024> buf; if (unite) { InetAddress v4,v6; if (fromPeerAddress) { - SharedPtr fromPeer(RR->topology->getPeer(fromPeerAddress)); + SharedPtr fromPeer(RR->topology->getPeerNoCache(fromPeerAddress,now)); if (fromPeer) fromPeer->getBestActiveAddresses(now,v4,v6); } @@ -408,7 +412,7 @@ bool Cluster::sendViaCluster(const Address &fromPeerAddress,const Address &toPee void Cluster::replicateHavePeer(const Identity &peerId,const InetAddress &physicalAddress) { const uint64_t now = RR->node->now(); - { // Use peer affinity table to track our own last announce time for peers + { Mutex::Lock _l2(_peerAffinities_m); _PA &pa = _peerAffinities[peerId.address()]; if (pa.mid != _id) { @@ -436,7 +440,7 @@ void Cluster::replicateHavePeer(const Identity &peerId,const InetAddress &physic void Cluster::replicateMulticastLike(uint64_t nwid,const Address &peerAddress,const MulticastGroup &group) { - Buffer<2048> buf; + Buffer<1024> buf; buf.append((uint64_t)nwid); peerAddress.appendTo(buf); group.mac().appendTo(buf); @@ -453,7 +457,7 @@ void Cluster::replicateMulticastLike(uint64_t nwid,const Address &peerAddress,co void Cluster::replicateCertificateOfNetworkMembership(const CertificateOfMembership &com) { - Buffer<2048> buf; + Buffer<4096> buf; com.serialize(buf); TRACE("replicating %s COM for %.16llx to all members",com.issuedTo().toString().c_str(),com.networkId()); { @@ -502,6 +506,20 @@ void Cluster::doPeriodicTasks() _flush(*mid); // does nothing if nothing to flush } } + + { + if ((now - _lastCleanedPeerAffinities) >= (ZT_PEER_ACTIVITY_TIMEOUT * 10)) { + _lastCleanedPeerAffinities = now; + Address *k = (Address *)0; + _PA *v = (_PA *)0; + Mutex::Lock _l(_peerAffinities_m); + Hashtable< Address,_PA >::Iterator i(_peerAffinities); + while (i.next(k,v)) { + if ((now - v->ts) >= (ZT_PEER_ACTIVITY_TIMEOUT * 10)) + _peerAffinities.erase(*k); + } + } + } } void Cluster::addMember(uint16_t memberId) @@ -563,7 +581,7 @@ bool Cluster::findBetterEndpoint(InetAddress &redirectTo,const Address &peerAddr // Find member closest to this peer const uint64_t now = RR->node->now(); - std::vector best; // initial "best" is for peer to stay put + std::vector best; const double currentDistance = _dist3d(_x,_y,_z,px,py,pz); double bestDistance = (offload ? 2147483648.0 : currentDistance); unsigned int bestMember = _id; @@ -575,7 +593,7 @@ bool Cluster::findBetterEndpoint(InetAddress &redirectTo,const Address &peerAddr // Consider member if it's alive and has sent us a location and one or more physical endpoints to send peers to if ( ((now - m.lastReceivedAliveAnnouncement) < ZT_CLUSTER_TIMEOUT) && ((m.x != 0)||(m.y != 0)||(m.z != 0)) && (m.zeroTierPhysicalEndpoints.size() > 0) ) { - double mdist = _dist3d(m.x,m.y,m.z,px,py,pz); + const double mdist = _dist3d(m.x,m.y,m.z,px,py,pz); if (mdist < bestDistance) { bestDistance = mdist; bestMember = *mid; @@ -585,7 +603,7 @@ bool Cluster::findBetterEndpoint(InetAddress &redirectTo,const Address &peerAddr } } - // Suggestion redirection if a closer member was found + // Redirect to a closer member if it has a ZeroTier endpoint address in the same ss_family for(std::vector::const_iterator a(best.begin());a!=best.end();++a) { if (a->ss_family == peerPhysicalAddress.ss_family) { TRACE("%s at [%d,%d,%d] is %f from us but %f from %u, can redirect to %s",peerAddress.toString().c_str(),px,py,pz,currentDistance,bestDistance,bestMember,a->toString().c_str()); diff --git a/node/Cluster.hpp b/node/Cluster.hpp index c3367d57..cc9edd1d 100644 --- a/node/Cluster.hpp +++ b/node/Cluster.hpp @@ -47,7 +47,7 @@ /** * Timeout for cluster members being considered "alive" */ -#define ZT_CLUSTER_TIMEOUT 10000 +#define ZT_CLUSTER_TIMEOUT 20000 /** * How often should we announce that we have a peer? @@ -349,6 +349,7 @@ private: }; Hashtable< Address,_PA > _peerAffinities; Mutex _peerAffinities_m; + uint64_t _lastCleanedPeerAffinities; }; } // namespace ZeroTier diff --git a/node/Path.hpp b/node/Path.hpp index 99f6590b..2b05b812 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -95,6 +95,14 @@ public: { } + inline Path &operator=(const Path &p) + throw() + { + if (this != &p) + memcpy(this,&p,sizeof(Path)); + return *this; + } + /** * Called when a packet is sent to this remote path * -- cgit v1.2.3 From a994573a436ec2835781d13ecd2307e18c67855b Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 29 Oct 2015 09:42:15 -0700 Subject: Eliminate some more dead code. We may do path trust, but not like that. --- include/ZeroTierOne.h | 17 +---------------- node/Node.cpp | 6 +++--- node/Node.hpp | 2 +- node/Path.hpp | 16 +++------------- node/Peer.cpp | 2 +- service/OneService.cpp | 4 ++-- 6 files changed, 11 insertions(+), 36 deletions(-) (limited to 'node/Path.hpp') diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index 01c8bcde..e9b38c52 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -424,15 +424,6 @@ enum ZT_VirtualNetworkConfigOperation ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY = 4 }; -/** - * Local interface trust levels - */ -enum ZT_LocalInterfaceAddressTrust { - ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL = 0, - ZT_LOCAL_INTERFACE_ADDRESS_TRUST_PRIVACY = 10, - ZT_LOCAL_INTERFACE_ADDRESS_TRUST_ULTIMATE = 20 -}; - /** * What trust hierarchy role does this peer have? */ @@ -1337,11 +1328,6 @@ void ZT_Node_freeQueryResult(ZT_Node *node,void *qr); /** * Add a local interface address * - * Local interface addresses may be added if you want remote peers - * with whom you have a trust relatinship (e.g. common network membership) - * to receive information about these endpoints as potential endpoints for - * direct communication. - * * Take care that these are never ZeroTier interface addresses, otherwise * strange things might happen or they simply won't work. * @@ -1356,10 +1342,9 @@ void ZT_Node_freeQueryResult(ZT_Node *node,void *qr); * reject bad, empty, and unusable addresses. * * @param addr Local interface address - * @param trust How much do you trust the local network under this interface? * @return Boolean: non-zero if address was accepted and added */ -int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr,enum ZT_LocalInterfaceAddressTrust trust); +int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr); /** * Clear local interface addresses diff --git a/node/Node.cpp b/node/Node.cpp index 82cda66d..42180e99 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -499,7 +499,7 @@ void Node::freeQueryResult(void *qr) ::free(qr); } -int Node::addLocalInterfaceAddress(const struct sockaddr_storage *addr,ZT_LocalInterfaceAddressTrust trust) +int Node::addLocalInterfaceAddress(const struct sockaddr_storage *addr) { if (Path::isAddressValidForPath(*(reinterpret_cast(addr)))) { Mutex::Lock _l(_directPaths_m); @@ -900,10 +900,10 @@ void ZT_Node_freeQueryResult(ZT_Node *node,void *qr) } catch ( ... ) {} } -int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr,enum ZT_LocalInterfaceAddressTrust trust) +int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr) { try { - return reinterpret_cast(node)->addLocalInterfaceAddress(addr,trust); + return reinterpret_cast(node)->addLocalInterfaceAddress(addr); } catch ( ... ) { return 0; } diff --git a/node/Node.hpp b/node/Node.hpp index 48c5ead8..9b85b832 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -105,7 +105,7 @@ public: ZT_VirtualNetworkConfig *networkConfig(uint64_t nwid) const; ZT_VirtualNetworkList *networks() const; void freeQueryResult(void *qr); - int addLocalInterfaceAddress(const struct sockaddr_storage *addr,ZT_LocalInterfaceAddressTrust trust); + int addLocalInterfaceAddress(const struct sockaddr_storage *addr); void clearLocalInterfaceAddresses(); void setNetconfMaster(void *networkControllerInstance); ZT_ResultCode circuitTestBegin(ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *)); diff --git a/node/Path.hpp b/node/Path.hpp index 2b05b812..c0182990 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -79,18 +79,16 @@ public: _addr(), _localAddress(), _ipScope(InetAddress::IP_SCOPE_NONE), - _trust(TRUST_NORMAL), _flags(0) { } - Path(const InetAddress &localAddress,const InetAddress &addr,Trust trust) : + Path(const InetAddress &localAddress,const InetAddress &addr) : _lastSend(0), _lastReceived(0), _addr(addr), _localAddress(localAddress), _ipScope(addr.ipScope()), - _trust(trust), _flags(0) { } @@ -187,11 +185,6 @@ public: return ( ((int)_ipScope * 2) + ((_addr.ss_family == AF_INET6) ? 1 : 0) ); } - /** - * @return Path trust level - */ - inline Trust trust() const throw() { return _trust; } - /** * @return True if path is considered reliable (no NAT keepalives etc. are needed) */ @@ -243,12 +236,11 @@ public: template inline void serialize(Buffer &b) const { - b.append((uint8_t)0); // version + b.append((uint8_t)1); // version b.append((uint64_t)_lastSend); b.append((uint64_t)_lastReceived); _addr.serialize(b); _localAddress.serialize(b); - b.append((uint8_t)_trust); b.append((uint16_t)_flags); } @@ -256,14 +248,13 @@ public: inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) { unsigned int p = startAt; - if (b[p++] != 0) + if (b[p++] != 1) throw std::invalid_argument("invalid serialized Path"); _lastSend = b.template at(p); p += 8; _lastReceived = b.template at(p); p += 8; p += _addr.deserialize(b,p); p += _localAddress.deserialize(b,p); _ipScope = _addr.ipScope(); - _trust = (Path::Trust)b[p++]; _flags = b.template at(p); p += 2; return (p - startAt); } @@ -274,7 +265,6 @@ private: InetAddress _addr; InetAddress _localAddress; InetAddress::IpScope _ipScope; // memoize this since it's a computed value checked often - Trust _trust; uint16_t _flags; }; diff --git a/node/Peer.cpp b/node/Peer.cpp index 976c7c44..9d0d78e5 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -179,7 +179,7 @@ void Peer::received( } } if (slot) { - *slot = Path(localAddr,remoteAddr,Path::TRUST_NORMAL); + *slot = Path(localAddr,remoteAddr); slot->received(now); _numPaths = np; pathIsConfirmed = true; diff --git a/service/OneService.cpp b/service/OneService.cpp index 4e3f24c7..8c8ff1ed 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -731,7 +731,7 @@ public: #ifdef ZT_USE_MINIUPNPC std::vector upnpAddresses(_upnpClient->get()); for(std::vector::const_iterator ext(upnpAddresses.begin());ext!=upnpAddresses.end();++ext) - _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext)),ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); + _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext))); #endif struct ifaddrs *ifatbl = (struct ifaddrs *)0; @@ -749,7 +749,7 @@ public: if (!isZT) { InetAddress ip(ifa->ifa_addr); ip.setPort(_port); - _node->addLocalInterfaceAddress(reinterpret_cast(&ip),ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); + _node->addLocalInterfaceAddress(reinterpret_cast(&ip)); } } ifa = ifa->ifa_next; -- cgit v1.2.3 From 9f0f0197fe5a79ed04647b110485a530ed06ed8e Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 29 Oct 2015 09:44:25 -0700 Subject: More dead code removal. --- node/Path.hpp | 33 ++------------------------------- 1 file changed, 2 insertions(+), 31 deletions(-) (limited to 'node/Path.hpp') diff --git a/node/Path.hpp b/node/Path.hpp index c0182990..39a18c43 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -49,37 +49,12 @@ class RuntimeEnvironment; class Path { public: - /** - * Path trust category - * - * Note that this is NOT peer trust and has nothing to do with root server - * designations or other trust metrics. This indicates how much we trust - * this path to be secure and/or private. A trust level of normal means - * encrypt and authenticate all traffic. Privacy trust means we can send - * traffic in the clear. Ultimate trust means we don't even need - * authentication. Generally a private path would be a hard-wired local - * LAN, while an ultimate trust path would be a physically isolated private - * server backplane. - * - * Nearly all paths will be normal trust. The other levels are for high - * performance local SDN use only. - * - * These values MUST match ZT_LocalInterfaceAddressTrust in ZeroTierOne.h - */ - enum Trust // NOTE: max 255 - { - TRUST_NORMAL = 0, - TRUST_PRIVACY = 10, - TRUST_ULTIMATE = 20 - }; - Path() : _lastSend(0), _lastReceived(0), _addr(), _localAddress(), - _ipScope(InetAddress::IP_SCOPE_NONE), - _flags(0) + _ipScope(InetAddress::IP_SCOPE_NONE) { } @@ -88,8 +63,7 @@ public: _lastReceived(0), _addr(addr), _localAddress(localAddress), - _ipScope(addr.ipScope()), - _flags(0) + _ipScope(addr.ipScope()) { } @@ -241,7 +215,6 @@ public: b.append((uint64_t)_lastReceived); _addr.serialize(b); _localAddress.serialize(b); - b.append((uint16_t)_flags); } template @@ -255,7 +228,6 @@ public: p += _addr.deserialize(b,p); p += _localAddress.deserialize(b,p); _ipScope = _addr.ipScope(); - _flags = b.template at(p); p += 2; return (p - startAt); } @@ -265,7 +237,6 @@ private: InetAddress _addr; InetAddress _localAddress; InetAddress::IpScope _ipScope; // memoize this since it's a computed value checked often - uint16_t _flags; }; } // namespace ZeroTier -- cgit v1.2.3 From 35c4e28f314881f3f6647deaaaf3e58d2ccb5417 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 9 Nov 2015 14:25:28 -0800 Subject: Mark geo-redirected paths as suboptimal and do not report that we have a peer if all we have is one of these. Also a few other small fixes. --- node/Cluster.cpp | 2 +- node/Cluster.hpp | 2 +- node/Path.hpp | 44 +++++++++++++++++++++++++++++++------------- node/Peer.cpp | 8 ++++++++ node/Peer.hpp | 49 ++++++++++++++++++------------------------------- service/OneService.cpp | 2 +- 6 files changed, 60 insertions(+), 47 deletions(-) (limited to 'node/Path.hpp') diff --git a/node/Cluster.cpp b/node/Cluster.cpp index 419948e2..a819372e 100644 --- a/node/Cluster.cpp +++ b/node/Cluster.cpp @@ -239,7 +239,7 @@ void Cluster::handleIncomingStateMessage(const void *msg,unsigned int len) case CLUSTER_MESSAGE_WANT_PEER: { const Address zeroTierAddress(dmsg.field(ptr,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); ptr += ZT_ADDRESS_LENGTH; SharedPtr peer(RR->topology->getPeerNoCache(zeroTierAddress)); - if ( (peer) && (peer->hasActiveDirectPath(RR->node->now())) ) { + if ( (peer) && (peer->hasClusterOptimalPath(RR->node->now())) ) { Buffer<1024> buf; peer->identity().serialize(buf); Mutex::Lock _l2(_members[fromMemberId].lock); diff --git a/node/Cluster.hpp b/node/Cluster.hpp index 4197a14b..1c4331b4 100644 --- a/node/Cluster.hpp +++ b/node/Cluster.hpp @@ -55,7 +55,7 @@ * A cluster member is considered dead and will no longer have peers * redirected to it if we have not heard a heartbeat in this long. */ -#define ZT_CLUSTER_TIMEOUT 10000 +#define ZT_CLUSTER_TIMEOUT 5000 /** * Desired period between doPeriodicTasks() in milliseconds diff --git a/node/Path.hpp b/node/Path.hpp index 39a18c43..00f8ed36 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -37,6 +37,16 @@ #include "Constants.hpp" #include "InetAddress.hpp" +/** + * Flag indicating that this path is suboptimal + * + * This is used in cluster mode to indicate that the peer has been directed + * to a better path. This path can continue to be used but shouldn't be kept + * or advertised to other cluster members. Not used if clustering is not + * built and enabled. + */ +#define ZT_PATH_FLAG_CLUSTER_SUBOPTIMAL 0x0001 + namespace ZeroTier { class RuntimeEnvironment; @@ -54,6 +64,7 @@ public: _lastReceived(0), _addr(), _localAddress(), + _flags(0), _ipScope(InetAddress::IP_SCOPE_NONE) { } @@ -63,12 +74,12 @@ public: _lastReceived(0), _addr(addr), _localAddress(localAddress), + _flags(0), _ipScope(addr.ipScope()) { } inline Path &operator=(const Path &p) - throw() { if (this != &p) memcpy(this,&p,sizeof(Path)); @@ -82,22 +93,14 @@ public: * * @param t Time of send */ - inline void sent(uint64_t t) - throw() - { - _lastSend = t; - } + inline void sent(uint64_t t) { _lastSend = t; } /** * Called when a packet is received from this remote path * * @param t Time of receive */ - inline void received(uint64_t t) - throw() - { - _lastReceived = t; - } + inline void received(uint64_t t) { _lastReceived = t; } /** * @param now Current time @@ -207,26 +210,40 @@ public: return false; } +#ifdef ZT_ENABLE_CLUSTER + /** + * @param f New value of ZT_PATH_FLAG_CLUSTER_SUBOPTIMAL + */ + inline void setClusterSuboptimal(bool f) { _flags = ((f) ? (_flags | ZT_PATH_FLAG_CLUSTER_SUBOPTIMAL) : (_flags & (~ZT_PATH_FLAG_CLUSTER_SUBOPTIMAL))); } + + /** + * @return True if ZT_PATH_FLAG_CLUSTER_SUBOPTIMAL is set + */ + inline bool isClusterSuboptimal() const { return ((_flags & ZT_PATH_FLAG_CLUSTER_SUBOPTIMAL) != 0); } +#endif + template inline void serialize(Buffer &b) const { - b.append((uint8_t)1); // version + b.append((uint8_t)0); // version b.append((uint64_t)_lastSend); b.append((uint64_t)_lastReceived); _addr.serialize(b); _localAddress.serialize(b); + b.append((uint16_t)_flags); } template inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) { unsigned int p = startAt; - if (b[p++] != 1) + if (b[p++] != 0) throw std::invalid_argument("invalid serialized Path"); _lastSend = b.template at(p); p += 8; _lastReceived = b.template at(p); p += 8; p += _addr.deserialize(b,p); p += _localAddress.deserialize(b,p); + _flags = b.template at(p); p += 2; _ipScope = _addr.ipScope(); return (p - startAt); } @@ -236,6 +253,7 @@ private: uint64_t _lastReceived; InetAddress _addr; InetAddress _localAddress; + unsigned int _flags; InetAddress::IpScope _ipScope; // memoize this since it's a computed value checked often }; diff --git a/node/Peer.cpp b/node/Peer.cpp index 6f987da2..0e90b17d 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -83,6 +83,7 @@ void Peer::received( Packet::Verb inReVerb) { #ifdef ZT_ENABLE_CLUSTER + bool suboptimalPath = false; if ((RR->cluster)&&(hops == 0)) { // Note: findBetterEndpoint() is first since we still want to check // for a better endpoint even if we don't actually send a redirect. @@ -124,6 +125,7 @@ void Peer::received( RR->antiRec->logOutgoingZT(outp.data(),outp.size()); RR->node->putPacket(localAddr,remoteAddr,outp.data(),outp.size()); } + suboptimalPath = true; } } #endif @@ -151,6 +153,9 @@ void Peer::received( for(unsigned int p=0;preceived(now); +#ifdef ZT_ENABLE_CLUSTER + slot->setClusterSuboptimal(suboptimalPath); +#endif _numPaths = np; pathIsConfirmed = true; _sortPaths(now); diff --git a/node/Peer.hpp b/node/Peer.hpp index 42708128..bf627caf 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -269,7 +269,6 @@ public: * @param l Direct latency measurment in ms */ inline void addDirectLatencyMeasurment(unsigned int l) - throw() { unsigned int ol = _latency; if ((ol > 0)&&(ol < 10000)) @@ -282,7 +281,6 @@ public: * @return True if this peer has at least one active direct path */ inline bool hasActiveDirectPath(uint64_t now) const - throw() { Mutex::Lock _l(_lock); for(unsigned int p=0,np=_numPaths;p 0)||(_vMinor > 0)||(_vRevision > 0)); } - /** - * Check whether this peer's version is both known and is at least what is specified - * - * @param major Major version to check against - * @param minor Minor version - * @param rev Revision - * @return True if peer's version is at least supplied tuple - */ - inline bool atLeastVersion(unsigned int major,unsigned int minor,unsigned int rev) - throw() - { - Mutex::Lock _l(_lock); - if ((_vMajor > 0)||(_vMinor > 0)||(_vRevision > 0)) { - if (_vMajor > major) - return true; - else if (_vMajor == major) { - if (_vMinor > minor) - return true; - else if (_vMinor == minor) { - if (_vRevision >= rev) - return true; - } - } - } - return false; - } - /** * Get most recently active path addresses for IPv4 and/or IPv6 * @@ -467,7 +454,7 @@ public: const unsigned int recSizePos = b.size(); b.addSize(4); // space for uint32_t field length - b.append((uint16_t)1); // version of serialized Peer data + b.append((uint16_t)0); // version of serialized Peer data _id.serialize(b,false); @@ -531,7 +518,7 @@ public: const unsigned int recSize = b.template at(p); p += 4; if ((p + recSize) > b.size()) return SharedPtr(); // size invalid - if (b.template at(p) != 1) + if (b.template at(p) != 0) return SharedPtr(); // version mismatch p += 2; diff --git a/service/OneService.cpp b/service/OneService.cpp index 299d6697..684dc470 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -517,7 +517,7 @@ public: for(int k=0;k<512;++k) { const unsigned int upnport = 40000 + (((port + 1) * (k + 1)) % 25500); _v4UpnpLocalAddress = InetAddress(0,upnport); - _v4UpnpUdpSocket = _phy.udpBind((const struct sockaddr *)&_v4UpnpLocalAddress,reinterpret_cast(&_v4UpnpLocalAddress),131072); + _v4UpnpUdpSocket = _phy.udpBind((const struct sockaddr *)&_v4UpnpLocalAddress,reinterpret_cast(&_v4UpnpLocalAddress),ZT_UDP_DESIRED_BUF_SIZE); if (_v4UpnpUdpSocket) { _upnpClient = new UPNPClient(upnport); break; -- cgit v1.2.3