mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-06 20:43:44 +02:00
Fixes to legacy peer support.
This commit is contained in:
parent
a9c6913f12
commit
c2aac69a9f
3 changed files with 45 additions and 46 deletions
|
@ -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();
|
||||||
|
for(std::vector<Address>::iterator lp(members.begin());lp!=members.end();++lp) {
|
||||||
unsigned int count = 0;
|
SharedPtr<Peer> lpp(RR->topology->getPeer(*lp));
|
||||||
for(std::vector<Address>::iterator lp(legacyPeers.begin());lp!=legacyPeers.end();++lp) {
|
if ( (*lp != origin) && (*lp != peer->address()) && ((senderIsLegacy) || (!lpp) || (lpp->remoteVersionMajor() < 1)) ) {
|
||||||
if ((*lp != origin)&&(*lp != source())) {
|
|
||||||
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;
|
SharedPtr<Network> network(RR->nc->network(nwid));
|
||||||
} else {
|
if (network) {
|
||||||
SharedPtr<Network> network(RR->nc->network(nwid)); // will be NULL if not a member
|
if ((flags & ZT_PROTO_VERB_P5_MULTICAST_FRAME_FLAGS_HAS_MEMBERSHIP_CERTIFICATE)) {
|
||||||
if (network) {
|
CertificateOfMembership com;
|
||||||
if ((flags & ZT_PROTO_VERB_P5_MULTICAST_FRAME_FLAGS_HAS_MEMBERSHIP_CERTIFICATE)) {
|
com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME + frameLen + 2 + signatureLen);
|
||||||
CertificateOfMembership com;
|
if (com.hasRequiredFields())
|
||||||
com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME + frameLen + 2 + signatureLen);
|
network->addMembershipCertificate(com,false);
|
||||||
if (com.hasRequiredFields())
|
}
|
||||||
network->addMembershipCertificate(com,false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!network->isAllowed(origin)) {
|
if (!network->isAllowed(origin)) {
|
||||||
_sendErrorNeedCertificate(RR,peer,network->id());
|
_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) {
|
network->tapPut(sourceMac,dest.mac(),etherType,frame,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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (std::exception &ex) {
|
} catch (std::exception &ex) {
|
||||||
|
|
|
@ -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_reverse_iterator m(gs->second.members.rbegin());m!=gs->second.members.rend();++m) {
|
||||||
for(std::vector<MulticastGroupMember>::const_iterator m(gs->second.members.begin());m!=gs->second.members.end();++m) {
|
ls.push_back(m->address);
|
||||||
SharedPtr<Peer> p(RR->topology->getPeer(m->address));
|
if (ls.size() >= limit)
|
||||||
if ((p)&&(p->remoteVersionKnown())&&(p->remoteVersionMajor() < 1))
|
break;
|
||||||
ls.push_back(m->address);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -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
|
* Get subscribers to a multicast group
|
||||||
*
|
|
||||||
* This is legacy peer compatibility code and will be removed later.
|
|
||||||
*
|
*
|
||||||
* @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
|
||||||
|
|
Loading…
Add table
Reference in a new issue