Push more than one packet for credentials if we happen to have a whole lot. Should not happen often but might if a member has tons of tags.

This commit is contained in:
Adam Ierymenko 2016-08-26 14:43:16 -07:00
parent 297b1b4258
commit a3c7627acf
2 changed files with 47 additions and 44 deletions

View File

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

View File

@ -127,9 +127,8 @@ public:
* @param peerAddress Address of member peer * @param peerAddress Address of member peer
* @param nconf My network config * @param nconf My network config
* @param cap Capability to send or 0 if none * @param cap Capability to send or 0 if none
* @return True if we pushed something
*/ */
bool sendCredentialsIfNeeded(const RuntimeEnvironment *RR,const uint64_t now,const Address &peerAddress,const NetworkConfig &nconf,const Capability *cap); void sendCredentialsIfNeeded(const RuntimeEnvironment *RR,const uint64_t now,const Address &peerAddress,const NetworkConfig &nconf,const Capability *cap);
/** /**
* @param nconf Our network config * @param nconf Our network config