summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2016-08-24 17:24:35 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2016-08-24 17:24:35 -0700
commite52c2c41ecab0410f926965fd433da6eb9cd4039 (patch)
tree382f4b6eb1d29b888ecd24c0cceb76c2ddf565a0 /node
parent95ff057e04fe9ca0822af59c4284e3ea3fdccfc7 (diff)
downloadinfinitytier-e52c2c41ecab0410f926965fd433da6eb9cd4039.tar.gz
infinitytier-e52c2c41ecab0410f926965fd433da6eb9cd4039.zip
Add a circuit breaker to prevent too many credentials from being stored per member.
Diffstat (limited to 'node')
-rw-r--r--node/Membership.cpp30
-rw-r--r--node/Membership.hpp2
2 files changed, 31 insertions, 1 deletions
diff --git a/node/Membership.cpp b/node/Membership.cpp
index f1bd94aa..8bf5b784 100644
--- a/node/Membership.cpp
+++ b/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;
diff --git a/node/Membership.hpp b/node/Membership.hpp
index dc525483..bb356902 100644
--- a/node/Membership.hpp
+++ b/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
{