mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-16 17:33:45 +02:00
Network ID object and some more cleanup.
This commit is contained in:
parent
6e55419581
commit
85b5f0c5e0
5 changed files with 148 additions and 13 deletions
|
@ -6,9 +6,6 @@
|
||||||
* https://www.zerotier.com/
|
* https://www.zerotier.com/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate lazy_static;
|
|
||||||
|
|
||||||
pub const VERSION_MAJOR: u8 = 1;
|
pub const VERSION_MAJOR: u8 = 1;
|
||||||
pub const VERSION_MINOR: u8 = 99;
|
pub const VERSION_MINOR: u8 = 99;
|
||||||
pub const VERSION_REVISION: u8 = 1;
|
pub const VERSION_REVISION: u8 = 1;
|
||||||
|
|
|
@ -406,17 +406,8 @@ impl InetAddress {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the address family of this InetAddress: AF_INET, AF_INET6, or 0 if uninitialized.
|
/// Get the address family of this InetAddress: AF_INET, AF_INET6, or 0 if uninitialized.
|
||||||
#[inline(always)]
|
|
||||||
#[cfg(not(target_os = "linux"))]
|
|
||||||
pub fn family(&self) -> u8 {
|
pub fn family(&self) -> u8 {
|
||||||
unsafe { self.sa.sa_family }
|
unsafe { self.sa.sa_family as u8 }
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the address family of this InetAddress: AF_INET, AF_INET6, or 0 if uninitialized.
|
|
||||||
#[inline(always)]
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
pub fn family(&self) -> u16 {
|
|
||||||
unsafe { self.sa.sa_family }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a pointer to the C "sockaddr" structure and the size of the returned structure in bytes.
|
/// Get a pointer to the C "sockaddr" structure and the size of the returned structure in bytes.
|
||||||
|
|
|
@ -12,6 +12,7 @@ use std::num::NonZeroI64;
|
||||||
use std::sync::atomic::{AtomicI64, Ordering};
|
use std::sync::atomic::{AtomicI64, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use lazy_static::lazy_static;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use zerotier_core_crypto::hash::SHA384_HASH_SIZE;
|
use zerotier_core_crypto::hash::SHA384_HASH_SIZE;
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mod multicastgroup;
|
mod multicastgroup;
|
||||||
|
mod networkid;
|
||||||
mod switch;
|
mod switch;
|
||||||
|
|
||||||
pub use multicastgroup::MulticastGroup;
|
pub use multicastgroup::MulticastGroup;
|
||||||
|
pub use networkid::NetworkId;
|
||||||
pub use switch::{Switch, SwitchInterface};
|
pub use switch::{Switch, SwitchInterface};
|
||||||
|
|
144
zerotier-network-hypervisor/src/vl2/networkid.rs
Normal file
144
zerotier-network-hypervisor/src/vl2/networkid.rs
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* (c)2021 ZeroTier, Inc.
|
||||||
|
* https://www.zerotier.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
|
use std::num::NonZeroU64;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
|
use crate::error::InvalidFormatError;
|
||||||
|
use crate::util::buffer::Buffer;
|
||||||
|
use crate::util::hex::HEX_CHARS;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct NetworkId(NonZeroU64);
|
||||||
|
|
||||||
|
impl NetworkId {
|
||||||
|
/// Get an address from a 64-bit integer or return None if it is zero or reserved.
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn from_u64(i: u64) -> Option<NetworkId> {
|
||||||
|
NonZeroU64::new(i).map(|i| Self(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn from_bytes(b: &[u8]) -> Option<NetworkId> {
|
||||||
|
if b.len() >= 8 {
|
||||||
|
Self::from_bytes_fixed(b[0..8].try_into().unwrap())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn from_bytes_fixed(b: &[u8; 8]) -> Option<NetworkId> {
|
||||||
|
Self::from_u64(u64::from_be_bytes(*b))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn to_bytes(&self) -> [u8; 8] {
|
||||||
|
self.0.get().to_be_bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn to_u64(&self) -> u64 {
|
||||||
|
self.0.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub(crate) fn marshal<const BL: usize>(&self, buf: &mut Buffer<BL>) -> std::io::Result<()> {
|
||||||
|
buf.append_u64(self.0.get())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub(crate) fn unmarshal<const BL: usize>(buf: &Buffer<BL>, cursor: &mut usize) -> std::io::Result<Option<Self>> {
|
||||||
|
Ok(Self::from_u64(buf.read_u64(cursor)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for NetworkId {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
let mut v = self.0.get();
|
||||||
|
let mut s = String::with_capacity(16);
|
||||||
|
for _ in 0..16 {
|
||||||
|
s.push(HEX_CHARS[(v >> 60) as usize] as char);
|
||||||
|
v <<= 4;
|
||||||
|
}
|
||||||
|
s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for NetworkId {
|
||||||
|
type Err = InvalidFormatError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
NetworkId::from_bytes(crate::util::hex::from_string(s).as_slice()).map_or_else(|| Err(InvalidFormatError), |a| Ok(a))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hash for NetworkId {
|
||||||
|
#[inline(always)]
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
state.write_u64(self.0.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for NetworkId {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
if serializer.is_human_readable() {
|
||||||
|
serializer.serialize_str(self.to_string().as_str())
|
||||||
|
} else {
|
||||||
|
serializer.serialize_bytes(&self.to_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NetworkIdVisitor;
|
||||||
|
|
||||||
|
impl<'de> serde::de::Visitor<'de> for NetworkIdVisitor {
|
||||||
|
type Value = NetworkId;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
formatter.write_str("a ZeroTier network ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: serde::de::Error,
|
||||||
|
{
|
||||||
|
if v.len() == 8 {
|
||||||
|
NetworkId::from_bytes(v).map_or_else(|| Err(E::custom("object too large")), |a| Ok(a))
|
||||||
|
} else {
|
||||||
|
Err(E::custom("object too large"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: serde::de::Error,
|
||||||
|
{
|
||||||
|
NetworkId::from_str(v).map_err(|e| E::custom(e.to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for NetworkId {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<NetworkId, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
if deserializer.is_human_readable() {
|
||||||
|
deserializer.deserialize_str(NetworkIdVisitor)
|
||||||
|
} else {
|
||||||
|
deserializer.deserialize_bytes(NetworkIdVisitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue