summaryrefslogtreecommitdiff
path: root/node/Membership.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'node/Membership.hpp')
-rw-r--r--node/Membership.hpp121
1 files changed, 62 insertions, 59 deletions
diff --git a/node/Membership.hpp b/node/Membership.hpp
index c54aec9b..97510b57 100644
--- a/node/Membership.hpp
+++ b/node/Membership.hpp
@@ -39,49 +39,30 @@ class Network;
/**
* A container for certificates of membership and other network credentials
*
- * This is kind of analogous to a join table between Peer and Network. It is
- * held by the Network object for each participating Peer.
+ * This is essentially a relational join between Peer and Network.
*
* This class is not thread safe. It must be locked externally.
*/
class Membership
{
private:
- // Tags and related state
- struct _RemoteTag
- {
- _RemoteTag() : id(ZT_MEMBERSHIP_CRED_ID_UNUSED),lastReceived(0),revocationThreshold(0) {}
- // Tag ID (last 32 bits, first 32 bits are set in unused entries to sort them to end)
- uint64_t id;
- // Last time we received THEIR tag (with this ID)
- uint64_t lastReceived;
- // Revocation blacklist threshold or 0 if none
- uint64_t revocationThreshold;
- // THEIR tag
- Tag tag;
- };
-
- // Credentials and related state
- struct _RemoteCapability
+ template<typename T>
+ struct _RemoteCredential
{
- _RemoteCapability() : id(ZT_MEMBERSHIP_CRED_ID_UNUSED),lastReceived(0),revocationThreshold(0) {}
- // Capability ID (last 32 bits, first 32 bits are set in unused entries to sort them to end)
+ _RemoteCredential() : id(ZT_MEMBERSHIP_CRED_ID_UNUSED),lastReceived(0),revocationThreshold(0) {}
uint64_t id;
- // Last time we received THEIR capability (with this ID)
- uint64_t lastReceived;
- // Revocation blacklist threshold or 0 if none
- uint64_t revocationThreshold;
- // THEIR capability
- Capability cap;
+ uint64_t lastReceived; // last time we got this credential
+ uint64_t revocationThreshold; // credentials before this time are invalid
+ T credential;
+ inline bool operator<(const _RemoteCredential &c) const { return (id < c.id); }
};
- // Comparison operator for remote credential entries
template<typename T>
- struct _RemoteCredentialSorter
+ struct _RemoteCredentialComp
{
- inline bool operator()(const T *a,const T *b) const { return (a->id < b->id); }
- inline bool operator()(const uint64_t a,const T *b) const { return (a < b->id); }
- inline bool operator()(const T *a,const uint64_t b) const { return (a->id < b); }
+ inline bool operator()(const _RemoteCredential<T> *a,const _RemoteCredential<T> *b) const { return (a->id < b->id); }
+ inline bool operator()(const uint64_t a,const _RemoteCredential<T> *b) const { return (a < b->id); }
+ inline bool operator()(const _RemoteCredential<T> *a,const uint64_t b) const { return (a->id < b); }
inline bool operator()(const uint64_t a,const uint64_t b) const { return (a < b); }
};
@@ -89,8 +70,8 @@ private:
struct _LocalCredentialPushState
{
_LocalCredentialPushState() : lastPushed(0),id(0) {}
- uint64_t lastPushed;
- uint32_t id;
+ uint64_t lastPushed; // last time we sent our own copy of this credential
+ uint64_t id;
};
public:
@@ -117,8 +98,8 @@ public:
{
for(;;) {
if ((_i != &(_m->_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]))&&((*_i)->id != ZT_MEMBERSHIP_CRED_ID_UNUSED)) {
- const Capability *tmp = &((*_i)->cap);
- if (_m->_isCredentialTimestampValid(*_c,*tmp,**_i)) {
+ const Capability *tmp = &((*_i)->credential);
+ if (_m->_isCredentialTimestampValid(*_c,**_i)) {
++_i;
return tmp;
} else ++_i;
@@ -131,7 +112,7 @@ public:
private:
const Membership *_m;
const NetworkConfig *_c;
- const _RemoteCapability *const *_i;
+ const _RemoteCredential<Capability> *const *_i;
};
friend class CapabilityIterator;
@@ -150,8 +131,8 @@ public:
{
for(;;) {
if ((_i != &(_m->_remoteTags[ZT_MAX_NETWORK_TAGS]))&&((*_i)->id != ZT_MEMBERSHIP_CRED_ID_UNUSED)) {
- const Tag *tmp = &((*_i)->tag);
- if (_m->_isCredentialTimestampValid(*_c,*tmp,**_i)) {
+ const Tag *tmp = &((*_i)->credential);
+ if (_m->_isCredentialTimestampValid(*_c,**_i)) {
++_i;
return tmp;
} else ++_i;
@@ -164,7 +145,7 @@ public:
private:
const Membership *_m;
const NetworkConfig *_c;
- const _RemoteTag *const *_i;
+ const _RemoteCredential<Tag> *const *_i;
};
friend class TagIterator;
@@ -210,17 +191,30 @@ public:
{
if (nconf.isPublic())
return true;
- if ((_comRevocationThreshold)&&(_com.timestamp().first <= _comRevocationThreshold))
+ if (_com.timestamp().first <= _comRevocationThreshold)
return false;
return nconf.com.agreesWith(_com);
}
/**
- * @param nconf Network configuration
- * @param id Capablity ID
- * @return Pointer to capability or NULL if not found
+ * Check whether the peer represented by this Membership owns a given resource
+ *
+ * @tparam Type of resource: InetAddress or MAC
+ * @param nconf Our network config
+ * @param r Resource to check
+ * @return True if this peer has a certificate of ownership for the given resource
*/
- const Capability *getCapability(const NetworkConfig &nconf,const uint32_t id) const;
+ template<typename T>
+ inline bool hasCertificateOfOwnershipFor(const NetworkConfig &nconf,const T &r) const
+ {
+ for(unsigned int i=0;i<ZT_MAX_CERTIFICATES_OF_OWNERSHIP;++i) {
+ if (_remoteCoos[i]->id == ZT_MEMBERSHIP_CRED_ID_UNUSED)
+ break;
+ if ((_isCredentialTimestampValid(nconf,*_remoteCoos[i]))&&(_remoteCoos[i]->credential.owns(r)))
+ return true;
+ }
+ return false;
+ }
/**
* @param nconf Network configuration
@@ -249,26 +243,32 @@ public:
*/
AddCredentialResult addCredential(const RuntimeEnvironment *RR,const NetworkConfig &nconf,const Revocation &rev);
+ /**
+ * Validate and add a credential if signature is okay and it's otherwise good
+ */
+ AddCredentialResult addCredential(const RuntimeEnvironment *RR,const NetworkConfig &nconf,const CertificateOfOwnership &coo);
+
private:
- _RemoteTag *_newTag(const uint64_t id);
- _RemoteCapability *_newCapability(const uint64_t id);
+ _RemoteCredential<Tag> *_newTag(const uint64_t id);
+ _RemoteCredential<Capability> *_newCapability(const uint64_t id);
+ _RemoteCredential<CertificateOfOwnership> *_newCoo(const uint64_t id);
bool _revokeCom(const Revocation &rev);
bool _revokeCap(const Revocation &rev,const uint64_t now);
bool _revokeTag(const Revocation &rev,const uint64_t now);
+ bool _revokeCoo(const Revocation &rev,const uint64_t now);
- template<typename C,typename CS>
- inline bool _isCredentialTimestampValid(const NetworkConfig &nconf,const C &cred,const CS &state) const
+ template<typename C>
+ inline bool _isCredentialTimestampValid(const NetworkConfig &nconf,const _RemoteCredential<C> &remoteCredential) const
{
- const uint64_t ts = cred.timestamp();
- return ( (((ts >= nconf.timestamp) ? (ts - nconf.timestamp) : (nconf.timestamp - ts)) <= nconf.credentialTimeMaxDelta) && (ts > state.revocationThreshold) );
+ if (!remoteCredential.lastReceived)
+ return false;
+ const uint64_t ts = remoteCredential.credential.timestamp();
+ return ( (((ts >= nconf.timestamp) ? (ts - nconf.timestamp) : (nconf.timestamp - ts)) <= nconf.credentialTimeMaxDelta) && (ts > remoteCredential.revocationThreshold) );
}
// Last time we pushed MULTICAST_LIKE(s)
uint64_t _lastUpdatedMulticast;
- // Last time we checked if credential push was needed
- uint64_t _lastPushAttempt;
-
// Last time we pushed our COM to this peer
uint64_t _lastPushedCom;
@@ -278,17 +278,20 @@ private:
// Remote member's latest network COM
CertificateOfMembership _com;
- // Sorted (in ascending order of ID) arrays of pointers to remote tags and capabilities
- _RemoteTag *_remoteTags[ZT_MAX_NETWORK_TAGS];
- _RemoteCapability *_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES];
+ // Sorted (in ascending order of ID) arrays of pointers to remote credentials
+ _RemoteCredential<Tag> *_remoteTags[ZT_MAX_NETWORK_TAGS];
+ _RemoteCredential<Capability> *_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES];
+ _RemoteCredential<CertificateOfOwnership> *_remoteCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP];
- // This is the RAM allocated for remote tags and capabilities from which the sorted arrays are populated
- _RemoteTag _tagMem[ZT_MAX_NETWORK_TAGS];
- _RemoteCapability _capMem[ZT_MAX_NETWORK_CAPABILITIES];
+ // This is the RAM allocated for remote credential cache objects
+ _RemoteCredential<Tag> _tagMem[ZT_MAX_NETWORK_TAGS];
+ _RemoteCredential<Capability> _capMem[ZT_MAX_NETWORK_CAPABILITIES];
+ _RemoteCredential<CertificateOfOwnership> _cooMem[ZT_MAX_CERTIFICATES_OF_OWNERSHIP];
// Local credential push state tracking
_LocalCredentialPushState _localTags[ZT_MAX_NETWORK_TAGS];
_LocalCredentialPushState _localCaps[ZT_MAX_NETWORK_CAPABILITIES];
+ _LocalCredentialPushState _localCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP];
};
} // namespace ZeroTier