diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-04-06 16:52:52 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-04-06 16:52:52 -0700 |
commit | 8001b2c0cb6d35bfbc7b7be78d1a8b6d0fafbd53 (patch) | |
tree | 2491d429727fb9d732d86bfae778068a889d363e | |
parent | a86300c58fe29e9a8626f935f0b3ed25e844b0aa (diff) | |
download | infinitytier-8001b2c0cb6d35bfbc7b7be78d1a8b6d0fafbd53.tar.gz infinitytier-8001b2c0cb6d35bfbc7b7be78d1a8b6d0fafbd53.zip |
Network now calls port config function as per new API.
-rw-r--r-- | include/ZeroTierOne.h | 70 | ||||
-rw-r--r-- | node/Network.cpp | 78 | ||||
-rw-r--r-- | node/Network.hpp | 21 | ||||
-rw-r--r-- | node/NetworkConfig.cpp | 4 | ||||
-rw-r--r-- | node/Node.cpp | 8 | ||||
-rw-r--r-- | node/Node.hpp | 42 |
6 files changed, 155 insertions, 68 deletions
diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index 298b8157..2d0e837a 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -79,6 +79,21 @@ extern "C" { #define ZT1_MAX_MTU 2800 /** + * Maximum length of network short name + */ +#define ZT1_MAX_NETWORK_SHORT_NAME_LENGTH 255 + +/** + * Maximum number of statically assigned IP addresses per network endpoint using ZT address management (not DHCP) + */ +#define ZT1_MAX_ZT_ASSIGNED_ADDRESSES 16 + +/** + * Maximum number of multicast group subscriptions per network + */ +#define ZT1_MAX_NETWORK_MULTICAST_SUBSCRIPTIONS 8194 + +/** * Feature flag: this is an official ZeroTier, Inc. binary build (built with ZT_OFFICIAL_RELEASE) */ #define ZT1_FEATURE_FLAG_OFFICIAL 0x00000001 @@ -272,7 +287,7 @@ enum ZT1_VirtualNetworkStatus /** * Initialization of network failed or other internal error */ - ZT1_NETWORK_STATUS_INITIALIZATION_FAILED = 4 + ZT1_NETWORK_STATUS_PORT_ERROR = 4 }; /** @@ -323,6 +338,11 @@ typedef struct uint64_t mac; /** + * Network name (from network configuration master) + */ + char name[ZT1_MAX_NETWORK_SHORT_NAME_LENGTH + 1]; + + /** * Network configuration request status */ enum ZT1_VirtualNetworkStatus status; @@ -360,43 +380,43 @@ typedef struct int broadcastEnabled; /** - * Network config revision as reported by netconf master - * - * If this is zero, it means we're still waiting for our netconf. + * If the network is in PORT_ERROR state, this is the error most recently returned by the port config callback */ - unsigned long netconfRevision; + int portError; /** - * ZeroTier-assigned addresses (in sockaddr_storage structures) - * - * For IP, the port number of the sockaddr_XX structure contains the number - * of bits in the address netmask. Only the IP address and port are used. - * Other fields like interface number can be ignored. + * Network config revision as reported by netconf master * - * This is only used for ZeroTier-managed address assignments sent by the - * virtual network's configuration master. + * If this is zero, it means we're still waiting for our netconf. */ - const struct sockaddr_storage *assignedAddresses; + unsigned long netconfRevision; /** - * Number of assigned addresses + * Number of multicast group subscriptions */ - unsigned int assignedAddressCount; + unsigned int multicastSubscriptionCount; /** * Multicast group subscriptions */ - ZT1_MulticastGroup *multicastSubscriptions; + ZT1_MulticastGroup multicastSubscriptions[ZT1_MAX_NETWORK_MULTICAST_SUBSCRIPTIONS]; /** - * Number of multicast group subscriptions + * Number of assigned addresses */ - unsigned int multicastSubscriptionCount; + unsigned int assignedAddressCount; /** - * Network name (from network configuration master) + * ZeroTier-assigned addresses (in sockaddr_storage structures) + * + * For IP, the port number of the sockaddr_XX structure contains the number + * of bits in the address netmask. Only the IP address and port are used. + * Other fields like interface number can be ignored. + * + * This is only used for ZeroTier-managed address assignments sent by the + * virtual network's configuration master. */ - const char *networkName; + struct sockaddr_storage assignedAddresses[ZT1_MAX_ZT_ASSIGNED_ADDRESSES]; } ZT1_VirtualNetworkConfig; /** @@ -539,8 +559,12 @@ typedef void ZT1_Node; * * The supplied config pointer is not guaranteed to remain valid, so make * a copy if you want one. + * + * This must return 0 on success. It can return any OS-dependent error code + * on failure, and this results in the network being placed into the + * PORT_ERROR state. */ -typedef void (*ZT1_VirtualNetworkConfigCallback)(ZT1_Node *,uint64_t,const ZT1_VirtualNetworkConfig *); +typedef int (*ZT1_VirtualNetworkConfigFunction)(ZT1_Node *,uint64_t,const ZT1_VirtualNetworkConfig *); /** * Callback for status messages @@ -622,7 +646,7 @@ typedef void (*ZT1_VirtualNetworkFrameFunction)(ZT1_Node *,uint64_t,uint64_t,uin * @param now Current clock in milliseconds * @param dataStoreGetFunction Function called to get objects from persistent storage * @param dataStorePutFunction Function called to put objects in persistent storage - * @param virtualNetworkConfigCallback Function to be called when virtual LANs are created, deleted, or their config parameters change + * @param virtualNetworkConfigFunction Function to be called when virtual LANs are created, deleted, or their config parameters change * @param statusCallback Function to receive status updates and non-fatal error notices * @return OK (0) or error code if a fatal error condition has occurred */ @@ -633,7 +657,7 @@ enum ZT1_ResultCode ZT1_Node_new( ZT1_DataStorePutFunction dataStorePutFunction, ZT1_WirePacketSendFunction wirePacketSendFunction, ZT1_VirtualNetworkFrameFunction virtualNetworkFrameFunction, - ZT1_VirtualNetworkConfigCallback virtualNetworkConfigCallback, + ZT1_VirtualNetworkConfigFunction virtualNetworkConfigFunction, ZT1_StatusCallback statusCallback); /** diff --git a/node/Network.cpp b/node/Network.cpp index dc6b87a0..7b033181 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -49,7 +49,8 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid) : _enabled(true), _lastConfigUpdate(0), _destroyed(false), - _netconfFailure(NETCONF_FAILURE_NONE) + _netconfFailure(NETCONF_FAILURE_NONE), + _portError(0) { char confn[128],mcdbn[128]; Utils::snprintf(confn,sizeof(confn),"networks.d/%.16llx.conf",_id); @@ -96,10 +97,16 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid) : } requestConfiguration(); + + ZT1_VirtualNetworkConfig ctmp; + _externalConfig(&ctmp); + _portError = RR->node->configureVirtualNetworkPort(_id,&ctmp); } Network::~Network() { + RR->node->configureVirtualNetworkPort(_id,(const ZT1_VirtualNetworkConfig *)0); + char n[128]; if (_destroyed) { Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.conf",_id); @@ -179,6 +186,11 @@ bool Network::applyConfiguration(const SharedPtr<NetworkConfig> &conf) _config = conf; _lastConfigUpdate = RR->node->now(); _netconfFailure = NETCONF_FAILURE_NONE; + + ZT1_VirtualNetworkConfig ctmp; + _externalConfig(&ctmp); + _portError = RR->node->configureVirtualNetworkPort(_id,&ctmp); + return true; } else { LOG("ignored invalid configuration for network %.16llx (configuration contains mismatched network ID or issued-to address)",(unsigned long long)_id); @@ -368,21 +380,6 @@ void Network::clean() } } -ZT1_VirtualNetworkStatus Network::status() const -{ - Mutex::Lock _l(_lock); - switch(_netconfFailure) { - case NETCONF_FAILURE_ACCESS_DENIED: - return ZT1_NETWORK_STATUS_ACCESS_DENIED; - case NETCONF_FAILURE_NOT_FOUND: - return ZT1_NETWORK_STATUS_NOT_FOUND; - case NETCONF_FAILURE_NONE: - return ((_lastConfigUpdate > 0) ? ZT1_NETWORK_STATUS_OK : ZT1_NETWORK_STATUS_REQUESTING_CONFIGURATION); - default: - return ZT1_NETWORK_STATUS_INITIALIZATION_FAILED; - } -} - void Network::learnBridgeRoute(const MAC &mac,const Address &addr) { Mutex::Lock _l(_lock); @@ -421,4 +418,53 @@ void Network::destroy() _destroyed = true; } +ZT1_VirtualNetworkStatus Network::_status() const +{ + // assumes _lock is locked + if (_portError) + return ZT1_NETWORK_STATUS_PORT_ERROR; + switch(_netconfFailure) { + case NETCONF_FAILURE_ACCESS_DENIED: + return ZT1_NETWORK_STATUS_ACCESS_DENIED; + case NETCONF_FAILURE_NOT_FOUND: + return ZT1_NETWORK_STATUS_NOT_FOUND; + case NETCONF_FAILURE_NONE: + return ((_lastConfigUpdate > 0) ? ZT1_NETWORK_STATUS_OK : ZT1_NETWORK_STATUS_REQUESTING_CONFIGURATION); + default: + return ZT1_NETWORK_STATUS_PORT_ERROR; + } +} + +void Network::_externalConfig(ZT1_VirtualNetworkConfig *ec) const +{ + // assumes _lock is locked + ec->nwid = _id; + ec->mac = MAC(RR->identity.address(),_id); + if (_config) + Utils::scopy(ec->name,sizeof(ec->name),_config->name().c_str()); + else ec->name[0] = (char)0; + ec->status = _status(); + ec->type = (_config) ? (_config->isPrivate() ? ZT1_NETWORK_TYPE_PRIVATE : ZT1_NETWORK_TYPE_PUBLIC) : ZT1_NETWORK_TYPE_PRIVATE; + ec->mtu = ZT_IF_MTU; + ec->dhcp = 0; + ec->bridge = (_config) ? ((_config->allowPassiveBridging() || (std::find(_config->activeBridges().begin(),_config->activeBridges().end(),RR->identity.address()) != _config->activeBridges().end())) ? 1 : 0) : 0; + ec->broadcastEnabled = (_config) ? (_config->enableBroadcast() ? 1 : 0) : 0; + ec->portError = _portError; + ec->netconfRevision = (_config) ? (unsigned long)_config->revision() : 0; + + ec->multicastSubscriptionCount = std::max((unsigned int)_myMulticastGroups.size(),(unsigned int)ZT1_MAX_NETWORK_MULTICAST_SUBSCRIPTIONS); + for(unsigned int i=0;i<ec->multicastSubscriptionCount;++i) { + ec->multicastSubscriptions[i].mac = _myMulticastGroups[i].mac().toInt(); + ec->multicastSubscriptions[i].adi = _myMulticastGroups[i].adi(); + } + + if (_config) { + ec->assignedAddressCount = (unsigned int)_config->staticIps().size(); + for(unsigned long i=0;i<ZT1_MAX_ZT_ASSIGNED_ADDRESSES;++i) { + if (i < _config->staticIps().size()) + memcpy(&(ec->assignedAddresses[i]),&(_config->staticIps()[i]),sizeof(struct sockaddr_storage)); + } + } else ec->assignedAddressCount = 0; +} + } // namespace ZeroTier diff --git a/node/Network.hpp b/node/Network.hpp index 5693ff49..b51164a3 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -192,7 +192,20 @@ public: /** * @return Status of this network */ - ZT1_VirtualNetworkStatus status() const; + inline ZT1_VirtualNetworkStatus status() const + { + Mutex::Lock _l(_lock); + return _status(); + } + + /** + * @param ec Buffer to fill with externally-visible network configuration + */ + inline void externalConfig(ZT1_VirtualNetworkConfig *ec) const + { + Mutex::Lock _l(_lock); + _externalConfig(ec); + } /** * Update and check multicast rate balance for a multicast group @@ -321,6 +334,9 @@ public: void destroy(); private: + ZT1_VirtualNetworkStatus _status() const; + void _externalConfig(ZT1_VirtualNetworkConfig *ec) const; // assumes _lock is locked + const RuntimeEnvironment *RR; uint64_t _id; MAC _mac; // local MAC address @@ -340,12 +356,13 @@ private: volatile bool _destroyed; - volatile enum { + enum { NETCONF_FAILURE_NONE, NETCONF_FAILURE_ACCESS_DENIED, NETCONF_FAILURE_NOT_FOUND, NETCONF_FAILURE_INIT_FAILED } _netconfFailure; + int _portError; // return value from port config callback Mutex _lock; diff --git a/node/NetworkConfig.cpp b/node/NetworkConfig.cpp index e42b0299..ba72a415 100644 --- a/node/NetworkConfig.cpp +++ b/node/NetworkConfig.cpp @@ -125,6 +125,8 @@ void NetworkConfig::_fromDictionary(const Dictionary &d) _private = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_PRIVATE,one).c_str()) != 0); _enableBroadcast = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_ENABLE_BROADCAST,one).c_str()) != 0); _name = d.get(ZT_NETWORKCONFIG_DICT_KEY_NAME); + if (_name.length() > ZT1_MAX_NETWORK_SHORT_NAME_LENGTH) + throw std::invalid_argument("network short name too long (max: 255 characters)"); _description = d.get(ZT_NETWORKCONFIG_DICT_KEY_DESC,std::string()); // In dictionary IPs are split into V4 and V6 addresses, but we don't really @@ -156,6 +158,8 @@ void NetworkConfig::_fromDictionary(const Dictionary &d) } _staticIps.push_back(addr); } + if (_staticIps.size() > ZT1_MAX_ZT_ASSIGNED_ADDRESSES) + throw std::invalid_argument("too many ZT-assigned IP addresses"); std::sort(_staticIps.begin(),_staticIps.end()); std::unique(_staticIps.begin(),_staticIps.end()); diff --git a/node/Node.cpp b/node/Node.cpp index f1d107f1..29262eda 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -54,14 +54,14 @@ Node::Node( ZT1_DataStorePutFunction dataStorePutFunction, ZT1_WirePacketSendFunction wirePacketSendFunction, ZT1_VirtualNetworkFrameFunction virtualNetworkFrameFunction, - ZT1_VirtualNetworkConfigCallback virtualNetworkConfigCallback, + ZT1_VirtualNetworkConfigFunction virtualNetworkConfigFunction, ZT1_StatusCallback statusCallback) : RR(new RuntimeEnvironment(this)), _dataStoreGetFunction(dataStoreGetFunction), _dataStorePutFunction(dataStorePutFunction), _wirePacketSendFunction(wirePacketSendFunction), _virtualNetworkFrameFunction(virtualNetworkFrameFunction), - _virtualNetworkConfigCallback(virtualNetworkConfigCallback), + _virtualNetworkConfigFunction(virtualNetworkConfigFunction), _statusCallback(statusCallback), _networks(), _networks_m(), @@ -217,12 +217,12 @@ enum ZT1_ResultCode ZT1_Node_new( ZT1_DataStorePutFunction dataStorePutFunction, ZT1_WirePacketSendFunction wirePacketSendFunction, ZT1_VirtualNetworkFrameFunction virtualNetworkFrameFunction, - ZT1_VirtualNetworkConfigCallback virtualNetworkConfigCallback, + ZT1_VirtualNetworkConfigFunction virtualNetworkConfigFunction, ZT1_StatusCallback statusCallback) { *node = (ZT1_Node *)0; try { - *node = reinterpret_cast<ZT1_Node *>(new ZeroTier::Node(now,dataStoreGetFunction,dataStorePutFunction,wirePacketSendFunction,virtualNetworkFrameFunction,virtualNetworkConfigCallback,statusCallback)); + *node = reinterpret_cast<ZT1_Node *>(new ZeroTier::Node(now,dataStoreGetFunction,dataStorePutFunction,wirePacketSendFunction,virtualNetworkFrameFunction,virtualNetworkConfigFunction,statusCallback)); return ZT1_RESULT_OK; } catch (std::bad_alloc &exc) { return ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY; diff --git a/node/Node.hpp b/node/Node.hpp index fe704532..5b158228 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -61,7 +61,7 @@ public: ZT1_DataStorePutFunction dataStorePutFunction, ZT1_WirePacketSendFunction wirePacketSendFunction, ZT1_VirtualNetworkFrameFunction virtualNetworkFrameFunction, - ZT1_VirtualNetworkConfigCallback virtualNetworkConfigCallback, + ZT1_VirtualNetworkConfigFunction virtualNetworkConfigFunction, ZT1_StatusCallback statusCallback); ~Node(); @@ -115,16 +115,12 @@ public: */ inline bool putPacket(const InetAddress &addr,const void *data,unsigned int len,unsigned int desperation) { - try { - return (_wirePacketSendFunction( - reinterpret_cast<ZT1_Node *>(this), - reinterpret_cast<const struct sockaddr_storage *>(&addr), - desperation, - data, - len) == 0); - } catch ( ... ) { // callbacks should not throw - return false; - } + return (_wirePacketSendFunction( + reinterpret_cast<ZT1_Node *>(this), + reinterpret_cast<const struct sockaddr_storage *>(&addr), + desperation, + data, + len) == 0); } /** @@ -140,17 +136,15 @@ public: */ inline void putFrame(uint64_t nwid,const MAC &source,const MAC &dest,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) { - try { - _virtualNetworkFrameFunction( - reinterpret_cast<ZT1_Node *>(this), - nwid, - source.toInt(), - dest.toInt(), - etherType, - vlanId, - data, - len); - } catch ( ... ) {} // callbacks should not throw + _virtualNetworkFrameFunction( + reinterpret_cast<ZT1_Node *>(this), + nwid, + source.toInt(), + dest.toInt(), + etherType, + vlanId, + data, + len); } inline SharedPtr<Network> network(uint64_t nwid) @@ -167,6 +161,8 @@ public: inline void postEvent(ZT1_Event ev) { _statusCallback(reinterpret_cast<ZT1_Node *>(this),ev); } + inline int configureVirtualNetworkPort(uint64_t nwid,const ZT1_VirtualNetworkConfig *nc) { return _virtualNetworkConfigFunction(reinterpret_cast<ZT1_Node *>(this),nwid,nc); } + void postNewerVersionIfNewer(unsigned int major,unsigned int minor,unsigned int rev); private: @@ -176,7 +172,7 @@ private: ZT1_DataStorePutFunction _dataStorePutFunction; ZT1_WirePacketSendFunction _wirePacketSendFunction; ZT1_VirtualNetworkFrameFunction _virtualNetworkFrameFunction; - ZT1_VirtualNetworkConfigCallback _virtualNetworkConfigCallback; + ZT1_VirtualNetworkConfigFunction _virtualNetworkConfigFunction; ZT1_StatusCallback _statusCallback; //Dictionary _localConfig; // persisted as local.conf |