diff options
Diffstat (limited to 'node/PacketDecoder.cpp')
-rw-r--r-- | node/PacketDecoder.cpp | 140 |
1 files changed, 78 insertions, 62 deletions
diff --git a/node/PacketDecoder.cpp b/node/PacketDecoder.cpp index 1e62664e..369eda7b 100644 --- a/node/PacketDecoder.cpp +++ b/node/PacketDecoder.cpp @@ -530,7 +530,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared return false; } - // These fields change + // These fields in the packet are changed by each forwarder unsigned int depth = at<uint16_t>(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_DEPTH); unsigned char *const fifo = field(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_FIFO,ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_FIFO); unsigned char *const bloom = field(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_BLOOM,ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_BLOOM); @@ -568,6 +568,9 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared */ SharedPtr<Network> network(_r->nc->network(nwid)); + SharedPtr<NetworkConfig> nconf; + if (network) + nconf = network->config2(); /* Grab, verify, and learn certificate of network membership if any -- provided we are * a member of this network. Note: we can do this before verification of the actual @@ -679,50 +682,30 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared // be the case unless we're a supernode), check to see if we should // inject the packet. This also gives us an opportunity to check things // like multicast bandwidth constraints. - if (network) { - SharedPtr<NetworkConfig> nconf(network->config2()); - if (nconf) { - // Learn real maxDepth from netconf - maxDepth = std::min((unsigned int)ZT_MULTICAST_GLOBAL_MAX_DEPTH,nconf->multicastDepth()); - if (!maxDepth) - maxDepth = ZT_MULTICAST_GLOBAL_MAX_DEPTH; - - if (!network->isAllowed(origin)) { - // Papers, please... - Packet outp(source(),_r->identity.address(),Packet::VERB_ERROR); - outp.append((unsigned char)Packet::VERB_MULTICAST_FRAME); - outp.append(packetId()); - outp.append((unsigned char)Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE); - outp.append(nwid); - outp.armor(peer->key(),true); - _fromSock->send(_remoteAddress,outp.data(),outp.size()); - TRACE("dropped MULTICAST_FRAME from %s(%s) into %.16llx: sender %s not allowed or we don't have a certificate",source().toString().c_str(),_remoteAddress.toString().c_str(),nwid,origin.toString().c_str()); - return true; - } - - if (MAC(origin,network->id()) != sourceMac) { - if (!nconf->permitsBridging(origin)) { -#ifdef ZT_TRACE_MULTICAST - Utils::snprintf(mct,sizeof(mct), - "%.16llx %.2u %.3u%s %c %s dropped: bridging not allowed", - guid, - prefix, - depth, - mctdepth, - (_r->topology->amSupernode() ? 'S' : '-'), - _r->identity.address().toString().c_str()); - _r->sm->sendUdp(ZT_DEFAULTS.multicastTraceWatcher,mct,strlen(mct)); -#endif - TRACE("dropped MULTICAST_FRAME from %s(%s) into %.16llx: source mac %s doesn't belong to %s, and bridging is not supported on network",source().toString().c_str(),_remoteAddress.toString().c_str(),nwid,sourceMac.toString().c_str(),origin.toString().c_str()); - return true; - } - network->learnBridgeRoute(sourceMac,origin); - } + if ((network)&&(nconf)) { + // Learn real maxDepth from netconf + maxDepth = std::min((unsigned int)ZT_MULTICAST_GLOBAL_MAX_DEPTH,nconf->multicastDepth()); + if (!maxDepth) + maxDepth = ZT_MULTICAST_GLOBAL_MAX_DEPTH; + + if (!network->isAllowed(origin)) { + // Papers, please... + Packet outp(source(),_r->identity.address(),Packet::VERB_ERROR); + outp.append((unsigned char)Packet::VERB_MULTICAST_FRAME); + outp.append(packetId()); + outp.append((unsigned char)Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE); + outp.append(nwid); + outp.armor(peer->key(),true); + _fromSock->send(_remoteAddress,outp.data(),outp.size()); + TRACE("dropped MULTICAST_FRAME from %s(%s) into %.16llx: sender %s not allowed or we don't have a certificate",source().toString().c_str(),_remoteAddress.toString().c_str(),nwid,origin.toString().c_str()); + return true; + } - if (!nconf->permitsEtherType(etherType)) { + if (MAC(origin,network->id()) != sourceMac) { + if (!nconf->permitsBridging(origin)) { #ifdef ZT_TRACE_MULTICAST Utils::snprintf(mct,sizeof(mct), - "%.16llx %.2u %.3u%s %c %s dropped: ethertype not allowed", + "%.16llx %.2u %.3u%s %c %s dropped: bridging not allowed", guid, prefix, depth, @@ -731,31 +714,48 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared _r->identity.address().toString().c_str()); _r->sm->sendUdp(ZT_DEFAULTS.multicastTraceWatcher,mct,strlen(mct)); #endif - TRACE("dropped MULTICAST_FRAME from %s(%s) into %.16llx: ethertype %u is not allowed",source().toString().c_str(),nwid,_remoteAddress.toString().c_str(),etherType); + TRACE("dropped MULTICAST_FRAME from %s(%s) into %.16llx: source mac %s doesn't belong to %s, and bridging is not supported on network",source().toString().c_str(),_remoteAddress.toString().c_str(),nwid,sourceMac.toString().c_str(),origin.toString().c_str()); return true; } + network->learnBridgeRoute(sourceMac,origin); + } - if (!network->updateAndCheckMulticastBalance(origin,dest,frameLen)) { - // Rate limits can only be checked by members of this network, but - // there should be enough of them that over-limit multicasts get - // their propagation aborted. + if (!nconf->permitsEtherType(etherType)) { #ifdef ZT_TRACE_MULTICAST - Utils::snprintf(mct,sizeof(mct), - "%.16llx %.2u %.3u%s %c %s dropped: rate limits exceeded", - guid, - prefix, - depth, - mctdepth, - (_r->topology->amSupernode() ? 'S' : '-'), - _r->identity.address().toString().c_str()); - _r->sm->sendUdp(ZT_DEFAULTS.multicastTraceWatcher,mct,strlen(mct)); + Utils::snprintf(mct,sizeof(mct), + "%.16llx %.2u %.3u%s %c %s dropped: ethertype not allowed", + guid, + prefix, + depth, + mctdepth, + (_r->topology->amSupernode() ? 'S' : '-'), + _r->identity.address().toString().c_str()); + _r->sm->sendUdp(ZT_DEFAULTS.multicastTraceWatcher,mct,strlen(mct)); #endif - TRACE("dropped MULTICAST_FRAME from %s(%s): rate limits exceeded for sender %s",source().toString().c_str(),_remoteAddress.toString().c_str(),origin.toString().c_str()); - return true; - } + TRACE("dropped MULTICAST_FRAME from %s(%s) into %.16llx: ethertype %u is not allowed",source().toString().c_str(),nwid,_remoteAddress.toString().c_str(),etherType); + return true; + } - network->tapPut(sourceMac,dest.mac(),etherType,frame,frameLen); + if (!network->updateAndCheckMulticastBalance(origin,dest,frameLen)) { + // Rate limits can only be checked by members of this network, but + // there should be enough of them that over-limit multicasts get + // their propagation aborted. +#ifdef ZT_TRACE_MULTICAST + Utils::snprintf(mct,sizeof(mct), + "%.16llx %.2u %.3u%s %c %s dropped: rate limits exceeded", + guid, + prefix, + depth, + mctdepth, + (_r->topology->amSupernode() ? 'S' : '-'), + _r->identity.address().toString().c_str()); + _r->sm->sendUdp(ZT_DEFAULTS.multicastTraceWatcher,mct,strlen(mct)); +#endif + TRACE("dropped MULTICAST_FRAME from %s(%s): rate limits exceeded for sender %s",source().toString().c_str(),_remoteAddress.toString().c_str(),origin.toString().c_str()); + return true; } + + network->tapPut(sourceMac,dest.mac(),etherType,frame,frameLen); } } @@ -816,11 +816,27 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared } else break; } - // Add any next hops we know about to FIFO + // Add any other next hops we know about to FIFO #ifdef ZT_TRACE_MULTICAST unsigned char *beforeAdd = newFifoPtr; #endif - _r->mc->getNextHops(nwid,dest,Multicaster::AddToPropagationQueue(&newFifoPtr,newFifoEnd,bloom,bloomNonce,origin,prefixBits,prefix)); + Multicaster::AddToPropagationQueue appender( + &newFifoPtr, + newFifoEnd, + bloom, + bloomNonce, + origin, + prefixBits, + prefix, + _r->topology, + Utils::now()); + if (nconf) { + for(std::set<Address>::const_iterator ab(nconf->activeBridges().begin());ab!=nconf->activeBridges().end();++ab) { + if (!appender(*ab)) + break; + } + } + _r->mc->getNextHops(nwid,dest,appender); #ifdef ZT_TRACE_MULTICAST unsigned int numAdded = (unsigned int)(newFifoPtr - beforeAdd) / ZT_ADDRESS_LENGTH; #endif |