1use std::{
2 future::{Future, IntoFuture},
3 net::{IpAddr, SocketAddr},
4 pin::Pin,
5 sync::Arc,
6 task::{Context, Poll},
7};
8
9use proto::{ConnectionError, ConnectionId, DecryptedInitial, ServerConfig};
10use thiserror::Error;
11
12use crate::{
13 connection::{Connecting, Connection},
14 endpoint::EndpointRef,
15};
16
17#[derive(Debug)]
19pub struct Incoming(Option<State>);
20
21impl Incoming {
22 pub(crate) fn new(inner: proto::Incoming, endpoint: EndpointRef) -> Self {
23 Self(Some(State { inner, endpoint }))
24 }
25
26 pub fn accept(mut self) -> Result<Connecting, ConnectionError> {
28 let state = self.0.take().unwrap();
29 state.endpoint.accept(state.inner, None)
30 }
31
32 pub fn accept_with(
36 mut self,
37 server_config: Arc<ServerConfig>,
38 ) -> Result<Connecting, ConnectionError> {
39 let state = self.0.take().unwrap();
40 state.endpoint.accept(state.inner, Some(server_config))
41 }
42
43 pub fn refuse(mut self) {
45 let state = self.0.take().unwrap();
46 state.endpoint.refuse(state.inner);
47 }
48
49 pub fn retry(mut self) -> Result<(), RetryError> {
53 let state = self.0.take().unwrap();
54 state.endpoint.retry(state.inner).map_err(|e| {
55 RetryError(Box::new(Self(Some(State {
56 inner: e.into_incoming(),
57 endpoint: state.endpoint,
58 }))))
59 })
60 }
61
62 pub fn ignore(mut self) {
64 let state = self.0.take().unwrap();
65 state.endpoint.ignore(state.inner);
66 }
67
68 pub fn local_ip(&self) -> Option<IpAddr> {
70 self.0.as_ref().unwrap().inner.local_ip()
71 }
72
73 pub fn remote_address(&self) -> SocketAddr {
75 self.0.as_ref().unwrap().inner.remote_address()
76 }
77
78 pub fn remote_address_validated(&self) -> bool {
86 self.0.as_ref().unwrap().inner.remote_address_validated()
87 }
88
89 pub fn may_retry(&self) -> bool {
94 self.0.as_ref().unwrap().inner.may_retry()
95 }
96
97 pub fn orig_dst_cid(&self) -> ConnectionId {
99 self.0.as_ref().unwrap().inner.orig_dst_cid()
100 }
101
102 pub fn decrypt(&self) -> Option<DecryptedInitial> {
108 self.0.as_ref()?.inner.decrypt()
109 }
110}
111
112impl Drop for Incoming {
113 fn drop(&mut self) {
114 if let Some(state) = self.0.take() {
116 state.endpoint.refuse(state.inner);
117 }
118 }
119}
120
121#[derive(Debug)]
122struct State {
123 inner: proto::Incoming,
124 endpoint: EndpointRef,
125}
126
127#[derive(Debug, Error)]
129#[error("retry() with validated Incoming")]
130pub struct RetryError(Box<Incoming>);
131
132impl RetryError {
133 pub fn into_incoming(self) -> Incoming {
135 *self.0
136 }
137}
138
139#[derive(Debug)]
141pub struct IncomingFuture(Result<Connecting, ConnectionError>);
142
143impl Future for IncomingFuture {
144 type Output = Result<Connection, ConnectionError>;
145
146 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
147 match &mut self.0 {
148 Ok(connecting) => Pin::new(connecting).poll(cx),
149 Err(e) => Poll::Ready(Err(e.clone())),
150 }
151 }
152}
153
154impl IntoFuture for Incoming {
155 type Output = Result<Connection, ConnectionError>;
156 type IntoFuture = IncomingFuture;
157
158 fn into_future(self) -> Self::IntoFuture {
159 IncomingFuture(self.accept())
160 }
161}