socks5_impl/server/
mod.rs1use std::{
2 net::SocketAddr,
3 task::{Context, Poll},
4};
5use tokio::net::{TcpListener, TcpStream};
6
7pub mod auth;
8pub mod connection;
9
10use crate::protocol::{AsyncStreamOperation, Request};
11pub use crate::{
12 server::auth::{AuthAdaptor, AuthExecutor},
13 server::connection::{
14 ClientConnection, IncomingConnection,
15 associate::{AssociatedUdpSocket, UdpAssociate},
16 bind::Bind,
17 connect::Connect,
18 },
19};
20
21pub struct Server {
28 listener: TcpListener,
29 auth: AuthAdaptor,
30}
31
32impl Server {
33 #[inline]
35 pub fn new(listener: TcpListener, auth: AuthAdaptor) -> Self {
36 Self { listener, auth }
37 }
38
39 #[inline]
41 pub async fn bind(addr: SocketAddr, auth: AuthAdaptor) -> std::io::Result<Self> {
42 Self::bind_with_backlog(addr, auth, 1024).await
43 }
44
45 pub async fn bind_with_backlog(addr: SocketAddr, auth: AuthAdaptor, backlog: u32) -> std::io::Result<Self> {
46 let socket = if addr.is_ipv4() {
47 tokio::net::TcpSocket::new_v4()?
48 } else {
49 tokio::net::TcpSocket::new_v6()?
50 };
51 socket.set_reuseaddr(true)?;
52 socket.bind(addr)?;
53 let listener = socket.listen(backlog)?;
54 Ok(Self::new(listener, auth))
55 }
56
57 #[inline]
62 pub async fn accept(&self) -> std::io::Result<(IncomingConnection, SocketAddr)> {
63 let (stream, addr) = self.listener.accept().await?;
64 Ok((IncomingConnection::new(stream, self.auth.clone()), addr))
65 }
66
67 #[inline]
77 pub fn poll_accept(&self, cx: &mut Context<'_>) -> Poll<std::io::Result<(IncomingConnection, SocketAddr)>> {
78 self.listener
79 .poll_accept(cx)
80 .map_ok(|(stream, addr)| (IncomingConnection::new(stream, self.auth.clone()), addr))
81 }
82
83 #[inline]
85 pub fn local_addr(&self) -> std::io::Result<SocketAddr> {
86 self.listener.local_addr()
87 }
88}
89
90impl From<(TcpListener, AuthAdaptor)> for Server {
91 #[inline]
92 fn from((listener, auth): (TcpListener, AuthAdaptor)) -> Self {
93 Self { listener, auth }
94 }
95}
96
97impl From<Server> for (TcpListener, AuthAdaptor) {
98 #[inline]
99 fn from(server: Server) -> Self {
100 (server.listener, server.auth)
101 }
102}
103
104pub async fn socks5_service_handshake(mut stream: &mut TcpStream, auth: auth::AuthAdaptor) -> std::io::Result<Request> {
105 let request = crate::protocol::handshake::Request::retrieve_from_async_stream(&mut stream).await?;
106 let auth_method = auth.auth_method();
107 let supported = request.evaluate_method(auth_method);
108 let method = if supported {
109 auth_method
110 } else {
111 crate::protocol::AuthMethod::NoAcceptableMethods
112 };
113 let response = crate::protocol::handshake::Response::new(method);
114 response.write_to_async_stream(&mut stream).await?;
115
116 if !supported {
117 return Err(std::io::Error::other("no acceptable SOCKS5 authentication method"));
118 }
119
120 if !auth.execute(stream).await? {
121 return Err(std::io::Error::other("SOCKS5 authentication failed"));
122 }
123
124 let req = crate::protocol::Request::retrieve_from_async_stream(&mut stream).await?;
125 Ok(req)
126}