socks5_impl/server/connection/bind.rs
1use crate::protocol::{Address, AsyncStreamOperation, Reply, Response};
2use std::{
3 marker::PhantomData,
4 net::SocketAddr,
5 pin::Pin,
6 task::{Context, Poll},
7 time::Duration,
8};
9use tokio::{
10 io::{AsyncRead, AsyncWrite, AsyncWriteExt, ReadBuf},
11 net::{
12 TcpStream,
13 tcp::{ReadHalf, WriteHalf},
14 },
15};
16
17/// Socks5 command type `Bind`
18///
19/// By [`wait_request`](crate::server::connection::Authenticated::wait_request)
20/// on an [`Authenticated`](crate::server::connection::Authenticated) from SOCKS5 client,
21/// you may get a `Bind<NeedFirstReply>`. After replying the client 2 times
22/// using [`reply()`](crate::server::connection::Bind::reply),
23/// you will get a `Bind<Ready>`, which can be used as a regular async TCP stream.
24///
25/// A `Bind<S>` can be converted to a regular tokio [`TcpStream`](https://docs.rs/tokio/latest/tokio/net/struct.TcpStream.html) by using the `From` trait.
26#[derive(Debug)]
27pub struct Bind<S> {
28 stream: TcpStream,
29 _state: PhantomData<S>,
30}
31
32/// Marker type indicating that the connection needs its first reply.
33#[derive(Debug, Default)]
34pub struct NeedFirstReply;
35
36/// Marker type indicating that the connection needs its second reply.
37#[derive(Debug, Default)]
38pub struct NeedSecondReply;
39
40/// Marker type indicating that the connection is ready to use as a regular TCP stream.
41#[derive(Debug, Default)]
42pub struct Ready;
43
44impl Bind<NeedFirstReply> {
45 #[inline]
46 pub(super) fn new(stream: TcpStream) -> Self {
47 Self {
48 stream,
49 _state: PhantomData,
50 }
51 }
52
53 /// Reply to the SOCKS5 client with the given reply and address.
54 ///
55 /// If encountered an error while writing the reply, the error alongside the original `TcpStream` is returned.
56 pub async fn reply(mut self, reply: Reply, addr: Address) -> std::io::Result<Bind<NeedSecondReply>> {
57 let resp = Response::new(reply, addr);
58 resp.write_to_async_stream(&mut self.stream).await?;
59 Ok(Bind::<NeedSecondReply>::new(self.stream))
60 }
61
62 /// Causes the other peer to receive a read of length 0, indicating that no more data will be sent. This only closes the stream in one direction.
63 #[inline]
64 pub async fn shutdown(&mut self) -> std::io::Result<()> {
65 self.stream.shutdown().await
66 }
67
68 /// Returns the local address that this stream is bound to.
69 #[inline]
70 pub fn local_addr(&self) -> std::io::Result<SocketAddr> {
71 self.stream.local_addr()
72 }
73
74 /// Returns the remote address that this stream is connected to.
75 #[inline]
76 pub fn peer_addr(&self) -> std::io::Result<SocketAddr> {
77 self.stream.peer_addr()
78 }
79
80 /// Reads the linger duration for this socket by getting the `SO_LINGER` option.
81 ///
82 /// For more information about this option, see [`set_linger`](crate::server::connection::Bind::set_linger).
83 #[inline]
84 pub fn linger(&self) -> std::io::Result<Option<Duration>> {
85 self.stream.linger()
86 }
87
88 /// Sets the linger duration of this socket by setting the `SO_LINGER` option.
89 ///
90 /// This option controls the action taken when a stream has unsent messages and the stream is closed.
91 /// If `SO_LINGER` is set, the system shall block the process until it can transmit the data or until the time expires.
92 ///
93 /// If `SO_LINGER` is not specified, and the stream is closed, the system handles the call in a way
94 /// that allows the process to continue as quickly as possible.
95 #[inline]
96 pub fn set_linger(&self, dur: Option<Duration>) -> std::io::Result<()> {
97 self.stream.set_linger(dur)
98 }
99
100 /// Gets the value of the `TCP_NODELAY` option on this socket.
101 ///
102 /// For more information about this option, see [`set_nodelay`](crate::server::connection::Bind::set_nodelay).
103 #[inline]
104 pub fn nodelay(&self) -> std::io::Result<bool> {
105 self.stream.nodelay()
106 }
107
108 /// Sets the value of the `TCP_NODELAY` option on this socket.
109 ///
110 /// If set, this option disables the Nagle algorithm. This means that segments are always sent as soon as possible,
111 /// even if there is only a small amount of data. When not set, data is buffered until there is a sufficient amount to send out,
112 /// thereby avoiding the frequent sending of small packets.
113 pub fn set_nodelay(&self, nodelay: bool) -> std::io::Result<()> {
114 self.stream.set_nodelay(nodelay)
115 }
116
117 /// Gets the value of the `IP_TTL` option for this socket.
118 ///
119 /// For more information about this option, see [`set_ttl`](crate::server::connection::Bind::set_ttl).
120 pub fn ttl(&self) -> std::io::Result<u32> {
121 self.stream.ttl()
122 }
123
124 /// Sets the value for the `IP_TTL` option on this socket.
125 ///
126 /// This value sets the time-to-live field that is used in every packet sent from this socket.
127 pub fn set_ttl(&self, ttl: u32) -> std::io::Result<()> {
128 self.stream.set_ttl(ttl)
129 }
130}
131
132impl Bind<NeedSecondReply> {
133 #[inline]
134 fn new(stream: TcpStream) -> Self {
135 Self {
136 stream,
137 _state: PhantomData,
138 }
139 }
140
141 /// Reply to the SOCKS5 client with the given reply and address.
142 ///
143 /// If encountered an error while writing the reply, the error alongside the original `TcpStream` is returned.
144 pub async fn reply(mut self, reply: Reply, addr: Address) -> Result<Bind<Ready>, (std::io::Error, TcpStream)> {
145 let resp = Response::new(reply, addr);
146
147 if let Err(err) = resp.write_to_async_stream(&mut self.stream).await {
148 return Err((err, self.stream));
149 }
150
151 Ok(Bind::<Ready>::new(self.stream))
152 }
153
154 /// Causes the other peer to receive a read of length 0, indicating that no more data will be sent. This only closes the stream in one direction.
155 #[inline]
156 pub async fn shutdown(&mut self) -> std::io::Result<()> {
157 self.stream.shutdown().await
158 }
159
160 /// Returns the local address that this stream is bound to.
161 #[inline]
162 pub fn local_addr(&self) -> std::io::Result<SocketAddr> {
163 self.stream.local_addr()
164 }
165
166 /// Returns the remote address that this stream is connected to.
167 #[inline]
168 pub fn peer_addr(&self) -> std::io::Result<SocketAddr> {
169 self.stream.peer_addr()
170 }
171
172 /// Reads the linger duration for this socket by getting the `SO_LINGER` option.
173 ///
174 /// For more information about this option, see [`set_linger`](crate::server::connection::Bind::set_linger).
175 #[inline]
176 pub fn linger(&self) -> std::io::Result<Option<Duration>> {
177 self.stream.linger()
178 }
179
180 /// Sets the linger duration of this socket by setting the `SO_LINGER` option.
181 ///
182 /// This option controls the action taken when a stream has unsent messages and the stream is closed.
183 /// If `SO_LINGER` is set, the system shall block the process until it can transmit the data or until the time expires.
184 ///
185 /// If `SO_LINGER` is not specified, and the stream is closed, the system handles the call in a way
186 /// that allows the process to continue as quickly as possible.
187 #[inline]
188 pub fn set_linger(&self, dur: Option<Duration>) -> std::io::Result<()> {
189 self.stream.set_linger(dur)
190 }
191
192 /// Gets the value of the `TCP_NODELAY` option on this socket.
193 ///
194 /// For more information about this option, see
195 /// [`set_nodelay`](crate::server::connection::Bind::set_nodelay).
196 #[inline]
197 pub fn nodelay(&self) -> std::io::Result<bool> {
198 self.stream.nodelay()
199 }
200
201 /// Sets the value of the `TCP_NODELAY` option on this socket.
202 ///
203 /// If set, this option disables the Nagle algorithm. This means that segments are always sent as soon as possible,
204 /// even if there is only a small amount of data. When not set, data is buffered until there is a sufficient amount to send out,
205 /// thereby avoiding the frequent sending of small packets.
206 pub fn set_nodelay(&self, nodelay: bool) -> std::io::Result<()> {
207 self.stream.set_nodelay(nodelay)
208 }
209
210 /// Gets the value of the `IP_TTL` option for this socket.
211 ///
212 /// For more information about this option, see [`set_ttl`](crate::server::connection::Bind::set_ttl).
213 pub fn ttl(&self) -> std::io::Result<u32> {
214 self.stream.ttl()
215 }
216
217 /// Sets the value for the `IP_TTL` option on this socket.
218 ///
219 /// This value sets the time-to-live field that is used in every packet sent from this socket.
220 pub fn set_ttl(&self, ttl: u32) -> std::io::Result<()> {
221 self.stream.set_ttl(ttl)
222 }
223}
224
225impl Bind<Ready> {
226 #[inline]
227 fn new(stream: TcpStream) -> Self {
228 Self {
229 stream,
230 _state: PhantomData,
231 }
232 }
233
234 /// Split the connection into a read and a write half.
235 #[inline]
236 pub fn split(&mut self) -> (ReadHalf, WriteHalf) {
237 self.stream.split()
238 }
239}
240
241impl std::ops::Deref for Bind<Ready> {
242 type Target = TcpStream;
243
244 #[inline]
245 fn deref(&self) -> &Self::Target {
246 &self.stream
247 }
248}
249
250impl std::ops::DerefMut for Bind<Ready> {
251 #[inline]
252 fn deref_mut(&mut self) -> &mut Self::Target {
253 &mut self.stream
254 }
255}
256
257impl AsyncRead for Bind<Ready> {
258 #[inline]
259 fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<std::io::Result<()>> {
260 Pin::new(&mut self.stream).poll_read(cx, buf)
261 }
262}
263
264impl AsyncWrite for Bind<Ready> {
265 #[inline]
266 fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<std::io::Result<usize>> {
267 Pin::new(&mut self.stream).poll_write(cx, buf)
268 }
269
270 #[inline]
271 fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
272 Pin::new(&mut self.stream).poll_flush(cx)
273 }
274
275 #[inline]
276 fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
277 Pin::new(&mut self.stream).poll_shutdown(cx)
278 }
279}
280
281impl<S> From<Bind<S>> for TcpStream {
282 #[inline]
283 fn from(conn: Bind<S>) -> Self {
284 conn.stream
285 }
286}