build fixes

This commit is contained in:
Adam Ierymenko 2022-09-02 16:21:08 -04:00
parent 614b84ef40
commit 3770fcdc83
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
9 changed files with 102 additions and 38 deletions

View file

@ -5,6 +5,8 @@ use std::mem::{size_of, MaybeUninit};
use crate::util::pool::PoolFactory;
use zerotier_utils::varint;
/// An I/O buffer with extensions for efficiently reading and writing various objects.
///
/// WARNING: Structures can only be handled through raw read/write here if they are
@ -280,7 +282,7 @@ impl<const L: usize> Buffer<L> {
#[inline(always)]
pub fn append_varint(&mut self, i: u64) -> std::io::Result<()> {
crate::util::varint::write(self, i)
varint::write(self, i)
}
#[inline(always)]
@ -469,7 +471,7 @@ impl<const L: usize> Buffer<L> {
let c = *cursor;
if c < self.0 {
let mut a = &self.1[c..];
crate::util::varint::read(&mut a).map(|r| {
varint::read(&mut a).map(|r| {
*cursor = c + r.1;
debug_assert!(*cursor <= self.0);
r.0

View file

@ -6,9 +6,6 @@ pub(crate) mod gate;
pub mod marshalable;
pub(crate) mod pool;
pub use zerotier_core_crypto::hex;
pub use zerotier_core_crypto::varint;
/// A value for ticks that indicates that something never happened, and is thus very long before zero ticks.
pub(crate) const NEVER_HAPPENED_TICKS: i64 = -2147483648;
@ -55,8 +52,3 @@ pub(crate) fn bytes_as_flat_object<T: Copy + AlignmentNeutral>(b: &[u8]) -> &T {
assert!(b.len() >= std::mem::size_of::<T>());
unsafe { &*b.as_ptr().cast() }
}
/// Include this in a branch to hint the compiler that it's unlikely.
#[inline(never)]
#[cold]
pub(crate) extern "C" fn unlikely_branch() {}

View file

@ -8,10 +8,12 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::error::InvalidFormatError;
use crate::util::buffer::Buffer;
use crate::util::hex::HEX_CHARS;
use crate::util::marshalable::Marshalable;
use crate::vl1::protocol::{ADDRESS_RESERVED_PREFIX, ADDRESS_SIZE};
use zerotier_utils::hex;
use zerotier_utils::hex::HEX_CHARS;
/// A unique address on the global ZeroTier VL1 network.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[repr(transparent)]
@ -96,7 +98,7 @@ impl FromStr for Address {
type Err = InvalidFormatError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Address::from_bytes(crate::util::hex::from_string(s).as_slice()).map_or_else(|| Err(InvalidFormatError), |a| Ok(a))
Address::from_bytes(hex::from_string(s).as_slice()).map_or_else(|| Err(InvalidFormatError), |a| Ok(a))
}
}

View file

@ -5,7 +5,7 @@ use std::io::{Read, Write};
use crate::vl1::identity::Identity;
use crate::vl1::protocol::IDENTITY_FINGERPRINT_SIZE;
use zerotier_core_crypto::varint;
use zerotier_utils::varint;
/// A signed bundle of identity fingerprints of nodes through which a node might be reached (e.g. roots).
///

View file

@ -3,7 +3,8 @@
use std::collections::BTreeMap;
use std::io::Write;
use crate::util::hex::HEX_CHARS;
use zerotier_utils::hex;
use zerotier_utils::hex::HEX_CHARS;
const BOOL_TRUTH: &str = "1tTyY";
@ -104,7 +105,7 @@ impl Dictionary {
}
pub fn set_u64(&mut self, k: &str, v: u64) {
let _ = self.0.insert(String::from(k), crate::util::hex::to_vec_u64(v, true));
let _ = self.0.insert(String::from(k), hex::to_vec_u64(v, true));
}
pub fn set_bytes(&mut self, k: &str, v: Vec<u8>) {
@ -112,7 +113,14 @@ impl Dictionary {
}
pub fn set_bool(&mut self, k: &str, v: bool) {
let _ = self.0.insert(String::from(k), vec![if v { b'1' } else { b'0' }]);
let _ = self.0.insert(
String::from(k),
vec![if v {
b'1'
} else {
b'0'
}],
);
}
/// Write a dictionary in transport format to a writer.

View file

@ -9,12 +9,13 @@ use std::str::FromStr;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use zerotier_core_crypto::hash::*;
use zerotier_core_crypto::hex;
use zerotier_core_crypto::p384::*;
use zerotier_core_crypto::salsa::Salsa;
use zerotier_core_crypto::secret::Secret;
use zerotier_core_crypto::x25519::*;
use zerotier_utils::hex;
use crate::error::{InvalidFormatError, InvalidParameterError};
use crate::util::{bytes_as_flat_object, flat_object_as_bytes, AlignmentNeutral};
use crate::vl1::protocol::{ADDRESS_SIZE, ADDRESS_SIZE_STRING, IDENTITY_FINGERPRINT_SIZE, IDENTITY_POW_THRESHOLD};
@ -208,7 +209,8 @@ impl Identity {
let p384_ecdh = P384KeyPair::generate();
let p384_ecdsa = P384KeyPair::generate();
let mut self_sign_buf: Vec<u8> = Vec::with_capacity(ADDRESS_SIZE + C25519_PUBLIC_KEY_SIZE + ED25519_PUBLIC_KEY_SIZE + P384_PUBLIC_KEY_SIZE + P384_PUBLIC_KEY_SIZE + P384_ECDSA_SIGNATURE_SIZE + 4);
let mut self_sign_buf: Vec<u8> =
Vec::with_capacity(ADDRESS_SIZE + C25519_PUBLIC_KEY_SIZE + ED25519_PUBLIC_KEY_SIZE + P384_PUBLIC_KEY_SIZE + P384_PUBLIC_KEY_SIZE + P384_ECDSA_SIGNATURE_SIZE + 4);
let _ = self_sign_buf.write_all(&self.address.to_bytes());
let _ = self_sign_buf.write_all(&self.x25519);
let _ = self_sign_buf.write_all(&self.ed25519);
@ -302,7 +304,13 @@ impl Identity {
// for the final result to be technically FIPS compliant. Non-FIPS algorithm secrets are considered
// a salt in the HMAC(salt, key) HKDF construction.
if secret.p384.is_some() && other.p384.is_some() {
secret.p384.as_ref().unwrap().ecdh.agree(&other.p384.as_ref().unwrap().ecdh).map(|p384_secret| Secret(hmac_sha512(&c25519_secret.0, &p384_secret.0)))
secret
.p384
.as_ref()
.unwrap()
.ecdh
.agree(&other.p384.as_ref().unwrap().ecdh)
.map(|p384_secret| Secret(hmac_sha512(&c25519_secret.0, &p384_secret.0)))
} else {
Some(c25519_secret)
}
@ -493,7 +501,12 @@ impl Identity {
}
IdentityBytes::X25519P384Public(b) => {
let b: &packed::V1 = bytes_as_flat_object(b);
if b.v0.key_type == 0 && b.v0.secret_length == 0 && b.v0.reserved == 0x03 && u16::from_be_bytes(b.v0.ext_len) == (Self::BYTE_LENGTH_X25519P384_PUBLIC - Self::BYTE_LENGTH_X25519_PUBLIC) as u16 && b.key_type_flags == Self::ALGORITHM_EC_NIST_P384 {
if b.v0.key_type == 0
&& b.v0.secret_length == 0
&& b.v0.reserved == 0x03
&& u16::from_be_bytes(b.v0.ext_len) == (Self::BYTE_LENGTH_X25519P384_PUBLIC - Self::BYTE_LENGTH_X25519_PUBLIC) as u16
&& b.key_type_flags == Self::ALGORITHM_EC_NIST_P384
{
Some(Self {
address: Address::from_bytes_fixed(&b.v0.address)?,
x25519: b.v0.x25519,
@ -608,13 +621,15 @@ impl Identity {
s.push(':');
}
s.push_str(":2:"); // 2 == IDENTITY_ALGORITHM_EC_NIST_P384
let p384_joined: [u8; P384_PUBLIC_KEY_SIZE + P384_PUBLIC_KEY_SIZE + P384_ECDSA_SIGNATURE_SIZE + ED25519_SIGNATURE_SIZE] = concat_arrays_4(p384.ecdh.as_bytes(), p384.ecdsa.as_bytes(), &p384.ecdsa_self_signature, &p384.ed25519_self_signature);
let p384_joined: [u8; P384_PUBLIC_KEY_SIZE + P384_PUBLIC_KEY_SIZE + P384_ECDSA_SIGNATURE_SIZE + ED25519_SIGNATURE_SIZE] =
concat_arrays_4(p384.ecdh.as_bytes(), p384.ecdsa.as_bytes(), &p384.ecdsa_self_signature, &p384.ed25519_self_signature);
s.push_str(base64::encode_config(p384_joined, base64::URL_SAFE_NO_PAD).as_str());
if self.secret.is_some() && include_private {
let secret = self.secret.as_ref().unwrap();
if secret.p384.is_some() {
let p384_secret = secret.p384.as_ref().unwrap();
let p384_secret_joined: [u8; P384_SECRET_KEY_SIZE + P384_SECRET_KEY_SIZE] = concat_arrays_2(p384_secret.ecdh.secret_key_bytes().as_bytes(), p384_secret.ecdsa.secret_key_bytes().as_bytes());
let p384_secret_joined: [u8; P384_SECRET_KEY_SIZE + P384_SECRET_KEY_SIZE] =
concat_arrays_2(p384_secret.ecdh.secret_key_bytes().as_bytes(), p384_secret.ecdsa.secret_key_bytes().as_bytes());
s.push(':');
s.push_str(base64::encode_config(p384_secret_joined, base64::URL_SAFE_NO_PAD).as_str());
}
@ -723,7 +738,9 @@ impl FromStr for Identity {
Some(IdentityP384Public {
ecdh: ecdh.unwrap(),
ecdsa: ecdsa.unwrap(),
ecdsa_self_signature: keys[2].as_slice()[(P384_PUBLIC_KEY_SIZE * 2)..((P384_PUBLIC_KEY_SIZE * 2) + P384_ECDSA_SIGNATURE_SIZE)].try_into().unwrap(),
ecdsa_self_signature: keys[2].as_slice()[(P384_PUBLIC_KEY_SIZE * 2)..((P384_PUBLIC_KEY_SIZE * 2) + P384_ECDSA_SIGNATURE_SIZE)]
.try_into()
.unwrap(),
ed25519_self_signature: keys[2].as_slice()[((P384_PUBLIC_KEY_SIZE * 2) + P384_ECDSA_SIGNATURE_SIZE)..].try_into().unwrap(),
})
},
@ -937,7 +954,10 @@ impl<'de> serde::de::Visitor<'de> for IdentityVisitor {
where
E: serde::de::Error,
{
IdentityBytes::try_from(v).map_or_else(|e| Err(E::custom(e.to_string())), |b| Identity::from_bytes(&b).map_or_else(|| Err(E::custom("invalid identity")), |id| Ok(id)))
IdentityBytes::try_from(v).map_or_else(
|e| Err(E::custom(e.to_string())),
|b| Identity::from_bytes(&b).map_or_else(|| Err(E::custom("invalid identity")), |id| Ok(id)),
)
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
@ -965,7 +985,7 @@ impl<'de> Deserialize<'de> for Identity {
mod tests {
use crate::vl1::identity::*;
use std::str::FromStr;
use zerotier_core_crypto::hex;
use zerotier_utils::hex;
#[test]
fn v0_identity() {

View file

@ -11,6 +11,8 @@ use crate::error::InvalidFormatError;
use crate::util::buffer::Buffer;
use crate::util::marshalable::Marshalable;
use zerotier_utils::hex;
/// An Ethernet MAC address.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[repr(transparent)]
@ -88,7 +90,7 @@ impl FromStr for MAC {
type Err = InvalidFormatError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
MAC::from_bytes(crate::util::hex::from_string(s).as_slice()).map_or_else(|| Err(InvalidFormatError), |m| Ok(m))
MAC::from_bytes(hex::from_string(s).as_slice()).map_or_else(|| Err(InvalidFormatError), |m| Ok(m))
}
}

View file

@ -22,6 +22,8 @@ use crate::vl1::whoisqueue::{QueuedPacket, WhoisQueue};
use crate::vl1::{Address, Endpoint, Identity, RootSet};
use crate::Event;
use zerotier_utils::hex;
/// Trait implemented by external code to handle events and provide an interface to the system or application.
///
/// These methods are basically callbacks that the core calls to request or transmit things. They are called
@ -97,7 +99,16 @@ pub trait InnerProtocolInterface: Sync + Send + 'static {
async fn handle_packet<SI: SystemInterface>(&self, source: &Peer<SI>, source_path: &Path<SI>, verb: u8, payload: &PacketBuffer) -> bool;
/// Handle errors, returning true if the error was recognized.
async fn handle_error<SI: SystemInterface>(&self, source: &Peer<SI>, source_path: &Path<SI>, in_re_verb: u8, in_re_message_id: u64, error_code: u8, payload: &PacketBuffer, cursor: &mut usize) -> bool;
async fn handle_error<SI: SystemInterface>(
&self,
source: &Peer<SI>,
source_path: &Path<SI>,
in_re_verb: u8,
in_re_message_id: u64,
error_code: u8,
payload: &PacketBuffer,
cursor: &mut usize,
) -> bool;
/// Handle an OK, returing true if the OK was recognized.
async fn handle_ok<SI: SystemInterface>(&self, source: &Peer<SI>, source_path: &Path<SI>, in_re_verb: u8, in_re_message_id: u64, payload: &PacketBuffer, cursor: &mut usize) -> bool;
@ -400,7 +411,9 @@ impl<SI: SystemInterface> Node<SI> {
for m in rs.members.iter() {
if m.identity.eq(&self.identity) {
let _ = my_root_sets.get_or_insert_with(|| Vec::new()).write_all(rs.to_bytes().as_slice());
} else if self.peers.read().get(&m.identity.address).map_or(false, |p| !p.identity.eq(&m.identity)) || address_collision_check.insert(m.identity.address, &m.identity).map_or(false, |old_id| !old_id.eq(&m.identity)) {
} else if self.peers.read().get(&m.identity.address).map_or(false, |p| !p.identity.eq(&m.identity))
|| address_collision_check.insert(m.identity.address, &m.identity).map_or(false, |old_id| !old_id.eq(&m.identity))
{
address_collisions.push(m.identity.address);
}
}
@ -410,14 +423,22 @@ impl<SI: SystemInterface> Node<SI> {
for (_, rs) in roots.sets.iter() {
for m in rs.members.iter() {
if m.endpoints.is_some() && !address_collisions.contains(&m.identity.address) && !m.identity.eq(&self.identity) {
debug_event!(si, "[vl1] examining root {} with {} endpoints", m.identity.address.to_string(), m.endpoints.as_ref().map_or(0, |e| e.len()));
debug_event!(
si,
"[vl1] examining root {} with {} endpoints",
m.identity.address.to_string(),
m.endpoints.as_ref().map_or(0, |e| e.len())
);
let peers = self.peers.upgradable_read();
if let Some(peer) = peers.get(&m.identity.address) {
new_roots.insert(peer.clone(), m.endpoints.as_ref().unwrap().iter().cloned().collect());
} else {
if let Some(peer) = Peer::<SI>::new(&self.identity, m.identity.clone(), tt) {
new_roots.insert(
parking_lot::RwLockUpgradableReadGuard::upgrade(peers).entry(m.identity.address).or_insert_with(|| Arc::new(peer)).clone(),
parking_lot::RwLockUpgradableReadGuard::upgrade(peers)
.entry(m.identity.address)
.or_insert_with(|| Arc::new(peer))
.clone(),
m.endpoints.as_ref().unwrap().iter().cloned().collect(),
);
} else {
@ -542,14 +563,22 @@ impl<SI: SystemInterface> Node<SI> {
Duration::from_millis(1000)
}
pub async fn handle_incoming_physical_packet<PH: InnerProtocolInterface>(&self, si: &SI, ph: &PH, source_endpoint: &Endpoint, source_local_socket: &SI::LocalSocket, source_local_interface: &SI::LocalInterface, mut data: PooledPacketBuffer) {
pub async fn handle_incoming_physical_packet<PH: InnerProtocolInterface>(
&self,
si: &SI,
ph: &PH,
source_endpoint: &Endpoint,
source_local_socket: &SI::LocalSocket,
source_local_interface: &SI::LocalInterface,
mut data: PooledPacketBuffer,
) {
debug_event!(
si,
"[vl1] {} -> #{} {}->{} length {} (on socket {}@{})",
source_endpoint.to_string(),
data.bytes_fixed_at::<8>(0).map_or("????????????????".into(), |pid| zerotier_core_crypto::hex::to_string(pid)),
data.bytes_fixed_at::<5>(13).map_or("??????????".into(), |src| zerotier_core_crypto::hex::to_string(src)),
data.bytes_fixed_at::<5>(8).map_or("??????????".into(), |dest| zerotier_core_crypto::hex::to_string(dest)),
data.bytes_fixed_at::<8>(0).map_or("????????????????".into(), |pid| hex::to_string(pid)),
data.bytes_fixed_at::<5>(13).map_or("??????????".into(), |src| hex::to_string(src)),
data.bytes_fixed_at::<5>(8).map_or("??????????".into(), |dest| hex::to_string(dest)),
data.len(),
source_local_socket.to_string(),
source_local_interface.to_string()
@ -565,7 +594,13 @@ impl<SI: SystemInterface> Node<SI> {
if fragment_header.is_fragment() {
#[cfg(debug_assertions)]
let fragment_header_id = u64::from_be_bytes(fragment_header.id);
debug_event!(si, "[vl1] #{:0>16x} fragment {} of {} received", u64::from_be_bytes(fragment_header.id), fragment_header.fragment_no(), fragment_header.total_fragments());
debug_event!(
si,
"[vl1] #{:0>16x} fragment {} of {} received",
u64::from_be_bytes(fragment_header.id),
fragment_header.fragment_no(),
fragment_header.total_fragments()
);
if let Some(assembled_packet) = path.receive_fragment(fragment_header.packet_id(), fragment_header.fragment_no(), fragment_header.total_fragments(), data, time_ticks) {
if let Some(frag0) = assembled_packet.frags[0].as_ref() {
@ -575,7 +610,8 @@ impl<SI: SystemInterface> Node<SI> {
if let Ok(packet_header) = frag0.struct_at::<PacketHeader>(0) {
if let Some(source) = Address::from_bytes(&packet_header.src) {
if let Some(peer) = self.peer(source) {
peer.receive(self, si, ph, time_ticks, &path, &packet_header, frag0, &assembled_packet.frags[1..(assembled_packet.have as usize)]).await;
peer.receive(self, si, ph, time_ticks, &path, &packet_header, frag0, &assembled_packet.frags[1..(assembled_packet.have as usize)])
.await;
} else {
self.whois.query(self, si, source, Some(QueuedPacket::Fragmented(assembled_packet)));
}

View file

@ -8,9 +8,11 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::error::InvalidFormatError;
use crate::util::buffer::Buffer;
use crate::util::hex::HEX_CHARS;
use crate::util::marshalable::Marshalable;
use zerotier_utils::hex;
use zerotier_utils::hex::HEX_CHARS;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[repr(transparent)]
pub struct NetworkId(NonZeroU64);
@ -85,7 +87,7 @@ impl FromStr for NetworkId {
type Err = InvalidFormatError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
NetworkId::from_bytes(crate::util::hex::from_string(s).as_slice()).map_or_else(|| Err(InvalidFormatError), |a| Ok(a))
NetworkId::from_bytes(hex::from_string(s).as_slice()).map_or_else(|| Err(InvalidFormatError), |a| Ok(a))
}
}