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 QueueAddAddress(crate::frame::AddAddress),
19 QueuePunchMeNow(crate::frame::PunchMeNow),
21}
22
23#[derive(Debug)]
25pub(crate) struct DatagramConnectionEvent {
26 pub(crate) now: Instant,
27 pub(crate) remote: SocketAddr,
28 pub(crate) ecn: Option<EcnCodepoint>,
29 pub(crate) first_decode: PartialDecode,
30 pub(crate) remaining: Option<BytesMut>,
31}
32
33#[derive(Debug)]
35pub struct EndpointEvent(pub(crate) EndpointEventInner);
36
37impl EndpointEvent {
38 pub fn drained() -> Self {
43 Self(EndpointEventInner::Drained)
44 }
45
46 pub fn is_drained(&self) -> bool {
50 self.0 == EndpointEventInner::Drained
51 }
52}
53
54#[derive(Clone, Debug, Eq, PartialEq)]
55
56pub(crate) enum EndpointEventInner {
57 Drained,
59 ResetToken(SocketAddr, ResetToken),
61 NeedIdentifiers(Instant, u64),
63 RetireConnectionId(Instant, u64, bool),
66 RelayPunchMeNow([u8; 32], crate::frame::PunchMeNow),
68 SendAddressFrame(crate::frame::AddAddress),
70 NatCandidateValidated { address: SocketAddr, challenge: u64 },
72}
73
74#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
78pub struct ConnectionId {
79 len: u8,
81 bytes: [u8; MAX_CID_SIZE],
83}
84
85impl ConnectionId {
86 pub fn new(bytes: &[u8]) -> Self {
88 debug_assert!(bytes.len() <= MAX_CID_SIZE);
89 let mut res = Self {
90 len: bytes.len() as u8,
91 bytes: [0; MAX_CID_SIZE],
92 };
93 res.bytes[..bytes.len()].copy_from_slice(bytes);
94 res
95 }
96
97 pub fn from_buf(buf: &mut (impl Buf + ?Sized), len: usize) -> Self {
101 debug_assert!(len <= MAX_CID_SIZE);
102 let mut res = Self {
103 len: len as u8,
104 bytes: [0; MAX_CID_SIZE],
105 };
106 buf.copy_to_slice(&mut res[..len]);
107 res
108 }
109
110 pub(crate) fn decode_long(buf: &mut impl Buf) -> Option<Self> {
112 let len = buf.get::<u8>().ok()? as usize;
113 match len > MAX_CID_SIZE || buf.remaining() < len {
114 false => Some(Self::from_buf(buf, len)),
115 true => None,
116 }
117 }
118
119 pub(crate) fn encode_long(&self, buf: &mut impl BufMut) {
121 buf.put_u8(self.len() as u8);
122 buf.put_slice(self);
123 }
124}
125
126impl ::std::ops::Deref for ConnectionId {
127 type Target = [u8];
128 fn deref(&self) -> &[u8] {
129 &self.bytes[0..self.len as usize]
130 }
131}
132
133impl ::std::ops::DerefMut for ConnectionId {
134 fn deref_mut(&mut self) -> &mut [u8] {
135 &mut self.bytes[0..self.len as usize]
136 }
137}
138
139impl fmt::Debug for ConnectionId {
140 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141 self.bytes[0..self.len as usize].fmt(f)
142 }
143}
144
145impl fmt::Display for ConnectionId {
146 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147 for byte in self.iter() {
148 write!(f, "{byte:02x}")?;
149 }
150 Ok(())
151 }
152}
153
154#[repr(u8)]
156#[derive(Debug, Copy, Clone, Eq, PartialEq)]
157pub enum EcnCodepoint {
158 Ect0 = 0b10,
160 Ect1 = 0b01,
162 Ce = 0b11,
164}
165
166impl EcnCodepoint {
167 pub fn from_bits(x: u8) -> Option<Self> {
169 use EcnCodepoint::*;
170 Some(match x & 0b11 {
171 0b10 => Ect0,
172 0b01 => Ect1,
173 0b11 => Ce,
174 _ => {
175 return None;
176 }
177 })
178 }
179
180 pub fn is_ce(self) -> bool {
182 matches!(self, Self::Ce)
183 }
184}
185
186#[derive(Debug, Copy, Clone)]
187pub(crate) struct IssuedCid {
188 pub(crate) sequence: u64,
189 pub(crate) id: ConnectionId,
190 pub(crate) reset_token: ResetToken,
191}