mirror of https://github.com/telemt/telemt.git
Merge pull request #190 from vladon/feature/socks-hostname-support
feat: add hostname support for SOCKS4/SOCKS5 upstream proxies
This commit is contained in:
commit
d5a7882ad1
|
|
@ -383,9 +383,9 @@ impl UpstreamManager {
|
||||||
Ok(stream)
|
Ok(stream)
|
||||||
},
|
},
|
||||||
UpstreamType::Socks4 { address, interface, user_id } => {
|
UpstreamType::Socks4 { address, interface, user_id } => {
|
||||||
let proxy_addr: SocketAddr = address.parse()
|
// Try to parse as SocketAddr first (IP:port), otherwise treat as hostname:port
|
||||||
.map_err(|_| ProxyError::Config("Invalid SOCKS4 address".to_string()))?;
|
let mut stream = if let Ok(proxy_addr) = address.parse::<SocketAddr>() {
|
||||||
|
// IP:port format - use socket with optional interface binding
|
||||||
let bind_ip = Self::resolve_bind_address(
|
let bind_ip = Self::resolve_bind_address(
|
||||||
interface,
|
interface,
|
||||||
&None,
|
&None,
|
||||||
|
|
@ -403,12 +403,23 @@ impl UpstreamManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
let std_stream: std::net::TcpStream = socket.into();
|
let std_stream: std::net::TcpStream = socket.into();
|
||||||
let mut stream = TcpStream::from_std(std_stream)?;
|
let stream = TcpStream::from_std(std_stream)?;
|
||||||
|
|
||||||
stream.writable().await?;
|
stream.writable().await?;
|
||||||
if let Some(e) = stream.take_error()? {
|
if let Some(e) = stream.take_error()? {
|
||||||
return Err(ProxyError::Io(e));
|
return Err(ProxyError::Io(e));
|
||||||
}
|
}
|
||||||
|
stream
|
||||||
|
} else {
|
||||||
|
// Hostname:port format - use tokio DNS resolution
|
||||||
|
// Note: interface binding is not supported for hostnames
|
||||||
|
if interface.is_some() {
|
||||||
|
warn!("SOCKS4 interface binding is not supported for hostname addresses, ignoring");
|
||||||
|
}
|
||||||
|
TcpStream::connect(address).await
|
||||||
|
.map_err(ProxyError::Io)?
|
||||||
|
};
|
||||||
|
|
||||||
// replace socks user_id with config.selected_scope, if set
|
// replace socks user_id with config.selected_scope, if set
|
||||||
let scope: Option<&str> = Some(config.selected_scope.as_str())
|
let scope: Option<&str> = Some(config.selected_scope.as_str())
|
||||||
.filter(|s| !s.is_empty());
|
.filter(|s| !s.is_empty());
|
||||||
|
|
@ -418,9 +429,9 @@ impl UpstreamManager {
|
||||||
Ok(stream)
|
Ok(stream)
|
||||||
},
|
},
|
||||||
UpstreamType::Socks5 { address, interface, username, password } => {
|
UpstreamType::Socks5 { address, interface, username, password } => {
|
||||||
let proxy_addr: SocketAddr = address.parse()
|
// Try to parse as SocketAddr first (IP:port), otherwise treat as hostname:port
|
||||||
.map_err(|_| ProxyError::Config("Invalid SOCKS5 address".to_string()))?;
|
let mut stream = if let Ok(proxy_addr) = address.parse::<SocketAddr>() {
|
||||||
|
// IP:port format - use socket with optional interface binding
|
||||||
let bind_ip = Self::resolve_bind_address(
|
let bind_ip = Self::resolve_bind_address(
|
||||||
interface,
|
interface,
|
||||||
&None,
|
&None,
|
||||||
|
|
@ -438,12 +449,22 @@ impl UpstreamManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
let std_stream: std::net::TcpStream = socket.into();
|
let std_stream: std::net::TcpStream = socket.into();
|
||||||
let mut stream = TcpStream::from_std(std_stream)?;
|
let stream = TcpStream::from_std(std_stream)?;
|
||||||
|
|
||||||
stream.writable().await?;
|
stream.writable().await?;
|
||||||
if let Some(e) = stream.take_error()? {
|
if let Some(e) = stream.take_error()? {
|
||||||
return Err(ProxyError::Io(e));
|
return Err(ProxyError::Io(e));
|
||||||
}
|
}
|
||||||
|
stream
|
||||||
|
} else {
|
||||||
|
// Hostname:port format - use tokio DNS resolution
|
||||||
|
// Note: interface binding is not supported for hostnames
|
||||||
|
if interface.is_some() {
|
||||||
|
warn!("SOCKS5 interface binding is not supported for hostname addresses, ignoring");
|
||||||
|
}
|
||||||
|
TcpStream::connect(address).await
|
||||||
|
.map_err(ProxyError::Io)?
|
||||||
|
};
|
||||||
|
|
||||||
debug!(config = ?config, "Socks5 connection");
|
debug!(config = ?config, "Socks5 connection");
|
||||||
// replace socks user:pass with config.selected_scope, if set
|
// replace socks user:pass with config.selected_scope, if set
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue