|
@@ -554,6 +554,8 @@ bool IncomingPacket::_doP5_MULTICAST_FRAME(const RuntimeEnvironment *RR,const Sh
|
|
|
const unsigned int signatureLen = at<uint16_t>(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_FRAME + frameLen);
|
|
|
|
|
|
{
|
|
|
+ if (origin == RR->identity.address())
|
|
|
+ return true;
|
|
|
Mutex::Lock _l(p5MulticastDedupBuffer_m);
|
|
|
if (!p5MulticastDedupBufferPtr) {
|
|
|
memset(p5MulticastDedupBuffer,0,sizeof(p5MulticastDedupBuffer));
|
|
@@ -566,6 +568,32 @@ bool IncomingPacket::_doP5_MULTICAST_FRAME(const RuntimeEnvironment *RR,const Sh
|
|
|
p5MulticastDedupBuffer[p5MulticastDedupBufferPtr++ % 1024] = guid;
|
|
|
}
|
|
|
|
|
|
+ SharedPtr<Network> network(RR->nc->network(nwid));
|
|
|
+ if (network) {
|
|
|
+ if ((flags & ZT_PROTO_VERB_P5_MULTICAST_FRAME_FLAGS_HAS_MEMBERSHIP_CERTIFICATE) != 0) {
|
|
|
+ CertificateOfMembership com;
|
|
|
+ com.deserialize(*this,ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_FRAME + frameLen + 2 + signatureLen);
|
|
|
+ if (com.hasRequiredFields())
|
|
|
+ network->addMembershipCertificate(com,false);
|
|
|
+ }
|
|
|
+ if (!network->isAllowed(origin)) {
|
|
|
+ SharedPtr<Peer> originPeer(RR->topology->getPeer(origin));
|
|
|
+ if (originPeer)
|
|
|
+ _sendErrorNeedCertificate(RR,originPeer,nwid);
|
|
|
+ } else if ((frameLen > 0)&&(frameLen <= 2800)) {
|
|
|
+ if (!dest.mac().isMulticast())
|
|
|
+ return true;
|
|
|
+ if ((!sourceMac)||(sourceMac.isMulticast())||(sourceMac == network->mac()))
|
|
|
+ return true;
|
|
|
+ if (sourceMac != MAC(origin,nwid)) {
|
|
|
+ if (network->permitsBridging(origin)) {
|
|
|
+ network->learnBridgeRoute(sourceMac,origin);
|
|
|
+ } else return true;
|
|
|
+ }
|
|
|
+ network->tapPut(sourceMac,dest.mac(),etherType,frame,frameLen);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
peer->receive(RR,_fromSock,_remoteAddress,hops(),packetId(),Packet::VERB_P5_MULTICAST_FRAME,0,Packet::VERB_NOP,Utils::now());
|
|
|
|
|
|
if (RR->topology->amSupernode()) {
|
|
@@ -577,12 +605,14 @@ bool IncomingPacket::_doP5_MULTICAST_FRAME(const RuntimeEnvironment *RR,const Sh
|
|
|
const unsigned int limit = 128; // use a fairly generous limit since we want legacy peers to always work until they go away
|
|
|
|
|
|
std::vector<Address> members(RR->mc->getMembers(nwid,dest,limit));
|
|
|
+ SharedPtr<Peer> lpp;
|
|
|
|
|
|
setAt(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_DEPTH,(uint16_t)0xffff);
|
|
|
setSource(RR->identity.address());
|
|
|
compress();
|
|
|
for(std::vector<Address>::iterator lp(members.begin());lp!=members.end();++lp) {
|
|
|
- SharedPtr<Peer> lpp(RR->topology->getPeer(*lp));
|
|
|
+ if (!senderIsLegacy)
|
|
|
+ lpp = RR->topology->getPeer(*lp);
|
|
|
if ( (*lp != origin) && (*lp != peer->address()) && ((senderIsLegacy) || (!lpp) || (lpp->remoteVersionMajor() < 1)) ) {
|
|
|
newInitializationVector();
|
|
|
setDestination(*lp);
|
|
@@ -605,35 +635,6 @@ bool IncomingPacket::_doP5_MULTICAST_FRAME(const RuntimeEnvironment *RR,const Sh
|
|
|
sn->send(RR,data(),size(),Utils::now());
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- 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());
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- if ((frameLen > 0)&&(frameLen <= 2800)) {
|
|
|
- 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) {
|
|
|
TRACE("dropped P5_MULTICAST_FRAME from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what());
|
|
|
} catch ( ... ) {
|