From a69e1876f10266e5578be0a469ae7498f705fe96 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 2 Apr 2015 17:54:56 -0700 Subject: [PATCH] The concept of link desperation (escalating to less desirable transports) simplifies a ton of stuff. Loads of spaghetti logic can die since we no longer have to make these decisions down in the core. --- include/ZeroTierOne.h | 22 ++--- node/Constants.hpp | 4 +- node/Node.cpp | 5 +- node/Node.hpp | 45 ++------- node/Path.hpp | 124 ++++++++++++----------- node/Peer.cpp | 223 +++++++++++++----------------------------- node/Peer.hpp | 82 ++++------------ node/Switch.cpp | 32 +----- node/Switch.hpp | 25 ----- node/Topology.cpp | 5 +- node/Topology.hpp | 41 +------- 11 files changed, 180 insertions(+), 428 deletions(-) diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index f7e952968..90f92b4a8 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -144,19 +144,17 @@ enum ZT1_ResultCode enum ZT1_NodeStatusCode { /** - * Node is online + * Node is offline -- nothing is reachable + */ + ZT1_NODE_STATUS_OFFLINE = 0, + + /** + * Node is online -- at least one upstream is reachable */ ZT1_NODE_STATUS_ONLINE = 1, /** - * Node is offline -- nothing is reachable - */ - ZT1_NODE_STATUS_OFFLINE = 2, - - /** - * The desperation level has changed - * - * 'extra' will point to an int containing the new level. + * Link desperation level has changed */ ZT1_NODE_STATUS_DESPERATION_CHANGE = 3 }; @@ -407,12 +405,12 @@ typedef struct } ZT1_PeerPhysicalPath; /** - * What trust hierarchy role does this device have? + * What trust hierarchy role does this peer have? */ enum ZT1_PeerRole { - ZT1_PEER_ROLE_SUPERNODE = 0, // planetary supernode + ZT1_PEER_ROLE_NODE = 0 // ordinary node ZT1_PEER_ROLE_HUB = 1, // locally federated hub - ZT1_PEER_ROLE_NODE = 2 // ordinary node + ZT1_PEER_ROLE_SUPERNODE = 2, // planetary supernode }; /** diff --git a/node/Constants.hpp b/node/Constants.hpp index 212276829..8cef29e61 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -287,9 +287,9 @@ #define ZT_DESPERATION_INCREMENT (ZT_STARTUP_AGGRO * 2) /** - * "Spam" packets to lower desperation links every Nth packet + * Interval between "spams" if desperation > 0 */ -#define ZT_DESPERATION_SPAM_EVERY 10 +#define ZT_DESPERATION_SPAM_INTERVAL 60000 /** * Maximum delay between runs of the main loop in Node.cpp diff --git a/node/Node.cpp b/node/Node.cpp index c36b82d9b..936a5b60e 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -61,10 +61,7 @@ Node::Node( _statusCallback(statusCallback), _networks(), _networks_m(), - _now(now), - _timeOfLastPacketReceived(0), - _timeOfLastPrivilegedPacket(0), - _spamCounter(0) + _now(now) { try { RR->prng = new CMWC4096(); diff --git a/node/Node.hpp b/node/Node.hpp index 461b9e9ac..f7cab5f7b 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -104,51 +104,25 @@ public: */ inline uint64_t now() const throw() { return _now; } - /** - * @return Current level of desperation - */ - inline int desperation() const throw() { return (int)((_now - _timeOfLastPrivilgedPacket) / ZT_DESPERATION_INCREMENT); } - - /** - * Called to update last packet receive time whenever a packet is received - * - * @param fromPrivilegedPeer If true, peer is a supernode or federated hub (a.k.a. an upstream link) - */ - inline void packetReceived(bool fromPrivilegedPeer) - throw() - { - const uint64_t n = _now; - _timeOfLastPacketReceived = n; - if (fromPrivilegedPeer) - _timeOfLastPrivilgedPacket = n; - } - - /** - * @return Most recent time of any packet receipt - */ - inline uint64_t timeOfLastPacketReceived() const throw() { return _timeOfLastPacketReceived; } - - /** - * @return Timestamp of last packet received from a supernode or hub (upstream link) - */ - inline uint64_t timeOfLastPrivilgedPacket() const throw() { return _timeOfLastPrivilgedPacket; } - /** * Enqueue a ZeroTier message to be sent * * @param addr Destination address * @param data Packet data * @param len Packet length + * @param desperation Link desperation for reaching this address + * @param spam If true, flag this packet to be spammed to lower-desperation links + * @return True if packet appears to have been sent */ - inline void putPacket(const InetAddress &addr,const void *data,unsigned int len) + inline bool putPacket(const InetAddress &addr,const void *data,unsigned int len,int desperation,bool spam) { - _wirePacketSendFunction( + return (_wirePacketSendFunction( reinterpret_cast(this), reinterpret_cast(&addr), - this->desperation(), - (int)((++_spamCounter % ZT_DESPERATION_SPAM_EVERY) == 0), + desperation, + (int)spam, data, - len); + len) == 0); } /** @@ -216,9 +190,6 @@ private: Mutex _networks_m; volatile uint64_t _now; // time of last run() - volatile uint64_t _timeOfLastPacketReceived; - volatile _timeOfLastPrivilgedPacket; - volatile unsigned int _spamCounter; // used to "spam" every Nth packet }; } // namespace ZeroTier diff --git a/node/Path.hpp b/node/Path.hpp index 9d0f66123..df68339e9 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -33,6 +33,7 @@ #include #include +#include #include "Constants.hpp" #include "InetAddress.hpp" @@ -49,42 +50,28 @@ namespace ZeroTier { class Path { public: - enum Type - { - PATH_TYPE_NULL = 0, - PATH_TYPE_UDP = 1, - PATH_TYPE_TCP_OUT = 2, - PATH_TYPE_TCP_IN = 3 - }; - Path() : _lastSend(0), _lastReceived(0), - _lastPing(0), _addr(), - _type(PATH_TYPE_NULL), + _lastReceiveDesperation(0), _fixed(false) {} - Path(const Path &p) - { - memcpy(this,&p,sizeof(Path)); - } + Path(const Path &p) throw() { memcpy(this,&p,sizeof(Path)); } - Path(const InetAddress &addr,Type t,bool fixed = false) : + Path(const InetAddress &addr,bool fixed) : _lastSend(0), _lastReceived(0), - _lastPing(0), _addr(addr), - _type(t), + _lastReceiveDesperation(0), _fixed(fixed) {} - inline void init(const InetAddress &addr,Type t,bool fixed = false) + inline void init(const InetAddress &addr,bool fixed) { _lastSend = 0; _lastReceived = 0; - _lastPing = 0; _addr = addr; - _type = t; + _lastReceiveDesperation = 0; _fixed = fixed; } @@ -97,19 +84,54 @@ public: inline const InetAddress &address() const throw() { return _addr; } - inline Type type() const throw() { return _type; } - inline bool tcp() const throw() { return ((_type == PATH_TYPE_TCP_IN)||(_type == PATH_TYPE_TCP_OUT)); } - inline uint64_t lastSend() const throw() { return _lastSend; } inline uint64_t lastReceived() const throw() { return _lastReceived; } - inline uint64_t lastPing() const throw() { return _lastPing; } + inline int lastReceiveDesperation() const throw() { return _lastReceiveDesperation; } + /** + * Called when a packet is sent to this path + * + * @param t Time of send + */ + inline void sent(uint64_t t) throw() { _lastSend = t; } + + /** + * Called when a packet is received from this path + * + * @param t Time of receive + * @param d Link desperation of receive + */ + inline void received(uint64_t t,int d) throw() { _lastReceived = t; _lastReceiveDesperation = d; } + + /** + * @return Is this a fixed path? + */ inline bool fixed() const throw() { return _fixed; } + + /** + * @param f New value of fixed path flag + */ inline void setFixed(bool f) throw() { _fixed = f; } - inline void sent(uint64_t t) throw() { _lastSend = t; } - inline void received(uint64_t t) throw() { _lastReceived = t; } - inline void pinged(uint64_t t) throw() { _lastPing = t; } + /** + * Compute path desperation + * + * Path desperation affects escalation to less efficient fallback + * transports such as TCP or HTTP relaying. + * + * Right now we only escalate desperation for fixed paths, which + * are paths to supernodes. This causes our fallback tunneling + * mechanisms to kick in. + * + * @param now Current time + * @return Path desperation, starting at 0 + */ + inline int desperation(uint64_t now) const + { + if ((_lastSend > _lastReceived)&&(_fixed)) + return std::max(_lastReceiveDesperation,(int)((_lastSend - _lastReceived) / ZT_DESPERATION_INCREMENT)); + return _lastReceiveDesperation; + } /** * @param now Current time @@ -118,53 +140,37 @@ public: inline bool active(uint64_t now) const throw() { - return ((_addr)&&((_fixed)||((now - _lastReceived) < ZT_PEER_PATH_ACTIVITY_TIMEOUT))); + return ( (_fixed) || ((now - _lastReceived) < ZT_PEER_PATH_ACTIVITY_TIMEOUT) ); } /** - * @return Human-readable address and other information about this path, some computed as of current time + * @param now Current time + * @return Human-readable address and other information about this path */ - inline std::string toString() const + inline std::string toString(uint64_t now) const { - uint64_t now = Utils::now(); char tmp[1024]; - const char *t = ""; - switch(_type) { - case PATH_TYPE_NULL: t = "null"; break; - case PATH_TYPE_UDP: t = "udp"; break; - case PATH_TYPE_TCP_OUT: t = "tcp_out"; break; - case PATH_TYPE_TCP_IN: t = "tcp_in"; break; - } - Utils::snprintf(tmp,sizeof(tmp),"%s;%s;%lld;%lld;%lld;%s", - t, + Utils::snprintf(tmp,sizeof(tmp),"%s(%s)", _addr.toString().c_str(), - (long long)((_lastSend != 0) ? ((now - _lastSend) / 1000LL) : -1), - (long long)((_lastReceived != 0) ? ((now - _lastReceived) / 1000LL) : -1), - (long long)((_lastPing != 0) ? ((now - _lastPing) / 1000LL) : -1), ((_fixed) ? "fixed" : (active(now) ? "active" : "inactive")) ); return std::string(tmp); } - inline bool operator==(const Path &p) const throw() { return ((_addr == p._addr)&&(_type == p._type)); } - inline bool operator!=(const Path &p) const throw() { return ((_addr != p._addr)||(_type != p._type)); } - inline bool operator<(const Path &p) const - throw() - { - if (_addr == p._addr) - return ((int)_type < (int)p._type); - else return (_addr < p._addr); - } - inline bool operator>(const Path &p) const throw() { return (p < *this); } - inline bool operator<=(const Path &p) const throw() { return !(p < *this); } - inline bool operator>=(const Path &p) const throw() { return !(*this < p); } + inline operator bool() const throw() { return (_addr); } + + inline bool operator==(const Path &p) const throw() { return (_addr == p._addr); } + inline bool operator!=(const Path &p) const throw() { return (_addr != p._addr); } + inline bool operator<(const Path &p) const throw() { return (_addr < p._addr); } + inline bool operator>(const Path &p) const throw() { return (_addr > p._addr); } + inline bool operator<=(const Path &p) const throw() { return (_addr <= p._addr); } + inline bool operator>=(const Path &p) const throw() { return (_addr >= p._addr); } private: - volatile uint64_t _lastSend; - volatile uint64_t _lastReceived; - volatile uint64_t _lastPing; + uint64_t _lastSend; + uint64_t _lastReceived; InetAddress _addr; - Type _type; + int _lastReceiveDesperation; bool _fixed; }; diff --git a/node/Peer.cpp b/node/Peer.cpp index eb0146f83..294c02bf5 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -27,10 +27,9 @@ #include "Constants.hpp" #include "Peer.hpp" +#include "Node.hpp" #include "Switch.hpp" -#include "Packet.hpp" #include "Network.hpp" -#include "NodeConfig.hpp" #include "AntiRecursion.hpp" #include @@ -44,12 +43,13 @@ Peer::Peer(const Identity &myIdentity,const Identity &peerIdentity) _lastUnicastFrame(0), _lastMulticastFrame(0), _lastAnnouncedTo(0), + _lastSpammed(0), _vMajor(0), _vMinor(0), _vRevision(0), + _id(peerIdentity), _numPaths(0), - _latency(0), - _id(peerIdentity) + _latency(0) { if (!myIdentity.agree(peerIdentity,_key,ZT_PEER_SECRET_KEY_LENGTH)) throw std::runtime_error("new peer identity key agreement failed"); @@ -57,53 +57,50 @@ Peer::Peer(const Identity &myIdentity,const Identity &peerIdentity) void Peer::received( const RuntimeEnvironment *RR, - const SharedPtr &fromSock, const InetAddress &remoteAddr, + int linkDesperation unsigned int hops, uint64_t packetId, Packet::Verb verb, uint64_t inRePacketId, - Packet::Verb inReVerb, - uint64_t now) + Packet::Verb inReVerb) { - // Update system-wide last packet receive time - *((const_cast(&(RR->timeOfLastPacketReceived)))) = now; - - // Global last receive time regardless of path + const uint64_t now = RR->node->now(); _lastReceive = now; if (!hops) { - // Learn paths from direct packets (hops == 0) + /* Learn new paths from direct (hops == 0) packets */ { + unsigned int np = _numPaths; + bool havePath = false; - for(unsigned int p=0,np=_numPaths;ptcp())) { - _paths[p].received(now); + for(unsigned int p=0;p= ZT_PEER_MAX_PATHS) - clean(now); - np = _numPaths; + Path *slot = (Path *)0; if (np < ZT_PEER_MAX_PATHS) { - Path::Type pt = Path::PATH_TYPE_UDP; - switch(fromSock->type()) { - case Socket::ZT_SOCKET_TYPE_TCP_IN: - pt = Path::PATH_TYPE_TCP_IN; - break; - case Socket::ZT_SOCKET_TYPE_TCP_OUT: - pt = Path::PATH_TYPE_TCP_OUT; - break; - default: - break; + // Add new path + slot = &(_paths[np++]); + } else { + // Replace oldest non-fixed path + uint64_t slotLRmin = 0xffffffffffffffffULL; + for(unsigned int p=0;pinit(remoteAddr,false); + slot->received(now,linkDesperation); + _numPaths = np; } } } @@ -126,7 +123,7 @@ void Peer::received( for(std::set::iterator mg(mgs.begin());mg!=mgs.end();++mg) { if ((outp.size() + 18) > ZT_UDP_DEFAULT_PAYLOAD_MTU) { outp.armor(_key,true); - fromSock->send(remoteAddr,outp.data(),outp.size()); + RR->node->putPacket(remoteAddr,outp.data(),outp.size(),linkDesperation,false); outp.reset(_id.address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE); } @@ -139,156 +136,70 @@ void Peer::received( } if (outp.size() > ZT_PROTO_MIN_PACKET_LENGTH) { outp.armor(_key,true); - fromSock->send(remoteAddr,outp.data(),outp.size()); + RR->node->putPacket(remoteAddr,outp.data(),outp.size(),linkDesperation,false); } } } if ((verb == Packet::VERB_FRAME)||(verb == Packet::VERB_EXT_FRAME)) _lastUnicastFrame = now; - else if ((verb == Packet::VERB_P5_MULTICAST_FRAME)||(verb == Packet::VERB_MULTICAST_FRAME)) + else if (verb == Packet::VERB_MULTICAST_FRAME) _lastMulticastFrame = now; } -Path::Type Peer::send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) +bool Peer::send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) { - /* For sending ordinary packets, paths are divided into two categories: - * "normal" and "TCP out." Normal includes UDP and incoming TCP. We want - * to treat outbound TCP differently since if we use it it may end up - * overriding UDP and UDP performs much better. We only want to initiate - * TCP if it looks like UDP isn't available. */ - Path *bestNormalPath = (Path *)0; - Path *bestTcpOutPath = (Path *)0; - uint64_t bestNormalPathLastReceived = 0; - uint64_t bestTcpOutPathLastReceived = 0; - for(unsigned int p=0,np=_numPaths;p= bestTcpOutPathLastReceived) { - bestTcpOutPathLastReceived = lr; - bestTcpOutPath = &(_paths[p]); - } - } else { - if (lr >= bestNormalPathLastReceived) { - bestNormalPathLastReceived = lr; - bestNormalPath = &(_paths[p]); - } - } - } - Path *bestPath = (Path *)0; - uint64_t normalPathAge = now - bestNormalPathLastReceived; - uint64_t tcpOutPathAge = now - bestTcpOutPathLastReceived; - if (normalPathAge < ZT_PEER_PATH_ACTIVITY_TIMEOUT) { - /* If we have a normal path that looks alive, only use TCP if it looks - * even more alive, if the UDP path is not a very recent acquisition, - * and if TCP tunneling is globally enabled. */ - bestPath = ( (tcpOutPathAge < normalPathAge) && (normalPathAge > (ZT_PEER_DIRECT_PING_DELAY / 4)) && (RR->tcpTunnelingEnabled) ) ? bestTcpOutPath : bestNormalPath; - } else if ( (tcpOutPathAge < ZT_PEER_PATH_ACTIVITY_TIMEOUT) || ((RR->tcpTunnelingEnabled)&&(bestTcpOutPath)) ) { - /* Otherwise use a TCP path if we have an active one or if TCP - * fallback has been globally triggered and we know of one at all. */ - bestPath = bestTcpOutPath; - } else if ( (bestNormalPath) && (bestNormalPath->fixed()) ) { - /* Finally, use a normal path if we have a "fixed" one as these are - * always considered basically alive. */ - bestPath = bestNormalPath; - } - - /* Old path choice logic -- would attempt to use inactive paths... deprecating and will probably kill. - Path *bestPath = (Path *)0; - if (bestTcpOutPath) { // we have a TCP out path - if (bestNormalPath) { // we have both paths, decide which to use - if (RR->tcpTunnelingEnabled) { // TCP tunneling is enabled, so use normal path only if it looks alive - if ((bestNormalPathLastReceived > RR->timeOfLastResynchronize)&&((now - bestNormalPathLastReceived) < ZT_PEER_PATH_ACTIVITY_TIMEOUT)) - bestPath = bestNormalPath; - else bestPath = bestTcpOutPath; - } else { // TCP tunneling is disabled, use normal path - bestPath = bestNormalPath; - } - } else { // we only have a TCP_OUT path, so use it regardless - bestPath = bestTcpOutPath; - } - } else { // we only have a normal path (or none at all, that case is caught below) - bestPath = bestNormalPath; - } - */ - - if (!bestPath) - return Path::PATH_TYPE_NULL; - - RR->antiRec->logOutgoingZT(data,len); - - if (RR->sm->send(bestPath->address(),bestPath->tcp(),bestPath->type() == Path::PATH_TYPE_TCP_OUT,data,len)) { - bestPath->sent(now); - return bestPath->type(); - } - - return Path::PATH_TYPE_NULL; -} - -bool Peer::sendPing(const RuntimeEnvironment *RR,uint64_t now) -{ - bool sent = false; - SharedPtr self(this); - - /* Ping (and thus open) outbound TCP connections if we have no other options - * or if the TCP tunneling master switch is enabled and pings have been - * unanswered for ZT_TCP_TUNNEL_FAILOVER_TIMEOUT ms over normal channels. */ - uint64_t lastNormalPingSent = 0; - uint64_t lastNormalReceive = 0; - bool haveNormal = false; + uint64_t lrMax = 0; for(unsigned int p=0,np=_numPaths;p= lrMax)) { + lrMax = _paths[p].lastReceived(); + bestPath = &(_paths[p]); } } - const bool useTcpOut = ( (!haveNormal) || ( (RR->tcpTunnelingEnabled) && (lastNormalPingSent > RR->timeOfLastResynchronize) && (lastNormalPingSent > lastNormalReceive) && ((lastNormalPingSent - lastNormalReceive) >= ZT_TCP_TUNNEL_FAILOVER_TIMEOUT) ) ); - TRACE("PING %s (useTcpOut==%d)",_id.address().toString().c_str(),(int)useTcpOut); - - for(unsigned int p=0,np=_numPaths;psw->sendHELLO(self,_paths[p])) { - _paths[p].sent(now); - sent = true; - } + if (bestPath) { + bool spam = ((now - _lastSpammed) >= ZT_DESPERATION_SPAM_INTERVAL); + if (RR->node->putPacket(bestPath->address(),data,len,bestPath->desperation(),spam)) { + bestPath->sent(now); + RR->antiRec->logOutgoingZT(data,len); + if (spam) + _lastSpammed = now; + return true; } } - return sent; -} - -void Peer::clean(uint64_t now) -{ - unsigned int np = _numPaths; - unsigned int x = 0; - unsigned int y = 0; - while (x < np) { - if (_paths[x].active(now)) - _paths[y++] = _paths[x]; - ++x; - } - _numPaths = y; + return false; } void Peer::addPath(const Path &newp) { unsigned int np = _numPaths; + for(unsigned int p=0;p= ZT_PEER_MAX_PATHS) - clean(Utils::now()); - np = _numPaths; + + Path *slot = (Path *)0; if (np < ZT_PEER_MAX_PATHS) { - _paths[np] = newp; - _numPaths = ++np; + // Add new path + slot = &(_paths[np++]); + } else { + // Replace oldest non-fixed path + uint64_t slotLRmin = 0xffffffffffffffffULL; + for(unsigned int p=0;p #include +#include "../include/ZeroTierOne.h" + #include "Constants.hpp" #include "RuntimeEnvironment.hpp" #include "Path.hpp" @@ -51,7 +53,7 @@ /** * Maximum number of paths a peer can have */ -#define ZT_PEER_MAX_PATHS 8 +#define ZT_PEER_MAX_PATHS 3 namespace ZeroTier { @@ -111,25 +113,23 @@ public: * and appears to be valid. * * @param RR Runtime environment - * @param fromSock Socket from which packet was received * @param remoteAddr Internet address of sender + * @param linkDesperation Link desperation level * @param hops ZeroTier (not IP) hops * @param packetId Packet ID * @param verb Packet verb - * @param inRePacketId Packet ID in reply to (for OK/ERROR, 0 otherwise) - * @param inReVerb Verb in reply to (for OK/ERROR, VERB_NOP otherwise) - * @param now Current time + * @param inRePacketId Packet ID in reply to (default: none) + * @param inReVerb Verb in reply to (for OK/ERROR, default: VERB_NOP) */ void received( const RuntimeEnvironment *RR, - const SharedPtr &fromSock, const InetAddress &remoteAddr, + int linkDesperation, unsigned int hops, uint64_t packetId, Packet::Verb verb, - uint64_t inRePacketId, - Packet::Verb inReVerb, - uint64_t now); + uint64_t inRePacketId = 0, + Packet::Verb inReVerb = Packet::VERB_NOP); /** * Send a packet directly to this peer @@ -141,26 +141,9 @@ public: * @param data Data to send * @param len Length of packet * @param now Current time - * @return Type of path used or Path::PATH_TYPE_NULL on failure + * @return True if packet appears to have been sent via some available path */ - Path::Type send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now); - - /** - * Send HELLO to a peer via all direct paths available - * - * This begins attempting to use TCP paths if no ping response has been - * received from any UDP path in more than ZT_TCP_FALLBACK_AFTER. - * - * @param RR Runtime environment - * @param now Current time - * @return True if send appears successful for at least one address type - */ - bool sendPing(const RuntimeEnvironment *RR,uint64_t now); - - /** - * Called periodically by Topology::clean() to remove stale paths and do other cleanup - */ - void clean(uint64_t now); + bool send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now); /** * @return All known direct paths to this peer @@ -173,19 +156,6 @@ public: return pp; } - /** - * @param addr IP:port - * @return True if we have a UDP path to this address - */ - inline bool haveUdpPath(const InetAddress &addr) const - { - for(unsigned int p=0,np=_numPaths;p findCommonGround(const Peer &a,const Peer &b,uint64_t now) { std::pair v4,v6; - b.getBestActiveUdpPathAddresses(now,v4.first,v6.first); - a.getBestActiveUdpPathAddresses(now,v4.second,v6.second); + b.getBestActiveAddresses(now,v4.first,v6.first); + a.getBestActiveAddresses(now,v4.second,v6.second); if ((v6.first)&&(v6.second)) // prefer IPv6 if both have it since NAT-t is (almost) unnecessary return v6; else if ((v4.first)&&(v4.second)) @@ -403,23 +358,26 @@ public: private: void _announceMulticastGroups(const RuntimeEnvironment *RR,uint64_t now); + unsigned char _key[ZT_PEER_SECRET_KEY_LENGTH]; + uint64_t _lastUsed; uint64_t _lastReceive; // direct or indirect uint64_t _lastUnicastFrame; uint64_t _lastMulticastFrame; uint64_t _lastAnnouncedTo; + uint64_t _lastSpammed; uint16_t _vProto; uint16_t _vMajor; uint16_t _vMinor; uint16_t _vRevision; + Identity _id; + Path _paths[ZT_PEER_MAX_PATHS]; unsigned int _numPaths; unsigned int _latency; - unsigned char _key[ZT_PEER_SECRET_KEY_LENGTH]; - Identity _id; - + unsigned int _spamCounter; AtomicCounter __refCount; }; diff --git a/node/Switch.cpp b/node/Switch.cpp index 0c6d52240..ec66586d7 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -270,6 +270,7 @@ void Switch::send(const Packet &packet,bool encrypt) } } +#if 0 void Switch::sendHELLO(const Address &dest) { Packet outp(dest,RR->identity.address(),Packet::VERB_HELLO); @@ -281,36 +282,7 @@ void Switch::sendHELLO(const Address &dest) RR->identity.serialize(outp,false); send(outp,false); } - -bool Switch::sendHELLO(const SharedPtr &dest,const Path &path) -{ - uint64_t now = Utils::now(); - Packet outp(dest->address(),RR->identity.address(),Packet::VERB_HELLO); - outp.append((unsigned char)ZT_PROTO_VERSION); - outp.append((unsigned char)ZEROTIER_ONE_VERSION_MAJOR); - outp.append((unsigned char)ZEROTIER_ONE_VERSION_MINOR); - outp.append((uint16_t)ZEROTIER_ONE_VERSION_REVISION); - outp.append(now); - RR->identity.serialize(outp,false); - outp.armor(dest->key(),false); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); - return RR->sm->send(path.address(),path.tcp(),path.type() == Path::PATH_TYPE_TCP_OUT,outp.data(),outp.size()); -} - -bool Switch::sendHELLO(const SharedPtr &dest,const InetAddress &destUdp) -{ - uint64_t now = Utils::now(); - Packet outp(dest->address(),RR->identity.address(),Packet::VERB_HELLO); - outp.append((unsigned char)ZT_PROTO_VERSION); - outp.append((unsigned char)ZEROTIER_ONE_VERSION_MAJOR); - outp.append((unsigned char)ZEROTIER_ONE_VERSION_MINOR); - outp.append((uint16_t)ZEROTIER_ONE_VERSION_REVISION); - outp.append(now); - RR->identity.serialize(outp,false); - outp.armor(dest->key(),false); - RR->antiRec->logOutgoingZT(outp.data(),outp.size()); - return RR->sm->send(destUdp,false,false,outp.data(),outp.size()); -} +#endif bool Switch::unite(const Address &p1,const Address &p2,bool force) { diff --git a/node/Switch.hpp b/node/Switch.hpp index da99b5cd6..b5da54a09 100644 --- a/node/Switch.hpp +++ b/node/Switch.hpp @@ -116,31 +116,6 @@ public: */ void send(const Packet &packet,bool encrypt); - /** - * Send a HELLO announcement - * - * @param dest Address of destination - */ - void sendHELLO(const Address &dest); - - /** - * Send a HELLO announcement immediately to the indicated address - * - * @param dest Destination peer - * @param path Network path to peer - * @return True if send appears successful - */ - bool sendHELLO(const SharedPtr &dest,const Path &path); - - /** - * Send a HELLO announcement immediately to the indicated address via UDP - * - * @param dest Destination peer - * @param destUdp UDP inet address - * @return True if send appears successful - */ - bool sendHELLO(const SharedPtr &dest,const InetAddress &destUdp); - /** * Send RENDEZVOUS to two peers to permit them to directly connect * diff --git a/node/Topology.cpp b/node/Topology.cpp index 3687d4ee8..99361cffa 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -251,10 +251,7 @@ void Topology::clean(uint64_t now) for(std::map< Address,SharedPtr >::iterator p(_activePeers.begin());p!=_activePeers.end();) { if (((now - p->second->lastUsed()) >= ZT_PEER_IN_MEMORY_EXPIRATION)&&(std::find(_supernodeAddresses.begin(),_supernodeAddresses.end(),p->first) == _supernodeAddresses.end())) { _activePeers.erase(p++); - } else { - p->second->clean(now); - ++p; - } + } else ++p; } } diff --git a/node/Topology.hpp b/node/Topology.hpp index 6290bb9fb..ec8de5d0a 100644 --- a/node/Topology.hpp +++ b/node/Topology.hpp @@ -191,6 +191,7 @@ public: f(*this,p->second); } +#if 0 /** * Apply a function or function object to all supernode peers * @@ -274,7 +275,7 @@ public: uint64_t lp = 0; uint64_t lr = 0; p->lastPingAndDirectReceive(lp,lr); - if ( (lr < RR->timeOfLastResynchronize) || ((lr < lp)&&((lp - lr) >= ZT_PING_UNANSWERED_AFTER)) || ((_now - lr) >= ZT_PEER_DIRECT_PING_DELAY) ) + if ( ((lr < lp)&&((lp - lr) >= ZT_PING_UNANSWERED_AFTER)) || ((_now - lr) >= ZT_PEER_DIRECT_PING_DELAY) ) p->sendPing(RR,_now); } @@ -283,22 +284,9 @@ public: const RuntimeEnvironment *RR; }; - /** - * Computes most recent timestamp of direct packet receive over a list of peers - */ - class FindMostRecentDirectReceiveTimestamp - { - public: - FindMostRecentDirectReceiveTimestamp(uint64_t &ts) throw() : _ts(ts) {} - inline void operator()(Topology &t,const SharedPtr &p) throw() { _ts = std::max(p->lastDirectReceive(),_ts); } - private: - uint64_t &_ts; - }; - /** * Function object to forget direct links to active peers and then ping them indirectly */ - /* class ResetActivePeers { public: @@ -333,28 +321,7 @@ public: std::vector
_supernodeAddresses; const RuntimeEnvironment *RR; }; - */ - - /** - * Function object to collect peers with any known direct path - */ - class CollectPeersWithActiveDirectPath - { - public: - CollectPeersWithActiveDirectPath(std::vector< SharedPtr > &v,uint64_t now) throw() : - _now(now), - _v(v) {} - - inline void operator()(Topology &t,const SharedPtr &p) - { - if (p->hasActiveDirectPath(_now)) - _v.push_back(p); - } - - private: - uint64_t _now; - std::vector< SharedPtr > &_v; - }; +#endif /** * Update our knowledge of exterior network addresses @@ -396,7 +363,7 @@ private: Mutex _lock; // Set to true if my identity is in _supernodes - volatile bool _amSupernode; + bool _amSupernode; }; } // namespace ZeroTier