Browse Source

Bump version to 1.0.0, add legacy support code to Multicaster to not send new frame to known-to-be-old peers.

Adam Ierymenko 10 years ago
parent
commit
ab22feba9a
4 changed files with 73 additions and 17 deletions
  1. 2 2
      node/IncomingPacket.cpp
  2. 57 10
      node/Multicaster.cpp
  3. 11 2
      node/Multicaster.hpp
  4. 3 3
      version.h

+ 2 - 2
node/IncomingPacket.cpp

@@ -925,7 +925,7 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,const Shar
 			outp.append(nwid);
 			outp.append(nwid);
 			mg.mac().appendTo(outp);
 			mg.mac().appendTo(outp);
 			outp.append((uint32_t)mg.adi());
 			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);
 				outp.armor(peer->key(),true);
 				_fromSock->send(_remoteAddress,outp.data(),outp.size());
 				_fromSock->send(_remoteAddress,outp.data(),outp.size());
 			}
 			}
@@ -1003,7 +1003,7 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share
 					to.mac().appendTo(outp);
 					to.mac().appendTo(outp);
 					outp.append((uint32_t)to.adi());
 					outp.append((uint32_t)to.adi());
 					outp.append((unsigned char)0x01); // flag 0x01 = contains gather results
 					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);
 						outp.armor(peer->key(),true);
 						_fromSock->send(_remoteAddress,outp.data(),outp.size());
 						_fromSock->send(_remoteAddress,outp.data(),outp.size());
 					}
 					}

+ 57 - 10
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 char *p;
 	unsigned int n = 0,i,rptr,skipped = 0;
 	unsigned int n = 0,i,rptr,skipped = 0;
@@ -111,6 +111,24 @@ restart_member_scan:
 	return n;
 	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(
 void Multicaster::send(
 	const CertificateOfMembership *com,
 	const CertificateOfMembership *com,
 	unsigned int limit,
 	unsigned int limit,
@@ -148,12 +166,24 @@ void Multicaster::send(
 		unsigned int count = 0;
 		unsigned int count = 0;
 
 
 		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;
+			}
+
 			if (count++ >= limit)
 			if (count++ >= limit)
 				break;
 				break;
 			out.sendOnly(*(RR->sw),*ast);
 			out.sendOnly(*(RR->sw),*ast);
 		}
 		}
 
 
 		for(std::vector<MulticastGroupMember>::const_reverse_iterator m(gs.members.rbegin());m!=gs.members.rend();++m) {
 		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)
 			if (count++ >= limit)
 				break;
 				break;
 			if (std::find(alwaysSendTo.begin(),alwaysSendTo.end(),m->address) == alwaysSendTo.end())
 			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) {
 		if ((now - gs.lastExplicitGather) >= ZT_MULTICAST_EXPLICIT_GATHER_DELAY) {
 			gs.lastExplicitGather = now;
 			gs.lastExplicitGather = now;
-
 			SharedPtr<Peer> sn(RR->topology->getBestSupernode());
 			SharedPtr<Peer> sn(RR->topology->getBestSupernode());
 			if (sn) {
 			if (sn) {
 				Packet outp(sn->address(),RR->identity.address(),Packet::VERB_MULTICAST_GATHER);
 				Packet outp(sn->address(),RR->identity.address(),Packet::VERB_MULTICAST_GATHER);
@@ -176,13 +205,12 @@ void Multicaster::send(
 				outp.armor(sn->key(),true);
 				outp.armor(sn->key(),true);
 				sn->send(RR,outp.data(),outp.size(),now);
 				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;
 			gs.lastImplicitGather = now;
-		else gatherLimit = 0;
+		} else {
+			gatherLimit = 0;
+		}
 
 
 		gs.txQueue.push_back(OutboundMulticast());
 		gs.txQueue.push_back(OutboundMulticast());
 		OutboundMulticast &out = gs.txQueue.back();
 		OutboundMulticast &out = gs.txQueue.back();
@@ -200,10 +228,23 @@ void Multicaster::send(
 			data,
 			data,
 			len);
 			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);
 			out.sendAndLog(*(RR->sw),*ast);
+		}
 
 
 		for(std::vector<MulticastGroupMember>::const_reverse_iterator m(gs.members.rbegin());m!=gs.members.rend();++m) {
 		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())
 			if (std::find(alwaysSendTo.begin(),alwaysSendTo.end(),m->address) == alwaysSendTo.end())
 				out.sendAndLog(*(RR->sw),m->address);
 				out.sendAndLog(*(RR->sw),m->address);
 		}
 		}
@@ -211,7 +252,7 @@ void Multicaster::send(
 
 
 	// DEPRECATED / LEGACY / TODO:
 	// DEPRECATED / LEGACY / TODO:
 	// Currently we also always send a legacy P5_MULTICAST_FRAME packet to our
 	// 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)
 	// nodes. This code can go away (along with support for P5_MULTICAST_FRAME)
 	// once there are no more such nodes on the network.
 	// 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
 	// 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();) {
 	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);
 		tx->sendIfNew(*(RR->sw),member);
 		if (tx->atLimit())
 		if (tx->atLimit())
 			gs.txQueue.erase(tx++);
 			gs.txQueue.erase(tx++);

+ 11 - 2
node/Multicaster.hpp

@@ -109,7 +109,6 @@ public:
 	 *
 	 *
 	 * If zero is returned, the first two fields will still have been appended.
 	 * 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 queryingPeer Peer asking for gather (to skip in results)
 	 * @param nwid Network ID
 	 * @param nwid Network ID
 	 * @param mg Multicast group
 	 * @param mg Multicast group
@@ -118,7 +117,17 @@ public:
 	 * @return Number of addresses appended
 	 * @return Number of addresses appended
 	 * @throws std::out_of_range Buffer overflow writing to packet
 	 * @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
 	 * Send a multicast

+ 3 - 3
version.h

@@ -31,16 +31,16 @@
 /**
 /**
  * Major version
  * Major version
  */
  */
-#define ZEROTIER_ONE_VERSION_MAJOR 0
+#define ZEROTIER_ONE_VERSION_MAJOR 1
 
 
 /**
 /**
  * Minor version
  * Minor version
  */
  */
-#define ZEROTIER_ONE_VERSION_MINOR 9
+#define ZEROTIER_ONE_VERSION_MINOR 0
 
 
 /**
 /**
  * Revision
  * Revision
  */
  */
-#define ZEROTIER_ONE_VERSION_REVISION 3
+#define ZEROTIER_ONE_VERSION_REVISION 0
 
 
 #endif
 #endif