Jelajahi Sumber

Improve efficiency of pushCredentials() method since it gets called a lot.

Adam Ierymenko 8 tahun lalu
induk
melakukan
59ba7c8bf5
1 mengubah file dengan 45 tambahan dan 51 penghapusan
  1. 45 51
      node/Membership.cpp

+ 45 - 51
node/Membership.cpp

@@ -41,59 +41,53 @@ Membership::Membership() :
 
 void Membership::pushCredentials(const RuntimeEnvironment *RR,const uint64_t now,const Address &peerAddress,const NetworkConfig &nconf,int localCapabilityIndex,const bool force)
 {
-	//TRACE("pushCredentials() to %s localCapabilityIndex==%d force==%d",peerAddress.toString().c_str(),localCapabilityIndex,(int)force);
-	try {
-		unsigned int localTagPtr = 0;
-		bool needCom = ( (nconf.com) && ( ((now - _lastPushedCom) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) );
-		do {
-			Buffer<ZT_PROTO_MAX_PACKET_LENGTH> capsAndTags;
-
-			unsigned int appendedCaps = 0;
-			if (localCapabilityIndex >= 0) {
-				capsAndTags.addSize(2);
-
-				if ( (_localCaps[localCapabilityIndex].id != nconf.capabilities[localCapabilityIndex].id()) || ((now - _localCaps[localCapabilityIndex].lastPushed) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) {
-					_localCaps[localCapabilityIndex].lastPushed = now;
-					_localCaps[localCapabilityIndex].id = nconf.capabilities[localCapabilityIndex].id();
-					nconf.capabilities[localCapabilityIndex].serialize(capsAndTags);
-					++appendedCaps;
-				}
-
-				capsAndTags.setAt<uint16_t>(0,(uint16_t)appendedCaps);
-				localCapabilityIndex = -1; // don't send this cap again on subsequent loops if force is true
-			} else {
-				capsAndTags.append((uint16_t)0);
-			}
+	bool sendCom = ( (nconf.com) && ( ((now - _lastPushedCom) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) );
 
-			unsigned int appendedTags = 0;
-			const unsigned int tagCountPos = capsAndTags.size();
-			capsAndTags.addSize(2);
-			for(;localTagPtr<nconf.tagCount;++localTagPtr) {
-				if ( (_localTags[localTagPtr].id != nconf.tags[localTagPtr].id()) || ((now - _localTags[localTagPtr].lastPushed) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) {
-					if ((capsAndTags.size() + sizeof(Tag)) >= (ZT_PROTO_MAX_PACKET_LENGTH - sizeof(CertificateOfMembership)))
-						break;
-					nconf.tags[localTagPtr].serialize(capsAndTags);
-					++appendedTags;
-				}
-			}
-			capsAndTags.setAt<uint16_t>(tagCountPos,(uint16_t)appendedTags);
-
-			if (needCom||appendedCaps||appendedTags) {
-				Packet outp(peerAddress,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS);
-				if (needCom) {
-					nconf.com.serialize(outp);
-					_lastPushedCom = now;
-				}
-				outp.append((uint8_t)0x00);
-				outp.append(capsAndTags.data(),capsAndTags.size());
-				outp.append((uint16_t)0); // no revocations, these propagate differently
-				outp.compress();
-				RR->sw->send(outp,true);
-				needCom = false; // don't send COM again on subsequent loops if force is true
+	const Capability *sendCap;
+	if (localCapabilityIndex >= 0) {
+		sendCap = &(nconf.capabilities[localCapabilityIndex]);
+		if ( (_localCaps[localCapabilityIndex].id != sendCap->id()) || ((now - _localCaps[localCapabilityIndex].lastPushed) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) {
+			_localCaps[localCapabilityIndex].lastPushed = now;
+			_localCaps[localCapabilityIndex].id = sendCap->id();
+		} else sendCap = (const Capability *)0;
+	} else sendCap = (const Capability *)0;
+
+	unsigned int tagPtr = 0;
+	while ((tagPtr < nconf.tagCount)||(sendCom)||(sendCap)) {
+		Packet outp(peerAddress,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS);
+
+		if (sendCom) {
+			sendCom = false;
+			nconf.com.serialize(outp);
+			_lastPushedCom = now;
+		}
+		outp.append((uint8_t)0x00);
+
+		if (sendCap) {
+			outp.append((uint16_t)1);
+			sendCap->serialize(outp);
+			sendCap = (const Capability *)0;
+		} else outp.append((uint16_t)0);
+
+		const unsigned int tagCountAt = outp.size();
+		outp.addSize(2);
+		unsigned int thisPacketTagCount = 0;
+		while ((tagPtr < nconf.tagCount)&&((outp.size() + sizeof(Tag) + 32) < ZT_PROTO_MAX_PACKET_LENGTH)) {
+			if ( (_localTags[tagPtr].id != nconf.tags[tagPtr].id()) || ((now - _localTags[tagPtr].lastPushed) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) {
+				_localTags[tagPtr].lastPushed = now;
+				_localTags[tagPtr].id = nconf.tags[tagPtr].id();
+				nconf.tags[tagPtr].serialize(outp);
+				++thisPacketTagCount;
 			}
-		} while (localTagPtr < nconf.tagCount);
-	} catch ( ... ) {
-		TRACE("unable to send credentials due to unexpected exception");
+			++tagPtr;
+		}
+		outp.setAt(tagCountAt,(uint16_t)thisPacketTagCount);
+
+		// No revocations, these propagate differently
+		outp.append((uint16_t)0);
+
+		outp.compress();
+		RR->sw->send(outp,true);
 	}
 }