From e43537939a00450bec22c2aa97fd2a5a45dd768d Mon Sep 17 00:00:00 2001 From: "Sijie.Sun" Date: Sun, 10 Aug 2025 22:56:41 +0800 Subject: [PATCH] clippy all codes (#1214) 1. clippy code 2. add fmt and clippy check in ci --- .github/workflows/core.yml | 4 +- .github/workflows/gui.yml | 19 +- .github/workflows/install_gui_dep.sh | 11 ++ .github/workflows/install_rust.sh | 4 +- .github/workflows/test.yml | 20 ++- CONTRIBUTING.md | 6 +- CONTRIBUTING_zh.md | 6 +- easytier-contrib/easytier-ffi/src/lib.rs | 51 ++++-- easytier-gui/src-tauri/src/elevate/linux.rs | 36 +--- easytier-gui/src-tauri/src/elevate/mod.rs | 81 --------- easytier-rpc-build/Cargo.toml | 2 +- easytier-rpc-build/src/lib.rs | 17 +- easytier-web/build.rs | 17 +- easytier-web/src/client_manager/mod.rs | 8 +- easytier-web/src/client_manager/session.rs | 12 +- easytier-web/src/client_manager/storage.rs | 12 +- easytier-web/src/main.rs | 2 +- easytier-web/src/restful/auth.rs | 2 +- .../src/restful/captcha/base/captcha.rs | 41 ++--- .../src/restful/captcha/base/randoms.rs | 4 +- .../captcha/{captcha => builder}/mod.rs | 0 .../captcha/{captcha => builder}/spec.rs | 0 .../captcha/extension/axum_tower_sessions.rs | 4 +- .../src/restful/captcha/extension/mod.rs | 2 +- easytier-web/src/restful/captcha/mod.rs | 2 +- .../src/restful/captcha/utils/color.rs | 23 +-- .../src/restful/captcha/utils/font.rs | 4 +- easytier-web/src/restful/mod.rs | 2 +- easytier-web/src/restful/network.rs | 19 +- easytier-web/src/restful/users.rs | 10 +- easytier-web/src/web/mod.rs | 4 +- easytier/Cargo.toml | 2 +- easytier/build.rs | 6 +- easytier/src/common/acl_processor.rs | 155 +++++++++-------- easytier/src/common/compressor.rs | 14 +- easytier/src/common/config.rs | 105 ++++++----- easytier/src/common/constants.rs | 4 +- easytier/src/common/defer.rs | 4 +- easytier/src/common/dns.rs | 20 +-- easytier/src/common/global_ctx.rs | 30 ++-- easytier/src/common/ifcfg/mod.rs | 4 +- easytier/src/common/ifcfg/netlink.rs | 12 +- easytier/src/common/ifcfg/win/luid.rs | 2 +- easytier/src/common/ifcfg/win/mod.rs | 2 +- easytier/src/common/ifcfg/win/netsh.rs | 2 +- easytier/src/common/ifcfg/win/types.rs | 2 +- easytier/src/common/mod.rs | 4 +- easytier/src/common/netns.rs | 9 +- easytier/src/common/network.rs | 24 +-- easytier/src/common/stats_manager.rs | 15 +- easytier/src/common/stun.rs | 51 +++--- easytier/src/common/token_bucket.rs | 16 +- easytier/src/connector/direct.rs | 44 ++--- easytier/src/connector/dns_connector.rs | 7 +- easytier/src/connector/http_connector.rs | 4 +- easytier/src/connector/manual.rs | 51 +++--- .../connector/udp_hole_punch/both_easy_sym.rs | 2 +- .../src/connector/udp_hole_punch/common.rs | 12 +- easytier/src/connector/udp_hole_punch/cone.rs | 4 +- easytier/src/connector/udp_hole_punch/mod.rs | 12 +- .../connector/udp_hole_punch/sym_to_cone.rs | 26 +-- easytier/src/easytier-cli.rs | 63 +++---- easytier/src/easytier-core.rs | 38 ++-- easytier/src/gateway/fast_socks5/mod.rs | 2 +- easytier/src/gateway/fast_socks5/server.rs | 8 +- .../gateway/fast_socks5/util/target_addr.rs | 12 +- easytier/src/gateway/icmp_proxy.rs | 69 ++++---- easytier/src/gateway/ip_reassembler.rs | 43 ++--- easytier/src/gateway/kcp_proxy.rs | 30 ++-- easytier/src/gateway/mod.rs | 10 +- easytier/src/gateway/quic_proxy.rs | 4 +- easytier/src/gateway/socks5.rs | 90 ++++------ easytier/src/gateway/tcp_proxy.rs | 26 ++- .../gateway/tokio_smoltcp/channel_device.rs | 10 +- easytier/src/gateway/tokio_smoltcp/device.rs | 11 +- easytier/src/gateway/tokio_smoltcp/mod.rs | 8 +- easytier/src/gateway/tokio_smoltcp/reactor.rs | 20 +-- easytier/src/gateway/tokio_smoltcp/socket.rs | 8 +- easytier/src/gateway/udp_proxy.rs | 31 ++-- .../instance/dns_server/client_instance.rs | 7 +- easytier/src/instance/dns_server/config.rs | 6 +- easytier/src/instance/dns_server/runner.rs | 2 +- easytier/src/instance/dns_server/server.rs | 14 +- .../instance/dns_server/server_instance.rs | 21 ++- .../dns_server/system_config/linux.rs | 17 +- easytier/src/instance/dns_server/tests.rs | 2 +- easytier/src/instance/instance.rs | 24 ++- easytier/src/instance/listeners.rs | 2 +- easytier/src/instance/mod.rs | 2 + easytier/src/instance/virtual_nic.rs | 23 +-- easytier/src/instance_manager.rs | 31 ++-- easytier/src/launcher.rs | 79 ++++----- easytier/src/lib.rs | 6 +- easytier/src/peer_center/instance.rs | 22 +-- easytier/src/peer_center/server.rs | 2 +- easytier/src/peers/acl_filter.rs | 10 +- easytier/src/peers/encrypt/aes_gcm.rs | 18 +- easytier/src/peers/encrypt/mod.rs | 2 +- easytier/src/peers/encrypt/openssl_cipher.rs | 8 +- easytier/src/peers/encrypt/ring_aes_gcm.rs | 16 +- easytier/src/peers/encrypt/ring_chacha20.rs | 8 +- easytier/src/peers/encrypt/xor_cipher.rs | 4 +- easytier/src/peers/foreign_network_client.rs | 2 +- easytier/src/peers/foreign_network_manager.rs | 99 ++++++----- easytier/src/peers/graph_algo.rs | 41 +++-- easytier/src/peers/peer.rs | 6 +- easytier/src/peers/peer_conn.rs | 19 +- easytier/src/peers/peer_conn_ping.rs | 4 +- easytier/src/peers/peer_manager.rs | 81 ++++----- easytier/src/peers/peer_map.rs | 22 ++- easytier/src/peers/peer_ospf_route.rs | 164 ++++++++---------- easytier/src/peers/peer_rpc.rs | 7 +- easytier/src/peers/route_trait.rs | 14 +- easytier/src/peers/rpc_service.rs | 34 ++-- easytier/src/peers/tests.rs | 2 +- easytier/src/proto/cli.rs | 2 +- easytier/src/proto/common.rs | 36 ++-- easytier/src/proto/error.rs | 2 + easytier/src/proto/rpc_impl/bidirect.rs | 15 +- easytier/src/proto/rpc_impl/client.rs | 55 +++--- easytier/src/proto/rpc_impl/packet.rs | 66 +++---- easytier/src/proto/rpc_impl/server.rs | 30 ++-- .../src/proto/rpc_impl/service_registry.rs | 6 + easytier/src/proto/rpc_types/handler.rs | 1 - easytier/src/proto/tests.rs | 12 +- easytier/src/tests/mod.rs | 1 - easytier/src/tests/three_node.rs | 154 ++++++++-------- easytier/src/tunnel/common.rs | 24 +-- easytier/src/tunnel/filter.rs | 14 +- easytier/src/tunnel/mod.rs | 8 +- easytier/src/tunnel/mpsc.rs | 9 +- easytier/src/tunnel/packet_def.rs | 8 +- easytier/src/tunnel/quic.rs | 8 +- easytier/src/tunnel/ring.rs | 18 +- easytier/src/tunnel/tcp.rs | 6 +- easytier/src/tunnel/udp.rs | 41 ++--- easytier/src/tunnel/websocket.rs | 18 +- easytier/src/tunnel/wireguard.rs | 16 +- easytier/src/utils.rs | 15 +- easytier/src/vpn_portal/wireguard.rs | 42 ++--- easytier/src/web_client/controller.rs | 9 +- easytier/src/web_client/mod.rs | 12 +- easytier/src/web_client/session.rs | 2 +- flake.nix | 2 +- 144 files changed, 1475 insertions(+), 1531 deletions(-) create mode 100644 .github/workflows/install_gui_dep.sh rename easytier-web/src/restful/captcha/{captcha => builder}/mod.rs (100%) rename easytier-web/src/restful/captcha/{captcha => builder}/spec.rs (100%) diff --git a/.github/workflows/core.yml b/.github/workflows/core.yml index 8eb464e4..7cb8de18 100644 --- a/.github/workflows/core.yml +++ b/.github/workflows/core.yml @@ -229,8 +229,8 @@ jobs: rustup set auto-self-update disable - rustup install 1.87 - rustup default 1.87 + rustup install 1.89 + rustup default 1.89 export CC=clang export CXX=clang++ diff --git a/.github/workflows/gui.yml b/.github/workflows/gui.yml index aab8d4fe..146406c6 100644 --- a/.github/workflows/gui.yml +++ b/.github/workflows/gui.yml @@ -29,7 +29,7 @@ jobs: concurrent_skipping: 'same_content_newer' skip_after_successful_duplicate: 'true' cancel_others: 'true' - paths: '["Cargo.toml", "Cargo.lock", "easytier/**", "easytier-gui/**", ".github/workflows/gui.yml", ".github/workflows/install_rust.sh"]' + paths: '["Cargo.toml", "Cargo.lock", "easytier/**", "easytier-gui/**", ".github/workflows/gui.yml", ".github/workflows/install_rust.sh", ".github/workflows/install_gui_dep.sh"]' build-gui: strategy: fail-fast: false @@ -78,20 +78,11 @@ jobs: needs: pre_job if: needs.pre_job.outputs.should_skip != 'true' steps: + - uses: actions/checkout@v3 + - name: Install GUI dependencies (x86 only) if: ${{ matrix.TARGET == 'x86_64-unknown-linux-musl' }} - run: | - sudo apt update - sudo apt install -qq libwebkit2gtk-4.1-dev \ - build-essential \ - curl \ - wget \ - file \ - libgtk-3-dev \ - librsvg2-dev \ - libxdo-dev \ - libssl-dev \ - patchelf + run: bash ./.github/workflows/install_gui_dep.sh - name: Install GUI cross compile (aarch64 only) if: ${{ matrix.TARGET == 'aarch64-unknown-linux-musl' }} @@ -128,8 +119,6 @@ jobs: echo "PKG_CONFIG_SYSROOT_DIR=/usr/aarch64-linux-gnu/" >> "$GITHUB_ENV" echo "PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig/" >> "$GITHUB_ENV" - - uses: actions/checkout@v3 - - name: Set current ref as env variable run: | echo "GIT_DESC=$(git log -1 --format=%cd.%h --date=format:%Y-%m-%d_%H:%M:%S)" >> $GITHUB_ENV diff --git a/.github/workflows/install_gui_dep.sh b/.github/workflows/install_gui_dep.sh new file mode 100644 index 00000000..aa61b198 --- /dev/null +++ b/.github/workflows/install_gui_dep.sh @@ -0,0 +1,11 @@ +sudo apt update +sudo apt install -qq libwebkit2gtk-4.1-dev \ + build-essential \ + curl \ + wget \ + file \ + libgtk-3-dev \ + librsvg2-dev \ + libxdo-dev \ + libssl-dev \ + patchelf \ No newline at end of file diff --git a/.github/workflows/install_rust.sh b/.github/workflows/install_rust.sh index 9eefcf05..0c7176cb 100644 --- a/.github/workflows/install_rust.sh +++ b/.github/workflows/install_rust.sh @@ -31,8 +31,8 @@ fi # see https://github.com/rust-lang/rustup/issues/3709 rustup set auto-self-update disable -rustup install 1.87 -rustup default 1.87 +rustup install 1.89 +rustup default 1.89 # mips/mipsel cannot add target from rustup, need compile by ourselves if [[ $OS =~ ^ubuntu.*$ && $TARGET =~ ^mips.*$ ]]; then diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2d401035..8ff4da26 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,7 +28,7 @@ jobs: # All of these options are optional, so you can remove them if you are happy with the defaults concurrent_skipping: 'never' skip_after_successful_duplicate: 'true' - paths: '["Cargo.toml", "Cargo.lock", "easytier/**", ".github/workflows/test.yml"]' + paths: '["Cargo.toml", "Cargo.lock", "easytier/**", ".github/workflows/test.yml", ".github/workflows/install_gui_dep.sh", ".github/workflows/install_rust.sh"]' test: runs-on: ubuntu-22.04 needs: pre_job @@ -89,6 +89,24 @@ jobs: ./target key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock') }} + - name: Install GUI dependencies (Used by clippy) + run: | + bash ./.github/workflows/install_gui_dep.sh + bash ./.github/workflows/install_rust.sh + rustup component add rustfmt + rustup component add clippy + + - name: Check formatting + if: ${{ !cancelled() }} + run: cargo fmt --all -- --check + + - name: Check Clippy + if: ${{ !cancelled() }} + # NOTE: tauri need `dist` dir in build.rs + run: | + mkdir -p easytier-gui/dist + cargo clippy --all-targets --all-features --all -- -D warnings + - name: Run tests run: | sudo prlimit --pid $$ --nofile=1048576:1048576 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 31185251..d4cb38a2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ Thank you for your interest in contributing to EasyTier! This document provides #### Required Tools - Node.js v21 or higher - pnpm v9 or higher -- Rust toolchain (version 1.87) +- Rust toolchain (version 1.89) - LLVM and Clang - Protoc (Protocol Buffers compiler) @@ -79,8 +79,8 @@ sudo apt install -y bridge-utils 2. Install dependencies: ```bash # Install Rust toolchain - rustup install 1.87 - rustup default 1.87 + rustup install 1.89 + rustup default 1.89 # Install project dependencies pnpm -r install diff --git a/CONTRIBUTING_zh.md b/CONTRIBUTING_zh.md index 7eb04355..7e663da6 100644 --- a/CONTRIBUTING_zh.md +++ b/CONTRIBUTING_zh.md @@ -34,7 +34,7 @@ #### 必需工具 - Node.js v21 或更高版本 - pnpm v9 或更高版本 -- Rust 工具链(版本 1.87) +- Rust 工具链(版本 1.89) - LLVM 和 Clang - Protoc(Protocol Buffers 编译器) @@ -87,8 +87,8 @@ sudo apt install -y bridge-utils 2. 安装依赖: ```bash # 安装 Rust 工具链 - rustup install 1.87 - rustup default 1.87 + rustup install 1.89 + rustup default 1.89 # 安装项目依赖 pnpm -r install diff --git a/easytier-contrib/easytier-ffi/src/lib.rs b/easytier-contrib/easytier-ffi/src/lib.rs index da7fcc9c..1c2e5abd 100644 --- a/easytier-contrib/easytier-ffi/src/lib.rs +++ b/easytier-contrib/easytier-ffi/src/lib.rs @@ -29,8 +29,10 @@ fn set_error_msg(msg: &str) { msg_buf[..len].copy_from_slice(bytes); } +/// # Safety +/// Set the tun fd #[no_mangle] -pub extern "C" fn set_tun_fd( +pub unsafe extern "C" fn set_tun_fd( inst_name: *const std::ffi::c_char, fd: std::ffi::c_int, ) -> std::ffi::c_int { @@ -43,18 +45,23 @@ pub extern "C" fn set_tun_fd( if !INSTANCE_NAME_ID_MAP.contains_key(&inst_name) { return -1; } - match INSTANCE_MANAGER.set_tun_fd(&INSTANCE_NAME_ID_MAP.get(&inst_name).unwrap().value(), fd) { - Ok(_) => { - 0 - } - Err(_) => { - -1 - } + + let inst_id = *INSTANCE_NAME_ID_MAP + .get(&inst_name) + .as_ref() + .unwrap() + .value(); + + match INSTANCE_MANAGER.set_tun_fd(&inst_id, fd) { + Ok(_) => 0, + Err(_) => -1, } } +/// # Safety +/// Get the last error message #[no_mangle] -pub extern "C" fn get_error_msg(out: *mut *const std::ffi::c_char) { +pub unsafe extern "C" fn get_error_msg(out: *mut *const std::ffi::c_char) { let msg_buf = ERROR_MSG.lock().unwrap(); if msg_buf.is_empty() { unsafe { @@ -78,8 +85,10 @@ pub extern "C" fn free_string(s: *const std::ffi::c_char) { } } +/// # Safety +/// Parse the config #[no_mangle] -pub extern "C" fn parse_config(cfg_str: *const std::ffi::c_char) -> std::ffi::c_int { +pub unsafe extern "C" fn parse_config(cfg_str: *const std::ffi::c_char) -> std::ffi::c_int { let cfg_str = unsafe { assert!(!cfg_str.is_null()); std::ffi::CStr::from_ptr(cfg_str) @@ -95,8 +104,10 @@ pub extern "C" fn parse_config(cfg_str: *const std::ffi::c_char) -> std::ffi::c_ 0 } +/// # Safety +/// Run the network instance #[no_mangle] -pub extern "C" fn run_network_instance(cfg_str: *const std::ffi::c_char) -> std::ffi::c_int { +pub unsafe extern "C" fn run_network_instance(cfg_str: *const std::ffi::c_char) -> std::ffi::c_int { let cfg_str = unsafe { assert!(!cfg_str.is_null()); std::ffi::CStr::from_ptr(cfg_str) @@ -131,8 +142,10 @@ pub extern "C" fn run_network_instance(cfg_str: *const std::ffi::c_char) -> std: 0 } +/// # Safety +/// Retain the network instance #[no_mangle] -pub extern "C" fn retain_network_instance( +pub unsafe extern "C" fn retain_network_instance( inst_names: *const *const std::ffi::c_char, length: usize, ) -> std::ffi::c_int { @@ -168,13 +181,15 @@ pub extern "C" fn retain_network_instance( return -1; } - let _ = INSTANCE_NAME_ID_MAP.retain(|k, _| inst_names.contains(k)); + INSTANCE_NAME_ID_MAP.retain(|k, _| inst_names.contains(k)); 0 } +/// # Safety +/// Collect the network infos #[no_mangle] -pub extern "C" fn collect_network_infos( +pub unsafe extern "C" fn collect_network_infos( infos: *mut KeyValuePair, max_length: usize, ) -> std::ffi::c_int { @@ -233,7 +248,9 @@ mod tests { network = "test_network" "#; let cstr = std::ffi::CString::new(cfg_str).unwrap(); - assert_eq!(parse_config(cstr.as_ptr()), 0); + unsafe { + assert_eq!(parse_config(cstr.as_ptr()), 0); + } } #[test] @@ -243,6 +260,8 @@ mod tests { network = "test_network" "#; let cstr = std::ffi::CString::new(cfg_str).unwrap(); - assert_eq!(run_network_instance(cstr.as_ptr()), 0); + unsafe { + assert_eq!(run_network_instance(cstr.as_ptr()), 0); + } } } diff --git a/easytier-gui/src-tauri/src/elevate/linux.rs b/easytier-gui/src-tauri/src/elevate/linux.rs index 374a976e..346e2cfb 100644 --- a/easytier-gui/src-tauri/src/elevate/linux.rs +++ b/easytier-gui/src-tauri/src/elevate/linux.rs @@ -16,41 +16,13 @@ impl Command { /// Check the state the current program running /// /// Return `true` if the program is running as root, otherwise false - /// - /// # Examples - /// - /// ```no_run - /// use elevated_command::Command; - /// - /// fn main() { - /// let is_elevated = Command::is_elevated(); - /// - /// } - /// ``` pub fn is_elevated() -> bool { let uid = unsafe { libc::getuid() }; - if uid == 0 { - true - } else { - false - } + uid == 0 } /// Prompting the user with a graphical OS dialog for the root password, /// excuting the command with escalated privileges, and return the output - /// - /// # Examples - /// - /// ```no_run - /// use elevated_command::Command; - /// use std::process::Command as StdCommand; - /// - /// fn main() { - /// let mut cmd = StdCommand::new("path to the application"); - /// let elevated_cmd = Command::new(cmd); - /// let output = elevated_cmd.output().unwrap(); - /// } - /// ``` pub fn output(&self) -> Result { let pkexec = PathBuf::from_str("/bin/pkexec")?; let mut command = StdCommand::new(pkexec); @@ -70,10 +42,8 @@ impl Command { if let Ok(home) = home { command.arg(format!("HOME={}", home)); } - } else { - if self.cmd.get_envs().any(|(_, v)| v.is_some()) { - command.arg("env"); - } + } else if self.cmd.get_envs().any(|(_, v)| v.is_some()) { + command.arg("env"); } for (k, v) in self.cmd.get_envs() { if let Some(value) = v { diff --git a/easytier-gui/src-tauri/src/elevate/mod.rs b/easytier-gui/src-tauri/src/elevate/mod.rs index f3ff06ca..594be6f7 100644 --- a/easytier-gui/src-tauri/src/elevate/mod.rs +++ b/easytier-gui/src-tauri/src/elevate/mod.rs @@ -40,22 +40,6 @@ impl Command { /// To pass environment variables on Windows, /// to inherit environment variables from the parent process and /// to change the working directory will be supported in later versions - /// - /// # Examples - /// - /// ```no_run - /// use elevated_command::Command; - /// use std::process::Command as StdCommand; - /// - /// fn main() { - /// let mut cmd = StdCommand::new("path to the application"); - /// - /// cmd.arg("some arg"); - /// cmd.env("some key", "some value"); - /// - /// let elevated_cmd = Command::new(cmd); - /// } - /// ``` pub fn new(cmd: StdCommand) -> Self { Self { cmd, @@ -67,73 +51,21 @@ impl Command { /// Consumes the `Take`, returning the wrapped std::process::Command /// /// # Examples - /// - /// ```no_run - /// use elevated_command::Command; - /// use std::process::Command as StdCommand; - /// - /// fn main() { - /// let mut cmd = StdCommand::new("path to the application"); - /// let elevated_cmd = Command::new(cmd); - /// let cmd = elevated_cmd.into_inner(); - /// } - /// ``` pub fn into_inner(self) -> StdCommand { self.cmd } /// Gets a mutable reference to the underlying std::process::Command - /// - /// # Examples - /// - /// ```no_run - /// use elevated_command::Command; - /// use std::process::Command as StdCommand; - /// - /// fn main() { - /// let mut cmd = StdCommand::new("path to the application"); - /// let elevated_cmd = Command::new(cmd); - /// let cmd = elevated_cmd.get_ref(); - /// } - /// ``` pub fn get_ref(&self) -> &StdCommand { &self.cmd } /// Gets a reference to the underlying std::process::Command - /// - /// # Examples - /// - /// ```no_run - /// use elevated_command::Command; - /// use std::process::Command as StdCommand; - /// - /// fn main() { - /// let mut cmd = StdCommand::new("path to the application"); - /// let elevated_cmd = Command::new(cmd); - /// let cmd = elevated_cmd.get_mut(); - /// } - /// ``` pub fn get_mut(&mut self) -> &mut StdCommand { &mut self.cmd } /// Set the `icon` for the pop-up graphical OS dialog - /// - /// This method is only applicable on `MacOS` - /// - /// # Examples - /// - /// ```no_run - /// use elevated_command::Command; - /// use std::process::Command as StdCommand; - /// - /// fn main() { - /// let mut cmd = StdCommand::new("path to the application"); - /// let elevated_cmd = Command::new(cmd); - /// elevated_cmd.icon(include_bytes!("path to the icon").to_vec()); - /// } - /// ``` pub fn icon(&mut self, icon: Vec) -> &mut Self { self.icon = Some(icon); self @@ -142,19 +74,6 @@ impl Command { /// Set the name for the pop-up graphical OS dialog /// /// This method is only applicable on `MacOS` - /// - /// # Examples - /// - /// ```no_run - /// use elevated_command::Command; - /// use std::process::Command as StdCommand; - /// - /// fn main() { - /// let mut cmd = StdCommand::new("path to the application"); - /// let elevated_cmd = Command::new(cmd); - /// elevated_cmd.name("some name".to_string()); - /// } - /// ``` pub fn name(&mut self, name: String) -> &mut Self { self.name = Some(name); self diff --git a/easytier-rpc-build/Cargo.toml b/easytier-rpc-build/Cargo.toml index d433b460..3ed328ee 100644 --- a/easytier-rpc-build/Cargo.toml +++ b/easytier-rpc-build/Cargo.toml @@ -8,7 +8,7 @@ repository = "https://github.com/EasyTier/EasyTier" authors = ["kkrainbow"] keywords = ["vpn", "p2p", "network", "easytier"] categories = ["network-programming", "command-line-utilities"] -rust-version = "1.87.0" +rust-version = "1.89.0" license-file = "LICENSE" readme = "README.md" diff --git a/easytier-rpc-build/src/lib.rs b/easytier-rpc-build/src/lib.rs index a61ff1b8..3d24dadb 100644 --- a/easytier-rpc-build/src/lib.rs +++ b/easytier-rpc-build/src/lib.rs @@ -14,18 +14,11 @@ const NAMESPACE: &str = "easytier::proto::rpc_types"; /// /// See the crate-level documentation for more info. #[allow(missing_copy_implementations)] -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct ServiceGenerator { _private: (), } -impl ServiceGenerator { - /// Create a new `ServiceGenerator` instance with the default options set. - pub fn new() -> ServiceGenerator { - ServiceGenerator { _private: () } - } -} - impl prost_build::ServiceGenerator for ServiceGenerator { fn generate(&mut self, service: prost_build::Service, mut buf: &mut String) { use std::fmt::Write; @@ -78,7 +71,7 @@ impl prost_build::ServiceGenerator for ServiceGenerator { enum_methods, " {name} = {index},", name = method.proto_name, - index = format!("{}", idx + 1) + index = idx + 1 ) .unwrap(); @@ -87,7 +80,7 @@ impl prost_build::ServiceGenerator for ServiceGenerator { " {index} => Ok({service_name}MethodDescriptor::{name}),", service_name = service.name, name = method.proto_name, - index = format!("{}", idx + 1), + index = idx + 1, ) .unwrap(); @@ -102,12 +95,12 @@ impl prost_build::ServiceGenerator for ServiceGenerator { writeln!( client_methods, r#" async fn {name}(&self, ctrl: H::Controller, input: {input_type}) -> {namespace}::error::Result<{output_type}> {{ - {client_name}::{name}_inner(self.0.clone(), ctrl, input).await + {client_name}Client::{name}_inner(self.0.clone(), ctrl, input).await }}"#, name = method.name, input_type = method.input_type, output_type = method.output_type, - client_name = format!("{}Client", service.name), + client_name = service.name, namespace = NAMESPACE, ) .unwrap(); diff --git a/easytier-web/build.rs b/easytier-web/build.rs index 037ff6bd..3de4b90a 100644 --- a/easytier-web/build.rs +++ b/easytier-web/build.rs @@ -1,7 +1,10 @@ -fn main() { - // enable thunk-rs when target os is windows and arch is x86_64 or i686 - #[cfg(target_os = "windows")] - if !std::env::var("TARGET").unwrap_or_default().contains("aarch64"){ - thunk::thunk(); - } -} +fn main() { + // enable thunk-rs when target os is windows and arch is x86_64 or i686 + #[cfg(target_os = "windows")] + if !std::env::var("TARGET") + .unwrap_or_default() + .contains("aarch64") + { + thunk::thunk(); + } +} diff --git a/easytier-web/src/client_manager/mod.rs b/easytier-web/src/client_manager/mod.rs index 21458e85..f9e08024 100644 --- a/easytier-web/src/client_manager/mod.rs +++ b/easytier-web/src/client_manager/mod.rs @@ -25,7 +25,7 @@ fn load_geoip_db(geoip_db: Option) -> Option>> match maxminddb::Reader::open_readfile(&path) { Ok(reader) => { tracing::info!("Successfully loaded GeoIP2 database from {}", path); - return Some(reader); + Some(reader) } Err(err) => { tracing::debug!("Failed to load GeoIP2 database from {}: {}", path, err); @@ -207,10 +207,8 @@ impl ClientManager { let region = city.subdivisions.map(|r| { r.iter() - .map(|x| x.names.as_ref()) - .flatten() - .map(|x| x.get("zh-CN").or_else(|| x.get("en"))) - .flatten() + .filter_map(|x| x.names.as_ref()) + .filter_map(|x| x.get("zh-CN").or_else(|| x.get("en"))) .map(|x| x.to_string()) .collect::>() .join(",") diff --git a/easytier-web/src/client_manager/session.rs b/easytier-web/src/client_manager/session.rs index 877e7ce1..97a22598 100644 --- a/easytier-web/src/client_manager/session.rs +++ b/easytier-web/src/client_manager/session.rs @@ -94,14 +94,10 @@ impl SessionRpcService { return Ok(HeartbeatResponse {}); }; - let machine_id: uuid::Uuid = + let machine_id: uuid::Uuid = req.machine_id.map(Into::into).ok_or(anyhow::anyhow!( + "Machine id is not set correctly, expect uuid but got: {:?}", req.machine_id - .clone() - .map(Into::into) - .ok_or(anyhow::anyhow!( - "Machine id is not set correctly, expect uuid but got: {:?}", - req.machine_id - ))?; + ))?; let user_id = storage .db() @@ -121,7 +117,7 @@ impl SessionRpcService { if data.req.replace(req.clone()).is_none() { assert!(data.storage_token.is_none()); data.storage_token = Some(StorageToken { - token: req.user_token.clone().into(), + token: req.user_token.clone(), client_url: data.client_url.clone(), machine_id, user_id, diff --git a/easytier-web/src/client_manager/storage.rs b/easytier-web/src/client_manager/storage.rs index 9acf6f61..cbbac721 100644 --- a/easytier-web/src/client_manager/storage.rs +++ b/easytier-web/src/client_manager/storage.rs @@ -34,7 +34,7 @@ impl TryFrom for Storage { type Error = (); fn try_from(weak: Weak) -> Result { - weak.upgrade().map(|inner| Storage(inner)).ok_or(()) + weak.upgrade().map(Storage).ok_or(()) } } @@ -51,9 +51,7 @@ impl Storage { machine_id: &uuid::Uuid, client_url: &url::Url, ) { - map.remove_if(&machine_id, |_, v| { - v.storage_token.client_url == *client_url - }); + map.remove_if(machine_id, |_, v| v.storage_token.client_url == *client_url); } fn update_mid_to_client_info_map( @@ -74,11 +72,7 @@ impl Storage { } pub fn update_client(&self, stoken: StorageToken, report_time: i64) { - let inner = self - .0 - .user_clients_map - .entry(stoken.user_id) - .or_insert_with(DashMap::new); + let inner = self.0.user_clients_map.entry(stoken.user_id).or_default(); let client_info = ClientInfo { storage_token: stoken.clone(), diff --git a/easytier-web/src/main.rs b/easytier-web/src/main.rs index a238bbf3..b5949567 100644 --- a/easytier-web/src/main.rs +++ b/easytier-web/src/main.rs @@ -151,7 +151,7 @@ async fn get_dual_stack_listener( } else { None }; - let v4_listener = if let Ok(_) = local_ipv4().await { + let v4_listener = if local_ipv4().await.is_ok() { get_listener_by_url(&format!("{}://0.0.0.0:{}", protocol, port).parse().unwrap()).ok() } else { None diff --git a/easytier-web/src/restful/auth.rs b/easytier-web/src/restful/auth.rs index 8bb3aad0..9d0fffef 100644 --- a/easytier-web/src/restful/auth.rs +++ b/easytier-web/src/restful/auth.rs @@ -137,7 +137,7 @@ mod post { mod get { use crate::restful::{ captcha::{ - captcha::spec::SpecCaptcha, + builder::spec::SpecCaptcha, extension::{axum_tower_sessions::CaptchaAxumTowerSessionExt as _, CaptchaUtil}, NewCaptcha as _, }, diff --git a/easytier-web/src/restful/captcha/base/captcha.rs b/easytier-web/src/restful/captcha/base/captcha.rs index c7e45c87..3bed68e7 100644 --- a/easytier-web/src/restful/captcha/base/captcha.rs +++ b/easytier-web/src/restful/captcha/base/captcha.rs @@ -46,22 +46,22 @@ pub(crate) struct Captcha { /// 验证码文本类型 The character type of the captcha pub enum CaptchaType { /// 字母数字混合 - TypeDefault = 1, + Default = 1, /// 纯数字 - TypeOnlyNumber, + OnlyNumber, /// 纯字母 - TypeOnlyChar, + OnlyChar, /// 纯大写字母 - TypeOnlyUpper, + OnlyUpper, /// 纯小写字母 - TypeOnlyLower, + OnlyLower, /// 数字大写字母 - TypeNumAndUpper, + NumAndUpper, } /// 内置字体 Fonts shipped with the library @@ -92,29 +92,29 @@ impl Captcha { /// 生成随机验证码 pub fn alphas(&mut self) -> Vec { let mut cs = vec!['\0'; self.len]; - for i in 0..self.len { + for cs_i in cs.iter_mut() { match self.char_type { - CaptchaType::TypeDefault => cs[i] = self.randoms.alpha(), - CaptchaType::TypeOnlyNumber => { - cs[i] = self.randoms.alpha_under(self.randoms.num_max_index) + CaptchaType::Default => *cs_i = self.randoms.alpha(), + CaptchaType::OnlyNumber => { + *cs_i = self.randoms.alpha_under(self.randoms.num_max_index) } - CaptchaType::TypeOnlyChar => { - cs[i] = self + CaptchaType::OnlyChar => { + *cs_i = self .randoms .alpha_between(self.randoms.char_min_index, self.randoms.char_max_index) } - CaptchaType::TypeOnlyUpper => { - cs[i] = self + CaptchaType::OnlyUpper => { + *cs_i = self .randoms .alpha_between(self.randoms.upper_min_index, self.randoms.upper_max_index) } - CaptchaType::TypeOnlyLower => { - cs[i] = self + CaptchaType::OnlyLower => { + *cs_i = self .randoms .alpha_between(self.randoms.lower_min_index, self.randoms.lower_max_index) } - CaptchaType::TypeNumAndUpper => { - cs[i] = self.randoms.alpha_under(self.randoms.upper_max_index) + CaptchaType::NumAndUpper => { + *cs_i = self.randoms.alpha_under(self.randoms.upper_max_index) } } } @@ -142,7 +142,7 @@ impl Captcha { } } - pub fn get_font(&mut self) -> Arc { + pub fn get_font(&'_ mut self) -> Arc> { if let Some(font) = font::get_font(&self.font_name) { font } else { @@ -185,6 +185,7 @@ where /// 特别地/In particular: /// /// - 对算术验证码[ArithmeticCaptcha](crate::captcha::arithmetic::ArithmeticCaptcha)而言,这里的`len`是验证码中数字的数量。 + /// /// For [ArithmeticCaptcha](crate::captcha::arithmetic::ArithmeticCaptcha), the `len` presents the count of the digits /// in the Captcha. fn with_size_and_len(width: i32, height: i32, len: usize) -> Self; @@ -226,7 +227,7 @@ impl NewCaptcha for Captcha { let len = 5; let width = 130; let height = 48; - let char_type = CaptchaType::TypeDefault; + let char_type = CaptchaType::Default; let chars = None; Self { diff --git a/easytier-web/src/restful/captcha/base/randoms.rs b/easytier-web/src/restful/captcha/base/randoms.rs index ed78579c..956616d0 100644 --- a/easytier-web/src/restful/captcha/base/randoms.rs +++ b/easytier-web/src/restful/captcha/base/randoms.rs @@ -1,6 +1,4 @@ - -use rand::{random}; - +use rand::random; /// 随机数工具类 pub(crate) struct Randoms { diff --git a/easytier-web/src/restful/captcha/captcha/mod.rs b/easytier-web/src/restful/captcha/builder/mod.rs similarity index 100% rename from easytier-web/src/restful/captcha/captcha/mod.rs rename to easytier-web/src/restful/captcha/builder/mod.rs diff --git a/easytier-web/src/restful/captcha/captcha/spec.rs b/easytier-web/src/restful/captcha/builder/spec.rs similarity index 100% rename from easytier-web/src/restful/captcha/captcha/spec.rs rename to easytier-web/src/restful/captcha/builder/spec.rs diff --git a/easytier-web/src/restful/captcha/extension/axum_tower_sessions.rs b/easytier-web/src/restful/captcha/extension/axum_tower_sessions.rs index 81597dbe..a630282b 100644 --- a/easytier-web/src/restful/captcha/extension/axum_tower_sessions.rs +++ b/easytier-web/src/restful/captcha/extension/axum_tower_sessions.rs @@ -10,7 +10,7 @@ use axum::response::Response; use std::fmt::Debug; use tower_sessions::Session; -const CAPTCHA_KEY: &'static str = "ez-captcha"; +const CAPTCHA_KEY: &str = "ez-captcha"; /// Axum & Tower_Sessions #[async_trait] @@ -32,7 +32,7 @@ pub trait CaptchaAxumTowerSessionStaticExt { /// Verify the Captcha code, and return whether user's code is correct. async fn ver(code: &str, session: &Session) -> bool { match session.get::(CAPTCHA_KEY).await { - Ok(Some(ans)) => ans.to_ascii_lowercase() == code.to_ascii_lowercase(), + Ok(Some(ans)) => ans.eq_ignore_ascii_case(code), _ => false, } } diff --git a/easytier-web/src/restful/captcha/extension/mod.rs b/easytier-web/src/restful/captcha/extension/mod.rs index c11a9766..ada8a980 100644 --- a/easytier-web/src/restful/captcha/extension/mod.rs +++ b/easytier-web/src/restful/captcha/extension/mod.rs @@ -1,7 +1,7 @@ pub mod axum_tower_sessions; use super::base::captcha::AbstractCaptcha; -use super::captcha::spec::SpecCaptcha; +use super::builder::spec::SpecCaptcha; use super::{CaptchaFont, NewCaptcha}; /// 验证码工具类 - Captcha Utils diff --git a/easytier-web/src/restful/captcha/mod.rs b/easytier-web/src/restful/captcha/mod.rs index 6f504e4d..9fed9d91 100644 --- a/easytier-web/src/restful/captcha/mod.rs +++ b/easytier-web/src/restful/captcha/mod.rs @@ -117,7 +117,7 @@ #![allow(dead_code)] pub(crate) mod base; -pub mod captcha; +pub mod builder; pub mod extension; mod utils; diff --git a/easytier-web/src/restful/captcha/utils/color.rs b/easytier-web/src/restful/captcha/utils/color.rs index a5345c78..bf9bde4c 100644 --- a/easytier-web/src/restful/captcha/utils/color.rs +++ b/easytier-web/src/restful/captcha/utils/color.rs @@ -32,21 +32,24 @@ impl From<(u8, u8, u8)> for Color { } } -impl Into<(u8, u8, u8, u8)> for Color { - fn into(self) -> (u8, u8, u8, u8) { +impl From for (u8, u8, u8, u8) { + fn from(val: Color) -> Self { ( - (self.0 * 255.0) as u8, - (self.1 * 255.0) as u8, - (self.2 * 255.0) as u8, - (self.3 * 255.0) as u8, + (val.0 * 255.0) as u8, + (val.1 * 255.0) as u8, + (val.2 * 255.0) as u8, + (val.3 * 255.0) as u8, ) } } -impl Into for Color { - fn into(self) -> u32 { - let color: (u8, u8, u8, u8) = self.into(); - (color.0 as u32) << 24 + (color.1 as u32) << 16 + (color.2 as u32) << 8 + (color.3 as u32) +impl From for u32 { + fn from(val: Color) -> Self { + let color: (u8, u8, u8, u8) = val.into(); + (color.0 as u32) + << (24 + (color.1 as u32)) + << (16 + (color.2 as u32)) + << (8 + (color.3 as u32)) } } diff --git a/easytier-web/src/restful/captcha/utils/font.rs b/easytier-web/src/restful/captcha/utils/font.rs index 6bce05ce..5294fd32 100644 --- a/easytier-web/src/restful/captcha/utils/font.rs +++ b/easytier-web/src/restful/captcha/utils/font.rs @@ -11,7 +11,7 @@ struct FontAssets; // pub(crate) static ref FONTS: RwLock>> = Default::default(); // } -pub fn get_font(font_name: &str) -> Option> { +pub fn get_font(font_name: &'_ str) -> Option>> { // let fonts_cell = FONTS.get_or_init(|| Default::default()); // let guard = fonts_cell.read(); // @@ -31,7 +31,7 @@ pub fn get_font(font_name: &str) -> Option> { // } } -pub fn load_font(font_name: &str) -> Result, Box> { +pub fn load_font(font_name: &'_ str) -> Result>, Box> { match FontAssets::get(font_name) { Some(assets) => { let font = Font::try_from_vec(Vec::from(assets.data)).unwrap(); diff --git a/easytier-web/src/restful/mod.rs b/easytier-web/src/restful/mod.rs index d2170917..ba29da68 100644 --- a/easytier-web/src/restful/mod.rs +++ b/easytier-web/src/restful/mod.rs @@ -143,7 +143,7 @@ impl RestfulServer { return Err((StatusCode::UNAUTHORIZED, other_error("No such user").into())); }; - let machines = client_mgr.list_machine_by_user_id(user.id().clone()).await; + let machines = client_mgr.list_machine_by_user_id(user.id()).await; Ok(GetSummaryJsonResp { device_count: machines.len() as u32, diff --git a/easytier-web/src/restful/network.rs b/easytier-web/src/restful/network.rs index e8b08d16..9a103cc5 100644 --- a/easytier-web/src/restful/network.rs +++ b/easytier-web/src/restful/network.rs @@ -8,7 +8,7 @@ use axum_login::AuthUser; use easytier::launcher::NetworkConfig; use easytier::proto::common::Void; use easytier::proto::rpc_types::controller::BaseController; -use easytier::proto::web::*; +use easytier::proto::{self, web::*}; use crate::client_manager::session::{Location, Session}; use crate::client_manager::ClientManager; @@ -85,7 +85,7 @@ impl NetworkApi { let Some(user_id) = auth_session.user.as_ref().map(|x| x.id()) else { return Err(( StatusCode::UNAUTHORIZED, - other_error(format!("No user id found")).into(), + other_error("No user id found".to_string()).into(), )); }; Ok(user_id) @@ -108,7 +108,7 @@ impl NetworkApi { let Some(token) = result.get_token().await else { return Err(( StatusCode::UNAUTHORIZED, - other_error(format!("No token reported")).into(), + other_error("No token reported".to_string()).into(), )); }; @@ -120,7 +120,7 @@ impl NetworkApi { { return Err(( StatusCode::FORBIDDEN, - other_error(format!("Token mismatch")).into(), + other_error("Token mismatch".to_string()).into(), )); } @@ -177,7 +177,7 @@ impl NetworkApi { .insert_or_update_user_network_config( auth_session.user.as_ref().unwrap().id(), machine_id, - resp.inst_id.clone().unwrap_or_default().into(), + resp.inst_id.unwrap_or_default().into(), serde_json::to_string(&config).unwrap(), ) .await @@ -248,7 +248,7 @@ impl NetworkApi { .await .map_err(convert_rpc_error)?; - let running_inst_ids = ret.inst_ids.clone().into_iter().map(Into::into).collect(); + let running_inst_ids = ret.inst_ids.clone().into_iter().collect(); // collect networks that are disabled let disabled_inst_ids = client_mgr @@ -261,7 +261,7 @@ impl NetworkApi { .await .map_err(convert_db_error)? .iter() - .filter_map(|x| x.network_instance_id.clone().try_into().ok()) + .map(|x| Into::::into(x.network_instance_id.clone())) .collect::>(); Ok(ListNetworkInstanceIdsJsonResp { @@ -330,9 +330,8 @@ impl NetworkApi { // not implement disable all return Err(( StatusCode::NOT_IMPLEMENTED, - other_error(format!("Not implemented")).into(), - )) - .into(); + other_error("Not implemented".to_string()).into(), + )); }; let sess = Self::get_session_by_machine_id(&auth_session, &client_mgr, &machine_id).await?; diff --git a/easytier-web/src/restful/users.rs b/easytier-web/src/restful/users.rs index 1e879ae5..b489a145 100644 --- a/easytier-web/src/restful/users.rs +++ b/easytier-web/src/restful/users.rs @@ -76,32 +76,32 @@ impl Backend { pub async fn register_new_user(&self, new_user: &RegisterNewUser) -> anyhow::Result<()> { let hashed_password = password_auth::generate_hash(new_user.credentials.password.as_str()); - let mut txn = self.db.orm_db().begin().await?; + let txn = self.db.orm_db().begin().await?; entity::users::ActiveModel { username: Set(new_user.credentials.username.clone()), password: Set(hashed_password.clone()), ..Default::default() } - .save(&mut txn) + .save(&txn) .await?; entity::users_groups::ActiveModel { user_id: Set(entity::users::Entity::find() .filter(entity::users::Column::Username.eq(new_user.credentials.username.as_str())) - .one(&mut txn) + .one(&txn) .await? .unwrap() .id), group_id: Set(entity::groups::Entity::find() .filter(entity::groups::Column::Name.eq("users")) - .one(&mut txn) + .one(&txn) .await? .unwrap() .id), ..Default::default() } - .save(&mut txn) + .save(&txn) .await?; txn.commit().await?; diff --git a/easytier-web/src/web/mod.rs b/easytier-web/src/web/mod.rs index 7f0590d1..eabe307e 100644 --- a/easytier-web/src/web/mod.rs +++ b/easytier-web/src/web/mod.rs @@ -52,9 +52,7 @@ pub fn build_router(api_host: Option) -> Router { router }; - let router = router.fallback_service(service); - - router + router.fallback_service(service) } pub struct WebServer { diff --git a/easytier/Cargo.toml b/easytier/Cargo.toml index e3a5d8e1..8f53ee76 100644 --- a/easytier/Cargo.toml +++ b/easytier/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" authors = ["kkrainbow"] keywords = ["vpn", "p2p", "network", "easytier"] categories = ["network-programming", "command-line-utilities"] -rust-version = "1.87.0" +rust-version = "1.89.0" license-file = "LICENSE" readme = "README.md" diff --git a/easytier/build.rs b/easytier/build.rs index 1987c8f3..68273870 100644 --- a/easytier/build.rs +++ b/easytier/build.rs @@ -116,7 +116,7 @@ fn check_locale() { if let Ok(globs) = globwalk::glob(locale_path) { for entry in globs { if let Err(e) = entry { - println!("cargo:i18n-error={}", e); + println!("cargo:i18n-error={e}"); continue; } @@ -151,7 +151,7 @@ fn main() -> Result<(), Box> { ]; for proto_file in proto_files.iter().chain(proto_files_reflect.iter()) { - println!("cargo:rerun-if-changed={}", proto_file); + println!("cargo:rerun-if-changed={proto_file}"); } let mut config = prost_build::Config::new(); @@ -173,7 +173,7 @@ fn main() -> Result<(), Box> { .field_attribute(".web.NetworkConfig", "#[serde(default)]") .service_generator(Box::new(rpc_build::ServiceGenerator::new())) .btree_map(["."]) - .skip_debug(&[".common.Ipv4Addr", ".common.Ipv6Addr", ".common.UUID"]); + .skip_debug([".common.Ipv4Addr", ".common.Ipv6Addr", ".common.UUID"]); config.compile_protos(&proto_files, &["src/proto/"])?; diff --git a/easytier/src/common/acl_processor.rs b/easytier/src/common/acl_processor.rs index 60863073..6f979e3c 100644 --- a/easytier/src/common/acl_processor.rs +++ b/easytier/src/common/acl_processor.rs @@ -178,6 +178,12 @@ impl AclLogContext { } } +pub type SharedState = ( + Arc>, + Arc>>, + Arc>, +); + // High-performance ACL processor - No more internal locks! pub struct AclProcessor { // Immutable rule vectors - no locks needed since they're never modified after creation @@ -321,7 +327,7 @@ impl AclProcessor { .rules .iter() .filter(|rule| rule.enabled) - .map(|rule| Self::convert_to_fast_lookup_rule(rule)) + .map(Self::convert_to_fast_lookup_rule) .collect::>(); // Sort by priority (higher priority first) @@ -422,7 +428,7 @@ impl AclProcessor { self.inc_cache_entry_stats(cache_entry, packet_info); - return cache_entry.acl_result.clone().unwrap(); + cache_entry.acl_result.clone().unwrap() } fn inc_cache_entry_stats(&self, cache_entry: &AclCacheEntry, packet_info: &PacketInfo) { @@ -539,7 +545,7 @@ impl AclProcessor { cache_entry.rule_stats_vec.push(rule.rule_stats.clone()); cache_entry.matched_rule = RuleId::Priority(rule.priority); cache_entry.acl_result = Some(AclResult { - action: rule.action.clone(), + action: rule.action, matched_rule: Some(RuleId::Priority(rule.priority)), should_log: false, log_context: Some(AclLogContext::RuleMatch { @@ -595,13 +601,7 @@ impl AclProcessor { } /// Get shared state for preserving across hot reloads - pub fn get_shared_state( - &self, - ) -> ( - Arc>, - Arc>>, - Arc>, - ) { + pub fn get_shared_state(&self) -> SharedState { ( self.conn_track.clone(), self.rate_limiters.clone(), @@ -698,9 +698,9 @@ impl AclProcessor { } /// Check connection state for stateful rules - fn check_connection_state(&self, conn_track_key: &String, packet_info: &PacketInfo) { + fn check_connection_state(&self, conn_track_key: &str, packet_info: &PacketInfo) { self.conn_track - .entry(conn_track_key.clone()) + .entry(conn_track_key.to_string()) .and_modify(|x| { x.last_seen = SystemTime::now() .duration_since(UNIX_EPOCH) @@ -764,13 +764,13 @@ impl AclProcessor { let src_ip_ranges = rule .source_ips .iter() - .filter_map(|ip_inet| Self::convert_ip_inet_to_cidr(ip_inet)) + .filter_map(|x| Self::convert_ip_inet_to_cidr(x.as_str())) .collect(); let dst_ip_ranges = rule .destination_ips .iter() - .filter_map(|ip_inet| Self::convert_ip_inet_to_cidr(ip_inet)) + .filter_map(|x| Self::convert_ip_inet_to_cidr(x.as_str())) .collect(); let src_port_ranges = rule @@ -820,8 +820,8 @@ impl AclProcessor { } /// Convert IpInet to CIDR for fast lookup - fn convert_ip_inet_to_cidr(input: &String) -> Option { - cidr::IpCidr::from_str(input.as_str()).ok() + fn convert_ip_inet_to_cidr(input: &str) -> Option { + cidr::IpCidr::from_str(input).ok() } /// Increment statistics counter @@ -898,17 +898,13 @@ impl AclProcessor { } // 新增辅助函数 -fn parse_port_start( - port_strs: &::prost::alloc::vec::Vec<::prost::alloc::string::String>, -) -> Option { +fn parse_port_start(port_strs: &[String]) -> Option { port_strs .iter() .filter_map(|s| parse_port_range(s).map(|(start, _)| start)) .min() } -fn parse_port_end( - port_strs: &::prost::alloc::vec::Vec<::prost::alloc::string::String>, -) -> Option { +fn parse_port_end(port_strs: &[String]) -> Option { port_strs .iter() .filter_map(|s| parse_port_range(s).map(|(_, end)| end)) @@ -1154,18 +1150,22 @@ mod tests { let mut acl_v1 = AclV1::default(); // Create inbound chain - let mut chain = Chain::default(); - chain.name = "test_inbound".to_string(); - chain.chain_type = ChainType::Inbound as i32; - chain.enabled = true; + let mut chain = Chain { + name: "test_inbound".to_string(), + chain_type: ChainType::Inbound as i32, + enabled: true, + ..Default::default() + }; // Allow all rule - let mut rule = Rule::default(); - rule.name = "allow_all".to_string(); - rule.priority = 100; - rule.enabled = true; - rule.action = Action::Allow as i32; - rule.protocol = Protocol::Any as i32; + let rule = Rule { + name: "allow_all".to_string(), + priority: 100, + enabled: true, + action: Action::Allow as i32, + protocol: Protocol::Any as i32, + ..Default::default() + }; chain.rules.push(rule); acl_v1.chains.push(chain); @@ -1278,12 +1278,14 @@ mod tests { // 创建新配置(模拟热加载) let mut new_config = create_test_acl_config(); if let Some(ref mut acl_v1) = new_config.acl_v1 { - let mut drop_rule = Rule::default(); - drop_rule.name = "drop_all".to_string(); - drop_rule.priority = 200; - drop_rule.enabled = true; - drop_rule.action = Action::Drop as i32; - drop_rule.protocol = Protocol::Any as i32; + let drop_rule = Rule { + name: "drop_all".to_string(), + priority: 200, + enabled: true, + action: Action::Drop as i32, + protocol: Protocol::Any as i32, + ..Default::default() + }; acl_v1.chains[0].rules.push(drop_rule); } @@ -1321,40 +1323,48 @@ mod tests { let mut acl_config = Acl::default(); let mut acl_v1 = AclV1::default(); - let mut chain = Chain::default(); - chain.name = "performance_test".to_string(); - chain.chain_type = ChainType::Inbound as i32; - chain.enabled = true; + let mut chain = Chain { + name: "performance_test".to_string(), + chain_type: ChainType::Inbound as i32, + enabled: true, + ..Default::default() + }; // 1. High-priority simple rule for UDP (can be cached efficiently) - let mut simple_rule = Rule::default(); - simple_rule.name = "simple_udp".to_string(); - simple_rule.priority = 300; - simple_rule.enabled = true; - simple_rule.action = Action::Allow as i32; - simple_rule.protocol = Protocol::Udp as i32; + let simple_rule = Rule { + name: "simple_udp".to_string(), + priority: 300, + enabled: true, + action: Action::Allow as i32, + protocol: Protocol::Udp as i32, + ..Default::default() + }; // No stateful or rate limit - can benefit from full cache optimization chain.rules.push(simple_rule); // 2. Medium-priority stateful + rate-limited rule for TCP (security critical) - let mut security_rule = Rule::default(); - security_rule.name = "security_tcp".to_string(); - security_rule.priority = 200; - security_rule.enabled = true; - security_rule.action = Action::Allow as i32; - security_rule.protocol = Protocol::Tcp as i32; - security_rule.stateful = true; - security_rule.rate_limit = 100; // 100 packets/sec - security_rule.burst_limit = 200; + let security_rule = Rule { + name: "security_tcp".to_string(), + priority: 200, + enabled: true, + action: Action::Allow as i32, + protocol: Protocol::Tcp as i32, + stateful: true, + rate_limit: 100, + burst_limit: 200, + ..Default::default() + }; chain.rules.push(security_rule); // 3. Low-priority default allow rule for Any - let mut default_rule = Rule::default(); - default_rule.name = "default_allow".to_string(); - default_rule.priority = 100; - default_rule.enabled = true; - default_rule.action = Action::Allow as i32; - default_rule.protocol = Protocol::Any as i32; + let default_rule = Rule { + name: "default_allow".to_string(), + priority: 100, + enabled: true, + action: Action::Allow as i32, + protocol: Protocol::Any as i32, + ..Default::default() + }; chain.rules.push(default_rule); acl_v1.chains.push(chain); @@ -1441,15 +1451,16 @@ mod tests { // Create a very restrictive rate-limited rule if let Some(ref mut acl_v1) = acl_config.acl_v1 { - let mut rule = Rule::default(); - rule.name = "strict_rate_limit".to_string(); - rule.priority = 200; - rule.enabled = true; - rule.action = Action::Allow as i32; - rule.protocol = Protocol::Any as i32; - rule.rate_limit = 1; // Allow only 1 packet per second - rule.burst_limit = 1; // Burst of 1 packet - + let rule = Rule { + name: "strict_rate_limit".to_string(), + priority: 200, + enabled: true, + action: Action::Allow as i32, + protocol: Protocol::Any as i32, + rate_limit: 1, // Allow only 1 packet per second + burst_limit: 1, // Burst of 1 packet + ..Default::default() + }; acl_v1.chains[0].rules.push(rule); } diff --git a/easytier/src/common/compressor.rs b/easytier/src/common/compressor.rs index 7366378a..6e8d0143 100644 --- a/easytier/src/common/compressor.rs +++ b/easytier/src/common/compressor.rs @@ -21,6 +21,12 @@ pub trait Compressor { pub struct DefaultCompressor {} +impl Default for DefaultCompressor { + fn default() -> Self { + Self::new() + } +} + impl DefaultCompressor { pub fn new() -> Self { DefaultCompressor {} @@ -195,11 +201,11 @@ pub mod tests { packet, packet.payload_len() ); - assert_eq!(packet.peer_manager_header().unwrap().is_compressed(), true); + assert!(packet.peer_manager_header().unwrap().is_compressed()); compressor.decompress(&mut packet).await.unwrap(); assert_eq!(packet.payload(), text); - assert_eq!(packet.peer_manager_header().unwrap().is_compressed(), false); + assert!(!packet.peer_manager_header().unwrap().is_compressed()); } #[tokio::test] @@ -215,10 +221,10 @@ pub mod tests { .compress(&mut packet, CompressorAlgo::ZstdDefault) .await .unwrap(); - assert_eq!(packet.peer_manager_header().unwrap().is_compressed(), false); + assert!(!packet.peer_manager_header().unwrap().is_compressed()); compressor.decompress(&mut packet).await.unwrap(); assert_eq!(packet.payload(), text); - assert_eq!(packet.peer_manager_header().unwrap().is_compressed(), false); + assert!(!packet.peer_manager_header().unwrap().is_compressed()); } } diff --git a/easytier/src/common/config.rs b/easytier/src/common/config.rs index 780a11a6..bbd4b40f 100644 --- a/easytier/src/common/config.rs +++ b/easytier/src/common/config.rs @@ -1,8 +1,8 @@ use std::{ + hash::Hasher, net::{IpAddr, SocketAddr}, path::PathBuf, sync::{Arc, Mutex}, - u64, }; use anyhow::Context; @@ -48,7 +48,7 @@ pub fn gen_default_flags() -> Flags { disable_quic_input: false, foreign_relay_bps_limit: u64::MAX, multi_thread_count: 2, - encryption_algorithm: "".to_string(), // 空字符串表示使用默认的 AES-GCM + encryption_algorithm: "aes-gcm".to_string(), } } @@ -210,7 +210,7 @@ pub trait LoggingConfigLoader { pub type NetworkSecretDigest = [u8; 32]; -#[derive(Debug, Clone, Deserialize, Serialize, Default, Eq, Hash)] +#[derive(Debug, Clone, Deserialize, Serialize)] pub struct NetworkIdentity { pub network_name: String, pub network_secret: Option, @@ -218,27 +218,53 @@ pub struct NetworkIdentity { pub network_secret_digest: Option, } +#[derive(Eq, PartialEq, Hash)] +struct NetworkIdentityWithOnlyDigest { + network_name: String, + network_secret_digest: Option, +} + +impl From for NetworkIdentityWithOnlyDigest { + fn from(identity: NetworkIdentity) -> Self { + if identity.network_secret_digest.is_some() { + Self { + network_name: identity.network_name, + network_secret_digest: identity.network_secret_digest, + } + } else if identity.network_secret.is_some() { + let mut network_secret_digest = [0u8; 32]; + generate_digest_from_str( + &identity.network_name, + identity.network_secret.as_ref().unwrap(), + &mut network_secret_digest, + ); + Self { + network_name: identity.network_name, + network_secret_digest: Some(network_secret_digest), + } + } else { + Self { + network_name: identity.network_name, + network_secret_digest: None, + } + } + } +} + impl PartialEq for NetworkIdentity { fn eq(&self, other: &Self) -> bool { - if self.network_name != other.network_name { - return false; - } + let self_with_digest = NetworkIdentityWithOnlyDigest::from(self.clone()); + let other_with_digest = NetworkIdentityWithOnlyDigest::from(other.clone()); + self_with_digest == other_with_digest + } +} - if self.network_secret.is_some() - && other.network_secret.is_some() - && self.network_secret != other.network_secret - { - return false; - } +impl Eq for NetworkIdentity {} - if self.network_secret_digest.is_some() - && other.network_secret_digest.is_some() - && self.network_secret_digest != other.network_secret_digest - { - return false; - } - - return true; +impl std::hash::Hash for NetworkIdentity { + fn hash(&self, state: &mut H) { + let self_with_digest = NetworkIdentityWithOnlyDigest::from(self.clone()); + self_with_digest.hash(state); } } @@ -253,8 +279,10 @@ impl NetworkIdentity { network_secret_digest: Some(network_secret_digest), } } +} - pub fn default() -> Self { +impl Default for NetworkIdentity { + fn default() -> Self { Self::new("default".to_string(), "".to_string()) } } @@ -328,12 +356,12 @@ impl From for PortForwardConfig { } } -impl Into for PortForwardConfig { - fn into(self) -> PortForwardConfigPb { +impl From for PortForwardConfigPb { + fn from(val: PortForwardConfig) -> Self { PortForwardConfigPb { - bind_addr: Some(self.bind_addr.into()), - dst_addr: Some(self.dst_addr.into()), - socket_type: match self.proto.to_lowercase().as_str() { + bind_addr: Some(val.bind_addr.into()), + dst_addr: Some(val.dst_addr.into()), + socket_type: match val.proto.to_lowercase().as_str() { "tcp" => SocketType::Tcp as i32, "udp" => SocketType::Udp as i32, _ => SocketType::Tcp as i32, @@ -493,8 +521,7 @@ impl ConfigLoader for TomlConfigLoader { locked_config .ipv4 .as_ref() - .map(|s| s.parse().ok()) - .flatten() + .and_then(|s| s.parse().ok()) .map(|c: cidr::Ipv4Inet| { if c.network_length() == 32 { cidr::Ipv4Inet::new(c.address(), 24).unwrap() @@ -505,28 +532,16 @@ impl ConfigLoader for TomlConfigLoader { } fn set_ipv4(&self, addr: Option) { - self.config.lock().unwrap().ipv4 = if let Some(addr) = addr { - Some(addr.to_string()) - } else { - None - }; + self.config.lock().unwrap().ipv4 = addr.map(|addr| addr.to_string()); } fn get_ipv6(&self) -> Option { let locked_config = self.config.lock().unwrap(); - locked_config - .ipv6 - .as_ref() - .map(|s| s.parse().ok()) - .flatten() + locked_config.ipv6.as_ref().and_then(|s| s.parse().ok()) } fn set_ipv6(&self, addr: Option) { - self.config.lock().unwrap().ipv6 = if let Some(addr) = addr { - Some(addr.to_string()) - } else { - None - }; + self.config.lock().unwrap().ipv6 = addr.map(|addr| addr.to_string()); } fn get_dhcp(&self) -> bool { @@ -600,7 +615,7 @@ impl ConfigLoader for TomlConfigLoader { locked_config.instance_id = Some(id); id } else { - locked_config.instance_id.as_ref().unwrap().clone() + *locked_config.instance_id.as_ref().unwrap() } } @@ -614,7 +629,7 @@ impl ConfigLoader for TomlConfigLoader { .unwrap() .network_identity .clone() - .unwrap_or_else(NetworkIdentity::default) + .unwrap_or_default() } fn set_network_identity(&self, identity: NetworkIdentity) { diff --git a/easytier/src/common/constants.rs b/easytier/src/common/constants.rs index 7fb67ce9..3544b139 100644 --- a/easytier/src/common/constants.rs +++ b/easytier/src/common/constants.rs @@ -8,14 +8,14 @@ macro_rules! define_global_var { #[macro_export] macro_rules! use_global_var { ($name:ident) => { - crate::common::constants::$name.lock().unwrap().to_owned() + $crate::common::constants::$name.lock().unwrap().to_owned() }; } #[macro_export] macro_rules! set_global_var { ($name:ident, $val:expr) => { - *crate::common::constants::$name.lock().unwrap() = $val + *$crate::common::constants::$name.lock().unwrap() = $val }; } diff --git a/easytier/src/common/defer.rs b/easytier/src/common/defer.rs index 1132c9b7..c243d1ce 100644 --- a/easytier/src/common/defer.rs +++ b/easytier/src/common/defer.rs @@ -12,7 +12,9 @@ impl Defer { impl Drop for Defer { fn drop(&mut self) { - self.func.take().map(|f| f()); + if let Some(f) = self.func.take() { + f() + } } } diff --git a/easytier/src/common/dns.rs b/easytier/src/common/dns.rs index bf4990b1..9e638323 100644 --- a/easytier/src/common/dns.rs +++ b/easytier/src/common/dns.rs @@ -48,19 +48,15 @@ pub static RESOLVER: Lazy>>> pub async fn resolve_txt_record(domain_name: &str) -> Result { let r = RESOLVER.clone(); - let response = r.txt_lookup(domain_name).await.with_context(|| { - format!( - "txt_lookup failed, domain_name: {}", - domain_name.to_string() - ) - })?; + let response = r + .txt_lookup(domain_name) + .await + .with_context(|| format!("txt_lookup failed, domain_name: {}", domain_name))?; - let txt_record = response.iter().next().with_context(|| { - format!( - "no txt record found, domain_name: {}", - domain_name.to_string() - ) - })?; + let txt_record = response + .iter() + .next() + .with_context(|| format!("no txt record found, domain_name: {}", domain_name))?; let txt_data = String::from_utf8_lossy(&txt_record.txt_data()[0]); tracing::info!(?txt_data, ?domain_name, "get txt record"); diff --git a/easytier/src/common/global_ctx.rs b/easytier/src/common/global_ctx.rs index 8bd68400..2c5e2cb2 100644 --- a/easytier/src/common/global_ctx.rs +++ b/easytier/src/common/global_ctx.rs @@ -104,7 +104,7 @@ impl std::fmt::Debug for GlobalCtx { pub type ArcGlobalCtx = std::sync::Arc; impl GlobalCtx { - pub fn new(config_fs: impl ConfigLoader + 'static + Send + Sync) -> Self { + pub fn new(config_fs: impl ConfigLoader + 'static) -> Self { let id = config_fs.get_id(); let network = config_fs.get_network_identity(); let net_ns = NetNS::new(config_fs.get_netns()); @@ -118,9 +118,11 @@ impl GlobalCtx { let proxy_forward_by_system = config_fs.get_flags().proxy_forward_by_system; let no_tun = config_fs.get_flags().no_tun; - let mut feature_flags = PeerFeatureFlag::default(); - feature_flags.kcp_input = !config_fs.get_flags().disable_kcp_input; - feature_flags.no_relay_kcp = config_fs.get_flags().disable_relay_kcp; + let feature_flags = PeerFeatureFlag { + kcp_input: !config_fs.get_flags().disable_kcp_input, + no_relay_kcp: config_fs.get_flags().disable_relay_kcp, + ..Default::default() + }; GlobalCtx { inst_name: config_fs.get_inst_name(), @@ -185,7 +187,7 @@ impl GlobalCtx { { Ok(()) } else { - Err(anyhow::anyhow!("network {} not in whitelist", network_name).into()) + Err(anyhow::anyhow!("network {} not in whitelist", network_name)) } } @@ -194,8 +196,8 @@ impl GlobalCtx { return Some(ret); } let addr = self.config.get_ipv4(); - self.cached_ipv4.store(addr.clone()); - return addr; + self.cached_ipv4.store(addr); + addr } pub fn set_ipv4(&self, addr: Option) { @@ -208,8 +210,8 @@ impl GlobalCtx { return Some(ret); } let addr = self.config.get_ipv6(); - self.cached_ipv6.store(addr.clone()); - return addr; + self.cached_ipv6.store(addr); + addr } pub fn set_ipv6(&self, addr: Option) { @@ -376,18 +378,18 @@ pub mod tests { let mut subscriber = global_ctx.subscribe(); let peer_id = new_peer_id(); - global_ctx.issue_event(GlobalCtxEvent::PeerAdded(peer_id.clone())); - global_ctx.issue_event(GlobalCtxEvent::PeerRemoved(peer_id.clone())); + global_ctx.issue_event(GlobalCtxEvent::PeerAdded(peer_id)); + global_ctx.issue_event(GlobalCtxEvent::PeerRemoved(peer_id)); global_ctx.issue_event(GlobalCtxEvent::PeerConnAdded(PeerConnInfo::default())); global_ctx.issue_event(GlobalCtxEvent::PeerConnRemoved(PeerConnInfo::default())); assert_eq!( subscriber.recv().await.unwrap(), - GlobalCtxEvent::PeerAdded(peer_id.clone()) + GlobalCtxEvent::PeerAdded(peer_id) ); assert_eq!( subscriber.recv().await.unwrap(), - GlobalCtxEvent::PeerRemoved(peer_id.clone()) + GlobalCtxEvent::PeerRemoved(peer_id) ); assert_eq!( subscriber.recv().await.unwrap(), @@ -404,7 +406,7 @@ pub mod tests { ) -> ArcGlobalCtx { let config_fs = TomlConfigLoader::default(); config_fs.set_inst_name(format!("test_{}", config_fs.get_id())); - config_fs.set_network_identity(network_identy.unwrap_or(NetworkIdentity::default())); + config_fs.set_network_identity(network_identy.unwrap_or_default()); let ctx = Arc::new(GlobalCtx::new(config_fs)); ctx.replace_stun_info_collector(Box::new(MockStunInfoCollector { diff --git a/easytier/src/common/ifcfg/mod.rs b/easytier/src/common/ifcfg/mod.rs index 37bc3645..f5bd223a 100644 --- a/easytier/src/common/ifcfg/mod.rs +++ b/easytier/src/common/ifcfg/mod.rs @@ -1,6 +1,6 @@ #[cfg(any(target_os = "macos", target_os = "freebsd"))] mod darwin; -#[cfg(any(target_os = "linux"))] +#[cfg(target_os = "linux")] mod netlink; #[cfg(target_os = "windows")] mod win; @@ -141,7 +141,7 @@ pub struct DummyIfConfiger {} #[async_trait] impl IfConfiguerTrait for DummyIfConfiger {} -#[cfg(any(target_os = "linux"))] +#[cfg(target_os = "linux")] pub type IfConfiger = netlink::NetlinkIfConfiger; #[cfg(any(target_os = "macos", target_os = "freebsd"))] diff --git a/easytier/src/common/ifcfg/netlink.rs b/easytier/src/common/ifcfg/netlink.rs index 4af72341..f51b83e1 100644 --- a/easytier/src/common/ifcfg/netlink.rs +++ b/easytier/src/common/ifcfg/netlink.rs @@ -85,14 +85,14 @@ fn send_netlink_req_and_wait_one_resp { if e.code == NonZero::new(0) { - return Ok(()); + Ok(()) } else { - return Err(e.to_io().into()); + Err(e.to_io().into()) } } p => { tracing::error!("Unexpected netlink response: {:?}", p); - return Err(anyhow::anyhow!("Unexpected netlink response").into()); + Err(anyhow::anyhow!("Unexpected netlink response").into()) } } } @@ -263,8 +263,8 @@ impl NetlinkIfConfiger { let (address, netmask) = match (address.family(), netmask.family()) { (Some(Inet), Some(Inet)) => ( - IpAddr::V4(address.as_sockaddr_in().unwrap().ip().into()), - IpAddr::V4(netmask.as_sockaddr_in().unwrap().ip().into()), + IpAddr::V4(address.as_sockaddr_in().unwrap().ip()), + IpAddr::V4(netmask.as_sockaddr_in().unwrap().ip()), ), (Some(Inet6), Some(Inet6)) => ( IpAddr::V6(address.as_sockaddr_in6().unwrap().ip()), @@ -333,7 +333,7 @@ impl NetlinkIfConfiger { let mut resp = Vec::::new(); loop { - if resp.len() == 0 { + if resp.is_empty() { let (new_resp, _) = s.recv_from_full()?; resp = new_resp; } diff --git a/easytier/src/common/ifcfg/win/luid.rs b/easytier/src/common/ifcfg/win/luid.rs index 0e0c2e71..29af75c9 100644 --- a/easytier/src/common/ifcfg/win/luid.rs +++ b/easytier/src/common/ifcfg/win/luid.rs @@ -727,7 +727,7 @@ impl InterfaceLuid { if family == (AF_INET6 as ADDRESS_FAMILY) { // ipv6 mtu must be at least 1280 mtu = 1280.max(mtu); - } + } // https://stackoverflow.com/questions/54857292/setipinterfaceentry-returns-error-invalid-parameter row.SitePrefixLength = 0; diff --git a/easytier/src/common/ifcfg/win/mod.rs b/easytier/src/common/ifcfg/win/mod.rs index 6e140a5f..5c850f46 100644 --- a/easytier/src/common/ifcfg/win/mod.rs +++ b/easytier/src/common/ifcfg/win/mod.rs @@ -1,3 +1,3 @@ +pub mod luid; pub mod netsh; pub mod types; -pub mod luid; \ No newline at end of file diff --git a/easytier/src/common/ifcfg/win/netsh.rs b/easytier/src/common/ifcfg/win/netsh.rs index dcf368c9..267d404f 100644 --- a/easytier/src/common/ifcfg/win/netsh.rs +++ b/easytier/src/common/ifcfg/win/netsh.rs @@ -115,4 +115,4 @@ pub fn add_dns_ipv6(if_index: u32, dnses: &[Ipv6Addr]) -> Result<(), String> { } let dnses_str: Vec = dnses.iter().map(|addr| addr.to_string()).collect(); add_dns(AF_INET6 as _, if_index, &dnses_str) -} \ No newline at end of file +} diff --git a/easytier/src/common/ifcfg/win/types.rs b/easytier/src/common/ifcfg/win/types.rs index c0d90e6a..ee030c40 100644 --- a/easytier/src/common/ifcfg/win/types.rs +++ b/easytier/src/common/ifcfg/win/types.rs @@ -100,4 +100,4 @@ pub fn u16_ptr_to_string(ptr: *const u16) -> String { let slice = unsafe { std::slice::from_raw_parts(ptr, len) }; String::from_utf16_lossy(slice) -} \ No newline at end of file +} diff --git a/easytier/src/common/mod.rs b/easytier/src/common/mod.rs index 2178c96a..7d2572c7 100644 --- a/easytier/src/common/mod.rs +++ b/easytier/src/common/mod.rs @@ -140,8 +140,8 @@ pub fn get_machine_id() -> uuid::Uuid { )))] let gen_mid = None; - if gen_mid.is_some() { - return gen_mid.unwrap(); + if let Some(mid) = gen_mid { + return mid; } let gen_mid = uuid::Uuid::new_v4(); diff --git a/easytier/src/common/netns.rs b/easytier/src/common/netns.rs index 4f6ba3e1..27f5289f 100644 --- a/easytier/src/common/netns.rs +++ b/easytier/src/common/netns.rs @@ -34,13 +34,12 @@ impl NetNSGuard { return; } - let ns_path: String; let name = name.unwrap(); - if name == ROOT_NETNS_NAME { - ns_path = "/proc/1/ns/net".to_string(); + let ns_path: String = if name == ROOT_NETNS_NAME { + "/proc/1/ns/net".to_string() } else { - ns_path = format!("/var/run/netns/{}", name); - } + format!("/var/run/netns/{}", name) + }; let ns = std::fs::File::open(ns_path).unwrap(); tracing::info!( diff --git a/easytier/src/common/network.rs b/easytier/src/common/network.rs index e4d72f66..73dd97c6 100644 --- a/easytier/src/common/network.rs +++ b/easytier/src/common/network.rs @@ -211,7 +211,7 @@ impl IPCollector { cached_ip_list.read().await.public_ipv6 ); - let sleep_sec = if !cached_ip_list.read().await.public_ipv4.is_none() { + let sleep_sec = if cached_ip_list.read().await.public_ipv4.is_some() { CACHED_IP_LIST_TIMEOUT_SEC } else { 3 @@ -252,14 +252,11 @@ impl IPCollector { for iface in ifaces { for ip in iface.ips { let ip: std::net::IpAddr = ip.ip(); - match ip { - std::net::IpAddr::V4(v4) => { - if ip.is_loopback() || ip.is_multicast() { - continue; - } - ret.interface_ipv4s.push(v4.into()); + if let std::net::IpAddr::V4(v4) = ip { + if ip.is_loopback() || ip.is_multicast() { + continue; } - _ => {} + ret.interface_ipv4s.push(v4.into()); } } } @@ -269,14 +266,11 @@ impl IPCollector { for iface in ifaces { for ip in iface.ips { let ip: std::net::IpAddr = ip.ip(); - match ip { - std::net::IpAddr::V6(v6) => { - if v6.is_multicast() || v6.is_loopback() || v6.is_unicast_link_local() { - continue; - } - ret.interface_ipv6s.push(v6.into()); + if let std::net::IpAddr::V6(v6) = ip { + if v6.is_multicast() || v6.is_loopback() || v6.is_unicast_link_local() { + continue; } - _ => {} + ret.interface_ipv6s.push(v6.into()); } } } diff --git a/easytier/src/common/stats_manager.rs b/easytier/src/common/stats_manager.rs index fa20cf6e..43290132 100644 --- a/easytier/src/common/stats_manager.rs +++ b/easytier/src/common/stats_manager.rs @@ -277,6 +277,12 @@ pub struct UnsafeCounter { value: UnsafeCell, } +impl Default for UnsafeCounter { + fn default() -> Self { + Self::new() + } +} + impl UnsafeCounter { pub fn new() -> Self { Self { @@ -396,14 +402,15 @@ impl MetricKey { fn new(name: MetricName, labels: LabelSet) -> Self { Self { name, labels } } +} - /// Generate a string representation for this metric key - fn to_string(&self) -> String { +impl fmt::Display for MetricKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let label_str = self.labels.to_key(); if label_str.is_empty() { - self.name.to_string() + f.write_str(self.name.to_string().as_str()) } else { - format!("{}[{}]", self.name, label_str) + f.write_str(format!("{}[{}]", self.name, label_str).as_str()) } } } diff --git a/easytier/src/common/stun.rs b/easytier/src/common/stun.rs index f390c540..e9763b54 100644 --- a/easytier/src/common/stun.rs +++ b/easytier/src/common/stun.rs @@ -282,9 +282,7 @@ impl StunClient { .with_context(|| "encode stun message")?; tids.push(tid); tracing::trace!(?message, ?msg, tid, "send stun request"); - self.socket - .send_to(msg.as_slice().into(), &stun_host) - .await?; + self.socket.send_to(msg.as_slice(), &stun_host).await?; } let now = Instant::now(); @@ -372,7 +370,7 @@ impl StunClientBuilder { pub async fn stop(&mut self) { self.task_set.abort_all(); - while let Some(_) = self.task_set.join_next().await {} + while self.task_set.join_next().await.is_some() {} } } @@ -417,7 +415,7 @@ impl UdpNatTypeDetectResult { return true; } } - return false; + false } fn is_pat(&self) -> bool { @@ -457,16 +455,16 @@ impl UdpNatTypeDetectResult { if self.is_cone() { if self.has_ip_changed_resp() { if self.is_open_internet() { - return NatType::OpenInternet; + NatType::OpenInternet } else if self.is_pat() { - return NatType::NoPat; + NatType::NoPat } else { - return NatType::FullCone; + NatType::FullCone } } else if self.has_port_changed_resp() { - return NatType::Restricted; + NatType::Restricted } else { - return NatType::PortRestricted; + NatType::PortRestricted } } else if !self.stun_resps.is_empty() { if self.public_ips().len() != 1 @@ -480,7 +478,7 @@ impl UdpNatTypeDetectResult { .mapped_socket_addr .is_none() { - return NatType::Symmetric; + NatType::Symmetric } else { let extra_bind_test = self.extra_bind_test.as_ref().unwrap(); let extra_port = extra_bind_test.mapped_socket_addr.unwrap().port(); @@ -488,15 +486,15 @@ impl UdpNatTypeDetectResult { let max_port_diff = extra_port.saturating_sub(self.max_port()); let min_port_diff = self.min_port().saturating_sub(extra_port); if max_port_diff != 0 && max_port_diff < 100 { - return NatType::SymmetricEasyInc; + NatType::SymmetricEasyInc } else if min_port_diff != 0 && min_port_diff < 100 { - return NatType::SymmetricEasyDec; + NatType::SymmetricEasyDec } else { - return NatType::Symmetric; + NatType::Symmetric } } } else { - return NatType::Unknown; + NatType::Unknown } } @@ -679,7 +677,7 @@ impl StunInfoCollectorTrait for StunInfoCollector { .unwrap() .clone() .map(|x| x.collect_available_stun_server()) - .unwrap_or(vec![]); + .unwrap_or_default(); if stun_servers.is_empty() { let mut host_resolver = @@ -740,7 +738,7 @@ impl StunInfoCollector { pub fn get_default_servers() -> Vec { // NOTICE: we may need to choose stun stun server based on geo location // stun server cross nation may return a external ip address with high latency and loss rate - vec![ + [ "txt:stun.easytier.cn", "stun.miwifi.com", "stun.chat.bilibili.com", @@ -752,16 +750,16 @@ impl StunInfoCollector { } pub fn get_default_servers_v6() -> Vec { - vec!["txt:stun-v6.easytier.cn"] + ["txt:stun-v6.easytier.cn"] .iter() .map(|x| x.to_string()) .collect() } - async fn get_public_ipv6(servers: &Vec) -> Option { + async fn get_public_ipv6(servers: &[String]) -> Option { let mut ips = HostResolverIter::new(servers.to_vec(), 10, true); while let Some(ip) = ips.next().await { - let Ok(udp_socket) = UdpSocket::bind(format!("[::]:0")).await else { + let Ok(udp_socket) = UdpSocket::bind("[::]:0".to_string()).await else { break; }; let udp = Arc::new(udp_socket); @@ -770,11 +768,8 @@ impl StunInfoCollector { .bind_request(false, false) .await; tracing::debug!(?ret, "finish ipv6 udp nat type detect"); - match ret.map(|x| x.mapped_socket_addr.map(|x| x.ip())) { - Ok(Some(IpAddr::V6(v6))) => { - return Some(v6); - } - _ => {} + if let Ok(Some(IpAddr::V6(v6))) = ret.map(|x| x.mapped_socket_addr.map(|x| x.ip())) { + return Some(v6); } } None @@ -854,9 +849,9 @@ impl StunInfoCollector { self.tasks.lock().unwrap().spawn(async move { loop { let servers = stun_servers.read().unwrap().clone(); - Self::get_public_ipv6(&servers) - .await - .map(|x| stored_ipv6.store(Some(x))); + if let Some(x) = Self::get_public_ipv6(&servers).await { + stored_ipv6.store(Some(x)) + } let sleep_sec = if stored_ipv6.load().is_none() { 60 diff --git a/easytier/src/common/token_bucket.rs b/easytier/src/common/token_bucket.rs index ebbcf898..b3b2f503 100644 --- a/easytier/src/common/token_bucket.rs +++ b/easytier/src/common/token_bucket.rs @@ -34,7 +34,7 @@ impl From for BucketConfig { .unwrap_or(Duration::from_millis(10)); BucketConfig { capacity: burst_rate * fill_rate, - fill_rate: fill_rate, + fill_rate, refill_interval, } } @@ -162,6 +162,12 @@ pub struct TokenBucketManager { retain_task: ScopedTask<()>, } +impl Default for TokenBucketManager { + fn default() -> Self { + Self::new() + } +} + impl TokenBucketManager { /// Creates a new TokenBucketManager pub fn new() -> Self { @@ -318,7 +324,7 @@ mod tests { // Should have accumulated about 100 tokens (10,000 tokens/s * 0.001s) let tokens = bucket.available_tokens.load(Ordering::Relaxed); assert!( - tokens >= 100 && tokens <= 200, + (100..=200).contains(&tokens), "Unexpected token count: {}", tokens ); @@ -355,8 +361,7 @@ mod tests { .list_foreign_networks() .await .foreign_networks - .len() - == 0 + .is_empty() }, Duration::from_secs(5), ) @@ -370,8 +375,7 @@ mod tests { .get_global_ctx() .token_bucket_manager() .buckets - .len() - == 0 + .is_empty() }, Duration::from_secs(10), ) diff --git a/easytier/src/connector/direct.rs b/easytier/src/connector/direct.rs index 72c0c560..2a6ffb57 100644 --- a/easytier/src/connector/direct.rs +++ b/easytier/src/connector/direct.rs @@ -180,16 +180,13 @@ impl DirectConnectorManagerData { // ask remote to send v6 hole punch packet // and no matter what the result is, continue to connect let _ = self - .remote_send_v6_hole_punch_packet(dst_peer_id, &local_socket, &remote_url) + .remote_send_v6_hole_punch_packet(dst_peer_id, &local_socket, remote_url) .await; let udp_connector = UdpTunnelConnector::new(remote_url.clone()); - let remote_addr = super::check_scheme_and_get_socket_addr::( - &remote_url, - "udp", - IpVersion::V6, - ) - .await?; + let remote_addr = + super::check_scheme_and_get_socket_addr::(remote_url, "udp", IpVersion::V6) + .await?; let ret = udp_connector .try_connect_with_socket(local_socket, remote_addr) .await?; @@ -233,8 +230,8 @@ impl DirectConnectorManagerData { dst_peer_id: PeerId, addr: String, ) -> Result<(), Error> { - let mut rand_gen = rand::rngs::OsRng::default(); - let backoff_ms = vec![1000, 2000, 4000]; + let mut rand_gen = rand::rngs::OsRng; + let backoff_ms = [1000, 2000, 4000]; let mut backoff_idx = 0; tracing::debug!(?dst_peer_id, ?addr, "try_connect_to_ip start"); @@ -243,10 +240,7 @@ impl DirectConnectorManagerData { if self .dst_listener_blacklist - .contains(&DstListenerUrlBlackListItem( - dst_peer_id.clone(), - addr.clone(), - )) + .contains(&DstListenerUrlBlackListItem(dst_peer_id, addr.clone())) { return Err(Error::UrlInBlacklist); } @@ -281,7 +275,7 @@ impl DirectConnectorManagerData { continue; } else { self.dst_listener_blacklist.insert( - DstListenerUrlBlackListItem(dst_peer_id.clone(), addr), + DstListenerUrlBlackListItem(dst_peer_id, addr), (), std::time::Duration::from_secs(DIRECT_CONNECTOR_BLACKLIST_TIMEOUT_SEC), ); @@ -315,7 +309,7 @@ impl DirectConnectorManagerData { if addr.set_host(Some(ip.to_string().as_str())).is_ok() { tasks.spawn(Self::try_connect_to_ip( self.clone(), - dst_peer_id.clone(), + dst_peer_id, addr.to_string(), )); } else { @@ -330,7 +324,7 @@ impl DirectConnectorManagerData { } else if !s_addr.ip().is_loopback() || TESTING.load(Ordering::Relaxed) { tasks.spawn(Self::try_connect_to_ip( self.clone(), - dst_peer_id.clone(), + dst_peer_id, listener.to_string(), )); } @@ -355,13 +349,10 @@ impl DirectConnectorManagerData { .iter() .for_each(|ip| { let mut addr = (*listener).clone(); - if addr - .set_host(Some(format!("[{}]", ip.to_string()).as_str())) - .is_ok() - { + if addr.set_host(Some(format!("[{}]", ip).as_str())).is_ok() { tasks.spawn(Self::try_connect_to_ip( self.clone(), - dst_peer_id.clone(), + dst_peer_id, addr.to_string(), )); } else { @@ -376,7 +367,7 @@ impl DirectConnectorManagerData { } else if !s_addr.ip().is_loopback() || TESTING.load(Ordering::Relaxed) { tasks.spawn(Self::try_connect_to_ip( self.clone(), - dst_peer_id.clone(), + dst_peer_id, listener.to_string(), )); } @@ -436,13 +427,8 @@ impl DirectConnectorManagerData { } tracing::debug!("try direct connect to peer with listener: {}", listener); - self.spawn_direct_connect_task( - dst_peer_id.clone(), - &ip_list, - &listener, - &mut tasks, - ) - .await; + self.spawn_direct_connect_task(dst_peer_id, &ip_list, listener, &mut tasks) + .await; listener_list.push(listener.clone().to_string()); available_listeners.pop(); diff --git a/easytier/src/connector/dns_connector.rs b/easytier/src/connector/dns_connector.rs index bcc0d539..9a87576a 100644 --- a/easytier/src/connector/dns_connector.rs +++ b/easytier/src/connector/dns_connector.rs @@ -124,11 +124,11 @@ impl DNSTunnelConnector { let responses = responses.clone(); async move { let response = resolver.srv_lookup(srv_domain).await.with_context(|| { - format!("srv_lookup failed, srv_domain: {}", srv_domain.to_string()) + format!("srv_lookup failed, srv_domain: {}", srv_domain) })?; tracing::info!(?response, ?srv_domain, "srv_lookup response"); for record in response.iter() { - let parsed_record = Self::handle_one_srv_record(record, &protocol); + let parsed_record = Self::handle_one_srv_record(record, protocol); tracing::info!(?parsed_record, ?srv_domain, "parsed_record"); if parsed_record.is_err() { eprintln!( @@ -153,8 +153,7 @@ impl DNSTunnelConnector { let url = weighted_choice(srv_records.as_slice()).with_context(|| { format!( "failed to choose a srv record, domain_name: {}, srv_records: {:?}", - domain_name.to_string(), - srv_records + domain_name, srv_records ) })?; diff --git a/easytier/src/connector/http_connector.rs b/easytier/src/connector/http_connector.rs index acba6bd7..daefebbf 100644 --- a/easytier/src/connector/http_connector.rs +++ b/easytier/src/connector/http_connector.rs @@ -93,7 +93,7 @@ impl HttpTunnelConnector { tracing::info!("try to create connector by url: {}", query[0]); self.redirect_type = HttpRedirectType::RedirectToQuery; return create_connector_by_url( - &query[0].to_string(), + query[0].as_ref(), &self.global_ctx, self.ip_version, ) @@ -193,7 +193,7 @@ impl HttpTunnelConnector { .ok_or_else(|| Error::InvalidUrl("no redirect address found".to_string()))?; let new_url = url::Url::parse(redirect_url.as_str()) .with_context(|| format!("parsing redirect url failed. url: {}", redirect_url))?; - return self.handle_302_redirect(new_url, &redirect_url).await; + return self.handle_302_redirect(new_url, redirect_url).await; } else if res.status_code().is_success() { return self.handle_200_success(&body).await; } else { diff --git a/easytier/src/connector/manual.rs b/easytier/src/connector/manual.rs index fc04d54e..81bb7b98 100644 --- a/easytier/src/connector/manual.rs +++ b/easytier/src/connector/manual.rs @@ -131,7 +131,7 @@ impl ManualConnectorManager { .data .connectors .iter() - .map(|x| x.key().clone().into()) + .map(|x| x.key().clone()) .collect(); let dead_urls: BTreeSet = Self::collect_dead_conns(self.data.clone()) @@ -155,12 +155,8 @@ impl ManualConnectorManager { ); } - let reconnecting_urls: BTreeSet = self - .data - .reconnecting - .iter() - .map(|x| x.clone().into()) - .collect(); + let reconnecting_urls: BTreeSet = + self.data.reconnecting.iter().map(|x| x.clone()).collect(); for conn_url in reconnecting_urls { ret.insert( @@ -282,7 +278,7 @@ impl ManualConnectorManager { let remove_later = DashSet::new(); for it in data.removed_conn_urls.iter() { let url = it.key(); - if let Some(_) = data.connectors.remove(url) { + if data.connectors.remove(url).is_some() { tracing::warn!("connector: {}, removed", url); continue; } else if data.reconnecting.contains(url) { @@ -301,11 +297,7 @@ impl ManualConnectorManager { async fn collect_dead_conns(data: Arc) -> BTreeSet { Self::handle_remove_connector(data.clone()); - let all_urls: BTreeSet = data - .connectors - .iter() - .map(|x| x.key().clone().into()) - .collect(); + let all_urls: BTreeSet = data.connectors.iter().map(|x| x.key().clone()).collect(); let mut ret = BTreeSet::new(); for url in all_urls.iter() { if !data.alive_conn_urls.contains(url) { @@ -400,21 +392,28 @@ impl ManualConnectorManager { .await; tracing::info!("reconnect: {} done, ret: {:?}", dead_url, ret); - if ret.is_ok() && ret.as_ref().unwrap().is_ok() { - reconn_ret = ret.unwrap(); - break; - } else { - if ret.is_err() { - reconn_ret = Err(ret.unwrap_err().into()); - } else if ret.as_ref().unwrap().is_err() { - reconn_ret = Err(ret.unwrap().unwrap_err()); + match ret { + Ok(Ok(_)) => { + // 外层和内层都成功:解包并跳出 + reconn_ret = ret.unwrap(); + break; + } + Ok(Err(e)) => { + // 外层成功,内层失败 + reconn_ret = Err(e); + } + Err(e) => { + // 外层失败 + reconn_ret = Err(e.into()); } - data.global_ctx.issue_event(GlobalCtxEvent::ConnectError( - dead_url.clone(), - format!("{:?}", ip_version), - format!("{:?}", reconn_ret), - )); } + + // 发送事件(只有在未 break 时才执行) + data.global_ctx.issue_event(GlobalCtxEvent::ConnectError( + dead_url.clone(), + format!("{:?}", ip_version), + format!("{:?}", reconn_ret), + )); } reconn_ret diff --git a/easytier/src/connector/udp_hole_punch/both_easy_sym.rs b/easytier/src/connector/udp_hole_punch/both_easy_sym.rs index d58c6ea5..6db6c0d3 100644 --- a/easytier/src/connector/udp_hole_punch/both_easy_sym.rs +++ b/easytier/src/connector/udp_hole_punch/both_easy_sym.rs @@ -389,7 +389,7 @@ pub mod tests { let udp1 = Arc::new(UdpSocket::bind("0.0.0.0:40164").await.unwrap()); // 144 - DST_PORT_OFFSET = 124 let udp2 = Arc::new(UdpSocket::bind("0.0.0.0:40124").await.unwrap()); - let udps = vec![udp1, udp2]; + let udps = [udp1, udp2]; let counter = Arc::new(AtomicU32::new(0)); diff --git a/easytier/src/connector/udp_hole_punch/common.rs b/easytier/src/connector/udp_hole_punch/common.rs index 2840223f..975a9fee 100644 --- a/easytier/src/connector/udp_hole_punch/common.rs +++ b/easytier/src/connector/udp_hole_punch/common.rs @@ -67,9 +67,9 @@ impl From for UdpNatType { } } -impl Into for UdpNatType { - fn into(self) -> NatType { - match self { +impl From for NatType { + fn from(val: UdpNatType) -> Self { + match val { UdpNatType::Unknown => NatType::Unknown, UdpNatType::Open(nat_type) => nat_type, UdpNatType::Cone(nat_type) => nat_type, @@ -249,7 +249,7 @@ impl UdpSocketArray { tracing::info!(?addr, ?tid, "got hole punching packet with intreast tid"); tid_to_socket .entry(tid) - .or_insert_with(Vec::new) + .or_default() .push(PunchedUdpSocket { socket: socket.clone(), tid, @@ -556,7 +556,7 @@ impl PunchHoleServerCommon { #[tracing::instrument(err, ret(level=Level::DEBUG), skip(ports))] pub(crate) async fn send_symmetric_hole_punch_packet( - ports: &Vec, + ports: &[u16], udp: Arc, transaction_id: u32, public_ips: &Vec, @@ -628,5 +628,5 @@ pub(crate) async fn try_connect_with_socket( connector .try_connect_with_socket(socket, remote_mapped_addr) .await - .map_err(|e| Error::from(e)) + .map_err(Error::from) } diff --git a/easytier/src/connector/udp_hole_punch/cone.rs b/easytier/src/connector/udp_hole_punch/cone.rs index d7fa1853..d28948a3 100644 --- a/easytier/src/connector/udp_hole_punch/cone.rs +++ b/easytier/src/connector/udp_hole_punch/cone.rs @@ -172,7 +172,7 @@ impl PunchConeHoleClient { udp_array .send_with_all( &new_hole_punch_packet(tid, HOLE_PUNCH_PACKET_BODY_LEN).into_bytes(), - remote_mapped_addr.clone().into(), + remote_mapped_addr.into(), ) .await .with_context(|| "failed to send hole punch packet from local") @@ -188,7 +188,7 @@ impl PunchConeHoleClient { ..Default::default() }, SendPunchPacketConeRequest { - listener_mapped_addr: Some(remote_mapped_addr.into()), + listener_mapped_addr: Some(remote_mapped_addr), dest_addr: Some(local_mapped_addr.into()), transaction_id: tid, packet_count_per_batch: 2, diff --git a/easytier/src/connector/udp_hole_punch/mod.rs b/easytier/src/connector/udp_hole_punch/mod.rs index ab87da28..d9fc36cf 100644 --- a/easytier/src/connector/udp_hole_punch/mod.rs +++ b/easytier/src/connector/udp_hole_punch/mod.rs @@ -39,7 +39,7 @@ pub(crate) mod cone; pub(crate) mod sym_to_cone; // sym punch should be serialized -static SYM_PUNCH_LOCK: Lazy>>> = Lazy::new(|| DashMap::new()); +static SYM_PUNCH_LOCK: Lazy>>> = Lazy::new(DashMap::new); pub static RUN_TESTING: Lazy = Lazy::new(|| AtomicBool::new(false)); // Blacklist timeout in seconds @@ -223,7 +223,7 @@ impl UdpHoePunchConnectorData { #[tracing::instrument(skip(self))] async fn handle_punch_result( - self: &Self, + &self, ret: Result>, Error>, backoff: Option<&mut BackOff>, round: Option<&mut u32>, @@ -236,10 +236,8 @@ impl UdpHoePunchConnectorData { if let Some(round) = round { *round = round.saturating_sub(1); } - } else { - if let Some(round) = round { - *round += 1; - } + } else if let Some(round) = round { + *round += 1; } }; @@ -464,7 +462,7 @@ impl PeerTaskLauncher for UdpHolePunchPeerTaskLauncher { } let conns = data.peer_mgr.list_peer_conns(peer_id).await; - if conns.is_some() && conns.unwrap().len() > 0 { + if conns.is_some() && !conns.unwrap().is_empty() { continue; } diff --git a/easytier/src/connector/udp_hole_punch/sym_to_cone.rs b/easytier/src/connector/udp_hole_punch/sym_to_cone.rs index df90a449..21c51da8 100644 --- a/easytier/src/connector/udp_hole_punch/sym_to_cone.rs +++ b/easytier/src/connector/udp_hole_punch/sym_to_cone.rs @@ -80,9 +80,9 @@ impl PunchSymToConeHoleServer { let public_ips = request .public_ips .into_iter() - .map(|ip| std::net::Ipv4Addr::from(ip)) + .map(std::net::Ipv4Addr::from) .collect::>(); - if public_ips.len() == 0 { + if public_ips.is_empty() { tracing::warn!("send_punch_packet_easy_sym got zero len public ip"); return Err( anyhow::anyhow!("send_punch_packet_easy_sym got zero len public ip").into(), @@ -158,9 +158,9 @@ impl PunchSymToConeHoleServer { let public_ips = request .public_ips .into_iter() - .map(|ip| std::net::Ipv4Addr::from(ip)) + .map(std::net::Ipv4Addr::from) .collect::>(); - if public_ips.len() == 0 { + if public_ips.is_empty() { tracing::warn!("try_punch_symmetric got zero len public ip"); return Err(anyhow::anyhow!("try_punch_symmetric got zero len public ip").into()); } @@ -281,7 +281,7 @@ impl PunchSymToConeHoleClient { return; }; let req = SendPunchPacketEasySymRequest { - listener_mapped_addr: remote_mapped_addr.clone().into(), + listener_mapped_addr: remote_mapped_addr.into(), public_ips: public_ips.clone().into_iter().map(|x| x.into()).collect(), transaction_id: tid, base_port_num: base_port_for_easy_sym.unwrap() as u32, @@ -313,7 +313,7 @@ impl PunchSymToConeHoleClient { port_index: u32, ) -> Option { let req = SendPunchPacketHardSymRequest { - listener_mapped_addr: remote_mapped_addr.clone().into(), + listener_mapped_addr: remote_mapped_addr.into(), public_ips: public_ips.clone().into_iter().map(|x| x.into()).collect(), transaction_id: tid, round, @@ -333,9 +333,9 @@ impl PunchSymToConeHoleClient { { Err(e) => { tracing::error!(?e, "failed to send punch packet for hard sym"); - return None; + None } - Ok(resp) => return Some(resp.next_port_index), + Ok(resp) => Some(resp.next_port_index), } } @@ -366,7 +366,7 @@ impl PunchSymToConeHoleClient { let mut finish_time: Option = None; while finish_time.is_none() || finish_time.as_ref().unwrap().elapsed().as_millis() < 1000 { udp_array - .send_with_all(&packet, remote_mapped_addr.into()) + .send_with_all(packet, remote_mapped_addr.into()) .await?; tokio::time::sleep(Duration::from_millis(200)).await; @@ -484,7 +484,7 @@ impl PunchSymToConeHoleClient { rpc_stub, base_port_for_easy_sym, my_nat_info, - remote_mapped_addr.clone(), + remote_mapped_addr, public_ips.clone(), tid, )) @@ -494,7 +494,7 @@ impl PunchSymToConeHoleClient { &udp_array, &packet, tid, - remote_mapped_addr.clone(), + remote_mapped_addr, &scoped_punch_task, ) .await?; @@ -510,7 +510,7 @@ impl PunchSymToConeHoleClient { let scoped_punch_task: ScopedTask> = tokio::spawn(Self::remote_send_hole_punch_packet_random( rpc_stub, - remote_mapped_addr.clone(), + remote_mapped_addr, public_ips.clone(), tid, round, @@ -522,7 +522,7 @@ impl PunchSymToConeHoleClient { &udp_array, &packet, tid, - remote_mapped_addr.clone(), + remote_mapped_addr, &scoped_punch_task, ) .await?; diff --git a/easytier/src/easytier-cli.rs b/easytier/src/easytier-cli.rs index 02470d39..286d8a68 100644 --- a/easytier/src/easytier-cli.rs +++ b/easytier/src/easytier-cli.rs @@ -4,7 +4,6 @@ use std::{ net::{IpAddr, SocketAddr}, path::PathBuf, str::FromStr, - sync::Mutex, time::Duration, vec, }; @@ -30,15 +29,16 @@ use easytier::{ cli::{ list_peer_route_pair, AclManageRpc, AclManageRpcClientFactory, AddPortForwardRequest, ConnectorManageRpc, ConnectorManageRpcClientFactory, DumpRouteRequest, - GetAclStatsRequest, GetPrometheusStatsRequest, GetStatsRequest, GetVpnPortalInfoRequest, GetWhitelistRequest, ListConnectorRequest, + GetAclStatsRequest, GetPrometheusStatsRequest, GetStatsRequest, + GetVpnPortalInfoRequest, GetWhitelistRequest, ListConnectorRequest, ListForeignNetworkRequest, ListGlobalForeignNetworkRequest, ListMappedListenerRequest, ListPeerRequest, ListPeerResponse, ListPortForwardRequest, ListRouteRequest, ListRouteResponse, ManageMappedListenerRequest, MappedListenerManageAction, MappedListenerManageRpc, MappedListenerManageRpcClientFactory, NodeInfo, PeerManageRpc, PeerManageRpcClientFactory, PortForwardManageRpc, PortForwardManageRpcClientFactory, - RemovePortForwardRequest, SetWhitelistRequest, ShowNodeInfoRequest, StatsRpc, StatsRpcClientFactory, TcpProxyEntryState, - TcpProxyEntryTransportType, TcpProxyRpc, TcpProxyRpcClientFactory, VpnPortalRpc, - VpnPortalRpcClientFactory, + RemovePortForwardRequest, SetWhitelistRequest, ShowNodeInfoRequest, StatsRpc, + StatsRpcClientFactory, TcpProxyEntryState, TcpProxyEntryTransportType, TcpProxyRpc, + TcpProxyRpcClientFactory, VpnPortalRpc, VpnPortalRpcClientFactory, }, common::{NatType, SocketType}, peer_rpc::{GetGlobalPeerMapRequest, PeerCenterRpc, PeerCenterRpcClientFactory}, @@ -325,7 +325,7 @@ struct InstallArgs { type Error = anyhow::Error; struct CommandHandler<'a> { - client: Mutex, + client: tokio::sync::Mutex, verbose: bool, output_format: &'a OutputFormat, } @@ -339,7 +339,7 @@ impl CommandHandler<'_> { Ok(self .client .lock() - .unwrap() + .await .scoped_client::>("".to_string()) .await .with_context(|| "failed to get peer manager client")?) @@ -351,7 +351,7 @@ impl CommandHandler<'_> { Ok(self .client .lock() - .unwrap() + .await .scoped_client::>("".to_string()) .await .with_context(|| "failed to get connector manager client")?) @@ -363,7 +363,7 @@ impl CommandHandler<'_> { Ok(self .client .lock() - .unwrap() + .await .scoped_client::>("".to_string()) .await .with_context(|| "failed to get mapped listener manager client")?) @@ -375,7 +375,7 @@ impl CommandHandler<'_> { Ok(self .client .lock() - .unwrap() + .await .scoped_client::>("".to_string()) .await .with_context(|| "failed to get peer center client")?) @@ -387,7 +387,7 @@ impl CommandHandler<'_> { Ok(self .client .lock() - .unwrap() + .await .scoped_client::>("".to_string()) .await .with_context(|| "failed to get vpn portal client")?) @@ -399,7 +399,7 @@ impl CommandHandler<'_> { Ok(self .client .lock() - .unwrap() + .await .scoped_client::>("".to_string()) .await .with_context(|| "failed to get acl manager client")?) @@ -412,7 +412,7 @@ impl CommandHandler<'_> { Ok(self .client .lock() - .unwrap() + .await .scoped_client::>(transport_type.to_string()) .await .with_context(|| "failed to get vpn portal client")?) @@ -424,7 +424,7 @@ impl CommandHandler<'_> { Ok(self .client .lock() - .unwrap() + .await .scoped_client::>("".to_string()) .await .with_context(|| "failed to get port forward manager client")?) @@ -436,7 +436,7 @@ impl CommandHandler<'_> { Ok(self .client .lock() - .unwrap() + .await .scoped_client::>("".to_string()) .await .with_context(|| "failed to get stats client")?) @@ -865,7 +865,7 @@ impl CommandHandler<'_> { Ok(()) } - async fn handle_mapped_listener_add(&self, url: &String) -> Result<(), Error> { + async fn handle_mapped_listener_add(&self, url: &str) -> Result<(), Error> { let url = Self::mapped_listener_validate_url(url)?; let client = self.get_mapped_listener_manager_client().await?; let request = ManageMappedListenerRequest { @@ -878,7 +878,7 @@ impl CommandHandler<'_> { Ok(()) } - async fn handle_mapped_listener_remove(&self, url: &String) -> Result<(), Error> { + async fn handle_mapped_listener_remove(&self, url: &str) -> Result<(), Error> { let url = Self::mapped_listener_validate_url(url)?; let client = self.get_mapped_listener_manager_client().await?; let request = ManageMappedListenerRequest { @@ -891,7 +891,7 @@ impl CommandHandler<'_> { Ok(()) } - fn mapped_listener_validate_url(url: &String) -> Result { + fn mapped_listener_validate_url(url: &str) -> Result { let url = url::Url::parse(url)?; if url.scheme() != "tcp" && url.scheme() != "udp" { return Err(anyhow::anyhow!( @@ -925,8 +925,8 @@ impl CommandHandler<'_> { cfg: Some( PortForwardConfig { proto: protocol.to_string(), - bind_addr: bind_addr.into(), - dst_addr: dst_addr.into(), + bind_addr, + dst_addr, } .into(), ), @@ -961,11 +961,10 @@ impl CommandHandler<'_> { cfg: Some( PortForwardConfig { proto: protocol.to_string(), - bind_addr: bind_addr.into(), + bind_addr, dst_addr: dst_addr .map(|s| s.parse::().unwrap()) - .map(Into::into) - .unwrap_or("0.0.0.0:0".parse::().unwrap().into()), + .unwrap_or("0.0.0.0:0".parse::().unwrap()), } .into(), ), @@ -1458,7 +1457,7 @@ async fn main() -> Result<(), Error> { .unwrap(), )); let handler = CommandHandler { - client: Mutex::new(client), + client: tokio::sync::Mutex::new(client), verbose: cli.verbose, output_format: &cli.output_format, }; @@ -1716,16 +1715,10 @@ async fn main() -> Result<(), Error> { format!("{:?}", stun_info.udp_nat_type()).as_str(), ]); ip_list.interface_ipv4s.iter().for_each(|ip| { - builder.push_record(vec![ - "Interface IPv4", - format!("{}", ip.to_string()).as_str(), - ]); + builder.push_record(vec!["Interface IPv4", ip.to_string().as_str()]); }); ip_list.interface_ipv6s.iter().for_each(|ip| { - builder.push_record(vec![ - "Interface IPv6", - format!("{}", ip.to_string()).as_str(), - ]); + builder.push_record(vec!["Interface IPv6", ip.to_string().as_str()]); }); for (idx, l) in node_info.listeners.iter().enumerate() { if l.starts_with("ring") { @@ -1911,9 +1904,7 @@ async fn main() -> Result<(), Error> { Some(StatsSubCommand::Show) | None => { let client = handler.get_stats_client().await?; let request = GetStatsRequest {}; - let response = client - .get_stats(BaseController::default(), request) - .await?; + let response = client.get_stats(BaseController::default(), request).await?; if cli.output_format == OutputFormat::Json { println!("{}", serde_json::to_string_pretty(&response.metrics)?); @@ -1942,7 +1933,7 @@ async fn main() -> Result<(), Error> { .collect::>() .join(", ") }; - + let formatted_value = if metric.name.contains("bytes") { format_size(metric.value, humansize::BINARY) } else if metric.name.contains("duration") { diff --git a/easytier/src/easytier-core.rs b/easytier/src/easytier-core.rs index 3507a268..3b4f982c 100644 --- a/easytier/src/easytier-core.rs +++ b/easytier/src/easytier-core.rs @@ -61,7 +61,7 @@ pub static malloc_conf: &[u8] = b"prof:true,prof_active:true,lg_prof_sample:19\0 fn set_prof_active(_active: bool) { #[cfg(feature = "jemalloc-prof")] { - const PROF_ACTIVE: &'static [u8] = b"prof.active\0"; + const PROF_ACTIVE: &[u8] = b"prof.active\0"; let name = PROF_ACTIVE.name(); name.write(_active).expect("Should succeed to set prof"); } @@ -70,7 +70,7 @@ fn set_prof_active(_active: bool) { fn dump_profile(_cur_allocated: usize) { #[cfg(feature = "jemalloc-prof")] { - const PROF_DUMP: &'static [u8] = b"prof.dump\0"; + const PROF_DUMP: &[u8] = b"prof.dump\0"; static mut PROF_DUMP_FILE_NAME: [u8; 128] = [0; 128]; let file_name_str = format!( "profile-{}-{}.out", @@ -701,7 +701,7 @@ impl NetworkOptions { .map(|s| s.parse().unwrap()) .collect(), ); - } else if cfg.get_listeners() == None { + } else if cfg.get_listeners().is_none() { cfg.set_listeners( Cli::parse_listeners(false, vec!["11010".to_string()])? .into_iter() @@ -740,7 +740,7 @@ impl NetworkOptions { } for n in self.proxy_networks.iter() { - add_proxy_network_to_config(n, &cfg)?; + add_proxy_network_to_config(n, cfg)?; } let rpc_portal = if let Some(r) = &self.rpc_portal { @@ -754,9 +754,9 @@ impl NetworkOptions { cfg.set_rpc_portal(rpc_portal); if let Some(rpc_portal_whitelist) = &self.rpc_portal_whitelist { - let mut whitelist = cfg.get_rpc_portal_whitelist().unwrap_or_else(|| Vec::new()); + let mut whitelist = cfg.get_rpc_portal_whitelist().unwrap_or_default(); for cidr in rpc_portal_whitelist { - whitelist.push((*cidr).clone()); + whitelist.push(*cidr); } cfg.set_rpc_portal_whitelist(Some(whitelist)); } @@ -825,18 +825,18 @@ impl NetworkOptions { port_forward.port().expect("local bind port is missing") ) .parse() - .expect(format!("failed to parse local bind addr {}", example_str).as_str()); + .unwrap_or_else(|_| panic!("failed to parse local bind addr {}", example_str)); - let dst_addr = format!( - "{}", - port_forward - .path_segments() - .expect(format!("remote destination addr is missing {}", example_str).as_str()) - .next() - .expect(format!("remote destination addr is missing {}", example_str).as_str()) - ) - .parse() - .expect(format!("failed to parse remote destination addr {}", example_str).as_str()); + let dst_addr = port_forward + .path_segments() + .unwrap_or_else(|| panic!("remote destination addr is missing {}", example_str)) + .next() + .unwrap_or_else(|| panic!("remote destination addr is missing {}", example_str)) + .to_string() + .parse() + .unwrap_or_else(|_| { + panic!("failed to parse remote destination addr {}", example_str) + }); let port_forward_item = PortForwardConfig { bind_addr, @@ -1141,7 +1141,7 @@ async fn run_main(cli: Cli) -> anyhow::Result<()> { let mut cfg = TomlConfigLoader::default(); cli.network_options .merge_into(&mut cfg) - .with_context(|| format!("failed to create config from cli"))?; + .with_context(|| "failed to create config from cli".to_string())?; println!("Starting easytier from cli with config:"); println!("############### TOML ###############\n"); println!("{}", cfg.dump()); @@ -1156,7 +1156,7 @@ async fn run_main(cli: Cli) -> anyhow::Result<()> { .into_values() .filter_map(|info| info.error_msg) .collect::>(); - if errs.len() > 0 { + if !errs.is_empty() { return Err(anyhow::anyhow!("some instances stopped with errors")); } } diff --git a/easytier/src/gateway/fast_socks5/mod.rs b/easytier/src/gateway/fast_socks5/mod.rs index 133c94ca..73e32e87 100644 --- a/easytier/src/gateway/fast_socks5/mod.rs +++ b/easytier/src/gateway/fast_socks5/mod.rs @@ -294,7 +294,7 @@ pub fn new_udp_header(target_addr: T) -> Result> { } /// Parse data from UDP client on raw buffer, return (frag, target_addr, payload). -pub async fn parse_udp_request<'a>(mut req: &'a [u8]) -> Result<(u8, TargetAddr, &'a [u8])> { +pub async fn parse_udp_request(mut req: &[u8]) -> Result<(u8, TargetAddr, &[u8])> { let rsv = read_exact!(req, [0u8; 2]).context("Malformed request")?; if !rsv.eq(&[0u8; 2]) { diff --git a/easytier/src/gateway/fast_socks5/server.rs b/easytier/src/gateway/fast_socks5/server.rs index 44b72821..82e7d52d 100644 --- a/easytier/src/gateway/fast_socks5/server.rs +++ b/easytier/src/gateway/fast_socks5/server.rs @@ -455,16 +455,16 @@ impl info!("User logged successfully."); - return Ok(credentials); + Ok(credentials) } else { self.inner .write_all(&[1, consts::SOCKS5_AUTH_METHOD_NOT_ACCEPTABLE]) .await .context("Can't reply with auth method not acceptable.")?; - return Err(SocksError::AuthenticationRejected(format!( - "Authentication, rejected." - ))); + Err(SocksError::AuthenticationRejected( + "Authentication, rejected.".to_string(), + )) } } diff --git a/easytier/src/gateway/fast_socks5/util/target_addr.rs b/easytier/src/gateway/fast_socks5/util/target_addr.rs index fa2dbbf2..9700764a 100644 --- a/easytier/src/gateway/fast_socks5/util/target_addr.rs +++ b/easytier/src/gateway/fast_socks5/util/target_addr.rs @@ -72,10 +72,7 @@ impl TargetAddr { } pub fn is_ip(&self) -> bool { - match self { - TargetAddr::Ip(_) => true, - _ => false, - } + matches!(self, TargetAddr::Ip(_)) } pub fn is_domain(&self) -> bool { @@ -104,7 +101,7 @@ impl TargetAddr { } TargetAddr::Domain(ref domain, port) => { debug!("TargetAddr::Domain"); - if domain.len() > u8::max_value() as usize { + if domain.len() > u8::MAX as usize { return Err(SocksError::ExceededMaxDomainLen(domain.len()).into()); } buf.extend_from_slice(&[consts::SOCKS5_ADDR_TYPE_DOMAIN_NAME, domain.len() as u8]); @@ -125,8 +122,7 @@ impl std::net::ToSocketAddrs for TargetAddr { fn to_socket_addrs(&self) -> io::Result> { match *self { TargetAddr::Ip(addr) => Ok(vec![addr].into_iter()), - TargetAddr::Domain(_, _) => Err(io::Error::new( - io::ErrorKind::Other, + TargetAddr::Domain(_, _) => Err(io::Error::other( "Domain name has to be explicitly resolved, please use TargetAddr::resolve_dns().", )), } @@ -149,7 +145,7 @@ pub trait ToTargetAddr { fn to_target_addr(&self) -> io::Result; } -impl<'a> ToTargetAddr for (&'a str, u16) { +impl ToTargetAddr for (&str, u16) { fn to_target_addr(&self) -> io::Result { // try to parse as an IP first if let Ok(addr) = self.0.parse::() { diff --git a/easytier/src/gateway/icmp_proxy.rs b/easytier/src/gateway/icmp_proxy.rs index efde1de3..fc1f3dbc 100644 --- a/easytier/src/gateway/icmp_proxy.rs +++ b/easytier/src/gateway/icmp_proxy.rs @@ -23,6 +23,7 @@ use tracing::Instrument; use crate::{ common::{error::Error, global_ctx::ArcGlobalCtx, PeerId}, + gateway::ip_reassembler::ComposeIpv4PacketArgs, peers::{peer_manager::PeerManager, PeerPacketFilter}, tunnel::packet_def::{PacketType, ZCPacket}, }; @@ -118,7 +119,7 @@ fn socket_recv_loop( } }; - if len <= 0 { + if len == 0 { tracing::error!("recv empty packet, len: {}", len); return; } @@ -158,20 +159,18 @@ fn socket_recv_loop( let payload_len = len - ipv4_packet.get_header_length() as usize * 4; let id = ipv4_packet.get_identification(); let _ = compose_ipv4_packet( - &mut buf[..], - &v.mapped_dst_ip, - &dest_ip, - IpNextHeaderProtocols::Icmp, - payload_len, - 1200, - id, + ComposeIpv4PacketArgs { + buf: &mut buf[..], + src_v4: &v.mapped_dst_ip, + dst_v4: &dest_ip, + next_protocol: IpNextHeaderProtocols::Icmp, + payload_len, + payload_mtu: 1200, + ip_id: id, + }, |buf| { let mut p = ZCPacket::new_with_payload(buf); - p.fill_peer_manager_hdr( - v.my_peer_id.into(), - v.src_peer_id.into(), - PacketType::Data as u8, - ); + p.fill_peer_manager_hdr(v.my_peer_id, v.src_peer_id, PacketType::Data as u8); p.mut_peer_manager_header().unwrap().set_no_proxy(true); if let Err(e) = sender.send(p) { @@ -186,7 +185,7 @@ fn socket_recv_loop( #[async_trait::async_trait] impl PeerPacketFilter for IcmpProxy { async fn try_process_packet_from_peer(&self, packet: ZCPacket) -> Option { - if let Some(_) = self.try_handle_peer_packet(&packet).await { + if self.try_handle_peer_packet(&packet).await.is_some() { return None; } else { return Some(packet); @@ -320,10 +319,7 @@ impl IcmpProxy { .unwrap() .as_ref() .with_context(|| "icmp socket not created")? - .send_to( - icmp_packet.packet(), - &SocketAddrV4::new(dst_ip.into(), 0).into(), - )?; + .send_to(icmp_packet.packet(), &SocketAddrV4::new(dst_ip, 0).into())?; Ok(()) } @@ -349,13 +345,15 @@ impl IcmpProxy { let len = buf.len() - 20; let _ = compose_ipv4_packet( - &mut buf[..], - src_ip, - dst_ip, - IpNextHeaderProtocols::Icmp, - len, - 1200, - rand::random(), + ComposeIpv4PacketArgs { + buf: &mut buf[..], + src_v4: src_ip, + dst_v4: dst_ip, + next_protocol: IpNextHeaderProtocols::Icmp, + payload_len: len, + payload_mtu: 1200, + ip_id: rand::random(), + }, |buf| { let mut packet = ZCPacket::new_with_payload(buf); packet.fill_peer_manager_hdr(src_peer_id, dst_peer_id, PacketType::Data as u8); @@ -387,7 +385,7 @@ impl IcmpProxy { return None; }; - let ipv4 = Ipv4Packet::new(&packet.payload())?; + let ipv4 = Ipv4Packet::new(packet.payload())?; if ipv4.get_version() != 4 || ipv4.get_next_level_protocol() != IpNextHeaderProtocols::Icmp { @@ -396,17 +394,17 @@ impl IcmpProxy { let mut real_dst_ip = ipv4.get_destination(); - if !self + if !(self .cidr_set .contains_v4(ipv4.get_destination(), &mut real_dst_ip) - && !is_exit_node - && !(self.global_ctx.no_tun() + || is_exit_node + || (self.global_ctx.no_tun() && Some(ipv4.get_destination()) == self .global_ctx .get_ipv4() .as_ref() - .map(cidr::Ipv4Inet::address)) + .map(cidr::Ipv4Inet::address))) { return None; } @@ -416,12 +414,10 @@ impl IcmpProxy { resembled_buf = self.ip_resemmbler .add_fragment(ipv4.get_source(), ipv4.get_destination(), &ipv4); - if resembled_buf.is_none() { - return None; - }; + resembled_buf.as_ref()?; icmp::echo_request::EchoRequestPacket::new(resembled_buf.as_ref().unwrap())? } else { - icmp::echo_request::EchoRequestPacket::new(&ipv4.payload())? + icmp::echo_request::EchoRequestPacket::new(ipv4.payload())? }; if icmp_packet.get_icmp_type() != IcmpTypes::EchoRequest { @@ -484,10 +480,9 @@ impl Drop for IcmpProxy { "dropping icmp proxy, {:?}", self.socket.lock().unwrap().as_ref() ); - self.socket.lock().unwrap().as_ref().and_then(|s| { + if let Some(s) = self.socket.lock().unwrap().as_ref() { tracing::info!("shutting down icmp socket"); let _ = s.shutdown(std::net::Shutdown::Both); - Some(()) - }); + } } } diff --git a/easytier/src/gateway/ip_reassembler.rs b/easytier/src/gateway/ip_reassembler.rs index e05dc4e4..66f4b95a 100644 --- a/easytier/src/gateway/ip_reassembler.rs +++ b/easytier/src/gateway/ip_reassembler.rs @@ -190,33 +190,36 @@ impl IpReassembler { } } +pub struct ComposeIpv4PacketArgs<'a> { + pub buf: &'a mut [u8], + pub src_v4: &'a Ipv4Addr, + pub dst_v4: &'a Ipv4Addr, + pub next_protocol: IpNextHeaderProtocol, + pub payload_len: usize, + pub payload_mtu: usize, + pub ip_id: u16, +} + // ip payload should be in buf[20..] -pub fn compose_ipv4_packet( - buf: &mut [u8], - src_v4: &Ipv4Addr, - dst_v4: &Ipv4Addr, - next_protocol: IpNextHeaderProtocol, - payload_len: usize, - payload_mtu: usize, - ip_id: u16, - cb: F, -) -> Result<(), Error> +pub fn compose_ipv4_packet(args: ComposeIpv4PacketArgs, cb: F) -> Result<(), Error> where F: Fn(&[u8]) -> Result<(), Error>, { - let total_pieces = (payload_len + payload_mtu - 1) / payload_mtu; + let total_pieces = args.payload_len.div_ceil(args.payload_mtu); let mut buf_offset = 0; let mut fragment_offset = 0; let mut cur_piece = 0; - while fragment_offset < payload_len { - let next_fragment_offset = std::cmp::min(fragment_offset + payload_mtu, payload_len); + while fragment_offset < args.payload_len { + let next_fragment_offset = + std::cmp::min(fragment_offset + args.payload_mtu, args.payload_len); let fragment_len = next_fragment_offset - fragment_offset; let mut ipv4_packet = - MutableIpv4Packet::new(&mut buf[buf_offset..buf_offset + fragment_len + 20]).unwrap(); + MutableIpv4Packet::new(&mut args.buf[buf_offset..buf_offset + fragment_len + 20]) + .unwrap(); ipv4_packet.set_version(4); ipv4_packet.set_header_length(5); ipv4_packet.set_total_length((fragment_len + 20) as u16); - ipv4_packet.set_identification(ip_id); + ipv4_packet.set_identification(args.ip_id); if total_pieces > 1 { if cur_piece != total_pieces - 1 { ipv4_packet.set_flags(Ipv4Flags::MoreFragments); @@ -232,9 +235,9 @@ where ipv4_packet.set_ecn(0); ipv4_packet.set_dscp(0); ipv4_packet.set_ttl(32); - ipv4_packet.set_source(src_v4.clone()); - ipv4_packet.set_destination(dst_v4.clone()); - ipv4_packet.set_next_level_protocol(next_protocol); + ipv4_packet.set_source(*args.src_v4); + ipv4_packet.set_destination(*args.dst_v4); + ipv4_packet.set_next_level_protocol(args.next_protocol); ipv4_packet.set_checksum(ipv4::checksum(&ipv4_packet.to_immutable())); tracing::trace!(?ipv4_packet, "udp nat packet response send"); @@ -254,7 +257,7 @@ mod tests { #[test] fn resembler() { - let raw_packets = vec![ + let raw_packets = [ // last packet vec![ 0x45, 0x00, 0x00, 0x1c, 0x1c, 0x46, 0x20, 0x01, 0x40, 0x06, 0xb1, 0xe6, 0xc0, 0xa8, @@ -282,7 +285,7 @@ mod tests { let resembler = IpReassembler::new(Duration::from_secs(1)); for (idx, raw_packet) in raw_packets.iter().enumerate() { - if let Some(packet) = Ipv4Packet::new(&raw_packet) { + if let Some(packet) = Ipv4Packet::new(raw_packet) { let ret = resembler.add_fragment(source, destination, &packet); if idx != 2 { assert!(ret.is_none()); diff --git a/easytier/src/gateway/kcp_proxy.rs b/easytier/src/gateway/kcp_proxy.rs index 0dced50e..2c348563 100644 --- a/easytier/src/gateway/kcp_proxy.rs +++ b/easytier/src/gateway/kcp_proxy.rs @@ -70,7 +70,9 @@ impl PeerPacketFilter for KcpEndpointFilter { async fn try_process_packet_from_peer(&self, packet: ZCPacket) -> Option { let t = packet.peer_manager_header().unwrap().packet_type; if t == PacketType::KcpSrc as u8 && !self.is_src { + // src packet, but we are dst } else if t == PacketType::KcpDst as u8 && self.is_src { + // dst packet, but we are src } else { return Some(packet); } @@ -103,7 +105,7 @@ async fn handle_kcp_output( PacketType::KcpDst as u8 }; let mut packet = ZCPacket::new_with_payload(&packet.inner().freeze()); - packet.fill_peer_manager_hdr(peer_mgr.my_peer_id(), dst_peer_id, packet_type as u8); + packet.fill_peer_manager_hdr(peer_mgr.my_peer_id(), dst_peer_id, packet_type); if let Err(e) = peer_mgr.send_msg(packet, dst_peer_id).await { tracing::error!("failed to send kcp packet to peer: {:?}", e); @@ -171,7 +173,7 @@ impl NatDstConnector for NatDstKcpConnector { let kcp_endpoint = self.kcp_endpoint.clone(); let my_peer_id = peer_mgr.my_peer_id(); - let conn_data_clone = conn_data.clone(); + let conn_data_clone = conn_data; connect_tasks.spawn(async move { kcp_endpoint @@ -182,9 +184,7 @@ impl NatDstConnector for NatDstKcpConnector { Bytes::from(conn_data_clone.encode_to_vec()), ) .await - .with_context(|| { - format!("failed to connect to nat dst: {}", nat_dst.to_string()) - }) + .with_context(|| format!("failed to connect to nat dst: {}", nat_dst)) }); } @@ -203,7 +203,7 @@ impl NatDstConnector for NatDstKcpConnector { _ipv4: &Ipv4Packet, _real_dst_ip: &mut Ipv4Addr, ) -> bool { - return hdr.from_peer_id == hdr.to_peer_id && hdr.is_kcp_src_modified(); + hdr.from_peer_id == hdr.to_peer_id && hdr.is_kcp_src_modified() } fn transport_type(&self) -> TcpProxyEntryTransportType { @@ -230,7 +230,10 @@ impl TcpProxyForKcpSrcTrait for TcpProxyForKcpSrc { } async fn check_dst_allow_kcp_input(&self, dst_ip: &Ipv4Addr) -> bool { - self.0.get_peer_manager().check_allow_kcp_to_dst(&IpAddr::V4(*dst_ip)).await + self.0 + .get_peer_manager() + .check_allow_kcp_to_dst(&IpAddr::V4(*dst_ip)) + .await } } @@ -456,14 +459,11 @@ impl KcpProxyDst { .into(); let src_socket: SocketAddr = parsed_conn_data.src.unwrap_or_default().into(); - match dst_socket.ip() { - IpAddr::V4(dst_v4_ip) => { - let mut real_ip = dst_v4_ip; - if cidr_set.contains_v4(dst_v4_ip, &mut real_ip) { - dst_socket.set_ip(real_ip.into()); - } + if let IpAddr::V4(dst_v4_ip) = dst_socket.ip() { + let mut real_ip = dst_v4_ip; + if cidr_set.contains_v4(dst_v4_ip, &mut real_ip) { + dst_socket.set_ip(real_ip.into()); } - _ => {} }; let conn_id = kcp_stream.conn_id(); @@ -578,7 +578,7 @@ impl TcpProxyRpc for KcpProxyDstRpcService { let mut reply = ListTcpProxyEntryResponse::default(); if let Some(tcp_proxy) = self.0.upgrade() { for item in tcp_proxy.iter() { - reply.entries.push(item.value().clone()); + reply.entries.push(*item.value()); } } Ok(reply) diff --git a/easytier/src/gateway/mod.rs b/easytier/src/gateway/mod.rs index c8d8af9e..596dee69 100644 --- a/easytier/src/gateway/mod.rs +++ b/easytier/src/gateway/mod.rs @@ -56,11 +56,11 @@ impl CidrSet { cidr_set.lock().unwrap().clear(); for cidr in cidrs.iter() { let real_cidr = cidr.cidr; - let mapped = cidr.mapped_cidr.unwrap_or(real_cidr.clone()); - cidr_set.lock().unwrap().push(mapped.clone()); + let mapped = cidr.mapped_cidr.unwrap_or(real_cidr); + cidr_set.lock().unwrap().push(mapped); if mapped != real_cidr { - mapped_to_real.insert(mapped.clone(), real_cidr.clone()); + mapped_to_real.insert(mapped, real_cidr); } } } @@ -70,11 +70,11 @@ impl CidrSet { } pub fn contains_v4(&self, ipv4: std::net::Ipv4Addr, real_ip: &mut std::net::Ipv4Addr) -> bool { - let ip = ipv4.into(); + let ip = ipv4; let s = self.cidr_set.lock().unwrap(); for cidr in s.iter() { if cidr.contains(&ip) { - if let Some(real_cidr) = self.mapped_to_real.get(&cidr).map(|v| v.value().clone()) { + if let Some(real_cidr) = self.mapped_to_real.get(cidr).map(|v| *v.value()) { let origin_network_bits = real_cidr.first().address().to_bits(); let network_mask = cidr.mask().to_bits(); diff --git a/easytier/src/gateway/quic_proxy.rs b/easytier/src/gateway/quic_proxy.rs index e291b7ee..d2aa6325 100644 --- a/easytier/src/gateway/quic_proxy.rs +++ b/easytier/src/gateway/quic_proxy.rs @@ -172,7 +172,7 @@ impl NatDstConnector for NatDstQUICConnector { _ipv4: &Ipv4Packet, _real_dst_ip: &mut Ipv4Addr, ) -> bool { - return hdr.from_peer_id == hdr.to_peer_id && !hdr.is_kcp_src_modified(); + hdr.from_peer_id == hdr.to_peer_id && !hdr.is_kcp_src_modified() } fn transport_type(&self) -> TcpProxyEntryTransportType { @@ -457,7 +457,7 @@ impl TcpProxyRpc for QUICProxyDstRpcService { let mut reply = ListTcpProxyEntryResponse::default(); if let Some(tcp_proxy) = self.0.upgrade() { for item in tcp_proxy.iter() { - reply.entries.push(item.value().clone()); + reply.entries.push(*item.value()); } } Ok(reply) diff --git a/easytier/src/gateway/socks5.rs b/easytier/src/gateway/socks5.rs index 7e298621..84b2cdb5 100644 --- a/easytier/src/gateway/socks5.rs +++ b/easytier/src/gateway/socks5.rs @@ -72,9 +72,9 @@ impl SocksUdpSocket { } enum SocksTcpStream { - TcpStream(tokio::net::TcpStream), - SmolTcpStream(super::tokio_smoltcp::TcpStream), - KcpStream(KcpStream), + Tcp(tokio::net::TcpStream), + SmolTcp(super::tokio_smoltcp::TcpStream), + Kcp(KcpStream), } impl AsyncRead for SocksTcpStream { @@ -84,15 +84,11 @@ impl AsyncRead for SocksTcpStream { buf: &mut tokio::io::ReadBuf<'_>, ) -> std::task::Poll> { match self.get_mut() { - SocksTcpStream::TcpStream(ref mut stream) => { - std::pin::Pin::new(stream).poll_read(cx, buf) - } - SocksTcpStream::SmolTcpStream(ref mut stream) => { - std::pin::Pin::new(stream).poll_read(cx, buf) - } - SocksTcpStream::KcpStream(ref mut stream) => { + SocksTcpStream::Tcp(ref mut stream) => std::pin::Pin::new(stream).poll_read(cx, buf), + SocksTcpStream::SmolTcp(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), } } } @@ -104,15 +100,11 @@ impl AsyncWrite for SocksTcpStream { buf: &[u8], ) -> std::task::Poll> { match self.get_mut() { - SocksTcpStream::TcpStream(ref mut stream) => { - std::pin::Pin::new(stream).poll_write(cx, buf) - } - SocksTcpStream::SmolTcpStream(ref mut stream) => { - std::pin::Pin::new(stream).poll_write(cx, buf) - } - SocksTcpStream::KcpStream(ref mut stream) => { + SocksTcpStream::Tcp(ref mut stream) => std::pin::Pin::new(stream).poll_write(cx, buf), + SocksTcpStream::SmolTcp(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), } } @@ -121,11 +113,9 @@ impl AsyncWrite for SocksTcpStream { cx: &mut std::task::Context<'_>, ) -> std::task::Poll> { match self.get_mut() { - SocksTcpStream::TcpStream(ref mut stream) => std::pin::Pin::new(stream).poll_flush(cx), - SocksTcpStream::SmolTcpStream(ref mut stream) => { - std::pin::Pin::new(stream).poll_flush(cx) - } - SocksTcpStream::KcpStream(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::Kcp(ref mut stream) => std::pin::Pin::new(stream).poll_flush(cx), } } @@ -134,15 +124,9 @@ impl AsyncWrite for SocksTcpStream { cx: &mut std::task::Context<'_>, ) -> std::task::Poll> { match self.get_mut() { - SocksTcpStream::TcpStream(ref mut stream) => { - std::pin::Pin::new(stream).poll_shutdown(cx) - } - SocksTcpStream::SmolTcpStream(ref mut stream) => { - std::pin::Pin::new(stream).poll_shutdown(cx) - } - SocksTcpStream::KcpStream(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::Kcp(ref mut stream) => std::pin::Pin::new(stream).poll_shutdown(cx), } } } @@ -196,7 +180,7 @@ impl AsyncTcpConnector for SmolTcpConnector { let modified_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), addr.port()); - Ok(SocksTcpStream::TcpStream( + Ok(SocksTcpStream::Tcp( tcp_connect_with_timeout(modified_addr, timeout_s).await?, )) } else { @@ -207,9 +191,9 @@ impl AsyncTcpConnector for SmolTcpConnector { .await .with_context(|| "connect to remote timeout")?; - Ok(SocksTcpStream::SmolTcpStream(remote_socket.map_err( - |e| super::fast_socks5::SocksError::Other(e.into()), - )?)) + Ok(SocksTcpStream::SmolTcp(remote_socket.map_err(|e| { + super::fast_socks5::SocksError::Other(e.into()) + })?)) } } } @@ -249,7 +233,7 @@ impl AsyncTcpConnector for Socks5KcpConnector { .connect(self.src_addr, addr) .await .map_err(|e| super::fast_socks5::SocksError::Other(e.into()))?; - Ok(SocksTcpStream::KcpStream(ret)) + Ok(SocksTcpStream::Kcp(ret)) } } @@ -560,16 +544,16 @@ impl Socks5Server { tcp_forward_task.lock().unwrap().abort_all(); udp_client_map.clear(); - if cur_ipv4.is_none() { - let _ = net.lock().await.take(); - } else { + if let Some(cur_ipv4) = cur_ipv4 { net.lock().await.replace(Socks5ServerNet::new( - cur_ipv4.unwrap(), + cur_ipv4, None, peer_manager.clone(), packet_recv.clone(), entries.clone(), )); + } else { + let _ = net.lock().await.take(); } } @@ -621,7 +605,7 @@ impl Socks5Server { let cfgs = self.global_ctx.config.get_port_forwards(); self.reload_port_forwards(&cfgs).await?; - need_start = need_start || cfgs.len() > 0; + need_start = need_start || !cfgs.is_empty(); if need_start { self.peer_manager @@ -756,23 +740,21 @@ impl Socks5Server { continue; }; - let dst_allow_kcp = peer_mgr_arc.check_allow_kcp_to_dst(&dst_addr.ip()).await; + let dst_allow_kcp = peer_mgr_arc.check_allow_kcp_to_dst(&dst_addr.ip()).await; tracing::debug!("dst_allow_kcp: {:?}", dst_allow_kcp); let connector: Box + Send> = - if kcp_endpoint.is_none() || !dst_allow_kcp { - Box::new(SmolTcpConnector { + match (&kcp_endpoint, dst_allow_kcp) { + (Some(kcp_endpoint), true) => Box::new(Socks5KcpConnector { + kcp_endpoint: kcp_endpoint.clone(), + peer_mgr: peer_mgr.clone(), + src_addr: addr, + }), + (_, _) => Box::new(SmolTcpConnector { net: net.smoltcp_net.clone(), entries: entries.clone(), current_entry: std::sync::Mutex::new(None), - }) - } else { - let kcp_endpoint = kcp_endpoint.as_ref().unwrap().clone(); - Box::new(Socks5KcpConnector { - kcp_endpoint, - peer_mgr: peer_mgr.clone(), - src_addr: addr, - }) + }), }; forward_tasks @@ -962,10 +944,10 @@ impl Socks5Server { udp_client_map.retain(|_, client_info| { now.duration_since(client_info.last_active.load()).as_secs() < 600 }); - udp_forward_task.retain(|k, _| udp_client_map.contains_key(&k)); + udp_forward_task.retain(|k, _| udp_client_map.contains_key(k)); entries.retain(|_, data| match data { Socks5EntryData::Udp((_, udp_client_key)) => { - udp_client_map.contains_key(&udp_client_key) + udp_client_map.contains_key(udp_client_key) } _ => true, }); diff --git a/easytier/src/gateway/tcp_proxy.rs b/easytier/src/gateway/tcp_proxy.rs index 173048e9..12ed94fd 100644 --- a/easytier/src/gateway/tcp_proxy.rs +++ b/easytier/src/gateway/tcp_proxy.rs @@ -109,9 +109,9 @@ impl NatDstConnector for NatDstTcpConnector { ) -> bool { let is_exit_node = hdr.is_exit_node(); - if !cidr_set.contains_v4(ipv4.get_destination(), real_dst_ip) - && !is_exit_node - && !(global_ctx.no_tun() + if !(cidr_set.contains_v4(ipv4.get_destination(), real_dst_ip) + || is_exit_node + || global_ctx.no_tun() && Some(ipv4.get_destination()) == global_ctx.get_ipv4().as_ref().map(Ipv4Inet::address)) { @@ -154,10 +154,10 @@ impl NatDstEntry { } } - fn into_pb(&self, transport_type: TcpProxyEntryTransportType) -> TcpProxyEntry { + fn parse_as_pb(&self, transport_type: TcpProxyEntryTransportType) -> TcpProxyEntry { TcpProxyEntry { - src: Some(self.src.clone().into()), - dst: Some(self.real_dst.clone().into()), + src: Some(self.src.into()), + dst: Some(self.real_dst.into()), start_time: self.start_time_local.timestamp() as u64, state: self.state.load().into(), transport_type: transport_type.into(), @@ -332,16 +332,14 @@ pub struct TcpProxy { #[async_trait::async_trait] impl PeerPacketFilter for TcpProxy { async fn try_process_packet_from_peer(&self, mut packet: ZCPacket) -> Option { - if let Some(_) = self.try_handle_peer_packet(&mut packet).await { + if self.try_handle_peer_packet(&mut packet).await.is_some() { if self.is_smoltcp_enabled() { let smoltcp_stack_sender = self.smoltcp_stack_sender.as_ref().unwrap(); if let Err(e) = smoltcp_stack_sender.try_send(packet) { tracing::error!("send to smoltcp stack failed: {:?}", e); } - } else { - if let Err(e) = self.peer_manager.get_nic_channel().send(packet).await { - tracing::error!("send to nic failed: {:?}", e); - } + } else if let Err(e) = self.peer_manager.get_nic_channel().send(packet).await { + tracing::error!("send to nic failed: {:?}", e); } return None; } else { @@ -610,7 +608,7 @@ impl TcpProxy { self.enable_smoltcp .store(false, std::sync::atomic::Ordering::Relaxed); - return Ok(ProxyTcpListener::KernelTcpListener(tcp_listener)); + Ok(ProxyTcpListener::KernelTcpListener(tcp_listener)) } } @@ -917,10 +915,10 @@ impl TcpProxy { let mut entries: Vec = Vec::new(); let transport_type = self.connector.transport_type(); for entry in self.syn_map.iter() { - entries.push(entry.value().as_ref().into_pb(transport_type)); + entries.push(entry.value().as_ref().parse_as_pb(transport_type)); } for entry in self.conn_map.iter() { - entries.push(entry.value().as_ref().into_pb(transport_type)); + entries.push(entry.value().as_ref().parse_as_pb(transport_type)); } entries } diff --git a/easytier/src/gateway/tokio_smoltcp/channel_device.rs b/easytier/src/gateway/tokio_smoltcp/channel_device.rs index 6ee90d4c..1285780c 100644 --- a/easytier/src/gateway/tokio_smoltcp/channel_device.rs +++ b/easytier/src/gateway/tokio_smoltcp/channel_device.rs @@ -17,11 +17,17 @@ pub struct ChannelDevice { caps: DeviceCapabilities, } +pub type ChannelDeviceNewRet = ( + ChannelDevice, + Sender>>, + Receiver>, +); + impl ChannelDevice { /// Make a new `ChannelDevice` with the given `recv` and `send` channels. /// /// The `caps` is used to determine the device capabilities. `DeviceCapabilities::max_transmission_unit` must be set. - pub fn new(caps: DeviceCapabilities) -> (Self, Sender>>, Receiver>) { + pub fn new(caps: DeviceCapabilities) -> ChannelDeviceNewRet { let (tx1, rx1) = channel(1000); let (tx2, rx2) = channel(1000); ( @@ -45,7 +51,7 @@ impl Stream for ChannelDevice { } fn map_err(e: PollSendError>) -> io::Error { - io::Error::new(io::ErrorKind::Other, e) + io::Error::other(e) } impl Sink> for ChannelDevice { diff --git a/easytier/src/gateway/tokio_smoltcp/device.rs b/easytier/src/gateway/tokio_smoltcp/device.rs index 3bbe54b0..4df75d3b 100644 --- a/easytier/src/gateway/tokio_smoltcp/device.rs +++ b/easytier/src/gateway/tokio_smoltcp/device.rs @@ -46,8 +46,8 @@ impl RxToken for BufferRxToken { F: FnOnce(&[u8]) -> R, { let p = &mut self.0; - let result = f(p); - result + + f(p) } } @@ -79,10 +79,9 @@ impl Device for BufferDevice { Self: 'a; fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { - match self.recv_queue.pop_front() { - Some(p) => Some((BufferRxToken(p), BufferTxToken(self))), - None => None, - } + self.recv_queue + .pop_front() + .map(|p| (BufferRxToken(p), BufferTxToken(self))) } fn transmit(&mut self, _timestamp: Instant) -> Option> { diff --git a/easytier/src/gateway/tokio_smoltcp/mod.rs b/easytier/src/gateway/tokio_smoltcp/mod.rs index 3187d8c7..4a162ff4 100644 --- a/easytier/src/gateway/tokio_smoltcp/mod.rs +++ b/easytier/src/gateway/tokio_smoltcp/mod.rs @@ -4,7 +4,7 @@ use std::{ io, - net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}, + net::{IpAddr, SocketAddr}, sync::{ atomic::{AtomicU16, Ordering}, Arc, @@ -34,7 +34,7 @@ mod socket_allocator; /// Can be used to create a forever timestamp in neighbor. // The 60_000 is the same as NeighborCache::ENTRY_LIFETIME. pub const FOREVER: Instant = - Instant::from_micros_const(i64::max_value() - Duration::from_millis(60_000).micros() as i64); + Instant::from_micros_const(i64::MAX - Duration::from_millis(60_000).micros() as i64); pub struct Neighbor { pub protocol_addr: IpAddress, @@ -173,8 +173,8 @@ impl Net { fn set_address(&self, mut addr: SocketAddr) -> SocketAddr { if addr.ip().is_unspecified() { addr.set_ip(match self.ip_addr.address() { - IpAddress::Ipv4(ip) => Ipv4Addr::from(ip).into(), - IpAddress::Ipv6(ip) => Ipv6Addr::from(ip).into(), + IpAddress::Ipv4(ip) => ip.into(), + IpAddress::Ipv6(ip) => ip.into(), #[allow(unreachable_patterns)] _ => panic!("address must not be unspecified"), }); diff --git a/easytier/src/gateway/tokio_smoltcp/reactor.rs b/easytier/src/gateway/tokio_smoltcp/reactor.rs index b41c4929..f5ad22e8 100644 --- a/easytier/src/gateway/tokio_smoltcp/reactor.rs +++ b/easytier/src/gateway/tokio_smoltcp/reactor.rs @@ -51,9 +51,7 @@ async fn run( loop { let packets = device.take_send_queue(); - async_iface - .send_all(&mut iter(packets).map(|p| Ok(p))) - .await?; + async_iface.send_all(&mut iter(packets).map(Ok)).await?; if recv_buf.is_empty() && device.need_wait() { let start = Instant::now(); @@ -94,14 +92,10 @@ async fn run( // wake up all closed sockets (smoltcp seems have a bug that it doesn't wake up closed sockets) for (_, socket) in socket_allocator.sockets().lock().iter_mut() { - match socket { - Socket::Tcp(tcp) => { - if tcp.state() == smoltcp::socket::tcp::State::Closed { - tcp.abort(); - } + if let Socket::Tcp(tcp) = socket { + if tcp.state() == smoltcp::socket::tcp::State::Closed { + tcp.abort(); } - #[allow(unreachable_patterns)] - _ => {} } } } @@ -164,10 +158,8 @@ impl Reactor { impl Drop for Reactor { fn drop(&mut self) { for (_, socket) in self.socket_allocator.sockets().lock().iter_mut() { - match socket { - Socket::Tcp(tcp) => tcp.close(), - #[allow(unreachable_patterns)] - _ => {} + if let Socket::Tcp(tcp) = socket { + tcp.close() } } } diff --git a/easytier/src/gateway/tokio_smoltcp/socket.rs b/easytier/src/gateway/tokio_smoltcp/socket.rs index 1b1e6fcf..ffd57415 100644 --- a/easytier/src/gateway/tokio_smoltcp/socket.rs +++ b/easytier/src/gateway/tokio_smoltcp/socket.rs @@ -5,7 +5,7 @@ pub use smoltcp::socket::tcp; use smoltcp::socket::udp; use smoltcp::wire::{IpAddress, IpEndpoint}; use std::mem::replace; -use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; +use std::net::IpAddr; use std::{ io, net::SocketAddr, @@ -25,7 +25,7 @@ pub struct TcpListener { } fn map_err(e: E) -> io::Error { - io::Error::new(io::ErrorKind::Other, e.to_string()) + io::Error::other(e.to_string()) } impl TcpListener { @@ -95,8 +95,8 @@ impl Stream for Incoming { fn ep2sa(ep: &IpEndpoint) -> SocketAddr { match ep.addr { - IpAddress::Ipv4(v4) => SocketAddr::new(IpAddr::V4(Ipv4Addr::from(v4)), ep.port), - IpAddress::Ipv6(v6) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from(v6)), ep.port), + IpAddress::Ipv4(v4) => SocketAddr::new(IpAddr::V4(v4), ep.port), + IpAddress::Ipv6(v6) => SocketAddr::new(IpAddr::V6(v6), ep.port), #[allow(unreachable_patterns)] _ => unreachable!(), } diff --git a/easytier/src/gateway/udp_proxy.rs b/easytier/src/gateway/udp_proxy.rs index 5e29f0f1..44007491 100644 --- a/easytier/src/gateway/udp_proxy.rs +++ b/easytier/src/gateway/udp_proxy.rs @@ -26,7 +26,7 @@ use tracing::Level; use crate::{ common::{error::Error, global_ctx::ArcGlobalCtx, scoped_task::ScopedTask, PeerId}, - gateway::ip_reassembler::compose_ipv4_packet, + gateway::ip_reassembler::{compose_ipv4_packet, ComposeIpv4PacketArgs}, peers::{peer_manager::PeerManager, PeerPacketFilter}, tunnel::{ common::{reserve_buf, setup_sokcet2}, @@ -110,13 +110,15 @@ impl UdpNatEntry { )); compose_ipv4_packet( - &mut buf[..], - src_v4.ip(), - nat_src_v4.ip(), - IpNextHeaderProtocols::Udp, - payload_len + 8, // include udp header - payload_mtu, - ip_id, + ComposeIpv4PacketArgs { + buf: &mut buf[..], + src_v4: src_v4.ip(), + dst_v4: nat_src_v4.ip(), + next_protocol: IpNextHeaderProtocols::Udp, + payload_len: payload_len + 8, // include udp header + payload_mtu, + ip_id, + }, |buf| { let mut p = ZCPacket::new_with_payload(buf); p.fill_peer_manager_hdr(self.my_peer_id, self.src_peer_id, PacketType::Data as u8); @@ -273,11 +275,12 @@ impl UdpProxy { } let mut real_dst_ip = ipv4.get_destination(); - if !self + + if !(self .cidr_set .contains_v4(ipv4.get_destination(), &mut real_dst_ip) - && !is_exit_node - && !(self.global_ctx.no_tun() + || is_exit_node + || self.global_ctx.no_tun() && Some(ipv4.get_destination()) == self.global_ctx.get_ipv4().as_ref().map(Ipv4Inet::address)) { @@ -289,9 +292,7 @@ impl UdpProxy { resembled_buf = self.ip_resemmbler .add_fragment(ipv4.get_source(), ipv4.get_destination(), &ipv4); - if resembled_buf.is_none() { - return None; - }; + resembled_buf.as_ref()?; udp::UdpPacket::new(resembled_buf.as_ref().unwrap())? } else { udp::UdpPacket::new(ipv4.payload())? @@ -374,7 +375,7 @@ impl UdpProxy { #[async_trait::async_trait] impl PeerPacketFilter for UdpProxy { async fn try_process_packet_from_peer(&self, packet: ZCPacket) -> Option { - if let Some(_) = self.try_handle_packet(&packet).await { + if self.try_handle_packet(&packet).await.is_some() { return None; } else { return Some(packet); diff --git a/easytier/src/instance/dns_server/client_instance.rs b/easytier/src/instance/dns_server/client_instance.rs index 5139cfc4..b27d6a86 100644 --- a/easytier/src/instance/dns_server/client_instance.rs +++ b/easytier/src/instance/dns_server/client_instance.rs @@ -59,7 +59,7 @@ impl MagicDnsClientInstance { tokio::time::sleep(Duration::from_millis(500)).await; continue; } - prev_last_update = Some(last_update); + let mut routes = peer_mgr.list_routes().await; // add self as a route let ctx = peer_mgr.get_global_ctx(); @@ -79,6 +79,11 @@ impl MagicDnsClientInstance { rpc_stub .update_dns_record(BaseController::default(), req) .await?; + + let last_update_after_rpc = peer_mgr.get_route_peer_info_last_update_time().await; + if last_update_after_rpc == last_update { + prev_last_update = Some(last_update); + } } } diff --git a/easytier/src/instance/dns_server/config.rs b/easytier/src/instance/dns_server/config.rs index e55fadcd..e249ecfe 100644 --- a/easytier/src/instance/dns_server/config.rs +++ b/easytier/src/instance/dns_server/config.rs @@ -74,7 +74,7 @@ impl Record { } fn rr_type(&self) -> rr::RecordType { - self.rr_type.clone().into() + self.rr_type } } @@ -167,7 +167,7 @@ ttl = "61s" let (domain, records) = config .zones .get_key_value("et.internal") - .map_or(Err(anyhow!("parse error")), |x| Ok(x))?; + .ok_or(anyhow!("et.internal not found"))?; assert_eq!(domain, "et.internal"); assert_eq!(records.len(), 1); let record = &records[0]; @@ -179,7 +179,7 @@ ttl = "61s" let (domain, records) = config .zones .get_key_value("et.top") - .map_or(Err(anyhow!("parse error")), |x| Ok(x))?; + .ok_or(anyhow!("et.top not found"))?; assert_eq!(domain, "et.top"); assert_eq!(records.len(), 1); let record = &records[0]; diff --git a/easytier/src/instance/dns_server/runner.rs b/easytier/src/instance/dns_server/runner.rs index 524a2531..e777ca04 100644 --- a/easytier/src/instance/dns_server/runner.rs +++ b/easytier/src/instance/dns_server/runner.rs @@ -65,7 +65,7 @@ impl DnsRunner { self.client = Some(client); self.client.as_mut().unwrap().run_and_wait().await; - return Err(anyhow::anyhow!("Client instance exit")); + Err(anyhow::anyhow!("Client instance exit")) } pub async fn run(&mut self, canel_token: CancellationToken) { diff --git a/easytier/src/instance/dns_server/server.rs b/easytier/src/instance/dns_server/server.rs index 856b3385..32ae8a59 100644 --- a/easytier/src/instance/dns_server/server.rs +++ b/easytier/src/instance/dns_server/server.rs @@ -96,12 +96,12 @@ impl Server { .0 .name_servers() .iter() - .cloned() - .filter(|x| { + .filter(|&x| { !config .excluded_forward_nameservers() .contains(&x.socket_addr.ip()) }) + .cloned() .collect::>() .into(), options: Some(system_conf.1), @@ -148,7 +148,7 @@ impl Server { .with_context(|| { format!( "DNS Server failed to create UDP socket for address {}", - address.to_string() + address ) })?; socket2::SockRef::from(&socket) @@ -156,7 +156,7 @@ impl Server { .with_context(|| { format!( "DNS Server failed to set reuse address on socket {}", - address.to_string() + address ) })?; socket.bind(&bind_addr.into()).with_context(|| { @@ -164,17 +164,17 @@ impl Server { })?; socket .set_nonblocking(true) - .with_context(|| format!("DNS Server failed to set socket to non-blocking"))?; + .with_context(|| "DNS Server failed to set socket to non-blocking".to_string())?; let socket = UdpSocket::from_std(socket.into()).with_context(|| { format!( "DNS Server failed to convert socket to UdpSocket for address {}", - address.to_string() + address ) })?; let local_addr = socket .local_addr() - .with_context(|| format!("DNS Server failed to get local address"))?; + .with_context(|| "DNS Server failed to get local address".to_string())?; self.server.register_socket(socket); Ok(local_addr) diff --git a/easytier/src/instance/dns_server/server_instance.rs b/easytier/src/instance/dns_server/server_instance.rs index bbce4589..c25d21b6 100644 --- a/easytier/src/instance/dns_server/server_instance.rs +++ b/easytier/src/instance/dns_server/server_instance.rs @@ -70,6 +70,20 @@ pub(super) struct MagicDnsServerInstanceData { } impl MagicDnsServerInstanceData { + fn is_valid_subdomain_label(s: &str) -> bool { + let s = s.trim(); + + // 长度检查:1-63 个字符 + if s.is_empty() || s.len() > 63 { + return false; + } + + // 检查每个字符是否合法,并确保不以 '-' 开头或结尾 + s.chars().all(|c| matches!(c, 'a'..='z' | '0'..='9' | '-')) + && !s.starts_with('-') + && !s.ends_with('-') + } + pub async fn update_dns_records<'a, T: Iterator>( &self, routes: T, @@ -81,6 +95,11 @@ impl MagicDnsServerInstanceData { continue; } + // check host name valid for dns + if !Self::is_valid_subdomain_label(&route.hostname) { + continue; + } + let Some(ipv4_addr) = route.ipv4_addr.unwrap_or_default().address else { continue; }; @@ -432,7 +451,7 @@ impl MagicDnsServerInstance { if !self.tun_inet.contains(&self.data.fake_ip) && self.data.tun_dev.is_some() { let ifcfg = IfConfiger {}; let _ = ifcfg - .remove_ipv4_route(&self.data.tun_dev.as_ref().unwrap(), self.data.fake_ip, 32) + .remove_ipv4_route(self.data.tun_dev.as_ref().unwrap(), self.data.fake_ip, 32) .await; } diff --git a/easytier/src/instance/dns_server/system_config/linux.rs b/easytier/src/instance/dns_server/system_config/linux.rs index f2bfc619..834ef85c 100644 --- a/easytier/src/instance/dns_server/system_config/linux.rs +++ b/easytier/src/instance/dns_server/system_config/linux.rs @@ -26,13 +26,19 @@ struct DNSConfigError { source: Option, } +type DbusPingFn = dyn Fn(&str, &str) -> Result<()>; +type DbusReadStringFn = dyn Fn(&str, &str, &str, &str) -> Result; +type NmIsUsingResolvedFn = dyn Fn() -> Result<()>; +type NmVersionBetweenFn = dyn Fn(&str, &str) -> Result; +type ResolvconfStyleFn = dyn Fn() -> String; + // 配置环境结构体 struct OSConfigEnv { fs: Box, - dbus_ping: Box Result<()>>, - dbus_read_string: Box Result>, - nm_is_using_resolved: Box Result<()>>, - nm_version_between: Box Result>, + dbus_ping: Box, + dbus_read_string: Box, + nm_is_using_resolved: Box, + nm_version_between: Box, resolvconf_style: Box String>, } @@ -86,8 +92,7 @@ pub fn nm_is_using_resolved() -> Result<()> { return Err(anyhow::anyhow!( "NetworkManager is not using systemd-resolved, found: {:?}", value - ) - .into()); + )); } Ok(()) diff --git a/easytier/src/instance/dns_server/tests.rs b/easytier/src/instance/dns_server/tests.rs index 19a42607..fb046b29 100644 --- a/easytier/src/instance/dns_server/tests.rs +++ b/easytier/src/instance/dns_server/tests.rs @@ -41,7 +41,7 @@ pub async fn prepare_env(dns_name: &str, tun_ip: Ipv4Inet) -> (Arc, pub async fn check_dns_record(fake_ip: &Ipv4Addr, domain: &str, expected_ip: &str) { let stream = UdpClientStream::builder( - SocketAddr::new(fake_ip.clone().into(), 53), + SocketAddr::new((*fake_ip).into(), 53), TokioRuntimeProvider::default(), ) .build(); diff --git a/easytier/src/instance/instance.rs b/easytier/src/instance/instance.rs index bcbf44af..45151039 100644 --- a/easytier/src/instance/instance.rs +++ b/easytier/src/instance/instance.rs @@ -258,7 +258,7 @@ pub struct Instance { } impl Instance { - pub fn new(config: impl ConfigLoader + Send + Sync + 'static) -> Self { + pub fn new(config: impl ConfigLoader + 'static) -> Self { let global_ctx = Arc::new(GlobalCtx::new(config)); tracing::info!( @@ -304,10 +304,10 @@ impl Instance { #[cfg(feature = "socks5")] let socks5_server = Socks5Server::new(global_ctx.clone(), peer_manager.clone(), None); - let rpc_server = global_ctx.config.get_rpc_portal().and_then(|s| { - Some(StandAloneServer::new(TcpTunnelListener::new( + let rpc_server = global_ctx.config.get_rpc_portal().map(|s| { + StandAloneServer::new(TcpTunnelListener::new( format!("tcp://{}", s).parse().unwrap(), - ))) + )) }); Instance { @@ -470,7 +470,7 @@ impl Instance { continue; } - let last_ip = current_dhcp_ip.clone(); + let last_ip = current_dhcp_ip; tracing::debug!( ?current_dhcp_ip, ?candidate_ipv4_addr, @@ -509,11 +509,7 @@ impl Instance { Self::use_new_nic_ctx( nic_ctx.clone(), new_nic_ctx, - Self::create_magic_dns_runner( - peer_manager_c.clone(), - ifname, - ip.clone(), - ), + Self::create_magic_dns_runner(peer_manager_c.clone(), ifname, ip), ) .await; } @@ -890,7 +886,7 @@ impl Instance { ) -> Result { let stats_manager = self.global_ctx.stats_manager(); let snapshots = stats_manager.get_all_metrics(); - + let metrics = snapshots .into_iter() .map(|snapshot| { @@ -898,7 +894,7 @@ impl Instance { for label in snapshot.labels.labels() { labels.insert(label.key.clone(), label.value.clone()); } - + MetricSnapshot { name: snapshot.name_str(), value: snapshot.value, @@ -906,7 +902,7 @@ impl Instance { } }) .collect(); - + Ok(GetStatsResponse { metrics }) } @@ -917,7 +913,7 @@ impl Instance { ) -> Result { let stats_manager = self.global_ctx.stats_manager(); let prometheus_text = stats_manager.export_prometheus(); - + Ok(GetPrometheusStatsResponse { prometheus_text }) } } diff --git a/easytier/src/instance/listeners.rs b/easytier/src/instance/listeners.rs index 19a36f09..2fb8ed28 100644 --- a/easytier/src/instance/listeners.rs +++ b/easytier/src/instance/listeners.rs @@ -56,7 +56,7 @@ pub fn get_listener_by_url( } pub fn is_url_host_ipv6(l: &url::Url) -> bool { - l.host_str().map_or(false, |h| h.contains(':')) + l.host_str().is_some_and(|h| h.contains(':')) } pub fn is_url_host_unspecified(l: &url::Url) -> bool { diff --git a/easytier/src/instance/mod.rs b/easytier/src/instance/mod.rs index 1df957d6..82918ff3 100644 --- a/easytier/src/instance/mod.rs +++ b/easytier/src/instance/mod.rs @@ -1,5 +1,7 @@ pub mod dns_server; +#[allow(clippy::module_inception)] pub mod instance; + pub mod listeners; #[cfg(feature = "tun")] diff --git a/easytier/src/instance/virtual_nic.rs b/easytier/src/instance/virtual_nic.rs index 8e7a8edd..44b32eb2 100644 --- a/easytier/src/instance/virtual_nic.rs +++ b/easytier/src/instance/virtual_nic.rs @@ -68,10 +68,10 @@ impl Stream for TunStream { type Item = StreamItem; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - let mut self_mut = self.project(); + let self_mut = self.project(); let mut g = ready!(self_mut.l.poll_lock(cx)); - reserve_buf(&mut self_mut.cur_buf, 2500, 4 * 1024); - if self_mut.cur_buf.len() == 0 { + reserve_buf(self_mut.cur_buf, 2500, 4 * 1024); + if self_mut.cur_buf.is_empty() { unsafe { self_mut.cur_buf.set_len(*self_mut.payload_offset); } @@ -117,10 +117,7 @@ impl PacketProtocol { match self { PacketProtocol::IPv4 => Ok(libc::ETH_P_IP as u16), PacketProtocol::IPv6 => Ok(libc::ETH_P_IPV6 as u16), - PacketProtocol::Other(_) => Err(io::Error::new( - io::ErrorKind::Other, - "neither an IPv4 nor IPv6 packet", - )), + PacketProtocol::Other(_) => Err(io::Error::other("neither an IPv4 nor IPv6 packet")), } } @@ -175,7 +172,7 @@ impl TunZCPacketToBytes { } impl ZCPacketToBytes for TunZCPacketToBytes { - fn into_bytes(&self, zc_packet: ZCPacket) -> Result { + fn zcpacket_into_bytes(&self, zc_packet: ZCPacket) -> Result { let payload_offset = zc_packet.payload_offset(); let mut inner = zc_packet.inner(); // we have peer manager header, so payload offset must larger than 4 @@ -383,11 +380,11 @@ impl VirtualNic { let dev_name = self.global_ctx.get_flags().dev_name; if !dev_name.is_empty() { - config.tun_name(format!("{}", dev_name)); + config.tun_name(&dev_name); } } - #[cfg(any(target_os = "macos"))] + #[cfg(target_os = "macos")] config.platform_config(|config| { // disable packet information so we can process the header by ourselves, see tun2 impl for more details config.packet_information(false); @@ -515,9 +512,7 @@ impl VirtualNic { { // set mtu by ourselves, rust-tun does not handle it correctly on windows let _g = self.global_ctx.net_ns.guard(); - self.ifcfg - .set_mtu(ifname.as_str(), mtu_in_config as u32) - .await?; + self.ifcfg.set_mtu(ifname.as_str(), mtu_in_config).await?; } let has_packet_info = cfg!(target_os = "macos"); @@ -643,7 +638,7 @@ impl NicCtx { ) -> Self { NicCtx { global_ctx: global_ctx.clone(), - peer_mgr: Arc::downgrade(&peer_manager), + peer_mgr: Arc::downgrade(peer_manager), peer_packet_receiver, nic: Arc::new(Mutex::new(VirtualNic::new(global_ctx))), tasks: JoinSet::new(), diff --git a/easytier/src/instance_manager.rs b/easytier/src/instance_manager.rs index 9991c74a..1ec399bd 100644 --- a/easytier/src/instance_manager.rs +++ b/easytier/src/instance_manager.rs @@ -18,6 +18,12 @@ pub struct NetworkInstanceManager { stop_check_notifier: Arc, } +impl Default for NetworkInstanceManager { + fn default() -> Self { + Self::new() + } +} + impl NetworkInstanceManager { pub fn new() -> Self { NetworkInstanceManager { @@ -65,11 +71,9 @@ impl NetworkInstanceManager { let Some(instance_stop_notifier) = instance_stop_notifier else { return; }; - let _t = if let Some(event) = instance_event_receiver.flatten() { - Some(ScopedTask::from(handle_event(instance_id, event))) - } else { - None - }; + let _t = instance_event_receiver + .flatten() + .map(|event| ScopedTask::from(handle_event(instance_id, event))); instance_stop_notifier.notified().await; if let Some(instance) = instance_map.get(&instance_id) { if let Some(e) = instance.get_latest_error_msg() { @@ -124,17 +128,14 @@ impl NetworkInstanceManager { let mut ret = BTreeMap::new(); for instance in self.instance_map.iter() { if let Some(info) = instance.get_running_info() { - ret.insert(instance.key().clone(), info); + ret.insert(*instance.key(), info); } } Ok(ret) } pub fn list_network_instance_ids(&self) -> Vec { - self.instance_map - .iter() - .map(|item| item.key().clone()) - .collect() + self.instance_map.iter().map(|item| *item.key()).collect() } pub fn get_network_instance_name(&self, instance_id: &uuid::Uuid) -> Option { @@ -299,8 +300,8 @@ fn handle_event( instance_id, format!( "port forward added. local: {}, remote: {}, proto: {}", - cfg.bind_addr.unwrap().to_string(), - cfg.dst_addr.unwrap().to_string(), + cfg.bind_addr.unwrap(), + cfg.dst_addr.unwrap(), cfg.socket_type().as_str_name() ), ); @@ -347,9 +348,8 @@ mod tests { let instance_id1 = manager .run_network_instance( TomlConfigLoader::new_from_str(cfg_str) - .map(|c| { + .inspect(|c| { c.set_listeners(vec![format!("tcp://0.0.0.0:{}", port).parse().unwrap()]); - c }) .unwrap(), ConfigSource::Cli, @@ -426,9 +426,8 @@ mod tests { assert!(manager .run_network_instance( TomlConfigLoader::new_from_str(cfg_str) - .map(|c| { + .inspect(|c| { c.set_listeners(vec![format!("tcp://0.0.0.0:{}", port).parse().unwrap()]); - c }) .unwrap(), ConfigSource::GUI, diff --git a/easytier/src/launcher.rs b/easytier/src/launcher.rs index a96187c8..9f68d656 100644 --- a/easytier/src/launcher.rs +++ b/easytier/src/launcher.rs @@ -1,8 +1,5 @@ -use std::{ - collections::VecDeque, - sync::{atomic::AtomicBool, Arc, RwLock}, -}; -use std::net::SocketAddr; +use crate::common::config::PortForwardConfig; +use crate::proto::web; use crate::{ common::{ config::{ @@ -19,9 +16,12 @@ use crate::{ }; use anyhow::Context; use chrono::{DateTime, Local}; +use std::net::SocketAddr; +use std::{ + collections::VecDeque, + sync::{atomic::AtomicBool, Arc, RwLock}, +}; use tokio::{sync::broadcast, task::JoinSet}; -use crate::common::config::PortForwardConfig; -use crate::proto::web; pub type MyNodeInfo = crate::proto::web::MyNodeInfo; @@ -89,7 +89,7 @@ impl EasyTierLauncher { let _ = data.event_subscriber.read().unwrap().send(event.clone()); events.push_front(Event { time: chrono::Local::now(), - event: event, + event, }); if events.len() > 20 { events.pop_back(); @@ -380,9 +380,7 @@ impl NetworkInstance { } pub fn get_running_info(&self) -> Option { - if self.launcher.is_none() { - return None; - } + self.launcher.as_ref()?; let launcher = self.launcher.as_ref().unwrap(); @@ -434,19 +432,15 @@ impl NetworkInstance { } pub fn subscribe_event(&self) -> Option> { - if let Some(launcher) = self.launcher.as_ref() { - Some(launcher.data.event_subscriber.read().unwrap().subscribe()) - } else { - None - } + self.launcher + .as_ref() + .map(|launcher| launcher.data.event_subscriber.read().unwrap().subscribe()) } pub fn get_stop_notifier(&self) -> Option> { - if let Some(launcher) = self.launcher.as_ref() { - Some(launcher.data.instance_stop_notifier.clone()) - } else { - None - } + self.launcher + .as_ref() + .map(|launcher| launcher.data.instance_stop_notifier.clone()) } pub fn get_latest_error_msg(&self) -> Option { @@ -511,7 +505,7 @@ impl NetworkConfig { if !cfg.get_dhcp() { let virtual_ipv4 = self.virtual_ipv4.clone().unwrap_or_default(); - if virtual_ipv4.len() > 0 { + if !virtual_ipv4.is_empty() { let ip = format!("{}/{}", virtual_ipv4, self.network_length.unwrap_or(24)) .parse() .with_context(|| { @@ -596,8 +590,10 @@ impl NetworkConfig { .iter() .filter(|pf| !pf.bind_ip.is_empty() && !pf.dst_ip.is_empty()) .filter_map(|pf| { - let bind_addr = format!("{}:{}", pf.bind_ip, pf.bind_port).parse::(); - let dst_addr = format!("{}:{}", pf.dst_ip, pf.dst_port).parse::(); + let bind_addr = + format!("{}:{}", pf.bind_ip, pf.bind_port).parse::(); + let dst_addr = + format!("{}:{}", pf.dst_ip, pf.dst_port).parse::(); match (bind_addr, dst_addr) { (Ok(bind_addr), Ok(dst_addr)) => Some(PortForwardConfig { @@ -608,7 +604,7 @@ impl NetworkConfig { _ => None, } }) - .collect::>() + .collect::>(), ); } @@ -650,7 +646,7 @@ impl NetworkConfig { cfg.set_routes(Some(routes)); } - if self.exit_nodes.len() > 0 { + if !self.exit_nodes.is_empty() { let mut exit_nodes = Vec::::with_capacity(self.exit_nodes.len()); for node in self.exit_nodes.iter() { exit_nodes.push( @@ -669,7 +665,7 @@ impl NetworkConfig { } } - if self.mapped_listeners.len() > 0 { + if !self.mapped_listeners.is_empty() { cfg.set_mapped_listeners(Some( self.mapped_listeners .iter() @@ -754,7 +750,7 @@ impl NetworkConfig { } if self.enable_relay_network_whitelist.unwrap_or_default() { - if self.relay_network_whitelist.len() > 0 { + if !self.relay_network_whitelist.is_empty() { flags.relay_network_whitelist = self.relay_network_whitelist.join(" "); } else { flags.relay_network_whitelist = "".to_string(); @@ -784,7 +780,9 @@ impl NetworkConfig { pub fn new_from_config(config: &TomlConfigLoader) -> Result { let default_config = TomlConfigLoader::default(); - let mut result = Self::default(); + let mut result = Self { + ..Default::default() + }; result.instance_id = Some(config.get_id().to_string()); if config.get_hostname() != default_config.get_hostname() { @@ -819,7 +817,7 @@ impl NetworkConfig { result.listener_urls = config .get_listeners() - .unwrap_or_else(|| vec![]) + .unwrap_or_default() .iter() .map(|l| l.to_string()) .collect(); @@ -846,17 +844,16 @@ impl NetworkConfig { let port_forwards = config.get_port_forwards(); if !port_forwards.is_empty() { - result.port_forwards = port_forwards.iter() - .map(|f| { - web::PortForwardConfig { - proto: f.proto.clone(), - bind_ip: f.bind_addr.ip().to_string(), - bind_port: f.bind_addr.port() as u32, - dst_ip: f.dst_addr.ip().to_string(), - dst_port: f.dst_addr.port() as u32, - } - }). - collect(); + result.port_forwards = port_forwards + .iter() + .map(|f| web::PortForwardConfig { + proto: f.proto.clone(), + bind_ip: f.bind_addr.ip().to_string(), + bind_port: f.bind_addr.port() as u32, + dst_ip: f.dst_addr.ip().to_string(), + dst_port: f.dst_addr.port() as u32, + }) + .collect(); } if let Some(vpn_config) = config.get_vpn_portal_config() { diff --git a/easytier/src/lib.rs b/easytier/src/lib.rs index 4fe1e2cd..ac992099 100644 --- a/easytier/src/lib.rs +++ b/easytier/src/lib.rs @@ -13,8 +13,8 @@ mod vpn_portal; pub mod common; pub mod connector; -pub mod launcher; pub mod instance_manager; +pub mod launcher; pub mod peers; pub mod proto; pub mod tunnel; @@ -27,6 +27,6 @@ mod tests; pub const VERSION: &str = common::constants::EASYTIER_VERSION; rust_i18n::i18n!("locales", fallback = "en"); -pub fn print_completions(generator: G, cmd: &mut Command, bin_name:&str) { +pub fn print_completions(generator: G, cmd: &mut Command, bin_name: &str) { clap_complete::generate(generator, cmd, bin_name, &mut io::stdout()); -} \ No newline at end of file +} diff --git a/easytier/src/peer_center/instance.rs b/easytier/src/peer_center/instance.rs index bda929df..430acad6 100644 --- a/easytier/src/peer_center/instance.rs +++ b/easytier/src/peer_center/instance.rs @@ -97,13 +97,13 @@ impl PeerCenterBase { &self, job_ctx: T, job_fn: impl Fn( - Box + Send>, - Arc>, - ) -> Fut - + Send - + Sync - + 'static, - ) -> () { + Box + Send>, + Arc>, + ) -> Fut + + Send + + Sync + + 'static, + ) { let my_peer_id = self.my_peer_id; let peer_mgr = self.peer_mgr.clone(); let lock = self.lock.clone(); @@ -126,7 +126,7 @@ impl PeerCenterBase { return; }; - ctx.center_peer.store(center_peer.clone()); + ctx.center_peer.store(center_peer); tracing::trace!(?center_peer, "run periodic job"); let _g = lock.lock().await; let stub = rpc_mgr @@ -310,7 +310,7 @@ impl PeerCenterInstance { .init_periodic_job(ctx, |client, ctx| async move { let my_node_id = ctx.my_peer_id; let peers = ctx.job_ctx.peer_mgr.list_peers().await; - let peer_list = peers.direct_peers.keys().map(|k| *k).collect(); + let peer_list = peers.direct_peers.keys().copied().collect(); let job_ctx = &ctx.job_ctx; // only report when: @@ -370,7 +370,7 @@ impl PeerCenterInstance { .map .get(&src) .and_then(|src_peer_info| src_peer_info.direct_peers.get(&dst)) - .and_then(|info| Some(info.latency_ms)) + .map(|info| info.latency_ms) } } @@ -503,7 +503,7 @@ mod tests { let peer_center_b = PeerCenterInstance::new(peer_mgr_b.clone()); let peer_center_c = PeerCenterInstance::new(peer_mgr_c.clone()); - let peer_centers = vec![&peer_center_a, &peer_center_b, &peer_center_c]; + let peer_centers = [&peer_center_a, &peer_center_b, &peer_center_c]; for pc in peer_centers.iter() { pc.init().await; } diff --git a/easytier/src/peer_center/server.rs b/easytier/src/peer_center/server.rs index 9d98f4e2..9949ddb2 100644 --- a/easytier/src/peer_center/server.rs +++ b/easytier/src/peer_center/server.rs @@ -162,7 +162,7 @@ impl PeerCenterRpc for PeerCenterServer { direct_peers: Default::default(), }) .direct_peers - .insert(pair.dst, entry.info.clone()); + .insert(pair.dst, entry.info); } Ok(GetGlobalPeerMapResponse { diff --git a/easytier/src/peers/acl_filter.rs b/easytier/src/peers/acl_filter.rs index 1599b38a..4fdfd93d 100644 --- a/easytier/src/peers/acl_filter.rs +++ b/easytier/src/peers/acl_filter.rs @@ -27,6 +27,12 @@ pub struct AclFilter { acl_enabled: Arc, } +impl Default for AclFilter { + fn default() -> Self { + Self::new() + } +} + impl AclFilter { pub fn new() -> Self { Self { @@ -75,8 +81,8 @@ impl AclFilter { let rules_stats = processor.get_rules_stats(); AclStats { - global: global_stats.into_iter().map(|(k, v)| (k, v)).collect(), - conn_track: conn_track.iter().map(|x| x.value().clone()).collect(), + global: global_stats.into_iter().collect(), + conn_track: conn_track.iter().map(|x| *x.value()).collect(), rules: rules_stats, } } diff --git a/easytier/src/peers/encrypt/aes_gcm.rs b/easytier/src/peers/encrypt/aes_gcm.rs index ab396989..d39ed062 100644 --- a/easytier/src/peers/encrypt/aes_gcm.rs +++ b/easytier/src/peers/encrypt/aes_gcm.rs @@ -15,21 +15,21 @@ pub struct AesGcmCipher { #[derive(Clone)] pub enum AesGcmEnum { - AES128GCM(Aes128Gcm), - AES256GCM(Aes256Gcm), + AES128GCM(Box), + AES256GCM(Box), } impl AesGcmCipher { pub fn new_128(key: [u8; 16]) -> Self { let key: &Key = &key.into(); Self { - cipher: AesGcmEnum::AES128GCM(Aes128Gcm::new(key)), + cipher: AesGcmEnum::AES128GCM(Box::new(Aes128Gcm::new(key))), } } pub fn new_256(key: [u8; 32]) -> Self { let key: &Key = &key.into(); Self { - cipher: AesGcmEnum::AES256GCM(Aes256Gcm::new(key)), + cipher: AesGcmEnum::AES256GCM(Box::new(Aes256Gcm::new(key))), } } } @@ -80,7 +80,7 @@ impl Encryptor for AesGcmCipher { zc_packet .mut_inner() .truncate(old_len - AES_GCM_ENCRYPTION_RESERVED); - return Ok(()); + Ok(()) } fn encrypt(&self, zc_packet: &mut ZCPacket) -> Result<(), Error> { @@ -104,7 +104,7 @@ impl Encryptor for AesGcmCipher { } }; - return match rs { + match rs { Ok(tag) => { tail.tag.copy_from_slice(tag.as_slice()); @@ -114,7 +114,7 @@ impl Encryptor for AesGcmCipher { Ok(()) } Err(_) => Err(Error::EncryptionFailed), - }; + } } } @@ -137,10 +137,10 @@ mod tests { packet.payload().len(), text.len() + AES_GCM_ENCRYPTION_RESERVED ); - assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), true); + assert!(packet.peer_manager_header().unwrap().is_encrypted()); cipher.decrypt(&mut packet).unwrap(); assert_eq!(packet.payload(), text); - assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), false); + assert!(!packet.peer_manager_header().unwrap().is_encrypted()); } } diff --git a/easytier/src/peers/encrypt/mod.rs b/easytier/src/peers/encrypt/mod.rs index 8b7e468d..76a5c2a4 100644 --- a/easytier/src/peers/encrypt/mod.rs +++ b/easytier/src/peers/encrypt/mod.rs @@ -43,7 +43,7 @@ impl Encryptor for NullCipher { fn decrypt(&self, zc_packet: &mut ZCPacket) -> Result<(), Error> { let pm_header = zc_packet.peer_manager_header().unwrap(); if pm_header.is_encrypted() { - return Err(Error::DecryptionFailed); + Err(Error::DecryptionFailed) } else { Ok(()) } diff --git a/easytier/src/peers/encrypt/openssl_cipher.rs b/easytier/src/peers/encrypt/openssl_cipher.rs index 3730fb30..9d6db816 100644 --- a/easytier/src/peers/encrypt/openssl_cipher.rs +++ b/easytier/src/peers/encrypt/openssl_cipher.rs @@ -212,12 +212,12 @@ mod tests { // 加密 cipher.encrypt(&mut packet).unwrap(); assert!(packet.payload().len() > text.len() + OPENSSL_ENCRYPTION_RESERVED); - assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), true); + assert!(packet.peer_manager_header().unwrap().is_encrypted()); // 解密 cipher.decrypt(&mut packet).unwrap(); assert_eq!(packet.payload(), text); - assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), false); + assert!(!packet.peer_manager_header().unwrap().is_encrypted()); } #[test] @@ -231,11 +231,11 @@ mod tests { // 加密 cipher.encrypt(&mut packet).unwrap(); assert!(packet.payload().len() > text.len()); - assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), true); + assert!(packet.peer_manager_header().unwrap().is_encrypted()); // 解密 cipher.decrypt(&mut packet).unwrap(); assert_eq!(packet.payload(), text); - assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), false); + assert!(!packet.peer_manager_header().unwrap().is_encrypted()); } } diff --git a/easytier/src/peers/encrypt/ring_aes_gcm.rs b/easytier/src/peers/encrypt/ring_aes_gcm.rs index 603c25b2..c0c77624 100644 --- a/easytier/src/peers/encrypt/ring_aes_gcm.rs +++ b/easytier/src/peers/encrypt/ring_aes_gcm.rs @@ -65,7 +65,7 @@ impl Encryptor for AesGcmCipher { let text_and_tag_len = payload_len - AES_GCM_ENCRYPTION_RESERVED + 16; let aes_tail = AesGcmTail::ref_from_suffix(zc_packet.payload()).unwrap(); - let nonce = aead::Nonce::assume_unique_for_key(aes_tail.nonce.clone()); + let nonce = aead::Nonce::assume_unique_for_key(aes_tail.nonce); let rs = match &self.cipher { AesGcmEnum::AesGCM128(cipher, _) => cipher.open_in_place( @@ -79,7 +79,7 @@ impl Encryptor for AesGcmCipher { &mut zc_packet.mut_payload()[..text_and_tag_len], ), }; - if let Err(_) = rs { + if rs.is_err() { return Err(Error::DecryptionFailed); } @@ -89,7 +89,7 @@ impl Encryptor for AesGcmCipher { zc_packet .mut_inner() .truncate(old_len - AES_GCM_ENCRYPTION_RESERVED); - return Ok(()); + Ok(()) } fn encrypt(&self, zc_packet: &mut ZCPacket) -> Result<(), Error> { @@ -101,7 +101,7 @@ impl Encryptor for AesGcmCipher { let mut tail = AesGcmTail::default(); rand::thread_rng().fill_bytes(&mut tail.nonce); - let nonce = aead::Nonce::assume_unique_for_key(tail.nonce.clone()); + let nonce = aead::Nonce::assume_unique_for_key(tail.nonce); let rs = match &self.cipher { AesGcmEnum::AesGCM128(cipher, _) => cipher.seal_in_place_separate_tag( @@ -115,7 +115,7 @@ impl Encryptor for AesGcmCipher { zc_packet.mut_payload(), ), }; - return match rs { + match rs { Ok(tag) => { let tag = tag.as_ref(); if tag.len() != 16 { @@ -129,7 +129,7 @@ impl Encryptor for AesGcmCipher { Ok(()) } Err(_) => Err(Error::EncryptionFailed), - }; + } } } @@ -152,10 +152,10 @@ mod tests { packet.payload().len(), text.len() + AES_GCM_ENCRYPTION_RESERVED ); - assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), true); + assert!(packet.peer_manager_header().unwrap().is_encrypted()); cipher.decrypt(&mut packet).unwrap(); assert_eq!(packet.payload(), text); - assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), false); + assert!(!packet.peer_manager_header().unwrap().is_encrypted()); } } diff --git a/easytier/src/peers/encrypt/ring_chacha20.rs b/easytier/src/peers/encrypt/ring_chacha20.rs index 39d2eef3..687d02f9 100644 --- a/easytier/src/peers/encrypt/ring_chacha20.rs +++ b/easytier/src/peers/encrypt/ring_chacha20.rs @@ -44,7 +44,7 @@ impl Encryptor for RingChaCha20Cipher { let text_and_tag_len = payload_len - CHACHA20_POLY1305_ENCRYPTION_RESERVED + 16; let chacha20_tail = ChaCha20Poly1305Tail::ref_from_suffix(zc_packet.payload()).unwrap(); - let nonce = Nonce::assume_unique_for_key(chacha20_tail.nonce.clone()); + let nonce = Nonce::assume_unique_for_key(chacha20_tail.nonce); let rs = self.cipher.open_in_place( nonce, @@ -75,7 +75,7 @@ impl Encryptor for RingChaCha20Cipher { let mut tail = ChaCha20Poly1305Tail::default(); rand::thread_rng().fill_bytes(&mut tail.nonce); - let nonce = Nonce::assume_unique_for_key(tail.nonce.clone()); + let nonce = Nonce::assume_unique_for_key(tail.nonce); let rs = self.cipher @@ -116,10 +116,10 @@ mod tests { packet.payload().len(), text.len() + CHACHA20_POLY1305_ENCRYPTION_RESERVED ); - assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), true); + assert!(packet.peer_manager_header().unwrap().is_encrypted()); cipher.decrypt(&mut packet).unwrap(); assert_eq!(packet.payload(), text); - assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), false); + assert!(!packet.peer_manager_header().unwrap().is_encrypted()); } } diff --git a/easytier/src/peers/encrypt/xor_cipher.rs b/easytier/src/peers/encrypt/xor_cipher.rs index f7b9528f..0f249883 100644 --- a/easytier/src/peers/encrypt/xor_cipher.rs +++ b/easytier/src/peers/encrypt/xor_cipher.rs @@ -75,12 +75,12 @@ mod tests { // 加密 cipher.encrypt(&mut packet).unwrap(); - assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), true); + assert!(packet.peer_manager_header().unwrap().is_encrypted()); assert_ne!(packet.payload(), text); // 加密后数据应该不同 // 解密 cipher.decrypt(&mut packet).unwrap(); assert_eq!(packet.payload(), text); - assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), false); + assert!(!packet.peer_manager_header().unwrap().is_encrypted()); } } diff --git a/easytier/src/peers/foreign_network_client.rs b/easytier/src/peers/foreign_network_client.rs index 84ffab58..ddf3113e 100644 --- a/easytier/src/peers/foreign_network_client.rs +++ b/easytier/src/peers/foreign_network_client.rs @@ -53,7 +53,7 @@ impl ForeignNetworkClient { pub fn get_next_hop(&self, peer_id: PeerId) -> Option { if self.peer_map.has_peer(peer_id) { - return Some(peer_id.clone()); + return Some(peer_id); } None } diff --git a/easytier/src/peers/foreign_network_manager.rs b/easytier/src/peers/foreign_network_manager.rs index ab8be11b..5b4dc747 100644 --- a/easytier/src/peers/foreign_network_manager.rs +++ b/easytier/src/peers/foreign_network_manager.rs @@ -362,31 +362,32 @@ impl ForeignNetworkEntry { .get_gateway_peer_id(to_peer_id, NextHopPolicy::LeastHop) .await; - if gateway_peer_id.is_some() && peer_map.has_peer(gateway_peer_id.unwrap()) { - if let Err(e) = peer_map - .send_msg_directly(zc_packet, gateway_peer_id.unwrap()) - .await - { - tracing::error!( - ?e, - "send packet to foreign peer inside peer map failed" + match gateway_peer_id { + Some(peer_id) if peer_map.has_peer(peer_id) => { + if let Err(e) = peer_map.send_msg_directly(zc_packet, peer_id).await { + tracing::error!( + ?e, + "send packet to foreign peer inside peer map failed" + ); + } + } + _ => { + let mut foreign_packet = ZCPacket::new_for_foreign_network( + &network_name, + to_peer_id, + &zc_packet, ); + let via_peer = gateway_peer_id.unwrap_or(to_peer_id); + foreign_packet.fill_peer_manager_hdr( + my_node_id, + via_peer, + PacketType::ForeignNetworkPacket as u8, + ); + if let Err(e) = pm_sender.send(foreign_packet).await { + tracing::error!("send packet to peer with pm failed: {:?}", e); + } } - } else { - let mut foreign_packet = ZCPacket::new_for_foreign_network( - &network_name, - to_peer_id, - &zc_packet, - ); - foreign_packet.fill_peer_manager_hdr( - my_node_id, - gateway_peer_id.unwrap_or(to_peer_id), - PacketType::ForeignNetworkPacket as u8, - ); - if let Err(e) = pm_sender.send(foreign_packet).await { - tracing::error!("send packet to peer with pm failed: {:?}", e); - } - } + }; } } }); @@ -434,9 +435,10 @@ impl ForeignNetworkManagerData { let _ = v.remove(network_name); v.is_empty() }); - if let Some(_) = self + if self .network_peer_maps .remove_if(network_name, |_, v| v.peer_map.is_empty()) + .is_some() { self.network_peer_last_update.remove(network_name); } @@ -446,7 +448,7 @@ impl ForeignNetworkManagerData { let Some(peer_map) = self .network_peer_maps .get(network_name) - .and_then(|v| Some(v.peer_map.clone())) + .map(|v| v.peer_map.clone()) else { return; }; @@ -492,7 +494,7 @@ impl ForeignNetworkManagerData { self.peer_network_map .entry(dst_peer_id) - .or_insert_with(|| DashSet::new()) + .or_default() .insert(network_identity.network_name.clone()); self.network_peer_last_update @@ -553,7 +555,7 @@ impl ForeignNetworkManager { self.data .network_peer_maps .get(network_name) - .and_then(|v| Some(v.my_peer_id)) + .map(|v| v.my_peer_id) } pub async fn add_peer_conn(&self, peer_conn: PeerConn) -> Result<(), Error> { @@ -574,7 +576,7 @@ impl ForeignNetworkManager { &peer_conn.get_network_identity(), peer_conn.get_my_peer_id(), peer_conn.get_peer_id(), - !ret.is_err(), + ret.is_ok(), &self.global_ctx, &self.packet_sender_to_mgr, ) @@ -608,22 +610,21 @@ impl ForeignNetworkManager { if new_added { self.start_event_handler(&entry).await; - } else { - if let Some(peer) = entry.peer_map.get_peer_by_id(peer_conn.get_peer_id()) { - let direct_conns_len = peer.get_directly_connections().len(); - let max_count = use_global_var!(MAX_DIRECT_CONNS_PER_PEER_IN_FOREIGN_NETWORK); - if direct_conns_len >= max_count as usize { - return Err(anyhow::anyhow!( - "too many direct conns, cur: {}, max: {}", - direct_conns_len, - max_count - ) - .into()); - } + } else if let Some(peer) = entry.peer_map.get_peer_by_id(peer_conn.get_peer_id()) { + let direct_conns_len = peer.get_directly_connections().len(); + let max_count = use_global_var!(MAX_DIRECT_CONNS_PER_PEER_IN_FOREIGN_NETWORK); + if direct_conns_len >= max_count as usize { + return Err(anyhow::anyhow!( + "too many direct conns, cur: {}, max: {}", + direct_conns_len, + max_count + ) + .into()); } } - Ok(entry.peer_map.add_new_peer_conn(peer_conn).await) + entry.peer_map.add_new_peer_conn(peer_conn).await; + Ok(()) } async fn start_event_handler(&self, entry: &ForeignNetworkEntry) { @@ -686,9 +687,11 @@ impl ForeignNetworkManager { peers: Default::default(), }; for peer in item.peer_map.list_peers().await { - let mut peer_info = PeerInfo::default(); - peer_info.peer_id = peer; - peer_info.conns = item.peer_map.list_peer_conns(peer).await.unwrap_or(vec![]); + let peer_info = PeerInfo { + peer_id: peer, + conns: item.peer_map.list_peer_conns(peer).await.unwrap_or(vec![]), + ..Default::default() + }; entry.peers.push(peer_info); } @@ -701,7 +704,7 @@ impl ForeignNetworkManager { self.data .network_peer_last_update .get(network_name) - .map(|v| v.clone()) + .map(|v| *v) } pub async fn send_msg_to_peer( @@ -820,7 +823,7 @@ pub mod tests { let pm_center = create_mock_peer_manager_with_mock_stun(NatType::Unknown).await; tracing::debug!("pm_center: {:?}", pm_center.my_peer_id()); let mut flag = pm_center.get_global_ctx().get_flags(); - flag.relay_network_whitelist = vec!["net1".to_string(), "net2*".to_string()].join(" "); + flag.relay_network_whitelist = ["net1".to_string(), "net2*".to_string()].join(" "); pm_center.get_global_ctx().config.set_flags(flag); let pma_net1 = create_mock_peer_manager_for_foreign_network(name.as_str()).await; @@ -1026,7 +1029,7 @@ pub mod tests { drop(pm_center); wait_for_condition( - || async { pma_net1.list_routes().await.len() == 0 }, + || async { pma_net1.list_routes().await.is_empty() }, Duration::from_secs(5), ) .await; @@ -1168,7 +1171,7 @@ pub mod tests { println!("drop pm_center1, id: {:?}", pm_center1.my_peer_id()); drop(pm_center1); wait_for_condition( - || async { pma_net1.list_routes().await.len() == 0 }, + || async { pma_net1.list_routes().await.is_empty() }, Duration::from_secs(5), ) .await; diff --git a/easytier/src/peers/graph_algo.rs b/easytier/src/peers/graph_algo.rs index 33a77d24..63d1d6c9 100644 --- a/easytier/src/peers/graph_algo.rs +++ b/easytier/src/peers/graph_algo.rs @@ -60,14 +60,13 @@ impl Ord for MinScored { } } +pub type DijkstraResult = (HashMap, HashMap); + pub fn dijkstra_with_first_hop( graph: G, start: G::NodeId, mut edge_cost: F, -) -> ( - HashMap, - HashMap, -) +) -> DijkstraResult where G: IntoEdges + Visitable, G::NodeId: Eq + Hash + Clone, @@ -79,43 +78,43 @@ where let mut first_hop = HashMap::new(); let mut visit_next = BinaryHeap::new(); let zero_score = K::default(); - scores.insert(start.clone(), zero_score); - visit_next.push(MinScored(zero_score, start.clone())); - first_hop.insert(start.clone(), (start.clone(), 0)); + scores.insert(start, zero_score); + visit_next.push(MinScored(zero_score, start)); + first_hop.insert(start, (start, 0)); while let Some(MinScored(node_score, node)) = visit_next.pop() { if visited.is_visited(&node) { continue; } - for edge in graph.edges(node.clone()) { + for edge in graph.edges(node) { let next = edge.target(); if visited.is_visited(&next) { continue; } let next_score = node_score + edge_cost(edge); - match scores.entry(next.clone()) { + match scores.entry(next) { Occupied(mut ent) => { if next_score < *ent.get() { *ent.get_mut() = next_score; - visit_next.push(MinScored(next_score, next.clone())); + visit_next.push(MinScored(next_score, next)); // 继承前驱的 first_hop,或自己就是第一跳 let hop = if node == start { - (next.clone(), 0) + (next, 0) } else { - first_hop[&node].clone() + first_hop[&node] }; - first_hop.insert(next.clone(), (hop.0, hop.1 + 1)); + first_hop.insert(next, (hop.0, hop.1 + 1)); } } Vacant(ent) => { ent.insert(next_score); - visit_next.push(MinScored(next_score, next.clone())); + visit_next.push(MinScored(next_score, next)); let hop = if node == start { - (next.clone(), 0) + (next, 0) } else { - first_hop[&node].clone() + first_hop[&node] }; - first_hop.insert(next.clone(), (hop.0, hop.1 + 1)); + first_hop.insert(next, (hop.0, hop.1 + 1)); } } } @@ -138,9 +137,9 @@ mod tests { let c = graph.add_node("c"); let d = graph.add_node("d"); - graph.extend_with_edges(&[(a, b, 1)]); - graph.extend_with_edges(&[(b, c, 1)]); - graph.extend_with_edges(&[(c, d, 2)]); + graph.extend_with_edges([(a, b, 1)]); + graph.extend_with_edges([(b, c, 1)]); + graph.extend_with_edges([(c, d, 2)]); let (scores, first_hop) = dijkstra_with_first_hop(&graph, a, |edge| *edge.weight()); @@ -162,7 +161,7 @@ mod tests { let d = graph.add_node("d"); let e = graph.add_node("e"); - graph.extend_with_edges(&[(a, b, 1), (a, c, 2), (b, d, 1), (c, d, 3), (d, e, 1)]); + graph.extend_with_edges([(a, b, 1), (a, c, 2), (b, d, 1), (c, d, 3), (d, e, 1)]); let (scores, first_hop) = dijkstra_with_first_hop(&graph, a, |edge| *edge.weight()); diff --git a/easytier/src/peers/peer.rs b/easytier/src/peers/peer.rs index dbdd3b8e..bdcb712f 100644 --- a/easytier/src/peers/peer.rs +++ b/easytier/src/peers/peer.rs @@ -148,7 +148,7 @@ impl Peer { } // find a conn with the smallest latency - let mut min_latency = std::u64::MAX; + let mut min_latency = u64::MAX; for conn in self.conns.iter() { let latency = conn.value().get_stats().latency_us; if latency < min_latency { @@ -176,7 +176,7 @@ impl Peer { if !has_key { return Err(Error::NotFound); } - self.close_event_sender.send(conn_id.clone()).await.unwrap(); + self.close_event_sender.send(*conn_id).await.unwrap(); Ok(()) } @@ -277,7 +277,7 @@ mod tests { // wait for remote peer conn close timeout(std::time::Duration::from_secs(5), async { - while (&remote_peer).list_peer_conns().await.len() != 0 { + while !remote_peer.list_peer_conns().await.is_empty() { tokio::time::sleep(std::time::Duration::from_millis(100)).await; } }) diff --git a/easytier/src/peers/peer_conn.rs b/easytier/src/peers/peer_conn.rs index 92ae33ad..5a45e463 100644 --- a/easytier/src/peers/peer_conn.rs +++ b/easytier/src/peers/peer_conn.rs @@ -102,7 +102,7 @@ pub struct PeerConn { tunnel: Arc>>, sink: MpscTunnelSender, - recv: Arc>>>>, + recv: Mutex>>>, tunnel_info: Option, tasks: JoinSet>, @@ -149,7 +149,7 @@ impl PeerConn { let conn_id = PeerConnId::new_v4(); PeerConn { - conn_id: conn_id.clone(), + conn_id, my_peer_id, global_ctx, @@ -158,7 +158,7 @@ impl PeerConn { mpsc_tunnel.close() })))), sink, - recv: Arc::new(Mutex::new(Some(recv))), + recv: Mutex::new(Some(recv)), tunnel_info, tasks: JoinSet::new(), @@ -238,7 +238,7 @@ impl PeerConn { )); } - return Ok(rsp); + Ok(rsp) } async fn wait_handshake_loop(&mut self) -> Result { @@ -424,10 +424,8 @@ impl PeerConn { if let Err(e) = ctrl_sender.send(zc_packet) { tracing::error!(?e, "peer conn send ctrl resp error"); } - } else { - if sender.send(zc_packet).await.is_err() { - break; - } + } else if sender.send(zc_packet).await.is_err() { + break; } } @@ -650,7 +648,10 @@ mod tests { let throughput = c_peer.throughput.clone(); let _t = ScopedTask::from(tokio::spawn(async move { // if not drop both, we mock some rx traffic for client peer to test pinger - while !drop_both { + if drop_both { + return; + } + loop { tokio::time::sleep(Duration::from_millis(100)).await; throughput.record_rx_bytes(3); } diff --git a/easytier/src/peers/peer_conn_ping.rs b/easytier/src/peers/peer_conn_ping.rs index 0cfc7d94..24ffd4cf 100644 --- a/easytier/src/peers/peer_conn_ping.rs +++ b/easytier/src/peers/peer_conn_ping.rs @@ -106,7 +106,7 @@ impl PingIntervalController { } self.last_send_logic_time = self.logic_time; - return true; + true } } @@ -255,7 +255,7 @@ impl PeerConnPinger { "pingpong controller send pingpong task, seq: {}, node_id: {}, controller: {:?}", req_seq, my_node_id, - controller + controller, ); let mut sink = sink.clone(); diff --git a/easytier/src/peers/peer_manager.rs b/easytier/src/peers/peer_manager.rs index 0b5d94c2..1a112d32 100644 --- a/easytier/src/peers/peer_manager.rs +++ b/easytier/src/peers/peer_manager.rs @@ -351,7 +351,8 @@ impl PeerManager { "network identity not match".to_string(), )); } - Ok(self.peers.add_new_peer_conn(peer_conn).await) + self.peers.add_new_peer_conn(peer_conn).await; + Ok(()) } pub async fn add_client_tunnel( @@ -377,10 +378,8 @@ impl PeerManager { pub fn has_directly_connected_conn(&self, peer_id: PeerId) -> bool { if let Some(peer) = self.peers.get_peer_by_id(peer_id) { peer.has_directly_connected_conn() - } else if self.foreign_network_client.get_peer_map().has_peer(peer_id) { - true } else { - false + self.foreign_network_client.get_peer_map().has_peer(peer_id) } } @@ -441,14 +440,14 @@ impl PeerManager { match addr { SocketAddr::V4(addr) => { if let Some(virtual_ipv4) = virtual_ipv4 { - if virtual_ipv4.contains(&addr.ip()) { + if virtual_ipv4.contains(addr.ip()) { anyhow::bail!("tunnel src host is from the virtual network (ignore this error please)"); } } } SocketAddr::V6(addr) => { if let Some(virtual_ipv6) = virtual_ipv6 { - if virtual_ipv6.contains(&addr.ip()) { + if virtual_ipv6.contains(addr.ip()) { anyhow::bail!("tunnel src host is from the virtual network (ignore this error please)"); } } @@ -489,7 +488,7 @@ impl PeerManager { rand::random::() }).value()); } - peer.set_peer_id(peer_id.clone().unwrap()); + peer.set_peer_id(peer_id.unwrap()); tracing::info!( ?peer_id, @@ -742,10 +741,8 @@ impl PeerManager { let mut processed = false; let mut zc_packet = Some(ret); - let mut idx = 0; - for pipeline in pipe_line.read().await.iter().rev() { + for (idx, pipeline) in pipe_line.read().await.iter().rev().enumerate() { tracing::trace!(?zc_packet, ?idx, "try_process_packet_from_peer"); - idx += 1; zc_packet = pipeline .try_process_packet_from_peer(zc_packet.unwrap()) .await; @@ -938,14 +935,17 @@ impl PeerManager { let entry = resp .foreign_networks .entry(info.key.as_ref().unwrap().peer_id) - .or_insert_with(|| Default::default()); + .or_insert_with(Default::default); + let Some(route_info) = info.value.as_ref() else { + continue; + }; - let mut f = OneForeignNetwork::default(); - f.network_name = info.key.as_ref().unwrap().network_name.clone(); - f.peer_ids - .extend(info.value.as_ref().unwrap().foreign_peer_ids.iter()); - f.last_updated = format!("{}", info.value.as_ref().unwrap().last_update.unwrap()); - f.version = info.value.as_ref().unwrap().version; + let f = OneForeignNetwork { + network_name: info.key.as_ref().unwrap().network_name.clone(), + peer_ids: route_info.foreign_peer_ids.clone(), + last_updated: format!("{}", route_info.last_update.unwrap()), + version: route_info.version, + }; entry.foreign_networks.push(f); } @@ -1033,14 +1033,8 @@ impl PeerManager { || ipv4_addr.is_multicast() || *ipv4_addr == ipv4_inet.last_address() { - dst_peers.extend( - self.peers - .list_routes() - .await - .iter() - .map(|x| x.key().clone()), - ); - } else if let Some(peer_id) = self.peers.get_peer_id_by_ipv4(&ipv4_addr).await { + dst_peers.extend(self.peers.list_routes().await.iter().map(|x| *x.key())); + } else if let Some(peer_id) = self.peers.get_peer_id_by_ipv4(ipv4_addr).await { dst_peers.push(peer_id); } else { for exit_node in &self.exit_nodes { @@ -1075,14 +1069,8 @@ impl PeerManager { .unwrap_or(64); let ipv6_inet = cidr::Ipv6Inet::new(*ipv6_addr, network_length).unwrap(); if ipv6_addr.is_multicast() || *ipv6_addr == ipv6_inet.last_address() { - dst_peers.extend( - self.peers - .list_routes() - .await - .iter() - .map(|x| x.key().clone()), - ); - } else if let Some(peer_id) = self.peers.get_peer_id_by_ipv6(&ipv6_addr).await { + dst_peers.extend(self.peers.list_routes().await.iter().map(|x| *x.key())); + } else if let Some(peer_id) = self.peers.get_peer_id_by_ipv6(ipv6_addr).await { dst_peers.push(peer_id); } else if !ipv6_addr.is_unicast_link_local() { // NOTE: never route link local address to exit node. @@ -1168,14 +1156,13 @@ impl PeerManager { let mut errs: Vec = vec![]; let mut msg = Some(msg); let total_dst_peers = dst_peers.len(); - for i in 0..total_dst_peers { + for (i, peer_id) in dst_peers.iter().enumerate() { let mut msg = if i == total_dst_peers - 1 { msg.take().unwrap() } else { msg.clone().unwrap() }; - let peer_id = &dst_peers[i]; msg.mut_peer_manager_header() .unwrap() .to_peer_id @@ -1632,16 +1619,16 @@ mod tests { ..Default::default() }); tokio::time::sleep(Duration::from_secs(2)).await; - wait_route_appear_with_cost(peer_mgr_a.clone(), peer_mgr_c.my_peer_id, Some(3)) + if wait_route_appear_with_cost(peer_mgr_a.clone(), peer_mgr_c.my_peer_id, Some(3)) .await - .expect( - format!( - "route not appear, a route table: {}, table: {:#?}", - peer_mgr_a.get_route().dump().await, - peer_mgr_a.get_route().list_routes().await - ) - .as_str(), - ); + .is_err() + { + panic!( + "route not appear, a route table: {}, table: {:#?}", + peer_mgr_a.get_route().dump().await, + peer_mgr_a.get_route().list_routes().await + ) + } let ret = peer_mgr_a .get_route() @@ -1767,8 +1754,7 @@ mod tests { .get_foreign_network_client() .list_public_peers() .await - .len() - == 0 + .is_empty() }, Duration::from_secs(10), ) @@ -1810,8 +1796,7 @@ mod tests { .get_foreign_network_client() .list_public_peers() .await - .len() - == 0 + .is_empty() }, Duration::from_secs(10), ) diff --git a/easytier/src/peers/peer_map.rs b/easytier/src/peers/peer_map.rs index eef23fd9..4c900b2f 100644 --- a/easytier/src/peers/peer_map.rs +++ b/easytier/src/peers/peer_map.rs @@ -49,8 +49,8 @@ impl PeerMap { } async fn add_new_peer(&self, peer: Peer) { - let peer_id = peer.peer_node_id.clone(); - self.peer_map.insert(peer_id.clone(), Arc::new(peer)); + let peer_id = peer.peer_node_id; + self.peer_map.insert(peer_id, Arc::new(peer)); self.global_ctx .issue_event(GlobalCtxEvent::PeerAdded(peer_id)); } @@ -75,7 +75,7 @@ impl PeerMap { let conn_id = close_notifier.get_conn_id(); let conn_info = peer_conn.get_conn_info(); self.alive_conns - .insert((conn_info.peer_id, conn_id.clone()), conn_info.clone()); + .insert((conn_info.peer_id, conn_id), conn_info.clone()); tokio::spawn(async move { if let Some(mut waiter) = close_notifier.get_waiter().await { let _ = waiter.recv().await; @@ -173,9 +173,7 @@ impl PeerMap { ) -> Vec { let mut ret = Vec::new(); for route in self.routes.read().await.iter() { - let peers = route - .list_peers_own_foreign_network(&network_identity) - .await; + let peers = route.list_peers_own_foreign_network(network_identity).await; ret.extend(peers); } ret @@ -195,7 +193,7 @@ impl PeerMap { }; self.send_msg_directly(msg, gateway_peer_id).await?; - return Ok(()); + Ok(()) } pub async fn get_peer_id_by_ipv4(&self, ipv4: &Ipv4Addr) -> Option { @@ -263,7 +261,7 @@ impl PeerMap { let Some(peer) = self.get_peer_by_id(*peer_id) else { continue; }; - if peer.list_peer_conns().await.len() > 0 { + if !peer.list_peer_conns().await.is_empty() { ret.push(*peer_id); } } @@ -274,7 +272,7 @@ impl PeerMap { if let Some(p) = self.get_peer_by_id(peer_id) { Some(p.list_peer_conns().await) } else { - return None; + None } } @@ -291,7 +289,7 @@ impl PeerMap { if let Some(p) = self.get_peer_by_id(peer_id) { p.close_peer_conn(conn_id).await } else { - return Err(Error::NotFound); + Err(Error::NotFound) } } @@ -339,7 +337,7 @@ impl PeerMap { } pub async fn list_route_infos(&self) -> Vec { - for route in self.routes.read().await.iter() { + if let Some(route) = self.routes.read().await.iter().next() { return route.list_routes().await; } vec![] @@ -361,7 +359,7 @@ impl PeerMap { pub fn get_alive_conns(&self) -> DashMap<(PeerId, PeerConnId), PeerConnInfo> { self.alive_conns .iter() - .map(|v| (v.key().clone(), v.value().clone())) + .map(|v| (*v.key(), v.value().clone())) .collect() } diff --git a/easytier/src/peers/peer_ospf_route.rs b/easytier/src/peers/peer_ospf_route.rs index 5c0a1d67..0a969913 100644 --- a/easytier/src/peers/peer_ospf_route.rs +++ b/easytier/src/peers/peer_ospf_route.rs @@ -170,7 +170,7 @@ impl RoutePeerInfo { }; let need_update_periodically = if let Ok(Ok(d)) = - SystemTime::try_from(new.last_update.unwrap()).map(|x| x.elapsed()) + SystemTime::try_from(new.last_update.unwrap_or_default()).map(|x| x.elapsed()) { d > UPDATE_PEER_INFO_PERIOD } else { @@ -186,45 +186,41 @@ impl RoutePeerInfo { } } -impl Into for RoutePeerInfo { - fn into(self) -> crate::proto::cli::Route { - let network_length = if self.network_length == 0 { +impl From for crate::proto::cli::Route { + fn from(val: RoutePeerInfo) -> Self { + let network_length = if val.network_length == 0 { 24 } else { - self.network_length + val.network_length }; crate::proto::cli::Route { - peer_id: self.peer_id, - ipv4_addr: if let Some(ipv4_addr) = self.ipv4_addr { - Some(Ipv4Inet { - address: Some(ipv4_addr.into()), - network_length, - }) - } else { - None - }, + peer_id: val.peer_id, + ipv4_addr: val.ipv4_addr.map(|ipv4_addr| Ipv4Inet { + address: Some(ipv4_addr), + network_length, + }), next_hop_peer_id: 0, // next_hop_peer_id is calculated in RouteTable. cost: 0, // cost is calculated in RouteTable. path_latency: 0, // path_latency is calculated in RouteTable. - proxy_cidrs: self.proxy_cidrs.clone(), - hostname: self.hostname.unwrap_or_default(), + proxy_cidrs: val.proxy_cidrs.clone(), + hostname: val.hostname.unwrap_or_default(), stun_info: { let mut stun_info = StunInfo::default(); - if let Ok(udp_nat_type) = NatType::try_from(self.udp_stun_info as i32) { + if let Ok(udp_nat_type) = NatType::try_from(val.udp_stun_info) { stun_info.set_udp_nat_type(udp_nat_type); } Some(stun_info) }, - inst_id: self.inst_id.map(|x| x.to_string()).unwrap_or_default(), - version: self.easytier_version, - feature_flag: self.feature_flag, + inst_id: val.inst_id.map(|x| x.to_string()).unwrap_or_default(), + version: val.easytier_version, + feature_flag: val.feature_flag, next_hop_peer_id_latency_first: None, cost_latency_first: None, path_latency_latency_first: None, - ipv6_addr: self.ipv6_addr.map(Into::into), + ipv6_addr: val.ipv6_addr, } } } @@ -235,10 +231,10 @@ struct RouteConnBitmap { bitmap: Vec, } -impl Into for RouteConnBitmap { - fn into(self) -> crate::proto::peer_rpc::RouteConnBitmap { +impl From for crate::proto::peer_rpc::RouteConnBitmap { + fn from(val: RouteConnBitmap) -> Self { crate::proto::peer_rpc::RouteConnBitmap { - peer_ids: self + peer_ids: val .peer_ids .into_iter() .map(|x| PeerIdVersion { @@ -246,7 +242,7 @@ impl Into for RouteConnBitmap { version: x.1, }) .collect(), - bitmap: self.bitmap, + bitmap: val.bitmap, } } } @@ -318,7 +314,7 @@ impl SyncedRouteInfo { fn get_connected_peers>(&self, peer_id: PeerId) -> Option { self.conn_map .get(&peer_id) - .map(|x| x.0.clone().iter().map(|x| *x).collect()) + .map(|x| x.0.clone().iter().copied().collect()) } fn remove_peer(&self, peer_id: PeerId) { @@ -403,8 +399,8 @@ impl SyncedRouteInfo { my_peer_id: PeerId, my_peer_route_id: u64, dst_peer_id: PeerId, - peer_infos: &Vec, - raw_peer_infos: &Vec, + peer_infos: &[RoutePeerInfo], + raw_peer_infos: &[DynamicMessage], ) -> Result<(), Error> { let mut need_inc_version = false; for (idx, route_info) in peer_infos.iter().enumerate() { @@ -476,7 +472,7 @@ impl SyncedRouteInfo { }) .or_insert_with(|| { need_inc_version = true; - (connceted_peers, version.clone().into()) + (connceted_peers, (*version).into()) }); } if need_inc_version { @@ -512,11 +508,8 @@ impl SyncedRouteInfo { my_peer_route_id: u64, global_ctx: &ArcGlobalCtx, ) -> bool { - let mut old = self - .peer_infos - .entry(my_peer_id) - .or_insert(RoutePeerInfo::new()); - let new = old.update_self(my_peer_id, my_peer_route_id, &global_ctx); + let mut old = self.peer_infos.entry(my_peer_id).or_default(); + let new = old.update_self(my_peer_id, my_peer_route_id, global_ctx); let new_version = new.version; let old_version = old.version; *old = new; @@ -616,8 +609,8 @@ impl SyncedRouteInfo { } fn is_peer_directly_connected(&self, src_peer_id: PeerId, dst_peer_id: PeerId) -> bool { - return self.is_peer_bidirectly_connected(src_peer_id, dst_peer_id) - || self.is_peer_bidirectly_connected(dst_peer_id, src_peer_id); + self.is_peer_bidirectly_connected(src_peer_id, dst_peer_id) + || self.is_peer_bidirectly_connected(dst_peer_id, src_peer_id) } } @@ -674,7 +667,7 @@ impl RouteTable { fn get_nat_type(&self, peer_id: PeerId) -> Option { self.peer_infos .get(&peer_id) - .map(|x| NatType::try_from(x.udp_stun_info as i32).unwrap_or_default()) + .map(|x| NatType::try_from(x.udp_stun_info).unwrap_or_default()) } // return graph and start node index (node of my peer id). @@ -710,9 +703,9 @@ impl RouteTable { for item in peer_id_to_node_index.iter() { let src_peer_id = item.key(); let src_node_idx = item.value(); - let connected_peers = synced_info + let connected_peers: BTreeSet<_> = synced_info .get_connected_peers(*src_peer_id) - .unwrap_or(BTreeSet::new()); + .unwrap_or_default(); // if avoid relay, just set all outgoing edges to a large value: AVOID_RELAY_COST. let peer_avoid_relay_data = synced_info.get_avoid_relay_data(*src_peer_id); @@ -798,7 +791,7 @@ impl RouteTable { } // Step 3: 第二次 Dijkstra - 在子图上找代价最小的路径 - self.gen_next_hop_map_with_least_cost(&subgraph, &start_node_idx.clone().unwrap(), version); + self.gen_next_hop_map_with_least_cost(&subgraph, &start_node_idx.unwrap(), version); } fn gen_next_hop_map_with_least_cost( @@ -813,7 +806,7 @@ impl RouteTable { let info = NextHopInfo { next_hop_peer_id: *graph.node_weight(*next_hop).unwrap(), path_latency: (*costs.get(dst).unwrap() % AVOID_RELAY_COST) as i32, - path_len: *path_len as usize, + path_len: { *path_len }, version, }; let dst_peer_id = *graph.node_weight(*dst).unwrap(); @@ -841,7 +834,7 @@ impl RouteTable { // build next hop map let (graph, start_node) = - Self::build_peer_graph_from_synced_info(my_peer_id, &synced_info, cost_calc); + Self::build_peer_graph_from_synced_info(my_peer_id, synced_info, cost_calc); if graph.node_count() == 0 { tracing::warn!("no peer in graph, cannot build next hop map"); @@ -1031,11 +1024,11 @@ impl SyncRouteSession { .unwrap_or(false) } - fn update_dst_saved_peer_info_version(&self, infos: &Vec) { + fn update_dst_saved_peer_info_version(&self, infos: &[RoutePeerInfo]) { for info in infos.iter() { self.dst_saved_peer_info_versions .entry(info.peer_id) - .or_insert_with(|| AtomicVersion::new()) + .or_insert_with(AtomicVersion::new) .set_if_larger(info.version); } } @@ -1044,7 +1037,7 @@ impl SyncRouteSession { for (peer_id, version) in conn_bitmap.peer_ids.iter() { self.dst_saved_conn_bitmap_version .entry(*peer_id) - .or_insert_with(|| AtomicVersion::new()) + .or_insert_with(AtomicVersion::new) .set_if_larger(*version); } } @@ -1053,7 +1046,7 @@ impl SyncRouteSession { for item in foreign_network.infos.iter() { self.dst_saved_foreign_network_versions .entry(item.key.clone().unwrap()) - .or_insert_with(|| AtomicVersion::new()) + .or_insert_with(AtomicVersion::new) .set_if_larger(item.value.as_ref().unwrap().version); } } @@ -1249,13 +1242,10 @@ impl PeerRouteServiceImpl { .list_foreign_networks() .await; - let updated = self - .synced_route_info - .update_my_foreign_network(self.my_peer_id, foreign_networks); - // do not need update owner map because we always filter out my peer id. - updated + self.synced_route_info + .update_my_foreign_network(self.my_peer_id, foreign_networks) } fn update_route_table(&self) { @@ -1317,7 +1307,7 @@ impl PeerRouteServiceImpl { }; self.foreign_network_owner_map .entry(network_identity) - .or_insert_with(|| Vec::new()) + .or_default() .push(entry.my_peer_id_for_this_network); self.foreign_network_my_peer_id_map.insert( @@ -1350,8 +1340,7 @@ impl PeerRouteServiceImpl { .synced_route_info .conn_map .iter() - .map(|x| x.value().clone().0.into_iter()) - .flatten() + .flat_map(|x| x.value().clone().0.into_iter()) .collect::>(); let all_peer_ids = self @@ -1364,7 +1353,7 @@ impl PeerRouteServiceImpl { .collect::>(); let mut conn_bitmap = RouteConnBitmap::new(); - conn_bitmap.bitmap = vec![0; (all_peer_ids.len() * all_peer_ids.len() + 7) / 8]; + conn_bitmap.bitmap = vec![0; (all_peer_ids.len() * all_peer_ids.len()).div_ceil(8)]; conn_bitmap.peer_ids = all_peer_ids; let all_peer_ids = &conn_bitmap.peer_ids; @@ -1419,7 +1408,7 @@ impl PeerRouteServiceImpl { for (peer_id, local_version) in self.cached_local_conn_map.lock().unwrap().peer_ids.iter() { let peer_version = session .dst_saved_conn_bitmap_version - .get(&peer_id) + .get(peer_id) .map(|item| item.get()); if peer_version.is_none() || peer_version.unwrap() < *local_version { need_update = true; @@ -1442,7 +1431,7 @@ impl PeerRouteServiceImpl { for item in self.synced_route_info.foreign_network.iter() { if session .dst_saved_foreign_network_versions - .get(&item.key()) + .get(item.key()) .map(|x| x.get() >= item.value().version) .unwrap_or(false) { @@ -1485,9 +1474,9 @@ impl PeerRouteServiceImpl { Option, Option, ) { - let route_infos = self.build_route_info(&session); - let conn_bitmap = self.build_conn_bitmap(&session); - let foreign_network = self.build_foreign_network_info(&session); + let route_infos = self.build_route_info(session); + let conn_bitmap = self.build_conn_bitmap(session); + let foreign_network = self.build_foreign_network_info(session); (route_infos, conn_bitmap, foreign_network) } @@ -1661,19 +1650,19 @@ impl PeerRouteServiceImpl { session.update_dst_session_id(resp.session_id); if let Some(peer_infos) = &peer_infos { - session.update_dst_saved_peer_info_version(&peer_infos); + session.update_dst_saved_peer_info_version(peer_infos); } if let Some(conn_bitmap) = &conn_bitmap { - session.update_dst_saved_conn_bitmap_version(&conn_bitmap); + session.update_dst_saved_conn_bitmap_version(conn_bitmap); } if let Some(foreign_network) = &foreign_network { - session.update_dst_saved_foreign_network_version(&foreign_network); + session.update_dst_saved_foreign_network_version(foreign_network); } } } - return false; + false } fn update_peer_info_last_update(&self) { @@ -1767,11 +1756,10 @@ impl OspfRouteRpc for RouteSessionManager { Ok(match ret { Ok(v) => v, - Err(e) => { - let mut resp = SyncRouteInfoResponse::default(); - resp.error = Some(e as i32); - resp - } + Err(e) => SyncRouteInfoResponse { + error: Some(e as i32), + ..Default::default() + }, }) } } @@ -1828,12 +1816,9 @@ impl RouteSessionManager { select! { _ = tokio::time::sleep(Duration::from_secs(1)) => {} - ret = sync_now.recv() => match ret { - Err(e) => { - tracing::debug!(?e, "session_task sync_now recv failed, ospf route may exit"); - break; - }, - _ => {} + ret = sync_now.recv() => if let Err(e) = ret { + tracing::debug!(?e, "session_task sync_now recv failed, ospf route may exit"); + break; } } } @@ -1903,7 +1888,7 @@ impl RouteSessionManager { }; !session.dst_is_initiator.load(Ordering::Relaxed) }) - .map(|x| *x) + .copied() .collect::>(); if initiator_candidates.is_empty() { @@ -1998,6 +1983,7 @@ impl RouteSessionManager { tracing::debug!(?ret, ?reason, "sync_now_broadcast.send"); } + #[allow(clippy::too_many_arguments)] async fn do_sync_route_info( &self, from_peer_id: PeerId, @@ -2034,7 +2020,7 @@ impl RouteSessionManager { } if let Some(conn_bitmap) = &conn_bitmap { - service_impl.synced_route_info.update_conn_map(&conn_bitmap); + service_impl.synced_route_info.update_conn_map(conn_bitmap); session.update_dst_saved_conn_bitmap_version(conn_bitmap); need_update_route_table = true; } @@ -2046,7 +2032,7 @@ impl RouteSessionManager { if let Some(foreign_network) = &foreign_network { service_impl .synced_route_info - .update_foreign_network(&foreign_network); + .update_foreign_network(foreign_network); session.update_dst_saved_foreign_network_version(foreign_network); } @@ -2267,7 +2253,7 @@ impl Route for PeerRoute { route.cost_latency_first = next_hop_peer_latency_first.map(|x| x.path_len as i32); route.path_latency_latency_first = next_hop_peer_latency_first.map(|x| x.path_latency); - route.feature_flag = item.feature_flag.clone(); + route.feature_flag = item.feature_flag; routes.push(route); } @@ -2455,7 +2441,7 @@ mod tests { let r_a = create_mock_route(p_a.clone()).await; let r_b = create_mock_route(p_b.clone()).await; - for r in vec![r_a.clone(), r_b.clone()].iter() { + for r in [r_a.clone(), r_b.clone()].iter() { wait_for_condition( || async { println!("route: {:?}", r.list_routes().await); @@ -2507,7 +2493,7 @@ mod tests { drop(p_b); wait_for_condition( - || async { r_a.list_routes().await.len() == 0 }, + || async { r_a.list_routes().await.is_empty() }, Duration::from_secs(5), ) .await; @@ -2531,7 +2517,7 @@ mod tests { let r_b = create_mock_route(p_b.clone()).await; let r_c = create_mock_route(p_c.clone()).await; - for r in vec![r_a.clone(), r_b.clone(), r_c.clone()].iter() { + for r in [r_a.clone(), r_b.clone(), r_c.clone()].iter() { wait_for_condition( || async { r.service_impl.synced_route_info.peer_infos.len() == 3 }, Duration::from_secs(5), @@ -2563,10 +2549,10 @@ mod tests { connect_peer_manager(p_d.clone(), p_c.clone()).await; // find the smallest peer_id, which should be a center node - let mut all_route = vec![r_a.clone(), r_b.clone(), r_c.clone(), r_d.clone()]; + let mut all_route = [r_a.clone(), r_b.clone(), r_c.clone(), r_d.clone()]; all_route.sort_by(|a, b| a.my_peer_id.cmp(&b.my_peer_id)); - let mut all_peer_mgr = vec![p_a.clone(), p_b.clone(), p_c.clone(), p_d.clone()]; - all_peer_mgr.sort_by(|a, b| a.my_peer_id().cmp(&b.my_peer_id())); + let mut all_peer_mgr = [p_a.clone(), p_b.clone(), p_c.clone(), p_d.clone()]; + all_peer_mgr.sort_by_key(|a| a.my_peer_id()); wait_for_condition( || async { all_route[0].service_impl.sessions.len() == 3 }, @@ -2664,7 +2650,7 @@ mod tests { let r_b = create_mock_route(p_b.clone()).await; let r_c = create_mock_route(p_c.clone()).await; - for r in vec![r_a.clone(), r_b.clone(), r_c.clone()].iter() { + for r in [r_a.clone(), r_b.clone(), r_c.clone()].iter() { wait_for_condition( || async { r.service_impl.synced_route_info.peer_infos.len() == 3 }, Duration::from_secs(5), @@ -2684,7 +2670,7 @@ mod tests { drop(r_c); drop(p_c); - for r in vec![r_a.clone(), r_b.clone()].iter() { + for r in [r_a.clone(), r_b.clone()].iter() { wait_for_condition( || async { r.list_routes().await.len() == 1 }, Duration::from_secs(5), @@ -2717,7 +2703,7 @@ mod tests { .await .unwrap(); wait_for_condition( - || async { r_a.list_routes().await.len() == 0 }, + || async { r_a.list_routes().await.is_empty() }, Duration::from_secs(5), ) .await; @@ -2756,7 +2742,7 @@ mod tests { // in normal mode, packet from p_c should directly forward to p_a wait_for_condition( - || async { r_d.get_next_hop(p_a.my_peer_id()).await != None }, + || async { (r_d.get_next_hop(p_a.my_peer_id()).await).is_some() }, Duration::from_secs(5), ) .await; diff --git a/easytier/src/peers/peer_rpc.rs b/easytier/src/peers/peer_rpc.rs index 26a1da51..92a45861 100644 --- a/easytier/src/peers/peer_rpc.rs +++ b/easytier/src/peers/peer_rpc.rs @@ -4,7 +4,7 @@ use futures::{SinkExt as _, StreamExt}; use tokio::task::JoinSet; use crate::{ - common::{error::Error, PeerId, stats_manager::StatsManager}, + common::{error::Error, stats_manager::StatsManager, PeerId}, proto::rpc_impl::{self, bidirect::BidirectRpcManager}, tunnel::packet_def::ZCPacket, }; @@ -47,7 +47,10 @@ impl PeerRpcManager { } } - pub fn new_with_stats_manager(tspt: impl PeerRpcManagerTransport, stats_manager: Arc) -> Self { + pub fn new_with_stats_manager( + tspt: impl PeerRpcManagerTransport, + stats_manager: Arc, + ) -> Self { Self { tspt: Arc::new(Box::new(tspt)), bidirect_rpc: BidirectRpcManager::new_with_stats_manager(stats_manager), diff --git a/easytier/src/peers/route_trait.rs b/easytier/src/peers/route_trait.rs index 83e19a30..831c2ba0 100644 --- a/easytier/src/peers/route_trait.rs +++ b/easytier/src/peers/route_trait.rs @@ -1,4 +1,7 @@ -use std::{net::{Ipv4Addr, Ipv6Addr}, sync::Arc}; +use std::{ + net::{Ipv4Addr, Ipv6Addr}, + sync::Arc, +}; use dashmap::DashMap; @@ -10,18 +13,13 @@ use crate::{ }, }; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub enum NextHopPolicy { + #[default] LeastHop, LeastCost, } -impl Default for NextHopPolicy { - fn default() -> Self { - NextHopPolicy::LeastHop - } -} - pub type ForeignNetworkRouteInfoMap = DashMap; diff --git a/easytier/src/peers/rpc_service.rs b/easytier/src/peers/rpc_service.rs index 3c83f1cb..c8fc21c6 100644 --- a/easytier/src/peers/rpc_service.rs +++ b/easytier/src/peers/rpc_service.rs @@ -40,17 +40,19 @@ impl PeerManagerRpcService { let peer_map = peer_manager.get_peer_map(); let mut peer_infos = Vec::new(); for peer in peers { - let mut peer_info = PeerInfo::default(); - peer_info.peer_id = peer; - peer_info.default_conn_id = peer_map - .get_peer_default_conn_id(peer) - .await - .map(Into::into); - peer_info.directly_connected_conns = peer_map - .get_directly_connections_by_peer_id(peer) - .into_iter() - .map(Into::into) - .collect(); + let mut peer_info = PeerInfo { + peer_id: peer, + default_conn_id: peer_map + .get_peer_default_conn_id(peer) + .await + .map(Into::into), + directly_connected_conns: peer_map + .get_directly_connections_by_peer_id(peer) + .into_iter() + .map(Into::into) + .collect(), + ..Default::default() + }; if let Some(conns) = peer_map.list_peer_conns(peer).await { peer_info.conns = conns; @@ -93,8 +95,9 @@ impl PeerManageRpc for PeerManagerRpcService { _: BaseController, _request: ListRouteRequest, // Accept request of type HelloRequest ) -> Result { - let mut reply = ListRouteResponse::default(); - reply.routes = self.peer_manager.list_routes().await; + let reply = ListRouteResponse { + routes: self.peer_manager.list_routes().await, + }; Ok(reply) } @@ -103,8 +106,9 @@ impl PeerManageRpc for PeerManagerRpcService { _: BaseController, _request: DumpRouteRequest, // Accept request of type HelloRequest ) -> Result { - let mut reply = DumpRouteResponse::default(); - reply.result = self.peer_manager.dump_route().await; + let reply = DumpRouteResponse { + result: self.peer_manager.dump_route().await, + }; Ok(reply) } diff --git a/easytier/src/peers/tests.rs b/easytier/src/peers/tests.rs index a8b984e8..fe2362d2 100644 --- a/easytier/src/peers/tests.rs +++ b/easytier/src/peers/tests.rs @@ -65,7 +65,7 @@ pub async fn wait_route_appear_with_cost( } tokio::time::sleep(std::time::Duration::from_millis(50)).await; } - return Err(Error::NotFound); + Err(Error::NotFound) } pub async fn wait_route_appear( diff --git a/easytier/src/proto/cli.rs b/easytier/src/proto/cli.rs index f551e86b..4522871c 100644 --- a/easytier/src/proto/cli.rs +++ b/easytier/src/proto/cli.rs @@ -90,7 +90,7 @@ impl PeerRoutePair { } } - pub fn get_udp_nat_type(self: &Self) -> String { + pub fn get_udp_nat_type(&self) -> String { use crate::proto::common::NatType; let mut ret = NatType::Unknown; if let Some(r) = &self.route.clone().unwrap_or_default().stun_info { diff --git a/easytier/src/proto/common.rs b/easytier/src/proto/common.rs index e30a7d7e..7a2abafb 100644 --- a/easytier/src/proto/common.rs +++ b/easytier/src/proto/common.rs @@ -38,13 +38,13 @@ impl From for Uuid { impl fmt::Display for Uuid { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", uuid::Uuid::from(self.clone())) + write!(f, "{}", uuid::Uuid::from(*self)) } } impl fmt::Debug for Uuid { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", uuid::Uuid::from(self.clone())) + write!(f, "{}", uuid::Uuid::from(*self)) } } @@ -62,9 +62,9 @@ impl From for std::net::Ipv4Addr { } } -impl ToString for Ipv4Addr { - fn to_string(&self) -> String { - std::net::Ipv4Addr::from(self.addr).to_string() +impl Display for Ipv4Addr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", std::net::Ipv4Addr::from(self.addr)) } } @@ -93,9 +93,9 @@ impl From for std::net::Ipv6Addr { } } -impl ToString for Ipv6Addr { - fn to_string(&self) -> String { - std::net::Ipv6Addr::from(self.clone()).to_string() +impl Display for Ipv6Addr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", std::net::Ipv6Addr::from(*self)) } } @@ -120,7 +120,7 @@ impl From for cidr::Ipv4Inet { impl fmt::Display for Ipv4Inet { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", cidr::Ipv4Inet::from(self.clone())) + write!(f, "{}", cidr::Ipv4Inet::from(*self)) } } @@ -155,7 +155,7 @@ impl From for cidr::Ipv6Inet { impl fmt::Display for Ipv6Inet { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", cidr::Ipv6Inet::from(self.clone())) + write!(f, "{}", cidr::Ipv6Inet::from(*self)) } } @@ -194,7 +194,7 @@ impl From for cidr::IpInet { impl Display for IpInet { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", cidr::IpInet::from(self.clone())) + write!(f, "{}", cidr::IpInet::from(*self)) } } @@ -240,11 +240,11 @@ impl From for SocketAddr { fn from(value: std::net::SocketAddr) -> Self { match value { std::net::SocketAddr::V4(v4) => SocketAddr { - ip: Some(socket_addr::Ip::Ipv4(v4.ip().clone().into())), + ip: Some(socket_addr::Ip::Ipv4((*v4.ip()).into())), port: v4.port() as u32, }, std::net::SocketAddr::V6(v6) => SocketAddr { - ip: Some(socket_addr::Ip::Ipv6(v6.ip().clone().into())), + ip: Some(socket_addr::Ip::Ipv6((*v6.ip()).into())), port: v6.port() as u32, }, } @@ -271,9 +271,9 @@ impl From for std::net::SocketAddr { } } -impl ToString for SocketAddr { - fn to_string(&self) -> String { - std::net::SocketAddr::from(self.clone()).to_string() +impl Display for SocketAddr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", std::net::SocketAddr::from(*self)) } } @@ -302,14 +302,14 @@ impl TryFrom for CompressionAlgoPb { impl fmt::Debug for Ipv4Addr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let std_ipv4_addr = std::net::Ipv4Addr::from(self.clone()); + let std_ipv4_addr = std::net::Ipv4Addr::from(*self); write!(f, "{}", std_ipv4_addr) } } impl fmt::Debug for Ipv6Addr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let std_ipv6_addr = std::net::Ipv6Addr::from(self.clone()); + let std_ipv6_addr = std::net::Ipv6Addr::from(*self); write!(f, "{}", std_ipv6_addr) } } diff --git a/easytier/src/proto/error.rs b/easytier/src/proto/error.rs index b2cb2d35..d5d6607e 100644 --- a/easytier/src/proto/error.rs +++ b/easytier/src/proto/error.rs @@ -1,3 +1,5 @@ +#![allow(clippy::module_inception)] + use prost::DecodeError; use super::rpc_types; diff --git a/easytier/src/proto/rpc_impl/bidirect.rs b/easytier/src/proto/rpc_impl/bidirect.rs index b2ad47fa..ab55b8ed 100644 --- a/easytier/src/proto/rpc_impl/bidirect.rs +++ b/easytier/src/proto/rpc_impl/bidirect.rs @@ -24,6 +24,12 @@ pub struct BidirectRpcManager { tasks: Mutex>>, } +impl Default for BidirectRpcManager { + fn default() -> Self { + Self::new() + } +} + impl BidirectRpcManager { pub fn new() -> Self { Self { @@ -42,7 +48,10 @@ impl BidirectRpcManager { pub fn new_with_stats_manager(stats_manager: Arc) -> Self { Self { rpc_client: Client::new_with_stats_manager(stats_manager.clone()), - rpc_server: Server::new_with_registry_and_stats_manager(Arc::new(ServiceRegistry::new()), stats_manager), + rpc_server: Server::new_with_registry_and_stats_manager( + Arc::new(ServiceRegistry::new()), + stats_manager, + ), rx_timeout: None, error: Arc::new(Mutex::new(None)), @@ -176,7 +185,7 @@ impl BidirectRpcManager { return; }; tasks.abort_all(); - while let Some(_) = tasks.join_next().await {} + while tasks.join_next().await.is_some() {} } pub fn take_error(&self) -> Option { @@ -187,7 +196,7 @@ impl BidirectRpcManager { let Some(mut tasks) = self.tasks.lock().unwrap().take() else { return; }; - while let Some(_) = tasks.join_next().await { + while tasks.join_next().await.is_some() { // when any task is done, abort all tasks tasks.abort_all(); } diff --git a/easytier/src/proto/rpc_impl/client.rs b/easytier/src/proto/rpc_impl/client.rs index b03727ec..d1763386 100644 --- a/easytier/src/proto/rpc_impl/client.rs +++ b/easytier/src/proto/rpc_impl/client.rs @@ -18,7 +18,9 @@ use crate::defer; use crate::proto::common::{ CompressionAlgoPb, RpcCompressionInfo, RpcDescriptor, RpcPacket, RpcRequest, RpcResponse, }; -use crate::proto::rpc_impl::packet::{build_rpc_packet, compress_packet, decompress_packet}; +use crate::proto::rpc_impl::packet::{ + build_rpc_packet, compress_packet, decompress_packet, BuildRpcPacketArgs, +}; use crate::proto::rpc_types::controller::Controller; use crate::proto::rpc_types::descriptor::MethodDescriptor; use crate::proto::rpc_types::{ @@ -53,6 +55,15 @@ struct InflightRequest { start_time: std::time::Instant, } +impl std::fmt::Debug for InflightRequest { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("InflightRequest") + .field("sender", &self.sender) + .field("start_time", &self.start_time) + .finish() + } +} + #[derive(Debug, Clone, Default)] pub struct PeerInfo { pub peer_id: PeerId, @@ -72,6 +83,12 @@ pub struct Client { stats_manager: Option>, } +impl Default for Client { + fn default() -> Self { + Self::new() + } +} + impl Client { pub fn new() -> Self { let (ring_a, ring_b) = create_ring_tunnel_pair(); @@ -86,15 +103,9 @@ impl Client { } pub fn new_with_stats_manager(stats_manager: Arc) -> Self { - let (ring_a, ring_b) = create_ring_tunnel_pair(); - Self { - mpsc: Mutex::new(MpscTunnel::new(ring_a, None)), - transport: Mutex::new(MpscTunnel::new(ring_b, None)), - inflight_requests: Arc::new(DashMap::new()), - peer_info: Arc::new(DashMap::new()), - tasks: Mutex::new(JoinSet::new()), - stats_manager: Some(stats_manager), - } + let mut ret = Self::new(); + ret.stats_manager = Some(stats_manager); + ret } pub fn get_transport_sink(&self) -> MpscTunnelSender { @@ -151,7 +162,11 @@ impl Client { }; let Some(mut inflight_request) = inflight_requests.get_mut(&key) else { - tracing::warn!(?key, "No inflight request found for key"); + tracing::warn!( + ?key, + ?inflight_requests, + "No inflight request found for key" + ); continue; }; @@ -276,19 +291,19 @@ impl Client { .await .unwrap(); - let packets = build_rpc_packet( - self.from_peer_id, - self.to_peer_id, + let packets = build_rpc_packet(BuildRpcPacketArgs { + from_peer: self.from_peer_id, + to_peer: self.to_peer_id, rpc_desc, transaction_id, - true, - &buf, - ctrl.trace_id(), - RpcCompressionInfo { + is_req: true, + content: &buf, + trace_id: ctrl.trace_id(), + compression_info: RpcCompressionInfo { algo: c_algo.into(), accepted_algo: CompressionAlgoPb::Zstd.into(), }, - ); + }); let timeout_dur = std::time::Duration::from_millis(ctrl.timeout_ms() as u64); let mut rpc_packet = timeout(timeout_dur, self.do_rpc(packets, &mut rx)).await??; @@ -298,7 +313,7 @@ impl Client { self.to_peer_id, PeerInfo { peer_id: self.to_peer_id, - compression_info: compression_info.clone(), + compression_info, last_active: Some(std::time::Instant::now()), }, ); diff --git a/easytier/src/proto/rpc_impl/packet.rs b/easytier/src/proto/rpc_impl/packet.rs index 9f87111f..12280538 100644 --- a/easytier/src/proto/rpc_impl/packet.rs +++ b/easytier/src/proto/rpc_impl/packet.rs @@ -21,7 +21,7 @@ pub async fn compress_packet( let algo = accepted_compression_algo .try_into() .unwrap_or(CompressorAlgo::None); - let compressed = compressor.compress_raw(&content, algo).await?; + let compressed = compressor.compress_raw(content, algo).await?; if compressed.len() >= content.len() { Ok((content.to_vec(), CompressionAlgoPb::None)) } else { @@ -35,7 +35,7 @@ pub async fn decompress_packet( ) -> Result, Error> { let compressor = DefaultCompressor::new(); let algo = compression_algo.try_into()?; - let decompressed = compressor.decompress_raw(&content, algo).await?; + let decompressed = compressor.decompress_raw(content, algo).await?; Ok(decompressed) } @@ -45,6 +45,12 @@ pub struct PacketMerger { last_updated: std::time::Instant, } +impl Default for PacketMerger { + fn default() -> Self { + Self::new() + } +} + impl PacketMerger { pub fn new() -> Self { Self { @@ -133,55 +139,57 @@ impl PacketMerger { } } -pub fn build_rpc_packet( - from_peer: PeerId, - to_peer: PeerId, - rpc_desc: RpcDescriptor, - transaction_id: RpcTransactId, - is_req: bool, - content: &Vec, - trace_id: i32, - compression_info: RpcCompressionInfo, -) -> Vec { +pub struct BuildRpcPacketArgs<'a> { + pub from_peer: PeerId, + pub to_peer: PeerId, + pub rpc_desc: RpcDescriptor, + pub transaction_id: RpcTransactId, + pub is_req: bool, + pub content: &'a [u8], + pub trace_id: i32, + pub compression_info: RpcCompressionInfo, +} + +pub fn build_rpc_packet(args: BuildRpcPacketArgs<'_>) -> Vec { let mut ret = Vec::new(); let content_mtu = RPC_PACKET_CONTENT_MTU; - let total_pieces = (content.len() + content_mtu - 1) / content_mtu; + let total_pieces = args.content.len().div_ceil(content_mtu); let mut cur_offset = 0; - while cur_offset < content.len() || content.len() == 0 { + while cur_offset < args.content.len() || args.content.is_empty() { let mut cur_len = content_mtu; - if cur_offset + cur_len > content.len() { - cur_len = content.len() - cur_offset; + if cur_offset + cur_len > args.content.len() { + cur_len = args.content.len() - cur_offset; } let mut cur_content = Vec::new(); - cur_content.extend_from_slice(&content[cur_offset..cur_offset + cur_len]); + cur_content.extend_from_slice(&args.content[cur_offset..cur_offset + cur_len]); let cur_packet = RpcPacket { - from_peer, - to_peer, + from_peer: args.from_peer, + to_peer: args.to_peer, descriptor: if cur_offset == 0 - || compression_info.algo == CompressionAlgoPb::None as i32 + || args.compression_info.algo == CompressionAlgoPb::None as i32 { // old version must have descriptor on every piece - Some(rpc_desc.clone()) + Some(args.rpc_desc.clone()) } else { None }, - is_request: is_req, + is_request: args.is_req, total_pieces: total_pieces as u32, - piece_idx: (cur_offset / content_mtu) as u32, - transaction_id, + piece_idx: (cur_offset / RPC_PACKET_CONTENT_MTU) as u32, + transaction_id: args.transaction_id, body: cur_content, - trace_id, + trace_id: args.trace_id, compression_info: if cur_offset == 0 { - Some(compression_info.clone()) + Some(args.compression_info) } else { None }, }; cur_offset += cur_len; - let packet_type = if is_req { + let packet_type = if args.is_req { PacketType::RpcReq } else { PacketType::RpcResp @@ -190,10 +198,10 @@ pub fn build_rpc_packet( let mut buf = Vec::new(); cur_packet.encode(&mut buf).unwrap(); let mut zc_packet = ZCPacket::new_with_payload(&buf); - zc_packet.fill_peer_manager_hdr(from_peer, to_peer, packet_type as u8); + zc_packet.fill_peer_manager_hdr(args.from_peer, args.to_peer, packet_type as u8); ret.push(zc_packet); - if content.len() == 0 { + if args.content.is_empty() { break; } } diff --git a/easytier/src/proto/rpc_impl/server.rs b/easytier/src/proto/rpc_impl/server.rs index 39b8240d..c91ebfdb 100644 --- a/easytier/src/proto/rpc_impl/server.rs +++ b/easytier/src/proto/rpc_impl/server.rs @@ -20,6 +20,7 @@ use crate::{ self, CompressionAlgoPb, RpcCompressionInfo, RpcPacket, RpcRequest, RpcResponse, TunnelInfo, }, + rpc_impl::packet::BuildRpcPacketArgs, rpc_types::{controller::Controller, error::Result}, }, tunnel::{ @@ -53,6 +54,12 @@ pub struct Server { stats_manager: Option>, } +impl Default for Server { + fn default() -> Self { + Self::new() + } +} + impl Server { pub fn new() -> Self { Server::new_with_registry(Arc::new(ServiceRegistry::new())) @@ -139,10 +146,7 @@ impl Server { tracing::trace!(?key, ?packet, "Received request packet"); - let ret = packet_merges - .entry(key.clone()) - .or_insert_with(PacketMerger::new) - .feed(packet); + let ret = packet_merges.entry(key.clone()).or_default().feed(packet); match ret { Ok(Some(packet)) => { @@ -238,7 +242,7 @@ impl Server { let mut resp_msg = RpcResponse::default(); let now = std::time::Instant::now(); - let compression_info = packet.compression_info.clone(); + let compression_info = packet.compression_info; let resp_bytes = Self::handle_rpc_request(packet, reg, tunnel_info).await; match &resp_bytes { @@ -290,19 +294,19 @@ impl Server { .await .unwrap(); - let packets = build_rpc_packet( - to_peer, - from_peer, - desc, + let packets = build_rpc_packet(BuildRpcPacketArgs { + from_peer: to_peer, + to_peer: from_peer, + rpc_desc: desc, transaction_id, - false, - &compressed_resp, + is_req: false, + content: &compressed_resp, trace_id, - RpcCompressionInfo { + compression_info: RpcCompressionInfo { algo: algo.into(), accepted_algo: CompressionAlgoPb::Zstd.into(), }, - ); + }); for packet in packets { if let Err(err) = sender.send(packet).await { diff --git a/easytier/src/proto/rpc_impl/service_registry.rs b/easytier/src/proto/rpc_impl/service_registry.rs index cc6fbb59..14305282 100644 --- a/easytier/src/proto/rpc_impl/service_registry.rs +++ b/easytier/src/proto/rpc_impl/service_registry.rs @@ -52,6 +52,12 @@ pub struct ServiceRegistry { table: DashMap, } +impl Default for ServiceRegistry { + fn default() -> Self { + Self::new() + } +} + impl ServiceRegistry { pub fn new() -> Self { Self { diff --git a/easytier/src/proto/rpc_types/handler.rs b/easytier/src/proto/rpc_types/handler.rs index 05705497..7a2c531e 100644 --- a/easytier/src/proto/rpc_types/handler.rs +++ b/easytier/src/proto/rpc_types/handler.rs @@ -17,7 +17,6 @@ pub trait Handler: Clone + Send + Sync + 'static { type Descriptor: descriptor::ServiceDescriptor + Default; type Controller: super::controller::Controller; - /// /// Perform a raw call to the specified service and method. async fn call( diff --git a/easytier/src/proto/tests.rs b/easytier/src/proto/tests.rs index eff4bdd9..b161a11e 100644 --- a/easytier/src/proto/tests.rs +++ b/easytier/src/proto/tests.rs @@ -233,8 +233,10 @@ async fn rpc_tunnel_stuck_test() { let out = client.scoped_client::>(1, 1, "test".to_string()); tasks.spawn(async move { - let mut ctrl = RpcController::default(); - ctrl.timeout_ms = 1000; + let ctrl = RpcController { + timeout_ms: 1000, + ..Default::default() + }; let input = SayHelloRequest { name: "world".to_string(), @@ -263,8 +265,10 @@ async fn rpc_tunnel_stuck_test() { let out = client.scoped_client::>(1, 1, "test".to_string()); - let mut ctrl = RpcController::default(); - ctrl.timeout_ms = 1000; + let ctrl = RpcController { + timeout_ms: 1000, + ..Default::default() + }; let input = SayHelloRequest { name: "fuck world".to_string(), }; diff --git a/easytier/src/tests/mod.rs b/easytier/src/tests/mod.rs index ad5bb5a0..4c81fad9 100644 --- a/easytier/src/tests/mod.rs +++ b/easytier/src/tests/mod.rs @@ -154,7 +154,6 @@ async fn wait_proxy_route_appear( let now = std::time::Instant::now(); loop { for r in mgr.list_routes().await.iter() { - let r = r; if r.proxy_cidrs.contains(&proxy_cidr.to_owned()) { assert_eq!(r.peer_id, dst_peer_id); assert_eq!(r.ipv4_addr, Some(ipv4.parse().unwrap())); diff --git a/easytier/src/tests/three_node.rs b/easytier/src/tests/three_node.rs index 4c314037..3c529e68 100644 --- a/easytier/src/tests/three_node.rs +++ b/easytier/src/tests/three_node.rs @@ -1,3 +1,5 @@ +#![allow(clippy::too_many_arguments)] + use core::panic; use std::{ sync::{atomic::AtomicU32, Arc}, @@ -214,13 +216,13 @@ pub async fn drop_insts(insts: Vec) { debug_assert_eq!(pm.strong_count(), 0, "PeerManager should be dropped"); }); } - while let Some(_) = set.join_next().await {} + while set.join_next().await.is_some() {} } async fn ping_test(from_netns: &str, target_ip: &str, payload_size: Option) -> bool { let _g = NetNS::new(Some(ROOT_NETNS_NAME.to_owned())).guard(); let code = tokio::process::Command::new("ip") - .args(&[ + .args([ "netns", "exec", from_netns, @@ -244,7 +246,7 @@ async fn ping_test(from_netns: &str, target_ip: &str, payload_size: Option) -> bool { let _g = NetNS::new(Some(ROOT_NETNS_NAME.to_owned())).guard(); let code = tokio::process::Command::new("ip") - .args(&[ + .args([ "netns", "exec", from_netns, @@ -364,7 +366,7 @@ async fn subnet_proxy_test_udp(target_ip: &str) { let udp_connector = UdpTunnelConnector::new(format!("udp://{}:22233", target_ip).parse().unwrap()); - let mut buf = vec![0; 1 * 1024]; + let mut buf = vec![0; 1024]; rand::thread_rng().fill(&mut buf[..]); _tunnel_pingpong_netns( @@ -397,7 +399,7 @@ async fn subnet_proxy_test_udp(target_ip: &str) { let udp_listener = UdpTunnelListener::new("udp://0.0.0.0:22235".parse().unwrap()); let udp_connector = UdpTunnelConnector::new("udp://10.144.144.3:22235".parse().unwrap()); - let mut buf = vec![0; 1 * 1024]; + let mut buf = vec![0; 1024]; rand::thread_rng().fill(&mut buf[..]); _tunnel_pingpong_netns( @@ -690,8 +692,7 @@ pub async fn proxy_three_node_disconnect_test(#[values("tcp", "wg")] proto: &str .list_routes() .await .iter() - .find(|r| r.peer_id == inst4.peer_id()) - .is_some() + .any(|r| r.peer_id == inst4.peer_id()) }, Duration::from_secs(8), ) @@ -706,14 +707,13 @@ pub async fn proxy_three_node_disconnect_test(#[values("tcp", "wg")] proto: &str })); wait_for_condition( || async { - let ret = insts[2] + let ret = !insts[2] .get_peer_manager() .get_peer_map() .list_peers_with_conn() .await .iter() - .find(|r| **r == inst4.peer_id()) - .is_none(); + .any(|r| *r == inst4.peer_id()); ret }, @@ -726,13 +726,12 @@ pub async fn proxy_three_node_disconnect_test(#[values("tcp", "wg")] proto: &str wait_for_condition( || async { - insts[0] + !insts[0] .get_peer_manager() .list_routes() .await .iter() - .find(|r| r.peer_id == inst4.peer_id()) - .is_none() + .any(|r| r.peer_id == inst4.peer_id()) }, Duration::from_secs(7), ) @@ -788,9 +787,8 @@ pub async fn udp_broadcast_test() { // socket.connect(("10.144.144.255", 22111)).await.unwrap(); let call: Vec = vec![1; 1024]; println!("Sending call, {} bytes", call.len()); - match socket.send_to(&call, "10.144.144.255:22111").await { - Err(e) => panic!("Error sending call: {:?}", e), - _ => {} + if let Err(e) = socket.send_to(&call, "10.144.144.255:22111").await { + panic!("Error sending call: {:?}", e) } tokio::time::sleep(tokio::time::Duration::from_secs(2)).await; @@ -1163,7 +1161,7 @@ pub async fn manual_reconnector(#[values(true, false)] is_foreign: bool) { let conns = peer_map.list_peer_conns(center_inst_peer_id).await.unwrap(); - assert!(conns.len() >= 1); + assert!(!conns.is_empty()); wait_for_condition( || async { ping_test("net_b", "10.144.145.2", None).await }, @@ -1405,39 +1403,47 @@ pub async fn acl_rule_test_inbound( let mut acl = Acl::default(); let mut acl_v1 = AclV1::default(); - let mut chain = Chain::default(); - chain.name = "test_inbound".to_string(); - chain.chain_type = ChainType::Inbound as i32; - chain.enabled = true; + let mut chain = Chain { + name: "test_inbound".to_string(), + chain_type: ChainType::Inbound as i32, + enabled: true, + ..Default::default() + }; // 禁止 8080 - let mut deny_rule = Rule::default(); - deny_rule.name = "deny_8080".to_string(); - deny_rule.priority = 200; - deny_rule.enabled = true; - deny_rule.action = Action::Drop as i32; - deny_rule.protocol = Protocol::Any as i32; - deny_rule.ports = vec!["8080".to_string()]; + let deny_rule = Rule { + name: "deny_8080".to_string(), + priority: 200, + enabled: true, + action: Action::Drop as i32, + protocol: Protocol::Any as i32, + ports: vec!["8080".to_string()], + ..Default::default() + }; chain.rules.push(deny_rule); // 允许其他 - let mut allow_rule = Rule::default(); - allow_rule.name = "allow_all".to_string(); - allow_rule.priority = 100; - allow_rule.enabled = true; - allow_rule.action = Action::Allow as i32; - allow_rule.protocol = Protocol::Any as i32; - allow_rule.stateful = true; + let allow_rule = Rule { + name: "allow_all".to_string(), + priority: 100, + enabled: true, + action: Action::Allow as i32, + protocol: Protocol::Any as i32, + stateful: true, + ..Default::default() + }; chain.rules.push(allow_rule); // 禁止 src ip 为 10.144.144.2 的流量 - let mut deny_rule = Rule::default(); - deny_rule.name = "deny_10.144.144.2".to_string(); - deny_rule.priority = 200; - deny_rule.enabled = true; - deny_rule.action = Action::Drop as i32; - deny_rule.protocol = Protocol::Any as i32; - deny_rule.source_ips = vec!["10.144.144.2/32".to_string()]; + let deny_rule = Rule { + name: "deny_10.144.144.2".to_string(), + priority: 200, + enabled: true, + action: Action::Drop as i32, + protocol: Protocol::Any as i32, + source_ips: vec!["10.144.144.2/32".to_string()], + ..Default::default() + }; chain.rules.push(deny_rule); acl_v1.chains.push(chain); @@ -1626,42 +1632,50 @@ pub async fn acl_rule_test_subnet_proxy( let mut acl = Acl::default(); let mut acl_v1 = AclV1::default(); - let mut chain = Chain::default(); - chain.name = "test_subnet_proxy_inbound".to_string(); - chain.chain_type = ChainType::Forward as i32; - chain.enabled = true; + let mut chain = Chain { + name: "test_subnet_proxy_inbound".to_string(), + chain_type: ChainType::Forward as i32, + enabled: true, + ..Default::default() + }; // 禁止访问子网代理中的 8080 端口 - let mut deny_rule = Rule::default(); - deny_rule.name = "deny_subnet_8080".to_string(); - deny_rule.priority = 200; - deny_rule.enabled = true; - deny_rule.action = Action::Drop as i32; - deny_rule.protocol = Protocol::Any as i32; - deny_rule.ports = vec!["8080".to_string()]; - deny_rule.destination_ips = vec!["10.1.2.0/24".to_string()]; + let deny_rule = Rule { + name: "deny_subnet_8080".to_string(), + priority: 200, + enabled: true, + action: Action::Drop as i32, + protocol: Protocol::Any as i32, + ports: vec!["8080".to_string()], + destination_ips: vec!["10.1.2.0/24".to_string()], + ..Default::default() + }; chain.rules.push(deny_rule); // 禁止来自 inst1 (10.144.144.1) 访问子网代理中的 8081 端口 - let mut deny_src_rule = Rule::default(); - deny_src_rule.name = "deny_inst1_to_subnet_8081".to_string(); - deny_src_rule.priority = 200; - deny_src_rule.enabled = true; - deny_src_rule.action = Action::Drop as i32; - deny_src_rule.protocol = Protocol::Any as i32; - deny_src_rule.ports = vec!["8081".to_string()]; - deny_src_rule.source_ips = vec!["10.144.144.1/32".to_string()]; - deny_src_rule.destination_ips = vec!["10.1.2.0/24".to_string()]; + let deny_src_rule = Rule { + name: "deny_inst1_to_subnet_8081".to_string(), + priority: 200, + enabled: true, + action: Action::Drop as i32, + protocol: Protocol::Any as i32, + ports: vec!["8081".to_string()], + source_ips: vec!["10.144.144.1/32".to_string()], + destination_ips: vec!["10.1.2.0/24".to_string()], + ..Default::default() + }; chain.rules.push(deny_src_rule); // 允许其他流量 - let mut allow_rule = Rule::default(); - allow_rule.name = "allow_all".to_string(); - allow_rule.priority = 100; - allow_rule.enabled = true; - allow_rule.action = Action::Allow as i32; - allow_rule.protocol = Protocol::Any as i32; - allow_rule.stateful = true; + let allow_rule = Rule { + name: "allow_all".to_string(), + priority: 100, + enabled: true, + action: Action::Allow as i32, + protocol: Protocol::Any as i32, + stateful: true, + ..Default::default() + }; chain.rules.push(allow_rule); acl_v1.chains.push(chain); diff --git a/easytier/src/tunnel/common.rs b/easytier/src/tunnel/common.rs index f0ea3b8a..8d26db78 100644 --- a/easytier/src/tunnel/common.rs +++ b/easytier/src/tunnel/common.rs @@ -145,8 +145,7 @@ where return Poll::Ready(None); } - while let Some(packet) = - Self::extract_one_packet(self_mut.buf, *self_mut.max_packet_size) + if let Some(packet) = Self::extract_one_packet(self_mut.buf, *self_mut.max_packet_size) { if let Err(TunnelError::InvalidPacket(msg)) = packet.as_ref() { self_mut @@ -157,7 +156,7 @@ where } reserve_buf( - &mut self_mut.buf, + self_mut.buf, *self_mut.max_packet_size, *self_mut.max_packet_size * 2, ); @@ -186,12 +185,12 @@ where } pub trait ZCPacketToBytes { - fn into_bytes(&self, zc_packet: ZCPacket) -> Result; + fn zcpacket_into_bytes(&self, zc_packet: ZCPacket) -> Result; } pub struct TcpZCPacketToBytes; impl ZCPacketToBytes for TcpZCPacketToBytes { - fn into_bytes(&self, item: ZCPacket) -> Result { + fn zcpacket_into_bytes(&self, item: ZCPacket) -> Result { let mut item = item.convert_type(ZCPacketType::TCP); let tcp_len = PEER_MANAGER_HEADER_SIZE + item.payload_len(); @@ -280,7 +279,9 @@ where fn start_send(self: Pin<&mut Self>, item: ZCPacket) -> Result<(), Self::Error> { let pinned = self.project(); - pinned.sending_bufs.push(pinned.converter.into_bytes(item)?); + pinned + .sending_bufs + .push(pinned.converter.zcpacket_into_bytes(item)?); Ok(()) } @@ -461,14 +462,13 @@ pub mod tests { continue; }; tracing::debug!(?msg, "recv a msg, try echo back"); - if let Err(_) = send.send(msg).await { + if send.send(msg).await.is_err() { break; } } } else { let Some(ret) = recv.next().await else { - assert!(false, "recv error"); - return; + panic!("recv error"); }; if ret.is_err() { @@ -597,7 +597,7 @@ pub mod tests { let elapsed_sec = now.elapsed().as_secs(); if elapsed_sec > 0 { bps_clone.store( - count as u64 / now.elapsed().as_secs() as u64, + count as u64 / now.elapsed().as_secs(), std::sync::atomic::Ordering::Relaxed, ); } @@ -621,7 +621,7 @@ pub mod tests { while now.elapsed().as_secs() < 10 { // send.feed(item) let item = ZCPacket::new_with_payload(send_buf.as_ref()); - let _ = send.feed(item).await.unwrap(); + send.feed(item).await.unwrap(); } send.close().await.unwrap(); @@ -649,7 +649,7 @@ pub mod tests { .init(); } - pub async fn wait_for_condition(mut condition: F, timeout: std::time::Duration) -> () + pub async fn wait_for_condition(mut condition: F, timeout: std::time::Duration) where F: FnMut() -> FRet + Send, FRet: Future, diff --git a/easytier/src/tunnel/filter.rs b/easytier/src/tunnel/filter.rs index da588f27..2d1cf7f0 100644 --- a/easytier/src/tunnel/filter.rs +++ b/easytier/src/tunnel/filter.rs @@ -227,7 +227,7 @@ impl TunnelFilter for PacketRecorderTunnelFilter { fn after_received(&self, data: StreamItem) -> Option { match data { Ok(v) => { - self.sent.lock().unwrap().push(v.clone().into()); + self.sent.lock().unwrap().push(v.clone()); Some(Ok(v)) } Err(e) => Some(Err(e)), @@ -242,6 +242,12 @@ impl TunnelFilter for PacketRecorderTunnelFilter { } } +impl Default for PacketRecorderTunnelFilter { + fn default() -> Self { + Self::new() + } +} + impl PacketRecorderTunnelFilter { pub fn new() -> Self { Self { @@ -278,6 +284,12 @@ impl TunnelFilter for StatsRecorderTunnelFilter { } } +impl Default for StatsRecorderTunnelFilter { + fn default() -> Self { + Self::new() + } +} + impl StatsRecorderTunnelFilter { pub fn new() -> Self { Self { diff --git a/easytier/src/tunnel/mod.rs b/easytier/src/tunnel/mod.rs index cc39a858..5139f9af 100644 --- a/easytier/src/tunnel/mod.rs +++ b/easytier/src/tunnel/mod.rs @@ -90,9 +90,11 @@ impl ZCPacketStream for T where T: Stream + Send {} pub trait ZCPacketSink: Sink + Send {} impl ZCPacketSink for T where T: Sink + Send {} +pub type SplitTunnel = (Pin>, Pin>); + #[auto_impl::auto_impl(Box, Arc)] pub trait Tunnel: Send { - fn split(&self) -> (Pin>, Pin>); + fn split(&self) -> SplitTunnel; fn info(&self) -> Option; } @@ -189,7 +191,7 @@ where return Err(TunnelError::InvalidProtocol(url.scheme().to_string())); } - Ok(T::from_url(url.clone(), ip_version).await?) + T::from_url(url.clone(), ip_version).await } fn default_port(scheme: &str) -> Option { @@ -269,7 +271,7 @@ impl TunnelUrl { if s.is_empty() { None } else { - Some(String::from_utf8(percent_encoding::percent_decode_str(&s).collect()).unwrap()) + Some(String::from_utf8(percent_encoding::percent_decode_str(s).collect()).unwrap()) } }) } diff --git a/easytier/src/tunnel/mpsc.rs b/easytier/src/tunnel/mpsc.rs index dec73796..b6087294 100644 --- a/easytier/src/tunnel/mpsc.rs +++ b/easytier/src/tunnel/mpsc.rs @@ -86,12 +86,9 @@ impl MpscTunnel { sink.feed(initial_item).await?; while let Ok(item) = rx.try_recv() { - match sink.feed(item).await { - Err(e) => { - tracing::error!(?e, "feed error"); - return Err(e); - } - Ok(_) => {} + if let Err(e) = sink.feed(item).await { + tracing::error!(?e, "feed error"); + return Err(e); } } diff --git a/easytier/src/tunnel/packet_def.rs b/easytier/src/tunnel/packet_def.rs index a50da6f6..54c5f850 100644 --- a/easytier/src/tunnel/packet_def.rs +++ b/easytier/src/tunnel/packet_def.rs @@ -423,7 +423,7 @@ impl ZCPacket { let total_len = payload_off + payload.len(); ret.inner.reserve(total_len); unsafe { ret.inner.set_len(total_len) }; - ret.mut_payload()[..payload.len()].copy_from_slice(&payload); + ret.mut_payload()[..payload.len()].copy_from_slice(payload); ret } @@ -440,7 +440,7 @@ impl ZCPacket { dst_peer_id: u32, foreign_zc_packet: &ZCPacket, ) -> Self { - let foreign_network_hdr = ForeignNetworkPacketHeader::new(dst_peer_id, &network_name); + let foreign_network_hdr = ForeignNetworkPacketHeader::new(dst_peer_id, network_name); let total_payload_len = foreign_network_hdr.get_header_len() + foreign_zc_packet.tunnel_payload().len(); @@ -639,7 +639,7 @@ impl ZCPacket { return Self::new_from_buf(buf, target_packet_type); } - return Self::new_from_buf(self.inner.split_off(new_offset), target_packet_type); + Self::new_from_buf(self.inner.split_off(new_offset), target_packet_type) } pub fn into_bytes(self) -> Bytes { @@ -656,7 +656,7 @@ impl ZCPacket { pub fn is_lossy(&self) -> bool { self.peer_manager_header() - .and_then(|hdr| Some(hdr.packet_type == PacketType::Data as u8)) + .map(|hdr| hdr.packet_type == PacketType::Data as u8) .unwrap_or(false) } diff --git a/easytier/src/tunnel/quic.rs b/easytier/src/tunnel/quic.rs index 559f226c..b72ea6b4 100644 --- a/easytier/src/tunnel/quic.rs +++ b/easytier/src/tunnel/quic.rs @@ -90,8 +90,8 @@ impl AsyncUdpSocket for NoGroAsyncUdpSocket { pub fn make_server_endpoint(bind_addr: SocketAddr) -> Result<(Endpoint, Vec), Box> { let (server_config, server_cert) = configure_server()?; let socket = std::net::UdpSocket::bind(bind_addr)?; - let runtime = quinn::default_runtime() - .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::Other, "no async runtime found"))?; + let runtime = + quinn::default_runtime().ok_or_else(|| std::io::Error::other("no async runtime found"))?; let mut endpoint_config = EndpointConfig::default(); endpoint_config.max_udp_payload_size(1200)?; let socket = NoGroAsyncUdpSocket { @@ -110,7 +110,7 @@ pub fn make_server_endpoint(bind_addr: SocketAddr) -> Result<(Endpoint, Vec) pub fn configure_server() -> Result<(ServerConfig, Vec), Box> { let (certs, key) = get_insecure_tls_cert(); - let mut server_config = ServerConfig::with_single_cert(certs.clone(), key.into())?; + let mut server_config = ServerConfig::with_single_cert(certs.clone(), key)?; let transport_config = Arc::get_mut(&mut server_config.transport).unwrap(); transport_config.max_concurrent_uni_streams(10_u8.into()); transport_config.max_concurrent_bidi_streams(10_u8.into()); @@ -123,8 +123,6 @@ pub fn configure_server() -> Result<(ServerConfig, Vec), Box> { #[allow(unused)] pub const ALPN_QUIC_HTTP: &[&[u8]] = &[b"hq-29"]; -/// Runs a QUIC server bound to given address. - struct ConnWrapper { conn: Connection, } diff --git a/easytier/src/tunnel/ring.rs b/easytier/src/tunnel/ring.rs index d834a091..269f3ce4 100644 --- a/easytier/src/tunnel/ring.rs +++ b/easytier/src/tunnel/ring.rs @@ -47,7 +47,7 @@ impl RingTunnel { let ring_impl = AsyncHeapRb::new(std::cmp::max(RING_TUNNEL_RESERVERD_CAP * 2, cap)); let (ring_prod_impl, ring_cons_impl) = ring_impl.split(); Self { - id: id.clone(), + id, ring_cons_impl: AtomicCell::new(Some(ring_cons_impl)), ring_prod_impl: AtomicCell::new(Some(ring_prod_impl)), } @@ -74,7 +74,7 @@ pub struct RingStream { impl RingStream { pub fn new(tunnel: Arc) -> Self { Self { - id: tunnel.id.clone(), + id: tunnel.id, ring_cons_impl: tunnel.ring_cons_impl.take().unwrap(), } } @@ -113,7 +113,7 @@ pub struct RingSink { impl RingSink { pub fn new(tunnel: Arc) -> Self { Self { - id: tunnel.id.clone(), + id: tunnel.id, ring_prod_impl: tunnel.ring_prod_impl.take().unwrap(), } } @@ -181,9 +181,10 @@ struct Connection { server: Arc, } -static CONNECTION_MAP: Lazy< - Arc>>>>, -> = Lazy::new(|| Arc::new(std::sync::Mutex::new(HashMap::new()))); +type ConnectionMap = HashMap>>; + +static CONNECTION_MAP: Lazy>> = + Lazy::new(|| Arc::new(std::sync::Mutex::new(HashMap::new()))); #[derive(Debug)] pub struct RingTunnelListener { @@ -315,10 +316,7 @@ impl TunnelConnector for RingTunnelConnector { tracing::info!("connecting"); let conn = Arc::new(Connection { client: Arc::new(RingTunnel::new(RING_TUNNEL_CAP)), - server: Arc::new(RingTunnel::new_with_id( - remote_addr.clone(), - RING_TUNNEL_CAP, - )), + server: Arc::new(RingTunnel::new_with_id(remote_addr, RING_TUNNEL_CAP)), }); entry .send(conn.clone()) diff --git a/easytier/src/tunnel/tcp.rs b/easytier/src/tunnel/tcp.rs index c18e2235..55226eaa 100644 --- a/easytier/src/tunnel/tcp.rs +++ b/easytier/src/tunnel/tcp.rs @@ -155,7 +155,7 @@ impl TcpTunnelConnector { tracing::info!(url = ?self.addr, ?addr, "connect tcp start, bind addrs: {:?}", self.bind_addrs); let stream = TcpStream::connect(addr).await?; tracing::info!(url = ?self.addr, ?addr, "connect tcp succ"); - return get_tunnel_with_tcp_stream(stream, self.addr.clone().into()); + get_tunnel_with_tcp_stream(stream, self.addr.clone()) } async fn connect_with_custom_bind( @@ -179,11 +179,11 @@ impl TcpTunnelConnector { } let socket = TcpSocket::from_std_stream(socket2_socket.into()); - futures.push(socket.connect(addr.clone())); + futures.push(socket.connect(addr)); } let ret = wait_for_connect_futures(futures).await; - return get_tunnel_with_tcp_stream(ret?, self.addr.clone().into()); + get_tunnel_with_tcp_stream(ret?, self.addr.clone()) } } diff --git a/easytier/src/tunnel/udp.rs b/easytier/src/tunnel/udp.rs index 422c4141..cb0cc0ea 100644 --- a/easytier/src/tunnel/udp.rs +++ b/easytier/src/tunnel/udp.rs @@ -68,7 +68,7 @@ fn new_syn_packet(conn_id: u32, magic: u64) -> ZCPacket { header.conn_id.set(conn_id); header.len.set(8); }, - Some(&mut magic.to_le_bytes()), + Some(&magic.to_le_bytes()), ) } @@ -79,7 +79,7 @@ fn new_sack_packet(conn_id: u32, magic: u64) -> ZCPacket { header.conn_id.set(conn_id); header.len.set(8); }, - Some(&mut magic.to_le_bytes()), + Some(&magic.to_le_bytes()), ) } @@ -94,7 +94,7 @@ pub fn new_hole_punch_packet(tid: u32, buf_len: u16) -> ZCPacket { header.conn_id.set(tid); header.len.set(buf_len); }, - Some(&mut buf), + Some(&buf), ) } @@ -116,7 +116,7 @@ pub fn new_v6_hole_punch_packet(dst: &SocketAddrV6) -> ZCPacket { } fn extrace_dst_addr_from_hole_punch_packet(buf: &[u8]) -> Option { - let body = V6HolePunchPacket::ref_from_prefix(&buf[..])?; + let body = V6HolePunchPacket::ref_from_prefix(buf)?; let ip = Ipv6Addr::from(body.dst_ipv6); Some(SocketAddrV6::new(ip, body.dst_port.get(), 0, 0)) } @@ -173,9 +173,7 @@ async fn respond_stun_packet( // we discard the prefix, make sure our implementation is not compatible with other stun client u32_to_tid(tid_to_u32(&tid)), ); - resp_msg.add_attribute(Attribute::XorMappedAddress(XorMappedAddress::new( - addr.clone(), - ))); + resp_msg.add_attribute(Attribute::XorMappedAddress(XorMappedAddress::new(addr))); let mut encoder = MessageEncoder::new(); let rsp_buf = encoder @@ -189,7 +187,7 @@ async fn respond_stun_packet( if !change_req { socket - .send_to(&rsp_buf, addr.clone()) + .send_to(&rsp_buf, addr) .await .with_context(|| "send stun response error")?; } else { @@ -199,7 +197,7 @@ async fn respond_stun_packet( } else { UdpSocket::bind("[::]:0").await? }; - socket.send_to(&rsp_buf, addr.clone()).await?; + socket.send_to(&rsp_buf, addr).await?; } tracing::debug!(?addr, ?req_msg, ?change_req, "udp respond stun packet done"); @@ -241,9 +239,7 @@ async fn forward_from_ring_to_udp( ) -> Option { tracing::debug!("udp forward from ring to udp"); loop { - let Some(buf) = ring_recv.next().await else { - return None; - }; + let buf = ring_recv.next().await?; let packet = match buf { Ok(v) => v, Err(e) => { @@ -271,7 +267,7 @@ async fn forward_from_ring_to_udp( async fn udp_recv_from_socket_forward_task(socket: Arc, allow_stun: bool, mut f: F) where - F: FnMut(ZCPacket, SocketAddr) -> (), + F: FnMut(ZCPacket, SocketAddr), { let mut buf = BytesMut::new(); loop { @@ -355,10 +351,8 @@ impl UdpConnection { if let Err(e) = self.ring_sender.try_send(zc_packet) { tracing::trace!(?e, "ring sender full, drop lossy packet"); } - } else { - if let Err(e) = self.ring_sender.force_send(zc_packet) { - tracing::trace!(?e, "ring sender full, drop non-lossy packet"); - } + } else if let Err(e) = self.ring_sender.force_send(zc_packet) { + tracing::trace!(?e, "ring sender full, drop non-lossy packet"); } Ok(()) @@ -389,7 +383,7 @@ impl UdpTunnelListenerData { } } - async fn handle_new_connect(self: Self, remote_addr: SocketAddr, zc_packet: ZCPacket) { + async fn handle_new_connect(self, remote_addr: SocketAddr, zc_packet: ZCPacket) { let udp_payload = zc_packet.udp_payload(); if udp_payload.len() != 8 { tracing::warn!( @@ -482,7 +476,6 @@ impl UdpTunnelListenerData { tracing::error!(?e, "udp send hole punch packet error"); } tracing::debug!(?dst_addr, "udp forward packet send hole punch packet"); - return; } else if header.msg_type != UdpPacketType::HolePunch as u8 { let Some(mut conn) = self.sock_map.get_mut(&addr) else { tracing::trace!(?header, "udp forward packet error, connection not found"); @@ -496,7 +489,7 @@ impl UdpTunnelListenerData { } } - async fn do_forward_task(self: Self) { + async fn do_forward_task(self) { let socket = self.socket.as_ref().unwrap().clone(); udp_recv_from_socket_forward_task(socket, true, |zc_packet, addr| { self.do_forward_one_packet_to_conn(zc_packet, addr); @@ -587,7 +580,7 @@ impl TunnelListener for UdpTunnelListener { async fn accept(&mut self) -> Result, super::TunnelError> { tracing::info!("start udp accept: {:?}", self.addr); - while let Some(conn) = self.conn_recv.recv().await { + if let Some(conn) = self.conn_recv.recv().await { return Ok(conn); } return Err(super::TunnelError::InternalError( @@ -739,7 +732,6 @@ impl UdpTunnelConnector { tokio::select! { _ = close_event_recv.recv() => { tracing::debug!("connector udp close event"); - return; } _ = udp_recv_from_socket_forward_task(socket_clone,false, |zc_packet, addr| { tracing::trace!(?addr, "connector udp forward task done"); @@ -748,7 +740,6 @@ impl UdpTunnelConnector { } }) => { tracing::debug!("connector udp forward task done"); - return; } } } @@ -1023,9 +1014,9 @@ mod tests { let bind_dev = get_interface_name_by_ip(&IpAddr::V4(ips[0].into())); for ip in ips { - println!("bind to ip: {:?}, {:?}", ip, bind_dev); + println!("bind to ip: {}, {:?}", ip, bind_dev); let addr = check_scheme_and_get_socket_addr::( - &format!("udp://{}:11111", ip.to_string()).parse().unwrap(), + &format!("udp://{}:11111", ip).parse().unwrap(), "udp", IpVersion::Both, ) diff --git a/easytier/src/tunnel/websocket.rs b/easytier/src/tunnel/websocket.rs index 0ad98b30..ba292633 100644 --- a/easytier/src/tunnel/websocket.rs +++ b/easytier/src/tunnel/websocket.rs @@ -36,9 +36,9 @@ async fn sink_from_zc_packet(msg: ZCPacket) -> Result { async fn map_from_ws_message( msg: Result, ) -> Option> { - if msg.is_err() { - tracing::error!(?msg, "recv from websocket error"); - return Some(Err(TunnelError::WebSocketError(msg.unwrap_err()))); + if let Err(e) = msg { + tracing::error!(?e, "recv from websocket error"); + return Some(Err(TunnelError::WebSocketError(e))); } let msg = msg.unwrap(); @@ -101,15 +101,15 @@ impl WSTunnelListener { let (write, read) = server_bulder.accept(stream).await?.split(); Box::new(TunnelWrapper::new( - read.filter_map(move |msg| map_from_ws_message(msg)), - write.with(move |msg| sink_from_zc_packet(msg)), + read.filter_map(map_from_ws_message), + write.with(sink_from_zc_packet), Some(info), )) } else { let (write, read) = server_bulder.accept(stream).await?.split(); Box::new(TunnelWrapper::new( - read.filter_map(move |msg| map_from_ws_message(msg)), - write.with(move |msg| sink_from_zc_packet(msg)), + read.filter_map(map_from_ws_message), + write.with(sink_from_zc_packet), Some(info), )) }; @@ -217,8 +217,8 @@ impl WSTunnelConnector { let (client, _) = c.connect_on(stream).await?; let (write, read) = client.split(); - let read = read.filter_map(move |msg| map_from_ws_message(msg)); - let write = write.with(move |msg| sink_from_zc_packet(msg)); + let read = read.filter_map(map_from_ws_message); + let write = write.with(sink_from_zc_packet); Ok(Box::new(TunnelWrapper::new(read, write, Some(info)))) } diff --git a/easytier/src/tunnel/wireguard.rs b/easytier/src/tunnel/wireguard.rs index 3275b420..1d720b13 100644 --- a/easytier/src/tunnel/wireguard.rs +++ b/easytier/src/tunnel/wireguard.rs @@ -65,7 +65,7 @@ impl WgConfig { let my_secret_key = StaticSecret::from(my_sec); let my_public_key = PublicKey::from(&my_secret_key); let peer_secret_key = StaticSecret::from(my_sec); - let peer_public_key = my_public_key.clone(); + let peer_public_key = my_public_key; WgConfig { my_secret_key, @@ -186,7 +186,7 @@ impl WgPeerData { recv_buf: &[u8], ) { let mut send_buf = vec![0u8; MAX_PACKET]; - let data = &recv_buf[..]; + let data = recv_buf; let decapsulate_result = { let mut peer = self.tunn.lock().await; peer.decapsulate(None, data, &mut send_buf) @@ -325,9 +325,9 @@ impl WgPeerData { fn remove_ip_header<'a>(&self, packet: &'a [u8], is_v4: bool) -> &'a [u8] { if is_v4 { - return &packet[20..]; + &packet[20..] } else { - return &packet[40..]; + &packet[40..] } } } @@ -351,7 +351,7 @@ impl WgPeer { WgPeer { tunn: Some(Mutex::new(Tunn::new( config.my_secret_key.clone(), - config.peer_public_key.clone(), + config.peer_public_key, None, None, rand::thread_rng().next_u32(), @@ -513,7 +513,7 @@ impl WgTunnelListener { if !peer_map.contains_key(&addr) { tracing::info!("New peer: {}", addr); - let mut wg = WgPeer::new(socket.clone(), config.clone(), addr.clone()); + let mut wg = WgPeer::new(socket.clone(), config.clone(), addr); let (stream, sink) = wg.start_and_get_tunnel().split(); let tunnel = Box::new(TunnelWrapper::new( stream, @@ -579,7 +579,7 @@ impl TunnelListener for WgTunnelListener { } async fn accept(&mut self) -> Result, super::TunnelError> { - while let Some(tunnel) = self.conn_recv.recv().await { + if let Some(tunnel) = self.conn_recv.recv().await { tracing::info!(?tunnel, "Accepted tunnel"); return Ok(tunnel); } @@ -781,7 +781,7 @@ pub mod tests { my_secret_key: my_secret_key.clone(), my_public_key, peer_secret_key: their_secret_key.clone(), - peer_public_key: their_public_key.clone(), + peer_public_key: their_public_key, wg_type: WgType::InternalUse, }; diff --git a/easytier/src/utils.rs b/easytier/src/utils.rs index e705ca01..abb878a1 100644 --- a/easytier/src/utils.rs +++ b/easytier/src/utils.rs @@ -126,7 +126,7 @@ pub fn utf8_or_gbk_to_string(s: &[u8]) -> String { } thread_local! { - static PANIC_COUNT : std::cell::RefCell = std::cell::RefCell::new(0); + static PANIC_COUNT : std::cell::RefCell = const { std::cell::RefCell::new(0) }; } pub fn setup_panic_handler() { @@ -158,7 +158,7 @@ pub fn setup_panic_handler() { let thread = thread.name().unwrap_or(""); let tmp_path = std::env::temp_dir().join("easytier-panic.log"); - let candidate_path = vec![ + let candidate_path = [ std::path::PathBuf::from_str("easytier-panic.log").ok(), Some(tmp_path), ]; @@ -188,7 +188,7 @@ pub fn setup_panic_handler() { } }; - write_err(format!("panic occurred, if this is a bug, please report this issue on github (https://github.com/easytier/easytier/issues)")); + write_err("panic occurred, if this is a bug, please report this issue on github (https://github.com/easytier/easytier/issues)".to_string()); write_err(format!("easytier version: {}", crate::VERSION)); write_err(format!("os version: {}", std::env::consts::OS)); write_err(format!("arch: {}", std::env::consts::ARCH)); @@ -217,13 +217,8 @@ pub fn check_tcp_available(port: u16) -> bool { TcpListener::bind(s).is_ok() } -pub fn find_free_tcp_port(range: std::ops::Range) -> Option { - for port in range { - if check_tcp_available(port) { - return Some(port); - } - } - None +pub fn find_free_tcp_port(mut range: std::ops::Range) -> Option { + range.find(|&port| check_tcp_available(port)) } #[cfg(test)] diff --git a/easytier/src/vpn_portal/wireguard.rs b/easytier/src/vpn_portal/wireguard.rs index dca3ed01..f4d94d7d 100644 --- a/easytier/src/vpn_portal/wireguard.rs +++ b/easytier/src/vpn_portal/wireguard.rs @@ -132,12 +132,12 @@ impl WireGuardImpl { .await; } - if map_key.is_some() { + if let Some(map_key) = map_key { // Remove the client from the wg_peer_ip_table only when its endpoint address is unchanged, // or we may break clients behind NAT. - match wg_peer_ip_table.remove_if(&map_key.unwrap(), |_, entry| { - entry.endpoint_addr == endpoint_addr - }) { + match wg_peer_ip_table + .remove_if(&map_key, |_, entry| entry.endpoint_addr == endpoint_addr) + { Some(_) => tracing::info!(?map_key, "Removed wg client from table"), None => tracing::info!( ?map_key, @@ -286,18 +286,16 @@ impl VpnPortal for WireGuard { let routes = peer_mgr.list_routes().await; let mut allow_ips = routes .iter() - .map(|x| x.proxy_cidrs.iter().map(String::to_string)) - .flatten() + .flat_map(|x| x.proxy_cidrs.iter().map(String::to_string)) .collect::>(); - for ipv4 in routes + if let Some(ipv4) = routes .iter() - .filter(|x| x.ipv4_addr.is_some()) - .map(|x| x.ipv4_addr.unwrap()) + .filter_map(|x| x.ipv4_addr) .chain(global_ctx.get_ipv4().into_iter().map(Into::into)) + .next() { let inet = Ipv4Inet::from(ipv4); allow_ips.push(inet.network().to_string()); - break; } let vpn_cfg = global_ctx.config.get_vpn_portal_config().unwrap(); @@ -341,19 +339,17 @@ PersistentKeepalive = 25 async fn list_clients(&self) -> Vec { self.inner .as_ref() - .and_then(|w| { - Some( - w.wg_peer_ip_table - .iter() - .map(|x| { - x.value() - .endpoint_addr - .as_ref() - .map(|x| x.to_string()) - .unwrap_or_default() - }) - .collect(), - ) + .map(|w| { + w.wg_peer_ip_table + .iter() + .map(|x| { + x.value() + .endpoint_addr + .as_ref() + .map(|x| x.to_string()) + .unwrap_or_default() + }) + .collect() }) .unwrap_or_default() } diff --git a/easytier/src/web_client/controller.rs b/easytier/src/web_client/controller.rs index 45249c79..1133caa1 100644 --- a/easytier/src/web_client/controller.rs +++ b/easytier/src/web_client/controller.rs @@ -1,5 +1,8 @@ use crate::{ - common::config::ConfigLoader, launcher::ConfigSource, instance_manager::NetworkInstanceManager, proto::{ + common::config::ConfigLoader, + instance_manager::NetworkInstanceManager, + launcher::ConfigSource, + proto::{ rpc_types::{self, controller::BaseController}, web::{ CollectNetworkInfoRequest, CollectNetworkInfoResponse, DeleteNetworkInstanceRequest, @@ -8,7 +11,7 @@ use crate::{ RetainNetworkInstanceResponse, RunNetworkInstanceRequest, RunNetworkInstanceResponse, ValidateConfigRequest, ValidateConfigResponse, WebClientService, }, - } + }, }; pub struct Controller { @@ -108,7 +111,7 @@ impl WebClientService for Controller { if !include_inst_ids.is_empty() { let mut to_remove = Vec::new(); for (k, _) in ret.map.iter() { - if !include_inst_ids.contains(&k) { + if !include_inst_ids.contains(k) { to_remove.push(k.clone()); } } diff --git a/easytier/src/web_client/mod.rs b/easytier/src/web_client/mod.rs index 3726bd23..beeeaefa 100644 --- a/easytier/src/web_client/mod.rs +++ b/easytier/src/web_client/mod.rs @@ -11,9 +11,15 @@ pub struct WebClient { } impl WebClient { - pub fn new(connector: T, token: S, hostname: H) -> Self { - let controller = Arc::new(controller::Controller::new(token.to_string(), - hostname.to_string())); + pub fn new( + connector: T, + token: S, + hostname: H, + ) -> Self { + let controller = Arc::new(controller::Controller::new( + token.to_string(), + hostname.to_string(), + )); let controller_clone = controller.clone(); let tasks = ScopedTask::from(tokio::spawn(async move { diff --git a/easytier/src/web_client/session.rs b/easytier/src/web_client/session.rs index 58bb661d..72b4b720 100644 --- a/easytier/src/web_client/session.rs +++ b/easytier/src/web_client/session.rs @@ -114,7 +114,7 @@ impl Session { } Ok(resp) => { tracing::debug!("heartbeat response: {:?}", resp); - let _ = ctx_clone.notifier.send(resp.clone()); + let _ = ctx_clone.notifier.send(resp); ctx_clone.resp.lock().await.replace(resp); } } diff --git a/flake.nix b/flake.nix index 948b4f0e..b4e2009f 100644 --- a/flake.nix +++ b/flake.nix @@ -17,7 +17,7 @@ pkgs = import nixpkgs { inherit system overlays; }; - rustVersion = "1.87.0"; + rustVersion = "1.89.0"; rust = pkgs.rust-bin.stable.${rustVersion}.default.override{ extensions = [ "rust-src" "rust-analyzer" ]; };