Comments, implementation of some standard stuff in Rust.

This commit is contained in:
Adam Ierymenko 2021-01-13 16:09:27 -05:00
parent e2dbfc12a5
commit 98d6e05b2d
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
6 changed files with 56 additions and 25 deletions

View file

@ -44,13 +44,23 @@ impl Buffer {
}; };
} }
/// Get the current size of the data held by this buffer. Initially this is /// Get the current size of the data held by this buffer.
/// equal to CAPACITY. /// Initially this is equal to CAPACITY.
#[inline(always)] #[inline(always)]
pub fn len(&self) -> u32 { pub fn len(&self) -> u32 {
self.data_size self.data_size
} }
#[inline(always)]
pub fn as_ptr(&self) -> *const u8 {
self.zt_core_buf
}
#[inline(always)]
pub fn as_mut_ptr(&mut self) -> *mut u8 {
self.zt_core_buf
}
/// Set the size of the data held by this buffer. This is unsafe because /// Set the size of the data held by this buffer. This is unsafe because
/// setting it to a value larger than CAPACITY will place the buffer into /// setting it to a value larger than CAPACITY will place the buffer into
/// an invalid state. /// an invalid state.

View file

@ -21,7 +21,7 @@ use num_traits::FromPrimitive;
use crate::*; use crate::*;
use crate::bindings::capi as ztcore; use crate::bindings::capi as ztcore;
#[derive(FromPrimitive,ToPrimitive)] #[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
pub enum EndpointType { pub enum EndpointType {
Nil = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_NIL as isize, Nil = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_NIL as isize,
ZeroTier = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_ZEROTIER as isize, ZeroTier = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_ZEROTIER as isize,

View file

@ -29,7 +29,7 @@ use std::os::raw::{c_void, c_uint};
// blobs to be freely cast to one another. That the sizes are correct is // blobs to be freely cast to one another. That the sizes are correct is
// checked statically in the C++ code and in the tests in the Rust code. // checked statically in the C++ code and in the tests in the Rust code.
#[derive(FromPrimitive,ToPrimitive)] #[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
pub enum IpScope { pub enum IpScope {
None = ztcore::ZT_InetAddress_IpScope_ZT_IP_SCOPE_NONE as isize, None = ztcore::ZT_InetAddress_IpScope_ZT_IP_SCOPE_NONE as isize,
Multicast = ztcore::ZT_InetAddress_IpScope_ZT_IP_SCOPE_MULTICAST as isize, Multicast = ztcore::ZT_InetAddress_IpScope_ZT_IP_SCOPE_MULTICAST as isize,
@ -41,6 +41,7 @@ pub enum IpScope {
Private = ztcore::ZT_InetAddress_IpScope_ZT_IP_SCOPE_PRIVATE as isize Private = ztcore::ZT_InetAddress_IpScope_ZT_IP_SCOPE_PRIVATE as isize
} }
#[derive(PartialEq, Eq)]
pub enum InetAddressFamily { pub enum InetAddressFamily {
Nil, Nil,
IPv4, IPv4,
@ -91,6 +92,10 @@ impl InetAddress {
Some(a) Some(a)
} }
/// Transmute a ZT_InetAddress from the core into a reference to a Rust
/// InetAddress containing exactly the same data. The returned reference
/// of course only remains valid so long as the ZT_InetAddress remains
/// valid.
#[inline(always)] #[inline(always)]
pub(crate) fn transmute_capi(a: &ztcore::ZT_InetAddress) -> &InetAddress { pub(crate) fn transmute_capi(a: &ztcore::ZT_InetAddress) -> &InetAddress {
unsafe { unsafe {
@ -98,6 +103,8 @@ impl InetAddress {
} }
} }
/// Create an InetAddress by copying a ZT_InetAddress instead of transmuting.
/// Returns None if the input is a nil address.
pub(crate) fn new_from_capi(a: &ztcore::ZT_InetAddress) -> Option<InetAddress> { pub(crate) fn new_from_capi(a: &ztcore::ZT_InetAddress) -> Option<InetAddress> {
if a.bits[0] != 0 { if a.bits[0] != 0 {
Some(InetAddress { Some(InetAddress {

View file

@ -77,7 +77,7 @@ pub mod RulePacketCharacteristicFlags {
pub const TcpFlagFIN: u64 = crate::bindings::capi::ZT_RULE_PACKET_CHARACTERISTICS_TCP_FIN as u64; pub const TcpFlagFIN: u64 = crate::bindings::capi::ZT_RULE_PACKET_CHARACTERISTICS_TCP_FIN as u64;
} }
#[derive(FromPrimitive,ToPrimitive)] #[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
pub enum CredentialType { pub enum CredentialType {
Null = ztcore::ZT_CredentialType_ZT_CREDENTIAL_TYPE_NULL as isize, Null = ztcore::ZT_CredentialType_ZT_CREDENTIAL_TYPE_NULL as isize,
CertificateOfMembership = ztcore::ZT_CredentialType_ZT_CREDENTIAL_TYPE_COM as isize, CertificateOfMembership = ztcore::ZT_CredentialType_ZT_CREDENTIAL_TYPE_COM as isize,
@ -87,7 +87,7 @@ pub enum CredentialType {
Revocation = ztcore::ZT_CredentialType_ZT_CREDENTIAL_TYPE_REVOCATION as isize, Revocation = ztcore::ZT_CredentialType_ZT_CREDENTIAL_TYPE_REVOCATION as isize,
} }
#[derive(FromPrimitive,ToPrimitive)] #[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
pub enum TraceEventType { pub enum TraceEventType {
UnexpectedError = ztcore::ZT_TraceEventType_ZT_TRACE_UNEXPECTED_ERROR as isize, UnexpectedError = ztcore::ZT_TraceEventType_ZT_TRACE_UNEXPECTED_ERROR as isize,
ResetingPathsInScope = ztcore::ZT_TraceEventType_ZT_TRACE_VL1_RESETTING_PATHS_IN_SCOPE as isize, ResetingPathsInScope = ztcore::ZT_TraceEventType_ZT_TRACE_VL1_RESETTING_PATHS_IN_SCOPE as isize,
@ -100,7 +100,7 @@ pub enum TraceEventType {
NetworkFilter = ztcore::ZT_TraceEventType_ZT_TRACE_VL2_NETWORK_FILTER as isize, NetworkFilter = ztcore::ZT_TraceEventType_ZT_TRACE_VL2_NETWORK_FILTER as isize,
} }
#[derive(FromPrimitive,ToPrimitive)] #[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
pub enum TracePacketDropReason { pub enum TracePacketDropReason {
Unspecified = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_UNSPECIFIED as isize, 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, PeerTooOld = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_PEER_TOO_OLD as isize,
@ -113,7 +113,7 @@ pub enum TracePacketDropReason {
ReplyNotExpected = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_REPLY_NOT_EXPECTED as isize, ReplyNotExpected = ztcore::ZT_TracePacketDropReason_ZT_TRACE_PACKET_DROP_REASON_REPLY_NOT_EXPECTED as isize,
} }
#[derive(FromPrimitive,ToPrimitive)] #[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
pub enum TraceFrameDropReason { pub enum TraceFrameDropReason {
Unspecified = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_UNSPECIFIED as isize, 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, BridgingNotAllowedRemote = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_BRIDGING_NOT_ALLOWED_REMOTE as isize,
@ -125,7 +125,7 @@ pub enum TraceFrameDropReason {
PermissionDenied = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_PERMISSION_DENIED as isize, PermissionDenied = ztcore::ZT_TraceFrameDropReason_ZT_TRACE_FRAME_DROP_REASON_PERMISSION_DENIED as isize,
} }
#[derive(FromPrimitive,ToPrimitive)] #[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
pub enum TraceCredentialRejectionReason { pub enum TraceCredentialRejectionReason {
SignatureVerificationFailed = ztcore::ZT_TraceCredentialRejectionReason_ZT_TRACE_CREDENTIAL_REJECTION_REASON_SIGNATURE_VERIFICATION_FAILED as isize, 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, Revoked = ztcore::ZT_TraceCredentialRejectionReason_ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED as isize,
@ -133,7 +133,7 @@ pub enum TraceCredentialRejectionReason {
Invalid = ztcore::ZT_TraceCredentialRejectionReason_ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID as isize, Invalid = ztcore::ZT_TraceCredentialRejectionReason_ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID as isize,
} }
#[derive(FromPrimitive,ToPrimitive)] #[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
pub enum ResultCode { pub enum ResultCode {
Ok = ztcore::ZT_ResultCode_ZT_RESULT_OK as isize, Ok = ztcore::ZT_ResultCode_ZT_RESULT_OK as isize,
FatalErrorOutOfMemory = ztcore::ZT_ResultCode_ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY as isize, FatalErrorOutOfMemory = ztcore::ZT_ResultCode_ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY as isize,
@ -183,6 +183,7 @@ pub unsafe fn cstr_to_string(cstr: *const c_char, max_len: isize) -> String {
String::new() String::new()
} }
/// Macro to implement to_json and new_from_json on types that are Serializable.
#[macro_export(crate)] #[macro_export(crate)]
macro_rules! implement_to_from_json { macro_rules! implement_to_from_json {
($struct_name:ident) => { ($struct_name:ident) => {

View file

@ -30,10 +30,9 @@ use serde::{Deserialize, Serialize};
use crate::*; use crate::*;
use crate::bindings::capi as ztcore; use crate::bindings::capi as ztcore;
/// Minimum delay between iterations of the background loop. const NODE_BACKGROUND_MAX_DELAY: i64 = 250;
const NODE_BACKGROUND_MIN_DELAY: i64 = 250;
#[derive(FromPrimitive,ToPrimitive)] #[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
pub enum Event { pub enum Event {
Up = ztcore::ZT_Event_ZT_EVENT_UP as isize, Up = ztcore::ZT_Event_ZT_EVENT_UP as isize,
Offline = ztcore::ZT_Event_ZT_EVENT_OFFLINE as isize, Offline = ztcore::ZT_Event_ZT_EVENT_OFFLINE as isize,
@ -43,7 +42,7 @@ pub enum Event {
UserMessage = ztcore::ZT_Event_ZT_EVENT_USER_MESSAGE as isize, UserMessage = ztcore::ZT_Event_ZT_EVENT_USER_MESSAGE as isize,
} }
#[derive(FromPrimitive,ToPrimitive)] #[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
pub enum StateObjectType { pub enum StateObjectType {
IdentityPublic = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_IDENTITY_PUBLIC as isize, IdentityPublic = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_IDENTITY_PUBLIC as isize,
IdentitySecret = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_IDENTITY_SECRET as isize, IdentitySecret = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_IDENTITY_SECRET as isize,
@ -55,6 +54,7 @@ pub enum StateObjectType {
} }
impl StateObjectType { impl StateObjectType {
/// Get the canonical file extension for this object type.
pub fn to_file_ext(&self) -> &str { pub fn to_file_ext(&self) -> &str {
match *self { match *self {
StateObjectType::IdentityPublic => "public", StateObjectType::IdentityPublic => "public",
@ -171,9 +171,14 @@ extern "C" fn zt_virtual_network_frame_function<T: NodeEventHandler + 'static>(
) { ) {
if !nptr.is_null() { if !nptr.is_null() {
let n = node_from_raw_ptr!(uptr); let n = node_from_raw_ptr!(uptr);
let network_obj: &Arc<dyn Any> = unsafe { &*((*nptr).cast::<Arc<dyn Any>>()) }; n.event_handler.virtual_network_frame(
let data_slice = unsafe { &*slice_from_raw_parts(data.cast::<u8>(), data_size as usize) }; NetworkId(nwid),
n.event_handler.virtual_network_frame(NetworkId(nwid), network_obj, MAC(source_mac), MAC(dest_mac), ethertype as u16, vlan_id as u16, data_slice); unsafe { &*((*nptr).cast::<Arc<dyn Any>>()) },
MAC(source_mac),
MAC(dest_mac),
ethertype as u16,
vlan_id as u16,
unsafe { &*slice_from_raw_parts(data.cast::<u8>(), data_size as usize) });
} }
} }
@ -366,7 +371,7 @@ impl<T: NodeEventHandler + 'static> Node<T> {
let wn = Arc::downgrade(&n); let wn = Arc::downgrade(&n);
let run = n.background_thread_run.clone(); let run = n.background_thread_run.clone();
n.background_thread.replace(Some(std::thread::spawn(move || { n.background_thread.replace(Some(std::thread::spawn(move || {
let mut loop_delay = Duration::from_millis(500); let mut loop_delay = Duration::from_millis(NODE_BACKGROUND_MAX_DELAY as u64);
while run.load(Ordering::Relaxed) { while run.load(Ordering::Relaxed) {
std::thread::park_timeout(loop_delay); std::thread::park_timeout(loop_delay);
if run.load(Ordering::Relaxed) { if run.load(Ordering::Relaxed) {
@ -386,7 +391,6 @@ impl<T: NodeEventHandler + 'static> Node<T> {
} }
/// This is called periodically from the background service thread. /// This is called periodically from the background service thread.
#[inline(always)]
fn process_background_tasks(&self) -> i64 { fn process_background_tasks(&self) -> i64 {
let current_time = now(); let current_time = now();
self.now.set(current_time); self.now.set(current_time);
@ -399,8 +403,8 @@ impl<T: NodeEventHandler + 'static> Node<T> {
if next_delay < 10 { if next_delay < 10 {
next_delay = 10; next_delay = 10;
} else if next_delay > NODE_BACKGROUND_MIN_DELAY { } else if next_delay > NODE_BACKGROUND_MAX_DELAY {
next_delay = NODE_BACKGROUND_MIN_DELAY; next_delay = NODE_BACKGROUND_MAX_DELAY;
} }
next_delay next_delay
} }
@ -450,7 +454,7 @@ impl<T: NodeEventHandler + 'static> Node<T> {
} }
#[inline(always)] #[inline(always)]
pub fn process_wire_packet<A>(&self, local_socket: i64, remote_address: &InetAddress, data: Buffer) -> ResultCode { pub fn process_wire_packet(&self, local_socket: i64, remote_address: &InetAddress, data: Buffer) -> ResultCode {
let current_time = self.now.get(); let current_time = self.now.get();
let mut next_task_deadline: i64 = current_time; let mut next_task_deadline: i64 = current_time;
let rc = unsafe { ResultCode::from_i32(ztcore::ZT_Node_processWirePacket(self.capi.get(), null_mut(), current_time, local_socket, remote_address.as_capi_ptr(), data.zt_core_buf as *const c_void, data.data_size as u32, 1, &mut next_task_deadline as *mut i64) as i32).unwrap_or(ResultCode::ErrorInternalNonFatal) }; let rc = unsafe { ResultCode::from_i32(ztcore::ZT_Node_processWirePacket(self.capi.get(), null_mut(), current_time, local_socket, remote_address.as_capi_ptr(), data.zt_core_buf as *const c_void, data.data_size as u32, 1, &mut next_task_deadline as *mut i64) as i32).unwrap_or(ResultCode::ErrorInternalNonFatal) };
@ -479,9 +483,17 @@ impl<T: NodeEventHandler + 'static> Node<T> {
} }
} }
/// Get a copy of this node's identity.
pub fn identity(&self) -> Identity { pub fn identity(&self) -> Identity {
let id = unsafe { ztcore::ZT_Node_identity(self.capi.get()) }; unsafe { self.identity_fast().clone() }
return Identity::new_from_capi(id, false).clone(); }
/// Get an identity that simply holds a pointer to the underlying node's identity.
/// This is unsafe because the identity object becomes invalid if the node ceases
/// to exist the Identity becomes invalid. Use clone() on it to get a copy.
#[inline(always)]
pub(crate) unsafe fn identity_fast(&self) -> Identity {
Identity::new_from_capi(ztcore::ZT_Node_identity(self.capi.get()), false)
} }
pub fn status(&self) -> NodeStatus { pub fn status(&self) -> NodeStatus {

View file

@ -18,7 +18,8 @@ use std::sync::Mutex;
use std::sync::atomic::{AtomicI64, Ordering}; use std::sync::atomic::{AtomicI64, Ordering};
// This implements a basic atomic i64 that uses a mutex on 32-bit systems, // This implements a basic atomic i64 that uses a mutex on 32-bit systems,
// since you can't atomically access something larger than word size. // since you can't atomically access something larger than word size in most
// cases.
#[cfg(all(target_pointer_width = "32"))] #[cfg(all(target_pointer_width = "32"))]
pub struct PortableAtomicI64 { pub struct PortableAtomicI64 {