mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-02-07 11:50:13 +00:00
Fix to cluster network configs.
This commit is contained in:
parent
eebd271bb1
commit
ed31cb76d6
@ -476,7 +476,7 @@ void Cluster::handleIncomingStateMessage(const void *msg,unsigned int len)
|
|||||||
if (network) {
|
if (network) {
|
||||||
// Copy into a Packet just to conform to Network API. Eventually
|
// Copy into a Packet just to conform to Network API. Eventually
|
||||||
// will want to refactor.
|
// will want to refactor.
|
||||||
network->handleConfigChunk(Packet(dmsg),ptr);
|
network->handleConfigChunk(0,Address(),Packet(dmsg),ptr);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
@ -461,12 +461,8 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p
|
|||||||
|
|
||||||
case Packet::VERB_NETWORK_CONFIG_REQUEST: {
|
case Packet::VERB_NETWORK_CONFIG_REQUEST: {
|
||||||
const SharedPtr<Network> network(RR->node->network(at<uint64_t>(ZT_PROTO_VERB_OK_IDX_PAYLOAD)));
|
const SharedPtr<Network> network(RR->node->network(at<uint64_t>(ZT_PROTO_VERB_OK_IDX_PAYLOAD)));
|
||||||
if (network) {
|
if (network)
|
||||||
#ifdef ZT_ENABLE_CLUSTER
|
network->handleConfigChunk(packetId(),source(),*this,ZT_PROTO_VERB_OK_IDX_PAYLOAD);
|
||||||
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;
|
} break;
|
||||||
|
|
||||||
case Packet::VERB_MULTICAST_GATHER: {
|
case Packet::VERB_MULTICAST_GATHER: {
|
||||||
@ -926,10 +922,7 @@ bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment *RR,const Shared
|
|||||||
try {
|
try {
|
||||||
const SharedPtr<Network> network(RR->node->network(at<uint64_t>(ZT_PACKET_IDX_PAYLOAD)));
|
const SharedPtr<Network> network(RR->node->network(at<uint64_t>(ZT_PACKET_IDX_PAYLOAD)));
|
||||||
if (network) {
|
if (network) {
|
||||||
#ifdef ZT_ENABLE_CLUSTER
|
const uint64_t configUpdateId = network->handleConfigChunk(packetId(),source(),*this,ZT_PACKET_IDX_PAYLOAD);
|
||||||
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) {
|
if (configUpdateId) {
|
||||||
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK);
|
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK);
|
||||||
outp.append((uint8_t)Packet::VERB_ECHO);
|
outp.append((uint8_t)Packet::VERB_ECHO);
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "NetworkController.hpp"
|
#include "NetworkController.hpp"
|
||||||
#include "Node.hpp"
|
#include "Node.hpp"
|
||||||
#include "Peer.hpp"
|
#include "Peer.hpp"
|
||||||
|
#include "Cluster.hpp"
|
||||||
|
|
||||||
// Uncomment to make the rules engine dump trace info to stdout
|
// Uncomment to make the rules engine dump trace info to stdout
|
||||||
//#define ZT_RULES_ENGINE_DEBUGGING 1
|
//#define ZT_RULES_ENGINE_DEBUGGING 1
|
||||||
@ -908,7 +909,7 @@ void Network::multicastUnsubscribe(const MulticastGroup &mg)
|
|||||||
_myMulticastGroups.erase(i);
|
_myMulticastGroups.erase(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t Network::handleConfigChunk(const Packet &chunk,unsigned int ptr)
|
uint64_t Network::handleConfigChunk(const uint64_t packetId,const Address &source,const Buffer<ZT_PROTO_MAX_PACKET_LENGTH> &chunk,unsigned int ptr)
|
||||||
{
|
{
|
||||||
const unsigned int start = ptr;
|
const unsigned int start = ptr;
|
||||||
|
|
||||||
@ -931,12 +932,12 @@ uint64_t Network::handleConfigChunk(const Packet &chunk,unsigned int ptr)
|
|||||||
chunkIndex = chunk.at<uint32_t>(ptr); ptr += 4;
|
chunkIndex = chunk.at<uint32_t>(ptr); ptr += 4;
|
||||||
|
|
||||||
if (((chunkIndex + chunkLen) > totalLength)||(totalLength >= ZT_NETWORKCONFIG_DICT_CAPACITY)) { // >= since we need room for a null at the end
|
if (((chunkIndex + chunkLen) > totalLength)||(totalLength >= ZT_NETWORKCONFIG_DICT_CAPACITY)) { // >= since we need room for a null at the end
|
||||||
TRACE("discarded chunk from %s: invalid length or length overflow",chunk.source().toString().c_str());
|
TRACE("discarded chunk from %s: invalid length or length overflow",source.toString().c_str());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((chunk[ptr] != 1)||(chunk.at<uint16_t>(ptr + 1) != ZT_C25519_SIGNATURE_LEN)) {
|
if ((chunk[ptr] != 1)||(chunk.at<uint16_t>(ptr + 1) != ZT_C25519_SIGNATURE_LEN)) {
|
||||||
TRACE("discarded chunk from %s: unrecognized signature type",chunk.source().toString().c_str());
|
TRACE("discarded chunk from %s: unrecognized signature type",source.toString().c_str());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
const uint8_t *sig = reinterpret_cast<const uint8_t *>(chunk.field(ptr + 3,ZT_C25519_SIGNATURE_LEN));
|
const uint8_t *sig = reinterpret_cast<const uint8_t *>(chunk.field(ptr + 3,ZT_C25519_SIGNATURE_LEN));
|
||||||
@ -964,30 +965,35 @@ uint64_t Network::handleConfigChunk(const Packet &chunk,unsigned int ptr)
|
|||||||
// If it's not a duplicate, check chunk signature
|
// If it's not a duplicate, check chunk signature
|
||||||
const Identity controllerId(RR->topology->getIdentity(controller()));
|
const Identity controllerId(RR->topology->getIdentity(controller()));
|
||||||
if (!controllerId) { // we should always have the controller identity by now, otherwise how would we have queried it the first time?
|
if (!controllerId) { // we should always have the controller identity by now, otherwise how would we have queried it the first time?
|
||||||
TRACE("unable to verify chunk from %s: don't have controller identity",chunk.source().toString().c_str());
|
TRACE("unable to verify chunk from %s: don't have controller identity",source.toString().c_str());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!controllerId.verify(chunk.field(start,ptr - start),ptr - start,sig,ZT_C25519_SIGNATURE_LEN)) {
|
if (!controllerId.verify(chunk.field(start,ptr - start),ptr - start,sig,ZT_C25519_SIGNATURE_LEN)) {
|
||||||
TRACE("discarded chunk from %s: signature check failed",chunk.source().toString().c_str());
|
TRACE("discarded chunk from %s: signature check failed",source.toString().c_str());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ZT_ENABLE_CLUSTER
|
||||||
|
if (source)
|
||||||
|
RR->cluster->broadcastNetworkConfigChunk(chunk.field(start,chunk.size() - start),chunk.size() - start);
|
||||||
|
#endif
|
||||||
|
|
||||||
// New properly verified chunks can be flooded "virally" through the network
|
// New properly verified chunks can be flooded "virally" through the network
|
||||||
if (fastPropagate) {
|
if (fastPropagate) {
|
||||||
Address *a = (Address *)0;
|
Address *a = (Address *)0;
|
||||||
Membership *m = (Membership *)0;
|
Membership *m = (Membership *)0;
|
||||||
Hashtable<Address,Membership>::Iterator i(_memberships);
|
Hashtable<Address,Membership>::Iterator i(_memberships);
|
||||||
while (i.next(a,m)) {
|
while (i.next(a,m)) {
|
||||||
if ((*a != chunk.source())&&(*a != controller())) {
|
if ((*a != source)&&(*a != controller())) {
|
||||||
Packet outp(*a,RR->identity.address(),Packet::VERB_NETWORK_CONFIG);
|
Packet outp(*a,RR->identity.address(),Packet::VERB_NETWORK_CONFIG);
|
||||||
outp.append(reinterpret_cast<const uint8_t *>(chunk.data()) + start,chunk.size() - start);
|
outp.append(reinterpret_cast<const uint8_t *>(chunk.data()) + start,chunk.size() - start);
|
||||||
RR->sw->send(outp,true);
|
RR->sw->send(outp,true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (chunk.source() == controller()) {
|
} else if ((source == controller())||(!source)) { // since old chunks aren't signed, only accept from controller itself (or via cluster backplane)
|
||||||
// Legacy support for OK(NETWORK_CONFIG_REQUEST) from older controllers
|
// Legacy support for OK(NETWORK_CONFIG_REQUEST) from older controllers
|
||||||
chunkId = chunk.packetId();
|
chunkId = packetId;
|
||||||
configUpdateId = chunkId;
|
configUpdateId = chunkId;
|
||||||
totalLength = chunkLen;
|
totalLength = chunkLen;
|
||||||
chunkIndex = 0;
|
chunkIndex = 0;
|
||||||
@ -999,6 +1005,11 @@ uint64_t Network::handleConfigChunk(const Packet &chunk,unsigned int ptr)
|
|||||||
if ((!c)||(_incomingConfigChunks[i].ts < c->ts))
|
if ((!c)||(_incomingConfigChunks[i].ts < c->ts))
|
||||||
c = &(_incomingConfigChunks[i]);
|
c = &(_incomingConfigChunks[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ZT_ENABLE_CLUSTER
|
||||||
|
if (source)
|
||||||
|
RR->cluster->broadcastNetworkConfigChunk(chunk.field(start,chunk.size() - start),chunk.size() - start);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
TRACE("discarded single-chunk unsigned legacy config: this is only allowed if the sender is the controller itself");
|
TRACE("discarded single-chunk unsigned legacy config: this is only allowed if the sender is the controller itself");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -181,11 +181,13 @@ public:
|
|||||||
* chunks via OK(NETWORK_CONFIG_REQUEST) or NETWORK_CONFIG. It verifies
|
* chunks via OK(NETWORK_CONFIG_REQUEST) or NETWORK_CONFIG. It verifies
|
||||||
* each chunk and once assembled applies the configuration.
|
* each chunk and once assembled applies the configuration.
|
||||||
*
|
*
|
||||||
* @param chunk Packet containing chunk
|
* @param packetId Packet ID or 0 if none (e.g. via cluster path)
|
||||||
|
* @param source Address of sender of chunk or NULL if none (e.g. via cluster path)
|
||||||
|
* @param chunk Buffer containing chunk
|
||||||
* @param ptr Index of chunk and related fields in packet
|
* @param ptr Index of chunk and related fields in packet
|
||||||
* @return Update ID if update was fully assembled and accepted or 0 otherwise
|
* @return Update ID if update was fully assembled and accepted or 0 otherwise
|
||||||
*/
|
*/
|
||||||
uint64_t handleConfigChunk(const Packet &chunk,unsigned int ptr);
|
uint64_t handleConfigChunk(const uint64_t packetId,const Address &source,const Buffer<ZT_PROTO_MAX_PACKET_LENGTH> &chunk,unsigned int ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set network configuration
|
* Set network configuration
|
||||||
|
Loading…
x
Reference in New Issue
Block a user