1use std::{fmt, net::SocketAddr};
2
3use bytes::{Buf, BufMut, BytesMut};
4
5use crate::{Instant, MAX_CID_SIZE, ResetToken, coding::BufExt, packet::PartialDecode};
6
7#[derive(Debug)]
9pub struct ConnectionEvent(pub(crate) ConnectionEventInner);
10
11#[derive(Debug)]
12pub(crate) enum ConnectionEventInner {
13 Datagram(DatagramConnectionEvent),
15 NewIdentifiers(Vec<IssuedCid>, Instant),
17}
18
19#[derive(Debug)]
21pub(crate) struct DatagramConnectionEvent {
22 pub(crate) now: Instant,
23 pub(crate) remote: SocketAddr,
24 pub(crate) ecn: Option<EcnCodepoint>,
25 pub(crate) first_decode: PartialDecode,
26 pub(crate) remaining: Option<BytesMut>,
27}
28
29#[derive(Debug)]
31pub struct EndpointEvent(pub(crate) EndpointEventInner);
32
33impl EndpointEvent {
34 pub fn drained() -> Self {
39 Self(EndpointEventInner::Drained)
40 }
41
42 pub fn is_drained(&self) -> bool {
46 self.0 == EndpointEventInner::Drained
47 }
48}
49
50#[derive(Clone, Debug, Eq, PartialEq)]
51
52pub(crate) enum EndpointEventInner {
53 Drained,
55 ResetToken(SocketAddr, ResetToken),
57 NeedIdentifiers(Instant, u64),
59 RetireConnectionId(Instant, u64, bool),
62 RelayPunchMeNow([u8; 32], crate::frame::PunchMeNow),
64 SendAddressFrame(crate::frame::AddAddress),
66 NatCandidateValidated { address: SocketAddr, challenge: u64 },
68}
69
70#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
74pub struct ConnectionId {
75 len: u8,
77 bytes: [u8; MAX_CID_SIZE],
79}
80
81impl ConnectionId {
82 pub fn new(bytes: &[u8]) -> Self {
84 debug_assert!(bytes.len() <= MAX_CID_SIZE);
85 let mut res = Self {
86 len: bytes.len() as u8,
87 bytes: [0; MAX_CID_SIZE],
88 };
89 res.bytes[..bytes.len()].copy_from_slice(bytes);
90 res
91 }
92
93 pub fn from_buf(buf: &mut (impl Buf + ?Sized), len: usize) -> Self {
97 debug_assert!(len <= MAX_CID_SIZE);
98 let mut res = Self {
99 len: len as u8,
100 bytes: [0; MAX_CID_SIZE],
101 };
102 buf.copy_to_slice(&mut res[..len]);
103 res
104 }
105
106 pub(crate) fn decode_long(buf: &mut impl Buf) -> Option<Self> {
108 let len = buf.get::<u8>().ok()? as usize;
109 match len > MAX_CID_SIZE || buf.remaining() < len {
110 false => Some(Self::from_buf(buf, len)),
111 true => None,
112 }
113 }
114
115 pub(crate) fn encode_long(&self, buf: &mut impl BufMut) {
117 buf.put_u8(self.len() as u8);
118 buf.put_slice(self);
119 }
120}
121
122impl ::std::ops::Deref for ConnectionId {
123 type Target = [u8];
124 fn deref(&self) -> &[u8] {
125 &self.bytes[0..self.len as usize]
126 }
127}
128
129impl ::std::ops::DerefMut for ConnectionId {
130 fn deref_mut(&mut self) -> &mut [u8] {
131 &mut self.bytes[0..self.len as usize]
132 }
133}
134
135impl fmt::Debug for ConnectionId {
136 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
137 self.bytes[0..self.len as usize].fmt(f)
138 }
139}
140
141impl fmt::Display for ConnectionId {
142 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143 for byte in self.iter() {
144 write!(f, "{byte:02x}")?;
145 }
146 Ok(())
147 }
148}
149
150#[repr(u8)]
152#[derive(Debug, Copy, Clone, Eq, PartialEq)]
153pub enum EcnCodepoint {
154 Ect0 = 0b10,
156 Ect1 = 0b01,
158 Ce = 0b11,
160}
161
162impl EcnCodepoint {
163 pub fn from_bits(x: u8) -> Option<Self> {
165 use EcnCodepoint::*;
166 Some(match x & 0b11 {
167 0b10 => Ect0,
168 0b01 => Ect1,
169 0b11 => Ce,
170 _ => {
171 return None;
172 }
173 })
174 }
175
176 pub fn is_ce(self) -> bool {
178 matches!(self, Self::Ce)
179 }
180}
181
182#[derive(Debug, Copy, Clone)]
183pub(crate) struct IssuedCid {
184 pub(crate) sequence: u64,
185 pub(crate) id: ConnectionId,
186 pub(crate) reset_token: ResetToken,
187}