Browse Source

Clean up some routine stuff like pings, and stop keeping links open forever even if there are no frames passing between them.

Adam Ierymenko 12 years ago
parent
commit
58538500f2
7 changed files with 85 additions and 70 deletions
  1. 5 3
      node/Constants.hpp
  2. 4 28
      node/Node.cpp
  3. 1 1
      node/PacketDecoder.cpp
  4. 20 0
      node/Peer.cpp
  5. 11 13
      node/Peer.hpp
  6. 1 1
      node/Switch.cpp
  7. 43 24
      node/Topology.hpp

+ 5 - 3
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
  * very unlikely, as the transfer rate would have to be fast enough to fill
  * system memory in this time.
  * 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
  * First byte of MAC addresses derived from ZeroTier addresses
@@ -206,7 +206,7 @@ error_no_ZT_ARCH_defined;
 /**
 /**
  * Delay between WHOIS retries in ms
  * Delay between WHOIS retries in ms
  */
  */
-#define ZT_WHOIS_RETRY_DELAY 500
+#define ZT_WHOIS_RETRY_DELAY 350
 
 
 /**
 /**
  * Maximum identity WHOIS retries
  * Maximum identity WHOIS retries
@@ -233,7 +233,7 @@ error_no_ZT_ARCH_defined;
 /**
 /**
  * Size of multicast deduplication ring buffer in 64-bit ints
  * 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
  * Default number of bits in multicast propagation prefix
@@ -247,6 +247,8 @@ error_no_ZT_ARCH_defined;
 
 
 /**
 /**
  * Global maximum for multicast propagation depth
  * 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
 #define ZT_MULTICAST_GLOBAL_MAX_DEPTH 500
 
 

+ 4 - 28
node/Node.cpp

@@ -496,34 +496,10 @@ Node::ReasonForTermination Node::run()
 								_r->sw->sendHELLO((*p)->address());
 								_r->sw->sendHELLO((*p)->address());
 						}
 						}
 					} else {
 					} 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) {
 				} catch (std::exception &exc) {
 					LOG("unexpected exception running ping check cycle: %s",exc.what());
 					LOG("unexpected exception running ping check cycle: %s",exc.what());

+ 1 - 1
node/PacketDecoder.cpp

@@ -524,7 +524,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared
 			// for the same frame would not be fair.
 			// for the same frame would not be fair.
 			SharedPtr<Network> network(_r->nc->network(nwid));
 			SharedPtr<Network> network(_r->nc->network(nwid));
 			if (network) {
 			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)) {
 				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());
 					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());
 
 

+ 20 - 0
node/Peer.cpp

@@ -126,6 +126,26 @@ bool Peer::sendFirewallOpener(const RuntimeEnvironment *_r,uint64_t now)
 	return sent;
 	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)
 void Peer::setPathAddress(const InetAddress &addr,bool fixed)
 {
 {
 	if (addr.isV4()) {
 	if (addr.isV4()) {

+ 11 - 13
node/Peer.hpp

@@ -144,6 +144,15 @@ public:
 	 */
 	 */
 	bool sendFirewallOpener(const RuntimeEnvironment *_r,uint64_t now);
 	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
 	 * Set an address to reach this peer
 	 *
 	 *
@@ -222,18 +231,6 @@ public:
 		return _lastAnnouncedTo;
 		return _lastAnnouncedTo;
 	}
 	}
 
 
-	/**
-	 * 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
 	 * @return Lowest of measured latencies of all paths or 0 if unknown
 	 */
 	 */
@@ -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
 	 * @param now Current time
-	 * @return True if hasDirectPath() is true and at least one path is active
 	 */
 	 */
 	inline bool hasActiveDirectPath(uint64_t now) const
 	inline bool hasActiveDirectPath(uint64_t now) const
 		throw()
 		throw()

+ 1 - 1
node/Switch.cpp

@@ -379,7 +379,7 @@ unsigned long Switch::doTimerTasks()
 void Switch::announceMulticastGroups(const std::map< SharedPtr<Network>,std::set<MulticastGroup> > &allMemberships)
 void Switch::announceMulticastGroups(const std::map< SharedPtr<Network>,std::set<MulticastGroup> > &allMemberships)
 {
 {
 	std::vector< SharedPtr<Peer> > directPeers;
 	std::vector< SharedPtr<Peer> > directPeers;
-	_r->topology->eachPeer(Topology::CollectPeersWithActiveDirectPath(directPeers));
+	_r->topology->eachPeer(Topology::CollectPeersWithActiveDirectPath(directPeers,Utils::now()));
 
 
 #ifdef ZT_TRACE
 #ifdef ZT_TRACE
 	unsigned int totalMulticastGroups = 0;
 	unsigned int totalMulticastGroups = 0;

+ 43 - 24
node/Topology.hpp

@@ -190,90 +190,109 @@ public:
 	/**
 	/**
 	 * Function object to collect peers that need a firewall opener sent
 	 * Function object to collect peers that need a firewall opener sent
 	 */
 	 */
-	class CollectPeersThatNeedFirewallOpener
+	class OpenPeersThatNeedFirewallOpener
 	{
 	{
 	public:
 	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)
 		inline void operator()(Topology &t,const SharedPtr<Peer> &p)
 		{
 		{
 			if ((p->hasDirectPath())&&((_now - std::max(p->lastFirewallOpener(),p->lastDirectSend())) >= ZT_FIREWALL_OPENER_DELAY))
 			if ((p->hasDirectPath())&&((_now - std::max(p->lastFirewallOpener(),p->lastDirectSend())) >= ZT_FIREWALL_OPENER_DELAY))
-				_v.push_back(p);
+				p->sendFirewallOpener(_r,_now);
 		}
 		}
 
 
 	private:
 	private:
 		uint64_t _now;
 		uint64_t _now;
-		std::vector< SharedPtr<Peer> > &_v;
+		const RuntimeEnvironment *_r;
 	};
 	};
 
 
 	/**
 	/**
 	 * Function object to collect peers that need a ping sent
 	 * Function object to collect peers that need a ping sent
 	 */
 	 */
-	class CollectPeersThatNeedPing
+	class PingPeersThatNeedPing
 	{
 	{
 	public:
 	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)
 		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:
 	private:
 		uint64_t _now;
 		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:
 	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)
 		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:
 	private:
 		uint64_t _now;
 		uint64_t _now;
-		std::vector< SharedPtr<Peer> > &_v;
+		const RuntimeEnvironment *_r;
 	};
 	};
 
 
 	/**
 	/**
 	 * Function object to collect peers with any known direct path
 	 * Function object to collect peers with any known direct path
 	 */
 	 */
-	class CollectPeersWithDirectPath
+	class CollectPeersWithActiveDirectPath
 	{
 	{
 	public:
 	public:
-		CollectPeersWithDirectPath(std::vector< SharedPtr<Peer> > &v) :
+		CollectPeersWithActiveDirectPath(std::vector< SharedPtr<Peer> > &v,uint64_t now) throw() :
+			_now(now),
 			_v(v)
 			_v(v)
 		{
 		{
 		}
 		}
 
 
 		inline void operator()(Topology &t,const SharedPtr<Peer> &p)
 		inline void operator()(Topology &t,const SharedPtr<Peer> &p)
 		{
 		{
-			if (p->hasDirectPath())
+			if (p->hasActiveDirectPath(_now))
 				_v.push_back(p);
 				_v.push_back(p);
 		}
 		}
 
 
 	private:
 	private:
+		uint64_t _now;
 		std::vector< SharedPtr<Peer> > &_v;
 		std::vector< SharedPtr<Peer> > &_v;
 	};
 	};