Skip to content

Commit

Permalink
feat: use monoio 0.1.3 and support TCP_FASTOPEN
Browse files Browse the repository at this point in the history
  • Loading branch information
ihciah committed May 11, 2023
1 parent f359305 commit 5454cb4
Show file tree
Hide file tree
Showing 15 changed files with 84 additions and 19 deletions.
12 changes: 5 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions Cargo.toml
Expand Up @@ -7,10 +7,10 @@ license = "MIT/Apache-2.0"
name = "shadow-tls"
readme = "README.md"
repository = "https://github.com/ihciah/shadow-tls"
version = "0.2.21"
version = "0.2.22"

[dependencies]
monoio = { version = "0.1.2" }
monoio = { version = "0.1.3" }
monoio-rustls-fork-shadow-tls = { version = "0.1.1-mod.0" }
rustls-fork-shadow-tls = { version = "0.20.9-mod.2", default-features = false }

Expand All @@ -32,3 +32,6 @@ webpki-roots = "0.22"
[profile.release]
lto = true
opt-level = 3

[patch.crates-io]
monoio = { git = "https://github.com/ihciah/monoio", branch = "tfo-mac" }
1 change: 1 addition & 0 deletions Dockerfile
Expand Up @@ -15,6 +15,7 @@ ENV THREADS=""
ENV PASSWORD=""
ENV ALPN=""
ENV DISABLE_NODELAY=""
ENV FASTOPEN=""
ENV V3=""
ENV STRICT=""

Expand Down
1 change: 1 addition & 0 deletions Dockerfile.action
Expand Up @@ -16,6 +16,7 @@ ENV THREADS=""
ENV PASSWORD=""
ENV ALPN=""
ENV DISABLE_NODELAY=""
ENV FASTOPEN=""
ENV V3=""
ENV STRICT=""

Expand Down
1 change: 1 addition & 0 deletions docker-compose.yml
Expand Up @@ -22,6 +22,7 @@ services:
# ALPN(optional): set alpns(like http/1.1, http/1.1;h2, recommend to leave it blank if you don't know it)
# THREADS(optional): set threads number(recommend to leave it blank)
# DISABLE_NODELAY(optional): disable TCP_NODELAY(recommend to leave it blank)
# FASTOPEN(optional): enable TCP_FASTOPEN
# WILDCARD_SNI: Use sni:443 as handshake server(off/authed/all)

# Note:
Expand Down
5 changes: 5 additions & 0 deletions entrypoint.sh
Expand Up @@ -10,6 +10,11 @@ then
parameter="$parameter --disable-nodelay"
fi

if [ ! -z "$FASTOPEN" ]
then
parameter="$parameter --fastopen"
fi

if [ ! -z "$V3" ]
then
parameter="$parameter --v3"
Expand Down
30 changes: 26 additions & 4 deletions src/client.rs
Expand Up @@ -9,7 +9,7 @@ use byteorder::{BigEndian, WriteBytesExt};
use monoio::{
buf::IoBufMut,
io::{AsyncReadRent, AsyncReadRentExt, AsyncWriteRent, AsyncWriteRentExt, Splitable},
net::TcpStream,
net::{TcpConnectOpts, TcpStream},
};
use monoio_rustls_fork_shadow_tls::TlsConnector;
use rand::{prelude::Distribution, seq::SliceRandom, Rng};
Expand All @@ -34,6 +34,7 @@ pub struct ShadowTlsClient<LA, TA> {
tls_names: Arc<TlsNames>,
password: Arc<String>,
nodelay: bool,
fastopen: bool,
v3: V3Mode,
}

Expand Down Expand Up @@ -110,13 +111,15 @@ impl std::fmt::Display for TlsExtConfig {

impl<LA, TA> ShadowTlsClient<LA, TA> {
/// Create new ShadowTlsClient.
#[allow(clippy::too_many_arguments)]
pub fn new(
listen_addr: LA,
target_addr: TA,
tls_names: TlsNames,
tls_ext_config: TlsExtConfig,
password: String,
nodelay: bool,
fastopen: bool,
v3: V3Mode,
) -> anyhow::Result<Self> {
let mut root_store = RootCertStore::empty();
Expand Down Expand Up @@ -147,6 +150,7 @@ impl<LA, TA> ShadowTlsClient<LA, TA> {
tls_names: Arc::new(tls_names),
password: Arc::new(password),
nodelay,
fastopen,
v3,
})
}
Expand All @@ -157,7 +161,7 @@ impl<LA, TA> ShadowTlsClient<LA, TA> {
LA: std::net::ToSocketAddrs + 'static,
TA: std::net::ToSocketAddrs + 'static,
{
let listener = bind_with_pretty_error(self.listen_addr.as_ref())?;
let listener = bind_with_pretty_error(self.listen_addr.as_ref(), self.fastopen)?;
let shared = Rc::new(self);
loop {
match listener.accept().await {
Expand Down Expand Up @@ -204,7 +208,16 @@ impl<LA, TA> ShadowTlsClient<LA, TA> {
where
TA: std::net::ToSocketAddrs,
{
let mut stream = TcpStream::connect(self.target_addr.as_ref()).await?;
let addr = self
.target_addr
.to_socket_addrs()?
.next()
.ok_or_else(|| std::io::Error::new(std::io::ErrorKind::Other, "empty address"))?;
let mut stream = TcpStream::connect_addr_with_config(
addr,
&TcpConnectOpts::default().tcp_fast_open(self.fastopen),
)
.await?;
mod_tcp_conn(&mut stream, true, self.nodelay);
tracing::debug!("tcp connected, start handshaking");

Expand Down Expand Up @@ -269,7 +282,16 @@ impl<LA, TA> ShadowTlsClient<LA, TA> {
where
TA: std::net::ToSocketAddrs,
{
let mut stream = TcpStream::connect(self.target_addr.as_ref()).await?;
let addr = self
.target_addr
.to_socket_addrs()?
.next()
.ok_or_else(|| std::io::Error::new(std::io::ErrorKind::Other, "empty address"))?;
let mut stream = TcpStream::connect_addr_with_config(
addr,
&TcpConnectOpts::default().tcp_fast_open(self.fastopen),
)
.await?;
mod_tcp_conn(&mut stream, true, self.nodelay);
tracing::debug!("tcp connected, start handshaking");
let stream = HashedReadStream::new(stream, self.password.as_bytes())?;
Expand Down
6 changes: 6 additions & 0 deletions src/lib.rs
Expand Up @@ -22,6 +22,7 @@ pub enum RunningArgs {
tls_ext: TlsExtConfig,
password: String,
nodelay: bool,
fastopen: bool,
v3: V3Mode,
},
Server {
Expand All @@ -30,6 +31,7 @@ pub enum RunningArgs {
tls_addr: TlsAddrs,
password: String,
nodelay: bool,
fastopen: bool,
v3: V3Mode,
},
}
Expand All @@ -45,6 +47,7 @@ impl RunningArgs {
tls_ext,
password,
nodelay,
fastopen,
v3,
} => Ok(Runnable::Client(ShadowTlsClient::new(
listen_addr,
Expand All @@ -53,6 +56,7 @@ impl RunningArgs {
tls_ext,
password,
nodelay,
fastopen,
v3,
)?)),
RunningArgs::Server {
Expand All @@ -61,13 +65,15 @@ impl RunningArgs {
tls_addr,
password,
nodelay,
fastopen,
v3,
} => Ok(Runnable::Server(ShadowTlsServer::new(
listen_addr,
target_addr,
tls_addr,
password,
nodelay,
fastopen,
v3,
))),
}
Expand Down
6 changes: 5 additions & 1 deletion src/main.rs
Expand Up @@ -28,8 +28,10 @@ struct Args {
struct Opts {
#[clap(short, long, help = "Set parallelism manually")]
threads: Option<u8>,
#[clap(short, long, help = "Disable TCP_NODELAY")]
#[clap(long, help = "Disable TCP_NODELAY")]
disable_nodelay: bool,
#[clap(long, help = "Enable TCP_FASTOPEN")]
fastopen: bool,
#[clap(long, help = "Use v3 protocol")]
v3: bool,
#[clap(long, help = "Strict mode(only for v3 protocol)")]
Expand Down Expand Up @@ -126,6 +128,7 @@ impl From<Args> for RunningArgs {
tls_ext: TlsExtConfig::from(alpn),
password,
nodelay: !args.opts.disable_nodelay,
fastopen: args.opts.fastopen,
v3,
},
Commands::Server {
Expand All @@ -142,6 +145,7 @@ impl From<Args> for RunningArgs {
tls_addr,
password,
nodelay: !args.opts.disable_nodelay,
fastopen: args.opts.fastopen,
v3,
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/server.rs
Expand Up @@ -38,6 +38,7 @@ pub struct ShadowTlsServer<LA, TA> {
tls_addr: Arc<TlsAddrs>,
password: Arc<String>,
nodelay: bool,
fastopen: bool,
v3: V3Mode,
}

Expand Down Expand Up @@ -141,6 +142,7 @@ impl<LA, TA> ShadowTlsServer<LA, TA> {
tls_addr: TlsAddrs,
password: String,
nodelay: bool,
fastopen: bool,
v3: V3Mode,
) -> Self {
Self {
Expand All @@ -149,6 +151,7 @@ impl<LA, TA> ShadowTlsServer<LA, TA> {
tls_addr: Arc::new(tls_addr),
password: Arc::new(password),
nodelay,
fastopen,
v3,
}
}
Expand All @@ -161,7 +164,7 @@ impl<LA, TA> ShadowTlsServer<LA, TA> {
LA: std::net::ToSocketAddrs + 'static,
TA: std::net::ToSocketAddrs + 'static,
{
let listener = bind_with_pretty_error(self.listen_addr.as_ref())?;
let listener = bind_with_pretty_error(self.listen_addr.as_ref(), self.fastopen)?;
let shared = Rc::new(self);
loop {
match listener.accept().await {
Expand Down
2 changes: 1 addition & 1 deletion src/sip003.rs
Expand Up @@ -36,7 +36,7 @@ fn index_unescaped(s: &str, term: &[u8]) -> Result<(usize, String), anyhow::Erro

while i < s.len() {
let mut b: u8 = s.as_bytes()[i];
if let Some(..) = term.iter().find(|&&e| b == e) {
if term.iter().any(|&e| b == e) {
break;
}
if b == b'\\' {
Expand Down
10 changes: 7 additions & 3 deletions src/util.rs
Expand Up @@ -10,7 +10,7 @@ use local_sync::oneshot::{Receiver, Sender};
use monoio::{
buf::IoBufMut,
io::{AsyncReadRent, AsyncWriteRent, AsyncWriteRentExt, Splitable},
net::{TcpListener, TcpStream},
net::{ListenerOpts, TcpListener, TcpStream},
};

use hmac::Mac;
Expand Down Expand Up @@ -216,8 +216,12 @@ pub(crate) async fn verified_relay(
}

/// Bind with pretty error.
pub(crate) fn bind_with_pretty_error<A: ToSocketAddrs>(addr: A) -> anyhow::Result<TcpListener> {
TcpListener::bind(addr).map_err(|e| match e.kind() {
pub(crate) fn bind_with_pretty_error<A: ToSocketAddrs>(
addr: A,
fastopen: bool,
) -> anyhow::Result<TcpListener> {
let cfg = ListenerOpts::default().tcp_fast_open(fastopen);
TcpListener::bind_with_config(addr, &cfg).map_err(|e| match e.kind() {
ErrorKind::AddrInUse => {
anyhow::anyhow!("bind failed, check if the port is used: {e}")
}
Expand Down
1 change: 1 addition & 0 deletions tests/sni.rs
Expand Up @@ -36,6 +36,7 @@ async fn sni() {
tls_addr: TlsAddrs::try_from("captive.apple.com").unwrap(),
password: "test".to_string(),
nodelay: true,
fastopen: true,
v3: V3Mode::Strict,
};
server.build().expect("build server failed").start(1);
Expand Down
8 changes: 8 additions & 0 deletions tests/tls12.rs
Expand Up @@ -16,6 +16,7 @@ fn tls12_v2() {
tls_ext: TlsExtConfig::new(None),
password: "test".to_string(),
nodelay: true,
fastopen: true,
v3: V3Mode::Disabled,
};
let server = RunningArgs::Server {
Expand All @@ -24,6 +25,7 @@ fn tls12_v2() {
tls_addr: TlsAddrs::try_from("bing.com").unwrap(),
password: "test".to_string(),
nodelay: true,
fastopen: true,
v3: V3Mode::Disabled,
};
test_ok(client, server, CAPTIVE_HTTP_REQUEST, CAPTIVE_HTTP_RESP);
Expand All @@ -41,6 +43,7 @@ fn tls12_v3_lossy() {
tls_ext: TlsExtConfig::new(None),
password: "test".to_string(),
nodelay: true,
fastopen: true,
v3: V3Mode::Lossy,
};
let server = RunningArgs::Server {
Expand All @@ -49,6 +52,7 @@ fn tls12_v3_lossy() {
tls_addr: TlsAddrs::try_from("bing.com").unwrap(),
password: "test".to_string(),
nodelay: true,
fastopen: true,
v3: V3Mode::Lossy,
};
utils::test_ok(client, server, CAPTIVE_HTTP_REQUEST, CAPTIVE_HTTP_RESP);
Expand All @@ -68,6 +72,7 @@ fn tls12_v3_strict() {
tls_ext: TlsExtConfig::new(None),
password: "test".to_string(),
nodelay: true,
fastopen: true,
v3: V3Mode::Strict,
};
let server = RunningArgs::Server {
Expand All @@ -76,6 +81,7 @@ fn tls12_v3_strict() {
tls_addr: TlsAddrs::try_from("bing.com").unwrap(),
password: "test".to_string(),
nodelay: true,
fastopen: true,
v3: V3Mode::Strict,
};
utils::test_ok(client, server, CAPTIVE_HTTP_REQUEST, CAPTIVE_HTTP_RESP);
Expand All @@ -97,6 +103,7 @@ fn tls12_v2_hijack() {
tls_ext: TlsExtConfig::new(None),
password: "test".to_string(),
nodelay: true,
fastopen: true,
v3: V3Mode::Disabled,
};
test_hijack(client);
Expand All @@ -119,6 +126,7 @@ fn tls12_v3_lossy_hijack() {
tls_ext: TlsExtConfig::new(None),
password: "test".to_string(),
nodelay: true,
fastopen: true,
v3: V3Mode::Lossy,
};
test_hijack(client);
Expand Down

0 comments on commit 5454cb4

Please sign in to comment.