From 90e1262a8b607f35af0eade34eba7a49217cb7ed Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 26 Apr 2016 08:20:03 -0700 Subject: [PATCH] More refactoring to remove old Dictionary dependencies. --- node/IncomingPacket.cpp | 7 ++-- node/Network.cpp | 31 +++++++++++---- node/Network.hpp | 8 ++-- node/NetworkConfig.cpp | 4 +- node/NetworkConfig.hpp | 83 ++++++++++++++++++++++++++++++++++++++++- 5 files changed, 114 insertions(+), 19 deletions(-) diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index e4427f064..b21b42a25 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -403,10 +403,9 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr &p case Packet::VERB_NETWORK_CONFIG_REQUEST: { const SharedPtr nw(RR->node->network(at(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_NETWORK_ID))); if ((nw)&&(nw->controller() == peer->address())) { - const unsigned int dictlen = at(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT_LEN); - const std::string dict((const char *)field(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT,dictlen),dictlen); - if (dict.length()) { - nw->setConfiguration(Dictionary(dict)); + const unsigned int nclen = at(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT_LEN); + if (nclen) { + nw->setConfiguration(field(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT,nclen),nclen,true); TRACE("got network configuration for network %.16llx from %s",(unsigned long long)nw->id(),source().toString().c_str()); } } diff --git a/node/Network.cpp b/node/Network.cpp index 86780861d..f2c14db31 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -65,7 +65,7 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid,void *uptr) : try { std::string conf(RR->node->dataStoreGet(confn)); if (conf.length()) { - setConfiguration(Dictionary(conf),false); + this->setConfiguration((const void *)conf.data(),(unsigned int)conf.length(),false); _lastConfigUpdate = 0; // we still want to re-request a new config from the network gotConf = true; } @@ -178,26 +178,40 @@ bool Network::applyConfiguration(const NetworkConfig &conf) return false; } -int Network::setConfiguration(const Dictionary &conf,bool saveToDisk) +int Network::setConfiguration(const void *confBytes,unsigned int confLen,bool saveToDisk) { try { + if (!confLen) + return 0; + NetworkConfig newConfig; - newConfig.fromDictionary(conf); // throws if invalid + if (reinterpret_cast(confBytes)[0] == ZT_NETWORKCONFIG_V2_MARKER_BYTE) { + // TODO: deserialize new binary format netconf + return 0; + } else { +#ifdef ZT_SUPPORT_OLD_STYLE_NETCONF + newConfig.fromDictionary(reinterpret_cast(confBytes),confLen); // throws if invalid +#else + return 0; +#endif + } + { Mutex::Lock _l(_lock); if (_config == newConfig) return 1; // OK config, but duplicate of what we already have } + if (applyConfiguration(newConfig)) { if (saveToDisk) { char n[128]; Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.conf",_id); - RR->node->dataStorePut(n,conf.toString(),true); + RR->node->dataStorePut(n,confBytes,confLen,true); } return 2; // OK and configuration has changed } } catch ( ... ) { - TRACE("ignored invalid configuration for network %.16llx (dictionary decode failed)",(unsigned long long)_id); + TRACE("ignored invalid configuration for network %.16llx",(unsigned long long)_id); } return 0; } @@ -211,9 +225,10 @@ void Network::requestConfiguration() if (RR->localNetworkController) { Dictionary newconf; switch(RR->localNetworkController->doNetworkConfigRequest(InetAddress(),RR->identity,RR->identity,_id,Dictionary(),newconf)) { - case NetworkController::NETCONF_QUERY_OK: - this->setConfiguration(newconf,true); - return; + case NetworkController::NETCONF_QUERY_OK: { + std::string tmp(newconf.toString()); + this->setConfiguration((const void *)tmp.data(),(unsigned int)tmp.length(),true); + } return; case NetworkController::NETCONF_QUERY_OBJECT_NOT_FOUND: this->setNotFound(); return; diff --git a/node/Network.hpp b/node/Network.hpp index 5d33151bf..9d280fbf3 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -151,14 +151,12 @@ public: /** * Set or update this network's configuration * - * This decodes a network configuration in key=value dictionary form, - * applies it if valid, and persists it to disk if saveToDisk is true. - * - * @param conf Configuration in key/value dictionary form + * @param confBytes Network configuration in old-style Dictionary or new-style serialized format + * @param confLen Length of network configuration in bytes * @param saveToDisk IF true (default), write config to disk * @return 0 -- rejected, 1 -- accepted but not new, 2 -- accepted new config */ - int setConfiguration(const Dictionary &conf,bool saveToDisk = true); + int setConfiguration(const void *confBytes,unsigned int confLen,bool saveToDisk); /** * Set netconf failure to 'access denied' -- called in IncomingPacket when controller reports this diff --git a/node/NetworkConfig.cpp b/node/NetworkConfig.cpp index 090648f86..5ca432bad 100644 --- a/node/NetworkConfig.cpp +++ b/node/NetworkConfig.cpp @@ -80,8 +80,10 @@ NetworkConfig NetworkConfig::createTestNetworkConfig(const Address &self) #ifdef ZT_SUPPORT_OLD_STYLE_NETCONF -void NetworkConfig::fromDictionary(const Dictionary &d) +void NetworkConfig::fromDictionary(const char *ds,unsigned int dslen) { + Dictionary d(ds,dslen); + static const std::string zero("0"); static const std::string one("1"); diff --git a/node/NetworkConfig.hpp b/node/NetworkConfig.hpp index 0ed7b6a2b..4c8a0857a 100644 --- a/node/NetworkConfig.hpp +++ b/node/NetworkConfig.hpp @@ -39,6 +39,13 @@ #include "Address.hpp" #include "CertificateOfMembership.hpp" +/** + * First byte of V2 binary-serialized network configs + * + * This will never begin a Dictionary, so it serves to distinguish. + */ +#define ZT_NETWORKCONFIG_V2_MARKER_BYTE 0x00 + namespace ZeroTier { #ifdef ZT_SUPPORT_OLD_STYLE_NETCONF @@ -147,24 +154,76 @@ public: /** * Parse an old-style dictionary and fill in structure * + * @param ds String-serialized dictionary + * @param dslen Length of dictionary in bytes * @throws std::invalid_argument Invalid dictionary */ - void fromDictionary(const Dictionary &d); + void fromDictionary(const char *ds,unsigned int dslen); #endif + /** + * @return Network ID that this config applies to + */ inline uint64_t networkId() const throw() { return _nwid; } + + /** + * @return Timestamp of this config (controller-side) + */ inline uint64_t timestamp() const throw() { return _timestamp; } + + /** + * @return Config revision number + */ inline uint64_t revision() const throw() { return _revision; } + + /** + * @return ZeroTier address of device to which this config was issued + */ inline const Address &issuedTo() const throw() { return _issuedTo; } + + /** + * @return Maximum number of multicast recipients or 0 to disable multicast + */ inline unsigned int multicastLimit() const throw() { return _multicastLimit; } + + /** + * @return True if passive bridging is allowed (experimental) + */ inline bool allowPassiveBridging() const throw() { return _allowPassiveBridging; } + + /** + * @return True if broadcast (ff:ff:ff:ff:ff:ff) address should work on this network + */ inline bool enableBroadcast() const throw() { return _enableBroadcast; } + + /** + * @return Type of network (currently public or private) + */ inline ZT_VirtualNetworkType type() const throw() { return _type; } + + /** + * @return Network type is public (no access control) + */ inline bool isPublic() const throw() { return (_type == ZT_NETWORK_TYPE_PUBLIC); } + + /** + * @return Network type is private (certificate access control) + */ inline bool isPrivate() const throw() { return (_type == ZT_NETWORK_TYPE_PRIVATE); } + + /** + * @return Short network name + */ inline const char *name() const throw() { return _name; } + + /** + * @return Network certificate of membership or NULL COM object if none (public network) + */ inline const CertificateOfMembership &com() const throw() { return _com; } + /** + * @return Network/netmask routes that are considered local to this virtual LAN interface + */ inline std::vector localRoutes() const { std::vector r; @@ -173,6 +232,9 @@ public: return r; } + /** + * @return ZeroTier-managed static IPs assigned to this device on this network + */ inline std::vector staticIps() const { std::vector r; @@ -181,6 +243,9 @@ public: return r; } + /** + * @return ZeroTier-managed default gateways (for full tunnel) available on this network + */ inline std::vector gateways() const { std::vector r; @@ -189,6 +254,9 @@ public: return r; } + /** + * @return ZeroTier addresses of devices on this network designated as active bridges + */ inline std::vector
activeBridges() const { std::vector
r; @@ -197,6 +265,9 @@ public: return r; } + /** + * @return Network-preferred relays for this network (if none, only roots will be used) + */ inline std::vector relays() const { std::vector r; @@ -207,7 +278,14 @@ public: return r; } + /** + * @return Static device at index [i] (warning: no bounds checking! see staticDeviceCount() for count) + */ const ZT_VirtualNetworkStaticDevice &staticDevice(unsigned int i) const { return _static[i]; } + + /** + * @return Number of static devices defined in this network config + */ unsigned int staticDeviceCount() const { return _staticCount; } /** @@ -225,6 +303,9 @@ public: return false; } + /** + * @return True if this network config is non-NULL + */ inline operator bool() const throw() { return (_nwid != 0); } inline bool operator==(const NetworkConfig &nc) const { return (memcmp(this,&nc,sizeof(NetworkConfig)) == 0); }