Remove CRL from Certificate as it really does not belong there, and Rust cleanup.

This commit is contained in:
Adam Ierymenko 2021-01-01 17:09:30 -05:00
parent 890e7f5442
commit ce40a1df8a
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
11 changed files with 205 additions and 182 deletions

View file

@ -108,12 +108,6 @@ Certificate &Certificate::operator=(const ZT_Certificate &cert)
this->maxPathLength = cert.maxPathLength;
if ((cert.crl) && (cert.crlCount > 0)) {
for (unsigned int i = 0; i < cert.crlCount; ++i) {
if (cert.crl[i])
addCRLCertificate(cert.crl[i]);
}
}
if ((cert.signature) && (cert.signatureSize > 0)) {
m_signature.assign(cert.signature, cert.signature + cert.signatureSize);
this->signature = m_signature.data();
@ -223,14 +217,6 @@ bool Certificate::setSubjectUniqueId(const uint8_t uniqueId[ZT_CERTIFICATE_UNIQU
return true;
}
void Certificate::addCRLCertificate(const uint8_t serialNo[ZT_SHA384_DIGEST_SIZE])
{
m_serials.push_front(SHA384Hash(serialNo));
m_crl.push_back(m_serials.front().bytes());
this->crl = m_crl.data();
this->crlCount = (unsigned int)m_crl.size();
}
Vector< uint8_t > Certificate::encode(const bool omitSignature) const
{
char tmp[32];
@ -285,14 +271,6 @@ Vector< uint8_t > Certificate::encode(const bool omitSignature) const
if ((this->extendedAttributes) && (this->extendedAttributesSize > 0))
d["x"].assign(this->extendedAttributes, this->extendedAttributes + this->extendedAttributesSize);
if ((this->crl) && (this->crlCount > 0)) {
d.add("r$", (uint64_t)this->crlCount);
for (unsigned int i = 0; i < this->crlCount; ++i) {
if (this->crl[i])
d[Dictionary::arraySubscript(tmp, sizeof(tmp), "r$", i)].assign(this->crl[i], this->crl[i] + ZT_SHA384_DIGEST_SIZE);
}
}
if ((!omitSignature) && (this->signature) && (this->signatureSize > 0))
d["S"].assign(this->signature, this->signature + this->signatureSize);
@ -423,14 +401,6 @@ bool Certificate::decode(const void *const data, const unsigned int len)
this->extendedAttributesSize = (unsigned int)m_extendedAttributes.size();
}
cnt = (unsigned int)d.getUI("r$");
for (unsigned int i = 0; i < cnt; ++i) {
const Vector< uint8_t > &cr = d[Dictionary::arraySubscript(tmp, sizeof(tmp), "r$", i)];
if (cr.size() != ZT_SHA384_DIGEST_SIZE)
return false;
this->addCRLCertificate(cr.data());
}
m_signature = d["S"];
if (!m_signature.empty()) {
this->signature = m_signature.data();
@ -588,7 +558,6 @@ void Certificate::m_clear()
m_extendedAttributes.clear();
m_subjectUniqueId.clear();
m_subjectUniqueIdProofSignature.clear();
m_crl.clear();
m_signature.clear();
}

View file

@ -125,13 +125,6 @@ public:
*/
bool setSubjectUniqueId(const uint8_t uniqueId[ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_SIZE], const uint8_t uniqueIdPrivate[ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_PRIVATE_SIZE]);
/**
* Add a serial number to the CRL list
*
* @param serialNo Serial number of certificate to revoke
*/
void addCRLCertificate(const uint8_t serialNo[ZT_SHA384_DIGEST_SIZE]);
/**
* Marshal this certificate in binary form
*
@ -236,7 +229,6 @@ private:
Vector< uint8_t > m_extendedAttributes;
Vector< uint8_t > m_subjectUniqueId;
Vector< uint8_t > m_subjectUniqueIdProofSignature;
Vector< const uint8_t * > m_crl;
Vector< uint8_t > m_signature;
std::atomic< int > __refCount;

View file

@ -601,16 +601,6 @@ typedef struct
*/
unsigned int maxPathLength;
/**
* List of certificate serial numbers being revoked.
*/
const uint8_t *const *crl;
/**
* Number of 48-byte serial numbers in crl list.
*/
unsigned int crlCount;
/**
* Signature by issuer (algorithm determined by identity type).
*/

View file

@ -1,5 +1,6 @@
use std::cell::Cell;
use std::ffi::{CStr, CString};
use std::hash::{Hash, Hasher};
use std::mem::{MaybeUninit, zeroed};
use std::os::raw::{c_char, c_uint, c_void};
use std::ptr::{copy_nonoverlapping, null, null_mut};
@ -48,6 +49,7 @@ impl CertificateSerialNo {
}
impl From<&[u8; 48]> for CertificateSerialNo {
#[inline(always)]
fn from(a: &[u8; 48]) -> CertificateSerialNo {
CertificateSerialNo(*a)
}
@ -65,7 +67,15 @@ impl From<&[u8]> for CertificateSerialNo {
}
}
impl Hash for CertificateSerialNo {
#[inline(always)]
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}
impl ToString for CertificateSerialNo {
#[inline(always)]
fn to_string(&self) -> String {
hex::encode(self.0)
}
@ -162,7 +172,8 @@ impl<'de> serde::Deserialize<'de> for CertificateUniqueIdType {
pub struct CertificateSubjectUniqueIdSecret {
pub public: Vec<u8>,
pub private: Vec<u8>,
pub type_: CertificateUniqueIdType,
#[serde(rename = "type")]
pub type_: CertificateUniqueIdType
}
const CERTIFICATE_UNIQUE_ID_CREATE_BUF_SIZE: usize = 128;
@ -227,36 +238,56 @@ impl ToString for CertificateError {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[allow(non_snake_case)]
#[derive(Serialize, Deserialize)]
pub struct CertificateName {
pub serialNo: String,
pub commonName: String,
#[serde(rename = "serialNo")]
pub serial_no: String,
#[serde(rename = "commonName")]
pub common_name: String,
pub country: String,
pub organization: String,
pub unit: String,
pub locality: String,
pub province: String,
pub streetAddress: String,
pub postalCode: String,
#[serde(rename = "streetAddress")]
pub street_address: String,
#[serde(rename = "postalCode")]
pub postal_code: String,
pub email: String,
pub url: String,
pub host: String,
}
impl CertificateName {
pub fn new() -> CertificateName {
CertificateName {
serial_no: String::new(),
common_name: String::new(),
country: String::new(),
organization: String::new(),
unit: String::new(),
locality: String::new(),
province: String::new(),
street_address: String::new(),
postal_code: String::new(),
email: String::new(),
url: String::new(),
host: String::new()
}
}
pub(crate) unsafe fn new_from_capi(cn: &ztcore::ZT_Certificate_Name) -> CertificateName {
unsafe {
return CertificateName {
serialNo: cstr_to_string(cn.serialNo.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1),
commonName: cstr_to_string(cn.commonName.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),
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),
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),
province: cstr_to_string(cn.province.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1),
streetAddress: cstr_to_string(cn.streetAddress.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1),
postalCode: cstr_to_string(cn.postalCode.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),
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)
@ -282,15 +313,15 @@ impl CertificateName {
pub(crate) unsafe fn to_capi(&self) -> ztcore::ZT_Certificate_Name {
unsafe {
let mut cn: ztcore::ZT_Certificate_Name = zeroed();
Self::str_to_cert_cstr(&self.serialNo, &mut cn.serialNo);
Self::str_to_cert_cstr(&self.commonName, &mut cn.commonName);
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.country, &mut cn.country);
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.locality, &mut cn.locality);
Self::str_to_cert_cstr(&self.province, &mut cn.province);
Self::str_to_cert_cstr(&self.streetAddress, &mut cn.streetAddress);
Self::str_to_cert_cstr(&self.postalCode, &mut cn.postalCode);
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.email, &mut cn.email);
Self::str_to_cert_cstr(&self.url, &mut cn.url);
Self::str_to_cert_cstr(&self.host, &mut cn.host);
@ -364,17 +395,19 @@ implement_to_from_json!(CertificateIdentity);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[allow(non_snake_case)]
#[derive(Serialize, Deserialize)]
pub struct CertificateSubject {
pub timestamp: i64,
pub identities: Vec<CertificateIdentity>,
pub networks: Vec<CertificateNetwork>,
pub certificates: Vec<CertificateSerialNo>,
pub updateURLs: Vec<String>,
#[serde(rename = "updateURLs")]
pub update_urls: Vec<String>,
pub name: CertificateName,
pub uniqueId: Vec<u8>,
pub uniqueIdProofSignature: Vec<u8>,
#[serde(rename = "uniqueId")]
pub unique_id: Vec<u8>,
#[serde(rename = "uniqueIdProofSignature")]
pub unique_id_proof_signature: Vec<u8>,
}
pub(crate) struct CertificateSubjectCAPIContainer {
@ -387,6 +420,19 @@ pub(crate) struct CertificateSubjectCAPIContainer {
}
impl CertificateSubject {
pub fn new() -> CertificateSubject {
CertificateSubject {
timestamp: 0,
identities: Vec::new(),
networks: Vec::new(),
certificates: Vec::new(),
update_urls: Vec::new(),
name: CertificateName::new(),
unique_id: Vec::new(),
unique_id_proof_signature: Vec::new()
}
}
pub(crate) unsafe fn new_from_capi(cs: &ztcore::ZT_Certificate_Subject) -> CertificateSubject {
unsafe {
let mut identities: Vec<CertificateIdentity> = Vec::new();
@ -431,10 +477,10 @@ impl CertificateSubject {
identities: identities,
networks: networks,
certificates: certificates,
updateURLs: update_urls,
update_urls: update_urls,
name: CertificateName::new_from_capi(&cs.name),
uniqueId: Vec::from(std::slice::from_raw_parts(cs.uniqueId, cs.uniqueIdSize as usize)),
uniqueIdProofSignature: Vec::from(std::slice::from_raw_parts(cs.uniqueIdProofSignature, cs.uniqueIdProofSignatureSize as usize)),
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)),
};
}
}
@ -464,9 +510,9 @@ impl CertificateSubject {
capi_certificates.push((*i).0.as_ptr());
}
}
if !self.updateURLs.is_empty() {
capi_urls.reserve(self.updateURLs.len());
for i in self.updateURLs.iter() {
if !self.update_urls.is_empty() {
capi_urls.reserve(self.update_urls.len());
for i in self.update_urls.iter() {
let cs = CString::new((*i).as_str());
if cs.is_ok() {
capi_urls_strs.push(cs.unwrap());
@ -487,10 +533,10 @@ impl CertificateSubject {
certificateCount: capi_certificates.len() as c_uint,
updateURLCount: capi_urls.len() as c_uint,
name: unsafe { self.name.to_capi() },
uniqueId: self.uniqueId.as_ptr(),
uniqueIdProofSignature: self.uniqueIdProofSignature.as_ptr(),
uniqueIdSize: self.uniqueId.len() as c_uint,
uniqueIdProofSignatureSize: self.uniqueIdProofSignature.len() as c_uint,
uniqueId: self.unique_id.as_ptr(),
uniqueIdProofSignature: self.unique_id_proof_signature.as_ptr(),
uniqueIdSize: self.unique_id.len() as c_uint,
uniqueIdProofSignatureSize: self.unique_id_proof_signature.len() as c_uint,
},
subject_identities: capi_identities,
subject_networks: capi_networks,
@ -527,85 +573,79 @@ implement_to_from_json!(CertificateSubject);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[allow(non_snake_case)]
#[derive(Serialize, Deserialize)]
pub struct Certificate {
pub serialNo: CertificateSerialNo,
#[serde(rename = "serialNo")]
pub serial_no: CertificateSerialNo,
pub flags: u64,
pub timestamp: i64,
pub validity: [i64; 2],
pub subject: CertificateSubject,
pub issuer: Identity,
pub issuerName: CertificateName,
pub extendedAttributes: Vec<u8>,
pub maxPathLength: u32,
pub crl: Vec<CertificateSerialNo>,
pub signature: Vec<u8>,
pub issuer: Option<Identity>,
#[serde(rename = "issuerName")]
pub issuer_name: CertificateName,
#[serde(rename = "extendedAttributes")]
pub extended_attributes: Vec<u8>,
#[serde(rename = "maxPathLength")]
pub max_path_length: u32,
pub signature: Vec<u8>
}
pub(crate) struct CertificateCAPIContainer {
pub(crate) certificate: ztcore::ZT_Certificate,
certificate_crls: Vec<*const u8>,
subject_container: CertificateSubjectCAPIContainer,
}
impl Certificate {
pub fn new() -> Certificate {
Certificate {
serial_no: CertificateSerialNo::new(),
flags: 0,
timestamp: 0,
validity: [0, i64::max_value()],
subject: CertificateSubject::new(),
issuer: None,
issuer_name: CertificateName::new(),
extended_attributes: Vec::new(),
max_path_length: 0,
signature: Vec::new()
}
}
pub(crate) unsafe fn new_from_capi(c: &ztcore::ZT_Certificate) -> Certificate {
unsafe {
let mut crl: Vec<CertificateSerialNo> = Vec::new();
if !c.crl.is_null() && c.crlCount > 0 {
let ccrl: &[*const u8] = std::slice::from_raw_parts(c.crl, c.crlCount as usize);
let mut ctmp: [u8; 48] = [0; 48];
for i in ccrl.iter() {
if !(*i).is_null() {
copy_nonoverlapping(*i, ctmp.as_mut_ptr(), 48);
crl.push(CertificateSerialNo(ctmp));
}
}
}
return Certificate {
serialNo: CertificateSerialNo(c.serialNo),
serial_no: CertificateSerialNo(c.serialNo),
flags: c.flags,
timestamp: c.timestamp,
validity: c.validity,
subject: CertificateSubject::new_from_capi(&c.subject),
issuer: Identity::new_from_capi(c.issuer, false),
issuerName: CertificateName::new_from_capi(&c.issuerName),
extendedAttributes: Vec::from(std::slice::from_raw_parts(c.extendedAttributes, c.extendedAttributesSize as usize)),
maxPathLength: c.maxPathLength as u32,
crl: crl,
issuer: if c.issuer.is_null() { None } else { Some(Identity::new_from_capi(c.issuer, false)) },
issuer_name: CertificateName::new_from_capi(&c.issuerName),
extended_attributes: Vec::from(std::slice::from_raw_parts(c.extendedAttributes, c.extendedAttributesSize as usize)),
max_path_length: c.maxPathLength as u32,
signature: Vec::from(std::slice::from_raw_parts(c.signature, c.signatureSize as usize)),
};
}
}
pub(crate) unsafe fn to_capi(&self) -> CertificateCAPIContainer {
let mut capi_crls: Vec<*const u8> = Vec::new();
capi_crls.reserve(self.crl.len());
for i in self.crl.iter() {
capi_crls.push((*i).0.as_ptr());
}
let subject = unsafe { self.subject.to_capi() };
CertificateCAPIContainer {
certificate: ztcore::ZT_Certificate {
serialNo: self.serialNo.0,
serialNo: self.serial_no.0,
flags: self.flags,
timestamp: self.timestamp,
validity: self.validity,
subject: subject.subject,
issuer: self.issuer.capi,
issuerName: unsafe { self.issuerName.to_capi() },
extendedAttributes: self.extendedAttributes.as_ptr(),
extendedAttributesSize: self.extendedAttributes.len() as c_uint,
maxPathLength: self.maxPathLength as c_uint,
crl: capi_crls.as_ptr(),
crlCount: capi_crls.len() as c_uint,
issuer: if self.issuer.is_some() { self.issuer.as_ref().unwrap().capi } else { null() },
issuerName: unsafe { self.issuer_name.to_capi() },
extendedAttributes: self.extended_attributes.as_ptr(),
extendedAttributesSize: self.extended_attributes.len() as c_uint,
maxPathLength: self.max_path_length as c_uint,
signature: self.signature.as_ptr(),
signatureSize: self.signature.len() as c_uint,
},
certificate_crls: capi_crls,
subject_container: subject,
}
}
@ -669,3 +709,15 @@ impl Certificate {
implement_to_from_json!(Certificate);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[cfg(test)]
mod tests {
use crate::*;
#[test]
fn certificate_serial_no() {
let test: [u8; 48] = [1; 48];
let sn = CertificateSerialNo::from(&test[0..48]);
assert!(test.eq(&sn.0));
}
}

View file

@ -1,9 +1,25 @@
use crate::*;
use crate::bindings::capi as ztcore;
use num_traits::FromPrimitive;
use std::os::raw::{c_char, c_int};
use std::ffi::CStr;
use std::mem::MaybeUninit;
use std::os::raw::{c_char, c_int};
use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::FromPrimitive;
use crate::*;
use crate::bindings::capi as ztcore;
#[derive(FromPrimitive,ToPrimitive)]
pub enum EndpointType {
Nil = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_NIL as isize,
ZeroTier = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_ZEROTIER as isize,
Ethernet = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_ETHERNET as isize,
WifiDirect = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_WIFI_DIRECT as isize,
Bluetooth = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_BLUETOOTH as isize,
Ip = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_IP as isize,
IpUdp = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_IP_UDP as isize,
IpTcp = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_IP_TCP as isize,
IpHttp = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_IP_HTTP as isize,
}
pub struct Endpoint {
pub type_: EndpointType,
@ -11,7 +27,6 @@ pub struct Endpoint {
}
impl Endpoint {
#[inline]
pub(crate) fn new_from_capi(ep: &ztcore::ZT_Endpoint) -> Endpoint {
return Endpoint{
type_: EndpointType::from_u32(ep.type_ as u32).unwrap(),
@ -37,12 +52,12 @@ impl Endpoint {
impl ToString for Endpoint {
fn to_string(&self) -> String {
let mut buf: [u8; 1024] = [0; 1024];
unsafe {
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() {
let mut buf: MaybeUninit<[c_char; 1024]> = MaybeUninit::uninit();
if ztcore::ZT_Endpoint_toString(&(self.capi) as *const ztcore::ZT_Endpoint, (*buf.as_mut_ptr()).as_mut_ptr(), 1024).is_null() {
return String::from("(invalid)");
}
return String::from(CStr::from_bytes_with_nul(buf.as_ref()).unwrap().to_str().unwrap());
return cstr_to_string((*buf.as_ptr()).as_ptr(), 1024);
}
}
}

View file

@ -1,8 +1,11 @@
use std::ffi::CStr;
use std::mem::MaybeUninit;
use std::os::raw::*;
use num_traits::{FromPrimitive, ToPrimitive};
use crate::*;
use crate::bindings::capi as ztcore;
use std::os::raw::*;
use std::ffi::CStr;
use num_traits::{ToPrimitive, FromPrimitive};
#[derive(FromPrimitive,ToPrimitive)]
pub enum IdentityType {
@ -55,12 +58,12 @@ impl Identity {
}
fn intl_to_string(&self, include_private: bool) -> String {
let mut buf: [u8; 2048] = [0; 2048];
unsafe {
if ztcore::ZT_Identity_toString(self.capi, buf.as_mut_ptr() as *mut c_char, buf.len() as c_int, if include_private { 1 } else { 0 }).is_null() {
let mut buf: MaybeUninit<[c_char; 4096]> = MaybeUninit::uninit();
if ztcore::ZT_Identity_toString(self.capi, (*buf.as_mut_ptr()).as_mut_ptr(), 4096, if include_private { 1 } else { 0 }).is_null() {
return String::from("(invalid)");
}
return String::from(CStr::from_bytes_with_nul(buf.as_ref()).unwrap().to_str().unwrap());
return cstr_to_string((*buf.as_ptr()).as_ptr(), 4096);
}
}

View file

@ -23,13 +23,13 @@ use bindings::capi as ztcore;
pub use identity::*;
pub use address::Address;
pub use fingerprint::Fingerprint;
pub use endpoint::Endpoint;
pub use endpoint::*;
pub use certificate::*;
pub use networkid::NetworkId;
pub use locator::Locator;
pub use locator::*;
pub use path::Path;
pub use peer::Peer;
pub use node::Node;
pub use node::*;
pub use mac::MAC;
pub use buffer::Buffer;
pub use portableatomici64::PortableAtomicI64;
@ -72,19 +72,6 @@ pub enum CredentialType {
Revocation = ztcore::ZT_CredentialType_ZT_CREDENTIAL_TYPE_REVOCATION as isize,
}
#[derive(FromPrimitive,ToPrimitive)]
pub enum EndpointType {
Nil = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_NIL as isize,
ZeroTier = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_ZEROTIER as isize,
Ethernet = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_ETHERNET as isize,
WifiDirect = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_WIFI_DIRECT as isize,
Bluetooth = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_BLUETOOTH as isize,
Ip = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_IP as isize,
IpUdp = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_IP_UDP as isize,
IpTcp = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_IP_TCP as isize,
IpHttp = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_IP_HTTP as isize,
}
#[derive(FromPrimitive,ToPrimitive)]
pub enum TraceEventType {
UnexpectedError = ztcore::ZT_TraceEventType_ZT_TRACE_UNEXPECTED_ERROR as isize,

View file

@ -20,8 +20,10 @@ const NODE_BACKGROUND_MIN_DELAY: i64 = 250;
pub struct NodeStatus {
pub address: Address,
pub identity: Identity,
pub publicIdentity: String,
pub secretIdentity: String,
#[serde(rename = "publicIdentity")]
pub public_identity: String,
#[serde(rename = "secretIdentity")]
pub secret_identity: String,
pub online: bool
}
@ -293,8 +295,8 @@ impl Node {
return NodeStatus {
address: Address(ns.address),
identity: Identity::new_from_capi(&*ns.identity, false).clone(),
publicIdentity: String::from(CStr::from_ptr(ns.publicIdentity).to_str().unwrap()),
secretIdentity: String::from(CStr::from_ptr(ns.secretIdentity).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()),
online: ns.online != 0
}
}

View file

@ -2,12 +2,13 @@ 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,
#[serde(rename = "lastSend")]
pub last_send: i64,
#[serde(rename = "lastReceive")]
pub last_receive: i64,
pub alive: bool,
pub preferred: bool
}
@ -17,8 +18,8 @@ impl Path {
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,
last_send: p.lastSend,
last_receive: p.lastReceive,
alive: p.alive != 0,
preferred: p.preferred != 0
}

View file

@ -2,21 +2,24 @@ 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: Vec<NetworkId>,
paths: Vec<Path>,
// locator: Locator
pub address: Address,
pub identity: Identity,
pub fingerprint: Fingerprint,
#[serde(rename = "versionMajor")]
pub version_major: i32,
#[serde(rename = "versionMinor")]
pub version_minor: i32,
#[serde(rename = "versionRev")]
pub version_rev: i32,
#[serde(rename = "versionProto")]
pub version_proto: i32,
pub latency: i32,
pub root: bool,
pub networks: Vec<NetworkId>,
pub paths: Vec<Path>,
pub locator: Option<Locator>
}
impl Peer {
@ -35,14 +38,15 @@ impl Peer {
address: Address(p.address),
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,
versionRev: p.versionRev as i32,
versionProto: p.versionProto as i32,
version_major: p.versionMajor as i32,
version_minor: p.versionMinor as i32,
version_rev: p.versionRev as i32,
version_proto: p.versionProto as i32,
latency: p.latency as i32,
root: p.root != 0,
networks: networks,
paths: paths
paths: paths,
locator: if p.locator.is_null() { None } else { Some(Locator::new_from_capi(p.locator, false).clone() )}
}
}
}

View file

@ -83,12 +83,16 @@ pub struct VirtualNetworkConfig {
pub mac: MAC,
pub name: String,
pub status: VirtualNetworkStatus,
#[serde(rename = "type")]
pub type_: VirtualNetworkType,
pub mtu: u32,
pub bridge: bool,
pub broadcastEnabled: bool,
pub netconfRevision: u64,
pub assignedAddresses: Vec<SockAddr>,
#[serde(rename = "broadcastEnabled")]
pub broadcast_enabled: bool,
#[serde(rename = "netconfRevision")]
pub netconf_revision: u64,
#[serde(rename = "assignedAddresses")]
pub assigned_addresses: Vec<SockAddr>,
pub routes: Vec<VirtualNetworkRoute>
}
@ -97,6 +101,10 @@ const SIZEOF_SOCKADDR_IN6: ztcore::socklen_t = size_of::<ztcore::sockaddr_in6>()
/// Obtain a socket2::SockAddr from a C struct sockaddr_storage as used in the ZeroTier core.
pub(crate) fn sockaddr_from_capi(ss: &ztcore::sockaddr_storage) -> Option<SockAddr> {
// The transmute() calls in here are to work around the fact that socket2
// uses sockaddr_storage from the libc crate, while ztcore uses it as
// generated from bindgen from the system headers. It's the same thing but
// Rust's type system doesn't know that.
match ss.ss_family as u32 {
ztcore::AF_INET => { unsafe { Some(SockAddr::from_raw_parts(transmute(ss as *const ztcore::sockaddr_storage), transmute(SIZEOF_SOCKADDR_IN))) } },
ztcore::AF_INET6 => { unsafe { Some(SockAddr::from_raw_parts(transmute(ss as *const ztcore::sockaddr_storage), transmute(SIZEOF_SOCKADDR_IN6))) } },
@ -136,9 +144,9 @@ impl VirtualNetworkConfig {
type_: FromPrimitive::from_u32(vnc.type_ as u32).unwrap(),
mtu: vnc.mtu as u32,
bridge: vnc.bridge != 0,
broadcastEnabled: vnc.broadcastEnabled != 0,
netconfRevision: vnc.netconfRevision as u64,
assignedAddresses: aa,
broadcast_enabled: vnc.broadcastEnabled != 0,
netconf_revision: vnc.netconfRevision as u64,
assigned_addresses: aa,
routes: rts
}
}