mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-26 17:03:43 +02:00
Cleanup.
This commit is contained in:
parent
445a246506
commit
a708433146
17 changed files with 159 additions and 171 deletions
|
@ -674,6 +674,9 @@ enum ZT_CredentialType
|
||||||
/**
|
/**
|
||||||
* Endpoint address and protocol types
|
* 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
|
* Most of these are not currently implemented and are just reserved
|
||||||
* for future use.
|
* for future use.
|
||||||
*/
|
*/
|
||||||
|
@ -685,11 +688,16 @@ enum ZT_EndpointType
|
||||||
ZT_ENDPOINT_TYPE_WIFI_DIRECT = 3, /* Ethernet using WiFi direct */
|
ZT_ENDPOINT_TYPE_WIFI_DIRECT = 3, /* Ethernet using WiFi direct */
|
||||||
ZT_ENDPOINT_TYPE_BLUETOOTH = 4, /* Bluetooth (same address type as Ethernet) */
|
ZT_ENDPOINT_TYPE_BLUETOOTH = 4, /* Bluetooth (same address type as Ethernet) */
|
||||||
ZT_ENDPOINT_TYPE_IP = 5, /* Naked IP (protocol 193) */
|
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 = 7, /* IP/TCP */
|
||||||
ZT_ENDPOINT_TYPE_IP_TCP_WS = 8 /* IP/TCP web sockets */
|
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
|
* Flag indicating that VL1 tracing should be generated
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -61,27 +61,14 @@ impl PartialOrd for Address {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl serde::Serialize for Address {
|
impl serde::Serialize for Address {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer { serializer.serialize_str(self.to_string().as_str()) }
|
||||||
serializer.serialize_str(self.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AddressVisitor;
|
struct AddressVisitor;
|
||||||
|
|
||||||
impl<'de> serde::de::Visitor<'de> for AddressVisitor {
|
impl<'de> serde::de::Visitor<'de> for AddressVisitor {
|
||||||
type Value = Address;
|
type Value = Address;
|
||||||
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("ZeroTier Address in string format") }
|
||||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error { Ok(Address::from(s)) }
|
||||||
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 {
|
impl<'de> serde::Deserialize<'de> for Address {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> { deserializer.deserialize_str(AddressVisitor) }
|
||||||
deserializer.deserialize_str(AddressVisitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -766,7 +766,7 @@ mod tests {
|
||||||
});
|
});
|
||||||
cert.subject.networks.push(CertificateNetwork{
|
cert.subject.networks.push(CertificateNetwork{
|
||||||
id: NetworkId(0xdeadbeef),
|
id: NetworkId(0xdeadbeef),
|
||||||
controller: id0.fingerprint()
|
controller: Some(id0.fingerprint())
|
||||||
});
|
});
|
||||||
cert.subject.certificates.push(CertificateSerialNo::new());
|
cert.subject.certificates.push(CertificateSerialNo::new());
|
||||||
cert.subject.update_urls.push(String::from("http://foo.bar"));
|
cert.subject.update_urls.push(String::from("http://foo.bar"));
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
use std::os::raw::{c_char, c_int};
|
use std::os::raw::{c_char, c_int};
|
||||||
|
use std::ptr::copy_nonoverlapping;
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use crate::capi as ztcore;
|
use crate::capi as ztcore;
|
||||||
use std::ptr::copy_nonoverlapping;
|
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq)]
|
||||||
pub struct Fingerprint {
|
pub struct Fingerprint {
|
||||||
|
@ -54,15 +54,17 @@ impl Fingerprint {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_from_bytes(bytes: &[u8]) -> Result<Fingerprint, ResultCode> {
|
pub fn new_from_bytes(bytes: &[u8]) -> Result<Fingerprint, ResultCode> {
|
||||||
if bytes.len() < (5 + 48) {
|
if bytes.len() >= (5 + 48) {
|
||||||
let h: MaybeUninit<[u8; 48]> = MaybeUninit::uninit();
|
|
||||||
let mut fp = Fingerprint {
|
let mut fp = Fingerprint {
|
||||||
address: Address::from(bytes),
|
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::<u8>(), 48);
|
||||||
|
h.assume_init()
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
unsafe {
|
|
||||||
copy_nonoverlapping(bytes.as_ptr().offset(5), fp.hash.as_mut_ptr(), 48);
|
|
||||||
}
|
|
||||||
Ok(fp)
|
Ok(fp)
|
||||||
} else {
|
} else {
|
||||||
Err(ResultCode::ErrorBadParameter)
|
Err(ResultCode::ErrorBadParameter)
|
||||||
|
@ -74,10 +76,7 @@ impl ToString for Fingerprint {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
let mut buf: [u8; 256] = [0; 256];
|
let mut buf: [u8; 256] = [0; 256];
|
||||||
unsafe {
|
unsafe {
|
||||||
if ztcore::ZT_Fingerprint_toString(&ztcore::ZT_Fingerprint {
|
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() {
|
||||||
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 String::from("(invalid)");
|
||||||
}
|
}
|
||||||
return cstr_to_string(buf.as_ptr() as *const c_char, 256);
|
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 {
|
impl serde::Serialize for Fingerprint {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer { serializer.serialize_str(self.to_string().as_str()) }
|
||||||
serializer.serialize_str(self.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FingerprintVisitor;
|
struct FingerprintVisitor;
|
||||||
|
|
||||||
impl<'de> serde::de::Visitor<'de> for FingerprintVisitor {
|
impl<'de> serde::de::Visitor<'de> for FingerprintVisitor {
|
||||||
type Value = Fingerprint;
|
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 {
|
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error {
|
||||||
let id = Fingerprint::new_from_string(s);
|
let id = Fingerprint::new_from_string(s);
|
||||||
if id.is_err() {
|
if id.is_err() {
|
||||||
|
@ -108,9 +99,6 @@ impl<'de> serde::de::Visitor<'de> for FingerprintVisitor {
|
||||||
return Ok(id.ok().unwrap() as Self::Value);
|
return Ok(id.ok().unwrap() as Self::Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> serde::Deserialize<'de> for Fingerprint {
|
impl<'de> serde::Deserialize<'de> for Fingerprint {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> { deserializer.deserialize_str(FingerprintVisitor) }
|
||||||
deserializer.deserialize_str(FingerprintVisitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,20 +178,12 @@ impl ToString for Identity {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl serde::Serialize for Identity {
|
impl serde::Serialize for Identity {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
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()) }
|
||||||
serializer.serialize_str(self.intl_to_string(false).as_str())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct IdentityVisitor;
|
struct IdentityVisitor;
|
||||||
|
|
||||||
impl<'de> serde::de::Visitor<'de> for IdentityVisitor {
|
impl<'de> serde::de::Visitor<'de> for IdentityVisitor {
|
||||||
type Value = Identity;
|
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 {
|
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error {
|
||||||
let id = Identity::new_from_string(s);
|
let id = Identity::new_from_string(s);
|
||||||
if id.is_err() {
|
if id.is_err() {
|
||||||
|
@ -200,11 +192,8 @@ impl<'de> serde::de::Visitor<'de> for IdentityVisitor {
|
||||||
return Ok(id.ok().unwrap() as Self::Value);
|
return Ok(id.ok().unwrap() as Self::Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> serde::Deserialize<'de> for Identity {
|
impl<'de> serde::Deserialize<'de> for Identity {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> { deserializer.deserialize_str(IdentityVisitor) }
|
||||||
deserializer.deserialize_str(IdentityVisitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::mem::{MaybeUninit, transmute};
|
use std::mem::{MaybeUninit, transmute};
|
||||||
|
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||||
use std::os::raw::{c_uint, c_void};
|
use std::os::raw::{c_uint, c_void};
|
||||||
|
|
||||||
use num_derive::{FromPrimitive, ToPrimitive};
|
use num_derive::{FromPrimitive, ToPrimitive};
|
||||||
|
@ -21,7 +22,6 @@ use num_traits::FromPrimitive;
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use crate::capi as ztcore;
|
use crate::capi as ztcore;
|
||||||
use std::net::{SocketAddr, IpAddr, Ipv4Addr};
|
|
||||||
|
|
||||||
// WARNING: here be dragons! This defines an opaque blob in Rust that shadows
|
// 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
|
// 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 Eq for InetAddress {}
|
||||||
|
|
||||||
impl serde::Serialize for InetAddress {
|
impl serde::Serialize for InetAddress {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer { serializer.serialize_str(self.to_string().as_str()) }
|
||||||
serializer.serialize_str(self.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InetAddressVisitor;
|
struct InetAddressVisitor;
|
||||||
|
|
||||||
impl<'de> serde::de::Visitor<'de> for InetAddressVisitor {
|
impl<'de> serde::de::Visitor<'de> for InetAddressVisitor {
|
||||||
type Value = InetAddress;
|
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 {
|
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error {
|
||||||
let id = InetAddress::new_from_string(s);
|
let id = InetAddress::new_from_string(s);
|
||||||
if id.is_none() {
|
if id.is_none() {
|
||||||
|
@ -346,11 +338,8 @@ impl<'de> serde::de::Visitor<'de> for InetAddressVisitor {
|
||||||
return Ok(id.unwrap() as Self::Value);
|
return Ok(id.unwrap() as Self::Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> serde::Deserialize<'de> for InetAddress {
|
impl<'de> serde::Deserialize<'de> for InetAddress {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> { deserializer.deserialize_str(InetAddressVisitor) }
|
||||||
deserializer.deserialize_str(InetAddressVisitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -177,8 +177,7 @@ pub fn random() -> u64 {
|
||||||
|
|
||||||
/// Test whether this byte array or slice is all zeroes.
|
/// Test whether this byte array or slice is all zeroes.
|
||||||
pub fn is_all_zeroes<B: AsRef<[u8]>>(b: B) -> bool {
|
pub fn is_all_zeroes<B: AsRef<[u8]>>(b: B) -> bool {
|
||||||
let bb = b.as_ref();
|
for c in b.as_ref().iter() {
|
||||||
for c in bb.iter() {
|
|
||||||
if *c != 0 {
|
if *c != 0 {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ impl Locator {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn timestamp(&self) -> i64 {
|
pub fn timestamp(&self) -> i64 {
|
||||||
unsafe {
|
unsafe {
|
||||||
return ztcore::ZT_Locator_timestamp(self.capi) as i64;
|
ztcore::ZT_Locator_timestamp(self.capi) as i64
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
impl Ord for MAC {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
fn cmp(&self, other: &Self) -> Ordering { self.0.cmp(&other.0) }
|
||||||
self.0.cmp(&other.0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialOrd for MAC {
|
impl PartialOrd for MAC {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.0.cmp(&other.0)) }
|
||||||
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;
|
struct AddressVisitor;
|
||||||
|
|
||||||
impl<'de> serde::de::Visitor<'de> for AddressVisitor {
|
impl<'de> serde::de::Visitor<'de> for AddressVisitor {
|
||||||
type Value = MAC;
|
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 expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error { Ok(MAC::from(s)) }
|
||||||
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 {
|
impl<'de> serde::Deserialize<'de> for MAC {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> { deserializer.deserialize_str(AddressVisitor) }
|
||||||
deserializer.deserialize_str(AddressVisitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,10 @@ impl Ord for MulticastGroup {
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
let o1 = self.mac.0.cmp(&other.mac.0);
|
let o1 = self.mac.0.cmp(&other.mac.0);
|
||||||
if o1 == Ordering::Equal {
|
if o1 == Ordering::Equal {
|
||||||
return self.adi.cmp(&other.adi);
|
self.adi.cmp(&other.adi)
|
||||||
|
} else {
|
||||||
|
o1
|
||||||
}
|
}
|
||||||
o1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,27 +58,14 @@ impl PartialOrd for NetworkId {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl serde::Serialize for NetworkId {
|
impl serde::Serialize for NetworkId {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer { serializer.serialize_str(self.to_string().as_str()) }
|
||||||
serializer.serialize_str(self.to_string().as_str())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NetworkIdVisitor;
|
struct NetworkIdVisitor;
|
||||||
|
|
||||||
impl<'de> serde::de::Visitor<'de> for NetworkIdVisitor {
|
impl<'de> serde::de::Visitor<'de> for NetworkIdVisitor {
|
||||||
type Value = NetworkId;
|
type Value = NetworkId;
|
||||||
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("ZeroTier Address in string format") }
|
||||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error { Ok(NetworkId::new_from_string(s)) }
|
||||||
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 {
|
impl<'de> serde::Deserialize<'de> for NetworkId {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> { deserializer.deserialize_str(NetworkIdVisitor) }
|
||||||
deserializer.deserialize_str(NetworkIdVisitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use serde::{Deserialize, Serialize};
|
||||||
use crate::Endpoint;
|
use crate::Endpoint;
|
||||||
use crate::capi as ztcore;
|
use crate::capi as ztcore;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
pub struct Path {
|
pub struct Path {
|
||||||
pub endpoint: Endpoint,
|
pub endpoint: Endpoint,
|
||||||
#[serde(rename = "lastSend")]
|
#[serde(rename = "lastSend")]
|
||||||
|
|
|
@ -15,7 +15,7 @@ use serde::{Deserialize, Serialize};
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use crate::capi as ztcore;
|
use crate::capi as ztcore;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
pub struct Peer {
|
pub struct Peer {
|
||||||
pub address: Address,
|
pub address: Address,
|
||||||
pub identity: Identity,
|
pub identity: Identity,
|
||||||
|
@ -36,7 +36,6 @@ pub struct Peer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Peer {
|
impl Peer {
|
||||||
#[inline(always)]
|
|
||||||
pub(crate) fn new_from_capi(p: &ztcore::ZT_Peer) -> Peer {
|
pub(crate) fn new_from_capi(p: &ztcore::ZT_Peer) -> Peer {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut networks: Vec<NetworkId> = Vec::new();
|
let mut networks: Vec<NetworkId> = Vec::new();
|
||||||
|
@ -57,8 +56,8 @@ impl Peer {
|
||||||
version_proto: p.versionProto as i32,
|
version_proto: p.versionProto as i32,
|
||||||
latency: p.latency as i32,
|
latency: p.latency as i32,
|
||||||
root: p.root != 0,
|
root: p.root != 0,
|
||||||
networks: networks,
|
networks,
|
||||||
paths: paths,
|
paths,
|
||||||
locator: if p.locator.is_null() { None } else { Some(Locator::new_from_capi(p.locator, false).clone() )}
|
locator: if p.locator.is_null() { None } else { Some(Locator::new_from_capi(p.locator, false).clone() )}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,10 +208,10 @@ pub(crate) fn parse_cli_args() -> ArgMatches<'static> {
|
||||||
.arg(Arg::with_name("identity").index(1).required(true)))
|
.arg(Arg::with_name("identity").index(1).required(true)))
|
||||||
.subcommand(App::new("sign")
|
.subcommand(App::new("sign")
|
||||||
.arg(Arg::with_name("identity").index(1).required(true))
|
.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")
|
.subcommand(App::new("verify")
|
||||||
.arg(Arg::with_name("identity").index(1).required(true))
|
.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))))
|
.arg(Arg::with_name("signature").index(3).required(true))))
|
||||||
.subcommand(App::new("locator")
|
.subcommand(App::new("locator")
|
||||||
.subcommand(App::new("new")
|
.subcommand(App::new("new")
|
||||||
|
|
|
@ -15,18 +15,7 @@ use clap::ArgMatches;
|
||||||
use crate::store::Store;
|
use crate::store::Store;
|
||||||
use zerotier_core::{IdentityType, Identity};
|
use zerotier_core::{IdentityType, Identity};
|
||||||
|
|
||||||
/*
|
fn new_(cli_args: &ArgMatches) -> i32 {
|
||||||
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 {
|
|
||||||
let id_type = cli_args.value_of("type").map_or(IdentityType::Curve25519, |idt| {
|
let id_type = cli_args.value_of("type").map_or(IdentityType::Curve25519, |idt| {
|
||||||
match idt {
|
match idt {
|
||||||
"p384" => IdentityType::NistP384,
|
"p384" => IdentityType::NistP384,
|
||||||
|
@ -42,34 +31,101 @@ fn new_<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getpublic<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 {
|
fn getpublic(cli_args: &ArgMatches) -> i32 {
|
||||||
0
|
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 {
|
||||||
0
|
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 {
|
||||||
0
|
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 {
|
||||||
0
|
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 {
|
||||||
0
|
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() {
|
match cli_args.subcommand() {
|
||||||
("new", Some(sub_cli_args)) => new_(store, sub_cli_args),
|
("new", Some(sub_cli_args)) => new_(sub_cli_args),
|
||||||
("getpublic", Some(sub_cli_args)) => getpublic(store, sub_cli_args),
|
("getpublic", Some(sub_cli_args)) => getpublic(sub_cli_args),
|
||||||
("fingerprint", Some(sub_cli_args)) => fingerprint(store, sub_cli_args),
|
("fingerprint", Some(sub_cli_args)) => fingerprint(sub_cli_args),
|
||||||
("validate", Some(sub_cli_args)) => validate(store, sub_cli_args),
|
("validate", Some(sub_cli_args)) => validate(sub_cli_args),
|
||||||
("sign", Some(sub_cli_args)) => sign(store, sub_cli_args),
|
("sign", Some(sub_cli_args)) => sign(sub_cli_args),
|
||||||
("verify", Some(sub_cli_args)) => verify(store, sub_cli_args),
|
("verify", Some(sub_cli_args)) => verify(sub_cli_args),
|
||||||
_ => {
|
_ => {
|
||||||
crate::cli::print_help();
|
crate::cli::print_help();
|
||||||
1
|
1
|
||||||
|
|
|
@ -17,7 +17,7 @@ use zerotier_core::*;
|
||||||
|
|
||||||
use crate::store::Store;
|
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| {
|
let timestamp = cli_args.value_of("timestamp").map_or(crate::utils::ms_since_epoch(), |ts| {
|
||||||
if ts.is_empty() {
|
if ts.is_empty() {
|
||||||
0_i64
|
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);
|
let identity = crate::utils::read_identity(cli_args.value_of("identity").unwrap(), true);
|
||||||
if identity.is_err() {
|
if identity.is_err() {
|
||||||
println!("ERROR: identity invalid: {}", identity.err().unwrap());
|
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());
|
let locator = crate::utils::read_locator(cli_args.value_of("locator").unwrap());
|
||||||
if locator.is_err() {
|
if locator.is_err() {
|
||||||
println!("ERROR: locator invalid: {}", locator.err().unwrap());
|
println!("ERROR: locator invalid: {}", locator.err().unwrap());
|
||||||
|
@ -105,11 +105,11 @@ fn show<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 {
|
||||||
0
|
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() {
|
match cli_args.subcommand() {
|
||||||
("new", Some(sub_cli_args)) => new_(store, sub_cli_args),
|
("new", Some(sub_cli_args)) => new_(sub_cli_args),
|
||||||
("verify", Some(sub_cli_args)) => verify(store, sub_cli_args),
|
("verify", Some(sub_cli_args)) => verify(sub_cli_args),
|
||||||
("show", Some(sub_cli_args)) => show(store, sub_cli_args),
|
("show", Some(sub_cli_args)) => show(sub_cli_args),
|
||||||
_ => {
|
_ => {
|
||||||
crate::cli::print_help();
|
crate::cli::print_help();
|
||||||
1
|
1
|
||||||
|
|
|
@ -44,6 +44,10 @@ struct ServiceIntl {
|
||||||
online: AtomicBool,
|
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.
|
/// Core ZeroTier service, which is sort of just a container for all the things.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct Service {
|
pub(crate) struct Service {
|
||||||
|
@ -133,8 +137,7 @@ impl NodeEventHandler<Network> for Service {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn path_lookup(&self, address: Address, id: &Identity, desired_family: InetAddressFamily) -> Option<InetAddress> {
|
fn path_lookup(&self, address: Address, id: &Identity, desired_family: InetAddressFamily) -> Option<InetAddress> {
|
||||||
let lc = self.local_config();
|
let lc = self.local_config();
|
||||||
let vc = lc.virtual_.get(&address);
|
lc.virtual_.get(&address).map_or(None, |c: &LocalConfigVirtualConfig| {
|
||||||
vc.map_or(None, |c: &LocalConfigVirtualConfig| {
|
|
||||||
if c.try_.is_empty() {
|
if c.try_.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} 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 {
|
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 local_config = Arc::new(store.read_local_conf(false).unwrap_or_else(|_| { LocalConfig::default() }));
|
||||||
|
|
||||||
let log = Arc::new(Log::new(
|
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 {
|
let auth_token = auth_token.unwrap_or_else(|| -> String {
|
||||||
d!(log, "authtoken.secret not found, generating new...");
|
d!(log, "authtoken.secret not found, generating new...");
|
||||||
let mut rb = [0_u8; 32];
|
let mut rb = [0_u8; 32];
|
||||||
|
@ -458,6 +455,11 @@ pub(crate) fn run(store: &Arc<Store>, auth_token: Option<String>) -> i32 {
|
||||||
return 1;
|
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 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 });
|
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));
|
rt.shutdown_timeout(Duration::from_millis(500));
|
||||||
|
|
Loading…
Add table
Reference in a new issue