From e6fa8b694ce8a15d47bc3db802ab2a5a50ab6457 Mon Sep 17 00:00:00 2001 From: antifallobst Date: Tue, 21 May 2024 04:16:51 +0200 Subject: [PATCH] feat: implemented responses --- Cargo.lock | 28 +++++++++++---- Cargo.toml | 2 +- src/error.rs | 22 ++++++++++++ src/lib.rs | 99 ++++++++++++++++++++++++++++------------------------ 4 files changed, 98 insertions(+), 53 deletions(-) create mode 100644 src/error.rs diff --git a/Cargo.lock b/Cargo.lock index 1ec8272..b4d3eff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,12 +53,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "anyhow" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" - [[package]] name = "autocfg" version = "1.3.0" @@ -491,6 +485,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "thiserror" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tokio" version = "1.37.0" @@ -524,11 +538,11 @@ name = "triba-packet" version = "0.1.0" dependencies = [ "aes-gcm-siv", - "anyhow", "interprocess", "rmp-serde", "serde", "strum", + "thiserror", "tokio", "uuid", "x25519-dalek", diff --git a/Cargo.toml b/Cargo.toml index cf02ca3..13ce54c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ version = "0.1.0" edition = "2021" [dependencies] -anyhow = "1.0" +thiserror = "1.0.60" tokio = { version = "1.37", features = [ "macros", "rt-multi-thread", diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..092d7cb --- /dev/null +++ b/src/error.rs @@ -0,0 +1,22 @@ +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum Error { + #[error("Failed to encrypt packet")] + EncryptionError, + + #[error("Failed to decrypt packet")] + DecryptionError, + + #[error("Failed to serialize packet: {0}")] + SerializationError(String), + + #[error("Failed to deserialize packet: {0}")] + DeserializationError(String), + + #[error("Failed to read data from the stream")] + StreamReadError, + + #[error("Failed to write data to the stream")] + StreamWriteError, +} diff --git a/src/lib.rs b/src/lib.rs index 4ba395f..c1c1f69 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,9 @@ +mod error; + +pub use error::Error; +use std::fmt::Formatter; + use aes_gcm_siv::{AeadInPlace, Aes256GcmSiv, Nonce}; -use anyhow::{anyhow, Result}; use serde::{Deserialize, Serialize}; use strum::Display; use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; @@ -19,63 +23,63 @@ impl IdPool { } } -#[derive(Debug, Copy, Clone, Serialize, Deserialize)] -pub struct Version(u32); - -impl Version { - /// Splits the version into its three parts: (major, minor, patch) - pub fn extract(self) -> (u8, u16, u8) { - let major = ((self.0 & 0xFF000000) >> 24) as u8; - let minor = ((self.0 & 0x00FFFF00) >> 8) as u16; - let patch = (self.0 & 0x000000FF) as u8; - - (major, minor, patch) - } -} - -#[repr(u8)] -#[derive(Debug, Clone, Serialize, Deserialize)] -pub enum Error { - Fatal(String), -} - #[repr(u32)] #[derive(Debug, Clone, Serialize, Deserialize, Display)] -pub enum Body { +pub enum Request { // Misc - Exit(Error) = 0x000_00000, + Close = 0x000_00000, // Handshake HandshakeUpgradeConnection = 0x001_00000, - HandshakeApiVersion(Version) = 0x001_00001, + HandshakeApiVersion(String) = 0x001_00001, HandshakeConfig = 0x001_00002, HandshakeSuccess = 0x001_00003, } +#[repr(u32)] +#[derive(Debug, Clone, Serialize, Deserialize, Display)] +pub enum Response { + // Standard success / neutral responses + Success = 0xFFE_00000, + Ackknowledged = 0xFFE_00001, + + // Standard error responses + RessourceTimeout = 0xFFF_00000, + PermissionDenied = 0xFFF_00001, +} + #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Packet { - id: u64, - body: Body, +pub enum Packet { + Request { id: u64, body: Request }, + Response { id: u64, req: u64, body: Response }, +} + +impl std::fmt::Display for Packet { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Self::Request { body, .. } => write!(f, "Request::{body}")?, + Self::Response { body, .. } => write!(f, "Response::{body}")?, + } + Ok(()) + } } impl Packet { - pub fn new(id_pool: &mut IdPool, body: Body) -> Self { - Self { - id: id_pool.acquire(), - body, - } + pub fn request(id: u64, body: Request) -> Self { + Self::Request { id, body } } - pub fn body(&self) -> &Body { - &self.body + pub fn response(id: u64, req: u64, body: Response) -> Self { + Self::Response { id, req, body } } // Serializes the packet to MessagePack and encrypts it. - pub fn pack(&self, cipher: &Aes256GcmSiv, nonce: &Nonce) -> Result> { - let mut data = rmp_serde::to_vec(self)?; + pub fn pack(&self, cipher: &Aes256GcmSiv, nonce: &Nonce) -> Result, Error> { + let mut data = + rmp_serde::to_vec(self).map_err(|e| Error::SerializationError(e.to_string()))?; cipher .encrypt_in_place(&nonce, b"", &mut data) - .map_err(|e| anyhow!("while packing packet: {e}"))?; + .map_err(|_| Error::EncryptionError)?; let mut vec = (data.len() as u32).to_le_bytes().to_vec(); vec.append(&mut data); @@ -84,22 +88,25 @@ impl Packet { } // Deserializes a packet from encrypted MessagePack. - pub fn unpack(data: &mut Vec, cipher: &Aes256GcmSiv, nonce: &Nonce) -> Result { + pub fn unpack(data: &mut Vec, cipher: &Aes256GcmSiv, nonce: &Nonce) -> Result { cipher .decrypt_in_place(&nonce, b"", data) - .map_err(|e| anyhow!("while unpacking packet: {e}"))?; - Ok(rmp_serde::from_slice::(data.as_slice())?) + .map_err(|_| Error::DecryptionError)?; + Ok(rmp_serde::from_slice::(data.as_slice()) + .map_err(|e| Error::DeserializationError(e.to_string()))?) } pub async fn recv( rx: &mut T, cipher: &Aes256GcmSiv, nonce: &Nonce, - ) -> Result { - let size = rx.read_u32_le().await? as usize; + ) -> Result { + let size = rx.read_u32_le().await.map_err(|_| Error::StreamReadError)? as usize; let mut buffer = vec![0u8; size]; - rx.read(&mut buffer).await?; + rx.read(&mut buffer) + .await + .map_err(|_| Error::StreamReadError)?; Packet::unpack(&mut buffer, &cipher, &nonce) } @@ -109,9 +116,11 @@ impl Packet { tx: &mut T, cipher: &Aes256GcmSiv, nonce: &Nonce, - ) -> Result<()> { + ) -> Result<(), Error> { let raw = self.pack(cipher, nonce)?; - tx.write(raw.as_slice()).await?; + tx.write(raw.as_slice()) + .await + .map_err(|_| Error::StreamWriteError)?; Ok(()) } }