diff --git a/aes-gmac-siv/Cargo.toml b/aes-gmac-siv/Cargo.toml index 5bcad0bfd..03f3d9b54 100644 --- a/aes-gmac-siv/Cargo.toml +++ b/aes-gmac-siv/Cargo.toml @@ -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] diff --git a/aes-gmac-siv/src/lib.rs b/aes-gmac-siv/src/lib.rs index 824d2bbd0..e105a0ab5 100644 --- a/aes-gmac-siv/src/lib.rs +++ b/aes-gmac-siv/src/lib.rs @@ -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]; diff --git a/network-hypervisor/src/util/pool.rs b/network-hypervisor/src/util/pool.rs index 5b858d7ef..5e2cf39db 100644 --- a/network-hypervisor/src/util/pool.rs +++ b/network-hypervisor/src/util/pool.rs @@ -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> Pooled { } } -impl> Deref for Pooled { +impl> std::ops::Deref for Pooled { type Target = O; #[inline(always)] @@ -74,7 +73,7 @@ impl> AsRef for Pooled { } } -impl> DerefMut for Pooled { +impl> std::ops::DerefMut for Pooled { #[inline(always)] fn deref_mut(&mut self) -> &mut Self::Target { debug_assert!(!self.0.is_null()); @@ -157,7 +156,6 @@ unsafe impl> Send for Pool {} #[cfg(test)] mod tests { - use std::ops::DerefMut; use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; use std::time::Duration; diff --git a/network-hypervisor/src/vl1/dictionary.rs b/network-hypervisor/src/vl1/dictionary.rs index b555ed643..aec5d8d14 100644 --- a/network-hypervisor/src/vl1/dictionary.rs +++ b/network-hypervisor/src/vl1/dictionary.rs @@ -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>); impl Default for Dictionary { diff --git a/network-hypervisor/src/vl1/inetaddress.rs b/network-hypervisor/src/vl1/inetaddress.rs index ff3b144eb..9d116a53f 100644 --- a/network-hypervisor/src/vl1/inetaddress.rs +++ b/network-hypervisor/src/vl1/inetaddress.rs @@ -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) + } + } } } } diff --git a/network-hypervisor/src/vl1/node.rs b/network-hypervisor/src/vl1/node.rs index 10d2a8441..6aef2aa65 100644 --- a/network-hypervisor/src/vl1/node.rs +++ b/network-hypervisor/src/vl1/node.rs @@ -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, 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> { - 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(&self, ci: &CI, ph: &PH, source_endpoint: &Endpoint, source_local_socket: i64, source_local_interface: i64, mut data: PacketBuffer) { - /* - let _ = data.struct_mut_at::(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::(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::(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::(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. diff --git a/network-hypervisor/src/vl1/path.rs b/network-hypervisor/src/vl1/path.rs index 54e7e44d1..fe8b7091a 100644 --- a/network-hypervisor/src/vl1/path.rs +++ b/network-hypervisor/src/vl1/path.rs @@ -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 {} diff --git a/network-hypervisor/src/vl1/peer.rs b/network-hypervisor/src/vl1/peer.rs index 7189bf123..70f863cf6 100644 --- a/network-hypervisor/src/vl1/peer.rs +++ b/network-hypervisor/src/vl1/peer.rs @@ -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(&self, node: &Node, ci: &CI, ph: &PH, time_ticks: i64, source_path: &Arc, header: &PacketHeader, packet: &Buffer<{ PACKET_SIZE_MAX }>, fragments: &[Option]) { let _ = packet.as_bytes_starting_at(PACKET_VERB_INDEX).map(|packet_frag0_payload_bytes| { let mut payload: Buffer<{ PACKET_SIZE_MAX }> = Buffer::new();