Bug fix in new multicast frame handler, handling of old "P5" multicast frames in new way.

This commit is contained in:
Adam Ierymenko 2014-10-06 13:16:16 -07:00
parent ab22feba9a
commit 87f1b1b1e3
3 changed files with 104 additions and 21 deletions

View File

@ -330,7 +330,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p
case Packet::VERB_MULTICAST_FRAME: {
unsigned int flags = (*this)[ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_FLAGS];
if ((flags & 0x01) != 0) {
if ((flags & 0x01) != 0) { // frame includes implicit gather results
uint64_t nwid = at<uint64_t>(ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_NETWORK_ID);
MulticastGroup mg(MAC(field(ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_MAC,6),6),at<uint32_t>(ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_ADI));
_parseGatherResults(RR,peer,nwid,mg,ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_GATHER_RESULTS);
@ -548,6 +548,88 @@ bool IncomingPacket::_doP5_MULTICAST_FRAME(const RuntimeEnvironment *RR,const Sh
// though since there aren't likely to be many older nodes left after
// we do a software update.
// Quick and dirty -- this is all condemned code in any case
static uint64_t p5MulticastDedupBuffer[1024];
static unsigned long p5MulticastDedupBufferPtr = 0;
static Mutex p5MulticastDedupBuffer_m;
try {
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);
const uint64_t guid = at<uint64_t>(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_GUID);
const MAC sourceMac(field(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_SOURCE_MAC,ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_SOURCE_MAC),ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_SOURCE_MAC);
const MulticastGroup dest(MAC(field(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_DEST_MAC,ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_DEST_MAC),ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_DEST_MAC),at<uint32_t>(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_DEST_ADI));
const unsigned int etherType = at<uint16_t>(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_ETHERTYPE);
const unsigned int frameLen = at<uint16_t>(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_FRAME_LEN);
const unsigned char *const frame = field(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_FRAME,frameLen);
const unsigned int signatureLen = at<uint16_t>(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_FRAME + frameLen);
{
Mutex::Lock _l(p5MulticastDedupBuffer_m);
if (!p5MulticastDedupBufferPtr) {
memset(p5MulticastDedupBuffer,0,sizeof(p5MulticastDedupBuffer));
} else {
for(unsigned int i=0;i<1024;++i) {
if (p5MulticastDedupBuffer[i] == guid)
return true;
}
}
p5MulticastDedupBuffer[p5MulticastDedupBufferPtr++ % 1024] = guid;
}
peer->receive(RR,_fromSock,_remoteAddress,hops(),packetId(),Packet::VERB_P5_MULTICAST_FRAME,0,Packet::VERB_NOP,Utils::now());
if (RR->topology->amSupernode()) {
std::vector<Address> legacyPeers(RR->mc->getLegacySubscribers(nwid,dest));
setAt(ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_DEPTH,(uint16_t)0xffff);
for(std::vector<Address>::iterator lp(legacyPeers.begin());lp!=legacyPeers.end();++lp) {
if ((*lp != origin)&&(*lp != source())) {
newInitializationVector();
setDestination(*lp);
setSource(RR->identity.address());
compress();
RR->sw->send(*this,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);
}
if (!network->isAllowed(origin)) {
_sendErrorNeedCertificate(RR,peer,network->id());
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);
}
}
}
} 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 ( ... ) {
TRACE("dropped P5_MULTICAST_FRAME from %s(%s): unexpected exception: (unknown)",source().toString().c_str(),_remoteAddress.toString().c_str());
}
#if 0 // old code preserved below
try {
Address origin(Address(field(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ORIGIN,ZT_PROTO_VERB_MULTICAST_FRAME_LEN_ORIGIN),ZT_ADDRESS_LENGTH));
@ -953,7 +1035,7 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share
unsigned int comLen = 0;
if ((flags & 0x01) != 0) {
CertificateOfMembership com;
comLen = com.deserialize(*this,ZT_PROTO_VERB_EXT_FRAME_IDX_COM);
comLen = com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME_IDX_COM);
if (com.hasRequiredFields())
network->addMembershipCertificate(com,false);
}

View File

@ -224,38 +224,38 @@
// P5_MULTICAST_FRAME is deprecated
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_DEPTH (ZT_PACKET_IDX_PAYLOAD)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_PROPAGATION_DEPTH 2
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_FIFO (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_DEPTH + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_DEPTH)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_FIFO (ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_DEPTH + ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_PROPAGATION_DEPTH)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_PROPAGATION_FIFO 320
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_BLOOM (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_FIFO + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_FIFO)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_BLOOM (ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_FIFO + ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_PROPAGATION_FIFO)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_PROPAGATION_BLOOM 1024
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_FLAGS (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_BLOOM + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_BLOOM)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_FLAGS (ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_BLOOM + ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_PROPAGATION_BLOOM)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_FLAGS 1
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX__START_OF_SIGNED_PORTION (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FLAGS)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_NETWORK_ID (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FLAGS + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_FLAGS)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX__START_OF_SIGNED_PORTION (ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_FLAGS)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_NETWORK_ID (ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_FLAGS + ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_FLAGS)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_NETWORK_ID 8
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_BLOOM_NONCE (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_NETWORK_ID + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_NETWORK_ID)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_BLOOM_NONCE (ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_NETWORK_ID + ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_NETWORK_ID)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_PROPAGATION_BLOOM_NONCE 2
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_PREFIX_BITS (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_BLOOM_NONCE + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_BLOOM_NONCE)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_PREFIX_BITS (ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_BLOOM_NONCE + ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_PROPAGATION_BLOOM_NONCE)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_PROPAGATION_PREFIX_BITS 1
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_PREFIX (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_PREFIX_BITS + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_PREFIX_BITS)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_PREFIX (ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_PREFIX_BITS + ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_PROPAGATION_PREFIX_BITS)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_PROPAGATION_PREFIX 1
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_ORIGIN (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_PREFIX + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_PREFIX)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_ORIGIN (ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_PROPAGATION_PREFIX + ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_PROPAGATION_PREFIX)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_ORIGIN 5
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_ORIGIN_MCID (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ORIGIN + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_ORIGIN)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_ORIGIN_MCID (ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_ORIGIN + ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_ORIGIN)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_ORIGIN_MCID 3
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_GUID (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ORIGIN)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_GUID (ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_ORIGIN)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_GUID 8
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_SOURCE_MAC (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ORIGIN_MCID + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_ORIGIN_MCID)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_SOURCE_MAC (ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_ORIGIN_MCID + ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_ORIGIN_MCID)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_SOURCE_MAC 6
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_DEST_MAC (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SOURCE_MAC + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_SOURCE_MAC)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_DEST_MAC (ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_SOURCE_MAC + ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_SOURCE_MAC)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_DEST_MAC 6
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_DEST_ADI (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_MAC + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_DEST_MAC)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_DEST_ADI (ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_DEST_MAC + ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_DEST_MAC)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_DEST_ADI 4
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_ETHERTYPE (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_ADI + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_DEST_ADI)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_ETHERTYPE (ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_DEST_ADI + ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_DEST_ADI)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_ETHERTYPE 2
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_FRAME_LEN (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ETHERTYPE + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_ETHERTYPE)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_FRAME_LEN (ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_ETHERTYPE + ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_ETHERTYPE)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_FRAME_LEN 2
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_FRAME (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME_LEN + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_FRAME_LEN)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_FRAME (ZT_PROTO_VERB_P5_MULTICAST_FRAME_IDX_FRAME_LEN + ZT_PROTO_VERB_P5_MULTICAST_FRAME_LEN_FRAME_LEN)
#define ZT_PROTO_VERB_P5_MULTICAST_FRAME_FLAGS_HAS_MEMBERSHIP_CERTIFICATE 0x01
#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID (ZT_PACKET_IDX_PAYLOAD)
@ -272,7 +272,8 @@
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_NETWORK_ID (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ORIGIN + 5)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FLAGS (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_NETWORK_ID + 8)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_GATHER_LIMIT (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FLAGS + 1)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_ADI (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_GATHER_LIMIT + 4)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_COM (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_GATHER_LIMIT + 4)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_ADI ZT_PROTO_VERB_MULTICAST_FRAME_IDX_COM
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_MAC (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_ADI + 4)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SOURCE_MAC (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_MAC + 6)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ETHERTYPE (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SOURCE_MAC + 6)

View File

@ -149,7 +149,7 @@ void Peer::receive(
if ((verb == Packet::VERB_FRAME)||(verb == Packet::VERB_EXT_FRAME))
_lastUnicastFrame = now;
else if (verb == Packet::VERB_MULTICAST_FRAME)
else if ((verb == Packet::VERB_P5_MULTICAST_FRAME)||(verb == Packet::VERB_MULTICAST_FRAME))
_lastMulticastFrame = now;
}