From b10871cedcdaa6f18779fcebcc889cdd35df546b Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 18 Oct 2013 11:01:41 -0400 Subject: [PATCH] More work in netconf cleanup. --- netconf-service/netconf.cpp | 22 +++-------- node/MAC.hpp | 12 +----- node/MulticastGroup.hpp | 28 ++++++++++++++ node/NetworkConfig.cpp | 74 ++++++++++++++++++++++++++++++++++++- node/NetworkConfig.hpp | 42 ++++++++++++++++++--- objects.mk | 1 + 6 files changed, 146 insertions(+), 33 deletions(-) diff --git a/netconf-service/netconf.cpp b/netconf-service/netconf.cpp index 695e0795e..8d274d35f 100644 --- a/netconf-service/netconf.cpp +++ b/netconf-service/netconf.cpp @@ -325,23 +325,13 @@ int main(int argc,char **argv) q << "SELECT DISTINCT multicastGroupMac,multicastGroupAdi,preload,maxBalance,accrual FROM NetworkMulticastRates WHERE Network_id = " << nwid; StoreQueryResult rs = q.store(); for(unsigned long i=0;i NetworkConfig::allowedEtherTypes() +// This is fast enough for things like Apple's mDNS spam, so it should serve +// as a good default for your average network. It's 64 bytes per second, with +// a starting and max balance of 64k. +const NetworkConfig::MulticastRate NetworkConfig::DEFAULT_MULTICAST_RATE(65535,65535,64); + +std::set NetworkConfig::allowedEtherTypes() const { std::set ets; for(unsigned int i=0;i NetworkConfig::allowedEtherTypes() return ets; } +const NetworkConfig::MulticastRate &NetworkConfig::multicastRate(const MulticastGroup &mg) const + throw() +{ + std::map::const_iterator r(_multicastRates.find(mg)); + if (r == _multicastRates.end()) { + r = _multicastRates.find(MulticastGroup()); // zero MG signifies network's default rate + if (r == _multicastRates.end()) + return DEFAULT_MULTICAST_RATE; // neither specific nor default found in network config + } + return r->second; +} + +static const std::string _zero("0"); +void NetworkConfig::_fromDictionary(const Dictionary &d) +{ + // NOTE: d.get(name) throws if not found, d.get(name,default) returns default + + _nwid = Utils::hexStrToU64(d.get(ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID).c_str()); + if (!_nwid) + throw std::invalid_argument("configuration contains zero network ID"); + _timestamp = Utils::hexStrToU64(d.get(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP).c_str()); + _issuedTo = Address(d.get(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO)); + _multicastPrefixBits = Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_PREFIX_BITS,_zero).c_str()); + _multicastDepth = Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_DEPTH,_zero).c_str()); + _arpCacheTtl = Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_ARP_CACHE_TTL,_zero).c_str()); + _ndpCacheTtl = Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_NDP_CACHE_TTL,_zero).c_str()); + _emulateArp = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_EMULATE_ARP,_zero).c_str()) != 0); + _emulateNdp = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_EMULATE_NDP,_zero).c_str()) != 0); + _isOpen = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_IS_OPEN,_zero).c_str()) != 0); + _name = d.get(ZT_NETWORKCONFIG_DICT_KEY_NAME); + _description = d.get(ZT_NETWORKCONFIG_DICT_KEY_DESC,std::string()); + + std::string ipAddrs(d.get(ZT_NETWORKCONFIG_DICT_KEY_IPV4_STATIC,std::string())); + std::string v6s(d.get(ZT_NETWORKCONFIG_DICT_KEY_IPV6_STATIC,std::string())); + if (v6s.length()) { + if (ipAddrs.length()) + ipAddrs.push_back(','); + ipAddrs.append(v6s); + } + std::vector ipAddrs2(Utils::split(ipAddrs.c_str(),",","","")); + for(std::vector::const_iterator ipstr(ipAddrs2.begin());ipstr!=ipAddrs2.end();++ipstr) { + InetAddress addr(*ipstr); + switch(addr.type()) { + case InetAddress::TYPE_IPV4: + if ((!addr.netmaskBits())||(addr.netmaskBits() > 32)) + throw std::invalid_argument("static IP address fields contain one or more invalid IP/netmask entries"); + break; + case InetAddress::TYPE_IPV6: + if ((!addr.netmaskBits())||(addr.netmaskBits() > 128)) + throw std::invalid_argument("static IP address fields contain one or more invalid IP/netmask entries"); + break; + default: + throw std::invalid_argument("static IP address fields contain one or more invalid IP/netmask entries"); + } + _staticIps.insert(addr); + } + + Dictionary mr(d.get(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_RATES,std::string())); + for(Dictionary::const_iterator i(mr.begin());i!=mr.end();++i) { + std::vector params(Utils::split(i->second.c_str(),",","","")); + if (params.size() >= 3) + _multicastRates[MulticastGroup(i->first)] = MulticastRate(Utils::hexStrToUInt(params[0].c_str()),Utils::hexStrToUInt(params[1].c_str()),Utils::hexStrToUInt(params[2].c_str())); + } +} + } // namespace ZeroTier + diff --git a/node/NetworkConfig.hpp b/node/NetworkConfig.hpp index 317c66718..c4f5cf963 100644 --- a/node/NetworkConfig.hpp +++ b/node/NetworkConfig.hpp @@ -28,18 +28,25 @@ #ifndef _ZT_NETWORKCONFIG_HPP #define _ZT_NETWORKCONFIG_HPP +#include + +#include #include #include #include +#include "Constants.hpp" #include "Dictionary.hpp" #include "InetAddress.hpp" #include "AtomicCounter.hpp" #include "SharedPtr.hpp" +#include "MulticastGroup.hpp" +#include "Address.hpp" namespace ZeroTier { -// These are short to fit in packets with plenty of room to spare +// These dictionary keys are short so they don't take up much room in +// netconf response packets. #define ZT_NETWORKCONFIG_DICT_KEY_ALLOWED_ETHERNET_TYPES "et" #define ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID "nwid" #define ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP "ts" @@ -69,12 +76,28 @@ class NetworkConfig public: friend class SharedPtr; + /** + * Tuple of multicast rate parameters + */ + struct MulticastRate + { + MulticastRate() throw() {} + MulticastRate(uint32_t pl,uint32_t maxb,uint32_t acc) throw() : preload(pl),maxBalance(maxb),accrual(acc) {} + uint32_t preload; + uint32_t maxBalance; + uint32_t accrual; + }; + + /** + * A hard-coded default multicast rate for networks that don't specify + */ + static const MulticastRate DEFAULT_MULTICAST_RATE; + /** * @param d Dictionary containing configuration * @throws std::invalid_argument Invalid configuration */ NetworkConfig(const Dictionary &d) - throw(std::invalid_argument) { _fromDictionary(d); } @@ -107,14 +130,20 @@ public: inline const std::string &name() const throw() { return _name; } inline const std::string &description() const throw() { return _description; } inline const std::set &staticIps() const throw() { return _staticIps; } - inline const MulticastRateTable &multicastRates() const throw() { return _multicastRates; } + inline const std::map &multicastRates() const throw() { return _multicastRates; } + + /** + * @param mg Multicast group + * @return Multicast rate or DEFAULT_MULTICAST_RATE if not set + */ + const MulticastRate &multicastRate(const MulticastGroup &mg) const + throw(); private: NetworkConfig() {} ~NetworkConfig() {} - void _fromDictionary(const Dictionary &d) - throw(std::invalid_argument); + void _fromDictionary(const Dictionary &d); unsigned char _etWhitelist[65536 / 8]; uint64_t _nwid; @@ -130,7 +159,7 @@ private: std::string _name; std::string _description; std::set _staticIps; - MulticastRateTable _multicastRates; + std::map _multicastRates; AtomicCounter __refCount; }; @@ -138,3 +167,4 @@ private: } // namespace ZeroTier #endif + diff --git a/objects.mk b/objects.mk index 41e1d83cb..28d314348 100644 --- a/objects.mk +++ b/objects.mk @@ -12,6 +12,7 @@ OBJS=\ node/Logger.o \ node/Multicaster.o \ node/Network.o \ + node/NetworkConfig.o \ node/Node.o \ node/NodeConfig.o \ node/Packet.o \