diff --git a/Cargo.Bazel.lock b/Cargo.Bazel.lock index a8ca59ac..e14b446a 100644 --- a/Cargo.Bazel.lock +++ b/Cargo.Bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "8890f546dd54ed95ce8ac5363cc3bab5f58848c5f866b7e2a71e0f3b7c5c080d", + "checksum": "0af5c01f188447da06ff420d36d10dbc2070bb9b583c4e469662e1f2c2c769c7", "crates": { "addr2line 0.20.0": { "name": "addr2line", @@ -601,6 +601,47 @@ }, "license": "MIT/Apache-2.0" }, + "ansi_term 0.12.1": { + "name": "ansi_term", + "version": "0.12.1", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/ansi_term/0.12.1/download", + "sha256": "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" + } + }, + "targets": [ + { + "Library": { + "crate_name": "ansi_term", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "ansi_term", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [], + "selects": { + "cfg(target_os = \"windows\")": [ + { + "id": "winapi 0.3.9", + "target": "winapi" + } + ] + } + }, + "edition": "2015", + "version": "0.12.1" + }, + "license": "MIT" + }, "anstream 0.3.2": { "name": "anstream", "version": "0.3.2", @@ -1236,6 +1277,59 @@ }, "license": "MIT OR Apache-2.0" }, + "atty 0.2.14": { + "name": "atty", + "version": "0.2.14", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/atty/0.2.14/download", + "sha256": "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" + } + }, + "targets": [ + { + "Library": { + "crate_name": "atty", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "atty", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [], + "selects": { + "cfg(target_os = \"hermit\")": [ + { + "id": "hermit-abi 0.1.19", + "target": "hermit_abi" + } + ], + "cfg(unix)": [ + { + "id": "libc 0.2.147", + "target": "libc" + } + ], + "cfg(windows)": [ + { + "id": "winapi 0.3.9", + "target": "winapi" + } + ] + } + }, + "edition": "2015", + "version": "0.2.14" + }, + "license": "MIT" + }, "autocfg 1.1.0": { "name": "autocfg", "version": "1.1.0", @@ -1798,6 +1892,141 @@ }, "license": "MIT OR Apache-2.0" }, + "bindgen 0.59.2": { + "name": "bindgen", + "version": "0.59.2", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/bindgen/0.59.2/download", + "sha256": "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8" + } + }, + "targets": [ + { + "Library": { + "crate_name": "bindgen", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "bindgen", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "clap", + "default", + "env_logger", + "log", + "logging", + "runtime", + "which", + "which-rustfmt" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "bindgen 0.59.2", + "target": "build_script_build" + }, + { + "id": "bitflags 1.3.2", + "target": "bitflags" + }, + { + "id": "cexpr 0.6.0", + "target": "cexpr" + }, + { + "id": "clang-sys 1.6.1", + "target": "clang_sys" + }, + { + "id": "clap 2.34.0", + "target": "clap" + }, + { + "id": "env_logger 0.9.3", + "target": "env_logger" + }, + { + "id": "lazy_static 1.4.0", + "target": "lazy_static" + }, + { + "id": "lazycell 1.3.0", + "target": "lazycell" + }, + { + "id": "log 0.4.19", + "target": "log" + }, + { + "id": "peeking_take_while 0.1.2", + "target": "peeking_take_while" + }, + { + "id": "proc-macro2 1.0.66", + "target": "proc_macro2" + }, + { + "id": "quote 1.0.32", + "target": "quote" + }, + { + "id": "regex 1.9.1", + "target": "regex" + }, + { + "id": "rustc-hash 1.1.0", + "target": "rustc_hash" + }, + { + "id": "shlex 1.1.0", + "target": "shlex" + }, + { + "id": "which 4.4.0", + "target": "which" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.59.2" + }, + "build_script_attrs": { + "data_glob": [ + "**" + ], + "link_deps": { + "common": [ + { + "id": "clang-sys 1.6.1", + "target": "clang_sys" + } + ], + "selects": {} + } + }, + "license": "BSD-3-Clause" + }, "bindgen 0.65.1": { "name": "bindgen", "version": "0.65.1", @@ -3138,6 +3367,84 @@ }, "license": "Apache-2.0" }, + "clap 2.34.0": { + "name": "clap", + "version": "2.34.0", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/clap/2.34.0/download", + "sha256": "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" + } + }, + "targets": [ + { + "Library": { + "crate_name": "clap", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "clap", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "ansi_term", + "atty", + "color", + "default", + "strsim", + "suggestions", + "vec_map" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "atty 0.2.14", + "target": "atty" + }, + { + "id": "bitflags 1.3.2", + "target": "bitflags" + }, + { + "id": "strsim 0.8.0", + "target": "strsim" + }, + { + "id": "textwrap 0.11.0", + "target": "textwrap" + }, + { + "id": "unicode-width 0.1.10", + "target": "unicode_width" + }, + { + "id": "vec_map 0.8.2", + "target": "vec_map" + } + ], + "selects": { + "cfg(not(windows))": [ + { + "id": "ansi_term 0.12.1", + "target": "ansi_term" + } + ] + } + }, + "edition": "2018", + "version": "2.34.0" + }, + "license": "MIT" + }, "clap 4.3.19": { "name": "clap", "version": "4.3.19", @@ -3376,6 +3683,31 @@ }, "license": null }, + "clash_doc 0.1.0": { + "name": "clash_doc", + "version": "0.1.0", + "repository": null, + "targets": [ + { + "Library": { + "crate_name": "clash_doc", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "clash_doc", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2021", + "version": "0.1.0" + }, + "license": null + }, "clash_lib 0.1.0": { "name": "clash_lib", "version": "0.1.0", @@ -3521,6 +3853,10 @@ "id": "murmur3 0.5.2", "target": "murmur3" }, + { + "id": "netstack-lwip 0.3.4", + "target": "netstack_lwip" + }, { "id": "network-interface 1.0.1", "target": "network_interface" @@ -4915,6 +5251,7 @@ ], "crate_features": { "common": [ + "default", "use_std" ], "selects": {} @@ -5135,14 +5472,65 @@ "version": "0.6.0", "repository": { "Http": { - "url": "https://crates.io/api/v1/crates/enum-as-inner/0.6.0/download", - "sha256": "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" + "url": "https://crates.io/api/v1/crates/enum-as-inner/0.6.0/download", + "sha256": "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" + } + }, + "targets": [ + { + "ProcMacro": { + "crate_name": "enum_as_inner", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "enum_as_inner", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "heck 0.4.1", + "target": "heck" + }, + { + "id": "proc-macro2 1.0.66", + "target": "proc_macro2" + }, + { + "id": "quote 1.0.32", + "target": "quote" + }, + { + "id": "syn 2.0.28", + "target": "syn" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.6.0" + }, + "license": "MIT/Apache-2.0" + }, + "env_logger 0.9.3": { + "name": "env_logger", + "version": "0.9.3", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/env_logger/0.9.3/download", + "sha256": "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" } }, "targets": [ { - "ProcMacro": { - "crate_name": "enum_as_inner", + "Library": { + "crate_name": "env_logger", "crate_root": "src/lib.rs", "srcs": [ "**/*.rs" @@ -5150,36 +5538,50 @@ } } ], - "library_target_name": "enum_as_inner", + "library_target_name": "env_logger", "common_attrs": { "compile_data_glob": [ "**" ], + "crate_features": { + "common": [ + "atty", + "default", + "humantime", + "regex", + "termcolor" + ], + "selects": {} + }, "deps": { "common": [ { - "id": "heck 0.4.1", - "target": "heck" + "id": "atty 0.2.14", + "target": "atty" }, { - "id": "proc-macro2 1.0.66", - "target": "proc_macro2" + "id": "humantime 2.1.0", + "target": "humantime" }, { - "id": "quote 1.0.32", - "target": "quote" + "id": "log 0.4.19", + "target": "log" }, { - "id": "syn 2.0.28", - "target": "syn" + "id": "regex 1.9.1", + "target": "regex" + }, + { + "id": "termcolor 1.2.0", + "target": "termcolor" } ], "selects": {} }, "edition": "2018", - "version": "0.6.0" + "version": "0.9.3" }, - "license": "MIT/Apache-2.0" + "license": "MIT OR Apache-2.0" }, "equivalent 1.0.1": { "name": "equivalent", @@ -6953,6 +7355,45 @@ }, "license": "MIT OR Apache-2.0" }, + "hermit-abi 0.1.19": { + "name": "hermit-abi", + "version": "0.1.19", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/hermit-abi/0.1.19/download", + "sha256": "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" + } + }, + "targets": [ + { + "Library": { + "crate_name": "hermit_abi", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "hermit_abi", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "libc 0.2.147", + "target": "libc" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.1.19" + }, + "license": "MIT/Apache-2.0" + }, "hermit-abi 0.3.2": { "name": "hermit-abi", "version": "0.3.2", @@ -7371,6 +7812,36 @@ }, "license": "MIT/Apache-2.0" }, + "humantime 2.1.0": { + "name": "humantime", + "version": "2.1.0", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/humantime/2.1.0/download", + "sha256": "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + } + }, + "targets": [ + { + "Library": { + "crate_name": "humantime", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "humantime", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2018", + "version": "2.1.0" + }, + "license": "MIT/Apache-2.0" + }, "hyper 0.14.27": { "name": "hyper", "version": "0.14.27", @@ -9714,6 +10185,98 @@ }, "license": "MIT/Apache-2.0" }, + "netstack-lwip 0.3.4": { + "name": "netstack-lwip", + "version": "0.3.4", + "repository": { + "Git": { + "remote": "https://github.com/Watfaq/netstack-lwip.git", + "commitish": { + "Rev": "4fef23" + } + } + }, + "targets": [ + { + "Library": { + "crate_name": "netstack_lwip", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "netstack_lwip", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "anyhow 1.0.72", + "target": "anyhow" + }, + { + "id": "bytes 1.4.0", + "target": "bytes" + }, + { + "id": "futures 0.3.28", + "target": "futures" + }, + { + "id": "log 0.4.19", + "target": "log" + }, + { + "id": "netstack-lwip 0.3.4", + "target": "build_script_build" + }, + { + "id": "thiserror 1.0.44", + "target": "thiserror" + }, + { + "id": "tokio 1.29.1", + "target": "tokio" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.3.4" + }, + "build_script_attrs": { + "data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "bindgen 0.59.2", + "target": "bindgen" + }, + { + "id": "cc 1.0.79", + "target": "cc" + } + ], + "selects": {} + } + }, + "license": null + }, "network-interface 1.0.1": { "name": "network-interface", "version": "1.0.1", @@ -14412,6 +14975,36 @@ }, "license": "MIT" }, + "strsim 0.8.0": { + "name": "strsim", + "version": "0.8.0", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/strsim/0.8.0/download", + "sha256": "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + } + }, + "targets": [ + { + "Library": { + "crate_name": "strsim", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "strsim", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2015", + "version": "0.8.0" + }, + "license": "MIT" + }, "subtle 2.5.0": { "name": "subtle", "version": "2.5.0", @@ -14640,41 +15233,82 @@ "**" ], "deps": { - "common": [ - { - "id": "cfg-if 1.0.0", - "target": "cfg_if" - }, - { - "id": "fastrand 2.0.0", - "target": "fastrand" - } - ], + "common": [ + { + "id": "cfg-if 1.0.0", + "target": "cfg_if" + }, + { + "id": "fastrand 2.0.0", + "target": "fastrand" + } + ], + "selects": { + "cfg(any(unix, target_os = \"wasi\"))": [ + { + "id": "rustix 0.38.4", + "target": "rustix" + } + ], + "cfg(target_os = \"redox\")": [ + { + "id": "redox_syscall 0.3.5", + "target": "syscall" + } + ], + "cfg(windows)": [ + { + "id": "windows-sys 0.48.0", + "target": "windows_sys" + } + ] + } + }, + "edition": "2018", + "version": "3.7.0" + }, + "license": "MIT OR Apache-2.0" + }, + "termcolor 1.2.0": { + "name": "termcolor", + "version": "1.2.0", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/termcolor/1.2.0/download", + "sha256": "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" + } + }, + "targets": [ + { + "Library": { + "crate_name": "termcolor", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "termcolor", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [], "selects": { - "cfg(any(unix, target_os = \"wasi\"))": [ - { - "id": "rustix 0.38.4", - "target": "rustix" - } - ], - "cfg(target_os = \"redox\")": [ - { - "id": "redox_syscall 0.3.5", - "target": "syscall" - } - ], "cfg(windows)": [ { - "id": "windows-sys 0.48.0", - "target": "windows_sys" + "id": "winapi-util 0.1.5", + "target": "winapi_util" } ] } }, "edition": "2018", - "version": "3.7.0" + "version": "1.2.0" }, - "license": "MIT OR Apache-2.0" + "license": "Unlicense OR MIT" }, "termtree 0.4.1": { "name": "termtree", @@ -14706,6 +15340,45 @@ }, "license": "MIT" }, + "textwrap 0.11.0": { + "name": "textwrap", + "version": "0.11.0", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/textwrap/0.11.0/download", + "sha256": "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" + } + }, + "targets": [ + { + "Library": { + "crate_name": "textwrap", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "textwrap", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "unicode-width 0.1.10", + "target": "unicode_width" + } + ], + "selects": {} + }, + "edition": "2015", + "version": "0.11.0" + }, + "license": "MIT" + }, "thiserror 1.0.44": { "name": "thiserror", "version": "1.0.44", @@ -15608,6 +16281,72 @@ }, "license": "MIT" }, + "tokio-util 0.6.10": { + "name": "tokio-util", + "version": "0.6.10", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/tokio-util/0.6.10/download", + "sha256": "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" + } + }, + "targets": [ + { + "Library": { + "crate_name": "tokio_util", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "tokio_util", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "codec", + "default" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "bytes 1.4.0", + "target": "bytes" + }, + { + "id": "futures-core 0.3.28", + "target": "futures_core" + }, + { + "id": "futures-sink 0.3.28", + "target": "futures_sink" + }, + { + "id": "log 0.4.19", + "target": "log" + }, + { + "id": "pin-project-lite 0.2.10", + "target": "pin_project_lite" + }, + { + "id": "tokio 1.29.1", + "target": "tokio" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.6.10" + }, + "license": "MIT" + }, "tokio-util 0.7.8": { "name": "tokio-util", "version": "0.7.8", @@ -17312,6 +18051,17 @@ "compile_data_glob": [ "**" ], + "crate_features": { + "common": [ + "async", + "byteorder", + "bytes", + "futures-core", + "tokio", + "tokio-util" + ], + "selects": {} + }, "deps": { "common": [ { @@ -17330,6 +18080,28 @@ "target": "ioctl_sys", "alias": "ioctl" } + ], + "cfg(any(target_os = \"linux\", target_os = \"macos\", target_os = \"ios\", target_os = \"android\"))": [ + { + "id": "byteorder 1.4.3", + "target": "byteorder" + }, + { + "id": "bytes 1.4.0", + "target": "bytes" + }, + { + "id": "futures-core 0.3.28", + "target": "futures_core" + }, + { + "id": "tokio 1.29.1", + "target": "tokio" + }, + { + "id": "tokio-util 0.6.10", + "target": "tokio_util" + } ] } }, @@ -17657,6 +18429,42 @@ }, "license": "MIT/Apache-2.0" }, + "unicode-width 0.1.10": { + "name": "unicode-width", + "version": "0.1.10", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/unicode-width/0.1.10/download", + "sha256": "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + } + }, + "targets": [ + { + "Library": { + "crate_name": "unicode_width", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "unicode_width", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default" + ], + "selects": {} + }, + "edition": "2015", + "version": "0.1.10" + }, + "license": "MIT/Apache-2.0" + }, "universal-hash 0.4.0": { "name": "universal-hash", "version": "0.4.0", @@ -18093,6 +18901,36 @@ }, "license": "MIT" }, + "vec_map 0.8.2": { + "name": "vec_map", + "version": "0.8.2", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/vec_map/0.8.2/download", + "sha256": "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + } + }, + "targets": [ + { + "Library": { + "crate_name": "vec_map", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "vec_map", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2015", + "version": "0.8.2" + }, + "license": "MIT/Apache-2.0" + }, "version_check 0.9.4": { "name": "version_check", "version": "0.9.4", @@ -18670,6 +19508,56 @@ }, "license": "MPL-2.0" }, + "which 4.4.0": { + "name": "which", + "version": "4.4.0", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/which/4.4.0/download", + "sha256": "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" + } + }, + "targets": [ + { + "Library": { + "crate_name": "which", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "which", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "either 1.9.0", + "target": "either" + }, + { + "id": "libc 0.2.147", + "target": "libc" + } + ], + "selects": { + "cfg(windows)": [ + { + "id": "once_cell 1.18.0", + "target": "once_cell" + } + ] + } + }, + "edition": "2018", + "version": "4.4.0" + }, + "license": "MIT" + }, "widestring 1.0.2": { "name": "widestring", "version": "1.0.2", @@ -20645,6 +21533,7 @@ "binary_crates": [], "workspace_members": { "clash 0.1.0": "clash", + "clash_doc 0.1.0": "clash_doc", "clash_lib 0.1.0": "clash_lib" }, "conditions": { @@ -20868,6 +21757,25 @@ "x86_64-apple-darwin", "x86_64-unknown-linux-gnu" ], + "cfg(any(target_os = \"linux\", target_os = \"macos\", target_os = \"ios\", target_os = \"android\"))": [ + "aarch64-apple-darwin", + "aarch64-apple-ios", + "aarch64-apple-ios-sim", + "aarch64-linux-android", + "aarch64-unknown-linux-gnu", + "arm-unknown-linux-gnueabi", + "armv7-linux-androideabi", + "armv7-unknown-linux-gnueabi", + "i686-apple-darwin", + "i686-linux-android", + "i686-unknown-linux-gnu", + "powerpc-unknown-linux-gnu", + "s390x-unknown-linux-gnu", + "x86_64-apple-darwin", + "x86_64-apple-ios", + "x86_64-linux-android", + "x86_64-unknown-linux-gnu" + ], "cfg(any(target_os = \"macos\", target_os = \"ios\"))": [ "aarch64-apple-darwin", "aarch64-apple-ios", diff --git a/Cargo.lock b/Cargo.lock index d15717b5..c3bbcd8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -127,6 +127,15 @@ dependencies = [ "libc", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + [[package]] name = "anstream" version = "0.3.2" @@ -250,6 +259,17 @@ dependencies = [ "syn 2.0.28", ] +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -353,6 +373,29 @@ version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +[[package]] +name = "bindgen" +version = "0.59.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "clap 2.34.0", + "env_logger", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "which", +] + [[package]] name = "bindgen" version = "0.65.1" @@ -426,7 +469,7 @@ name = "boring-sys" version = "2.1.0" source = "git+https://github.com/Watfaq/boring.git?rev=a5c2442#a5c2442e894777f35b196dd99bbacd828aadc92b" dependencies = [ - "bindgen", + "bindgen 0.65.1", "cmake", ] @@ -592,6 +635,21 @@ dependencies = [ "libloading", ] +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags 1.3.2", + "strsim 0.8.0", + "textwrap", + "unicode-width", + "vec_map", +] + [[package]] name = "clap" version = "4.3.19" @@ -612,7 +670,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.10.0", ] [[package]] @@ -637,7 +695,7 @@ checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" name = "clash" version = "0.1.0" dependencies = [ - "clap", + "clap 4.3.19", "clash_lib", ] @@ -686,6 +744,7 @@ dependencies = [ "md-5", "mockall", "murmur3", + "netstack-lwip", "network-interface", "prost", "public-suffix", @@ -707,7 +766,7 @@ dependencies = [ "tokio-rustls", "tokio-test", "tokio-tungstenite", - "tokio-util", + "tokio-util 0.7.8", "tower", "tower-http", "tracing", @@ -1021,6 +1080,19 @@ dependencies = [ "syn 2.0.28", ] +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -1311,7 +1383,7 @@ dependencies = [ "indexmap 1.9.3", "slab", "tokio", - "tokio-util", + "tokio-util 0.7.8", "tracing", ] @@ -1333,6 +1405,15 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "hermit-abi" version = "0.3.2" @@ -1414,6 +1495,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "hyper" version = "0.14.27" @@ -1586,7 +1673,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.2", "rustix", "windows-sys 0.48.0", ] @@ -1860,6 +1947,21 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9252111cf132ba0929b6f8e030cac2a24b507f3a4d6db6fb2896f27b354c714b" +[[package]] +name = "netstack-lwip" +version = "0.3.4" +source = "git+https://github.com/Watfaq/netstack-lwip.git?rev=4fef23#4fef237a9c8f4a94afaa05a3d0e9c57bd0ae8754" +dependencies = [ + "anyhow", + "bindgen 0.59.2", + "bytes", + "cc", + "futures", + "log", + "thiserror", + "tokio", +] + [[package]] name = "network-interface" version = "1.0.3" @@ -1940,7 +2042,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.2", "libc", ] @@ -2738,6 +2840,12 @@ dependencies = [ "loom", ] +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + [[package]] name = "strsim" version = "0.10.0" @@ -2791,12 +2899,30 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + [[package]] name = "termtree" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.44" @@ -2974,6 +3100,20 @@ dependencies = [ "tungstenite", ] +[[package]] +name = "tokio-util" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "log", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.8" @@ -3057,7 +3197,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "tokio", - "tokio-util", + "tokio-util 0.7.8", "tower-layer", "tower-service", "tracing", @@ -3325,9 +3465,14 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbc25e23adc6cac7dd895ce2780f255902290fc39b00e1ae3c33e89f3d20fa66" dependencies = [ + "byteorder", + "bytes", + "futures-core", "ioctl-sys", "libc", "thiserror", + "tokio", + "tokio-util 0.6.10", ] [[package]] @@ -3385,6 +3530,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + [[package]] name = "universal-hash" version = "0.4.0" @@ -3469,6 +3620,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version_check" version = "0.9.4" @@ -3576,6 +3733,17 @@ version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +[[package]] +name = "which" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +dependencies = [ + "either", + "libc", + "once_cell", +] + [[package]] name = "widestring" version = "1.0.2" diff --git a/WORKSPACE b/WORKSPACE index ffab4f79..b4f78cab 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -69,6 +69,7 @@ crates_repository( "//:Cargo.toml", "//clash:Cargo.toml", "//clash_lib:Cargo.toml", + "//clash_doc:Cargo.toml", ], ) diff --git a/clash_doc/BUILD.bazel b/clash_doc/BUILD.bazel new file mode 100644 index 00000000..e69de29b diff --git a/clash_doc/Cargo.toml b/clash_doc/Cargo.toml new file mode 100644 index 00000000..7112bf45 --- /dev/null +++ b/clash_doc/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "clash_doc" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +clash_lib = { path = "../clash_lib" } \ No newline at end of file diff --git a/clash_doc/src/lib.rs b/clash_doc/src/lib.rs new file mode 100644 index 00000000..873d2588 --- /dev/null +++ b/clash_doc/src/lib.rs @@ -0,0 +1,5 @@ +#[doc = "docs for clash"] +#[doc(inline)] +pub use clash_lib::ClashConfigDef; +#[doc(inline)] +pub use clash_lib::ClashDNSConfigDef; diff --git a/clash_lib/Cargo.toml b/clash_lib/Cargo.toml index 58b66fa6..1bd5f3ae 100644 --- a/clash_lib/Cargo.toml +++ b/clash_lib/Cargo.toml @@ -48,7 +48,8 @@ filetime = "0.2" axum = { version = "0.6.20", features = ["ws"] } tower-http = { version = "0.4.0", features = ["fs", "trace", "cors"] } chrono = { version = "0.4.26", features = ["serde"] } -tun = "0.5" +tun = { version = "0.5", features = ["async"] } +netstack-lwip = { git = "https://github.com/Watfaq/netstack-lwip.git", rev = "4fef23" } serde = { version = "1.0", features=["derive"] } diff --git a/clash_lib/src/app/dispatcher.rs b/clash_lib/src/app/dispatcher.rs index c9b00094..1601c947 100644 --- a/clash_lib/src/app/dispatcher.rs +++ b/clash_lib/src/app/dispatcher.rs @@ -57,9 +57,9 @@ impl Dispatcher { mode.clone() } - pub async fn dispatch_stream(&self, sess: Session, mut lhs: Box) + pub async fn dispatch_stream(&self, sess: Session, mut lhs: S) where - S: AsyncRead + AsyncWrite + Unpin + ?Sized, + S: AsyncRead + AsyncWrite + Unpin + Send, { let sess = if self.resolver.fake_ip_enabled() { match sess.destination { diff --git a/clash_lib/src/config/internal/config.rs b/clash_lib/src/config/internal/config.rs index 08086c68..1497a5bd 100644 --- a/clash_lib/src/config/internal/config.rs +++ b/clash_lib/src/config/internal/config.rs @@ -75,11 +75,7 @@ impl TryFrom for Config { tun: match c.tun { Some(mapping) => TunConfig::deserialize(MapDeserializer::new(mapping.into_iter())) .map_err(|e| Error::InvalidConfig(format!("invalid tun config: {}", e)))?, - None => TunConfig { - enable: false, - device_url: String::new(), - dns_hijack: Vec::new(), - }, + None => TunConfig::default(), }, profile: Profile { store_selected: c.profile.store_selected, @@ -207,12 +203,11 @@ pub struct Profile { store_fakeip: bool, } -#[derive(Deserialize)] +#[derive(Deserialize, Default)] #[serde(rename_all = "kebab-case")] pub struct TunConfig { pub enable: bool, - pub device_url: String, - pub dns_hijack: Vec, + pub device_id: String, } #[derive(Clone, Default)] diff --git a/clash_lib/src/proxy/http/inbound/connector.rs b/clash_lib/src/proxy/http/inbound/connector.rs index 6d50601b..63619320 100644 --- a/clash_lib/src/proxy/http/inbound/connector.rs +++ b/clash_lib/src/proxy/http/inbound/connector.rs @@ -54,7 +54,7 @@ impl tower::Service for Connector { }; tokio::spawn(async move { - dispatcher.dispatch_stream(sess, Box::new(right) as _).await; + dispatcher.dispatch_stream(sess, right).await; }); Ok(Box::new(left) as _) diff --git a/clash_lib/src/proxy/http/inbound/proxy.rs b/clash_lib/src/proxy/http/inbound/proxy.rs index b04cda4b..80a2cbea 100644 --- a/clash_lib/src/proxy/http/inbound/proxy.rs +++ b/clash_lib/src/proxy/http/inbound/proxy.rs @@ -69,9 +69,7 @@ async fn proxy( ..Default::default() }; - dispatcher - .dispatch_stream(sess, Box::new(upgraded) as _) - .await + dispatcher.dispatch_stream(sess, upgraded).await } Err(e) => warn!("HTTP handshake failure, {}", e), } diff --git a/clash_lib/src/proxy/socks/inbound/stream.rs b/clash_lib/src/proxy/socks/inbound/stream.rs index 7e10cc02..78fc6235 100644 --- a/clash_lib/src/proxy/socks/inbound/stream.rs +++ b/clash_lib/src/proxy/socks/inbound/stream.rs @@ -131,9 +131,7 @@ pub async fn handle_tcp<'a>( s.write_all(&buf[..]).await?; sess.destination = dst; - dispatcher - .dispatch_stream(sess.to_owned(), Box::new(s) as _) - .await; + dispatcher.dispatch_stream(sess.to_owned(), s).await; Ok(()) } diff --git a/clash_lib/src/proxy/tun/datagram.rs b/clash_lib/src/proxy/tun/datagram.rs new file mode 100644 index 00000000..adb71a89 --- /dev/null +++ b/clash_lib/src/proxy/tun/datagram.rs @@ -0,0 +1,109 @@ +use std::task::Poll; + +use futures::{ready, Sink, Stream}; + +use crate::{ + common::errors::new_io_error, + proxy::{datagram::UdpPacket, InboundDatagram}, +}; + +#[derive(Debug)] +pub struct TunDatagram { + rx: tokio::sync::mpsc::Receiver, + tx: tokio::sync::mpsc::Sender, + + pkt: Option, + flushed: bool, +} + +impl TunDatagram { + pub fn new( + tx: tokio::sync::mpsc::Sender, + rx: tokio::sync::mpsc::Receiver, + ) -> Self { + Self { + rx, + tx, + pkt: None, + flushed: true, + } + } +} + +impl InboundDatagram for TunDatagram {} + +impl Stream for TunDatagram { + type Item = UdpPacket; + + fn poll_next( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + self.rx.poll_recv(cx) + } +} + +impl Sink for TunDatagram { + type Error = std::io::Error; + + fn poll_ready( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + if !self.flushed { + match self.poll_flush(cx)? { + Poll::Ready(()) => {} + Poll::Pending => return Poll::Pending, + } + } + + Poll::Ready(Ok(())) + } + + fn start_send(self: std::pin::Pin<&mut Self>, item: UdpPacket) -> Result<(), Self::Error> { + let pin = self.get_mut(); + pin.pkt = Some(item); + pin.flushed = false; + Ok(()) + } + + fn poll_flush( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + if self.flushed { + return Poll::Ready(Ok(())); + } + + let Self { + ref mut tx, + ref mut pkt, + ref mut flushed, + .. + } = *self; + + 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()))), + } + } else { + Poll::Ready(Err(new_io_error("no packet to send".into()))) + } + } + + fn poll_close( + mut self: std::pin::Pin<&mut Self>, + 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 new file mode 100644 index 00000000..cb428fae --- /dev/null +++ b/clash_lib/src/proxy/tun/inbound.rs @@ -0,0 +1,218 @@ +use super::{datagram::TunDatagram, netstack}; +use std::{net::SocketAddr, sync::Arc}; + +use futures::{SinkExt, StreamExt}; +use tracing::{error, info, warn}; +use tun::TunPacket; +use url::Url; + +use crate::{ + app::{dispatcher::Dispatcher, ThreadSafeDNSResolver}, + config::internal::config::TunConfig, + proxy::datagram::UdpPacket, + session::{Network, Session, SocksAddr}, + Runner, +}; + +async fn handl_inbound_stream( + stream: netstack::TcpStream, + local_addr: SocketAddr, + remote_addr: SocketAddr, + dispatcher: Arc, + resolver: ThreadSafeDNSResolver, +) { + let mut sess = Session { + network: Network::Tcp, + source: local_addr, + destination: remote_addr.into(), + ..Default::default() + }; + + if resolver.fake_ip_enabled() && resolver.is_fake_ip(remote_addr.ip()).await { + if let Some(host) = resolver.reverse_lookup(remote_addr.ip()).await { + sess.destination = (host, remote_addr.port()).try_into().unwrap(); + } else { + error!("failed to resolve fake ip: {}", remote_addr.ip()); + return; + } + } + + dispatcher.dispatch_stream(sess, stream).await; +} + +async fn handle_inbound_datagram( + socket: Box, + dispatcher: Arc, + resolver: ThreadSafeDNSResolver, +) { + // netstack communications + let (ls, mut lr) = socket.split(); + let ls = Arc::new(ls); + + let (l_tx, mut l_rx) = tokio::sync::mpsc::channel::(32); + + let (d_tx, mut d_rx) = tokio::sync::mpsc::channel::(32); + + // for dispatcher - the dispatcher would receive packets from this channel, which is from the stack + // and send back packets to this channel, which is to the tun + let udp_stream = TunDatagram::new(l_tx, d_rx); + + tokio::spawn(async move { + while let Some(pkt) = l_rx.recv().await { + let src_addr = match pkt.src_addr { + SocksAddr::Ip(ip) => ip, + SocksAddr::Domain(host, port) => { + if let Some(ip) = resolver.lookup_fake_ip(&host).await { + (ip, port).into() + } else { + warn!("failed to resolve fake ip: {}", host); + continue; + } + } + }; + if let Err(e) = ls.send_to( + &pkt.data[..], + &src_addr, + &pkt.dst_addr.must_into_socket_addr(), + ) { + warn!("failed to send udp packet to netstack: {}", e); + } + } + }); + + tokio::spawn(async move { + 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(pkt) => { + if let Err(e) = l_tx.send(pkt).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(), + dst_addr: dst_addr.into(), + }; + + match d_tx.send(pkt).await { + Ok(_) => {} + Err(e) => { + warn!("failed to send udp packet to proxy: {}", e); + } + } + } + }); + + let mut sess = Session { + network: Network::Udp, + ..Default::default() + }; + + dispatcher.dispatch_datagram(sess, Box::new(udp_stream)); +} + +pub fn get_runner( + cfg: TunConfig, + dispatcher: Arc, + resolver: ThreadSafeDNSResolver, +) -> anyhow::Result { + if !cfg.enable { + return Ok(Box::pin(async {})); + } + + let device_id = cfg.device_id; + + let u = Url::parse(&device_id)?; + + let mut tun_cfg = tun::Configuration::default(); + + match u.scheme() { + "fd" => { + let fd = u.path().parse()?; + tun_cfg.raw_fd(fd); + } + "dev" => { + let dev = u.path(); + tun_cfg.name(dev); + } + _ => { + return Err(anyhow!("invalid device id: {}", device_id)); + } + } + + tun_cfg.up(); + + let tun = tun::create_as_async(&tun_cfg)?; + + let (stack, mut tcp_listener, udp_socket) = netstack::NetStack::with_buffer_size(512, 256)?; + + Ok(Box::pin(async move { + let framed = tun.into_framed(); + + let (mut tun_sink, mut tun_stream) = framed.split(); + let (mut stack_sink, mut stack_stream) = stack.split(); + + let mut futs: Vec = vec![]; + + futs.push(Box::pin(async move { + while let Some(pkt) = stack_stream.next().await { + match pkt { + Ok(pkt) => { + if let Err(e) = tun_sink.send(TunPacket::new(pkt)).await { + error!("failed to send pkt to tun: {}", e); + break; + } + } + Err(e) => { + error!("tun stack error: {}", e); + break; + } + } + } + })); + + futs.push(Box::pin(async move { + while let Some(pkt) = tun_stream.next().await { + match pkt { + Ok(pkt) => { + if let Err(e) = stack_sink.send(pkt.into_bytes().into()).await { + error!("failed to send pkt to stack: {}", e); + break; + } + } + Err(e) => { + error!("tun stream error: {}", e); + break; + } + } + } + })); + + 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(), + )); + } + })); + + futs.push(Box::pin(async move { + handle_inbound_datagram(udp_socket, dispatcher, resolver).await; + })); + + info!("tun started"); + futures::future::select_all(futs).await; + })) +} diff --git a/clash_lib/src/proxy/tun/mod.rs b/clash_lib/src/proxy/tun/mod.rs index 1d0713ce..b619eca0 100644 --- a/clash_lib/src/proxy/tun/mod.rs +++ b/clash_lib/src/proxy/tun/mod.rs @@ -1,7 +1,3 @@ -use std::sync::Arc; - -use crate::{app::dispatcher::Dispatcher, config::internal::config::TunConfig, Runner}; - -pub fn get_runner(cfg: TunConfig, dispatcher: Arc) -> anyhow::Result { - todo!() -} +pub mod inbound; +pub use netstack_lwip as netstack; +mod datagram;