Skip to content

Commit

Permalink
support TFO on Linux, FreeBSD, macOS and Windows
Browse files Browse the repository at this point in the history
- ref #184
  • Loading branch information
zonyitoo committed Apr 11, 2021
1 parent 468207e commit ffee22c
Show file tree
Hide file tree
Showing 35 changed files with 1,808 additions and 672 deletions.
22 changes: 20 additions & 2 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,16 @@ jobs:
profile: minimal
- name: Build & Test (Default)
run: cargo test --verbose --no-fail-fast
- name: Build & Test (Default) - shadowsocks
run: cargo test --manifest-path ./crates/shadowsocks/Cargo.toml --verbose --no-fail-fast
- name: Build & Test (--no-default-features)
run: cargo test --verbose --no-default-features --no-fail-fast
- name: Build & Test (--no-default-features) - shadowsocks
run: cargo test --manifest-path ./crates/shadowsocks/Cargo.toml --verbose --no-default-features --no-fail-fast
- name: Build with All Features Enabled
run: cargo build --verbose --features "local-redir local-dns dns-over-tls dns-over-https stream-cipher"
run: cargo build --verbose --features "local-dns dns-over-tls dns-over-https stream-cipher"
- name: Build with All Features Enabled - shadowsocks
run: cargo build --manifest-path ./crates/shadowsocks/Cargo.toml --verbose --features "stream-cipher"

build-windows:
runs-on: windows-latest
Expand All @@ -53,10 +59,16 @@ jobs:
profile: minimal
- name: Build & Test (Default)
run: cargo test --verbose --no-fail-fast
- name: Build & Test (Default) - shadowsocks
run: cargo test --manifest-path ./crates/shadowsocks/Cargo.toml --verbose --no-fail-fast
- name: Build & Test (--no-default-features)
run: cargo test --verbose --no-default-features --no-fail-fast
- name: Build & Test (--no-default-features) - shadowsocks
run: cargo test --manifest-path ./crates/shadowsocks/Cargo.toml --verbose --no-default-features --no-fail-fast
- name: Build with All Features Enabled
run: cargo build --verbose --features "local-dns dns-over-tls dns-over-https stream-cipher"
- name: Build with All Features Enabled - shadowsocks
run: cargo build --manifest-path ./crates/shadowsocks/Cargo.toml --verbose --features "stream-cipher"

build-macos:
runs-on: macos-latest
Expand All @@ -81,7 +93,13 @@ jobs:
profile: minimal
- name: Build & Test (Default)
run: cargo test --verbose --no-fail-fast
- name: Build & Test (Default) - shadowsocks
run: cargo test --manifest-path ./crates/shadowsocks/Cargo.toml --verbose --no-fail-fast
- name: Build & Test (--no-default-features)
run: cargo test --verbose --no-default-features --no-fail-fast
- name: Build & Test (--no-default-features) - shadowsocks
run: cargo test --manifest-path ./crates/shadowsocks/Cargo.toml --verbose --no-default-features --no-fail-fast
- name: Build with All Features Enabled
run: cargo build --verbose --features "local-redir local-dns dns-over-tls dns-over-https stream-cipher"
run: cargo build --verbose --features "local-dns dns-over-tls dns-over-https stream-cipher"
- name: Build with All Features Enabled - shadowsocks
run: cargo build --manifest-path ./crates/shadowsocks/Cargo.toml --verbose --features "stream-cipher"
48 changes: 23 additions & 25 deletions Cargo.lock

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

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "shadowsocks-rust"
version = "1.10.5"
version = "1.11.0"
authors = ["Shadowsocks Contributors"]
description = "shadowsocks is a fast tunnel proxy that helps you bypass firewalls."
repository = "https://github.com/shadowsocks/shadowsocks-rust"
Expand Down Expand Up @@ -132,3 +132,6 @@ byteorder = "1.3"
env_logger = "0.8"
byte_string = "1.0"
tokio = { version = "1", features = ["net", "time", "macros", "io-util"]}

[patch.crates-io]
tokio = { git = "https://github.com/tokio-rs/tokio.git", features = ["full"] }
7 changes: 6 additions & 1 deletion bin/sslocal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ fn main() {
(@arg DNS: --dns +takes_value "DNS nameservers, formatted like [(tcp|udp)://]host[:port][,host[:port]]..., or unix:///path/to/dns, or predefined keys like \"google\", \"cloudflare\"")

(@arg TCP_NO_DELAY: --("tcp-no-delay") !takes_value alias("no-delay") "Set TCP_NODELAY option for socket")
(@arg TCP_FAST_OPEN: --("tcp-fast-open") !takes_value alias("fast-open") "Enable TCP Fast Open (TFO)")

(@arg UDP_TIMEOUT: --("udp-timeout") +takes_value {validator::validate_u64} "Timeout seconds for UDP relay")
(@arg UDP_MAX_ASSOCIATIONS: --("udp-max-associations") +takes_value {validator::validate_u64} "Maximum associations to be kept simultaneously for UDP relay")
Expand Down Expand Up @@ -339,14 +340,18 @@ fn main() {
config.no_delay = true;
}

if matches.is_present("TCP_FAST_OPEN") {
config.fast_open = true;
}

#[cfg(any(target_os = "linux", target_os = "android"))]
if let Some(mark) = matches.value_of("OUTBOUND_FWMARK") {
config.outbound_fwmark = Some(mark.parse::<u32>().expect("an unsigned integer for `outbound-fwmark`"));
}

#[cfg(any(target_os = "linux", target_os = "android", target_os = "macos", target_os = "ios"))]
if let Some(iface) = matches.value_of("OUTBOUND_BIND_INTERFACE") {
config.outbound_bind_interface = Some(From::from(iface.to_owned()));
config.outbound_bind_interface = Some(iface.to_owned());
}

if let Some(nofile) = matches.value_of("NOFILE") {
Expand Down
9 changes: 7 additions & 2 deletions bin/ssmanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ fn main() {
(@arg DNS: --dns +takes_value "DNS nameservers, formatted like [(tcp|udp)://]host[:port][,host[:port]]..., or unix:///path/to/dns, or predefined keys like \"google\", \"cloudflare\"")

(@arg TCP_NO_DELAY: --("tcp-no-delay") !takes_value alias("no-delay") "Set TCP_NODELAY option for socket")
(@arg TCP_FAST_OPEN: --("tcp-fast-open") !takes_value alias("fast-open") "Enable TCP Fast Open (TFO)")

(@arg UDP_TIMEOUT: --("udp-timeout") +takes_value {validator::validate_u64} "Timeout seconds for UDP relay")
(@arg UDP_MAX_ASSOCIATIONS: --("udp-max-associations") +takes_value {validator::validate_u64} "Maximum associations to be kept simultaneously for UDP relay")
Expand Down Expand Up @@ -147,14 +148,18 @@ fn main() {
config.no_delay = true;
}

if matches.is_present("TCP_FAST_OPEN") {
config.fast_open = true;
}

#[cfg(any(target_os = "linux", target_os = "android"))]
if let Some(mark) = matches.value_of("OUTBOUND_FWMARK") {
config.outbound_fwmark = Some(mark.parse::<u32>().expect("an unsigned integer for `outbound-fwmark`"));
}

#[cfg(any(target_os = "linux", target_os = "android"))]
#[cfg(any(target_os = "linux", target_os = "android", target_os = "macos", target_os = "ios"))]
if let Some(iface) = matches.value_of("OUTBOUND_BIND_INTERFACE") {
config.outbound_bind_interface = Some(From::from(iface.to_owned()));
config.outbound_bind_interface = Some(iface.to_owned());
}

if let Some(m) = matches.value_of("MANAGER_ADDRESS") {
Expand Down
9 changes: 7 additions & 2 deletions bin/ssserver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ fn main() {
(@arg DNS: --dns +takes_value "DNS nameservers, formatted like [(tcp|udp)://]host[:port][,host[:port]]..., or unix:///path/to/dns, or predefined keys like \"google\", \"cloudflare\"")

(@arg TCP_NO_DELAY: --("tcp-no-delay") !takes_value alias("no-delay") "Set TCP_NODELAY option for socket")
(@arg TCP_FAST_OPEN: --("tcp-fast-open") !takes_value alias("fast-open") "Enable TCP Fast Open (TFO)")

(@arg UDP_TIMEOUT: --("udp-timeout") +takes_value {validator::validate_u64} "Timeout seconds for UDP relay")
(@arg UDP_MAX_ASSOCIATIONS: --("udp-max-associations") +takes_value {validator::validate_u64} "Maximum associations to be kept simultaneously for UDP relay")
Expand Down Expand Up @@ -187,14 +188,18 @@ fn main() {
config.no_delay = true;
}

if matches.is_present("TCP_FAST_OPEN") {
config.fast_open = true;
}

#[cfg(any(target_os = "linux", target_os = "android"))]
if let Some(mark) = matches.value_of("OUTBOUND_FWMARK") {
config.outbound_fwmark = Some(mark.parse::<u32>().expect("an unsigned integer for `outbound-fwmark`"));
}

#[cfg(any(target_os = "linux", target_os = "android"))]
#[cfg(any(target_os = "linux", target_os = "android", target_os = "macos", target_os = "ios"))]
if let Some(iface) = matches.value_of("OUTBOUND_BIND_INTERFACE") {
config.outbound_bind_interface = Some(From::from(iface.to_owned()));
config.outbound_bind_interface = Some(iface.to_owned());
}

if let Some(m) = matches.value_of("MANAGER_ADDRESS") {
Expand Down
2 changes: 1 addition & 1 deletion crates/shadowsocks-service/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "shadowsocks-service"
version = "1.10.4"
version = "1.11.0"
authors = ["Shadowsocks Contributors"]
description = "shadowsocks is a fast tunnel proxy that helps you bypass firewalls."
repository = "https://github.com/shadowsocks/shadowsocks-rust"
Expand Down
22 changes: 18 additions & 4 deletions crates/shadowsocks-service/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
//!
//! These defined server will be used with a load balancing algorithm.

#[cfg(any(target_os = "linux", target_os = "android", target_os = "macos", target_os = "ios"))]
use std::ffi::OsString;
#[cfg(any(unix, features = "local-flow-stat"))]
use std::path::PathBuf;
use std::{
convert::{From, Infallible},
default::Default,
Expand All @@ -51,7 +51,7 @@ use std::{
io::Read,
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
option::Option,
path::{Path, PathBuf},
path::Path,
str::FromStr,
string::ToString,
time::Duration,
Expand Down Expand Up @@ -127,6 +127,8 @@ struct SSConfig {
nofile: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
ipv6_first: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
fast_open: Option<bool>,
}

#[derive(Serialize, Deserialize, Debug, Default)]
Expand Down Expand Up @@ -717,6 +719,8 @@ pub struct Config {

/// Set `TCP_NODELAY` socket option
pub no_delay: bool,
/// Set `TCP_FASTOPEN` socket option
pub fast_open: bool,
/// `RLIMIT_NOFILE` option for *nix systems
pub nofile: Option<u64>,

Expand All @@ -725,7 +729,7 @@ pub struct Config {
pub outbound_fwmark: Option<u32>,
/// Set `SO_BINDTODEVICE` socket option for outbound sockets
#[cfg(any(target_os = "linux", target_os = "android", target_os = "macos", target_os = "ios"))]
pub outbound_bind_interface: Option<OsString>,
pub outbound_bind_interface: Option<String>,
/// Path to protect callback unix address, only for Android
#[cfg(target_os = "android")]
pub outbound_vpn_protect_path: Option<PathBuf>,
Expand Down Expand Up @@ -829,6 +833,7 @@ impl Config {
ipv6_first: false,

no_delay: false,
fast_open: false,
nofile: None,

#[cfg(any(target_os = "linux", target_os = "android"))]
Expand Down Expand Up @@ -1275,6 +1280,11 @@ impl Config {
nconfig.no_delay = b;
}

// TCP fast open
if let Some(b) = config.fast_open {
nconfig.fast_open = b;
}

// UDP
nconfig.udp_timeout = config.udp_timeout.map(Duration::from_secs);

Expand Down Expand Up @@ -1758,6 +1768,10 @@ impl fmt::Display for Config {
jconf.no_delay = Some(self.no_delay);
}

if self.fast_open {
jconf.fast_open = Some(self.fast_open);
}

match self.dns {
DnsConfig::System => {}
#[cfg(feature = "trust-dns")]
Expand Down
Loading

0 comments on commit ffee22c

Please sign in to comment.