mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-26 17:03:43 +02:00
Some cleanup, move some more V1 only fields into V1 credentials struct.
This commit is contained in:
parent
5772a135f5
commit
6bf978d4de
8 changed files with 41 additions and 44 deletions
|
@ -43,10 +43,6 @@ impl Cache {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn list_cached_networks(&self) -> Vec<NetworkId> {
|
||||
self.by_nwid.read().unwrap().keys().cloned().collect()
|
||||
}
|
||||
|
||||
/// Update a network if changed, returning whether or not any update was made and the old version if any.
|
||||
/// A value of (true, None) indicates that there was no network by that ID in which case it is added.
|
||||
pub fn on_network_updated(&self, network: Network) -> (bool, Option<Network>) {
|
||||
|
|
|
@ -183,8 +183,8 @@ impl Controller {
|
|||
}
|
||||
}
|
||||
|
||||
/// Send one or more revocation object(s) to a peer (V1 protocol only).
|
||||
fn v1_proto_send_revocations(&self, peer: &Peer, mut revocations: Vec<Revocation>) {
|
||||
/// Send one or more revocation object(s) to a peer.
|
||||
fn send_revocations(&self, peer: &Peer, mut revocations: Vec<Revocation>) {
|
||||
if let Some(host_system) = self.service.read().unwrap().upgrade() {
|
||||
let time_ticks = ms_monotonic();
|
||||
while !revocations.is_empty() {
|
||||
|
@ -336,11 +336,9 @@ impl Controller {
|
|||
nc.name = network.name.clone();
|
||||
nc.private = network.private;
|
||||
nc.timestamp = now;
|
||||
nc.credential_ttl = credential_ttl;
|
||||
nc.revision = Some(now as u64);
|
||||
nc.mtu = network.mtu.unwrap_or(ZEROTIER_VIRTUAL_NETWORK_DEFAULT_MTU as u16);
|
||||
nc.multicast_limit = network.multicast_limit.unwrap_or(DEFAULT_MULTICAST_LIMIT as u32);
|
||||
nc.multicast_like_expire = Some(protocol::VL2_DEFAULT_MULTICAST_LIKE_EXPIRE as u32);
|
||||
nc.mtu = network.mtu.unwrap_or(ZEROTIER_VIRTUAL_NETWORK_DEFAULT_MTU as u16);
|
||||
nc.routes = network.ip_routes;
|
||||
nc.static_ips = member.ip_assignments.clone();
|
||||
nc.rules = network.rules;
|
||||
|
@ -354,6 +352,8 @@ impl Controller {
|
|||
vl2::v1::CertificateOfMembership::new(&self.local_identity, network_id, &source_identity, now, credential_ttl)
|
||||
{
|
||||
let mut v1cred = V1Credentials {
|
||||
revision: now as u64,
|
||||
max_delta: credential_ttl,
|
||||
certificate_of_membership: com,
|
||||
certificates_of_ownership: Vec::new(),
|
||||
tags: HashMap::new(),
|
||||
|
@ -383,7 +383,7 @@ impl Controller {
|
|||
// For anyone who has been deauthorized but is still in the window, send revocations.
|
||||
if let Ok(deauthed_members_still_in_window) = self
|
||||
.database
|
||||
.list_members_deauthorized_after(network.id, now - credential_ttl)
|
||||
.list_members_deauthorized_after(network.id, now - (credential_ttl as i64))
|
||||
.await
|
||||
{
|
||||
if !deauthed_members_still_in_window.is_empty() {
|
||||
|
@ -419,7 +419,7 @@ impl Controller {
|
|||
.unwrap()
|
||||
.entry(source_identity.fingerprint)
|
||||
.or_default()
|
||||
.insert(network_id, ms_monotonic() + nc.credential_ttl);
|
||||
.insert(network_id, ms_monotonic() + (credential_ttl as i64));
|
||||
|
||||
network_config = Some(nc);
|
||||
}
|
||||
|
@ -497,7 +497,7 @@ impl InnerProtocol for Controller {
|
|||
//println!("{}", serde_yaml::to_string(&config).unwrap());
|
||||
self2.send_network_config(source.as_ref(), &config, Some(message_id));
|
||||
if let Some(revocations) = revocations {
|
||||
self2.v1_proto_send_revocations(source.as_ref(), revocations);
|
||||
self2.send_revocations(source.as_ref(), revocations);
|
||||
}
|
||||
(result, Some(config))
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ impl FileDatabase {
|
|||
if let Some((record_type, network_id, node_id)) =
|
||||
Self::record_type_from_path(controller_address, path0.as_path())
|
||||
{
|
||||
// Paths to objects that were deleted or changed. Changed includes adding new objects.
|
||||
let mut deleted = None;
|
||||
let mut changed = None;
|
||||
|
||||
|
@ -117,6 +118,7 @@ impl FileDatabase {
|
|||
}
|
||||
|
||||
if deleted.is_some() {
|
||||
println!("DELETED: {}", deleted.unwrap().as_os_str().to_string_lossy());
|
||||
match record_type {
|
||||
RecordType::Network => {
|
||||
if let Some((network, mut members)) = db.cache.on_network_deleted(network_id) {
|
||||
|
@ -138,6 +140,7 @@ impl FileDatabase {
|
|||
}
|
||||
|
||||
if let Some(changed) = changed {
|
||||
println!("CHANGED: {}", changed.as_os_str().to_string_lossy());
|
||||
match record_type {
|
||||
RecordType::Network => {
|
||||
if let Ok(Some(new_network)) = Self::get_network_internal(changed).await {
|
||||
|
@ -375,6 +378,7 @@ impl Database for FileDatabase {
|
|||
let mut member = Self::get_member_internal(&self.member_path(network_id, node_id)).await?;
|
||||
if let Some(member) = member.as_mut() {
|
||||
if member.network_id != network_id {
|
||||
// Also auto-update member network IDs, see get_network().
|
||||
member.network_id = network_id;
|
||||
self.save_member(member.clone()).await?;
|
||||
}
|
||||
|
@ -385,7 +389,6 @@ impl Database for FileDatabase {
|
|||
async fn save_member(&self, obj: Member) -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
let base_member_path = self.member_path(obj.network_id, obj.node_id);
|
||||
let _ = fs::create_dir_all(base_member_path.parent().unwrap()).await;
|
||||
//let _ = fs::write(base_member_path, to_json_pretty(&obj).as_bytes()).await?;
|
||||
let _ = fs::write(base_member_path, serde_yaml::to_string(&obj)?.as_bytes()).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use zerotier_network_hypervisor::vl2::NetworkId;
|
|||
use crate::database::Database;
|
||||
use crate::model::Member;
|
||||
|
||||
pub const CREDENTIAL_WINDOW_SIZE_DEFAULT: i64 = 1000 * 60 * 60;
|
||||
pub const CREDENTIAL_WINDOW_SIZE_DEFAULT: u64 = 1000 * 60 * 60;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
|
||||
pub struct Ipv4AssignMode {
|
||||
|
@ -105,7 +105,7 @@ pub struct Network {
|
|||
/// Usually this does not need to be changed.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[serde(rename = "credentialTtl")]
|
||||
pub credential_ttl: Option<i64>,
|
||||
pub credential_ttl: Option<u64>,
|
||||
|
||||
/// Minimum supported ZeroTier protocol version for this network (default: undefined, up to members)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
|
|
@ -41,17 +41,6 @@ pub struct NetworkConfig {
|
|||
/// Network configuration timestamp
|
||||
pub timestamp: i64,
|
||||
|
||||
/// TTL for credentials on this network (or window size for V1 nodes)
|
||||
pub credential_ttl: i64,
|
||||
|
||||
/// Network configuration revision number (V1)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[serde(default)]
|
||||
pub revision: Option<u64>,
|
||||
|
||||
/// L2 Ethernet MTU for this network.
|
||||
pub mtu: u16,
|
||||
|
||||
/// Suggested horizon limit for multicast (not a hard limit, but 0 disables multicast)
|
||||
pub multicast_limit: u32,
|
||||
|
||||
|
@ -60,6 +49,9 @@ pub struct NetworkConfig {
|
|||
#[serde(default)]
|
||||
pub multicast_like_expire: Option<u32>,
|
||||
|
||||
/// L2 Ethernet MTU for this network.
|
||||
pub mtu: u16,
|
||||
|
||||
/// ZeroTier-assigned L3 routes for this node.
|
||||
#[serde(skip_serializing_if = "HashSet::is_empty")]
|
||||
#[serde(default)]
|
||||
|
@ -105,8 +97,6 @@ impl NetworkConfig {
|
|||
motd: String::new(),
|
||||
private: true,
|
||||
timestamp: 0,
|
||||
credential_ttl: 0,
|
||||
revision: None,
|
||||
mtu: 0,
|
||||
multicast_limit: 0,
|
||||
multicast_like_expire: None,
|
||||
|
@ -143,8 +133,6 @@ impl NetworkConfig {
|
|||
},
|
||||
);
|
||||
d.set_u64(proto_v1_field_name::network_config::TIMESTAMP, self.timestamp as u64);
|
||||
d.set_u64(proto_v1_field_name::network_config::MAX_DELTA, self.credential_ttl as u64);
|
||||
d.set_u64(proto_v1_field_name::network_config::REVISION, self.revision.unwrap_or(0));
|
||||
d.set_u64(proto_v1_field_name::network_config::MTU, self.mtu as u64);
|
||||
d.set_u64(proto_v1_field_name::network_config::MULTICAST_LIMIT, self.multicast_limit as u64);
|
||||
|
||||
|
@ -193,6 +181,9 @@ impl NetworkConfig {
|
|||
}
|
||||
|
||||
if let Some(v1cred) = self.v1_credentials.as_ref() {
|
||||
d.set_u64(proto_v1_field_name::network_config::REVISION, v1cred.revision);
|
||||
d.set_u64(proto_v1_field_name::network_config::MAX_DELTA, v1cred.max_delta);
|
||||
|
||||
d.set_bytes(
|
||||
proto_v1_field_name::network_config::CERTIFICATE_OF_MEMBERSHIP,
|
||||
v1cred
|
||||
|
@ -268,8 +259,6 @@ impl NetworkConfig {
|
|||
nc.timestamp = d
|
||||
.get_i64(proto_v1_field_name::network_config::TIMESTAMP)
|
||||
.ok_or(InvalidParameterError("missing timestamp"))?;
|
||||
nc.credential_ttl = d.get_i64(proto_v1_field_name::network_config::MAX_DELTA).unwrap_or(0);
|
||||
nc.revision = Some(d.get_u64(proto_v1_field_name::network_config::REVISION).unwrap_or(0));
|
||||
nc.mtu = d
|
||||
.get_u64(proto_v1_field_name::network_config::MTU)
|
||||
.unwrap_or(crate::protocol::ZEROTIER_VIRTUAL_NETWORK_DEFAULT_MTU as u64) as u16;
|
||||
|
@ -327,6 +316,8 @@ impl NetworkConfig {
|
|||
}
|
||||
|
||||
let mut v1cred = V1Credentials {
|
||||
revision: d.get_u64(proto_v1_field_name::network_config::REVISION).unwrap_or(0),
|
||||
max_delta: d.get_u64(proto_v1_field_name::network_config::MAX_DELTA).unwrap_or(0),
|
||||
certificate_of_membership: CertificateOfMembership::from_bytes(
|
||||
d.get_bytes(proto_v1_field_name::network_config::CERTIFICATE_OF_MEMBERSHIP)
|
||||
.ok_or(InvalidParameterError("missing certificate of membership"))?,
|
||||
|
@ -446,6 +437,8 @@ pub struct SSOAuthConfiguration {
|
|||
/// networks that support older protocol versions.
|
||||
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct V1Credentials {
|
||||
pub revision: u64,
|
||||
pub max_delta: u64,
|
||||
pub certificate_of_membership: CertificateOfMembership,
|
||||
pub certificates_of_ownership: Vec<CertificateOfOwnership>,
|
||||
#[serde(skip_serializing_if = "HashMap::is_empty")]
|
||||
|
|
|
@ -25,7 +25,7 @@ use zerotier_utils::memory;
|
|||
pub struct CertificateOfMembership {
|
||||
pub network_id: NetworkId,
|
||||
pub timestamp: i64,
|
||||
pub max_delta: i64,
|
||||
pub max_delta: u64,
|
||||
pub issued_to: Address,
|
||||
pub issued_to_fingerprint: Blob<32>,
|
||||
pub signature: ArrayVec<u8, { Identity::MAX_SIGNATURE_SIZE }>,
|
||||
|
@ -34,7 +34,7 @@ pub struct CertificateOfMembership {
|
|||
impl CertificateOfMembership {
|
||||
/// Create a new signed certificate of membership.
|
||||
/// None is returned if an error occurs, such as the issuer missing its secrets.
|
||||
pub fn new(issuer: &Identity, network_id: NetworkId, issued_to: &Identity, timestamp: i64, max_delta: i64) -> Option<Self> {
|
||||
pub fn new(issuer: &Identity, network_id: NetworkId, issued_to: &Identity, timestamp: i64, max_delta: u64) -> Option<Self> {
|
||||
let mut com = CertificateOfMembership {
|
||||
network_id,
|
||||
timestamp,
|
||||
|
@ -128,7 +128,7 @@ impl CertificateOfMembership {
|
|||
match qt {
|
||||
0 => {
|
||||
timestamp = i64::from_be_bytes(q);
|
||||
max_delta = qd as i64;
|
||||
max_delta = qd;
|
||||
}
|
||||
1 => {
|
||||
network_id = u64::from_be_bytes(q);
|
||||
|
|
|
@ -28,7 +28,7 @@ pub mod reaper;
|
|||
pub use tokio;
|
||||
|
||||
/// A monotonic ticks value for "never happened" that should be lower than any initial value.
|
||||
pub const NEVER_HAPPENED_TICKS: i64 = i64::MIN / 2;
|
||||
pub const NEVER_HAPPENED_TICKS: i64 = i64::MIN;
|
||||
|
||||
/// Get milliseconds since unix epoch.
|
||||
#[inline]
|
||||
|
@ -44,15 +44,19 @@ pub fn ms_since_epoch() -> i64 {
|
|||
pub fn ms_monotonic() -> i64 {
|
||||
static STARTUP_INSTANT: std::sync::RwLock<Option<std::time::Instant>> = std::sync::RwLock::new(None);
|
||||
let si = *STARTUP_INSTANT.read().unwrap();
|
||||
let instant_zero = if let Some(si) = si {
|
||||
si
|
||||
if let Some(si) = si {
|
||||
si.elapsed().as_millis() as i64
|
||||
} else {
|
||||
*STARTUP_INSTANT.write().unwrap().get_or_insert(std::time::Instant::now())
|
||||
};
|
||||
std::time::Instant::now().duration_since(instant_zero).as_millis() as i64
|
||||
STARTUP_INSTANT
|
||||
.write()
|
||||
.unwrap()
|
||||
.get_or_insert(std::time::Instant::now())
|
||||
.elapsed()
|
||||
.as_millis() as i64
|
||||
}
|
||||
}
|
||||
|
||||
/// Wait for a kill signal (e.g. SIGINT or OS-equivalent) and return when received.
|
||||
/// Wait for a kill signal (e.g. SIGINT or OS-equivalent) sent to this process and return when received.
|
||||
#[cfg(unix)]
|
||||
pub fn wait_for_process_abort() {
|
||||
if let Ok(mut signals) = signal_hook::iterator::Signals::new(&[libc::SIGINT, libc::SIGTERM, libc::SIGQUIT]) {
|
||||
|
@ -65,10 +69,10 @@ pub fn wait_for_process_abort() {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
}
|
||||
} else {
|
||||
panic!("unable to listen to OS signals");
|
||||
panic!("unable to listen for OS signals");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ use std::ptr::{drop_in_place, read, write};
|
|||
/// This will panic if the capacity is too small. If that occurs, it must be enlarged. It will
|
||||
/// also panic if any of the accessors (other than the try_ versions) are used to try to get
|
||||
/// a type other than the one it was constructed with.
|
||||
#[repr(C)]
|
||||
pub struct Thing<const CAPACITY: usize> {
|
||||
storage: [u8; CAPACITY],
|
||||
dropper: fn(*mut u8),
|
||||
|
|
Loading…
Add table
Reference in a new issue