summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--node/IncomingPacket.cpp4
-rw-r--r--node/Multicaster.cpp67
-rw-r--r--node/Multicaster.hpp13
-rw-r--r--version.h6
4 files changed, 73 insertions, 17 deletions
diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp
index 72ced7fa..521ca731 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 afe1c83f..585ced06 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<Address> Multicaster::getLegacySubscribers(uint64_t nwid,const MulticastGroup &mg) const
+{
+ std::vector<Address> ls;
+ Mutex::Lock _l(_groups_m);
+
+ std::map< std::pair<uint64_t,MulticastGroup>,MulticastGroupStatus >::const_iterator gs(_groups.find(std::pair<uint64_t,MulticastGroup>(nwid,mg)));
+ if (gs == _groups.end())
+ return ls;
+
+ for(std::vector<MulticastGroupMember>::const_iterator m(gs->second.members.begin());m!=gs->second.members.end();++m) {
+ SharedPtr<Peer> 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<Address>::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<Peer> 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<MulticastGroupMember>::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<Peer> 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<Peer> 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<Address>::const_iterator ast(alwaysSendTo.begin());ast!=alwaysSendTo.end();++ast)
+ for(std::vector<Address>::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<Peer> p(RR->topology->getPeer(*ast));
+ if ((p)&&(p->remoteVersionKnown())&&(p->remoteVersionMajor() < 1))
+ continue;
+ }
+
out.sendAndLog(*(RR->sw),*ast);
+ }
for(std::vector<MulticastGroupMember>::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<Peer> 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<OutboundMulticast>::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<Peer> 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 454f5c93..fd9c32d4 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<Address> getLegacySubscribers(uint64_t nwid,const MulticastGroup &mg) const;
/**
* Send a multicast
diff --git a/version.h b/version.h
index e0b822b0..7eff0966 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