From dcfd4d477b25a9dff28688a8d782a1c8924f6da7 Mon Sep 17 00:00:00 2001 From: dev0 Date: Mon, 4 Sep 2023 18:25:48 +1000 Subject: [PATCH] proxy providers --- .cargo/config | 5 +- Cargo.Bazel.lock | 310 ++++++++++-------- Cargo.lock | 65 ++-- README.md | 2 +- WORKSPACE | 10 - clash/tests/data/config/rules.yaml | 63 ++-- clash/tests/data/config/ss-obfs.yaml | 0 clash/tests/data/config/ss.yaml | 2 +- clash_lib/Cargo.toml | 11 +- clash_lib/src/app/api/handlers/provider.rs | 7 +- clash_lib/src/app/dns/config.rs | 12 + clash_lib/src/app/dns/dns_client.rs | 14 +- clash_lib/src/app/dns/helper.rs | 6 +- clash_lib/src/app/outbound/manager.rs | 76 ++++- clash_lib/src/app/outbound/utils.rs | 19 +- .../src/app/proxy_manager/healthcheck.rs | 27 +- .../src/app/proxy_manager/providers/fether.rs | 4 +- .../src/app/proxy_manager/providers/mod.rs | 2 + .../proxy_manager/providers/plain_provider.rs | 6 - .../providers/proxy_set_provider.rs | 35 +- clash_lib/src/config/internal/config.rs | 20 +- clash_lib/src/config/internal/proxy.rs | 3 + clash_lib/src/config/internal/rule.rs | 37 +++ clash_lib/src/proxy/tun/datagram.rs | 6 +- clash_lib/src/proxy/tun/inbound.rs | 30 +- 25 files changed, 469 insertions(+), 303 deletions(-) delete mode 100644 clash/tests/data/config/ss-obfs.yaml diff --git a/.cargo/config b/.cargo/config index 9823a4d5..05d3b376 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,2 +1,5 @@ [build] -target-dir = "target" \ No newline at end of file +target-dir = "target" + +[env] +BORING_BSSL_SOURCE_PATH = { value = "./deps/boringssl/src", relative = true} \ No newline at end of file diff --git a/Cargo.Bazel.lock b/Cargo.Bazel.lock index e14b446a..32f27361 100644 --- a/Cargo.Bazel.lock +++ b/Cargo.Bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "0af5c01f188447da06ff420d36d10dbc2070bb9b583c4e469662e1f2c2c769c7", + "checksum": "768ad301a2943def9ac3944c23c1d3600965319cde69050c1901a9273298005d", "crates": { "addr2line 0.20.0": { "name": "addr2line", @@ -2027,13 +2027,13 @@ }, "license": "BSD-3-Clause" }, - "bindgen 0.65.1": { + "bindgen 0.66.1": { "name": "bindgen", - "version": "0.65.1", + "version": "0.66.1", "repository": { "Http": { - "url": "https://crates.io/api/v1/crates/bindgen/0.65.1/download", - "sha256": "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" + "url": "https://crates.io/api/v1/crates/bindgen/0.66.1/download", + "sha256": "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7" } }, "targets": [ @@ -2070,11 +2070,11 @@ "deps": { "common": [ { - "id": "bindgen 0.65.1", + "id": "bindgen 0.66.1", "target": "build_script_build" }, { - "id": "bitflags 1.3.2", + "id": "bitflags 2.4.0", "target": "bitflags" }, { @@ -2097,10 +2097,6 @@ "id": "peeking_take_while 0.1.2", "target": "peeking_take_while" }, - { - "id": "prettyplease 0.2.12", - "target": "prettyplease" - }, { "id": "proc-macro2 1.0.66", "target": "proc_macro2" @@ -2129,7 +2125,7 @@ "selects": {} }, "edition": "2018", - "version": "0.65.1" + "version": "0.66.1" }, "build_script_attrs": { "data_glob": [ @@ -2140,10 +2136,6 @@ { "id": "clang-sys 1.6.1", "target": "clang_sys" - }, - { - "id": "prettyplease 0.2.12", - "target": "prettyplease" } ], "selects": {} @@ -2187,13 +2179,13 @@ }, "license": "MIT/Apache-2.0" }, - "bitflags 2.3.3": { + "bitflags 2.4.0": { "name": "bitflags", - "version": "2.3.3", + "version": "2.4.0", "repository": { "Http": { - "url": "https://crates.io/api/v1/crates/bitflags/2.3.3/download", - "sha256": "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + "url": "https://crates.io/api/v1/crates/bitflags/2.4.0/download", + "sha256": "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" } }, "targets": [ @@ -2219,7 +2211,7 @@ "selects": {} }, "edition": "2021", - "version": "2.3.3" + "version": "2.4.0" }, "license": "MIT OR Apache-2.0" }, @@ -2352,14 +2344,14 @@ }, "license": "MIT OR Apache-2.0" }, - "boring 2.1.0": { + "boring 3.0.4": { "name": "boring", - "version": "2.1.0", + "version": "3.0.4", "repository": { "Git": { "remote": "https://github.com/Watfaq/boring.git", "commitish": { - "Rev": "a5c2442" + "Rev": "24c006f" }, "strip_prefix": "boring" } @@ -2383,41 +2375,41 @@ "deps": { "common": [ { - "id": "bitflags 1.3.2", + "id": "bitflags 2.4.0", "target": "bitflags" }, { - "id": "boring-sys 2.1.0", + "id": "boring-sys 3.0.4", "target": "boring_sys" }, { "id": "foreign-types 0.5.0", "target": "foreign_types" }, - { - "id": "lazy_static 1.4.0", - "target": "lazy_static" - }, { "id": "libc 0.2.147", "target": "libc" + }, + { + "id": "once_cell 1.18.0", + "target": "once_cell" } ], "selects": {} }, - "edition": "2018", - "version": "2.1.0" + "edition": "2021", + "version": "3.0.4" }, "license": "Apache-2.0" }, - "boring-sys 2.1.0": { + "boring-sys 3.0.4": { "name": "boring-sys", - "version": "2.1.0", + "version": "3.0.4", "repository": { "Git": { "remote": "https://github.com/Watfaq/boring.git", "commitish": { - "Rev": "a5c2442" + "Rev": "24c006f" }, "strip_prefix": "boring-sys" } @@ -2456,14 +2448,14 @@ "deps": { "common": [ { - "id": "boring-sys 2.1.0", + "id": "boring-sys 3.0.4", "target": "build_script_build" } ], "selects": {} }, - "edition": "2018", - "version": "2.1.0" + "edition": "2021", + "version": "3.0.4" }, "build_script_attrs": { "data": { @@ -2478,12 +2470,20 @@ "deps": { "common": [ { - "id": "bindgen 0.65.1", + "id": "bindgen 0.66.1", "target": "bindgen" }, { "id": "cmake 0.1.50", "target": "cmake" + }, + { + "id": "fs_extra 1.3.0", + "target": "fs_extra" + }, + { + "id": "fslock 0.2.1", + "target": "fslock" } ], "selects": {} @@ -3754,11 +3754,11 @@ "target": "base64" }, { - "id": "boring 2.1.0", + "id": "boring 3.0.4", "target": "boring" }, { - "id": "boring-sys 2.1.0", + "id": "boring-sys 3.0.4", "target": "boring_sys" }, { @@ -3826,7 +3826,7 @@ "target": "hyper" }, { - "id": "hyper-boring 2.1.2", + "id": "hyper-boring 3.0.4", "target": "hyper_boring" }, { @@ -3858,7 +3858,7 @@ "target": "netstack_lwip" }, { - "id": "network-interface 1.0.1", + "id": "network-interface 1.0.3", "target": "network_interface" }, { @@ -3902,7 +3902,7 @@ "target": "shadowsocks" }, { - "id": "socket2 0.4.9", + "id": "socket2 0.5.3", "target": "socket2" }, { @@ -3918,7 +3918,7 @@ "target": "tokio" }, { - "id": "tokio-boring 2.1.5", + "id": "tokio-boring 3.0.4", "target": "tokio_boring" }, { @@ -6203,6 +6203,36 @@ }, "license": "Apache-2.0" }, + "fs_extra 1.3.0": { + "name": "fs_extra", + "version": "1.3.0", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/fs_extra/1.3.0/download", + "sha256": "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + } + }, + "targets": [ + { + "Library": { + "crate_name": "fs_extra", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "fs_extra", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2018", + "version": "1.3.0" + }, + "license": "MIT" + }, "fsevent-sys 4.1.0": { "name": "fsevent-sys", "version": "4.1.0", @@ -6242,6 +6272,60 @@ }, "license": "MIT" }, + "fslock 0.2.1": { + "name": "fslock", + "version": "0.2.1", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/fslock/0.2.1/download", + "sha256": "04412b8935272e3a9bae6f48c7bfff74c2911f60525404edfdd28e49884c3bfb" + } + }, + "targets": [ + { + "Library": { + "crate_name": "fslock", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "fslock", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "std" + ], + "selects": {} + }, + "deps": { + "common": [], + "selects": { + "cfg(unix)": [ + { + "id": "libc 0.2.147", + "target": "libc" + } + ], + "cfg(windows)": [ + { + "id": "winapi 0.3.9", + "target": "winapi" + } + ] + } + }, + "edition": "2018", + "version": "0.2.1" + }, + "license": "MIT" + }, "futures 0.3.28": { "name": "futures", "version": "0.3.28", @@ -7871,6 +7955,7 @@ "common": [ "client", "default", + "full", "h2", "http1", "http2", @@ -7956,14 +8041,14 @@ }, "license": "MIT" }, - "hyper-boring 2.1.2": { + "hyper-boring 3.0.4": { "name": "hyper-boring", - "version": "2.1.2", + "version": "3.0.4", "repository": { "Git": { "remote": "https://github.com/Watfaq/boring.git", "commitish": { - "Rev": "a5c2442" + "Rev": "24c006f" }, "strip_prefix": "hyper-boring" } @@ -7998,7 +8083,7 @@ "target": "antidote" }, { - "id": "boring 2.1.0", + "id": "boring 3.0.4", "target": "boring" }, { @@ -8022,7 +8107,7 @@ "target": "tokio" }, { - "id": "tokio-boring 2.1.5", + "id": "tokio-boring 3.0.4", "target": "tokio_boring" }, { @@ -8032,8 +8117,8 @@ ], "selects": {} }, - "edition": "2018", - "version": "2.1.2" + "edition": "2021", + "version": "3.0.4" }, "license": "MIT/Apache-2.0" }, @@ -10277,13 +10362,13 @@ }, "license": null }, - "network-interface 1.0.1": { + "network-interface 1.0.3": { "name": "network-interface", - "version": "1.0.1", + "version": "1.0.3", "repository": { "Http": { - "url": "https://crates.io/api/v1/crates/network-interface/1.0.1/download", - "sha256": "296ae2183dab440e352740b1fcf0589d8058afa40bc29fd163227ddb01fbf539" + "url": "https://crates.io/api/v1/crates/network-interface/1.0.3/download", + "sha256": "afd878f93491173e5d272d0dd3124ff89739e50f276c7b9857ac0d97cc024f96" } }, "targets": [ @@ -10314,7 +10399,7 @@ "deps": { "common": [ { - "id": "network-interface 1.0.1", + "id": "network-interface 1.0.3", "target": "build_script_build" }, { @@ -10323,13 +10408,13 @@ } ], "selects": { - "cfg(target_os = \"linux\")": [ + "cfg(any(target_os = \"android\", target_os = \"linux\"))": [ { "id": "libc 0.2.147", "target": "libc" } ], - "cfg(target_os = \"macos\")": [ + "cfg(any(target_os = \"ios\", target_os = \"macos\"))": [ { "id": "libc 0.2.147", "target": "libc" @@ -10348,7 +10433,7 @@ } }, "edition": "2018", - "version": "1.0.1" + "version": "1.0.3" }, "build_script_attrs": { "data_glob": [ @@ -11714,68 +11799,6 @@ }, "license": "MIT OR Apache-2.0" }, - "prettyplease 0.2.12": { - "name": "prettyplease", - "version": "0.2.12", - "repository": { - "Http": { - "url": "https://crates.io/api/v1/crates/prettyplease/0.2.12/download", - "sha256": "6c64d9ba0963cdcea2e1b2230fbae2bab30eb25a174be395c41e764bfb65dd62" - } - }, - "targets": [ - { - "Library": { - "crate_name": "prettyplease", - "crate_root": "src/lib.rs", - "srcs": [ - "**/*.rs" - ] - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": [ - "**/*.rs" - ] - } - } - ], - "library_target_name": "prettyplease", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "prettyplease 0.2.12", - "target": "build_script_build" - }, - { - "id": "proc-macro2 1.0.66", - "target": "proc_macro2" - }, - { - "id": "syn 2.0.28", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.2.12" - }, - "build_script_attrs": { - "data_glob": [ - "**" - ], - "links": "prettyplease02" - }, - "license": "MIT OR Apache-2.0" - }, "proc-macro2 1.0.66": { "name": "proc-macro2", "version": "1.0.66", @@ -12989,7 +13012,7 @@ "deps": { "common": [ { - "id": "bitflags 2.3.3", + "id": "bitflags 2.4.0", "target": "bitflags" }, { @@ -14797,6 +14820,12 @@ "compile_data_glob": [ "**" ], + "crate_features": { + "common": [ + "all" + ], + "selects": {} + }, "deps": { "common": [], "selects": { @@ -15889,14 +15918,14 @@ }, "license": "MIT" }, - "tokio-boring 2.1.5": { + "tokio-boring 3.0.4": { "name": "tokio-boring", - "version": "2.1.5", + "version": "3.0.4", "repository": { "Git": { "remote": "https://github.com/Watfaq/boring.git", "commitish": { - "Rev": "a5c2442" + "Rev": "24c006f" }, "strip_prefix": "tokio-boring" } @@ -15920,11 +15949,11 @@ "deps": { "common": [ { - "id": "boring 2.1.0", + "id": "boring 3.0.4", "target": "boring" }, { - "id": "boring-sys 2.1.0", + "id": "boring-sys 3.0.4", "target": "boring_sys" }, { @@ -15934,8 +15963,8 @@ ], "selects": {} }, - "edition": "2018", - "version": "2.1.5" + "edition": "2021", + "version": "3.0.4" }, "license": "MIT/Apache-2.0" }, @@ -16710,7 +16739,7 @@ "deps": { "common": [ { - "id": "bitflags 2.3.3", + "id": "bitflags 2.4.0", "target": "bitflags" }, { @@ -19645,8 +19674,10 @@ "ntdef", "ntsecapi", "processenv", + "processthreadsapi", "profileapi", "std", + "synchapi", "sysinfoapi", "timezoneapi", "winbase", @@ -21732,6 +21763,14 @@ "i686-unknown-freebsd", "x86_64-unknown-freebsd" ], + "cfg(any(target_os = \"ios\", target_os = \"macos\"))": [ + "aarch64-apple-darwin", + "aarch64-apple-ios", + "aarch64-apple-ios-sim", + "i686-apple-darwin", + "x86_64-apple-darwin", + "x86_64-apple-ios" + ], "cfg(any(target_os = \"linux\", target_os = \"android\"))": [ "aarch64-linux-android", "aarch64-unknown-linux-gnu", @@ -21986,15 +22025,6 @@ "cfg(target_os = \"dragonfly\")": [], "cfg(target_os = \"haiku\")": [], "cfg(target_os = \"hermit\")": [], - "cfg(target_os = \"linux\")": [ - "aarch64-unknown-linux-gnu", - "arm-unknown-linux-gnueabi", - "armv7-unknown-linux-gnueabi", - "i686-unknown-linux-gnu", - "powerpc-unknown-linux-gnu", - "s390x-unknown-linux-gnu", - "x86_64-unknown-linux-gnu" - ], "cfg(target_os = \"macos\")": [ "aarch64-apple-darwin", "i686-apple-darwin", diff --git a/Cargo.lock b/Cargo.lock index b65fffc4..6853629f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -398,17 +398,16 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.65.1" +version = "0.66.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" +checksum = "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "cexpr", "clang-sys", "lazy_static", "lazycell", "peeking_take_while", - "prettyplease", "proc-macro2", "quote", "regex", @@ -425,9 +424,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "blake3" @@ -454,23 +453,25 @@ dependencies = [ [[package]] name = "boring" -version = "2.1.0" -source = "git+https://github.com/Watfaq/boring.git?rev=a5c2442#a5c2442e894777f35b196dd99bbacd828aadc92b" +version = "3.0.4" +source = "git+https://github.com/Watfaq/boring.git?rev=24c006f#24c006fd8200bdf4244a58fd3d73bbcd27b7717b" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "boring-sys", "foreign-types", - "lazy_static", "libc", + "once_cell", ] [[package]] name = "boring-sys" -version = "2.1.0" -source = "git+https://github.com/Watfaq/boring.git?rev=a5c2442#a5c2442e894777f35b196dd99bbacd828aadc92b" +version = "3.0.4" +source = "git+https://github.com/Watfaq/boring.git?rev=24c006f#24c006fd8200bdf4244a58fd3d73bbcd27b7717b" dependencies = [ - "bindgen 0.65.1", + "bindgen 0.66.1", "cmake", + "fs_extra", + "fslock", ] [[package]] @@ -1204,6 +1205,12 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "fsevent-sys" version = "4.1.0" @@ -1213,6 +1220,16 @@ dependencies = [ "libc", ] +[[package]] +name = "fslock" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04412b8935272e3a9bae6f48c7bfff74c2911f60525404edfdd28e49884c3bfb" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "futures" version = "0.3.28" @@ -1527,8 +1544,8 @@ dependencies = [ [[package]] name = "hyper-boring" -version = "2.1.2" -source = "git+https://github.com/Watfaq/boring.git?rev=a5c2442#a5c2442e894777f35b196dd99bbacd828aadc92b" +version = "3.0.4" +source = "git+https://github.com/Watfaq/boring.git?rev=24c006f#24c006fd8200bdf4244a58fd3d73bbcd27b7717b" dependencies = [ "antidote", "boring", @@ -2244,16 +2261,6 @@ dependencies = [ "termtree", ] -[[package]] -name = "prettyplease" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64d9ba0963cdcea2e1b2230fbae2bab30eb25a174be395c41e764bfb65dd62" -dependencies = [ - "proc-macro2", - "syn 2.0.28", -] - [[package]] name = "proc-macro2" version = "1.0.66" @@ -2469,7 +2476,7 @@ version = "0.38.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.0", "errno", "libc", "linux-raw-sys", @@ -3018,8 +3025,8 @@ dependencies = [ [[package]] name = "tokio-boring" -version = "2.1.5" -source = "git+https://github.com/Watfaq/boring.git?rev=a5c2442#a5c2442e894777f35b196dd99bbacd828aadc92b" +version = "3.0.4" +source = "git+https://github.com/Watfaq/boring.git?rev=24c006f#24c006fd8200bdf4244a58fd3d73bbcd27b7717b" dependencies = [ "boring", "boring-sys", @@ -3184,7 +3191,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55ae70283aba8d2a8b411c695c437fe25b8b5e44e23e780662002fc72fb47a82" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.0", "bytes", "futures-core", "futures-util", diff --git a/README.md b/README.md index 40afa3f3..f73203d7 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ TODOs - [ ] grpc - [ ] tls - [ ] http -- [ ] providers (untested) +- [x] providers - [x] file - [x] remote - [ ] rules diff --git a/WORKSPACE b/WORKSPACE index b4f78cab..a214b48d 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -22,16 +22,6 @@ rust_register_toolchains( ], ) -load("@rules_rust//bindgen:repositories.bzl", "rust_bindgen_dependencies", "rust_bindgen_register_toolchains") - -rust_bindgen_dependencies() - -rust_bindgen_register_toolchains() - -load("@rules_rust//bindgen:transitive_repositories.bzl", "rust_bindgen_transitive_dependencies") - -rust_bindgen_transitive_dependencies() - load("@rules_rust//crate_universe:repositories.bzl", "crate_universe_dependencies") crate_universe_dependencies() diff --git a/clash/tests/data/config/rules.yaml b/clash/tests/data/config/rules.yaml index f7eaed92..d468a384 100644 --- a/clash/tests/data/config/rules.yaml +++ b/clash/tests/data/config/rules.yaml @@ -9,11 +9,11 @@ authentication: dns: enable: true - listen: - udp: 127.0.0.1:53553 - tcp: 127.0.0.1:53553 - dot: 127.0.0.1:53554 - doh: 127.0.0.1:53555 + # listen: + # udp: 127.0.0.1:53553 + # tcp: 127.0.0.1:53553 + # dot: 127.0.0.1:53554 + # doh: 127.0.0.1:53555 # ipv6: false # when the false, response to AAAA questions will be empty @@ -56,7 +56,6 @@ proxy-groups: - name: "relay" type: relay proxies: - - "ss" - "plain-vmess" - "ws-vmess" - "auto" @@ -67,29 +66,32 @@ proxy-groups: - name: "relay-one" type: relay - proxies: - - "ss" + use: + - "file-provider" - name: "auto" type: url-test + use: + - "file-provider" proxies: - - "ss" - DIRECT url: "http://www.gstatic.com/generate_204" interval: 300 - name: "fallback-auto" type: fallback + use: + - "file-provider" proxies: - - "ss" - DIRECT url: "http://www.gstatic.com/generate_204" interval: 300 - name: "load-balance" type: load-balance + use: + - "file-provider" proxies: - - "ss" - DIRECT strategy: round-robin url: "http://www.gstatic.com/generate_204" @@ -97,26 +99,17 @@ proxy-groups: - name: select type: select - proxies: - - "ss" - - DIRECT + use: + - "file-provider" - name: test 🌏 type: select + use: + - "file-provider" proxies: - - "ss" - DIRECT - - proxies: - - name: "ss" - type: ss - server: 10.0.0.13 - port: 8388 - cipher: aes-256-gcm - password: "password" - udp: true - name: plain-vmess type: vmess server: 10.0.0.13 @@ -154,13 +147,31 @@ proxies: headers: Host: 5607b9d187e655736f563fee87d7283994721.laowanxiang.com +proxy-providers: + file-provider: + type: file + path: ./ss.yaml + health-check: + enable: true + url: http://www.gstatic.com/generate_204 + interval: 300 + remote-provider: + type: http + url: https://xample.com/proxies.yaml + interval: 300 + path: ./proxies.yaml + health-check: + enable: true + url: http://www.gstatic.com/generate_204 + interval: 300 + rules: - DOMAIN,ipinfo.io,relay - GEOIP,CN,relay - DOMAIN-KEYWORD,httpbin,vmess-altid - DOMAIN-SUFFIX,facebook.com,REJECT - - DOMAIN-KEYWORD,google,ss - - DOMAIN,google.com,ss + - DOMAIN-KEYWORD,google,select + - DOMAIN,google.com,select - SRC-IP-CIDR,192.168.1.1/24,DIRECT - GEOIP,CN,DIRECT - DST-PORT,53,plain-vmess diff --git a/clash/tests/data/config/ss-obfs.yaml b/clash/tests/data/config/ss-obfs.yaml deleted file mode 100644 index e69de29b..00000000 diff --git a/clash/tests/data/config/ss.yaml b/clash/tests/data/config/ss.yaml index 7af92b38..cbd52757 100644 --- a/clash/tests/data/config/ss.yaml +++ b/clash/tests/data/config/ss.yaml @@ -45,7 +45,7 @@ experimental: proxies: - name: "ss" type: ss - server: localhost + server: 10.0.0.13 port: 8388 cipher: aes-256-gcm password: "password" diff --git a/clash_lib/Cargo.toml b/clash_lib/Cargo.toml index d8b73b20..e4703817 100644 --- a/clash_lib/Cargo.toml +++ b/clash_lib/Cargo.toml @@ -33,10 +33,11 @@ foreign-types-shared = "0.3.1" network-interface = "1.0.3" base64 = "0.21" uuid = { version = "1.2.1", features = ["v4", "fast-rng", "macro-diagnostics"] } -boring = { git = "https://github.com/Watfaq/boring.git", rev = "a5c2442" } -boring-sys = { git = "https://github.com/Watfaq/boring.git", rev = "a5c2442" } -hyper-boring = { git = "https://github.com/Watfaq/boring.git", rev = "a5c2442" } -tokio-boring = { git = "https://github.com/Watfaq/boring.git", rev = "a5c2442" } +boring = { git = "https://github.com/Watfaq/boring.git", rev = "24c006f" } +boring-sys = { git = "https://github.com/Watfaq/boring.git", rev = "24c006f" } +hyper-boring = { git = "https://github.com/Watfaq/boring.git", rev = "24c006f" } +tokio-boring = { git = "https://github.com/Watfaq/boring.git", rev = "24c006f" } + crc32fast = "1.3.2" brotli = "3.3.4" hmac = "0.12.1" @@ -68,7 +69,7 @@ dhcproto = "0.8" rand = "0.8" -socket2 = "0.5" +socket2 = { version = "0.5", features = ["all"] } tokio-tungstenite = "0.20.0" tracing = "0.1" diff --git a/clash_lib/src/app/api/handlers/provider.rs b/clash_lib/src/app/api/handlers/provider.rs index edee3eb5..bfce2e0f 100644 --- a/clash_lib/src/app/api/handlers/provider.rs +++ b/clash_lib/src/app/api/handlers/provider.rs @@ -57,7 +57,12 @@ async fn get_providers(State(state): State) -> impl IntoResponse let mut providers = HashMap::new(); for (name, p) in outbound_manager.get_proxy_providers() { - let m = p.lock().await.as_map().await; + let p = p.lock().await; + let proxies = p.proxies().await; + let proxies = + futures::future::join_all(proxies.iter().map(|x| outbound_manager.get_proxy(x))); + let mut m = p.as_map().await; + m.insert("proxies".to_owned(), Box::new(proxies.await)); providers.insert(name, m); } diff --git a/clash_lib/src/app/dns/config.rs b/clash_lib/src/app/dns/config.rs index 0cb245e6..09f76a7c 100644 --- a/clash_lib/src/app/dns/config.rs +++ b/clash_lib/src/app/dns/config.rs @@ -1,5 +1,6 @@ use std::{ collections::HashMap, + fmt::Display, io::BufReader, net::{IpAddr, SocketAddr}, sync::Arc, @@ -27,6 +28,17 @@ pub struct NameServer { pub address: String, pub interface: Option, } +impl Display for NameServer { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}://{}#{}", + self.net, + self.address, + self.interface.as_ref().unwrap_or(&"".to_owned()) + ) + } +} #[derive(Clone, Debug, Default)] pub struct FallbackFilter { diff --git a/clash_lib/src/app/dns/dns_client.rs b/clash_lib/src/app/dns/dns_client.rs index 0bdf4c53..fabd45c3 100644 --- a/clash_lib/src/app/dns/dns_client.rs +++ b/clash_lib/src/app/dns/dns_client.rs @@ -1,4 +1,4 @@ -use std::fmt::{Debug, Formatter}; +use std::fmt::{Debug, Display, Formatter}; use std::net::SocketAddr; use std::str::FromStr; use std::{net, sync::Arc, time::Duration}; @@ -37,6 +37,18 @@ pub enum DNSNetMode { DHCP, } +impl Display for DNSNetMode { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Self::UDP => write!(f, "UDP"), + Self::TCP => write!(f, "TCP"), + Self::DoT => write!(f, "DoT"), + Self::DoH => write!(f, "DoH"), + Self::DHCP => write!(f, "DHCP"), + } + } +} + impl FromStr for DNSNetMode { type Err = Error; diff --git a/clash_lib/src/app/dns/helper.rs b/clash_lib/src/app/dns/helper.rs index 49e1be08..9b44a3e6 100644 --- a/clash_lib/src/app/dns/helper.rs +++ b/clash_lib/src/app/dns/helper.rs @@ -33,13 +33,13 @@ pub async fn make_clients( port: port .parse::() .expect(format!("no port for DNS server: {}", s.address).as_str()), - net: s.net, - iface: s.interface.map(|x| Interface::Name(x)), + net: s.net.to_owned(), + iface: s.interface.as_ref().map(|x| Interface::Name(x.to_owned())), }) .await { Ok(c) => rv.push(c), - Err(e) => warn!("initializing DNS client: {}", e), + Err(e) => warn!("initializing DNS client {} with error {}", &s, e), } } diff --git a/clash_lib/src/app/outbound/manager.rs b/clash_lib/src/app/outbound/manager.rs index eed4b14f..0ab30876 100644 --- a/clash_lib/src/app/outbound/manager.rs +++ b/clash_lib/src/app/outbound/manager.rs @@ -221,10 +221,10 @@ impl OutboundManager { .map(|x| { handlers .get(x) - .expect(format!("proxy {} not found", x).as_str()) - .clone() + .ok_or_else(|| Error::InvalidConfig(format!("proxy {} not found", x))) + .map(Clone::clone) }) - .collect::>(); + .collect::, _>>()?; let hc = HealthCheck::new( proxies.clone(), @@ -248,6 +248,19 @@ impl OutboundManager { } match outbound_group { OutboundGroupProtocol::Relay(proto) => { + if proto.proxies.as_ref().map(|x| x.len()).unwrap_or_default() + + proto + .use_provider + .as_ref() + .map(|x| x.len()) + .unwrap_or_default() + == 0 + { + return Err(Error::InvalidConfig(format!( + "proxy group {} has no proxies", + proto.name + ))); + } let mut providers: Vec = vec![]; if let Some(proxies) = &proto.proxies { @@ -284,6 +297,19 @@ impl OutboundManager { handlers.insert(proto.name.clone(), relay); } OutboundGroupProtocol::UrlTest(proto) => { + if proto.proxies.as_ref().map(|x| x.len()).unwrap_or_default() + + proto + .use_provider + .as_ref() + .map(|x| x.len()) + .unwrap_or_default() + == 0 + { + return Err(Error::InvalidConfig(format!( + "proxy group {} has no proxies", + proto.name + ))); + } let mut providers: Vec = vec![]; if let Some(proxies) = &proto.proxies { @@ -322,6 +348,19 @@ impl OutboundManager { handlers.insert(proto.name.clone(), Arc::new(url_test)); } OutboundGroupProtocol::Fallback(proto) => { + if proto.proxies.as_ref().map(|x| x.len()).unwrap_or_default() + + proto + .use_provider + .as_ref() + .map(|x| x.len()) + .unwrap_or_default() + == 0 + { + return Err(Error::InvalidConfig(format!( + "proxy group {} has no proxies", + proto.name + ))); + } let mut providers: Vec = vec![]; if let Some(proxies) = &proto.proxies { @@ -359,6 +398,19 @@ impl OutboundManager { handlers.insert(proto.name.clone(), Arc::new(fallback)); } OutboundGroupProtocol::LoadBalance(proto) => { + if proto.proxies.as_ref().map(|x| x.len()).unwrap_or_default() + + proto + .use_provider + .as_ref() + .map(|x| x.len()) + .unwrap_or_default() + == 0 + { + return Err(Error::InvalidConfig(format!( + "proxy group {} has no proxies", + proto.name + ))); + } let mut providers: Vec = vec![]; if let Some(proxies) = &proto.proxies { @@ -395,6 +447,19 @@ impl OutboundManager { handlers.insert(proto.name.clone(), Arc::new(load_balance)); } OutboundGroupProtocol::Select(proto) => { + if proto.proxies.as_ref().map(|x| x.len()).unwrap_or_default() + + proto + .use_provider + .as_ref() + .map(|x| x.len()) + .unwrap_or_default() + == 0 + { + return Err(Error::InvalidConfig(format!( + "proxy group {} has no proxies", + proto.name + ))); + } let mut providers: Vec = vec![]; if let Some(proxies) = &proto.proxies { @@ -531,6 +596,11 @@ impl OutboundManager { } } } + + for p in provider_registry.values() { + info!("initializing provider {}", p.lock().await.name()); + p.lock().await.initialize().await?; + } Ok(()) } } diff --git a/clash_lib/src/app/outbound/utils.rs b/clash_lib/src/app/outbound/utils.rs index b9721d5d..3cfee036 100644 --- a/clash_lib/src/app/outbound/utils.rs +++ b/clash_lib/src/app/outbound/utils.rs @@ -1,4 +1,7 @@ -use std::{cell::RefCell, collections::HashMap}; +use std::{ + cell::RefCell, + collections::{HashMap, VecDeque}, +}; use crate::{config::internal::proxy::OutboundGroupProtocol, Error}; @@ -63,19 +66,21 @@ pub fn proxy_groups_dag_sort(groups: &mut Vec) -> Result< } let mut index = 0; - let mut queue = vec![]; + let mut queue = VecDeque::new(); for (name, node) in graph.iter() { if node.borrow_mut().in_degree == 0 { - queue.push(name.clone()); + queue.push_back(name.clone()); } } let group_len = groups.len(); while !queue.is_empty() { - let name = queue.first().unwrap().to_owned(); - let node = graph.get(&name).unwrap(); + let name = queue.pop_front().unwrap().to_owned(); + let node = graph + .get(&name) + .expect(format!("node {} not found", &name).as_str()); if node.borrow().proto.is_some() { index += 1; @@ -89,14 +94,12 @@ pub fn proxy_groups_dag_sort(groups: &mut Vec) -> Result< let node = graph.get(proxy.as_str()).unwrap(); node.borrow_mut().in_degree -= 1; if node.borrow().in_degree == 0 { - queue.push(proxy.clone()); + queue.push_back(proxy.clone()); } } } graph.remove(&name); - - queue.remove(0); } if graph.len() == 0 { diff --git a/clash_lib/src/app/proxy_manager/healthcheck.rs b/clash_lib/src/app/proxy_manager/healthcheck.rs index f459f818..a08134c0 100644 --- a/clash_lib/src/app/proxy_manager/healthcheck.rs +++ b/clash_lib/src/app/proxy_manager/healthcheck.rs @@ -9,16 +9,15 @@ use super::ThreadSafeProxyManager; struct HealCheckInner { last_check: Instant, + proxies: Vec, + task_handle: Option>>, } -#[derive(Clone)] pub struct HealthCheck { - proxies: Vec, url: String, interval: u64, lazy: bool, proxy_manager: ThreadSafeProxyManager, - task_handle: Option>>, inner: Arc>, } @@ -31,24 +30,24 @@ impl HealthCheck { proxy_manager: ThreadSafeProxyManager, ) -> anyhow::Result { let health_check = Self { - proxies, url, interval, lazy, proxy_manager, - task_handle: None, inner: Arc::new(tokio::sync::Mutex::new(HealCheckInner { last_check: tokio::time::Instant::now(), + proxies, + task_handle: None, })), }; Ok(health_check) } - pub fn kick_off(&mut self) { + pub async fn kick_off(&self) { let proxy_manager = self.proxy_manager.clone(); let interval = self.interval; let lazy = self.lazy; - let proxies = self.proxies.clone(); + let proxies = self.inner.lock().await.proxies.clone(); let url = self.url.clone(); let handle = tokio::spawn(async move { @@ -56,7 +55,7 @@ impl HealthCheck { }); let inner = self.inner.clone(); - let proxies = self.proxies.clone(); + let proxies = self.inner.lock().await.proxies.clone(); let proxy_manager = self.proxy_manager.clone(); let url = self.url.clone(); let task_handle = tokio::spawn(async move { @@ -75,23 +74,23 @@ impl HealthCheck { } }); - self.task_handle = Some(Arc::new(tokio::spawn(async move { + self.inner.lock().await.task_handle = Some(Arc::new(tokio::spawn(async move { futures::future::join_all(vec![task_handle, handle]).await; }))); } - pub async fn touch(&mut self) { + pub async fn touch(&self) { self.inner.lock().await.last_check = tokio::time::Instant::now(); } - pub async fn check(&mut self) { + pub async fn check(&self) { self.proxy_manager - .check(&self.proxies, &self.url, None) + .check(&self.inner.lock().await.proxies, &self.url, None) .await; } - pub fn update(&mut self, proxies: Vec) { - self.proxies = proxies; + pub async fn update(&self, proxies: Vec) { + self.inner.lock().await.proxies = proxies; } pub fn auto(&self) -> bool { diff --git a/clash_lib/src/app/proxy_manager/providers/fether.rs b/clash_lib/src/app/proxy_manager/providers/fether.rs index db0639d1..af5e4f3f 100644 --- a/clash_lib/src/app/proxy_manager/providers/fether.rs +++ b/clash_lib/src/app/proxy_manager/providers/fether.rs @@ -218,11 +218,11 @@ where }; if same { - tracing::info!("{} no update", &name); + tracing::info!("provider {} no update", &name); return; } - tracing::info!("{} updated", &name); + tracing::info!("provider {} updated", &name); let on_update = on_update.lock().await.take(); if let Some(on_update) = on_update { diff --git a/clash_lib/src/app/proxy_manager/providers/mod.rs b/clash_lib/src/app/proxy_manager/providers/mod.rs index f465bbae..84461907 100644 --- a/clash_lib/src/app/proxy_manager/providers/mod.rs +++ b/clash_lib/src/app/proxy_manager/providers/mod.rs @@ -16,6 +16,8 @@ pub mod rule_provider; #[cfg(test)] use mockall::automock; +use crate::app::outbound::manager::ThreadSafeOutboundManager; + #[derive(PartialEq, Clone, Copy, Debug)] pub enum ProviderVehicleType { File, diff --git a/clash_lib/src/app/proxy_manager/providers/plain_provider.rs b/clash_lib/src/app/proxy_manager/providers/plain_provider.rs index 87914756..41159434 100644 --- a/clash_lib/src/app/proxy_manager/providers/plain_provider.rs +++ b/clash_lib/src/app/proxy_manager/providers/plain_provider.rs @@ -60,8 +60,6 @@ impl Provider for PlainProvider { Ok(()) } - /// the proxy only contains basic information - /// to populate history/liveness information, use the proxy_manager async fn as_map(&self) -> HashMap> { let mut m: HashMap> = HashMap::new(); @@ -72,10 +70,6 @@ impl Provider for PlainProvider { Box::new(self.vehicle_type().to_string()), ); - let proxies = - futures::future::join_all(self.proxies().await.iter().map(|p| p.as_map())).await; - m.insert("proxies".to_owned(), Box::new(proxies)); - m } } diff --git a/clash_lib/src/app/proxy_manager/providers/proxy_set_provider.rs b/clash_lib/src/app/proxy_manager/providers/proxy_set_provider.rs index aa2cd936..c8a770dd 100644 --- a/clash_lib/src/app/proxy_manager/providers/proxy_set_provider.rs +++ b/clash_lib/src/app/proxy_manager/providers/proxy_set_provider.rs @@ -27,7 +27,7 @@ struct ProviderScheme { struct Inner { proxies: Vec, - hc: HealthCheck, + hc: Arc, } pub struct ProxySetProvider { @@ -43,11 +43,16 @@ impl ProxySetProvider { name: String, interval: Duration, vehicle: ThreadSafeProviderVehicle, - mut hc: HealthCheck, + hc: HealthCheck, ) -> anyhow::Result { + let hc = Arc::new(hc); + if hc.auto() { - debug!("kicking off healthcheck: {}", name); - hc.kick_off(); + let hc = hc.clone(); + debug!("kicking off healthcheck for: {}", name); + tokio::spawn(async move { + hc.kick_off().await; + }); } let inner = Arc::new(tokio::sync::Mutex::new(Inner { @@ -59,12 +64,12 @@ impl ProxySetProvider { let updater: Box) + Send + Sync + 'static> = Box::new(move |input: Vec| -> () { - let mut hc = hc.clone(); - hc.update(input.clone()); + let hc = hc.clone(); let inner = inner_clone.clone(); tokio::spawn(async move { let mut inner = inner.lock().await; - inner.proxies = input; + inner.proxies = input.clone(); + hc.update(input).await; }); }); @@ -83,8 +88,8 @@ impl ProxySetProvider { OutboundProxyProtocol::Direct => Ok(direct::Handler::new()), OutboundProxyProtocol::Reject => Ok(reject::Handler::new()), OutboundProxyProtocol::Ss(s) => s.try_into(), - OutboundProxyProtocol::Socks5(_) => todo!(), - OutboundProxyProtocol::Trojan(_) => todo!(), + OutboundProxyProtocol::Socks5(_) => todo!("socks5 not supported yet"), + OutboundProxyProtocol::Trojan(_) => todo!("trojan not supported yet"), OutboundProxyProtocol::Vmess(vm) => vm.try_into(), }) .collect::, _>>(); @@ -142,18 +147,6 @@ impl Provider for ProxySetProvider { Box::new(self.vehicle_type().to_string()), ); - let proxies = futures::future::join_all( - self.inner - .lock() - .await - .proxies - .clone() - .iter() - .map(|p| p.as_map()), - ) - .await; - m.insert("proxies".to_owned(), Box::new(proxies)); - m.insert( "updatedAt".to_owned(), Box::new(self.fetcher.updated_at().await), diff --git a/clash_lib/src/config/internal/config.rs b/clash_lib/src/config/internal/config.rs index 1497a5bd..362671cb 100644 --- a/clash_lib/src/config/internal/config.rs +++ b/clash_lib/src/config/internal/config.rs @@ -35,12 +35,27 @@ pub struct Config { pub proxy_providers: HashMap, } +impl Config { + fn validate(self) -> Result { + for r in self.rules.iter() { + if !self.proxies.contains_key(r.target()) && !self.proxy_groups.contains_key(r.target()) + { + return Err(Error::InvalidConfig(format!( + "proxy `{}` referenced in a rule was not found", + r.target() + ))); + } + } + Ok(self) + } +} + impl TryFrom for Config { type Error = crate::Error; fn try_from(c: def::Config) -> Result { let mut proxy_names = vec![String::from(PROXY_DIRECT), String::from(PROXY_REJECT)]; - Ok(Self { + Self { general: General { inbound: Inbound { port: c.port, @@ -164,7 +179,8 @@ impl TryFrom for Config { .expect("proxy provider parse error") }) .unwrap_or_default(), - }) + } + .validate() } } diff --git a/clash_lib/src/config/internal/proxy.rs b/clash_lib/src/config/internal/proxy.rs index 663ea611..a46b021a 100644 --- a/clash_lib/src/config/internal/proxy.rs +++ b/clash_lib/src/config/internal/proxy.rs @@ -292,12 +292,14 @@ pub struct OutboundGroupSelect { #[derive(serde::Serialize, serde::Deserialize, Debug)] #[serde(tag = "type")] +#[serde(rename_all = "kebab-case")] pub enum OutboundProxyProvider { Http(OutboundHttpProvider), File(OutboundFileProvider), } #[derive(serde::Serialize, serde::Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] pub struct OutboundHttpProvider { #[serde(skip)] pub name: String, @@ -308,6 +310,7 @@ pub struct OutboundHttpProvider { } #[derive(serde::Serialize, serde::Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] pub struct OutboundFileProvider { #[serde(skip)] pub name: String, diff --git a/clash_lib/src/config/internal/rule.rs b/clash_lib/src/config/internal/rule.rs index ba7b5676..deaee9c6 100644 --- a/clash_lib/src/config/internal/rule.rs +++ b/clash_lib/src/config/internal/rule.rs @@ -48,6 +48,43 @@ pub enum RuleType { }, } +impl RuleType { + pub fn target(&self) -> &str { + match self { + RuleType::Domain { domain, target } => target, + RuleType::DomainSuffix { + domain_suffix, + target, + } => target, + RuleType::DomainKeyword { + domain_keyword, + target, + } => target, + RuleType::GeoIP { + target, + country_code, + no_resolve, + } => target, + RuleType::IPCIDR { + ipnet, + target, + no_resolve, + } => target, + RuleType::SRCIPCIDR { + ipnet, + target, + no_resolve, + } => target, + RuleType::SRCPort { target, port } => target, + RuleType::DSTPort { target, port } => target, + RuleType::ProcessName => todo!(), + RuleType::ProcessPath => todo!(), + RuleType::RuleSet { rule_set, target } => target, + RuleType::Match { target } => target, + } + } +} + impl Display for RuleType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { diff --git a/clash_lib/src/proxy/tun/datagram.rs b/clash_lib/src/proxy/tun/datagram.rs index adb71a89..32a26f01 100644 --- a/clash_lib/src/proxy/tun/datagram.rs +++ b/clash_lib/src/proxy/tun/datagram.rs @@ -16,6 +16,7 @@ pub struct TunDatagram { flushed: bool, } +// TODO: make this work impl TunDatagram { pub fn new( tx: tokio::sync::mpsc::Sender, @@ -85,10 +86,6 @@ impl Sink for TunDatagram { let pkt_container = pkt; if let Some(pkt) = pkt_container.take() { - let data = pkt.data; - let addr: shadowsocks::relay::Address = - (pkt.dst_addr.host(), pkt.dst_addr.port()).into(); - match tx.blocking_send(pkt) { Ok(_) => Poll::Ready(Ok(())), Err(err) => Poll::Ready(Err(new_io_error(err.to_string().as_str()))), @@ -103,7 +100,6 @@ impl Sink for TunDatagram { cx: &mut std::task::Context<'_>, ) -> Poll> { ready!(self.poll_flush(cx))?; - self.rx.close(); Poll::Ready(Ok(())) } } diff --git a/clash_lib/src/proxy/tun/inbound.rs b/clash_lib/src/proxy/tun/inbound.rs index 5d994fc8..19dd98c9 100644 --- a/clash_lib/src/proxy/tun/inbound.rs +++ b/clash_lib/src/proxy/tun/inbound.rs @@ -81,28 +81,8 @@ async fn handle_inbound_datagram( }); tokio::spawn(async move { + // TODO: handle DNS while let Ok((data, src_addr, dst_addr)) = lr.recv_from().await { - if dst_addr.port() == 53 { - match resolver.generate_fake_ip_packet(data).await { - Ok(resp) => { - if let Err(e) = l_tx - .send(UdpPacket::new( - data, - SocksAddr::any_ipv4(), - SocksAddr::any_ipv4(), - )) - .await - { - warn!("failed to send udp packet to proxy: {}", e); - } - continue; - } - Err(e) => { - warn!("failed to generate fake ip packet: {}", e); - } - } - } - let pkt = UdpPacket { data, src_addr: src_addr.into(), @@ -118,7 +98,7 @@ async fn handle_inbound_datagram( } }); - let mut sess = Session { + let sess = Session { network: Network::Udp, ..Default::default() }; @@ -203,14 +183,16 @@ pub fn get_runner( } })); + let dsp = dispatcher.clone(); + let rsv = resolver.clone(); futs.push(Box::pin(async move { while let Some((stream, local_addr, remote_addr)) = tcp_listener.next().await { tokio::spawn(handl_inbound_stream( stream, local_addr, remote_addr, - dispatcher.clone(), - resolver.clone(), + dsp.clone(), + rsv.clone(), )); } }));