diff options
-rw-r--r-- | controller/EmbeddedNetworkController.cpp | 2 | ||||
-rw-r--r-- | include/ZeroTierOne.h | 21 | ||||
-rw-r--r-- | node/Network.cpp | 7 | ||||
-rw-r--r-- | node/Network.hpp | 5 | ||||
-rw-r--r-- | node/Node.cpp | 32 | ||||
-rw-r--r-- | node/Node.hpp | 1 |
6 files changed, 68 insertions, 0 deletions
diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp index 0a4a17f8..9cf43b79 100644 --- a/controller/EmbeddedNetworkController.cpp +++ b/controller/EmbeddedNetworkController.cpp @@ -1081,6 +1081,8 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST( _writeJson(_memberJP(nwid,Address(address),true).c_str(),member); + _node->pushNetworkRefresh(address,nwid,(const uint64_t *)0,(const uint64_t *)0,0); + // Add non-persisted fields member["clock"] = now; diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index 5864e346..906edef2 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -1854,6 +1854,27 @@ enum ZT_ResultCode ZT_Node_circuitTestBegin(ZT_Node *node,ZT_CircuitTest *test,v void ZT_Node_circuitTestEnd(ZT_Node *node,ZT_CircuitTest *test); /** + * Push a network refresh + * + * This is used by network controller implementations to send a + * NETWORK_CONFIG_REFRESH message to tell a node to refresh its + * config and to optionally push one or more credential timestamp + * blacklist thresholds for members of the network. + * + * Code outside a controller implementation will have no use for + * this as these messages are ignored if they do not come from a + * controller. + * + * @param node Node instance + * @param dest ZeroTier address of destination to which to send NETWORK_CONFIG_REFRESH + * @param nwid Network ID + * @param blacklistAddresses Array of ZeroTier addresses of network members to set timestamp blacklists for + * @param blacklistBeforeTimestamps Timestamps before which to blacklist credentials for each corresponding address in blacklistAddresses[] + * @param blacklistCount Size of blacklistAddresses[] and blacklistBeforeTimestamps[] + */ +void ZT_Node_pushNetworkRefresh(ZT_Node *node,uint64_t dest,uint64_t nwid,const uint64_t *blacklistAddresses,const uint64_t *blacklistBeforeTimestamps,unsigned int blacklistCount); + +/** * Initialize cluster operation * * This initializes the internal structures and state for cluster operation. diff --git a/node/Network.cpp b/node/Network.cpp index e12dd027..97341ee2 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -402,6 +402,7 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid,void *uptr) : _portInitialized(false), _inboundConfigPacketId(0), _lastConfigUpdate(0), + _lastRequestedConfiguration(0), _destroyed(false), _netconfFailure(NETCONF_FAILURE_NONE), _portError(0) @@ -691,6 +692,12 @@ void Network::handleInboundConfigChunk(const uint64_t inRePacketId,const void *d void Network::requestConfiguration() { + // Sanity limit: do not request more often than once per second + const uint64_t now = RR->node->now(); + if ((now - _lastRequestedConfiguration) < 1000ULL) + return; + _lastRequestedConfiguration = RR->node->now(); + Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> rmd; rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,(uint64_t)ZT_NETWORKCONFIG_VERSION); rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION,(uint64_t)ZT_PROTO_VERSION); diff --git a/node/Network.hpp b/node/Network.hpp index 37154dc7..382b16aa 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -249,6 +249,10 @@ public: /** * Causes this network to request an updated configuration from its master node now + * + * There is a circuit breaker here to prevent this from being done more often + * than once per second. This is to prevent things like NETWORK_CONFIG_REFRESH + * from causing multiple requests. */ void requestConfiguration(); @@ -442,6 +446,7 @@ private: NetworkConfig _config; volatile uint64_t _lastConfigUpdate; + volatile uint64_t _lastRequestedConfiguration; volatile bool _destroyed; diff --git a/node/Node.cpp b/node/Node.cpp index 4da79347..ff564eee 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -548,6 +548,31 @@ void Node::circuitTestEnd(ZT_CircuitTest *test) } } +void Node::pushNetworkRefresh(uint64_t dest,uint64_t nwid,const uint64_t *blacklistAddresses,const uint64_t *blacklistBeforeTimestamps,unsigned int blacklistCount) +{ + Packet outp(Address(dest),RR->identity.address(),Packet::VERB_NETWORK_CONFIG_REFRESH); + outp.append(nwid); + outp.addSize(2); + unsigned int c = 0; + for(unsigned int i=0;i<blacklistCount;++i) { + if ((outp.size() + 13) >= ZT_PROTO_MAX_PACKET_LENGTH) { + outp.setAt<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 8,(uint16_t)c); + RR->sw->send(outp,true); + outp = Packet(Address(dest),RR->identity.address(),Packet::VERB_NETWORK_CONFIG_REFRESH); + outp.append(nwid); + outp.addSize(2); + c = 0; + } + Address(blacklistAddresses[i]).appendTo(outp); + outp.append(blacklistBeforeTimestamps[i]); + ++c; + } + if (c > 0) { + outp.setAt<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 8,(uint16_t)c); + RR->sw->send(outp,true); + } +} + ZT_ResultCode Node::clusterInit( unsigned int myId, const struct sockaddr_storage *zeroTierPhysicalEndpoints, @@ -935,6 +960,13 @@ void ZT_Node_circuitTestEnd(ZT_Node *node,ZT_CircuitTest *test) } catch ( ... ) {} } +void ZT_Node_pushNetworkRefresh(ZT_Node *node,uint64_t dest,uint64_t nwid,const uint64_t *blacklistAddresses,const uint64_t *blacklistBeforeTimestamps,unsigned int blacklistCount) +{ + try { + reinterpret_cast<ZeroTier::Node *>(node)->pushNetworkRefresh(dest,nwid,blacklistAddresses,blacklistBeforeTimestamps,blacklistCount); + } catch ( ... ) {} +} + enum ZT_ResultCode ZT_Node_clusterInit( ZT_Node *node, unsigned int myId, diff --git a/node/Node.hpp b/node/Node.hpp index 98c4fd7c..3c0a5e92 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -102,6 +102,7 @@ public: void setNetconfMaster(void *networkControllerInstance); ZT_ResultCode circuitTestBegin(ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *)); void circuitTestEnd(ZT_CircuitTest *test); + void pushNetworkRefresh(uint64_t dest,uint64_t nwid,const uint64_t *blacklistAddresses,const uint64_t *blacklistBeforeTimestamps,unsigned int blacklistCount); ZT_ResultCode clusterInit( unsigned int myId, const struct sockaddr_storage *zeroTierPhysicalEndpoints, |