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> {
107 self.0.as_ref()?.inner.decrypt()
108 }
109}
110
111impl Drop for Incoming {
112 fn drop(&mut self) {
113 if let Some(state) = self.0.take() {
115 state.endpoint.refuse(state.inner);
116 }
117 }
118}
119
120#[derive(Debug)]
121struct State {
122 inner: proto::Incoming,
123 endpoint: EndpointRef,
124}
125
126#[derive(Debug, Error)]
128#[error("retry() with validated Incoming")]
129pub struct RetryError(Box<Incoming>);
130
131impl RetryError {
132 pub fn into_incoming(self) -> Incoming {
134 *self.0
135 }
136}
137
138#[derive(Debug)]
140pub struct IncomingFuture(Result<Connecting, ConnectionError>);
141
142impl Future for IncomingFuture {
143 type Output = Result<Connection, ConnectionError>;
144
145 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
146 match &mut self.0 {
147 Ok(connecting) => Pin::new(connecting).poll(cx),
148 Err(e) => Poll::Ready(Err(e.clone())),
149 }
150 }
151}
152
153impl IntoFuture for Incoming {
154 type Output = Result<Connection, ConnectionError>;
155 type IntoFuture = IncomingFuture;
156
157 fn into_future(self) -> Self::IntoFuture {
158 IncomingFuture(self.accept())
159 }
160}