summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
Diffstat (limited to 'node')
-rw-r--r--node/Constants.hpp17
-rw-r--r--node/Multicaster.hpp7
-rw-r--r--node/Network.cpp4
-rw-r--r--node/Network.hpp42
-rw-r--r--node/PacketDecoder.cpp8
-rw-r--r--node/Switch.cpp4
6 files changed, 56 insertions, 26 deletions
diff --git a/node/Constants.hpp b/node/Constants.hpp
index 67d404b7..926bac6f 100644
--- a/node/Constants.hpp
+++ b/node/Constants.hpp
@@ -233,25 +233,12 @@ error_no_ZT_ARCH_defined;
/**
* Breadth of tree for rumor mill multicast propagation
*/
-#define ZT_MULTICAST_PROPAGATION_BREADTH 4
+#define ZT_MULTICAST_DEFAULT_PROPAGATION_BREADTH 3
/**
* Depth of tree for rumor mill multicast propagation
- *
- * The maximum number of peers who can receive a multicast is equal to
- * the sum of BREADTH^i where I is from 1 to DEPTH. This ignores the effect
- * of the rate limiting algorithm or bloom filter collisions.
- *
- * 5 results in a max of 1364 recipients for a given multicast. With a limit
- * of 50 bytes/sec (average) for multicast, this results in a worst case of
- * around 68kb/sec of multicast traffic. FYI the average multicast traffic
- * from a Mac seems to be about ~25bytes/sec. Windows measurements are TBD.
- * Linux is quieter than Mac.
- *
- * This are eventually going to become per-network tunable parameters, along
- * with per-network peer multicast rate limits.
*/
-#define ZT_MULTICAST_PROPAGATION_DEPTH 5
+#define ZT_MULTICAST_DEFAULT_PROPAGATION_DEPTH 6
/**
* Length of ring buffer history of recent multicast packets
diff --git a/node/Multicaster.hpp b/node/Multicaster.hpp
index 77c7c532..c7e34d2f 100644
--- a/node/Multicaster.hpp
+++ b/node/Multicaster.hpp
@@ -52,9 +52,6 @@
#include "CMWC4096.hpp"
#include "C25519.hpp"
-// Maximum sample size to pick during choice of multicast propagation peers
-#define ZT_MULTICAST_PICK_MAX_SAMPLE_SIZE (ZT_MULTICAST_PROPAGATION_BREADTH * 8)
-
namespace ZeroTier {
/**
@@ -253,7 +250,7 @@ public:
Mutex::Lock _l(_multicastMemberships_m);
std::map< MulticastChannel,std::vector<MulticastMembership> >::iterator mm(_multicastMemberships.find(MulticastChannel(nwid,mg)));
if ((mm != _multicastMemberships.end())&&(!mm->second.empty())) {
- for(unsigned int stries=0;((stries<ZT_MULTICAST_PICK_MAX_SAMPLE_SIZE)&&(chosen < max));++stries) {
+ for(unsigned int stries=0,stmax=(max*10);((stries<stmax)&&(chosen < max));++stries) {
MulticastMembership &m = mm->second[prng.next32() % mm->second.size()];
unsigned int sum = m.first.sum();
if (
@@ -320,7 +317,7 @@ public:
Mutex::Lock _l(_multicastMemberships_m);
std::map< MulticastChannel,std::vector<MulticastMembership> >::iterator mm(_multicastMemberships.find(MulticastChannel(nwid,mg)));
if ((mm != _multicastMemberships.end())&&(!mm->second.empty())) {
- for(unsigned int stries=0;stries<ZT_MULTICAST_PICK_MAX_SAMPLE_SIZE;++stries) {
+ for(unsigned int stries=0,stmax=(max*10);stries<stmax;++stries) {
MulticastMembership &m = mm->second[prng.next32() % mm->second.size()];
if (
((now - m.second) < ZT_MULTICAST_LIKE_EXPIRE)&& /* LIKE is not expired */
diff --git a/node/Network.cpp b/node/Network.cpp
index b9ab513d..916a7caf 100644
--- a/node/Network.cpp
+++ b/node/Network.cpp
@@ -159,6 +159,8 @@ SharedPtr<Network> Network::newInstance(const RuntimeEnvironment *renv,uint64_t
nw->_ready = false; // disable handling of Ethernet frames during construct
nw->_r = renv;
nw->_tap = new EthernetTap(renv,tag,renv->identity.address().toMAC(),ZT_IF_MTU,&_CBhandleTapData,nw.ptr());
+ nw->_multicastPropagationBreadth = 0;
+ nw->_multicastPropagationDepth = 0;
memset(nw->_etWhitelist,0,sizeof(nw->_etWhitelist));
nw->_id = id;
nw->_lastConfigUpdate = 0;
@@ -179,6 +181,8 @@ void Network::setConfiguration(const Network::Config &conf)
_configuration = conf;
_myCertificate = conf.certificateOfMembership();
_mcRates = conf.multicastRates();
+ _multicastPropagationBreadth = conf.multicastPropagationBreadth();
+ _multicastPropagationDepth = conf.multicastPropagationDepth();
_lastConfigUpdate = Utils::now();
_tap->setIps(conf.staticAddresses());
diff --git a/node/Network.hpp b/node/Network.hpp
index ec4b9299..3e428ac2 100644
--- a/node/Network.hpp
+++ b/node/Network.hpp
@@ -318,6 +318,28 @@ public:
}
/**
+ * @return Breadth for multicast propagation
+ */
+ inline unsigned int multicastPropagationBreadth() const
+ {
+ const_iterator mcb(find("mcb"));
+ if (mcb == end())
+ return ZT_MULTICAST_DEFAULT_PROPAGATION_BREADTH;
+ return Utils::hexStrToUInt(mcb->second.c_str());
+ }
+
+ /**
+ * @return Depth for multicast propagation
+ */
+ inline unsigned int multicastPropagationDepth() const
+ {
+ const_iterator mcd(find("mcd"));
+ if (mcd == end())
+ return ZT_MULTICAST_DEFAULT_PROPAGATION_DEPTH;
+ return Utils::hexStrToUInt(mcd->second.c_str());
+ }
+
+ /**
* @return Certificate of membership for this network, or empty cert if none
*/
inline CertificateOfMembership certificateOfMembership() const
@@ -586,6 +608,24 @@ public:
//return tmp;
}
+ /**
+ * @return Breadth for multicast rumor mill propagation
+ */
+ inline unsigned int multicastPropagationBreadth() const
+ throw()
+ {
+ return _multicastPropagationBreadth;
+ }
+
+ /**
+ * @return Depth for multicast rumor mill propagation
+ */
+ inline unsigned int multicastPropagationDepth() const
+ throw()
+ {
+ return _multicastPropagationDepth;
+ }
+
private:
static void _CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned int etherType,const Buffer<4096> &data);
void _restoreState();
@@ -606,6 +646,8 @@ private:
Config _configuration;
CertificateOfMembership _myCertificate; // memoized from _configuration
MulticastRates _mcRates; // memoized from _configuration
+ unsigned int _multicastPropagationBreadth; // memoized from _configuration
+ unsigned int _multicastPropagationDepth; // memoized from _configuration
// Ethertype whitelist bit field, set from config, for really fast lookup
unsigned char _etWhitelist[65536 / 8];
diff --git a/node/PacketDecoder.cpp b/node/PacketDecoder.cpp
index b9eb5684..ca7af0bf 100644
--- a/node/PacketDecoder.cpp
+++ b/node/PacketDecoder.cpp
@@ -538,14 +538,14 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared
_r->multicaster->addToDedupHistory(mccrc,now);
}
- if (++hops >= ZT_MULTICAST_PROPAGATION_DEPTH) {
+ if (++hops >= network->multicastPropagationDepth()) {
TRACE("not propagating MULTICAST_FRAME from original submitter %s, received from %s(%s): max depth reached",originalSubmitterAddress.toString().c_str(),source().toString().c_str(),_remoteAddress.toString().c_str());
return true;
}
Address upstream(source()); // save this since we might mangle it below
Multicaster::MulticastBloomFilter bloom(field(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_BLOOM_FILTER,ZT_PROTO_VERB_MULTICAST_FRAME_BLOOM_FILTER_SIZE_BYTES));
- SharedPtr<Peer> propPeers[ZT_MULTICAST_PROPAGATION_BREADTH];
+ SharedPtr<Peer> propPeers[16];
unsigned int np = 0;
if (_r->topology->amSupernode()) {
@@ -567,7 +567,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared
originalSubmitterAddress,
upstream,
bloom,
- ZT_MULTICAST_PROPAGATION_BREADTH,
+ std::min(network->multicastPropagationBreadth(),(unsigned int)16), // 16 is a sanity check
propPeers,
now);
} else if (isDuplicate) {
@@ -584,7 +584,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared
originalSubmitterAddress,
upstream,
bloom,
- ZT_MULTICAST_PROPAGATION_BREADTH,
+ std::min(network->multicastPropagationBreadth(),(unsigned int)16), // 16 is a sanity check
propPeers,
now);
}
diff --git a/node/Switch.cpp b/node/Switch.cpp
index 0deece56..1677c145 100644
--- a/node/Switch.cpp
+++ b/node/Switch.cpp
@@ -119,7 +119,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
}
Multicaster::MulticastBloomFilter bloom;
- SharedPtr<Peer> propPeers[ZT_MULTICAST_PROPAGATION_BREADTH];
+ SharedPtr<Peer> propPeers[16];
unsigned int np = _r->multicaster->pickSocialPropagationPeers(
*(_r->prng),
*(_r->topology),
@@ -128,7 +128,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
_r->identity.address(),
Address(),
bloom,
- ZT_MULTICAST_PROPAGATION_BREADTH,
+ std::min(network->multicastPropagationBreadth(),(unsigned int)16), // 16 is a sanity check
propPeers,
now);