diff options
Diffstat (limited to 'node')
-rw-r--r-- | node/Constants.hpp | 16 | ||||
-rw-r--r-- | node/Network.cpp | 4 | ||||
-rw-r--r-- | node/Network.hpp | 62 | ||||
-rw-r--r-- | node/PacketDecoder.cpp | 4 | ||||
-rw-r--r-- | node/Switch.cpp | 7 |
5 files changed, 77 insertions, 16 deletions
diff --git a/node/Constants.hpp b/node/Constants.hpp index 91fd5abd..08ec2243 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -236,23 +236,19 @@ error_no_ZT_ARCH_defined; #define ZT_MULTICAST_DEDUP_HISTORY_LENGTH 1024 /** - * Maximum propagation depth for multicasts - * - * TODO: in the future make this configurable per-network. + * Default number of bits in multicast propagation prefix */ -#define ZT_MULTICAST_MAX_PROPAGATION_DEPTH 128 +#define ZT_DEFAULT_MULTICAST_PREFIX_BITS 2 /** - * Number of frames to send when originating a multicast - * - * This MUST be a power of two. + * Default max depth (TTL) for multicast propagation */ -#define ZT_MULTICAST_NUM_PROPAGATION_PREFIXES 4 +#define ZT_DEFAULT_MULTICAST_DEPTH 64 /** - * Power of two used for ZT_MULTICAST_NUM_PROPAGATION_PREFIXES + * Global maximum for multicast propagation depth */ -#define ZT_MULTICAST_NUM_PROPAGATION_PREFIX_BITS 2 +#define ZT_MULTICAST_GLOBAL_MAX_DEPTH 500 /** * Period between announcements of all multicast 'likes' in ms diff --git a/node/Network.cpp b/node/Network.cpp index 65e61738..82fa6398 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -161,6 +161,8 @@ SharedPtr<Network> Network::newInstance(const RuntimeEnvironment *renv,uint64_t nw->_r = renv; nw->_tap = new EthernetTap(renv,tag,renv->identity.address().toMAC(),ZT_IF_MTU,&_CBhandleTapData,nw.ptr()); nw->_isOpen = false; + nw->_multicastPrefixBits = ZT_DEFAULT_MULTICAST_PREFIX_BITS; + nw->_multicastDepth = ZT_DEFAULT_MULTICAST_DEPTH; memset(nw->_etWhitelist,0,sizeof(nw->_etWhitelist)); nw->_id = id; nw->_lastConfigUpdate = 0; @@ -185,6 +187,8 @@ void Network::setConfiguration(const Network::Config &conf) _mcRates = conf.multicastRates(); _staticAddresses = conf.staticAddresses(); _isOpen = conf.isOpen(); + _multicastPrefixBits = conf.multicastPrefixBits(); + _multicastDepth = conf.multicastDepth(); _lastConfigUpdate = Utils::now(); diff --git a/node/Network.hpp b/node/Network.hpp index 2ed70504..cccae17e 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -266,12 +266,20 @@ public: * nwid=<hex network ID> (required) * name=short name * desc=long(er) description - * com=Certificate (serialized dictionary) + * com=Serialized certificate of membership * mr=MulticastRates (serialized dictionary) + * md=multicast propagation depth + * mpb=multicast propagation prefix bits (2^mpb packets are sent by origin) * o=open network? (1 or 0, default false if missing) * et=ethertype whitelist (comma-delimited list of ethertypes in decimal) * v4s=IPv4 static assignments / netmasks (comma-delimited) * v6s=IPv6 static assignments / netmasks (comma-delimited) + * + * Notes: + * + * If zero appears in the 'et' list, the sense is inverted. It becomes an + * ethertype blacklist instead of a whitelist and anything not blacklisted + * is permitted. */ class Config : private Dictionary { @@ -340,6 +348,34 @@ public: } /** + * @return Number of bits in propagation prefix for this network + */ + inline unsigned int multicastPrefixBits() const + { + const_iterator mpb(find("mpb")); + if (mpb == end()) + return ZT_DEFAULT_MULTICAST_PREFIX_BITS; + unsigned int tmp = Utils::hexStrToUInt(mpb->second.c_str()); + if (tmp) + return tmp; + else return ZT_DEFAULT_MULTICAST_PREFIX_BITS; + } + + /** + * @return Maximum multicast propagation depth for this network + */ + inline unsigned int multicastDepth() const + { + const_iterator md(find("md")); + if (md == end()) + return ZT_DEFAULT_MULTICAST_DEPTH; + unsigned int tmp = Utils::hexStrToUInt(md->second.c_str()); + if (tmp) + return tmp; + else return ZT_DEFAULT_MULTICAST_DEPTH; + } + + /** * @return True if this is an open non-access-controlled network */ inline bool isOpen() const @@ -557,7 +593,9 @@ public: return false; else if (etherType > 65535) return false; - else return ((_etWhitelist[etherType / 8] & (unsigned char)(1 << (etherType % 8))) != 0); + else if ((_etWhitelist[0] & 1)) // if type 0 is in the whitelist, sense is inverted from whitelist to blacklist + return ((_etWhitelist[etherType / 8] & (unsigned char)(1 << (etherType & 7))) == 0); + else return ((_etWhitelist[etherType / 8] & (unsigned char)(1 << (etherType & 7))) != 0); } /** @@ -592,6 +630,24 @@ public: return false; // TODO: bridging not implemented yet } + /** + * @return Bits in multicast restriciton prefix + */ + inline unsigned int multicastPrefixBits() const + throw() + { + return _multicastPrefixBits; + } + + /** + * @return Max depth (TTL) for a multicast frame + */ + inline unsigned int multicastDepth() const + throw() + { + return _multicastDepth; + } + private: static void _CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned int etherType,const Buffer<4096> &data); void _restoreState(); @@ -614,6 +670,8 @@ private: MulticastRates _mcRates; // memoized from _configuration std::set<InetAddress> _staticAddresses; // memoized from _configuration bool _isOpen; // memoized from _configuration + unsigned int _multicastPrefixBits; // memoized from _configuration + unsigned int _multicastDepth; // 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 1ec087c7..afc7e4fe 100644 --- a/node/PacketDecoder.cpp +++ b/node/PacketDecoder.cpp @@ -485,6 +485,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared } bool rateLimitsExceeded = false; + unsigned int maxDepth = ZT_MULTICAST_GLOBAL_MAX_DEPTH; if ((origin == _r->identity.address())||(_r->mc->deduplicate(nwid,guid))) { // Ordinary frames will drop duplicates. Supernodes keep propagating @@ -502,6 +503,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared // for the same frame would not be fair. SharedPtr<Network> network(_r->nc->network(nwid)); if (network) { + maxDepth = network->multicastDepth(); // pull from network config if available if (!network->isAllowed(origin)) { TRACE("didn't inject MULTICAST_FRAME from %s(%s) into %.16llx: sender %s not allowed or we don't have a certificate",source().toString().c_str(),nwid,_remoteAddress.toString().c_str(),origin.toString().c_str()); @@ -541,7 +543,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared TRACE("not forwarding MULTICAST_FRAME from %s(%s): depth == 0xffff (do not forward)",source().toString().c_str(),_remoteAddress.toString().c_str()); return true; } - if (++depth > ZT_MULTICAST_MAX_PROPAGATION_DEPTH) { + if (++depth > maxDepth) { TRACE("not forwarding MULTICAST_FRAME from %s(%s): max propagation depth reached",source().toString().c_str(),_remoteAddress.toString().c_str()); return true; } diff --git a/node/Switch.cpp b/node/Switch.cpp index 90f0b2e5..14b658a7 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -111,13 +111,14 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c uint16_t bloomNonce = (uint16_t)_r->prng->next32(); // doesn't need to be cryptographically strong unsigned char bloom[ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_BLOOM]; unsigned char fifo[ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_FIFO + ZT_ADDRESS_LENGTH]; - for(unsigned int prefix=0;prefix<ZT_MULTICAST_NUM_PROPAGATION_PREFIXES;++prefix) { + + for(unsigned int prefix=0,np=((unsigned int)2 << (network->multicastPrefixBits() - 1));prefix<np;++prefix) { memset(bloom,0,sizeof(bloom)); unsigned char *fifoPtr = fifo; unsigned char *fifoEnd = fifo + sizeof(fifo); - _r->mc->getNextHops(network->id(),mg,Multicaster::AddToPropagationQueue(&fifoPtr,fifoEnd,bloom,bloomNonce,_r->identity.address(),ZT_MULTICAST_NUM_PROPAGATION_PREFIX_BITS,prefix)); + _r->mc->getNextHops(network->id(),mg,Multicaster::AddToPropagationQueue(&fifoPtr,fifoEnd,bloom,bloomNonce,_r->identity.address(),network->multicastPrefixBits(),prefix)); while (fifoPtr != fifoEnd) *(fifoPtr++) = (unsigned char)0; @@ -136,7 +137,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c outp.append((unsigned char)0); outp.append(network->id()); outp.append(bloomNonce); - outp.append((unsigned char)ZT_MULTICAST_NUM_PROPAGATION_PREFIX_BITS); + outp.append((unsigned char)network->multicastPrefixBits()); outp.append((unsigned char)prefix); _r->identity.address().appendTo(outp); outp.append((unsigned char)((mcid >> 16) & 0xff)); |