1use std::{
2 collections::VecDeque,
3 fmt,
4 future::Future,
5 io::{self, IoSliceMut},
6 mem,
7 net::{SocketAddr, SocketAddrV6},
8 num::NonZeroUsize,
9 pin::Pin,
10 str,
11 sync::{
12 Arc, Mutex,
13 atomic::{AtomicUsize, Ordering},
14 },
15 task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
16};
17
18#[cfg(all(
19 not(wasm_browser),
20 any(feature = "runtime-tokio", feature = "runtime-smol"),
21 any(feature = "aws-lc-rs", feature = "ring"),
22))]
23use crate::runtime::default_runtime;
24use crate::{
25 Instant,
26 runtime::{AsyncUdpSocket, Runtime, UdpSender},
27 udp_transmit,
28};
29use bytes::{Bytes, BytesMut};
30use pin_project_lite::pin_project;
31use proto::{
32 self as proto, ClientConfig, ConnectError, ConnectionError, ConnectionHandle, DatagramEvent,
33 EndpointEvent, FourTuple, NetworkChangeHint, ServerConfig,
34};
35use rustc_hash::FxHashMap;
36#[cfg(all(
37 not(wasm_browser),
38 any(feature = "runtime-tokio", feature = "runtime-smol"),
39 any(feature = "aws-lc-rs", feature = "ring"),
40))]
41use socket2::{Domain, Protocol, Socket, Type};
42use tokio::sync::{Notify, futures::Notified, mpsc};
43use tracing::{Instrument, Span, trace};
44use udp::{BATCH_SIZE, RecvMeta};
45
46use crate::{
47 ConnectionEvent, EndpointConfig, IO_LOOP_BOUND, RECV_TIME_BOUND, VarInt,
48 connection::Connecting, incoming::Incoming, work_limiter::WorkLimiter,
49};
50
51#[derive(Debug, Clone)]
58pub struct Endpoint {
59 pub(crate) inner: EndpointRef,
60 runtime: Arc<dyn Runtime>,
61}
62
63impl Endpoint {
64 #[cfg(all(
82 not(wasm_browser),
83 any(feature = "runtime-tokio", feature = "runtime-smol"),
84 any(feature = "aws-lc-rs", feature = "ring"), ))]
86 pub fn client(addr: SocketAddr) -> io::Result<Self> {
87 let socket = Socket::new(Domain::for_address(addr), Type::DGRAM, Some(Protocol::UDP))?;
88 if addr.is_ipv6()
89 && let Err(e) = socket.set_only_v6(false)
90 {
91 tracing::debug!(%e, "unable to make socket dual-stack");
92 }
93 socket.bind(&addr.into())?;
94 let runtime =
95 default_runtime().ok_or_else(|| io::Error::other("no async runtime found"))?;
96 Self::new_with_abstract_socket(
97 EndpointConfig::default(),
98 None,
99 runtime.wrap_udp_socket(socket.into())?,
100 runtime,
101 )
102 }
103
104 pub fn stats(&self) -> EndpointStats {
106 self.inner.state.lock().unwrap().stats
107 }
108
109 #[cfg(all(
124 not(wasm_browser),
125 any(feature = "runtime-tokio", feature = "runtime-smol"),
126 any(feature = "aws-lc-rs", feature = "ring"), ))]
128 pub fn server(config: ServerConfig, addr: SocketAddr) -> io::Result<Self> {
129 let socket = Socket::new(Domain::for_address(addr), Type::DGRAM, Some(Protocol::UDP))?;
130 if addr.is_ipv6()
131 && let Err(e) = socket.set_only_v6(false)
132 {
133 tracing::debug!(%e, "unable to make socket dual-stack");
134 }
135 socket.bind(&addr.into())?;
136 let runtime =
137 default_runtime().ok_or_else(|| io::Error::other("no async runtime found"))?;
138 Self::new_with_abstract_socket(
139 EndpointConfig::default(),
140 Some(config),
141 runtime.wrap_udp_socket(socket.into())?,
142 runtime,
143 )
144 }
145
146 #[cfg(not(wasm_browser))]
148 pub fn new(
149 config: EndpointConfig,
150 server_config: Option<ServerConfig>,
151 socket: std::net::UdpSocket,
152 runtime: Arc<dyn Runtime>,
153 ) -> io::Result<Self> {
154 let socket = runtime.wrap_udp_socket(socket)?;
155 Self::new_with_abstract_socket(config, server_config, socket, runtime)
156 }
157
158 pub fn new_with_abstract_socket(
163 config: EndpointConfig,
164 server_config: Option<ServerConfig>,
165 socket: Box<dyn AsyncUdpSocket>,
166 runtime: Arc<dyn Runtime>,
167 ) -> io::Result<Self> {
168 let addr = socket.local_addr()?;
169 let allow_mtud = !socket.may_fragment();
170 let rc = EndpointRef::new(
171 socket,
172 proto::Endpoint::new(Arc::new(config), server_config.map(Arc::new), allow_mtud),
173 addr.is_ipv6(),
174 runtime.clone(),
175 );
176 let driver = EndpointDriver(rc.clone());
177 runtime.spawn(Box::pin(
178 async {
179 if let Err(e) = driver.await {
180 tracing::error!("I/O error: {}", e);
181 }
182 }
183 .instrument(Span::current()),
184 ));
185 Ok(Self { inner: rc, runtime })
186 }
187
188 pub fn accept(&self) -> Accept<'_> {
195 Accept {
196 endpoint: self,
197 notify: self.inner.shared.incoming.notified(),
198 }
199 }
200
201 pub fn set_default_client_config(&self, config: ClientConfig) {
203 self.inner.0.state.lock().unwrap().default_client_config = Some(config);
204 }
205
206 pub fn connect(&self, addr: SocketAddr, server_name: &str) -> Result<Connecting, ConnectError> {
215 let Some(config) = self
216 .inner
217 .0
218 .state
219 .lock()
220 .unwrap()
221 .default_client_config
222 .clone()
223 else {
224 return Err(ConnectError::NoDefaultClientConfig);
225 };
226
227 self.connect_with(config, addr, server_name)
228 }
229
230 pub fn connect_with(
236 &self,
237 config: ClientConfig,
238 addr: SocketAddr,
239 server_name: &str,
240 ) -> Result<Connecting, ConnectError> {
241 let mut endpoint = self.inner.state.lock().unwrap();
242 if endpoint.driver_lost || endpoint.recv_state.connections.close.is_some() {
243 return Err(ConnectError::EndpointStopping);
244 }
245 if addr.is_ipv6() && !endpoint.ipv6 {
246 return Err(ConnectError::InvalidRemoteAddress(addr));
247 }
248 let addr = if endpoint.ipv6 {
249 SocketAddr::V6(ensure_ipv6(addr))
250 } else {
251 addr
252 };
253
254 let (ch, conn) = endpoint
255 .inner
256 .connect(self.runtime.now(), config, addr, server_name)?;
257
258 let sender = endpoint.socket.create_sender();
259 endpoint.stats.outgoing_handshakes += 1;
260 Ok(endpoint
261 .recv_state
262 .connections
263 .insert(ch, conn, sender, self.runtime.clone()))
264 }
265
266 #[cfg(not(wasm_browser))]
270 pub fn rebind(&self, socket: std::net::UdpSocket) -> io::Result<()> {
271 self.rebind_abstract(self.runtime.wrap_udp_socket(socket)?)
272 }
273
274 pub fn rebind_abstract(&self, socket: Box<dyn AsyncUdpSocket>) -> io::Result<()> {
281 let addr = socket.local_addr()?;
282 let mut inner = self.inner.state.lock().unwrap();
283 inner.prev_socket = Some(mem::replace(&mut inner.socket, socket));
284 inner.ipv6 = addr.is_ipv6();
285
286 for sender in inner.recv_state.connections.senders.values() {
288 let _ = sender.send(ConnectionEvent::Rebind(inner.socket.create_sender()));
290 }
291 if let Some(driver) = inner.driver.take() {
292 driver.wake();
294 }
295
296 Ok(())
297 }
298
299 pub fn handle_network_change(&self, hint: Option<Arc<dyn NetworkChangeHint + Sync + Send>>) {
314 let mut inner = self.inner.state.lock().unwrap();
315 for sender in inner.recv_state.connections.senders.values() {
316 let _ = sender.send(ConnectionEvent::LocalAddressChanged(hint.clone()));
318 }
319 if let Some(driver) = inner.driver.take() {
320 driver.wake();
321 }
322 }
323
324 pub fn set_server_config(&self, server_config: Option<ServerConfig>) {
328 self.inner
329 .state
330 .lock()
331 .unwrap()
332 .inner
333 .set_server_config(server_config.map(Arc::new))
334 }
335
336 pub fn local_addr(&self) -> io::Result<SocketAddr> {
338 self.inner.state.lock().unwrap().socket.local_addr()
339 }
340
341 pub fn open_connections(&self) -> usize {
343 self.inner.state.lock().unwrap().inner.open_connections()
344 }
345
346 pub fn close(&self, error_code: VarInt, reason: &[u8]) {
352 let reason = Bytes::copy_from_slice(reason);
353 let mut endpoint = self.inner.state.lock().unwrap();
354 endpoint.recv_state.connections.close = Some((error_code, reason.clone()));
355 for sender in endpoint.recv_state.connections.senders.values() {
356 let _ = sender.send(ConnectionEvent::Close {
358 error_code,
359 reason: reason.clone(),
360 });
361 }
362 self.inner.shared.incoming.notify_waiters();
363 if let Some(waker) = endpoint.driver.take() {
365 waker.wake();
366 }
367 }
368
369 pub async fn wait_idle(&self) {
380 loop {
381 {
382 let endpoint = &mut *self.inner.state.lock().unwrap();
383 if endpoint.recv_state.connections.is_empty() {
384 break;
385 }
386 self.inner.shared.idle.notified()
388 }
389 .await;
390 }
391 }
392
393 pub async fn wait_all_draining(&self) {
411 loop {
412 {
413 let endpoint = &mut *self.inner.state.lock().unwrap();
414 if endpoint.recv_state.connections.active_connections == 0 {
415 break;
416 }
417 self.inner.shared.all_draining.notified()
419 }
420 .await;
421 }
422 }
423}
424
425#[non_exhaustive]
427#[derive(Debug, Default, Copy, Clone)]
428pub struct EndpointStats {
429 pub accepted_handshakes: u64,
431 pub outgoing_handshakes: u64,
433 pub refused_handshakes: u64,
435 pub ignored_handshakes: u64,
437}
438
439#[must_use = "endpoint drivers must be spawned for I/O to occur"]
450#[derive(Debug)]
451pub(crate) struct EndpointDriver(pub(crate) EndpointRef);
452
453impl Future for EndpointDriver {
454 type Output = Result<(), io::Error>;
455
456 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
457 let mut endpoint = self.0.state.lock().unwrap();
458 if endpoint.driver.is_none() {
459 endpoint.driver = Some(cx.waker().clone());
460 }
461
462 let now = endpoint.runtime.now();
463 let mut keep_going = false;
464 keep_going |= endpoint.drive_recv(cx, now)?;
465 keep_going |= endpoint.handle_events(cx, &self.0.shared);
466
467 if !endpoint.recv_state.incoming.is_empty() {
468 self.0.shared.incoming.notify_waiters();
469 }
470
471 if endpoint.recv_state.connections.is_empty()
475 && (self.0.shared.ref_count.load(Ordering::Relaxed) == 0
476 || endpoint.recv_state.connections.close.is_some())
477 {
478 trace!("endpoint driver stopping");
479 Poll::Ready(Ok(()))
480 } else {
481 drop(endpoint);
482 if keep_going {
486 cx.waker().wake_by_ref();
487 }
488 Poll::Pending
489 }
490 }
491}
492
493impl Drop for EndpointDriver {
494 fn drop(&mut self) {
495 let mut endpoint = self.0.state.lock().unwrap();
496 endpoint.driver_lost = true;
497 self.0.shared.incoming.notify_waiters();
498 endpoint.recv_state.connections.senders.clear();
501 endpoint.recv_state.connections.active_connections = 0;
502 }
503}
504
505#[derive(Debug)]
506pub(crate) struct EndpointInner {
507 pub(crate) state: Mutex<State>,
508 pub(crate) shared: Shared,
509}
510
511impl EndpointInner {
512 pub(crate) fn accept(
513 &self,
514 incoming: proto::Incoming,
515 server_config: Option<Arc<ServerConfig>>,
516 ) -> Result<Connecting, ConnectionError> {
517 let mut state = self.state.lock().unwrap();
518 let mut response_buffer = Vec::new();
519 let now = state.runtime.now();
520 match state
521 .inner
522 .accept(incoming, now, &mut response_buffer, server_config)
523 {
524 Ok((handle, conn)) => {
525 state.stats.accepted_handshakes += 1;
526 let sender = state.socket.create_sender();
527 let runtime = state.runtime.clone();
528 Ok(state
529 .recv_state
530 .connections
531 .insert(handle, conn, sender, runtime))
532 }
533 Err(error) => {
534 if let Some(transmit) = error.response {
535 respond(transmit, &response_buffer, &mut state.sender);
536 }
537 Err(error.cause)
538 }
539 }
540 }
541
542 pub(crate) fn refuse(&self, incoming: proto::Incoming) {
543 let mut state = self.state.lock().unwrap();
544 state.stats.refused_handshakes += 1;
545 let mut response_buffer = Vec::new();
546 let transmit = state.inner.refuse(incoming, &mut response_buffer);
547 respond(transmit, &response_buffer, &mut state.sender);
548 }
549
550 pub(crate) fn retry(&self, incoming: proto::Incoming) -> Result<(), proto::RetryError> {
551 let mut state = self.state.lock().unwrap();
552 let mut response_buffer = Vec::new();
553 let transmit = state.inner.retry(incoming, &mut response_buffer)?;
554 respond(transmit, &response_buffer, &mut state.sender);
555 Ok(())
556 }
557
558 pub(crate) fn ignore(&self, incoming: proto::Incoming) {
559 let mut state = self.state.lock().unwrap();
560 state.stats.ignored_handshakes += 1;
561 state.inner.ignore(incoming);
562 }
563}
564
565#[derive(Debug)]
566pub(crate) struct State {
567 socket: Box<dyn AsyncUdpSocket>,
568 sender: Pin<Box<dyn UdpSender>>,
569 prev_socket: Option<Box<dyn AsyncUdpSocket>>,
572 inner: proto::Endpoint,
573 recv_state: RecvState,
574 driver: Option<Waker>,
575 ipv6: bool,
576 events: mpsc::UnboundedReceiver<(ConnectionHandle, EndpointEvent)>,
577 driver_lost: bool,
578 runtime: Arc<dyn Runtime>,
579 stats: EndpointStats,
580 default_client_config: Option<ClientConfig>,
581}
582
583#[derive(Debug)]
584pub(crate) struct Shared {
585 incoming: Notify,
589 all_draining: Notify,
593 idle: Notify,
597 ref_count: AtomicUsize,
599}
600
601impl State {
602 fn drive_recv(&mut self, cx: &mut Context<'_>, now: Instant) -> Result<bool, io::Error> {
603 let get_time = || self.runtime.now();
604 self.recv_state.recv_limiter.start_cycle(get_time);
605 if let Some(socket) = &mut self.prev_socket {
606 let poll_res = self.recv_state.poll_socket(
608 cx,
609 &mut self.inner,
610 &mut **socket,
611 &mut self.sender,
612 &*self.runtime,
613 now,
614 );
615 if poll_res.is_err() {
616 self.prev_socket = None;
617 }
618 };
619 let poll_res = self.recv_state.poll_socket(
620 cx,
621 &mut self.inner,
622 &mut *self.socket,
623 &mut self.sender,
624 &*self.runtime,
625 now,
626 );
627 self.recv_state.recv_limiter.finish_cycle(get_time);
628 let poll_res = poll_res?;
629 if poll_res.received_connection_packet {
630 self.prev_socket = None;
633 }
634 Ok(poll_res.keep_going)
635 }
636
637 fn handle_events(&mut self, cx: &mut Context<'_>, shared: &Shared) -> bool {
638 for _ in 0..IO_LOOP_BOUND {
639 let (ch, event) = match self.events.poll_recv(cx) {
640 Poll::Ready(Some(x)) => x,
641 Poll::Ready(None) => unreachable!("EndpointInner owns one sender"),
642 Poll::Pending => {
643 return false;
644 }
645 };
646
647 if event.is_draining() {
648 self.recv_state.connections.active_connections -= 1;
649 if self.recv_state.connections.active_connections == 0 {
650 shared.all_draining.notify_waiters();
651 }
652 } else if event.is_drained() {
653 self.recv_state.connections.senders.remove(&ch);
654 if self.recv_state.connections.is_empty() {
655 shared.idle.notify_waiters();
656 }
657 }
658 let Some(event) = self.inner.handle_event(ch, event) else {
659 continue;
660 };
661 let _ = self
663 .recv_state
664 .connections
665 .senders
666 .get_mut(&ch)
667 .unwrap()
668 .send(ConnectionEvent::Proto(event));
669 }
670
671 true
672 }
673}
674
675impl Drop for State {
676 fn drop(&mut self) {
677 for incoming in self.recv_state.incoming.drain(..) {
678 self.inner.ignore(incoming);
679 }
680 }
681}
682
683fn respond(
684 transmit: proto::Transmit,
685 response_buffer: &[u8],
686 sender: &mut Pin<Box<dyn UdpSender>>,
687) {
688 const NOOP: RawWaker = {
711 const VTABLE: RawWakerVTable = RawWakerVTable::new(
712 |_| NOOP,
714 |_| {},
716 |_| {},
718 |_| {},
720 );
721 RawWaker::new(std::ptr::null(), &VTABLE)
722 };
723 let waker = unsafe { Waker::from_raw(NOOP) };
726 let mut cx = Context::from_waker(&waker);
727 _ = sender.as_mut().poll_send(
728 &udp_transmit(&transmit, &response_buffer[..transmit.size]),
729 &mut cx,
730 );
731}
732
733#[inline]
734fn proto_ecn(ecn: udp::EcnCodepoint) -> proto::EcnCodepoint {
735 match ecn {
736 udp::EcnCodepoint::Ect0 => proto::EcnCodepoint::Ect0,
737 udp::EcnCodepoint::Ect1 => proto::EcnCodepoint::Ect1,
738 udp::EcnCodepoint::Ce => proto::EcnCodepoint::Ce,
739 }
740}
741
742#[derive(Debug)]
743struct ConnectionSet {
744 senders: FxHashMap<ConnectionHandle, mpsc::UnboundedSender<ConnectionEvent>>,
746 sender: mpsc::UnboundedSender<(ConnectionHandle, EndpointEvent)>,
748 close: Option<(VarInt, Bytes)>,
750 active_connections: u64,
760}
761
762impl ConnectionSet {
763 fn insert(
764 &mut self,
765 handle: ConnectionHandle,
766 conn: proto::Connection,
767 sender: Pin<Box<dyn UdpSender>>,
768 runtime: Arc<dyn Runtime>,
769 ) -> Connecting {
770 let (send, recv) = mpsc::unbounded_channel();
771 if let Some((error_code, ref reason)) = self.close {
772 send.send(ConnectionEvent::Close {
773 error_code,
774 reason: reason.clone(),
775 })
776 .unwrap();
777 }
778 self.senders.insert(handle, send);
779 self.active_connections += 1;
780 Connecting::new(handle, conn, self.sender.clone(), recv, sender, runtime)
781 }
782
783 fn is_empty(&self) -> bool {
784 self.senders.is_empty()
785 }
786}
787
788pub(crate) fn ensure_ipv6(x: SocketAddr) -> SocketAddrV6 {
789 match x {
790 SocketAddr::V6(x) => x,
791 SocketAddr::V4(x) => SocketAddrV6::new(x.ip().to_ipv6_mapped(), x.port(), 0, 0),
792 }
793}
794
795pin_project! {
796 pub struct Accept<'a> {
798 endpoint: &'a Endpoint,
799 #[pin]
800 notify: Notified<'a>,
801 }
802}
803
804impl Future for Accept<'_> {
805 type Output = Option<Incoming>;
806 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
807 let mut this = self.project();
808 let mut endpoint = this.endpoint.inner.state.lock().unwrap();
809 if endpoint.driver_lost {
810 return Poll::Ready(None);
811 }
812 if let Some(incoming) = endpoint.recv_state.incoming.pop_front() {
813 drop(endpoint);
815 let incoming = Incoming::new(incoming, this.endpoint.inner.clone());
816 return Poll::Ready(Some(incoming));
817 }
818 if endpoint.recv_state.connections.close.is_some() {
819 return Poll::Ready(None);
820 }
821 loop {
822 match this.notify.as_mut().poll(ctx) {
823 Poll::Pending => return Poll::Pending,
825 Poll::Ready(()) => this
827 .notify
828 .set(this.endpoint.inner.shared.incoming.notified()),
829 }
830 }
831 }
832}
833
834#[derive(Debug)]
835pub(crate) struct EndpointRef(Arc<EndpointInner>);
836
837impl EndpointRef {
838 pub(crate) fn new(
839 socket: Box<dyn AsyncUdpSocket>,
840 inner: proto::Endpoint,
841 ipv6: bool,
842 runtime: Arc<dyn Runtime>,
843 ) -> Self {
844 let (sender, events) = mpsc::unbounded_channel();
845 let recv_state = RecvState::new(sender, socket.max_receive_segments(), &inner);
846 let sender = socket.create_sender();
847 Self(Arc::new(EndpointInner {
848 shared: Shared {
849 incoming: Notify::new(),
850 all_draining: Notify::new(),
851 idle: Notify::new(),
852 ref_count: AtomicUsize::new(0),
853 },
854 state: Mutex::new(State {
855 socket,
856 sender,
857 prev_socket: None,
858 inner,
859 ipv6,
860 events,
861 driver: None,
862 driver_lost: false,
863 recv_state,
864 runtime,
865 stats: EndpointStats::default(),
866 default_client_config: None,
867 }),
868 }))
869 }
870}
871
872impl Clone for EndpointRef {
873 fn clone(&self) -> Self {
874 self.0.shared.ref_count.fetch_add(1, Ordering::Relaxed);
875 Self(self.0.clone())
876 }
877}
878
879impl Drop for EndpointRef {
880 fn drop(&mut self) {
881 if self.0.shared.ref_count.fetch_sub(1, Ordering::Relaxed) > 1 {
882 return;
883 }
884
885 let endpoint = &mut *self.0.state.lock().unwrap();
886 if let Some(task) = endpoint.driver.take() {
889 task.wake();
890 }
891 }
892}
893
894impl std::ops::Deref for EndpointRef {
895 type Target = EndpointInner;
896 fn deref(&self) -> &Self::Target {
897 &self.0
898 }
899}
900
901struct RecvState {
903 incoming: VecDeque<proto::Incoming>,
904 connections: ConnectionSet,
905 recv_buf: Box<[u8]>,
906 recv_limiter: WorkLimiter,
907}
908
909impl RecvState {
910 fn new(
911 sender: mpsc::UnboundedSender<(ConnectionHandle, EndpointEvent)>,
912 max_receive_segments: NonZeroUsize,
913 endpoint: &proto::Endpoint,
914 ) -> Self {
915 let recv_buf = vec![
916 0;
917 endpoint.config().get_max_udp_payload_size().min(64 * 1024) as usize
918 * max_receive_segments.get()
919 * BATCH_SIZE
920 ];
921 Self {
922 connections: ConnectionSet {
923 senders: FxHashMap::default(),
924 sender,
925 close: None,
926 active_connections: 0,
927 },
928 incoming: VecDeque::new(),
929 recv_buf: recv_buf.into(),
930 recv_limiter: WorkLimiter::new(RECV_TIME_BOUND),
931 }
932 }
933
934 fn poll_socket(
935 &mut self,
936 cx: &mut Context<'_>,
937 endpoint: &mut proto::Endpoint,
938 socket: &mut dyn AsyncUdpSocket,
939 sender: &mut Pin<Box<dyn UdpSender>>,
940 runtime: &dyn Runtime,
941 now: Instant,
942 ) -> Result<PollProgress, io::Error> {
943 let mut received_connection_packet = false;
944 let mut metas = [RecvMeta::default(); BATCH_SIZE];
945 let mut iovs: [IoSliceMut<'_>; BATCH_SIZE] = {
946 let mut bufs = self
947 .recv_buf
948 .chunks_mut(self.recv_buf.len() / BATCH_SIZE)
949 .map(IoSliceMut::new);
950
951 std::array::from_fn(|_| bufs.next().expect("BATCH_SIZE elements"))
955 };
956 loop {
957 match socket.poll_recv(cx, &mut iovs, &mut metas) {
958 Poll::Ready(Ok(msgs)) => {
959 self.recv_limiter.record_work(msgs);
960 for (meta, buf) in metas.iter().zip(iovs.iter()).take(msgs) {
961 let mut data: BytesMut = buf[0..meta.len].into();
962 while !data.is_empty() {
963 let buf = data.split_to(meta.stride.min(data.len()));
964 let mut response_buffer = Vec::new();
965 let addresses = FourTuple::new(meta.addr, meta.dst_ip);
966 match endpoint.handle(
967 now,
968 addresses,
969 meta.ecn.map(proto_ecn),
970 buf,
971 &mut response_buffer,
972 ) {
973 Some(DatagramEvent::NewConnection(incoming)) => {
974 if self.connections.close.is_none() {
975 self.incoming.push_back(incoming);
976 } else {
977 let transmit =
978 endpoint.refuse(incoming, &mut response_buffer);
979 respond(transmit, &response_buffer, sender);
980 }
981 }
982 Some(DatagramEvent::ConnectionEvent(handle, event)) => {
983 received_connection_packet = true;
985 let _ = self
986 .connections
987 .senders
988 .get_mut(&handle)
989 .unwrap()
990 .send(ConnectionEvent::Proto(event));
991 }
992 Some(DatagramEvent::Response(transmit)) => {
993 respond(transmit, &response_buffer, sender);
994 }
995 None => {}
996 }
997 }
998 }
999 }
1000 Poll::Pending => {
1001 return Ok(PollProgress {
1002 received_connection_packet,
1003 keep_going: false,
1004 });
1005 }
1006 Poll::Ready(Err(ref e)) if e.kind() == io::ErrorKind::ConnectionReset => {
1009 continue;
1010 }
1011 Poll::Ready(Err(e)) => {
1012 return Err(e);
1013 }
1014 }
1015 if !self.recv_limiter.allow_work(|| runtime.now()) {
1016 return Ok(PollProgress {
1017 received_connection_packet,
1018 keep_going: true,
1019 });
1020 }
1021 }
1022 }
1023}
1024
1025impl fmt::Debug for RecvState {
1026 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1027 f.debug_struct("RecvState")
1028 .field("incoming", &self.incoming)
1029 .field("connections", &self.connections)
1030 .field("recv_limiter", &self.recv_limiter)
1032 .finish_non_exhaustive()
1033 }
1034}
1035
1036#[derive(Default)]
1037struct PollProgress {
1038 received_connection_packet: bool,
1040 keep_going: bool,
1042}