فهرست منبع

Bunch of fixes to startup, pinging, and choice of route. Also some TRACE updates.

Adam Ierymenko 11 سال پیش
والد
کامیت
490e86dde3
6فایلهای تغییر یافته به همراه32 افزوده شده و 24 حذف شده
  1. 3 2
      node/Node.cpp
  2. 4 7
      node/PacketDecoder.cpp
  3. 8 6
      node/Peer.cpp
  4. 2 3
      node/Peer.hpp
  5. 9 1
      node/Switch.cpp
  6. 6 5
      node/Topology.hpp

+ 3 - 2
node/Node.cpp

@@ -543,7 +543,7 @@ Node::ReasonForTermination Node::run()
 				Thread::sleep(ZT_SLEEP_WAKE_SETTLE_TIME);
 			}
 
-			// If our network environment looks like it changed, also set resynchronize flag.
+			// If our network environment looks like it changed, resynchronize.
 			if ((resynchronize)||((now - lastNetworkFingerprintCheck) >= ZT_NETWORK_FINGERPRINT_CHECK_DELAY)) {
 				lastNetworkFingerprintCheck = now;
 				uint64_t fp = _r->sysEnv->getNetworkConfigurationFingerprint(_r->nc->networkTapDeviceNames());
@@ -559,8 +559,9 @@ Node::ReasonForTermination Node::run()
 			if ((resynchronize)||((now - lastSupernodePing) >= ZT_PEER_DIRECT_PING_DELAY)) {
 				lastSupernodePing = now;
 				std::vector< SharedPtr<Peer> > sns(_r->topology->supernodePeers());
+				TRACE("pinging %d supernodes",(int)sns.size());
 				for(std::vector< SharedPtr<Peer> >::const_iterator p(sns.begin());p!=sns.end();++p)
-					_r->sw->sendHELLO((*p)->address());
+					(*p)->sendPing(_r,now);
 			}
 
 			if (resynchronize) {

+ 4 - 7
node/PacketDecoder.cpp

@@ -51,7 +51,7 @@ bool PacketDecoder::tryDecode(const RuntimeEnvironment *_r)
 		// Unencrypted HELLOs are handled here since they are used to
 		// populate our identity cache in the first place. _doHELLO() is special
 		// in that it contains its own authentication logic.
-		TRACE("HELLO from %s(%s)",source().toString().c_str(),_remoteAddress.toString().c_str());
+		TRACE("<< HELLO from %s(%s) (normal unencrypted HELLO)",source().toString().c_str(),_remoteAddress.toString().c_str());
 		return _doHELLO(_r);
 	}
 
@@ -78,9 +78,10 @@ bool PacketDecoder::tryDecode(const RuntimeEnvironment *_r)
 			return true;
 		}
 
+		TRACE("<< %s from %s(%s)",Packet::verbString(verb()),source().toString().c_str(),_remoteAddress.toString().c_str());
+
 		switch(verb()) {
 			case Packet::VERB_NOP:
-				TRACE("NOP from %s(%s)",source().toString().c_str(),_remoteAddress.toString().c_str());
 				peer->onReceive(_r,_localPort,_remoteAddress,hops(),packetId(),Packet::VERB_NOP,0,Packet::VERB_NOP,Utils::now());
 				return true;
 			case Packet::VERB_HELLO:
@@ -107,11 +108,7 @@ bool PacketDecoder::tryDecode(const RuntimeEnvironment *_r)
 				return _doNETWORK_CONFIG_REQUEST(_r,peer);
 			case Packet::VERB_NETWORK_CONFIG_REFRESH:
 				return _doNETWORK_CONFIG_REFRESH(_r,peer);
-			default:
-				// This might be something from a new or old version of the protocol.
-				// Technically it passed MAC so the packet is still valid, but we
-				// ignore it.
-				TRACE("ignored unrecognized verb %.2x from %s(%s)",(unsigned int)verb(),source().toString().c_str(),_remoteAddress.toString().c_str());
+			default: // ignore unknown verbs
 				return true;
 		}
 	} else {

+ 8 - 6
node/Peer.cpp

@@ -77,12 +77,6 @@ void Peer::onReceive(
 	uint64_t now)
 {
 	if (!hops) { // direct packet
-		// Announce multicast LIKEs to peers to whom we have a direct link
-		if ((now - _lastAnnouncedTo) >= ((ZT_MULTICAST_LIKE_EXPIRE / 2) - 1000)) {
-			_lastAnnouncedTo = now;
-			_r->sw->announceMulticastGroups(SharedPtr<Peer>(this));
-		}
-
 		// Update last receive info for our direct path
 		WanPath *const wp = (remoteAddr.isV4() ? &_ipv4p : &_ipv6p);
 		wp->lastReceive = now;
@@ -100,6 +94,12 @@ void Peer::onReceive(
 				}
 			}
 		}
+
+		// Announce multicast LIKEs to peers to whom we have a direct link
+		if ((now - _lastAnnouncedTo) >= ((ZT_MULTICAST_LIKE_EXPIRE / 2) - 1000)) {
+			_lastAnnouncedTo = now;
+			_r->sw->announceMulticastGroups(SharedPtr<Peer>(this));
+		}
 	}
 
 	if (verb == Packet::VERB_FRAME) {
@@ -150,12 +150,14 @@ bool Peer::sendPing(const RuntimeEnvironment *_r,uint64_t now)
 {
 	bool sent = false;
 	if (_ipv4p.addr) {
+		TRACE("PING %s(%s)",_id.address().toString().c_str(),_ipv4p.addr.toString().c_str());
 		if (_r->sw->sendHELLO(SharedPtr<Peer>(this),_ipv4p.localPort,_ipv4p.addr)) {
 			_ipv4p.lastSend = now;
 			sent = true;
 		}
 	}
 	if (_ipv6p.addr) {
+		TRACE("PING %s(%s)",_id.address().toString().c_str(),_ipv6p.addr.toString().c_str());
 		if (_r->sw->sendHELLO(SharedPtr<Peer>(this),_ipv6p.localPort,_ipv6p.addr)) {
 			_ipv6p.lastSend = now;
 			sent = true;

+ 2 - 3
node/Peer.hpp

@@ -256,9 +256,8 @@ public:
 	inline bool hasDirectPath() const throw() { return ((_ipv4p.addr)||(_ipv6p.addr)); }
 
 	/**
-	 * @return True if this peer has at least one direct IP address path that looks active
-	 *
 	 * @param now Current time
+	 * @return True if this peer has at least one active or fixed direct path
 	 */
 	inline bool hasActiveDirectPath(uint64_t now) const throw() { return ((_ipv4p.isActive(now))||(_ipv6p.isActive(now))); }
 
@@ -446,7 +445,7 @@ private:
 		inline bool isActive(const uint64_t now) const
 			throw()
 		{
-			return ((addr)&&((now - lastReceive) < ZT_PEER_LINK_ACTIVITY_TIMEOUT));
+			return ((addr)&&((fixed)||((now - lastReceive) < ZT_PEER_LINK_ACTIVITY_TIMEOUT)));
 		}
 
 		template<unsigned int C>

+ 9 - 1
node/Switch.cpp

@@ -700,7 +700,7 @@ bool Switch::_trySend(const Packet &packet,bool encrypt)
 		uint64_t now = Utils::now();
 
 		SharedPtr<Peer> via;
-		if ((_r->topology->isSupernode(peer->address()))||(peer->hasActiveDirectPath(now))) {
+		if (peer->hasActiveDirectPath(now)) {
 			via = peer;
 		} else {
 			via = _r->topology->getBestSupernode();
@@ -745,6 +745,14 @@ bool Switch::_trySend(const Packet &packet,bool encrypt)
 					break;
 			}
 
+#ifdef ZT_TRACE
+			if (via != peer) {
+				TRACE(">> %s to %s via %s (%d)",Packet::verbString(packet.verb()),peer->address().toString().c_str(),via->address().toString().c_str(),(int)packet.size());
+			} else {
+				TRACE(">> %s to %s (%d)",Packet::verbString(packet.verb()),peer->address().toString().c_str(),(int)packet.size());
+			}
+#endif
+
 			return true;
 		}
 		return false;

+ 6 - 5
node/Topology.hpp

@@ -211,13 +211,14 @@ public:
 	};
 
 	/**
-	 * Function object to collect peers that need a ping sent
+	 * Pings all peers that need a ping sent, excluding supernodes (which are pinged separately)
 	 */
 	class PingPeersThatNeedPing
 	{
 	public:
 		PingPeersThatNeedPing(const RuntimeEnvironment *renv,uint64_t now) throw() :
 			_now(now),
+			_supernodeAddresses(renv->topology->supernodeAddresses()),
 			_r(renv) {}
 
 		inline void operator()(Topology &t,const SharedPtr<Peer> &p)
@@ -228,8 +229,8 @@ public:
 				     (
 				       (p->hasDirectPath())&&
 				       ((_now - p->lastFrame()) < ZT_PEER_LINK_ACTIVITY_TIMEOUT)
-				     ) ||
-			       (t.isSupernode(p->address()))
+				     ) &&
+			       (!_supernodeAddresses.count(p->address()))
 				   )
 				 ) {
 				p->sendPing(_r,_now);
@@ -238,6 +239,7 @@ public:
 
 	private:
 		uint64_t _now;
+		std::set<Address> _supernodeAddresses;
 		const RuntimeEnvironment *_r;
 	};
 
@@ -259,10 +261,9 @@ public:
 		{
 			if (_supernodeAddresses.count(p->address()))
 				return; // skip supernodes
-			TRACE(">> %s",p->address().toString().c_str());
 			p->forgetDirectPaths(false); // false means don't forget 'fixed' paths e.g. supernodes
 			if (((_now - p->lastFrame()) < ZT_PEER_LINK_ACTIVITY_TIMEOUT)&&(_supernode)) {
-				TRACE("sending NOP to %s",p->address().toString().c_str());
+				TRACE("sending reset NOP to %s",p->address().toString().c_str());
 				Packet outp(p->address(),_r->identity.address(),Packet::VERB_NOP);
 				outp.armor(p->key(),false); // no need to encrypt a NOP
 				_supernode->send(_r,outp.data(),outp.size(),_now);