diff options
| -rw-r--r-- | node/Node.cpp | 5 | ||||
| -rw-r--r-- | node/PacketDecoder.cpp | 11 | ||||
| -rw-r--r-- | node/Peer.cpp | 14 | ||||
| -rw-r--r-- | node/Peer.hpp | 5 | ||||
| -rw-r--r-- | node/Switch.cpp | 10 | ||||
| -rw-r--r-- | node/Topology.hpp | 11 | 
6 files changed, 32 insertions, 24 deletions
diff --git a/node/Node.cpp b/node/Node.cpp index 323e8b21..fe3407be 100644 --- a/node/Node.cpp +++ b/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) { diff --git a/node/PacketDecoder.cpp b/node/PacketDecoder.cpp index 919b537e..25ec85ce 100644 --- a/node/PacketDecoder.cpp +++ b/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 { diff --git a/node/Peer.cpp b/node/Peer.cpp index 5a59031d..512918de 100644 --- a/node/Peer.cpp +++ b/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; diff --git a/node/Peer.hpp b/node/Peer.hpp index 64e9c39a..ac9de661 100644 --- a/node/Peer.hpp +++ b/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> diff --git a/node/Switch.cpp b/node/Switch.cpp index 9ec15411..6c7d0fc9 100644 --- a/node/Switch.cpp +++ b/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; diff --git a/node/Topology.hpp b/node/Topology.hpp index 505cf10e..4a6d711f 100644 --- a/node/Topology.hpp +++ b/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);  | 
