mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-26 17:03:43 +02:00
A bunch of logging and tracing.
This commit is contained in:
parent
411373dd2c
commit
d201cdec2a
11 changed files with 407 additions and 212 deletions
|
@ -77,18 +77,21 @@ 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::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);
|
||||
if (triggeringPeer)
|
||||
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());
|
||||
if ((trying)&&(physicalAddress)) {
|
||||
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());
|
||||
Dictionary::appendObject(buf, ZT_TRACE_FIELD_ENDPOINT, physicalAddress);
|
||||
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);
|
||||
if (triggeringPeer)
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
void Trace::_learnedNewPath(
|
||||
|
@ -99,17 +102,19 @@ 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::appendObject(buf, ZT_TRACE_FIELD_IDENTITY_FINGERPRINT, peerIdentity.fingerprint());
|
||||
if (physicalAddress)
|
||||
Dictionary::appendObject(buf, ZT_TRACE_FIELD_ENDPOINT, Endpoint(physicalAddress));
|
||||
if (replaced)
|
||||
Dictionary::appendObject(buf, ZT_TRACE_FIELD_OLD_ENDPOINT, Endpoint(replaced));
|
||||
buf.push_back(0);
|
||||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
if (peerIdentity) {
|
||||
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));
|
||||
if (replaced)
|
||||
Dictionary::appendObject(buf, ZT_TRACE_FIELD_OLD_ENDPOINT, Endpoint(replaced));
|
||||
buf.push_back(0);
|
||||
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
|
||||
}
|
||||
}
|
||||
|
||||
void Trace::_incomingPacketDropped(
|
||||
|
@ -184,6 +189,7 @@ void Trace::_incomingNetworkFrameDropped(
|
|||
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_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);
|
||||
|
|
|
@ -42,8 +42,6 @@ extern "C" fn populate_dict_callback(arg: *mut c_void, c_key: *const c_char, key
|
|||
}
|
||||
}
|
||||
|
||||
pub type DictionaryIter = std::collections::hash_map::Iter<'_, String, Vec<u8>>;
|
||||
|
||||
impl Dictionary {
|
||||
#[inline(always)]
|
||||
pub fn new() -> Dictionary {
|
||||
|
@ -70,9 +68,15 @@ impl Dictionary {
|
|||
self.data.get(&ks)
|
||||
}
|
||||
|
||||
pub fn get_or_empty<K: AsRef<[u8]>>(&self, k: K) -> Vec<u8> {
|
||||
let ks = String::from(String::from_utf8_lossy(k.as_ref()));
|
||||
self.data.get(&ks).map_or_else(|| -> Vec<u8> { Vec::new() }, |d| -> Vec<u8> { d.clone() })
|
||||
}
|
||||
|
||||
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 ks = String::from(String::from_utf8_lossy(k.as_ref()));
|
||||
let v = self.data.get(&ks);
|
||||
v.map_or(None, |v: &Vec<u8>| {
|
||||
let vs = std::str::from_utf8(v.as_slice());
|
||||
vs.map_or(None, |v: &str| {
|
||||
Some(v)
|
||||
|
@ -95,8 +99,8 @@ impl Dictionary {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn iter(&self) -> DictionaryIter {
|
||||
self.data.iter()
|
||||
pub fn len(&self) -> usize {
|
||||
self.data.len()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ 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);
|
||||
let ec = ztcore::ZT_Endpoint_fromBytes(cep.as_mut_ptr(), bytes.as_ptr().cast(), bytes.len() as c_uint);
|
||||
if ec == 0 {
|
||||
let epi = cep.assume_init();
|
||||
return Ok(Endpoint{
|
||||
|
|
|
@ -41,6 +41,21 @@ pub enum IpScope {
|
|||
Private = ztcore::ZT_InetAddress_IpScope_ZT_IP_SCOPE_PRIVATE as isize
|
||||
}
|
||||
|
||||
impl IpScope {
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match *self {
|
||||
IpScope::None => "None",
|
||||
IpScope::Multicast => "Multicast",
|
||||
IpScope::Loopback => "Loopback",
|
||||
IpScope::PseudoPrivate => "PseudoPrivate",
|
||||
IpScope::Global => "Global",
|
||||
IpScope::LinkLocal => "LinkLocal",
|
||||
IpScope::Shared => "Shared",
|
||||
IpScope::Private => "Private",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub enum InetAddressFamily {
|
||||
Nil,
|
||||
|
@ -48,6 +63,16 @@ pub enum InetAddressFamily {
|
|||
IPv6
|
||||
}
|
||||
|
||||
impl InetAddressFamily {
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match *self {
|
||||
InetAddressFamily::Nil => "Nil",
|
||||
InetAddressFamily::IPv4 => "IPv4",
|
||||
InetAddressFamily::IPv6 => "IPv6",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const IPV4_INADDR_ANY: [u8; 4] = [0; 4];
|
||||
pub const IPV6_INADDR_ANY: [u8; 16] = [0; 16];
|
||||
|
||||
|
|
|
@ -108,6 +108,19 @@ pub enum CredentialType {
|
|||
Revocation = ztcore::ZT_CredentialType_ZT_CREDENTIAL_TYPE_REVOCATION as isize,
|
||||
}
|
||||
|
||||
impl CredentialType {
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match *self {
|
||||
CredentialType::Null => "Null",
|
||||
CredentialType::CertificateOfMembership => "CertificateOfMembership",
|
||||
CredentialType::Capability => "Capability",
|
||||
CredentialType::Tag => "Tag",
|
||||
CredentialType::CertificateOfOwnership => "CertificateOfOwnership",
|
||||
CredentialType::Revocation => "Revocation",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
||||
pub enum ResultCode {
|
||||
Ok = ztcore::ZT_ResultCode_ZT_RESULT_OK as isize,
|
||||
|
@ -122,8 +135,8 @@ pub enum ResultCode {
|
|||
ErrorInternalNonFatal = ztcore::ZT_ResultCode_ZT_RESULT_ERROR_INTERNAL as isize,
|
||||
}
|
||||
|
||||
impl ToString for ResultCode {
|
||||
fn to_string(&self) -> String {
|
||||
impl ResultCode {
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match *self {
|
||||
ResultCode::Ok => "Ok",
|
||||
ResultCode::FatalErrorOutOfMemory => "FatalErrorOutOfMemory",
|
||||
|
@ -135,7 +148,7 @@ impl ToString for ResultCode {
|
|||
ResultCode::ErrorInvalidCredential => "ErrorInvalidCredential",
|
||||
ResultCode::ErrorCollidingObject => "ErrorCollidingObject",
|
||||
ResultCode::ErrorInternalNonFatal => "ErrorInternalNonFatal",
|
||||
}.to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,3 +213,22 @@ macro_rules! implement_to_from_json {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export(crate)]
|
||||
macro_rules! enum_str {
|
||||
(enum $name:ident {
|
||||
$($variant:ident = $val:expr),*,
|
||||
}) => {
|
||||
enum $name {
|
||||
$($variant = $val),*
|
||||
}
|
||||
|
||||
impl $name {
|
||||
fn name(&self) -> &'static str {
|
||||
match self {
|
||||
$($name::$variant => stringify!($variant)),*
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -18,71 +18,7 @@ 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)]
|
||||
#[derive(FromPrimitive, 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,
|
||||
|
@ -95,7 +31,23 @@ pub enum TracePacketDropReason {
|
|||
ReplyNotExpected = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_REPLY_NOT_EXPECTED as isize,
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
||||
impl TracePacketDropReason {
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match *self {
|
||||
TracePacketDropReason::Unspecified => "Unspecified",
|
||||
TracePacketDropReason::PeerTooOld => "PeerTooOld",
|
||||
TracePacketDropReason::MalformedPacket => "MalformedPacket",
|
||||
TracePacketDropReason::MacFailed => "MacFailed",
|
||||
TracePacketDropReason::RateLimitExceeded => "RateLimitExceeded",
|
||||
TracePacketDropReason::InvalidObject => "InvalidObject",
|
||||
TracePacketDropReason::InvalidCompressedData => "InvalidCompressedData",
|
||||
TracePacketDropReason::UnrecognizedVerb => "UnrecognizedVerb",
|
||||
TracePacketDropReason::ReplyNotExpected => "ReplyNotExpected",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive, 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,
|
||||
|
@ -107,7 +59,22 @@ pub enum TraceFrameDropReason {
|
|||
PermissionDenied = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_PERMISSION_DENIED as isize,
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
||||
impl TraceFrameDropReason {
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match *self {
|
||||
TraceFrameDropReason::Unspecified => "Unspecified",
|
||||
TraceFrameDropReason::BridgingNotAllowedRemote => "BridgingNotAllowedRemote",
|
||||
TraceFrameDropReason::BridgingNotAllowedLocal => "BridgingNotAllowedLocal",
|
||||
TraceFrameDropReason::MulticastDisabled => "MulticastDisabled",
|
||||
TraceFrameDropReason::BroadcastDisabled => "BroadcastDisabled",
|
||||
TraceFrameDropReason::FilterBlocked => "FilterBlocked",
|
||||
TraceFrameDropReason::FilterBlockedAtBridgeReplication => "FilterBlockedAtBridgeReplication",
|
||||
TraceFrameDropReason::PermissionDenied => "PermissionDenied",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive, 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,
|
||||
|
@ -115,13 +82,35 @@ pub enum TraceCredentialRejectionReason {
|
|||
Invalid = ztcore::ZT_TraceCredentialRejectionReason_ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID as isize,
|
||||
}
|
||||
|
||||
impl TraceCredentialRejectionReason {
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match *self {
|
||||
TraceCredentialRejectionReason::SignatureVerificationFailed => "SignatureVerificationFailed",
|
||||
TraceCredentialRejectionReason::Revoked => "Revoked",
|
||||
TraceCredentialRejectionReason::OlderThanLatest => "OlderThanLatest",
|
||||
TraceCredentialRejectionReason::Invalid => "Invalid",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub enum TraceAccept {
|
||||
pub enum TraceFilterResult {
|
||||
Reject,
|
||||
Accept,
|
||||
SuperAccept,
|
||||
}
|
||||
|
||||
impl TraceFilterResult {
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match *self {
|
||||
TraceFilterResult::Reject => "Reject",
|
||||
TraceFilterResult::Accept => "Accept",
|
||||
TraceFilterResult::SuperAccept => "SuperAccept",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub enum TraceEvent {
|
||||
UnexpectedError {
|
||||
code_location: u32,
|
||||
|
@ -137,8 +126,9 @@ pub enum TraceEvent {
|
|||
},
|
||||
TryingNewPath {
|
||||
code_location: u32,
|
||||
trying: Fingerprint,
|
||||
trigger_peer: Option<Fingerproint>,
|
||||
trying_peer: Fingerprint,
|
||||
trying_endpoint: Endpoint,
|
||||
trigger_peer: Option<Fingerprint>,
|
||||
trigger_packet_from: Option<Endpoint>,
|
||||
trigger_packet_id: u64,
|
||||
trigger_packet_verb: i32,
|
||||
|
@ -147,15 +137,15 @@ pub enum TraceEvent {
|
|||
code_location: u32,
|
||||
learned_from_packet_id: u64,
|
||||
peer: Fingerprint,
|
||||
new_address: Option<Endpoint>,
|
||||
replaced_address: Option<Endpoint>,
|
||||
new_endpoint: Option<Endpoint>,
|
||||
old_endpoint: Option<Endpoint>,
|
||||
},
|
||||
IncomingPacketDropped {
|
||||
code_location: u32,
|
||||
packet_id: u64,
|
||||
network_id: u64,
|
||||
peer: Option<Fingerprint>,
|
||||
peer_address: Option<Endpoint>,
|
||||
peer_endpoint: Option<Endpoint>,
|
||||
hops: i32,
|
||||
verb: i32,
|
||||
reason: TracePacketDropReason,
|
||||
|
@ -172,11 +162,12 @@ pub enum TraceEvent {
|
|||
},
|
||||
IncomingFrameDropped {
|
||||
code_location: u32,
|
||||
network_id: u64,
|
||||
source_mac: MAC,
|
||||
dest_mac: MAC,
|
||||
ethertype: u16,
|
||||
peer: Fingerprint,
|
||||
peer_address: Option<Endpoint>,
|
||||
peer_endpoint: Option<Endpoint>,
|
||||
hops: i32,
|
||||
verb: i32,
|
||||
frame_length: u32,
|
||||
|
@ -203,9 +194,9 @@ pub enum TraceEvent {
|
|||
frame_data: Vec<u8>,
|
||||
ethertype: u16,
|
||||
vlan_id: u16,
|
||||
rule_flag_notee: bool,
|
||||
rule_flag_inbound: bool,
|
||||
rule_flag_accept: TraceAccept,
|
||||
flag_notee: bool,
|
||||
inbound: bool,
|
||||
result: TraceFilterResult,
|
||||
},
|
||||
NetworkCredentialRejected {
|
||||
code_location: u32,
|
||||
|
@ -218,6 +209,125 @@ pub enum TraceEvent {
|
|||
},
|
||||
}
|
||||
|
||||
fn trace_to_string_optional<T: ToString>(x: &Option<T>) -> String {
|
||||
x.as_ref().map_or_else(|| { "<unknown>".to_string() }, |xx| { xx.to_string() })
|
||||
}
|
||||
|
||||
fn trace_peer_address_to_string_optional(p: &Option<Fingerprint>) -> String {
|
||||
p.as_ref().map_or_else(|| { "<unknown>".to_string() }, |pp| { pp.address.to_string() })
|
||||
}
|
||||
|
||||
impl ToString for TraceEvent {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
TraceEvent::UnexpectedError { code_location, message } => {
|
||||
format!("UnexpectedError: {} ({:0>8x})", message, code_location)
|
||||
}
|
||||
TraceEvent::ResetingPathsInScope { code_location, reporter, reporter_endpoint, my_old_external, my_new_external, scope } => {
|
||||
format!(
|
||||
"VL1 ResettingPathsInScope: resetting scope {} because {}@{} reported that my address changed from {} to {} ({:0>8x})",
|
||||
scope.to_str(),
|
||||
trace_peer_address_to_string_optional(reporter),
|
||||
trace_to_string_optional(reporter_endpoint),
|
||||
trace_to_string_optional(my_old_external),
|
||||
trace_to_string_optional(my_new_external),
|
||||
code_location,
|
||||
)
|
||||
}
|
||||
TraceEvent::TryingNewPath { code_location, trying_peer, trying_endpoint, trigger_peer, trigger_packet_from, trigger_packet_id, .. } => {
|
||||
format!(
|
||||
"VL1 TryingNewPath: trying {}@{} triggered by packet {:0>16x} from {}@{} ({:0>8x})",
|
||||
trying_peer.address.to_string(),
|
||||
trying_endpoint.to_string(),
|
||||
trigger_packet_id,
|
||||
trace_peer_address_to_string_optional(trigger_peer),
|
||||
trace_to_string_optional(trigger_packet_from),
|
||||
code_location,
|
||||
)
|
||||
}
|
||||
TraceEvent::LearnedNewPath { code_location, learned_from_packet_id, peer, old_endpoint, new_endpoint } => {
|
||||
format!(
|
||||
"VL1 LearnedNewPath: {} is now at {}, was at {}, learned from packet {:0>16x} ({:0>8x})",
|
||||
peer.address.to_string(),
|
||||
trace_to_string_optional(new_endpoint),
|
||||
trace_to_string_optional(old_endpoint),
|
||||
learned_from_packet_id,
|
||||
code_location,
|
||||
)
|
||||
}
|
||||
TraceEvent::IncomingPacketDropped { code_location, packet_id, peer, peer_endpoint, hops, verb, reason, .. } => {
|
||||
format!(
|
||||
"VL1 IncomingPacketDropped: packet {:0>16x} from {}@{} (hops: {}, verb: {}) dropped: {} ({:0>8x})",
|
||||
packet_id,
|
||||
trace_peer_address_to_string_optional(peer),
|
||||
trace_to_string_optional(peer_endpoint),
|
||||
hops,
|
||||
verb,
|
||||
reason.to_str(),
|
||||
code_location,
|
||||
)
|
||||
}
|
||||
TraceEvent::OutgoingFrameDropped { code_location, network_id, source_mac, dest_mac, ethertype, frame_length, reason, .. } => {
|
||||
format!(
|
||||
"VL2 OutgoingFrameDropped: network {:0>16x} {} -> {} ethertype {:0>4x} length {} dropped: {} ({:0>8x})",
|
||||
network_id,
|
||||
source_mac.to_string(),
|
||||
dest_mac.to_string(),
|
||||
ethertype,
|
||||
frame_length,
|
||||
reason.to_str(),
|
||||
code_location,
|
||||
)
|
||||
}
|
||||
TraceEvent::IncomingFrameDropped { code_location, network_id, source_mac, dest_mac, ethertype, peer, peer_endpoint, frame_length, reason, .. } => {
|
||||
format!(
|
||||
"VL2 IncomingFrameDropped: network {:0>16x} {} -> {} ethertype {:0>4x} length {} from {}@{} dropped: {} ({:0>8x})",
|
||||
network_id,
|
||||
source_mac.to_string(),
|
||||
dest_mac.to_string(),
|
||||
ethertype,
|
||||
frame_length,
|
||||
peer.address.to_string(),
|
||||
trace_to_string_optional(peer_endpoint),
|
||||
reason.to_str(),
|
||||
code_location,
|
||||
)
|
||||
}
|
||||
TraceEvent::NetworkConfigRequested { code_location, network_id } => {
|
||||
format!(
|
||||
"VL2 NetworkConfigRequested: {:0>16x} ({:0>8x})", network_id, code_location)
|
||||
}
|
||||
TraceEvent::NetworkFilter { code_location, network_id, source_address, dest_address, source_mac, dest_mac, frame_length, ethertype, inbound, result, .. } => {
|
||||
format!(
|
||||
"VL2 NetworkFilter: network {:0>16x} {}: {} via {} -> {} via {} length {} ethertype {:0>4x} result {} ({:0>8x})",
|
||||
network_id,
|
||||
if *inbound { "IN" } else { "OUT" },
|
||||
source_mac.to_string(),
|
||||
source_address.to_string(),
|
||||
dest_mac.to_string(),
|
||||
dest_address.to_string(),
|
||||
frame_length,
|
||||
ethertype,
|
||||
result.to_str(),
|
||||
code_location,
|
||||
)
|
||||
}
|
||||
TraceEvent::NetworkCredentialRejected { code_location, network_id, from_peer, credential_id, credential_timestamp, credential_type, reason } => {
|
||||
format!(
|
||||
"VL2 NetworkCredentialRejected: network {:0>16x} from {} id {:0>8x} timestamp {} type {}: {} ({:0>8x})",
|
||||
network_id,
|
||||
from_peer.address.to_string(),
|
||||
credential_id,
|
||||
credential_timestamp,
|
||||
credential_type.to_str(),
|
||||
reason.to_str(),
|
||||
code_location,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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| {
|
||||
|
@ -235,16 +345,21 @@ fn trace_optional_fingerprint(bytes: Option<&Vec<u8>>) -> Option<Fingerprint> {
|
|||
}
|
||||
|
||||
impl TraceEvent {
|
||||
/// Decode a trace event packaged in a dictionary and return a TraceEvent if it is valid.
|
||||
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 => {
|
||||
_ => { // ztcore::ZT_TraceEventType_ZT_TRACE_UNEXPECTED_ERROR
|
||||
Some(TraceEvent::UnexpectedError {
|
||||
code_location: cl,
|
||||
message: msg.get_string_or_empty(ztcore::ZT_TRACE_FIELD_MESSAGE),
|
||||
message: msg.get_str(ztcore::ZT_TRACE_FIELD_MESSAGE).map_or_else(|| {
|
||||
format!("WARNING: unknown trace message type {}, this version may be too old!", mt)
|
||||
}, |m| {
|
||||
m.to_string()
|
||||
}),
|
||||
})
|
||||
},
|
||||
}
|
||||
ztcore::ZT_TraceEventType_ZT_TRACE_VL1_RESETTING_PATHS_IN_SCOPE => {
|
||||
Some(TraceEvent::ResetingPathsInScope {
|
||||
code_location: cl,
|
||||
|
@ -254,15 +369,18 @@ impl TraceEvent {
|
|||
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 ep = msg.get(ztcore::ZT_TRACE_FIELD_ENDPOINT);
|
||||
if tf.is_some() && ep.is_some() {
|
||||
let tf = Fingerprint::new_from_bytes(tf.unwrap().as_slice()).ok();
|
||||
if tf.is_some() {
|
||||
let ep = Endpoint::new_from_bytes(ep.unwrap().as_slice()).ok();
|
||||
if tf.is_some() && ep.is_some() {
|
||||
return Some(TraceEvent::TryingNewPath {
|
||||
code_location: cl,
|
||||
trying: tf.unwrap(),
|
||||
trying_peer: tf.unwrap(),
|
||||
trying_endpoint: ep.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),
|
||||
|
@ -271,7 +389,7 @@ impl TraceEvent {
|
|||
}
|
||||
}
|
||||
None
|
||||
},
|
||||
}
|
||||
ztcore::ZT_TraceEventType_ZT_TRACE_VL1_LEARNED_NEW_PATH => {
|
||||
let fp = msg.get(ztcore::ZT_TRACE_FIELD_IDENTITY_FINGERPRINT);
|
||||
if fp.is_some() {
|
||||
|
@ -281,28 +399,28 @@ impl TraceEvent {
|
|||
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)),
|
||||
new_endpoint: trace_optional_endpoint(msg.get(ztcore::ZT_TRACE_FIELD_ENDPOINT)),
|
||||
old_endpoint: 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)),
|
||||
peer_endpoint: 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),
|
||||
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,
|
||||
code_location: cl,
|
||||
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)),
|
||||
|
@ -310,12 +428,12 @@ impl TraceEvent {
|
|||
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: &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() {
|
||||
|
@ -323,46 +441,42 @@ impl TraceEvent {
|
|||
if fp.is_some() {
|
||||
return Some(TraceEvent::IncomingFrameDropped {
|
||||
code_location: cl,
|
||||
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,
|
||||
peer: fp.unwrap(),
|
||||
peer_address: trace_optional_endpoint(msg.get(ztcore::ZT_TRACE_FIELD_ENDPOINT)),
|
||||
peer_endpoint: 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()
|
||||
}),
|
||||
frame_data: msg.get_or_empty(ztcore::ZT_TRACE_FIELD_FRAME_DATA),
|
||||
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 => {
|
||||
let verdict_int = 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) });
|
||||
let mut verdict = TraceFilterResult::Reject;
|
||||
if verdict_int == 1 {
|
||||
verdict = TraceFilterResult::Accept;
|
||||
} else if verdict_int > 1 {
|
||||
verdict = TraceFilterResult::SuperAccept;
|
||||
}
|
||||
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()
|
||||
}),
|
||||
primary_rule_set_log: msg.get_or_empty(ztcore::ZT_TRACE_FIELD_PRIMARY_RULE_SET_LOG),
|
||||
matching_capability_rule_set_log: msg.get_or_empty(ztcore::ZT_TRACE_FIELD_MATCHING_CAPABILITY_RULE_SET_LOG),
|
||||
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)),
|
||||
|
@ -370,22 +484,14 @@ impl TraceEvent {
|
|||
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()
|
||||
}),
|
||||
frame_data: msg.get_or_empty(ztcore::ZT_TRACE_FIELD_FRAME_DATA),
|
||||
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 },
|
||||
}
|
||||
flag_notee: msg.get_ui(ztcore::ZT_TRACE_FIELD_RULE_FLAG_NOTEE).unwrap_or(0) != 0,
|
||||
inbound: msg.get_ui(ztcore::ZT_TRACE_FIELD_RULE_FLAG_INBOUND).unwrap_or(0) != 0,
|
||||
result: verdict,
|
||||
})
|
||||
},
|
||||
}
|
||||
ztcore::ZT_TraceEventType_ZT_TRACE_VL2_NETWORK_CREDENTIAL_REJECTED => {
|
||||
let fp = msg.get(ztcore::ZT_TRACE_FIELD_IDENTITY_FINGERPRINT);
|
||||
if fp.is_some() {
|
||||
|
@ -403,8 +509,7 @@ impl TraceEvent {
|
|||
}
|
||||
}
|
||||
None
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -20,34 +20,38 @@ use std::sync::Mutex;
|
|||
use chrono::Datelike;
|
||||
|
||||
struct LogIntl {
|
||||
prefix: String,
|
||||
path: String,
|
||||
file: Option<File>,
|
||||
cur_size: u64,
|
||||
max_size: usize,
|
||||
log_to_stderr: bool,
|
||||
}
|
||||
|
||||
/// It's big it's heavy it's wood.
|
||||
pub(crate) struct Log {
|
||||
prefix: String,
|
||||
path: String,
|
||||
inner: Mutex<LogIntl>,
|
||||
}
|
||||
|
||||
impl Log {
|
||||
const MIN_MAX_SIZE: usize = 1024;
|
||||
|
||||
/// Construct a new logger.
|
||||
/// If path is empty logs will not be written to files. If log_to_stderr is also
|
||||
/// false then no logs will be output at all.
|
||||
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(' ');
|
||||
}
|
||||
Log{
|
||||
prefix: p,
|
||||
path: String::from(path),
|
||||
inner: Mutex::new(LogIntl {
|
||||
prefix: p,
|
||||
path: String::from(path),
|
||||
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,
|
||||
log_to_stderr,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
@ -61,60 +65,60 @@ impl Log {
|
|||
}
|
||||
|
||||
pub fn log<S: AsRef<str>>(&self, s: S) {
|
||||
// Output FATAL errors to stderr.
|
||||
let mut l = self.inner.lock().unwrap();
|
||||
|
||||
let ss: &str = s.as_ref();
|
||||
if ss.starts_with("FATAL") {
|
||||
eprintln!("{}", ss);
|
||||
}
|
||||
let log_line = format!("{}[{}] {}\n", l.prefix.as_str(), chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string(), ss);
|
||||
|
||||
let mut l = self.inner.lock().unwrap();
|
||||
if l.path.len() > 0 {
|
||||
if l.file.is_none() {
|
||||
let mut f = OpenOptions::new().read(true).write(true).create(true).open(l.path.as_str());
|
||||
if f.is_err() {
|
||||
return;
|
||||
}
|
||||
let mut f = f.unwrap();
|
||||
let eof = f.seek(SeekFrom::End(0));
|
||||
if eof.is_err() {
|
||||
return;
|
||||
}
|
||||
l.cur_size = eof.unwrap();
|
||||
l.file = Some(f);
|
||||
}
|
||||
|
||||
// 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() {
|
||||
return;
|
||||
if l.max_size > 0 && l.cur_size > l.max_size as u64 {
|
||||
l.file = None;
|
||||
l.cur_size = 0;
|
||||
|
||||
let mut old_path = l.path.clone();
|
||||
old_path.push_str(".old");
|
||||
let _ = std::fs::remove_file(old_path.as_str());
|
||||
let _ = std::fs::rename(l.path.as_str(), old_path.as_str());
|
||||
let _ = std::fs::remove_file(l.path.as_str()); // should fail
|
||||
|
||||
let mut f = OpenOptions::new().read(true).write(true).create(true).open(l.path.as_str());
|
||||
if f.is_err() {
|
||||
return;
|
||||
}
|
||||
l.file = Some(f.unwrap());
|
||||
}
|
||||
let mut f = f.unwrap();
|
||||
let eof = f.seek(SeekFrom::End(0));
|
||||
if eof.is_err() {
|
||||
return;
|
||||
|
||||
let f = l.file.as_mut().unwrap();
|
||||
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;
|
||||
}
|
||||
l.cur_size = eof.unwrap();
|
||||
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;
|
||||
|
||||
let mut old_path = self.path.clone();
|
||||
old_path.push_str(".old");
|
||||
let _ = std::fs::remove_file(old_path.as_str());
|
||||
let _ = std::fs::rename(self.path.as_str(), old_path.as_str());
|
||||
let _ = std::fs::remove_file(self.path.as_str()); // should fail
|
||||
|
||||
let mut f = OpenOptions::new().read(true).write(true).create(true).open(self.path.as_str());
|
||||
if f.is_err() {
|
||||
return;
|
||||
}
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -107,13 +107,13 @@ fn main() {
|
|||
auth_token = Some(t.unwrap().trim().to_string());
|
||||
}
|
||||
} else {
|
||||
drop(auth_token_path);
|
||||
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() {
|
||||
match cli_args.as_ref().subcommand_name().unwrap() {
|
||||
"version" => {
|
||||
let ver = zerotier_core::version();
|
||||
println!("{}.{}.{}", ver.0, ver.1, ver.2);
|
||||
|
|
|
@ -175,6 +175,7 @@ pub(crate) fn run(store: &Arc<Store>, auth_token: Option<String>) -> i32 {
|
|||
}
|
||||
let auth_token = Arc::new(auth_token);
|
||||
|
||||
// From this point on we're in tokio / async.
|
||||
let tokio_rt = tokio::runtime::Builder::new_current_thread().build().unwrap();
|
||||
tokio_rt.block_on(async {
|
||||
let mut udp_sockets: BTreeMap<InetAddress, FastUDPSocket> = BTreeMap::new();
|
||||
|
@ -195,7 +196,7 @@ pub(crate) fn run(store: &Arc<Store>, auth_token: Option<String>) -> i32 {
|
|||
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());
|
||||
l!(log, "FATAL: error initializing node: {}", node.err().unwrap().to_str());
|
||||
return;
|
||||
}
|
||||
let node = Arc::new(node.ok().unwrap());
|
||||
|
@ -254,7 +255,7 @@ pub(crate) fn run(store: &Arc<Store>, auth_token: Option<String>) -> i32 {
|
|||
_ = tokio::time::sleep(Duration::from_millis(loop_delay)) => {
|
||||
now = ms_since_epoch();
|
||||
let actual_delay = now - loop_start;
|
||||
if actual_delay > (loop_delay * 4) {
|
||||
if actual_delay > ((loop_delay as i64) * 4_i64) {
|
||||
// TODO: handle likely sleep/wake or other system interruption
|
||||
}
|
||||
},
|
||||
|
|
|
@ -19,7 +19,8 @@ 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"))]
|
||||
/// BSD based OSes support getifmaddrs().
|
||||
#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd", target_os = "dragonfly", target_os = "ios", target_os = "bsd", target_os = "darwin"))]
|
||||
pub(crate) fn bsd_get_multicast_groups(dev: &str) -> BTreeSet<MulticastGroup> {
|
||||
let mut groups: BTreeSet<MulticastGroup> = BTreeSet::new();
|
||||
let dev = dev.as_bytes();
|
||||
|
@ -47,6 +48,7 @@ pub(crate) fn bsd_get_multicast_groups(dev: &str) -> BTreeSet<MulticastGroup> {
|
|||
groups
|
||||
}
|
||||
|
||||
/// Linux stores this stuff in /proc and it needs to be fetched from there.
|
||||
#[cfg(target_os = "linux")]
|
||||
pub(crate) fn linux_get_multicast_groups(dev: &str) -> BTreeSet<MulticastGroup> {
|
||||
let mut groups: BTreeSet<MulticastGroup> = BTreeSet::new();
|
||||
|
|
|
@ -11,11 +11,27 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
/// Virtual network interface
|
||||
pub(crate) trait VNIC {
|
||||
/// Add a new IPv4 or IPv6 address to this interface, returning true on success.
|
||||
fn add_ip(&self, ip: &zerotier_core::InetAddress) -> bool;
|
||||
|
||||
/// Remove an IPv4 or IPv6 address, returning true on success.
|
||||
/// Nothing happens if the address is not found.
|
||||
fn remove_ip(&self, ip: &zerotier_core::InetAddress) -> bool;
|
||||
|
||||
/// Enumerate all IPs on this interface including ones assigned outside ZeroTier.
|
||||
fn ips(&self) -> Vec<zerotier_core::InetAddress>;
|
||||
|
||||
/// Get the OS-specific device name for this interface, e.g. zt## or tap##.
|
||||
fn device_name(&self) -> String;
|
||||
|
||||
/// Get L2 multicast groups to which this interface is subscribed.
|
||||
/// This doesn't do any IGMP snooping. It just reports the groups the port
|
||||
/// knows about. On some OSes this may not be supported in which case it
|
||||
/// will return an empty set.
|
||||
fn get_multicast_groups(&self) -> std::collections::BTreeSet<zerotier_core::MulticastGroup>;
|
||||
|
||||
/// Inject an Ethernet frame into this port.
|
||||
fn put(&self, source_mac: &zerotier_core::MAC, dest_mac: &zerotier_core::MAC, ethertype: u16, vlan_id: u16, data: *const u8, len: usize) -> bool;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue