Procházet zdrojové kódy

Fixes to legacy peer support.

Adam Ierymenko před 11 roky
rodič
revize
c2aac69a9f
3 změnil soubory, kde provedl 45 přidání a 46 odebrání
  1. 34 32
      node/IncomingPacket.cpp
  2. 8 9
      node/Multicaster.cpp
  3. 3 5
      node/Multicaster.hpp

+ 34 - 32
node/IncomingPacket.cpp

@@ -604,52 +604,54 @@ bool IncomingPacket::_doP5_MULTICAST_FRAME(const RuntimeEnvironment *RR,const Sh
 		peer->receive(RR,_fromSock,_remoteAddress,hops(),packetId(),Packet::VERB_P5_MULTICAST_FRAME,0,Packet::VERB_NOP,Utils::now());
 		peer->receive(RR,_fromSock,_remoteAddress,hops(),packetId(),Packet::VERB_P5_MULTICAST_FRAME,0,Packet::VERB_NOP,Utils::now());
 
 
 		if (RR->topology->amSupernode()) {
 		if (RR->topology->amSupernode()) {
-			std::vector<Address> legacyPeers(RR->mc->getLegacySubscribers(nwid,dest));
+			// To support legacy peers, old fashioned "P5" multicasts are propagated manually by supernodes.
+			// If the sending peer is >=1.0.0, they only go to legacy peers. Otherwise they go to all
+			// peers.
+
+			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));
 
 
 			setAt(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_DEPTH,(uint16_t)0xffff);
 			setAt(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_DEPTH,(uint16_t)0xffff);
 			setSource(RR->identity.address());
 			setSource(RR->identity.address());
 			compress();
 			compress();
-
-			unsigned int count = 0;
-			for(std::vector<Address>::iterator lp(legacyPeers.begin());lp!=legacyPeers.end();++lp) {
-				if ((*lp != origin)&&(*lp != source())) {
+			for(std::vector<Address>::iterator lp(members.begin());lp!=members.end();++lp) {
+				SharedPtr<Peer> lpp(RR->topology->getPeer(*lp));
+				if ( (*lp != origin) && (*lp != peer->address()) && ((senderIsLegacy) || (!lpp) || (lpp->remoteVersionMajor() < 1)) ) {
 					newInitializationVector();
 					newInitializationVector();
 					setDestination(*lp);
 					setDestination(*lp);
 					RR->sw->send(*this,true);
 					RR->sw->send(*this,true);
-					if (++count >= 128) // harded-coded sanity limit for these legacy nodes
-						break;
 				}
 				}
 			}
 			}
+		}
 
 
-			return true;
-		} else {
-			SharedPtr<Network> network(RR->nc->network(nwid)); // will be NULL if not a member
-			if (network) {
-				if ((flags & ZT_PROTO_VERB_P5_MULTICAST_FRAME_FLAGS_HAS_MEMBERSHIP_CERTIFICATE)) {
-					CertificateOfMembership com;
-					com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME + frameLen + 2 + signatureLen);
-					if (com.hasRequiredFields())
-						network->addMembershipCertificate(com,false);
-				}
+		SharedPtr<Network> network(RR->nc->network(nwid));
+		if (network) {
+			if ((flags & ZT_PROTO_VERB_P5_MULTICAST_FRAME_FLAGS_HAS_MEMBERSHIP_CERTIFICATE)) {
+				CertificateOfMembership com;
+				com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME + frameLen + 2 + signatureLen);
+				if (com.hasRequiredFields())
+					network->addMembershipCertificate(com,false);
+			}
 
 
-				if (!network->isAllowed(origin)) {
-					_sendErrorNeedCertificate(RR,peer,network->id());
+			if (!network->isAllowed(origin)) {
+				_sendErrorNeedCertificate(RR,peer,network->id());
+				return true;
+			}
+
+			if ((frameLen > 0)&&(frameLen <= 2800)) {
+				if (!dest.mac().isMulticast())
 					return true;
 					return true;
+				if ((!sourceMac)||(sourceMac.isMulticast())||(sourceMac == network->mac()))
+					return true;
+				if (sourceMac != MAC(origin,network->id())) {
+					if (network->permitsBridging(origin)) {
+						network->learnBridgeRoute(sourceMac,origin);
+					} else return true;
 				}
 				}
 
 
-				if (frameLen) {
-					if (!dest.mac().isMulticast())
-						return true;
-					if ((!sourceMac)||(sourceMac.isMulticast())||(sourceMac == network->mac()))
-						return true;
-					if (sourceMac != MAC(origin,network->id())) {
-						if (network->permitsBridging(origin)) {
-							network->learnBridgeRoute(sourceMac,origin);
-						} else return true;
-					}
-
-					network->tapPut(sourceMac,dest.mac(),etherType,frame,frameLen);
-				}
+				network->tapPut(sourceMac,dest.mac(),etherType,frame,frameLen);
 			}
 			}
 		}
 		}
 	} catch (std::exception &ex) {
 	} catch (std::exception &ex) {

+ 8 - 9
node/Multicaster.cpp

@@ -118,21 +118,18 @@ restart_member_scan:
 	return added;
 	return added;
 }
 }
 
 
-std::vector<Address> Multicaster::getLegacySubscribers(uint64_t nwid,const MulticastGroup &mg) const
+std::vector<Address> Multicaster::getMembers(uint64_t nwid,const MulticastGroup &mg,unsigned int limit) const
 {
 {
 	std::vector<Address> ls;
 	std::vector<Address> ls;
 	Mutex::Lock _l(_groups_m);
 	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)));
 	std::map< std::pair<uint64_t,MulticastGroup>,MulticastGroupStatus >::const_iterator gs(_groups.find(std::pair<uint64_t,MulticastGroup>(nwid,mg)));
 	if (gs == _groups.end())
 	if (gs == _groups.end())
 		return ls;
 		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);
+	for(std::vector<MulticastGroupMember>::const_reverse_iterator m(gs->second.members.rbegin());m!=gs->second.members.rend();++m) {
+		ls.push_back(m->address);
+		if (ls.size() >= limit)
+			break;
 	}
 	}
-
 	return ls;
 	return ls;
 }
 }
 
 
@@ -281,7 +278,9 @@ void Multicaster::send(
 			outp.append((unsigned char)0);
 			outp.append((unsigned char)0);
 			RR->identity.address().appendTo(outp);
 			RR->identity.address().appendTo(outp);
 			outp.append((const void *)&rn,3); // random multicast ID
 			outp.append((const void *)&rn,3); // random multicast ID
-			src.appendTo(outp);
+			if (src)
+				src.appendTo(outp);
+			else MAC(RR->identity.address(),nwid).appendTo(outp);
 			mg.mac().appendTo(outp);
 			mg.mac().appendTo(outp);
 			outp.append((uint32_t)mg.adi());
 			outp.append((uint32_t)mg.adi());
 			outp.append((uint16_t)etherType);
 			outp.append((uint16_t)etherType);

+ 3 - 5
node/Multicaster.hpp

@@ -120,14 +120,12 @@ public:
 	unsigned int gather(const Address &queryingPeer,uint64_t nwid,const 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.
+	 * Get subscribers to a multicast group
 	 *
 	 *
 	 * @param nwid Network ID
 	 * @param nwid Network ID
 	 * @param mg Multicast group
 	 * @param mg Multicast group
 	 */
 	 */
-	std::vector<Address> getLegacySubscribers(uint64_t nwid,const MulticastGroup &mg) const;
+	std::vector<Address> getMembers(uint64_t nwid,const MulticastGroup &mg,unsigned int limit) const;
 
 
 	/**
 	/**
 	 * Send a multicast
 	 * Send a multicast
@@ -138,7 +136,7 @@ public:
 	 * @param nwid Network ID
 	 * @param nwid Network ID
 	 * @param alwaysSendTo Send to these peers first and even if not included in subscriber list
 	 * @param alwaysSendTo Send to these peers first and even if not included in subscriber list
 	 * @param mg Multicast group
 	 * @param mg Multicast group
-	 * @param src Source Ethernet MAC address
+	 * @param src Source Ethernet MAC address or NULL to skip in packet and compute from ZT address (non-bridged mode)
 	 * @param etherType Ethernet frame type
 	 * @param etherType Ethernet frame type
 	 * @param data Packet data
 	 * @param data Packet data
 	 * @param len Length of packet data
 	 * @param len Length of packet data