Rust cleanup.

This commit is contained in:
Adam Ierymenko 2021-01-04 19:36:47 -05:00
parent 07b99a982d
commit 5ba672274c
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
10 changed files with 141 additions and 59 deletions

View file

@ -2943,6 +2943,9 @@ ZT_SDK_API int ZT_Fingerprint_fromString(ZT_Fingerprint *fp, const char *s);
#define ZT_InetAddress_cast_const_sockaddr_in6_ptr(a) ((const struct sockaddr_in6 *)(&(a)))
#define ZT_InetAddress_cast_const_sockaddr_storage_ptr(a) ((const struct sockaddr_storage *)(&(a)))
/**
* Zero the contents of an InetAddress
*/
ZT_SDK_API void ZT_InetAddress_clear(ZT_InetAddress *ia);
/**
@ -2955,22 +2958,65 @@ ZT_SDK_API void ZT_InetAddress_clear(ZT_InetAddress *ia);
*/
ZT_SDK_API char *ZT_InetAddress_toString(const ZT_InetAddress *ia, char *buf, unsigned int cap);
/**
* Parse an InetAddress in IP/port format
*
* @param ia InetAddress to fill with results
* @param str String to parse
* @return Non-zero on success, zero if IP/port is invalid
*/
ZT_SDK_API int ZT_InetAddress_fromString(ZT_InetAddress *ia, const char *str);
/**
* Set to the value of a sockaddr such as sockaddr_in or sockaddr_in6.
*
* This takes a void type pointer to a sockaddr to avoid having to include
* all the network headers within zerotier.h. It's the responsibility of
* the caller to ensure that a valid sockaddr is supplied.
*
* @param ia InetAddress to fill
* @param saddr A pointer to a sockaddr
*/
ZT_SDK_API void ZT_InetAddress_set(ZT_InetAddress *ia, const void *saddr);
/**
* Set raw IP bytes
*
* @param ia InetAddress to fill
* @param ipBytes Raw IP data
* @param ipLen Length of IP: 4 or 16 for IPv4 or IPv6
* @param port IP port
*/
ZT_SDK_API void ZT_InetAddress_setIpBytes(ZT_InetAddress *ia, const void *ipBytes, unsigned int ipLen, unsigned int port);
/**
* Set IP port
*/
ZT_SDK_API void ZT_InetAddress_setPort(ZT_InetAddress *ia, unsigned int port);
/**
* Get IP port, which can also be used as a CIDR in some use cases.
*/
ZT_SDK_API unsigned int ZT_InetAddress_port(const ZT_InetAddress *ia);
/**
* Returns non-zero if this InetAddress is nil/zero.
*/
ZT_SDK_API int ZT_InetAddress_isNil(const ZT_InetAddress *ia);
/**
* Returns non-zero if this is an IPv4 address.
*/
ZT_SDK_API int ZT_InetAddress_isV4(const ZT_InetAddress *ia);
/**
* Returns non-zero if this is an IPv6 address.
*/
ZT_SDK_API int ZT_InetAddress_isV6(const ZT_InetAddress *ia);
/**
* Classify the network scope of this IP address (local net, global, etc.)
*/
ZT_SDK_API enum ZT_InetAddress_IpScope ZT_InetAddress_ipScope(const ZT_InetAddress *ia);
/* ---------------------------------------------------------------------------------------------------------------- */

View file

@ -1,49 +1,68 @@
use crate::bindings::capi as ztcore;
use std::os::raw::c_void;
use std::slice::{from_raw_parts_mut};
use std::ptr::null_mut;
use std::slice::{from_raw_parts, from_raw_parts_mut};
use crate::bindings::capi as ztcore;
pub struct Buffer {
pub(crate) zt_core_buf: *mut u8,
pub(crate) data_size: usize
pub(crate) data_size: u32
}
impl Buffer {
pub const CAPACITY: u32 = ztcore::ZT_BUF_SIZE;
#[inline(always)]
pub fn new() -> Buffer {
let b = unsafe { ztcore::ZT_getBuffer() as *mut u8 };
if b.is_null() {
panic!("out of memory calling ZT_getBuffer()");
}
return Buffer {
zt_core_buf: b,
data_size: ztcore::ZT_BUF_SIZE
};
}
#[inline(always)]
pub fn len(&self) -> u32 {
self.data_size
}
/// 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
/// an invalid state.
#[inline(always)]
pub unsafe fn set_len(&mut self, s: u32) {
self.data_size = s;
}
}
impl AsRef<&[u8]> for Buffer {
#[inline(always)]
fn as_ref(&self) -> &[u8] {
unsafe {
let b = ztcore::ZT_getBuffer() as *mut u8;
if b.is_null() {
panic!("out of memory calling ZT_getBuffer()");
}
return Buffer {
zt_core_buf: b,
data_size: ztcore::ZT_BUF_SIZE as usize
};
return from_raw_parts(self.zt_core_buf, self.data_size as usize);
}
}
}
impl AsMut<&[u8]> for Buffer {
#[inline(always)]
pub fn get(&mut self) -> &mut [u8] {
fn as_mut(&mut self) -> &mut [u8] {
unsafe {
return from_raw_parts_mut(self.zt_core_buf, ztcore::ZT_BUF_SIZE as usize);
return from_raw_parts_mut(self.zt_core_buf, self.data_size as usize);
}
}
#[inline(always)]
pub fn set_data_size(&mut self, s: usize) {
self.data_size = s & (ztcore::ZT_BUF_SIZE - 1) as usize;
}
#[inline(always)]
pub(crate) fn mark_consumed(&mut self) {
self.zt_core_buf = null_mut();
}
}
impl Drop for Buffer {
#[inline(always)]
fn drop(&mut self) {
// ZT_freeBuffer() does nothing if passed a null pointer.
// NOTE: in node.rs std::mem::forget() is used to prevent this from
// being called on buffers that have been returned via one of the
// process_XX() methods on ZT_Node. This destructor only exists to
// return buffers that were not consumed normally.
unsafe {
ztcore::ZT_freeBuffer(self.zt_core_buf as *mut c_void);
}

View file

@ -1,5 +1,5 @@
use std::cell::Cell;
use std::ffi::{CStr, CString};
use std::ffi::CString;
use std::hash::{Hash, Hasher};
use std::mem::{MaybeUninit, zeroed};
use std::os::raw::{c_char, c_uint, c_void};

View file

@ -1,4 +1,4 @@
use std::ffi::{CStr, CString};
use std::ffi::CString;
use std::mem::MaybeUninit;
use std::os::raw::{c_char, c_int, c_void};

View file

@ -1,8 +1,9 @@
use std::ffi::CString;
use std::mem::MaybeUninit;
use std::os::raw::{c_char, c_int};
use crate::*;
use crate::bindings::capi as ztcore;
use std::os::raw::{c_char, c_int};
use std::ffi::{CStr, CString};
use std::mem::MaybeUninit;
pub struct Fingerprint {
pub address: Address,

View file

@ -1,4 +1,4 @@
use std::ffi::{CStr, CString};
use std::ffi::CString;
use std::mem::MaybeUninit;
use std::os::raw::*;

View file

@ -2,10 +2,23 @@ use std::ffi::CString;
use std::mem::{MaybeUninit, transmute, size_of};
use serde::{Deserialize, Serialize};
use num_derive::{FromPrimitive, ToPrimitive};
use crate::*;
use crate::bindings::capi as ztcore;
#[derive(FromPrimitive,ToPrimitive)]
pub enum IpScope {
None = ztcore::ZT_InetAddress_IpScope_ZT_IP_SCOPE_NONE as isize,
Multicast = ztcore::ZT_InetAddress_IpScope_ZT_IP_SCOPE_MULTICAST as isize,
Loopback = ztcore::ZT_InetAddress_IpScope_ZT_IP_SCOPE_LOOPBACK as isize,
PseudoPrivate = ztcore::ZT_InetAddress_IpScope_ZT_IP_SCOPE_PSEUDOPRIVATE as isize,
Global = ztcore::ZT_InetAddress_IpScope_ZT_IP_SCOPE_GLOBAL as isize,
LinkLocal = ztcore::ZT_InetAddress_IpScope_ZT_IP_SCOPE_LINK_LOCAL as isize,
Shared = ztcore::ZT_InetAddress_IpScope_ZT_IP_SCOPE_SHARED as isize,
Private = ztcore::ZT_InetAddress_IpScope_ZT_IP_SCOPE_PRIVATE as isize
}
/// Opaque structure that can hold an IPv4 or IPv6 address.
pub struct InetAddress {
// This must be the same size as ZT_InetAddress in zerotier.h. This is
@ -27,7 +40,7 @@ impl InetAddress {
if cs.is_ok() {
let cs = cs.unwrap();
unsafe {
if ztcore::ZT_InetAddress_fromString(a.as_mut_ptr(), cs.as_ptr()) == 0 {
if ztcore::ZT_InetAddress_fromString(a.as_capi_mut_ptr(), cs.as_ptr()) == 0 {
return None
}
}
@ -36,13 +49,13 @@ impl InetAddress {
}
#[inline(always)]
pub(crate) unsafe fn transmute_capi(a: &ztcore::ZT_InetAddress) -> &InetAddress {
pub(crate) fn transmute_capi(a: &ztcore::ZT_InetAddress) -> &InetAddress {
unsafe {
transmute(a)
}
}
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 {
Some(InetAddress {
bits: a.bits
@ -64,25 +77,31 @@ impl InetAddress {
}
#[inline(always)]
pub(crate) fn as_ptr(&self) -> *const ztcore::ZT_InetAddress {
pub(crate) fn as_capi_ptr(&self) -> *const ztcore::ZT_InetAddress {
unsafe {
transmute(self as *const InetAddress)
}
}
#[inline(always)]
pub(crate) fn as_mut_ptr(&mut self) -> *mut ztcore::ZT_InetAddress {
pub(crate) fn as_capi_mut_ptr(&mut self) -> *mut ztcore::ZT_InetAddress {
unsafe {
transmute(self as *mut InetAddress)
}
}
pub fn ip_scope(&self) -> IpScope {
unsafe {
IpScope::from_u32(ztcore::ZT_InetAddress_ipScope(self.as_capi_ptr())).unwrap_or(IpScope::None)
}
}
}
impl ToString for InetAddress {
fn to_string(&self) -> String {
let mut buf: MaybeUninit<[c_char; 128]> = MaybeUninit::uninit();
unsafe {
return cstr_to_string(ztcore::ZT_InetAddress_toString(self.as_ptr(), (*buf.as_mut_ptr()).as_mut_ptr(), 128), 128);
return cstr_to_string(ztcore::ZT_InetAddress_toString(self.as_capi_ptr(), (*buf.as_mut_ptr()).as_mut_ptr(), 128), 128);
}
}
}
@ -129,7 +148,7 @@ impl<'de> serde::Deserialize<'de> for InetAddress {
#[cfg(test)]
mod tests {
use std::mem::{size_of, zeroed};
use std::mem::size_of;
use crate::*;

View file

@ -170,9 +170,9 @@ pub fn version() -> (i32, i32, i32, i32) {
}
/// Convenience function to get the number of milliseconds since the Unix epoch.
#[inline]
#[inline(always)]
pub fn now() -> i64 {
(std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_millis() & 0x7fffffffffffffff) as i64
std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_millis() as i64
}
/// The CStr stuff is cumbersome, so this is an easier to use function to turn a C string into a String.

View file

@ -1,14 +1,6 @@
pub struct MAC(pub u64);
impl MAC {
#[inline]
pub fn new_from_string(s: &str) -> MAC {
return MAC(u64::from_str_radix(s.replace(":","").as_str(), 16).unwrap_or(0));
}
}
impl ToString for MAC {
#[inline]
fn to_string(&self) -> String {
let x = self.0;
format!("{:0>2x}:{:0>2x}:{:0>2x}:{:0>2x}:{:0>2x}:{:0>2x}",
@ -21,6 +13,12 @@ impl ToString for MAC {
}
}
impl From<&str> for MAC {
fn from(s: &str) -> MAC {
MAC(u64::from_str_radix(s.replace(":","").as_str(), 16).unwrap_or(0))
}
}
impl serde::Serialize for MAC {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
serializer.serialize_str(self.to_string().as_str())
@ -33,11 +31,11 @@ impl<'de> serde::de::Visitor<'de> for AddressVisitor {
type Value = MAC;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("Ethernet MAC address in string format")
formatter.write_str("Ethernet MAC address in string format (with or without : separators)")
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error {
Ok(MAC::new_from_string(s))
Ok(MAC::from(s))
}
}

View file

@ -197,8 +197,7 @@ impl Node {
Ok(n)
}
/// This is called periodically from internal background thread.
/// Don't call directly.
/// This is called periodically from the background service thread.
#[inline(always)]
fn process_background_tasks(&self) -> i64 {
let current_time = now();
@ -249,21 +248,21 @@ impl Node {
}
#[inline(always)]
pub fn process_wire_packet<A>(&self, local_socket: i64, remote_address: &InetAddress, data: &mut Buffer) -> ResultCode {
pub fn process_wire_packet<A>(&self, local_socket: i64, remote_address: &InetAddress, data: Buffer) -> ResultCode {
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.get(), null_mut(), current_time, local_socket, remote_address.as_ptr() as *const ztcore::ZT_InetAddress, 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);
}
let rc = unsafe { ResultCode::from_u32(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 u32).unwrap_or(ResultCode::ErrorInternalNonFatal) };
std::mem::forget(data); // prevent Buffer from being returned to ZT core twice
rc
}
#[inline(always)]
pub fn process_virtual_network_frame(&self, nwid: &NetworkId, source_mac: &MAC, dest_mac: &MAC, ethertype: u16, vlan_id: u16, data: &mut Buffer) -> ResultCode {
pub fn process_virtual_network_frame(&self, nwid: &NetworkId, source_mac: &MAC, dest_mac: &MAC, ethertype: u16, vlan_id: u16, data: Buffer) -> ResultCode {
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.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);
}
let rc = unsafe { 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) };
std::mem::forget(data); // prevent Buffer from being returned to ZT core twice
rc
}
pub fn multicast_subscribe(&self, nwid: &NetworkId, multicast_group: &MAC, multicast_adi: u32) -> ResultCode {