clean up packet errors
This commit is contained in:
parent
eb5e5fd0fa
commit
76502f5e00
@ -71,6 +71,7 @@ async fn authenticate(
|
||||
let _ip = dyn_ip_update(&config.dyn_ip_server, number, pin, port).await?;
|
||||
}
|
||||
|
||||
// TODO: do we want to cache this? If so, for how long?
|
||||
#[cfg(feature = "debug_server")]
|
||||
let name = peer_query(&config.dyn_ip_server, number).await?;
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
use std::fmt::Debug;
|
||||
use std::fmt::{Debug, Display};
|
||||
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use eyre::eyre;
|
||||
use serde::Serialize;
|
||||
use smallvec::SmallVec;
|
||||
use tokio::{
|
||||
@ -12,6 +11,47 @@ use tokio::{
|
||||
pub const REJECT_OOP: &[u8; 6] = b"\x04\x04oop\x00";
|
||||
pub const REJECT_TIMEOUT: &[u8; 10] = b"\x04\x08timeout\x00";
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
TooLittleData {
|
||||
expected: u8,
|
||||
got: u8,
|
||||
},
|
||||
Unexpected {
|
||||
expected: PacketKind,
|
||||
got: PacketKind,
|
||||
},
|
||||
Io(std::io::Error),
|
||||
Client(Option<String>),
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {}
|
||||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Error::TooLittleData { expected, got } => write!(
|
||||
f,
|
||||
"received too little data: expected {expected} bytes but received only {got}"
|
||||
),
|
||||
Error::Unexpected { expected, got } => write!(
|
||||
f,
|
||||
"received an unexpected packet: expected {expected:?} but received {got:?}",
|
||||
),
|
||||
Error::Io(inner) => Display::fmt(inner, f),
|
||||
Error::Client(Some(inner)) => write!(f, "client reported an error: {inner}"),
|
||||
Error::Client(None) => write!(f, "client reported a malformed error",),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for Error {
|
||||
fn from(value: std::io::Error) -> Self {
|
||||
Self::Io(value)
|
||||
}
|
||||
}
|
||||
|
||||
type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum PacketKind {
|
||||
@ -151,10 +191,7 @@ impl Packet {
|
||||
}
|
||||
|
||||
#[allow(clippy::missing_errors_doc)]
|
||||
pub async fn recv_into_cancelation_safe(
|
||||
&mut self,
|
||||
stream: &mut ReadHalf<'_>,
|
||||
) -> eyre::Result<()> {
|
||||
pub async fn recv_into_cancelation_safe(&mut self, stream: &mut ReadHalf<'_>) -> Result<()> {
|
||||
// Makes sure all data is available before reading
|
||||
let header_bytes = bytemuck::bytes_of_mut(&mut self.header);
|
||||
stream.peek(header_bytes).await?;
|
||||
@ -166,7 +203,7 @@ impl Packet {
|
||||
}
|
||||
|
||||
#[allow(clippy::missing_errors_doc)]
|
||||
pub async fn recv_into(&mut self, stream: &mut ReadHalf<'_>) -> eyre::Result<()> {
|
||||
pub async fn recv_into(&mut self, stream: &mut ReadHalf<'_>) -> Result<()> {
|
||||
let header_bytes = bytemuck::bytes_of_mut(&mut self.header);
|
||||
|
||||
stream.read_exact(header_bytes).await?;
|
||||
@ -176,10 +213,7 @@ impl Packet {
|
||||
stream.read_exact(&mut self.data).await?;
|
||||
|
||||
if self.header.kind == PacketKind::Error.raw() {
|
||||
return Err(eyre!(
|
||||
"client reported error: {:?}",
|
||||
self.as_string().unwrap_or("unknown dyn auth error")
|
||||
));
|
||||
return Err(Error::Client(self.as_string().map(ToOwned::to_owned)));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -199,24 +233,26 @@ impl Packet {
|
||||
|
||||
/// # Errors
|
||||
/// the packet must be a `RemConnect` packet and must contain at least 6 bytes of data
|
||||
pub fn as_rem_connect(&self) -> eyre::Result<RemConnect> {
|
||||
#[allow(clippy::missing_panics_doc)]
|
||||
pub fn as_rem_connect(&self) -> Result<RemConnect> {
|
||||
if self.kind() != PacketKind::RemConnect {
|
||||
return Err(eyre!(
|
||||
"Unexpected Packet: {:?} expected RemConnect",
|
||||
self.kind()
|
||||
));
|
||||
return Err(Error::Unexpected {
|
||||
expected: PacketKind::RemConnect,
|
||||
got: self.kind(),
|
||||
});
|
||||
}
|
||||
|
||||
if self.data.len() < 6 {
|
||||
return Err(eyre!(
|
||||
"Too little data for RemConnect. Need at least 6 Bytes got {}",
|
||||
self.data.len()
|
||||
));
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
return Err(Error::TooLittleData {
|
||||
expected: 6,
|
||||
got: self.data.len() as u8,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(RemConnect {
|
||||
number: u32::from_le_bytes(self.data[..4].try_into()?),
|
||||
pin: u16::from_le_bytes(self.data[4..6].try_into()?),
|
||||
number: u32::from_le_bytes(self.data[..4].try_into().unwrap()),
|
||||
pin: u16::from_le_bytes(self.data[4..6].try_into().unwrap()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user