From 5e11cf637816121f79c3ed00370843e93b62b1c6 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 1 Feb 2017 12:32:06 -0800 Subject: [PATCH] Can't armor() a packet until all flags are set. --- node/Cluster.cpp | 6 ++---- node/Cluster.hpp | 5 ++--- node/Switch.cpp | 12 +++++++++++- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/node/Cluster.cpp b/node/Cluster.cpp index 16ef040b3..a24cf99d0 100644 --- a/node/Cluster.cpp +++ b/node/Cluster.cpp @@ -516,12 +516,11 @@ void Cluster::broadcastNetworkConfigChunk(const void *chunk,unsigned int len) } } -int Cluster::prepSendViaCluster(const Address &toPeerAddress,Packet &outp,bool encrypt) +int Cluster::prepSendViaCluster(const Address &toPeerAddress,void *peerSecret) { const uint64_t now = RR->node->now(); uint64_t mostRecentTs = 0; int mostRecentMemberId = -1; - uint8_t mostRecentSecretKey[ZT_PEER_SECRET_KEY_LENGTH]; { Mutex::Lock _l2(_remotePeers_m); std::map< std::pair,_RemotePeer >::const_iterator rpe(_remotePeers.lower_bound(std::pair(toPeerAddress,0))); @@ -530,7 +529,7 @@ int Cluster::prepSendViaCluster(const Address &toPeerAddress,Packet &outp,bool e break; else if (rpe->second.lastHavePeerReceived > mostRecentTs) { mostRecentTs = rpe->second.lastHavePeerReceived; - memcpy(mostRecentSecretKey,rpe->second.key,ZT_PEER_SECRET_KEY_LENGTH); + memcpy(peerSecret,rpe->second.key,ZT_PEER_SECRET_KEY_LENGTH); mostRecentMemberId = (int)rpe->first.second; } ++rpe; @@ -566,7 +565,6 @@ int Cluster::prepSendViaCluster(const Address &toPeerAddress,Packet &outp,bool e } } - outp.armor(mostRecentSecretKey,encrypt); return mostRecentMemberId; } else return -1; } diff --git a/node/Cluster.hpp b/node/Cluster.hpp index 7ebef0c9c..90ea3e7d4 100644 --- a/node/Cluster.hpp +++ b/node/Cluster.hpp @@ -285,11 +285,10 @@ public: * Note that outp is only armored (or modified at all) if the return value is a member ID. * * @param toPeerAddress Value of outp.destination(), simply to save additional lookup - * @param outp Packet to armor with peer key (via cluster knowledge of peer shared secret) - * @param encrypt If true, encrypt packet payload (passed to Packet::armor()) + * @param peerSecret Buffer to fill with peer secret on valid return value, must be at least ZT_PEER_SECRET_KEY_LENGTH bytes * @return -1 if cluster does not know this peer, or a member ID to pass to sendViaCluster() */ - int prepSendViaCluster(const Address &toPeerAddress,Packet &outp,bool encrypt); + int prepSendViaCluster(const Address &toPeerAddress,void *peerSecret); /** * Send data via cluster front plane (packet head or fragment) diff --git a/node/Switch.cpp b/node/Switch.cpp index 6df841019..d4f477f00 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -693,6 +693,7 @@ bool Switch::_trySend(Packet &packet,bool encrypt) const Address destination(packet.destination()); #ifdef ZT_ENABLE_CLUSTER int clusterMostRecentMemberId = -1; + uint8_t clusterPeerSecret[ZT_PEER_SECRET_KEY_LENGTH]; #endif const SharedPtr peer(RR->topology->getPeer(destination)); @@ -714,7 +715,7 @@ bool Switch::_trySend(Packet &packet,bool encrypt) if (!viaPath) { #ifdef ZT_ENABLE_CLUSTER if (RR->cluster) - clusterMostRecentMemberId = RR->cluster->prepSendViaCluster(destination,packet,encrypt); + clusterMostRecentMemberId = RR->cluster->prepSendViaCluster(destination,clusterPeerSecret); if (clusterMostRecentMemberId < 0) { #endif peer->tryMemorizedPath(now); // periodically attempt memorized or statically defined paths, if any are known @@ -751,12 +752,21 @@ bool Switch::_trySend(Packet &packet,bool encrypt) unsigned int chunkSize = std::min(packet.size(),(unsigned int)ZT_UDP_DEFAULT_PAYLOAD_MTU); packet.setFragmented(chunkSize < packet.size()); +#ifdef ZT_ENABLE_CLUSTER + const uint64_t trustedPathId = (viaPath) ? RR->topology->getOutboundPathTrust(viaPath->address()) : 0; + if (trustedPathId) { + packet.setTrusted(trustedPathId); + } else { + packet.armor((clusterMostRecentMemberId >= 0) ? clusterPeerSecret : peer->key(),encrypt); + } +#else const uint64_t trustedPathId = RR->topology->getOutboundPathTrust(viaPath->address()); if (trustedPathId) { packet.setTrusted(trustedPathId); } else { packet.armor(peer->key(),encrypt); } +#endif #ifdef ZT_ENABLE_CLUSTER if ( ((viaPath)&&(viaPath->send(RR,packet.data(),chunkSize,now))) || ((clusterMostRecentMemberId >= 0)&&(RR->cluster->sendViaCluster(clusterMostRecentMemberId,destination,packet.data(),chunkSize))) ) {