use std::fmt::Debug;
use bytes::{BufMut, BytesMut, buf::UninitSlice};
use derive_more::{Deref, DerefMut};
use enum_dispatch::enum_dispatch;
use getset::CopyGetters;
use header::{LongHeader, io::WriteHeader};
use crate::{
cid::ConnectionId,
frame::{ContainSpec, FrameFeature, FrameType, Spec},
packet::keys::DirectionalKeys,
};
pub mod error;
pub mod signal;
#[doc(hidden)]
pub use signal::{KeyPhaseBit, SpinBit};
pub mod r#type;
#[doc(hidden)]
pub use r#type::{
GetPacketNumberLength, LONG_RESERVED_MASK, LongSpecificBits, SHORT_RESERVED_MASK,
ShortSpecificBits, Type,
};
pub mod header;
#[doc(hidden)]
pub use header::{
EncodeHeader, GetDcid, GetScid, GetType, HandshakeHeader, Header, InitialHeader,
LongHeaderBuilder, OneRttHeader, RetryHeader, VersionNegotiationHeader, ZeroRttHeader, long,
};
pub mod io;
pub use io::{
AssemblePacket, Package, PacketProperties, PacketSpace, PacketWriter, ProductHeader,
RecordFrame,
};
pub mod number;
#[doc(hidden)]
pub use number::{InvalidPacketNumber, PacketNumber, WritePacketNumber, take_pn_len};
pub mod decrypt;
pub mod encrypt;
pub mod keys;
#[derive(Debug, Clone)]
#[enum_dispatch(GetDcid, GetType)]
pub enum DataHeader {
Long(long::DataHeader),
Short(OneRttHeader),
}
#[derive(Debug, Clone, Deref, DerefMut)]
pub struct DataPacket {
#[deref]
#[deref_mut]
pub header: DataHeader,
pub bytes: BytesMut,
pub offset: usize,
}
impl GetType for DataPacket {
fn get_type(&self) -> Type {
self.header.get_type()
}
}
#[derive(Default, Debug, Clone, Copy, PartialEq)]
pub enum PacketContains {
#[default]
NonAckEliciting,
JustPing,
EffectivePayload,
}
impl PacketContains {
pub fn include(self, frame_type: FrameType) -> Self {
match frame_type {
FrameType::Ping if self != PacketContains::EffectivePayload => Self::JustPing,
fty if !fty.specs().contain(Spec::NonAckEliciting) => Self::EffectivePayload,
_ => self,
}
}
pub fn ack_eliciting(self) -> bool {
self != Self::NonAckEliciting
}
}
#[derive(Debug, Clone)]
pub enum Packet {
VN(VersionNegotiationHeader),
Retry(RetryHeader),
Data(DataPacket),
}
#[derive(Debug)]
pub struct PacketReader {
raw_bytes: BytesMut,
dcid_len: usize,
}
impl PacketReader {
pub fn new(raw_bytes: BytesMut, dcid_len: usize) -> Self {
Self {
raw_bytes,
dcid_len,
}
}
}
impl Iterator for PacketReader {
type Item = Result<Packet, error::Error>;
fn next(&mut self) -> Option<Self::Item> {
if self.raw_bytes.is_empty() {
return None;
}
match io::be_packet(&mut self.raw_bytes, self.dcid_len) {
Ok(packet) => Some(Ok(packet)),
Err(error) => {
tracing::debug!(target: "quic", ?error, "Dropped unparsed packet");
self.raw_bytes.clear(); Some(Err(error))
}
}
}
}