From ab22feba9a6e6c7e2eb3bc8ba3ecc48f19f878a0 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Sun, 5 Oct 2014 10:34:25 -0700 Subject: [PATCH] Bump version to 1.0.0, add legacy support code to Multicaster to not send new frame to known-to-be-old peers. --- node/IncomingPacket.cpp | 4 +-- node/Multicaster.cpp | 67 +++++++++++++++++++++++++++++++++++------ node/Multicaster.hpp | 13 ++++++-- version.h | 6 ++-- 4 files changed, 73 insertions(+), 17 deletions(-) diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 72ced7faf..521ca7310 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -925,7 +925,7 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,const Shar outp.append(nwid); mg.mac().appendTo(outp); outp.append((uint32_t)mg.adi()); - if (RR->mc->gather(RR,peer->address(),nwid,mg,outp,gatherLimit)) { + if (RR->mc->gather(peer->address(),nwid,mg,outp,gatherLimit)) { outp.armor(peer->key(),true); _fromSock->send(_remoteAddress,outp.data(),outp.size()); } @@ -1003,7 +1003,7 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share to.mac().appendTo(outp); outp.append((uint32_t)to.adi()); outp.append((unsigned char)0x01); // flag 0x01 = contains gather results - if (RR->mc->gather(RR,peer->address(),nwid,to,outp,gatherLimit)) { + if (RR->mc->gather(peer->address(),nwid,to,outp,gatherLimit)) { outp.armor(peer->key(),true); _fromSock->send(_remoteAddress,outp.data(),outp.size()); } diff --git a/node/Multicaster.cpp b/node/Multicaster.cpp index afe1c83fd..585ced061 100644 --- a/node/Multicaster.cpp +++ b/node/Multicaster.cpp @@ -50,7 +50,7 @@ Multicaster::~Multicaster() { } -unsigned int Multicaster::gather(const RuntimeEnvironment *RR,const Address &queryingPeer,uint64_t nwid,MulticastGroup &mg,Packet &appendTo,unsigned int limit) const +unsigned int Multicaster::gather(const Address &queryingPeer,uint64_t nwid,const MulticastGroup &mg,Packet &appendTo,unsigned int limit) const { unsigned char *p; unsigned int n = 0,i,rptr,skipped = 0; @@ -111,6 +111,24 @@ restart_member_scan: return n; } +std::vector
Multicaster::getLegacySubscribers(uint64_t nwid,const MulticastGroup &mg) const +{ + std::vector
ls; + Mutex::Lock _l(_groups_m); + + std::map< std::pair,MulticastGroupStatus >::const_iterator gs(_groups.find(std::pair(nwid,mg))); + if (gs == _groups.end()) + return ls; + + for(std::vector::const_iterator m(gs->second.members.begin());m!=gs->second.members.end();++m) { + SharedPtr p(RR->topology->getPeer(m->address)); + if ((p)&&(p->remoteVersionKnown())&&(p->remoteVersionMajor() < 1)) + ls.push_back(m->address); + } + + return ls; +} + void Multicaster::send( const CertificateOfMembership *com, unsigned int limit, @@ -148,12 +166,24 @@ void Multicaster::send( unsigned int count = 0; for(std::vector
::const_iterator ast(alwaysSendTo.begin());ast!=alwaysSendTo.end();++ast) { + { // TODO / LEGACY: don't send new multicast frame to old peers (if we know their version) + SharedPtr p(RR->topology->getPeer(*ast)); + if ((p)&&(p->remoteVersionKnown())&&(p->remoteVersionMajor() < 1)) + continue; + } + if (count++ >= limit) break; out.sendOnly(*(RR->sw),*ast); } for(std::vector::const_reverse_iterator m(gs.members.rbegin());m!=gs.members.rend();++m) { + { // TODO / LEGACY: don't send new multicast frame to old peers (if we know their version) + SharedPtr p(RR->topology->getPeer(m->address)); + if ((p)&&(p->remoteVersionKnown())&&(p->remoteVersionMajor() < 1)) + continue; + } + if (count++ >= limit) break; if (std::find(alwaysSendTo.begin(),alwaysSendTo.end(),m->address) == alwaysSendTo.end()) @@ -164,7 +194,6 @@ void Multicaster::send( if ((now - gs.lastExplicitGather) >= ZT_MULTICAST_EXPLICIT_GATHER_DELAY) { gs.lastExplicitGather = now; - SharedPtr sn(RR->topology->getBestSupernode()); if (sn) { Packet outp(sn->address(),RR->identity.address(),Packet::VERB_MULTICAST_GATHER); @@ -176,13 +205,12 @@ void Multicaster::send( outp.armor(sn->key(),true); sn->send(RR,outp.data(),outp.size(),now); } - - gatherLimit = 0; // once we've done this we don't need to do it implicitly - } - - if ((gatherLimit > 0)&&((now - gs.lastImplicitGather) > ZT_MULTICAST_IMPLICIT_GATHER_DELAY)) + gatherLimit = 0; // implicit not needed + } else if ((now - gs.lastImplicitGather) > ZT_MULTICAST_IMPLICIT_GATHER_DELAY) { gs.lastImplicitGather = now; - else gatherLimit = 0; + } else { + gatherLimit = 0; + } gs.txQueue.push_back(OutboundMulticast()); OutboundMulticast &out = gs.txQueue.back(); @@ -200,10 +228,23 @@ void Multicaster::send( data, len); - for(std::vector
::const_iterator ast(alwaysSendTo.begin());ast!=alwaysSendTo.end();++ast) + for(std::vector
::const_iterator ast(alwaysSendTo.begin());ast!=alwaysSendTo.end();++ast) { + { // TODO / LEGACY: don't send new multicast frame to old peers (if we know their version) + SharedPtr p(RR->topology->getPeer(*ast)); + if ((p)&&(p->remoteVersionKnown())&&(p->remoteVersionMajor() < 1)) + continue; + } + out.sendAndLog(*(RR->sw),*ast); + } for(std::vector::const_reverse_iterator m(gs.members.rbegin());m!=gs.members.rend();++m) { + { // TODO / LEGACY: don't send new multicast frame to old peers (if we know their version) + SharedPtr p(RR->topology->getPeer(m->address)); + if ((p)&&(p->remoteVersionKnown())&&(p->remoteVersionMajor() < 1)) + continue; + } + if (std::find(alwaysSendTo.begin(),alwaysSendTo.end(),m->address) == alwaysSendTo.end()) out.sendAndLog(*(RR->sw),m->address); } @@ -211,7 +252,7 @@ void Multicaster::send( // DEPRECATED / LEGACY / TODO: // Currently we also always send a legacy P5_MULTICAST_FRAME packet to our - // supernode. Our supernode then takes care of relaying it down to all <1.0.0 + // supernode. Our supernode then takes care of relaying it down to <1.0.0 // nodes. This code can go away (along with support for P5_MULTICAST_FRAME) // once there are no more such nodes on the network. { @@ -337,6 +378,12 @@ void Multicaster::_add(uint64_t now,uint64_t nwid,MulticastGroupStatus &gs,const // Try to send to any outgoing multicasts that are waiting for more recipients for(std::list::iterator tx(gs.txQueue.begin());tx!=gs.txQueue.end();) { + { // TODO / LEGACY: don't send new multicast frame to old peers (if we know their version) + SharedPtr p(RR->topology->getPeer(member)); + if ((p)&&(p->remoteVersionKnown())&&(p->remoteVersionMajor() < 1)) + continue; + } + tx->sendIfNew(*(RR->sw),member); if (tx->atLimit()) gs.txQueue.erase(tx++); diff --git a/node/Multicaster.hpp b/node/Multicaster.hpp index 454f5c936..fd9c32d48 100644 --- a/node/Multicaster.hpp +++ b/node/Multicaster.hpp @@ -109,7 +109,6 @@ public: * * If zero is returned, the first two fields will still have been appended. * - * @param RR Runtime environment * @param queryingPeer Peer asking for gather (to skip in results) * @param nwid Network ID * @param mg Multicast group @@ -118,7 +117,17 @@ public: * @return Number of addresses appended * @throws std::out_of_range Buffer overflow writing to packet */ - unsigned int gather(const RuntimeEnvironment *RR,const Address &queryingPeer,uint64_t nwid,MulticastGroup &mg,Packet &appendTo,unsigned int limit) const; + unsigned int gather(const Address &queryingPeer,uint64_t nwid,const MulticastGroup &mg,Packet &appendTo,unsigned int limit) const; + + /** + * Get known peers with versions <1.0.0 and that are not supernodes + * + * This is legacy peer compatibility code and will be removed later. + * + * @param nwid Network ID + * @param mg Multicast group + */ + std::vector
getLegacySubscribers(uint64_t nwid,const MulticastGroup &mg) const; /** * Send a multicast diff --git a/version.h b/version.h index e0b822b03..7eff09663 100644 --- a/version.h +++ b/version.h @@ -31,16 +31,16 @@ /** * Major version */ -#define ZEROTIER_ONE_VERSION_MAJOR 0 +#define ZEROTIER_ONE_VERSION_MAJOR 1 /** * Minor version */ -#define ZEROTIER_ONE_VERSION_MINOR 9 +#define ZEROTIER_ONE_VERSION_MINOR 0 /** * Revision */ -#define ZEROTIER_ONE_VERSION_REVISION 3 +#define ZEROTIER_ONE_VERSION_REVISION 0 #endif