From ba8e07e7694344a7d8f38fc7152ea9f75adc90fa Mon Sep 17 00:00:00 2001 From: zonyitoo Date: Fri, 24 May 2024 23:10:03 +0800 Subject: [PATCH] feat: local-tun compilable for not-supported platforms - Prepare for v1.19.0 release. Upgraded MSRV to 1.74 - "default" build feature now contains only basic shadowsocks features (BREAKING) - Add "full" build feature for all suggested features - Add "full-extra" build feature for including *-extra features --- .github/workflows/build-and-test.yml | 10 +- .github/workflows/build-msrv.yml | 6 +- .github/workflows/build-nightly-release.yml | 10 +- .github/workflows/build-release.yml | 10 +- .github/workflows/clippy-check.yml | 9 +- Cargo.lock | 34 ++--- Cargo.toml | 34 ++++- Dockerfile | 4 +- clippy.toml | 1 + crates/shadowsocks-service/Cargo.toml | 8 +- .../src/local/fake_dns/manager.rs | 11 +- .../src/local/tun/fake_tun.rs | 144 ++++++++++++++++++ .../shadowsocks-service/src/local/tun/mod.rs | 21 ++- .../src/local/tun/sys/others.rs | 6 + .../src/local/tun/sys/unix/android.rs | 7 +- .../src/local/tun/sys/unix/apple/macos.rs | 9 +- .../src/local/tun/sys/unix/apple/others.rs | 7 +- .../src/local/tun/sys/unix/bsd.rs | 7 +- .../src/local/tun/sys/unix/linux.rs | 7 +- .../src/local/tun/sys/windows/mod.rs | 7 +- crates/shadowsocks/Cargo.toml | 4 +- snap/snapcraft.yaml | 5 +- src/service/local.rs | 8 +- 23 files changed, 289 insertions(+), 80 deletions(-) create mode 100644 clippy.toml create mode 100644 crates/shadowsocks-service/src/local/tun/fake_tun.rs create mode 100644 crates/shadowsocks-service/src/local/tun/sys/others.rs diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 9235856e..01699cbb 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -33,6 +33,10 @@ jobs: rustup override set stable - name: Build & Test (Default) run: cargo test --verbose --no-fail-fast + - name: Build & Test (full) + run: cargo test --features "full" --verbose --no-fail-fast + - name: Build & Test (full-extra) + run: cargo test --features "full-extra" --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) @@ -41,9 +45,9 @@ jobs: run: cargo test --manifest-path ./crates/shadowsocks/Cargo.toml --verbose --no-default-features --no-fail-fast - name: Build with All Features Enabled (Unix) if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }} - run: cargo build --verbose --features "local-http-rustls local-redir local-dns local-tun local-online-config dns-over-tls dns-over-https stream-cipher aead-cipher-extra aead-cipher-2022 aead-cipher-2022-extra security-replay-attack-detect" + run: cargo build --verbose --features "full-extra local-flow-stat utility-url-outline" - name: Build with All Features Enabled (Windows) if: ${{ runner.os == 'Windows' }} - run: cargo build --verbose --features "local-http-rustls local-dns local-tun local-online-config dns-over-tls dns-over-https stream-cipher aead-cipher-extra aead-cipher-2022 aead-cipher-2022-extra security-replay-attack-detect winservice" + run: cargo build --verbose --features "full-extra local-flow-stat utility-url-outline winservice" - name: Build with All Features Enabled - shadowsocks - run: cargo build --manifest-path ./crates/shadowsocks/Cargo.toml --verbose --features "stream-cipher aead-cipher-2022" + run: cargo build --manifest-path ./crates/shadowsocks/Cargo.toml --verbose --features "stream-cipher aead-cipher-extra aead-cipher-2022 aead-cipher-2022-extra security-replay-attack-detect" diff --git a/.github/workflows/build-msrv.yml b/.github/workflows/build-msrv.yml index 44dee776..760dbc40 100644 --- a/.github/workflows/build-msrv.yml +++ b/.github/workflows/build-msrv.yml @@ -28,9 +28,9 @@ jobs: - name: Install Rust run: | rustup set profile minimal - rustup toolchain install 1.71 - rustup default 1.71 - rustup override set 1.71 + rustup toolchain install 1.74 + rustup default 1.74 + rustup override set 1.74 - name: Build with All Features Enabled (Unix) if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }} run: cargo build --verbose --features "local-http-rustls local-redir local-dns local-tun local-online-config dns-over-tls dns-over-https stream-cipher aead-cipher-extra aead-cipher-2022 aead-cipher-2022-extra security-replay-attack-detect" diff --git a/.github/workflows/build-nightly-release.yml b/.github/workflows/build-nightly-release.yml index cbdf9901..ee8e2bd2 100644 --- a/.github/workflows/build-nightly-release.yml +++ b/.github/workflows/build-nightly-release.yml @@ -38,12 +38,10 @@ jobs: run: | compile_target=${{ matrix.target }} - if [[ "$compile_target" == *"-linux-"* || "$compile_target" == *"-apple-"* ]]; then - compile_features="-f local-redir -f local-tun" - fi + compile_features="-f full" if [[ "$compile_target" == *"-windows-"* ]]; then - compile_features="-f winservice -f local-tun" + compile_features="$compile_features -f winservice" fi if [[ "$compile_target" == "mips-"* || "$compile_target" == "mipsel-"* || "$compile_target" == "mips64-"* || "$compile_target" == "mips64el-"* ]]; then @@ -65,7 +63,7 @@ jobs: build-unix: runs-on: ${{ matrix.os }} env: - BUILD_EXTRA_FEATURES: "local-redir local-tun" + BUILD_EXTRA_FEATURES: "full" RUST_BACKTRACE: full strategy: fail-fast: false @@ -129,7 +127,7 @@ jobs: - name: Build release run: | - pwsh ./build/build-host-release.ps1 "winservice local-tun" + pwsh ./build/build-host-release.ps1 "full winservice" - name: Upload Artifacts uses: actions/upload-artifact@v4 diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index bf824f38..cc9eeb3a 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -54,12 +54,10 @@ jobs: run: | compile_target=${{ matrix.target }} - if [[ "$compile_target" == *"-linux-"* || "$compile_target" == *"-apple-"* ]]; then - compile_features="-f local-redir -f local-tun" - fi + compile_features="-f full" if [[ "$compile_target" == *"-windows-"* ]]; then - compile_features="-f winservice -f local-tun" + compile_features="$compile_features -f winservice" fi if [[ "$compile_target" == "mips-"* || "$compile_target" == "mipsel-"* || "$compile_target" == "mips64-"* || "$compile_target" == "mips64el-"* ]]; then @@ -84,7 +82,7 @@ jobs: build-unix: runs-on: ${{ matrix.os }} env: - BUILD_EXTRA_FEATURES: "local-redir local-tun" + BUILD_EXTRA_FEATURES: "full" RUST_BACKTRACE: full strategy: fail-fast: false @@ -152,7 +150,7 @@ jobs: - name: Build release run: | - pwsh ./build/build-host-release.ps1 "winservice local-tun" + pwsh ./build/build-host-release.ps1 "full winservice" - name: Upload Github Assets uses: softprops/action-gh-release@v1 diff --git a/.github/workflows/clippy-check.yml b/.github/workflows/clippy-check.yml index e18fe54d..214bc662 100644 --- a/.github/workflows/clippy-check.yml +++ b/.github/workflows/clippy-check.yml @@ -32,16 +32,11 @@ jobs: - name: Install Rust run: | rustup set profile minimal - rustup toolchain install nightly --component clippy - rustup default nightly - rustup override set nightly + rustup toolchain install stable --component clippy - name: Clippy Check uses: actions-rs/clippy-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} args: | - --features "local-http-rustls local-redir local-flow-stat local-dns local-tun local-fake-dns local-online-config dns-over-tls dns-over-https stream-cipher aead-cipher-2022" -- -Z macro-backtrace - -W clippy::absurd_extreme_comparisons - -W clippy::erasing_op - -A clippy::collapsible_else_if + --features "full-extra local-flow-stat utility-url-outline" name: clippy ${{ matrix.platform }} diff --git a/Cargo.lock b/Cargo.lock index f9a29f97..2241ff84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -428,9 +428,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cfg_aliases" -version = "0.1.1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chacha20" @@ -492,18 +492,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.18" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.4.18" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", @@ -514,9 +514,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "cmake" @@ -1700,9 +1700,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.154" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" @@ -1925,9 +1925,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ "bitflags 2.5.0", "cfg-if", @@ -3071,7 +3071,7 @@ dependencies = [ [[package]] name = "shadowsocks" -version = "1.18.3" +version = "1.19.0" dependencies = [ "aes", "arc-swap", @@ -3137,7 +3137,7 @@ dependencies = [ [[package]] name = "shadowsocks-rust" -version = "1.18.5" +version = "1.19.0" dependencies = [ "base64 0.22.1", "build-time", @@ -3178,7 +3178,7 @@ dependencies = [ [[package]] name = "shadowsocks-service" -version = "1.18.5" +version = "1.19.0" dependencies = [ "arc-swap", "async-trait", @@ -3379,9 +3379,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" diff --git a/Cargo.toml b/Cargo.toml index b0b2599f..70738fd6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "shadowsocks-rust" -version = "1.18.5" +version = "1.19.0" authors = ["Shadowsocks Contributors"] description = "shadowsocks is a fast tunnel proxy that helps you bypass firewalls." repository = "https://github.com/shadowsocks/shadowsocks-rust" @@ -9,7 +9,7 @@ documentation = "https://docs.rs/shadowsocks-rust" keywords = ["shadowsocks", "proxy", "socks", "socks5", "firewall"] license = "MIT" edition = "2021" -rust-version = "1.71" +rust-version = "1.74" [badges] maintenance = { status = "passively-maintained" } @@ -55,21 +55,45 @@ panic = "abort" strip = true [features] -default = [ +default = ["basic"] + +# Basic Features +basic = ["logging", "hickory-dns", "local", "server", "multi-threaded"] + +# All Suggested Features +full = [ "logging", "hickory-dns", + "dns-over-tls", + "dns-over-https", + "dns-over-h3", "local", "server", "manager", "utility", "service", "local-http", + "local-http-rustls", "local-tunnel", "local-socks4", + "local-dns", + "local-redir", + "local-tun", + "local-fake-dns", + "local-online-config", "multi-threaded", + "stream-cipher", "aead-cipher-2022", ] +# Full features with extra (non-stable) +full-extra = [ + "full", + "aead-cipher-extra", + "aead-cipher-2022-extra", + "security-replay-attack-detect", +] + # Enable local server local = ["shadowsocks-service/local"] # Enable remote server @@ -188,7 +212,7 @@ json5 = "0.4" thiserror = "1.0" base64 = "0.22" -clap = { version = "~4.4", features = ["wrap_help", "suggestions"] } +clap = { version = "4.5", features = ["wrap_help", "suggestions"] } cfg-if = "1" qrcode = { version = "0.14", default-features = false, optional = true } sysexits = "0.7" @@ -211,7 +235,7 @@ jemallocator = { version = "0.5", optional = true } snmalloc-rs = { version = "0.3", optional = true } rpmalloc = { version = "0.2", optional = true } -shadowsocks-service = { version = "1.18.5", path = "./crates/shadowsocks-service" } +shadowsocks-service = { version = "1.19.0", path = "./crates/shadowsocks-service" } windows-service = { version = "0.7", optional = true } diff --git a/Dockerfile b/Dockerfile index 0297c7e3..12c0cc72 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ FROM --platform=$BUILDPLATFORM rust:1.67.1-alpine3.17 AS builder ARG TARGETARCH RUN set -x \ - && apk add --no-cache build-base + && apk add --no-cache build-base protoc WORKDIR /root/shadowsocks-rust @@ -33,7 +33,7 @@ RUN case "$TARGETARCH" in \ && echo "CC=$CC" \ && rustup override set stable \ && rustup target add "$RUST_TARGET" \ - && RUSTFLAGS="-C linker=$CC" CC=$CC cargo build --target "$RUST_TARGET" --release --features "local-tun local-redir stream-cipher aead-cipher-2022" \ + && RUSTFLAGS="-C linker=$CC" CC=$CC cargo build --target "$RUST_TARGET" --release --features "full" \ && mv target/$RUST_TARGET/release/ss* target/release/ FROM alpine:3.17 AS sslocal diff --git a/clippy.toml b/clippy.toml new file mode 100644 index 00000000..866add68 --- /dev/null +++ b/clippy.toml @@ -0,0 +1 @@ +msrv = "1.74" diff --git a/crates/shadowsocks-service/Cargo.toml b/crates/shadowsocks-service/Cargo.toml index 15ec1053..1297f20c 100644 --- a/crates/shadowsocks-service/Cargo.toml +++ b/crates/shadowsocks-service/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "shadowsocks-service" -version = "1.18.5" +version = "1.19.0" authors = ["Shadowsocks Contributors"] description = "shadowsocks is a fast tunnel proxy that helps you bypass firewalls." repository = "https://github.com/shadowsocks/shadowsocks-rust" @@ -9,7 +9,7 @@ documentation = "https://docs.rs/shadowsocks-service" keywords = ["shadowsocks", "proxy", "socks", "socks5", "firewall"] license = "MIT" edition = "2021" -rust-version = "1.71" +rust-version = "1.74" [badges] maintenance = { status = "passively-maintained" } @@ -184,11 +184,11 @@ smoltcp = { version = "0.11", optional = true, default-features = false, feature serde = { version = "1.0", features = ["derive"] } json5 = "0.4" -shadowsocks = { version = "1.18.3", path = "../shadowsocks", default-features = false } +shadowsocks = { version = "1.19.0", path = "../shadowsocks", default-features = false } # Just for the ioctl call macro [target.'cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))'.dependencies] -nix = { version = "0.28", features = ["ioctl"] } +nix = { version = "0.29", features = ["ioctl"] } [target.'cfg(windows)'.dependencies] windows-sys = { version = "0.52", features = ["Win32_Networking_WinSock"] } diff --git a/crates/shadowsocks-service/src/local/fake_dns/manager.rs b/crates/shadowsocks-service/src/local/fake_dns/manager.rs index 264235cf..1fccfee0 100644 --- a/crates/shadowsocks-service/src/local/fake_dns/manager.rs +++ b/crates/shadowsocks-service/src/local/fake_dns/manager.rs @@ -164,7 +164,7 @@ impl FakeDnsManager { .cache_capacity(10 * 1024 * 1024) .use_compression(true) .mode(sled::Mode::HighThroughput) - .flush_every_ms(Some(1 * 1000)) + .flush_every_ms(Some(1_000)) .path(db_path) .open()?; @@ -193,10 +193,11 @@ impl FakeDnsManager { if recreate_database { let _ = db.clear(); - let mut c = proto::StorageMeta::default(); - c.ipv4_network = ipv4_network_str; - c.ipv6_network = ipv6_network_str; - c.version = FAKE_DNS_MANAGER_STORAGE_VERSION; + let c = proto::StorageMeta { + ipv4_network: ipv4_network_str, + ipv6_network: ipv6_network_str, + version: FAKE_DNS_MANAGER_STORAGE_VERSION, + }; let v = c.encode_to_vec(); db.insert(key, v)?; diff --git a/crates/shadowsocks-service/src/local/tun/fake_tun.rs b/crates/shadowsocks-service/src/local/tun/fake_tun.rs new file mode 100644 index 00000000..f28b3ea3 --- /dev/null +++ b/crates/shadowsocks-service/src/local/tun/fake_tun.rs @@ -0,0 +1,144 @@ +//! Fake `tun` for those platforms that doesn't support `tun` + +use std::{ + io::{self, Read, Write}, + net::Ipv4Addr, + pin::Pin, + task::{Context, Poll}, +}; + +use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; +use tun::{Configuration, Device, Error as TunError}; + +pub struct FakeQueue; + +impl Read for FakeQueue { + fn read(&mut self, _: &mut [u8]) -> io::Result { + Err(io::Error::new(io::ErrorKind::Other, "not implemented")) + } +} + +impl Write for FakeQueue { + fn write(&mut self, _: &[u8]) -> io::Result { + Err(io::Error::new(io::ErrorKind::Other, "not implemented")) + } + + fn flush(&mut self) -> io::Result<()> { + Err(io::Error::new(io::ErrorKind::Other, "not implemented")) + } +} + +pub struct FakeDevice; + +impl Device for FakeDevice { + type Queue = FakeQueue; + + fn name(&self) -> tun::Result { + Err(TunError::NotImplemented) + } + + fn set_name(&mut self, _: &str) -> tun::Result<()> { + Err(TunError::NotImplemented) + } + + fn enabled(&mut self, _: bool) -> tun::Result<()> { + Err(TunError::NotImplemented) + } + + fn address(&self) -> tun::Result { + Err(TunError::NotImplemented) + } + + fn set_address(&mut self, _: Ipv4Addr) -> tun::Result<()> { + Err(TunError::NotImplemented) + } + + fn destination(&self) -> tun::Result { + Err(TunError::NotImplemented) + } + + fn set_destination(&mut self, _: Ipv4Addr) -> tun::Result<()> { + Err(TunError::NotImplemented) + } + + fn broadcast(&self) -> tun::Result { + Err(TunError::NotImplemented) + } + + fn set_broadcast(&mut self, _: Ipv4Addr) -> tun::Result<()> { + Err(TunError::NotImplemented) + } + + fn netmask(&self) -> tun::Result { + Err(TunError::NotImplemented) + } + + fn set_netmask(&mut self, _: Ipv4Addr) -> tun::Result<()> { + Err(TunError::NotImplemented) + } + + fn mtu(&self) -> tun::Result { + Err(TunError::NotImplemented) + } + + fn set_mtu(&mut self, _: i32) -> tun::Result<()> { + Err(TunError::NotImplemented) + } + + fn queue(&mut self, _: usize) -> Option<&mut Self::Queue> { + None + } +} + +impl Read for FakeDevice { + fn read(&mut self, _: &mut [u8]) -> io::Result { + Err(io::Error::new(io::ErrorKind::Other, "not implemented")) + } +} + +impl Write for FakeDevice { + fn write(&mut self, _: &[u8]) -> io::Result { + Err(io::Error::new(io::ErrorKind::Other, "not implemented")) + } + + fn flush(&mut self) -> io::Result<()> { + Err(io::Error::new(io::ErrorKind::Other, "not implemented")) + } +} + +pub struct AsyncDevice(FakeDevice); + +impl AsyncDevice { + pub fn get_ref(&self) -> &FakeDevice { + &self.0 + } + + pub fn get_mut(&mut self) -> &mut FakeDevice { + &mut self.0 + } +} + +impl AsyncRead for AsyncDevice { + fn poll_read(self: Pin<&mut Self>, _cx: &mut Context<'_>, _buf: &mut ReadBuf<'_>) -> Poll> { + Err(io::Error::new(io::ErrorKind::Other, "not implemented")).into() + } +} + +impl AsyncWrite for AsyncDevice { + fn poll_write(self: Pin<&mut Self>, _cx: &mut Context<'_>, _buf: &[u8]) -> Poll> { + Err(io::Error::new(io::ErrorKind::Other, "not implemented")).into() + } + + fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { + Err(io::Error::new(io::ErrorKind::Other, "not implemented")).into() + } + + fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { + Err(io::Error::new(io::ErrorKind::Other, "not implemented")).into() + } +} + +/// Create a TUN device with the given name. +pub fn create_as_async(_: &Configuration) -> Result { + Err(TunError::NotImplemented) +} diff --git a/crates/shadowsocks-service/src/local/tun/mod.rs b/crates/shadowsocks-service/src/local/tun/mod.rs index 7d4a9174..c3f03f1c 100644 --- a/crates/shadowsocks-service/src/local/tun/mod.rs +++ b/crates/shadowsocks-service/src/local/tun/mod.rs @@ -10,12 +10,29 @@ use std::{ }; use byte_string::ByteStr; +use cfg_if::cfg_if; use ipnet::{IpNet, Ipv4Net}; use log::{debug, error, info, trace, warn}; use shadowsocks::config::Mode; use smoltcp::wire::{IpProtocol, TcpPacket, UdpPacket}; use tokio::{io::AsyncReadExt, sync::mpsc, time}; -use tun::{AsyncDevice, Configuration as TunConfiguration, Device as TunDevice, Error as TunError, Layer}; + +cfg_if! { + if #[cfg(any(target_os = "ios", + target_os = "macos", + target_os = "linux", + target_os = "android", + target_os = "windows"))] { + use tun::{ + create_as_async, AsyncDevice, Configuration as TunConfiguration, Device as TunDevice, Error as TunError, Layer, + }; + } else { + use tun::{Configuration as TunConfiguration, Device as TunDevice, Error as TunError, Layer}; + + mod fake_tun; + use self::fake_tun::{create_as_async, AsyncDevice}; + } +} use crate::local::{context::ServiceContext, loadbalancing::PingBalancer}; @@ -94,7 +111,7 @@ impl TunBuilder { tun_config.packet_information(false); }); - let device = match tun::create_as_async(&self.tun_config) { + let device = match create_as_async(&self.tun_config) { Ok(d) => d, Err(TunError::Io(err)) => return Err(err), Err(err) => return Err(io::Error::new(ErrorKind::Other, err)), diff --git a/crates/shadowsocks-service/src/local/tun/sys/others.rs b/crates/shadowsocks-service/src/local/tun/sys/others.rs new file mode 100644 index 00000000..cdf99694 --- /dev/null +++ b/crates/shadowsocks-service/src/local/tun/sys/others.rs @@ -0,0 +1,6 @@ +//! Other platforms + +/// Set platform specific route configuration +pub async fn set_route_configuration(_: &mut TunDevice) -> io::Result<()> { + Ok(()) +} diff --git a/crates/shadowsocks-service/src/local/tun/sys/unix/android.rs b/crates/shadowsocks-service/src/local/tun/sys/unix/android.rs index a7fb183f..02c66f8b 100644 --- a/crates/shadowsocks-service/src/local/tun/sys/unix/android.rs +++ b/crates/shadowsocks-service/src/local/tun/sys/unix/android.rs @@ -1,7 +1,7 @@ use std::{io, marker::Unpin}; use tokio::io::{AsyncWrite, AsyncWriteExt}; -use tun::platform::Device as TunDevice; +use tun::Device; /// Packet Information length in bytes /// @@ -16,6 +16,9 @@ pub async fn write_packet_with_pi(writer: &mut W, packet: } /// Set platform specific route configuration -pub async fn set_route_configuration(_device: &mut TunDevice) -> io::Result<()> { +pub async fn set_route_configuration(_: &mut (dyn Device + Send)) -> io::Result<()> +where + Q: Read + Write, +{ Ok(()) } diff --git a/crates/shadowsocks-service/src/local/tun/sys/unix/apple/macos.rs b/crates/shadowsocks-service/src/local/tun/sys/unix/apple/macos.rs index 87a079f2..8cf468f1 100644 --- a/crates/shadowsocks-service/src/local/tun/sys/unix/apple/macos.rs +++ b/crates/shadowsocks-service/src/local/tun/sys/unix/apple/macos.rs @@ -1,12 +1,12 @@ use std::{ ffi::CStr, - io::{self, ErrorKind}, + io::{self, ErrorKind, Read, Write}, mem, ptr, }; use log::{error, trace}; -use tun::{platform::Device as TunDevice, Device, Error as TunError}; +use tun::{Device, Error as TunError}; /// These numbers are used by reliable protocols for determining /// retransmission behavior and are included in the routing structure. @@ -58,7 +58,10 @@ struct rt_msg { } /// Set platform specific route configuration -pub async fn set_route_configuration(device: &mut TunDevice) -> io::Result<()> { +pub async fn set_route_configuration(device: &mut (dyn Device + Send)) -> io::Result<()> +where + Q: Read + Write, +{ let tun_address = match device.address() { Ok(t) => t, Err(err) => { diff --git a/crates/shadowsocks-service/src/local/tun/sys/unix/apple/others.rs b/crates/shadowsocks-service/src/local/tun/sys/unix/apple/others.rs index 7ef4be54..21d66a51 100644 --- a/crates/shadowsocks-service/src/local/tun/sys/unix/apple/others.rs +++ b/crates/shadowsocks-service/src/local/tun/sys/unix/apple/others.rs @@ -1,8 +1,11 @@ use std::io; -use tun::platform::Device as TunDevice; +use tun::Device; /// Set platform specific route configuration -pub async fn set_route_configuration(_device: &mut TunDevice) -> io::Result<()> { +pub async fn set_route_configuration(_: &mut (dyn Device + Send)) -> io::Result<()> +where + Q: Read + Write, +{ Ok(()) } diff --git a/crates/shadowsocks-service/src/local/tun/sys/unix/bsd.rs b/crates/shadowsocks-service/src/local/tun/sys/unix/bsd.rs index 5ba7f41c..396c2b8d 100644 --- a/crates/shadowsocks-service/src/local/tun/sys/unix/bsd.rs +++ b/crates/shadowsocks-service/src/local/tun/sys/unix/bsd.rs @@ -4,7 +4,7 @@ use std::{ }; use tokio::io::{AsyncWrite, AsyncWriteExt}; -use tun::platform::Device as TunDevice; +use tun::Device; /// Packet Information length in bytes pub const IFF_PI_PREFIX_LEN: usize = 4; @@ -54,6 +54,9 @@ pub async fn write_packet_with_pi(writer: &mut W, packet: } /// Set platform specific route configuration -pub async fn set_route_configuration(_device: &mut TunDevice) -> io::Result<()> { +pub async fn set_route_configuration(_: &mut (dyn Device + Send)) -> io::Result<()> +where + Q: Read + Write, +{ Ok(()) } diff --git a/crates/shadowsocks-service/src/local/tun/sys/unix/linux.rs b/crates/shadowsocks-service/src/local/tun/sys/unix/linux.rs index 4d710e3c..35728bee 100644 --- a/crates/shadowsocks-service/src/local/tun/sys/unix/linux.rs +++ b/crates/shadowsocks-service/src/local/tun/sys/unix/linux.rs @@ -1,7 +1,7 @@ use std::{io, marker::Unpin}; use tokio::io::{AsyncWrite, AsyncWriteExt}; -use tun::platform::Device as TunDevice; +use tun::Device; /// Packet Information length in bytes /// @@ -16,6 +16,9 @@ pub async fn write_packet_with_pi(writer: &mut W, packet: } /// Set platform specific route configuration -pub async fn set_route_configuration(_device: &mut TunDevice) -> io::Result<()> { +pub async fn set_route_configuration(_: &mut (dyn Device + Send)) -> io::Result<()> +where + Q: Read + Write, +{ Ok(()) } diff --git a/crates/shadowsocks-service/src/local/tun/sys/windows/mod.rs b/crates/shadowsocks-service/src/local/tun/sys/windows/mod.rs index 332de0be..5e203f38 100644 --- a/crates/shadowsocks-service/src/local/tun/sys/windows/mod.rs +++ b/crates/shadowsocks-service/src/local/tun/sys/windows/mod.rs @@ -1,7 +1,7 @@ use std::{io, marker::Unpin}; use tokio::io::{AsyncWrite, AsyncWriteExt}; -use tun::{platform::Device as TunDevice, Device}; +use tun::Device; /// Packet Information length in bytes /// @@ -16,6 +16,9 @@ pub async fn write_packet_with_pi(writer: &mut W, packet: } /// Set platform specific route configuration -pub async fn set_route_configuration(_device: &mut TunDevice) -> io::Result<()> { +pub async fn set_route_configuration(_: &mut (dyn Device + Send)) -> io::Result<()> +where + Q: Read + Write, +{ Ok(()) } diff --git a/crates/shadowsocks/Cargo.toml b/crates/shadowsocks/Cargo.toml index bae9c433..92adbcda 100644 --- a/crates/shadowsocks/Cargo.toml +++ b/crates/shadowsocks/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "shadowsocks" -version = "1.18.3" +version = "1.19.0" authors = ["Shadowsocks Contributors"] description = "shadowsocks is a fast tunnel proxy that helps you bypass firewalls." repository = "https://github.com/shadowsocks/shadowsocks-rust" @@ -9,7 +9,7 @@ documentation = "https://docs.rs/shadowsocks-core" keywords = ["shadowsocks", "proxy", "socks", "socks5", "firewall"] license = "MIT" edition = "2021" -rust-version = "1.71" +rust-version = "1.74" [badges] maintenance = { status = "passively-maintained" } diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 0e9d83af..63069a20 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -58,7 +58,10 @@ parts: plugin: rust source: https://github.com/shadowsocks/shadowsocks-rust.git rust-channel: stable - rust-features: [local-tun, local-redir] + rust-features: [full] override-pull: | snapcraftctl pull snapcraftctl set-version `git describe --tags --long | sed 's/\([^-]*-g\)/r\1/;s/-/./g'` + +build-packages: + - protobuf diff --git a/src/service/local.rs b/src/service/local.rs index 66232336..100930ee 100644 --- a/src/service/local.rs +++ b/src/service/local.rs @@ -1186,7 +1186,7 @@ impl ServerReloader { // Load servers from online-config (SIP008) #[cfg(feature = "local-online-config")] if let Some(ref online_config_url) = self.online_config_url { - let mut online_servers = get_online_config_servers(&online_config_url).await?; + let mut online_servers = get_online_config_servers(online_config_url).await?; servers.append(&mut online_servers); } @@ -1207,7 +1207,7 @@ impl ServerReloader { if let Some(ref online_config_url) = self.0.online_config_url { if !is_first { f.write_str(", ")?; - f.write_str(&online_config_url)?; + f.write_str(online_config_url)?; } } @@ -1226,7 +1226,7 @@ impl ServerReloader { info!( "server-loader task load from {} with {} servers, fetch costs: {:?}, total costs: {:?}", - ConfigDisplay(&self), + ConfigDisplay(self), server_len, fetch_end_time - start_time, total_end_time - start_time, @@ -1256,7 +1256,7 @@ impl ServerReloader { let update_interval = self .online_config_update_interval - .unwrap_or(Duration::from_secs(1 * 60 * 60)); + .unwrap_or(Duration::from_secs(60 * 60)); debug!("server-loader task updating in interval {:?}", update_interval);