From 005f76cd9b6e47280fdf510e9526facbe8313f9b Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 5 Aug 2021 18:25:04 -0400 Subject: [PATCH] Various cleanup. --- aes-gmac-siv/Cargo.toml | 2 +- network-hypervisor/src/vl1/constants.rs | 3 ++ network-hypervisor/src/vl1/dictionary.rs | 1 + network-hypervisor/src/vl1/endpoint.rs | 42 +++++++++++------------ network-hypervisor/src/vl1/inetaddress.rs | 2 +- network-hypervisor/src/vl1/node.rs | 8 +++++ network-hypervisor/src/vl1/path.rs | 1 + network-hypervisor/src/vl1/peer.rs | 14 +++++--- network-hypervisor/src/vl1/whois.rs | 20 ++++++++--- 9 files changed, 60 insertions(+), 33 deletions(-) diff --git a/aes-gmac-siv/Cargo.toml b/aes-gmac-siv/Cargo.toml index 0ab6689f2..5bcad0bfd 100644 --- a/aes-gmac-siv/Cargo.toml +++ b/aes-gmac-siv/Cargo.toml @@ -9,7 +9,7 @@ lto = true codegen-units = 1 panic = 'abort' -[dependencies] +[target."cfg(all(not(any(target_os = \"macos\", target_os = \"ios\")), target_arch = \"s390x\"))".dependencies] openssl = "^0" [target."cfg(not(any(target_os = \"macos\", target_os = \"ios\")))".dependencies] diff --git a/network-hypervisor/src/vl1/constants.rs b/network-hypervisor/src/vl1/constants.rs index 4287f0bd9..1be516b2c 100644 --- a/network-hypervisor/src/vl1/constants.rs +++ b/network-hypervisor/src/vl1/constants.rs @@ -106,6 +106,9 @@ pub const WHOIS_RETRY_INTERVAL: i64 = 1000; /// Maximum number of WHOIS retries pub const WHOIS_RETRY_MAX: u16 = 3; +/// Maximum number of packets to queue up behind a WHOIS. +pub const WHOIS_MAX_WAITING_PACKETS: usize = 64; + /// Maximum number of endpoints allowed in a Locator. pub const LOCATOR_MAX_ENDPOINTS: usize = 32; diff --git a/network-hypervisor/src/vl1/dictionary.rs b/network-hypervisor/src/vl1/dictionary.rs index 09eb3e3f0..b555ed643 100644 --- a/network-hypervisor/src/vl1/dictionary.rs +++ b/network-hypervisor/src/vl1/dictionary.rs @@ -183,6 +183,7 @@ impl Dictionary { impl ToString for Dictionary { /// Get the dictionary in an always readable format with non-printable characters replaced by '\xXX'. + /// This is not a serializable output that can be re-imported. Use write_to() for that. fn to_string(&self) -> String { let mut s = String::new(); for kv in self.0.iter() { diff --git a/network-hypervisor/src/vl1/endpoint.rs b/network-hypervisor/src/vl1/endpoint.rs index c3888691d..f2f398759 100644 --- a/network-hypervisor/src/vl1/endpoint.rs +++ b/network-hypervisor/src/vl1/endpoint.rs @@ -1,9 +1,9 @@ +use std::cmp::Ordering; use std::hash::{Hash, Hasher}; use crate::vl1::{Address, MAC}; -use crate::vl1::inetaddress::InetAddress; use crate::vl1::buffer::Buffer; -use std::cmp::Ordering; +use crate::vl1::inetaddress::InetAddress; const TYPE_NIL: u8 = 0; const TYPE_ZEROTIER: u8 = 1; @@ -82,26 +82,26 @@ impl Endpoint { pub fn marshal(&self, buf: &mut Buffer) -> std::io::Result<()> { match self { Endpoint::Nil => { - buf.append_u8(Type::Nil as u8) + buf.append_u8(TYPE_NIL) } Endpoint::ZeroTier(a) => { - buf.append_u8(16 + (Type::ZeroTier as u8))?; + buf.append_u8(16 + TYPE_ZEROTIER)?; buf.append_bytes_fixed(&a.to_bytes()) } Endpoint::Ethernet(m) => { - buf.append_u8(16 + (Type::Ethernet as u8))?; + buf.append_u8(16 + TYPE_ETHERNET)?; buf.append_bytes_fixed(&m.to_bytes()) } Endpoint::WifiDirect(m) => { - buf.append_u8(16 + (Type::WifiDirect as u8))?; + buf.append_u8(16 + TYPE_WIFIDIRECT)?; buf.append_bytes_fixed(&m.to_bytes()) } Endpoint::Bluetooth(m) => { - buf.append_u8(16 + (Type::Bluetooth as u8))?; + buf.append_u8(16 + TYPE_BLUETOOTH)?; buf.append_bytes_fixed(&m.to_bytes()) } Endpoint::Ip(ip) => { - buf.append_u8(16 + (Type::Ip as u8))?; + buf.append_u8(16 + TYPE_IP)?; ip.marshal(buf) } Endpoint::IpUdp(ip) => { @@ -111,17 +111,17 @@ impl Endpoint { ip.marshal(buf) } Endpoint::IpTcp(ip) => { - buf.append_u8(16 + (Type::IpTcp as u8))?; + buf.append_u8(16 + TYPE_IPTCP)?; ip.marshal(buf) } Endpoint::Http(url) => { - buf.append_u8(16 + (Type::Http as u8))?; + buf.append_u8(16 + TYPE_HTTP)?; let b = url.as_bytes(); buf.append_u16(b.len() as u16)?; buf.append_bytes(b) } Endpoint::WebRTC(offer) => { - buf.append_u8(16 + (Type::WebRTC as u8))?; + buf.append_u8(16 + TYPE_WEBRTC)?; let b = offer.as_slice(); buf.append_u16(b.len() as u16)?; buf.append_bytes(b) @@ -166,42 +166,42 @@ impl Hash for Endpoint { fn hash(&self, state: &mut H) { match self { Endpoint::Nil => { - state.write_u8(Type::Nil as u8); + state.write_u8(TYPE_NIL); } Endpoint::ZeroTier(a) => { - state.write_u8(Type::ZeroTier as u8); + state.write_u8(TYPE_ZEROTIER); state.write_u64(a.to_u64()) } Endpoint::Ethernet(m) => { - state.write_u8(Type::Ethernet as u8); + state.write_u8(TYPE_ETHERNET); state.write_u64(m.to_u64()) } Endpoint::WifiDirect(m) => { - state.write_u8(Type::WifiDirect as u8); + state.write_u8(TYPE_WIFIDIRECT); state.write_u64(m.to_u64()) } Endpoint::Bluetooth(m) => { - state.write_u8(Type::Bluetooth as u8); + state.write_u8(TYPE_BLUETOOTH); state.write_u64(m.to_u64()) } Endpoint::Ip(ip) => { - state.write_u8(Type::Ip as u8); + state.write_u8(TYPE_IP); ip.hash(state); } Endpoint::IpUdp(ip) => { - state.write_u8(Type::IpUdp as u8); + state.write_u8(TYPE_IPUDP); ip.hash(state); } Endpoint::IpTcp(ip) => { - state.write_u8(Type::IpTcp as u8); + state.write_u8(TYPE_IPTCP); ip.hash(state); } Endpoint::Http(url) => { - state.write_u8(Type::Http as u8); + state.write_u8(TYPE_HTTP); url.hash(state); } Endpoint::WebRTC(offer) => { - state.write_u8(Type::WebRTC as u8); + state.write_u8(TYPE_WEBRTC); offer.hash(state); } } diff --git a/network-hypervisor/src/vl1/inetaddress.rs b/network-hypervisor/src/vl1/inetaddress.rs index 4269d8d17..ff3b144eb 100644 --- a/network-hypervisor/src/vl1/inetaddress.rs +++ b/network-hypervisor/src/vl1/inetaddress.rs @@ -210,7 +210,7 @@ impl InetAddress { match self.sa.sa_family as u8 { AF_INET => &*(&self.sin.sin_addr.s_addr as *const u32).cast::<[u8; 4]>(), AF_INET6 => &*(&(self.sin6.sin6_addr) as *const in6_addr).cast::<[u8; 16]>(), - _ => &[] + _ => &[], } } } diff --git a/network-hypervisor/src/vl1/node.rs b/network-hypervisor/src/vl1/node.rs index 64c8e0bac..10d2a8441 100644 --- a/network-hypervisor/src/vl1/node.rs +++ b/network-hypervisor/src/vl1/node.rs @@ -125,6 +125,7 @@ pub struct Node { locator: Mutex>, paths: DashMap>, peers: DashMap>, + root: Mutex>>, whois: WhoisQueue, buffer_pool: Pool, PooledBufferFactory<{ PACKET_SIZE_MAX }>>, secure_prng: SecureRandom, @@ -162,6 +163,7 @@ impl Node { locator: Mutex::new(None), paths: DashMap::new(), peers: DashMap::new(), + root: Mutex::new(None), whois: WhoisQueue::new(), buffer_pool: Pool::new(64, PooledBufferFactory), secure_prng: SecureRandom::get(), @@ -245,6 +247,12 @@ impl Node { */ } + /// Get the current best root peer that we should use for WHOIS, relaying, etc. + #[inline(always)] + pub(crate) fn root(&self) -> Option> { + self.root.lock().clone() + } + /// Get the canonical Path object for a given endpoint and local socket information. /// This is a canonicalizing function that returns a unique path object for every tuple /// of endpoint, local socket, and local interface. diff --git a/network-hypervisor/src/vl1/path.rs b/network-hypervisor/src/vl1/path.rs index 9e11a4c11..54e7e44d1 100644 --- a/network-hypervisor/src/vl1/path.rs +++ b/network-hypervisor/src/vl1/path.rs @@ -91,6 +91,7 @@ impl Path { self.last_receive_time_ticks.store(time_ticks, Ordering::Relaxed); } + /// Called every INTERVAL during background tasks. #[inline(always)] pub fn on_interval(&self, ct: &CI, time_ticks: i64) { self.fragmented_packets.lock().retain(|packet_id, frag| (time_ticks - frag.ts_ticks) < FRAGMENT_EXPIRATION); diff --git a/network-hypervisor/src/vl1/peer.rs b/network-hypervisor/src/vl1/peer.rs index 8265a6b71..7189bf123 100644 --- a/network-hypervisor/src/vl1/peer.rs +++ b/network-hypervisor/src/vl1/peer.rs @@ -12,7 +12,7 @@ use crate::crypto::random::next_u64_secure; use crate::crypto::salsa::Salsa; use crate::crypto::secret::Secret; use crate::util::pool::{Pool, PoolFactory}; -use crate::vl1::{Identity, Path}; +use crate::vl1::{Identity, Path, Endpoint}; use crate::vl1::buffer::Buffer; use crate::vl1::constants::*; use crate::vl1::node::*; @@ -167,9 +167,8 @@ impl Peer { 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(); - let mut forward_secrecy = true; let cipher = header.cipher(); - + let mut forward_secrecy = true; let ephemeral_secret = self.ephemeral_secret.lock().clone(); for secret in [ephemeral_secret.as_ref().map_or(&self.static_secret, |s| s.as_ref()), &self.static_secret] { match cipher { @@ -234,7 +233,10 @@ impl Peer { } } - _ => {} + _ => { + // Unrecognized or unsupported cipher type. + return; + } } if (secret as *const PeerSecret) == (&self.static_secret as *const PeerSecret) { @@ -247,7 +249,6 @@ impl Peer { payload.clear(); } } - drop(ephemeral_secret); // If decryption and authentication succeeded, the code above will break out of the // for loop and end up here. Otherwise it returns from the whole function. @@ -277,6 +278,9 @@ impl Peer { }); } + pub(crate) fn send_hello(&self, ci: &CI, to_endpoint: &Endpoint) { + } + /// Get the remote version of this peer: major, minor, revision, and build. /// Returns None if it's not yet known. pub fn version(&self) -> Option<[u16; 4]> { diff --git a/network-hypervisor/src/vl1/whois.rs b/network-hypervisor/src/vl1/whois.rs index 03f68c179..f574d4779 100644 --- a/network-hypervisor/src/vl1/whois.rs +++ b/network-hypervisor/src/vl1/whois.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{HashMap, LinkedList}; use parking_lot::Mutex; @@ -14,7 +14,7 @@ pub(crate) enum QueuedPacket { } struct WhoisQueueItem { - packet_queue: Vec, + packet_queue: LinkedList, retry_gate: IntervalGate<{ WHOIS_RETRY_INTERVAL }>, retry_count: u16, } @@ -24,7 +24,7 @@ pub(crate) struct WhoisQueue { } impl WhoisQueue { - pub const INTERVAL: i64 = WHOIS_RETRY_INTERVAL; + pub(crate) const INTERVAL: i64 = WHOIS_RETRY_INTERVAL; pub fn new() -> Self { Self { @@ -36,7 +36,7 @@ impl WhoisQueue { let mut q = self.queue.lock(); let qi = q.entry(target).or_insert_with(|| WhoisQueueItem { - packet_queue: Vec::new(), + packet_queue: LinkedList::new(), retry_gate: IntervalGate::new(0), retry_count: 0, }); @@ -44,12 +44,22 @@ impl WhoisQueue { if qi.retry_gate.gate(ci.time_ticks()) { qi.retry_count += 1; if packet.is_some() { - qi.packet_queue.push(packet.unwrap()); + while qi.packet_queue.len() >= WHOIS_MAX_WAITING_PACKETS { + let _ = qi.packet_queue.pop_front(); + } + qi.packet_queue.push_back(packet.unwrap()); } self.send_whois(node, ci, &[target]); } } + /// Remove a WHOIS request from the queue and call the supplied function for all queued packets. + pub fn response_received_get_packets(&self, address: Address, packet_handler: F) { + let mut qi = self.queue.lock().remove(&address); + let _ = qi.map(|mut qi| qi.packet_queue.iter_mut().for_each(packet_handler)); + } + + /// Called every INTERVAL during background tasks. pub fn on_interval(&self, node: &Node, ci: &CI, time_ticks: i64) { let mut targets: Vec
= Vec::new(); self.queue.lock().retain(|target, qi| {