diff options
Diffstat (limited to 'node')
| -rw-r--r-- | node/MAC.hpp | 12 | ||||
| -rw-r--r-- | node/MulticastGroup.hpp | 28 | ||||
| -rw-r--r-- | node/NetworkConfig.cpp | 74 | ||||
| -rw-r--r-- | node/NetworkConfig.hpp | 42 | 
4 files changed, 139 insertions, 17 deletions
| diff --git a/node/MAC.hpp b/node/MAC.hpp index 9765aa59..b1864511 100644 --- a/node/MAC.hpp +++ b/node/MAC.hpp @@ -135,17 +135,9 @@ public:  	 * @param s String hex representation (with or without :'s)  	 * @return True if string decoded into a full-length MAC  	 */ -	inline bool fromString(const char *s) +	inline void fromString(const char *s)  	{ -		std::string b(Utils::unhex(s)); -		if (b.length() == 6) { -			for(unsigned int i=0;i<6;++i) -				data[i] = (unsigned char)b[i]; -			return true; -		} -		for(unsigned int i=0;i<6;++i) -			data[i] = 0; -		return false; +		Utils::unhex(s,data,6);  	}  	inline std::string toString() const diff --git a/node/MulticastGroup.hpp b/node/MulticastGroup.hpp index bb025ab1..426ef048 100644 --- a/node/MulticastGroup.hpp +++ b/node/MulticastGroup.hpp @@ -69,6 +69,16 @@ public:  	{  	} +	MulticastGroup(const char *s) +	{ +		fromString(s); +	} + +	MulticastGroup(const std::string &s) +	{ +		fromString(s.c_str()); +	} +  	/**  	 * Derive the multicast group used for address resolution (ARP/NDP) for an IP  	 * @@ -113,6 +123,24 @@ public:  	}  	/** +	 * Parse a human-readable multicast group +	 * +	 * @param s Multicast group in hex MAC/ADI format +	 */ +	inline void fromString(const char *s) +	{ +		char hex[17]; +		unsigned int hexlen = 0; +		while ((*s)&&(*s != '/')&&(hexlen < sizeof(hex) - 1)) +			hex[hexlen++] = *s; +		hex[hexlen] = (char)0; +		_mac.fromString(hex); +		if (*s == '/') +			_adi = (uint32_t)Utils::hexStrToULong(++s); +		else _adi = 0; +	} + +	/**  	 * @return Multicast address  	 */  	inline const MAC &mac() const throw() { return _mac; } diff --git a/node/NetworkConfig.cpp b/node/NetworkConfig.cpp index 1536af88..6354bdb7 100644 --- a/node/NetworkConfig.cpp +++ b/node/NetworkConfig.cpp @@ -26,10 +26,16 @@   */  #include "NetworkConfig.hpp" +#include "Utils.hpp"  namespace ZeroTier { -std::set<unsigned int> 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<unsigned int> NetworkConfig::allowedEtherTypes() const  {  	std::set<unsigned int> ets;  	for(unsigned int i=0;i<sizeof(_etWhitelist);++i) { @@ -47,4 +53,70 @@ std::set<unsigned int> NetworkConfig::allowedEtherTypes()  	return ets;  } +const NetworkConfig::MulticastRate &NetworkConfig::multicastRate(const MulticastGroup &mg) const +	throw() +{ +	std::map<MulticastGroup,MulticastRate>::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<std::string> ipAddrs2(Utils::split(ipAddrs.c_str(),",","","")); +	for(std::vector<std::string>::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<std::string> 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 317c6671..c4f5cf96 100644 --- a/node/NetworkConfig.hpp +++ b/node/NetworkConfig.hpp @@ -28,18 +28,25 @@  #ifndef _ZT_NETWORKCONFIG_HPP  #define _ZT_NETWORKCONFIG_HPP +#include <stdint.h> + +#include <map>  #include <set>  #include <string>  #include <stdexcept> +#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" @@ -70,11 +77,27 @@ public:  	friend class SharedPtr<NetworkConfig>;  	/** +	 * 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<InetAddress> &staticIps() const throw() { return _staticIps; } -	inline const MulticastRateTable &multicastRates() const throw() { return _multicastRates; } +	inline const std::map<MulticastGroup,MulticastRate> &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<InetAddress> _staticIps; -	MulticastRateTable _multicastRates; +	std::map<MulticastGroup,MulticastRate> _multicastRates;  	AtomicCounter __refCount;  }; @@ -138,3 +167,4 @@ private:  } // namespace ZeroTier  #endif + | 
