internet 0.0.3

Network library for rust
Documentation
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),
        }
    }
}

/// [RFC 9293]: https://datatracker.ietf.org/doc/html/rfc9293#section-3.1
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(u8)]
pub enum Type {
    /// End of Option List (EOOL). RFC 9293.
    EndOfOptionList = 0,
    /// No-Operation (NOP). RFC 9293.
    NoOperation = 1,
    /// Maximum Segment Size (MSS). RFC 9293.
    MaximumSegmentSize = 2,
    /// Window Scale (WS). RFC 9293, RFC 7323.
    WindowScale = 3,
    /// SACK Permitted. RFC 9293, RFC 2018.
    SackPermitted = 4,
    /// Selective Acknowledgment (SACK). RFC 9293, RFC 2018.
    Sack = 5,
    /// Timestamps (TS). RFC 9293, RFC 7323.
    Timestamps = 8,
    /// MD5 Signature Option. RFC 2385.
    Md5Signature = 19,
    /// Experimental Option (RFC 6994).
    Experimental254 = 254,
    /// Experimental Option (RFC 6994).
    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),
        }
    }
}

/// End of Option List (EOOL)
///
/// Defined in [RFC 9293, Section 3.1].
#[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)
    }
}

/// No-Operation (NOP)
///
/// Defined in [RFC 9293, Section 3.1].
#[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)
    }
}

/// Maximum Segment Size (MSS)
///
/// Defined in [RFC 9293, Section 3.1].
#[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, ())?; // length
        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, ())?,
        })
    }
}

/// Window Scale (WS)
///
/// Defined in [RFC 9293, Section 3.1] and [RFC 7323].
#[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, ())?; // length
        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, ())?,
        })
    }
}

/// SACK Permitted
///
/// Defined in [RFC 9293, Section 3.1] and [RFC 2018].
#[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, ()) // length
    }

    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)
    }
}

/// Selective Acknowledgment (SACK)
///
/// Defined in [RFC 9293, Section 3.1] and [RFC 2018].
#[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, ())?;
        // (self.encoded_len() as u8).encode(writer, ())?; // length

        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");
    }
}

/// Timestamps (TS)
///
/// Defined in [RFC 9293, Section 3.1] and [RFC 7323].
#[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, ())?; // length
        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, ())?,
        })
    }
}

/// MD5 Signature Option
///
/// Defined in [RFC 2385].
#[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, ())?;
        // (self.encoded_len() as u8).encode(writer, ())?; // length

        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");
    }
}

/// Experimental Option
///
/// Defined in [RFC 6994].
#[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.encoded_len() as u8).encode(writer, ())?; // length
        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 exp_kind = u16::decode(reader, ())?;
        let _data_len = (length as usize).saturating_sub(4);

        todo!("Decode variable length slice of length: _data_len");
    }
}