mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-26 17:03:43 +02:00
OMG Rust links! On MacOS only so far.
This commit is contained in:
parent
f677a7408e
commit
36f9dd54d9
7 changed files with 114 additions and 35 deletions
|
@ -3,6 +3,7 @@ name = "rust-zerotier-core"
|
|||
version = "0.1.0"
|
||||
authors = ["Adam Ierymenko <adam.ierymenko@zerotier.com>"]
|
||||
edition = "2018"
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
num-traits = "0.2.14"
|
||||
|
|
6
rust-zerotier-core/build.rs
Normal file
6
rust-zerotier-core/build.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
fn main() {
|
||||
let d = env!("CARGO_MANIFEST_DIR");
|
||||
println!("cargo:rustc-link-search=native={}/../build/core", d);
|
||||
println!("cargo:rustc-link-lib=static=zt_core");
|
||||
println!("cargo:rustc-link-lib=c++");
|
||||
}
|
|
@ -1,16 +1,21 @@
|
|||
pub struct Address(pub u64);
|
||||
|
||||
impl Address {
|
||||
#[inline]
|
||||
pub fn new_from_string(s: &str) -> Address {
|
||||
return Address(u64::from_str_radix(s, 16).unwrap_or(0));
|
||||
impl ToString for Address {
|
||||
fn to_string(&self) -> String {
|
||||
format!("{:0>10x}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for Address {
|
||||
#[inline]
|
||||
fn to_string(&self) -> String {
|
||||
format!("{:0>10x}", self.0)
|
||||
impl From<u64> for Address {
|
||||
#[inline(always)]
|
||||
fn from(i: u64) -> Address {
|
||||
Address(i)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for Address {
|
||||
fn from(s: &str) -> Address {
|
||||
Address(u64::from_str_radix(s, 16).unwrap_or(0))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,7 +35,7 @@ impl<'de> serde::de::Visitor<'de> for AddressVisitor {
|
|||
}
|
||||
|
||||
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error {
|
||||
Ok(Address::new_from_string(s))
|
||||
Ok(Address::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,24 @@
|
|||
use std::os::raw::c_void;
|
||||
use std::ptr::null_mut;
|
||||
use std::slice::{from_raw_parts, from_raw_parts_mut};
|
||||
use std::ptr::{slice_from_raw_parts, slice_from_raw_parts_mut};
|
||||
|
||||
use crate::bindings::capi as ztcore;
|
||||
|
||||
/// A reusable buffer for I/O to/from the ZeroTier core.
|
||||
/// The core allocates and manages a pool of these. This provides a Rust
|
||||
/// interface to that pool. ZT core buffers are used to reduce the need for
|
||||
/// memory copying by passing buffers around instead of memcpy'ing when
|
||||
/// packet data is passed into and out of the core.
|
||||
pub struct Buffer {
|
||||
pub(crate) zt_core_buf: *mut u8,
|
||||
pub(crate) data_size: u32
|
||||
}
|
||||
|
||||
impl Buffer {
|
||||
pub const CAPACITY: u32 = ztcore::ZT_BUF_SIZE;
|
||||
/// Maximum capacity of a ZeroTier reusable buffer.
|
||||
pub const CAPACITY: u32 = ztcore::ZT_BUF_SIZE as u32;
|
||||
|
||||
/// Obtain a new buffer from the core and set the size of its data to CAPACITY.
|
||||
/// The contents of the buffer are not defined.
|
||||
#[inline(always)]
|
||||
pub fn new() -> Buffer {
|
||||
let b = unsafe { ztcore::ZT_getBuffer() as *mut u8 };
|
||||
|
@ -24,6 +31,8 @@ impl Buffer {
|
|||
};
|
||||
}
|
||||
|
||||
/// Get the current size of the data held by this buffer. Initially this is
|
||||
/// equal to CAPACITY.
|
||||
#[inline(always)]
|
||||
pub fn len(&self) -> u32 {
|
||||
self.data_size
|
||||
|
@ -36,10 +45,29 @@ impl Buffer {
|
|||
pub unsafe fn set_len(&mut self, s: u32) {
|
||||
self.data_size = s;
|
||||
}
|
||||
|
||||
/// Get a slice that points to this buffer's data. This is unsafe because
|
||||
/// the returned slice will be invalid if set_len() has been called with a
|
||||
/// value higher than CAPACITY or if this has been consumed by the ZeroTier
|
||||
/// core. The latter case is handled automatically in node.rs though, so it
|
||||
/// is not something you generally have to worry about.
|
||||
#[inline(always)]
|
||||
pub unsafe fn as_mut_slice(&mut self) -> &mut [u8] {
|
||||
return &mut *slice_from_raw_parts_mut(self.zt_core_buf, self.data_size as usize);
|
||||
}
|
||||
|
||||
/// Get a slice that points to this buffer's data. This is unsafe because
|
||||
/// the returned slice will be invalid if set_len() has been called with a
|
||||
/// value higher than CAPACITY or if this has been consumed by the ZeroTier
|
||||
/// core. The latter case is handled automatically in node.rs though, so it
|
||||
/// is not something you generally have to worry about.
|
||||
#[inline(always)]
|
||||
pub unsafe fn as_slice(&mut self) -> &[u8] {
|
||||
return &*slice_from_raw_parts(self.zt_core_buf, self.data_size as usize);
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Buffer {
|
||||
#[inline(always)]
|
||||
fn drop(&mut self) {
|
||||
// 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
|
||||
|
|
|
@ -6,6 +6,7 @@ use std::os::raw::{c_char, c_uint, c_void};
|
|||
use std::ptr::{copy_nonoverlapping, null, null_mut};
|
||||
use std::sync::Mutex;
|
||||
|
||||
use num_derive::{FromPrimitive, ToPrimitive};
|
||||
use num_traits::FromPrimitive;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
@ -173,7 +174,7 @@ pub struct CertificateSubjectUniqueIdSecret {
|
|||
pub public: Vec<u8>,
|
||||
pub private: Vec<u8>,
|
||||
#[serde(rename = "type")]
|
||||
pub type_: CertificateUniqueIdType
|
||||
pub type_: CertificateUniqueIdType,
|
||||
}
|
||||
|
||||
const CERTIFICATE_UNIQUE_ID_CREATE_BUF_SIZE: usize = 128;
|
||||
|
@ -236,6 +237,49 @@ impl ToString for CertificateError {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<&str> for CertificateError {
|
||||
fn from(s: &str) -> CertificateError {
|
||||
match s.to_ascii_lowercase().as_str() {
|
||||
"havenewercert" => CertificateError::HaveNewerCert,
|
||||
"invalidformat" => CertificateError::InvalidFormat,
|
||||
"invalididentity" => CertificateError::InvalidIdentity,
|
||||
"invalidprimarysignature" => CertificateError::InvalidPrimarySignature,
|
||||
"invalidchain" => CertificateError::InvalidChain,
|
||||
"invalidcomponentsignature" => CertificateError::InvalidComponentSignature,
|
||||
"invaliduniqueidproof" => CertificateError::InvalidUniqueIdProof,
|
||||
"missingrequiredfields" => CertificateError::MissingRequiredFields,
|
||||
"outofvalidtimewindow" => CertificateError::OutOfValidTimeWindow,
|
||||
_ => CertificateError::None // also "none"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::Serialize for CertificateError {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
||||
serializer.serialize_str(self.to_string().as_str())
|
||||
}
|
||||
}
|
||||
|
||||
struct CertificateErrorVisitor;
|
||||
|
||||
impl<'de> serde::de::Visitor<'de> for CertificateErrorVisitor {
|
||||
type Value = CertificateError;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("CertificateError value in string form")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error {
|
||||
return Ok(CertificateError::from(s));
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::Deserialize<'de> for CertificateError {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
|
||||
deserializer.deserialize_str(CertificateErrorVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
|
@ -272,7 +316,7 @@ impl CertificateName {
|
|||
postal_code: String::new(),
|
||||
email: String::new(),
|
||||
url: String::new(),
|
||||
host: String::new()
|
||||
host: String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,7 +333,7 @@ impl CertificateName {
|
|||
postal_code: cstr_to_string(cn.postalCode.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1),
|
||||
email: cstr_to_string(cn.email.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1),
|
||||
url: cstr_to_string(cn.url.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1),
|
||||
host: cstr_to_string(cn.host.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1)
|
||||
host: cstr_to_string(cn.host.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -425,7 +469,7 @@ impl CertificateSubject {
|
|||
update_urls: Vec::new(),
|
||||
name: CertificateName::new(),
|
||||
unique_id: Vec::new(),
|
||||
unique_id_proof_signature: Vec::new()
|
||||
unique_id_proof_signature: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -582,7 +626,7 @@ pub struct Certificate {
|
|||
pub extended_attributes: Vec<u8>,
|
||||
#[serde(rename = "maxPathLength")]
|
||||
pub max_path_length: u32,
|
||||
pub signature: Vec<u8>
|
||||
pub signature: Vec<u8>,
|
||||
}
|
||||
|
||||
pub(crate) struct CertificateCAPIContainer {
|
||||
|
@ -602,7 +646,7 @@ impl Certificate {
|
|||
issuer_name: CertificateName::new(),
|
||||
extended_attributes: Vec::new(),
|
||||
max_path_length: 0,
|
||||
signature: Vec::new()
|
||||
signature: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -712,4 +756,11 @@ mod tests {
|
|||
let sn = CertificateSerialNo::from(&test[0..48]);
|
||||
assert!(test.eq(&sn.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generate_certificate_unique_id() {
|
||||
let uid = CertificateSubjectUniqueIdSecret::new(CertificateUniqueIdType::NistP384);
|
||||
println!("certificate unique ID public: {}", hex::encode(uid.public).as_str());
|
||||
println!("certificate unique ID private: {}", hex::encode(uid.private).as_str());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#[link(name = ":../../build/core/libzt_core.a")]
|
||||
|
||||
use std::os::raw::{c_char, c_int};
|
||||
use num_derive::{FromPrimitive, ToPrimitive};
|
||||
|
||||
|
@ -49,7 +47,7 @@ pub const DEFAULT_UDP_MTU: u32 = ztcore::ZT_DEFAULT_UDP_MTU;
|
|||
pub const MAX_UDP_MTU: u32 = ztcore::ZT_MAX_UDP_MTU;
|
||||
|
||||
#[allow(non_snake_case,non_upper_case_globals)]
|
||||
pub mod RulePacketCharacteristics {
|
||||
pub mod RulePacketCharacteristicFlags {
|
||||
pub const Inbound: u64 = crate::bindings::capi::ZT_RULE_PACKET_CHARACTERISTICS_INBOUND as u64;
|
||||
pub const Multicast: u64 = crate::bindings::capi::ZT_RULE_PACKET_CHARACTERISTICS_MULTICAST as u64;
|
||||
pub const Broadcast: u64 = crate::bindings::capi::ZT_RULE_PACKET_CHARACTERISTICS_BROADCAST as u64;
|
||||
|
@ -183,7 +181,7 @@ pub unsafe fn cstr_to_string(cstr: *const c_char, max_len: isize) -> String {
|
|||
if !cstr.is_null() {
|
||||
let mut cstr_len: isize = 0;
|
||||
while max_len < 0 || cstr_len < max_len {
|
||||
if (*cstr.offset(cstr_len) == 0) {
|
||||
if *cstr.offset(cstr_len) == 0 {
|
||||
break;
|
||||
}
|
||||
cstr_len += 1;
|
||||
|
|
|
@ -56,7 +56,6 @@ macro_rules! node_from_raw_ptr {
|
|||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn zt_virtual_network_config_function<T: NodeEventHandler + 'static>(
|
||||
capi: *mut ztcore::ZT_Node,
|
||||
uptr: *mut c_void,
|
||||
|
@ -70,7 +69,6 @@ extern "C" fn zt_virtual_network_config_function<T: NodeEventHandler + 'static>(
|
|||
n.event_handler.virtual_network_config();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn zt_virtual_network_frame_function<T: NodeEventHandler + 'static>(
|
||||
capi: *mut ztcore::ZT_Node,
|
||||
uptr: *mut c_void,
|
||||
|
@ -88,7 +86,6 @@ extern "C" fn zt_virtual_network_frame_function<T: NodeEventHandler + 'static>(
|
|||
n.event_handler.virtual_network_frame();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn zt_event_callback<T: NodeEventHandler + 'static>(
|
||||
capi: *mut ztcore::ZT_Node,
|
||||
uptr: *mut c_void,
|
||||
|
@ -100,7 +97,6 @@ extern "C" fn zt_event_callback<T: NodeEventHandler + 'static>(
|
|||
n.event_handler.event();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn zt_state_put_function<T: NodeEventHandler + 'static>(
|
||||
capi: *mut ztcore::ZT_Node,
|
||||
uptr: *mut c_void,
|
||||
|
@ -114,7 +110,6 @@ extern "C" fn zt_state_put_function<T: NodeEventHandler + 'static>(
|
|||
n.event_handler.state_put();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn zt_state_get_function<T: NodeEventHandler + 'static>(
|
||||
capi: *mut ztcore::ZT_Node,
|
||||
uptr: *mut c_void,
|
||||
|
@ -128,7 +123,6 @@ extern "C" fn zt_state_get_function<T: NodeEventHandler + 'static>(
|
|||
n.event_handler.state_get();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn zt_wire_packet_send_function<T: NodeEventHandler + 'static>(
|
||||
capi: *mut ztcore::ZT_Node,
|
||||
uptr: *mut c_void,
|
||||
|
@ -143,7 +137,6 @@ extern "C" fn zt_wire_packet_send_function<T: NodeEventHandler + 'static>(
|
|||
n.event_handler.wire_packet_send();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn zt_path_check_function<T: NodeEventHandler + 'static>(
|
||||
capi: *mut ztcore::ZT_Node,
|
||||
uptr: *mut c_void,
|
||||
|
@ -157,7 +150,6 @@ extern "C" fn zt_path_check_function<T: NodeEventHandler + 'static>(
|
|||
n.event_handler.path_check();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn zt_path_lookup_function<T: NodeEventHandler + 'static>(
|
||||
capi: *mut ztcore::ZT_Node,
|
||||
uptr: *mut c_void,
|
||||
|
@ -309,10 +301,8 @@ impl<T: NodeEventHandler + 'static> Node<T> {
|
|||
}
|
||||
|
||||
pub fn identity(&self) -> Identity {
|
||||
unsafe {
|
||||
let mut id = ztcore::ZT_Node_identity(self.capi.get());
|
||||
return Identity::new_from_capi(id, false).clone();
|
||||
}
|
||||
let id = unsafe { ztcore::ZT_Node_identity(self.capi.get()) };
|
||||
return Identity::new_from_capi(id, false).clone();
|
||||
}
|
||||
|
||||
pub fn status(&self) -> NodeStatus {
|
||||
|
|
Loading…
Add table
Reference in a new issue