mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 03:53:44 +02:00
Remove old circuit test code. Rules engine will let us do this much better and more simply.
This commit is contained in:
parent
36049a940c
commit
2ec88e8008
9 changed files with 4 additions and 764 deletions
|
@ -726,59 +726,6 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
|
||||||
responseContentType = "application/json";
|
responseContentType = "application/json";
|
||||||
|
|
||||||
return 200;
|
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 404
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -1118,7 +1065,6 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpDELETE(
|
||||||
void EmbeddedNetworkController::threadMain()
|
void EmbeddedNetworkController::threadMain()
|
||||||
throw()
|
throw()
|
||||||
{
|
{
|
||||||
uint64_t lastCircuitTestCheck = 0;
|
|
||||||
_RQEntry *qe = (_RQEntry *)0;
|
_RQEntry *qe = (_RQEntry *)0;
|
||||||
while ((_running)&&(_queue.get(qe))) {
|
while ((_running)&&(_queue.get(qe))) {
|
||||||
try {
|
try {
|
||||||
|
@ -1153,80 +1099,9 @@ void EmbeddedNetworkController::threadMain()
|
||||||
}
|
}
|
||||||
} catch ( ... ) {}
|
} catch ( ... ) {}
|
||||||
delete qe;
|
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(
|
void EmbeddedNetworkController::_request(
|
||||||
uint64_t nwid,
|
uint64_t nwid,
|
||||||
const InetAddress &fromAddr,
|
const InetAddress &fromAddr,
|
||||||
|
|
|
@ -45,9 +45,6 @@
|
||||||
|
|
||||||
#include "JSONDB.hpp"
|
#include "JSONDB.hpp"
|
||||||
|
|
||||||
// TTL for circuit tests
|
|
||||||
#define ZT_EMBEDDEDNETWORKCONTROLLER_CIRCUIT_TEST_EXPIRATION 120000
|
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
class Node;
|
class Node;
|
||||||
|
@ -110,7 +107,6 @@ private:
|
||||||
} type;
|
} 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);
|
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()
|
inline void _startThreads()
|
||||||
|
@ -219,9 +215,6 @@ private:
|
||||||
NetworkController::Sender *_sender;
|
NetworkController::Sender *_sender;
|
||||||
Identity _signingId;
|
Identity _signingId;
|
||||||
|
|
||||||
std::list< ZT_CircuitTest > _tests;
|
|
||||||
Mutex _tests_m;
|
|
||||||
|
|
||||||
struct _MemberStatusKey
|
struct _MemberStatusKey
|
||||||
{
|
{
|
||||||
_MemberStatusKey() : networkId(0),nodeId(0) {}
|
_MemberStatusKey() : networkId(0),nodeId(0) {}
|
||||||
|
|
|
@ -760,7 +760,6 @@ typedef struct
|
||||||
*/
|
*/
|
||||||
uint64_t expiration;
|
uint64_t expiration;
|
||||||
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint64_t from;
|
uint64_t from;
|
||||||
uint64_t to;
|
uint64_t to;
|
||||||
|
@ -1105,197 +1104,6 @@ typedef struct
|
||||||
unsigned long peerCount;
|
unsigned long peerCount;
|
||||||
} ZT_PeerList;
|
} 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
|
* 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);
|
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
|
* Initialize cluster operation
|
||||||
*
|
*
|
||||||
|
|
|
@ -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_GATHER: return _doMULTICAST_GATHER(RR,tPtr,peer);
|
||||||
case Packet::VERB_MULTICAST_FRAME: return _doMULTICAST_FRAME(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_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);
|
case Packet::VERB_USER_MESSAGE: return _doUSER_MESSAGE(RR,tPtr,peer);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1252,196 +1250,6 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,void *tPt
|
||||||
return true;
|
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)
|
bool IncomingPacket::_doUSER_MESSAGE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
@ -1453,9 +1261,9 @@ bool IncomingPacket::_doUSER_MESSAGE(const RuntimeEnvironment *RR,void *tPtr,con
|
||||||
um.length = size() - (ZT_PACKET_IDX_PAYLOAD + 8);
|
um.length = size() - (ZT_PACKET_IDX_PAYLOAD + 8);
|
||||||
RR->node->postEvent(tPtr,ZT_EVENT_USER_MESSAGE,reinterpret_cast<const void *>(&um));
|
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 ( ... ) {
|
} 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,8 +138,6 @@ private:
|
||||||
bool _doMULTICAST_GATHER(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
|
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 _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 _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);
|
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);
|
void _sendErrorNeedCredentials(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer,const uint64_t nwid);
|
||||||
|
|
|
@ -503,64 +503,6 @@ void Node::setNetconfMaster(void *networkControllerInstance)
|
||||||
RR->localNetworkController->init(RR->identity,this);
|
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(
|
ZT_ResultCode Node::clusterInit(
|
||||||
unsigned int myId,
|
unsigned int myId,
|
||||||
const struct sockaddr_storage *zeroTierPhysicalEndpoints,
|
const struct sockaddr_storage *zeroTierPhysicalEndpoints,
|
||||||
|
@ -715,20 +657,6 @@ uint64_t Node::prng()
|
||||||
return z + y;
|
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)
|
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);
|
RR->topology->setTrustedPaths(reinterpret_cast<const InetAddress *>(networks),ids,count);
|
||||||
|
@ -1070,22 +998,6 @@ void ZT_Node_setNetconfMaster(ZT_Node *node,void *networkControllerInstance)
|
||||||
} catch ( ... ) {}
|
} 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(
|
enum ZT_ResultCode ZT_Node_clusterInit(
|
||||||
ZT_Node *node,
|
ZT_Node *node,
|
||||||
unsigned int myId,
|
unsigned int myId,
|
||||||
|
|
|
@ -117,8 +117,6 @@ public:
|
||||||
void clearLocalInterfaceAddresses();
|
void clearLocalInterfaceAddresses();
|
||||||
int sendUserMessage(void *tptr,uint64_t dest,uint64_t typeId,const void *data,unsigned int len);
|
int sendUserMessage(void *tptr,uint64_t dest,uint64_t typeId,const void *data,unsigned int len);
|
||||||
void setNetconfMaster(void *networkControllerInstance);
|
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(
|
ZT_ResultCode clusterInit(
|
||||||
unsigned int myId,
|
unsigned int myId,
|
||||||
const struct sockaddr_storage *zeroTierPhysicalEndpoints,
|
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 ); }
|
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();
|
uint64_t prng();
|
||||||
void postCircuitTestReport(const ZT_CircuitTestReport *report);
|
|
||||||
void setTrustedPaths(const struct sockaddr_storage *networks,const uint64_t *ids,unsigned int count);
|
void setTrustedPaths(const struct sockaddr_storage *networks,const uint64_t *ids,unsigned int count);
|
||||||
|
|
||||||
World planet() const;
|
World planet() const;
|
||||||
|
@ -309,9 +306,6 @@ private:
|
||||||
std::vector< std::pair< uint64_t, SharedPtr<Network> > > _networks;
|
std::vector< std::pair< uint64_t, SharedPtr<Network> > > _networks;
|
||||||
Mutex _networks_m;
|
Mutex _networks_m;
|
||||||
|
|
||||||
std::vector< ZT_CircuitTest * > _circuitTests;
|
|
||||||
Mutex _circuitTests_m;
|
|
||||||
|
|
||||||
std::vector<InetAddress> _directPaths;
|
std::vector<InetAddress> _directPaths;
|
||||||
Mutex _directPaths_m;
|
Mutex _directPaths_m;
|
||||||
|
|
||||||
|
|
|
@ -1082,8 +1082,6 @@ const char *Packet::verbString(Verb v)
|
||||||
case VERB_MULTICAST_GATHER: return "MULTICAST_GATHER";
|
case VERB_MULTICAST_GATHER: return "MULTICAST_GATHER";
|
||||||
case VERB_MULTICAST_FRAME: return "MULTICAST_FRAME";
|
case VERB_MULTICAST_FRAME: return "MULTICAST_FRAME";
|
||||||
case VERB_PUSH_DIRECT_PATHS: return "PUSH_DIRECT_PATHS";
|
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";
|
case VERB_USER_MESSAGE: return "USER_MESSAGE";
|
||||||
}
|
}
|
||||||
return "(unknown)";
|
return "(unknown)";
|
||||||
|
|
116
node/Packet.hpp
116
node/Packet.hpp
|
@ -61,7 +61,7 @@
|
||||||
* 4 - 0.6.0 ... 1.0.6
|
* 4 - 0.6.0 ... 1.0.6
|
||||||
* + BREAKING CHANGE: New identity format based on hashcash design
|
* + BREAKING CHANGE: New identity format based on hashcash design
|
||||||
* 5 - 1.1.0 ... 1.1.5
|
* 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
|
* + Supports in-band world (root server definition) updates
|
||||||
* + Clustering! (Though this will work with protocol v4 clients.)
|
* + Clustering! (Though this will work with protocol v4 clients.)
|
||||||
* + Otherwise backward compatible with protocol v4
|
* + Otherwise backward compatible with protocol v4
|
||||||
|
@ -954,119 +954,7 @@ public:
|
||||||
*/
|
*/
|
||||||
VERB_PUSH_DIRECT_PATHS = 0x10,
|
VERB_PUSH_DIRECT_PATHS = 0x10,
|
||||||
|
|
||||||
/**
|
// 0x11, 0x12 -- deprecated
|
||||||
* 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,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A message with arbitrary user-definable content:
|
* A message with arbitrary user-definable content:
|
||||||
|
|
Loading…
Add table
Reference in a new issue