1use std::{
2 future::{Future, IntoFuture},
3 net::{IpAddr, SocketAddr},
4 pin::Pin,
5 task::{Context, Poll},
6};
7
8use futures_util::FutureExt;
9use quinn_proto::{ConnectionId, ServerConfig};
10use thiserror::Error;
11
12use crate::{Connecting, Connection, ConnectionError, EndpointRef};
13
14#[derive(Debug)]
15pub(crate) struct IncomingInner {
16 pub(crate) incoming: quinn_proto::Incoming,
17 pub(crate) endpoint: EndpointRef,
18}
19
20#[derive(Debug)]
23pub struct Incoming(Option<IncomingInner>);
24
25impl Incoming {
26 pub(crate) fn new(incoming: quinn_proto::Incoming, endpoint: EndpointRef) -> Self {
27 Self(Some(IncomingInner { incoming, endpoint }))
28 }
29
30 #[track_caller]
33 pub fn accept(mut self) -> Result<Connecting, ConnectionError> {
34 let inner = self.0.take().unwrap();
35 Ok(inner.endpoint.accept(inner.incoming, None)?)
36 }
37
38 pub fn accept_with(
44 mut self,
45 server_config: ServerConfig,
46 ) -> Result<Connecting, ConnectionError> {
47 let inner = self.0.take().unwrap();
48 Ok(inner.endpoint.accept(inner.incoming, Some(server_config))?)
49 }
50
51 pub fn refuse(mut self) {
53 let inner = self.0.take().unwrap();
54 inner.endpoint.refuse(inner.incoming);
55 }
56
57 #[allow(clippy::result_large_err)]
62 pub fn retry(mut self) -> Result<(), RetryError> {
63 let inner = self.0.take().unwrap();
64 inner
65 .endpoint
66 .retry(inner.incoming)
67 .map_err(|e| RetryError(Box::new(Self::new(e.into_incoming(), inner.endpoint))))
68 }
69
70 pub fn ignore(mut self) {
73 let inner = self.0.take().unwrap();
74 inner.endpoint.ignore(inner.incoming);
75 }
76
77 pub fn local_ip(&self) -> Option<IpAddr> {
80 self.0.as_ref().unwrap().incoming.local_ip()
81 }
82
83 pub fn remote_address(&self) -> SocketAddr {
85 self.0.as_ref().unwrap().incoming.remote_address()
86 }
87
88 pub fn remote_address_validated(&self) -> bool {
94 self.0.as_ref().unwrap().incoming.remote_address_validated()
95 }
96
97 pub fn may_retry(&self) -> bool {
102 self.0.as_ref().unwrap().incoming.may_retry()
103 }
104
105 pub fn orig_dst_cid(&self) -> ConnectionId {
107 *self.0.as_ref().unwrap().incoming.orig_dst_cid()
108 }
109}
110
111impl Drop for Incoming {
112 fn drop(&mut self) {
113 if let Some(inner) = self.0.take() {
115 inner.endpoint.refuse(inner.incoming);
116 }
117 }
118}
119
120#[derive(Debug, Error)]
123#[error("retry() with validated Incoming")]
124pub struct RetryError(Box<Incoming>);
125
126impl RetryError {
127 pub fn into_incoming(self) -> Incoming {
129 *self.0
130 }
131}
132
133#[derive(Debug)]
135pub struct IncomingFuture(Result<Connecting, ConnectionError>);
136
137impl Future for IncomingFuture {
138 type Output = Result<Connection, ConnectionError>;
139
140 fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
141 match &mut self.0 {
142 Ok(connecting) => connecting.poll_unpin(cx),
143 Err(e) => Poll::Ready(Err(e.clone())),
144 }
145 }
146}
147
148impl IntoFuture for Incoming {
149 type IntoFuture = IncomingFuture;
150 type Output = Result<Connection, ConnectionError>;
151
152 fn into_future(self) -> Self::IntoFuture {
153 IncomingFuture(self.accept())
154 }
155}