1use std::cell::{Cell, RefCell};
12use std::collections::VecDeque;
13use std::net::SocketAddr;
14use std::rc::Rc;
15use std::sync::Arc;
16use std::task::Poll;
17use std::time::Instant;
18
19use bytes::BytesMut;
20use moq_noq_proto::{ConnectionHandle, DatagramEvent, Incoming, Transmit};
21use rustc_hash::FxHashMap;
22
23use super::super::{Error, endpoint::Config};
24use super::connection;
25use crate::quic::Connection;
26use crate::shared::Shared;
27use crate::udp;
28use crate::worker::Owner;
29
30struct Accepting {
33 queue: VecDeque<Connection>,
34}
35
36pub(crate) struct Inner {
39 owner: Owner,
41 socket: Rc<udp::Socket>,
42 local: SocketAddr,
43 endpoint: RefCell<moq_noq_proto::Endpoint>,
45 accepting: RefCell<Option<Accepting>>,
46 conns: RefCell<FxHashMap<ConnectionHandle, connection::Shared>>,
52 pending: Cell<usize>,
55 backlog: usize,
56 handles: Cell<usize>,
59 closed: RefCell<Option<Error>>,
61 task_waiters: RefCell<kio::WaiterList>,
63 accept_waiters: RefCell<kio::WaiterList>,
64}
65
66pub struct Endpoint {
73 inner: Rc<Inner>,
74}
75
76impl Endpoint {
77 pub fn new(socket: udp::Socket, config: Config) -> Result<Self, Error> {
84 let owner = socket.owner();
85 let Some(handle) = owner.handle() else {
86 return Err(Error::Io(Shared::gone_error().to_string()));
87 };
88 let local = socket.local_addr().map_err(|err| Error::Io(err.to_string()))?;
89 let server = match &config.server {
90 Some(server) => {
91 let mut server = super::server_config(server)?;
92 server.max_incoming(config.backlog);
95 Some(Arc::new(server))
96 }
97 None => None,
98 };
99 let accepting = server.is_some().then(|| Accepting { queue: VecDeque::new() });
100 let endpoint = moq_noq_proto::Endpoint::new(super::endpoint_config(socket.shard())?, server, false);
103
104 let inner = Rc::new(Inner {
105 owner,
106 socket: Rc::new(socket),
107 local,
108 endpoint: RefCell::new(endpoint),
109 accepting: RefCell::new(accepting),
110 conns: RefCell::new(FxHashMap::default()),
111 pending: Cell::new(0),
112 backlog: config.backlog,
113 handles: Cell::new(1),
114 closed: RefCell::new(None),
115 task_waiters: RefCell::new(kio::WaiterList::new()),
116 accept_waiters: RefCell::new(kio::WaiterList::new()),
117 });
118
119 let task = inner.clone();
120 handle.spawn(async move { kio::wait(|waiter| task.poll_run(waiter)).await });
121
122 Ok(Self { inner })
123 }
124
125 pub fn local_addr(&self) -> SocketAddr {
127 self.inner.local
128 }
129
130 pub async fn accept(&self) -> Result<Connection, Error> {
136 kio::wait(|waiter| {
137 if let Some(err) = self.inner.closed() {
138 return Poll::Ready(Err(err));
139 }
140 let mut accepting = self.inner.accepting.borrow_mut();
141 let Some(accepting) = accepting.as_mut() else {
142 return Poll::Ready(Err(Error::NotServer));
143 };
144 if let Some(conn) = accepting.queue.pop_front() {
145 return Poll::Ready(Ok(conn));
146 }
147 waiter.register(&mut self.inner.accept_waiters.borrow_mut());
148 Poll::Pending
149 })
150 .await
151 }
152
153 pub async fn connect(&self, config: &crate::quic::client::Config) -> Result<Connection, Error> {
156 if let Some(err) = self.inner.closed() {
157 return Err(err);
158 }
159 let client = super::client_config(config)?;
160 let (key, conn) = self
161 .inner
162 .endpoint
163 .borrow_mut()
164 .connect(Instant::now(), client, config.peer, &config.server_name)
165 .map_err(|err| Error::Quic(err.to_string()))?;
166 let shared = self.inner.launch(key, conn);
167 shared.kick();
169 connection::establish(shared).await
170 }
171}
172
173impl Clone for Endpoint {
174 fn clone(&self) -> Self {
175 self.inner.handles.set(self.inner.handles.get() + 1);
176 Self {
177 inner: self.inner.clone(),
178 }
179 }
180}
181
182impl Drop for Endpoint {
183 fn drop(&mut self) {
184 let handles = self.inner.handles.get() - 1;
185 self.inner.handles.set(handles);
186 if handles > 0 {
187 return;
188 }
189 if let Some(accepting) = self.inner.accepting.borrow_mut().as_mut() {
192 for mut conn in accepting.queue.drain(..) {
193 web_transport_trait::poll::Session::close(&mut conn, 0, "endpoint closed");
194 }
195 }
196 self.inner.task_waiters.borrow_mut().wake();
197 }
198}
199
200impl std::fmt::Debug for Endpoint {
201 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
202 f.debug_struct("Endpoint")
203 .field("local", &self.inner.local)
204 .field("conns", &self.inner.conns.borrow().len())
205 .finish()
206 }
207}
208
209impl Inner {
210 fn closed(&self) -> Option<Error> {
213 if let Some(err) = &*self.closed.borrow() {
214 return Some(err.clone());
215 }
216 self.owner
217 .handle()
218 .is_none()
219 .then(|| Error::Io(Shared::gone_error().to_string()))
220 }
221
222 fn poll_run(self: &Rc<Self>, waiter: &kio::Waiter) -> Poll<()> {
224 waiter.register(&mut self.task_waiters.borrow_mut());
226
227 loop {
228 if self.handles.get() == 0 && self.conns.borrow().is_empty() {
229 return Poll::Ready(());
230 }
231 match self.socket.poll_recv(waiter) {
232 Poll::Ready(Ok(mut packet)) => self.demux(&mut packet),
233 Poll::Ready(Err(err)) => {
234 self.fail(Error::Io(err.to_string()));
235 return Poll::Ready(());
236 }
237 Poll::Pending => return Poll::Pending,
238 }
239 }
240 }
241
242 fn demux(self: &Rc<Self>, packet: &mut udp::Packet) {
244 let from = packet.from();
245 let ecn = packet.ecn().map(super::ecn_to_noq);
246 let mut buf = Vec::new();
249
250 let mut fed: Vec<ConnectionHandle> = Vec::new();
253
254 for segment in packet.segments() {
255 buf.clear();
256 let event = self.endpoint.borrow_mut().handle(
260 Instant::now(),
261 from.into(),
262 ecn,
263 BytesMut::from(&segment[..]),
264 &mut buf,
265 );
266 match event {
267 Some(DatagramEvent::ConnectionEvent(key, event)) => {
268 let conn = self.conns.borrow().get(&key).cloned();
269 if let Some(conn) = conn {
272 conn.conn.borrow_mut().handle_event(event);
273 if !fed.contains(&key) {
274 fed.push(key);
275 }
276 }
277 }
278 Some(DatagramEvent::NewConnection(incoming)) => {
279 if let Some(key) = self.greet(incoming, &mut buf)
280 && !fed.contains(&key)
281 {
282 fed.push(key);
283 }
284 }
285 Some(DatagramEvent::Response(transmit)) if self.accepting.borrow().is_some() => {
289 self.respond(&transmit, &buf)
290 }
291 Some(DatagramEvent::Response(_)) => {}
292 None => {}
293 }
294 }
295
296 for key in fed {
297 let conn = self.conns.borrow().get(&key).cloned();
298 if let Some(conn) = conn {
299 conn.kick();
300 }
301 }
302 }
303
304 fn greet(self: &Rc<Self>, incoming: Incoming, buf: &mut Vec<u8>) -> Option<ConnectionHandle> {
307 if self.handles.get() == 0 {
310 self.endpoint.borrow_mut().ignore(incoming);
311 return None;
312 }
313 let queued = self
316 .accepting
317 .borrow()
318 .as_ref()
319 .map(|accepting| accepting.queue.len())
320 .unwrap_or(0);
321 if self.pending.get() + queued >= self.backlog {
322 tracing::debug!(from = %incoming.remote_address(), "dropping a handshake over the backlog");
323 self.endpoint.borrow_mut().ignore(incoming);
326 return None;
327 }
328
329 buf.clear();
330 let accepted = self.endpoint.borrow_mut().accept(incoming, Instant::now(), buf, None);
331 let (key, conn) = match accepted {
332 Ok(accepted) => accepted,
333 Err(err) => {
334 tracing::debug!(err = %err.cause, "failed to accept a connection");
335 if let Some(transmit) = err.response {
336 self.respond(&transmit, buf);
337 }
338 return None;
339 }
340 };
341
342 let shared = self.launch(key, conn);
343
344 self.pending.set(self.pending.get() + 1);
346 let inner = self.clone();
347 self.owner.spawn(async move {
348 let outcome = connection::establish(shared).await;
349 inner.pending.set(inner.pending.get() - 1);
350 let mut conn = match outcome {
351 Ok(conn) => conn,
352 Err(err) => {
353 tracing::debug!(%err, "incoming handshake failed");
354 return;
355 }
356 };
357 if inner.handles.get() == 0 {
359 web_transport_trait::poll::Session::close(&mut conn, 0, "endpoint closed");
360 return;
361 }
362 {
363 let mut accepting = inner.accepting.borrow_mut();
364 let accepting = accepting.as_mut().expect("accepted without a server config");
365 accepting.queue.push_back(conn);
366 }
367 inner.accept_waiters.borrow_mut().wake();
368 });
369
370 Some(key)
371 }
372
373 fn respond(&self, transmit: &Transmit, buf: &[u8]) {
378 let Poll::Ready(Ok(mut tx)) = self.socket.poll_acquire(&kio::Waiter::noop()) else {
379 return;
380 };
381 if transmit.size > tx.len() {
382 tracing::debug!(size = transmit.size, "dropping an oversized endpoint response");
383 return;
384 }
385 tx[..transmit.size].copy_from_slice(&buf[..transmit.size]);
386 let transmit = udp::Transmit {
387 to: transmit.destination,
388 len: transmit.size,
389 segment: transmit.segment_size.unwrap_or(transmit.size),
390 ecn: transmit.ecn.map(super::ecn_from_noq),
391 };
392 if let Err(err) = tx.send(transmit) {
393 tracing::debug!(%err, "failed to send an endpoint response");
394 }
395 }
396
397 fn launch(self: &Rc<Self>, key: ConnectionHandle, conn: moq_noq_proto::Connection) -> connection::Shared {
399 let (shared, driver) = connection::launch(&self.owner, self.socket.clone(), Rc::downgrade(self), key, conn);
400 self.conns.borrow_mut().insert(key, shared.clone());
401
402 let inner = self.clone();
403 self.owner.spawn(async move {
404 driver.await;
405 inner.release(key);
406 });
407 shared
408 }
409
410 pub(crate) fn on_connection_event(
413 &self,
414 key: ConnectionHandle,
415 event: moq_noq_proto::EndpointEvent,
416 ) -> Option<moq_noq_proto::ConnectionEvent> {
417 self.endpoint.borrow_mut().handle_event(key, event)
418 }
419
420 fn release(&self, key: ConnectionHandle) {
422 self.conns.borrow_mut().remove(&key);
423 self.task_waiters.borrow_mut().wake();
425 }
426
427 fn fail(&self, err: Error) {
429 *self.closed.borrow_mut() = Some(err.clone());
430 let conns: Vec<connection::Shared> = self.conns.borrow().values().cloned().collect();
431 for conn in conns {
432 conn.fail(err.clone());
433 }
434 self.accept_waiters.borrow_mut().wake();
435 }
436}