Browse Source

Two for one! (std::map removal)

Adam Ierymenko 10 years ago
parent
commit
307e44f7c8
2 changed files with 45 additions and 46 deletions
  1. 36 42
      node/Network.cpp
  2. 9 4
      node/Network.hpp

+ 36 - 42
node/Network.cpp

@@ -92,7 +92,7 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid) :
 						com.deserialize2(p,e);
 						if (!com)
 							break;
-						_membershipCertificates.insert(std::pair< Address,CertificateOfMembership >(com.issuedTo(),com));
+						_certInfo[com.issuedTo()].com = com;
 					}
 				}
 			}
@@ -125,19 +125,22 @@ Network::~Network()
 
 		clean();
 
-		std::string buf("ZTMCD0");
 		Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.mcerts",_id);
-		Mutex::Lock _l(_lock);
 
-		if ((!_config)||(_config->isPublic())||(_membershipCertificates.size() == 0)) {
+		Mutex::Lock _l(_lock);
+		if ((!_config)||(_config->isPublic())||(_certInfo.empty())) {
 			RR->node->dataStoreDelete(n);
-			return;
+		} else {
+			std::string buf("ZTMCD0");
+			Hashtable< Address,_RemoteMemberCertificateInfo >::Iterator i(_certInfo);
+			Address *a = (Address *)0;
+			_RemoteMemberCertificateInfo *ci = (_RemoteMemberCertificateInfo *)0;
+			while (i.next(a,ci)) {
+				if (ci->com)
+					ci->com.serialize2(buf);
+			}
+			RR->node->dataStorePut(n,buf,true);
 		}
-
-		for(std::map<Address,CertificateOfMembership>::iterator c(_membershipCertificates.begin());c!=_membershipCertificates.end();++c)
-			c->second.serialize2(buf);
-
-		RR->node->dataStorePut(n,buf,true);
 	}
 }
 
@@ -284,11 +287,12 @@ bool Network::validateAndAddMembershipCertificate(const CertificateOfMembership
 		return false;
 
 	Mutex::Lock _l(_lock);
-	CertificateOfMembership &old = _membershipCertificates[cert.issuedTo()];
 
-	// Nothing to do if the cert hasn't changed -- we get duplicates due to zealous cert pushing
-	if (old == cert)
-		return true; // but if it's a duplicate of one we already accepted, return is 'true'
+	{
+		const _RemoteMemberCertificateInfo *ci = _certInfo.get(cert.issuedTo());
+		if ((ci)&&(ci->com == cert))
+			return true; // we already have it
+	}
 
 	// Check signature, log and return if cert is invalid
 	if (cert.signedBy() != controller()) {
@@ -322,9 +326,8 @@ bool Network::validateAndAddMembershipCertificate(const CertificateOfMembership
 		}
 	}
 
-	// If we made it past authentication, update cert
-	if (cert.revision() != old.revision())
-		old = cert;
+	// If we made it past authentication, add or update cert in our cert info store
+	_certInfo[cert.issuedTo()].com = cert;
 
 	return true;
 }
@@ -333,9 +336,9 @@ bool Network::peerNeedsOurMembershipCertificate(const Address &to,uint64_t now)
 {
 	Mutex::Lock _l(_lock);
 	if ((_config)&&(!_config->isPublic())&&(_config->com())) {
-		uint64_t &lastPushed = _lastPushedMembershipCertificate[to];
-		if ((now - lastPushed) > (ZT_NETWORK_AUTOCONF_DELAY / 2)) {
-			lastPushed = now;
+		_RemoteMemberCertificateInfo &ci = _certInfo[to];
+		if ((now - ci.lastPushed) > (ZT_NETWORK_AUTOCONF_DELAY / 2)) {
+			ci.lastPushed = now;
 			return true;
 		}
 	}
@@ -352,23 +355,16 @@ void Network::clean()
 
 	if ((_config)&&(_config->isPublic())) {
 		// Open (public) networks do not track certs or cert pushes at all.
-		_membershipCertificates.clear();
-		_lastPushedMembershipCertificate.clear();
+		_certInfo.clear();
 	} else if (_config) {
-		// Clean certificates that are no longer valid from the cache.
-		for(std::map<Address,CertificateOfMembership>::iterator c=(_membershipCertificates.begin());c!=_membershipCertificates.end();) {
-			if (_config->com().agreesWith(c->second))
-				++c;
-			else _membershipCertificates.erase(c++);
-		}
-
-		// Clean entries from the last pushed tracking map if they're so old as
-		// to be no longer relevant.
-		uint64_t forgetIfBefore = now - (ZT_PEER_ACTIVITY_TIMEOUT * 16); // arbitrary reasonable cutoff
-		for(std::map<Address,uint64_t>::iterator lp(_lastPushedMembershipCertificate.begin());lp!=_lastPushedMembershipCertificate.end();) {
-			if (lp->second < forgetIfBefore)
-				_lastPushedMembershipCertificate.erase(lp++);
-			else ++lp;
+		// Clean obsolete entries from private network cert info table
+		Hashtable< Address,_RemoteMemberCertificateInfo >::Iterator i(_certInfo);
+		Address *a = (Address *)0;
+		_RemoteMemberCertificateInfo *ci = (_RemoteMemberCertificateInfo *)0;
+		const uint64_t forgetIfBefore = now - (ZT_PEER_ACTIVITY_TIMEOUT * 16); // arbitrary reasonable cutoff
+		while (i.next(a,ci)) {
+			if ((ci->lastPushed < forgetIfBefore)&&(!ci->com.agreesWith(_config->com())))
+				_certInfo.erase(*a);
 		}
 	}
 
@@ -506,12 +502,10 @@ bool Network::_isAllowed(const Address &peer) const
 			return false;
 		if (_config->isPublic())
 			return true;
-
-		std::map<Address,CertificateOfMembership>::const_iterator pc(_membershipCertificates.find(peer));
-		if (pc == _membershipCertificates.end())
-			return false; // no certificate on file
-
-		return _config->com().agreesWith(pc->second); // is other cert valid against ours?
+		const _RemoteMemberCertificateInfo *ci = _certInfo.get(peer);
+		if (!ci)
+			return false;
+		return _config->com().agreesWith(ci->com);
 	} catch (std::exception &exc) {
 		TRACE("isAllowed() check failed for peer %s: unexpected exception: %s",peer.toString().c_str(),exc.what());
 	} catch ( ... ) {

+ 9 - 4
node/Network.hpp

@@ -347,6 +347,13 @@ public:
 	inline bool operator>=(const Network &n) const throw() { return (_id >= n._id); }
 
 private:
+	struct _RemoteMemberCertificateInfo
+	{
+		_RemoteMemberCertificateInfo() : com(),lastPushed(0) {}
+		CertificateOfMembership com; // remote member's COM
+		uint64_t lastPushed; // when did we last push ours to them?
+	};
+
 	ZT1_VirtualNetworkStatus _status() const;
 	void _externalConfig(ZT1_VirtualNetworkConfig *ec) const; // assumes _lock is locked
 	bool _isAllowed(const Address &peer) const;
@@ -361,11 +368,9 @@ private:
 
 	std::vector< MulticastGroup > _myMulticastGroups; // multicast groups that we belong to (according to tap)
 	Hashtable< MulticastGroup,uint64_t > _multicastGroupsBehindMe; // multicast groups that seem to be behind us and when we last saw them (if we are a bridge)
+	Hashtable< MAC,Address > _remoteBridgeRoutes; // remote addresses where given MACs are reachable (for tracking devices behind remote bridges)
 
-	Hashtable< MAC,Address > _remoteBridgeRoutes; // remote addresses where given MACs are reachable (for remote bridges)
-
-	std::map<Address,CertificateOfMembership> _membershipCertificates; // Other members' certificates of membership
-	std::map<Address,uint64_t> _lastPushedMembershipCertificate; // When did we last push our certificate to each remote member?
+	Hashtable< Address,_RemoteMemberCertificateInfo > _certInfo;
 
 	SharedPtr<NetworkConfig> _config; // Most recent network configuration, which is an immutable value-object
 	volatile uint64_t _lastConfigUpdate;