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::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 pub fn accept(mut self) -> Result<Connecting, ConnectionError> {
33 let inner = self.0.take().unwrap();
34 Ok(inner.endpoint.accept(inner.incoming, None)?)
35 }
36
37 pub fn accept_with(
43 mut self,
44 server_config: ServerConfig,
45 ) -> Result<Connecting, ConnectionError> {
46 let inner = self.0.take().unwrap();
47 Ok(inner.endpoint.accept(inner.incoming, Some(server_config))?)
48 }
49
50 pub fn refuse(mut self) {
52 let inner = self.0.take().unwrap();
53 inner.endpoint.refuse(inner.incoming);
54 }
55
56 #[allow(clippy::result_large_err)]
61 pub fn retry(mut self) -> Result<(), RetryError> {
62 let inner = self.0.take().unwrap();
63 inner
64 .endpoint
65 .retry(inner.incoming)
66 .map_err(|e| RetryError(Self::new(e.into_incoming(), inner.endpoint)))
67 }
68
69 pub fn ignore(mut self) {
72 let inner = self.0.take().unwrap();
73 inner.endpoint.ignore(inner.incoming);
74 }
75
76 pub fn local_ip(&self) -> Option<IpAddr> {
79 self.0.as_ref().unwrap().incoming.local_ip()
80 }
81
82 pub fn remote_address(&self) -> SocketAddr {
84 self.0.as_ref().unwrap().incoming.remote_address()
85 }
86
87 pub fn remote_address_validated(&self) -> bool {
93 self.0.as_ref().unwrap().incoming.remote_address_validated()
94 }
95}
96
97impl Drop for Incoming {
98 fn drop(&mut self) {
99 if let Some(inner) = self.0.take() {
101 inner.endpoint.refuse(inner.incoming);
102 }
103 }
104}
105
106#[derive(Debug, Error)]
109#[error("retry() with validated Incoming")]
110pub struct RetryError(Incoming);
111
112impl RetryError {
113 pub fn into_incoming(self) -> Incoming {
115 self.0
116 }
117}
118
119#[derive(Debug)]
121pub struct IncomingFuture(Result<Connecting, ConnectionError>);
122
123impl Future for IncomingFuture {
124 type Output = Result<Connection, ConnectionError>;
125
126 fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
127 match &mut self.0 {
128 Ok(connecting) => connecting.poll_unpin(cx),
129 Err(e) => Poll::Ready(Err(e.clone())),
130 }
131 }
132}
133
134impl IntoFuture for Incoming {
135 type IntoFuture = IncomingFuture;
136 type Output = Result<Connection, ConnectionError>;
137
138 fn into_future(self) -> Self::IntoFuture {
139 IncomingFuture(self.accept())
140 }
141}