2016-08-04 16:51:15 +00:00
/*
* ZeroTier One - Network Virtualization Everywhere
* Copyright ( C ) 2011 - 2016 ZeroTier , Inc . https : //www.zerotier.com/
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2016-09-23 23:08:38 +00:00
# include <algorithm>
2016-08-04 16:51:15 +00:00
# include "Membership.hpp"
# include "RuntimeEnvironment.hpp"
# include "Peer.hpp"
# include "Topology.hpp"
# include "Switch.hpp"
# include "Packet.hpp"
# include "Node.hpp"
2016-09-09 02:48:05 +00:00
# define ZT_CREDENTIAL_PUSH_EVERY (ZT_NETWORK_AUTOCONF_DELAY / 3)
2016-08-04 16:51:15 +00:00
namespace ZeroTier {
2016-09-23 23:08:38 +00:00
Membership : : Membership ( ) :
_lastUpdatedMulticast ( 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 ] ) ;
2017-02-23 19:47:36 +00:00
for ( unsigned int i = 0 ; i < ZT_MAX_CERTIFICATES_OF_OWNERSHIP ; + + i ) _remoteCoos [ i ] = & ( _cooMem [ i ] ) ;
2016-09-23 23:08:38 +00:00
}
2017-03-28 00:03:17 +00:00
void Membership : : pushCredentials ( const RuntimeEnvironment * RR , void * tPtr , const uint64_t now , const Address & peerAddress , const NetworkConfig & nconf , int localCapabilityIndex , const bool force )
2016-08-04 16:51:15 +00:00
{
2017-02-07 01:10:20 +00:00
bool sendCom = ( ( nconf . com ) & & ( ( ( now - _lastPushedCom ) > = ZT_CREDENTIAL_PUSH_EVERY ) | | ( force ) ) ) ;
2016-08-04 16:51:15 +00:00
2017-02-07 01:10:20 +00:00
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 ;
2016-09-23 23:08:38 +00:00
2017-02-07 01:20:22 +00:00
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 ] ) ;
}
}
2017-02-23 19:47:36 +00:00
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 ] ) ;
}
}
2017-02-07 01:10:20 +00:00
unsigned int tagPtr = 0 ;
2017-02-23 19:47:36 +00:00
unsigned int cooPtr = 0 ;
while ( ( tagPtr < sendTagCount ) | | ( cooPtr < sendCooCount ) | | ( sendCom ) | | ( sendCap ) ) {
2017-02-07 01:10:20 +00:00
Packet outp ( peerAddress , RR - > identity . address ( ) , Packet : : VERB_NETWORK_CREDENTIALS ) ;
2016-09-23 23:08:38 +00:00
2017-02-07 01:10:20 +00:00
if ( sendCom ) {
sendCom = false ;
nconf . com . serialize ( outp ) ;
_lastPushedCom = now ;
}
outp . append ( ( uint8_t ) 0x00 ) ;
2016-08-04 16:51:15 +00:00
2017-02-07 01:10:20 +00:00
if ( sendCap ) {
outp . append ( ( uint16_t ) 1 ) ;
sendCap - > serialize ( outp ) ;
sendCap = ( const Capability * ) 0 ;
} else outp . append ( ( uint16_t ) 0 ) ;
2016-08-04 16:51:15 +00:00
2017-02-07 01:10:20 +00:00
const unsigned int tagCountAt = outp . size ( ) ;
outp . addSize ( 2 ) ;
unsigned int thisPacketTagCount = 0 ;
2017-02-23 19:47:36 +00:00
while ( ( tagPtr < sendTagCount ) & & ( ( outp . size ( ) + sizeof ( Tag ) + 16 ) < ZT_PROTO_MAX_PACKET_LENGTH ) ) {
2017-02-07 22:06:40 +00:00
sendTags [ tagPtr + + ] - > serialize ( outp ) ;
+ + thisPacketTagCount ;
2017-02-07 01:10:20 +00:00
}
outp . setAt ( tagCountAt , ( uint16_t ) thisPacketTagCount ) ;
// No revocations, these propagate differently
outp . append ( ( uint16_t ) 0 ) ;
2017-02-23 19:47:36 +00:00
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 ) ;
2017-02-07 01:10:20 +00:00
outp . compress ( ) ;
2017-03-28 00:03:17 +00:00
RR - > sw - > send ( tPtr , outp , true ) ;
2016-08-04 16:51:15 +00:00
}
}
2016-09-23 23:08:38 +00:00
const Tag * Membership : : getTag ( const NetworkConfig & nconf , const uint32_t id ) const
{
2017-02-23 19:47:36 +00:00
const _RemoteCredential < Tag > * const * t = std : : lower_bound ( & ( _remoteTags [ 0 ] ) , & ( _remoteTags [ ZT_MAX_NETWORK_TAGS ] ) , ( uint64_t ) id , _RemoteCredentialComp < Tag > ( ) ) ;
2017-02-23 20:34:17 +00:00
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 ) ;
2016-09-23 23:08:38 +00:00
}
2017-03-28 00:03:17 +00:00
Membership : : AddCredentialResult Membership : : addCredential ( const RuntimeEnvironment * RR , void * tPtr , const NetworkConfig & nconf , const CertificateOfMembership & com )
2016-09-23 23:08:38 +00:00
{
const uint64_t newts = com . timestamp ( ) . first ;
if ( newts < = _comRevocationThreshold ) {
TRACE ( " addCredential(CertificateOfMembership) for %s on %.16llx REJECTED (revoked) " , com . issuedTo ( ) . toString ( ) . c_str ( ) , com . networkId ( ) ) ;
return ADD_REJECTED ;
2016-08-24 22:45:37 +00:00
}
2016-09-07 22:15:52 +00:00
2016-09-23 23:08:38 +00:00
const uint64_t oldts = _com . timestamp ( ) . first ;
if ( newts < oldts ) {
TRACE ( " addCredential(CertificateOfMembership) for %s on %.16llx REJECTED (older than current) " , com . issuedTo ( ) . toString ( ) . c_str ( ) , com . networkId ( ) ) ;
return ADD_REJECTED ;
}
if ( ( newts = = oldts ) & & ( _com = = com ) ) {
TRACE ( " addCredential(CertificateOfMembership) for %s on %.16llx ACCEPTED (redundant) " , com . issuedTo ( ) . toString ( ) . c_str ( ) , com . networkId ( ) ) ;
return ADD_ACCEPTED_REDUNDANT ;
}
2016-09-07 22:15:52 +00:00
2017-03-28 00:03:17 +00:00
switch ( com . verify ( RR , tPtr ) ) {
2016-09-23 23:08:38 +00:00
default :
TRACE ( " addCredential(CertificateOfMembership) for %s on %.16llx REJECTED (invalid signature or object) " , com . issuedTo ( ) . toString ( ) . c_str ( ) , com . networkId ( ) ) ;
return ADD_REJECTED ;
case 0 :
2016-09-09 02:48:05 +00:00
TRACE ( " addCredential(CertificateOfMembership) for %s on %.16llx ACCEPTED (new) " , com . issuedTo ( ) . toString ( ) . c_str ( ) , com . networkId ( ) ) ;
2016-08-24 22:45:37 +00:00
_com = com ;
2016-09-23 23:08:38 +00:00
return ADD_ACCEPTED_NEW ;
case 1 :
return ADD_DEFERRED_FOR_WHOIS ;
2016-08-24 22:45:37 +00:00
}
2016-08-04 16:51:15 +00:00
}
2017-03-28 00:03:17 +00:00
Membership : : AddCredentialResult Membership : : addCredential ( const RuntimeEnvironment * RR , void * tPtr , const NetworkConfig & nconf , const Tag & tag )
2016-08-04 16:51:15 +00:00
{
2017-02-23 19:47:36 +00:00
_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 ;
2016-09-23 23:08:38 +00:00
if ( have ) {
2017-02-23 20:34:17 +00:00
if ( ( ! _isCredentialTimestampValid ( nconf , * have ) ) | | ( have - > credential . timestamp ( ) > tag . timestamp ( ) ) ) {
2016-09-23 23:08:38 +00:00
TRACE ( " addCredential(Tag) for %s on %.16llx REJECTED (revoked or too old) " , tag . issuedTo ( ) . toString ( ) . c_str ( ) , tag . networkId ( ) ) ;
return ADD_REJECTED ;
}
2017-02-23 19:47:36 +00:00
if ( have - > credential = = tag ) {
2016-09-23 23:08:38 +00:00
TRACE ( " addCredential(Tag) for %s on %.16llx ACCEPTED (redundant) " , tag . issuedTo ( ) . toString ( ) . c_str ( ) , tag . networkId ( ) ) ;
return ADD_ACCEPTED_REDUNDANT ;
}
2016-08-24 22:45:37 +00:00
}
2016-09-23 23:08:38 +00:00
2017-03-28 00:03:17 +00:00
switch ( tag . verify ( RR , tPtr ) ) {
2016-09-23 23:08:38 +00:00
default :
TRACE ( " addCredential(Tag) for %s on %.16llx REJECTED (invalid) " , tag . issuedTo ( ) . toString ( ) . c_str ( ) , tag . networkId ( ) ) ;
return ADD_REJECTED ;
case 0 :
TRACE ( " addCredential(Tag) for %s on %.16llx ACCEPTED (new) " , tag . issuedTo ( ) . toString ( ) . c_str ( ) , tag . networkId ( ) ) ;
2016-09-26 23:17:02 +00:00
if ( ! have ) have = _newTag ( tag . id ( ) ) ;
have - > lastReceived = RR - > node - > now ( ) ;
2017-02-23 19:47:36 +00:00
have - > credential = tag ;
2016-09-23 23:08:38 +00:00
return ADD_ACCEPTED_NEW ;
case 1 :
return ADD_DEFERRED_FOR_WHOIS ;
2016-08-04 16:51:15 +00:00
}
}
2017-03-28 00:03:17 +00:00
Membership : : AddCredentialResult Membership : : addCredential ( const RuntimeEnvironment * RR , void * tPtr , const NetworkConfig & nconf , const Capability & cap )
2016-08-04 16:51:15 +00:00
{
2017-02-23 19:47:36 +00:00
_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 ;
2016-09-23 23:08:38 +00:00
if ( have ) {
2017-02-23 20:34:17 +00:00
if ( ( ! _isCredentialTimestampValid ( nconf , * have ) ) | | ( have - > credential . timestamp ( ) > cap . timestamp ( ) ) ) {
2017-02-07 00:38:48 +00:00
TRACE ( " addCredential(Capability) for %s on %.16llx REJECTED (revoked or too old) " , cap . issuedTo ( ) . toString ( ) . c_str ( ) , cap . networkId ( ) ) ;
2016-09-23 23:08:38 +00:00
return ADD_REJECTED ;
}
2017-02-23 19:47:36 +00:00
if ( have - > credential = = cap ) {
2017-02-07 00:38:48 +00:00
TRACE ( " addCredential(Capability) for %s on %.16llx ACCEPTED (redundant) " , cap . issuedTo ( ) . toString ( ) . c_str ( ) , cap . networkId ( ) ) ;
2016-09-23 23:08:38 +00:00
return ADD_ACCEPTED_REDUNDANT ;
}
2016-08-24 22:45:37 +00:00
}
2016-09-23 23:08:38 +00:00
2017-03-28 00:03:17 +00:00
switch ( cap . verify ( RR , tPtr ) ) {
2016-09-23 23:08:38 +00:00
default :
2017-02-07 00:38:48 +00:00
TRACE ( " addCredential(Capability) for %s on %.16llx REJECTED (invalid) " , cap . issuedTo ( ) . toString ( ) . c_str ( ) , cap . networkId ( ) ) ;
2016-09-23 23:08:38 +00:00
return ADD_REJECTED ;
case 0 :
2017-02-07 00:38:48 +00:00
TRACE ( " addCredential(Capability) for %s on %.16llx ACCEPTED (new) " , cap . issuedTo ( ) . toString ( ) . c_str ( ) , cap . networkId ( ) ) ;
2016-09-26 23:17:02 +00:00
if ( ! have ) have = _newCapability ( cap . id ( ) ) ;
have - > lastReceived = RR - > node - > now ( ) ;
2017-02-23 19:47:36 +00:00
have - > credential = cap ;
2016-09-23 23:08:38 +00:00
return ADD_ACCEPTED_NEW ;
case 1 :
return ADD_DEFERRED_FOR_WHOIS ;
2016-08-04 16:51:15 +00:00
}
}
2017-03-28 00:03:17 +00:00
Membership : : AddCredentialResult Membership : : addCredential ( const RuntimeEnvironment * RR , void * tPtr , const NetworkConfig & nconf , const Revocation & rev )
2016-09-26 23:17:02 +00:00
{
2017-03-28 00:03:17 +00:00
switch ( rev . verify ( RR , tPtr ) ) {
2016-09-26 23:17:02 +00:00
default :
return ADD_REJECTED ;
case 0 : {
const uint64_t now = RR - > node - > now ( ) ;
switch ( rev . type ( ) ) {
default :
2017-03-13 13:53:23 +00:00
return ADD_REJECTED ;
2016-09-26 23:17:02 +00:00
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 ) ;
2017-02-23 19:47:36 +00:00
case Revocation : : CREDENTIAL_TYPE_COO :
return ( _revokeCoo ( rev , now ) ? ADD_ACCEPTED_NEW : ADD_ACCEPTED_REDUNDANT ) ;
2016-09-26 23:17:02 +00:00
}
}
case 1 :
return ADD_DEFERRED_FOR_WHOIS ;
}
}
2017-03-28 00:03:17 +00:00
Membership : : AddCredentialResult Membership : : addCredential ( const RuntimeEnvironment * RR , void * tPtr , const NetworkConfig & nconf , const CertificateOfOwnership & coo )
2017-02-23 19:47:36 +00:00
{
_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 ) {
2017-02-23 20:34:17 +00:00
if ( ( ! _isCredentialTimestampValid ( nconf , * have ) ) | | ( have - > credential . timestamp ( ) > coo . timestamp ( ) ) ) {
2017-02-23 20:26:11 +00:00
TRACE ( " addCredential(CertificateOfOwnership) for %s on %.16llx REJECTED (revoked or too old) " , coo . issuedTo ( ) . toString ( ) . c_str ( ) , coo . networkId ( ) ) ;
2017-02-23 19:47:36 +00:00
return ADD_REJECTED ;
}
if ( have - > credential = = coo ) {
2017-02-23 20:26:11 +00:00
TRACE ( " addCredential(CertificateOfOwnership) for %s on %.16llx ACCEPTED (redundant) " , coo . issuedTo ( ) . toString ( ) . c_str ( ) , coo . networkId ( ) ) ;
2017-02-23 19:47:36 +00:00
return ADD_ACCEPTED_REDUNDANT ;
}
}
2017-03-28 00:03:17 +00:00
switch ( coo . verify ( RR , tPtr ) ) {
2017-02-23 19:47:36 +00:00
default :
2017-02-23 20:26:11 +00:00
TRACE ( " addCredential(CertificateOfOwnership) for %s on %.16llx REJECTED (invalid) " , coo . issuedTo ( ) . toString ( ) . c_str ( ) , coo . networkId ( ) ) ;
2017-02-23 19:47:36 +00:00
return ADD_REJECTED ;
case 0 :
2017-02-23 20:26:11 +00:00
TRACE ( " addCredential(CertificateOfOwnership) for %s on %.16llx ACCEPTED (new) " , coo . issuedTo ( ) . toString ( ) . c_str ( ) , coo . networkId ( ) ) ;
2017-02-23 19:47:36 +00:00
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 )
2016-09-26 23:17:02 +00:00
{
2017-02-23 19:47:36 +00:00
_RemoteCredential < Tag > * t = NULL ;
2016-09-26 23:17:02 +00:00
uint64_t minlr = 0xffffffffffffffffULL ;
for ( unsigned int i = 0 ; i < ZT_MAX_NETWORK_TAGS ; + + i ) {
if ( _remoteTags [ i ] - > id = = ZT_MEMBERSHIP_CRED_ID_UNUSED ) {
t = _remoteTags [ i ] ;
break ;
} else if ( _remoteTags [ i ] - > lastReceived < = minlr ) {
t = _remoteTags [ i ] ;
minlr = _remoteTags [ i ] - > lastReceived ;
}
}
2017-02-23 19:47:36 +00:00
if ( t ) {
t - > id = id ;
t - > lastReceived = 0 ;
t - > revocationThreshold = 0 ;
t - > credential = Tag ( ) ;
}
2017-02-23 20:34:17 +00:00
std : : sort ( & ( _remoteTags [ 0 ] ) , & ( _remoteTags [ ZT_MAX_NETWORK_TAGS ] ) , _RemoteCredentialComp < Tag > ( ) ) ;
2016-09-26 23:17:02 +00:00
return t ;
}
2017-02-23 19:47:36 +00:00
Membership : : _RemoteCredential < Capability > * Membership : : _newCapability ( const uint64_t id )
2016-09-26 23:17:02 +00:00
{
2017-02-23 19:47:36 +00:00
_RemoteCredential < Capability > * c = NULL ;
2016-09-26 23:17:02 +00:00
uint64_t minlr = 0xffffffffffffffffULL ;
for ( unsigned int i = 0 ; i < ZT_MAX_NETWORK_CAPABILITIES ; + + i ) {
if ( _remoteCaps [ i ] - > id = = ZT_MEMBERSHIP_CRED_ID_UNUSED ) {
c = _remoteCaps [ i ] ;
break ;
} else if ( _remoteCaps [ i ] - > lastReceived < = minlr ) {
c = _remoteCaps [ i ] ;
minlr = _remoteCaps [ i ] - > lastReceived ;
}
}
2016-11-03 19:10:50 +00:00
if ( c ) {
c - > id = id ;
c - > lastReceived = 0 ;
c - > revocationThreshold = 0 ;
2017-02-23 19:47:36 +00:00
c - > credential = Capability ( ) ;
}
2017-02-23 20:34:17 +00:00
std : : sort ( & ( _remoteCaps [ 0 ] ) , & ( _remoteCaps [ ZT_MAX_NETWORK_CAPABILITIES ] ) , _RemoteCredentialComp < Capability > ( ) ) ;
2017-02-23 19:47:36 +00:00
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 ( ) ;
2016-11-03 19:10:50 +00:00
}
2017-02-23 20:34:17 +00:00
std : : sort ( & ( _remoteCoos [ 0 ] ) , & ( _remoteCoos [ ZT_MAX_CERTIFICATES_OF_OWNERSHIP ] ) , _RemoteCredentialComp < CertificateOfOwnership > ( ) ) ;
2016-09-26 23:17:02 +00:00
return c ;
}
bool Membership : : _revokeCom ( const Revocation & rev )
{
if ( rev . threshold ( ) > _comRevocationThreshold ) {
_comRevocationThreshold = rev . threshold ( ) ;
return true ;
}
return false ;
}
bool Membership : : _revokeCap ( const Revocation & rev , const uint64_t now )
{
2017-02-23 19:47:36 +00:00
_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 ;
2016-09-26 23:17:02 +00:00
if ( ! have ) have = _newCapability ( rev . credentialId ( ) ) ;
if ( rev . threshold ( ) > have - > revocationThreshold ) {
have - > lastReceived = now ;
have - > revocationThreshold = rev . threshold ( ) ;
return true ;
}
return false ;
}
bool Membership : : _revokeTag ( const Revocation & rev , const uint64_t now )
{
2017-02-23 19:47:36 +00:00
_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 ;
2016-09-26 23:17:02 +00:00
if ( ! have ) have = _newTag ( rev . credentialId ( ) ) ;
if ( rev . threshold ( ) > have - > revocationThreshold ) {
have - > lastReceived = now ;
have - > revocationThreshold = rev . threshold ( ) ;
return true ;
}
return false ;
}
2017-02-23 19:47:36 +00:00
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 ;
}
2016-08-04 16:51:15 +00:00
} // namespace ZeroTier