Browse Source

Add a circuit breaker to prevent too many credentials from being stored per member.

Adam Ierymenko 9 years ago
parent
commit
e52c2c41ec
2 changed files with 31 additions and 1 deletions
  1. 29 1
      node/Membership.cpp
  2. 2 0
      node/Membership.hpp

+ 29 - 1
node/Membership.cpp

@@ -106,8 +106,24 @@ int Membership::addCredential(const RuntimeEnvironment *RR,const Tag &tag)
 	const int vr = tag.verify(RR);
 	if (vr == 0) {
 		TRACE("addCredential(Tag) for %s on %.16llx ACCEPTED (new)",tag.issuedTo().toString().c_str(),tag.networkId());
-		if (!t)
+		if (!t) {
+			while (_tags.size() >= ZT_MAX_NETWORK_TAGS) {
+				uint32_t oldest = 0;
+				uint64_t oldestLastReceived = 0xffffffffffffffffULL;
+				uint32_t *i = (uint32_t *)0;
+				TState *ts = (TState *)0;
+				Hashtable<uint32_t,TState>::Iterator tsi(_tags);
+				while (tsi.next(i,ts)) {
+					if (ts->lastReceived < oldestLastReceived) {
+						oldestLastReceived = ts->lastReceived;
+						oldest = *i;
+					}
+				}
+				if (oldestLastReceived != 0xffffffffffffffffULL)
+					_tags.erase(oldest);
+			}
 			t = &(_tags[tag.id()]);
+		}
 		if (t->tag.timestamp() <= tag.timestamp()) {
 			t->lastReceived = RR->node->now();
 			t->tag = tag;
@@ -129,6 +145,18 @@ int Membership::addCredential(const RuntimeEnvironment *RR,const Capability &cap
 	if (vr == 0) {
 		TRACE("addCredential(Capability) for %s on %.16llx ACCEPTED (new)",cap.issuedTo().toString().c_str(),cap.networkId());
 		if (c == _caps.end()) {
+			while (_caps.size() >= ZT_MAX_NETWORK_CAPABILITIES) {
+				std::map<uint32_t,CState>::iterator oldest;
+				uint64_t oldestLastReceived = 0xffffffffffffffffULL;
+				for(std::map<uint32_t,CState>::iterator i(_caps.begin());i!=_caps.end();++i) {
+					if (i->second.lastReceived < oldestLastReceived) {
+						oldestLastReceived = i->second.lastReceived;
+						oldest = i;
+					}
+				}
+				if (oldestLastReceived != 0xffffffffffffffffULL)
+					_caps.erase(oldest);
+			}
 			CState &c2 = _caps[cap.id()];
 			c2.lastReceived = RR->node->now();
 			c2.cap = cap;

+ 2 - 0
node/Membership.hpp

@@ -46,6 +46,8 @@ class RuntimeEnvironment;
  *
  * This is kind of analogous to a join table between Peer and Network. It is
  * presently held by the Network object for each participating Peer.
+ *
+ * This is not thread safe. It must be locked externally.
  */
 class Membership
 {