From 45c041ed2d2cf3f5477ac70d3156410de3c5fd97 Mon Sep 17 00:00:00 2001 From: zephyr Date: Wed, 20 Apr 2022 21:18:25 +0900 Subject: [PATCH] add transport-boost feature flag --- Cargo.lock | 6 ++-- Cargo.toml | 9 ++++-- readme.md | 23 ++++++++------ src/lib.rs | 2 +- src/relay/tcp/mod.rs | 25 +++++++-------- src/relay/tcp/transport.rs | 62 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 96 insertions(+), 31 deletions(-) create mode 100644 src/relay/tcp/transport.rs diff --git a/Cargo.lock b/Cargo.lock index 532831a5..51280b91 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -465,9 +465,9 @@ dependencies = [ [[package]] name = "kaminari" -version = "0.5.7" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d989f3eafc94bd963bd7cc22ca71e3991fe1486bb7ae1b5bbb959f8b839cd6d7" +checksum = "c916164c17dac1db5b54b4a17050474f895ca3676d81ec9fb074292f7ef64d33" dependencies = [ "lazy_static", "lightws", @@ -823,7 +823,7 @@ dependencies = [ [[package]] name = "realm" -version = "2.0.5" +version = "2.1.0" dependencies = [ "bytes", "cfg-if", diff --git a/Cargo.toml b/Cargo.toml index 2268d6e3..f579ff9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "realm" -version = "2.0.5" +version = "2.1.0" authors = ["zhboner "] edition = "2021" @@ -32,7 +32,7 @@ pin-project = "1" lazy_static = "1" # transport -kaminari = { version = "0.5.7", optional = true } +kaminari = { version = "0.6.0", optional = true } # tfo @@ -65,12 +65,15 @@ panic = "abort" opt-level = 0 [features] -default = ["udp", "zero-copy", "trust-dns", "multi-thread", "proxy-protocol", "transport"] +default = ["udp", "zero-copy", "trust-dns", "multi-thread", + "proxy-protocol", "transport", "transport-boost" +] udp = [] tfo = ["tokio-tfo"] zero-copy = [] trust-dns = ["trust-dns-resolver"] transport = ["kaminari"] +transport-boost = [] proxy-protocol = ["haproxy"] multi-thread = ["tokio/rt-multi-thread"] jemalloc = ["jemallocator"] diff --git a/readme.md b/readme.md index 292d0bb0..6046e3ce 100644 --- a/readme.md +++ b/readme.md @@ -49,16 +49,19 @@ cargo build --release ### Build Options -- udp *(enabled by default)* -- trust-dns *(enabled by default)* -- zero-copy *(enabled on linux)* -- transport *(enabled by default)* -- multi-thread *(enabled by default)* -- tfo -- mi-malloc -- jemalloc +- udp: enable udp relay. +- trust-dns: enable trust-dns's async dns resolver. +- zero-copy: enable zero-copy on linux. +- transport: enable ws/tls/wss. +- transport-boost: enable optimizations for transport, at the cost of increasing binary size. +- multi-thread: enable tokio's multi-threaded IO scheduler. +- tfo: enable tcp-fast-open. +- mi-malloc: custom memory allocator. +- jemalloc: custom memory allocator. -See also: `Cargo.toml` +Default: udp + trust-dns + zero-copy + multi-thread + transport + transport-boost. + +See also: `Cargo.toml`. Examples: @@ -67,7 +70,7 @@ Examples: cargo build --release --no-default-features # enable other options -cargo build --release --no-default-features --features udp, tfo, zero-copy, trust-dns +cargo build --release --no-default-features --features udp,tfo,zero-copy,trust-dns.. ``` ### Cross Compile diff --git a/src/lib.rs b/src/lib.rs index 3b05d4f4..6ab8675b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,5 +4,5 @@ pub mod conf; pub mod utils; pub mod relay; -pub const VERSION: &str = "2.0.5"; +pub const VERSION: &str = "2.1.0"; pub const ENV_CONFIG: &str = "REALM_CONF"; diff --git a/src/relay/tcp/mod.rs b/src/relay/tcp/mod.rs index 4a7efe14..599626f7 100644 --- a/src/relay/tcp/mod.rs +++ b/src/relay/tcp/mod.rs @@ -4,6 +4,9 @@ use cfg_if::cfg_if; #[cfg(feature = "proxy-protocol")] mod haproxy; +#[cfg(feature = "transport")] +mod transport; + cfg_if! { if #[cfg(feature = "tfo")] { mod tfo; @@ -16,7 +19,6 @@ cfg_if! { } use std::io::Result; -use futures::try_join; use log::debug; use tokio::net::TcpSocket; @@ -73,16 +75,11 @@ pub async fn connect_and_relay( let res = { #[cfg(feature = "transport")] { - use kaminari::{AsyncAccept, AsyncConnect}; - + use transport::relay_transport; if let Some((ac, cc)) = transport { - let (mut inbound, mut outbound) = - try_join!(ac.accept(inbound), cc.connect(outbound))?; - tokio::io::copy_bidirectional(&mut inbound, &mut outbound) - .await - .map(|_| ()) + relay_transport(inbound, outbound, ac, cc).await } else { - relay_plain(&mut inbound, &mut outbound, *zero_copy).await + relay_plain(inbound, outbound, *zero_copy).await } } #[cfg(not(feature = "transport"))] @@ -99,17 +96,17 @@ pub async fn connect_and_relay( #[inline] async fn relay_plain( - inbound: &mut TcpStream, - outbound: &mut TcpStream, + mut inbound: TcpStream, + mut outbound: TcpStream, zero_copy: bool, ) -> Result<()> { #[cfg(all(target_os = "linux", feature = "zero-copy"))] if zero_copy { - zio::bidi_copy_pipe(inbound, outbound).await + zio::bidi_copy_pipe(&mut inbound, &mut outbound).await } else { - zio::bidi_copy_buffer(inbound, outbound).await + zio::bidi_copy_buffer(&mut inbound, &mut outbound).await } #[cfg(not(all(target_os = "linux", feature = "zero-copy")))] - zio::bidi_copy_buffer(inbound, outbound).await + zio::bidi_copy_buffer(&mut inbound, &mut outbound).await } diff --git a/src/relay/tcp/transport.rs b/src/relay/tcp/transport.rs new file mode 100644 index 00000000..c22917b7 --- /dev/null +++ b/src/relay/tcp/transport.rs @@ -0,0 +1,62 @@ +use std::io::Result; +use futures::try_join; +use tokio::io::copy_bidirectional; +use kaminari::{AsyncAccept, AsyncConnect, IOStream}; +use kaminari::mix::{MixAccept, MixConnect}; + +pub async fn relay_transport( + src: S, + dst: S, + ac: &MixAccept, + cc: &MixConnect, +) -> Result<()> { + macro_rules! hs_relay { + ($ac: expr, $cc: expr) => { + handshake_and_relay(src, dst, $ac, $cc).await + }; + } + + #[cfg(feature = "transport-boost")] + { + use MixConnect::*; + if let Some(ac) = ac.as_plain() { + return match cc { + Plain(cc) => hs_relay!(ac, cc), + Ws(cc) => hs_relay!(ac, cc), + Tls(cc) => hs_relay!(ac, cc), + Wss(cc) => hs_relay!(ac, cc), + }; + } + } + + #[cfg(feature = "transport-boost")] + { + use MixAccept::*; + if let Some(cc) = cc.as_plain() { + return match ac { + Plain(ac) => hs_relay!(ac, cc), + Ws(ac) => hs_relay!(ac, cc), + Tls(ac) => hs_relay!(ac, cc), + Wss(ac) => hs_relay!(ac, cc), + }; + } + } + + hs_relay!(ac, cc) +} + +pub async fn handshake_and_relay( + src: S, + dst: S, + ac: &AC, + cc: &CC, +) -> Result<()> +where + S: IOStream, + AC: AsyncAccept, + CC: AsyncConnect, +{ + let (mut src, mut dst) = try_join!(ac.accept(src), cc.connect(dst))?; + + copy_bidirectional(&mut src, &mut dst).await.map(|_| ()) +}