mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 20:13:44 +02:00
Finish removing constantly changing stuff from controller.
This commit is contained in:
parent
a9ce773584
commit
718e1d6c08
5 changed files with 142 additions and 87 deletions
|
@ -518,7 +518,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpGET(
|
||||||
json member;
|
json member;
|
||||||
if (!_db.getNetworkMember(nwid,address,member))
|
if (!_db.getNetworkMember(nwid,address,member))
|
||||||
return 404;
|
return 404;
|
||||||
_addMemberNonPersistedFields(member,OSUtils::now());
|
_addMemberNonPersistedFields(nwid,address,member,OSUtils::now());
|
||||||
responseBody = OSUtils::jsonDump(member);
|
responseBody = OSUtils::jsonDump(member);
|
||||||
responseContentType = "application/json";
|
responseContentType = "application/json";
|
||||||
} else {
|
} else {
|
||||||
|
@ -569,6 +569,26 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpGET(
|
||||||
|
|
||||||
} // else 404
|
} // else 404
|
||||||
|
|
||||||
|
} else if ((path.size() == 1)&&(path[0] == "memberStatus")) {
|
||||||
|
|
||||||
|
const uint64_t now = OSUtils::now();
|
||||||
|
Mutex::Lock _l(_memberStatus_m);
|
||||||
|
responseBody.push_back('{');
|
||||||
|
_db.eachId([this,&responseBody,&now](uint64_t networkId,uint64_t nodeId) {
|
||||||
|
char tmp[64];
|
||||||
|
auto ms = this->_memberStatus.find(_MemberStatusKey(networkId,nodeId));
|
||||||
|
Utils::snprintf(tmp,sizeof(tmp),"%s\"%.16llx-%.10llx\":%s",
|
||||||
|
(responseBody.length() > 1) ? "," : "",
|
||||||
|
(unsigned long long)networkId,
|
||||||
|
(unsigned long long)nodeId,
|
||||||
|
((ms != _memberStatus.end())&&(ms->second.online(now))) ? "true" : "false");
|
||||||
|
responseBody.append(tmp);
|
||||||
|
});
|
||||||
|
responseBody.push_back('}');
|
||||||
|
responseContentType = "application/json";
|
||||||
|
|
||||||
|
return 200;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
char tmp[4096];
|
char tmp[4096];
|
||||||
|
@ -649,10 +669,11 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
|
||||||
if (!newAuth) {
|
if (!newAuth) {
|
||||||
Revocation rev((uint32_t)_node->prng(),nwid,0,now,ZT_REVOCATION_FLAG_FAST_PROPAGATE,Address(address),Revocation::CREDENTIAL_TYPE_COM);
|
Revocation rev((uint32_t)_node->prng(),nwid,0,now,ZT_REVOCATION_FLAG_FAST_PROPAGATE,Address(address),Revocation::CREDENTIAL_TYPE_COM);
|
||||||
rev.sign(_signingId);
|
rev.sign(_signingId);
|
||||||
Mutex::Lock _l(_lastRequestTime_m);
|
|
||||||
for(std::map< std::pair<uint64_t,uint64_t>,uint64_t >::iterator i(_lastRequestTime.begin());i!=_lastRequestTime.end();++i) {
|
Mutex::Lock _l(_memberStatus_m);
|
||||||
if ((now - i->second) < ZT_NETWORK_AUTOCONF_DELAY)
|
for(auto i=_memberStatus.begin();i!=_memberStatus.end();++i) {
|
||||||
_node->ncSendRevocation(Address(i->first.first),rev);
|
if ((i->first.networkId == nwid)&&(i->second.online(now)))
|
||||||
|
_node->ncSendRevocation(Address(i->first.nodeId),rev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -720,10 +741,17 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
|
||||||
json &revj = member["revision"];
|
json &revj = member["revision"];
|
||||||
member["revision"] = (revj.is_number() ? ((uint64_t)revj + 1ULL) : 1ULL);
|
member["revision"] = (revj.is_number() ? ((uint64_t)revj + 1ULL) : 1ULL);
|
||||||
_db.saveNetworkMember(nwid,address,member);
|
_db.saveNetworkMember(nwid,address,member);
|
||||||
_pushMemberUpdate(now,nwid,member);
|
|
||||||
|
// Push update to member if online
|
||||||
|
try {
|
||||||
|
Mutex::Lock _l(_memberStatus_m);
|
||||||
|
_MemberStatus &ms = _memberStatus[_MemberStatusKey(nwid,address)];
|
||||||
|
if ((ms.online(now))&&(ms.lastRequestMetaData))
|
||||||
|
request(nwid,InetAddress(),0,ms.identity,ms.lastRequestMetaData);
|
||||||
|
} catch ( ... ) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
_addMemberNonPersistedFields(member,now);
|
_addMemberNonPersistedFields(nwid,address,member,now);
|
||||||
responseBody = OSUtils::jsonDump(member);
|
responseBody = OSUtils::jsonDump(member);
|
||||||
responseContentType = "application/json";
|
responseContentType = "application/json";
|
||||||
|
|
||||||
|
@ -1022,10 +1050,12 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
|
||||||
network["revision"] = (revj.is_number() ? ((uint64_t)revj + 1ULL) : 1ULL);
|
network["revision"] = (revj.is_number() ? ((uint64_t)revj + 1ULL) : 1ULL);
|
||||||
_db.saveNetwork(nwid,network);
|
_db.saveNetwork(nwid,network);
|
||||||
|
|
||||||
// Send an update to all members of the network
|
// Send an update to all members of the network that are online
|
||||||
_db.eachMember(nwid,[this,&now,&nwid](uint64_t networkId,uint64_t nodeId,const json &obj) {
|
Mutex::Lock _l(_memberStatus_m);
|
||||||
this->_pushMemberUpdate(now,nwid,obj);
|
for(auto i=_memberStatus.begin();i!=_memberStatus.end();++i) {
|
||||||
});
|
if ((i->first.networkId == nwid)&&(i->second.online(now))&&(i->second.lastRequestMetaData))
|
||||||
|
request(nwid,InetAddress(),0,i->second.identity,i->second.lastRequestMetaData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONDB::NetworkSummaryInfo ns;
|
JSONDB::NetworkSummaryInfo ns;
|
||||||
|
@ -1044,7 +1074,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
|
||||||
json testRec;
|
json testRec;
|
||||||
const uint64_t now = OSUtils::now();
|
const uint64_t now = OSUtils::now();
|
||||||
testRec["clock"] = now;
|
testRec["clock"] = now;
|
||||||
testRec["uptime"] = (now - _startTime);
|
testRec["startTime"] = _startTime;
|
||||||
testRec["content"] = b;
|
testRec["content"] = b;
|
||||||
responseBody = OSUtils::jsonDump(testRec);
|
responseBody = OSUtils::jsonDump(testRec);
|
||||||
_db.writeRaw("pong",responseBody);
|
_db.writeRaw("pong",responseBody);
|
||||||
|
@ -1075,6 +1105,12 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpDELETE(
|
||||||
const uint64_t address = Utils::hexStrToU64(path[3].c_str());
|
const uint64_t address = Utils::hexStrToU64(path[3].c_str());
|
||||||
|
|
||||||
json member = _db.eraseNetworkMember(nwid,address);
|
json member = _db.eraseNetworkMember(nwid,address);
|
||||||
|
|
||||||
|
{
|
||||||
|
Mutex::Lock _l(_memberStatus_m);
|
||||||
|
_memberStatus.erase(_MemberStatusKey(nwid,address));
|
||||||
|
}
|
||||||
|
|
||||||
if (!member.size())
|
if (!member.size())
|
||||||
return 404;
|
return 404;
|
||||||
responseBody = OSUtils::jsonDump(member);
|
responseBody = OSUtils::jsonDump(member);
|
||||||
|
@ -1083,6 +1119,16 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpDELETE(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
json network = _db.eraseNetwork(nwid);
|
json network = _db.eraseNetwork(nwid);
|
||||||
|
|
||||||
|
{
|
||||||
|
Mutex::Lock _l(_memberStatus_m);
|
||||||
|
for(auto i=_memberStatus.begin();i!=_memberStatus.end();) {
|
||||||
|
if (i->first.networkId == nwid)
|
||||||
|
_memberStatus.erase(i++);
|
||||||
|
else ++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!network.size())
|
if (!network.size())
|
||||||
return 404;
|
return 404;
|
||||||
responseBody = OSUtils::jsonDump(network);
|
responseBody = OSUtils::jsonDump(network);
|
||||||
|
@ -1106,6 +1152,7 @@ void EmbeddedNetworkController::threadMain()
|
||||||
_request(qe->nwid,qe->fromAddr,qe->requestPacketId,qe->identity,qe->metaData);
|
_request(qe->nwid,qe->fromAddr,qe->requestPacketId,qe->identity,qe->metaData);
|
||||||
} catch ( ... ) {}
|
} catch ( ... ) {}
|
||||||
delete qe;
|
delete qe;
|
||||||
|
|
||||||
if (_running) {
|
if (_running) {
|
||||||
uint64_t now = OSUtils::now();
|
uint64_t now = OSUtils::now();
|
||||||
if ((now - lastCircuitTestCheck) > ZT_EMBEDDEDNETWORKCONTROLLER_CIRCUIT_TEST_EXPIRATION) {
|
if ((now - lastCircuitTestCheck) > ZT_EMBEDDEDNETWORKCONTROLLER_CIRCUIT_TEST_EXPIRATION) {
|
||||||
|
@ -1196,11 +1243,11 @@ void EmbeddedNetworkController::_request(
|
||||||
const uint64_t now = OSUtils::now();
|
const uint64_t now = OSUtils::now();
|
||||||
|
|
||||||
if (requestPacketId) {
|
if (requestPacketId) {
|
||||||
Mutex::Lock _l(_lastRequestTime_m);
|
Mutex::Lock _l(_memberStatus_m);
|
||||||
uint64_t &lrt = _lastRequestTime[std::pair<uint64_t,uint64_t>(identity.address().toInt(),nwid)];
|
_MemberStatus &ms = _memberStatus[_MemberStatusKey(nwid,identity.address().toInt())];
|
||||||
if ((now - lrt) <= ZT_NETCONF_MIN_REQUEST_PERIOD)
|
if ((now - ms.lastRequestTime) <= ZT_NETCONF_MIN_REQUEST_PERIOD)
|
||||||
return;
|
return;
|
||||||
lrt = now;
|
ms.lastRequestTime = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::snprintf(nwids,sizeof(nwids),"%.16llx",nwid);
|
Utils::snprintf(nwids,sizeof(nwids),"%.16llx",nwid);
|
||||||
|
@ -1315,37 +1362,37 @@ void EmbeddedNetworkController::_request(
|
||||||
member["revision"] = (revj.is_number() ? ((uint64_t)revj + 1ULL) : 1ULL);
|
member["revision"] = (revj.is_number() ? ((uint64_t)revj + 1ULL) : 1ULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log this request
|
if (authorizedBy) {
|
||||||
if (requestPacketId) { // only log if this is a request, not for generated pushes
|
// Update version info and meta-data if authorized and if this is a genuine request
|
||||||
json rlEntry = json::object();
|
if (requestPacketId) {
|
||||||
rlEntry["ts"] = now;
|
const uint64_t vMajor = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,0);
|
||||||
rlEntry["auth"] = (authorizedBy) ? true : false;
|
const uint64_t vMinor = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION,0);
|
||||||
rlEntry["authBy"] = (authorizedBy) ? authorizedBy : "";
|
const uint64_t vRev = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION,0);
|
||||||
rlEntry["vMajor"] = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,0);
|
const uint64_t vProto = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION,0);
|
||||||
rlEntry["vMinor"] = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION,0);
|
|
||||||
rlEntry["vRev"] = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION,0);
|
|
||||||
rlEntry["vProto"] = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION,0);
|
|
||||||
if (fromAddr)
|
|
||||||
rlEntry["fromAddr"] = fromAddr.toString();
|
|
||||||
|
|
||||||
json recentLog = json::array();
|
member["vMajor"] = vMajor;
|
||||||
recentLog.push_back(rlEntry);
|
member["vMinor"] = vMinor;
|
||||||
json &oldLog = member["recentLog"];
|
member["vRev"] = vRev;
|
||||||
if (oldLog.is_array()) {
|
member["vProto"] = vProto;
|
||||||
for(unsigned long i=0;i<oldLog.size();++i) {
|
|
||||||
recentLog.push_back(oldLog[i]);
|
{
|
||||||
if (recentLog.size() >= ZT_NETCONF_DB_MEMBER_HISTORY_LENGTH)
|
Mutex::Lock _l(_memberStatus_m);
|
||||||
break;
|
_MemberStatus &ms = _memberStatus[_MemberStatusKey(nwid,identity.address().toInt())];
|
||||||
|
|
||||||
|
ms.vMajor = (int)vMajor;
|
||||||
|
ms.vMinor = (int)vMinor;
|
||||||
|
ms.vRev = (int)vRev;
|
||||||
|
ms.vProto = (int)vProto;
|
||||||
|
ms.lastRequestMetaData = metaData;
|
||||||
|
ms.identity = identity;
|
||||||
|
|
||||||
|
if (fromAddr)
|
||||||
|
ms.physicalAddr = fromAddr;
|
||||||
|
member["physicalAddr"] = ms.physicalAddr.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
member["recentLog"] = recentLog;
|
} else {
|
||||||
|
// If they are not authorized, STOP!
|
||||||
// Also only do this on real requests
|
|
||||||
member["lastRequestMetaData"] = metaData.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If they are not authorized, STOP!
|
|
||||||
if (!authorizedBy) {
|
|
||||||
_removeMemberNonPersistedFields(member);
|
_removeMemberNonPersistedFields(member);
|
||||||
if (origMember != member)
|
if (origMember != member)
|
||||||
_db.saveNetworkMember(nwid,identity.address().toInt(),member);
|
_db.saveNetworkMember(nwid,identity.address().toInt(),member);
|
||||||
|
@ -1702,27 +1749,4 @@ void EmbeddedNetworkController::_request(
|
||||||
_sender->ncSendConfig(nwid,requestPacketId,identity.address(),*(nc.get()),metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,0) < 6);
|
_sender->ncSendConfig(nwid,requestPacketId,identity.address(),*(nc.get()),metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,0) < 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmbeddedNetworkController::_pushMemberUpdate(uint64_t now,uint64_t nwid,const nlohmann::json &member)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
const std::string idstr = member["identity"];
|
|
||||||
const std::string mdstr = member["lastRequestMetaData"];
|
|
||||||
if ((idstr.length() > 0)&&(mdstr.length() > 0)) {
|
|
||||||
const Identity id(idstr);
|
|
||||||
bool online;
|
|
||||||
{
|
|
||||||
Mutex::Lock _l(_lastRequestTime_m);
|
|
||||||
std::map< std::pair<uint64_t,uint64_t>,uint64_t >::iterator lrt(_lastRequestTime.find(std::pair<uint64_t,uint64_t>(id.address().toInt(),nwid)));
|
|
||||||
online = ( (lrt != _lastRequestTime.end()) && ((now - lrt->second) < ZT_NETWORK_AUTOCONF_DELAY) );
|
|
||||||
}
|
|
||||||
if (online) {
|
|
||||||
Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> metaData(mdstr.c_str());
|
|
||||||
try {
|
|
||||||
this->request(nwid,InetAddress(),0,id,metaData);
|
|
||||||
} catch ( ... ) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch ( ... ) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
|
|
@ -107,7 +107,6 @@ private:
|
||||||
|
|
||||||
static void _circuitTestCallback(ZT_Node *node,ZT_CircuitTest *test,const ZT_CircuitTestReport *report);
|
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);
|
||||||
void _pushMemberUpdate(uint64_t now,uint64_t nwid,const nlohmann::json &member);
|
|
||||||
|
|
||||||
// These init objects with default and static/informational fields
|
// These init objects with default and static/informational fields
|
||||||
inline void _initMember(nlohmann::json &member)
|
inline void _initMember(nlohmann::json &member)
|
||||||
|
@ -164,9 +163,11 @@ private:
|
||||||
network.erase("activeMemberCount");
|
network.erase("activeMemberCount");
|
||||||
network.erase("totalMemberCount");
|
network.erase("totalMemberCount");
|
||||||
}
|
}
|
||||||
inline void _addMemberNonPersistedFields(nlohmann::json &member,uint64_t now)
|
inline void _addMemberNonPersistedFields(uint64_t nwid,uint64_t nodeId,nlohmann::json &member,uint64_t now)
|
||||||
{
|
{
|
||||||
member["clock"] = now;
|
member["clock"] = now;
|
||||||
|
Mutex::Lock _l(_memberStatus_m);
|
||||||
|
member["online"] = _memberStatus[_MemberStatusKey(nwid,nodeId)].online(now);
|
||||||
}
|
}
|
||||||
inline void _removeMemberNonPersistedFields(nlohmann::json &member)
|
inline void _removeMemberNonPersistedFields(nlohmann::json &member)
|
||||||
{
|
{
|
||||||
|
@ -191,8 +192,33 @@ private:
|
||||||
std::list< ZT_CircuitTest > _tests;
|
std::list< ZT_CircuitTest > _tests;
|
||||||
Mutex _tests_m;
|
Mutex _tests_m;
|
||||||
|
|
||||||
std::map< std::pair<uint64_t,uint64_t>,uint64_t > _lastRequestTime; // last request time by <address,networkId>
|
struct _MemberStatusKey
|
||||||
Mutex _lastRequestTime_m;
|
{
|
||||||
|
_MemberStatusKey() : networkId(0),nodeId(0) {}
|
||||||
|
_MemberStatusKey(const uint64_t nwid,const uint64_t nid) : networkId(nwid),nodeId(nid) {}
|
||||||
|
uint64_t networkId;
|
||||||
|
uint64_t nodeId;
|
||||||
|
inline bool operator==(const _MemberStatusKey &k) const { return ((k.networkId == networkId)&&(k.nodeId == nodeId)); }
|
||||||
|
};
|
||||||
|
struct _MemberStatus
|
||||||
|
{
|
||||||
|
_MemberStatus() : lastRequestTime(0),vMajor(-1),vMinor(-1),vRev(-1),vProto(-1) {}
|
||||||
|
uint64_t lastRequestTime;
|
||||||
|
int vMajor,vMinor,vRev,vProto;
|
||||||
|
Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> lastRequestMetaData;
|
||||||
|
Identity identity;
|
||||||
|
InetAddress physicalAddr; // last known physical address
|
||||||
|
inline bool online(const uint64_t now) const { return ((now - lastRequestTime) < (ZT_NETWORK_AUTOCONF_DELAY * 2)); }
|
||||||
|
};
|
||||||
|
struct _MemberStatusHash
|
||||||
|
{
|
||||||
|
inline std::size_t operator()(const _MemberStatusKey &networkIdNodeId) const
|
||||||
|
{
|
||||||
|
return (std::size_t)(networkIdNodeId.networkId + networkIdNodeId.nodeId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::unordered_map< _MemberStatusKey,_MemberStatus,_MemberStatusHash > _memberStatus;
|
||||||
|
Mutex _memberStatus_m;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
|
|
@ -107,6 +107,19 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
inline void eachId(F func)
|
||||||
|
{
|
||||||
|
Mutex::Lock _l(_networks_m);
|
||||||
|
for(std::unordered_map<uint64_t,_NW>::const_iterator i(_networks.begin());i!=_networks.end();++i) {
|
||||||
|
for(std::unordered_map< uint64_t,std::vector<uint8_t> >::const_iterator m(i->second.members.begin());m!=i->second.members.end();++m) {
|
||||||
|
try {
|
||||||
|
func(i->first,m->first);
|
||||||
|
} catch ( ... ) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void threadMain()
|
void threadMain()
|
||||||
throw();
|
throw();
|
||||||
|
|
||||||
|
|
|
@ -227,22 +227,12 @@ This returns an object containing all currently online members and the most rece
|
||||||
| activeBridge | boolean | Member is able to bridge to other Ethernet nets | YES |
|
| activeBridge | boolean | Member is able to bridge to other Ethernet nets | YES |
|
||||||
| identity | string | Member's public ZeroTier identity (if known) | no |
|
| identity | string | Member's public ZeroTier identity (if known) | no |
|
||||||
| ipAssignments | array[string] | Managed IP address assignments | YES |
|
| ipAssignments | array[string] | Managed IP address assignments | YES |
|
||||||
| memberRevision | integer | Member revision counter | no |
|
| revision | integer | Member revision counter | no |
|
||||||
| recentLog | array[object] | Recent member activity log; see below | no |
|
| vMajor | integer | Most recently known major version | no |
|
||||||
|
| vMinor | integer | Most recently known minor version | no |
|
||||||
|
| vRev | integer | Most recently known revision | no |
|
||||||
|
| vProto | integer | Most recently known protocl version | no |
|
||||||
|
| physicalAddr | string | Last known physical IP/port or null if none | no |
|
||||||
|
|
||||||
Note that managed IP assignments are only used if they fall within a managed route. Otherwise they are ignored.
|
Note that managed IP assignments are only used if they fall within a managed route. Otherwise they are ignored.
|
||||||
|
|
||||||
**Recent log object format:**
|
|
||||||
|
|
||||||
| Field | Type | Description |
|
|
||||||
| --------------------- | ------------- | ------------------------------------------------- |
|
|
||||||
| ts | integer | Time of request, ms since epoch |
|
|
||||||
| auth | boolean | Was member authorized? |
|
|
||||||
| authBy | string | How was member authorized? |
|
|
||||||
| vMajor | integer | Client major version or -1 if unknown |
|
|
||||||
| vMinor | integer | Client minor version or -1 if unknown |
|
|
||||||
| vRev | integer | Client revision or -1 if unknown |
|
|
||||||
| vProto | integer | ZeroTier protocol version reported by client |
|
|
||||||
| fromAddr | string | Physical address if known |
|
|
||||||
|
|
||||||
The controller can only know a member's `fromAddr` if it's able to establish a direct path to it. Members behind very restrictive firewalls may not have this information since the controller will be receiving the member's requests by way of a relay. ZeroTier does not back-trace IP paths as packets are relayed since this would add a lot of protocol overhead.
|
|
||||||
|
|
|
@ -99,6 +99,8 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline operator bool() const { return (_d[0] != 0); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a dictionary from a C-string
|
* Load a dictionary from a C-string
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Reference in a new issue