ptrs/lib.rs
1#![deny(missing_docs)]
2#![doc = include_str!("../README.md")]
3
4use std::{
5 net::{SocketAddrV4, SocketAddrV6},
6 pin::Pin,
7 time::{Duration, Instant},
8};
9
10use futures::Future; // , Sink, TryStream};
11use tokio::io::{AsyncRead, AsyncWrite};
12
13mod error;
14pub use error::Error;
15#[macro_use]
16pub mod args;
17mod helpers;
18pub use helpers::*;
19mod log;
20/// ORPort authentication and connection helpers.
21pub mod orport;
22
23/// Core trait for a pluggable transport, defining its builder types.
24pub trait PluggableTransport<InRW>
25where
26 InRW: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static,
27{
28 /// The client-side builder type for this transport.
29 type ClientBuilder: ClientBuilder<InRW>;
30 /// The server-side builder type for this transport.
31 type ServerBuilder: ServerBuilder<InRW>;
32
33 /// Returns a string identifier for this transport
34 fn name() -> String;
35
36 /// Return a fresh client builder for this transport.
37 fn client_builder() -> <Self as PluggableTransport<InRW>>::ClientBuilder;
38
39 /// Return a fresh server builder for this transport.
40 fn server_builder() -> <Self as PluggableTransport<InRW>>::ServerBuilder;
41}
42
43// ================================================================ //
44// Client //
45// ================================================================ //
46
47/// Client Transport Builder
48// Struct builder, passed by type and then built from default for each client
49// with params baked in as builder pattern.
50pub trait ClientBuilder<InRW>: Default + Clone
51where
52 InRW: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static,
53{
54 /// Error type produced by builder methods.
55 type Error: std::error::Error + Send + Sync;
56 /// The client transport produced by [`build`](ClientBuilder::build).
57 type ClientPT: ClientTransport<InRW, Self::Error>;
58 /// The underlying transport type (used for associated-type matching).
59 type Transport;
60
61 /// Returns a string identifier for this transport
62 fn method_name() -> String;
63
64 /// Builds a new PtCommonParameters.
65 ///
66 /// **Errors**
67 /// If a required field has not been initialized.
68 fn build(&self) -> Self::ClientPT;
69
70 /// Pluggable transport attempts to parse and validate options from a string,
71 /// typically using ['parse_smethod_args'].
72 fn options(&mut self, opts: &args::Args) -> Result<&mut Self, Self::Error>;
73
74 /// A path where the launched PT can store state.
75 fn statefile_location(&mut self, path: &str) -> Result<&mut Self, Self::Error>;
76
77 /// The maximum time we should wait for a pluggable transport binary to
78 /// report successful initialization. If `None`, a default value is used.
79 fn timeout(&mut self, timeout: Option<Duration>) -> Result<&mut Self, Self::Error>;
80
81 /// An IPv4 address to bind outgoing connections to (if specified).
82 ///
83 /// Leaving this out will mean the PT uses a sane default.
84 fn v4_bind_addr(&mut self, addr: SocketAddrV4) -> Result<&mut Self, Self::Error>;
85
86 /// An IPv6 address to bind outgoing connections to (if specified).
87 ///
88 /// Leaving this out will mean the PT uses a sane default.
89 fn v6_bind_addr(&mut self, addr: SocketAddrV6) -> Result<&mut Self, Self::Error>;
90}
91
92/// Client Transport
93pub trait ClientTransport<InRW, InErr>
94where
95 InRW: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static,
96{
97 /// Output stream type produced by the transport.
98 type OutRW: AsyncRead + AsyncWrite + Send + Unpin;
99 /// Error type produced by the transport.
100 type OutErr: std::error::Error + Send + Sync;
101 /// The builder type that creates this transport.
102 type Builder: ClientBuilder<InRW>;
103
104 /// Create a pluggable transport connection given a future that will return
105 /// a Read/Write object that can be used as the underlying socket for the
106 /// connection.
107 fn establish(self, input: Pin<F<InRW, InErr>>) -> Pin<F<Self::OutRW, Self::OutErr>>;
108
109 /// Create a connection for the pluggable transport client using the provided
110 /// (pre-existing/pre-connected) Read/Write object as the underlying socket.
111 fn wrap(self, io: InRW) -> Pin<F<Self::OutRW, Self::OutErr>>;
112
113 /// Returns a string identifier for this transport
114 fn method_name() -> String;
115}
116
117// ================================================================ //
118// Server //
119// ================================================================ //
120
121/// Server Transport
122// try using objects so we can accept and then handshake (proxy equivalent of
123// accept) as separate steps by the transport user.
124pub trait ServerTransport<InRW>
125where
126 InRW: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static,
127{
128 /// Output stream type produced by the server transport.
129 type OutRW: AsyncRead + AsyncWrite + Send + Unpin;
130 /// Error type produced by the server transport.
131 type OutErr: std::error::Error + Send + Sync;
132 /// The builder type that creates this transport.
133 type Builder: ServerBuilder<InRW>;
134
135 /// Create/accept a connection for the pluggable transport client using the
136 /// provided (pre-existing/pre-connected) Read/Write object as the
137 /// underlying socket.
138 ///
139 /// Uses `self` instead of `&self` to encourage/force use of reference
140 /// counted objects (Arc, Rc) for server implementations where the server
141 /// needs internal mutability across multiple threads concurrently.
142 fn reveal(self, io: InRW) -> Pin<F<Self::OutRW, Self::OutErr>>;
143
144 /// Returns a string identifier for this transport
145 fn method_name() -> String;
146}
147
148/// Server Transport builder interface
149pub trait ServerBuilder<InRW>: Default
150where
151 InRW: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static,
152{
153 /// The server transport produced by [`build`](ServerBuilder::build).
154 type ServerPT: ServerTransport<InRW>;
155 /// Error type produced by builder methods.
156 type Error: std::error::Error;
157 /// The underlying transport type (used for associated-type matching).
158 type Transport;
159
160 /// Returns a string identifier for this transport
161 fn method_name() -> String;
162
163 /// Builds a new PtCommonParameters.
164 ///
165 /// **Errors**
166 /// If a required field has not been initialized.
167 fn build(&self) -> Self::ServerPT;
168
169 /// Pluggable transport attempts to parse and validate options from a string,
170 /// typically using ['parse_smethod_args'].
171 fn options(&mut self, opts: &args::Args) -> Result<&mut Self, Self::Error>;
172
173 /// Returns a string or parameters that can be used by a ['ClientBuilder']
174 /// in the `options(...)` function to properly establish a connection with
175 /// this server based on the configuration of the server when this method
176 /// is called.
177 fn get_client_params(&self) -> String;
178
179 /// A path where the launched PT can store state.
180 fn statefile_location(&mut self, path: &str) -> Result<&mut Self, Self::Error>;
181
182 /// The maximum time we should wait for a pluggable transport binary to
183 /// report successful initialization. If `None`, a default value is used.
184 fn timeout(&mut self, timeout: Option<Duration>) -> Result<&mut Self, Self::Error>;
185
186 /// An IPv4 address to bind outgoing connections to (if specified).
187 ///
188 /// Leaving this out will mean the PT uses a sane default.
189 fn v4_bind_addr(&mut self, addr: SocketAddrV4) -> Result<&mut Self, Self::Error>;
190
191 /// An IPv6 address to bind outgoing connections to (if specified).
192 ///
193 /// Leaving this out will mean the PT uses a sane default.
194 fn v6_bind_addr(&mut self, addr: SocketAddrV6) -> Result<&mut Self, Self::Error>;
195}
196
197// ================================================================ //
198// Connections //
199// ================================================================ //
200
201/// Creator1 defines a stream creator that could be applied to either the input
202/// stream feature or the resulting stream future making them composable.
203pub trait Conn {
204 /// Output connection type.
205 type OutRW;
206 /// Error type for the connection future.
207 type OutErr;
208 /// Future that resolves to the connected stream.
209 type Future: Future<Output = Result<Self::OutRW, Self::OutErr>>;
210
211 /// Create a new connection future.
212 fn new() -> Self::Future;
213}
214
215/// In concept this trait provides extended functionality that can be appled to
216/// the client / server traits for creating connections / pluggable transports.
217/// this is still in a TODO state.
218pub trait ConnectExt: Conn {
219 /// Connect with an absolute deadline.
220 fn connect_with_deadline(
221 &mut self,
222 deadline: Instant,
223 ) -> Result<Self::Future, tokio::time::error::Elapsed>;
224 /// Connect with a relative timeout.
225 fn connect_with_timeout(
226 &mut self,
227 timeout: Duration,
228 ) -> Result<Self::Future, tokio::time::error::Elapsed>;
229}
230
231impl Conn for tokio::net::TcpStream {
232 type OutRW = Self;
233 type OutErr = std::io::Error;
234 type Future = Pin<F<Self::OutRW, Self::OutErr>>;
235
236 fn new() -> Self::Future {
237 let f = tokio::net::TcpStream::connect("127.0.0.1:9000");
238 Box::pin(f)
239 }
240}
241
242impl Conn for tokio::net::UdpSocket {
243 type OutErr = std::io::Error;
244 type OutRW = tokio::net::UdpSocket;
245 type Future = Pin<F<Self::OutRW, Self::OutErr>>;
246
247 fn new() -> Self::Future {
248 let f = tokio::net::UdpSocket::bind("127.0.0.1:9000");
249 Box::pin(f)
250 }
251}
252
253/// Future containing a generic result. We use this for functions that take
254/// and/or return futures that will produce Read/Write tunnels once awaited.
255pub type FutureResult<T, E> = Box<dyn Future<Output = Result<T, E>> + Send>;
256
257/// Future containing a generic result, shorthand for ['FutureResult']. We use
258/// this for functions that take and/or return futures that will produce
259/// Read/Write tunnels once awaited.
260pub(crate) type F<T, E> = FutureResult<T, E>;
261
262/// Future resolving to a TCP stream or its error.
263pub type TcpStreamFut = Pin<FutureResult<tokio::net::TcpStream, std::io::Error>>;
264
265/// Future resolving to a UDP socket or its error.
266pub type UdpSocketFut = Pin<FutureResult<tokio::net::UdpSocket, std::io::Error>>;
267
268#[cfg(test)]
269mod passthrough;