commit d418cf876bcd29d2f5f466a79a8363b2b18aaa77 Author: Avril Date: Sun Apr 11 00:33:21 2021 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..20c5f3d --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "encrypted-network" +version = "0.1.0" +authors = ["Avril "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +chacha20stream = {version = "1.0", features=["async"]} diff --git a/src/dual.rs b/src/dual.rs new file mode 100644 index 0000000..945aa9a --- /dev/null +++ b/src/dual.rs @@ -0,0 +1,119 @@ +//! Container for switching between un/encrypted stream +use super::*; +use std::mem::{self, MaybeUninit, ManuallyDrop}; +use std::ops::{Drop, Deref, DerefMut}; +use std::ptr; +use std::fmt; +use chacha20stream::AsyncSink; + +#[derive(Debug)] +pub enum DualStreamKind +{ + Encrypted(AsyncSink), + Plain(S), +} + +pub struct DualStream(MaybeUninit>>); + +impl fmt::Debug for DualStream +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + fmt::Debug::fmt(self.as_ref(), f) + } +} + + +impl DualStream +{ + fn as_mut_ref(&mut self) -> &mut Box> + { + // SAFETY: It is always initialised except exactly within the swap function + unsafe { + &mut *self.0.as_mut_ptr() + } + } + fn as_ref(&self) -> &Box> + { + // SAFETY: It is always initialised except exactly within the swap function + unsafe { + &*self.0.as_ptr() + } + } + + pub fn + + /// Create explicit + pub fn new(k: DualStreamKind) -> Self + { + Self(MaybeUninit::new(Box::new(k))) + } + + /// Consume into explicit (non-swappable) dual stream + pub fn into_inner(self) -> Box> + { + let mut md = ManuallyDrop::new(self); + unsafe { + // We could just `read()` the pointer, but this is more semantiacally equivalent to moving the value, I think. Idk if it's more or less efficient or whatever. + mem::replace(&mut md.0, MaybeUninit::uninit()).assume_init() + } + } +} + +impl Deref for DualStream +{ + type Target = DualStreamKind; + fn deref(&self) -> &Self::Target { + self.as_ref() + } +} +impl DerefMut for DualStream +{ + fn deref_mut(&mut self) -> &mut Self::Target { + self.as_mut_ref() + } +} + +impl From>> for DualStream +{ + fn from(from: Box>) -> Self + { + Self(MaybeUninit::new(from)) + } +} + +impl From> for DualStream +{ + fn from(from: DualStreamKind) -> Self + { + Self::new(from) + } +} + +impl From> for Box> +{ + fn from(from: DualStream) -> Self + { + from.into_inner() + } +} + + +impl From> for DualStreamKind +{ + fn from(from: DualStream) -> Self + { + *from.into_inner() + } +} + +impl Drop for DualStream +{ + fn drop(&mut self) { + // SAFETY: Value is always initialised except exactly within swap function + unsafe { + ptr::drop_in_place(self.0.as_mut_ptr()) + } + } +} + diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..22cf027 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,4 @@ + +#![allow(dead_code)] + +mod dual;