diff --git a/zerotier-network-hypervisor/src/lib.rs b/zerotier-network-hypervisor/src/lib.rs index 95a7d3dde..b1b350577 100644 --- a/zerotier-network-hypervisor/src/lib.rs +++ b/zerotier-network-hypervisor/src/lib.rs @@ -15,5 +15,3 @@ mod networkhypervisor; pub use event::Event; pub use networkhypervisor::{Interface, NetworkHypervisor}; pub use vl1::protocol::{PacketBuffer, PooledPacketBuffer}; - -pub use async_trait::async_trait; diff --git a/zerotier-network-hypervisor/src/vl1/identity.rs b/zerotier-network-hypervisor/src/vl1/identity.rs index 5ae8519f7..e43185614 100644 --- a/zerotier-network-hypervisor/src/vl1/identity.rs +++ b/zerotier-network-hypervisor/src/vl1/identity.rs @@ -216,9 +216,7 @@ impl Identity { /// /// This is somewhat time consuming due to the memory-intensive work algorithm. pub fn validate_identity(&self) -> bool { - if self.p384.is_some() { - let p384 = self.p384.as_ref().unwrap(); - + if let Some(p384) = self.p384.as_ref() { let mut self_sign_buf: Vec = Vec::with_capacity(ADDRESS_SIZE + 4 + C25519_PUBLIC_KEY_SIZE + ED25519_PUBLIC_KEY_SIZE + P384_PUBLIC_KEY_SIZE + P384_PUBLIC_KEY_SIZE); let _ = self_sign_buf.write_all(&self.address.to_bytes()); let _ = self_sign_buf.write_all(&self.c25519); @@ -260,7 +258,7 @@ impl Identity { /// Nothing actually uses a 512-bit secret directly, but if the base secret is 512 bits then /// no entropy is lost when deriving smaller secrets with a KDF. pub fn agree(&self, other: &Identity) -> Option> { - self.secret.as_ref().and_then(|secret| { + if let Some(secret) = self.secret.as_ref() { let c25519_secret = Secret(SHA512::hash(&secret.c25519.agree(&other.c25519).0)); // FIPS note: FIPS-compliant exchange algorithms must be the last algorithms in any HKDF chain @@ -271,7 +269,9 @@ impl Identity { } else { Some(c25519_secret) } - }) + } else { + None + } } /// Sign a message with this identity. @@ -281,8 +281,7 @@ impl Identity { /// /// A return of None happens if we don't have our secret key(s) or some other error occurs. pub fn sign(&self, msg: &[u8], legacy_ed25519_only: bool) -> Option> { - if self.secret.is_some() { - let secret = self.secret.as_ref().unwrap(); + if let Some(secret) = self.secret.as_ref() { if legacy_ed25519_only { Some(secret.ed25519.sign_zt(msg).to_vec()) } else if let Some(p384s) = secret.p384.as_ref() { diff --git a/zerotier-network-hypervisor/src/vl1/peer.rs b/zerotier-network-hypervisor/src/vl1/peer.rs index 62ac71f4b..30f8d0622 100644 --- a/zerotier-network-hypervisor/src/vl1/peer.rs +++ b/zerotier-network-hypervisor/src/vl1/peer.rs @@ -438,11 +438,11 @@ impl Peer { pub(crate) async fn send_hello(&self, si: &SI, node: &Node, explicit_endpoint: Option<&Endpoint>) -> bool { let mut path = None; let destination = if let Some(explicit_endpoint) = explicit_endpoint { - explicit_endpoint.clone() + explicit_endpoint } else { if let Some(p) = self.path(node) { let _ = path.insert(p); - path.as_ref().unwrap().endpoint.clone() + &path.as_ref().unwrap().endpoint } else { return false; } @@ -534,15 +534,15 @@ impl Peer { debug_event!(si, "HELLO -> {} @ {} ({} bytes)", self.identity.address.to_string(), destination.to_string(), packet.len()); } - if let Some(p) = path { - if self.internal_send(si, &destination, Some(&p.local_socket), Some(&p.local_interface), max_fragment_size, &packet).await { + if let Some(p) = path.as_ref() { + if self.internal_send(si, destination, Some(&p.local_socket), Some(&p.local_interface), max_fragment_size, &packet).await { p.log_send_anything(time_ticks); true } else { false } } else { - self.internal_send(si, &destination, None, None, max_fragment_size, &packet).await + self.internal_send(si, destination, None, None, max_fragment_size, &packet).await } } diff --git a/zerotier-network-hypervisor/src/vl1/rootset.rs b/zerotier-network-hypervisor/src/vl1/rootset.rs index 7ed912bad..67abf66be 100644 --- a/zerotier-network-hypervisor/src/vl1/rootset.rs +++ b/zerotier-network-hypervisor/src/vl1/rootset.rs @@ -176,7 +176,7 @@ impl RootSet { /// All current members must sign whether they are disabled (witnessing) or active. The verify() /// method will return true when signing is complete. pub fn sign(&mut self, member_identity: &Identity) -> bool { - let signature = member_identity.sign(self.marshal_for_signing().as_bytes(), Identity::ALGORITHM_ALL, false); + let signature = member_identity.sign(self.marshal_for_signing().as_bytes(), false); let unsigned_entry = self.members.iter().find_map(|m| if m.identity.eq(member_identity) { Some(m.clone()) } else { None }); if unsigned_entry.is_some() && signature.is_some() { let unsigned_entry = unsigned_entry.unwrap(); diff --git a/zerotier-system-service/Cargo.lock b/zerotier-system-service/Cargo.lock index 0c2c8e4aa..8f81b7f09 100644 --- a/zerotier-system-service/Cargo.lock +++ b/zerotier-system-service/Cargo.lock @@ -1056,6 +1056,7 @@ dependencies = [ name = "zerotier-system-service" version = "0.1.0" dependencies = [ + "async-trait", "clap", "lazy_static", "libc", diff --git a/zerotier-system-service/Cargo.toml b/zerotier-system-service/Cargo.toml index 8432d1e71..80868086a 100644 --- a/zerotier-system-service/Cargo.toml +++ b/zerotier-system-service/Cargo.toml @@ -14,6 +14,7 @@ panic = 'abort' [dependencies] zerotier-network-hypervisor = { path = "../zerotier-network-hypervisor" } zerotier-core-crypto = { path = "../zerotier-core-crypto" } +async-trait = "^0" num-traits = "^0" tokio = { version = "^1", features = ["full"], default-features = false } serde = { version = "^1", features = ["derive"], default-features = false } diff --git a/zerotier-system-service/src/service.rs b/zerotier-system-service/src/service.rs index e05f03b5f..0a3f05983 100644 --- a/zerotier-system-service/src/service.rs +++ b/zerotier-system-service/src/service.rs @@ -6,7 +6,8 @@ use std::path::Path; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; -use zerotier_network_hypervisor::async_trait; +use async_trait::async_trait; + use zerotier_network_hypervisor::vl1::*; use zerotier_network_hypervisor::vl2::*; use zerotier_network_hypervisor::*; diff --git a/zerotier-system-service/src/vnic/common.rs b/zerotier-system-service/src/vnic/common.rs index b3157efd5..cd146b877 100644 --- a/zerotier-system-service/src/vnic/common.rs +++ b/zerotier-system-service/src/vnic/common.rs @@ -39,7 +39,8 @@ pub fn get_l2_multicast_subscriptions(dev: &str) -> HashSet { let la: &libc::sockaddr_dl = &*((*i).ifma_addr.cast()); if la.sdl_alen == 6 && in_.sdl_nlen <= dev.len().as_() && libc::memcmp(dev.as_ptr().cast(), in_.sdl_data.as_ptr().cast(), in_.sdl_nlen.as_()) == 0 { let mi = la.sdl_nlen as usize; - MAC::from_u64((la.sdl_data[mi] as u64) << 40 | (la.sdl_data[mi + 1] as u64) << 32 | (la.sdl_data[mi + 2] as u64) << 24 | (la.sdl_data[mi + 3] as u64) << 16 | (la.sdl_data[mi + 4] as u64) << 8 | la.sdl_data[mi + 5] as u64).map(|mac| groups.insert(mac)); + MAC::from_u64((la.sdl_data[mi] as u64) << 40 | (la.sdl_data[mi + 1] as u64) << 32 | (la.sdl_data[mi + 2] as u64) << 24 | (la.sdl_data[mi + 3] as u64) << 16 | (la.sdl_data[mi + 4] as u64) << 8 | la.sdl_data[mi + 5] as u64) + .map(|mac| groups.insert(mac)); } } i = (*i).ifma_next; @@ -53,6 +54,5 @@ pub fn get_l2_multicast_subscriptions(dev: &str) -> HashSet { /// Linux stores this stuff in /proc and it needs to be fetched from there. #[cfg(target_os = "linux")] pub fn get_l2_multicast_subscriptions(dev: &str) -> HashSet { - let mut groups: HashSet = HashSet::new(); - groups + todo!() } diff --git a/zerotier-system-service/src/vnic/vnic.rs b/zerotier-system-service/src/vnic/vnic.rs index b7a801ea5..cafc14602 100644 --- a/zerotier-system-service/src/vnic/vnic.rs +++ b/zerotier-system-service/src/vnic/vnic.rs @@ -1,19 +1,22 @@ // (c) 2020-2022 ZeroTier, Inc. -- currently propritery pending actual release and licensing. See LICENSE.md. +use async_trait::async_trait; + use zerotier_network_hypervisor::vl1::{InetAddress, MAC}; use zerotier_network_hypervisor::vl2::MulticastGroup; /// Virtual network interface +#[async_trait] pub trait VNIC { /// Add a new IPv4 or IPv6 address to this interface, returning true on success. - fn add_ip(&self, ip: &InetAddress) -> bool; + async fn add_ip(&self, ip: &InetAddress) -> bool; /// Remove an IPv4 or IPv6 address, returning true on success. /// Nothing happens if the address is not found. - fn remove_ip(&self, ip: &InetAddress) -> bool; + async fn remove_ip(&self, ip: &InetAddress) -> bool; /// Enumerate all IPs on this interface including ones assigned outside ZeroTier. - fn ips(&self) -> Vec; + async fn ips(&self) -> Vec; /// Get the OS-specific device name for this interface, e.g. zt## or tap##. fn device_name(&self) -> String; @@ -22,8 +25,8 @@ pub trait VNIC { /// This doesn't do any IGMP snooping. It just reports the groups the port /// knows about. On some OSes this may not be supported in which case it /// will return an empty set. - fn get_multicast_groups(&self) -> std::collections::BTreeSet; + async fn get_multicast_groups(&self) -> std::collections::BTreeSet; /// Inject an Ethernet frame into this port. - fn put(&self, source_mac: &MAC, dest_mac: &MAC, ethertype: u16, vlan_id: u16, data: *const u8, len: usize) -> bool; + async fn put(&self, source_mac: &MAC, dest_mac: &MAC, ethertype: u16, vlan_id: u16, data: &[u8]) -> bool; }