diff --git a/Makefile b/Makefile index e6159e30a..f66ec4c74 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,6 @@ distclean: FORCE rust-zerotier-core-bindgen: FORCE cargo install bindgen rm -f rust-zerotier-core/src/bindings/capi.rs - bindgen --no-doc-comments core/zerotier.h >rust-zerotier-core/src/bindings/capi.rs + bindgen --no-doc-comments --no-layout-tests --no-derive-debug core/zerotier.h >rust-zerotier-core/src/bindings/capi.rs FORCE: diff --git a/core/InetAddress.cpp b/core/InetAddress.cpp index baea687b8..a355d3d84 100644 --- a/core/InetAddress.cpp +++ b/core/InetAddress.cpp @@ -464,4 +464,7 @@ InetAddress InetAddress::makeIpv66plane(uint64_t nwid, uint64_t zeroTierAddress) return r; } +const int ZT_AF_INET = (int)AF_INET; +const int ZT_AF_INET6 = (int)AF_INET6; + } // namespace ZeroTier diff --git a/core/Node.cpp b/core/Node.cpp index cc7a291c9..e5fa19383 100644 --- a/core/Node.cpp +++ b/core/Node.cpp @@ -83,7 +83,7 @@ Node::Node( uint64_t idtmp[2]; idtmp[0] = 0; idtmp[1] = 0; - Vector< uint8_t > data(stateObjectGet(tPtr, ZT_STATE_OBJECT_IDENTITY_SECRET, idtmp)); + Vector< uint8_t > data(stateObjectGet(tPtr, ZT_STATE_OBJECT_IDENTITY_SECRET, idtmp, 0)); bool haveIdentity = false; if (!data.empty()) { data.push_back(0); // zero-terminate string @@ -102,15 +102,16 @@ Node::Node( RR->identity.toString(true, RR->secretIdentityStr); idtmp[0] = RR->identity.address(); idtmp[1] = 0; - stateObjectPut(tPtr, ZT_STATE_OBJECT_IDENTITY_SECRET, idtmp, RR->secretIdentityStr, (unsigned int)strlen(RR->secretIdentityStr)); - stateObjectPut(tPtr, ZT_STATE_OBJECT_IDENTITY_PUBLIC, idtmp, RR->publicIdentityStr, (unsigned int)strlen(RR->publicIdentityStr)); + stateObjectPut(tPtr, ZT_STATE_OBJECT_IDENTITY_SECRET, idtmp, 1, RR->secretIdentityStr, (unsigned int)strlen(RR->secretIdentityStr)); + stateObjectPut(tPtr, ZT_STATE_OBJECT_IDENTITY_PUBLIC, idtmp, 1, RR->publicIdentityStr, (unsigned int)strlen(RR->publicIdentityStr)); ZT_SPEW("no pre-existing identity found, created %s", RR->identity.toString().c_str()); } else { idtmp[0] = RR->identity.address(); idtmp[1] = 0; - data = stateObjectGet(tPtr, ZT_STATE_OBJECT_IDENTITY_PUBLIC, idtmp); - if ((data.empty()) || (memcmp(data.data(), RR->publicIdentityStr, strlen(RR->publicIdentityStr)) != 0)) - stateObjectPut(tPtr, ZT_STATE_OBJECT_IDENTITY_PUBLIC, idtmp, RR->publicIdentityStr, (unsigned int)strlen(RR->publicIdentityStr)); + data = stateObjectGet(tPtr, ZT_STATE_OBJECT_IDENTITY_PUBLIC, idtmp, 1); + if ((data.empty()) || (memcmp(data.data(), RR->publicIdentityStr, strlen(RR->publicIdentityStr)) != 0)) { + stateObjectPut(tPtr, ZT_STATE_OBJECT_IDENTITY_PUBLIC, idtmp, 1, RR->publicIdentityStr, (unsigned int)strlen(RR->publicIdentityStr)); + } } // Create a secret key for encrypting local data at rest. @@ -329,7 +330,7 @@ ZT_ResultCode Node::leave( uint64_t tmp[2]; tmp[0] = nwid; tmp[1] = 0; - RR->node->stateObjectDelete(tptr, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp); + RR->node->stateObjectDelete(tptr, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, 1); return ZT_RESULT_OK; } @@ -661,7 +662,7 @@ void Node::setController(void *networkControllerInstance) // Methods used only within the core ---------------------------------------------------------------------------------- -Vector< uint8_t > Node::stateObjectGet(void *const tPtr, ZT_StateObjectType type, const uint64_t *id) +Vector< uint8_t > Node::stateObjectGet(void *const tPtr, ZT_StateObjectType type, const uint64_t *id, const unsigned int idSize) { Vector< uint8_t > r; if (m_cb.stateGetFunction) { @@ -673,6 +674,7 @@ Vector< uint8_t > Node::stateObjectGet(void *const tPtr, ZT_StateObjectType type tPtr, type, id, + idSize, &data, &freeFunc); if ((l > 0) && (data) && (freeFunc)) { diff --git a/core/Node.hpp b/core/Node.hpp index 2cc9fb99a..8ccf4cf98 100644 --- a/core/Node.hpp +++ b/core/Node.hpp @@ -241,9 +241,10 @@ public: * @param tPtr Thread pointer * @param ev Event object * @param md Event data or NULL if none + * @param mdSize Size of event data */ - ZT_INLINE void postEvent(void *tPtr, ZT_Event ev, const void *md = nullptr) noexcept - { m_cb.eventCallback(reinterpret_cast(this), m_uPtr, tPtr, ev, md); } + ZT_INLINE void postEvent(void *tPtr, ZT_Event ev, const void *md = nullptr, const unsigned int mdSize = 0) noexcept + { m_cb.eventCallback(reinterpret_cast(this), m_uPtr, tPtr, ev, md, mdSize); } /** * Post network port configuration via external callback @@ -271,7 +272,7 @@ public: * @param id Object ID or NULL if this type does not use one * @return Vector containing data or empty vector if not found or empty */ - Vector< uint8_t > stateObjectGet(void *tPtr, ZT_StateObjectType type, const uint64_t *id); + Vector< uint8_t > stateObjectGet(void *tPtr, ZT_StateObjectType type, const uint64_t *id, unsigned int idSize); /** * Store a state object @@ -282,10 +283,10 @@ public: * @param data Data to store * @param len Length of data */ - ZT_INLINE void stateObjectPut(void *const tPtr, ZT_StateObjectType type, const uint64_t id[2], const void *const data, const unsigned int len) noexcept + ZT_INLINE void stateObjectPut(void *const tPtr, ZT_StateObjectType type, const uint64_t *const id, const unsigned int idSize, const void *const data, const unsigned int len) noexcept { if (m_cb.statePutFunction) - m_cb.statePutFunction(reinterpret_cast(this), m_uPtr, tPtr, type, id, data, (int)len); + m_cb.statePutFunction(reinterpret_cast(this), m_uPtr, tPtr, type, id, idSize, data, (int)len); } /** @@ -295,10 +296,10 @@ public: * @param type Object type to delete * @param id Object ID */ - ZT_INLINE void stateObjectDelete(void *const tPtr, ZT_StateObjectType type, const uint64_t id[2]) noexcept + ZT_INLINE void stateObjectDelete(void *const tPtr, ZT_StateObjectType type, const uint64_t *const id, const unsigned int idSize) noexcept { if (m_cb.statePutFunction) - m_cb.statePutFunction(reinterpret_cast(this), m_uPtr, tPtr, type, id, nullptr, -1); + m_cb.statePutFunction(reinterpret_cast(this), m_uPtr, tPtr, type, id, idSize, nullptr, -1); } /** diff --git a/core/Peer.cpp b/core/Peer.cpp index 623f8e9db..eb619d021 100644 --- a/core/Peer.cpp +++ b/core/Peer.cpp @@ -508,7 +508,7 @@ void Peer::save(void *tPtr) const uint64_t id[2]; id[0] = m_id.address().toInt(); id[1] = 0; - RR->node->stateObjectPut(tPtr, ZT_STATE_OBJECT_PEER, id, buf, (unsigned int)len + 8); + RR->node->stateObjectPut(tPtr, ZT_STATE_OBJECT_PEER, id, 1, buf, (unsigned int)len + 8); } } diff --git a/core/Topology.cpp b/core/Topology.cpp index 9515a83b9..3f39b78d1 100644 --- a/core/Topology.cpp +++ b/core/Topology.cpp @@ -23,7 +23,7 @@ Topology::Topology(const RuntimeEnvironment *renv, void *tPtr, const int64_t now char tmp[32]; Dictionary d; - Vector< uint8_t > trustData(RR->node->stateObjectGet(tPtr, ZT_STATE_OBJECT_TRUST_STORE, Utils::ZERO256)); + Vector< uint8_t > trustData(RR->node->stateObjectGet(tPtr, ZT_STATE_OBJECT_TRUST_STORE, Utils::ZERO256, 0)); if (trustData.empty() || (!d.decode(trustData.data(), (unsigned int)trustData.size()))) { if (!d.decode(Defaults::CERTIFICATES, Defaults::CERTIFICATES_BYTES)) d.clear(); @@ -37,7 +37,7 @@ Topology::Topology(const RuntimeEnvironment *renv, void *tPtr, const int64_t now if (serialNo.size() == ZT_SHA384_DIGEST_SIZE) { Utils::copy< 48 >(id, serialNo.data()); Certificate cert; - Vector< uint8_t > enc(RR->node->stateObjectGet(tPtr, ZT_STATE_OBJECT_CERT, id)); + Vector< uint8_t > enc(RR->node->stateObjectGet(tPtr, ZT_STATE_OBJECT_CERT, id, 6)); if (cert.decode(enc.data(), (unsigned int)enc.size())) addCertificate(tPtr, cert, now, (unsigned int)d.getUI(Dictionary::arraySubscript(tmp, sizeof(tmp), "c$.lt", idx)), false, false, false); } @@ -236,7 +236,7 @@ ZT_CertificateError Topology::addCertificate(void *tPtr, const Certificate &cert Vector< uint8_t > certData(cert.encode()); uint64_t id[6]; Utils::copy< 48 >(id, cert.serialNo); - RR->node->stateObjectPut(tPtr, ZT_STATE_OBJECT_CERT, id, certData.data(), (unsigned int)certData.size()); + RR->node->stateObjectPut(tPtr, ZT_STATE_OBJECT_CERT, id, 6, certData.data(), (unsigned int)certData.size()); } return ZT_CERTIFICATE_ERROR_NONE; @@ -330,7 +330,7 @@ void Topology::m_eraseCertificate(void *tPtr, const SharedPtr< const Certificate } } - RR->node->stateObjectDelete(tPtr, ZT_STATE_OBJECT_CERT, serialNo.data); + RR->node->stateObjectDelete(tPtr, ZT_STATE_OBJECT_CERT, serialNo.data, 6); } bool Topology::m_cleanCertificates(void *tPtr, int64_t now) @@ -427,7 +427,7 @@ void Topology::m_loadCached(void *tPtr, const Address &zta, SharedPtr< Peer > &p uint64_t id[2]; id[0] = zta.toInt(); id[1] = 0; - Vector< uint8_t > data(RR->node->stateObjectGet(tPtr, ZT_STATE_OBJECT_PEER, id)); + Vector< uint8_t > data(RR->node->stateObjectGet(tPtr, ZT_STATE_OBJECT_PEER, id, 1)); if (data.size() > 8) { const uint8_t *d = data.data(); int dl = (int)data.size(); @@ -521,7 +521,7 @@ void Topology::m_writeTrustStore(void *tPtr) Vector< uint8_t > trustStore; d.encode(trustStore); - RR->node->stateObjectPut(tPtr, ZT_STATE_OBJECT_TRUST_STORE, Utils::ZERO256, trustStore.data(), (unsigned int)trustStore.size()); + RR->node->stateObjectPut(tPtr, ZT_STATE_OBJECT_TRUST_STORE, Utils::ZERO256, 0, trustStore.data(), (unsigned int)trustStore.size()); } } // namespace ZeroTier diff --git a/core/zerotier.h b/core/zerotier.h index 980b62be8..bb26d136c 100644 --- a/core/zerotier.h +++ b/core/zerotier.h @@ -1838,7 +1838,8 @@ typedef void (*ZT_EventCallback)( void *, /* User ptr */ void *, /* Thread ptr */ enum ZT_Event, /* Event type */ - const void *); /* Event payload (if applicable) */ + const void *, /* Event payload (if applicable) */ + unsigned int); /* Size of event payload */ /** * Callback for storing and/or publishing state information @@ -1846,10 +1847,6 @@ typedef void (*ZT_EventCallback)( * See ZT_StateObjectType docs for information about each state object type * and when and if it needs to be persisted. * - * The state object ID's size depends on the object type, and is always - * in the form of one or more 64-bit unsigned integers. Some object types - * do not use this field, and for these it may be NULL. - * * An object of length -1 is sent to indicate that an object should be * deleted. */ @@ -1859,6 +1856,7 @@ typedef void (*ZT_StatePutFunction)( void *, /* Thread ptr */ enum ZT_StateObjectType, /* State object type */ const uint64_t *, /* State object ID (if applicable) */ + unsigned int, /* Length of state object ID in quads */ const void *, /* State object data */ int); /* Length of data or -1 to delete */ @@ -1877,6 +1875,7 @@ typedef int (*ZT_StateGetFunction)( void *, /* Thread ptr */ enum ZT_StateObjectType, /* State object type */ const uint64_t *, /* State object ID (if applicable) */ + unsigned int, /* Length of object ID in quads */ void **, /* Result parameter: data */ void (**)(void *)); /* Result parameter: data free function */ @@ -3019,6 +3018,9 @@ ZT_SDK_API int ZT_InetAddress_isV6(const ZT_InetAddress *ia); */ ZT_SDK_API enum ZT_InetAddress_IpScope ZT_InetAddress_ipScope(const ZT_InetAddress *ia); +/* These mirror the values of AF_INET and AF_INET6 for use by Rust and other things that need it. */ +ZT_SDK_API const int ZT_AF_INET,ZT_AF_INET6; + /* ---------------------------------------------------------------------------------------------------------------- */ diff --git a/rust-zerotier-core/Cargo.toml b/rust-zerotier-core/Cargo.toml index a0cea1e89..d174bf869 100644 --- a/rust-zerotier-core/Cargo.toml +++ b/rust-zerotier-core/Cargo.toml @@ -6,8 +6,8 @@ edition = "2018" build = "build.rs" [dependencies] -num-traits = "0.2.14" -num-derive = "0.3.3" +num-traits = "0.2" +num-derive = "0.3" serde = { version = "1", features = ["derive"] } serde_json = "1" -hex = "0.4.2" +hex = "0.4" diff --git a/rust-zerotier-core/src/address.rs b/rust-zerotier-core/src/address.rs index 5bbd60925..dd3b37e81 100644 --- a/rust-zerotier-core/src/address.rs +++ b/rust-zerotier-core/src/address.rs @@ -1,3 +1,16 @@ +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2025-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + pub struct Address(pub u64); impl ToString for Address { diff --git a/rust-zerotier-core/src/bindings/mod.rs b/rust-zerotier-core/src/bindings/mod.rs index 0d3b33419..e7287f54d 100644 --- a/rust-zerotier-core/src/bindings/mod.rs +++ b/rust-zerotier-core/src/bindings/mod.rs @@ -1,2 +1,15 @@ +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2025-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + #[allow(non_snake_case,non_upper_case_globals,non_camel_case_types,dead_code,improper_ctypes)] pub mod capi; diff --git a/rust-zerotier-core/src/buffer.rs b/rust-zerotier-core/src/buffer.rs index 961c8b50d..8ae984839 100644 --- a/rust-zerotier-core/src/buffer.rs +++ b/rust-zerotier-core/src/buffer.rs @@ -1,3 +1,16 @@ +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2025-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + use std::os::raw::c_void; use std::ptr::{slice_from_raw_parts, slice_from_raw_parts_mut}; diff --git a/rust-zerotier-core/src/certificate.rs b/rust-zerotier-core/src/certificate.rs index 400886328..60850d864 100644 --- a/rust-zerotier-core/src/certificate.rs +++ b/rust-zerotier-core/src/certificate.rs @@ -1,3 +1,16 @@ +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2025-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + use std::cell::Cell; use std::ffi::CString; use std::hash::{Hash, Hasher}; @@ -199,8 +212,6 @@ impl CertificateSubjectUniqueIdSecret { } } -implement_to_from_json!(CertificateSubjectUniqueIdSecret); - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Reasons a certificate may be rejected. @@ -370,8 +381,6 @@ impl CertificateName { } } -implement_to_from_json!(CertificateName); - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #[derive(Serialize, Deserialize)] @@ -402,8 +411,6 @@ impl CertificateNetwork { } } -implement_to_from_json!(CertificateNetwork); - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #[derive(Serialize, Deserialize)] @@ -431,8 +438,6 @@ impl CertificateIdentity { } } -implement_to_from_json!(CertificateIdentity); - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #[derive(Serialize, Deserialize)] @@ -607,8 +612,6 @@ impl CertificateSubject { } } -implement_to_from_json!(CertificateSubject); - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #[derive(Serialize, Deserialize)] @@ -742,8 +745,6 @@ impl Certificate { } } -implement_to_from_json!(Certificate); - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #[cfg(test)] diff --git a/rust-zerotier-core/src/endpoint.rs b/rust-zerotier-core/src/endpoint.rs index 15718c96f..8d3e3fdf5 100644 --- a/rust-zerotier-core/src/endpoint.rs +++ b/rust-zerotier-core/src/endpoint.rs @@ -1,3 +1,16 @@ +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2025-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + use std::ffi::CString; use std::mem::MaybeUninit; use std::os::raw::{c_char, c_int, c_void}; diff --git a/rust-zerotier-core/src/fingerprint.rs b/rust-zerotier-core/src/fingerprint.rs index 00012277e..747f4bbec 100644 --- a/rust-zerotier-core/src/fingerprint.rs +++ b/rust-zerotier-core/src/fingerprint.rs @@ -1,3 +1,16 @@ +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2025-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + use std::ffi::CString; use std::mem::MaybeUninit; use std::os::raw::{c_char, c_int}; diff --git a/rust-zerotier-core/src/identity.rs b/rust-zerotier-core/src/identity.rs index 257a244e2..b2df27325 100644 --- a/rust-zerotier-core/src/identity.rs +++ b/rust-zerotier-core/src/identity.rs @@ -1,3 +1,16 @@ +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2025-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + use std::ffi::CString; use std::mem::MaybeUninit; use std::os::raw::*; diff --git a/rust-zerotier-core/src/inetaddress.rs b/rust-zerotier-core/src/inetaddress.rs index 4360ea943..bff38b95c 100644 --- a/rust-zerotier-core/src/inetaddress.rs +++ b/rust-zerotier-core/src/inetaddress.rs @@ -1,3 +1,16 @@ +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2025-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + use std::ffi::CString; use std::mem::{MaybeUninit, transmute, size_of}; @@ -7,6 +20,14 @@ use num_traits::FromPrimitive; use crate::*; use crate::bindings::capi as ztcore; +use std::os::raw::{c_void, c_uint}; + +// WARNING: here be dragons! This defines an opaque blob in Rust that shadows +// and is of the exact size as an opaque blob in C that shadows and is the +// exact size of struct sockaddr_storage. This Rust code makes use of a good +// deal of transmute() magic to save copying and allow these identically sized +// blobs to be freely cast to one another. That the sizes are correct is +// checked statically in the C++ code and in the tests in the Rust code. #[derive(FromPrimitive,ToPrimitive)] pub enum IpScope { @@ -20,6 +41,12 @@ pub enum IpScope { Private = ztcore::ZT_InetAddress_IpScope_ZT_IP_SCOPE_PRIVATE as isize } +pub enum InetAddressFamily { + Nil, + IPv4, + IPv6 +} + /// 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 @@ -28,13 +55,28 @@ pub struct InetAddress { } impl InetAddress { - #[inline(always)] + /// Create a new empty and "nil" InetAddress. pub fn new() -> InetAddress { InetAddress { bits: [0; (ztcore::ZT_SOCKADDR_STORAGE_SIZE / 8) as usize] } } + /// Create from a 4-byte IPv4 IP or a 16-byte IPv6 IP. + /// Returns None if ip is not 4 or 16 bytes. + pub fn new_from_ip_bytes(ip: &[u8], port: u16) -> Option { + if ip.len() != 4 && ip.len() != 16 { + return None; + } + let mut a = InetAddress::new(); + unsafe { + ztcore::ZT_InetAddress_setIpBytes(a.as_capi_mut_ptr(), ip.as_ptr() as *const c_void, ip.len() as c_uint, port as c_uint); + } + Some(a) + } + + /// Create from an InetAddress in string form. + /// Returns None if the string is not valid. pub fn new_from_string(s: &str) -> Option { let mut a = InetAddress::new(); let cs = CString::new(s); @@ -66,12 +108,14 @@ impl InetAddress { } } + /// Clear and set to the "nil" value. pub fn clear(&mut self) { for i in self.bits.iter_mut() { *i = 0; } } + /// Returns true if this InetAddress holds nothing. #[inline(always)] pub fn is_nil(&self) -> bool { self.bits[0] == 0 // if ss_family != 0, this will not be zero @@ -91,11 +135,27 @@ impl InetAddress { } } + /// Get the network scope of the IP in this object. pub fn ip_scope(&self) -> IpScope { unsafe { IpScope::from_u32(ztcore::ZT_InetAddress_ipScope(self.as_capi_ptr()) as u32).unwrap_or(IpScope::None) } } + + /// Get the address family of this InetAddress. + pub fn family(&self) -> InetAddressFamily { + if !self.is_nil() { + unsafe { + if ztcore::ZT_InetAddress_isV4(self.as_capi_ptr()) != 0 { + return InetAddressFamily::IPv6; + } + if ztcore::ZT_InetAddress_isV6(self.as_capi_ptr()) != 0 { + return InetAddressFamily::IPv6; + } + } + } + InetAddressFamily::Nil + } } impl ToString for InetAddress { diff --git a/rust-zerotier-core/src/lib.rs b/rust-zerotier-core/src/lib.rs index 40cc6c757..eedc104b8 100644 --- a/rust-zerotier-core/src/lib.rs +++ b/rust-zerotier-core/src/lib.rs @@ -1,3 +1,16 @@ +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2025-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + use std::os::raw::{c_char, c_int}; use num_derive::{FromPrimitive, ToPrimitive}; @@ -134,27 +147,6 @@ pub enum ResultCode { ErrorInternalNonFatal = ztcore::ZT_ResultCode_ZT_RESULT_ERROR_INTERNAL as isize, } -#[derive(FromPrimitive,ToPrimitive)] -pub enum Event { - Up = ztcore::ZT_Event_ZT_EVENT_UP as isize, - Offline = ztcore::ZT_Event_ZT_EVENT_OFFLINE as isize, - Online = ztcore::ZT_Event_ZT_EVENT_ONLINE as isize, - Down = ztcore::ZT_Event_ZT_EVENT_DOWN as isize, - Trace = ztcore::ZT_Event_ZT_EVENT_TRACE as isize, - UserMessage = ztcore::ZT_Event_ZT_EVENT_USER_MESSAGE as isize, -} - -#[derive(FromPrimitive,ToPrimitive)] -pub enum StateObjectType { - IdentityPublic = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_IDENTITY_PUBLIC as isize, - IdentitySecret = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_IDENTITY_SECRET as isize, - Locator = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_LOCATOR as isize, - Peer = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_PEER as isize, - NetworkConfig = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_NETWORK_CONFIG as isize, - TrustStore = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_TRUST_STORE as isize, - Certificate = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_CERT as isize -} - /// Returns a tuple of major, minor, revision, and build version numbers from the ZeroTier core. pub fn version() -> (i32, i32, i32, i32) { let mut major: c_int = 0; @@ -191,6 +183,7 @@ pub unsafe fn cstr_to_string(cstr: *const c_char, max_len: isize) -> String { String::new() } +/* #[macro_export(crate)] macro_rules! implement_to_from_json { ($struct_name:ident) => { @@ -213,3 +206,4 @@ macro_rules! implement_to_from_json { } }; } +*/ diff --git a/rust-zerotier-core/src/locator.rs b/rust-zerotier-core/src/locator.rs index a00ad30e7..1ab47b51b 100644 --- a/rust-zerotier-core/src/locator.rs +++ b/rust-zerotier-core/src/locator.rs @@ -1,7 +1,21 @@ +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2025-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +use std::ffi::CString; +use std::os::raw::{c_char, c_int, c_uint}; + use crate::*; use crate::bindings::capi as ztcore; -use std::os::raw::{c_char, c_int, c_uint}; -use std::ffi::CString; pub struct Locator { pub(crate) capi: *const ztcore::ZT_Locator, diff --git a/rust-zerotier-core/src/mac.rs b/rust-zerotier-core/src/mac.rs index 9be780adf..4ba140131 100644 --- a/rust-zerotier-core/src/mac.rs +++ b/rust-zerotier-core/src/mac.rs @@ -1,3 +1,16 @@ +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2025-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + pub struct MAC(pub u64); impl ToString for MAC { diff --git a/rust-zerotier-core/src/networkid.rs b/rust-zerotier-core/src/networkid.rs index d6a0c64f5..330ffdb57 100644 --- a/rust-zerotier-core/src/networkid.rs +++ b/rust-zerotier-core/src/networkid.rs @@ -1,3 +1,16 @@ +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2025-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + pub struct NetworkId(pub u64); impl NetworkId { diff --git a/rust-zerotier-core/src/node.rs b/rust-zerotier-core/src/node.rs index 9ef633cea..1c3ccf9ce 100644 --- a/rust-zerotier-core/src/node.rs +++ b/rust-zerotier-core/src/node.rs @@ -1,9 +1,25 @@ -use std::cell::Cell; +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2025-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +use std::any::Any; +use std::cell::{Cell, RefCell}; +use std::collections::hash_map::HashMap; use std::ffi::CStr; -use std::mem::MaybeUninit; -use std::mem::transmute; +use std::fs::copy; +use std::intrinsics::copy_nonoverlapping; +use std::mem::{MaybeUninit, transmute}; use std::os::raw::{c_int, c_uint, c_ulong, c_void}; -use std::ptr::null_mut; +use std::ptr::{null, null_mut, slice_from_raw_parts}; use std::sync::*; use std::sync::atomic::*; use std::time::Duration; @@ -14,8 +30,45 @@ use serde::{Deserialize, Serialize}; use crate::*; use crate::bindings::capi as ztcore; +/// Minimum delay between iterations of the background loop. const NODE_BACKGROUND_MIN_DELAY: i64 = 250; +#[derive(FromPrimitive,ToPrimitive)] +pub enum Event { + Up = ztcore::ZT_Event_ZT_EVENT_UP as isize, + Offline = ztcore::ZT_Event_ZT_EVENT_OFFLINE as isize, + Online = ztcore::ZT_Event_ZT_EVENT_ONLINE as isize, + Down = ztcore::ZT_Event_ZT_EVENT_DOWN as isize, + Trace = ztcore::ZT_Event_ZT_EVENT_TRACE as isize, + UserMessage = ztcore::ZT_Event_ZT_EVENT_USER_MESSAGE as isize, +} + +#[derive(FromPrimitive,ToPrimitive)] +pub enum StateObjectType { + IdentityPublic = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_IDENTITY_PUBLIC as isize, + IdentitySecret = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_IDENTITY_SECRET as isize, + Locator = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_LOCATOR as isize, + Peer = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_PEER as isize, + NetworkConfig = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_NETWORK_CONFIG as isize, + TrustStore = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_TRUST_STORE as isize, + Certificate = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_CERT as isize +} + +impl StateObjectType { + pub fn to_file_ext(&self) -> &str { + match *self { + StateObjectType::IdentityPublic => "public", + StateObjectType::IdentitySecret => "secret", + StateObjectType::Locator => "locator", + StateObjectType::Peer => "peer", + StateObjectType::NetworkConfig => "network", + StateObjectType::TrustStore => "trust", + StateObjectType::Certificate => "cert" + } + } +} + +/// The status of a ZeroTier node. #[derive(Serialize, Deserialize)] pub struct NodeStatus { pub address: Address, @@ -27,29 +80,53 @@ pub struct NodeStatus { pub online: bool, } +/// An event handler that receives events, frames, and packets from the core. +/// Note that these handlers can be called concurrently from any thread and +/// must be thread safe. 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); + /// Called when a configuration change or update should be applied to a network. + fn virtual_network_config(&self, network_id: NetworkId, network_obj: &Arc, config_op: VirtualNetworkConfigOperation, config: Option<&VirtualNetworkConfig>); + + /// Called when a frame should be injected into the virtual network (physical -> virtual). + fn virtual_network_frame(&self, network_id: NetworkId, network_obj: &Arc, source_mac: MAC, dest_mac: MAC, ethertype: u16, vlan_id: u16, data: &[u8]); + + /// Called when a core ZeroTier event occurs. + fn event(&self, event: Event, event_data: &[u8]); + + /// Called to store an object into the object store. + fn state_put(&self, obj_type: StateObjectType, obj_id: &[u64], obj_data: &[u8]); + + /// Called to retrieve an object from the object store. + fn state_get(&self, obj_type: StateObjectType, obj_id: &[u64]) -> Box<[u8]>; + + /// Called to send a packet over the physical network (virtual -> physical). + fn wire_packet_send(&self, local_socket: i64, sock_addr: &InetAddress, data: &[u8], packet_ttl: u32) -> i32; + + /// Called to check and see if a physical address should be used for ZeroTier traffic. + fn path_check(&self, address: Address, id: &Identity, local_socket: i64, sock_addr: &InetAddress) -> bool; + + /// Called to look up a path to a known node, allowing out of band lookup methods for physical paths to nodes. + fn path_lookup(&self, address: Address, id: &Identity, desired_family: InetAddressFamily) -> Option; } +/// An instance of the ZeroTier core. +/// This is templated on the actual implementation of NodeEventHandler for performance reasons, +/// as it avoids an extra indirect function call. pub struct Node { event_handler: Arc, capi: Cell<*mut ztcore::ZT_Node>, background_thread: Cell>>, background_thread_run: Arc, now: PortableAtomicI64, + networks_by_id: Mutex>> // pointer to an Arc<> is a raw value created from Box> } +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + macro_rules! node_from_raw_ptr { ($uptr:ident) => { unsafe { - let ntmp: *const Node = transmute($uptr); + let ntmp: *const Node = $uptr.cast::>(); let ntmp: &Node = &*ntmp; ntmp } @@ -57,22 +134,32 @@ macro_rules! node_from_raw_ptr { } extern "C" fn zt_virtual_network_config_function( - capi: *mut ztcore::ZT_Node, + _: *mut ztcore::ZT_Node, uptr: *mut c_void, - tptr: *mut c_void, + _: *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); - n.event_handler.virtual_network_config(); + let op2 = VirtualNetworkConfigOperation::from_u32(op as u32); + if op2.is_some() { + let op2 = op2.unwrap(); + let n = node_from_raw_ptr!(uptr); + let network_obj: &Arc = unsafe { &*((*nptr).cast::>()) }; + if conf.is_null() { + n.event_handler.virtual_network_config(NetworkId(nwid), network_obj, op2, None); + } else { + let conf2 = unsafe { VirtualNetworkConfig::new_from_capi(&*conf) }; + n.event_handler.virtual_network_config(NetworkId(nwid), network_obj, op2, Some(&conf2)); + } + } } extern "C" fn zt_virtual_network_frame_function( - capi: *mut ztcore::ZT_Node, + _: *mut ztcore::ZT_Node, uptr: *mut c_void, - tptr: *mut c_void, + _: *mut c_void, nwid: u64, nptr: *mut *mut c_void, source_mac: u64, @@ -82,87 +169,162 @@ extern "C" fn zt_virtual_network_frame_function( data: *const c_void, data_size: c_uint, ) { - let n = node_from_raw_ptr!(uptr); - n.event_handler.virtual_network_frame(); + if !nptr.is_null() { + let n = node_from_raw_ptr!(uptr); + let network_obj: &Arc = unsafe { &*((*nptr).cast::>()) }; + let data_slice = unsafe { &*slice_from_raw_parts(data.cast::(), data_size as usize) }; + n.event_handler.virtual_network_frame(NetworkId(nwid), network_obj, MAC(source_mac), MAC(dest_mac), ethertype as u16, vlan_id as u16, data_slice); + } } extern "C" fn zt_event_callback( - capi: *mut ztcore::ZT_Node, + _: *mut ztcore::ZT_Node, uptr: *mut c_void, - tptr: *mut c_void, + _: *mut c_void, ev: ztcore::ZT_Event, data: *const c_void, + data_size: c_uint ) { - let n = node_from_raw_ptr!(uptr); - n.event_handler.event(); + let ev2 = Event::from_u32(ev as u32); + if ev2.is_some() { + let ev2 = ev2.unwrap(); + let n = node_from_raw_ptr!(uptr); + if data.is_null() { + n.event_handler.event(ev2, &[u8; 0]); + } else { + let data2 = unsafe { &*slice_from_raw_parts(data.cast::(), data_size as usize) }; + n.event_handler.event(ev2, data2); + } + } } extern "C" fn zt_state_put_function( - capi: *mut ztcore::ZT_Node, + _: *mut ztcore::ZT_Node, uptr: *mut c_void, - tptr: *mut c_void, + _: *mut c_void, obj_type: ztcore::ZT_StateObjectType, obj_id: *const u64, + obj_id_len: c_uint, obj_data: *const c_void, obj_data_len: c_int, ) { - let n = node_from_raw_ptr!(uptr); - n.event_handler.state_put(); + let obj_type2 = StateObjectType::from_u32(obj_type as u32); + if obj_type2.is_some() { + let obj_type2 = obj_type2.unwrap(); + let n = node_from_raw_ptr!(uptr); + let obj_id2 = unsafe { &*slice_from_raw_parts(obj_id, obj_id_len as usize) }; + let obj_data2 = unsafe { &*slice_from_raw_parts(obj_data.cast::(), obj_data_len as usize) }; + n.event_handler.state_put(obj_type2, obj_id2, obj_data2); + } } extern "C" fn zt_state_get_function( - capi: *mut ztcore::ZT_Node, + _: *mut ztcore::ZT_Node, uptr: *mut c_void, - tptr: *mut c_void, + _: *mut c_void, obj_type: ztcore::ZT_StateObjectType, obj_id: *const u64, + obj_id_len: c_uint, obj_data: *mut *mut c_void, obj_data_free_function: *mut *mut c_void, -) { - let n = node_from_raw_ptr!(uptr); - n.event_handler.state_get(); +) -> c_int { + if obj_data.is_null() || obj_data_free_function.is_null() { + return -1; + } + unsafe { + *obj_data = null_mut(); + *obj_data_free_function = transmute(ztcore::free as *const ()); + } + + let obj_type2 = StateObjectType::from_u32(obj_type as u32); + if obj_type2.is_some() { + let obj_type2 = obj_type2.unwrap(); + let n = node_from_raw_ptr!(uptr); + let obj_id2 = unsafe { &*slice_from_raw_parts(obj_id, obj_id_len as usize) }; + let obj_data_result = n.event_handler.state_get(obj_type2, obj_id2); + if obj_data_result.len() > 0 { + unsafe { + let obj_data_len: c_int = obj_data_result.len() as c_int; + let obj_data_raw = ztcore::malloc(obj_data_len as c_ulong); + if !obj_data_raw.is_null() { + copy_nonoverlapping(obj_data_result.as_ptr(), obj_data_raw.cast::(), obj_data_len as usize); + *obj_data = obj_data_raw; + return obj_data_len; + } + } + } + } + return -1; } extern "C" fn zt_wire_packet_send_function( - capi: *mut ztcore::ZT_Node, + _: *mut ztcore::ZT_Node, uptr: *mut c_void, - tptr: *mut c_void, + _: *mut c_void, local_socket: i64, sock_addr: *const ztcore::ZT_InetAddress, data: *const c_void, data_size: c_uint, packet_ttl: c_uint, -) { +) -> c_int { let n = node_from_raw_ptr!(uptr); - n.event_handler.wire_packet_send(); + return n.event_handler.wire_packet_send(local_socket, InetAddress::transmute_capi(unsafe { &*sock_addr }), unsafe { &*slice_from_raw_parts(data.cast::(), data_size as usize) }, packet_ttl as u32) as c_int; } extern "C" fn zt_path_check_function( - capi: *mut ztcore::ZT_Node, + _: *mut ztcore::ZT_Node, uptr: *mut c_void, - tptr: *mut c_void, + _: *mut c_void, address: u64, identity: *const ztcore::ZT_Identity, local_socket: i64, sock_addr: *const ztcore::ZT_InetAddress, -) { +) -> c_int { let n = node_from_raw_ptr!(uptr); - n.event_handler.path_check(); + let id = Identity::new_from_capi(identity, false); + if n.event_handler.path_check(Address(address), &id, local_socket, InetAddress::transmute_capi(unsafe{ &*sock_addr })) { + return 1; + } + return 0; } extern "C" fn zt_path_lookup_function( - capi: *mut ztcore::ZT_Node, + _: *mut ztcore::ZT_Node, uptr: *mut c_void, - tptr: *mut c_void, + _: *mut c_void, address: u64, identity: *const ztcore::ZT_Identity, sock_family: c_int, sock_addr: *mut ztcore::ZT_InetAddress, -) { +) -> c_int { + if sock_addr.is_null() { + return 0; + } + let mut sock_family2: InetAddressFamily = InetAddressFamily::Nil; + unsafe { + match sock_family { + ztcore::ZT_AF_INET => InetAddressFamily::IPv4, + ztcore::ZT_AF_INET6 => InetAddressFamily::IPv6, + _ => { return 0; } + } + } + let n = node_from_raw_ptr!(uptr); - n.event_handler.path_lookup(); + let id = Identity::new_from_capi(identity, false); + let result = n.event_handler.path_lookup(Address(address), &id, sock_family2); + if result.is_some() { + let result = result.unwrap(); + let result_ptr = &result as *const InetAddress; + unsafe { + copy_nonoverlapping(result_ptr.cast::(), sock_addr, 1); + } + return 1; + } + return 0; } +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + impl Node { /// Create a new Node with a given event handler. pub fn new(event_handler: Arc) -> Result>, ResultCode> { @@ -174,6 +336,7 @@ impl Node { background_thread: Cell::new(None), background_thread_run: Arc::new(AtomicBool::new(true)), now: PortableAtomicI64::new(now), + networks_by_id: Mutex::new(HashMap::new()) }); let mut capi: *mut ztcore::ZT_Node = null_mut(); @@ -240,7 +403,7 @@ impl Node { next_delay } - pub fn join(&self, nwid: NetworkId, controller_fingerprint: Option) -> ResultCode { + pub fn join(&self, nwid: NetworkId, controller_fingerprint: Option, network_obj: &Arc) -> ResultCode { let mut cfp: MaybeUninit = MaybeUninit::uninit(); let mut cfpp: *mut ztcore::ZT_Fingerprint = null_mut(); if controller_fingerprint.is_some() { @@ -251,13 +414,27 @@ impl Node { (*cfpp).hash = cfp2.hash; } } - unsafe { - let rc = ztcore::ZT_Node_join(self.capi.get(), nwid.0, cfpp, null_mut(), null_mut()); - return ResultCode::from_u32(rc as u32).unwrap(); + + let nptr = Box::into_raw(Box::new(network_obj.clone())); + self.networks_by_id.lock().as_deref_mut().unwrap().insert(nwid.0, nptr); + let rc = unsafe { ztcore::ZT_Node_join(self.capi.get(), nwid.0, cfpp, nptr.cast::(), null_mut()) }; + if rc != ztcore::ZT_ResultCode_ZT_RESULT_OK { + self.delete_network_uptr(nwid.0); + } + return ResultCode::from_u32(rc as u32).unwrap_or(ResultCode::ErrorInternalNonFatal); + } + + fn delete_network_uptr(&self, nwid: u64) { + let nptr = self.networks_by_id.lock().as_deref_mut().unwrap().remove(&nwid).unwrap_or(null_mut()); + if !nptr.is_null() { + unsafe { + Box::from_raw(nptr); + } } } pub fn leave(&self, nwid: NetworkId) -> ResultCode { + self.delete_network_uptr(nwid.0); unsafe { return ResultCode::from_u32(ztcore::ZT_Node_leave(self.capi.get(), nwid.0, null_mut(), null_mut()) as u32).unwrap(); } @@ -306,8 +483,8 @@ impl Node { } pub fn status(&self) -> NodeStatus { + let mut ns: MaybeUninit = MaybeUninit::zeroed(); unsafe { - let mut ns: MaybeUninit = MaybeUninit::zeroed(); ztcore::ZT_Node_status(self.capi.get(), ns.as_mut_ptr()); let ns = ns.assume_init(); if ns.identity.is_null() { @@ -386,6 +563,15 @@ impl Drop for Node { let _ = bt.join(); } + // Manually take care of the unboxed Boxes in networks_by_id + let mut nwids: Vec = Vec::new(); + for n in self.networks_by_id.lock().unwrap().iter() { + nwids.push(*n.0); + } + for nwid in nwids.iter() { + self.delete_network_uptr(*nwid); + } + unsafe { ztcore::ZT_Node_delete(self.capi.get(), null_mut()); } diff --git a/rust-zerotier-core/src/path.rs b/rust-zerotier-core/src/path.rs index 98185e530..abf08ebcd 100644 --- a/rust-zerotier-core/src/path.rs +++ b/rust-zerotier-core/src/path.rs @@ -1,6 +1,20 @@ +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2025-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +use serde::{Deserialize, Serialize}; + use crate::*; use crate::bindings::capi as ztcore; -use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] pub struct Path { @@ -14,7 +28,7 @@ pub struct Path { } impl Path { - #[inline] + #[inline(always)] pub(crate) fn new_from_capi(p: &ztcore::ZT_Path) -> Path { Path{ endpoint: Endpoint::new_from_capi(&p.endpoint), diff --git a/rust-zerotier-core/src/peer.rs b/rust-zerotier-core/src/peer.rs index 8db1f67de..5e3b811c6 100644 --- a/rust-zerotier-core/src/peer.rs +++ b/rust-zerotier-core/src/peer.rs @@ -1,6 +1,20 @@ +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2025-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +use serde::{Deserialize, Serialize}; + use crate::*; use crate::bindings::capi as ztcore; -use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] pub struct Peer { @@ -23,7 +37,7 @@ pub struct Peer { } impl Peer { - #[inline] + #[inline(always)] pub(crate) fn new_from_capi(p: &ztcore::ZT_Peer) -> Peer { unsafe { let mut networks: Vec = Vec::new(); diff --git a/rust-zerotier-core/src/portableatomici64.rs b/rust-zerotier-core/src/portableatomici64.rs index f4763a4d0..0d45c6313 100644 --- a/rust-zerotier-core/src/portableatomici64.rs +++ b/rust-zerotier-core/src/portableatomici64.rs @@ -1,3 +1,16 @@ +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2025-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + #[cfg(all(target_pointer_width = "32"))] use std::sync::Mutex; diff --git a/rust-zerotier-core/src/virtualnetworkconfig.rs b/rust-zerotier-core/src/virtualnetworkconfig.rs index 48a4448ea..3df1f423b 100644 --- a/rust-zerotier-core/src/virtualnetworkconfig.rs +++ b/rust-zerotier-core/src/virtualnetworkconfig.rs @@ -1,3 +1,16 @@ +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2025-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + use std::mem::{size_of, transmute, zeroed}; use serde::{Deserialize, Serialize};