summaryrefslogtreecommitdiff
path: root/node/PacketDecoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'node/PacketDecoder.cpp')
-rw-r--r--node/PacketDecoder.cpp140
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