summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--node/Cluster.cpp19
-rw-r--r--node/Cluster.hpp15
-rw-r--r--node/IncomingPacket.cpp9
3 files changed, 38 insertions, 5 deletions
diff --git a/node/Cluster.cpp b/node/Cluster.cpp
index 2a261e51..55503f63 100644
--- a/node/Cluster.cpp
+++ b/node/Cluster.cpp
@@ -44,6 +44,7 @@
#include "Packet.hpp"
#include "Switch.hpp"
#include "Node.hpp"
+#include "Network.hpp"
#include "Array.hpp"
namespace ZeroTier {
@@ -469,6 +470,15 @@ void Cluster::handleIncomingStateMessage(const void *msg,unsigned int len)
RR->sw->send(outp,true);
//TRACE("[%u] proxy send %s to %s length %u",(unsigned int)fromMemberId,Packet::verbString(verb),rcpt.toString().c_str(),len);
} break;
+
+ case CLUSTER_MESSAGE_NETWORK_CONFIG: {
+ const SharedPtr<Network> network(RR->node->network(dmsg.at<uint64_t>(ptr)));
+ if (network) {
+ // Copy into a Packet just to conform to Network API. Eventually
+ // will want to refactor.
+ network->handleConfigChunk(Packet(dmsg),ptr);
+ }
+ } break;
}
} catch ( ... ) {
TRACE("invalid message of size %u type %d (inner decode), discarding",mlen,mtype);
@@ -494,6 +504,15 @@ void Cluster::broadcastHavePeer(const Identity &id)
}
}
+void Cluster::broadcastNetworkConfigChunk(const void *chunk,unsigned int len)
+{
+ Mutex::Lock _l(_memberIds_m);
+ for(std::vector<uint16_t>::const_iterator mid(_memberIds.begin());mid!=_memberIds.end();++mid) {
+ Mutex::Lock _l2(_members[*mid].lock);
+ _send(*mid,CLUSTER_MESSAGE_NETWORK_CONFIG,chunk,len);
+ }
+}
+
void Cluster::sendViaCluster(const Address &fromPeerAddress,const Address &toPeerAddress,const void *data,unsigned int len,bool unite)
{
if (len > ZT_PROTO_MAX_PACKET_LENGTH) // sanity check
diff --git a/node/Cluster.hpp b/node/Cluster.hpp
index dafbf425..aba3b8a9 100644
--- a/node/Cluster.hpp
+++ b/node/Cluster.hpp
@@ -216,14 +216,13 @@ public:
/**
* Replicate a network config for a network we belong to:
- * <[8] 64-bit network ID>
- * <[2] 16-bit length of network config>
- * <[...] serialized network config>
+ * <[...] network config chunk>
*
* This is used by clusters to avoid every member having to query
* for the same netconf for networks all members belong to.
*
- * TODO: not implemented yet!
+ * The first field of a network config chunk is the network ID,
+ * so this can be checked to look up the network on receipt.
*/
CLUSTER_MESSAGE_NETWORK_CONFIG = 7
};
@@ -268,6 +267,14 @@ public:
void broadcastHavePeer(const Identity &id);
/**
+ * Broadcast a network config chunk to other members of cluster
+ *
+ * @param chunk Chunk data
+ * @param len Length of chunk
+ */
+ void broadcastNetworkConfigChunk(const void *chunk,unsigned int len);
+
+ /**
* Send this packet via another node in this cluster if another node has this peer
*
* This is used in the outgoing packet and relaying logic in Switch to
diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp
index a3fbbefc..e703af59 100644
--- a/node/IncomingPacket.cpp
+++ b/node/IncomingPacket.cpp
@@ -461,8 +461,12 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p
case Packet::VERB_NETWORK_CONFIG_REQUEST: {
const SharedPtr<Network> network(RR->node->network(at<uint64_t>(ZT_PROTO_VERB_OK_IDX_PAYLOAD)));
- if (network)
+ if (network) {
+#ifdef ZT_ENABLE_CLUSTER
+ RR->cluster->broadcastNetworkConfigChunk(field(ZT_PACKET_IDX_PAYLOAD,size() - ZT_PROTO_VERB_OK_IDX_PAYLOAD),size() - ZT_PROTO_VERB_OK_IDX_PAYLOAD);
+#endif
network->handleConfigChunk(*this,ZT_PROTO_VERB_OK_IDX_PAYLOAD);
+ }
} break;
case Packet::VERB_MULTICAST_GATHER: {
@@ -922,6 +926,9 @@ bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment *RR,const Shared
try {
const SharedPtr<Network> network(RR->node->network(at<uint64_t>(ZT_PACKET_IDX_PAYLOAD)));
if (network) {
+#ifdef ZT_ENABLE_CLUSTER
+ RR->cluster->broadcastNetworkConfigChunk(field(ZT_PACKET_IDX_PAYLOAD,size() - ZT_PACKET_IDX_PAYLOAD),size() - ZT_PACKET_IDX_PAYLOAD);
+#endif
const uint64_t configUpdateId = network->handleConfigChunk(*this,ZT_PACKET_IDX_PAYLOAD);
if (configUpdateId) {
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK);