Browse Source

More correct and efficient to initialize member relationship push stuff lazily when member is learned.

Adam Ierymenko 9 years ago
parent
commit
daf8a66ced
4 changed files with 30 additions and 17 deletions
  1. 1 3
      node/Membership.cpp
  2. 1 2
      node/Membership.hpp
  3. 23 8
      node/Network.cpp
  4. 5 4
      node/Network.hpp

+ 1 - 3
node/Membership.cpp

@@ -89,11 +89,10 @@ void Membership::sendCredentialsIfNeeded(const RuntimeEnvironment *RR,const uint
 	}
 }
 
-int Membership::addCredential(const RuntimeEnvironment *RR,const Network *network,const CertificateOfMembership &com)
+int Membership::addCredential(const RuntimeEnvironment *RR,const CertificateOfMembership &com)
 {
 	if (_com == com) {
 		TRACE("addCredential(CertificateOfMembership) for %s on %.16llx ACCEPTED (redundant)",com.issuedTo().toString().c_str(),com.networkId());
-		sendCredentialsIfNeeded(RR,RR->node->now(),com.issuedTo(),network->config(),(const Capability *)0);
 		return 0;
 	}
 
@@ -104,7 +103,6 @@ int Membership::addCredential(const RuntimeEnvironment *RR,const Network *networ
 		if (com.timestamp().first > _com.timestamp().first) {
 			_com = com;
 		}
-		sendCredentialsIfNeeded(RR,RR->node->now(),com.issuedTo(),network->config(),(const Capability *)0);
 	} else {
 		TRACE("addCredential(CertificateOfMembership) for %s on %.16llx REJECTED (%d)",com.issuedTo().toString().c_str(),com.networkId(),vr);
 	}

+ 1 - 2
node/Membership.hpp

@@ -218,11 +218,10 @@ public:
 	 * Validate and add a credential if signature is okay and it's otherwise good
 	 *
 	 * @param RR Runtime environment
-	 * @param network Network that owns this Membership
 	 * @param com Certificate of membership
 	 * @return 0 == OK, 1 == waiting for WHOIS, -1 == BAD signature or credential
 	 */
-	int addCredential(const RuntimeEnvironment *RR,const Network *network,const CertificateOfMembership &com);
+	int addCredential(const RuntimeEnvironment *RR,const CertificateOfMembership &com);
 
 	/**
 	 * Validate and add a credential if signature is okay and it's otherwise good

+ 23 - 8
node/Network.cpp

@@ -678,7 +678,7 @@ bool Network::filterOutgoingPacket(
 						accept = true;
 
 						if ((!noTee)&&(cc2)) {
-							_memberships[cc2].sendCredentialsIfNeeded(RR,RR->node->now(),cc2,_config,relevantCap);
+							_membership(cc2).sendCredentialsIfNeeded(RR,RR->node->now(),cc2,_config,relevantCap);
 
 							Packet outp(cc2,RR->identity.address(),Packet::VERB_EXT_FRAME);
 							outp.append(_id);
@@ -710,7 +710,7 @@ bool Network::filterOutgoingPacket(
 
 	if (accept) {
 		if ((!noTee)&&(cc)) {
-			_memberships[cc].sendCredentialsIfNeeded(RR,RR->node->now(),cc,_config,relevantCap);
+			_membership(cc).sendCredentialsIfNeeded(RR,RR->node->now(),cc,_config,relevantCap);
 
 			Packet outp(cc,RR->identity.address(),Packet::VERB_EXT_FRAME);
 			outp.append(_id);
@@ -724,7 +724,7 @@ bool Network::filterOutgoingPacket(
 		}
 
 		if ((ztDest != ztDest2)&&(ztDest2)) {
-			_memberships[ztDest2].sendCredentialsIfNeeded(RR,RR->node->now(),ztDest2,_config,relevantCap);
+			_membership(ztDest2).sendCredentialsIfNeeded(RR,RR->node->now(),ztDest2,_config,relevantCap);
 
 			Packet outp(ztDest2,RR->identity.address(),Packet::VERB_EXT_FRAME);
 			outp.append(_id);
@@ -764,7 +764,7 @@ int Network::filterIncomingPacket(
 
 	Mutex::Lock _l(_lock);
 
-	Membership &m = _memberships[ztDest];
+	Membership &m = _membership(ztDest);
 	const unsigned int remoteTagCount = m.getAllTags(_config,remoteTagIds,remoteTagValues,ZT_MAX_NETWORK_TAGS);
 
 	switch (_doZtFilter(RR,_config,true,sourcePeer->address(),ztDest2,macSource,macDest,frameData,frameLen,etherType,vlanId,_config.rules,_config.ruleCount,_config.tags,_config.tagCount,remoteTagIds,remoteTagValues,remoteTagCount,cc,ccLength)) {
@@ -791,7 +791,7 @@ int Network::filterIncomingPacket(
 
 				if (accept) {
 					if (cc2) {
-						_memberships[cc2].sendCredentialsIfNeeded(RR,RR->node->now(),cc2,_config,(const Capability *)0);
+						_membership(cc2).sendCredentialsIfNeeded(RR,RR->node->now(),cc2,_config,(const Capability *)0);
 
 						Packet outp(cc2,RR->identity.address(),Packet::VERB_EXT_FRAME);
 						outp.append(_id);
@@ -822,7 +822,7 @@ int Network::filterIncomingPacket(
 
 	if (accept) {
 		if (cc) {
-			_memberships[cc].sendCredentialsIfNeeded(RR,RR->node->now(),cc,_config,(const Capability *)0);
+			_membership(cc).sendCredentialsIfNeeded(RR,RR->node->now(),cc,_config,(const Capability *)0);
 
 			Packet outp(cc,RR->identity.address(),Packet::VERB_EXT_FRAME);
 			outp.append(_id);
@@ -836,7 +836,7 @@ int Network::filterIncomingPacket(
 		}
 
 		if ((ztDest != ztDest2)&&(ztDest2)) {
-			_memberships[ztDest2].sendCredentialsIfNeeded(RR,RR->node->now(),ztDest2,_config,(const Capability *)0);
+			_membership(ztDest2).sendCredentialsIfNeeded(RR,RR->node->now(),ztDest2,_config,(const Capability *)0);
 
 			Packet outp(ztDest2,RR->identity.address(),Packet::VERB_EXT_FRAME);
 			outp.append(_id);
@@ -1247,7 +1247,8 @@ void Network::_announceMulticastGroups(const MulticastGroup *const onlyThis)
 	}
 
 	// Make sure that all "network anchors" have Membership records so we will
-	// push multicasts to them.
+	// push multicasts to them. Note that _membership() also does this but in a
+	// piecemeal on-demand fashion.
 	const std::vector<Address> anchors(_config.anchors());
 	for(std::vector<Address>::const_iterator a(anchors.begin());a!=anchors.end();++a)
 		_memberships[*a];
@@ -1306,4 +1307,18 @@ std::vector<MulticastGroup> Network::_allMulticastGroups() const
 	return mgs;
 }
 
+Membership &Network::_membership(const Address &a)
+{
+	// assumes _lock is locked
+	const unsigned long ms = _memberships.size();
+	Membership &m = _memberships[a];
+	if (ms != _memberships.size()) {
+		const uint64_t now = RR->node->now();
+		m.sendCredentialsIfNeeded(RR,now,a,_config,(const Capability *)0);
+		_announceMulticastGroupsTo(a,_allMulticastGroups());
+		m.likingMulticasts(now);
+	}
+	return m;
+}
+
 } // namespace ZeroTier

+ 5 - 4
node/Network.hpp

@@ -353,7 +353,7 @@ public:
 		if (com.networkId() != _id)
 			return -1;
 		Mutex::Lock _l(_lock);
-		return _memberships[com.issuedTo()].addCredential(RR,this,com);
+		return _membership(com.issuedTo()).addCredential(RR,com);
 	}
 
 	/**
@@ -365,7 +365,7 @@ public:
 		if (cap.networkId() != _id)
 			return -1;
 		Mutex::Lock _l(_lock);
-		return _memberships[cap.issuedTo()].addCredential(RR,cap);
+		return _membership(cap.issuedTo()).addCredential(RR,cap);
 	}
 
 	/**
@@ -377,7 +377,7 @@ public:
 		if (tag.networkId() != _id)
 			return -1;
 		Mutex::Lock _l(_lock);
-		return _memberships[tag.issuedTo()].addCredential(RR,tag);
+		return _membership(tag.issuedTo()).addCredential(RR,tag);
 	}
 
 	/**
@@ -388,7 +388,7 @@ public:
 	inline void blacklistBefore(const Address &peerAddress,const uint64_t ts)
 	{
 		Mutex::Lock _l(_lock);
-		_memberships[peerAddress].blacklistBefore(ts);
+		_membership(peerAddress).blacklistBefore(ts);
 	}
 
 	/**
@@ -412,6 +412,7 @@ private:
 	void _announceMulticastGroups(const MulticastGroup *const onlyThis);
 	void _announceMulticastGroupsTo(const Address &peer,const std::vector<MulticastGroup> &allMulticastGroups);
 	std::vector<MulticastGroup> _allMulticastGroups() const;
+	Membership &_membership(const Address &a); // also lazily sends COM and MULTICAST_LIKE(s) if this is a new member
 
 	const RuntimeEnvironment *RR;
 	void *_uPtr;