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
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]

View file

@ -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];

View file

@ -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;

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
/// 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 {

View file

@ -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)
}
}
}
}
}

View file

@ -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.

View file

@ -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 {}

View file

@ -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();