Ease up some template restrictions and wire up some more stuff in controller.

This commit is contained in:
Adam Ierymenko 2022-10-13 13:45:07 -04:00
parent 5601b83f10
commit 3e713360e3
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
7 changed files with 148 additions and 125 deletions

View file

@ -1,7 +1,7 @@
// (c) 2020-2022 ZeroTier, Inc. -- currently propritery pending actual release and licensing. See LICENSE.md.
use std::error::Error;
use std::sync::Arc;
use std::sync::{Arc, Mutex};
use tokio::time::{Duration, Instant};
@ -13,52 +13,42 @@ use zerotier_utils::error::{InvalidParameterError, UnexpectedError};
use zerotier_utils::ms_since_epoch;
use zerotier_utils::reaper::Reaper;
use zerotier_utils::tokio;
use zerotier_vl1_service::VL1Service;
use crate::database::*;
use crate::model::{AuthorizationResult, Member, CREDENTIAL_WINDOW_SIZE_DEFAULT};
// A netconf per-query task timeout, just a sanity limit.
const REQUEST_TIMEOUT: Duration = Duration::from_secs(10);
/// ZeroTier VL2 network controller packet handler, answers VL2 netconf queries.
pub struct Handler<DatabaseImpl: Database> {
inner: Arc<Inner<DatabaseImpl>>,
change_watcher: Option<tokio::task::JoinHandle<()>>,
}
struct Inner<DatabaseImpl: Database> {
reaper: Reaper,
daemons: Mutex<Vec<tokio::task::JoinHandle<()>>>, // drop() aborts these
runtime: tokio::runtime::Handle,
database: Arc<DatabaseImpl>,
local_identity: Identity,
}
impl<DatabaseImpl: Database> Handler<DatabaseImpl> {
/// Start an inner protocol handler answer ZeroTier VL2 network controller queries.
pub async fn new(database: Arc<DatabaseImpl>, runtime: tokio::runtime::Handle) -> Result<Arc<Self>, Box<dyn Error>> {
if let Some(local_identity) = database.load_node_identity() {
assert!(local_identity.secret.is_some());
let inner = Arc::new(Inner::<DatabaseImpl> {
reaper: Reaper::new(&runtime),
daemons: Mutex::new(Vec::with_capacity(1)),
runtime,
database: database.clone(),
local_identity,
});
let h = Arc::new(Self {
inner: inner.clone(),
change_watcher: database.changes().await.map(|mut ch| {
let inner2 = inner.clone();
inner.runtime.spawn(async move {
loop {
if let Ok(change) = ch.recv().await {
inner2.reaper.add(
inner2.runtime.spawn(inner2.clone().handle_change_notification(change)),
Instant::now().checked_add(REQUEST_TIMEOUT).unwrap(),
);
}
}
})
}),
});
let h = Arc::new(Self { inner: inner.clone() });
Ok(h)
} else {
@ -67,16 +57,33 @@ impl<DatabaseImpl: Database> Handler<DatabaseImpl> {
)))
}
}
}
impl<DatabaseImpl: Database> Drop for Handler<DatabaseImpl> {
fn drop(&mut self) {
let _ = self.change_watcher.take().map(|w| w.abort());
/// Start a change watcher to respond to changes detected by the database.
/// This should only be called once, though multiple calls won't do anything but create unnecessary async tasks.
pub async fn start_change_watcher(&self, service: &Arc<VL1Service<DatabaseImpl, Self, Self>>) {
if let Some(cw) = self.inner.database.changes().await.map(|mut ch| {
let inner = self.inner.clone();
let service = service.clone();
self.inner.runtime.spawn(async move {
loop {
if let Ok(change) = ch.recv().await {
inner.reaper.add(
inner
.runtime
.spawn(inner.clone().handle_change_notification(service.clone(), change)),
Instant::now().checked_add(REQUEST_TIMEOUT).unwrap(),
);
}
}
})
}) {
self.inner.daemons.lock().unwrap().push(cw);
}
}
}
impl<DatabaseImpl: Database> PathFilter for Handler<DatabaseImpl> {
fn should_use_physical_path<HostSystemImpl: HostSystem>(
fn should_use_physical_path<HostSystemImpl: HostSystem + ?Sized>(
&self,
_id: &Identity,
_endpoint: &zerotier_network_hypervisor::vl1::Endpoint,
@ -86,7 +93,7 @@ impl<DatabaseImpl: Database> PathFilter for Handler<DatabaseImpl> {
true
}
fn get_path_hints<HostSystemImpl: HostSystem>(
fn get_path_hints<HostSystemImpl: HostSystem + ?Sized>(
&self,
_id: &Identity,
) -> Option<
@ -101,7 +108,7 @@ impl<DatabaseImpl: Database> PathFilter for Handler<DatabaseImpl> {
}
impl<DatabaseImpl: Database> InnerProtocol for Handler<DatabaseImpl> {
fn handle_packet<HostSystemImpl: HostSystem>(
fn handle_packet<HostSystemImpl: HostSystem + ?Sized>(
&self,
_node: &Node<HostSystemImpl>,
source: &Arc<Peer<HostSystemImpl>>,
@ -177,7 +184,7 @@ impl<DatabaseImpl: Database> InnerProtocol for Handler<DatabaseImpl> {
}
}
fn handle_error<HostSystemImpl: HostSystem>(
fn handle_error<HostSystemImpl: HostSystem + ?Sized>(
&self,
_node: &Node<HostSystemImpl>,
_source: &Arc<Peer<HostSystemImpl>>,
@ -192,7 +199,7 @@ impl<DatabaseImpl: Database> InnerProtocol for Handler<DatabaseImpl> {
PacketHandlerResult::NotHandled
}
fn handle_ok<HostSystemImpl: HostSystem>(
fn handle_ok<HostSystemImpl: HostSystem + ?Sized>(
&self,
_node: &Node<HostSystemImpl>,
_source: &Arc<Peer<HostSystemImpl>>,
@ -212,11 +219,15 @@ impl<DatabaseImpl: Database> InnerProtocol for Handler<DatabaseImpl> {
}
impl<DatabaseImpl: Database> Inner<DatabaseImpl> {
async fn handle_change_notification(self: Arc<Self>, _change: Change) {
async fn handle_change_notification(
self: Arc<Self>,
service: Arc<VL1Service<DatabaseImpl, Handler<DatabaseImpl>, Handler<DatabaseImpl>>>,
_change: Change,
) {
todo!()
}
async fn handle_network_config_request<HostSystemImpl: HostSystem>(
async fn handle_network_config_request<HostSystemImpl: HostSystem + ?Sized>(
self: Arc<Self>,
source: Arc<Peer<HostSystemImpl>>,
_source_path: Arc<Path<HostSystemImpl>>,
@ -339,3 +350,11 @@ impl<DatabaseImpl: Database> Inner<DatabaseImpl> {
Ok((authorization_result, nc))
}
}
impl<DatabaseImpl: Database> Drop for Inner<DatabaseImpl> {
fn drop(&mut self) {
for h in self.daemons.lock().unwrap().drain(..) {
h.abort();
}
}
}

View file

@ -22,15 +22,18 @@ async fn run<DatabaseImpl: Database>(database: Arc<DatabaseImpl>, runtime: &Runt
exitcode::ERR_CONFIG
} else {
let handler = handler.unwrap();
let svc = VL1Service::new(
database.clone(),
handler.clone(),
handler.clone(),
zerotier_vl1_service::VL1Settings::default(),
);
if svc.is_ok() {
let svc = svc.unwrap();
svc.node().init_default_roots();
handler.start_change_watcher(&svc).await;
// Wait for kill signal on Unix-like platforms.
#[cfg(unix)]

View file

@ -31,10 +31,10 @@ use zerotier_utils::ringbuffer::RingBuffer;
/// during calls to things like wire_recieve() and do_background_tasks().
pub trait HostSystem: Sync + Send + 'static {
/// Type for local system sockets.
type LocalSocket: Sync + Send + Hash + PartialEq + Eq + Clone + ToString + 'static;
type LocalSocket: Sync + Send + Hash + PartialEq + Eq + Clone + ToString + Sized + 'static;
/// Type for local system interfaces.
type LocalInterface: Sync + Send + Hash + PartialEq + Eq + Clone + ToString;
type LocalInterface: Sync + Send + Hash + PartialEq + Eq + Clone + ToString + Sized;
/// A VL1 level event occurred.
fn event(&self, event: Event);
@ -91,7 +91,7 @@ pub trait NodeStorage: Sync + Send + 'static {
/// Trait to be implemented to provide path hints and a filter to approve physical paths.
pub trait PathFilter: Sync + Send + 'static {
/// Called to check and see if a physical address should be used for ZeroTier traffic to a node.
fn should_use_physical_path<HostSystemImpl: HostSystem>(
fn should_use_physical_path<HostSystemImpl: HostSystem + ?Sized>(
&self,
id: &Identity,
endpoint: &Endpoint,
@ -100,7 +100,7 @@ pub trait PathFilter: Sync + Send + 'static {
) -> bool;
/// Called to look up any statically defined or memorized paths to known nodes.
fn get_path_hints<HostSystemImpl: HostSystem>(
fn get_path_hints<HostSystemImpl: HostSystem + ?Sized>(
&self,
id: &Identity,
) -> Option<
@ -132,7 +132,7 @@ pub trait InnerProtocol: Sync + Send + 'static {
/// Handle a packet, returning true if it was handled by the next layer.
///
/// Do not attempt to handle OK or ERROR. Instead implement handle_ok() and handle_error().
fn handle_packet<HostSystemImpl: HostSystem>(
fn handle_packet<HostSystemImpl: HostSystem + ?Sized>(
&self,
node: &Node<HostSystemImpl>,
source: &Arc<Peer<HostSystemImpl>>,
@ -143,7 +143,7 @@ pub trait InnerProtocol: Sync + Send + 'static {
) -> PacketHandlerResult;
/// Handle errors, returning true if the error was recognized.
fn handle_error<HostSystemImpl: HostSystem>(
fn handle_error<HostSystemImpl: HostSystem + ?Sized>(
&self,
node: &Node<HostSystemImpl>,
source: &Arc<Peer<HostSystemImpl>>,
@ -157,7 +157,7 @@ pub trait InnerProtocol: Sync + Send + 'static {
) -> PacketHandlerResult;
/// Handle an OK, returing true if the OK was recognized.
fn handle_ok<HostSystemImpl: HostSystem>(
fn handle_ok<HostSystemImpl: HostSystem + ?Sized>(
&self,
node: &Node<HostSystemImpl>,
source: &Arc<Peer<HostSystemImpl>>,
@ -176,7 +176,7 @@ pub trait InnerProtocol: Sync + Send + 'static {
/// How often to check the root cluster definitions against the root list and update.
const ROOT_SYNC_INTERVAL_MS: i64 = 1000;
struct RootInfo<HostSystemImpl: HostSystem> {
struct RootInfo<HostSystemImpl: HostSystem + ?Sized> {
/// Root sets to which we are a member.
sets: HashMap<String, Verified<RootSet>>,
@ -206,14 +206,14 @@ struct BackgroundTaskIntervals {
}
/// WHOIS requests and any packets that are waiting on them to be decrypted and authenticated.
struct WhoisQueueItem<HostSystemImpl: HostSystem> {
struct WhoisQueueItem<HostSystemImpl: HostSystem + ?Sized> {
v1_proto_waiting_packets: RingBuffer<(Weak<Path<HostSystemImpl>>, PooledPacketBuffer), WHOIS_MAX_WAITING_PACKETS>,
last_retry_time: i64,
retry_count: u16,
}
/// A ZeroTier VL1 node that can communicate securely with the ZeroTier peer-to-peer network.
pub struct Node<HostSystemImpl: HostSystem> {
pub struct Node<HostSystemImpl: HostSystem + ?Sized> {
/// A random ID generated to identify this particular running instance.
///
/// This can be used to implement multi-homing by allowing remote nodes to distinguish instances
@ -242,8 +242,8 @@ pub struct Node<HostSystemImpl: HostSystem> {
whois_queue: Mutex<HashMap<Address, WhoisQueueItem<HostSystemImpl>>>,
}
impl<HostSystemImpl: HostSystem> Node<HostSystemImpl> {
pub fn new<NodeStorageImpl: NodeStorage>(
impl<HostSystemImpl: HostSystem + ?Sized> Node<HostSystemImpl> {
pub fn new<NodeStorageImpl: NodeStorage + ?Sized>(
host_system: &HostSystemImpl,
storage: &NodeStorageImpl,
auto_generate_identity: bool,
@ -301,6 +301,58 @@ impl<HostSystemImpl: HostSystem> Node<HostSystemImpl> {
self.roots.read().unwrap().online
}
/// Get the current "best" root from among this node's trusted roots.
pub fn best_root(&self) -> Option<Arc<Peer<HostSystemImpl>>> {
self.best_root.read().unwrap().clone()
}
/// Check whether a peer is a root according to any root set trusted by this node.
pub fn is_peer_root(&self, peer: &Peer<HostSystemImpl>) -> bool {
self.roots.read().unwrap().roots.keys().any(|p| p.identity.eq(&peer.identity))
}
/// Returns true if this node is a member of a root set (that it knows about).
pub fn this_node_is_root(&self) -> bool {
self.roots.read().unwrap().this_root_sets.is_some()
}
/// Add a new root set or update the existing root set if the new root set is newer and otherwise matches.
pub fn add_update_root_set(&self, rs: Verified<RootSet>) -> bool {
let mut roots = self.roots.write().unwrap();
if let Some(entry) = roots.sets.get_mut(&rs.name) {
if rs.should_replace(entry) {
*entry = rs;
roots.sets_modified = true;
true
} else {
false
}
} else {
let _ = roots.sets.insert(rs.name.clone(), rs);
roots.sets_modified = true;
true
}
}
/// Returns whether or not this node has any root sets defined.
pub fn has_roots_defined(&self) -> bool {
self.roots.read().unwrap().sets.iter().any(|rs| !rs.1.members.is_empty())
}
/// Initialize with default roots if there are no roots defined, otherwise do nothing.
pub fn init_default_roots(&self) -> bool {
if !self.has_roots_defined() {
self.add_update_root_set(RootSet::zerotier_default())
} else {
false
}
}
/// Get the root sets that this node trusts.
pub fn root_sets(&self) -> Vec<RootSet> {
self.roots.read().unwrap().sets.values().cloned().map(|s| s.unwrap()).collect()
}
pub fn do_background_tasks(&self, host_system: &HostSystemImpl) -> Duration {
const INTERVAL_MS: i64 = 1000;
const INTERVAL: Duration = Duration::from_millis(INTERVAL_MS as u64);
@ -624,7 +676,7 @@ impl<HostSystemImpl: HostSystem> Node<HostSystemImpl> {
INTERVAL
}
pub fn handle_incoming_physical_packet<InnerProtocolImpl: InnerProtocol>(
pub fn handle_incoming_physical_packet<InnerProtocolImpl: InnerProtocol + ?Sized>(
&self,
host_system: &HostSystemImpl,
inner: &InnerProtocolImpl,
@ -864,7 +916,7 @@ impl<HostSystemImpl: HostSystem> Node<HostSystemImpl> {
}
/// Called by Peer when an identity is received from another node, e.g. via OK(WHOIS).
pub(crate) fn handle_incoming_identity<InnerProtocolImpl: InnerProtocol>(
pub(crate) fn handle_incoming_identity<InnerProtocolImpl: InnerProtocol + ?Sized>(
&self,
host_system: &HostSystemImpl,
inner: &InnerProtocolImpl,
@ -900,26 +952,11 @@ impl<HostSystemImpl: HostSystem> Node<HostSystemImpl> {
}
}
/// Get the current "best" root from among this node's trusted roots.
pub fn best_root(&self) -> Option<Arc<Peer<HostSystemImpl>>> {
self.best_root.read().unwrap().clone()
}
/// Check whether a peer is a root according to any root set trusted by this node.
pub fn is_peer_root(&self, peer: &Peer<HostSystemImpl>) -> bool {
self.roots.read().unwrap().roots.keys().any(|p| p.identity.eq(&peer.identity))
}
/// Returns true if this node is a member of a root set (that it knows about).
pub fn this_node_is_root(&self) -> bool {
self.roots.read().unwrap().this_root_sets.is_some()
}
/// Called when a remote node sends us a root set update, applying the update if it is valid and applicable.
///
/// This will only replace an existing root set with a newer one. It won't add a new root set, which must be
/// done by an authorized user or administrator not just by a root.
pub(crate) fn remote_update_root_set(&self, received_from: &Identity, rs: Verified<RootSet>) {
pub(crate) fn on_remote_update_root_set(&self, received_from: &Identity, rs: Verified<RootSet>) {
let mut roots = self.roots.write().unwrap();
if let Some(entry) = roots.sets.get_mut(&rs.name) {
if entry.members.iter().any(|m| m.identity.eq(received_from)) && rs.should_replace(entry) {
@ -929,43 +966,6 @@ impl<HostSystemImpl: HostSystem> Node<HostSystemImpl> {
}
}
/// Add a new root set or update the existing root set if the new root set is newer and otherwise matches.
pub fn add_update_root_set(&self, rs: Verified<RootSet>) -> bool {
let mut roots = self.roots.write().unwrap();
if let Some(entry) = roots.sets.get_mut(&rs.name) {
if rs.should_replace(entry) {
*entry = rs;
roots.sets_modified = true;
true
} else {
false
}
} else {
let _ = roots.sets.insert(rs.name.clone(), rs);
roots.sets_modified = true;
true
}
}
/// Returns whether or not this node has any root sets defined.
pub fn has_roots_defined(&self) -> bool {
self.roots.read().unwrap().sets.iter().any(|rs| !rs.1.members.is_empty())
}
/// Initialize with default roots if there are no roots defined, otherwise do nothing.
pub fn init_default_roots(&self) -> bool {
if !self.has_roots_defined() {
self.add_update_root_set(RootSet::zerotier_default())
} else {
false
}
}
/// Get the root sets that this node trusts.
pub fn root_sets(&self) -> Vec<RootSet> {
self.roots.read().unwrap().sets.values().cloned().map(|s| s.unwrap()).collect()
}
/// Get the canonical Path object corresponding to an endpoint.
pub(crate) fn canonical_path(
&self,
@ -991,12 +991,12 @@ impl<HostSystemImpl: HostSystem> Node<HostSystemImpl> {
/// Key used to look up paths in a hash map
/// This supports copied keys for storing and refs for fast lookup without having to copy anything.
enum PathKey<'a, 'b, HostSystemImpl: HostSystem> {
enum PathKey<'a, 'b, HostSystemImpl: HostSystem + ?Sized> {
Copied(Endpoint, HostSystemImpl::LocalSocket),
Ref(&'a Endpoint, &'b HostSystemImpl::LocalSocket),
}
impl<'a, 'b, HostSystemImpl: HostSystem> Hash for PathKey<'a, 'b, HostSystemImpl> {
impl<'a, 'b, HostSystemImpl: HostSystem + ?Sized> Hash for PathKey<'a, 'b, HostSystemImpl> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
match self {
Self::Copied(ep, ls) => {
@ -1011,7 +1011,7 @@ impl<'a, 'b, HostSystemImpl: HostSystem> Hash for PathKey<'a, 'b, HostSystemImpl
}
}
impl<HostSystemImpl: HostSystem> PartialEq for PathKey<'_, '_, HostSystemImpl> {
impl<HostSystemImpl: HostSystem + ?Sized> PartialEq for PathKey<'_, '_, HostSystemImpl> {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Copied(ep1, ls1), Self::Copied(ep2, ls2)) => ep1.eq(ep2) && ls1.eq(ls2),
@ -1022,9 +1022,9 @@ impl<HostSystemImpl: HostSystem> PartialEq for PathKey<'_, '_, HostSystemImpl> {
}
}
impl<HostSystemImpl: HostSystem> Eq for PathKey<'_, '_, HostSystemImpl> {}
impl<HostSystemImpl: HostSystem + ?Sized> Eq for PathKey<'_, '_, HostSystemImpl> {}
impl<'a, 'b, HostSystemImpl: HostSystem> PathKey<'a, 'b, HostSystemImpl> {
impl<'a, 'b, HostSystemImpl: HostSystem + ?Sized> PathKey<'a, 'b, HostSystemImpl> {
#[inline(always)]
fn local_socket(&self) -> &HostSystemImpl::LocalSocket {
match self {
@ -1048,7 +1048,7 @@ pub struct DummyInnerProtocol;
impl InnerProtocol for DummyInnerProtocol {
#[inline(always)]
fn handle_packet<HostSystemImpl: HostSystem>(
fn handle_packet<HostSystemImpl: HostSystem + ?Sized>(
&self,
_node: &Node<HostSystemImpl>,
_source: &Arc<Peer<HostSystemImpl>>,
@ -1061,7 +1061,7 @@ impl InnerProtocol for DummyInnerProtocol {
}
#[inline(always)]
fn handle_error<HostSystemImpl: HostSystem>(
fn handle_error<HostSystemImpl: HostSystem + ?Sized>(
&self,
_node: &Node<HostSystemImpl>,
_source: &Arc<Peer<HostSystemImpl>>,
@ -1077,7 +1077,7 @@ impl InnerProtocol for DummyInnerProtocol {
}
#[inline(always)]
fn handle_ok<HostSystemImpl: HostSystem>(
fn handle_ok<HostSystemImpl: HostSystem + ?Sized>(
&self,
_node: &Node<HostSystemImpl>,
_source: &Arc<Peer<HostSystemImpl>>,
@ -1103,7 +1103,7 @@ pub struct DummyPathFilter;
impl PathFilter for DummyPathFilter {
#[inline(always)]
fn should_use_physical_path<HostSystemImpl: HostSystem>(
fn should_use_physical_path<HostSystemImpl: HostSystem + ?Sized>(
&self,
_id: &Identity,
_endpoint: &Endpoint,
@ -1114,7 +1114,7 @@ impl PathFilter for DummyPathFilter {
}
#[inline(always)]
fn get_path_hints<HostSystemImpl: HostSystem>(
fn get_path_hints<HostSystemImpl: HostSystem + ?Sized>(
&self,
_id: &Identity,
) -> Option<

View file

@ -24,7 +24,7 @@ pub(crate) enum PathServiceResult {
/// These are maintained in Node and canonicalized so that all unique paths have
/// one and only one unique path object. That enables statistics to be tracked
/// for them and uniform application of things like keepalives.
pub struct Path<HostSystemImpl: HostSystem> {
pub struct Path<HostSystemImpl: HostSystem + ?Sized> {
pub endpoint: Endpoint,
pub local_socket: HostSystemImpl::LocalSocket,
pub local_interface: HostSystemImpl::LocalInterface,
@ -34,7 +34,7 @@ pub struct Path<HostSystemImpl: HostSystem> {
fragmented_packets: Mutex<HashMap<u64, v1::FragmentedPacket, PacketIdHasher>>,
}
impl<HostSystemImpl: HostSystem> Path<HostSystemImpl> {
impl<HostSystemImpl: HostSystem + ?Sized> Path<HostSystemImpl> {
#[inline]
pub fn new(
endpoint: Endpoint,

View file

@ -22,7 +22,7 @@ use crate::{VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION};
pub(crate) const SERVICE_INTERVAL_MS: i64 = 10000;
pub struct Peer<HostSystemImpl: HostSystem> {
pub struct Peer<HostSystemImpl: HostSystem + ?Sized> {
pub identity: Identity,
v1_proto_static_secret: v1::SymmetricSecret,
@ -39,7 +39,7 @@ pub struct Peer<HostSystemImpl: HostSystem> {
remote_node_info: RwLock<RemoteNodeInfo>,
}
struct PeerPath<HostSystemImpl: HostSystem> {
struct PeerPath<HostSystemImpl: HostSystem + ?Sized> {
path: Weak<Path<HostSystemImpl>>,
last_receive_time_ticks: i64,
}
@ -51,11 +51,11 @@ struct RemoteNodeInfo {
}
/// Sort a list of paths by quality or priority, with best paths first.
fn prioritize_paths<HostSystemImpl: HostSystem>(paths: &mut Vec<PeerPath<HostSystemImpl>>) {
fn prioritize_paths<HostSystemImpl: HostSystem + ?Sized>(paths: &mut Vec<PeerPath<HostSystemImpl>>) {
paths.sort_unstable_by(|a, b| a.last_receive_time_ticks.cmp(&b.last_receive_time_ticks).reverse());
}
impl<HostSystemImpl: HostSystem> Peer<HostSystemImpl> {
impl<HostSystemImpl: HostSystem + ?Sized> Peer<HostSystemImpl> {
/// Create a new peer.
///
/// This only returns None if this_node_identity does not have its secrets or if some
@ -451,7 +451,7 @@ impl<HostSystemImpl: HostSystem> Peer<HostSystemImpl> {
/// those fragments after the main packet header and first chunk.
///
/// This returns true if the packet decrypted and passed authentication.
pub(crate) fn v1_proto_receive<InnerProtocolImpl: InnerProtocol>(
pub(crate) fn v1_proto_receive<InnerProtocolImpl: InnerProtocol + ?Sized>(
self: &Arc<Self>,
node: &Node<HostSystemImpl>,
host_system: &HostSystemImpl,
@ -560,7 +560,7 @@ impl<HostSystemImpl: HostSystem> Peer<HostSystemImpl> {
return PacketHandlerResult::Error;
}
fn handle_incoming_hello<InnerProtocolImpl: InnerProtocol>(
fn handle_incoming_hello<InnerProtocolImpl: InnerProtocol + ?Sized>(
&self,
host_system: &HostSystemImpl,
inner: &InnerProtocolImpl,
@ -620,7 +620,7 @@ impl<HostSystemImpl: HostSystem> Peer<HostSystemImpl> {
return PacketHandlerResult::Error;
}
fn handle_incoming_error<InnerProtocolImpl: InnerProtocol>(
fn handle_incoming_error<InnerProtocolImpl: InnerProtocol + ?Sized>(
self: &Arc<Self>,
_: &HostSystemImpl,
inner: &InnerProtocolImpl,
@ -654,7 +654,7 @@ impl<HostSystemImpl: HostSystem> Peer<HostSystemImpl> {
return PacketHandlerResult::Error;
}
fn handle_incoming_ok<InnerProtocolImpl: InnerProtocol>(
fn handle_incoming_ok<InnerProtocolImpl: InnerProtocol + ?Sized>(
self: &Arc<Self>,
host_system: &HostSystemImpl,
inner: &InnerProtocolImpl,
@ -752,7 +752,7 @@ impl<HostSystemImpl: HostSystem> Peer<HostSystemImpl> {
return PacketHandlerResult::Error;
}
fn handle_incoming_whois<InnerProtocolImpl: InnerProtocol>(
fn handle_incoming_whois<InnerProtocolImpl: InnerProtocol + ?Sized>(
self: &Arc<Self>,
host_system: &HostSystemImpl,
inner: &InnerProtocolImpl,
@ -812,7 +812,7 @@ impl<HostSystemImpl: HostSystem> Peer<HostSystemImpl> {
return PacketHandlerResult::Ok;
}
fn handle_incoming_echo<InnerProtocolImpl: InnerProtocol>(
fn handle_incoming_echo<InnerProtocolImpl: InnerProtocol + ?Sized>(
&self,
host_system: &HostSystemImpl,
inner: &InnerProtocolImpl,
@ -866,21 +866,21 @@ impl<HostSystemImpl: HostSystem> Peer<HostSystemImpl> {
}
}
impl<HostSystemImpl: HostSystem> Hash for Peer<HostSystemImpl> {
impl<HostSystemImpl: HostSystem + ?Sized> Hash for Peer<HostSystemImpl> {
#[inline(always)]
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
state.write_u64(self.identity.address.into());
}
}
impl<HostSystemImpl: HostSystem> PartialEq for Peer<HostSystemImpl> {
impl<HostSystemImpl: HostSystem + ?Sized> PartialEq for Peer<HostSystemImpl> {
#[inline(always)]
fn eq(&self, other: &Self) -> bool {
self.identity.fingerprint.eq(&other.identity.fingerprint)
}
}
impl<HostSystemImpl: HostSystem> Eq for Peer<HostSystemImpl> {}
impl<HostSystemImpl: HostSystem + ?Sized> Eq for Peer<HostSystemImpl> {}
fn v1_proto_try_aead_decrypt(
secret: &v1::SymmetricSecret,

View file

@ -11,7 +11,7 @@ pub trait SwitchInterface: Sync + Send {}
pub struct Switch {}
impl InnerProtocol for Switch {
fn handle_packet<HostSystemImpl: HostSystem>(
fn handle_packet<HostSystemImpl: HostSystem + ?Sized>(
&self,
node: &Node<HostSystemImpl>,
source: &Arc<Peer<HostSystemImpl>>,
@ -23,7 +23,7 @@ impl InnerProtocol for Switch {
PacketHandlerResult::NotHandled
}
fn handle_error<HostSystemImpl: HostSystem>(
fn handle_error<HostSystemImpl: HostSystem + ?Sized>(
&self,
node: &Node<HostSystemImpl>,
source: &Arc<Peer<HostSystemImpl>>,
@ -38,7 +38,7 @@ impl InnerProtocol for Switch {
PacketHandlerResult::NotHandled
}
fn handle_ok<HostSystemImpl: HostSystem>(
fn handle_ok<HostSystemImpl: HostSystem + ?Sized>(
&self,
node: &Node<HostSystemImpl>,
source: &Arc<Peer<HostSystemImpl>>,

View file

@ -36,7 +36,7 @@ pub struct VL1Service<
inner: Arc<InnerProtocolImpl>,
path_filter: Arc<PathFilterImpl>,
buffer_pool: Arc<PacketBufferPool>,
node_container: Option<Node<Self>>,
node_container: Option<Node<Self>>, // never None, set in new()
}
struct VL1ServiceMutableState {
@ -71,6 +71,7 @@ impl<NodeStorageImpl: NodeStorage + 'static, PathFilterImpl: PathFilter + 'stati
)),
node_container: None,
};
service.node_container.replace(Node::new(&service, &*service.storage, true, false)?);
let service = Arc::new(service);