From 3231b51f893043f22a1b058e9b07363f7f722b86 Mon Sep 17 00:00:00 2001 From: Nadja Reitzenstein Date: Thu, 28 Oct 2021 01:10:35 +0200 Subject: [PATCH] Make more things burn less --- bffhd/db.rs | 4 ++-- bffhd/db/hash.rs | 21 ++++++++++++++++++++- bffhd/db/pass.rs | 2 +- bffhd/db/resources.rs | 2 +- bffhd/db/typed.rs | 42 ++++++++++++++++------------------------- bffhd/db/user.rs | 2 +- bffhd/error.rs | 16 ++-------------- bffhd/lib.rs | 16 ++++++++++++++-- bffhd/network.rs | 25 ------------------------ bffhd/oid.rs | 44 +++++++++++++++++++++++++------------------ bffhd/resource.rs | 1 + bffhd/state.rs | 1 + bffhd/state/value.rs | 1 + bffhd/varint.rs | 1 + bin/bffhd/main.rs | 3 ++- 15 files changed, 89 insertions(+), 92 deletions(-) delete mode 100644 bffhd/network.rs diff --git a/bffhd/db.rs b/bffhd/db.rs index 87e6c7e..0159edb 100644 --- a/bffhd/db.rs +++ b/bffhd/db.rs @@ -27,7 +27,6 @@ pub use typed::{ Adapter, OutputBuffer, - OutputWriter, }; mod hash; @@ -112,7 +111,7 @@ impl> Adapter for AllocAdapter { } } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub struct AlignedAdapter { phantom: PhantomData, } @@ -136,6 +135,7 @@ impl>> Adapter for AlignedAdapter } } +#[derive(Debug)] pub struct Databases { pub userdb: UserDB, pub passdb: PassDB, diff --git a/bffhd/db/hash.rs b/bffhd/db/hash.rs index 4ceca48..f6f85ea 100644 --- a/bffhd/db/hash.rs +++ b/bffhd/db/hash.rs @@ -6,7 +6,10 @@ use std::{ BuildHasher, }, collections::hash_map::RandomState, + fmt, + fmt::Debug, }; +use std::fmt::Formatter; use rkyv::{ Archive, @@ -31,7 +34,7 @@ use super::{ }; -#[derive(Archive, Serialize, Deserialize)] +#[derive(Archive, Serialize, Deserialize, Debug)] /// The entry as it is stored inside the database. pub struct Entry { pub key: K, @@ -48,6 +51,12 @@ impl HashAdapter { Self { k: PhantomData, a: PhantomData } } } +impl Debug for HashAdapter { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + use core::any::type_name; + write!(f, "HashAdapter<{}, {}>", type_name::(), type_name::()) + } +} impl Fallible for HashAdapter { type Error = ::Error; } impl Adapter for HashAdapter @@ -77,6 +86,16 @@ pub struct HashDB hash_builder: H, } +impl fmt::Debug for HashDB { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let adapter = HashAdapter::::new(); + f.debug_struct("HashDB") + .field("db", &adapter) + .field("hasher", &self.hash_builder) + .finish() + } +} + impl HashDB { pub unsafe fn create(env: &Environment, name: Option<&str>) -> lmdb::Result { diff --git a/bffhd/db/pass.rs b/bffhd/db/pass.rs index 35c4b6d..1f1064a 100644 --- a/bffhd/db/pass.rs +++ b/bffhd/db/pass.rs @@ -10,7 +10,7 @@ use super::Transaction; use argon2; type Adapter = AllocAdapter; -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct PassDB { env: Arc, db: DB, diff --git a/bffhd/db/resources.rs b/bffhd/db/resources.rs index 139f488..e11913f 100644 --- a/bffhd/db/resources.rs +++ b/bffhd/db/resources.rs @@ -19,7 +19,7 @@ pub struct Resource { description_idx: u64, } -#[derive(Clone)] +#[derive(Debug, Clone)] pub struct ResourceDB { env: Arc, db: DB>, diff --git a/bffhd/db/typed.rs b/bffhd/db/typed.rs index 60ff419..a10fa78 100644 --- a/bffhd/db/typed.rs +++ b/bffhd/db/typed.rs @@ -31,18 +31,28 @@ use lmdb::{ use super::RawDB; +/// Database Adapter to create a typed DB returning Rust types pub trait Adapter: Fallible { + /// The serializer that will be instantiated to resolve the stored types type Serializer: rkyv::ser::Serializer; + /// Actual Value that will be extracted type Value: Serialize; + /// Create a new serializer fn new_serializer() -> Self::Serializer; + /// Convert any Serializer Error in your shared error. + /// + /// You *must* implement this if you don't use `Infallible` as Supertrait. fn from_ser_err(e: ::Error) -> ::Error; + + /// Convert the Database Error type into your shared error. + // TODO: Extract both conversion into their own trait because there's a sensible impl for + // `Infallible` for both. fn from_db_err(e: lmdb::Error) -> ::Error; } struct AdapterPrettyPrinter(PhantomData); - impl AdapterPrettyPrinter { pub fn new() -> Self { Self(PhantomData) } } @@ -56,8 +66,11 @@ impl fmt::Debug for AdapterPrettyPrinter { } } +/// Deserialize adapter to write into an Buffer pub trait OutputBuffer { + /// The kind of buffer type Buffer: AsRef<[u8]>; + /// convert yourself into this buffer fn into_slice(self) -> Self::Buffer; } @@ -68,11 +81,6 @@ impl OutputBuffer for AllocSerializer { } } -// TODO: This should be possible to autoimplement for Sized Serializers -pub trait OutputWriter: Fallible { - fn write_into(&mut self, buf: &mut [u8]) -> Result<(), Self::Error>; -} - pub struct DB { db: RawDB, phantom: PhantomData, @@ -171,26 +179,7 @@ impl<'a, A> DB } } -impl<'a, A> DB - where A: Adapter, - A::Serializer: OutputWriter, -{ - pub fn put_nocopy>(&self, txn: &mut RwTransaction, key: &K, val: &A::Value, flags: WriteFlags) - -> Result - { - let mut serializer = A::new_serializer(); - let pos = serializer.serialize_value(val) - .map_err(A::from_ser_err)?; - - let mut buf = self.db.reserve(txn, &key.as_ref(), pos, flags) - .map_err(A::from_db_err)?; - serializer.write_into(&mut buf) - .map_err(A::from_ser_err)?; - - Ok(pos) - } -} - +#[derive(Debug)] pub struct TypedCursor { cursor: C, phantom: PhantomData, @@ -218,6 +207,7 @@ impl<'txn, C, A> TypedCursor } } +#[derive(Debug)] pub struct Iter<'txn, A> { iter: lmdb::Iter<'txn>, phantom: PhantomData, diff --git a/bffhd/db/user.rs b/bffhd/db/user.rs index 8ada90c..0434a1c 100644 --- a/bffhd/db/user.rs +++ b/bffhd/db/user.rs @@ -6,7 +6,7 @@ use crate::db::{DatabaseFlags, LMDBorrow, RoTransaction, WriteFlags, }; use rkyv::{Archive, Serialize, Deserialize, Archived}; type Adapter = AllocAdapter; -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct UserDB { env: Arc, db: DB, diff --git a/bffhd/error.rs b/bffhd/error.rs index faa60c2..9ec0b38 100644 --- a/bffhd/error.rs +++ b/bffhd/error.rs @@ -1,6 +1,5 @@ use std::io; use std::fmt; -use serde_dhall; use rsasl::SaslError; @@ -9,8 +8,8 @@ use crate::db::DBError; //FIXME use crate::network; #[derive(Debug)] +/// Shared error type pub enum Error { - Dhall(serde_dhall::Error), SASL(SaslError), IO(io::Error), Boxed(Box), @@ -22,9 +21,6 @@ pub enum Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Error::Dhall(e) => { - write!(f, "Dhall coding error: {}", e) - }, Error::SASL(e) => { write!(f, "SASL Error: {}", e) }, @@ -59,12 +55,6 @@ impl From for Error { } } -impl From for Error { - fn from(e: serde_dhall::Error) -> Error { - Error::Dhall(e) - } -} - impl From> for Error { fn from(e: Box) -> Error { Error::Boxed(e) @@ -81,6 +71,4 @@ impl From for Error { fn from(e: DBError) -> Error { Error::DB(e) } -} - -pub(crate) type Result = std::result::Result; \ No newline at end of file +} \ No newline at end of file diff --git a/bffhd/lib.rs b/bffhd/lib.rs index 250dc11..c526f7d 100644 --- a/bffhd/lib.rs +++ b/bffhd/lib.rs @@ -1,14 +1,26 @@ #![forbid(unused_imports)] -#![warn(missing_docs, missing_debug_implementations)] +#![warn(missing_debug_implementations)] +//! Diflouroborane +//! +//! This is the server component of the FabAccess project. +//! The entry point of bffhd can be found in [bin/bffhd/main.rs](../bin/bffhd/main.rs) +//! +//! P.S.: If you're curious about the name; the project was initially called "Better Fablab +//! Friend and Helper" (BFFH). And the chemical formula of Diflouroborane is BF2H. +/// Internal Databases build on top of LMDB, a mmap()'ed B-tree DB optimized for reads pub mod db; +/// Shared error type pub mod error; -pub mod network; pub mod oid; +/// Policy decision engine pub mod permissions; +/// Resources pub mod resource; +/// State of Resources pub mod state; +/// Varints pub mod varint; use intmap::IntMap; diff --git a/bffhd/network.rs b/bffhd/network.rs deleted file mode 100644 index 51d1c02..0000000 --- a/bffhd/network.rs +++ /dev/null @@ -1,25 +0,0 @@ -use std::{ - sync::Arc, - collections::HashMap, -}; - -use futures_signals::signal::{ - Mutable, - MutableSignalCloned -}; - -use crate::state::State; - -type ResourceState = Mutable>; -type ResourceStateSignal = MutableSignalCloned>; - -/// Connection Broker between Resources and Subscribers -/// -/// This serves as touch-off point between resources and anybody else. It doesn't drive -/// any state updates, it only allows subscribers to subscribe to the resources that are -/// driving the state updates -pub struct Network { - sources: HashMap, -} - - diff --git a/bffhd/oid.rs b/bffhd/oid.rs index 9096399..e6a4ef2 100644 --- a/bffhd/oid.rs +++ b/bffhd/oid.rs @@ -293,23 +293,6 @@ fn parse_string_first_node(first_child_node: &str) -> Result -) -> Result<(), ObjectIdentifierError> { - let node: Node = node_str.parse() - .map_err(|_| ObjectIdentifierError::IllegalChildNodeValue)?; - // TODO bench against !*node &= 0x80, compiler may already optimize better - if node <= 127 { - out.push(node as u8); - } else { - let vi: VarNode = node.into(); - out.extend_from_slice(vi.as_bytes()); - } - - Ok(()) -} - impl ObjectIdentifier { fn from_string(value: S) -> Result where @@ -512,7 +495,7 @@ pub(crate) mod tests { pub(crate) fn gen_random() -> ObjectIdentifier { let amt: u8 = rand::random::() % 10 + 1; let mut children = Vec::new(); - for i in 0..amt { + for _ in 0..amt { children.push(rand::random()); } @@ -868,6 +851,31 @@ pub(crate) mod tests { assert_eq!(expected, actual); } + #[test] + fn parse_string_large_children_ok() { + let expected = + ObjectIdentifier::build(ObjectIdentifierRoot::JointIsoItuT, + 25, + vec![190754093376743485973207716749546715206, + 255822649272987943607843257596365752308, + 15843412533224453995377625663329542022, + 6457999595881951503805148772927347934, + 19545192863105095042881850060069531734, + 195548685662657784196186957311035194990, + 233020488258340943072303499291936117654, + 193307160423854019916786016773068715190, + ]).unwrap(); + let actual = "2.25.190754093376743485973207716749546715206.\ + 255822649272987943607843257596365752308.\ + 15843412533224453995377625663329542022.\ + 6457999595881951503805148772927347934.\ + 19545192863105095042881850060069531734.\ + 195548685662657784196186957311035194990.\ + 233020488258340943072303499291936117654.\ + 193307160423854019916786016773068715190".try_into().unwrap(); + assert_eq!(expected, actual); + } + #[test] fn encode_to_string() { let expected = String::from("1.2.3.4"); diff --git a/bffhd/resource.rs b/bffhd/resource.rs index fa4006c..eb1c6d3 100644 --- a/bffhd/resource.rs +++ b/bffhd/resource.rs @@ -64,6 +64,7 @@ pub enum Error { } // TODO: more message context +#[derive(Debug)] pub struct Update { pub state: State, pub errchan: Sender, diff --git a/bffhd/state.rs b/bffhd/state.rs index 65aca8c..9ba5093 100644 --- a/bffhd/state.rs +++ b/bffhd/state.rs @@ -73,6 +73,7 @@ impl fmt::Debug for State { } } +#[derive(Debug)] pub struct StateBuilder { hasher: DefaultHasher, inner: Vec diff --git a/bffhd/state/value.rs b/bffhd/state/value.rs index 86804ae..e914ca6 100644 --- a/bffhd/state/value.rs +++ b/bffhd/state/value.rs @@ -380,6 +380,7 @@ impl ImplData<'_> { } } +#[derive(Debug)] pub struct ImplEntry<'a> { id: ImplId<'a>, data: ImplData<'a>, diff --git a/bffhd/varint.rs b/bffhd/varint.rs index a7d3f83..e6e44bf 100644 --- a/bffhd/varint.rs +++ b/bffhd/varint.rs @@ -1,6 +1,7 @@ use std::default::Default; use std::ops::{Deref}; +#[derive(Debug)] pub struct VarUInt { offset: usize, bytes: [u8; N], diff --git a/bin/bffhd/main.rs b/bin/bffhd/main.rs index 009bb32..4fef228 100644 --- a/bin/bffhd/main.rs +++ b/bin/bffhd/main.rs @@ -75,7 +75,8 @@ fn main() -> Result<(), Error> { // If no `config` option is given use a preset default. let configpath = matches.value_of("config").unwrap_or("/etc/diflouroborane.dhall"); - let config = config::read(&PathBuf::from_str(configpath).unwrap())?; + let config = config::read(&PathBuf::from_str(configpath).unwrap()) + .expect("Failed to parse config"); println!("{:#?}", config); let mut sockaddrs = Vec::new();