Browse Source

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

Adam Ierymenko 11 years ago
parent
commit
490e86dde3
6 changed files with 32 additions and 24 deletions
  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);