Browse Source

Can't armor() a packet until all flags are set.

Adam Ierymenko 8 years ago
parent
commit
5e11cf6378
3 changed files with 15 additions and 8 deletions
  1. 2 4
      node/Cluster.cpp
  2. 2 3
      node/Cluster.hpp
  3. 11 1
      node/Switch.cpp

+ 2 - 4
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();
 	const uint64_t now = RR->node->now();
 	uint64_t mostRecentTs = 0;
 	uint64_t mostRecentTs = 0;
 	int mostRecentMemberId = -1;
 	int mostRecentMemberId = -1;
-	uint8_t mostRecentSecretKey[ZT_PEER_SECRET_KEY_LENGTH];
 	{
 	{
 		Mutex::Lock _l2(_remotePeers_m);
 		Mutex::Lock _l2(_remotePeers_m);
 		std::map< std::pair<Address,unsigned int>,_RemotePeer >::const_iterator rpe(_remotePeers.lower_bound(std::pair<Address,unsigned int>(toPeerAddress,0)));
 		std::map< std::pair<Address,unsigned int>,_RemotePeer >::const_iterator rpe(_remotePeers.lower_bound(std::pair<Address,unsigned int>(toPeerAddress,0)));
@@ -530,7 +529,7 @@ int Cluster::prepSendViaCluster(const Address &toPeerAddress,Packet &outp,bool e
 				break;
 				break;
 			else if (rpe->second.lastHavePeerReceived > mostRecentTs) {
 			else if (rpe->second.lastHavePeerReceived > mostRecentTs) {
 				mostRecentTs = rpe->second.lastHavePeerReceived;
 				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;
 				mostRecentMemberId = (int)rpe->first.second;
 			}
 			}
 			++rpe;
 			++rpe;
@@ -566,7 +565,6 @@ int Cluster::prepSendViaCluster(const Address &toPeerAddress,Packet &outp,bool e
 			}
 			}
 		}
 		}
 
 
-		outp.armor(mostRecentSecretKey,encrypt);
 		return mostRecentMemberId;
 		return mostRecentMemberId;
 	} else return -1;
 	} else return -1;
 }
 }

+ 2 - 3
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.
 	 * 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 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()
 	 * @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)
 	 * Send data via cluster front plane (packet head or fragment)

+ 11 - 1
node/Switch.cpp

@@ -693,6 +693,7 @@ bool Switch::_trySend(Packet &packet,bool encrypt)
 	const Address destination(packet.destination());
 	const Address destination(packet.destination());
 #ifdef ZT_ENABLE_CLUSTER
 #ifdef ZT_ENABLE_CLUSTER
 	int clusterMostRecentMemberId = -1;
 	int clusterMostRecentMemberId = -1;
+	uint8_t clusterPeerSecret[ZT_PEER_SECRET_KEY_LENGTH];
 #endif
 #endif
 
 
 	const SharedPtr<Peer> peer(RR->topology->getPeer(destination));
 	const SharedPtr<Peer> peer(RR->topology->getPeer(destination));
@@ -714,7 +715,7 @@ bool Switch::_trySend(Packet &packet,bool encrypt)
 		if (!viaPath) {
 		if (!viaPath) {
 #ifdef ZT_ENABLE_CLUSTER
 #ifdef ZT_ENABLE_CLUSTER
 			if (RR->cluster)
 			if (RR->cluster)
-				clusterMostRecentMemberId = RR->cluster->prepSendViaCluster(destination,packet,encrypt);
+				clusterMostRecentMemberId = RR->cluster->prepSendViaCluster(destination,clusterPeerSecret);
 			if (clusterMostRecentMemberId < 0) {
 			if (clusterMostRecentMemberId < 0) {
 #endif
 #endif
 				peer->tryMemorizedPath(now); // periodically attempt memorized or statically defined paths, if any are known
 				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);
 	unsigned int chunkSize = std::min(packet.size(),(unsigned int)ZT_UDP_DEFAULT_PAYLOAD_MTU);
 	packet.setFragmented(chunkSize < packet.size());
 	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());
 	const uint64_t trustedPathId = RR->topology->getOutboundPathTrust(viaPath->address());
 	if (trustedPathId) {
 	if (trustedPathId) {
 		packet.setTrusted(trustedPathId);
 		packet.setTrusted(trustedPathId);
 	} else {
 	} else {
 		packet.armor(peer->key(),encrypt);
 		packet.armor(peer->key(),encrypt);
 	}
 	}
+#endif
 
 
 #ifdef ZT_ENABLE_CLUSTER
 #ifdef ZT_ENABLE_CLUSTER
 	if ( ((viaPath)&&(viaPath->send(RR,packet.data(),chunkSize,now))) || ((clusterMostRecentMemberId >= 0)&&(RR->cluster->sendViaCluster(clusterMostRecentMemberId,destination,packet.data(),chunkSize))) ) {
 	if ( ((viaPath)&&(viaPath->send(RR,packet.data(),chunkSize,now))) || ((clusterMostRecentMemberId >= 0)&&(RR->cluster->sendViaCluster(clusterMostRecentMemberId,destination,packet.data(),chunkSize))) ) {