mirror of
https://github.com/shadowsocks/shadowsocks-rust.git
synced 2026-02-09 01:59:16 +08:00
fix: bump msrv to 1.88 (#2054)
This commit is contained in:
18
.github/workflows/build-msrv.yml
vendored
18
.github/workflows/build-msrv.yml
vendored
@@ -30,9 +30,9 @@ jobs:
|
||||
- name: Install Rust
|
||||
run: |
|
||||
rustup set profile minimal
|
||||
rustup toolchain install 1.85
|
||||
rustup default 1.85
|
||||
rustup override set 1.85
|
||||
rustup toolchain install 1.88
|
||||
rustup default 1.88
|
||||
rustup override set 1.88
|
||||
- name: Build with All Features Enabled (Unix)
|
||||
if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }}
|
||||
run: cargo build --verbose --features "full-extra local-flow-stat utility-url-outline"
|
||||
@@ -63,9 +63,9 @@ jobs:
|
||||
- name: Install Rust
|
||||
run: |
|
||||
rustup set profile minimal
|
||||
rustup toolchain install 1.85
|
||||
rustup default 1.85
|
||||
rustup override set 1.85
|
||||
rustup toolchain install 1.88
|
||||
rustup default 1.88
|
||||
rustup override set 1.88
|
||||
- name: Build with All Features Enabled
|
||||
run: cargo build --manifest-path crates/shadowsocks-service/Cargo.toml --verbose --features "full dns-over-tls dns-over-https dns-over-h3 local-dns local-flow-stat local-http-rustls local-tun local-fake-dns local-online-config stream-cipher aead-cipher-extra aead-cipher-2022 aead-cipher-2022-extra security-replay-attack-detect"
|
||||
|
||||
@@ -92,8 +92,8 @@ jobs:
|
||||
- name: Install Rust
|
||||
run: |
|
||||
rustup set profile minimal
|
||||
rustup toolchain install 1.85
|
||||
rustup default 1.85
|
||||
rustup override set 1.85
|
||||
rustup toolchain install 1.88
|
||||
rustup default 1.88
|
||||
rustup override set 1.88
|
||||
- name: Build with All Features Enabled
|
||||
run: cargo build --manifest-path crates/shadowsocks/Cargo.toml --verbose --features "stream-cipher aead-cipher-extra aead-cipher-2022 aead-cipher-2022-extra security-replay-attack-detect"
|
||||
|
||||
@@ -9,7 +9,7 @@ documentation = "https://docs.rs/shadowsocks-rust"
|
||||
keywords = ["shadowsocks", "proxy", "socks", "socks5", "firewall"]
|
||||
license = "MIT"
|
||||
edition = "2024"
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.88"
|
||||
|
||||
[badges]
|
||||
maintenance = { status = "passively-maintained" }
|
||||
|
||||
@@ -18,8 +18,8 @@ fn main() -> ExitCode {
|
||||
.about("A fast tunnel proxy that helps you bypass firewalls. (https://shadowsocks.org)");
|
||||
|
||||
// Allow running `ssservice` as symlink of `sslocal`, `ssserver` and `ssmanager`
|
||||
if let Some(program_path) = env::args().next() {
|
||||
if let Some(program_name) = Path::new(&program_path).file_name() {
|
||||
if let Some(program_path) = env::args().next()
|
||||
&& let Some(program_name) = Path::new(&program_path).file_name() {
|
||||
match program_name.to_str() {
|
||||
Some("sslocal") => return local::main(&local::define_command_line_options(app).get_matches()),
|
||||
Some("ssserver") => return server::main(&server::define_command_line_options(app).get_matches()),
|
||||
@@ -27,7 +27,6 @@ fn main() -> ExitCode {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let matches = app
|
||||
.subcommand_required(true)
|
||||
|
||||
@@ -1 +1 @@
|
||||
msrv = "1.85"
|
||||
msrv = "1.88"
|
||||
|
||||
@@ -9,7 +9,7 @@ documentation = "https://docs.rs/shadowsocks-service"
|
||||
keywords = ["shadowsocks", "proxy", "socks", "socks5", "firewall"]
|
||||
license = "MIT"
|
||||
edition = "2024"
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.88"
|
||||
|
||||
[badges]
|
||||
maintenance = { status = "passively-maintained" }
|
||||
|
||||
@@ -208,15 +208,14 @@ impl ParsingRules {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if let Some(set_rule) = caps.get(2) {
|
||||
if let Ok(set_rule) = str::from_utf8(set_rule.as_bytes()) {
|
||||
} else if let Some(set_rule) = caps.get(2)
|
||||
&& let Ok(set_rule) = str::from_utf8(set_rule.as_bytes()) {
|
||||
let set_rule = set_rule.replace("\\.", ".");
|
||||
if self.add_set_rule_inner(&set_rule).is_ok() {
|
||||
trace!("REGEX-RULE {} => SET-RULE {}", rule, set_rule);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trace!("REGEX-RULE {}", rule);
|
||||
|
||||
@@ -2388,9 +2388,9 @@ impl Config {
|
||||
}
|
||||
|
||||
// Security
|
||||
if let Some(sec) = config.security {
|
||||
if let Some(replay_attack) = sec.replay_attack {
|
||||
if let Some(policy) = replay_attack.policy {
|
||||
if let Some(sec) = config.security
|
||||
&& let Some(replay_attack) = sec.replay_attack
|
||||
&& let Some(policy) = replay_attack.policy {
|
||||
match policy.parse::<ReplayAttackPolicy>() {
|
||||
Ok(p) => nconfig.security.replay_attack.policy = p,
|
||||
Err(..) => {
|
||||
@@ -2399,8 +2399,6 @@ impl Config {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(balancer) = config.balancer {
|
||||
nconfig.balancer = BalancerConfig {
|
||||
@@ -2620,19 +2618,17 @@ impl Config {
|
||||
}
|
||||
|
||||
// Balancer related checks
|
||||
if let Some(rtt) = self.balancer.max_server_rtt {
|
||||
if rtt.as_secs() == 0 {
|
||||
if let Some(rtt) = self.balancer.max_server_rtt
|
||||
&& rtt.as_secs() == 0 {
|
||||
let err = Error::new(ErrorKind::Invalid, "balancer.max_server_rtt must be > 0", None);
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(intv) = self.balancer.check_interval {
|
||||
if intv.as_secs() == 0 {
|
||||
if let Some(intv) = self.balancer.check_interval
|
||||
&& intv.as_secs() == 0 {
|
||||
let err = Error::new(ErrorKind::Invalid, "balancer.check_interval must be > 0", None);
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.config_type.is_server() && self.server.is_empty() {
|
||||
@@ -2667,12 +2663,11 @@ impl Config {
|
||||
let server = &inst.config;
|
||||
|
||||
// Plugin shouldn't be an empty string
|
||||
if let Some(plugin) = server.plugin() {
|
||||
if plugin.plugin.trim().is_empty() {
|
||||
if let Some(plugin) = server.plugin()
|
||||
&& plugin.plugin.trim().is_empty() {
|
||||
let err = Error::new(ErrorKind::Malformed, "`plugin` shouldn't be an empty string", None);
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
|
||||
// Server's domain name shouldn't be an empty string
|
||||
match server.addr() {
|
||||
@@ -3072,14 +3067,13 @@ impl fmt::Display for Config {
|
||||
jconf.mode = Some(m.mode.to_string());
|
||||
}
|
||||
|
||||
if jconf.method.is_none() {
|
||||
if let Some(ref m) = m.method {
|
||||
if jconf.method.is_none()
|
||||
&& let Some(ref m) = m.method {
|
||||
jconf.method = Some(m.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
if jconf.plugin.is_none() {
|
||||
if let Some(ref p) = m.plugin {
|
||||
if jconf.plugin.is_none()
|
||||
&& let Some(ref p) = m.plugin {
|
||||
jconf.plugin = Some(p.plugin.clone());
|
||||
if let Some(ref o) = p.plugin_opts {
|
||||
jconf.plugin_opts = Some(o.clone());
|
||||
@@ -3088,7 +3082,6 @@ impl fmt::Display for Config {
|
||||
jconf.plugin_args = Some(p.plugin_args.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.no_delay {
|
||||
@@ -3194,8 +3187,8 @@ impl fmt::Display for Config {
|
||||
/// If value is in format `${VAR_NAME}` then it will try to read from `VAR_NAME` environment variable.
|
||||
/// It will return the original value if fails to read `${VAR_NAME}`.
|
||||
pub fn read_variable_field_value(value: &str) -> Cow<'_, str> {
|
||||
if let Some(left_over) = value.strip_prefix("${") {
|
||||
if let Some(var_name) = left_over.strip_suffix('}') {
|
||||
if let Some(left_over) = value.strip_prefix("${")
|
||||
&& let Some(var_name) = left_over.strip_suffix('}') {
|
||||
match env::var(var_name) {
|
||||
Ok(value) => return value.into(),
|
||||
Err(err) => {
|
||||
@@ -3206,7 +3199,6 @@ pub fn read_variable_field_value(value: &str) -> Cow<'_, str> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
value.into()
|
||||
}
|
||||
|
||||
@@ -163,11 +163,10 @@ impl PingBalancerBuilder {
|
||||
}
|
||||
|
||||
pub async fn build(self) -> io::Result<PingBalancer> {
|
||||
if let Some(intv) = self.check_best_interval {
|
||||
if intv > self.check_interval {
|
||||
if let Some(intv) = self.check_best_interval
|
||||
&& intv > self.check_interval {
|
||||
return Err(io::Error::other("check_interval must be >= check_best_interval"));
|
||||
}
|
||||
}
|
||||
|
||||
let (shared_context, task_abortable) = PingBalancerContext::new(
|
||||
self.servers,
|
||||
|
||||
@@ -193,7 +193,7 @@ impl ServerStat {
|
||||
vlat_abs_diff.sort_unstable();
|
||||
|
||||
let abs_diff_median_mid = vlat_abs_diff.len() / 2;
|
||||
self.data.latency_mad = if vlat_abs_diff.len() % 2 == 0 {
|
||||
self.data.latency_mad = if vlat_abs_diff.len().is_multiple_of(2) {
|
||||
(vlat_abs_diff[abs_diff_median_mid] + vlat_abs_diff[abs_diff_median_mid - 1]) / 2
|
||||
} else {
|
||||
vlat_abs_diff[abs_diff_median_mid]
|
||||
|
||||
@@ -515,12 +515,11 @@ where
|
||||
}
|
||||
};
|
||||
|
||||
if UDP_SOCKET_SUPPORT_DUAL_STACK {
|
||||
if let SocketAddr::V4(saddr) = target_addr {
|
||||
if UDP_SOCKET_SUPPORT_DUAL_STACK
|
||||
&& let SocketAddr::V4(saddr) = target_addr {
|
||||
let mapped_ip = saddr.ip().to_ipv6_mapped();
|
||||
target_addr = SocketAddr::V6(SocketAddrV6::new(mapped_ip, saddr.port(), 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
let n = socket.send_to(data, target_addr).await?;
|
||||
if n != data.len() {
|
||||
|
||||
@@ -214,15 +214,14 @@ impl OnlineConfigService {
|
||||
// Check plugin whitelist
|
||||
if let Some(ref allowed_plugins) = self.allowed_plugins {
|
||||
for server in &online_config.server {
|
||||
if let Some(plugin) = server.config.plugin() {
|
||||
if !allowed_plugins.contains(&plugin.plugin) {
|
||||
if let Some(plugin) = server.config.plugin()
|
||||
&& !allowed_plugins.contains(&plugin.plugin) {
|
||||
error!(
|
||||
"server-loader task found not allowed plugin: {}, url: {}",
|
||||
plugin.plugin, self.config_url
|
||||
);
|
||||
return Err(io::Error::other(format!("not allowed plugin: {}", plugin.plugin)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,11 +63,10 @@ async fn handle_redir_client(
|
||||
// Get forward address from socket
|
||||
//
|
||||
// Try to convert IPv4 mapped IPv6 address for dual-stack mode.
|
||||
if let SocketAddr::V6(ref a) = daddr {
|
||||
if let Some(v4) = to_ipv4_mapped(a.ip()) {
|
||||
if let SocketAddr::V6(ref a) = daddr
|
||||
&& let Some(v4) = to_ipv4_mapped(a.ip()) {
|
||||
daddr = SocketAddr::new(IpAddr::from(v4), a.port());
|
||||
}
|
||||
}
|
||||
let target_addr = Address::from(daddr);
|
||||
establish_client_tcp_redir(context, balancer, s, peer_addr, &target_addr).await
|
||||
}
|
||||
|
||||
@@ -296,11 +296,10 @@ impl RedirUdpServer {
|
||||
}
|
||||
|
||||
// Try to convert IPv4 mapped IPv6 address for dual-stack mode.
|
||||
if let SocketAddr::V6(ref a) = dst {
|
||||
if let Some(v4) = to_ipv4_mapped(a.ip()) {
|
||||
if let SocketAddr::V6(ref a) = dst
|
||||
&& let Some(v4) = to_ipv4_mapped(a.ip()) {
|
||||
dst = SocketAddr::new(IpAddr::from(v4), a.port());
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(err) = manager.send_to(src, Address::from(dst), pkt).await {
|
||||
debug!(
|
||||
|
||||
@@ -71,8 +71,8 @@ impl UdpRedirSocket {
|
||||
|
||||
socket.set_nonblocking(true)?;
|
||||
socket.set_reuse_address(true)?;
|
||||
if reuse_port {
|
||||
if let Err(err) = socket.set_reuse_port(true) {
|
||||
if reuse_port
|
||||
&& let Err(err) = socket.set_reuse_port(true) {
|
||||
if let Some(libc::ENOPROTOOPT) = err.raw_os_error() {
|
||||
// SO_REUSEPORT is supported after 3.9
|
||||
trace!("failed to set SO_REUSEPORT, error: {}", err);
|
||||
@@ -81,7 +81,6 @@ impl UdpRedirSocket {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let sock_addr = SockAddr::from(addr);
|
||||
|
||||
|
||||
@@ -52,8 +52,8 @@ impl UdpRedirSocket {
|
||||
|
||||
socket.set_nonblocking(true)?;
|
||||
socket.set_reuse_address(true)?;
|
||||
if reuse_port {
|
||||
if let Err(err) = socket.set_reuse_port(true) {
|
||||
if reuse_port
|
||||
&& let Err(err) = socket.set_reuse_port(true) {
|
||||
if let Some(libc::ENOPROTOOPT) = err.raw_os_error() {
|
||||
trace!("failed to set SO_REUSEPORT, error: {}", err);
|
||||
} else {
|
||||
@@ -61,7 +61,6 @@ impl UdpRedirSocket {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let sock_addr = SockAddr::from(addr);
|
||||
|
||||
|
||||
@@ -159,11 +159,10 @@ impl AsyncRead for TcpConnection {
|
||||
}
|
||||
|
||||
// Nothing could be read. Wait for notify.
|
||||
if let Some(old_waker) = control.recv_waker.replace(cx.waker().clone()) {
|
||||
if !old_waker.will_wake(cx.waker()) {
|
||||
if let Some(old_waker) = control.recv_waker.replace(cx.waker().clone())
|
||||
&& !old_waker.will_wake(cx.waker()) {
|
||||
old_waker.wake();
|
||||
}
|
||||
}
|
||||
|
||||
return Poll::Pending;
|
||||
}
|
||||
@@ -191,11 +190,10 @@ impl AsyncWrite for TcpConnection {
|
||||
// Write to buffer
|
||||
|
||||
if control.send_buffer.is_full() {
|
||||
if let Some(old_waker) = control.send_waker.replace(cx.waker().clone()) {
|
||||
if !old_waker.will_wake(cx.waker()) {
|
||||
if let Some(old_waker) = control.send_waker.replace(cx.waker().clone())
|
||||
&& !old_waker.will_wake(cx.waker()) {
|
||||
old_waker.wake();
|
||||
}
|
||||
}
|
||||
|
||||
return Poll::Pending;
|
||||
}
|
||||
@@ -224,11 +222,10 @@ impl AsyncWrite for TcpConnection {
|
||||
control.send_state = TcpSocketState::Close;
|
||||
}
|
||||
|
||||
if let Some(old_waker) = control.send_waker.replace(cx.waker().clone()) {
|
||||
if !old_waker.will_wake(cx.waker()) {
|
||||
if let Some(old_waker) = control.send_waker.replace(cx.waker().clone())
|
||||
&& !old_waker.will_wake(cx.waker()) {
|
||||
old_waker.wake();
|
||||
}
|
||||
}
|
||||
|
||||
self.manager_notify.notify();
|
||||
Poll::Pending
|
||||
@@ -421,11 +418,10 @@ impl TcpTun {
|
||||
wake_receiver = true;
|
||||
}
|
||||
|
||||
if wake_receiver && control.recv_waker.is_some() {
|
||||
if let Some(waker) = control.recv_waker.take() {
|
||||
if wake_receiver && control.recv_waker.is_some()
|
||||
&& let Some(waker) = control.recv_waker.take() {
|
||||
waker.wake();
|
||||
}
|
||||
}
|
||||
|
||||
// Check if writable
|
||||
let mut wake_sender = false;
|
||||
@@ -456,11 +452,10 @@ impl TcpTun {
|
||||
}
|
||||
}
|
||||
|
||||
if wake_sender && control.send_waker.is_some() {
|
||||
if let Some(waker) = control.send_waker.take() {
|
||||
if wake_sender && control.send_waker.is_some()
|
||||
&& let Some(waker) = control.send_waker.take() {
|
||||
waker.wake();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for socket_handle in sockets_to_remove {
|
||||
@@ -601,11 +596,10 @@ async fn handle_redir_client(
|
||||
// Get forward address from socket
|
||||
//
|
||||
// Try to convert IPv4 mapped IPv6 address for dual-stack mode.
|
||||
if let SocketAddr::V6(ref a) = daddr {
|
||||
if let Some(v4) = to_ipv4_mapped(a.ip()) {
|
||||
if let SocketAddr::V6(ref a) = daddr
|
||||
&& let Some(v4) = to_ipv4_mapped(a.ip()) {
|
||||
daddr = SocketAddr::new(IpAddr::from(v4), a.port());
|
||||
}
|
||||
}
|
||||
let target_addr = Address::from(daddr);
|
||||
establish_client_tcp_redir(context, balancer, s, peer_addr, &target_addr).await
|
||||
}
|
||||
|
||||
@@ -329,8 +329,8 @@ impl Manager {
|
||||
};
|
||||
|
||||
let pid_path = self.server_pid_path(port);
|
||||
if pid_path.exists() {
|
||||
if let Ok(mut pid_file) = File::open(&pid_path) {
|
||||
if pid_path.exists()
|
||||
&& let Ok(mut pid_file) = File::open(&pid_path) {
|
||||
let mut pid_content = String::new();
|
||||
if pid_file.read_to_string(&mut pid_content).is_ok() {
|
||||
let pid_content = pid_content.trim();
|
||||
@@ -346,7 +346,6 @@ impl Manager {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let server_config_path = self.server_config_path(port);
|
||||
|
||||
|
||||
@@ -593,15 +593,14 @@ impl UdpAssociationContext {
|
||||
data: &[u8],
|
||||
control: &Option<UdpSocketControlData>,
|
||||
) {
|
||||
if let Some(ref mut session) = self.client_session {
|
||||
if peer_addr != self.peer_addr {
|
||||
if let Some(ref mut session) = self.client_session
|
||||
&& peer_addr != self.peer_addr {
|
||||
debug!(
|
||||
"udp relay for {} changed to {}, session: {:?}",
|
||||
self.peer_addr, peer_addr, session.client_session_id
|
||||
);
|
||||
self.peer_addr = peer_addr;
|
||||
}
|
||||
}
|
||||
|
||||
trace!(
|
||||
"udp relay {} -> {} with {} bytes, control: {:?}",
|
||||
@@ -737,11 +736,10 @@ impl UdpAssociationContext {
|
||||
// It is an undefined behavior in shadowsocks' protocol about how to handle IPv4-mapped-IPv6.
|
||||
// But for some implementations, they may expect the target address to be IPv4, because
|
||||
// the peer address is IPv4 when calling `sendto`.
|
||||
if let Address::SocketAddress(SocketAddr::V6(ref v6)) = addr {
|
||||
if let Some(v4) = to_ipv4_mapped(v6.ip()) {
|
||||
if let Address::SocketAddress(SocketAddr::V6(ref v6)) = addr
|
||||
&& let Some(v4) = to_ipv4_mapped(v6.ip()) {
|
||||
addr = Address::SocketAddress(SocketAddr::new(v4.into(), v6.port()));
|
||||
}
|
||||
}
|
||||
|
||||
match self.client_session {
|
||||
None => {
|
||||
|
||||
@@ -9,7 +9,7 @@ documentation = "https://docs.rs/shadowsocks-core"
|
||||
keywords = ["shadowsocks", "proxy", "socks", "socks5", "firewall"]
|
||||
license = "MIT"
|
||||
edition = "2024"
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.88"
|
||||
|
||||
[badges]
|
||||
maintenance = { status = "passively-maintained" }
|
||||
|
||||
@@ -695,21 +695,19 @@ impl ServerConfig {
|
||||
|
||||
/// Get server's TCP external address
|
||||
pub fn tcp_external_addr(&self) -> &ServerAddr {
|
||||
if let Some(plugin) = self.plugin() {
|
||||
if plugin.plugin_mode.enable_tcp() {
|
||||
if let Some(plugin) = self.plugin()
|
||||
&& plugin.plugin_mode.enable_tcp() {
|
||||
return self.plugin_addr.as_ref().unwrap_or(&self.addr);
|
||||
}
|
||||
}
|
||||
&self.addr
|
||||
}
|
||||
|
||||
/// Get server's UDP external address
|
||||
pub fn udp_external_addr(&self) -> &ServerAddr {
|
||||
if let Some(plugin) = self.plugin() {
|
||||
if plugin.plugin_mode.enable_udp() {
|
||||
if let Some(plugin) = self.plugin()
|
||||
&& plugin.plugin_mode.enable_udp() {
|
||||
return self.plugin_addr.as_ref().unwrap_or(&self.addr);
|
||||
}
|
||||
}
|
||||
&self.addr
|
||||
}
|
||||
|
||||
|
||||
@@ -167,15 +167,14 @@ static IP_STACK_CAPABILITIES: LazyLock<IpStackCapabilities> = LazyLock::new(|| {
|
||||
}
|
||||
|
||||
// Check IPv6 (::1)
|
||||
if let Ok(ipv6_socket) = Socket::new(Domain::IPV6, Type::STREAM, Some(Protocol::TCP)) {
|
||||
if ipv6_socket.set_only_v6(true).is_ok() {
|
||||
if let Ok(ipv6_socket) = Socket::new(Domain::IPV6, Type::STREAM, Some(Protocol::TCP))
|
||||
&& ipv6_socket.set_only_v6(true).is_ok() {
|
||||
let local_host = SockAddr::from(SocketAddr::new(Ipv6Addr::LOCALHOST.into(), 0));
|
||||
if ipv6_socket.bind(&local_host).is_ok() {
|
||||
caps.support_ipv6 = true;
|
||||
debug!("IpStackCapability support_ipv6=true");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check IPv4-mapped-IPv6 (127.0.0.1)
|
||||
if check_ipv4_mapped_ipv6_capability().is_ok() {
|
||||
|
||||
@@ -390,11 +390,10 @@ pub async fn bind_outbound_udp_socket(bind_addr: &SocketAddr, config: &ConnectOp
|
||||
UdpSocket::from_std(socket.into())?
|
||||
};
|
||||
|
||||
if !config.udp.allow_fragmentation {
|
||||
if let Err(err) = set_disable_ip_fragmentation(af, &socket) {
|
||||
if !config.udp.allow_fragmentation
|
||||
&& let Err(err) = set_disable_ip_fragmentation(af, &socket) {
|
||||
warn!("failed to disable IP fragmentation, error: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
// Set IP_BOUND_IF for BSD-like
|
||||
if let Some(ref iface) = config.bind_interface {
|
||||
|
||||
@@ -310,11 +310,10 @@ pub async fn bind_outbound_udp_socket(bind_addr: &SocketAddr, config: &ConnectOp
|
||||
UdpSocket::from_std(socket.into())?
|
||||
};
|
||||
|
||||
if !config.udp.allow_fragmentation {
|
||||
if let Err(err) = set_disable_ip_fragmentation(af, &socket) {
|
||||
if !config.udp.allow_fragmentation
|
||||
&& let Err(err) = set_disable_ip_fragmentation(af, &socket) {
|
||||
warn!("failed to disable IP fragmentation, error: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
// Any traffic except localhost should be protected
|
||||
// This is a workaround for VPNService
|
||||
|
||||
@@ -189,11 +189,10 @@ impl UdpSocket {
|
||||
/// Wrapper of `UdpSocket::poll_send`
|
||||
pub fn poll_send(&self, cx: &mut TaskContext<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {
|
||||
// Check MTU
|
||||
if let Some(mtu) = self.mtu {
|
||||
if buf.len() > mtu {
|
||||
if let Some(mtu) = self.mtu
|
||||
&& buf.len() > mtu {
|
||||
return Err(make_mtu_error(buf.len(), mtu)).into();
|
||||
}
|
||||
}
|
||||
|
||||
self.socket.poll_send(cx, buf)
|
||||
}
|
||||
@@ -202,11 +201,10 @@ impl UdpSocket {
|
||||
#[inline]
|
||||
pub async fn send(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
// Check MTU
|
||||
if let Some(mtu) = self.mtu {
|
||||
if buf.len() > mtu {
|
||||
if let Some(mtu) = self.mtu
|
||||
&& buf.len() > mtu {
|
||||
return Err(make_mtu_error(buf.len(), mtu));
|
||||
}
|
||||
}
|
||||
|
||||
self.socket.send(buf).await
|
||||
}
|
||||
@@ -214,11 +212,10 @@ impl UdpSocket {
|
||||
/// Wrapper of `UdpSocket::poll_send_to`
|
||||
pub fn poll_send_to(&self, cx: &mut TaskContext<'_>, buf: &[u8], target: SocketAddr) -> Poll<io::Result<usize>> {
|
||||
// Check MTU
|
||||
if let Some(mtu) = self.mtu {
|
||||
if buf.len() > mtu {
|
||||
if let Some(mtu) = self.mtu
|
||||
&& buf.len() > mtu {
|
||||
return Err(make_mtu_error(buf.len(), mtu)).into();
|
||||
}
|
||||
}
|
||||
|
||||
self.socket.poll_send_to(cx, buf, target)
|
||||
}
|
||||
@@ -227,11 +224,10 @@ impl UdpSocket {
|
||||
#[inline]
|
||||
pub async fn send_to<A: ToSocketAddrs>(&self, buf: &[u8], target: A) -> io::Result<usize> {
|
||||
// Check MTU
|
||||
if let Some(mtu) = self.mtu {
|
||||
if buf.len() > mtu {
|
||||
if let Some(mtu) = self.mtu
|
||||
&& buf.len() > mtu {
|
||||
return Err(make_mtu_error(buf.len(), mtu));
|
||||
}
|
||||
}
|
||||
|
||||
self.socket.send_to(buf, target).await
|
||||
}
|
||||
@@ -241,11 +237,10 @@ impl UdpSocket {
|
||||
pub fn poll_recv(&self, cx: &mut TaskContext<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {
|
||||
ready!(self.socket.poll_recv(cx, buf))?;
|
||||
|
||||
if let Some(mtu) = self.mtu {
|
||||
if buf.filled().len() > mtu {
|
||||
if let Some(mtu) = self.mtu
|
||||
&& buf.filled().len() > mtu {
|
||||
return Err(make_mtu_error(buf.filled().len(), mtu)).into();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(()).into()
|
||||
}
|
||||
@@ -255,11 +250,10 @@ impl UdpSocket {
|
||||
pub async fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let n = self.socket.recv(buf).await?;
|
||||
|
||||
if let Some(mtu) = self.mtu {
|
||||
if n > mtu {
|
||||
if let Some(mtu) = self.mtu
|
||||
&& n > mtu {
|
||||
return Err(make_mtu_error(n, mtu));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(n)
|
||||
}
|
||||
@@ -269,11 +263,10 @@ impl UdpSocket {
|
||||
pub fn poll_recv_from(&self, cx: &mut TaskContext<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<SocketAddr>> {
|
||||
let addr = ready!(self.socket.poll_recv_from(cx, buf))?;
|
||||
|
||||
if let Some(mtu) = self.mtu {
|
||||
if buf.filled().len() > mtu {
|
||||
if let Some(mtu) = self.mtu
|
||||
&& buf.filled().len() > mtu {
|
||||
return Err(make_mtu_error(buf.filled().len(), mtu)).into();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(addr).into()
|
||||
}
|
||||
@@ -283,11 +276,10 @@ impl UdpSocket {
|
||||
pub async fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
let (n, addr) = self.socket.recv_from(buf).await?;
|
||||
|
||||
if let Some(mtu) = self.mtu {
|
||||
if n > mtu {
|
||||
if let Some(mtu) = self.mtu
|
||||
&& n > mtu {
|
||||
return Err(make_mtu_error(n, mtu));
|
||||
}
|
||||
}
|
||||
|
||||
Ok((n, addr))
|
||||
}
|
||||
|
||||
@@ -159,11 +159,10 @@ where
|
||||
|
||||
// Wakeup writer task because we have already received the salt
|
||||
#[cfg(feature = "aead-cipher-2022")]
|
||||
if let ProxyServerStreamWriteState::PrepareHeader(waker) = this.writer_state {
|
||||
if let Some(waker) = waker.take() {
|
||||
if let ProxyServerStreamWriteState::PrepareHeader(waker) = this.writer_state
|
||||
&& let Some(waker) = waker.take() {
|
||||
waker.wake();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(()).into()
|
||||
}
|
||||
@@ -190,11 +189,10 @@ where
|
||||
*(this.writer_state) = ProxyServerStreamWriteState::Established;
|
||||
} else {
|
||||
// Reader didn't receive the salt from client yet.
|
||||
if let Some(waker) = waker.take() {
|
||||
if !waker.will_wake(cx.waker()) {
|
||||
if let Some(waker) = waker.take()
|
||||
&& !waker.will_wake(cx.waker()) {
|
||||
waker.wake();
|
||||
}
|
||||
}
|
||||
*waker = Some(cx.waker().clone());
|
||||
return Poll::Pending;
|
||||
}
|
||||
|
||||
@@ -755,17 +755,15 @@ pub fn create(matches: &ArgMatches) -> ShadowsocksResult<(Runtime, impl Future<O
|
||||
|
||||
#[cfg(feature = "local-redir")]
|
||||
{
|
||||
if RedirType::tcp_default() != RedirType::NotSupported {
|
||||
if let Some(tcp_redir) = matches.get_one::<String>("TCP_REDIR") {
|
||||
if RedirType::tcp_default() != RedirType::NotSupported
|
||||
&& let Some(tcp_redir) = matches.get_one::<String>("TCP_REDIR") {
|
||||
local_config.tcp_redir = tcp_redir.parse::<RedirType>().expect("tcp-redir");
|
||||
}
|
||||
}
|
||||
|
||||
if RedirType::udp_default() != RedirType::NotSupported {
|
||||
if let Some(udp_redir) = matches.get_one::<String>("UDP_REDIR") {
|
||||
if RedirType::udp_default() != RedirType::NotSupported
|
||||
&& let Some(udp_redir) = matches.get_one::<String>("UDP_REDIR") {
|
||||
local_config.udp_redir = udp_redir.parse::<RedirType>().expect("udp-redir");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "local-dns")]
|
||||
|
||||
@@ -404,17 +404,15 @@ pub fn create(matches: &ArgMatches) -> ShadowsocksResult<(Runtime, impl Future<O
|
||||
}
|
||||
|
||||
// Overrides
|
||||
if matches.get_flag("UDP_ONLY") {
|
||||
if let Some(ref mut m) = config.manager {
|
||||
if matches.get_flag("UDP_ONLY")
|
||||
&& let Some(ref mut m) = config.manager {
|
||||
m.mode = Mode::UdpOnly;
|
||||
}
|
||||
}
|
||||
|
||||
if matches.get_flag("TCP_AND_UDP") {
|
||||
if let Some(ref mut m) = config.manager {
|
||||
if matches.get_flag("TCP_AND_UDP")
|
||||
&& let Some(ref mut m) = config.manager {
|
||||
m.mode = Mode::TcpAndUdp;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(acl_file) = matches.get_one::<String>("ACL") {
|
||||
let acl = AccessControl::load_from_file(acl_file)
|
||||
|
||||
Reference in New Issue
Block a user