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