mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-03 19:13:43 +02:00
Docs, stub out VL2, create root level Node that is a composition of VL1 and VL2.
This commit is contained in:
parent
39aeab6819
commit
e732c3569c
14 changed files with 128 additions and 26 deletions
|
@ -12,6 +12,8 @@ pub mod vl1;
|
|||
pub mod vl2;
|
||||
pub mod defaults;
|
||||
|
||||
mod node;
|
||||
|
||||
pub const VERSION_MAJOR: u8 = 1;
|
||||
pub const VERSION_MINOR: u8 = 99;
|
||||
pub const VERSION_REVISION: u8 = 1;
|
||||
|
|
62
zerotier-network-hypervisor/src/node.rs
Normal file
62
zerotier-network-hypervisor/src/node.rs
Normal file
|
@ -0,0 +1,62 @@
|
|||
/* 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::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::vl1::node::VL1CallerInterface;
|
||||
use crate::error::InvalidParameterError;
|
||||
use crate::vl1::{PacketBuffer, PacketBufferPool, Address, Identity, Endpoint};
|
||||
|
||||
pub trait CallerInterface: VL1CallerInterface {
|
||||
}
|
||||
|
||||
/// A complete ZeroTier node.
|
||||
///
|
||||
/// This is a composition of the VL1 node and the VL2 virtual switch.
|
||||
pub struct Node {
|
||||
vl1: crate::vl1::node::Node,
|
||||
vl2: crate::vl2::switch::Switch,
|
||||
}
|
||||
|
||||
impl Node {
|
||||
pub fn new<CI: CallerInterface>(ci: &CI, auto_generate_identity_type: Option<crate::vl1::identity::Type>) -> Result<Node, InvalidParameterError> {
|
||||
Ok(Node {
|
||||
vl1: crate::vl1::node::Node::new(ci, auto_generate_identity_type)?,
|
||||
vl2: crate::vl2::switch::Switch::new(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Obtain a new packet buffer from the buffer pool.
|
||||
///
|
||||
/// The returned object is a Pooled<Buffer<>> instance. The buffer is returned to the pool when the container is destroyed.
|
||||
#[inline(always)]
|
||||
pub fn get_packet_buffer(&self) -> PacketBuffer { self.vl1.get_packet_buffer() }
|
||||
|
||||
/// Get a direct reference to the packet buffer pool.
|
||||
#[inline(always)]
|
||||
pub fn packet_buffer_pool(&self) -> &Arc<PacketBufferPool> { self.vl1.packet_buffer_pool() }
|
||||
|
||||
#[inline(always)]
|
||||
pub fn address(&self) -> Address { self.vl1.address() }
|
||||
|
||||
#[inline(always)]
|
||||
pub fn identity(&self) -> &Identity { self.vl1.identity() }
|
||||
|
||||
#[inline(always)]
|
||||
pub fn fips_mode(&self) -> bool { self.vl1.fips_mode() }
|
||||
|
||||
pub fn do_background_tasks<CI: CallerInterface>(&self, ci: &CI) -> Duration {
|
||||
self.vl1.do_background_tasks(ci)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn wire_receive<CI: VL1CallerInterface>(&self, ci: &CI, source_endpoint: &Endpoint, source_local_socket: i64, source_local_interface: i64, mut data: PacketBuffer) {
|
||||
self.vl1.wire_receive(ci, &self.vl2, source_endpoint, source_local_socket, source_local_interface, data)
|
||||
}
|
||||
}
|
|
@ -111,9 +111,11 @@ impl Endpoint {
|
|||
ip.marshal(buf)
|
||||
}
|
||||
Endpoint::IpUdp(ip) => {
|
||||
// IP/UDP endpoints are marshaled as naked InetAddress objects for backward
|
||||
// compatibility. This is why 16 is added to all the other type IDs. Naked
|
||||
// InetAddress objects always start with either 4 or 6.
|
||||
// Wire encoding of IP/UDP type endpoints is the same as naked InetAddress
|
||||
// objects for backward compatibility. That way a naked InetAddress unmarshals
|
||||
// here as an IP/UDP Endpoint and vice versa. Supporting this is why 16 is added
|
||||
// to all Endpoint type IDs for wire encoding so that values of 4 or 6 can be
|
||||
// interpreted as IP/UDP InetAddress.
|
||||
ip.marshal(buf)
|
||||
}
|
||||
Endpoint::IpTcp(ip) => {
|
||||
|
|
0
zerotier-network-hypervisor/src/vl1/ephemeral.rs
Normal file
0
zerotier-network-hypervisor/src/vl1/ephemeral.rs
Normal file
|
@ -22,6 +22,7 @@ pub(crate) mod address;
|
|||
pub(crate) mod mac;
|
||||
pub(crate) mod fragmentedpacket;
|
||||
pub(crate) mod whoisqueue;
|
||||
pub(crate) mod ephemeral;
|
||||
|
||||
pub use address::Address;
|
||||
pub use mac::MAC;
|
||||
|
|
|
@ -142,7 +142,6 @@ pub struct Node {
|
|||
whois: WhoisQueue,
|
||||
buffer_pool: Arc<PacketBufferPool>,
|
||||
secure_prng: SecureRandom,
|
||||
fips_mode: bool,
|
||||
}
|
||||
|
||||
impl Node {
|
||||
|
@ -183,7 +182,6 @@ impl Node {
|
|||
whois: WhoisQueue::new(),
|
||||
buffer_pool: Arc::new(PacketBufferPool::new(64, PooledBufferFactory)),
|
||||
secure_prng: SecureRandom::get(),
|
||||
fips_mode: false,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -202,9 +200,6 @@ impl Node {
|
|||
/// Get a peer by address.
|
||||
pub fn peer(&self, a: Address) -> Option<Arc<Peer>> { self.peers.get(&a).map(|peer| peer.value().clone()) }
|
||||
|
||||
#[inline(always)]
|
||||
pub fn fips_mode(&self) -> bool { self.fips_mode }
|
||||
|
||||
/// Get all peers currently in the peer cache.
|
||||
pub fn peers(&self) -> Vec<Arc<Peer>> {
|
||||
let mut v: Vec<Arc<Peer>> = Vec::new();
|
||||
|
@ -215,21 +210,20 @@ impl Node {
|
|||
v
|
||||
}
|
||||
|
||||
pub fn fips_mode(&self) -> bool { false }
|
||||
|
||||
/// Run background tasks and return desired delay until next call in milliseconds.
|
||||
///
|
||||
/// This should only be called once at a time. It technically won't hurt anything to
|
||||
/// call concurrently but it will waste CPU cycles.
|
||||
pub fn do_background_tasks<CI: VL1CallerInterface>(&self, ci: &CI) -> Duration {
|
||||
let mut intervals = self.intervals.lock();
|
||||
let tt = ci.time_ticks();
|
||||
|
||||
if intervals.whois.gate(tt) {
|
||||
self.whois.on_interval(self, ci, tt);
|
||||
self.whois.call_every_interval(self, ci, tt);
|
||||
}
|
||||
|
||||
if intervals.paths.gate(tt) {
|
||||
self.paths.retain(|_, path| {
|
||||
path.on_interval(ci, tt);
|
||||
path.call_every_interval(ci, tt);
|
||||
todo!();
|
||||
true
|
||||
});
|
||||
|
@ -237,7 +231,7 @@ impl Node {
|
|||
|
||||
if intervals.peers.gate(tt) {
|
||||
self.peers.retain(|_, peer| {
|
||||
peer.on_interval(ci, tt);
|
||||
peer.call_every_interval(ci, tt);
|
||||
todo!();
|
||||
true
|
||||
});
|
||||
|
@ -251,14 +245,16 @@ impl Node {
|
|||
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_bytes(&fragment_header.dest);
|
||||
if dest.is_some() {
|
||||
let time_ticks = ci.time_ticks();
|
||||
let dest = dest.unwrap();
|
||||
if dest == self.identity.address() {
|
||||
// Handle packets addressed to this node.
|
||||
|
||||
let path = self.path(source_endpoint, source_local_socket, source_local_interface);
|
||||
path.log_receive(time_ticks);
|
||||
|
||||
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| {
|
||||
|
@ -301,6 +297,8 @@ impl Node {
|
|||
}
|
||||
|
||||
} else {
|
||||
// Forward packets not destined for this node.
|
||||
// TODO: need to add check for whether this node should forward. Regular nodes should only forward if a trust relationship exists.
|
||||
|
||||
if fragment_header.is_fragment() {
|
||||
if fragment_header.increment_hops() > FORWARD_MAX_HOPS {
|
||||
|
|
|
@ -103,7 +103,7 @@ impl Path {
|
|||
|
||||
/// Called every INTERVAL during background tasks.
|
||||
#[inline(always)]
|
||||
pub(crate) fn on_interval<CI: VL1CallerInterface>(&self, ct: &CI, time_ticks: i64) {
|
||||
pub(crate) fn call_every_interval<CI: VL1CallerInterface>(&self, ct: &CI, time_ticks: i64) {
|
||||
self.fragmented_packets.lock().retain(|packet_id, frag| (time_ticks - frag.ts_ticks) < FRAGMENT_EXPIRATION);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -504,7 +504,7 @@ impl Peer {
|
|||
|
||||
/// Called every INTERVAL during background tasks.
|
||||
#[inline(always)]
|
||||
pub(crate) fn on_interval<CI: VL1CallerInterface>(&self, ct: &CI, time_ticks: i64) {}
|
||||
pub(crate) fn call_every_interval<CI: VL1CallerInterface>(&self, ct: &CI, time_ticks: i64) {}
|
||||
|
||||
#[inline(always)]
|
||||
fn receive_hello<CI: VL1CallerInterface>(&self, ci: &CI, node: &Node, time_ticks: i64, source_path: &Arc<Path>, payload: &Buffer<{ PACKET_SIZE_MAX }>) {}
|
||||
|
|
|
@ -63,7 +63,7 @@ impl WhoisQueue {
|
|||
}
|
||||
|
||||
/// Called every INTERVAL during background tasks.
|
||||
pub fn on_interval<CI: VL1CallerInterface>(&self, node: &Node, ci: &CI, time_ticks: i64) {
|
||||
pub fn call_every_interval<CI: VL1CallerInterface>(&self, node: &Node, ci: &CI, time_ticks: i64) {
|
||||
let mut targets: Vec<Address> = Vec::new();
|
||||
self.0.lock().retain(|target, qi| {
|
||||
if qi.retry_count < WHOIS_RETRY_MAX {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* https://www.zerotier.com/
|
||||
*/
|
||||
|
||||
pub mod switch;
|
||||
mod multicastgroup;
|
||||
|
||||
pub use multicastgroup::MulticastGroup;
|
||||
|
|
37
zerotier-network-hypervisor/src/vl2/switch.rs
Normal file
37
zerotier-network-hypervisor/src/vl2/switch.rs
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* 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::sync::Arc;
|
||||
|
||||
use crate::vl1::node::VL1PacketHandler;
|
||||
use crate::vl1::{Peer, Path};
|
||||
use crate::vl1::buffer::Buffer;
|
||||
use crate::vl1::protocol::{PACKET_SIZE_MAX, PacketID};
|
||||
|
||||
pub struct Switch {
|
||||
}
|
||||
|
||||
impl VL1PacketHandler for Switch {
|
||||
fn handle_packet(&self, peer: &Peer, source_path: &Arc<Path>, forward_secrecy: bool, extended_authentication: bool, verb: u8, payload: &Buffer<{ PACKET_SIZE_MAX }>) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn handle_error(&self, peer: &Peer, source_path: &Arc<Path>, forward_secrecy: bool, extended_authentication: bool, in_re_verb: u8, in_re_packet_id: PacketID, error_code: u8, payload: &Buffer<{ PACKET_SIZE_MAX }>, cursor: &mut usize) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn handle_ok(&self, peer: &Peer, source_path: &Arc<Path>, forward_secrecy: bool, extended_authentication: bool, in_re_verb: u8, in_re_packet_id: PacketID, payload: &Buffer<{ PACKET_SIZE_MAX }>, cursor: &mut usize) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl Switch {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
|
@ -8,8 +8,6 @@
|
|||
|
||||
use clap::ArgMatches;
|
||||
|
||||
use zerotier_core::{Identity, IdentityType};
|
||||
|
||||
fn new_(cli_args: &ArgMatches) -> i32 {
|
||||
let id_type = cli_args.value_of("type").map_or(IdentityType::Curve25519, |idt| {
|
||||
match idt {
|
||||
|
@ -53,7 +51,7 @@ fn validate(cli_args: &ArgMatches) -> i32 {
|
|||
println!("FAILED");
|
||||
1
|
||||
}, |id| {
|
||||
if id.validate() {
|
||||
if id.locally_validate() {
|
||||
println!("OK");
|
||||
0
|
||||
} else {
|
||||
|
|
|
@ -13,8 +13,8 @@ use std::sync::{Arc, Mutex, Weak};
|
|||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::time::Duration;
|
||||
|
||||
use zerotier_core::*;
|
||||
use zerotier_core::trace::{TraceEvent, TraceEventLayer};
|
||||
use zerotier_network_hypervisor::vl1::{Address, Identity, InetAddress, MAC, PacketBuffer};
|
||||
|
||||
use futures::StreamExt;
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
|
@ -26,6 +26,7 @@ use crate::network::Network;
|
|||
use crate::store::Store;
|
||||
use crate::utils::{ms_since_epoch, ms_monotonic};
|
||||
use crate::httplistener::HttpListener;
|
||||
use zerotier_network_hypervisor::vl1::inetaddress::IpScope;
|
||||
|
||||
/// How often to check for major configuration changes. This shouldn't happen
|
||||
/// too often since it uses a bit of CPU.
|
||||
|
@ -362,7 +363,7 @@ async fn run_async(store: Arc<Store>, local_config: Arc<LocalConfig>) -> i32 {
|
|||
}
|
||||
for a in system_addrs.iter() {
|
||||
if !udp_sockets.contains_key(a.0) {
|
||||
let _ = FastUDPSocket::new(a.1.as_str(), a.0, |raw_socket: &FastUDPRawOsSocket, from_address: &InetAddress, data: Buffer| {
|
||||
let _ = FastUDPSocket::new(a.1.as_str(), a.0, |raw_socket: &FastUDPRawOsSocket, from_address: &InetAddress, data: PacketBuffer| {
|
||||
// TODO: incoming packet handler
|
||||
}).map_or_else(|e| {
|
||||
l!(service.log, "error binding UDP socket to {}: {}", a.0.to_string(), e.to_string());
|
||||
|
|
|
@ -11,11 +11,11 @@ use std::fs::File;
|
|||
use std::io::Read;
|
||||
use std::path::Path;
|
||||
|
||||
use zerotier_core::{Identity, Locator};
|
||||
|
||||
use serde::Serialize;
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
use zerotier_network_hypervisor::vl1::Identity;
|
||||
|
||||
use crate::osdep;
|
||||
|
||||
#[inline(always)]
|
||||
|
|
Loading…
Add table
Reference in a new issue