From 73153b89b4270a6cc99aea47fb4019d660116e84 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 9 Apr 2014 16:00:25 -0700 Subject: [PATCH] Some cleanup, and use best (not first) UDP addresses for NAT-t VERB_RENDEZVOUS computation. --- node/Peer.cpp | 38 ++++++++++++++++++ node/Peer.hpp | 105 +++++++++++++------------------------------------- 2 files changed, 65 insertions(+), 78 deletions(-) diff --git a/node/Peer.cpp b/node/Peer.cpp index 99ef7ce37..502a0002a 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -225,4 +225,42 @@ bool Peer::_isTcpFailoverTime(const RuntimeEnvironment *_r,uint64_t now) const return false; } +bool Peer::pingUnanswered(const RuntimeEnvironment *_r,uint64_t now) +{ + uint64_t lp = 0; + uint64_t lr = 0; + { + Mutex::Lock _l(_lock); + for(std::vector::const_iterator p(_paths.begin());p!=_paths.end();++p) { + lp = std::max(p->lastPing(),lp); + lr = std::max(p->lastReceived(),lr); + } + } + return ( (lp > _r->timeOfLastResynchronize) && ((lr < lp)&&((lp - lr) >= ZT_PING_UNANSWERED_AFTER)) ); +} + +void Peer::getBestActiveUdpPathAddresses(uint64_t now,InetAddress &v4,InetAddress &v6) const +{ + uint64_t bestV4 = 0,bestV6 = 0; + Mutex::Lock _l(_lock); + for(std::vector::const_iterator p(_paths.begin());p!=_paths.end();++p) { + if ((p->type() == Path::PATH_TYPE_UDP)&&(p->active(now))) { + uint64_t lr = p->lastReceived(); + if (lr) { + if (p->address().isV4()) { + if (lr >= bestV4) { + bestV4 = lr; + v4 = p->address(); + } + } else if (p->address().isV6()) { + if (lr >= bestV6) { + bestV6 = lr; + v6 = p->address(); + } + } + } + } + } +} + } // namespace ZeroTier diff --git a/node/Peer.hpp b/node/Peer.hpp index 89a6ab26c..40261a29c 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -186,11 +186,8 @@ public: { uint64_t x = 0; Mutex::Lock _l(_lock); - for(std::vector::const_iterator p(_paths.begin());p!=_paths.end();++p) { - uint64_t l = p->lastFirewallOpener(); - if (l > x) - x = l; - } + for(std::vector::const_iterator p(_paths.begin());p!=_paths.end();++p) + x = std::max(x,p->lastFirewallOpener()); return x; } @@ -202,11 +199,8 @@ public: { uint64_t x = 0; Mutex::Lock _l(_lock); - for(std::vector::const_iterator p(_paths.begin());p!=_paths.end();++p) { - uint64_t l = p->lastReceived(); - if (l > x) - x = l; - } + for(std::vector::const_iterator p(_paths.begin());p!=_paths.end();++p) + x = std::max(x,p->lastReceived()); return x; } @@ -218,11 +212,8 @@ public: { uint64_t x = 0; Mutex::Lock _l(_lock); - for(std::vector::const_iterator p(_paths.begin());p!=_paths.end();++p) { - uint64_t l = p->lastSend(); - if (l > x) - x = l; - } + for(std::vector::const_iterator p(_paths.begin());p!=_paths.end();++p) + x = std::max(x,p->lastSend()); return x; } @@ -231,56 +222,27 @@ public: * @param now Current time * @return True if the last ping is unanswered */ - inline bool pingUnanswered(const RuntimeEnvironment *_r,uint64_t now) - throw() - { - uint64_t lp = 0; - uint64_t lr = 0; - { - Mutex::Lock _l(_lock); - for(std::vector::const_iterator p(_paths.begin());p!=_paths.end();++p) { - lp = std::max(p->lastPing(),lp); - lr = std::max(p->lastReceived(),lr); - } - } - return ( (lp > _r->timeOfLastResynchronize) && ((lr < lp)&&((lp - lr) >= ZT_PING_UNANSWERED_AFTER)) ); - } + bool pingUnanswered(const RuntimeEnvironment *_r,uint64_t now); /** * @return Time of most recent unicast frame received */ - inline uint64_t lastUnicastFrame() const - throw() - { - return _lastUnicastFrame; - } + inline uint64_t lastUnicastFrame() const throw() { return _lastUnicastFrame; } /** * @return Time of most recent multicast frame received */ - inline uint64_t lastMulticastFrame() const - throw() - { - return _lastMulticastFrame; - } + inline uint64_t lastMulticastFrame() const throw() { return _lastMulticastFrame; } /** * @return Time of most recent frame of any kind (unicast or multicast) */ - inline uint64_t lastFrame() const - throw() - { - return std::max(_lastUnicastFrame,_lastMulticastFrame); - } + inline uint64_t lastFrame() const throw() { return std::max(_lastUnicastFrame,_lastMulticastFrame); } /** * @return Time we last announced state TO this peer, such as multicast LIKEs */ - inline uint64_t lastAnnouncedTo() const - throw() - { - return _lastAnnouncedTo; - } + inline uint64_t lastAnnouncedTo() const throw() { return _lastAnnouncedTo; } /** * @return Current latency or 0 if unknown (max: 65535) @@ -300,11 +262,10 @@ public: inline void addDirectLatencyMeasurment(unsigned int l) throw() { - if (l > 65535) l = 65535; unsigned int ol = _latency; if ((ol > 0)&&(ol < 10000)) - _latency = (ol + l) / 2; - else _latency = l; + _latency = (ol + std::min(l,(unsigned int)65535)) / 2; + else _latency = std::min(l,(unsigned int)65535); } /** @@ -380,6 +341,7 @@ public: * @param vrev Revision */ inline void setRemoteVersion(unsigned int vmaj,unsigned int vmin,unsigned int vrev) + throw() { _vMajor = vmaj; _vMinor = vmin; @@ -391,12 +353,12 @@ public: */ inline std::string remoteVersion() const { - if ((_vMajor)||(_vMinor)||(_vRevision)) { + if ((_vMajor > 0)||(_vMinor > 0)||(_vRevision > 0)) { char tmp[32]; Utils::snprintf(tmp,sizeof(tmp),"%u.%u.%u",_vMajor,_vMinor,_vRevision); return std::string(tmp); } - return std::string("?"); + return std::string("?.?.?"); } /** @@ -405,28 +367,16 @@ public: inline operator bool() const throw() { return (_id); } /** + * Get most recently active UDP path addresses for IPv4 and/or IPv6 + * + * Note that v4 and v6 are not modified if they are not found, so + * initialize these to a NULL address to be able to check. + * * @param now Current time * @param v4 Result parameter to receive active IPv4 address, if any * @param v6 Result parameter to receive active IPv6 address, if any */ - inline void getActiveUdpPathAddresses(uint64_t now,InetAddress &v4,InetAddress &v6) const - { - bool gotV4 = false,gotV6 = false; - Mutex::Lock _l(_lock); - for(std::vector::const_iterator p(_paths.begin());p!=_paths.end();++p) { - if (!gotV4) { - if ((!p->tcp())&&(p->address().isV4())&&(p->active(now))) { - gotV4 = true; - v4 = p->address(); - } - } else if (!gotV6) { - if ((!p->tcp())&&(p->address().isV6())&&(p->active(now))) { - gotV6 = true; - v6 = p->address(); - } - } else break; - } - } + void getBestActiveUdpPathAddresses(uint64_t now,InetAddress &v4,InetAddress &v6) const; /** * Find a common set of addresses by which two peers can link, if any @@ -437,16 +387,15 @@ public: * @return Pair: B's address (to send to A), A's address (to send to B) */ static inline std::pair findCommonGround(const Peer &a,const Peer &b,uint64_t now) - throw() { std::pair v4,v6; - b.getActiveUdpPathAddresses(now,v4.first,v6.first); - a.getActiveUdpPathAddresses(now,v4.second,v6.second); - if ((v6.first)&&(v6.second)) + b.getBestActiveUdpPathAddresses(now,v4.first,v6.first); + a.getBestActiveUdpPathAddresses(now,v4.second,v6.second); + if ((v6.first)&&(v6.second)) // prefer IPv6 if both have it since NAT-t is (almost) unnecessary return v6; - if ((v4.first)&&(v4.second)) + else if ((v4.first)&&(v4.second)) return v4; - return std::pair(); + else return std::pair(); } template