Skip to content

Commit

Permalink
Bring back header::decode
Browse files Browse the repository at this point in the history
  • Loading branch information
thomaseizinger committed Oct 6, 2023
1 parent 166f8ff commit 5c6b172
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 45 deletions.
33 changes: 11 additions & 22 deletions yamux/src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,6 @@ impl<T> Frame<T> {
}
}

pub fn try_from_header_buffer(buffer: [u8; HEADER_SIZE]) -> Result<Self, FrameDecodeError> {
let frame = Self {
buffer: buffer.to_vec(),
_marker: PhantomData,
};
let header = frame.header();
header.validate()?;

Ok(frame)
}

pub fn header(&self) -> &Header<T> {
Ref::<_, Header<T>>::new_from_prefix(self.buffer.as_slice())
.expect("buffer always holds a valid header")
Expand Down Expand Up @@ -122,12 +111,17 @@ impl<A: header::private::Sealed> From<Frame<A>> for Frame<()> {
}

impl Frame<()> {
pub(crate) fn try_into_data(self) -> Result<Frame<Data>, Self> {
if self.header().is_data() {
Ok(self.into_data())
} else {
Err(self)
}
pub(crate) fn try_from_header_buffer(
buffer: [u8; HEADER_SIZE],
) -> Result<Either<Frame<()>, Frame<Data>>, FrameDecodeError> {
let header = header::decode(&buffer)?;

let either = match header.try_into_data() {
Ok(data) => Either::Right(Frame::new(data)),
Err(other) => Either::Left(Frame::no_body(other)),
};

Ok(either)
}

pub(crate) fn into_data(self) -> Frame<Data> {
Expand Down Expand Up @@ -186,11 +180,6 @@ impl Frame<Data> {

Frame::new(header)
}

fn ensure_buffer_len(&mut self) {
self.buffer
.resize(HEADER_SIZE + self.header().len().val() as usize, 0);
}
}

impl Frame<WindowUpdate> {
Expand Down
42 changes: 24 additions & 18 deletions yamux/src/frame/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,6 @@ impl<T> Header<T> {
pub(crate) fn is_data(&self) -> bool {
self.tag == Tag::Data as u8
}

/// Validate a [`Header`] value.
pub fn validate(&self) -> Result<(), HeaderDecodeError> {
if self.version.0 != 0 {
return Err(HeaderDecodeError::Version(self.version.0));
}

if !(0..4).contains(&self.tag) {
return Err(HeaderDecodeError::Type(self.tag));
}

Ok(())
}
}

impl<A: private::Sealed> From<Header<A>> for Header<()> {
Expand All @@ -122,6 +109,14 @@ impl Header<()> {
debug_assert!(self.is_data());
self.cast()
}

pub(crate) fn try_into_data(self) -> Result<Header<Data>, Self> {
if self.tag == Tag::Data as u8 {
return Ok(self.into_data());
}

Err(self)
}
}

impl<T: HasSyn> Header<T> {
Expand Down Expand Up @@ -383,6 +378,22 @@ pub const RST: Flags = Flags(U16::from_bytes([0, 8]));
/// The serialised header size in bytes.
pub const HEADER_SIZE: usize = 12;

// Decode a [`Header`] value.
pub fn decode(buf: &[u8; HEADER_SIZE]) -> Result<Header<()>, HeaderDecodeError> {
if buf[0] != 0 {
return Err(HeaderDecodeError::Version(buf[0]));
}

let tag = buf[1];
if !(0..4).contains(&tag) {
return Err(HeaderDecodeError::Type(tag));
}

let hdr = Header::read_from(buf).expect("buffer to be correct size");

Ok(hdr)
}

/// Possible errors while decoding a message frame header.
#[non_exhaustive]
#[derive(Debug)]
Expand Down Expand Up @@ -426,11 +437,6 @@ mod tests {
}
}

fn decode(buf: &[u8; HEADER_SIZE]) -> Result<Header<()>, HeaderDecodeError> {
let hdr = Header::read_from(buf).expect("buffer to be correct size");
hdr.validate().map(|_| hdr)
}

/// Encode a [`Header`] value.
fn encode<T>(hdr: &Header<T>) -> [u8; HEADER_SIZE] {
let mut buf = [0; HEADER_SIZE];
Expand Down
9 changes: 4 additions & 5 deletions yamux/src/frame/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use super::{
};
use crate::connection::Id;
use crate::frame::header::Data;
use futures::future::Either;
use futures::{prelude::*, ready};
use std::{
fmt, io, mem,
Expand Down Expand Up @@ -139,9 +140,9 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Stream for Io<T> {

log::trace!("{}: read: {:?}", this.id, frame);

let mut frame = match frame.try_into_data() {
Ok(data_frame) => data_frame,
Err(other_frame) => {
let frame = match frame {
Either::Right(data_frame) => data_frame,
Either::Left(other_frame) => {
this.read_state = ReadState::header();
return Poll::Ready(Some(Ok(other_frame)));
}
Expand All @@ -155,8 +156,6 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Stream for Io<T> {
))));
}

frame.ensure_buffer_len();

this.read_state = ReadState::Body { frame, offset: 0 };
continue;
}
Expand Down

0 comments on commit 5c6b172

Please sign in to comment.