diff options
Diffstat (limited to 'node/Membership.cpp')
-rw-r--r-- | node/Membership.cpp | 282 |
1 files changed, 184 insertions, 98 deletions
diff --git a/node/Membership.cpp b/node/Membership.cpp index c8fb8e4e..a60b86be 100644 --- a/node/Membership.cpp +++ b/node/Membership.cpp @@ -32,87 +32,95 @@ namespace ZeroTier { Membership::Membership() : _lastUpdatedMulticast(0), - _lastPushAttempt(0), _lastPushedCom(0), _comRevocationThreshold(0) { for(unsigned int i=0;i<ZT_MAX_NETWORK_TAGS;++i) _remoteTags[i] = &(_tagMem[i]); for(unsigned int i=0;i<ZT_MAX_NETWORK_CAPABILITIES;++i) _remoteCaps[i] = &(_capMem[i]); + for(unsigned int i=0;i<ZT_MAX_CERTIFICATES_OF_OWNERSHIP;++i) _remoteCoos[i] = &(_cooMem[i]); } void Membership::pushCredentials(const RuntimeEnvironment *RR,const uint64_t now,const Address &peerAddress,const NetworkConfig &nconf,int localCapabilityIndex,const bool force) { - // This limits how often we go through this logic, which prevents us from - // doing all this for every single packet or other event. - if ( ((now - _lastPushAttempt) < 1000ULL) && (!force) ) - return; - _lastPushAttempt = now; - - try { - unsigned int localTagPtr = 0; - bool needCom = ( (nconf.com) && ( ((now - _lastPushedCom) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) ); - do { - Buffer<ZT_PROTO_MAX_PACKET_LENGTH> capsAndTags; - - unsigned int appendedCaps = 0; - if (localCapabilityIndex >= 0) { - capsAndTags.addSize(2); - - if ( (_localCaps[localCapabilityIndex].id != nconf.capabilities[localCapabilityIndex].id()) || ((now - _localCaps[localCapabilityIndex].lastPushed) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) { - _localCaps[localCapabilityIndex].lastPushed = now; - _localCaps[localCapabilityIndex].id = nconf.capabilities[localCapabilityIndex].id(); - nconf.capabilities[localCapabilityIndex].serialize(capsAndTags); - ++appendedCaps; - } - - capsAndTags.setAt<uint16_t>(0,(uint16_t)appendedCaps); - localCapabilityIndex = -1; // don't send this cap again on subsequent loops if force is true - } else { - capsAndTags.append((uint16_t)0); - } + bool sendCom = ( (nconf.com) && ( ((now - _lastPushedCom) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) ); - unsigned int appendedTags = 0; - const unsigned int tagCountPos = capsAndTags.size(); - capsAndTags.addSize(2); - for(;localTagPtr<nconf.tagCount;++localTagPtr) { - if ( (_localTags[localTagPtr].id != nconf.tags[localTagPtr].id()) || ((now - _localTags[localTagPtr].lastPushed) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) { - if ((capsAndTags.size() + sizeof(Tag)) >= (ZT_PROTO_MAX_PACKET_LENGTH - sizeof(CertificateOfMembership))) - break; - nconf.tags[localTagPtr].serialize(capsAndTags); - ++appendedTags; - } - } - capsAndTags.setAt<uint16_t>(tagCountPos,(uint16_t)appendedTags); - - if (needCom||appendedCaps||appendedTags) { - Packet outp(peerAddress,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS); - if (needCom) { - nconf.com.serialize(outp); - _lastPushedCom = now; - } - outp.append((uint8_t)0x00); - outp.append(capsAndTags.data(),capsAndTags.size()); - outp.append((uint16_t)0); // no revocations, these propagate differently - outp.compress(); - RR->sw->send(outp,true); - needCom = false; // don't send COM again on subsequent loops if force is true - } - } while (localTagPtr < nconf.tagCount); - } catch ( ... ) { - TRACE("unable to send credentials due to unexpected exception"); + const Capability *sendCap; + if (localCapabilityIndex >= 0) { + sendCap = &(nconf.capabilities[localCapabilityIndex]); + if ( (_localCaps[localCapabilityIndex].id != sendCap->id()) || ((now - _localCaps[localCapabilityIndex].lastPushed) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) { + _localCaps[localCapabilityIndex].lastPushed = now; + _localCaps[localCapabilityIndex].id = sendCap->id(); + } else sendCap = (const Capability *)0; + } else sendCap = (const Capability *)0; + + const Tag *sendTags[ZT_MAX_NETWORK_TAGS]; + unsigned int sendTagCount = 0; + for(unsigned int t=0;t<nconf.tagCount;++t) { + if ( (_localTags[t].id != nconf.tags[t].id()) || ((now - _localTags[t].lastPushed) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) { + _localTags[t].lastPushed = now; + _localTags[t].id = nconf.tags[t].id(); + sendTags[sendTagCount++] = &(nconf.tags[t]); + } } -} -const Capability *Membership::getCapability(const NetworkConfig &nconf,const uint32_t id) const -{ - const _RemoteCapability *const *c = std::lower_bound(&(_remoteCaps[0]),&(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]),(uint64_t)id,_RemoteCredentialSorter<_RemoteCapability>()); - return ( ((c != &(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]))&&((*c)->id == (uint64_t)id)) ? ((((*c)->lastReceived)&&(_isCredentialTimestampValid(nconf,(*c)->cap,**c))) ? &((*c)->cap) : (const Capability *)0) : (const Capability *)0); + const CertificateOfOwnership *sendCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP]; + unsigned int sendCooCount = 0; + for(unsigned int c=0;c<nconf.certificateOfOwnershipCount;++c) { + if ( (_localCoos[c].id != nconf.certificatesOfOwnership[c].id()) || ((now - _localCoos[c].lastPushed) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) { + _localCoos[c].lastPushed = now; + _localCoos[c].id = nconf.certificatesOfOwnership[c].id(); + sendCoos[sendCooCount++] = &(nconf.certificatesOfOwnership[c]); + } + } + + unsigned int tagPtr = 0; + unsigned int cooPtr = 0; + while ((tagPtr < sendTagCount)||(cooPtr < sendCooCount)||(sendCom)||(sendCap)) { + Packet outp(peerAddress,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS); + + if (sendCom) { + sendCom = false; + nconf.com.serialize(outp); + _lastPushedCom = now; + } + outp.append((uint8_t)0x00); + + if (sendCap) { + outp.append((uint16_t)1); + sendCap->serialize(outp); + sendCap = (const Capability *)0; + } else outp.append((uint16_t)0); + + const unsigned int tagCountAt = outp.size(); + outp.addSize(2); + unsigned int thisPacketTagCount = 0; + while ((tagPtr < sendTagCount)&&((outp.size() + sizeof(Tag) + 16) < ZT_PROTO_MAX_PACKET_LENGTH)) { + sendTags[tagPtr++]->serialize(outp); + ++thisPacketTagCount; + } + outp.setAt(tagCountAt,(uint16_t)thisPacketTagCount); + + // No revocations, these propagate differently + outp.append((uint16_t)0); + + const unsigned int cooCountAt = outp.size(); + outp.addSize(2); + unsigned int thisPacketCooCount = 0; + while ((cooPtr < sendCooCount)&&((outp.size() + sizeof(CertificateOfOwnership) + 16) < ZT_PROTO_MAX_PACKET_LENGTH)) { + sendCoos[cooPtr++]->serialize(outp); + ++thisPacketCooCount; + } + outp.setAt(cooCountAt,(uint16_t)thisPacketCooCount); + + outp.compress(); + RR->sw->send(outp,true); + } } const Tag *Membership::getTag(const NetworkConfig &nconf,const uint32_t id) const { - const _RemoteTag *const *t = std::lower_bound(&(_remoteTags[0]),&(_remoteTags[ZT_MAX_NETWORK_TAGS]),(uint64_t)id,_RemoteCredentialSorter<_RemoteTag>()); - return ( ((t != &(_remoteTags[ZT_MAX_NETWORK_CAPABILITIES]))&&((*t)->id == (uint64_t)id)) ? ((((*t)->lastReceived)&&(_isCredentialTimestampValid(nconf,(*t)->tag,**t))) ? &((*t)->tag) : (const Tag *)0) : (const Tag *)0); + const _RemoteCredential<Tag> *const *t = std::lower_bound(&(_remoteTags[0]),&(_remoteTags[ZT_MAX_NETWORK_TAGS]),(uint64_t)id,_RemoteCredentialComp<Tag>()); + return ( ((t != &(_remoteTags[ZT_MAX_NETWORK_CAPABILITIES]))&&((*t)->id == (uint64_t)id)) ? ((((*t)->lastReceived)&&(_isCredentialTimestampValid(nconf,**t))) ? &((*t)->credential) : (const Tag *)0) : (const Tag *)0); } Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,const NetworkConfig &nconf,const CertificateOfMembership &com) @@ -148,14 +156,14 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,const NetworkConfig &nconf,const Tag &tag) { - _RemoteTag *const *htmp = std::lower_bound(&(_remoteTags[0]),&(_remoteTags[ZT_MAX_NETWORK_TAGS]),(uint64_t)tag.id(),_RemoteCredentialSorter<_RemoteTag>()); - _RemoteTag *have = ((htmp != &(_remoteTags[ZT_MAX_NETWORK_TAGS]))&&((*htmp)->id == (uint64_t)tag.id())) ? *htmp : (_RemoteTag *)0; + _RemoteCredential<Tag> *const *htmp = std::lower_bound(&(_remoteTags[0]),&(_remoteTags[ZT_MAX_NETWORK_TAGS]),(uint64_t)tag.id(),_RemoteCredentialComp<Tag>()); + _RemoteCredential<Tag> *have = ((htmp != &(_remoteTags[ZT_MAX_NETWORK_TAGS]))&&((*htmp)->id == (uint64_t)tag.id())) ? *htmp : (_RemoteCredential<Tag> *)0; if (have) { - if ( (!_isCredentialTimestampValid(nconf,tag,*have)) || (have->tag.timestamp() > tag.timestamp()) ) { + if ( (!_isCredentialTimestampValid(nconf,*have)) || (have->credential.timestamp() > tag.timestamp()) ) { TRACE("addCredential(Tag) for %s on %.16llx REJECTED (revoked or too old)",tag.issuedTo().toString().c_str(),tag.networkId()); return ADD_REJECTED; } - if (have->tag == tag) { + if (have->credential == tag) { TRACE("addCredential(Tag) for %s on %.16llx ACCEPTED (redundant)",tag.issuedTo().toString().c_str(),tag.networkId()); return ADD_ACCEPTED_REDUNDANT; } @@ -169,7 +177,7 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme TRACE("addCredential(Tag) for %s on %.16llx ACCEPTED (new)",tag.issuedTo().toString().c_str(),tag.networkId()); if (!have) have = _newTag(tag.id()); have->lastReceived = RR->node->now(); - have->tag = tag; + have->credential = tag; return ADD_ACCEPTED_NEW; case 1: return ADD_DEFERRED_FOR_WHOIS; @@ -178,28 +186,28 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,const NetworkConfig &nconf,const Capability &cap) { - _RemoteCapability *const *htmp = std::lower_bound(&(_remoteCaps[0]),&(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]),(uint64_t)cap.id(),_RemoteCredentialSorter<_RemoteCapability>()); - _RemoteCapability *have = ((htmp != &(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]))&&((*htmp)->id == (uint64_t)cap.id())) ? *htmp : (_RemoteCapability *)0; + _RemoteCredential<Capability> *const *htmp = std::lower_bound(&(_remoteCaps[0]),&(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]),(uint64_t)cap.id(),_RemoteCredentialComp<Capability>()); + _RemoteCredential<Capability> *have = ((htmp != &(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]))&&((*htmp)->id == (uint64_t)cap.id())) ? *htmp : (_RemoteCredential<Capability> *)0; if (have) { - if ( (!_isCredentialTimestampValid(nconf,cap,*have)) || (have->cap.timestamp() > cap.timestamp()) ) { - TRACE("addCredential(Tag) for %s on %.16llx REJECTED (revoked or too old)",cap.issuedTo().toString().c_str(),cap.networkId()); + if ( (!_isCredentialTimestampValid(nconf,*have)) || (have->credential.timestamp() > cap.timestamp()) ) { + TRACE("addCredential(Capability) for %s on %.16llx REJECTED (revoked or too old)",cap.issuedTo().toString().c_str(),cap.networkId()); return ADD_REJECTED; } - if (have->cap == cap) { - TRACE("addCredential(Tag) for %s on %.16llx ACCEPTED (redundant)",cap.issuedTo().toString().c_str(),cap.networkId()); + if (have->credential == cap) { + TRACE("addCredential(Capability) for %s on %.16llx ACCEPTED (redundant)",cap.issuedTo().toString().c_str(),cap.networkId()); return ADD_ACCEPTED_REDUNDANT; } } switch(cap.verify(RR)) { default: - TRACE("addCredential(Tag) for %s on %.16llx REJECTED (invalid)",cap.issuedTo().toString().c_str(),cap.networkId()); + TRACE("addCredential(Capability) for %s on %.16llx REJECTED (invalid)",cap.issuedTo().toString().c_str(),cap.networkId()); return ADD_REJECTED; case 0: - TRACE("addCredential(Tag) for %s on %.16llx ACCEPTED (new)",cap.issuedTo().toString().c_str(),cap.networkId()); + TRACE("addCredential(Capability) for %s on %.16llx ACCEPTED (new)",cap.issuedTo().toString().c_str(),cap.networkId()); if (!have) have = _newCapability(cap.id()); have->lastReceived = RR->node->now(); - have->cap = cap; + have->credential = cap; return ADD_ACCEPTED_NEW; case 1: return ADD_DEFERRED_FOR_WHOIS; @@ -216,13 +224,15 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme switch(rev.type()) { default: //case Revocation::CREDENTIAL_TYPE_ALL: - return ( (_revokeCom(rev)||_revokeCap(rev,now)||_revokeTag(rev,now)) ? ADD_ACCEPTED_NEW : ADD_ACCEPTED_REDUNDANT ); + return ( (_revokeCom(rev)||_revokeCap(rev,now)||_revokeTag(rev,now)||_revokeCoo(rev,now)) ? ADD_ACCEPTED_NEW : ADD_ACCEPTED_REDUNDANT ); case Revocation::CREDENTIAL_TYPE_COM: return (_revokeCom(rev) ? ADD_ACCEPTED_NEW : ADD_ACCEPTED_REDUNDANT); case Revocation::CREDENTIAL_TYPE_CAPABILITY: return (_revokeCap(rev,now) ? ADD_ACCEPTED_NEW : ADD_ACCEPTED_REDUNDANT); case Revocation::CREDENTIAL_TYPE_TAG: return (_revokeTag(rev,now) ? ADD_ACCEPTED_NEW : ADD_ACCEPTED_REDUNDANT); + case Revocation::CREDENTIAL_TYPE_COO: + return (_revokeCoo(rev,now) ? ADD_ACCEPTED_NEW : ADD_ACCEPTED_REDUNDANT); } } case 1: @@ -230,9 +240,39 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme } } -Membership::_RemoteTag *Membership::_newTag(const uint64_t id) +Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,const NetworkConfig &nconf,const CertificateOfOwnership &coo) +{ + _RemoteCredential<CertificateOfOwnership> *const *htmp = std::lower_bound(&(_remoteCoos[0]),&(_remoteCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP]),(uint64_t)coo.id(),_RemoteCredentialComp<CertificateOfOwnership>()); + _RemoteCredential<CertificateOfOwnership> *have = ((htmp != &(_remoteCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP]))&&((*htmp)->id == (uint64_t)coo.id())) ? *htmp : (_RemoteCredential<CertificateOfOwnership> *)0; + if (have) { + if ( (!_isCredentialTimestampValid(nconf,*have)) || (have->credential.timestamp() > coo.timestamp()) ) { + TRACE("addCredential(CertificateOfOwnership) for %s on %.16llx REJECTED (revoked or too old)",coo.issuedTo().toString().c_str(),coo.networkId()); + return ADD_REJECTED; + } + if (have->credential == coo) { + TRACE("addCredential(CertificateOfOwnership) for %s on %.16llx ACCEPTED (redundant)",coo.issuedTo().toString().c_str(),coo.networkId()); + return ADD_ACCEPTED_REDUNDANT; + } + } + + switch(coo.verify(RR)) { + default: + TRACE("addCredential(CertificateOfOwnership) for %s on %.16llx REJECTED (invalid)",coo.issuedTo().toString().c_str(),coo.networkId()); + return ADD_REJECTED; + case 0: + TRACE("addCredential(CertificateOfOwnership) for %s on %.16llx ACCEPTED (new)",coo.issuedTo().toString().c_str(),coo.networkId()); + if (!have) have = _newCoo(coo.id()); + have->lastReceived = RR->node->now(); + have->credential = coo; + return ADD_ACCEPTED_NEW; + case 1: + return ADD_DEFERRED_FOR_WHOIS; + } +} + +Membership::_RemoteCredential<Tag> *Membership::_newTag(const uint64_t id) { - _RemoteTag *t; + _RemoteCredential<Tag> *t = NULL; uint64_t minlr = 0xffffffffffffffffULL; for(unsigned int i=0;i<ZT_MAX_NETWORK_TAGS;++i) { if (_remoteTags[i]->id == ZT_MEMBERSHIP_CRED_ID_UNUSED) { @@ -243,17 +283,21 @@ Membership::_RemoteTag *Membership::_newTag(const uint64_t id) minlr = _remoteTags[i]->lastReceived; } } - t->id = id; - t->lastReceived = 0; - t->revocationThreshold = 0; - t->tag = Tag(); - std::sort(&(_remoteTags[0]),&(_remoteTags[ZT_MAX_NETWORK_TAGS]),_RemoteCredentialSorter<_RemoteTag>()); + + if (t) { + t->id = id; + t->lastReceived = 0; + t->revocationThreshold = 0; + t->credential = Tag(); + } + + std::sort(&(_remoteTags[0]),&(_remoteTags[ZT_MAX_NETWORK_TAGS]),_RemoteCredentialComp<Tag>()); return t; } -Membership::_RemoteCapability *Membership::_newCapability(const uint64_t id) +Membership::_RemoteCredential<Capability> *Membership::_newCapability(const uint64_t id) { - _RemoteCapability *c; + _RemoteCredential<Capability> *c = NULL; uint64_t minlr = 0xffffffffffffffffULL; for(unsigned int i=0;i<ZT_MAX_NETWORK_CAPABILITIES;++i) { if (_remoteCaps[i]->id == ZT_MEMBERSHIP_CRED_ID_UNUSED) { @@ -264,11 +308,40 @@ Membership::_RemoteCapability *Membership::_newCapability(const uint64_t id) minlr = _remoteCaps[i]->lastReceived; } } - c->id = id; - c->lastReceived = 0; - c->revocationThreshold = 0; - c->cap = Capability(); - std::sort(&(_remoteCaps[0]),&(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]),_RemoteCredentialSorter<_RemoteCapability>()); + + if (c) { + c->id = id; + c->lastReceived = 0; + c->revocationThreshold = 0; + c->credential = Capability(); + } + + std::sort(&(_remoteCaps[0]),&(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]),_RemoteCredentialComp<Capability>()); + return c; +} + +Membership::_RemoteCredential<CertificateOfOwnership> *Membership::_newCoo(const uint64_t id) +{ + _RemoteCredential<CertificateOfOwnership> *c = NULL; + uint64_t minlr = 0xffffffffffffffffULL; + for(unsigned int i=0;i<ZT_MAX_CERTIFICATES_OF_OWNERSHIP;++i) { + if (_remoteCoos[i]->id == ZT_MEMBERSHIP_CRED_ID_UNUSED) { + c = _remoteCoos[i]; + break; + } else if (_remoteCoos[i]->lastReceived <= minlr) { + c = _remoteCoos[i]; + minlr = _remoteCoos[i]->lastReceived; + } + } + + if (c) { + c->id = id; + c->lastReceived = 0; + c->revocationThreshold = 0; + c->credential = CertificateOfOwnership(); + } + + std::sort(&(_remoteCoos[0]),&(_remoteCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP]),_RemoteCredentialComp<CertificateOfOwnership>()); return c; } @@ -283,8 +356,8 @@ bool Membership::_revokeCom(const Revocation &rev) bool Membership::_revokeCap(const Revocation &rev,const uint64_t now) { - _RemoteCapability *const *htmp = std::lower_bound(&(_remoteCaps[0]),&(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]),(uint64_t)rev.credentialId(),_RemoteCredentialSorter<_RemoteCapability>()); - _RemoteCapability *have = ((htmp != &(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]))&&((*htmp)->id == (uint64_t)rev.credentialId())) ? *htmp : (_RemoteCapability *)0; + _RemoteCredential<Capability> *const *htmp = std::lower_bound(&(_remoteCaps[0]),&(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]),(uint64_t)rev.credentialId(),_RemoteCredentialComp<Capability>()); + _RemoteCredential<Capability> *have = ((htmp != &(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]))&&((*htmp)->id == (uint64_t)rev.credentialId())) ? *htmp : (_RemoteCredential<Capability> *)0; if (!have) have = _newCapability(rev.credentialId()); if (rev.threshold() > have->revocationThreshold) { have->lastReceived = now; @@ -296,8 +369,8 @@ bool Membership::_revokeCap(const Revocation &rev,const uint64_t now) bool Membership::_revokeTag(const Revocation &rev,const uint64_t now) { - _RemoteTag *const *htmp = std::lower_bound(&(_remoteTags[0]),&(_remoteTags[ZT_MAX_NETWORK_TAGS]),(uint64_t)rev.credentialId(),_RemoteCredentialSorter<_RemoteTag>()); - _RemoteTag *have = ((htmp != &(_remoteTags[ZT_MAX_NETWORK_TAGS]))&&((*htmp)->id == (uint64_t)rev.credentialId())) ? *htmp : (_RemoteTag *)0; + _RemoteCredential<Tag> *const *htmp = std::lower_bound(&(_remoteTags[0]),&(_remoteTags[ZT_MAX_NETWORK_TAGS]),(uint64_t)rev.credentialId(),_RemoteCredentialComp<Tag>()); + _RemoteCredential<Tag> *have = ((htmp != &(_remoteTags[ZT_MAX_NETWORK_TAGS]))&&((*htmp)->id == (uint64_t)rev.credentialId())) ? *htmp : (_RemoteCredential<Tag> *)0; if (!have) have = _newTag(rev.credentialId()); if (rev.threshold() > have->revocationThreshold) { have->lastReceived = now; @@ -307,4 +380,17 @@ bool Membership::_revokeTag(const Revocation &rev,const uint64_t now) return false; } +bool Membership::_revokeCoo(const Revocation &rev,const uint64_t now) +{ + _RemoteCredential<CertificateOfOwnership> *const *htmp = std::lower_bound(&(_remoteCoos[0]),&(_remoteCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP]),(uint64_t)rev.credentialId(),_RemoteCredentialComp<CertificateOfOwnership>()); + _RemoteCredential<CertificateOfOwnership> *have = ((htmp != &(_remoteCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP]))&&((*htmp)->id == (uint64_t)rev.credentialId())) ? *htmp : (_RemoteCredential<CertificateOfOwnership> *)0; + if (!have) have = _newCoo(rev.credentialId()); + if (rev.threshold() > have->revocationThreshold) { + have->lastReceived = now; + have->revocationThreshold = rev.threshold(); + return true; + } + return false; +} + } // namespace ZeroTier |