瀏覽代碼

Remove old circuit test code. Rules engine will let us do this much better and more simply.

Adam Ierymenko 8 年之前
父節點
當前提交
2ec88e8008

+ 0 - 125
controller/EmbeddedNetworkController.cpp

@@ -726,59 +726,6 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
 					responseContentType = "application/json";
 
 					return 200;
-				} else if ((path.size() == 3)&&(path[2] == "test")) {
-
-					Mutex::Lock _l(_tests_m);
-
-					_tests.push_back(ZT_CircuitTest());
-					ZT_CircuitTest *const test = &(_tests.back());
-					memset(test,0,sizeof(ZT_CircuitTest));
-
-					Utils::getSecureRandom(&(test->testId),sizeof(test->testId));
-					test->credentialNetworkId = nwid;
-					test->ptr = (void *)this;
-					json hops = b["hops"];
-					if (hops.is_array()) {
-						for(unsigned long i=0;i<hops.size();++i) {
-							json &hops2 = hops[i];
-							if (hops2.is_array()) {
-								for(unsigned long j=0;j<hops2.size();++j) {
-									std::string s = hops2[j];
-									test->hops[test->hopCount].addresses[test->hops[test->hopCount].breadth++] = Utils::hexStrToU64(s.c_str()) & 0xffffffffffULL;
-								}
-								++test->hopCount;
-							} else if (hops2.is_string()) {
-								std::string s = hops2;
-								test->hops[test->hopCount].addresses[test->hops[test->hopCount].breadth++] = Utils::hexStrToU64(s.c_str()) & 0xffffffffffULL;
-								++test->hopCount;
-							}
-						}
-					}
-					test->reportAtEveryHop = (OSUtils::jsonBool(b["reportAtEveryHop"],true) ? 1 : 0);
-
-					if (!test->hopCount) {
-						_tests.pop_back();
-						responseBody = "{ \"message\": \"a test must contain at least one hop\" }";
-						responseContentType = "application/json";
-						return 400;
-					}
-
-					test->timestamp = OSUtils::now();
-
-					if (_node) {
-						_node->circuitTestBegin((void *)0,test,&(EmbeddedNetworkController::_circuitTestCallback));
-					} else {
-						_tests.pop_back();
-						return 500;
-					}
-
-					char json[512];
-					Utils::snprintf(json,sizeof(json),"{\"testId\":\"%.16llx\",\"timestamp\":%llu}",test->testId,test->timestamp);
-					responseBody = json;
-					responseContentType = "application/json";
-
-					return 200;
-
 				} // else 404
 
 			} else {
@@ -1118,7 +1065,6 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpDELETE(
 void EmbeddedNetworkController::threadMain()
 	throw()
 {
-	uint64_t lastCircuitTestCheck = 0;
 	_RQEntry *qe = (_RQEntry *)0;
 	while ((_running)&&(_queue.get(qe))) {
 		try {
@@ -1153,80 +1099,9 @@ void EmbeddedNetworkController::threadMain()
 			}
 		} catch ( ... ) {}
 		delete qe;
-
-		if (_running) {
-			uint64_t now = OSUtils::now();
-			if ((now - lastCircuitTestCheck) > ZT_EMBEDDEDNETWORKCONTROLLER_CIRCUIT_TEST_EXPIRATION) {
-				lastCircuitTestCheck = now;
-				Mutex::Lock _l(_tests_m);
-				for(std::list< ZT_CircuitTest >::iterator i(_tests.begin());i!=_tests.end();) {
-					if ((now - i->timestamp) > ZT_EMBEDDEDNETWORKCONTROLLER_CIRCUIT_TEST_EXPIRATION) {
-						_node->circuitTestEnd(&(*i));
-						_tests.erase(i++);
-					} else ++i;
-				}
-			}
-		}
 	}
 }
 
-void EmbeddedNetworkController::_circuitTestCallback(ZT_Node *node,ZT_CircuitTest *test,const ZT_CircuitTestReport *report)
-{
-	char tmp[2048],id[128];
-	EmbeddedNetworkController *const self = reinterpret_cast<EmbeddedNetworkController *>(test->ptr);
-
-	if ((!test)||(!report)||(!test->credentialNetworkId)) return; // sanity check
-
-	const uint64_t now = OSUtils::now();
-	Utils::snprintf(id,sizeof(id),"network/%.16llx/test/%.16llx-%.16llx-%.10llx-%.10llx",test->credentialNetworkId,test->testId,now,report->upstream,report->current);
-	Utils::snprintf(tmp,sizeof(tmp),
-		"{\"id\": \"%s\","
-		"\"objtype\": \"circuit_test\","
-		"\"timestamp\": %llu,"
-		"\"networkId\": \"%.16llx\","
-		"\"testId\": \"%.16llx\","
-		"\"upstream\": \"%.10llx\","
-		"\"current\": \"%.10llx\","
-		"\"receivedTimestamp\": %llu,"
-		"\"sourcePacketId\": \"%.16llx\","
-		"\"flags\": %llu,"
-		"\"sourcePacketHopCount\": %u,"
-		"\"errorCode\": %u,"
-		"\"vendor\": %d,"
-		"\"protocolVersion\": %u,"
-		"\"majorVersion\": %u,"
-		"\"minorVersion\": %u,"
-		"\"revision\": %u,"
-		"\"platform\": %d,"
-		"\"architecture\": %d,"
-		"\"receivedOnLocalAddress\": \"%s\","
-		"\"receivedFromRemoteAddress\": \"%s\","
-		"\"receivedFromLinkQuality\": %f}",
-		id + 30, // last bit only, not leading path
-		(unsigned long long)test->timestamp,
-		(unsigned long long)test->credentialNetworkId,
-		(unsigned long long)test->testId,
-		(unsigned long long)report->upstream,
-		(unsigned long long)report->current,
-		(unsigned long long)now,
-		(unsigned long long)report->sourcePacketId,
-		(unsigned long long)report->flags,
-		report->sourcePacketHopCount,
-		report->errorCode,
-		(int)report->vendor,
-		report->protocolVersion,
-		report->majorVersion,
-		report->minorVersion,
-		report->revision,
-		(int)report->platform,
-		(int)report->architecture,
-		reinterpret_cast<const InetAddress *>(&(report->receivedOnLocalAddress))->toString().c_str(),
-		reinterpret_cast<const InetAddress *>(&(report->receivedFromRemoteAddress))->toString().c_str(),
-		((double)report->receivedFromLinkQuality / (double)ZT_PATH_LINK_QUALITY_MAX));
-
-	self->_db.writeRaw(id,std::string(tmp));
-}
-
 void EmbeddedNetworkController::_request(
 	uint64_t nwid,
 	const InetAddress &fromAddr,

+ 0 - 7
controller/EmbeddedNetworkController.hpp

@@ -45,9 +45,6 @@
 
 #include "JSONDB.hpp"
 
-// TTL for circuit tests
-#define ZT_EMBEDDEDNETWORKCONTROLLER_CIRCUIT_TEST_EXPIRATION 120000
-
 namespace ZeroTier {
 
 class Node;
@@ -110,7 +107,6 @@ private:
 		} type;
 	};
 
-	static void _circuitTestCallback(ZT_Node *node,ZT_CircuitTest *test,const ZT_CircuitTestReport *report);
 	void _request(uint64_t nwid,const InetAddress &fromAddr,uint64_t requestPacketId,const Identity &identity,const Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> &metaData);
 
 	inline void _startThreads()
@@ -219,9 +215,6 @@ private:
 	NetworkController::Sender *_sender;
 	Identity _signingId;
 
-	std::list< ZT_CircuitTest > _tests;
-	Mutex _tests_m;
-
 	struct _MemberStatusKey
 	{
 		_MemberStatusKey() : networkId(0),nodeId(0) {}

+ 0 - 226
include/ZeroTierOne.h

@@ -760,7 +760,6 @@ typedef struct
 	 */
 	uint64_t expiration;
 
-
 	struct {
 		uint64_t from;
 		uint64_t to;
@@ -1105,197 +1104,6 @@ typedef struct
 	unsigned long peerCount;
 } ZT_PeerList;
 
-/**
- * ZeroTier circuit test configuration and path
- */
-typedef struct {
-	/**
-	 * Test ID -- an arbitrary 64-bit identifier
-	 */
-	uint64_t testId;
-
-	/**
-	 * Timestamp -- sent with test and echoed back by each reporter
-	 */
-	uint64_t timestamp;
-
-	/**
-	 * Originator credential: network ID
-	 *
-	 * If this is nonzero, a network ID will be set for this test and
-	 * the originator must be its primary network controller. This is
-	 * currently the only authorization method available, so it must
-	 * be set to run a test.
-	 */
-	uint64_t credentialNetworkId;
-
-	/**
-	 * Hops in circuit test (a.k.a. FIFO for graph traversal)
-	 */
-	struct {
-		/**
-		 * Hop flags (currently unused, must be zero)
-		 */
-		unsigned int flags;
-
-		/**
-		 * Number of addresses in this hop (max: ZT_CIRCUIT_TEST_MAX_HOP_BREADTH)
-		 */
-		unsigned int breadth;
-
-		/**
-		 * 40-bit ZeroTier addresses (most significant 24 bits ignored)
-		 */
-		uint64_t addresses[ZT_CIRCUIT_TEST_MAX_HOP_BREADTH];
-	} hops[ZT_CIRCUIT_TEST_MAX_HOPS];
-
-	/**
-	 * Number of hops (max: ZT_CIRCUIT_TEST_MAX_HOPS)
-	 */
-	unsigned int hopCount;
-
-	/**
-	 * If non-zero, circuit test will report back at every hop
-	 */
-	int reportAtEveryHop;
-
-	/**
-	 * An arbitrary user-settable pointer
-	 */
-	void *ptr;
-
-	/**
-	 * Pointer for internal use -- initialize to zero and do not modify
-	 */
-	void *_internalPtr;
-} ZT_CircuitTest;
-
-/**
- * Circuit test result report
- */
-typedef struct {
-	/**
-	 * Sender of report (current hop)
-	 */
-	uint64_t current;
-
-	/**
-	 * Previous hop
-	 */
-	uint64_t upstream;
-
-	/**
-	 * 64-bit test ID
-	 */
-	uint64_t testId;
-
-	/**
-	 * Timestamp from original test (echoed back at each hop)
-	 */
-	uint64_t timestamp;
-
-	/**
-	 * 64-bit packet ID of packet received by the reporting device
-	 */
-	uint64_t sourcePacketId;
-
-	/**
-	 * Flags
-	 */
-	uint64_t flags;
-
-	/**
-	 * ZeroTier protocol-level hop count of packet received by reporting device (>0 indicates relayed)
-	 */
-	unsigned int sourcePacketHopCount;
-
-	/**
-	 * Error code (currently unused, will be zero)
-	 */
-	unsigned int errorCode;
-
-	/**
-	 * Remote device vendor ID
-	 */
-	enum ZT_Vendor vendor;
-
-	/**
-	 * Remote device protocol compliance version
-	 */
-	unsigned int protocolVersion;
-
-	/**
-	 * Software major version
-	 */
-	unsigned int majorVersion;
-
-	/**
-	 * Software minor version
-	 */
-	unsigned int minorVersion;
-
-	/**
-	 * Software revision
-	 */
-	unsigned int revision;
-
-	/**
-	 * Platform / OS
-	 */
-	enum ZT_Platform platform;
-
-	/**
-	 * System architecture
-	 */
-	enum ZT_Architecture architecture;
-
-	/**
-	 * Local device address on which packet was received by reporting device
-	 *
-	 * This may have ss_family equal to zero (null address) if unspecified.
-	 */
-	struct sockaddr_storage receivedOnLocalAddress;
-
-	/**
-	 * Remote address from which reporter received the test packet
-	 *
-	 * This may have ss_family set to zero (null address) if unspecified.
-	 */
-	struct sockaddr_storage receivedFromRemoteAddress;
-
-	/**
-	 * Path link quality of physical path over which test was received
-	 */
-	int receivedFromLinkQuality;
-
-	/**
-	 * Next hops to which packets are being or will be sent by the reporter
-	 *
-	 * In addition to reporting back, the reporter may send the test on if
-	 * there are more recipients in the FIFO. If it does this, it can report
-	 * back the address(es) that make up the next hop and the physical address
-	 * for each if it has one. The physical address being null/unspecified
-	 * typically indicates that no direct path exists and the next packet
-	 * will be relayed.
-	 */
-	struct {
-		/**
-		 * 40-bit ZeroTier address
-		 */
-		uint64_t address;
-
-		/**
-		 * Physical address or null address (ss_family == 0) if unspecified or unknown
-		 */
-		struct sockaddr_storage physicalAddress;
-	} nextHops[ZT_CIRCUIT_TEST_MAX_HOP_BREADTH];
-
-	/**
-	 * Number of next hops reported in nextHops[]
-	 */
-	unsigned int nextHopCount;
-} ZT_CircuitTestReport;
-
 /**
  * A cluster member's status
  */
@@ -1957,40 +1765,6 @@ int ZT_Node_sendUserMessage(ZT_Node *node,void *tptr,uint64_t dest,uint64_t type
  */
 void ZT_Node_setNetconfMaster(ZT_Node *node,void *networkConfigMasterInstance);
 
-/**
- * Initiate a VL1 circuit test
- *
- * This sends an initial VERB_CIRCUIT_TEST and reports results back to the
- * supplied callback until circuitTestEnd() is called. The supplied
- * ZT_CircuitTest structure should be initially zeroed and then filled
- * in with settings and hops.
- *
- * It is the caller's responsibility to call circuitTestEnd() and then
- * to dispose of the test structure. Otherwise this node will listen
- * for results forever.
- *
- * @param node Node instance
- * @param tptr Thread pointer to pass to functions/callbacks resulting from this call
- * @param test Test configuration
- * @param reportCallback Function to call each time a report is received
- * @return OK or error if, for example, test is too big for a packet or support isn't compiled in
- */
-enum ZT_ResultCode ZT_Node_circuitTestBegin(ZT_Node *node,void *tptr,ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *, ZT_CircuitTest *,const ZT_CircuitTestReport *));
-
-/**
- * Stop listening for results to a given circuit test
- *
- * This does not free the 'test' structure. The caller may do that
- * after calling this method to unregister it.
- *
- * Any reports that are received for a given test ID after it is
- * terminated are ignored.
- *
- * @param node Node instance
- * @param test Test configuration to unregister
- */
-void ZT_Node_circuitTestEnd(ZT_Node *node,ZT_CircuitTest *test);
-
 /**
  * Initialize cluster operation
  *

+ 2 - 194
node/IncomingPacket.cpp

@@ -115,8 +115,6 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,void *tPtr)
 				case Packet::VERB_MULTICAST_GATHER:           return _doMULTICAST_GATHER(RR,tPtr,peer);
 				case Packet::VERB_MULTICAST_FRAME:            return _doMULTICAST_FRAME(RR,tPtr,peer);
 				case Packet::VERB_PUSH_DIRECT_PATHS:          return _doPUSH_DIRECT_PATHS(RR,tPtr,peer);
-				case Packet::VERB_CIRCUIT_TEST:               return _doCIRCUIT_TEST(RR,tPtr,peer);
-				case Packet::VERB_CIRCUIT_TEST_REPORT:        return _doCIRCUIT_TEST_REPORT(RR,tPtr,peer);
 				case Packet::VERB_USER_MESSAGE:               return _doUSER_MESSAGE(RR,tPtr,peer);
 			}
 		} else {
@@ -1252,196 +1250,6 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,void *tPt
 	return true;
 }
 
-bool IncomingPacket::_doCIRCUIT_TEST(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
-{
-	try {
-		const Address originatorAddress(field(ZT_PACKET_IDX_PAYLOAD,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
-		SharedPtr<Peer> originator(RR->topology->getPeer(tPtr,originatorAddress));
-		if (!originator) {
-			RR->sw->requestWhois(tPtr,originatorAddress);
-			return false;
-		}
-
-		const unsigned int flags = at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 5);
-		const uint64_t timestamp = at<uint64_t>(ZT_PACKET_IDX_PAYLOAD + 7);
-		const uint64_t testId = at<uint64_t>(ZT_PACKET_IDX_PAYLOAD + 15);
-
-		// Tracks total length of variable length fields, initialized to originator credential length below
-		unsigned int vlf;
-
-		// Originator credentials -- right now only a network ID for which the originator is controller or is authorized by controller is allowed
-		const unsigned int originatorCredentialLength = vlf = at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 23);
-		uint64_t originatorCredentialNetworkId = 0;
-		if (originatorCredentialLength >= 1) {
-			switch((*this)[ZT_PACKET_IDX_PAYLOAD + 25]) {
-				case 0x01: { // 64-bit network ID, originator must be controller
-					if (originatorCredentialLength >= 9)
-						originatorCredentialNetworkId = at<uint64_t>(ZT_PACKET_IDX_PAYLOAD + 26);
-				}	break;
-				default: break;
-			}
-		}
-
-		// Add length of "additional fields," which are currently unused
-		vlf += at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 25 + vlf);
-
-		// Verify signature -- only tests signed by their originators are allowed
-		const unsigned int signatureLength = at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 27 + vlf);
-		if (!originator->identity().verify(field(ZT_PACKET_IDX_PAYLOAD,27 + vlf),27 + vlf,field(ZT_PACKET_IDX_PAYLOAD + 29 + vlf,signatureLength),signatureLength)) {
-			TRACE("dropped CIRCUIT_TEST from %s(%s): signature by originator %s invalid",source().toString().c_str(),_path->address().toString().c_str(),originatorAddress.toString().c_str());
-			peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST,0,Packet::VERB_NOP,false);
-			return true;
-		}
-		vlf += signatureLength;
-
-		// Save this length so we can copy the immutable parts of this test
-		// into the one we send along to next hops.
-		const unsigned int lengthOfSignedPortionAndSignature = 29 + vlf;
-
-		// Add length of second "additional fields" section.
-		vlf += at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 29 + vlf);
-
-		uint64_t reportFlags = 0;
-
-		// Check credentials (signature already verified)
-		if (originatorCredentialNetworkId) {
-			SharedPtr<Network> network(RR->node->network(originatorCredentialNetworkId));
-			if ((!network)||(!network->config().circuitTestingAllowed(originatorAddress))) {
-				TRACE("dropped CIRCUIT_TEST from %s(%s): originator %s specified network ID %.16llx as credential, and we don't belong to that network or originator is not allowed'",source().toString().c_str(),_path->address().toString().c_str(),originatorAddress.toString().c_str(),originatorCredentialNetworkId);
-				peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST,0,Packet::VERB_NOP,false);
-				return true;
-			}
-			if (network->gate(tPtr,peer))
-				reportFlags |= ZT_CIRCUIT_TEST_REPORT_FLAGS_UPSTREAM_AUTHORIZED_IN_PATH;
-		} else {
-			TRACE("dropped CIRCUIT_TEST from %s(%s): originator %s did not specify a credential or credential type",source().toString().c_str(),_path->address().toString().c_str(),originatorAddress.toString().c_str());
-			peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST,0,Packet::VERB_NOP,false);
-			return true;
-		}
-
-		const uint64_t now = RR->node->now();
-
-		unsigned int breadth = 0;
-		Address nextHop[256]; // breadth is a uin8_t, so this is the max
-		InetAddress nextHopBestPathAddress[256];
-		unsigned int remainingHopsPtr = ZT_PACKET_IDX_PAYLOAD + 33 + vlf;
-		if ((ZT_PACKET_IDX_PAYLOAD + 31 + vlf) < size()) {
-			// unsigned int nextHopFlags = (*this)[ZT_PACKET_IDX_PAYLOAD + 31 + vlf]
-			breadth = (*this)[ZT_PACKET_IDX_PAYLOAD + 32 + vlf];
-			for(unsigned int h=0;h<breadth;++h) {
-				nextHop[h].setTo(field(remainingHopsPtr,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
-				remainingHopsPtr += ZT_ADDRESS_LENGTH;
-				SharedPtr<Peer> nhp(RR->topology->getPeer(tPtr,nextHop[h]));
-				if (nhp) {
-					SharedPtr<Path> nhbp(nhp->getBestPath(now,false));
-					if ((nhbp)&&(nhbp->alive(now)))
-						nextHopBestPathAddress[h] = nhbp->address();
-				}
-			}
-		}
-
-		// Report back to originator, depending on flags and whether we are last hop
-		if ( ((flags & 0x01) != 0) || ((breadth == 0)&&((flags & 0x02) != 0)) ) {
-			Packet outp(originatorAddress,RR->identity.address(),Packet::VERB_CIRCUIT_TEST_REPORT);
-			outp.append((uint64_t)timestamp);
-			outp.append((uint64_t)testId);
-			outp.append((uint64_t)0); // field reserved for future use
-			outp.append((uint8_t)ZT_VENDOR_ZEROTIER);
-			outp.append((uint8_t)ZT_PROTO_VERSION);
-			outp.append((uint8_t)ZEROTIER_ONE_VERSION_MAJOR);
-			outp.append((uint8_t)ZEROTIER_ONE_VERSION_MINOR);
-			outp.append((uint16_t)ZEROTIER_ONE_VERSION_REVISION);
-			outp.append((uint16_t)ZT_PLATFORM_UNSPECIFIED);
-			outp.append((uint16_t)ZT_ARCHITECTURE_UNSPECIFIED);
-			outp.append((uint16_t)0); // error code, currently unused
-			outp.append((uint64_t)reportFlags);
-			outp.append((uint64_t)packetId());
-			peer->address().appendTo(outp);
-			outp.append((uint8_t)hops());
-			_path->localAddress().serialize(outp);
-			_path->address().serialize(outp);
-			outp.append((uint16_t)_path->linkQuality());
-			outp.append((uint8_t)breadth);
-			for(unsigned int h=0;h<breadth;++h) {
-				nextHop[h].appendTo(outp);
-				nextHopBestPathAddress[h].serialize(outp); // appends 0 if null InetAddress
-			}
-			RR->sw->send(tPtr,outp,true);
-		}
-
-		// If there are next hops, forward the test along through the graph
-		if (breadth > 0) {
-			Packet outp(Address(),RR->identity.address(),Packet::VERB_CIRCUIT_TEST);
-			outp.append(field(ZT_PACKET_IDX_PAYLOAD,lengthOfSignedPortionAndSignature),lengthOfSignedPortionAndSignature);
-			outp.append((uint16_t)0); // no additional fields
-			if (remainingHopsPtr < size())
-				outp.append(field(remainingHopsPtr,size() - remainingHopsPtr),size() - remainingHopsPtr);
-
-			for(unsigned int h=0;h<breadth;++h) {
-				if (RR->identity.address() != nextHop[h]) { // next hops that loop back to the current hop are not valid
-					outp.newInitializationVector();
-					outp.setDestination(nextHop[h]);
-					RR->sw->send(tPtr,outp,true);
-				}
-			}
-		}
-
-		peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST,0,Packet::VERB_NOP,false);
-	} catch ( ... ) {
-		TRACE("dropped CIRCUIT_TEST from %s(%s): unexpected exception",source().toString().c_str(),_path->address().toString().c_str());
-	}
-	return true;
-}
-
-bool IncomingPacket::_doCIRCUIT_TEST_REPORT(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
-{
-	try {
-		ZT_CircuitTestReport report;
-		memset(&report,0,sizeof(report));
-
-		report.current = peer->address().toInt();
-		report.upstream = Address(field(ZT_PACKET_IDX_PAYLOAD + 52,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH).toInt();
-		report.testId = at<uint64_t>(ZT_PACKET_IDX_PAYLOAD + 8);
-		report.timestamp = at<uint64_t>(ZT_PACKET_IDX_PAYLOAD);
-		report.sourcePacketId = at<uint64_t>(ZT_PACKET_IDX_PAYLOAD + 44);
-		report.flags = at<uint64_t>(ZT_PACKET_IDX_PAYLOAD + 36);
-		report.sourcePacketHopCount = (*this)[ZT_PACKET_IDX_PAYLOAD + 57]; // end of fixed length headers: 58
-		report.errorCode = at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 34);
-		report.vendor = (enum ZT_Vendor)((*this)[ZT_PACKET_IDX_PAYLOAD + 24]);
-		report.protocolVersion = (*this)[ZT_PACKET_IDX_PAYLOAD + 25];
-		report.majorVersion = (*this)[ZT_PACKET_IDX_PAYLOAD + 26];
-		report.minorVersion = (*this)[ZT_PACKET_IDX_PAYLOAD + 27];
-		report.revision = at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 28);
-		report.platform = (enum ZT_Platform)at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 30);
-		report.architecture = (enum ZT_Architecture)at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 32);
-
-		const unsigned int receivedOnLocalAddressLen = reinterpret_cast<InetAddress *>(&(report.receivedOnLocalAddress))->deserialize(*this,ZT_PACKET_IDX_PAYLOAD + 58);
-		const unsigned int receivedFromRemoteAddressLen = reinterpret_cast<InetAddress *>(&(report.receivedFromRemoteAddress))->deserialize(*this,ZT_PACKET_IDX_PAYLOAD + 58 + receivedOnLocalAddressLen);
-		unsigned int ptr = ZT_PACKET_IDX_PAYLOAD + 58 + receivedOnLocalAddressLen + receivedFromRemoteAddressLen;
-		if (report.protocolVersion >= 9) {
-			report.receivedFromLinkQuality = at<uint16_t>(ptr); ptr += 2;
-		} else {
-			report.receivedFromLinkQuality = ZT_PATH_LINK_QUALITY_MAX;
-			ptr += at<uint16_t>(ptr) + 2; // this field was once an 'extended field length' reserved field, which was always set to 0
-		}
-
-		report.nextHopCount = (*this)[ptr++];
-		if (report.nextHopCount > ZT_CIRCUIT_TEST_MAX_HOP_BREADTH) // sanity check, shouldn't be possible
-			report.nextHopCount = ZT_CIRCUIT_TEST_MAX_HOP_BREADTH;
-		for(unsigned int h=0;h<report.nextHopCount;++h) {
-			report.nextHops[h].address = Address(field(ptr,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH).toInt(); ptr += ZT_ADDRESS_LENGTH;
-			ptr += reinterpret_cast<InetAddress *>(&(report.nextHops[h].physicalAddress))->deserialize(*this,ptr);
-		}
-
-		RR->node->postCircuitTestReport(&report);
-
-		peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST_REPORT,0,Packet::VERB_NOP,false);
-	} catch ( ... ) {
-		TRACE("dropped CIRCUIT_TEST_REPORT from %s(%s): unexpected exception",source().toString().c_str(),_path->address().toString().c_str());
-	}
-	return true;
-}
-
 bool IncomingPacket::_doUSER_MESSAGE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
 {
 	try {
@@ -1453,9 +1261,9 @@ bool IncomingPacket::_doUSER_MESSAGE(const RuntimeEnvironment *RR,void *tPtr,con
 			um.length = size() - (ZT_PACKET_IDX_PAYLOAD + 8);
 			RR->node->postEvent(tPtr,ZT_EVENT_USER_MESSAGE,reinterpret_cast<const void *>(&um));
 		}
-		peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST_REPORT,0,Packet::VERB_NOP,false);
+		peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_USER_MESSAGE,0,Packet::VERB_NOP,false);
 	} catch ( ... ) {
-		TRACE("dropped CIRCUIT_TEST_REPORT from %s(%s): unexpected exception",source().toString().c_str(),_path->address().toString().c_str());
+		TRACE("dropped USER_MESSAGE from %s(%s): unexpected exception",source().toString().c_str(),_path->address().toString().c_str());
 	}
 	return true;
 }

+ 0 - 2
node/IncomingPacket.hpp

@@ -138,8 +138,6 @@ private:
 	bool _doMULTICAST_GATHER(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
 	bool _doMULTICAST_FRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
 	bool _doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
-	bool _doCIRCUIT_TEST(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
-	bool _doCIRCUIT_TEST_REPORT(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
 	bool _doUSER_MESSAGE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
 
 	void _sendErrorNeedCredentials(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer,const uint64_t nwid);

+ 0 - 88
node/Node.cpp

@@ -503,64 +503,6 @@ void Node::setNetconfMaster(void *networkControllerInstance)
 		RR->localNetworkController->init(RR->identity,this);
 }
 
-ZT_ResultCode Node::circuitTestBegin(void *tptr,ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *))
-{
-	if (test->hopCount > 0) {
-		try {
-			Packet outp(Address(),RR->identity.address(),Packet::VERB_CIRCUIT_TEST);
-			RR->identity.address().appendTo(outp);
-			outp.append((uint16_t)((test->reportAtEveryHop != 0) ? 0x03 : 0x02));
-			outp.append((uint64_t)test->timestamp);
-			outp.append((uint64_t)test->testId);
-			outp.append((uint16_t)0); // originator credential length, updated later
-			if (test->credentialNetworkId) {
-				outp.append((uint8_t)0x01);
-				outp.append((uint64_t)test->credentialNetworkId);
-				outp.setAt<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 23,(uint16_t)9);
-			}
-			outp.append((uint16_t)0);
-			C25519::Signature sig(RR->identity.sign(reinterpret_cast<const char *>(outp.data()) + ZT_PACKET_IDX_PAYLOAD,outp.size() - ZT_PACKET_IDX_PAYLOAD));
-			outp.append((uint16_t)sig.size());
-			outp.append(sig.data,(unsigned int)sig.size());
-			outp.append((uint16_t)0); // originator doesn't need an extra credential, since it's the originator
-			for(unsigned int h=1;h<test->hopCount;++h) {
-				outp.append((uint8_t)0);
-				outp.append((uint8_t)(test->hops[h].breadth & 0xff));
-				for(unsigned int a=0;a<test->hops[h].breadth;++a)
-					Address(test->hops[h].addresses[a]).appendTo(outp);
-			}
-
-			for(unsigned int a=0;a<test->hops[0].breadth;++a) {
-				outp.newInitializationVector();
-				outp.setDestination(Address(test->hops[0].addresses[a]));
-				RR->sw->send(tptr,outp,true);
-			}
-		} catch ( ... ) {
-			return ZT_RESULT_FATAL_ERROR_INTERNAL; // probably indicates FIFO too big for packet
-		}
-	}
-
-	{
-		test->_internalPtr = reinterpret_cast<void *>(reportCallback);
-		Mutex::Lock _l(_circuitTests_m);
-		if (std::find(_circuitTests.begin(),_circuitTests.end(),test) == _circuitTests.end())
-			_circuitTests.push_back(test);
-	}
-
-	return ZT_RESULT_OK;
-}
-
-void Node::circuitTestEnd(ZT_CircuitTest *test)
-{
-	Mutex::Lock _l(_circuitTests_m);
-	for(;;) {
-		std::vector< ZT_CircuitTest * >::iterator ct(std::find(_circuitTests.begin(),_circuitTests.end(),test));
-		if (ct == _circuitTests.end())
-			break;
-		else _circuitTests.erase(ct);
-	}
-}
-
 ZT_ResultCode Node::clusterInit(
 	unsigned int myId,
 	const struct sockaddr_storage *zeroTierPhysicalEndpoints,
@@ -715,20 +657,6 @@ uint64_t Node::prng()
 	return z + y;
 }
 
-void Node::postCircuitTestReport(const ZT_CircuitTestReport *report)
-{
-	std::vector< ZT_CircuitTest * > toNotify;
-	{
-		Mutex::Lock _l(_circuitTests_m);
-		for(std::vector< ZT_CircuitTest * >::iterator i(_circuitTests.begin());i!=_circuitTests.end();++i) {
-			if ((*i)->testId == report->testId)
-				toNotify.push_back(*i);
-		}
-	}
-	for(std::vector< ZT_CircuitTest * >::iterator i(toNotify.begin());i!=toNotify.end();++i)
-		(reinterpret_cast<void (*)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *)>((*i)->_internalPtr))(reinterpret_cast<ZT_Node *>(this),*i,report);
-}
-
 void Node::setTrustedPaths(const struct sockaddr_storage *networks,const uint64_t *ids,unsigned int count)
 {
 	RR->topology->setTrustedPaths(reinterpret_cast<const InetAddress *>(networks),ids,count);
@@ -1070,22 +998,6 @@ void ZT_Node_setNetconfMaster(ZT_Node *node,void *networkControllerInstance)
 	} catch ( ... ) {}
 }
 
-enum ZT_ResultCode ZT_Node_circuitTestBegin(ZT_Node *node,void *tptr,ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *))
-{
-	try {
-		return reinterpret_cast<ZeroTier::Node *>(node)->circuitTestBegin(tptr,test,reportCallback);
-	} catch ( ... ) {
-		return ZT_RESULT_FATAL_ERROR_INTERNAL;
-	}
-}
-
-void ZT_Node_circuitTestEnd(ZT_Node *node,ZT_CircuitTest *test)
-{
-	try {
-		reinterpret_cast<ZeroTier::Node *>(node)->circuitTestEnd(test);
-	} catch ( ... ) {}
-}
-
 enum ZT_ResultCode ZT_Node_clusterInit(
 	ZT_Node *node,
 	unsigned int myId,

+ 0 - 6
node/Node.hpp

@@ -117,8 +117,6 @@ public:
 	void clearLocalInterfaceAddresses();
 	int sendUserMessage(void *tptr,uint64_t dest,uint64_t typeId,const void *data,unsigned int len);
 	void setNetconfMaster(void *networkControllerInstance);
-	ZT_ResultCode circuitTestBegin(void *tptr,ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *));
-	void circuitTestEnd(ZT_CircuitTest *test);
 	ZT_ResultCode clusterInit(
 		unsigned int myId,
 		const struct sockaddr_storage *zeroTierPhysicalEndpoints,
@@ -219,7 +217,6 @@ public:
 	inline bool externalPathLookup(void *tPtr,const Address &ztaddr,int family,InetAddress &addr) { return ( (_cb.pathLookupFunction) ? (_cb.pathLookupFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ztaddr.toInt(),family,reinterpret_cast<struct sockaddr_storage *>(&addr)) != 0) : false ); }
 
 	uint64_t prng();
-	void postCircuitTestReport(const ZT_CircuitTestReport *report);
 	void setTrustedPaths(const struct sockaddr_storage *networks,const uint64_t *ids,unsigned int count);
 
 	World planet() const;
@@ -309,9 +306,6 @@ private:
 	std::vector< std::pair< uint64_t, SharedPtr<Network> > > _networks;
 	Mutex _networks_m;
 
-	std::vector< ZT_CircuitTest * > _circuitTests;
-	Mutex _circuitTests_m;
-
 	std::vector<InetAddress> _directPaths;
 	Mutex _directPaths_m;
 

+ 0 - 2
node/Packet.cpp

@@ -1082,8 +1082,6 @@ const char *Packet::verbString(Verb v)
 		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_USER_MESSAGE: return "USER_MESSAGE";
 	}
 	return "(unknown)";

+ 2 - 114
node/Packet.hpp

@@ -61,7 +61,7 @@
  * 4 - 0.6.0 ... 1.0.6
  *   + BREAKING CHANGE: New identity format based on hashcash design
  * 5 - 1.1.0 ... 1.1.5
- *   + Supports circuit test, proof of work, and echo
+ *   + Supports echo
  *   + Supports in-band world (root server definition) updates
  *   + Clustering! (Though this will work with protocol v4 clients.)
  *   + Otherwise backward compatible with protocol v4
@@ -954,119 +954,7 @@ public:
 		 */
 		VERB_PUSH_DIRECT_PATHS = 0x10,
 
-		/**
-		 * Source-routed circuit test message:
-		 *   <[5] address of originator of circuit test>
-		 *   <[2] 16-bit flags>
-		 *   <[8] 64-bit timestamp>
-		 *   <[8] 64-bit test ID (arbitrary, set by tester)>
-		 *   <[2] 16-bit originator credential length (includes type)>
-		 *   [[1] originator credential type (for authorizing test)]
-		 *   [[...] originator credential]
-		 *   <[2] 16-bit length of additional fields>
-		 *   [[...] additional fields]
-		 *   [ ... end of signed portion of request ... ]
-		 *   <[2] 16-bit length of signature of request>
-		 *   <[...] signature of request by originator>
-		 *   <[2] 16-bit length of additional fields>
-		 *   [[...] additional fields]
-		 *   <[...] next hop(s) in path>
-		 *
-		 * Flags:
-		 *   0x01 - Report back to originator at all hops
-		 *   0x02 - Report back to originator at last hop
-		 *
-		 * Originator credential types:
-		 *   0x01 - 64-bit network ID for which originator is controller
-		 *
-		 * Path record format:
-		 *   <[1] 8-bit flags (unused, must be zero)>
-		 *   <[1] 8-bit breadth (number of next hops)>
-		 *   <[...] one or more ZeroTier addresses of next hops>
-		 *
-		 * The circuit test allows a device to send a message that will traverse
-		 * the network along a specified path, with each hop optionally reporting
-		 * back to the tester via VERB_CIRCUIT_TEST_REPORT.
-		 *
-		 * Each circuit test packet includes a digital signature by the originator
-		 * of the request, as well as a credential by which that originator claims
-		 * authorization to perform the test. Currently this signature is ed25519,
-		 * but in the future flags might be used to indicate an alternative
-		 * algorithm. For example, the originator might be a network controller.
-		 * In this case the test might be authorized if the recipient is a member
-		 * of a network controlled by it, and if the previous hop(s) are also
-		 * members. Each hop may include its certificate of network membership.
-		 *
-		 * Circuit test paths consist of a series of records. When a node receives
-		 * an authorized circuit test, it:
-		 *
-		 * (1) Reports back to circuit tester as flags indicate
-		 * (2) Reads and removes the next hop from the packet's path
-		 * (3) Sends the packet along to next hop(s), if any.
-		 *
-		 * It is perfectly legal for a path to contain the same hop more than
-		 * once. In fact, this can be a very useful test to determine if a hop
-		 * can be reached bidirectionally and if so what that connectivity looks
-		 * like.
-		 *
-		 * The breadth field in source-routed path records allows a hop to forward
-		 * to more than one recipient, allowing the tester to specify different
-		 * forms of graph traversal in a test.
-		 *
-		 * There is no hard limit to the number of hops in a test, but it is
-		 * practically limited by the maximum size of a (possibly fragmented)
-		 * ZeroTier packet.
-		 *
-		 * Support for circuit tests is optional. If they are not supported, the
-		 * node should respond with an UNSUPPORTED_OPERATION error. If a circuit
-		 * test request is not authorized, it may be ignored or reported as
-		 * an INVALID_REQUEST. No OK messages are generated, but TEST_REPORT
-		 * messages may be sent (see below).
-		 *
-		 * ERROR packet format:
-		 *   <[8] 64-bit timestamp (echoed from original>
-		 *   <[8] 64-bit test ID (echoed from original)>
-		 */
-		VERB_CIRCUIT_TEST = 0x11,
-
-		/**
-		 * Circuit test hop report:
-		 *   <[8] 64-bit timestamp (echoed from original test)>
-		 *   <[8] 64-bit test ID (echoed from original test)>
-		 *   <[8] 64-bit reserved field (set to 0, currently unused)>
-		 *   <[1] 8-bit vendor ID (set to 0, currently unused)>
-		 *   <[1] 8-bit reporter protocol version>
-		 *   <[1] 8-bit reporter software major version>
-		 *   <[1] 8-bit reporter software minor version>
-		 *   <[2] 16-bit reporter software revision>
-		 *   <[2] 16-bit reporter OS/platform or 0 if not specified>
-		 *   <[2] 16-bit reporter architecture or 0 if not specified>
-		 *   <[2] 16-bit error code (set to 0, currently unused)>
-		 *   <[8] 64-bit report flags>
-		 *   <[8] 64-bit packet ID of received CIRCUIT_TEST packet>
-		 *   <[5] upstream ZeroTier address from which CIRCUIT_TEST was received>
-		 *   <[1] 8-bit packet hop count of received CIRCUIT_TEST>
-		 *   <[...] local wire address on which packet was received>
-		 *   <[...] remote wire address from which packet was received>
-		 *   <[2] 16-bit path link quality of path over which packet was received>
-		 *   <[1] 8-bit number of next hops (breadth)>
-		 *   <[...] next hop information>
-		 *
-		 * Next hop information record format:
-		 *   <[5] ZeroTier address of next hop>
-		 *   <[...] current best direct path address, if any, 0 if none>
-		 *
-		 * Report flags:
-		 *   0x1 - Upstream peer in circuit test path allowed in path (e.g. network COM valid)
-		 *
-		 * Circuit test reports can be sent by hops in a circuit test to report
-		 * back results. They should include information about the sender as well
-		 * as about the paths to which next hops are being sent.
-		 *
-		 * If a test report is received and no circuit test was sent, it should be
-		 * ignored. This message generates no OK or ERROR response.
-		 */
-		VERB_CIRCUIT_TEST_REPORT = 0x12,
+		// 0x11, 0x12 -- deprecated
 
 		/**
 		 * A message with arbitrary user-definable content: