use std::{fmt, net::SocketAddr, time::Instant};
use bytes::{Buf, BufMut, BytesMut};
use crate::{coding::BufExt, packet::PartialDecode, ResetToken, MAX_CID_SIZE};
#[derive(Debug)]
pub struct ConnectionEvent(pub(crate) ConnectionEventInner);
#[derive(Debug)]
pub(crate) enum ConnectionEventInner {
Datagram(DatagramConnectionEvent),
NewIdentifiers(Vec<IssuedCid>, Instant),
}
#[derive(Debug)]
pub(crate) struct DatagramConnectionEvent {
pub(crate) now: Instant,
pub(crate) remote: SocketAddr,
pub(crate) ecn: Option<EcnCodepoint>,
pub(crate) first_decode: PartialDecode,
pub(crate) remaining: Option<BytesMut>,
}
#[derive(Debug)]
pub struct EndpointEvent(pub(crate) EndpointEventInner);
impl EndpointEvent {
pub fn drained() -> Self {
Self(EndpointEventInner::Drained)
}
pub fn is_drained(&self) -> bool {
self.0 == EndpointEventInner::Drained
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) enum EndpointEventInner {
Drained,
ResetToken(SocketAddr, ResetToken),
NeedIdentifiers(Instant, u64),
RetireConnectionId(Instant, u64, bool),
}
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ConnectionId {
len: u8,
bytes: [u8; MAX_CID_SIZE],
}
impl ConnectionId {
pub fn new(bytes: &[u8]) -> Self {
debug_assert!(bytes.len() <= MAX_CID_SIZE);
let mut res = Self {
len: bytes.len() as u8,
bytes: [0; MAX_CID_SIZE],
};
res.bytes[..bytes.len()].copy_from_slice(bytes);
res
}
pub fn from_buf(buf: &mut (impl Buf + ?Sized), len: usize) -> Self {
debug_assert!(len <= MAX_CID_SIZE);
let mut res = Self {
len: len as u8,
bytes: [0; MAX_CID_SIZE],
};
buf.copy_to_slice(&mut res[..len]);
res
}
pub(crate) fn decode_long(buf: &mut impl Buf) -> Option<Self> {
let len = buf.get::<u8>().ok()? as usize;
match len > MAX_CID_SIZE || buf.remaining() < len {
false => Some(Self::from_buf(buf, len)),
true => None,
}
}
pub(crate) fn encode_long(&self, buf: &mut impl BufMut) {
buf.put_u8(self.len() as u8);
buf.put_slice(self);
}
}
impl ::std::ops::Deref for ConnectionId {
type Target = [u8];
fn deref(&self) -> &[u8] {
&self.bytes[0..self.len as usize]
}
}
impl ::std::ops::DerefMut for ConnectionId {
fn deref_mut(&mut self) -> &mut [u8] {
&mut self.bytes[0..self.len as usize]
}
}
impl fmt::Debug for ConnectionId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.bytes[0..self.len as usize].fmt(f)
}
}
impl fmt::Display for ConnectionId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for byte in self.iter() {
write!(f, "{byte:02x}")?;
}
Ok(())
}
}
#[repr(u8)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum EcnCodepoint {
#[doc(hidden)]
Ect0 = 0b10,
#[doc(hidden)]
Ect1 = 0b01,
#[doc(hidden)]
Ce = 0b11,
}
impl EcnCodepoint {
pub fn from_bits(x: u8) -> Option<Self> {
use self::EcnCodepoint::*;
Some(match x & 0b11 {
0b10 => Ect0,
0b01 => Ect1,
0b11 => Ce,
_ => {
return None;
}
})
}
pub fn is_ce(self) -> bool {
matches!(self, Self::Ce)
}
}
#[derive(Debug, Copy, Clone)]
pub(crate) struct IssuedCid {
pub(crate) sequence: u64,
pub(crate) id: ConnectionId,
pub(crate) reset_token: ResetToken,
}