ferogram_connect/
socks5.rs1use tokio::net::TcpStream;
14use tokio_socks::tcp::Socks5Stream;
15
16use crate::error::ConnectError;
17
18#[derive(Clone, Debug)]
20pub struct Socks5Config {
21 pub proxy_addr: String,
23 pub auth: Option<(String, String)>,
25}
26
27impl Socks5Config {
28 pub fn new(proxy_addr: impl Into<String>) -> Self {
30 Self {
31 proxy_addr: proxy_addr.into(),
32 auth: None,
33 }
34 }
35
36 pub fn with_auth(
38 proxy_addr: impl Into<String>,
39 username: impl Into<String>,
40 password: impl Into<String>,
41 ) -> Self {
42 Self {
43 proxy_addr: proxy_addr.into(),
44 auth: Some((username.into(), password.into())),
45 }
46 }
47
48 pub async fn connect(&self, target: &str) -> Result<TcpStream, ConnectError> {
50 tracing::info!("[socks5] Connecting via {} -> {target}", self.proxy_addr);
51 let stream = match &self.auth {
52 None => Socks5Stream::connect(self.proxy_addr.as_str(), target)
53 .await
54 .map_err(|e| ConnectError::Io(std::io::Error::other(e)))?,
55 Some((user, pass)) => Socks5Stream::connect_with_password(
56 self.proxy_addr.as_str(),
57 target,
58 user.as_str(),
59 pass.as_str(),
60 )
61 .await
62 .map_err(|e| ConnectError::Io(std::io::Error::other(e)))?,
63 };
64 Ok(stream.into_inner())
65 }
66}