summaryrefslogtreecommitdiff
path: root/node/PacketDecoder.cpp
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2014-06-30 11:31:04 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2014-06-30 11:31:04 -0700
commit88bdb81791e7879c6c199d6e9d03a326ec786484 (patch)
treec22c9e36e803ba820c55ca04a82ba204ff906ade /node/PacketDecoder.cpp
parent458f6ae7c37c7877a842e7931edc67d9fed201cd (diff)
downloadinfinitytier-88bdb81791e7879c6c199d6e9d03a326ec786484.tar.gz
infinitytier-88bdb81791e7879c6c199d6e9d03a326ec786484.zip
Keep track of basic aliveness for peers regardless if direct or indirect connectivity and use this for multicast propagation. Also consolidate adding of active bridges via the same functor as regular multicast next hops.
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