A bunch of logging and tracing.

This commit is contained in:
Adam Ierymenko 2021-02-19 17:05:53 -05:00
parent 411373dd2c
commit d201cdec2a
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
11 changed files with 407 additions and 212 deletions

View file

@ -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);

View file

@ -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()
}
}

View file

@ -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{

View file

@ -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];

View file

@ -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)),*
}
}
}
};
}

View file

@ -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,
}
}
})
}

View file

@ -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;
}
}
}

View file

@ -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);

View file

@ -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
}
},

View file

@ -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();

View file

@ -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;
}