diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2017-01-30 16:04:05 -0800 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2017-01-30 16:04:05 -0800 |
commit | ed31cb76d6c8e632456a554b79e05df0593b5e9c (patch) | |
tree | c34834252dde1d34764f03ea7698804c87835fda /node | |
parent | eebd271bb1e3ab0d25f48db07a1a3f1154215bc7 (diff) | |
download | infinitytier-ed31cb76d6c8e632456a554b79e05df0593b5e9c.tar.gz infinitytier-ed31cb76d6c8e632456a554b79e05df0593b5e9c.zip |
Fix to cluster network configs.
Diffstat (limited to 'node')
-rw-r--r-- | node/Cluster.cpp | 2 | ||||
-rw-r--r-- | node/IncomingPacket.cpp | 13 | ||||
-rw-r--r-- | node/Network.cpp | 27 | ||||
-rw-r--r-- | node/Network.hpp | 6 |
4 files changed, 27 insertions, 21 deletions
diff --git a/node/Cluster.cpp b/node/Cluster.cpp index 55503f63..b9359dc6 100644 --- a/node/Cluster.cpp +++ b/node/Cluster.cpp @@ -476,7 +476,7 @@ void Cluster::handleIncomingStateMessage(const void *msg,unsigned int len) if (network) { // Copy into a Packet just to conform to Network API. Eventually // will want to refactor. - network->handleConfigChunk(Packet(dmsg),ptr); + network->handleConfigChunk(0,Address(),Packet(dmsg),ptr); } } break; } diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index e703af59..c11b0377 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -461,12 +461,8 @@ 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) { -#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); - } + if (network) + network->handleConfigChunk(packetId(),source(),*this,ZT_PROTO_VERB_OK_IDX_PAYLOAD); } break; case Packet::VERB_MULTICAST_GATHER: { @@ -926,10 +922,7 @@ 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); + const uint64_t configUpdateId = network->handleConfigChunk(packetId(),source(),*this,ZT_PACKET_IDX_PAYLOAD); if (configUpdateId) { Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK); outp.append((uint8_t)Packet::VERB_ECHO); diff --git a/node/Network.cpp b/node/Network.cpp index ec1bcb33..320dcf39 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -34,6 +34,7 @@ #include "NetworkController.hpp" #include "Node.hpp" #include "Peer.hpp" +#include "Cluster.hpp" // Uncomment to make the rules engine dump trace info to stdout //#define ZT_RULES_ENGINE_DEBUGGING 1 @@ -908,7 +909,7 @@ void Network::multicastUnsubscribe(const MulticastGroup &mg) _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; @@ -931,12 +932,12 @@ uint64_t Network::handleConfigChunk(const Packet &chunk,unsigned int ptr) 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 - 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; } 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; } 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 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? - 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; } 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; } +#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 if (fastPropagate) { Address *a = (Address *)0; Membership *m = (Membership *)0; Hashtable<Address,Membership>::Iterator i(_memberships); 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); outp.append(reinterpret_cast<const uint8_t *>(chunk.data()) + start,chunk.size() - start); 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 - chunkId = chunk.packetId(); + chunkId = packetId; configUpdateId = chunkId; totalLength = chunkLen; chunkIndex = 0; @@ -999,6 +1005,11 @@ uint64_t Network::handleConfigChunk(const Packet &chunk,unsigned int ptr) if ((!c)||(_incomingConfigChunks[i].ts < c->ts)) c = &(_incomingConfigChunks[i]); } + +#ifdef ZT_ENABLE_CLUSTER + if (source) + RR->cluster->broadcastNetworkConfigChunk(chunk.field(start,chunk.size() - start),chunk.size() - start); +#endif } else { TRACE("discarded single-chunk unsigned legacy config: this is only allowed if the sender is the controller itself"); return 0; diff --git a/node/Network.hpp b/node/Network.hpp index 1627be58..85ee6e9a 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -181,11 +181,13 @@ public: * chunks via OK(NETWORK_CONFIG_REQUEST) or NETWORK_CONFIG. It verifies * 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 * @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 |