diff --git a/node/CertificateOfMembership.cpp b/node/CertificateOfMembership.cpp index 82e7bc811..dd92455eb 100644 --- a/node/CertificateOfMembership.cpp +++ b/node/CertificateOfMembership.cpp @@ -86,6 +86,9 @@ void CertificateOfMembership::fromString(const char *s) _signedBy.zero(); memset(_signature.data,0,_signature.size()); + if (!*s) + return; + unsigned int colonAt = 0; while ((s[colonAt])&&(s[colonAt] != ':')) ++colonAt; diff --git a/node/CertificateOfMembership.hpp b/node/CertificateOfMembership.hpp index 7f3dcbb3e..76e1cfbc6 100644 --- a/node/CertificateOfMembership.hpp +++ b/node/CertificateOfMembership.hpp @@ -265,6 +265,7 @@ public: * * Invalid strings will result in invalid or undefined certificate * contents. These will subsequently fail validation and comparison. + * Empty strings will result in an empty certificate. * * @param s String to deserialize */ diff --git a/node/Network.cpp b/node/Network.cpp index acc2588de..43cd83a20 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -221,12 +221,14 @@ void Network::_CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned void Network::_pushMembershipCertificate(const Address &peer,bool force,uint64_t now) { - uint64_t timestampMaxDelta = _config->com().timestampMaxDelta(); - if (!timestampMaxDelta) + uint64_t pushTimeout = _config->com().timestampMaxDelta() / 2; + if (!pushTimeout) return; // still waiting on my own cert + if (pushTimeout > 1000) + pushTimeout -= 1000; uint64_t &lastPushed = _lastPushedMembershipCertificate[peer]; - if ((force)||((now - lastPushed) > (timestampMaxDelta / 2))) { + if ((force)||((now - lastPushed) > pushTimeout)) { lastPushed = now; Packet outp(peer,_r->identity.address(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE); diff --git a/node/Network.hpp b/node/Network.hpp index 1b74a0487..ecee77c13 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -203,7 +203,7 @@ public: inline void pushMembershipCertificate(const Address &peer,bool force,uint64_t now) { Mutex::Lock _l(_lock); - if ((_config)&&(!_config->isOpen())) + if ((_config)&&(!_config->isOpen())&&(_config->com())) _pushMembershipCertificate(peer,force,now); } @@ -214,15 +214,17 @@ public: * len is reached or a null address is encountered. * * @param peers Packed array of 5-byte big-endian addresses - * @param len Length of peers[] in total, MUST be a multiple of 5 + * @param len Length of peers[] in total (bytes, not addresses) * @param force If true, push even if we've already done so within required time frame * @param now Current time */ inline void pushMembershipCertificate(const void *peers,unsigned int len,bool force,uint64_t now) { Mutex::Lock _l(_lock); - if ((_config)&&(!_config->isOpen())) { + if ((_config)&&(!_config->isOpen())&&(_config->com())) { for(unsigned int i=0;i len) + break; Address a((char *)peers + i,ZT_ADDRESS_LENGTH); if (a) _pushMembershipCertificate(a,force,now); diff --git a/node/NetworkConfig.cpp b/node/NetworkConfig.cpp index 977b9aa32..f384ccf95 100644 --- a/node/NetworkConfig.cpp +++ b/node/NetworkConfig.cpp @@ -128,6 +128,8 @@ void NetworkConfig::_fromDictionary(const Dictionary &d) if (params.size() >= 3) _multicastRates[MulticastGroup(i->first)] = MulticastRate(Utils::hexStrToUInt(params[0].c_str()),Utils::hexStrToUInt(params[1].c_str()),Utils::hexStrToUInt(params[2].c_str())); } + + _com.fromString(d.get(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATE_OF_MEMBERSHIP,std::string())); } } // namespace ZeroTier