Ver código fonte

Fix a possible excessive memory use issue in controller and clean up a bunch of COM handling and other code in the normal node.

Adam Ierymenko 3 anos atrás
pai
commit
ef08346a74

+ 1 - 1
controller/EmbeddedNetworkController.cpp

@@ -1854,7 +1854,7 @@ void EmbeddedNetworkController::_startThreads()
 					for(auto s=_expiringSoon.begin();s!=_expiringSoon.end();) {
 						const int64_t when = s->first;
 						if (when <= now) {
-							// The user MAY have re-authorized, so we must actually look it up and check.
+							// The user may have re-authorized, so we must actually look it up and check.
 							network.clear();
 							member.clear();
 							if (_db.get(s->second.networkId, network, s->second.nodeId, member)) {

+ 2 - 1
controller/EmbeddedNetworkController.hpp

@@ -117,6 +117,7 @@ private:
 		uint64_t networkId;
 		uint64_t nodeId;
 		inline bool operator==(const _MemberStatusKey &k) const { return ((k.networkId == networkId)&&(k.nodeId == nodeId)); }
+		inline bool operator<(const _MemberStatusKey &k) const { return (k.networkId < networkId) || ((k.networkId == networkId)&&(k.nodeId < nodeId)); }
 	};
 	struct _MemberStatus
 	{
@@ -154,7 +155,7 @@ private:
 	std::unordered_map< _MemberStatusKey,_MemberStatus,_MemberStatusHash > _memberStatus;
 	std::mutex _memberStatus_l;
 
-	std::multimap< int64_t, _MemberStatusKey > _expiringSoon;
+	std::set< std::pair<int64_t, _MemberStatusKey> > _expiringSoon;
 	std::mutex _expiringSoon_l;
 
 	RedisConfig *_rc;

+ 5 - 0
node/Constants.hpp

@@ -539,6 +539,11 @@
  */
 #define ZT_PEER_CREDENTIALS_CUTOFF_LIMIT 15
 
+/**
+ * Rate limit for responding to peer credential requests
+ */
+#define ZT_PEER_CREDENTIALS_REQUEST_RATE_LIMIT 1000
+
 /**
  * WHOIS rate limit (we allow these to be pretty fast)
  */

+ 1 - 13
node/IncomingPacket.cpp

@@ -1098,16 +1098,7 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,void *tPtr
 		} catch ( ... ) {} // discard invalid COMs
 	}
 
-	bool trustEstablished = false;
-	if (network) {
-		if (network->gate(tPtr,peer)) {
-			trustEstablished = true;
-		} else {
-			_sendErrorNeedCredentials(RR,tPtr,peer,nwid);
-			return false;
-		}
-	}
-
+	const bool trustEstablished = (network) ? network->gate(tPtr,peer) : false;
 	const int64_t now = RR->node->now();
 	if ((gatherLimit > 0)&&((trustEstablished)||(RR->topology->amUpstream())||(RR->node->localControllerHasAuthorized(now,nwid,peer->address())))) {
 		Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK);
@@ -1224,9 +1215,6 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,void *tPtr,
 		}
 
 		peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,true,nwid,ZT_QOS_NO_FLOW);
-	} else {
-		_sendErrorNeedCredentials(RR,tPtr,peer,nwid);
-		return false;
 	}
 
 	return true;

+ 2 - 1
node/Membership.cpp

@@ -115,7 +115,7 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
 		RR->t->credentialRejected(tPtr,com,"old");
 		return ADD_REJECTED;
 	}
-	if ((newts == oldts)&&(_com == com))
+	if (_com == com)
 		return ADD_ACCEPTED_REDUNDANT;
 
 	switch(com.verify(RR,tPtr)) {
@@ -123,6 +123,7 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
 			RR->t->credentialRejected(tPtr,com,"invalid");
 			return ADD_REJECTED;
 		case 0:
+			//printf("%.16llx %.10llx replacing COM %lld with %lld\n", com.networkId(), com.issuedTo().toInt(), _com.timestamp(), com.timestamp()); fflush(stdout);
 			_com = com;
 			return ADD_ACCEPTED_NEW;
 		case 1:

+ 1 - 1
node/Membership.hpp

@@ -90,7 +90,7 @@ public:
 	 */
 	inline bool isAllowedOnNetwork(const NetworkConfig &thisNodeNetworkConfig, const Identity &otherNodeIdentity) const
 	{
-		return (thisNodeNetworkConfig.isPublic() || (((_com.timestamp() > _comRevocationThreshold) && (thisNodeNetworkConfig.com.agreesWith(_com, otherNodeIdentity)))));
+		return thisNodeNetworkConfig.isPublic() || (((_com.timestamp() > _comRevocationThreshold) && (thisNodeNetworkConfig.com.agreesWith(_com, otherNodeIdentity))));
 	}
 
 	inline bool recentlyAssociated(const int64_t now) const

+ 1 - 0
node/Network.cpp

@@ -1237,6 +1237,7 @@ bool Network::gate(void *tPtr,const SharedPtr<Peer> &peer)
 			}
 		}
 	} catch ( ... ) {}
+	//printf("%.16llx %.10llx not allowed\n", _id, peer->address().toInt()); fflush(stdout);
 	return false;
 }
 

+ 4 - 1
node/Network.hpp

@@ -375,7 +375,10 @@ public:
 	inline void peerRequestedCredentials(void *tPtr,const Address &to,const int64_t now)
 	{
 		Mutex::Lock _l(_lock);
-		_membership(to).pushCredentials(RR,tPtr,now,to,_config);
+		Membership &m = _membership(to);
+		const int64_t lastPushed = m.lastPushedCredentials();
+		if ((lastPushed < _lastConfigUpdate)||((now - lastPushed) > ZT_PEER_CREDENTIALS_REQUEST_RATE_LIMIT))
+			m.pushCredentials(RR,tPtr,now,to,_config);
 	}
 
 	/**