We are going to do things cleaner this time, so Node will remain wholly separate from the I/O stuff and service.

This commit is contained in:
Adam Ierymenko 2021-01-05 00:07:16 -05:00
parent 5ba672274c
commit f677a7408e
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
6 changed files with 181 additions and 175 deletions

View file

@ -38,24 +38,6 @@ impl Buffer {
} }
} }
impl AsRef<&[u8]> for Buffer {
#[inline(always)]
fn as_ref(&self) -> &[u8] {
unsafe {
return from_raw_parts(self.zt_core_buf, self.data_size as usize);
}
}
}
impl AsMut<&[u8]> for Buffer {
#[inline(always)]
fn as_mut(&mut self) -> &mut [u8] {
unsafe {
return from_raw_parts_mut(self.zt_core_buf, self.data_size as usize);
}
}
}
impl Drop for Buffer { impl Drop for Buffer {
#[inline(always)] #[inline(always)]
fn drop(&mut self) { fn drop(&mut self) {

View file

@ -277,22 +277,20 @@ impl CertificateName {
} }
pub(crate) unsafe fn new_from_capi(cn: &ztcore::ZT_Certificate_Name) -> CertificateName { pub(crate) unsafe fn new_from_capi(cn: &ztcore::ZT_Certificate_Name) -> CertificateName {
unsafe { return CertificateName {
return CertificateName { serial_no: cstr_to_string(cn.serialNo.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1),
serial_no: cstr_to_string(cn.serialNo.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), common_name: cstr_to_string(cn.commonName.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1),
common_name: cstr_to_string(cn.commonName.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), country: cstr_to_string(cn.country.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1),
country: cstr_to_string(cn.country.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), organization: cstr_to_string(cn.organization.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1),
organization: cstr_to_string(cn.organization.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), unit: cstr_to_string(cn.unit.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1),
unit: cstr_to_string(cn.unit.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), locality: cstr_to_string(cn.locality.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1),
locality: cstr_to_string(cn.locality.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), province: cstr_to_string(cn.province.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1),
province: cstr_to_string(cn.province.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), street_address: cstr_to_string(cn.streetAddress.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1),
street_address: cstr_to_string(cn.streetAddress.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), postal_code: cstr_to_string(cn.postalCode.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1),
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),
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),
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) };
};
}
} }
fn str_to_cert_cstr(s: &String, cs: &mut [c_char; 128]) { fn str_to_cert_cstr(s: &String, cs: &mut [c_char; 128]) {
@ -311,22 +309,20 @@ impl CertificateName {
} }
pub(crate) unsafe fn to_capi(&self) -> ztcore::ZT_Certificate_Name { pub(crate) unsafe fn to_capi(&self) -> ztcore::ZT_Certificate_Name {
unsafe { let mut cn: ztcore::ZT_Certificate_Name = zeroed();
let mut cn: ztcore::ZT_Certificate_Name = zeroed(); Self::str_to_cert_cstr(&self.serial_no, &mut cn.serialNo);
Self::str_to_cert_cstr(&self.serial_no, &mut cn.serialNo); Self::str_to_cert_cstr(&self.common_name, &mut cn.commonName);
Self::str_to_cert_cstr(&self.common_name, &mut cn.commonName); Self::str_to_cert_cstr(&self.country, &mut cn.country);
Self::str_to_cert_cstr(&self.country, &mut cn.country); Self::str_to_cert_cstr(&self.organization, &mut cn.organization);
Self::str_to_cert_cstr(&self.organization, &mut cn.organization); Self::str_to_cert_cstr(&self.unit, &mut cn.unit);
Self::str_to_cert_cstr(&self.unit, &mut cn.unit); Self::str_to_cert_cstr(&self.locality, &mut cn.locality);
Self::str_to_cert_cstr(&self.locality, &mut cn.locality); Self::str_to_cert_cstr(&self.province, &mut cn.province);
Self::str_to_cert_cstr(&self.province, &mut cn.province); Self::str_to_cert_cstr(&self.street_address, &mut cn.streetAddress);
Self::str_to_cert_cstr(&self.street_address, &mut cn.streetAddress); Self::str_to_cert_cstr(&self.postal_code, &mut cn.postalCode);
Self::str_to_cert_cstr(&self.postal_code, &mut cn.postalCode); Self::str_to_cert_cstr(&self.email, &mut cn.email);
Self::str_to_cert_cstr(&self.email, &mut cn.email); Self::str_to_cert_cstr(&self.url, &mut cn.url);
Self::str_to_cert_cstr(&self.url, &mut cn.url); Self::str_to_cert_cstr(&self.host, &mut cn.host);
Self::str_to_cert_cstr(&self.host, &mut cn.host); return cn;
return cn;
}
} }
} }
@ -434,55 +430,53 @@ impl CertificateSubject {
} }
pub(crate) unsafe fn new_from_capi(cs: &ztcore::ZT_Certificate_Subject) -> CertificateSubject { pub(crate) unsafe fn new_from_capi(cs: &ztcore::ZT_Certificate_Subject) -> CertificateSubject {
unsafe { let mut identities: Vec<CertificateIdentity> = Vec::new();
let mut identities: Vec<CertificateIdentity> = Vec::new(); if !cs.identities.is_null() && cs.identityCount > 0 {
if !cs.identities.is_null() && cs.identityCount > 0 { let cidentities: &[ztcore::ZT_Certificate_Identity] = std::slice::from_raw_parts(cs.identities, cs.identityCount as usize);
let cidentities: &[ztcore::ZT_Certificate_Identity] = std::slice::from_raw_parts(cs.identities, cs.identityCount as usize); for i in cidentities.iter() {
for i in cidentities.iter() { let ci = CertificateIdentity::new_from_capi(i);
let ci = CertificateIdentity::new_from_capi(i); if ci.is_some() {
if ci.is_some() { identities.push(ci.unwrap());
identities.push(ci.unwrap());
}
} }
} }
let mut networks: Vec<CertificateNetwork> = Vec::new();
if !cs.networks.is_null() && cs.networkCount > 0 {
let cnetworks: &[ztcore::ZT_Certificate_Network] = std::slice::from_raw_parts(cs.networks, cs.networkCount as usize);
for i in cnetworks.iter() {
networks.push(CertificateNetwork::new_from_capi(i));
}
}
let mut certificates: Vec<CertificateSerialNo> = Vec::new();
if !cs.certificates.is_null() && cs.certificateCount > 0 {
let ccertificates: &[*const u8] = std::slice::from_raw_parts(cs.certificates, cs.certificateCount as usize);
let mut ctmp: [u8; 48] = [0; 48];
for i in ccertificates.iter() {
copy_nonoverlapping(*i, ctmp.as_mut_ptr(), 48);
certificates.push(CertificateSerialNo(ctmp));
}
}
let mut update_urls: Vec<String> = Vec::new();
if !cs.updateURLs.is_null() && cs.updateURLCount > 0 {
let cupdate_urls: &[*const c_char] = std::slice::from_raw_parts(cs.updateURLs, cs.updateURLCount as usize);
for i in cupdate_urls.iter() {
update_urls.push(cstr_to_string(*i, CERTIFICATE_MAX_STRING_LENGTH - 1));
}
}
return CertificateSubject {
timestamp: cs.timestamp,
identities: identities,
networks: networks,
certificates: certificates,
update_urls: update_urls,
name: CertificateName::new_from_capi(&cs.name),
unique_id: Vec::from(std::slice::from_raw_parts(cs.uniqueId, cs.uniqueIdSize as usize)),
unique_id_proof_signature: Vec::from(std::slice::from_raw_parts(cs.uniqueIdProofSignature, cs.uniqueIdProofSignatureSize as usize)),
};
} }
let mut networks: Vec<CertificateNetwork> = Vec::new();
if !cs.networks.is_null() && cs.networkCount > 0 {
let cnetworks: &[ztcore::ZT_Certificate_Network] = std::slice::from_raw_parts(cs.networks, cs.networkCount as usize);
for i in cnetworks.iter() {
networks.push(CertificateNetwork::new_from_capi(i));
}
}
let mut certificates: Vec<CertificateSerialNo> = Vec::new();
if !cs.certificates.is_null() && cs.certificateCount > 0 {
let ccertificates: &[*const u8] = std::slice::from_raw_parts(cs.certificates, cs.certificateCount as usize);
let mut ctmp: [u8; 48] = [0; 48];
for i in ccertificates.iter() {
copy_nonoverlapping(*i, ctmp.as_mut_ptr(), 48);
certificates.push(CertificateSerialNo(ctmp));
}
}
let mut update_urls: Vec<String> = Vec::new();
if !cs.updateURLs.is_null() && cs.updateURLCount > 0 {
let cupdate_urls: &[*const c_char] = std::slice::from_raw_parts(cs.updateURLs, cs.updateURLCount as usize);
for i in cupdate_urls.iter() {
update_urls.push(cstr_to_string(*i, CERTIFICATE_MAX_STRING_LENGTH - 1));
}
}
return CertificateSubject {
timestamp: cs.timestamp,
identities: identities,
networks: networks,
certificates: certificates,
update_urls: update_urls,
name: CertificateName::new_from_capi(&cs.name),
unique_id: Vec::from(std::slice::from_raw_parts(cs.uniqueId, cs.uniqueIdSize as usize)),
unique_id_proof_signature: Vec::from(std::slice::from_raw_parts(cs.uniqueIdProofSignature, cs.uniqueIdProofSignatureSize as usize)),
};
} }
pub(crate) unsafe fn to_capi(&self) -> CertificateSubjectCAPIContainer { pub(crate) unsafe fn to_capi(&self) -> CertificateSubjectCAPIContainer {
@ -495,7 +489,7 @@ impl CertificateSubject {
if !self.identities.is_empty() { if !self.identities.is_empty() {
capi_identities.reserve(self.identities.len()); capi_identities.reserve(self.identities.len());
for i in self.identities.iter() { for i in self.identities.iter() {
capi_identities.push(unsafe { (*i).to_capi() }); capi_identities.push((*i).to_capi());
} }
} }
if !self.networks.is_empty() { if !self.networks.is_empty() {
@ -532,7 +526,7 @@ impl CertificateSubject {
networkCount: capi_networks.len() as c_uint, networkCount: capi_networks.len() as c_uint,
certificateCount: capi_certificates.len() as c_uint, certificateCount: capi_certificates.len() as c_uint,
updateURLCount: capi_urls.len() as c_uint, updateURLCount: capi_urls.len() as c_uint,
name: unsafe { self.name.to_capi() }, name: self.name.to_capi(),
uniqueId: self.unique_id.as_ptr(), uniqueId: self.unique_id.as_ptr(),
uniqueIdProofSignature: self.unique_id_proof_signature.as_ptr(), uniqueIdProofSignature: self.unique_id_proof_signature.as_ptr(),
uniqueIdSize: self.unique_id.len() as c_uint, uniqueIdSize: self.unique_id.len() as c_uint,
@ -613,24 +607,22 @@ impl Certificate {
} }
pub(crate) unsafe fn new_from_capi(c: &ztcore::ZT_Certificate) -> Certificate { pub(crate) unsafe fn new_from_capi(c: &ztcore::ZT_Certificate) -> Certificate {
unsafe { return Certificate {
return Certificate { serial_no: CertificateSerialNo(c.serialNo),
serial_no: CertificateSerialNo(c.serialNo), flags: c.flags,
flags: c.flags, timestamp: c.timestamp,
timestamp: c.timestamp, validity: c.validity,
validity: c.validity, subject: CertificateSubject::new_from_capi(&c.subject),
subject: CertificateSubject::new_from_capi(&c.subject), issuer: if c.issuer.is_null() { None } else { Some(Identity::new_from_capi(c.issuer, false)) },
issuer: if c.issuer.is_null() { None } else { Some(Identity::new_from_capi(c.issuer, false)) }, issuer_name: CertificateName::new_from_capi(&c.issuerName),
issuer_name: CertificateName::new_from_capi(&c.issuerName), extended_attributes: Vec::from(std::slice::from_raw_parts(c.extendedAttributes, c.extendedAttributesSize as usize)),
extended_attributes: Vec::from(std::slice::from_raw_parts(c.extendedAttributes, c.extendedAttributesSize as usize)), max_path_length: c.maxPathLength as u32,
max_path_length: c.maxPathLength as u32, signature: Vec::from(std::slice::from_raw_parts(c.signature, c.signatureSize as usize)),
signature: Vec::from(std::slice::from_raw_parts(c.signature, c.signatureSize as usize)), };
};
}
} }
pub(crate) unsafe fn to_capi(&self) -> CertificateCAPIContainer { pub(crate) unsafe fn to_capi(&self) -> CertificateCAPIContainer {
let subject = unsafe { self.subject.to_capi() }; let subject = self.subject.to_capi();
CertificateCAPIContainer { CertificateCAPIContainer {
certificate: ztcore::ZT_Certificate { certificate: ztcore::ZT_Certificate {
serialNo: self.serial_no.0, serialNo: self.serial_no.0,
@ -639,7 +631,7 @@ impl Certificate {
validity: self.validity, validity: self.validity,
subject: subject.subject, subject: subject.subject,
issuer: if self.issuer.is_some() { self.issuer.as_ref().unwrap().capi } else { null() }, issuer: if self.issuer.is_some() { self.issuer.as_ref().unwrap().capi } else { null() },
issuerName: unsafe { self.issuer_name.to_capi() }, issuerName: self.issuer_name.to_capi(),
extendedAttributes: self.extended_attributes.as_ptr(), extendedAttributes: self.extended_attributes.as_ptr(),
extendedAttributesSize: self.extended_attributes.len() as c_uint, extendedAttributesSize: self.extended_attributes.len() as c_uint,
maxPathLength: self.max_path_length as c_uint, maxPathLength: self.max_path_length as c_uint,

View file

@ -3,6 +3,7 @@ use std::mem::{MaybeUninit, transmute, size_of};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use num_derive::{FromPrimitive, ToPrimitive}; use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::FromPrimitive;
use crate::*; use crate::*;
use crate::bindings::capi as ztcore; use crate::bindings::capi as ztcore;
@ -92,7 +93,7 @@ impl InetAddress {
pub fn ip_scope(&self) -> IpScope { pub fn ip_scope(&self) -> IpScope {
unsafe { unsafe {
IpScope::from_u32(ztcore::ZT_InetAddress_ipScope(self.as_capi_ptr())).unwrap_or(IpScope::None) IpScope::from_u32(ztcore::ZT_InetAddress_ipScope(self.as_capi_ptr()) as u32).unwrap_or(IpScope::None)
} }
} }
} }

View file

@ -183,12 +183,12 @@ pub unsafe fn cstr_to_string(cstr: *const c_char, max_len: isize) -> String {
if !cstr.is_null() { if !cstr.is_null() {
let mut cstr_len: isize = 0; let mut cstr_len: isize = 0;
while max_len < 0 || cstr_len < max_len { while max_len < 0 || cstr_len < max_len {
if (unsafe { *cstr.offset(cstr_len) } == 0) { if (*cstr.offset(cstr_len) == 0) {
break; break;
} }
cstr_len += 1; cstr_len += 1;
} }
return String::from(std::str::from_utf8(unsafe { std::slice::from_raw_parts(cstr as *const u8, cstr_len as usize) }).unwrap_or("")); return String::from(std::str::from_utf8(std::slice::from_raw_parts(cstr as *const u8, cstr_len as usize)).unwrap_or(""));
} }
String::new() String::new()
} }

View file

@ -8,12 +8,11 @@ use std::sync::*;
use std::sync::atomic::*; use std::sync::atomic::*;
use std::time::Duration; use std::time::Duration;
use serde::{Deserialize, Serialize};
use num_traits::FromPrimitive; use num_traits::FromPrimitive;
use serde::{Deserialize, Serialize};
use crate::*; use crate::*;
use crate::bindings::capi as ztcore; use crate::bindings::capi as ztcore;
use crate::inetaddress::InetAddress;
const NODE_BACKGROUND_MIN_DELAY: i64 = 250; const NODE_BACKGROUND_MIN_DELAY: i64 = 250;
@ -25,12 +24,23 @@ pub struct NodeStatus {
pub public_identity: String, pub public_identity: String,
#[serde(rename = "secretIdentity")] #[serde(rename = "secretIdentity")]
pub secret_identity: String, pub secret_identity: String,
pub online: bool pub online: bool,
} }
pub struct Node { pub trait NodeEventHandler {
fn virtual_network_config(&self);
fn virtual_network_frame(&self);
fn event(&self);
fn state_put(&self);
fn state_get(&self);
fn wire_packet_send(&self);
fn path_check(&self);
fn path_lookup(&self);
}
pub struct Node<T: NodeEventHandler + 'static> {
event_handler: Arc<T>,
capi: Cell<*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: Cell<Option<std::thread::JoinHandle<()>>>,
background_thread_run: Arc<AtomicBool>, background_thread_run: Arc<AtomicBool>,
now: PortableAtomicI64, now: PortableAtomicI64,
@ -38,16 +48,16 @@ pub struct Node {
macro_rules! node_from_raw_ptr { macro_rules! node_from_raw_ptr {
($uptr:ident) => { ($uptr:ident) => {
{ unsafe {
let ntmp = unsafe { (*($uptr as *mut Weak<Node>)).upgrade() }; let ntmp: *const Node<T> = transmute($uptr);
if ntmp.is_none() { return; } let ntmp: &Node<T> = &*ntmp;
ntmp.unwrap() ntmp
} }
} }
} }
#[no_mangle] #[no_mangle]
extern "C" fn zt_virtual_network_config_function( extern "C" fn zt_virtual_network_config_function<T: NodeEventHandler + 'static>(
capi: *mut ztcore::ZT_Node, capi: *mut ztcore::ZT_Node,
uptr: *mut c_void, uptr: *mut c_void,
tptr: *mut c_void, tptr: *mut c_void,
@ -56,11 +66,12 @@ extern "C" fn zt_virtual_network_config_function(
op: ztcore::ZT_VirtualNetworkConfigOperation, op: ztcore::ZT_VirtualNetworkConfigOperation,
conf: *const ztcore::ZT_VirtualNetworkConfig, conf: *const ztcore::ZT_VirtualNetworkConfig,
) { ) {
//let n = node_from_raw_ptr!(uptr); let n = node_from_raw_ptr!(uptr);
n.event_handler.virtual_network_config();
} }
#[no_mangle] #[no_mangle]
extern "C" fn zt_virtual_network_frame_function( extern "C" fn zt_virtual_network_frame_function<T: NodeEventHandler + 'static>(
capi: *mut ztcore::ZT_Node, capi: *mut ztcore::ZT_Node,
uptr: *mut c_void, uptr: *mut c_void,
tptr: *mut c_void, tptr: *mut c_void,
@ -72,41 +83,53 @@ extern "C" fn zt_virtual_network_frame_function(
vlan_id: c_uint, vlan_id: c_uint,
data: *const c_void, data: *const c_void,
data_size: c_uint, data_size: c_uint,
) {} ) {
let n = node_from_raw_ptr!(uptr);
n.event_handler.virtual_network_frame();
}
#[no_mangle] #[no_mangle]
extern "C" fn zt_event_callback( extern "C" fn zt_event_callback<T: NodeEventHandler + 'static>(
capi: *mut ztcore::ZT_Node, capi: *mut ztcore::ZT_Node,
uptr: *mut c_void, uptr: *mut c_void,
tptr: *mut c_void, tptr: *mut c_void,
ev: ztcore::ZT_Event, ev: ztcore::ZT_Event,
data: *const c_void, data: *const c_void,
) {} ) {
let n = node_from_raw_ptr!(uptr);
n.event_handler.event();
}
#[no_mangle] #[no_mangle]
extern "C" fn zt_state_put_function( extern "C" fn zt_state_put_function<T: NodeEventHandler + 'static>(
capi: *mut ztcore::ZT_Node, capi: *mut ztcore::ZT_Node,
uptr: *mut c_void, uptr: *mut c_void,
tptr: *mut c_void, tptr: *mut c_void,
obj_type: ztcore::ZT_StateObjectType, obj_type: ztcore::ZT_StateObjectType,
obj_id: *const u64, obj_id: *const u64,
obj_data: *const c_void, obj_data: *const c_void,
obj_data_len: c_int obj_data_len: c_int,
) {} ) {
let n = node_from_raw_ptr!(uptr);
n.event_handler.state_put();
}
#[no_mangle] #[no_mangle]
extern "C" fn zt_state_get_function( extern "C" fn zt_state_get_function<T: NodeEventHandler + 'static>(
capi: *mut ztcore::ZT_Node, capi: *mut ztcore::ZT_Node,
uptr: *mut c_void, uptr: *mut c_void,
tptr: *mut c_void, tptr: *mut c_void,
obj_type: ztcore::ZT_StateObjectType, obj_type: ztcore::ZT_StateObjectType,
obj_id: *const u64, obj_id: *const u64,
obj_data: *mut *mut c_void, obj_data: *mut *mut c_void,
obj_data_free_function: *mut *mut c_void obj_data_free_function: *mut *mut c_void,
) {} ) {
let n = node_from_raw_ptr!(uptr);
n.event_handler.state_get();
}
#[no_mangle] #[no_mangle]
extern "C" fn zt_wire_packet_send_function( extern "C" fn zt_wire_packet_send_function<T: NodeEventHandler + 'static>(
capi: *mut ztcore::ZT_Node, capi: *mut ztcore::ZT_Node,
uptr: *mut c_void, uptr: *mut c_void,
tptr: *mut c_void, tptr: *mut c_void,
@ -114,60 +137,67 @@ extern "C" fn zt_wire_packet_send_function(
sock_addr: *const ztcore::ZT_InetAddress, sock_addr: *const ztcore::ZT_InetAddress,
data: *const c_void, data: *const c_void,
data_size: c_uint, data_size: c_uint,
packet_ttl: c_uint packet_ttl: c_uint,
) {} ) {
let n = node_from_raw_ptr!(uptr);
n.event_handler.wire_packet_send();
}
#[no_mangle] #[no_mangle]
extern "C" fn zt_path_check_function( extern "C" fn zt_path_check_function<T: NodeEventHandler + 'static>(
capi: *mut ztcore::ZT_Node, capi: *mut ztcore::ZT_Node,
uptr: *mut c_void, uptr: *mut c_void,
tptr: *mut c_void, tptr: *mut c_void,
address: u64, address: u64,
identity: *const ztcore::ZT_Identity, identity: *const ztcore::ZT_Identity,
local_socket: i64, local_socket: i64,
sock_addr: *const ztcore::ZT_InetAddress sock_addr: *const ztcore::ZT_InetAddress,
) {} ) {
let n = node_from_raw_ptr!(uptr);
n.event_handler.path_check();
}
#[no_mangle] #[no_mangle]
extern "C" fn zt_path_lookup_function( extern "C" fn zt_path_lookup_function<T: NodeEventHandler + 'static>(
capi: *mut ztcore::ZT_Node, capi: *mut ztcore::ZT_Node,
uptr: *mut c_void, uptr: *mut c_void,
tptr: *mut c_void, tptr: *mut c_void,
address: u64, address: u64,
identity: *const ztcore::ZT_Identity, identity: *const ztcore::ZT_Identity,
sock_family: c_int, sock_family: c_int,
sock_addr: *mut ztcore::ZT_InetAddress sock_addr: *mut ztcore::ZT_InetAddress,
) {} ) {
let n = node_from_raw_ptr!(uptr);
n.event_handler.path_lookup();
}
impl Node { impl<T: NodeEventHandler + 'static> Node<T> {
pub fn new(base_dir: &std::path::Path) -> Result<Arc<Node>, ResultCode> { /// Create a new Node with a given event handler.
pub fn new(event_handler: Arc<T>) -> Result<Arc<Node<T>>, ResultCode> {
let now = now(); let now = now();
let n = Arc::new(Node { let n = Arc::new(Node {
event_handler: event_handler.clone(),
capi: Cell::new(null_mut()), capi: Cell::new(null_mut()),
node_uptr: Cell::new(Weak::new()),
background_thread: Cell::new(None), background_thread: Cell::new(None),
background_thread_run: Arc::new(AtomicBool::new(true)), 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(); let mut capi: *mut ztcore::ZT_Node = null_mut();
unsafe { unsafe {
let callbacks = ztcore::ZT_Node_Callbacks { let callbacks = ztcore::ZT_Node_Callbacks {
statePutFunction: transmute(zt_state_put_function as *const ()), statePutFunction: transmute(zt_state_put_function::<T> as *const ()),
stateGetFunction: transmute(zt_state_get_function as *const ()), stateGetFunction: transmute(zt_state_get_function::<T> as *const ()),
wirePacketSendFunction: transmute(zt_wire_packet_send_function as *const ()), wirePacketSendFunction: transmute(zt_wire_packet_send_function::<T> as *const ()),
virtualNetworkFrameFunction: transmute(zt_virtual_network_frame_function as *const ()), virtualNetworkFrameFunction: transmute(zt_virtual_network_frame_function::<T> as *const ()),
virtualNetworkConfigFunction: transmute(zt_virtual_network_config_function as *const ()), virtualNetworkConfigFunction: transmute(zt_virtual_network_config_function::<T> as *const ()),
eventCallback: transmute(zt_event_callback as *const ()), eventCallback: transmute(zt_event_callback::<T> as *const ()),
pathCheckFunction: transmute(zt_path_check_function as *const ()), pathCheckFunction: transmute(zt_path_check_function::<T> as *const ()),
pathLookupFunction: transmute(zt_path_lookup_function as *const ()) pathLookupFunction: transmute(zt_path_lookup_function::<T> 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); let rc = ztcore::ZT_Node_new(&mut capi as *mut *mut ztcore::ZT_Node, transmute(Arc::as_ptr(&n)), null_mut(), &callbacks as *const ztcore::ZT_Node_Callbacks, now);
if rc != 0 { if rc != 0 {
return Err(ResultCode::from_u32(rc as u32).unwrap_or(ResultCode::FatalErrorInternal)); return Err(ResultCode::from_u32(rc as u32).unwrap_or(ResultCode::FatalErrorInternal));
} else if capi.is_null() { } else if capi.is_null() {
@ -176,6 +206,7 @@ impl Node {
} }
n.capi.replace(capi); n.capi.replace(capi);
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(500);
@ -205,12 +236,12 @@ impl Node {
let mut next_task_deadline: i64 = current_time; let mut next_task_deadline: i64 = current_time;
unsafe { unsafe {
ztcore::ZT_Node_processBackgroundTasks(self.capi.get(), 0 as *mut c_void, current_time, &mut next_task_deadline as *mut i64); ztcore::ZT_Node_processBackgroundTasks(self.capi.get(), null_mut(), current_time, &mut next_task_deadline as *mut i64);
} }
let mut next_delay = next_task_deadline - current_time; let mut next_delay = next_task_deadline - current_time;
if next_delay < 5 { if next_delay < 10 {
next_delay = 5; next_delay = 10;
} else if next_delay > NODE_BACKGROUND_MIN_DELAY { } else if next_delay > NODE_BACKGROUND_MIN_DELAY {
next_delay = NODE_BACKGROUND_MIN_DELAY; next_delay = NODE_BACKGROUND_MIN_DELAY;
} }
@ -252,7 +283,7 @@ impl Node {
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_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) }; 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 std::mem::forget(data); // prevent Buffer from being returned to ZT core twice, see comment in drop() in buffer.rs
rc rc
} }
@ -261,7 +292,7 @@ impl Node {
let current_time = self.now.get(); let current_time = self.now.get();
let mut next_tick_deadline: i64 = current_time; let mut next_tick_deadline: i64 = current_time;
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) }; 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 std::mem::forget(data); // prevent Buffer from being returned to ZT core twice, see comment in drop() in buffer.rs
rc rc
} }
@ -297,8 +328,8 @@ impl Node {
identity: Identity::new_from_capi(&*ns.identity, false).clone(), identity: Identity::new_from_capi(&*ns.identity, false).clone(),
public_identity: String::from(CStr::from_ptr(ns.publicIdentity).to_str().unwrap()), public_identity: String::from(CStr::from_ptr(ns.publicIdentity).to_str().unwrap()),
secret_identity: String::from(CStr::from_ptr(ns.secretIdentity).to_str().unwrap()), secret_identity: String::from(CStr::from_ptr(ns.secretIdentity).to_str().unwrap()),
online: ns.online != 0 online: ns.online != 0,
} };
} }
} }
@ -351,11 +382,11 @@ impl Node {
} }
} }
unsafe impl Sync for Node {} unsafe impl<T: NodeEventHandler + 'static> Sync for Node<T> {}
unsafe impl Send for Node {} unsafe impl<T: NodeEventHandler + 'static> Send for Node<T> {}
impl Drop for Node { impl<T: NodeEventHandler + 'static> Drop for Node<T> {
fn drop(&mut self) { fn drop(&mut self) {
self.background_thread_run.store(false, Ordering::Relaxed); self.background_thread_run.store(false, Ordering::Relaxed);
let bt = self.background_thread.replace(None); let bt = self.background_thread.replace(None);

View file

@ -219,7 +219,7 @@ impl VirtualNetworkConfig {
let mut aa: Vec<InetAddress> = Vec::new(); let mut aa: Vec<InetAddress> = Vec::new();
let saptr = vnc.assignedAddresses.as_ptr(); let saptr = vnc.assignedAddresses.as_ptr();
for i in 0..vnc.assignedAddressCount as isize { for i in 0..vnc.assignedAddressCount as isize {
let a = InetAddress::new_from_capi(unsafe { *saptr.offset(i) }); let a = InetAddress::new_from_capi(unsafe { &*saptr.offset(i) });
if a.is_some() { if a.is_some() {
aa.push(a.unwrap()); aa.push(a.unwrap());
} }
@ -230,8 +230,8 @@ impl VirtualNetworkConfig {
for i in 0..vnc.routeCount as isize { for i in 0..vnc.routeCount as isize {
let r = unsafe { *rtptr.offset(i) }; let r = unsafe { *rtptr.offset(i) };
rts.push(VirtualNetworkRoute{ rts.push(VirtualNetworkRoute{
target: InetAddress::new_from_capi(r.target), target: InetAddress::new_from_capi(&r.target),
via: InetAddress::new_from_capi(r.via), via: InetAddress::new_from_capi(&r.via),
flags: r.flags, flags: r.flags,
metric: r.metric metric: r.metric
}) })