summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--node/Constants.hpp8
-rw-r--r--node/Node.cpp32
-rw-r--r--node/PacketDecoder.cpp2
-rw-r--r--node/Peer.cpp20
-rw-r--r--node/Peer.hpp24
-rw-r--r--node/Switch.cpp2
-rw-r--r--node/Topology.hpp67
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;
};