Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
Signed-off-by: Eval EXEC <[email protected]>
  • Loading branch information
eval-exec committed Dec 4, 2024
1 parent d3ebf8f commit 0567306
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 37 deletions.
1 change: 0 additions & 1 deletion tentacle/src/builder.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::{io, sync::Arc, time::Duration};

use crate::service::config::ProxyConfig;
use crate::service::config::TcpSocketConfig;
use nohash_hasher::IntMap;
use tokio_util::codec::LengthDelimitedCodec;

Expand Down
File renamed without changes.
2 changes: 0 additions & 2 deletions tentacle/src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ mod generic_split {
}
}

mod socks5;

mod budget;
pub use budget::*;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use libc::TCP_FASTOPEN_CONNECT;
use shadowsocks_service::local::socks::client::Socks5TcpClient;
pub(crate) mod socks5;
use socks5::Socks5Config;
pub use tokio::{
net::{TcpListener, TcpStream},
spawn,
Expand All @@ -12,8 +12,8 @@ use socket2::{Domain, Protocol as SocketProtocol, Socket, Type};
use std::os::unix::io::{FromRawFd, IntoRawFd};
#[cfg(windows)]
use std::os::windows::io::{FromRawSocket, IntoRawSocket};
use std::{io, net::SocketAddr, pin::Pin};
use tokio::net::{TcpSocket as TokioTcp, ToSocketAddrs};
use std::{io, net::SocketAddr};
use tokio::net::TcpSocket as TokioTcp;

#[cfg(feature = "tokio-timer")]
pub use {
Expand Down Expand Up @@ -120,9 +120,12 @@ pub(crate) async fn connect(
tcp_config: TcpSocketConfig,
) -> io::Result<TcpStream> {
match tcp_config.proxy_config {
Some(proxy_config) => super::socks5::connect(addr, proxy_config.proxy_url)
.await
.map_err(|err| io::Error::new(io::ErrorKind::Other, err)),
Some(proxy_config) => {
let proxy_config: Socks5Config = super::socks5::parse(&proxy_config.proxy_url)?;
super::socks5::connect(addr, proxy_config)
.await
.map_err(|err| io::Error::other(err))
}
None => {
let domain = Domain::for_address(addr);
let socket = Socket::new(domain, Type::STREAM, Some(SocketProtocol::TCP))?;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
use log::{debug, trace};
use std::io;

use log::debug;
use shadowsocks::relay::socks5::{
self, Address, Command, Error as Socks5Error, HandshakeRequest, HandshakeResponse,
PasswdAuthRequest, PasswdAuthResponse, Reply, TcpRequestHeader, TcpResponseHeader,
};
use tokio::{
io::{AsyncRead, AsyncWrite, ReadBuf},
net::{TcpStream, ToSocketAddrs},
};

use crate::service::ProxyConfig;
use tokio::net::TcpStream;

pub(crate) struct Socks5Config {
pub(crate) proxy_url: String,
pub(crate) auth: Option<(String, String)>,
}

// parse proxy url like "socks5://username:password@localhost:1080" to Socks5Config
pub(crate) fn parse(proxy_url: &str) -> Result<Socks5Config, std::error::Error> {
let parsed_url = url::Url::parse(proxy_url)?;
pub(crate) fn parse(proxy_url: &str) -> io::Result<Socks5Config> {
let parsed_url = url::Url::parse(proxy_url).map_err(|err| io::Error::other(err))?;
let scheme = parsed_url.scheme();
match scheme {
"socks5" => {
Expand All @@ -28,28 +25,27 @@ pub(crate) fn parse(proxy_url: &str) -> Result<Socks5Config, std::error::Error>
parsed_url.password().unwrap_or("").to_string(),
)),
};
let proxy_url = parsed_url.host_str().ok_or(Err("missing host"))?;
Ok(Socks5Config {
proxy_url,
auth,
})
let proxy_url = parsed_url
.host_str()
.ok_or(io::Error::other("missing host"))?
.to_string();
Ok(Socks5Config { proxy_url, auth })
}
_ => Err(format!("tentacle doesn't support proxy scheme: {}", scheme).into(),
_ => Err(io::Error::other(format!(
"tentacle doesn't support proxy scheme: {}",
scheme
))),
}
}

pub async fn connect<A, P>(
addr: A,
socks5_config: Socks5Config,
) -> Result<TcpStream, Socks5Error>
pub async fn connect<A>(addr: A, socks5_config: Socks5Config) -> Result<TcpStream, Socks5Error>
where
A: Into<Address>,
P: ToSocketAddrs,
{
debug!("client connecting proxy server");
// destruct socks5_config
let Socks5Config { auth, proxy_url } = socks5_config;

let mut s = TcpStream::connect(proxy_url).await?;

// 1. Handshake
Expand All @@ -70,14 +66,24 @@ where
match hsp.chosen_method {
socks5::SOCKS5_AUTH_METHOD_NONE => (),
socks5::SOCKS5_AUTH_METHOD_PASSWORD => {
let pr = PasswdAuthRequest::new(auth.0, auth.1);
pr.write_to(&mut s).await?;
let prp = PasswdAuthResponse::read_from(&mut s).await?;
match Reply::from_u8(prp.status) {
Reply::Succeeded => debug!("password auth succeeded"),
r => return Err(Socks5Error::Reply(r)),
if let Some((uname, passwd)) = auth {
let pr = PasswdAuthRequest::new(uname, passwd);
pr.write_to(&mut s).await?;
let prp = PasswdAuthResponse::read_from(&mut s).await?;
match Reply::from_u8(prp.status) {
Reply::Succeeded => debug!("password auth succeeded"),
r => return Err(Socks5Error::Reply(r)),
}
} else {
return Err(Socks5Error::PasswdAuthInvalidRequest);
}
}
_ => {
return Err(Socks5Error::IoError(io::Error::other(format!(
"unsupported auth method: {}",
hsp.chosen_method
))))
}
}

// 2. Send request header
Expand Down

0 comments on commit 0567306

Please sign in to comment.