diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2014-10-06 13:16:16 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2014-10-06 13:16:16 -0700 |
commit | 87f1b1b1e35de52d993779bc9de9f988e91147c4 (patch) | |
tree | 41101b62e429088d81bf557a53e9020e1d646166 | |
parent | ab22feba9a6e6c7e2eb3bc8ba3ecc48f19f878a0 (diff) | |
download | infinitytier-87f1b1b1e35de52d993779bc9de9f988e91147c4.tar.gz infinitytier-87f1b1b1e35de52d993779bc9de9f988e91147c4.zip |
Bug fix in new multicast frame handler, handling of old "P5" multicast frames in new way.
-rw-r--r-- | node/IncomingPacket.cpp | 86 | ||||
-rw-r--r-- | node/Packet.hpp | 37 | ||||
-rw-r--r-- | node/Peer.cpp | 2 |
3 files changed, 104 insertions, 21 deletions
diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 521ca731..4f449d3e 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -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); } diff --git a/node/Packet.hpp b/node/Packet.hpp index 68a4439e..9dff4405 100644 --- a/node/Packet.hpp +++ b/node/Packet.hpp @@ -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) diff --git a/node/Peer.cpp b/node/Peer.cpp index 8012c5ff..540a83a1 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -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; } |