mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-28 18:03:46 +02:00
Formatting, build fixes, tests.
This commit is contained in:
parent
c5ed599ef3
commit
a23bd89202
13 changed files with 124 additions and 89 deletions
|
@ -55,9 +55,7 @@ impl Write for SHA512 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn flush(&mut self) -> std::io::Result<()> {
|
fn flush(&mut self) -> std::io::Result<()> { self.0.flush() }
|
||||||
self.0.flush()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SHA384(gcrypt::digest::MessageDigest);
|
pub struct SHA384(gcrypt::digest::MessageDigest);
|
||||||
|
@ -110,7 +108,5 @@ impl Write for SHA384 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn flush(&mut self) -> std::io::Result<()> {
|
fn flush(&mut self) -> std::io::Result<()> { self.0.flush() }
|
||||||
self.0.flush()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/// The poly1305 message authentication function.
|
||||||
pub struct Poly1305(gcrypt::mac::Mac);
|
pub struct Poly1305(gcrypt::mac::Mac);
|
||||||
|
|
||||||
pub const POLY1305_ONE_TIME_KEY_SIZE: usize = 32;
|
pub const POLY1305_ONE_TIME_KEY_SIZE: usize = 32;
|
||||||
|
|
|
@ -2,13 +2,12 @@ use rand_core::{RngCore, Error};
|
||||||
use rand_core::CryptoRng;
|
use rand_core::CryptoRng;
|
||||||
use gcrypt::rand::{Level, randomize};
|
use gcrypt::rand::{Level, randomize};
|
||||||
|
|
||||||
|
/// Secure random source based on the desired third party library (gcrypt).
|
||||||
pub struct SecureRandom;
|
pub struct SecureRandom;
|
||||||
|
|
||||||
impl SecureRandom {
|
impl SecureRandom {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn get() -> Self {
|
pub fn get() -> Self { Self }
|
||||||
Self
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RngCore for SecureRandom {
|
impl RngCore for SecureRandom {
|
||||||
|
@ -27,9 +26,7 @@ impl RngCore for SecureRandom {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn fill_bytes(&mut self, dest: &mut [u8]) {
|
fn fill_bytes(&mut self, dest: &mut [u8]) { randomize(Level::Strong, dest); }
|
||||||
randomize(Level::Strong, dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
|
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
|
||||||
|
@ -41,20 +38,18 @@ impl RngCore for SecureRandom {
|
||||||
impl CryptoRng for SecureRandom {}
|
impl CryptoRng for SecureRandom {}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn next_u32_secure() -> u32 {
|
pub fn next_u32_secure() -> u32 {
|
||||||
let mut tmp = 0_u32;
|
let mut tmp = 0_u32;
|
||||||
randomize(Level::Strong, unsafe { &mut *(&mut tmp as *mut u32).cast::<[u8; 4]>() });
|
randomize(Level::Strong, unsafe { &mut *(&mut tmp as *mut u32).cast::<[u8; 4]>() });
|
||||||
tmp
|
tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn next_u64_secure() -> u64 {
|
pub fn next_u64_secure() -> u64 {
|
||||||
let mut tmp = 0_u64;
|
let mut tmp = 0_u64;
|
||||||
randomize(Level::Strong, unsafe { &mut *(&mut tmp as *mut u64).cast::<[u8; 8]>() });
|
randomize(Level::Strong, unsafe { &mut *(&mut tmp as *mut u64).cast::<[u8; 8]>() });
|
||||||
tmp
|
tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn fill_bytes_secure(dest: &mut [u8]) {
|
pub fn fill_bytes_secure(dest: &mut [u8]) { randomize(Level::Strong, dest); }
|
||||||
randomize(Level::Strong, dest);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/// The classic Salsa20 stream cipher supporting 20-round and 12-round variants.
|
||||||
pub struct Salsa(gcrypt::cipher::Cipher);
|
pub struct Salsa(gcrypt::cipher::Cipher);
|
||||||
|
|
||||||
impl Salsa {
|
impl Salsa {
|
||||||
|
|
|
@ -11,14 +11,10 @@ impl<const FREQ: i64> Default for IntervalGate<FREQ> {
|
||||||
|
|
||||||
impl<const FREQ: i64> IntervalGate<FREQ> {
|
impl<const FREQ: i64> IntervalGate<FREQ> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn new(initial_ts: i64) -> Self {
|
pub fn new(initial_ts: i64) -> Self { Self(initial_ts) }
|
||||||
Self(initial_ts)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) { self.0 = 0; }
|
||||||
self.0 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn gate(&mut self, time: i64) -> bool {
|
pub fn gate(&mut self, time: i64) -> bool {
|
||||||
|
@ -35,33 +31,31 @@ impl<const FREQ: i64> IntervalGate<FREQ> {
|
||||||
pub struct AtomicIntervalGate<const FREQ: i64>(AtomicI64);
|
pub struct AtomicIntervalGate<const FREQ: i64>(AtomicI64);
|
||||||
|
|
||||||
impl<const FREQ: i64> Default for AtomicIntervalGate<FREQ> {
|
impl<const FREQ: i64> Default for AtomicIntervalGate<FREQ> {
|
||||||
fn default() -> Self {
|
fn default() -> Self { Self(AtomicI64::new(0)) }
|
||||||
Self(AtomicI64::new(0))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const FREQ: i64> AtomicIntervalGate<FREQ> {
|
impl<const FREQ: i64> AtomicIntervalGate<FREQ> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn new(initial_ts: i64) -> Self {
|
pub fn new(initial_ts: i64) -> Self { Self(AtomicI64::new(initial_ts)) }
|
||||||
Self(AtomicI64::new(initial_ts))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn reset(&self) {
|
pub fn reset(&self) { self.0.store(0, Ordering::Relaxed); }
|
||||||
self.0.store(0, Ordering::Relaxed);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn gate(&self, time: i64) -> bool {
|
pub fn gate(&self, mut time: i64) -> bool {
|
||||||
// Note that if two or more threads are using this at once, any thread's time might
|
let prev_time = self.0.load(Ordering::Relaxed);
|
||||||
// end up being the one stored. This is okay since these times should either be the
|
if (time - prev_time) < FREQ {
|
||||||
// same or very close, and slight differences won't cause issues with the use cases
|
|
||||||
// for this. This is primarily used to rate gate operations to prevent DOS attacks.
|
|
||||||
if (time - self.0.load(Ordering::Relaxed)) >= FREQ {
|
|
||||||
self.0.store(time, Ordering::Relaxed);
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
false
|
||||||
|
} else {
|
||||||
|
loop {
|
||||||
|
let pt = self.0.swap(time, Ordering::Relaxed);
|
||||||
|
if pt <= time {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
time = pt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
pub mod hex;
|
pub mod hex;
|
||||||
pub mod pool;
|
pub mod pool;
|
||||||
pub mod gate;
|
pub mod gate;
|
||||||
|
pub mod varint;
|
||||||
|
|
||||||
pub(crate) const ZEROES: [u8; 64] = [0_u8; 64];
|
pub(crate) const ZEROES: [u8; 64] = [0_u8; 64];
|
||||||
|
|
||||||
|
|
53
network-hypervisor/src/util/varint.rs
Normal file
53
network-hypervisor/src/util/varint.rs
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
|
pub fn write<W: Write>(w: &mut W, mut v: u64) -> std::io::Result<()> {
|
||||||
|
let mut b = [0_u8; 10];
|
||||||
|
let mut i = 10;
|
||||||
|
loop {
|
||||||
|
if v > 0x7f {
|
||||||
|
i -= 1;
|
||||||
|
b[i] = (v as u8) & 0x7f;
|
||||||
|
v >>= 7;
|
||||||
|
} else {
|
||||||
|
i -= 1;
|
||||||
|
b[i] = (v as u8) | 0x80;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.write_all(&b[i..])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read<R: Read>(r: &mut R) -> std::io::Result<u64> {
|
||||||
|
let mut v = 0_u64;
|
||||||
|
let mut buf = [0_u8; 1];
|
||||||
|
loop {
|
||||||
|
v <<= 7;
|
||||||
|
let _ = r.read_exact(&mut buf)?;
|
||||||
|
let b = buf[0];
|
||||||
|
if b <= 0x7f {
|
||||||
|
v |= b as u64;
|
||||||
|
} else {
|
||||||
|
v |= (b & 0x7f) as u64;
|
||||||
|
return Ok(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn read_from_bytes(r: &[u8], cursor: &mut usize) -> std::io::Result<u64> {
|
||||||
|
let mut v = 0_u64;
|
||||||
|
let mut c = *cursor;
|
||||||
|
while c < r.len() {
|
||||||
|
v <<= 7;
|
||||||
|
let b = unsafe { *r.get_unchecked(c) };
|
||||||
|
c += 1;
|
||||||
|
if b <= 0x7f {
|
||||||
|
v |= b as u64;
|
||||||
|
} else {
|
||||||
|
v |= (b & 0x7f) as u64;
|
||||||
|
*cursor = c;
|
||||||
|
return Ok(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*cursor = c;
|
||||||
|
return Err(std::io::Error::new(std::io::ErrorKind::UnexpectedEof, "incomplete varint"));
|
||||||
|
}
|
|
@ -23,7 +23,6 @@ impl Address {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an address from a byte slice or return None if it is zero or reserved.
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn from_bytes(b: &[u8]) -> Option<Address> {
|
pub fn from_bytes(b: &[u8]) -> Option<Address> {
|
||||||
if b.len() >= ADDRESS_SIZE {
|
if b.len() >= ADDRESS_SIZE {
|
||||||
|
@ -38,6 +37,16 @@ impl Address {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn from_bytes_fixed(b: &[u8; ADDRESS_SIZE]) -> Option<Address> {
|
||||||
|
let i = (b[0] as u64) << 32 | (b[1] as u64) << 24 | (b[2] as u64) << 16 | (b[3] as u64) << 8 | b[4] as u64;
|
||||||
|
if i != 0 && (i >> 32) != ADDRESS_RESERVED_PREFIX as u64 {
|
||||||
|
Some(Address(unsafe { NonZeroU64::new_unchecked(i) }))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn to_bytes(&self) -> [u8; ADDRESS_SIZE] {
|
pub fn to_bytes(&self) -> [u8; ADDRESS_SIZE] {
|
||||||
let i = self.0.get();
|
let i = self.0.get();
|
||||||
|
@ -61,7 +70,7 @@ impl Address {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn unmarshal<const BL: usize>(buf: &Buffer<BL>, cursor: &mut usize) -> std::io::Result<Option<Self>> {
|
pub(crate) fn unmarshal<const BL: usize>(buf: &Buffer<BL>, cursor: &mut usize) -> std::io::Result<Option<Self>> {
|
||||||
buf.read_bytes_fixed::<{ ADDRESS_SIZE }>(cursor).map(|b| Self::from_bytes(b))
|
buf.read_bytes_fixed::<{ ADDRESS_SIZE }>(cursor).map(|b| Self::from_bytes_fixed(b))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ impl<const L: usize> Buffer<L> {
|
||||||
pub fn new() -> Self { Self(0, [0_u8; L]) }
|
pub fn new() -> Self { Self(0, [0_u8; L]) }
|
||||||
|
|
||||||
/// Get a Buffer initialized with a copy of a byte slice.
|
/// Get a Buffer initialized with a copy of a byte slice.
|
||||||
#[inline(always)]
|
|
||||||
pub fn from_bytes(b: &[u8]) -> std::io::Result<Self> {
|
pub fn from_bytes(b: &[u8]) -> std::io::Result<Self> {
|
||||||
let l = b.len();
|
let l = b.len();
|
||||||
if l <= L {
|
if l <= L {
|
||||||
|
@ -165,19 +164,9 @@ impl<const L: usize> Buffer<L> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Append a variable length integer to this buffer.
|
/// Append a variable length integer to this buffer.
|
||||||
///
|
#[inline(always)]
|
||||||
/// Varints are encoded as a series of 7-bit bytes terminated by a final 7-bit byte whose
|
|
||||||
/// most significant bit is set. Unlike fixed size integers varints are written in little
|
|
||||||
/// endian order (in 7-bit chunks).
|
|
||||||
///
|
|
||||||
/// They are slower than fixed size values so they should not be used in formats that are
|
|
||||||
/// created or parsed in very speed-critical paths.
|
|
||||||
pub fn append_varint(&mut self, mut i: u64) -> std::io::Result<()> {
|
pub fn append_varint(&mut self, mut i: u64) -> std::io::Result<()> {
|
||||||
while i >= 0x80 {
|
crate::util::varint::write(self, i)
|
||||||
self.append_u8((i as u8) & 0x7f)?;
|
|
||||||
i >>= 7;
|
|
||||||
}
|
|
||||||
self.append_u8((i as u8) | 0x80)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Append a byte
|
/// Append a byte
|
||||||
|
@ -317,20 +306,9 @@ impl<const L: usize> Buffer<L> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the next variable length integer and advance the cursor by its length in bytes.
|
/// Get the next variable length integer and advance the cursor by its length in bytes.
|
||||||
|
#[inline(always)]
|
||||||
pub fn read_varint(&self, cursor: &mut usize) -> std::io::Result<u64> {
|
pub fn read_varint(&self, cursor: &mut usize) -> std::io::Result<u64> {
|
||||||
let mut i = 0_u64;
|
crate::util::varint::read_from_bytes(&(self.1[self.0..]), cursor)
|
||||||
let mut p = 0;
|
|
||||||
loop {
|
|
||||||
let b = self.read_u8(cursor)?;
|
|
||||||
if (b & 0x80) == 0 {
|
|
||||||
i |= (b as u64).wrapping_shl(p);
|
|
||||||
p += 7;
|
|
||||||
} else {
|
|
||||||
i |= ((b & 0x7f) as u64) << p;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(i)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the next u8 and advance the cursor.
|
/// Get the next u8 and advance the cursor.
|
||||||
|
|
|
@ -71,16 +71,7 @@ impl Dictionary {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_bool(&self, k: &str) -> Option<bool> {
|
pub fn get_bool(&self, k: &str) -> Option<bool> {
|
||||||
self.0.get(k).map_or(None, |v| {
|
self.0.get(k).map_or(None, |v| v.first().map_or(Some(false), |c| Some("1tTyY".contains(*c as char))))
|
||||||
if v.is_empty() {
|
|
||||||
Some(false)
|
|
||||||
} else {
|
|
||||||
Some(match v[0] {
|
|
||||||
b'1' | b't' | b'T' | b'y' | b'Y' => true,
|
|
||||||
_ => false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_str(&mut self, k: &str, v: &str) {
|
pub fn set_str(&mut self, k: &str, v: &str) {
|
||||||
|
@ -96,7 +87,7 @@ impl Dictionary {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_bool(&mut self, k: &str, v: bool) {
|
pub fn set_bool(&mut self, k: &str, v: bool) {
|
||||||
let _ = self.0.insert(String::from(k), (if v { [b'1'] } else { [b'0'] }).to_vec());
|
let _ = self.0.insert(String::from(k), vec![if v { b'1' } else { b'0' }]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a dictionary in transport format to a writer.
|
/// Write a dictionary in transport format to a writer.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
|
||||||
use crate::vl1::{Address, Endpoint, Identity};
|
use crate::vl1::{Address, Endpoint, Identity, Dictionary};
|
||||||
use crate::vl1::buffer::Buffer;
|
use crate::vl1::buffer::Buffer;
|
||||||
use crate::vl1::protocol::PACKET_SIZE_MAX;
|
use crate::vl1::protocol::PACKET_SIZE_MAX;
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ pub struct Locator {
|
||||||
pub subject: Address,
|
pub subject: Address,
|
||||||
pub signer: Address,
|
pub signer: Address,
|
||||||
pub timestamp: i64,
|
pub timestamp: i64,
|
||||||
|
pub metadata: Option<Dictionary>,
|
||||||
pub endpoints: Vec<Endpoint>,
|
pub endpoints: Vec<Endpoint>,
|
||||||
pub signature: Vec<u8>,
|
pub signature: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
@ -34,6 +35,7 @@ impl Locator {
|
||||||
subject,
|
subject,
|
||||||
signer: signer_identity.address(),
|
signer: signer_identity.address(),
|
||||||
timestamp: ts,
|
timestamp: ts,
|
||||||
|
metadata: None,
|
||||||
endpoints: endpoints.to_vec(),
|
endpoints: endpoints.to_vec(),
|
||||||
signature: Vec::new()
|
signature: Vec::new()
|
||||||
};
|
};
|
||||||
|
@ -81,12 +83,16 @@ impl Locator {
|
||||||
fn marshal_internal<const BL: usize>(&self, buf: &mut Buffer<BL>, exclude_signature: bool) -> std::io::Result<()> {
|
fn marshal_internal<const BL: usize>(&self, buf: &mut Buffer<BL>, exclude_signature: bool) -> std::io::Result<()> {
|
||||||
self.subject.marshal(buf)?;
|
self.subject.marshal(buf)?;
|
||||||
self.signer.marshal(buf)?;
|
self.signer.marshal(buf)?;
|
||||||
buf.append_u64(self.timestamp as u64)?;
|
buf.append_varint(self.timestamp as u64)?;
|
||||||
|
self.metadata.map_or_else(|| buf.append_varint(0), |d| {
|
||||||
|
let db = d.to_bytes();
|
||||||
|
buf.append_varint(db.len() as u64)?;
|
||||||
|
buf.append_bytes(db.as_slice())
|
||||||
|
})?;
|
||||||
buf.append_varint(self.endpoints.len() as u64)?;
|
buf.append_varint(self.endpoints.len() as u64)?;
|
||||||
for e in self.endpoints.iter() {
|
for e in self.endpoints.iter() {
|
||||||
e.marshal(buf)?;
|
e.marshal(buf)?;
|
||||||
}
|
}
|
||||||
buf.append_varint(0)?; // length of any additional fields
|
|
||||||
if !exclude_signature {
|
if !exclude_signature {
|
||||||
buf.append_varint(self.signature.len() as u64)?;
|
buf.append_varint(self.signature.len() as u64)?;
|
||||||
buf.append_bytes(self.signature.as_slice())?;
|
buf.append_bytes(self.signature.as_slice())?;
|
||||||
|
@ -104,18 +110,26 @@ impl Locator {
|
||||||
return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "invalid subject or signer address"));
|
return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "invalid subject or signer address"));
|
||||||
}
|
}
|
||||||
let timestamp = buf.read_u64(cursor)? as i64;
|
let timestamp = buf.read_u64(cursor)? as i64;
|
||||||
|
let metadata_size = buf.read_varint(cursor)? as usize;
|
||||||
|
let metadata = if metadata_size > 0 {
|
||||||
|
let md = Dictionary::from_bytes(buf.read_bytes(metadata_size, cursor)?);
|
||||||
|
if md.is_none() {
|
||||||
|
return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "invalid meta-data"));
|
||||||
|
}
|
||||||
|
md
|
||||||
|
} else { None };
|
||||||
let endpoint_count = buf.read_varint(cursor)? as usize;
|
let endpoint_count = buf.read_varint(cursor)? as usize;
|
||||||
let mut endpoints: Vec<Endpoint> = Vec::new();
|
let mut endpoints: Vec<Endpoint> = Vec::new();
|
||||||
for _ in 0..endpoint_count {
|
for _ in 0..endpoint_count {
|
||||||
endpoints.push(Endpoint::unmarshal(buf, cursor)?);
|
endpoints.push(Endpoint::unmarshal(buf, cursor)?);
|
||||||
}
|
}
|
||||||
*cursor += buf.read_varint(cursor)? as usize;
|
|
||||||
let signature_len = buf.read_varint(cursor)? as usize;
|
let signature_len = buf.read_varint(cursor)? as usize;
|
||||||
let signature = buf.read_bytes(signature_len, cursor)?;
|
let signature = buf.read_bytes(signature_len, cursor)?;
|
||||||
Ok(Locator {
|
Ok(Locator {
|
||||||
subject: subject.unwrap(),
|
subject: subject.unwrap(),
|
||||||
signer: signer.unwrap(),
|
signer: signer.unwrap(),
|
||||||
timestamp,
|
timestamp,
|
||||||
|
metadata,
|
||||||
endpoints,
|
endpoints,
|
||||||
signature: signature.to_vec(),
|
signature: signature.to_vec(),
|
||||||
})
|
})
|
||||||
|
|
|
@ -16,12 +16,17 @@ impl MAC {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn from_bytes(b: &[u8]) -> Option<MAC> {
|
pub fn from_bytes(b: &[u8]) -> Option<MAC> {
|
||||||
if b.len() >= 6 {
|
if b.len() >= 6 {
|
||||||
NonZeroU64::new((b[0] as u64) << 40 | (b[1] as u64) << 32 | (b[2] as u64) << 24 | (b[3] as u64) << 16 as u64 | (b[4] as u64) << 8 | b[5] as u64).map_or(None, |i| Some(MAC(i)))
|
NonZeroU64::new((b[0] as u64) << 40 | (b[1] as u64) << 32 | (b[2] as u64) << 24 | (b[3] as u64) << 16 as u64 | (b[4] as u64) << 8 | b[5] as u64).map(|i| MAC(i))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn from_bytes_fixed(b: &[u8; 6]) -> Option<MAC> {
|
||||||
|
NonZeroU64::new((b[0] as u64) << 40 | (b[1] as u64) << 32 | (b[2] as u64) << 24 | (b[3] as u64) << 16 as u64 | (b[4] as u64) << 8 | b[5] as u64).map(|i| MAC(i))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn to_bytes(&self) -> [u8; 6] {
|
pub fn to_bytes(&self) -> [u8; 6] {
|
||||||
let i = self.0.get();
|
let i = self.0.get();
|
||||||
|
@ -31,7 +36,6 @@ impl MAC {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn to_u64(&self) -> u64 { self.0.get() }
|
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<()> {
|
pub(crate) fn marshal<const BL: usize>(&self, buf: &mut Buffer<BL>) -> std::io::Result<()> {
|
||||||
buf.append_and_init_bytes_fixed(|b: &mut [u8; 6]| {
|
buf.append_and_init_bytes_fixed(|b: &mut [u8; 6]| {
|
||||||
let i = self.0.get();
|
let i = self.0.get();
|
||||||
|
@ -46,7 +50,7 @@ impl MAC {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn unmarshal<const BL: usize>(buf: &Buffer<BL>, cursor: &mut usize) -> std::io::Result<Option<Self>> {
|
pub(crate) fn unmarshal<const BL: usize>(buf: &Buffer<BL>, cursor: &mut usize) -> std::io::Result<Option<Self>> {
|
||||||
buf.read_bytes_fixed::<6>(cursor).map(|b| Self::from_bytes(b))
|
buf.read_bytes_fixed::<6>(cursor).map(|b| Self::from_bytes_fixed(b))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -296,13 +296,11 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn default_root_set() {
|
fn default_root_set() {
|
||||||
let rs = RootSet::from_bytes(&crate::defaults::ROOT_SET).unwrap();
|
let rs = RootSet::from_bytes(&crate::defaults::ROOT_SET).unwrap();
|
||||||
/*
|
|
||||||
rs.roots.iter().for_each(|r| {
|
rs.roots.iter().for_each(|r| {
|
||||||
println!("{}", r.identity.to_string());
|
println!("{}", r.identity.to_string());
|
||||||
r.endpoints.iter().for_each(|ep| {
|
r.endpoints.iter().for_each(|ep| {
|
||||||
println!(" {}", ep.to_string());
|
println!(" {}", ep.to_string());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue