diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2016-08-24 17:24:35 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2016-08-24 17:24:35 -0700 |
commit | e52c2c41ecab0410f926965fd433da6eb9cd4039 (patch) | |
tree | 382f4b6eb1d29b888ecd24c0cceb76c2ddf565a0 /node | |
parent | 95ff057e04fe9ca0822af59c4284e3ea3fdccfc7 (diff) | |
download | infinitytier-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.cpp | 30 | ||||
-rw-r--r-- | node/Membership.hpp | 2 |
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 { |