1use std::{fmt, net::SocketAddr};
9
10use bytes::{Buf, BufMut, BytesMut};
11
12use crate::{Instant, MAX_CID_SIZE, ResetToken, coding::BufExt, packet::PartialDecode};
13
14#[derive(Debug)]
16pub struct ConnectionEvent(pub(crate) ConnectionEventInner);
17
18#[derive(Debug)]
19pub(crate) enum ConnectionEventInner {
20 Datagram(DatagramConnectionEvent),
22 NewIdentifiers(Vec<IssuedCid>, Instant),
24 QueueAddAddress(crate::frame::AddAddress),
26 QueuePunchMeNow(crate::frame::PunchMeNow),
28}
29
30#[derive(Debug)]
32pub(crate) struct DatagramConnectionEvent {
33 pub(crate) now: Instant,
34 pub(crate) remote: SocketAddr,
35 pub(crate) ecn: Option<EcnCodepoint>,
36 pub(crate) first_decode: PartialDecode,
37 pub(crate) remaining: Option<BytesMut>,
38}
39
40#[derive(Debug)]
42pub struct EndpointEvent(pub(crate) EndpointEventInner);
43
44impl EndpointEvent {
45 pub fn drained() -> Self {
50 Self(EndpointEventInner::Drained)
51 }
52
53 pub fn is_drained(&self) -> bool {
57 self.0 == EndpointEventInner::Drained
58 }
59}
60
61#[derive(Clone, Debug, Eq, PartialEq)]
62
63pub(crate) enum EndpointEventInner {
64 Drained,
66 ResetToken(SocketAddr, ResetToken),
68 NeedIdentifiers(Instant, u64),
70 RetireConnectionId(Instant, u64, bool),
73 RelayPunchMeNow([u8; 32], crate::frame::PunchMeNow),
75 #[allow(dead_code)]
77 SendAddressFrame(crate::frame::AddAddress),
78 #[allow(dead_code)]
80 NatCandidateValidated { address: SocketAddr, challenge: u64 },
81 TryConnectTo {
83 request_id: crate::VarInt,
84 target_address: SocketAddr,
85 timeout_ms: u16,
86 requester_connection: SocketAddr,
87 requested_at: crate::Instant,
88 },
89}
90
91#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
95pub struct ConnectionId {
96 len: u8,
98 bytes: [u8; MAX_CID_SIZE],
100}
101
102impl ConnectionId {
103 pub fn new(bytes: &[u8]) -> Self {
105 debug_assert!(bytes.len() <= MAX_CID_SIZE);
106 let mut res = Self {
107 len: bytes.len() as u8,
108 bytes: [0; MAX_CID_SIZE],
109 };
110 res.bytes[..bytes.len()].copy_from_slice(bytes);
111 res
112 }
113
114 pub fn from_buf(buf: &mut (impl Buf + ?Sized), len: usize) -> Self {
118 debug_assert!(len <= MAX_CID_SIZE);
119 let mut res = Self {
120 len: len as u8,
121 bytes: [0; MAX_CID_SIZE],
122 };
123 buf.copy_to_slice(&mut res[..len]);
124 res
125 }
126
127 pub(crate) fn decode_long(buf: &mut impl Buf) -> Option<Self> {
129 let len = buf.get::<u8>().ok()? as usize;
130 match len > MAX_CID_SIZE || buf.remaining() < len {
131 false => Some(Self::from_buf(buf, len)),
132 true => None,
133 }
134 }
135
136 pub(crate) fn encode_long(&self, buf: &mut impl BufMut) {
138 buf.put_u8(self.len() as u8);
139 buf.put_slice(self);
140 }
141}
142
143impl ::std::ops::Deref for ConnectionId {
144 type Target = [u8];
145 fn deref(&self) -> &[u8] {
146 &self.bytes[0..self.len as usize]
147 }
148}
149
150impl ::std::ops::DerefMut for ConnectionId {
151 fn deref_mut(&mut self) -> &mut [u8] {
152 &mut self.bytes[0..self.len as usize]
153 }
154}
155
156impl fmt::Debug for ConnectionId {
157 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158 self.bytes[0..self.len as usize].fmt(f)
159 }
160}
161
162impl fmt::Display for ConnectionId {
163 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
164 for byte in self.iter() {
165 write!(f, "{byte:02x}")?;
166 }
167 Ok(())
168 }
169}
170
171#[repr(u8)]
173#[derive(Debug, Copy, Clone, Eq, PartialEq)]
174pub enum EcnCodepoint {
175 Ect0 = 0b10,
177 Ect1 = 0b01,
179 Ce = 0b11,
181}
182
183impl EcnCodepoint {
184 pub fn from_bits(x: u8) -> Option<Self> {
186 use EcnCodepoint::*;
187 Some(match x & 0b11 {
188 0b10 => Ect0,
189 0b01 => Ect1,
190 0b11 => Ce,
191 _ => {
192 return None;
193 }
194 })
195 }
196
197 pub fn is_ce(self) -> bool {
199 matches!(self, Self::Ce)
200 }
201}
202
203#[derive(Debug, Copy, Clone)]
204pub(crate) struct IssuedCid {
205 pub(crate) sequence: u64,
206 pub(crate) id: ConnectionId,
207 pub(crate) reset_token: ResetToken,
208}