From a708433146807f73cfcc556f6cbba2d181f8cf6b Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Sun, 14 Mar 2021 11:46:16 -0400 Subject: [PATCH] Cleanup. --- core/zerotier.h | 10 +- rust-zerotier-core/src/address.rs | 21 +---- rust-zerotier-core/src/certificate.rs | 2 +- rust-zerotier-core/src/fingerprint.rs | 38 +++----- rust-zerotier-core/src/identity.rs | 17 +--- rust-zerotier-core/src/inetaddress.rs | 19 +--- rust-zerotier-core/src/lib.rs | 3 +- rust-zerotier-core/src/locator.rs | 2 +- rust-zerotier-core/src/mac.rs | 33 ++----- rust-zerotier-core/src/multicastgroup.rs | 5 +- rust-zerotier-core/src/networkid.rs | 21 +---- rust-zerotier-core/src/path.rs | 2 +- rust-zerotier-core/src/peer.rs | 7 +- service/src/cli.rs | 4 +- service/src/commands/identity.rs | 114 +++++++++++++++++------ service/src/commands/locator.rs | 14 +-- service/src/service.rs | 18 ++-- 17 files changed, 159 insertions(+), 171 deletions(-) diff --git a/core/zerotier.h b/core/zerotier.h index b210c96b4..9cdb115a6 100644 --- a/core/zerotier.h +++ b/core/zerotier.h @@ -674,6 +674,9 @@ enum ZT_CredentialType /** * Endpoint address and protocol types * + * Do not change these. They're used as protocol constants and the + * fact that IP types start at 5 is exploited in the code. + * * Most of these are not currently implemented and are just reserved * for future use. */ @@ -685,11 +688,16 @@ enum ZT_EndpointType ZT_ENDPOINT_TYPE_WIFI_DIRECT = 3, /* Ethernet using WiFi direct */ ZT_ENDPOINT_TYPE_BLUETOOTH = 4, /* Bluetooth (same address type as Ethernet) */ ZT_ENDPOINT_TYPE_IP = 5, /* Naked IP (protocol 193) */ - ZT_ENDPOINT_TYPE_IP_UDP = 6, /* IP/UDP */ + ZT_ENDPOINT_TYPE_IP_UDP = 6, /* IP/UDP (the default and original) */ ZT_ENDPOINT_TYPE_IP_TCP = 7, /* IP/TCP */ ZT_ENDPOINT_TYPE_IP_TCP_WS = 8 /* IP/TCP web sockets */ }; +/** + * Maximum numeric value of the ZT_EndpointType enum. + */ +#define ZT_ENDPOINT_TYPE__MAX 8 + /** * Flag indicating that VL1 tracing should be generated */ diff --git a/rust-zerotier-core/src/address.rs b/rust-zerotier-core/src/address.rs index 693d34da2..1e46e3c1b 100644 --- a/rust-zerotier-core/src/address.rs +++ b/rust-zerotier-core/src/address.rs @@ -61,27 +61,14 @@ impl PartialOrd for Address { } impl serde::Serialize for Address { - fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - serializer.serialize_str(self.to_string().as_str()) - } + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { serializer.serialize_str(self.to_string().as_str()) } } - struct AddressVisitor; - impl<'de> serde::de::Visitor<'de> for AddressVisitor { type Value = Address; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("ZeroTier Address in string format") - } - - fn visit_str(self, s: &str) -> Result where E: serde::de::Error { - Ok(Address::from(s)) - } + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("ZeroTier Address in string format") } + fn visit_str(self, s: &str) -> Result where E: serde::de::Error { Ok(Address::from(s)) } } - impl<'de> serde::Deserialize<'de> for Address { - fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { - deserializer.deserialize_str(AddressVisitor) - } + fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { deserializer.deserialize_str(AddressVisitor) } } diff --git a/rust-zerotier-core/src/certificate.rs b/rust-zerotier-core/src/certificate.rs index 9d930098c..4b87a4bd2 100644 --- a/rust-zerotier-core/src/certificate.rs +++ b/rust-zerotier-core/src/certificate.rs @@ -766,7 +766,7 @@ mod tests { }); cert.subject.networks.push(CertificateNetwork{ id: NetworkId(0xdeadbeef), - controller: id0.fingerprint() + controller: Some(id0.fingerprint()) }); cert.subject.certificates.push(CertificateSerialNo::new()); cert.subject.update_urls.push(String::from("http://foo.bar")); diff --git a/rust-zerotier-core/src/fingerprint.rs b/rust-zerotier-core/src/fingerprint.rs index eb62b2b0a..4d6ea716c 100644 --- a/rust-zerotier-core/src/fingerprint.rs +++ b/rust-zerotier-core/src/fingerprint.rs @@ -14,10 +14,10 @@ use std::ffi::CString; use std::mem::MaybeUninit; use std::os::raw::{c_char, c_int}; +use std::ptr::copy_nonoverlapping; use crate::*; use crate::capi as ztcore; -use std::ptr::copy_nonoverlapping; #[derive(PartialEq, Eq)] pub struct Fingerprint { @@ -54,15 +54,17 @@ impl Fingerprint { } pub fn new_from_bytes(bytes: &[u8]) -> Result { - if bytes.len() < (5 + 48) { - let h: MaybeUninit<[u8; 48]> = MaybeUninit::uninit(); + if bytes.len() >= (5 + 48) { let mut fp = Fingerprint { address: Address::from(bytes), - hash: unsafe { h.assume_init() }, + hash: { + let mut h: MaybeUninit<[u8; 48]> = MaybeUninit::uninit(); + unsafe { + copy_nonoverlapping(bytes.as_ptr().offset(5), h.as_mut_ptr().cast::(), 48); + h.assume_init() + } + }, }; - unsafe { - copy_nonoverlapping(bytes.as_ptr().offset(5), fp.hash.as_mut_ptr(), 48); - } Ok(fp) } else { Err(ResultCode::ErrorBadParameter) @@ -74,10 +76,7 @@ impl ToString for Fingerprint { fn to_string(&self) -> String { let mut buf: [u8; 256] = [0; 256]; unsafe { - if ztcore::ZT_Fingerprint_toString(&ztcore::ZT_Fingerprint { - address: self.address.0, - hash: self.hash - }, buf.as_mut_ptr() as *mut c_char, buf.len() as c_int).is_null() { + if ztcore::ZT_Fingerprint_toString(&ztcore::ZT_Fingerprint { address: self.address.0, hash: self.hash }, buf.as_mut_ptr() as *mut c_char, buf.len() as c_int).is_null() { return String::from("(invalid)"); } return cstr_to_string(buf.as_ptr() as *const c_char, 256); @@ -86,20 +85,12 @@ impl ToString for Fingerprint { } impl serde::Serialize for Fingerprint { - fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - serializer.serialize_str(self.to_string().as_str()) - } + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { serializer.serialize_str(self.to_string().as_str()) } } - struct FingerprintVisitor; - impl<'de> serde::de::Visitor<'de> for FingerprintVisitor { type Value = Fingerprint; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("ZeroTier Fingerprint in string format") - } - + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("ZeroTier Fingerprint in string format") } fn visit_str(self, s: &str) -> Result where E: serde::de::Error { let id = Fingerprint::new_from_string(s); if id.is_err() { @@ -108,9 +99,6 @@ impl<'de> serde::de::Visitor<'de> for FingerprintVisitor { return Ok(id.ok().unwrap() as Self::Value); } } - impl<'de> serde::Deserialize<'de> for Fingerprint { - fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { - deserializer.deserialize_str(FingerprintVisitor) - } + fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { deserializer.deserialize_str(FingerprintVisitor) } } diff --git a/rust-zerotier-core/src/identity.rs b/rust-zerotier-core/src/identity.rs index 90f5a01f4..8943a71b1 100644 --- a/rust-zerotier-core/src/identity.rs +++ b/rust-zerotier-core/src/identity.rs @@ -178,20 +178,12 @@ impl ToString for Identity { } impl serde::Serialize for Identity { - fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - serializer.serialize_str(self.intl_to_string(false).as_str()) - } + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { serializer.serialize_str(self.intl_to_string(false).as_str()) } } - struct IdentityVisitor; - impl<'de> serde::de::Visitor<'de> for IdentityVisitor { type Value = Identity; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("ZeroTier Identity in string format") - } - + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("ZeroTier Identity in string format") } fn visit_str(self, s: &str) -> Result where E: serde::de::Error { let id = Identity::new_from_string(s); if id.is_err() { @@ -200,11 +192,8 @@ impl<'de> serde::de::Visitor<'de> for IdentityVisitor { return Ok(id.ok().unwrap() as Self::Value); } } - impl<'de> serde::Deserialize<'de> for Identity { - fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { - deserializer.deserialize_str(IdentityVisitor) - } + fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { deserializer.deserialize_str(IdentityVisitor) } } #[cfg(test)] diff --git a/rust-zerotier-core/src/inetaddress.rs b/rust-zerotier-core/src/inetaddress.rs index b19dad79f..80a1f5e49 100644 --- a/rust-zerotier-core/src/inetaddress.rs +++ b/rust-zerotier-core/src/inetaddress.rs @@ -14,6 +14,7 @@ use std::cmp::Ordering; use std::ffi::CString; use std::mem::{MaybeUninit, transmute}; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::os::raw::{c_uint, c_void}; use num_derive::{FromPrimitive, ToPrimitive}; @@ -21,7 +22,6 @@ use num_traits::FromPrimitive; use crate::*; use crate::capi as ztcore; -use std::net::{SocketAddr, IpAddr, Ipv4Addr}; // 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 @@ -324,20 +324,12 @@ impl PartialEq for InetAddress { impl Eq for InetAddress {} impl serde::Serialize for InetAddress { - fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - serializer.serialize_str(self.to_string().as_str()) - } + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { serializer.serialize_str(self.to_string().as_str()) } } - struct InetAddressVisitor; - impl<'de> serde::de::Visitor<'de> for InetAddressVisitor { type Value = InetAddress; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("InetAddress value in string form") - } - + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("InetAddress value in string form") } fn visit_str(self, s: &str) -> Result where E: serde::de::Error { let id = InetAddress::new_from_string(s); if id.is_none() { @@ -346,11 +338,8 @@ impl<'de> serde::de::Visitor<'de> for InetAddressVisitor { return Ok(id.unwrap() as Self::Value); } } - impl<'de> serde::Deserialize<'de> for InetAddress { - fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { - deserializer.deserialize_str(InetAddressVisitor) - } + fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { deserializer.deserialize_str(InetAddressVisitor) } } #[cfg(test)] diff --git a/rust-zerotier-core/src/lib.rs b/rust-zerotier-core/src/lib.rs index 39227f17c..f568a8eb7 100644 --- a/rust-zerotier-core/src/lib.rs +++ b/rust-zerotier-core/src/lib.rs @@ -177,8 +177,7 @@ pub fn random() -> u64 { /// Test whether this byte array or slice is all zeroes. pub fn is_all_zeroes>(b: B) -> bool { - let bb = b.as_ref(); - for c in bb.iter() { + for c in b.as_ref().iter() { if *c != 0 { return false; } diff --git a/rust-zerotier-core/src/locator.rs b/rust-zerotier-core/src/locator.rs index b31132305..78ff55cb3 100644 --- a/rust-zerotier-core/src/locator.rs +++ b/rust-zerotier-core/src/locator.rs @@ -66,7 +66,7 @@ impl Locator { #[inline(always)] pub fn timestamp(&self) -> i64 { unsafe { - return ztcore::ZT_Locator_timestamp(self.capi) as i64; + ztcore::ZT_Locator_timestamp(self.capi) as i64 } } diff --git a/rust-zerotier-core/src/mac.rs b/rust-zerotier-core/src/mac.rs index 572c18933..48e1b7120 100644 --- a/rust-zerotier-core/src/mac.rs +++ b/rust-zerotier-core/src/mac.rs @@ -35,42 +35,25 @@ impl From<&str> for MAC { } } -impl serde::Serialize for MAC { - fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - serializer.serialize_str(self.to_string().as_str()) - } -} - impl Ord for MAC { #[inline(always)] - fn cmp(&self, other: &Self) -> Ordering { - self.0.cmp(&other.0) - } + fn cmp(&self, other: &Self) -> Ordering { self.0.cmp(&other.0) } } impl PartialOrd for MAC { #[inline(always)] - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.0.cmp(&other.0)) - } + fn partial_cmp(&self, other: &Self) -> Option { Some(self.0.cmp(&other.0)) } } +impl serde::Serialize for MAC { + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { serializer.serialize_str(self.to_string().as_str()) } +} struct AddressVisitor; - impl<'de> serde::de::Visitor<'de> for AddressVisitor { type Value = MAC; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("Ethernet MAC address in string format (with or without : separators)") - } - - fn visit_str(self, s: &str) -> Result where E: serde::de::Error { - Ok(MAC::from(s)) - } + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("Ethernet MAC address in string format (with or without : separators)") } + fn visit_str(self, s: &str) -> Result where E: serde::de::Error { Ok(MAC::from(s)) } } - impl<'de> serde::Deserialize<'de> for MAC { - fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { - deserializer.deserialize_str(AddressVisitor) - } + fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { deserializer.deserialize_str(AddressVisitor) } } diff --git a/rust-zerotier-core/src/multicastgroup.rs b/rust-zerotier-core/src/multicastgroup.rs index 0154902a3..99e595be1 100644 --- a/rust-zerotier-core/src/multicastgroup.rs +++ b/rust-zerotier-core/src/multicastgroup.rs @@ -25,9 +25,10 @@ impl Ord for MulticastGroup { fn cmp(&self, other: &Self) -> Ordering { let o1 = self.mac.0.cmp(&other.mac.0); if o1 == Ordering::Equal { - return self.adi.cmp(&other.adi); + self.adi.cmp(&other.adi) + } else { + o1 } - o1 } } diff --git a/rust-zerotier-core/src/networkid.rs b/rust-zerotier-core/src/networkid.rs index e4379ea47..ec2a7b0dc 100644 --- a/rust-zerotier-core/src/networkid.rs +++ b/rust-zerotier-core/src/networkid.rs @@ -58,27 +58,14 @@ impl PartialOrd for NetworkId { } impl serde::Serialize for NetworkId { - fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { - serializer.serialize_str(self.to_string().as_str()) - } + fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { serializer.serialize_str(self.to_string().as_str()) } } - struct NetworkIdVisitor; - impl<'de> serde::de::Visitor<'de> for NetworkIdVisitor { type Value = NetworkId; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("ZeroTier Address in string format") - } - - fn visit_str(self, s: &str) -> Result where E: serde::de::Error { - Ok(NetworkId::new_from_string(s)) - } + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("ZeroTier Address in string format") } + fn visit_str(self, s: &str) -> Result where E: serde::de::Error { Ok(NetworkId::new_from_string(s)) } } - impl<'de> serde::Deserialize<'de> for NetworkId { - fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { - deserializer.deserialize_str(NetworkIdVisitor) - } + fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { deserializer.deserialize_str(NetworkIdVisitor) } } diff --git a/rust-zerotier-core/src/path.rs b/rust-zerotier-core/src/path.rs index 8bac4cfd8..9fcb5a7da 100644 --- a/rust-zerotier-core/src/path.rs +++ b/rust-zerotier-core/src/path.rs @@ -15,7 +15,7 @@ use serde::{Deserialize, Serialize}; use crate::Endpoint; use crate::capi as ztcore; -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Clone)] pub struct Path { pub endpoint: Endpoint, #[serde(rename = "lastSend")] diff --git a/rust-zerotier-core/src/peer.rs b/rust-zerotier-core/src/peer.rs index 322c45ed4..0458621ee 100644 --- a/rust-zerotier-core/src/peer.rs +++ b/rust-zerotier-core/src/peer.rs @@ -15,7 +15,7 @@ use serde::{Deserialize, Serialize}; use crate::*; use crate::capi as ztcore; -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Clone)] pub struct Peer { pub address: Address, pub identity: Identity, @@ -36,7 +36,6 @@ pub struct Peer { } impl Peer { - #[inline(always)] pub(crate) fn new_from_capi(p: &ztcore::ZT_Peer) -> Peer { unsafe { let mut networks: Vec = Vec::new(); @@ -57,8 +56,8 @@ impl Peer { version_proto: p.versionProto as i32, latency: p.latency as i32, root: p.root != 0, - networks: networks, - paths: paths, + networks, + paths, locator: if p.locator.is_null() { None } else { Some(Locator::new_from_capi(p.locator, false).clone() )} } } diff --git a/service/src/cli.rs b/service/src/cli.rs index 9f748fc6d..1916c198b 100644 --- a/service/src/cli.rs +++ b/service/src/cli.rs @@ -208,10 +208,10 @@ pub(crate) fn parse_cli_args() -> ArgMatches<'static> { .arg(Arg::with_name("identity").index(1).required(true))) .subcommand(App::new("sign") .arg(Arg::with_name("identity").index(1).required(true)) - .arg(Arg::with_name("file").index(2).required(true))) + .arg(Arg::with_name("path").index(2).required(true))) .subcommand(App::new("verify") .arg(Arg::with_name("identity").index(1).required(true)) - .arg(Arg::with_name("file").index(2).required(true)) + .arg(Arg::with_name("path").index(2).required(true)) .arg(Arg::with_name("signature").index(3).required(true)))) .subcommand(App::new("locator") .subcommand(App::new("new") diff --git a/service/src/commands/identity.rs b/service/src/commands/identity.rs index 6a9a3cbcd..31f0f5347 100644 --- a/service/src/commands/identity.rs +++ b/service/src/commands/identity.rs @@ -15,18 +15,7 @@ use clap::ArgMatches; use crate::store::Store; use zerotier_core::{IdentityType, Identity}; -/* - identity [args] - new [c25519 | p384] Create identity (default: c25519) - getpublic Extract public part of identity - fingerprint Get an identity's fingerprint - validate Locally validate an identity - sign Sign a file with an identity's key - verify Verify a signature - - */ - -fn new_<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 { +fn new_(cli_args: &ArgMatches) -> i32 { let id_type = cli_args.value_of("type").map_or(IdentityType::Curve25519, |idt| { match idt { "p384" => IdentityType::NistP384, @@ -42,34 +31,101 @@ fn new_<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 { 0 } -fn getpublic<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 { - 0 +fn getpublic(cli_args: &ArgMatches) -> i32 { + let identity = crate::utils::read_identity(cli_args.value_of("identity").unwrap_or(""), false); + identity.map_or_else(|e| { + println!("ERROR: identity invalid: {}", e.to_string()); + 1 + }, |id| { + println!("{}", id.to_string()); + 0 + }) } -fn fingerprint<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 { - 0 +fn fingerprint(cli_args: &ArgMatches) -> i32 { + let identity = crate::utils::read_identity(cli_args.value_of("identity").unwrap_or(""), false); + identity.map_or_else(|e| { + println!("ERROR: identity invalid: {}", e.to_string()); + 1 + }, |id| { + println!("{}", id.fingerprint().to_string()); + 0 + }) } -fn validate<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 { - 0 +fn validate(cli_args: &ArgMatches) -> i32 { + crate::utils::read_identity(cli_args.value_of("identity").unwrap_or(""), false).map_or_else(|e| { + println!("FAILED"); + 1 + }, |id| { + if id.validate() { + println!("OK"); + 0 + } else { + println!("FAILED"); + 1 + } + }) } -fn sign<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 { - 0 +fn sign(cli_args: &ArgMatches) -> i32 { + crate::utils::read_identity(cli_args.value_of("identity").unwrap_or(""), false).map_or_else(|e| { + println!("ERROR: invalid or unreadable identity: {}", e.as_str()); + 1 + }, |id| { + if id.has_private() { + std::fs::read(cli_args.value_of("path").unwrap()).map_or_else(|e| { + println!("ERROR: unable to read file: {}", e.to_string()); + 1 + }, |data| { + id.sign(data.as_slice()).map_or_else(|e| { + println!("ERROR: failed to sign: {}", e.to_str()); + 1 + }, |sig| { + println!("{}", hex::encode(sig.as_ref())); + 0 + }) + }) + } else { + println!("ERROR: identity must include secret key to sign."); + 1 + } + }) } -fn verify<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 { - 0 +fn verify(cli_args: &ArgMatches) -> i32 { + crate::utils::read_identity(cli_args.value_of("identity").unwrap_or(""), false).map_or_else(|e| { + println!("ERROR: invalid or unreadable identity: {}", e.as_str()); + 1 + }, |id| { + std::fs::read(cli_args.value_of("path").unwrap()).map_or_else(|e| { + println!("ERROR: unable to read file: {}", e.to_string()); + 1 + }, |data| { + hex::decode(cli_args.value_of("signature").unwrap()).map_or_else(|e| { + println!("FAILED"); + 1 + }, |sig| { + if id.verify(data.as_slice(), sig.as_slice()) { + println!("OK"); + 0 + } else { + println!("FAILED"); + 1 + } + }) + }) + }) } -pub(crate) fn run<'a>(store: &Store, cli_args: &ArgMatches<'a>, _: &Option) -> i32 { +pub(crate) fn run<'a>(_: &Store, cli_args: &ArgMatches<'a>, _: &Option) -> i32 { match cli_args.subcommand() { - ("new", Some(sub_cli_args)) => new_(store, sub_cli_args), - ("getpublic", Some(sub_cli_args)) => getpublic(store, sub_cli_args), - ("fingerprint", Some(sub_cli_args)) => fingerprint(store, sub_cli_args), - ("validate", Some(sub_cli_args)) => validate(store, sub_cli_args), - ("sign", Some(sub_cli_args)) => sign(store, sub_cli_args), - ("verify", Some(sub_cli_args)) => verify(store, sub_cli_args), + ("new", Some(sub_cli_args)) => new_(sub_cli_args), + ("getpublic", Some(sub_cli_args)) => getpublic(sub_cli_args), + ("fingerprint", Some(sub_cli_args)) => fingerprint(sub_cli_args), + ("validate", Some(sub_cli_args)) => validate(sub_cli_args), + ("sign", Some(sub_cli_args)) => sign(sub_cli_args), + ("verify", Some(sub_cli_args)) => verify(sub_cli_args), _ => { crate::cli::print_help(); 1 diff --git a/service/src/commands/locator.rs b/service/src/commands/locator.rs index 965cad4e1..7a779bf6b 100644 --- a/service/src/commands/locator.rs +++ b/service/src/commands/locator.rs @@ -17,7 +17,7 @@ use zerotier_core::*; use crate::store::Store; -fn new_<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 { +fn new_(cli_args: &ArgMatches) -> i32 { let timestamp = cli_args.value_of("timestamp").map_or(crate::utils::ms_since_epoch(), |ts| { if ts.is_empty() { 0_i64 @@ -69,7 +69,7 @@ fn new_<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 { }) } -fn verify<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 { +fn verify(cli_args: &ArgMatches) -> i32 { let identity = crate::utils::read_identity(cli_args.value_of("identity").unwrap(), true); if identity.is_err() { println!("ERROR: identity invalid: {}", identity.err().unwrap()); @@ -90,7 +90,7 @@ fn verify<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 { } } -fn show<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 { +fn show(cli_args: &ArgMatches) -> i32 { let locator = crate::utils::read_locator(cli_args.value_of("locator").unwrap()); if locator.is_err() { println!("ERROR: locator invalid: {}", locator.err().unwrap()); @@ -105,11 +105,11 @@ fn show<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 { 0 } -pub(crate) fn run<'a>(store: &Store, cli_args: &ArgMatches<'a>, _: &Option) -> i32 { +pub(crate) fn run<'a>(_: &Store, cli_args: &ArgMatches<'a>, _: &Option) -> i32 { match cli_args.subcommand() { - ("new", Some(sub_cli_args)) => new_(store, sub_cli_args), - ("verify", Some(sub_cli_args)) => verify(store, sub_cli_args), - ("show", Some(sub_cli_args)) => show(store, sub_cli_args), + ("new", Some(sub_cli_args)) => new_(sub_cli_args), + ("verify", Some(sub_cli_args)) => verify(sub_cli_args), + ("show", Some(sub_cli_args)) => show(sub_cli_args), _ => { crate::cli::print_help(); 1 diff --git a/service/src/service.rs b/service/src/service.rs index 97ad7a019..317164c29 100644 --- a/service/src/service.rs +++ b/service/src/service.rs @@ -44,6 +44,10 @@ struct ServiceIntl { online: AtomicBool, } +unsafe impl Send for ServiceIntl {} + +unsafe impl Sync for ServiceIntl {} + /// Core ZeroTier service, which is sort of just a container for all the things. #[derive(Clone)] pub(crate) struct Service { @@ -133,8 +137,7 @@ impl NodeEventHandler for Service { #[inline(always)] fn path_lookup(&self, address: Address, id: &Identity, desired_family: InetAddressFamily) -> Option { let lc = self.local_config(); - let vc = lc.virtual_.get(&address); - vc.map_or(None, |c: &LocalConfigVirtualConfig| { + lc.virtual_.get(&address).map_or(None, |c: &LocalConfigVirtualConfig| { if c.try_.is_empty() { None } else { @@ -415,11 +418,6 @@ async fn run_async(store: &Arc, auth_token: String, log: &Arc, local } pub(crate) fn run(store: &Arc, auth_token: Option) -> i32 { - if store.write_pid().is_err() { - eprintln!("FATAL: error writing to directory '{}': unable to write zerotier.pid", store.base_path.to_str().unwrap()); - return 1; - } - let local_config = Arc::new(store.read_local_conf(false).unwrap_or_else(|_| { LocalConfig::default() })); let log = Arc::new(Log::new( @@ -434,7 +432,6 @@ pub(crate) fn run(store: &Arc, auth_token: Option) -> i32 { "", )); - // Generate authtoken.secret from secure random bytes if not already set. let auth_token = auth_token.unwrap_or_else(|| -> String { d!(log, "authtoken.secret not found, generating new..."); let mut rb = [0_u8; 32]; @@ -458,6 +455,11 @@ pub(crate) fn run(store: &Arc, auth_token: Option) -> i32 { return 1; } + if store.write_pid().is_err() { + eprintln!("FATAL: error writing to directory '{}': unable to write zerotier.pid", store.base_path.to_str().unwrap()); + return 1; + } + let rt = tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap(); let process_exit_value = rt.block_on(async move { run_async(store, auth_token, &log, local_config).await }); rt.shutdown_timeout(Duration::from_millis(500));