This commit is contained in:
Adam Ierymenko 2021-03-14 11:46:16 -04:00
parent 445a246506
commit a708433146
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
17 changed files with 159 additions and 171 deletions

View file

@ -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
*/

View file

@ -61,27 +61,14 @@ impl PartialOrd for Address {
}
impl serde::Serialize for Address {
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 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<E>(self, s: &str) -> Result<Self::Value, E> 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<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error { Ok(Address::from(s)) }
}
impl<'de> serde::Deserialize<'de> for Address {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
deserializer.deserialize_str(AddressVisitor)
}
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> { deserializer.deserialize_str(AddressVisitor) }
}

View file

@ -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"));

View file

@ -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<Fingerprint, ResultCode> {
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), fp.hash.as_mut_ptr(), 48);
copy_nonoverlapping(bytes.as_ptr().offset(5), h.as_mut_ptr().cast::<u8>(), 48);
h.assume_init()
}
},
};
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<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 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<E>(self, s: &str) -> Result<Self::Value, E> 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<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
deserializer.deserialize_str(FingerprintVisitor)
}
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> { deserializer.deserialize_str(FingerprintVisitor) }
}

View file

@ -178,20 +178,12 @@ impl ToString for Identity {
}
impl serde::Serialize for Identity {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
serializer.serialize_str(self.intl_to_string(false).as_str())
}
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 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<E>(self, s: &str) -> Result<Self::Value, E> 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<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
deserializer.deserialize_str(IdentityVisitor)
}
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> { deserializer.deserialize_str(IdentityVisitor) }
}
#[cfg(test)]

View file

@ -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<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 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<E>(self, s: &str) -> Result<Self::Value, E> 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<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
deserializer.deserialize_str(InetAddressVisitor)
}
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> { deserializer.deserialize_str(InetAddressVisitor) }
}
#[cfg(test)]

View file

@ -177,8 +177,7 @@ pub fn random() -> u64 {
/// Test whether this byte array or slice is all zeroes.
pub fn is_all_zeroes<B: AsRef<[u8]>>(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;
}

View file

@ -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
}
}

View file

@ -35,42 +35,25 @@ impl From<&str> for MAC {
}
}
impl serde::Serialize for MAC {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 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<Ordering> {
Some(self.0.cmp(&other.0))
}
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.0.cmp(&other.0)) }
}
impl serde::Serialize for MAC {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 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<E>(self, s: &str) -> Result<Self::Value, E> 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<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error { Ok(MAC::from(s)) }
}
impl<'de> serde::Deserialize<'de> for MAC {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
deserializer.deserialize_str(AddressVisitor)
}
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> { deserializer.deserialize_str(AddressVisitor) }
}

View file

@ -25,10 +25,11 @@ 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
}
}
}
impl PartialOrd for MulticastGroup {

View file

@ -58,27 +58,14 @@ impl PartialOrd for NetworkId {
}
impl serde::Serialize for NetworkId {
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 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<E>(self, s: &str) -> Result<Self::Value, E> 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<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error { Ok(NetworkId::new_from_string(s)) }
}
impl<'de> serde::Deserialize<'de> for NetworkId {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
deserializer.deserialize_str(NetworkIdVisitor)
}
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> { deserializer.deserialize_str(NetworkIdVisitor) }
}

View file

@ -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")]

View file

@ -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<NetworkId> = 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() )}
}
}

View file

@ -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")

View file

@ -15,18 +15,7 @@ use clap::ArgMatches;
use crate::store::Store;
use zerotier_core::{IdentityType, Identity};
/*
identity <command> [args]
new [c25519 | p384] Create identity (default: c25519)
getpublic <identity> Extract public part of identity
fingerprint <identity> Get an identity's fingerprint
validate <identity> Locally validate an identity
sign <identity> <file> Sign a file with an identity's key
verify <identity> <file> <sig> 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 {
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 {
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 {
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 {
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 {
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<String>) -> i32 {
pub(crate) fn run<'a>(_: &Store, cli_args: &ArgMatches<'a>, _: &Option<String>) -> 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

View file

@ -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<String>) -> i32 {
pub(crate) fn run<'a>(_: &Store, cli_args: &ArgMatches<'a>, _: &Option<String>) -> 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

View file

@ -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<Network> for Service {
#[inline(always)]
fn path_lookup(&self, address: Address, id: &Identity, desired_family: InetAddressFamily) -> Option<InetAddress> {
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<Store>, auth_token: String, log: &Arc<Log>, local
}
pub(crate) fn run(store: &Arc<Store>, auth_token: Option<String>) -> 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<Store>, auth_token: Option<String>) -> 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<Store>, auth_token: Option<String>) -> 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));