Move default root set to network-hypervisor, add a priority level to roots.

This commit is contained in:
Adam Ierymenko 2022-05-09 17:22:01 -04:00
parent 188f404361
commit d41e1b1c41
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
12 changed files with 170 additions and 111 deletions

View file

@ -0,0 +1,14 @@
#!/bin/bash
# This is for internal use by ZeroTier, but obviously users can repurpose it to make their own.
# Usage: make-root-set.sh <identity.secret> [<...>]
for i in $*; do
echo $i
../../zerotier-system-service/target/debug/zerotier-system-service rootset sign root.zerotier.com.json $i >tmp.json
mv -f tmp.json root.zerotier.com.json
../../zerotier-system-service/target/debug/zerotier-system-service rootset marshal root.zerotier.com.json >root.zerotier.com.bin
done
cat root.zerotier.com.json

View file

@ -0,0 +1,25 @@
{
"name": "root.zerotier.com",
"revision": 1,
"members": [ {
"identity": "62f865ae71:0:e2076c57de870e6288d7d5e7404408b1545efca37d67f77b87e9e54168c25d3ef1a9abf2905ea5e785c01dff23887ad4232d95c7a8fd2c27111a72bd159322dc",
"endpoints": [ "udp:50.7.252.138/9993", "udp:2001:49f0:d0db:2::2/9993" ],
"signature": [ 1, 250, 55, 178, 250, 221, 13, 136, 125, 246, 209, 222, 43, 154, 3, 87, 224, 202, 86, 154, 217, 132, 141, 77, 246, 233, 118, 35, 112, 37, 58, 226, 104, 232, 33, 180, 29, 159, 20, 100, 217, 129, 242, 16, 247, 253, 70, 245, 59, 22, 126, 148, 52, 7, 231, 5, 230, 252, 35, 204, 22, 12, 85, 122, 10 ],
"priority": 0
}, {
"identity": "778cde7190:0:3f6681a99e5ad1895e9fba33e6212d4454e168bcec7112101bf000956ed8e92e42892cb6f2ec410881a84ab19da50e1287ba3d926c3a1f755cccf299a1207055",
"endpoints": [ "udp:103.195.103.66/9993", "udp:2605:9880:400:c3:254:f2bc:a1f7:19/9993" ],
"signature": [ 1, 115, 251, 30, 185, 137, 187, 219, 80, 35, 19, 117, 38, 241, 200, 137, 205, 208, 73, 54, 30, 158, 150, 64, 232, 214, 248, 54, 26, 180, 29, 68, 87, 34, 102, 251, 199, 158, 215, 199, 77, 8, 128, 93, 166, 199, 39, 139, 143, 20, 180, 29, 145, 232, 90, 181, 75, 237, 175, 238, 2, 124, 18, 124, 4 ],
"priority": 0
}, {
"identity": "cafe04eba9:0:6c6a9d1dea55c1616bfe2a2b8f0ff9a8cacaf70374fb1f39e3bef81cbfebef17b7228268a0a2a29d3488c752565c6c965cbd6506ec24397cc8a5d9d15285a87f",
"endpoints": [ "udp:84.17.53.155/9993", "udp:2a02:6ea0:d405::9993/9993" ],
"signature": [ 1, 51, 245, 92, 49, 30, 240, 161, 49, 14, 233, 231, 237, 169, 55, 1, 171, 91, 121, 3, 157, 139, 135, 177, 212, 199, 26, 188, 98, 130, 138, 39, 193, 45, 190, 243, 146, 15, 234, 220, 203, 154, 39, 230, 88, 152, 164, 74, 44, 136, 125, 207, 23, 31, 112, 52, 16, 116, 179, 99, 93, 133, 133, 189, 6 ],
"priority": 0
}, {
"identity": "cafe9efeb9:0:ccdef76bc7b97ded904eabc5df09886d9c1514a610036cb9139cc214001a2958978efcec15712dd3948c6e6b3a8e893df01ff493d1f8d9806a860c5420571bf0",
"endpoints": [ "udp:104.194.8.134/9993", "udp:2605:9880:200:1200:30:571:e34:51/9993" ],
"signature": [ 1, 237, 145, 250, 221, 80, 44, 48, 158, 74, 198, 149, 192, 96, 220, 223, 232, 141, 163, 254, 173, 190, 7, 16, 67, 234, 182, 183, 16, 36, 154, 40, 141, 98, 18, 253, 57, 186, 222, 71, 223, 247, 43, 131, 203, 38, 79, 36, 43, 52, 130, 80, 218, 188, 3, 175, 221, 108, 218, 139, 248, 37, 228, 112, 5 ],
"priority": 0
} ]
}

View file

@ -497,6 +497,20 @@ impl<const L: usize> AsMut<[u8]> for Buffer<L> {
}
}
impl<const L: usize> From<[u8; L]> for Buffer<L> {
#[inline(always)]
fn from(a: [u8; L]) -> Self {
Self(L, a)
}
}
impl<const L: usize> From<&[u8; L]> for Buffer<L> {
#[inline(always)]
fn from(a: &[u8; L]) -> Self {
Self(L, a.clone())
}
}
pub struct PooledBufferFactory<const L: usize>;
impl<const L: usize> PooledBufferFactory<L> {

View file

@ -18,34 +18,44 @@ use crate::vl1::Endpoint;
use serde::{Deserialize, Serialize};
/// Description of a member of a root cluster.
///
/// Natural sort order is in order of identity address.
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Root {
/// Full identity of this node.
/// Identity of this node (not including secret).
pub identity: Identity,
/// Endpoints for this root or None if this is a former member attesting to an update that removes it.
/// Endpoints for this root or None if this is a disabled entry.
///
/// Disabled entries typically exist when a former member is needed to sign a new revision to
/// achieve N-1 quorum and issue an update.
pub endpoints: Option<BTreeSet<Endpoint>>,
/// Signature of entire root set by this identity.
///
/// This is populated by the sign() method when the completed root set is signed by each member.
/// All member roots must sign.
#[serde(default)]
pub signature: Vec<u8>,
/// Flags field (currently unused).
/// Priority (higher number is lower priority, 0 is default).
///
/// Lower priority roots are only used if NO roots of a higher priority can be reached (in any root set).
#[serde(default)]
pub flags: u64,
pub priority: u8,
}
impl PartialOrd for Root {
#[inline(always)]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.identity.partial_cmp(&other.identity)
self.identity.address.partial_cmp(&other.identity.address)
}
}
impl Ord for Root {
#[inline(always)]
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.identity.cmp(&other.identity)
self.identity.address.cmp(&other.identity.address)
}
}
@ -67,7 +77,8 @@ pub struct RootSet {
pub revision: u64,
/// A set of Root nodes that are current or immediately former members of this cluster.
/// This will always be sorted by member identity.
///
/// This will always be sorted by member identity address. Duplicate addresses are not allowed.
pub members: Vec<Root>,
}
@ -76,6 +87,12 @@ impl RootSet {
Self { name, revision, members: Vec::new() }
}
/// Get the ZeroTier default root set, which contains roots run by ZeroTier Inc.
pub fn zerotier_default() -> Self {
let mut cursor = 0;
Self::unmarshal(&Buffer::from(include_bytes!("../../default-rootset/root.zerotier.com.json")), &mut cursor).unwrap()
}
fn marshal_internal<const BL: usize>(&self, buf: &mut Buffer<BL>, include_signatures: bool) -> std::io::Result<()> {
buf.append_u8(0)?; // version byte for future use
buf.append_varint(self.name.as_bytes().len() as u64)?;
@ -97,7 +114,8 @@ impl RootSet {
buf.append_varint(m.signature.len() as u64)?;
buf.append_bytes(m.signature.as_slice())?;
}
buf.append_varint(m.flags)?;
buf.append_varint(0)?; // flags, currently always 0
buf.append_u8(m.priority)?;
buf.append_varint(0)?; // size of additional fields for future use
}
buf.append_varint(0)?; // size of additional fields for future use
@ -127,9 +145,9 @@ impl RootSet {
return true;
}
/// Add a member to this definition, replacing any current entry for this identity.
pub fn add<'a, I: Iterator<Item = &'a Endpoint>>(&mut self, member_identity: &Identity, endpoints: Option<I>) {
self.members.retain(|m| !m.identity.eq(member_identity));
/// Add a member to this definition, replacing any current entry with this address.
pub fn add<'a, I: Iterator<Item = &'a Endpoint>>(&mut self, member_identity: &Identity, endpoints: Option<I>, priority: u8) {
self.members.retain(|m| m.identity.address != member_identity.address);
let _ = self.members.push(Root {
identity: member_identity.clone_without_secret(),
endpoints: endpoints.map(|endpoints| {
@ -140,7 +158,7 @@ impl RootSet {
tmp
}),
signature: Vec::new(),
flags: 0,
priority,
});
self.members.sort();
}
@ -162,7 +180,7 @@ impl RootSet {
identity: unsigned_entry.identity,
endpoints: unsigned_entry.endpoints,
signature: signature.unwrap(),
flags: unsigned_entry.flags,
priority: unsigned_entry.priority,
});
self.members.sort();
return true;
@ -178,7 +196,7 @@ impl RootSet {
/// root nodes can replace one member if three cluster members sign the update, but to
/// remove two at a time one of the exiting members would have to sign. This is done by
/// adding it with None as its address list, making it disabled. Disabled members function
/// only as signers (witnesses).
/// only as signers (witnesses) and only if they were enabled previously.
///
/// There is one edge case though. If a cluster definition has only one member, that one
/// member must sign the next update. N-1 is not permitted to be less than one. If that was
@ -237,7 +255,7 @@ impl Marshalable for RootSet {
identity: Identity::unmarshal(buf, cursor)?,
endpoints: None,
signature: Vec::new(),
flags: 0,
priority: 0,
};
let endpoint_count = buf.read_varint(cursor)?;
@ -252,7 +270,8 @@ impl Marshalable for RootSet {
let signature_size = buf.read_varint(cursor)?;
let _ = m.signature.write_all(buf.read_bytes(signature_size as usize, cursor)?);
m.flags = buf.read_varint(cursor)?;
let _ = buf.read_varint(cursor)?; // flags, currently unused
m.priority = buf.read_u8(cursor)?;
*cursor += buf.read_varint(cursor)? as usize;

View file

@ -1,25 +0,0 @@
{
"name": "root.zerotier.com",
"revision": 1,
"members": [ {
"identity": "62f865ae71:0:e2076c57de870e6288d7d5e7404408b1545efca37d67f77b87e9e54168c25d3ef1a9abf2905ea5e785c01dff23887ad4232d95c7a8fd2c27111a72bd159322dc",
"endpoints": [ "udp:50.7.252.138/9993", "udp:2001:49f0:d0db:2::2/9993" ],
"signature": [ 1, 45, 14, 211, 108, 240, 151, 85, 43, 241, 113, 18, 24, 45, 198, 197, 67, 254, 96, 138, 194, 77, 170, 156, 168, 31, 240, 55, 168, 108, 69, 135, 253, 198, 153, 36, 166, 200, 222, 157, 122, 50, 149, 149, 40, 35, 125, 93, 78, 228, 51, 245, 53, 238, 133, 84, 188, 190, 98, 145, 177, 19, 54, 154, 0 ],
"flags": 0
}, {
"identity": "778cde7190:0:3f6681a99e5ad1895e9fba33e6212d4454e168bcec7112101bf000956ed8e92e42892cb6f2ec410881a84ab19da50e1287ba3d926c3a1f755cccf299a1207055",
"endpoints": [ "udp:103.195.103.66/9993", "udp:2605:9880:400:c3:254:f2bc:a1f7:19/9993" ],
"signature": [ 1, 202, 181, 145, 69, 58, 169, 42, 149, 210, 160, 77, 220, 56, 246, 54, 210, 161, 144, 158, 103, 70, 104, 236, 58, 66, 127, 100, 117, 242, 208, 70, 68, 87, 142, 163, 222, 231, 146, 60, 205, 180, 202, 18, 181, 137, 216, 204, 109, 118, 224, 86, 220, 26, 142, 61, 18, 50, 174, 173, 44, 167, 231, 249, 0 ],
"flags": 0
}, {
"identity": "cafe04eba9:0:6c6a9d1dea55c1616bfe2a2b8f0ff9a8cacaf70374fb1f39e3bef81cbfebef17b7228268a0a2a29d3488c752565c6c965cbd6506ec24397cc8a5d9d15285a87f",
"endpoints": [ "udp:84.17.53.155/9993", "udp:2a02:6ea0:d405::9993/9993" ],
"signature": [ 1, 129, 31, 37, 249, 242, 179, 153, 184, 117, 15, 192, 41, 69, 112, 196, 189, 18, 57, 96, 33, 82, 31, 142, 57, 251, 151, 118, 86, 71, 11, 170, 197, 11, 20, 55, 74, 66, 10, 248, 133, 216, 88, 212, 34, 139, 128, 179, 246, 241, 8, 126, 105, 195, 126, 235, 140, 219, 66, 92, 166, 203, 111, 132, 0 ],
"flags": 0
}, {
"identity": "cafe9efeb9:0:ccdef76bc7b97ded904eabc5df09886d9c1514a610036cb9139cc214001a2958978efcec15712dd3948c6e6b3a8e893df01ff493d1f8d9806a860c5420571bf0",
"endpoints": [ "udp:104.194.8.134/9993", "udp:2605:9880:200:1200:30:571:e34:51/9993" ],
"signature": [ 1, 254, 236, 249, 244, 29, 229, 55, 85, 171, 15, 42, 222, 51, 237, 237, 47, 54, 158, 123, 96, 24, 101, 207, 63, 82, 113, 254, 154, 225, 188, 147, 75, 115, 243, 200, 253, 221, 198, 234, 74, 168, 126, 13, 137, 143, 13, 56, 73, 206, 242, 29, 97, 8, 221, 31, 236, 187, 86, 190, 15, 65, 184, 253, 13 ],
"flags": 0
} ]
}

View file

@ -30,7 +30,7 @@ pub async fn cmd(flags: Flags, cmd_args: &ArgMatches) -> i32 {
let path = path.unwrap();
let secret_arg = secret_arg.unwrap();
let secret = crate::utils::parse_cli_identity(secret_arg, true).await;
let json_data = crate::utils::read_limit(path, 1048576).await;
let json_data = crate::utils::read_limit(path, crate::utils::DEFAULT_FILE_IO_READ_LIMIT).await;
if secret.is_err() {
eprintln!("ERROR: unable to parse '{}' or read as a file.", secret_arg);
return exitcode::ERR_IOERR;
@ -66,7 +66,7 @@ pub async fn cmd(flags: Flags, cmd_args: &ArgMatches) -> i32 {
let path = sc_args.value_of("path");
if path.is_some() {
let path = path.unwrap();
let json_data = crate::utils::read_limit(path, 1048576).await;
let json_data = crate::utils::read_limit(path, crate::utils::DEFAULT_FILE_IO_READ_LIMIT).await;
if json_data.is_err() {
eprintln!("ERROR: unable to read '{}'.", path);
return exitcode::ERR_IOERR;

View file

@ -7,7 +7,6 @@
use serde_json::ser::Formatter;
#[derive(Clone, Debug)]
pub struct JsonFormatter<'a> {
current_indent: usize,
has_value: bool,

View file

@ -13,6 +13,7 @@ use serde::{Deserialize, Serialize};
use zerotier_network_hypervisor::vl1::{Address, InetAddress};
use zerotier_network_hypervisor::vl2::NetworkId;
/// A list of unassigned or obsolete ports under 1024 that could possibly be squatted.
pub const UNASSIGNED_PRIVILEGED_PORTS: [u16; 299] = [
4, 6, 8, 10, 12, 14, 15, 16, 26, 28, 30, 32, 34, 36, 40, 60, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 285, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 323, 324, 325, 326, 327, 328,
329, 330, 331, 332, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 703, 708, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 732, 733, 734, 735, 736, 737, 738, 739, 740, 743, 745, 746, 755, 756, 766, 768, 778, 779,
@ -22,36 +23,37 @@ pub const UNASSIGNED_PRIVILEGED_PORTS: [u16; 299] = [
954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1023,
];
/// Default primary ZeroTier port.
pub const DEFAULT_PORT: u16 = 9993;
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(default)]
pub struct LocalConfigPhysicalPathConfig {
pub struct PhysicalPathSettings {
pub blacklist: bool,
}
impl Default for LocalConfigPhysicalPathConfig {
impl Default for PhysicalPathSettings {
fn default() -> Self {
LocalConfigPhysicalPathConfig { blacklist: false }
Self { blacklist: false }
}
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(default)]
pub struct LocalConfigVirtualConfig {
pub struct VirtualNetworkSettings {
#[serde(rename = "try")]
pub try_: Vec<InetAddress>,
}
impl Default for LocalConfigVirtualConfig {
impl Default for VirtualNetworkSettings {
fn default() -> Self {
LocalConfigVirtualConfig { try_: Vec::new() }
Self { try_: Vec::new() }
}
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(default)]
pub struct LocalConfigNetworkSettings {
pub struct NetworkSettings {
#[serde(rename = "allowManagedIPs")]
pub allow_managed_ips: bool,
#[serde(rename = "allowGlobalIPs")]
@ -64,9 +66,9 @@ pub struct LocalConfigNetworkSettings {
pub allow_default_route_override: bool,
}
impl Default for LocalConfigNetworkSettings {
impl Default for NetworkSettings {
fn default() -> Self {
LocalConfigNetworkSettings {
Self {
allow_managed_ips: true,
allow_global_ips: false,
allow_managed_routes: true,
@ -78,78 +80,43 @@ impl Default for LocalConfigNetworkSettings {
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(default)]
pub struct LocalConfigLogSettings {
pub path: Option<String>,
#[serde(rename = "maxSize")]
pub max_size: usize,
pub vl1: bool,
pub vl2: bool,
#[serde(rename = "vl2TraceRules")]
pub vl2_trace_rules: bool,
#[serde(rename = "vl2TraceMulticast")]
pub vl2_trace_multicast: bool,
pub debug: bool,
pub stderr: bool,
}
impl Default for LocalConfigLogSettings {
fn default() -> Self {
// TODO: change before release to saner defaults
LocalConfigLogSettings {
path: None,
max_size: 131072,
vl1: true,
vl2: true,
vl2_trace_rules: true,
vl2_trace_multicast: true,
debug: true,
stderr: true,
}
}
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(default)]
pub struct LocalConfigSettings {
pub struct GlobalSettings {
#[serde(rename = "primaryPort")]
pub primary_port: u16,
#[serde(rename = "portMapping")]
pub port_mapping: bool,
#[serde(rename = "log")]
pub log: LocalConfigLogSettings,
#[serde(rename = "interfacePrefixBlacklist")]
pub interface_prefix_blacklist: Vec<String>,
#[serde(rename = "explicitAddresses")]
pub explicit_addresses: Vec<InetAddress>,
}
impl Default for LocalConfigSettings {
impl Default for GlobalSettings {
fn default() -> Self {
let mut bl: Vec<String> = Vec::new();
bl.reserve(LocalConfigSettings::DEFAULT_PREFIX_BLACKLIST.len());
for n in LocalConfigSettings::DEFAULT_PREFIX_BLACKLIST.iter() {
bl.reserve(Self::DEFAULT_PREFIX_BLACKLIST.len());
for n in Self::DEFAULT_PREFIX_BLACKLIST.iter() {
bl.push(String::from(*n));
}
LocalConfigSettings {
Self {
primary_port: DEFAULT_PORT,
port_mapping: true,
log: LocalConfigLogSettings::default(),
interface_prefix_blacklist: bl,
explicit_addresses: Vec::new(),
}
}
}
impl LocalConfigSettings {
impl GlobalSettings {
#[cfg(target_os = "macos")]
const DEFAULT_PREFIX_BLACKLIST: [&'static str; 9] = ["lo", "utun", "gif", "stf", "iptap", "pktap", "feth", "zt", "llw"];
pub const DEFAULT_PREFIX_BLACKLIST: [&'static str; 9] = ["lo", "utun", "gif", "stf", "iptap", "pktap", "feth", "zt", "llw"];
#[cfg(target_os = "linux")]
const DEFAULT_PREFIX_BLACKLIST: [&'static str; 5] = ["lo", "tun", "tap", "ipsec", "zt"];
pub const DEFAULT_PREFIX_BLACKLIST: [&'static str; 5] = ["lo", "tun", "tap", "ipsec", "zt", "tailscale"];
#[cfg(windows)]
const DEFAULT_PREFIX_BLACKLIST: [&'static str; 0] = [];
pub const DEFAULT_PREFIX_BLACKLIST: [&'static str; 0] = [];
pub fn is_interface_blacklisted(&self, ifname: &str) -> bool {
for p in self.interface_prefix_blacklist.iter() {
@ -163,21 +130,66 @@ impl LocalConfigSettings {
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(default)]
pub struct LocalConfig {
pub physical: BTreeMap<InetAddress, LocalConfigPhysicalPathConfig>,
pub struct Config {
pub physical: BTreeMap<InetAddress, PhysicalPathSettings>,
#[serde(rename = "virtual")]
pub virtual_: BTreeMap<Address, LocalConfigVirtualConfig>,
pub network: BTreeMap<NetworkId, LocalConfigNetworkSettings>,
pub settings: LocalConfigSettings,
pub virtual_: BTreeMap<Address, VirtualNetworkSettings>,
pub network: BTreeMap<NetworkId, NetworkSettings>,
pub settings: GlobalSettings,
#[serde(skip_serializing, skip_deserializing)]
file_content_hash: [u8; 48],
}
impl Default for LocalConfig {
impl Default for Config {
fn default() -> Self {
LocalConfig {
Self {
physical: BTreeMap::new(),
virtual_: BTreeMap::new(),
network: BTreeMap::new(),
settings: LocalConfigSettings::default(),
settings: GlobalSettings::default(),
file_content_hash: [0_u8; 48],
}
}
}
impl Config {
/// Load this configuration from disk.
pub async fn load(path: &str) -> std::io::Result<Self> {
let mut t = Self::default();
t.reload(path).await.map(|_| t)
}
/// Load this configuration from disk if its contents have changed.
///
/// This returns true if a new configuration was loaded, false if the file hasn't changed, or an error.
pub async fn reload(&mut self, path: &str) -> std::io::Result<bool> {
let config_data = crate::utils::read_limit(path, crate::utils::DEFAULT_FILE_IO_READ_LIMIT).await?;
let hash = zerotier_core_crypto::hash::SHA384::hash(config_data.as_slice());
Ok(if hash != self.file_content_hash {
let config = serde_json::from_slice(config_data.as_slice());
if config.is_err() {
return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, config.err().unwrap().to_string()));
}
*self = config.unwrap();
self.file_content_hash = hash;
true
} else {
false
})
}
/// Write this configuration to a file (with human-friendly formatting).
///
/// This is mutable because it updates an external state if the write is successful.
pub async fn save(&mut self, path: &str) -> std::io::Result<()> {
let config_data = crate::utils::to_json_pretty(self);
let result = tokio::fs::write(path, &config_data).await;
if result.is_ok() {
self.file_content_hash = zerotier_core_crypto::hash::SHA384::hash(config_data.as_bytes());
Ok(())
} else {
result
}
}
}

View file

@ -86,7 +86,6 @@ Advanced Operations:
· list List root sets in use
sign <path> <?identity secret> Sign a root set with an identity
verify <path> Load and verify a root set
marshal <path> Dump root set as binary to stdout
service Start local service
(usually not invoked manually)
@ -105,12 +104,12 @@ pub fn print_help() {
let _ = std::io::stdout().write_all(h.as_bytes());
}
#[cfg(any(target_os = "macos"))]
#[cfg(target_os = "macos")]
pub fn platform_default_home_path() -> String {
"/Library/Application Support/ZeroTier".into()
}
#[cfg(any(target_os = "linux"))]
#[cfg(target_os = "linux")]
pub fn platform_default_home_path() -> String {
"/var/lib/zerotier".into()
}

View file

@ -6,22 +6,24 @@
* https://www.zerotier.com/
*/
use std::error::Error;
use std::str::FromStr;
use std::time::{Instant, SystemTime, UNIX_EPOCH};
use serde::de::DeserializeOwned;
use serde::{Serialize, Serializer};
use serde::Serialize;
use lazy_static::lazy_static;
use tokio::fs::File;
use tokio::io::{AsyncRead, AsyncReadExt};
use tokio::io::AsyncReadExt;
use crate::jsonformatter::JsonFormatter;
use zerotier_network_hypervisor::vl1::Identity;
/// Default sanity limit parameter for read_limit() used throughout the service.
pub const DEFAULT_FILE_IO_READ_LIMIT: usize = 1048576;
lazy_static! {
static ref STARTUP_INSTANT: Instant = Instant::now();
}