ソースを参照

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 年 前
コミット
58538500f2
7 ファイル変更85 行追加70 行削除
  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;
 	};
 	};