From aac36757d44cd69bc0122d67bc48e9b8e9b2b6cb Mon Sep 17 00:00:00 2001 From: zonyitoo Date: Wed, 26 Mar 2025 00:36:35 +0800 Subject: [PATCH] feat(local-tun): disable receive checksum, improving performance - ref #1923 Checksum running on receiving packets are the most significant cost of CPU time in local-tun. --- crates/shadowsocks-service/Cargo.toml | 1 + crates/shadowsocks-service/src/local/tun/tcp.rs | 13 +++++++++---- .../src/local/tun/virt_device.rs | 1 + 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/crates/shadowsocks-service/Cargo.toml b/crates/shadowsocks-service/Cargo.toml index 9c14bad6..53188a91 100644 --- a/crates/shadowsocks-service/Cargo.toml +++ b/crates/shadowsocks-service/Cargo.toml @@ -185,6 +185,7 @@ smoltcp = { version = "0.12", optional = true, default-features = false, feature "log", "medium-ip", "proto-ipv4", + "proto-ipv4-fragmentation", "proto-ipv6", "socket-icmp", "socket-udp", diff --git a/crates/shadowsocks-service/src/local/tun/tcp.rs b/crates/shadowsocks-service/src/local/tun/tcp.rs index 3096c4f5..42889bfe 100644 --- a/crates/shadowsocks-service/src/local/tun/tcp.rs +++ b/crates/shadowsocks-service/src/local/tun/tcp.rs @@ -18,7 +18,7 @@ use log::{debug, error, trace}; use shadowsocks::{net::TcpSocketOpts, relay::socks5::Address}; use smoltcp::{ iface::{Config as InterfaceConfig, Interface, PollResult, SocketHandle, SocketSet}, - phy::{DeviceCapabilities, Medium}, + phy::{Checksum, DeviceCapabilities, Medium}, socket::tcp::{CongestionControl, Socket as TcpSocket, SocketBuffer as TcpSocketBuffer, State as TcpState}, storage::RingBuffer, time::{Duration as SmolDuration, Instant as SmolInstant}, @@ -42,9 +42,9 @@ use crate::{ use super::virt_device::VirtTunDevice; -// NOTE: Default buffer could contain 20 AEAD packets -const DEFAULT_TCP_SEND_BUFFER_SIZE: u32 = 0x3FFF * 20; -const DEFAULT_TCP_RECV_BUFFER_SIZE: u32 = 0x3FFF * 20; +// NOTE: Default buffer could contain 5 AEAD packets +const DEFAULT_TCP_SEND_BUFFER_SIZE: u32 = (0x3FFFu32 * 5).next_power_of_two(); +const DEFAULT_TCP_RECV_BUFFER_SIZE: u32 = (0x3FFFu32 * 5).next_power_of_two(); #[derive(Debug, Clone, Copy, Eq, PartialEq)] enum TcpSocketState { @@ -261,6 +261,11 @@ impl TcpTun { let mut capabilities = DeviceCapabilities::default(); capabilities.medium = Medium::Ip; capabilities.max_transmission_unit = mtu as usize; + capabilities.checksum.ipv4 = Checksum::Tx; + capabilities.checksum.tcp = Checksum::Tx; + capabilities.checksum.udp = Checksum::Tx; + capabilities.checksum.icmpv4 = Checksum::Tx; + capabilities.checksum.icmpv6 = Checksum::Tx; let (mut device, iface_rx, iface_tx, iface_tx_avail) = VirtTunDevice::new(capabilities); diff --git a/crates/shadowsocks-service/src/local/tun/virt_device.rs b/crates/shadowsocks-service/src/local/tun/virt_device.rs index 6fdc797d..1dc06fc8 100644 --- a/crates/shadowsocks-service/src/local/tun/virt_device.rs +++ b/crates/shadowsocks-service/src/local/tun/virt_device.rs @@ -64,6 +64,7 @@ impl Device for VirtTunDevice { buffer, phantom_device: PhantomData, }; + self.in_buf_avail.store(true, Ordering::Release); let tx = VirtTxToken(self); return Some((rx, tx)); }