|
|
|
|
@ -28,61 +28,65 @@
|
|
|
|
|
|
|
|
|
|
namespace ZeroTier { |
|
|
|
|
|
|
|
|
|
bool Membership::sendCredentialsIfNeeded(const RuntimeEnvironment *RR,const uint64_t now,const Address &peerAddress,const NetworkConfig &nconf,const Capability *cap) |
|
|
|
|
void Membership::sendCredentialsIfNeeded(const RuntimeEnvironment *RR,const uint64_t now,const Address &peerAddress,const NetworkConfig &nconf,const Capability *cap) |
|
|
|
|
{ |
|
|
|
|
if ((now - _lastPushAttempt) < 1000ULL) |
|
|
|
|
return false; |
|
|
|
|
return; |
|
|
|
|
_lastPushAttempt = now; |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
Buffer<ZT_PROTO_MAX_PACKET_LENGTH> capsAndTags; |
|
|
|
|
bool unfinished; |
|
|
|
|
do { |
|
|
|
|
unfinished = false; |
|
|
|
|
Buffer<ZT_PROTO_MAX_PACKET_LENGTH> capsAndTags; |
|
|
|
|
|
|
|
|
|
unsigned int appendedCaps = 0; |
|
|
|
|
if (cap) { |
|
|
|
|
capsAndTags.addSize(2); |
|
|
|
|
std::map<uint32_t,CState>::iterator cs(_caps.find(cap->id())); |
|
|
|
|
if ((cs != _caps.end())&&((now - cs->second.lastPushed) >= ZT_CREDENTIAL_PUSH_EVERY)) { |
|
|
|
|
cap->serialize(capsAndTags); |
|
|
|
|
cs->second.lastPushed = now; |
|
|
|
|
++appendedCaps; |
|
|
|
|
unsigned int appendedCaps = 0; |
|
|
|
|
if (cap) { |
|
|
|
|
capsAndTags.addSize(2); |
|
|
|
|
std::map<uint32_t,CState>::iterator cs(_caps.find(cap->id())); |
|
|
|
|
if ((cs != _caps.end())&&((now - cs->second.lastPushed) >= ZT_CREDENTIAL_PUSH_EVERY)) { |
|
|
|
|
cap->serialize(capsAndTags); |
|
|
|
|
cs->second.lastPushed = now; |
|
|
|
|
++appendedCaps; |
|
|
|
|
} |
|
|
|
|
capsAndTags.setAt<uint16_t>(0,(uint16_t)appendedCaps); |
|
|
|
|
} else { |
|
|
|
|
capsAndTags.append((uint16_t)0); |
|
|
|
|
} |
|
|
|
|
capsAndTags.setAt<uint16_t>(0,(uint16_t)appendedCaps); |
|
|
|
|
} else { |
|
|
|
|
capsAndTags.append((uint16_t)0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
unsigned int appendedTags = 0; |
|
|
|
|
const unsigned int tagCountPos = capsAndTags.size(); |
|
|
|
|
capsAndTags.addSize(2); |
|
|
|
|
for(unsigned int i=0;i<nconf.tagCount;++i) { |
|
|
|
|
TState *const ts = _tags.get(nconf.tags[i].id()); |
|
|
|
|
if ((now - ts->lastPushed) >= ZT_CREDENTIAL_PUSH_EVERY) { |
|
|
|
|
if ((capsAndTags.size() + sizeof(Tag)) > (ZT_PROTO_MAX_PACKET_LENGTH - sizeof(CertificateOfMembership))) |
|
|
|
|
break; |
|
|
|
|
nconf.tags[i].serialize(capsAndTags); |
|
|
|
|
ts->lastPushed = now; |
|
|
|
|
++appendedTags; |
|
|
|
|
unsigned int appendedTags = 0; |
|
|
|
|
const unsigned int tagCountPos = capsAndTags.size(); |
|
|
|
|
capsAndTags.addSize(2); |
|
|
|
|
for(unsigned int i=0;i<nconf.tagCount;++i) { |
|
|
|
|
TState *const ts = _tags.get(nconf.tags[i].id()); |
|
|
|
|
if ((now - ts->lastPushed) >= ZT_CREDENTIAL_PUSH_EVERY) { |
|
|
|
|
if ((capsAndTags.size() + sizeof(Tag)) >= (ZT_PROTO_MAX_PACKET_LENGTH - sizeof(CertificateOfMembership))) { |
|
|
|
|
unfinished = true; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
nconf.tags[i].serialize(capsAndTags); |
|
|
|
|
ts->lastPushed = now; |
|
|
|
|
++appendedTags; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
capsAndTags.setAt<uint16_t>(tagCountPos,(uint16_t)appendedTags); |
|
|
|
|
capsAndTags.setAt<uint16_t>(tagCountPos,(uint16_t)appendedTags); |
|
|
|
|
|
|
|
|
|
const bool needCom = ((nconf.isPrivate())&&(nconf.com)&&((now - _lastPushedCom) >= ZT_CREDENTIAL_PUSH_EVERY)); |
|
|
|
|
if ( (needCom) || (appendedCaps) || (appendedTags) ) { |
|
|
|
|
Packet outp(peerAddress,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS); |
|
|
|
|
if (needCom) { |
|
|
|
|
nconf.com.serialize(outp); |
|
|
|
|
_lastPushedCom = now; |
|
|
|
|
const bool needCom = ((nconf.isPrivate())&&(nconf.com)&&((now - _lastPushedCom) >= ZT_CREDENTIAL_PUSH_EVERY)); |
|
|
|
|
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.compress(); |
|
|
|
|
RR->sw->send(outp,true); |
|
|
|
|
} |
|
|
|
|
outp.append((uint8_t)0x00); |
|
|
|
|
outp.append(capsAndTags.data(),capsAndTags.size()); |
|
|
|
|
outp.compress(); |
|
|
|
|
RR->sw->send(outp,true); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
} while (unfinished); // if there are many tags, etc., we can send more than one
|
|
|
|
|
} catch ( ... ) { |
|
|
|
|
TRACE("unable to send credentials due to unexpected exception"); |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int Membership::addCredential(const RuntimeEnvironment *RR,const CertificateOfMembership &com) |
|
|
|
|
|