summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--controller/EmbeddedNetworkController.cpp2
-rw-r--r--include/ZeroTierOne.h21
-rw-r--r--node/Network.cpp7
-rw-r--r--node/Network.hpp5
-rw-r--r--node/Node.cpp32
-rw-r--r--node/Node.hpp1
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,