use crate::{Buf, BufError, BufMut, BufResult, Codec, Cursor};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum TcpOption<'a> {
EndOfOptionList(EndOfOptionList),
NoOperation(NoOperation),
MaximumSegmentSize(MaximumSegmentSize),
WindowScale(WindowScale),
SackPermitted(SackPermitted),
Sack(Sack<'a>),
Timestamps(Timestamps),
Md5Signature(Md5Signature<'a>),
Experimental(Experimental<'a>),
}
impl<'a> Codec for TcpOption<'a> {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
match self {
TcpOption::EndOfOptionList(opt) => opt.encode(writer, ()),
TcpOption::NoOperation(opt) => opt.encode(writer, ()),
TcpOption::MaximumSegmentSize(opt) => opt.encode(writer, ()),
TcpOption::WindowScale(opt) => opt.encode(writer, ()),
TcpOption::SackPermitted(opt) => opt.encode(writer, ()),
TcpOption::Sack(opt) => opt.encode(writer, ()),
TcpOption::Timestamps(opt) => opt.encode(writer, ()),
TcpOption::Md5Signature(opt) => opt.encode(writer, ()),
TcpOption::Experimental(opt) => opt.encode(writer, ()),
}
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
let typ_peek = reader.peek_u8()?;
match typ_peek {
0 => Ok(Self::EndOfOptionList(EndOfOptionList::decode(reader, ())?)),
1 => Ok(Self::NoOperation(NoOperation::decode(reader, ())?)),
2 => Ok(Self::MaximumSegmentSize(MaximumSegmentSize::decode(
reader,
(),
)?)),
3 => Ok(Self::WindowScale(WindowScale::decode(reader, ())?)),
4 => Ok(Self::SackPermitted(SackPermitted::decode(reader, ())?)),
5 => Ok(Self::Sack(Sack::decode(reader, ())?)),
8 => Ok(Self::Timestamps(Timestamps::decode(reader, ())?)),
19 => Ok(Self::Md5Signature(Md5Signature::decode(reader, ())?)),
254 | 255 => Ok(Self::Experimental(Experimental::decode(reader, ())?)),
_ => Err(BufError::UnexpectedValue),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(u8)]
pub enum Type {
EndOfOptionList = 0,
NoOperation = 1,
MaximumSegmentSize = 2,
WindowScale = 3,
SackPermitted = 4,
Sack = 5,
Timestamps = 8,
Md5Signature = 19,
Experimental254 = 254,
Experimental255 = 255,
}
impl Codec for Type {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
(*self as u8).encode(writer, ())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
match u8::decode(reader, ())? {
x if x == Self::EndOfOptionList as u8 => Ok(Self::EndOfOptionList),
x if x == Self::NoOperation as u8 => Ok(Self::NoOperation),
x if x == Self::MaximumSegmentSize as u8 => Ok(Self::MaximumSegmentSize),
x if x == Self::WindowScale as u8 => Ok(Self::WindowScale),
x if x == Self::SackPermitted as u8 => Ok(Self::SackPermitted),
x if x == Self::Sack as u8 => Ok(Self::Sack),
x if x == Self::Timestamps as u8 => Ok(Self::Timestamps),
x if x == Self::Md5Signature as u8 => Ok(Self::Md5Signature),
x if x == Self::Experimental254 as u8 => Ok(Self::Experimental254),
x if x == Self::Experimental255 as u8 => Ok(Self::Experimental255),
_ => Err(BufError::UnexpectedValue),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct EndOfOptionList;
impl EndOfOptionList {
pub const TYPE: Type = Type::EndOfOptionList;
}
impl Codec for EndOfOptionList {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
if Type::decode(reader, ())? != Self::TYPE {
return Err(BufError::UnexpectedValue);
}
Ok(Self)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct NoOperation;
impl NoOperation {
pub const TYPE: Type = Type::NoOperation;
}
impl Codec for NoOperation {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
if Type::decode(reader, ())? != Self::TYPE {
return Err(BufError::UnexpectedValue);
}
Ok(Self)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MaximumSegmentSize {
pub mss: u16,
}
impl MaximumSegmentSize {
pub const TYPE: Type = Type::MaximumSegmentSize;
}
impl Codec for MaximumSegmentSize {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())?;
4u8.encode(writer, ())?; self.mss.encode(writer, ())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
if Type::decode(reader, ())? != Self::TYPE {
return Err(BufError::UnexpectedValue);
}
let _length = u8::decode(reader, ())?;
Ok(Self {
mss: u16::decode(reader, ())?,
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct WindowScale {
pub shift_count: u8,
}
impl WindowScale {
pub const TYPE: Type = Type::WindowScale;
}
impl Codec for WindowScale {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())?;
3u8.encode(writer, ())?; self.shift_count.encode(writer, ())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
if Type::decode(reader, ())? != Self::TYPE {
return Err(BufError::UnexpectedValue);
}
let _length = u8::decode(reader, ())?;
Ok(Self {
shift_count: u8::decode(reader, ())?,
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SackPermitted;
impl SackPermitted {
pub const TYPE: Type = Type::SackPermitted;
}
impl Codec for SackPermitted {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())?;
2u8.encode(writer, ()) }
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
if Type::decode(reader, ())? != Self::TYPE {
return Err(BufError::UnexpectedValue);
}
let _length = u8::decode(reader, ())?;
Ok(Self)
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Sack<'a> {
pub blocks: &'a [u8],
}
impl<'a> Sack<'a> {
pub const TYPE: Type = Type::Sack;
}
impl<'a> Codec for Sack<'a> {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())?;
todo!("Encode variable length slice: self.blocks");
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
if Type::decode(reader, ())? != Self::TYPE {
return Err(BufError::UnexpectedValue);
}
let length = u8::decode(reader, ())?;
let _data_len = length.saturating_sub(2);
todo!("Decode variable length slice of length: _data_len");
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Timestamps {
pub tsval: u32,
pub tsecr: u32,
}
impl Timestamps {
pub const TYPE: Type = Type::Timestamps;
}
impl Codec for Timestamps {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())?;
10u8.encode(writer, ())?; self.tsval.encode(writer, ())?;
self.tsecr.encode(writer, ())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
if Type::decode(reader, ())? != Self::TYPE {
return Err(BufError::UnexpectedValue);
}
let _length = u8::decode(reader, ())?;
Ok(Self {
tsval: u32::decode(reader, ())?,
tsecr: u32::decode(reader, ())?,
})
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Md5Signature<'a> {
pub digest: &'a [u8],
}
impl<'a> Md5Signature<'a> {
pub const TYPE: Type = Type::Md5Signature;
}
impl<'a> Codec for Md5Signature<'a> {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())?;
todo!("Encode variable length slice: self.digest");
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
if Type::decode(reader, ())? != Self::TYPE {
return Err(BufError::UnexpectedValue);
}
let length = u8::decode(reader, ())?;
let _data_len = length.saturating_sub(2);
todo!("Decode variable length slice of length: _data_len");
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Experimental<'a> {
pub exp_kind: u16,
pub data: &'a [u8],
}
impl<'a> Experimental<'a> {
pub const TYPE: Type = Type::Experimental254;
}
impl<'a> Codec for Experimental<'a> {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())?;
self.exp_kind.encode(writer, ())?;
todo!("Encode variable length slice: self.data");
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
let kind = Type::decode(reader, ())?;
if kind != Type::Experimental254 && kind != Type::Experimental255 {
return Err(BufError::UnexpectedValue);
}
let length = u8::decode(reader, ())?;
let _data_len = (length as usize).saturating_sub(4);
todo!("Decode variable length slice of length: _data_len");
}
}