diff --git a/Cargo.toml b/Cargo.toml index aa8bb7a4..64664167 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -82,10 +82,7 @@ url = "2.5" bytes = "1.0" serde = { version = "1.0", features = ["derive"] } serde_urlencoded = "0.7.1" -tower = { version = "0.5.2", default-features = false, features = [ - "timeout", - "util", -] } +tower = { version = "0.5.2", default-features = false, features = ["timeout","util"] } tower-service = "0.3" futures-util = { version = "0.3.0", default-features = false } sync_wrapper = { version = "1.0", features = ["futures"] } @@ -104,6 +101,8 @@ encoding_rs = { version = "0.8", optional = true } http-body = "1" http-body-util = "0.1" hyper2 = { version = "1.5.0", features = ["http1", "http2", "client"] } +socket2 = { version = "0.5", features = ["all"] } +lru = { version = "0.13", default-features = false } log = "0.4" mime = "0.3.17" percent-encoding = "2.3" @@ -112,10 +111,6 @@ pin-project-lite = "0.2.0" ipnet = "2.11.0" arc-swap = "1.7.0" -## util -socket2 = { version = "0.5", features = ["all"] } -lru = { version = "0.13", default-features = false } - ## boring-tls boring2 = { version = "4.15.2", features = ["pq-experimental", "cert-compression"] } tokio-boring2 = { version = "4.15.2", features = ["pq-experimental"] } diff --git a/src/connect.rs b/src/connect.rs index aeed3ef3..48050dbb 100644 --- a/src/connect.rs +++ b/src/connect.rs @@ -223,7 +223,12 @@ impl ConnectorService { #[cfg(feature = "socks")] async fn connect_socks(&self, mut dst: Dst, proxy: ProxyScheme) -> Result { let dns = match proxy { - ProxyScheme::Socks4 { .. } => socks::DnsResolve::Local, + ProxyScheme::Socks4 { + remote_dns: false, .. + } => socks::DnsResolve::Local, + ProxyScheme::Socks4 { + remote_dns: true, .. + } => socks::DnsResolve::Proxy, ProxyScheme::Socks5 { remote_dns: false, .. } => socks::DnsResolve::Local, @@ -777,7 +782,7 @@ mod socks { } match proxy { - ProxyScheme::Socks4 { addr } => { + ProxyScheme::Socks4 { addr, .. } => { let stream = Socks4Stream::connect(addr, (host.as_str(), port)) .await .map_err(|e| format!("socks connect error: {e}"))?; diff --git a/src/proxy.rs b/src/proxy.rs index fd57801a..d1d317e6 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -106,7 +106,7 @@ pub enum ProxyScheme { host: http::uri::Authority, }, #[cfg(feature = "socks")] - Socks4 { addr: SocketAddr }, + Socks4 { addr: SocketAddr, remote_dns: bool }, #[cfg(feature = "socks")] Socks5 { addr: SocketAddr, @@ -586,7 +586,25 @@ impl ProxyScheme { /// Current SOCKS4 support is provided via blocking IO. #[cfg(feature = "socks")] fn socks4(addr: SocketAddr) -> crate::Result { - Ok(ProxyScheme::Socks4 { addr }) + Ok(ProxyScheme::Socks4 { + addr, + remote_dns: false, + }) + } + + /// Proxy traffic via the specified socket address over SOCKS4A + /// + /// This differs from SOCKS4 in that DNS resolution is also performed via the proxy. + /// + /// # Note + /// + /// Current SOCKS4 support is provided via blocking IO. + #[cfg(feature = "socks")] + fn socks4a(addr: SocketAddr) -> crate::Result { + Ok(ProxyScheme::Socks4 { + addr, + remote_dns: true, + }) } /// Proxy traffic via the specified socket address over SOCKS5 @@ -702,7 +720,7 @@ impl ProxyScheme { let to_addr = || { let addrs = url .socket_addrs(|| match url.scheme() { - "socks4" | "socks5" | "socks5h" => Some(1080), + "socks4" | "socks4a" | "socks5" | "socks5h" => Some(1080), _ => None, }) .map_err(crate::error::builder)?; @@ -718,6 +736,8 @@ impl ProxyScheme { #[cfg(feature = "socks")] "socks4" => Self::socks4(to_addr()?)?, #[cfg(feature = "socks")] + "socks4a" => Self::socks4a(to_addr()?)?, + #[cfg(feature = "socks")] "socks5" => Self::socks5(to_addr()?)?, #[cfg(feature = "socks")] "socks5h" => Self::socks5h(to_addr()?)?, @@ -740,8 +760,9 @@ impl fmt::Debug for ProxyScheme { ProxyScheme::Http { auth: _auth, host } => write!(f, "http://{}", host), ProxyScheme::Https { auth: _auth, host } => write!(f, "https://{}", host), #[cfg(feature = "socks")] - ProxyScheme::Socks4 { addr } => { - write!(f, "socks4://{addr}") + ProxyScheme::Socks4 { addr, remote_dns } => { + let h = if *remote_dns { "a" } else { "" }; + write!(f, "socks4{}://{}", h, addr) } #[cfg(feature = "socks")] ProxyScheme::Socks5 {