mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-06 20:43:44 +02:00
Tons of service work including trace events, etc.
This commit is contained in:
parent
8d6d457dd6
commit
411373dd2c
18 changed files with 979 additions and 265 deletions
|
@ -732,6 +732,16 @@ int ZT_Endpoint_fromString(
|
|||
return reinterpret_cast<ZeroTier::Endpoint *>(ep)->fromString(str) ? ZT_RESULT_OK : ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
int ZT_Endpoint_fromBytes(
|
||||
ZT_Endpoint *ep,
|
||||
const void *bytes,
|
||||
unsigned int len)
|
||||
{
|
||||
if ((!ep) || (!bytes) || (!len))
|
||||
return ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
return (reinterpret_cast<ZeroTier::Endpoint *>(ep)->unmarshal(reinterpret_cast<const uint8_t *>(bytes), (int)len) > 0) ? 0 : ZT_RESULT_ERROR_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
char *ZT_Fingerprint_toString(const ZT_Fingerprint *fp, char *buf, int capacity)
|
||||
|
@ -848,6 +858,20 @@ int ZT_InetAddress_lessThan(const ZT_InetAddress *a, const ZT_InetAddress *b)
|
|||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
int ZT_Dictionary_parse(const void *const dict, const unsigned int len, void *const arg, void (*f)(void *, const char *, unsigned int, const void *, unsigned int))
|
||||
{
|
||||
ZeroTier::Dictionary d;
|
||||
if (d.decode(dict, len)) {
|
||||
for(ZeroTier::Dictionary::const_iterator i(d.begin());i!=d.end();++i) {
|
||||
f(arg, i->first.c_str(), (unsigned int)i->first.length(), i->second.data(), (unsigned int)i->second.size());
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/********************************************************************************************************************/
|
||||
|
||||
uint64_t ZT_random()
|
||||
{
|
||||
return ZeroTier::Utils::random();
|
||||
|
|
212
core/Trace.cpp
212
core/Trace.cpp
|
@ -24,7 +24,7 @@ namespace ZeroTier {
|
|||
|
||||
Trace::Trace(const RuntimeEnvironment *renv) :
|
||||
RR(renv),
|
||||
_f(0)
|
||||
m_traceFlags(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -34,12 +34,12 @@ void Trace::unexpectedError(
|
|||
const char *message,
|
||||
...)
|
||||
{
|
||||
FCV<uint8_t,4096> buf;
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_TYPE,ZT_TRACE_UNEXPECTED_ERROR);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_MESSAGE,message);
|
||||
FCV< uint8_t, 4096 > buf;
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_UNEXPECTED_ERROR);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_CODE_LOCATION, codeLocation);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_MESSAGE, message);
|
||||
buf.push_back(0);
|
||||
RR->node->postEvent(tPtr,ZT_EVENT_TRACE,buf.data());
|
||||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
}
|
||||
|
||||
void Trace::_resettingPathsInScope(
|
||||
|
@ -51,18 +51,20 @@ void Trace::_resettingPathsInScope(
|
|||
const InetAddress &newExternal,
|
||||
const InetAddress::IpScope scope)
|
||||
{
|
||||
FCV<uint8_t,4096> buf;
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_TYPE,ZT_TRACE_VL1_RESETTING_PATHS_IN_SCOPE);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
|
||||
FCV< uint8_t, 4096 > buf;
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL1_RESETTING_PATHS_IN_SCOPE);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_CODE_LOCATION, codeLocation);
|
||||
if (reporter)
|
||||
Dictionary::appendObject(buf, ZT_TRACE_FIELD_IDENTITY_FINGERPRINT, reporter.fingerprint());
|
||||
if (from)
|
||||
Dictionary::appendObject(buf,ZT_TRACE_FIELD_ENDPOINT,Endpoint(from));
|
||||
Dictionary::appendObject(buf, ZT_TRACE_FIELD_TRIGGER_FROM_ENDPOINT, Endpoint(from));
|
||||
if (oldExternal)
|
||||
Dictionary::appendObject(buf,ZT_TRACE_FIELD_OLD_ENDPOINT,Endpoint(oldExternal));
|
||||
Dictionary::appendObject(buf, ZT_TRACE_FIELD_OLD_ENDPOINT, Endpoint(oldExternal));
|
||||
if (newExternal)
|
||||
Dictionary::appendObject(buf,ZT_TRACE_FIELD_NEW_ENDPOINT,Endpoint(newExternal));
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_RESET_ADDRESS_SCOPE,scope);
|
||||
Dictionary::appendObject(buf, ZT_TRACE_FIELD_NEW_ENDPOINT, Endpoint(newExternal));
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_RESET_ADDRESS_SCOPE, scope);
|
||||
buf.push_back(0);
|
||||
RR->node->postEvent(tPtr,ZT_EVENT_TRACE,buf.data());
|
||||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
}
|
||||
|
||||
void Trace::_tryingNewPath(
|
||||
|
@ -75,18 +77,18 @@ void Trace::_tryingNewPath(
|
|||
const uint8_t triggeringPacketVerb,
|
||||
const Identity &triggeringPeer)
|
||||
{
|
||||
FCV<uint8_t,4096> buf;
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_TYPE,ZT_TRACE_VL1_TRYING_NEW_PATH);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_IDENTITY_FINGERPRINT_HASH,trying.fingerprint().hash,ZT_FINGERPRINT_HASH_SIZE);
|
||||
FCV< uint8_t, 4096 > buf;
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL1_TRYING_NEW_PATH);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_CODE_LOCATION, codeLocation);
|
||||
Dictionary::appendObject(buf, ZT_TRACE_FIELD_IDENTITY_FINGERPRINT, trying.fingerprint());
|
||||
if (triggerAddress)
|
||||
Dictionary::appendObject(buf,ZT_TRACE_FIELD_TRIGGER_FROM_ENDPOINT,Endpoint(triggerAddress));
|
||||
Dictionary::appendPacketId(buf,ZT_TRACE_FIELD_TRIGGER_FROM_PACKET_ID,triggeringPacketId);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_TRIGGER_FROM_PACKET_VERB,triggeringPacketVerb);
|
||||
Dictionary::appendObject(buf, ZT_TRACE_FIELD_TRIGGER_FROM_ENDPOINT, Endpoint(triggerAddress));
|
||||
Dictionary::appendPacketId(buf, ZT_TRACE_FIELD_TRIGGER_FROM_PACKET_ID, triggeringPacketId);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_TRIGGER_FROM_PACKET_VERB, triggeringPacketVerb);
|
||||
if (triggeringPeer)
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_TRIGGER_FROM_PEER_FINGERPRINT_HASH,triggeringPeer.fingerprint().hash,ZT_FINGERPRINT_HASH_SIZE);
|
||||
Dictionary::appendObject(buf, ZT_TRACE_FIELD_TRIGGER_FROM_PEER_FINGERPRINT, triggeringPeer.fingerprint());
|
||||
buf.push_back(0);
|
||||
RR->node->postEvent(tPtr,ZT_EVENT_TRACE,buf.data());
|
||||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
}
|
||||
|
||||
void Trace::_learnedNewPath(
|
||||
|
@ -97,17 +99,17 @@ void Trace::_learnedNewPath(
|
|||
const InetAddress &physicalAddress,
|
||||
const InetAddress &replaced)
|
||||
{
|
||||
FCV<uint8_t,4096> buf;
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_TYPE,ZT_TRACE_VL1_LEARNED_NEW_PATH);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
|
||||
Dictionary::appendPacketId(buf,ZT_TRACE_FIELD_PACKET_ID,packetId);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_IDENTITY_FINGERPRINT_HASH,peerIdentity.fingerprint().hash,ZT_FINGERPRINT_HASH_SIZE);
|
||||
FCV< uint8_t, 4096 > buf;
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL1_LEARNED_NEW_PATH);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_CODE_LOCATION, codeLocation);
|
||||
Dictionary::appendPacketId(buf, ZT_TRACE_FIELD_PACKET_ID, packetId);
|
||||
Dictionary::appendObject(buf, ZT_TRACE_FIELD_IDENTITY_FINGERPRINT, peerIdentity.fingerprint());
|
||||
if (physicalAddress)
|
||||
Dictionary::appendObject(buf,ZT_TRACE_FIELD_ENDPOINT,Endpoint(physicalAddress));
|
||||
Dictionary::appendObject(buf, ZT_TRACE_FIELD_ENDPOINT, Endpoint(physicalAddress));
|
||||
if (replaced)
|
||||
Dictionary::appendObject(buf,ZT_TRACE_FIELD_OLD_ENDPOINT,Endpoint(replaced));
|
||||
Dictionary::appendObject(buf, ZT_TRACE_FIELD_OLD_ENDPOINT, Endpoint(replaced));
|
||||
buf.push_back(0);
|
||||
RR->node->postEvent(tPtr,ZT_EVENT_TRACE,buf.data());
|
||||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
}
|
||||
|
||||
void Trace::_incomingPacketDropped(
|
||||
|
@ -121,19 +123,20 @@ void Trace::_incomingPacketDropped(
|
|||
const uint8_t verb,
|
||||
const ZT_TracePacketDropReason reason)
|
||||
{
|
||||
FCV<uint8_t,4096> buf;
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_TYPE,ZT_TRACE_VL1_INCOMING_PACKET_DROPPED);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
|
||||
Dictionary::appendPacketId(buf,ZT_TRACE_FIELD_PACKET_ID,packetId);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_NETWORK_ID,networkId);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_IDENTITY_FINGERPRINT_HASH,peerIdentity.fingerprint().hash,ZT_FINGERPRINT_HASH_SIZE);
|
||||
FCV< uint8_t, 4096 > buf;
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL1_INCOMING_PACKET_DROPPED);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_CODE_LOCATION, codeLocation);
|
||||
Dictionary::appendPacketId(buf, ZT_TRACE_FIELD_PACKET_ID, packetId);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_NETWORK_ID, networkId);
|
||||
if (peerIdentity)
|
||||
Dictionary::appendObject(buf, ZT_TRACE_FIELD_IDENTITY_FINGERPRINT, peerIdentity.fingerprint());
|
||||
if (physicalAddress)
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_ENDPOINT,Endpoint(physicalAddress));
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_PACKET_HOPS,hops);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_PACKET_VERB,verb);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_REASON,reason);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_ENDPOINT, Endpoint(physicalAddress));
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_PACKET_HOPS, hops);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_PACKET_VERB, verb);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_REASON, reason);
|
||||
buf.push_back(0);
|
||||
RR->node->postEvent(tPtr,ZT_EVENT_TRACE,buf.data());
|
||||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
}
|
||||
|
||||
void Trace::_outgoingNetworkFrameDropped(
|
||||
|
@ -147,18 +150,19 @@ void Trace::_outgoingNetworkFrameDropped(
|
|||
const uint8_t *frameData,
|
||||
const ZT_TraceFrameDropReason reason)
|
||||
{
|
||||
FCV<uint8_t,4096> buf;
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_TYPE,ZT_TRACE_VL1_INCOMING_PACKET_DROPPED);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_SOURCE_MAC,sourceMac.toInt());
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_DEST_MAC,destMac.toInt());
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_ETHERTYPE,etherType);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_FRAME_LENGTH,frameLength);
|
||||
FCV< uint8_t, 4096 > buf;
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL1_INCOMING_PACKET_DROPPED);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_CODE_LOCATION, codeLocation);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_NETWORK_ID, networkId);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_SOURCE_MAC, sourceMac.toInt());
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_DEST_MAC, destMac.toInt());
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_ETHERTYPE, etherType);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_FRAME_LENGTH, frameLength);
|
||||
if (frameData)
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_FRAME_DATA,frameData,std::min((unsigned int)64,(unsigned int)frameLength));
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_REASON,reason);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_FRAME_DATA, frameData, std::min((unsigned int)64, (unsigned int)frameLength));
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_REASON, reason);
|
||||
buf.push_back(0);
|
||||
RR->node->postEvent(tPtr,ZT_EVENT_TRACE,buf.data());
|
||||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
}
|
||||
|
||||
void Trace::_incomingNetworkFrameDropped(
|
||||
|
@ -167,6 +171,7 @@ void Trace::_incomingNetworkFrameDropped(
|
|||
const uint64_t networkId,
|
||||
const MAC &sourceMac,
|
||||
const MAC &destMac,
|
||||
const uint16_t etherType,
|
||||
const Identity &peerIdentity,
|
||||
const InetAddress &physicalAddress,
|
||||
const uint8_t hops,
|
||||
|
@ -176,23 +181,24 @@ void Trace::_incomingNetworkFrameDropped(
|
|||
const bool credentialRequestSent,
|
||||
const ZT_TraceFrameDropReason reason)
|
||||
{
|
||||
FCV<uint8_t,4096> buf;
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_TYPE,ZT_TRACE_VL2_INCOMING_FRAME_DROPPED);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_SOURCE_MAC,sourceMac.toInt());
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_DEST_MAC,destMac.toInt());
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_IDENTITY_FINGERPRINT_HASH,peerIdentity.fingerprint().hash,ZT_FINGERPRINT_HASH_SIZE);
|
||||
FCV< uint8_t, 4096 > buf;
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL2_INCOMING_FRAME_DROPPED);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_CODE_LOCATION, codeLocation);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_SOURCE_MAC, sourceMac.toInt());
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_DEST_MAC, destMac.toInt());
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_ETHERTYPE, etherType);
|
||||
Dictionary::appendObject(buf, ZT_TRACE_FIELD_IDENTITY_FINGERPRINT, peerIdentity.fingerprint());
|
||||
if (physicalAddress)
|
||||
Dictionary::appendObject(buf,ZT_TRACE_FIELD_ENDPOINT,Endpoint(physicalAddress));
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_PACKET_HOPS,hops);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_PACKET_VERB,verb);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_FRAME_LENGTH,frameLength);
|
||||
Dictionary::appendObject(buf, ZT_TRACE_FIELD_ENDPOINT, Endpoint(physicalAddress));
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_PACKET_HOPS, hops);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_PACKET_VERB, verb);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_FRAME_LENGTH, frameLength);
|
||||
if (frameData)
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_FRAME_DATA,frameData,std::min((unsigned int)64,(unsigned int)frameLength));
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_FLAG_CREDENTIAL_REQUEST_SENT,credentialRequestSent);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_REASON,reason);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_FRAME_DATA, frameData, std::min((unsigned int)64, (unsigned int)frameLength));
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_FLAG_CREDENTIAL_REQUEST_SENT, credentialRequestSent);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_REASON, reason);
|
||||
buf.push_back(0);
|
||||
RR->node->postEvent(tPtr,ZT_EVENT_TRACE,buf.data());
|
||||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
}
|
||||
|
||||
void Trace::_networkConfigRequestSent(
|
||||
|
@ -200,12 +206,12 @@ void Trace::_networkConfigRequestSent(
|
|||
const uint32_t codeLocation,
|
||||
const uint64_t networkId)
|
||||
{
|
||||
FCV<uint8_t,4096> buf;
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_TYPE,ZT_TRACE_VL2_NETWORK_CONFIG_REQUESTED);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_NETWORK_ID,networkId);
|
||||
FCV< uint8_t, 4096 > buf;
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL2_NETWORK_CONFIG_REQUESTED);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_CODE_LOCATION, codeLocation);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_NETWORK_ID, networkId);
|
||||
buf.push_back(0);
|
||||
RR->node->postEvent(tPtr,ZT_EVENT_TRACE,buf.data());
|
||||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
}
|
||||
|
||||
void Trace::_networkFilter(
|
||||
|
@ -228,30 +234,30 @@ void Trace::_networkFilter(
|
|||
const bool inbound,
|
||||
const int accept)
|
||||
{
|
||||
FCV<uint8_t,4096> buf;
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_TYPE,ZT_TRACE_VL2_NETWORK_FILTER);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_NETWORK_ID,networkId);
|
||||
if ((primaryRuleSetLog)&&(!Utils::allZero(primaryRuleSetLog,512)))
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_PRIMARY_RULE_SET_LOG,primaryRuleSetLog,512);
|
||||
if ((matchingCapabilityRuleSetLog)&&(!Utils::allZero(matchingCapabilityRuleSetLog,512)))
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_MATCHING_CAPABILITY_RULE_SET_LOG,matchingCapabilityRuleSetLog,512);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_MATCHING_CAPABILITY_ID,matchingCapabilityId);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_MATCHING_CAPABILITY_TIMESTAMP,matchingCapabilityTimestamp);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_SOURCE_ZT_ADDRESS,source);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_DEST_ZT_ADDRESS,dest);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_SOURCE_MAC,sourceMac.toInt());
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_DEST_MAC,destMac.toInt());
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_FRAME_LENGTH,frameLength);
|
||||
FCV< uint8_t, 4096 > buf;
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL2_NETWORK_FILTER);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_CODE_LOCATION, codeLocation);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_NETWORK_ID, networkId);
|
||||
if ((primaryRuleSetLog) && (!Utils::allZero(primaryRuleSetLog, 512)))
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_PRIMARY_RULE_SET_LOG, primaryRuleSetLog, 512);
|
||||
if ((matchingCapabilityRuleSetLog) && (!Utils::allZero(matchingCapabilityRuleSetLog, 512)))
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_MATCHING_CAPABILITY_RULE_SET_LOG, matchingCapabilityRuleSetLog, 512);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_MATCHING_CAPABILITY_ID, matchingCapabilityId);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_MATCHING_CAPABILITY_TIMESTAMP, matchingCapabilityTimestamp);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_SOURCE_ZT_ADDRESS, source);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_DEST_ZT_ADDRESS, dest);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_SOURCE_MAC, sourceMac.toInt());
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_DEST_MAC, destMac.toInt());
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_FRAME_LENGTH, frameLength);
|
||||
if (frameData)
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_FRAME_DATA,frameData,std::min((unsigned int)64,(unsigned int)frameLength));
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_ETHERTYPE,etherType);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_VLAN_ID,vlanId);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_RULE_FLAG_NOTEE,noTee);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_RULE_FLAG_INBOUND,inbound);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_RULE_FLAG_ACCEPT,(int32_t)accept);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_FRAME_DATA, frameData, std::min((unsigned int)64, (unsigned int)frameLength));
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_ETHERTYPE, etherType);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_VLAN_ID, vlanId);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_RULE_FLAG_NOTEE, noTee);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_RULE_FLAG_INBOUND, inbound);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_RULE_FLAG_ACCEPT, (int32_t)accept);
|
||||
buf.push_back(0);
|
||||
RR->node->postEvent(tPtr,ZT_EVENT_TRACE,buf.data());
|
||||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
}
|
||||
|
||||
void Trace::_credentialRejected(
|
||||
|
@ -264,17 +270,17 @@ void Trace::_credentialRejected(
|
|||
const uint8_t credentialType,
|
||||
const ZT_TraceCredentialRejectionReason reason)
|
||||
{
|
||||
FCV<uint8_t,4096> buf;
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_TYPE,ZT_TRACE_VL2_NETWORK_FILTER);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_CODE_LOCATION,codeLocation);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_NETWORK_ID,networkId);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_IDENTITY_FINGERPRINT_HASH,identity.fingerprint().hash,ZT_FINGERPRINT_HASH_SIZE);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_CREDENTIAL_ID,credentialId);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_CREDENTIAL_TIMESTAMP,credentialTimestamp);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_CREDENTIAL_TYPE,credentialType);
|
||||
Dictionary::append(buf,ZT_TRACE_FIELD_REASON,reason);
|
||||
FCV< uint8_t, 4096 > buf;
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_TYPE, ZT_TRACE_VL2_NETWORK_CREDENTIAL_REJECTED);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_CODE_LOCATION, codeLocation);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_NETWORK_ID, networkId);
|
||||
Dictionary::appendObject(buf, ZT_TRACE_FIELD_IDENTITY_FINGERPRINT, identity.fingerprint());
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_CREDENTIAL_ID, credentialId);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_CREDENTIAL_TIMESTAMP, credentialTimestamp);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_CREDENTIAL_TYPE, credentialType);
|
||||
Dictionary::append(buf, ZT_TRACE_FIELD_REASON, reason);
|
||||
buf.push_back(0);
|
||||
RR->node->postEvent(tPtr,ZT_EVENT_TRACE,buf.data());
|
||||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
|
|
@ -31,15 +31,25 @@
|
|||
namespace ZeroTier {
|
||||
|
||||
class RuntimeEnvironment;
|
||||
|
||||
class Identity;
|
||||
|
||||
class Peer;
|
||||
|
||||
class Path;
|
||||
|
||||
class Network;
|
||||
|
||||
class MembershipCredential;
|
||||
|
||||
class OwnershipCredential;
|
||||
|
||||
class RevocationCredential;
|
||||
|
||||
class TagCredential;
|
||||
|
||||
class CapabilityCredential;
|
||||
|
||||
struct NetworkConfig;
|
||||
|
||||
/**
|
||||
|
@ -62,14 +72,16 @@ public:
|
|||
{
|
||||
uint8_t l[ZT_MAX_NETWORK_RULES / 2]; // ZT_MAX_NETWORK_RULES 4-bit fields
|
||||
|
||||
ZT_INLINE void log(const unsigned int rn,const uint8_t thisRuleMatches,const uint8_t thisSetMatches) noexcept
|
||||
ZT_INLINE void log(const unsigned int rn, const uint8_t thisRuleMatches, const uint8_t thisSetMatches) noexcept
|
||||
{
|
||||
l[rn >> 1U] |= ( ((thisRuleMatches + 1U) << 2U) | (thisSetMatches + 1U) ) << ((rn & 1U) << 2U);
|
||||
l[rn >> 1U] |= (((thisRuleMatches + 1U) << 2U) | (thisSetMatches + 1U)) << ((rn & 1U) << 2U);
|
||||
}
|
||||
ZT_INLINE void logSkipped(const unsigned int rn,const uint8_t thisSetMatches) noexcept
|
||||
|
||||
ZT_INLINE void logSkipped(const unsigned int rn, const uint8_t thisSetMatches) noexcept
|
||||
{
|
||||
l[rn >> 1U] |= (thisSetMatches + 1U) << ((rn & 1U) << 2U);
|
||||
}
|
||||
|
||||
ZT_INLINE void clear() noexcept
|
||||
{
|
||||
memoryZero(this);
|
||||
|
@ -93,8 +105,8 @@ public:
|
|||
const InetAddress &newExternal,
|
||||
const InetAddress::IpScope scope)
|
||||
{
|
||||
if ((_f & ZT_TRACE_F_VL1) != 0)
|
||||
_resettingPathsInScope(tPtr,codeLocation,reporter,from,oldExternal,newExternal,scope);
|
||||
if ((m_traceFlags & ZT_TRACE_F_VL1) != 0)
|
||||
_resettingPathsInScope(tPtr, codeLocation, reporter, from, oldExternal, newExternal, scope);
|
||||
}
|
||||
|
||||
ZT_INLINE void tryingNewPath(
|
||||
|
@ -107,8 +119,8 @@ public:
|
|||
uint8_t triggeringPacketVerb,
|
||||
const Identity &triggeringPeer)
|
||||
{
|
||||
if ((_f & ZT_TRACE_F_VL1) != 0)
|
||||
_tryingNewPath(tPtr,codeLocation,trying,physicalAddress,triggerAddress,triggeringPacketId,triggeringPacketVerb,triggeringPeer);
|
||||
if ((m_traceFlags & ZT_TRACE_F_VL1) != 0)
|
||||
_tryingNewPath(tPtr, codeLocation, trying, physicalAddress, triggerAddress, triggeringPacketId, triggeringPacketVerb, triggeringPeer);
|
||||
}
|
||||
|
||||
ZT_INLINE void learnedNewPath(
|
||||
|
@ -119,8 +131,8 @@ public:
|
|||
const InetAddress &physicalAddress,
|
||||
const InetAddress &replaced)
|
||||
{
|
||||
if ((_f & ZT_TRACE_F_VL1) != 0)
|
||||
_learnedNewPath(tPtr,codeLocation,packetId,peerIdentity,physicalAddress,replaced);
|
||||
if ((m_traceFlags & ZT_TRACE_F_VL1) != 0)
|
||||
_learnedNewPath(tPtr, codeLocation, packetId, peerIdentity, physicalAddress, replaced);
|
||||
}
|
||||
|
||||
ZT_INLINE void incomingPacketDropped(
|
||||
|
@ -134,8 +146,8 @@ public:
|
|||
uint8_t verb,
|
||||
const ZT_TracePacketDropReason reason)
|
||||
{
|
||||
if ((_f & ZT_TRACE_F_VL1) != 0)
|
||||
_incomingPacketDropped(tPtr,codeLocation,packetId,networkId,peerIdentity,physicalAddress,hops,verb,reason);
|
||||
if ((m_traceFlags & ZT_TRACE_F_VL1) != 0)
|
||||
_incomingPacketDropped(tPtr, codeLocation, packetId, networkId, peerIdentity, physicalAddress, hops, verb, reason);
|
||||
}
|
||||
|
||||
ZT_INLINE void outgoingNetworkFrameDropped(
|
||||
|
@ -149,8 +161,8 @@ public:
|
|||
const uint8_t *frameData,
|
||||
ZT_TraceFrameDropReason reason)
|
||||
{
|
||||
if ((_f & ZT_TRACE_F_VL2) != 0)
|
||||
_outgoingNetworkFrameDropped(tPtr,codeLocation,networkId,sourceMac,destMac,etherType,frameLength,frameData,reason);
|
||||
if ((m_traceFlags & ZT_TRACE_F_VL2) != 0)
|
||||
_outgoingNetworkFrameDropped(tPtr, codeLocation, networkId, sourceMac, destMac, etherType, frameLength, frameData, reason);
|
||||
}
|
||||
|
||||
ZT_INLINE void incomingNetworkFrameDropped(
|
||||
|
@ -159,6 +171,7 @@ public:
|
|||
uint64_t networkId,
|
||||
const MAC &sourceMac,
|
||||
const MAC &destMac,
|
||||
const uint16_t etherType,
|
||||
const Identity &peerIdentity,
|
||||
const InetAddress &physicalAddress,
|
||||
uint8_t hops,
|
||||
|
@ -168,8 +181,8 @@ public:
|
|||
bool credentialRequestSent,
|
||||
ZT_TraceFrameDropReason reason)
|
||||
{
|
||||
if ((_f & ZT_TRACE_F_VL2) != 0)
|
||||
_incomingNetworkFrameDropped(tPtr,codeLocation,networkId,sourceMac,destMac,peerIdentity,physicalAddress,hops,frameLength,frameData,verb,credentialRequestSent,reason);
|
||||
if ((m_traceFlags & ZT_TRACE_F_VL2) != 0)
|
||||
_incomingNetworkFrameDropped(tPtr, codeLocation, networkId, sourceMac, destMac, etherType, peerIdentity, physicalAddress, hops, frameLength, frameData, verb, credentialRequestSent, reason);
|
||||
}
|
||||
|
||||
ZT_INLINE void networkConfigRequestSent(
|
||||
|
@ -177,8 +190,8 @@ public:
|
|||
const uint32_t codeLocation,
|
||||
uint64_t networkId)
|
||||
{
|
||||
if ((_f & ZT_TRACE_F_VL2) != 0)
|
||||
_networkConfigRequestSent(tPtr,codeLocation,networkId);
|
||||
if ((m_traceFlags & ZT_TRACE_F_VL2) != 0)
|
||||
_networkConfigRequestSent(tPtr, codeLocation, networkId);
|
||||
}
|
||||
|
||||
ZT_INLINE void networkFilter(
|
||||
|
@ -201,7 +214,7 @@ public:
|
|||
bool inbound,
|
||||
int accept)
|
||||
{
|
||||
if ((_f & ZT_TRACE_F_VL2_FILTER) != 0) {
|
||||
if ((m_traceFlags & ZT_TRACE_F_VL2_FILTER) != 0) {
|
||||
_networkFilter(
|
||||
tPtr,
|
||||
codeLocation,
|
||||
|
@ -234,8 +247,8 @@ public:
|
|||
uint8_t credentialType,
|
||||
ZT_TraceCredentialRejectionReason reason)
|
||||
{
|
||||
if ((_f & ZT_TRACE_F_VL2) != 0)
|
||||
_credentialRejected(tPtr,codeLocation,networkId,identity,credentialId,credentialTimestamp,credentialType,reason);
|
||||
if ((m_traceFlags & ZT_TRACE_F_VL2) != 0)
|
||||
_credentialRejected(tPtr, codeLocation, networkId, identity, credentialId, credentialTimestamp, credentialType, reason);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -247,6 +260,7 @@ private:
|
|||
const InetAddress &oldExternal,
|
||||
const InetAddress &newExternal,
|
||||
InetAddress::IpScope scope);
|
||||
|
||||
void _tryingNewPath(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
|
@ -256,6 +270,7 @@ private:
|
|||
uint64_t triggeringPacketId,
|
||||
uint8_t triggeringPacketVerb,
|
||||
const Identity &triggeringPeer);
|
||||
|
||||
void _learnedNewPath(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
|
@ -263,6 +278,7 @@ private:
|
|||
const Identity &peerIdentity,
|
||||
const InetAddress &physicalAddress,
|
||||
const InetAddress &replaced);
|
||||
|
||||
void _incomingPacketDropped(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
|
@ -273,6 +289,7 @@ private:
|
|||
uint8_t hops,
|
||||
uint8_t verb,
|
||||
ZT_TracePacketDropReason reason);
|
||||
|
||||
void _outgoingNetworkFrameDropped(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
|
@ -283,12 +300,14 @@ private:
|
|||
uint16_t frameLength,
|
||||
const uint8_t *frameData,
|
||||
ZT_TraceFrameDropReason reason);
|
||||
|
||||
void _incomingNetworkFrameDropped(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
uint64_t networkId,
|
||||
const MAC &sourceMac,
|
||||
const MAC &destMac,
|
||||
const uint16_t etherType,
|
||||
const Identity &peerIdentity,
|
||||
const InetAddress &physicalAddress,
|
||||
uint8_t hops,
|
||||
|
@ -297,10 +316,12 @@ private:
|
|||
uint8_t verb,
|
||||
bool credentialRequestSent,
|
||||
ZT_TraceFrameDropReason reason);
|
||||
|
||||
void _networkConfigRequestSent(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
uint64_t networkId);
|
||||
|
||||
void _networkFilter(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
|
@ -320,6 +341,7 @@ private:
|
|||
bool noTee,
|
||||
bool inbound,
|
||||
int accept);
|
||||
|
||||
void _credentialRejected(
|
||||
void *tPtr,
|
||||
uint32_t codeLocation,
|
||||
|
@ -331,7 +353,7 @@ private:
|
|||
ZT_TraceCredentialRejectionReason reason);
|
||||
|
||||
const RuntimeEnvironment *const RR;
|
||||
volatile unsigned int _f; // faster than atomic, but may not "instantly" change... will after next memory fence
|
||||
volatile unsigned int m_traceFlags; // faster than atomic, but may not "instantly" change... should be okay
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
|
|
@ -725,7 +725,8 @@ enum ZT_TraceEventType
|
|||
ZT_TRACE_VL2_OUTGOING_FRAME_DROPPED = 100,
|
||||
ZT_TRACE_VL2_INCOMING_FRAME_DROPPED = 101,
|
||||
ZT_TRACE_VL2_NETWORK_CONFIG_REQUESTED = 102,
|
||||
ZT_TRACE_VL2_NETWORK_FILTER = 103
|
||||
ZT_TRACE_VL2_NETWORK_FILTER = 103,
|
||||
ZT_TRACE_VL2_NETWORK_CREDENTIAL_REJECTED = 104,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -778,10 +779,10 @@ enum ZT_TraceCredentialRejectionReason
|
|||
#define ZT_TRACE_FIELD_TRIGGER_FROM_ENDPOINT "te"
|
||||
#define ZT_TRACE_FIELD_TRIGGER_FROM_PACKET_ID "ti"
|
||||
#define ZT_TRACE_FIELD_TRIGGER_FROM_PACKET_VERB "tv"
|
||||
#define ZT_TRACE_FIELD_TRIGGER_FROM_PEER_FINGERPRINT_HASH "tp"
|
||||
#define ZT_TRACE_FIELD_TRIGGER_FROM_PEER_FINGERPRINT "tp"
|
||||
#define ZT_TRACE_FIELD_MESSAGE "m"
|
||||
#define ZT_TRACE_FIELD_RESET_ADDRESS_SCOPE "rs"
|
||||
#define ZT_TRACE_FIELD_IDENTITY_FINGERPRINT_HASH "f"
|
||||
#define ZT_TRACE_FIELD_IDENTITY_FINGERPRINT "f"
|
||||
#define ZT_TRACE_FIELD_PACKET_ID "p"
|
||||
#define ZT_TRACE_FIELD_PACKET_VERB "v"
|
||||
#define ZT_TRACE_FIELD_PACKET_HOPS "h"
|
||||
|
@ -933,9 +934,10 @@ enum ZT_Event
|
|||
* Trace (debugging) message
|
||||
*
|
||||
* These events are only generated if this is a TRACE-enabled build.
|
||||
* This is for local debug traces, not remote trace diagnostics.
|
||||
* This is for local debug traces, not remote trace diagnostics. The
|
||||
* supplied Dictionary will always be null-terminated.
|
||||
*
|
||||
* Meta-data: struct of type ZT_Trace_*
|
||||
* Meta-data: null-terminated Dictionary containing trace info
|
||||
*/
|
||||
ZT_EVENT_TRACE = 5,
|
||||
|
||||
|
@ -2620,6 +2622,19 @@ ZT_SDK_API int ZT_Endpoint_fromString(
|
|||
ZT_Endpoint *ep,
|
||||
const char *str);
|
||||
|
||||
/**
|
||||
* Decode a binary serialized endpoint
|
||||
*
|
||||
* @param ep Endpoint structure to populate
|
||||
* @param bytes Bytes to decode
|
||||
* @param len Length of bytes
|
||||
* @return OK (0) or error code
|
||||
*/
|
||||
ZT_SDK_API int ZT_Endpoint_fromBytes(
|
||||
ZT_Endpoint *ep,
|
||||
const void *bytes,
|
||||
unsigned int len);
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
|
@ -3021,6 +3036,24 @@ ZT_SDK_API const int ZT_AF_INET,ZT_AF_INET6;
|
|||
|
||||
/* ---------------------------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Parse a dictionary and invoke 'f' for each key/value pair.
|
||||
*
|
||||
* This can be used to parse a dictionary such as a network config or trace
|
||||
* data supplied with a trace event.
|
||||
*
|
||||
* Function arguments are: arg, key, length of key (not including terminating null),
|
||||
* value, length of value in bytes.
|
||||
*
|
||||
* @param dict Dictionary in serialized form
|
||||
* @param len Maximum length of 'dict' (will also end at first zero)
|
||||
* @param f Function to invoke with each key and (binary) value
|
||||
* @return Non-zero if dictionary was valid
|
||||
*/
|
||||
ZT_SDK_API int ZT_Dictionary_parse(const void *dict, unsigned int len, void *arg, void (*f)(void *, const char *, unsigned int, const void *, unsigned int));
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------------------- */
|
||||
|
||||
ZT_SDK_API uint64_t ZT_random();
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -15,6 +15,16 @@ use std::cmp::Ordering;
|
|||
|
||||
pub struct Address(pub u64);
|
||||
|
||||
impl From<&[u8]> for Address {
|
||||
fn from(bytes: &[u8]) -> Self {
|
||||
if bytes.len() >= 5 {
|
||||
Address(((bytes[0] as u64) << 32) | ((bytes[0] as u64) << 24) | ((bytes[0] as u64) << 16) | ((bytes[0] as u64) << 8) | (bytes[0] as u64))
|
||||
} else {
|
||||
Address(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for Address {
|
||||
fn to_string(&self) -> String {
|
||||
format!("{:0>10x}", self.0)
|
||||
|
@ -23,14 +33,14 @@ impl ToString for Address {
|
|||
|
||||
impl From<u64> for Address {
|
||||
#[inline(always)]
|
||||
fn from(i: u64) -> Address {
|
||||
fn from(i: u64) -> Self {
|
||||
Address(i)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for Address {
|
||||
#[inline(always)]
|
||||
fn from(s: &str) -> Address {
|
||||
fn from(s: &str) -> Self {
|
||||
Address(u64::from_str_radix(s, 16).unwrap_or(0))
|
||||
}
|
||||
}
|
||||
|
|
109
rust-zerotier-core/src/dictionary.rs
Normal file
109
rust-zerotier-core/src/dictionary.rs
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c)2013-2020 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2025-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::c_void;
|
||||
use std::os::raw::{c_char, c_uint};
|
||||
|
||||
use crate::{cstr_to_string, ResultCode};
|
||||
use crate::capi::ZT_Dictionary_parse;
|
||||
|
||||
/// Rust interface to the Dictionary data structure.
|
||||
pub struct Dictionary {
|
||||
data: HashMap<String, Vec<u8>>,
|
||||
}
|
||||
|
||||
// Callback called by ZeroTier core to parse a Dictionary, populates a Rust Dictionary object.
|
||||
extern "C" fn populate_dict_callback(arg: *mut c_void, c_key: *const c_char, key_len: c_uint, c_value: *const c_void, value_len: c_uint) {
|
||||
unsafe {
|
||||
let d = &mut *(arg.cast::<Dictionary>());
|
||||
let k = cstr_to_string(c_key, key_len as isize);
|
||||
if !k.is_empty() {
|
||||
let mut v: Vec<u8> = Vec::new();
|
||||
if value_len > 0 {
|
||||
let vp = c_value.cast::<u8>();
|
||||
v.reserve(value_len as usize);
|
||||
for i in 0..(value_len as isize) {
|
||||
v.push(*(vp.offset(i)));
|
||||
}
|
||||
}
|
||||
let _ = d.data.insert(k, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type DictionaryIter = std::collections::hash_map::Iter<'_, String, Vec<u8>>;
|
||||
|
||||
impl Dictionary {
|
||||
#[inline(always)]
|
||||
pub fn new() -> Dictionary {
|
||||
Dictionary {
|
||||
data: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_from_bytes(dict: &[u8]) -> Result<Dictionary, ResultCode> {
|
||||
let mut d = Dictionary{
|
||||
data: HashMap::new(),
|
||||
};
|
||||
unsafe {
|
||||
if ZT_Dictionary_parse(dict.as_ptr().cast(), dict.len() as c_uint, (&mut d as *mut Dictionary).cast(), Some(populate_dict_callback)) != 0 {
|
||||
Ok(d)
|
||||
} else {
|
||||
Err(ResultCode::ErrorBadParameter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get<K: AsRef<[u8]>>(&self, k: K) -> Option<&Vec<u8>> {
|
||||
let ks = String::from(String::from_utf8_lossy(k.as_ref()));
|
||||
self.data.get(&ks)
|
||||
}
|
||||
|
||||
pub fn get_str<K: AsRef<[u8]>>(&self, k: K) -> Option<&str> {
|
||||
let v = self.data.get(k);
|
||||
v.map_or(None, |v: Vec<u8>| {
|
||||
let vs = std::str::from_utf8(v.as_slice());
|
||||
vs.map_or(None, |v: &str| {
|
||||
Some(v)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_string_or_empty<K: AsRef<[u8]>>(&self, k: K) -> String {
|
||||
self.get_str(k).map_or_else(|| { String::new() },|s| { String::from(s) })
|
||||
}
|
||||
|
||||
pub fn get_ui<K: AsRef<[u8]>>(&self, k: K) -> Option<u64> {
|
||||
let v = self.get_str(k);
|
||||
v.map_or(None, |v: &str| {
|
||||
let vi = u64::from_str_radix(v, 16);
|
||||
vi.map_or(None, |i: u64| {
|
||||
Some(i)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn iter(&self) -> DictionaryIter {
|
||||
self.data.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for Dictionary {
|
||||
fn clone(&self) -> Self {
|
||||
Dictionary {
|
||||
data: self.data.clone(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
use std::ffi::CString;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::os::raw::c_char;
|
||||
use std::os::raw::{c_char, c_uint};
|
||||
|
||||
use num_derive::{FromPrimitive, ToPrimitive};
|
||||
use num_traits::FromPrimitive;
|
||||
|
@ -47,6 +47,21 @@ impl Endpoint {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn new_from_bytes(bytes: &[u8]) -> Result<Endpoint, ResultCode> {
|
||||
unsafe {
|
||||
let mut cep: MaybeUninit<ztcore::ZT_Endpoint> = MaybeUninit::uninit();
|
||||
let ec = ztcore::ZT_Endpoint_fromBytes(bytes.as_ptr().cast(), bytes.len() as c_uint);
|
||||
if ec == 0 {
|
||||
let epi = cep.assume_init();
|
||||
return Ok(Endpoint{
|
||||
type_: EndpointType::from_i32(epi.type_ as i32).unwrap(),
|
||||
capi: epi
|
||||
});
|
||||
}
|
||||
return Err(ResultCode::from_i32(ec).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_from_string(s: &str) -> Result<Endpoint, ResultCode> {
|
||||
let cs = CString::new(s);
|
||||
if cs.is_err() {
|
||||
|
|
|
@ -17,6 +17,7 @@ use std::os::raw::{c_char, c_int};
|
|||
|
||||
use crate::*;
|
||||
use crate::capi as ztcore;
|
||||
use std::ptr::copy_nonoverlapping;
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct Fingerprint {
|
||||
|
@ -51,6 +52,22 @@ impl Fingerprint {
|
|||
}
|
||||
return Err(ResultCode::ErrorBadParameter);
|
||||
}
|
||||
|
||||
pub fn new_from_bytes(bytes: &[u8]) -> Result<Fingerprint, ResultCode> {
|
||||
if bytes.len() < (5 + 48) {
|
||||
let h: MaybeUninit<[u8; 48]> = MaybeUninit::uninit();
|
||||
let mut fp = Fingerprint {
|
||||
address: Address::from(bytes),
|
||||
hash: unsafe { h.assume_init() },
|
||||
};
|
||||
unsafe {
|
||||
copy_nonoverlapping(bytes.as_ptr().offset(5), fp.hash.as_mut_ptr(), 48);
|
||||
}
|
||||
Ok(fp)
|
||||
} else {
|
||||
Err(ResultCode::ErrorBadParameter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for Fingerprint {
|
||||
|
|
|
@ -33,6 +33,8 @@ mod buffer;
|
|||
mod portableatomici64;
|
||||
mod virtualnetworkconfig;
|
||||
mod multicastgroup;
|
||||
mod dictionary;
|
||||
pub mod trace;
|
||||
|
||||
use crate::capi as ztcore;
|
||||
|
||||
|
@ -52,6 +54,7 @@ pub use buffer::Buffer;
|
|||
pub use portableatomici64::PortableAtomicI64;
|
||||
pub use virtualnetworkconfig::*;
|
||||
pub use multicastgroup::MulticastGroup;
|
||||
pub use dictionary::*;
|
||||
|
||||
/// Recommended minimum thread stack size for background threads.
|
||||
pub const RECOMMENDED_THREAD_STACK_SIZE: usize = 262144;
|
||||
|
@ -105,52 +108,6 @@ pub enum CredentialType {
|
|||
Revocation = ztcore::ZT_CredentialType_ZT_CREDENTIAL_TYPE_REVOCATION as isize,
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
||||
pub enum TraceEventType {
|
||||
UnexpectedError = ztcore::ZT_TraceEventType_ZT_TRACE_UNEXPECTED_ERROR as isize,
|
||||
ResetingPathsInScope = ztcore::ZT_TraceEventType_ZT_TRACE_VL1_RESETTING_PATHS_IN_SCOPE as isize,
|
||||
TryingNewPath = ztcore::ZT_TraceEventType_ZT_TRACE_VL1_TRYING_NEW_PATH as isize,
|
||||
LearnedNewPath = ztcore::ZT_TraceEventType_ZT_TRACE_VL1_LEARNED_NEW_PATH as isize,
|
||||
IncomingPacketDropped = ztcore::ZT_TraceEventType_ZT_TRACE_VL1_INCOMING_PACKET_DROPPED as isize,
|
||||
OutgoingFrameDropped = ztcore::ZT_TraceEventType_ZT_TRACE_VL2_OUTGOING_FRAME_DROPPED as isize,
|
||||
IncomingFrameDropped = ztcore::ZT_TraceEventType_ZT_TRACE_VL2_INCOMING_FRAME_DROPPED as isize,
|
||||
NetworkConfigRequested = ztcore::ZT_TraceEventType_ZT_TRACE_VL2_NETWORK_CONFIG_REQUESTED as isize,
|
||||
NetworkFilter = ztcore::ZT_TraceEventType_ZT_TRACE_VL2_NETWORK_FILTER as isize,
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
||||
pub enum TracePacketDropReason {
|
||||
Unspecified = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_UNSPECIFIED as isize,
|
||||
PeerTooOld = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_PEER_TOO_OLD as isize,
|
||||
MalformedPacket = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET as isize,
|
||||
MacFailed = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED as isize,
|
||||
RateLimitExceeded = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_RATE_LIMIT_EXCEEDED as isize,
|
||||
InvalidObject = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT as isize,
|
||||
InvalidCompressedData = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_INVALID_COMPRESSED_DATA as isize,
|
||||
UnrecognizedVerb = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_UNRECOGNIZED_VERB as isize,
|
||||
ReplyNotExpected = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_REPLY_NOT_EXPECTED as isize,
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
||||
pub enum TraceFrameDropReason {
|
||||
Unspecified = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_UNSPECIFIED as isize,
|
||||
BridgingNotAllowedRemote = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_BRIDGING_NOT_ALLOWED_REMOTE as isize,
|
||||
BridgingNotAllowedLocal = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_BRIDGING_NOT_ALLOWED_LOCAL as isize,
|
||||
MulticastDisabled = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_MULTICAST_DISABLED as isize,
|
||||
BroadcastDisabled = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_BROADCAST_DISABLED as isize,
|
||||
FilterBlocked = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_FILTER_BLOCKED as isize,
|
||||
FilterBlockedAtBridgeReplication = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_FILTER_BLOCKED_AT_BRIDGE_REPLICATION as isize,
|
||||
PermissionDenied = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_PERMISSION_DENIED as isize,
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
||||
pub enum TraceCredentialRejectionReason {
|
||||
SignatureVerificationFailed = ztcore::ZT_TraceCredentialRejectionReason_ZT_TRACE_CREDENTIAL_REJECTION_REASON_SIGNATURE_VERIFICATION_FAILED as isize,
|
||||
Revoked = ztcore::ZT_TraceCredentialRejectionReason_ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED as isize,
|
||||
OlderThanLatest = ztcore::ZT_TraceCredentialRejectionReason_ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST as isize,
|
||||
Invalid = ztcore::ZT_TraceCredentialRejectionReason_ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID as isize,
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
||||
pub enum ResultCode {
|
||||
Ok = ztcore::ZT_ResultCode_ZT_RESULT_OK as isize,
|
||||
|
@ -194,12 +151,6 @@ pub fn version() -> (i32, i32, i32, i32) {
|
|||
(major as i32, minor as i32, revision as i32, build as i32)
|
||||
}
|
||||
|
||||
/// Convenience function to get the number of milliseconds since the Unix epoch.
|
||||
#[inline(always)]
|
||||
pub fn now() -> i64 {
|
||||
std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_millis() as i64
|
||||
}
|
||||
|
||||
/// Get a random 64-bit integer using the non-cryptographic PRNG in the ZeroTier core.
|
||||
#[inline(always)]
|
||||
pub fn random() -> u64 {
|
||||
|
|
|
@ -53,7 +53,7 @@ impl Locator {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn endpoints(&self) -> Box<[Endpoint]> {
|
||||
pub fn endpoints(&self) -> Vec<Endpoint> {
|
||||
let mut eps: Vec<Endpoint> = Vec::new();
|
||||
unsafe {
|
||||
let ep_count = ztcore::ZT_Locator_endpointCount(self.capi) as usize;
|
||||
|
@ -65,7 +65,7 @@ impl Locator {
|
|||
}
|
||||
}
|
||||
}
|
||||
eps.into_boxed_slice()
|
||||
eps
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ use crate::*;
|
|||
use crate::capi as ztcore;
|
||||
|
||||
/// Maximum delay between calls to run_background_tasks()
|
||||
pub const NODE_BACKGROUND_TASKS_MAX_INTERVAL: u64 = 250;
|
||||
pub const NODE_BACKGROUND_TASKS_MAX_INTERVAL: u64 = 200;
|
||||
|
||||
#[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
||||
pub enum Event {
|
||||
|
@ -316,9 +316,7 @@ extern "C" fn zt_path_lookup_function<T: NodeEventHandler<N> + Sync + Send + Clo
|
|||
|
||||
impl<T: NodeEventHandler<N> + Sync + Send + Clone + 'static, N: 'static> Node<T, N> {
|
||||
/// Create a new Node with a given event handler.
|
||||
pub fn new(event_handler: T) -> Result<Node<T, N>, ResultCode> {
|
||||
let now = now();
|
||||
|
||||
pub fn new(event_handler: T, now: i64) -> Result<Node<T, N>, ResultCode> {
|
||||
let mut n = Node {
|
||||
event_handler: event_handler.clone(),
|
||||
capi: null_mut(),
|
||||
|
@ -354,15 +352,14 @@ impl<T: NodeEventHandler<N> + Sync + Send + Clone + 'static, N: 'static> Node<T,
|
|||
/// The first call should happen no more than NODE_BACKGROUND_TASKS_MAX_INTERVAL milliseconds
|
||||
/// since the node was created, and after this runs it returns the amount of time the caller
|
||||
/// should wait before calling it again.
|
||||
pub fn process_background_tasks(&self) -> u64 {
|
||||
let current_time = now();
|
||||
self.now.set(current_time);
|
||||
pub fn process_background_tasks(&self, now: i64) -> u64 {
|
||||
self.now.set(now);
|
||||
|
||||
let mut next_task_deadline: i64 = current_time;
|
||||
let mut next_task_deadline: i64 = now;
|
||||
unsafe {
|
||||
ztcore::ZT_Node_processBackgroundTasks(self.capi, null_mut(), current_time, (&mut next_task_deadline as *mut i64).cast());
|
||||
ztcore::ZT_Node_processBackgroundTasks(self.capi, null_mut(), now, (&mut next_task_deadline as *mut i64).cast());
|
||||
}
|
||||
let mut next_delay = next_task_deadline - current_time;
|
||||
let mut next_delay = next_task_deadline - now;
|
||||
|
||||
if next_delay < 1 {
|
||||
next_delay = 1;
|
||||
|
|
411
rust-zerotier-core/src/trace.rs
Normal file
411
rust-zerotier-core/src/trace.rs
Normal file
|
@ -0,0 +1,411 @@
|
|||
/*
|
||||
* Copyright (c)2013-2020 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2025-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
use std::str;
|
||||
|
||||
use crate::{capi as ztcore, Dictionary, Endpoint, Fingerprint, IpScope, MAC, Address, CredentialType};
|
||||
use num_derive::{FromPrimitive, ToPrimitive};
|
||||
use num_traits::FromPrimitive;
|
||||
use crate::trace::TraceEvent::TryingNewPath;
|
||||
|
||||
/*
|
||||
// Used to construct String instances from constant strings in C. This assumes
|
||||
// the string is valid UTF8 and may panic or crash otherwise.
|
||||
fn string_from_static_array<A: AsRef<[u8]>>(a: A) -> &'static str {
|
||||
str::from_utf8(a.as_ref()).unwrap()
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref TRACE_FIELD_TYPE: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_TYPE);
|
||||
pub static ref TRACE_FIELD_CODE_LOCATION: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_CODE_LOCATION);
|
||||
pub static ref TRACE_FIELD_ENDPOINT: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_ENDPOINT);
|
||||
pub static ref TRACE_FIELD_OLD_ENDPOINT: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_OLD_ENDPOINT);
|
||||
pub static ref TRACE_FIELD_NEW_ENDPOINT: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_NEW_ENDPOINT);
|
||||
pub static ref TRACE_FIELD_TRIGGER_FROM_ENDPOINT: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_TRIGGER_FROM_ENDPOINT);
|
||||
pub static ref TRACE_FIELD_TRIGGER_FROM_PACKET_ID: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_TRIGGER_FROM_PACKET_ID);
|
||||
pub static ref TRACE_FIELD_TRIGGER_FROM_PACKET_VERB: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_TRIGGER_FROM_PACKET_VERB);
|
||||
pub static ref TRACE_FIELD_TRIGGER_FROM_PEER_FINGERPRINT_HASH: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_TRIGGER_FROM_PEER_FINGERPRINT_HASH);
|
||||
pub static ref TRACE_FIELD_MESSAGE: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_MESSAGE);
|
||||
pub static ref TRACE_FIELD_RESET_ADDRESS_SCOPE: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_RESET_ADDRESS_SCOPE);
|
||||
pub static ref TRACE_FIELD_IDENTITY_FINGERPRINT_HASH: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_IDENTITY_FINGERPRINT_HASH);
|
||||
pub static ref TRACE_FIELD_PACKET_ID: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_PACKET_ID);
|
||||
pub static ref TRACE_FIELD_PACKET_VERB: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_PACKET_VERB);
|
||||
pub static ref TRACE_FIELD_PACKET_HOPS: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_PACKET_HOPS);
|
||||
pub static ref TRACE_FIELD_NETWORK_ID: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_NETWORK_ID);
|
||||
pub static ref TRACE_FIELD_REASON: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_REASON);
|
||||
pub static ref TRACE_FIELD_SOURCE_MAC: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_SOURCE_MAC);
|
||||
pub static ref TRACE_FIELD_DEST_MAC: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_DEST_MAC);
|
||||
pub static ref TRACE_FIELD_ETHERTYPE: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_ETHERTYPE);
|
||||
pub static ref TRACE_FIELD_VLAN_ID: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_VLAN_ID);
|
||||
pub static ref TRACE_FIELD_FRAME_LENGTH: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_FRAME_LENGTH);
|
||||
pub static ref TRACE_FIELD_FRAME_DATA: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_FRAME_DATA);
|
||||
pub static ref TRACE_FIELD_FLAG_CREDENTIAL_REQUEST_SENT: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_FLAG_CREDENTIAL_REQUEST_SENT);
|
||||
pub static ref TRACE_FIELD_PRIMARY_RULE_SET_LOG: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_PRIMARY_RULE_SET_LOG);
|
||||
pub static ref TRACE_FIELD_MATCHING_CAPABILITY_RULE_SET_LOG: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_MATCHING_CAPABILITY_RULE_SET_LOG);
|
||||
pub static ref TRACE_FIELD_MATCHING_CAPABILITY_ID: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_MATCHING_CAPABILITY_ID);
|
||||
pub static ref TRACE_FIELD_MATCHING_CAPABILITY_TIMESTAMP: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_MATCHING_CAPABILITY_TIMESTAMP);
|
||||
pub static ref TRACE_FIELD_SOURCE_ZT_ADDRESS: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_SOURCE_ZT_ADDRESS);
|
||||
pub static ref TRACE_FIELD_DEST_ZT_ADDRESS: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_DEST_ZT_ADDRESS);
|
||||
pub static ref TRACE_FIELD_MATCHING_CAPABILITY_ID: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_MATCHING_CAPABILITY_ID);
|
||||
pub static ref TRACE_FIELD_RULE_FLAG_NOTEE: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_RULE_FLAG_NOTEE);
|
||||
pub static ref TRACE_FIELD_RULE_FLAG_INBOUND: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_RULE_FLAG_INBOUND);
|
||||
pub static ref TRACE_FIELD_RULE_FLAG_ACCEPT: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_RULE_FLAG_ACCEPT);
|
||||
pub static ref TRACE_FIELD_CREDENTIAL_ID: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_CREDENTIAL_ID);
|
||||
pub static ref TRACE_FIELD_CREDENTIAL_TYPE: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_CREDENTIAL_TYPE);
|
||||
pub static ref TRACE_FIELD_CREDENTIAL_TIMESTAMP: &'static str = string_from_static_array(ztcore::ZT_TRACE_FIELD_CREDENTIAL_TIMESTAMP);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
#[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
||||
pub enum TraceEventType {
|
||||
UnexpectedError = ztcore::ZT_TraceEventType_ZT_TRACE_UNEXPECTED_ERROR as isize,
|
||||
ResetingPathsInScope = ztcore::ZT_TraceEventType_ZT_TRACE_VL1_RESETTING_PATHS_IN_SCOPE as isize,
|
||||
TryingNewPath = ztcore::ZT_TraceEventType_ZT_TRACE_VL1_TRYING_NEW_PATH as isize,
|
||||
LearnedNewPath = ztcore::ZT_TraceEventType_ZT_TRACE_VL1_LEARNED_NEW_PATH as isize,
|
||||
IncomingPacketDropped = ztcore::ZT_TraceEventType_ZT_TRACE_VL1_INCOMING_PACKET_DROPPED as isize,
|
||||
OutgoingFrameDropped = ztcore::ZT_TraceEventType_ZT_TRACE_VL2_OUTGOING_FRAME_DROPPED as isize,
|
||||
IncomingFrameDropped = ztcore::ZT_TraceEventType_ZT_TRACE_VL2_INCOMING_FRAME_DROPPED as isize,
|
||||
NetworkConfigRequested = ztcore::ZT_TraceEventType_ZT_TRACE_VL2_NETWORK_CONFIG_REQUESTED as isize,
|
||||
NetworkFilter = ztcore::ZT_TraceEventType_ZT_TRACE_VL2_NETWORK_FILTER as isize,
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
#[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
||||
pub enum TracePacketDropReason {
|
||||
Unspecified = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_UNSPECIFIED as isize,
|
||||
PeerTooOld = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_PEER_TOO_OLD as isize,
|
||||
MalformedPacket = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET as isize,
|
||||
MacFailed = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED as isize,
|
||||
RateLimitExceeded = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_RATE_LIMIT_EXCEEDED as isize,
|
||||
InvalidObject = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT as isize,
|
||||
InvalidCompressedData = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_INVALID_COMPRESSED_DATA as isize,
|
||||
UnrecognizedVerb = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_UNRECOGNIZED_VERB as isize,
|
||||
ReplyNotExpected = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_REPLY_NOT_EXPECTED as isize,
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
||||
pub enum TraceFrameDropReason {
|
||||
Unspecified = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_UNSPECIFIED as isize,
|
||||
BridgingNotAllowedRemote = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_BRIDGING_NOT_ALLOWED_REMOTE as isize,
|
||||
BridgingNotAllowedLocal = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_BRIDGING_NOT_ALLOWED_LOCAL as isize,
|
||||
MulticastDisabled = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_MULTICAST_DISABLED as isize,
|
||||
BroadcastDisabled = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_BROADCAST_DISABLED as isize,
|
||||
FilterBlocked = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_FILTER_BLOCKED as isize,
|
||||
FilterBlockedAtBridgeReplication = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_FILTER_BLOCKED_AT_BRIDGE_REPLICATION as isize,
|
||||
PermissionDenied = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_PERMISSION_DENIED as isize,
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
||||
pub enum TraceCredentialRejectionReason {
|
||||
SignatureVerificationFailed = ztcore::ZT_TraceCredentialRejectionReason_ZT_TRACE_CREDENTIAL_REJECTION_REASON_SIGNATURE_VERIFICATION_FAILED as isize,
|
||||
Revoked = ztcore::ZT_TraceCredentialRejectionReason_ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED as isize,
|
||||
OlderThanLatest = ztcore::ZT_TraceCredentialRejectionReason_ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST as isize,
|
||||
Invalid = ztcore::ZT_TraceCredentialRejectionReason_ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID as isize,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub enum TraceAccept {
|
||||
Reject,
|
||||
Accept,
|
||||
SuperAccept,
|
||||
}
|
||||
|
||||
pub enum TraceEvent {
|
||||
UnexpectedError {
|
||||
code_location: u32,
|
||||
message: String,
|
||||
},
|
||||
ResetingPathsInScope {
|
||||
code_location: u32,
|
||||
reporter: Option<Fingerprint>,
|
||||
reporter_endpoint: Option<Endpoint>,
|
||||
my_old_external: Option<Endpoint>,
|
||||
my_new_external: Option<Endpoint>,
|
||||
scope: IpScope,
|
||||
},
|
||||
TryingNewPath {
|
||||
code_location: u32,
|
||||
trying: Fingerprint,
|
||||
trigger_peer: Option<Fingerproint>,
|
||||
trigger_packet_from: Option<Endpoint>,
|
||||
trigger_packet_id: u64,
|
||||
trigger_packet_verb: i32,
|
||||
},
|
||||
LearnedNewPath {
|
||||
code_location: u32,
|
||||
learned_from_packet_id: u64,
|
||||
peer: Fingerprint,
|
||||
new_address: Option<Endpoint>,
|
||||
replaced_address: Option<Endpoint>,
|
||||
},
|
||||
IncomingPacketDropped {
|
||||
code_location: u32,
|
||||
packet_id: u64,
|
||||
network_id: u64,
|
||||
peer: Option<Fingerprint>,
|
||||
peer_address: Option<Endpoint>,
|
||||
hops: i32,
|
||||
verb: i32,
|
||||
reason: TracePacketDropReason,
|
||||
},
|
||||
OutgoingFrameDropped {
|
||||
code_location: u32,
|
||||
network_id: u64,
|
||||
source_mac: MAC,
|
||||
dest_mac: MAC,
|
||||
ethertype: u16,
|
||||
frame_length: u32,
|
||||
frame_data: Vec<u8>,
|
||||
reason: TraceFrameDropReason,
|
||||
},
|
||||
IncomingFrameDropped {
|
||||
code_location: u32,
|
||||
source_mac: MAC,
|
||||
dest_mac: MAC,
|
||||
ethertype: u16,
|
||||
peer: Fingerprint,
|
||||
peer_address: Option<Endpoint>,
|
||||
hops: i32,
|
||||
verb: i32,
|
||||
frame_length: u32,
|
||||
frame_data: Vec<u8>,
|
||||
credential_request_sent: bool,
|
||||
reason: TraceFrameDropReason,
|
||||
},
|
||||
NetworkConfigRequested {
|
||||
code_location: u32,
|
||||
network_id: u64,
|
||||
},
|
||||
NetworkFilter {
|
||||
code_location: u32,
|
||||
network_id: u64,
|
||||
primary_rule_set_log: Vec<u8>,
|
||||
matching_capability_rule_set_log: Vec<u8>,
|
||||
matching_capability_id: u32,
|
||||
matching_capability_timestamp: i64,
|
||||
source_address: Address,
|
||||
dest_address: Address,
|
||||
source_mac: MAC,
|
||||
dest_mac: MAC,
|
||||
frame_length: u32,
|
||||
frame_data: Vec<u8>,
|
||||
ethertype: u16,
|
||||
vlan_id: u16,
|
||||
rule_flag_notee: bool,
|
||||
rule_flag_inbound: bool,
|
||||
rule_flag_accept: TraceAccept,
|
||||
},
|
||||
NetworkCredentialRejected {
|
||||
code_location: u32,
|
||||
network_id: u64,
|
||||
from_peer: Fingerprint,
|
||||
credential_id: u32,
|
||||
credential_timestamp: i64,
|
||||
credential_type: CredentialType,
|
||||
reason: TraceCredentialRejectionReason,
|
||||
},
|
||||
}
|
||||
|
||||
fn trace_optional_endpoint(bytes: Option<&Vec<u8>>) -> Option<Endpoint> {
|
||||
bytes.map_or(None, |ep| {
|
||||
Endpoint::new_from_bytes(ep.as_slice()).map_or(None, |ep| {
|
||||
Some(ep)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn trace_optional_fingerprint(bytes: Option<&Vec<u8>>) -> Option<Fingerprint> {
|
||||
bytes.map_or(None, |fp| {
|
||||
Fingerprint::new_from_bytes(fp).map_or(None, |fp| {
|
||||
Some(fp)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
impl TraceEvent {
|
||||
pub fn parse_message(msg: &Dictionary) -> Option<TraceEvent> {
|
||||
msg.get_ui(ztcore::ZT_TRACE_FIELD_TYPE).map_or(None, |mt: u64| -> Option<TraceEvent> {
|
||||
let cl = msg.get_ui(ztcore::ZT_TRACE_FIELD_CODE_LOCATION).unwrap_or(0) as u32;
|
||||
match mt as u32 {
|
||||
ztcore::ZT_TraceEventType_ZT_TRACE_UNEXPECTED_ERROR => {
|
||||
Some(TraceEvent::UnexpectedError {
|
||||
code_location: cl,
|
||||
message: msg.get_string_or_empty(ztcore::ZT_TRACE_FIELD_MESSAGE),
|
||||
})
|
||||
},
|
||||
ztcore::ZT_TraceEventType_ZT_TRACE_VL1_RESETTING_PATHS_IN_SCOPE => {
|
||||
Some(TraceEvent::ResetingPathsInScope {
|
||||
code_location: cl,
|
||||
reporter: trace_optional_fingerprint(msg.get(ztcore::ZT_TRACE_FIELD_IDENTITY_FINGERPRINT)),
|
||||
reporter_endpoint: trace_optional_endpoint(msg.get(ztcore::ZT_TRACE_FIELD_TRIGGER_FROM_ENDPOINT)),
|
||||
my_old_external: trace_optional_endpoint(msg.get(ztcore::ZT_TRACE_FIELD_OLD_ENDPOINT)),
|
||||
my_new_external: trace_optional_endpoint(msg.get(ztcore::ZT_TRACE_FIELD_NEW_ENDPOINT)),
|
||||
scope: IpScope::from_i32(msg.get_ui(ztcore::ZT_TRACE_FIELD_RESET_ADDRESS_SCOPE).unwrap_or(0) as i32).unwrap_or(IpScope::None),
|
||||
})
|
||||
},
|
||||
ztcore::ZT_TraceEventType_ZT_TRACE_VL1_TRYING_NEW_PATH => {
|
||||
let tf = msg.get(ztcore::ZT_TRACE_FIELD_IDENTITY_FINGERPRINT);
|
||||
if tf.is_some() {
|
||||
let tf = Fingerprint::new_from_bytes(tf.unwrap().as_slice()).ok();
|
||||
if tf.is_some() {
|
||||
return Some(TraceEvent::TryingNewPath {
|
||||
code_location: cl,
|
||||
trying: tf.unwrap(),
|
||||
trigger_peer: trace_optional_fingerprint(msg.get(ztcore::ZT_TRACE_FIELD_TRIGGER_FROM_PEER_FINGERPRINT)),
|
||||
trigger_packet_from: trace_optional_endpoint(msg.get(ztcore::ZT_TRACE_FIELD_TRIGGER_FROM_ENDPOINT)),
|
||||
trigger_packet_id: msg.get_ui(ztcore::ZT_TRACE_FIELD_TRIGGER_FROM_PACKET_ID).unwrap_or(0),
|
||||
trigger_packet_verb: msg.get_ui(ztcore::ZT_TRACE_FIELD_TRIGGER_FROM_PACKET_VERB).unwrap_or(0) as i32,
|
||||
});
|
||||
}
|
||||
}
|
||||
None
|
||||
},
|
||||
ztcore::ZT_TraceEventType_ZT_TRACE_VL1_LEARNED_NEW_PATH => {
|
||||
let fp = msg.get(ztcore::ZT_TRACE_FIELD_IDENTITY_FINGERPRINT);
|
||||
if fp.is_some() {
|
||||
let fp = Fingerprint::new_from_bytes(fp.unwrap().as_slice()).ok();
|
||||
if fp.is_some() {
|
||||
return Some(TraceEvent::LearnedNewPath {
|
||||
code_location: cl,
|
||||
learned_from_packet_id: msg.get_ui(ztcore::ZT_TRACE_FIELD_PACKET_ID).unwrap_or(0),
|
||||
peer: fp.unwrap(),
|
||||
new_address: trace_optional_endpoint(msg.get(ztcore::ZT_TRACE_FIELD_ENDPOINT)),
|
||||
replaced_address: trace_optional_endpoint(msg.get(ztcore::ZT_TRACE_FIELD_OLD_ENDPOINT)),
|
||||
});
|
||||
}
|
||||
}
|
||||
None
|
||||
},
|
||||
ztcore::ZT_TraceEventType_ZT_TRACE_VL1_INCOMING_PACKET_DROPPED => {
|
||||
Some(TraceEvent::IncomingPacketDropped {
|
||||
code_location: cl,
|
||||
packet_id: msg.get_ui(ztcore::ZT_TRACE_FIELD_PACKET_ID).unwrap_or(0),
|
||||
network_id: msg.get_ui(ztcore::ZT_TRACE_FIELD_NETWORK_ID).unwrap_or(0),
|
||||
peer: trace_optional_fingerprint(msg.get(ztcore::ZT_TRACE_FIELD_IDENTITY_FINGERPRINT)),
|
||||
peer_address: trace_optional_endpoint(msg.get(ztcore::ZT_TRACE_FIELD_ENDPOINT)),
|
||||
hops: msg.get_ui(ztcore::ZT_TRACE_FIELD_PACKET_HOPS).unwrap_or(0) as i32,
|
||||
verb: msg.get_ui(ztcore::ZT_TRACE_FIELD_PACKET_VERB).unwrap_or(0) as i32,
|
||||
reason: TracePacketDropReason.from_i32(msg.get_ui(ztcore::ZT_TRACE_FIELD_REASON).unwrap_or(0) as i32).unwrap_or(TracePacketDropReason::Unspecified),
|
||||
})
|
||||
},
|
||||
ztcore::ZT_TraceEventType_ZT_TRACE_VL2_OUTGOING_FRAME_DROPPED => {
|
||||
Some(TraceEvent::OutgoingFrameDropped {
|
||||
code_location: ci,
|
||||
network_id: msg.get_ui(ztcore::ZT_TRACE_FIELD_NETWORK_ID).unwrap_or(0),
|
||||
source_mac: MAC(msg.get_ui(ztcore::ZT_TRACE_FIELD_SOURCE_MAC).unwrap_or(0)),
|
||||
dest_mac: MAC(msg.get_ui(ztcore::ZT_TRACE_FIELD_DEST_MAC).unwrap_or(0)),
|
||||
ethertype: msg.get_ui(ztcore::ZT_TRACE_FIELD_ETHERTYPE).unwrap_or(0) as u16,
|
||||
frame_length: msg.get_ui(ztcore::ZT_TRACE_FIELD_FRAME_LENGTH).unwrap_or(0) as u32,
|
||||
frame_data: msg.get(ztcore::ZT_TRACE_FIELD_FRAME_DATA).map_or_else(|| -> Vec<u8> {
|
||||
Vec::new()
|
||||
},|d: &Vec<u8>| -> Vec<u8> {
|
||||
d.clone()
|
||||
}),
|
||||
reason: TraceFrameDropReason::from_i32(msg.get_ui(ztcore::ZT_TRACE_FIELD_REASON).unwrap_or(0) as i32).unwrap_or(TraceFrameDropReason::Unspecified),
|
||||
})
|
||||
},
|
||||
ztcore::ZT_TraceEventType_ZT_TRACE_VL2_INCOMING_FRAME_DROPPED => {
|
||||
let fp = msg.get(ztcore::ZT_TRACE_FIELD_IDENTITY_FINGERPRINT);
|
||||
if fp.is_some() {
|
||||
let fp = Fingerprint::new_from_bytes(fp.unwrap().as_slice()).ok();
|
||||
if fp.is_some() {
|
||||
return Some(TraceEvent::IncomingFrameDropped {
|
||||
code_location: cl,
|
||||
source_mac: MAC(msg.get_ui(ztcore::ZT_TRACE_FIELD_SOURCE_MAC).unwrap_or(0)),
|
||||
dest_mac: MAC(msg.get_ui(ztcore::ZT_TRACE_FIELD_DEST_MAC).unwrap_or(0)),
|
||||
ethertype: msg.get_ui(ztcore::ZT_TRACE_FIELD_ETHERTYPE).unwrap_or(0) as u16,
|
||||
peer: fp.unwrap(),
|
||||
peer_address: trace_optional_endpoint(msg.get(ztcore::ZT_TRACE_FIELD_ENDPOINT)),
|
||||
hops: msg.get_ui(ztcore::ZT_TRACE_FIELD_PACKET_HOPS).unwrap_or(0) as i32,
|
||||
verb: msg.get_ui(ztcore::ZT_TRACE_FIELD_PACKET_VERB).unwrap_or(0) as i32,
|
||||
frame_length: msg.get_ui(ztcore::ZT_TRACE_FIELD_FRAME_LENGTH).unwrap_or(0) as u32,
|
||||
frame_data: msg.get(ztcore::ZT_TRACE_FIELD_FRAME_DATA).map_or_else(|| -> Vec<u8> {
|
||||
Vec::new()
|
||||
},|d: &Vec<u8>| -> Vec<u8> {
|
||||
d.clone()
|
||||
}),
|
||||
credential_request_sent: msg.get_ui(ztcore::ZT_TRACE_FIELD_FLAG_CREDENTIAL_REQUEST_SENT).unwrap_or(0) != 0,
|
||||
reason: TraceFrameDropReason::from_i32(msg.get_ui(ztcore::ZT_TRACE_FIELD_REASON).unwrap_or(0) as i32).unwrap_or(TraceFrameDropReason::Unspecified),
|
||||
})
|
||||
}
|
||||
}
|
||||
None
|
||||
},
|
||||
ztcore::ZT_TraceEventType_ZT_TRACE_VL2_NETWORK_CONFIG_REQUESTED => {
|
||||
Some(TraceEvent::NetworkConfigRequested {
|
||||
code_location: cl,
|
||||
network_id: msg.get_ui(ztcore::ZT_TRACE_FIELD_NETWORK_ID).unwrap_or(0),
|
||||
})
|
||||
},
|
||||
ztcore::ZT_TraceEventType_ZT_TRACE_VL2_NETWORK_FILTER => {
|
||||
Some(TraceEvent::NetworkFilter {
|
||||
code_location: cl,
|
||||
network_id: msg.get_ui(ztcore::ZT_TRACE_FIELD_NETWORK_ID).unwrap_or(0),
|
||||
primary_rule_set_log: msg.get(ztcore::ZT_TRACE_FIELD_PRIMARY_RULE_SET_LOG).map_or_else(|| {
|
||||
Vec::new()
|
||||
},|l| {
|
||||
l.clone()
|
||||
}),
|
||||
matching_capability_rule_set_log: msg.get(ztcore::ZT_TRACE_FIELD_MATCHING_CAPABILITY_RULE_SET_LOG).map_or_else(|| {
|
||||
Vec::new()
|
||||
},|l| {
|
||||
l.clone()
|
||||
}),
|
||||
matching_capability_id: msg.get_ui(ztcore::ZT_TRACE_FIELD_MATCHING_CAPABILITY_ID).unwrap_or(0) as u32,
|
||||
matching_capability_timestamp: msg.get_ui(ztcore::ZT_TRACE_FIELD_MATCHING_CAPABILITY_TIMESTAMP).unwrap_or(0) as i64,
|
||||
source_address: Address(msg.get_ui(ztcore::ZT_TRACE_FIELD_SOURCE_ZT_ADDRESS).unwrap_or(0)),
|
||||
dest_address: Address(msg.get_ui(ztcore::ZT_TRACE_FIELD_DEST_ZT_ADDRESS).unwrap_or(0)),
|
||||
source_mac: MAC(msg.get_ui(ztcore::ZT_TRACE_FIELD_SOURCE_MAC).unwrap_or(0)),
|
||||
dest_mac: MAC(msg.get_ui(ztcore::ZT_TRACE_FIELD_DEST_MAC).unwrap_or(0)),
|
||||
frame_length: msg.get_ui(ztcore::ZT_TRACE_FIELD_FRAME_LENGTH).unwrap_or(0) as u32,
|
||||
frame_data: msg.get(ztcore::ZT_TRACE_FIELD_FRAME_DATA).map_or_else(|| -> Vec<u8> {
|
||||
Vec::new()
|
||||
},|d: &Vec<u8>| -> Vec<u8> {
|
||||
d.clone()
|
||||
}),
|
||||
ethertype: msg.get_ui(ztcore::ZT_TRACE_FIELD_ETHERTYPE).unwrap_or(0) as u16,
|
||||
vlan_id: msg.get_ui(ztcore::ZT_TRACE_FIELD_VLAN_ID).unwrap_or(0) as u16,
|
||||
rule_flag_notee: msg.get_ui(ztcore::ZT_TRACE_FIELD_RULE_FLAG_NOTEE).unwrap_or(0) != 0,
|
||||
rule_flag_inbound: msg.get_ui(ztcore::ZT_TRACE_FIELD_RULE_FLAG_INBOUND).unwrap_or(0) != 0,
|
||||
rule_flag_accept: match msg.get(ztcore::ZT_TRACE_FIELD_RULE_FLAG_ACCEPT).map_or_else(|| -> i32 { 0 as i32 },|a| -> i32 { i32::from_str_radix(str::from_utf8(a).unwrap_or("0"), 16).unwrap_or(0) }) {
|
||||
1 => { TraceAccept::Accept },
|
||||
2 => { TraceAccept::SuperAccept },
|
||||
_ => { TraceAccept::Reject },
|
||||
}
|
||||
})
|
||||
},
|
||||
ztcore::ZT_TraceEventType_ZT_TRACE_VL2_NETWORK_CREDENTIAL_REJECTED => {
|
||||
let fp = msg.get(ztcore::ZT_TRACE_FIELD_IDENTITY_FINGERPRINT);
|
||||
if fp.is_some() {
|
||||
let fp = Fingerprint::new_from_bytes(fp.unwrap().as_slice()).ok();
|
||||
if fp.is_some() {
|
||||
return Some(TraceEvent::NetworkCredentialRejected {
|
||||
code_location: cl,
|
||||
network_id: msg.get_ui(ztcore::ZT_TRACE_FIELD_NETWORK_ID).unwrap_or(0),
|
||||
from_peer: fp.unwrap(),
|
||||
credential_id: msg.get_ui(ztcore::ZT_TRACE_FIELD_CREDENTIAL_ID).unwrap_or(0) as u32,
|
||||
credential_timestamp: msg.get_ui(ztcore::ZT_TRACE_FIELD_CREDENTIAL_TIMESTAMP).unwrap_or(0) as i64,
|
||||
credential_type: CredentialType::from_i32(msg.get_ui(ztcore::ZT_TRACE_FIELD_CREDENTIAL_TYPE).unwrap_or(0) as i32).unwrap_or(CredentialType::Null),
|
||||
reason: TraceCredentialRejectionReason::from_i32(msg.get_ui(ztcore::ZT_TRACE_FIELD_REASON).unwrap_or(0) as i32).unwrap_or(TraceCredentialRejectionReason::Invalid),
|
||||
});
|
||||
}
|
||||
}
|
||||
None
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -112,8 +112,8 @@ pub struct LocalConfigSettings {
|
|||
pub log_filter_events: bool,
|
||||
#[serde(rename = "logMulticastEvents")]
|
||||
pub log_multicast_events: bool,
|
||||
#[serde(rename = "logDebug")]
|
||||
pub log_debug: bool,
|
||||
#[serde(rename = "logToStderr")]
|
||||
pub log_to_stderr: bool,
|
||||
#[serde(rename = "interfacePrefixBlacklist")]
|
||||
pub interface_prefix_blacklist: Vec<String>,
|
||||
#[serde(rename = "explicitAddresses")]
|
||||
|
@ -197,7 +197,7 @@ impl Default for LocalConfigSettings {
|
|||
log_vl2_events: false,
|
||||
log_filter_events: false,
|
||||
log_multicast_events: false,
|
||||
log_debug: false,
|
||||
log_to_stderr: true, // TODO: change for release
|
||||
interface_prefix_blacklist: bl,
|
||||
explicit_addresses: Vec::new()
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
use std::cell::Cell;
|
||||
use std::fmt::Display;
|
||||
use std::fs::{File, OpenOptions};
|
||||
use std::io::{Seek, SeekFrom, Write};
|
||||
use std::io::{Seek, SeekFrom, Write, stderr};
|
||||
use std::sync::Mutex;
|
||||
|
||||
use chrono::Datelike;
|
||||
|
@ -23,18 +23,19 @@ struct LogIntl {
|
|||
file: Option<File>,
|
||||
cur_size: u64,
|
||||
max_size: usize,
|
||||
log_to_stderr: bool,
|
||||
}
|
||||
|
||||
pub(crate) struct Log {
|
||||
prefix: String,
|
||||
path: String,
|
||||
intl: Mutex<LogIntl>,
|
||||
inner: Mutex<LogIntl>,
|
||||
}
|
||||
|
||||
impl Log {
|
||||
const MIN_MAX_SIZE: usize = 1024;
|
||||
|
||||
pub fn new(path: &str, max_size: usize, prefix: &str) -> Log {
|
||||
pub fn new(path: &str, max_size: usize, log_to_stderr: bool, prefix: &str) -> Log {
|
||||
let mut p = String::from(prefix);
|
||||
if !p.is_empty() {
|
||||
p.push(' ');
|
||||
|
@ -42,25 +43,33 @@ impl Log {
|
|||
Log{
|
||||
prefix: p,
|
||||
path: String::from(path),
|
||||
intl: Mutex::new(LogIntl {
|
||||
inner: Mutex::new(LogIntl {
|
||||
file: None,
|
||||
cur_size: 0,
|
||||
max_size: if max_size < Log::MIN_MAX_SIZE { Log::MIN_MAX_SIZE } else { max_size },
|
||||
log_to_stderr: log_to_stderr,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_max_size(&self, new_max_size: usize) {
|
||||
self.intl.lock().unwrap().max_size = if new_max_size < Log::MIN_MAX_SIZE { Log::MIN_MAX_SIZE } else { new_max_size };
|
||||
self.inner.lock().unwrap().max_size = if new_max_size < Log::MIN_MAX_SIZE { Log::MIN_MAX_SIZE } else { new_max_size };
|
||||
}
|
||||
|
||||
pub fn set_log_to_stderr(&self, log_to_stderr: bool) {
|
||||
self.inner.lock().unwrap().log_to_stderr = log_to_stderr;
|
||||
}
|
||||
|
||||
pub fn log<S: AsRef<str>>(&self, s: S) {
|
||||
// Output FATAL errors to stderr.
|
||||
let ss: &str = s.as_ref();
|
||||
if ss.starts_with("FATAL") {
|
||||
eprintln!("{}", ss);
|
||||
}
|
||||
|
||||
let mut l = self.intl.lock().unwrap();
|
||||
let mut l = self.inner.lock().unwrap();
|
||||
|
||||
// If the file isn't open, open or create and seek to end.
|
||||
if l.file.is_none() {
|
||||
let mut f = OpenOptions::new().read(true).write(true).create(true).open(self.path.as_str());
|
||||
if f.is_err() {
|
||||
|
@ -75,6 +84,7 @@ impl Log {
|
|||
l.file = Some(f);
|
||||
}
|
||||
|
||||
// If there is a maximum size limit configured, rotate if exceeded.
|
||||
if l.max_size > 0 && l.cur_size > l.max_size as u64 {
|
||||
l.file = None;
|
||||
l.cur_size = 0;
|
||||
|
@ -92,12 +102,19 @@ impl Log {
|
|||
l.file = Some(f.unwrap());
|
||||
}
|
||||
|
||||
let log_line = format!("{}[{}] {}\n", self.prefix.as_str(), chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string(), ss);
|
||||
if l.log_to_stderr {
|
||||
stderr().write_all(log_line.as_bytes());
|
||||
}
|
||||
let f = l.file.as_mut().unwrap();
|
||||
let now_str = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
|
||||
let log_line = format!("{}[{}] {}\n", self.prefix.as_str(), now_str.as_str(), ss);
|
||||
let _ = f.write_all(log_line.as_bytes());
|
||||
let _ = f.flush();
|
||||
l.cur_size += log_line.len() as u64;
|
||||
let e = f.write_all(log_line.as_bytes());
|
||||
if e.is_err() {
|
||||
eprintln!("ERROR: I/O error writing to log: {}", e.err().unwrap().to_string());
|
||||
l.file = None;
|
||||
} else {
|
||||
let _ = f.flush();
|
||||
l.cur_size += log_line.len() as u64;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,37 +26,60 @@ mod service;
|
|||
#[allow(non_snake_case,non_upper_case_globals,non_camel_case_types,dead_code,improper_ctypes)]
|
||||
mod osdep; // bindgen generated
|
||||
|
||||
use std::boxed::Box;
|
||||
use std::ffi::CStr;
|
||||
use std::path::Path;
|
||||
use std::boxed::Box;
|
||||
use std::sync::Arc;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::os::raw::c_uint;
|
||||
|
||||
use crate::store::Store;
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn sha512<T: AsRef<[u8]>>(data: T) -> [u8; 64] {
|
||||
unsafe {
|
||||
let mut r: MaybeUninit<[u8; 64]> = MaybeUninit::uninit();
|
||||
let d = data.as_ref();
|
||||
osdep::sha512(d.as_ptr().cast(), d.len() as c_uint, r.as_mut_ptr().cast());
|
||||
r.assume_init()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn sha384<T: AsRef<[u8]>>(data: T) -> [u8; 48] {
|
||||
unsafe {
|
||||
let mut r: MaybeUninit<[u8; 48]> = MaybeUninit::uninit();
|
||||
let d = data.as_ref();
|
||||
osdep::sha384(d.as_ptr().cast(), d.len() as c_uint, r.as_mut_ptr().cast());
|
||||
r.assume_init()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn ms_since_epoch() -> i64 {
|
||||
// This is easy to do in the Rust stdlib, but the version in OSUtils is probably faster.
|
||||
unsafe { osdep::msSinceEpoch() }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut process_exit_value: i32 = 0;
|
||||
|
||||
let mut cli_args = Some(Box::new(cli::parse_cli_args()));
|
||||
let cli_args = Box::new(cli::parse_cli_args());
|
||||
let mut zerotier_path = unsafe { zerotier_core::cstr_to_string(osdep::platformDefaultHomePath(), -1) };
|
||||
|
||||
let json_output: bool;
|
||||
let mut auth_token: Option<String> = None;
|
||||
let mut auth_token_path: Option<String> = None;
|
||||
{
|
||||
let a = cli_args.as_ref().unwrap();
|
||||
json_output = a.is_present("json");
|
||||
let v = a.value_of("path");
|
||||
if v.is_some() {
|
||||
zerotier_path = String::from(v.unwrap());
|
||||
}
|
||||
let v = a.value_of("token");
|
||||
if v.is_some() {
|
||||
auth_token = Some(v.unwrap().trim().to_string());
|
||||
}
|
||||
let v = a.value_of("token_path");
|
||||
if v.is_some() {
|
||||
auth_token_path = Some(v.unwrap().to_string());
|
||||
}
|
||||
//let json_output = cli_args.is_present("json");
|
||||
let v = cli_args.value_of("path");
|
||||
if v.is_some() {
|
||||
zerotier_path = String::from(v.unwrap());
|
||||
}
|
||||
let v = cli_args.value_of("token");
|
||||
if v.is_some() {
|
||||
auth_token = Some(v.unwrap().trim().to_string());
|
||||
}
|
||||
let v = cli_args.value_of("token_path");
|
||||
if v.is_some() {
|
||||
auth_token_path = Some(v.unwrap().to_string());
|
||||
}
|
||||
|
||||
let store = Store::new(zerotier_path.as_str());
|
||||
|
@ -65,6 +88,13 @@ fn main() {
|
|||
std::process::exit(1);
|
||||
}
|
||||
let store = Arc::new(store.unwrap());
|
||||
if store.write_pid().is_err() {
|
||||
eprintln!("FATAL: error writing to directory '{}': unable to write zerotier.pid", zerotier_path);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
// From this point on we shouldn't call std::process::exit() since that would
|
||||
// fail to erase zerotier.pid from the working directory.
|
||||
|
||||
if auth_token.is_none() {
|
||||
let t;
|
||||
|
@ -80,17 +110,21 @@ fn main() {
|
|||
auth_token = Some(auth_token.unwrap().trim().to_string());
|
||||
}
|
||||
|
||||
drop(zerotier_path);
|
||||
drop(auth_token_path);
|
||||
|
||||
match cli_args.as_ref().unwrap().subcommand_name().unwrap() {
|
||||
"version" => {
|
||||
let ver = zerotier_core::version();
|
||||
println!("{}.{}.{}", ver.0, ver.1, ver.2);
|
||||
},
|
||||
"service" => {
|
||||
cli_args = None; // free any memory we can when launching service
|
||||
drop(cli_args); // free unnecssary memory before launching service
|
||||
process_exit_value = service::run(&store, auth_token);
|
||||
},
|
||||
_ => cli::print_help(), // includes "help"
|
||||
}
|
||||
|
||||
store.erase_pid();
|
||||
std::process::exit(process_exit_value);
|
||||
}
|
||||
|
|
|
@ -23,10 +23,10 @@ use warp::{Filter, Reply};
|
|||
use warp::http::{HeaderMap, Method, StatusCode};
|
||||
use warp::hyper::body::Bytes;
|
||||
|
||||
use zerotier_core::{Buffer, Address, IpScope, Node, NodeEventHandler, NetworkId, VirtualNetworkConfigOperation, VirtualNetworkConfig, StateObjectType, MAC, Event, InetAddress, InetAddressFamily, Identity};
|
||||
use zerotier_core::{Buffer, Address, IpScope, Node, NodeEventHandler, NetworkId, VirtualNetworkConfigOperation, VirtualNetworkConfig, StateObjectType, MAC, Event, InetAddress, InetAddressFamily, Identity, Dictionary};
|
||||
|
||||
use crate::fastudpsocket::*;
|
||||
use crate::getifaddrs;
|
||||
use crate::{getifaddrs, ms_since_epoch};
|
||||
use crate::localconfig::*;
|
||||
use crate::log::Log;
|
||||
use crate::network::Network;
|
||||
|
@ -40,8 +40,9 @@ struct Service {
|
|||
log: Arc<Log>,
|
||||
_local_config: Arc<Mutex<Arc<LocalConfig>>>,
|
||||
run: Arc<AtomicBool>,
|
||||
online: Arc<AtomicBool>,
|
||||
store: Arc<Store>,
|
||||
node: Weak<Node<Service, Network>>, // weak since Node can hold a reference to this
|
||||
node: Weak<Node<Service, Network>>, // weak since Node itself may hold a reference to this
|
||||
}
|
||||
|
||||
impl NodeEventHandler<Network> for Service {
|
||||
|
@ -53,10 +54,21 @@ impl NodeEventHandler<Network> for Service {
|
|||
fn event(&self, event: Event, event_data: &[u8]) {
|
||||
match event {
|
||||
Event::Up => {}
|
||||
Event::Down => {}
|
||||
Event::Online => {}
|
||||
Event::Offline => {}
|
||||
Event::Trace => {}
|
||||
Event::Down => {
|
||||
self.run.store(false, Ordering::Relaxed);
|
||||
}
|
||||
Event::Online => {
|
||||
self.online.store(true, Ordering::Relaxed);
|
||||
}
|
||||
Event::Offline => {
|
||||
self.online.store(true, Ordering::Relaxed);
|
||||
}
|
||||
Event::Trace => {
|
||||
if !event_data.is_empty() {
|
||||
let _ = Dictionary::new_from_bytes(event_data).map(|tm| {
|
||||
});
|
||||
}
|
||||
}
|
||||
Event::UserMessage => {}
|
||||
}
|
||||
}
|
||||
|
@ -126,21 +138,23 @@ impl Service {
|
|||
pub(crate) fn run(store: &Arc<Store>, auth_token: Option<String>) -> i32 {
|
||||
let mut process_exit_value: i32 = 0;
|
||||
|
||||
let init_local_config = Arc::new(store.read_local_conf(false).unwrap_or(LocalConfig::default()));
|
||||
let init_local_config = Arc::new(store.read_local_conf(false).unwrap_or_else(|_| { LocalConfig::default() }));
|
||||
|
||||
// Open log in store.
|
||||
let log = Arc::new(Log::new(
|
||||
if init_local_config.settings.log_path.as_ref().is_some() { init_local_config.settings.log_path.as_ref().unwrap().as_str() } else { store.default_log_path.to_str().unwrap() },
|
||||
if init_local_config.settings.log_path.as_ref().is_some() {
|
||||
init_local_config.settings.log_path.as_ref().unwrap().as_str()
|
||||
} else {
|
||||
store.default_log_path.to_str().unwrap()
|
||||
},
|
||||
init_local_config.settings.log_size_max,
|
||||
init_local_config.settings.log_to_stderr,
|
||||
"",
|
||||
));
|
||||
|
||||
// Generate authtoken.secret from secure random bytes if not already set.
|
||||
let auth_token = auth_token.unwrap_or_else(|| {
|
||||
let mut rb = [0_u8; 64];
|
||||
unsafe {
|
||||
crate::osdep::getSecureRandom(rb.as_mut_ptr().cast(), 64);
|
||||
}
|
||||
unsafe { crate::osdep::getSecureRandom(rb.as_mut_ptr().cast(), 64) };
|
||||
let mut t = String::new();
|
||||
t.reserve(64);
|
||||
for b in rb.iter() {
|
||||
|
@ -172,12 +186,13 @@ pub(crate) fn run(store: &Arc<Store>, auth_token: Option<String>) -> i32 {
|
|||
log: log.clone(),
|
||||
_local_config: Arc::new(Mutex::new(init_local_config)),
|
||||
run: Arc::new(AtomicBool::new(true)),
|
||||
online: Arc::new(AtomicBool::new(false)),
|
||||
store: store.clone(),
|
||||
node: Weak::new(),
|
||||
};
|
||||
|
||||
// Create instance of Node which will call Service on events.
|
||||
let node = Node::new(service.clone());
|
||||
let node = Node::new(service.clone(), ms_since_epoch());
|
||||
if node.is_err() {
|
||||
process_exit_value = 1;
|
||||
l!(log, "FATAL: error initializing node: {}", node.err().unwrap().to_string());
|
||||
|
@ -188,7 +203,6 @@ pub(crate) fn run(store: &Arc<Store>, auth_token: Option<String>) -> i32 {
|
|||
service.node = Arc::downgrade(&node);
|
||||
let service = service; // make immutable after setting node
|
||||
|
||||
let mut last_checked_config: i64 = 0;
|
||||
let mut loop_delay = zerotier_core::NODE_BACKGROUND_TASKS_MAX_INTERVAL;
|
||||
loop {
|
||||
let mut local_config = service.local_config();
|
||||
|
@ -221,17 +235,32 @@ pub(crate) fn run(store: &Arc<Store>, auth_token: Option<String>) -> i32 {
|
|||
);
|
||||
}
|
||||
if warp_server.is_err() {
|
||||
l!(log, "ERROR: local API http server failed to bind to port {}: {}", local_config.settings.primary_port, warp_server.err().unwrap().to_string());
|
||||
l!(log, "ERROR: local API http server failed to bind to port {} or failed to start: {}", local_config.settings.primary_port, warp_server.err().unwrap().to_string());
|
||||
break;
|
||||
}
|
||||
let warp_server = tokio_rt.spawn(warp_server.unwrap().1);
|
||||
|
||||
// Write zerotier.port which is used by the CLI to know how to reach the HTTP API.
|
||||
store.write_port(local_config.settings.primary_port);
|
||||
|
||||
let mut last_checked_config: i64 = 0;
|
||||
loop {
|
||||
let loop_start = ms_since_epoch();
|
||||
let mut now: i64 = 0;
|
||||
|
||||
// Wait for (1) loop delay elapsed, (2) a signal to interrupt delay now, or
|
||||
// (3) an external signal to exit.
|
||||
tokio::select! {
|
||||
_ = tokio::time::sleep(Duration::from_millis(loop_delay)) => {},
|
||||
_ = interrupt_rx.next() => {},
|
||||
_ = tokio::time::sleep(Duration::from_millis(loop_delay)) => {
|
||||
now = ms_since_epoch();
|
||||
let actual_delay = now - loop_start;
|
||||
if actual_delay > (loop_delay * 4) {
|
||||
// TODO: handle likely sleep/wake or other system interruption
|
||||
}
|
||||
},
|
||||
_ = interrupt_rx.next() => {
|
||||
now = ms_since_epoch();
|
||||
},
|
||||
_ = tokio::signal::ctrl_c() => {
|
||||
l!(log, "exit signal received, shutting down...");
|
||||
service.run.store(false, Ordering::Relaxed);
|
||||
|
@ -241,7 +270,6 @@ pub(crate) fn run(store: &Arc<Store>, auth_token: Option<String>) -> i32 {
|
|||
|
||||
// Check every CONFIG_CHECK_INTERVAL for changes to either the system configuration
|
||||
// or the node's local configuration and take actions as needed.
|
||||
let now = zerotier_core::now();
|
||||
if (now - last_checked_config) >= CONFIG_CHECK_INTERVAL {
|
||||
last_checked_config = now;
|
||||
|
||||
|
@ -251,12 +279,17 @@ pub(crate) fn run(store: &Arc<Store>, auth_token: Option<String>) -> i32 {
|
|||
service.set_local_config(new_config.unwrap());
|
||||
}
|
||||
|
||||
// Check for configuration changes that require a reboot of the inner loop
|
||||
// or other actions to be taken.
|
||||
// Check for and handle configuration changes, some of which require inner loop restart.
|
||||
let next_local_config = service.local_config();
|
||||
if local_config.settings.primary_port != next_local_config.settings.primary_port {
|
||||
break;
|
||||
}
|
||||
if local_config.settings.log_size_max != next_local_config.settings.log_size_max {
|
||||
log.set_max_size(next_local_config.settings.log_size_max);
|
||||
}
|
||||
if local_config.settings.log_to_stderr != next_local_config.settings.log_to_stderr {
|
||||
log.set_log_to_stderr(next_local_config.settings.log_to_stderr);
|
||||
}
|
||||
local_config = next_local_config;
|
||||
|
||||
// Enumerate all useful addresses bound to interfaces on the system.
|
||||
|
@ -320,17 +353,22 @@ pub(crate) fn run(store: &Arc<Store>, auth_token: Option<String>) -> i32 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if primary_port_bind_failure {
|
||||
if local_config.settings.auto_port_search {
|
||||
// TODO: port hunting if enabled
|
||||
// TODO: port hunting
|
||||
} else {
|
||||
l!(log, "primary port {} failed to bind, waiting and trying again...", local_config.settings.primary_port);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if secondary_port_bind_failure {
|
||||
l!(log, "secondary port {} failed to bind (non-fatal, will try again)", local_config.settings.secondary_port.unwrap_or(0));
|
||||
// hunt for a secondary port.
|
||||
if local_config.settings.auto_port_search {
|
||||
// TODO: port hunting
|
||||
} else {
|
||||
l!(log, "secondary port {} failed to bind (non-fatal, will try again)", local_config.settings.secondary_port.unwrap_or(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -340,7 +378,7 @@ pub(crate) fn run(store: &Arc<Store>, auth_token: Option<String>) -> i32 {
|
|||
}
|
||||
|
||||
// Run background task handler in ZeroTier core.
|
||||
loop_delay = node.process_background_tasks();
|
||||
loop_delay = node.process_background_tasks(now);
|
||||
}
|
||||
|
||||
// Gracefully shut down the local web server.
|
||||
|
|
|
@ -15,12 +15,14 @@ use std::error::Error;
|
|||
use std::io::{Read, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Mutex;
|
||||
use std::str::FromStr;
|
||||
use std::ffi::CString;
|
||||
|
||||
use zerotier_core::{StateObjectType, NetworkId};
|
||||
|
||||
use crate::localconfig::LocalConfig;
|
||||
|
||||
/// In-filesystem data store for configuration and objects.
|
||||
pub(crate) struct Store {
|
||||
pub base_path: Box<Path>,
|
||||
pub default_log_path: Box<Path>,
|
||||
|
@ -195,6 +197,21 @@ impl Store {
|
|||
self.write_file("local.conf", json.as_bytes())
|
||||
}
|
||||
|
||||
/// Writes the primary port number bound to zerotier.port.
|
||||
pub fn write_port(&self, port: u16) -> std::io::Result<()> {
|
||||
let ps = port.to_string();
|
||||
self.write_file("zerotier.port", ps.as_bytes())
|
||||
}
|
||||
|
||||
/// Read zerotier.port and return port or 0 if not found or not readable.
|
||||
pub fn read_port(&self) -> u16 {
|
||||
self.read_file_str("zerotier.port").map_or_else(|_| {
|
||||
0_u16
|
||||
},|s| {
|
||||
u16::from_str(s.trim()).unwrap_or(0_u16)
|
||||
})
|
||||
}
|
||||
|
||||
/// Reads the authtoken.secret file in the home directory.
|
||||
#[inline(always)]
|
||||
pub fn read_authtoken_secret(&self) -> std::io::Result<String> {
|
||||
|
@ -209,6 +226,18 @@ impl Store {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Write zerotier.pid file with current process's PID.
|
||||
#[cfg(unix)]
|
||||
pub fn write_pid(&self) -> std::io::Result<()> {
|
||||
let pid = unsafe { crate::osdep::getpid() }.to_string();
|
||||
self.write_file(self.base_path.join("zerotier.pid").to_str().unwrap(), pid.as_bytes())
|
||||
}
|
||||
|
||||
/// Erase zerotier.pid if present.
|
||||
pub fn erase_pid(&self) {
|
||||
std::fs::remove_file(self.base_path.join("zerotier.pid"));
|
||||
}
|
||||
|
||||
/// Load a ZeroTier core object.
|
||||
pub fn load_object(&self, obj_type: &StateObjectType, obj_id: &[u64]) -> std::io::Result<Vec<u8>> {
|
||||
let obj_path = self.make_obj_path(&obj_type, obj_id);
|
||||
|
|
|
@ -12,15 +12,17 @@
|
|||
/****/
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
use std::ptr::null_mut;
|
||||
use std::os::raw::c_ulong;
|
||||
use std::ptr::null_mut;
|
||||
|
||||
use zerotier_core::{MAC, MulticastGroup};
|
||||
|
||||
use crate::osdep as osdep;
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd", target_os = "dragonfly", target_os = "ios"))]
|
||||
pub(crate) fn bsd_get_multicast_groups(dev: &str) -> BTreeSet<MulticastGroup> {
|
||||
let dev = dev.as_bytes();
|
||||
let mut groups: BTreeSet<MulticastGroup> = BTreeSet::new();
|
||||
let dev = dev.as_bytes();
|
||||
unsafe {
|
||||
let mut maddrs: *mut osdep::ifmaddrs = null_mut();
|
||||
if osdep::getifmaddrs(&mut maddrs as *mut *mut osdep::ifmaddrs) == 0 {
|
||||
|
@ -32,14 +34,7 @@ pub(crate) fn bsd_get_multicast_groups(dev: &str) -> BTreeSet<MulticastGroup> {
|
|||
if la.sdl_alen == 6 && in_.sdl_nlen <= dev.len() as osdep::u_char && osdep::memcmp(dev.as_ptr().cast(), in_.sdl_data.as_ptr().cast(), in_.sdl_nlen as c_ulong) == 0 {
|
||||
let mi = la.sdl_nlen as usize;
|
||||
groups.insert(MulticastGroup{
|
||||
mac: MAC(
|
||||
(la.sdl_data[mi] as u64) << 40 |
|
||||
(la.sdl_data[mi+1] as u64) << 32 |
|
||||
(la.sdl_data[mi+2] as u64) << 24 |
|
||||
(la.sdl_data[mi+3] as u64) << 16 |
|
||||
(la.sdl_data[mi+4] as u64) << 8 |
|
||||
la.sdl_data[mi+5] as u64
|
||||
),
|
||||
mac: MAC((la.sdl_data[mi] as u64) << 40 | (la.sdl_data[mi+1] as u64) << 32 | (la.sdl_data[mi+2] as u64) << 24 | (la.sdl_data[mi+3] as u64) << 16 | (la.sdl_data[mi+4] as u64) << 8 | la.sdl_data[mi+5] as u64),
|
||||
adi: 0,
|
||||
});
|
||||
}
|
||||
|
@ -51,3 +46,9 @@ pub(crate) fn bsd_get_multicast_groups(dev: &str) -> BTreeSet<MulticastGroup> {
|
|||
}
|
||||
groups
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub(crate) fn linux_get_multicast_groups(dev: &str) -> BTreeSet<MulticastGroup> {
|
||||
let mut groups: BTreeSet<MulticastGroup> = BTreeSet::new();
|
||||
groups
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue