Browse Source

Stop persisting last announcement time since Multicaster is volatile. Also some more legacy multicast fixes.

Adam Ierymenko 11 years ago
parent
commit
0d017c043f
3 changed files with 28 additions and 17 deletions
  1. 20 8
      node/IncomingPacket.cpp
  2. 4 4
      node/Peer.cpp
  3. 4 5
      node/Peer.hpp

+ 20 - 8
node/IncomingPacket.cpp

@@ -563,13 +563,9 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr<P
 
 bool IncomingPacket::_doP5_MULTICAST_FRAME(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
 {
-	/* This handles the old deprecated "P5" multicast frame, and will
-	 * go away once there are no longer nodes using this on the network.
-	 * We handle these old nodes by accepting these as simple multicasts
-	 * and if we are a supernode performing individual relaying of them
-	 * to all older nodes that expect them. This won't be too expensive
-	 * though since there aren't likely to be many older nodes left after
-	 * we do a software update. */
+	/* This code is a bit of a hack to handle compatibility with <1.0.0 peers
+	 * and will go away once there's no longer any left (to speak of) on the
+	 * network. */
 
 	// Quick and dirty dedup -- this is all condemned code in any case
 	static uint64_t p5MulticastDedupBuffer[1024];
@@ -577,6 +573,7 @@ bool IncomingPacket::_doP5_MULTICAST_FRAME(const RuntimeEnvironment *RR,const Sh
 	static Mutex p5MulticastDedupBuffer_m;
 
 	try {
+		unsigned int depth = at<uint16_t>(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_DEPTH);
 		Address origin(Address(field(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_ORIGIN,ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_ORIGIN),ZT_ADDRESS_LENGTH));
 		const unsigned int flags = (*this)[ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_FLAGS];
 		const uint64_t nwid = at<uint64_t>(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_NETWORK_ID);
@@ -608,8 +605,8 @@ bool IncomingPacket::_doP5_MULTICAST_FRAME(const RuntimeEnvironment *RR,const Sh
 			// If the sending peer is >=1.0.0, they only go to legacy peers. Otherwise they go to all
 			// peers.
 
+			const bool senderIsLegacy = ((peer->remoteVersionMajor() < 1)||(depth == 0xbeef));
 			const unsigned int limit = 128; // use a fairly generous limit since we want legacy peers to always work until they go away
-			const bool senderIsLegacy = (peer->remoteVersionMajor() < 1);
 
 			std::vector<Address> members(RR->mc->getMembers(nwid,dest,limit));
 
@@ -624,6 +621,21 @@ bool IncomingPacket::_doP5_MULTICAST_FRAME(const RuntimeEnvironment *RR,const Sh
 					RR->sw->send(*this,true);
 				}
 			}
+		} else if (!RR->topology->isSupernode(peer->address())) {
+			// If we received this from a non-supernode, this must be a legacy peer. In that
+			// case relay it up to our supernode so it can get broadcast since there are now
+			// going to be too few legacy peers to form a mesh for the old style of propagation.
+
+			SharedPtr<Peer> sn(RR->topology->getBestSupernode());
+			if (sn) {
+				setAt(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_DEPTH,(uint16_t)0xbeef); // magic number means "relayed on behalf of legacy peer"
+				newInitializationVector();
+				setDestination(sn->address());
+				setSource(RR->identity.address());
+				compress();
+				armor(sn->key(),true);
+				sn->send(RR,data(),size(),Utils::now());
+			}
 		}
 
 		SharedPtr<Network> network(RR->nc->network(nwid));

+ 4 - 4
node/Peer.cpp

@@ -42,7 +42,7 @@ Peer::Peer() :
 	_lastReceive(0),
 	_lastUnicastFrame(0),
 	_lastMulticastFrame(0),
-	_lastAnnouncedTo(0),
+	__lastAnnouncedTo(0),
 	_vMajor(0),
 	_vMinor(0),
 	_vRevision(0),
@@ -55,7 +55,7 @@ Peer::Peer(const Identity &myIdentity,const Identity &peerIdentity)
 	_lastReceive(0),
 	_lastUnicastFrame(0),
 	_lastMulticastFrame(0),
-	_lastAnnouncedTo(0),
+	__lastAnnouncedTo(0),
 	_vMajor(0),
 	_vMinor(0),
 	_vRevision(0),
@@ -118,8 +118,8 @@ void Peer::receive(
 		 * supernodes and network controllers. The other place this is done
 		 * is in rescanMulticastGroups() in Network, but that only sends something
 		 * if a network's multicast groups change. */
-		if ((now - _lastAnnouncedTo) >= ((ZT_MULTICAST_LIKE_EXPIRE / 2) - 1000)) {
-			_lastAnnouncedTo = now;
+		if ((now - __lastAnnouncedTo) >= ((ZT_MULTICAST_LIKE_EXPIRE / 2) - 1000)) {
+			__lastAnnouncedTo = now;
 
 			Packet outp(_id.address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE);
 			std::vector< SharedPtr<Network> > networks(RR->nc->networks());

+ 4 - 5
node/Peer.hpp

@@ -50,7 +50,7 @@
 #include "NonCopyable.hpp"
 #include "Mutex.hpp"
 
-#define ZT_PEER_SERIALIZATION_VERSION 12
+#define ZT_PEER_SERIALIZATION_VERSION 13
 
 namespace ZeroTier {
 
@@ -247,7 +247,7 @@ public:
 	/**
 	 * @return Time we last announced state TO this peer, such as multicast LIKEs
 	 */
-	inline uint64_t lastAnnouncedTo() const throw() { return _lastAnnouncedTo; }
+	inline uint64_t lastAnnouncedTo() const throw() { return __lastAnnouncedTo; }
 
 	/**
 	 * @param now Current time
@@ -416,7 +416,6 @@ public:
 		b.append(_lastReceive);
 		b.append(_lastUnicastFrame);
 		b.append(_lastMulticastFrame);
-		b.append(_lastAnnouncedTo);
 		b.append((uint16_t)_vProto);
 		b.append((uint16_t)_vMajor);
 		b.append((uint16_t)_vMinor);
@@ -442,7 +441,7 @@ public:
 		_lastReceive = b.template at<uint64_t>(p); p += sizeof(uint64_t);
 		_lastUnicastFrame = b.template at<uint64_t>(p); p += sizeof(uint64_t);
 		_lastMulticastFrame = b.template at<uint64_t>(p); p += sizeof(uint64_t);
-		_lastAnnouncedTo = b.template at<uint64_t>(p); p += sizeof(uint64_t);
+		__lastAnnouncedTo = 0;
 		_vProto = b.template at<uint16_t>(p); p += sizeof(uint16_t);
 		_vMajor = b.template at<uint16_t>(p); p += sizeof(uint16_t);
 		_vMinor = b.template at<uint16_t>(p); p += sizeof(uint16_t);
@@ -470,7 +469,7 @@ private:
 	volatile uint64_t _lastReceive; // direct or indirect
 	volatile uint64_t _lastUnicastFrame;
 	volatile uint64_t _lastMulticastFrame;
-	volatile uint64_t _lastAnnouncedTo;
+	volatile uint64_t __lastAnnouncedTo; // not persisted -- shouldn't be unless Multicaster state is also persisted
 	volatile uint16_t _vProto;
 	volatile uint16_t _vMajor;
 	volatile uint16_t _vMinor;