AES-GMAC-SIV fixes, build fixes, finish up non-forwarding path in wire_packet().

This commit is contained in:
Adam Ierymenko 2021-08-05 22:51:47 -04:00
parent 005f76cd9b
commit 9ea1cd2d6e
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
8 changed files with 73 additions and 41 deletions

View file

@ -9,10 +9,10 @@ lto = true
codegen-units = 1 codegen-units = 1
panic = 'abort' 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" 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" gcrypt = "^0"
[dev-dependencies] [dev-dependencies]

View file

@ -1,19 +1,19 @@
#[cfg(any(target_os = "macos", target_os = "ios"))] #[cfg(any(target_os = "macos", target_os = "ios"))]
mod impl_macos; 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; 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; mod impl_openssl;
#[cfg(any(target_os = "macos", target_os = "ios"))] #[cfg(any(target_os = "macos", target_os = "ios"))]
pub use impl_macos::AesGmacSiv; 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; 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 use impl_openssl::AesGmacSiv;
pub(crate) const ZEROES: [u8; 16] = [0_u8; 16]; pub(crate) const ZEROES: [u8; 16] = [0_u8; 16];

View file

@ -1,5 +1,4 @@
use std::mem::size_of; use std::mem::size_of;
use std::ops::{Deref, DerefMut};
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use parking_lot::Mutex; 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; type Target = O;
#[inline(always)] #[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)] #[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
debug_assert!(!self.0.is_null()); debug_assert!(!self.0.is_null());
@ -157,7 +156,6 @@ unsafe impl<O, F: PoolFactory<O>> Send for Pool<O, F> {}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::ops::DerefMut;
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::Duration; use std::time::Duration;

View file

@ -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 /// 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 /// entirely human readable. Keys are serialized in natural sort order so the result can be consistently
/// checksummed or hashed. /// checksummed or hashed.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] #[derive(Clone, PartialEq, Eq)]
pub struct Dictionary(BTreeMap<String, Vec<u8>>); pub struct Dictionary(BTreeMap<String, Vec<u8>>);
impl Default for Dictionary { impl Default for Dictionary {

View file

@ -509,29 +509,47 @@ impl Ord for InetAddress {
if self.sa.sa_family == other.sa.sa_family { if self.sa.sa_family == other.sa.sa_family {
match self.sa.sa_family as u8 { match self.sa.sa_family as u8 {
AF_INET => { AF_INET => {
if self.sin.sin_port == other.sin.sin_port { 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));
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 {
} else {
u16::from_be(self.sin.sin_port as u16).cmp(&u16::from_be(other.sin.sin_port as u16)) u16::from_be(self.sin.sin_port as u16).cmp(&u16::from_be(other.sin.sin_port as u16))
} else {
ip_ordering
} }
} }
AF_INET6 => { 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 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 b = &*(&(other.sin6.sin6_addr) as *const in6_addr).cast::<[u8; 16]>(); let ip_ordering = a.cmp(b);
a.cmp(b) if ip_ordering == Ordering::Equal {
} else {
u16::from_be(self.sin6.sin6_port as u16).cmp(&u16::from_be(other.sin6.sin6_port as u16)) u16::from_be(self.sin6.sin6_port as u16).cmp(&u16::from_be(other.sin6.sin6_port as u16))
} else {
ip_ordering
} }
} }
_ => { _ => {
Ordering::Equal Ordering::Equal
} }
} }
} else if self.sa.sa_family < other.sa.sa_family {
Ordering::Less
} else { } 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)
}
}
} }
} }
} }

View file

@ -15,7 +15,7 @@ use crate::vl1::constants::PACKET_SIZE_MAX;
use crate::vl1::path::Path; use crate::vl1::path::Path;
use crate::vl1::peer::Peer; use crate::vl1::peer::Peer;
use crate::vl1::protocol::*; use crate::vl1::protocol::*;
use crate::vl1::whois::WhoisQueue; use crate::vl1::whois::{WhoisQueue, QueuedPacket};
/// Standard packet buffer type including pool container. /// Standard packet buffer type including pool container.
pub type PacketBuffer = Pooled<Buffer<{ PACKET_SIZE_MAX }>, PooledBufferFactory<{ PACKET_SIZE_MAX }>>; pub type PacketBuffer = Pooled<Buffer<{ PACKET_SIZE_MAX }>, PooledBufferFactory<{ PACKET_SIZE_MAX }>>;
@ -184,15 +184,13 @@ impl Node {
/// Get a reusable packet buffer. /// Get a reusable packet buffer.
/// The buffer will automatically be returned to the pool if it is dropped. /// The buffer will automatically be returned to the pool if it is dropped.
#[inline(always)]
pub fn get_packet_buffer(&self) -> PacketBuffer { pub fn get_packet_buffer(&self) -> PacketBuffer {
self.buffer_pool.get() self.buffer_pool.get()
} }
/// Get a peer by address. /// Get a peer by address.
#[inline(always)]
pub fn peer(&self, a: Address) -> Option<Arc<Peer>> { 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. /// Get all peers currently in the peer cache.
@ -227,24 +225,47 @@ impl Node {
/// Called when a packet is received on the physical wire. /// 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) { 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 fragment_header = data.struct_mut_at::<FragmentHeader>(0);
let _ = data.struct_mut_at::<FragmentHeader>(0).map(|fragment_header| { if fragment_header.is_ok() {
// NOTE: destination address is located at the same index in both the fragment let fragment_header = fragment_header.unwrap();
// header and the full packet header, allowing us to make this decision once. let time_ticks = ci.time_ticks();
let dest = Address::from(&fragment_header.dest); let dest = Address::from(&fragment_header.dest);
if dest == self.identity.address() { 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); let path = self.path(source_endpoint, source_local_socket, source_local_interface);
if fragment_header.is_fragment() { 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 { } 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 { } else {
// Packet or fragment is addressed to another node.
} }
}); }
*/
} }
/// Get the current best root peer that we should use for WHOIS, relaying, etc. /// Get the current best root peer that we should use for WHOIS, relaying, etc.

View file

@ -97,7 +97,3 @@ impl Path {
self.fragmented_packets.lock().retain(|packet_id, frag| (time_ticks - frag.ts_ticks) < FRAGMENT_EXPIRATION); 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 {}

View file

@ -163,7 +163,6 @@ impl Peer {
/// Receive, decrypt, authenticate, and process an incoming packet from this 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 /// If the packet comes in multiple fragments, the fragments slice should contain all
/// those fragments after the main packet header and first chunk. /// 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>]) { 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 _ = packet.as_bytes_starting_at(PACKET_VERB_INDEX).map(|packet_frag0_payload_bytes| {
let mut payload: Buffer<{ PACKET_SIZE_MAX }> = Buffer::new(); let mut payload: Buffer<{ PACKET_SIZE_MAX }> = Buffer::new();