Adam Ierymenko 9 лет назад
Родитель
Сommit
d7f2287ce9
5 измененных файлов с 34 добавлено и 24 удалено
  1. 2 8
      node/Path.hpp
  2. 27 12
      node/Peer.cpp
  3. 2 2
      node/Peer.hpp
  4. 1 0
      node/Utils.cpp
  5. 2 2
      service/ControlPlane.cpp

+ 2 - 8
node/Path.hpp

@@ -152,16 +152,10 @@ public:
 	inline InetAddress::IpScope ipScope() const { return _ipScope; }
 
 	/**
-	 * @return Preference rank, higher == better (will be less than 255)
+	 * @return Preference rank, higher == better
 	 */
 	inline unsigned int preferenceRank() const
 	{
-		/* First, since the scope enum values in InetAddress.hpp are in order of
-		 * use preference rank, we take that. Then we multiple by two, yielding
-		 * a sequence like 0, 2, 4, 6, etc. Then if it's IPv6 we add one. This
-		 * makes IPv6 addresses of a given scope outrank IPv4 addresses of the
-		 * same scope -- e.g. 1 outranks 0. This makes us prefer IPv6, but not
-		 * if the address scope/class is of a fundamentally lower rank. */
 		return ( ((unsigned int)_ipScope << 1) | (unsigned int)(_addr.ss_family == AF_INET6) );
 	}
 
@@ -213,7 +207,7 @@ public:
 	/**
 	 * @return True if this path needs a heartbeat
 	 */
-	inline bool needsHeartbeat(const uint64_t now) const { return ((now - _lastOut) > ZT_PATH_HEARTBEAT_PERIOD); }
+	inline bool needsHeartbeat(const uint64_t now) const { return ((now - _lastOut) >= ZT_PATH_HEARTBEAT_PERIOD); }
 
 	/**
 	 * @return Last time we sent something

+ 27 - 12
node/Peer.cpp

@@ -134,24 +134,38 @@ void Peer::received(
 			}
 		}
 
-		if ((!pathIsConfirmed)&&(RR->node->shouldUsePathForZeroTierTraffic(path->localAddress(),path->address()))) {
+		if ( (!pathIsConfirmed) && (RR->node->shouldUsePathForZeroTierTraffic(path->localAddress(),path->address())) ) {
 			if (verb == Packet::VERB_OK) {
 				Mutex::Lock _l(_paths_m);
 
-				unsigned int slot = 0;
+				unsigned int slot;
 				if (_numPaths < ZT_MAX_PEER_NETWORK_PATHS) {
 					slot = _numPaths++;
 				} else {
+					// First try to replace the worst within the same address family, if possible
+					int worstSlot = -1;
 					uint64_t worstScore = 0xffffffffffffffffULL;
-					unsigned int worstPath = ZT_MAX_PEER_NETWORK_PATHS-1;
 					for(unsigned int p=0;p<_numPaths;++p) {
-						const uint64_t s = _pathScore(p);
-						if (s < worstScore) {
-							worstScore = s;
-							worstPath = p;
+						if (_paths[p].path->address().ss_family == path->address().ss_family) {
+							const uint64_t s = _pathScore(p);
+							if (s < worstScore) {
+								worstScore = s;
+								worstSlot = (int)p;
+							}
+						}
+					}
+					if (worstSlot >= 0) {
+						slot = (unsigned int)worstSlot;
+					} else {
+						slot = ZT_MAX_PEER_NETWORK_PATHS - 1;
+						for(unsigned int p=0;p<_numPaths;++p) {
+							const uint64_t s = _pathScore(p);
+							if (s < worstScore) {
+								worstScore = s;
+								slot = p;
+							}
 						}
 					}
-					slot = worstPath;
 				}
 
 				_paths[slot].lastReceive = now;
@@ -164,20 +178,21 @@ void Peer::received(
 				_paths[slot].clusterWeights = 1;
 #endif
 			} else {
-
-				TRACE("got %s via unknown path %s(%s), confirming...",Packet::verbString(verb),_id.address().toString().c_str(),remoteAddr.toString().c_str());
+				TRACE("got %s via unknown path %s(%s), confirming...",Packet::verbString(verb),_id.address().toString().c_str(),path->address().toString().c_str());
 
 				if ( (_vProto >= 5) && ( !((_vMajor == 1)&&(_vMinor == 1)&&(_vRevision == 0)) ) ) {
+					// Newer than 1.1.0 can use ECHO, which is smaller
 					Packet outp(_id.address(),RR->identity.address(),Packet::VERB_ECHO);
 					outp.armor(_key,true);
 					path->send(RR,outp.data(),outp.size(),now);
 				} else {
+					// For backward compatibility we send HELLO to ancient nodes
 					sendHELLO(path->localAddress(),path->address(),now);
 				}
-
 			}
 		}
 	} else if (trustEstablished) {
+		// Send PUSH_DIRECT_PATHS if hops>0 (relayed) and we have a trust relationship (common network membership)
 		_pushDirectPaths(path,now);
 	}
 
@@ -286,7 +301,7 @@ bool Peer::doPingAndKeepalive(uint64_t now,int inetAddressFamily)
 	int bestp = -1;
 	uint64_t best = 0ULL;
 	for(unsigned int p=0;p<_numPaths;++p) {
-		if ((inetAddressFamily < 0)||(_paths[p].path->address().ss_family == inetAddressFamily)) {
+		if ((inetAddressFamily < 0)||((int)_paths[p].path->address().ss_family == inetAddressFamily)) {
 			const uint64_t s = _pathScore(p);
 			if (s >= best) {
 				best = s;

+ 2 - 2
node/Peer.hpp

@@ -164,7 +164,7 @@ public:
 	 *
 	 * @param now Current time
 	 * @param inetAddressFamily Keep this address family alive, or -1 for any
-	 * @return True if we have at least one direct path
+	 * @return True if we have at least one direct path of the given family (or any if family is -1)
 	 */
 	bool doPingAndKeepalive(uint64_t now,int inetAddressFamily);
 
@@ -367,7 +367,7 @@ private:
 
 	inline uint64_t _pathScore(const unsigned int p) const
 	{
-		return ( _paths[p].path->lastIn() +
+		return ( _paths[p].lastReceive +
 		         (uint64_t)(_paths[p].path->preferenceRank() * (ZT_PEER_PING_PERIOD / ZT_PATH_MAX_PREFERENCE_RANK)) +
 						 (uint64_t)(_paths[p].clusterWeights * ZT_PEER_PING_PERIOD) );
 	}

+ 1 - 0
node/Utils.cpp

@@ -292,6 +292,7 @@ unsigned int Utils::snprintf(char *buf,unsigned int len,const char *fmt,...)
 	if ((n >= (int)len)||(n < 0)) {
 		if (len)
 			buf[len - 1] = (char)0;
+		abort();
 		throw std::length_error("buf[] overflow in Utils::snprintf");
 	}
 

+ 2 - 2
service/ControlPlane.cpp

@@ -165,7 +165,7 @@ static void _jsonAppend(unsigned int depth,std::string &buf,const ZT_VirtualNetw
 
 static std::string _jsonEnumerate(unsigned int depth,const ZT_PeerPhysicalPath *pp,unsigned int count)
 {
-	char json[1024];
+	char json[2048];
 	char prefix[32];
 
 	if (depth >= sizeof(prefix)) // sanity check -- shouldn't be possible
@@ -201,7 +201,7 @@ static std::string _jsonEnumerate(unsigned int depth,const ZT_PeerPhysicalPath *
 
 static void _jsonAppend(unsigned int depth,std::string &buf,const ZT_Peer *peer)
 {
-	char json[1024];
+	char json[2048];
 	char prefix[32];
 
 	if (depth >= sizeof(prefix)) // sanity check -- shouldn't be possible