C++ build fixes, fix regression in SharedPtr

This commit is contained in:
Adam Ierymenko 2021-03-09 18:08:31 -05:00
parent f82085cede
commit 8c45fbe64c
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
8 changed files with 176 additions and 126 deletions

View file

@ -156,7 +156,7 @@ void Peer::send(void *tPtr, int64_t now, const void *data, unsigned int len) noe
if (via) {
via->send(RR, tPtr, data, len, now);
} else {
const SharedPtr< Peer > root(RR->topology->root(now));
const SharedPtr< Peer > root(RR->topology->root());
if ((root) && (root.ptr() != this)) {
via = root->path(now);
if (via) {
@ -397,7 +397,7 @@ void Peer::pulse(void *const tPtr, const int64_t now, const bool isRoot)
// Send a HELLO indirectly if we were not able to send one via any direct path.
if (needHello) {
const SharedPtr< Peer > root(RR->topology->root(now));
const SharedPtr< Peer > root(RR->topology->root());
if (root) {
const SharedPtr< Path > via(root->path(now));
if (via) {

View file

@ -42,7 +42,7 @@ public:
ZT_INLINE ~SharedPtr()
{
if (likely(m_ptr != nullptr)) {
if (unlikely(const_cast<std::atomic< int > *>(&(m_ptr->__refCount))->fetch_sub(1, std::memory_order_relaxed) <= 0))
if (unlikely(const_cast<std::atomic< int > *>(&(m_ptr->__refCount))->fetch_sub(1, std::memory_order_relaxed) <= 1))
delete m_ptr;
}
}
@ -52,7 +52,7 @@ public:
if (likely(m_ptr != sp.m_ptr)) {
T *const p = sp._getAndInc();
if (likely(m_ptr != nullptr)) {
if (unlikely(const_cast<std::atomic< int > *>(&(m_ptr->__refCount))->fetch_sub(1, std::memory_order_relaxed) <= 0))
if (unlikely(const_cast<std::atomic< int > *>(&(m_ptr->__refCount))->fetch_sub(1, std::memory_order_relaxed) <= 1))
delete m_ptr;
}
m_ptr = p;
@ -63,7 +63,7 @@ public:
ZT_INLINE void set(T *ptr) noexcept
{
if (likely(m_ptr != nullptr)) {
if (unlikely(const_cast<std::atomic< int > *>(&(m_ptr->__refCount))->fetch_sub(1, std::memory_order_relaxed) <= 0))
if (unlikely(const_cast<std::atomic< int > *>(&(m_ptr->__refCount))->fetch_sub(1, std::memory_order_relaxed) <= 1))
delete m_ptr;
}
const_cast<std::atomic< int > *>(&(ptr->__refCount))->fetch_add(1, std::memory_order_relaxed);
@ -93,7 +93,7 @@ public:
ZT_INLINE void move(SharedPtr &from)
{
if (m_ptr != nullptr) {
if (const_cast<std::atomic< int > *>(&(m_ptr->__refCount))->fetch_sub(1, std::memory_order_relaxed) <= 0)
if (const_cast<std::atomic< int > *>(&(m_ptr->__refCount))->fetch_sub(1, std::memory_order_relaxed) <= 1)
delete m_ptr;
}
m_ptr = from.m_ptr;
@ -121,7 +121,7 @@ public:
ZT_INLINE void zero()
{
if (likely(m_ptr != nullptr)) {
if (unlikely(const_cast<std::atomic< int > *>(&(m_ptr->__refCount))->fetch_sub(1, std::memory_order_relaxed) <= 0))
if (unlikely(const_cast<std::atomic< int > *>(&(m_ptr->__refCount))->fetch_sub(1, std::memory_order_relaxed) <= 1))
delete m_ptr;
m_ptr = nullptr;
}
@ -188,7 +188,7 @@ public:
private:
ZT_INLINE T *_getAndInc() const noexcept
{
if (likely(m_ptr))
if (likely(m_ptr != nullptr))
const_cast<std::atomic< int > *>(&(m_ptr->__refCount))->fetch_add(1, std::memory_order_relaxed);
return m_ptr;
}

View file

@ -649,18 +649,18 @@ extern "C" const char *ZTT_general()
bufs.push_back(SharedPtr< Buf >(new Buf()));
cnt += ZT_BUF_MAX_POOL_SIZE + 100;
if (Buf::poolAllocated() != cnt) {
ZT_T_PRINTF("FAILED" ZT_EOL_S);
ZT_T_PRINTF("FAILED (1)" ZT_EOL_S);
return "Buf memory pool test failed";
}
bufs.clear();
if (Buf::poolAllocated() != ZT_BUF_MAX_POOL_SIZE) {
ZT_T_PRINTF("FAILED" ZT_EOL_S);
ZT_T_PRINTF("FAILED (2)" ZT_EOL_S);
return "Buf memory pool test failed";
}
Buf::freePool();
cnt -= ZT_BUF_MAX_POOL_SIZE + 100;
if (Buf::poolAllocated() != cnt) {
ZT_T_PRINTF("FAILED" ZT_EOL_S);
ZT_T_PRINTF("FAILED (3)" ZT_EOL_S);
return "Buf memory pool test failed";
}
} catch (...) {

View file

@ -437,7 +437,7 @@ void VL1::m_relay(void *tPtr, const SharedPtr< Path > &path, Address destination
void VL1::m_sendPendingWhois(void *tPtr, int64_t now)
{
const SharedPtr< Peer > root(RR->topology->root(now));
const SharedPtr< Peer > root(RR->topology->root());
if (unlikely(!root))
return;
const SharedPtr< Path > rootPath(root->path(now));

View file

@ -41,86 +41,41 @@ pub const CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_PRIVATE_SIZE: u32 = ztcore::ZT_C
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(PartialEq, Eq)]
#[derive(PartialEq, Eq, PartialOrd, Ord)]
pub struct CertificateSerialNo(pub [u8; 48]);
impl CertificateSerialNo {
/// Create a new empty (all zero) serial number.
#[inline(always)]
pub fn new() -> CertificateSerialNo {
CertificateSerialNo([0; 48])
}
pub fn new_from_string(s: &str) -> Result<CertificateSerialNo, ResultCode> {
let b = hex::decode(s);
if b.is_err() {
return Err(ResultCode::ErrorBadParameter);
}
return Ok(CertificateSerialNo::from(b.unwrap().as_slice()));
}
pub fn new() -> CertificateSerialNo { CertificateSerialNo([0; 48]) }
pub fn new_from_string(s: &str) -> Result<CertificateSerialNo, ResultCode> { hex::decode(s).map_or_else(|_| { Err(ResultCode::ErrorBadParameter) }, |b| { Ok(CertificateSerialNo::from(b.unwrap().as_slice())) }) }
}
impl From<&[u8; 48]> for CertificateSerialNo {
#[inline(always)]
fn from(a: &[u8; 48]) -> CertificateSerialNo {
CertificateSerialNo(*a)
}
}
impl From<&[u8]> for CertificateSerialNo {
fn from(v: &[u8]) -> CertificateSerialNo {
let mut l = v.len();
if l > 48 {
l = 48;
}
let mut s = CertificateSerialNo::new();
s.0[0..l].copy_from_slice(&v[0..l]);
s
}
fn from(a: &[u8; 48]) -> CertificateSerialNo { CertificateSerialNo(*a) }
}
impl Hash for CertificateSerialNo {
#[inline(always)]
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
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)
}
fn to_string(&self) -> String { hex::encode(self.0) }
}
impl serde::Serialize for CertificateSerialNo {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
serializer.serialize_str(self.to_string().as_str())
}
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer { serializer.serialize_str(self.to_string().as_str()) }
}
struct CertificateSerialNoVisitor;
impl<'de> serde::de::Visitor<'de> for CertificateSerialNoVisitor {
type Value = CertificateSerialNo;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("CertificateSerialNoVisitor value in string form")
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error {
let id = CertificateSerialNo::new_from_string(s);
if id.is_err() {
return Err(serde::de::Error::invalid_value(serde::de::Unexpected::Str(s), &self));
}
return Ok(id.ok().unwrap() as Self::Value);
}
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("object") }
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error { Self::Value::new_from_string(s).map_or_else(|_| { Err(serde::de::Error::invalid_value(serde::de::Unexpected::Str(s), &self)) },|id| { Ok(id as Self::Value) }) }
}
impl<'de> serde::Deserialize<'de> for CertificateSerialNo {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
deserializer.deserialize_str(CertificateSerialNoVisitor)
}
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> { deserializer.deserialize_str(CertificateSerialNoVisitor) }
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -149,33 +104,16 @@ impl ToString for CertificateUniqueIdType {
}
impl serde::Serialize for CertificateUniqueIdType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
serializer.serialize_str(self.to_string().as_str())
}
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer { serializer.serialize_str(self.to_string().as_str()) }
}
struct CertificateUniqueIdTypeVisitor;
impl<'de> serde::de::Visitor<'de> for CertificateUniqueIdTypeVisitor {
type Value = CertificateUniqueIdType;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("CertificateUniqueIdType value in string form")
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error {
let id = CertificateUniqueIdType::new_from_string(s);
if id.is_err() {
return Err(serde::de::Error::invalid_value(serde::de::Unexpected::Str(s), &self));
}
return Ok(id.ok().unwrap() as Self::Value);
}
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("object") }
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error { Self::Value::new_from_string(s).map_or_else(|_| { Err(serde::de::Error::invalid_value(serde::de::Unexpected::Str(s), &self)) },|id| { Ok(id as Self::Value) }) }
}
impl<'de> serde::Deserialize<'de> for CertificateUniqueIdType {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
deserializer.deserialize_str(CertificateUniqueIdTypeVisitor)
}
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> { deserializer.deserialize_str(CertificateUniqueIdTypeVisitor) }
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -210,9 +148,10 @@ impl CertificateSubjectUniqueIdSecret {
}
}
implement_to_from_json!(CertificateSubjectUniqueIdSecret);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Reasons a certificate may be rejected.
#[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
pub enum CertificateError {
None = ztcore::ZT_CertificateError_ZT_CERTIFICATE_ERROR_NONE as isize,
@ -246,9 +185,9 @@ impl ToString for CertificateError {
}
}
impl From<&str> for CertificateError {
fn from(s: &str) -> CertificateError {
match s.to_ascii_lowercase().as_str() {
impl<S: AsRef<str>> From<S> for CertificateError {
fn from(s: S) -> CertificateError {
match s.as_ref().to_ascii_lowercase().as_str() {
"havenewercert" => CertificateError::HaveNewerCert,
"invalidformat" => CertificateError::InvalidFormat,
"invalididentity" => CertificateError::InvalidIdentity,
@ -264,29 +203,16 @@ impl From<&str> for CertificateError {
}
impl serde::Serialize for CertificateError {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
serializer.serialize_str(self.to_string().as_str())
}
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer { serializer.serialize_str(self.to_string().as_str()) }
}
struct CertificateErrorVisitor;
impl<'de> serde::de::Visitor<'de> for CertificateErrorVisitor {
type Value = CertificateError;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("CertificateError value in string form")
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error {
return Ok(CertificateError::from(s));
}
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("object") }
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error { return Ok(CertificateError::from(s)); }
}
impl<'de> serde::Deserialize<'de> for CertificateError {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
deserializer.deserialize_str(CertificateErrorVisitor)
}
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> { deserializer.deserialize_str(CertificateErrorVisitor) }
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -379,6 +305,8 @@ impl CertificateName {
}
}
implement_to_from_json!(CertificateName);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Serialize, Deserialize, PartialEq, Eq)]
@ -409,6 +337,8 @@ impl CertificateNetwork {
}
}
implement_to_from_json!(CertificateNetwork);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Serialize, Deserialize, PartialEq, Eq)]
@ -436,6 +366,8 @@ impl CertificateIdentity {
}
}
implement_to_from_json!(CertificateIdentity);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Serialize, Deserialize, PartialEq, Eq)]
@ -614,6 +546,8 @@ impl CertificateSubject {
}
}
implement_to_from_json!(CertificateSubject);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Serialize, Deserialize, PartialEq, Eq)]

View file

@ -93,8 +93,8 @@ Advanced Operations:
cert <command> [args]
· list List certificates at local node
· show <serial> Show certificate details
newsid <secret out> Create a new subject unique ID
newcsr <subject> <secret> <csr out> Create a subject CSR
newsid [sid secret out] Create a new subject unique ID
newcsr <sid secret> <csr out> Create a subject CSR
sign <csr> <identity> <cert out> Sign a CSR to create a certificate
verify <cert> Verify certificate (not chain)
dump <cert> Verify and print certificate
@ -229,15 +229,14 @@ pub(crate) fn parse_cli_args() -> ArgMatches<'static> {
.subcommand(App::new("show")
.arg(Arg::with_name("serial").index(1).required(true)))
.subcommand(App::new("newsid")
.arg(Arg::with_name("path").index(1).required(true)))
.arg(Arg::with_name("path").index(1).required(false)))
.subcommand(App::new("newcsr")
.arg(Arg::with_name("subject").index(1).required(true))
.arg(Arg::with_name("secret").index(2).required(true))
.arg(Arg::with_name("output").index(3).required(true)))
.arg(Arg::with_name("secret").index(1).required(true))
.arg(Arg::with_name("output").index(2).required(false)))
.subcommand(App::new("sign")
.arg(Arg::with_name("csr").index(1).required(true))
.arg(Arg::with_name("identity").index(2).required(true))
.arg(Arg::with_name("output").index(3).required(true)))
.arg(Arg::with_name("output").index(3).required(false)))
.subcommand(App::new("verify")
.arg(Arg::with_name("cert").index(1).required(true)))
.subcommand(App::new("dump")
@ -248,7 +247,7 @@ pub(crate) fn parse_cli_args() -> ArgMatches<'static> {
.subcommand(App::new("restore"))
.subcommand(App::new("export")
.arg(Arg::with_name("serial").index(1).required(true))
.arg(Arg::with_name("path").index(2)))
.arg(Arg::with_name("path").index(2).required(false)))
.subcommand(App::new("delete")
.arg(Arg::with_name("serial").index(1).required(true))))
.help(help.as_str())

View file

@ -0,0 +1,100 @@
/*
* Copyright (c)2013-2021 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: 2026-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 clap::ArgMatches;
use crate::store::Store;
use zerotier_core::{CertificateSubjectUniqueIdSecret, CertificateUniqueIdType};
use std::io::Write;
#[inline(always)]
fn list(store: &Store, auth_token: &Option<String>) -> i32 {
0
}
#[inline(always)]
fn show<'a>(store: &Store, cli_args: &ArgMatches<'a>, auth_token: &Option<String>) -> i32 {
0
}
#[inline(always)]
fn newsid<'a>(store: &Store, cli_args: Option<&ArgMatches<'a>>, auth_token: &Option<String>) -> i32 {
let sid = CertificateSubjectUniqueIdSecret::new(CertificateUniqueIdType::NistP384); // right now there's only one type
let sid = sid.to_json();
let path = cli_args.map_or("", |cli_args| { cli_args.value_of("path").unwrap_or("") });
if path.is_empty() {
let _ = std::io::stdout().write_all(sid.as_bytes());
0
} else {
std::fs::write(path, sid.as_bytes()).map_or_else(|e| {
eprintln!("FATAL: error writing '{}': {}", path, e.to_string());
e.raw_os_error().unwrap_or(1)
}, || {
0
})
}
}
#[inline(always)]
fn sign<'a>(store: &Store, cli_args: &ArgMatches<'a>, auth_token: &Option<String>) -> i32 {
0
}
#[inline(always)]
fn verify<'a>(store: &Store, cli_args: &ArgMatches<'a>, auth_token: &Option<String>) -> i32 {
0
}
#[inline(always)]
fn dump<'a>(store: &Store, cli_args: &ArgMatches<'a>, auth_token: &Option<String>) -> i32 {
0
}
#[inline(always)]
fn import<'a>(store: &Store, cli_args: &ArgMatches<'a>, auth_token: &Option<String>) -> i32 {
0
}
#[inline(always)]
fn restore(store: &Store, auth_token: &Option<String>) -> i32 {
0
}
#[inline(always)]
fn export<'a>(store: &Store, cli_args: &ArgMatches<'a>, auth_token: &Option<String>) -> i32 {
0
}
#[inline(always)]
fn delete<'a>(store: &Store, cli_args: &ArgMatches<'a>, auth_token: &Option<String>) -> i32 {
0
}
pub(crate) fn run<'a>(store: &Store, cli_args: &ArgMatches<'a>, auth_token: &Option<String>) -> i32 {
match cli_args.subcommand() {
("list", None) => list(store, auth_token),
("show", Some(sub_cli_args)) => show(store, sub_cli_args, auth_token),
("newsid", sub_cli_args) => newsid(store, sub_cli_args, auth_token),
("newcsr", Some(sub_cli_args)) => newcsr(store, sub_cli_args, auth_token),
("sign", Some(sub_cli_args)) => sign(store, sub_cli_args, auth_token),
("verify", Some(sub_cli_args)) => verify(store, sub_cli_args, auth_token),
("dump", Some(sub_cli_args)) => dump(store, sub_cli_args, auth_token),
("import", Some(sub_cli_args)) => import(store, sub_cli_args, auth_token),
("restore", None) => restore(store, auth_token),
("export", Some(sub_cli_args)) => export(store, sub_cli_args, auth_token),
("delete", Some(sub_cli_args)) => delete(store, sub_cli_args, auth_token),
_ => {
crate::cli::print_help();
1
}
}
}

View file

@ -25,13 +25,14 @@ mod service;
mod utils;
mod weblistener;
#[allow(non_snake_case,non_upper_case_globals,non_camel_case_types,dead_code,improper_ctypes)]
#[allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, improper_ctypes)]
mod osdep; // bindgen generated
use std::boxed::Box;
use std::sync::Arc;
use crate::store::Store;
use clap::ArgMatches;
fn main() {
let mut process_exit_value: i32 = 0;
@ -85,18 +86,34 @@ fn main() {
drop(zerotier_path);
match cli_args.as_ref().subcommand_name().unwrap() {
"version" => {
match cli_args.subcommand() {
("help", None) => {
cli::print_help()
}
("version", None) => {
let ver = zerotier_core::version();
println!("{}.{}.{}", ver.0, ver.1, ver.2);
},
"service" => {
}
("status", None) => {}
("set", Some(sub_cli_args)) => {}
("peer", Some(sub_cli_args)) => {}
("network", Some(sub_cli_args)) => {}
("join", Some(sub_cli_args)) => {}
("leave", Some(sub_cli_args)) => {}
("service", None) => {
drop(cli_args); // free unnecssary memory before launching service
process_exit_value = service::run(&store, auth_token);
},
_ => cli::print_help(), // includes "help"
}
("controller", Some(sub_cli_args)) => {}
("identity", Some(sub_cli_args)) => {}
("locator", Some(sub_cli_args)) => {}
("cert", Some(sub_cli_args)) => {
process_exit_value = crate::commands::cert::run(&store, sub_cli_args, &auth_token);
}
_ => {
cli::print_help();
process_exit_value = 1;
}
}
store.erase_pid();