1use crate::conn::DTLSConn;
11use shared::error::{Error, Result};
12use shared::{EcnCodepoint, TransportContext};
13use shared::{TransportMessage, TransportProtocol};
14
15use crate::config::HandshakeConfig;
16use crate::state::State;
17use bytes::BytesMut;
18use std::collections::hash_map::Keys;
19use std::collections::{HashMap, VecDeque, hash_map::Entry::Vacant};
20use std::net::SocketAddr;
21use std::sync::Arc;
22use std::time::Instant;
23
24pub enum EndpointEvent {
26 HandshakeComplete,
28 ApplicationData(BytesMut),
30}
31
32pub struct Endpoint {
38 local_addr: SocketAddr,
39 transport_protocol: TransportProtocol,
40 transmits: VecDeque<TransportMessage<BytesMut>>,
41 connections: HashMap<SocketAddr, DTLSConn>,
42 server_config: Option<Arc<HandshakeConfig>>,
43}
44
45impl Endpoint {
46 pub fn new(
50 local_addr: SocketAddr,
51 protocol: TransportProtocol,
52 server_config: Option<Arc<HandshakeConfig>>,
53 ) -> Self {
54 Self {
55 local_addr,
56 transport_protocol: protocol,
57 transmits: VecDeque::new(),
58 connections: HashMap::new(),
59 server_config,
60 }
61 }
62
63 pub fn set_server_config(&mut self, server_config: Option<Arc<HandshakeConfig>>) {
65 self.server_config = server_config;
66 }
67
68 #[must_use]
70 pub fn poll_transmit(&mut self) -> Option<TransportMessage<BytesMut>> {
71 self.transmits.pop_front()
72 }
73
74 pub fn get_connections_keys(&self) -> Keys<'_, SocketAddr, DTLSConn> {
76 self.connections.keys()
77 }
78
79 pub fn get_connection_state(&self, remote: SocketAddr) -> Option<&State> {
81 if let Some(conn) = self.connections.get(&remote) {
82 Some(conn.connection_state())
83 } else {
84 None
85 }
86 }
87
88 pub fn connect(
90 &mut self,
91 remote: SocketAddr,
92 client_config: Arc<HandshakeConfig>,
93 initial_state: Option<State>,
94 ) -> Result<()> {
95 if remote.port() == 0 {
96 return Err(Error::InvalidRemoteAddress(remote));
97 }
98
99 if let Vacant(e) = self.connections.entry(remote) {
100 let mut conn = DTLSConn::new(client_config, true, initial_state);
101 conn.handshake()?;
102
103 while let Some(payload) = conn.outgoing_raw_packet() {
104 self.transmits.push_back(TransportMessage {
105 now: Instant::now(),
106 transport: TransportContext {
107 local_addr: self.local_addr,
108 peer_addr: remote,
109 ecn: None,
110 transport_protocol: self.transport_protocol,
111 },
112 message: payload,
113 });
114 }
115
116 e.insert(conn);
117 }
118
119 Ok(())
120 }
121
122 pub fn stop(&mut self, remote: SocketAddr) -> Option<DTLSConn> {
124 if let Some(conn) = self.connections.get_mut(&remote) {
125 conn.close();
126 while let Some(payload) = conn.outgoing_raw_packet() {
127 self.transmits.push_back(TransportMessage {
128 now: Instant::now(),
129 transport: TransportContext {
130 local_addr: self.local_addr,
131 peer_addr: remote,
132 ecn: None,
133 transport_protocol: self.transport_protocol,
134 },
135 message: payload,
136 });
137 }
138 }
139 self.connections.remove(&remote)
140 }
141
142 pub fn close(&mut self) -> Result<()> {
144 for (remote_addr, conn) in self.connections.iter_mut() {
145 conn.close();
146 while let Some(payload) = conn.outgoing_raw_packet() {
147 self.transmits.push_back(TransportMessage {
148 now: Instant::now(),
149 transport: TransportContext {
150 local_addr: self.local_addr,
151 peer_addr: *remote_addr,
152 ecn: None,
153 transport_protocol: self.transport_protocol,
154 },
155 message: payload,
156 });
157 }
158 }
159 self.connections.clear();
160
161 Ok(())
162 }
163
164 pub fn read(
166 &mut self,
167 now: Instant,
168 remote: SocketAddr,
169 ecn: Option<EcnCodepoint>,
170 data: BytesMut,
171 ) -> Result<Vec<EndpointEvent>> {
172 if let Vacant(e) = self.connections.entry(remote) {
173 if let Some(server_config) = &self.server_config {
174 let handshake_config = server_config.clone();
175 let conn = DTLSConn::new(handshake_config, false, None);
176 e.insert(conn);
177 } else {
178 return Err(Error::NoServerConfig);
179 }
180 }
181
182 let mut messages = vec![];
184 if let Some(conn) = self.connections.get_mut(&remote) {
185 let is_handshake_completed_before = conn.is_handshake_completed();
186 conn.read(&data)?;
187 if !conn.is_handshake_completed() {
188 conn.handshake()?;
189 let is_handshake = conn.handle_incoming_queued_packets()?;
193 if is_handshake && !conn.is_handshake_completed() {
194 conn.handshake()?;
195 }
196 }
197 if !is_handshake_completed_before && conn.is_handshake_completed() {
198 messages.push(EndpointEvent::HandshakeComplete)
199 }
200 while let Some(message) = conn.incoming_application_data() {
201 messages.push(EndpointEvent::ApplicationData(message));
202 }
203 while let Some(payload) = conn.outgoing_raw_packet() {
204 self.transmits.push_back(TransportMessage {
205 now,
206 transport: TransportContext {
207 local_addr: self.local_addr,
208 peer_addr: remote,
209 ecn,
210 transport_protocol: self.transport_protocol,
211 },
212 message: payload,
213 });
214 }
215 }
216
217 Ok(messages)
218 }
219
220 pub fn write(&mut self, remote: SocketAddr, data: &[u8]) -> Result<()> {
226 if let Some(conn) = self.connections.get_mut(&remote) {
227 conn.write(data)?;
228 while let Some(payload) = conn.outgoing_raw_packet() {
229 self.transmits.push_back(TransportMessage {
230 now: Instant::now(),
231 transport: TransportContext {
232 local_addr: self.local_addr,
233 peer_addr: remote,
234 ecn: None,
235 transport_protocol: self.transport_protocol,
236 },
237 message: payload,
238 });
239 }
240 Ok(())
241 } else {
242 Err(Error::InvalidRemoteAddress(remote))
243 }
244 }
245
246 pub fn handle_timeout(&mut self, remote: SocketAddr, now: Instant) -> Result<()> {
252 if let Some(conn) = self.connections.get_mut(&remote) {
253 if let Some(current_retransmit_timer) = &conn.current_retransmit_timer
254 && now >= *current_retransmit_timer
255 {
256 if conn.current_retransmit_timer.take().is_some() && !conn.is_handshake_completed()
257 {
258 conn.handshake_timeout(now)?;
259 }
260 while let Some(payload) = conn.outgoing_raw_packet() {
261 self.transmits.push_back(TransportMessage {
262 now,
263 transport: TransportContext {
264 local_addr: self.local_addr,
265 peer_addr: remote,
266 ecn: None,
267 transport_protocol: self.transport_protocol,
268 },
269 message: payload,
270 });
271 }
272 }
273 Ok(())
274 } else {
275 Err(Error::InvalidRemoteAddress(remote))
276 }
277 }
278
279 pub fn poll_timeout(&self, remote: SocketAddr, eto: &mut Instant) -> Result<()> {
281 if let Some(conn) = self.connections.get(&remote) {
282 if let Some(current_retransmit_timer) = &conn.current_retransmit_timer
283 && *current_retransmit_timer < *eto
284 {
285 *eto = *current_retransmit_timer;
286 }
287 Ok(())
288 } else {
289 Err(Error::InvalidRemoteAddress(remote))
290 }
291 }
292}