Преглед изворни кода

Cleanup and stub out new object transfer messages.

Adam Ierymenko пре 9 година
родитељ
комит
4929be08f7
4 измењених фајлова са 77 додато и 59 уклоњено
  1. 11 21
      node/IncomingPacket.cpp
  2. 2 1
      node/IncomingPacket.hpp
  3. 2 1
      node/Packet.cpp
  4. 62 36
      node/Packet.hpp

+ 11 - 21
node/IncomingPacket.cpp

@@ -108,7 +108,6 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,bool deferred)
 				case Packet::VERB_MULTICAST_LIKE:                 return _doMULTICAST_LIKE(RR,peer);
 				case Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE: return _doNETWORK_MEMBERSHIP_CERTIFICATE(RR,peer);
 				case Packet::VERB_NETWORK_CONFIG_REQUEST:         return _doNETWORK_CONFIG_REQUEST(RR,peer);
-				case Packet::VERB_NETWORK_CONFIG_REFRESH:         return _doNETWORK_CONFIG_REFRESH(RR,peer);
 				case Packet::VERB_MULTICAST_GATHER:               return _doMULTICAST_GATHER(RR,peer);
 				case Packet::VERB_MULTICAST_FRAME:                return _doMULTICAST_FRAME(RR,peer);
 				case Packet::VERB_PUSH_DIRECT_PATHS:              return _doPUSH_DIRECT_PATHS(RR,peer);
@@ -162,8 +161,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer>
 
 			case Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE: {
 				/* Note: certificates are public so it's safe to push them to anyone
-				 * who asks. We won't communicate unless we also get a certificate
-				 * from the remote that agrees. */
+				 * who asks. */
 				SharedPtr<Network> network(RR->node->network(at<uint64_t>(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD)));
 				if ((network)&&(network->hasConfig())&&(network->config().com)) {
 					Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE);
@@ -805,24 +803,6 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
 	return true;
 }
 
-bool IncomingPacket::_doNETWORK_CONFIG_REFRESH(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
-{
-	try {
-		unsigned int ptr = ZT_PACKET_IDX_PAYLOAD;
-		while ((ptr + 8) <= size()) {
-			uint64_t nwid = at<uint64_t>(ptr);
-			SharedPtr<Network> nw(RR->node->network(nwid));
-			if ((nw)&&(peer->address() == nw->controller()))
-				nw->requestConfiguration();
-			ptr += 8;
-		}
-		peer->received(_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_CONFIG_REFRESH,0,Packet::VERB_NOP);
-	} catch ( ... ) {
-		TRACE("dropped NETWORK_CONFIG_REFRESH from %s(%s): unexpected exception",source().toString().c_str(),_remoteAddress.toString().c_str());
-	}
-	return true;
-}
-
 bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
 {
 	try {
@@ -1320,6 +1300,16 @@ bool IncomingPacket::_doREQUEST_PROOF_OF_WORK(const RuntimeEnvironment *RR,const
 	return true;
 }
 
+bool IncomingPacket::_doREQUEST_OBJECT(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
+{
+	return true;
+}
+
+bool IncomingPacket::_doOBJECT_UPDATED(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
+{
+	return true;
+}
+
 void IncomingPacket::computeSalsa2012Sha512ProofOfWork(unsigned int difficulty,const void *challenge,unsigned int challengeLength,unsigned char result[16])
 {
 	unsigned char salsabuf[131072]; // 131072 == protocol constant, size of memory buffer for this proof of work function

+ 2 - 1
node/IncomingPacket.hpp

@@ -174,13 +174,14 @@ private:
 	bool _doMULTICAST_LIKE(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
 	bool _doNETWORK_MEMBERSHIP_CERTIFICATE(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
 	bool _doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
-	bool _doNETWORK_CONFIG_REFRESH(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
 	bool _doMULTICAST_GATHER(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
 	bool _doMULTICAST_FRAME(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
 	bool _doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
 	bool _doCIRCUIT_TEST(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
 	bool _doCIRCUIT_TEST_REPORT(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
 	bool _doREQUEST_PROOF_OF_WORK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+	bool _doREQUEST_OBJECT(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
+	bool _doOBJECT_UPDATED(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
 
 	// Send an ERROR_NEED_MEMBERSHIP_CERTIFICATE to a peer indicating that an updated cert is needed to communicate
 	void _sendErrorNeedCertificate(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer,uint64_t nwid);

+ 2 - 1
node/Packet.cpp

@@ -40,13 +40,14 @@ const char *Packet::verbString(Verb v)
 		case VERB_MULTICAST_LIKE: return "MULTICAST_LIKE";
 		case VERB_NETWORK_MEMBERSHIP_CERTIFICATE: return "NETWORK_MEMBERSHIP_CERTIFICATE";
 		case VERB_NETWORK_CONFIG_REQUEST: return "NETWORK_CONFIG_REQUEST";
-		case VERB_NETWORK_CONFIG_REFRESH: return "NETWORK_CONFIG_REFRESH";
 		case VERB_MULTICAST_GATHER: return "MULTICAST_GATHER";
 		case VERB_MULTICAST_FRAME: return "MULTICAST_FRAME";
 		case VERB_PUSH_DIRECT_PATHS: return "PUSH_DIRECT_PATHS";
 		case VERB_CIRCUIT_TEST: return "CIRCUIT_TEST";
 		case VERB_CIRCUIT_TEST_REPORT: return "CIRCUIT_TEST_REPORT";
 		case VERB_REQUEST_PROOF_OF_WORK: return "REQUEST_PROOF_OF_WORK";
+		case VERB_REQUEST_OBJECT: return "REQUEST_OBJECT";
+		case VERB_OBJECT_UPDATED: return "OBJECT_UPDATED";
 	}
 	return "(unknown)";
 }

+ 62 - 36
node/Packet.hpp

@@ -715,53 +715,23 @@ public:
 		VERB_NETWORK_MEMBERSHIP_CERTIFICATE = 10,
 
 		/**
-		 * Network configuration request:
-		 *   <[8] 64-bit network ID>
-		 *   <[2] 16-bit length of request meta-data dictionary>
-		 *   <[...] string-serialized request meta-data>
-		 *  [<[8] 64-bit revision of netconf we currently have>]
+		 * DEPRECATED but still supported, interpreted as an object request:
+		 *
+		 * /controller/network/<network ID>/member/<requester address>
 		 *
-		 * This message requests network configuration from a node capable of
-		 * providing it. If the optional revision is included, a response is
-		 * only generated if there is a newer network configuration available.
+		 * When received in this manner the response is sent via the old
+		 * OK(NETWORK_CONFIG_REQUEST) instead of OK(REQUEST_OBJECT).
 		 *
 		 * OK response payload:
 		 *   <[8] 64-bit network ID>
 		 *   <[2] 16-bit length of network configuration dictionary>
 		 *   <[...] network configuration dictionary>
 		 *
-		 * OK returns a Dictionary (string serialized) containing the network's
-		 * configuration and IP address assignment information for the querying
-		 * node. It also contains a membership certificate that the querying
-		 * node can push to other peers to demonstrate its right to speak on
-		 * a given network.
-		 *
-		 * When a new network configuration is received, another config request
-		 * should be sent with the new netconf's revision. This confirms receipt
-		 * and also causes any subsequent changes to rapidly propagate as this
-		 * cycle will repeat until there are no changes. This is optional but
-		 * recommended behavior.
-		 *
 		 * ERROR response payload:
 		 *   <[8] 64-bit network ID>
-		 *
-		 * UNSUPPORTED_OPERATION is returned if this service is not supported,
-		 * and OBJ_NOT_FOUND if the queried network ID was not found.
 		 */
 		VERB_NETWORK_CONFIG_REQUEST = 11,
 
-		/**
-		 * Network configuration refresh request:
-		 *   <[...] array of 64-bit network IDs>
-		 *
-		 * This can be sent by the network controller to inform a node that it
-		 * should now make a NETWORK_CONFIG_REQUEST.
-		 *
-		 * It does not generate an OK or ERROR message, and is treated only as
-		 * a hint to refresh now.
-		 */
-		VERB_NETWORK_CONFIG_REFRESH = 12,
-
 		/**
 		 * Request endpoints for multicast distribution:
 		 *   <[8] 64-bit network ID>
@@ -1030,7 +1000,63 @@ public:
 		 *
 		 * ERROR has no payload.
 		 */
-		VERB_REQUEST_PROOF_OF_WORK = 19
+		VERB_REQUEST_PROOF_OF_WORK = 19,
+
+		/**
+		 * Request an object or a chunk of an object with optional meta-data:
+		 *   <[8] 64-bit chunk offset>
+		 *   <[2] 16-bit chunk length or 0 for any / sender-preferred>
+		 *   <[2] 16-bit object path length in bytes>
+		 *   <[...] object path>
+		 *   <[2] 16-bit length of request meta-data dictionary>
+		 *   <[...] request meta-data dictionary>
+		 *
+		 * This is used to request an object. Objects can be things like network
+		 * configs, software updates, etc. This provides an in-band way to
+		 * distribute such things and obsoletes the network config specific
+		 * messages. (They are still supported for backward compatibility.)
+		 *
+		 * The use of path and request/response meta-data makes the semantics of
+		 * this analogous to HTTP POST, and it could therefore be mapped to
+		 * HTTP POST requests to permit plugins that leverage the ZT protocol
+		 * to do out-of-band things like special authentication, etc.
+		 *
+		 * Large objects can be transferred via repeated calls with higher and
+		 * higher chunk offsets and then SHA-512 verified on receipt, but this is
+		 * not efficient. It should not be used heavily as an alternative to
+		 * TCP. It's a bit more like X-Modem and other old-school SEND/ACK
+		 * protocols. It is potentially a good idea for software updates since
+		 * it means that ZT can update itself even on networks with no "vanilla"
+		 * Internet access.
+		 *
+		 * OK and ERROR responses are optional but recommended. ERROR responses
+		 * can include OBJECT_NOT_FOUND.
+		 *
+		 * OK response payload:
+		 *   <[16] first 16 bytes of SHA-512 of complete object>
+		 *   <[8] 64-bit total object size>
+		 *   <[8] 64-bit chunk offset>
+		 *   <[2] 16-bit length of chunk payload>
+		 *   <[...] chunk payload>
+		 */
+		VERB_REQUEST_OBJECT = 20,
+
+		/**
+		 * Notification of a remote object update:
+		 *   <[8] 64-bit total object size or 0 if unspecified here>
+		 *   <[16] first 16 bytes of SHA-512 of object (if size specified)>
+		 *   <[2] 16-bit length of object path>
+		 *   <[...] object path>
+		 *   <[2] 16-bit length of meta-data dictionary>
+		 *   <[...] meta-data dictionary>
+		 *
+		 * This can be sent to notify another peer that an object has updated and
+		 * should be re-requested. The receiving peer is not required to do anything
+		 * or send anything in response to this. If the first size field is zero, the
+		 * SHA-512 hash is also unspecified and should be zero. This means that the
+		 * object was updated but must be re-requested.
+		 */
+		VERB_OBJECT_UPDATED = 21
 	};
 
 	/**