From 36b293345b4fc2ea1c8ca96ebe6ad0ea90db8ab4 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 17 Dec 2020 21:08:34 -0500 Subject: [PATCH] Path and Peer. --- rust-zerotier-core/src/endpoint.rs | 18 +++++----- rust-zerotier-core/src/fingerprint.rs | 8 +++++ rust-zerotier-core/src/lib.rs | 14 +++++--- rust-zerotier-core/src/locator.rs | 5 ++- rust-zerotier-core/src/path.rs | 26 ++++++++++++++ rust-zerotier-core/src/peer.rs | 49 +++++++++++++++++++++++++++ 6 files changed, 104 insertions(+), 16 deletions(-) create mode 100644 rust-zerotier-core/src/path.rs create mode 100644 rust-zerotier-core/src/peer.rs diff --git a/rust-zerotier-core/src/endpoint.rs b/rust-zerotier-core/src/endpoint.rs index aece9a6ec..1b6bc51ec 100644 --- a/rust-zerotier-core/src/endpoint.rs +++ b/rust-zerotier-core/src/endpoint.rs @@ -7,18 +7,16 @@ use std::mem::MaybeUninit; pub struct Endpoint { pub type_: EndpointType, - intl: ztcore::ZT_Endpoint + capi: ztcore::ZT_Endpoint } impl Endpoint { #[inline] - pub(crate) fn new_from_capi(ep: *const ztcore::ZT_Endpoint) -> Endpoint { - unsafe { - return Endpoint{ - type_: EndpointType::from_u32((*ep).type_ as u32).unwrap(), - intl: *ep - }; - } + pub(crate) fn new_from_capi(ep: &ztcore::ZT_Endpoint) -> Endpoint { + return Endpoint{ + type_: EndpointType::from_u32(ep.type_ as u32).unwrap(), + capi: *ep + }; } pub fn new_from_string(s: &str) -> Result { @@ -29,7 +27,7 @@ impl Endpoint { let epi = cep.assume_init(); return Ok(Endpoint{ type_: EndpointType::from_u32(epi.type_ as u32).unwrap(), - intl: epi + capi: epi }); } return Err(ResultCode::from_i32(ec).unwrap()); @@ -41,7 +39,7 @@ impl ToString for Endpoint { fn to_string(&self) -> String { let mut buf: [u8; 1024] = [0; 1024]; unsafe { - if ztcore::ZT_Endpoint_toString(&(self.intl) as *const ztcore::ZT_Endpoint,buf.as_mut_ptr() as *mut c_char, buf.len() as c_int).is_null() { + if ztcore::ZT_Endpoint_toString(&(self.capi) as *const ztcore::ZT_Endpoint, buf.as_mut_ptr() as *mut c_char, buf.len() as c_int).is_null() { return String::from("(invalid)"); } return String::from(CStr::from_bytes_with_nul(buf.as_ref()).unwrap().to_str().unwrap()); diff --git a/rust-zerotier-core/src/fingerprint.rs b/rust-zerotier-core/src/fingerprint.rs index 0bfc0f78a..7cd7367ea 100644 --- a/rust-zerotier-core/src/fingerprint.rs +++ b/rust-zerotier-core/src/fingerprint.rs @@ -10,6 +10,14 @@ pub struct Fingerprint { } impl Fingerprint { + #[inline] + pub(crate) fn new_from_capi(fp: &ztcore::ZT_Fingerprint) -> Fingerprint { + Fingerprint{ + address: Address(fp.address), + hash: fp.hash + } + } + pub fn new_from_string(s: &str) -> Result { unsafe { let mut cfp: MaybeUninit = MaybeUninit::uninit(); diff --git a/rust-zerotier-core/src/lib.rs b/rust-zerotier-core/src/lib.rs index e2f6c4302..eb013c6eb 100644 --- a/rust-zerotier-core/src/lib.rs +++ b/rust-zerotier-core/src/lib.rs @@ -6,6 +6,8 @@ mod endpoint; mod certificate; mod networkid; mod locator; +mod path; +mod peer; pub use identity::*; pub use address::*; @@ -14,10 +16,11 @@ pub use endpoint::*; pub use networkid::*; pub use locator::*; pub use certificate::*; +pub use path::*; +pub use peer::*; use bindings::capi as ztcore; -use num_derive::FromPrimitive; -use num_derive::ToPrimitive; +use num_derive::{FromPrimitive, ToPrimitive}; use std::os::raw::c_int; pub const DEFAULT_PORT: u16 = ztcore::ZT_DEFAULT_PORT as u16; @@ -212,7 +215,8 @@ pub enum StateObjectType { Certificate = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_CERT as isize } -pub fn version() -> (u32, u32, u32, u32) { +/// Returns a tuple of major, minor, revision, and build version numbers from the ZeroTier core. +pub fn version() -> (i32, i32, i32, i32) { let mut major: c_int = 0; let mut minor: c_int = 0; let mut revision: c_int = 0; @@ -220,10 +224,10 @@ pub fn version() -> (u32, u32, u32, u32) { unsafe { ztcore::ZT_version(&mut major as *mut c_int, &mut minor as *mut c_int, &mut revision as *mut c_int, &mut build as *mut c_int); } - (major as u32, minor as u32, revision as u32, build as u32) + (major as i32, minor as i32, revision as i32, build as i32) } -#[macro_export] +#[macro_export(crate)] macro_rules! implement_json_serializable { ($struct_name:ident) => { impl $struct_name { diff --git a/rust-zerotier-core/src/locator.rs b/rust-zerotier-core/src/locator.rs index 7c985e6fe..af4c375d7 100644 --- a/rust-zerotier-core/src/locator.rs +++ b/rust-zerotier-core/src/locator.rs @@ -39,7 +39,10 @@ impl Locator { let ep_count = ztcore::ZT_Locator_endpointCount(self.capi) as usize; eps.reserve(ep_count as usize); for i in 0..ep_count { - eps.push(Endpoint::new_from_capi(ztcore::ZT_Locator_endpoint(self.capi, i as c_uint))); + let ep = ztcore::ZT_Locator_endpoint(self.capi, i as c_uint); + if !ep.is_null() { + eps.push(Endpoint::new_from_capi(&(*ep))); + } } } eps.into_boxed_slice() diff --git a/rust-zerotier-core/src/path.rs b/rust-zerotier-core/src/path.rs new file mode 100644 index 000000000..e27063516 --- /dev/null +++ b/rust-zerotier-core/src/path.rs @@ -0,0 +1,26 @@ +use crate::*; +use crate::bindings::capi as ztcore; +use serde::{Deserialize, Serialize}; + +#[allow(non_snake_case)] +#[derive(Serialize, Deserialize)] +pub struct Path { + pub endpoint: Endpoint, + pub lastSend: i64, + pub lastReceive: i64, + pub alive: bool, + pub preferred: bool +} + +impl Path { + #[inline] + pub(crate) fn new_from_capi(p: &ztcore::ZT_Path) -> Path { + Path{ + endpoint: Endpoint::new_from_capi(&p.endpoint), + lastSend: p.lastSend, + lastReceive: p.lastReceive, + alive: p.alive != 0, + preferred: p.preferred != 0 + } + } +} diff --git a/rust-zerotier-core/src/peer.rs b/rust-zerotier-core/src/peer.rs new file mode 100644 index 000000000..6eae08bbe --- /dev/null +++ b/rust-zerotier-core/src/peer.rs @@ -0,0 +1,49 @@ +use crate::*; +use crate::bindings::capi as ztcore; +use serde::{Deserialize, Serialize}; + +#[allow(non_snake_case)] +#[derive(Serialize, Deserialize)] +pub struct Peer { + address: Address, + identity: Identity, + fingerprint: Fingerprint, + versionMajor: i32, + versionMinor: i32, + versionRev: i32, + versionProto: i32, + latency: i32, + root: bool, + networks: Box<[NetworkId]>, + paths: Box<[Path]>, + // locator: Locator +} + +impl Peer { + #[inline] + pub(crate) fn new_from_capi(p: &ztcore::ZT_Peer) -> Peer { + unsafe { + let mut networks: Vec = Vec::new(); + for i in 0..(p.networkCount as isize) { + networks.push(NetworkId(*p.networks.offset(i))); + } + let mut paths: Vec = Vec::new(); + for i in 0..(p.pathCount as isize) { + paths.push(Path::new_from_capi(&(*p.paths.offset(i)))); + } + return Peer { + address: Address(p.address), + identity: Identity::new_from_capi(p.identity, false), + fingerprint: Fingerprint::new_from_capi(&(*p.fingerprint)), + versionMajor: p.versionMajor as i32, + versionMinor: p.versionMinor as i32, + versionRev: p.versionRev as i32, + versionProto: p.versionProto as i32, + latency: p.latency as i32, + root: p.root != 0, + networks: networks.into_boxed_slice(), + paths: paths.into_boxed_slice() + } + } + } +}