feat: implemented responses

This commit is contained in:
antifallobst 2024-05-21 04:16:51 +02:00
parent 1c868ff972
commit e6fa8b694c
Signed by: antifallobst
GPG Key ID: 2B4F402172791BAF
4 changed files with 98 additions and 53 deletions

28
Cargo.lock generated
View File

@ -53,12 +53,6 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "anyhow"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3"
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.3.0" version = "1.3.0"
@ -491,6 +485,26 @@ dependencies = [
"unicode-ident", "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]] [[package]]
name = "tokio" name = "tokio"
version = "1.37.0" version = "1.37.0"
@ -524,11 +538,11 @@ name = "triba-packet"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"aes-gcm-siv", "aes-gcm-siv",
"anyhow",
"interprocess", "interprocess",
"rmp-serde", "rmp-serde",
"serde", "serde",
"strum", "strum",
"thiserror",
"tokio", "tokio",
"uuid", "uuid",
"x25519-dalek", "x25519-dalek",

View File

@ -23,7 +23,7 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
anyhow = "1.0" thiserror = "1.0.60"
tokio = { version = "1.37", features = [ tokio = { version = "1.37", features = [
"macros", "macros",
"rt-multi-thread", "rt-multi-thread",

22
src/error.rs Normal file
View File

@ -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,
}

View File

@ -1,5 +1,9 @@
mod error;
pub use error::Error;
use std::fmt::Formatter;
use aes_gcm_siv::{AeadInPlace, Aes256GcmSiv, Nonce}; use aes_gcm_siv::{AeadInPlace, Aes256GcmSiv, Nonce};
use anyhow::{anyhow, Result};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use strum::Display; use strum::Display;
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; 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)] #[repr(u32)]
#[derive(Debug, Clone, Serialize, Deserialize, Display)] #[derive(Debug, Clone, Serialize, Deserialize, Display)]
pub enum Body { pub enum Request {
// Misc // Misc
Exit(Error) = 0x000_00000, Close = 0x000_00000,
// Handshake // Handshake
HandshakeUpgradeConnection = 0x001_00000, HandshakeUpgradeConnection = 0x001_00000,
HandshakeApiVersion(Version) = 0x001_00001, HandshakeApiVersion(String) = 0x001_00001,
HandshakeConfig = 0x001_00002, HandshakeConfig = 0x001_00002,
HandshakeSuccess = 0x001_00003, 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)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Packet { pub enum Packet {
id: u64, Request { id: u64, body: Request },
body: Body, 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 { impl Packet {
pub fn new(id_pool: &mut IdPool, body: Body) -> Self { pub fn request(id: u64, body: Request) -> Self {
Self { Self::Request { id, body }
id: id_pool.acquire(),
body,
}
} }
pub fn body(&self) -> &Body { pub fn response(id: u64, req: u64, body: Response) -> Self {
&self.body Self::Response { id, req, body }
} }
// Serializes the packet to MessagePack and encrypts it. // Serializes the packet to MessagePack and encrypts it.
pub fn pack(&self, cipher: &Aes256GcmSiv, nonce: &Nonce) -> Result<Vec<u8>> { pub fn pack(&self, cipher: &Aes256GcmSiv, nonce: &Nonce) -> Result<Vec<u8>, Error> {
let mut data = rmp_serde::to_vec(self)?; let mut data =
rmp_serde::to_vec(self).map_err(|e| Error::SerializationError(e.to_string()))?;
cipher cipher
.encrypt_in_place(&nonce, b"", &mut data) .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(); let mut vec = (data.len() as u32).to_le_bytes().to_vec();
vec.append(&mut data); vec.append(&mut data);
@ -84,22 +88,25 @@ impl Packet {
} }
// Deserializes a packet from encrypted MessagePack. // Deserializes a packet from encrypted MessagePack.
pub fn unpack(data: &mut Vec<u8>, cipher: &Aes256GcmSiv, nonce: &Nonce) -> Result<Self> { pub fn unpack(data: &mut Vec<u8>, cipher: &Aes256GcmSiv, nonce: &Nonce) -> Result<Self, Error> {
cipher cipher
.decrypt_in_place(&nonce, b"", data) .decrypt_in_place(&nonce, b"", data)
.map_err(|e| anyhow!("while unpacking packet: {e}"))?; .map_err(|_| Error::DecryptionError)?;
Ok(rmp_serde::from_slice::<Packet>(data.as_slice())?) Ok(rmp_serde::from_slice::<Packet>(data.as_slice())
.map_err(|e| Error::DeserializationError(e.to_string()))?)
} }
pub async fn recv<T: AsyncRead + Unpin>( pub async fn recv<T: AsyncRead + Unpin>(
rx: &mut T, rx: &mut T,
cipher: &Aes256GcmSiv, cipher: &Aes256GcmSiv,
nonce: &Nonce, nonce: &Nonce,
) -> Result<Self> { ) -> Result<Self, Error> {
let size = rx.read_u32_le().await? as usize; let size = rx.read_u32_le().await.map_err(|_| Error::StreamReadError)? as usize;
let mut buffer = vec![0u8; size]; 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) Packet::unpack(&mut buffer, &cipher, &nonce)
} }
@ -109,9 +116,11 @@ impl Packet {
tx: &mut T, tx: &mut T,
cipher: &Aes256GcmSiv, cipher: &Aes256GcmSiv,
nonce: &Nonce, nonce: &Nonce,
) -> Result<()> { ) -> Result<(), Error> {
let raw = self.pack(cipher, nonce)?; let raw = self.pack(cipher, nonce)?;
tx.write(raw.as_slice()).await?; tx.write(raw.as_slice())
.await
.map_err(|_| Error::StreamWriteError)?;
Ok(()) Ok(())
} }
} }