1use std::{
2 future::{Future, IntoFuture},
3 net::{IpAddr, SocketAddr},
4 pin::Pin,
5 sync::Arc,
6 task::{Context, Poll},
7};
8
9use futures_util::FutureExt;
10use quinn_proto::ServerConfig;
11use thiserror::Error;
12
13use crate::{Connecting, Connection, ConnectionError, EndpointInner};
14
15#[derive(Debug)]
16pub(crate) struct IncomingInner {
17 pub(crate) incoming: quinn_proto::Incoming,
18 pub(crate) endpoint: Arc<EndpointInner>,
19}
20
21#[derive(Debug)]
24pub struct Incoming(Option<IncomingInner>);
25
26impl Incoming {
27 pub(crate) fn new(incoming: quinn_proto::Incoming, endpoint: Arc<EndpointInner>) -> Self {
28 Self(Some(IncomingInner { incoming, endpoint }))
29 }
30
31 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(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
98impl Drop for Incoming {
99 fn drop(&mut self) {
100 if let Some(inner) = self.0.take() {
102 inner.endpoint.refuse(inner.incoming);
103 }
104 }
105}
106
107#[derive(Debug, Error)]
110#[error("retry() with validated Incoming")]
111pub struct RetryError(Incoming);
112
113impl RetryError {
114 pub fn into_incoming(self) -> Incoming {
116 self.0
117 }
118}
119
120#[derive(Debug)]
122pub struct IncomingFuture(Result<Connecting, ConnectionError>);
123
124impl Future for IncomingFuture {
125 type Output = Result<Connection, ConnectionError>;
126
127 fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
128 match &mut self.0 {
129 Ok(connecting) => connecting.poll_unpin(cx),
130 Err(e) => Poll::Ready(Err(e.clone())),
131 }
132 }
133}
134
135impl IntoFuture for Incoming {
136 type IntoFuture = IncomingFuture;
137 type Output = Result<Connection, ConnectionError>;
138
139 fn into_future(self) -> Self::IntoFuture {
140 IncomingFuture(self.accept())
141 }
142}