Fix: Fixed compilation issue after partially removing the feature flag (#1835)

This commit is contained in:
Chenx Dust
2026-01-28 21:38:34 +08:00
committed by GitHub
parent 977e502150
commit ccc684a9ab
14 changed files with 512 additions and 239 deletions
+7
View File
@@ -96,6 +96,9 @@ jobs:
rustup component add rustfmt rustup component add rustfmt
rustup component add clippy rustup component add clippy
- name: Install cargo-hack
run: cargo install cargo-hack --locked
- name: Check formatting - name: Check formatting
if: ${{ !cancelled() }} if: ${{ !cancelled() }}
run: cargo fmt --all -- --check run: cargo fmt --all -- --check
@@ -107,6 +110,10 @@ jobs:
mkdir -p easytier-gui/dist mkdir -p easytier-gui/dist
cargo clippy --all-targets --all-features --all -- -D warnings cargo clippy --all-targets --all-features --all -- -D warnings
- name: Check features
if: ${{ !cancelled() }}
run: cargo hack check --package easytier --each-feature --features aes-gcm --verbose
- name: Run tests - name: Run tests
run: | run: |
sudo prlimit --pid $$ --nofile=1048576:1048576 sudo prlimit --pid $$ --nofile=1048576:1048576
+192 -40
View File
@@ -38,6 +38,20 @@ dependencies = [
"cpufeatures", "cpufeatures",
] ]
[[package]]
name = "aes-gcm"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1"
dependencies = [
"aead",
"aes",
"cipher",
"ctr",
"ghash",
"subtle",
]
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "1.1.3" version = "1.1.3"
@@ -133,6 +147,12 @@ version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
[[package]]
name = "arrayvec"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]] [[package]]
name = "async-recursion" name = "async-recursion"
version = "1.1.1" version = "1.1.1"
@@ -254,14 +274,14 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]] [[package]]
name = "bindgen" name = "bindgen"
version = "0.71.1" version = "0.72.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895"
dependencies = [ dependencies = [
"bitflags 2.9.4", "bitflags 2.9.4",
"cexpr", "cexpr",
"clang-sys", "clang-sys",
"itertools 0.13.0", "itertools 0.11.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"regex", "regex",
@@ -540,6 +560,16 @@ dependencies = [
"clap", "clap",
] ]
[[package]]
name = "clap_complete_nushell"
version = "4.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "685bc86fd34b7467e0532a4f8435ab107960d69a243785ef0275e571b35b641a"
dependencies = [
"clap",
"clap_complete",
]
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "4.5.47" version = "4.5.47"
@@ -746,6 +776,15 @@ version = "0.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2931af7e13dc045d8e9d26afccc6fa115d64e115c9c84b1166288b46f6782c2" checksum = "e2931af7e13dc045d8e9d26afccc6fa115d64e115c9c84b1166288b46f6782c2"
[[package]]
name = "ctr"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
dependencies = [
"cipher",
]
[[package]] [[package]]
name = "curve25519-dalek" name = "curve25519-dalek"
version = "4.1.3" version = "4.1.3"
@@ -995,7 +1034,7 @@ checksum = "7454e41ff9012c00d53cf7f475c5e3afa3b91b7c90568495495e8d9bf47a1055"
[[package]] [[package]]
name = "easytier" name = "easytier"
version = "2.4.5" version = "2.5.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"arc-swap", "arc-swap",
@@ -1011,16 +1050,19 @@ dependencies = [
"bytecodec", "bytecodec",
"byteorder", "byteorder",
"bytes", "bytes",
"cfg-if",
"chrono", "chrono",
"cidr", "cidr",
"clap", "clap",
"clap_complete", "clap_complete",
"clap_complete_nushell",
"crossbeam", "crossbeam",
"dashmap", "dashmap",
"dbus", "dbus",
"derive_builder", "derive_builder",
"easytier-rpc-build", "easytier-rpc-build",
"encoding", "encoding",
"flume",
"futures", "futures",
"gethostname", "gethostname",
"git-version", "git-version",
@@ -1046,6 +1088,7 @@ dependencies = [
"network-interface", "network-interface",
"nix 0.29.0", "nix 0.29.0",
"once_cell", "once_cell",
"ordered_hash_map",
"parking_lot", "parking_lot",
"percent-encoding", "percent-encoding",
"petgraph 0.8.2", "petgraph 0.8.2",
@@ -1073,6 +1116,7 @@ dependencies = [
"sha2", "sha2",
"shellexpand", "shellexpand",
"smoltcp", "smoltcp",
"snow",
"socket2 0.5.10", "socket2 0.5.10",
"stun_codec", "stun_codec",
"sys-locale", "sys-locale",
@@ -1097,10 +1141,12 @@ dependencies = [
"which 7.0.3", "which 7.0.3",
"wildmatch", "wildmatch",
"winapi", "winapi",
"windivert",
"windows 0.52.0", "windows 0.52.0",
"windows-service", "windows-service",
"windows-sys 0.52.0", "windows-sys 0.52.0",
"winreg 0.52.0", "winreg 0.52.0",
"x25519-dalek",
"zerocopy 0.7.35", "zerocopy 0.7.35",
"zip", "zip",
"zstd", "zstd",
@@ -1126,8 +1172,6 @@ dependencies = [
[[package]] [[package]]
name = "easytier-rpc-build" name = "easytier-rpc-build"
version = "0.1.0" version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24829168c28f6a448f57d18116c255dcbd2b8c25e76dbc60f6cd16d68ad2cf07"
dependencies = [ dependencies = [
"heck 0.5.0", "heck 0.5.0",
"prost-build", "prost-build",
@@ -1264,10 +1308,19 @@ dependencies = [
] ]
[[package]] [[package]]
name = "fastbloom" name = "etherparse"
version = "0.14.0" version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18c1ddb9231d8554c2d6bdf4cfaabf0c59251658c68b6c95cd52dd0c513a912a" checksum = "827292ea592108849932ad8e30218f8b1f21c0dfd0696698a18b5d0aed62d990"
dependencies = [
"arrayvec",
]
[[package]]
name = "fastbloom"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e7f34442dbe69c60fe8eaf58a8cafff81a1f278816d8ab4db255b3bef4ac3c4"
dependencies = [ dependencies = [
"getrandom 0.3.3", "getrandom 0.3.3",
"libm", "libm",
@@ -1280,6 +1333,9 @@ name = "fastrand"
version = "2.3.0" version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
dependencies = [
"getrandom 0.2.16",
]
[[package]] [[package]]
name = "fiat-crypto" name = "fiat-crypto"
@@ -1310,6 +1366,18 @@ dependencies = [
"miniz_oxide", "miniz_oxide",
] ]
[[package]]
name = "flume"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be"
dependencies = [
"fastrand",
"futures-core",
"futures-sink",
"spin",
]
[[package]] [[package]]
name = "fnv" name = "fnv"
version = "1.0.7" version = "1.0.7"
@@ -1496,6 +1564,16 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "ghash"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1"
dependencies = [
"opaque-debug",
"polyval",
]
[[package]] [[package]]
name = "gimli" name = "gimli"
version = "0.31.1" version = "0.31.1"
@@ -1605,9 +1683,9 @@ checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
[[package]] [[package]]
name = "heapless" name = "heapless"
version = "0.9.1" version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1edcd5a338e64688fbdcb7531a846cfd3476a54784dcb918a0844682bc7ada5" checksum = "2af2455f757db2b292a9b1768c4b70186d443bcb3b316252d6b540aec1cd89ed"
dependencies = [ dependencies = [
"hash32", "hash32",
"stable_deref_trait", "stable_deref_trait",
@@ -2161,15 +2239,6 @@ dependencies = [
"either", "either",
] ]
[[package]]
name = "itertools"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
dependencies = [
"either",
]
[[package]] [[package]]
name = "itertools" name = "itertools"
version = "0.14.0" version = "0.14.0"
@@ -2230,7 +2299,7 @@ dependencies = [
[[package]] [[package]]
name = "kcp-sys" name = "kcp-sys"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/EasyTier/kcp-sys?rev=71eff18c573a4a71bf99c7fabc6a8b9f211c84c1#71eff18c573a4a71bf99c7fabc6a8b9f211c84c1" source = "git+https://github.com/EasyTier/kcp-sys?rev=94964794caaed5d388463137da59b97499619e5f#94964794caaed5d388463137da59b97499619e5f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"auto_impl", "auto_impl",
@@ -2564,7 +2633,7 @@ dependencies = [
"libc", "libc",
"log", "log",
"openssl", "openssl",
"openssl-probe", "openssl-probe 0.1.6",
"openssl-sys", "openssl-sys",
"schannel", "schannel",
"security-framework 2.11.1", "security-framework 2.11.1",
@@ -2810,6 +2879,12 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
[[package]]
name = "openssl-probe"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
[[package]] [[package]]
name = "openssl-sys" name = "openssl-sys"
version = "0.9.109" version = "0.9.109"
@@ -2822,6 +2897,15 @@ dependencies = [
"vcpkg", "vcpkg",
] ]
[[package]]
name = "ordered_hash_map"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6c699f8a30f345785be969deed7eee4c73a5de58c7faf61d6a3251ef798ff61"
dependencies = [
"hashbrown 0.15.5",
]
[[package]] [[package]]
name = "papergrid" name = "papergrid"
version = "0.12.0" version = "0.12.0"
@@ -2874,12 +2958,12 @@ dependencies = [
[[package]] [[package]]
name = "pem" name = "pem"
version = "3.0.5" version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be"
dependencies = [ dependencies = [
"base64 0.22.1", "base64 0.22.1",
"serde", "serde_core",
] ]
[[package]] [[package]]
@@ -3045,6 +3129,18 @@ dependencies = [
"universal-hash", "universal-hash",
] ]
[[package]]
name = "polyval"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25"
dependencies = [
"cfg-if",
"cpufeatures",
"opaque-debug",
"universal-hash",
]
[[package]] [[package]]
name = "portable-atomic" name = "portable-atomic"
version = "1.11.1" version = "1.11.1"
@@ -3273,7 +3369,7 @@ dependencies = [
"quinn-udp", "quinn-udp",
"rustc-hash", "rustc-hash",
"rustls", "rustls",
"socket2 0.6.0", "socket2 0.5.10",
"thiserror 2.0.16", "thiserror 2.0.16",
"tokio", "tokio",
"tracing", "tracing",
@@ -3312,9 +3408,9 @@ dependencies = [
"cfg_aliases", "cfg_aliases",
"libc", "libc",
"once_cell", "once_cell",
"socket2 0.6.0", "socket2 0.5.10",
"tracing", "tracing",
"windows-sys 0.60.2", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
@@ -3652,14 +3748,14 @@ dependencies = [
[[package]] [[package]]
name = "rustls-native-certs" name = "rustls-native-certs"
version = "0.8.1" version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63"
dependencies = [ dependencies = [
"openssl-probe", "openssl-probe 0.2.1",
"rustls-pki-types", "rustls-pki-types",
"schannel", "schannel",
"security-framework 3.5.0", "security-framework 3.5.1",
] ]
[[package]] [[package]]
@@ -3683,9 +3779,9 @@ dependencies = [
[[package]] [[package]]
name = "rustls-platform-verifier" name = "rustls-platform-verifier"
version = "0.6.1" version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be59af91596cac372a6942530653ad0c3a246cdd491aaa9dcaee47f88d67d5a0" checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784"
dependencies = [ dependencies = [
"core-foundation 0.10.1", "core-foundation 0.10.1",
"core-foundation-sys", "core-foundation-sys",
@@ -3696,10 +3792,10 @@ dependencies = [
"rustls-native-certs", "rustls-native-certs",
"rustls-platform-verifier-android", "rustls-platform-verifier-android",
"rustls-webpki", "rustls-webpki",
"security-framework 3.5.0", "security-framework 3.5.1",
"security-framework-sys", "security-framework-sys",
"webpki-root-certs", "webpki-root-certs",
"windows-sys 0.59.0", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
@@ -3776,9 +3872,9 @@ dependencies = [
[[package]] [[package]]
name = "security-framework" name = "security-framework"
version = "3.5.0" version = "3.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc198e42d9b7510827939c9a15f5062a0c913f3371d765977e586d2fe6c16f4a" checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef"
dependencies = [ dependencies = [
"bitflags 2.9.4", "bitflags 2.9.4",
"core-foundation 0.10.1", "core-foundation 0.10.1",
@@ -3987,6 +4083,23 @@ dependencies = [
"managed", "managed",
] ]
[[package]]
name = "snow"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "599b506ccc4aff8cf7844bc42cf783009a434c1e26c964432560fb6d6ad02d82"
dependencies = [
"aes-gcm",
"blake2",
"chacha20poly1305",
"curve25519-dalek",
"getrandom 0.3.3",
"ring",
"rustc_version",
"sha2",
"subtle",
]
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.5.10" version = "0.5.10"
@@ -4007,6 +4120,15 @@ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"lock_api",
]
[[package]] [[package]]
name = "stable_deref_trait" name = "stable_deref_trait"
version = "1.2.0" version = "1.2.0"
@@ -4895,9 +5017,9 @@ dependencies = [
[[package]] [[package]]
name = "webpki-root-certs" name = "webpki-root-certs"
version = "1.0.2" version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e4ffd8df1c57e87c325000a3d6ef93db75279dc3a231125aac571650f22b12a" checksum = "36a29fc0408b113f68cf32637857ab740edfafdf460c326cd2afaa2d84cc05dc"
dependencies = [ dependencies = [
"rustls-pki-types", "rustls-pki-types",
] ]
@@ -4987,6 +5109,36 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windivert"
version = "0.6.0"
source = "git+https://github.com/EasyTier/windivert-rust.git?rev=adcc56d1550f7b5377ec2b3429f413ee24a77375#adcc56d1550f7b5377ec2b3429f413ee24a77375"
dependencies = [
"etherparse",
"thiserror 1.0.69",
"windivert-sys",
"windows 0.48.0",
]
[[package]]
name = "windivert-sys"
version = "0.10.0"
source = "git+https://github.com/EasyTier/windivert-rust.git?rev=adcc56d1550f7b5377ec2b3429f413ee24a77375#adcc56d1550f7b5377ec2b3429f413ee24a77375"
dependencies = [
"cc",
"thiserror 1.0.69",
"windows 0.48.0",
]
[[package]]
name = "windows"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
dependencies = [
"windows-targets 0.48.5",
]
[[package]] [[package]]
name = "windows" name = "windows"
version = "0.52.0" version = "0.52.0"
+2 -3
View File
@@ -6,6 +6,7 @@ extern crate rust_i18n;
use std::sync::Arc; use std::sync::Arc;
use clap::Parser; use clap::Parser;
use easytier::tunnel::websocket::WSTunnelListener;
use easytier::{ use easytier::{
common::{ common::{
config::{ConsoleLoggerConfig, FileLoggerConfig, LoggingConfigLoader}, config::{ConsoleLoggerConfig, FileLoggerConfig, LoggingConfigLoader},
@@ -13,9 +14,7 @@ use easytier::{
error::Error, error::Error,
network::{local_ipv4, local_ipv6}, network::{local_ipv4, local_ipv6},
}, },
tunnel::{ tunnel::{tcp::TcpTunnelListener, udp::UdpTunnelListener, TunnelListener},
tcp::TcpTunnelListener, udp::UdpTunnelListener, websocket::WSTunnelListener, TunnelListener,
},
utils::{init_logger, setup_panic_handler}, utils::{init_logger, setup_panic_handler},
}; };
+12 -8
View File
@@ -155,7 +155,7 @@ bitflags = "2.5"
aes-gcm = { version = "0.10.3", optional = true } aes-gcm = { version = "0.10.3", optional = true }
openssl = { version = "0.10", optional = true, features = ["vendored"] } openssl = { version = "0.10", optional = true, features = ["vendored"] }
snow = "0.10.0" snow = "0.10.0"
x25519-dalek = "2.0" x25519-dalek = { version = "2.0", features = ["static_secrets"] }
# for cli # for cli
tabled = "0.16" tabled = "0.16"
@@ -185,7 +185,7 @@ smoltcp = { git = "https://github.com/smoltcp-rs/smoltcp.git", rev = "0a926767a6
# "socket-tcp-cubic", # "socket-tcp-cubic",
"async", "async",
] } ] }
parking_lot = { version = "0.12.0", optional = true } parking_lot = { version = "0.12.0" }
wildmatch = "2.3.4" wildmatch = "2.3.4"
@@ -199,7 +199,7 @@ service-manager = { git = "https://github.com/EasyTier/service-manager-rs.git",
zstd = { version = "0.13" } zstd = { version = "0.13" }
kcp-sys = { git = "https://github.com/EasyTier/kcp-sys", rev = "94964794caaed5d388463137da59b97499619e5f" } kcp-sys = { git = "https://github.com/EasyTier/kcp-sys", rev = "94964794caaed5d388463137da59b97499619e5f", optional = true }
prost-reflect = { version = "0.14.5", default-features = false, features = [ prost-reflect = { version = "0.14.5", default-features = false, features = [
"derive", "derive",
@@ -215,8 +215,9 @@ hickory-resolver = "0.25.2"
hickory-proto = "0.25.2" hickory-proto = "0.25.2"
# for magic dns # for magic dns
hickory-client = "0.25.2" hickory-client = { version = "0.25.2", optional = true }
hickory-server = { version = "0.25.2", features = ["resolver"] } hickory-server = { version = "0.25.2", features = ["resolver"], optional = true }
derive_builder = "0.20.2" derive_builder = "0.20.2"
humantime-serde = "1.1.1" humantime-serde = "1.1.1"
multimap = "0.10.1" multimap = "0.10.1"
@@ -318,7 +319,7 @@ tokio-socks = "0.5.2"
[features] [features]
default = ["wireguard", "websocket", "smoltcp", "tun", "socks5", "quic"] default = ["wireguard", "websocket", "smoltcp", "tun", "socks5", "kcp", "quic", "magic-dns"]
full = [ full = [
"websocket", "websocket",
"wireguard", "wireguard",
@@ -327,9 +328,11 @@ full = [
"smoltcp", "smoltcp",
"tun", "tun",
"socks5", "socks5",
"magic-dns",
] ]
wireguard = ["dep:boringtun", "dep:ring"] wireguard = ["dep:boringtun", "dep:ring"]
quic = ["dep:quinn", "dep:rustls", "dep:rcgen"] quic = ["dep:quinn", "dep:rustls", "dep:rcgen"]
kcp = ["dep:kcp-sys"]
mimalloc = ["dep:mimalloc"] mimalloc = ["dep:mimalloc"]
aes-gcm = ["dep:aes-gcm"] aes-gcm = ["dep:aes-gcm"]
openssl-crypto = ["dep:openssl"] openssl-crypto = ["dep:openssl"]
@@ -341,8 +344,9 @@ websocket = [
"dep:rustls", "dep:rustls",
"dep:rcgen", "dep:rcgen",
] ]
smoltcp = ["dep:smoltcp", "dep:parking_lot"] smoltcp = ["dep:smoltcp"]
socks5 = ["dep:smoltcp"] socks5 = ["smoltcp"]
jemalloc = ["dep:jemallocator", "dep:jemalloc-sys"] jemalloc = ["dep:jemallocator", "dep:jemalloc-sys"]
jemalloc-prof = ["jemalloc", "dep:jemalloc-ctl", "jemalloc-ctl/stats", "jemalloc-sys/profiling", "jemalloc-sys/stats"] jemalloc-prof = ["jemalloc", "dep:jemalloc-ctl", "jemalloc-ctl/stats", "jemalloc-sys/profiling", "jemalloc-sys/stats"]
tracing = ["tokio/tracing", "dep:console-subscriber"] tracing = ["tokio/tracing", "dep:console-subscriber"]
magic-dns = ["dep:hickory-client", "dep:hickory-server"]
-1
View File
@@ -931,7 +931,6 @@ impl NetworkOptions {
)); ));
} }
#[cfg(feature = "socks5")]
for port_forward in self.port_forward.iter() { for port_forward in self.port_forward.iter() {
let example_str = ", example: udp://0.0.0.0:12345/10.126.126.1:12345"; let example_str = ", example: udp://0.0.0.0:12345/10.126.126.1:12345";
+7 -142
View File
@@ -13,19 +13,9 @@ use kcp_sys::{
packet_def::KcpPacket, packet_def::KcpPacket,
stream::KcpStream, stream::KcpStream,
}; };
use pnet::packet::{ use pnet::packet::ipv4::Ipv4Packet;
ip::IpNextHeaderProtocols,
ipv4::Ipv4Packet,
tcp::{TcpFlags, TcpPacket},
Packet as _,
};
use prost::Message; use prost::Message;
use tokio::{ use tokio::{select, task::JoinSet};
io::{copy_bidirectional, AsyncRead, AsyncWrite},
select,
task::JoinSet,
};
use tokio_util::io::InspectReader;
use super::{ use super::{
tcp_proxy::{NatDstConnector, NatDstTcpConnector, TcpProxy}, tcp_proxy::{NatDstConnector, NatDstTcpConnector, TcpProxy},
@@ -37,9 +27,10 @@ use crate::{
error::Result, error::Result,
global_ctx::{ArcGlobalCtx, GlobalCtx}, global_ctx::{ArcGlobalCtx, GlobalCtx},
}, },
peers::{acl_filter::AclFilter, peer_manager::PeerManager, NicPacketFilter, PeerPacketFilter}, gateway::wrapped_proxy::{ProxyAclHandler, TcpProxyForWrappedSrcTrait},
peers::{peer_manager::PeerManager, PeerPacketFilter},
proto::{ proto::{
acl::{Action, ChainType, Protocol}, acl::{ChainType, Protocol},
api::instance::{ api::instance::{
ListTcpProxyEntryRequest, ListTcpProxyEntryResponse, TcpProxyEntry, TcpProxyEntryState, ListTcpProxyEntryRequest, ListTcpProxyEntryResponse, TcpProxyEntry, TcpProxyEntryState,
TcpProxyEntryTransportType, TcpProxyRpc, TcpProxyEntryTransportType, TcpProxyRpc,
@@ -215,21 +206,14 @@ impl NatDstConnector for NatDstKcpConnector {
struct TcpProxyForKcpSrc(Arc<TcpProxy<NatDstKcpConnector>>); struct TcpProxyForKcpSrc(Arc<TcpProxy<NatDstKcpConnector>>);
#[async_trait::async_trait] #[async_trait::async_trait]
pub(crate) trait TcpProxyForKcpSrcTrait: Send + Sync + 'static { impl TcpProxyForWrappedSrcTrait for TcpProxyForKcpSrc {
type Connector: NatDstConnector;
fn get_tcp_proxy(&self) -> &Arc<TcpProxy<Self::Connector>>;
async fn check_dst_allow_kcp_input(&self, dst_ip: &Ipv4Addr) -> bool;
}
#[async_trait::async_trait]
impl TcpProxyForKcpSrcTrait for TcpProxyForKcpSrc {
type Connector = NatDstKcpConnector; type Connector = NatDstKcpConnector;
fn get_tcp_proxy(&self) -> &Arc<TcpProxy<Self::Connector>> { fn get_tcp_proxy(&self) -> &Arc<TcpProxy<Self::Connector>> {
&self.0 &self.0
} }
async fn check_dst_allow_kcp_input(&self, dst_ip: &Ipv4Addr) -> bool { async fn check_dst_allow_wrapped_input(&self, dst_ip: &Ipv4Addr) -> bool {
let Some(peer_manager) = self.0.get_peer_manager() else { let Some(peer_manager) = self.0.get_peer_manager() else {
return false; return false;
}; };
@@ -239,81 +223,6 @@ impl TcpProxyForKcpSrcTrait for TcpProxyForKcpSrc {
} }
} }
#[async_trait::async_trait]
impl<C: NatDstConnector, T: TcpProxyForKcpSrcTrait<Connector = C>> NicPacketFilter for T {
async fn try_process_packet_from_nic(&self, zc_packet: &mut ZCPacket) -> bool {
let ret = self
.get_tcp_proxy()
.try_process_packet_from_nic(zc_packet)
.await;
if ret {
return true;
}
let data = zc_packet.payload();
let ip_packet = Ipv4Packet::new(data).unwrap();
if ip_packet.get_version() != 4
|| ip_packet.get_next_level_protocol() != IpNextHeaderProtocols::Tcp
{
return false;
}
// if no connection is established, only allow SYN packet
let tcp_packet = TcpPacket::new(ip_packet.payload()).unwrap();
let is_syn = tcp_packet.get_flags() & TcpFlags::SYN != 0
&& tcp_packet.get_flags() & TcpFlags::ACK == 0;
if is_syn {
// only check dst feature flag when SYN packet
if !self
.check_dst_allow_kcp_input(&ip_packet.get_destination())
.await
{
tracing::warn!(
"{:?} proxy src: dst {} not allow kcp input",
self.get_tcp_proxy().get_transport_type(),
ip_packet.get_destination()
);
return false;
}
} else {
// if not syn packet, only allow established connection
if !self
.get_tcp_proxy()
.is_tcp_proxy_connection(SocketAddr::new(
IpAddr::V4(ip_packet.get_source()),
tcp_packet.get_source(),
))
{
return false;
}
}
if let Some(my_ipv4) = self.get_tcp_proxy().get_global_ctx().get_ipv4() {
// this is a net-to-net packet, only allow it when smoltcp is enabled
// because the syn-ack packet will not be through and handled by the tun device when
// the source ip is in the local network
if ip_packet.get_source() != my_ipv4.address()
&& !self.get_tcp_proxy().is_smoltcp_enabled()
{
tracing::warn!(
"{:?} nat 2 nat packet, src: {} dst: {} not allow kcp input",
self.get_tcp_proxy().get_transport_type(),
ip_packet.get_source(),
ip_packet.get_destination()
);
return false;
}
};
let hdr = zc_packet.mut_peer_manager_header().unwrap();
hdr.to_peer_id = self.get_tcp_proxy().get_my_peer_id().into();
if self.get_tcp_proxy().get_transport_type() == TcpProxyEntryTransportType::Kcp {
hdr.set_kcp_src_modified(true);
}
true
}
}
pub struct KcpProxySrc { pub struct KcpProxySrc {
kcp_endpoint: Arc<KcpEndpoint>, kcp_endpoint: Arc<KcpEndpoint>,
peer_manager: Arc<PeerManager>, peer_manager: Arc<PeerManager>,
@@ -387,50 +296,6 @@ pub struct KcpProxyDst {
tasks: JoinSet<()>, tasks: JoinSet<()>,
} }
#[derive(Clone)]
pub struct ProxyAclHandler {
pub acl_filter: Arc<AclFilter>,
pub packet_info: PacketInfo,
pub chain_type: ChainType,
}
impl ProxyAclHandler {
pub fn handle_packet(&self, buf: &[u8]) -> Result<()> {
let mut packet_info = self.packet_info.clone();
packet_info.packet_size = buf.len();
let ret = self
.acl_filter
.get_processor()
.process_packet(&packet_info, self.chain_type);
self.acl_filter.handle_acl_result(
&ret,
&packet_info,
self.chain_type,
&self.acl_filter.get_processor(),
);
if !matches!(ret.action, Action::Allow) {
return Err(anyhow::anyhow!("acl denied").into());
}
Ok(())
}
pub async fn copy_bidirection_with_acl(
&self,
src: impl AsyncRead + AsyncWrite + Unpin,
mut dst: impl AsyncRead + AsyncWrite + Unpin,
) -> Result<()> {
let (src_reader, src_writer) = tokio::io::split(src);
let src_reader = InspectReader::new(src_reader, |buf| {
let _ = self.handle_packet(buf);
});
let mut src = tokio::io::join(src_reader, src_writer);
copy_bidirectional(&mut src, &mut dst).await?;
Ok(())
}
}
impl KcpProxyDst { impl KcpProxyDst {
pub async fn new(peer_manager: Arc<PeerManager>) -> Self { pub async fn new(peer_manager: Arc<PeerManager>) -> Self {
let mut kcp_endpoint = create_kcp_endpoint(); let mut kcp_endpoint = create_kcp_endpoint();
+3
View File
@@ -16,8 +16,11 @@ pub mod fast_socks5;
#[cfg(feature = "socks5")] #[cfg(feature = "socks5")]
pub mod socks5; pub mod socks5;
#[cfg(feature = "kcp")]
pub mod kcp_proxy; pub mod kcp_proxy;
mod wrapped_proxy;
#[cfg(feature = "quic")]
pub mod quic_proxy; pub mod quic_proxy;
#[derive(Debug)] #[derive(Debug)]
+3 -3
View File
@@ -17,8 +17,8 @@ use crate::common::error::Result;
use crate::common::global_ctx::{ArcGlobalCtx, GlobalCtx}; use crate::common::global_ctx::{ArcGlobalCtx, GlobalCtx};
use crate::common::join_joinset_background; use crate::common::join_joinset_background;
use crate::defer; use crate::defer;
use crate::gateway::kcp_proxy::{ProxyAclHandler, TcpProxyForKcpSrcTrait};
use crate::gateway::tcp_proxy::{NatDstConnector, NatDstTcpConnector, TcpProxy}; use crate::gateway::tcp_proxy::{NatDstConnector, NatDstTcpConnector, TcpProxy};
use crate::gateway::wrapped_proxy::{ProxyAclHandler, TcpProxyForWrappedSrcTrait};
use crate::gateway::CidrSet; use crate::gateway::CidrSet;
use crate::peers::peer_manager::PeerManager; use crate::peers::peer_manager::PeerManager;
use crate::proto::acl::{ChainType, Protocol}; use crate::proto::acl::{ChainType, Protocol};
@@ -184,14 +184,14 @@ impl NatDstConnector for NatDstQUICConnector {
struct TcpProxyForQUICSrc(Arc<TcpProxy<NatDstQUICConnector>>); struct TcpProxyForQUICSrc(Arc<TcpProxy<NatDstQUICConnector>>);
#[async_trait::async_trait] #[async_trait::async_trait]
impl TcpProxyForKcpSrcTrait for TcpProxyForQUICSrc { impl TcpProxyForWrappedSrcTrait for TcpProxyForQUICSrc {
type Connector = NatDstQUICConnector; type Connector = NatDstQUICConnector;
fn get_tcp_proxy(&self) -> &Arc<TcpProxy<Self::Connector>> { fn get_tcp_proxy(&self) -> &Arc<TcpProxy<Self::Connector>> {
&self.0 &self.0
} }
async fn check_dst_allow_kcp_input(&self, dst_ip: &Ipv4Addr) -> bool { async fn check_dst_allow_wrapped_input(&self, dst_ip: &Ipv4Addr) -> bool {
let Some(peer_manager) = self.0.get_peer_manager() else { let Some(peer_manager) = self.0.get_peer_manager() else {
return false; return false;
}; };
+29 -3
View File
@@ -9,9 +9,12 @@ use std::{
}; };
use crossbeam::atomic::AtomicCell; use crossbeam::atomic::AtomicCell;
#[cfg(feature = "kcp")]
use kcp_sys::{endpoint::KcpEndpoint, stream::KcpStream}; use kcp_sys::{endpoint::KcpEndpoint, stream::KcpStream};
use tokio_util::sync::{CancellationToken, DropGuard}; use tokio_util::sync::{CancellationToken, DropGuard};
#[cfg(feature = "kcp")]
use crate::gateway::kcp_proxy::NatDstKcpConnector;
use crate::{ use crate::{
common::{ common::{
config::PortForwardConfig, global_ctx::GlobalCtxEvent, join_joinset_background, config::PortForwardConfig, global_ctx::GlobalCtxEvent, join_joinset_background,
@@ -25,7 +28,6 @@ use crate::{
util::stream::tcp_connect_with_timeout, util::stream::tcp_connect_with_timeout,
}, },
ip_reassembler::IpReassembler, ip_reassembler::IpReassembler,
kcp_proxy::NatDstKcpConnector,
tokio_smoltcp::{channel_device, BufferSize, Net, NetConfig}, tokio_smoltcp::{channel_device, BufferSize, Net, NetConfig},
}, },
tunnel::{ tunnel::{
@@ -52,6 +54,7 @@ use crate::{
peers::{peer_manager::PeerManager, PeerPacketFilter}, peers::{peer_manager::PeerManager, PeerPacketFilter},
}; };
#[cfg(feature = "kcp")]
use super::tcp_proxy::NatDstConnector as _; use super::tcp_proxy::NatDstConnector as _;
enum SocksUdpSocket { enum SocksUdpSocket {
@@ -78,6 +81,7 @@ impl SocksUdpSocket {
enum SocksTcpStream { enum SocksTcpStream {
Tcp(tokio::net::TcpStream), Tcp(tokio::net::TcpStream),
SmolTcp(super::tokio_smoltcp::TcpStream), SmolTcp(super::tokio_smoltcp::TcpStream),
#[cfg(feature = "kcp")]
Kcp(KcpStream), Kcp(KcpStream),
} }
@@ -92,6 +96,7 @@ impl AsyncRead for SocksTcpStream {
SocksTcpStream::SmolTcp(ref mut stream) => { SocksTcpStream::SmolTcp(ref mut stream) => {
std::pin::Pin::new(stream).poll_read(cx, buf) std::pin::Pin::new(stream).poll_read(cx, buf)
} }
#[cfg(feature = "kcp")]
SocksTcpStream::Kcp(ref mut stream) => std::pin::Pin::new(stream).poll_read(cx, buf), SocksTcpStream::Kcp(ref mut stream) => std::pin::Pin::new(stream).poll_read(cx, buf),
} }
} }
@@ -108,6 +113,7 @@ impl AsyncWrite for SocksTcpStream {
SocksTcpStream::SmolTcp(ref mut stream) => { SocksTcpStream::SmolTcp(ref mut stream) => {
std::pin::Pin::new(stream).poll_write(cx, buf) std::pin::Pin::new(stream).poll_write(cx, buf)
} }
#[cfg(feature = "kcp")]
SocksTcpStream::Kcp(ref mut stream) => std::pin::Pin::new(stream).poll_write(cx, buf), SocksTcpStream::Kcp(ref mut stream) => std::pin::Pin::new(stream).poll_write(cx, buf),
} }
} }
@@ -119,6 +125,7 @@ impl AsyncWrite for SocksTcpStream {
match self.get_mut() { match self.get_mut() {
SocksTcpStream::Tcp(ref mut stream) => std::pin::Pin::new(stream).poll_flush(cx), SocksTcpStream::Tcp(ref mut stream) => std::pin::Pin::new(stream).poll_flush(cx),
SocksTcpStream::SmolTcp(ref mut stream) => std::pin::Pin::new(stream).poll_flush(cx), SocksTcpStream::SmolTcp(ref mut stream) => std::pin::Pin::new(stream).poll_flush(cx),
#[cfg(feature = "kcp")]
SocksTcpStream::Kcp(ref mut stream) => std::pin::Pin::new(stream).poll_flush(cx), SocksTcpStream::Kcp(ref mut stream) => std::pin::Pin::new(stream).poll_flush(cx),
} }
} }
@@ -130,6 +137,7 @@ impl AsyncWrite for SocksTcpStream {
match self.get_mut() { match self.get_mut() {
SocksTcpStream::Tcp(ref mut stream) => std::pin::Pin::new(stream).poll_shutdown(cx), SocksTcpStream::Tcp(ref mut stream) => std::pin::Pin::new(stream).poll_shutdown(cx),
SocksTcpStream::SmolTcp(ref mut stream) => std::pin::Pin::new(stream).poll_shutdown(cx), SocksTcpStream::SmolTcp(ref mut stream) => std::pin::Pin::new(stream).poll_shutdown(cx),
#[cfg(feature = "kcp")]
SocksTcpStream::Kcp(ref mut stream) => std::pin::Pin::new(stream).poll_shutdown(cx), SocksTcpStream::Kcp(ref mut stream) => std::pin::Pin::new(stream).poll_shutdown(cx),
} }
} }
@@ -211,12 +219,14 @@ impl Drop for SmolTcpConnector {
} }
} }
#[cfg(feature = "kcp")]
struct Socks5KcpConnector { struct Socks5KcpConnector {
kcp_endpoint: Weak<KcpEndpoint>, kcp_endpoint: Weak<KcpEndpoint>,
peer_mgr: Weak<PeerManager>, peer_mgr: Weak<PeerManager>,
src_addr: SocketAddr, src_addr: SocketAddr,
} }
#[cfg(feature = "kcp")]
#[async_trait::async_trait] #[async_trait::async_trait]
impl AsyncTcpConnector for Socks5KcpConnector { impl AsyncTcpConnector for Socks5KcpConnector {
type S = SocksTcpStream; type S = SocksTcpStream;
@@ -242,6 +252,7 @@ impl AsyncTcpConnector for Socks5KcpConnector {
} }
struct Socks5AutoConnector { struct Socks5AutoConnector {
#[cfg(feature = "kcp")]
kcp_endpoint: Option<Weak<KcpEndpoint>>, kcp_endpoint: Option<Weak<KcpEndpoint>>,
peer_mgr: Weak<PeerManager>, peer_mgr: Weak<PeerManager>,
entries: Socks5EntrySet, entries: Socks5EntrySet,
@@ -288,6 +299,7 @@ impl AsyncTcpConnector for Socks5AutoConnector {
let dst_allow_kcp = peer_mgr_arc.check_allow_kcp_to_dst(&addr.ip()).await; let dst_allow_kcp = peer_mgr_arc.check_allow_kcp_to_dst(&addr.ip()).await;
tracing::debug!("dst_allow_kcp: {:?}", dst_allow_kcp); tracing::debug!("dst_allow_kcp: {:?}", dst_allow_kcp);
#[cfg(feature = "kcp")]
let connector: Box<dyn AsyncTcpConnector<S = SocksTcpStream> + Send> = let connector: Box<dyn AsyncTcpConnector<S = SocksTcpStream> + Send> =
match (&self.kcp_endpoint, dst_allow_kcp) { match (&self.kcp_endpoint, dst_allow_kcp) {
(Some(kcp_endpoint), true) => Box::new(Socks5KcpConnector { (Some(kcp_endpoint), true) => Box::new(Socks5KcpConnector {
@@ -301,6 +313,12 @@ impl AsyncTcpConnector for Socks5AutoConnector {
current_entry: std::sync::Mutex::new(None), current_entry: std::sync::Mutex::new(None),
}), }),
}; };
#[cfg(not(feature = "kcp"))]
let connector = Box::new(SmolTcpConnector {
net: self.smoltcp_net.clone().unwrap(),
entries: self.entries.clone(),
current_entry: std::sync::Mutex::new(None),
});
let ret = connector.tcp_connect(addr, timeout_s).await; let ret = connector.tcp_connect(addr, timeout_s).await;
self.inner_connector.lock().replace(Box::new(connector)); self.inner_connector.lock().replace(Box::new(connector));
@@ -490,6 +508,7 @@ pub struct Socks5Server {
udp_client_map: Arc<DashMap<UdpClientKey, Arc<UdpClientInfo>>>, udp_client_map: Arc<DashMap<UdpClientKey, Arc<UdpClientInfo>>>,
udp_forward_task: Arc<DashMap<UdpClientKey, ScopedTask<()>>>, udp_forward_task: Arc<DashMap<UdpClientKey, ScopedTask<()>>>,
#[cfg(feature = "kcp")]
kcp_endpoint: Mutex<Option<Weak<KcpEndpoint>>>, kcp_endpoint: Mutex<Option<Weak<KcpEndpoint>>>,
socks5_enabled: Arc<AtomicBool>, socks5_enabled: Arc<AtomicBool>,
@@ -603,6 +622,7 @@ impl Socks5Server {
udp_client_map: Arc::new(DashMap::new()), udp_client_map: Arc::new(DashMap::new()),
udp_forward_task: Arc::new(DashMap::new()), udp_forward_task: Arc::new(DashMap::new()),
#[cfg(feature = "kcp")]
kcp_endpoint: Mutex::new(None), kcp_endpoint: Mutex::new(None),
socks5_enabled: Arc::new(AtomicBool::new(false)), socks5_enabled: Arc::new(AtomicBool::new(false)),
@@ -662,9 +682,12 @@ impl Socks5Server {
pub async fn run( pub async fn run(
self: &Arc<Self>, self: &Arc<Self>,
kcp_endpoint: Option<Weak<KcpEndpoint>>, #[cfg(feature = "kcp")] kcp_endpoint: Option<Weak<KcpEndpoint>>,
) -> Result<(), Error> { ) -> Result<(), Error> {
*self.kcp_endpoint.lock().await = kcp_endpoint.clone(); #[cfg(feature = "kcp")]
{
*self.kcp_endpoint.lock().await = kcp_endpoint.clone();
}
if let Some(proxy_url) = self.global_ctx.config.get_socks5_portal() { if let Some(proxy_url) = self.global_ctx.config.get_socks5_portal() {
let bind_addr = format!( let bind_addr = format!(
"{}:{}", "{}:{}",
@@ -692,6 +715,7 @@ impl Socks5Server {
.as_ref() .as_ref()
.map(|net| net.smoltcp_net.clone()), .map(|net| net.smoltcp_net.clone()),
entries: entries.clone(), entries: entries.clone(),
#[cfg(feature = "kcp")]
kcp_endpoint: kcp_endpoint.clone(), kcp_endpoint: kcp_endpoint.clone(),
peer_mgr: peer_manager.clone(), peer_mgr: peer_manager.clone(),
src_addr: addr, src_addr: addr,
@@ -811,6 +835,7 @@ impl Socks5Server {
let tasks = Arc::new(std::sync::Mutex::new(JoinSet::new())); let tasks = Arc::new(std::sync::Mutex::new(JoinSet::new()));
join_joinset_background(tasks.clone(), "tcp port forward".to_string()); join_joinset_background(tasks.clone(), "tcp port forward".to_string());
let forward_tasks = tasks; let forward_tasks = tasks;
#[cfg(feature = "kcp")]
let kcp_endpoint = self.kcp_endpoint.lock().await.clone(); let kcp_endpoint = self.kcp_endpoint.lock().await.clone();
let peer_mgr = self.peer_manager.clone(); let peer_mgr = self.peer_manager.clone();
let cancel_token = CancellationToken::new(); let cancel_token = CancellationToken::new();
@@ -843,6 +868,7 @@ impl Socks5Server {
); );
let connector = Socks5AutoConnector { let connector = Socks5AutoConnector {
#[cfg(feature = "kcp")]
kcp_endpoint: kcp_endpoint.clone(), kcp_endpoint: kcp_endpoint.clone(),
peer_mgr: peer_mgr.clone(), peer_mgr: peer_mgr.clone(),
entries: entries.clone(), entries: entries.clone(),
+4
View File
@@ -201,6 +201,7 @@ impl ProxyTcpStream {
} }
} }
#[cfg(feature = "smoltcp")]
type SmolTcpAcceptResult = Result<(tokio_smoltcp::TcpStream, SocketAddr)>; type SmolTcpAcceptResult = Result<(tokio_smoltcp::TcpStream, SocketAddr)>;
#[cfg(feature = "smoltcp")] #[cfg(feature = "smoltcp")]
struct SmolTcpListener { struct SmolTcpListener {
@@ -331,6 +332,7 @@ pub struct TcpProxy<C: NatDstConnector> {
smoltcp_stack_receiver: Arc<Mutex<Option<mpsc::Receiver<ZCPacket>>>>, smoltcp_stack_receiver: Arc<Mutex<Option<mpsc::Receiver<ZCPacket>>>>,
#[cfg(feature = "smoltcp")] #[cfg(feature = "smoltcp")]
smoltcp_net: Arc<Mutex<Option<Net>>>, smoltcp_net: Arc<Mutex<Option<Net>>>,
#[cfg(feature = "smoltcp")]
smoltcp_listener_tx: std::sync::Mutex<Option<mpsc::UnboundedSender<SmolTcpAcceptResult>>>, smoltcp_listener_tx: std::sync::Mutex<Option<mpsc::UnboundedSender<SmolTcpAcceptResult>>>,
enable_smoltcp: Arc<AtomicBool>, enable_smoltcp: Arc<AtomicBool>,
@@ -461,6 +463,7 @@ impl<C: NatDstConnector> TcpProxy<C> {
#[cfg(feature = "smoltcp")] #[cfg(feature = "smoltcp")]
smoltcp_net: Arc::new(Mutex::new(None)), smoltcp_net: Arc::new(Mutex::new(None)),
#[cfg(feature = "smoltcp")]
smoltcp_listener_tx: std::sync::Mutex::new(None), smoltcp_listener_tx: std::sync::Mutex::new(None),
enable_smoltcp: Arc::new(AtomicBool::new(true)), enable_smoltcp: Arc::new(AtomicBool::new(true)),
@@ -930,6 +933,7 @@ impl<C: NatDstConnector> TcpProxy<C> {
tracing::info!(src = ?src, ?real_dst, ?mapped_dst, old_entry = ?old_val, "tcp syn received"); tracing::info!(src = ?src, ?real_dst, ?mapped_dst, old_entry = ?old_val, "tcp syn received");
// if smoltcp is enabled, add the listener to the net // if smoltcp is enabled, add the listener to the net
#[cfg(feature = "smoltcp")]
if self.is_smoltcp_enabled() { if self.is_smoltcp_enabled() {
let smoltcp_listener_tx = self.smoltcp_listener_tx.lock().unwrap().clone().unwrap(); let smoltcp_listener_tx = self.smoltcp_listener_tx.lock().unwrap().clone().unwrap();
SmolTcpListener::add_listener( SmolTcpListener::add_listener(
+150
View File
@@ -0,0 +1,150 @@
use std::{
net::{IpAddr, Ipv4Addr, SocketAddr},
sync::Arc,
};
use pnet::packet::{
ip::IpNextHeaderProtocols,
ipv4::Ipv4Packet,
tcp::{TcpFlags, TcpPacket},
Packet as _,
};
use tokio::io::{copy_bidirectional, AsyncRead, AsyncWrite};
use tokio_util::io::InspectReader;
use crate::{
common::{acl_processor::PacketInfo, error::Result},
gateway::tcp_proxy::{NatDstConnector, TcpProxy},
peers::{acl_filter::AclFilter, NicPacketFilter},
proto::{
acl::{Action, ChainType},
api::instance::TcpProxyEntryTransportType,
},
tunnel::packet_def::ZCPacket,
};
#[derive(Clone)]
pub struct ProxyAclHandler {
pub acl_filter: Arc<AclFilter>,
pub packet_info: PacketInfo,
pub chain_type: ChainType,
}
impl ProxyAclHandler {
pub fn handle_packet(&self, buf: &[u8]) -> Result<()> {
let mut packet_info = self.packet_info.clone();
packet_info.packet_size = buf.len();
let ret = self
.acl_filter
.get_processor()
.process_packet(&packet_info, self.chain_type);
self.acl_filter.handle_acl_result(
&ret,
&packet_info,
self.chain_type,
&self.acl_filter.get_processor(),
);
if !matches!(ret.action, Action::Allow) {
return Err(anyhow::anyhow!("acl denied").into());
}
Ok(())
}
pub async fn copy_bidirection_with_acl(
&self,
src: impl AsyncRead + AsyncWrite + Unpin,
mut dst: impl AsyncRead + AsyncWrite + Unpin,
) -> Result<()> {
let (src_reader, src_writer) = tokio::io::split(src);
let src_reader = InspectReader::new(src_reader, |buf| {
let _ = self.handle_packet(buf);
});
let mut src = tokio::io::join(src_reader, src_writer);
copy_bidirectional(&mut src, &mut dst).await?;
Ok(())
}
}
#[async_trait::async_trait]
pub(crate) trait TcpProxyForWrappedSrcTrait: Send + Sync + 'static {
type Connector: NatDstConnector;
fn get_tcp_proxy(&self) -> &Arc<TcpProxy<Self::Connector>>;
async fn check_dst_allow_wrapped_input(&self, dst_ip: &Ipv4Addr) -> bool;
}
#[async_trait::async_trait]
impl<C: NatDstConnector, T: TcpProxyForWrappedSrcTrait<Connector = C>> NicPacketFilter for T {
async fn try_process_packet_from_nic(&self, zc_packet: &mut ZCPacket) -> bool {
let ret = self
.get_tcp_proxy()
.try_process_packet_from_nic(zc_packet)
.await;
if ret {
return true;
}
let data = zc_packet.payload();
let ip_packet = Ipv4Packet::new(data).unwrap();
if ip_packet.get_version() != 4
|| ip_packet.get_next_level_protocol() != IpNextHeaderProtocols::Tcp
{
return false;
}
// if no connection is established, only allow SYN packet
let tcp_packet = TcpPacket::new(ip_packet.payload()).unwrap();
let is_syn = tcp_packet.get_flags() & TcpFlags::SYN != 0
&& tcp_packet.get_flags() & TcpFlags::ACK == 0;
if is_syn {
// only check dst feature flag when SYN packet
if !self
.check_dst_allow_wrapped_input(&ip_packet.get_destination())
.await
{
tracing::warn!(
"{:?} proxy src: dst {} not allow wrapped input",
self.get_tcp_proxy().get_transport_type(),
ip_packet.get_destination()
);
return false;
}
} else {
// if not syn packet, only allow established connection
if !self
.get_tcp_proxy()
.is_tcp_proxy_connection(SocketAddr::new(
IpAddr::V4(ip_packet.get_source()),
tcp_packet.get_source(),
))
{
return false;
}
}
if let Some(my_ipv4) = self.get_tcp_proxy().get_global_ctx().get_ipv4() {
// this is a net-to-net packet, only allow it when smoltcp is enabled
// because the syn-ack packet will not be through and handled by the tun device when
// the source ip is in the local network
if ip_packet.get_source() != my_ipv4.address()
&& !self.get_tcp_proxy().is_smoltcp_enabled()
{
tracing::warn!(
"{:?} nat 2 nat packet, src: {} dst: {} not allow wrapped input",
self.get_tcp_proxy().get_transport_type(),
ip_packet.get_source(),
ip_packet.get_destination()
);
return false;
}
};
let hdr = zc_packet.mut_peer_manager_header().unwrap();
hdr.to_peer_id = self.get_tcp_proxy().get_my_peer_id().into();
if self.get_tcp_proxy().get_transport_type() == TcpProxyEntryTransportType::Kcp {
hdr.set_kcp_src_modified(true);
}
true
}
}
+7 -1
View File
@@ -1,13 +1,19 @@
// This module is copy and modified from https://github.com/fanyang89/libdns // This module is copy and modified from https://github.com/fanyang89/libdns
#[cfg(feature = "magic-dns")]
pub(crate) mod config; pub(crate) mod config;
#[cfg(feature = "magic-dns")]
pub(crate) mod server; pub(crate) mod server;
#[cfg(feature = "magic-dns")]
pub mod client_instance; pub mod client_instance;
#[cfg(feature = "magic-dns")]
pub mod runner; pub mod runner;
#[cfg(feature = "magic-dns")]
pub mod server_instance; pub mod server_instance;
#[cfg(feature = "magic-dns")]
pub mod system_config; pub mod system_config;
#[cfg(test)] #[cfg(all(test, feature = "tun", feature = "magic-dns"))]
mod tests; mod tests;
pub static MAGIC_DNS_INSTANCE_ADDR: &str = "tcp://127.0.0.1:49813"; pub static MAGIC_DNS_INSTANCE_ADDR: &str = "tcp://127.0.0.1:49813";
+95 -38
View File
@@ -1,16 +1,20 @@
#[cfg(feature = "tun")]
use std::any::Any; use std::any::Any;
use std::collections::HashSet; use std::collections::HashSet;
use std::net::{IpAddr, Ipv4Addr}; use std::net::{IpAddr, Ipv4Addr};
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
#[cfg(feature = "tun")]
use std::time::Duration; use std::time::Duration;
use anyhow::Context; use anyhow::Context;
use cidr::{IpCidr, Ipv4Inet}; use cidr::{IpCidr, Ipv4Inet};
use futures::FutureExt; use futures::FutureExt;
use tokio::sync::{oneshot, Notify}; use tokio::sync::{Mutex, Notify};
use tokio::{sync::Mutex, task::JoinSet}; #[cfg(feature = "tun")]
use tokio::{sync::oneshot, task::JoinSet};
#[cfg(feature = "magic-dns")]
use tokio_util::sync::CancellationToken; use tokio_util::sync::CancellationToken;
use crate::common::acl_processor::AclRuleBuilder; use crate::common::acl_processor::AclRuleBuilder;
@@ -24,15 +28,19 @@ use crate::connector::manual::{ConnectorManagerRpcService, ManualConnectorManage
use crate::connector::tcp_hole_punch::TcpHolePunchConnector; use crate::connector::tcp_hole_punch::TcpHolePunchConnector;
use crate::connector::udp_hole_punch::UdpHolePunchConnector; use crate::connector::udp_hole_punch::UdpHolePunchConnector;
use crate::gateway::icmp_proxy::IcmpProxy; use crate::gateway::icmp_proxy::IcmpProxy;
#[cfg(feature = "kcp")]
use crate::gateway::kcp_proxy::{KcpProxyDst, KcpProxyDstRpcService, KcpProxySrc}; use crate::gateway::kcp_proxy::{KcpProxyDst, KcpProxyDstRpcService, KcpProxySrc};
#[cfg(feature = "quic")]
use crate::gateway::quic_proxy::{QUICProxyDst, QUICProxyDstRpcService, QUICProxySrc}; use crate::gateway::quic_proxy::{QUICProxyDst, QUICProxyDstRpcService, QUICProxySrc};
use crate::gateway::tcp_proxy::{NatDstTcpConnector, TcpProxy, TcpProxyRpcService}; use crate::gateway::tcp_proxy::{NatDstTcpConnector, TcpProxy, TcpProxyRpcService};
use crate::gateway::udp_proxy::UdpProxy; use crate::gateway::udp_proxy::UdpProxy;
use crate::peer_center::instance::PeerCenterInstance; use crate::peer_center::instance::PeerCenterInstance;
use crate::peers::peer_conn::PeerConnId; use crate::peers::peer_conn::PeerConnId;
use crate::peers::peer_manager::{PeerManager, RouteAlgoType}; use crate::peers::peer_manager::{PeerManager, RouteAlgoType};
#[cfg(feature = "tun")]
use crate::peers::recv_packet_from_chan;
use crate::peers::rpc_service::PeerManagerRpcService; use crate::peers::rpc_service::PeerManagerRpcService;
use crate::peers::{create_packet_recv_chan, recv_packet_from_chan, PacketRecvChanReceiver}; use crate::peers::{create_packet_recv_chan, PacketRecvChanReceiver};
use crate::proto::api::config::{ use crate::proto::api::config::{
ConfigPatchAction, ConfigRpc, GetConfigRequest, GetConfigResponse, PatchConfigRequest, ConfigPatchAction, ConfigRpc, GetConfigRequest, GetConfigResponse, PatchConfigRequest,
PatchConfigResponse, PortForwardPatch, PatchConfigResponse, PortForwardPatch,
@@ -53,8 +61,8 @@ use crate::rpc_service::InstanceRpcService;
use crate::utils::weak_upgrade; use crate::utils::weak_upgrade;
use crate::vpn_portal::{self, VpnPortal}; use crate::vpn_portal::{self, VpnPortal};
use super::dns_server::runner::DnsRunner; #[cfg(feature = "magic-dns")]
use super::dns_server::MAGIC_DNS_FAKE_IP; use super::dns_server::{runner::DnsRunner, MAGIC_DNS_FAKE_IP};
use super::listeners::ListenerManager; use super::listeners::ListenerManager;
#[cfg(feature = "socks5")] #[cfg(feature = "socks5")]
@@ -120,35 +128,31 @@ impl IpProxy {
#[cfg(feature = "tun")] #[cfg(feature = "tun")]
type NicCtx = super::virtual_nic::NicCtx; type NicCtx = super::virtual_nic::NicCtx;
#[cfg(not(feature = "tun"))]
struct NicCtx;
#[cfg(not(feature = "tun"))]
impl NicCtx {
pub fn new(
_global_ctx: ArcGlobalCtx,
_peer_manager: &Arc<PeerManager>,
_peer_packet_receiver: Arc<Mutex<PacketRecvChanReceiver>>,
) -> Self {
Self
}
pub async fn run(&mut self, _ipv4_addr: Ipv4Addr) -> Result<(), Error> {
Ok(())
}
}
#[cfg(feature = "magic-dns")]
struct MagicDnsContainer { struct MagicDnsContainer {
dns_runner_task: ScopedTask<()>, dns_runner_task: ScopedTask<()>,
dns_runner_cancel_token: CancellationToken, dns_runner_cancel_token: CancellationToken,
} }
// nic container will be cleared when dhcp ip changed // nic container will be cleared when dhcp ip changed
#[cfg(feature = "tun")]
pub struct NicCtxContainer { pub struct NicCtxContainer {
nic_ctx: Option<Box<dyn Any + 'static + Send>>, nic_ctx: Option<Box<dyn Any + 'static + Send>>,
#[cfg(feature = "magic-dns")]
magic_dns: Option<MagicDnsContainer>, magic_dns: Option<MagicDnsContainer>,
} }
#[cfg(feature = "tun")]
impl NicCtxContainer { impl NicCtxContainer {
#[cfg(not(feature = "magic-dns"))]
fn new(nic_ctx: NicCtx) -> Self {
Self {
nic_ctx: Some(Box::new(nic_ctx)),
}
}
#[cfg(feature = "magic-dns")]
fn new(nic_ctx: NicCtx, dns_runner: Option<DnsRunner>) -> Self { fn new(nic_ctx: NicCtx, dns_runner: Option<DnsRunner>) -> Self {
if let Some(mut dns_runner) = dns_runner { if let Some(mut dns_runner) = dns_runner {
let token = CancellationToken::new(); let token = CancellationToken::new();
@@ -174,11 +178,13 @@ impl NicCtxContainer {
fn new_with_any<T: 'static + Send>(ctx: T) -> Self { fn new_with_any<T: 'static + Send>(ctx: T) -> Self {
Self { Self {
nic_ctx: Some(Box::new(ctx)), nic_ctx: Some(Box::new(ctx)),
#[cfg(feature = "magic-dns")]
magic_dns: None, magic_dns: None,
} }
} }
} }
#[cfg(feature = "tun")]
type ArcNicCtx = Arc<Mutex<Option<NicCtxContainer>>>; type ArcNicCtx = Arc<Mutex<Option<NicCtxContainer>>>;
pub struct InstanceRpcServerHook { pub struct InstanceRpcServerHook {
@@ -236,6 +242,7 @@ impl RpcServerHook for InstanceRpcServerHook {
#[derive(Clone)] #[derive(Clone)]
pub struct InstanceConfigPatcher { pub struct InstanceConfigPatcher {
global_ctx: Weak<GlobalCtx>, global_ctx: Weak<GlobalCtx>,
#[cfg(feature = "socks5")]
socks5_server: Weak<Socks5Server>, socks5_server: Weak<Socks5Server>,
peer_manager: Weak<PeerManager>, peer_manager: Weak<PeerManager>,
conn_manager: Weak<ManualConnectorManager>, conn_manager: Weak<ManualConnectorManager>,
@@ -313,6 +320,7 @@ impl InstanceConfigPatcher {
if port_forwards.is_empty() { if port_forwards.is_empty() {
return Ok(()); return Ok(());
} }
#[cfg(feature = "socks5")]
let Some(socks5_server) = self.socks5_server.upgrade() else { let Some(socks5_server) = self.socks5_server.upgrade() else {
return Err(anyhow::anyhow!("socks5 server not available")); return Err(anyhow::anyhow!("socks5 server not available"));
}; };
@@ -326,6 +334,7 @@ impl InstanceConfigPatcher {
global_ctx global_ctx
.config .config
.set_port_forwards(current_forwards.clone()); .set_port_forwards(current_forwards.clone());
#[cfg(feature = "socks5")]
socks5_server socks5_server
.reload_port_forwards(&current_forwards) .reload_port_forwards(&current_forwards)
.await .await
@@ -513,6 +522,7 @@ pub struct Instance {
id: uuid::Uuid, id: uuid::Uuid,
#[cfg(feature = "tun")]
nic_ctx: ArcNicCtx, nic_ctx: ArcNicCtx,
peer_packet_receiver: Arc<Mutex<PacketRecvChanReceiver>>, peer_packet_receiver: Arc<Mutex<PacketRecvChanReceiver>>,
@@ -525,10 +535,14 @@ pub struct Instance {
ip_proxy: Option<IpProxy>, ip_proxy: Option<IpProxy>,
#[cfg(feature = "kcp")]
kcp_proxy_src: Option<KcpProxySrc>, kcp_proxy_src: Option<KcpProxySrc>,
#[cfg(feature = "kcp")]
kcp_proxy_dst: Option<KcpProxyDst>, kcp_proxy_dst: Option<KcpProxyDst>,
#[cfg(feature = "quic")]
quic_proxy_src: Option<QUICProxySrc>, quic_proxy_src: Option<QUICProxySrc>,
#[cfg(feature = "quic")]
quic_proxy_dst: Option<QUICProxyDst>, quic_proxy_dst: Option<QUICProxyDst>,
peer_center: Arc<PeerCenterInstance>, peer_center: Arc<PeerCenterInstance>,
@@ -596,6 +610,7 @@ impl Instance {
id, id,
peer_packet_receiver: Arc::new(Mutex::new(peer_packet_receiver)), peer_packet_receiver: Arc::new(Mutex::new(peer_packet_receiver)),
#[cfg(feature = "tun")]
nic_ctx: Arc::new(Mutex::new(None)), nic_ctx: Arc::new(Mutex::new(None)),
peer_manager, peer_manager,
@@ -606,10 +621,14 @@ impl Instance {
tcp_hole_puncher: Arc::new(Mutex::new(tcp_hole_puncher)), tcp_hole_puncher: Arc::new(Mutex::new(tcp_hole_puncher)),
ip_proxy: None, ip_proxy: None,
#[cfg(feature = "kcp")]
kcp_proxy_src: None, kcp_proxy_src: None,
#[cfg(feature = "kcp")]
kcp_proxy_dst: None, kcp_proxy_dst: None,
#[cfg(feature = "quic")]
quic_proxy_src: None, quic_proxy_src: None,
#[cfg(feature = "quic")]
quic_proxy_dst: None, quic_proxy_dst: None,
peer_center, peer_center,
@@ -639,10 +658,12 @@ impl Instance {
} }
// use a mock nic ctx to consume packets. // use a mock nic ctx to consume packets.
#[cfg(feature = "tun")]
async fn clear_nic_ctx( async fn clear_nic_ctx(
arc_nic_ctx: ArcNicCtx, arc_nic_ctx: ArcNicCtx,
packet_recv: Arc<Mutex<PacketRecvChanReceiver>>, packet_recv: Arc<Mutex<PacketRecvChanReceiver>>,
) { ) {
#[cfg(feature = "magic-dns")]
if let Some(old_ctx) = arc_nic_ctx.lock().await.take() { if let Some(old_ctx) = arc_nic_ctx.lock().await.take() {
if let Some(dns_runner) = old_ctx.magic_dns { if let Some(dns_runner) = old_ctx.magic_dns {
dns_runner.dns_runner_cancel_token.cancel(); dns_runner.dns_runner_cancel_token.cancel();
@@ -667,6 +688,7 @@ impl Instance {
tracing::debug!("nic ctx cleared."); tracing::debug!("nic ctx cleared.");
} }
#[cfg(feature = "magic-dns")]
fn create_magic_dns_runner( fn create_magic_dns_runner(
peer_mgr: Arc<PeerManager>, peer_mgr: Arc<PeerManager>,
tun_dev: Option<String>, tun_dev: Option<String>,
@@ -686,13 +708,18 @@ impl Instance {
Some(runner) Some(runner)
} }
#[cfg(feature = "tun")]
async fn use_new_nic_ctx( async fn use_new_nic_ctx(
arc_nic_ctx: ArcNicCtx, arc_nic_ctx: ArcNicCtx,
nic_ctx: NicCtx, nic_ctx: NicCtx,
magic_dns: Option<DnsRunner>, #[cfg(feature = "magic-dns")] magic_dns: Option<DnsRunner>,
) { ) {
let mut g = arc_nic_ctx.lock().await; let mut g = arc_nic_ctx.lock().await;
*g = Some(NicCtxContainer::new(nic_ctx, magic_dns)); *g = Some(NicCtxContainer::new(
nic_ctx,
#[cfg(feature = "magic-dns")]
magic_dns,
));
tracing::debug!("nic ctx updated."); tracing::debug!("nic ctx updated.");
} }
@@ -701,6 +728,7 @@ impl Instance {
use rand::Rng; use rand::Rng;
let peer_manager_c = Arc::downgrade(&self.peer_manager.clone()); let peer_manager_c = Arc::downgrade(&self.peer_manager.clone());
let global_ctx_c = self.get_global_ctx(); let global_ctx_c = self.get_global_ctx();
#[cfg(feature = "tun")]
let nic_ctx = self.nic_ctx.clone(); let nic_ctx = self.nic_ctx.clone();
let _peer_packet_receiver = self.peer_packet_receiver.clone(); let _peer_packet_receiver = self.peer_packet_receiver.clone();
tokio::spawn(async move { tokio::spawn(async move {
@@ -765,6 +793,7 @@ impl Instance {
"dhcp start changing ip" "dhcp start changing ip"
); );
#[cfg(feature = "tun")]
Self::clear_nic_ctx(nic_ctx.clone(), _peer_packet_receiver.clone()).await; Self::clear_nic_ctx(nic_ctx.clone(), _peer_packet_receiver.clone()).await;
if let Some(ip) = candidate_ipv4_addr { if let Some(ip) = candidate_ipv4_addr {
@@ -776,11 +805,10 @@ impl Instance {
continue; continue;
} }
#[cfg(not(any( #[cfg(all(
target_os = "android", not(any(target_os = "android", target_os = "ios", target_env = "ohos")),
target_os = "ios", feature = "tun"
target_env = "ohos" ))]
)))]
{ {
let mut new_nic_ctx = NicCtx::new( let mut new_nic_ctx = NicCtx::new(
global_ctx_c.clone(), global_ctx_c.clone(),
@@ -798,10 +826,12 @@ impl Instance {
global_ctx_c.set_ipv4(None); global_ctx_c.set_ipv4(None);
continue; continue;
} }
#[cfg(feature = "magic-dns")]
let ifname = new_nic_ctx.ifname().await; let ifname = new_nic_ctx.ifname().await;
Self::use_new_nic_ctx( Self::use_new_nic_ctx(
nic_ctx.clone(), nic_ctx.clone(),
new_nic_ctx, new_nic_ctx,
#[cfg(feature = "magic-dns")]
Self::create_magic_dns_runner(peer_manager_c.clone(), ifname, ip), Self::create_magic_dns_runner(peer_manager_c.clone(), ifname, ip),
) )
.await; .await;
@@ -819,6 +849,10 @@ impl Instance {
}); });
} }
#[cfg(all(
not(any(target_os = "android", target_os = "ios", target_env = "ohos")),
feature = "tun"
))]
fn check_for_static_ip(&self, first_round_output: oneshot::Sender<Result<(), Error>>) { fn check_for_static_ip(&self, first_round_output: oneshot::Sender<Result<(), Error>>) {
let ipv4_addr = self.global_ctx.get_ipv4(); let ipv4_addr = self.global_ctx.get_ipv4();
let ipv6_addr = self.global_ctx.get_ipv6(); let ipv6_addr = self.global_ctx.get_ipv6();
@@ -862,15 +896,20 @@ impl Instance {
tokio::time::sleep(Duration::from_secs(1)).await; tokio::time::sleep(Duration::from_secs(1)).await;
continue; continue;
} }
let ifname = new_nic_ctx.ifname().await;
// Create Magic DNS runner only if we have IPv4 // Create Magic DNS runner only if we have IPv4
let dns_runner = if let Some(ipv4) = ipv4_addr { #[cfg(feature = "magic-dns")]
Self::create_magic_dns_runner(peer_manager, ifname, ipv4) {
} else { let ifname = new_nic_ctx.ifname().await;
None let dns_runner = if let Some(ipv4) = ipv4_addr {
}; Self::create_magic_dns_runner(peer_manager, ifname, ipv4)
Self::use_new_nic_ctx(nic_ctx.clone(), new_nic_ctx, dns_runner).await; } else {
None
};
Self::use_new_nic_ctx(nic_ctx.clone(), new_nic_ctx, dns_runner).await;
}
#[cfg(not(feature = "magic-dns"))]
Self::use_new_nic_ctx(nic_ctx.clone(), new_nic_ctx).await;
if let Some(output_tx) = output_tx.take() { if let Some(output_tx) = output_tx.take() {
let _ = output_tx.send(Ok(())); let _ = output_tx.send(Ok(()));
@@ -888,6 +927,7 @@ impl Instance {
}); });
} }
#[cfg(feature = "quic")]
async fn run_quic_dst(&mut self) -> Result<(), Error> { async fn run_quic_dst(&mut self) -> Result<(), Error> {
if self.global_ctx.get_flags().disable_quic_input { if self.global_ctx.get_flags().disable_quic_input {
return Ok(()); return Ok(());
@@ -911,11 +951,12 @@ impl Instance {
self.listener_manager.lock().await.run().await?; self.listener_manager.lock().await.run().await?;
self.peer_manager.run().await?; self.peer_manager.run().await?;
Self::clear_nic_ctx(self.nic_ctx.clone(), self.peer_packet_receiver.clone()).await; #[cfg(feature = "tun")]
{
Self::clear_nic_ctx(self.nic_ctx.clone(), self.peer_packet_receiver.clone()).await;
if !self.global_ctx.config.get_flags().no_tun {
#[cfg(not(any(target_os = "android", target_os = "ios", target_env = "ohos")))] #[cfg(not(any(target_os = "android", target_os = "ios", target_env = "ohos")))]
{ if !self.global_ctx.config.get_flags().no_tun {
let (output_tx, output_rx) = oneshot::channel(); let (output_tx, output_rx) = oneshot::channel();
self.check_for_static_ip(output_tx); self.check_for_static_ip(output_tx);
output_rx.await.unwrap()?; output_rx.await.unwrap()?;
@@ -926,24 +967,28 @@ impl Instance {
self.check_dhcp_ip_conflict(); self.check_dhcp_ip_conflict();
} }
#[cfg(feature = "kcp")]
if self.global_ctx.get_flags().enable_kcp_proxy { if self.global_ctx.get_flags().enable_kcp_proxy {
let src_proxy = KcpProxySrc::new(self.get_peer_manager()).await; let src_proxy = KcpProxySrc::new(self.get_peer_manager()).await;
src_proxy.start().await; src_proxy.start().await;
self.kcp_proxy_src = Some(src_proxy); self.kcp_proxy_src = Some(src_proxy);
} }
#[cfg(feature = "kcp")]
if !self.global_ctx.get_flags().disable_kcp_input { if !self.global_ctx.get_flags().disable_kcp_input {
let mut dst_proxy = KcpProxyDst::new(self.get_peer_manager()).await; let mut dst_proxy = KcpProxyDst::new(self.get_peer_manager()).await;
dst_proxy.start().await; dst_proxy.start().await;
self.kcp_proxy_dst = Some(dst_proxy); self.kcp_proxy_dst = Some(dst_proxy);
} }
#[cfg(feature = "quic")]
if self.global_ctx.get_flags().enable_quic_proxy { if self.global_ctx.get_flags().enable_quic_proxy {
let quic_src = QUICProxySrc::new(self.get_peer_manager()).await; let quic_src = QUICProxySrc::new(self.get_peer_manager()).await;
quic_src.start().await; quic_src.start().await;
self.quic_proxy_src = Some(quic_src); self.quic_proxy_src = Some(quic_src);
} }
#[cfg(feature = "quic")]
if !self.global_ctx.get_flags().disable_quic_input { if !self.global_ctx.get_flags().disable_quic_input {
if let Err(e) = self.run_quic_dst().await { if let Err(e) = self.run_quic_dst().await {
eprintln!( eprintln!(
@@ -989,6 +1034,7 @@ impl Instance {
#[cfg(feature = "socks5")] #[cfg(feature = "socks5")]
self.socks5_server self.socks5_server
.run( .run(
#[cfg(feature = "kcp")]
self.kcp_proxy_src self.kcp_proxy_src
.as_ref() .as_ref()
.map(|x| Arc::downgrade(&x.get_kcp_endpoint())), .map(|x| Arc::downgrade(&x.get_kcp_endpoint())),
@@ -1126,6 +1172,7 @@ impl Instance {
#[derive(Clone)] #[derive(Clone)]
pub struct PortForwardManagerRpcService { pub struct PortForwardManagerRpcService {
global_ctx: Weak<GlobalCtx>, global_ctx: Weak<GlobalCtx>,
#[cfg(feature = "socks5")]
socks5_server: Weak<Socks5Server>, socks5_server: Weak<Socks5Server>,
} }
@@ -1146,6 +1193,7 @@ impl Instance {
PortForwardManagerRpcService { PortForwardManagerRpcService {
global_ctx: Arc::downgrade(&self.global_ctx), global_ctx: Arc::downgrade(&self.global_ctx),
#[cfg(feature = "socks5")]
socks5_server: Arc::downgrade(&self.socks5_server), socks5_server: Arc::downgrade(&self.socks5_server),
} }
} }
@@ -1209,6 +1257,7 @@ impl Instance {
pub fn get_config_patcher(&self) -> InstanceConfigPatcher { pub fn get_config_patcher(&self) -> InstanceConfigPatcher {
InstanceConfigPatcher { InstanceConfigPatcher {
global_ctx: Arc::downgrade(&self.global_ctx), global_ctx: Arc::downgrade(&self.global_ctx),
#[cfg(feature = "socks5")]
socks5_server: Arc::downgrade(&self.socks5_server), socks5_server: Arc::downgrade(&self.socks5_server),
peer_manager: Arc::downgrade(&self.peer_manager), peer_manager: Arc::downgrade(&self.peer_manager),
conn_manager: Arc::downgrade(&self.conn_manager), conn_manager: Arc::downgrade(&self.conn_manager),
@@ -1357,6 +1406,7 @@ impl Instance {
Arc::new(TcpProxyRpcService::new(ip_proxy.tcp_proxy.clone())), Arc::new(TcpProxyRpcService::new(ip_proxy.tcp_proxy.clone())),
); );
} }
#[cfg(feature = "kcp")]
if let Some(kcp_proxy) = self.kcp_proxy_src.as_ref() { if let Some(kcp_proxy) = self.kcp_proxy_src.as_ref() {
tcp_proxy_rpc_services.insert( tcp_proxy_rpc_services.insert(
"kcp_src".to_string(), "kcp_src".to_string(),
@@ -1364,6 +1414,7 @@ impl Instance {
); );
} }
#[cfg(feature = "kcp")]
if let Some(kcp_proxy) = self.kcp_proxy_dst.as_ref() { if let Some(kcp_proxy) = self.kcp_proxy_dst.as_ref() {
tcp_proxy_rpc_services.insert( tcp_proxy_rpc_services.insert(
"kcp_dst".to_string(), "kcp_dst".to_string(),
@@ -1371,6 +1422,7 @@ impl Instance {
); );
} }
#[cfg(feature = "quic")]
if let Some(quic_proxy) = self.quic_proxy_src.as_ref() { if let Some(quic_proxy) = self.quic_proxy_src.as_ref() {
tcp_proxy_rpc_services.insert( tcp_proxy_rpc_services.insert(
"quic_src".to_string(), "quic_src".to_string(),
@@ -1378,6 +1430,7 @@ impl Instance {
); );
} }
#[cfg(feature = "quic")]
if let Some(quic_proxy) = self.quic_proxy_dst.as_ref() { if let Some(quic_proxy) = self.quic_proxy_dst.as_ref() {
tcp_proxy_rpc_services.insert( tcp_proxy_rpc_services.insert(
"quic_dst".to_string(), "quic_dst".to_string(),
@@ -1402,6 +1455,7 @@ impl Instance {
self.vpn_portal.clone() self.vpn_portal.clone()
} }
#[cfg(feature = "tun")]
pub fn get_nic_ctx(&self) -> ArcNicCtx { pub fn get_nic_ctx(&self) -> ArcNicCtx {
self.nic_ctx.clone() self.nic_ctx.clone()
} }
@@ -1446,6 +1500,7 @@ impl Instance {
pub async fn clear_resources(&mut self) { pub async fn clear_resources(&mut self) {
self.peer_manager.clear_resources().await; self.peer_manager.clear_resources().await;
#[cfg(feature = "tun")]
let _ = self.nic_ctx.lock().await.take(); let _ = self.nic_ctx.lock().await.take();
} }
} }
@@ -1454,8 +1509,10 @@ impl Drop for Instance {
fn drop(&mut self) { fn drop(&mut self) {
let my_peer_id = self.peer_manager.my_peer_id(); let my_peer_id = self.peer_manager.my_peer_id();
let pm = Arc::downgrade(&self.peer_manager); let pm = Arc::downgrade(&self.peer_manager);
#[cfg(feature = "tun")]
let nic_ctx = self.nic_ctx.clone(); let nic_ctx = self.nic_ctx.clone();
tokio::spawn(async move { tokio::spawn(async move {
#[cfg(feature = "tun")]
nic_ctx.lock().await.take(); nic_ctx.lock().await.take();
if let Some(pm) = pm.upgrade() { if let Some(pm) = pm.upgrade() {
pm.clear_resources().await; pm.clear_resources().await;
+1
View File
@@ -5,6 +5,7 @@ pub mod acl;
pub mod api; pub mod api;
pub mod common; pub mod common;
pub mod error; pub mod error;
#[cfg(feature = "magic-dns")]
pub mod magic_dns; pub mod magic_dns;
pub mod peer_rpc; pub mod peer_rpc;
pub mod web; pub mod web;