mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-03 19:13:43 +02:00
... more Rust
This commit is contained in:
parent
2c07a0cd75
commit
8d0d479662
5 changed files with 214 additions and 31 deletions
|
@ -129,6 +129,14 @@ impl Identity {
|
|||
}
|
||||
}
|
||||
|
||||
impl Clone for Identity {
|
||||
fn clone(&self) -> Identity {
|
||||
unsafe {
|
||||
return Identity::new_from_capi(ztcore::ZT_Identity_clone(self.capi), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Identity {
|
||||
fn drop(&mut self) {
|
||||
if self.requires_delete {
|
||||
|
|
|
@ -13,7 +13,7 @@ mod mac;
|
|||
mod buffer;
|
||||
mod portableatomici64;
|
||||
|
||||
pub use identity::*;
|
||||
pub use identity::{Identity, IdentityType};
|
||||
pub use address::Address;
|
||||
pub use fingerprint::Fingerprint;
|
||||
pub use endpoint::Endpoint;
|
||||
|
@ -22,7 +22,7 @@ pub use locator::Locator;
|
|||
pub use certificate::*;
|
||||
pub use path::Path;
|
||||
pub use peer::Peer;
|
||||
pub use node::*;
|
||||
pub use node::Node;
|
||||
pub use mac::MAC;
|
||||
pub use buffer::Buffer;
|
||||
pub use portableatomici64::PortableAtomicI64;
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
use std::cell::Cell;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::os::raw::{c_uint, c_ulong, c_void};
|
||||
use std::os::raw::{c_int, c_uint, c_ulong, c_void};
|
||||
use std::ptr::null_mut;
|
||||
use std::sync::*;
|
||||
use std::sync::atomic::*;
|
||||
use std::time::Duration;
|
||||
use std::mem::transmute;
|
||||
use std::intrinsics::arith_offset;
|
||||
use std::ffi::CStr;
|
||||
|
||||
use num_traits::FromPrimitive;
|
||||
use socket2::SockAddr;
|
||||
|
@ -12,23 +15,163 @@ use socket2::SockAddr;
|
|||
use crate::*;
|
||||
use crate::bindings::capi as ztcore;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub struct NodeStatus {
|
||||
pub address: Address,
|
||||
pub identity: Identity,
|
||||
pub publicIdentity: String,
|
||||
pub secretIdentity: String,
|
||||
pub online: bool
|
||||
}
|
||||
|
||||
pub struct Node {
|
||||
capi: *mut ztcore::ZT_Node,
|
||||
capi: Cell<*mut ztcore::ZT_Node>,
|
||||
node_uptr: Cell<Weak<Node>>, // A pointer to this Weak<Node> is passed in as 'uptr' for the core Node.
|
||||
background_thread: Cell<Option<std::thread::JoinHandle<()>>>,
|
||||
background_thread_run: Arc<AtomicBool>,
|
||||
now: PortableAtomicI64,
|
||||
}
|
||||
|
||||
macro_rules! node_from_raw_ptr {
|
||||
($uptr:ident) => {
|
||||
{
|
||||
let ntmp = unsafe { (*($uptr as *mut Weak<Node>)).upgrade() };
|
||||
if ntmp.is_none() { return; }
|
||||
ntmp.unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn zt_virtual_network_config_function(
|
||||
capi: *mut ztcore::ZT_Node,
|
||||
uptr: *mut c_void,
|
||||
tptr: *mut c_void,
|
||||
nwid: u64,
|
||||
nptr: *mut *mut c_void,
|
||||
op: ztcore::ZT_VirtualNetworkConfigOperation,
|
||||
conf: *const ztcore::ZT_VirtualNetworkConfig,
|
||||
) {
|
||||
//let n = node_from_raw_ptr!(uptr);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn zt_virtual_network_frame_function(
|
||||
capi: *mut ztcore::ZT_Node,
|
||||
uptr: *mut c_void,
|
||||
tptr: *mut c_void,
|
||||
nwid: u64,
|
||||
nptr: *mut *mut c_void,
|
||||
source_mac: u64,
|
||||
dest_mac: u64,
|
||||
ethertype: c_uint,
|
||||
vlan_id: c_uint,
|
||||
data: *const c_void,
|
||||
data_size: c_uint,
|
||||
) {}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn zt_event_callback(
|
||||
capi: *mut ztcore::ZT_Node,
|
||||
uptr: *mut c_void,
|
||||
tptr: *mut c_void,
|
||||
ev: ztcore::ZT_Event,
|
||||
data: *const c_void,
|
||||
) {}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn zt_state_put_function(
|
||||
capi: *mut ztcore::ZT_Node,
|
||||
uptr: *mut c_void,
|
||||
tptr: *mut c_void,
|
||||
obj_type: ztcore::ZT_StateObjectType,
|
||||
obj_id: *const u64,
|
||||
obj_data: *const c_void,
|
||||
obj_data_len: c_int
|
||||
) {}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn zt_state_get_function(
|
||||
capi: *mut ztcore::ZT_Node,
|
||||
uptr: *mut c_void,
|
||||
tptr: *mut c_void,
|
||||
obj_type: ztcore::ZT_StateObjectType,
|
||||
obj_id: *const u64,
|
||||
obj_data: *mut *mut c_void,
|
||||
obj_data_free_function: *mut *mut c_void
|
||||
) {}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn zt_wire_packet_send_function(
|
||||
capi: *mut ztcore::ZT_Node,
|
||||
uptr: *mut c_void,
|
||||
tptr: *mut c_void,
|
||||
local_socket: i64,
|
||||
sock_addr: *const ztcore::sockaddr_storage,
|
||||
data: *const c_void,
|
||||
data_size: c_uint,
|
||||
packet_ttl: c_uint
|
||||
) {}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn zt_path_check_function(
|
||||
capi: *mut ztcore::ZT_Node,
|
||||
uptr: *mut c_void,
|
||||
tptr: *mut c_void,
|
||||
address: u64,
|
||||
identity: *const ztcore::ZT_Identity,
|
||||
local_socket: i64,
|
||||
sock_addr: *const ztcore::sockaddr_storage
|
||||
) {}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn zt_path_lookup_function(
|
||||
capi: *mut ztcore::ZT_Node,
|
||||
uptr: *mut c_void,
|
||||
tptr: *mut c_void,
|
||||
address: u64,
|
||||
identity: *const ztcore::ZT_Identity,
|
||||
sock_family: c_int,
|
||||
sock_addr: *mut ztcore::sockaddr_storage
|
||||
) {}
|
||||
|
||||
impl Node {
|
||||
pub fn new(base_dir: &std::path::Path) -> Arc<Node> {
|
||||
let n: Arc<Node> = Arc::new(Node {
|
||||
capi: null_mut(), // TODO
|
||||
pub fn new(base_dir: &std::path::Path) -> Result<Arc<Node>, ResultCode> {
|
||||
let now = now();
|
||||
|
||||
let n = Arc::new(Node {
|
||||
capi: Cell::new(null_mut()),
|
||||
node_uptr: Cell::new(Weak::new()),
|
||||
background_thread: Cell::new(None),
|
||||
background_thread_run: Arc::new(AtomicBool::new(true)),
|
||||
now: PortableAtomicI64::new(now()),
|
||||
now: PortableAtomicI64::new(now),
|
||||
});
|
||||
|
||||
let wn = Arc::downgrade(&n);
|
||||
n.node_uptr.replace(wn.clone());
|
||||
|
||||
let mut capi: *mut ztcore::ZT_Node = null_mut();
|
||||
unsafe {
|
||||
let callbacks = ztcore::ZT_Node_Callbacks {
|
||||
statePutFunction: transmute(zt_state_put_function as *const ()),
|
||||
stateGetFunction: transmute(zt_state_get_function as *const ()),
|
||||
wirePacketSendFunction: transmute(zt_wire_packet_send_function as *const ()),
|
||||
virtualNetworkFrameFunction: transmute(zt_virtual_network_frame_function as *const ()),
|
||||
virtualNetworkConfigFunction: transmute(zt_virtual_network_config_function as *const ()),
|
||||
eventCallback: transmute(zt_event_callback as *const ()),
|
||||
pathCheckFunction: transmute(zt_path_check_function as *const ()),
|
||||
pathLookupFunction: transmute(zt_path_lookup_function as *const ())
|
||||
};
|
||||
|
||||
let rc = ztcore::ZT_Node_new(&mut capi as *mut *mut ztcore::ZT_Node, n.node_uptr.as_ptr() as *mut c_void, null_mut(), &callbacks as *const ztcore::ZT_Node_Callbacks, now);
|
||||
if rc != 0 {
|
||||
return Err(ResultCode::from_u32(rc as u32).unwrap_or(ResultCode::FatalErrorInternal));
|
||||
} else if capi.is_null() {
|
||||
return Err(ResultCode::FatalErrorInternal);
|
||||
}
|
||||
}
|
||||
n.capi.replace(capi);
|
||||
|
||||
let run = n.background_thread_run.clone();
|
||||
n.background_thread.replace(Some(std::thread::spawn(move || {
|
||||
let mut loop_delay = Duration::from_millis(500);
|
||||
|
@ -47,7 +190,7 @@ impl Node {
|
|||
}
|
||||
})));
|
||||
|
||||
n
|
||||
Ok(n)
|
||||
}
|
||||
|
||||
/// This is called periodically from internal background thread.
|
||||
|
@ -59,7 +202,7 @@ impl Node {
|
|||
|
||||
let mut next_task_deadline: i64 = current_time;
|
||||
unsafe {
|
||||
ztcore::ZT_Node_processBackgroundTasks(self.capi, 0 as *mut c_void, current_time, &mut next_task_deadline as *mut i64);
|
||||
ztcore::ZT_Node_processBackgroundTasks(self.capi.get(), 0 as *mut c_void, current_time, &mut next_task_deadline as *mut i64);
|
||||
}
|
||||
let mut next_delay = next_task_deadline - current_time;
|
||||
|
||||
|
@ -83,28 +226,21 @@ impl Node {
|
|||
}
|
||||
}
|
||||
unsafe {
|
||||
let rc = ztcore::ZT_Node_join(self.capi, nwid.0, cfpp, null_mut(), null_mut());
|
||||
let rc = ztcore::ZT_Node_join(self.capi.get(), nwid.0, cfpp, null_mut(), null_mut());
|
||||
return ResultCode::from_u32(rc as u32).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn leave(&self, nwid: NetworkId) -> ResultCode {
|
||||
unsafe {
|
||||
let rc = ztcore::ZT_Node_leave(self.capi, nwid.0, null_mut(), null_mut());
|
||||
return ResultCode::from_u32(rc as u32).unwrap();
|
||||
return ResultCode::from_u32(ztcore::ZT_Node_leave(self.capi.get(), nwid.0, null_mut(), null_mut()) as u32).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn address(&self) -> Address {
|
||||
unsafe {
|
||||
return Address(ztcore::ZT_Node_address(self.capi) as u64);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn identity(&self) -> Identity {
|
||||
unsafe {
|
||||
return Identity::new_from_capi(ztcore::ZT_Node_identity(self.capi), false);
|
||||
return Address(ztcore::ZT_Node_address(self.capi.get()) as u64);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,7 +249,7 @@ impl Node {
|
|||
let current_time = self.now.get();
|
||||
let mut next_task_deadline: i64 = current_time;
|
||||
unsafe {
|
||||
return ResultCode::from_u32(ztcore::ZT_Node_processWirePacket(self.capi, null_mut(), current_time, local_socket, remote_address.as_ptr() as *const ztcore::sockaddr_storage, data.zt_core_buf as *const c_void, data.data_size as u32, 1, &mut next_task_deadline as *mut i64) as u32).unwrap_or(ResultCode::ErrorInternalNonFatal);
|
||||
return ResultCode::from_u32(ztcore::ZT_Node_processWirePacket(self.capi.get(), null_mut(), current_time, local_socket, remote_address.as_ptr() as *const ztcore::sockaddr_storage, data.zt_core_buf as *const c_void, data.data_size as u32, 1, &mut next_task_deadline as *mut i64) as u32).unwrap_or(ResultCode::ErrorInternalNonFatal);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,21 +258,61 @@ impl Node {
|
|||
let current_time = self.now.get();
|
||||
let mut next_tick_deadline: i64 = current_time;
|
||||
unsafe {
|
||||
return ResultCode::from_u32(ztcore::ZT_Node_processVirtualNetworkFrame(self.capi, null_mut(), current_time, nwid.0, source_mac.0, dest_mac.0, ethertype as c_uint, vlan_id as c_uint, data.zt_core_buf as *const c_void, data.data_size as u32, 1, &mut next_tick_deadline as *mut i64) as u32).unwrap_or(ResultCode::ErrorInternalNonFatal);
|
||||
return ResultCode::from_u32(ztcore::ZT_Node_processVirtualNetworkFrame(self.capi.get(), null_mut(), current_time, nwid.0, source_mac.0, dest_mac.0, ethertype as c_uint, vlan_id as c_uint, data.zt_core_buf as *const c_void, data.data_size as u32, 1, &mut next_tick_deadline as *mut i64) as u32).unwrap_or(ResultCode::ErrorInternalNonFatal);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn multicast_subscribe(&self, nwid: &NetworkId, multicast_group: &MAC, multicast_adi: u32) -> ResultCode {
|
||||
unsafe {
|
||||
return ResultCode::from_u32(ztcore::ZT_Node_multicastSubscribe(self.capi, null_mut(), nwid.0, multicast_group.0, multicast_adi as c_ulong) as u32).unwrap_or(ResultCode::ErrorInternalNonFatal);
|
||||
return ResultCode::from_u32(ztcore::ZT_Node_multicastSubscribe(self.capi.get(), null_mut(), nwid.0, multicast_group.0, multicast_adi as c_ulong) as u32).unwrap_or(ResultCode::ErrorInternalNonFatal);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn multicast_unsubscribe(&self, nwid: &NetworkId, multicast_group: &MAC, multicast_adi: u32) -> ResultCode {
|
||||
unsafe {
|
||||
return ResultCode::from_u32(ztcore::ZT_Node_multicastUnsubscribe(self.capi, nwid.0, multicast_group.0, multicast_adi as c_ulong) as u32).unwrap_or(ResultCode::ErrorInternalNonFatal);
|
||||
return ResultCode::from_u32(ztcore::ZT_Node_multicastUnsubscribe(self.capi.get(), nwid.0, multicast_group.0, multicast_adi as c_ulong) as u32).unwrap_or(ResultCode::ErrorInternalNonFatal);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn identity(&self) -> Identity {
|
||||
unsafe {
|
||||
let mut id = ztcore::ZT_Node_identity(self.capi.get());
|
||||
return Identity::new_from_capi(id, false).clone();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn status(&self) -> NodeStatus {
|
||||
unsafe {
|
||||
let mut ns: MaybeUninit<ztcore::ZT_NodeStatus> = MaybeUninit::zeroed();
|
||||
ztcore::ZT_Node_status(self.capi.get(), ns.as_mut_ptr());
|
||||
let ns = ns.assume_init();
|
||||
if ns.identity.is_null() {
|
||||
panic!("ZT_Node_status() returned null identity");
|
||||
}
|
||||
return NodeStatus {
|
||||
address: Address(ns.address),
|
||||
identity: Identity::new_from_capi(&*ns.identity, false).clone(),
|
||||
publicIdentity: String::from(CStr::from_ptr(ns.publicIdentity)),
|
||||
secretIdentity: String::from(CStr::from_ptr(ns.secretIdentity)),
|
||||
online: ns.online != 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn peers(&self) -> Vec<Peer> {
|
||||
let mut p: Vec<Peer> = Vec::new();
|
||||
unsafe {
|
||||
let pl = ztcore::ZT_Node_peers(self.capi.get());
|
||||
if !pl.is_null() {
|
||||
p.reserve(pl.peerCount as usize);
|
||||
for i in 0..(pl.peerCount as isize) {
|
||||
p.push(Peer::new_from_capi(&*arith_offset(pl.peers, i)));
|
||||
}
|
||||
ztcore::ZT_freeQueryResult(pl as *const c_void);
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Sync for Node {}
|
||||
|
@ -146,7 +322,6 @@ unsafe impl Send for Node {}
|
|||
impl Drop for Node {
|
||||
fn drop(&mut self) {
|
||||
self.background_thread_run.store(false, Ordering::Relaxed);
|
||||
std::thread::yield_now();
|
||||
let bt = self.background_thread.replace(None);
|
||||
if bt.is_some() {
|
||||
let bt = bt.unwrap();
|
||||
|
@ -155,7 +330,7 @@ impl Drop for Node {
|
|||
}
|
||||
|
||||
unsafe {
|
||||
ztcore::ZT_Node_delete(self.capi, 0 as *mut c_void);
|
||||
ztcore::ZT_Node_delete(self.capi.get(), null_mut());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,8 @@ pub struct Peer {
|
|||
versionProto: i32,
|
||||
latency: i32,
|
||||
root: bool,
|
||||
networks: Box<[NetworkId]>,
|
||||
paths: Box<[Path]>,
|
||||
networks: Vec<NetworkId>,
|
||||
paths: Vec<Path>,
|
||||
// locator: Locator
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ impl Peer {
|
|||
}
|
||||
return Peer {
|
||||
address: Address(p.address),
|
||||
identity: Identity::new_from_capi(p.identity, false),
|
||||
identity: Identity::new_from_capi(p.identity, false).clone(), // clone to get a copy independent of 'p'
|
||||
fingerprint: Fingerprint::new_from_capi(&(*p.fingerprint)),
|
||||
versionMajor: p.versionMajor as i32,
|
||||
versionMinor: p.versionMinor as i32,
|
||||
|
@ -41,8 +41,8 @@ impl Peer {
|
|||
versionProto: p.versionProto as i32,
|
||||
latency: p.latency as i32,
|
||||
root: p.root != 0,
|
||||
networks: networks.into_boxed_slice(),
|
||||
paths: paths.into_boxed_slice()
|
||||
networks: networks,
|
||||
paths: paths
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue