mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-03 19:13:43 +02:00
AES-GMAC-SIV fixes, build fixes, finish up non-forwarding path in wire_packet().
This commit is contained in:
parent
005f76cd9b
commit
9ea1cd2d6e
8 changed files with 73 additions and 41 deletions
|
@ -9,10 +9,10 @@ lto = true
|
|||
codegen-units = 1
|
||||
panic = 'abort'
|
||||
|
||||
[target."cfg(all(not(any(target_os = \"macos\", target_os = \"ios\")), target_arch = \"s390x\"))".dependencies]
|
||||
[target."cfg(all(not(any(target_os = \"macos\", target_os = \"ios\")), any(target_arch = \"s390x\", target_arch = \"powerpc64le\", target_arch = \"powerpc64\")))".dependencies]
|
||||
openssl = "^0"
|
||||
|
||||
[target."cfg(not(any(target_os = \"macos\", target_os = \"ios\")))".dependencies]
|
||||
[target."cfg(not(any(target_os = \"macos\", target_os = \"ios\", target_arch = \"s390x\", target_arch = \"powerpc64le\", target_arch = \"powerpc64\")))".dependencies]
|
||||
gcrypt = "^0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
mod impl_macos;
|
||||
|
||||
#[cfg(not(any(target_os = "macos", target_os = "ios", target_arch = "s390x")))]
|
||||
#[cfg(not(any(target_os = "macos", target_os = "ios", target_arch = "s390x", target_arch = "powerpc64le", target_arch = "powerpc64")))]
|
||||
mod impl_gcrypt;
|
||||
|
||||
#[cfg(all(not(any(target_os = "macos", target_os = "ios")), target_arch = "s390x"))]
|
||||
#[cfg(all(not(any(target_os = "macos", target_os = "ios")), any(target_arch = "s390x", target_arch = "powerpc64le", target_arch = "powerpc64")))]
|
||||
mod impl_openssl;
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
pub use impl_macos::AesGmacSiv;
|
||||
|
||||
#[cfg(not(any(target_os = "macos", target_os = "ios", target_arch = "s390x")))]
|
||||
#[cfg(not(any(target_os = "macos", target_os = "ios", target_arch = "s390x", target_arch = "powerpc64le", target_arch = "powerpc64")))]
|
||||
pub use impl_gcrypt::AesGmacSiv;
|
||||
|
||||
#[cfg(all(not(any(target_os = "macos", target_os = "ios")), target_arch = "s390x"))]
|
||||
#[cfg(all(not(any(target_os = "macos", target_os = "ios")), any(target_arch = "s390x", target_arch = "powerpc64le", target_arch = "powerpc64")))]
|
||||
pub use impl_openssl::AesGmacSiv;
|
||||
|
||||
pub(crate) const ZEROES: [u8; 16] = [0_u8; 16];
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use std::mem::size_of;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
use parking_lot::Mutex;
|
||||
|
@ -56,7 +55,7 @@ impl<O, F: PoolFactory<O>> Pooled<O, F> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<O, F: PoolFactory<O>> Deref for Pooled<O, F> {
|
||||
impl<O, F: PoolFactory<O>> std::ops::Deref for Pooled<O, F> {
|
||||
type Target = O;
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -74,7 +73,7 @@ impl<O, F: PoolFactory<O>> AsRef<O> for Pooled<O, F> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<O, F: PoolFactory<O>> DerefMut for Pooled<O, F> {
|
||||
impl<O, F: PoolFactory<O>> std::ops::DerefMut for Pooled<O, F> {
|
||||
#[inline(always)]
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
debug_assert!(!self.0.is_null());
|
||||
|
@ -157,7 +156,6 @@ unsafe impl<O, F: PoolFactory<O>> Send for Pool<O, F> {}
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::ops::DerefMut;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::time::Duration;
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::util::hex::HEX_CHARS;
|
|||
/// It also supports binary keys and values which will be minimally escaped but render the result not
|
||||
/// entirely human readable. Keys are serialized in natural sort order so the result can be consistently
|
||||
/// checksummed or hashed.
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct Dictionary(BTreeMap<String, Vec<u8>>);
|
||||
|
||||
impl Default for Dictionary {
|
||||
|
|
|
@ -509,29 +509,47 @@ impl Ord for InetAddress {
|
|||
if self.sa.sa_family == other.sa.sa_family {
|
||||
match self.sa.sa_family as u8 {
|
||||
AF_INET => {
|
||||
if self.sin.sin_port == other.sin.sin_port {
|
||||
u32::from_be(self.sin.sin_addr.s_addr as u32).cmp(&u32::from_be(other.sin.sin_addr.s_addr as u32))
|
||||
} else {
|
||||
let ip_ordering = u32::from_be(self.sin.sin_addr.s_addr as u32).cmp(&u32::from_be(other.sin.sin_addr.s_addr as u32));
|
||||
if ip_ordering == Ordering::Equal {
|
||||
u16::from_be(self.sin.sin_port as u16).cmp(&u16::from_be(other.sin.sin_port as u16))
|
||||
} else {
|
||||
ip_ordering
|
||||
}
|
||||
}
|
||||
AF_INET6 => {
|
||||
if self.sin6.sin6_port == other.sin6.sin6_port {
|
||||
let a = &*(&(self.sin6.sin6_addr) as *const in6_addr).cast::<[u8; 16]>();
|
||||
let b = &*(&(other.sin6.sin6_addr) as *const in6_addr).cast::<[u8; 16]>();
|
||||
a.cmp(b)
|
||||
} else {
|
||||
let a = &*(&(self.sin6.sin6_addr) as *const in6_addr).cast::<[u8; 16]>();
|
||||
let b = &*(&(other.sin6.sin6_addr) as *const in6_addr).cast::<[u8; 16]>();
|
||||
let ip_ordering = a.cmp(b);
|
||||
if ip_ordering == Ordering::Equal {
|
||||
u16::from_be(self.sin6.sin6_port as u16).cmp(&u16::from_be(other.sin6.sin6_port as u16))
|
||||
} else {
|
||||
ip_ordering
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
Ordering::Equal
|
||||
}
|
||||
}
|
||||
} else if self.sa.sa_family < other.sa.sa_family {
|
||||
Ordering::Less
|
||||
} else {
|
||||
Ordering::Greater
|
||||
match self.sa.sa_family as u8 {
|
||||
AF_INET => {
|
||||
if other.sa.sa_family as u8 == AF_INET6 {
|
||||
Ordering::Less
|
||||
} else {
|
||||
self.sa.sa_family.cmp(&other.sa.sa_family)
|
||||
}
|
||||
}
|
||||
AF_INET6 => {
|
||||
if other.sa.sa_family as u8 == AF_INET {
|
||||
Ordering::Greater
|
||||
} else {
|
||||
self.sa.sa_family.cmp(&other.sa.sa_family)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.sa.sa_family.cmp(&other.sa.sa_family)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ use crate::vl1::constants::PACKET_SIZE_MAX;
|
|||
use crate::vl1::path::Path;
|
||||
use crate::vl1::peer::Peer;
|
||||
use crate::vl1::protocol::*;
|
||||
use crate::vl1::whois::WhoisQueue;
|
||||
use crate::vl1::whois::{WhoisQueue, QueuedPacket};
|
||||
|
||||
/// Standard packet buffer type including pool container.
|
||||
pub type PacketBuffer = Pooled<Buffer<{ PACKET_SIZE_MAX }>, PooledBufferFactory<{ PACKET_SIZE_MAX }>>;
|
||||
|
@ -184,15 +184,13 @@ impl Node {
|
|||
|
||||
/// Get a reusable packet buffer.
|
||||
/// The buffer will automatically be returned to the pool if it is dropped.
|
||||
#[inline(always)]
|
||||
pub fn get_packet_buffer(&self) -> PacketBuffer {
|
||||
self.buffer_pool.get()
|
||||
}
|
||||
|
||||
/// Get a peer by address.
|
||||
#[inline(always)]
|
||||
pub fn peer(&self, a: Address) -> Option<Arc<Peer>> {
|
||||
self.peers.get(&a).map(|peer| peer.clone() )
|
||||
self.peers.get(&a).map(|peer| peer.value().clone())
|
||||
}
|
||||
|
||||
/// Get all peers currently in the peer cache.
|
||||
|
@ -227,24 +225,47 @@ impl Node {
|
|||
|
||||
/// Called when a packet is received on the physical wire.
|
||||
pub fn wire_receive<CI: VL1CallerInterface, PH: VL1PacketHandler>(&self, ci: &CI, ph: &PH, source_endpoint: &Endpoint, source_local_socket: i64, source_local_interface: i64, mut data: PacketBuffer) {
|
||||
/*
|
||||
let _ = data.struct_mut_at::<FragmentHeader>(0).map(|fragment_header| {
|
||||
// NOTE: destination address is located at the same index in both the fragment
|
||||
// header and the full packet header, allowing us to make this decision once.
|
||||
let fragment_header = data.struct_mut_at::<FragmentHeader>(0);
|
||||
if fragment_header.is_ok() {
|
||||
let fragment_header = fragment_header.unwrap();
|
||||
let time_ticks = ci.time_ticks();
|
||||
let dest = Address::from(&fragment_header.dest);
|
||||
if dest == self.identity.address() {
|
||||
// Packet or fragment is addressed to this node.
|
||||
|
||||
let path = self.path(source_endpoint, source_local_socket, source_local_interface);
|
||||
if fragment_header.is_fragment() {
|
||||
let _ = path.receive_fragment(fragment_header.id, fragment_header.fragment_no(), fragment_header.total_fragments(), data, time_ticks).map(|assembled_packet| {
|
||||
if assembled_packet.frags[0].is_some() {
|
||||
let frag0 = assembled_packet.frags[0].as_ref().unwrap();
|
||||
let packet_header = frag0.struct_at::<PacketHeader>(0);
|
||||
if packet_header.is_ok() {
|
||||
let packet_header = packet_header.unwrap();
|
||||
let source = Address::from(&packet_header.src);
|
||||
let peer = self.peer(source);
|
||||
if peer.is_some() {
|
||||
peer.unwrap().receive(self, ci, ph, time_ticks, &path, &packet_header, frag0.as_ref(), &assembled_packet.frags[1..(assembled_packet.have as usize)]);
|
||||
} else {
|
||||
self.whois.query(self, ci, source, Some(QueuedPacket::Fragmented(assembled_packet)));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
path.receive_other(time_ticks);
|
||||
let packet_header = data.struct_at::<PacketHeader>(0);
|
||||
if packet_header.is_ok() {
|
||||
let packet_header = packet_header.unwrap();
|
||||
let source = Address::from(&packet_header.src);
|
||||
let peer = self.peer(source);
|
||||
if peer.is_some() {
|
||||
peer.unwrap().receive(self, ci, ph, time_ticks, &path, &packet_header, data.as_ref(), &[]);
|
||||
} else {
|
||||
self.whois.query(self, ci, source, Some(QueuedPacket::Singular(data)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Packet or fragment is addressed to another node.
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the current best root peer that we should use for WHOIS, relaying, etc.
|
||||
|
|
|
@ -97,7 +97,3 @@ impl Path {
|
|||
self.fragmented_packets.lock().retain(|packet_id, frag| (time_ticks - frag.ts_ticks) < FRAGMENT_EXPIRATION);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for Path {}
|
||||
|
||||
unsafe impl Sync for Path {}
|
||||
|
|
|
@ -163,7 +163,6 @@ impl Peer {
|
|||
/// Receive, decrypt, authenticate, and process an incoming packet from this peer.
|
||||
/// If the packet comes in multiple fragments, the fragments slice should contain all
|
||||
/// those fragments after the main packet header and first chunk.
|
||||
#[inline(always)]
|
||||
pub(crate) fn receive<CI: VL1CallerInterface, PH: VL1PacketHandler>(&self, node: &Node, ci: &CI, ph: &PH, time_ticks: i64, source_path: &Arc<Path>, header: &PacketHeader, packet: &Buffer<{ PACKET_SIZE_MAX }>, fragments: &[Option<PacketBuffer>]) {
|
||||
let _ = packet.as_bytes_starting_at(PACKET_VERB_INDEX).map(|packet_frag0_payload_bytes| {
|
||||
let mut payload: Buffer<{ PACKET_SIZE_MAX }> = Buffer::new();
|
||||
|
|
Loading…
Add table
Reference in a new issue