diff options
-rw-r--r-- | node/Constants.hpp | 8 | ||||
-rw-r--r-- | node/Node.cpp | 32 | ||||
-rw-r--r-- | node/PacketDecoder.cpp | 2 | ||||
-rw-r--r-- | node/Peer.cpp | 20 | ||||
-rw-r--r-- | node/Peer.hpp | 24 | ||||
-rw-r--r-- | node/Switch.cpp | 2 | ||||
-rw-r--r-- | node/Topology.hpp | 67 |
7 files changed, 85 insertions, 70 deletions
diff --git a/node/Constants.hpp b/node/Constants.hpp index 6b2f6d40..8f36421b 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -188,7 +188,7 @@ error_no_ZT_ARCH_defined; * very unlikely, as the transfer rate would have to be fast enough to fill * system memory in this time. */ -#define ZT_FRAGMENTED_PACKET_RECEIVE_TIMEOUT 1500 +#define ZT_FRAGMENTED_PACKET_RECEIVE_TIMEOUT 1000 /** * First byte of MAC addresses derived from ZeroTier addresses @@ -206,7 +206,7 @@ error_no_ZT_ARCH_defined; /** * Delay between WHOIS retries in ms */ -#define ZT_WHOIS_RETRY_DELAY 500 +#define ZT_WHOIS_RETRY_DELAY 350 /** * Maximum identity WHOIS retries @@ -233,7 +233,7 @@ error_no_ZT_ARCH_defined; /** * Size of multicast deduplication ring buffer in 64-bit ints */ -#define ZT_MULTICAST_DEDUP_HISTORY_LENGTH 1024 +#define ZT_MULTICAST_DEDUP_HISTORY_LENGTH 512 /** * Default number of bits in multicast propagation prefix @@ -247,6 +247,8 @@ error_no_ZT_ARCH_defined; /** * Global maximum for multicast propagation depth + * + * This is kind of an insane value, meant as a sanity check. */ #define ZT_MULTICAST_GLOBAL_MAX_DEPTH 500 diff --git a/node/Node.cpp b/node/Node.cpp index ef0598de..740bc89e 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -496,34 +496,10 @@ Node::ReasonForTermination Node::run() _r->sw->sendHELLO((*p)->address()); } } else { - std::vector< SharedPtr<Peer> > needPing,needFirewallOpener; - - if (resynchronize) { - _r->topology->eachPeer(Topology::CollectPeersWithDirectPath(needPing)); - } else { - _r->topology->eachPeer(Topology::CollectPeersThatNeedPing(needPing)); - } - - for(std::vector< SharedPtr<Peer> >::iterator p(needPing.begin());p!=needPing.end();++p) { - try { - _r->sw->sendHELLO((*p)->address()); - } catch (std::exception &exc) { - LOG("unexpected exception sending HELLO to %s: %s",(*p)->address().toString().c_str()); - } catch ( ... ) { - LOG("unexpected exception sending HELLO to %s: (unknown)",(*p)->address().toString().c_str()); - } - } - - _r->topology->eachPeer(Topology::CollectPeersThatNeedFirewallOpener(needFirewallOpener)); - for(std::vector< SharedPtr<Peer> >::iterator p(needFirewallOpener.begin());p!=needFirewallOpener.end();++p) { - try { - (*p)->sendFirewallOpener(_r,now); - } catch (std::exception &exc) { - LOG("unexpected exception sending firewall opener to %s: %s",(*p)->address().toString().c_str(),exc.what()); - } catch ( ... ) { - LOG("unexpected exception sending firewall opener to %s: (unknown)",(*p)->address().toString().c_str()); - } - } + if (resynchronize) + _r->topology->eachPeer(Topology::PingAllActivePeers(_r,now)); + else _r->topology->eachPeer(Topology::PingPeersThatNeedPing(_r,now)); + _r->topology->eachPeer(Topology::OpenPeersThatNeedFirewallOpener(_r,now)); } } catch (std::exception &exc) { LOG("unexpected exception running ping check cycle: %s",exc.what()); diff --git a/node/PacketDecoder.cpp b/node/PacketDecoder.cpp index be7acf8d..c8d33a43 100644 --- a/node/PacketDecoder.cpp +++ b/node/PacketDecoder.cpp @@ -524,7 +524,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared // for the same frame would not be fair. SharedPtr<Network> network(_r->nc->network(nwid)); if (network) { - maxDepth = network->multicastDepth(); // pull from network config if available + maxDepth = std::min((unsigned int)ZT_MULTICAST_GLOBAL_MAX_DEPTH,network->multicastDepth()); if (!network->isAllowed(origin)) { TRACE("didn't inject MULTICAST_FRAME from %s(%s) into %.16llx: sender %s not allowed or we don't have a certificate",source().toString().c_str(),nwid,_remoteAddress.toString().c_str(),origin.toString().c_str()); diff --git a/node/Peer.cpp b/node/Peer.cpp index 1c7eec34..ec9edfa6 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -126,6 +126,26 @@ bool Peer::sendFirewallOpener(const RuntimeEnvironment *_r,uint64_t now) return sent; } +bool Peer::sendPing(const RuntimeEnvironment *_r,uint64_t now) +{ + bool sent = false; + if (_ipv4p.addr) { + if (_r->sw->sendHELLO(SharedPtr<Peer>(this),_ipv4p.localPort,_ipv4p.addr)) { + _ipv4p.lastSend = now; + _dirty = true; + sent = true; + } + } + if (_ipv6p.addr) { + if (_r->sw->sendHELLO(SharedPtr<Peer>(this),_ipv6p.localPort,_ipv6p.addr)) { + _ipv6p.lastSend = now; + _dirty = true; + sent = true; + } + } + return sent; +} + void Peer::setPathAddress(const InetAddress &addr,bool fixed) { if (addr.isV4()) { diff --git a/node/Peer.hpp b/node/Peer.hpp index 5ef8c97d..96e8d49a 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -145,6 +145,15 @@ public: bool sendFirewallOpener(const RuntimeEnvironment *_r,uint64_t now); /** + * Send HELLO to a peer using one or both active link types + * + * @param _r Runtime environment + * @param now Current time + * @return True if send appears successful for at least one address type + */ + bool sendPing(const RuntimeEnvironment *_r,uint64_t now); + + /** * Set an address to reach this peer * * @param addr Address to set @@ -223,18 +232,6 @@ public: } /** - * Set the time of last announcement - * - * @param t Time, typically current - */ - inline void setLastAnnouncedTo(const uint64_t t) - throw() - { - _lastAnnouncedTo = t; - _dirty = true; - } - - /** * @return Lowest of measured latencies of all paths or 0 if unknown */ inline unsigned int latency() const @@ -274,8 +271,9 @@ public: } /** + * @return True if this peer has at least one direct IP address path that looks active + * * @param now Current time - * @return True if hasDirectPath() is true and at least one path is active */ inline bool hasActiveDirectPath(uint64_t now) const throw() diff --git a/node/Switch.cpp b/node/Switch.cpp index b1e5f624..f471700c 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -379,7 +379,7 @@ unsigned long Switch::doTimerTasks() void Switch::announceMulticastGroups(const std::map< SharedPtr<Network>,std::set<MulticastGroup> > &allMemberships) { std::vector< SharedPtr<Peer> > directPeers; - _r->topology->eachPeer(Topology::CollectPeersWithActiveDirectPath(directPeers)); + _r->topology->eachPeer(Topology::CollectPeersWithActiveDirectPath(directPeers,Utils::now())); #ifdef ZT_TRACE unsigned int totalMulticastGroups = 0; diff --git a/node/Topology.hpp b/node/Topology.hpp index 23f04ae4..ecafeef8 100644 --- a/node/Topology.hpp +++ b/node/Topology.hpp @@ -190,90 +190,109 @@ public: /** * Function object to collect peers that need a firewall opener sent */ - class CollectPeersThatNeedFirewallOpener + class OpenPeersThatNeedFirewallOpener { public: - CollectPeersThatNeedFirewallOpener(std::vector< SharedPtr<Peer> > &v) : - _now(Utils::now()), - _v(v) + OpenPeersThatNeedFirewallOpener(const RuntimeEnvironment *renv,uint64_t now) throw() : + _now(now), + _r(renv) { } inline void operator()(Topology &t,const SharedPtr<Peer> &p) { if ((p->hasDirectPath())&&((_now - std::max(p->lastFirewallOpener(),p->lastDirectSend())) >= ZT_FIREWALL_OPENER_DELAY)) - _v.push_back(p); + p->sendFirewallOpener(_r,_now); } private: uint64_t _now; - std::vector< SharedPtr<Peer> > &_v; + const RuntimeEnvironment *_r; }; /** * Function object to collect peers that need a ping sent */ - class CollectPeersThatNeedPing + class PingPeersThatNeedPing { public: - CollectPeersThatNeedPing(std::vector< SharedPtr<Peer> > &v) : - _now(Utils::now()), - _v(v) + PingPeersThatNeedPing(const RuntimeEnvironment *renv,uint64_t now) throw() : + _now(now), + _r(renv) { } inline void operator()(Topology &t,const SharedPtr<Peer> &p) { - if ( ((t.isSupernode(p->address()))&&((_now - p->lastDirectReceive()) >= ZT_PEER_DIRECT_PING_DELAY)) || ((p->hasActiveDirectPath(_now))&&((_now - p->lastDirectSend()) >= ZT_PEER_DIRECT_PING_DELAY)) ) - _v.push_back(p); + if ( + ((_now - p->lastDirectReceive()) >= ZT_PEER_DIRECT_PING_DELAY) && + ( + ( + (p->hasDirectPath())&& + ((_now - p->lastFrame()) < ZT_PEER_LINK_ACTIVITY_TIMEOUT) + ) || + (t.isSupernode(p->address())) + ) + ) { + p->sendPing(_r,_now); + } } private: uint64_t _now; - std::vector< SharedPtr<Peer> > &_v; + const RuntimeEnvironment *_r; }; /** - * Function object to collect peers with active links (and supernodes) + * Function object to collect peers that we're talking to */ - class CollectPeersWithActiveDirectPath + class PingAllActivePeers { public: - CollectPeersWithActiveDirectPath(std::vector< SharedPtr<Peer> > &v) : - _now(Utils::now()), - _v(v) + PingAllActivePeers(const RuntimeEnvironment *renv,uint64_t now) throw() : + _now(now), + _r(renv) { } inline void operator()(Topology &t,const SharedPtr<Peer> &p) { - if ((p->hasActiveDirectPath(_now))||(t.isSupernode(p->address()))) - _v.push_back(p); + if ( + ( + (p->hasDirectPath())&& + ((_now - p->lastFrame()) < ZT_PEER_LINK_ACTIVITY_TIMEOUT) + ) || + (t.isSupernode(p->address())) + ) { + p->sendPing(_r,_now); + } } private: uint64_t _now; - std::vector< SharedPtr<Peer> > &_v; + const RuntimeEnvironment *_r; }; /** * Function object to collect peers with any known direct path */ - class CollectPeersWithDirectPath + class CollectPeersWithActiveDirectPath { public: - CollectPeersWithDirectPath(std::vector< SharedPtr<Peer> > &v) : + CollectPeersWithActiveDirectPath(std::vector< SharedPtr<Peer> > &v,uint64_t now) throw() : + _now(now), _v(v) { } inline void operator()(Topology &t,const SharedPtr<Peer> &p) { - if (p->hasDirectPath()) + if (p->hasActiveDirectPath(_now)) _v.push_back(p); } private: + uint64_t _now; std::vector< SharedPtr<Peer> > &_v; }; |