mirror of
https://github.com/shadowsocks/shadowsocks-rust.git
synced 2026-02-09 01:59:16 +08:00
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
This commit is contained in:
10
.github/workflows/build-and-test.yml
vendored
10
.github/workflows/build-and-test.yml
vendored
@@ -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"
|
||||
|
||||
6
.github/workflows/build-msrv.yml
vendored
6
.github/workflows/build-msrv.yml
vendored
@@ -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"
|
||||
|
||||
10
.github/workflows/build-nightly-release.yml
vendored
10
.github/workflows/build-nightly-release.yml
vendored
@@ -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
|
||||
|
||||
10
.github/workflows/build-release.yml
vendored
10
.github/workflows/build-release.yml
vendored
@@ -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
|
||||
|
||||
9
.github/workflows/clippy-check.yml
vendored
9
.github/workflows/clippy-check.yml
vendored
@@ -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 }}
|
||||
|
||||
34
Cargo.lock
generated
34
Cargo.lock
generated
@@ -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"
|
||||
|
||||
34
Cargo.toml
34
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 }
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
1
clippy.toml
Normal file
1
clippy.toml
Normal file
@@ -0,0 +1 @@
|
||||
msrv = "1.74"
|
||||
@@ -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"] }
|
||||
|
||||
@@ -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)?;
|
||||
|
||||
144
crates/shadowsocks-service/src/local/tun/fake_tun.rs
Normal file
144
crates/shadowsocks-service/src/local/tun/fake_tun.rs
Normal file
@@ -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<usize> {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "not implemented"))
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for FakeQueue {
|
||||
fn write(&mut self, _: &[u8]) -> io::Result<usize> {
|
||||
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<String> {
|
||||
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<Ipv4Addr> {
|
||||
Err(TunError::NotImplemented)
|
||||
}
|
||||
|
||||
fn set_address(&mut self, _: Ipv4Addr) -> tun::Result<()> {
|
||||
Err(TunError::NotImplemented)
|
||||
}
|
||||
|
||||
fn destination(&self) -> tun::Result<Ipv4Addr> {
|
||||
Err(TunError::NotImplemented)
|
||||
}
|
||||
|
||||
fn set_destination(&mut self, _: Ipv4Addr) -> tun::Result<()> {
|
||||
Err(TunError::NotImplemented)
|
||||
}
|
||||
|
||||
fn broadcast(&self) -> tun::Result<Ipv4Addr> {
|
||||
Err(TunError::NotImplemented)
|
||||
}
|
||||
|
||||
fn set_broadcast(&mut self, _: Ipv4Addr) -> tun::Result<()> {
|
||||
Err(TunError::NotImplemented)
|
||||
}
|
||||
|
||||
fn netmask(&self) -> tun::Result<Ipv4Addr> {
|
||||
Err(TunError::NotImplemented)
|
||||
}
|
||||
|
||||
fn set_netmask(&mut self, _: Ipv4Addr) -> tun::Result<()> {
|
||||
Err(TunError::NotImplemented)
|
||||
}
|
||||
|
||||
fn mtu(&self) -> tun::Result<i32> {
|
||||
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<usize> {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "not implemented"))
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for FakeDevice {
|
||||
fn write(&mut self, _: &[u8]) -> io::Result<usize> {
|
||||
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<io::Result<()>> {
|
||||
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<io::Result<usize>> {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "not implemented")).into()
|
||||
}
|
||||
|
||||
fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "not implemented")).into()
|
||||
}
|
||||
|
||||
fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||
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<AsyncDevice, TunError> {
|
||||
Err(TunError::NotImplemented)
|
||||
}
|
||||
@@ -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)),
|
||||
|
||||
6
crates/shadowsocks-service/src/local/tun/sys/others.rs
Normal file
6
crates/shadowsocks-service/src/local/tun/sys/others.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
//! Other platforms
|
||||
|
||||
/// Set platform specific route configuration
|
||||
pub async fn set_route_configuration(_: &mut TunDevice) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
@@ -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<W: AsyncWrite + Unpin>(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<Q>(_: &mut (dyn Device<Queue = Q> + Send)) -> io::Result<()>
|
||||
where
|
||||
Q: Read + Write,
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -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<Q>(device: &mut (dyn Device<Queue = Q> + Send)) -> io::Result<()>
|
||||
where
|
||||
Q: Read + Write,
|
||||
{
|
||||
let tun_address = match device.address() {
|
||||
Ok(t) => t,
|
||||
Err(err) => {
|
||||
|
||||
@@ -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<Q>(_: &mut (dyn Device<Queue = Q> + Send)) -> io::Result<()>
|
||||
where
|
||||
Q: Read + Write,
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -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<W: AsyncWrite + Unpin>(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<Q>(_: &mut (dyn Device<Queue = Q> + Send)) -> io::Result<()>
|
||||
where
|
||||
Q: Read + Write,
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -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<W: AsyncWrite + Unpin>(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<Q>(_: &mut (dyn Device<Queue = Q> + Send)) -> io::Result<()>
|
||||
where
|
||||
Q: Read + Write,
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -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<W: AsyncWrite + Unpin>(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<Q>(_: &mut (dyn Device<Queue = Q> + Send)) -> io::Result<()>
|
||||
where
|
||||
Q: Read + Write,
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -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" }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user