ferogram_connect/
socks5.rs1use tokio::net::TcpStream;
16#[cfg(feature = "socks5")]
17use tokio_socks::tcp::Socks5Stream;
18
19use crate::error::ConnectError;
20
21#[derive(Clone, Debug)]
23pub struct Socks5Config {
24 pub proxy_addr: String,
26 pub auth: Option<(String, String)>,
28}
29
30impl Socks5Config {
31 pub fn new(proxy_addr: impl Into<String>) -> Self {
33 Self {
34 proxy_addr: proxy_addr.into(),
35 auth: None,
36 }
37 }
38
39 pub fn with_auth(
41 proxy_addr: impl Into<String>,
42 username: impl Into<String>,
43 password: impl Into<String>,
44 ) -> Self {
45 Self {
46 proxy_addr: proxy_addr.into(),
47 auth: Some((username.into(), password.into())),
48 }
49 }
50
51 #[cfg(feature = "socks5")]
53 pub async fn connect(&self, target: &str) -> Result<TcpStream, ConnectError> {
54 tracing::debug!(
55 "[ferogram::connect] SOCKS5: relaying through {} to {target}",
56 self.proxy_addr
57 );
58 let stream = match &self.auth {
59 None => Socks5Stream::connect(self.proxy_addr.as_str(), target)
60 .await
61 .map_err(|e| ConnectError::Io(std::io::Error::other(e)))?,
62 Some((user, pass)) => Socks5Stream::connect_with_password(
63 self.proxy_addr.as_str(),
64 target,
65 user.as_str(),
66 pass.as_str(),
67 )
68 .await
69 .map_err(|e| ConnectError::Io(std::io::Error::other(e)))?,
70 };
71 Ok(stream.into_inner())
72 }
73
74 #[cfg(not(feature = "socks5"))]
79 pub async fn connect(&self, _target: &str) -> Result<TcpStream, ConnectError> {
80 Err(ConnectError::Io(std::io::Error::new(
81 std::io::ErrorKind::Unsupported,
82 "SOCKS5 proxy requested but ferogram-connect was built without the \"socks5\" feature",
83 )))
84 }
85}